first commit

This commit is contained in:
2025-06-25 10:53:11 +08:00
commit 9f374011ae
1240 changed files with 181139 additions and 0 deletions
+25
View File
@@ -0,0 +1,25 @@
<?php
/**
* @copyright Copyright (c) 2023-2024 美天智能科技
* @author 李志强
* @link http://www.meteteme.com
*/
/**
======================
*模块数据获取公共文件
======================
*/
use think\facade\Db;
//读取知识库分类
function knowledge_cate()
{
$cate = Db::name('KnowledgeCate')->where(['status' => 1])->select()->toArray();
return $cate;
}
function knowledge_doc($kid = 0)
{
$list = Db::name('KnowledgeDoc')->where(['knowledge_id' => $kid, 'delete_time' => 0])->select()->toArray();
return $list;
}
+276
View File
@@ -0,0 +1,276 @@
<?php
/**
* @copyright Copyright (c) 2023-2024 美天智能科技
* @author 李志强
* @link http://www.meteteme.com
*/
declare(strict_types=1);
namespace app\knowledge\controller;
use app\base\BaseController;
use app\model\Knowledge as KnowledgeList;
use app\knowledge\validate\KnowledgeCheck;
use think\exception\ValidateException;
use think\facade\Db;
use think\facade\View;
class Index extends BaseController
{
public function index()
{
$param = get_params();
if (request()->isAjax()) {
$where = array();
if (!empty($param['keywords'])) {
$where[] = ['a.id|a.title|a.keywords|a.desc|a.content|c.title', 'like', '%' . $param['keywords'] . '%'];
}
if (!empty($param['cate_id'])) {
$where[] = ['a.cate_id', '=', $param['cate_id']];
}
if ($param['share'] == 1) {
$where[] = ['a.is_share', '=', 1];
} else {
$where[] = ['a.admin_id', '=', $this->uid];
}
$where[] = ['a.delete_time', '=', 0];
$rows = empty($param['limit']) ? get_config('app.page_size') : $param['limit'];
$content = KnowledgeList::where($where)
->field('a.*,c.id as cate_id,a.id as id,c.title as cate_title,a.title as title,u.name as user')
->alias('a')
->join('KnowledgeCate c', 'a.cate_id = c.id')
->join('admin u', 'a.admin_id = u.id', 'LEFT')
->order('a.create_time asc')
->paginate($rows, false, ['query' => $param])
->each(function ($item, $key) {
$item->views = Db::name('KnowledgeDoc')->where([['delete_time', '=', 0], ['knowledge_id', '=', $item->id]])->sum('read');
$item->sections = Db::name('KnowledgeDoc')->where([['delete_time', '=', 0], ['knowledge_id', '=', $item->id]])->count();
$item->tagsid = $item->tags;
$item->tags = Db::name('KnowledgeTags')->where(['id' => $item['tags']])->value('name');
});
return table_assign(0, '', $content);
} else {
$eid = isset($param['eid']) ? $param['eid'] : 0;
$kid = isset($param['kid']) ? $param['kid'] : 0;
View::assign('eid', $eid);
View::assign('kid', $kid);
return view();
}
}
public function list()
{
$param = get_params();
if (request()->isAjax()) {
$where = array();
if (!empty($param['keywords'])) {
$where[] = ['a.id|a.title|a.keywords|a.desc|a.content|c.title', 'like', '%' . $param['keywords'] . '%'];
}
if (!empty($param['cate_id'])) {
$where[] = ['a.cate_id', '=', $param['cate_id']];
}
$where[] = ['a.delete_time', '=', 0];
$where[] = ['a.is_share', '=', 1];
$rows = empty($param['limit']) ? get_config('app.page_size') : $param['limit'];
$content = KnowledgeList::where($where)
->field('a.*,c.id as cate_id,a.id as id,c.title as cate_title,a.title as title,u.name as user')
->alias('a')
->join('KnowledgeCate c', 'a.cate_id = c.id')
->join('admin u', 'a.admin_id = u.id', 'LEFT')
->order('a.create_time desc')
->paginate($rows, false, ['query' => $param]);
return table_assign(0, '', $content);
} else {
$eid = isset($param['eid']) ? $param['eid'] : 0;
$kid = isset($param['kid']) ? $param['kid'] : 0;
View::assign('eid', $eid);
View::assign('kid', $kid);
return view();
}
}
// 获取标签
public function get_tags()
{
$tags = Db::name('KnowledgeTags')->field('id, name')->select();
return json(['data' => $tags]);
}
//添加&&编辑
public function add()
{
$param = get_params();
if (request()->isPost()) {
if (!empty($param['id']) && $param['id'] > 0) {
try {
validate(KnowledgeCheck::class)->scene('edit')->check($param);
} catch (ValidateException $e) {
// 验证失败 输出错误信息
return to_assign(1, $e->getError());
}
$param['update_time'] = time();
$res = KnowledgeList::where('id', $param['id'])->strict(false)->field(true)->update($param);
if ($res) {
add_log('edit', $param['id'], $param);
}
return to_assign(0, '编辑成功', $param['id']);
} else {
try {
validate(KnowledgeCheck::class)->scene('add')->check($param);
} catch (ValidateException $e) {
// 验证失败 输出错误信息
return to_assign(1, $e->getError());
}
$param['admin_id'] = $this->uid;
$param['create_time'] = time();
$kid = KnowledgeList::strict(false)->field(true)->insertGetId($param);
if ($kid) {
add_log('add', $kid, $param);
}
return to_assign(0, '添加成功', $kid);
}
} else {
$id = isset($param['id']) ? $param['id'] : 0;
if ($id > 0) {
$knowledge = Db::name('Knowledge')->where(['id' => $id])->find();
View::assign('knowledge', $knowledge);
}
View::assign('id', $id);
return view();
}
}
//查看
public function view()
{
$id = get_params("id");
$detail = (new KnowledgeList())->detail($id);
// if ($detail['admin_id'] != $this->uid) {
// return to_assign(1, "您不是该知识库创建者,无权限操作");
// }
View::assign('detail', $detail);
return view();
}
//删除
public function delete()
{
$id = get_params("id");
$data['id'] = $id;
$data['delete_time'] = time();
if (Db::name('Knowledge')->update($data) !== false) {
add_log('delete', $id);
return to_assign(0, "删除成功");
} else {
return to_assign(1, "删除失败");
}
}
//文档添加&&编辑
public function doc_add()
{
$param = get_params();
if (request()->isPost()) {
if (isset($param['table-align'])) {
unset($param['table-align']);
}
if (isset($param['docContent-html-code'])) {
$param['content'] = $param['docContent-html-code'];
unset($param['docContent-html-code']);
}
if (isset($param['id']) && $param['id'] > 0) {
$param['update_time'] = time();
$res = Db::name('KnowledgeDoc')->strict(false)->field(true)->update($param);
$aid = $param['id'];
if ($res) {
add_log('edit', $param['id'], $param);
return to_assign();
} else {
return to_assign(1, '操作失败');
}
} else {
$param['admin_id'] = $this->uid;
$param['create_time'] = time();
if (isset($param['content'])) {
$param['desc'] = getDescriptionFromContent($param['content'], 100);
}
$aid = Db::name('KnowledgeDoc')->strict(false)->field(true)->insertGetId($param);
if ($aid) {
add_log('add', $aid, $param);
return to_assign(0, '保存成功', $aid);
} else {
return to_assign(1, '操作失败');
}
}
} else {
$id = empty($param['id']) ? 0 : $param['id'];
$pid = empty($param['pid']) ? 0 : $param['pid'];
View::assign('id', $id);
View::assign('pid', $pid);
if ($id > 0) {
$detail = Db::name('KnowledgeDoc')->where(['id' => $id])->find();
View::assign('detail', $detail);
}
return view();
}
}
//删除文档
public function doc_delete()
{
$id = get_params("id");
$count = Db::name('KnowledgeDoc')->where(["pid" => $id, "delete_time" => 0])->count();
if ($count > 0) {
return to_assign(1, "该分类下还有子文档,无法删除");
}
$data['id'] = $id;
$data['delete_time'] = time();
if (Db::name('KnowledgeDoc')->update($data) !== false) {
add_log('delete', $id);
return to_assign(0, "删除成功");
} else {
return to_assign(1, "删除失败");
}
}
/*
*文档详情
*/
public function doc_detail()
{
$param = get_params();
$kid = empty($param['kid']) ? 0 : $param['kid'];
$id = empty($param['id']) ? 0 : $param['id'];
if (request()->isAjax()) {
$info = Db::name('KnowledgeDoc')->where(['id' => $id])->find();
Db::name('KnowledgeDoc')->where(['id' => $id])->inc('read')->update();
add_log('view', $id);
return to_assign(0, '', $info);
} else {
$where = array();
$where[] = ['knowledge_id', '=', $kid];
$where[] = ['delete_time', '=', 0];
$list = Db::name('KnowledgeDoc')->where($where)
->field('id,pid,title,type,knowledge_id,link,read,sort,create_time,update_time')
->order('sort asc,id asc')
->select()->toArray();
$detail = (new KnowledgeList())->detail($kid);
$info = [];
if ($id == 0 && !empty($list)) {
$id = $list[0]['id'];
}
$info = Db::name('KnowledgeDoc')->where(['id' => $id])->find();
Db::name('KnowledgeDoc')->where(['id' => $id])->inc('read')->update();
View::assign([
'detail' => $detail,
'info' => $info,
'kid' => $kid,
'id' => $id
]);
add_log('view', $id);
return View();
}
}
}
+5
View File
@@ -0,0 +1,5 @@
<?php
// 这是系统自动生成的event定义文件
return [
];
+13
View File
@@ -0,0 +1,13 @@
<?php
/**
* @copyright Copyright (c) 2023-2024 美天智能科技
* @author 李志强
* @link http://www.meteteme.com
*/
// 这是系统自动生成的middleware定义文件
return [
//开启session中间件
//'think\middleware\SessionInit',
\app\home\middleware\Install::class,
];
+32
View File
@@ -0,0 +1,32 @@
<?php
/**
* @copyright Copyright (c) 2023-2024 美天智能科技
* @author 李志强
* @link http://www.meteteme.com
*/
namespace app\knowledge\validate;
use think\Validate;
class KnowledgeCheck extends Validate
{
protected $rule = [
'title' => 'require',
'desc' => 'require',
'id' => 'require',
'cate_id' => 'require',
];
protected $message = [
'title.require' => '标题不能为空',
'cate_id.require' => '所属分类为必选',
'id.require' => '缺少更新条件',
'desc.require' => '描述不能为空',
];
protected $scene = [
'add' => ['title', 'cate_id', 'content', 'desc'],
'edit' => ['title', 'cate_id', 'content', 'id', 'desc'],
];
}
+125
View File
@@ -0,0 +1,125 @@
<form class="layui-form page-content p-4">
{eq name="$id" value="0"}
<h3 class="h3-title">新建知识</h3>
{else/}
<h3 class="h3-title">编辑知识</h3>
{/eq}
<table class="layui-table layui-table-form">
<tr>
<td class="layui-td-gray">知识标题<font>*</font>
</td>
<td colspan="7">
<input type="text" name="title" lay-verify="required" lay-reqText="请输入知识标题" placeholder="请输入知识标题"
class="layui-input" {notempty name="$knowledge.title" }value="{$knowledge.title}" {/notempty}>
</td>
</tr>
<tr>
<td class="layui-td-gray">标签</td>
<td>
<select name="tags" id="tags" lay-verify="required" lay-reqText="请选择标签">
<option value="">请选择标签</option>
</select>
</td>
<td class="layui-td-gray">所属分类<span style="color: red">*</span></td>
<td>
<select name="cate_id" lay-verify="required" lay-reqText="请选择分类">
<option value="">请选择分类</option>
{notempty name="$knowledge.cate_id"}
{volist name=":set_recursion(knowledge_cate())" id="v"}
<option value="{$v.id}" {eq name="$knowledge.cate_id" value="$v.id" }selected{/eq}>{$v.title}
</option>
{/volist}
{else/}
{volist name=":set_recursion(knowledge_cate())" id="v"}
<option value="{$v.id}">{$v.title}</option>
{/volist}
{/notempty}
</select>
</td>
<td class="layui-td-gray">排序</td>
<td>
<input type="text" name="sort" placeholder="请输入排序,数字" class="layui-input" {notempty
name="$knowledge.sort" }value="{$knowledge.sort}" {/notempty}>
</td>
<td class="layui-td-gray">是否公开<span style="color: red">*</span></td>
<td>
{if condition="$id eq 0"}
<input type="radio" name="is_share" value="1" title="公开" checked>
<input type="radio" name="is_share" value="0" title="私有">
{else/}
<input type="radio" name="is_share" value="1" title="公开" {eq name="$knowledge.is_share" value="1"
}checked{/eq}>
<input type="radio" name="is_share" value="0" title="私有" {eq name="$knowledge.is_share" value="0"
}checked{/eq}>
{/if}
</td>
</tr>
<tr>
<td class="layui-td-gray" style="vertical-align:top;">知识描述<span style="color: red">*</span></td>
<td colspan="7">
<textarea class="layui-textarea" name="desc"
style="height:300px;">{notempty name="$knowledge.desc" }{$knowledge.desc}{/notempty}</textarea>
</td>
</tr>
</table>
<div style="padding: 10px 0">
<input type="hidden" name="id" value="{$id}" />
<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</form>
<script>
layui.use(['form', 'layer', 'tool'], function () {
var form = layui.form,
layer = layui.layer,
tool = layui.tool;
form.render();
//监听提交
form.on('submit(webform)', function (data) {
let callback = function (e) {
layer.msg(e.msg);
if (e.code == 0) {
getData.page = 1;
getKnowledge();
tool.load('/knowledge/index/view/id/' + e.data + '.html');
}
}
tool.post("/knowledge/index/add", data.field, callback);
return false;
});
// 使用Ajax获取标签数据并填充下拉选择框
$.ajax({
url: '/knowledge/index/get_tags',
type: 'GET',
success: function (response) {
console.log(response); // 打印获取的数据到浏览器控制台
if (response && response.data && Array.isArray(response.data)) {
var select = $('#tags');
select.empty(); // 清空下拉框
select.append('<option value="">请选择标签</option>'); // 添加默认选项
$.each(response.data, function (key, value) {
if (value) {
var selected = '';
{notempty name="$knowledge.tags"}
if (value.id == {$knowledge.tags}) {
selected = 'selected';
}
{/notempty}
var displayName = value.name || '无'; // 如果name为空,则显示为'无'
select.append('<option value="' + value.id + '" ' + selected + '>' + displayName + '</option>');
}
});
form.render('select'); // 重新渲染表单
}
},
error: function () {
console.log('Failed to fetch tags data.');
}
});
});
</script>
+255
View File
@@ -0,0 +1,255 @@
{extend name="../../base/view/common/base" /}
{block name="style"}
<style>
.layui-tree-set .layui-tree-txt.on,.layui-tree-set .layui-tree-txt.on:hover{font-weight:800; color:#1E9FFF}
.layui-tree-txt{display:inline-block; width:132px; overflow:hidden;}
.layui-tree-iconClick{margin-right:3px;}
.tree-left{width:268px; float:left; height:calc(100% - 22px); overflow-y: scroll; overflow-x: hidden; border-right:1px solid #e5ecf0; background-color:#fff; padding:12px 10px 10px 5px;}
.tree-left h3{font-size:16px; height:30px; padding-left:10px; font-weight:800}
.editormd-code-toolbar select{display:inline;}
.editormd{margin-bottom:0}
.layui-table td{border-color:#e5ecf0}
.editormd li{list-style: inherit;}
</style>
{/block}
{block name="breadcrumb"}
<span class="layui-breadcrumb">
<a href="http://www.meteteme.com/" target="_blank">江苏美天科技</a>
<a href="/knowledge/index/index">知识库</a>
<a><cite>编辑知识</cite></a>
</span>
{/block}
<!-- 主体 -->
{block name="body"}
<div class="table-content" style="height:100%">
<div class="tree-left">
<h3>知识库目录</h3>
<div id="tree"></div>
</div>
<div class="body-table pt-3 pr-3" style="margin-left:296px;">
<form class="layui-form">
<table class="layui-table" style="margin-bottom:0;">
<tr>
<td class="layui-td-gray">标题 <span style="color: red">*</span></td>
<td><input type="text" value="{$detail.title}" name="title" lay-verify="required" lay-reqText="请输入标题" autocomplete="off" placeholder="请输入标题" class="layui-input"></td>
<td class="layui-td-gray">上级目录<span style="color: red">*</span></td>
<td>
<select name="pid">
<option value="0">请选择顶级目录</option>
{volist name=":set_recursion(knowledge_doc($detail.knowledge_id))" id="v"}
<option value="{$v.id}" {eq name="$v.id" value="$detail.pid"} selected{/eq}>{$v.title}</option>
{/volist}
</select>
</td>
<td class="layui-td-gray">排序<span style="color: red">*</span></td>
<td style="width:80px; text-align:center"><input type="text" name="sort" value="{$detail.sort}" placeholder="请输入排序,数字" autocomplete="off" class="layui-input"></td>
</tr>
{eq name="$detail.type" value="3"}
<tr>
<td class="layui-td-gray">跳转链接 <span style="color: red">*</span></td>
<td colspan="5">
<input type="text" value="{$detail.link}" name="link" lay-verify="required" lay-reqText="请输入标题" autocomplete="off" placeholder="请输入标题" class="layui-input">
</td>
</tr>
{/eq}
</table>
{eq name="$detail.type" value="1"}
<h5 class="my-3">文档内容</h5>
<div>
<!-- <textarea id="mdContent" style="display:none;">{$detail.md_content|raw}</textarea> -->
<!-- <div id="docContent"></div> -->
<textarea class="layui-textarea" id="container"></textarea>
</div>
{/eq}
<div class="mt-4">
<input type="hidden" name="id" value="{$id}">
<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">提交保存</button>
<button lay-event="back" class="layui-btn layui-btn-primary">返回目录</button>
</div>
</form>
</div>
</div>
</div>
{/block}
<!-- 脚本 -->
{block name="script"}
<script>
const moduleInit = ['tool','tinymce'];
function gouguInit() {
var form = layui.form,table = layui.table,tool = layui.tool,tree = layui.tree,layer = layui.layer,editor = layui.tinymce;
var doc_id = '{$detail.id}';
var knowledge_id = '{$detail.knowledge_id}';
var content = `{$detail.content|raw}`; // 使用模板字符串来处理内容
// if($('#docContent').length>0){
// var edit = editor.render({
// selector: '#docContent',
// height: window.innerHeight - 240
// });
// }
var edit = editor.render({
selector: "#container",
height: window.innerHeight - 240,
setup: function (editor) {
editor.on('init', function () {
editor.setContent(content);
});
}
});
var treeRender = function(res){
//仅节点左侧图标控制收缩
tree.render({
elem: '#tree',
data: res.trees,
spread: true,
id: 'book',
edit: ['add', 'del'], //操作节点的图标
onlyIconControl: true, //是否仅允许节点左侧图标控制展开收缩
click: function(obj){
//layer.msg(JSON.stringify(obj.data));
window.location.href='/knowledge/index/doc_add?id='+obj.data.id;
},
operate: function(obj){
let type = obj.type; //得到操作类型:add、edit、del
let data = obj.data; //得到当前节点的数据
let elem = obj.elem; //得到当前节点元素
if(type === 'add'){ //增加节点
add(obj.data.id);
} else if(type === 'update'){ //修改节点
// console.log(elem.find('.layui-tree-txt').html()); //得到修改后的内容
} else if(type === 'del'){ //删除节点
let deletecallback = function (e) {
layer.msg(e.msg);
setTimeout(function(){
$('#tree').find('.layui-tree-txt').eq(0).click();
},1000)
}
tool.delete("/knowledge/index/doc_delete",{ id: obj.data.id },deletecallback);
};
}
});
setTimeout(function(){
$('[data-id="'+doc_id+'"]').find('.layui-tree-txt').eq(0).addClass('on');
},100)
}
tool.get("/api/index/get_doc_list",{kid:knowledge_id,tree:1},treeRender);
//监听提交
form.on('submit(webform)', function (data) {
data.field['docContent-html-code'] = tinymce.get('container').getContent();
let callback = function(e){
layer.msg(e.msg);
if(e.code == 0){
setTimeout(function(){
window.location.href='/knowledge/index/?kid='+knowledge_id;
},1000)
}
}
tool.post('/knowledge/index/doc_add',data.field,callback);
return false;
});
//监听返回
$('.body-table').on('click', '[lay-event="back"]', function () {
window.location.href='/knowledge/index/?kid='+knowledge_id;
return false;
});
//添加
var selectTable=null;
function add(pid) {
var type=[{'id':1,'title':'新建文档'},{'id':2,'title':'新建目录'},{'id':3,'title':'新建链接'}];
layer.open({
title:'选择节点类型',
type:1,
area:['360px','300px'],
content:'<div style="width:328px; padding:15px 15px 0"><div id="selectType"></div></div>',
success:function(){
selectTable=table.render({
elem: '#selectType',
cols: [[ //标题栏
{type:'radio',title: '选择'},
{field: 'title', title: '节点类型'}
]],
data: type
});
},
btn:['确定'],
btnAlign:'c',
yes: function(idx){
let checkStatus = table.checkStatus(selectTable.config.id);
let data = checkStatus.data;
if(data.length>0){
if(data[0].id==1 || data[0].id==2){
layer.prompt({title: '标题', formType: 3,value :''}, function(text, index){
if(text == ''){
layer.msg('输入标题');
return false;
}
let postData = {knowledge_id:knowledge_id,pid:pid,type:data[0].id,title:text}
let callback = function(e){
layer.msg(e.msg);
if(e.code == 0){
setTimeout(function(){
window.location.href='/knowledge/index/doc_add/id/'+e.data;
},1000)
}
}
tool.post('/knowledge/index/doc_add',postData,callback);
})
}else if(data[0].id==3){
var content='<div style="padding:0 15px;"><table class="layui-table">\
<tr>\
<td class="layui-td-gray">链接标题 <span style="color: red">*</span></td>\
<td><input name="title" id="docTitle" class="layui-input" value="" placeholder="请输入标题"></td>\
</tr>\
<tr>\
<td class="layui-td-gray">URL链接 <span style="color: red">*</span></td>\
<td><input name="link" id="docLink" class="layui-input" value="" placeholder="请输入链接"></td>\
</tr>\
</table></div>';
layer.open({
type:1,
title:'新建链接',
area:['480px','300px'],
content:content,
btn: ['确定提交'],
btnAlign:'c',
yes: function(idx){
let docTitle = $('#docTitle').val();
let docLink = $('#docLink').val();
if(docTitle==''){
layer.msg('请输入标题');
return;
}
if(docLink==''){
layer.msg('请输入链接');
return;
}
let postData = {knowledge_id:knowledge_id,pid:pid,type:data[0].id,title:docTitle,link:docLink}
let callback = function(e){
layer.msg(e.msg);
if(e.code == 0){
setTimeout(function(){
window.location.href='/knowledge/index/doc_add/id/'+e.data;
},1000)
}
}
tool.post('/knowledge/index/doc_add',postData,callback);
}
})
}
}
else{
layer.msg('请选择节点类型');
return false;
}
}
})
}
}
</script>
{/block}
<!-- /脚本 -->
+150
View File
@@ -0,0 +1,150 @@
{extend name="../../base/view/common/base" /}
{block name="style"}
<link rel="stylesheet" href="{__METE__}/third_party/prism/prism.css?v=1"/>
<link rel="stylesheet" href="{__STATIC__}/viewer/viewer.min.css?v=1"/>
<link rel="stylesheet" href="{__STATIC__}/ztree/css/metroStyle/metroStyle.css" >
<style>
.content-chapter{width:300px; position:fixed; top:50px; left:60px; bottom:0; overflow: hidden; border-right:1px solid #e5ecf0; background-color:#F5F8FA;}
.content-text{margin-left:300px; padding:16px 32px; /*max-width:900px;*/}
.menu-title span{font-size:12px; font-weight:400}
.tree-menu{height:calc(100% - 145px); overflow-y: scroll; overflow-x: hidden;}
.editormd-preview2{font-size:16px; line-height:1.72; background-color:#fff;}
.editormd-html-preview code, .editormd-preview-container code {padding:2px; border-radius:2px; font-size:14px; font-family:SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;}
.editormd-html-preview, .editormd-preview-container .code-toolbar{font-size:14px;}
.editormd-preview2 li {list-style: initial;}
.editormd-html-preview pre, .editormd-preview-container pre{border: 1px solid #f6f6f6; font-size:14px;}
</style>
{/block}
{block name="breadcrumb"}
<span class="layui-breadcrumb">
<a href="http://www.meteteme.com/" target="_blank">江苏美天科技</a>
<a href="/knowledge/index/index">知识库</a>
<a><cite>知识详情</cite></a>
</span>
{/block}
<!-- 主体 -->
{block name="body"}
<div class="main-content">
{empty name="$info"}
<div style="padding:200px 0 0; width:100%; min-height:500px; text-align:center; font-size:30px; color:#999">暂无文档内容</div>
{else/}
<div class="content-chapter">
<div class="p-4">
<h4>{$detail['title']}</h4>
<p class="font-gray py-4">创建人:{$detail['user']}</p>
<h5 class="menu-title">目录<span class="font-gray">{$detail['count']}</span></h5>
</div>
<div class="tree-menu px-4">
<ul id="treeDemo" class="ztree"></ul>
</div>
</div>
<div class="content-text">
<!-- <div class="pb-4"><h2 id="infoTilte">{$info.title}</h2></div> -->
<div class="editormd-preview2">
<div class="markdown-body" id="infoContent">
{$info.content|raw}
</div>
</div>
<div class="end-tip">
-- 内容展示完毕 --
</div>
</div>
{/empty}
</div>
{/block}
<!-- /主体 -->
{block name="footer"}{/block}
<!-- 脚本 -->
{block name="script"}
<script src="{__STATIC__}/ztree/js/jquery.ztree.all.min.js?v=1"></script>
<script src="{__STATIC__}/viewer/viewer.min.js?v=1"></script>
<script src="{__METE__}/third_party/prism/prism.js?v=1"></script>
<script>
var kid='{$kid}';
var did='{$id}';
var treeObj = null;
var zNodes =[
{ id:1, pId:0, name:"文档", open:true}
];
const moduleInit = ['tool'];
function gouguInit() {
var layer = layui.layer;
var tool = layui.tool;
var viewer = new Viewer(document.getElementById('infoContent'));
var $codepre = $("code[class]");
if($codepre.length>0){
for(var i = 0;i<$codepre.length;i++){
var item = $codepre.eq(i).parent();
item.addClass("line-numbers");
}
}
var setting = {
data: {
simpleData: {
enable: true
}
},
callback: {
onClick: zTreeOnClick
}
};
function zTreeOnClick(event, treeId, treeNode) {
let type=treeNode.type;
let id=treeNode.id;
if(type==1){
detail(id);
}
if(type == 2){
treeObj.expandNode(treeNode, !treeNode.open, false, true);
}
if(type == 3){
window.open(treeNode.link);
}
};
let treeback = function(e){
if (e.code == 0) {
zNodes = e.data;
treeObj = $.fn.zTree.init($("#treeDemo"), setting, zNodes);
treeObj.expandAll(true);
if(did>0){
var node = treeObj.getNodeByParam("id", did, null);
treeObj.selectNode(node);
}
} else {
layer.msg(e.msg);
}
}
tool.get("/api/index/get_doc_list",{kid:kid,tree:2},treeback);
function detail(id){
viewer.destroy();
let detailback = function(e){
if (e.code == 0) {
history.pushState({},e.data.title,window.location.protocol+'//'+window.location.host+'/knowledge/index/doc_detail/kid/'+kid+'/id/'+id+'.html');
$('#infoTilte').html(e.data.title);
$('#infoContent').html(e.data.content);
document.body.scrollTop=document.documentElement.scrollTop=0
var $codepre = $('#infoContent').find("code[class]");
if($codepre.length>0){
for(var i = 0;i<$codepre.length;i++){
var item = $codepre.eq(i).parent();
item.addClass("line-numbers").addClass('lang-javascript');
}
Prism.highlightAll();
}
viewer = new Viewer(document.getElementById('infoContent'));
} else {
layer.msg(e.msg);
}
}
tool.get("/knowledge/index/doc_detail",{id:id},detailback);
}
}
</script>
{/block}
<!-- /脚本 -->
+187
View File
@@ -0,0 +1,187 @@
{extend name="../../base/view/common/base" /}
{block name="breadcrumb"}
<span class="layui-breadcrumb">
<a href="http://www.meteteme.com/" target="_blank">江苏美天科技</a>
<a><cite>知识库</cite></a>
</span>
{/block}
<!-- 主体 -->
{block name="body"}
<div class="table-content p-3">
<div class="layui-tab knowledge-tab" style="margin:0" lay-filter="docDemoTabBrief">
<ul class="layui-tab-title">
<li>个人知识库</li>
<li class="layui-this">共享知识库</li>
</ul>
</div>
<form class="layui-form layui-form-bar border-x border-b mb-3">
<div class="layui-input-inline" style="width:120px">
<select name="cate_id">
<option value="">请选择分类</option>
{volist name=":set_recursion(knowledge_cate())" id="v"}
<option value="{$v.id}">{$v.title}</option>
{/volist}
</select>
</div>
<div class="layui-input-inline" style="width:240px;">
<input type="text" name="keywords" placeholder="标题/分类/描述" class="layui-input" autocomplete="off" />
</div>
<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">提交搜索</button>
<span style="float:right" class="layui-btn add-new">+ 新建知识库</span>
</form>
<div class="knowledge-list layui-row layui-col-space12" id="knowledgeContent">
</div>
<div id="pageBox" class="page-box py-4"></div>
</div>
<script type="text/html" id="barDemo">
<div class="layui-btn-group"><span class="layui-btn layui-btn-normal layui-btn-xs" lay-event="view">查看</span></div>
</script>
{/block}
<!-- /主体 -->
<!-- 脚本 -->
{block name="script"}
<script>
const eid = {$eid};
const kid = {$kid};
var getKnowledge = null;
var getData = {'page':1,'share':1};
const moduleInit = ['tool','treeGrid'];
function gouguInit() {
var tool = layui.tool,
layer = layui.layer,
form = layui.form,
element = layui.element,
laypage = layui.laypage;
element.on('tab(docDemoTabBrief)', function(data){
getData.share=data.index;
getKnowledge();
});
if(eid>0 && kid == 0){
tool.open('/knowledge/index/add/id/'+kid+'.html');
}
if(eid == 0 && kid > 0){
tool.open('/knowledge/index/view/id/'+kid+'.html');
}
getKnowledge = function(){
tool.get("/knowledge/index/index",getData,function(res){
if(res.code == 0){
let card='';
for(let i=0; i<res.data.length;i++){
let item = res.data[i];
if(getData.share == 1){
card+=`
<div class="layui-col-md4">
<div class="layui-card">
<div class="card-body">
<div class="meta-title text-overflow1"><a href="/knowledge/index/doc_detail/kid/${item.id}">${item.tags ? `<span class="tags tags-${item.tagsid}">${item.tags}</span>` : ``}${item.title}</a></div>
<div class="meta-desc text-overflow3"><a href="/knowledge/index/doc_detail/kid/${item.id}">${item.desc}</a></div>
</div>
<div class="card-actions">
<ul>
<li title="章节数">共${item.sections}章节</li>
<li title="查阅数">浏览:${item.views}</li>
<li title="编辑"><a class="action-edit" data-id="${item.id}" data-admin="${item.admin_id}" href="javascript:;">编辑</a></li>
<li title="浏览详情"><a class="action-view" href="/knowledge/index/doc_detail/kid/${item.id}">详情</a></li>
</ul>
</div>
</div>
</div>
`;
}
else{
card+=`
<div class="layui-col-md4">
<div class="layui-card">
<div class="card-body">
<div class="meta-title text-overflow1"><a href="/knowledge/index/doc_detail/kid/${item.id}">${item.title}</a></div>
<div class="meta-desc text-overflow3"><a href="/knowledge/index/doc_detail/kid/${item.id}">${item.desc}</a></div>
</div>
<div class="card-actions">
<ul>
<li title="章节数">共${item.sections}章节</li>
<li title="删除"><a class="action-del" data-id="${item.id}" data-admin="${item.admin_id}" href="javascript:;">删除</a></li>
<li title="编辑"><a class="action-edit" data-id="${item.id}" data-admin="${item.admin_id}" href="javascript:;">编辑</a></li>
<li title="浏览详情"><a class="action-view" href="/knowledge/index/doc_detail/kid/${item.id}">详情</a></li>
</ul>
</div>
</div>
</div>
`;
}
}
if(card == ''){
card='<div style="text-align:center; color:#999; padding:24px 0">暂无数据</div>';
}
$('#knowledgeContent').html(card);
// if(getData.page==1){
// window.pageInitialized = true;
// laypage.render({
// elem: 'pageBox'
// ,limit:9
// ,count: 50 //数据总数,从服务端得到
// ,jump: function(obj, first){
// console.log('当前页码:' + obj.curr); //得到当前页
// getData.page=obj.curr;
// getKnowledge();
// //首次不执行
// if(!first){
// //do something
// }
// }
// });
// }
}
});
}
getKnowledge();
$('.add-new').on('click',function(){
tool.open('/knowledge/index/add');
});
$('#knowledgeContent').on('click','.action-del',function(){
let admin_id = $(this).data('admin');
if(admin_id != GOUGU_DEV.uid){
layer.msg('您不是该知识库创建者,无权限删除');
return false;
}
let id=$(this).data('id');
layer.confirm('确定要删除该知识吗?', { icon: 3, title: '提示' }, function (index) {
let callback = function (e) {
layer.closeAll();
layer.msg(e.msg);
getKnowledge();
}
let postData = { "id": id };
tool.delete("/knowledge/index/delete", postData, callback);
});
});
$('#knowledgeContent').on('click','.action-edit',function(){
// let admin_id = $(this).data('admin');
// if(admin_id != GOUGU_DEV.uid){
// layer.msg('您不是该知识库创建者,无权限编辑');
// return false;
// }
let id=$(this).data('id');
tool.open('/knowledge/index/view/id/'+id+'.html');
});
//监听搜索提交
form.on('submit(webform)', function(data) {
getData.page=1;
getData.keywords=data.field.keywords;
getData.cate_id=data.field.cate_id;
getKnowledge();
return false;
});
}
</script>
{/block}
<!-- /脚本 -->
+230
View File
@@ -0,0 +1,230 @@
<div class="page-content">
<div class="p-4 border-b">
<h3 class="h3-title">{$detail.title}</h3>
<div class="font-gray">介绍:{$detail.desc}</div>
</div>
<div class="p-4">
<div class="mb-2">
<table class="layui-table">
<tr>
<td class="layui-td-gray">文档数</td>
<td style="text-align:center;">{$detail.count}</td>
<td class="layui-td-gray">阅览数</td>
<td style="text-align:center;">{$detail.views}</td>
<td class="layui-td-gray">收藏数</td>
<td style="text-align:center;">{$detail.sort}</td>
<td class="layui-td-gray">是否公开</td>
<td style="text-align:center;">
{eq name="$detail.is_share" value="1"}是{/eq}
{eq name="$detail.is_share" value="2"}否{/eq}
</td>
<td class="layui-td-gray">所属分类</td>
<td style="text-align:center;">
{$detail.cate_name}
</td>
<td style="text-align:right;">
<input type="hidden" name="knowledge_id" value="{$detail.id}">
<button class="layui-btn layui-btn-normal layui-btn-sm edit-doc">编辑</button>
<button class="layui-btn layui-btn-sm add-doc" title="添加一级目录">+ 添加一级目录</button>
</td>
</tr>
</table>
</div>
<table class="layui-hide" id="treeTable" lay-filter="treeTable"></table>
</div>
</div>
<script>
function openInit(){
var tableId='treeTable',tool = layui.tool,table = layui.table,treeGrid = layui.treeGrid,layer=layui.layer;
treeGrid.render({
id:tableId
,elem: '#'+tableId
,idField:'id'
,url:'/api/index/get_doc_list'
,cellMinWidth: 100
,treeId:'id'//树形id字段名称
,treeUpId:'pid'//树形父id字段名称
,treeShowName:'title'//以树形式显示的字段
,heightRemove:[".dHead",138]//不计算的高度,表格设定的是固定高度,此项不生效
,height:'100%'
,isFilter:false
,iconOpen:false//是否显示图标【默认显示】
,isOpenDefault:false//节点默认是展开还是折叠【默认展开】
,loading:true
,isPage:false
,where:{kid:$('[name="knowledge_id"]').val()}
,cols: [[
{field:'id',width:80, title: '编码ID', align:'center'}
,{field: 'sort', title: '排序', edit: 'text', align:'center', style:'cursor: pointer;', width:80}
,{field:'pid', title: '父级ID', edit:'text',width:80, align:'center'}
,{field:'type', title: '类型',width:80,align:'center',templet: function(d){
var html='';
if(d.type==1){
html='<span class="layui-btn layui-btn-warm layui-btn-xs">文档</span>';
}
else if(d.type==2){
html='<span class="layui-btn layui-btn-xs">目录</span>';
}
if(d.type==3){
html='<span class="layui-btn layui-btn-normal layui-btn-xs">链接</span>';
}
return html;
}}
,{field:'title', edit:'text',title: '章节名称'}
,{field: 'read',title: '阅览数',align: 'center',width: 80}
,{width:166,title: '操作', align:'center',templet: function(d){
var html='<span class="layui-btn-group">';
html+='<a class="layui-btn layui-btn-xs" title="新建子节点" lay-event="add">新建子节点</a>';
html+='<a class="layui-btn layui-btn-normal layui-btn-xs" title="编辑" href="/knowledge/index/doc_add/id/'+d.id+'">编辑</a>';
html+='<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a>';
html+='</span>';
return html;
}
}
]]
});
//单元格编辑
treeGrid.on('edit('+tableId+')', function(obj){
layer.confirm('确定要提交修改吗?', {icon: 3, title:'提示'}, function(index){
let editData={};
editData['id'] = obj.data.id;
editData[obj.field] = obj.value;
let callback = function(e){
layer.msg(e.msg);
if(e.code == 0){
treeGrid.reload(tableId);
setTimeout(function(){
layer.closeAll();
},1000)
}
}
tool.post('/knowledge/index/doc_add',editData,callback);
})
});
//删除
treeGrid.on('tool('+tableId+')',function (obj) {
if(obj.event === 'del'){
layer.confirm('确定要删除吗?', {icon: 3, title:'提示'}, function(index){
let callback = function(e){
layer.msg(e.msg);
if(e.code == 0){
obj.del();
setTimeout(function(){
layer.closeAll();
},1000)
}
}
tool.post('/knowledge/index/doc_delete',{id:obj.data.id},callback);
});
}else if(obj.event==="add"){
add(obj.data.id);
}
});
$('.edit-doc').on('click',function(){
let kid = $('[name="knowledge_id"]').val();
tool.load('/knowledge/index/add/id/'+kid+'.html');
})
//新增
$('.add-doc').on('click',function(){
add(0);
});
//添加
var selectTable=null;
function add(pid) {
var type=[{'id':1,'title':'新建文档'},{'id':2,'title':'新建目录'},{'id':3,'title':'新建链接'}];
layer.open({
title:'选择节点类型',
type:1,
area:['360px','300px'],
content:'<div style="width:328px; padding:15px 15px 0"><div id="selectType"></div></div>',
success:function(){
selectTable=table.render({
elem: '#selectType',
cols: [[ //标题栏
{type:'radio',title: '选择'},
{field: 'title', title: '节点类型'}
]],
data: type
});
},
btn:['确定'],
btnAlign:'c',
yes: function(idx){
let checkStatus = table.checkStatus(selectTable.config.id);
let data = checkStatus.data;
if(data.length>0){
if(data[0].id==1 || data[0].id==2){
layer.prompt({title: '标题', formType: 3,value :''}, function(text, index){
if(text == ''){
layer.msg('输入标题');
return false;
}
let postData = {knowledge_id:$('[name="knowledge_id"]').val(),pid:pid,type:data[0].id,title:text}
let callback = function(e){
layer.msg(e.msg);
if(e.code == 0){
treeGrid.reload(tableId);
setTimeout(function(){
layer.closeAll();
},1000)
}
}
tool.post('/knowledge/index/doc_add',postData,callback);
})
}else if(data[0].id==3){
var content='<div style="padding:0 15px;"><table class="layui-table">\
<tr>\
<td class="layui-td-gray">链接标题 <span style="color: red">*</span></td>\
<td><input name="title" id="docTitle" class="layui-input" value="" placeholder="请输入标题"></td>\
</tr>\
<tr>\
<td class="layui-td-gray">URL链接 <span style="color: red">*</span></td>\
<td><input name="link" id="docLink" class="layui-input" value="" placeholder="请输入链接"></td>\
</tr>\
</table></div>';
layer.open({
type:1,
title:'新建链接',
area:['480px','300px'],
content:content,
btn: ['确定提交'],
btnAlign:'c',
yes: function(idx){
let docTitle = $('#docTitle').val();
let docLink = $('#docLink').val();
if(docTitle==''){
layer.msg('请输入标题');
return;
}
if(docLink==''){
layer.msg('请输入链接');
return;
}
let postData = {knowledge_id:$('[name="knowledge_id"]').val(),pid:pid,type:data[0].id,title:docTitle,link:docLink}
let callback = function(e){
layer.msg(e.msg);
if(e.code == 0){
treeGrid.reload(tableId);
setTimeout(function(){
layer.closeAll();
},1000)
}
}
tool.post('/knowledge/index/doc_add',postData,callback);
}
})
}
}
else{
layer.msg('请选择节点类型');
return false;
}
}
})
}
}
</script>