Compare commits

...

4 Commits

Author SHA1 Message Date
yumo a353e056be 完善接口数据 2023-12-31 18:15:31 +08:00
yumo cc15e83a70 更新编辑器为wangEditer
主题支持代码高亮和复制
2023-12-31 12:59:27 +08:00
yumo 759fe7fa06 完善ape拓展标签 2023-12-19 16:34:54 +08:00
yumo 16cfdb89b6 添加文档信息和修复主页的bug 2023-12-14 18:30:24 +08:00
27 changed files with 646 additions and 197 deletions

View File

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

View File

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

View File

@ -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('修改完成');
});
});
/**

View File

@ -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('修改完成');
});
});
/**

View File

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

View File

@ -27,8 +27,4 @@ class Base extends BaseController
protected $userId;
// 初始化
protected function initialize()
{
parent::initialize();
}
}

View File

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

View File

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

View File

@ -0,0 +1,8 @@
<?php
namespace app\api\controller;
class Page extends Base
{
}

View File

@ -0,0 +1,10 @@
<?php
namespace app\api\controller;
class User extends Base
{
public function info(){
}
}

View File

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

View File

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

View File

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

View File

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

View File

@ -105,6 +105,7 @@ function get_document_category_by_name($name, $field = false)
}
}
/**
* 获取一个文章分类
*/

View File

@ -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' => '页面错误!请稍后再试~',

120
public/doc/安装教程.md Normal file
View File

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

View File

@ -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**里面反馈,谢谢!

View File

@ -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 命令行入口文件
```

View File

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

View File

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

View File

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

View File

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

View File

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