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)
{
if(Request::isAjax()){
try {
$arr = explode(",",$id);
foreach($arr as $v){
$comm = CommentModel::find($v);
$result = $comm->delete();
$comm->delete();
}
if($result){
return json(['code'=>0,'msg'=>'删除成功']);
}else{
} catch (\Exception $e) {
return json(['code'=>-1,'msg'=>'删除失败']);
}
}

View File

@ -12,6 +12,7 @@ namespace app\admin\controller\content;
use app\common\controller\AdminController;
use app\common\model\Article;
use app\facade\Cate;
use think\App;
use think\facade\View;
use think\facade\Request;
@ -43,7 +44,7 @@ class Forum extends AdminController
public function list()
{
$data = Request::only(['id','name','title','sec']);
$data = Request::only(['id','name','title','sec','cate_id']);
$where = [];
if (!empty($data['sec'])) {
switch ($data['sec']) {
@ -73,13 +74,17 @@ class Forum extends AdminController
$where[] = ['id', '=', $data['id']];
}
if(!empty($data['cate_id'])){
$where[] = ['cate_id', '=', $data['cate_id']];
}
if(!empty($data['name'])){
$userId = Db::name('user')->where('name',$data['name'])->value('id');
$where[] = ['user_id', '=', $userId];
}
if(!empty($data['title'])){
$where[] = ['title', 'like', $data['title'].'%'];
$where[] = ['title', 'like', '%'.$data['title'].'%'];
}
$list = $this->model->getList($where, input('limit'), input('page'));
@ -91,6 +96,7 @@ class Forum extends AdminController
'poster' => $v['user']['name'],
'avatar' => $v['user']['user_img'],
'title' => htmlspecialchars($v['title']),
'cate' => $v['cate']['catename'],
'url' => $this->getArticleUrl($v['id'], 'index', $v['cate']['ename']),
'content' => strip_tags($v['content']),
'posttime' => $v['update_time'],
@ -163,11 +169,6 @@ class Forum extends AdminController
}
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');
}
@ -236,29 +237,22 @@ class Forum extends AdminController
}
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();
}
//删除帖子
//删除帖子 多选和单独
public function delete($id)
{
if(Request::isAjax()){
try {
$arr = explode(",",$id);
foreach($arr as $v){
$article = Article::find($v);
$result = $article->together(['comments'])->delete();
$article->together(['comments'])->delete();
}
if($result){
return json(['code'=>0,'msg'=>'删除成功']);
}else{
} catch (\Exception $e) {
return json(['code'=>-1,'msg'=>'删除失败']);
}
}
@ -352,7 +346,7 @@ class Forum extends AdminController
/**
* 分类
* 分类
* @return Json
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
@ -374,6 +368,28 @@ class Forum extends AdminController
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过滤函数
protected function filtr($arr){
if($arr === '' || $arr === null){

View File

@ -16,6 +16,8 @@ use think\facade\Request;
use think\facade\Db;
use app\common\model\User as UserModel;
use app\common\lib\Uploads;
use app\common\validate\User as userValidate;
use think\exception\ValidateException;
class User extends AdminController
@ -79,6 +81,14 @@ class User extends AdminController
//
if(Request::isAjax()){
$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();
$salt = substr(md5($data['create_time']),-6);
// 密码
@ -100,9 +110,13 @@ class User extends AdminController
{
if(Request::isAjax()){
$data = Request::only(['id','name','email','user_img','password','phone','sex']);
if(empty($data['password'])) {
unset($data['password']);
} 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{
Db::name('user')->update($data);
return json(['code'=>0,'msg'=>'编辑成功']);

View File

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

View File

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

View File

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

View File

@ -13,12 +13,7 @@
<div class="layui-col-md3">
<label class="layui-form-label">{:lang('special column')}</label>
<div class="layui-input-block">
<select lay-verify="required" name="cate_id" lay-filter="column">
<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 id="CateId" class="xm-select-demo"></div>
</div>
</div>
<div class="layui-col-md8">
@ -89,10 +84,8 @@
<script src="/static/component/layui/layui.js"></script>
<script src="/static/component/pear/pear.js"></script>
<script src="/static/addons/taonyeditor/tinymce/tinymce.min.js"></script>
<script src="/static/xm-select.js"></script>
<script>
layui.extend({
editor: '{/}/static/addons/taonyeditor/js/taonyeditor'
}).use(["form", "colorpicker", "upload",'editor','xmSelect'], function () {
@ -120,6 +113,34 @@
$('[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标签
$(function(){
//1.渲染标签
@ -205,8 +226,12 @@
elem: "#zip-button",
url: "{:url('content.forum/uploads')}", //改成您自己的上传接口
data: { type: "zip" },
accept: "file", //普通文件
accept: "file",
before: function(obj){
layer.load();
},
done: function (res) {
layer.closeAll('loading');
if (res.status === 0) {
$('input[name="upzip"]').val(res.url);
layer.msg("上传成功");

View File

@ -14,12 +14,7 @@
<div class="layui-col-md3">
<label class="layui-form-label">{:lang('special column')}</label>
<div class="layui-input-block">
<select lay-verify="required" name="cate_id" lay-filter="column">
<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 id="CateId" class="xm-select-demo"></div>
</div>
</div>
<div class="layui-col-md8">
@ -90,19 +85,18 @@
<script src="/static/component/layui/layui.js"></script>
<script src="/static/component/pear/pear.js"></script>
<script src="/static/addons/taonyeditor/tinymce/tinymce.min.js"></script>
<script src="/static/xm-select.js"></script>
<script>
layui.extend({
editor: '{/}/static/addons/taonyeditor/js/taonyeditor'
}).use(['colorpicker','form','upload', 'editor'], function(){
}).use(['colorpicker','form','upload', 'editor','xmSelect'], function(){
var $ = layui.jquery
,colorpicker = layui.colorpicker
,form = layui.form
,upload = layui.upload;
var artId = "{$article.id}";
var editor = layui.editor;
var xmSelect = layui.xmSelect;
// 初始化编辑器
editor.render({
@ -152,6 +146,35 @@
$('[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(){
var content = $(this).val()
@ -208,8 +231,12 @@
elem: '#zip-button'
,url: "{:url('content.forum/uploads')}" //改成您自己的上传接口
,data: {type:'zip'}
,accept: 'file' //普通文件
,done: function(res){
,accept: 'file',
before: function(obj){
layer.load();
},
done: function(res){
layer.closeAll('loading');
if(res.status === 0){
$('input[name="upzip"]').val(res.url);
layer.msg('上传成功');

View File

@ -9,26 +9,32 @@
<div class="layui-card">
<div class="layui-card-body">
<form class="layui-form" action="">
<div class="layui-form-item">
<div class="layui-form-item layui-inline">
<div class="layui-row layui-col-space15 ">
<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>
<div class="layui-input-block">
<input type="text" name="id" placeholder="请输入" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item layui-inline">
<div class="layui-col-md3">
<label class="layui-form-label">发帖人</label>
<div class="layui-input-block">
<input type="text" name="name" placeholder="请输入" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item layui-inline">
<div class="layui-col-md3">
<label class="layui-form-label">标题</label>
<div class="layui-input-block">
<input type="text" name="title" placeholder="请输入" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item layui-inline">
<div class="layui-col-md3">
<label class="layui-form-label">状态</label>
<div class="layui-input-block">
<select name="sec">
@ -42,7 +48,7 @@
</select>
</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">
<i class="layui-icon layui-icon-search"></i>
查询
@ -100,12 +106,13 @@
<script>
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
,form = layui.form
,table = layui.table;
let common = layui.common;
var toast = layui.toast;
var xmSelect = layui.xmSelect;
//如果你是采用模版自带的编辑器,你需要开启以下语句来解析。
var taonystatus = "{:hook('taonystatus')}";
@ -120,6 +127,7 @@
,{field: 'avatar', title: '头像', width: 60, templet: '#avatarTpl'}
,{field: 'poster', title: '账号',width: 80}
,{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: 'posttime', title: '时间',width: 120, sort: true}
,{field: 'top', title: '置顶', templet: '#forum-istop', width: 80, align: 'center'}
@ -144,6 +152,38 @@
}, '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) {
if (obj.event === 'remove') {
window.remove(obj);
@ -269,9 +309,7 @@
}
window.batchRemove = function(obj) {
var checkIds = common.checkField(obj,'id');
if (checkIds === "") {
layer.msg("未选中数据", {
icon: 3,
@ -280,25 +318,25 @@
return false;
}
layer.confirm('确定要删除这些用户', {
layer.confirm('确定要删除?', {
icon: 3,
title: '提示'
}, function(index) {
layer.close(index);
let loading = layer.load();
$.ajax({
url: "{:url('system.admin/delete')}",
url: "{:url('content.forum/delete')}?id=" + checkIds,
dataType: 'json',
type: 'delete',
data:{"id":checkIds},
success: function(result) {
layer.close(loading);
if (result.success) {
if (result.code === 0) {
layer.msg(result.msg, {
icon: 1,
time: 1000
}, function() {
table.reload('user-table');
table.reload('forum-table');
});
} else {
layer.msg(result.msg, {
@ -312,7 +350,7 @@
}
window.refresh = function(param) {
table.reload('user-table');
table.reload('forum-table');
}
});

View File

@ -76,6 +76,7 @@
layui.use(['form', 'jquery'], function() {
let form = layui.form;
let $ = layui.jquery;
let upload = layui.upload;
form.on('submit(user-save)', function(data) {
$.ajax({
@ -103,6 +104,33 @@
})
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>

View File

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

View File

@ -79,12 +79,14 @@ if(!function_exists('getUserImg'))
function getArtContent($content)
{
//过滤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('/\s*/','',$content);
$content = preg_replace('/\[[^\]]+\]/','',$content);
return mb_substr(strip_tags($content),0,150).'...';
return mb_substr($content,0,150).'...';
}
//根据帖子收藏主键ID查询帖子名称

View File

@ -18,7 +18,6 @@ use think\facade\Db;
use think\facade\Session;
use think\facade\Cache;
use app\BaseController as BaseCtrl;
use app\common\model\Cate;
/**
* 控制器基础类
@ -39,8 +38,6 @@ class BaseController extends BaseCtrl
//变量赋给模板
View::assign([
//显示分类导航
'cateList' => $this->showNav(),
//显示子分类导航
'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
protected function showSubnav()
{
// dump($this->showNav());
//1.查询父分类id
$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;
use think\facade\Lang;
use think\Response;
class Msgres
{
@ -66,13 +67,13 @@ class Msgres
}
/**
* 成功提示
* @param string $strMsg
* @param string|null $url
* @param string $data
* @return string|\think\response\Json
* @param array|$data
* @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 = [
'code' => self::getCode('success'),
'msg' => self::getMsg($strMsg),

View File

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

View File

@ -389,7 +389,7 @@ class Article extends Model
$query->field('id,name,user_img');
},
'cate' => function($query){
$query->field('id,ename');
$query->field('id,ename,catename');
}
])
->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();
}
// 查询兄弟分类
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
@ -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
public function getUrlAttr($value,$data)
{

View File

@ -35,11 +35,28 @@ class Comment extends Model
//获取评论
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])
->order(['cai'=>'asc','create_time'=>'asc'])
->paginate(['list_rows'=>10, 'page'=>$page])
// ->paginate(['list_rows'=>10, 'page'=>$page])
->append(['touser'])
->select()
->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' => ''];
}
}
//回帖榜
@ -155,4 +172,29 @@ class Comment extends Model
}
}
// 获取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)
{
//查询使用邮箱或者用户名登陆
$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){
return Lang::get('Account disabled');

View File

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

View File

@ -8,7 +8,7 @@
* @FilePath: \TaoLer\app\common\taglib\Article.php
* Copyright (c) 2020~2022 https://www.aieok.com All rights reserved.
*/
//declare (strict_types = 1);
declare (strict_types = 1);
namespace app\common\taglib;
@ -42,6 +42,7 @@ class Article extends TagLib
'istop' => ['attr' => '', 'close' => 0],
'detail' => ['attr' => 'name', 'close' => 0],
// 'detail' => ['attr' => '', 'close' => 0],
];
@ -145,12 +146,24 @@ class Article extends TagLib
return '{$article.cate.id}';
}
// 详情
// public function tagDetail($tag)
// {
// return '{$article.' . $tag['name'] . '}';
// }
// 详情
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
{
//dump($this->article);
@ -162,6 +175,17 @@ class Article extends TagLib
return $parseStr;
}
// 评论
public function tagComment2($tag, $content): string
{
$parse = '<?php ';
$parse .= ' ?>';
$parse .= '{volist name="comments" id="comment" empty= "还没有内容"}';
$parse .= $content;
$parse .= '{/volist}';
return $parse;
}
// 评论
public function tagComment($tag, $content): string
{

View File

@ -14,8 +14,45 @@ use think\template\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],
'showlist' => ['attr' => '', 'close' => 0],
'blackname' => ['attr' => '', 'close' => 0],
'sys_version_num' => ['attr' => '', 'close' => 0],
'sys_version_num'=> ['attr' => '', 'close' => 0],
'key' => ['attr' => '', 'close' => 0],
'clevel' => ['attr' => '', 'close' => 0],
'api_url' => ['attr' => '', 'close' => 0],

