7

基于 Laravel6.x 构建的博客应用,支持 Markdown,支持图片拖拽上传,基于 RBAC 权限管理系统

首页

首页.png

基于 RBAC 的权限管理后台,Dashboard 页面统计了用户总数、文章发布总数、评论率、评论总数、文章支持按天、按月、按年统计、支持按分类、按标签统计……

后台首页.png

登录页面

登录页面.png

注册页面

注册页面.png

支持 GitHub 授权登录

GitHub授权登录页面.png

支持邮箱重置密码

重置密码页面.png

同时兼容 HTML 编辑器和 Markdown 编辑器

富文本编辑器.png

markdown 编辑器.png

Markdown 编辑器:支持拖拽粘贴上传图片、预览、全屏、分屏预览

markdown 编辑器预览效果.png

支持代码高亮

文章详情.png

后台用户.png

项目概述

功能如下

  • 用户认证 —— 注册、登录、退出;
  • 个人中心 —— 用户个人中心,编辑资料;
  • 用户授权 —— 作者才能删除自己的内容;
  • 上传图片 —— 修改头像和编辑文章时上传图片;
  • 表单验证 —— 使用表单验证类;
  • 重置密码 —— 通过邮箱找回密码
  • 文章支持分类、多标签、访问量统计;
  • 编辑文章支持 markdown 编辑器 、html 编辑器;
  • markdown 编辑器支持拖拽上传图片、截屏粘贴上传图片、语法高亮、预览、全屏、分屏实时预览;
  • 文章发布时自动 Slug 翻译,支持使用队列方式以提高响应;
  • 站点『活跃用户』计算,一小时计算一次;
  • 多角色权限管理 —— 允许站长,管理员权限的存在;
  • 后台管理 —— 基于 RBAC 后台数据模型管理;
  • 邮件通知 —— 发送新回复邮件通知,队列发送邮件;
  • 站内通知 —— 文章有新回复;
  • 自定义 Artisan 命令行 —— 自定义活跃用户计算命令;
  • 自定义 Trait —— 活跃用户的业务逻辑实现;
  • 自定义中间件 —— 记录用户的最后登录时间;
  • XSS 安全防御;
  • 第三方授权登录,目前支持 GitHub,兼容 Facebook,Twitter,LinkedIn,Google,GitHub,GitLab 和 Bitbucket 的身份验证;
  • 支持自定义 meta title、description、keywords;
  • 支持友链
  • 站点地图
  • RSS 订阅

运行环境要求

  • Nginx 1.8+
  • PHP 7.0+
  • Mysql 5.7+
  • Redis 3.0+

开发环境部署和安装

本项目代码使用 PHP 框架 laravel6.x 开发,本地开发环境使用 Laravel Homestead

基础安装

  1. 克隆源代码

克隆 larablog 源代码到本地:

// gitee
git clone git@gitee.com:pudongping/larablog.git

// GitHub
git clone git@github.com:pudongping/larablog.git
  1. 安装扩展包依赖
// 先切换到 larablog 项目根目录
cd larablog

// 执行安装命令
composer install
  1. 生成配置文件
cp .env.example .env

你可以根据情况修改 .env 文件里的内容,如数据库连接、缓存、邮件设置、第三方授权登录等:


DB_HOST=localhost
DB_DATABASE=larablog
DB_USERNAME=homestead
DB_PASSWORD=secret
  1. 生成数据表及生成测试数据
// 需要生成测试数据则执行:
php artisan migrate --seed

// 不需要生成测试数据则执行:
php artisan migrate
  1. 生成秘钥

php artisan key:generate
  1. 创建 storage 软连接

php artisan storage:link
  1. 赋予 storage 相应权限

// 建议在 Linux 系统中新建一个 www 用户,并设置该用户不可登录系统
useradd -s /sbin/nologin www

// 将项目目录所有权赋予 www 用户
chown -Rf www:www larablog

// 给 storage 目录赋权限
chmod -Rf 0755 larablog/storage/
  1. 配置 hosts 文件 (如果直接想部署在线上环境,则跳过此步骤)

