This commit is contained in:
taoser 2021-10-12 16:46:49 +08:00
parent 087a731c8f
commit de91c8b1dd
12 changed files with 250 additions and 169 deletions

View File

@ -7,8 +7,8 @@
* 后台http://adm.aieok.com:888
* 账号test
* 密码test123
* 版本TaoLer 1.8.8
* 日期2021.10.11
* 版本TaoLer 1.8.4
* 日期2021.8.18
#### 项目地址
@ -21,10 +21,11 @@
1. 采用动态密码加密,相同密码在入库时具有唯一性,即使管理员也无法破解,用户信息安全牢固。
2. 系统采用最新版TinkPHP6框架开发底层安全可靠数据查询更快运行效率更高网站速度更快。
3. 自适应前端,桌面和移动端访问界面友好简洁,模块清晰。
4. 完善的后台系统管理便捷动态菜单和权限角色分配系统。支持3级菜单和无限极分类。
5. 双升级系统,可支持自动和手动升级。可在线检测并升级系统,保持网站的更新和安全。
6. 代码开源,不设暗门操作,更安全。
7. 项目会长期维护,优化更新。
4. 多模板多单页,可以设置不同分类模块,不同模板单页,论坛模块,问答模板,企业站模板,产品模块等自由开发。
5. 完善的后台系统管理便捷动态菜单和权限角色分配系统。支持3级菜单和无限极分类。
6. 双升级系统,可支持自动和手动升级。可在线检测并升级系统,保持网站的更新和安全。
7. 代码开源,不设暗门操作,更安全。
8. 项目会长期维护,优化更新。
#### 构架组成
@ -34,11 +35,12 @@
- 前端Fly template V3.0
#### 构架介绍
thinkphp:
快速、简单的面向对象的轻量级PHP开发框架出色的性能和至简代码的更注重易用性。代码维护方便。
layui前端
layui前端:
极简、丰盈简单高效模块化UI框架体积轻盈组件丰盈。
Fly模板:
一款至简的社区模板,适合政府机构、教育机构、事业单位、商业企业、个人站长等众多行业领域
一款至简的社区模板。
#### 安装教程
1. 首选确保满目使用环境要求php > 7.2, mysql > 5.7.3
@ -53,8 +55,8 @@
}
```
4. 首次安装访问域名http://www.youdomain.com可自动跳转到/install/index进行引导安装重新安装需删除public目录下install.lock。
5. 安装前需要先创建mysql数据库(准备:数据库连接地址,数据库用户名,数据库密码,数据库端口,建好在数据库名)
6. 请牢记安装设置的管理员用户名和密码默认admin/123456。前后台的管理员密码一致。前后端管理员账户是独立的,前端主要对文章内容的审查管理等操作。
5. 安装前需要先创建mysql数据库(准备:数据库连接地址,数据库用户名,密码,端口)
6. 如果手动导入数据库管理员用户名和密码默认admin/123456前后台的管理员密码一致。前后端管理员账户是独立的,前端主要对文章内容的审查管理等操作。
#### 使用说明

View File

@ -5,7 +5,7 @@ namespace app;
class Request extends \think\Request
{
//过滤空格
//protected $filter = ['trim','htmlspecialchars','strip_tags'];
protected $filter = ['trim'];
protected $filter = ['trim','htmlspecialchars','strip_tags'];
//protected $filter = ['trim'];
}

View File

@ -6,9 +6,9 @@ use think\facade\View;
use think\facade\Db;
use think\facade\Request;
use think\facade\Config;
use think\exception\ValidateException;
use app\admin\model\Addons as AddonsModel;
use taoler\com\Files;
use taoler\com\Api;
class Addons extends AdminController
{
@ -19,60 +19,123 @@ class Addons extends AdminController
*/
public function index()
{
if(Request::isAjax()){
var_dump(Files::getDirName('../addons/'));
$type = input('type');
//$filter = input('filter') ? input('filter') : 'public-list';
//动态field
switch($type){
//已安装
case 'installed':
$col = [
['type' => 'numbers', 'fixed'=> 'left'],
['field' => 'name','title'=> '插件', 'width'=> 150],
['field'=> 'title','title'=> '标题', 'width'=> 100],
['field'=> 'version','title'=> '版本', 'width'=> 100],
['field' => 'author','title'=> '作者', 'width'=> 100],
['field' => 'description','title'=> '简介', 'minWidth'=> 200],
['field' => 'status','title'=> '状态', 'width'=> 100],
['field' => 'install','title'=> '安装', 'width'=> 100],
['field' => 'ctime','title'=> '到期时间', 'width'=> 150],
['title' => '操作', 'width'=> 220, 'align'=>'center', 'toolbar'=> '#addons-installed-tool']
];
break;
//在线
case 'onlineAddons':
$col = [
['type' => 'numbers', 'fixed'=> 'left'],
['field' => 'name','title'=> '插件', 'width'=> 150],
['field'=> 'title','title'=> '标题', 'width'=> 100],
['field'=> 'version','title'=> '版本', 'width'=> 100],
['field' => 'author','title'=> '作者', 'width'=> 100],
['field' => 'description','title'=> '简介', 'minWidth'=> 200],
['field' => 'price','title'=> '价格(元)'],
['field' => 'status','title'=> '状态', 'width'=> 100],
['field' => 'install','title'=> '安装', 'width'=> 100],
['field' => 'ctime','title'=> '时间', 'width'=> 150],
['title' => '操作', 'width'=> 150, 'align'=>'center', 'toolbar'=> '#addons-tool']
];
break;
default:
$col = [
['type' => 'numbers', 'fixed'=> 'left'],
['field' => 'name','title'=> '插件', 'width'=> 150],
['field'=> 'title','title'=> '标题', 'width'=> 100],
['field'=> 'version','title'=> '版本', 'width'=> 100],
['field' => 'author','title'=> '作者', 'width'=> 100],
['field' => 'description','title'=> '简介', 'minWidth'=> 200],
['field' => 'status','title'=> '状态', 'width'=> 100],
['field' => 'install','title'=> '安装', 'width'=> 100],
['field' => 'ctime','title'=> '到期时间', 'width'=> 150],
['title' => '操作', 'width'=> 220, 'align'=>'center', 'toolbar'=> '#addons-installed-tool']
];
}
View::assign('col',$col);
return View::fetch();
}
public function addonsList()
{
$type = input('type') ? input('type') : 'installed';
$res = [];
switch($type){
//已安装
case 'installed':
$addons = Files::getDirName('../addons/');
if($addons){
$res = ['code'=>0,'msg'=>'','count'=>5];
foreach($addons as $v){
$info_file = '../addons/'.$v.'/info.ini';
$info = parse_ini_file($info_file);
$res['data'][] = $info;
}
}
break;
//在线
case 'onlineAddons':
$url = $this->getSystem()['api_url'].'/v1/addons';
$addons = Api::urlPost($url,[]);
if( $addons->code !== -1){
$res['code'] = 0;
$res['msg'] = '';
$res['data'] = $addons->data;
}
break;
//已安装
default:
$addons = Files::getDirName('../addons/');
if($addons){
$res = ['code'=>0,'msg'=>'','count'=>5];
foreach($addons as $v){
$info_file = '../addons/'.$v.'/info.ini';
$info = parse_ini_file($info_file);
$res['data'][] = $info;
}
}
break;
}
return json($res);
}
/**
* 显示创建资源表单页.
*
* @return \think\Response
*/
public function add()
public function install()
{
//添加版本
if(Request::isAjax()){
$data = Request::param();
$result = AddonsModel::create($data);
if($result){
$res = ['code'=>0,'msg'=>'添加成功'];
}else{
$res = ['code'=>-1,'msg'=>'添加失败'];
}
return json($res);
}
return View::fetch();
//
}
/**
* 编辑版本
*
* @param int $id
* @return \think\Response
*/
public function edit($id)
{
$addons = AddonsModel::find($id);
if(Request::isAjax()){
$data = Request::only(['id','addons_name','addons_version','addons_auther','addons_resume','addons_price','addons_src']);
$result = $addons->where('id',$id)->save($data);
if($result){
$res = ['code'=>0,'msg'=>'编辑成功'];
}else{
$res = ['code'=>-1,'msg'=>'编辑失败'];
}
return json($res);
}
View::assign('addons',$addons);
return View::fetch();
}
/**
* 上传版本的zip资源
@ -83,24 +146,7 @@ class Addons extends AdminController
*/
public function uploadZip()
{
$id = Request::param();
$file = request()->file('file');
try {
validate(['file'=>'filesize:2048|fileExt:zip,rar,7z'])
->check(array($file));
$savename = \think\facade\Filesystem::disk('public')->putFile('addons',$file);
} catch (think\exception\ValidateException $e) {
echo $e->getMessage();
}
$upload = Config::get('filesystem.disks.public.url');
if($savename){
$name_path =str_replace('\\',"/",$upload.'/'.$savename);
$res = ['code'=>0,'msg'=>'插件上传成功','src'=>$name_path];
} else {
$res = ['code'=>-1,'msg'=>'上传错误'];
}
return json($res);
//
}
/**

View File

@ -64,7 +64,7 @@ class Forum extends AdminController
$forumList = Db::name('article')
->alias('a')
->join('user u','a.user_id = u.id')
->field('a.id as aid,name,user_img,title,a.update_time as update_time,is_top,is_hot,is_reply,a.status as status')
->field('a.id as aid,name,user_img,title,content,a.update_time as update_time,is_top,is_hot,is_reply,a.status as status')
->where('a.delete_time',0)
->where($map)
->where($where)
@ -77,7 +77,7 @@ class Forum extends AdminController
$res['msg'] = '';
$res['count'] = $count;
foreach($forumList as $k=>$v){
$res['data'][]= ['id'=>$v['aid'],'poster'=>$v['name'],'avatar'=>$v['user_img'],'content'=>$v['title'],'posttime'=>date("Y-m-d",$v['update_time']),'top'=>$v['is_top'],'hot'=>$v['is_hot'],'reply'=>$v['is_reply'],'check'=>$v['status']];
$res['data'][]= ['id'=>$v['aid'],'poster'=>$v['name'],'avatar'=>$v['user_img'],'title'=>$v['title'],'content'=>$v['content'],'posttime'=>date("Y-m-d",$v['update_time']),'top'=>$v['is_top'],'hot'=>$v['is_hot'],'reply'=>$v['is_reply'],'check'=>$v['status']];
}
} else {
$res = ['code'=>-1,'msg'=>'没有查询结果!'];
@ -102,16 +102,20 @@ class Forum extends AdminController
public function listdel($id)
{
if(Request::isAjax()){
$article =Article::find($id);
$result = $article->together(['comments'])->delete();
if($result){
return json(['code'=>0,'msg'=>'删除成功']);
}else{
return json(['code'=>-1,'msg'=>'删除失败']);
}
$arr = explode(",",$id);
foreach($arr as $v){
$article =Article::find($v);
$result = $article->together(['comments'])->delete();
}
if($result){
return json(['code'=>0,'msg'=>'删除成功']);
}else{
return json(['code'=>-1,'msg'=>'删除失败']);
}
}
}
//置顶帖子
public function top()
{

View File

@ -2,51 +2,62 @@
{block name="body"}
<div class="layui-fluid">
<div class="layui-card">
<div class="layui-form layui-card-header layuiadmin-card-header-auto">
<div class="layui-form-item">
<div class="layui-inline">
插件分类
</div>
<div class="layui-inline">
<select name="id" lay-filter="LAY-user-adminrole-type">
<option value="">全部插件</option>
<option value="">支付</option>
<option value="">第三方登陆</option>
</select>
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
插件分类
</div>
<div class="layui-inline">
<select name="id" lay-filter="LAY-user-adminrole-type">
<option value="">全部插件</option>
<option value="">支付</option>
<option value="">第三方登陆</option>
</select>
</div>
</div>
</div>
<div class="layui-card-body">
<table id="addons-list" lay-filter="addons-list"></table>
<script type="text/html" id="toolbar">
<div class="layui-btn-group" style="padding-bottom: 10px;">
<button class="layui-btn layuiadmin-btn-admin" data-type="batchdel">刷新</button>
<button class="layui-btn layuiadmin-btn-admin" data-type="add">离线安装</button>
<button class="layui-btn layuiadmin-btn-admin" data-type="add1">离线安装</button>
</div>
<div class="layui-btn-group" style="padding-bottom: 10px;">
<button type="button" class="layui-btn">全部</button>
<button type="button" class="layui-btn">免费</button>
<button type="button" class="layui-btn">付费</button>
<button type="button" class="layui-btn">已安装</button>
<button type="button" class="layui-btn layui-btn-sm" lay-event="installed">已安装</button>
<button type="button" class="layui-btn layui-btn-sm" lay-event="onlineAddons">在线</button>
<button type="button" class="layui-btn layui-btn-sm" lay-event="freeAddons">免费</button>
<button type="button" class="layui-btn layui-btn-sm" lay-event="payAddons">付费</button>
</div>
<table id="addons-list" lay-filter="addons-list"></table>
<script type="text/html" id="addons-tool">
<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="install"><i class="layui-icon layui-icon-edit"></i>安装</a>
<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="edit"><i class="layui-icon layui-icon-edit"></i>卸载</a>
<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del"><i class="layui-icon layui-icon-delete"></i>删除</a>
</script>
</div>
</div>
<script type="text/html" id="addons-installed-tool">
<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="install"><i class="layui-icon layui-icon-edit"></i>安装</a>
<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="set"><i class="layui-icon layui-icon-edit"></i>设置</a>
<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="del"><i class="layui-icon layui-icon-delete"></i>卸载</a>
</script>
<script type="text/html" id="addons-tool">
<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="install"><i class="layui-icon layui-icon-edit"></i>安装</a>
<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="set"><i class="layui-icon layui-icon-edit"></i>设置</a>
</script>
</div>
{/block}
{block name="js"}
<script>
var filter = "{:url('Addons')}";
//console.log(filter);
var addonsIndex = "{:url('Addons/index')}",
addonsList = "{:url('Addons/addonsList')}",
pluginsList = "{:url('Addons/pluginsList')}",
addonsDelete = "{:url('Addons/delete')}",
addonsEdit = "{:url('Addons/edit')}";
var col = new Array();
col = {:json_encode($col)};
layui.config({
base: '/static/admin/' //静态资源所在路径
}).extend({
@ -56,38 +67,11 @@
,table = layui.table
,form = layui.form
,upload = layui.upload;
//事件
var active = {
batchdel: function(){
var checkStatus = table.checkStatus('addons-list')
,checkData = checkStatus.data; //得到选中的数据
if(checkData.length === 0){
return layer.msg('请选择数据');
}
layer.prompt({
formType: 1
,title: '敏感操作,请验证口令'
}, function(value, index){
layer.close(index);
layer.confirm('确定删除吗?', function(index) {
//执行 Ajax 后重载
/*
admin.req({
url: 'xxx'
//,……
});
*/
table.reload('addons-list');
layer.msg('已删除');
});
});
}
,add: function(){
add: function(){
layer.open({
type: 2
,title: '添加插件'

View File

@ -49,12 +49,12 @@
<div style="padding-bottom: 10px;">
<button class="layui-btn layuiadmin-btn-forum-list" data-type="batchdel">删除</button>
</div>
<table id="LAY-app-forum-list" lay-filter="LAY-app-forum-list"></table>
<table id="LAY-app-forum-list" lay-filter="LAY-app-forum-list" ></table>
<script type="text/html" id="imgTpl">
<img style="display: inline-block; width: 50%; height: 100%;" src= "{{ d.avatar }}">
</script>
<script type="text/html" id="title">
<a href="{$domain}/jie/{{d.id}}.html" target="_blank">{{d.content}}</a>
<a href="{$domain}/jie/{{d.id}}.html" target="_blank">{{d.title}}</a>
</script>
<script type="text/html" id="buttonTpl">
{{# if(d.top == 1){ }}
@ -135,14 +135,29 @@ var forumList = "{:url('Forum/list')}",
}
layer.confirm('确定删除吗?', function(index) {
//获取所选id
var idsArray = [];
for (var i = 0; i < checkData.length; i++) {
idsArray.push(checkData[i].id);
}
var ids = idsArray.toString();
//console.log(ids);
//执行 Ajax 后重载
/*
admin.req({
url: 'xxx'
$.post("{:url('admin/Forum/listdel')}",{"id": ids},function(res){
if(res.code == 0){
layer.msg('删除成功', {
icon: 1
,shade: 0
});
}
}
//,……
});
*/
);
table.reload('LAY-app-forum-list');
layer.msg('已删除');
});

View File

@ -7,6 +7,7 @@ use think\Model;
use think\model\concern\SoftDelete;
use think\facade\Cache;
use think\facade\Config;
use think\facade\Db;
class Article extends Model
{
@ -57,7 +58,8 @@ class Article extends Model
*/
public function add(array $data)
{
$data['status'] = Config::get('taoler.config.posts_check');
$superAdmin = Db::name('user')->where('id',$data['user_id'])->value('auth');
$data['status'] = $superAdmin ? 1 : Config::get('taoler.config.posts_check');
$msg = $data['status'] ? '发布成功' : '发布成功,请等待审核';
$result = $this->save($data);
if($result) {

View File

@ -120,7 +120,8 @@ class Article extends BaseController
if(empty($data['content'])){
return json(['code'=>0, 'msg'=>'评论不能为空!']);
}
$data['status'] = Config::get('taoler.config.commnets_check');
$superAdmin = Db::name('user')->where('id',$sendId)->value('auth');
$data['status'] = $superAdmin ? 1 : Config::get('taoler.config.commnets_check');
$msg = $data['status'] ? '留言成功' : '留言成功,请等待审核';
//用户留言存入数据库

View File

@ -7,7 +7,7 @@ return [
//应用名,此项不可更改
'appname' => 'TaoLer',
//版本配置
'version' => '1.8.8',
'version' => '1.8.4',
//加盐
'salt' => 'taoler',
//数据库备份目录
@ -17,9 +17,9 @@ return [
'email_notice' => 0,
'cate_show' => 0,
'area_show' => 0,
'regist_check' => 1,
'posts_check' => 1,
'commnets_check' => 1,
'regist_check' => 0,
'posts_check' => 0,
'commnets_check' => 0,
]

View File

@ -1,32 +1,57 @@
//网站app版本发布
layui.define(['table', 'form','upload'], function(exports){
var $ = layui.$
var $ = layui.jquery
,table = layui.table
,form = layui.form
,upload = layui.upload;
//版本推送
//安装插件
table.render({
elem: '#addons-list',
url: addonsIndex,
limit: 5,
cols:[[
{type: 'numbers', fixed: 'left'},
{field: 'addons_name',title: '插件', width: 150},
{field: 'addons_version',title: '版本', width: 100},
{field: 'addons_auther',title: '作者', width: 100},
{field: 'addons_resume',title: '简介', minWidth: 200},
{field: 'addons_price',title: '价格(元)'},
{field: 'addons_status',title: '状态', width: 100},
{field: 'ctime',title: '时间', width: 150},
{title: '操作', width: 250, align:'center', fixed: 'right', toolbar: '#addons-tool'}
]]
toolbar: '#toolbar',
url: addonsList,
cols:[
col
]
,page: true
,limit: 10
,height: 'full-220'
,text: '对不起,加载出现异常!'
});
//头工具栏事件
table.on('toolbar(addons-list)', function(obj){
var checkStatus = table.checkStatus(obj.config.id);
switch(obj.event){
case 'installed':
$.post(addonsIndex + '?type=installed',function(){
location.href = addonsIndex + '?type=installed';
});
$.post(addonsList + '?type=installed',{"type":"installed"});
table.reload('addons-list', {
where: {"type":"installed"}
}); //数据刷新
break;
case 'onlineAddons':
$.post(addonsIndex + '?type=onlineAddons',function(){
location.href = addonsIndex + '?type=onlineAddons';
});
$.post(addonsList + '?type=onlineAddons',{"type":"onlineAddons"});
table.reload('addons-list', {
where: {"type":"onlineAddons"}
}); //数据刷新
break;
case 'isAll':
layer.msg(checkStatus.isAll ? '全选': '未全选');
break;
//自定义头工具栏右侧图标 - 提示
case 'LAYTABLE_TIPS':
layer.alert('这是工具栏右侧自定义的一个图标按钮');
break;
};
});
//监听工具条
table.on('tool(addons-list)', function(obj){

View File

@ -22,7 +22,8 @@ layui.define(['table', 'form'], function(exports){
,{field: 'id', width: 60, title: 'ID', sort: true}
,{field: 'poster', title: '贴主',width: 100}
,{field: 'avatar', title: '头像', width: 80, templet: '#imgTpl'}
,{field: 'content', title: '标题', mWidth: 200,templet: '#title'}
,{field: 'title', title: '标题', mWidth: 200,templet: '#title'}
,{field: 'content', title: '内容', mWidth: 200}
,{field: 'posttime', title: '时间',width: 120, sort: true}
,{field: 'top', title: '置顶', templet: '#buttonTpl', width: 80, align: 'center'}
,{field: 'hot', title: '精贴', templet: '#buttonHot', width: 80, align: 'center'}

View File

@ -34,7 +34,8 @@
</div>
{//问题内容}
<div class="detail-body-wenda photos">问题描述:{$article.content|raw}</div>
<div>问题描述:</div>
<div class="detail-body-wenda photos">{$article.content|raw}</div>
{//管理}
{if (($article.upzip !== '') || (session('user_id')==$article.user_id) OR ($user.auth ?? ''))}