1.9.20
This commit is contained in:
parent
f17b24122f
commit
608211d178
31
README.md
31
README.md
@ -1,10 +1,13 @@
|
|||||||
# TaoLer
|
# TaoLer
|
||||||
|
|
||||||
> TaoLer是一个简单迅捷的轻论坛系统,适用于个人或组织区域型信息交流发布平台。
|
> TaoLer是一个简单迅捷的管理系统,支持插件化开发,适用于企业、个人或组织建站需求。
|
||||||
|
|
||||||
|
支持多模板、多单页自由切换,网站风格可定制性强,支持插件化开发,方便二开。可做为企业门户网站,生活服务,学习问答笔记,文章分享等。
|
||||||
|
默认内置一套完整的**问答+博客+论坛+新闻+轻社区化**的模板系统,还可持续增加模块,一个系统拥有多个版式的网站风格。
|
||||||
|
|
||||||
* 官网:https://www.aieok.com
|
* 官网:https://www.aieok.com
|
||||||
|
* 文档:http://wiki.aieok.com
|
||||||
webman版新架构已适配90%
|
* 演示后台:https://www.aieok.com/adminff
|
||||||
|
|
||||||
#### 项目地址
|
#### 项目地址
|
||||||
|
|
||||||
@ -24,15 +27,14 @@
|
|||||||
6. 双升级系统,可支持自动和手动升级。可在线检测并升级系统,保持网站的更新和安全。
|
6. 双升级系统,可支持自动和手动升级。可在线检测并升级系统,保持网站的更新和安全。
|
||||||
7. 代码开源,不设暗门操作,更安全。
|
7. 代码开源,不设暗门操作,更安全。
|
||||||
8. 项目会长期维护,优化更新。
|
8. 项目会长期维护,优化更新。
|
||||||
9. 预增加插件管理机制1.0(2.0版本正式上线)
|
9. 预增加插件管理机制1.x(2.x版本正式上线)
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
#### 构架组成
|
#### 构架组成
|
||||||
- 1.x版本构架:
|
- 1.x版本构架:
|
||||||
- 构架:Tinkphp6 + layui2.6
|
- 构架:Tinkphp6 + layui2.7
|
||||||
- 环境:php7/php8.0 + mysql
|
- 环境:php7/8.1 + mysql5.7/8.0
|
||||||
- 前端:Fly template V3.0
|
|
||||||
|
|
||||||
#### 构架介绍
|
#### 构架介绍
|
||||||
thinkphp:
|
thinkphp:
|
||||||
@ -44,11 +46,16 @@
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
####重点
|
||||||
|
* 长期维护,对抗消亡
|
||||||
|
* 迭代及时,查漏补缺
|
||||||
|
* 多模板多模块,一站顶多站
|
||||||
|
|
||||||
#### 安装教程
|
#### 安装教程
|
||||||
|
|
||||||
1. 首选确保满目使用环境要求,php > 7.2, mysql > 5.7.3
|
1. 首选确保满目使用环境要求,php > 7.2, mysql > 5.7.3
|
||||||
2. git下载:https://gitee.com/toogee/TaoLer
|
2. https://github.com/taoser/TaoLer/archive/refs/heads/master.zip
|
||||||
github https://www.github.com/taoser/TaoLer
|
git下载:https://gitee.com/toogee/TaoLer
|
||||||
官网下载:https://www.aieok.com
|
官网下载:https://www.aieok.com
|
||||||
|
|
||||||
#### 引导安装
|
#### 引导安装
|
||||||
@ -92,14 +99,18 @@
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
>如果是宝塔集成环境,网站目录部署如下示例:
|
> 如果是宝塔集成环境,网站目录部署如下示例:
|
||||||
网站目录:D:/www/TaoLer
|
网站目录:D:/www/TaoLer
|
||||||
运行目录:/public
|
运行目录:/public
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
3. 首次安装,访问域名http://www.youdomain.com可自动跳转到/install/index进行引导安装,重新安装需删除public目录下install.lock。
|
3. 首次安装,访问域名http://www.youdomain.com可自动跳转到/install/index进行引导安装,重新安装需删除public目录下install.lock。
|
||||||
4. 安装前需要先创建mysql数据库(准备:数据库连接地址,数据库用户名,密码,端口)
|
4. 安装前需要先创建mysql数据库(准备:数据库连接地址,数据库用户名,密码,端口)
|
||||||
5. 如果手动导入数据库,管理员用户名和密码,默认admin/123456,前后台的管理员密码一致。前后端管理员账户是独立的,前端主要对文章内容的审查管理等操作。
|
5. 如果手动导入数据库,管理员用户名和密码,默认admin/123456,前后台的管理员密码一致。前后端管理员账户是独立的,前端主要对文章内容的审查管理等操作。
|
||||||
|
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
#### 前后台独立域名的绑定
|
#### 前后台独立域名的绑定
|
||||||
|
@ -12,6 +12,7 @@ use think\facade\Db;
|
|||||||
use think\facade\Request;
|
use think\facade\Request;
|
||||||
use think\facade\Lang;
|
use think\facade\Lang;
|
||||||
use think\facade\View;
|
use think\facade\View;
|
||||||
|
use think\facade\Route;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 控制器基础类
|
* 控制器基础类
|
||||||
@ -244,10 +245,16 @@ abstract class BaseController
|
|||||||
* @param integer $aid
|
* @param integer $aid
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
protected function getRouteUrl(int $aid) : string
|
protected function getRouteUrl(int $aid,string $ename = '') : string
|
||||||
{
|
{
|
||||||
$indexUrl = $this->getIndexUrl();
|
$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'));
|
//$domain_bind = array_key_exists('domain_bind',config('app'));
|
||||||
|
@ -1,4 +1,13 @@
|
|||||||
<?php
|
<?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;
|
namespace app;
|
||||||
|
|
||||||
// 应用请求对象类
|
// 应用请求对象类
|
||||||
@ -8,6 +17,7 @@ class Request extends \think\Request
|
|||||||
//protected $filter = ['trim','htmlspecialchars','strip_tags'];
|
//protected $filter = ['trim','htmlspecialchars','strip_tags'];
|
||||||
//protected $filter = ['trim','htmlspecialchars'];
|
//protected $filter = ['trim','htmlspecialchars'];
|
||||||
//protected $filter = ['trim','strip_tags'];
|
//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;
|
//$conf = new \addons\social\model\Conf;
|
||||||
//$arr = $conf->getConf();
|
//$arr = $conf->getConf();
|
||||||
//dump($arr);
|
//dump($arr);
|
||||||
//dump($arr[0]['value']['app_key']);
|
|
||||||
return View::fetch();
|
return View::fetch();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,7 +158,7 @@ class Addons extends AdminController
|
|||||||
validate(['file'=>'filesize:2048|fileExt:zip,rar,7z'])
|
validate(['file'=>'filesize:2048|fileExt:zip,rar,7z'])
|
||||||
->check(array($file));
|
->check(array($file));
|
||||||
$savename = \think\facade\Filesystem::disk('public')->putFile('addons',$file);
|
$savename = \think\facade\Filesystem::disk('public')->putFile('addons',$file);
|
||||||
} catch (think\exception\ValidateException $e) {
|
} catch (\think\exception\ValidateException $e) {
|
||||||
echo $e->getMessage();
|
echo $e->getMessage();
|
||||||
}
|
}
|
||||||
$upload = Config::get('filesystem.disks.public.url');
|
$upload = Config::get('filesystem.disks.public.url');
|
||||||
@ -189,6 +188,7 @@ class Addons extends AdminController
|
|||||||
if(!$verRes){
|
if(!$verRes){
|
||||||
return json(['code'=>-1,'msg'=>'不能降级,请选择正确版本']);
|
return json(['code'=>-1,'msg'=>'不能降级,请选择正确版本']);
|
||||||
}
|
}
|
||||||
|
//$tpl_ver_res = version_compare($addInstalledVersion['template_version'], config('taoler.template_version'),'<');
|
||||||
}
|
}
|
||||||
|
|
||||||
$file_url = $addons->addons_src;
|
$file_url = $addons->addons_src;
|
||||||
|
@ -60,7 +60,8 @@ class Forum extends AdminController
|
|||||||
$forumList = Db::name('article')
|
$forumList = Db::name('article')
|
||||||
->alias('a')
|
->alias('a')
|
||||||
->join('user u','a.user_id = u.id')
|
->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('a.delete_time',0)
|
||||||
->where($map)
|
->where($map)
|
||||||
->where($where)
|
->where($where)
|
||||||
@ -73,7 +74,7 @@ class Forum extends AdminController
|
|||||||
$res['msg'] = '';
|
$res['msg'] = '';
|
||||||
$res['count'] = $count;
|
$res['count'] = $count;
|
||||||
foreach($forumList as $k=>$v){
|
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']];
|
$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 {
|
} else {
|
||||||
@ -236,7 +237,8 @@ class Forum extends AdminController
|
|||||||
->alias('a')
|
->alias('a')
|
||||||
->join('user u','a.user_id = u.id')
|
->join('user u','a.user_id = u.id')
|
||||||
->join('article c','a.article_id = c.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('a.delete_time',0)
|
||||||
->where($map)
|
->where($map)
|
||||||
->where($where)
|
->where($where)
|
||||||
@ -248,7 +250,7 @@ class Forum extends AdminController
|
|||||||
if ($count) {
|
if ($count) {
|
||||||
$res = ['code'=>0,'msg'=>'','count'=>$count];
|
$res = ['code'=>0,'msg'=>'','count'=>$count];
|
||||||
foreach($replys as $k => $v){
|
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['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];
|
$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 app\admin\model\Cunsult;
|
||||||
use think\facade\Config;
|
use think\facade\Config;
|
||||||
use taoler\com\Api;
|
use taoler\com\Api;
|
||||||
|
use taoser\SetArr;
|
||||||
|
|
||||||
class Index extends AdminController
|
class Index extends AdminController
|
||||||
{
|
{
|
||||||
@ -111,7 +112,7 @@ class Index extends AdminController
|
|||||||
->alias('a')
|
->alias('a')
|
||||||
->join('user u','a.user_id = u.id')
|
->join('user u','a.user_id = u.id')
|
||||||
->join('cate c','a.cate_id = c.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)
|
->where('a.delete_time',0)
|
||||||
->whereWeek('a.create_time')
|
->whereWeek('a.create_time')
|
||||||
->order('a.create_time', 'desc')
|
->order('a.create_time', 'desc')
|
||||||
@ -124,7 +125,7 @@ class Index extends AdminController
|
|||||||
$res['count'] = $count;
|
$res['count'] = $count;
|
||||||
foreach($forumList as $k=>$v){
|
foreach($forumList as $k=>$v){
|
||||||
//$url = (string) str_replace("admin","index",$this->domain.url('article/detail',['id'=>$v['aid']]));
|
//$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']];
|
$res['data'][]= ['id'=>$url,'title'=>htmlspecialchars($v['title']),'name'=>$v['name'],'catename'=>$v['catename'],'pv'=>$v['pv']];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -142,7 +143,8 @@ class Index extends AdminController
|
|||||||
->alias('a')
|
->alias('a')
|
||||||
->join('user u','a.user_id = u.id')
|
->join('user u','a.user_id = u.id')
|
||||||
->join('article c','a.article_id = c.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)
|
->where('c.delete_time',0)
|
||||||
->whereWeek('a.create_time')
|
->whereWeek('a.create_time')
|
||||||
->order('a.create_time', 'desc')
|
->order('a.create_time', 'desc')
|
||||||
@ -153,7 +155,7 @@ class Index extends AdminController
|
|||||||
if ($count) {
|
if ($count) {
|
||||||
$res = ['code'=>0,'msg'=>'','count'=>$count];
|
$res = ['code'=>0,'msg'=>'','count'=>$count];
|
||||||
foreach($replys as $k => $v){
|
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 {
|
} else {
|
||||||
$res = ['code'=>-1,'msg'=>'本周还没评论'];
|
$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(){
|
public function layout(){
|
||||||
return view();
|
return view();
|
||||||
|
@ -2,11 +2,11 @@
|
|||||||
/*
|
/*
|
||||||
* @Author: TaoLer <alipey_tao@qq.com>
|
* @Author: TaoLer <alipey_tao@qq.com>
|
||||||
* @Date: 2022-04-13 09:54:31
|
* @Date: 2022-04-13 09:54:31
|
||||||
* @LastEditTime: 2022-05-12 16:21:33
|
* @LastEditTime: 2022-07-15 18:28:57
|
||||||
* @LastEditors: TaoLer
|
* @LastEditors: TaoLer
|
||||||
* @Description: 搜索引擎SEO优化设置
|
* @Description: 搜索引擎SEO优化设置
|
||||||
* @FilePath: \TaoLer\app\admin\controller\Seo.php
|
* @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);
|
declare(strict_types=1);
|
||||||
namespace app\admin\controller;
|
namespace app\admin\controller;
|
||||||
@ -20,6 +20,8 @@ use app\admin\model\PushJscode;
|
|||||||
|
|
||||||
class Seo extends AdminController
|
class Seo extends AdminController
|
||||||
{
|
{
|
||||||
|
// 写ID
|
||||||
|
protected $w_id = 0;
|
||||||
|
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
@ -43,25 +45,63 @@ class Seo extends AdminController
|
|||||||
return View::fetch();
|
return View::fetch();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 百度推送
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
public function push()
|
public function push()
|
||||||
{
|
{
|
||||||
$data = Request::only(['start_id','end_id','time']);
|
$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 = [];
|
$urls = [];
|
||||||
if(empty($data['start_id']) || empty($data['end_id'])) {
|
if(empty($data['start_id']) || empty($data['end_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');
|
$artAllId = Db::name('article')->where(['delete_time'=>0,'status'=>1])->whereTime('create_time', $data['time'])->column('id');
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
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 {
|
} 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');
|
$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'=>'没有查询到结果,无需推送']);
|
if(empty($artAllId)) return json(['code'=>-1,'msg'=>'没有查询到结果,无需推送']);
|
||||||
// 组装链接数组
|
// 组装链接数组
|
||||||
|
if($article_as == '<ename>/') {
|
||||||
|
foreach($artAllId as $art) {
|
||||||
|
$urls[] = $this->getRouteUrl($art['aid'], $art['ename']);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
foreach($artAllId as $aid) {
|
foreach($artAllId as $aid) {
|
||||||
$urls[] = $this->getRouteUrl($aid);
|
$urls[] = $this->getRouteUrl($aid);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 百度接口单次最大提交200,进行分组
|
// 百度接口单次最大提交200,进行分组
|
||||||
$urls = array_chunk($urls,2000);
|
$urls = array_chunk($urls,2000);
|
||||||
$api = config('taoler.baidu.push_api');
|
|
||||||
$ch = curl_init();
|
$ch = curl_init();
|
||||||
foreach($urls as $url) {
|
foreach($urls as $url) {
|
||||||
$options = array(
|
$options = array(
|
||||||
@ -125,7 +165,7 @@ class Seo extends AdminController
|
|||||||
$data = Request::only(['map_num','map_time','map_level']);
|
$data = Request::only(['map_num','map_time','map_level']);
|
||||||
// 写文件字符串
|
// 写文件字符串
|
||||||
$str = '';
|
$str = '';
|
||||||
// 标记第一次调用写ID
|
// 标记每次调用首次调用写ID
|
||||||
$flag= true;
|
$flag= true;
|
||||||
// 写ID
|
// 写ID
|
||||||
$w_id = '';
|
$w_id = '';
|
||||||
@ -133,6 +173,8 @@ class Seo extends AdminController
|
|||||||
$i = 1;
|
$i = 1;
|
||||||
// 获取public下所有xml文件
|
// 获取public下所有xml文件
|
||||||
$newFile = $this->getXmlFile(public_path());
|
$newFile = $this->getXmlFile(public_path());
|
||||||
|
// 路由配置
|
||||||
|
$article_as = config('taoler.url_rewrite.article_as');
|
||||||
// 没有xml文件时,不存在重写
|
// 没有xml文件时,不存在重写
|
||||||
if(empty($newFile)) {
|
if(empty($newFile)) {
|
||||||
$rewrite = false;
|
$rewrite = false;
|
||||||
@ -157,21 +199,55 @@ class Seo extends AdminController
|
|||||||
} else {
|
} else {
|
||||||
$limit = (int) $data['map_num'];
|
$limit = (int) $data['map_num'];
|
||||||
}
|
}
|
||||||
|
|
||||||
// 最新ID
|
// 最新ID
|
||||||
$maxId = Db::name('article')->where(['delete_time'=>0,'status'=>1])->max('id');
|
$maxId = Db::name('article')->where(['delete_time'=>0,'status'=>1])->max('id');
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
$wr_id = $flag ? config('taoler.sitemap.write_id') : $w_id;
|
$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')
|
$artAllId = Db::name('article')
|
||||||
->where(['delete_time'=>0,'status'=>1])
|
->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');
|
->order('id','asc')->limit($limit)->column('update_time','id');
|
||||||
|
}
|
||||||
|
|
||||||
if(empty($artAllId)) {
|
if(empty($artAllId)) {
|
||||||
return json(['code'=>-1,'msg'=>'本次无需生成']);
|
return json(['code'=>-1,'msg'=>'本次无需生成']);
|
||||||
} else {
|
} else {
|
||||||
// 本次最新文件ID
|
// 本次最新文件ID
|
||||||
$last_id = array_key_last($artAllId);
|
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) {
|
foreach($artAllId as $aid => $uptime) {
|
||||||
// url生成
|
// url生成
|
||||||
@ -187,6 +263,8 @@ class Seo extends AdminController
|
|||||||
</url>\n
|
</url>\n
|
||||||
STR;
|
STR;
|
||||||
}
|
}
|
||||||
|
$last_id = array_key_last($artAllId);
|
||||||
|
}
|
||||||
|
|
||||||
// 写文件
|
// 写文件
|
||||||
if($rewrite){
|
if($rewrite){
|
||||||
@ -213,7 +291,7 @@ class Seo extends AdminController
|
|||||||
// 重置标记内容
|
// 重置标记内容
|
||||||
$str = '';
|
$str = '';
|
||||||
$i++;
|
$i++;
|
||||||
$w_id = $last_id;
|
$this->w_id = $last_id;
|
||||||
$flag = false;
|
$flag = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -228,8 +306,7 @@ class Seo extends AdminController
|
|||||||
if($res == false){
|
if($res == false){
|
||||||
return json(['code'=>-1,'msg'=>'写xml配置失败']);
|
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 json(['code'=>0,'msg'=>'删除成功']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 搜索引擎日志分析
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
public function searchLog()
|
public function searchLog()
|
||||||
{
|
{
|
||||||
$time = input('search_time');
|
$time = input('search_time');
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
/*
|
/*
|
||||||
* @Author: TaoLer <alipey_tao@qq.com>
|
* @Author: TaoLer <alipey_tao@qq.com>
|
||||||
* @Date: 2021-12-06 16:04:50
|
* @Date: 2021-12-06 16:04:50
|
||||||
* @LastEditTime: 2022-05-10 15:00:49
|
* @LastEditTime: 2022-07-24 11:06:14
|
||||||
* @LastEditors: TaoLer
|
* @LastEditors: TaoLer
|
||||||
* @Description: 搜索引擎SEO优化设置
|
* @Description: 搜索引擎SEO优化设置
|
||||||
* @FilePath: \TaoLer\app\admin\controller\Set.php
|
* @FilePath: \TaoLer\app\admin\controller\Set.php
|
||||||
@ -161,7 +161,7 @@ class Set extends AdminController
|
|||||||
return json($res);
|
return json($res);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**配置设置
|
/**基础服务配置
|
||||||
* parem $id
|
* parem $id
|
||||||
*/
|
*/
|
||||||
public function config()
|
public function config()
|
||||||
@ -173,7 +173,6 @@ class Set extends AdminController
|
|||||||
if(!isset($data['posts_check'])) $data['posts_check'] =1;
|
if(!isset($data['posts_check'])) $data['posts_check'] =1;
|
||||||
if(!isset($data['commnets_check'])) $data['commnets_check'] =1;
|
if(!isset($data['commnets_check'])) $data['commnets_check'] =1;
|
||||||
foreach($conf as $c=>$f){
|
foreach($conf as $c=>$f){
|
||||||
|
|
||||||
if(array_key_exists($c,$data)){
|
if(array_key_exists($c,$data)){
|
||||||
$conf[$c] = (int) $data[$c];
|
$conf[$c] = (int) $data[$c];
|
||||||
}else{
|
}else{
|
||||||
@ -356,16 +355,25 @@ class Set extends AdminController
|
|||||||
//上传logo
|
//上传logo
|
||||||
public function upload()
|
public function upload()
|
||||||
{
|
{
|
||||||
|
$param = Request::param('field');
|
||||||
$uploads = new \app\common\lib\Uploads();
|
$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();
|
$logoJson = $upRes->getData();
|
||||||
if($logoJson['status'] == 0){
|
if($logoJson['status'] == 0){
|
||||||
|
if($param == 'logo'){
|
||||||
$result = Db::name('system')->where('id', 1)->cache('system')->update(['logo'=>$logoJson['url']]);
|
$result = Db::name('system')->where('id', 1)->cache('system')->update(['logo'=>$logoJson['url']]);
|
||||||
if($result){
|
|
||||||
$res = ['code'=>0,'msg'=>'上传logo成功'];
|
|
||||||
} else {
|
} else {
|
||||||
$res = ['code'=>1,'msg'=>'上传错误'];
|
//移动端logo
|
||||||
|
$result = Db::name('system')->where('id', 1)->cache('system')->update(['m_logo'=>$logoJson['url']]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if($result){
|
||||||
|
$res = ['code'=>0,'msg'=>'更新logo成功'];
|
||||||
|
} else {
|
||||||
|
$res = ['code'=>-1,'msg'=>'上传成功,数据无须更新'];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$res = ['code'=>-1, 'msg'=>$logoJson['msg']];
|
||||||
}
|
}
|
||||||
return json($res);
|
return json($res);
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ class Slider extends AdminController
|
|||||||
$limit = input('limit');
|
$limit = input('limit');
|
||||||
$page = input('page');
|
$page = input('page');
|
||||||
if($type) {
|
if($type) {
|
||||||
$datas = SliderModel::where('slid_type',$type)->where('')->paginate([
|
$datas = SliderModel::where('slid_type',$type)->paginate([
|
||||||
'list_rows'=> $limit,
|
'list_rows'=> $limit,
|
||||||
'page'=>$page
|
'page'=>$page
|
||||||
]);
|
]);
|
||||||
@ -126,7 +126,7 @@ class Slider extends AdminController
|
|||||||
public function uploadImg()
|
public function uploadImg()
|
||||||
{
|
{
|
||||||
$uploads = new \app\common\lib\Uploads();
|
$uploads = new \app\common\lib\Uploads();
|
||||||
$upRes = $uploads->put('file','slider',1024,'image');
|
$upRes = $uploads->put('file','SYS_slider',1024,'image');
|
||||||
$slires = $upRes->getData();
|
$slires = $upRes->getData();
|
||||||
|
|
||||||
if($slires['status'] == 0){
|
if($slires['status'] == 0){
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
* |————runtime
|
* |————runtime
|
||||||
* | |
|
* | |
|
||||||
* | |___update.sql(更新脚本) //create table test(id init(11)); create table test2(id init(11));
|
* | |___update.sql(更新脚本) //create table test(id init(11)); create table test2(id init(11));
|
||||||
*
|
|
||||||
* | |___rockback.sql(回滚脚本) //drop table test; //drop table test2;
|
* | |___rockback.sql(回滚脚本) //drop table test; //drop table test2;
|
||||||
|
* | |___remove.txt // clear清除目录和文件
|
||||||
* |
|
* |
|
||||||
* |____php
|
* |____php
|
||||||
*
|
*
|
||||||
|
@ -31,7 +31,7 @@ class User extends AdminController
|
|||||||
if($count){
|
if($count){
|
||||||
$res = ['code'=>0,'msg'=>'','count'=>$count];
|
$res = ['code'=>0,'msg'=>'','count'=>$count];
|
||||||
foreach($user as $k => $v){
|
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;
|
$res['data'][] = $data;
|
||||||
}
|
}
|
||||||
} else {
|
} 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>
|
* @Author: TaoLer <alipay_tao@qq.com>
|
||||||
* @Date: 2021-12-06 16:04:50
|
* @Date: 2021-12-06 16:04:50
|
||||||
* @LastEditTime: 2022-05-07 18:33:23
|
* @LastEditTime: 2022-06-29 15:29:13
|
||||||
* @LastEditors: TaoLer
|
* @LastEditors: TaoLer
|
||||||
* @Description: admin路由配置
|
* @Description: admin路由配置
|
||||||
* @FilePath: \TaoLer\app\admin\route\route.php
|
* @FilePath: \TaoLer\app\admin\route\route.php
|
||||||
@ -14,4 +14,9 @@ use think\facade\Route;
|
|||||||
$detail_as = config('taoler.url_rewrite.article_as');
|
$detail_as = config('taoler.url_rewrite.article_as');
|
||||||
|
|
||||||
Route::get('captcha/[:config]','\\think\\captcha\\CaptchaController@index');
|
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');
|
||||||
|
@ -99,23 +99,7 @@
|
|||||||
//监听搜索
|
//监听搜索
|
||||||
form.on('submit(LAY-user-back-search)', function(data){
|
form.on('submit(LAY-user-back-search)', function(data){
|
||||||
var field = data.field;
|
var field = data.field;
|
||||||
$.ajax({
|
$.post("{:url('admin/index')}",field);
|
||||||
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
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
//执行重载
|
//执行重载
|
||||||
table.reload('LAY-user-back-manage', {
|
table.reload('LAY-user-back-manage', {
|
||||||
where: field
|
where: field
|
||||||
@ -125,37 +109,17 @@
|
|||||||
//监听管理员审核
|
//监听管理员审核
|
||||||
form.on('switch(admincheck)', function(data){
|
form.on('switch(admincheck)', function(data){
|
||||||
var data= data.elem;
|
var data= data.elem;
|
||||||
//console.log(data);
|
|
||||||
|
|
||||||
if(data.checked == true){
|
|
||||||
data.value = 1;
|
|
||||||
}else{
|
|
||||||
data.value = 0;
|
|
||||||
}
|
|
||||||
//执行管理员审核
|
//执行管理员审核
|
||||||
$.ajax({
|
var status = data.checked ? 1 : 0;
|
||||||
type:'post',
|
$.post("{:url('admin/check')}",{"id":data.id,"status":status},function(res){
|
||||||
url:"{:url('admin/check')}",
|
|
||||||
data:{"id":data.id,"status":data.value,},
|
|
||||||
dataType:'json',
|
|
||||||
success:function(res){
|
|
||||||
if(res.code == 0){
|
if(res.code == 0){
|
||||||
layer.msg(res.msg,{
|
layer.msg(res.msg,{icon:res.icon,time:2000})
|
||||||
icon:res.icon,
|
|
||||||
time:2000
|
|
||||||
}
|
|
||||||
//,function(){location.reload();}
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
layer.open({
|
layer.open({title:'审核失败',content:res.msg,icon:5,adim:6})
|
||||||
title:'审核失败',
|
|
||||||
content:res.msg,
|
|
||||||
icon:5,
|
|
||||||
adim:6
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -206,25 +170,11 @@
|
|||||||
var field = data.field; //获取提交的字段
|
var field = data.field; //获取提交的字段
|
||||||
|
|
||||||
//提交 Ajax 成功后,静态更新表格中的数据
|
//提交 Ajax 成功后,静态更新表格中的数据
|
||||||
$.ajax({
|
$.post("{:url('admin/add')}",field,function(res){
|
||||||
type:"post",
|
if(res.code == 0){
|
||||||
url:"{:url('admin/add')}",
|
layer.msg(res.msg,{icon:res.icon,time:2000})
|
||||||
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 {
|
} else {
|
||||||
layer.open({
|
layer.open({title:'添加失败',content:res.msg,icon:5,adim:6})
|
||||||
title:'添加失败',
|
|
||||||
content:data.msg,
|
|
||||||
icon:5,
|
|
||||||
anim:6
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -237,6 +187,7 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$('.layui-btn.layuiadmin-btn-admin').on('click', function(){
|
$('.layui-btn.layuiadmin-btn-admin').on('click', function(){
|
||||||
var type = $(this).data('type');
|
var type = $(this).data('type');
|
||||||
active[type] ? active[type].call(this) : '';
|
active[type] ? active[type].call(this) : '';
|
||||||
|
@ -41,13 +41,10 @@
|
|||||||
</div>
|
</div>
|
||||||
<table id="LAY-app-forumreply-list" lay-filter="LAY-app-forumreply-list"></table>
|
<table id="LAY-app-forumreply-list" lay-filter="LAY-app-forumreply-list"></table>
|
||||||
<script type="text/html" id="imgTpl">
|
<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>
|
||||||
<script type="text/html" id="buttonCheck">
|
<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}}" >
|
{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}
|
{else /}<button class="layui-btn layui-btn-xs layui-btn-radius layui-btn-disabled">无权限</button>{/if}
|
||||||
</script>
|
</script>
|
||||||
<script type="text/html" id="table-forum-replys">
|
<script type="text/html" id="table-forum-replys">
|
||||||
|
@ -10,7 +10,6 @@
|
|||||||
<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 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>
|
</div>
|
||||||
|
|
||||||
<div class="layui-col-md6">
|
<div class="layui-col-md6">
|
||||||
<div class="layui-card">
|
<div class="layui-card">
|
||||||
<div class="layui-card-header">快捷方式</div>
|
<div class="layui-card-header">快捷方式</div>
|
||||||
@ -127,7 +126,6 @@
|
|||||||
<div class="layui-card">
|
<div class="layui-card">
|
||||||
<div class="layui-card-header">数据概览</div>
|
<div class="layui-card-header">数据概览</div>
|
||||||
<div class="layui-card-body">
|
<div class="layui-card-body">
|
||||||
|
|
||||||
<div class="layui-carousel layadmin-carousel layadmin-dataview" data-anim="fade" lay-filter="LAY-index-dataview">
|
<div class="layui-carousel layadmin-carousel layadmin-dataview" data-anim="fade" lay-filter="LAY-index-dataview">
|
||||||
<div carousel-item id="LAY-index-dataview">
|
<div carousel-item id="LAY-index-dataview">
|
||||||
<div><i class="layui-icon layui-icon-loading1 layadmin-loading"></i></div>
|
<div><i class="layui-icon layui-icon-loading1 layadmin-loading"></i></div>
|
||||||
@ -135,7 +133,6 @@
|
|||||||
<div></div>
|
<div></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="layui-card">
|
<div class="layui-card">
|
||||||
@ -207,6 +204,14 @@
|
|||||||
<div class="layui-card">
|
<div class="layui-card">
|
||||||
<div class="layui-card-header">版本信息</div>
|
<div class="layui-card-header">版本信息</div>
|
||||||
<div class="layui-card-body layui-text">
|
<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">
|
<table class="layui-table">
|
||||||
<colgroup>
|
<colgroup>
|
||||||
<col width="100">
|
<col width="100">
|
||||||
@ -226,7 +231,7 @@
|
|||||||
<td>
|
<td>
|
||||||
<script type="text/html" template>
|
<script type="text/html" template>
|
||||||
TaoLer_{:config('taoler.version')}
|
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>
|
</script>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -367,6 +372,30 @@
|
|||||||
content: function(value){
|
content: function(value){
|
||||||
return layedit.sync(index);
|
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){
|
form.on('submit(cunsult-add)',function(data){
|
||||||
@ -438,7 +467,6 @@
|
|||||||
$.get("{:url('Index/getVersion')}",function(data){
|
$.get("{:url('Index/getVersion')}",function(data){
|
||||||
$('#up_version').html(data);
|
$('#up_version').html(data);
|
||||||
})
|
})
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
|
||||||
@ -449,10 +477,10 @@
|
|||||||
|
|
||||||
});
|
});
|
||||||
var indexForums = "{:url('Index/forums')}", //帖子
|
var indexForums = "{:url('Index/forums')}", //帖子
|
||||||
indexReplys = "{:url('Index/replys')}"; //回复
|
indexReplys = "{:url('Index/replys')}", //回复
|
||||||
var indexNews = "{:url('Index/news')}", //动态
|
indexNews = "{:url('Index/news')}", //动态
|
||||||
indexReply = "{:url('Index/reply')}"; //反馈
|
indexReply = "{:url('Index/reply')}", //反馈
|
||||||
var monthTime = "{$monthTime}",
|
monthTime = "{$monthTime}",
|
||||||
monthUserCount = "{$monthUserCount}";
|
monthUserCount = "{$monthUserCount}";
|
||||||
</script>
|
</script>
|
||||||
{/block}
|
{/block}
|
@ -1,7 +1,7 @@
|
|||||||
<!--
|
<!--
|
||||||
* @Author: TaoLer <alipey_tao@qq.com>
|
* @Author: TaoLer <alipey_tao@qq.com>
|
||||||
* @Date: 2021-12-06 16:04:50
|
* @Date: 2021-12-06 16:04:50
|
||||||
* @LastEditTime: 2022-04-21 11:05:47
|
* @LastEditTime: 2022-06-28 10:02:16
|
||||||
* @LastEditors: TaoLer
|
* @LastEditors: TaoLer
|
||||||
* @Description: 搜索引擎SEO优化设置
|
* @Description: 搜索引擎SEO优化设置
|
||||||
* @FilePath: \TaoLer\app\admin\view\public\base.html
|
* @FilePath: \TaoLer\app\admin\view\public\base.html
|
||||||
@ -19,9 +19,8 @@
|
|||||||
<link rel="stylesheet" href="/static/admin/style/admin.css" media="all">
|
<link rel="stylesheet" href="/static/admin/style/admin.css" media="all">
|
||||||
{block name="css"}{/block}
|
{block name="css"}{/block}
|
||||||
</head>
|
</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}
|
{block name="body"}内容{/block}
|
||||||
<script src="/static/layui/jquery.min.js" charset="utf-8"></script>
|
|
||||||
<script src="/static/layui/layui.js"></script>
|
<script src="/static/layui/layui.js"></script>
|
||||||
<script type="text/javascript" charset="utf-8">
|
<script type="text/javascript" charset="utf-8">
|
||||||
var AdminLogin = "{:url('Login/index')}",
|
var AdminLogin = "{:url('Login/index')}",
|
||||||
|
@ -1,14 +1,13 @@
|
|||||||
<!--
|
<!--
|
||||||
* @Author: TaoLer <alipey_tao@qq.com>
|
* @Author: TaoLer <alipey_tao@qq.com>
|
||||||
* @Date: 2021-12-06 16:04:50
|
* @Date: 2021-12-06 16:04:50
|
||||||
* @LastEditTime: 2022-04-21 11:06:13
|
* @LastEditTime: 2022-06-28 10:01:43
|
||||||
* @LastEditors: TaoLer
|
* @LastEditors: TaoLer
|
||||||
* @Description: 搜索引擎SEO优化设置
|
* @Description: 后台页脚结构
|
||||||
* @FilePath: \TaoLer\app\admin\view\public\footer.html
|
* @FilePath: \TaoLer\app\admin\view\public\footer.html
|
||||||
* Copyright (c) 2020~2022 http://www.aieok.com All rights reserved.
|
* Copyright (c) 2020~2022 http://www.aieok.com All rights reserved.
|
||||||
-->
|
-->
|
||||||
<div class="layui-footer">
|
<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>
|
</div>
|
@ -1,3 +1,12 @@
|
|||||||
|
<!--
|
||||||
|
* @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">
|
<div class="layui-header">
|
||||||
<!-- 头部区域 -->
|
<!-- 头部区域 -->
|
||||||
<ul class="layui-nav layui-layout-left">
|
<ul class="layui-nav layui-layout-left">
|
||||||
@ -21,7 +30,6 @@
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul class="layui-nav layui-layout-right" lay-filter="layadmin-layout-right">
|
<ul class="layui-nav layui-layout-right" lay-filter="layadmin-layout-right">
|
||||||
|
|
||||||
<li class="layui-nav-item" lay-unselect>
|
<li class="layui-nav-item" lay-unselect>
|
||||||
<a lay-href="app/message/index.html" layadmin-event="message" lay-text="消息中心">
|
<a lay-href="app/message/index.html" layadmin-event="message" lay-text="消息中心">
|
||||||
<i class="layui-icon layui-icon-notice"></i>
|
<i class="layui-icon layui-icon-notice"></i>
|
||||||
@ -61,7 +69,6 @@
|
|||||||
<dd layadmin-event="logout" style="text-align: center;"><a>退出</a></dd>
|
<dd layadmin-event="logout" style="text-align: center;"><a>退出</a></dd>
|
||||||
</dl>
|
</dl>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li class="layui-nav-item layui-hide-xs" lay-unselect>
|
<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>
|
<a href="javascript:;" layadmin-event=""><i class="layui-icon layui-icon-more-vertical"></i></a>
|
||||||
</li>
|
</li>
|
||||||
@ -69,4 +76,4 @@
|
|||||||
<a href="javascript:;" layadmin-event=""><i class="layui-icon layui-icon-more-vertical"></i></a>
|
<a href="javascript:;" layadmin-event=""><i class="layui-icon layui-icon-more-vertical"></i></a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
@ -1,6 +1,15 @@
|
|||||||
|
<!--
|
||||||
|
* @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 layui-side-menu">
|
||||||
<div class="layui-side-scroll">
|
<div class="layui-side-scroll">
|
||||||
<div class="layui-logo" lay-href="home/console.html">
|
<div class="layui-logo" lay-href="home/console.html">
|
||||||
<span>TaoLer_Admin</span>
|
<span>TaoLer_Admin</span>
|
||||||
@ -40,7 +49,7 @@
|
|||||||
</dl>
|
</dl>
|
||||||
</li-->
|
</li-->
|
||||||
|
|
||||||
{volist name="menu" id="vo1"}
|
{volist name="menu" id="vo1"}
|
||||||
{if condition="isset($vo1['children'])"}
|
{if condition="isset($vo1['children'])"}
|
||||||
<li data-name="set" class="layui-nav-item">
|
<li data-name="set" class="layui-nav-item">
|
||||||
<a href="javascript:;" lay-tips="{$vo1.title}" lay-direction="2">
|
<a href="javascript:;" lay-tips="{$vo1.title}" lay-direction="2">
|
||||||
@ -73,8 +82,8 @@
|
|||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{/if}
|
{/if}
|
||||||
{/volist}
|
{/volist}
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
@ -43,13 +43,23 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<label class="layui-form-label">LOGO</label>
|
<label class="layui-form-label">Logo</label>
|
||||||
<div class="layui-input-block">
|
<div class="layui-input-block">
|
||||||
<span><img src="{$sysInfo.logo}" hight="40" width="50" ></span>
|
<span><img src="{$sysInfo.logo}" hight="40" width="50" ></span>
|
||||||
{if condition="checkRuleButton('set/upload')"}
|
{if condition="checkRuleButton('set/upload')"}
|
||||||
<button type="button" class="layui-btn layui-btn-normal" id="logo-img">选择文件</button>
|
<button type="button" class="layui-btn layui-btn-sm" id="logo-img">选择文件</button>
|
||||||
<button type="button" class="layui-btn" id="logo-upload-button">开始上传</button>
|
<button type="button" class="layui-btn layui-btn-sm" id="logo-upload-button">开始上传</button>
|
||||||
{else /}<button type="button" class="layui-btn layui-btn-normal layui-btn-disabled">选择文件</button>{/if}
|
{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>
|
</div>
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
@ -202,6 +212,103 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="layui-tab-item">
|
<div class="layui-tab-item">
|
||||||
<div class="layui-form" wid100 lay-filter="config">
|
<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)}
|
{if($mailserver.active == 1)}
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<label class="layui-form-label">邮件通知:</label>
|
<label class="layui-form-label">邮件通知:</label>
|
||||||
@ -211,57 +318,6 @@
|
|||||||
<div class="layui-form-mid layui-word-aux">发帖及评论等邮件提醒(邮箱服务未激活无法设置)</div>
|
<div class="layui-form-mid layui-word-aux">发帖及评论等邮件提醒(邮箱服务未激活无法设置)</div>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/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>
|
|
||||||
<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-form-item">
|
||||||
<div class="layui-input-block">
|
<div class="layui-input-block">
|
||||||
<button class="layui-btn" lay-submit lay-filter="set_system_config">确认保存</button>
|
<button class="layui-btn" lay-submit lay-filter="set_system_config">确认保存</button>
|
||||||
@ -380,7 +436,7 @@
|
|||||||
upload.render({
|
upload.render({
|
||||||
elem: '#logo-img'
|
elem: '#logo-img'
|
||||||
,url: "{:url('set/upload')}"
|
,url: "{:url('set/upload')}"
|
||||||
,data: {type:'image'}
|
,data: {type:'image',field:'logo'}
|
||||||
,auto: false
|
,auto: false
|
||||||
,exts: 'jpg|png|gif|bmp|jpeg'
|
,exts: 'jpg|png|gif|bmp|jpeg'
|
||||||
,size: 1000
|
,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){
|
form.on('submit(set_system_config)', function(data){
|
||||||
var field = data.field;
|
var field = data.field;
|
||||||
|
@ -20,6 +20,8 @@
|
|||||||
<option value="9">9友情链接</option>
|
<option value="9">9友情链接</option>
|
||||||
<option value="10">10头部菜单</option>
|
<option value="10">10头部菜单</option>
|
||||||
<option value="11">11页脚链接</option>
|
<option value="11">11页脚链接</option>
|
||||||
|
<option value="12">12移动首页幻灯-360x172</option>
|
||||||
|
<option value="13">13首页右栏广告</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -75,7 +77,7 @@
|
|||||||
base: '/static/admin/' //静态资源所在路径
|
base: '/static/admin/' //静态资源所在路径
|
||||||
}).extend({
|
}).extend({
|
||||||
index: 'lib/index' //主入口模块
|
index: 'lib/index' //主入口模块
|
||||||
}).use(['index', 'form', 'upload','laydate','colorpicker', 'imgcom'], function(){
|
}).use(['index','imgcom'], function(){
|
||||||
var $ = layui.$
|
var $ = layui.$
|
||||||
,form = layui.form
|
,form = layui.form
|
||||||
,laydate = layui.laydate
|
,laydate = layui.laydate
|
||||||
@ -98,13 +100,13 @@
|
|||||||
,btns: ['clear', 'now']
|
,btns: ['clear', 'now']
|
||||||
,trigger: 'click'
|
,trigger: 'click'
|
||||||
});
|
});
|
||||||
|
|
||||||
//结束时间
|
//结束时间
|
||||||
laydate.render({
|
laydate.render({
|
||||||
elem: '#over-time'
|
elem: '#over-time'
|
||||||
,btns: ['clear', 'now']
|
,btns: ['clear', 'now']
|
||||||
,trigger: 'click'
|
,trigger: 'click'
|
||||||
});
|
});
|
||||||
|
|
||||||
//上传图片
|
//上传图片
|
||||||
upload.render({
|
upload.render({
|
||||||
elem: '#layuiadmin-upload-slid-img'
|
elem: '#layuiadmin-upload-slid-img'
|
||||||
@ -117,20 +119,11 @@
|
|||||||
imgcom.uploads(obj);
|
imgcom.uploads(obj);
|
||||||
}
|
}
|
||||||
,done: function(res){
|
,done: function(res){
|
||||||
//console.log(res)
|
|
||||||
$(this.item).prev("div").children("input").val(res.src)
|
$(this.item).prev("div").children("input").val(res.src)
|
||||||
if(res.code == 0){
|
if(res.code == 0){
|
||||||
layer.msg(res.msg,{
|
layer.msg(res.msg,{icon:6,tiye:2000});
|
||||||
icon:6,
|
|
||||||
tiye:2000
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
layer.open({
|
layer.open({title:"上传失败",content:res.msg,icon:5,anim:6});
|
||||||
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 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 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 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>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -25,6 +25,8 @@
|
|||||||
<option value="9">9友情链接</option>
|
<option value="9">9友情链接</option>
|
||||||
<option value="10">10头部菜单</option>
|
<option value="10">10头部菜单</option>
|
||||||
<option value="11">11页脚链接</option>
|
<option value="11">11页脚链接</option>
|
||||||
|
<option value="12">12移动首页幻灯</option>
|
||||||
|
<option value="13">13首页右栏广告</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -67,13 +69,13 @@
|
|||||||
,cols: [[ //表头
|
,cols: [[ //表头
|
||||||
{field: 'id', title: 'ID', width:80, sort: true, fixed: 'left'}
|
{field: 'id', title: 'ID', width:80, sort: true, fixed: 'left'}
|
||||||
,{field: 'slid_type', title: '位置', width:120}
|
,{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_name', title: '名称', width:180}
|
||||||
,{field: 'slid_href', title: 'URL', minWidth: 250}
|
,{field: 'slid_href', title: 'URL', minWidth: 250}
|
||||||
,{field: 'slid_color', title: '颜色', width: 80}
|
,{field: 'slid_color', title: '颜色', width: 80}
|
||||||
,{field: 'slid_start', title: '开始', width: 150, sort: true}
|
,{field: 'slid_start', title: '开始', width: 150, sort: true}
|
||||||
,{field: 'slid_over', 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}
|
,{fixed: 'right', title:'操作', toolbar: '#barDemo', width:150}
|
||||||
]]
|
]]
|
||||||
,limit: 15
|
,limit: 15
|
||||||
|
@ -61,14 +61,10 @@
|
|||||||
|
|
||||||
<table id="LAY-user-manage" lay-filter="LAY-user-manage"></table>
|
<table id="LAY-user-manage" lay-filter="LAY-user-manage"></table>
|
||||||
<script type="text/html" id="imgTpl">
|
<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>
|
||||||
<script type="text/html" id="sex">
|
<script type="text/html" id="sex">
|
||||||
{{# if(d.sex == 0){ }}
|
<span class="layui-btn {{ d.sex == 0 ? 'layui-btn-normal' : 'layui-btn-danger' }} layui-btn-xs" >{{ d.sex == 0 ? '男' : '女' }}</span>
|
||||||
<button class="layui-btn layui-btn-normal layui-btn-xs" >男</button>
|
|
||||||
{{# } else { }}
|
|
||||||
<button class="layui-btn layui-btn-danger layui-btn-xs">女</button>
|
|
||||||
{{# } }}
|
|
||||||
</script>
|
</script>
|
||||||
<script type="text/html" id="buttonCheck">
|
<script type="text/html" id="buttonCheck">
|
||||||
{{# if(d.id == '1'){ }}
|
{{# if(d.id == '1'){ }}
|
||||||
@ -86,11 +82,11 @@
|
|||||||
</script>
|
</script>
|
||||||
<script type="text/html" id="table-useradmin-webuser">
|
<script type="text/html" id="table-useradmin-webuser">
|
||||||
{if condition="checkRuleButton('user/useredit')"}
|
{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>
|
<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}
|
{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')"}
|
{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>
|
<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}
|
{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>
|
</script>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
{extend name="public/base" /}
|
{extend name="public/base" /}
|
||||||
|
|
||||||
{block name="body"}
|
{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" lay-filter="layuiadmin-form-useradmin" id="layuiadmin-form-useradmin" style="padding: 20px 0 0 0;">
|
||||||
<div class="layui-form-item layui-hide">
|
<div class="layui-form-item layui-hide">
|
||||||
<input type="text" name="id" class="layui-input" value="{$user.id}">
|
<input type="text" name="id" class="layui-input" value="{$user.id}">
|
||||||
@ -50,9 +49,8 @@
|
|||||||
base: '/static/admin/' //静态资源所在路径
|
base: '/static/admin/' //静态资源所在路径
|
||||||
}).extend({
|
}).extend({
|
||||||
index: 'lib/index' //主入口模块
|
index: 'lib/index' //主入口模块
|
||||||
}).use(['index', 'form', 'upload'], function(){
|
}).use(['index', 'upload'], function(){
|
||||||
var $ = layui.$
|
var $ = layui.$
|
||||||
,form = layui.form
|
|
||||||
,upload = layui.upload ;
|
,upload = layui.upload ;
|
||||||
//上传头像
|
//上传头像
|
||||||
upload.render({
|
upload.render({
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
{extend name="public/base" /}
|
{extend name="public/base" /}
|
||||||
|
|
||||||
{block name="body"}
|
{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" lay-filter="layuiadmin-form-useradmin" id="layuiadmin-form-useradmin" style="padding: 20px 30px 0 0;">
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<label class="layui-form-label">用户名</label>
|
<label class="layui-form-label">用户名</label>
|
||||||
@ -47,9 +46,8 @@
|
|||||||
base: '/static/admin/' //静态资源所在路径
|
base: '/static/admin/' //静态资源所在路径
|
||||||
}).extend({
|
}).extend({
|
||||||
index: 'lib/index' //主入口模块
|
index: 'lib/index' //主入口模块
|
||||||
}).use(['index', 'form', 'upload'], function(){
|
}).use(['index', 'upload'], function(){
|
||||||
var $ = layui.$
|
var $ = layui.$
|
||||||
,form = layui.form
|
|
||||||
,upload = layui.upload ;
|
,upload = layui.upload ;
|
||||||
//上传头像
|
//上传头像
|
||||||
upload.render({
|
upload.render({
|
||||||
|
@ -4,7 +4,6 @@ use PHPMailer\PHPMailer\PHPMailer;
|
|||||||
use PHPMailer\PHPMailer\Exception;
|
use PHPMailer\PHPMailer\Exception;
|
||||||
use think\facade\Request;
|
use think\facade\Request;
|
||||||
use think\facade\Db;
|
use think\facade\Db;
|
||||||
use think\facade\Cache;
|
|
||||||
use think\facade\Session;
|
use think\facade\Session;
|
||||||
use taoser\think\Auth;
|
use taoser\think\Auth;
|
||||||
|
|
||||||
@ -46,11 +45,13 @@ try {
|
|||||||
|
|
||||||
$mail->send();
|
$mail->send();
|
||||||
//echo 'Message has been sent';
|
//echo 'Message has been sent';
|
||||||
return true;
|
//return true;
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
//echo 'Message could not be sent. Mailer Error: ', $mail->ErrorInfo;
|
//echo 'Message could not be sent. Mailer Error: ', $mail->ErrorInfo;
|
||||||
return false;
|
//return false;
|
||||||
|
return $mail->ErrorInfo;
|
||||||
}
|
}
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//根据user area_id查询区域简称
|
//根据user area_id查询区域简称
|
||||||
@ -79,19 +80,28 @@ if(!function_exists('getUserImg'))
|
|||||||
//根据文章分类ID查询分类名
|
//根据文章分类ID查询分类名
|
||||||
function getCateName($ename)
|
function getCateName($ename)
|
||||||
{
|
{
|
||||||
|
if($ename == 'all') {
|
||||||
|
return '全部分类';
|
||||||
|
} else {
|
||||||
return Db::name('cate')->where('ename',$ename)->cache(3600)->value('catename');
|
return Db::name('cate')->where('ename',$ename)->cache(3600)->value('catename');
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//根据文章分类ID查询分类描述
|
//根据文章分类ID查询分类描述
|
||||||
function getCateDesc($ename)
|
function getCateDesc($ename)
|
||||||
{
|
{
|
||||||
|
if($ename == 'all') {
|
||||||
|
return '全部分类,为您展示全部分类信息';
|
||||||
|
} else {
|
||||||
return Db::name('cate')->where('ename',$ename)->cache(3600)->value('desc');
|
return Db::name('cate')->where('ename',$ename)->cache(3600)->value('desc');
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//过滤文章摘要
|
//过滤文章摘要
|
||||||
function getArtContent($content)
|
function getArtContent($content)
|
||||||
{
|
{
|
||||||
|
//过滤html标签
|
||||||
|
$content = strip_tags($content);
|
||||||
// 过滤音视频图片
|
// 过滤音视频图片
|
||||||
$content = preg_replace('/(?:img|audio|video)(\(\S+\))?\[\S+\]/','',$content);
|
$content = preg_replace('/(?:img|audio|video)(\(\S+\))?\[\S+\]/','',$content);
|
||||||
$content = preg_replace('/\s*/','',$content);
|
$content = preg_replace('/\s*/','',$content);
|
||||||
@ -257,3 +267,39 @@ function getSpaceNmu($level)
|
|||||||
{
|
{
|
||||||
return str_repeat('---',$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>
|
* @Author: TaoLer <alipay_tao@qq.com>
|
||||||
* @Date: 2021-12-06 16:04:50
|
* @Date: 2021-12-06 16:04:50
|
||||||
* @LastEditTime: 2022-05-12 16:02:40
|
* @LastEditTime: 2022-05-17 11:15:46
|
||||||
* @LastEditors: TaoLer
|
* @LastEditors: TaoLer
|
||||||
* @Description: 搜索引擎SEO优化设置
|
* @Description: 后台控制器设置
|
||||||
* @FilePath: \TaoLer\app\common\controller\AdminController.php
|
* @FilePath: \TaoLer\app\common\controller\AdminController.php
|
||||||
* Copyright (c) 2020~2022 https://www.aieok.com All rights reserved.
|
* 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\Session;
|
||||||
use think\facade\View;
|
use think\facade\View;
|
||||||
use think\facade\Db;
|
use think\facade\Db;
|
||||||
use think\facade\Request;
|
|
||||||
use taoser\think\Auth;
|
use taoser\think\Auth;
|
||||||
use taoler\com\Files;
|
use taoler\com\Files;
|
||||||
use think\facade\Lang;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 控制器基础类
|
* 控制器基础类
|
||||||
@ -76,7 +74,7 @@ class AdminController extends \app\BaseController
|
|||||||
protected function getMenus($type)
|
protected function getMenus($type)
|
||||||
{
|
{
|
||||||
$menu = [];
|
$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);
|
//var_export($auth_rule_list);
|
||||||
|
|
||||||
foreach ($auth_rule_list as $value) {
|
foreach ($auth_rule_list as $value) {
|
||||||
|
@ -1,13 +1,23 @@
|
|||||||
<?php
|
<?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);
|
declare (strict_types = 1);
|
||||||
|
|
||||||
namespace app\common\controller;
|
namespace app\common\controller;
|
||||||
|
|
||||||
use think\App;
|
use think\facade\Request;
|
||||||
use think\facade\View;
|
use think\facade\View;
|
||||||
use think\facade\Db;
|
use think\facade\Db;
|
||||||
use think\facade\Session;
|
use think\facade\Session;
|
||||||
use think\facade\Cache;
|
use think\facade\Cache;
|
||||||
|
use app\facade\Article;
|
||||||
use app\BaseController as BaseCtrl;
|
use app\BaseController as BaseCtrl;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -46,14 +56,6 @@ class BaseController extends BaseCtrl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* //判断密码找回是否已进行了邮件发送?
|
|
||||||
protected function isMailed()
|
|
||||||
{
|
|
||||||
if(Cache::get('repass') != 1){
|
|
||||||
$this->error('错误请求,请正确操作!','/index/user/forget');
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// 显示导航
|
// 显示导航
|
||||||
protected function showNav()
|
protected function showNav()
|
||||||
{
|
{
|
||||||
@ -81,24 +83,42 @@ class BaseController extends BaseCtrl
|
|||||||
return $user;
|
return $user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//热门标签
|
||||||
|
protected function getHotTag()
|
||||||
|
{
|
||||||
|
//热门标签
|
||||||
|
return Article::getHotTags();
|
||||||
|
//转换为字符串
|
||||||
|
// $tagStr = implode(",",$tags);
|
||||||
|
//转换为数组并去重
|
||||||
|
// return array_unique(explode(",",$tagStr));
|
||||||
|
}
|
||||||
|
|
||||||
//显示网站设置
|
//显示网站设置
|
||||||
protected function showSystem()
|
protected function showSystem()
|
||||||
{
|
{
|
||||||
//1.查询分类表获取所有分类
|
//1.查询分类表获取所有分类
|
||||||
$sysInfo = Db::name('system')->cache('system',3600)->find(1);
|
$sysInfo = $this->getSystem();
|
||||||
|
$slider = new \app\common\model\Slider();
|
||||||
//头部链接
|
//头部链接
|
||||||
$head_links = Cache::get('headlinks');
|
$head_links = $slider->getSliderList(10);
|
||||||
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);
|
|
||||||
}
|
|
||||||
//页脚链接
|
//页脚链接
|
||||||
$foot_links = Cache::get('footlinks');
|
$foot_links = $slider->getSliderList(11);
|
||||||
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();
|
$friend_links = $slider->getSliderList(9);
|
||||||
Cache::set('footlinks',$foot_links,3600);
|
//获取热门标签
|
||||||
}
|
$hotTag = $this->getHotTag();
|
||||||
View::assign(['sysInfo'=>$sysInfo,'headlinks'=>$head_links,'footlinks'=>$foot_links]);
|
|
||||||
|
$assign = [
|
||||||
|
'sysInfo' => $sysInfo,
|
||||||
|
'headlinks' => $head_links,
|
||||||
|
'footlinks' => $foot_links,
|
||||||
|
'flinks' => $friend_links,
|
||||||
|
'hotTag' => $hotTag,
|
||||||
|
'host' => Request::domain() . '/'
|
||||||
|
];
|
||||||
|
|
||||||
|
View::assign($assign);
|
||||||
return $sysInfo;
|
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 $fileType 上传文件的类型只能为:视频video,文件application,图片image,文本text
|
||||||
* @param string $type 获取文件的mime还是文件后缀ext
|
* @param string $type 获取文件的mime还是文件后缀ext
|
||||||
* @return array
|
* @return array
|
||||||
@ -57,28 +57,23 @@ class Uploads
|
|||||||
return $arr;
|
return $arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
//上传文件
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 上传文件
|
* 上传文件
|
||||||
|
* 1.可以指定目录(若目录前有SYS_前缀,会上传到public/sys系统目录,不指定前缀,会上传到public/storage/用户ID)
|
||||||
|
* 2.命名规则 可定义文件名类型a.jpg,b.php,或使用sha1,uniqid,md5函数
|
||||||
|
*
|
||||||
* @param string $fileName 文件名,form表单中的name
|
* @param string $fileName 文件名,form表单中的name
|
||||||
* @param string $dirName
|
* @param string $dirName 文件夹名,上传路径中的文件夹名称,sys_前缀存放在/public/sys系统目录
|
||||||
* @param int $fileSize
|
|
||||||
* @param string $fileType
|
|
||||||
* @return \think\response\Json
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $fileName 文件名,form表单中的name
|
|
||||||
* @param string $dirName 文件夹名,上传路径中的文件夹名称
|
|
||||||
* @param int $fileSize 文件大小,上传限制大小
|
* @param int $fileSize 文件大小,上传限制大小
|
||||||
* @param string $fileType 文件类型,只能为:视频video,文件application,图片image,文本text
|
* @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
|
* @return \think\response\Json
|
||||||
*/
|
*/
|
||||||
public function put(string $fileName, string $dirName, int $fileSize, string $fileType, string $rule = null)
|
public function put(string $fileName, string $dirName, int $fileSize, string $fileType, string $rule = null)
|
||||||
{
|
{
|
||||||
$file = request()->file($fileName);
|
$file = request()->file($fileName);
|
||||||
|
//halt($file->getOriginalName());
|
||||||
//$type = $file->getMime();
|
//$type = $file->getMime();
|
||||||
$fileExt = $this->getFileInfo($fileType,'ext');
|
$fileExt = $this->getFileInfo($fileType,'ext');
|
||||||
$fileMime = $this->getFileInfo($fileType,'mime');
|
$fileMime = $this->getFileInfo($fileType,'mime');
|
||||||
@ -90,21 +85,39 @@ class Uploads
|
|||||||
} catch (ValidateException $e) {
|
} catch (ValidateException $e) {
|
||||||
return json(['status'=>-1,'msg'=>$e->getMessage()]);
|
return json(['status'=>-1,'msg'=>$e->getMessage()]);
|
||||||
}
|
}
|
||||||
|
// 解析存储位置
|
||||||
$savename = \think\facade\Filesystem::disk('public')->putFile(session('user_id'). '/' .$dirName, $file, $rule);
|
$isSys = stripos($dirName, 'SYS_');
|
||||||
$upload = Config::get('filesystem.disks.public.url');
|
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){
|
if($savename){
|
||||||
//$name = $file->hashName();
|
//$name = $file->hashName();
|
||||||
$name_path =str_replace('\\',"/",$upload.'/'.$savename);
|
$name_path =str_replace('\\',"/", $uploadDir . '/' . $savename);
|
||||||
//halt($name_path);
|
|
||||||
//$image = \think\Image::open("uploads/$name_path");
|
//$image = \think\Image::open("uploads/$name_path");
|
||||||
//$image->thumb(168, 168)->save("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{
|
}else{
|
||||||
$res = ['status'=>-1,'msg'=>'上传错误'];
|
$res = ['status'=>-1,'msg'=>'上传错误'];
|
||||||
}
|
}
|
||||||
|
|
||||||
return json($res);
|
return json($res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ use think\Model;
|
|||||||
use think\model\concern\SoftDelete;
|
use think\model\concern\SoftDelete;
|
||||||
use think\facade\Cache;
|
use think\facade\Cache;
|
||||||
use think\facade\Config;
|
use think\facade\Config;
|
||||||
use think\facade\Db;
|
use Overtrue\Pinyin\Pinyin;
|
||||||
|
|
||||||
class Article extends Model
|
class Article extends Model
|
||||||
{
|
{
|
||||||
@ -45,6 +45,12 @@ class Article extends Model
|
|||||||
return $this->hasMany(Collection::class);
|
return $this->hasMany(Collection::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//文章关联用户点赞
|
||||||
|
public function userzan()
|
||||||
|
{
|
||||||
|
return $this->hasMany(UserZan::class);
|
||||||
|
}
|
||||||
|
|
||||||
//文章关联用户
|
//文章关联用户
|
||||||
public function user()
|
public function user()
|
||||||
{
|
{
|
||||||
@ -58,12 +64,13 @@ class Article extends Model
|
|||||||
*/
|
*/
|
||||||
public function add(array $data)
|
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');
|
$data['status'] = $superAdmin ? 1 : Config::get('taoler.config.posts_check');
|
||||||
$msg = $data['status'] ? '发布成功' : '发布成功,请等待审核';
|
$msg = $data['status'] ? '发布成功' : '发布成功,请等待审核';
|
||||||
$result = $this->save($data);
|
$result = $this->save($data);
|
||||||
if($result) {
|
if($result) {
|
||||||
return ['code'=>1,'msg'=>$msg];
|
return ['code' => 1, 'msg' => $msg, 'data' => ['status' => $data['status']]];
|
||||||
} else {
|
} else {
|
||||||
return 'add_error';
|
return 'add_error';
|
||||||
}
|
}
|
||||||
@ -79,7 +86,7 @@ class Article extends Model
|
|||||||
*/
|
*/
|
||||||
public function edit(array $data)
|
public function edit(array $data)
|
||||||
{
|
{
|
||||||
$article = $this->find($data['id']);
|
$article = $this::find($data['id']);
|
||||||
$result = $article->save($data);
|
$result = $article->save($data);
|
||||||
if($result) {
|
if($result) {
|
||||||
return 1;
|
return 1;
|
||||||
@ -107,7 +114,12 @@ class Article extends Model
|
|||||||
'user' => function ($query) {
|
'user' => function ($query) {
|
||||||
$query->field('id,name,nickname,user_img,area_id,vip');
|
$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);
|
Cache::tag('tagArtDetail')->set('arttop', $artTop, 60);
|
||||||
}
|
}
|
||||||
@ -134,7 +146,14 @@ class Article extends Model
|
|||||||
'user' => function($query){
|
'user' => function($query){
|
||||||
$query->field('id,name,nickname,user_img,area_id,vip');
|
$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);
|
Cache::tag('tagArt')->set('artlist',$artList,60);
|
||||||
}
|
}
|
||||||
return $artList;
|
return $artList;
|
||||||
@ -150,13 +169,19 @@ class Article extends Model
|
|||||||
*/
|
*/
|
||||||
public function getArtHot(int $num)
|
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')
|
->withCount('comments')
|
||||||
->where(['status'=>1,'delete_time'=>0])
|
->where(['status'=>1,'delete_time'=>0])
|
||||||
->whereTime('create_time', 'year')
|
->whereTime('create_time', 'year')
|
||||||
->order('comments_count','desc')
|
->order('comments_count','desc')
|
||||||
->limit($num)
|
->limit($num)
|
||||||
->withCache(60)->select();
|
->withCache(120)
|
||||||
|
->append(['url'])
|
||||||
|
->select();
|
||||||
|
|
||||||
return $artHot;
|
return $artHot;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,19 +193,23 @@ class Article extends Model
|
|||||||
* @throws \think\db\exception\DbException
|
* @throws \think\db\exception\DbException
|
||||||
* @throws \think\db\exception\ModelNotFoundException
|
* @throws \think\db\exception\ModelNotFoundException
|
||||||
*/
|
*/
|
||||||
public function getArtDetail(int $id, int $page)
|
public function getArtDetail(int $id)
|
||||||
{
|
{
|
||||||
$article = Cache::get('article_'.$id);
|
$article = Cache::get('article_'.$id);
|
||||||
if(!$article){
|
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){
|
'cate' => function($query){
|
||||||
$query->where('delete_time',0)->field('id,catename,ename');
|
$query->where('delete_time',0)->field('id,catename,ename');
|
||||||
},
|
},
|
||||||
'user' => function($query){
|
'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);
|
Cache::tag('tagArtDetail')->set('article_'.$id, $article, 3600);
|
||||||
}
|
}
|
||||||
return $article;
|
return $article;
|
||||||
@ -212,84 +241,143 @@ class Article extends Model
|
|||||||
switch ($type) {
|
switch ($type) {
|
||||||
//查询文章,15个分1页
|
//查询文章,15个分1页
|
||||||
case 'jie':
|
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([
|
$where['jie'] = 1;
|
||||||
'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();
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'hot':
|
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([
|
$where['is_hot'] = 1;
|
||||||
'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();
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'top':
|
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([
|
$where['is_top'] = 1;
|
||||||
'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();
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'wait':
|
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([
|
$where['jie'] = 0;
|
||||||
'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();
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
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([
|
$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){
|
'cate' => function($query){
|
||||||
$query->where('delete_time',0)->field('id,catename,ename');
|
$query->where('delete_time',0)->field('id,catename,ename');
|
||||||
},
|
},
|
||||||
'user' => function($query){
|
'user' => function($query){
|
||||||
$query->field('id,name,nickname,user_img,area_id,vip');
|
$query->field('id,name,nickname,user_img,area_id,vip');
|
||||||
}
|
}
|
||||||
])->withCount(['comments'])->where('status',1)->where($where)->order(['is_top'=>'desc','create_time'=>'desc'])
|
])->withCount(['comments'])
|
||||||
|
->where('status',1)
|
||||||
|
->where($where)
|
||||||
|
->order(['is_top'=>'desc','create_time'=>'desc'])
|
||||||
->paginate([
|
->paginate([
|
||||||
'list_rows' => 15,
|
'list_rows' => 15,
|
||||||
'page' => $page
|
'page' => $page
|
||||||
])->toArray();
|
])->append(['url'])->toArray();
|
||||||
break;
|
|
||||||
}
|
|
||||||
Cache::tag('tagArtDetail')->set('arts'.$ename.$type.$page,$artList,600);
|
Cache::tag('tagArtDetail')->set('arts'.$ename.$type.$page,$artList,600);
|
||||||
}
|
}
|
||||||
return $artList;
|
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
|
<?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;
|
namespace app\common\model;
|
||||||
|
|
||||||
use think\Model;
|
use think\Model;
|
||||||
@ -31,24 +40,38 @@ class Comment extends Model
|
|||||||
//获取评论
|
//获取评论
|
||||||
public function getComment($id, $page)
|
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;
|
return $comments;
|
||||||
}
|
}
|
||||||
|
|
||||||
//回帖榜
|
//回帖榜
|
||||||
public function reply($num)
|
public function reply($num)
|
||||||
{
|
{
|
||||||
$res = Cache::get('reply');
|
// $user = Cache::get('user_reply');
|
||||||
if(!$res){
|
// if(empty($user)){
|
||||||
$user = User::withCount('comments')->order(['comments_count'=>'desc','last_login_time'=>'desc'])->limit($num)->select()->toArray();
|
try {
|
||||||
if($user)
|
$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('user_reply',$user,180);
|
||||||
|
// }
|
||||||
|
|
||||||
|
if(count($user)) {
|
||||||
$res['status'] = 0;
|
$res['status'] = 0;
|
||||||
$res['data'] = array();
|
$res['data'] = array();
|
||||||
foreach ($user as $key=>$v) {
|
foreach ($user as $key=>$v) {
|
||||||
|
//$u['uid'] = (string) url('user/home',['id'=>$v['id']]);
|
||||||
$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'];
|
$u['count'] = $v['comments_count'];
|
||||||
if($v['nickname'])
|
if($v['nickname'])
|
||||||
{
|
{
|
||||||
$u['user'] = ['username'=>$v['nickname'],'avatar'=>$v['user_img']];
|
$u['user'] = ['username'=>$v['nickname'],'avatar'=>$v['user_img']];
|
||||||
@ -57,11 +80,42 @@ class Comment extends Model
|
|||||||
}
|
}
|
||||||
$res['data'][] = $u;
|
$res['data'][] = $u;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
$res = ['status' => 0, 'msg' =>'no reply'];
|
||||||
}
|
}
|
||||||
Cache::set('reply',$res,3600);
|
|
||||||
}
|
|
||||||
|
|
||||||
return json($res);
|
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
|
<?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;
|
namespace app\common\model;
|
||||||
|
|
||||||
use think\Model;
|
use think\Model;
|
||||||
@ -22,5 +31,14 @@ class MessageTo extends Model
|
|||||||
return $this->belongsTo('Message','message_id','id');
|
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
|
<?php
|
||||||
/*
|
/*
|
||||||
* @Author: TaoLer <alipey_tao@qq.com>
|
* @Author: TaoLer <alipay_tao@qq.com>
|
||||||
* @Date: 2021-12-06 16:04:50
|
* @Date: 2021-12-06 16:04:50
|
||||||
* @LastEditTime: 2022-05-01 17:10:55
|
* @LastEditTime: 2022-06-28 13:54:55
|
||||||
* @LastEditors: TaoLer
|
* @LastEditors: TaoLer
|
||||||
* @Description: 链接投放优化设置
|
* @Description: 链接设置
|
||||||
* @FilePath: \TaoLer\app\common\model\Slider.php
|
* @FilePath: \TaoLer\app\common\model\Slider.php
|
||||||
* Copyright (c) 2020~2022 http://www.aieok.com All rights reserved.
|
* Copyright (c) 2020~2022 http://www.aieok.com All rights reserved.
|
||||||
*/
|
*/
|
||||||
@ -44,41 +44,41 @@ class Slider extends Model
|
|||||||
$sliders = Cache::get('slider'.$type);
|
$sliders = Cache::get('slider'.$type);
|
||||||
if(!$sliders){
|
if(!$sliders){
|
||||||
$sliders = $this::where(['slid_status'=>1,'delete_time'=>0,'slid_type'=>$type])->whereTime('slid_over','>=',time())->select()->toArray();
|
$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;
|
return $sliders;
|
||||||
}
|
}
|
||||||
|
|
||||||
//添加
|
// 添加
|
||||||
public function add($data)
|
public function add($data)
|
||||||
{
|
{
|
||||||
$result = $this::save($data);
|
$result = $this::create($data);
|
||||||
|
|
||||||
if($result) {
|
if($result) {
|
||||||
Cache::tag('tagSlider')->clear();
|
Cache::tag('tagSlider'.$data['slid_type'])->clear();
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
return 'add_error';
|
return 'add_error';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//文章编辑
|
// 文章编辑
|
||||||
public function edit($data)
|
public function edit($data)
|
||||||
{
|
{
|
||||||
$slider = $this::find($data['id']);
|
$slider = $this::find($data['id']);
|
||||||
$result = $slider->save($data);
|
$result = $slider->save($data);
|
||||||
if($result) {
|
if($result) {
|
||||||
Cache::tag('tagSlider')->clear();
|
Cache::tag('tagSlider'.$data['slid_type'])->clear();
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
return 'edit_error';
|
return 'edit_error';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//获取器
|
// 获取器
|
||||||
public function getSlidTypeAttr($value)
|
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];
|
return $slid_type[$value];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ class UpgradeAuth extends Model
|
|||||||
|
|
||||||
public function getAuthLevelAttr($value)
|
public function getAuthLevelAttr($value)
|
||||||
{
|
{
|
||||||
$level = [0=>'免费版',1=>'初级版',2=>'高级版'];
|
$level = [0=>'免费版', 1=>'初级版', 2=>'中级版', 3=>'高级版'];
|
||||||
return $level[$value];
|
return $level[$value];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,6 +41,11 @@ class User extends Model
|
|||||||
return $this->belongsTo('UserArea','user_raea_id','id');
|
return $this->belongsTo('UserArea','user_raea_id','id');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function article()
|
||||||
|
{
|
||||||
|
return $this->hasMany(Article::class);
|
||||||
|
}
|
||||||
|
|
||||||
//登陆校验
|
//登陆校验
|
||||||
public function login($data)
|
public function login($data)
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,13 @@
|
|||||||
<?php
|
<?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;
|
namespace app\common\model;
|
||||||
|
|
||||||
use think\Model;
|
use think\Model;
|
||||||
@ -27,4 +36,10 @@ class UserZan extends Model
|
|||||||
return $this->belongsTo('User','user_id','id');
|
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
|
<?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;
|
namespace app\common\validate;
|
||||||
|
|
||||||
use think\Validate;
|
use think\Validate;
|
||||||
@ -42,7 +51,7 @@ class User extends Validate
|
|||||||
//注册验证场景
|
//注册验证场景
|
||||||
public function sceneReg()
|
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
|
<?php
|
||||||
|
|
||||||
namespace app\index\controller;
|
namespace app\index\controller;
|
||||||
|
|
||||||
use app\common\controller\BaseController;
|
use app\common\controller\BaseController;
|
||||||
@ -10,11 +11,13 @@ use think\facade\Config;
|
|||||||
use app\common\model\Comment;
|
use app\common\model\Comment;
|
||||||
use app\common\model\Article as ArticleModel;
|
use app\common\model\Article as ArticleModel;
|
||||||
use app\common\model\Slider;
|
use app\common\model\Slider;
|
||||||
use think\exception\ValidateException;
|
use app\common\model\UserZan;
|
||||||
use taoler\com\Message;
|
use taoler\com\Message;
|
||||||
use app\common\lib\Msgres;
|
use app\common\lib\Msgres;
|
||||||
use app\common\lib\Uploads;
|
use app\common\lib\Uploads;
|
||||||
use taoser\SetArr;
|
use taoser\SetArr;
|
||||||
|
use taoler\com\Api;
|
||||||
|
use Overtrue\Pinyin\Pinyin;
|
||||||
|
|
||||||
class Article extends BaseController
|
class Article extends BaseController
|
||||||
{
|
{
|
||||||
@ -43,7 +46,6 @@ class Article extends BaseController
|
|||||||
//分类列表
|
//分类列表
|
||||||
$article = new ArticleModel();
|
$article = new ArticleModel();
|
||||||
$artList = $article->getCateList($ename,$type,$page);
|
$artList = $article->getCateList($ename,$type,$page);
|
||||||
|
|
||||||
// 热议文章
|
// 热议文章
|
||||||
$artHot = $article->getArtHot(10);
|
$artHot = $article->getArtHot(10);
|
||||||
//广告
|
//广告
|
||||||
@ -70,20 +72,55 @@ class Article extends BaseController
|
|||||||
//输出内容
|
//输出内容
|
||||||
$page = input('page') ? input('page') : 1;
|
$page = input('page') ? input('page') : 1;
|
||||||
$article = new ArticleModel();
|
$article = new ArticleModel();
|
||||||
$artDetail = $article->getArtDetail($id,$page);
|
$artDetail = $article->getArtDetail($id);
|
||||||
// 设置tag内链
|
//用户个人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']);
|
$artDetail['content'] = $this->setArtTagLink($artDetail['content']);
|
||||||
|
|
||||||
// tag
|
// tag
|
||||||
$attr = explode(',', $artDetail['tags']);
|
// $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 = [];
|
$tags = [];
|
||||||
|
if(!is_null($artDetail['tags'])){
|
||||||
|
$attr = explode(',', $artDetail['tags']);
|
||||||
foreach($attr as $v){
|
foreach($attr as $v){
|
||||||
if ($v !='') {
|
if ($v !='') {
|
||||||
$tags[] = $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') : '';
|
$download = $artDetail['upzip'] ? download($artDetail['upzip'],'file') : '';
|
||||||
|
|
||||||
//$count = $comments->total();
|
//$count = $comments->total();
|
||||||
@ -95,7 +132,8 @@ class Article extends BaseController
|
|||||||
|
|
||||||
//评论
|
//评论
|
||||||
$comments = $this->getComments($id, $page);
|
$comments = $this->getComments($id, $page);
|
||||||
|
//最新评论时间
|
||||||
|
$lrDate_time = Db::name('comment')->where('article_id', $id)->max('update_time',false) ?? time();
|
||||||
// 热议文章
|
// 热议文章
|
||||||
$artHot = $article->getArtHot(10);
|
$artHot = $article->getArtHot(10);
|
||||||
//广告
|
//广告
|
||||||
@ -104,6 +142,7 @@ class Article extends BaseController
|
|||||||
$ad_artImg = $ad->getSliderList(4);
|
$ad_artImg = $ad->getSliderList(4);
|
||||||
//分类钻展赞助
|
//分类钻展赞助
|
||||||
$ad_comm = $ad->getSliderList(7);
|
$ad_comm = $ad->getSliderList(7);
|
||||||
|
//push
|
||||||
$push_js = Db::name('push_jscode')->where(['delete_time'=>0])->cache(true)->select();
|
$push_js = Db::name('push_jscode')->where(['delete_time'=>0])->cache(true)->select();
|
||||||
|
|
||||||
View::assign([
|
View::assign([
|
||||||
@ -115,8 +154,12 @@ class Article extends BaseController
|
|||||||
'tags' => $tags,
|
'tags' => $tags,
|
||||||
'page' => $page,
|
'page' => $page,
|
||||||
'comments' => $comments,
|
'comments' => $comments,
|
||||||
'jspage' => 'jie',
|
|
||||||
'push_js' => $push_js,
|
'push_js' => $push_js,
|
||||||
|
'cid' => $id,
|
||||||
|
'lrDate_time' => $lrDate_time,
|
||||||
|
'userZanList' => $userZanList,
|
||||||
|
'userTagCount'=> $userTagCount,
|
||||||
|
'jspage' => 'jie',
|
||||||
$download,
|
$download,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@ -133,16 +176,20 @@ class Article extends BaseController
|
|||||||
//文章评论
|
//文章评论
|
||||||
public function comment()
|
public function comment()
|
||||||
{
|
{
|
||||||
|
// 检验发帖是否开放
|
||||||
|
if(config('taoler.config.is_reply') == 0 ) return json(['code'=>-1,'msg'=>'抱歉,系统维护中,暂时禁止评论!']);
|
||||||
|
|
||||||
if (Request::isAjax()){
|
if (Request::isAjax()){
|
||||||
//获取评论
|
//获取评论
|
||||||
$data = Request::only(['content','article_id','user_id']);
|
$data = Request::only(['content','article_id','user_id']);
|
||||||
$sendId = $data['user_id'];
|
$sendId = $data['user_id'];
|
||||||
$art = Db::name('article')->field('id,status,is_reply,delete_time')->find($data['article_id']);
|
$art = Db::name('article')->field('id,status,is_reply,delete_time')->find($data['article_id']);
|
||||||
|
|
||||||
if($art['delete_time'] != 0 || $art['status'] != 1 || $art['is_reply'] != 1){
|
if($art['delete_time'] != 0 || $art['status'] != 1 || $art['is_reply'] != 1){
|
||||||
return json(['code'=>-1, 'msg'=>'评论不可用状态']);
|
return json(['code'=>-1, 'msg'=>'评论不可用状态']);
|
||||||
}
|
}
|
||||||
if(empty($data['content'])){
|
if(empty($data['content'])){
|
||||||
return json(['code'=>0, 'msg'=>'评论不能为空!']);
|
return json(['code'=>-1, 'msg'=>'评论不能为空!']);
|
||||||
}
|
}
|
||||||
$superAdmin = Db::name('user')->where('id',$sendId)->value('auth');
|
$superAdmin = Db::name('user')->where('id',$sendId)->value('auth');
|
||||||
$data['status'] = $superAdmin ? 1 : Config::get('taoler.config.commnets_check');
|
$data['status'] = $superAdmin ? 1 : Config::get('taoler.config.commnets_check');
|
||||||
@ -151,9 +198,12 @@ class Article extends BaseController
|
|||||||
//用户留言存入数据库
|
//用户留言存入数据库
|
||||||
if (Comment::create($data)) {
|
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'];
|
$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
|
//评论中回复@user comment
|
||||||
$preg = "/@([^@\s]*)\s/";
|
$preg = "/@([^@\s]*)\s/";
|
||||||
@ -180,9 +230,12 @@ class Article extends BaseController
|
|||||||
*/
|
*/
|
||||||
public function add()
|
public function add()
|
||||||
{
|
{
|
||||||
//dump(empty(config('taoler.baidu.client_id')));
|
|
||||||
if (Request::isAjax()) {
|
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)
|
if(Config::get('taoler.config.post_captcha') == 1)
|
||||||
{
|
{
|
||||||
@ -201,6 +254,8 @@ class Article extends BaseController
|
|||||||
// 获取内容图片音视频标识
|
// 获取内容图片音视频标识
|
||||||
$iva= $this->hasIva($data['content']);
|
$iva= $this->hasIva($data['content']);
|
||||||
$data = array_merge($data,$iva);
|
$data = array_merge($data,$iva);
|
||||||
|
// 获取分类ename
|
||||||
|
$cate_ename = Db::name('cate')->where('id',$data['cate_id'])->value('ename');
|
||||||
|
|
||||||
$article = new ArticleModel();
|
$article = new ArticleModel();
|
||||||
$result = $article->add($data);
|
$result = $article->add($data);
|
||||||
@ -212,24 +267,27 @@ class Article extends BaseController
|
|||||||
// 发提醒邮件
|
// 发提醒邮件
|
||||||
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.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 = $this->getRouteUrl((int)$aid, $cate_ename);
|
||||||
$link = (string)url('article/detail', ['id' => $aid]);
|
|
||||||
}else{
|
|
||||||
$link = (string)url('index/');
|
|
||||||
}
|
|
||||||
// 推送给百度收录接口
|
// 推送给百度收录接口
|
||||||
if(empty(config('taoler.baidu.push_api'))) {
|
$this->baiduPush($link);
|
||||||
$this->baiduPush($aid);
|
|
||||||
}
|
|
||||||
|
|
||||||
$res = Msgres::success($result['msg'], $link);
|
$url = $result['data']['status'] ? $link : (string)url('index/');
|
||||||
|
$res = Msgres::success($result['msg'], $url);
|
||||||
} else {
|
} else {
|
||||||
$res = Msgres::error('add_error');
|
$res = Msgres::error('add_error');
|
||||||
}
|
}
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
View::assign(['jspage'=>'jie']);
|
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) {
|
if($result == 1) {
|
||||||
//删除原有缓存显示编辑后内容
|
//删除原有缓存显示编辑后内容
|
||||||
Cache::delete('article_'.$id);
|
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($link);
|
||||||
$this->baiduPush($data['id']);
|
|
||||||
}
|
|
||||||
$editRes = Msgres::success('edit_success',$link);
|
$editRes = Msgres::success('edit_success',$link);
|
||||||
} else {
|
} else {
|
||||||
$editRes = Msgres::error($result);
|
$editRes = Msgres::error($result);
|
||||||
@ -282,16 +338,27 @@ class Article extends BaseController
|
|||||||
}
|
}
|
||||||
// 查询标签
|
// 查询标签
|
||||||
$tag = $article->tags;
|
$tag = $article->tags;
|
||||||
$attr = explode(',',$tag);
|
|
||||||
$tags = [];
|
$tags = [];
|
||||||
|
if(!is_null($tag)) {
|
||||||
|
$attr = explode(',',$tag);
|
||||||
foreach($attr as $key => $v){
|
foreach($attr as $key => $v){
|
||||||
if ($v !='') {
|
if ($v !='') {
|
||||||
$tags[] = $v;
|
$tags[] = $v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
View::assign(['article'=>$article,'tags'=>$tags,'jspage'=>'jie']);
|
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 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']);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 关键词
|
* 关键词
|
||||||
*
|
*
|
||||||
@ -432,7 +526,8 @@ class Article extends BaseController
|
|||||||
'access_token' => json_decode($res)->access_token,
|
'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;
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
//文章置顶,状态
|
// 文章置顶、加精、评论状态
|
||||||
public function jieset(){
|
public function jieset()
|
||||||
|
{
|
||||||
$data = Request::param();
|
$data = Request::param();
|
||||||
$article = ArticleModel::field('id,is_top,is_hot,is_reply')->find($data['id']);
|
$article = ArticleModel::field('id,is_top,is_hot,is_reply')->find($data['id']);
|
||||||
switch ($data['field']){
|
switch ($data['field']){
|
||||||
@ -482,22 +578,22 @@ class Article extends BaseController
|
|||||||
$res = ['status'=>0,'msg'=>'置顶成功'];
|
$res = ['status'=>0,'msg'=>'置顶成功'];
|
||||||
} else {
|
} else {
|
||||||
$article->save(['is_top' => 0]);
|
$article->save(['is_top' => 0]);
|
||||||
$res = ['status'=>0,'msg'=>'已取消置顶'];
|
$res = ['status'=>0,'msg'=>'置顶已取消'];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'hot':
|
case 'hot':
|
||||||
if($data['rank']==1){
|
if($data['rank']==1){
|
||||||
$article->save(['is_hot' => 1]);
|
$article->save(['is_hot' => 1]);
|
||||||
$res = ['status'=>0,'msg'=>'已设精贴'];
|
$res = ['status'=>0,'msg'=>'加精成功'];
|
||||||
} else {
|
} else {
|
||||||
$article->save(['is_hot' => 0]);
|
$article->save(['is_hot' => 0]);
|
||||||
$res = ['status'=>0,'msg'=>'精贴已取消'];
|
$res = ['status'=>0,'msg'=>'加精已取消'];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'reply':
|
case 'reply':
|
||||||
if($data['rank']==1){
|
if($data['rank']==1){
|
||||||
$article->save(['is_reply' => 1]);
|
$article->save(['is_reply' => 1]);
|
||||||
$res = ['status'=>0,'msg'=>'本帖禁评'];
|
$res = ['status'=>0,'msg'=>'禁评成功'];
|
||||||
} else {
|
} else {
|
||||||
$article->save(['is_reply' => 0]);
|
$article->save(['is_reply' => 0]);
|
||||||
$res = ['status'=>0,'msg'=>'禁评已取消'];
|
$res = ['status'=>0,'msg'=>'禁评已取消'];
|
||||||
@ -510,7 +606,7 @@ class Article extends BaseController
|
|||||||
return json($res);
|
return json($res);
|
||||||
}
|
}
|
||||||
|
|
||||||
//改变标题颜色
|
// 改变标题颜色
|
||||||
public function titleColor()
|
public function titleColor()
|
||||||
{
|
{
|
||||||
$data = Request::param();
|
$data = Request::param();
|
||||||
@ -555,21 +651,33 @@ class Article extends BaseController
|
|||||||
foreach($tag as $key=>$value) {
|
foreach($tag as $key=>$value) {
|
||||||
// 匹配所有
|
// 匹配所有
|
||||||
//$content = str_replace("$key", 'a('.$value.')['.$key.']',$content);
|
//$content = str_replace("$key", 'a('.$value.')['.$key.']',$content);
|
||||||
// 限定匹配数量
|
// 限定匹配数量 '/'.$key.'/'
|
||||||
$content = preg_replace('/'.$key.'/','a('.$value.')['.$key.']',$content,2);
|
// 匹配不包含[和]的内容
|
||||||
|
$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;
|
return $content;
|
||||||
}
|
}
|
||||||
|
|
||||||
// baidu push api
|
/**
|
||||||
protected function baiduPush($id)
|
* baidu push api
|
||||||
|
*
|
||||||
|
* @param string $link
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function baiduPush(string $link)
|
||||||
{
|
{
|
||||||
// baidu 接口
|
// baidu 接口
|
||||||
$api = config('taoler.baidu.push_api');
|
$api = config('taoler.baidu.push_api');
|
||||||
$artUrl = $this->getRouteUrl((int)$id);
|
if(!empty($api)) {
|
||||||
$url = [$artUrl];
|
$url[] = $link;
|
||||||
$ch = curl_init();
|
$ch = curl_init();
|
||||||
$options = array(
|
$options = array(
|
||||||
CURLOPT_URL => $api,
|
CURLOPT_URL => $api,
|
||||||
@ -581,6 +689,25 @@ class Article extends BaseController
|
|||||||
curl_setopt_array($ch, $options);
|
curl_setopt_array($ch, $options);
|
||||||
curl_exec($ch);
|
curl_exec($ch);
|
||||||
curl_close($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
|
<?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;
|
namespace app\index\controller;
|
||||||
|
|
||||||
use app\common\controller\BaseController;
|
use app\common\controller\BaseController;
|
||||||
use think\App;
|
|
||||||
use think\facade\View;
|
use think\facade\View;
|
||||||
use think\facade\Request;
|
use think\facade\Request;
|
||||||
use think\facade\Db;
|
use think\facade\Db;
|
||||||
@ -25,21 +33,21 @@ class Index extends BaseController
|
|||||||
|
|
||||||
$slider = new Slider();
|
$slider = new Slider();
|
||||||
//幻灯
|
//幻灯
|
||||||
$sliders = $slider->getSliderList(1);
|
$sliders = Request::isMobile() ? $slider->getSliderList(12) : $slider->getSliderList(1);
|
||||||
//置顶文章
|
//置顶文章
|
||||||
$artTop = Article::getArtTop(5);
|
$artTop = Article::getArtTop(5);
|
||||||
//首页文章列表,显示20个
|
//首页文章列表,显示20个
|
||||||
$artList = Article::getArtList(22);
|
$artList = Article::getArtList(22);
|
||||||
//热议文章
|
//热议文章
|
||||||
$artHot = Article::getArtHot(10);
|
$artHot = Article::getArtHot(10);
|
||||||
|
//首页广告
|
||||||
|
$indexAd = $slider->getSliderList(13);
|
||||||
//温馨通道
|
//温馨通道
|
||||||
$fast_links = $slider->getSliderList(8);
|
$fast_links = $slider->getSliderList(8);
|
||||||
//首页赞助
|
//首页赞助
|
||||||
$ad_index = $slider->getSliderList(5);
|
$ad_index = $slider->getSliderList(5);
|
||||||
//首页右栏图片
|
//首页右栏图片
|
||||||
$ad_comm = $slider->getSliderList(2);
|
$ad_comm = $slider->getSliderList(2);
|
||||||
//友情链接
|
|
||||||
$friend_links = $slider->getSliderList(9);
|
|
||||||
|
|
||||||
//友情链接申请
|
//友情链接申请
|
||||||
$adminEmail = Db::name('user')->where('id',1)->cache(true)->value('email');
|
$adminEmail = Db::name('user')->where('id',1)->cache(true)->value('email');
|
||||||
@ -49,11 +57,11 @@ class Index extends BaseController
|
|||||||
'artTop' => $artTop,
|
'artTop' => $artTop,
|
||||||
'artList' => $artList,
|
'artList' => $artList,
|
||||||
'artHot' => $artHot,
|
'artHot' => $artHot,
|
||||||
|
'ad_index_r'=> $indexAd,
|
||||||
'type' => $types,
|
'type' => $types,
|
||||||
'ad_index' => $ad_index,
|
'ad_index' => $ad_index,
|
||||||
'ad_comm' => $ad_comm,
|
'ad_comm' => $ad_comm,
|
||||||
'fastlinks' => $fast_links,
|
'fastlinks' => $fast_links,
|
||||||
'flinks' => $friend_links,
|
|
||||||
'adminEmail' => $adminEmail,
|
'adminEmail' => $adminEmail,
|
||||||
'jspage' => '',
|
'jspage' => '',
|
||||||
];
|
];
|
||||||
@ -69,34 +77,6 @@ class Index extends BaseController
|
|||||||
return $comment->reply(20);
|
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()
|
public function jump()
|
||||||
{
|
{
|
||||||
$username = Request::param('username');
|
$username = Request::param('username');
|
||||||
|
@ -38,7 +38,8 @@ class Login extends BaseController
|
|||||||
//获取登录前访问页面refer
|
//获取登录前访问页面refer
|
||||||
$refer = Request::server('HTTP_REFERER');
|
$refer = Request::server('HTTP_REFERER');
|
||||||
if(Request::isAjax()) {
|
if(Request::isAjax()) {
|
||||||
|
// 检验登录是否开放
|
||||||
|
if(config('taoler.config.is_login') == 0 ) return json(['code'=>-1,'msg'=>'抱歉,网站维护中,暂时不能登录哦!']);
|
||||||
//登陆前数据校验
|
//登陆前数据校验
|
||||||
$data = Request::param();
|
$data = Request::param();
|
||||||
if(Config::get('taoler.config.login_captcha') == 1)
|
if(Config::get('taoler.config.login_captcha') == 1)
|
||||||
@ -94,8 +95,31 @@ class Login extends BaseController
|
|||||||
//注册
|
//注册
|
||||||
public function reg()
|
public function reg()
|
||||||
{
|
{
|
||||||
|
|
||||||
if(Request::isAjax()){
|
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的方法数据
|
//校验场景中reg的方法数据
|
||||||
try{
|
try{
|
||||||
@ -203,12 +227,35 @@ class Login extends BaseController
|
|||||||
$user = new User();
|
$user = new User();
|
||||||
$res = $user->respass($data);
|
$res = $user->respass($data);
|
||||||
if ($res == 1) {
|
if ($res == 1) {
|
||||||
return json(['code'=>0,'msg'=>'修改成功','url'=>(string) url('login/index')]);
|
return json(['code'=> 0, 'msg'=> '修改成功', 'url'=>(string) url('login/index')]);
|
||||||
} else {
|
} else {
|
||||||
return json(['code'=>-1,'msg'=>'$res']);
|
return json(['code'=> -1, 'msg'=> '$res']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return View::fetch('forget');
|
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
|
<?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;
|
namespace app\index\controller;
|
||||||
|
|
||||||
use app\common\controller\BaseController;
|
use app\common\controller\BaseController;
|
||||||
@ -14,13 +23,12 @@ class Message extends BaseController
|
|||||||
//消息数目
|
//消息数目
|
||||||
public function nums()
|
public function nums()
|
||||||
{
|
{
|
||||||
$msg = Db::name('message_to')->where('receve_id',Session::get('user_id'))->where(['is_read'=>0,'delete_time'=>0])->select();
|
$messgeto = new MessageTo();
|
||||||
|
$num = $messgeto->getMsgNum($this->uid);
|
||||||
$count = $msg->count();
|
if(!is_null($num)){
|
||||||
if($count){
|
$res = ['status' =>0,'count' => $num, 'msg' => 'ok'];
|
||||||
$res=['status' =>0,'count' => $count, 'msg' => 'nums'];
|
|
||||||
} else {
|
} else {
|
||||||
$res=['status' =>0,'count' => 0, 'msg' => $count];
|
$res = ['status' =>-1,'count' => 0, 'msg' => 'message error'];
|
||||||
}
|
}
|
||||||
return json($res);
|
return json($res);
|
||||||
}
|
}
|
||||||
@ -28,8 +36,7 @@ class Message extends BaseController
|
|||||||
//消息查询
|
//消息查询
|
||||||
public function find()
|
public function find()
|
||||||
{
|
{
|
||||||
$uid = Session::get('user_id');
|
$msg = MessageApi::receveMsg($this->uid);
|
||||||
$msg = MessageApi::receveMsg($uid);
|
|
||||||
$count = $msg->count();
|
$count = $msg->count();
|
||||||
$res = [];
|
$res = [];
|
||||||
if($count){
|
if($count){
|
||||||
@ -39,7 +46,7 @@ class Message extends BaseController
|
|||||||
$res['rows'][] = $data;
|
$res['rows'][] = $data;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$res = ['status'=>0,'msg'=>'','rows'=>''];;
|
$res = ['status'=>-1,'msg'=>'message find error','rows'=>''];;
|
||||||
}
|
}
|
||||||
//var_dump($res);
|
//var_dump($res);
|
||||||
return json($res);
|
return json($res);
|
||||||
@ -62,7 +69,7 @@ class Message extends BaseController
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return json(['status' =>0]);
|
return json(['status' =>0, 'url'=>(string) url('User/message')]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,23 +1,45 @@
|
|||||||
<?php
|
<?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;
|
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)
|
//搜索功能
|
||||||
|
public function getSearch()
|
||||||
{
|
{
|
||||||
//全局查询条件
|
$ser = Request::only(['keywords']);
|
||||||
$map = []; //所有的查询条件封装到数组中
|
$artList = Article::getSearchKeyWord($ser['keywords']);
|
||||||
//条件1:
|
$counts = $artList->count();
|
||||||
$map[] = ['status','=',1]; //这里等号不能省略
|
$slider = new Slider();
|
||||||
|
//首页右栏
|
||||||
|
$ad_comm = $slider->getSliderList(2);
|
||||||
|
// 查询热议
|
||||||
|
$artHot = Article::getArtHot(10);
|
||||||
|
|
||||||
if(!empty($keywords)){
|
$searchs = [
|
||||||
//条件2
|
'artList' => $artList,
|
||||||
$map[] = ['title','like','%'.$keywords.'%'];
|
'keywords' => $ser['keywords'],
|
||||||
$res = Article::where($map)->withCount('comments')->order('create_time','desc')->paginate(10);
|
'counts' => $counts,
|
||||||
return $res;
|
'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()
|
public function status()
|
||||||
{
|
{
|
||||||
if(session('user_id')){
|
if($this->uid){
|
||||||
$res = $this->todayData()->getData();
|
$res = $this->todayData()->getData();
|
||||||
|
|
||||||
if($res['is_sign'] == 1){
|
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\Article;
|
||||||
use app\common\model\Collection;
|
use app\common\model\Collection;
|
||||||
use app\common\model\User as userModel;
|
use app\common\model\User as userModel;
|
||||||
use think\facade\Config;
|
use app\common\model\Comment;
|
||||||
use taoler\com\Message;
|
use taoler\com\Message;
|
||||||
|
|
||||||
class User extends BaseController
|
class User extends BaseController
|
||||||
@ -29,11 +29,10 @@ class User extends BaseController
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//发帖list
|
// 发帖list
|
||||||
public function artList()
|
public function artList()
|
||||||
{
|
{
|
||||||
$article = Article::withCount('comments')->where(['user_id'=>$this->uid])->order('update_time','desc')->paginate(10);
|
$article = Article::withCount('comments')->where(['user_id'=>$this->uid])->order('update_time','desc')->paginate(10);
|
||||||
//var_dump($article);
|
|
||||||
$count = $article->total();
|
$count = $article->total();
|
||||||
$res = [];
|
$res = [];
|
||||||
if($count){
|
if($count){
|
||||||
@ -43,6 +42,7 @@ class User extends BaseController
|
|||||||
$res['data'][] = ['id'=>$v['id'],
|
$res['data'][] = ['id'=>$v['id'],
|
||||||
'title' => htmlspecialchars($v['title']),
|
'title' => htmlspecialchars($v['title']),
|
||||||
'url' => (string) url('article/detail',['id'=>$v['id']]),
|
'url' => (string) url('article/detail',['id'=>$v['id']]),
|
||||||
|
'url' => $this->getRouteUrl($v['id'], $v->cate->ename),
|
||||||
'status' => $v['status'] ? '正常':'待审核',
|
'status' => $v['status'] ? '正常':'待审核',
|
||||||
'ctime' => $v['create_time'],
|
'ctime' => $v['create_time'],
|
||||||
'datas' => $v['pv'].'阅/'.$v['comments_count'].'答'
|
'datas' => $v['pv'].'阅/'.$v['comments_count'].'答'
|
||||||
@ -55,8 +55,9 @@ class User extends BaseController
|
|||||||
return json($res);
|
return json($res);
|
||||||
}
|
}
|
||||||
|
|
||||||
//收藏list
|
// 收藏list
|
||||||
public function collList(){
|
public function collList()
|
||||||
|
{
|
||||||
//收藏的帖子
|
//收藏的帖子
|
||||||
$collect = Collection::with(['article'=>function($query){
|
$collect = Collection::with(['article'=>function($query){
|
||||||
$query->withCount('comments')->where('status',1);
|
$query->withCount('comments')->where('status',1);
|
||||||
@ -71,7 +72,7 @@ class User extends BaseController
|
|||||||
$res['data'][] = [
|
$res['data'][] = [
|
||||||
'id' =>$v['id'],
|
'id' =>$v['id'],
|
||||||
'title' => htmlspecialchars($v['collect_title']),
|
'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'],
|
'auther' => $v['auther'],
|
||||||
'status' => is_null(Db::name('article')->field('id')->where('delete_time',0)->find($v['article_id'])) ? '已失效' : '正常',
|
'status' => is_null(Db::name('article')->field('id')->where('delete_time',0)->find($v['article_id'])) ? '已失效' : '正常',
|
||||||
'ctime' => $v['create_time']
|
'ctime' => $v['create_time']
|
||||||
@ -112,6 +113,15 @@ class User extends BaseController
|
|||||||
{
|
{
|
||||||
if(Request::isAjax()){
|
if(Request::isAjax()){
|
||||||
$data = Request::only(['user_id','email','nickname','sex','city','area_id','sign']);
|
$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;
|
$validate = new userValidate;
|
||||||
$result = $validate->scene('Set')->check($data);
|
$result = $validate->scene('Set')->check($data);
|
||||||
if(!$result){
|
if(!$result){
|
||||||
@ -131,7 +141,7 @@ class User extends BaseController
|
|||||||
$result = $user->setNew($data);
|
$result = $user->setNew($data);
|
||||||
if($result == 1){
|
if($result == 1){
|
||||||
Cache::tag('user')->clear();
|
Cache::tag('user')->clear();
|
||||||
return ['code'=>0,'msg'=>'资料更新成功'];
|
return json(['code'=>0,'msg'=>'资料更新成功']);
|
||||||
} else {
|
} else {
|
||||||
$this->error($result);
|
$this->error($result);
|
||||||
}
|
}
|
||||||
@ -167,12 +177,12 @@ class User extends BaseController
|
|||||||
->update(['user_img'=>$name_path]);
|
->update(['user_img'=>$name_path]);
|
||||||
Cache::tag(['user','tagArtDetail','tagArt'])->clear();
|
Cache::tag(['user','tagArtDetail','tagArt'])->clear();
|
||||||
if($result) {
|
if($result) {
|
||||||
$res = ['status'=>0,'msg'=>'头像更新成功'];
|
$res = ['code'=>0,'msg'=>'头像更新成功'];
|
||||||
} else {
|
} else {
|
||||||
$res = ['status'=>1,'msg'=>'头像更新失败'];
|
$res = ['code'=>1,'msg'=>'头像更新失败'];
|
||||||
}
|
}
|
||||||
} else {
|
} 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);
|
$u = Db::name('user')->field('name,nickname,city,sex,sign,user_img,point,vip,create_time')->cache(3600)->find($id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$article = new Article();
|
||||||
|
$commont = new Comment();
|
||||||
|
$arts = $article->getUserArtList((int) $id);
|
||||||
|
|
||||||
//用户发贴
|
// $reys = $commont->getUserCommentList((int) $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();
|
// 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'=>'']);
|
View::assign(['u'=>$u,'arts'=>$arts,'reys'=>$reys,'jspage'=>'']);
|
||||||
return View::fetch();
|
return View::fetch();
|
||||||
|
@ -67,9 +67,9 @@ return [
|
|||||||
'go sign' => '去签到',
|
'go sign' => '去签到',
|
||||||
'more post' => '更多帖子',
|
'more post' => '更多帖子',
|
||||||
'friendly link' => '友情链接',
|
'friendly link' => '友情链接',
|
||||||
'reviewers list' => '回帖热榜',
|
'reviewers list' => '活跃榜',
|
||||||
'hot post list' => '本周热议',
|
'hot post list' => '本周热议',
|
||||||
'links list' => '温馨通道',
|
'links list' => '快捷导航',
|
||||||
'statement' => '说明',
|
'statement' => '说明',
|
||||||
'trends' => '动态',
|
'trends' => '动态',
|
||||||
'sponsor' => '钻级赞助商',
|
'sponsor' => '钻级赞助商',
|
||||||
@ -105,7 +105,7 @@ return [
|
|||||||
'submit' => '提交',
|
'submit' => '提交',
|
||||||
'go back' => '返回',
|
'go back' => '返回',
|
||||||
'register now' => '立即注册',
|
'register now' => '立即注册',
|
||||||
'mail/username' => '邮箱/用户名',
|
'mail/username/mobile' => '邮箱/用户名/手机号',
|
||||||
'6-16 characters' => '6-16 字符',
|
'6-16 characters' => '6-16 字符',
|
||||||
'strong type encryption' => '经过强类型加密',
|
'strong type encryption' => '经过强类型加密',
|
||||||
'it cannot be changed' => '不能更改',
|
'it cannot be changed' => '不能更改',
|
||||||
|
@ -2,11 +2,11 @@
|
|||||||
/*
|
/*
|
||||||
* @Author: TaoLer <alipey_tao@qq.com>
|
* @Author: TaoLer <alipey_tao@qq.com>
|
||||||
* @Date: 2021-12-06 16:04:50
|
* @Date: 2021-12-06 16:04:50
|
||||||
* @LastEditTime: 2022-04-22 16:25:14
|
* @LastEditTime: 2022-07-26 13:58:17
|
||||||
* @LastEditors: TaoLer
|
* @LastEditors: TaoLer
|
||||||
* @Description: 搜索引擎SEO优化设置
|
* @Description: 前端路由设置
|
||||||
* @FilePath: \TaoLer\app\index\route\route.php
|
* @FilePath: \github\TaoLer\app\index\route\route.php
|
||||||
* Copyright (c) 2020~2022 http://www.aieok.com All rights reserved.
|
* Copyright (c) 2020~2022 https://www.aieok.com All rights reserved.
|
||||||
*/
|
*/
|
||||||
use think\facade\Route;
|
use think\facade\Route;
|
||||||
|
|
||||||
@ -17,30 +17,58 @@ $cate_as = config('taoler.url_rewrite.cate_as');
|
|||||||
|
|
||||||
Route::get('captcha/[:config]','\\think\\captcha\\CaptchaController@index');
|
Route::get('captcha/[:config]','\\think\\captcha\\CaptchaController@index');
|
||||||
Route::rule('/', '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::group(function () use($detail_as,$cate_as){
|
||||||
Route::get("$detail_as<id>", 'article/detail');
|
Route::rule('add/[:cate]','Article/add')->name('add_article');
|
||||||
Route::get("$cate_as<ename>$",'article/cate')->name('cate');
|
Route::rule('delete/[:id]','Article/delete');
|
||||||
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('tags','Article/tags')->allowCrossDomain();
|
Route::rule('tags','Article/tags')->allowCrossDomain();
|
||||||
Route::rule('edit/[:id]','Article/edit');
|
Route::rule('edit/[:id]','Article/edit');
|
||||||
})->pattern([
|
// 动态路径路由会影响下面的路由,所以动态路由放下面
|
||||||
|
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+',
|
'ename' => '\w+',
|
||||||
'type' => '\w+',
|
'type' => '\w+',
|
||||||
'page' => '\d+',
|
'page' => '\d+',
|
||||||
'id' => '\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'); // 搜索
|
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禁止',
|
`status` enum('0','-1','1') NOT NULL DEFAULT '1' COMMENT '状态1显示0待审-1禁止',
|
||||||
`cate_id` int(11) NOT NULL COMMENT '分类id',
|
`cate_id` int(11) NOT NULL COMMENT '分类id',
|
||||||
`user_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_top` enum('0','1') NOT NULL DEFAULT '0' COMMENT '置顶1否0',
|
||||||
`is_hot` 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可评',
|
`is_reply` enum('1','0') NOT NULL DEFAULT '1' COMMENT '0禁评1可评',
|
||||||
@ -76,7 +77,7 @@ CREATE TABLE `tao_article` (
|
|||||||
PRIMARY KEY (`id`),
|
PRIMARY KEY (`id`),
|
||||||
KEY `user_id` (`user_id`) USING BTREE COMMENT '文章的用户索引',
|
KEY `user_id` (`user_id`) USING BTREE COMMENT '文章的用户索引',
|
||||||
KEY `cate_id` (`cate_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
|
-- Records of tao_article
|
||||||
@ -141,7 +142,7 @@ CREATE TABLE `tao_auth_group_copy` (
|
|||||||
`update_time` int(11) NOT NULL DEFAULT '0' COMMENT '更新时间',
|
`update_time` int(11) NOT NULL DEFAULT '0' COMMENT '更新时间',
|
||||||
`delete_time` int(11) NOT NULL DEFAULT '0' COMMENT '删除时间',
|
`delete_time` int(11) NOT NULL DEFAULT '0' COMMENT '删除时间',
|
||||||
PRIMARY KEY (`id`)
|
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
|
-- Records of tao_auth_group_copy
|
||||||
@ -310,7 +311,7 @@ CREATE TABLE `tao_collection` (
|
|||||||
`create_time` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间',
|
`create_time` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间',
|
||||||
`delete_time` int(11) NOT NULL DEFAULT '0' COMMENT '删除时间',
|
`delete_time` int(11) NOT NULL DEFAULT '0' COMMENT '删除时间',
|
||||||
PRIMARY KEY (`id`)
|
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
|
-- Table structure for tao_comment
|
||||||
@ -350,7 +351,7 @@ CREATE TABLE `tao_cunsult` (
|
|||||||
`create_time` int(10) NOT NULL DEFAULT '0' COMMENT '创建时间',
|
`create_time` int(10) NOT NULL DEFAULT '0' COMMENT '创建时间',
|
||||||
`delete_time` int(10) NOT NULL DEFAULT '0' COMMENT '删除时间',
|
`delete_time` int(10) NOT NULL DEFAULT '0' COMMENT '删除时间',
|
||||||
PRIMARY KEY (`id`)
|
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
|
-- Table structure for tao_friend_link
|
||||||
@ -460,7 +461,7 @@ CREATE TABLE `tao_slider` (
|
|||||||
`slid_name` varchar(30) NOT NULL COMMENT '幻灯名',
|
`slid_name` varchar(30) NOT NULL COMMENT '幻灯名',
|
||||||
`slid_type` tinyint(1) NOT NULL DEFAULT '1' COMMENT '类型',
|
`slid_type` tinyint(1) NOT NULL DEFAULT '1' COMMENT '类型',
|
||||||
`slid_img` varchar(70) NOT NULL DEFAULT '' 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_color` varchar(10) NOT NULL DEFAULT '' COMMENT '广告块颜色',
|
||||||
`slid_start` int(11) NOT NULL DEFAULT '0' COMMENT '开始时间',
|
`slid_start` int(11) NOT NULL DEFAULT '0' COMMENT '开始时间',
|
||||||
`slid_over` 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,
|
`domain` varchar(50) NOT NULL,
|
||||||
`template` varchar(30) NOT NULL DEFAULT '' COMMENT '模板',
|
`template` varchar(30) NOT NULL DEFAULT '' COMMENT '模板',
|
||||||
`logo` varchar(70) NOT NULL DEFAULT '' COMMENT '网站logo',
|
`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 '缓存时间分钟',
|
`cache` tinyint(5) NOT NULL DEFAULT '0' COMMENT '缓存时间分钟',
|
||||||
`upsize` int(5) NOT NULL DEFAULT '0' COMMENT '上传文件大小KB',
|
`upsize` int(5) NOT NULL DEFAULT '0' COMMENT '上传文件大小KB',
|
||||||
`uptype` varchar(255) NOT NULL DEFAULT '0' COMMENT '上传文件类型',
|
`uptype` varchar(255) NOT NULL DEFAULT '0' COMMENT '上传文件类型',
|
||||||
`copyright` varchar(100) NOT NULL DEFAULT '' COMMENT '版权',
|
`copyright` varchar(100) NOT NULL DEFAULT '' COMMENT '版权',
|
||||||
`keywords` tinytext NOT NULL COMMENT '网站关键字',
|
`keywords` tinytext NOT NULL COMMENT '网站关键字',
|
||||||
`descript` 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_open` enum('0','1') NOT NULL DEFAULT '1' COMMENT '是否开启站点1开启0关闭',
|
||||||
`is_comment` 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禁止',
|
`is_reg` enum('0','1') NOT NULL DEFAULT '1' COMMENT '是否开放注册1开启0禁止',
|
||||||
@ -515,7 +518,7 @@ CREATE TABLE `tao_system` (
|
|||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of 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
|
-- Table structure for tao_user
|
||||||
@ -532,7 +535,7 @@ CREATE TABLE `tao_user` (
|
|||||||
`city` varchar(50) NOT NULL DEFAULT '' COMMENT '归属地',
|
`city` varchar(50) NOT NULL DEFAULT '' COMMENT '归属地',
|
||||||
`sex` enum('0','1') NOT NULL DEFAULT '0' COMMENT '性别0男1女',
|
`sex` enum('0','1') NOT NULL DEFAULT '0' COMMENT '性别0男1女',
|
||||||
`sign` varchar(255) NOT NULL DEFAULT '' COMMENT '签名',
|
`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超级',
|
`auth` enum('1','0') NOT NULL DEFAULT '0' COMMENT '管理员权限0普通1超级',
|
||||||
`point` int(11) NOT NULL DEFAULT '0' COMMENT '积分',
|
`point` int(11) NOT NULL DEFAULT '0' COMMENT '积分',
|
||||||
`area_id` int(11) DEFAULT NULL COMMENT '用户所属区域ID',
|
`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`;
|
DROP TABLE IF EXISTS `tao_user_zan`;
|
||||||
CREATE TABLE `tao_user_zan` (
|
CREATE TABLE `tao_user_zan` (
|
||||||
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '点赞主键id',
|
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '点赞主键id',
|
||||||
|
`article_id` int DEFAULT NULL COMMENT '文章id',
|
||||||
`comment_id` int(11) NOT NULL COMMENT '评论id',
|
`comment_id` int(11) NOT NULL COMMENT '评论id',
|
||||||
`user_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 '点赞时间',
|
`create_time` int(11) NOT NULL DEFAULT '0' COMMENT '点赞时间',
|
||||||
PRIMARY KEY (`id`)
|
PRIMARY KEY (`id`)
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
) 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" /}
|
{extend name="index/base" /}
|
||||||
{block name="body"}
|
{block name="body"}
|
||||||
<div class="inside2">
|
<div class="inside2">
|
||||||
@ -15,7 +24,7 @@
|
|||||||
<p>9、在理解、同意、并遵守本协议的全部条款后,方可开始使用本程序。本许可协议条款的解释,效力及纠纷的解决,适用于中华人民共和国大陆法律。</p>
|
<p>9、在理解、同意、并遵守本协议的全部条款后,方可开始使用本程序。本许可协议条款的解释,效力及纠纷的解决,适用于中华人民共和国大陆法律。</p>
|
||||||
<p>10、您使用本系统,需要遵循许可协议,一旦安装表示您已接受该系统各项条款。</p>
|
<p>10、您使用本系统,需要遵循许可协议,一旦安装表示您已接受该系统各项条款。</p>
|
||||||
<div class="inout1">
|
<div class="inout1">
|
||||||
<a>拒绝安装</a>
|
<a id="no-install">拒绝安装</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="inout2">
|
<div class="inout2">
|
||||||
<a href="{:url('index/test')}">同意安装</a>
|
<a href="{:url('index/test')}">同意安装</a>
|
||||||
@ -24,3 +33,19 @@
|
|||||||
</br>
|
</br>
|
||||||
</div>
|
</div>
|
||||||
{/block}
|
{/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>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>TaoLer安装程序</title>
|
<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/res/css/admin.css">
|
||||||
<link rel="stylesheet" href="/static/layui/css/layui.css">
|
<link rel="stylesheet" href="/static/layui/css/layui.css">
|
||||||
<script src="/static/layui/layui.js"></script>
|
<script src="/static/layui/layui.js"></script>
|
||||||
@ -34,7 +41,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{block name="body"}主题{/block}
|
{block name="body"}主题{/block}
|
||||||
|
<script>
|
||||||
|
var $ = layui.jquery;
|
||||||
|
var layer = layui.layer;
|
||||||
|
</script>
|
||||||
|
{block name="script"}{/block}
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
@ -5,16 +5,13 @@
|
|||||||
<div class="inwp cl">
|
<div class="inwp cl">
|
||||||
<form class="layui-form layui-form-pane" >
|
<form class="layui-form layui-form-pane" >
|
||||||
<h2>创建数据库:</h2>
|
<h2>创建数据库:</h2>
|
||||||
|
|
||||||
<input type="hidden" name="DB_TYPE" value="mysql">
|
<input type="hidden" name="DB_TYPE" value="mysql">
|
||||||
|
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<label class="layui-form-label">数据库服务器</label>
|
<label class="layui-form-label">数据库服务器</label>
|
||||||
<div class="layui-input-block">
|
<div class="layui-input-block">
|
||||||
<input type="text" name="DB_HOST" value="127.0.0.1" required lay-verify="required" autocomplete="off" class="layui-input">
|
<input type="text" name="DB_HOST" value="127.0.0.1" required lay-verify="required" autocomplete="off" class="layui-input">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<label class="layui-form-label">数据库账号</label>
|
<label class="layui-form-label">数据库账号</label>
|
||||||
<div class="layui-input-block">
|
<div class="layui-input-block">
|
||||||
@ -91,14 +88,17 @@
|
|||||||
<input type="submit" lay-submit lay-filter="formDemo" value="确认安装">
|
<input type="submit" lay-submit lay-filter="formDemo" value="确认安装">
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<script>
|
</div>
|
||||||
|
</div>
|
||||||
|
{/block}
|
||||||
|
{block name="script"}
|
||||||
|
<script>
|
||||||
layui.use('form', function() {
|
layui.use('form', function() {
|
||||||
var $ = layui.jquery,
|
var $ = layui.jquery,
|
||||||
form = layui.form;
|
form = layui.form;
|
||||||
|
|
||||||
form.on('submit(formDemo)', function(data){
|
form.on('submit(formDemo)', function(data){
|
||||||
var field = data.field;
|
var field = data.field;
|
||||||
//console.log(field); //当前容器的全部表单字段,名值对形式:{name: value}
|
|
||||||
loading = layer.load(2, {
|
loading = layer.load(2, {
|
||||||
shade: [0.2, '#000'],
|
shade: [0.2, '#000'],
|
||||||
time: 2000,
|
time: 2000,
|
||||||
@ -112,28 +112,17 @@
|
|||||||
success:function (data){
|
success:function (data){
|
||||||
if (data.code == 0) {
|
if (data.code == 0) {
|
||||||
layer.close(loading);
|
layer.close(loading);
|
||||||
layer.msg(data.msg,{
|
layer.msg(data.msg,{icon:6,time:2000}, function(){
|
||||||
icon:6,
|
|
||||||
time:2000
|
|
||||||
}, function(){
|
|
||||||
location.href = data.url;
|
location.href = data.url;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
layer.open({
|
layer.open({tiele:'安装失败',content:data.msg,icon:5,anim:6});
|
||||||
tiele:'安装失败',
|
|
||||||
content:data.msg,
|
|
||||||
icon:5,
|
|
||||||
anim:6
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
return false; //阻止表单跳转。如果需要表单跳转,去掉这段即可。
|
return false; //阻止表单跳转。如果需要表单跳转,去掉这段即可。
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{/block}
|
{/block}
|
@ -119,13 +119,16 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
|
||||||
|
{/block}
|
||||||
|
{block name="script"}
|
||||||
|
<script>
|
||||||
function testClick() {
|
function testClick() {
|
||||||
if ($('.yes').length != 7) {
|
if ($('.yes').length != 7) {
|
||||||
alert('您的配置或权限不符合要求');
|
alert('您的配置或权限不符合要求');
|
||||||
} else {
|
} else {
|
||||||
location.href = '{:url('index/create')}';
|
location.href = "{:url('index/create')}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
{/block}
|
{/block}
|
@ -1,6 +1,15 @@
|
|||||||
|
<!--
|
||||||
|
* @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" /}
|
{extend name="index/base" /}
|
||||||
{block name="body"}
|
{block name="body"}
|
||||||
<div class="inside2">
|
<div class="inside2">
|
||||||
<div class="inwp cl">
|
<div class="inwp cl">
|
||||||
<h2>恭喜您安装成功</h2>
|
<h2>恭喜您安装成功</h2>
|
||||||
|
|
||||||
@ -8,8 +17,8 @@
|
|||||||
<a href="/" target="_blank">去前台首页</a>
|
<a href="/" target="_blank">去前台首页</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="inout2">
|
<div class="inout2">
|
||||||
<a href="/admin/login" target="_blank">去后台首页</a>
|
<a href="/admin" target="_blank">去后台首页</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/block}
|
{/block}
|
@ -1,4 +1,13 @@
|
|||||||
<?php
|
<?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);
|
declare (strict_types = 1);
|
||||||
|
|
||||||
namespace app\listener;
|
namespace app\listener;
|
||||||
@ -7,6 +16,7 @@ use think\facade\Db;
|
|||||||
use think\facade\Log;
|
use think\facade\Log;
|
||||||
use app\common\model\User;
|
use app\common\model\User;
|
||||||
use think\facade\Lang;
|
use think\facade\Lang;
|
||||||
|
use taoler\com\Api;
|
||||||
|
|
||||||
class UserLogin
|
class UserLogin
|
||||||
{
|
{
|
||||||
@ -25,21 +35,17 @@ class UserLogin
|
|||||||
if($type == 'log'){
|
if($type == 'log'){
|
||||||
//$name = $user->user['name'];
|
//$name = $user->user['name'];
|
||||||
$ip = request()->ip();
|
$ip = request()->ip();
|
||||||
|
$url = 'http://ip-api.com/json/' . $ip . '?lang=zh-CN&fields=57361';
|
||||||
/*
|
$ipJson = Api::urlGet($url);
|
||||||
$url = 'http://ip-api.com/json/'.$ip.'?lang=zh-CN';
|
if($ipJson->status == 'success'){
|
||||||
//$url = 'http://ip-api.com/json/?lang=zh-CN';
|
$city = $ipJson->city;
|
||||||
$add = Api::urlGet($url);
|
|
||||||
if($add->status == 'success'){
|
|
||||||
$city = $add->city;
|
|
||||||
} else {
|
} else {
|
||||||
$city ='未知';
|
$city ='未知';
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
$u->allowField(['last_login_ip','last_login_time','login_error_num'])->save(
|
$u->allowField(['city','last_login_ip','last_login_time','login_error_num'])->save(
|
||||||
[
|
[
|
||||||
//'city' => $city,
|
'city' => $city,
|
||||||
'last_login_ip' => $ip,
|
'last_login_ip' => $ip,
|
||||||
'last_login_time' => time(),
|
'last_login_time' => time(),
|
||||||
'login_error_num' => 0
|
'login_error_num' => 0
|
||||||
|
@ -11,6 +11,7 @@ class CheckRegister
|
|||||||
//排除禁止注册用户名的字段
|
//排除禁止注册用户名的字段
|
||||||
if($request->action(true)=='reg'){
|
if($request->action(true)=='reg'){
|
||||||
$name = $request->param('name');
|
$name = $request->param('name');
|
||||||
|
if(!is_null($name)) {
|
||||||
$disname = Db::name('system')->where('id',1)->value('blackname');
|
$disname = Db::name('system')->where('id',1)->value('blackname');
|
||||||
$data = explode("|",$disname);
|
$data = explode("|",$disname);
|
||||||
foreach($data as $v){
|
foreach($data as $v){
|
||||||
@ -19,6 +20,7 @@ class CheckRegister
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return $next($request);
|
return $next($request);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,13 @@
|
|||||||
"taoser/think-addons": "^1.0",
|
"taoser/think-addons": "^1.0",
|
||||||
"liliuwei/thinkphp-social": "^1.3",
|
"liliuwei/thinkphp-social": "^1.3",
|
||||||
"taoser/think-setarr": "^0.0.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": {
|
"require-dev": {
|
||||||
"symfony/var-dumper": "^4.2",
|
"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>
|
* @Author: TaoLer <alipey_tao@qq.com>
|
||||||
* @Date: 2021-12-06 16:04:50
|
* @Date: 2021-12-06 16:04:50
|
||||||
* @LastEditTime: 2022-04-21 20:56:48
|
* @LastEditTime: 2022-07-03 04:21:02
|
||||||
* @LastEditors: TaoLer
|
* @LastEditors: TaoLer
|
||||||
* @Description: 搜索引擎SEO优化设置
|
* @Description: 搜索引擎SEO优化设置
|
||||||
* @FilePath: \TaoLer\config\app.php
|
* @FilePath: \TaoLer\config\app.php
|
||||||
@ -28,15 +28,17 @@ return [
|
|||||||
|
|
||||||
// 应用映射(自动多应用模式有效)
|
// 应用映射(自动多应用模式有效)
|
||||||
'app_map' => [
|
'app_map' => [
|
||||||
|
//'bbs' => 'index'
|
||||||
],
|
],
|
||||||
// 域名绑定(自动多应用模式有效)
|
// 域名绑定(自动多应用模式有效)
|
||||||
'domain_bind' => [
|
'domain_bind' => [
|
||||||
|
//'www' => 'index',
|
||||||
|
//'adm' => 'admin'
|
||||||
],
|
],
|
||||||
// 禁止URL访问的应用列表(自动多应用模式有效)
|
// 禁止URL访问的应用列表(自动多应用模式有效)
|
||||||
|
|
||||||
// 异常页面的模板文件
|
// 异常页面的模板文件
|
||||||
'exception_tmpl' => app()->getThinkPath() . 'tpl/think_exception.tpl',
|
'exception_tmpl' => app()->getThinkPath() . 'tpl/think_exception.tpl',
|
||||||
//'exception_tmpl' => app()->getAppPath() . '404.html',
|
|
||||||
|
|
||||||
// 错误显示信息,非调试模式有效
|
// 错误显示信息,非调试模式有效
|
||||||
'error_message' => '页面错误!请稍后再试~',
|
'error_message' => '页面错误!请稍后再试~',
|
||||||
|
@ -1,4 +1,13 @@
|
|||||||
<?php
|
<?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 [
|
return [
|
||||||
// 默认磁盘
|
// 默认磁盘
|
||||||
@ -19,6 +28,11 @@ return [
|
|||||||
// 可见性
|
// 可见性
|
||||||
'visibility' => 'public',
|
'visibility' => 'public',
|
||||||
],
|
],
|
||||||
|
'sys' => [
|
||||||
|
'type' => 'local',
|
||||||
|
'root' => app()->getRootPath() . 'public/sys',
|
||||||
|
'url' => '/sys',
|
||||||
|
],
|
||||||
// 更多的磁盘配置信息
|
// 更多的磁盘配置信息
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
return [
|
return [
|
||||||
|
'一个' => 'http://www.bi.com',
|
||||||
|
'描述' => 'http://ww.com',
|
||||||
];
|
];
|
@ -1,12 +1,12 @@
|
|||||||
<?php
|
<?php
|
||||||
/*
|
/*
|
||||||
* @Author: TaoLer <alipey_tao@qq.com>
|
* @Author: TaoLer <alipay_tao@qq.com>
|
||||||
* @Date: 2021-12-06 16:04:50
|
* @Date: 2021-12-06 16:04:50
|
||||||
* @LastEditTime: 2022-04-22 06:57:15
|
* @LastEditTime: 2022-06-27 13:14:46
|
||||||
* @LastEditors: TaoLer
|
* @LastEditors: TaoLer
|
||||||
* @Description: 网站公共配置
|
* @Description: 网站公共配置
|
||||||
* @FilePath: \TaoLer\config\taoler.php
|
* @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',
|
'appname' => 'TaoLer',
|
||||||
// 版本配置
|
// 版本配置
|
||||||
'version' => '1.9.3',
|
'version' => '1.9.20',
|
||||||
// 加盐
|
// 加盐
|
||||||
'salt' => 'taoler',
|
'salt' => 'taoler',
|
||||||
// 数据库备份目录
|
// 数据库备份目录
|
||||||
@ -24,23 +24,43 @@ return [
|
|||||||
|
|
||||||
// 配置
|
// 配置
|
||||||
'config' =>[
|
'config' =>[
|
||||||
'email_notice' => 0,
|
// 注册开关
|
||||||
'cate_show' => 1,
|
'is_regist' => 1,
|
||||||
'area_show' => 1,
|
// 登录开关
|
||||||
|
'is_login' => 1,
|
||||||
|
// 发帖开关
|
||||||
|
'is_post' => 1,
|
||||||
|
// 评论开关
|
||||||
|
'is_reply' => 1,
|
||||||
|
// 注册审核
|
||||||
'regist_check' => 0,
|
'regist_check' => 0,
|
||||||
|
// 发帖审核
|
||||||
'posts_check' => 0,
|
'posts_check' => 0,
|
||||||
|
// 评论审核
|
||||||
'commnets_check' => 0,
|
'commnets_check' => 0,
|
||||||
|
// 注册验证类型 1验证码2邮箱3手机短信
|
||||||
|
'regist_type' => 1,
|
||||||
|
// 登录验证码
|
||||||
'login_captcha' => 0,
|
'login_captcha' => 0,
|
||||||
|
// 发帖验证码
|
||||||
'post_captcha' => 0,
|
'post_captcha' => 0,
|
||||||
|
// 显示分类
|
||||||
|
'cate_show' => 0,
|
||||||
|
// 显示用户归属地简称
|
||||||
|
'area_show' => 0,
|
||||||
|
// 邮件通知
|
||||||
|
'email_notice' => 0,
|
||||||
|
// 百度词条开关
|
||||||
|
'baidu_title_switch' => 0,
|
||||||
],
|
],
|
||||||
|
|
||||||
// 百度标签分词
|
// 百度标签分词
|
||||||
'baidu' => [
|
'baidu' => [
|
||||||
'grant_type' => '',
|
'grant_type' => 'client_credentials',
|
||||||
'client_id' => '',
|
'client_id' => '',
|
||||||
'client_secret' => '',
|
'client_secret' => '',
|
||||||
'access_token' => '',
|
'access_token' => '',
|
||||||
'push_api' => 'http://',
|
'push_api' => '',
|
||||||
],
|
],
|
||||||
|
|
||||||
// sitemap
|
// sitemap
|
||||||
@ -50,14 +70,14 @@ return [
|
|||||||
'map_time' => 'daily',
|
'map_time' => 'daily',
|
||||||
'map_level' => '0.5',
|
'map_level' => '0.5',
|
||||||
// 已生成id位标记
|
// 已生成id位标记
|
||||||
'write_id' => 12,
|
'write_id' => 21,
|
||||||
|
|
||||||
],
|
],
|
||||||
|
|
||||||
// URL美化
|
// URL美化
|
||||||
'url_rewrite' => [
|
'url_rewrite' => [
|
||||||
// 详情url
|
// 详情url
|
||||||
'article_as' => 'article/',
|
'article_as' => '<ename>/',
|
||||||
// 分类url
|
// 分类url
|
||||||
'cate_as' => 'column/',
|
'cate_as' => 'column/',
|
||||||
],
|
],
|
||||||
|
@ -1,10 +1,23 @@
|
|||||||
<?php
|
<?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设置 开启调试模式后有效
|
// | Trace设置 开启调试模式后有效
|
||||||
// +----------------------------------------------------------------------
|
// +----------------------------------------------------------------------
|
||||||
return [
|
return [
|
||||||
// 内置Html和Console两种方式 支持扩展
|
'type' => 'console',
|
||||||
'type' => 'Html',
|
'tabs' => [
|
||||||
// 读取的日志通道名
|
'base' => '基本',
|
||||||
'channel' => '',
|
'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 [
|
return [
|
||||||
// 模板引擎类型使用Think
|
// 模板引擎类型使用Think
|
||||||
'type' => 'Think',
|
'type' => 'Think',
|
||||||
// 默认模板渲染规则 1 解析为小写+下划线 2 全部转换小写 3 保持操作方法
|
// 默认模板渲染规则 1 解析为小写+下划线 2 全部转换小写 3 保持操作方法
|
||||||
'auto_rule' => 1,
|
'auto_rule' => 1,
|
||||||
// 模板目录名
|
|
||||||
'view_dir_name' => 'view/'.$template,
|
|
||||||
// 模板后缀
|
// 模板后缀
|
||||||
'view_suffix' => 'html',
|
'view_suffix' => 'html',
|
||||||
// 模板文件名分隔符
|
// 模板文件名分隔符
|
||||||
@ -31,6 +22,8 @@ return [
|
|||||||
'taglib_end' => '}',
|
'taglib_end' => '}',
|
||||||
|
|
||||||
'default_filter' => 'htmlspecialchars',
|
'default_filter' => 'htmlspecialchars',
|
||||||
|
|
||||||
|
|
||||||
//模板输出替换
|
//模板输出替换
|
||||||
'tpl_replace_string' => [
|
'tpl_replace_string' => [
|
||||||
'__STATIC__'=>'/static/layui',
|
'__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: [[
|
,cols: [[
|
||||||
{type: 'checkbox'}
|
{type: 'checkbox'}
|
||||||
,{field: 'id', width: 80, title: 'ID', sort: true}
|
,{field: 'id', width: 80, title: 'ID', sort: true}
|
||||||
,{field: 'replyer', title: '回帖人', width: 80}
|
,{field: 'title', title: '标题',minWidth: 150, templet: '<div><a href="{{d.url}}" target="_blank">{{d.title}}</a></div>'}
|
||||||
,{field: 'title', title: '帖ID',templet: '#title'}
|
,{field: 'replyer', title: '账号', width: 80}
|
||||||
,{field: 'avatar', title: '头像', width: 80, templet: '#imgTpl'}
|
,{field: 'avatar', title: '头像', width: 60, templet: '#imgTpl'}
|
||||||
,{field: 'content', title: '评论', minWidth: 200}
|
,{field: 'content', title: '评论', minWidth: 200}
|
||||||
,{field: 'replytime', title: '回复时间', width: 120, sort: true}
|
,{field: 'replytime', title: '回复时间', width: 120, sort: true}
|
||||||
,{field: 'check', title: '审核', templet: '#buttonCheck', width: 100}
|
,{field: 'check', title: '审核', templet: '#buttonCheck', width: 100}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/**
|
/**
|
||||||
images压缩扩展模块
|
images压缩扩展模块
|
||||||
changlin_zhao@qq.com
|
changlin_zhao@qq.com
|
||||||
2021.5.25
|
2021.5.25
|
||||||
@ -12,7 +12,6 @@ var compressImage = {
|
|||||||
//obj.preview(function(index, file, result){
|
//obj.preview(function(index, file, result){
|
||||||
|
|
||||||
//执行实例
|
//执行实例
|
||||||
|
|
||||||
var files = obj.pushFile();
|
var files = obj.pushFile();
|
||||||
var filesArry = [];
|
var filesArry = [];
|
||||||
for (var key in files) { //将上传的文件转为数组形式
|
for (var key in files) { //将上传的文件转为数组形式
|
||||||
@ -54,7 +53,7 @@ var compressImage = {
|
|||||||
reader.readAsDataURL(file)
|
reader.readAsDataURL(file)
|
||||||
reader.onload = function (e) {
|
reader.onload = function (e) {
|
||||||
const img = new Image()
|
const img = new Image()
|
||||||
const quality = 0.5 // 图像质量
|
const quality = 0.8 // 图像质量
|
||||||
const canvas = document.createElement('canvas')
|
const canvas = document.createElement('canvas')
|
||||||
const drawer = canvas.getContext('2d')
|
const drawer = canvas.getContext('2d')
|
||||||
img.src = this.result
|
img.src = this.result
|
||||||
@ -64,7 +63,7 @@ var compressImage = {
|
|||||||
originHeight = img.height; /* 图片的高度 */
|
originHeight = img.height; /* 图片的高度 */
|
||||||
|
|
||||||
// 设置最大尺寸限制,将所有图片都压缩到小于1m
|
// 设置最大尺寸限制,将所有图片都压缩到小于1m
|
||||||
const maxWidth = 1024, maxHeight = 1024;
|
const maxWidth = 2560, maxHeight = 1600;
|
||||||
// 需要压缩的目标尺寸
|
// 需要压缩的目标尺寸
|
||||||
let targetWidth = originWidth, targetHeight = originHeight;
|
let targetWidth = originWidth, targetHeight = originHeight;
|
||||||
// 等比例计算超过最大限制时缩放后的图片尺寸
|
// 等比例计算超过最大限制时缩放后的图片尺寸
|
||||||
|
@ -20,11 +20,11 @@ layui.define(['table', 'form'], function(exports){
|
|||||||
,cols: [[
|
,cols: [[
|
||||||
{type: 'checkbox'}
|
{type: 'checkbox'}
|
||||||
,{field: 'id', width: 60, title: 'ID', sort: true}
|
,{field: 'id', width: 60, title: 'ID', sort: true}
|
||||||
,{field: 'username', title: '用户名', minWidth: 100}
|
,{field: 'username', title: '用户名', minWidth: 80}
|
||||||
,{field: 'nick', title: '昵称',minWidth: 100}
|
,{field: 'nick', title: '昵称',Width: 80}
|
||||||
,{field: 'avatar', title: '头像', width: 80, templet: '#imgTpl'}
|
,{field: 'avatar', title: '头像', width: 60, templet: '#imgTpl'}
|
||||||
//,{field: 'phone', title: '手机',width: 80}
|
//,{field: 'phone', title: '手机',width: 80}
|
||||||
,{field: 'email', title: '邮箱', width: 120}
|
,{field: 'email', title: '邮箱', minWidth: 120}
|
||||||
,{field: 'sex', width: 60, title: '性别',templet: '#sex'}
|
,{field: 'sex', width: 60, title: '性别',templet: '#sex'}
|
||||||
,{field: 'ip', title: '登录IP', width: 100}
|
,{field: 'ip', title: '登录IP', width: 100}
|
||||||
,{field: 'city', title: '城市', width: 80}
|
,{field: 'city', title: '城市', width: 80}
|
||||||
@ -32,7 +32,7 @@ layui.define(['table', 'form'], function(exports){
|
|||||||
,{field: 'jointime', title: '注册时间',width: 110, sort: true}
|
,{field: 'jointime', title: '注册时间',width: 110, sort: true}
|
||||||
,{field: 'check', title: '状态', templet: '#buttonCheck', width: 95, align: 'center'}
|
,{field: 'check', title: '状态', templet: '#buttonCheck', width: 95, align: 'center'}
|
||||||
,{field: 'auth', title: '超级管理员', templet: '#buttonAuth', width: 80, align: 'center'}
|
,{field: 'auth', title: '超级管理员', templet: '#buttonAuth', width: 80, align: 'center'}
|
||||||
,{title: '操作', width: 150, align:'center', toolbar: '#table-useradmin-webuser'}
|
,{title: '操作', width: 100, align:'center', toolbar: '#table-useradmin-webuser'}
|
||||||
]]
|
]]
|
||||||
,page: true
|
,page: true
|
||||||
,limit: 30
|
,limit: 30
|
||||||
@ -59,23 +59,14 @@ layui.define(['table', 'form'], function(exports){
|
|||||||
dataType:'json',
|
dataType:'json',
|
||||||
success:function(data){
|
success:function(data){
|
||||||
if(data.code == 0){
|
if(data.code == 0){
|
||||||
layer.msg(data.msg,{
|
layer.msg(data.msg,{icon:6,time:2000});
|
||||||
icon:6,
|
|
||||||
time:2000
|
|
||||||
},function(){
|
|
||||||
location.reload();
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
layer.open({
|
layer.open({title:'删除失败',content:data.msg,icon:5,adim:6})
|
||||||
title:'删除失败',
|
|
||||||
content:data.msg,
|
|
||||||
icon:5,
|
|
||||||
adim:6
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
table.reload('LAY-user-manage');
|
||||||
layer.close(index);
|
layer.close(index);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -106,25 +97,14 @@ layui.define(['table', 'form'], function(exports){
|
|||||||
data:{"id":field.id,"name":field.username,"phone":field.phone,"email":field.email,"user_img":field.avatar,"sex":field.sex},
|
data:{"id":field.id,"name":field.username,"phone":field.phone,"email":field.email,"user_img":field.avatar,"sex":field.sex},
|
||||||
daType:"json",
|
daType:"json",
|
||||||
success:function (res){
|
success:function (res){
|
||||||
if (res.code == 0) {
|
if(data.code == 0){
|
||||||
layer.msg(res.msg,{
|
layer.msg(data.msg,{icon:6,time:2000});
|
||||||
icon:6,
|
|
||||||
time:2000
|
|
||||||
}, function(){
|
|
||||||
location.reload();
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
layer.open({
|
layer.open({title:'修改失败',content:data.msg,icon:5,adim:6})
|
||||||
tiele:'修改失败',
|
|
||||||
content:res.msg,
|
|
||||||
icon:5,
|
|
||||||
anim:6
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
table.reload('LAY-user-manage'); //数据刷新
|
||||||
table.reload('LAY-user-front-submit'); //数据刷新
|
|
||||||
layer.close(index); //关闭弹层
|
layer.close(index); //关闭弹层
|
||||||
});
|
});
|
||||||
|
|
||||||
|
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社区
|
@Name: Fly社区
|
||||||
@Author: 贤心
|
@Author: 贤心
|
||||||
@Site: fly.layui.com
|
@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 {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{padding:0 6px; font-weight: 300;color: rgb(230, 227, 227);}
|
||||||
.fly-footer a:hover{color: #777;}
|
.fly-footer a:hover{color: #fff;}
|
||||||
.fly-union{margin-top: 10px; color: #999;}
|
.fly-union{margin-top: 10px; color: #999;}
|
||||||
.fly-union>*{display: inline-block; vertical-align: middle;}
|
.fly-union>*{display: inline-block; vertical-align: middle;}
|
||||||
.fly-union a[upyun] img{width: 80px;}
|
.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-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:last-child{border-bottom: none;}
|
||||||
.fly-list li h2,
|
.fly-list li h2,
|
||||||
.fly-list li h2 a,
|
.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 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{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]{color: #999;}
|
||||||
.fly-list-info a[link]:hover{color: #5FB878;}
|
.fly-list-info a[link]:hover{color: #5FB878;}
|
||||||
.fly-list-info .icon-renzheng{position: relative; top: 1px; margin-right: 3px;}
|
.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 .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-kiss{color: #FF5722;}
|
||||||
.fly-list-nums{position: absolute; right: 0; top: 0; padding-right: 0!important;}
|
.fly-list-nums{position: absolute; right: 0; top: 0; padding-right: 0!important;}
|
||||||
.fly-list-nums i{position: relative; padding: 0 3px 0 15px;}
|
.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 .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 a,
|
||||||
.fly-list-one dd span{display: inline-block; *display: inline; *zoom: 1; vertical-align: top; font-style: normal}
|
.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 span{font-size: 12px; color: #ccc;}
|
||||||
.fly-list-one dd:last-child{padding-bottom: 5px;}
|
.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{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-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-ask,
|
||||||
.que-sta-jie{background: #5FB878;}
|
.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-ask{background: #FF5722;}
|
.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{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{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 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{display: block; text-overflow: ellipsis;}
|
||||||
.que-body .que-user-info a{margin-right: 10px;}
|
.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{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 .que-avatar i{position: absolute; left: 35px; top: 15px; }
|
||||||
.que-body .que-user-info span{display: inline-block; font-size: 12px; padding-left: 5px;}
|
.que-body .que-user-info span{display: inline-block; font-size: 12px; padding-left: 5px;}
|
||||||
.que-content{font-size: 14px; color:#999;}
|
|
||||||
|
|
||||||
|
|
||||||
/* 签到 */
|
/* 签到 */
|
||||||
.fly-signin cite{padding: 0 5px; color: #FF5722; font-style: normal;}
|
.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 a{padding-right: 10px; font-size: 14px;}
|
||||||
.fly-detail-user .guanzhu{position: absolute; right:10px; }
|
.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{
|
||||||
.detail-assist span{height: 20px; line-height: 20px;}
|
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{border-radius: 0;}
|
||||||
.detail-assist .layui-btn+.layui-btn{margin-left: 1px;}
|
.detail-assist .layui-btn+.layui-btn{margin-left: 1px;}
|
||||||
.detail-assist .jie-admin{margin-right: 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 .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;}
|
.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;}
|
.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;}
|
.jie-admin{cursor: pointer;}
|
||||||
.detail-hits .jie-admin{color: #fff; padding: 0 10px; }
|
.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;}
|
.laypage-main .laypage-next{display: inline-block;}
|
||||||
|
|
||||||
/* 列表 */
|
/* 列表 */
|
||||||
.fly-list li h2 a{max-width: 72%;}
|
.fly-list li h2 a{max-width: 90%;}
|
||||||
|
|
||||||
/* Detail 页
|
/* Detail 页
|
||||||
.fly-admin-box{display: block; margin: 0; margin-top: 10px;}
|
.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()
|
,device = layui.device()
|
||||||
,DISABLED = 'layui-btn-disabled';
|
,DISABLED = 'layui-btn-disabled';
|
||||||
var uid = layui.cache.user.uid;
|
var uid = layui.cache.user.uid;
|
||||||
|
var login = $('.fly-nav-user').attr('userlogin');
|
||||||
|
|
||||||
//阻止IE7以下访问
|
//阻止IE7以下访问
|
||||||
if(device.ie && device.ie < 8){
|
if(device.ie && device.ie < 8){
|
||||||
layer.alert('如果您非得使用 IE 浏览器访问Fly社区,那么请使用 IE8+');
|
layer.alert('如果您非得使用 IE 浏览器访问Fly社区,那么请使用 IE8+');
|
||||||
@ -442,9 +444,7 @@ layui.define(['layer', 'laytpl', 'form', 'element', 'upload', 'util', 'imgcom'],
|
|||||||
,preview: function(editor, span){ //预览
|
,preview: function(editor, span){ //预览
|
||||||
var othis = $(span), getContent = function(){
|
var othis = $(span), getContent = function(){
|
||||||
var content = editor.val();
|
var content = editor.val();
|
||||||
return /^\{html\}/.test(content)
|
return /^\{html\}/.test(content) ? content.replace(/^\{html\}/, '') : fly.content(content)
|
||||||
? content.replace(/^\{html\}/, '')
|
|
||||||
: fly.content(content)
|
|
||||||
}, isMobile = device.ios || device.android;
|
}, isMobile = device.ios || device.android;
|
||||||
|
|
||||||
if(mod.preview.isOpen) return layer.close(mod.preview.index);
|
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){
|
.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(){
|
,newmsg: function(){
|
||||||
var elemUser = $('.fly-nav-user');
|
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, {
|
fly.json(messageNums, {
|
||||||
_: new Date().getTime()
|
_: new Date().getTime()
|
||||||
}, function(res){
|
}, function(res){
|
||||||
@ -617,7 +619,7 @@ layui.define(['layer', 'laytpl', 'form', 'element', 'upload', 'util', 'imgcom'],
|
|||||||
msg.on('click', function(){
|
msg.on('click', function(){
|
||||||
fly.json(messageRead, {}, function(res){
|
fly.json(messageRead, {}, function(res){
|
||||||
if(res.status === 0){
|
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){ }}'
|
var tplReply = ['{{# layui.each(d.data, function(index, item){ }}'
|
||||||
,'<dd>'
|
,'<dd>'
|
||||||
,'<a href="{{item.uid}}">'
|
,'<a href="{{item.uid}}">'
|
||||||
,'<img src="{{item.user.avatar}}">'
|
,'<img src="{{item.user.avatar}}">'
|
||||||
,'<cite>{{item.user.username}}</cite>'
|
,'<cite>{{item.user.username}}</cite>'
|
||||||
,'<i>{{item["count(*)"]}}' +replyNum+'</i>'
|
,'<i>{{item["count"]}}' + replyNum + '</i>'
|
||||||
,'</a>'
|
,'</a>'
|
||||||
,'</dd>'
|
,'</dd>'
|
||||||
,'{{# }); }}'].join('')
|
,'{{# }); }}'].join('')
|
||||||
,elemReply = $('#LAY_replyRank');
|
,elemReply = $('#LAY_replyRank');
|
||||||
|
|
||||||
|
var replyUrl = elemReply.attr('data-url');
|
||||||
if(elemReply[0]){
|
if(elemReply[0]){
|
||||||
|
|
||||||
fly.json(replyUrl, {
|
fly.json(replyUrl, {
|
||||||
limit: 20
|
limit: 20
|
||||||
}, function(res){
|
}, function(res){
|
||||||
var html = laytpl(tplReply).render(res);
|
var html = laytpl(tplReply).render(res);
|
||||||
elemReply.find('dl').html(html);
|
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({
|
layer.open({
|
||||||
type: 1
|
type: 1
|
||||||
,title: false
|
,title: false
|
||||||
,closeBtn: false
|
,closeBtn: false
|
||||||
//,shade: [0.1, '#fff']
|
,shade: [0.1, '#fff']
|
||||||
,shadeClose: true
|
,shadeClose: true
|
||||||
,maxWidth: 10000
|
,maxWidth: 10000
|
||||||
,skin: 'fly-layer-search'
|
,skin: 'fly-layer-search'
|
||||||
,content: ['<form action='+searchUrl+'>'
|
,content: [forms
|
||||||
,'<input autocomplete="off" placeholder="搜索内容,回车跳转" type="text" name="keywords">'
|
,'<input autocomplete="off" placeholder="搜索内容,回车跳转" type="text" name="keywords">'
|
||||||
,'</form>'].join('')
|
,'</form>'].join('')
|
||||||
,success: function(layero){
|
,success: function(layero){
|
||||||
@ -1030,7 +873,7 @@ layui.define(['layer', 'laytpl', 'form', 'element', 'upload', 'util', 'imgcom'],
|
|||||||
elem: '.fly-editor'
|
elem: '.fly-editor'
|
||||||
});
|
});
|
||||||
|
|
||||||
//手机设备的简单适配 底部左侧栏导航
|
//手机设备的简单适配 用户中心底部左侧栏导航
|
||||||
var treeMobile = $('.site-tree-mobile')
|
var treeMobile = $('.site-tree-mobile')
|
||||||
,shadeMobile = $('.site-mobile-shade')
|
,shadeMobile = $('.site-mobile-shade')
|
||||||
|
|
||||||
@ -1136,6 +979,7 @@ layui.define(['layer', 'laytpl', 'form', 'element', 'upload', 'util', 'imgcom'],
|
|||||||
});
|
});
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
//移动端左侧栏监听多语言切换
|
//移动端左侧栏监听多语言切换
|
||||||
$('#language1').on('change',function(){
|
$('#language1').on('change',function(){
|
||||||
var data = $(this).val();
|
var data = $(this).val();
|
||||||
|
@ -102,7 +102,7 @@ layui.define('fly', function(exports){
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
//设置置顶、加精、禁评、状态
|
// 设置置顶、加精、禁评、状态
|
||||||
,set: function(div){
|
,set: function(div){
|
||||||
var othis = $(this);
|
var othis = $(this);
|
||||||
fly.json(articleJieset, {
|
fly.json(articleJieset, {
|
||||||
@ -117,7 +117,7 @@ layui.define('fly', function(exports){
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
//收藏
|
// 收藏
|
||||||
,collect: function(div){
|
,collect: function(div){
|
||||||
var othis = $(this), type = othis.data('type');
|
var othis = $(this), type = othis.data('type');
|
||||||
fly.json(collection+ type +'/', {
|
fly.json(collection+ type +'/', {
|
||||||
|
@ -36,7 +36,7 @@ layui.define(['laypage', 'fly', 'element', 'flow', 'imgcom'], function(exports){
|
|||||||
,title: ''
|
,title: ''
|
||||||
,cols: [[
|
,cols: [[
|
||||||
{type: 'numbers', fixed: 'left'}
|
{type: 'numbers', fixed: 'left'}
|
||||||
,{field: 'title', title: '标题',minWidth: 250 ,templet: '<div><a href="{{d.url}}" target="_blank">{{d.title}}</a></div>'}
|
,{field: 'title', title: '标题',minWidth: 250 ,templet: '<div><a href="{{d.url}}" target="_blank">{{-d.title}}</a></div>'}
|
||||||
,{field: 'status', title: '状态', width: 80}
|
,{field: 'status', title: '状态', width: 80}
|
||||||
,{field: 'ctime', title: '时间', width: 120}
|
,{field: 'ctime', title: '时间', width: 120}
|
||||||
,{field: 'datas', title: '数据', width: 120}
|
,{field: 'datas', title: '数据', width: 120}
|
||||||
@ -75,23 +75,14 @@ layui.define(['laypage', 'fly', 'element', 'flow', 'imgcom'], function(exports){
|
|||||||
layer.close(index);
|
layer.close(index);
|
||||||
$.post(atrDelUrl,{"id":id},function(data){
|
$.post(atrDelUrl,{"id":id},function(data){
|
||||||
if(data.code == 0){
|
if(data.code == 0){
|
||||||
layer.msg(data.msg,{
|
layer.msg(data.msg,{icon:6,time:2000});
|
||||||
icon:6,
|
|
||||||
time:2000
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
layer.open({
|
layer.open({title:'删除失败',content:data.msg,icon:5,adim:6})
|
||||||
title:'删除失败',
|
|
||||||
content:data.msg,
|
|
||||||
icon:5,
|
|
||||||
adim:6
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
table.reload('art-post');
|
table.reload('art-post');
|
||||||
});
|
});
|
||||||
|
|
||||||
} else if(obj.event === 'edit'){//编辑
|
} else if(obj.event === 'edit'){//编辑
|
||||||
$.post(artEditUrl,{"id":id},function(){
|
$.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;
|
location.hash = layid;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
/*
|
||||||
//根据ip获取城市
|
//根据ip获取城市
|
||||||
if($('#L_city').val() === ''){
|
if($('#L_city').val() === ''){
|
||||||
$.getScript('http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=js', function(){
|
$.getScript('http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=js', function(){
|
||||||
$('#L_city').val(remote_ip_info.city||'');
|
$('#L_city').val(remote_ip_info.city||'');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
//上传图片
|
//上传图片
|
||||||
if($('.upload-img')[0]){
|
if($('.upload-img')[0]){
|
||||||
layui.use('upload', function(upload){
|
layui.use('upload', function(upload){
|
||||||
@ -169,14 +160,12 @@ layui.define(['laypage', 'fly', 'element', 'flow', 'imgcom'], function(exports){
|
|||||||
avatarAdd.find('.loading').show();
|
avatarAdd.find('.loading').show();
|
||||||
}
|
}
|
||||||
,done: function(res){
|
,done: function(res){
|
||||||
if(res.status == 0){
|
if(res.code == 0){
|
||||||
$.post(userSet, {
|
layer.msg(res.msg, { icon: 6, time: 2000 },function(){
|
||||||
avatar: res.url
|
|
||||||
}, function(res){
|
|
||||||
location.reload();
|
location.reload();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
layer.msg(res.msg, {icon: 5});
|
layer.open({ content: data.msg, icon: 5, adim: 6 });
|
||||||
}
|
}
|
||||||
avatarAdd.find('.loading').hide();
|
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
|
// 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';
|
require_once __DIR__ . '/composer/autoload_real.php';
|
||||||
|
|
||||||
return ComposerAutoloaderInit1b32198725235c8d6500c87262ef30c2::getLoader();
|
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
|
||||||
|
|
||||||
|
[](https://github.com/Bacon/BaconQrCode/actions/workflows/ci.yml)
|
||||||
|
[](https://codecov.io/gh/Bacon/BaconQrCode)
|
||||||
|
[](https://packagist.org/packages/bacon/bacon-qr-code)
|
||||||
|
[](https://packagist.org/packages/bacon/bacon-qr-code)
|
||||||
|
[](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…
x
Reference in New Issue
Block a user