如果开发环境没有采用 Laravel Homestead 则 ip 映射以你实际为主,一般为 127.0.0.1。我这里使用的 Laravel Homestead 虚拟机的 ip 地址为:192.168.10.10

// Linux 或 MacOS 环境

echo "192.168.10.10   larablog.test" | sudo tee -a /etc/hosts

// Windows 环境
需要打开 C:/Windows/System32/Drivers/etc/hosts  文件,然后新增一行

192.168.10.10 larablog.test

前端安装

  1. 安装 npm 和 yarn

CentOS / Fedora / RHEL 环境下

文档地址:https://yarn.bootcss.com/docs/install/#centos-stable
  • 配置相应的 yum 源
curl --silent --location https://dl.yarnpkg.com/rpm/yarn.repo | sudo tee /etc/yum.repos.d/yarn.repo

curl --silent --location https://rpm.nodesource.com/setup_8.x | sudo bash -
  • 之后执行以下任意一条命令,就可以了
sudo yum install yarn
## OR ##
sudo dnf install yarn

Windows 环境下

  • 安装 node.js

直接去官网 https://nodejs.org/en 下载安装最新版本。

  • 安装 Yarn

请安装最新版本的 Yarn —— http://yarnpkg.cn/zh-Hans/docs/install

  1. 为 NPM 和 Yarn 配置淘宝镜像,加速安装包下载
npm config set registry=https://registry.npm.taobao.org

yarn config set registry https://registry.npm.taobao.org
  1. 使用 Yarn 安装前端依赖包
yarn install

或者

npm install
  • 监控 resources 文件夹下的资源文件是否有发生改变。在 watch-poll 命令运行的情况下,一旦资源文件发生变化,Webpack 会自动重新编译。
npm run watch-poll

// 如果遇到报错,尝试先执行以下命令更新 npm 到最新版本,之后再次执行监控命令
npm install -g npm
  • 编译前端内容
// 运行所有 Mix 任务...
npm run dev

// 运行所有 Mix 任务并缩小输出..
npm run production

访问入口

管理员账号密码如下:

username: 1414818093@qq.com
password: 123456

默认网站第一位用户为站长角色,第二位用户为管理员角色。如果填充了测试数据,则默认所有用户的密码为:123456

==至此,安装完成^_^。enjoy yourself……==

后端扩展包使用情况

扩展包简介描述本项目应用场景
laravel/uilaravel 6.x UI 脚手架前端页面框架
barryvdh/laravel-ide-helper能让你的 IDE (PHPStorm, Sublime) 实现自动补全、代码智能提示和代码跟踪等功能代码补全和智能提示
barryvdh/laravel-debugbar页面调试工具栏 (对 phpdebugbar 的封装)开发环境中的 DEBUG
overtrue/laravel-lang支持 52 个国家的语言包翻译 Laravel 自带模板
mews/captcha图片验证码注册页面图片验证码
intervention/image图片处理功能库用于图片裁剪
summerblue/laravel-active方便设置 active 类文章排序添加 active 类
mews/purifier用户提交的 Html 白名单过滤文章内容的 Html 安全过滤,防止 XSS 攻击
guzzlehttp/guzzleHTTP 请求套件请求百度翻译 API,翻译文章标题,做 SEO 优化
overtrue/pinyin基于 CC-CEDICT 词典的中文转拼音工具翻译文章标题的备用方案
predis/predisRedis 官方首推的 PHP 客户端开发包缓存驱动 Redis 基础扩展包
laravel/horizon队列监控队列监控命令与页面控制台 /horizon
spatie/laravel-permission角色权限管理角色和权限控制
viacreative/sudo-su用户切换调试环境中快速切换登录账号
erusev/parsedownmarkdown 转换 html 工具文章模块解析 markdown 语法
thephpleague/html-to-markdownhtml 转换成 markdown 工具文章编辑采用 markdown 编辑器时
laravel/socialitelaravel 官方推荐社会化登录Github 登录
suin/php-rss-writerrss 订阅生成生成 rss 订阅代码
hhxsv5/laravel-sLaravelS 是 Swoole 和 Laravel/Lumen 之间开箱即用的适配器优化访问速度