View File

@ -26,7 +26,8 @@ class Taoler extends TagLib
public function tagNav($tag, $content): string
{
$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 .= '{/volist}';
return $parse;
@ -35,18 +36,22 @@ class Taoler extends TagLib
public function tagSnav($tag, $content): string
{
$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 .= '{/volist}';
$parse .= '{/notempty}';
return $parse;
}
public function tagGnav($tag, $content): string
{
$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 .= '{/volist}';
$parse .= '{/notempty}';
return $parse;
}

View File

@ -17,6 +17,7 @@ class User extends Validate
protected $rule = [
'name|用户名' => 'require|min:2|max:18|chsDash|unique:user',
'email|邮箱' => 'require|email|unique:user',
'phone|手机号' => 'require|mobile|unique:user',
'password|密码' => 'require|min:6|max:20',
'repassword|确认密码'=>'require|confirm:password',
'nickname|昵称' => 'require|min:2|max:20',
@ -48,11 +49,23 @@ class User extends Validate
->remove('email', 'unique');
}
//phone登陆验证场景
public function sceneLoginPhone()
{
return $this->only(['phone','password'])
->remove('phone', 'unique');
}
//注册验证场景
public function sceneReg()
{
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_suffix' => 'html',
// 定义内置标签
//'taglib_build_in' => 'app\common\taglib\Article',
// 预先加载的标签库
'taglib_pre_load' => $taglib_pre_load,
// 模板文件名分隔符

View File

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

View File

@ -76,21 +76,16 @@ class Article extends BaseController
$page = input('page',1);
//输出内容
$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) {
$artDetail->content = '本文已加密!请输入正确密码查看!';
}
if(is_null($artDetail)){
// 抛出 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);
//被赞
$zanCount = Db::name('user_zan')->where('user_id', $artDetail['user_id'])->count('id');
//赞列表
$userZanList = [];
@ -162,7 +157,7 @@ class Article extends BaseController
'cid' => $id,
'lrDate_time' => $lrDate_time,
'userZanList' => $userZanList,
'userTagCount'=> $userTagCount,
'zanCount' => $zanCount,
'jspage' => 'jie',
'passJieMi' => session('art_pass_'.$id),
$download,
@ -186,8 +181,10 @@ class Article extends BaseController
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'];
// halt($data);
$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){
@ -616,15 +613,22 @@ class Article extends BaseController
/**
* 分类树
* @return \think\response\Json
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getCateTree()
{
$data = $this->showNav();
$count = count($data);
$cateList = Cate::field('id,pid,catename,sort')->where(['status' => 1])->select()->toArray();
$list = getTree($cateList);
// 排序
$cmf_arr = array_column($list, 'sort');
array_multisort($cmf_arr, SORT_ASC, $list);
$count = count($list);
$tree = [];
if($count){
$tree = ['code'=>0, 'msg'=>'ok','count'=>$count];
$tree['data'] = $data;
$tree['data'] = $list;
}
return json($tree);

View File

@ -31,7 +31,7 @@ class Index extends BaseController
$types = input('type');
//置顶文章
$artTop = Article::getArtTop(5);
//首页文章列表,显示20
//首页文章列表,显示15
$artList = Article::getArtList(15);
//热议文章
$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";
//判断输入的是邮箱还是用户名
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登陆验证
$data['email'] = $data['name'];
unset($data['name']);

View File

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

View File

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

View File

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

View File

@ -5,7 +5,7 @@
Target Server Version : 80020 (8.0.20)
File Encoding : 65001
Date: 14/03/2023 19:57:43
Date: 8/06/2023 19:57:43
*/
SET NAMES utf8mb4;
@ -313,36 +313,29 @@ CREATE TABLE `tao_collection` (
PRIMARY KEY (`id`) USING BTREE
) 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
-- ----------------------------
DROP TABLE IF EXISTS `tao_comment`;
CREATE TABLE `tao_comment` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '评论id',
`pid` int NOT NULL DEFAULT 0 COMMENT '父id',
`content` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '评论',
`article_id` int NOT NULL COMMENT '文章id',
`user_id` int NOT NULL COMMENT '评论用户',
`to_user_id` int NULL DEFAULT NULL COMMENT '给用户留言',
`zan` tinyint NOT NULL DEFAULT 0 COMMENT '',
`cai` enum('1','0') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '0' COMMENT '0求解1采纳',
`status` enum('0','-1','1') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '1' COMMENT '1通过0待审-1禁止',
`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,
INDEX `aiticle_id`(`article_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;
-- ----------------------------
-- 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);
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '评论表' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for tao_cunsult
@ -359,10 +352,6 @@ CREATE TABLE `tao_cunsult` (
PRIMARY KEY (`id`) USING BTREE
) 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
-- ----------------------------
@ -376,14 +365,12 @@ CREATE TABLE `tao_friend_link` (
`update_time` int NOT NULL COMMENT '更新时间',
`delete_time` int NOT NULL,
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
-- ----------------------------
INSERT INTO `tao_friend_link` VALUES (1, 'taobao', 'https://www.taobao.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);
INSERT INTO `tao_friend_link` VALUES (1, 'taoler', 'https://www.aieok.com', '', 0, 0, 0);
-- ----------------------------
-- Table structure for tao_mail_server
@ -421,13 +408,7 @@ CREATE TABLE `tao_message` (
`update_time` int NOT NULL DEFAULT 0 COMMENT '更新时间',
`delete_time` int NOT NULL DEFAULT 0 COMMENT '删除时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = MyISAM AUTO_INCREMENT = 3 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);
) ENGINE = MyISAM AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '消息表' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for tao_message_to
@ -444,13 +425,7 @@ CREATE TABLE `tao_message_to` (
`update_time` int NOT NULL DEFAULT 0 COMMENT '更新时间',
`delete_time` int NOT NULL DEFAULT 0 COMMENT '删除时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = MyISAM AUTO_INCREMENT = 3 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);
) ENGINE = MyISAM AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '消息详细表' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for tao_push_jscode
@ -467,10 +442,6 @@ CREATE TABLE `tao_push_jscode` (
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '站长平台自动推送js代码' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of tao_push_jscode
-- ----------------------------
-- ----------------------------
-- Table structure for tao_slider
-- ----------------------------
@ -489,13 +460,7 @@ CREATE TABLE `tao_slider` (
`update_time` int NOT NULL DEFAULT 0 COMMENT '更新时间',
`delete_time` int NOT NULL DEFAULT 0 COMMENT '删除时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = MyISAM AUTO_INCREMENT = 3 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);
) ENGINE = MyISAM AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for tao_system
@ -556,10 +521,6 @@ CREATE TABLE `tao_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;
-- ----------------------------
-- Records of tao_tag
-- ----------------------------
-- ----------------------------
-- Table structure for tao_taglist
-- ----------------------------
@ -655,10 +616,6 @@ CREATE TABLE `tao_user_sign` (
PRIMARY KEY (`id`) USING BTREE
) 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
-- ----------------------------
@ -721,8 +678,4 @@ CREATE TABLE `tao_user_zan` (
PRIMARY KEY (`id`) USING BTREE
) 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;

View File

@ -29,12 +29,14 @@ class UserLogin
$id = $user->user['id'];
$u = User::find($id);
//日志
if($type == 'log'){
//$name = $user->user['name'];
$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{
$ipInfo = HttpHelper::get($url)->toJson();
if($ipInfo->status == 'success')
@ -62,6 +64,12 @@ class UserLogin
// }
// }
}
if($type == 'logError'){
$u->allowField(['login_error_num','login_error_time'])->save(['login_error_num'=>$u->login_error_num + 1,'login_error_time'=>time()]);
}
$u->allowField(['city','last_login_ip','last_login_time','login_error_num'])->save(
[
'city' => $city,
@ -71,11 +79,6 @@ class UserLogin
]
);
Log::channel('login')->info('login:{user} {ip}',['user'=>$u->name,'ip'=>$ip]);
}
if($type == 'logError'){
$res = $u->allowField(['login_error_num','login_error_time'])->save(['login_error_num'=>$u->login_error_num + 1,'login_error_time'=>time()]);
}
}
}

43
composer.lock generated
View File

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

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{background-color: #F2F2F2;}
i{font-style: normal;}
h1,h2,h3 {font-weight: 400;}
/* 布局 */
.layui-mm{position: fixed; top: 100px; bottom: 0;}
@ -230,7 +231,7 @@ pre{overflow-y: auto;
text-align: center;
}
/* 搜索 */
/* 搜索 */
.fly-search{display: inline-block; width: 50px; margin-right: 10px; cursor: pointer; font-size: 20px;}
.fly-search .layui-icon{font-size: 20px;}
.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 span{display: inline-block; font-size: 12px; padding-left: 5px;}
/* 签到 */
/* 签到 */
.fly-signin cite{padding: 0 5px; color: #FF5722; font-style: normal;}
.fly-signin .layui-badge-dot{top: -7px; margin-left: 0px;}
.fly-signin-list{padding: 0; line-height: 30px;}
@ -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 .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 a{color:#4f99cf}
.jieda-reply{position:relative; font-size: 14px}
@ -1018,9 +1019,9 @@ blockquote {
}
}
figure {
figure {
margin: 0;
}
}
@media (min-width: 768px){
.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 {
margin-right: .5rem !important;
}
}
}
.ml-1, .mx-1 {
@ -1045,34 +1046,34 @@ blockquote {
.d-inline-block {
display: inline-block !important;
}
.text-muted {
.text-muted {
color: #9ca0ad !important;
}
.text-xs {
}
.text-xs {
font-size: .75rem !important;
}
.text-muted {
}
.text-muted {
color: #6c757d !important;
}
.align-items-center {
}
.align-items-center {
-ms-flex-align: center !important;
align-items: center !important;
}
.flex-fill {
}
.flex-fill {
-ms-flex: 1 1 auto !important;
flex: 1 1 auto !important;
}
}
.list-footer {
margin-top: .5rem;
}
.d-flex {
.d-flex {
display: -ms-flexbox !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;}
}
}

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'));
});
//头条轮播
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",
"version": "1.5.2",
"version_normalized": "1.5.2.0",
"version": "1.5.3",
"version_normalized": "1.5.3.0",
"source": {
"type": "git",
"url": "https://github.com/guzzle/promises.git",
"reference": "b94b2807d85443f9719887892882d0329d1e2598"
"reference": "67ab6e18aaa14d753cc148911d273f6e6cb6721e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/promises/zipball/b94b2807d85443f9719887892882d0329d1e2598",
"reference": "b94b2807d85443f9719887892882d0329d1e2598",
"shasum": ""
"url": "https://api.github.com/repos/guzzle/promises/zipball/67ab6e18aaa14d753cc148911d273f6e6cb6721e",
"reference": "67ab6e18aaa14d753cc148911d273f6e6cb6721e",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"php": ">=5.5"
@ -510,13 +516,8 @@
"require-dev": {
"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",
"extra": {
"branch-alias": {
"dev-master": "1.5-dev"
}
},
"installation-source": "dist",
"autoload": {
"files": [
@ -558,7 +559,7 @@
],
"support": {
"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": [
{
@ -2610,17 +2611,17 @@
},
{
"name": "topthink/framework",
"version": "v6.1.2",
"version_normalized": "6.1.2.0",
"version": "v6.1.3",
"version_normalized": "6.1.3.0",
"source": {
"type": "git",
"url": "https://github.com/top-think/framework.git",
"reference": "67235be5b919aaaf1de5aed9839f65d8e766aca3"
"reference": "7c324e7011246f0064b055b62ab9c3921cf0a041"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/top-think/framework/zipball/67235be5b919aaaf1de5aed9839f65d8e766aca3",
"reference": "67235be5b919aaaf1de5aed9839f65d8e766aca3",
"url": "https://api.github.com/repos/top-think/framework/zipball/7c324e7011246f0064b055b62ab9c3921cf0a041",
"reference": "7c324e7011246f0064b055b62ab9c3921cf0a041",
"shasum": "",
"mirrors": [
{
@ -2646,7 +2647,7 @@
"mockery/mockery": "^1.2",
"phpunit/phpunit": "^7.0"
},
"time": "2023-02-08T02:24:01+00:00",
"time": "2023-05-22T03:02:08+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
@ -2678,7 +2679,7 @@
],
"support": {
"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"
},
@ -2918,17 +2919,17 @@
},
{
"name": "topthink/think-multi-app",
"version": "v1.0.16",
"version_normalized": "1.0.16.0",
"version": "v1.0.17",
"version_normalized": "1.0.17.0",
"source": {
"type": "git",
"url": "https://github.com/top-think/think-multi-app.git",
"reference": "07b9183855150455e1f76f8cbe9d77d6d1bc399f"
"reference": "4055a6187296ac16c0bc7bbab4ed5d92f82f791c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/top-think/think-multi-app/zipball/07b9183855150455e1f76f8cbe9d77d6d1bc399f",
"reference": "07b9183855150455e1f76f8cbe9d77d6d1bc399f",
"url": "https://api.github.com/repos/top-think/think-multi-app/zipball/4055a6187296ac16c0bc7bbab4ed5d92f82f791c",
"reference": "4055a6187296ac16c0bc7bbab4ed5d92f82f791c",
"shasum": "",
"mirrors": [
{
@ -2941,7 +2942,7 @@
"php": ">=7.1.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",
"extra": {
"think": {
@ -2966,10 +2967,10 @@
"email": "liu21st@gmail.com"
}
],
"description": "thinkphp6 multi app support",
"description": "thinkphp multi app support",
"support": {
"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"
},

View File

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

View File

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

View File

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

View File

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

View File

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

2
vendor/services.php vendored
View File

@ -1,5 +1,5 @@
<?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);
return array (
0 => 'taoser\\addons\\Service',

View File

@ -38,7 +38,7 @@ use think\initializer\RegisterService;
*/
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\Domain;
use think\route\Resource;
use think\route\ResourceRegister;
use think\route\Rule;
use think\route\RuleGroup;
use think\route\RuleItem;
@ -182,6 +183,11 @@ class Route
$this->removeSlash = $this->config['remove_slash'];
$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)
@ -317,8 +323,7 @@ class Route
$domainName = is_array($name) ? array_shift($name) : $name;
if (!isset($this->domains[$domainName])) {
$domain = (new Domain($this, $domainName, $rule))
->lazy($this->lazy)
$domain = (new Domain($this, $domainName, $rule, $this->lazy))
->removeSlash($this->removeSlash)
->mergeRuleRegex($this->mergeRuleRegex);
@ -523,19 +528,18 @@ class Route
}
/**
* 设置跨域有效路由规则
* 设置路由规则全局有效
* @access public
* @param Rule $rule 路由规则
* @param string $method 请求类型
* @return $this
*/
public function setCrossDomainRule(Rule $rule, string $method = '*')
public function setCrossDomainRule(Rule $rule)
{
if (!isset($this->cross)) {
$this->cross = (new RuleGroup($this))->mergeRuleRegex($this->mergeRuleRegex);
}
$this->cross->addRuleItem($rule, $method);
$this->cross->addRuleItem($rule);
return $this;
}
@ -554,8 +558,7 @@ class Route
$name = '';
}
return (new RuleGroup($this, $this->group, $name, $route))
->lazy($this->lazy)
return (new RuleGroup($this, $this->group, $name, $route, $this->lazy))
->removeSlash($this->removeSlash)
->mergeRuleRegex($this->mergeRuleRegex);
}
@ -661,12 +664,17 @@ class Route
* @access public
* @param string $rule 路由规则
* @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))
->lazy($this->lazy);
$resource = new Resource($this, $this->group, $rule, $route, $this->rest);
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
{
$this->app->route->setTestMode(true);
$this->app->route->clear();
$this->app->route->lazy(false);
if ($dir) {
$path = $this->app->getRootPath() . 'route' . DIRECTORY_SEPARATOR . $dir . DIRECTORY_SEPARATOR;

View File

@ -13,6 +13,7 @@ declare (strict_types = 1);
namespace think\facade;
use think\Facade;
use think\Response;
use think\route\Dispatch;
use think\route\Domain;
use think\route\Rule;
@ -20,6 +21,7 @@ use think\route\RuleGroup;
use think\route\RuleItem;
use think\route\RuleName;
use think\route\Url as UrlBuild;
use think\route\ResourceRegister as Resource;
/**
* @see \think\Route
@ -48,7 +50,7 @@ use think\route\Url as UrlBuild;
* @method static array getRuleList() 读取路由列表
* @method static void clear() 清空路由规则
* @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 RuleItem any(string $rule, mixed $route) 注册路由
* @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 array|null getRest(string $name = null) 获取rest方法定义的参数
* @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 url(string $url) 默认URL解析
* @method static UrlBuild buildUrl(string $url = '', array $vars = []) URL生成 支持路由反射

View File

@ -68,7 +68,7 @@ class SessionInit
$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;
}

View File

@ -36,6 +36,12 @@ class Redirect extends Response
$this->cacheControl('no-cache,must-revalidate');
}
public function data($data)
{
$this->header['Location'] = $data;
return parent::data($data);
}
/**
* 处理数据
* @access protected
@ -44,8 +50,6 @@ class Redirect extends Response
*/
protected function output($data): string
{
$this->header['Location'] = $data;
return '';
}

View File

@ -77,16 +77,6 @@ abstract class Dispatch
*/
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();
return $this->autoResponse($data);
}

View File

@ -29,12 +29,17 @@ class Domain extends RuleGroup
* @param Route $router 路由对象
* @param string $name 路由域名
* @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->domain = $name;
$this->rule = $rule;
if (!$lazy) {
$this->parseGroupRule($rule);
}
}
/**

View File

@ -19,18 +19,6 @@ use think\Route;
*/
class Resource extends RuleGroup
{
/**
* 资源路由名称
* @var string
*/
protected $resource;
/**
* 资源路由地址
* @var string
*/
protected $route;
/**
* REST方法定义
* @var array
@ -59,7 +47,7 @@ class Resource extends RuleGroup
* 架构函数
* @access public
* @param Route $router 路由对象
* @param RuleGroup $parent 上级对象
* @param RuleGroup|null $parent 上级对象
* @param string $name 资源名称
* @param string $route 路由地址
* @param array $rest 资源定义
@ -69,7 +57,7 @@ class Resource extends RuleGroup
$name = ltrim($name, '/');
$this->router = $router;
$this->parent = $parent;
$this->resource = $name;
$this->rule = $name;
$this->route = $route;
$this->name = strpos($name, '.') ? strstr($name, '.', true) : $name;
@ -84,20 +72,16 @@ class Resource extends RuleGroup
$this->domain = $this->parent->getDomain();
$this->parent->addRuleItem($this);
}
if ($router->isTest()) {
$this->buildResourceRule();
}
}
/**
* 生成资源路由规则
* @access protected
* 解析资源路由规则
* @access public
* @param mixed $rule 路由规则
* @return void
*/
protected function buildResourceRule(): void
public function parseGroupRule($rule): void
{
$rule = $this->resource;
$option = $this->option;
$origin = $this->router->getGroup();
$this->router->setGroup($this);
@ -141,6 +125,7 @@ class Resource extends RuleGroup
}
$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
*/
protected $method;
protected $method = '*';
/**
* 路由变量
@ -572,14 +572,7 @@ abstract class Rule
*/
public function crossDomainRule()
{
if ($this instanceof RuleGroup) {
$method = '*';
} else {
$method = $this->method;
}
$this->router->setCrossDomainRule($this, $method);
$this->router->setCrossDomainRule($this);
return $this;
}

View File

@ -25,15 +25,15 @@ class RuleGroup extends Rule
{
/**
* 分组路由(包括子分组)
* @var array
* @var Rule[]
*/
protected $rules = [];
/**
* 分组路由规则
* @var mixed
* 是否已经解析
* @var bool
*/
protected $rule;
protected $hasParsed;
/**
* MISS路由
@ -57,11 +57,12 @@ class RuleGroup extends Rule
* 架构函数
* @access public
* @param Route $router 路由对象
* @param RuleGroup $parent 上级对象
* @param RuleGroup|null $parent 上级对象
* @param string $name 分组名称
* @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->parent = $parent;
@ -75,8 +76,8 @@ class RuleGroup extends Rule
$this->parent->addRuleItem($this);
}
if ($router->isTest()) {
$this->lazy(false);
if (!$lazy) {
$this->parseGroupRule($rule);
}
}
@ -138,9 +139,7 @@ class RuleGroup extends Rule
}
// 解析分组路由
if ($this instanceof Resource) {
$this->buildResourceRule();
} else {
if (!$this->hasParsed) {
$this->parseGroupRule($this->rule);
}
@ -163,8 +162,8 @@ class RuleGroup extends Rule
}
// 检查分组路由
foreach ($rules as $key => $item) {
$result = $item[1]->check($request, $url, $completeMatch);
foreach ($rules as $item) {
$result = $item->check($request, $url, $completeMatch);
if (false !== $result) {
return $result;
@ -173,9 +172,9 @@ class RuleGroup extends Rule
if (!empty($option['dispatcher'])) {
$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 {
$result = false;
}
@ -222,22 +221,6 @@ class RuleGroup extends Rule
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
@ -246,6 +229,10 @@ class RuleGroup extends Rule
*/
public function parseGroupRule($rule): void
{
if (is_null($rule)) {
return;
}
if (is_string($rule) && is_subclass_of($rule, Dispatch::class)) {
$this->dispatcher($rule);
return;
@ -254,13 +241,14 @@ class RuleGroup extends Rule
$origin = $this->router->getGroup();
$this->router->setGroup($this);
if ($rule instanceof \Closure) {
if ($rule instanceof Closure) {
Container::getInstance()->invokeFunction($rule);
} elseif (is_string($rule) && $rule) {
$this->router->bind($rule, $this->domain);
}
$this->router->setGroup($origin);
$this->hasParsed = true;
}
/**
@ -368,11 +356,19 @@ class RuleGroup extends Rule
/**
* 获取分组的MISS路由
* @access public
* @param string $method 请求类型
* @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->setMiss();
$this->miss = $ruleItem;
$this->miss[$method] = $ruleItem->setMiss();
return $ruleItem;
}
@ -419,7 +414,7 @@ class RuleGroup extends Rule
// 创建路由规则实例
$ruleItem = new RuleItem($this->router, $this, $name, $rule, $route, $method);
$this->addRuleItem($ruleItem, $method);
$this->addRuleItem($ruleItem);
return $ruleItem;
}
@ -428,21 +423,11 @@ class RuleGroup extends Rule
* 注册分组下的路由规则
* @access public
* @param Rule $rule 路由规则
* @param string $method 请求类型
* @return $this
*/
public function addRuleItem(Rule $rule, string $method = '*')
public function addRuleItem(Rule $rule)
{
if (strpos($method, '|')) {
$rule->method($method);
$method = '*';
}
$this->rules[] = [$method, $rule];
if ($rule instanceof RuleItem && 'options' != $method) {
$this->rules[] = ['options', $rule->setAutoOptions()];
}
$this->rules[] = $rule;
return $this;
}
@ -507,7 +492,8 @@ class RuleGroup extends Rule
}
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
* @param Route $router 路由实例
* @param RuleGroup $parent 上级对象
* @param string $name 路由标识
* @param string|null $name 路由标识
* @param string $rule 路由规则
* @param string|\Closure $route 路由地址
* @param string $method 请求类型
@ -77,27 +77,6 @@ class RuleItem extends Rule
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后缀
* @access public

View File

@ -115,6 +115,7 @@ class RuleName
{
$this->item = [];
$this->rule = [];
$this->group = [];
}
/**

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -18,7 +18,7 @@
<div class="layui-row layui-col-space15">
<div class="layui-col-md8">
<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">
<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>
@ -31,8 +31,8 @@
<li>
{if ($article.jie == 1)}
<div class="que-sta-jie">
<span >已解</span>
<span >&radic;</span>
<span>已解</span>
<span>&radic;</span>
</div>
{else /}
<div class="que-sta-ask">

View File

@ -27,9 +27,9 @@
{block name="content"}
<main class="py-2 py-md-2 pb-3">
<div class="container">
<div class="row">
<div class="col-lg-8">
<div class="layui-container">
<div class="layui-row layui-col-space15">
<div class="layui-col-md8">
<div class="post"><h1>{$sysInfo.webname}</h1></div>
<section id="main" class="list-home list-grid list-grid-padding">
{article:list}
@ -83,7 +83,7 @@
</div>
</nav>
</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">
<!--博客列表广告赞助位-->
{:hook('ads_blog_cate_rimg')}

View File

@ -27,9 +27,9 @@
{block name="column"}<div class="layui-hide-xs">{include file="/public/column" /}</div>{/block}
{block name="content"}
<main class="py-2 py-md-2 pb-3" style="transform: none">
<div class="container" style="transform: none">
<div class="row" style="transform: none">
<div class="col-lg-8" itemscope itemType="">
<div class="layui-container" style="transform: none">
<div class="layui-row layui-col-space15" style="transform: none">
<div class="layui-col-md8" itemscope itemType="">
<div class="post card">
<section class="card-body">
<div class="post-header border-bottom mb-4 pb-4">
@ -199,7 +199,7 @@
</div>
</section>
</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">
{//作者}
<dl class="function" id="rongkeji_User">
@ -223,7 +223,7 @@
<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.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>

View File

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

View File

@ -100,16 +100,34 @@
</div>
</div>
{//评论}
<div class="fly-panel">
{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-item layui-form-text">
<a name="comment"></a>
<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"></textarea>
</div>
</div>
<div class="layui-form-item">
<input type="hidden" name="article_id" value="{$article.id}">
<button class="layui-btn" lay-filter="user-comment" lay-submit>{:lang('submit comments')}</button>
</div>
</div>
{/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">
<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>
<img src="{comment:uimg /}" alt="{comment:uname}">
</a>
<div class="fly-detail-user">
<a href="{comment:ulink /}" class="fly-link">
@ -118,18 +136,19 @@
{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 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"><i class="iconfont icon-svgmoban53"></i>{:lang('reply')}</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 ?? '')}
@ -137,6 +156,61 @@
<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">
@ -144,29 +218,14 @@
评论解密后查看
</div>
{/if}
</div>
</li>
{/article:comment}
</ul>
<div style="text-align: center" id="pages"></div>
</div>
</div>
{//评论}
{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-item layui-form-text">
<a name="comment"></a>
<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>
</div>
</div>
<div class="layui-form-item">
<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>
</div>
</div>
{/if}
</div>
</div>
{//右栏}
<div class="layui-col-md4">
<div class="fly-panel">
@ -206,7 +265,7 @@
{/block}
{block name="script"}
{:hook('taonyeditor')}
{:hook('taoplayer')}
@ -311,36 +370,66 @@ layui.use(['fly', 'face','colorpicker', 'laypage'], function(){
}
});
//评论需要登陆
form.on('submit(user-comment)',function (data){
var index = layer.load(1);
var filed = data.field;
// 评论接口
function comment(data){
if (uid == -1) {
layer.msg('请先登陆',{icon:5,time:2000},function(){location.href = "{:url('login/index')}"});
} else {
return false;
}
var index = layer.load(1);
$.ajax({
type: "post",
url: "{:url('article/comment')}",
data: filed,
data: data,
dataType: "json",
success:function (data) {
if (data.code == 0) {
layer.msg(data.msg,{icon:6,time:2000},function () {
location.reload(true);
});
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:data.msg,icon:5,anim:6});
layer.open({title:'评论失败',content:res.msg,icon:5,anim:6});
}
}
});
}
// 评论
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({
elem: "pages", //注意,这里的 test1 是 ID不用加 # 号
count: "{$article.comments_count}", //数据总数,从服务端得到
count: "{$comments['total']}", //数据总数,从服务端得到
limit: 10,
curr: "{$page}",
//获取起始页
@ -352,7 +441,7 @@ layui.use(['fly', 'face','colorpicker', 'laypage'], function(){
//首次不执行
if (!first) {
$.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>
{:hook('taoplyr')}
{:hook('taonyeditor')}
{//图片点击放大}
{include file="/public/images-click" /}

View File

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

View File

@ -1,19 +1,23 @@
<div class="fly-panel fly-column layui-hide-xs">
<div class="layui-container fly-nav-sub">
<ul class="layui-clear">
<li class="layui-hide-xs {if ($Request.param.ename =='' && $Request.param.id =='')} layui-this {/if}" >
<ul class="layui-nav layui-bg-white layui-hide-xs">
<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>
</li>
{volist name="subcatelist" id="vo"}
<li {if($vo.ename eq $Request.param.ename)} class='layui-this' {/if}>
<span style="color: #8d8d8d">></span>
<a href="{$Request.domain}{:url('cate',['ename' => $vo.ename])}">{:cookie('think_lang') == 'en-us' ? $vo.ename : $vo.catename}</a>
{//导航nav}
{if config('taoler.config.nav_top') == 0}
{taoler:nav}
<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>
{/volist}
<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>
{/taoler:nav}
{/if}
</ul>
<div class="fly-column-right layui-hide-xs">

View File

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

View File

@ -1,13 +1,14 @@
<div class="fly-header layui-bg-black">
<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-mobile-shade-top"></div>
{//移动端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>
<ul class="layui-nav fly-nav layui-hide-xs">
{//导航nav}
<ul class="layui-nav fly-nav layui-hide-xs">
{if config('taoler.config.nav_top') != 0}
{taoler:nav}
<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>
@ -20,7 +21,7 @@
{/notempty}
</li>
{/taoler:nav}
{/if}
{// 后台自定义头部链接}
{:hook('ads_header_link')}
</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')}">
<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>
<!-- 登录 -->
{if session('?user_id')}
@ -36,14 +37,12 @@
<li class="layui-nav-item"><a href="{$Request.domain}">{:lang('home page')}</a></li>
{/if}
<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">
<dd><a href="{:url('user/index')}"><i class="layui-icon">&#xe612;</i>{:lang('user center')}</a></dd>
<dd><a href="{:url('user/set')}"><i class="layui-icon">&#xe620;</i>{:lang('set info')}</a></dd>
<hr>
<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" style="margin-left: 2px; font-size: 22px;">&#xe68e;</i>{:lang('my page')}</a></dd>
<hr style="margin: 5px 0;">
<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 layui-icon-set"></i>{:lang('set info')}</a></dd>
<dd><a href="{:url('user/message')}"><i class="iconfont icon-tongzhi"></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 data-url="{:url('user/logout')}" href="javascript:void(0)" class="logi_logout" style="text-align: center;">{:lang('logout')}</a></dd>
</dl>
</li>

View File

@ -1,8 +1,9 @@
<li>
<div>
<li>
<a href="{$Request.domain}{:url('user/home',['id'=>$top.user_id])}" class="fly-avatar">
<img src="{$Request.domain}{$top.user.user_img}" alt="{$top.user.name}">
</a>
<h2><a href="{$Request.domain}{$top.url}" style="color:{$top.title_color ?? ''};">{$top.title}</a></h2>
<h2><a href="{$Request.domain}{$top.url}" style="color:red;">{$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>
@ -23,4 +24,5 @@
<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>
</li>
</div>

View File

@ -32,22 +32,23 @@
</div>
<hr>
<ul>
{volist name="cateList" id="cate"}
<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'}">
{taoler:nav}
<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">
<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}
{if condition="$cate.is_hot eq 1"}<span class="layui-badge-dot"></span>{/if}
<a href="{nav:link /}">
<i class="layui-icon {nav:icon /}"></i>{nav:title}
{if condition="$nav.is_hot eq 1"}<span class="layui-badge-dot"></span>{/if}
</a>
</div>
{notempty name="cate.children"}
{notempty name="nav.children"}
<ul>
{volist name="cate.children" id="vo2"}
<li><a href="{$Request.domain}{:url('cate',['ename' => $vo2.ename])}">{$vo2.catename}</a></li>
{/volist}
{taoler:snav}
<li><a href="{snav:link /}">{snav:name /}</a></li>
{/taoler:snav}
</ul>
{/notempty}
</li>
{/volist}
{/taoler:nav}
</ul>
</li>