This commit is contained in:
tao 2022-08-16 15:29:04 +08:00
parent ad7510a7bb
commit 43013c2e39
84 changed files with 1924 additions and 45264 deletions

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -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);
}
}

View 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]);
}
}

View File

@ -12,13 +12,6 @@ use app\common\lib\Uploads;
class User extends AdminController
{
/**
protected function initialize()
{
parent::initialize();
}
*/
//用户表
public function list()
{

View File

@ -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

View File

@ -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);
},
});
});

View File

@ -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>

View File

@ -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}

View 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}

View 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}

View 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}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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);
}
}
}
}
}

View File

@ -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

View File

@ -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.
*/

View File

@ -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 {

View 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;
}
}
}

View File

@ -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
View 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;
}
}
}

View 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;
}
}
}

View File

@ -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;
}
}

View File

@ -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]);
}
}

View File

@ -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);

View File

@ -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');

View File

@ -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;

View File

@ -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
-- ----------------------------

View File

@ -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
View File

@ -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",

View File

@ -1,5 +0,0 @@
<?php
return [
'一个' => 'http://www.bi.com',
'描述' => 'http://ww.com',
];

View File

@ -16,7 +16,7 @@ return [
// 应用名,此项不可更改
'appname' => 'TaoLer',
// 版本配置
'version' => '1.9.22',
'version' => '1.9.23',
// 加盐
'salt' => 'taoler',
// 数据库备份目录

View File

@ -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

View File

@ -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);

View File

@ -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"
}

View File

@ -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"
}

View File

@ -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é"
}

View File

@ -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"
}

View File

@ -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": "업로드 실패"
}

View File

@ -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"
}

View 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')

View File

@ -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;}

View 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;
}

View 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')

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

25
runtime/update.sql Normal file
View 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 '关键词';

View File

@ -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',

View File

@ -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'),

View File

@ -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',

View File

@ -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",

View File

@ -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(),

View File

@ -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

View File

@ -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"

View File

@ -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.

View File

@ -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)

View File

@ -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."
}
}

View File

@ -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',
);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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);
}

View File

@ -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);
}
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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
View File

@ -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',

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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'; //跳转
}
}
});
});

View File

@ -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();

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>