前端扩展包使用情况

扩展包简介描述本项目应用场景
yarn add @fortawesome/fontawesome-freeFont Awesome 提供了可缩放的矢量图标字体图标库
npm i startbootstrap-sb-admin-2界面简洁美观的皮肤cms 后台模板
npm install simplemdemarkdown 编辑器文章编辑器
npm install highlight.js语法高亮工具markdown 编辑器代码语法高亮
npm install inline-attachment文本框拖动上传图片工具markdown 文本框图片拖动上传
multiselect.js多选下拉框文章多选标签
chartjs图表插件后台管理界面图表

邮箱认证

  • 开发环境时将 .ENV 文件设置为如下所示,将邮箱认证邮件发送至当前日志中,以便调试

    MAIL_DRIVER=log
  • 生产环境时,建议将 .ENV 文件中相关邮件设置为自己所需配置,以下为默认配置

    MAIL_DRIVER=smtp
    MAIL_HOST=smtp.mailtrap.io
    MAIL_PORT=2525
    MAIL_USERNAME=null
    MAIL_PASSWORD=null
    MAIL_ENCRYPTION=null

翻译队列

  • 修改 .ENV 文件设置为

# 如果是开发环境的话,就把队列驱动改回 sync 同步模式,也就是说不使用任何队列,实时执行:
QUEUE_CONNECTION=redis
REDIS_CLIENT=predis
  • 启动队列系统,队列在启动完成后会进入监听状态
php artisan queue:listen

或者使用

php artisan horizon

文章标题翻译

使用了百度翻译 api,请将 .ENV中的百度 api 相关信息换成你自己的开发者信息

如果不采用百度翻译翻译文章标题的话,那么不用配置 .ENV 文件中以下配置项


# 百度翻译 APP ID
BAIDU_TRANSLATE_APPID=
# 百度翻译密钥 KEY
BAIDU_TRANSLATE_KEY=

并且也不需要更改


QUEUE_CONNECTION=redis

默认保持为


QUEUE_CONNECTION=sync

这样将会每发一篇文章时,将文章标题直接翻译成拼音达到 slug 的效果。

邮件通知

如果不想要,发表文章评论时有邮件通知,可以不用配置,直接忽略,功能上没有任何影响
  1. 需要先开启 QQ 邮箱的 SMTP 支持

如何打开 POP3/SMTP/IMAP 功能?

  1. 邮箱发送配置 (请将以下配置换成你自己的邮箱配置)
如果你是使用的阿里云 ECS,那么一定要注意,阿里云的 ECS 默认禁用了 25 端口,需要单独申请解封25端口,点我解封阿里云 ECS 25端口,如果你不知道如何解封,请查看 解封步骤。当然替代方案,你可以采用 465 端口,如果你打算采用 465 端口,那么需要将以下配置中的 MAIL_PORT 修改为 465,并且也需要将加密类型 MAIL_ENCRYPTION 修改为 ssl 即可,这里我使用的是 qq 邮箱,可能其他的邮箱服务有差异,视情况而定吧。
# 使用支持 ESMTP 的 SMTP 服务器发送邮件
MAIL_DRIVER=smtp
# QQ 邮箱的 SMTP 服务器地址,必须为此值
MAIL_HOST=smtp.qq.com
# QQ 邮箱的 SMTP 服务器端口,必须为此值
MAIL_PORT=25
# 请将此值换为你的 QQ + @qq.com
MAIL_USERNAME=xxxxxxxxxxxxxx@qq.com
# 密码是我们第一步拿到的授权码
MAIL_PASSWORD=xxxxxxxxx
# 加密类型,选项 null 表示不使用任何加密,其他选项还有 ssl,这里我们使用 tls 即可,如果出现报错的话,多半是因为这个 smtp 主机不支持 TLS,那么只需要将此项设置为 null 即可。
MAIL_ENCRYPTION=tls
# 此值必须同 MAIL_USERNAME 一致
MAIL_FROM_ADDRESS=xxxxxxxxxxxxxx@qq.com
# 用来作为邮件的发送者名称
MAIL_FROM_NAME=番茄炖土豆的个人博客
  1. 如果需要支持队列,请将 .ENV 配置文件中,设置成

