This commit is contained in:
taoser 2023-07-03 12:50:57 +08:00
parent 6a735f6fc8
commit ac854d627d
89 changed files with 1667 additions and 1371 deletions

View File

@ -140,14 +140,14 @@ class Comment extends AdminController
public function delete($id) public function delete($id)
{ {
if(Request::isAjax()){ if(Request::isAjax()){
$arr = explode(",",$id); try {
foreach($arr as $v){ $arr = explode(",",$id);
$comm = CommentModel::find($v); foreach($arr as $v){
$result = $comm->delete(); $comm = CommentModel::find($v);
} $comm->delete();
if($result){ }
return json(['code'=>0,'msg'=>'删除成功']); return json(['code'=>0,'msg'=>'删除成功']);
}else{ } catch (\Exception $e) {
return json(['code'=>-1,'msg'=>'删除失败']); return json(['code'=>-1,'msg'=>'删除失败']);
} }
} }

View File

@ -12,6 +12,7 @@ namespace app\admin\controller\content;
use app\common\controller\AdminController; use app\common\controller\AdminController;
use app\common\model\Article; use app\common\model\Article;
use app\facade\Cate;
use think\App; use think\App;
use think\facade\View; use think\facade\View;
use think\facade\Request; use think\facade\Request;
@ -43,7 +44,7 @@ class Forum extends AdminController
public function list() public function list()
{ {
$data = Request::only(['id','name','title','sec']); $data = Request::only(['id','name','title','sec','cate_id']);
$where = []; $where = [];
if (!empty($data['sec'])) { if (!empty($data['sec'])) {
switch ($data['sec']) { switch ($data['sec']) {
@ -73,13 +74,17 @@ class Forum extends AdminController
$where[] = ['id', '=', $data['id']]; $where[] = ['id', '=', $data['id']];
} }
if(!empty($data['cate_id'])){
$where[] = ['cate_id', '=', $data['cate_id']];
}
if(!empty($data['name'])){ if(!empty($data['name'])){
$userId = Db::name('user')->where('name',$data['name'])->value('id'); $userId = Db::name('user')->where('name',$data['name'])->value('id');
$where[] = ['user_id', '=', $userId]; $where[] = ['user_id', '=', $userId];
} }
if(!empty($data['title'])){ if(!empty($data['title'])){
$where[] = ['title', 'like', $data['title'].'%']; $where[] = ['title', 'like', '%'.$data['title'].'%'];
} }
$list = $this->model->getList($where, input('limit'), input('page')); $list = $this->model->getList($where, input('limit'), input('page'));
@ -91,6 +96,7 @@ class Forum extends AdminController
'poster' => $v['user']['name'], 'poster' => $v['user']['name'],
'avatar' => $v['user']['user_img'], 'avatar' => $v['user']['user_img'],
'title' => htmlspecialchars($v['title']), 'title' => htmlspecialchars($v['title']),
'cate' => $v['cate']['catename'],
'url' => $this->getArticleUrl($v['id'], 'index', $v['cate']['ename']), 'url' => $this->getArticleUrl($v['id'], 'index', $v['cate']['ename']),
'content' => strip_tags($v['content']), 'content' => strip_tags($v['content']),
'posttime' => $v['update_time'], 'posttime' => $v['update_time'],
@ -163,11 +169,6 @@ class Forum extends AdminController
} }
return $res; return $res;
} }
//1.查询分类表获取所有分类
$cateList = Db::name('cate')->where(['status'=>1,'delete_time'=>0])->order('sort','asc')->cache('catename',3600)->select();
//2.将catelist变量赋给模板 公共模板nav.html
View::assign('cateList',$cateList);
return View::fetch('add'); return View::fetch('add');
} }
@ -236,31 +237,24 @@ class Forum extends AdminController
} }
View::assign(['article'=>$article]); View::assign(['article'=>$article]);
//1.查询分类表获取所有分类
$cateList = Db::name('cate')->where(['status'=>1,'delete_time'=>0])->order('sort','asc')->cache('catename',3600)->select();
//2.将catelist变量赋给模板 公共模板nav.html
View::assign('cateList',$cateList);
return View::fetch(); return View::fetch();
} }
//删除帖子 //删除帖子 多选和单独
public function delete($id) public function delete($id)
{ {
if(Request::isAjax()){ if(Request::isAjax()){
$arr = explode(",",$id); try {
foreach($arr as $v){ $arr = explode(",",$id);
$article = Article::find($v); foreach($arr as $v){
$result = $article->together(['comments'])->delete(); $article = Article::find($v);
} $article->together(['comments'])->delete();
}
if($result){ return json(['code'=>0,'msg'=>'删除成功']);
return json(['code'=>0,'msg'=>'删除成功']); } catch (\Exception $e) {
}else{ return json(['code'=>-1,'msg'=>'删除失败']);
return json(['code'=>-1,'msg'=>'删除失败']); }
}
} }
} }
@ -352,7 +346,7 @@ class Forum extends AdminController
/** /**
* 分类 * 分类
* @return Json * @return Json
* @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException * @throws \think\db\exception\DbException
@ -374,6 +368,28 @@ class Forum extends AdminController
return json($tree); return json($tree);
} }
/**
* 分类
* @return \think\response\Json
*/
public function getCateList()
{
$cateList = Cate::field('id,pid,catename,sort')->where(['status' => 1])->select()->toArray();
// 排序
$cmf_arr = array_column($cateList, 'sort');
array_multisort($cmf_arr, SORT_ASC, $cateList);
$list = getTree($cateList);
$count = count($list);
$tree = [];
if($count){
$tree = ['code'=>0, 'msg'=>'ok','count'=>$count];
$tree['data'] = $list;
}
return json($tree);
}
//array_filter过滤函数 //array_filter过滤函数
protected function filtr($arr){ protected function filtr($arr){
if($arr === '' || $arr === null){ if($arr === '' || $arr === null){

View File

@ -16,6 +16,8 @@ use think\facade\Request;
use think\facade\Db; use think\facade\Db;
use app\common\model\User as UserModel; use app\common\model\User as UserModel;
use app\common\lib\Uploads; use app\common\lib\Uploads;
use app\common\validate\User as userValidate;
use think\exception\ValidateException;
class User extends AdminController class User extends AdminController
@ -79,6 +81,14 @@ class User extends AdminController
// //
if(Request::isAjax()){ if(Request::isAjax()){
$data = Request::only(['name','email','user_img','password','phone','sex']); $data = Request::only(['name','email','user_img','password','phone','sex']);
try{
validate(userValidate::class)
->scene('userReg')
->check($data);
} catch (ValidateException $e) {
// 验证失败 输出错误信息
return json(['code'=>-1,'msg'=>$e->getError()]);
}
$data['create_time'] = time(); $data['create_time'] = time();
$salt = substr(md5($data['create_time']),-6); $salt = substr(md5($data['create_time']),-6);
// 密码 // 密码
@ -100,9 +110,13 @@ class User extends AdminController
{ {
if(Request::isAjax()){ if(Request::isAjax()){
$data = Request::only(['id','name','email','user_img','password','phone','sex']); $data = Request::only(['id','name','email','user_img','password','phone','sex']);
$user = Db::name('user')->field('create_time')->find($data['id']); if(empty($data['password'])) {
$salt = substr(md5($user['create_time']),-6); unset($data['password']);
$data['password'] = md5(substr_replace(md5($data['password']),$salt,0,6)); // 密码 } else {
$user = Db::name('user')->field('create_time')->find($data['id']);
$salt = substr(md5($user['create_time']),-6);
$data['password'] = md5(substr_replace(md5($data['password']),$salt,0,6)); // 密码
}
try{ try{
Db::name('user')->update($data); Db::name('user')->update($data);
return json(['code'=>0,'msg'=>'编辑成功']); return json(['code'=>0,'msg'=>'编辑成功']);

View File

@ -16,14 +16,20 @@
<div class="layui-input-block"> <div class="layui-input-block">
<input type="text" name="catename" lay-verify="required" placeholder="分类名*" autocomplete="off" class="layui-input"> <input type="text" name="catename" lay-verify="required" placeholder="分类名*" autocomplete="off" class="layui-input">
</div> </div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">EN别名</label> <label class="layui-form-label">EN别名</label>
<div class="layui-input-block"> <div class="layui-input-block">
<input type="text" name="ename" lay-verify="required" placeholder="英文名*" autocomplete="off" class="layui-input"> <input type="text" name="ename" lay-verify="required" placeholder="英文名*" autocomplete="off" class="layui-input">
</div> </div>
</div>
<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="text" name="icon" placeholder="图标*" id="iconPicker" lay-filter="iconPicker" style="display:none;" class="layui-input"> <input type="text" name="icon" placeholder="图标*" id="iconPicker" lay-filter="iconPicker" style="display:none;" class="layui-input">
</div> </div>
</div>
<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">
<select name="detpl" id="tpl" lay-verify="required"> <select name="detpl" id="tpl" lay-verify="required">
@ -32,10 +38,14 @@
{/volist} {/volist}
</select> </select>
</div> </div>
</div>
<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="text" name="desc" lay-verify="required" placeholder="描述*" autocomplete="off" class="layui-input"> <textarea type="text" name="desc" lay-verify="required" placeholder="描述*" autocomplete="off" class="layui-textarea"></textarea>
</div> </div>
</div>
<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="text" name="sort" lay-verify="number|required" placeholder="请填数字" autocomplete="off" class="layui-input"> <input type="text" name="sort" lay-verify="number|required" placeholder="请填数字" autocomplete="off" class="layui-input">

View File

@ -42,7 +42,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">
<input type="text" name="desc" lay-verify="required" value="{$cate.desc}" placeholder="描述*" autocomplete="off" class="layui-input"> <textarea type="text" name="desc" lay-verify="required" value="{$cate.desc}" placeholder="描述*" autocomplete="off" class="layui-textarea">{$cate.desc}</textarea>
</div> </div>
</div> </div>
<div class="layui-form-item"> <div class="layui-form-item">

View File

@ -146,7 +146,7 @@
type: 2, type: 2,
title: '新增', title: '新增',
shade: 0.1, shade: 0.1,
area: ['450px', '500px'], area: ['550px', '650px'],
content: 'addEdit.html' content: 'addEdit.html'
}); });
} }
@ -156,7 +156,7 @@
type: 2, type: 2,
title: '修改', title: '修改',
shade: 0.1, shade: 0.1,
area: ['450px', '500px'], area: ['550px', '650px'],
content: 'addEdit.html?id=' + obj.data.id content: 'addEdit.html?id=' + obj.data.id
}); });
} }

View File

