1.9.20
This commit is contained in:
parent
f17b24122f
commit
608211d178
33
README.md
33
README.md
@ -1,10 +1,13 @@
|
||||
# TaoLer
|
||||
|
||||
> TaoLer是一个简单迅捷的轻论坛系统,适用于个人或组织区域型信息交流发布平台。
|
||||
> TaoLer是一个简单迅捷的管理系统,支持插件化开发,适用于企业、个人或组织建站需求。
|
||||
|
||||
支持多模板、多单页自由切换,网站风格可定制性强,支持插件化开发,方便二开。可做为企业门户网站,生活服务,学习问答笔记,文章分享等。
|
||||
默认内置一套完整的**问答+博客+论坛+新闻+轻社区化**的模板系统,还可持续增加模块,一个系统拥有多个版式的网站风格。
|
||||
|
||||
* 官网:https://www.aieok.com
|
||||
|
||||
webman版新架构已适配90%
|
||||
* 文档:http://wiki.aieok.com
|
||||
* 演示后台:https://www.aieok.com/adminff
|
||||
|
||||
#### 项目地址
|
||||
|
||||
@ -24,15 +27,14 @@
|
||||
6. 双升级系统,可支持自动和手动升级。可在线检测并升级系统,保持网站的更新和安全。
|
||||
7. 代码开源,不设暗门操作,更安全。
|
||||
8. 项目会长期维护,优化更新。
|
||||
9. 预增加插件管理机制1.0(2.0版本正式上线)
|
||||
9. 预增加插件管理机制1.x(2.x版本正式上线)
|
||||
|
||||
![alt taoler官网](https://www.aieok.com/storage/1/article_pic/20220802/6ea6bb3e40d9a3bc7c9ec28f3e0d7b90.png "TaoLerCMS")
|
||||
|
||||
#### 构架组成
|
||||
- 1.x版本构架:
|
||||
- 构架:Tinkphp6 + layui2.6
|
||||
- 环境:php7/php8.0 + mysql
|
||||
- 前端:Fly template V3.0
|
||||
- 构架:Tinkphp6 + layui2.7
|
||||
- 环境:php7/8.1 + mysql5.7/8.0
|
||||
|
||||
#### 构架介绍
|
||||
thinkphp:
|
||||
@ -43,12 +45,17 @@
|
||||
一款至简的社区模板。
|
||||
|
||||
![alt taoler官网](https://www.aieok.com/storage/1/article_pic/20220802/edd9bfc2ca1d1ec52a551b2233b5ab62.png "TaoLerCMS")
|
||||
|
||||
####重点
|
||||
* 长期维护,对抗消亡
|
||||
* 迭代及时,查漏补缺
|
||||
* 多模板多模块,一站顶多站
|
||||
|
||||
#### 安装教程
|
||||
|
||||
1. 首选确保满目使用环境要求,php > 7.2, mysql > 5.7.3
|
||||
2. git下载:https://gitee.com/toogee/TaoLer
|
||||
github https://www.github.com/taoser/TaoLer
|
||||
2. https://github.com/taoser/TaoLer/archive/refs/heads/master.zip
|
||||
git下载:https://gitee.com/toogee/TaoLer
|
||||
官网下载:https://www.aieok.com
|
||||
|
||||
#### 引导安装
|
||||
@ -92,14 +99,18 @@
|
||||
}
|
||||
```
|
||||
|
||||
>如果是宝塔集成环境,网站目录部署如下示例:
|
||||
> 如果是宝塔集成环境,网站目录部署如下示例:
|
||||
网站目录:D:/www/TaoLer
|
||||
运行目录:/public
|
||||
运行目录:/public
|
||||
|
||||
![alt install](http://wiki.aieok.com/_images/BT.png "install")
|
||||
|
||||
|
||||
3. 首次安装,访问域名http://www.youdomain.com可自动跳转到/install/index进行引导安装,重新安装需删除public目录下install.lock。
|
||||
4. 安装前需要先创建mysql数据库(准备:数据库连接地址,数据库用户名,密码,端口)
|
||||
5. 如果手动导入数据库,管理员用户名和密码,默认admin/123456,前后台的管理员密码一致。前后端管理员账户是独立的,前端主要对文章内容的审查管理等操作。
|
||||
|
||||
|
||||
![alt taoler官网](https://www.aieok.com/storage/1/article_pic/20220802/54c8364fffd9ca1d15856efd90b689bc.png "TaoLerAdmin")
|
||||
|
||||
#### 前后台独立域名的绑定
|
||||
|
@ -12,6 +12,7 @@ use think\facade\Db;
|
||||
use think\facade\Request;
|
||||
use think\facade\Lang;
|
||||
use think\facade\View;
|
||||
use think\facade\Route;
|
||||
|
||||
/**
|
||||
* 控制器基础类
|
||||
@ -244,10 +245,16 @@ abstract class BaseController
|
||||
* @param integer $aid
|
||||
* @return string
|
||||
*/
|
||||
protected function getRouteUrl(int $aid) : string
|
||||
protected function getRouteUrl(int $aid,string $ename = '') : string
|
||||
{
|
||||
$indexUrl = $this->getIndexUrl();
|
||||
$artUrl = (string) url('detail_id', ['id' => $aid]);
|
||||
if(config('taoler.url_rewrite.article_as') == '<ename>/'){
|
||||
// 分类可变路由
|
||||
$artUrl = (string) Route::buildUrl('article_detail', ['id' => $aid, 'ename'=> $ename]);
|
||||
} else {
|
||||
$artUrl = (string) url('article_detail', ['id' => $aid]);
|
||||
}
|
||||
|
||||
|
||||
// 判断是否开启绑定
|
||||
//$domain_bind = array_key_exists('domain_bind',config('app'));
|
||||
|
@ -1,4 +1,13 @@
|
||||
<?php
|
||||
/*
|
||||
* @Author: TaoLer <317927823@qq.com>
|
||||
* @Date: 2021-12-06 16:04:50
|
||||
* @LastEditTime: 2022-07-28 11:44:38
|
||||
* @LastEditors: TaoLer
|
||||
* @Description: 优化版
|
||||
* @FilePath: \github\TaoLer\app\Request.php
|
||||
* Copyright (c) 2020~2022 https://www.aieok.com All rights reserved.
|
||||
*/
|
||||
namespace app;
|
||||
|
||||
// 应用请求对象类
|
||||
@ -8,6 +17,7 @@ class Request extends \think\Request
|
||||
//protected $filter = ['trim','htmlspecialchars','strip_tags'];
|
||||
//protected $filter = ['trim','htmlspecialchars'];
|
||||
//protected $filter = ['trim','strip_tags'];
|
||||
protected $filter = ['trim'];
|
||||
//protected $filter = ['htmlspecialchars'];
|
||||
//protected $filter = ['trim'];
|
||||
|
||||
}
|
||||
|
@ -22,7 +22,6 @@ class Addons extends AdminController
|
||||
//$conf = new \addons\social\model\Conf;
|
||||
//$arr = $conf->getConf();
|
||||
//dump($arr);
|
||||
//dump($arr[0]['value']['app_key']);
|
||||
return View::fetch();
|
||||
}
|
||||
|
||||
@ -159,7 +158,7 @@ class Addons extends AdminController
|
||||
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) {
|
||||
} catch (\think\exception\ValidateException $e) {
|
||||
echo $e->getMessage();
|
||||
}
|
||||
$upload = Config::get('filesystem.disks.public.url');
|
||||
@ -189,6 +188,7 @@ class Addons extends AdminController
|
||||
if(!$verRes){
|
||||
return json(['code'=>-1,'msg'=>'不能降级,请选择正确版本']);
|
||||
}
|
||||
//$tpl_ver_res = version_compare($addInstalledVersion['template_version'], config('taoler.template_version'),'<');
|
||||
}
|
||||
|
||||
$file_url = $addons->addons_src;
|
||||
|
@ -60,7 +60,8 @@ 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,content,a.update_time as update_time,is_top,is_hot,is_reply,a.status as status')
|
||||
->join('cate c','a.cate_id = c.id')
|
||||
->field('a.id as aid,ename,name,user_img,title,content,a.update_time as update_time,is_top,a.is_hot as is_hot,is_reply,a.status as status')
|
||||
->where('a.delete_time',0)
|
||||
->where($map)
|
||||
->where($where)
|
||||
@ -73,7 +74,7 @@ class Forum extends AdminController
|
||||
$res['msg'] = '';
|
||||
$res['count'] = $count;
|
||||
foreach($forumList as $k=>$v){
|
||||
$url = $this->getRouteUrl($v['aid']);
|
||||
$url = $this->getRouteUrl($v['aid'],$v['ename']);
|
||||
$res['data'][]= ['id'=>$v['aid'],'poster'=>$v['name'],'avatar'=>$v['user_img'],'title'=>htmlspecialchars($v['title']),'url'=>$url,'content'=>htmlspecialchars($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 {
|
||||
@ -236,7 +237,8 @@ class Forum extends AdminController
|
||||
->alias('a')
|
||||
->join('user u','a.user_id = u.id')
|
||||
->join('article c','a.article_id = c.id')
|
||||
->field('a.id as aid,name,title,user_img,a.content as content,a.create_time as create_time,a.status as astatus,c.id as cid')
|
||||
->join('cate ca','c.cate_id = ca.id')
|
||||
->field('a.id as aid,name,ename,title,user_img,a.content as content,a.create_time as create_time,a.status as astatus,c.id as cid')
|
||||
->where('a.delete_time',0)
|
||||
->where($map)
|
||||
->where($where)
|
||||
@ -248,7 +250,7 @@ class Forum extends AdminController
|
||||
if ($count) {
|
||||
$res = ['code'=>0,'msg'=>'','count'=>$count];
|
||||
foreach($replys as $k => $v){
|
||||
$url = $this->getRouteUrl($v['cid']);
|
||||
$url = $this->getRouteUrl($v['cid'],$v['ename']);
|
||||
//$res['data'][] = ['id'=>$v['id'],'replyer'=>$v->user->name,'cardid'=>$v->article->title,'avatar'=>$v->user->user_img,'content'=>$v['content'],'replytime'=>$v['create_time']];
|
||||
$res['data'][] = ['id'=>$v['aid'],'replyer'=>$v['name'],'title'=>htmlspecialchars($v['title']),'avatar'=>$v['user_img'],'content'=>htmlspecialchars($v['content']),'replytime'=>date("Y-m-d",$v['create_time']),'check'=>$v['astatus'],'url'=>$url];
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ use app\admin\model\Article;
|
||||
use app\admin\model\Cunsult;
|
||||
use think\facade\Config;
|
||||
use taoler\com\Api;
|
||||
use taoser\SetArr;
|
||||
|
||||
class Index extends AdminController
|
||||
{
|
||||
@ -111,7 +112,7 @@ class Index extends AdminController
|
||||
->alias('a')
|
||||
->join('user u','a.user_id = u.id')
|
||||
->join('cate c','a.cate_id = c.id')
|
||||
->field('a.id as aid,title,name,catename,pv')
|
||||
->field('a.id as aid,title,name,ename,catename,pv')
|
||||
->where('a.delete_time',0)
|
||||
->whereWeek('a.create_time')
|
||||
->order('a.create_time', 'desc')
|
||||
@ -124,7 +125,7 @@ class Index extends AdminController
|
||||
$res['count'] = $count;
|
||||
foreach($forumList as $k=>$v){
|
||||
//$url = (string) str_replace("admin","index",$this->domain.url('article/detail',['id'=>$v['aid']]));
|
||||
$url = $this->getRouteUrl($v['aid']);
|
||||
$url = $this->getRouteUrl($v['aid'],$v['ename']);
|
||||
$res['data'][]= ['id'=>$url,'title'=>htmlspecialchars($v['title']),'name'=>$v['name'],'catename'=>$v['catename'],'pv'=>$v['pv']];
|
||||
}
|
||||
} else {
|
||||
@ -142,7 +143,8 @@ class Index extends AdminController
|
||||
->alias('a')
|
||||
->join('user u','a.user_id = u.id')
|
||||
->join('article c','a.article_id = c.id')
|
||||
->field('a.content as content,title,c.id as cid,name')
|
||||
->join('cate ca','c.cate_id = ca.id')
|
||||
->field('a.content as content,title,c.id as cid,name,ename')
|
||||
->where('c.delete_time',0)
|
||||
->whereWeek('a.create_time')
|
||||
->order('a.create_time', 'desc')
|
||||
@ -153,7 +155,7 @@ class Index extends AdminController
|
||||
if ($count) {
|
||||
$res = ['code'=>0,'msg'=>'','count'=>$count];
|
||||
foreach($replys as $k => $v){
|
||||
$res['data'][] = ['content'=>htmlspecialchars($v['content']),'title'=>htmlspecialchars($v['title']),'cid'=>$this->getRouteUrl($v['cid']),'name'=>$v['name']];
|
||||
$res['data'][] = ['content'=>htmlspecialchars($v['content']),'title'=>htmlspecialchars($v['title']),'cid'=>$this->getRouteUrl($v['cid'],$v['ename']),'name'=>$v['name']];
|
||||
}
|
||||
} else {
|
||||
$res = ['code'=>-1,'msg'=>'本周还没评论'];
|
||||
@ -242,7 +244,40 @@ class Index extends AdminController
|
||||
}
|
||||
}
|
||||
|
||||
// 系统调试
|
||||
public function sysSys()
|
||||
{
|
||||
$status = input('status');
|
||||
|
||||
//打开调试
|
||||
$env = root_path().'.env';
|
||||
$app = config_path().'app.php';
|
||||
|
||||
if(file_exists($env)){
|
||||
$str = file_get_contents($env);
|
||||
$appStr = file_get_contents($app);
|
||||
$patk = '/APP_DEBUG[^\r?\n]*/';
|
||||
$appPatk = '/'.'exception_tmpl'.'[^\r?\n]*/';
|
||||
if($status == 'true'){
|
||||
$reps = 'APP_DEBUG = true';
|
||||
$appArr = "exception_tmpl' => app()->getThinkPath() . 'tpl/think_exception.tpl',";
|
||||
} else {
|
||||
$reps = 'APP_DEBUG = false';
|
||||
$appArr = "exception_tmpl' => app()->getAppPath() . '404.html',";
|
||||
}
|
||||
$str = preg_replace($patk, $reps, $str);
|
||||
file_put_contents($env, $str);
|
||||
|
||||
$appStr = preg_replace($appPatk, $appArr, $appStr);
|
||||
$res = file_put_contents($app, $appStr) ? true : false;
|
||||
if($res == true){
|
||||
return json(['code'=>0,'msg'=>'设置成功']);
|
||||
} else {
|
||||
return json(['code'=>-1,'msg'=>'开启失败']);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function layout(){
|
||||
return view();
|
||||
|
@ -2,11 +2,11 @@
|
||||
/*
|
||||
* @Author: TaoLer <alipey_tao@qq.com>
|
||||
* @Date: 2022-04-13 09:54:31
|
||||
* @LastEditTime: 2022-05-12 16:21:33
|
||||
* @LastEditTime: 2022-07-15 18:28:57
|
||||
* @LastEditors: TaoLer
|
||||
* @Description: 搜索引擎SEO优化设置
|
||||
* @FilePath: \TaoLer\app\admin\controller\Seo.php
|
||||
* Copyright (c) 2020~2022 http://www.aieok.com All rights reserved.
|
||||
* Copyright (c) 2020~2022 https://www.aieok.com All rights reserved.
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
namespace app\admin\controller;
|
||||
@ -20,6 +20,8 @@ use app\admin\model\PushJscode;
|
||||
|
||||
class Seo extends AdminController
|
||||
{
|
||||
// 写ID
|
||||
protected $w_id = 0;
|
||||
|
||||
public function index()
|
||||
{
|
||||
@ -43,25 +45,63 @@ class Seo extends AdminController
|
||||
return View::fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 百度推送
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function push()
|
||||
{
|
||||
$data = Request::only(['start_id','end_id','time']);
|
||||
// 动态路由配置
|
||||
$article_as = config('taoler.url_rewrite.article_as');
|
||||
$api = config('taoler.baidu.push_api');
|
||||
|
||||
if(empty(config('taoler.baidu.push_api'))) return json(['code'=>-1,'msg'=>'请先配置接口push_api']);
|
||||
if(empty($api)) return json(['code'=>-1,'msg'=>'请先配置接口push_api']);
|
||||
$urls = [];
|
||||
if(empty($data['start_id']) || empty($data['end_id'])) {
|
||||
$artAllId = Db::name('article')->where(['delete_time'=>0,'status'=>1])->whereTime('create_time', $data['time'])->column('id');
|
||||
if($article_as == '<ename>/'){ //变量路由
|
||||
$artAllId = Db::name('article')
|
||||
->alias('a')
|
||||
->join('cate c','a.cate_id = c.id')
|
||||
->field('a.id as aid,ename')
|
||||
->where(['a.delete_time'=>0,'a.status'=>1])
|
||||
->whereTime('a.create_time', $data['time'])
|
||||
->select()->toArray();
|
||||
} else { //常量路由
|
||||
$artAllId = Db::name('article')->where(['delete_time'=>0,'status'=>1])->whereTime('create_time', $data['time'])->column('id');
|
||||
}
|
||||
|
||||
} else {
|
||||
$artAllId = Db::name('article')->where(['delete_time'=>0,'status'=>1])->where('id','between',[$data['start_id'],$data['end_id']])->whereTime('create_time', $data['time'])->column('id');
|
||||
if($article_as == '<ename>/') {
|
||||
$artAllId = Db::name('article')
|
||||
->alias('a')
|
||||
->join('cate c','a.cate_id = c.id')
|
||||
->field('a.id as aid,ename')
|
||||
->where(['a.delete_time'=>0,'a.status'=>1])
|
||||
->where('a.id','between',[$data['start_id'],$data['end_id']])
|
||||
->whereTime('a.create_time', $data['time'])
|
||||
->select()->toArray();
|
||||
} else {
|
||||
$artAllId = Db::name('article')->where(['delete_time'=>0,'status'=>1])->where('id','between',[$data['start_id'],$data['end_id']])->whereTime('create_time', $data['time'])->column('id');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(empty($artAllId)) return json(['code'=>-1,'msg'=>'没有查询到结果,无需推送']);
|
||||
// 组装链接数组
|
||||
foreach($artAllId as $aid) {
|
||||
$urls[] = $this->getRouteUrl($aid);
|
||||
if($article_as == '<ename>/') {
|
||||
foreach($artAllId as $art) {
|
||||
$urls[] = $this->getRouteUrl($art['aid'], $art['ename']);
|
||||
}
|
||||
} else {
|
||||
foreach($artAllId as $aid) {
|
||||
$urls[] = $this->getRouteUrl($aid);
|
||||
}
|
||||
}
|
||||
|
||||
// 百度接口单次最大提交200,进行分组
|
||||
$urls = array_chunk($urls,2000);
|
||||
$api = config('taoler.baidu.push_api');
|
||||
$urls = array_chunk($urls,2000);
|
||||
$ch = curl_init();
|
||||
foreach($urls as $url) {
|
||||
$options = array(
|
||||
@ -125,7 +165,7 @@ class Seo extends AdminController
|
||||
$data = Request::only(['map_num','map_time','map_level']);
|
||||
// 写文件字符串
|
||||
$str = '';
|
||||
// 标记第一次调用写ID
|
||||
// 标记每次调用首次调用写ID
|
||||
$flag= true;
|
||||
// 写ID
|
||||
$w_id = '';
|
||||
@ -133,6 +173,8 @@ class Seo extends AdminController
|
||||
$i = 1;
|
||||
// 获取public下所有xml文件
|
||||
$newFile = $this->getXmlFile(public_path());
|
||||
// 路由配置
|
||||
$article_as = config('taoler.url_rewrite.article_as');
|
||||
// 没有xml文件时,不存在重写
|
||||
if(empty($newFile)) {
|
||||
$rewrite = false;
|
||||
@ -143,7 +185,7 @@ class Seo extends AdminController
|
||||
// 是否有需要追加在文件,判断最新文件是否未写满
|
||||
$rewrite = $num < $data['map_num'] ? true : false;
|
||||
}
|
||||
|
||||
|
||||
if($rewrite){
|
||||
// 需要追加的数量
|
||||
$limit = (int) $data['map_num'] - $num;
|
||||
@ -157,37 +199,73 @@ class Seo extends AdminController
|
||||
} else {
|
||||
$limit = (int) $data['map_num'];
|
||||
}
|
||||
|
||||
// 最新ID
|
||||
$maxId = Db::name('article')->where(['delete_time'=>0,'status'=>1])->max('id');
|
||||
|
||||
|
||||
do
|
||||
{
|
||||
$wr_id = $flag ? config('taoler.sitemap.write_id') : $w_id;
|
||||
$artAllId = Db::name('article')
|
||||
$this->wr_id = $flag ? config('taoler.sitemap.write_id') : $this->w_id;
|
||||
|
||||
if($article_as == '<ename>/') {
|
||||
// 分类名
|
||||
$artAllId = Db::name('article')
|
||||
->alias('a')
|
||||
->join('cate c','a.cate_id = c.id')
|
||||
->field('a.id as aid,a.update_time as uptime,ename')
|
||||
->where(['a.delete_time'=>0,'a.status'=>1])
|
||||
->where('a.id', '>', (int) $this->wr_id)
|
||||
->order('a.id','asc')->limit($limit)
|
||||
->select()->toArray();
|
||||
} else {
|
||||
$artAllId = Db::name('article')
|
||||
->where(['delete_time'=>0,'status'=>1])
|
||||
->where('id', '>', (int) $wr_id)
|
||||
->where('id', '>', (int) $this->wr_id)
|
||||
->order('id','asc')->limit($limit)->column('update_time','id');
|
||||
}
|
||||
|
||||
if(empty($artAllId)) {
|
||||
return json(['code'=>-1,'msg'=>'本次无需生成']);
|
||||
} else {
|
||||
// 本次最新文件ID
|
||||
$last_id = array_key_last($artAllId);
|
||||
// 循环拼接文件字符串
|
||||
foreach($artAllId as $aid => $uptime) {
|
||||
// url生成
|
||||
$url = $this->getRouteUrl($aid);
|
||||
$time = date('Y-m-d', $uptime);
|
||||
// 组装字符串
|
||||
$str .= <<<STR
|
||||
<url>
|
||||
<loc>$url</loc>
|
||||
<lastmod>$time</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
<priority>0.5</priority>
|
||||
</url>\n
|
||||
STR;
|
||||
if($article_as == '<ename>/') {
|
||||
// 循环拼接文件字符串
|
||||
foreach($artAllId as $art) {
|
||||
//url生成
|
||||
$url = $this->getRouteUrl($art['aid'], $art['ename']);
|
||||
$time = date('Y-m-d', $art['uptime']);
|
||||
// 组装字符串
|
||||
$str .= <<<STR
|
||||
<url>
|
||||
<loc>$url</loc>
|
||||
<lastmod>$time</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
<priority>0.5</priority>
|
||||
</url>\n
|
||||
STR;
|
||||
}
|
||||
|
||||
$last_arr = end($artAllId);
|
||||
$last_id = $last_arr['aid'];
|
||||
} else {
|
||||
// 循环拼接文件字符串
|
||||
foreach($artAllId as $aid => $uptime) {
|
||||
// url生成
|
||||
$url = $this->getRouteUrl($aid);
|
||||
$time = date('Y-m-d', $uptime);
|
||||
// 组装字符串
|
||||
$str .= <<<STR
|
||||
<url>
|
||||
<loc>$url</loc>
|
||||
<lastmod>$time</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
<priority>0.5</priority>
|
||||
</url>\n
|
||||
STR;
|
||||
}
|
||||
$last_id = array_key_last($artAllId);
|
||||
}
|
||||
|
||||
|
||||
// 写文件
|
||||
if($rewrite){
|
||||
// 写入旧xml文件
|
||||
@ -213,7 +291,7 @@ class Seo extends AdminController
|
||||
// 重置标记内容
|
||||
$str = '';
|
||||
$i++;
|
||||
$w_id = $last_id;
|
||||
$this->w_id = $last_id;
|
||||
$flag = false;
|
||||
}
|
||||
}
|
||||
@ -228,8 +306,7 @@ class Seo extends AdminController
|
||||
if($res == false){
|
||||
return json(['code'=>-1,'msg'=>'写xml配置失败']);
|
||||
}
|
||||
|
||||
return json(['code'=>0,'msg'=>'本次成功生成'.count($artAllId).'条xml']);
|
||||
return json(['code'=>0,'msg'=>'本次成功生成' . count($artAllId) . '条xml']);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -314,6 +391,11 @@ class Seo extends AdminController
|
||||
return json(['code'=>0,'msg'=>'删除成功']);
|
||||
}
|
||||
|
||||
/**
|
||||
* 搜索引擎日志分析
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function searchLog()
|
||||
{
|
||||
$time = input('search_time');
|
||||
|
@ -2,7 +2,7 @@
|
||||
/*
|
||||
* @Author: TaoLer <alipey_tao@qq.com>
|
||||
* @Date: 2021-12-06 16:04:50
|
||||
* @LastEditTime: 2022-05-10 15:00:49
|
||||
* @LastEditTime: 2022-07-24 11:06:14
|
||||
* @LastEditors: TaoLer
|
||||
* @Description: 搜索引擎SEO优化设置
|
||||
* @FilePath: \TaoLer\app\admin\controller\Set.php
|
||||
@ -161,7 +161,7 @@ class Set extends AdminController
|
||||
return json($res);
|
||||
}
|
||||
|
||||
/**配置设置
|
||||
/**基础服务配置
|
||||
* parem $id
|
||||
*/
|
||||
public function config()
|
||||
@ -173,7 +173,6 @@ class Set extends AdminController
|
||||
if(!isset($data['posts_check'])) $data['posts_check'] =1;
|
||||
if(!isset($data['commnets_check'])) $data['commnets_check'] =1;
|
||||
foreach($conf as $c=>$f){
|
||||
|
||||
if(array_key_exists($c,$data)){
|
||||
$conf[$c] = (int) $data[$c];
|
||||
}else{
|
||||
@ -356,18 +355,27 @@ class Set extends AdminController
|
||||
//上传logo
|
||||
public function upload()
|
||||
{
|
||||
$param = Request::param('field');
|
||||
$uploads = new \app\common\lib\Uploads();
|
||||
$upRes = $uploads->put('file','logo',2000,'image','uniqid');
|
||||
$upRes = $uploads->put('file','SYS_logo',2000,'image');
|
||||
$logoJson = $upRes->getData();
|
||||
if($logoJson['status'] == 0){
|
||||
$result = Db::name('system')->where('id', 1)->cache('system')->update(['logo'=>$logoJson['url']]);
|
||||
if($result){
|
||||
$res = ['code'=>0,'msg'=>'上传logo成功'];
|
||||
if($param == 'logo'){
|
||||
$result = Db::name('system')->where('id', 1)->cache('system')->update(['logo'=>$logoJson['url']]);
|
||||
} else {
|
||||
$res = ['code'=>1,'msg'=>'上传错误'];
|
||||
//移动端logo
|
||||
$result = Db::name('system')->where('id', 1)->cache('system')->update(['m_logo'=>$logoJson['url']]);
|
||||
}
|
||||
}
|
||||
return json($res);
|
||||
|
||||
if($result){
|
||||
$res = ['code'=>0,'msg'=>'更新logo成功'];
|
||||
} else {
|
||||
$res = ['code'=>-1,'msg'=>'上传成功,数据无须更新'];
|
||||
}
|
||||
} else {
|
||||
$res = ['code'=>-1, 'msg'=>$logoJson['msg']];
|
||||
}
|
||||
return json($res);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ class Slider extends AdminController
|
||||
$limit = input('limit');
|
||||
$page = input('page');
|
||||
if($type) {
|
||||
$datas = SliderModel::where('slid_type',$type)->where('')->paginate([
|
||||
$datas = SliderModel::where('slid_type',$type)->paginate([
|
||||
'list_rows'=> $limit,
|
||||
'page'=>$page
|
||||
]);
|
||||
@ -126,7 +126,7 @@ class Slider extends AdminController
|
||||
public function uploadImg()
|
||||
{
|
||||
$uploads = new \app\common\lib\Uploads();
|
||||
$upRes = $uploads->put('file','slider',1024,'image');
|
||||
$upRes = $uploads->put('file','SYS_slider',1024,'image');
|
||||
$slires = $upRes->getData();
|
||||
|
||||
if($slires['status'] == 0){
|
||||
@ -135,7 +135,7 @@ class Slider extends AdminController
|
||||
} else {
|
||||
$res = ['code'=>1,'msg'=>'上传错误'];
|
||||
}
|
||||
return json($res);
|
||||
return json($res);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -6,8 +6,8 @@
|
||||
* |————runtime
|
||||
* | |
|
||||
* | |___update.sql(更新脚本) //create table test(id init(11)); create table test2(id init(11));
|
||||
*
|
||||
* | |___rockback.sql(回滚脚本) //drop table test; //drop table test2;
|
||||
* | |___remove.txt // clear清除目录和文件
|
||||
* |
|
||||
* |____php
|
||||
*
|
||||
|
@ -31,7 +31,7 @@ class User extends AdminController
|
||||
if($count){
|
||||
$res = ['code'=>0,'msg'=>'','count'=>$count];
|
||||
foreach($user as $k => $v){
|
||||
$data = ['id'=>$v['id'],'username'=>$v['name'],'avatar'=>$v['user_img'],'phone'=>$v['phone'],'email'=>$v['email'],'sex'=>$v['sex'],'ip'=>$v['last_login_ip'],'city'=>$v['city'],'logintime'=>date("Y-m-d H:i",$v['last_login_time']),'jointime'=>date("Y-m-d",$v['create_time']),'check'=>$v['status'],'auth'=>$v['auth']];
|
||||
$data = ['id'=>$v['id'],'username'=>$v['name'],'nick'=>$v['nickname'],'avatar'=>$v['user_img'],'phone'=>$v['phone'],'email'=>$v['email'],'sex'=>$v['sex'],'ip'=>$v['last_login_ip'],'city'=>$v['city'],'logintime'=>date("Y-m-d H:i",$v['last_login_time']),'jointime'=>date("Y-m-d",$v['create_time']),'check'=>$v['status'],'auth'=>$v['auth']];
|
||||
$res['data'][] = $data;
|
||||
}
|
||||
} else {
|
||||
|
25
app/admin/model/Addons.php
Normal file
25
app/admin/model/Addons.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
/*
|
||||
* @Author: TaoLer <317927823@qq.com>
|
||||
* @Date: 2022-07-02 10:39:43
|
||||
* @LastEditTime: 2022-07-02 10:42:19
|
||||
* @LastEditors: TaoLer
|
||||
* @Description: 优化版
|
||||
* @FilePath: \TaoLer\app\admin\model\Addons.php
|
||||
* Copyright (c) 2020~2022 https://www.aieok.com All rights reserved.
|
||||
*/
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use think\Model;
|
||||
use think\model\concern\SoftDelete;
|
||||
|
||||
class Addons extends Model
|
||||
{
|
||||
//软删除
|
||||
use SoftDelete;
|
||||
protected $deleteTime = 'delete_time';
|
||||
protected $defaultSoftDelete = 0;
|
||||
protected $createTime = 'false';
|
||||
|
||||
}
|
@ -2,7 +2,7 @@
|
||||
/*
|
||||
* @Author: TaoLer <alipay_tao@qq.com>
|
||||
* @Date: 2021-12-06 16:04:50
|
||||
* @LastEditTime: 2022-05-07 18:33:23
|
||||
* @LastEditTime: 2022-06-29 15:29:13
|
||||
* @LastEditors: TaoLer
|
||||
* @Description: admin路由配置
|
||||
* @FilePath: \TaoLer\app\admin\route\route.php
|
||||
@ -14,4 +14,9 @@ use think\facade\Route;
|
||||
$detail_as = config('taoler.url_rewrite.article_as');
|
||||
|
||||
Route::get('captcha/[:config]','\\think\\captcha\\CaptchaController@index');
|
||||
Route::get("$detail_as<id>$", '\app\index\controller\Article@detail')->name('detail_id');
|
||||
Route::get("$detail_as<id>$", '\app\index\controller\Article@detail')
|
||||
->pattern([
|
||||
//'name' => '\w+',
|
||||
'id' => '\d+',
|
||||
])
|
||||
->name('article_detail');
|
||||
|
@ -46,23 +46,23 @@
|
||||
{{# } }}
|
||||
</script>
|
||||
-->
|
||||
<script type="text/html" id="buttonTpl">
|
||||
{{# if(d.id == '1'){ }}
|
||||
<input type="checkbox" name="check" lay-skin="switch" disabled lay-text="通过|禁用" value="1" checked id="{{d.id}}">
|
||||
{{# } else { }}
|
||||
{if condition="checkRuleButton('admin/check')"}<input type="checkbox" name="check" lay-skin="switch" lay-filter="admincheck" lay-text="通过|禁用" {{# if(d.check == 1){ }} checked {{# } }} id="{{d.id}}" >{else}<button class="layui-btn layui-btn-xs layui-btn-radius layui-btn-disabled">无权限</button>{/if}
|
||||
{{# } }}
|
||||
<script type="text/html" id="buttonTpl">
|
||||
{{# if(d.id == '1'){ }}
|
||||
<input type="checkbox" name="check" lay-skin="switch" disabled lay-text="通过|禁用" value="1" checked id="{{d.id}}">
|
||||
{{# } else { }}
|
||||
{if condition="checkRuleButton('admin/check')"}<input type="checkbox" name="check" lay-skin="switch" lay-filter="admincheck" lay-text="通过|禁用" {{# if(d.check == 1){ }} checked {{# } }} id="{{d.id}}" >{else}<button class="layui-btn layui-btn-xs layui-btn-radius layui-btn-disabled">无权限</button>{/if}
|
||||
{{# } }}
|
||||
</script>
|
||||
<script type="text/html" id="table-useradmin-admin">
|
||||
{if condition="checkRuleButton('admin/edit')"}
|
||||
{if condition="checkRuleButton('admin/edit')"}
|
||||
<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="edit"><i class="layui-icon layui-icon-edit"></i>编辑</a>
|
||||
{else /}<a class="layui-btn layui-btn-normal layui-btn-xs layui-btn-disabled"><i class="layui-icon layui-icon-edit"></i>编辑</a>{/if}
|
||||
{else /}<a class="layui-btn layui-btn-normal layui-btn-xs layui-btn-disabled"><i class="layui-icon layui-icon-edit"></i>编辑</a>{/if}
|
||||
{{# if(d.id == '1'){ }}
|
||||
<a class="layui-btn layui-btn-disabled layui-btn-xs"><i class="layui-icon layui-icon-delete"></i>删除</a>
|
||||
{{# } else { }}
|
||||
{if condition="checkRuleButton('admin/delete')"}
|
||||
{if condition="checkRuleButton('admin/delete')"}
|
||||
<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del"><i class="layui-icon layui-icon-delete"></i>删除</a>
|
||||
{else /}<a class="layui-btn layui-btn-danger layui-btn-xs layui-btn-disabled"><i class="layui-icon layui-icon-delete"></i>删除</a>{/if}
|
||||
{else /}<a class="layui-btn layui-btn-danger layui-btn-xs layui-btn-disabled"><i class="layui-icon layui-icon-delete"></i>删除</a>{/if}
|
||||
{{# } }}
|
||||
</script>
|
||||
</div>
|
||||
@ -99,23 +99,7 @@
|
||||
//监听搜索
|
||||
form.on('submit(LAY-user-back-search)', function(data){
|
||||
var field = data.field;
|
||||
$.ajax({
|
||||
type:"post",
|
||||
url:"{:url('admin/index')}",
|
||||
data:{"id":field.id,"username":field.username,"mobile":field.mobile,"email":field.email},
|
||||
daType:"json",
|
||||
success:function (data){
|
||||
if (data.code == 0) {
|
||||
|
||||
} else {
|
||||
layer.open({
|
||||
content:data.msg,
|
||||
icon:5,
|
||||
anim:6
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
$.post("{:url('admin/index')}",field);
|
||||
//执行重载
|
||||
table.reload('LAY-user-back-manage', {
|
||||
where: field
|
||||
@ -125,37 +109,17 @@
|
||||
//监听管理员审核
|
||||
form.on('switch(admincheck)', function(data){
|
||||
var data= data.elem;
|
||||
//console.log(data);
|
||||
|
||||
if(data.checked == true){
|
||||
data.value = 1;
|
||||
}else{
|
||||
data.value = 0;
|
||||
}
|
||||
//执行管理员审核
|
||||
$.ajax({
|
||||
type:'post',
|
||||
url:"{:url('admin/check')}",
|
||||
data:{"id":data.id,"status":data.value,},
|
||||
dataType:'json',
|
||||
success:function(res){
|
||||
|
||||
//执行管理员审核
|
||||
var status = data.checked ? 1 : 0;
|
||||
$.post("{:url('admin/check')}",{"id":data.id,"status":status},function(res){
|
||||
if(res.code == 0){
|
||||
layer.msg(res.msg,{
|
||||
icon:res.icon,
|
||||
time:2000
|
||||
}
|
||||
//,function(){location.reload();}
|
||||
);
|
||||
layer.msg(res.msg,{icon:res.icon,time:2000})
|
||||
} else {
|
||||
layer.open({
|
||||
title:'审核失败',
|
||||
content:res.msg,
|
||||
icon:5,
|
||||
adim:6
|
||||
})
|
||||
layer.open({title:'审核失败',content:res.msg,icon:5,adim:6})
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
@ -206,28 +170,14 @@
|
||||
var field = data.field; //获取提交的字段
|
||||
|
||||
//提交 Ajax 成功后,静态更新表格中的数据
|
||||
$.ajax({
|
||||
type:"post",
|
||||
url:"{:url('admin/add')}",
|
||||
data:{"username":field.username,"password":field.password,"mobile":field.mobile,"email":field.email,"auth_group_id":field.auth_group_id,"status":field.status},
|
||||
daType:"json",
|
||||
success:function (data){
|
||||
if (data.code == 0) {
|
||||
layer.msg(data.msg,{
|
||||
icon:6,
|
||||
time:2000
|
||||
});
|
||||
} else {
|
||||
layer.open({
|
||||
title:'添加失败',
|
||||
content:data.msg,
|
||||
icon:5,
|
||||
anim:6
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$.post("{:url('admin/add')}",field,function(res){
|
||||
if(res.code == 0){
|
||||
layer.msg(res.msg,{icon:res.icon,time:2000})
|
||||
} else {
|
||||
layer.open({title:'添加失败',content:res.msg,icon:5,adim:6})
|
||||
}
|
||||
});
|
||||
|
||||
table.reload('LAY-user-back-manage'); //数据刷新
|
||||
layer.close(index); //关闭弹层
|
||||
});
|
||||
@ -236,7 +186,8 @@
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$('.layui-btn.layuiadmin-btn-admin').on('click', function(){
|
||||
var type = $(this).data('type');
|
||||
active[type] ? active[type].call(this) : '';
|
||||
|
@ -17,14 +17,14 @@
|
||||
<input type="text" name="content" placeholder="请输入" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-inline">
|
||||
<div class="layui-inline">
|
||||
<label class="layui-form-label">状态</label>
|
||||
<div class="layui-input-block">
|
||||
<select name="status" lay-filter="fourm-check">
|
||||
<option value="">全部</option>
|
||||
<option value="0">待审</option>
|
||||
<option value="">全部</option>
|
||||
<option value="0">待审</option>
|
||||
<option value="-1">禁止</option>
|
||||
<option value="1">通过</option>
|
||||
<option value="1">通过</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
@ -41,20 +41,17 @@
|
||||
</div>
|
||||
<table id="LAY-app-forumreply-list" lay-filter="LAY-app-forumreply-list"></table>
|
||||
<script type="text/html" id="imgTpl">
|
||||
<img style="display: inline-block; width: 50%; height: 100%;" src= {{ d.avatar }}>
|
||||
<img style="width: 25px; height: 25px;" src= {{ d.avatar }}>
|
||||
</script>
|
||||
<script type="text/html" id="title">
|
||||
<a href="{{d.url}}.html" target="_blank">{{d.title}}</a>
|
||||
</script>
|
||||
<script type="text/html" id="buttonCheck">
|
||||
{if condition="checkRuleButton('forum/recheck')"}<input type="checkbox" name="check" lay-skin="switch" lay-filter="recheck" lay-text="通过|{{# if(d.check == -1){ }}禁止{{# } }} {{# if(d.check == 0){ }}待审{{# } }}" {{# if(d.check == 1){ }} checked {{# } }} id="{{d.id}}" >
|
||||
{else /}<button class="layui-btn layui-btn-xs layui-btn-radius layui-btn-disabled">无权限</button>{/if}
|
||||
<script type="text/html" id="buttonCheck">
|
||||
{if condition="checkRuleButton('forum/recheck')"}<input type="checkbox" name="check" lay-skin="switch" lay-filter="recheck" lay-text="通过|{{ d.check == 0 ? '待审' : '禁止' }}" {{ d.check == 1 ? 'checked' : '' }} id="{{d.id}}" >
|
||||
{else /}<button class="layui-btn layui-btn-xs layui-btn-radius layui-btn-disabled">无权限</button>{/if}
|
||||
</script>
|
||||
<script type="text/html" id="table-forum-replys">
|
||||
{if condition="checkRuleButton('forum/redel')"}
|
||||
{if condition="checkRuleButton('forum/redel')"}
|
||||
<!--a class="layui-btn layui-btn-disabled 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>
|
||||
{else / }<a class="layui-btn layui-btn-danger layui-btn-xs layui-btn-disabled"><i class="layui-icon layui-icon-delete"></i>删除</a>{/if}
|
||||
{else / }<a class="layui-btn layui-btn-danger layui-btn-xs layui-btn-disabled"><i class="layui-icon layui-icon-delete"></i>删除</a>{/if}
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -5,12 +5,11 @@
|
||||
<div class="layui-row layui-col-space15">
|
||||
<div class="layui-col-md8">
|
||||
<div class="layui-row layui-col-space15">
|
||||
<div class="layui-col-md12">
|
||||
<div class="layui-col-md12">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header"><i class="layui-icon layui-icon-voice"></i><a id="up_version" lay-href="{:url('Upgrade/index')}"></a></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-col-md6">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">快捷方式</div>
|
||||
@ -127,7 +126,6 @@
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">数据概览</div>
|
||||
<div class="layui-card-body">
|
||||
|
||||
<div class="layui-carousel layadmin-carousel layadmin-dataview" data-anim="fade" lay-filter="LAY-index-dataview">
|
||||
<div carousel-item id="LAY-index-dataview">
|
||||
<div><i class="layui-icon layui-icon-loading1 layadmin-loading"></i></div>
|
||||
@ -135,7 +133,6 @@
|
||||
<div></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-card">
|
||||
@ -207,6 +204,14 @@
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">版本信息</div>
|
||||
<div class="layui-card-body layui-text">
|
||||
<div class="layui-form">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">系统调试:</label>
|
||||
<div class="layui-input-inline" style="width: 60px;">
|
||||
<input type="checkbox" name="sys-sys" lay-skin="switch" lay-text="开启|关闭" lay-filter="sys-sys" {if env('APP_DEBUG') == true} checked {/if}>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<table class="layui-table">
|
||||
<colgroup>
|
||||
<col width="100">
|
||||
@ -226,7 +231,7 @@
|
||||
<td>
|
||||
<script type="text/html" template>
|
||||
TaoLer_{:config('taoler.version')}
|
||||
<a href="https://www.aieok.com/bbs/doc/timeline.html" target="_blank" style="padding-left: 15px;">更新日志</a>
|
||||
<a href="https://www.aieok.com/article/doc/timeline.html" target="_blank">更新日志</a>
|
||||
</script>
|
||||
</td>
|
||||
</tr>
|
||||
@ -324,7 +329,7 @@
|
||||
<div class="layui-card-body layui-text layadmin-text">
|
||||
<p>TaoLer,采用Thinkphp6.0最新版本为开发框架,代码简洁,运行高效,更新及时。layui是国内比较流行的前端框架,两者完美结合,您会拥有一个非常让人舒适的网站。</p>
|
||||
<p>专注专一,大简其道!--本系统的特点,力争做到简洁,不臃肿,功能专一。不管是学习还是商用,都可以良好的运行。</p>
|
||||
<p>作者尽最大可能,长期进行项目的维护,做到长期可用。</p>
|
||||
<p>作者尽最大可能,长期进行项目的维护,做到长期可用。</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -368,6 +373,30 @@
|
||||
return layedit.sync(index);
|
||||
}
|
||||
});
|
||||
|
||||
// 系统调试
|
||||
form.on('switch(sys-sys)',function(data){
|
||||
var status = data.elem.checked;
|
||||
console.log(status);
|
||||
$.post("{:url('index/sysSys')}",{status:status},function(res){
|
||||
if (res.code == 0) {
|
||||
layer.msg(res.msg,{
|
||||
icon:6,
|
||||
time:2000
|
||||
}, function(){
|
||||
location.reload();
|
||||
});
|
||||
} else {
|
||||
layer.open({
|
||||
content:res.msg,
|
||||
icon:5,
|
||||
anim:6
|
||||
});
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
});
|
||||
|
||||
form.on('submit(cunsult-add)',function(data){
|
||||
var field = data.field;
|
||||
@ -427,7 +456,7 @@
|
||||
}
|
||||
});
|
||||
//obj.del();
|
||||
table.reload('LAY-index-topreply');
|
||||
table.reload('LAY-index-topreply');
|
||||
layer.close(index);
|
||||
});
|
||||
}
|
||||
@ -438,21 +467,20 @@
|
||||
$.get("{:url('Index/getVersion')}",function(data){
|
||||
$('#up_version').html(data);
|
||||
})
|
||||
|
||||
})();
|
||||
|
||||
|
||||
$('.layui-btn.layuiadmin-btn-oiltank').on('click', function(){
|
||||
var type = $(this).data('type');
|
||||
active[type] ? active[type].call(this) : '';
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
var indexForums = "{:url('Index/forums')}", //帖子
|
||||
indexReplys = "{:url('Index/replys')}"; //回复
|
||||
var indexNews = "{:url('Index/news')}", //动态
|
||||
indexReply = "{:url('Index/reply')}"; //反馈
|
||||
var monthTime = "{$monthTime}",
|
||||
monthUserCount = "{$monthUserCount}";
|
||||
indexReplys = "{:url('Index/replys')}", //回复
|
||||
indexNews = "{:url('Index/news')}", //动态
|
||||
indexReply = "{:url('Index/reply')}", //反馈
|
||||
monthTime = "{$monthTime}",
|
||||
monthUserCount = "{$monthUserCount}";
|
||||
</script>
|
||||
{/block}
|
@ -1,7 +1,7 @@
|
||||
<!--
|
||||
* @Author: TaoLer <alipey_tao@qq.com>
|
||||
* @Date: 2021-12-06 16:04:50
|
||||
* @LastEditTime: 2022-04-21 11:05:47
|
||||
* @LastEditTime: 2022-06-28 10:02:16
|
||||
* @LastEditors: TaoLer
|
||||
* @Description: 搜索引擎SEO优化设置
|
||||
* @FilePath: \TaoLer\app\admin\view\public\base.html
|
||||
@ -19,9 +19,8 @@
|
||||
<link rel="stylesheet" href="/static/admin/style/admin.css" media="all">
|
||||
{block name="css"}{/block}
|
||||
</head>
|
||||
<body {if($Request.url==url('index/index'))}class="layui-layout-body"{/if}>
|
||||
<body {if($Request.url == url('index/index'))}class="layui-layout-body"{/if}>
|
||||
{block name="body"}内容{/block}
|
||||
<script src="/static/layui/jquery.min.js" charset="utf-8"></script>
|
||||
<script src="/static/layui/layui.js"></script>
|
||||
<script type="text/javascript" charset="utf-8">
|
||||
var AdminLogin = "{:url('Login/index')}",
|
||||
|
@ -1,14 +1,13 @@
|
||||
<!--
|
||||
* @Author: TaoLer <alipey_tao@qq.com>
|
||||
* @Date: 2021-12-06 16:04:50
|
||||
* @LastEditTime: 2022-04-21 11:06:13
|
||||
* @LastEditTime: 2022-06-28 10:01:43
|
||||
* @LastEditors: TaoLer
|
||||
* @Description: 搜索引擎SEO优化设置
|
||||
* @Description: 后台页脚结构
|
||||
* @FilePath: \TaoLer\app\admin\view\public\footer.html
|
||||
* Copyright (c) 2020~2022 http://www.aieok.com All rights reserved.
|
||||
-->
|
||||
<div class="layui-footer">
|
||||
<!-- 底部固定区域 -->
|
||||
© <a href="https://www.aieok.com">aieok.com</a> - 联系QQ:317927823
|
||||
|
||||
© <a href="https://www.aieok.com">aieok.com</a> - 联系QQ:317927823
|
||||
</div>
|
@ -1,72 +1,79 @@
|
||||
<!--
|
||||
* @Author: TaoLer <alipay_tao@qq.com>
|
||||
* @Date: 2021-12-06 16:04:50
|
||||
* @LastEditTime: 2022-06-28 10:00:54
|
||||
* @LastEditors: TaoLer
|
||||
* @Description: 后台头部结构
|
||||
* @FilePath: \TaoLer\app\admin\view\public\header.html
|
||||
* Copyright (c) 2020~2022 https://www.aieok.com All rights reserved.
|
||||
-->
|
||||
<div class="layui-header">
|
||||
<!-- 头部区域 -->
|
||||
<ul class="layui-nav layui-layout-left">
|
||||
<li class="layui-nav-item layadmin-flexible" lay-unselect>
|
||||
<a href="javascript:;" layadmin-event="flexible" title="侧边伸缩">
|
||||
<i class="layui-icon layui-icon-shrink-right" id="LAY_app_flexible"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li class="layui-nav-item layui-hide-xs" lay-unselect>
|
||||
<a href="{$domain}" target="_blank" title="前台">
|
||||
<i class="layui-icon layui-icon-website"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li class="layui-nav-item" lay-unselect>
|
||||
<a href="javascript:;" layadmin-event="refresh" title="刷新">
|
||||
<i class="layui-icon layui-icon-refresh-3"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li class="layui-nav-item layui-hide-xs" lay-unselect>
|
||||
<input type="text" placeholder="搜索..." autocomplete="off" class="layui-input layui-input-search" layadmin-event="serach" lay-action="template/search.html?keywords=">
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="layui-nav layui-layout-right" lay-filter="layadmin-layout-right">
|
||||
|
||||
<li class="layui-nav-item" lay-unselect>
|
||||
<a lay-href="app/message/index.html" layadmin-event="message" lay-text="消息中心">
|
||||
<i class="layui-icon layui-icon-notice"></i>
|
||||
|
||||
<!-- 如果有新消息,则显示小圆点 -->
|
||||
<span class="layui-badge-dot"></span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="layui-nav-item layui-hide-xs" lay-unselect>
|
||||
<a href="javascript:;" layadmin-event="theme">
|
||||
<i class="layui-icon layui-icon-theme"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li class="layui-nav-item layui-hide-xs" lay-unselect>
|
||||
<a href="javascript:;" layadmin-event="note">
|
||||
<i class="layui-icon layui-icon-note"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li class="layui-nav-item layui-hide-xs" lay-unselect>
|
||||
<a href="javascript:;" layadmin-event="fullscreen">
|
||||
<i class="layui-icon layui-icon-screen-full"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li class="layui-nav-item layui-hide-xs" lay-unselect>
|
||||
<a href="javascript:;" layadmin-event="clearcache">
|
||||
<i class="layui-icon layui-icon-fonts-clear"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li class="layui-nav-item" lay-unselect>
|
||||
<a href="javascript:;">
|
||||
<cite>{:session('admin_name')}</cite>
|
||||
</a>
|
||||
<dl class="layui-nav-child">
|
||||
<dd><a lay-href="{:url('Admin/info')}">基本资料</a></dd>
|
||||
<dd><a lay-href="{:url('Admin/repass')}">修改密码</a></dd>
|
||||
<hr>
|
||||
<dd layadmin-event="logout" style="text-align: center;"><a>退出</a></dd>
|
||||
</dl>
|
||||
</li>
|
||||
|
||||
<li class="layui-nav-item layui-hide-xs" lay-unselect>
|
||||
<a href="javascript:;" layadmin-event=""><i class="layui-icon layui-icon-more-vertical"></i></a>
|
||||
</li>
|
||||
<li class="layui-nav-item layui-show-xs-inline-block layui-hide-sm" lay-unselect>
|
||||
<a href="javascript:;" layadmin-event=""><i class="layui-icon layui-icon-more-vertical"></i></a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<!-- 头部区域 -->
|
||||
<ul class="layui-nav layui-layout-left">
|
||||
<li class="layui-nav-item layadmin-flexible" lay-unselect>
|
||||
<a href="javascript:;" layadmin-event="flexible" title="侧边伸缩">
|
||||
<i class="layui-icon layui-icon-shrink-right" id="LAY_app_flexible"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li class="layui-nav-item layui-hide-xs" lay-unselect>
|
||||
<a href="{$domain}" target="_blank" title="前台">
|
||||
<i class="layui-icon layui-icon-website"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li class="layui-nav-item" lay-unselect>
|
||||
<a href="javascript:;" layadmin-event="refresh" title="刷新">
|
||||
<i class="layui-icon layui-icon-refresh-3"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li class="layui-nav-item layui-hide-xs" lay-unselect>
|
||||
<input type="text" placeholder="搜索..." autocomplete="off" class="layui-input layui-input-search" layadmin-event="serach" lay-action="template/search.html?keywords=">
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="layui-nav layui-layout-right" lay-filter="layadmin-layout-right">
|
||||
<li class="layui-nav-item" lay-unselect>
|
||||
<a lay-href="app/message/index.html" layadmin-event="message" lay-text="消息中心">
|
||||
<i class="layui-icon layui-icon-notice"></i>
|
||||
|
||||
<!-- 如果有新消息,则显示小圆点 -->
|
||||
<span class="layui-badge-dot"></span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="layui-nav-item layui-hide-xs" lay-unselect>
|
||||
<a href="javascript:;" layadmin-event="theme">
|
||||
<i class="layui-icon layui-icon-theme"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li class="layui-nav-item layui-hide-xs" lay-unselect>
|
||||
<a href="javascript:;" layadmin-event="note">
|
||||
<i class="layui-icon layui-icon-note"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li class="layui-nav-item layui-hide-xs" lay-unselect>
|
||||
<a href="javascript:;" layadmin-event="fullscreen">
|
||||
<i class="layui-icon layui-icon-screen-full"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li class="layui-nav-item layui-hide-xs" lay-unselect>
|
||||
<a href="javascript:;" layadmin-event="clearcache">
|
||||
<i class="layui-icon layui-icon-fonts-clear"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li class="layui-nav-item" lay-unselect>
|
||||
<a href="javascript:;">
|
||||
<cite>{:session('admin_name')}</cite>
|
||||
</a>
|
||||
<dl class="layui-nav-child">
|
||||
<dd><a lay-href="{:url('Admin/info')}">基本资料</a></dd>
|
||||
<dd><a lay-href="{:url('Admin/repass')}">修改密码</a></dd>
|
||||
<hr>
|
||||
<dd layadmin-event="logout" style="text-align: center;"><a>退出</a></dd>
|
||||
</dl>
|
||||
</li>
|
||||
<li class="layui-nav-item layui-hide-xs" lay-unselect>
|
||||
<a href="javascript:;" layadmin-event=""><i class="layui-icon layui-icon-more-vertical"></i></a>
|
||||
</li>
|
||||
<li class="layui-nav-item layui-show-xs-inline-block layui-hide-sm" lay-unselect>
|
||||
<a href="javascript:;" layadmin-event=""><i class="layui-icon layui-icon-more-vertical"></i></a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
@ -1,80 +1,89 @@
|
||||
<!--
|
||||
* @Author: TaoLer <alipay_tao@qq.com>
|
||||
* @Date: 2021-12-06 16:04:50
|
||||
* @LastEditTime: 2022-06-28 10:01:33
|
||||
* @LastEditors: TaoLer
|
||||
* @Description: 后台菜单结构
|
||||
* @FilePath: \TaoLer\app\admin\view\public\side_menu.html
|
||||
* Copyright (c) 2020~2022 https://www.aieok.com All rights reserved.
|
||||
-->
|
||||
|
||||
<!-- 侧边菜单 -->
|
||||
<div class="layui-side layui-side-menu">
|
||||
<div class="layui-side-scroll">
|
||||
<div class="layui-logo" lay-href="home/console.html">
|
||||
<span>TaoLer_Admin</span>
|
||||
</div>
|
||||
|
||||
<ul class="layui-nav layui-nav-tree" lay-shrink="all" id="LAY-system-side-menu" lay-filter="layadmin-system-side-menu">
|
||||
<li data-name="home" class="layui-nav-item layui-nav-itemed">
|
||||
<a href="javascript:;" lay-tips="主页" lay-direction="2">
|
||||
<i class="layui-icon layui-icon-home"></i>
|
||||
<cite>主页</cite>
|
||||
</a>
|
||||
<dl class="layui-nav-child">
|
||||
<dd data-name="console" class="layui-this">
|
||||
<a lay-href="{:url('index/home')}">控制台</a>
|
||||
</dd>
|
||||
</dl>
|
||||
</li>
|
||||
|
||||
<!--li data-name="user" class="layui-nav-item">
|
||||
<a href="javascript:;" lay-tips="用户" lay-direction="2">
|
||||
<i class="layui-icon layui-icon-user"></i>
|
||||
<cite>管理</cite>
|
||||
</a>
|
||||
<dl class="layui-nav-child">
|
||||
<dd>
|
||||
<a lay-href="{:url('User/list')}">网站用户1</a>
|
||||
</dd>
|
||||
<dd>
|
||||
<a lay-href="{:url('adminList')}">后台管理员</a>
|
||||
</dd>
|
||||
<dd>
|
||||
<a lay-href="{:url('authgroup/role')}">角色管理</a>
|
||||
</dd>
|
||||
<dd>
|
||||
<a lay-href="{:url('authrule/index')}">权限管理</a>
|
||||
</dd>
|
||||
</dl>
|
||||
</li-->
|
||||
|
||||
{volist name="menu" id="vo1"}
|
||||
{if condition="isset($vo1['children'])"}
|
||||
<li data-name="set" class="layui-nav-item">
|
||||
<a href="javascript:;" lay-tips="{$vo1.title}" lay-direction="2">
|
||||
<i class="layui-icon {$vo1.icon}"></i>
|
||||
<cite>{$vo1.title}</cite>
|
||||
</a>
|
||||
|
||||
<dl class="layui-nav-child">
|
||||
{volist name="vo1['children']" id="vo2"}
|
||||
{if condition="isset($vo2['children'])"}
|
||||
<dd class="layui-nav-itemed">
|
||||
<a href="javascript:;">{$vo2.title}</a>
|
||||
<dl class="layui-nav-child">
|
||||
{volist name="vo2['children']" id="vo3"}
|
||||
<dd><a lay-href="{:url($vo3.name)}">{$vo3.title}</a></dd>
|
||||
{/volist}
|
||||
</dl>
|
||||
</dd>
|
||||
{else /}
|
||||
<dd><a lay-href="{:url($vo2.name)}">{$vo2.title}</a></dd>
|
||||
{/if}
|
||||
{/volist}
|
||||
</dl>
|
||||
</li>
|
||||
{else /}
|
||||
<li data-name="get" class="layui-nav-item">
|
||||
<a href="javascript:;" lay-href="{:url($vo1.name)}" lay-tips="{$vo1.title}" lay-direction="2">
|
||||
<i class="layui-icon {$vo1.icon}"></i>
|
||||
<cite>{$vo1.title}</cite>
|
||||
</a>
|
||||
</li>
|
||||
{/if}
|
||||
{/volist}
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-side layui-side-menu">
|
||||
<div class="layui-side-scroll">
|
||||
<div class="layui-logo" lay-href="home/console.html">
|
||||
<span>TaoLer_Admin</span>
|
||||
</div>
|
||||
|
||||
<ul class="layui-nav layui-nav-tree" lay-shrink="all" id="LAY-system-side-menu" lay-filter="layadmin-system-side-menu">
|
||||
<li data-name="home" class="layui-nav-item layui-nav-itemed">
|
||||
<a href="javascript:;" lay-tips="主页" lay-direction="2">
|
||||
<i class="layui-icon layui-icon-home"></i>
|
||||
<cite>主页</cite>
|
||||
</a>
|
||||
<dl class="layui-nav-child">
|
||||
<dd data-name="console" class="layui-this">
|
||||
<a lay-href="{:url('index/home')}">控制台</a>
|
||||
</dd>
|
||||
</dl>
|
||||
</li>
|
||||
|
||||
<!--li data-name="user" class="layui-nav-item">
|
||||
<a href="javascript:;" lay-tips="用户" lay-direction="2">
|
||||
<i class="layui-icon layui-icon-user"></i>
|
||||
<cite>管理</cite>
|
||||
</a>
|
||||
<dl class="layui-nav-child">
|
||||
<dd>
|
||||
<a lay-href="{:url('User/list')}">网站用户1</a>
|
||||
</dd>
|
||||
<dd>
|
||||
<a lay-href="{:url('adminList')}">后台管理员</a>
|
||||
</dd>
|
||||
<dd>
|
||||
<a lay-href="{:url('authgroup/role')}">角色管理</a>
|
||||
</dd>
|
||||
<dd>
|
||||
<a lay-href="{:url('authrule/index')}">权限管理</a>
|
||||
</dd>
|
||||
</dl>
|
||||
</li-->
|
||||
|
||||
{volist name="menu" id="vo1"}
|
||||
{if condition="isset($vo1['children'])"}
|
||||
<li data-name="set" class="layui-nav-item">
|
||||
<a href="javascript:;" lay-tips="{$vo1.title}" lay-direction="2">
|
||||
<i class="layui-icon {$vo1.icon}"></i>
|
||||
<cite>{$vo1.title}</cite>
|
||||
</a>
|
||||
|
||||
<dl class="layui-nav-child">
|
||||
{volist name="vo1['children']" id="vo2"}
|
||||
{if condition="isset($vo2['children'])"}
|
||||
<dd class="layui-nav-itemed">
|
||||
<a href="javascript:;">{$vo2.title}</a>
|
||||
<dl class="layui-nav-child">
|
||||
{volist name="vo2['children']" id="vo3"}
|
||||
<dd><a lay-href="{:url($vo3.name)}">{$vo3.title}</a></dd>
|
||||
{/volist}
|
||||
</dl>
|
||||
</dd>
|
||||
{else /}
|
||||
<dd><a lay-href="{:url($vo2.name)}">{$vo2.title}</a></dd>
|
||||
{/if}
|
||||
{/volist}
|
||||
</dl>
|
||||
</li>
|
||||
{else /}
|
||||
<li data-name="get" class="layui-nav-item">
|
||||
<a href="javascript:;" lay-href="{:url($vo1.name)}" lay-tips="{$vo1.title}" lay-direction="2">
|
||||
<i class="layui-icon {$vo1.icon}"></i>
|
||||
<cite>{$vo1.title}</cite>
|
||||
</a>
|
||||
</li>
|
||||
{/if}
|
||||
{/volist}
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
@ -43,13 +43,23 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">LOGO</label>
|
||||
<label class="layui-form-label">Logo</label>
|
||||
<div class="layui-input-block">
|
||||
<span><img src="{$sysInfo.logo}" hight="40" width="50" ></span>
|
||||
{if condition="checkRuleButton('set/upload')"}
|
||||
<button type="button" class="layui-btn layui-btn-normal" id="logo-img">选择文件</button>
|
||||
<button type="button" class="layui-btn" id="logo-upload-button">开始上传</button>
|
||||
{else /}<button type="button" class="layui-btn layui-btn-normal layui-btn-disabled">选择文件</button>{/if}
|
||||
<button type="button" class="layui-btn layui-btn-sm" id="logo-img">选择文件</button>
|
||||
<button type="button" class="layui-btn layui-btn-sm" id="logo-upload-button">开始上传</button>
|
||||
{else /}<button type="button" class="layui-btn layui-btn-sm layui-btn-disabled">选择文件</button>{/if}
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">M-logo</label>
|
||||
<div class="layui-input-block">
|
||||
<span><img src="{$sysInfo.m_logo}" hight="40" width="50" ></span>
|
||||
{if condition="checkRuleButton('set/upload')"}
|
||||
<button type="button" class="layui-btn layui-btn-sm" id="m-logo-img">选择文件</button>
|
||||
<button type="button" class="layui-btn layui-btn-sm" id="m-logo-upload-button">开始上传</button>
|
||||
{else /}<button type="button" class="layui-btn layui-btn-sm layui-btn-disabled">选择文件</button>{/if}
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
@ -202,6 +212,103 @@
|
||||
</div>
|
||||
<div class="layui-tab-item">
|
||||
<div class="layui-form" wid100 lay-filter="config">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">注册开关:</label>
|
||||
<div class="layui-input-inline" style="width: 30px;">
|
||||
<input type="checkbox" name="is_regist" lay-skin="primary" value=1 {if config('taoler.config.is_regist') == 1} checked {/if}>
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">勾选可注册</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">登录开关:</label>
|
||||
<div class="layui-input-inline" style="width: 30px;">
|
||||
<input type="checkbox" name="is_login" lay-skin="primary" value=1 {if config('taoler.config.is_login') == 1} checked {/if}>
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">勾选可登录</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">发帖开关:</label>
|
||||
<div class="layui-input-inline" style="width: 30px;">
|
||||
<input type="checkbox" name="is_post" lay-skin="primary" value=1 {if config('taoler.config.is_post') == 1} checked {/if}>
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">勾选可发贴</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">评论开关:</label>
|
||||
<div class="layui-input-inline" style="width: 30px;">
|
||||
<input type="checkbox" name="is_reply" lay-skin="primary" value=1 {if config('taoler.config.is_reply') == 1} checked {/if}>
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">勾选可评论</div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">注册审核:</label>
|
||||
<div class="layui-input-inline" style="width: 30px;">
|
||||
<input type="checkbox" name="regist_check" lay-skin="primary" value=0 {if config('taoler.config.regist_check') == 0} checked {/if}>
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">勾选需审核</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">发帖审核:</label>
|
||||
<div class="layui-input-inline" style="width: 30px;">
|
||||
<input type="checkbox" name="posts_check" lay-skin="primary" value=0 {if config('taoler.config.posts_check') == 0} checked {/if}>
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">勾选需审核</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">评论审核:</label>
|
||||
<div class="layui-input-inline" style="width: 30px;">
|
||||
<input type="checkbox" name="commnets_check" lay-skin="primary" value=0 {if config('taoler.config.commnets_check') == 0} checked {/if}>
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">勾选需审核</div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">注册验证:</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="radio" name="regist_type" value=1 title="验证码" {if config('taoler.config.regist_type') == 1} checked {/if}>
|
||||
<input type="radio" name="regist_type" value=2 title="邮箱验证" {if config('taoler.config.regist_type') == 2} checked {/if}>
|
||||
<input type="radio" name="regist_type" value=3 title="手机短信" {if config('taoler.config.regist_type') == 3} checked {/if}>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">登录验证码:</label>
|
||||
<div class="layui-input-inline" style="width: 30px;">
|
||||
<input type="checkbox" name="login_captcha" lay-skin="primary" value=1 {if config('taoler.config.login_captcha') == 1} checked {/if}>
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">勾选需验证</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">发帖验证码:</label>
|
||||
<div class="layui-input-inline" style="width: 30px;">
|
||||
<input type="checkbox" name="post_captcha" lay-skin="primary" value=1 {if config('taoler.config.post_captcha') == 1} checked {/if}>
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">勾选需验证</div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">分类显示:</label>
|
||||
<div class="layui-input-inline" style="width: 30px;">
|
||||
<input type="checkbox" name="cate_show" lay-skin="primary" value=1 {if config('taoler.config.cate_show') == 1} checked {/if}>
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">勾选显示文章所属类别</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">区域简称:</label>
|
||||
<div class="layui-input-inline" style="width: 30px;">
|
||||
<input type="checkbox" name="area_show" lay-skin="primary" value=1 {if config('taoler.config.area_show') == 1} checked {/if}>
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">勾选显示归属地简称</div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">百度词条:</label>
|
||||
<div class="layui-input-inline" style="width: 60px;">
|
||||
<input type="checkbox" name="baidu_title_switch" lay-skin="switch" lay-text="开启|关闭" value=1 {if config('taoler.config.baidu_title_switch') == 1} checked {/if}>
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">发文章标题引用百度词条</div>
|
||||
</div>
|
||||
<hr>
|
||||
{if($mailserver.active == 1)}
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">邮件通知:</label>
|
||||
@ -212,61 +319,10 @@
|
||||
</div>
|
||||
{/if}
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">注册审核:</label>
|
||||
<div class="layui-input-inline" style="width: 30px;">
|
||||
<input type="checkbox" name="regist_check" lay-skin="primary" value=0 {if config('taoler.config.regist_check') == 0} checked {/if}>
|
||||
<div class="layui-input-block">
|
||||
<button class="layui-btn" lay-submit lay-filter="set_system_config">确认保存</button>
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">注册是否需要审核</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">发帖审核:</label>
|
||||
<div class="layui-input-inline" style="width: 30px;">
|
||||
<input type="checkbox" name="posts_check" lay-skin="primary" value=0 {if config('taoler.config.posts_check') == 0} checked {/if}>
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">发帖是否需要审核</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">评论审核:</label>
|
||||
<div class="layui-input-inline" style="width: 30px;">
|
||||
<input type="checkbox" name="commnets_check" lay-skin="primary" value=0 {if config('taoler.config.commnets_check') == 0} checked {/if}>
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">评论是否需要审核</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">分类显示:</label>
|
||||
<div class="layui-input-inline" style="width: 30px;">
|
||||
<input type="checkbox" name="cate_show" lay-skin="primary" value=1 {if config('taoler.config.cate_show') == 1} checked {/if}>
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">是否显示列表及详情所属分类</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">区域简称:</label>
|
||||
<div class="layui-input-inline" style="width: 30px;">
|
||||
<input type="checkbox" name="area_show" lay-skin="primary" value=1 {if config('taoler.config.area_show') == 1} checked {/if}>
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">是否显示发件人所在地区简称</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">登录验证码:</label>
|
||||
<div class="layui-input-inline" style="width: 30px;">
|
||||
<input type="checkbox" name="login_captcha" lay-skin="primary" value=1 {if config('taoler.config.login_captcha') == 1} checked {/if}>
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">勾选则验证</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">发帖验证码:</label>
|
||||
<div class="layui-input-inline" style="width: 30px;">
|
||||
<input type="checkbox" name="post_captcha" lay-skin="primary" value=1 {if config('taoler.config.post_captcha') == 1} checked {/if}>
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">勾选则验证</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-input-block">
|
||||
<button class="layui-btn" lay-submit lay-filter="set_system_config">确认保存</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -380,7 +436,7 @@
|
||||
upload.render({
|
||||
elem: '#logo-img'
|
||||
,url: "{:url('set/upload')}"
|
||||
,data: {type:'image'}
|
||||
,data: {type:'image',field:'logo'}
|
||||
,auto: false
|
||||
,exts: 'jpg|png|gif|bmp|jpeg'
|
||||
,size: 1000
|
||||
@ -397,6 +453,27 @@
|
||||
}
|
||||
});
|
||||
|
||||
//移动端logo
|
||||
upload.render({
|
||||
elem: '#m-logo-img'
|
||||
,url: "{:url('set/upload')}"
|
||||
,data: {type:'image',field:'mlogo'}
|
||||
,auto: false
|
||||
,exts: 'jpg|png|gif|bmp|jpeg'
|
||||
,size: 1000
|
||||
//,multiple: true
|
||||
,bindAction: '#m-logo-upload-button'
|
||||
,done: function(res){
|
||||
if(res.code == 0){
|
||||
layer.msg(res.msg,{icon:6,tiye:2000},function(){
|
||||
location.reload();
|
||||
});
|
||||
} else {
|
||||
layer.open({title:"上传失败",content:res.msg,icon:5,anim:6});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
//网站配置
|
||||
form.on('submit(set_system_config)', function(data){
|
||||
var field = data.field;
|
||||
|
@ -20,6 +20,8 @@
|
||||
<option value="9">9友情链接</option>
|
||||
<option value="10">10头部菜单</option>
|
||||
<option value="11">11页脚链接</option>
|
||||
<option value="12">12移动首页幻灯-360x172</option>
|
||||
<option value="13">13首页右栏广告</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
@ -75,21 +77,21 @@
|
||||
base: '/static/admin/' //静态资源所在路径
|
||||
}).extend({
|
||||
index: 'lib/index' //主入口模块
|
||||
}).use(['index', 'form', 'upload','laydate','colorpicker', 'imgcom'], function(){
|
||||
}).use(['index','imgcom'], function(){
|
||||
var $ = layui.$
|
||||
,form = layui.form
|
||||
,laydate = layui.laydate
|
||||
,laydate = layui.laydate
|
||||
,upload = layui.upload
|
||||
,imgcom = layui.imgcom;
|
||||
var colorpicker = layui.colorpicker;
|
||||
,imgcom = layui.imgcom;
|
||||
var colorpicker = layui.colorpicker;
|
||||
|
||||
//颜色表单赋值
|
||||
colorpicker.render({
|
||||
elem: '#coloer-form'
|
||||
,color: '#1c97f5'
|
||||
,done: function(color){
|
||||
$('#color-select').val(color);
|
||||
}
|
||||
elem: '#coloer-form'
|
||||
,color: '#1c97f5'
|
||||
,done: function(color){
|
||||
$('#color-select').val(color);
|
||||
}
|
||||
});
|
||||
|
||||
//开始时间
|
||||
@ -98,13 +100,13 @@
|
||||
,btns: ['clear', 'now']
|
||||
,trigger: 'click'
|
||||
});
|
||||
|
||||
//结束时间
|
||||
//结束时间
|
||||
laydate.render({
|
||||
elem: '#over-time'
|
||||
,btns: ['clear', 'now']
|
||||
,trigger: 'click'
|
||||
});
|
||||
|
||||
//上传图片
|
||||
upload.render({
|
||||
elem: '#layuiadmin-upload-slid-img'
|
||||
@ -112,26 +114,17 @@
|
||||
,data:{type:'image'}
|
||||
,accept: 'images'
|
||||
,acceptMime: 'image/*'
|
||||
,auto: false
|
||||
,choose: function (obj) { //选择文件后的回调
|
||||
imgcom.uploads(obj);
|
||||
}
|
||||
,auto: false
|
||||
,choose: function (obj) { //选择文件后的回调
|
||||
imgcom.uploads(obj);
|
||||
}
|
||||
,done: function(res){
|
||||
//console.log(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
|
||||
});
|
||||
}
|
||||
$(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});
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
|
@ -18,6 +18,8 @@
|
||||
<option {if condition="$slider.slid_type eq 9"} selected {/if} value="9">9友情链接</option>
|
||||
<option {if condition="$slider.slid_type eq 10"} selected {/if} value="10">10头部菜单</option>
|
||||
<option {if condition="$slider.slid_type eq 11"} selected {/if} value="11">11页脚链接</option>
|
||||
<option {if condition="$slider.slid_type eq 12"} selected {/if} value="12">12移动首页幻灯</option>
|
||||
<option {if condition="$slider.slid_type eq 13"} selected {/if} value="13">13移动首页幻灯</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -25,6 +25,8 @@
|
||||
<option value="9">9友情链接</option>
|
||||
<option value="10">10头部菜单</option>
|
||||
<option value="11">11页脚链接</option>
|
||||
<option value="12">12移动首页幻灯</option>
|
||||
<option value="13">13首页右栏广告</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
@ -67,13 +69,13 @@
|
||||
,cols: [[ //表头
|
||||
{field: 'id', title: 'ID', width:80, sort: true, fixed: 'left'}
|
||||
,{field: 'slid_type', title: '位置', width:120}
|
||||
,{field: 'slid_img', title: '图片/icon', width:150, templet: '#imgTpl'}
|
||||
,{field: 'slid_img', title: '图片/icon', width:120, templet: '#imgTpl'}
|
||||
,{field: 'slid_name', title: '名称', width:180}
|
||||
,{field: 'slid_href', title: 'URL', minWidth: 250}
|
||||
,{field: 'slid_color', title: '颜色', width: 80}
|
||||
,{field: 'slid_start', title: '开始', width: 150, sort: true}
|
||||
,{field: 'slid_over', title: '结束', width: 150, sort: true}
|
||||
,{field: 'slid_status', title: '状态', width: 135}
|
||||
,{field: 'slid_status', title: '状态', width: 80}
|
||||
,{fixed: 'right', title:'操作', toolbar: '#barDemo', width:150}
|
||||
]]
|
||||
,limit: 15
|
||||
|
@ -61,36 +61,32 @@
|
||||
|
||||
<table id="LAY-user-manage" lay-filter="LAY-user-manage"></table>
|
||||
<script type="text/html" id="imgTpl">
|
||||
<img style="display: inline-block; width: 50%; height: 100%;" src= {{ d.avatar }}>
|
||||
<img style="width: 25px; height: 25px;" src= {{ d.avatar }}>
|
||||
</script>
|
||||
<script type="text/html" id="sex">
|
||||
{{# if(d.sex == 0){ }}
|
||||
<button class="layui-btn layui-btn-normal layui-btn-xs" >男</button>
|
||||
{{# } else { }}
|
||||
<button class="layui-btn layui-btn-danger layui-btn-xs">女</button>
|
||||
{{# } }}
|
||||
<span class="layui-btn {{ d.sex == 0 ? 'layui-btn-normal' : 'layui-btn-danger' }} layui-btn-xs" >{{ d.sex == 0 ? '男' : '女' }}</span>
|
||||
</script>
|
||||
<script type="text/html" id="buttonCheck">
|
||||
{{# if(d.id == '1'){ }}
|
||||
<input type="checkbox" name="check" lay-skin="switch" disabled lay-text="通过|禁用" value="1" checked id="{{d.id}}">
|
||||
{{# } else { }}
|
||||
{if condition="checkRuleButton('user/check')"}<input type="checkbox" name="check" lay-skin="switch" lay-filter="usercheck" lay-text="通过|{{# if(d.check == -1){ }}禁止{{# } }} {{# if(d.check == 0){ }}待审{{# } }}" {{# if(d.check == 1){ }} checked {{# } }} id="{{d.id}}" >{else}<button class="layui-btn layui-btn-xs layui-btn-radius layui-btn-disabled">无权限</button>{/if}
|
||||
{{# } }}
|
||||
<script type="text/html" id="buttonCheck">
|
||||
{{# if(d.id == '1'){ }}
|
||||
<input type="checkbox" name="check" lay-skin="switch" disabled lay-text="通过|禁用" value="1" checked id="{{d.id}}">
|
||||
{{# } else { }}
|
||||
{if condition="checkRuleButton('user/check')"}<input type="checkbox" name="check" lay-skin="switch" lay-filter="usercheck" lay-text="通过|{{# if(d.check == -1){ }}禁止{{# } }} {{# if(d.check == 0){ }}待审{{# } }}" {{# if(d.check == 1){ }} checked {{# } }} id="{{d.id}}" >{else}<button class="layui-btn layui-btn-xs layui-btn-radius layui-btn-disabled">无权限</button>{/if}
|
||||
{{# } }}
|
||||
</script>
|
||||
<script type="text/html" id="buttonAuth">
|
||||
{{# if(d.id == '1'){ }}
|
||||
<input type="checkbox" name="auth" lay-skin="primary" checked disabled >
|
||||
{{# } else { }}
|
||||
{if condition="checkRuleButton('user/auth')"}<input type="checkbox" name="auth" lay-skin="primary" lay-filter="auth" {{# if(d.auth ==1){ }}checked value="0"{{# } else { }}value="1"{{# } }} id="{{d.id}}" >{else}<button class="layui-btn layui-btn-xs layui-btn-disabled">无权限</button>{/if}
|
||||
{{# } }}
|
||||
<script type="text/html" id="buttonAuth">
|
||||
{{# if(d.id == '1'){ }}
|
||||
<input type="checkbox" name="auth" lay-skin="primary" checked disabled >
|
||||
{{# } else { }}
|
||||
{if condition="checkRuleButton('user/auth')"}<input type="checkbox" name="auth" lay-skin="primary" lay-filter="auth" {{# if(d.auth ==1){ }}checked value="0"{{# } else { }}value="1"{{# } }} id="{{d.id}}" >{else}<button class="layui-btn layui-btn-xs layui-btn-disabled">无权限</button>{/if}
|
||||
{{# } }}
|
||||
</script>
|
||||
<script type="text/html" id="table-useradmin-webuser">
|
||||
{if condition="checkRuleButton('user/useredit')"}
|
||||
<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="edit" id={{ d.id }}><i class="layui-icon layui-icon-edit"></i>编辑</a>
|
||||
{else /}<a class="layui-btn layui-btn-normal layui-btn-xs layui-btn-disabled"><i class="layui-icon layui-icon-edit"></i>编辑</a>{/if}
|
||||
{if condition="checkRuleButton('user/delete')"}
|
||||
<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del" id={{ d.id }}><i class="layui-icon layui-icon-delete"></i>删除</a>
|
||||
{else /}<a class="layui-btn layui-btn-danger layui-btn-xs layui-btn-disabled"><i class="layui-icon layui-icon-delete"></i>删除</a>{/if}
|
||||
{if condition="checkRuleButton('user/useredit')"}
|
||||
<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="edit" id={{ d.id }}><i class="layui-icon layui-icon-edit"></i></a>
|
||||
{else /}<a class="layui-btn layui-btn-normal layui-btn-xs layui-btn-disabled"><i class="layui-icon layui-icon-edit"></i></a>{/if}
|
||||
{if condition="checkRuleButton('user/delete')"}
|
||||
<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del" id={{ d.id }}><i class="layui-icon layui-icon-delete"></i></a>
|
||||
{else /}<a class="layui-btn layui-btn-danger layui-btn-xs layui-btn-disabled"><i class="layui-icon layui-icon-delete"></i></a>{/if}
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,7 +1,6 @@
|
||||
{extend name="public/base" /}
|
||||
|
||||
{block name="body"}
|
||||
|
||||
<div class="layui-form" lay-filter="layuiadmin-form-useradmin" id="layuiadmin-form-useradmin" style="padding: 20px 0 0 0;">
|
||||
<div class="layui-form-item layui-hide">
|
||||
<input type="text" name="id" class="layui-input" value="{$user.id}">
|
||||
@ -50,9 +49,8 @@
|
||||
base: '/static/admin/' //静态资源所在路径
|
||||
}).extend({
|
||||
index: 'lib/index' //主入口模块
|
||||
}).use(['index', 'form', 'upload'], function(){
|
||||
}).use(['index', 'upload'], function(){
|
||||
var $ = layui.$
|
||||
,form = layui.form
|
||||
,upload = layui.upload ;
|
||||
//上传头像
|
||||
upload.render({
|
||||
@ -64,19 +62,19 @@
|
||||
,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
|
||||
});
|
||||
}
|
||||
if(res.code == 0){
|
||||
layer.msg(res.msg,{
|
||||
icon:6,
|
||||
tiye:2000
|
||||
});
|
||||
} else {
|
||||
layer.open({
|
||||
title:"上传失败",
|
||||
content:res.msg,
|
||||
icon:5,
|
||||
anim:6
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
|
@ -1,7 +1,6 @@
|
||||
{extend name="public/base" /}
|
||||
|
||||
{block name="body"}
|
||||
|
||||
<div class="layui-form" lay-filter="layuiadmin-form-useradmin" id="layuiadmin-form-useradmin" style="padding: 20px 30px 0 0;">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">用户名</label>
|
||||
@ -47,9 +46,8 @@
|
||||
base: '/static/admin/' //静态资源所在路径
|
||||
}).extend({
|
||||
index: 'lib/index' //主入口模块
|
||||
}).use(['index', 'form', 'upload'], function(){
|
||||
}).use(['index', 'upload'], function(){
|
||||
var $ = layui.$
|
||||
,form = layui.form
|
||||
,upload = layui.upload ;
|
||||
//上传头像
|
||||
upload.render({
|
||||
@ -61,19 +59,19 @@
|
||||
,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
|
||||
});
|
||||
}
|
||||
if(res.code == 0){
|
||||
layer.msg(res.msg,{
|
||||
icon:6,
|
||||
tiye:2000
|
||||
});
|
||||
} else {
|
||||
layer.open({
|
||||
title:"上传失败",
|
||||
content:res.msg,
|
||||
icon:5,
|
||||
anim:6
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
|
@ -4,7 +4,6 @@ use PHPMailer\PHPMailer\PHPMailer;
|
||||
use PHPMailer\PHPMailer\Exception;
|
||||
use think\facade\Request;
|
||||
use think\facade\Db;
|
||||
use think\facade\Cache;
|
||||
use think\facade\Session;
|
||||
use taoser\think\Auth;
|
||||
|
||||
@ -46,11 +45,13 @@ try {
|
||||
|
||||
$mail->send();
|
||||
//echo 'Message has been sent';
|
||||
return true;
|
||||
//return true;
|
||||
} catch (Exception $e) {
|
||||
//echo 'Message could not be sent. Mailer Error: ', $mail->ErrorInfo;
|
||||
return false;
|
||||
//return false;
|
||||
return $mail->ErrorInfo;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
//根据user area_id查询区域简称
|
||||
@ -79,19 +80,28 @@ if(!function_exists('getUserImg'))
|
||||
//根据文章分类ID查询分类名
|
||||
function getCateName($ename)
|
||||
{
|
||||
|
||||
return Db::name('cate')->where('ename',$ename)->cache(3600)->value('catename');
|
||||
if($ename == 'all') {
|
||||
return '全部分类';
|
||||
} else {
|
||||
return Db::name('cate')->where('ename',$ename)->cache(3600)->value('catename');
|
||||
}
|
||||
}
|
||||
|
||||
//根据文章分类ID查询分类描述
|
||||
function getCateDesc($ename)
|
||||
{
|
||||
return Db::name('cate')->where('ename',$ename)->cache(3600)->value('desc');
|
||||
if($ename == 'all') {
|
||||
return '全部分类,为您展示全部分类信息';
|
||||
} else {
|
||||
return Db::name('cate')->where('ename',$ename)->cache(3600)->value('desc');
|
||||
}
|
||||
}
|
||||
|
||||
//过滤文章摘要
|
||||
function getArtContent($content)
|
||||
{
|
||||
//过滤html标签
|
||||
$content = strip_tags($content);
|
||||
// 过滤音视频图片
|
||||
$content = preg_replace('/(?:img|audio|video)(\(\S+\))?\[\S+\]/','',$content);
|
||||
$content = preg_replace('/\s*/','',$content);
|
||||
@ -257,3 +267,39 @@ function getSpaceNmu($level)
|
||||
{
|
||||
return str_repeat('---',$level);
|
||||
}
|
||||
|
||||
//链接投放开关,有设置则打开
|
||||
function showSlider($type)
|
||||
{
|
||||
$sliders = new \app\common\model\Slider();
|
||||
$sliderArr = $sliders->getSliderList($type);
|
||||
if(!empty($sliderArr)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//提取内容第一张图片
|
||||
function getOnepic($str)
|
||||
{
|
||||
// <img src="http://img.com" />
|
||||
/* $pattern = "/<[img|IMG].*?src=[\'|\"](.*?(?:[\.gif|\.jpg|\.png]))[\'|\"].*?[\/]?>/";
|
||||
preg_match_all($pattern,$str,$matchContent);
|
||||
if(isset($matchContent[1][0])){
|
||||
$img = $matchContent[1][0];
|
||||
}else{
|
||||
$temp="./images/no-image.jpg";//在相应位置放置一张命名为no-image的jpg图片
|
||||
}
|
||||
*/
|
||||
// img[/storage/1/article_pic/20220428/6c2647d24d5ca2c179e4a5b76990c00c.jpg]
|
||||
$pattern = "/(?<=img\[)[^\]]*(?=\])/";
|
||||
preg_match($pattern,$str,$matchContent);
|
||||
if(isset($matchContent[0])){
|
||||
$img = $matchContent[0];
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
return $img;
|
||||
|
||||
}
|
@ -2,9 +2,9 @@
|
||||
/*
|
||||
* @Author: TaoLer <alipay_tao@qq.com>
|
||||
* @Date: 2021-12-06 16:04:50
|
||||
* @LastEditTime: 2022-05-12 16:02:40
|
||||
* @LastEditTime: 2022-05-17 11:15:46
|
||||
* @LastEditors: TaoLer
|
||||
* @Description: 搜索引擎SEO优化设置
|
||||
* @Description: 后台控制器设置
|
||||
* @FilePath: \TaoLer\app\common\controller\AdminController.php
|
||||
* Copyright (c) 2020~2022 https://www.aieok.com All rights reserved.
|
||||
*/
|
||||
@ -15,10 +15,8 @@ namespace app\common\controller;
|
||||
use think\facade\Session;
|
||||
use think\facade\View;
|
||||
use think\facade\Db;
|
||||
use think\facade\Request;
|
||||
use taoser\think\Auth;
|
||||
use taoler\com\Files;
|
||||
use think\facade\Lang;
|
||||
|
||||
/**
|
||||
* 控制器基础类
|
||||
@ -76,7 +74,7 @@ class AdminController extends \app\BaseController
|
||||
protected function getMenus($type)
|
||||
{
|
||||
$menu = [];
|
||||
$auth_rule_list = Db::name('auth_rule')->where('delete_time',0)->where(['status'=> 1])->where('type',$type)->order(['sort' => 'ASC', 'id' => 'ASC'])->select();
|
||||
$auth_rule_list = Db::name('auth_rule')->where(['delete_time'=> 0, 'status'=> 1,'type'=> $type])->order(['sort' => 'ASC', 'id' => 'ASC'])->select();
|
||||
//var_export($auth_rule_list);
|
||||
|
||||
foreach ($auth_rule_list as $value) {
|
||||
|
@ -1,13 +1,23 @@
|
||||
<?php
|
||||
/*
|
||||
* @Author: TaoLer <alipay_tao@qq.com>
|
||||
* @Date: 2021-12-06 16:04:50
|
||||
* @LastEditTime: 2022-07-26 15:17:08
|
||||
* @LastEditors: TaoLer
|
||||
* @Description: 前端基础控制器设置
|
||||
* @FilePath: \github\TaoLer\app\common\controller\BaseController.php
|
||||
* Copyright (c) 2020~2022 https://www.aieok.com All rights reserved.
|
||||
*/
|
||||
declare (strict_types = 1);
|
||||
|
||||
namespace app\common\controller;
|
||||
|
||||
use think\App;
|
||||
use think\facade\Request;
|
||||
use think\facade\View;
|
||||
use think\facade\Db;
|
||||
use think\facade\Session;
|
||||
use think\facade\Cache;
|
||||
use app\facade\Article;
|
||||
use app\BaseController as BaseCtrl;
|
||||
|
||||
/**
|
||||
@ -45,14 +55,6 @@ class BaseController extends BaseCtrl
|
||||
$this->error('请登录','/index/user/login');
|
||||
}
|
||||
}
|
||||
|
||||
/* //判断密码找回是否已进行了邮件发送?
|
||||
protected function isMailed()
|
||||
{
|
||||
if(Cache::get('repass') != 1){
|
||||
$this->error('错误请求,请正确操作!','/index/user/forget');
|
||||
}
|
||||
}*/
|
||||
|
||||
// 显示导航
|
||||
protected function showNav()
|
||||
@ -80,25 +82,43 @@ class BaseController extends BaseCtrl
|
||||
View::assign('user',$user);
|
||||
return $user;
|
||||
}
|
||||
|
||||
//热门标签
|
||||
protected function getHotTag()
|
||||
{
|
||||
//热门标签
|
||||
return Article::getHotTags();
|
||||
//转换为字符串
|
||||
// $tagStr = implode(",",$tags);
|
||||
//转换为数组并去重
|
||||
// return array_unique(explode(",",$tagStr));
|
||||
}
|
||||
|
||||
//显示网站设置
|
||||
//显示网站设置
|
||||
protected function showSystem()
|
||||
{
|
||||
//1.查询分类表获取所有分类
|
||||
$sysInfo = Db::name('system')->cache('system',3600)->find(1);
|
||||
$sysInfo = $this->getSystem();
|
||||
$slider = new \app\common\model\Slider();
|
||||
//头部链接
|
||||
$head_links = Cache::get('headlinks');
|
||||
if(!$head_links){
|
||||
$head_links = Db::name('slider')->where(['slid_status'=>1,'delete_time'=>0,'slid_type'=>10])->whereTime('slid_over','>=',time())->field('slid_name,slid_img,slid_href')->select();
|
||||
Cache::set('headlinks',$head_links,3600);
|
||||
}
|
||||
$head_links = $slider->getSliderList(10);
|
||||
//页脚链接
|
||||
$foot_links = Cache::get('footlinks');
|
||||
if(!$foot_links){
|
||||
$foot_links = Db::name('slider')->where(['slid_status'=>1,'delete_time'=>0,'slid_type'=>11])->whereTime('slid_over','>=',time())->field('slid_name,slid_href')->select();
|
||||
Cache::set('footlinks',$foot_links,3600);
|
||||
}
|
||||
View::assign(['sysInfo'=>$sysInfo,'headlinks'=>$head_links,'footlinks'=>$foot_links]);
|
||||
$foot_links = $slider->getSliderList(11);
|
||||
//友情链接
|
||||
$friend_links = $slider->getSliderList(9);
|
||||
//获取热门标签
|
||||
$hotTag = $this->getHotTag();
|
||||
|
||||
$assign = [
|
||||
'sysInfo' => $sysInfo,
|
||||
'headlinks' => $head_links,
|
||||
'footlinks' => $foot_links,
|
||||
'flinks' => $friend_links,
|
||||
'hotTag' => $hotTag,
|
||||
'host' => Request::domain() . '/'
|
||||
];
|
||||
|
||||
View::assign($assign);
|
||||
return $sysInfo;
|
||||
}
|
||||
|
||||
|
72
app/common/lib/QrCode.php
Normal file
72
app/common/lib/QrCode.php
Normal file
@ -0,0 +1,72 @@
|
||||
<?php
|
||||
/*
|
||||
* @Author: TaoLer <alipay_tao@qq.com>
|
||||
* @Date: 2022-05-27 20:57:43
|
||||
* @LastEditTime: 2022-05-28 09:33:43
|
||||
* @LastEditors: TaoLer
|
||||
* @Description: 搜索引擎SEO优化设置
|
||||
* @FilePath: \TaoLer\app\common\lib\QrCode.php
|
||||
* Copyright (c) 2020~2022 https://www.aieok.com All rights reserved.
|
||||
*/
|
||||
declare (strict_types = 1);
|
||||
|
||||
namespace app\common\lib;
|
||||
|
||||
use Endroid\QrCode\Builder\Builder;
|
||||
use Endroid\QrCode\Encoding\Encoding;
|
||||
use Endroid\QrCode\ErrorCorrectionLevel\ErrorCorrectionLevelHigh;
|
||||
use Endroid\QrCode\Label\Alignment\LabelAlignmentCenter;
|
||||
use Endroid\QrCode\Label\Font\NotoSans;
|
||||
use Endroid\QrCode\RoundBlockSizeMode\RoundBlockSizeModeMargin;
|
||||
use Endroid\QrCode\Writer\PngWriter;
|
||||
|
||||
class QrCode
|
||||
{
|
||||
/**
|
||||
* 生成二维码
|
||||
*
|
||||
* @param string $data
|
||||
* @param string $labText
|
||||
* @param string $logoPath
|
||||
* @return string 返回图片src
|
||||
*/
|
||||
public function getQrcode(string $data, $labText = '', $logoPath = ''): string
|
||||
{
|
||||
//
|
||||
if(empty($logoPath)) {
|
||||
$result = Builder::create()
|
||||
->writer(new PngWriter())
|
||||
->writerOptions([])
|
||||
->data($data)
|
||||
->encoding(new Encoding('UTF-8'))
|
||||
->errorCorrectionLevel(new ErrorCorrectionLevelHigh())
|
||||
->size(300)
|
||||
->margin(10)
|
||||
->roundBlockSizeMode(new RoundBlockSizeModeMargin())
|
||||
->labelText($labText)
|
||||
->labelFont(new NotoSans(20))
|
||||
->labelAlignment(new LabelAlignmentCenter())
|
||||
->build();
|
||||
} else {
|
||||
$result = Builder::create()
|
||||
->writer(new PngWriter())
|
||||
->writerOptions([])
|
||||
->data($data)
|
||||
->encoding(new Encoding('UTF-8'))
|
||||
->errorCorrectionLevel(new ErrorCorrectionLevelHigh())
|
||||
->size(300)
|
||||
->margin(10)
|
||||
->roundBlockSizeMode(new RoundBlockSizeModeMargin())
|
||||
->logoPath($logoPath)
|
||||
->labelText($labText)
|
||||
->labelFont(new NotoSans(20))
|
||||
->labelAlignment(new LabelAlignmentCenter())
|
||||
->build();
|
||||
}
|
||||
|
||||
header('Content-Type: ' . $result->getMimeType());
|
||||
//$result->getString();
|
||||
$imgsrc = $result->getDataUri();
|
||||
return $imgsrc;
|
||||
}
|
||||
}
|
@ -15,7 +15,7 @@ class Uploads
|
||||
|
||||
|
||||
/**
|
||||
* 获取上传文件的mime和后缀
|
||||
* 根据后台设置的文件类型,获取允许上传文件的mime和后缀
|
||||
* @param string $fileType 上传文件的类型只能为:视频video,文件application,图片image,文本text
|
||||
* @param string $type 获取文件的mime还是文件后缀ext
|
||||
* @return array
|
||||
@ -57,28 +57,23 @@ class Uploads
|
||||
return $arr;
|
||||
}
|
||||
|
||||
//上传文件
|
||||
|
||||
/**
|
||||
* 上传文件
|
||||
* 1.可以指定目录(若目录前有SYS_前缀,会上传到public/sys系统目录,不指定前缀,会上传到public/storage/用户ID)
|
||||
* 2.命名规则 可定义文件名类型a.jpg,b.php,或使用sha1,uniqid,md5函数
|
||||
*
|
||||
* @param string $fileName 文件名,form表单中的name
|
||||
* @param string $dirName
|
||||
* @param int $fileSize
|
||||
* @param string $fileType
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param string $fileName 文件名,form表单中的name
|
||||
* @param string $dirName 文件夹名,上传路径中的文件夹名称
|
||||
* @param string $dirName 文件夹名,上传路径中的文件夹名称,sys_前缀存放在/public/sys系统目录
|
||||
* @param int $fileSize 文件大小,上传限制大小
|
||||
* @param string $fileType 文件类型,只能为:视频video,文件application,图片image,文本text
|
||||
* @param string $rule 文件命名规则,默认md5,uniqid,date,sha1
|
||||
* @param string $rule 文件命名规则,默认md5,uniqid,date,sha1,为空则取文件上传名称,或者自定义如a.jpg文件名
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function put(string $fileName, string $dirName, int $fileSize, string $fileType, string $rule = null)
|
||||
{
|
||||
$file = request()->file($fileName);
|
||||
//halt($file->getOriginalName());
|
||||
//$type = $file->getMime();
|
||||
$fileExt = $this->getFileInfo($fileType,'ext');
|
||||
$fileMime = $this->getFileInfo($fileType,'mime');
|
||||
@ -90,22 +85,40 @@ class Uploads
|
||||
} catch (ValidateException $e) {
|
||||
return json(['status'=>-1,'msg'=>$e->getMessage()]);
|
||||
}
|
||||
|
||||
$savename = \think\facade\Filesystem::disk('public')->putFile(session('user_id'). '/' .$dirName, $file, $rule);
|
||||
$upload = Config::get('filesystem.disks.public.url');
|
||||
// 解析存储位置
|
||||
$isSys = stripos($dirName, 'SYS_');
|
||||
if($isSys !== false) {
|
||||
$disk = 'sys';
|
||||
$dirName = substr($dirName,4);
|
||||
$uploadDir = Config::get('filesystem.disks.sys.url');
|
||||
} else {
|
||||
$disk = 'public';
|
||||
$dirName = session('user_id'). '/' .$dirName;
|
||||
$uploadDir = Config::get('filesystem.disks.public.url');
|
||||
}
|
||||
$rules = ['md5','date','sha1','uniqid'];
|
||||
// 解析是否自定义文件名
|
||||
if(!in_array($rule, $rules) && !is_null($rule)) {
|
||||
if(stripos($rule, '.') == false) {
|
||||
$rule = $file->getOriginalName();
|
||||
}
|
||||
$savename = \think\facade\Filesystem::disk($disk)->putFileAs($dirName, $file, $rule);
|
||||
} else {
|
||||
$savename = \think\facade\Filesystem::disk($disk)->putFile($dirName, $file, $rule);
|
||||
}
|
||||
|
||||
if($savename){
|
||||
//$name = $file->hashName();
|
||||
$name_path =str_replace('\\',"/",$upload.'/'.$savename);
|
||||
//halt($name_path);
|
||||
$name_path =str_replace('\\',"/", $uploadDir . '/' . $savename);
|
||||
//$image = \think\Image::open("uploads/$name_path");
|
||||
//$image->thumb(168, 168)->save("uploads/$name_path");
|
||||
|
||||
$res = ['status'=>0,'msg'=>'上传成功','url'=> $name_path];
|
||||
$res = ['status'=>0,'msg'=>'上传成功','url'=> $name_path, 'location'=>$name_path];
|
||||
}else{
|
||||
$res = ['status'=>-1,'msg'=>'上传错误'];
|
||||
}
|
||||
return json($res);
|
||||
|
||||
return json($res);
|
||||
}
|
||||
|
||||
}
|
@ -7,7 +7,7 @@ use think\Model;
|
||||
use think\model\concern\SoftDelete;
|
||||
use think\facade\Cache;
|
||||
use think\facade\Config;
|
||||
use think\facade\Db;
|
||||
use Overtrue\Pinyin\Pinyin;
|
||||
|
||||
class Article extends Model
|
||||
{
|
||||
@ -44,6 +44,12 @@ class Article extends Model
|
||||
{
|
||||
return $this->hasMany(Collection::class);
|
||||
}
|
||||
|
||||
//文章关联用户点赞
|
||||
public function userzan()
|
||||
{
|
||||
return $this->hasMany(UserZan::class);
|
||||
}
|
||||
|
||||
//文章关联用户
|
||||
public function user()
|
||||
@ -58,12 +64,13 @@ class Article extends Model
|
||||
*/
|
||||
public function add(array $data)
|
||||
{
|
||||
$superAdmin = Db::name('user')->where('id',$data['user_id'])->value('auth');
|
||||
$superAdmin = 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) {
|
||||
return ['code'=>1,'msg'=>$msg];
|
||||
return ['code' => 1, 'msg' => $msg, 'data' => ['status' => $data['status']]];
|
||||
} else {
|
||||
return 'add_error';
|
||||
}
|
||||
@ -79,7 +86,7 @@ class Article extends Model
|
||||
*/
|
||||
public function edit(array $data)
|
||||
{
|
||||
$article = $this->find($data['id']);
|
||||
$article = $this::find($data['id']);
|
||||
$result = $article->save($data);
|
||||
if($result) {
|
||||
return 1;
|
||||
@ -107,7 +114,12 @@ class Article extends Model
|
||||
'user' => function ($query) {
|
||||
$query->field('id,name,nickname,user_img,area_id,vip');
|
||||
}
|
||||
])->withCount(['comments'])->order('create_time', 'desc')->limit($num)->select()->toArray();
|
||||
])->withCount(['comments'])
|
||||
->order('create_time', 'desc')
|
||||
->limit($num)
|
||||
->append(['url'])
|
||||
->select()
|
||||
->toArray();
|
||||
|
||||
Cache::tag('tagArtDetail')->set('arttop', $artTop, 60);
|
||||
}
|
||||
@ -134,7 +146,14 @@ class Article extends Model
|
||||
'user' => function($query){
|
||||
$query->field('id,name,nickname,user_img,area_id,vip');
|
||||
} ])
|
||||
->withCount(['comments'])->where(['status'=>1,'is_top'=>0])->order('create_time','desc')->limit($num)->select()->toArray();
|
||||
->withCount(['comments'])
|
||||
->where(['status'=>1,'is_top'=>0])
|
||||
->order('create_time','desc')
|
||||
->limit($num)
|
||||
->append(['url'])
|
||||
->select()
|
||||
->toArray();
|
||||
|
||||
Cache::tag('tagArt')->set('artlist',$artList,60);
|
||||
}
|
||||
return $artList;
|
||||
@ -150,13 +169,19 @@ class Article extends Model
|
||||
*/
|
||||
public function getArtHot(int $num)
|
||||
{
|
||||
$artHot = $this::field('id,title')
|
||||
$artHot = $this::field('id,cate_id,title,create_time')
|
||||
->with([ 'cate' => function($query){
|
||||
$query->where('delete_time',0)->field('id,ename');
|
||||
}])
|
||||
->withCount('comments')
|
||||
->where(['status'=>1,'delete_time'=>0])
|
||||
->whereTime('create_time', 'year')
|
||||
->order('comments_count','desc')
|
||||
->limit($num)
|
||||
->withCache(60)->select();
|
||||
->withCache(120)
|
||||
->append(['url'])
|
||||
->select();
|
||||
|
||||
return $artHot;
|
||||
}
|
||||
|
||||
@ -168,19 +193,23 @@ class Article extends Model
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function getArtDetail(int $id, int $page)
|
||||
public function getArtDetail(int $id)
|
||||
{
|
||||
$article = Cache::get('article_'.$id);
|
||||
if(!$article){
|
||||
//查询文章
|
||||
$article = $this::field('id,title,content,status,cate_id,user_id,is_top,is_hot,is_reply,pv,jie,upzip,downloads,tags,description,title_color,create_time')->where('status',1)->with([
|
||||
$article = $this::field('id,title,content,status,cate_id,user_id,goods_detail_id,is_top,is_hot,is_reply,pv,jie,upzip,downloads,tags,description,title_color,create_time,update_time')->where('status',1)->with([
|
||||
'cate' => function($query){
|
||||
$query->where('delete_time',0)->field('id,catename,ename');
|
||||
},
|
||||
'user' => function($query){
|
||||
$query->field('id,name,nickname,user_img,area_id,vip');
|
||||
$query->field('id,name,nickname,user_img,area_id,vip,city')->withCount(['article','comments']);
|
||||
}
|
||||
])->withCount(['comments'])->find($id)->toArray();
|
||||
])
|
||||
->withCount(['comments'])
|
||||
->append(['url'])
|
||||
->find($id)
|
||||
->toArray();
|
||||
Cache::tag('tagArtDetail')->set('article_'.$id, $article, 3600);
|
||||
}
|
||||
return $article;
|
||||
@ -212,84 +241,143 @@ class Article extends Model
|
||||
switch ($type) {
|
||||
//查询文章,15个分1页
|
||||
case 'jie':
|
||||
$artList = $this::field('id,title,content,title_color,cate_id,user_id,create_time,is_top,is_hot,pv,jie,upzip,has_img,has_video,has_audio')->with([
|
||||
'cate' => function($query){
|
||||
$query->where('delete_time',0)->field('id,catename,ename');
|
||||
},
|
||||
'user' => function($query){
|
||||
$query->field('id,name,nickname,user_img,area_id,vip');
|
||||
}
|
||||
])->withCount(['comments'])->where(['status'=>1,'jie'=>1])->where($where)->order(['is_top'=>'desc','create_time'=>'desc'])
|
||||
->paginate([
|
||||
'list_rows' => 15,
|
||||
'page' => $page
|
||||
])->toArray();
|
||||
$where['jie'] = 1;
|
||||
break;
|
||||
|
||||
case 'hot':
|
||||
$artList = $this::field('id,title,content,title_color,cate_id,user_id,create_time,is_top,is_hot,pv,jie,upzip,has_img,has_video,has_audio')->with([
|
||||
'cate' => function($query){
|
||||
$query->where('delete_time',0)->field('id,catename,ename');
|
||||
},
|
||||
'user' => function($query){
|
||||
$query->field('id,name,nickname,user_img,area_id,vip');
|
||||
}
|
||||
])->withCount(['comments'])->where('status',1)->where($where)->where('is_hot',1)->order(['is_top'=>'desc','create_time'=>'desc'])
|
||||
->paginate([
|
||||
'list_rows' => 15,
|
||||
'page' => $page
|
||||
])->toArray();
|
||||
$where['is_hot'] = 1;
|
||||
break;
|
||||
|
||||
case 'top':
|
||||
$artList = $this::field('id,title,content,title_color,cate_id,user_id,create_time,is_top,is_hot,pv,jie,upzip,has_img,has_video,has_audio')->with([
|
||||
'cate' => function($query){
|
||||
$query->where('delete_time',0)->field('id,catename,ename');
|
||||
},
|
||||
'user' => function($query){
|
||||
$query->field('id,name,nickname,user_img,area_id,vip');
|
||||
}
|
||||
])->withCount(['comments'])->where('status',1)->where($where)->where('is_top',1)->order(['is_top'=>'desc','create_time'=>'desc'])
|
||||
->paginate([
|
||||
'list_rows' => 15,
|
||||
'page' => $page
|
||||
])->toArray();
|
||||
$where['is_top'] = 1;
|
||||
break;
|
||||
|
||||
case 'wait':
|
||||
$artList = $this::field('id,title,content,title_color,cate_id,user_id,create_time,is_top,is_hot,pv,jie,upzip,has_img,has_video,has_audio')->with([
|
||||
'cate' => function($query){
|
||||
$query->where('delete_time',0)->field('id,catename,ename');
|
||||
},
|
||||
'user' => function($query){
|
||||
$query->field('id,name,nickname,user_img,area_id,vip');
|
||||
}
|
||||
])->withCount(['comments'])->where('status',1)->where($where)->where('jie',0)->order(['is_top'=>'desc','create_time'=>'desc'])
|
||||
->paginate([
|
||||
'list_rows' => 15,
|
||||
'page' => $page
|
||||
])->toArray();
|
||||
$where['jie'] = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
$artList = $this::field('id,title,content,title_color,cate_id,user_id,create_time,is_top,is_hot,pv,jie,upzip,has_img,has_video,has_audio')->with([
|
||||
'cate' => function($query){
|
||||
$query->where('delete_time',0)->field('id,catename,ename');
|
||||
},
|
||||
'user' => function($query){
|
||||
$query->field('id,name,nickname,user_img,area_id,vip');
|
||||
}
|
||||
])->withCount(['comments'])->where('status',1)->where($where)->order(['is_top'=>'desc','create_time'=>'desc'])
|
||||
->paginate([
|
||||
'list_rows' => 15,
|
||||
'page' => $page
|
||||
])->toArray();
|
||||
$where = $where;
|
||||
break;
|
||||
}
|
||||
$artList = $this::field('id,title,content,title_color,cate_id,user_id,create_time,is_top,is_hot,pv,jie,upzip,has_img,has_video,has_audio')
|
||||
->with([
|
||||
'cate' => function($query){
|
||||
$query->where('delete_time',0)->field('id,catename,ename');
|
||||
},
|
||||
'user' => function($query){
|
||||
$query->field('id,name,nickname,user_img,area_id,vip');
|
||||
}
|
||||
])->withCount(['comments'])
|
||||
->where('status',1)
|
||||
->where($where)
|
||||
->order(['is_top'=>'desc','create_time'=>'desc'])
|
||||
->paginate([
|
||||
'list_rows' => 15,
|
||||
'page' => $page
|
||||
])->append(['url'])->toArray();
|
||||
|
||||
Cache::tag('tagArtDetail')->set('arts'.$ename.$type.$page,$artList,600);
|
||||
}
|
||||
return $artList;
|
||||
}
|
||||
|
||||
// 获取用户发帖列表
|
||||
public function getUserArtList(int $id) {
|
||||
$userArtList = $this::field('id,cate_id,title,create_time,pv,is_hot')
|
||||
->with(['cate' => function($query){
|
||||
$query->where(['delete_time'=>0,'status'=>1])->field('id,ename');
|
||||
}])
|
||||
->where(['user_id' => $id,'status' => 1])
|
||||
->order(['create_time'=>'desc'])
|
||||
->append(['url'])
|
||||
->cache(3600)
|
||||
->select()
|
||||
->toArray();
|
||||
|
||||
return $userArtList;
|
||||
}
|
||||
|
||||
// 获取搜索文章
|
||||
public function getSearchKeyWord(string $keywords)
|
||||
{
|
||||
//全局查询条件
|
||||
$map = []; //所有的查询条件封装到数组中
|
||||
//条件1:
|
||||
$map[] = ['status','=',1]; //这里等号不能省略
|
||||
|
||||
if(!empty($keywords)){
|
||||
//条件2
|
||||
$map[] = ['title','like','%'.$keywords.'%'];
|
||||
$res = Article::where($map)
|
||||
->withCount('comments')
|
||||
->order('create_time','desc')
|
||||
->append(['url'])
|
||||
->paginate(10);
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
|
||||
// 热门标签
|
||||
public function getHotTags()
|
||||
{
|
||||
$pinyin = new Pinyin();
|
||||
$tags = $this->where(['status'=>1])->where('tags','<>','')->order('pv desc')->limit(100)->column('tags');
|
||||
//转换为字符串
|
||||
$tagStr = implode(",",$tags);
|
||||
//转换为数组并去重
|
||||
$tagArr = array_unique(explode(",",$tagStr));
|
||||
|
||||
$tagHot = [];
|
||||
foreach($tagArr as $v) {
|
||||
$tagHot[] = ['tag'=>$v,'url'=> (string) url('tag_list',['tag'=>$pinyin->permalink($v,'')])];
|
||||
}
|
||||
|
||||
return $tagHot;
|
||||
}
|
||||
|
||||
// 查询包含tag标签的文章
|
||||
public function getAllTags($tag)
|
||||
{
|
||||
$pinyin = new Pinyin();
|
||||
$allTags = $this->field('id,title,is_hot,tags,cate_id,user_id,create_time,pv')->where(['status'=>1])->where('tags','<>','')
|
||||
->with([
|
||||
'cate' => function($query){
|
||||
$query->where('delete_time',0)->field('id,catename,ename');
|
||||
},
|
||||
'user' => function($query){
|
||||
$query->field('id,name,nickname,user_img,area_id,vip');
|
||||
}
|
||||
])->withCount(['comments'])
|
||||
->order('pv desc')->limit(100)->append(['url'])->select()->toArray();
|
||||
//halt($tags);
|
||||
$artTag = [];
|
||||
foreach($allTags as $v) {
|
||||
if(stripos($v['tags'],',') !== false){
|
||||
$tagArr = explode(",",$v['tags']);
|
||||
foreach($tagArr as $s) {
|
||||
$tagPinyin = $pinyin->permalink($s,'');
|
||||
if(stripos($tagPinyin, $tag) !== false) {
|
||||
$artTag[] = $v;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$tagPinyin = $pinyin->permalink($v['tags'],'');
|
||||
if(stripos($tagPinyin, $tag) !== false) {
|
||||
$artTag[] = $v;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return $artTag;
|
||||
}
|
||||
|
||||
// 获取url
|
||||
public function getUrlAttr($value,$data)
|
||||
{
|
||||
if(config('taoler.url_rewrite.article_as') == '<ename>/') {
|
||||
$cate = Cate::field('id,ename')->find($data['cate_id']);
|
||||
return (string) url('article_detail',['id' => $data['id'],'ename' => $cate->ename]);
|
||||
} else {
|
||||
return (string) url('article_detail',['id' => $data['id']]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,4 +1,13 @@
|
||||
<?php
|
||||
/*
|
||||
* @Author: TaoLer <alipay_tao@qq.com>
|
||||
* @Date: 2021-12-06 16:04:50
|
||||
* @LastEditTime: 2022-07-27 21:42:34
|
||||
* @LastEditors: TaoLer
|
||||
* @Description: 搜索引擎SEO优化设置
|
||||
* @FilePath: \github\TaoLer\app\common\model\Comment.php
|
||||
* Copyright (c) 2020~2022 https://www.aieok.com All rights reserved.
|
||||
*/
|
||||
namespace app\common\model;
|
||||
|
||||
use think\Model;
|
||||
@ -31,37 +40,82 @@ class Comment extends Model
|
||||
//获取评论
|
||||
public function getComment($id, $page)
|
||||
{
|
||||
$comments = $this::with(['user'])->where(['article_id'=>$id,'status'=>1])->order(['cai'=>'asc','create_time'=>'asc'])->paginate(['list_rows'=>10, 'page'=>$page]);
|
||||
$comments = $this::with(['user'])->where(['article_id'=>(int)$id,'status'=>1])->order(['cai'=>'asc','create_time'=>'asc'])->paginate(['list_rows'=>10, 'page'=>$page]);
|
||||
return $comments;
|
||||
}
|
||||
|
||||
//回帖榜
|
||||
public function reply($num)
|
||||
{
|
||||
$res = Cache::get('reply');
|
||||
if(!$res){
|
||||
$user = User::withCount('comments')->order(['comments_count'=>'desc','last_login_time'=>'desc'])->limit($num)->select()->toArray();
|
||||
if($user)
|
||||
{
|
||||
$res['status'] = 0;
|
||||
$res['data'] = array();
|
||||
foreach ($user as $key=>$v) {
|
||||
|
||||
$u['uid'] = (string) url('user/home',['id'=>$v['id']]);
|
||||
$u['count(*)'] = $v['comments_count'];
|
||||
if($v['nickname'])
|
||||
{
|
||||
$u['user'] = ['username'=>$v['nickname'],'avatar'=>$v['user_img']];
|
||||
} else {
|
||||
$u['user'] = ['username'=>$v['name'],'avatar'=>$v['user_img']];
|
||||
}
|
||||
$res['data'][] = $u;
|
||||
}
|
||||
// $user = Cache::get('user_reply');
|
||||
// if(empty($user)){
|
||||
try {
|
||||
$user = User::field('id,user_img,name,nickname')
|
||||
->withCount(['comments'=> function($query) {
|
||||
$query->where(['status'=>1]);
|
||||
}])
|
||||
->order(['comments_count'=>'desc','last_login_time'=>'desc'])
|
||||
->limit($num)
|
||||
->select()
|
||||
->toArray();
|
||||
} catch(\Exception $e) {
|
||||
return json(['status'=>-1,'msg'=>$e->getMessage()]);
|
||||
}
|
||||
Cache::set('reply',$res,3600);
|
||||
}
|
||||
|
||||
// Cache::set('user_reply',$user,180);
|
||||
// }
|
||||
|
||||
if(count($user)) {
|
||||
$res['status'] = 0;
|
||||
$res['data'] = array();
|
||||
foreach ($user as $key=>$v) {
|
||||
//$u['uid'] = (string) url('user/home',['id'=>$v['id']]);
|
||||
$u['uid'] = (string) \think\facade\Route::buildUrl('user_home', ['id' => $v['id']]);
|
||||
$u['count'] = $v['comments_count'];
|
||||
if($v['nickname'])
|
||||
{
|
||||
$u['user'] = ['username'=>$v['nickname'],'avatar'=>$v['user_img']];
|
||||
} else {
|
||||
$u['user'] = ['username'=>$v['name'],'avatar'=>$v['user_img']];
|
||||
}
|
||||
$res['data'][] = $u;
|
||||
}
|
||||
} else {
|
||||
$res = ['status' => 0, 'msg' =>'no reply'];
|
||||
}
|
||||
return json($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户评论列表
|
||||
*
|
||||
* @param integer $id
|
||||
* @return void
|
||||
*/
|
||||
public function getUserCommentList(int $id) {
|
||||
$userCommList = $this::field('id,user_id,create_time,delete_time,article_id,content')
|
||||
->with(['article' => function(\think\model\Relation $query){
|
||||
$query->withField('id,title,cate_id,delete_time')->where(['status' => 1,'delete_time' => 0]);
|
||||
}])
|
||||
->where(['user_id' => $id,'status' => 1,'delete_time'=>0])
|
||||
//->append(['url'])
|
||||
->order(['create_time' => 'desc'])
|
||||
//->cache(3600)
|
||||
->select()
|
||||
->toArray();
|
||||
|
||||
return $userCommList;
|
||||
}
|
||||
|
||||
// 获取url
|
||||
public function getUrlAttr($value,$data)
|
||||
{
|
||||
if(config('taoler.url_rewrite.article_as') == '<ename>/') {
|
||||
$cate = Cate::field('id,ename')->find($data['article']['cate_id']);
|
||||
return (string) url('detail',['id' => $data['id'],'ename'=>$cate->ename]);
|
||||
} else {
|
||||
return (string) url('detail',['id' => $data['id']]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,4 +1,13 @@
|
||||
<?php
|
||||
/*
|
||||
* @Author: TaoLer <317927823@qq.com>
|
||||
* @Date: 2021-12-06 16:04:50
|
||||
* @LastEditTime: 2022-07-27 21:25:14
|
||||
* @LastEditors: TaoLer
|
||||
* @Description: 优化版
|
||||
* @FilePath: \github\TaoLer\app\common\model\MessageTo.php
|
||||
* Copyright (c) 2020~2022 https://www.aieok.com All rights reserved.
|
||||
*/
|
||||
namespace app\common\model;
|
||||
|
||||
use think\Model;
|
||||
@ -22,5 +31,14 @@ class MessageTo extends Model
|
||||
return $this->belongsTo('Message','message_id','id');
|
||||
}
|
||||
|
||||
//得到消息数
|
||||
public function getMsgNum($id)
|
||||
{
|
||||
$msg = $this::field('id')->where(['receve_id'=>$id,'is_read'=>0])->column('id');
|
||||
if(!is_null($msg)) {
|
||||
return count($msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,10 +1,10 @@
|
||||
<?php
|
||||
/*
|
||||
* @Author: TaoLer <alipey_tao@qq.com>
|
||||
* @Author: TaoLer <alipay_tao@qq.com>
|
||||
* @Date: 2021-12-06 16:04:50
|
||||
* @LastEditTime: 2022-05-01 17:10:55
|
||||
* @LastEditTime: 2022-06-28 13:54:55
|
||||
* @LastEditors: TaoLer
|
||||
* @Description: 链接投放优化设置
|
||||
* @Description: 链接设置
|
||||
* @FilePath: \TaoLer\app\common\model\Slider.php
|
||||
* Copyright (c) 2020~2022 http://www.aieok.com All rights reserved.
|
||||
*/
|
||||
@ -44,41 +44,41 @@ class Slider extends Model
|
||||
$sliders = Cache::get('slider'.$type);
|
||||
if(!$sliders){
|
||||
$sliders = $this::where(['slid_status'=>1,'delete_time'=>0,'slid_type'=>$type])->whereTime('slid_over','>=',time())->select()->toArray();
|
||||
Cache::tag('tagSlider')->set('slider'.$type,$sliders,3600);
|
||||
Cache::tag('tagSlider'.$type)->set('slider'.$type,$sliders,3600);
|
||||
}
|
||||
return $sliders;
|
||||
}
|
||||
|
||||
//添加
|
||||
// 添加
|
||||
public function add($data)
|
||||
{
|
||||
$result = $this::save($data);
|
||||
$result = $this::create($data);
|
||||
|
||||
if($result) {
|
||||
Cache::tag('tagSlider')->clear();
|
||||
Cache::tag('tagSlider'.$data['slid_type'])->clear();
|
||||
return 1;
|
||||
} else {
|
||||
return 'add_error';
|
||||
}
|
||||
}
|
||||
|
||||
//文章编辑
|
||||
// 文章编辑
|
||||
public function edit($data)
|
||||
{
|
||||
$slider = $this::find($data['id']);
|
||||
$result = $slider->save($data);
|
||||
if($result) {
|
||||
Cache::tag('tagSlider')->clear();
|
||||
Cache::tag('tagSlider'.$data['slid_type'])->clear();
|
||||
return 1;
|
||||
} else {
|
||||
return 'edit_error';
|
||||
}
|
||||
}
|
||||
|
||||
//获取器
|
||||
// 获取器
|
||||
public function getSlidTypeAttr($value)
|
||||
{
|
||||
$slid_type = [1=>'首页幻灯',2=>'首页图片',3=>'分类图片',4=>'详情图片',5=>'首页赞助',6=>'分类赞助',7=>'详情赞助',8=>'温馨通道',9=>'友情链接',10=>'头部菜单',11=>'页脚链接'];
|
||||
$slid_type = [1=>'首页幻灯',2=>'首页图片',3=>'分类图片',4=>'详情图片',5=>'首页赞助',6=>'分类赞助',7=>'详情赞助',8=>'温馨通道',9=>'友情链接',10=>'头部菜单',11=>'页脚链接',12=>'移动首页幻灯',13=>'首页右栏广告'];
|
||||
return $slid_type[$value];
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,7 @@ class UpgradeAuth extends Model
|
||||
|
||||
public function getAuthLevelAttr($value)
|
||||
{
|
||||
$level = [0=>'免费版',1=>'初级版',2=>'高级版'];
|
||||
$level = [0=>'免费版', 1=>'初级版', 2=>'中级版', 3=>'高级版'];
|
||||
return $level[$value];
|
||||
}
|
||||
|
||||
|
@ -40,6 +40,11 @@ class User extends Model
|
||||
{
|
||||
return $this->belongsTo('UserArea','user_raea_id','id');
|
||||
}
|
||||
|
||||
public function article()
|
||||
{
|
||||
return $this->hasMany(Article::class);
|
||||
}
|
||||
|
||||
//登陆校验
|
||||
public function login($data)
|
||||
|
@ -1,4 +1,13 @@
|
||||
<?php
|
||||
/*
|
||||
* @Author: TaoLer <317927823@qq.com>
|
||||
* @Date: 2021-12-06 16:04:50
|
||||
* @LastEditTime: 2022-07-18 18:32:40
|
||||
* @LastEditors: TaoLer
|
||||
* @Description: 优化版
|
||||
* @FilePath: \TaoLer\app\common\model\UserZan.php
|
||||
* Copyright (c) 2020~2022 https://www.aieok.com All rights reserved.
|
||||
*/
|
||||
namespace app\common\model;
|
||||
|
||||
use think\Model;
|
||||
@ -26,5 +35,11 @@ class UserZan extends Model
|
||||
//评论关联用户
|
||||
return $this->belongsTo('User','user_id','id');
|
||||
}
|
||||
|
||||
public function article()
|
||||
{
|
||||
//评论关联用户
|
||||
return $this->belongsTo(Article::class);
|
||||
}
|
||||
|
||||
}
|
115
app/common/taglib/Article.php
Normal file
115
app/common/taglib/Article.php
Normal file
@ -0,0 +1,115 @@
|
||||
<?php
|
||||
/*
|
||||
* @Author: TaoLer <alipay_tao@qq.com>
|
||||
* @Date: 2022-05-17 13:08:11
|
||||
* @LastEditTime: 2022-07-23 09:39:52
|
||||
* @LastEditors: TaoLer
|
||||
* @Description: 搜索引擎SEO优化设置
|
||||
* @FilePath: \TaoLer\app\common\taglib\Article.php
|
||||
* Copyright (c) 2020~2022 https://www.aieok.com All rights reserved.
|
||||
*/
|
||||
//declare (strict_types = 1);
|
||||
|
||||
namespace app\common\taglib;
|
||||
|
||||
use think\template\TagLib;
|
||||
use app\common\model\Article as ArticleModel;
|
||||
|
||||
class Article extends TagLib
|
||||
{
|
||||
//
|
||||
protected $tags = [
|
||||
// 标签定义: attr 属性列表 close 是否闭合(0 或者1 默认1) alias 标签别名 level 嵌套层次
|
||||
'id' => ['attr' => '', 'close' => 0],
|
||||
'title' => ['attr' => 'cid', 'close' => 0],
|
||||
'content' => ['attr' => 'name', 'close' => 0],
|
||||
'istop' => ['attr' => '', 'close' => 0],
|
||||
'aname' => ['attr' => 'name', 'close' => 0],
|
||||
'commentnum' => ['attr' => 'name', 'close' => 0],
|
||||
'comment' => ['attr' => '', 'close' => 1],
|
||||
|
||||
];
|
||||
|
||||
// public function __construct($a)
|
||||
// {
|
||||
// $id = (int) input('id');
|
||||
// $this->id = $id;
|
||||
// $page = input('page') ? (int) input('page') : 1;
|
||||
// //parent::__construct();
|
||||
// if(request()->action() == 'detail') {
|
||||
// $article = new ArticleModel();
|
||||
// $this->article = $article->getArtDetail($id);
|
||||
// // dump($this->article);
|
||||
// }
|
||||
|
||||
// }
|
||||
|
||||
public function tagId($tag): string
|
||||
{
|
||||
//dump($tag);
|
||||
$parseStr = $this->article;
|
||||
//return $parseStr;
|
||||
return '<?php echo "' . $parseStr['id'] . '"; ?>';
|
||||
}
|
||||
|
||||
public function tagTitle(array $tag, string $content): string
|
||||
{
|
||||
$cid = (int) $this->tpl->get('cid');
|
||||
$article = new ArticleModel();
|
||||
$art = $article->getArtDetail($cid);
|
||||
//dump($art);
|
||||
$parseStr = $art['title'];
|
||||
//$parseStr = 123;
|
||||
//return $parseStr;
|
||||
return '<?php echo "' . $parseStr . '"; ?>';
|
||||
}
|
||||
|
||||
public function tagContent($tag): string
|
||||
{
|
||||
$parseStr = $this->article['content'];
|
||||
//return $parseStr;
|
||||
return '<?php echo "' . $parseStr . '"; ?>';
|
||||
}
|
||||
|
||||
public function tagAname($tag): string
|
||||
{
|
||||
$parseStr = $this->article['user']['nickname'] ?: $this->article['user']['name'];
|
||||
// dump($parseStr);
|
||||
return $parseStr;
|
||||
|
||||
}
|
||||
|
||||
public function tagCommentnum($tag): string
|
||||
{
|
||||
$parseStr = $this->article['comments_count'];
|
||||
// dump($parseStr);
|
||||
return $parseStr;
|
||||
|
||||
}
|
||||
|
||||
public function tagIstop($tag): string
|
||||
{
|
||||
//dump($this->article);
|
||||
$parseStr = '{if($article.is_top == 0)}';
|
||||
$parseStr .= '<span class="layui-btn layui-btn-xs jie-admin" type="set" field="top" rank="1" style="background-color: #ccc" title="置顶">顶</span>';
|
||||
$parseStr .= '{else /}';
|
||||
$parseStr .= '<span class="layui-btn layui-btn-xs jie-admin" type="set" field="top" rank="0" title="取消置顶">顶</span>';
|
||||
$parseStr .= '{/if}';
|
||||
return $parseStr;
|
||||
}
|
||||
|
||||
// public function tagComment($tag, $content): string
|
||||
// {
|
||||
// //
|
||||
// //$arr = $this->getComments($this->id, $this->page);
|
||||
// $parse = '<?php ';
|
||||
// $parse .= '$comment_arr=[[1,3,5,7,9],[2,4,6,8,10]];'; // 这里是模拟数据
|
||||
// $parse .= '$__LIST__ = $comment_arr[' . $type . '];';
|
||||
/** $parse .= ' ?>';*/
|
||||
// $parse .= '{volist name="__LIST__" id="' . $name . '"}';
|
||||
// $parse .= $content;
|
||||
// $parse .= '{/volist}';
|
||||
// return $parse;
|
||||
// }
|
||||
|
||||
}
|
@ -1,4 +1,13 @@
|
||||
<?php
|
||||
/*
|
||||
* @Author: TaoLer <alipay_tao@qq.com>
|
||||
* @Date: 2021-12-06 16:04:50
|
||||
* @LastEditTime: 2022-06-22 16:19:38
|
||||
* @LastEditors: TaoLer
|
||||
* @Description: 搜索引擎SEO优化设置
|
||||
* @FilePath: \TaoLer\app\common\validate\User.php
|
||||
* Copyright (c) 2020~2022 https://www.aieok.com All rights reserved.
|
||||
*/
|
||||
namespace app\common\validate;
|
||||
|
||||
use think\Validate;
|
||||
@ -42,7 +51,7 @@ class User extends Validate
|
||||
//注册验证场景
|
||||
public function sceneReg()
|
||||
{
|
||||
return $this->only(['name','email','password','repassword','captcha']);
|
||||
return $this->only(['name','email','password','repassword']);
|
||||
|
||||
}
|
||||
|
||||
|
43
app/index/config/view.php
Normal file
43
app/index/config/view.php
Normal file
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 模板设置
|
||||
// +----------------------------------------------------------------------
|
||||
use think\facade\Db;
|
||||
//如果网站安装从数据库查询选择的模板
|
||||
if(file_exists('./install.lock')){
|
||||
$template = Db::name('system')->where('id',1)->value('template');
|
||||
} else {
|
||||
$template = '';
|
||||
}
|
||||
|
||||
return [
|
||||
// 模板引擎类型使用Think
|
||||
'type' => 'Think',
|
||||
// 默认模板渲染规则 1 解析为小写+下划线 2 全部转换小写 3 保持操作方法
|
||||
'auto_rule' => 1,
|
||||
// 模板目录名
|
||||
'view_dir_name' => 'view' . DIRECTORY_SEPARATOR . $template,
|
||||
// 模板后缀
|
||||
'view_suffix' => 'html',
|
||||
// 预先加载的标签库
|
||||
'taglib_pre_load' => 'app\common\taglib\Article',
|
||||
// 模板文件名分隔符
|
||||
'view_depr' => DIRECTORY_SEPARATOR,
|
||||
// 模板引擎普通标签开始标记
|
||||
'tpl_begin' => '{',
|
||||
// 模板引擎普通标签结束标记
|
||||
'tpl_end' => '}',
|
||||
// 标签库标签开始标记
|
||||
'taglib_begin' => '{',
|
||||
// 标签库标签结束标记
|
||||
'taglib_end' => '}',
|
||||
|
||||
'default_filter' => 'htmlspecialchars',
|
||||
|
||||
//模板输出替换
|
||||
// 'tpl_replace_string' => [
|
||||
// '__STATIC__'=>'/static/layui',
|
||||
// '__JS__' => '/static/res/',
|
||||
// ],
|
||||
|
||||
];
|
@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
namespace app\index\controller;
|
||||
|
||||
use app\common\controller\BaseController;
|
||||
@ -10,11 +11,13 @@ use think\facade\Config;
|
||||
use app\common\model\Comment;
|
||||
use app\common\model\Article as ArticleModel;
|
||||
use app\common\model\Slider;
|
||||
use think\exception\ValidateException;
|
||||
use app\common\model\UserZan;
|
||||
use taoler\com\Message;
|
||||
use app\common\lib\Msgres;
|
||||
use app\common\lib\Uploads;
|
||||
use taoser\SetArr;
|
||||
use taoler\com\Api;
|
||||
use Overtrue\Pinyin\Pinyin;
|
||||
|
||||
class Article extends BaseController
|
||||
{
|
||||
@ -43,7 +46,6 @@ class Article extends BaseController
|
||||
//分类列表
|
||||
$article = new ArticleModel();
|
||||
$artList = $article->getCateList($ename,$type,$page);
|
||||
|
||||
// 热议文章
|
||||
$artHot = $article->getArtHot(10);
|
||||
//广告
|
||||
@ -52,7 +54,7 @@ class Article extends BaseController
|
||||
$ad_cateImg = $ad->getSliderList(3);
|
||||
//分类钻展赞助
|
||||
$ad_comm = $ad->getSliderList(6);
|
||||
|
||||
|
||||
View::assign(['type'=>$type,'artList'=>$artList,'artHot'=>$artHot,'ad_cateImg'=>$ad_cateImg,'ad_comm'=>$ad_comm,'jspage'=>'jie','ename'=>$ename,'path'=>$path]);
|
||||
return View::fetch('article/'.$tpl.'/cate');
|
||||
}
|
||||
@ -70,20 +72,55 @@ class Article extends BaseController
|
||||
//输出内容
|
||||
$page = input('page') ? input('page') : 1;
|
||||
$article = new ArticleModel();
|
||||
$artDetail = $article->getArtDetail($id,$page);
|
||||
// 设置tag内链
|
||||
$artDetail = $article->getArtDetail($id);
|
||||
//用户个人tag标签
|
||||
$userTags = $article->where(['user_id'=>$artDetail['user_id'],'status'=>1])->where('tags','<>','')->column('tags');
|
||||
//转换为字符串
|
||||
$tagStr = implode(",",$userTags);
|
||||
//转换为数组并去重
|
||||
$tagArr = array_unique(explode(",",$tagStr));
|
||||
$userTagCount = count($tagArr);
|
||||
|
||||
//赞列表
|
||||
$userZanList = [];
|
||||
$userZan = UserZan::where(['article_id'=>$id,'type'=>1])->select();
|
||||
foreach($userZan as $v){
|
||||
$userZanList[] = ['userImg'=>$v->user->user_img,'name'=>$v->user->name];
|
||||
}
|
||||
|
||||
// 设置内容的tag内链
|
||||
$artDetail['content'] = $this->setArtTagLink($artDetail['content']);
|
||||
|
||||
// tag
|
||||
$attr = explode(',', $artDetail['tags']);
|
||||
$tags = [];
|
||||
foreach($attr as $v){
|
||||
if ($v !='') {
|
||||
$tags[] = $v;
|
||||
}
|
||||
// $tags = [];
|
||||
// if(!is_null($artDetail['tags'])){
|
||||
// $attr = explode(',', $artDetail['tags']);
|
||||
// foreach($attr as $v){
|
||||
// if ($v !='') {
|
||||
// $tags[] = $v;
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// $tags[] = $artDetail['title'];
|
||||
// }
|
||||
|
||||
// $tag = new Tag();
|
||||
// $tags = $tag->getArtTag($artDetail['tags']);
|
||||
|
||||
$pinyin = new Pinyin();
|
||||
$tags = [];
|
||||
if(!is_null($artDetail['tags'])){
|
||||
$attr = explode(',', $artDetail['tags']);
|
||||
foreach($attr as $v){
|
||||
if ($v !='') {
|
||||
$tags[] = ['tag'=>$v,'pinyin'=>$pinyin->permalink($v,''), 'url'=> (string) url('tag_list',['tag'=>$pinyin->permalink($v,'')])];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$arId = $artDetail['cate_id'];
|
||||
$tpl = Db::name('cate')->where('id',$arId)->value('detpl');
|
||||
|
||||
|
||||
$tpl = Db::name('cate')->where('id', $artDetail['cate_id'])->value('detpl');
|
||||
$download = $artDetail['upzip'] ? download($artDetail['upzip'],'file') : '';
|
||||
|
||||
//$count = $comments->total();
|
||||
@ -95,7 +132,8 @@ class Article extends BaseController
|
||||
|
||||
//评论
|
||||
$comments = $this->getComments($id, $page);
|
||||
|
||||
//最新评论时间
|
||||
$lrDate_time = Db::name('comment')->where('article_id', $id)->max('update_time',false) ?? time();
|
||||
// 热议文章
|
||||
$artHot = $article->getArtHot(10);
|
||||
//广告
|
||||
@ -104,6 +142,7 @@ class Article extends BaseController
|
||||
$ad_artImg = $ad->getSliderList(4);
|
||||
//分类钻展赞助
|
||||
$ad_comm = $ad->getSliderList(7);
|
||||
//push
|
||||
$push_js = Db::name('push_jscode')->where(['delete_time'=>0])->cache(true)->select();
|
||||
|
||||
View::assign([
|
||||
@ -115,11 +154,15 @@ class Article extends BaseController
|
||||
'tags' => $tags,
|
||||
'page' => $page,
|
||||
'comments' => $comments,
|
||||
'jspage' => 'jie',
|
||||
'push_js' => $push_js,
|
||||
'cid' => $id,
|
||||
'lrDate_time' => $lrDate_time,
|
||||
'userZanList' => $userZanList,
|
||||
'userTagCount'=> $userTagCount,
|
||||
'jspage' => 'jie',
|
||||
$download,
|
||||
]);
|
||||
|
||||
|
||||
return View::fetch('article/'.$tpl.'/detail');
|
||||
}
|
||||
|
||||
@ -133,16 +176,20 @@ class Article extends BaseController
|
||||
//文章评论
|
||||
public function comment()
|
||||
{
|
||||
// 检验发帖是否开放
|
||||
if(config('taoler.config.is_reply') == 0 ) return json(['code'=>-1,'msg'=>'抱歉,系统维护中,暂时禁止评论!']);
|
||||
|
||||
if (Request::isAjax()){
|
||||
//获取评论
|
||||
$data = Request::only(['content','article_id','user_id']);
|
||||
$sendId = $data['user_id'];
|
||||
$art = Db::name('article')->field('id,status,is_reply,delete_time')->find($data['article_id']);
|
||||
|
||||
if($art['delete_time'] != 0 || $art['status'] != 1 || $art['is_reply'] != 1){
|
||||
return json(['code'=>-1, 'msg'=>'评论不可用状态']);
|
||||
}
|
||||
if(empty($data['content'])){
|
||||
return json(['code'=>0, 'msg'=>'评论不能为空!']);
|
||||
return json(['code'=>-1, 'msg'=>'评论不能为空!']);
|
||||
}
|
||||
$superAdmin = Db::name('user')->where('id',$sendId)->value('auth');
|
||||
$data['status'] = $superAdmin ? 1 : Config::get('taoler.config.commnets_check');
|
||||
@ -151,9 +198,12 @@ class Article extends BaseController
|
||||
//用户留言存入数据库
|
||||
if (Comment::create($data)) {
|
||||
//站内信
|
||||
$article = Db::name('article')->field('id,title,user_id')->where('id',$data['article_id'])->find();
|
||||
$article = Db::name('article')->field('id,title,user_id,cate_id')->where('id',$data['article_id'])->find();
|
||||
// 获取分类ename
|
||||
$cate_ename = Db::name('cate')->where('id',$article['cate_id'])->value('ename');
|
||||
$title = $article['title'];
|
||||
$link = (string) url('article/detail',['id'=>$data['article_id']]);
|
||||
//$link = (string) url('article_detail',['id'=>$data['article_id']]);
|
||||
$link = $this->getRouteUrl($data['article_id'], $cate_ename);
|
||||
|
||||
//评论中回复@user comment
|
||||
$preg = "/@([^@\s]*)\s/";
|
||||
@ -180,9 +230,12 @@ class Article extends BaseController
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
//dump(empty(config('taoler.baidu.client_id')));
|
||||
if (Request::isAjax()) {
|
||||
$data = Request::only(['cate_id', 'title', 'title_color', 'user_id', 'content', 'upzip', 'tags', 'description', 'captcha']);
|
||||
// 检验发帖是否开放
|
||||
if(config('taoler.config.is_post') == 0 ) return json(['code'=>-1,'msg'=>'抱歉,系统维护中,暂时禁止发帖!']);
|
||||
|
||||
$data = Request::only(['cate_id', 'title', 'title_color', 'user_id', 'tiny_content', 'content', 'upzip', 'tags', 'description', 'captcha']);
|
||||
|
||||
// 验证码
|
||||
if(Config::get('taoler.config.post_captcha') == 1)
|
||||
{
|
||||
@ -201,6 +254,8 @@ class Article extends BaseController
|
||||
// 获取内容图片音视频标识
|
||||
$iva= $this->hasIva($data['content']);
|
||||
$data = array_merge($data,$iva);
|
||||
// 获取分类ename
|
||||
$cate_ename = Db::name('cate')->where('id',$data['cate_id'])->value('ename');
|
||||
|
||||
$article = new ArticleModel();
|
||||
$result = $article->add($data);
|
||||
@ -211,25 +266,28 @@ class Article extends BaseController
|
||||
Cache::tag('tagArtDetail')->clear();
|
||||
// 发提醒邮件
|
||||
if(Config::get('taoler.config.email_notice')) mailto($this->showUser(1)['email'],'发帖审核通知','Hi亲爱的管理员:</br>用户'.$this->showUser($this->uid)['name'].'刚刚发表了 <b>'.$data['title'].'</b> 新的帖子,请尽快处理。');
|
||||
|
||||
if(Config::get('taoler.config.posts_check')){
|
||||
$link = (string)url('article/detail', ['id' => $aid]);
|
||||
}else{
|
||||
$link = (string)url('index/');
|
||||
}
|
||||
// 推送给百度收录接口
|
||||
if(empty(config('taoler.baidu.push_api'))) {
|
||||
$this->baiduPush($aid);
|
||||
}
|
||||
|
||||
$res = Msgres::success($result['msg'], $link);
|
||||
|
||||
$link = $this->getRouteUrl((int)$aid, $cate_ename);
|
||||
// 推送给百度收录接口
|
||||
$this->baiduPush($link);
|
||||
|
||||
$url = $result['data']['status'] ? $link : (string)url('index/');
|
||||
$res = Msgres::success($result['msg'], $url);
|
||||
} else {
|
||||
$res = Msgres::error('add_error');
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
View::assign(['jspage'=>'jie']);
|
||||
return View::fetch();
|
||||
$tpl = Db::name('cate')->where('ename', input('cate'))->value('detpl');
|
||||
$appName = $this->app->http->getName();
|
||||
$viewRoot = root_path() . config('view.view_dir_name') . DIRECTORY_SEPARATOR . $appName . DIRECTORY_SEPARATOR;
|
||||
$view = 'article' . DIRECTORY_SEPARATOR . $tpl . DIRECTORY_SEPARATOR . 'add.html';
|
||||
$vfile = $viewRoot . $view;
|
||||
$addTpl = is_file($vfile) ? $vfile : 'add';
|
||||
|
||||
return View::fetch($addTpl);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -268,11 +326,9 @@ class Article extends BaseController
|
||||
if($result == 1) {
|
||||
//删除原有缓存显示编辑后内容
|
||||
Cache::delete('article_'.$id);
|
||||
$link = (string) url('article/detail',['id'=> $id]);
|
||||
$link = $this->getRouteUrl((int) $id, $article->cate->ename);
|
||||
// 推送给百度收录接口
|
||||
if(empty(config('taoler.baidu.push_api'))) {
|
||||
$this->baiduPush($data['id']);
|
||||
}
|
||||
$this->baiduPush($link);
|
||||
$editRes = Msgres::success('edit_success',$link);
|
||||
} else {
|
||||
$editRes = Msgres::error($result);
|
||||
@ -282,16 +338,27 @@ class Article extends BaseController
|
||||
}
|
||||
// 查询标签
|
||||
$tag = $article->tags;
|
||||
$attr = explode(',',$tag);
|
||||
$tags = [];
|
||||
foreach($attr as $key => $v){
|
||||
if ($v !='') {
|
||||
$tags[] = $v;
|
||||
}
|
||||
if(!is_null($tag)) {
|
||||
$attr = explode(',',$tag);
|
||||
foreach($attr as $key => $v){
|
||||
if ($v !='') {
|
||||
$tags[] = $v;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
View::assign(['article'=>$article,'tags'=>$tags,'jspage'=>'jie']);
|
||||
return View::fetch();
|
||||
// 编辑多模板支持
|
||||
$tpl = Db::name('cate')->where('id', $article['cate_id'])->value('detpl');
|
||||
$appName = $this->app->http->getName();
|
||||
$viewRoot = root_path() . config('view.view_dir_name') . DIRECTORY_SEPARATOR . $appName . DIRECTORY_SEPARATOR;
|
||||
$view = 'article' . DIRECTORY_SEPARATOR . $tpl . DIRECTORY_SEPARATOR . 'edit.html';
|
||||
$vfile = $viewRoot . $view;
|
||||
$editTpl = is_file($vfile) ? $vfile : 'edit';
|
||||
|
||||
return View::fetch($editTpl);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -368,6 +435,33 @@ class Article extends BaseController
|
||||
return json(['code'=>0,'data'=>$description]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 标题调用百度关键词词条
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function getWordList()
|
||||
{
|
||||
$title = input('title');
|
||||
if(empty($title)) return json(['code'=>-1,'msg'=>'null']);
|
||||
$url = 'https://www.baidu.com/sugrec?prod=pc&from=pc_web&wd='.$title;
|
||||
//$result = Api::urlGet($url);
|
||||
$curl = curl_init();
|
||||
curl_setopt($curl, CURLOPT_URL, $url);
|
||||
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
|
||||
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
|
||||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
|
||||
$datas = curl_exec($curl);
|
||||
curl_close($curl);
|
||||
$data = json_decode($datas,true);
|
||||
if(isset($data['g'])) {
|
||||
return json(['code'=>0,'msg'=>'success','data'=>$data['g']]);
|
||||
} else {
|
||||
return json(['code'=>-1,'msg'=>'null']);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 关键词
|
||||
*
|
||||
@ -415,9 +509,9 @@ class Article extends BaseController
|
||||
} else {
|
||||
// 接口正常但获取数据失败,可能参数错误,重新获取token
|
||||
$url = 'https://aip.baidubce.com/oauth/2.0/token';
|
||||
$post_data['grant_type'] = config('taoler.baidu.grant_type');;
|
||||
$post_data['grant_type'] = config('taoler.baidu.grant_type');;
|
||||
$post_data['client_id'] = config('taoler.baidu.client_id');
|
||||
$post_data['client_secret'] = config('taoler.baidu.client_secret');
|
||||
$post_data['client_secret'] = config('taoler.baidu.client_secret');
|
||||
|
||||
$o = "";
|
||||
foreach ( $post_data as $k => $v )
|
||||
@ -432,7 +526,8 @@ class Article extends BaseController
|
||||
'access_token' => json_decode($res)->access_token,
|
||||
]
|
||||
]);
|
||||
echo 'api接口数据错误,重新自动尝试链接';
|
||||
echo 'api接口数据错误 - ';
|
||||
echo $dataItem->error_msg;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -471,8 +566,9 @@ class Article extends BaseController
|
||||
return $data;
|
||||
}
|
||||
|
||||
//文章置顶,状态
|
||||
public function jieset(){
|
||||
// 文章置顶、加精、评论状态
|
||||
public function jieset()
|
||||
{
|
||||
$data = Request::param();
|
||||
$article = ArticleModel::field('id,is_top,is_hot,is_reply')->find($data['id']);
|
||||
switch ($data['field']){
|
||||
@ -482,22 +578,22 @@ class Article extends BaseController
|
||||
$res = ['status'=>0,'msg'=>'置顶成功'];
|
||||
} else {
|
||||
$article->save(['is_top' => 0]);
|
||||
$res = ['status'=>0,'msg'=>'已取消置顶'];
|
||||
$res = ['status'=>0,'msg'=>'置顶已取消'];
|
||||
}
|
||||
break;
|
||||
case 'hot':
|
||||
if($data['rank']==1){
|
||||
$article->save(['is_hot' => 1]);
|
||||
$res = ['status'=>0,'msg'=>'已设精贴'];
|
||||
$res = ['status'=>0,'msg'=>'加精成功'];
|
||||
} else {
|
||||
$article->save(['is_hot' => 0]);
|
||||
$res = ['status'=>0,'msg'=>'精贴已取消'];
|
||||
$res = ['status'=>0,'msg'=>'加精已取消'];
|
||||
}
|
||||
break;
|
||||
case 'reply':
|
||||
if($data['rank']==1){
|
||||
$article->save(['is_reply' => 1]);
|
||||
$res = ['status'=>0,'msg'=>'本帖禁评'];
|
||||
$res = ['status'=>0,'msg'=>'禁评成功'];
|
||||
} else {
|
||||
$article->save(['is_reply' => 0]);
|
||||
$res = ['status'=>0,'msg'=>'禁评已取消'];
|
||||
@ -510,7 +606,7 @@ class Article extends BaseController
|
||||
return json($res);
|
||||
}
|
||||
|
||||
//改变标题颜色
|
||||
// 改变标题颜色
|
||||
public function titleColor()
|
||||
{
|
||||
$data = Request::param();
|
||||
@ -555,33 +651,64 @@ class Article extends BaseController
|
||||
foreach($tag as $key=>$value) {
|
||||
// 匹配所有
|
||||
//$content = str_replace("$key", 'a('.$value.')['.$key.']',$content);
|
||||
// 限定匹配数量
|
||||
$content = preg_replace('/'.$key.'/','a('.$value.')['.$key.']',$content,2);
|
||||
// 限定匹配数量 '/'.$key.'/'
|
||||
// 匹配不包含[和]的内容
|
||||
$pats = '/(?<!\[)'.$key.'(?!\])/';
|
||||
//preg_match($pats,$content,$arr);
|
||||
//halt($arr[0]);
|
||||
// 开启和关闭编辑器使用不同的链接方式
|
||||
$rpes = hook('taonystatus') ? '<a href="'.$value.'" target="_blank" title="'.$key.'" style="font-weight: bold;color:#31BDEC">'.$key.'</a>' : 'a('.$value.')['.$key.']';
|
||||
|
||||
$content = preg_replace($pats,$rpes,$content,2);
|
||||
}
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
// baidu push api
|
||||
protected function baiduPush($id)
|
||||
/**
|
||||
* baidu push api
|
||||
*
|
||||
* @param string $link
|
||||
* @return void
|
||||
*/
|
||||
protected function baiduPush(string $link)
|
||||
{
|
||||
// baidu 接口
|
||||
$api = config('taoler.baidu.push_api');
|
||||
$artUrl = $this->getRouteUrl((int)$id);
|
||||
$url = [$artUrl];
|
||||
$ch = curl_init();
|
||||
$options = array(
|
||||
CURLOPT_URL => $api,
|
||||
CURLOPT_POST => true,
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_POSTFIELDS => implode("\n", $url),
|
||||
CURLOPT_HTTPHEADER => array('Content-Type: text/plain'),
|
||||
);
|
||||
curl_setopt_array($ch, $options);
|
||||
curl_exec($ch);
|
||||
curl_close($ch);
|
||||
if(!empty($api)) {
|
||||
$url[] = $link;
|
||||
$ch = curl_init();
|
||||
$options = array(
|
||||
CURLOPT_URL => $api,
|
||||
CURLOPT_POST => true,
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_POSTFIELDS => implode("\n", $url),
|
||||
CURLOPT_HTTPHEADER => array('Content-Type: text/plain'),
|
||||
);
|
||||
curl_setopt_array($ch, $options);
|
||||
curl_exec($ch);
|
||||
curl_close($ch);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function userZanArticle()
|
||||
{
|
||||
//
|
||||
if(Request::isPost()) {
|
||||
$data = Request::post();
|
||||
$data['user_id'] = $this->uid;
|
||||
$userZan = Db::name('user_zan')->where(['user_id'=>$this->uid,'article_id'=>$data['article_id']])->find();
|
||||
if($userZan){
|
||||
return json(['code'=> -1, 'msg'=>'您已赞过了哦']);
|
||||
}
|
||||
$res = Db::name('user_zan')->insert($data);
|
||||
if($res) {
|
||||
return json(['code'=> 0, 'msg'=>'点赞成功']);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,8 +1,16 @@
|
||||
<?php
|
||||
/*
|
||||
* @Author: TaoLer <317927823@qq.com>
|
||||
* @Date: 2021-12-06 16:04:50
|
||||
* @LastEditTime: 2022-07-27 09:14:12
|
||||
* @LastEditors: TaoLer
|
||||
* @Description: 首页优化版
|
||||
* @FilePath: \github\TaoLer\app\index\controller\Index.php
|
||||
* Copyright (c) 2020~2022 https://www.aieok.com All rights reserved.
|
||||
*/
|
||||
namespace app\index\controller;
|
||||
|
||||
use app\common\controller\BaseController;
|
||||
use think\App;
|
||||
use think\facade\View;
|
||||
use think\facade\Request;
|
||||
use think\facade\Db;
|
||||
@ -25,21 +33,21 @@ class Index extends BaseController
|
||||
|
||||
$slider = new Slider();
|
||||
//幻灯
|
||||
$sliders = $slider->getSliderList(1);
|
||||
$sliders = Request::isMobile() ? $slider->getSliderList(12) : $slider->getSliderList(1);
|
||||
//置顶文章
|
||||
$artTop = Article::getArtTop(5);
|
||||
//首页文章列表,显示20个
|
||||
$artList = Article::getArtList(22);
|
||||
//热议文章
|
||||
$artHot = Article::getArtHot(10);
|
||||
//首页广告
|
||||
$indexAd = $slider->getSliderList(13);
|
||||
//温馨通道
|
||||
$fast_links = $slider->getSliderList(8);
|
||||
//首页赞助
|
||||
$ad_index = $slider->getSliderList(5);
|
||||
//首页右栏图片
|
||||
$ad_comm = $slider->getSliderList(2);
|
||||
//友情链接
|
||||
$friend_links = $slider->getSliderList(9);
|
||||
|
||||
//友情链接申请
|
||||
$adminEmail = Db::name('user')->where('id',1)->cache(true)->value('email');
|
||||
@ -49,11 +57,11 @@ class Index extends BaseController
|
||||
'artTop' => $artTop,
|
||||
'artList' => $artList,
|
||||
'artHot' => $artHot,
|
||||
'ad_index_r'=> $indexAd,
|
||||
'type' => $types,
|
||||
'ad_index' => $ad_index,
|
||||
'ad_comm' => $ad_comm,
|
||||
'fastlinks' => $fast_links,
|
||||
'flinks' => $friend_links,
|
||||
'adminEmail' => $adminEmail,
|
||||
'jspage' => '',
|
||||
];
|
||||
@ -69,34 +77,6 @@ class Index extends BaseController
|
||||
return $comment->reply(20);
|
||||
}
|
||||
|
||||
//搜索功能
|
||||
public function search()
|
||||
{
|
||||
//$t = input('keywords');
|
||||
//halt($t);
|
||||
$ser = Request::only(['keywords']);
|
||||
|
||||
$search = new \app\index\controller\Search();
|
||||
$artList = $search->getSearch($ser['keywords']);
|
||||
$counts = $artList->count();
|
||||
$slider = new Slider();
|
||||
//首页右栏
|
||||
$ad_comm = $slider->getSliderList(2);
|
||||
// 查询热议
|
||||
$artHot = Article::getArtHot(10);
|
||||
|
||||
$searchs = [
|
||||
'artList' => $artList,
|
||||
'keywords' => $ser['keywords'],
|
||||
'counts' => $counts,
|
||||
'ad_comm'=>$ad_comm,
|
||||
'artHot'=>$artHot,
|
||||
'jspage'=>''
|
||||
];
|
||||
View::assign($searchs);
|
||||
return View::fetch('search');
|
||||
}
|
||||
|
||||
public function jump()
|
||||
{
|
||||
$username = Request::param('username');
|
||||
|
@ -38,7 +38,8 @@ class Login extends BaseController
|
||||
//获取登录前访问页面refer
|
||||
$refer = Request::server('HTTP_REFERER');
|
||||
if(Request::isAjax()) {
|
||||
|
||||
// 检验登录是否开放
|
||||
if(config('taoler.config.is_login') == 0 ) return json(['code'=>-1,'msg'=>'抱歉,网站维护中,暂时不能登录哦!']);
|
||||
//登陆前数据校验
|
||||
$data = Request::param();
|
||||
if(Config::get('taoler.config.login_captcha') == 1)
|
||||
@ -94,8 +95,31 @@ class Login extends BaseController
|
||||
//注册
|
||||
public function reg()
|
||||
{
|
||||
|
||||
if(Request::isAjax()){
|
||||
$data = Request::only(['name','email','password','repassword','captcha']);
|
||||
// 检验注册是否开放
|
||||
if(config('taoler.config.is_regist') == 0 ) return json(['code'=>-1,'msg'=>'抱歉,注册暂时未开放']);
|
||||
|
||||
$data = Request::only(['name','email','email_code','password','repassword','captcha']);
|
||||
|
||||
if(Config::get('taoler.config.regist_type') == 1) {
|
||||
//先校验验证码
|
||||
if(!captcha_check($data['captcha'])){
|
||||
// 验证失败
|
||||
return json(['code'=>-1,'msg'=> '验证码失败']);
|
||||
};
|
||||
}
|
||||
if(Config::get('taoler.config.regist_type') == 2) {
|
||||
$emailCode = Cache::get($data['email']);
|
||||
if($emailCode) {
|
||||
if($data['email_code'] != $emailCode) {
|
||||
// 验证失败
|
||||
return json(['code' => -1,'msg' => '验证码不正确']);
|
||||
}
|
||||
} else {
|
||||
return json(['code' => -1,'msg' => '验证码过期,请重试']);
|
||||
}
|
||||
}
|
||||
|
||||
//校验场景中reg的方法数据
|
||||
try{
|
||||
@ -203,12 +227,35 @@ class Login extends BaseController
|
||||
$user = new User();
|
||||
$res = $user->respass($data);
|
||||
if ($res == 1) {
|
||||
return json(['code'=>0,'msg'=>'修改成功','url'=>(string) url('login/index')]);
|
||||
return json(['code'=> 0, 'msg'=> '修改成功', 'url'=>(string) url('login/index')]);
|
||||
} else {
|
||||
return json(['code'=>-1,'msg'=>'$res']);
|
||||
return json(['code'=> -1, 'msg'=> '$res']);
|
||||
}
|
||||
}
|
||||
return View::fetch('forget');
|
||||
}
|
||||
|
||||
// 邮箱注册验证
|
||||
public function sentMailCode()
|
||||
{
|
||||
if(Request::isAjax()) {
|
||||
// 用户邮箱
|
||||
$email = input('email');
|
||||
//dump($email);
|
||||
if(empty($email)) return json(['code'=>-1,'msg'=>'邮箱不能为空']);
|
||||
|
||||
$code = mt_rand('1111','9999');
|
||||
Cache::set($email, $code, 600);
|
||||
|
||||
$result = mailto($email,'注册邮箱验证码','Hi亲爱的新用户:</br>您正在注册我们站点的新账户,请在10分钟内验证,您的验证码为:'.$code);
|
||||
if($result == 1) {
|
||||
$res = ['code' => 0, 'msg' => '验证码已发送成功,请去邮箱查看!'];
|
||||
} else {
|
||||
$res = ['code' => -1, 'msg' => $result];
|
||||
}
|
||||
return json($res);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,4 +1,13 @@
|
||||
<?php
|
||||
/*
|
||||
* @Author: TaoLer <317927823@qq.com>
|
||||
* @Date: 2021-12-06 16:04:50
|
||||
* @LastEditTime: 2022-07-27 21:29:43
|
||||
* @LastEditors: TaoLer
|
||||
* @Description: 优化版
|
||||
* @FilePath: \github\TaoLer\app\index\controller\Message.php
|
||||
* Copyright (c) 2020~2022 https://www.aieok.com All rights reserved.
|
||||
*/
|
||||
namespace app\index\controller;
|
||||
|
||||
use app\common\controller\BaseController;
|
||||
@ -14,13 +23,12 @@ class Message extends BaseController
|
||||
//消息数目
|
||||
public function nums()
|
||||
{
|
||||
$msg = Db::name('message_to')->where('receve_id',Session::get('user_id'))->where(['is_read'=>0,'delete_time'=>0])->select();
|
||||
|
||||
$count = $msg->count();
|
||||
if($count){
|
||||
$res=['status' =>0,'count' => $count, 'msg' => 'nums'];
|
||||
$messgeto = new MessageTo();
|
||||
$num = $messgeto->getMsgNum($this->uid);
|
||||
if(!is_null($num)){
|
||||
$res = ['status' =>0,'count' => $num, 'msg' => 'ok'];
|
||||
} else {
|
||||
$res=['status' =>0,'count' => 0, 'msg' => $count];
|
||||
$res = ['status' =>-1,'count' => 0, 'msg' => 'message error'];
|
||||
}
|
||||
return json($res);
|
||||
}
|
||||
@ -28,8 +36,7 @@ class Message extends BaseController
|
||||
//消息查询
|
||||
public function find()
|
||||
{
|
||||
$uid = Session::get('user_id');
|
||||
$msg = MessageApi::receveMsg($uid);
|
||||
$msg = MessageApi::receveMsg($this->uid);
|
||||
$count = $msg->count();
|
||||
$res = [];
|
||||
if($count){
|
||||
@ -39,7 +46,7 @@ class Message extends BaseController
|
||||
$res['rows'][] = $data;
|
||||
}
|
||||
} else {
|
||||
$res = ['status'=>0,'msg'=>'','rows'=>''];;
|
||||
$res = ['status'=>-1,'msg'=>'message find error','rows'=>''];;
|
||||
}
|
||||
//var_dump($res);
|
||||
return json($res);
|
||||
@ -62,7 +69,7 @@ class Message extends BaseController
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return json(['status' =>0]);
|
||||
return json(['status' =>0, 'url'=>(string) url('User/message')]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,23 +1,45 @@
|
||||
<?php
|
||||
/*
|
||||
* @Author: TaoLer <317927823@qq.com>
|
||||
* @Date: 2021-12-06 16:04:50
|
||||
* @LastEditTime: 2022-07-20 13:21:54
|
||||
* @LastEditors: TaoLer
|
||||
* @Description: 优化版
|
||||
* @FilePath: \TaoLer\app\index\controller\Search.php
|
||||
* Copyright (c) 2020~2022 https://www.aieok.com All rights reserved.
|
||||
*/
|
||||
|
||||
namespace app\index\controller;
|
||||
|
||||
use app\common\model\Article;
|
||||
use app\common\controller\BaseController;
|
||||
use think\facade\View;
|
||||
use think\facade\Request;
|
||||
use app\facade\Article;
|
||||
use app\common\model\Slider;
|
||||
|
||||
class Search
|
||||
class Search extends BaseController
|
||||
{
|
||||
public function getSearch(string $keywords)
|
||||
{
|
||||
//全局查询条件
|
||||
$map = []; //所有的查询条件封装到数组中
|
||||
//条件1:
|
||||
$map[] = ['status','=',1]; //这里等号不能省略
|
||||
//搜索功能
|
||||
public function getSearch()
|
||||
{
|
||||
$ser = Request::only(['keywords']);
|
||||
$artList = Article::getSearchKeyWord($ser['keywords']);
|
||||
$counts = $artList->count();
|
||||
$slider = new Slider();
|
||||
//首页右栏
|
||||
$ad_comm = $slider->getSliderList(2);
|
||||
// 查询热议
|
||||
$artHot = Article::getArtHot(10);
|
||||
|
||||
if(!empty($keywords)){
|
||||
//条件2
|
||||
$map[] = ['title','like','%'.$keywords.'%'];
|
||||
$res = Article::where($map)->withCount('comments')->order('create_time','desc')->paginate(10);
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
$searchs = [
|
||||
'artList' => $artList,
|
||||
'keywords' => $ser['keywords'],
|
||||
'counts' => $counts,
|
||||
'ad_comm'=>$ad_comm,
|
||||
'artHot'=>$artHot,
|
||||
'jspage'=>''
|
||||
];
|
||||
View::assign($searchs);
|
||||
return View::fetch('search');
|
||||
}
|
||||
}
|
@ -64,7 +64,7 @@ class Sign extends BaseController
|
||||
*/
|
||||
public function status()
|
||||
{
|
||||
if(session('user_id')){
|
||||
if($this->uid){
|
||||
$res = $this->todayData()->getData();
|
||||
|
||||
if($res['is_sign'] == 1){
|
||||
|
86
app/index/controller/Tag.php
Normal file
86
app/index/controller/Tag.php
Normal file
@ -0,0 +1,86 @@
|
||||
<?php
|
||||
/*
|
||||
* @Author: TaoLer <317927823@qq.com>
|
||||
* @Date: 2022-07-24 15:58:51
|
||||
* @LastEditTime: 2022-07-24 21:28:52
|
||||
* @LastEditors: TaoLer
|
||||
* @Description: Tag优化版
|
||||
* @FilePath: \TaoLer\app\index\controller\Tag.php
|
||||
* Copyright (c) 2020~2022 https://www.aieok.com All rights reserved.
|
||||
*/
|
||||
namespace app\index\controller;
|
||||
|
||||
use app\common\controller\BaseController;
|
||||
use app\facade\Article;
|
||||
use think\cache\driver\Redis;
|
||||
use think\facade\View;
|
||||
use think\facade\Request;
|
||||
use think\facade\Db;
|
||||
use app\common\model\Slider;
|
||||
use Overtrue\Pinyin\Pinyin;
|
||||
|
||||
class Tag extends BaseController
|
||||
{
|
||||
//
|
||||
public function index()
|
||||
{
|
||||
return View::fetch();
|
||||
}
|
||||
|
||||
// 获取tag列表
|
||||
public function List()
|
||||
{
|
||||
//
|
||||
$tag = Request::param('tag');
|
||||
|
||||
$artList = Article::getAllTags($tag);
|
||||
|
||||
$slider = new Slider();
|
||||
//首页右栏
|
||||
$ad_comm = $slider->getSliderList(2);
|
||||
// 查询热议
|
||||
$artHot = Article::getArtHot(10);
|
||||
|
||||
$assign = [
|
||||
'tag'=>$tag,
|
||||
'artList'=>$artList,
|
||||
'ad_comm'=>$ad_comm,
|
||||
'artHot'=>$artHot,
|
||||
'jspage'=>''
|
||||
];
|
||||
View::assign($assign);
|
||||
return View::fetch('index');
|
||||
//halt($tag);
|
||||
}
|
||||
|
||||
//获取文章的tag
|
||||
public function getArtTag($tag)
|
||||
{
|
||||
//
|
||||
$pinyin = new Pinyin();
|
||||
$tags = [];
|
||||
if(!is_null($tag)){
|
||||
$attr = explode(',', $tag);
|
||||
foreach($attr as $v){
|
||||
if ($v !='') {
|
||||
$tags[] = ['tag'=>$v, 'url'=> (string) url('tag_list',['tag'=>$pinyin->permalink($v,'')])];
|
||||
}
|
||||
}
|
||||
}
|
||||
return $tags;
|
||||
}
|
||||
|
||||
//获取热门tag
|
||||
public function getHotTag()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
//获取tag链接
|
||||
public function setTagUrl()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ use think\facade\View;
|
||||
use app\common\model\Article;
|
||||
use app\common\model\Collection;
|
||||
use app\common\model\User as userModel;
|
||||
use think\facade\Config;
|
||||
use app\common\model\Comment;
|
||||
use taoler\com\Message;
|
||||
|
||||
class User extends BaseController
|
||||
@ -29,11 +29,10 @@ class User extends BaseController
|
||||
}
|
||||
|
||||
|
||||
//发帖list
|
||||
// 发帖list
|
||||
public function artList()
|
||||
{
|
||||
$article = Article::withCount('comments')->where(['user_id'=>$this->uid])->order('update_time','desc')->paginate(10);
|
||||
//var_dump($article);
|
||||
$count = $article->total();
|
||||
$res = [];
|
||||
if($count){
|
||||
@ -43,6 +42,7 @@ class User extends BaseController
|
||||
$res['data'][] = ['id'=>$v['id'],
|
||||
'title' => htmlspecialchars($v['title']),
|
||||
'url' => (string) url('article/detail',['id'=>$v['id']]),
|
||||
'url' => $this->getRouteUrl($v['id'], $v->cate->ename),
|
||||
'status' => $v['status'] ? '正常':'待审核',
|
||||
'ctime' => $v['create_time'],
|
||||
'datas' => $v['pv'].'阅/'.$v['comments_count'].'答'
|
||||
@ -55,8 +55,9 @@ class User extends BaseController
|
||||
return json($res);
|
||||
}
|
||||
|
||||
//收藏list
|
||||
public function collList(){
|
||||
// 收藏list
|
||||
public function collList()
|
||||
{
|
||||
//收藏的帖子
|
||||
$collect = Collection::with(['article'=>function($query){
|
||||
$query->withCount('comments')->where('status',1);
|
||||
@ -71,7 +72,7 @@ class User extends BaseController
|
||||
$res['data'][] = [
|
||||
'id' =>$v['id'],
|
||||
'title' => htmlspecialchars($v['collect_title']),
|
||||
'url' => (string) url('article/detail',['id'=>$v['article_id']]),
|
||||
'url' => $this->getRouteUrl($v['article_id'], $v->article->cate->ename),
|
||||
'auther' => $v['auther'],
|
||||
'status' => is_null(Db::name('article')->field('id')->where('delete_time',0)->find($v['article_id'])) ? '已失效' : '正常',
|
||||
'ctime' => $v['create_time']
|
||||
@ -112,6 +113,15 @@ class User extends BaseController
|
||||
{
|
||||
if(Request::isAjax()){
|
||||
$data = Request::only(['user_id','email','nickname','sex','city','area_id','sign']);
|
||||
// 过滤
|
||||
$sign = strtolower($data['sign']);
|
||||
if(strstr($sign, 'script')) return json(['code'=>-1,'msg'=>'包含有非法字符串script脚本']);
|
||||
if(strstr($sign, 'alert')) return json(['code'=>-1,'msg'=>'包含有非法字符alert']);
|
||||
if(strstr($sign, 'img')) return json(['code'=>-1,'msg'=>'禁用img标签']);
|
||||
if(strstr($sign, 'body')) return json(['code'=>-1,'msg'=>'禁用img标签']);
|
||||
if(strstr($sign, 'video')) return json(['code'=>-1,'msg'=>'禁用video标签']);
|
||||
|
||||
// 验证
|
||||
$validate = new userValidate;
|
||||
$result = $validate->scene('Set')->check($data);
|
||||
if(!$result){
|
||||
@ -131,7 +141,7 @@ class User extends BaseController
|
||||
$result = $user->setNew($data);
|
||||
if($result == 1){
|
||||
Cache::tag('user')->clear();
|
||||
return ['code'=>0,'msg'=>'资料更新成功'];
|
||||
return json(['code'=>0,'msg'=>'资料更新成功']);
|
||||
} else {
|
||||
$this->error($result);
|
||||
}
|
||||
@ -167,14 +177,14 @@ class User extends BaseController
|
||||
->update(['user_img'=>$name_path]);
|
||||
Cache::tag(['user','tagArtDetail','tagArt'])->clear();
|
||||
if($result) {
|
||||
$res = ['status'=>0,'msg'=>'头像更新成功'];
|
||||
$res = ['code'=>0,'msg'=>'头像更新成功'];
|
||||
} else {
|
||||
$res = ['status'=>1,'msg'=>'头像更新失败'];
|
||||
$res = ['code'=>1,'msg'=>'头像更新失败'];
|
||||
}
|
||||
} else {
|
||||
$res = ['status'=>1,'msg'=>'上传错误'];
|
||||
$res = ['code'=>1,'msg'=>'上传错误'];
|
||||
}
|
||||
return json($res);
|
||||
return json($res);
|
||||
}
|
||||
|
||||
|
||||
@ -196,11 +206,21 @@ class User extends BaseController
|
||||
$u = Db::name('user')->field('name,nickname,city,sex,sign,user_img,point,vip,create_time')->cache(3600)->find($id);
|
||||
}
|
||||
|
||||
|
||||
//用户发贴
|
||||
$arts = Db::name('user')->alias('u')->join('article a','u.id = a.user_id')->field('u.id,a.id,a.title,a.pv,a.is_hot,a.create_time,a.delete_time,a.status')->where(['a.delete_time'=>0,'a.status'=>1])->where('a.user_id',$id)->order(['a.create_time'=>'desc'])->cache(3600)->select();
|
||||
$article = new Article();
|
||||
$commont = new Comment();
|
||||
$arts = $article->getUserArtList((int) $id);
|
||||
|
||||
// $reys = $commont->getUserCommentList((int) $id);
|
||||
// dump($reys);
|
||||
//用户回答
|
||||
$reys = Db::name('comment')->alias('c')->join('article a','c.article_id = a.id')->field('a.id,a.title,c.content,c.create_time,c.delete_time,c.status')->where(['a.delete_time'=>0,'c.delete_time'=>0,'c.status'=>1])->where('c.user_id',$id)->order(['c.create_time'=>'desc'])->cache(3600)->select();
|
||||
$reys = Db::name('comment')
|
||||
->alias('c')
|
||||
->join('article a','c.article_id = a.id')
|
||||
->field('a.id,a.title,c.content,c.create_time,c.delete_time,c.status')
|
||||
->where(['a.delete_time'=>0,'c.delete_time'=>0,'c.status'=>1])
|
||||
->where('c.user_id',$id)
|
||||
->order(['c.create_time'=>'desc'])
|
||||
->cache(3600)->select();
|
||||
|
||||
View::assign(['u'=>$u,'arts'=>$arts,'reys'=>$reys,'jspage'=>'']);
|
||||
return View::fetch();
|
||||
|
@ -67,9 +67,9 @@ return [
|
||||
'go sign' => '去签到',
|
||||
'more post' => '更多帖子',
|
||||
'friendly link' => '友情链接',
|
||||
'reviewers list' => '回帖热榜',
|
||||
'reviewers list' => '活跃榜',
|
||||
'hot post list' => '本周热议',
|
||||
'links list' => '温馨通道',
|
||||
'links list' => '快捷导航',
|
||||
'statement' => '说明',
|
||||
'trends' => '动态',
|
||||
'sponsor' => '钻级赞助商',
|
||||
@ -105,7 +105,7 @@ return [
|
||||
'submit' => '提交',
|
||||
'go back' => '返回',
|
||||
'register now' => '立即注册',
|
||||
'mail/username' => '邮箱/用户名',
|
||||
'mail/username/mobile' => '邮箱/用户名/手机号',
|
||||
'6-16 characters' => '6-16 字符',
|
||||
'strong type encryption' => '经过强类型加密',
|
||||
'it cannot be changed' => '不能更改',
|
||||
|
@ -2,11 +2,11 @@
|
||||
/*
|
||||
* @Author: TaoLer <alipey_tao@qq.com>
|
||||
* @Date: 2021-12-06 16:04:50
|
||||
* @LastEditTime: 2022-04-22 16:25:14
|
||||
* @LastEditTime: 2022-07-26 13:58:17
|
||||
* @LastEditors: TaoLer
|
||||
* @Description: 搜索引擎SEO优化设置
|
||||
* @FilePath: \TaoLer\app\index\route\route.php
|
||||
* Copyright (c) 2020~2022 http://www.aieok.com All rights reserved.
|
||||
* @Description: 前端路由设置
|
||||
* @FilePath: \github\TaoLer\app\index\route\route.php
|
||||
* Copyright (c) 2020~2022 https://www.aieok.com All rights reserved.
|
||||
*/
|
||||
use think\facade\Route;
|
||||
|
||||
@ -17,30 +17,58 @@ $cate_as = config('taoler.url_rewrite.cate_as');
|
||||
|
||||
Route::get('captcha/[:config]','\\think\\captcha\\CaptchaController@index');
|
||||
Route::rule('/', 'index'); // 首页访问路由
|
||||
|
||||
Route::get('index/reply','index/reply')->name('user_reply');
|
||||
Route::rule('search','Search/getSearch')->name('user_search');
|
||||
Route::get('message/nums','message/nums')->name('user_message');
|
||||
Route::get('tag/:tag', 'Tag/list')->name('tag_list');
|
||||
// 用户中心
|
||||
Route::group(function () {
|
||||
Route::get('u/:id$', 'user/home')->name('user_home');
|
||||
Route::get('user/index', 'user/index');
|
||||
Route::get('user/set', 'user/set');
|
||||
Route::get('user/message', 'user/message');
|
||||
Route::get('user/post', 'user/post');
|
||||
Route::get('user/article','user/artList');
|
||||
Route::get('user/coll','user/collList');
|
||||
Route::get('user/colldel','user/collDel');
|
||||
Route::get('user/setpass','user/setPass');
|
||||
Route::get('user/activate','user/activate');
|
||||
Route::get('user/active','user/active');
|
||||
Route::get('user/uploadHeadImg','user/uploadHeadImg');
|
||||
Route::get('logout', 'user/logout');
|
||||
});
|
||||
|
||||
// 登录注册
|
||||
Route::group(function () {
|
||||
Route::rule('login','login/index')->name('user_login');
|
||||
Route::rule('forget','login/forget')->name('user_forget');
|
||||
Route::rule('postcode','login/postcode');
|
||||
Route::rule('sentemailcode','login/sentMailCode');
|
||||
Route::rule('respass','login/respass');
|
||||
Route::rule('reg$','Login/reg')->name('user_reg')
|
||||
->middleware(\app\middleware\CheckRegister::class);
|
||||
});
|
||||
|
||||
|
||||
|
||||
// article
|
||||
Route::group(function () use($detail_as,$cate_as){
|
||||
Route::get("$detail_as<id>", 'article/detail');
|
||||
Route::get("$cate_as<ename>$",'article/cate')->name('cate');
|
||||
Route::get("$cate_as<ename>/<type>$", 'article/cate')->name('cate_type');
|
||||
Route::rule("$cate_as<ename>/<type>/<page>", 'article/cate')->name('cate_page');
|
||||
Route::rule('add','Article/add');
|
||||
Route::rule('add/[:cate]','Article/add')->name('add_article');
|
||||
Route::rule('delete/[:id]','Article/delete');
|
||||
Route::rule('tags','Article/tags')->allowCrossDomain();
|
||||
Route::rule('edit/[:id]','Article/edit');
|
||||
})->pattern([
|
||||
'ename' => '\w+',
|
||||
'type' => '\w+',
|
||||
'page' => '\d+',
|
||||
'id' => '\d+',
|
||||
]);
|
||||
// 动态路径路由会影响下面的路由,所以动态路由放下面
|
||||
Route::get($detail_as . ':id$', 'article/detail')->name('article_detail');
|
||||
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+',
|
||||
'type' => '\w+',
|
||||
'page' => '\d+',
|
||||
'id' => '\d+',
|
||||
]);
|
||||
|
||||
Route::group(function () {
|
||||
Route::rule('u/:id', 'user/home');
|
||||
});
|
||||
Route::rule('login','login/index');
|
||||
Route::rule('forget','login/forget');
|
||||
Route::rule('postcode','login/postcode');
|
||||
Route::rule('respass','login/respass');
|
||||
Route::rule('reg$','Login/reg')
|
||||
->middleware(\app\middleware\CheckRegister::class);
|
||||
|
||||
Route::rule('search/[:keywords]', 'index/search'); // 搜索
|
||||
|
@ -54,6 +54,7 @@ CREATE TABLE `tao_article` (
|
||||
`status` enum('0','-1','1') NOT NULL DEFAULT '1' COMMENT '状态1显示0待审-1禁止',
|
||||
`cate_id` int(11) NOT NULL COMMENT '分类id',
|
||||
`user_id` int(11) NOT NULL COMMENT '用户id',
|
||||
`goods_detail_id` int DEFAULT NULL COMMENT '商品ID',
|
||||
`is_top` enum('0','1') NOT NULL DEFAULT '0' COMMENT '置顶1否0',
|
||||
`is_hot` enum('0','1') NOT NULL DEFAULT '0' COMMENT '推荐1否0',
|
||||
`is_reply` enum('1','0') NOT NULL DEFAULT '1' COMMENT '0禁评1可评',
|
||||
@ -76,7 +77,7 @@ CREATE TABLE `tao_article` (
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `user_id` (`user_id`) USING BTREE COMMENT '文章的用户索引',
|
||||
KEY `cate_id` (`cate_id`) USING BTREE COMMENT '文章分类索引'
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of tao_article
|
||||
@ -141,7 +142,7 @@ CREATE TABLE `tao_auth_group_copy` (
|
||||
`update_time` int(11) NOT NULL DEFAULT '0' COMMENT '更新时间',
|
||||
`delete_time` int(11) NOT NULL DEFAULT '0' COMMENT '删除时间',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of tao_auth_group_copy
|
||||
@ -310,7 +311,7 @@ CREATE TABLE `tao_collection` (
|
||||
`create_time` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间',
|
||||
`delete_time` int(11) NOT NULL DEFAULT '0' COMMENT '删除时间',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=10 DEFAULT CHARSET=utf8 COMMENT='文章收藏表';
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='文章收藏表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for tao_comment
|
||||
@ -350,7 +351,7 @@ CREATE TABLE `tao_cunsult` (
|
||||
`create_time` int(10) NOT NULL DEFAULT '0' COMMENT '创建时间',
|
||||
`delete_time` int(10) NOT NULL DEFAULT '0' COMMENT '删除时间',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for tao_friend_link
|
||||
@ -460,7 +461,7 @@ CREATE TABLE `tao_slider` (
|
||||
`slid_name` varchar(30) NOT NULL COMMENT '幻灯名',
|
||||
`slid_type` tinyint(1) NOT NULL DEFAULT '1' COMMENT '类型',
|
||||
`slid_img` varchar(70) NOT NULL DEFAULT '' COMMENT '幻灯图片地址',
|
||||
`slid_href` varchar(70) NOT NULL DEFAULT '' COMMENT '链接',
|
||||
`slid_href` varchar(255) NOT NULL DEFAULT '' COMMENT '链接',
|
||||
`slid_color` varchar(10) NOT NULL DEFAULT '' COMMENT '广告块颜色',
|
||||
`slid_start` int(11) NOT NULL DEFAULT '0' COMMENT '开始时间',
|
||||
`slid_over` int(11) NOT NULL DEFAULT '0' COMMENT '结束时间',
|
||||
@ -488,12 +489,14 @@ CREATE TABLE `tao_system` (
|
||||
`domain` varchar(50) NOT NULL,
|
||||
`template` varchar(30) NOT NULL DEFAULT '' COMMENT '模板',
|
||||
`logo` varchar(70) NOT NULL DEFAULT '' COMMENT '网站logo',
|
||||
`m_logo` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '/static/res/images/logo-m.png' COMMENT '移动端logo',
|
||||
`cache` tinyint(5) NOT NULL DEFAULT '0' COMMENT '缓存时间分钟',
|
||||
`upsize` int(5) NOT NULL DEFAULT '0' COMMENT '上传文件大小KB',
|
||||
`uptype` varchar(255) NOT NULL DEFAULT '0' COMMENT '上传文件类型',
|
||||
`copyright` varchar(100) NOT NULL DEFAULT '' COMMENT '版权',
|
||||
`keywords` tinytext NOT NULL COMMENT '网站关键字',
|
||||
`descript` tinytext NOT NULL COMMENT '网站描述',
|
||||
`state` tinytext CHARACTER SET utf8 COLLATE utf8_general_ci COMMENT '网站声明',
|
||||
`is_open` enum('0','1') NOT NULL DEFAULT '1' COMMENT '是否开启站点1开启0关闭',
|
||||
`is_comment` enum('0','1') NOT NULL DEFAULT '1' COMMENT '是否开启评论1开启0关闭',
|
||||
`is_reg` enum('0','1') NOT NULL DEFAULT '1' COMMENT '是否开放注册1开启0禁止',
|
||||
@ -515,7 +518,7 @@ CREATE TABLE `tao_system` (
|
||||
-- ----------------------------
|
||||
-- Records of tao_system
|
||||
-- ----------------------------
|
||||
INSERT INTO `tao_system` VALUES ('1', 'TaoLer社区演示站', '轻论坛系统', 'http://www.xxx.com', 'taoler', '/storage/logo/logo.png', '10', '2048', 'image:png|gif|jpg|jpeg,application:zip|rar,video:mp4,audio:mp3|m4a|mp4', '<a href="https://www.aieok.com" target="_blank">TaoLer</a>', 'TaoLer,轻社区系统,bbs,论坛,Thinkphp6,layui,fly模板,', '这是一个Taoler轻社区论坛系统', '1', '1', '1', '0.0.0.0-1', '', '管理员|admin|审核员|超级|垃圾', '1.6.3', '','0', 'http://api.aieok.com', 'http://api.aieok.com/v1/cy', 'http://api.aieok.com/v1/upload/check', 'http://api.aieok.com/v1/upload/api', '1581221008', '1577419197');
|
||||
INSERT INTO `tao_system` VALUES (1, 'TaoLer', 'TaoLer社区-www.aieok.com', 'www.tp6.com', 'taoler', '/storage/logo/logo.png', '/static/res/images/logo-m.png', 10, 2048, 'image:png|gif|jpg|jpeg,application:zip|rar|docx,video:mp4,audio:mp3|m4a|mp4,zip:zip,application/msword:docx', '<a href=\"https://www.aieok.com\" target=\"_blank\">TaoLer</a>', 'TaoLer,轻社区系统,bbs,论坛,Thinkphp6,layui,fly模板,', '这是一个Taoler轻社区论坛系统', '网站声明:如果转载,请联系本站管理员。否则一切后果自行承担。', '1', '1', '1', '0.0.0.0-1', '', '管理员|admin|审核员|超级|垃圾', '1.6.3', '', 0, 'http://api.aieok.com', 'http://api.aieok.com/v1/cy', 'http://api.aieok.com/v1/upload/check', 'http://api.aieok.com/v1/upload/api', 1641004619, 1652345050);
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for tao_user
|
||||
@ -532,7 +535,7 @@ CREATE TABLE `tao_user` (
|
||||
`city` varchar(50) NOT NULL DEFAULT '' COMMENT '归属地',
|
||||
`sex` enum('0','1') NOT NULL DEFAULT '0' COMMENT '性别0男1女',
|
||||
`sign` varchar(255) NOT NULL DEFAULT '' COMMENT '签名',
|
||||
`user_img` varchar(70) NOT NULL DEFAULT '' COMMENT '头像',
|
||||
`user_img` varchar(150) NOT NULL DEFAULT '' COMMENT '头像',
|
||||
`auth` enum('1','0') NOT NULL DEFAULT '0' COMMENT '管理员权限0普通1超级',
|
||||
`point` int(11) NOT NULL DEFAULT '0' COMMENT '积分',
|
||||
`area_id` int(11) DEFAULT NULL COMMENT '用户所属区域ID',
|
||||
@ -648,12 +651,11 @@ INSERT INTO `tao_user_viprule` VALUES ('4', '501-699', '3', '土豪', '', '15855
|
||||
DROP TABLE IF EXISTS `tao_user_zan`;
|
||||
CREATE TABLE `tao_user_zan` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '点赞主键id',
|
||||
`article_id` int DEFAULT NULL COMMENT '文章id',
|
||||
`comment_id` int(11) NOT NULL COMMENT '评论id',
|
||||
`user_id` int(11) NOT NULL COMMENT '用户id',
|
||||
`type` tinyint NOT NULL DEFAULT '2' COMMENT '1文章点赞2评论点赞',
|
||||
`create_time` int(11) NOT NULL DEFAULT '0' COMMENT '点赞时间',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of tao_user_zan
|
||||
-- ----------------------------
|
||||
|
@ -1,3 +1,12 @@
|
||||
<!--
|
||||
* @Author: TaoLer <317927823@qq.com>
|
||||
* @Date: 2021-12-06 16:04:50
|
||||
* @LastEditTime: 2022-07-01 13:48:22
|
||||
* @LastEditors: TaoLer
|
||||
* @Description: 优化版
|
||||
* @FilePath: \TaoLer\app\install\view\index\agreement.html
|
||||
* Copyright (c) 2020~2022 https://www.aieok.com All rights reserved.
|
||||
-->
|
||||
{extend name="index/base" /}
|
||||
{block name="body"}
|
||||
<div class="inside2">
|
||||
@ -15,7 +24,7 @@
|
||||
<p>9、在理解、同意、并遵守本协议的全部条款后,方可开始使用本程序。本许可协议条款的解释,效力及纠纷的解决,适用于中华人民共和国大陆法律。</p>
|
||||
<p>10、您使用本系统,需要遵循许可协议,一旦安装表示您已接受该系统各项条款。</p>
|
||||
<div class="inout1">
|
||||
<a>拒绝安装</a>
|
||||
<a id="no-install">拒绝安装</a>
|
||||
</div>
|
||||
<div class="inout2">
|
||||
<a href="{:url('index/test')}">同意安装</a>
|
||||
@ -24,3 +33,19 @@
|
||||
</br>
|
||||
</div>
|
||||
{/block}
|
||||
{block name="script"}
|
||||
<script>
|
||||
// 关闭当前页
|
||||
$("#no-install").on('click',function(){
|
||||
var userAgent = navigator.userAgent;
|
||||
if (userAgent.indexOf("Firefox") != -1 || userAgent.indexOf("Chrome") != -1) {
|
||||
location.href = "about:blank";
|
||||
} else {
|
||||
window.opener = null;
|
||||
window.open('', '_self');
|
||||
}
|
||||
window.close();
|
||||
|
||||
});
|
||||
</script>
|
||||
{/block}
|
||||
|
@ -1,10 +1,17 @@
|
||||
<!--
|
||||
* @Author: TaoLer <317927823@qq.com>
|
||||
* @Date: 2021-12-06 16:04:50
|
||||
* @LastEditTime: 2022-07-01 13:44:37
|
||||
* @LastEditors: TaoLer
|
||||
* @Description: 安装引导程序优化版
|
||||
* @FilePath: \TaoLer\app\install\view\index\base.html
|
||||
* Copyright (c) 2020~2022 https://www.aieok.com All rights reserved.
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>TaoLer安装程序</title>
|
||||
<script type="text/javascript" src="/static/layui/jquery.min.js"></script>
|
||||
<link rel="stylesheet" href="/static/res/css/admin.css">
|
||||
<link rel="stylesheet" href="/static/layui/css/layui.css">
|
||||
<script src="/static/layui/layui.js"></script>
|
||||
@ -34,7 +41,10 @@
|
||||
</div>
|
||||
</div>
|
||||
{block name="body"}主题{/block}
|
||||
|
||||
<script>
|
||||
var $ = layui.jquery;
|
||||
var layer = layui.layer;
|
||||
</script>
|
||||
{block name="script"}{/block}
|
||||
</body>
|
||||
|
||||
</html>
|
@ -5,16 +5,13 @@
|
||||
<div class="inwp cl">
|
||||
<form class="layui-form layui-form-pane" >
|
||||
<h2>创建数据库:</h2>
|
||||
|
||||
<input type="hidden" name="DB_TYPE" value="mysql">
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">数据库服务器</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="DB_HOST" value="127.0.0.1" required lay-verify="required" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">数据库账号</label>
|
||||
<div class="layui-input-block">
|
||||
@ -91,49 +88,41 @@
|
||||
<input type="submit" lay-submit lay-filter="formDemo" value="确认安装">
|
||||
</div>
|
||||
</form>
|
||||
<script>
|
||||
layui.use('form', function() {
|
||||
var $ = layui.jquery,
|
||||
form = layui.form;
|
||||
|
||||
form.on('submit(formDemo)', function(data){
|
||||
var field = data.field;
|
||||
//console.log(field); //当前容器的全部表单字段,名值对形式:{name: value}
|
||||
loading = layer.load(2, {
|
||||
shade: [0.2, '#000'],
|
||||
time: 2000,
|
||||
});
|
||||
|
||||
$.ajax({
|
||||
type:"post",
|
||||
url:"{:url('index/install')}",
|
||||
data:{"DB_TYPE":field.DB_TYPE,"DB_HOST":field.DB_HOST,"DB_USER":field.DB_USER,"DB_PWD":field.DB_PWD,"DB_PORT":field.DB_PORT,"DB_NAME":field.DB_NAME,"DB_PREFIX":field.DB_PREFIX,"webname":field.webname,"webtitle":field.webtitle,"admin_user":field.admin_user,"admin_email":field.admin_email,"admin_pass":field.admin_pass,"admin_pass2":field.admin_pass2},
|
||||
daType:"json",
|
||||
success:function (data){
|
||||
if (data.code == 0) {
|
||||
layer.close(loading);
|
||||
layer.msg(data.msg,{
|
||||
icon:6,
|
||||
time:2000
|
||||
}, function(){
|
||||
location.href = data.url;
|
||||
});
|
||||
} else {
|
||||
layer.open({
|
||||
tiele:'安装失败',
|
||||
content:data.msg,
|
||||
icon:5,
|
||||
anim:6
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
return false; //阻止表单跳转。如果需要表单跳转,去掉这段即可。
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
{/block}
|
||||
{block name="script"}
|
||||
<script>
|
||||
layui.use('form', function() {
|
||||
var $ = layui.jquery,
|
||||
form = layui.form;
|
||||
|
||||
form.on('submit(formDemo)', function(data){
|
||||
var field = data.field;
|
||||
loading = layer.load(2, {
|
||||
shade: [0.2, '#000'],
|
||||
time: 2000,
|
||||
});
|
||||
|
||||
$.ajax({
|
||||
type:"post",
|
||||
url:"{:url('index/install')}",
|
||||
data:{"DB_TYPE":field.DB_TYPE,"DB_HOST":field.DB_HOST,"DB_USER":field.DB_USER,"DB_PWD":field.DB_PWD,"DB_PORT":field.DB_PORT,"DB_NAME":field.DB_NAME,"DB_PREFIX":field.DB_PREFIX,"webname":field.webname,"webtitle":field.webtitle,"admin_user":field.admin_user,"admin_email":field.admin_email,"admin_pass":field.admin_pass,"admin_pass2":field.admin_pass2},
|
||||
daType:"json",
|
||||
success:function (data){
|
||||
if (data.code == 0) {
|
||||
layer.close(loading);
|
||||
layer.msg(data.msg,{icon:6,time:2000}, function(){
|
||||
location.href = data.url;
|
||||
});
|
||||
} else {
|
||||
layer.open({tiele:'安装失败',content:data.msg,icon:5,anim:6});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return false; //阻止表单跳转。如果需要表单跳转,去掉这段即可。
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{/block}
|
@ -119,13 +119,16 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
function testClick() {
|
||||
if ($('.yes').length != 7) {
|
||||
alert('您的配置或权限不符合要求');
|
||||
} else {
|
||||
location.href = '{:url('index/create')}';
|
||||
}
|
||||
|
||||
{/block}
|
||||
{block name="script"}
|
||||
<script>
|
||||
function testClick() {
|
||||
if ($('.yes').length != 7) {
|
||||
alert('您的配置或权限不符合要求');
|
||||
} else {
|
||||
location.href = "{:url('index/create')}";
|
||||
}
|
||||
</script>
|
||||
}
|
||||
</script>
|
||||
{/block}
|
@ -1,15 +1,24 @@
|
||||
<!--
|
||||
* @Author: TaoLer <317927823@qq.com>
|
||||
* @Date: 2021-12-06 16:04:50
|
||||
* @LastEditTime: 2022-07-01 13:30:39
|
||||
* @LastEditors: TaoLer
|
||||
* @Description: 优化版
|
||||
* @FilePath: \TaoLer\app\install\view\success\complete.html
|
||||
* Copyright (c) 2020~2022 https://www.aieok.com All rights reserved.
|
||||
-->
|
||||
{extend name="index/base" /}
|
||||
{block name="body"}
|
||||
<div class="inside2">
|
||||
<div class="inwp cl">
|
||||
<h2>恭喜您安装成功</h2>
|
||||
{block name="body"}
|
||||
<div class="inside2">
|
||||
<div class="inwp cl">
|
||||
<h2>恭喜您安装成功</h2>
|
||||
|
||||
<div class="inout1">
|
||||
<a href="/" target="_blank">去前台首页</a>
|
||||
</div>
|
||||
<div class="inout2">
|
||||
<a href="/admin/login" target="_blank">去后台首页</a>
|
||||
</div>
|
||||
<div class="inout1">
|
||||
<a href="/" target="_blank">去前台首页</a>
|
||||
</div>
|
||||
<div class="inout2">
|
||||
<a href="/admin" target="_blank">去后台首页</a>
|
||||
</div>
|
||||
</div>
|
||||
{/block}
|
||||
</div>
|
||||
{/block}
|
@ -1,4 +1,13 @@
|
||||
<?php
|
||||
/*
|
||||
* @Author: TaoLer <alipay_tao@qq.com>
|
||||
* @Date: 2021-12-06 16:04:50
|
||||
* @LastEditTime: 2022-06-19 16:35:30
|
||||
* @LastEditors: TaoLer
|
||||
* @Description: 搜索引擎SEO优化设置
|
||||
* @FilePath: \TaoLer\app\listener\UserLogin.php
|
||||
* Copyright (c) 2020~2022 https://www.aieok.com All rights reserved.
|
||||
*/
|
||||
declare (strict_types = 1);
|
||||
|
||||
namespace app\listener;
|
||||
@ -7,6 +16,7 @@ use think\facade\Db;
|
||||
use think\facade\Log;
|
||||
use app\common\model\User;
|
||||
use think\facade\Lang;
|
||||
use taoler\com\Api;
|
||||
|
||||
class UserLogin
|
||||
{
|
||||
@ -25,21 +35,17 @@ class UserLogin
|
||||
if($type == 'log'){
|
||||
//$name = $user->user['name'];
|
||||
$ip = request()->ip();
|
||||
|
||||
/*
|
||||
$url = 'http://ip-api.com/json/'.$ip.'?lang=zh-CN';
|
||||
//$url = 'http://ip-api.com/json/?lang=zh-CN';
|
||||
$add = Api::urlGet($url);
|
||||
if($add->status == 'success'){
|
||||
$city = $add->city;
|
||||
} else {
|
||||
$city ='未知';
|
||||
}
|
||||
*/
|
||||
|
||||
$u->allowField(['last_login_ip','last_login_time','login_error_num'])->save(
|
||||
$url = 'http://ip-api.com/json/' . $ip . '?lang=zh-CN&fields=57361';
|
||||
$ipJson = Api::urlGet($url);
|
||||
if($ipJson->status == 'success'){
|
||||
$city = $ipJson->city;
|
||||
} else {
|
||||
$city ='未知';
|
||||
}
|
||||
|
||||
$u->allowField(['city','last_login_ip','last_login_time','login_error_num'])->save(
|
||||
[
|
||||
//'city' => $city,
|
||||
'city' => $city,
|
||||
'last_login_ip' => $ip,
|
||||
'last_login_time' => time(),
|
||||
'login_error_num' => 0
|
||||
|
@ -11,13 +11,15 @@ class CheckRegister
|
||||
//排除禁止注册用户名的字段
|
||||
if($request->action(true)=='reg'){
|
||||
$name = $request->param('name');
|
||||
$disname = Db::name('system')->where('id',1)->value('blackname');
|
||||
$data = explode("|",$disname);
|
||||
foreach($data as $v){
|
||||
if(stripos($name,$v) !== false){
|
||||
return json(['msg'=>'非法字段或该用户名禁止注册,请更换']);
|
||||
if(!is_null($name)) {
|
||||
$disname = Db::name('system')->where('id',1)->value('blackname');
|
||||
$data = explode("|",$disname);
|
||||
foreach($data as $v){
|
||||
if(stripos($name,$v) !== false){
|
||||
return json(['msg'=>'非法字段或该用户名禁止注册,请更换']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $next($request);
|
||||
}
|
||||
|
@ -30,7 +30,13 @@
|
||||
"taoser/think-addons": "^1.0",
|
||||
"liliuwei/thinkphp-social": "^1.3",
|
||||
"taoser/think-setarr": "^0.0.3",
|
||||
"topthink/think-migration": "^3.0"
|
||||
"topthink/think-migration": "^3.0",
|
||||
"workerman/workerman": "^4.0",
|
||||
"endroid/qr-code": "^4.4",
|
||||
"overtrue/pinyin": "^4.0",
|
||||
"yansongda/pay": "~3.1.0",
|
||||
"guzzlehttp/guzzle": "7.0",
|
||||
"php-di/php-di": "^6.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/var-dumper": "^4.2",
|
||||
|
1250
composer.lock
generated
1250
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@ -2,7 +2,7 @@
|
||||
/*
|
||||
* @Author: TaoLer <alipey_tao@qq.com>
|
||||
* @Date: 2021-12-06 16:04:50
|
||||
* @LastEditTime: 2022-04-21 20:56:48
|
||||
* @LastEditTime: 2022-07-03 04:21:02
|
||||
* @LastEditors: TaoLer
|
||||
* @Description: 搜索引擎SEO优化设置
|
||||
* @FilePath: \TaoLer\config\app.php
|
||||
@ -28,15 +28,17 @@ return [
|
||||
|
||||
// 应用映射(自动多应用模式有效)
|
||||
'app_map' => [
|
||||
//'bbs' => 'index'
|
||||
],
|
||||
// 域名绑定(自动多应用模式有效)
|
||||
'domain_bind' => [
|
||||
//'www' => 'index',
|
||||
//'adm' => 'admin'
|
||||
],
|
||||
// 禁止URL访问的应用列表(自动多应用模式有效)
|
||||
|
||||
// 异常页面的模板文件
|
||||
'exception_tmpl' => app()->getThinkPath() . 'tpl/think_exception.tpl',
|
||||
//'exception_tmpl' => app()->getAppPath() . '404.html',
|
||||
'exception_tmpl' => app()->getThinkPath() . 'tpl/think_exception.tpl',
|
||||
|
||||
// 错误显示信息,非调试模式有效
|
||||
'error_message' => '页面错误!请稍后再试~',
|
||||
|
@ -1,4 +1,13 @@
|
||||
<?php
|
||||
/*
|
||||
* @Author: TaoLer <317927823@qq.com>
|
||||
* @Date: 2021-12-06 16:04:50
|
||||
* @LastEditTime: 2022-07-24 09:57:31
|
||||
* @LastEditors: TaoLer
|
||||
* @Description: 文件存储优化版
|
||||
* @FilePath: \TaoLer\config\filesystem.php
|
||||
* Copyright (c) 2020~2022 https://www.aieok.com All rights reserved.
|
||||
*/
|
||||
|
||||
return [
|
||||
// 默认磁盘
|
||||
@ -19,6 +28,11 @@ return [
|
||||
// 可见性
|
||||
'visibility' => 'public',
|
||||
],
|
||||
'sys' => [
|
||||
'type' => 'local',
|
||||
'root' => app()->getRootPath() . 'public/sys',
|
||||
'url' => '/sys',
|
||||
],
|
||||
// 更多的磁盘配置信息
|
||||
],
|
||||
];
|
||||
|
@ -1,3 +1,5 @@
|
||||
<?php
|
||||
return [
|
||||
'一个' => 'http://www.bi.com',
|
||||
'描述' => 'http://ww.com',
|
||||
];
|
@ -1,12 +1,12 @@
|
||||
<?php
|
||||
/*
|
||||
* @Author: TaoLer <alipey_tao@qq.com>
|
||||
* @Author: TaoLer <alipay_tao@qq.com>
|
||||
* @Date: 2021-12-06 16:04:50
|
||||
* @LastEditTime: 2022-04-22 06:57:15
|
||||
* @LastEditTime: 2022-06-27 13:14:46
|
||||
* @LastEditors: TaoLer
|
||||
* @Description: 网站公共配置
|
||||
* @FilePath: \TaoLer\config\taoler.php
|
||||
* Copyright (c) 2020~2022 http://www.aieok.com All rights reserved.
|
||||
* Copyright (c) 2020~2022 https://www.aieok.com All rights reserved.
|
||||
*/
|
||||
// +----------------------------------------------------------------------
|
||||
// | 网站公共配置
|
||||
@ -16,7 +16,7 @@ return [
|
||||
// 应用名,此项不可更改
|
||||
'appname' => 'TaoLer',
|
||||
// 版本配置
|
||||
'version' => '1.9.3',
|
||||
'version' => '1.9.20',
|
||||
// 加盐
|
||||
'salt' => 'taoler',
|
||||
// 数据库备份目录
|
||||
@ -24,23 +24,43 @@ return [
|
||||
|
||||
// 配置
|
||||
'config' =>[
|
||||
'email_notice' => 0,
|
||||
'cate_show' => 1,
|
||||
'area_show' => 1,
|
||||
'regist_check' => 0,
|
||||
'posts_check' => 0,
|
||||
'commnets_check' => 0,
|
||||
'login_captcha' => 0,
|
||||
'post_captcha' => 0,
|
||||
// 注册开关
|
||||
'is_regist' => 1,
|
||||
// 登录开关
|
||||
'is_login' => 1,
|
||||
// 发帖开关
|
||||
'is_post' => 1,
|
||||
// 评论开关
|
||||
'is_reply' => 1,
|
||||
// 注册审核
|
||||
'regist_check' => 0,
|
||||
// 发帖审核
|
||||
'posts_check' => 0,
|
||||
// 评论审核
|
||||
'commnets_check' => 0,
|
||||
// 注册验证类型 1验证码2邮箱3手机短信
|
||||
'regist_type' => 1,
|
||||
// 登录验证码
|
||||
'login_captcha' => 0,
|
||||
// 发帖验证码
|
||||
'post_captcha' => 0,
|
||||
// 显示分类
|
||||
'cate_show' => 0,
|
||||
// 显示用户归属地简称
|
||||
'area_show' => 0,
|
||||
// 邮件通知
|
||||
'email_notice' => 0,
|
||||
// 百度词条开关
|
||||
'baidu_title_switch' => 0,
|
||||
],
|
||||
|
||||
// 百度标签分词
|
||||
'baidu' => [
|
||||
'grant_type' => '',
|
||||
'grant_type' => 'client_credentials',
|
||||
'client_id' => '',
|
||||
'client_secret' => '',
|
||||
'access_token' => '',
|
||||
'push_api' => 'http://',
|
||||
'push_api' => '',
|
||||
],
|
||||
|
||||
// sitemap
|
||||
@ -50,14 +70,14 @@ return [
|
||||
'map_time' => 'daily',
|
||||
'map_level' => '0.5',
|
||||
// 已生成id位标记
|
||||
'write_id' => 12,
|
||||
'write_id' => 21,
|
||||
|
||||
],
|
||||
|
||||
// URL美化
|
||||
'url_rewrite' => [
|
||||
// 详情url
|
||||
'article_as' => 'article/',
|
||||
'article_as' => '<ename>/',
|
||||
// 分类url
|
||||
'cate_as' => 'column/',
|
||||
],
|
||||
|
@ -1,10 +1,23 @@
|
||||
<?php
|
||||
/*
|
||||
* @Author: TaoLer <317927823@qq.com>
|
||||
* @Date: 2021-12-06 16:04:50
|
||||
* @LastEditTime: 2022-07-03 04:55:42
|
||||
* @LastEditors: TaoLer
|
||||
* @Description: 优化版
|
||||
* @FilePath: \TaoLer\config\trace.php
|
||||
* Copyright (c) 2020~2022 https://www.aieok.com All rights reserved.
|
||||
*/
|
||||
// +----------------------------------------------------------------------
|
||||
// | Trace设置 开启调试模式后有效
|
||||
// +----------------------------------------------------------------------
|
||||
return [
|
||||
// 内置Html和Console两种方式 支持扩展
|
||||
'type' => 'Html',
|
||||
// 读取的日志通道名
|
||||
'channel' => '',
|
||||
'type' => 'console',
|
||||
'tabs' => [
|
||||
'base' => '基本',
|
||||
'file' => '文件',
|
||||
'error|notice|warning' => '错误',
|
||||
'sql' => 'SQL',
|
||||
'debug|info' => '调试',
|
||||
],
|
||||
];
|
||||
|
@ -2,21 +2,12 @@
|
||||
// +----------------------------------------------------------------------
|
||||
// | 模板设置
|
||||
// +----------------------------------------------------------------------
|
||||
use think\facade\Db;
|
||||
//如果网站安装从数据库查询选择的模板
|
||||
if(file_exists('./install.lock')){
|
||||
$template = Db::name('system')->where('id',1)->value('template');
|
||||
} else {
|
||||
$template = '';
|
||||
}
|
||||
|
||||
return [
|
||||
// 模板引擎类型使用Think
|
||||
'type' => 'Think',
|
||||
// 默认模板渲染规则 1 解析为小写+下划线 2 全部转换小写 3 保持操作方法
|
||||
'auto_rule' => 1,
|
||||
// 模板目录名
|
||||
'view_dir_name' => 'view/'.$template,
|
||||
// 模板后缀
|
||||
'view_suffix' => 'html',
|
||||
// 模板文件名分隔符
|
||||
@ -31,6 +22,8 @@ return [
|
||||
'taglib_end' => '}',
|
||||
|
||||
'default_filter' => 'htmlspecialchars',
|
||||
|
||||
|
||||
//模板输出替换
|
||||
'tpl_replace_string' => [
|
||||
'__STATIC__'=>'/static/layui',
|
||||
|
@ -1,21 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?> <!-- XML文件需以utf-8编码-->
|
||||
<urlset>
|
||||
<url>
|
||||
<loc>http://www.test.com/index/jie/7.html</loc>
|
||||
<lastmod>2022-01-01</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
<priority>0.5</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>http://www.test.com/index/jie/8.html</loc>
|
||||
<lastmod>2022-01-01</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
<priority>0.5</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>http://www.test.com/index/jie/9.html</loc>
|
||||
<lastmod>2022-04-12</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
<priority>0.5</priority>
|
||||
</url>
|
||||
</urlset>
|
@ -1,21 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?> <!-- XML文件需以utf-8编码-->
|
||||
<urlset>
|
||||
<url>
|
||||
<loc>http://www.test.com/index/jie/10.html</loc>
|
||||
<lastmod>2022-04-15</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
<priority>0.5</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>http://www.test.com/index/jie/11.html</loc>
|
||||
<lastmod>2022-04-12</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
<priority>0.5</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>http://www.test.com/index/jie/12.html</loc>
|
||||
<lastmod>2022-04-12</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
<priority>0.5</priority>
|
||||
</url>
|
||||
</urlset>
|
@ -127,9 +127,9 @@ var forms = table.render({
|
||||
,cols: [[
|
||||
{type: 'checkbox'}
|
||||
,{field: 'id', width: 80, title: 'ID', sort: true}
|
||||
,{field: 'replyer', title: '回帖人', width: 80}
|
||||
,{field: 'title', title: '帖ID',templet: '#title'}
|
||||
,{field: 'avatar', title: '头像', width: 80, templet: '#imgTpl'}
|
||||
,{field: 'title', title: '标题',minWidth: 150, templet: '<div><a href="{{d.url}}" target="_blank">{{d.title}}</a></div>'}
|
||||
,{field: 'replyer', title: '账号', width: 80}
|
||||
,{field: 'avatar', title: '头像', width: 60, templet: '#imgTpl'}
|
||||
,{field: 'content', title: '评论', minWidth: 200}
|
||||
,{field: 'replytime', title: '回复时间', width: 120, sort: true}
|
||||
,{field: 'check', title: '审核', templet: '#buttonCheck', width: 100}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/**
|
||||
/**
|
||||
images压缩扩展模块
|
||||
changlin_zhao@qq.com
|
||||
2021.5.25
|
||||
@ -10,9 +10,8 @@ var layer = layui.layer;
|
||||
var compressImage = {
|
||||
uploads: function(obj){
|
||||
//obj.preview(function(index, file, result){
|
||||
|
||||
//执行实例
|
||||
|
||||
|
||||
//执行实例
|
||||
var files = obj.pushFile();
|
||||
var filesArry = [];
|
||||
for (var key in files) { //将上传的文件转为数组形式
|
||||
@ -54,7 +53,7 @@ var compressImage = {
|
||||
reader.readAsDataURL(file)
|
||||
reader.onload = function (e) {
|
||||
const img = new Image()
|
||||
const quality = 0.5 // 图像质量
|
||||
const quality = 0.8 // 图像质量
|
||||
const canvas = document.createElement('canvas')
|
||||
const drawer = canvas.getContext('2d')
|
||||
img.src = this.result
|
||||
@ -64,7 +63,7 @@ var compressImage = {
|
||||
originHeight = img.height; /* 图片的高度 */
|
||||
|
||||
// 设置最大尺寸限制,将所有图片都压缩到小于1m
|
||||
const maxWidth = 1024, maxHeight = 1024;
|
||||
const maxWidth = 2560, maxHeight = 1600;
|
||||
// 需要压缩的目标尺寸
|
||||
let targetWidth = originWidth, targetHeight = originHeight;
|
||||
// 等比例计算超过最大限制时缩放后的图片尺寸
|
||||
@ -105,7 +104,7 @@ var compressImage = {
|
||||
|
||||
//})
|
||||
}
|
||||
}
|
||||
}
|
||||
//输出 imgcom 接口
|
||||
exports('imgcom', compressImage);
|
||||
});
|
||||
|
@ -20,19 +20,19 @@ layui.define(['table', 'form'], function(exports){
|
||||
,cols: [[
|
||||
{type: 'checkbox'}
|
||||
,{field: 'id', width: 60, title: 'ID', sort: true}
|
||||
,{field: 'username', title: '用户名', minWidth: 100}
|
||||
,{field: 'nick', title: '昵称',minWidth: 100}
|
||||
,{field: 'avatar', title: '头像', width: 80, templet: '#imgTpl'}
|
||||
,{field: 'username', title: '用户名', minWidth: 80}
|
||||
,{field: 'nick', title: '昵称',Width: 80}
|
||||
,{field: 'avatar', title: '头像', width: 60, templet: '#imgTpl'}
|
||||
//,{field: 'phone', title: '手机',width: 80}
|
||||
,{field: 'email', title: '邮箱', width: 120}
|
||||
,{field: 'email', title: '邮箱', minWidth: 120}
|
||||
,{field: 'sex', width: 60, title: '性别',templet: '#sex'}
|
||||
,{field: 'ip', title: '登录IP', width: 100}
|
||||
,{field: 'city', title: '城市', width: 80}
|
||||
,{field: 'logintime', title: '最后登录',width: 150, sort: true}
|
||||
,{field: 'city', title: '城市', width: 80}
|
||||
,{field: 'logintime', title: '最后登录',width: 150, sort: true}
|
||||
,{field: 'jointime', title: '注册时间',width: 110, sort: true}
|
||||
,{field: 'check', title: '状态', templet: '#buttonCheck', width: 95, align: 'center'}
|
||||
,{field: 'auth', title: '超级管理员', templet: '#buttonAuth', width: 80, align: 'center'}
|
||||
,{title: '操作', width: 150, align:'center', toolbar: '#table-useradmin-webuser'}
|
||||
,{field: 'check', title: '状态', templet: '#buttonCheck', width: 95, align: 'center'}
|
||||
,{field: 'auth', title: '超级管理员', templet: '#buttonAuth', width: 80, align: 'center'}
|
||||
,{title: '操作', width: 100, align:'center', toolbar: '#table-useradmin-webuser'}
|
||||
]]
|
||||
,page: true
|
||||
,limit: 30
|
||||
@ -52,30 +52,21 @@ layui.define(['table', 'form'], function(exports){
|
||||
|
||||
layer.confirm('真的删除行么', function(index){
|
||||
//obj.del();
|
||||
$.ajax({
|
||||
type:'post',
|
||||
url:userDelete,
|
||||
data:{id:data.id},
|
||||
dataType:'json',
|
||||
success:function(data){
|
||||
if(data.code == 0){
|
||||
layer.msg(data.msg,{
|
||||
icon:6,
|
||||
time:2000
|
||||
},function(){
|
||||
location.reload();
|
||||
});
|
||||
} else {
|
||||
layer.open({
|
||||
title:'删除失败',
|
||||
content:data.msg,
|
||||
icon:5,
|
||||
adim:6
|
||||
})
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$.ajax({
|
||||
type:'post',
|
||||
url:userDelete,
|
||||
data:{id:data.id},
|
||||
dataType:'json',
|
||||
success:function(data){
|
||||
if(data.code == 0){
|
||||
layer.msg(data.msg,{icon:6,time:2000});
|
||||
} else {
|
||||
layer.open({title:'删除失败',content:data.msg,icon:5,adim:6})
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
table.reload('LAY-user-manage');
|
||||
layer.close(index);
|
||||
});
|
||||
});
|
||||
@ -97,34 +88,23 @@ layui.define(['table', 'form'], function(exports){
|
||||
|
||||
//监听提交
|
||||
iframeWindow.layui.form.on('submit('+ submitID +')', function(data){
|
||||
var field = data.field; //获取提交的字段
|
||||
var field = data.field; //获取提交的字段
|
||||
|
||||
//提交 Ajax 成功后,静态更新表格中的数据
|
||||
$.ajax({
|
||||
type:"post",
|
||||
url:userEdit,
|
||||
data:{"id":field.id,"name":field.username,"phone":field.phone,"email":field.email,"user_img":field.avatar,"sex":field.sex},
|
||||
daType:"json",
|
||||
success:function (res){
|
||||
if (res.code == 0) {
|
||||
layer.msg(res.msg,{
|
||||
icon:6,
|
||||
time:2000
|
||||
}, function(){
|
||||
location.reload();
|
||||
});
|
||||
} else {
|
||||
layer.open({
|
||||
tiele:'修改失败',
|
||||
content:res.msg,
|
||||
icon:5,
|
||||
anim:6
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
table.reload('LAY-user-front-submit'); //数据刷新
|
||||
type:"post",
|
||||
url:userEdit,
|
||||
data:{"id":field.id,"name":field.username,"phone":field.phone,"email":field.email,"user_img":field.avatar,"sex":field.sex},
|
||||
daType:"json",
|
||||
success:function (res){
|
||||
if(data.code == 0){
|
||||
layer.msg(data.msg,{icon:6,time:2000});
|
||||
} else {
|
||||
layer.open({title:'修改失败',content:data.msg,icon:5,adim:6})
|
||||
}
|
||||
}
|
||||
});
|
||||
table.reload('LAY-user-manage'); //数据刷新
|
||||
layer.close(index); //关闭弹层
|
||||
});
|
||||
|
||||
@ -149,7 +129,7 @@ layui.define(['table', 'form'], function(exports){
|
||||
,{field: 'email', title: '邮箱', minWidth: 150}
|
||||
,{field: 'check', title:'审核状态', templet: '#buttonTpl', width: 100, align: 'center'}
|
||||
,{field: 'ip', title: 'IP', width: 100}
|
||||
,{field: 'logintime', title: '最后登陆', width: 150}
|
||||
,{field: 'logintime', title: '最后登陆', width: 150}
|
||||
,{title: '操作', width: 150, align: 'center', toolbar: '#table-useradmin-admin'}
|
||||
]]
|
||||
,text: '对不起,加载出现异常!'
|
||||
|
2
public/static/jquery-3.6.0.min.js
vendored
Normal file
2
public/static/jquery-3.6.0.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1 +1 @@
|
||||
html #layuicss-skincodecss{display:none;position:absolute;width:1989px}.layui-code-h3,.layui-code-view{position:relative;font-size:12px}.layui-code-view{display:block;margin:10px 0;padding:0;border:1px solid #eee;border-left-width:6px;background-color:#FAFAFA;color:#333;font-family:Courier New}.layui-code-h3{padding:0 10px;height:40px;line-height:40px;border-bottom:1px solid #eee}.layui-code-h3 a{position:absolute;right:10px;top:0;color:#999}.layui-code-view .layui-code-ol{position:relative;overflow:auto}.layui-code-view .layui-code-ol li{position:relative;margin-left:45px;line-height:20px;padding:0 10px;border-left:1px solid #e2e2e2;list-style-type:decimal-leading-zero;*list-style-type:decimal;background-color:#fff}.layui-code-view .layui-code-ol li:first-child{padding-top:10px}.layui-code-view .layui-code-ol li:last-child{padding-bottom:10px}.layui-code-view pre{margin:0}.layui-code-notepad{border:1px solid #0C0C0C;border-left-color:#3F3F3F;background-color:#0C0C0C;color:#C2BE9E}.layui-code-notepad .layui-code-h3{border-bottom:none}.layui-code-notepad .layui-code-ol li{background-color:#3F3F3F;border-left:none}.layui-code-demo .layui-code{visibility:visible!important;margin:-15px;border-top:none;border-right:none;border-bottom:none}.layui-code-demo .layui-tab-content{padding:15px;border-top:none}
|
||||
html #layuicss-skincodecss{display:none;position:absolute;width:1989px}.layui-code-view{display:block;position:relative;margin:10px 0;padding:0;border:1px solid #eee;border-left-width:6px;background-color:#fafafa;color:#333;font-family:Courier New;font-size:13px}.layui-code-title{position:relative;padding:0 10px;height:40px;line-height:40px;border-bottom:1px solid #eee;font-size:12px}.layui-code-title>.layui-code-about{position:absolute;right:10px;top:0;color:#b7b7b7}.layui-code-about>a{padding-left:10px}.layui-code-view>.layui-code-ol,.layui-code-view>.layui-code-ul{position:relative;overflow:auto}.layui-code-view>.layui-code-ol>li{position:relative;margin-left:45px;line-height:20px;padding:0 10px;border-left:1px solid #e2e2e2;list-style-type:decimal-leading-zero;*list-style-type:decimal;background-color:#fff}.layui-code-view>.layui-code-ol>li:first-child,.layui-code-view>.layui-code-ul>li:first-child{padding-top:10px}.layui-code-view>.layui-code-ol>li:last-child,.layui-code-view>.layui-code-ul>li:last-child{padding-bottom:10px}.layui-code-view>.layui-code-ul>li{position:relative;line-height:20px;padding:0 10px;list-style-type:none;*list-style-type:none;background-color:#fff}.layui-code-view pre{margin:0}.layui-code-dark{border:1px solid #0c0c0c;border-left-color:#3f3f3f;background-color:#0c0c0c;color:#c2be9e}.layui-code-dark>.layui-code-title{border-bottom:none}.layui-code-dark>.layui-code-ol>li,.layui-code-dark>.layui-code-ul>li{background-color:#3f3f3f;border-left:none}.layui-code-dark>.layui-code-ul>li{margin-left:6px}.layui-code-demo .layui-code{visibility:visible!important;margin:-15px;border-top:none;border-right:none;border-bottom:none}.layui-code-demo .layui-tab-content{padding:15px;border-top:none}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
4
public/static/layui/jquery.min.js
vendored
4
public/static/layui/jquery.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,5 +1,4 @@
|
||||
/**
|
||||
|
||||
/**
|
||||
@Name: Fly社区
|
||||
@Author: 贤心
|
||||
@Site: fly.layui.com
|
||||
@ -221,8 +220,8 @@ pre{position: relative; margin: 10px 0; padding: 15px; line-height: 20px; border
|
||||
|
||||
/* 底部 */
|
||||
.fly-footer {margin: 50px 0 0; padding: 20px 0 30px; line-height: 30px; text-align: center; color: #737573; border-top: 1px solid #e2e2e2;}
|
||||
.fly-footer a{padding:0 6px; font-weight: 300; color: #333;}
|
||||
.fly-footer a:hover{color: #777;}
|
||||
.fly-footer a{padding:0 6px; font-weight: 300;color: rgb(230, 227, 227);}
|
||||
.fly-footer a:hover{color: #fff;}
|
||||
.fly-union{margin-top: 10px; color: #999;}
|
||||
.fly-union>*{display: inline-block; vertical-align: middle;}
|
||||
.fly-union a[upyun] img{width: 80px;}
|
||||
@ -319,7 +318,7 @@ pre{position: relative; margin: 10px 0; padding: 15px; line-height: 20px; border
|
||||
.fly-list-top li h2 a{display: inline-block; padding-right: 10px; font-size: 16px;}
|
||||
|
||||
/* 列表 */
|
||||
.fly-list li{position: relative; height: 45px; line-height: 22px; padding: 15px 15px 15px 75px; border-bottom: 1px dotted #e2e2e2;}
|
||||
.fly-list li{position: relative; height: 45px; line-height: 22px; padding: 15px 15px 15px 75px; border-bottom: 1px dotted #c3c1c1;}
|
||||
.fly-list li:last-child{border-bottom: none;}
|
||||
.fly-list li h2,
|
||||
.fly-list li h2 a,
|
||||
@ -329,11 +328,12 @@ pre{position: relative; margin: 10px 0; padding: 15px; line-height: 20px; border
|
||||
.fly-list li h2 .layui-badge{top: -2px; height: 16px; line-height: 16px; padding: 0 5px; margin-right: 10px; font-size: 12px; border: 1px solid #5FB878; background: none; color: #5FB878;}
|
||||
|
||||
.fly-list-info{position: relative; font-size: 13px; color: #999;}
|
||||
.fly-list-info>*{padding-right: 15px;}
|
||||
.fly-list-info>*{padding-right: 5px;}
|
||||
.fly-list-info a[link]{color: #999;}
|
||||
.fly-list-info a[link]:hover{color: #5FB878;}
|
||||
.fly-list-info .icon-renzheng{position: relative; top: 1px; margin-right: 3px;}
|
||||
.fly-list-info .fly-badge-vip{position: relative; margin-left: 2px;}
|
||||
.fly-list-info .layui-badge{height: 16px; line-height: 16px; padding: 0 5px; margin-right: 5px; font-size: 12px; border: 1px solid #5FB878; background: none; color: #5FB878;}
|
||||
.fly-list-kiss{color: #FF5722;}
|
||||
.fly-list-nums{position: absolute; right: 0; top: 0; padding-right: 0!important;}
|
||||
.fly-list-nums i{position: relative; padding: 0 3px 0 15px;}
|
||||
@ -343,10 +343,10 @@ pre{position: relative; margin: 10px 0; padding: 15px; line-height: 20px; border
|
||||
|
||||
/* 单行列表 */
|
||||
.fly-list-one .fly-panel-title{margin-bottom: 5px;}
|
||||
.fly-list-one dd{margin: 0 15px; line-height: 26px; white-space: nowrap; overflow: hidden; list-style: decimal-leading-zero inside; *list-style-type: decimal inside; color: #009E94;}
|
||||
.fly-list-one dd{margin: 0 15px; line-height: 28px; white-space: nowrap; overflow: hidden; list-style: decimal-leading-zero inside; *list-style-type: decimal inside; color: #009E94;}
|
||||
.fly-list-one dd a,
|
||||
.fly-list-one dd span{display: inline-block; *display: inline; *zoom: 1; vertical-align: top; font-style: normal}
|
||||
.fly-list-one dd a{max-width: 85%; margin-right: 5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 14px;}
|
||||
.fly-list-one dd a{max-width: 85%; margin-right: 5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 16px;}
|
||||
.fly-list-one dd span{font-size: 12px; color: #ccc;}
|
||||
.fly-list-one dd:last-child{padding-bottom: 5px;}
|
||||
|
||||
@ -359,22 +359,26 @@ body .layui-edit-face .layui-layer-content{padding:0; background-color:#fff; co
|
||||
|
||||
/*问题列表*/
|
||||
.question-list{width: 100%;}
|
||||
.question-list li{line-height: 30px; padding: 10px 15px 15px 20px; border-bottom: 1px dotted #e2e2e2; }
|
||||
.question-list li{line-height: 30px; padding: 10px 15px 15px 20px; border-bottom: 1px dotted #cccbcb; }
|
||||
.que-sta-jie,
|
||||
.que-sta-ask{float: left; margin-top:5px; margin-right:10px; text-align:center; padding:2px; width:38px; height:38px; line-height: 20px; border-radius: 10%; color: #fff;}
|
||||
.que-sta-jie{background: #5FB878;}
|
||||
.que-sta-ask{background: #FF5722;}
|
||||
.que-sta-ask,
|
||||
.que-sta-view{float: left; margin-top:5px; margin-right:10px; text-align:center; padding:2px; width:46px; height:46px; line-height: 23px; border-radius: 10%;}
|
||||
.que-sta-jie{color: #fff; background: #5FB878;}
|
||||
.que-sta-ask{color: #fff; background: #FF5722;}
|
||||
.que-sta-jie span{display: block;width:46px; height:23px;}
|
||||
.que-sta-ask span{display: block;width:46px; height:23px;}
|
||||
|
||||
.que-sta-view{color: rgb(84, 81, 81);background: #f7f6f5;}
|
||||
.que-sta-view span{display: block;width:46px; height:23px;}
|
||||
|
||||
.que-body{width:100%; padding: 0px; }
|
||||
.que-body h2{margin-right:10px; line-height: 26px; font-size: 16px; overflow: hidden; white-space: nowrap;text-overflow: ellipsis;}
|
||||
.que-body h2 a{display: inline-block; max-width: 95%; height: 20px; font-size: 16px;}
|
||||
.que-body .que-user-info{display: block; text-overflow: ellipsis;}
|
||||
.que-body .que-user-info a{margin-right: 10px;}
|
||||
.que-body .que-user-info .que-avatar{top: 20px;}
|
||||
.que-body .que-user-info .que-avatar img{width: 25px; height: 25px; margin-top: 10; border-radius: 100%;}
|
||||
.que-body .que-user-info .que-avatar i{position: absolute; left: 35px; top: 15px; }
|
||||
.que-body .que-user-info span{display: inline-block; font-size: 12px; padding-left: 5px;}
|
||||
.que-content{font-size: 14px; color:#999;}
|
||||
|
||||
|
||||
/* 签到 */
|
||||
.fly-signin cite{padding: 0 5px; color: #FF5722; font-style: normal;}
|
||||
@ -452,9 +456,24 @@ body .layui-edit-face .layui-layer-content{padding:0; background-color:#fff; co
|
||||
.fly-detail-user a{padding-right: 10px; font-size: 14px;}
|
||||
.fly-detail-user .guanzhu{position: absolute; right:10px; }
|
||||
|
||||
.detail-assist{position: relative; height:22px; margin-top: 10px; line-height: 15px; padding: 5px 10px 5px 10px; font-size: 13px; background-color: #f8f8f8; color: #999;border-radius:5px;}
|
||||
.detail-assist .fly-admin-box{position: absolute; top: 6px;right:10px;}
|
||||
.detail-assist span{height: 20px; line-height: 20px;}
|
||||
/*详情页管理工具条*/
|
||||
.detail-assist{
|
||||
position: fixed;
|
||||
width: 35px;
|
||||
height:185px;
|
||||
right: calc(50% - 625px);
|
||||
top: 200px;
|
||||
margin: 0 auto;
|
||||
display: block;
|
||||
line-height: 30px;
|
||||
font-size: 13px;
|
||||
background-color: #e7acac;
|
||||
color: #999;
|
||||
border-radius:5px;
|
||||
z-index: 100;
|
||||
}
|
||||
.detail-assist .fly-admin-box{text-align: center;}
|
||||
.detail-assist span{height: 30px;width:30px; line-height:30px;}
|
||||
.detail-assist .layui-btn{border-radius: 0;}
|
||||
.detail-assist .layui-btn+.layui-btn{margin-left: 1px;}
|
||||
.detail-assist .jie-admin{margin-right: 1px;}
|
||||
@ -499,6 +518,12 @@ body .layui-edit-face .layui-layer-content{padding:0; background-color:#fff; co
|
||||
.wenda-user .user-img i{posation:absolute;right:20px;top:30px;width: 25px; height:25px; color:#fff; font-site:18px; border-radius: 100%;background-color:#FFB800;}
|
||||
.wenda-user .questions{height:30px;margin:20px 20px;}
|
||||
|
||||
/*详情页-文章post*/
|
||||
.detail-zan{margin-top: 15px;}
|
||||
.detail-zan span{padding-right:5px; color:#999; cursor:pointer;}
|
||||
.detail-zan span:hover{color:#666;}
|
||||
.detail-zan span .icon-zan{font-size: 22px;}
|
||||
.detail-zan span img{height: 25px; border-radius: 100%;}
|
||||
|
||||
|
||||
/* 详情页的底部操作条 */
|
||||
@ -518,7 +543,9 @@ body .layui-edit-face .layui-layer-content{padding:0; background-color:#fff; co
|
||||
|
||||
/* 发帖 */
|
||||
.layui-form-item.layui-col-space15{margin-bottom: 7.5px;}
|
||||
|
||||
.bdsug{height: auto; position: absolute; left: 0; top: 30px; z-index: 100; background: #fff; border-radius: 0 0 10px 10px; border: 1px solid #dadade!important; border-top: 0!important; box-shadow: none;}
|
||||
.bdsug ul{display: block;margin: 5px 2px 0; padding: 5px 0 7px; background: 0 0; border-top: 0px solid #f5f5f6;}
|
||||
.bdsug ul>li{margin-top: 0;height:30px;line-height: 25px;}
|
||||
/* 求解管理 */
|
||||
.jie-admin{cursor: pointer;}
|
||||
.detail-hits .jie-admin{color: #fff; padding: 0 10px; }
|
||||
@ -705,7 +732,7 @@ body .fly-user-main{position: relative; min-height: 600px;}
|
||||
.laypage-main .laypage-next{display: inline-block;}
|
||||
|
||||
/* 列表 */
|
||||
.fly-list li h2 a{max-width: 72%;}
|
||||
.fly-list li h2 a{max-width: 90%;}
|
||||
|
||||
/* Detail 页
|
||||
.fly-admin-box{display: block; margin: 0; margin-top: 10px;}
|
||||
@ -730,38 +757,3 @@ body .fly-user-main{position: relative; min-height: 600px;}
|
||||
|
||||
/*前台公用样式*/
|
||||
|
||||
/*分页*/
|
||||
.pagination {
|
||||
display: inline-block;
|
||||
padding: 0 auto;
|
||||
margin: 20px 0;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.pagination li {
|
||||
display: inline;
|
||||
}
|
||||
.pagination li a,
|
||||
.pagination li span {
|
||||
position: relative;
|
||||
float: left;
|
||||
padding: 6px 12px;
|
||||
line-height: 1.42857143;
|
||||
color: #393D49;
|
||||
background: #fff;
|
||||
margin: 0 0 0 8px;
|
||||
border: 1px solid #eee;
|
||||
}
|
||||
|
||||
.pagination li a:hover {
|
||||
color: #fff;
|
||||
background: #009688;
|
||||
}
|
||||
.pagination .active span{
|
||||
background: #009688;
|
||||
color: #fff;
|
||||
}
|
||||
.pagination .disabled{
|
||||
display: none;
|
||||
@media screen and (max-width: 992px) {
|
||||
body .header .layui-nav .layui-nav-item{margin: 0 5px;}
|
||||
}
|
||||
|
@ -17,6 +17,8 @@ layui.define(['layer', 'laytpl', 'form', 'element', 'upload', 'util', 'imgcom'],
|
||||
,device = layui.device()
|
||||
,DISABLED = 'layui-btn-disabled';
|
||||
var uid = layui.cache.user.uid;
|
||||
var login = $('.fly-nav-user').attr('userlogin');
|
||||
|
||||
//阻止IE7以下访问
|
||||
if(device.ie && device.ie < 8){
|
||||
layer.alert('如果您非得使用 IE 浏览器访问Fly社区,那么请使用 IE8+');
|
||||
@ -442,9 +444,7 @@ layui.define(['layer', 'laytpl', 'form', 'element', 'upload', 'util', 'imgcom'],
|
||||
,preview: function(editor, span){ //预览
|
||||
var othis = $(span), getContent = function(){
|
||||
var content = editor.val();
|
||||
return /^\{html\}/.test(content)
|
||||
? content.replace(/^\{html\}/, '')
|
||||
: fly.content(content)
|
||||
return /^\{html\}/.test(content) ? content.replace(/^\{html\}/, '') : fly.content(content)
|
||||
}, isMobile = device.ios || device.android;
|
||||
|
||||
if(mod.preview.isOpen) return layer.close(mod.preview.index);
|
||||
@ -517,7 +517,7 @@ layui.define(['layer', 'laytpl', 'form', 'element', 'upload', 'util', 'imgcom'],
|
||||
|
||||
//转义图片
|
||||
.replace(/img\[([^\s]+?)\]/g, function(img){
|
||||
return '<div style="text-align: center;"><img src="' + img.replace(/(^img\[)|(\]$)/g, '') + '"></div>';
|
||||
return '<div><img src="' + img.replace(/(^img\[)|(\]$)/g, '') + '"></div>';
|
||||
})
|
||||
|
||||
//转义@
|
||||
@ -607,7 +607,9 @@ layui.define(['layer', 'laytpl', 'form', 'element', 'upload', 'util', 'imgcom'],
|
||||
//新消息通知
|
||||
,newmsg: function(){
|
||||
var elemUser = $('.fly-nav-user');
|
||||
if(layui.cache.user.uid !== -1 && elemUser[0]){
|
||||
var messageNums = elemUser.attr('msg-url'),
|
||||
messageRead = elemUser.attr('readMsg-url');
|
||||
if(uid != -1 && elemUser[0]){
|
||||
fly.json(messageNums, {
|
||||
_: new Date().getTime()
|
||||
}, function(res){
|
||||
@ -617,7 +619,7 @@ layui.define(['layer', 'laytpl', 'form', 'element', 'upload', 'util', 'imgcom'],
|
||||
msg.on('click', function(){
|
||||
fly.json(messageRead, {}, function(res){
|
||||
if(res.status === 0){
|
||||
location.href = userMessage;
|
||||
location.href = res.url;
|
||||
}
|
||||
});
|
||||
});
|
||||
@ -730,189 +732,28 @@ layui.define(['layer', 'laytpl', 'form', 'element', 'upload', 'util', 'imgcom'],
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
//签到
|
||||
var jName = "金币";
|
||||
var tplSignin = ['{{# if(d.signed){ }}'
|
||||
,'<button class="layui-btn layui-btn-disabled">今日已签到</button>'
|
||||
,'<span>获得了<cite>{{ d.experience }}</cite>' + jName + '</span>'
|
||||
,'{{# } else { }}'
|
||||
,'<button class="layui-btn layui-btn-danger" id="LAY_signin">今日签到</button>'
|
||||
,'<span>可获得<cite>{{ d.experience }}</cite>' + jName + '</span>'
|
||||
,'{{# } }}'].join('')
|
||||
,tplSigninDay = '已连续签到<cite>{{ d.days }}</cite>天'
|
||||
|
||||
,signRender = function(data){
|
||||
laytpl(tplSignin).render(data, function(html){
|
||||
elemSigninMain.html(html);
|
||||
});
|
||||
laytpl(tplSigninDay).render(data, function(html){
|
||||
elemSigninDays.html(html);
|
||||
});
|
||||
}
|
||||
|
||||
,elemSigninHelp = $('#LAY_signinHelp')
|
||||
,elemSigninTop = $('#LAY_signinTop')
|
||||
,elemSigninMain = $('.fly-signin-main')
|
||||
,elemSigninDays = $('.fly-signin-days');
|
||||
|
||||
if(elemSigninMain[0]){
|
||||
fly.json(signStatusUrl, function(res){
|
||||
if(!res.data) return;
|
||||
signRender.token = res.data.token;
|
||||
signRender(res.data);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
$('body').on('click', '#LAY_signin', function(){
|
||||
//登录判断
|
||||
if(uid == -1){
|
||||
layer.msg('请登录再签到', {icon: 6}, function(){
|
||||
location.href = login;
|
||||
})
|
||||
return false;
|
||||
}
|
||||
|
||||
var othis = $(this);
|
||||
if(othis.hasClass(DISABLED)) return;
|
||||
|
||||
fly.json(signInUrl, {
|
||||
token: signRender.token || 1
|
||||
}, function(res){
|
||||
signRender(res.data);
|
||||
}, {
|
||||
error: function(){
|
||||
othis.removeClass(DISABLED);
|
||||
}
|
||||
});
|
||||
|
||||
othis.addClass(DISABLED);
|
||||
});
|
||||
|
||||
//签到说明
|
||||
elemSigninHelp.on('click', function(){
|
||||
|
||||
$.getJSON(signRuleUrl, function(data) {
|
||||
|
||||
//拼接表格字符串
|
||||
var $str = '';
|
||||
$.each(data.msg, function(k, v) {
|
||||
$str += '<tr><td>≥' + v.days + '</td><td>' + v.score + '</td></tr>';
|
||||
});
|
||||
|
||||
layer.open({
|
||||
type: 1
|
||||
,title: '签到说明'
|
||||
,area: '300px'
|
||||
,shade: 0.8
|
||||
,shadeClose: true
|
||||
,content: ['<div class="layui-text" style="padding: 20px;">'
|
||||
,'<blockquote class="layui-elem-quote">“签到”可获得社区' + jName + ',规则如下</blockquote>'
|
||||
,'<table class="layui-table">'
|
||||
,'<thead>'
|
||||
,'<tr><th>连续签到天数</th><th>每天可获' + jName + '</th></tr>'
|
||||
,'</thead>'
|
||||
,'<tbody>'
|
||||
,$str
|
||||
,'</tbody>'
|
||||
,'</table>'
|
||||
,'<ul>'
|
||||
,'<li>中间若有间隔,则连续天数重新计算</li>'
|
||||
,'<li style="color: #FF5722;">不可利用程序自动签到,否则' + jName + '清零</li>'
|
||||
,'</ul>'
|
||||
,'</div>'].join('')
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
//签到活跃榜
|
||||
var tplSigninTop = ['{{# layui.each(d.data, function(index, item){ }}'
|
||||
,'<li>'
|
||||
,'<a href="/u/{{item.uid}}" target="_blank">'
|
||||
,'<img src="{{item.user.avatar}}">'
|
||||
,'<cite class="fly-link">{{item.user.username}}</cite>'
|
||||
,'</a>'
|
||||
,'{{# var date = new Date(item.time); if(d.index === 0) { }}'
|
||||
,'<span class="fly-grey"> {{ layui.laytpl.digit(date.getFullYear()) + "-" + layui.laytpl.digit(date.getMonth()+1) + "-" + layui.laytpl.digit(date.getDate())}} 签到 <i class="layui-icon layui-icon-ok"></i></span>'
|
||||
,'{{# } else if(d.index == 1) { }}'
|
||||
,'<span class="fly-grey">签到于 {{ layui.laytpl.digit(date.getHours()) + ":" + layui.laytpl.digit(date.getMinutes()) + ":" + layui.laytpl.digit(date.getSeconds()) }} <i class="layui-icon layui-icon-flag"></i></span>'
|
||||
,'{{# } else { }}'
|
||||
,'<span class="fly-grey">已连续签到 <i>{{ item.days }}</i> 天 <i class="layui-icon layui-icon-face-smile"></i></span>'
|
||||
,'{{# } }}'
|
||||
,'</li>'
|
||||
,'{{# }); }}'
|
||||
,'{{# if(d.data.length === 0) { }}'
|
||||
,'{{# if(d.index < 2) { }}'
|
||||
,'<li class="fly-none fly-grey">今天还没有人签到</li>'
|
||||
,'{{# } else { }}'
|
||||
,'<li class="fly-none fly-grey">还没有签到记录</li>'
|
||||
,'{{# } }}'
|
||||
,'{{# } }}'].join('');
|
||||
|
||||
elemSigninTop.on('click', function(){
|
||||
var loadIndex = layer.load(1, {shade: 0.8});
|
||||
fly.json(signJsonUrl, function(res){ //实际使用,请将 url 改为真实接口
|
||||
var tpl = $(['<div class="layui-tab layui-tab-brief" style="margin: 5px 0 0;">'
|
||||
,'<ul class="layui-tab-title">'
|
||||
,'<li class="layui-this">最新签到</li>'
|
||||
,'<li>今日最快</li>'
|
||||
,'<li>总签到榜</li>'
|
||||
,'</ul>'
|
||||
,'<div class="layui-tab-content fly-signin-list" id="LAY_signin_list">'
|
||||
,'<ul class="layui-tab-item layui-show"></ul>'
|
||||
,'<ul class="layui-tab-item">2</ul>'
|
||||
,'<ul class="layui-tab-item">3</ul>'
|
||||
,'</div>'
|
||||
,'</div>'].join(''))
|
||||
,signinItems = tpl.find('.layui-tab-item');
|
||||
|
||||
layer.close(loadIndex);
|
||||
|
||||
layui.each(signinItems, function(index, item){
|
||||
var html = laytpl(tplSigninTop).render({
|
||||
data: res.data[index]
|
||||
,index: index
|
||||
});
|
||||
$(item).html(html);
|
||||
});
|
||||
|
||||
layer.open({
|
||||
type: 1
|
||||
,title: '签到活跃榜 - TOP 20'
|
||||
,area: '300px'
|
||||
,shade: 0.8
|
||||
,shadeClose: true
|
||||
,id: 'layer-pop-signintop'
|
||||
,content: tpl.prop('outerHTML')
|
||||
});
|
||||
|
||||
}, {type: 'get'});
|
||||
});
|
||||
|
||||
|
||||
//回帖榜
|
||||
//活跃榜
|
||||
var tplReply = ['{{# layui.each(d.data, function(index, item){ }}'
|
||||
,'<dd>'
|
||||
,'<a href="{{item.uid}}">'
|
||||
,'<img src="{{item.user.avatar}}">'
|
||||
,'<cite>{{item.user.username}}</cite>'
|
||||
,'<i>{{item["count(*)"]}}' +replyNum+'</i>'
|
||||
,'<i>{{item["count"]}}' + replyNum + '</i>'
|
||||
,'</a>'
|
||||
,'</dd>'
|
||||
,'{{# }); }}'].join('')
|
||||
,elemReply = $('#LAY_replyRank');
|
||||
|
||||
var replyUrl = elemReply.attr('data-url');
|
||||
if(elemReply[0]){
|
||||
|
||||
fly.json(replyUrl, {
|
||||
limit: 20
|
||||
}, function(res){
|
||||
var html = laytpl(tplReply).render(res);
|
||||
elemReply.find('dl').html(html);
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
//相册
|
||||
@ -930,16 +771,18 @@ layui.define(['layer', 'laytpl', 'form', 'element', 'upload', 'util', 'imgcom'],
|
||||
|
||||
|
||||
//搜索
|
||||
$('.fly-search').on('click', function(){
|
||||
$('.fly-search').on('click', function(data){
|
||||
var searchUrl = $('.fly-search').attr('data-url');
|
||||
var forms = '<form action='+ searchUrl + '>';
|
||||
layer.open({
|
||||
type: 1
|
||||
,title: false
|
||||
,closeBtn: false
|
||||
//,shade: [0.1, '#fff']
|
||||
,shade: [0.1, '#fff']
|
||||
,shadeClose: true
|
||||
,maxWidth: 10000
|
||||
,skin: 'fly-layer-search'
|
||||
,content: ['<form action='+searchUrl+'>'
|
||||
,content: [forms
|
||||
,'<input autocomplete="off" placeholder="搜索内容,回车跳转" type="text" name="keywords">'
|
||||
,'</form>'].join('')
|
||||
,success: function(layero){
|
||||
@ -1030,7 +873,7 @@ layui.define(['layer', 'laytpl', 'form', 'element', 'upload', 'util', 'imgcom'],
|
||||
elem: '.fly-editor'
|
||||
});
|
||||
|
||||
//手机设备的简单适配 底部左侧栏导航
|
||||
//手机设备的简单适配 用户中心底部左侧栏导航
|
||||
var treeMobile = $('.site-tree-mobile')
|
||||
,shadeMobile = $('.site-mobile-shade')
|
||||
|
||||
@ -1136,6 +979,7 @@ layui.define(['layer', 'laytpl', 'form', 'element', 'upload', 'util', 'imgcom'],
|
||||
});
|
||||
return false;
|
||||
});
|
||||
|
||||
//移动端左侧栏监听多语言切换
|
||||
$('#language1').on('change',function(){
|
||||
var data = $(this).val();
|
||||
|
@ -75,34 +75,34 @@ layui.define('fly', function(exports){
|
||||
//删帖子
|
||||
del: function(div){
|
||||
layer.confirm('确认删除该贴么?', function(index){
|
||||
layer.close(index);
|
||||
$.ajax({
|
||||
type:'get',
|
||||
url:articleDelete,
|
||||
data:{id: div.data('id')},
|
||||
dataType:'json',
|
||||
success:function(data){
|
||||
if(data.code == 0){
|
||||
layer.msg(data.msg,{
|
||||
icon:6,
|
||||
time:2000
|
||||
},function(){
|
||||
location.href = '/';
|
||||
});
|
||||
} else {
|
||||
layer.open({
|
||||
title:'删除失败',
|
||||
content:data.msg,
|
||||
icon:5,
|
||||
adim:6
|
||||
})
|
||||
}
|
||||
}
|
||||
});
|
||||
layer.close(index);
|
||||
$.ajax({
|
||||
type:'get',
|
||||
url:articleDelete,
|
||||
data:{id: div.data('id')},
|
||||
dataType:'json',
|
||||
success:function(data){
|
||||
if(data.code == 0){
|
||||
layer.msg(data.msg,{
|
||||
icon:6,
|
||||
time:2000
|
||||
},function(){
|
||||
location.href = '/';
|
||||
});
|
||||
} else {
|
||||
layer.open({
|
||||
title:'删除失败',
|
||||
content:data.msg,
|
||||
icon:5,
|
||||
adim:6
|
||||
})
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
//设置置顶、加精、禁评、状态
|
||||
// 设置置顶、加精、禁评、状态
|
||||
,set: function(div){
|
||||
var othis = $(this);
|
||||
fly.json(articleJieset, {
|
||||
@ -111,13 +111,13 @@ layui.define('fly', function(exports){
|
||||
,field: othis.attr('field')
|
||||
}, function(res){
|
||||
if(res.status === 0){
|
||||
layer.msg(res.msg);
|
||||
location.reload();
|
||||
}
|
||||
layer.msg(res.msg);
|
||||
location.reload();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//收藏
|
||||
// 收藏
|
||||
,collect: function(div){
|
||||
var othis = $(this), type = othis.data('type');
|
||||
fly.json(collection+ type +'/', {
|
||||
|
@ -33,34 +33,34 @@ layui.define(['laypage', 'fly', 'element', 'flow', 'imgcom'], function(exports){
|
||||
var post = table.render({
|
||||
elem: '#art-post'
|
||||
,url: artListUrl
|
||||
,title: ''
|
||||
,title: ''
|
||||
,cols: [[
|
||||
{type: 'numbers', fixed: 'left'}
|
||||
,{field: 'title', title: '标题',minWidth: 250 ,templet: '<div><a href="{{d.url}}" target="_blank">{{d.title}}</a></div>'}
|
||||
,{field: 'status', title: '状态', width: 80}
|
||||
,{field: 'ctime', title: '时间', width: 120}
|
||||
,{field: 'title', title: '标题',minWidth: 250 ,templet: '<div><a href="{{d.url}}" target="_blank">{{-d.title}}</a></div>'}
|
||||
,{field: 'status', title: '状态', width: 80}
|
||||
,{field: 'ctime', title: '时间', width: 120}
|
||||
,{field: 'datas', title: '数据', width: 120}
|
||||
,{title: '操作', width: 150, align: 'center', toolbar: '#artTool'}
|
||||
]]
|
||||
,text: '对不起,加载出现异常!'
|
||||
,page: true
|
||||
,page: true
|
||||
});
|
||||
|
||||
//收藏list
|
||||
table.render({
|
||||
elem: '#coll-post'
|
||||
,url: collListUrl
|
||||
,title: ''
|
||||
,title: ''
|
||||
,cols: [[
|
||||
{type: 'numbers', fixed: 'left'}
|
||||
,{field: 'title', title: '标题',minWidth: 250,templet: '<div><a href="{{d.url}}" target="_blank">{{d.title}}</a></div>'}
|
||||
,{field: 'auther', title: '作者', width: 120}
|
||||
,{field: 'status', title: '状态', width: 80}
|
||||
,{field: 'ctime', title: '时间', width: 120}
|
||||
,{field: 'auther', title: '作者', width: 120}
|
||||
,{field: 'status', title: '状态', width: 80}
|
||||
,{field: 'ctime', title: '时间', width: 120}
|
||||
,{title: '取消', width: 80, align: 'center', toolbar: '#collTool'}
|
||||
]]
|
||||
,text: '对不起,加载出现异常!'
|
||||
,page: true
|
||||
,page: true
|
||||
});
|
||||
|
||||
//监听行工具事件
|
||||
@ -68,33 +68,24 @@ layui.define(['laypage', 'fly', 'element', 'flow', 'imgcom'], function(exports){
|
||||
var data = obj.data;
|
||||
var id = data.id;
|
||||
if(obj.event === 'del'){
|
||||
layer.confirm('确定删除吗?',{
|
||||
title:'删除文章',
|
||||
icon:3
|
||||
},function(index){
|
||||
layer.close(index);
|
||||
$.post(atrDelUrl,{"id":id},function(data){
|
||||
if(data.code == 0){
|
||||
layer.msg(data.msg,{
|
||||
icon:6,
|
||||
time:2000
|
||||
});
|
||||
} else {
|
||||
layer.open({
|
||||
title:'删除失败',
|
||||
content:data.msg,
|
||||
icon:5,
|
||||
adim:6
|
||||
})
|
||||
}
|
||||
}
|
||||
);
|
||||
table.reload('art-post');
|
||||
});
|
||||
|
||||
layer.confirm('确定删除吗?',{
|
||||
title:'删除文章',
|
||||
icon:3
|
||||
},function(index){
|
||||
layer.close(index);
|
||||
$.post(atrDelUrl,{"id":id},function(data){
|
||||
if(data.code == 0){
|
||||
layer.msg(data.msg,{icon:6,time:2000});
|
||||
} else {
|
||||
layer.open({title:'删除失败',content:data.msg,icon:5,adim:6})
|
||||
}
|
||||
}
|
||||
);
|
||||
table.reload('art-post');
|
||||
});
|
||||
} else if(obj.event === 'edit'){//编辑
|
||||
$.post(artEditUrl,{"id":id},function(){
|
||||
location.href = artEditUrl + '?id=' + id;
|
||||
location.href = artEditUrl + '?id=' + id;
|
||||
});
|
||||
}
|
||||
|
||||
@ -141,14 +132,14 @@ layui.define(['laypage', 'fly', 'element', 'flow', 'imgcom'], function(exports){
|
||||
location.hash = layid;
|
||||
}
|
||||
});
|
||||
|
||||
/*
|
||||
//根据ip获取城市
|
||||
if($('#L_city').val() === ''){
|
||||
$.getScript('http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=js', function(){
|
||||
$('#L_city').val(remote_ip_info.city||'');
|
||||
});
|
||||
}
|
||||
|
||||
*/
|
||||
//上传图片
|
||||
if($('.upload-img')[0]){
|
||||
layui.use('upload', function(upload){
|
||||
@ -156,27 +147,25 @@ layui.define(['laypage', 'fly', 'element', 'flow', 'imgcom'], function(exports){
|
||||
|
||||
upload.render({
|
||||
elem: '.upload-img'
|
||||
,accept: 'images'
|
||||
,acceptMime: 'image/*'
|
||||
,exts: 'jpg|png|gif|bmp|jpeg'
|
||||
,accept: 'images'
|
||||
,acceptMime: 'image/*'
|
||||
,exts: 'jpg|png|gif|bmp|jpeg'
|
||||
,url: uploadHeadImg
|
||||
,size: 10240
|
||||
,auto: false
|
||||
,choose: function (obj) { //选择文件后的回调
|
||||
,auto: false
|
||||
,choose: function (obj) { //选择文件后的回调
|
||||
imgcom.uploads(obj);
|
||||
}
|
||||
,before: function(){
|
||||
avatarAdd.find('.loading').show();
|
||||
}
|
||||
,done: function(res){
|
||||
if(res.status == 0){
|
||||
$.post(userSet, {
|
||||
avatar: res.url
|
||||
}, function(res){
|
||||
if(res.code == 0){
|
||||
layer.msg(res.msg, { icon: 6, time: 2000 },function(){
|
||||
location.reload();
|
||||
});
|
||||
} else {
|
||||
layer.msg(res.msg, {icon: 5});
|
||||
layer.open({ content: data.msg, icon: 5, adim: 6 });
|
||||
}
|
||||
avatarAdd.find('.loading').hide();
|
||||
}
|
||||
|
2
runtime/.gitignore
vendored
2
runtime/.gitignore
vendored
@ -1,2 +0,0 @@
|
||||
*
|
||||
!.gitignore
|
5
vendor/autoload.php
vendored
5
vendor/autoload.php
vendored
@ -2,6 +2,11 @@
|
||||
|
||||
// autoload.php @generated by Composer
|
||||
|
||||
if (PHP_VERSION_ID < 50600) {
|
||||
echo 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
require_once __DIR__ . '/composer/autoload_real.php';
|
||||
|
||||
return ComposerAutoloaderInit1b32198725235c8d6500c87262ef30c2::getLoader();
|
||||
|
22
vendor/bacon/bacon-qr-code/LICENSE
vendored
Normal file
22
vendor/bacon/bacon-qr-code/LICENSE
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
Copyright (c) 2017, Ben Scholzen 'DASPRiD'
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
39
vendor/bacon/bacon-qr-code/README.md
vendored
Normal file
39
vendor/bacon/bacon-qr-code/README.md
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
# QR Code generator
|
||||
|
||||
[![PHP CI](https://github.com/Bacon/BaconQrCode/actions/workflows/ci.yml/badge.svg)](https://github.com/Bacon/BaconQrCode/actions/workflows/ci.yml)
|
||||
[![codecov](https://codecov.io/gh/Bacon/BaconQrCode/branch/master/graph/badge.svg?token=rD0HcAiEEx)](https://codecov.io/gh/Bacon/BaconQrCode)
|
||||
[![Latest Stable Version](https://poser.pugx.org/bacon/bacon-qr-code/v/stable)](https://packagist.org/packages/bacon/bacon-qr-code)
|
||||
[![Total Downloads](https://poser.pugx.org/bacon/bacon-qr-code/downloads)](https://packagist.org/packages/bacon/bacon-qr-code)
|
||||
[![License](https://poser.pugx.org/bacon/bacon-qr-code/license)](https://packagist.org/packages/bacon/bacon-qr-code)
|
||||
|
||||
|
||||
## Introduction
|
||||
BaconQrCode is a port of QR code portion of the ZXing library. It currently
|
||||
only features the encoder part, but could later receive the decoder part as
|
||||
well.
|
||||
|
||||
As the Reed Solomon codec implementation of the ZXing library performs quite
|
||||
slow in PHP, it was exchanged with the implementation by Phil Karn.
|
||||
|
||||
|
||||
## Example usage
|
||||
```php
|
||||
use BaconQrCode\Renderer\ImageRenderer;
|
||||
use BaconQrCode\Renderer\Image\ImagickImageBackEnd;
|
||||
use BaconQrCode\Renderer\RendererStyle\RendererStyle;
|
||||
use BaconQrCode\Writer;
|
||||
|
||||
$renderer = new ImageRenderer(
|
||||
new RendererStyle(400),
|
||||
new ImagickImageBackEnd()
|
||||
);
|
||||
$writer = new Writer($renderer);
|
||||
$writer->writeFile('Hello World!', 'qrcode.png');
|
||||
```
|
||||
|
||||
## Available image renderer back ends
|
||||
BaconQrCode comes with multiple back ends for rendering images. Currently included are the following:
|
||||
|
||||
- `ImagickImageBackEnd`: renders raster images using the Imagick library
|
||||
- `SvgImageBackEnd`: renders SVG files using XMLWriter
|
||||
- `EpsImageBackEnd`: renders EPS files
|
38
vendor/bacon/bacon-qr-code/composer.json
vendored
Normal file
38
vendor/bacon/bacon-qr-code/composer.json
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
{
|
||||
"name": "bacon/bacon-qr-code",
|
||||
"description": "BaconQrCode is a QR code generator for PHP.",
|
||||
"license" : "BSD-2-Clause",
|
||||
"homepage": "https://github.com/Bacon/BaconQrCode",
|
||||
"require": {
|
||||
"php": "^7.1 || ^8.0",
|
||||
"ext-iconv": "*",
|
||||
"dasprid/enum": "^1.0.3"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-imagick": "to generate QR code images"
|
||||
},
|
||||
"authors": [
|
||||
{
|
||||
"name": "Ben Scholzen 'DASPRiD'",
|
||||
"email": "mail@dasprids.de",
|
||||
"homepage": "https://dasprids.de/",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"BaconQrCode\\": "src/"
|
||||
}
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^7 | ^8 | ^9",
|
||||
"spatie/phpunit-snapshot-assertions": "^4.2.9",
|
||||
"squizlabs/php_codesniffer": "^3.4",
|
||||
"phly/keep-a-changelog": "^2.1"
|
||||
},
|
||||
"config": {
|
||||
"allow-plugins": {
|
||||
"ocramius/package-versions": true
|
||||
}
|
||||
}
|
||||
}
|
372
vendor/bacon/bacon-qr-code/src/Common/BitArray.php
vendored
Normal file
372
vendor/bacon/bacon-qr-code/src/Common/BitArray.php
vendored
Normal file
@ -0,0 +1,372 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace BaconQrCode\Common;
|
||||
|
||||
use BaconQrCode\Exception\InvalidArgumentException;
|
||||
use SplFixedArray;
|
||||
|
||||
/**
|
||||
* A simple, fast array of bits.
|
||||
*/
|
||||
final class BitArray
|
||||
{
|
||||
/**
|
||||
* Bits represented as an array of integers.
|
||||
*
|
||||
* @var SplFixedArray<int>
|
||||
*/
|
||||
private $bits;
|
||||
|
||||
/**
|
||||
* Size of the bit array in bits.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $size;
|
||||
|
||||
/**
|
||||
* Creates a new bit array with a given size.
|
||||
*/
|
||||
public function __construct(int $size = 0)
|
||||
{
|
||||
$this->size = $size;
|
||||
$this->bits = SplFixedArray::fromArray(array_fill(0, ($this->size + 31) >> 3, 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the size in bits.
|
||||
*/
|
||||
public function getSize() : int
|
||||
{
|
||||
return $this->size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the size in bytes.
|
||||
*/
|
||||
public function getSizeInBytes() : int
|
||||
{
|
||||
return ($this->size + 7) >> 3;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that the array has a minimum capacity.
|
||||
*/
|
||||
public function ensureCapacity(int $size) : void
|
||||
{
|
||||
if ($size > count($this->bits) << 5) {
|
||||
$this->bits->setSize(($size + 31) >> 5);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a specific bit.
|
||||
*/
|
||||
public function get(int $i) : bool
|
||||
{
|
||||
return 0 !== ($this->bits[$i >> 5] & (1 << ($i & 0x1f)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a specific bit.
|
||||
*/
|
||||
public function set(int $i) : void
|
||||
{
|
||||
$this->bits[$i >> 5] = $this->bits[$i >> 5] | 1 << ($i & 0x1f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Flips a specific bit.
|
||||
*/
|
||||
public function flip(int $i) : void
|
||||
{
|
||||
$this->bits[$i >> 5] ^= 1 << ($i & 0x1f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the next set bit position from a given position.
|
||||
*/
|
||||
public function getNextSet(int $from) : int
|
||||
{
|
||||
if ($from >= $this->size) {
|
||||
return $this->size;
|
||||
}
|
||||
|
||||
$bitsOffset = $from >> 5;
|
||||
$currentBits = $this->bits[$bitsOffset];
|
||||
$bitsLength = count($this->bits);
|
||||
$currentBits &= ~((1 << ($from & 0x1f)) - 1);
|
||||
|
||||
while (0 === $currentBits) {
|
||||
if (++$bitsOffset === $bitsLength) {
|
||||
return $this->size;
|
||||
}
|
||||
|
||||
$currentBits = $this->bits[$bitsOffset];
|
||||
}
|
||||
|
||||
$result = ($bitsOffset << 5) + BitUtils::numberOfTrailingZeros($currentBits);
|
||||
return $result > $this->size ? $this->size : $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the next unset bit position from a given position.
|
||||
*/
|
||||
public function getNextUnset(int $from) : int
|
||||
{
|
||||
if ($from >= $this->size) {
|
||||
return $this->size;
|
||||
}
|
||||
|
||||
$bitsOffset = $from >> 5;
|
||||
$currentBits = ~$this->bits[$bitsOffset];
|
||||
$bitsLength = count($this->bits);
|
||||
$currentBits &= ~((1 << ($from & 0x1f)) - 1);
|
||||
|
||||
while (0 === $currentBits) {
|
||||
if (++$bitsOffset === $bitsLength) {
|
||||
return $this->size;
|
||||
}
|
||||
|
||||
$currentBits = ~$this->bits[$bitsOffset];
|
||||
}
|
||||
|
||||
$result = ($bitsOffset << 5) + BitUtils::numberOfTrailingZeros($currentBits);
|
||||
return $result > $this->size ? $this->size : $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a bulk of bits.
|
||||
*/
|
||||
public function setBulk(int $i, int $newBits) : void
|
||||
{
|
||||
$this->bits[$i >> 5] = $newBits;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a range of bits.
|
||||
*
|
||||
* @throws InvalidArgumentException if end is smaller than start
|
||||
*/
|
||||
public function setRange(int $start, int $end) : void
|
||||
{
|
||||
if ($end < $start) {
|
||||
throw new InvalidArgumentException('End must be greater or equal to start');
|
||||
}
|
||||
|
||||
if ($end === $start) {
|
||||
return;
|
||||
}
|
||||
|
||||
--$end;
|
||||
|
||||
$firstInt = $start >> 5;
|
||||
$lastInt = $end >> 5;
|
||||
|
||||
for ($i = $firstInt; $i <= $lastInt; ++$i) {
|
||||
$firstBit = $i > $firstInt ? 0 : $start & 0x1f;
|
||||
$lastBit = $i < $lastInt ? 31 : $end & 0x1f;
|
||||
|
||||
if (0 === $firstBit && 31 === $lastBit) {
|
||||
$mask = 0x7fffffff;
|
||||
} else {
|
||||
$mask = 0;
|
||||
|
||||
for ($j = $firstBit; $j < $lastBit; ++$j) {
|
||||
$mask |= 1 << $j;
|
||||
}
|
||||
}
|
||||
|
||||
$this->bits[$i] = $this->bits[$i] | $mask;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the bit array, unsetting every bit.
|
||||
*/
|
||||
public function clear() : void
|
||||
{
|
||||
$bitsLength = count($this->bits);
|
||||
|
||||
for ($i = 0; $i < $bitsLength; ++$i) {
|
||||
$this->bits[$i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a range of bits is set or not set.
|
||||
|
||||
* @throws InvalidArgumentException if end is smaller than start
|
||||
*/
|
||||
public function isRange(int $start, int $end, bool $value) : bool
|
||||
{
|
||||
if ($end < $start) {
|
||||
throw new InvalidArgumentException('End must be greater or equal to start');
|
||||
}
|
||||
|
||||
if ($end === $start) {
|
||||
return true;
|
||||
}
|
||||
|
||||
--$end;
|
||||
|
||||
$firstInt = $start >> 5;
|
||||
$lastInt = $end >> 5;
|
||||
|
||||
for ($i = $firstInt; $i <= $lastInt; ++$i) {
|
||||
$firstBit = $i > $firstInt ? 0 : $start & 0x1f;
|
||||
$lastBit = $i < $lastInt ? 31 : $end & 0x1f;
|
||||
|
||||
if (0 === $firstBit && 31 === $lastBit) {
|
||||
$mask = 0x7fffffff;
|
||||
} else {
|
||||
$mask = 0;
|
||||
|
||||
for ($j = $firstBit; $j <= $lastBit; ++$j) {
|
||||
$mask |= 1 << $j;
|
||||
}
|
||||
}
|
||||
|
||||
if (($this->bits[$i] & $mask) !== ($value ? $mask : 0)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a bit to the array.
|
||||
*/
|
||||
public function appendBit(bool $bit) : void
|
||||
{
|
||||
$this->ensureCapacity($this->size + 1);
|
||||
|
||||
if ($bit) {
|
||||
$this->bits[$this->size >> 5] = $this->bits[$this->size >> 5] | (1 << ($this->size & 0x1f));
|
||||
}
|
||||
|
||||
++$this->size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a number of bits (up to 32) to the array.
|
||||
|
||||
* @throws InvalidArgumentException if num bits is not between 0 and 32
|
||||
*/
|
||||
public function appendBits(int $value, int $numBits) : void
|
||||
{
|
||||
if ($numBits < 0 || $numBits > 32) {
|
||||
throw new InvalidArgumentException('Num bits must be between 0 and 32');
|
||||
}
|
||||
|
||||
$this->ensureCapacity($this->size + $numBits);
|
||||
|
||||
for ($numBitsLeft = $numBits; $numBitsLeft > 0; $numBitsLeft--) {
|
||||
$this->appendBit((($value >> ($numBitsLeft - 1)) & 0x01) === 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends another bit array to this array.
|
||||
*/
|
||||
public function appendBitArray(self $other) : void
|
||||
{
|
||||
$otherSize = $other->getSize();
|
||||
$this->ensureCapacity($this->size + $other->getSize());
|
||||
|
||||
for ($i = 0; $i < $otherSize; ++$i) {
|
||||
$this->appendBit($other->get($i));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes an exclusive-or comparision on the current bit array.
|
||||
*
|
||||
* @throws InvalidArgumentException if sizes don't match
|
||||
*/
|
||||
public function xorBits(self $other) : void
|
||||
{
|
||||
$bitsLength = count($this->bits);
|
||||
$otherBits = $other->getBitArray();
|
||||
|
||||
if ($bitsLength !== count($otherBits)) {
|
||||
throw new InvalidArgumentException('Sizes don\'t match');
|
||||
}
|
||||
|
||||
for ($i = 0; $i < $bitsLength; ++$i) {
|
||||
$this->bits[$i] = $this->bits[$i] ^ $otherBits[$i];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the bit array to a byte array.
|
||||
*
|
||||
* @return SplFixedArray<int>
|
||||
*/
|
||||
public function toBytes(int $bitOffset, int $numBytes) : SplFixedArray
|
||||
{
|
||||
$bytes = new SplFixedArray($numBytes);
|
||||
|
||||
for ($i = 0; $i < $numBytes; ++$i) {
|
||||
$byte = 0;
|
||||
|
||||
for ($j = 0; $j < 8; ++$j) {
|
||||
if ($this->get($bitOffset)) {
|
||||
$byte |= 1 << (7 - $j);
|
||||
}
|
||||
|
||||
++$bitOffset;
|
||||
}
|
||||
|
||||
$bytes[$i] = $byte;
|
||||
}
|
||||
|
||||
return $bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the internal bit array.
|
||||
*
|
||||
* @return SplFixedArray<int>
|
||||
*/
|
||||
public function getBitArray() : SplFixedArray
|
||||
{
|
||||
return $this->bits;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverses the array.
|
||||
*/
|
||||
public function reverse() : void
|
||||
{
|
||||
$newBits = new SplFixedArray(count($this->bits));
|
||||
|
||||
for ($i = 0; $i < $this->size; ++$i) {
|
||||
if ($this->get($this->size - $i - 1)) {
|
||||
$newBits[$i >> 5] = $newBits[$i >> 5] | (1 << ($i & 0x1f));
|
||||
}
|
||||
}
|
||||
|
||||
$this->bits = $newBits;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of the bit array.
|
||||
*/
|
||||
public function __toString() : string
|
||||
{
|
||||
$result = '';
|
||||
|
||||
for ($i = 0; $i < $this->size; ++$i) {
|
||||
if (0 === ($i & 0x07)) {
|
||||
$result .= ' ';
|
||||
}
|
||||
|
||||
$result .= $this->get($i) ? 'X' : '.';
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
313
vendor/bacon/bacon-qr-code/src/Common/BitMatrix.php
vendored
Normal file
313
vendor/bacon/bacon-qr-code/src/Common/BitMatrix.php
vendored
Normal file
@ -0,0 +1,313 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace BaconQrCode\Common;
|
||||
|
||||
use BaconQrCode\Exception\InvalidArgumentException;
|
||||
use SplFixedArray;
|
||||
|
||||
/**
|
||||
* Bit matrix.
|
||||
*
|
||||
* Represents a 2D matrix of bits. In function arguments below, and throughout
|
||||
* the common module, x is the column position, and y is the row position. The
|
||||
* ordering is always x, y. The origin is at the top-left.
|
||||
*/
|
||||
class BitMatrix
|
||||
{
|
||||
/**
|
||||
* Width of the bit matrix.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $width;
|
||||
|
||||
/**
|
||||
* Height of the bit matrix.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $height;
|
||||
|
||||
/**
|
||||
* Size in bits of each individual row.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $rowSize;
|
||||
|
||||
/**
|
||||
* Bits representation.
|
||||
*
|
||||
* @var SplFixedArray<int>
|
||||
*/
|
||||
private $bits;
|
||||
|
||||
/**
|
||||
* @throws InvalidArgumentException if a dimension is smaller than zero
|
||||
*/
|
||||
public function __construct(int $width, int $height = null)
|
||||
{
|
||||
if (null === $height) {
|
||||
$height = $width;
|
||||
}
|
||||
|
||||
if ($width < 1 || $height < 1) {
|
||||
throw new InvalidArgumentException('Both dimensions must be greater than zero');
|
||||
}
|
||||
|
||||
$this->width = $width;
|
||||
$this->height = $height;
|
||||
$this->rowSize = ($width + 31) >> 5;
|
||||
$this->bits = SplFixedArray::fromArray(array_fill(0, $this->rowSize * $height, 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the requested bit, where true means black.
|
||||
*/
|
||||
public function get(int $x, int $y) : bool
|
||||
{
|
||||
$offset = $y * $this->rowSize + ($x >> 5);
|
||||
return 0 !== (BitUtils::unsignedRightShift($this->bits[$offset], ($x & 0x1f)) & 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the given bit to true.
|
||||
*/
|
||||
public function set(int $x, int $y) : void
|
||||
{
|
||||
$offset = $y * $this->rowSize + ($x >> 5);
|
||||
$this->bits[$offset] = $this->bits[$offset] | (1 << ($x & 0x1f));
|
||||
}
|
||||
|
||||
/**
|
||||
* Flips the given bit.
|
||||
*/
|
||||
public function flip(int $x, int $y) : void
|
||||
{
|
||||
$offset = $y * $this->rowSize + ($x >> 5);
|
||||
$this->bits[$offset] = $this->bits[$offset] ^ (1 << ($x & 0x1f));
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all bits (set to false).
|
||||
*/
|
||||
public function clear() : void
|
||||
{
|
||||
$max = count($this->bits);
|
||||
|
||||
for ($i = 0; $i < $max; ++$i) {
|
||||
$this->bits[$i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a square region of the bit matrix to true.
|
||||
*
|
||||
* @throws InvalidArgumentException if left or top are negative
|
||||
* @throws InvalidArgumentException if width or height are smaller than 1
|
||||
* @throws InvalidArgumentException if region does not fit into the matix
|
||||
*/
|
||||
public function setRegion(int $left, int $top, int $width, int $height) : void
|
||||
{
|
||||
if ($top < 0 || $left < 0) {
|
||||
throw new InvalidArgumentException('Left and top must be non-negative');
|
||||
}
|
||||
|
||||
if ($height < 1 || $width < 1) {
|
||||
throw new InvalidArgumentException('Width and height must be at least 1');
|
||||
}
|
||||
|
||||
$right = $left + $width;
|
||||
$bottom = $top + $height;
|
||||
|
||||
if ($bottom > $this->height || $right > $this->width) {
|
||||
throw new InvalidArgumentException('The region must fit inside the matrix');
|
||||
}
|
||||
|
||||
for ($y = $top; $y < $bottom; ++$y) {
|
||||
$offset = $y * $this->rowSize;
|
||||
|
||||
for ($x = $left; $x < $right; ++$x) {
|
||||
$index = $offset + ($x >> 5);
|
||||
$this->bits[$index] = $this->bits[$index] | (1 << ($x & 0x1f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A fast method to retrieve one row of data from the matrix as a BitArray.
|
||||
*/
|
||||
public function getRow(int $y, BitArray $row = null) : BitArray
|
||||
{
|
||||
if (null === $row || $row->getSize() < $this->width) {
|
||||
$row = new BitArray($this->width);
|
||||
}
|
||||
|
||||
$offset = $y * $this->rowSize;
|
||||
|
||||
for ($x = 0; $x < $this->rowSize; ++$x) {
|
||||
$row->setBulk($x << 5, $this->bits[$offset + $x]);
|
||||
}
|
||||
|
||||
return $row;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a row of data from a BitArray.
|
||||
*/
|
||||
public function setRow(int $y, BitArray $row) : void
|
||||
{
|
||||
$bits = $row->getBitArray();
|
||||
|
||||
for ($i = 0; $i < $this->rowSize; ++$i) {
|
||||
$this->bits[$y * $this->rowSize + $i] = $bits[$i];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is useful in detecting the enclosing rectangle of a 'pure' barcode.
|
||||
*
|
||||
* @return int[]|null
|
||||
*/
|
||||
public function getEnclosingRectangle() : ?array
|
||||
{
|
||||
$left = $this->width;
|
||||
$top = $this->height;
|
||||
$right = -1;
|
||||
$bottom = -1;
|
||||
|
||||
for ($y = 0; $y < $this->height; ++$y) {
|
||||
for ($x32 = 0; $x32 < $this->rowSize; ++$x32) {
|
||||
$bits = $this->bits[$y * $this->rowSize + $x32];
|
||||
|
||||
if (0 !== $bits) {
|
||||
if ($y < $top) {
|
||||
$top = $y;
|
||||
}
|
||||
|
||||
if ($y > $bottom) {
|
||||
$bottom = $y;
|
||||
}
|
||||
|
||||
if ($x32 * 32 < $left) {
|
||||
$bit = 0;
|
||||
|
||||
while (($bits << (31 - $bit)) === 0) {
|
||||
$bit++;
|
||||
}
|
||||
|
||||
if (($x32 * 32 + $bit) < $left) {
|
||||
$left = $x32 * 32 + $bit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($x32 * 32 + 31 > $right) {
|
||||
$bit = 31;
|
||||
|
||||
while (0 === BitUtils::unsignedRightShift($bits, $bit)) {
|
||||
--$bit;
|
||||
}
|
||||
|
||||
if (($x32 * 32 + $bit) > $right) {
|
||||
$right = $x32 * 32 + $bit;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$width = $right - $left;
|
||||
$height = $bottom - $top;
|
||||
|
||||
if ($width < 0 || $height < 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return [$left, $top, $width, $height];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the most top left set bit.
|
||||
*
|
||||
* This is useful in detecting a corner of a 'pure' barcode.
|
||||
*
|
||||
* @return int[]|null
|
||||
*/
|
||||
public function getTopLeftOnBit() : ?array
|
||||
{
|
||||
$bitsOffset = 0;
|
||||
|
||||
while ($bitsOffset < count($this->bits) && 0 === $this->bits[$bitsOffset]) {
|
||||
++$bitsOffset;
|
||||
}
|
||||
|
||||
if (count($this->bits) === $bitsOffset) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$x = intdiv($bitsOffset, $this->rowSize);
|
||||
$y = ($bitsOffset % $this->rowSize) << 5;
|
||||
|
||||
$bits = $this->bits[$bitsOffset];
|
||||
$bit = 0;
|
||||
|
||||
while (0 === ($bits << (31 - $bit))) {
|
||||
++$bit;
|
||||
}
|
||||
|
||||
$x += $bit;
|
||||
|
||||
return [$x, $y];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the most bottom right set bit.
|
||||
*
|
||||
* This is useful in detecting a corner of a 'pure' barcode.
|
||||
*
|
||||
* @return int[]|null
|
||||
*/
|
||||
public function getBottomRightOnBit() : ?array
|
||||
{
|
||||
$bitsOffset = count($this->bits) - 1;
|
||||
|
||||
while ($bitsOffset >= 0 && 0 === $this->bits[$bitsOffset]) {
|
||||
--$bitsOffset;
|
||||
}
|
||||
|
||||
if ($bitsOffset < 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$x = intdiv($bitsOffset, $this->rowSize);
|
||||
$y = ($bitsOffset % $this->rowSize) << 5;
|
||||
|
||||
$bits = $this->bits[$bitsOffset];
|
||||
$bit = 0;
|
||||
|
||||
while (0 === BitUtils::unsignedRightShift($bits, $bit)) {
|
||||
--$bit;
|
||||
}
|
||||
|
||||
$x += $bit;
|
||||
|
||||
return [$x, $y];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the width of the matrix,
|
||||
*/
|
||||
public function getWidth() : int
|
||||
{
|
||||
return $this->width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the height of the matrix.
|
||||
*/
|
||||
public function getHeight() : int
|
||||
{
|
||||
return $this->height;
|
||||
}
|
||||
}
|
41
vendor/bacon/bacon-qr-code/src/Common/BitUtils.php
vendored
Normal file
41
vendor/bacon/bacon-qr-code/src/Common/BitUtils.php
vendored
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace BaconQrCode\Common;
|
||||
|
||||
/**
|
||||
* General bit utilities.
|
||||
*
|
||||
* All utility methods are based on 32-bit integers and also work on 64-bit
|
||||
* systems.
|
||||
*/
|
||||
final class BitUtils
|
||||
{
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs an unsigned right shift.
|
||||
*
|
||||
* This is the same as the unsigned right shift operator ">>>" in other
|
||||
* languages.
|
||||
*/
|
||||
public static function unsignedRightShift(int $a, int $b) : int
|
||||
{
|
||||
return (
|
||||
$a >= 0
|
||||
? $a >> $b
|
||||
: (($a & 0x7fffffff) >> $b) | (0x40000000 >> ($b - 1))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of trailing zeros.
|
||||
*/
|
||||
public static function numberOfTrailingZeros(int $i) : int
|
||||
{
|
||||
$lastPos = strrpos(str_pad(decbin($i), 32, '0', STR_PAD_LEFT), '1');
|
||||
return $lastPos === false ? 32 : 31 - $lastPos;
|
||||
}
|
||||
}
|
180
vendor/bacon/bacon-qr-code/src/Common/CharacterSetEci.php
vendored
Normal file
180
vendor/bacon/bacon-qr-code/src/Common/CharacterSetEci.php
vendored
Normal file
@ -0,0 +1,180 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace BaconQrCode\Common;
|
||||
|
||||
use BaconQrCode\Exception\InvalidArgumentException;
|
||||
use DASPRiD\Enum\AbstractEnum;
|
||||
|
||||
/**
|
||||
* Encapsulates a Character Set ECI, according to "Extended Channel Interpretations" 5.3.1.1 of ISO 18004.
|
||||
*
|
||||
* @method static self CP437()
|
||||
* @method static self ISO8859_1()
|
||||
* @method static self ISO8859_2()
|
||||
* @method static self ISO8859_3()
|
||||
* @method static self ISO8859_4()
|
||||
* @method static self ISO8859_5()
|
||||
* @method static self ISO8859_6()
|
||||
* @method static self ISO8859_7()
|
||||
* @method static self ISO8859_8()
|
||||
* @method static self ISO8859_9()
|
||||
* @method static self ISO8859_10()
|
||||
* @method static self ISO8859_11()
|
||||
* @method static self ISO8859_12()
|
||||
* @method static self ISO8859_13()
|
||||
* @method static self ISO8859_14()
|
||||
* @method static self ISO8859_15()
|
||||
* @method static self ISO8859_16()
|
||||
* @method static self SJIS()
|
||||
* @method static self CP1250()
|
||||
* @method static self CP1251()
|
||||
* @method static self CP1252()
|
||||
* @method static self CP1256()
|
||||
* @method static self UNICODE_BIG_UNMARKED()
|
||||
* @method static self UTF8()
|
||||
* @method static self ASCII()
|
||||
* @method static self BIG5()
|
||||
* @method static self GB18030()
|
||||
* @method static self EUC_KR()
|
||||
*/
|
||||
final class CharacterSetEci extends AbstractEnum
|
||||
{
|
||||
protected const CP437 = [[0, 2]];
|
||||
protected const ISO8859_1 = [[1, 3], 'ISO-8859-1'];
|
||||
protected const ISO8859_2 = [[4], 'ISO-8859-2'];
|
||||
protected const ISO8859_3 = [[5], 'ISO-8859-3'];
|
||||
protected const ISO8859_4 = [[6], 'ISO-8859-4'];
|
||||
protected const ISO8859_5 = [[7], 'ISO-8859-5'];
|
||||
protected const ISO8859_6 = [[8], 'ISO-8859-6'];
|
||||
protected const ISO8859_7 = [[9], 'ISO-8859-7'];
|
||||
protected const ISO8859_8 = [[10], 'ISO-8859-8'];
|
||||
protected const ISO8859_9 = [[11], 'ISO-8859-9'];
|
||||
protected const ISO8859_10 = [[12], 'ISO-8859-10'];
|
||||
protected const ISO8859_11 = [[13], 'ISO-8859-11'];
|
||||
protected const ISO8859_12 = [[14], 'ISO-8859-12'];
|
||||
protected const ISO8859_13 = [[15], 'ISO-8859-13'];
|
||||
protected const ISO8859_14 = [[16], 'ISO-8859-14'];
|
||||
protected const ISO8859_15 = [[17], 'ISO-8859-15'];
|
||||
protected const ISO8859_16 = [[18], 'ISO-8859-16'];
|
||||
protected const SJIS = [[20], 'Shift_JIS'];
|
||||
protected const CP1250 = [[21], 'windows-1250'];
|
||||
protected const CP1251 = [[22], 'windows-1251'];
|
||||
protected const CP1252 = [[23], 'windows-1252'];
|
||||
protected const CP1256 = [[24], 'windows-1256'];
|
||||
protected const UNICODE_BIG_UNMARKED = [[25], 'UTF-16BE', 'UnicodeBig'];
|
||||
protected const UTF8 = [[26], 'UTF-8'];
|
||||
protected const ASCII = [[27, 170], 'US-ASCII'];
|
||||
protected const BIG5 = [[28]];
|
||||
protected const GB18030 = [[29], 'GB2312', 'EUC_CN', 'GBK'];
|
||||
protected const EUC_KR = [[30], 'EUC-KR'];
|
||||
|
||||
/**
|
||||
* @var int[]
|
||||
*/
|
||||
private $values;
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
private $otherEncodingNames;
|
||||
|
||||
/**
|
||||
* @var array<int, self>|null
|
||||
*/
|
||||
private static $valueToEci;
|
||||
|
||||
/**
|
||||
* @var array<string, self>|null
|
||||
*/
|
||||
private static $nameToEci;
|
||||
|
||||
public function __construct(array $values, string ...$otherEncodingNames)
|
||||
{
|
||||
$this->values = $values;
|
||||
$this->otherEncodingNames = $otherEncodingNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the primary value.
|
||||
*/
|
||||
public function getValue() : int
|
||||
{
|
||||
return $this->values[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets character set ECI by value.
|
||||
*
|
||||
* Returns the representing ECI of a given value, or null if it is legal but unsupported.
|
||||
*
|
||||
* @throws InvalidArgumentException if value is not between 0 and 900
|
||||
*/
|
||||
public static function getCharacterSetEciByValue(int $value) : ?self
|
||||
{
|
||||
if ($value < 0 || $value >= 900) {
|
||||
throw new InvalidArgumentException('Value must be between 0 and 900');
|
||||
}
|
||||
|
||||
$valueToEci = self::valueToEci();
|
||||
|
||||
if (! array_key_exists($value, $valueToEci)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $valueToEci[$value];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns character set ECI by name.
|
||||
*
|
||||
* Returns the representing ECI of a given name, or null if it is legal but unsupported
|
||||
*/
|
||||
public static function getCharacterSetEciByName(string $name) : ?self
|
||||
{
|
||||
$nameToEci = self::nameToEci();
|
||||
$name = strtolower($name);
|
||||
|
||||
if (! array_key_exists($name, $nameToEci)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $nameToEci[$name];
|
||||
}
|
||||
|
||||
private static function valueToEci() : array
|
||||
{
|
||||
if (null !== self::$valueToEci) {
|
||||
return self::$valueToEci;
|
||||
}
|
||||
|
||||
self::$valueToEci = [];
|
||||
|
||||
foreach (self::values() as $eci) {
|
||||
foreach ($eci->values as $value) {
|
||||
self::$valueToEci[$value] = $eci;
|
||||
}
|
||||
}
|
||||
|
||||
return self::$valueToEci;
|
||||
}
|
||||
|
||||
private static function nameToEci() : array
|
||||
{
|
||||
if (null !== self::$nameToEci) {
|
||||
return self::$nameToEci;
|
||||
}
|
||||
|
||||
self::$nameToEci = [];
|
||||
|
||||
foreach (self::values() as $eci) {
|
||||
self::$nameToEci[strtolower($eci->name())] = $eci;
|
||||
|
||||
foreach ($eci->otherEncodingNames as $name) {
|
||||
self::$nameToEci[strtolower($name)] = $eci;
|
||||
}
|
||||
}
|
||||
|
||||
return self::$nameToEci;
|
||||
}
|
||||
}
|
49
vendor/bacon/bacon-qr-code/src/Common/EcBlock.php
vendored
Normal file
49
vendor/bacon/bacon-qr-code/src/Common/EcBlock.php
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace BaconQrCode\Common;
|
||||
|
||||
/**
|
||||
* Encapsulates the parameters for one error-correction block in one symbol version.
|
||||
*
|
||||
* This includes the number of data codewords, and the number of times a block with these parameters is used
|
||||
* consecutively in the QR code version's format.
|
||||
*/
|
||||
final class EcBlock
|
||||
{
|
||||
/**
|
||||
* How many times the block is used.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $count;
|
||||
|
||||
/**
|
||||
* Number of data codewords.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $dataCodewords;
|
||||
|
||||
public function __construct(int $count, int $dataCodewords)
|
||||
{
|
||||
$this->count = $count;
|
||||
$this->dataCodewords = $dataCodewords;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns how many times the block is used.
|
||||
*/
|
||||
public function getCount() : int
|
||||
{
|
||||
return $this->count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of data codewords.
|
||||
*/
|
||||
public function getDataCodewords() : int
|
||||
{
|
||||
return $this->dataCodewords;
|
||||
}
|
||||
}
|
74
vendor/bacon/bacon-qr-code/src/Common/EcBlocks.php
vendored
Normal file
74
vendor/bacon/bacon-qr-code/src/Common/EcBlocks.php
vendored
Normal file
@ -0,0 +1,74 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace BaconQrCode\Common;
|
||||
|
||||
/**
|
||||
* Encapsulates a set of error-correction blocks in one symbol version.
|
||||
*
|
||||
* Most versions will use blocks of differing sizes within one version, so, this encapsulates the parameters for each
|
||||
* set of blocks. It also holds the number of error-correction codewords per block since it will be the same across all
|
||||
* blocks within one version.
|
||||
*/
|
||||
final class EcBlocks
|
||||
{
|
||||
/**
|
||||
* Number of EC codewords per block.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $ecCodewordsPerBlock;
|
||||
|
||||
/**
|
||||
* List of EC blocks.
|
||||
*
|
||||
* @var EcBlock[]
|
||||
*/
|
||||
private $ecBlocks;
|
||||
|
||||
public function __construct(int $ecCodewordsPerBlock, EcBlock ...$ecBlocks)
|
||||
{
|
||||
$this->ecCodewordsPerBlock = $ecCodewordsPerBlock;
|
||||
$this->ecBlocks = $ecBlocks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of EC codewords per block.
|
||||
*/
|
||||
public function getEcCodewordsPerBlock() : int
|
||||
{
|
||||
return $this->ecCodewordsPerBlock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the total number of EC block appearances.
|
||||
*/
|
||||
public function getNumBlocks() : int
|
||||
{
|
||||
$total = 0;
|
||||
|
||||
foreach ($this->ecBlocks as $ecBlock) {
|
||||
$total += $ecBlock->getCount();
|
||||
}
|
||||
|
||||
return $total;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the total count of EC codewords.
|
||||
*/
|
||||
public function getTotalEcCodewords() : int
|
||||
{
|
||||
return $this->ecCodewordsPerBlock * $this->getNumBlocks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the EC blocks included in this collection.
|
||||
*
|
||||
* @return EcBlock[]
|
||||
*/
|
||||
public function getEcBlocks() : array
|
||||
{
|
||||
return $this->ecBlocks;
|
||||
}
|
||||
}
|
63
vendor/bacon/bacon-qr-code/src/Common/ErrorCorrectionLevel.php
vendored
Normal file
63
vendor/bacon/bacon-qr-code/src/Common/ErrorCorrectionLevel.php
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace BaconQrCode\Common;
|
||||
|
||||
use BaconQrCode\Exception\OutOfBoundsException;
|
||||
use DASPRiD\Enum\AbstractEnum;
|
||||
|
||||
/**
|
||||
* Enum representing the four error correction levels.
|
||||
*
|
||||
* @method static self L() ~7% correction
|
||||
* @method static self M() ~15% correction
|
||||
* @method static self Q() ~25% correction
|
||||
* @method static self H() ~30% correction
|
||||
*/
|
||||
final class ErrorCorrectionLevel extends AbstractEnum
|
||||
{
|
||||
protected const L = [0x01];
|
||||
protected const M = [0x00];
|
||||
protected const Q = [0x03];
|
||||
protected const H = [0x02];
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $bits;
|
||||
|
||||
protected function __construct(int $bits)
|
||||
{
|
||||
$this->bits = $bits;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws OutOfBoundsException if number of bits is invalid
|
||||
*/
|
||||
public static function forBits(int $bits) : self
|
||||
{
|
||||
switch ($bits) {
|
||||
case 0:
|
||||
return self::M();
|
||||
|
||||
case 1:
|
||||
return self::L();
|
||||
|
||||
case 2:
|
||||
return self::H();
|
||||
|
||||
case 3:
|
||||
return self::Q();
|
||||
}
|
||||
|
||||
throw new OutOfBoundsException('Invalid number of bits');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the two bits used to encode this error correction level.
|
||||
*/
|
||||
public function getBits() : int
|
||||
{
|
||||
return $this->bits;
|
||||
}
|
||||
}
|
203
vendor/bacon/bacon-qr-code/src/Common/FormatInformation.php
vendored
Normal file
203
vendor/bacon/bacon-qr-code/src/Common/FormatInformation.php
vendored
Normal file
@ -0,0 +1,203 @@
|
||||
<?php
|
||||
/**
|
||||
* BaconQrCode
|
||||
*
|
||||
* @link http://github.com/Bacon/BaconQrCode For the canonical source repository
|
||||
* @copyright 2013 Ben 'DASPRiD' Scholzen
|
||||
* @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
|
||||
*/
|
||||
|
||||
namespace BaconQrCode\Common;
|
||||
|
||||
/**
|
||||
* Encapsulates a QR Code's format information, including the data mask used and error correction level.
|
||||
*/
|
||||
class FormatInformation
|
||||
{
|
||||
/**
|
||||
* Mask for format information.
|
||||
*/
|
||||
private const FORMAT_INFO_MASK_QR = 0x5412;
|
||||
|
||||
/**
|
||||
* Lookup table for decoding format information.
|
||||
*
|
||||
* See ISO 18004:2006, Annex C, Table C.1
|
||||
*/
|
||||
private const FORMAT_INFO_DECODE_LOOKUP = [
|
||||
[0x5412, 0x00],
|
||||
[0x5125, 0x01],
|
||||
[0x5e7c, 0x02],
|
||||
[0x5b4b, 0x03],
|
||||
[0x45f9, 0x04],
|
||||
[0x40ce, 0x05],
|
||||
[0x4f97, 0x06],
|
||||
[0x4aa0, 0x07],
|
||||
[0x77c4, 0x08],
|
||||
[0x72f3, 0x09],
|
||||
[0x7daa, 0x0a],
|
||||
[0x789d, 0x0b],
|
||||
[0x662f, 0x0c],
|
||||
[0x6318, 0x0d],
|
||||
[0x6c41, 0x0e],
|
||||
[0x6976, 0x0f],
|
||||
[0x1689, 0x10],
|
||||
[0x13be, 0x11],
|
||||
[0x1ce7, 0x12],
|
||||
[0x19d0, 0x13],
|
||||
[0x0762, 0x14],
|
||||
[0x0255, 0x15],
|
||||
[0x0d0c, 0x16],
|
||||
[0x083b, 0x17],
|
||||
[0x355f, 0x18],
|
||||
[0x3068, 0x19],
|
||||
[0x3f31, 0x1a],
|
||||
[0x3a06, 0x1b],
|
||||
[0x24b4, 0x1c],
|
||||
[0x2183, 0x1d],
|
||||
[0x2eda, 0x1e],
|
||||
[0x2bed, 0x1f],
|
||||
];
|
||||
|
||||
/**
|
||||
* Offset i holds the number of 1 bits in the binary representation of i.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private const BITS_SET_IN_HALF_BYTE = [0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4];
|
||||
|
||||
/**
|
||||
* Error correction level.
|
||||
*
|
||||
* @var ErrorCorrectionLevel
|
||||
*/
|
||||
private $ecLevel;
|
||||
|
||||
/**
|
||||
* Data mask.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $dataMask;
|
||||
|
||||
protected function __construct(int $formatInfo)
|
||||
{
|
||||
$this->ecLevel = ErrorCorrectionLevel::forBits(($formatInfo >> 3) & 0x3);
|
||||
$this->dataMask = $formatInfo & 0x7;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks how many bits are different between two integers.
|
||||
*/
|
||||
public static function numBitsDiffering(int $a, int $b) : int
|
||||
{
|
||||
$a ^= $b;
|
||||
|
||||
return (
|
||||
self::BITS_SET_IN_HALF_BYTE[$a & 0xf]
|
||||
+ self::BITS_SET_IN_HALF_BYTE[(BitUtils::unsignedRightShift($a, 4) & 0xf)]
|
||||
+ self::BITS_SET_IN_HALF_BYTE[(BitUtils::unsignedRightShift($a, 8) & 0xf)]
|
||||
+ self::BITS_SET_IN_HALF_BYTE[(BitUtils::unsignedRightShift($a, 12) & 0xf)]
|
||||
+ self::BITS_SET_IN_HALF_BYTE[(BitUtils::unsignedRightShift($a, 16) & 0xf)]
|
||||
+ self::BITS_SET_IN_HALF_BYTE[(BitUtils::unsignedRightShift($a, 20) & 0xf)]
|
||||
+ self::BITS_SET_IN_HALF_BYTE[(BitUtils::unsignedRightShift($a, 24) & 0xf)]
|
||||
+ self::BITS_SET_IN_HALF_BYTE[(BitUtils::unsignedRightShift($a, 28) & 0xf)]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes format information.
|
||||
*/
|
||||
public static function decodeFormatInformation(int $maskedFormatInfo1, int $maskedFormatInfo2) : ?self
|
||||
{
|
||||
$formatInfo = self::doDecodeFormatInformation($maskedFormatInfo1, $maskedFormatInfo2);
|
||||
|
||||
if (null !== $formatInfo) {
|
||||
return $formatInfo;
|
||||
}
|
||||
|
||||
// Should return null, but, some QR codes apparently do not mask this info. Try again by actually masking the
|
||||
// pattern first.
|
||||
return self::doDecodeFormatInformation(
|
||||
$maskedFormatInfo1 ^ self::FORMAT_INFO_MASK_QR,
|
||||
$maskedFormatInfo2 ^ self::FORMAT_INFO_MASK_QR
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method for decoding format information.
|
||||
*/
|
||||
private static function doDecodeFormatInformation(int $maskedFormatInfo1, int $maskedFormatInfo2) : ?self
|
||||
{
|
||||
$bestDifference = PHP_INT_MAX;
|
||||
$bestFormatInfo = 0;
|
||||
|
||||
foreach (self::FORMAT_INFO_DECODE_LOOKUP as $decodeInfo) {
|
||||
$targetInfo = $decodeInfo[0];
|
||||
|
||||
if ($targetInfo === $maskedFormatInfo1 || $targetInfo === $maskedFormatInfo2) {
|
||||
// Found an exact match
|
||||
return new self($decodeInfo[1]);
|
||||
}
|
||||
|
||||
$bitsDifference = self::numBitsDiffering($maskedFormatInfo1, $targetInfo);
|
||||
|
||||
if ($bitsDifference < $bestDifference) {
|
||||
$bestFormatInfo = $decodeInfo[1];
|
||||
$bestDifference = $bitsDifference;
|
||||
}
|
||||
|
||||
if ($maskedFormatInfo1 !== $maskedFormatInfo2) {
|
||||
// Also try the other option
|
||||
$bitsDifference = self::numBitsDiffering($maskedFormatInfo2, $targetInfo);
|
||||
|
||||
if ($bitsDifference < $bestDifference) {
|
||||
$bestFormatInfo = $decodeInfo[1];
|
||||
$bestDifference = $bitsDifference;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Hamming distance of the 32 masked codes is 7, by construction, so <= 3 bits differing means we found a match.
|
||||
if ($bestDifference <= 3) {
|
||||
return new self($bestFormatInfo);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the error correction level.
|
||||
*/
|
||||
public function getErrorCorrectionLevel() : ErrorCorrectionLevel
|
||||
{
|
||||
return $this->ecLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data mask.
|
||||
*/
|
||||
public function getDataMask() : int
|
||||
{
|
||||
return $this->dataMask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hashes the code of the EC level.
|
||||
*/
|
||||
public function hashCode() : int
|
||||
{
|
||||
return ($this->ecLevel->getBits() << 3) | $this->dataMask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies if this instance equals another one.
|
||||
*/
|
||||
public function equals(self $other) : bool
|
||||
{
|
||||
return (
|
||||
$this->ecLevel === $other->ecLevel
|
||||
&& $this->dataMask === $other->dataMask
|
||||
);
|
||||
}
|
||||
}
|
76
vendor/bacon/bacon-qr-code/src/Common/Mode.php
vendored
Normal file
76
vendor/bacon/bacon-qr-code/src/Common/Mode.php
vendored
Normal file
@ -0,0 +1,76 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace BaconQrCode\Common;
|
||||
|
||||
use DASPRiD\Enum\AbstractEnum;
|
||||
|
||||
/**
|
||||
* Enum representing various modes in which data can be encoded to bits.
|
||||
*
|
||||
* @method static self TERMINATOR()
|
||||
* @method static self NUMERIC()
|
||||
* @method static self ALPHANUMERIC()
|
||||
* @method static self STRUCTURED_APPEND()
|
||||
* @method static self BYTE()
|
||||
* @method static self ECI()
|
||||
* @method static self KANJI()
|
||||
* @method static self FNC1_FIRST_POSITION()
|
||||
* @method static self FNC1_SECOND_POSITION()
|
||||
* @method static self HANZI()
|
||||
*/
|
||||
final class Mode extends AbstractEnum
|
||||
{
|
||||
protected const TERMINATOR = [[0, 0, 0], 0x00];
|
||||
protected const NUMERIC = [[10, 12, 14], 0x01];
|
||||
protected const ALPHANUMERIC = [[9, 11, 13], 0x02];
|
||||
protected const STRUCTURED_APPEND = [[0, 0, 0], 0x03];
|
||||
protected const BYTE = [[8, 16, 16], 0x04];
|
||||
protected const ECI = [[0, 0, 0], 0x07];
|
||||
protected const KANJI = [[8, 10, 12], 0x08];
|
||||
protected const FNC1_FIRST_POSITION = [[0, 0, 0], 0x05];
|
||||
protected const FNC1_SECOND_POSITION = [[0, 0, 0], 0x09];
|
||||
protected const HANZI = [[8, 10, 12], 0x0d];
|
||||
|
||||
/**
|
||||
* @var int[]
|
||||
*/
|
||||
private $characterCountBitsForVersions;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $bits;
|
||||
|
||||
protected function __construct(array $characterCountBitsForVersions, int $bits)
|
||||
{
|
||||
$this->characterCountBitsForVersions = $characterCountBitsForVersions;
|
||||
$this->bits = $bits;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of bits used in a specific QR code version.
|
||||
*/
|
||||
public function getCharacterCountBits(Version $version) : int
|
||||
{
|
||||
$number = $version->getVersionNumber();
|
||||
|
||||
if ($number <= 9) {
|
||||
$offset = 0;
|
||||
} elseif ($number <= 26) {
|
||||
$offset = 1;
|
||||
} else {
|
||||
$offset = 2;
|
||||
}
|
||||
|
||||
return $this->characterCountBitsForVersions[$offset];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the four bits used to encode this mode.
|
||||
*/
|
||||
public function getBits() : int
|
||||
{
|
||||
return $this->bits;
|
||||
}
|
||||
}
|
468
vendor/bacon/bacon-qr-code/src/Common/ReedSolomonCodec.php
vendored
Normal file
468
vendor/bacon/bacon-qr-code/src/Common/ReedSolomonCodec.php
vendored
Normal file
@ -0,0 +1,468 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace BaconQrCode\Common;
|
||||
|
||||
use BaconQrCode\Exception\InvalidArgumentException;
|
||||
use BaconQrCode\Exception\RuntimeException;
|
||||
use SplFixedArray;
|
||||
|
||||
/**
|
||||
* Reed-Solomon codec for 8-bit characters.
|
||||
*
|
||||
* Based on libfec by Phil Karn, KA9Q.
|
||||
*/
|
||||
final class ReedSolomonCodec
|
||||
{
|
||||
/**
|
||||
* Symbol size in bits.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $symbolSize;
|
||||
|
||||
/**
|
||||
* Block size in symbols.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $blockSize;
|
||||
|
||||
/**
|
||||
* First root of RS code generator polynomial, index form.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $firstRoot;
|
||||
|
||||
/**
|
||||
* Primitive element to generate polynomial roots, index form.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $primitive;
|
||||
|
||||
/**
|
||||
* Prim-th root of 1, index form.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $iPrimitive;
|
||||
|
||||
/**
|
||||
* RS code generator polynomial degree (number of roots).
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $numRoots;
|
||||
|
||||
/**
|
||||
* Padding bytes at front of shortened block.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $padding;
|
||||
|
||||
/**
|
||||
* Log lookup table.
|
||||
*
|
||||
* @var SplFixedArray
|
||||
*/
|
||||
private $alphaTo;
|
||||
|
||||
/**
|
||||
* Anti-Log lookup table.
|
||||
*
|
||||
* @var SplFixedArray
|
||||
*/
|
||||
private $indexOf;
|
||||
|
||||
/**
|
||||
* Generator polynomial.
|
||||
*
|
||||
* @var SplFixedArray
|
||||
*/
|
||||
private $generatorPoly;
|
||||
|
||||
/**
|
||||
* @throws InvalidArgumentException if symbol size ist not between 0 and 8
|
||||
* @throws InvalidArgumentException if first root is invalid
|
||||
* @throws InvalidArgumentException if num roots is invalid
|
||||
* @throws InvalidArgumentException if padding is invalid
|
||||
* @throws RuntimeException if field generator polynomial is not primitive
|
||||
*/
|
||||
public function __construct(
|
||||
int $symbolSize,
|
||||
int $gfPoly,
|
||||
int $firstRoot,
|
||||
int $primitive,
|
||||
int $numRoots,
|
||||
int $padding
|
||||
) {
|
||||
if ($symbolSize < 0 || $symbolSize > 8) {
|
||||
throw new InvalidArgumentException('Symbol size must be between 0 and 8');
|
||||
}
|
||||
|
||||
if ($firstRoot < 0 || $firstRoot >= (1 << $symbolSize)) {
|
||||
throw new InvalidArgumentException('First root must be between 0 and ' . (1 << $symbolSize));
|
||||
}
|
||||
|
||||
if ($numRoots < 0 || $numRoots >= (1 << $symbolSize)) {
|
||||
throw new InvalidArgumentException('Num roots must be between 0 and ' . (1 << $symbolSize));
|
||||
}
|
||||
|
||||
if ($padding < 0 || $padding >= ((1 << $symbolSize) - 1 - $numRoots)) {
|
||||
throw new InvalidArgumentException(
|
||||
'Padding must be between 0 and ' . ((1 << $symbolSize) - 1 - $numRoots)
|
||||
);
|
||||
}
|
||||
|
||||
$this->symbolSize = $symbolSize;
|
||||
$this->blockSize = (1 << $symbolSize) - 1;
|
||||
$this->padding = $padding;
|
||||
$this->alphaTo = SplFixedArray::fromArray(array_fill(0, $this->blockSize + 1, 0), false);
|
||||
$this->indexOf = SplFixedArray::fromArray(array_fill(0, $this->blockSize + 1, 0), false);
|
||||
|
||||
// Generate galous field lookup table
|
||||
$this->indexOf[0] = $this->blockSize;
|
||||
$this->alphaTo[$this->blockSize] = 0;
|
||||
|
||||
$sr = 1;
|
||||
|
||||
for ($i = 0; $i < $this->blockSize; ++$i) {
|
||||
$this->indexOf[$sr] = $i;
|
||||
$this->alphaTo[$i] = $sr;
|
||||
|
||||
$sr <<= 1;
|
||||
|
||||
if ($sr & (1 << $symbolSize)) {
|
||||
$sr ^= $gfPoly;
|
||||
}
|
||||
|
||||
$sr &= $this->blockSize;
|
||||
}
|
||||
|
||||
if (1 !== $sr) {
|
||||
throw new RuntimeException('Field generator polynomial is not primitive');
|
||||
}
|
||||
|
||||
// Form RS code generator polynomial from its roots
|
||||
$this->generatorPoly = SplFixedArray::fromArray(array_fill(0, $numRoots + 1, 0), false);
|
||||
$this->firstRoot = $firstRoot;
|
||||
$this->primitive = $primitive;
|
||||
$this->numRoots = $numRoots;
|
||||
|
||||
// Find prim-th root of 1, used in decoding
|
||||
for ($iPrimitive = 1; ($iPrimitive % $primitive) !== 0; $iPrimitive += $this->blockSize) {
|
||||
}
|
||||
|
||||
$this->iPrimitive = intdiv($iPrimitive, $primitive);
|
||||
|
||||
$this->generatorPoly[0] = 1;
|
||||
|
||||
for ($i = 0, $root = $firstRoot * $primitive; $i < $numRoots; ++$i, $root += $primitive) {
|
||||
$this->generatorPoly[$i + 1] = 1;
|
||||
|
||||
for ($j = $i; $j > 0; $j--) {
|
||||
if ($this->generatorPoly[$j] !== 0) {
|
||||
$this->generatorPoly[$j] = $this->generatorPoly[$j - 1] ^ $this->alphaTo[
|
||||
$this->modNn($this->indexOf[$this->generatorPoly[$j]] + $root)
|
||||
];
|
||||
} else {
|
||||
$this->generatorPoly[$j] = $this->generatorPoly[$j - 1];
|
||||
}
|
||||
}
|
||||
|
||||
$this->generatorPoly[$j] = $this->alphaTo[$this->modNn($this->indexOf[$this->generatorPoly[0]] + $root)];
|
||||
}
|
||||
|
||||
// Convert generator poly to index form for quicker encoding
|
||||
for ($i = 0; $i <= $numRoots; ++$i) {
|
||||
$this->generatorPoly[$i] = $this->indexOf[$this->generatorPoly[$i]];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes data and writes result back into parity array.
|
||||
*/
|
||||
public function encode(SplFixedArray $data, SplFixedArray $parity) : void
|
||||
{
|
||||
for ($i = 0; $i < $this->numRoots; ++$i) {
|
||||
$parity[$i] = 0;
|
||||
}
|
||||
|
||||
$iterations = $this->blockSize - $this->numRoots - $this->padding;
|
||||
|
||||
for ($i = 0; $i < $iterations; ++$i) {
|
||||
$feedback = $this->indexOf[$data[$i] ^ $parity[0]];
|
||||
|
||||
if ($feedback !== $this->blockSize) {
|
||||
// Feedback term is non-zero
|
||||
$feedback = $this->modNn($this->blockSize - $this->generatorPoly[$this->numRoots] + $feedback);
|
||||
|
||||
for ($j = 1; $j < $this->numRoots; ++$j) {
|
||||
$parity[$j] = $parity[$j] ^ $this->alphaTo[
|
||||
$this->modNn($feedback + $this->generatorPoly[$this->numRoots - $j])
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
for ($j = 0; $j < $this->numRoots - 1; ++$j) {
|
||||
$parity[$j] = $parity[$j + 1];
|
||||
}
|
||||
|
||||
if ($feedback !== $this->blockSize) {
|
||||
$parity[$this->numRoots - 1] = $this->alphaTo[$this->modNn($feedback + $this->generatorPoly[0])];
|
||||
} else {
|
||||
$parity[$this->numRoots - 1] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes received data.
|
||||
*/
|
||||
public function decode(SplFixedArray $data, SplFixedArray $erasures = null) : ?int
|
||||
{
|
||||
// This speeds up the initialization a bit.
|
||||
$numRootsPlusOne = SplFixedArray::fromArray(array_fill(0, $this->numRoots + 1, 0), false);
|
||||
$numRoots = SplFixedArray::fromArray(array_fill(0, $this->numRoots, 0), false);
|
||||
|
||||
$lambda = clone $numRootsPlusOne;
|
||||
$b = clone $numRootsPlusOne;
|
||||
$t = clone $numRootsPlusOne;
|
||||
$omega = clone $numRootsPlusOne;
|
||||
$root = clone $numRoots;
|
||||
$loc = clone $numRoots;
|
||||
|
||||
$numErasures = (null !== $erasures ? count($erasures) : 0);
|
||||
|
||||
// Form the Syndromes; i.e., evaluate data(x) at roots of g(x)
|
||||
$syndromes = SplFixedArray::fromArray(array_fill(0, $this->numRoots, $data[0]), false);
|
||||
|
||||
for ($i = 1; $i < $this->blockSize - $this->padding; ++$i) {
|
||||
for ($j = 0; $j < $this->numRoots; ++$j) {
|
||||
if ($syndromes[$j] === 0) {
|
||||
$syndromes[$j] = $data[$i];
|
||||
} else {
|
||||
$syndromes[$j] = $data[$i] ^ $this->alphaTo[
|
||||
$this->modNn($this->indexOf[$syndromes[$j]] + ($this->firstRoot + $j) * $this->primitive)
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Convert syndromes to index form, checking for nonzero conditions
|
||||
$syndromeError = 0;
|
||||
|
||||
for ($i = 0; $i < $this->numRoots; ++$i) {
|
||||
$syndromeError |= $syndromes[$i];
|
||||
$syndromes[$i] = $this->indexOf[$syndromes[$i]];
|
||||
}
|
||||
|
||||
if (! $syndromeError) {
|
||||
// If syndrome is zero, data[] is a codeword and there are no errors to correct, so return data[]
|
||||
// unmodified.
|
||||
return 0;
|
||||
}
|
||||
|
||||
$lambda[0] = 1;
|
||||
|
||||
if ($numErasures > 0) {
|
||||
// Init lambda to be the erasure locator polynomial
|
||||
$lambda[1] = $this->alphaTo[$this->modNn($this->primitive * ($this->blockSize - 1 - $erasures[0]))];
|
||||
|
||||
for ($i = 1; $i < $numErasures; ++$i) {
|
||||
$u = $this->modNn($this->primitive * ($this->blockSize - 1 - $erasures[$i]));
|
||||
|
||||
for ($j = $i + 1; $j > 0; --$j) {
|
||||
$tmp = $this->indexOf[$lambda[$j - 1]];
|
||||
|
||||
if ($tmp !== $this->blockSize) {
|
||||
$lambda[$j] = $lambda[$j] ^ $this->alphaTo[$this->modNn($u + $tmp)];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for ($i = 0; $i <= $this->numRoots; ++$i) {
|
||||
$b[$i] = $this->indexOf[$lambda[$i]];
|
||||
}
|
||||
|
||||
// Begin Berlekamp-Massey algorithm to determine error+erasure locator polynomial
|
||||
$r = $numErasures;
|
||||
$el = $numErasures;
|
||||
|
||||
while (++$r <= $this->numRoots) {
|
||||
// Compute discrepancy at the r-th step in poly form
|
||||
$discrepancyR = 0;
|
||||
|
||||
for ($i = 0; $i < $r; ++$i) {
|
||||
if ($lambda[$i] !== 0 && $syndromes[$r - $i - 1] !== $this->blockSize) {
|
||||
$discrepancyR ^= $this->alphaTo[
|
||||
$this->modNn($this->indexOf[$lambda[$i]] + $syndromes[$r - $i - 1])
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$discrepancyR = $this->indexOf[$discrepancyR];
|
||||
|
||||
if ($discrepancyR === $this->blockSize) {
|
||||
$tmp = $b->toArray();
|
||||
array_unshift($tmp, $this->blockSize);
|
||||
array_pop($tmp);
|
||||
$b = SplFixedArray::fromArray($tmp, false);
|
||||
continue;
|
||||
}
|
||||
|
||||
$t[0] = $lambda[0];
|
||||
|
||||
for ($i = 0; $i < $this->numRoots; ++$i) {
|
||||
if ($b[$i] !== $this->blockSize) {
|
||||
$t[$i + 1] = $lambda[$i + 1] ^ $this->alphaTo[$this->modNn($discrepancyR + $b[$i])];
|
||||
} else {
|
||||
$t[$i + 1] = $lambda[$i + 1];
|
||||
}
|
||||
}
|
||||
|
||||
if (2 * $el <= $r + $numErasures - 1) {
|
||||
$el = $r + $numErasures - $el;
|
||||
|
||||
for ($i = 0; $i <= $this->numRoots; ++$i) {
|
||||
$b[$i] = (
|
||||
$lambda[$i] === 0
|
||||
? $this->blockSize
|
||||
: $this->modNn($this->indexOf[$lambda[$i]] - $discrepancyR + $this->blockSize)
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$tmp = $b->toArray();
|
||||
array_unshift($tmp, $this->blockSize);
|
||||
array_pop($tmp);
|
||||
$b = SplFixedArray::fromArray($tmp, false);
|
||||
}
|
||||
|
||||
$lambda = clone $t;
|
||||
}
|
||||
|
||||
// Convert lambda to index form and compute deg(lambda(x))
|
||||
$degLambda = 0;
|
||||
|
||||
for ($i = 0; $i <= $this->numRoots; ++$i) {
|
||||
$lambda[$i] = $this->indexOf[$lambda[$i]];
|
||||
|
||||
if ($lambda[$i] !== $this->blockSize) {
|
||||
$degLambda = $i;
|
||||
}
|
||||
}
|
||||
|
||||
// Find roots of the error+erasure locator polynomial by Chien search.
|
||||
$reg = clone $lambda;
|
||||
$reg[0] = 0;
|
||||
$count = 0;
|
||||
$i = 1;
|
||||
|
||||
for ($k = $this->iPrimitive - 1; $i <= $this->blockSize; ++$i, $k = $this->modNn($k + $this->iPrimitive)) {
|
||||
$q = 1;
|
||||
|
||||
for ($j = $degLambda; $j > 0; $j--) {
|
||||
if ($reg[$j] !== $this->blockSize) {
|
||||
$reg[$j] = $this->modNn($reg[$j] + $j);
|
||||
$q ^= $this->alphaTo[$reg[$j]];
|
||||
}
|
||||
}
|
||||
|
||||
if ($q !== 0) {
|
||||
// Not a root
|
||||
continue;
|
||||
}
|
||||
|
||||
// Store root (index-form) and error location number
|
||||
$root[$count] = $i;
|
||||
$loc[$count] = $k;
|
||||
|
||||
if (++$count === $degLambda) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($degLambda !== $count) {
|
||||
// deg(lambda) unequal to number of roots: uncorrectable error detected
|
||||
return null;
|
||||
}
|
||||
|
||||
// Compute err+eras evaluate poly omega(x) = s(x)*lambda(x) (modulo x**numRoots). In index form. Also find
|
||||
// deg(omega).
|
||||
$degOmega = $degLambda - 1;
|
||||
|
||||
for ($i = 0; $i <= $degOmega; ++$i) {
|
||||
$tmp = 0;
|
||||
|
||||
for ($j = $i; $j >= 0; --$j) {
|
||||
if ($syndromes[$i - $j] !== $this->blockSize && $lambda[$j] !== $this->blockSize) {
|
||||
$tmp ^= $this->alphaTo[$this->modNn($syndromes[$i - $j] + $lambda[$j])];
|
||||
}
|
||||
}
|
||||
|
||||
$omega[$i] = $this->indexOf[$tmp];
|
||||
}
|
||||
|
||||
// Compute error values in poly-form. num1 = omega(inv(X(l))), num2 = inv(X(l))**(firstRoot-1) and
|
||||
// den = lambda_pr(inv(X(l))) all in poly form.
|
||||
for ($j = $count - 1; $j >= 0; --$j) {
|
||||
$num1 = 0;
|
||||
|
||||
for ($i = $degOmega; $i >= 0; $i--) {
|
||||
if ($omega[$i] !== $this->blockSize) {
|
||||
$num1 ^= $this->alphaTo[$this->modNn($omega[$i] + $i * $root[$j])];
|
||||
}
|
||||
}
|
||||
|
||||
$num2 = $this->alphaTo[$this->modNn($root[$j] * ($this->firstRoot - 1) + $this->blockSize)];
|
||||
$den = 0;
|
||||
|
||||
// lambda[i+1] for i even is the formal derivativelambda_pr of lambda[i]
|
||||
for ($i = min($degLambda, $this->numRoots - 1) & ~1; $i >= 0; $i -= 2) {
|
||||
if ($lambda[$i + 1] !== $this->blockSize) {
|
||||
$den ^= $this->alphaTo[$this->modNn($lambda[$i + 1] + $i * $root[$j])];
|
||||
}
|
||||
}
|
||||
|
||||
// Apply error to data
|
||||
if ($num1 !== 0 && $loc[$j] >= $this->padding) {
|
||||
$data[$loc[$j] - $this->padding] = $data[$loc[$j] - $this->padding] ^ (
|
||||
$this->alphaTo[
|
||||
$this->modNn(
|
||||
$this->indexOf[$num1] + $this->indexOf[$num2] + $this->blockSize - $this->indexOf[$den]
|
||||
)
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (null !== $erasures) {
|
||||
if (count($erasures) < $count) {
|
||||
$erasures->setSize($count);
|
||||
}
|
||||
|
||||
for ($i = 0; $i < $count; $i++) {
|
||||
$erasures[$i] = $loc[$i];
|
||||
}
|
||||
}
|
||||
|
||||
return $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes $x % GF_SIZE, where GF_SIZE is 2**GF_BITS - 1, without a slow divide.
|
||||
*/
|
||||
private function modNn(int $x) : int
|
||||
{
|
||||
while ($x >= $this->blockSize) {
|
||||
$x -= $this->blockSize;
|
||||
$x = ($x >> $this->symbolSize) + ($x & $this->blockSize);
|
||||
}
|
||||
|
||||
return $x;
|
||||
}
|
||||
}
|
596
vendor/bacon/bacon-qr-code/src/Common/Version.php
vendored
Normal file
596
vendor/bacon/bacon-qr-code/src/Common/Version.php
vendored
Normal file
@ -0,0 +1,596 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace BaconQrCode\Common;
|
||||
|
||||
use BaconQrCode\Exception\InvalidArgumentException;
|
||||
use SplFixedArray;
|
||||
|
||||
/**
|
||||
* Version representation.
|
||||
*/
|
||||
final class Version
|
||||
{
|
||||
private const VERSION_DECODE_INFO = [
|
||||
0x07c94,
|
||||
0x085bc,
|
||||
0x09a99,
|
||||
0x0a4d3,
|
||||
0x0bbf6,
|
||||
0x0c762,
|
||||
0x0d847,
|
||||
0x0e60d,
|
||||
0x0f928,
|
||||
0x10b78,
|
||||
0x1145d,
|
||||
0x12a17,
|
||||
0x13532,
|
||||
0x149a6,
|
||||
0x15683,
|
||||
0x168c9,
|
||||
0x177ec,
|
||||
0x18ec4,
|
||||
0x191e1,
|
||||
0x1afab,
|
||||
0x1b08e,
|
||||
0x1cc1a,
|
||||
0x1d33f,
|
||||
0x1ed75,
|
||||
0x1f250,
|
||||
0x209d5,
|
||||
0x216f0,
|
||||
0x228ba,
|
||||
0x2379f,
|
||||
0x24b0b,
|
||||
0x2542e,
|
||||
0x26a64,
|
||||
0x27541,
|
||||
0x28c69,
|
||||
];
|
||||
|
||||
/**
|
||||
* Version number of this version.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $versionNumber;
|
||||
|
||||
/**
|
||||
* Alignment pattern centers.
|
||||
*
|
||||
* @var SplFixedArray
|
||||
*/
|
||||
private $alignmentPatternCenters;
|
||||
|
||||
/**
|
||||
* Error correction blocks.
|
||||
*
|
||||
* @var EcBlocks[]
|
||||
*/
|
||||
private $ecBlocks;
|
||||
|
||||
/**
|
||||
* Total number of codewords.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $totalCodewords;
|
||||
|
||||
/**
|
||||
* Cached version instances.
|
||||
*
|
||||
* @var array<int, self>|null
|
||||
*/
|
||||
private static $versions;
|
||||
|
||||
/**
|
||||
* @param int[] $alignmentPatternCenters
|
||||
*/
|
||||
private function __construct(
|
||||
int $versionNumber,
|
||||
array $alignmentPatternCenters,
|
||||
EcBlocks ...$ecBlocks
|
||||
) {
|
||||
$this->versionNumber = $versionNumber;
|
||||
$this->alignmentPatternCenters = $alignmentPatternCenters;
|
||||
$this->ecBlocks = $ecBlocks;
|
||||
|
||||
$totalCodewords = 0;
|
||||
$ecCodewords = $ecBlocks[0]->getEcCodewordsPerBlock();
|
||||
|
||||
foreach ($ecBlocks[0]->getEcBlocks() as $ecBlock) {
|
||||
$totalCodewords += $ecBlock->getCount() * ($ecBlock->getDataCodewords() + $ecCodewords);
|
||||
}
|
||||
|
||||
$this->totalCodewords = $totalCodewords;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the version number.
|
||||
*/
|
||||
public function getVersionNumber() : int
|
||||
{
|
||||
return $this->versionNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the alignment pattern centers.
|
||||
*
|
||||
* @return int[]
|
||||
*/
|
||||
public function getAlignmentPatternCenters() : array
|
||||
{
|
||||
return $this->alignmentPatternCenters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the total number of codewords.
|
||||
*/
|
||||
public function getTotalCodewords() : int
|
||||
{
|
||||
return $this->totalCodewords;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the dimension for the current version.
|
||||
*/
|
||||
public function getDimensionForVersion() : int
|
||||
{
|
||||
return 17 + 4 * $this->versionNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of EC blocks for a specific EC level.
|
||||
*/
|
||||
public function getEcBlocksForLevel(ErrorCorrectionLevel $ecLevel) : EcBlocks
|
||||
{
|
||||
return $this->ecBlocks[$ecLevel->ordinal()];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a provisional version number for a specific dimension.
|
||||
*
|
||||
* @throws InvalidArgumentException if dimension is not 1 mod 4
|
||||
*/
|
||||
public static function getProvisionalVersionForDimension(int $dimension) : self
|
||||
{
|
||||
if (1 !== $dimension % 4) {
|
||||
throw new InvalidArgumentException('Dimension is not 1 mod 4');
|
||||
}
|
||||
|
||||
return self::getVersionForNumber(intdiv($dimension - 17, 4));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a version instance for a specific version number.
|
||||
*
|
||||
* @throws InvalidArgumentException if version number is out of range
|
||||
*/
|
||||
public static function getVersionForNumber(int $versionNumber) : self
|
||||
{
|
||||
if ($versionNumber < 1 || $versionNumber > 40) {
|
||||
throw new InvalidArgumentException('Version number must be between 1 and 40');
|
||||
}
|
||||
|
||||
return self::versions()[$versionNumber - 1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes version information from an integer and returns the version.
|
||||
*/
|
||||
public static function decodeVersionInformation(int $versionBits) : ?self
|
||||
{
|
||||
$bestDifference = PHP_INT_MAX;
|
||||
$bestVersion = 0;
|
||||
|
||||
foreach (self::VERSION_DECODE_INFO as $i => $targetVersion) {
|
||||
if ($targetVersion === $versionBits) {
|
||||
return self::getVersionForNumber($i + 7);
|
||||
}
|
||||
|
||||
$bitsDifference = FormatInformation::numBitsDiffering($versionBits, $targetVersion);
|
||||
|
||||
if ($bitsDifference < $bestDifference) {
|
||||
$bestVersion = $i + 7;
|
||||
$bestDifference = $bitsDifference;
|
||||
}
|
||||
}
|
||||
|
||||
if ($bestDifference <= 3) {
|
||||
return self::getVersionForNumber($bestVersion);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the function pattern for the current version.
|
||||
*/
|
||||
public function buildFunctionPattern() : BitMatrix
|
||||
{
|
||||
$dimension = $this->getDimensionForVersion();
|
||||
$bitMatrix = new BitMatrix($dimension);
|
||||
|
||||
// Top left finder pattern + separator + format
|
||||
$bitMatrix->setRegion(0, 0, 9, 9);
|
||||
// Top right finder pattern + separator + format
|
||||
$bitMatrix->setRegion($dimension - 8, 0, 8, 9);
|
||||
// Bottom left finder pattern + separator + format
|
||||
$bitMatrix->setRegion(0, $dimension - 8, 9, 8);
|
||||
|
||||
// Alignment patterns
|
||||
$max = count($this->alignmentPatternCenters);
|
||||
|
||||
for ($x = 0; $x < $max; ++$x) {
|
||||
$i = $this->alignmentPatternCenters[$x] - 2;
|
||||
|
||||
for ($y = 0; $y < $max; ++$y) {
|
||||
if (($x === 0 && ($y === 0 || $y === $max - 1)) || ($x === $max - 1 && $y === 0)) {
|
||||
// No alignment patterns near the three finder paterns
|
||||
continue;
|
||||
}
|
||||
|
||||
$bitMatrix->setRegion($this->alignmentPatternCenters[$y] - 2, $i, 5, 5);
|
||||
}
|
||||
}
|
||||
|
||||
// Vertical timing pattern
|
||||
$bitMatrix->setRegion(6, 9, 1, $dimension - 17);
|
||||
// Horizontal timing pattern
|
||||
$bitMatrix->setRegion(9, 6, $dimension - 17, 1);
|
||||
|
||||
if ($this->versionNumber > 6) {
|
||||
// Version info, top right
|
||||
$bitMatrix->setRegion($dimension - 11, 0, 3, 6);
|
||||
// Version info, bottom left
|
||||
$bitMatrix->setRegion(0, $dimension - 11, 6, 3);
|
||||
}
|
||||
|
||||
return $bitMatrix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation for the version.
|
||||
*/
|
||||
public function __toString() : string
|
||||
{
|
||||
return (string) $this->versionNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build and cache a specific version.
|
||||
*
|
||||
* See ISO 18004:2006 6.5.1 Table 9.
|
||||
*
|
||||
* @return array<int, self>
|
||||
*/
|
||||
private static function versions() : array
|
||||
{
|
||||
if (null !== self::$versions) {
|
||||
return self::$versions;
|
||||
}
|
||||
|
||||
return self::$versions = [
|
||||
new self(
|
||||
1,
|
||||
[],
|
||||
new EcBlocks(7, new EcBlock(1, 19)),
|
||||
new EcBlocks(10, new EcBlock(1, 16)),
|
||||
new EcBlocks(13, new EcBlock(1, 13)),
|
||||
new EcBlocks(17, new EcBlock(1, 9))
|
||||
),
|
||||
new self(
|
||||
2,
|
||||
[6, 18],
|
||||
new EcBlocks(10, new EcBlock(1, 34)),
|
||||
new EcBlocks(16, new EcBlock(1, 28)),
|
||||
new EcBlocks(22, new EcBlock(1, 22)),
|
||||
new EcBlocks(28, new EcBlock(1, 16))
|
||||
),
|
||||
new self(
|
||||
3,
|
||||
[6, 22],
|
||||
new EcBlocks(15, new EcBlock(1, 55)),
|
||||
new EcBlocks(26, new EcBlock(1, 44)),
|
||||
new EcBlocks(18, new EcBlock(2, 17)),
|
||||
new EcBlocks(22, new EcBlock(2, 13))
|
||||
),
|
||||
new self(
|
||||
4,
|
||||
[6, 26],
|
||||
new EcBlocks(20, new EcBlock(1, 80)),
|
||||
new EcBlocks(18, new EcBlock(2, 32)),
|
||||
new EcBlocks(26, new EcBlock(3, 24)),
|
||||
new EcBlocks(16, new EcBlock(4, 9))
|
||||
),
|
||||
new self(
|
||||
5,
|
||||
[6, 30],
|
||||
new EcBlocks(26, new EcBlock(1, 108)),
|
||||
new EcBlocks(24, new EcBlock(2, 43)),
|
||||
new EcBlocks(18, new EcBlock(2, 15), new EcBlock(2, 16)),
|
||||
new EcBlocks(22, new EcBlock(2, 11), new EcBlock(2, 12))
|
||||
),
|
||||
new self(
|
||||
6,
|
||||
[6, 34],
|
||||
new EcBlocks(18, new EcBlock(2, 68)),
|
||||
new EcBlocks(16, new EcBlock(4, 27)),
|
||||
new EcBlocks(24, new EcBlock(4, 19)),
|
||||
new EcBlocks(28, new EcBlock(4, 15))
|
||||
),
|
||||
new self(
|
||||
7,
|
||||
[6, 22, 38],
|
||||
new EcBlocks(20, new EcBlock(2, 78)),
|
||||
new EcBlocks(18, new EcBlock(4, 31)),
|
||||
new EcBlocks(18, new EcBlock(2, 14), new EcBlock(4, 15)),
|
||||
new EcBlocks(26, new EcBlock(4, 13), new EcBlock(1, 14))
|
||||
),
|
||||
new self(
|
||||
8,
|
||||
[6, 24, 42],
|
||||
new EcBlocks(24, new EcBlock(2, 97)),
|
||||
new EcBlocks(22, new EcBlock(2, 38), new EcBlock(2, 39)),
|
||||
new EcBlocks(22, new EcBlock(4, 18), new EcBlock(2, 19)),
|
||||
new EcBlocks(26, new EcBlock(4, 14), new EcBlock(2, 15))
|
||||
),
|
||||
new self(
|
||||
9,
|
||||
[6, 26, 46],
|
||||
new EcBlocks(30, new EcBlock(2, 116)),
|
||||
new EcBlocks(22, new EcBlock(3, 36), new EcBlock(2, 37)),
|
||||
new EcBlocks(20, new EcBlock(4, 16), new EcBlock(4, 17)),
|
||||
new EcBlocks(24, new EcBlock(4, 12), new EcBlock(4, 13))
|
||||
),
|
||||
new self(
|
||||
10,
|
||||
[6, 28, 50],
|
||||
new EcBlocks(18, new EcBlock(2, 68), new EcBlock(2, 69)),
|
||||
new EcBlocks(26, new EcBlock(4, 43), new EcBlock(1, 44)),
|
||||
new EcBlocks(24, new EcBlock(6, 19), new EcBlock(2, 20)),
|
||||
new EcBlocks(28, new EcBlock(6, 15), new EcBlock(2, 16))
|
||||
),
|
||||
new self(
|
||||
11,
|
||||
[6, 30, 54],
|
||||
new EcBlocks(20, new EcBlock(4, 81)),
|
||||
new EcBlocks(30, new EcBlock(1, 50), new EcBlock(4, 51)),
|
||||
new EcBlocks(28, new EcBlock(4, 22), new EcBlock(4, 23)),
|
||||
new EcBlocks(24, new EcBlock(3, 12), new EcBlock(8, 13))
|
||||
),
|
||||
new self(
|
||||
12,
|
||||
[6, 32, 58],
|
||||
new EcBlocks(24, new EcBlock(2, 92), new EcBlock(2, 93)),
|
||||
new EcBlocks(22, new EcBlock(6, 36), new EcBlock(2, 37)),
|
||||
new EcBlocks(26, new EcBlock(4, 20), new EcBlock(6, 21)),
|
||||
new EcBlocks(28, new EcBlock(7, 14), new EcBlock(4, 15))
|
||||
),
|
||||
new self(
|
||||
13,
|
||||
[6, 34, 62],
|
||||
new EcBlocks(26, new EcBlock(4, 107)),
|
||||
new EcBlocks(22, new EcBlock(8, 37), new EcBlock(1, 38)),
|
||||
new EcBlocks(24, new EcBlock(8, 20), new EcBlock(4, 21)),
|
||||
new EcBlocks(22, new EcBlock(12, 11), new EcBlock(4, 12))
|
||||
),
|
||||
new self(
|
||||
14,
|
||||
[6, 26, 46, 66],
|
||||
new EcBlocks(30, new EcBlock(3, 115), new EcBlock(1, 116)),
|
||||
new EcBlocks(24, new EcBlock(4, 40), new EcBlock(5, 41)),
|
||||
new EcBlocks(20, new EcBlock(11, 16), new EcBlock(5, 17)),
|
||||
new EcBlocks(24, new EcBlock(11, 12), new EcBlock(5, 13))
|
||||
),
|
||||
new self(
|
||||
15,
|
||||
[6, 26, 48, 70],
|
||||
new EcBlocks(22, new EcBlock(5, 87), new EcBlock(1, 88)),
|
||||
new EcBlocks(24, new EcBlock(5, 41), new EcBlock(5, 42)),
|
||||
new EcBlocks(30, new EcBlock(5, 24), new EcBlock(7, 25)),
|
||||
new EcBlocks(24, new EcBlock(11, 12), new EcBlock(7, 13))
|
||||
),
|
||||
new self(
|
||||
16,
|
||||
[6, 26, 50, 74],
|
||||
new EcBlocks(24, new EcBlock(5, 98), new EcBlock(1, 99)),
|
||||
new EcBlocks(28, new EcBlock(7, 45), new EcBlock(3, 46)),
|
||||
new EcBlocks(24, new EcBlock(15, 19), new EcBlock(2, 20)),
|
||||
new EcBlocks(30, new EcBlock(3, 15), new EcBlock(13, 16))
|
||||
),
|
||||
new self(
|
||||
17,
|
||||
[6, 30, 54, 78],
|
||||
new EcBlocks(28, new EcBlock(1, 107), new EcBlock(5, 108)),
|
||||
new EcBlocks(28, new EcBlock(10, 46), new EcBlock(1, 47)),
|
||||
new EcBlocks(28, new EcBlock(1, 22), new EcBlock(15, 23)),
|
||||
new EcBlocks(28, new EcBlock(2, 14), new EcBlock(17, 15))
|
||||
),
|
||||
new self(
|
||||
18,
|
||||
[6, 30, 56, 82],
|
||||
new EcBlocks(30, new EcBlock(5, 120), new EcBlock(1, 121)),
|
||||
new EcBlocks(26, new EcBlock(9, 43), new EcBlock(4, 44)),
|
||||
new EcBlocks(28, new EcBlock(17, 22), new EcBlock(1, 23)),
|
||||
new EcBlocks(28, new EcBlock(2, 14), new EcBlock(19, 15))
|
||||
),
|
||||
new self(
|
||||
19,
|
||||
[6, 30, 58, 86],
|
||||
new EcBlocks(28, new EcBlock(3, 113), new EcBlock(4, 114)),
|
||||
new EcBlocks(26, new EcBlock(3, 44), new EcBlock(11, 45)),
|
||||
new EcBlocks(26, new EcBlock(17, 21), new EcBlock(4, 22)),
|
||||
new EcBlocks(26, new EcBlock(9, 13), new EcBlock(16, 14))
|
||||
),
|
||||
new self(
|
||||
20,
|
||||
[6, 34, 62, 90],
|
||||
new EcBlocks(28, new EcBlock(3, 107), new EcBlock(5, 108)),
|
||||
new EcBlocks(26, new EcBlock(3, 41), new EcBlock(13, 42)),
|
||||
new EcBlocks(30, new EcBlock(15, 24), new EcBlock(5, 25)),
|
||||
new EcBlocks(28, new EcBlock(15, 15), new EcBlock(10, 16))
|
||||
),
|
||||
new self(
|
||||
21,
|
||||
[6, 28, 50, 72, 94],
|
||||
new EcBlocks(28, new EcBlock(4, 116), new EcBlock(4, 117)),
|
||||
new EcBlocks(26, new EcBlock(17, 42)),
|
||||
new EcBlocks(28, new EcBlock(17, 22), new EcBlock(6, 23)),
|
||||
new EcBlocks(30, new EcBlock(19, 16), new EcBlock(6, 17))
|
||||
),
|
||||
new self(
|
||||
22,
|
||||
[6, 26, 50, 74, 98],
|
||||
new EcBlocks(28, new EcBlock(2, 111), new EcBlock(7, 112)),
|
||||
new EcBlocks(28, new EcBlock(17, 46)),
|
||||
new EcBlocks(30, new EcBlock(7, 24), new EcBlock(16, 25)),
|
||||
new EcBlocks(24, new EcBlock(34, 13))
|
||||
),
|
||||
new self(
|
||||
23,
|
||||
[6, 30, 54, 78, 102],
|
||||
new EcBlocks(30, new EcBlock(4, 121), new EcBlock(5, 122)),
|
||||
new EcBlocks(28, new EcBlock(4, 47), new EcBlock(14, 48)),
|
||||
new EcBlocks(30, new EcBlock(11, 24), new EcBlock(14, 25)),
|
||||
new EcBlocks(30, new EcBlock(16, 15), new EcBlock(14, 16))
|
||||
),
|
||||
new self(
|
||||
24,
|
||||
[6, 28, 54, 80, 106],
|
||||
new EcBlocks(30, new EcBlock(6, 117), new EcBlock(4, 118)),
|
||||
new EcBlocks(28, new EcBlock(6, 45), new EcBlock(14, 46)),
|
||||
new EcBlocks(30, new EcBlock(11, 24), new EcBlock(16, 25)),
|
||||
new EcBlocks(30, new EcBlock(30, 16), new EcBlock(2, 17))
|
||||
),
|
||||
new self(
|
||||
25,
|
||||
[6, 32, 58, 84, 110],
|
||||
new EcBlocks(26, new EcBlock(8, 106), new EcBlock(4, 107)),
|
||||
new EcBlocks(28, new EcBlock(8, 47), new EcBlock(13, 48)),
|
||||
new EcBlocks(30, new EcBlock(7, 24), new EcBlock(22, 25)),
|
||||
new EcBlocks(30, new EcBlock(22, 15), new EcBlock(13, 16))
|
||||
),
|
||||
new self(
|
||||
26,
|
||||
[6, 30, 58, 86, 114],
|
||||
new EcBlocks(28, new EcBlock(10, 114), new EcBlock(2, 115)),
|
||||
new EcBlocks(28, new EcBlock(19, 46), new EcBlock(4, 47)),
|
||||
new EcBlocks(28, new EcBlock(28, 22), new EcBlock(6, 23)),
|
||||
new EcBlocks(30, new EcBlock(33, 16), new EcBlock(4, 17))
|
||||
),
|
||||
new self(
|
||||
27,
|
||||
[6, 34, 62, 90, 118],
|
||||
new EcBlocks(30, new EcBlock(8, 122), new EcBlock(4, 123)),
|
||||
new EcBlocks(28, new EcBlock(22, 45), new EcBlock(3, 46)),
|
||||
new EcBlocks(30, new EcBlock(8, 23), new EcBlock(26, 24)),
|
||||
new EcBlocks(30, new EcBlock(12, 15), new EcBlock(28, 16))
|
||||
),
|
||||
new self(
|
||||
28,
|
||||
[6, 26, 50, 74, 98, 122],
|
||||
new EcBlocks(30, new EcBlock(3, 117), new EcBlock(10, 118)),
|
||||
new EcBlocks(28, new EcBlock(3, 45), new EcBlock(23, 46)),
|
||||
new EcBlocks(30, new EcBlock(4, 24), new EcBlock(31, 25)),
|
||||
new EcBlocks(30, new EcBlock(11, 15), new EcBlock(31, 16))
|
||||
),
|
||||
new self(
|
||||
29,
|
||||
[6, 30, 54, 78, 102, 126],
|
||||
new EcBlocks(30, new EcBlock(7, 116), new EcBlock(7, 117)),
|
||||
new EcBlocks(28, new EcBlock(21, 45), new EcBlock(7, 46)),
|
||||
new EcBlocks(30, new EcBlock(1, 23), new EcBlock(37, 24)),
|
||||
new EcBlocks(30, new EcBlock(19, 15), new EcBlock(26, 16))
|
||||
),
|
||||
new self(
|
||||
30,
|
||||
[6, 26, 52, 78, 104, 130],
|
||||
new EcBlocks(30, new EcBlock(5, 115), new EcBlock(10, 116)),
|
||||
new EcBlocks(28, new EcBlock(19, 47), new EcBlock(10, 48)),
|
||||
new EcBlocks(30, new EcBlock(15, 24), new EcBlock(25, 25)),
|
||||
new EcBlocks(30, new EcBlock(23, 15), new EcBlock(25, 16))
|
||||
),
|
||||
new self(
|
||||
31,
|
||||
[6, 30, 56, 82, 108, 134],
|
||||
new EcBlocks(30, new EcBlock(13, 115), new EcBlock(3, 116)),
|
||||
new EcBlocks(28, new EcBlock(2, 46), new EcBlock(29, 47)),
|
||||
new EcBlocks(30, new EcBlock(42, 24), new EcBlock(1, 25)),
|
||||
new EcBlocks(30, new EcBlock(23, 15), new EcBlock(28, 16))
|
||||
),
|
||||
new self(
|
||||
32,
|
||||
[6, 34, 60, 86, 112, 138],
|
||||
new EcBlocks(30, new EcBlock(17, 115)),
|
||||
new EcBlocks(28, new EcBlock(10, 46), new EcBlock(23, 47)),
|
||||
new EcBlocks(30, new EcBlock(10, 24), new EcBlock(35, 25)),
|
||||
new EcBlocks(30, new EcBlock(19, 15), new EcBlock(35, 16))
|
||||
),
|
||||
new self(
|
||||
33,
|
||||
[6, 30, 58, 86, 114, 142],
|
||||
new EcBlocks(30, new EcBlock(17, 115), new EcBlock(1, 116)),
|
||||
new EcBlocks(28, new EcBlock(14, 46), new EcBlock(21, 47)),
|
||||
new EcBlocks(30, new EcBlock(29, 24), new EcBlock(19, 25)),
|
||||
new EcBlocks(30, new EcBlock(11, 15), new EcBlock(46, 16))
|
||||
),
|
||||
new self(
|
||||
34,
|
||||
[6, 34, 62, 90, 118, 146],
|
||||
new EcBlocks(30, new EcBlock(13, 115), new EcBlock(6, 116)),
|
||||
new EcBlocks(28, new EcBlock(14, 46), new EcBlock(23, 47)),
|
||||
new EcBlocks(30, new EcBlock(44, 24), new EcBlock(7, 25)),
|
||||
new EcBlocks(30, new EcBlock(59, 16), new EcBlock(1, 17))
|
||||
),
|
||||
new self(
|
||||
35,
|
||||
[6, 30, 54, 78, 102, 126, 150],
|
||||
new EcBlocks(30, new EcBlock(12, 121), new EcBlock(7, 122)),
|
||||
new EcBlocks(28, new EcBlock(12, 47), new EcBlock(26, 48)),
|
||||
new EcBlocks(30, new EcBlock(39, 24), new EcBlock(14, 25)),
|
||||
new EcBlocks(30, new EcBlock(22, 15), new EcBlock(41, 16))
|
||||
),
|
||||
new self(
|
||||
36,
|
||||
[6, 24, 50, 76, 102, 128, 154],
|
||||
new EcBlocks(30, new EcBlock(6, 121), new EcBlock(14, 122)),
|
||||
new EcBlocks(28, new EcBlock(6, 47), new EcBlock(34, 48)),
|
||||
new EcBlocks(30, new EcBlock(46, 24), new EcBlock(10, 25)),
|
||||
new EcBlocks(30, new EcBlock(2, 15), new EcBlock(64, 16))
|
||||
),
|
||||
new self(
|
||||
37,
|
||||
[6, 28, 54, 80, 106, 132, 158],
|
||||
new EcBlocks(30, new EcBlock(17, 122), new EcBlock(4, 123)),
|
||||
new EcBlocks(28, new EcBlock(29, 46), new EcBlock(14, 47)),
|
||||
new EcBlocks(30, new EcBlock(49, 24), new EcBlock(10, 25)),
|
||||
new EcBlocks(30, new EcBlock(24, 15), new EcBlock(46, 16))
|
||||
),
|
||||
new self(
|
||||
38,
|
||||
[6, 32, 58, 84, 110, 136, 162],
|
||||
new EcBlocks(30, new EcBlock(4, 122), new EcBlock(18, 123)),
|
||||
new EcBlocks(28, new EcBlock(13, 46), new EcBlock(32, 47)),
|
||||
new EcBlocks(30, new EcBlock(48, 24), new EcBlock(14, 25)),
|
||||
new EcBlocks(30, new EcBlock(42, 15), new EcBlock(32, 16))
|
||||
),
|
||||
new self(
|
||||
39,
|
||||
[6, 26, 54, 82, 110, 138, 166],
|
||||
new EcBlocks(30, new EcBlock(20, 117), new EcBlock(4, 118)),
|
||||
new EcBlocks(28, new EcBlock(40, 47), new EcBlock(7, 48)),
|
||||
new EcBlocks(30, new EcBlock(43, 24), new EcBlock(22, 25)),
|
||||
new EcBlocks(30, new EcBlock(10, 15), new EcBlock(67, 16))
|
||||
),
|
||||
new self(
|
||||
40,
|
||||
[6, 30, 58, 86, 114, 142, 170],
|
||||
new EcBlocks(30, new EcBlock(19, 118), new EcBlock(6, 119)),
|
||||
new EcBlocks(28, new EcBlock(18, 47), new EcBlock(31, 48)),
|
||||
new EcBlocks(30, new EcBlock(34, 24), new EcBlock(34, 25)),
|
||||
new EcBlocks(30, new EcBlock(20, 15), new EcBlock(61, 16))
|
||||
),
|
||||
];
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user