QUEUE_CONNECTION=redis

用户切换调试

默认只在调试模式 .ENV 文件中


APP_DEBUG=true

时启用,且 config/sudosu.php 文件中


// 允许使用的顶级域名
'allowed_tlds' => ['dev', 'local', 'test'],
    

顶级域名(Top Level Domain)加入你域名的顶级域名

第三方授权登录

目前项目中只支持 github 授权登录,因为只申请了 GitHub 的 OAuth application,如果你也需要使用 GitHub 作为第三方授权登录,那么需要按照以下步骤进行:

  1. 在 GitHub 上注册一个 OAuth application
  • Application name:你可以填写你自己的应用名称,比如:myWebBlog
  • Homepage URL:首页连接地址需要添加你自己的,比如:http://larablog.test
  • Application description:应用描述可以随便填写,比如:自己的博客
  • Authorization callback URL:授权回调地址,一定要填写成: <Your domain>/login/github/callback ,比如,我这里则需要填写成:http://larablog.test/login/github/callback
  1. 注册成功之后,需要在 .ENV 配置文件中填写申请成功的 Client ID 和 Client Secret。填写好之后,直接访问 http://larablog.test/login/github 即可支持 GitHub 第三方授权登录,如果不设置 .ENV 配置文件,则登录、注册页面不会显示 GitHub 第三方授权登录入口。
# Github Client ID
GITHUB_CLIENT_ID=
# Github Client Secret
GITHUB_CLIENT_SECRET=
  1. 扩展其它第三方授权登录。

    Socialite 目前支持 Facebook,Twitter,LinkedIn,Google,GitHub,GitLab 和 Bitbucket 的身份验证。本项目已经对以上支持的第三方登录做了兼容性处理,如果我们需要支持以上除 GitHub 以外的应用(因为目前已经设置好了 GitHub 相关的配置),那么我们只需要按照以下的步骤配置即可。这里以 Google 为例子。
  • 第一步:申请 google 的 Client ID 和 Client Secret。
  • 第二步:将申请的 Client ID 和 Client Secret 填写入 .ENV 配置文件中
GOOGLE_CLIENT_ID="your google client id"
GOOGLE_CLIENT_SECRET="your google client secret"
  • 第三步:配置 app/services.php
'google' => [
    'client_id' => env('GOOGLE_CLIENT_ID'),  // google 客户端授权 ID
    'client_secret' => env('GOOGLE_CLIENT_SECRET'),  // google 客户端授权密钥
    'redirect' => '/login/google/callback',  // 授权回调链接 如果 redirect 配置项包含的是相对路径,系统会自动将其转化为完整 URL
],
  • 第四步:将第三方服务添加到 app/Models/Auth/User.php => $allowedProviders 数组中
public static $allowedProviders = ['github', 'google'];
  • 第五步:直接访问 <your domain>/login/google 即可

自定义 Artisan 命令

命令说明Cron
php artisan larablog:calculate-active-user生成活跃用户一个小时运行一次
php artisan larablog:sync-article-view-count同步文章的访问量每天早上 0 点准时
php artisan larablog:sync-user-actived-at从 Redis 中同步最后登录时间到数据库中每天早上 0 点准时

计划任务

当前计划任务主要是计算主页右侧 「活跃用户」

artisan 命令为:


php artisan larablog:calculate-active-user

同步文章的访问量

artisan 命令为:


php artisan larablog:sync-article-view-count

和同步 「用户最后活跃时间」 到数据库

artisan 命令为:


php artisan larablog:sync-user-actived-at

并且已经在 调度器 中设置好了相关代码。(调度器在 app/Console/Kernel.php 文件的 schedule 方法中定义)

