1.9.23
This commit is contained in:
parent
ad7510a7bb
commit
43013c2e39
@ -12,7 +12,6 @@ use think\facade\Db;
|
||||
use think\facade\Request;
|
||||
use think\facade\Lang;
|
||||
use think\facade\View;
|
||||
use think\facade\Route;
|
||||
use taoser\SetArr;
|
||||
use app\common\lib\Uploads;
|
||||
|
||||
@ -296,9 +295,9 @@ abstract class BaseController
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setTags($data)
|
||||
public function setKeywords($data)
|
||||
{
|
||||
$tags = [];
|
||||
$keywords = [];
|
||||
|
||||
if($data['flag'] == 'on') {
|
||||
// 百度分词自动生成关键词
|
||||
@ -309,7 +308,7 @@ abstract class BaseController
|
||||
$headers = array();
|
||||
$headers[] = "Content-Type:application/json";
|
||||
$body = array(
|
||||
"text" => $data['tags']
|
||||
"text" => $data['$keywords']
|
||||
);
|
||||
$postBody = json_encode($body);
|
||||
$curl = curl_init();
|
||||
@ -330,8 +329,8 @@ abstract class BaseController
|
||||
// 数据正常
|
||||
$items = $dataItem->items;
|
||||
foreach($items as $item) {
|
||||
if($item->pos == 'n' && !in_array($item->item,$tags)){
|
||||
$tags[] = $item->item;
|
||||
if($item->pos == 'n' && !in_array($item->item,$keywords)){
|
||||
$keywords[] = $item->item;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -362,16 +361,16 @@ abstract class BaseController
|
||||
} else {
|
||||
// 手动添加关键词
|
||||
// 中文一个或者多个空格转换为英文空格
|
||||
$str = preg_replace('/\s+/',' ',$data['tags']);
|
||||
$str = preg_replace('/\s+/',' ',$data['keywords']);
|
||||
$att = explode(' ', $str);
|
||||
foreach($att as $v){
|
||||
if ($v !='') {
|
||||
$tags[] = $v;
|
||||
$keywords[] = $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return json(['code'=>0,'data'=>$tags]);
|
||||
return json(['code'=>0,'data'=>$keywords]);
|
||||
}
|
||||
|
||||
// api_post接口
|
||||
@ -475,6 +474,95 @@ abstract class BaseController
|
||||
return $upRes;
|
||||
}
|
||||
|
||||
//获取artcile所有图片
|
||||
protected function getArticleAllpic($str)
|
||||
{
|
||||
// <img src="http://img.com" />
|
||||
$pattern = "/<[img|IMG].*?src=[\'|\"](.*?(?:[\.gif|\.jpg|\.png]))[\'|\"].*?[\/]?>/";
|
||||
preg_match_all($pattern,$str,$matchContent);
|
||||
if(isset($matchContent[1])){
|
||||
$img = $matchContent[1];
|
||||
}else{
|
||||
$temp = "./images/no-image.jpg";//在相应位置放置一张命名为no-image的jpg图片
|
||||
}
|
||||
|
||||
return $img;
|
||||
|
||||
}
|
||||
|
||||
|
||||
//下载图片
|
||||
private function downloadImage($url)
|
||||
{
|
||||
$ch = curl_init();
|
||||
curl_setopt ($ch, CURLOPT_CUSTOMREQUEST, 'GET' );
|
||||
curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, false );
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
|
||||
$file = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
return $this->saveAsImage($url, $file);
|
||||
|
||||
}
|
||||
|
||||
//保存图片
|
||||
private function saveAsImage($url, $file)
|
||||
{
|
||||
$filename = pathinfo($url, PATHINFO_BASENAME);
|
||||
//$dirname = pathinfo(parse_url($url, PHP_URL_PATH), PATHINFO_DIRNAME);
|
||||
$dirname = date('Ymd',time());
|
||||
//路径
|
||||
$path = 'storage/' . $this->uid . '/article_pic/' . $dirname . '/';
|
||||
//绝对文件夹
|
||||
$fileDir = public_path() . $path;
|
||||
//文件绝对路径
|
||||
$filePath = $fileDir . $filename;
|
||||
//相对路径文件名
|
||||
$realFile = '/' . $path . $filename;
|
||||
// 如果目录不存在,则创建
|
||||
|
||||
if(!is_dir($fileDir)) {
|
||||
mkdir($fileDir, 0777, true);
|
||||
}
|
||||
|
||||
if(file_exists($filePath)) {
|
||||
//$this->output->writeln("【已存在】输出路径" . $fullpath);
|
||||
return $realFile;
|
||||
|
||||
} else {
|
||||
$resource = fopen($filePath, 'a');
|
||||
$res = fwrite($resource, $file);
|
||||
fclose($resource);
|
||||
if($res !== false) {
|
||||
return $realFile;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//下载网络图片到本地并替换
|
||||
public function downUrlPicsReaplace($content)
|
||||
{
|
||||
// 批量下载网络图片并替换
|
||||
$images = $this->getArticleAllpic($content);
|
||||
if(count($images)) {
|
||||
foreach($images as $image){
|
||||
//1.网络图片
|
||||
//halt((stripos($image, Request::domain()) === false));
|
||||
if((stripos($image,'http') !== false) && (stripos($image, Request::domain()) === false)) {
|
||||
|
||||
//2.下载远程图片
|
||||
$newImageUrl = $this->downloadImage($image);
|
||||
|
||||
$content = str_replace($image,Request::domain().$newImageUrl,$content);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -337,7 +337,8 @@ class Forum extends AdminController
|
||||
{
|
||||
if (Request::isAjax()) {
|
||||
|
||||
$data = Request::only(['cate_id', 'title', 'title_color', 'tiny_content', 'content', 'upzip', 'tags', 'description', 'captcha']);
|
||||
$data = Request::only(['cate_id', 'title', 'title_color', 'tiny_content', 'content', 'upzip', 'keywords', 'description', 'captcha']);
|
||||
$tagId = input('tagid');
|
||||
$data['user_id'] = 1; //管理员ID
|
||||
|
||||
// 调用验证器
|
||||
@ -350,6 +351,12 @@ class Forum extends AdminController
|
||||
// 获取内容图片音视频标识
|
||||
$iva= $this->hasIva($data['content']);
|
||||
$data = array_merge($data,$iva);
|
||||
|
||||
// 处理内容
|
||||
$data['content'] = $this->downUrlPicsReaplace($data['content']);
|
||||
// 把,转换为,并去空格->转为数组->去掉空数组->再转化为带,号的字符串
|
||||
$data['keywords'] = implode(',',array_filter(explode(',',trim(str_replace(',',',',$data['keywords'])))));
|
||||
|
||||
// 获取分类ename
|
||||
$cate_ename = Db::name('cate')->where('id',$data['cate_id'])->value('ename');
|
||||
|
||||
@ -357,7 +364,17 @@ class Forum extends AdminController
|
||||
$result = $article->add($data);
|
||||
if ($result['code'] == 1) {
|
||||
// 获取到的最新ID
|
||||
$aid = Db::name('article')->max('id');
|
||||
$aid = $result['data']['id'];
|
||||
//写入taglist表
|
||||
$tagArr = [];
|
||||
if(isset($tagId)) {
|
||||
$tagIdArr = explode(',',$tagId);
|
||||
foreach($tagIdArr as $tid) {
|
||||
$tagArr[] = ['article_id'=>$aid,'tag_id'=>$tid,'create_time'=>time()];
|
||||
}
|
||||
}
|
||||
Db::name('taglist')->insertAll($tagArr);
|
||||
|
||||
// 清除文章tag缓存
|
||||
Cache::tag('tagArtDetail')->clear();
|
||||
|
||||
@ -394,7 +411,8 @@ class Forum extends AdminController
|
||||
$article = Article::find($id);
|
||||
|
||||
if(Request::isAjax()){
|
||||
$data = Request::only(['id','cate_id','title','title_color','content','upzip','tags','description','captcha']);
|
||||
$data = Request::only(['id','cate_id','title','title_color','content','upzip','keywords','description','captcha']);
|
||||
$tagId = input('tagid');
|
||||
$data['user_id'] = 1;
|
||||
//调用验证器
|
||||
$validate = new \app\common\validate\Article();
|
||||
@ -406,9 +424,36 @@ class Forum extends AdminController
|
||||
//获取内容图片音视频标识
|
||||
$iva= $this->hasIva($data['content']);
|
||||
$data = array_merge($data,$iva);
|
||||
|
||||
// 处理内容
|
||||
$data['content'] = $this->downUrlPicsReaplace($data['content']);
|
||||
// 把,转换为,并去空格->转为数组->去掉空数组->再转化为带,号的字符串
|
||||
$data['keywords'] = implode(',',array_filter(explode(',',trim(str_replace(',',',',$data['keywords'])))));
|
||||
|
||||
$result = $article->edit($data);
|
||||
if($result == 1) {
|
||||
//处理标签
|
||||
$artTags = Db::name('taglist')->where('article_id',$id)->column('tag_id','id');
|
||||
if(isset($tagId)) {
|
||||
$tagIdArr = explode(',',$tagId);
|
||||
foreach($artTags as $aid => $tid) {
|
||||
if(!in_array($tid,$tagIdArr)){
|
||||
//删除被取消的tag
|
||||
Db::name('taglist')->delete($aid);
|
||||
}
|
||||
}
|
||||
//查询保留的标签
|
||||
$artTags = Db::name('taglist')->where('article_id',$id)->column('tag_id');
|
||||
$tagArr = [];
|
||||
foreach($tagIdArr as $tid) {
|
||||
if(!in_array($tid, $artTags)){
|
||||
//新标签
|
||||
$tagArr[] = ['article_id'=>$data['id'],'tag_id'=>$tid,'create_time'=>time()];
|
||||
}
|
||||
}
|
||||
//更新新标签
|
||||
Db::name('taglist')->insertAll($tagArr);
|
||||
}
|
||||
//删除原有缓存显示编辑后内容
|
||||
Cache::delete('article_'.$id);
|
||||
$link = $this->getRouteUrl((int) $id, $article->cate->ename);
|
||||
@ -449,10 +494,10 @@ class Forum extends AdminController
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function tagWord()
|
||||
public function getKeywords()
|
||||
{
|
||||
$data = Request::only(['tags','flag']);
|
||||
return $this->setTags($data);
|
||||
return $this->setKeywords($data);
|
||||
|
||||
}
|
||||
|
||||
|
@ -2,10 +2,10 @@
|
||||
/*
|
||||
* @Author: TaoLer <alipey_tao@qq.com>
|
||||
* @Date: 2022-04-13 09:54:31
|
||||
* @LastEditTime: 2022-07-15 18:28:57
|
||||
* @LastEditTime: 2022-08-14 09:23:13
|
||||
* @LastEditors: TaoLer
|
||||
* @Description: 搜索引擎SEO优化设置
|
||||
* @FilePath: \TaoLer\app\admin\controller\Seo.php
|
||||
* @FilePath: \github\TaoLer\app\admin\controller\Seo.php
|
||||
* Copyright (c) 2020~2022 https://www.aieok.com All rights reserved.
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
@ -16,7 +16,7 @@ use think\facade\View;
|
||||
use think\facade\Request;
|
||||
use think\facade\Db;
|
||||
use taoser\SetArr;
|
||||
use app\admin\model\PushJscode;
|
||||
use app\common\model\PushJscode;
|
||||
|
||||
class Seo extends AdminController
|
||||
{
|
||||
@ -40,7 +40,7 @@ class Seo extends AdminController
|
||||
}
|
||||
// push_js
|
||||
$pushjs = new PushJscode();
|
||||
$jscode = $pushjs->getAllCodes();
|
||||
$jscode = $pushjs->getAllCodes(1);
|
||||
View::assign(['xml'=>$xml,'jscode'=>$jscode,'robots'=>$robots]);
|
||||
return View::fetch();
|
||||
}
|
||||
@ -360,7 +360,7 @@ class Seo extends AdminController
|
||||
*/
|
||||
public function savePushJs()
|
||||
{
|
||||
$data = Request::only(['name','jscode']);
|
||||
$data = Request::only(['name','jscode','type']);
|
||||
if(empty($data['name'])) {
|
||||
return json(['code'=>-1,'msg'=>'请术输入名称']);
|
||||
}
|
||||
@ -486,4 +486,20 @@ class Seo extends AdminController
|
||||
|
||||
}
|
||||
|
||||
public function tagLinkList()
|
||||
{
|
||||
$arr = [];
|
||||
$pushjs = new PushJscode();
|
||||
$tags = $pushjs->getAllCodes(2);
|
||||
if(count($tags)) {
|
||||
$arr = ['code'=>0, 'msg'=>'', 'count' => count($tags)];
|
||||
foreach($tags as $k=>$v) {
|
||||
$arr['data'][] = ['id'=>$v['id'],'tag'=>$v['name'], 'link'=>$v['jscode'],'time'=>$v['create_time']];
|
||||
}
|
||||
} else {
|
||||
$arr = ['code'=>-1, 'msg'=>'没有数据'];
|
||||
}
|
||||
return json($arr);
|
||||
}
|
||||
|
||||
}
|
122
app/admin/controller/Tag.php
Normal file
122
app/admin/controller/Tag.php
Normal file
@ -0,0 +1,122 @@
|
||||
<?php
|
||||
/*
|
||||
* @Author: TaoLer <317927823@qq.com>
|
||||
* @Date: 2022-08-14 09:39:01
|
||||
* @LastEditTime: 2022-08-15 16:12:13
|
||||
* @LastEditors: TaoLer
|
||||
* @Description: 优化版
|
||||
* @FilePath: \TaoLer\app\admin\controller\Tag.php
|
||||
* Copyright (c) 2020~2022 https://www.aieok.com All rights reserved.
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
namespace app\admin\controller;
|
||||
|
||||
use app\common\controller\AdminController;
|
||||
use think\facade\View;
|
||||
use think\facade\Request;
|
||||
use think\facade\Db;
|
||||
use app\common\model\Tag as TagModel;
|
||||
|
||||
class Tag extends AdminController
|
||||
{
|
||||
|
||||
|
||||
// public function __construct(TagModel $tagModel)
|
||||
// {
|
||||
|
||||
// $this->tagModel = new TagModel;
|
||||
// }
|
||||
|
||||
public function index()
|
||||
{
|
||||
return View::fetch('index');
|
||||
}
|
||||
|
||||
public function list()
|
||||
{
|
||||
$arr = [];
|
||||
$tag = new TagModel;
|
||||
$tags = $tag->getTagList();
|
||||
// dump($tags);
|
||||
if(count($tags)) {
|
||||
$arr = ['code'=>0, 'msg'=>'', 'count' => count($tags)];
|
||||
foreach($tags as $k=>$v) {
|
||||
$arr['data'][] = ['id'=>$v['id'],'name'=>$v['name'], 'ename'=>$v['ename'],'time'=>$v['create_time']];
|
||||
}
|
||||
} else {
|
||||
$arr = ['code'=>-1, 'msg'=>'没有数据'];
|
||||
}
|
||||
return json($arr);
|
||||
}
|
||||
|
||||
public function add()
|
||||
{
|
||||
if(Request::isAjax()) {
|
||||
$data = Request::only(['name','ename']);
|
||||
$tagModel = new TagModel;
|
||||
$res = $tagModel->saveTag($data);
|
||||
if($res == true){
|
||||
return json(['code'=>0,'msg'=>'设置成功']);
|
||||
}
|
||||
}
|
||||
return view();
|
||||
}
|
||||
|
||||
public function edit()
|
||||
{
|
||||
$tagModel = new TagModel;
|
||||
|
||||
if(Request::isAjax()) {
|
||||
$data = Request::only(['name','ename','id']);
|
||||
$res =$tagModel::update($data);
|
||||
if($res == true){
|
||||
return json(['code'=>0,'msg'=>'设置成功']);
|
||||
}
|
||||
}
|
||||
$tag = $tagModel->getTag(input('id'));
|
||||
View::assign('tag',$tag);
|
||||
return view();
|
||||
}
|
||||
|
||||
public function delete()
|
||||
{
|
||||
if(Request::isPost()) {
|
||||
$tagModel = new TagModel;
|
||||
$res = $tagModel->delTag(input('id'));
|
||||
if($res == true){
|
||||
return json(['code'=>0,'msg'=>'删除成功']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 所有tag标签
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function getAllTag()
|
||||
{
|
||||
$data = [];
|
||||
$tagModel = new TagModel;
|
||||
$tags = $tagModel->getTagList();
|
||||
foreach($tags as $tag) {
|
||||
$data[] = ['name'=> $tag['name'], 'value'=> $tag['id']];
|
||||
}
|
||||
return json(['code'=>0,'data'=>$data]);
|
||||
}
|
||||
|
||||
public function getArticleTag($id)
|
||||
{
|
||||
//
|
||||
$data = [];
|
||||
$artTags = Db::name('taglist')->where('article_id',$id)->select();
|
||||
// halt($artTags);
|
||||
foreach($artTags as $v) {
|
||||
$tag = Db::name('tag')->find($v['tag_id']);
|
||||
$data[] = ['name'=>$tag['name'],'value'=>$tag['id']];
|
||||
}
|
||||
// halt($data);
|
||||
return json(['code'=>0,'data'=>$data]);
|
||||
}
|
||||
|
||||
}
|
@ -12,13 +12,6 @@ use app\common\lib\Uploads;
|
||||
|
||||
class User extends AdminController
|
||||
{
|
||||
/**
|
||||
protected function initialize()
|
||||
{
|
||||
parent::initialize();
|
||||
|
||||
}
|
||||
*/
|
||||
//用户表
|
||||
public function list()
|
||||
{
|
||||
|
@ -2,10 +2,10 @@
|
||||
/*
|
||||
* @Author: TaoLer <alipay_tao@qq.com>
|
||||
* @Date: 2021-12-06 16:04:50
|
||||
* @LastEditTime: 2022-07-29 17:17:41
|
||||
* @LastEditTime: 2022-08-15 16:17:32
|
||||
* @LastEditors: TaoLer
|
||||
* @Description: admin路由配置
|
||||
* @FilePath: \github\TaoLer\app\admin\route\route.php
|
||||
* @FilePath: \TaoLer\app\admin\route\route.php
|
||||
* Copyright (c) 2020~2022 https://www.aieok.com All rights reserved.
|
||||
*/
|
||||
use think\facade\Route;
|
||||
@ -20,3 +20,7 @@ Route::get("$detail_as<id>$", '\app\index\controller\Article@detail')
|
||||
'id' => '\d+',
|
||||
])
|
||||
->name('article_detail');
|
||||
|
||||
//tag
|
||||
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
{extend name="public/base" /}
|
||||
|
||||
{block name="body"}
|
||||
|
||||
<div class="layui-form layui-form-pane" lay-filter="layuiadmin-form-addforum" id="layuiadmin-form-addforum">
|
||||
<div class="layui-tab layui-tab-brief" lay-filter="user">
|
||||
<div class="layui-tab-content" id="LAY_ucm" style="padding: 20px 0">
|
||||
@ -63,19 +62,21 @@
|
||||
<textarea name="description" class="layui-textarea" placeholder="SEO描述"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
{//关键词}
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-inline">
|
||||
<label class="layui-form-label">{:lang('add tags')}</label>
|
||||
<div class="layui-input-inline" style="width: 190px">
|
||||
<input type="text" class="layui-input" name="tags" value="" placeholder="多个用空格隔开" title="添加标签" />
|
||||
<label class="layui-form-label">{:lang('添加关键词')}</label>
|
||||
<div class="layui-input-block">
|
||||
<!-- <input type="text" class="layui-input" name="" id="inputTags" value="" placeholder="多个回车添加" title="添加关键词" /> -->
|
||||
<input type="text" class="layui-input" name="keywords" value="" placeholder="多个用逗号隔开" title="添加关键词" />
|
||||
</div>
|
||||
<button type="button" class="layui-btn" id="article-tags-button">{:lang('add')}</button>
|
||||
</div>
|
||||
</div>
|
||||
{//tag}
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-btn-container"></div>
|
||||
<label class="layui-form-label">{:lang('add tags')}</label>
|
||||
<div class="layui-input-block">
|
||||
<div id="tag"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-hide">
|
||||
<button type="submit" class="layui-btn" lay-filter="article-add" lay-submit id="article-add">{:lang('post now')}</button>
|
||||
</div>
|
||||
@ -102,13 +103,13 @@
|
||||
$(mytextareaid).removeClass();
|
||||
</script>
|
||||
<script src="/addons/taonyeditor/js/taonyeditor.js"></script>
|
||||
|
||||
<script src="/static/xm-select.js"></script>
|
||||
<script>
|
||||
layui.config({
|
||||
base: '/static/admin/' //静态资源所在路径
|
||||
}).extend({
|
||||
index: 'lib/index' //主入口模块
|
||||
}).use(["form", "colorpicker", "upload", 'editor'], function () {
|
||||
}).use(["form", "colorpicker", "upload", 'editor','inputTags'], function () {
|
||||
var $ = layui.jquery,
|
||||
form = layui.form,
|
||||
colorpicker = layui.colorpicker,
|
||||
@ -116,6 +117,18 @@ layui.config({
|
||||
|
||||
var editor = layui.editor;
|
||||
|
||||
|
||||
//如果你是采用模版自带的编辑器,你需要开启以下语句来解析。
|
||||
var taonystatus = "{:hook('taonystatus')}";
|
||||
// 编辑器插件启用状态
|
||||
var isShow = taonystatus ? false : true;
|
||||
if(isShow) {
|
||||
$('.layui-textarea').each(function(){
|
||||
var othis = $(this), html = othis.html();
|
||||
othis.attr(fly.content(html));
|
||||
})
|
||||
}
|
||||
|
||||
// 从详情页自动调用端口过滤,获取描述信息
|
||||
tinymce.get('L_content').on('mouseleave', function() {
|
||||
var content = tinymce.get('L_content').getContent({format: 'text'});
|
||||
@ -127,40 +140,37 @@ layui.config({
|
||||
$('[name="description"]').val(content);
|
||||
});
|
||||
|
||||
|
||||
// 改变标题颜色
|
||||
colorpicker.render({
|
||||
elem: "#color",
|
||||
color: "#393d49",
|
||||
predefine: true, // 开启预定义颜色
|
||||
done: function (color) {
|
||||
//譬如你可以在回调中把得到的 color 赋值给表单
|
||||
$("#L_title_color").val(color);
|
||||
$("#L_title").css("color", color);
|
||||
},
|
||||
});
|
||||
|
||||
//上传附件
|
||||
upload.render({
|
||||
elem: "#zip-button",
|
||||
url: "{:url('forum/uploads')}", //改成您自己的上传接口
|
||||
data: { type: "zip" },
|
||||
accept: "file", //普通文件
|
||||
done: function (res) {
|
||||
if (res.status == 0) {
|
||||
$('input[name="upzip"]').val(res.url);
|
||||
layer.msg("上传成功");
|
||||
} else {
|
||||
layer.msg(res.msg);
|
||||
var inputTags = layui.inputTags;
|
||||
//关键词
|
||||
inputTags.render({
|
||||
elem:'#inputTags',
|
||||
content: [],
|
||||
aldaBtn: false,
|
||||
done: function(value){
|
||||
//console.log(value)
|
||||
var keywords = this.content.join(',');
|
||||
$("input[name='keywords']").val(keywords);
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
//1.渲染标签
|
||||
var addTags = xmSelect.render({
|
||||
el: '#tag',
|
||||
name: 'tagid',
|
||||
layVerify: 'required',
|
||||
layVerType: 'msg',
|
||||
paging: true,
|
||||
pageSize: 5,
|
||||
data: []
|
||||
});
|
||||
|
||||
// 手动添加tags
|
||||
$("#article-tags-button").on("click", function () {
|
||||
var tags = $("input[name='tags']").val();
|
||||
var flag = "off";
|
||||
getTags(tags, flag);
|
||||
//2.动态标签赋值
|
||||
$.get("{:url('tag/getAllTag')}",function(res){
|
||||
if(res.code == 0){
|
||||
addTags.update({
|
||||
data: res.data,
|
||||
autoRow: true,
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
// 通过接口自动获取tag的内容
|
||||
@ -169,11 +179,17 @@ layui.config({
|
||||
$("#L_title").on("blur", function () {
|
||||
var title = $(this).val();
|
||||
var flag = "on";
|
||||
// 清空上次生成的tag button
|
||||
$(".layui-btn-container").children("button").each(function () {
|
||||
$(this).remove();
|
||||
});
|
||||
getTags(title, flag);
|
||||
$.ajax({
|
||||
type: "post",
|
||||
url: "{:url('Forum/getKeywords')}",
|
||||
data: { keywords: keywords, flag: flag },
|
||||
daType: "json",
|
||||
success: function (data) {
|
||||
if (data.code == 0) {
|
||||
$("input[name='tags']").val(data.data);
|
||||
}
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@ -211,48 +227,34 @@ layui.config({
|
||||
$(".bdsug").addClass('layui-hide');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 添加关键词button
|
||||
function getTags(tags, flag) {
|
||||
if (tags == "") {
|
||||
layer.msg("tag不能为空");
|
||||
return false;
|
||||
}
|
||||
|
||||
//把得到的tags放进数组
|
||||
var numArr = new Array();
|
||||
$(".layui-btn-container")
|
||||
.children("button")
|
||||
.each(function () {
|
||||
numArr.push($(this).val()); //添加至数组
|
||||
});
|
||||
|
||||
$.ajax({
|
||||
type: "post",
|
||||
url: "{:url('Forum/tagWord')}",
|
||||
data: { tags: tags, flag: flag },
|
||||
daType: "json",
|
||||
success: function (data) {
|
||||
if (data.code == 0) {
|
||||
for (var i = 0; i < data.data.length; i++) {
|
||||
if ($.inArray(data.data[i], numArr) < 0) {
|
||||
$(".layui-btn-container").append(
|
||||
'<button type="button" class="layui-btn layui-btn-sm layui-btn-danger" value=' + data.data[i] + ">" + data.data[i] + " x" + "</button>"
|
||||
);
|
||||
}
|
||||
}
|
||||
$("input[name='tags']").val("");
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
//上传附件
|
||||
upload.render({
|
||||
elem: "#zip-button",
|
||||
url: "{:url('forum/uploads')}", //改成您自己的上传接口
|
||||
data: { type: "zip" },
|
||||
accept: "file", //普通文件
|
||||
done: function (res) {
|
||||
if (res.status == 0) {
|
||||
$('input[name="upzip"]').val(res.url);
|
||||
layer.msg("上传成功");
|
||||
} else {
|
||||
layer.msg(res.msg);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
// 删除tag
|
||||
$(document).ready(function () {
|
||||
$(".layui-btn-container").on("click", "button", function () {
|
||||
$(this).remove();
|
||||
});
|
||||
// 改变标题颜色
|
||||
colorpicker.render({
|
||||
elem: "#color",
|
||||
color: "#393d49",
|
||||
predefine: true, // 开启预定义颜色
|
||||
done: function (color) {
|
||||
//譬如你可以在回调中把得到的 color 赋值给表单
|
||||
$("#L_title_color").val(color);
|
||||
$("#L_title").css("color", color);
|
||||
},
|
||||
});
|
||||
|
||||
});
|
||||
|
@ -53,21 +53,19 @@
|
||||
<textarea name="description" class="layui-textarea" placeholder="SEO描述">{$article.description}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
{//关键词}
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-inline">
|
||||
<label class="layui-form-label">{:lang('add tags')}</label>
|
||||
<div class="layui-input-inline" style="width: 190px;">
|
||||
<input type="text" class="layui-input" name="tags" placeholder="多个用空格隔开" title="添加标签"/>
|
||||
<label class="layui-form-label">{:lang('添加关键词')}</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" class="layui-input" name="keywords" value="{$article.keywords}" placeholder="多个英文逗号隔开" title="添加关键词" />
|
||||
</div>
|
||||
<button type="button" class="layui-btn" id="article-tags-button">{:lang('add')}</button>
|
||||
</div>
|
||||
</div>
|
||||
{//tag}
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-btn-container">
|
||||
{volist name="tags" id="vo" }
|
||||
<button type="button" class="layui-btn layui-btn-sm layui-btn-danger" value="{$vo}">{$vo} x</button>
|
||||
{/volist}
|
||||
</div>
|
||||
<label class="layui-form-label">{:lang('add tags')}</label>
|
||||
<div class="layui-input-block">
|
||||
<div id="tag"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item layui-hide">
|
||||
<button type="submit" class="layui-btn" lay-filter="article-edit" lay-submit id="article-edit">{:lang('post now')}</button>
|
||||
@ -98,6 +96,38 @@
|
||||
$(mytextareaid).removeClass();
|
||||
</script>
|
||||
<script src="/addons/taonyeditor/js/taonyeditor.js"></script>
|
||||
<script src="/static/xm-select.js"></script>
|
||||
<script>
|
||||
var artId = "{$article.id}";
|
||||
|
||||
//1.渲染标签
|
||||
var addTags = xmSelect.render({
|
||||
el: '#tag',
|
||||
name: 'tagid',
|
||||
layVerify: 'required',
|
||||
layVerType: 'msg',
|
||||
paging: true,
|
||||
pageSize: 5,
|
||||
data: []
|
||||
});
|
||||
//2.动态赋值
|
||||
$.get("{:url('tag/getArtTag')}",{id:artId},function(res){
|
||||
if(res.code == 0){
|
||||
addTags.setValue(
|
||||
res.data
|
||||
)
|
||||
}
|
||||
});
|
||||
//3.动态标签赋值
|
||||
$.get("{:url('tag/getAllTag')}",function(res){
|
||||
if(res.code == 0){
|
||||
addTags.update({
|
||||
data: res.data,
|
||||
autoRow: true,
|
||||
})
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
layui.use(['colorpicker','form','upload', 'editor'], function(){
|
||||
var $ = layui.jquery
|
||||
@ -117,36 +147,6 @@
|
||||
$('[name="description"]').val(content);
|
||||
});
|
||||
|
||||
//预定义颜色项
|
||||
colorpicker.render({
|
||||
elem: '#color'
|
||||
,color: "{$article.title_color ?? '#333'}"
|
||||
,predefine: true // 开启预定义颜色
|
||||
,done: function(color){
|
||||
//譬如你可以在回调中把得到的 color 赋值给表单
|
||||
$('#L_title_color').val(color);
|
||||
//改变标题颜色
|
||||
$('#L_title').css("color", color);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
//指定允许上传的文件类型
|
||||
upload.render({
|
||||
elem: '#zip-button'
|
||||
,url: "{:url('forum/uploads')}" //改成您自己的上传接口
|
||||
,data: {type:'zip'}
|
||||
,accept: 'file' //普通文件
|
||||
,done: function(res){
|
||||
if(res.status == 0){
|
||||
$('input[name="upzip"]').val(res.url);
|
||||
layer.msg('上传成功');
|
||||
} else {
|
||||
layer.msg(res.msg);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 获取描述的内容
|
||||
$("#L_content").bind('input propertychange', function(){
|
||||
var content = $(this).val()
|
||||
@ -164,65 +164,55 @@
|
||||
return false;
|
||||
})
|
||||
|
||||
// 手动添加tags
|
||||
$('#article-tags-button').on('click',function(){
|
||||
var tags = $("input[name='tags']").val();
|
||||
var flag = 'off';
|
||||
getTags(tags,flag);
|
||||
});
|
||||
|
||||
// 获取tag的内容
|
||||
var conf = "{:empty(config('taoler.baidu.client_id'))}";
|
||||
if(conf !== '1'){
|
||||
$("#L_title").on('blur', function(){
|
||||
var title = $(this).val();
|
||||
var flag = 'on';
|
||||
// 清空上次生成的tag button
|
||||
$('.layui-btn-container').children('button').each(function(){
|
||||
$(this).remove();
|
||||
});
|
||||
getTags(title,flag);
|
||||
})
|
||||
}
|
||||
|
||||
// 循环添加button
|
||||
function getTags(tags,flag)
|
||||
{
|
||||
if(tags == ''){
|
||||
layer.msg('不能为空');
|
||||
return false;
|
||||
}
|
||||
//把得到的tags放进数组
|
||||
var numArr = new Array();
|
||||
$('.layui-btn-container').children('button').each(function(){
|
||||
numArr.push($(this).val());//添加至数组
|
||||
});
|
||||
|
||||
$.ajax({
|
||||
type:"post",
|
||||
url:"{:url('Forum/tagWord')}",
|
||||
data:{"tags":tags,"flag":flag},
|
||||
url:"{:url('Forum/getKeywords')}",
|
||||
data:{"keywords":keywords,"flag":flag},
|
||||
daType:"json",
|
||||
success:function (data){
|
||||
if (data.code == 0) {
|
||||
for(var i=0; i<data.data.length; i++){
|
||||
if($.inArray(data.data[i],numArr) < 0){
|
||||
$('.layui-btn-container').append('<button type="button" class="layui-btn layui-btn-sm layui-btn-danger" value='+data.data[i]+'>'+data.data[i]+' x'+'</button>');
|
||||
}
|
||||
}
|
||||
$("input[name='tags']").val("");
|
||||
$("input[name='keywords']").val("");
|
||||
}
|
||||
}
|
||||
});
|
||||
return false;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
//删除tag
|
||||
$(document).ready(function(){
|
||||
$('.layui-btn-container').on('click','button',function(){
|
||||
$(this).remove();
|
||||
//预定义颜色项
|
||||
colorpicker.render({
|
||||
elem: '#color'
|
||||
,color: "{$article.title_color ?? '#333'}"
|
||||
,predefine: true // 开启预定义颜色
|
||||
,done: function(color){
|
||||
//譬如你可以在回调中把得到的 color 赋值给表单
|
||||
$('#L_title_color').val(color);
|
||||
//改变标题颜色
|
||||
$('#L_title').css("color", color);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
//指定允许上传的文件类型
|
||||
upload.render({
|
||||
elem: '#zip-button'
|
||||
,url: "{:url('forum/uploads')}" //改成您自己的上传接口
|
||||
,data: {type:'zip'}
|
||||
,accept: 'file' //普通文件
|
||||
,done: function(res){
|
||||
if(res.status == 0){
|
||||
$('input[name="upzip"]').val(res.url);
|
||||
layer.msg('上传成功');
|
||||
} else {
|
||||
layer.msg(res.msg);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
|
@ -13,6 +13,7 @@
|
||||
<li lay-id="map">站点地图</li>
|
||||
<li lay-id="robots">robots</li>
|
||||
<li lay-id="push_js">自动提交</li>
|
||||
<li lay-id="tag_link">TagLink</li>
|
||||
<li lay-id="search_show">蜘蛛分析</li>
|
||||
</ul>
|
||||
<div class="layui-tab-content">
|
||||
@ -176,8 +177,43 @@
|
||||
</div>
|
||||
</div>
|
||||
{/volist}
|
||||
|
||||
</div>
|
||||
|
||||
{//taglink}
|
||||
<div class="layui-tab-item">
|
||||
<div class="layui-form" wid100 lay-filter="tag_link">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">关键词</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" name="name" required lay-verify="required" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">链接</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" name="jscode" required lay-verify="required" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-input-block">
|
||||
<button class="layui-btn layui-btn-danger" lay-submit lay-filter="tag_link_submit">提交</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-input-block">
|
||||
<table id="taglink" lay-filter="taglink"></table>
|
||||
<script type="text/html" id="barDemo">
|
||||
<a class="layui-btn layui-btn-xs" lay-event="edit"><i class="layui-icon layui-icon-edit"></i></a>
|
||||
<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del"><i class="layui-icon layui-icon-delete"></i></a>
|
||||
</script>
|
||||
<!--textarea type="text" name="search_list" placeholder="搜索引擎抓取结果" class="layui-textarea" style="height: 600px;"></textarea-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{//蜘蛛分析}
|
||||
|
||||
<div class="layui-tab-item">
|
||||
<div class="layui-form" wid100 lay-filter="search_show">
|
||||
<div class="layui-form-item">
|
||||
@ -206,7 +242,6 @@
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">分析结果</label>
|
||||
|
||||
<div class="layui-input-block">
|
||||
<table id="spider" lay-filter="spider"></table>
|
||||
<!--textarea type="text" name="search_list" placeholder="搜索引擎抓取结果" class="layui-textarea" style="height: 600px;"></textarea-->
|
||||
@ -225,14 +260,14 @@
|
||||
{/block}
|
||||
|
||||
{block name="js"}
|
||||
<script>
|
||||
var setWebSite ="{:url('Set/website')}";
|
||||
var setEmail ="{:url('Set/email')}";
|
||||
<script>
|
||||
var setWebSite ="{:url('Set/website')}";
|
||||
var setEmail ="{:url('Set/email')}";
|
||||
layui.config({
|
||||
base: '/static/admin/' //静态资源所在路径
|
||||
}).extend({
|
||||
index: 'lib/index' //主入口模块
|
||||
}).use(['index', 'laydate', 'table'], function(){
|
||||
}).use(['index'], function(){
|
||||
var $ = layui.$
|
||||
,form = layui.form
|
||||
var element =layui.element ;
|
||||
@ -245,9 +280,9 @@
|
||||
,type: 'date'
|
||||
,format: 'yyyyMM/dd'
|
||||
,value: new Date()
|
||||
});
|
||||
});
|
||||
|
||||
//第一个实例
|
||||
//蜘蛛列表
|
||||
table.render({
|
||||
elem: '#spider'
|
||||
,url: "{:url('seo/searchLog')}" //数据接口
|
||||
@ -262,6 +297,19 @@
|
||||
,limit: 20
|
||||
,text: '对不起,加载出现异常!'
|
||||
});
|
||||
//taglink列表
|
||||
table.render({
|
||||
elem: '#taglink'
|
||||
,url: "{:url('seo/tagLinkList')}" //数据接口
|
||||
,cols: [[ //表头
|
||||
{field: 'id', title: 'ID', width:80, sort: true, fixed: 'left'}
|
||||
,{field: 'tag', title: '名称', width:120, sort: true}
|
||||
,{field: 'link', title: 'URL', minWidth: 200, templet: '<div><a href="{{d.link}}" target="_blank">{{d.link}}</a></div>'}
|
||||
,{field: 'time', title: '时间', width:160}
|
||||
,{fixed: 'right', title:'操作', toolbar: '#barDemo', width:150}
|
||||
]]
|
||||
,text: '对不起,加载出现异常!'
|
||||
});
|
||||
|
||||
// baidu push
|
||||
form.on('submit(search_push)', function(data){
|
||||
@ -326,6 +374,7 @@
|
||||
// 添加自动提交JS代码
|
||||
form.on('submit(push_jscode_submit)', function(data){
|
||||
var field = data.field;
|
||||
field.type = 1;
|
||||
$.post("{:url('seo/savePushJs')}",field,function(res){
|
||||
if(res.code == 0){
|
||||
layer.msg(res.msg,{icon:6,tiye:2000},function(){
|
||||
@ -353,6 +402,43 @@
|
||||
return false;
|
||||
});
|
||||
|
||||
// 添加taglink
|
||||
form.on('submit(tag_link_submit)', function(data){
|
||||
var field = data.field;
|
||||
field.type = 2;
|
||||
$.post("{:url('seo/savePushJs')}",field,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});
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
|
||||
// 删除taglink代码
|
||||
table.on('tool(taglink)', function(obj){
|
||||
var data = obj.data;
|
||||
if(obj.event === 'del'){
|
||||
layer.confirm('真的删除行么', {icon: 3, title:'删除TagLink?'}, function(index){
|
||||
//提交 Ajax 成功后,静态更新表格中的数据
|
||||
$.post("{:url('seo/delPushJs')}", {"id":data.id}, function(data){
|
||||
if (data.code == 0) {
|
||||
layer.msg(data.msg,{icon:6,time:2000}, function(){
|
||||
location.reload();
|
||||
});
|
||||
} else {
|
||||
layer.open({title:'删除失败',content:data.msg,icon:5,anim:6});
|
||||
}
|
||||
});
|
||||
});
|
||||
layer.close(index);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// 搜索引擎分析
|
||||
form.on('submit(search_show_submit)', function(data){
|
||||
var field = data.field;
|
||||
@ -385,8 +471,7 @@
|
||||
location.hash = layid;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
});
|
||||
</script>
|
||||
{/block}
|
||||
|
34
app/admin/view/tag/add.html
Normal file
34
app/admin/view/tag/add.html
Normal file
@ -0,0 +1,34 @@
|
||||
<!--
|
||||
* @Author: TaoLer <317927823@qq.com>
|
||||
* @Date: 2022-05-09 08:31:24
|
||||
* @LastEditTime: 2022-08-14 10:19:20
|
||||
* @LastEditors: TaoLer
|
||||
* @Description: 优化版
|
||||
* @FilePath: \github\TaoLer\app\admin\view\tag\add.html
|
||||
* Copyright (c) 2020~2022 https://www.aieok.com All rights reserved.
|
||||
-->
|
||||
{extend name="public/base" /}
|
||||
|
||||
{block name="body"}
|
||||
<div class="layui-form" lay-filter="layuiadmin-form-slider" id="layuiadmin-form-slider" style="padding: 20px 20px 0 0;">
|
||||
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">名称</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" name="name" lay-verify="required" placeholder="tag名" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">别名</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" name="ename" lay-verify="required" placeholder="英文或者拼音别名" autocomplete="off" class="layui-input" >
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item layui-hide">
|
||||
<input type="button" lay-submit lay-filter="Tag-submit" id="Tag-submit" value="确认">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/block}
|
||||
{block name="js"}{/block}
|
37
app/admin/view/tag/edit.html
Normal file
37
app/admin/view/tag/edit.html
Normal file
@ -0,0 +1,37 @@
|
||||
<!--
|
||||
* @Author: TaoLer <317927823@qq.com>
|
||||
* @Date: 2022-05-09 08:31:24
|
||||
* @LastEditTime: 2022-08-14 10:51:17
|
||||
* @LastEditors: TaoLer
|
||||
* @Description: 优化版
|
||||
* @FilePath: \github\TaoLer\app\admin\view\tag\edit.html
|
||||
* Copyright (c) 2020~2022 https://www.aieok.com All rights reserved.
|
||||
-->
|
||||
{extend name="public/base" /}
|
||||
|
||||
{block name="body"}
|
||||
<div class="layui-form" lay-filter="layuiadmin-form-tag" id="layuiadmin-form-tag" style="padding: 20px 20px 0 0;">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">名称</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" name="name" lay-verify="required" placeholder="tag名" class="layui-input" value="{$tag.name}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">别名</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" name="ename" lay-verify="required" placeholder="英文或者拼音别名" class="layui-input" value="{$tag.ename}" >
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item layui-hide">
|
||||
<input type="text" name="id" class="layui-input layui-hide" value="{$tag.id}">
|
||||
<input type="button" lay-submit lay-filter="Tag-submit" id="Tag-submit" value="确认">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/block}
|
||||
{block name="js"}
|
||||
<script>
|
||||
|
||||
</script>
|
||||
{/block}
|
183
app/admin/view/tag/index.html
Normal file
183
app/admin/view/tag/index.html
Normal file
@ -0,0 +1,183 @@
|
||||
{extend name="public/base" /}
|
||||
|
||||
{block name="body"}
|
||||
<div class="layui-fluid">
|
||||
<div class="layui-row layui-col-space15">
|
||||
<div class="layui-col-md12">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-body">
|
||||
|
||||
<!--div class="layui-form layui-card-header layuiadmin-card-header-auto">
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-inline">
|
||||
<label class="layui-form-label">Tag关键词</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="tag" placeholder="请输入关键词" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-inline">
|
||||
<button class="layui-btn layuiadmin-btn-forum-list" lay-submit lay-filter="Tag-link-search">
|
||||
<i class="layui-icon layui-icon-search layuiadmin-button-btn"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div-->
|
||||
<div style="padding-bottom: 10px;">
|
||||
<button type="button" class="layui-btn layuiadmin-btn-forum-list" id="slid-add">添加</button>
|
||||
</div>
|
||||
<table id="tag" lay-filter="tag"></table>
|
||||
<script type="text/html" id="barDemo">
|
||||
<a class="layui-btn layui-btn-xs" lay-event="edit"><i class="layui-icon layui-icon-edit"></i></a>
|
||||
<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del"><i class="layui-icon layui-icon-delete"></i></a>
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/block}
|
||||
{block name="js"}
|
||||
<script>
|
||||
layui.config({
|
||||
base: '/static/admin/' //静态资源所在路径
|
||||
}).extend({
|
||||
index: 'lib/index' //主入口模块
|
||||
}).use(['index','table'], function(){
|
||||
var $ = layui.jquery
|
||||
,layer = layui.layer
|
||||
,table = layui.table
|
||||
,form = layui.form;
|
||||
|
||||
//第一个实例
|
||||
table.render({
|
||||
elem: '#tag'
|
||||
,url: "{:url('Tag/list')}" //数据接口
|
||||
,page: true //开启分页
|
||||
,cols: [[ //表头
|
||||
{type: 'numbers', fixed: 'left'}
|
||||
,{field: 'name', title: '名称', width:200}
|
||||
,{field: 'ename', title: '别名', minWidth:300}
|
||||
,{field: 'time', title: '时间', minWidth:100}
|
||||
,{fixed: 'right', title:'操作', toolbar: '#barDemo', width:150}
|
||||
]]
|
||||
,limit: 100
|
||||
,text: '对不起,加载出现异常!'
|
||||
});
|
||||
|
||||
form.on('submit(Tag-link-search)', function(data){
|
||||
$.post("{:url('Tag/list')}", {"tag":data.value}, function (data){
|
||||
if (data.code == -1){
|
||||
layer.open({content:data.msg,icon:5,anim:6});
|
||||
}
|
||||
}
|
||||
);
|
||||
//执行重载
|
||||
table.reload('tag-link', {
|
||||
where: {tag: data.value}
|
||||
,page: {
|
||||
curr: 1 //重新从第 1 页开始
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
//监听行工具事件
|
||||
table.on('tool(tag)', function(obj){
|
||||
var data = obj.data;
|
||||
var id = data.id;
|
||||
if(obj.event === 'del'){
|
||||
layer.confirm('真的删除行么', {icon: 3, title:'删除TagLink?'}, function(index){
|
||||
//提交 Ajax 成功后,静态更新表格中的数据
|
||||
$.post("{:url('Tag/delete')}", {"id":id}, function(data){
|
||||
if (data.code == 0) {
|
||||
layer.msg(data.msg,{icon:6,time:2000}, function(){
|
||||
location.reload();
|
||||
});
|
||||
} else {
|
||||
layer.open({title:'删除失败',content:data.msg,icon:5,anim:6});
|
||||
}
|
||||
});
|
||||
});
|
||||
layer.close(index);
|
||||
} else if(obj.event === 'edit'){
|
||||
layer.open({
|
||||
type: 2,
|
||||
title: '编辑Tag',
|
||||
content: 'edit.html?id='+ id,
|
||||
maxmin: true,
|
||||
area : ['400px' , '300px'],
|
||||
btn: ['确定', '取消'],
|
||||
yes: function(index, layero){
|
||||
var iframeWindow = window['layui-layer-iframe'+ index]
|
||||
,submitID = 'Tag-submit'
|
||||
,submit = layero.find('iframe').contents().find('#'+ submitID);
|
||||
//监听提交
|
||||
iframeWindow.layui.form.on('submit('+ submitID +')', function(data){
|
||||
var field = data.field; //获取提交的字段
|
||||
$.ajax({
|
||||
type:"post",
|
||||
url:"{:url('Tag/edit')}",
|
||||
data: field,
|
||||
daType:"json",
|
||||
success:function (data){
|
||||
if (data.code == 0) {
|
||||
layer.msg(data.msg,{icon:6,time:2000}, function(){
|
||||
location.reload();
|
||||
});
|
||||
} else {
|
||||
layer.open({title:'添加失败',content:data.msg,icon:5,anim:6});
|
||||
}
|
||||
}
|
||||
});
|
||||
layer.close(index);
|
||||
});
|
||||
submit.trigger('click');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// 添加
|
||||
$('#slid-add').on('click', function(){
|
||||
layer.open({
|
||||
type: 2,
|
||||
title: '添加Tag',
|
||||
content: 'add.html',
|
||||
maxmin: true,
|
||||
area : ['400px' , '300px'],
|
||||
btn: ['确定', '取消'],
|
||||
yes: function(index, layero){
|
||||
var iframeWindow = window['layui-layer-iframe'+ index]
|
||||
,submitID = 'Tag-submit'
|
||||
,submit = layero.find('iframe').contents().find('#'+ submitID);
|
||||
|
||||
//监听提交
|
||||
iframeWindow.layui.form.on('submit('+ submitID +')', function(data){
|
||||
var field = data.field; //获取提交的字段
|
||||
|
||||
//提交 Ajax 成功后,静态更新表格中的数据
|
||||
$.ajax({
|
||||
type:"post",
|
||||
url:"{:url('Tag/add')}",
|
||||
data: field,
|
||||
daType:"json",
|
||||
success:function (data){
|
||||
if (data.code == 0) {
|
||||
layer.msg(data.msg,{icon:6,time:2000}, function(){
|
||||
location.reload();
|
||||
});
|
||||
} else {
|
||||
layer.open({title:'添加失败',content:data.msg,icon:5,anim:6});
|
||||
}
|
||||
}
|
||||
});
|
||||
layer.close(index);
|
||||
});
|
||||
submit.trigger('click');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
{/block}
|
@ -2,10 +2,10 @@
|
||||
/*
|
||||
* @Author: TaoLer <alipay_tao@qq.com>
|
||||
* @Date: 2021-12-06 16:04:50
|
||||
* @LastEditTime: 2022-08-03 10:34:42
|
||||
* @LastEditTime: 2022-08-15 13:30:05
|
||||
* @LastEditors: TaoLer
|
||||
* @Description: 前端基础控制器设置
|
||||
* @FilePath: \github\TaoLer\app\common\controller\BaseController.php
|
||||
* @FilePath: \TaoLer\app\common\controller\BaseController.php
|
||||
* Copyright (c) 2020~2022 https://www.aieok.com All rights reserved.
|
||||
*/
|
||||
declare (strict_types = 1);
|
||||
@ -87,11 +87,19 @@ class BaseController extends BaseCtrl
|
||||
protected function getHotTag()
|
||||
{
|
||||
//热门标签
|
||||
return Article::getHotTags();
|
||||
//return Article::getHotTags();
|
||||
//转换为字符串
|
||||
// $tagStr = implode(",",$tags);
|
||||
//转换为数组并去重
|
||||
// return array_unique(explode(",",$tagStr));
|
||||
$allTags = Db::name('tag')->field('name,ename')->select();
|
||||
$tagHot = [];
|
||||
foreach($allTags as $v) {
|
||||
$tagHot[] = ['name'=>$v['name'],'url'=> (string) url('tag_list',['ename'=>$v['ename']])];
|
||||
}
|
||||
|
||||
return $tagHot;
|
||||
|
||||
}
|
||||
|
||||
//显示网站设置
|
||||
@ -122,20 +130,4 @@ class BaseController extends BaseCtrl
|
||||
return $sysInfo;
|
||||
}
|
||||
|
||||
//获取artcile所有图片
|
||||
protected function getArticleAllpic($str)
|
||||
{
|
||||
// <img src="http://img.com" />
|
||||
$pattern = "/<[img|IMG].*?src=[\'|\"](.*?(?:[\.gif|\.jpg|\.png]))[\'|\"].*?[\/]?>/";
|
||||
preg_match_all($pattern,$str,$matchContent);
|
||||
if(isset($matchContent[1])){
|
||||
$img = $matchContent[1];
|
||||
}else{
|
||||
$temp = "./images/no-image.jpg";//在相应位置放置一张命名为no-image的jpg图片
|
||||
}
|
||||
|
||||
return $img;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,150 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: TaoLer changlin_zhao@qq.com
|
||||
* Date: 2021-03-12
|
||||
* Time: 17:24
|
||||
*/
|
||||
namespace app\common\lib;
|
||||
|
||||
|
||||
class SetConf
|
||||
{
|
||||
protected string $str = '';
|
||||
|
||||
function __construct(string $fileName)
|
||||
{
|
||||
$this->file = $fileName;
|
||||
$this->file = app()->getConfigPath() . $fileName . '.php';
|
||||
$this->str = $str = file_get_contents($this->file); //加载配置文件
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改配置
|
||||
* @param string $file
|
||||
* @param array $data
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
function setConfig(string $file,array $data=[])
|
||||
{
|
||||
if (is_array($data)){
|
||||
$fileurl = app()->getConfigPath() . $file.".php";
|
||||
$string = file_get_contents($fileurl); //加载配置文件
|
||||
foreach ($data as $key => $value) {
|
||||
if(is_array($value)){//二维数组
|
||||
foreach ($value as $k => $v) {
|
||||
if(is_int($v)){//数字类型
|
||||
$pats = '/\'' . $k . '\'(.*?),/';
|
||||
$reps = "'". $k. "'". " => " . $v .",";
|
||||
//halt($reps);
|
||||
}else{//字符类型
|
||||
$pats = '/\'' . $k . '\'(.*?)\',/';
|
||||
$reps = "'". $k. "'". " => " . "'".$v ."',";
|
||||
}
|
||||
|
||||
$string = preg_replace($pats, $reps, $string); // 正则查找然后替换
|
||||
}
|
||||
|
||||
}else{//一维数组
|
||||
|
||||
if(is_int($value)){//数字类型
|
||||
$pats = '/\'' . $key . '\'(.*?),/';
|
||||
$reps = "'". $key. "'". " => " . "".$value .",";
|
||||
}else{//字符类型
|
||||
$pats = '/\'' . $key . '\'(.*?)\',/';
|
||||
$reps = "'". $key. "'". " => " . "'".$value ."',";
|
||||
}
|
||||
|
||||
$string = preg_replace($pats, $reps, $string); // 正则查找然后替换
|
||||
}
|
||||
}
|
||||
try {
|
||||
file_put_contents($fileurl, $string); // 写入配置文件
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
// 这是进行异常捕获
|
||||
//$e->getMessage();
|
||||
return json(['code'=>-1,'msg'=> $file . '无写入权限']);
|
||||
}
|
||||
|
||||
return json(['code'=>0,'msg'=>'配置修改成功']);
|
||||
}else{
|
||||
return json(['code'=>-1,'msg'=>'配置项错误!']);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 修改配置
|
||||
function editConfig($data)
|
||||
{
|
||||
|
||||
if (is_array($data)){
|
||||
|
||||
foreach ($data as $key => $value)
|
||||
{
|
||||
// 多维数组
|
||||
if (is_array($value)) {
|
||||
$this->editConfig($value);
|
||||
} else {
|
||||
// 一维数组
|
||||
if(is_int($value)){
|
||||
// 数字类型
|
||||
$pats = '/\'' . $key . '\'(.*?),/';
|
||||
$reps = "'". $key. "'". " => " . "".$value .",";
|
||||
} else {
|
||||
// 字符类型
|
||||
$pats = '/\'' . $key . '\'(.*?)\',/';
|
||||
$reps = "'". $key. "'". " => " . "'".$value ."',";
|
||||
}
|
||||
|
||||
$this->str = preg_replace($pats, $reps, $this->str); // 正则查找然后替换
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
file_put_contents($this->file, $this->str); // 写入配置文件
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
// 这是进行异常捕获
|
||||
echo $e->getMessage();
|
||||
//return json(['code'=>-1,'msg'=> $file . '无写入权限']);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/* 删除配置
|
||||
*
|
||||
*/
|
||||
function del(array $arr)
|
||||
{
|
||||
if (is_array($arr)){
|
||||
foreach ($arr as $key => $value)
|
||||
{
|
||||
// 递归删除key
|
||||
if (is_array($value)) {
|
||||
$this->del($value);
|
||||
} else {
|
||||
// 正则查找然后替换
|
||||
$pats = '/\s?\'' . $value . '\'(.*?)\r\n/';
|
||||
$this->str = preg_replace($pats, '', $this->str);
|
||||
}
|
||||
|
||||
/* 匹配空数组
|
||||
* 'key' => [
|
||||
* ],
|
||||
*/
|
||||
$pats = '/\s?\'\w+\'\s*\=\>\s*\[\s*\]{1}\S*\,?\s$/m';
|
||||
$this->str = preg_replace($pats, '', $this->str);
|
||||
|
||||
}
|
||||
//写入配置
|
||||
file_put_contents($this->file, $this->str); // 写入配置文件
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -1,4 +1,13 @@
|
||||
<?php
|
||||
/*
|
||||
* @Author: TaoLer <317927823@qq.com>
|
||||
* @Date: 2021-12-06 16:04:50
|
||||
* @LastEditTime: 2022-08-16 14:16:40
|
||||
* @LastEditors: TaoLer
|
||||
* @Description: 优化版
|
||||
* @FilePath: \TaoLer\app\common\lib\SqlFile.php
|
||||
* Copyright (c) 2020~2022 https://www.aieok.com All rights reserved.
|
||||
*/
|
||||
declare (strict_types = 1);
|
||||
|
||||
namespace app\common\lib;
|
||||
@ -20,7 +29,7 @@ class SqlFile
|
||||
return false;
|
||||
}
|
||||
$lines = file($path, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
|
||||
$aout = false;
|
||||
$aout = [];
|
||||
$str = '';
|
||||
$skip = false;
|
||||
$fn = false;
|
||||
|
@ -1,30 +0,0 @@
|
||||
<?php
|
||||
namespace app\common\lib;
|
||||
|
||||
class UploadFile
|
||||
{
|
||||
protected static $_instance = null;
|
||||
protected $file;
|
||||
protected $path;
|
||||
protected $filesize;
|
||||
protected $fileExt;
|
||||
|
||||
private function __construct($path)
|
||||
{
|
||||
$this->path = $path;
|
||||
}
|
||||
|
||||
private function __clone()
|
||||
{
|
||||
// TODO: Implement __clone() method.
|
||||
}
|
||||
|
||||
static function getInstance()
|
||||
{
|
||||
if(!(self::$_instance)){
|
||||
self::$_instance = new self();
|
||||
}
|
||||
return self::$_instance;
|
||||
}
|
||||
|
||||
}
|
@ -1,99 +0,0 @@
|
||||
<?php
|
||||
namespace app\common\lib;
|
||||
|
||||
|
||||
class ZipFile
|
||||
{
|
||||
/**
|
||||
* header('Content-type:text/html;charset=utf-8');
|
||||
* @param string $filename 解压文件
|
||||
* @param string $dir 解压到路径
|
||||
* @param bool $overwrite 是否覆盖文件 true false
|
||||
* @return bool
|
||||
*/
|
||||
public function unZip($filename, $dir ,$overwrite = true)
|
||||
{
|
||||
if(!is_dir($dir)) {
|
||||
//mkdir($dir, 0777, true);//创建目录保存解压内容
|
||||
$this->create_dirs($dir);
|
||||
}
|
||||
|
||||
if(file_exists($filename)) {
|
||||
$resource = zip_open($filename);
|
||||
|
||||
while($zip = zip_read($resource)) {
|
||||
if(zip_entry_open($resource, $zip)) {
|
||||
|
||||
//获得文件名,mac压缩成zip,解压需要过滤资源库隐藏文件
|
||||
$file_content = zip_entry_name($zip);
|
||||
|
||||
|
||||
// 如果文件不在根目录中
|
||||
$pos_last_slash = strrpos($file_content, "/");
|
||||
$file_name = substr($file_content, $pos_last_slash+1);
|
||||
|
||||
$save_path = $dir.$file_content;
|
||||
if(!is_dir($save_path));
|
||||
{
|
||||
$this->create_dirs($save_path);
|
||||
}
|
||||
|
||||
if($file_name) {
|
||||
|
||||
if(file_exists($save_path)) {
|
||||
if($overwrite === true){
|
||||
//echo $file_name . '<pre />';
|
||||
$file_size = zip_entry_filesize($zip);
|
||||
$file = zip_entry_read($zip, $file_size);
|
||||
$fpc = file_put_contents($save_path, $file);
|
||||
//zip_entry_close($zip);
|
||||
}else{
|
||||
//echo '文件夹内已存在文件 "' . $file_name . '" <pre />';
|
||||
return json(['code'=>-1,'msg'=>'文件夹内已存在文件']);
|
||||
}
|
||||
|
||||
} else {
|
||||
//echo $file_name . '<pre />';
|
||||
$file_size = zip_entry_filesize($zip);
|
||||
$file = zip_entry_read($zip, $file_size);
|
||||
$fpc = file_put_contents($save_path, $file);
|
||||
//zip_entry_close($zip);
|
||||
}
|
||||
|
||||
}
|
||||
zip_entry_close($zip);
|
||||
}
|
||||
}
|
||||
zip_close($resource);
|
||||
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建文件夹及子文件夹
|
||||
* @param $path
|
||||
* @return bool
|
||||
*/
|
||||
public function create_dirs($path)
|
||||
{
|
||||
if (!is_dir($path))
|
||||
{
|
||||
$directory_path = "";
|
||||
$directories = explode("/",$path);
|
||||
array_pop($directories);
|
||||
|
||||
foreach($directories as $directory)
|
||||
{
|
||||
$directory_path .= $directory."/";
|
||||
if (!is_dir($directory_path))
|
||||
{
|
||||
mkdir($directory_path);
|
||||
chmod($directory_path, 0777);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -7,11 +7,9 @@ use think\Model;
|
||||
use think\model\concern\SoftDelete;
|
||||
use think\facade\Cache;
|
||||
use think\facade\Config;
|
||||
use Overtrue\Pinyin\Pinyin;
|
||||
|
||||
class Article extends Model
|
||||
{
|
||||
//protected $pk = 'id'; //主键
|
||||
protected $autoWriteTimestamp = true; //开启自动时间戳
|
||||
protected $createTime = 'create_time';
|
||||
protected $updateTime = 'update_time';
|
||||
@ -57,6 +55,12 @@ class Article extends Model
|
||||
return $this->belongsTo('User','user_id','id');
|
||||
}
|
||||
|
||||
//文章关联Tag表
|
||||
public function taglist()
|
||||
{
|
||||
return $this->hasMany(Taglist::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加
|
||||
* @param array $data
|
||||
@ -69,10 +73,10 @@ class Article extends Model
|
||||
$data['status'] = $superAdmin ? 1 : Config::get('taoler.config.posts_check');
|
||||
$msg = $data['status'] ? '发布成功' : '发布成功,请等待审核';
|
||||
$result = $this->save($data);
|
||||
if($result) {
|
||||
return ['code' => 1, 'msg' => $msg, 'data' => ['status' => $data['status']]];
|
||||
if($result == true) {
|
||||
return ['code' => 1, 'msg' => $msg, 'data' => ['status' => $data['status'], 'id'=> $this->id]];
|
||||
} else {
|
||||
return 'add_error';
|
||||
return ['code' => -1, 'msg'=> '添加文章失败'];
|
||||
}
|
||||
}
|
||||
|
||||
@ -170,7 +174,7 @@ class Article extends Model
|
||||
public function getArtHot(int $num)
|
||||
{
|
||||
$artHot = $this::field('id,cate_id,title,create_time')
|
||||
->with([ 'cate' => function($query){
|
||||
->with(['cate' => function($query){
|
||||
$query->where('delete_time',0)->field('id,ename');
|
||||
}])
|
||||
->withCount('comments')
|
||||
@ -198,7 +202,9 @@ class Article extends Model
|
||||
$article = Cache::get('article_'.$id);
|
||||
if(!$article){
|
||||
//查询文章
|
||||
$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([
|
||||
$article = $this::field('id,title,content,status,cate_id,user_id,goods_detail_id,is_top,is_hot,is_reply,pv,jie,upzip,downloads,keywords,description,title_color,create_time,update_time')
|
||||
->where(['status'=>1])
|
||||
->with([
|
||||
'cate' => function($query){
|
||||
$query->where('delete_time',0)->field('id,catename,ename');
|
||||
},
|
||||
@ -208,9 +214,13 @@ class Article extends Model
|
||||
])
|
||||
->withCount(['comments'])
|
||||
->append(['url'])
|
||||
->find($id)
|
||||
->toArray();
|
||||
Cache::tag('tagArtDetail')->set('article_'.$id, $article, 3600);
|
||||
->find($id);
|
||||
if (!is_null($article)) {
|
||||
Cache::tag('tagArtDetail')->set('article_'.$id, $article->toArray(), 3600);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
return $article;
|
||||
}
|
||||
@ -314,58 +324,23 @@ class Article extends Model
|
||||
}
|
||||
}
|
||||
|
||||
// 热门标签
|
||||
public function getHotTags()
|
||||
// 标签列表
|
||||
public function getAllTags($tagId)
|
||||
{
|
||||
$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;
|
||||
$allTags = $this::hasWhere('taglist',['tag_id'=>$tagId])
|
||||
->with(['user' => function($query){
|
||||
$query->field('id,name,nickname,user_img,area_id,vip');
|
||||
},'cate' => function($query){
|
||||
$query->where('delete_time',0)->field('id,catename,ename');
|
||||
}])
|
||||
->where(['status'=>1])
|
||||
->order('pv desc')
|
||||
->limit(50)
|
||||
->append(['url'])
|
||||
->select()
|
||||
->toArray();
|
||||
|
||||
return $allTags;
|
||||
}
|
||||
|
||||
// 获取url
|
||||
|
@ -2,9 +2,9 @@
|
||||
/*
|
||||
* @Author: TaoLer <317927823@qq.com>
|
||||
* @Date: 2021-12-06 16:04:50
|
||||
* @LastEditTime: 2022-08-10 14:36:20
|
||||
* @LastEditTime: 2022-08-14 07:33:14
|
||||
* @LastEditors: TaoLer
|
||||
* @Description: 优化版
|
||||
* @Description: 分类模型
|
||||
* @FilePath: \github\TaoLer\app\common\model\Cate.php
|
||||
* Copyright (c) 2020~2022 https://www.aieok.com All rights reserved.
|
||||
*/
|
||||
|
@ -2,24 +2,19 @@
|
||||
/*
|
||||
* @Author: TaoLer <alipay_tao@qq.com>
|
||||
* @Date: 2021-12-06 16:04:50
|
||||
* @LastEditTime: 2022-07-27 21:42:34
|
||||
* @LastEditTime: 2022-08-15 13:37:58
|
||||
* @LastEditors: TaoLer
|
||||
* @Description: 搜索引擎SEO优化设置
|
||||
* @FilePath: \github\TaoLer\app\common\model\Comment.php
|
||||
* @Description: 评论模型
|
||||
* @FilePath: \TaoLer\app\common\model\Comment.php
|
||||
* Copyright (c) 2020~2022 https://www.aieok.com All rights reserved.
|
||||
*/
|
||||
namespace app\common\model;
|
||||
|
||||
use think\Model;
|
||||
use think\model\concern\SoftDelete;
|
||||
use think\facade\Cache;
|
||||
|
||||
class Comment extends Model
|
||||
{
|
||||
protected $autoWriteTimestamp = true; //开启自动时间戳
|
||||
protected $createTime = 'create_time';
|
||||
protected $updateTime = 'update_time';
|
||||
|
||||
{
|
||||
//软删除
|
||||
use SoftDelete;
|
||||
protected $deleteTime = 'delete_time';
|
||||
@ -47,37 +42,30 @@ class Comment extends Model
|
||||
//回帖榜
|
||||
public function reply($num)
|
||||
{
|
||||
// $user = Cache::get('user_reply');
|
||||
// if(empty($user)){
|
||||
try {
|
||||
$user = User::field('id,user_img,name,nickname')
|
||||
->withCount(['comments'=> function($query) {
|
||||
$query->where(['status'=>1]);
|
||||
}])
|
||||
->order(['comments_count'=>'desc','last_login_time'=>'desc'])
|
||||
->limit($num)
|
||||
->select()
|
||||
->toArray();
|
||||
} catch(\Exception $e) {
|
||||
return json(['status'=>-1,'msg'=>$e->getMessage()]);
|
||||
}
|
||||
|
||||
// Cache::set('user_reply',$user,180);
|
||||
// }
|
||||
try {
|
||||
$user = User::field('id,user_img,name,nickname')
|
||||
->withCount(['comments'=> function($query) {
|
||||
$query->where(['status'=>1]);
|
||||
}])
|
||||
->order(['comments_count'=>'desc','last_login_time'=>'desc'])
|
||||
->limit($num)
|
||||
->withCache(300)
|
||||
->select()
|
||||
->toArray();
|
||||
} catch(\Exception $e) {
|
||||
return json(['status'=>-1,'msg'=>$e->getMessage()]);
|
||||
}
|
||||
|
||||
if(count($user)) {
|
||||
$res['status'] = 0;
|
||||
$res['data'] = array();
|
||||
foreach ($user as $key=>$v) {
|
||||
//$u['uid'] = (string) url('user/home',['id'=>$v['id']]);
|
||||
$u['uid'] = (string) \think\facade\Route::buildUrl('user_home', ['id' => $v['id']]);
|
||||
$u['uid'] = (string) url('user_home',['id'=>$v['id']]);
|
||||
// $u['uid'] = (string) \think\facade\Route::buildUrl('user_home', ['id' => $v['id']]);
|
||||
$u['count'] = $v['comments_count'];
|
||||
if($v['nickname'])
|
||||
{
|
||||
$u['user'] = ['username'=>$v['nickname'],'avatar'=>$v['user_img']];
|
||||
} else {
|
||||
$u['user'] = ['username'=>$v['name'],'avatar'=>$v['user_img']];
|
||||
}
|
||||
|
||||
$u['user'] = ['username'=>$v['nickname'] ?: $v['name'] ,'avatar'=>$v['user_img']];
|
||||
|
||||
$res['data'][] = $u;
|
||||
}
|
||||
} else {
|
||||
|
65
app/common/model/PushJscode.php
Normal file
65
app/common/model/PushJscode.php
Normal file
@ -0,0 +1,65 @@
|
||||
<?php
|
||||
/*
|
||||
* @Author: TaoLer <alipey_tao@qq.com>
|
||||
* @Date: 2022-04-20 10:45:41
|
||||
* @LastEditTime: 2022-08-14 09:23:02
|
||||
* @LastEditors: TaoLer
|
||||
* @Description: jscode和taglink设置
|
||||
* @FilePath: \github\TaoLer\app\common\model\PushJscode.php
|
||||
* Copyright (c) 2020~2022 http://www.aieok.com All rights reserved.
|
||||
*/
|
||||
|
||||
namespace app\common\model;
|
||||
|
||||
use think\Model;
|
||||
|
||||
class PushJscode extends Model
|
||||
{
|
||||
/**
|
||||
* 保存代码
|
||||
*
|
||||
* @param [type] $data
|
||||
* @return void
|
||||
*/
|
||||
public function saveCode($data)
|
||||
{
|
||||
$res = $this->save($data);
|
||||
if($res == true) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取分类数据
|
||||
* 1jscode 2taglink
|
||||
*
|
||||
* @param integer $type
|
||||
* @return array
|
||||
*/
|
||||
public function getAllCodes(int $type)
|
||||
{
|
||||
//
|
||||
return $this->where('type',$type)->select()->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除数据
|
||||
*
|
||||
* @param [type] $id
|
||||
* @return void
|
||||
*/
|
||||
public function delCode($id)
|
||||
{
|
||||
//
|
||||
$res = $this::destroy($id);
|
||||
|
||||
if($res == true) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,4 +1,13 @@
|
||||
<?php
|
||||
/*
|
||||
* @Author: TaoLer <317927823@qq.com>
|
||||
* @Date: 2021-12-06 16:04:50
|
||||
* @LastEditTime: 2022-08-14 07:32:32
|
||||
* @LastEditors: TaoLer
|
||||
* @Description: 签到模型
|
||||
* @FilePath: \github\TaoLer\app\common\model\Sign.php
|
||||
* Copyright (c) 2020~2022 https://www.aieok.com All rights reserved.
|
||||
*/
|
||||
namespace app\common\model;
|
||||
|
||||
use think\Model;
|
||||
@ -8,14 +17,6 @@ use think\facade\Session;
|
||||
|
||||
class Sign extends Model
|
||||
{
|
||||
protected $pk = 'id'; //主键
|
||||
protected $autoWriteTimestamp = true; //开启自动时间戳
|
||||
protected $createTime = 'create_time';
|
||||
protected $updateTime = 'update_time';
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//用户关联评论
|
||||
public function user()
|
||||
|
61
app/common/model/Tag.php
Normal file
61
app/common/model/Tag.php
Normal file
@ -0,0 +1,61 @@
|
||||
<?php
|
||||
/*
|
||||
* @Author: TaoLer <alipey_tao@qq.com>
|
||||
* @Date: 2022-04-20 10:45:41
|
||||
* @LastEditTime: 2022-08-15 12:16:41
|
||||
* @LastEditors: TaoLer
|
||||
* @Description: 文章tag设置
|
||||
* @FilePath: \TaoLer\app\common\model\Tag.php
|
||||
* Copyright (c) 2020~2022 http://www.aieok.com All rights reserved.
|
||||
*/
|
||||
|
||||
namespace app\common\model;
|
||||
|
||||
use think\Model;
|
||||
|
||||
class Tag extends Model
|
||||
{
|
||||
|
||||
|
||||
public function getTagList()
|
||||
{
|
||||
//
|
||||
return $this::select()->toArray();
|
||||
}
|
||||
|
||||
public function getTag($id)
|
||||
{
|
||||
//
|
||||
return $this::find($id);
|
||||
}
|
||||
|
||||
|
||||
public function saveTag($data)
|
||||
{
|
||||
$res = $this->save($data);
|
||||
if($res == true) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除数据
|
||||
*
|
||||
* @param [type] $id
|
||||
* @return void
|
||||
*/
|
||||
public function delTag($id)
|
||||
{
|
||||
//
|
||||
$res = $this::destroy($id);
|
||||
|
||||
if($res == true) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
56
app/common/model/Taglist.php
Normal file
56
app/common/model/Taglist.php
Normal file
@ -0,0 +1,56 @@
|
||||
<?php
|
||||
/*
|
||||
* @Author: TaoLer <alipey_tao@qq.com>
|
||||
* @Date: 2022-04-20 10:45:41
|
||||
* @LastEditTime: 2022-08-15 13:37:35
|
||||
* @LastEditors: TaoLer
|
||||
* @Description: 文章tag设置
|
||||
* @FilePath: \TaoLer\app\common\model\Taglist.php
|
||||
* Copyright (c) 2020~2022 http://www.aieok.com All rights reserved.
|
||||
*/
|
||||
|
||||
namespace app\common\model;
|
||||
|
||||
use think\Model;
|
||||
|
||||
class Taglist extends Model
|
||||
{
|
||||
public function article()
|
||||
{
|
||||
//评论关联文章
|
||||
return $this->belongsTo('Article','article_id','id');
|
||||
}
|
||||
|
||||
|
||||
public function getTagList()
|
||||
{
|
||||
//
|
||||
return $this::select()->toArray();
|
||||
}
|
||||
|
||||
public function getTag($id)
|
||||
{
|
||||
//
|
||||
return $this::find($id);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 删除数据
|
||||
*
|
||||
* @param [type] $id
|
||||
* @return void
|
||||
*/
|
||||
public function delTag($id)
|
||||
{
|
||||
//
|
||||
$res = $this::destroy($id);
|
||||
|
||||
if($res == true) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -13,11 +13,9 @@ use app\common\model\Comment;
|
||||
use app\common\model\Article as ArticleModel;
|
||||
use app\common\model\Slider;
|
||||
use app\common\model\UserZan;
|
||||
|
||||
use app\common\model\PushJscode;
|
||||
use taoler\com\Message;
|
||||
use app\common\lib\Msgres;
|
||||
use Overtrue\Pinyin\Pinyin;
|
||||
|
||||
|
||||
class Article extends BaseController
|
||||
{
|
||||
@ -28,18 +26,16 @@ class Article extends BaseController
|
||||
//文章分类
|
||||
public function cate()
|
||||
{
|
||||
//非法请求参数,抛出异常
|
||||
if(count(Request::param()) >3){
|
||||
// 抛出 HTTP 异常
|
||||
throw new \think\exception\HttpException(404, '请求异常');
|
||||
}
|
||||
//动态参数
|
||||
$ename = Request::param('ename') ?? 'all';
|
||||
$cate = new Cate();
|
||||
$ad = new Slider();
|
||||
$article = new ArticleModel();
|
||||
//动态参数
|
||||
$ename = Request::param('ename');
|
||||
$type = Request::param('type','all');
|
||||
$page = Request::param('page',1);
|
||||
|
||||
// 分类信息
|
||||
$cateInfo = $cate->getCateInfo($ename);
|
||||
// halt($cateInfo);
|
||||
$type = Request::param('type') ?? 'all';
|
||||
$page = Request::param('page') ? Request::param('page') : 1;
|
||||
|
||||
//分页url
|
||||
$url = url('cate_page',['ename'=>$ename,'type'=>$type,'page'=>$page]);
|
||||
@ -47,18 +43,15 @@ class Article extends BaseController
|
||||
$path = substr($url,0,strrpos($url,"/"));
|
||||
|
||||
//分类列表
|
||||
$article = new ArticleModel();
|
||||
$artList = $article->getCateList($ename,$type,$page);
|
||||
// 热议文章
|
||||
$artHot = $article->getArtHot(10);
|
||||
//广告
|
||||
$ad = new Slider();
|
||||
//分类图片
|
||||
$ad_cateImg = $ad->getSliderList(3);
|
||||
//分类钻展赞助
|
||||
$ad_comm = $ad->getSliderList(6);
|
||||
|
||||
View::assign([
|
||||
$assignArr = [
|
||||
'ename'=>$ename,
|
||||
'cateinfo'=> $cateInfo,
|
||||
'type'=>$type,
|
||||
@ -68,26 +61,27 @@ class Article extends BaseController
|
||||
'ad_comm'=>$ad_comm,
|
||||
'path'=>$path,
|
||||
'jspage'=>'jie'
|
||||
]);
|
||||
return View::fetch('article/' . $cateInfo->detpl . '/cate');
|
||||
];
|
||||
View::assign($assignArr);
|
||||
|
||||
$cateView = is_null($cateInfo) ? 'article/cate' : 'article/' . $cateInfo->detpl . '/cate';
|
||||
return View::fetch($cateView);
|
||||
}
|
||||
|
||||
//文章详情页
|
||||
public function detail()
|
||||
{
|
||||
$id = input('id');
|
||||
$artStu = Db::name('article')->field('id')->where(['status'=>1,'delete_time'=>0])->find($id);
|
||||
if(is_null($artStu)){
|
||||
// 抛出 HTTP 异常
|
||||
throw new \think\exception\HttpException(404, '异常消息');
|
||||
}
|
||||
|
||||
$page = input('page',1);
|
||||
//输出内容
|
||||
$page = input('page') ? input('page') : 1;
|
||||
$article = new ArticleModel();
|
||||
$artDetail = $article->getArtDetail($id);
|
||||
if(is_null($artDetail)){
|
||||
// 抛出 HTTP 异常
|
||||
throw new \think\exception\HttpException(404, '无内容');
|
||||
}
|
||||
//用户个人tag标签
|
||||
$userTags = $article->where(['user_id'=>$artDetail['user_id'],'status'=>1])->where('tags','<>','')->column('tags');
|
||||
$userTags = $article->where(['user_id'=>$artDetail['user_id'],'status'=>1])->where('keywords','<>','')->column('keywords');
|
||||
//转换为字符串
|
||||
$tagStr = implode(",",$userTags);
|
||||
//转换为数组并去重
|
||||
@ -103,42 +97,20 @@ class Article extends BaseController
|
||||
|
||||
// 设置内容的tag内链
|
||||
$artDetail['content'] = $this->setArtTagLink($artDetail['content']);
|
||||
|
||||
// tag
|
||||
// $tags = [];
|
||||
// if(!is_null($artDetail['tags'])){
|
||||
// $attr = explode(',', $artDetail['tags']);
|
||||
// foreach($attr as $v){
|
||||
// if ($v !='') {
|
||||
// $tags[] = $v;
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// $tags[] = $artDetail['title'];
|
||||
// }
|
||||
|
||||
// $tag = new Tag();
|
||||
// $tags = $tag->getArtTag($artDetail['tags']);
|
||||
|
||||
$pinyin = new Pinyin();
|
||||
$tags = [];
|
||||
if(!is_null($artDetail['tags'])){
|
||||
$attr = explode(',', $artDetail['tags']);
|
||||
foreach($attr as $v){
|
||||
if ($v !='') {
|
||||
$tags[] = ['tag'=>$v,'pinyin'=>$pinyin->permalink($v,''), 'url'=> (string) url('tag_list',['tag'=>$pinyin->permalink($v,'')])];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 标签
|
||||
$tags = [];
|
||||
$artTags = Db::name('taglist')->where('article_id',$id)->select();
|
||||
// halt($artTags);
|
||||
foreach($artTags as $v) {
|
||||
$tag = Db::name('tag')->find($v['tag_id']);
|
||||
$tags[] = ['name'=>$tag['name'],'url'=> (string) url('tag_list',['ename'=>$tag['ename']])];
|
||||
}
|
||||
|
||||
|
||||
$tpl = Db::name('cate')->where('id', $artDetail['cate_id'])->value('detpl');
|
||||
$download = $artDetail['upzip'] ? download($artDetail['upzip'],'file') : '';
|
||||
|
||||
//$count = $comments->total();
|
||||
//$artDetail->inc('pv')->update();
|
||||
|
||||
//浏览pv
|
||||
Db::name('article')->where('id',$id)->inc('pv')->update();
|
||||
$pv = Db::name('article')->field('pv')->where('id',$id)->value('pv');
|
||||
@ -246,18 +218,18 @@ class Article extends BaseController
|
||||
if (Request::isAjax()) {
|
||||
// 检验发帖是否开放
|
||||
if(config('taoler.config.is_post') == 0 ) return json(['code'=>-1,'msg'=>'抱歉,系统维护中,暂时禁止发帖!']);
|
||||
|
||||
$data = Request::only(['cate_id', 'title', 'title_color', 'user_id', 'content', 'upzip', 'tags', 'description', 'captcha']);
|
||||
// 数据
|
||||
$data = Request::only(['cate_id', 'title', 'title_color', 'user_id', 'content', 'upzip', 'keywords', 'description', 'captcha']);
|
||||
$tagId = input('tagid');
|
||||
|
||||
// 验证码
|
||||
if(Config::get('taoler.config.post_captcha') == 1)
|
||||
{
|
||||
if(Config::get('taoler.config.post_captcha') == 1) {
|
||||
if(!captcha_check($data['captcha'])){
|
||||
return json(['code'=>-1,'msg'=> '验证码失败']);
|
||||
};
|
||||
}
|
||||
|
||||
// 调用验证器
|
||||
// 验证器
|
||||
$validate = new \app\common\validate\Article;
|
||||
$result = $validate->scene('Artadd')->check($data);
|
||||
if (true !== $result) {
|
||||
@ -268,7 +240,10 @@ class Article extends BaseController
|
||||
$iva= $this->hasIva($data['content']);
|
||||
$data = array_merge($data,$iva);
|
||||
|
||||
// 处理内容
|
||||
$data['content'] = $this->downUrlPicsReaplace($data['content']);
|
||||
// 把,转换为,并去空格->转为数组->去掉空数组->再转化为带,号的字符串
|
||||
$data['keywords'] = implode(',',array_filter(explode(',',trim(str_replace(',',',',$data['keywords'])))));
|
||||
|
||||
// 获取分类ename
|
||||
$cate_ename = Db::name('cate')->where('id',$data['cate_id'])->value('ename');
|
||||
@ -277,8 +252,19 @@ class Article extends BaseController
|
||||
|
||||
$result = $article->add($data);
|
||||
if ($result['code'] == 1) {
|
||||
$aid = $result['data']['id'];
|
||||
//写入taglist表
|
||||
$tagArr = [];
|
||||
if(isset($tagId)) {
|
||||
$tagIdArr = explode(',',$tagId);
|
||||
foreach($tagIdArr as $tid) {
|
||||
$tagArr[] = ['article_id'=>$aid,'tag_id'=>$tid,'create_time'=>time()];
|
||||
}
|
||||
}
|
||||
Db::name('taglist')->insertAll($tagArr);
|
||||
// 获取到的最新ID
|
||||
$aid = Db::name('article')->max('id');
|
||||
//$aid = Db::name('article')->max('id');
|
||||
|
||||
// 清除文章tag缓存
|
||||
Cache::tag('tagArtDetail')->clear();
|
||||
// 发提醒邮件
|
||||
@ -296,7 +282,8 @@ class Article extends BaseController
|
||||
return $res;
|
||||
}
|
||||
|
||||
View::assign(['jspage'=>'jie']);
|
||||
|
||||
// 子模块自定义自适应add.html模板
|
||||
$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;
|
||||
@ -304,6 +291,7 @@ class Article extends BaseController
|
||||
$vfile = $viewRoot . $view;
|
||||
$addTpl = is_file($vfile) ? $vfile : 'add';
|
||||
|
||||
View::assign(['jspage'=>'jie']);
|
||||
return View::fetch($addTpl);
|
||||
}
|
||||
|
||||
@ -320,7 +308,10 @@ class Article extends BaseController
|
||||
$article = ArticleModel::find($id);
|
||||
|
||||
if(Request::isAjax()){
|
||||
$data = Request::only(['id','cate_id','title','title_color','user_id','content','upzip','tags','description','captcha']);
|
||||
$data = Request::only(['id','cate_id','title','title_color','user_id','content','upzip','keywords','description','captcha']);
|
||||
$tagId = input('tagid');
|
||||
|
||||
|
||||
// 验证码
|
||||
if(Config::get('taoler.config.post_captcha') == 1)
|
||||
{
|
||||
@ -340,10 +331,35 @@ class Article extends BaseController
|
||||
$data = array_merge($data,$iva);
|
||||
|
||||
$data['content'] = $this->downUrlPicsReaplace($data['content']);
|
||||
// 把,转换为,并去空格->转为数组->去掉空数组->再转化为带,号的字符串
|
||||
$data['keywords'] = implode(',',array_filter(explode(',',trim(str_replace(',',',',$data['keywords'])))));
|
||||
|
||||
|
||||
$result = $article->edit($data);
|
||||
if($result == 1) {
|
||||
//处理标签
|
||||
$artTags = Db::name('taglist')->where('article_id',$id)->column('tag_id','id');
|
||||
if(isset($tagId)) {
|
||||
$tagIdArr = explode(',',$tagId);
|
||||
foreach($artTags as $aid => $tid) {
|
||||
if(!in_array($tid,$tagIdArr)){
|
||||
//删除被取消的tag
|
||||
Db::name('taglist')->delete($aid);
|
||||
}
|
||||
}
|
||||
//查询保留的标签
|
||||
$artTags = Db::name('taglist')->where('article_id',$id)->column('tag_id');
|
||||
$tagArr = [];
|
||||
foreach($tagIdArr as $tid) {
|
||||
if(!in_array($tid, $artTags)){
|
||||
//新标签
|
||||
$tagArr[] = ['article_id'=>$data['id'],'tag_id'=>$tid,'create_time'=>time()];
|
||||
}
|
||||
}
|
||||
//更新新标签
|
||||
Db::name('taglist')->insertAll($tagArr);
|
||||
}
|
||||
|
||||
//删除原有缓存显示编辑后内容
|
||||
Cache::delete('article_'.$id);
|
||||
$link = $this->getRouteUrl((int) $id, $article->cate->ename);
|
||||
@ -453,10 +469,10 @@ class Article extends BaseController
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function tags()
|
||||
public function keywords()
|
||||
{
|
||||
$data = Request::only(['tags','flag']);
|
||||
return $this->setTags($data);
|
||||
$data = Request::only(['keywords','flag']);
|
||||
return $this->setKeywords($data);
|
||||
}
|
||||
|
||||
// 文章置顶、加精、评论状态
|
||||
@ -539,7 +555,8 @@ class Article extends BaseController
|
||||
protected function setArtTagLink($content)
|
||||
{
|
||||
// tag链接数组
|
||||
$tag = Config::get('taglink');
|
||||
$taglink = new PushJscode();
|
||||
$tag = $taglink->getAllCodes(2);
|
||||
if(count($tag)) {
|
||||
foreach($tag as $key=>$value) {
|
||||
// 匹配所有
|
||||
@ -551,12 +568,12 @@ class Article extends BaseController
|
||||
// $pats = '/(?<!<a\s?(.*)?)'.$key.'(?!<\/a>)/';
|
||||
//$pats = '/'.$key.'(?!<\/a>)/';
|
||||
// 不匹配 $key</a>已经存在链接的情况
|
||||
$pats = '/'.$key. '\s?(?!<\/a>|")/is';
|
||||
$pats = '/' . $value['name'] . '\s?(?!<\/a>|")/is';
|
||||
|
||||
preg_match($pats,$content,$arr);
|
||||
|
||||
// 开启和关闭编辑器使用不同的链接方式
|
||||
$rpes = hook('taonystatus') ? '<a href="'.$value.'" target="_blank" title="'.$key.'" style="font-weight: bold;color:#31BDEC">'.$key.'</a>' : 'a('.$value.')['.$key.']';
|
||||
$rpes = hook('taonystatus') ? '<a href="' . $value['jscode'] . '" target="_blank" title="' . $value['name'] . '" style="font-weight: bold;color:#31BDEC">' . $value['name'] . '</a>' : 'a(' . $value['jscode'] . ')[' . $value['name'] . ']';
|
||||
|
||||
$content = preg_replace($pats,$rpes,$content,2);
|
||||
}
|
||||
@ -584,77 +601,5 @@ class Article extends BaseController
|
||||
|
||||
}
|
||||
|
||||
//下载图片
|
||||
private function downloadImage($url)
|
||||
{
|
||||
$ch = curl_init();
|
||||
curl_setopt ($ch, CURLOPT_CUSTOMREQUEST, 'GET' );
|
||||
curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, false );
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
|
||||
$file = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
return $this->saveAsImage($url, $file);
|
||||
|
||||
}
|
||||
|
||||
//保存图片
|
||||
private function saveAsImage($url, $file)
|
||||
{
|
||||
$filename = pathinfo($url, PATHINFO_BASENAME);
|
||||
//$dirname = pathinfo(parse_url($url, PHP_URL_PATH), PATHINFO_DIRNAME);
|
||||
$dirname = date('Ymd',time());
|
||||
//路径
|
||||
$path = 'storage/' . $this->uid . '/article_pic/' . $dirname . '/';
|
||||
//绝对文件夹
|
||||
$fileDir = public_path() . $path;
|
||||
//文件绝对路径
|
||||
$filePath = $fileDir . $filename;
|
||||
//相对路径文件名
|
||||
$realFile = '/' . $path . $filename;
|
||||
// 如果目录不存在,则创建
|
||||
|
||||
if(!is_dir($fileDir)) {
|
||||
mkdir($fileDir, 0777, true);
|
||||
}
|
||||
|
||||
if(file_exists($filePath)) {
|
||||
//$this->output->writeln("【已存在】输出路径" . $fullpath);
|
||||
return $realFile;
|
||||
|
||||
} else {
|
||||
$resource = fopen($filePath, 'a');
|
||||
$res = fwrite($resource, $file);
|
||||
fclose($resource);
|
||||
if($res !== false) {
|
||||
return $realFile;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//下载网络图片到本地并替换
|
||||
public function downUrlPicsReaplace($content)
|
||||
{
|
||||
// 批量下载网络图片并替换
|
||||
$images = $this->getArticleAllpic($content);
|
||||
if(count($images)) {
|
||||
foreach($images as $image){
|
||||
//1.网络图片
|
||||
//halt((stripos($image, Request::domain()) === false));
|
||||
if((stripos($image,'http') !== false) && (stripos($image, Request::domain()) === false)) {
|
||||
|
||||
//2.下载远程图片
|
||||
$newImageUrl = $this->downloadImage($image);
|
||||
|
||||
$content = str_replace($image,Request::domain().$newImageUrl,$content);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -2,9 +2,9 @@
|
||||
/*
|
||||
* @Author: TaoLer <317927823@qq.com>
|
||||
* @Date: 2022-07-24 15:58:51
|
||||
* @LastEditTime: 2022-07-24 21:28:52
|
||||
* @LastEditTime: 2022-08-15 14:52:49
|
||||
* @LastEditors: TaoLer
|
||||
* @Description: Tag优化版
|
||||
* @Description: 标签
|
||||
* @FilePath: \TaoLer\app\index\controller\Tag.php
|
||||
* Copyright (c) 2020~2022 https://www.aieok.com All rights reserved.
|
||||
*/
|
||||
@ -12,12 +12,11 @@ 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;
|
||||
use app\common\model\Tag as TagModel;
|
||||
|
||||
class Tag extends BaseController
|
||||
{
|
||||
@ -31,10 +30,10 @@ class Tag extends BaseController
|
||||
public function List()
|
||||
{
|
||||
//
|
||||
$tag = Request::param('tag');
|
||||
|
||||
$artList = Article::getAllTags($tag);
|
||||
$tagEname = Request::param('ename');
|
||||
$tagId = Db::name('tag')->where('ename',$tagEname)->value('id');
|
||||
|
||||
$artList = Article::getAllTags($tagId);
|
||||
$slider = new Slider();
|
||||
//首页右栏
|
||||
$ad_comm = $slider->getSliderList(2);
|
||||
@ -42,7 +41,7 @@ class Tag extends BaseController
|
||||
$artHot = Article::getArtHot(10);
|
||||
|
||||
$assign = [
|
||||
'tag'=>$tag,
|
||||
'tag'=>$tagEname,
|
||||
'artList'=>$artList,
|
||||
'ad_comm'=>$ad_comm,
|
||||
'artHot'=>$artHot,
|
||||
@ -50,36 +49,36 @@ class Tag extends BaseController
|
||||
];
|
||||
View::assign($assign);
|
||||
return View::fetch('index');
|
||||
//halt($tag);
|
||||
}
|
||||
|
||||
//获取文章的tag
|
||||
public function getArtTag($tag)
|
||||
/**
|
||||
* 所有tag标签
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function getAllTag()
|
||||
{
|
||||
$data = [];
|
||||
$tagModel = new TagModel;
|
||||
$tags = $tagModel->getTagList();
|
||||
foreach($tags as $tag) {
|
||||
$data[] = ['name'=> $tag['name'], 'value'=> $tag['id']];
|
||||
}
|
||||
return json(['code'=>0,'data'=>$data]);
|
||||
}
|
||||
|
||||
public function getArticleTag($id)
|
||||
{
|
||||
//
|
||||
$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()
|
||||
{
|
||||
|
||||
$data = [];
|
||||
$artTags = Db::name('taglist')->where('article_id',$id)->select();
|
||||
// halt($artTags);
|
||||
foreach($artTags as $v) {
|
||||
$tag = Db::name('tag')->find($v['tag_id']);
|
||||
$data[] = ['name'=>$tag['name'],'value'=>$tag['id']];
|
||||
}
|
||||
// halt($data);
|
||||
return json(['code'=>0,'data'=>$data]);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -207,7 +207,7 @@ class User extends BaseController
|
||||
}
|
||||
|
||||
$article = new Article();
|
||||
$commont = new Comment();
|
||||
// $commont = new Comment();
|
||||
$arts = $article->getUserArtList((int) $id);
|
||||
|
||||
// $reys = $commont->getUserCommentList((int) $id);
|
||||
|
@ -2,10 +2,10 @@
|
||||
/*
|
||||
* @Author: TaoLer <alipey_tao@qq.com>
|
||||
* @Date: 2021-12-06 16:04:50
|
||||
* @LastEditTime: 2022-07-30 08:58:51
|
||||
* @LastEditTime: 2022-08-15 12:24:56
|
||||
* @LastEditors: TaoLer
|
||||
* @Description: 前端路由设置
|
||||
* @FilePath: \github\TaoLer\app\index\route\route.php
|
||||
* @FilePath: \TaoLer\app\index\route\route.php
|
||||
* Copyright (c) 2020~2022 https://www.aieok.com All rights reserved.
|
||||
*/
|
||||
use think\facade\Route;
|
||||
@ -21,7 +21,7 @@ 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::get('tag/:ename', 'Tag/list')->name('tag_list');
|
||||
// 用户中心
|
||||
Route::group(function () {
|
||||
Route::get('u/:id$', 'user/home')->name('user_home');
|
||||
@ -50,8 +50,6 @@ Route::group(function () {
|
||||
->middleware(\app\middleware\CheckRegister::class);
|
||||
});
|
||||
|
||||
|
||||
|
||||
// article
|
||||
Route::group('art',function () use($detail_as,$cate_as){
|
||||
Route::rule('add/[:cate]','Article/add')->name('add_article');
|
||||
@ -59,6 +57,11 @@ Route::group('art',function () use($detail_as,$cate_as){
|
||||
Route::rule('tags','Article/tags')->allowCrossDomain();
|
||||
Route::rule('edit/[:id]','Article/edit');
|
||||
});
|
||||
|
||||
//tag
|
||||
Route::get('tag','tag/getAllTag')->name('get_all_tag');
|
||||
Route::get('arttag','tag/getArticleTag')->name('get_art_tag');
|
||||
|
||||
Route::group(function () use($detail_as,$cate_as){
|
||||
// 动态路径路由会影响下面的路由,所以动态路由放下面
|
||||
Route::get($detail_as . ':id$', 'article/detail')->name('article_detail');
|
||||
|
@ -10,9 +10,7 @@
|
||||
// 检测环境是否支持可写
|
||||
//define('IS_WRITE', true);
|
||||
|
||||
use Think\Request;
|
||||
use think\facade\Session;
|
||||
use think\facade\Config;
|
||||
use think\facade\Env;
|
||||
|
||||
/**
|
||||
@ -51,12 +49,12 @@ function create_tables($db, $prefix = '')
|
||||
{
|
||||
// 导入sql数据表
|
||||
//$sql = file_get_contents('../app/install/data/taoler.sql');
|
||||
//$sql_array = preg_split("/;[\r\n]+/", $sql);
|
||||
$sql_array = load_sql_file('../app/install/data/taoler.sql'); //sql文件中sql语句转换为数组
|
||||
if ($sql_array) {
|
||||
if (count($sql_array)) {
|
||||
$orginal = 'tao_'; //sql表前缀
|
||||
($orginal==$prefix) ? true : $sql_array = str_replace(" `{$orginal}", " `{$prefix}", $sql_array); //替换数组中表前缀
|
||||
//$sql_array = preg_split("/;[\r\n]+/", $sql);
|
||||
|
||||
|
||||
//开始写入表
|
||||
foreach ($sql_array as $k => $v) {
|
||||
//halt($v);
|
||||
@ -176,7 +174,7 @@ function load_sql_file($path, $fn_splitor = ';;') {
|
||||
return false;
|
||||
}
|
||||
$lines = file($path, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
|
||||
$aout = false;
|
||||
$aout = [];
|
||||
$str = '';
|
||||
$skip = false;
|
||||
$fn = false;
|
||||
|
@ -65,7 +65,7 @@ CREATE TABLE `tao_article` (
|
||||
`jie` enum('1','0') NOT NULL DEFAULT '0' COMMENT '0未结1已结',
|
||||
`upzip` varchar(70) DEFAULT NULL COMMENT '文章附件',
|
||||
`downloads` int(5) NOT NULL DEFAULT '0' COMMENT '下载量',
|
||||
`tags` varchar(255) DEFAULT NULL COMMENT 'tag',
|
||||
`keywords` varchar(255) DEFAULT NULL COMMENT '关键词',
|
||||
`description` text NOT NULL COMMENT 'seo描述',
|
||||
`read_type` tinyint(1) NOT NULL DEFAULT '0' COMMENT '阅读权限0开放1回复可读2密码可读3私密',
|
||||
`art_pass` varchar(6) DEFAULT NULL COMMENT '文章加密密码',
|
||||
@ -77,7 +77,7 @@ CREATE TABLE `tao_article` (
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `user_id` (`user_id`) USING BTREE COMMENT '文章的用户索引',
|
||||
KEY `cate_id` (`cate_id`) USING BTREE COMMENT '文章分类索引'
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='文章表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of tao_article
|
||||
@ -98,7 +98,7 @@ CREATE TABLE `tao_auth_group` (
|
||||
`update_time` int(11) NOT NULL DEFAULT '0' COMMENT '更新时间',
|
||||
`delete_time` int(11) NOT NULL DEFAULT '0' COMMENT '删除时间',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 COMMENT='用户组权限表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of tao_auth_group
|
||||
@ -124,7 +124,7 @@ CREATE TABLE `tao_auth_group_access` (
|
||||
KEY `uid` (`uid`),
|
||||
KEY `group_id` (`group_id`),
|
||||
KEY `uid_group_id` (`uid`,`group_id`) USING BTREE
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 COMMENT='用户组明细表';
|
||||
|
||||
|
||||
-- ----------------------------
|
||||
@ -142,7 +142,7 @@ CREATE TABLE `tao_auth_group_copy` (
|
||||
`update_time` int(11) NOT NULL DEFAULT '0' COMMENT '更新时间',
|
||||
`delete_time` int(11) NOT NULL DEFAULT '0' COMMENT '删除时间',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 COMMENT='用户角色表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of tao_auth_group_copy
|
||||
@ -174,7 +174,7 @@ CREATE TABLE `tao_auth_rule` (
|
||||
`delete_time` int(11) NOT NULL DEFAULT '0' COMMENT '删除时间',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `name` (`name`)
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=97 DEFAULT CHARSET=utf8;
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=97 DEFAULT CHARSET=utf8 COMMENT='权限表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of tao_auth_rule
|
||||
@ -267,7 +267,7 @@ INSERT INTO `tao_auth_rule` VALUES ('97', 'addons', '插件', '', '1', '1', '0',
|
||||
INSERT INTO `tao_auth_rule` VALUES ('98', 'Addons/index', '插件市场', '', '1', '1', '97', '1', '', '1', '0', '', '1635757426', '0', '0');
|
||||
INSERT INTO `tao_auth_rule` VALUES ('99', 'Addons/addonsList', '插件列表', '', '1', '1', '98', '2', '', '-1', '0', '', '1638775199', '0', '0');
|
||||
INSERT INTO `tao_auth_rule` VALUES ('111','Seo/index','SEO', '', '1','1','0','0','layui-icon-component','1','7','','1649829142','0','0');
|
||||
INSERT INTO `tao_auth_rule` VALUES ('112', 'TagLink/index', 'TagLinks', '', '1', '1', '93', '1', '', '1', '0', '', '1652053762', '1652053830', '0');
|
||||
INSERT INTO `tao_auth_rule` VALUES ('112', 'Tag/index', 'Tag设置', '', '1', '1', '5', '1', '', '1', '16', '', '1652053762', '1652053830', '0');
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for tao_cate
|
||||
@ -289,7 +289,7 @@ CREATE TABLE `tao_cate` (
|
||||
`delete_time` int(11) NOT NULL DEFAULT '0' COMMENT '删除时间',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `ename` (`ename`) COMMENT '英文名称索引'
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COMMENT='分类表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of tao_cate
|
||||
@ -319,7 +319,7 @@ CREATE TABLE `tao_collection` (
|
||||
DROP TABLE IF EXISTS `tao_comment`;
|
||||
CREATE TABLE `tao_comment` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '评论id',
|
||||
`content` text NOT NULL COMMENT '评论',
|
||||
`content` text COLLATE utf8mb4_general_ci NOT NULL COMMENT '评论',
|
||||
`article_id` int(11) NOT NULL COMMENT '文章id',
|
||||
`user_id` int(11) NOT NULL COMMENT '评论用户',
|
||||
`zan` tinyint(4) NOT NULL DEFAULT '0' COMMENT '赞',
|
||||
@ -331,7 +331,7 @@ CREATE TABLE `tao_comment` (
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `aiticle_id` (`article_id`) USING BTREE COMMENT '文章评论索引',
|
||||
KEY `user_id` (`user_id`) USING BTREE COMMENT '评论用户索引'
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='评论表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of tao_comment
|
||||
@ -351,7 +351,7 @@ CREATE TABLE `tao_cunsult` (
|
||||
`create_time` int(10) NOT NULL DEFAULT '0' COMMENT '创建时间',
|
||||
`delete_time` int(10) NOT NULL DEFAULT '0' COMMENT '删除时间',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='反馈表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for tao_friend_link
|
||||
@ -366,7 +366,7 @@ CREATE TABLE `tao_friend_link` (
|
||||
`update_time` int(10) NOT NULL COMMENT '更新时间',
|
||||
`delete_time` int(10) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COMMENT='友情链接';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of tao_friend_link
|
||||
@ -389,7 +389,7 @@ CREATE TABLE `tao_mail_server` (
|
||||
`active` tinyint(1) NOT NULL DEFAULT '0' COMMENT '邮箱服务1激活0未激活',
|
||||
`create_time` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='邮件服务器配置表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of tao_mail_server
|
||||
@ -411,11 +411,8 @@ CREATE TABLE `tao_message` (
|
||||
`update_time` int(11) NOT NULL DEFAULT '0' COMMENT '更新时间',
|
||||
`delete_time` int(11) NOT NULL DEFAULT '0' COMMENT '删除时间',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='消息表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of tao_message
|
||||
-- ----------------------------
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for tao_message_to
|
||||
@ -432,20 +429,17 @@ CREATE TABLE `tao_message_to` (
|
||||
`update_time` int(11) NOT NULL DEFAULT '0' COMMENT '更新时间',
|
||||
`delete_time` int(11) NOT NULL DEFAULT '0' COMMENT '删除时间',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of tao_message_to
|
||||
-- ----------------------------
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='消息详细表';
|
||||
|
||||
--
|
||||
-- 表的结构 `tao_push_jscode`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `tao_push_jscode`;
|
||||
CREATE TABLE `tao_push_jscode` (
|
||||
`id` int(2) NOT NULL AUTO_INCREMENT COMMENT '自增ID',
|
||||
`name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '平台名',
|
||||
`jscode` text CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 'js代码',
|
||||
`type` tinyint(1) NOT NULL DEFAULT '1' COMMENT '1push2taglink',
|
||||
`create_time` int NOT NULL DEFAULT '0' COMMENT '创建时间',
|
||||
`update_time` int NOT NULL DEFAULT '0' COMMENT '更新时间',
|
||||
`delete_time` int NOT NULL DEFAULT '0' COMMENT '删除时间',
|
||||
@ -470,13 +464,13 @@ CREATE TABLE `tao_slider` (
|
||||
`update_time` int(11) NOT NULL DEFAULT '0' COMMENT '更新时间',
|
||||
`delete_time` int(11) NOT NULL DEFAULT '0' COMMENT '删除时间',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of tao_slider
|
||||
-- ----------------------------
|
||||
INSERT INTO `tao_slider` VALUES ('1', 'CODING', '1', '/storage/slider/F1.jpg', '#', '', '1574870400', '1575043200', '1', '0', '0', '0');
|
||||
INSERT INTO `tao_slider` VALUES ('3', '通用右栏底部广告', '2', '/storage/slider/20200101/851c0b88a72590293bcb45454bdce056.jpg', 'https://www.aieok.com', '', '1571155200', '1609344000', '1', '0', '0', '0');
|
||||
INSERT INTO `tao_slider` VALUES ('2', '通用右栏底部广告', '2', '/storage/slider/20200101/851c0b88a72590293bcb45454bdce056.jpg', 'https://www.aieok.com', '', '1571155200', '1609344000', '1', '0', '0', '0');
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for tao_system
|
||||
@ -520,6 +514,28 @@ CREATE TABLE `tao_system` (
|
||||
-- ----------------------------
|
||||
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);
|
||||
|
||||
DROP TABLE IF EXISTS `tao_tag`;
|
||||
CREATE TABLE `tao_tag` (
|
||||
`id` int(10) NOT NULL AUTO_INCREMENT COMMENT 'tag自增id',
|
||||
`name` varchar(20) NOT NULL COMMENT '名称',
|
||||
`ename` varchar(20) NOT NULL COMMENT '英文名',
|
||||
`create_time` int NOT NULL COMMENT '创建时间',
|
||||
`update_time` int NOT NULL COMMENT '更新时间',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `ename` (`ename`) USING BTREE COMMENT 'ename查询tag索引'
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='文章tag表';
|
||||
|
||||
DROP TABLE IF EXISTS `tao_taglist`;
|
||||
CREATE TABLE `tao_taglist` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '标签列表id',
|
||||
`tag_id` int NOT NULL COMMENT '标签id',
|
||||
`article_id` int NOT NULL COMMENT '文章id',
|
||||
`create_time` int NOT NULL COMMENT '创建时间',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `tag_id` (`tag_id`) USING BTREE COMMENT 'tagID索引',
|
||||
KEY `article_id` (`article_id`) USING BTREE COMMENT '文章ID查询索引'
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='tag详细列表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for tao_user
|
||||
-- ----------------------------
|
||||
|
@ -33,7 +33,6 @@
|
||||
"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",
|
||||
|
75
composer.lock
generated
75
composer.lock
generated
@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "8e024ab98b5bfe9d89eb50e675b21b20",
|
||||
"content-hash": "ae8b0fc745366cac28cf9550ec737472",
|
||||
"packages": [
|
||||
{
|
||||
"name": "bacon/bacon-qr-code",
|
||||
@ -894,79 +894,6 @@
|
||||
},
|
||||
"time": "2022-06-18T12:21:57+00:00"
|
||||
},
|
||||
{
|
||||
"name": "overtrue/pinyin",
|
||||
"version": "4.0.8",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/overtrue/pinyin.git",
|
||||
"reference": "04bdb4d33d50e8fb1aa5a824064c5151c4b15dc2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/overtrue/pinyin/zipball/04bdb4d33d50e8fb1aa5a824064c5151c4b15dc2",
|
||||
"reference": "04bdb4d33d50e8fb1aa5a824064c5151c4b15dc2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"brainmaestro/composer-git-hooks": "^2.7",
|
||||
"friendsofphp/php-cs-fixer": "^2.16",
|
||||
"phpunit/phpunit": "~8.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"hooks": {
|
||||
"pre-commit": [
|
||||
"composer test",
|
||||
"composer fix-style"
|
||||
],
|
||||
"pre-push": [
|
||||
"composer test",
|
||||
"composer check-style"
|
||||
]
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/const.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Overtrue\\Pinyin\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "overtrue",
|
||||
"email": "anzhengchao@gmail.com",
|
||||
"homepage": "http://github.com/overtrue"
|
||||
}
|
||||
],
|
||||
"description": "Chinese to pinyin translator.",
|
||||
"homepage": "https://github.com/overtrue/pinyin",
|
||||
"keywords": [
|
||||
"Chinese",
|
||||
"Pinyin",
|
||||
"cn2pinyin"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/overtrue/pinyin/issues",
|
||||
"source": "https://github.com/overtrue/pinyin/tree/4.0.8"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://www.patreon.com/overtrue",
|
||||
"type": "patreon"
|
||||
}
|
||||
],
|
||||
"time": "2021-07-19T03:43:32+00:00"
|
||||
},
|
||||
{
|
||||
"name": "php-di/invoker",
|
||||
"version": "2.3.3",
|
||||
|
@ -1,5 +0,0 @@
|
||||
<?php
|
||||
return [
|
||||
'一个' => 'http://www.bi.com',
|
||||
'描述' => 'http://ww.com',
|
||||
];
|
@ -16,7 +16,7 @@ return [
|
||||
// 应用名,此项不可更改
|
||||
'appname' => 'TaoLer',
|
||||
// 版本配置
|
||||
'version' => '1.9.22',
|
||||
'version' => '1.9.23',
|
||||
// 加盐
|
||||
'salt' => 'taoler',
|
||||
// 数据库备份目录
|
||||
|
@ -1,662 +0,0 @@
|
||||
<?php
|
||||
namespace AngularFilemanager\LocalBridge;
|
||||
|
||||
use AngularFilemanager\LocalBridge\Translate;
|
||||
|
||||
/**
|
||||
* File Manager API Class
|
||||
*
|
||||
* Made for PHP Local filesystem bridge for angular-filemanager to handle file manipulations
|
||||
* @author Jakub Ďuraš <jakub@duras.me>
|
||||
*/
|
||||
class FileManagerApi
|
||||
{
|
||||
private $basePath = null;
|
||||
|
||||
private $translate;
|
||||
|
||||
public function __construct($basePath = null, $lang = 'en', $muteErrors = true)
|
||||
{
|
||||
if ($muteErrors) {
|
||||
ini_set('display_errors', 0);
|
||||
}
|
||||
|
||||
$this->basePath = $basePath ?: dirname(__DIR__);
|
||||
$this->translate = new Translate($lang);
|
||||
}
|
||||
|
||||
public function postHandler($query, $request, $files)
|
||||
{
|
||||
$t = $this->translate;
|
||||
|
||||
// Probably file upload
|
||||
if (!isset($request['action'])
|
||||
&& (isset($_SERVER["CONTENT_TYPE"])
|
||||
&& strpos($_SERVER["CONTENT_TYPE"], 'multipart/form-data') !== false)
|
||||
) {
|
||||
$uploaded = $this->uploadAction($request['destination'], $files);
|
||||
if ($uploaded === true) {
|
||||
$response = $this->simpleSuccessResponse();
|
||||
} else {
|
||||
$response = $this->simpleErrorResponse($t->upload_failed);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
switch ($request['action']) {
|
||||
case 'list':
|
||||
$list = $this->listAction($request['path']);
|
||||
|
||||
if (!is_array($list)) {
|
||||
$response = $this->simpleErrorResponse($t->listing_failed);
|
||||
} else {
|
||||
$response = new Response();
|
||||
$response->setData([
|
||||
'result' => $list
|
||||
]);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'rename':
|
||||
$renamed = $this->renameAction($request['item'], $request['newItemPath']);
|
||||
if ($renamed === true) {
|
||||
$response = $this->simpleSuccessResponse();
|
||||
} elseif ($renamed === 'notfound') {
|
||||
$response = $this->simpleErrorResponse($t->file_not_found);
|
||||
} else {
|
||||
$response = $this->simpleErrorResponse($t->renaming_failed);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'move':
|
||||
$moved = $this->moveAction($request['items'], $request['newPath']);
|
||||
if ($moved === true) {
|
||||
$response = $this->simpleSuccessResponse();
|
||||
} else {
|
||||
$response = $this->simpleErrorResponse($t->moving_failed);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'copy':
|
||||
$copied = $this->copyAction($request['items'], $request['newPath']);
|
||||
if ($copied === true) {
|
||||
$response = $this->simpleSuccessResponse();
|
||||
} else {
|
||||
$response = $this->simpleErrorResponse($t->copying_failed);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'remove':
|
||||
$removed = $this->removeAction($request['items']);
|
||||
if ($removed === true) {
|
||||
$response = $this->simpleSuccessResponse();
|
||||
} elseif ($removed === 'notempty') {
|
||||
$response = $this->simpleErrorResponse($t->removing_failed_directory_not_empty);
|
||||
} else {
|
||||
$response = $this->simpleErrorResponse($t->removing_failed);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'edit':
|
||||
$edited = $this->editAction($request['item'], $request['content']);
|
||||
if ($edited !== false) {
|
||||
$response = $this->simpleSuccessResponse();
|
||||
} else {
|
||||
$response = $this->simpleErrorResponse($t->saving_failed);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'getContent':
|
||||
$content = $this->getContentAction($request['item']);
|
||||
if ($content !== false) {
|
||||
$response = new Response();
|
||||
$response->setData([
|
||||
'result' => $content
|
||||
]);
|
||||
} else {
|
||||
$response = $this->simpleErrorResponse($t->file_not_found);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'createFolder':
|
||||
$created = $this->createFolderAction($request['newPath']);
|
||||
if ($created === true) {
|
||||
$response = $this->simpleSuccessResponse();
|
||||
} elseif ($created === 'exists') {
|
||||
$response = $this->simpleErrorResponse($t->folder_already_exists);
|
||||
} else {
|
||||
$response = $this->simpleErrorResponse($t->folder_creation_failed);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'changePermissions':
|
||||
$changed = $this->changePermissionsAction($request['items'], $request['perms'], $request['recursive']);
|
||||
if ($changed === true) {
|
||||
$response = $this->simpleSuccessResponse();
|
||||
} elseif ($changed === 'missing') {
|
||||
$response = $this->simpleErrorResponse($t->file_not_found);
|
||||
} else {
|
||||
$response = $this->simpleErrorResponse($t->permissions_change_failed);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'compress':
|
||||
$compressed = $this->compressAction(
|
||||
$request['items'],
|
||||
$request['destination'],
|
||||
$request['compressedFilename']
|
||||
);
|
||||
if ($compressed === true) {
|
||||
$response = $this->simpleSuccessResponse();
|
||||
} else {
|
||||
$response = $this->simpleErrorResponse($t->compression_failed);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'extract':
|
||||
$extracted = $this->extractAction($request['destination'], $request['item'], $request['folderName']);
|
||||
if ($extracted === true) {
|
||||
$response = $this->simpleSuccessResponse();
|
||||
} elseif ($extracted === 'unsupported') {
|
||||
$response = $this->simpleErrorResponse($t->archive_opening_failed);
|
||||
} else {
|
||||
$response = $this->simpleErrorResponse($t->extraction_failed);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
$response = $this->simpleErrorResponse($t->function_not_implemented);
|
||||
break;
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
public function getHandler($queries)
|
||||
{
|
||||
$t = $this->translate;
|
||||
|
||||
switch ($queries['action']) {
|
||||
case 'download':
|
||||
$downloaded = $this->downloadAction($queries['path']);
|
||||
if ($downloaded === true) {
|
||||
exit;
|
||||
} else {
|
||||
$response = $this->simpleErrorResponse($t->file_not_found);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'downloadMultiple':
|
||||
$downloaded = $this->downloadMultipleAction($queries['items'], $queries['toFilename']);
|
||||
if ($downloaded === true) {
|
||||
exit;
|
||||
} else {
|
||||
$response = $this->simpleErrorResponse($t->file_not_found);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
$response = $this->simpleErrorResponse($t->function_not_implemented);
|
||||
break;
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
private function downloadAction($path)
|
||||
{
|
||||
$file_name = basename($path);
|
||||
$path = $this->canonicalizePath($this->basePath . $path);
|
||||
|
||||
if (!file_exists($path)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$finfo = finfo_open(FILEINFO_MIME_TYPE);
|
||||
$mime_type = finfo_file($finfo, $path);
|
||||
finfo_close($finfo);
|
||||
|
||||
if (ob_get_level()) {
|
||||
ob_end_clean();
|
||||
}
|
||||
|
||||
header("Content-Disposition: attachment; filename=\"$file_name\"");
|
||||
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
|
||||
header("Content-Type: $mime_type");
|
||||
header('Pragma: public');
|
||||
header('Content-Length: ' . filesize($path));
|
||||
readfile($path);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function downloadMultipleAction($items, $archiveName)
|
||||
{
|
||||
$archivePath = tempnam('../', 'archive');
|
||||
|
||||
$zip = new \ZipArchive();
|
||||
if ($zip->open($archivePath, \ZipArchive::CREATE) !== true) {
|
||||
unlink($archivePath);
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($items as $path) {
|
||||
$zip->addFile($this->basePath . $path, basename($path));
|
||||
}
|
||||
|
||||
$zip->close();
|
||||
|
||||
header("Content-Disposition: attachment; filename=\"$archiveName\"");
|
||||
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
|
||||
header("Content-Type: application/zip");
|
||||
header('Pragma: public');
|
||||
header('Content-Length: ' . filesize($archivePath));
|
||||
readfile($archivePath);
|
||||
|
||||
unlink($archivePath);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function uploadAction($path, $files)
|
||||
{
|
||||
$path = $this->canonicalizePath($this->basePath . $path);
|
||||
|
||||
foreach ($_FILES as $file) {
|
||||
$fileInfo = pathinfo($file['name']);
|
||||
$fileName = $this->normalizeName($fileInfo['filename']) . '.' . $fileInfo['extension'];
|
||||
|
||||
$uploaded = move_uploaded_file(
|
||||
$file['tmp_name'],
|
||||
$path . DIRECTORY_SEPARATOR . $fileName
|
||||
);
|
||||
if ($uploaded === false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function listAction($path)
|
||||
{
|
||||
$files = array_values(array_filter(
|
||||
scandir($this->basePath . $path),
|
||||
function ($path) {
|
||||
return !($path === '.' || $path === '..');
|
||||
}
|
||||
));
|
||||
|
||||
$files = array_map(function ($file) use ($path) {
|
||||
$file = $this->canonicalizePath(
|
||||
$this->basePath . $path . DIRECTORY_SEPARATOR . $file
|
||||
);
|
||||
$date = new \DateTime('@' . filemtime($file));
|
||||
|
||||
return [
|
||||
'name' => basename($file),
|
||||
'rights' => $this->parsePerms(fileperms($file)),
|
||||
'size' => filesize($file),
|
||||
'date' => $date->format('Y-m-d H:i:s'),
|
||||
'type' => is_dir($file) ? 'dir' : 'file'
|
||||
];
|
||||
}, $files);
|
||||
|
||||
return $files;
|
||||
}
|
||||
|
||||
public function listActionData($path)
|
||||
{
|
||||
$files = array_values(array_filter(
|
||||
scandir($this->basePath . $path),
|
||||
function ($path) {
|
||||
return !($path === '.' || $path === '..');
|
||||
}
|
||||
));
|
||||
|
||||
$files = array_map(function ($file) use ($path) {
|
||||
$file = $this->canonicalizePath(
|
||||
$this->basePath . $path . DIRECTORY_SEPARATOR . $file
|
||||
);
|
||||
$date = new \DateTime('@' . filemtime($file));
|
||||
|
||||
return [
|
||||
'name' => basename($file),
|
||||
'rights' => $this->parsePerms(fileperms($file)),
|
||||
'size' => filesize($file),
|
||||
'date' => $date->format('Y-m-d H:i:s'),
|
||||
'type' => is_dir($file) ? 'dir' : 'file'
|
||||
];
|
||||
}, $files);
|
||||
|
||||
return $files;
|
||||
}
|
||||
|
||||
private function renameAction($oldPath, $newPath)
|
||||
{
|
||||
$oldPath = $this->basePath . $oldPath;
|
||||
$newPath = $this->basePath . $newPath;
|
||||
|
||||
if (! file_exists($oldPath)) {
|
||||
return 'notfound';
|
||||
}
|
||||
|
||||
return rename($oldPath, $newPath);
|
||||
}
|
||||
|
||||
private function moveAction($oldPaths, $newPath)
|
||||
{
|
||||
$newPath = $this->basePath . $this->canonicalizePath($newPath) . DIRECTORY_SEPARATOR;
|
||||
|
||||
foreach ($oldPaths as $oldPath) {
|
||||
if (!file_exists($this->basePath . $oldPath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$renamed = rename($this->basePath . $oldPath, $newPath . basename($oldPath));
|
||||
if ($renamed === false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function copyAction($oldPaths, $newPath)
|
||||
{
|
||||
$newPath = $this->basePath . $this->canonicalizePath($newPath) . DIRECTORY_SEPARATOR;
|
||||
|
||||
foreach ($oldPaths as $oldPath) {
|
||||
if (!file_exists($this->basePath . $oldPath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$copied = copy(
|
||||
$this->basePath . $oldPath,
|
||||
$newPath . basename($oldPath)
|
||||
);
|
||||
if ($copied === false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function removeAction($paths)
|
||||
{
|
||||
foreach ($paths as $path) {
|
||||
$path = $this->canonicalizePath($this->basePath . $path);
|
||||
|
||||
if (is_dir($path)) {
|
||||
$dirEmpty = (new \FilesystemIterator($path))->valid();
|
||||
|
||||
if ($dirEmpty) {
|
||||
return 'notempty';
|
||||
} else {
|
||||
$removed = rmdir($path);
|
||||
}
|
||||
} else {
|
||||
$removed = unlink($path);
|
||||
}
|
||||
|
||||
if ($removed === false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function editAction($path, $content)
|
||||
{
|
||||
$path = $this->basePath . $path;
|
||||
return file_put_contents($path, $content);
|
||||
}
|
||||
|
||||
private function getContentAction($path)
|
||||
{
|
||||
$path = $this->basePath . $path;
|
||||
|
||||
if (! file_exists($path)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return file_get_contents($path);
|
||||
}
|
||||
|
||||
private function createFolderAction($path)
|
||||
{
|
||||
$path = $this->basePath . $path;
|
||||
|
||||
if (file_exists($path) && is_dir($path)) {
|
||||
return 'exists';
|
||||
}
|
||||
|
||||
return mkdir($path);
|
||||
}
|
||||
|
||||
private function changePermissionsAction($paths, $permissions, $recursive)
|
||||
{
|
||||
foreach ($paths as $path) {
|
||||
if (!file_exists($this->basePath . $path)) {
|
||||
return 'missing';
|
||||
}
|
||||
|
||||
if (is_dir($path) && $recursive === true) {
|
||||
$iterator = new RecursiveIteratorIterator(
|
||||
new RecursiveDirectoryIterator($path),
|
||||
RecursiveIteratorIterator::SELF_FIRST
|
||||
);
|
||||
|
||||
foreach ($iterator as $item) {
|
||||
$changed = chmod($this->basePath . $item, octdec($permissions));
|
||||
|
||||
if ($changed === false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return chmod($this->basePath . $path, octdec($permissions));
|
||||
}
|
||||
}
|
||||
|
||||
private function compressAction($paths, $destination, $archiveName)
|
||||
{
|
||||
$archivePath = $this->basePath . $destination . $archiveName;
|
||||
|
||||
$zip = new \ZipArchive();
|
||||
if ($zip->open($archivePath, \ZipArchive::CREATE) !== true) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($paths as $path) {
|
||||
$fullPath = $this->basePath . $path;
|
||||
|
||||
if (is_dir($fullPath)) {
|
||||
$dirs = [
|
||||
[
|
||||
'dir' => basename($path),
|
||||
'path' => $this->canonicalizePath($this->basePath . $path),
|
||||
]
|
||||
];
|
||||
|
||||
while (count($dirs)) {
|
||||
$dir = current($dirs);
|
||||
$zip->addEmptyDir($dir['dir']);
|
||||
|
||||
$dh = opendir($dir['path']);
|
||||
while ($file = readdir($dh)) {
|
||||
if ($file != '.' && $file != '..') {
|
||||
$filePath = $dir['path'] . DIRECTORY_SEPARATOR . $file;
|
||||
if (is_file($filePath)) {
|
||||
$zip->addFile(
|
||||
$dir['path'] . DIRECTORY_SEPARATOR . $file,
|
||||
$dir['dir'] . '/' . basename($file)
|
||||
);
|
||||
} elseif (is_dir($filePath)) {
|
||||
$dirs[] = [
|
||||
'dir' => $dir['dir'] . '/' . $file,
|
||||
'path' => $dir['path'] . DIRECTORY_SEPARATOR . $file
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir($dh);
|
||||
array_shift($dirs);
|
||||
}
|
||||
} else {
|
||||
$zip->addFile($path, basename($path));
|
||||
}
|
||||
}
|
||||
|
||||
return $zip->close();
|
||||
}
|
||||
|
||||
private function extractAction($destination, $archivePath, $folderName)
|
||||
{
|
||||
$archivePath = $this->basePath . $archivePath;
|
||||
$folderPath = $this->basePath . $this->canonicalizePath($destination) . DIRECTORY_SEPARATOR . $folderName;
|
||||
|
||||
$zip = new \ZipArchive;
|
||||
if ($zip->open($archivePath) === false) {
|
||||
return 'unsupported';
|
||||
}
|
||||
|
||||
mkdir($folderPath);
|
||||
$zip->extractTo($folderPath);
|
||||
return $zip->close();
|
||||
}
|
||||
|
||||
private function simpleSuccessResponse()
|
||||
{
|
||||
$response = new Response();
|
||||
$response->setData([
|
||||
'result' => [
|
||||
'success' => true
|
||||
]
|
||||
]);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
private function simpleErrorResponse($message)
|
||||
{
|
||||
$response = new Response();
|
||||
$response
|
||||
->setStatus(500, 'Internal Server Error')
|
||||
->setData([
|
||||
'result' => [
|
||||
'success' => false,
|
||||
'error' => $message
|
||||
]
|
||||
]);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
private function parsePerms($perms)
|
||||
{
|
||||
if (($perms & 0xC000) == 0xC000) {
|
||||
// Socket
|
||||
$info = 's';
|
||||
} elseif (($perms & 0xA000) == 0xA000) {
|
||||
// Symbolic Link
|
||||
$info = 'l';
|
||||
} elseif (($perms & 0x8000) == 0x8000) {
|
||||
// Regular
|
||||
$info = '-';
|
||||
} elseif (($perms & 0x6000) == 0x6000) {
|
||||
// Block special
|
||||
$info = 'b';
|
||||
} elseif (($perms & 0x4000) == 0x4000) {
|
||||
// Directory
|
||||
$info = 'd';
|
||||
} elseif (($perms & 0x2000) == 0x2000) {
|
||||
// Character special
|
||||
$info = 'c';
|
||||
} elseif (($perms & 0x1000) == 0x1000) {
|
||||
// FIFO pipe
|
||||
$info = 'p';
|
||||
} else {
|
||||
// Unknown
|
||||
$info = 'u';
|
||||
}
|
||||
|
||||
// Owner
|
||||
$info .= (($perms & 0x0100) ? 'r' : '-');
|
||||
$info .= (($perms & 0x0080) ? 'w' : '-');
|
||||
$info .= (($perms & 0x0040) ?
|
||||
(($perms & 0x0800) ? 's' : 'x' ) :
|
||||
(($perms & 0x0800) ? 'S' : '-'));
|
||||
|
||||
// Group
|
||||
$info .= (($perms & 0x0020) ? 'r' : '-');
|
||||
$info .= (($perms & 0x0010) ? 'w' : '-');
|
||||
$info .= (($perms & 0x0008) ?
|
||||
(($perms & 0x0400) ? 's' : 'x' ) :
|
||||
(($perms & 0x0400) ? 'S' : '-'));
|
||||
|
||||
// World
|
||||
$info .= (($perms & 0x0004) ? 'r' : '-');
|
||||
$info .= (($perms & 0x0002) ? 'w' : '-');
|
||||
$info .= (($perms & 0x0001) ?
|
||||
(($perms & 0x0200) ? 't' : 'x' ) :
|
||||
(($perms & 0x0200) ? 'T' : '-'));
|
||||
|
||||
return $info;
|
||||
}
|
||||
|
||||
private function canonicalizePath($path)
|
||||
{
|
||||
$dirSep = DIRECTORY_SEPARATOR;
|
||||
$wrongDirSep = DIRECTORY_SEPARATOR === '/' ? '\\' : '/';
|
||||
|
||||
// Replace incorrect dir separators
|
||||
$path = str_replace($wrongDirSep, $dirSep, $path);
|
||||
|
||||
$path = explode($dirSep, $path);
|
||||
$stack = array();
|
||||
foreach ($path as $seg) {
|
||||
if ($seg == '..') {
|
||||
// Ignore this segment, remove last segment from stack
|
||||
array_pop($stack);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($seg == '.') {
|
||||
// Ignore this segment
|
||||
continue;
|
||||
}
|
||||
|
||||
$stack[] = $seg;
|
||||
}
|
||||
|
||||
// Remove last /
|
||||
if (empty($stack[count($stack) - 1])) {
|
||||
array_pop($stack);
|
||||
}
|
||||
|
||||
return implode($dirSep, $stack);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates ASCII name
|
||||
*
|
||||
* @param string name encoded in UTF-8
|
||||
* @return string name containing only numbers, chars without diacritics, underscore and dash
|
||||
* @copyright Jakub Vrána, https://php.vrana.cz/
|
||||
*/
|
||||
private function normalizeName($name)
|
||||
{
|
||||
$name = preg_replace('~[^\\pL0-9_]+~u', '-', $name);
|
||||
$name = trim($name, "-");
|
||||
//$name = iconv("utf-8", "us-ascii//TRANSLIT", $name);
|
||||
$name = preg_replace('~[^-a-z0-9_]+~', '', $name);
|
||||
return $name;
|
||||
}
|
||||
}
|
Binary file not shown.
Before Width: | Height: | Size: 303 KiB |
Binary file not shown.
Before Width: | Height: | Size: 87 KiB |
@ -1,76 +0,0 @@
|
||||
(function(angular) {
|
||||
'use strict';
|
||||
angular.module('FileManagerApp').provider('fileManagerConfig', function() {
|
||||
|
||||
var values = {
|
||||
appName: 'angular-filemanager v1.5',
|
||||
defaultLang: 'zh_cn',
|
||||
multiLang: true,
|
||||
|
||||
listUrl: '/FileManager/handler',
|
||||
uploadUrl: '/FileManager/handler/',
|
||||
renameUrl: '/FileManager/handler/',
|
||||
copyUrl: '/FileManager/handler/',
|
||||
moveUrl: '/FileManager/handler/',
|
||||
removeUrl: '/FileManager/handle/r',
|
||||
editUrl: '/FileManager/handler/',
|
||||
getContentUrl: '/FileManager/handler/',
|
||||
createFolderUrl: '/FileManager/handler/',
|
||||
downloadFileUrl: '/FileManager/handler/',
|
||||
downloadMultipleUrl: '/FileManager/handler/',
|
||||
compressUrl: '/FileManager/handler/',
|
||||
extractUrl: '/FileManager/handler/',
|
||||
permissionsUrl: '/FileManager/handler/',
|
||||
basePath: '/',
|
||||
|
||||
searchForm: true,
|
||||
sidebar: true,
|
||||
breadcrumb: true,
|
||||
allowedActions: {
|
||||
upload: true,
|
||||
rename: true,
|
||||
move: true,
|
||||
copy: true,
|
||||
edit: true,
|
||||
changePermissions: true,
|
||||
compress: true,
|
||||
compressChooseName: true,
|
||||
extract: true,
|
||||
download: true,
|
||||
downloadMultiple: true,
|
||||
preview: true,
|
||||
remove: true,
|
||||
createFolder: true,
|
||||
pickFiles: false,
|
||||
pickFolders: false
|
||||
},
|
||||
|
||||
multipleDownloadFileName: 'angular-filemanager.zip',
|
||||
filterFileExtensions: [],
|
||||
showExtensionIcons: true,
|
||||
showSizeForDirectories: false,
|
||||
useBinarySizePrefixes: false,
|
||||
downloadFilesByAjax: true,
|
||||
previewImagesInModal: true,
|
||||
enablePermissionsRecursive: true,
|
||||
compressAsync: false,
|
||||
extractAsync: false,
|
||||
pickCallback: null,
|
||||
|
||||
isEditableFilePattern: /\.(txt|diff?|patch|svg|asc|cnf|cfg|conf|html?|.html|cfm|cgi|aspx?|ini|pl|py|md|css|cs|js|jsp|log|htaccess|htpasswd|gitignore|gitattributes|env|json|atom|eml|rss|markdown|sql|xml|xslt?|sh|rb|as|bat|cmd|cob|for|ftn|frm|frx|inc|lisp|scm|coffee|php[3-6]?|java|c|cbl|go|h|scala|vb|tmpl|lock|go|yml|yaml|tsv|lst)$/i,
|
||||
isImageFilePattern: /\.(jpe?g|gif|bmp|png|svg|tiff?)$/i,
|
||||
isExtractableFilePattern: /\.(gz|tar|rar|g?zip)$/i,
|
||||
tplPath: '/file/src/templates'
|
||||
};
|
||||
|
||||
return {
|
||||
$get: function() {
|
||||
return values;
|
||||
},
|
||||
set: function (constants) {
|
||||
angular.extend(values, constants);
|
||||
}
|
||||
};
|
||||
|
||||
});
|
||||
})(angular);
|
@ -1,18 +0,0 @@
|
||||
{
|
||||
"function_not_implemented": "Funktion nicht implementiert",
|
||||
"file_not_found": "Datei nicht gefunden",
|
||||
"listing_failed": "Auflistung fehlgeschlagen",
|
||||
"moving_failed": "Verschiebung fehlgeschlagen",
|
||||
"renaming_failed": "Umbenennung fehlgeschlagen",
|
||||
"copying_failed": "Kopieren fehlgeschlagen",
|
||||
"removing_failed": "Löschen fehlgeschlagen",
|
||||
"removing_failed_directory_not_empty": "Entfernen fehlgeschlagen, der Ordner, welchen Sie versuchen zu löschen, ist nicht leer.",
|
||||
"saving_failed": "Speichern fehlgeschlagen",
|
||||
"folder_already_exists": "Ordner existiert bereits",
|
||||
"folder_creation_failed": "Ordner Anlage fehlgeschlagen",
|
||||
"permissions_change_failed": "Berechtigungsänderung fehlgeschlagen",
|
||||
"compression_failed": "Kompression fehlgeschlagen",
|
||||
"archive_opening_failed": "Öffnen des Archivs fehlgeschlagen, es ist entweder korrupt oder nicht unterstützt.",
|
||||
"extraction_failed": "Auspacken fehlgeschlagen",
|
||||
"upload_failed": "Hochladen fehlgeschlagen"
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
{
|
||||
"function_not_implemented": "Function not implemented",
|
||||
"file_not_found": "File not found",
|
||||
"listing_failed": "Listing failed",
|
||||
"moving_failed": "Moving failed",
|
||||
"renaming_failed": "Renaming failed",
|
||||
"copying_failed": "Copying failed",
|
||||
"removing_failed": "Removing failed",
|
||||
"removing_failed_directory_not_empty": "Removing failed, the directory you are trying to remove is not empty",
|
||||
"saving_failed": "Saving failed",
|
||||
"folder_already_exists": "Folder already exists",
|
||||
"folder_creation_failed": "Folder creation failed",
|
||||
"permissions_change_failed": "Permissions change failed",
|
||||
"compression_failed": "Compression failed",
|
||||
"archive_opening_failed": "Could not open the archive, it is either corrupted or unsupported",
|
||||
"extraction_failed": "Extraction failed",
|
||||
"upload_failed": "Upload failed"
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
{
|
||||
"function_not_implemented": "Fonction non implémentée",
|
||||
"file_not_found": "Fichier non trouvé",
|
||||
"listing_failed": "Le listing a échoué",
|
||||
"moving_failed": "Le déplacement a échoué",
|
||||
"renaming_failed": "Le renommage a échoué",
|
||||
"copying_failed": "La copie a échouée",
|
||||
"removing_failed": "La suppression a échouée",
|
||||
"removing_failed_directory_not_empty": "La suppression a échouée, le répertoire que vous voulez supprimer n'est pas vide",
|
||||
"saving_failed": "L'enregistrement a échoué",
|
||||
"folder_already_exists": "Le répertoire existe déjà",
|
||||
"folder_creation_failed": "La création du répertoire a échoué",
|
||||
"permissions_change_failed": "Le changement de permission a échoué",
|
||||
"compression_failed": "La compression a échouée",
|
||||
"archive_opening_failed": "L'ouverture de l'archive est impossible, le fichier est corrompu ou non supporté",
|
||||
"extraction_failed": "L'extraction a échouée",
|
||||
"upload_failed": "L'upload a échoué"
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
{
|
||||
"function_not_implemented": "Funzione non implementata",
|
||||
"file_not_found": "File non trovato",
|
||||
"listing_failed": "Elenco fallito",
|
||||
"moving_failed": "Spostamento fallito",
|
||||
"renaming_failed": "Rinomina fallita",
|
||||
"copying_failed": "Copia fallita",
|
||||
"removing_failed": "Rimozione fallita",
|
||||
"removing_failed_directory_not_empty": "Rimozione fallita, la cartella che stai tentando di rimuovere non è vuota",
|
||||
"saving_failed": "Salvataggio fallito",
|
||||
"folder_already_exists": "La cartella esiste già",
|
||||
"folder_creation_failed": "Creazione della cartella fallita",
|
||||
"permissions_change_failed": "Modifica dei permessi non riuscita",
|
||||
"compression_failed": "Compressione fallita",
|
||||
"archive_opening_failed": "Impossibile aprire l'archivio, è danneggiato o non supportato",
|
||||
"extraction_failed": "Estrazione fallita",
|
||||
"upload_failed": "Caricamento fallito"
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
{
|
||||
"function_not_implemented": "구현되지 않은 기능입니다",
|
||||
"file_not_found": "파일을 찾을 수 없습니다",
|
||||
"listing_failed": "목록 작성 실패",
|
||||
"moving_failed": "이동 실패",
|
||||
"renaming_failed": "이름 변경 실패",
|
||||
"copying_failed": "복사 실패",
|
||||
"removing_failed": "삭제 실패",
|
||||
"removing_failed_directory_not_empty": "폴더가 비어 있지 않아, 삭제할 수 없습니다",
|
||||
"saving_failed": "저장 실패",
|
||||
"folder_already_exists": "폴더가 이미 존재합니다",
|
||||
"folder_creation_failed": "폴더 생성 실패",
|
||||
"permissions_change_failed": "권한 변경 실패",
|
||||
"compression_failed": "압축 실패",
|
||||
"archive_opening_failed": "파일이 손상되었거나 지원되지 않아, 압축 파일을 열 수 없습니다",
|
||||
"extraction_failed": "추출 실패",
|
||||
"upload_failed": "업로드 실패"
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
{
|
||||
"function_not_implemented": "Funkcia nie je implementovaná",
|
||||
"file_not_found": "Súbor nenájdený",
|
||||
"listing_failed": "Výpis súborov zlyhal",
|
||||
"moving_failed": "Presunutie zlyhalo",
|
||||
"renaming_failed": "Premenovanie zlyhalo",
|
||||
"copying_failed": "Kopírovanie zlyhalo",
|
||||
"removing_failed": "Odstraňovanie zlyhalo",
|
||||
"removing_failed_directory_not_empty": "Odstraňovanie zlyhalo, priečinok, ktorý sa snažíte odstrániť nie je prázdny",
|
||||
"saving_failed": "Ukladanie zlyhalo",
|
||||
"folder_already_exists": "Priečinok s daným názvom už existuje",
|
||||
"folder_creation_failed": "Priečinok sa nepodarilo vytvoriť",
|
||||
"permissions_change_failed": "Nepodarilo sa zmeniť oprávnenia",
|
||||
"compression_failed": "Komprimovanie zlyhalo",
|
||||
"archive_opening_failed": "Nepodarilo sa otvoriť archív je buď poškodený alebo nepodporovaného formátu",
|
||||
"extraction_failed": "Extrahovanie zlyhalo",
|
||||
"upload_failed": "Nahrávanie zlyhalo"
|
||||
}
|
129
public/static/admin/inputTags.js
Normal file
129
public/static/admin/inputTags.js
Normal file
@ -0,0 +1,129 @@
|
||||
/*
|
||||
* @Author: layui-2
|
||||
* @Date: 2018-08-31 11:40:42
|
||||
* @Last Modified by: layui-2
|
||||
* @Last Modified time: 2018-09-04 14:44:38
|
||||
*/
|
||||
layui.define(['jquery','layer'],function(exports){
|
||||
"use strict";
|
||||
var $ = layui.jquery,layer = layui.layer
|
||||
|
||||
|
||||
//外部接口
|
||||
,inputTags = {
|
||||
config: {}
|
||||
|
||||
//设置全局项
|
||||
,set: function(options){
|
||||
var that = this;
|
||||
that.config = $.extend({}, that.config, options);
|
||||
return that;
|
||||
}
|
||||
|
||||
// 事件监听
|
||||
,on: function(events, callback){
|
||||
return layui.onevent.call(this, MOD_NAME, events, callback)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//操作当前实例
|
||||
,thisinputTags = function(){
|
||||
var that = this
|
||||
,options = that.config;
|
||||
|
||||
return {
|
||||
config: options
|
||||
}
|
||||
}
|
||||
|
||||
//字符常量
|
||||
,MOD_NAME = 'inputTags'
|
||||
|
||||
|
||||
// 构造器
|
||||
,Class = function(options){
|
||||
var that = this;
|
||||
that.config = $.extend({}, that.config, inputTags.config, options);
|
||||
that.render();
|
||||
};
|
||||
|
||||
//默认配置
|
||||
Class.prototype.config = {
|
||||
close: false //默认:不开启关闭按钮
|
||||
,theme: '' //背景:颜色
|
||||
,content: [] //默认标签
|
||||
,aldaBtn: false //默认配置
|
||||
};
|
||||
|
||||
// 初始化
|
||||
Class.prototype.init = function(){
|
||||
var that = this
|
||||
,spans = ''
|
||||
,options = that.config
|
||||
,span = document.createElement("span"),
|
||||
spantext = $(span).text("获取全部数据").addClass('albtn');
|
||||
if(options.aldaBtn){
|
||||
$('body').append(spantext)
|
||||
}
|
||||
|
||||
$.each(options.content,function(index,item){
|
||||
spans +='<span><em>'+item+'</em><button type="button" class="close">×</button></span>';
|
||||
// $('<div class="layui-flow-more"><a href="javascript:;">'+ ELEM_TEXT +'</a></div>');
|
||||
})
|
||||
options.elem.before(spans)
|
||||
that.events()
|
||||
}
|
||||
|
||||
Class.prototype.render = function(){
|
||||
var that = this
|
||||
,options = that.config
|
||||
options.elem = $(options.elem);
|
||||
that.enter()
|
||||
};
|
||||
|
||||
// 回车生成标签
|
||||
Class.prototype.enter = function(){
|
||||
var that = this
|
||||
,spans = ''
|
||||
,options = that.config;
|
||||
options.elem.focus();
|
||||
options.elem.keypress(function(event){
|
||||
var keynum = (event.keyCode ? event.keyCode : event.which);
|
||||
if(keynum == '13'){
|
||||
var $val = options.elem.val().trim();
|
||||
if(!$val) return false;
|
||||
if(options.content.indexOf($val) == -1){
|
||||
options.content.push($val)
|
||||
that.render()
|
||||
spans ='<span><em>'+$val+'</em><button type="button" class="close">×</button></span>';
|
||||
options.elem.before(spans)
|
||||
}
|
||||
options.done && typeof options.done === 'function' && options.done($val);
|
||||
options.elem.val('');
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
//事件处理
|
||||
Class.prototype.events = function(){
|
||||
var that = this
|
||||
,options = that.config;
|
||||
$('.albtn').on('click',function(){
|
||||
console.log(options.content)
|
||||
})
|
||||
$('#tags').on('click','.close',function(){
|
||||
var Thisremov = $(this).parent('span').remove(),
|
||||
ThisText = $(Thisremov).find('em').text();
|
||||
options.content.splice($.inArray(ThisText,options.content),1)
|
||||
})
|
||||
};
|
||||
|
||||
//核心入口
|
||||
inputTags.render = function(options){
|
||||
var inst = new Class(options);
|
||||
inst.init();
|
||||
return thisinputTags.call(inst);
|
||||
};
|
||||
exports('inputTags',inputTags);
|
||||
}).link('/static/res/css/inputTags.css')
|
@ -342,10 +342,10 @@ pre{position: relative; margin: 10px 0; padding: 15px; line-height: 20px; border
|
||||
|
||||
/* 单行列表 */
|
||||
.fly-list-one .fly-panel-title{margin-bottom: 5px;}
|
||||
.fly-list-one dd{margin: 0 15px; line-height: 28px; 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: 35px; white-space: nowrap; overflow: hidden; list-style: decimal-leading-zero inside; *list-style-type: decimal inside; color: #009E94;}
|
||||
.fly-list-one dd a,
|
||||
.fly-list-one dd span{display: inline-block; *display: inline; *zoom: 1; vertical-align: top; font-style: normal}
|
||||
.fly-list-one dd a{max-width: 85%; margin-right: 5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 16px;}
|
||||
.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 span{font-size: 12px; color: #ccc;}
|
||||
.fly-list-one dd:last-child{padding-bottom: 5px;}
|
||||
|
||||
|
81
public/static/res/css/inputTags.css
Normal file
81
public/static/res/css/inputTags.css
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* @Author: layui-2
|
||||
* @Date: 2018-08-31 11:40:53
|
||||
* @Last Modified by: xuzhiwen
|
||||
* @Last Modified time: 2018-09-07 15:26:19
|
||||
*/
|
||||
em{
|
||||
font-style: normal;
|
||||
}
|
||||
#tags
|
||||
{
|
||||
padding-left: 10px;
|
||||
|
||||
color: #777;
|
||||
border: 1px solid #d5d5d5;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
#tags span{
|
||||
font-size: 12px;
|
||||
font-weight: normal;
|
||||
line-height: 16px;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
height: 16px;
|
||||
margin-right: 3px;
|
||||
margin-bottom: 3px;
|
||||
padding: 4px 22px 5px 9px;
|
||||
cursor: pointer;
|
||||
transition: all .2s ease 0s;
|
||||
vertical-align: baseline;
|
||||
white-space: nowrap;
|
||||
color: #fff;
|
||||
background-color: #009688;
|
||||
text-shadow: 1px 1px 1px rgba(0, 0, 0, .15);
|
||||
}
|
||||
#tags .close{
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
line-height: 20px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
float: none;
|
||||
width: 18px;
|
||||
padding: 0;
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
opacity: 1;
|
||||
color: #fff;
|
||||
border: 0 none;
|
||||
background: transparent none repeat scroll 0 0;
|
||||
text-shadow: none;
|
||||
}
|
||||
#tags .close:hover{
|
||||
background: #ffb800;
|
||||
}
|
||||
#inputTags[type='text'],
|
||||
#inputTags[type='text']:focus{
|
||||
line-height: 25px;
|
||||
display: inline;
|
||||
width: 150px;
|
||||
margin: 0;
|
||||
padding: 0 6px;
|
||||
border: 0 none;
|
||||
outline: 0 none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.albtn{
|
||||
line-height: 30px;
|
||||
display: block;
|
||||
width: 100px;
|
||||
height: 30px;
|
||||
margin: 0 auto;
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
background: #ffb800;
|
||||
}
|
129
public/static/res/mods/inputTags.js
Normal file
129
public/static/res/mods/inputTags.js
Normal file
@ -0,0 +1,129 @@
|
||||
/*
|
||||
* @Author: layui-2
|
||||
* @Date: 2018-08-31 11:40:42
|
||||
* @Last Modified by: layui-2
|
||||
* @Last Modified time: 2018-09-04 14:44:38
|
||||
*/
|
||||
layui.define(['jquery','layer'],function(exports){
|
||||
"use strict";
|
||||
var $ = layui.jquery,layer = layui.layer
|
||||
|
||||
|
||||
//外部接口
|
||||
,inputTags = {
|
||||
config: {}
|
||||
|
||||
//设置全局项
|
||||
,set: function(options){
|
||||
var that = this;
|
||||
that.config = $.extend({}, that.config, options);
|
||||
return that;
|
||||
}
|
||||
|
||||
// 事件监听
|
||||
,on: function(events, callback){
|
||||
return layui.onevent.call(this, MOD_NAME, events, callback)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//操作当前实例
|
||||
,thisinputTags = function(){
|
||||
var that = this
|
||||
,options = that.config;
|
||||
|
||||
return {
|
||||
config: options
|
||||
}
|
||||
}
|
||||
|
||||
//字符常量
|
||||
,MOD_NAME = 'inputTags'
|
||||
|
||||
|
||||
// 构造器
|
||||
,Class = function(options){
|
||||
var that = this;
|
||||
that.config = $.extend({}, that.config, inputTags.config, options);
|
||||
that.render();
|
||||
};
|
||||
|
||||
//默认配置
|
||||
Class.prototype.config = {
|
||||
close: false //默认:不开启关闭按钮
|
||||
,theme: '' //背景:颜色
|
||||
,content: [] //默认标签
|
||||
,aldaBtn: false //默认配置
|
||||
};
|
||||
|
||||
// 初始化
|
||||
Class.prototype.init = function(){
|
||||
var that = this
|
||||
,spans = ''
|
||||
,options = that.config
|
||||
,span = document.createElement("span"),
|
||||
spantext = $(span).text("获取全部数据").addClass('albtn');
|
||||
if(options.aldaBtn){
|
||||
$('body').append(spantext)
|
||||
}
|
||||
|
||||
$.each(options.content,function(index,item){
|
||||
spans +='<span><em>'+item+'</em><button type="button" class="close">×</button></span>';
|
||||
// $('<div class="layui-flow-more"><a href="javascript:;">'+ ELEM_TEXT +'</a></div>');
|
||||
})
|
||||
options.elem.before(spans)
|
||||
that.events()
|
||||
}
|
||||
|
||||
Class.prototype.render = function(){
|
||||
var that = this
|
||||
,options = that.config
|
||||
options.elem = $(options.elem);
|
||||
that.enter()
|
||||
};
|
||||
|
||||
// 回车生成标签
|
||||
Class.prototype.enter = function(){
|
||||
var that = this
|
||||
,spans = ''
|
||||
,options = that.config;
|
||||
options.elem.focus();
|
||||
options.elem.keypress(function(event){
|
||||
var keynum = (event.keyCode ? event.keyCode : event.which);
|
||||
if(keynum == '13'){
|
||||
var $val = options.elem.val().trim();
|
||||
if(!$val) return false;
|
||||
if(options.content.indexOf($val) == -1){
|
||||
options.content.push($val)
|
||||
that.render()
|
||||
spans ='<span><em>'+$val+'</em><button type="button" class="close">×</button></span>';
|
||||
options.elem.before(spans)
|
||||
}
|
||||
options.done && typeof options.done === 'function' && options.done($val);
|
||||
options.elem.val('');
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
//事件处理
|
||||
Class.prototype.events = function(){
|
||||
var that = this
|
||||
,options = that.config;
|
||||
$('.albtn').on('click',function(){
|
||||
console.log(options.content)
|
||||
})
|
||||
$('#tags').on('click','.close',function(){
|
||||
var Thisremov = $(this).parent('span').remove(),
|
||||
ThisText = $(Thisremov).find('em').text();
|
||||
options.content.splice($.inArray(ThisText,options.content),1)
|
||||
})
|
||||
};
|
||||
|
||||
//核心入口
|
||||
inputTags.render = function(options){
|
||||
var inst = new Class(options);
|
||||
inst.init();
|
||||
return thisinputTags.call(inst);
|
||||
};
|
||||
exports('inputTags',inputTags);
|
||||
}).link('/static/res/css/inputTags.css')
|
8
public/static/res/mods/xm-select.js
Normal file
8
public/static/res/mods/xm-select.js
Normal file
File diff suppressed because one or more lines are too long
8
public/static/xm-select.js
Normal file
8
public/static/xm-select.js
Normal file
File diff suppressed because one or more lines are too long
25
runtime/update.sql
Normal file
25
runtime/update.sql
Normal file
@ -0,0 +1,25 @@
|
||||
ALTER TABLE `tao_push_jscode` ADD `type` tinyint(1) NOT NULL DEFAULT '1' COMMENT '1push2taglink' AFTER `jscode`;
|
||||
|
||||
DROP TABLE IF EXISTS `tao_tag`;
|
||||
CREATE TABLE `tao_tag` (
|
||||
`id` int(10) NOT NULL AUTO_INCREMENT COMMENT 'tag自增id',
|
||||
`name` varchar(20) NOT NULL COMMENT '名称',
|
||||
`ename` varchar(20) NOT NULL COMMENT '英文名',
|
||||
`create_time` int NOT NULL COMMENT '创建时间',
|
||||
`update_time` int NOT NULL COMMENT '更新时间',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `ename` (`ename`) USING BTREE COMMENT 'ename查询tag索引'
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='文章tag表';
|
||||
|
||||
DROP TABLE IF EXISTS `tao_taglist`;
|
||||
CREATE TABLE `tao_taglist` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '标签列表id',
|
||||
`tag_id` int NOT NULL COMMENT '标签id',
|
||||
`article_id` int NOT NULL COMMENT '文章id',
|
||||
`create_time` int NOT NULL COMMENT '创建时间',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `tag_id` (`tag_id`) USING BTREE COMMENT 'tagID索引',
|
||||
KEY `article_id` (`article_id`) USING BTREE COMMENT '文章ID查询索引'
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='tag详细列表';
|
||||
|
||||
ALTER TABLE `tao_article` CHANGE `tags` `keywords` varchar(255) DEFAULT NULL COMMENT '关键词';
|
1
vendor/composer/autoload_files.php
vendored
1
vendor/composer/autoload_files.php
vendored
@ -16,7 +16,6 @@ return array(
|
||||
'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php',
|
||||
'6b998e7ad3182c0d21d23780badfa07b' => $vendorDir . '/yansongda/supports/src/Functions.php',
|
||||
'37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php',
|
||||
'dc1275c308c5b416beb314b6317daca2' => $vendorDir . '/overtrue/pinyin/src/const.php',
|
||||
'b33e3d135e5d9e47d845c576147bda89' => $vendorDir . '/php-di/php-di/src/functions.php',
|
||||
'667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php',
|
||||
'223fa6f9b46fbe5d6b44c5ff847bfceb' => $vendorDir . '/taoser/think-addons/src/helper.php',
|
||||
|
1
vendor/composer/autoload_psr4.php
vendored
1
vendor/composer/autoload_psr4.php
vendored
@ -37,7 +37,6 @@ return array(
|
||||
'Phinx\\' => array($vendorDir . '/topthink/think-migration/phinx/src/Phinx'),
|
||||
'PHPSocketIO\\' => array($vendorDir . '/workerman/phpsocket.io/src'),
|
||||
'PHPMailer\\PHPMailer\\' => array($vendorDir . '/phpmailer/phpmailer/src'),
|
||||
'Overtrue\\Pinyin\\' => array($vendorDir . '/overtrue/pinyin/src'),
|
||||
'League\\MimeTypeDetection\\' => array($vendorDir . '/league/mime-type-detection/src'),
|
||||
'League\\Flysystem\\Cached\\' => array($vendorDir . '/league/flysystem-cached-adapter/src'),
|
||||
'League\\Flysystem\\' => array($vendorDir . '/league/flysystem/src'),
|
||||
|
9
vendor/composer/autoload_static.php
vendored
9
vendor/composer/autoload_static.php
vendored
@ -17,7 +17,6 @@ class ComposerStaticInit1b32198725235c8d6500c87262ef30c2
|
||||
'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php',
|
||||
'6b998e7ad3182c0d21d23780badfa07b' => __DIR__ . '/..' . '/yansongda/supports/src/Functions.php',
|
||||
'37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php',
|
||||
'dc1275c308c5b416beb314b6317daca2' => __DIR__ . '/..' . '/overtrue/pinyin/src/const.php',
|
||||
'b33e3d135e5d9e47d845c576147bda89' => __DIR__ . '/..' . '/php-di/php-di/src/functions.php',
|
||||
'667aeda72477189d0494fecd327c3641' => __DIR__ . '/..' . '/symfony/var-dumper/Resources/functions/dump.php',
|
||||
'223fa6f9b46fbe5d6b44c5ff847bfceb' => __DIR__ . '/..' . '/taoser/think-addons/src/helper.php',
|
||||
@ -85,10 +84,6 @@ class ComposerStaticInit1b32198725235c8d6500c87262ef30c2
|
||||
'PHPSocketIO\\' => 12,
|
||||
'PHPMailer\\PHPMailer\\' => 20,
|
||||
),
|
||||
'O' =>
|
||||
array (
|
||||
'Overtrue\\Pinyin\\' => 16,
|
||||
),
|
||||
'L' =>
|
||||
array (
|
||||
'League\\MimeTypeDetection\\' => 25,
|
||||
@ -258,10 +253,6 @@ class ComposerStaticInit1b32198725235c8d6500c87262ef30c2
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/phpmailer/phpmailer/src',
|
||||
),
|
||||
'Overtrue\\Pinyin\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/overtrue/pinyin/src',
|
||||
),
|
||||
'League\\MimeTypeDetection\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/league/mime-type-detection/src',
|
||||
|
76
vendor/composer/installed.json
vendored
76
vendor/composer/installed.json
vendored
@ -947,82 +947,6 @@
|
||||
},
|
||||
"install-path": "../lotofbadcode/phpspirit_databackup"
|
||||
},
|
||||
{
|
||||
"name": "overtrue/pinyin",
|
||||
"version": "4.0.8",
|
||||
"version_normalized": "4.0.8.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/overtrue/pinyin.git",
|
||||
"reference": "04bdb4d33d50e8fb1aa5a824064c5151c4b15dc2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/overtrue/pinyin/zipball/04bdb4d33d50e8fb1aa5a824064c5151c4b15dc2",
|
||||
"reference": "04bdb4d33d50e8fb1aa5a824064c5151c4b15dc2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"brainmaestro/composer-git-hooks": "^2.7",
|
||||
"friendsofphp/php-cs-fixer": "^2.16",
|
||||
"phpunit/phpunit": "~8.0"
|
||||
},
|
||||
"time": "2021-07-19T03:43:32+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"hooks": {
|
||||
"pre-commit": [
|
||||
"composer test",
|
||||
"composer fix-style"
|
||||
],
|
||||
"pre-push": [
|
||||
"composer test",
|
||||
"composer check-style"
|
||||
]
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/const.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Overtrue\\Pinyin\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "overtrue",
|
||||
"email": "anzhengchao@gmail.com",
|
||||
"homepage": "http://github.com/overtrue"
|
||||
}
|
||||
],
|
||||
"description": "Chinese to pinyin translator.",
|
||||
"homepage": "https://github.com/overtrue/pinyin",
|
||||
"keywords": [
|
||||
"Chinese",
|
||||
"Pinyin",
|
||||
"cn2pinyin"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/overtrue/pinyin/issues",
|
||||
"source": "https://github.com/overtrue/pinyin/tree/4.0.8"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://www.patreon.com/overtrue",
|
||||
"type": "patreon"
|
||||
}
|
||||
],
|
||||
"install-path": "../overtrue/pinyin"
|
||||
},
|
||||
{
|
||||
"name": "php-di/invoker",
|
||||
"version": "2.3.3",
|
||||
|
13
vendor/composer/installed.php
vendored
13
vendor/composer/installed.php
vendored
@ -3,7 +3,7 @@
|
||||
'name' => 'taoser/taoler',
|
||||
'pretty_version' => 'dev-master',
|
||||
'version' => 'dev-master',
|
||||
'reference' => '36ce800bdbb34844639cbef6c8658e5a36b1dc6e',
|
||||
'reference' => 'b7290931244a7ca51d61cdc44ac0e774d54a44d9',
|
||||
'type' => 'project',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
@ -127,15 +127,6 @@
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'overtrue/pinyin' => array(
|
||||
'pretty_version' => '4.0.8',
|
||||
'version' => '4.0.8.0',
|
||||
'reference' => '04bdb4d33d50e8fb1aa5a824064c5151c4b15dc2',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../overtrue/pinyin',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'php-di/invoker' => array(
|
||||
'pretty_version' => '2.3.3',
|
||||
'version' => '2.3.3.0',
|
||||
@ -301,7 +292,7 @@
|
||||
'taoser/taoler' => array(
|
||||
'pretty_version' => 'dev-master',
|
||||
'version' => 'dev-master',
|
||||
'reference' => '36ce800bdbb34844639cbef6c8658e5a36b1dc6e',
|
||||
'reference' => 'b7290931244a7ca51d61cdc44ac0e774d54a44d9',
|
||||
'type' => 'project',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
|
9
vendor/overtrue/pinyin/.github/FUNDING.yml
vendored
9
vendor/overtrue/pinyin/.github/FUNDING.yml
vendored
@ -1,9 +0,0 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||
patreon: overtrue
|
||||
open_collective: # Replace with a single Open Collective username
|
||||
ko_fi: # Replace with a single Ko-fi username
|
||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
custom: # Replace with a single custom sponsorship URL
|
12
vendor/overtrue/pinyin/.github/dependabot.yml
vendored
12
vendor/overtrue/pinyin/.github/dependabot.yml
vendored
@ -1,12 +0,0 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: composer
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: daily
|
||||
time: "21:00"
|
||||
open-pull-requests-limit: 10
|
||||
ignore:
|
||||
- dependency-name: phpunit/phpunit
|
||||
versions:
|
||||
- ">= 8.a, < 9"
|
21
vendor/overtrue/pinyin/LICENSE
vendored
21
vendor/overtrue/pinyin/LICENSE
vendored
@ -1,21 +0,0 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 安正超
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
130
vendor/overtrue/pinyin/README.md
vendored
130
vendor/overtrue/pinyin/README.md
vendored
@ -1,130 +0,0 @@
|
||||
<h1 align="center">Pinyin</h1>
|
||||
|
||||
<p align="center">
|
||||
|
||||
[![Build Status](https://travis-ci.org/overtrue/pinyin.svg?branch=master)](https://travis-ci.org/overtrue/pinyin)
|
||||
[![Latest Stable Version](https://poser.pugx.org/overtrue/pinyin/v/stable.svg)](https://packagist.org/packages/overtrue/pinyin) [![Total Downloads](https://poser.pugx.org/overtrue/pinyin/downloads.svg)](https://packagist.org/packages/overtrue/pinyin) [![Latest Unstable Version](https://poser.pugx.org/overtrue/pinyin/v/unstable.svg)](https://packagist.org/packages/overtrue/pinyin) [![License](https://poser.pugx.org/overtrue/pinyin/license.svg)](https://packagist.org/packages/overtrue/pinyin)
|
||||
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/overtrue/pinyin/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/overtrue/pinyin/?branch=master)
|
||||
[![Code Coverage](https://scrutinizer-ci.com/g/overtrue/pinyin/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/overtrue/pinyin/?branch=master)
|
||||
[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fovertrue%2Fpinyin.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fovertrue%2Fpinyin?ref=badge_shield)
|
||||
|
||||
</p>
|
||||
|
||||
:cn: 基于 [CC-CEDICT](http://cc-cedict.org/wiki/) 词典的中文转拼音工具,更准确的支持多音字的汉字转拼音解决方案。
|
||||
|
||||
|
||||
## 安装
|
||||
|
||||
使用 Composer 安装:
|
||||
|
||||
```
|
||||
$ composer require "overtrue/pinyin:~4.0"
|
||||
```
|
||||
|
||||
## 使用
|
||||
|
||||
可选转换方案:
|
||||
|
||||
- 内存型,适用于服务器内存空间较富余,优点:转换快
|
||||
- 小内存型(默认),适用于内存比较紧张的环境,优点:占用内存小,转换不如内存型快
|
||||
- I/O型,适用于虚拟机,内存限制比较严格环境。优点:非常微小内存消耗。缺点:转换慢,不如内存型转换快,php >= 5.5
|
||||
|
||||
## 可用选项:
|
||||
|
||||
| 选项 | 描述 |
|
||||
| ------------- | ---------------------------------------------------|
|
||||
| `PINYIN_TONE` | UNICODE 式音调:`měi hǎo` |
|
||||
| `PINYIN_ASCII_TONE` | 带数字式音调: `mei3 hao3` |
|
||||
| `PINYIN_NO_TONE` | 无音调:`mei hao` |
|
||||
| `PINYIN_KEEP_NUMBER` | 保留数字 |
|
||||
| `PINYIN_KEEP_ENGLISH` | 保留英文 |
|
||||
| `PINYIN_KEEP_PUNCTUATION` | 保留标点 |
|
||||
| `PINYIN_UMLAUT_V` | 使用 `v` 代替 `yu`, 例如:吕 `lyu` 将会转为 `lv` |
|
||||
|
||||
### 拼音数组
|
||||
|
||||
```php
|
||||
use Overtrue\Pinyin\Pinyin;
|
||||
|
||||
// 小内存型
|
||||
$pinyin = new Pinyin(); // 默认
|
||||
// 内存型
|
||||
// $pinyin = new Pinyin('\\Overtrue\\Pinyin\\MemoryFileDictLoader');
|
||||
// I/O型
|
||||
// $pinyin = new Pinyin('\\Overtrue\\Pinyin\\GeneratorFileDictLoader');
|
||||
|
||||
$pinyin->convert('带着希望去旅行,比到达终点更美好');
|
||||
// ["dai", "zhe", "xi", "wang", "qu", "lyu", "xing", "bi", "dao", "da", "zhong", "dian", "geng", "mei", "hao"]
|
||||
|
||||
$pinyin->convert('带着希望去旅行,比到达终点更美好', PINYIN_TONE);
|
||||
// ["dài","zhe","xī","wàng","qù","lǚ","xíng","bǐ","dào","dá","zhōng","diǎn","gèng","měi","hǎo"]
|
||||
|
||||
$pinyin->convert('带着希望去旅行,比到达终点更美好', PINYIN_ASCII_TONE);
|
||||
//["dai4","zhe","xi1","wang4","qu4","lyu3","xing2","bi3","dao4","da2","zhong1","dian3","geng4","mei3","hao3"]
|
||||
```
|
||||
|
||||
- 小内存型: 将字典分片载入内存
|
||||
- 内存型: 将所有字典预先载入内存
|
||||
- I/O型: 不载入内存,将字典使用文件流打开逐行遍历并运用php5.5生成器(yield)特性分配单行内存
|
||||
|
||||
|
||||
### 生成用于链接的拼音字符串
|
||||
|
||||
```php
|
||||
$pinyin->permalink('带着希望去旅行'); // dai-zhe-xi-wang-qu-lyu-xing
|
||||
$pinyin->permalink('带着希望去旅行', '.'); // dai.zhe.xi.wang.qu.lyu.xing
|
||||
```
|
||||
|
||||
### 获取首字符字符串
|
||||
|
||||
```php
|
||||
$pinyin->abbr('带着希望去旅行'); // dzxwqlx
|
||||
$pinyin->abbr('带着希望去旅行', '-'); // d-z-x-w-q-l-x
|
||||
|
||||
$pinyin->abbr('你好2018!', PINYIN_KEEP_NUMBER); // nh2018
|
||||
$pinyin->abbr('Happy New Year! 2018!', PINYIN_KEEP_ENGLISH); // HNY2018
|
||||
```
|
||||
|
||||
### 翻译整段文字为拼音
|
||||
|
||||
将会保留中文字符:`,。 ! ? : “ ” ‘ ’` 并替换为对应的英文符号。
|
||||
|
||||
```php
|
||||
$pinyin->sentence('带着希望去旅行,比到达终点更美好!');
|
||||
// dai zhe xi wang qu lyu xing, bi dao da zhong dian geng mei hao!
|
||||
|
||||
$pinyin->sentence('带着希望去旅行,比到达终点更美好!', PINYIN_TONE);
|
||||
// dài zhe xī wàng qù lǚ xíng, bǐ dào dá zhōng diǎn gèng měi hǎo!
|
||||
```
|
||||
|
||||
### 翻译姓名
|
||||
|
||||
姓名的姓的读音有些与普通字不一样,比如 ‘单’ 常见的音为 `dan`,而作为姓的时候读 `shan`。
|
||||
|
||||
```php
|
||||
$pinyin->name('单某某'); // ['shan', 'mou', 'mou']
|
||||
$pinyin->name('单某某', PINYIN_TONE); // ["shàn","mǒu","mǒu"]
|
||||
```
|
||||
|
||||
更多使用请参考 [测试用例](https://github.com/overtrue/pinyin/blob/master/tests/AbstractDictLoaderTestCase.php)。
|
||||
|
||||
## 在 Laravel 中使用
|
||||
|
||||
独立的包在这里:[overtrue/laravel-pinyin](https://github.com/overtrue/laravel-pinyin)
|
||||
|
||||
## Contribution
|
||||
欢迎提意见及完善补充词库 [`overtrue/pinyin-dictionary-maker`](https://github.com/overtrue/pinyin-dictionary-maker/tree/master/patches) :kiss:
|
||||
|
||||
## 参考
|
||||
|
||||
- [详细参考资料](https://github.com/overtrue/pinyin-resources)
|
||||
|
||||
## PHP 扩展包开发
|
||||
|
||||
> 想知道如何从零开始构建 PHP 扩展包?
|
||||
>
|
||||
> 请关注我的实战课程,我会在此课程中分享一些扩展开发经验 —— [《PHP 扩展包实战教程 - 从入门到发布》](https://learnku.com/courses/creating-package)
|
||||
|
||||
# License
|
||||
|
||||
[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fovertrue%2Fpinyin.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fovertrue%2Fpinyin?ref=badge_large)
|
68
vendor/overtrue/pinyin/composer.json
vendored
68
vendor/overtrue/pinyin/composer.json
vendored
@ -1,68 +0,0 @@
|
||||
{
|
||||
"name": "overtrue/pinyin",
|
||||
"description": "Chinese to pinyin translator.",
|
||||
"keywords": [
|
||||
"chinese",
|
||||
"pinyin",
|
||||
"cn2pinyin"
|
||||
],
|
||||
"homepage": "https://github.com/overtrue/pinyin",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "overtrue",
|
||||
"homepage": "http://github.com/overtrue",
|
||||
"email": "anzhengchao@gmail.com"
|
||||
}
|
||||
],
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Overtrue\\Pinyin\\": "src/"
|
||||
},
|
||||
"files": ["src/const.php"]
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Overtrue\\Pinyin\\Test\\": "tests/"
|
||||
}
|
||||
},
|
||||
"require": {
|
||||
"php":">=7.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~8.0",
|
||||
"brainmaestro/composer-git-hooks": "^2.7",
|
||||
"friendsofphp/php-cs-fixer": "^2.16"
|
||||
},
|
||||
"extra": {
|
||||
"hooks": {
|
||||
"pre-commit": [
|
||||
"composer test",
|
||||
"composer fix-style"
|
||||
],
|
||||
"pre-push": [
|
||||
"composer test",
|
||||
"composer check-style"
|
||||
]
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"post-update-cmd": [
|
||||
"cghooks update"
|
||||
],
|
||||
"post-merge": "composer install",
|
||||
"post-install-cmd": [
|
||||
"cghooks add --ignore-lock",
|
||||
"cghooks update"
|
||||
],
|
||||
"cghooks": "vendor/bin/cghooks",
|
||||
"check-style": "php-cs-fixer fix --using-cache=no --diff --config=.php_cs --dry-run --ansi",
|
||||
"fix-style": "php-cs-fixer fix --using-cache=no --config=.php_cs --ansi",
|
||||
"test": "vendor/bin/phpunit --colors=always"
|
||||
},
|
||||
"scripts-descriptions": {
|
||||
"test": "Run all tests.",
|
||||
"check-style": "Run style checks (only dry run - no fixing!).",
|
||||
"fix-style": "Run style checks and fix violations."
|
||||
}
|
||||
}
|
86
vendor/overtrue/pinyin/data/surnames
vendored
86
vendor/overtrue/pinyin/data/surnames
vendored
@ -1,86 +0,0 @@
|
||||
<?php
|
||||
return array (
|
||||
'万俟' => ' mò qí',
|
||||
'尉迟' => ' yù chí',
|
||||
'单于' => ' chán yú',
|
||||
'不' => ' fǒu',
|
||||
'沈' => ' shěn',
|
||||
'称' => ' chēng',
|
||||
'车' => ' chē',
|
||||
'万' => ' wàn',
|
||||
'汤' => ' tāng',
|
||||
'阿' => ' ā',
|
||||
'丁' => ' dīng',
|
||||
'强' => ' qiáng',
|
||||
'仇' => ' qiú',
|
||||
'叶' => ' yè',
|
||||
'阚' => ' kàn',
|
||||
'乐' => ' yuè',
|
||||
'乜' => ' niè',
|
||||
'陆' => ' lù',
|
||||
'殷' => ' yīn',
|
||||
'牟' => ' móu',
|
||||
'区' => ' ōu',
|
||||
'宿' => ' sù',
|
||||
'俞' => ' yú',
|
||||
'余' => ' yú',
|
||||
'齐' => ' qí',
|
||||
'许' => ' xǔ',
|
||||
'信' => ' xìn',
|
||||
'无' => ' wú',
|
||||
'浣' => ' wǎn',
|
||||
'艾' => ' ài',
|
||||
'浅' => ' qiǎn',
|
||||
'烟' => ' yān',
|
||||
'蓝' => ' lán',
|
||||
'於' => ' yú',
|
||||
'寻' => ' xún',
|
||||
'殳' => ' shū',
|
||||
'思' => ' sī',
|
||||
'鸟' => ' niǎo',
|
||||
'卜' => ' bǔ',
|
||||
'单' => ' shàn',
|
||||
'南' => ' nán',
|
||||
'柏' => ' bǎi',
|
||||
'朴' => ' piáo',
|
||||
'繁' => ' pó',
|
||||
'曾' => ' zēng',
|
||||
'瞿' => ' qú',
|
||||
'缪' => ' miào',
|
||||
'石' => ' shí',
|
||||
'冯' => ' féng',
|
||||
'覃' => ' qín',
|
||||
'幺' => ' yāo',
|
||||
'种' => ' chóng',
|
||||
'折' => ' shè',
|
||||
'燕' => ' yān',
|
||||
'纪' => ' jǐ',
|
||||
'过' => ' guō',
|
||||
'华' => ' huà',
|
||||
'冼' => ' xiǎn',
|
||||
'秘' => ' bì',
|
||||
'重' => ' chóng',
|
||||
'解' => ' xiè',
|
||||
'那' => ' nā',
|
||||
'和' => ' hé',
|
||||
'贾' => ' jiǎ',
|
||||
'塔' => ' tǎ',
|
||||
'盛' => ' shèng',
|
||||
'查' => ' zhā',
|
||||
'盖' => ' gě',
|
||||
'居' => ' jū',
|
||||
'哈' => ' hǎ',
|
||||
'的' => ' dē',
|
||||
'薄' => ' bó',
|
||||
'佴' => ' nài',
|
||||
'六' => ' lù',
|
||||
'都' => ' dū',
|
||||
'翟' => ' zhái',
|
||||
'扎' => ' zā',
|
||||
'藏' => ' zàng',
|
||||
'粘' => ' niàn',
|
||||
'难' => ' nàn',
|
||||
'若' => ' ruò',
|
||||
'貟' => ' yùn',
|
||||
'贠' => ' yùn',
|
||||
);
|
8003
vendor/overtrue/pinyin/data/words_0
vendored
8003
vendor/overtrue/pinyin/data/words_0
vendored
File diff suppressed because it is too large
Load Diff
8003
vendor/overtrue/pinyin/data/words_1
vendored
8003
vendor/overtrue/pinyin/data/words_1
vendored
File diff suppressed because it is too large
Load Diff
8003
vendor/overtrue/pinyin/data/words_2
vendored
8003
vendor/overtrue/pinyin/data/words_2
vendored
File diff suppressed because it is too large
Load Diff
8003
vendor/overtrue/pinyin/data/words_3
vendored
8003
vendor/overtrue/pinyin/data/words_3
vendored
File diff suppressed because it is too large
Load Diff
8003
vendor/overtrue/pinyin/data/words_4
vendored
8003
vendor/overtrue/pinyin/data/words_4
vendored
File diff suppressed because it is too large
Load Diff
2055
vendor/overtrue/pinyin/data/words_5
vendored
2055
vendor/overtrue/pinyin/data/words_5
vendored
File diff suppressed because it is too large
Load Diff
@ -1,42 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the overtrue/pinyin.
|
||||
*
|
||||
* (c) overtrue <i@overtrue.me>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Overtrue\Pinyin;
|
||||
|
||||
use Closure;
|
||||
|
||||
/**
|
||||
* Dict loader interface.
|
||||
*/
|
||||
interface DictLoaderInterface
|
||||
{
|
||||
/**
|
||||
* Load dict.
|
||||
*
|
||||
* <pre>
|
||||
* [
|
||||
* '响应时间' => "[\t]xiǎng[\t]yìng[\t]shí[\t]jiān",
|
||||
* '长篇连载' => '[\t]cháng[\t]piān[\t]lián[\t]zǎi',
|
||||
* //...
|
||||
* ]
|
||||
* </pre>
|
||||
*
|
||||
* @param Closure $callback
|
||||
*/
|
||||
public function map(Closure $callback);
|
||||
|
||||
/**
|
||||
* Load surname dict.
|
||||
*
|
||||
* @param Closure $callback
|
||||
*/
|
||||
public function mapSurname(Closure $callback);
|
||||
}
|
73
vendor/overtrue/pinyin/src/FileDictLoader.php
vendored
73
vendor/overtrue/pinyin/src/FileDictLoader.php
vendored
@ -1,73 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the overtrue/pinyin.
|
||||
*
|
||||
* (c) overtrue <i@overtrue.me>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Overtrue\Pinyin;
|
||||
|
||||
use Closure;
|
||||
|
||||
class FileDictLoader implements DictLoaderInterface
|
||||
{
|
||||
/**
|
||||
* Words segment name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $segmentName = 'words_%s';
|
||||
|
||||
/**
|
||||
* Dict path.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $path;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $path
|
||||
*/
|
||||
public function __construct($path)
|
||||
{
|
||||
$this->path = $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load dict.
|
||||
*
|
||||
* @param Closure $callback
|
||||
*/
|
||||
public function map(Closure $callback)
|
||||
{
|
||||
for ($i = 0; $i < 100; ++$i) {
|
||||
$segment = $this->path . '/' . sprintf($this->segmentName, $i);
|
||||
|
||||
if (file_exists($segment)) {
|
||||
$dictionary = (array) include $segment;
|
||||
$callback($dictionary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load surname dict.
|
||||
*
|
||||
* @param Closure $callback
|
||||
*/
|
||||
public function mapSurname(Closure $callback)
|
||||
{
|
||||
$surnames = $this->path . '/surnames';
|
||||
|
||||
if (file_exists($surnames)) {
|
||||
$dictionary = (array) include $surnames;
|
||||
$callback($dictionary);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,142 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the overtrue/pinyin.
|
||||
*
|
||||
* (c) overtrue <i@overtrue.me>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Overtrue\Pinyin;
|
||||
|
||||
use Closure;
|
||||
use SplFileObject;
|
||||
use Generator;
|
||||
|
||||
class GeneratorFileDictLoader implements DictLoaderInterface
|
||||
{
|
||||
/**
|
||||
* Data directory.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $path;
|
||||
|
||||
/**
|
||||
* Words segment name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $segmentName = 'words_%s';
|
||||
|
||||
/**
|
||||
* SplFileObjects.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $handles = [];
|
||||
|
||||
/**
|
||||
* surnames.
|
||||
*
|
||||
* @var SplFileObject
|
||||
*/
|
||||
protected static $surnamesHandle;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $path
|
||||
*/
|
||||
public function __construct($path)
|
||||
{
|
||||
$this->path = $path;
|
||||
|
||||
for ($i = 0; $i < 100; ++$i) {
|
||||
$segment = $this->path . '/' . sprintf($this->segmentName, $i);
|
||||
|
||||
if (file_exists($segment) && is_file($segment)) {
|
||||
array_push(static::$handles, $this->openFile($segment));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new file object.
|
||||
*
|
||||
* @param string $filename file path
|
||||
* @param string $mode file open mode
|
||||
*
|
||||
* @return SplFileObject
|
||||
*/
|
||||
protected function openFile($filename, $mode = 'r')
|
||||
{
|
||||
return new SplFileObject($filename, $mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* get Generator syntax.
|
||||
*
|
||||
* @param array $handles SplFileObjects
|
||||
*
|
||||
* @return Generator
|
||||
*/
|
||||
protected function getGenerator(array $handles)
|
||||
{
|
||||
foreach ($handles as $handle) {
|
||||
$handle->seek(0);
|
||||
while (false === $handle->eof()) {
|
||||
$string = str_replace(['\'', ' ', PHP_EOL, ','], '', $handle->fgets());
|
||||
|
||||
if (false === strpos($string, '=>')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
list($string, $pinyin) = explode('=>', $string);
|
||||
|
||||
yield $string => $pinyin;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Traverse the stream.
|
||||
*
|
||||
* @param Generator $generator
|
||||
* @param Closure $callback
|
||||
*
|
||||
* @author Seven Du <shiweidu@outlook.com>
|
||||
*/
|
||||
protected function traversing(Generator $generator, Closure $callback)
|
||||
{
|
||||
foreach ($generator as $string => $pinyin) {
|
||||
$callback([$string => $pinyin]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load dict.
|
||||
*
|
||||
* @param Closure $callback
|
||||
*/
|
||||
public function map(Closure $callback)
|
||||
{
|
||||
$this->traversing($this->getGenerator(static::$handles), $callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load surname dict.
|
||||
*
|
||||
* @param Closure $callback
|
||||
*/
|
||||
public function mapSurname(Closure $callback)
|
||||
{
|
||||
if (!static::$surnamesHandle instanceof SplFileObject) {
|
||||
static::$surnamesHandle = $this->openFile($this->path . '/surnames');
|
||||
}
|
||||
|
||||
$this->traversing($this->getGenerator([static::$surnamesHandle]), $callback);
|
||||
}
|
||||
}
|
@ -1,93 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the overtrue/pinyin.
|
||||
*
|
||||
* (c) overtrue <i@overtrue.me>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Overtrue\Pinyin;
|
||||
|
||||
use Closure;
|
||||
|
||||
class MemoryFileDictLoader implements DictLoaderInterface
|
||||
{
|
||||
/**
|
||||
* Data directory.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $path;
|
||||
|
||||
/**
|
||||
* Words segment name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $segmentName = 'words_%s';
|
||||
|
||||
/**
|
||||
* Segment files.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $segments = [];
|
||||
|
||||
/**
|
||||
* Surname cache.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $surnames = [];
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $path
|
||||
*/
|
||||
public function __construct($path)
|
||||
{
|
||||
$this->path = $path;
|
||||
|
||||
for ($i = 0; $i < 100; ++$i) {
|
||||
$segment = $path . '/' . sprintf($this->segmentName, $i);
|
||||
|
||||
if (file_exists($segment)) {
|
||||
$this->segments[] = (array) include $segment;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load dict.
|
||||
*
|
||||
* @param Closure $callback
|
||||
*/
|
||||
public function map(Closure $callback)
|
||||
{
|
||||
foreach ($this->segments as $dictionary) {
|
||||
$callback($dictionary);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load surname dict.
|
||||
*
|
||||
* @param Closure $callback
|
||||
*/
|
||||
public function mapSurname(Closure $callback)
|
||||
{
|
||||
if (empty($this->surnames)) {
|
||||
$surnames = $this->path . '/surnames';
|
||||
|
||||
if (file_exists($surnames)) {
|
||||
$this->surnames = (array) include $surnames;
|
||||
}
|
||||
}
|
||||
|
||||
$callback($this->surnames);
|
||||
}
|
||||
}
|
341
vendor/overtrue/pinyin/src/Pinyin.php
vendored
341
vendor/overtrue/pinyin/src/Pinyin.php
vendored
@ -1,341 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the overtrue/pinyin.
|
||||
*
|
||||
* (c) overtrue <i@overtrue.me>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Overtrue\Pinyin;
|
||||
|
||||
use InvalidArgumentException;
|
||||
|
||||
class Pinyin
|
||||
{
|
||||
/**
|
||||
* Dict loader.
|
||||
*
|
||||
* @var \Overtrue\Pinyin\DictLoaderInterface
|
||||
*/
|
||||
protected $loader;
|
||||
|
||||
/**
|
||||
* Punctuations map.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $punctuations = [
|
||||
',' => ',',
|
||||
'。' => '.',
|
||||
'!' => '!',
|
||||
'?' => '?',
|
||||
':' => ':',
|
||||
'“' => '"',
|
||||
'”' => '"',
|
||||
'‘' => "'",
|
||||
'’' => "'",
|
||||
'_' => '_',
|
||||
];
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $loaderName
|
||||
*/
|
||||
public function __construct($loaderName = null)
|
||||
{
|
||||
$this->loader = $loaderName ?: 'Overtrue\\Pinyin\\FileDictLoader';
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert string to pinyin.
|
||||
*
|
||||
* @param string $string
|
||||
* @param int $option
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function convert($string, $option = PINYIN_DEFAULT)
|
||||
{
|
||||
$pinyin = $this->romanize($string, $option);
|
||||
|
||||
return $this->splitWords($pinyin, $option);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert string (person name) to pinyin.
|
||||
*
|
||||
* @param string $stringName
|
||||
* @param int $option
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function name($stringName, $option = PINYIN_NAME)
|
||||
{
|
||||
$option = $option | PINYIN_NAME;
|
||||
|
||||
$pinyin = $this->romanize($stringName, $option);
|
||||
|
||||
return $this->splitWords($pinyin, $option);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a pinyin permalink from string.
|
||||
*
|
||||
* @param string $string
|
||||
* @param string $delimiter
|
||||
* @param int $option
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function permalink($string, $delimiter = '-', $option = PINYIN_DEFAULT)
|
||||
{
|
||||
if (\is_int($delimiter)) {
|
||||
list($option, $delimiter) = [$delimiter, '-'];
|
||||
}
|
||||
|
||||
if (!in_array($delimiter, ['_', '-', '.', ''], true)) {
|
||||
throw new InvalidArgumentException("Delimiter must be one of: '_', '-', '', '.'.");
|
||||
}
|
||||
|
||||
return implode($delimiter, $this->convert($string, $option | \PINYIN_KEEP_NUMBER | \PINYIN_KEEP_ENGLISH));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return first letters.
|
||||
*
|
||||
* @param string $string
|
||||
* @param string $delimiter
|
||||
* @param int $option
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function abbr($string, $delimiter = '', $option = PINYIN_DEFAULT)
|
||||
{
|
||||
if (\is_int($delimiter)) {
|
||||
list($option, $delimiter) = [$delimiter, ''];
|
||||
}
|
||||
|
||||
return implode($delimiter, array_map(function ($pinyin) {
|
||||
return \is_numeric($pinyin) || preg_match('/\d+/', $pinyin) ? $pinyin : mb_substr($pinyin, 0, 1);
|
||||
}, $this->convert($string, $option | PINYIN_NO_TONE)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Chinese phrase to pinyin.
|
||||
*
|
||||
* @param string $string
|
||||
* @param string $delimiter
|
||||
* @param int $option
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function phrase($string, $delimiter = ' ', $option = PINYIN_DEFAULT)
|
||||
{
|
||||
if (\is_int($delimiter)) {
|
||||
list($option, $delimiter) = [$delimiter, ' '];
|
||||
}
|
||||
|
||||
return implode($delimiter, $this->convert($string, $option));
|
||||
}
|
||||
|
||||
/**
|
||||
* Chinese to pinyin sentence.
|
||||
*
|
||||
* @param string $string
|
||||
* @param string $delimiter
|
||||
* @param int $option
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function sentence($string, $delimiter = ' ', $option = \PINYIN_NO_TONE)
|
||||
{
|
||||
if (\is_int($delimiter)) {
|
||||
list($option, $delimiter) = [$delimiter, ' '];
|
||||
}
|
||||
|
||||
return implode($delimiter, $this->convert($string, $option | \PINYIN_KEEP_PUNCTUATION | \PINYIN_KEEP_ENGLISH | \PINYIN_KEEP_NUMBER));
|
||||
}
|
||||
|
||||
/**
|
||||
* Loader setter.
|
||||
*
|
||||
* @param \Overtrue\Pinyin\DictLoaderInterface $loader
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setLoader(DictLoaderInterface $loader)
|
||||
{
|
||||
$this->loader = $loader;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return dict loader,.
|
||||
*
|
||||
* @return \Overtrue\Pinyin\DictLoaderInterface
|
||||
*/
|
||||
public function getLoader()
|
||||
{
|
||||
if (!($this->loader instanceof DictLoaderInterface)) {
|
||||
$dataDir = dirname(__DIR__) . '/data/';
|
||||
|
||||
$loaderName = $this->loader;
|
||||
$this->loader = new $loaderName($dataDir);
|
||||
}
|
||||
|
||||
return $this->loader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert Chinese to pinyin.
|
||||
*
|
||||
* @param string $string
|
||||
* @param int $option
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function romanize($string, $option = \PINYIN_DEFAULT)
|
||||
{
|
||||
$string = $this->prepare($string, $option);
|
||||
|
||||
$dictLoader = $this->getLoader();
|
||||
|
||||
if ($this->hasOption($option, \PINYIN_NAME)) {
|
||||
$string = $this->convertSurname($string, $dictLoader);
|
||||
}
|
||||
|
||||
$dictLoader->map(function ($dictionary) use (&$string) {
|
||||
$string = strtr($string, $dictionary);
|
||||
});
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert Chinese Surname to pinyin.
|
||||
*
|
||||
* @param string $string
|
||||
* @param \Overtrue\Pinyin\DictLoaderInterface $dictLoader
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function convertSurname($string, $dictLoader)
|
||||
{
|
||||
$dictLoader->mapSurname(function ($dictionary) use (&$string) {
|
||||
foreach ($dictionary as $surname => $pinyin) {
|
||||
if (0 === strpos($string, $surname)) {
|
||||
$string = $pinyin . mb_substr($string, mb_strlen($surname, 'UTF-8'), mb_strlen($string, 'UTF-8') - 1, 'UTF-8');
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Split pinyin string to words.
|
||||
*
|
||||
* @param string $pinyin
|
||||
* @param string $option
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function splitWords($pinyin, $option)
|
||||
{
|
||||
$split = array_filter(preg_split('/\s+/i', $pinyin));
|
||||
|
||||
if (!$this->hasOption($option, PINYIN_TONE)) {
|
||||
foreach ($split as $index => $pinyin) {
|
||||
$split[$index] = $this->formatTone($pinyin, $option);
|
||||
}
|
||||
}
|
||||
|
||||
return array_values($split);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $option
|
||||
* @param int $check
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasOption($option, $check)
|
||||
{
|
||||
return ($option & $check) === $check;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pre-process.
|
||||
*
|
||||
* @param string $string
|
||||
* @param int $option
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function prepare($string, $option = \PINYIN_DEFAULT)
|
||||
{
|
||||
$string = preg_replace_callback('~[a-z0-9_-]+~i', function ($matches) {
|
||||
return "\t" . $matches[0];
|
||||
}, $string);
|
||||
|
||||
$regex = ['\p{Han}', '\p{Z}', '\p{M}', "\t"];
|
||||
|
||||
if ($this->hasOption($option, \PINYIN_KEEP_NUMBER)) {
|
||||
\array_push($regex, '0-9');
|
||||
}
|
||||
|
||||
if ($this->hasOption($option, \PINYIN_KEEP_ENGLISH)) {
|
||||
\array_push($regex, 'a-zA-Z');
|
||||
}
|
||||
|
||||
if ($this->hasOption($option, \PINYIN_KEEP_PUNCTUATION)) {
|
||||
$punctuations = array_merge($this->punctuations, ["\t" => ' ', ' ' => ' ']);
|
||||
$string = trim(str_replace(array_keys($punctuations), $punctuations, $string));
|
||||
|
||||
\array_push($regex, preg_quote(implode(array_merge(array_keys($this->punctuations), $this->punctuations)), '~'));
|
||||
}
|
||||
|
||||
return preg_replace(\sprintf('~[^%s]~u', implode($regex)), '', $string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format.
|
||||
*
|
||||
* @param string $pinyin
|
||||
* @param int $option
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function formatTone($pinyin, $option = \PINYIN_NO_TONE)
|
||||
{
|
||||
$replacements = [
|
||||
'üē' => ['ue', 1], 'üé' => ['ue', 2], 'üě' => ['ue', 3], 'üè' => ['ue', 4],
|
||||
'ā' => ['a', 1], 'ē' => ['e', 1], 'ī' => ['i', 1], 'ō' => ['o', 1], 'ū' => ['u', 1], 'ǖ' => ['yu', 1],
|
||||
'á' => ['a', 2], 'é' => ['e', 2], 'í' => ['i', 2], 'ó' => ['o', 2], 'ú' => ['u', 2], 'ǘ' => ['yu', 2],
|
||||
'ǎ' => ['a', 3], 'ě' => ['e', 3], 'ǐ' => ['i', 3], 'ǒ' => ['o', 3], 'ǔ' => ['u', 3], 'ǚ' => ['yu', 3],
|
||||
'à' => ['a', 4], 'è' => ['e', 4], 'ì' => ['i', 4], 'ò' => ['o', 4], 'ù' => ['u', 4], 'ǜ' => ['yu', 4],
|
||||
];
|
||||
|
||||
foreach ($replacements as $unicode => $replacement) {
|
||||
if (false !== strpos($pinyin, $unicode)) {
|
||||
$umlaut = $replacement[0];
|
||||
|
||||
// https://zh.wikipedia.org/wiki/%C3%9C
|
||||
if ($this->hasOption($option, \PINYIN_UMLAUT_V) && 'yu' == $umlaut) {
|
||||
$umlaut = 'v';
|
||||
}
|
||||
|
||||
$pinyin = str_replace($unicode, $umlaut, $pinyin) . ($this->hasOption($option, PINYIN_ASCII_TONE) ? $replacement[1] : '');
|
||||
}
|
||||
}
|
||||
|
||||
return $pinyin;
|
||||
}
|
||||
}
|
20
vendor/overtrue/pinyin/src/const.php
vendored
20
vendor/overtrue/pinyin/src/const.php
vendored
@ -1,20 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the overtrue/pinyin.
|
||||
*
|
||||
* (c) overtrue <i@overtrue.me>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
define('PINYIN_DEFAULT', 4096);
|
||||
define('PINYIN_TONE', 2);
|
||||
define('PINYIN_NO_TONE', 4);
|
||||
define('PINYIN_ASCII_TONE', 8);
|
||||
define('PINYIN_NAME', 16);
|
||||
define('PINYIN_KEEP_NUMBER', 32);
|
||||
define('PINYIN_KEEP_ENGLISH', 64);
|
||||
define('PINYIN_UMLAUT_V', 128);
|
||||
define('PINYIN_KEEP_PUNCTUATION', 256);
|
2
vendor/services.php
vendored
2
vendor/services.php
vendored
@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// This file is automatically generated at:2022-08-10 16:58:09
|
||||
// This file is automatically generated at:2022-08-15 14:50:32
|
||||
declare (strict_types = 1);
|
||||
return array (
|
||||
0 => 'taoser\\addons\\Service',
|
||||
|
@ -99,17 +99,20 @@
|
||||
<textarea name="description" class="layui-textarea" placeholder="SEO描述"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
{//关键词}
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-inline">
|
||||
<label class="layui-form-label">{:lang('add tags')}</label>
|
||||
<div class="layui-input-inline" style="width: 190px">
|
||||
<input type="text" class="layui-input" name="tags" value="" placeholder="多个用空格隔开" title="添加标签" />
|
||||
<label class="layui-form-label">{:lang('添加关键词')}</label>
|
||||
<div class="layui-input-block">
|
||||
<!-- <input type="text" class="layui-input" name="" id="inputTags" value="" placeholder="多个回车添加" title="添加关键词" /> -->
|
||||
<input type="text" class="layui-input" name="keywords" value="" placeholder="多个用逗号隔开" title="添加关键词" />
|
||||
</div>
|
||||
<button type="button" class="layui-btn" id="article-tags-button">{:lang('add')}</button>
|
||||
</div>
|
||||
</div>
|
||||
{//tag}
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-btn-container"></div>
|
||||
<label class="layui-form-label">{:lang('add tags')}</label>
|
||||
<div class="layui-input-block">
|
||||
<div id="tag"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--div class="layui-form-item">
|
||||
@ -132,25 +135,10 @@
|
||||
<div class="layui-form-item">
|
||||
<label for="L_vercode" class="layui-form-label">{:lang('captcha')}</label>
|
||||
<div class="layui-input-inline">
|
||||
<input
|
||||
type="text"
|
||||
id="L_vercode"
|
||||
name="captcha"
|
||||
required
|
||||
lay-verify="required"
|
||||
placeholder="{:lang('please input the captcha')}"
|
||||
autocomplete="off"
|
||||
class="layui-input"
|
||||
/>
|
||||
<input type="text" id="L_vercode" name="captcha" required lay-verify="required" placeholder="{:lang('please input the captcha')}" autocomplete="off" class="layui-input" />
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux" style="padding-top: 0px !important">
|
||||
<img
|
||||
id="captcha"
|
||||
src="{:captcha_src()}"
|
||||
onclick="this.src='{:captcha_src()}?'+Math.random();"
|
||||
style="float: left; cursor: pointer"
|
||||
alt="captcha"
|
||||
/>
|
||||
<img id="captcha" src="{:captcha_src()}" onclick="this.src='{:captcha_src()}?'+Math.random();" style="float: left; cursor: pointer" alt="captcha" />
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
@ -170,8 +158,9 @@
|
||||
|
||||
{block name="script"}
|
||||
{:hook('taonyeditor')}
|
||||
<script src="/static/xm-select.js"></script>
|
||||
<script>
|
||||
layui.use(["fly", "form", "colorpicker", "upload", "plyr"], function () {
|
||||
layui.use(["fly", "plyr",'inputTags'], function () {
|
||||
var $ = layui.jquery,
|
||||
fly = layui.fly,
|
||||
form = layui.form,
|
||||
@ -179,94 +168,68 @@
|
||||
upload = layui.upload,
|
||||
plyr = layui.plyr;
|
||||
|
||||
// 改变标题颜色
|
||||
colorpicker.render({
|
||||
elem: "#color",
|
||||
color: "#393d49",
|
||||
predefine: true, // 开启预定义颜色
|
||||
done: function (color) {
|
||||
//譬如你可以在回调中把得到的 color 赋值给表单
|
||||
$("#L_title_color").val(color);
|
||||
$("#L_title").css("color", color);
|
||||
},
|
||||
});
|
||||
|
||||
//上传附件
|
||||
upload.render({
|
||||
elem: "#zip-button",
|
||||
url: "{:url('article/uploads')}", //改成您自己的上传接口
|
||||
data: { type: "zip" },
|
||||
accept: "file", //普通文件
|
||||
done: function (res) {
|
||||
if (res.status == 0) {
|
||||
$('input[name="upzip"]').val(res.url);
|
||||
layer.msg("上传成功");
|
||||
} else {
|
||||
layer.msg(res.msg);
|
||||
//如果你是采用模版自带的编辑器,你需要开启以下语句来解析。
|
||||
var taonystatus = "{:hook('taonystatus')}";
|
||||
// 编辑器插件启用状态
|
||||
var isShow = taonystatus ? false : true;
|
||||
if(isShow) {
|
||||
$('.layui-textarea').each(function(){
|
||||
var othis = $(this), html = othis.html();
|
||||
othis.attr(fly.content(html));
|
||||
})
|
||||
}
|
||||
|
||||
var inputTags = layui.inputTags;
|
||||
//关键词
|
||||
inputTags.render({
|
||||
elem:'#inputTags',
|
||||
content: [],
|
||||
aldaBtn: false,
|
||||
done: function(value){
|
||||
//console.log(value)
|
||||
var keywords = this.content.join(',');
|
||||
$("input[name='keywords']").val(keywords);
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
//1.渲染标签
|
||||
var addTags = xmSelect.render({
|
||||
el: '#tag',
|
||||
name: 'tagid',
|
||||
layVerify: 'required',
|
||||
layVerType: 'msg',
|
||||
paging: true,
|
||||
pageSize: 5,
|
||||
data: []
|
||||
});
|
||||
//2.动态标签赋值
|
||||
$.get("{:url('get_all_tag')}",function(res){
|
||||
if(res.code == 0){
|
||||
addTags.update({
|
||||
data: res.data,
|
||||
autoRow: true,
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
// 发布文章
|
||||
form.on("submit(article-add)", function (data) {
|
||||
var field = data.field;
|
||||
var numArr = new Array();
|
||||
$(".layui-btn-container").children("button").each(function () {
|
||||
numArr.push($(this).val()); //添加至数组
|
||||
});
|
||||
field.tags = numArr.lenth ? "" : numArr.join(",");
|
||||
|
||||
var index = layer.load(1);
|
||||
$.ajax({
|
||||
type: "post",
|
||||
url: "{:url('article/add')}",
|
||||
data: field,
|
||||
dataType: "json",
|
||||
success: function (data) {
|
||||
if (data.code == 0) {
|
||||
layer.msg(data.msg, { icon: 6, time: 2000 }, function () {
|
||||
location.href = data.url;
|
||||
});
|
||||
} else {
|
||||
layer.open({ title: "发布失败", content: data.msg, icon: 5, anim: 6 });
|
||||
layui.jquery("#captcha").attr("src", "{:captcha_src()}?" + Math.random());
|
||||
}
|
||||
layer.close(index);
|
||||
},
|
||||
});
|
||||
return false;
|
||||
});
|
||||
|
||||
// 从详情页自动调用端口过滤,获取描述信息
|
||||
$("#L_content").mouseleave(function() {
|
||||
var content = $(this).val().replace(/[\r\n]/g,"").replace(/\n/g, '').replace(/\s/g, '').replace(/\t/g, '');
|
||||
$.post("{:url('article/getDescription')}", { content: content }, function(data){
|
||||
if (data.code == 0) {
|
||||
$('[name="description"]').val(data.data);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// 手动添加tags
|
||||
$("#article-tags-button").on("click", function () {
|
||||
var tags = $("input[name='tags']").val();
|
||||
var flag = "off";
|
||||
getTags(tags, flag);
|
||||
});
|
||||
|
||||
// 获取tag的内容
|
||||
// 通过标题内容自动获取tag的内容
|
||||
var conf = "{:empty(config('taoler.baidu.client_id'))}";
|
||||
if (conf !== "1") {
|
||||
$("#L_title").on("blur", function () {
|
||||
var title = $(this).val();
|
||||
var flag = "on";
|
||||
// 清空上次生成的tag button
|
||||
$(".layui-btn-container")
|
||||
.children("button")
|
||||
.each(function () {
|
||||
$(this).remove();
|
||||
});
|
||||
getTags(title, flag);
|
||||
$.ajax({
|
||||
type: "post",
|
||||
url: "{:url('article/keywords')}",
|
||||
data: { keywords: keywords, flag: flag },
|
||||
daType: "json",
|
||||
success: function (res) {
|
||||
if (res.code == 0) {
|
||||
$("input[name='keywords']").val(res.data);
|
||||
}
|
||||
},
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
@ -304,53 +267,74 @@
|
||||
$(".bdsug").addClass('layui-hide');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 添加关键词button
|
||||
function getTags(tags, flag)
|
||||
{
|
||||
if (tags == "") {
|
||||
layer.msg("tag不能为空");
|
||||
return false;
|
||||
}
|
||||
|
||||
//把得到的tags放进数组
|
||||
var numArr = new Array();
|
||||
$(".layui-btn-container")
|
||||
.children("button")
|
||||
.each(function () {
|
||||
numArr.push($(this).val()); //添加至数组
|
||||
});
|
||||
|
||||
$.ajax({
|
||||
type: "post",
|
||||
url: "{:url('article/tags')}",
|
||||
data: { tags: tags, flag: flag },
|
||||
daType: "json",
|
||||
success: function (data) {
|
||||
if (data.code == 0) {
|
||||
for (var i = 0; i < data.data.length; i++) {
|
||||
if ($.inArray(data.data[i], numArr) < 0) {
|
||||
$(".layui-btn-container").append(
|
||||
'<button type="button" class="layui-btn layui-btn-sm layui-btn-danger" value=' + data.data[i] + ">" + data.data[i] + " x" + "</button>"
|
||||
);
|
||||
}
|
||||
}
|
||||
$("input[name='tags']").val("");
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// 删除tag
|
||||
$(document).ready(function () {
|
||||
$(".layui-btn-container").on("click", "button", function () {
|
||||
$(this).remove();
|
||||
// 从详情页自动调用端口过滤,获取描述信息
|
||||
$("#L_content").mouseleave(function() {
|
||||
var content = $(this).val().replace(/[\r\n]/g,"").replace(/\n/g, '').replace(/\s/g, '').replace(/\t/g, '');
|
||||
$.post("{:url('article/getDescription')}", { content: content }, function(data){
|
||||
if (data.code == 0) {
|
||||
$('[name="description"]').val(data.data);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// 改变标题颜色
|
||||
colorpicker.render({
|
||||
elem: "#color",
|
||||
color: "#393d49",
|
||||
predefine: true, // 开启预定义颜色
|
||||
done: function (color) {
|
||||
//譬如你可以在回调中把得到的 color 赋值给表单
|
||||
$("#L_title_color").val(color);
|
||||
$("#L_title").css("color", color);
|
||||
},
|
||||
});
|
||||
|
||||
// 发布文章
|
||||
form.on("submit(article-add)", function (data) {
|
||||
var field = data.field;
|
||||
console.log(field)
|
||||
var index = layer.load(1);
|
||||
$.ajax({
|
||||
type: "post",
|
||||
url: "{:url('article/add')}",
|
||||
data: field,
|
||||
dataType: "json",
|
||||
success: function (data) {
|
||||
if (data.code == 0) {
|
||||
layer.msg(data.msg, { icon: 6, time: 2000 }, function () {
|
||||
location.href = data.url;
|
||||
});
|
||||
} else {
|
||||
layer.open({ title: "发布失败", content: data.msg, icon: 5, anim: 6 });
|
||||
l$("#captcha").attr("src", "{:captcha_src()}?" + Math.random());
|
||||
}
|
||||
layer.close(index);
|
||||
},
|
||||
});
|
||||
return false;
|
||||
});
|
||||
|
||||
//上传附件
|
||||
upload.render({
|
||||
elem: "#zip-button",
|
||||
url: "{:url('article/uploads')}",
|
||||
data: { type: "zip" },
|
||||
accept: "file", //普通文件
|
||||
done: function (res) {
|
||||
if (res.status == 0) {
|
||||
$('input[name="upzip"]').val(res.url);
|
||||
layer.msg("上传成功");
|
||||
} else {
|
||||
layer.msg(res.msg);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
//加载播放器
|
||||
plyr.setup();
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
|
@ -84,7 +84,7 @@
|
||||
<div class="fly-panel-main">
|
||||
<ul>
|
||||
{volist name="hotTag" id="vo"}
|
||||
<li style="padding:10px;display:inline-block;height: 15px;"><a href="{$Request.domain}{$vo.url}">{$vo.tag}</a></li>
|
||||
<li style="padding:10px;display:inline-block;height: 15px;"><a href="{$Request.domain}{$vo.url}">{$vo.name}</a></li>
|
||||
{/volist}
|
||||
</ul>
|
||||
</div>
|
||||
|
@ -1,6 +1,6 @@
|
||||
{extend name="public/base" /}
|
||||
{block name="title"}{$article.title} - {$sysInfo.webname}{/block}
|
||||
{block name="keywords"}{$article.tags ?: $article.title}{/block}
|
||||
{block name="keywords"}{$article.keywords ?: $article.title}{/block}
|
||||
{block name="description"}{$article.title},{$article.description ?? ''}{/block}
|
||||
{block name="ogtitle"}<meta property="og:title" content="{$article.title} - {$sysInfo.webname}"/>{/block}
|
||||
{block name="ogdescription"}<meta property="og:description" content="{$article.title},{$article.description ?? ''}" />{/block}
|
||||
@ -46,13 +46,10 @@
|
||||
<div class="detail-body-wenda photos" id="content">{$article.content|raw}</div>
|
||||
|
||||
<div style="margin-top: 25px">本文链接:<a href="{$Request.domain}{$Request.url}">{$Request.domain}{$Request.url}</a></div>
|
||||
<div style="margin-top: 15px">
|
||||
<h3>关键词</h3>
|
||||
<div class="layui-btn-container" style="padding-top: 15px">
|
||||
{volist name="tags" id="vo" }
|
||||
<a href="{:url('tag_list',['tag'=>$vo.pinyin])}"><span class="layui-btn layui-btn-sm layui-btn-radius layui-btn-danger">{$vo.tag}</span></a>
|
||||
{/volist}
|
||||
</div>
|
||||
<div style="margin-top: 15px">标签
|
||||
{volist name="tags" id="vo" }
|
||||
<a href="{$vo.url}"><span class="layui-btn layui-btn-xs layui-btn-normal layui-btn-radius">{$vo.name}</span></a>
|
||||
{/volist}
|
||||
</div>
|
||||
<div style="margin: 20px 0px 15px 0px; color: rgb(130, 125, 125)">
|
||||
<p>{$sysInfo.state}</p>
|
||||
|
@ -1,7 +1,16 @@
|
||||
{extend name="public/base" /}
|
||||
{block name="title"}{$sysInfo.webname}{/block}
|
||||
{block name="keywords"}{$Request.param.ename|getCateName},{$sysInfo.webname}{/block}
|
||||
{block name="description"}{$sysInfo.webname}{$Request.param.ename|getCateDesc}{/block}
|
||||
{block name="keywords"}{$sysInfo.keywords}{/block}
|
||||
{block name="description"}{$sysInfo.descript}{/block}
|
||||
{block name="ogtitle"}<meta property="og:title" content="{$sysInfo.webtitle}" />{/block}
|
||||
{block name="ogdescription"}<meta property="og:description" content="{$sysInfo.descript}" />{/block}
|
||||
{block name="ogimage"}<meta property="og:image" content="{$Request.domain}{$sysInfo.logo}" />{/block}
|
||||
{block name="meta"}
|
||||
<!-- SEO优化 -->
|
||||
<meta name="Copyright" content="{$sysInfo.webname}">
|
||||
<meta property="og:type" content="website"/>
|
||||
<meta property="og:image" content=""/>
|
||||
{/block}
|
||||
{block name="column"}{include file="/public/column" /}{/block}
|
||||
|
||||
{block name="content"}
|
||||
@ -68,11 +77,11 @@
|
||||
<dl class="fly-panel fly-list-one layui-hide-xs">
|
||||
<dt class="fly-panel-title">{:lang('hot post list')}</dt>
|
||||
{volist name="artHot" id="vo"}
|
||||
<dd>
|
||||
<dd>
|
||||
<a href="{$Request.domain}{$vo.url}">{$vo.title}</a>
|
||||
<span><i class="iconfont icon-pinglun1"></i> {$vo.comments_count}</span>
|
||||
</dd>
|
||||
{/volist}
|
||||
{/volist}
|
||||
</dl>
|
||||
{if showSlider(6)}
|
||||
<div class="fly-panel">
|
||||
@ -105,9 +114,9 @@
|
||||
//获取起始页
|
||||
,jump: function(obj, first){
|
||||
//首次不执行
|
||||
if(!first){
|
||||
window.location.href = '{$path}/'+ obj.curr +'.html'; //跳转
|
||||
}
|
||||
if(!first){
|
||||
window.location.href = '{$path}/'+ obj.curr +'.html'; //跳转
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -1,7 +1,7 @@
|
||||
{extend name="public/base" /}
|
||||
|
||||
{block name="title"}编辑帖子{/block}
|
||||
{block name="link"}<link rel="stylesheet" href="{$Request.domain}/static/res/css/plyr.css" charset="utf-8">{/block}
|
||||
{block name="link"}<link rel="stylesheet" href="/static/res/css/plyr.css" charset="utf-8">{/block}
|
||||
{block name="column"}{/block}
|
||||
{block name="content"}
|
||||
<div class="layui-container fly-marginTop">
|
||||
@ -106,22 +106,22 @@
|
||||
<textarea name="description" class="layui-textarea" placeholder="SEO描述">{$article.description}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
{//关键词}
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-inline">
|
||||
<label class="layui-form-label">{:lang('add tags')}</label>
|
||||
<div class="layui-input-inline" style="width: 190px;">
|
||||
<input type="text" class="layui-input" name="tags" placeholder="多个用空格隔开" title="添加标签"/>
|
||||
<label class="layui-form-label">{:lang('添加关键词')}</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" class="layui-input" name="keywords" value="{$article.keywords}" placeholder="多个英文逗号隔开" title="添加关键词" />
|
||||
</div>
|
||||
<button type="button" class="layui-btn" id="article-tags-button">{:lang('add')}</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{//tag}
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-btn-container">
|
||||
{volist name="tags" id="vo" }
|
||||
<button type="button" class="layui-btn layui-btn-sm layui-btn-danger" value="{$vo}">{$vo} x</button>
|
||||
{/volist}
|
||||
</div>
|
||||
<label class="layui-form-label">{:lang('add tags')}</label>
|
||||
<div class="layui-input-block">
|
||||
<div id="tag"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{if config('taoler.config.post_captcha') == 1}
|
||||
<div class="layui-form-item">
|
||||
<label for="L_vercode" class="layui-form-label">{:lang('captcha')}</label>
|
||||
@ -148,8 +148,40 @@
|
||||
|
||||
{block name="script"}
|
||||
{:hook('taonyeditor')}
|
||||
<script src="/static/xm-select.js"></script>
|
||||
<script>
|
||||
layui.use(['fly','colorpicker','form','upload','plyr'], function(){
|
||||
var artId = "{$article.id}";
|
||||
|
||||
//1.渲染标签
|
||||
var addTags = xmSelect.render({
|
||||
el: '#tag',
|
||||
name: 'tagid',
|
||||
layVerify: 'required',
|
||||
layVerType: 'msg',
|
||||
paging: true,
|
||||
pageSize: 5,
|
||||
data: []
|
||||
});
|
||||
//2.动态赋值
|
||||
$.get("{:url('get_art_tag')}",{id:artId},function(res){
|
||||
if(res.code == 0){
|
||||
addTags.setValue(
|
||||
res.data
|
||||
)
|
||||
}
|
||||
});
|
||||
//3.动态标签赋值
|
||||
$.get("{:url('get_all_tag')}",function(res){
|
||||
if(res.code == 0){
|
||||
addTags.update({
|
||||
data: res.data,
|
||||
autoRow: true,
|
||||
})
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
layui.use(['fly','plyr'], function(){
|
||||
var $ = layui.jquery
|
||||
,fly = layui.fly
|
||||
,colorpicker = layui.colorpicker
|
||||
@ -157,6 +189,18 @@
|
||||
,upload = layui.upload
|
||||
,plyr = layui.plyr;
|
||||
|
||||
|
||||
//如果你是采用模版自带的编辑器,你需要开启以下语句来解析。
|
||||
var taonystatus = "{:hook('taonystatus')}";
|
||||
// 编辑器插件启用状态
|
||||
var isShow = taonystatus ? false : true;
|
||||
if(isShow) {
|
||||
$('.layui-textarea').each(function(){
|
||||
var othis = $(this), html = othis.html();
|
||||
othis.attr(fly.content(html));
|
||||
})
|
||||
}
|
||||
|
||||
//预定义颜色项
|
||||
colorpicker.render({
|
||||
elem: '#color'
|
||||
@ -170,32 +214,46 @@
|
||||
$('#L_title').css("color", color);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
//指定允许上传的文件类型
|
||||
upload.render({
|
||||
elem: '#zip-button'
|
||||
,url: "{:url('article/uploads')}" //改成您自己的上传接口
|
||||
,data: {type:'zip'}
|
||||
,accept: 'file' //普通文件
|
||||
,done: function(res){
|
||||
if(res.status == 0){
|
||||
$('input[name="upzip"]').val(res.url);
|
||||
layer.msg('上传成功');
|
||||
} else {
|
||||
layer.msg(res.msg);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
//编辑文章
|
||||
// 获取描述的内容
|
||||
$("#L_content").bind('input propertychange', function(){
|
||||
var content = $(this).val()
|
||||
$.ajax({
|
||||
type:"post",
|
||||
url:"{:url('article/getDescription')}",
|
||||
data:{"content":content},
|
||||
daType:"json",
|
||||
success:function (data){
|
||||
if (data.code == 0) {
|
||||
$('[name="description"]').val(data.data);
|
||||
}
|
||||
}
|
||||
});
|
||||
return false;
|
||||
})
|
||||
|
||||
// 获取百度获取的关键词内容
|
||||
var conf = "{:empty(config('taoler.baidu.client_id'))}";
|
||||
if(conf !== '1'){
|
||||
$("#L_title").on('blur', function(){
|
||||
var title = $(this).val();
|
||||
var flag = 'on';
|
||||
$.ajax({
|
||||
type:"post",
|
||||
url:"{:url('article/keywords')}",
|
||||
data:{"keywords":keywords,"flag":flag},
|
||||
daType:"json",
|
||||
success:function (data){
|
||||
$("input[name='keywords']").val(res.data);
|
||||
}
|
||||
});
|
||||
return false;
|
||||
})
|
||||
}
|
||||
|
||||
//编辑文章
|
||||
form.on('submit(article-edit)', function(data){
|
||||
var field = data.field;
|
||||
var numArr = new Array();
|
||||
$('.layui-btn-container').children('button').each(function(){
|
||||
numArr.push($(this).val());//添加至数组
|
||||
});
|
||||
field.tags = numArr.lenth ? '' : numArr.join(',');
|
||||
$.ajax({
|
||||
type:"post",
|
||||
url:"{:url('article/edit')}",
|
||||
@ -215,88 +273,22 @@
|
||||
return false;
|
||||
});
|
||||
|
||||
// 获取描述的内容
|
||||
$("#L_content").bind('input propertychange', function(){
|
||||
var content = $(this).val()
|
||||
$.ajax({
|
||||
type:"post",
|
||||
url:"{:url('article/getDescription')}",
|
||||
data:{"content":content},
|
||||
daType:"json",
|
||||
success:function (data){
|
||||
if (data.code == 0) {
|
||||
$('[name="description"]').val(data.data);
|
||||
}
|
||||
}
|
||||
});
|
||||
return false;
|
||||
})
|
||||
//指定允许上传的文件类型
|
||||
upload.render({
|
||||
elem: '#zip-button'
|
||||
,url: "{:url('article/uploads')}" //改成您自己的上传接口
|
||||
,data: {type:'zip'}
|
||||
,accept: 'file' //普通文件
|
||||
,done: function(res){
|
||||
if(res.status == 0){
|
||||
$('input[name="upzip"]').val(res.url);
|
||||
layer.msg('上传成功');
|
||||
} else {
|
||||
layer.msg(res.msg);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 手动添加tags
|
||||
$('#article-tags-button').on('click',function(){
|
||||
var tags = $("input[name='tags']").val();
|
||||
var flag = 'off';
|
||||
getTags(tags,flag);
|
||||
});
|
||||
|
||||
// 获取tag的内容
|
||||
var conf = "{:empty(config('taoler.baidu.client_id'))}";
|
||||
if(conf !== '1'){
|
||||
$("#L_title").on('blur', function(){
|
||||
var title = $(this).val();
|
||||
var flag = 'on';
|
||||
// 清空上次生成的tag button
|
||||
$('.layui-btn-container').children('button').each(function(){
|
||||
$(this).remove();
|
||||
});
|
||||
getTags(title,flag);
|
||||
})
|
||||
}
|
||||
|
||||
// 循环添加button
|
||||
function getTags(tags,flag)
|
||||
{
|
||||
if(tags == ''){
|
||||
layer.msg('不能为空');
|
||||
return false;
|
||||
}
|
||||
//把得到的tags放进数组
|
||||
var numArr = new Array();
|
||||
$('.layui-btn-container').children('button').each(function(){
|
||||
numArr.push($(this).val());//添加至数组
|
||||
});
|
||||
|
||||
$.ajax({
|
||||
type:"post",
|
||||
url:"{:url('article/tags')}",
|
||||
data:{"tags":tags,"flag":flag},
|
||||
daType:"json",
|
||||
success:function (data){
|
||||
if (data.code == 0) {
|
||||
for(var i=0; i<data.data.length; i++){
|
||||
if($.inArray(data.data[i],numArr) < 0){
|
||||
$('.layui-btn-container').append('<button type="button" class="layui-btn layui-btn-sm layui-btn-danger" value='+data.data[i]+'>'+data.data[i]+' x'+'</button>');
|
||||
}
|
||||
}
|
||||
$("input[name='tags']").val("");
|
||||
}
|
||||
}
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
//删除tag
|
||||
$(document).ready(function(){
|
||||
$('.layui-btn-container').on('click','button',function(){
|
||||
$(this).remove();
|
||||
});
|
||||
});
|
||||
|
||||
//如果你是采用模版自带的编辑器,你需要开启以下语句来解析。
|
||||
$('.layui-textarea').each(function(){
|
||||
var othis = $(this), html = othis.html();
|
||||
othis.attr(fly.content(html));
|
||||
})
|
||||
//加载播放器
|
||||
plyr.setup();
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{extend name="public/base" /}
|
||||
{block name="title"}{$article.title} - {$sysInfo.webname}{/block}
|
||||
{block name="keywords"}{$article.tags ?: $article.title}{/block}
|
||||
{block name="keywords"}{$article.keywords ?: $article.title}{/block}
|
||||
{block name="description"}{$article.title},{$article.description ?? ''}{/block}
|
||||
{block name="ogtitle"}<meta property="og:title" content="{$article.title} - {$sysInfo.webname}">{/block}
|
||||
{block name="ogdescription"}<meta property="og:description" content="{$article.title},{$article.description ?? ''}" />{/block}
|
||||
@ -33,14 +33,11 @@
|
||||
{// 内容}
|
||||
<div class="detail-body photos" style="font-size: 18px;line-height: 200%;" id="content">{$article.content|raw}</div>
|
||||
<div style="margin-top: 25px;">本文链接:<a href="{$Request.domain}{$Request.url}">{$Request.domain}{$Request.url}</a></div>
|
||||
<div style="margin-top: 15px">
|
||||
<h2>关键词</h2>
|
||||
<div class="layui-btn-container" style="padding-top: 15px;">
|
||||
{volist name="tags" id="vo" }
|
||||
<a href="{$vo.url}"><span class="layui-btn layui-btn-sm layui-btn-radius layui-btn-danger">{$vo.tag}</span></a>
|
||||
{/volist}
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-top: 15px">标签
|
||||
{volist name="tags" id="vo" }
|
||||
<a href="{$vo.url}"><span class="layui-btn layui-btn-xs layui-btn-normal layui-btn-radius">{$vo.name}</span></a>
|
||||
{/volist}
|
||||
</div>
|
||||
<div style="margin: 20px 0px 15px 0px; color: rgb(130, 125, 125);">
|
||||
<p>{$sysInfo.state}</p>
|
||||
</div>
|
||||
|
@ -85,7 +85,7 @@
|
||||
<div class="fly-panel-main">
|
||||
<ul>
|
||||
{volist name="hotTag" id="vo"}
|
||||
<li style="padding:10px;display:inline-block;height: 15px;"><a href="{$Request.domain}{$vo.url}">{$vo.tag}</a></li>
|
||||
<li style="padding:10px;display:inline-block;height: 15px;"><a href="{$Request.domain}{$vo.url}">{$vo.name}</a></li>
|
||||
{/volist}
|
||||
</ul>
|
||||
</div>
|
||||
|
@ -1,7 +1,7 @@
|
||||
{extend name="public/base" /}
|
||||
|
||||
{block name="title"}{$article.title} - {$sysInfo.webname}{/block}
|
||||
{block name="keywords"}{$article.tags ?: $article.title}{/block}
|
||||
{block name="keywords"}{$article.keywords ?: $article.title}{/block}
|
||||
{block name="description"}{$article.title},{$article.description}{/block}
|
||||
{block name="ogtitle"}<meta property="og:title" content="{$article.title} - {$sysInfo.webname}">{/block}
|
||||
{block name="ogdescription"}<meta property="og:description" content="{$article.title},{$article.description ?? ''}" />{/block}
|
||||
@ -55,14 +55,11 @@
|
||||
{// 内容}
|
||||
<div class="detail-body photos mce-content-body" id="content">{$article.content|raw}</div>
|
||||
<div style="margin-top: 25px;">本文链接:<a href="{$Request.domain}{$Request.url}">{$Request.domain}{$Request.url}</a></div>
|
||||
<div style="margin-top: 15px">
|
||||
<h2>关键词</h2>
|
||||
<div class="layui-btn-container" style="padding-top: 15px;">
|
||||
{volist name="tags" id="vo" }
|
||||
<a href="{$vo.url}"><span class="layui-btn layui-btn-sm layui-btn-radius layui-btn-danger">{$vo.tag}</span></a>
|
||||
{/volist}
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-top: 15px">标签
|
||||
{volist name="tags" id="vo" }
|
||||
<a href="{$vo.url}"><span class="layui-btn layui-btn-xs layui-btn-normal layui-btn-radius">{$vo.name}</span></a>
|
||||
{/volist}
|
||||
</div>
|
||||
<div style="margin: 20px 0px 15px 0px; color: rgb(130, 125, 125);">
|
||||
<p>{$sysInfo.state}</p>
|
||||
</div>
|
||||
|
@ -1,14 +1,19 @@
|
||||
<!--
|
||||
* @Author: TaoLer <alipay_tao@qq.com>
|
||||
* @Date: 2021-12-06 16:04:51
|
||||
* @LastEditTime: 2022-07-26 11:42:58
|
||||
* @LastEditTime: 2022-08-15 14:56:31
|
||||
* @LastEditors: TaoLer
|
||||
* @Description: 搜索引擎SEO优化设置
|
||||
* @FilePath: \github\TaoLer\view\taoler\index\tag\index.html
|
||||
* @FilePath: \TaoLer\view\taoler\index\tag\index.html
|
||||
* Copyright (c) 2020~2022 https://www.aieok.com All rights reserved.
|
||||
-->
|
||||
{extend name="public/base" /}
|
||||
{block name="title"}{$sysInfo.webname}Tag内容{/block}
|
||||
{block name="title"}{$tag} - {$sysInfo.webname}{/block}
|
||||
{block name="keywords"}{$tag},{$sysInfo.keywords}{/block}
|
||||
{block name="description"}{$tag},{$sysInfo.descript}{/block}
|
||||
{block name="ogtitle"}<meta property="og:title" content="{$tag} - {$sysInfo.webtitle}" />{/block}
|
||||
{block name="ogdescription"}<meta property="og:description" content="{$tag},{$sysInfo.descript}" />{/block}
|
||||
{block name="ogimage"}<meta property="og:image" content="{$Request.domain}{$sysInfo.logo}" />{/block}
|
||||
{block name="column"}{include file="public/column" /}{/block}
|
||||
{block name="content"}
|
||||
<div class="layui-container">
|
||||
@ -29,7 +34,6 @@
|
||||
{/if}
|
||||
<a href="{$Request.domain}{:url('user_home',['id'=>$art.user_id])}" link><cite>{$art.user.name}</cite></a>
|
||||
<span>{$art.create_time|date='Y-m-d'}</span>
|
||||
<span class="fly-list-nums"><i class="iconfont icon-pinglun1" title="回答"></i>{$art.comments_count}</span>
|
||||
</div>
|
||||
{if ($art.is_hot == 1)}
|
||||
<div class="fly-list-badge"><span class="layui-badge layui-bg-red">精帖</span></div>
|
||||
|
Loading…
Reference in New Issue
Block a user