@ -148,7 +148,7 @@
data:{id:data.id,status:status}, data:{id:data.id,status:status},
dataType:'json', dataType:'json',
success:function(res){ success:function(res){
if(res.code == 0){ if(res.code === 0){
layer.msg(res.msg,{ layer.msg(res.msg,{
icon:res.icon, icon:res.icon,
time:2000 time:2000
@ -225,7 +225,7 @@
data:{"id":checkIds}, data:{"id":checkIds},
success: function(result) { success: function(result) {
layer.close(loading); layer.close(loading);
if (result.success) { if (result.code === 0) {
layer.msg(result.msg, { layer.msg(result.msg, {
icon: 1, icon: 1,
time: 1000 time: 1000
@ -244,7 +244,7 @@
} }
window.refresh = function(param) { window.refresh = function(param) {
table.reload('user-table'); table.reload('comment-table');
} }

View File

@ -13,12 +13,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">
@ -89,10 +84,8 @@
<script src="/static/component/layui/layui.js"></script> <script src="/static/component/layui/layui.js"></script>
<script src="/static/component/pear/pear.js"></script> <script src="/static/component/pear/pear.js"></script>
<script src="/static/addons/taonyeditor/tinymce/tinymce.min.js"></script> <script src="/static/addons/taonyeditor/tinymce/tinymce.min.js"></script>
<script src="/static/xm-select.js"></script>
<script> <script>
layui.extend({ layui.extend({
editor: '{/}/static/addons/taonyeditor/js/taonyeditor' editor: '{/}/static/addons/taonyeditor/js/taonyeditor'
}).use(["form", "colorpicker", "upload",'editor','xmSelect'], function () { }).use(["form", "colorpicker", "upload",'editor','xmSelect'], function () {
@ -120,6 +113,34 @@
$('[name="description"]').val(content); $('[name="description"]').val(content);
}); });
// 分类选择
$.get("{:url('content.forum/getCateList')}",function(res){
// 渲染下拉树
xmSelect.render({
el: '#CateId',
name: 'cate_id',
height: '250px',
layVerify: 'required',
layVerType: 'tips',
data: res.data,
initValue: [res.data[0].id],
model: {label: {type: 'text'}},
prop: {
name: 'catename',
value: 'id'
},
radio: true,
clickClose: true,
tree: {
show: true,
indent: 15,
strict: false,
expandedKeys: true
},
tips: '请选择'
});
});
// tag标签 // tag标签
$(function(){ $(function(){
//1.渲染标签 //1.渲染标签
@ -205,8 +226,12 @@
elem: "#zip-button", elem: "#zip-button",
url: "{:url('content.forum/uploads')}", //改成您自己的上传接口 url: "{:url('content.forum/uploads')}", //改成您自己的上传接口
data: { type: "zip" }, data: { type: "zip" },
accept: "file", //普通文件 accept: "file",
before: function(obj){
layer.load();
},
done: function (res) { done: function (res) {
layer.closeAll('loading');
if (res.status === 0) { if (res.status === 0) {
$('input[name="upzip"]').val(res.url); $('input[name="upzip"]').val(res.url);
layer.msg("上传成功"); layer.msg("上传成功");

View File

@ -14,12 +14,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">
@ -90,19 +85,18 @@
<script src="/static/component/layui/layui.js"></script> <script src="/static/component/layui/layui.js"></script>
<script src="/static/component/pear/pear.js"></script> <script src="/static/component/pear/pear.js"></script>
<script src="/static/addons/taonyeditor/tinymce/tinymce.min.js"></script> <script src="/static/addons/taonyeditor/tinymce/tinymce.min.js"></script>
<script src="/static/xm-select.js"></script>
<script> <script>
layui.extend({ layui.extend({
editor: '{/}/static/addons/taonyeditor/js/taonyeditor' editor: '{/}/static/addons/taonyeditor/js/taonyeditor'
}).use(['colorpicker','form','upload', 'editor'], function(){ }).use(['colorpicker','form','upload', 'editor','xmSelect'], function(){
var $ = layui.jquery var $ = layui.jquery
,colorpicker = layui.colorpicker ,colorpicker = layui.colorpicker
,form = layui.form ,form = layui.form
,upload = layui.upload; ,upload = layui.upload;
var artId = "{$article.id}"; var artId = "{$article.id}";
var editor = layui.editor; var editor = layui.editor;
var xmSelect = layui.xmSelect;
// 初始化编辑器 // 初始化编辑器
editor.render({ editor.render({
@ -152,6 +146,35 @@
$('[name="description"]').val(content); $('[name="description"]').val(content);
}); });
// 分类选择
$.get("{:url('content.forum/getCateList')}",function(res){
var INITCID = "{$article.cate_id}";
// 渲染下拉树
xmSelect.render({
el: '#CateId',
name: 'cate_id',
height: '250px',
layVerify: 'required',
layVerType: 'tips',
data: res.data,
initValue: [INITCID],
model: {label: {type: 'text'}},
prop: {
name: 'catename',
value: 'id'
},
radio: true,
clickClose: true,
tree: {
show: true,
indent: 15,
strict: false,
expandedKeys: true
},
tips: '请选择'
});
});
// 获取描述的内容 // 获取描述的内容
$("#L_content").bind('input propertychange', function(){ $("#L_content").bind('input propertychange', function(){
var content = $(this).val() var content = $(this).val()
@ -208,8 +231,12 @@
elem: '#zip-button' elem: '#zip-button'
,url: "{:url('content.forum/uploads')}" //改成您自己的上传接口 ,url: "{:url('content.forum/uploads')}" //改成您自己的上传接口
,data: {type:'zip'} ,data: {type:'zip'}
,accept: 'file' //普通文件 ,accept: 'file',
,done: function(res){ before: function(obj){
layer.load();
},
done: function(res){
layer.closeAll('loading');
if(res.status === 0){ if(res.status === 0){
$('input[name="upzip"]').val(res.url); $('input[name="upzip"]').val(res.url);
layer.msg('上传成功'); layer.msg('上传成功');

View File

@ -9,26 +9,32 @@
<div class="layui-card"> <div class="layui-card">
<div class="layui-card-body"> <div class="layui-card-body">
<form class="layui-form" action=""> <form class="layui-form" action="">
<div class="layui-form-item"> <div class="layui-row layui-col-space15 ">
<div class="layui-form-item layui-inline"> <div class="layui-col-md3">
<label class="layui-form-label">选择类目</label>
<div class="layui-input-block">
<div id="CateId" class="xm-select-demo"></div>
</div>
</div>
<div class="layui-col-md3">
<label class="layui-form-label">帖子ID</label> <label class="layui-form-label">帖子ID</label>
<div class="layui-input-block"> <div class="layui-input-block">
<input type="text" name="id" placeholder="请输入" autocomplete="off" class="layui-input"> <input type="text" name="id" placeholder="请输入" autocomplete="off" class="layui-input">
</div> </div>
</div> </div>
<div class="layui-form-item layui-inline"> <div class="layui-col-md3">
<label class="layui-form-label">发帖人</label> <label class="layui-form-label">发帖人</label>
<div class="layui-input-block"> <div class="layui-input-block">
<input type="text" name="name" placeholder="请输入" autocomplete="off" class="layui-input"> <input type="text" name="name" placeholder="请输入" autocomplete="off" class="layui-input">
</div> </div>
</div> </div>
<div class="layui-form-item layui-inline"> <div class="layui-col-md3">
<label class="layui-form-label">标题</label> <label class="layui-form-label">标题</label>
<div class="layui-input-block"> <div class="layui-input-block">
<input type="text" name="title" placeholder="请输入" autocomplete="off" class="layui-input"> <input type="text" name="title" placeholder="请输入" autocomplete="off" class="layui-input">
</div> </div>
</div> </div>
<div class="layui-form-item layui-inline"> <div class="layui-col-md3">
<label class="layui-form-label">状态</label> <label class="layui-form-label">状态</label>
<div class="layui-input-block"> <div class="layui-input-block">
<select name="sec"> <select name="sec">
@ -42,7 +48,7 @@
</select> </select>
</div> </div>
</div> </div>
<div class="layui-form-item layui-inline"> <div class="layui-col-md3">
<button class="pear-btn pear-btn-md pear-btn-primary" lay-submit lay-filter="forum-query"> <button class="pear-btn pear-btn-md pear-btn-primary" lay-submit lay-filter="forum-query">
<i class="layui-icon layui-icon-search"></i> <i class="layui-icon layui-icon-search"></i>
查询 查询
@ -100,12 +106,13 @@
<script> <script>
const FORUM_List = "{:url('content.forum/list')}"; const FORUM_List = "{:url('content.forum/list')}";
layui.use(['toast','jquery','form', 'table','common'], function(){ layui.use(['toast','jquery','form', 'table','common','xmSelect'], function(){
var $ = layui.jquery var $ = layui.jquery
,form = layui.form ,form = layui.form
,table = layui.table; ,table = layui.table;
let common = layui.common; let common = layui.common;
var toast = layui.toast; var toast = layui.toast;
var xmSelect = layui.xmSelect;
//如果你是采用模版自带的编辑器,你需要开启以下语句来解析。 //如果你是采用模版自带的编辑器,你需要开启以下语句来解析。
var taonystatus = "{:hook('taonystatus')}"; var taonystatus = "{:hook('taonystatus')}";
@ -120,6 +127,7 @@
,{field: 'avatar', title: '头像', width: 60, templet: '#avatarTpl'} ,{field: 'avatar', title: '头像', width: 60, templet: '#avatarTpl'}
,{field: 'poster', title: '账号',width: 80} ,{field: 'poster', title: '账号',width: 80}
,{field: 'title', title: '标题', minWidth: 180,templet: '<div><a href="{{- d.url }}" target="_blank">{{- d.title }}</a></div>'} ,{field: 'title', title: '标题', minWidth: 180,templet: '<div><a href="{{- d.url }}" target="_blank">{{- d.title }}</a></div>'}
,{field: 'cate', title: '类别', width: 120}
,{field: 'content', title: '内容', 'escape':false, minWidth: 200} ,{field: 'content', title: '内容', 'escape':false, minWidth: 200}
,{field: 'posttime', title: '时间',width: 120, sort: true} ,{field: 'posttime', title: '时间',width: 120, sort: true}
,{field: 'top', title: '置顶', templet: '#forum-istop', width: 80, align: 'center'} ,{field: 'top', title: '置顶', templet: '#forum-istop', width: 80, align: 'center'}
@ -144,6 +152,38 @@
}, 'filter', 'print', 'exports'] }, 'filter', 'print', 'exports']
}); });
// 动态分类
function getSelectCate() {
// 分类选择
$.get("{:url('content.forum/getCateList')}", function(res){
// 渲染下拉树
xmSelect.render({
el: '#CateId',
name: 'cate_id',
height: '250px',
layVerify: 'required',
layVerType: 'tips',
data: res.data,
initValue: [res.data[0].id],
model: {label: {type: 'text'}},
prop: {
name: 'catename',
value: 'id'
},
radio: true,
clickClose: true,
tree: {
show: true,
indent: 15,
strict: false,
expandedKeys: true
},
tips: '请选择'
});
});
}
getSelectCate();
table.on('tool(forum-table)', function(obj) { table.on('tool(forum-table)', function(obj) {
if (obj.event === 'remove') { if (obj.event === 'remove') {
window.remove(obj); window.remove(obj);
@ -269,9 +309,7 @@
} }
window.batchRemove = function(obj) { window.batchRemove = function(obj) {
var checkIds = common.checkField(obj,'id'); var checkIds = common.checkField(obj,'id');
if (checkIds === "") { if (checkIds === "") {
layer.msg("未选中数据", { layer.msg("未选中数据", {
icon: 3, icon: 3,
@ -280,25 +318,25 @@
return false; return false;
} }
layer.confirm('确定要删除这些用户', { layer.confirm('确定要删除?', {
icon: 3, icon: 3,
title: '提示' title: '提示'
}, function(index) { }, function(index) {
layer.close(index); layer.close(index);
let loading = layer.load(); let loading = layer.load();
$.ajax({ $.ajax({
url: "{:url('system.admin/delete')}", url: "{:url('content.forum/delete')}?id=" + checkIds,
dataType: 'json', dataType: 'json',
type: 'delete', type: 'delete',
data:{"id":checkIds}, data:{"id":checkIds},
success: function(result) { success: function(result) {
layer.close(loading); layer.close(loading);
if (result.success) { if (result.code === 0) {
layer.msg(result.msg, { layer.msg(result.msg, {
icon: 1, icon: 1,
time: 1000 time: 1000
}, function() { }, function() {
table.reload('user-table'); table.reload('forum-table');
}); });
} else { } else {
layer.msg(result.msg, { layer.msg(result.msg, {
@ -312,7 +350,7 @@
} }
window.refresh = function(param) { window.refresh = function(param) {
table.reload('user-table'); table.reload('forum-table');
} }
}); });

View File

@ -76,6 +76,7 @@
layui.use(['form', 'jquery'], function() { layui.use(['form', 'jquery'], function() {
let form = layui.form; let form = layui.form;
let $ = layui.jquery; let $ = layui.jquery;
let upload = layui.upload;
form.on('submit(user-save)', function(data) { form.on('submit(user-save)', function(data) {
$.ajax({ $.ajax({
@ -103,6 +104,33 @@
}) })
return false; return false;
}); });
//上传头像
upload.render({
elem: '#layuiadmin-upload-useradmin'
,url: "{:url('user.user/uploadImg')}"
,data: {type:'image'}
,accept: 'images'
,method: 'get'
,acceptMime: 'image/*'
,done: function(res){
$(this.item).prev("div").children("input").val(res.src);
if(res.code === 0){
layer.msg(res.msg,{
icon:6,
tiye:2000
});
} else {
layer.open({
title:"上传失败",
content:res.msg,
icon:5,
anim:6
});
}
}
});
}) })
</script> </script>
<script> <script>

View File

@ -212,8 +212,7 @@
{ {
title: '注册', title: '注册',
field: 'jointime', field: 'jointime',
align: 'center', align: 'center'
templet: '#user-createTime'
}, },
{ {
title: '操作', title: '操作',

View File

@ -79,12 +79,14 @@ if(!function_exists('getUserImg'))
function getArtContent($content) function getArtContent($content)
{ {
//过滤html标签 //过滤html标签
$content = strip_tags($content); // $content = strip_tags($content);
// 去除所有& nbsp和html标签
$content = preg_replace("/(\s|\&nbsp\;|\&ldquo\;|\&rdquo\;| |\xc2\xa0)/", "", strip_tags($content));
// 过滤音视频图片 // 过滤音视频图片
$content = preg_replace('/(?:img|audio|video)(\(\S+\))?\[\S+\]/','',$content); $content = preg_replace('/(?:img|audio|video)(\(\S+\))?\[\S+\]/','',$content);
$content = preg_replace('/\s*/','',$content); $content = preg_replace('/\s*/','',$content);
$content = preg_replace('/\[[^\]]+\]/','',$content); $content = preg_replace('/\[[^\]]+\]/','',$content);
return mb_substr(strip_tags($content),0,150).'...'; return mb_substr($content,0,150).'...';
} }
//根据帖子收藏主键ID查询帖子名称 //根据帖子收藏主键ID查询帖子名称

View File

@ -18,7 +18,6 @@ use think\facade\Db;
use think\facade\Session; use think\facade\Session;
use think\facade\Cache; use think\facade\Cache;
use app\BaseController as BaseCtrl; use app\BaseController as BaseCtrl;
use app\common\model\Cate;
/** /**
* 控制器基础类 * 控制器基础类
@ -39,8 +38,6 @@ class BaseController extends BaseCtrl
//变量赋给模板 //变量赋给模板
View::assign([ View::assign([
//显示分类导航
'cateList' => $this->showNav(),
//显示子分类导航 //显示子分类导航
'subcatelist' => $this->showSubnav(), 'subcatelist' => $this->showSubnav(),
//当前登录用户 //当前登录用户
@ -65,23 +62,9 @@ class BaseController extends BaseCtrl
} }
} }
// 显示导航nav
protected function showNav()
{
//1.查询分类表获取所有分类
$cate = new Cate();
$cateList = $cate->menu();
$list = getTree($cateList);
// 排序
$cmf_arr = array_column($list, 'sort');
array_multisort($cmf_arr, SORT_ASC, $list);
return $list;
}
// 显示子导航subnav // 显示子导航subnav
protected function showSubnav() protected function showSubnav()
{ {
// dump($this->showNav());
//1.查询父分类id //1.查询父分类id
$pCate = Db::name('cate')->field('id,pid,ename,catename,is_hot')->where(['ename'=>input('ename'),'status'=>1,'delete_time'=>0])->find(); $pCate = Db::name('cate')->field('id,pid,ename,catename,is_hot')->where(['ename'=>input('ename'),'status'=>1,'delete_time'=>0])->find();

View File

@ -4,6 +4,7 @@ declare (strict_types = 1);
namespace app\common\lib; namespace app\common\lib;
use think\facade\Lang; use think\facade\Lang;
use think\Response;
class Msgres class Msgres
{ {
@ -66,13 +67,13 @@ class Msgres
} }
/** /**
* 成功提示
* @param string $strMsg * @param string $strMsg
* @param string|null $url * @param string|null $url
* @param string $data * @param array|$data
* @return string|\think\response\Json * @return Response
*/ */
public static function success(string $strMsg = '',string $url = null, $data = '') { public static function success(string $strMsg = '',string $url = null, array $data = []): Response
{
$result = [ $result = [
'code' => self::getCode('success'), 'code' => self::getCode('success'),
'msg' => self::getMsg($strMsg), 'msg' => self::getMsg($strMsg),

View File

@ -93,7 +93,7 @@ class Uploads
} }
// 解析存储位置 SYS_开头为系统位置 // 解析存储位置 SYS_开头为系统位置
$isSys = stripos($dirName, 'SYS_'); $isSys = stripos($dirName, 'SYS_');
if($isSys !== false) { if($isSys) {
$disk = 'sys'; $disk = 'sys';
$dirName = substr($dirName,4); $dirName = substr($dirName,4);
$uploadDir = Config::get('filesystem.disks.sys.url'); $uploadDir = Config::get('filesystem.disks.sys.url');
@ -105,7 +105,7 @@ class Uploads
$rules = ['md5','date','sha1','uniqid']; $rules = ['md5','date','sha1','uniqid'];
// 解析是否自定义文件名 // 解析是否自定义文件名
if(!in_array($rule, $rules) && !is_null($rule)) { if(!in_array($rule, $rules) && !is_null($rule)) {
if(stripos($rule, '.') == false) { if(!stripos($rule, '.')) {
$rule = $file->getOriginalName(); $rule = $file->getOriginalName();
} }
$savename = Filesystem::disk($disk)->putFileAs($dirName, $file, $rule); $savename = Filesystem::disk($disk)->putFileAs($dirName, $file, $rule);
@ -160,7 +160,7 @@ class Uploads
// 解析存储位置 SYS_开头为系统位置 // 解析存储位置 SYS_开头为系统位置
$isSys = stripos($dirName, 'SYS_'); $isSys = stripos($dirName, 'SYS_');
if($isSys !== false) { if($isSys) {
$disk = 'sys'; $disk = 'sys';
$dirName = substr($dirName,4); $dirName = substr($dirName,4);
$uploadDir = Config::get('filesystem.disks.sys.url'); $uploadDir = Config::get('filesystem.disks.sys.url');

View File

@ -389,7 +389,7 @@ class Article extends Model
$query->field('id,name,user_img'); $query->field('id,name,user_img');
}, },
'cate' => function($query){ 'cate' => function($query){
$query->field('id,ename'); $query->field('id,ename,catename');
} }
]) ])
->where($where) ->where($where)

View File

@ -46,6 +46,12 @@ class Cate extends Model
return $this->field('ename,catename')->where('pid', $this::where('ename', $ename)->value('id'))->select(); return $this->field('ename,catename')->where('pid', $this::where('ename', $ename)->value('id'))->select();
} }
// 查询兄弟分类
public function getBrotherCate(string $ename)
{
return $this->field('id,ename,catename')->where('pid', $this::where('ename', $ename)->value('pid'))->append(['url'])->order('sort asc')->select();
}
/** /**
* 删除分类 * 删除分类
* @param $id * @param $id
@ -93,6 +99,24 @@ class Cate extends Model
} }
// 分类导航菜单
public function getNav()
{
try {
$cateList = $this->where(['status' => 1])
->cache('catename', 3600)
->append(['url'])
->select()
->toArray();
// 排序
$cmf_arr = array_column($cateList, 'sort');
array_multisort($cmf_arr, SORT_ASC, $cateList);
return getTree($cateList);
} catch (DbException $e) {
return $e->getMessage();
}
}
// 获取url // 获取url
public function getUrlAttr($value,$data) public function getUrlAttr($value,$data)
{ {

View File

@ -35,11 +35,28 @@ class Comment extends Model
//获取评论 //获取评论
public function getComment($id, $page) public function getComment($id, $page)
{ {
return $this::with(['user']) $comment = $this::withTrashed()->with(['user'=>function($query){
$query->field('id,name,user_img,sign,city,vip');
}])
->where(['article_id'=>(int)$id,'status'=>1]) ->where(['article_id'=>(int)$id,'status'=>1])
->order(['cai'=>'asc','create_time'=>'asc']) ->order(['cai'=>'asc','create_time'=>'asc'])
->paginate(['list_rows'=>10, 'page'=>$page]) // ->paginate(['list_rows'=>10, 'page'=>$page])
->append(['touser'])
->select()
->toArray(); ->toArray();
// halt($comment);
if(count($comment)) {
$data['data'] = getTree($comment);
$data['total'] = count($data['data']);
$arr = array_chunk($data['data'], 10);
//当前页
$page = $page - 1;
return ['total' => $data['total'], 'data' => $arr[$page]];
} else {
return ['total' => 0, 'data' => ''];
}
} }
//回帖榜 //回帖榜
@ -154,5 +171,30 @@ class Comment extends Model
return (string) url('detail',['id' => $data['id']]); return (string) url('detail',['id' => $data['id']]);
} }
} }
// 获取to_user_id
public function getTouserAttr($value,$data)
{
if(isset($data['to_user_id'])) {
return User::where('id', $data['to_user_id'])->value('name');
}
return '';
}
/**
* 评论下有评论且自身已删除,会显示为 评论已删除,评论下无评论且已删除则不显示
* @param $value
* @param $data
* @return string
*/
public function getContentAttr($value,$data)
{
if($data['delete_time'] !== 0) {
if($this::getByPid($data['id'])) {
return '<span style="text-decoration:line-through;">评论已删除</span>';
}
}
return $value;
}
} }

View File

@ -51,9 +51,9 @@ class User extends Model
public function login($data) public function login($data)
{ {
//查询使用邮箱或者用户名登陆 //查询使用邮箱或者用户名登陆
$user = $this::whereOr('email',$data['name'])->whereOr('name',$data['name'])->findOrEmpty(); $user = $this::whereOr('phone',$data['name'])->whereOr('email',$data['name'])->whereOr('name',$data['name'])->findOrEmpty();
if(!($user->isEmpty())){ if(!$user->isEmpty()){
//被禁用和待审核 //被禁用和待审核
if($user['status'] == -1){ if($user['status'] == -1){
return Lang::get('Account disabled'); return Lang::get('Account disabled');

View File

@ -11,34 +11,27 @@
namespace app\common\model; namespace app\common\model;
use think\Model; use think\Model;
//use think\model\concern\SoftDelete;
class UserZan extends Model class UserZan extends Model
{ {
protected $autoWriteTimestamp = true; //开启自动时间戳 protected $autoWriteTimestamp = true; //开启自动时间戳
protected $createTime = 'create_time'; protected $createTime = 'create_time';
//软删除
//use SoftDelete;
//protected $deleteTime = 'delete_time';
//protected $defaultSoftDelete = 0;
public function comment() public function comment()
{ {
//评论关联文章 //关联评论
return $this->belongsTo('Comment','comment_id','id'); return $this->belongsTo('Comment','comment_id','id');
} }
public function user() public function user()
{ {
//评论关联用户 //关联用户
return $this->belongsTo('User','user_id','id'); return $this->belongsTo('User','user_id','id');
} }
public function article() public function article()
{ {
//评论关联用户 //关联文章
return $this->belongsTo(Article::class); return $this->belongsTo(Article::class);
} }

View File

@ -8,7 +8,7 @@
* @FilePath: \TaoLer\app\common\taglib\Article.php * @FilePath: \TaoLer\app\common\taglib\Article.php
* Copyright (c) 2020~2022 https://www.aieok.com All rights reserved. * Copyright (c) 2020~2022 https://www.aieok.com All rights reserved.
*/ */
//declare (strict_types = 1); declare (strict_types = 1);
namespace app\common\taglib; namespace app\common\taglib;
@ -42,6 +42,7 @@ class Article extends TagLib
'istop' => ['attr' => '', 'close' => 0], 'istop' => ['attr' => '', 'close' => 0],
'detail' => ['attr' => 'name', 'close' => 0], 'detail' => ['attr' => 'name', 'close' => 0],
// 'detail' => ['attr' => '', 'close' => 0],
]; ];
@ -145,12 +146,24 @@ class Article extends TagLib
return '{$article.cate.id}'; return '{$article.cate.id}';
} }
// 详情
// public function tagDetail($tag)
// {
// return '{$article.' . $tag['name'] . '}';
// }
// 详情 // 详情
public function tagDetail($tag) public function tagDetail($tag)
{ {
return '{$article.' . $tag['name'] . '}'; $parseStr = '{assign name="id" value="$Request.param.id" /}';
$parseStr .= '<?php ';
$parseStr .= '$__article__ = \app\facade\Article::find($id);';
$parseStr .= ' ?>';
$parseStr .= '{$__article__.'. $tag['name'] .'}';
return $parseStr;
} }
public function tagIstop($tag): string public function tagIstop($tag): string
{ {
//dump($this->article); //dump($this->article);
@ -163,16 +176,27 @@ class Article extends TagLib
} }
// 评论 // 评论
public function tagComment($tag, $content): string public function tagComment2($tag, $content): string
{ {
$parse = '<?php '; $parse = '<?php ';
$parse .= ' ?>'; $parse .= ' ?>';
$parse .= '{volist name="comments['.'\'data\''.']" id="comment" empty= "还没有内容"}'; $parse .= '{volist name="comments" id="comment" empty= "还没有内容"}';
$parse .= $content; $parse .= $content;
$parse .= '{/volist}'; $parse .= '{/volist}';
return $parse; return $parse;
} }
// 评论
public function tagComment($tag, $content): string
{
$parse = '<?php ';
$parse .= ' ?>';
$parse .= '{volist name="comments['.'\'data\''.']" id="comment" empty= "还没有内容"}';
$parse .= $content;
$parse .= '{/volist}';
return $parse;
}
// 分类列表 // 分类列表
public function tagList($tag, $content): string public function tagList($tag, $content): string
{ {

View File

@ -14,8 +14,45 @@ use think\template\TagLib;
class Cate extends TagLib class Cate extends TagLib
{ {
protected $tag = [ protected $tags = [
'brother' => ['attr' => '', 'close' => 1],
'bro_name' => ['attr' => '', 'close' => 0],
'bro_ename' => ['attr' => '', 'close' => 0],
'bro_url' => ['attr' => '', 'close' => 0],
'list' => ['attr' => '', 'close' => 1]
]; ];
public function tagBrother($tag, $content): string
{
$parse = '{assign name="ename" value="$Request.param.ename" /}';
$parse .= '{php}$__brotherCate__ = \app\facade\Cate::getBrotherCate($ename);{/php}';
$parse .= '{volist name="__brotherCate__" id="brother"}';
$parse .= $content;
$parse .= '{/volist}';
return $parse;
}
public function tagBro_name($tag): string
{
return '{$brother.catename}';
}
public function tagBro_ename($tag): string
{
return '{$brother.ename}';
}
public function tagBro_url($tag): string
{
return '{$brother.url}';
}
public function tagList($tag, $content): string
{
//$paras = ;
}
} }

View File

@ -35,7 +35,7 @@ class System extends TagLib
'icp' => ['attr' => '', 'close' => 0], 'icp' => ['attr' => '', 'close' => 0],
'showlist' => ['attr' => '', 'close' => 0], 'showlist' => ['attr' => '', 'close' => 0],
'blackname' => ['attr' => '', 'close' => 0], 'blackname' => ['attr' => '', 'close' => 0],
'sys_version_num' => ['attr' => '', 'close' => 0], 'sys_version_num'=> ['attr' => '', 'close' => 0],
'key' => ['attr' => '', 'close' => 0], 'key' => ['attr' => '', 'close' => 0],
'clevel' => ['attr' => '', 'close' => 0], 'clevel' => ['attr' => '', 'close' => 0],
'api_url' => ['attr' => '', 'close' => 0], 'api_url' => ['attr' => '', 'close' => 0],

View File

@ -16,7 +16,7 @@ class Taoler extends TagLib
{ {
protected $tags = [ protected $tags = [
// 标签定义: attr 属性列表 close 是否闭合0 或者1 默认1 alias 标签别名 level 嵌套层次 // 标签定义: attr 属性列表 close 是否闭合0 或者1 默认1 alias 标签别名 level 嵌套层次
'nav' => ['attr' => '', 'close' => 1], 'nav' => ['attr' => '', 'close' => 1],
'snav' => ['attr' => '', 'close' => 1], 'snav' => ['attr' => '', 'close' => 1],
'gnav' => ['attr' => '', 'close' => 1], 'gnav' => ['attr' => '', 'close' => 1],
'if' => ['condition', 'expression' => true, 'close' => 1], 'if' => ['condition', 'expression' => true, 'close' => 1],
@ -26,7 +26,8 @@ class Taoler extends TagLib
public function tagNav($tag, $content): string public function tagNav($tag, $content): string
{ {
$id = $tag['id'] ?? 'nav'; $id = $tag['id'] ?? 'nav';
$parse = '{volist name="cateList" id="'.$id.'"}'; $parse = '{php}$__cate__ = \app\facade\Cate::getNav();{/php}';
$parse .= '{volist name="__cate__" id="'.$id.'"}';
$parse .= $content; $parse .= $content;
$parse .= '{/volist}'; $parse .= '{/volist}';
return $parse; return $parse;
@ -35,18 +36,22 @@ class Taoler extends TagLib
public function tagSnav($tag, $content): string public function tagSnav($tag, $content): string
{ {
$id = $tag['id'] ?? 'snav'; $id = $tag['id'] ?? 'snav';
$parse = '{volist name="nav.children" id="'.$id.'"}'; $parse = '{notempty name="nav.children"}';
$parse .= '{volist name="nav.children" id="'.$id.'"}';
$parse .= $content; $parse .= $content;
$parse .= '{/volist}'; $parse .= '{/volist}';
$parse .= '{/notempty}';
return $parse; return $parse;
} }
public function tagGnav($tag, $content): string public function tagGnav($tag, $content): string
{ {
$id = $tag['id'] ?? 'gnav'; $id = $tag['id'] ?? 'gnav';
$parse = '{volist name="snav.children" id="'.$id.'"}'; $parse = '{notempty name="snav.children"}';
$parse .= '{volist name="snav.children" id="'.$id.'"}';
$parse .= $content; $parse .= $content;
$parse .= '{/volist}'; $parse .= '{/volist}';
$parse .= '{/notempty}';
return $parse; return $parse;
} }

View File

@ -17,6 +17,7 @@ class User extends Validate
protected $rule = [ protected $rule = [
'name|用户名' => 'require|min:2|max:18|chsDash|unique:user', 'name|用户名' => 'require|min:2|max:18|chsDash|unique:user',
'email|邮箱' => 'require|email|unique:user', 'email|邮箱' => 'require|email|unique:user',
'phone|手机号' => 'require|mobile|unique:user',
'password|密码' => 'require|min:6|max:20', 'password|密码' => 'require|min:6|max:20',
'repassword|确认密码'=>'require|confirm:password', 'repassword|确认密码'=>'require|confirm:password',
'nickname|昵称' => 'require|min:2|max:20', 'nickname|昵称' => 'require|min:2|max:20',
@ -48,11 +49,23 @@ class User extends Validate
->remove('email', 'unique'); ->remove('email', 'unique');
} }
//注册验证场景 //phone登陆验证场景
public function sceneLoginPhone()
{
return $this->only(['phone','password'])
->remove('phone', 'unique');
}
//注册验证场景
public function sceneReg() public function sceneReg()
{ {
return $this->only(['name','email','password','repassword']); return $this->only(['name','email','password','repassword']);
}
//后台注册验证场景
public function sceneUserReg()
{
return $this->only(['name','email','phone','password']);
} }
//密码找回 //密码找回

View File

@ -43,6 +43,8 @@ return [
'view_dir_name' => 'view' . DIRECTORY_SEPARATOR . $template, 'view_dir_name' => 'view' . DIRECTORY_SEPARATOR . $template,
// 模板后缀 // 模板后缀
'view_suffix' => 'html', 'view_suffix' => 'html',
// 定义内置标签
//'taglib_build_in' => 'app\common\taglib\Article',
// 预先加载的标签库 // 预先加载的标签库
'taglib_pre_load' => $taglib_pre_load, 'taglib_pre_load' => $taglib_pre_load,
// 模板文件名分隔符 // 模板文件名分隔符

View File

@ -1 +1,2 @@
Api.php Api.php
Works.php

View File

@ -76,21 +76,16 @@ class Article extends BaseController
$page = input('page',1); $page = input('page',1);
//输出内容 //输出内容
$artDetail = $this->model->getArtDetail($id); $artDetail = $this->model->getArtDetail($id);
if(is_null($artDetail)){
throw new \think\exception\HttpException(404, '无内容');
}
//加密
if($artDetail->read_type == 1 && session('art_pass_'.$id) != $artDetail->art_pass) { if($artDetail->read_type == 1 && session('art_pass_'.$id) != $artDetail->art_pass) {
$artDetail->content = '本文已加密!请输入正确密码查看!'; $artDetail->content = '本文已加密!请输入正确密码查看!';
} }
//被赞
if(is_null($artDetail)){ $zanCount = Db::name('user_zan')->where('user_id', $artDetail['user_id'])->count('id');
// 抛出 HTTP 异常
throw new \think\exception\HttpException(404, '无内容');
}
//用户个人tag标签
$userTags = $this->model->where(['user_id' => $artDetail['user_id'],'status'=>1])->where('keywords','<>','')->column('keywords');
//转换为字符串
$tagStr = implode(",",$userTags);
//转换为数组并去重
$tagArr = array_unique(explode(",",$tagStr));
$userTagCount = count($tagArr);
//赞列表 //赞列表
$userZanList = []; $userZanList = [];
@ -162,9 +157,9 @@ class Article extends BaseController
'cid' => $id, 'cid' => $id,
'lrDate_time' => $lrDate_time, 'lrDate_time' => $lrDate_time,
'userZanList' => $userZanList, 'userZanList' => $userZanList,
'userTagCount'=> $userTagCount, 'zanCount' => $zanCount,
'jspage' => 'jie', 'jspage' => 'jie',
'passJieMi' => session('art_pass_'.$id), 'passJieMi' => session('art_pass_'.$id),
$download, $download,
]); ]);
@ -186,8 +181,10 @@ class Article extends BaseController
if (Request::isAjax()){ if (Request::isAjax()){
//获取评论 //获取评论
$data = Request::only(['content','article_id','user_id']); $data = Request::only(['content','article_id','pid','to_user_id']);
$data['user_id'] = $this->uid;
$sendId = $data['user_id']; $sendId = $data['user_id'];
// halt($data);
$art = Db::name('article')->field('id,status,is_reply,delete_time')->find($data['article_id']); $art = Db::name('article')->field('id,status,is_reply,delete_time')->find($data['article_id']);
if($art['delete_time'] != 0 || $art['status'] != 1 || $art['is_reply'] != 1){ if($art['delete_time'] != 0 || $art['status'] != 1 || $art['is_reply'] != 1){
@ -616,15 +613,22 @@ class Article extends BaseController
/** /**
* 分类树 * 分类树
* @return \think\response\Json * @return \think\response\Json
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/ */
public function getCateTree() public function getCateTree()
{ {
$data = $this->showNav(); $cateList = Cate::field('id,pid,catename,sort')->where(['status' => 1])->select()->toArray();
$count = count($data); $list = getTree($cateList);
// 排序
$cmf_arr = array_column($list, 'sort');
array_multisort($cmf_arr, SORT_ASC, $list);
$count = count($list);
$tree = []; $tree = [];
if($count){ if($count){
$tree = ['code'=>0, 'msg'=>'ok','count'=>$count]; $tree = ['code'=>0, 'msg'=>'ok','count'=>$count];
$tree['data'] = $data; $tree['data'] = $list;
} }
return json($tree); return json($tree);

View File

@ -31,7 +31,7 @@ class Index extends BaseController
$types = input('type'); $types = input('type');
//置顶文章 //置顶文章
$artTop = Article::getArtTop(5); $artTop = Article::getArtTop(5);
//首页文章列表,显示20 //首页文章列表,显示15
$artList = Article::getArtList(15); $artList = Article::getArtList(15);
//热议文章 //热议文章
$artHot = Article::getArtHot(10); $artHot = Article::getArtHot(10);

View File

@ -54,8 +54,24 @@ class Login extends BaseController
//邮箱正则表达式 //邮箱正则表达式
$pattern = "/^([0-9A-Za-z\\-_\\.]+)@([0-9a-z]+\\.[a-z]{2,3}(\\.[a-z]{2})?)$/i"; $pattern = "/^([0-9A-Za-z\\-_\\.]+)@([0-9a-z]+\\.[a-z]{2,3}(\\.[a-z]{2})?)$/i";
//判断输入的是邮箱还是用户名
if (preg_match($pattern, $data['name'])){ if(preg_match("/^1[34578]\d{9}$/",$data['name']))
{
//手机验证登录
$data['phone'] = $data['name'];
unset($data['name']);
try{
validate(userValidate::class)
->scene('loginPhone')
->check($data);
} catch (ValidateException $e) {
// 验证失败 输出错误信息
return json(['code'=>-1,'msg'=>$e->getError()]);
}
$data['name'] = $data['phone'];
unset($data['phone']);
} elseif (preg_match($pattern, $data['name'])){
//输入邮箱email登陆验证 //输入邮箱email登陆验证
$data['email'] = $data['name']; $data['email'] = $data['name'];
unset($data['name']); unset($data['name']);
@ -89,7 +105,7 @@ class Login extends BaseController
return Msgres::error($res); return Msgres::error($res);
} }
} }
return View::fetch('login'); return View::fetch('login');
} }

View File

@ -30,7 +30,7 @@ return [
'index' => 'index', 'index' => 'index',
'home page' => '首页', 'home page' => '首页',
'user center' => '用户中心', 'user center' => '用户中心',
'set info' => '设置', 'set info' => '个人设置',
'my message' => '我的消息', 'my message' => '我的消息',
'my page' => '我的主页', 'my page' => '我的主页',

View File

@ -1 +1,2 @@
myroute.php myroute.php
a.php

View File

@ -9,6 +9,7 @@
* Copyright (c) 2020~2022 https://www.aieok.com All rights reserved. * Copyright (c) 2020~2022 https://www.aieok.com All rights reserved.
*/ */
use think\facade\Route; use think\facade\Route;
use think\facade\Request;
//详情页URL别称 //详情页URL别称
$detail_as = config('taoler.url_rewrite.article_as'); $detail_as = config('taoler.url_rewrite.article_as');
@ -68,19 +69,24 @@ Route::group('art',function () use($detail_as,$cate_as){
Route::get('tag','tag/getAllTag')->name('get_all_tag'); Route::get('tag','tag/getAllTag')->name('get_all_tag');
Route::get('arttag','tag/getArticleTag')->name('get_art_tag'); Route::get('arttag','tag/getArticleTag')->name('get_art_tag');
Route::rule('search/[:keywords]', 'index/search'); // 搜索
// article分类和详情路由 !放到最后!
Route::group(function () use($detail_as, $cate_as){ Route::group(function () use($detail_as, $cate_as){
// 动态路径路由会影响下面的路由,所以动态路由放下面 // 动态路径路由会影响下面的路由,所以动态路由放下面
Route::get($detail_as . ':id$', 'article/detail')->name('article_detail'); Route::get($detail_as . ':id$', 'article/detail')->name('article_detail');
Route::get($detail_as . '<id>/<page>$', 'article/detail')->name('article_comment'); Route::get($detail_as . '<id>/<page>$', 'article/detail')->name('article_comment');
//分类
Route::get($cate_as . '<ename>$','article/cate')->name('cate'); Route::get($cate_as . '<ename>$','article/cate')->name('cate');
Route::get($cate_as . '<ename>/<type>$', 'article/cate')->name('cate_type'); Route::get($cate_as . '<ename>/<type>$', 'article/cate')->name('cate_type');
Route::get($cate_as . '<ename>/<type>/<page>$', 'article/cate')->name('cate_page'); Route::get($cate_as . '<ename>/<type>/<page>$', 'article/cate')->name('cate_page');
})->pattern([ })->pattern([
'ename' => '\w+', 'ename' => '[\w|\-]+',
'type' => '\w+', 'type' => '\w+',
'page' => '\d+', 'page' => '\d+',
'id' => '\d+', 'id' => '\d+',
]); ]);
Route::rule('search/[:keywords]', 'index/search'); // 搜索

View File

@ -5,7 +5,7 @@
Target Server Version : 80020 (8.0.20) Target Server Version : 80020 (8.0.20)
File Encoding : 65001 File Encoding : 65001
Date: 14/03/2023 19:57:43 Date: 8/06/2023 19:57:43
*/ */
SET NAMES utf8mb4; SET NAMES utf8mb4;
@ -313,36 +313,29 @@ CREATE TABLE `tao_collection` (
PRIMARY KEY (`id`) USING BTREE PRIMARY KEY (`id`) USING BTREE
) ENGINE = MyISAM AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '文章收藏表' ROW_FORMAT = Dynamic; ) ENGINE = MyISAM AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '文章收藏表' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of tao_collection
-- ----------------------------
-- ---------------------------- -- ----------------------------
-- Table structure for tao_comment -- Table structure for tao_comment
-- ---------------------------- -- ----------------------------
DROP TABLE IF EXISTS `tao_comment`; DROP TABLE IF EXISTS `tao_comment`;
CREATE TABLE `tao_comment` ( CREATE TABLE `tao_comment` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '评论id', `id` int NOT NULL AUTO_INCREMENT COMMENT '评论id',
`content` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '评论', `pid` int NOT NULL DEFAULT 0 COMMENT '父id',
`article_id` int NOT NULL COMMENT '文章id', `content` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '评论',
`user_id` int NOT NULL COMMENT '评论用户', `article_id` int NOT NULL COMMENT '文章id',
`zan` tinyint NOT NULL DEFAULT 0 COMMENT '', `user_id` int NOT NULL COMMENT '评论用户',
`cai` enum('1','0') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '0' COMMENT '0求解1采纳', `to_user_id` int NULL DEFAULT NULL COMMENT '给用户留言',
`status` enum('0','-1','1') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '1' COMMENT '1通过0待审-1禁止', `zan` tinyint NOT NULL DEFAULT 0 COMMENT '',
`create_time` int NOT NULL DEFAULT 0 COMMENT '创建时间', `cai` enum('1','0') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '0' COMMENT '0求解1采纳',
`update_time` int NOT NULL DEFAULT 0 COMMENT '更新时间', `status` enum('0','-1','1') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '1' COMMENT '1通过0待审-1禁止',
`delete_time` int NOT NULL DEFAULT 0 COMMENT '删除时间', `type` tinyint(1) NOT NULL DEFAULT 1 COMMENT '评论类型1帖子2其它',
`create_time` int NOT NULL DEFAULT 0 COMMENT '创建时间',
`update_time` int NOT NULL DEFAULT 0 COMMENT '更新时间',
`delete_time` int NOT NULL DEFAULT 0 COMMENT '删除时间',
PRIMARY KEY (`id`) USING BTREE, PRIMARY KEY (`id`) USING BTREE,
INDEX `aiticle_id`(`article_id` ASC) USING BTREE COMMENT '文章评论索引', INDEX `aiticle_id`(`article_id` ASC) USING BTREE COMMENT '文章评论索引',
INDEX `user_id`(`user_id` ASC) USING BTREE COMMENT '评论用户索引' INDEX `user_id`(`user_id` ASC) USING BTREE COMMENT '评论用户索引'
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '评论表' ROW_FORMAT = Dynamic; ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '评论表' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of tao_comment
-- ----------------------------
INSERT INTO `tao_comment` VALUES (1, 'https://www.aieok.com', 1, 1, 0, '0', '1', 1555127897, 1578977505, 0);
INSERT INTO `tao_comment` VALUES (2, 'face[嘻嘻] ddddd', 1, 1, 0, '0', '1', 1677900207, 1677975943, 1677975943);
INSERT INTO `tao_comment` VALUES (3, 'ddddfdfd', 1, 1, 0, '0', '1', 1677900215, 1677975943, 1677975943);
-- ---------------------------- -- ----------------------------
-- Table structure for tao_cunsult -- Table structure for tao_cunsult
@ -359,10 +352,6 @@ CREATE TABLE `tao_cunsult` (
PRIMARY KEY (`id`) USING BTREE PRIMARY KEY (`id`) USING BTREE
) ENGINE = MyISAM AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '反馈表' ROW_FORMAT = Dynamic; ) ENGINE = MyISAM AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '反馈表' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of tao_cunsult
-- ----------------------------
-- ---------------------------- -- ----------------------------
-- Table structure for tao_friend_link -- Table structure for tao_friend_link
-- ---------------------------- -- ----------------------------
@ -376,14 +365,12 @@ CREATE TABLE `tao_friend_link` (
`update_time` int NOT NULL COMMENT '更新时间', `update_time` int NOT NULL COMMENT '更新时间',
`delete_time` int NOT NULL, `delete_time` int NOT NULL,
PRIMARY KEY (`id`) USING BTREE PRIMARY KEY (`id`) USING BTREE
) ENGINE = MyISAM AUTO_INCREMENT = 4 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '友情链接' ROW_FORMAT = Dynamic; ) ENGINE = MyISAM AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '友情链接' ROW_FORMAT = Dynamic;
-- ---------------------------- -- ----------------------------
-- Records of tao_friend_link -- Records of tao_friend_link
-- ---------------------------- -- ----------------------------
INSERT INTO `tao_friend_link` VALUES (1, 'taobao', 'https://www.taobao.com', '', 0, 0, 0); INSERT INTO `tao_friend_link` VALUES (1, 'taoler', 'https://www.aieok.com', '', 0, 0, 0);
INSERT INTO `tao_friend_link` VALUES (2, 'baidu', 'https://www.baidu.com', '', 0, 0, 0);
INSERT INTO `tao_friend_link` VALUES (3, 'tensent', 'https://www.qq.com', '', 0, 0, 0);
-- ---------------------------- -- ----------------------------
-- Table structure for tao_mail_server -- Table structure for tao_mail_server
@ -421,13 +408,7 @@ CREATE TABLE `tao_message` (
`update_time` int NOT NULL DEFAULT 0 COMMENT '更新时间', `update_time` int NOT NULL DEFAULT 0 COMMENT '更新时间',
`delete_time` int NOT NULL DEFAULT 0 COMMENT '删除时间', `delete_time` int NOT NULL DEFAULT 0 COMMENT '删除时间',
PRIMARY KEY (`id`) USING BTREE PRIMARY KEY (`id`) USING BTREE
) ENGINE = MyISAM AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '消息表' ROW_FORMAT = Dynamic; ) ENGINE = MyISAM AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '消息表' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of tao_message
-- ----------------------------
INSERT INTO `tao_message` VALUES (1, '测试后台帖子', '评论通知', 1, 'http://www.tp6.com/index/ask/1.html', 2, 1677900207, 1677900207, 0);
INSERT INTO `tao_message` VALUES (2, '测试后台帖子', '评论通知', 1, 'http://www.tp6.com/index/ask/1.html', 2, 1677900215, 1677900215, 0);
-- ---------------------------- -- ----------------------------
-- Table structure for tao_message_to -- Table structure for tao_message_to
@ -444,13 +425,7 @@ CREATE TABLE `tao_message_to` (
`update_time` int NOT NULL DEFAULT 0 COMMENT '更新时间', `update_time` int NOT NULL DEFAULT 0 COMMENT '更新时间',
`delete_time` int NOT NULL DEFAULT 0 COMMENT '删除时间', `delete_time` int NOT NULL DEFAULT 0 COMMENT '删除时间',
PRIMARY KEY (`id`) USING BTREE PRIMARY KEY (`id`) USING BTREE
) ENGINE = MyISAM AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '消息详细表' ROW_FORMAT = Dynamic; ) ENGINE = MyISAM AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '消息详细表' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of tao_message_to
-- ----------------------------
INSERT INTO `tao_message_to` VALUES (1, 1, 1, '1', 2, 0, 1677900207, 1677900207, 0);
INSERT INTO `tao_message_to` VALUES (2, 1, 1, '2', 2, 0, 1677900215, 1677900215, 0);
-- ---------------------------- -- ----------------------------
-- Table structure for tao_push_jscode -- Table structure for tao_push_jscode
@ -467,10 +442,6 @@ CREATE TABLE `tao_push_jscode` (
PRIMARY KEY (`id`) USING BTREE PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '站长平台自动推送js代码' ROW_FORMAT = Dynamic; ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '站长平台自动推送js代码' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of tao_push_jscode
-- ----------------------------
-- ---------------------------- -- ----------------------------
-- Table structure for tao_slider -- Table structure for tao_slider
-- ---------------------------- -- ----------------------------
@ -489,13 +460,7 @@ CREATE TABLE `tao_slider` (
`update_time` int NOT NULL DEFAULT 0 COMMENT '更新时间', `update_time` int NOT NULL DEFAULT 0 COMMENT '更新时间',
`delete_time` int NOT NULL DEFAULT 0 COMMENT '删除时间', `delete_time` int NOT NULL DEFAULT 0 COMMENT '删除时间',
PRIMARY KEY (`id`) USING BTREE PRIMARY KEY (`id`) USING BTREE
) ENGINE = MyISAM AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; ) ENGINE = MyISAM AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of tao_slider
-- ----------------------------
INSERT INTO `tao_slider` VALUES (1, 'CODING', 1, '/storage/slider/F1.jpg', '#', '', 1574870400, 1575043200, '1', 0, 0, 0);
INSERT INTO `tao_slider` VALUES (2, '通用右栏底部广告', 2, '/storage/slider/20200101/851c0b88a72590293bcb45454bdce056.jpg', 'https://www.aieok.com', '', 1571155200, 1609344000, '1', 0, 0, 0);
-- ---------------------------- -- ----------------------------
-- Table structure for tao_system -- Table structure for tao_system
@ -556,10 +521,6 @@ CREATE TABLE `tao_tag` (
INDEX `ename`(`ename` ASC) USING BTREE COMMENT 'ename查询tag索引' INDEX `ename`(`ename` ASC) USING BTREE COMMENT 'ename查询tag索引'
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '文章tag表' ROW_FORMAT = Dynamic; ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '文章tag表' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of tao_tag
-- ----------------------------
-- ---------------------------- -- ----------------------------
-- Table structure for tao_taglist -- Table structure for tao_taglist
-- ---------------------------- -- ----------------------------
@ -655,10 +616,6 @@ CREATE TABLE `tao_user_sign` (
PRIMARY KEY (`id`) USING BTREE PRIMARY KEY (`id`) USING BTREE
) ENGINE = MyISAM AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '用户签到表' ROW_FORMAT = Fixed; ) ENGINE = MyISAM AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '用户签到表' ROW_FORMAT = Fixed;
-- ----------------------------
-- Records of tao_user_sign
-- ----------------------------
-- ---------------------------- -- ----------------------------
-- Table structure for tao_user_signrule -- Table structure for tao_user_signrule
-- ---------------------------- -- ----------------------------
@ -721,8 +678,4 @@ CREATE TABLE `tao_user_zan` (
PRIMARY KEY (`id`) USING BTREE PRIMARY KEY (`id`) USING BTREE
) ENGINE = MyISAM AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Fixed; ) ENGINE = MyISAM AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Fixed;
-- ----------------------------
-- Records of tao_user_zan
-- ----------------------------
SET FOREIGN_KEY_CHECKS = 1; SET FOREIGN_KEY_CHECKS = 1;

View File

@ -25,16 +25,18 @@ class UserLogin
*/ */
public function handle($user) public function handle($user)
{ {
$type = $user->user['type']; $type = $user->user['type'];
$id = $user->user['id']; $id = $user->user['id'];
$u = User::find($id); $u = User::find($id);
//日志 $ip = request()->ip();
if($type == 'log'){ $url = 'http://ip-api.com/json/' . $ip . '?lang=zh-CN&fields=57361';
//$name = $user->user['name']; $city = 'earth';
$ip = request()->ip();
$url = 'http://ip-api.com/json/' . $ip . '?lang=zh-CN&fields=57361'; //日志
$city = 'earth'; if($type == 'log'){
//$name = $user->user['name'];
try{ try{
$ipInfo = HttpHelper::get($url)->toJson(); $ipInfo = HttpHelper::get($url)->toJson();
if($ipInfo->status == 'success') if($ipInfo->status == 'success')
@ -61,21 +63,22 @@ class UserLogin
// $city = $arr[2]; // $city = $arr[2];
// } // }
// } // }
$u->allowField(['city','last_login_ip','last_login_time','login_error_num'])->save( }
[
'city' => $city, if($type == 'logError'){
'last_login_ip' => $ip, $u->allowField(['login_error_num','login_error_time'])->save(['login_error_num'=>$u->login_error_num + 1,'login_error_time'=>time()]);
'last_login_time' => time(), }
'login_error_num' => 0
] $u->allowField(['city','last_login_ip','last_login_time','login_error_num'])->save(
); [
Log::channel('login')->info('login:{user} {ip}',['user'=>$u->name,'ip'=>$ip]); 'city' => $city,
} 'last_login_ip' => $ip,
'last_login_time' => time(),
if($type == 'logError'){ 'login_error_num' => 0
$res = $u->allowField(['login_error_num','login_error_time'])->save(['login_error_num'=>$u->login_error_num + 1,'login_error_time'=>time()]); ]
} );
Log::channel('login')->info('login:{user} {ip}',['user'=>$u->name,'ip'=>$ip]);
} }
} }

43
composer.lock generated
View File

@ -506,16 +506,16 @@
}, },
{ {
"name": "guzzlehttp/promises", "name": "guzzlehttp/promises",
"version": "1.5.2", "version": "1.5.3",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/guzzle/promises.git", "url": "https://github.com/guzzle/promises.git",
"reference": "b94b2807d85443f9719887892882d0329d1e2598" "reference": "67ab6e18aaa14d753cc148911d273f6e6cb6721e"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/guzzle/promises/zipball/b94b2807d85443f9719887892882d0329d1e2598", "url": "https://api.github.com/repos/guzzle/promises/zipball/67ab6e18aaa14d753cc148911d273f6e6cb6721e",
"reference": "b94b2807d85443f9719887892882d0329d1e2598", "reference": "67ab6e18aaa14d753cc148911d273f6e6cb6721e",
"shasum": "", "shasum": "",
"mirrors": [ "mirrors": [
{ {
@ -531,11 +531,6 @@
"symfony/phpunit-bridge": "^4.4 || ^5.1" "symfony/phpunit-bridge": "^4.4 || ^5.1"
}, },
"type": "library", "type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.5-dev"
}
},
"autoload": { "autoload": {
"files": [ "files": [
"src/functions_include.php" "src/functions_include.php"
@ -576,7 +571,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/guzzle/promises/issues", "issues": "https://github.com/guzzle/promises/issues",
"source": "https://github.com/guzzle/promises/tree/1.5.2" "source": "https://github.com/guzzle/promises/tree/1.5.3"
}, },
"funding": [ "funding": [
{ {
@ -592,7 +587,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2022-08-28T14:55:35+00:00" "time": "2023-05-21T12:31:43+00:00"
}, },
{ {
"name": "guzzlehttp/psr7", "name": "guzzlehttp/psr7",
@ -2616,16 +2611,16 @@
}, },
{ {
"name": "topthink/framework", "name": "topthink/framework",
"version": "v6.1.2", "version": "v6.1.3",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/top-think/framework.git", "url": "https://github.com/top-think/framework.git",
"reference": "67235be5b919aaaf1de5aed9839f65d8e766aca3" "reference": "7c324e7011246f0064b055b62ab9c3921cf0a041"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/top-think/framework/zipball/67235be5b919aaaf1de5aed9839f65d8e766aca3", "url": "https://api.github.com/repos/top-think/framework/zipball/7c324e7011246f0064b055b62ab9c3921cf0a041",
"reference": "67235be5b919aaaf1de5aed9839f65d8e766aca3", "reference": "7c324e7011246f0064b055b62ab9c3921cf0a041",
"shasum": "", "shasum": "",
"mirrors": [ "mirrors": [
{ {
@ -2681,9 +2676,9 @@
], ],
"support": { "support": {
"issues": "https://github.com/top-think/framework/issues", "issues": "https://github.com/top-think/framework/issues",
"source": "https://github.com/top-think/framework/tree/v6.1.2" "source": "https://github.com/top-think/framework/tree/v6.1.3"
}, },
"time": "2023-02-08T02:24:01+00:00" "time": "2023-05-22T03:02:08+00:00"
}, },
{ {
"name": "topthink/think-captcha", "name": "topthink/think-captcha",
@ -2909,16 +2904,16 @@
}, },
{ {
"name": "topthink/think-multi-app", "name": "topthink/think-multi-app",
"version": "v1.0.16", "version": "v1.0.17",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/top-think/think-multi-app.git", "url": "https://github.com/top-think/think-multi-app.git",
"reference": "07b9183855150455e1f76f8cbe9d77d6d1bc399f" "reference": "4055a6187296ac16c0bc7bbab4ed5d92f82f791c"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/top-think/think-multi-app/zipball/07b9183855150455e1f76f8cbe9d77d6d1bc399f", "url": "https://api.github.com/repos/top-think/think-multi-app/zipball/4055a6187296ac16c0bc7bbab4ed5d92f82f791c",
"reference": "07b9183855150455e1f76f8cbe9d77d6d1bc399f", "reference": "4055a6187296ac16c0bc7bbab4ed5d92f82f791c",
"shasum": "", "shasum": "",
"mirrors": [ "mirrors": [
{ {
@ -2954,12 +2949,12 @@
"email": "liu21st@gmail.com" "email": "liu21st@gmail.com"
} }
], ],
"description": "thinkphp6 multi app support", "description": "thinkphp multi app support",
"support": { "support": {
"issues": "https://github.com/top-think/think-multi-app/issues", "issues": "https://github.com/top-think/think-multi-app/issues",
"source": "https://github.com/top-think/think-multi-app/tree/v1.0.16" "source": "https://github.com/top-think/think-multi-app/tree/v1.0.17"
}, },
"time": "2023-02-07T08:40:09+00:00" "time": "2023-03-29T02:04:29+00:00"
}, },
{ {
"name": "topthink/think-orm", "name": "topthink/think-orm",

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 299 KiB

After

Width:  |  Height:  |  Size: 322 KiB

File diff suppressed because one or more lines are too long

View File

@ -4,6 +4,7 @@ html,body{overflow-x: hidden;}
html body{margin-top: 61px;} html body{margin-top: 61px;}
html{background-color: #F2F2F2;} html{background-color: #F2F2F2;}
i{font-style: normal;} i{font-style: normal;}
h1,h2,h3 {font-weight: 400;}
/* 布局 */ /* 布局 */
.layui-mm{position: fixed; top: 100px; bottom: 0;} .layui-mm{position: fixed; top: 100px; bottom: 0;}
@ -25,7 +26,7 @@ i{font-style: normal;}
.site-mobile .site-menu{left: 0;} .site-mobile .site-menu{left: 0;}
.site-mobile .site-mobile-shade-top{content: ''; position: fixed; top: 0; bottom: 0; left: 0; right: 0; background-color: rgba(0,0,0,.8); z-index: 999;} .site-mobile .site-mobile-shade-top{content: ''; position: fixed; top: 0; bottom: 0; left: 0; right: 0; background-color: rgba(0,0,0,.8); z-index: 999;}
.site-tree-mobile-top i{font-size: 30px;} .site-tree-mobile-top i{font-size: 30px;}
/* 底部伸缩菜单栏 */ /* 底部伸缩菜单栏 */
.site-tree-mobile{display: block!important; position: fixed; z-index: 16666669; bottom: 15px; left: 15px; width: 30px; height: 30px; line-height: 30px; border-radius: 2px; text-align: center; background-color: #009688; color: #fff;} .site-tree-mobile{display: block!important; position: fixed; z-index: 16666669; bottom: 15px; left: 15px; width: 30px; height: 30px; line-height: 30px; border-radius: 2px; text-align: center; background-color: #009688; color: #fff;}
.site-home .site-tree-mobile{display: none!important;} .site-home .site-tree-mobile{display: none!important;}
@ -34,7 +35,7 @@ i{font-style: normal;}
.site-tree-mobile i{font-size: 20px;} .site-tree-mobile i{font-size: 20px;}
.site-mobile .layui-side{left: 0;} .site-mobile .layui-side{left: 0;}
.site-mobile .layui-side-child{top: 50%; left: 200px; height: 300px; margin-top: -100px;} .site-mobile .layui-side-child{top: 50%; left: 200px; height: 300px; margin-top: -100px;}
} }
/* 图标 */ /* 图标 */
@ -230,7 +231,7 @@ pre{overflow-y: auto;
text-align: center; text-align: center;
} }
/* 搜索 */ /* 搜索 */
.fly-search{display: inline-block; width: 50px; margin-right: 10px; cursor: pointer; font-size: 20px;} .fly-search{display: inline-block; width: 50px; margin-right: 10px; cursor: pointer; font-size: 20px;}
.fly-search .layui-icon{font-size: 20px;} .fly-search .layui-icon{font-size: 20px;}
.fly-search:hover{color: #5FB878;} .fly-search:hover{color: #5FB878;}
@ -390,7 +391,7 @@ body .layui-edit-face .layui-layer-content{padding:0; background-color:#fff; co
.que-body .que-user-info .que-avatar i{position: absolute; left: 35px; top: 15px; } .que-body .que-user-info .que-avatar i{position: absolute; left: 35px; top: 15px; }
.que-body .que-user-info span{display: inline-block; font-size: 12px; padding-left: 5px;} .que-body .que-user-info span{display: inline-block; font-size: 12px; padding-left: 5px;}
/* 签到 */ /* 签到 */
.fly-signin cite{padding: 0 5px; color: #FF5722; font-style: normal;} .fly-signin cite{padding: 0 5px; color: #FF5722; font-style: normal;}
.fly-signin .layui-badge-dot{top: -7px; margin-left: 0px;} .fly-signin .layui-badge-dot{top: -7px; margin-left: 0px;}
.fly-signin-list{padding: 0; line-height: 30px;} .fly-signin-list{padding: 0; line-height: 30px;}
@ -469,7 +470,7 @@ body .layui-edit-face .layui-layer-content{padding:0; background-color:#fff; co
/*详情页管理工具条*/ /*详情页管理工具条*/
.detail-assist{ .detail-assist{
position: fixed; position: fixed;
width: 35px; width: 35px;
right: calc(50% - 625px); right: calc(50% - 625px);
top: 200px; top: 200px;
margin: 0 auto; margin: 0 auto;
@ -576,7 +577,7 @@ body .layui-edit-face .layui-layer-content{padding:0; background-color:#fff; co
.detail-about-reply .detail-hits{left: 0; bottom: 0;} .detail-about-reply .detail-hits{left: 0; bottom: 0;}
.detail-about-reply .fly-avatar{left: 0; top: 0;} .detail-about-reply .fly-avatar{left: 0; top: 0;}
.jieda-body{margin: 25px 0 20px; min-height: 0; line-height: 24px; font-size:14px;} .jieda-body{margin: 10px 0; min-height: 0; line-height: 24px; font-size:14px;}
.jieda-body p{margin-bottom: 10px;} .jieda-body p{margin-bottom: 10px;}
.jieda-body a{color:#4f99cf} .jieda-body a{color:#4f99cf}
.jieda-reply{position:relative; font-size: 14px} .jieda-reply{position:relative; font-size: 14px}
@ -680,7 +681,7 @@ body .fly-user-main{position: relative; min-height: 600px;}
.fly-case-tab .tab-this{background-color: #009688; color: #fff;} .fly-case-tab .tab-this{background-color: #009688; color: #fff;}
.fly-case-list{margin-top: 15px; font-size: 0;} .fly-case-list{margin-top: 15px; font-size: 0;}
.fly-case-list li, .fly-case-list li,
.layer-ext-ul li{display: inline-block; vertical-align: middle; *display: inline; *zoom:1; font-size: 14px; background-color: #fff;} .layer-ext-ul li{display: inline-block; vertical-align: middle; *display: inline; *zoom:1; font-size: 14px; background-color: #fff;}
.fly-case-list{width: 110%;} .fly-case-list{width: 110%;}
.fly-case-list li{width: 239px; margin: 0 15px 15px 0; padding: 10px;} .fly-case-list li{width: 239px; margin: 0 15px 15px 0; padding: 10px;}
@ -719,7 +720,7 @@ body .fly-user-main{position: relative; min-height: 600px;}
@media screen and (max-width: 768px) { @media screen and (max-width: 768px) {
.fly-main{width: 100%;} .fly-main{width: 100%;}
/* 顶边距 */ /* 顶边距 */
.fly-marginTop{margin-top: 0;} .fly-marginTop{margin-top: 0;}
@ -833,7 +834,7 @@ blockquote {
@media (max-width:767px) {.footer-col {margin-right:0} @media (max-width:767px) {.footer-col {margin-right:0}
} }
@media (max-width:1239px) { @media (max-width:1239px) {
.footer-col-logo {display:none} .footer-col-logo {display:none}
} }
.footer-col-logo img {display:block;max-width:160px;max-height:60px;height:auto} .footer-col-logo img {display:block;max-width:160px;max-height:60px;height:auto}
.footer-col-sns {float:right;margin-right:0} .footer-col-sns {float:right;margin-right:0}
@ -863,19 +864,19 @@ blockquote {
@media (min-width: 768px) { @media (min-width: 768px) {
.container { .container {
width:750px; width:750px;
} }
} }
@media (min-width: 992px) { @media (min-width: 992px) {
.container { .container {
width:970px; width:970px;
} }
} }
@media (min-width: 1200px) { @media (min-width: 1200px) {
.container { .container {
width:1170px; width:1170px;
} }
} }
@ -1018,9 +1019,9 @@ blockquote {
} }
} }
figure { figure {
margin: 0; margin: 0;
} }
@media (min-width: 768px){ @media (min-width: 768px){
.ml-md-2, .mx-md-2 { .ml-md-2, .mx-md-2 {
@ -1028,11 +1029,11 @@ blockquote {
} }
} }
@media (min-width: 768px){ @media (min-width: 768px){
.mr-md-2, .mx-md-2 { .mr-md-2, .mx-md-2 {
margin-right: .5rem !important; margin-right: .5rem !important;
}
} }
}
.ml-1, .mx-1 { .ml-1, .mx-1 {
@ -1045,34 +1046,34 @@ blockquote {
.d-inline-block { .d-inline-block {
display: inline-block !important; display: inline-block !important;
} }
.text-muted { .text-muted {
color: #9ca0ad !important; color: #9ca0ad !important;
} }
.text-xs { .text-xs {
font-size: .75rem !important; font-size: .75rem !important;
} }
.text-muted { .text-muted {
color: #6c757d !important; color: #6c757d !important;
} }
.align-items-center { .align-items-center {
-ms-flex-align: center !important; -ms-flex-align: center !important;
align-items: center !important; align-items: center !important;
} }
.flex-fill { .flex-fill {
-ms-flex: 1 1 auto !important; -ms-flex: 1 1 auto !important;
flex: 1 1 auto !important; flex: 1 1 auto !important;
} }
.list-footer { .list-footer {
margin-top: .5rem; margin-top: .5rem;
} }
.d-flex { .d-flex {
display: -ms-flexbox !important; display: -ms-flexbox !important;
display: flex !important; display: flex !important;
} }
@media (min-width: 768px) and (max-width: 991.98px) { @media (min-width: 768px) and (max-width: 991.98px) {
.card, .block {margin-bottom: 1rem;} .card, .block {margin-bottom: 1rem;}
} }

View File

@ -0,0 +1,105 @@
/**
images压缩扩展模块
changlin_zhao@qq.com
2023.5.23
**/
layui.define(['upload','layer'],function(exports){
var layer = layui.layer;
var Compressor = {
upload: function (obj) {
// opthions = {
// width: option[0],
// height: option[1],
// quality: option[2]
// }
obj.preview(function(index, file, result){
canvasDataURL(result, {quality: 0.7}, function(base64Codes){
obj.upload(index, convertBase64UrlTo(base64Codes, file.name));
});
});
}
}
// 已知 base64
// canvasDataURL(base64, {quality: 0.7}, function(base64Codes){
// // base64Codes 为压缩后的
// // 其中 convertBase64UrlTo(base64Codes, file.name) 可返回 File 对象和 Blob
// obj.upload(index, convertBase64UrlTo(base64Codes, file.name));
// });
// 未知 base64
// imageCompress(file, {quality: 0.7}, function(base64Codes){
// // base64Codes 为压缩后的
// obj.upload(index, convertBase64UrlTo(base64Codes, file.name));
// });
/**
* 读取文件
* @param {file or Blob} file 上传文件
* @param {object} config 压缩配置 可配置压缩长宽质量等
* @param {function} callback
*/
function imageCompress(file, config, callback){
var ready = new FileReader();
ready.readAsDataURL(file);
ready.onload=function(){
canvasDataURL(this.result, config, callback)
}
}
/**
*
* @param {string} path
* @param {object} config -- {width: '', height: '', quality: 0.7}
* @param {function} callback
*/
function canvasDataURL(path, config, callback){
var img = new Image();
img.src = path;
img.onload = function(){
var that = this, quality = 0.7;
var w = that.width, h = that.height, scale = w / h;
w = config.width || w;
h = config.height || (w / scale);
//生成canvas
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
var anw = document.createAttribute("width");
anw.nodeValue = w;
var anh = document.createAttribute("height");
anh.nodeValue = h;
canvas.setAttributeNode(anw);
canvas.setAttributeNode(anh);
ctx.drawImage(that, 0, 0, w, h);
if(config.quality && config.quality <= 1 && config.quality > 0){
quality = config.quality;
}
callback(canvas.toDataURL('image/jpeg', quality));
}
}
/**
* 将图片 base64 转为 File 对象或者 Blob
* @param {*} urlData 图片 base64
* @param {*} filename 图片名 没有图片名将转为 Blob
*/
function convertBase64UrlTo(urlData, filename = null){
var base64Arr = urlData.split(','), mime = base64Arr[0].match(/:(.*?);/)[1],
bstr = atob(base64Arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
while(n--){
u8arr[n] = bstr.charCodeAt(n);
}
return filename ? new File([u8arr], filename, {type:mime}) : new Blob([u8arr], {type:mime});
}
//输出 imagecut接口
exports('imagecut', Compressor);
});

View File

@ -696,42 +696,6 @@ layui.define(['layer', 'laytpl', 'form', 'element', 'upload', 'util', 'imgcom'],
//console.log(othis.attr('src')); //console.log(othis.attr('src'));
}); });
//头条轮播
if($('#FLY_topline')[0]){
layui.use('carousel', function(){
var carousel = layui.carousel;
var ins = carousel.render({
elem: '#FLY_topline'
,width: '100%'
,height: '250px'
,anim: 'fade'
});
var resizeTopline = function(){
var width = $(this).prop('innerWidth');
if(width >= 1200){
ins.reload({
height: '250px'
});
} else if(width >= 992){
ins.reload({
height: '250px'
});
} else if(width >= 768){
ins.reload({
height: '166px'
});
}
};
resizeTopline()
$(window).on('resize', resizeTopline);
});
}
//签到 //签到
//活跃榜 //活跃榜

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -491,18 +491,24 @@
}, },
{ {
"name": "guzzlehttp/promises", "name": "guzzlehttp/promises",
"version": "1.5.2", "version": "1.5.3",
"version_normalized": "1.5.2.0", "version_normalized": "1.5.3.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/guzzle/promises.git", "url": "https://github.com/guzzle/promises.git",
"reference": "b94b2807d85443f9719887892882d0329d1e2598" "reference": "67ab6e18aaa14d753cc148911d273f6e6cb6721e"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/guzzle/promises/zipball/b94b2807d85443f9719887892882d0329d1e2598", "url": "https://api.github.com/repos/guzzle/promises/zipball/67ab6e18aaa14d753cc148911d273f6e6cb6721e",
"reference": "b94b2807d85443f9719887892882d0329d1e2598", "reference": "67ab6e18aaa14d753cc148911d273f6e6cb6721e",
"shasum": "" "shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
}, },
"require": { "require": {
"php": ">=5.5" "php": ">=5.5"
@ -510,13 +516,8 @@
"require-dev": { "require-dev": {
"symfony/phpunit-bridge": "^4.4 || ^5.1" "symfony/phpunit-bridge": "^4.4 || ^5.1"
}, },
"time": "2022-08-28T14:55:35+00:00", "time": "2023-05-21T12:31:43+00:00",
"type": "library", "type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.5-dev"
}
},
"installation-source": "dist", "installation-source": "dist",
"autoload": { "autoload": {
"files": [ "files": [
@ -558,7 +559,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/guzzle/promises/issues", "issues": "https://github.com/guzzle/promises/issues",
"source": "https://github.com/guzzle/promises/tree/1.5.2" "source": "https://github.com/guzzle/promises/tree/1.5.3"
}, },
"funding": [ "funding": [
{ {
@ -2610,17 +2611,17 @@
}, },
{ {
"name": "topthink/framework", "name": "topthink/framework",
"version": "v6.1.2", "version": "v6.1.3",
"version_normalized": "6.1.2.0", "version_normalized": "6.1.3.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/top-think/framework.git", "url": "https://github.com/top-think/framework.git",
"reference": "67235be5b919aaaf1de5aed9839f65d8e766aca3" "reference": "7c324e7011246f0064b055b62ab9c3921cf0a041"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/top-think/framework/zipball/67235be5b919aaaf1de5aed9839f65d8e766aca3", "url": "https://api.github.com/repos/top-think/framework/zipball/7c324e7011246f0064b055b62ab9c3921cf0a041",
"reference": "67235be5b919aaaf1de5aed9839f65d8e766aca3", "reference": "7c324e7011246f0064b055b62ab9c3921cf0a041",
"shasum": "", "shasum": "",
"mirrors": [ "mirrors": [
{ {
@ -2646,7 +2647,7 @@
"mockery/mockery": "^1.2", "mockery/mockery": "^1.2",
"phpunit/phpunit": "^7.0" "phpunit/phpunit": "^7.0"
}, },
"time": "2023-02-08T02:24:01+00:00", "time": "2023-05-22T03:02:08+00:00",
"type": "library", "type": "library",
"installation-source": "dist", "installation-source": "dist",
"autoload": { "autoload": {
@ -2678,7 +2679,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/top-think/framework/issues", "issues": "https://github.com/top-think/framework/issues",
"source": "https://github.com/top-think/framework/tree/v6.1.2" "source": "https://github.com/top-think/framework/tree/v6.1.3"
}, },
"install-path": "../topthink/framework" "install-path": "../topthink/framework"
}, },
@ -2918,17 +2919,17 @@
}, },
{ {
"name": "topthink/think-multi-app", "name": "topthink/think-multi-app",
"version": "v1.0.16", "version": "v1.0.17",
"version_normalized": "1.0.16.0", "version_normalized": "1.0.17.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/top-think/think-multi-app.git", "url": "https://github.com/top-think/think-multi-app.git",
"reference": "07b9183855150455e1f76f8cbe9d77d6d1bc399f" "reference": "4055a6187296ac16c0bc7bbab4ed5d92f82f791c"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/top-think/think-multi-app/zipball/07b9183855150455e1f76f8cbe9d77d6d1bc399f", "url": "https://api.github.com/repos/top-think/think-multi-app/zipball/4055a6187296ac16c0bc7bbab4ed5d92f82f791c",
"reference": "07b9183855150455e1f76f8cbe9d77d6d1bc399f", "reference": "4055a6187296ac16c0bc7bbab4ed5d92f82f791c",
"shasum": "", "shasum": "",
"mirrors": [ "mirrors": [
{ {
@ -2941,7 +2942,7 @@
"php": ">=7.1.0", "php": ">=7.1.0",
"topthink/framework": "^6.0|^8.0" "topthink/framework": "^6.0|^8.0"
}, },
"time": "2023-02-07T08:40:09+00:00", "time": "2023-03-29T02:04:29+00:00",
"type": "library", "type": "library",
"extra": { "extra": {
"think": { "think": {
@ -2966,10 +2967,10 @@
"email": "liu21st@gmail.com" "email": "liu21st@gmail.com"
} }
], ],
"description": "thinkphp6 multi app support", "description": "thinkphp multi app support",
"support": { "support": {
"issues": "https://github.com/top-think/think-multi-app/issues", "issues": "https://github.com/top-think/think-multi-app/issues",
"source": "https://github.com/top-think/think-multi-app/tree/v1.0.16" "source": "https://github.com/top-think/think-multi-app/tree/v1.0.17"
}, },
"install-path": "../topthink/think-multi-app" "install-path": "../topthink/think-multi-app"
}, },

View File

@ -3,7 +3,7 @@
'name' => 'taoser/taoler', 'name' => 'taoser/taoler',
'pretty_version' => 'dev-master', 'pretty_version' => 'dev-master',
'version' => 'dev-master', 'version' => 'dev-master',
'reference' => '3f1e60a9976d29a84fa29d28bdfe68dea0c89c26', 'reference' => 'c74d8b8052c4f2da4466d3ed181a1636e5c52c39',
'type' => 'project', 'type' => 'project',
'install_path' => __DIR__ . '/../../', 'install_path' => __DIR__ . '/../../',
'aliases' => array(), 'aliases' => array(),
@ -74,9 +74,9 @@
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'guzzlehttp/promises' => array( 'guzzlehttp/promises' => array(
'pretty_version' => '1.5.2', 'pretty_version' => '1.5.3',
'version' => '1.5.2.0', 'version' => '1.5.3.0',
'reference' => 'b94b2807d85443f9719887892882d0329d1e2598', 'reference' => '67ab6e18aaa14d753cc148911d273f6e6cb6721e',
'type' => 'library', 'type' => 'library',
'install_path' => __DIR__ . '/../guzzlehttp/promises', 'install_path' => __DIR__ . '/../guzzlehttp/promises',
'aliases' => array(), 'aliases' => array(),
@ -349,7 +349,7 @@
'taoser/taoler' => array( 'taoser/taoler' => array(
'pretty_version' => 'dev-master', 'pretty_version' => 'dev-master',
'version' => 'dev-master', 'version' => 'dev-master',
'reference' => '3f1e60a9976d29a84fa29d28bdfe68dea0c89c26', 'reference' => 'c74d8b8052c4f2da4466d3ed181a1636e5c52c39',
'type' => 'project', 'type' => 'project',
'install_path' => __DIR__ . '/../../', 'install_path' => __DIR__ . '/../../',
'aliases' => array(), 'aliases' => array(),
@ -392,9 +392,9 @@
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'topthink/framework' => array( 'topthink/framework' => array(
'pretty_version' => 'v6.1.2', 'pretty_version' => 'v6.1.3',
'version' => '6.1.2.0', 'version' => '6.1.3.0',
'reference' => '67235be5b919aaaf1de5aed9839f65d8e766aca3', 'reference' => '7c324e7011246f0064b055b62ab9c3921cf0a041',
'type' => 'library', 'type' => 'library',
'install_path' => __DIR__ . '/../topthink/framework', 'install_path' => __DIR__ . '/../topthink/framework',
'aliases' => array(), 'aliases' => array(),
@ -437,9 +437,9 @@
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'topthink/think-multi-app' => array( 'topthink/think-multi-app' => array(
'pretty_version' => 'v1.0.16', 'pretty_version' => 'v1.0.17',
'version' => '1.0.16.0', 'version' => '1.0.17.0',
'reference' => '07b9183855150455e1f76f8cbe9d77d6d1bc399f', 'reference' => '4055a6187296ac16c0bc7bbab4ed5d92f82f791c',
'type' => 'library', 'type' => 'library',
'install_path' => __DIR__ . '/../topthink/think-multi-app', 'install_path' => __DIR__ . '/../topthink/think-multi-app',
'aliases' => array(), 'aliases' => array(),

View File

@ -1,5 +1,11 @@
# CHANGELOG # CHANGELOG
## 1.5.3 - 2023-05-21
### Changed
- Removed remaining usage of deprecated functions
## 1.5.2 - 2022-08-07 ## 1.5.2 - 2022-08-07
### Changed ### Changed

View File

@ -46,11 +46,6 @@
"test": "vendor/bin/simple-phpunit", "test": "vendor/bin/simple-phpunit",
"test-ci": "vendor/bin/simple-phpunit --coverage-text" "test-ci": "vendor/bin/simple-phpunit --coverage-text"
}, },
"extra": {
"branch-alias": {
"dev-master": "1.5-dev"
}
},
"config": { "config": {
"preferred-install": "dist", "preferred-install": "dist",
"sort-packages": true "sort-packages": true

View File

@ -78,7 +78,7 @@ final class Each
$concurrency, $concurrency,
callable $onFulfilled = null callable $onFulfilled = null
) { ) {
return each_limit( return self::ofLimit(
$iterable, $iterable,
$concurrency, $concurrency,
$onFulfilled, $onFulfilled,

View File

@ -107,7 +107,7 @@ final class Utils
{ {
$results = []; $results = [];
foreach ($promises as $key => $promise) { foreach ($promises as $key => $promise) {
$results[$key] = inspect($promise); $results[$key] = self::inspect($promise);
} }
return $results; return $results;

2
vendor/services.php vendored
View File

@ -1,5 +1,5 @@
<?php <?php
// This file is automatically generated at:2023-05-17 09:05:27 // This file is automatically generated at:2023-06-08 13:25:29
declare (strict_types = 1); declare (strict_types = 1);
return array ( return array (
0 => 'taoser\\addons\\Service', 0 => 'taoser\\addons\\Service',

View File

@ -38,7 +38,7 @@ use think\initializer\RegisterService;
*/ */
class App extends Container class App extends Container
{ {
const VERSION = '6.1.1'; const VERSION = '6.1.3';
/** /**
* 应用调试模式 * 应用调试模式

View File

@ -19,6 +19,7 @@ use think\route\dispatch\Callback;
use think\route\dispatch\Url as UrlDispatch; use think\route\dispatch\Url as UrlDispatch;
use think\route\Domain; use think\route\Domain;
use think\route\Resource; use think\route\Resource;
use think\route\ResourceRegister;
use think\route\Rule; use think\route\Rule;
use think\route\RuleGroup; use think\route\RuleGroup;
use think\route\RuleItem; use think\route\RuleItem;
@ -182,6 +183,11 @@ class Route
$this->removeSlash = $this->config['remove_slash']; $this->removeSlash = $this->config['remove_slash'];
$this->group->removeSlash($this->removeSlash); $this->group->removeSlash($this->removeSlash);
// 注册全局MISS路由
$this->miss(function () {
return Response::create('', 'html', 204)->header(['Allow' => 'GET, POST, PUT, DELETE']);
}, 'options')->allowCrossDomain();
} }
public function config(string $name = null) public function config(string $name = null)
@ -317,8 +323,7 @@ class Route
$domainName = is_array($name) ? array_shift($name) : $name; $domainName = is_array($name) ? array_shift($name) : $name;
if (!isset($this->domains[$domainName])) { if (!isset($this->domains[$domainName])) {
$domain = (new Domain($this, $domainName, $rule)) $domain = (new Domain($this, $domainName, $rule, $this->lazy))
->lazy($this->lazy)
->removeSlash($this->removeSlash) ->removeSlash($this->removeSlash)
->mergeRuleRegex($this->mergeRuleRegex); ->mergeRuleRegex($this->mergeRuleRegex);
@ -523,19 +528,18 @@ class Route
} }
/** /**
* 设置跨域有效路由规则 * 设置路由规则全局有效
* @access public * @access public
* @param Rule $rule 路由规则 * @param Rule $rule 路由规则
* @param string $method 请求类型
* @return $this * @return $this
*/ */
public function setCrossDomainRule(Rule $rule, string $method = '*') public function setCrossDomainRule(Rule $rule)
{ {
if (!isset($this->cross)) { if (!isset($this->cross)) {
$this->cross = (new RuleGroup($this))->mergeRuleRegex($this->mergeRuleRegex); $this->cross = (new RuleGroup($this))->mergeRuleRegex($this->mergeRuleRegex);
} }
$this->cross->addRuleItem($rule, $method); $this->cross->addRuleItem($rule);
return $this; return $this;
} }
@ -554,8 +558,7 @@ class Route
$name = ''; $name = '';
} }
return (new RuleGroup($this, $this->group, $name, $route)) return (new RuleGroup($this, $this->group, $name, $route, $this->lazy))
->lazy($this->lazy)
->removeSlash($this->removeSlash) ->removeSlash($this->removeSlash)
->mergeRuleRegex($this->mergeRuleRegex); ->mergeRuleRegex($this->mergeRuleRegex);
} }
@ -661,12 +664,17 @@ class Route
* @access public * @access public
* @param string $rule 路由规则 * @param string $rule 路由规则
* @param string $route 路由地址 * @param string $route 路由地址
* @return Resource * @return Resource|ResourceRegister
*/ */
public function resource(string $rule, string $route): Resource public function resource(string $rule, string $route)
{ {
return (new Resource($this, $this->group, $rule, $route, $this->rest)) $resource = new Resource($this, $this->group, $rule, $route, $this->rest);
->lazy($this->lazy);
if (!$this->lazy) {
return new ResourceRegister($resource);
}
return $resource;
} }
/** /**

View File

@ -56,8 +56,8 @@ class RouteList extends Command
protected function getRouteList(string $dir = null): string protected function getRouteList(string $dir = null): string
{ {
$this->app->route->setTestMode(true);
$this->app->route->clear(); $this->app->route->clear();
$this->app->route->lazy(false);
if ($dir) { if ($dir) {
$path = $this->app->getRootPath() . 'route' . DIRECTORY_SEPARATOR . $dir . DIRECTORY_SEPARATOR; $path = $this->app->getRootPath() . 'route' . DIRECTORY_SEPARATOR . $dir . DIRECTORY_SEPARATOR;

View File

@ -13,6 +13,7 @@ declare (strict_types = 1);
namespace think\facade; namespace think\facade;
use think\Facade; use think\Facade;
use think\Response;
use think\route\Dispatch; use think\route\Dispatch;
use think\route\Domain; use think\route\Domain;
use think\route\Rule; use think\route\Rule;
@ -20,6 +21,7 @@ use think\route\RuleGroup;
use think\route\RuleItem; use think\route\RuleItem;
use think\route\RuleName; use think\route\RuleName;
use think\route\Url as UrlBuild; use think\route\Url as UrlBuild;
use think\route\ResourceRegister as Resource;
/** /**
* @see \think\Route * @see \think\Route
@ -48,7 +50,7 @@ use think\route\Url as UrlBuild;
* @method static array getRuleList() 读取路由列表 * @method static array getRuleList() 读取路由列表
* @method static void clear() 清空路由规则 * @method static void clear() 清空路由规则
* @method static RuleItem rule(string $rule, mixed $route = null, string $method = '*') 注册路由规则 * @method static RuleItem rule(string $rule, mixed $route = null, string $method = '*') 注册路由规则
* @method static \think\Route setCrossDomainRule(Rule $rule, string $method = '*') 设置跨域有效路由规则 * @method static \think\Route setCrossDomainRule(Rule $rule) 设置跨域有效路由规则
* @method static RuleGroup group(string|\Closure $name, mixed $route = null) 注册路由分组 * @method static RuleGroup group(string|\Closure $name, mixed $route = null) 注册路由分组
* @method static RuleItem any(string $rule, mixed $route) 注册路由 * @method static RuleItem any(string $rule, mixed $route) 注册路由
* @method static RuleItem get(string $rule, mixed $route) 注册GET路由 * @method static RuleItem get(string $rule, mixed $route) 注册GET路由
@ -64,7 +66,7 @@ use think\route\Url as UrlBuild;
* @method static \think\Route rest(string|array $name, array|bool $resource = []) rest方法定义和修改 * @method static \think\Route rest(string|array $name, array|bool $resource = []) rest方法定义和修改
* @method static array|null getRest(string $name = null) 获取rest方法定义的参数 * @method static array|null getRest(string $name = null) 获取rest方法定义的参数
* @method static RuleItem miss(string|\Closure $route, string $method = '*') 注册未匹配路由规则后的处理 * @method static RuleItem miss(string|\Closure $route, string $method = '*') 注册未匹配路由规则后的处理
* @method static Response dispatch(\think\Request $request, Closure|bool $withRoute = true) 路由调度 * @method static Response dispatch(\think\Request $request, \Closure|bool $withRoute = true) 路由调度
* @method static Dispatch|false check() 检测URL路由 * @method static Dispatch|false check() 检测URL路由
* @method static Dispatch url(string $url) 默认URL解析 * @method static Dispatch url(string $url) 默认URL解析
* @method static UrlBuild buildUrl(string $url = '', array $vars = []) URL生成 支持路由反射 * @method static UrlBuild buildUrl(string $url = '', array $vars = []) URL生成 支持路由反射

View File

@ -68,7 +68,7 @@ class SessionInit
$response->setSession($this->session); $response->setSession($this->session);
$this->app->cookie->set($cookieName, $this->session->getId()); $this->app->cookie->set($cookieName, $this->session->getId(), $this->session->getConfig('expire'));
return $response; return $response;
} }

View File

@ -36,24 +36,28 @@ class Redirect extends Response
$this->cacheControl('no-cache,must-revalidate'); $this->cacheControl('no-cache,must-revalidate');
} }
public function data($data)
{
$this->header['Location'] = $data;
return parent::data($data);
}
/** /**
* 处理数据 * 处理数据
* @access protected * @access protected
* @param mixed $data 要处理的数据 * @param mixed $data 要处理的数据
* @return string * @return string
*/ */
protected function output($data): string protected function output($data): string
{ {
$this->header['Location'] = $data;
return ''; return '';
} }
/** /**
* 重定向传值通过Session * 重定向传值通过Session
* @access protected * @access protected
* @param string|array $name 变量名或者数组 * @param string|array $name 变量名或者数组
* @param mixed $value * @param mixed $value
* @return $this * @return $this
*/ */
public function with($name, $value = null) public function with($name, $value = null)

View File

@ -77,16 +77,6 @@ abstract class Dispatch
*/ */
public function run(): Response public function run(): Response
{ {
if ($this->rule instanceof RuleItem && $this->request->method() == 'OPTIONS' && $this->rule->isAutoOptions()) {
$rules = $this->rule->getRouter()->getRule($this->rule->getRule());
$allow = [];
foreach ($rules as $item) {
$allow[] = strtoupper($item->getMethod());
}
return Response::create('', 'html', 204)->header(['Allow' => implode(', ', $allow)]);
}
$data = $this->exec(); $data = $this->exec();
return $this->autoResponse($data); return $this->autoResponse($data);
} }

View File

@ -29,12 +29,17 @@ class Domain extends RuleGroup
* @param Route $router 路由对象 * @param Route $router 路由对象
* @param string $name 路由域名 * @param string $name 路由域名
* @param mixed $rule 域名路由 * @param mixed $rule 域名路由
* @param bool $lazy 延迟解析
*/ */
public function __construct(Route $router, string $name = null, $rule = null) public function __construct(Route $router, string $name = null, $rule = null, bool $lazy = false)
{ {
$this->router = $router; $this->router = $router;
$this->domain = $name; $this->domain = $name;
$this->rule = $rule; $this->rule = $rule;
if (!$lazy) {
$this->parseGroupRule($rule);
}
} }
/** /**

View File

@ -19,18 +19,6 @@ use think\Route;
*/ */
class Resource extends RuleGroup class Resource extends RuleGroup
{ {
/**
* 资源路由名称
* @var string
*/
protected $resource;
/**
* 资源路由地址
* @var string
*/
protected $route;
/** /**
* REST方法定义 * REST方法定义
* @var array * @var array
@ -58,18 +46,18 @@ class Resource extends RuleGroup
/** /**
* 架构函数 * 架构函数
* @access public * @access public
* @param Route $router 路由对象 * @param Route $router 路由对象
* @param RuleGroup $parent 上级对象 * @param RuleGroup|null $parent 上级对象
* @param string $name 资源名称 * @param string $name 资源名称
* @param string $route 路由地址 * @param string $route 路由地址
* @param array $rest 资源定义 * @param array $rest 资源定义
*/ */
public function __construct(Route $router, RuleGroup $parent = null, string $name = '', string $route = '', array $rest = []) public function __construct(Route $router, RuleGroup $parent = null, string $name = '', string $route = '', array $rest = [])
{ {
$name = ltrim($name, '/'); $name = ltrim($name, '/');
$this->router = $router; $this->router = $router;
$this->parent = $parent; $this->parent = $parent;
$this->resource = $name; $this->rule = $name;
$this->route = $route; $this->route = $route;
$this->name = strpos($name, '.') ? strstr($name, '.', true) : $name; $this->name = strpos($name, '.') ? strstr($name, '.', true) : $name;
@ -84,20 +72,16 @@ class Resource extends RuleGroup
$this->domain = $this->parent->getDomain(); $this->domain = $this->parent->getDomain();
$this->parent->addRuleItem($this); $this->parent->addRuleItem($this);
} }
if ($router->isTest()) {
$this->buildResourceRule();
}
} }
/** /**
* 生成资源路由规则 * 解析资源路由规则
* @access protected * @access public
* @param mixed $rule 路由规则
* @return void * @return void
*/ */
protected function buildResourceRule(): void public function parseGroupRule($rule): void
{ {
$rule = $this->resource;
$option = $this->option; $option = $this->option;
$origin = $this->router->getGroup(); $origin = $this->router->getGroup();
$this->router->setGroup($this); $this->router->setGroup($this);
@ -141,6 +125,7 @@ class Resource extends RuleGroup
} }
$this->router->setGroup($origin); $this->router->setGroup($origin);
$this->hasParsed = true;
} }
/** /**

View File

@ -0,0 +1,72 @@
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2021 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
declare (strict_types = 1);
namespace think\route;
/**
* 资源路由注册类
*/
class ResourceRegister
{
/**
* 资源路由
* @var Resource
*/
protected $resource;
/**
* 是否注册过
* @var bool
*/
protected $registered = false;
/**
* 架构函数
* @access public
* @param Resource $resource 资源路由
*/
public function __construct(Resource $resource)
{
$this->resource = $resource;
}
/**
* 注册资源路由
* @access protected
* @return void
*/
protected function register()
{
$this->registered = true;
$this->resource->parseGroupRule($this->resource->getRule());
}
/**
* 动态方法
* @access public
* @param string $method 方法名
* @param array $args 调用参数
* @return mixed
*/
public function __call($method, $args)
{
return call_user_func_array([$this->resource, $method], $args);
}
public function __destruct()
{
if (!$this->registered) {
$this->register();
}
}
}

View File

@ -67,7 +67,7 @@ abstract class Rule
* 请求类型 * 请求类型
* @var string * @var string
*/ */
protected $method; protected $method = '*';
/** /**
* 路由变量 * 路由变量
@ -572,14 +572,7 @@ abstract class Rule
*/ */
public function crossDomainRule() public function crossDomainRule()
{ {
if ($this instanceof RuleGroup) { $this->router->setCrossDomainRule($this);
$method = '*';
} else {
$method = $this->method;
}
$this->router->setCrossDomainRule($this, $method);
return $this; return $this;
} }

View File

@ -25,15 +25,15 @@ class RuleGroup extends Rule
{ {
/** /**
* 分组路由(包括子分组) * 分组路由(包括子分组)
* @var array * @var Rule[]
*/ */
protected $rules = []; protected $rules = [];
/** /**
* 分组路由规则 * 是否已经解析
* @var mixed * @var bool
*/ */
protected $rule; protected $hasParsed;
/** /**
* MISS路由 * MISS路由
@ -56,12 +56,13 @@ class RuleGroup extends Rule
/** /**
* 架构函数 * 架构函数
* @access public * @access public
* @param Route $router 路由对象 * @param Route $router 路由对象
* @param RuleGroup $parent 上级对象 * @param RuleGroup|null $parent 上级对象
* @param string $name 分组名称 * @param string $name 分组名称
* @param mixed $rule 分组路由 * @param mixed $rule 分组路由
* @param bool $lazy 延迟解析
*/ */
public function __construct(Route $router, RuleGroup $parent = null, string $name = '', $rule = null) public function __construct(Route $router, RuleGroup $parent = null, string $name = '', $rule = null, bool $lazy = false)
{ {
$this->router = $router; $this->router = $router;
$this->parent = $parent; $this->parent = $parent;
@ -75,8 +76,8 @@ class RuleGroup extends Rule
$this->parent->addRuleItem($this); $this->parent->addRuleItem($this);
} }
if ($router->isTest()) { if (!$lazy) {
$this->lazy(false); $this->parseGroupRule($rule);
} }
} }
@ -138,9 +139,7 @@ class RuleGroup extends Rule
} }
// 解析分组路由 // 解析分组路由
if ($this instanceof Resource) { if (!$this->hasParsed) {
$this->buildResourceRule();
} else {
$this->parseGroupRule($this->rule); $this->parseGroupRule($this->rule);
} }
@ -163,8 +162,8 @@ class RuleGroup extends Rule
} }
// 检查分组路由 // 检查分组路由
foreach ($rules as $key => $item) { foreach ($rules as $item) {
$result = $item[1]->check($request, $url, $completeMatch); $result = $item->check($request, $url, $completeMatch);
if (false !== $result) { if (false !== $result) {
return $result; return $result;
@ -173,9 +172,9 @@ class RuleGroup extends Rule
if (!empty($option['dispatcher'])) { if (!empty($option['dispatcher'])) {
$result = $this->parseRule($request, '', $option['dispatcher'], $url, $option); $result = $this->parseRule($request, '', $option['dispatcher'], $url, $option);
} elseif ($this->miss && in_array($this->miss->getMethod(), ['*', $method])) { } elseif ($miss = $this->getMissRule($method)) {
// 未匹配所有路由的路由规则处理 // 未匹配所有路由的路由规则处理
$result = $this->parseRule($request, '', $this->miss->getRoute(), $url, $this->miss->getOption()); $result = $miss->parseRule($request, '', $miss->getRoute(), $url, $miss->getOption());
} else { } else {
$result = false; $result = false;
} }
@ -222,22 +221,6 @@ class RuleGroup extends Rule
return $this; return $this;
} }
/**
* 延迟解析分组的路由规则
* @access public
* @param bool $lazy 路由是否延迟解析
* @return $this
*/
public function lazy(bool $lazy = true)
{
if (!$lazy) {
$this->parseGroupRule($this->rule);
$this->rule = null;
}
return $this;
}
/** /**
* 解析分组和域名的路由规则及绑定 * 解析分组和域名的路由规则及绑定
* @access public * @access public
@ -246,6 +229,10 @@ class RuleGroup extends Rule
*/ */
public function parseGroupRule($rule): void public function parseGroupRule($rule): void
{ {
if (is_null($rule)) {
return;
}
if (is_string($rule) && is_subclass_of($rule, Dispatch::class)) { if (is_string($rule) && is_subclass_of($rule, Dispatch::class)) {
$this->dispatcher($rule); $this->dispatcher($rule);
return; return;
@ -254,13 +241,14 @@ class RuleGroup extends Rule
$origin = $this->router->getGroup(); $origin = $this->router->getGroup();
$this->router->setGroup($this); $this->router->setGroup($this);
if ($rule instanceof \Closure) { if ($rule instanceof Closure) {
Container::getInstance()->invokeFunction($rule); Container::getInstance()->invokeFunction($rule);
} elseif (is_string($rule) && $rule) { } elseif (is_string($rule) && $rule) {
$this->router->bind($rule, $this->domain); $this->router->bind($rule, $this->domain);
} }
$this->router->setGroup($origin); $this->router->setGroup($origin);
$this->hasParsed = true;
} }
/** /**
@ -368,11 +356,19 @@ class RuleGroup extends Rule
/** /**
* 获取分组的MISS路由 * 获取分组的MISS路由
* @access public * @access public
* @param string $method 请求类型
* @return RuleItem|null * @return RuleItem|null
*/ */
public function getMissRule(): ? RuleItem public function getMissRule(string $method = '*'): ?RuleItem
{ {
return $this->miss; if (isset($this->miss[$method])) {
$miss = $this->miss[$method];
} elseif (isset($this->miss['*'])) {
$miss = $this->miss['*'];
} else {
return null;
}
return $miss;
} }
/** /**
@ -387,8 +383,7 @@ class RuleGroup extends Rule
// 创建路由规则实例 // 创建路由规则实例
$ruleItem = new RuleItem($this->router, $this, null, '', $route, strtolower($method)); $ruleItem = new RuleItem($this->router, $this, null, '', $route, strtolower($method));
$ruleItem->setMiss(); $this->miss[$method] = $ruleItem->setMiss();
$this->miss = $ruleItem;
return $ruleItem; return $ruleItem;
} }
@ -419,7 +414,7 @@ class RuleGroup extends Rule
// 创建路由规则实例 // 创建路由规则实例
$ruleItem = new RuleItem($this->router, $this, $name, $rule, $route, $method); $ruleItem = new RuleItem($this->router, $this, $name, $rule, $route, $method);
$this->addRuleItem($ruleItem, $method); $this->addRuleItem($ruleItem);
return $ruleItem; return $ruleItem;
} }
@ -428,21 +423,11 @@ class RuleGroup extends Rule
* 注册分组下的路由规则 * 注册分组下的路由规则
* @access public * @access public
* @param Rule $rule 路由规则 * @param Rule $rule 路由规则
* @param string $method 请求类型
* @return $this * @return $this
*/ */
public function addRuleItem(Rule $rule, string $method = '*') public function addRuleItem(Rule $rule)
{ {
if (strpos($method, '|')) { $this->rules[] = $rule;
$rule->method($method);
$method = '*';
}
$this->rules[] = [$method, $rule];
if ($rule instanceof RuleItem && 'options' != $method) {
$this->rules[] = ['options', $rule->setAutoOptions()];
}
return $this; return $this;
} }
@ -507,7 +492,8 @@ class RuleGroup extends Rule
} }
return array_filter($this->rules, function ($item) use ($method) { return array_filter($this->rules, function ($item) use ($method) {
return $method == $item[0] || '*' == $item[0]; $ruleMethod = $item->getMethod();
return '*' == $ruleMethod || false !== strpos($ruleMethod, $method);
}); });
} }

View File

@ -38,7 +38,7 @@ class RuleItem extends Rule
* @access public * @access public
* @param Route $router 路由实例 * @param Route $router 路由实例
* @param RuleGroup $parent 上级对象 * @param RuleGroup $parent 上级对象
* @param string $name 路由标识 * @param string|null $name 路由标识
* @param string $rule 路由规则 * @param string $rule 路由规则
* @param string|\Closure $route 路由地址 * @param string|\Closure $route 路由地址
* @param string $method 请求类型 * @param string $method 请求类型
@ -77,27 +77,6 @@ class RuleItem extends Rule
return $this->miss; return $this->miss;
} }
/**
* 设置当前路由为自动注册OPTIONS
* @access public
* @return $this
*/
public function setAutoOptions()
{
$this->autoOption = true;
return $this;
}
/**
* 判断当前路由规则是否为自动注册的OPTIONS路由
* @access public
* @return bool
*/
public function isAutoOptions(): bool
{
return $this->autoOption;
}
/** /**
* 获取当前路由的URL后缀 * 获取当前路由的URL后缀
* @access public * @access public

View File

@ -113,8 +113,9 @@ class RuleName
*/ */
public function clear(): void public function clear(): void
{ {
$this->item = []; $this->item = [];
$this->rule = []; $this->rule = [];
$this->group = [];
} }
/** /**

View File

@ -358,7 +358,7 @@ class Url
* @access public * @access public
* @return string * @return string
*/ */
public function build() public function build(): string
{ {
// 解析URL // 解析URL
$url = $this->url; $url = $this->url;

View File

@ -1,6 +1,6 @@
{ {
"name": "topthink/think-multi-app", "name": "topthink/think-multi-app",
"description": "thinkphp6 multi app support", "description": "thinkphp multi app support",
"license": "Apache-2.0", "license": "Apache-2.0",
"authors": [ "authors": [
{ {

View File

@ -27,29 +27,9 @@ class MultiApp
/** @var App */ /** @var App */
protected $app; protected $app;
/**
* 应用名称
* @var string
*/
protected $name;
/**
* 应用名称
* @var string
*/
protected $appName;
/**
* 应用路径
* @var string
*/
protected $path;
public function __construct(App $app) public function __construct(App $app)
{ {
$this->app = $app; $this->app = $app;
$this->name = $this->app->http->getName();
$this->path = $this->app->http->getPath();
} }
/** /**
@ -90,15 +70,15 @@ class MultiApp
{ {
$scriptName = $this->getScriptName(); $scriptName = $this->getScriptName();
$defaultApp = $this->app->config->get('app.default_app') ?: 'index'; $defaultApp = $this->app->config->get('app.default_app') ?: 'index';
$appName = $this->app->http->getName();
if ($this->name || ($scriptName && !in_array($scriptName, ['index', 'router', 'think']))) { if ($appName || ($scriptName && !in_array($scriptName, ['index', 'router', 'think']))) {
$appName = $this->name ?: $scriptName; $appName = $appName ?: $scriptName;
$this->app->http->setBind(); $this->app->http->setBind();
} else { } else {
// 自动多应用识别 // 自动多应用识别
$this->app->http->setBind(false); $this->app->http->setBind(false);
$appName = null; $appName = null;
$this->appName = '';
$bind = $this->app->config->get('app.domain_bind', []); $bind = $this->app->config->get('app.domain_bind', []);
@ -142,7 +122,7 @@ class MultiApp
$appName = $map['*']; $appName = $map['*'];
} else { } else {
$appName = $name ?: $defaultApp; $appName = $name ?: $defaultApp;
$appPath = $this->path ?: $this->app->getBasePath() . $appName . DIRECTORY_SEPARATOR; $appPath = $this->app->http->getPath() ?: $this->app->getBasePath() . $appName . DIRECTORY_SEPARATOR;
if (!is_dir($appPath)) { if (!is_dir($appPath)) {
$express = $this->app->config->get('app.app_express', false); $express = $this->app->config->get('app.app_express', false);
@ -189,10 +169,9 @@ class MultiApp
*/ */
protected function setApp(string $appName): void protected function setApp(string $appName): void
{ {
$this->appName = $appName;
$this->app->http->name($appName); $this->app->http->name($appName);
$appPath = $this->path ?: $this->app->getBasePath() . $appName . DIRECTORY_SEPARATOR; $appPath = $this->app->http->getPath() ?: $this->app->getBasePath() . $appName . DIRECTORY_SEPARATOR;
$this->app->setAppPath($appPath); $this->app->setAppPath($appPath);
// 设置应用命名空间 // 设置应用命名空间

View File

@ -68,7 +68,7 @@ class Url extends UrlBuild
return $url; return $url;
} }
public function build() public function build(): string
{ {
// 解析URL // 解析URL
$url = $this->url; $url = $this->url;

View File

@ -1 +1,2 @@
/api /api
/works

View File

@ -1,5 +1,2 @@
/.idea
/.vscode !.gitignore
pay_order.php
*.log
.env

View File

@ -346,9 +346,13 @@
elem: "#zip-button", elem: "#zip-button",
url: "{:url('article/uploads')}", url: "{:url('article/uploads')}",
data: { type: "zip" }, data: { type: "zip" },
accept: "file", //普通文件 accept: "file",
before: function(obj){
layer.load();
},
done: function (res) { done: function (res) {
if (res.status == 0) { layer.closeAll('loading');
if (res.status === 0) {
$('input[name="upzip"]').val(res.url); $('input[name="upzip"]').val(res.url);
layer.msg("上传成功"); layer.msg("上传成功");
} else { } else {

View File

@ -18,7 +18,7 @@
<div class="layui-row layui-col-space15"> <div class="layui-row layui-col-space15">
<div class="layui-col-md8"> <div class="layui-col-md8">
<div class="fly-panel" style="margin-bottom: 0;"> <div class="fly-panel" style="margin-bottom: 0;">
<div class="layui-tab-card"> <div class="layui-tab layui-tab-card">
<ul class="layui-tab-title"> <ul class="layui-tab-title">
<li {if condition="$type eq 'all'" } class="layui-this" {/if}><a href="{$Request.domain}{:url('cate_type',['ename' => $Request.param.ename,'type' => 'all'])} " >{:lang('all')}</a></li> <li {if condition="$type eq 'all'" } class="layui-this" {/if}><a href="{$Request.domain}{:url('cate_type',['ename' => $Request.param.ename,'type' => 'all'])} " >{:lang('all')}</a></li>
<li {if condition="$type eq 'jie'" } class="layui-this" {/if}><a href="{$Request.domain}{:url('cate_type',['ename' => $Request.param.ename,'type' => 'jie'])} ">{:lang('end')}</a></li> <li {if condition="$type eq 'jie'" } class="layui-this" {/if}><a href="{$Request.domain}{:url('cate_type',['ename' => $Request.param.ename,'type' => 'jie'])} ">{:lang('end')}</a></li>
@ -31,8 +31,8 @@
<li> <li>
{if ($article.jie == 1)} {if ($article.jie == 1)}
<div class="que-sta-jie"> <div class="que-sta-jie">
<span >已解</span> <span>已解</span>
<span >&radic;</span> <span>&radic;</span>
</div> </div>
{else /} {else /}
<div class="que-sta-ask"> <div class="que-sta-ask">

View File

@ -27,9 +27,9 @@
{block name="content"} {block name="content"}
<main class="py-2 py-md-2 pb-3"> <main class="py-2 py-md-2 pb-3">
<div class="container"> <div class="layui-container">
<div class="row"> <div class="layui-row layui-col-space15">
<div class="col-lg-8"> <div class="layui-col-md8">
<div class="post"><h1>{$sysInfo.webname}</h1></div> <div class="post"><h1>{$sysInfo.webname}</h1></div>
<section id="main" class="list-home list-grid list-grid-padding"> <section id="main" class="list-home list-grid list-grid-padding">
{article:list} {article:list}
@ -83,31 +83,31 @@
</div> </div>
</nav> </nav>
</div> </div>
<div class="sidebar col-lg-4 d-none d-lg-block"> <div class="sidebar layui-col-md4 d-none d-lg-block">
<div class="theiaStickySidebar"> <div class="theiaStickySidebar">
<!--博客列表广告赞助位--> <!--博客列表广告赞助位-->
{:hook('ads_blog_cate_rimg')} {:hook('ads_blog_cate_rimg')}
<dl class="function" id="rongkeji_remenwenzhang"> <dl class="function" id="rongkeji_remenwenzhang">
<dt class="function_t">热门文章</dt> <dt class="function_t">热门文章</dt>
<dd class="function_c"> <dd class="function_c">
<ul> <ul>
{volist name="artHot" id="vo"} {volist name="artHot" id="vo"}
<li style="display: block;"> <li style="display: block;">
<div class="list-body fanpian"> <div class="list-body fanpian">
<a href="{$Request.domain}{$vo.url}" target="_blank">{$vo.title}</a> <a href="{$Request.domain}{$vo.url}" target="_blank">{$vo.title}</a>
</div> </div>
<div class="list-footer"> <div class="list-footer">
<div class="text-muted text-xs"><time class="d-inline-block">{$vo.create_time|date='Y-m-d'}</time></div> <div class="text-muted text-xs"><time class="d-inline-block">{$vo.create_time|date='Y-m-d'}</time></div>
</div> </div>
</li> </li>
{/volist} {/volist}
</ul> </ul>
</dd> </dd>
</dl> </dl>
<!--博客列表友情链接--> <!--博客列表友情链接-->
{:hook('ads_blog_cate_flink')} {:hook('ads_blog_cate_flink')}
</div> </div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -27,9 +27,9 @@
{block name="column"}<div class="layui-hide-xs">{include file="/public/column" /}</div>{/block} {block name="column"}<div class="layui-hide-xs">{include file="/public/column" /}</div>{/block}
{block name="content"} {block name="content"}
<main class="py-2 py-md-2 pb-3" style="transform: none"> <main class="py-2 py-md-2 pb-3" style="transform: none">
<div class="container" style="transform: none"> <div class="layui-container" style="transform: none">
<div class="row" style="transform: none"> <div class="layui-row layui-col-space15" style="transform: none">
<div class="col-lg-8" itemscope itemType=""> <div class="layui-col-md8" itemscope itemType="">
<div class="post card"> <div class="post card">
<section class="card-body"> <section class="card-body">
<div class="post-header border-bottom mb-4 pb-4"> <div class="post-header border-bottom mb-4 pb-4">
@ -199,7 +199,7 @@
</div> </div>
</section> </section>
</div> </div>
<div class="sidebar col-lg-4 d-none d-lg-block"> <div class="sidebar layui-col-md4 d-none d-lg-block">
<div class="theiaStickySidebar"> <div class="theiaStickySidebar">
{//作者} {//作者}
<dl class="function" id="rongkeji_User"> <dl class="function" id="rongkeji_User">
@ -223,7 +223,7 @@
<div class="row g-0 text-center"> <div class="row g-0 text-center">
<div class="col"><div class="font-theme h5">{$article.user.article_count}</div><div class="text-xs text-muted">文章</div></div> <div class="col"><div class="font-theme h5">{$article.user.article_count}</div><div class="text-xs text-muted">文章</div></div>
<div class="col"><div class="font-theme h5">{$article.user.comments_count}</div><div class="text-xs text-muted">评论</div></div> <div class="col"><div class="font-theme h5">{$article.user.comments_count}</div><div class="text-xs text-muted">评论</div></div>
<div class="col"><div class="font-theme h5">{$userTagCount}</div><div class="text-xs text-muted">标签</div></div> <div class="col"><div class="font-theme h5">{$zanCount}</div><div class="text-xs text-muted">被赞</div></div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -348,14 +348,18 @@
elem: '#zip-button' elem: '#zip-button'
,url: "{:url('article/uploads')}" //改成您自己的上传接口 ,url: "{:url('article/uploads')}" //改成您自己的上传接口
,data: {type:'zip'} ,data: {type:'zip'}
,accept: 'file' //普通文件 ,accept: 'file',
,done: function(res){ before: function(obj){
if(res.status == 0){ layer.load();
$('input[name="upzip"]').val(res.url); },
notify.success(res.msg); done: function(res){
} else { layer.closeAll('loading');
notify.error(res.msg); if(res.status === 0){
} $('input[name="upzip"]').val(res.url);
notify.success(res.msg);
} else {
notify.error(res.msg);
}
} }
}); });

View File

@ -100,73 +100,132 @@
</div> </div>
</div> </div>
{//评论内容} {//评论}
<div class="fly-panel detail-box" id="flyReply"> <div class="fly-panel">
<span style="font-size:18px;">评论 {$article.comments_count}</span>
<ul class="jieda" id="jieda">
{article:comment}
<li data-id="{comment:id /}" class="jieda-daan">
<a name="item-1111111111"></a>
<div class="detail-about detail-about-reply">
<a class="fly-avatar" href="{comment:ulink /}">
<img src="{comment:uimg /}" alt=" "><i class="iconfont icon-renzheng" title="认证信息"></i>
</a>
<div class="fly-detail-user">
<a href="{comment:ulink /}" class="fly-link">
<cite>{comment:uname /}</cite>
</a>
{if condition="$article.user_id eq $comment.user_id"}<span>({:lang('poster')})</span>{/if}
<span>{comment:usign /}</span>
</div>
<div class="detail-hits"><span class="post-time" data="{comment:time}"></span>{:hook('ipShow',$comment.user.city)}</span>
</div>
</div>
{//加密未解密评论不可查看}
{if($article.read_type == 0 || (($article.read_type == 1) && $passJieMi))}
<div class="detail-body jieda-body photos">{comment:content /}</div>
<div class="jieda-reply">
<span class="jieda-zan {if($comment.zan != 0)}zanok{/if}" type="zan">
<i class="iconfont icon-zan"></i><em>{comment:zan /}</em>
</span>
<span type="reply"><i class="iconfont icon-svgmoban53"></i>{:lang('reply')}</span>
{//评论编辑删除采纳权限}
<div class="jieda-admin">
{if ((session('user_id') == $comment.user_id) && (getLimtTime($comment.create_time) < 2)) OR ($user.auth ?? '')}
<span type="edit" class="comment-edit" data-id="{comment:id /}">{:lang('edit')}</span>
<span type="del">{:lang('delete')}</span>
{/if}
</div>
</div>
{else /}
<div class="detail-body jieda-body photos">
<i class="layui-icon layui-icon-password" style="font-size: 24px; color: #FF5722;"></i>
评论解密后查看
</div>
{/if}
</li>
{/article:comment}
</ul>
<div style="text-align: center" id="pages"></div>
{//评论}
{if session('?user_id') AND ( config('taoler.config.is_reply') == 1 ) AND ( $article.is_reply == 1 )} {if session('?user_id') AND ( config('taoler.config.is_reply') == 1 ) AND ( $article.is_reply == 1 )}
<div class="layui-form layui-form-pane"> <div class="layui-form layui-form-pane">
<div class="layui-form-item layui-form-text"> <div class="layui-form-item layui-form-text">
<a name="comment"></a> <a name="comment"></a>
<div class="layui-input-block"> <div class="layui-input-block">
<textarea id="L_content" name="content" required lay-verify="required" placeholder="{:lang('please input the content')}" class="layui-textarea fly-editor" style="height: 150px;"></textarea> <textarea id="L_content" name="content" required lay-verify="required" placeholder="{:lang('please input the content')}" class="layui-textarea fly-editor"></textarea>
</div> </div>
</div> </div>
<div class="layui-form-item"> <div class="layui-form-item">
<input type="hidden" name="article_id" value="{$article.id}"> <input type="hidden" name="article_id" value="{$article.id}">
<input type="hidden" name="user_id" value="{:session('user_id')}">
<button class="layui-btn" lay-filter="user-comment" lay-submit>{:lang('submit comments')}</button> <button class="layui-btn" lay-filter="user-comment" lay-submit>{:lang('submit comments')}</button>
</div> </div>
</div> </div>
{/if} {/if}
</div>
{//评论内容}
<div class="fly-panel detail-box" id="flyReply">
<span style="font-size:18px;">评论 {$article.comments_count}</span>
<ul class="jieda" id="jieda">
{article:comment}
<li data-id="{comment:id /}" class="jieda-daan">
<div class="detail-about detail-about-reply">
<a class="fly-avatar" href="{comment:ulink /}">
<img src="{comment:uimg /}" alt="{comment:uname}">
</a>
<div class="fly-detail-user">
<a href="{comment:ulink /}" class="fly-link">
<cite>{comment:uname /}</cite>
</a>
{if condition="$article.user_id eq $comment.user_id"}<span>({:lang('poster')})</span>{/if}
<span>{comment:usign /}</span>
</div>
<div class="detail-hits">
<span class="post-time" data="{comment:time}"></span>{:hook('ipShow',$comment.user.city)}</span>
</div>
{//加密未解密评论不可查看}
{if($article.read_type == 0 || (($article.read_type == 1) && $passJieMi))}
<div class="detail-body jieda-body photos">{comment:content /}</div>
<div class="jieda-reply">
<span class="jieda-zan {if($comment.zan != 0)}zanok{/if}" type="zan">
<i class="iconfont icon-zan"></i><em>{comment:zan /}</em>
</span>
<span type="reply" data-pid="{comment:id /}" data-tid="{comment:uid /}"><i class="iconfont icon-svgmoban53"></i>{:lang('reply')}</span>
{//评论编辑删除采纳权限}
<div class="jieda-admin">
{if ((session('user_id') == $comment.user_id) && (getLimtTime($comment.create_time) < 2)) OR ($user.auth ?? '')}
<span type="edit" class="comment-edit" data-id="{comment:id /}">{:lang('edit')}</span>
<span type="del">{:lang('delete')}</span>
{/if}
</div>
{// 第二层回复}
{notempty name="$comment.children"}
{volist name="$comment.children" id="vo"}
<div class="layui-clear" style="margin:10px 0; padding: 10px; border: 1px solid #f0f0f0; background: #f6f6f6">
<a style="display: inline-block; float: left; width: 50px;"><img src="{$vo.user.user_img}" style="width: 30px; height: 30px; border-radius: 15px; object-fit: cover"></a>
<div style="float: left;width: calc(100% - 50px);">
<div>{$vo.user.name} {$vo.create_time|date='Y-m-d H:i'}</div>
<div class="detail-body jieda-body photos">{$vo.content|raw}</div>
<div class="jieda-reply">
<span class="jieda-zan {if($vo.zan != 0)}zanok{/if}" type="zan">
<i class="iconfont icon-zan"></i><em>{$vo.zan}</em>
</span>
<span type="reply" data-pid="{$vo.id}" data-tid="{$vo.user.id}"><i class="iconfont icon-svgmoban53"></i>{:lang('reply')}</span>
{//评论编辑删除采纳权限}
<div class="jieda-admin">
{if ((session('user_id') == $vo.user.id) && (getLimtTime($vo.create_time) < 2)) OR ($user.auth ?? '')}
<span type="edit" class="comment-edit" data-id="{$vo.id}">{:lang('edit')}</span>
<span type="del">{:lang('delete')}</span>
{/if}
</div>
</div>
</div>
</div>
{// 第三层回复}
{notempty name="$vo.children"}
{volist name="$vo.children" id="voo"}
<div class="layui-clear" style="margin:10px 0; padding: 10px; border: 1px solid #f0f0f0;">
<a style="display: inline-block; float: left; width: 50px;"><img src="{$voo.user.user_img}" style="width: 30px; height: 30px; object-fit: cover; border-radius: 15px;"></a>
<div style="float: left;width: calc(100% - 50px);">
<div>{$voo.user.name} 回复 {$voo.touser} {$voo.create_time|date='Y-m-d H:i'}</div>
<div class="detail-body jieda-body photos">{$voo.content|raw}</div>
<div class="jieda-reply">
<span class="jieda-zan {if($voo.zan != 0)}zanok{/if}" type="zan">
<i class="iconfont icon-zan"></i><em>{$voo.zan}</em>
</span>
<span type="reply" data-pid="{$vo.id}" data-tid="{$voo.user.id}"><i class="iconfont icon-svgmoban53"></i>{:lang('reply')}</span>
{//评论编辑删除采纳权限}
<div class="jieda-admin">
{if ((session('user_id') == $voo.user.id) && (getLimtTime($voo.create_time) < 2)) OR ($user.auth ?? '')}
<span type="edit" class="comment-edit" data-id="{$voo.id}">{:lang('edit')}</span>
<span type="del">{:lang('delete')}</span>
{/if}
</div>
</div>
</div>
</div>
{/volist}
{/notempty}
{/volist}
{/notempty}
</div>
{else /}
<div class="detail-body jieda-body photos">
<i class="layui-icon layui-icon-password" style="font-size: 24px; color: #FF5722;"></i>
评论解密后查看
</div>
{/if}
</div>
</li>
{/article:comment}
</ul>
<div style="text-align: center" id="pages"></div>
</div> </div>
</div> </div>
{//右栏} {//右栏}
<div class="layui-col-md4"> <div class="layui-col-md4">
<div class="fly-panel"> <div class="fly-panel">
@ -206,7 +265,7 @@
{/block} {/block}
{block name="script"} {block name="script"}
{:hook('taonyeditor')}
{:hook('taoplayer')} {:hook('taoplayer')}
@ -310,37 +369,67 @@ layui.use(['fly', 'face','colorpicker', 'laypage'], function(){
}); });
} }
}); });
//评论需要登陆 // 评论接口
form.on('submit(user-comment)',function (data){ function comment(data){
var index = layer.load(1); if (uid == -1) {
var filed = data.field; layer.msg('请先登陆',{icon:5,time:2000},function(){location.href = "{:url('login/index')}"});
if (uid == -1) { return false;
layer.msg('请先登陆',{icon:5,time:2000},function(){location.href = "{:url('login/index')}"});
} else {
$.ajax({
type: "post",
url: "{:url('article/comment')}",
data: filed,
dataType: "json",
success:function (data) {
if (data.code == 0) {
layer.msg(data.msg,{icon:6,time:2000},function () {
location.reload(true);
});
}else {
layer.open({title:'评论失败',content:data.msg,icon:5,anim:6});
}
} }
}); var index = layer.load(1);
$.ajax({
type: "post",
url: "{:url('article/comment')}",
data: data,
dataType: "json",
success:function (res) {
layer.close(index);
if (res.code === 0) {
layer.msg(res.msg,{icon:6,time:2000},function () {location.reload(true)});
}else {
layer.open({title:'评论失败',content:res.msg,icon:5,anim:6});
}
}
});
} }
return false;
// 评论
form.on('submit(user-comment)',function (data){
comment(data.field);
}); });
// 回复用户
$("span[type='reply']").on('click',function (){
var pid = $(this).attr('data-pid');
var tid = $(this).data('tid');
var html =
'<form class="layui-form user-comment" style="margin-left:50px;">' +
'<div>' +
'<input type="hidden" name="article_id" value="{$article.id}">' +
'<input name="pid" value="'+ pid +'" class="layui-hide">' +
'<input name="to_user_id" value="'+ tid +'" class="layui-hide">' +
'<textarea name="content" required lay-verify="required" class="layui-textarea fly-editor" style="height: 100px; right: 5px; margin: 10px 5px;"></textarea>' +
'<button type="submit" class="layui-btn" lay-submit lay-filter="submit-user-comment">提交</button>' +
'</div>' +
'</form>';
var forms = $(this).nextAll('form');
if(forms.length == 0) {
// 移除其它评论块
$('.user-comment').remove();
//动态添加评论块
$(this).next().after(html);
}
})
//提交回复
form.on('submit(submit-user-comment)', function(data){
comment(data.field);
return false;
})
// 评论分页 // 评论分页
laypage.render({ laypage.render({
elem: "pages", //注意,这里的 test1 是 ID不用加 # 号 elem: "pages", //注意,这里的 test1 是 ID不用加 # 号
count: "{$article.comments_count}", //数据总数,从服务端得到 count: "{$comments['total']}", //数据总数,从服务端得到
limit: 10, limit: 10,
curr: "{$page}", curr: "{$page}",
//获取起始页 //获取起始页
@ -352,7 +441,7 @@ layui.use(['fly', 'face','colorpicker', 'laypage'], function(){
//首次不执行 //首次不执行
if (!first) { if (!first) {
$.post("{:url('article/detail')}", { id: id, page: page }, function () { $.post("{:url('article/detail')}", { id: id, page: page }, function () {
location.href = url + '?page=' + page + '#flyReply'; location.href = url + '?page=' + page + '#comment';
}); });
} }
}, },
@ -397,7 +486,7 @@ layui.use(['fly', 'face','colorpicker', 'laypage'], function(){
</script> </script>
{:hook('taoplyr')} {:hook('taoplyr')}
{:hook('taonyeditor')}
{//图片点击放大} {//图片点击放大}
{include file="/public/images-click" /} {include file="/public/images-click" /}

View File

@ -1,11 +1,11 @@
{extend name="public:base" /} {extend name="public:base" /}
{block name="title"}{$sysInfo.webtitle}{/block} {block name="title"}{system:webtitle /}{/block}
{block name="keywords"}{$sysInfo.keywords}{/block} {block name="keywords"}{system:keywords /}{/block}
{block name="description"}{$sysInfo.descript}{/block} {block name="description"}{system:descript}{/block}
{block name="ogtitle"}<meta property="og:title" content="{$sysInfo.webtitle}" />{/block} {block name="ogtitle"}<meta property="og:title" content="{system:webtitle /}" >{/block}
{block name="ogdescription"}<meta property="og:description" content="{$sysInfo.descript}" />{/block} {block name="ogdescription"}<meta property="og:description" content="{system:descript /}" >{/block}
{block name="ogimage"}<meta property="og:image" content="{$Request.domain}{$sysInfo.logo}" />{/block} {block name="ogimage"}<meta property="og:image" content="{$Request.domain}{system:logo /}" >{/block}
{block name="meta"}{/block} {block name="meta"}{/block}
{block name="link"} {block name="link"}
<!-- 特效丶样式 --> <!-- 特效丶样式 -->
@ -15,31 +15,35 @@
{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-md8"> <div class="layui-col-md8">
<!--首页幻灯--> <!--首页幻灯-->
{:hook('ads_slider')} {:hook('ads_slider')}
<!--置顶文章-->
<!--置顶文章-->
<div class="fly-panel"> <div class="fly-panel">
<div class="fly-panel-title fly-filter"> <div class="fly-panel-title fly-filter">
<a>{:lang('top')}</a> <span>{:lang('top')}</span>
<a href="#signin" class="layui-hide-sm layui-show-xs-block fly-right" id="LAY_goSignin" style="color: #FF5722;">{:lang('go sign')}</a> <a href="#signin" class="layui-hide-sm layui-show-xs-block fly-right" id="LAY_goSignin">{:lang('go sign')}</a>
</div> </div>
<ul class="fly-list"> <ul class="fly-list">
<div class="layui-carousel" id="ID-carousel">
{volist name="artTop" id="top"} <div carousel-item>
{include file="public/index-topforum" /} {volist name="artTop" id="top"}
{/volist} {include file="public/index-topforum" /}
{/volist}
</div>
</div>
</ul> </ul>
</div> </div>
<!--文章列表-->
<!--文章列表-->
<section id="main" class="list-home list-grid list-grid-padding"> <section id="main" class="list-home list-grid list-grid-padding">
{volist name="artList" id="article"} {volist name="artList" id="article"}
<article class="list-item block card-plain"> <article class="list-item block card-plain">
{if getOnepic($article.content)} {if getOnepic($article.content)}
<figure class="media media-3x2 col-4 col-md-4 d-none d-md-block"> <figure class="media media-3x2 d-none d-md-block">
<a class="media-content" href="{article:link /}" title="{article:title /}"> <a class="media-content" href="{article:link /}" title="{article:title /}">
<img src="{:getOnepic($article.content)}" alt="{article:title /}"> <img src="{:getOnepic($article.content)}" alt="{article:title /}">
</a> </a>
@ -79,15 +83,17 @@
{/volist} {/volist}
</section> </section>
<!--更多帖子-->
<div class="fly-panel" style="margin-bottom: 0;"> <div class="fly-panel" style="margin-bottom: 0;">
<div style="text-align: center"> <div style="text-align: center">
<div class="laypage-main"> <div class="laypage-main">
<a href="{$Request.domain}{:url('cate',['ename'=>'all'])}" class="laypage-next">{:lang('more post')}</a> <a href="{$Request.domain}{:url('cate',['ename'=>'all'])}" class="laypage-next">{:lang('more post')}</a>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
{//右栏} {//右栏}
<div class="layui-col-md4"> <div class="layui-col-md4">
<!--签到--> <!--签到-->
@ -121,27 +127,40 @@
{:hook('ads_index_rfimg')} {:hook('ads_index_rfimg')}
<!--友情链接--> <!--友情链接-->
{:hook('ads_index_flink')} {:hook('ads_index_flink')}
</div> </div>
</div> </div>
</div> </div>
<!--移动端菜单-->
{include file="public/menu" /} {include file="public/menu" /}
{/block} {/block}
{block name="script"} {block name="script"}
<script> <script>
layui.use(['util','laytpl'], function(){ layui.use(['util'], function(){
let util = layui.util; let util = layui.util;
let carousel = layui.carousel;
// 置顶文章
//tpl模板给发布时间赋值 //tpl模板给发布时间赋值
$("time").each(function () { $("time").each(function () {
var othis = $(this); var othis = $(this);
var datetime = othis.attr("datetime"); var datetime = othis.attr("datetime");
var posttime = layui.util.timeAgo(datetime, 30); var posttime = util.timeAgo(datetime, 30);
othis.text(posttime); othis.text(posttime);
}); });
// 渲染 - 设置时间间隔、动画类型、宽高度等属性
carousel.render({
elem: '#ID-carousel',
interval: 2000,
anim: 'updown',
arrow: 'none',
indicator: 'none',
width: 'auto',
height: '80px'
});
}); });
</script> </script>
{/block} {/block}

View File

@ -37,19 +37,11 @@
<link rel="stylesheet" href="{$Request.domain}/static/layui/css/layui.css"> <link rel="stylesheet" href="{$Request.domain}/static/layui/css/layui.css">
<link rel="stylesheet" href="{$Request.domain}/static/res/css/global.css"> <link rel="stylesheet" href="{$Request.domain}/static/res/css/global.css">
{block name="link"}{/block} {block name="link"}{/block}
<!-- 5+ 引擎环境下自动隐藏无关元素,适配App -->
<style>
.html5plus .html5plus-hide {display: none}
{if strpos($Request.SERVER.HTTP_USER_AGENT,"Html5Plus") !== false} html body{margin-top: 1px;} {/if}
</style>
<script src="/static/share/plusShare.js" type="text/javascript" charset="utf-8"></script> <script src="/static/share/plusShare.js" type="text/javascript" charset="utf-8"></script>
{$sysInfo.showlist|raw} {$sysInfo.showlist|raw}
</head> </head>
<body > <body >
<script> if(navigator.userAgent.indexOf("Html5Plus") > -1) {document.body.classList.add("html5plus")} </script>
{if strpos($Request.SERVER.HTTP_USER_AGENT,"Html5Plus") === false}
{include file="public/header" /} {include file="public/header" /}
{/if}
{block name="column"}导航{/block} {block name="column"}导航{/block}
{block name="content"}内容{/block} {block name="content"}内容{/block}
{include file="public/footer" /} {include file="public/footer" /}

View File

@ -1,21 +1,25 @@
<div class="fly-panel fly-column layui-hide-xs"> <div class="fly-panel fly-column layui-hide-xs">
<div class="layui-container fly-nav-sub"> <div class="layui-container fly-nav-sub">
<ul class="layui-clear"> <ul class="layui-nav layui-bg-white layui-hide-xs">
<li class="layui-hide-xs {if ($Request.param.ename =='' && $Request.param.id =='')} layui-this {/if}" > <li class="layui-nav-item layui-hide-xs {if ($Request.param.ename =='' && $Request.param.id =='')} layui-this {/if}" >
<a href="{$Request.domain}">{:lang('home page')}</a> <a href="{$Request.domain}">{:lang('home page')}</a>
</li> </li>
{volist name="subcatelist" id="vo"} {//导航nav}
<li {if($vo.ename eq $Request.param.ename)} class='layui-this' {/if}> {if config('taoler.config.nav_top') == 0}
<span style="color: #8d8d8d">></span> {taoler:nav}
<a href="{$Request.domain}{:url('cate',['ename' => $vo.ename])}">{:cookie('think_lang') == 'en-us' ? $vo.ename : $vo.catename}</a> <li class="layui-nav-item {if condition='$nav.ename eq $Request.param.ename'} layui-this {/if}" >
<a href="{nav:link /}">{nav:title} {if condition="$nav.is_hot eq 1"} <span class="layui-badge-dot"></span> {/if}</a>
{notempty name="nav.children"}
<dl class="layui-nav-child"> <!-- 二级菜单 -->
{taoler:snav}
<dd><a href="{snav:link /}">{snav:name /}</a></dd>
{/taoler:snav}
</dl>
{/notempty}
</li> </li>
{/volist} {/taoler:nav}
<li class="layui-hide-xs layui-hide-sm layui-show-md-inline-block"><span class="fly-mid"></span></li>
{if session('?user_id')}
<li class="layui-hide-xs layui-hide-sm layui-show-md-inline-block"><a href="{:url('user/post')}">{:lang('my post')}</a></li>
<li class="layui-hide-xs layui-hide-sm layui-show-md-inline-block"><a href="{:url('user/post#collection')}">{:lang('my collection')}</a></li>
{/if} {/if}
</ul> </ul>
<div class="fly-column-right layui-hide-xs"> <div class="fly-column-right layui-hide-xs">
<a href="{:url('add_article',['cate'=>$Request.param.ename])}" class="layui-btn" id="add_post">{:lang('add post')}</a> <a href="{:url('add_article',['cate'=>$Request.param.ename])}" class="layui-btn" id="add_post">{:lang('add post')}</a>
</div> </div>

View File

@ -1,5 +1,5 @@
<footer class="footer"> <footer class="footer">
<div class="container"> <div class="layui-container">
<div class="footer-col footer-col-logo"> <div class="footer-col footer-col-logo">
<img src="{$sysInfo.logo}" alt="{$sysInfo.webname}"></div> <img src="{$sysInfo.logo}" alt="{$sysInfo.webname}"></div>
<div class="footer-col footer-col-copy"> <div class="footer-col footer-col-copy">

View File

@ -1,14 +1,15 @@
<div class="fly-header layui-bg-black"> <div class="fly-header layui-bg-black">
<div class="layui-container"> <div class="layui-container">
<a class="fly-logo layui-hide-xs" href="{$Request.domain}"><img src="{$Request.domain}{$sysInfo.logo}" alt="{$sysInfo.webname}logo" width="135" height="37"></a> <a class="fly-logo layui-hide-xs" href="{$Request.domain}"><img src="{$Request.domain}{$sysInfo.logo}" alt="{system:webname}logo"></a>
<!--头部伸缩侧边栏--> <!--头部伸缩侧边栏-->
<div class="site-tree-mobile-top layui-hide"><i class="layui-icon layui-icon-spread-left"></i></div> <div class="site-tree-mobile-top layui-hide"><i class="layui-icon layui-icon-spread-left"></i></div>
<div class="site-mobile-shade-top"></div> <div class="site-mobile-shade-top"></div>
{//移动端LOGO} {//移动端LOGO}
<a class="layui-hide-md layui-hide-sm" href="{$Request.domain}" ><img class="fly-logo-m" src="{$Request.domain}{$sysInfo.m_logo}" alt="logo"></a> <a class="layui-hide-md layui-hide-sm" href="{$Request.domain}" ><img class="fly-logo-m" src="{$Request.domain}{$sysInfo.m_logo}" alt="logo"></a>
{//导航nav}
<ul class="layui-nav fly-nav layui-hide-xs"> <ul class="layui-nav fly-nav layui-hide-xs">
{//导航nav} {if config('taoler.config.nav_top') != 0}
{taoler:nav} {taoler:nav}
<li class="layui-nav-item {if condition='$nav.ename eq $Request.param.ename'} layui-this {/if}" > <li class="layui-nav-item {if condition='$nav.ename eq $Request.param.ename'} layui-this {/if}" >
<a href="{nav:link /}">{nav:title} {if condition="$nav.is_hot eq 1"} <span class="layui-badge-dot"></span> {/if}</a> <a href="{nav:link /}">{nav:title} {if condition="$nav.is_hot eq 1"} <span class="layui-badge-dot"></span> {/if}</a>
{notempty name="nav.children"} {notempty name="nav.children"}
@ -19,8 +20,8 @@
</dl> </dl>
{/notempty} {/notempty}
</li> </li>
{/taoler:nav} {/taoler:nav}
{/if}
{// 后台自定义头部链接} {// 后台自定义头部链接}
{:hook('ads_header_link')} {:hook('ads_header_link')}
</ul> </ul>
@ -28,7 +29,7 @@
{//头部右栏} {//头部右栏}
<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')}">
<li class="layui-nav-item"> <li class="layui-nav-item">
<span class="fly-search layui-hide-xs" data-url="{:url('user_search')}"><i class="layui-icon">&#xe615;</i></span> <span class="fly-search layui-hide-xs" data-url="{:url('user_search')}"><i class="layui-icon layui-icon-search"></i></span>
</li> </li>
<!-- 登录 --> <!-- 登录 -->
{if session('?user_id')} {if session('?user_id')}
@ -36,14 +37,12 @@
<li class="layui-nav-item"><a href="{$Request.domain}">{:lang('home page')}</a></li> <li class="layui-nav-item"><a href="{$Request.domain}">{:lang('home page')}</a></li>
{/if} {/if}
<li class="layui-nav-item"> <li class="layui-nav-item">
<a class="fly-nav-avatar" href="javascript:;"><cite class="layui-hide-xs">{$user.name}</cite><img src="{$Request.domain}{$user.user_img}"></a> <a class="fly-nav-avatar" ><cite class="layui-hide-xs">{$user.name}</cite><img src="{$Request.domain}{$user.user_img}"></a>
<dl class="layui-nav-child"> <dl class="layui-nav-child">
<dd><a href="{:url('user/index')}"><i class="layui-icon">&#xe612;</i>{:lang('user center')}</a></dd> <dd><a href="{:url('user/index')}"><i class="layui-icon layui-icon-username"></i>{:lang('user center')}</a></dd>
<dd><a href="{:url('user/set')}"><i class="layui-icon">&#xe620;</i>{:lang('set info')}</a></dd> <dd><a href="{:url('user/set')}"><i class="layui-icon layui-icon-set"></i>{:lang('set info')}</a></dd>
<hr> <dd><a href="{:url('user/message')}"><i class="iconfont icon-tongzhi"></i>{:lang('my message')}</a></dd>
<dd><a href="{:url('user/message')}"><i class="iconfont icon-tongzhi" style="top: 4px;"></i>{:lang('my message')}</a></dd> <dd><a href="{:url('user/home',['id'=>$user.id])}"><i class="layui-icon layui-icon-home"></i>{:lang('my page')}</a></dd>
<dd><a href="{:url('user/home',['id'=>$user.id])}"><i class="layui-icon" style="margin-left: 2px; font-size: 22px;">&#xe68e;</i>{:lang('my page')}</a></dd>
<hr style="margin: 5px 0;">
<dd><a data-url="{:url('user/logout')}" href="javascript:void(0)" class="logi_logout" style="text-align: center;">{:lang('logout')}</a></dd> <dd><a data-url="{:url('user/logout')}" href="javascript:void(0)" class="logi_logout" style="text-align: center;">{:lang('logout')}</a></dd>
</dl> </dl>
</li> </li>

View File

@ -1,26 +1,28 @@
<li> <div>
<a href="{$Request.domain}{:url('user/home',['id'=>$top.user_id])}" class="fly-avatar"> <li>
<img src="{$Request.domain}{$top.user.user_img}" alt="{$top.user.name}"> <a href="{$Request.domain}{:url('user/home',['id'=>$top.user_id])}" class="fly-avatar">
</a> <img src="{$Request.domain}{$top.user.user_img}" alt="{$top.user.name}">
<h2><a href="{$Request.domain}{$top.url}" style="color:{$top.title_color ?? ''};">{$top.title}</a></h2>
<div class="fly-list-info">
{if config('taoler.config.cate_show') == 1}
<a class="layui-badge">{:cookie('think_lang') == 'en-us' ? $top.cate.ename : $top.cate.catename}</a>
{/if}
<a href="{$Request.domain}{:url('user/home',['id'=>$top.user_id])}" link>
<cite>{$top.user.nickname ?: $top.user.name}</cite>
</a> </a>
<i>{$top.create_time|date='Y-m-d'}</i> <h2><a href="{$Request.domain}{$top.url}" style="color:red;">{$top.title}</a></h2>
{$top.has_img ?= '<span><i class="layui-icon layui-icon-picture" style="color: #5FB878;"></i></span>'} <div class="fly-list-info">
{$top.has_video ?= '<span><i class="layui-icon layui-icon-play" style="color: #FF5722;"></i></span>'} {if config('taoler.config.cate_show') == 1}
{$top.has_audio ?= '<span><i class="layui-icon layui-icon-speaker" style="color: #000000;"></i></span>'} <a class="layui-badge">{:cookie('think_lang') == 'en-us' ? $top.cate.ename : $top.cate.catename}</a>
{$top.upzip ?= '<span><i class="layui-icon layui-icon-file-b" style="color: #009688;" title="附件"></i></span>'} {/if}
<span class=" layui-hide-xs" title="浏览"> <i class="iconfont" title="浏览">&#xe60b;</i> {$top.pv} </span> <a href="{$Request.domain}{:url('user/home',['id'=>$top.user_id])}" link>
<span class="fly-list-nums"><i class="iconfont icon-pinglun1" title="回答"></i> {$top.comments_count}</span> <cite>{$top.user.nickname ?: $top.user.name}</cite>
</div> </a>
<div class="fly-list-badge"> <i>{$top.create_time|date='Y-m-d'}</i>
{if ($top.is_top == 1)} {$top.has_img ?= '<span><i class="layui-icon layui-icon-picture" style="color: #5FB878;"></i></span>'}
<i class="layui-icon layui-icon-top layui-hide-md" style="font-size: 25px; color: #000000;"></i> <span class="layui-badge layui-bg-black layui-hide-xs" >{:lang('top')}</span> {$top.has_video ?= '<span><i class="layui-icon layui-icon-play" style="color: #FF5722;"></i></span>'}
{/if} {$top.has_audio ?= '<span><i class="layui-icon layui-icon-speaker" style="color: #000000;"></i></span>'}
</div> {$top.upzip ?= '<span><i class="layui-icon layui-icon-file-b" style="color: #009688;" title="附件"></i></span>'}
</li> <span class=" layui-hide-xs" title="浏览"> <i class="iconfont" title="浏览">&#xe60b;</i> {$top.pv} </span>
<span class="fly-list-nums"><i class="iconfont icon-pinglun1" title="回答"></i> {$top.comments_count}</span>
</div>
<div class="fly-list-badge">
{if ($top.is_top == 1)}
<i class="layui-icon layui-icon-top layui-hide-md" style="font-size: 25px; color: #000000;"></i> <span class="layui-badge layui-bg-black layui-hide-xs" >{:lang('top')}</span>
{/if}
</div>
</li>
</div>

View File

@ -32,22 +32,23 @@
</div> </div>
<hr> <hr>
<ul> <ul>
{volist name="cateList" id="cate"} {taoler:nav}
<li {if condition="$cate.ename eq $Request.param.ename"} class="layui-this" {/if} class="layui-menu-item-group layui-menu-item-down" lay-options="{type: 'group'}"> <li {if condition="$nav.ename eq $Request.param.ename"} class="layui-this" {/if} class="layui-menu-item-group layui-menu-item-down" lay-options="{type: 'group'}">
<div class="layui-menu-body-title"> <div class="layui-menu-body-title">
<a href="{$Request.domain}{:url('cate',['ename' => $cate.ename])}"><i class="layui-icon {$cate.icon}"></i> {:cookie('think_lang') == 'en-us' ? $cate.ename : $cate.catename} <a href="{nav:link /}">
{if condition="$cate.is_hot eq 1"}<span class="layui-badge-dot"></span>{/if} <i class="layui-icon {nav:icon /}"></i>{nav:title}
</a> {if condition="$nav.is_hot eq 1"}<span class="layui-badge-dot"></span>{/if}
</div> </a>
{notempty name="cate.children"} </div>
<ul> {notempty name="nav.children"}
{volist name="cate.children" id="vo2"} <ul>
<li><a href="{$Request.domain}{:url('cate',['ename' => $vo2.ename])}">{$vo2.catename}</a></li> {taoler:snav}
{/volist} <li><a href="{snav:link /}">{snav:name /}</a></li>
</ul> {/taoler:snav}
{/notempty} </ul>
</li> {/notempty}
{/volist} </li>
{/taoler:nav}
</ul> </ul>
</li> </li>