使用 Linux 系统的 Cron 计划任务需执行


export EDITOR=vi && crontab -e

然后填入以下内容(注意将项目根目录换成你自己的)
这里我的项目根目录为:/home/vagrant/Code/larablog


* * * * * php /home/vagrant/Code/larablog/artisan schedule:run >> /dev/null 2>&1
如果不设定计划任务的话,直接执行以上 Artisan 命令的话会是如下情况:
「活跃用户」将每 65 分钟重新生成一次,设定计划任务的话,默认一个小时重新生成一次。
「用户最后活跃时间」将不会同步到数据库中,将会直接从 Redis 中获取,如果 Redis 中不存在,则以用户注册时间替代。

队列清单

文件路径说明调用时机
app\Notifications\ArticleReplied.php通知文章作者有新评论回复文章被评论以后 App\Observers\Portal\Article\ReplyObserver@created
app\Jobs\TranslateSlug.php将文章标题翻译为 Slug文章保存时 App\Observers\Portal\Article\ArticleObserver@saved

线上部署

如果需要优化网站打开速度,可依次进行如下步骤:

  • 压缩前端代码
npm run prod
  • 缓存路由

    # 缓存路由
    php artisan route:cache
    
    # 清空路由缓存
    php artisan route:clear
  • 缓存配置文件

    # 缓存配置文件
    php artisan config:cache
    
    # 清空配置文件缓存
    php artisan cache:clear
  • composer 优化

    sudo composer dump-autoload --optimize
  • 类映射加载优化

laravel 6.x 中,会生成 bootstrap/cache/config.phpbootstrap/cache/packages.phpbootstrap/cache/routes.phpbootstrap/cache/services.php 这四个文件。

php artisan optimize

# 清空类映射
php artisan optimize:clear
  • 使用 swoole 加速网站

在项目根目录下执行以下命令,以守护进程的方式运行 laravelS

php bin/laravels start -d

参考以下内容配置 nginx 配置


upstream swoole {
    # 如果是使用 laradock ,请将 127.0.0.1 更改为 workspace
    server 127.0.0.1:5200 weight=5 max_fails=3 fail_timeout=30s;
    keepalive 16;
}

server {
    listen 80;
    server_name pudongping.com www.pudongping.com;
    root /www/wwwroot/larablog/public;

    index index.html index.htm index.php;

    charset utf-8;

    location / {
        try_files $uri @laravels;
    }

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    access_log  /www/wwwlogs/pudongping.com.log;
    error_log  /www/wwwlogs/pudongping.com.error.log;

    sendfile off;

    client_max_body_size 100m;

    location @laravels {
        # proxy_connect_timeout 60s;
        # proxy_send_timeout 60s;
        # proxy_read_timeout 120s;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Real-PORT $remote_port;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header Scheme $scheme;
        proxy_set_header Server-Protocol $server_protocol;
        proxy_set_header Server-Name $server_name;
        proxy_set_header Server-Addr $server_addr;
        proxy_set_header Server-Port $server_port;
        # “swoole”是指upstream
        proxy_pass http://swoole;
    }

    location ~ /\.ht {
        deny all;
    }

}

如果是使用 laradock 的话,还需要将 .env 添加监听地址为 workspace

LARAVELS_LISTEN_IP=workspace

# 设置后台启动 laravelS 服务,如果需要查看则执行 ps -ef|grep laravels 命令
LARAVELS_DAEMONIZE=true

代码规范

遵循 PSR-2 编码风格规范
遵循 PSR-12 编码规范扩充

其他

代码中涵盖了丰富的注释,如果仍有不清楚之处,可以给我留言。
如果你觉得还不错,请帮我点一下 Star,不胜感激 !❤(❤´艸`❤)

GitHub 地址
码云 地址

License

源代码基于 MIT 协议发布。


左诗右码
85 声望11 粉丝

三观比五官更正,思想比套路更深。常用技术栈PHP、Go、Python,享受编程,平时爱好写点文章。V公主号:「左诗右码」,欢迎关注交流。