mirror of https://github.com/1099438829/apeblog
Compare commits
4 Commits
e25404ee2f
...
a353e056be
| Author | SHA1 | Date |
|---|---|---|
|
|
a353e056be | |
|
|
cc15e83a70 | |
|
|
759fe7fa06 | |
|
|
16cfdb89b6 |
|
|
@ -225,7 +225,8 @@ class Admin extends AuthController
|
|||
*/
|
||||
public function profile(): string
|
||||
{
|
||||
$this->assign("info", aModel::find($this->adminId));
|
||||
$this->assign("info", (new \app\admin\model\Admin)->find($this->adminId));
|
||||
// dd((new \app\admin\model\Admin)->find($this->adminId));
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@
|
|||
<div class="card">
|
||||
<div class="card-body">
|
||||
<div class="edit-avatar">
|
||||
<img src="{$info.avatar}" alt="{$info.name}" class="img-avatar">
|
||||
<img src="{$info.avatar}" alt="{$info.nickname}" class="img-avatar">
|
||||
<div class="avatar-divider"></div>
|
||||
<div class="edit-avatar-content">
|
||||
<button class="btn btn-default trigger-btn">修改头像</button>
|
||||
|
|
@ -109,7 +109,7 @@
|
|||
<input type="hidden" class="form-control" name="avatar" id="avatar" value="{$info.avatar}"/>
|
||||
<div class="form-group">
|
||||
<label for="name">用户名</label>
|
||||
<input type="text" class="form-control" name="name" id="name" value="{$info.name}"
|
||||
<input type="text" class="form-control" name="username" id="username" value="{$info.username}"
|
||||
disabled="disabled"/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
<!--标签插件-->
|
||||
<link rel="stylesheet" href="/static/admin/js/jquery-tags-input/jquery.tagsinput.min.css">
|
||||
<!--富文本输入框-->
|
||||
<link rel="stylesheet" href="/static/admin/js/summernote/summernote.min.css">
|
||||
<link href="https://cdn.staticfile.org/wangeditor5/5.1.23/css/style.min.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div class="row">
|
||||
|
|
@ -74,8 +74,12 @@
|
|||
placeholder="请输入标签">
|
||||
</div>
|
||||
<div class="form-group col-md-12">
|
||||
<label for="content">文章内容</label>
|
||||
<textarea id="content" name="content" data-provide="summernote" data-toolbar="full"></textarea>
|
||||
<label for="editor-text-area">文章内容</label>
|
||||
<div style="border: 1px solid #ccc;">
|
||||
<div id="editor-toolbar" style="border-bottom: 1px solid #ccc;"></div>
|
||||
<div id="editor-text-area" style="height: 500px"></div>
|
||||
</div>
|
||||
<textarea id="content" name="content" style="display: none;"></textarea>
|
||||
</div>
|
||||
<div class="form-group col-md-12">
|
||||
<button type="submit" class="btn btn-primary ajax-post" target-form="add-form">立即提交
|
||||
|
|
@ -155,60 +159,45 @@
|
|||
<!--select2-->
|
||||
<script type="text/javascript" src="/static/admin/js/select2.min.js"></script>
|
||||
<!--富文本输入框-->
|
||||
<script type="text/javascript" src="/static/admin/js/summernote/summernote.min.js"></script>
|
||||
<script type="text/javascript" src="/static/admin/js/summernote/lang/summernote-zh-CN.min.js"></script>
|
||||
<script src="https://cdn.staticfile.org/wangeditor5/5.1.23/index.js"></script>
|
||||
<!--标签-->
|
||||
<script src="/static/admin/js/jquery-tags-input/jquery.tagsinput.min.js"></script>
|
||||
<script>
|
||||
$(function () {
|
||||
$('#tag').select2();
|
||||
});
|
||||
|
||||
$(document).ready(function(){
|
||||
$('[data-provide="summernote"]').each(function() {
|
||||
var options = {
|
||||
dialogsInBody: true,
|
||||
lang: 'zh-CN',
|
||||
dialogsFade: true,
|
||||
height:400
|
||||
};
|
||||
var config = {};
|
||||
$.each( $(this).data(), function(key, value){
|
||||
key = key.replace(/-([a-z])/g, function(x){return x[1].toUpperCase();});
|
||||
if ( key == 'provide' ) {
|
||||
return;
|
||||
var E = window.wangEditor
|
||||
// 切换语言
|
||||
var LANG = location.href.indexOf('lang=en') > 0 ? 'en' : 'zh-CN'
|
||||
E.i18nChangeLanguage(LANG)
|
||||
window.editor = E.createEditor({
|
||||
selector: '#editor-text-area',
|
||||
html: '<p><br></p>',
|
||||
config: {
|
||||
placeholder: '请输入...',
|
||||
MENU_CONF: {
|
||||
uploadImage: {
|
||||
fieldName: 'your-fileName',
|
||||
base64LimitSize: 10 * 1024 * 1024 // 10M 以下插入 base64
|
||||
}
|
||||
},
|
||||
onChange(editor) {
|
||||
let content = editor.getHtml()
|
||||
console.log('editor content', content)
|
||||
// 也可以同步到 <textarea>
|
||||
$("#content").val(content)
|
||||
}
|
||||
config[key] = value;
|
||||
});
|
||||
}
|
||||
})
|
||||
|
||||
options = $.extend(options, config);
|
||||
options.toolbar = [
|
||||
// [groupName, [list of button]]
|
||||
['para_style', ['style']],
|
||||
['style', ['bold', 'italic', 'underline', 'clear']],
|
||||
['font', ['strikethrough', 'superscript', 'subscript']],
|
||||
['fontsize', ['fontname', 'fontsize', 'height']],
|
||||
['color', ['color']],
|
||||
['para', ['ul', 'ol', 'paragraph', 'hr']],
|
||||
['table', ['table']],
|
||||
['insert', ['link', 'picture', 'video']],
|
||||
['do', ['undo', 'redo']],
|
||||
['misc', ['fullscreen', 'codeview', 'help']]
|
||||
];
|
||||
$(this).summernote(options);
|
||||
});
|
||||
window.toolbar = E.createToolbar({
|
||||
editor,
|
||||
selector: '#editor-toolbar',
|
||||
config: {}
|
||||
})
|
||||
|
||||
$(document).on('click', '[data-summernote-edit]', function(){
|
||||
var target = $(this).data('summernote-edit');
|
||||
$(target).summernote({focus: true});
|
||||
});
|
||||
|
||||
|
||||
$(document).on('click', '[data-summernote-save]', function(){
|
||||
var target = $(this).data('summernote-save');
|
||||
var markup = $(target).summernote('code');
|
||||
$(target).summernote('destroy');
|
||||
alert('修改完成');
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
<!--标签插件-->
|
||||
<link rel="stylesheet" href="/static/admin/js/jquery-tags-input/jquery.tagsinput.min.css">
|
||||
<!--富文本输入框-->
|
||||
<link rel="stylesheet" href="/static/admin/js/summernote/summernote.min.css">
|
||||
<link href="https://cdn.staticfile.org/wangeditor5/5.1.23/css/style.min.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div class="row">
|
||||
|
|
@ -93,8 +93,12 @@
|
|||
placeholder="请输入标签" value="{$info.tags}">
|
||||
</div>
|
||||
<div class="form-group col-md-12">
|
||||
<label for="content">文章内容</label>
|
||||
<textarea id="content" name="content" data-provide="summernote" data-toolbar="full">{$info.content}</textarea>
|
||||
<label for="editor-text-area">文章内容</label>
|
||||
<div style="border: 1px solid #ccc;">
|
||||
<div id="editor-toolbar" style="border-bottom: 1px solid #ccc;"></div>
|
||||
<div id="editor-text-area" style="height: 500px"></div>
|
||||
</div>
|
||||
<textarea id="content" name="content" style="display: none;">{$info.content}</textarea>
|
||||
</div>
|
||||
<div class="form-group col-md-12">
|
||||
<button type="submit" class="btn btn-primary ajax-post" target-form="add-form">立即提交
|
||||
|
|
@ -175,8 +179,7 @@
|
|||
<!--select2-->
|
||||
<script type="text/javascript" src="/static/admin/js/select2.min.js"></script>
|
||||
<!--富文本输入框-->
|
||||
<script type="text/javascript" src="/static/admin/js/summernote/summernote.min.js"></script>
|
||||
<script type="text/javascript" src="/static/admin/js/summernote/lang/summernote-zh-CN.min.js"></script>
|
||||
<script src="https://cdn.staticfile.org/wangeditor5/5.1.23/index.js"></script>
|
||||
<!--标签-->
|
||||
<script src="/static/admin/js/jquery-tags-input/jquery.tagsinput.min.js"></script>
|
||||
<script>
|
||||
|
|
@ -184,51 +187,37 @@
|
|||
$('#tag').select2();
|
||||
});
|
||||
$(document).ready(function(){
|
||||
$('[data-provide="summernote"]').each(function() {
|
||||
var options = {
|
||||
dialogsInBody: true,
|
||||
lang: 'zh-CN',
|
||||
dialogsFade: true,
|
||||
height:400
|
||||
};
|
||||
var config = {};
|
||||
$.each( $(this).data(), function(key, value){
|
||||
key = key.replace(/-([a-z])/g, function(x){return x[1].toUpperCase();});
|
||||
if ( key == 'provide' ) {
|
||||
return;
|
||||
var E = window.wangEditor
|
||||
// 切换语言
|
||||
var LANG = location.href.indexOf('lang=en') > 0 ? 'en' : 'zh-CN'
|
||||
E.i18nChangeLanguage(LANG)
|
||||
//需要判断是否含有html标签
|
||||
window.editor = E.createEditor({
|
||||
selector: '#editor-text-area',
|
||||
html: $('#content').val(), // 从 editor.getHtml() 获取的 html 内容
|
||||
config: {
|
||||
placeholder: '请输入...',
|
||||
MENU_CONF: {
|
||||
uploadImage: {
|
||||
fieldName: 'your-fileName',
|
||||
base64LimitSize: 10 * 1024 * 1024 // 10M 以下插入 base64
|
||||
}
|
||||
},
|
||||
onChange(editor) {
|
||||
let content = editor.getHtml()
|
||||
console.log('editor content', content)
|
||||
// 也可以同步到 <textarea>
|
||||
$("#content").val(content)
|
||||
}
|
||||
config[key] = value;
|
||||
});
|
||||
}
|
||||
})
|
||||
|
||||
options = $.extend(options, config);
|
||||
options.toolbar = [
|
||||
// [groupName, [list of button]]
|
||||
['para_style', ['style']],
|
||||
['style', ['bold', 'italic', 'underline', 'clear']],
|
||||
['font', ['strikethrough', 'superscript', 'subscript']],
|
||||
['fontsize', ['fontname', 'fontsize', 'height']],
|
||||
['color', ['color']],
|
||||
['para', ['ul', 'ol', 'paragraph', 'hr']],
|
||||
['table', ['table']],
|
||||
['insert', ['link', 'picture', 'video']],
|
||||
['do', ['undo', 'redo']],
|
||||
['misc', ['fullscreen', 'codeview', 'help']]
|
||||
];
|
||||
$(this).summernote(options);
|
||||
});
|
||||
window.toolbar = E.createToolbar({
|
||||
editor,
|
||||
selector: '#editor-toolbar',
|
||||
config: {}
|
||||
})
|
||||
|
||||
$(document).on('click', '[data-summernote-edit]', function(){
|
||||
var target = $(this).data('summernote-edit');
|
||||
$(target).summernote({focus: true});
|
||||
});
|
||||
|
||||
|
||||
$(document).on('click', '[data-summernote-save]', function(){
|
||||
var target = $(this).data('summernote-save');
|
||||
var markup = $(target).summernote('code');
|
||||
$(target).summernote('destroy');
|
||||
alert('修改完成');
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
|
||||
namespace app\api\controller;
|
||||
|
||||
use app\admin\extend\Util;
|
||||
use app\common\constant\Data;
|
||||
use app\common\model\Document;
|
||||
use app\Request;
|
||||
use think\Exception;
|
||||
use think\facade\Log;
|
||||
use think\Response;
|
||||
|
||||
class Article extends Base
|
||||
{
|
||||
public function list(){
|
||||
$where = Util::postMore([
|
||||
['cid',''],
|
||||
['typeId', ''],
|
||||
['orderBy', 'sort asc,create_time desc'],
|
||||
['row', 100],
|
||||
['void', 'field'],
|
||||
['model', "article"],
|
||||
['type', "find"],
|
||||
['where', ""],
|
||||
['display',1],
|
||||
['ids',""],
|
||||
['page',1],
|
||||
['limit',20],
|
||||
]);
|
||||
$list = tpl_get_article_list($where['cid'], $where['row'], $where['orderby'], $where['model'], $where['type'], $where['where'], $where['display'], $where['ids']);
|
||||
return app("json")->layui($list);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return mixed
|
||||
* @throws Exception
|
||||
*/
|
||||
public function detail(Request $request)
|
||||
{
|
||||
$where = Util::postMore([
|
||||
['id', ''],
|
||||
],$request);
|
||||
if (empty($where['id'])){
|
||||
return app("json")->fail("参数错误");
|
||||
}
|
||||
//获取该文章
|
||||
$documentModel = new Document();
|
||||
$article = $documentModel->getFullInfo($where['id'], Data::DOCUMENT_TYPE_ARTICLE);
|
||||
$article['cover_path'] = file_cdn($article['cover_path']);
|
||||
if (!$article) {
|
||||
return app("json")->fail("文章不存在或已删除");
|
||||
}
|
||||
return app("json")->success($article,'code');
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -27,8 +27,4 @@ class Base extends BaseController
|
|||
protected $userId;
|
||||
|
||||
// 初始化
|
||||
protected function initialize()
|
||||
{
|
||||
parent::initialize();
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ namespace app\api\controller;
|
|||
|
||||
use app\admin\controller\AuthController;
|
||||
use app\common\constant\Data;
|
||||
use app\common\model\SystemConfig;
|
||||
|
||||
/**
|
||||
* 应用入口
|
||||
|
|
@ -19,4 +20,13 @@ class Index extends Base
|
|||
{
|
||||
return app("json")->success("获取成功", 'code');
|
||||
}
|
||||
|
||||
public function config(){
|
||||
$systemConfig = cache(Data::DATA_SYSTEM_CONFIG);
|
||||
if (empty($systemConfig)) {
|
||||
$systemConfig = SystemConfig::getSystemConfigValues();
|
||||
cache(Data::DATA_SYSTEM_CONFIG, $systemConfig);
|
||||
}
|
||||
return app("json")->success($systemConfig,"code");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace app\api\controller;
|
||||
|
||||
use app\admin\controller\AuthController;
|
||||
use app\admin\extend\Util as Util;
|
||||
use app\admin\model\Admin as adminModel;
|
||||
use Exception;
|
||||
use think\db\exception\DataNotFoundException;
|
||||
use think\db\exception\DbException;
|
||||
use think\db\exception\ModelNotFoundException;
|
||||
use think\Response;
|
||||
|
||||
class Login extends Base
|
||||
{
|
||||
/**
|
||||
* 无需登录使用jwt
|
||||
* @var array
|
||||
*/
|
||||
protected $noNeedLogin = ['login', 'register', 'forget', 'captcha', 'verify'];
|
||||
|
||||
/**
|
||||
* 登录
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
public function login()
|
||||
{
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证登录
|
||||
* @return mixed
|
||||
* @throws DataNotFoundException
|
||||
* @throws DbException
|
||||
* @throws ModelNotFoundException
|
||||
*/
|
||||
public function verify()
|
||||
{
|
||||
list($username, $password, $captcha) = Util::postMore(['username', 'password', 'captcha'], null, true);
|
||||
if (empty($username) || empty($password)) return app("json")->fail("账号、密码和验证码不能为空!");
|
||||
// 验证码验证
|
||||
if (!captcha_check($captcha)) return app("json")->fail("验证码不正确!");
|
||||
// 验证登录
|
||||
if (!adminModel::login($username, $password)) return app("json")->fail(adminModel::getErrorInfo());
|
||||
return app("json")->success("登录成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
public function register(): string
|
||||
{
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 忘记密码
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
public function forget(): string
|
||||
{
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 退出登陆
|
||||
* @return mixed
|
||||
* @throws Exception
|
||||
*/
|
||||
public function logout()
|
||||
{
|
||||
return adminModel::clearLoginInfo() ? $this->successfulNotice("操作成功", "/admin/login/login") : $this->failedNotice("操作失败", "/admin/index/index");
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证码
|
||||
* @return Response
|
||||
*/
|
||||
public function captcha(): Response
|
||||
{
|
||||
ob_clean();
|
||||
return captcha();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
<?php
|
||||
|
||||
namespace app\api\controller;
|
||||
|
||||
class Page extends Base
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace app\api\controller;
|
||||
|
||||
class User extends Base
|
||||
{
|
||||
public function info(){
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@
|
|||
namespace app\common\model;
|
||||
|
||||
|
||||
use think\db\exception\DbException;
|
||||
use think\facade\Db;
|
||||
use think\Model;
|
||||
|
||||
|
|
@ -16,6 +17,22 @@ class BaseModel extends Model
|
|||
private static $transaction = 0;
|
||||
private static $DbInstance = [];
|
||||
|
||||
/**
|
||||
* 错误信息,解决调用无法明确错误的问题
|
||||
* @var mixed
|
||||
*/
|
||||
protected $error;
|
||||
|
||||
/**
|
||||
* 获取错误信息
|
||||
* @access public
|
||||
* @return mixed
|
||||
*/
|
||||
public function getError()
|
||||
{
|
||||
return $this->error;
|
||||
}
|
||||
|
||||
//自动时间戳
|
||||
protected $autoWriteTimestamp = true;
|
||||
|
||||
|
|
@ -30,53 +47,18 @@ class BaseModel extends Model
|
|||
}
|
||||
|
||||
/**
|
||||
* 开启事务
|
||||
* 查询一条数据是否存在
|
||||
* @param $map
|
||||
* @param string $field
|
||||
* @return bool 是否存在
|
||||
* @throws DbException
|
||||
*/
|
||||
public static function beginTrans()
|
||||
public static function isExist($map, $field = ''): bool
|
||||
{
|
||||
Db::startTrans();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据结果提交滚回事务
|
||||
* @param $res
|
||||
*/
|
||||
public static function checkTrans($res)
|
||||
{
|
||||
if ($res) {
|
||||
self::commitTrans();
|
||||
} else {
|
||||
self::rollbackTrans();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 提交事务
|
||||
*/
|
||||
public static function commitTrans()
|
||||
{
|
||||
Db::commit();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置错误信息
|
||||
* @param string $errorMsg
|
||||
* @param bool $rollback
|
||||
* @return bool
|
||||
*/
|
||||
protected static function setErrorInfo($errorMsg = self::DEFAULT_ERROR_MSG, $rollback = false)
|
||||
{
|
||||
if ($rollback) self::rollbackTrans();
|
||||
self::$errorMsg = $errorMsg;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭事务
|
||||
*/
|
||||
public static function rollbackTrans()
|
||||
{
|
||||
Db::rollback();
|
||||
$model = (new self);
|
||||
if (!is_array($map) && empty($field)) $field = $model->getPk();
|
||||
$map = !is_array($map) ? [$field => $map] : $map;
|
||||
return 0 < $model->where($map)->count();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -51,8 +51,11 @@ class Document extends BaseModel
|
|||
* 获取文章信息
|
||||
* @param $id
|
||||
* @param string $type
|
||||
* @param string $status
|
||||
* @param int $status
|
||||
* @return array
|
||||
* @throws DataNotFoundException
|
||||
* @throws DbException
|
||||
* @throws ModelNotFoundException
|
||||
*/
|
||||
public function getInfo($id, string $type = Data::DOCUMENT_TYPE_ARTICLE, $status = 1): array
|
||||
{
|
||||
|
|
@ -183,4 +186,50 @@ class Document extends BaseModel
|
|||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文章信息
|
||||
* @param $id
|
||||
* @param string $type
|
||||
* @param int $status
|
||||
* @return array
|
||||
* @throws DataNotFoundException
|
||||
* @throws DbException
|
||||
* @throws ModelNotFoundException
|
||||
*/
|
||||
public function getFullInfo($id, string $type = Data::DOCUMENT_TYPE_ARTICLE, $status = 1): array
|
||||
{
|
||||
if (empty($id)) {
|
||||
return [];
|
||||
}
|
||||
$model = new Document();
|
||||
$model = $model->alias('a')
|
||||
->leftJoin('document_category c', 'c.id = a.category_id')
|
||||
->leftJoin('user u', 'u.id = a.uid')
|
||||
->field("a.*,p.content,c.title,c.alias,u.nickname,u.avatar,u.remark")
|
||||
;
|
||||
if (is_numeric($id)) {
|
||||
$model->where("a.id", $id);
|
||||
} else {
|
||||
$model->where("a.alias", $id);
|
||||
}
|
||||
if ($type !== '') $model->where("a.type", $type);
|
||||
if ($status !== '') $model->where("a.status", $status);
|
||||
switch ($type) {
|
||||
case Data::DOCUMENT_TYPE_ARTICLE:
|
||||
$model->leftJoin('document_article p', 'a.id = p.id');
|
||||
break;
|
||||
case Data::DOCUMENT_TYPE_PAGE:
|
||||
$model->leftJoin('document_page p', 'a.id = p.id');
|
||||
break;
|
||||
case Data::DOCUMENT_TYPE_PRODUCT:
|
||||
$model->leftJoin('document_product p', 'a.id = p.id');
|
||||
break;
|
||||
}
|
||||
$info = $model->find();
|
||||
if (!$info) {
|
||||
return [];
|
||||
}
|
||||
return $info->toArray();
|
||||
}
|
||||
}
|
||||
|
|
@ -13,34 +13,5 @@ use think\Model;
|
|||
|
||||
trait ModelTrait
|
||||
{
|
||||
/**
|
||||
* 错误信息,解决调用无法明确错误的问题
|
||||
* @var mixed
|
||||
*/
|
||||
protected $error;
|
||||
|
||||
/**
|
||||
* 获取错误信息
|
||||
* @access public
|
||||
* @return mixed
|
||||
*/
|
||||
public function getError()
|
||||
{
|
||||
return $this->error;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询一条数据是否存在
|
||||
* @param $map
|
||||
* @param string $field
|
||||
* @return bool 是否存在
|
||||
* @throws DbException
|
||||
*/
|
||||
public static function isExist($map, $field = ''): bool
|
||||
{
|
||||
$model = (new self);
|
||||
if (!is_array($map) && empty($field)) $field = $model->getPk();
|
||||
$map = !is_array($map) ? [$field => $map] : $map;
|
||||
return 0 < $model->where($map)->count();
|
||||
}
|
||||
}
|
||||
|
|
@ -25,6 +25,7 @@ class Ape extends TagLib
|
|||
'tags' => ['attr' => 'tags,void', 'close' => 1],
|
||||
'archive' => ['attr' => 'type,format,void', 'close' => 1],
|
||||
'nav' => ['attr' => 'type,typeId,row,void,where,orderBy,display', 'close' => 1],
|
||||
'table' => ['attr' => 'name,where,orderby,row,pagesize,void', 'close' => 1]
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
@ -129,7 +130,7 @@ class Ape extends TagLib
|
|||
* @param $content
|
||||
* @return string
|
||||
*/
|
||||
public function tagList($tag, $content): string
|
||||
public function tagList($tag, $content)
|
||||
{
|
||||
$orderBy = $tag['orderBy'] ?? 'sort desc,create_time desc';
|
||||
$pageSize = $tag['pageSize'] ?? 15;
|
||||
|
|
@ -193,6 +194,24 @@ class Ape extends TagLib
|
|||
return $parse;
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行SQL
|
||||
*/
|
||||
public function tagSql($tag,$content)
|
||||
{
|
||||
if(!isset($tag['sql'])){
|
||||
return '';
|
||||
}
|
||||
$sql=$tag['sql'];
|
||||
$parse = '<?php ';
|
||||
$parse .= '$__LIST__ ='."db()->query(\"$sql\");";
|
||||
$parse .= ' ?>';
|
||||
$parse .= '{volist name="__LIST__" id="field"}';
|
||||
$parse .= $content;
|
||||
$parse .= '{/volist}';
|
||||
return $parse;
|
||||
}
|
||||
|
||||
/**
|
||||
* tagAdvert 广告
|
||||
* @param $tag
|
||||
|
|
@ -371,4 +390,35 @@ class Ape extends TagLib
|
|||
$parse .= '{/volist}';
|
||||
return $parse;
|
||||
}
|
||||
|
||||
/**
|
||||
* 表数据读取
|
||||
*/
|
||||
public function tagTable($tag, $content)
|
||||
{
|
||||
$name = isset($tag['name']) ? $tag['name'] : false;
|
||||
if (!$name) {
|
||||
return '';
|
||||
}
|
||||
$orderby = isset($tag['orderby']) ? $tag['orderby'] : '';
|
||||
$pagesize = isset($tag['pagesize']) ? $tag['pagesize'] : '';
|
||||
$void = isset($tag['void']) ? $tag['void'] : 'field';
|
||||
$where = isset($tag['where']) ? $tag['where'] : '';
|
||||
$row = isset($tag['row']) ? $tag['row'] : '100';
|
||||
|
||||
$parse = '<?php ';
|
||||
$parse .= '$__FUN__ =' . "tpl_get_table_list(\"$orderby\",\"$pagesize\",\"$name\",\"$where\",$row);";
|
||||
if ($pagesize) {
|
||||
$parse .= '$__LIST__ =$__FUN__["lists"];$pager = $__FUN__["model"]->render();';
|
||||
} else {
|
||||
$parse .= '$__LIST__ =$__FUN__;';
|
||||
}
|
||||
|
||||
$parse .= ' ?>';
|
||||
$parse .= '{volist name="__LIST__" id="' . $void . '"}';
|
||||
$parse .= $content;
|
||||
$parse .= '{/volist}';
|
||||
return $parse;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -105,6 +105,7 @@ function get_document_category_by_name($name, $field = false)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取一个文章分类
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -34,8 +34,8 @@ return [
|
|||
// 异常页面的模板文件
|
||||
'exception_tmpl' => app()->getThinkPath() . 'tpl/think_exception.tpl',
|
||||
// 默认跳转页面对应的模板文件
|
||||
'dispatch_success_tmpl' => root_path(). 'app/common/tpl/dispatch_jump.tpl',
|
||||
'dispatch_error_tmpl' => root_path(). 'app/common/tpl/dispatch_jump.tpl',
|
||||
'dispatch_success_tmpl' => public_path() . '/tpl/dispatch_jump.tpl',
|
||||
'dispatch_error_tmpl' => public_path() . '/tpl/dispatch_jump.tpl',
|
||||
|
||||
// 错误显示信息,非调试模式有效
|
||||
'error_message' => '页面错误!请稍后再试~',
|
||||
|
|
|
|||
|
|
@ -0,0 +1,120 @@
|
|||
# 安装教程
|
||||
|
||||
#### 一、ape博客推荐你使用阿里云和腾讯云服务器
|
||||
|
||||
阿里云服务器官方长期折扣优惠地址:
|
||||
点击访问,([https://www.aliyun.com/daily-act/ecs/activity_selection?userCode=dery8ymr](https://www.aliyun.com/daily-act/ecs/activity_selection?userCode=dery8ymr))
|
||||
|
||||
腾讯云服务器官方长期折扣优惠地址:
|
||||
点击访问,([https://curl.qcloud.com/G8kYi1YB](https://curl.qcloud.com/G8kYi1YB))
|
||||
|
||||
服务器最低配置:
|
||||
|
||||
```auto
|
||||
1核CPU (建议2核+)
|
||||
2G内存 (建议4G+)
|
||||
2M带宽 (建议5M+)
|
||||
```
|
||||
|
||||
#### 二、服务器运行环境要求
|
||||
|
||||
```auto
|
||||
PHP >= 7.1
|
||||
Mysql >= 5.5.0 (需支持innodb引擎)
|
||||
Apache 或 Nginx
|
||||
PDO PHP Extension
|
||||
MBstring PHP Extension
|
||||
CURL PHP Extension
|
||||
Composer (用于管理第三方扩展包)
|
||||
```
|
||||
|
||||
#### 三、系统安装
|
||||
|
||||
**方式一:完整包安装**
|
||||
|
||||
第一步:前往官网博客下载页面 ([https://gitee.com/muziys/apeblog/releases](https://gitee.com/muziys/apeblog/releases)) 下载完整包解压到你的项目目录
|
||||
|
||||
第二步:添加虚拟主机并绑定到项目的public目录
|
||||
|
||||
第三步:访问 [http://www.yoursite.com/install/index](http://www.yoursite.com/install/index) 进行安装
|
||||
|
||||
**方式二:命令行安装(推荐)**
|
||||
推荐使用命令行安装,因为采用命令行安装的方式可以和勾股blog随时保持更新同步。使用命令行安装请提前准备好`Git`、`Composer`。
|
||||
|
||||
**Linux下,勾股blog的安装请使用以下命令进行安装**
|
||||
|
||||
第一步:克隆ape博客到你本地
|
||||
|
||||
```shell
|
||||
git clone https://gitee.com/gougucms/blog.git
|
||||
```
|
||||
|
||||
复制
|
||||
|
||||
第二步:进入目录
|
||||
|
||||
```shell
|
||||
cd blog
|
||||
```
|
||||
|
||||
复制
|
||||
|
||||
第三步:下载PHP依赖包
|
||||
|
||||
composer install
|
||||
|
||||
第四步:添加虚拟主机并绑定到项目的public目录
|
||||
实际部署中,确保绑定域名访问到的是public目录。
|
||||
|
||||
第五步:访问 [http://www.yoursite.com/install/index](http://www.yoursite.com/install/index) 进行安装
|
||||
|
||||
⚠️ 注意:安装过程中,系统会自动创建数据库,请确保填写的数据库用户的权限可创建数据库,如果权限不足,请先手动创建空的数据库,然后填写刚创建的数据库名称和用户名也可完成安装。
|
||||
|
||||
🔺 提醒:安装过程中,如果进度条卡住,一般都是数据库写入权限或者安装环境配置问题,请注意检查。
|
||||
|
||||
⚠️遇到解决不了的问题请到QQ群反馈:24641076(群一满),46924914(群二满),295256660(群三)。
|
||||
|
||||
✅ PS:如需要重新安装,请删除目录里面 config/install.lock 的文件,即可重新安装。
|
||||
|
||||
#### 四、伪静态配置
|
||||
|
||||
**Nginx**
|
||||
|
||||
修改nginx.conf 配置文件 加入下面的语句。
|
||||
|
||||
```shell
|
||||
location /admin/ {
|
||||
index index.php index.html index.htm;
|
||||
if (!-e $request_filename){
|
||||
rewrite ^/admin/(.*)$ /admin.php?s=$1;
|
||||
}
|
||||
}
|
||||
location /api/ {
|
||||
index index.php index.html index.htm;
|
||||
if (!-e $request_filename){
|
||||
rewrite ^/api/(.*)$ /api.php?s=$1;
|
||||
}
|
||||
}
|
||||
location / {
|
||||
index index.php index.html index.htm;
|
||||
if (!-e $request_filename){
|
||||
rewrite ^/(.*)$ /index.php?s=$1 last;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Apache**
|
||||
|
||||
把下面的内容保存为.htaccess文件放到应用入 public 文件的同级目录下。
|
||||
|
||||
```shell
|
||||
<IfModule mod_rewrite.c>
|
||||
Options +FollowSymlinks -Multiviews
|
||||
RewriteEngine On
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteRule ^admin/(.*)$ admin.php?s=$1;
|
||||
RewriteRule ^api/(.*)$ api.php?s=$1;
|
||||
RewriteRule ^(.*)$ index.php?s=$1 [L]
|
||||
</IfModule>
|
||||
```
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
# 常见问题
|
||||
|
||||
1、安装失败,可能存在php配置文件禁止了`putenv`和`proc_open`函数。解决方法,查找`php.ini`文件位置,打开`php.ini`,搜索`disable_functions`项,看是否禁用了`putenv` 和`proc_open`函数。如果在禁用列表里,移除`putenv` `proc_open`然后退出,重启php即可。
|
||||
|
||||
2、如果安装后打开页面提示`404`错误,请检查服务器伪静态配置,如果是宝塔面板,网站伪静态请配置使用`thinkphp规则`。
|
||||
|
||||
**伪静态配置如下:**
|
||||
|
||||
**Nginx**
|
||||
|
||||
修改nginx.conf 配置文件 加入下面的语句。
|
||||
|
||||
```shell
|
||||
location /admin/ {
|
||||
index index.php index.html index.htm;
|
||||
if (!-e $request_filename){
|
||||
rewrite ^/admin/(.*)$ /admin.php?s=$1;
|
||||
}
|
||||
}
|
||||
location /api/ {
|
||||
index index.php index.html index.htm;
|
||||
if (!-e $request_filename){
|
||||
rewrite ^/api/(.*)$ /api.php?s=$1;
|
||||
}
|
||||
}
|
||||
location / {
|
||||
index index.php index.html index.htm;
|
||||
if (!-e $request_filename){
|
||||
rewrite ^/(.*)$ /index.php?s=$1 last;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Apache**
|
||||
|
||||
把下面的内容保存为.htaccess文件放到应用入 public 文件的同级目录下。
|
||||
|
||||
```shell
|
||||
<IfModule mod_rewrite.c>
|
||||
Options +FollowSymlinks -Multiviews
|
||||
RewriteEngine On
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteRule ^admin/(.*)$ admin.php?s=$1;
|
||||
RewriteRule ^api/(.*)$ api.php?s=$1;
|
||||
RewriteRule ^(.*)$ index.php?s=$1 [L]
|
||||
</IfModule>
|
||||
```
|
||||
|
||||
3、如果提示当前权限不足,无法写入配置文件`config/database.php`,请检查`database.php`是否可读,还有可能是当前安装程序无法访问父目录,请检查PHP的`open_basedir`配置。
|
||||
|
||||
4、如果`composer install`失败,请尝试在命令行进行切换配置到国内源,命令如下:
|
||||
|
||||
```shell
|
||||
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/
|
||||
```
|
||||
|
||||
复制
|
||||
|
||||
5、如果`composer install`失败,请尝试composer降级:
|
||||
|
||||
```shell
|
||||
composer self-update
|
||||
```
|
||||
|
||||
复制
|
||||
|
||||
6、如果`composer install`失败,请尝试删除项目文件,重新拉取。
|
||||
|
||||
7、访问 [http://www.yoursite.com/install/index](http://www.yoursite.com/install/index) ,请注意查看伪静态请配置是否设置了`thinkphp规则`。
|
||||
|
||||
8、遇到问题请到QQ:**1099438829** 反馈,或者到**Issue**里面反馈,谢谢!
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
**初始的目录结构如下:**
|
||||
|
||||
```auto
|
||||
www 系统部署目录(或者子目录)
|
||||
├── app 应用目录
|
||||
│ ├── admin 后台模块目录
|
||||
│ │ ├── config 后台配置文件目录
|
||||
│ │ ├── controller 控制器目录
|
||||
│ │ ├── extend 拓展目录
|
||||
│ │ ├── lang 语言文件目录
|
||||
│ │ ├── model 模型目录
|
||||
│ │ ├── subscribes 事件目录
|
||||
│ │ └── view 视图模板目录
|
||||
│ ├── api
|
||||
│ │ └── controller 控制器目录
|
||||
│ ├── common 公共目录
|
||||
│ │ ├── constant 全局变量目录
|
||||
│ │ ├── extend 拓展目录
|
||||
│ │ ├── model 模型目录
|
||||
│ │ ├── paginator 分页组件
|
||||
│ │ ├── taglib 模板拓展标签
|
||||
│ │ └── validate 校验器目录
|
||||
│ └── index
|
||||
│ ├── config 配置目录
|
||||
│ ├── controller 控制器目录
|
||||
│ ├── route 路由目录
|
||||
│ └── validate 校验器目录
|
||||
├── config 配置文件目录
|
||||
├── public 公共目录
|
||||
│ ├── doc 文档目录
|
||||
│ ├── install 安装模块目录(系统安装完后,建议删除)
|
||||
│ │ ├── css 安装器css
|
||||
│ │ ├── images 图片资源
|
||||
│ │ ├── js js资源
|
||||
│ │ └── templates 模板
|
||||
│ ├── static 系统静态资源
|
||||
│ │ ├── admin 后台静态资源
|
||||
│ │ └── banner banner静态文件
|
||||
│ ├── storage 文件存储目录
|
||||
│ │ └── image 图片目录
|
||||
│ ├── template 主题目录
|
||||
│ │ └── default 默认主题
|
||||
│ └── tpl 系统跳转等模板目录
|
||||
├───route 路由目录
|
||||
├───vendor 第三方类库目录(Composer依赖库目录)
|
||||
├───runtime 应用的运行时目录(可写,可定制)
|
||||
├───composer.json composer 定义文件
|
||||
├───LICENSE.txt 授权说明文件
|
||||
├───README.md README 文件
|
||||
├───think 命令行入口文件
|
||||
```
|
||||
|
|
@ -317,11 +317,11 @@
|
|||
</main>
|
||||
{include file="public/footer"/}
|
||||
</div>
|
||||
<script src="__LIB__/highlight/highlight.min.js"></script>
|
||||
<script src="__LIB__/highlight/init.js"></script>
|
||||
<script src="__JS__/post-content.js"></script>
|
||||
<script src="__JS__/clipboard.min.js"></script>
|
||||
<script src="__LIB__/fancybox/jquery.fancybox.min.js"></script>
|
||||
<script src="__LIB__/fancybox/init.js"></script>
|
||||
<script src="__LIB__/highlight/highlight.min.js"></script>
|
||||
<script src="__JS__/post-content.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -69,14 +69,14 @@
|
|||
}
|
||||
|
||||
|
||||
pre.corepress-code-pre code {
|
||||
pre.ape-code-pre code {
|
||||
position: relative;
|
||||
max-height: 500px;
|
||||
overflow: auto;
|
||||
padding: 10px 20px;
|
||||
}
|
||||
|
||||
.corepress-code-pre:hover .code-bar {
|
||||
.ape-code-pre:hover .code-bar {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
}
|
||||
|
|
@ -105,7 +105,7 @@ pre.corepress-code-pre code {
|
|||
cursor: pointer;
|
||||
}
|
||||
|
||||
pre[class='corepress-code-pre'] {
|
||||
pre[class='ape-code-pre'] {
|
||||
position: relative;
|
||||
font-size: 14px;
|
||||
margin: 0;
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -1,10 +1,12 @@
|
|||
document.addEventListener('DOMContentLoaded', (event) => {
|
||||
document.querySelectorAll('.corepress-code-pre code').forEach((block) => {
|
||||
hljs.highlightBlock(block);
|
||||
document.querySelectorAll('pre').forEach((pre) => {
|
||||
pre.classList.add('ape-code-pre');
|
||||
pre.querySelectorAll('code').forEach((block) => {
|
||||
hljs.highlightBlock(block);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
$('.corepress-code-pre').append('<div class="code-bar"><i class="fal fa-clone code-bar-btn-copy-fonticon" title="复制"></i></div>')
|
||||
$(".corepress-code-pre code").each(function () {
|
||||
$('pre').append('<div class="code-bar"><i class="fal fa-clone code-bar-btn-copy-fonticon" title="复制"></i></div>')
|
||||
$("pre code").each(function () {
|
||||
$(this).html("<ul class='hijs-line-number'><li>" + $(this).html().replace(/\n/g, "\n</li><li>") + "\n</li></ul>");
|
||||
});
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@
|
|||
}
|
||||
|
||||
|
||||
pre.corepress-code-pre code {
|
||||
pre.ape-code-pre code {
|
||||
position: relative;
|
||||
border-radius: 5px;
|
||||
max-height: 500px;
|
||||
|
|
@ -76,7 +76,7 @@ pre.corepress-code-pre code {
|
|||
padding: 10px 20px;
|
||||
}
|
||||
|
||||
.corepress-code-pre:hover .code-bar {
|
||||
.ape-code-pre:hover .code-bar {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
}
|
||||
|
|
@ -103,7 +103,7 @@ pre.corepress-code-pre code {
|
|||
color: #fff;
|
||||
cursor: pointer;
|
||||
}
|
||||
pre[class='corepress-code-pre'] {
|
||||
pre[class='ape-code-pre'] {
|
||||
position: relative;
|
||||
font-size: 14px;
|
||||
border-radius: 4px;
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@
|
|||
}
|
||||
|
||||
|
||||
pre.corepress-code-pre code {
|
||||
pre.ape-code-pre code {
|
||||
position: relative;
|
||||
border-radius: 5px;
|
||||
background: #fafafa;
|
||||
|
|
@ -62,7 +62,7 @@ pre.corepress-code-pre code {
|
|||
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace, sans-serif;
|
||||
}
|
||||
|
||||
.corepress-code-pre:hover .code-bar {
|
||||
.ape-code-pre:hover .code-bar {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
}
|
||||
|
|
@ -88,7 +88,7 @@ pre.corepress-code-pre code {
|
|||
.code-bar-btn-copy-fonticon {
|
||||
cursor: pointer;
|
||||
}
|
||||
pre[class='corepress-code-pre'] {
|
||||
pre[class='ape-code-pre'] {
|
||||
position: relative;
|
||||
font-size: 14px;
|
||||
border-radius: 4px;
|
||||
|
|
|
|||
Loading…
Reference in New Issue