mirror of
https://gitee.com/koogua/course-tencent-cloud.git
synced 2025-06-26 04:21:27 +08:00
v1.2.4优化
This commit is contained in:
parent
197e4a62af
commit
f58a45a981
16
CHANGELOG.md
16
CHANGELOG.md
@ -1,3 +1,19 @@
|
||||
### [v1.2.4](https://gitee.com/koogua/course-tencent-cloud/releases/v1.2.4)(2021-01-10)
|
||||
|
||||
#### 增加
|
||||
|
||||
- 后台增加上传logo和favicon图标
|
||||
- 后台增加公众号自定义菜单配置
|
||||
- 课程页增加咨询
|
||||
|
||||
### 优化
|
||||
|
||||
- oauth中state参数为安全base64加解码
|
||||
- findById参数类型不对时抛出异常
|
||||
- task表增加索引加快数据查找
|
||||
- markdown内容解析改由后端完成
|
||||
- 公众号应答处理逻辑
|
||||
|
||||
### [v1.2.3](https://gitee.com/koogua/course-tencent-cloud/releases/v1.2.3)(2021-01-03)
|
||||
|
||||
#### 增加
|
||||
|
61
README.md
61
README.md
@ -2,16 +2,16 @@
|
||||
|
||||

|
||||
|
||||
#### 项目介绍
|
||||
### 项目介绍
|
||||
|
||||
酷瓜云课堂,依托腾讯云基础服务架构,采用C扩展框架Phalcon开发,GPL-2.0开源协议,致力开源网课系统,开源网校系统,开源在线教育系统。
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
#### 系统功能
|
||||
### 系统功能
|
||||
|
||||
实现了点播、直播、专栏、会员、微聊等,是一个完整的产品,具体功能我也不想写一大堆,自己体验吧!
|
||||
|
||||
@ -21,17 +21,19 @@
|
||||
- 课程数据来源于网络(无实质内容),切莫购买
|
||||
- 管理后台已禁止数据提交,私密配置已过滤
|
||||
|
||||
演示帐号:**13507083515 / 123456** (前后台通用)
|
||||
|
||||
桌面端演示:
|
||||
|
||||
- [前台演示](https://ctc.koogua.com)
|
||||
- [后台演示](https://ctc.koogua.com/admin)
|
||||
|
||||
演示帐号:100015@163.com / 123456 (前后台通用)
|
||||
|
||||
移动端演示:
|
||||
|
||||

|
||||
|
||||
演示帐号:13507083515 / 123456
|
||||
|
||||
支付流程演示:
|
||||
|
||||
- [MySQL提升课程全面讲解MySQL架构设计(0.01元)](https://ctc.koogua.com/order/confirm?item_id=1390&item_type=1)
|
||||
@ -40,7 +42,18 @@
|
||||
|
||||
Tips: 测试支付请用手机号注册一个新账户,以便接收订单通知,以及避免课程无法购买
|
||||
|
||||
#### 项目组件
|
||||
即时通讯演示:
|
||||
|
||||
请使用以下两个帐号在不同终端或者浏览器登录,打开微聊界面
|
||||
|
||||
- 帐号A:100015@163.com / 123456
|
||||
- 帐号B:100065@163.com / 123456
|
||||
|
||||
微信推送演示:
|
||||
|
||||
Tips: 请用手机注册一个新账号,用户中心 -> 关注订阅,扫码关注公众号。之后的登录、购买、退款、直播、咨询等会有消息推送。
|
||||
|
||||
### 项目组件
|
||||
|
||||
- 后台框架:[phalcon 3.4.5](https://phalcon.io)
|
||||
- 前端框架:[layui 2.5.6](https://layui.com), [layim 3.9.5](https://www.layui.com/layim)(已授权)
|
||||
@ -48,45 +61,27 @@ Tips: 测试支付请用手机号注册一个新账户,以便接收订单通
|
||||
- 即时通讯:[workerman 3.5.22](https://workerman.net)
|
||||
- 基础依赖:[php7.3](https://php.net), [mysql5.7](https://mysql.com), [redis5.0](https://redis.io)
|
||||
|
||||
#### 安装指南
|
||||
### 安装指南
|
||||
|
||||
- [运行环境搭建](https://gitee.com/koogua/course-tencent-cloud-docker)
|
||||
- [系统服务配置](https://gitee.com/koogua/course-tencent-cloud/wikis)
|
||||
- [客户终端配置](https://gitee.com/koogua/course-tencent-cloud-app)
|
||||
|
||||
#### 开发计划
|
||||
|
||||
- 桌面端:进行中
|
||||
- 移动端:进行中
|
||||
- 小程序:待启动
|
||||
|
||||
#### 意见反馈
|
||||
### 意见反馈
|
||||
|
||||
- [在线反馈](https://gitee.com/koogua/course-tencent-cloud/issues)(推荐)
|
||||
- [官方论坛](https://koogua.com/forum)(推荐)
|
||||
- QQ交流群: 787363898
|
||||
|
||||
#### 通过这个项目能学到什么?
|
||||
|
||||
- 项目规划,phalcon,缓存,JWT,即时通讯,全文检索
|
||||
- docker,supervisor,devops
|
||||
- git,linux,php,mysql,redis,nginx
|
||||
|
||||
#### 有阿里云版吗?
|
||||
### 有阿里云版吗?
|
||||
|
||||
阿里云版规划中,之前阿里云服务过期未续费,所以腾讯云版本先出。
|
||||
|
||||
#### 代码有加密吗?
|
||||
### 代码有加密吗?
|
||||
|
||||
所有代码都公开(授权代码除外,例如layim),没有所谓的商业版和付费插件。
|
||||
|
||||
#### 有商业服务吗?
|
||||
|
||||
生存才能发展,我们目前提供的服务包括:
|
||||
|
||||
- 系统安装
|
||||
- 系统定制
|
||||
- 企业授权
|
||||
|
||||
#### 开源助力
|
||||
### 开源助力
|
||||
|
||||
毫无保留的真开源不容易,如果对你有帮助,请给我们 **STAR** !!!
|
||||
|
||||
|
@ -210,29 +210,29 @@ class Setting extends Service
|
||||
|
||||
if (!empty($settings['menu'])) {
|
||||
foreach ($settings['menu'] as $i => $top) {
|
||||
$buttons[$i]['name'] = !empty($top['name']) ? $top['name'] : sprintf('菜单%s', $i + 1);
|
||||
if (!empty($top['url'])) {
|
||||
$buttons[$i]['name'] = $top['name'];
|
||||
$buttons[$i]['url'] = $top['url'];
|
||||
$buttons[$i]['type'] = 'view';
|
||||
}
|
||||
foreach ($top['children'] as $j => $sub) {
|
||||
if (!empty($sub['name']) && !empty($sub['url'])) {
|
||||
$buttons[$i]['sub_button'][$j]['name'] = $sub['name'];
|
||||
$buttons[$i]['sub_button'][$j]['url'] = $sub['url'];
|
||||
$buttons[$i]['sub_button'][$j]['type'] = 'view';
|
||||
} else {
|
||||
unset($settings['menu'][$i]['children'][$j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
$settings['menu'] = kg_json_encode($settings['menu']);
|
||||
}
|
||||
|
||||
$this->updateSettings($section, $settings);
|
||||
|
||||
if (!empty($buttons)) {
|
||||
$service = new WechatService();
|
||||
$oa = $service->getOfficialAccount();
|
||||
$oa->menu->create($buttons);
|
||||
}
|
||||
|
||||
$this->updateSettings($section, $settings);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Http\Home\Controllers;
|
||||
|
||||
use App\Http\Home\Services\Index as IndexService;
|
||||
use App\Services\Logic\Help\HelpInfo as HelpInfoService;
|
||||
use App\Services\Logic\Help\HelpList as HelpListService;
|
||||
|
||||
@ -12,7 +13,7 @@ class HelpController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* @Get("/index", name="home.help.index")
|
||||
* @Get("/", name="home.help.index")
|
||||
*/
|
||||
public function indexAction()
|
||||
{
|
||||
@ -34,9 +35,19 @@ class HelpController extends Controller
|
||||
|
||||
$help = $service->handle($id);
|
||||
|
||||
$featuredCourses = $this->getFeaturedCourses();
|
||||
|
||||
$this->seo->prependTitle(['帮助', $help['title']]);
|
||||
|
||||
$this->view->setVar('help', $help);
|
||||
$this->view->setVar('featured_courses', $featuredCourses);
|
||||
}
|
||||
|
||||
protected function getFeaturedCourses()
|
||||
{
|
||||
$service = new IndexService();
|
||||
|
||||
return $service->getSimpleFeaturedCourses();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Http\Home\Controllers;
|
||||
|
||||
use App\Http\Home\Services\Index as IndexService;
|
||||
use App\Services\Logic\Page\PageInfo as PageInfoService;
|
||||
|
||||
/**
|
||||
@ -19,9 +20,19 @@ class PageController extends Controller
|
||||
|
||||
$page = $service->handle($id);
|
||||
|
||||
$this->seo->prependTitle(['单页', $page['title']]);
|
||||
$featuredCourses = $this->getFeaturedCourses();
|
||||
|
||||
$this->seo->prependTitle($page['title']);
|
||||
|
||||
$this->view->setVar('page', $page);
|
||||
$this->view->setVar('featured_courses', $featuredCourses);
|
||||
}
|
||||
|
||||
protected function getFeaturedCourses()
|
||||
{
|
||||
$service = new IndexService();
|
||||
|
||||
return $service->getSimpleFeaturedCourses();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3,9 +3,9 @@
|
||||
namespace App\Http\Home\Services;
|
||||
|
||||
use App\Models\WechatSubscribe as WechatSubscribeModel;
|
||||
use App\Repos\User as UserRepo;
|
||||
use App\Repos\WechatSubscribe as WechatSubscribeRepo;
|
||||
use App\Services\Wechat as WechatService;
|
||||
use App\Validators\User as UserValidator;
|
||||
use EasyWeChat\Kernel\Messages\Text as TextMessage;
|
||||
|
||||
class WechatOfficialAccount extends Service
|
||||
@ -50,7 +50,7 @@ class WechatOfficialAccount extends Service
|
||||
{
|
||||
$service = new WechatService();
|
||||
|
||||
$service->logger->debug('Received Message ' . json_encode($message));
|
||||
$service->logger->info('Received Message ' . json_encode($message));
|
||||
|
||||
switch ($message['MsgType']) {
|
||||
case 'event':
|
||||
@ -74,7 +74,7 @@ class WechatOfficialAccount extends Service
|
||||
return $this->handleLocationEvent($message);
|
||||
break;
|
||||
default:
|
||||
return $this->emptyReplyMessage();
|
||||
return $this->noMatchReply();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@ -100,7 +100,7 @@ class WechatOfficialAccount extends Service
|
||||
return $this->handleLinkReply($message);
|
||||
break;
|
||||
default:
|
||||
return $this->emptyReplyMessage();
|
||||
return $this->noMatchReply();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -108,16 +108,16 @@ class WechatOfficialAccount extends Service
|
||||
protected function handleSubscribeEvent($message)
|
||||
{
|
||||
$openId = $message['FromUserName'] ?? '';
|
||||
$eventKey = $message['EventKey'] ?? '';
|
||||
|
||||
if (!$eventKey) {
|
||||
return $this->emptyReplyMessage();
|
||||
$subscribeRepo = new WechatSubscribeRepo();
|
||||
|
||||
$subscribe = $subscribeRepo->findByOpenId($openId);
|
||||
|
||||
if ($subscribe && $subscribe->deleted == 1) {
|
||||
$subscribe->deleted = 0;
|
||||
$subscribe->update();
|
||||
}
|
||||
|
||||
$userId = str_replace('qrscene_', '', $eventKey);
|
||||
|
||||
$this->handleSubscribeRelation($userId, $openId);
|
||||
|
||||
return new TextMessage('开心呀,我们又多了一个小伙伴!');
|
||||
}
|
||||
|
||||
@ -129,7 +129,7 @@ class WechatOfficialAccount extends Service
|
||||
|
||||
$subscribe = $subscribeRepo->findByOpenId($openId);
|
||||
|
||||
if ($subscribe) {
|
||||
if ($subscribe && $subscribe->deleted == 0) {
|
||||
$subscribe->deleted = 1;
|
||||
$subscribe->update();
|
||||
}
|
||||
@ -139,100 +139,95 @@ class WechatOfficialAccount extends Service
|
||||
|
||||
protected function handleScanEvent($message)
|
||||
{
|
||||
/**
|
||||
* 注意:当已关注过用户扫码时,"EventKey"没有带"qrscene_"前缀
|
||||
*/
|
||||
$openId = $message['FromUserName'] ?? '';
|
||||
$eventKey = $message['EventKey'] ?? '';
|
||||
$userId = $eventKey;
|
||||
|
||||
$this->handleSubscribeRelation($userId, $openId);
|
||||
}
|
||||
$userId = str_replace('qrscene_', '', $eventKey);
|
||||
|
||||
protected function handleClickEvent($message)
|
||||
{
|
||||
$this->defaultReplyMessage();
|
||||
}
|
||||
$userRepo = new UserRepo();
|
||||
|
||||
protected function handleViewEvent($message)
|
||||
{
|
||||
$this->defaultReplyMessage();
|
||||
}
|
||||
$user = $userRepo->findById($userId);
|
||||
|
||||
protected function handleLocationEvent($message)
|
||||
{
|
||||
$this->defaultReplyMessage();
|
||||
}
|
||||
|
||||
protected function handleTextReply($message)
|
||||
{
|
||||
return $this->defaultReplyMessage();
|
||||
}
|
||||
|
||||
protected function handleImageReply($message)
|
||||
{
|
||||
return $this->defaultReplyMessage();
|
||||
}
|
||||
|
||||
protected function handleVoiceReply($message)
|
||||
{
|
||||
return $this->defaultReplyMessage();
|
||||
}
|
||||
|
||||
protected function handleVideoReply($message)
|
||||
{
|
||||
return $this->defaultReplyMessage();
|
||||
}
|
||||
|
||||
protected function handleShortVideoReply($message)
|
||||
{
|
||||
return $this->defaultReplyMessage();
|
||||
}
|
||||
|
||||
protected function handleLocationReply($message)
|
||||
{
|
||||
return $this->defaultReplyMessage();
|
||||
}
|
||||
|
||||
protected function handleLinkReply($message)
|
||||
{
|
||||
return $this->defaultReplyMessage();
|
||||
}
|
||||
|
||||
protected function emptyReplyMessage()
|
||||
{
|
||||
return new TextMessage('');
|
||||
}
|
||||
|
||||
protected function defaultReplyMessage()
|
||||
{
|
||||
return new TextMessage('没有匹配的服务,如有需要请联系客服!');
|
||||
}
|
||||
|
||||
protected function handleSubscribeRelation($userId, $openId)
|
||||
{
|
||||
$validator = new UserValidator();
|
||||
|
||||
$validator->checkUser($userId);
|
||||
if (!$user) return;
|
||||
|
||||
$subscribeRepo = new WechatSubscribeRepo();
|
||||
|
||||
$subscribe = $subscribeRepo->findByOpenId($openId);
|
||||
|
||||
if ($subscribe) {
|
||||
if ($subscribe->user_id != $userId) {
|
||||
$subscribe->user_id = $userId;
|
||||
}
|
||||
if ($subscribe->deleted == 1) {
|
||||
$subscribe->deleted = 0;
|
||||
$subscribe->update();
|
||||
}
|
||||
$subscribe->update();
|
||||
} else {
|
||||
$subscribe = $subscribeRepo->findSubscribe($userId, $openId);
|
||||
if (!$subscribe) {
|
||||
$subscribe = new WechatSubscribeModel();
|
||||
$subscribe->user_id = $userId;
|
||||
$subscribe->open_id = $openId;
|
||||
$subscribe->create();
|
||||
}
|
||||
}
|
||||
|
||||
protected function handleClickEvent($message)
|
||||
{
|
||||
return $this->emptyReply();
|
||||
}
|
||||
|
||||
protected function handleViewEvent($message)
|
||||
{
|
||||
return $this->emptyReply();
|
||||
}
|
||||
|
||||
protected function handleLocationEvent($message)
|
||||
{
|
||||
return $this->emptyReply();
|
||||
}
|
||||
|
||||
protected function handleTextReply($message)
|
||||
{
|
||||
return $this->emptyReply();
|
||||
}
|
||||
|
||||
protected function handleImageReply($message)
|
||||
{
|
||||
return $this->emptyReply();
|
||||
}
|
||||
|
||||
protected function handleVoiceReply($message)
|
||||
{
|
||||
return $this->emptyReply();
|
||||
}
|
||||
|
||||
protected function handleVideoReply($message)
|
||||
{
|
||||
return $this->emptyReply();
|
||||
}
|
||||
|
||||
protected function handleShortVideoReply($message)
|
||||
{
|
||||
return $this->emptyReply();
|
||||
}
|
||||
|
||||
protected function handleLocationReply($message)
|
||||
{
|
||||
return $this->emptyReply();
|
||||
}
|
||||
|
||||
protected function handleLinkReply($message)
|
||||
{
|
||||
return $this->emptyReply();
|
||||
}
|
||||
|
||||
protected function emptyReply()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
protected function noMatchReply()
|
||||
{
|
||||
return new TextMessage('没有匹配的服务哦!');
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -58,7 +58,7 @@
|
||||
{{ partial('course/show_catalog') }}
|
||||
</div>
|
||||
<div class="layui-tab-item">
|
||||
<div class="course-details" id="preview">{{ course.details }}</div>
|
||||
<div class="course-details markdown-body">{{ course.details }}</div>
|
||||
</div>
|
||||
{% if show_tab_packages %}
|
||||
{% set packages_url = url({'for':'home.course.packages','id':course.id}) %}
|
||||
@ -112,14 +112,12 @@
|
||||
|
||||
{% block link_css %}
|
||||
|
||||
{{ css_link('https://cdn.jsdelivr.net/npm/vditor/dist/index.css', false) }}
|
||||
{{ css_link('home/css/markdown.css') }}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block include_js %}
|
||||
|
||||
{{ js_include('https://cdn.jsdelivr.net/npm/vditor/dist/method.min.js', false) }}
|
||||
{{ js_include('home/js/markdown.preview.js') }}
|
||||
{{ js_include('home/js/course.show.js') }}
|
||||
{{ js_include('home/js/course.share.js') }}
|
||||
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
{% block content %}
|
||||
|
||||
{{ partial('macros/course') }}
|
||||
|
||||
<div class="breadcrumb">
|
||||
<span class="layui-breadcrumb">
|
||||
<a href="/">首页</a>
|
||||
@ -10,21 +12,32 @@
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="layout-main clearfix">
|
||||
<div class="layout-content">
|
||||
<div class="page-info wrap">
|
||||
<div class="content" id="preview">{{ help.content }}</div>
|
||||
<div class="content markdown-body">{{ help.content }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layout-sidebar">
|
||||
{% if featured_courses %}
|
||||
<div class="sidebar">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">推荐课程</div>
|
||||
<div class="layui-card-body">
|
||||
{% for course in featured_courses %}
|
||||
{{ sidebar_course_card(course) }}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block link_css %}
|
||||
|
||||
{{ css_link('https://cdn.jsdelivr.net/npm/vditor/dist/index.css', false) }}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block include_js %}
|
||||
|
||||
{{ js_include('https://cdn.jsdelivr.net/npm/vditor/dist/method.min.js', false) }}
|
||||
{{ js_include('home/js/markdown.preview.js') }}
|
||||
{{ css_link('home/css/markdown.css') }}
|
||||
|
||||
{% endblock %}
|
@ -2,29 +2,41 @@
|
||||
|
||||
{% block content %}
|
||||
|
||||
{{ partial('macros/course') }}
|
||||
|
||||
<div class="breadcrumb">
|
||||
<span class="layui-breadcrumb">
|
||||
<a href="/">首页</a>
|
||||
<a><cite>单页</cite></a>
|
||||
<a><cite>{{ page.title }}</cite></a>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="layout-main clearfix">
|
||||
<div class="layout-content">
|
||||
<div class="page-info wrap">
|
||||
<div class="content layui-hide" id="preview">{{ page.content }}</div>
|
||||
<div class="content markdown-body">{{ page.content }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layout-sidebar">
|
||||
{% if featured_courses %}
|
||||
<div class="sidebar">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">推荐课程</div>
|
||||
<div class="layui-card-body">
|
||||
{% for course in featured_courses %}
|
||||
{{ sidebar_course_card(course) }}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block link_css %}
|
||||
|
||||
{{ css_link('https://cdn.jsdelivr.net/npm/vditor/dist/index.css', false) }}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block include_js %}
|
||||
|
||||
{{ js_include('https://cdn.jsdelivr.net/npm/vditor/dist/method.min.js', false) }}
|
||||
{{ js_include('home/js/markdown.preview.js') }}
|
||||
{{ css_link('home/css/markdown.css') }}
|
||||
|
||||
{% endblock %}
|
@ -1,4 +1,4 @@
|
||||
<div class="logo layui-layout-left">
|
||||
<div class="logo">
|
||||
{% if site_info.logo %}
|
||||
{{ image(site_info.logo,false) }}
|
||||
{% else %}
|
||||
|
@ -5,7 +5,7 @@
|
||||
{% set item.title = item.title ? item.title : '小小教书匠' %}
|
||||
{% set item.about = item.about ? item.about : '这个人很懒,什么都没留下' %}
|
||||
{% set user_url = url({'for':'home.teacher.show','id':item.id}) %}
|
||||
<div class="layui-col-md2">
|
||||
<div class="layui-col-md3">
|
||||
<div class="user-card">
|
||||
<div class="avatar">
|
||||
<a href="{{ user_url }}" title="{{ item.about }}">
|
||||
|
@ -11,7 +11,7 @@ class AppInfo
|
||||
|
||||
protected $link = 'https://gitee.com/koogua';
|
||||
|
||||
protected $version = '1.2.3';
|
||||
protected $version = '1.2.4';
|
||||
|
||||
public function __get($name)
|
||||
{
|
||||
|
@ -277,9 +277,13 @@ function kg_cos_img_style_trim($path)
|
||||
*/
|
||||
function kg_parse_markdown($content)
|
||||
{
|
||||
return preg_replace_callback('/\/img\/content\/(.*?)\)/', function ($matches) {
|
||||
return '/img/content/' . trim($matches[1]) . '!content_800';
|
||||
$content = preg_replace_callback('/\/img\/content\/(.*?)\)/', function ($matches) {
|
||||
return sprintf('/img/content/%s!content_800)', trim($matches[1]));
|
||||
}, $content);
|
||||
|
||||
$parser = new HyperDown\Parser();
|
||||
|
||||
return $parser->makeHtml($content);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -70,24 +70,19 @@ abstract class OAuth extends Service
|
||||
*/
|
||||
$crypt = Di::getDefault()->get('crypt');
|
||||
|
||||
return $crypt->encryptBase64(rand(1000, 9999));
|
||||
$text = rand(1000, 9999);
|
||||
|
||||
return $crypt->encryptBase64($text, null, true);
|
||||
}
|
||||
|
||||
public function checkState($state)
|
||||
{
|
||||
/**
|
||||
* 注意事项:
|
||||
* callback中的state参数并未做encode处理,参数中含有"+"
|
||||
* 获取参数的时候却自动做了decode处理,"+"变成了空格
|
||||
*/
|
||||
$state = str_replace(' ', '+', $state);
|
||||
|
||||
/**
|
||||
* @var $crypt Crypt
|
||||
*/
|
||||
$crypt = Di::getDefault()->get('crypt');
|
||||
|
||||
$value = $crypt->decryptBase64($state);
|
||||
$value = $crypt->decryptBase64($state, null, true);
|
||||
|
||||
if ($value < 1000 || $value > 9999) {
|
||||
throw new \Exception('Invalid OAuth State Value');
|
||||
|
@ -21,7 +21,8 @@
|
||||
"xiaochong0302/ip2region": "^1.0",
|
||||
"robmorgan/phinx": "^0.12",
|
||||
"lcobucci/jwt": "^3.3",
|
||||
"overtrue/wechat": "^4.2"
|
||||
"overtrue/wechat": "^4.2",
|
||||
"joyqi/hyper-down": "dev-master"
|
||||
},
|
||||
"require-dev": {
|
||||
"odan/phinx-migrations-generator": "^5.3",
|
||||
|
54
composer.lock
generated
54
composer.lock
generated
@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "09a618cffed2c4cfb593c0a791c19b3f",
|
||||
"content-hash": "907178db979a21189806683196c6516b",
|
||||
"packages": [
|
||||
{
|
||||
"name": "aferrandini/phpqrcode",
|
||||
@ -865,6 +865,54 @@
|
||||
],
|
||||
"time": "2020-09-03T16:46:04+00:00"
|
||||
},
|
||||
{
|
||||
"name": "joyqi/hyper-down",
|
||||
"version": "dev-master",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/SegmentFault/HyperDown.git",
|
||||
"reference": "1774a7bb8a3853503e44cfa5a2186b1943f6493f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/SegmentFault/HyperDown/zipball/1774a7bb8a3853503e44cfa5a2186b1943f6493f",
|
||||
"reference": "1774a7bb8a3853503e44cfa5a2186b1943f6493f",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
|
||||
"preferred": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"require": {
|
||||
"ext-mbstring": "*",
|
||||
"php": ">=5.4.0"
|
||||
},
|
||||
"default-branch": true,
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"HyperDown\\": "./"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "joyqi",
|
||||
"email": "joyqi@segmentfault.com"
|
||||
}
|
||||
],
|
||||
"description": "A light weight markdown parser library",
|
||||
"support": {
|
||||
"issues": "https://github.com/SegmentFault/HyperDown/issues",
|
||||
"source": "https://github.com/SegmentFault/HyperDown/tree/master"
|
||||
},
|
||||
"time": "2020-11-30T04:05:08+00:00"
|
||||
},
|
||||
{
|
||||
"name": "lcobucci/jwt",
|
||||
"version": "3.3.3",
|
||||
@ -4371,7 +4419,9 @@
|
||||
],
|
||||
"aliases": [],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": [],
|
||||
"stability-flags": {
|
||||
"joyqi/hyper-down": 20
|
||||
},
|
||||
"prefer-stable": false,
|
||||
"prefer-lowest": false,
|
||||
"platform": {
|
||||
|
@ -5,6 +5,7 @@ layui.use(['jquery'], function () {
|
||||
var $textarea = $('#vditor-textarea');
|
||||
|
||||
var vditor = new Vditor('vditor', {
|
||||
mode: 'sv',
|
||||
minHeight: 300,
|
||||
outline: false,
|
||||
resize: {
|
||||
|
972
public/static/home/css/markdown.css
Normal file
972
public/static/home/css/markdown.css
Normal file
@ -0,0 +1,972 @@
|
||||
.markdown-body .octicon {
|
||||
display: inline-block;
|
||||
fill: currentColor;
|
||||
vertical-align: text-bottom;
|
||||
}
|
||||
|
||||
.markdown-body .anchor {
|
||||
float: left;
|
||||
line-height: 1;
|
||||
margin-left: -20px;
|
||||
padding-right: 4px;
|
||||
}
|
||||
|
||||
.markdown-body .anchor:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.markdown-body h1 .octicon-link,
|
||||
.markdown-body h2 .octicon-link,
|
||||
.markdown-body h3 .octicon-link,
|
||||
.markdown-body h4 .octicon-link,
|
||||
.markdown-body h5 .octicon-link,
|
||||
.markdown-body h6 .octicon-link {
|
||||
color: #1b1f23;
|
||||
vertical-align: middle;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.markdown-body h1:hover .anchor,
|
||||
.markdown-body h2:hover .anchor,
|
||||
.markdown-body h3:hover .anchor,
|
||||
.markdown-body h4:hover .anchor,
|
||||
.markdown-body h5:hover .anchor,
|
||||
.markdown-body h6:hover .anchor {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.markdown-body h1:hover .anchor .octicon-link,
|
||||
.markdown-body h2:hover .anchor .octicon-link,
|
||||
.markdown-body h3:hover .anchor .octicon-link,
|
||||
.markdown-body h4:hover .anchor .octicon-link,
|
||||
.markdown-body h5:hover .anchor .octicon-link,
|
||||
.markdown-body h6:hover .anchor .octicon-link {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.markdown-body h1:hover .anchor .octicon-link:before,
|
||||
.markdown-body h2:hover .anchor .octicon-link:before,
|
||||
.markdown-body h3:hover .anchor .octicon-link:before,
|
||||
.markdown-body h4:hover .anchor .octicon-link:before,
|
||||
.markdown-body h5:hover .anchor .octicon-link:before,
|
||||
.markdown-body h6:hover .anchor .octicon-link:before {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
content: ' ';
|
||||
display: inline-block;
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' version='1.1' width='16' height='16' aria-hidden='true'%3E%3Cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z'%3E%3C/path%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.markdown-body {
|
||||
-ms-text-size-adjust: 100%;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
line-height: 1.5;
|
||||
color: #24292e;
|
||||
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji;
|
||||
font-size: 14px;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.markdown-body details {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.markdown-body summary {
|
||||
display: list-item;
|
||||
}
|
||||
|
||||
.markdown-body a {
|
||||
background-color: initial;
|
||||
}
|
||||
|
||||
.markdown-body a:active,
|
||||
.markdown-body a:hover {
|
||||
outline-width: 0;
|
||||
}
|
||||
|
||||
.markdown-body strong {
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
.markdown-body h1 {
|
||||
font-size: 2em;
|
||||
margin: .67em 0;
|
||||
}
|
||||
|
||||
.markdown-body img {
|
||||
border-style: none;
|
||||
}
|
||||
|
||||
.markdown-body code,
|
||||
.markdown-body kbd,
|
||||
.markdown-body pre {
|
||||
font-family: monospace, monospace;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
.markdown-body hr {
|
||||
box-sizing: initial;
|
||||
height: 0;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.markdown-body input {
|
||||
font: inherit;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.markdown-body input {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.markdown-body [type=checkbox] {
|
||||
box-sizing: border-box;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.markdown-body * {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.markdown-body input {
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
.markdown-body a {
|
||||
color: #0366d6;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.markdown-body a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.markdown-body strong {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.markdown-body hr {
|
||||
height: 0;
|
||||
margin: 15px 0;
|
||||
overflow: hidden;
|
||||
background: transparent;
|
||||
border: 0;
|
||||
border-bottom: 1px solid #dfe2e5;
|
||||
}
|
||||
|
||||
.markdown-body hr:after,
|
||||
.markdown-body hr:before {
|
||||
display: table;
|
||||
content: "";
|
||||
}
|
||||
|
||||
.markdown-body hr:after {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.markdown-body table {
|
||||
border-spacing: 0;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
.markdown-body td,
|
||||
.markdown-body th {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.markdown-body details summary {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.markdown-body kbd {
|
||||
display: inline-block;
|
||||
padding: 3px 5px;
|
||||
font: 11px SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace;
|
||||
line-height: 10px;
|
||||
color: #444d56;
|
||||
vertical-align: middle;
|
||||
background-color: #fafbfc;
|
||||
border: 1px solid #d1d5da;
|
||||
border-radius: 3px;
|
||||
box-shadow: inset 0 -1px 0 #d1d5da;
|
||||
}
|
||||
|
||||
.markdown-body h1,
|
||||
.markdown-body h2,
|
||||
.markdown-body h3,
|
||||
.markdown-body h4,
|
||||
.markdown-body h5,
|
||||
.markdown-body h6 {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.markdown-body h1 {
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
.markdown-body h1,
|
||||
.markdown-body h2 {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.markdown-body h2 {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.markdown-body h3 {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.markdown-body h3,
|
||||
.markdown-body h4 {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.markdown-body h4 {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.markdown-body h5 {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.markdown-body h5,
|
||||
.markdown-body h6 {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.markdown-body h6 {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.markdown-body p {
|
||||
margin-top: 0;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.markdown-body blockquote {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.markdown-body ol,
|
||||
.markdown-body ul {
|
||||
padding-left: 0;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.markdown-body ol ol,
|
||||
.markdown-body ul ol {
|
||||
list-style-type: lower-roman;
|
||||
}
|
||||
|
||||
.markdown-body ol ol ol,
|
||||
.markdown-body ol ul ol,
|
||||
.markdown-body ul ol ol,
|
||||
.markdown-body ul ul ol {
|
||||
list-style-type: lower-alpha;
|
||||
}
|
||||
|
||||
.markdown-body dd {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.markdown-body code,
|
||||
.markdown-body pre {
|
||||
font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.markdown-body pre {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.markdown-body input::-webkit-inner-spin-button,
|
||||
.markdown-body input::-webkit-outer-spin-button {
|
||||
margin: 0;
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
}
|
||||
|
||||
.markdown-body :checked + .radio-label {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
border-color: #0366d6;
|
||||
}
|
||||
|
||||
.markdown-body .border {
|
||||
border: 1px solid #e1e4e8 !important;
|
||||
}
|
||||
|
||||
.markdown-body .border-0 {
|
||||
border: 0 !important;
|
||||
}
|
||||
|
||||
.markdown-body .border-bottom {
|
||||
border-bottom: 1px solid #e1e4e8 !important;
|
||||
}
|
||||
|
||||
.markdown-body .rounded-1 {
|
||||
border-radius: 3px !important;
|
||||
}
|
||||
|
||||
.markdown-body .bg-white {
|
||||
background-color: #fff !important;
|
||||
}
|
||||
|
||||
.markdown-body .bg-gray-light {
|
||||
background-color: #fafbfc !important;
|
||||
}
|
||||
|
||||
.markdown-body .text-gray-light {
|
||||
color: #6a737d !important;
|
||||
}
|
||||
|
||||
.markdown-body .mb-0 {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
|
||||
.markdown-body .my-2 {
|
||||
margin-top: 8px !important;
|
||||
margin-bottom: 8px !important;
|
||||
}
|
||||
|
||||
.markdown-body .pl-0 {
|
||||
padding-left: 0 !important;
|
||||
}
|
||||
|
||||
.markdown-body .py-0 {
|
||||
padding-top: 0 !important;
|
||||
padding-bottom: 0 !important;
|
||||
}
|
||||
|
||||
.markdown-body .pl-1 {
|
||||
padding-left: 4px !important;
|
||||
}
|
||||
|
||||
.markdown-body .pl-2 {
|
||||
padding-left: 8px !important;
|
||||
}
|
||||
|
||||
.markdown-body .py-2 {
|
||||
padding-top: 8px !important;
|
||||
padding-bottom: 8px !important;
|
||||
}
|
||||
|
||||
.markdown-body .pl-3,
|
||||
.markdown-body .px-3 {
|
||||
padding-left: 16px !important;
|
||||
}
|
||||
|
||||
.markdown-body .px-3 {
|
||||
padding-right: 16px !important;
|
||||
}
|
||||
|
||||
.markdown-body .pl-4 {
|
||||
padding-left: 24px !important;
|
||||
}
|
||||
|
||||
.markdown-body .pl-5 {
|
||||
padding-left: 32px !important;
|
||||
}
|
||||
|
||||
.markdown-body .pl-6 {
|
||||
padding-left: 40px !important;
|
||||
}
|
||||
|
||||
.markdown-body .f6 {
|
||||
font-size: 12px !important;
|
||||
}
|
||||
|
||||
.markdown-body .lh-condensed {
|
||||
line-height: 1.25 !important;
|
||||
}
|
||||
|
||||
.markdown-body .text-bold {
|
||||
font-weight: 600 !important;
|
||||
}
|
||||
|
||||
.markdown-body .pl-c {
|
||||
color: #6a737d;
|
||||
}
|
||||
|
||||
.markdown-body .pl-c1,
|
||||
.markdown-body .pl-s .pl-v {
|
||||
color: #005cc5;
|
||||
}
|
||||
|
||||
.markdown-body .pl-e,
|
||||
.markdown-body .pl-en {
|
||||
color: #6f42c1;
|
||||
}
|
||||
|
||||
.markdown-body .pl-s .pl-s1,
|
||||
.markdown-body .pl-smi {
|
||||
color: #24292e;
|
||||
}
|
||||
|
||||
.markdown-body .pl-ent {
|
||||
color: #22863a;
|
||||
}
|
||||
|
||||
.markdown-body .pl-k {
|
||||
color: #d73a49;
|
||||
}
|
||||
|
||||
.markdown-body .pl-pds,
|
||||
.markdown-body .pl-s,
|
||||
.markdown-body .pl-s .pl-pse .pl-s1,
|
||||
.markdown-body .pl-sr,
|
||||
.markdown-body .pl-sr .pl-cce,
|
||||
.markdown-body .pl-sr .pl-sra,
|
||||
.markdown-body .pl-sr .pl-sre {
|
||||
color: #032f62;
|
||||
}
|
||||
|
||||
.markdown-body .pl-smw,
|
||||
.markdown-body .pl-v {
|
||||
color: #e36209;
|
||||
}
|
||||
|
||||
.markdown-body .pl-bu {
|
||||
color: #b31d28;
|
||||
}
|
||||
|
||||
.markdown-body .pl-ii {
|
||||
color: #fafbfc;
|
||||
background-color: #b31d28;
|
||||
}
|
||||
|
||||
.markdown-body .pl-c2 {
|
||||
color: #fafbfc;
|
||||
background-color: #d73a49;
|
||||
}
|
||||
|
||||
.markdown-body .pl-c2:before {
|
||||
content: "^M";
|
||||
}
|
||||
|
||||
.markdown-body .pl-sr .pl-cce {
|
||||
font-weight: 700;
|
||||
color: #22863a;
|
||||
}
|
||||
|
||||
.markdown-body .pl-ml {
|
||||
color: #735c0f;
|
||||
}
|
||||
|
||||
.markdown-body .pl-mh,
|
||||
.markdown-body .pl-mh .pl-en,
|
||||
.markdown-body .pl-ms {
|
||||
font-weight: 700;
|
||||
color: #005cc5;
|
||||
}
|
||||
|
||||
.markdown-body .pl-mi {
|
||||
font-style: italic;
|
||||
color: #24292e;
|
||||
}
|
||||
|
||||
.markdown-body .pl-mb {
|
||||
font-weight: 700;
|
||||
color: #24292e;
|
||||
}
|
||||
|
||||
.markdown-body .pl-md {
|
||||
color: #b31d28;
|
||||
background-color: #ffeef0;
|
||||
}
|
||||
|
||||
.markdown-body .pl-mi1 {
|
||||
color: #22863a;
|
||||
background-color: #f0fff4;
|
||||
}
|
||||
|
||||
.markdown-body .pl-mc {
|
||||
color: #e36209;
|
||||
background-color: #ffebda;
|
||||
}
|
||||
|
||||
.markdown-body .pl-mi2 {
|
||||
color: #f6f8fa;
|
||||
background-color: #005cc5;
|
||||
}
|
||||
|
||||
.markdown-body .pl-mdr {
|
||||
font-weight: 700;
|
||||
color: #6f42c1;
|
||||
}
|
||||
|
||||
.markdown-body .pl-ba {
|
||||
color: #586069;
|
||||
}
|
||||
|
||||
.markdown-body .pl-sg {
|
||||
color: #959da5;
|
||||
}
|
||||
|
||||
.markdown-body .pl-corl {
|
||||
text-decoration: underline;
|
||||
color: #032f62;
|
||||
}
|
||||
|
||||
.markdown-body .mb-0 {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
|
||||
.markdown-body .my-2 {
|
||||
margin-bottom: 8px !important;
|
||||
}
|
||||
|
||||
.markdown-body .my-2 {
|
||||
margin-top: 8px !important;
|
||||
}
|
||||
|
||||
.markdown-body .pl-0 {
|
||||
padding-left: 0 !important;
|
||||
}
|
||||
|
||||
.markdown-body .py-0 {
|
||||
padding-top: 0 !important;
|
||||
padding-bottom: 0 !important;
|
||||
}
|
||||
|
||||
.markdown-body .pl-1 {
|
||||
padding-left: 4px !important;
|
||||
}
|
||||
|
||||
.markdown-body .pl-2 {
|
||||
padding-left: 8px !important;
|
||||
}
|
||||
|
||||
.markdown-body .py-2 {
|
||||
padding-top: 8px !important;
|
||||
padding-bottom: 8px !important;
|
||||
}
|
||||
|
||||
.markdown-body .pl-3 {
|
||||
padding-left: 16px !important;
|
||||
}
|
||||
|
||||
.markdown-body .pl-4 {
|
||||
padding-left: 24px !important;
|
||||
}
|
||||
|
||||
.markdown-body .pl-5 {
|
||||
padding-left: 32px !important;
|
||||
}
|
||||
|
||||
.markdown-body .pl-6 {
|
||||
padding-left: 40px !important;
|
||||
}
|
||||
|
||||
.markdown-body .pl-7 {
|
||||
padding-left: 48px !important;
|
||||
}
|
||||
|
||||
.markdown-body .pl-8 {
|
||||
padding-left: 64px !important;
|
||||
}
|
||||
|
||||
.markdown-body .pl-9 {
|
||||
padding-left: 80px !important;
|
||||
}
|
||||
|
||||
.markdown-body .pl-10 {
|
||||
padding-left: 96px !important;
|
||||
}
|
||||
|
||||
.markdown-body .pl-11 {
|
||||
padding-left: 112px !important;
|
||||
}
|
||||
|
||||
.markdown-body .pl-12 {
|
||||
padding-left: 128px !important;
|
||||
}
|
||||
|
||||
.markdown-body hr {
|
||||
border-bottom-color: #eee;
|
||||
}
|
||||
|
||||
.markdown-body:after,
|
||||
.markdown-body:before {
|
||||
display: table;
|
||||
content: "";
|
||||
}
|
||||
|
||||
.markdown-body:after {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.markdown-body > :first-child {
|
||||
margin-top: 0 !important;
|
||||
}
|
||||
|
||||
.markdown-body > :last-child {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
|
||||
.markdown-body a:not([href]) {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.markdown-body blockquote,
|
||||
.markdown-body details,
|
||||
.markdown-body dl,
|
||||
.markdown-body ol,
|
||||
.markdown-body p,
|
||||
.markdown-body pre,
|
||||
.markdown-body table,
|
||||
.markdown-body ul {
|
||||
margin-top: 0;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.markdown-body hr {
|
||||
height: .25em;
|
||||
padding: 0;
|
||||
margin: 24px 0;
|
||||
background-color: #e1e4e8;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.markdown-body blockquote {
|
||||
padding: 0 1em;
|
||||
color: #6a737d;
|
||||
border-left: .25em solid #dfe2e5;
|
||||
}
|
||||
|
||||
.markdown-body blockquote > :first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.markdown-body blockquote > :last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.markdown-body h1,
|
||||
.markdown-body h2,
|
||||
.markdown-body h3,
|
||||
.markdown-body h4,
|
||||
.markdown-body h5,
|
||||
.markdown-body h6 {
|
||||
margin-top: 24px;
|
||||
margin-bottom: 16px;
|
||||
font-weight: 600;
|
||||
line-height: 1.25;
|
||||
}
|
||||
|
||||
.markdown-body h1 {
|
||||
font-size: 2em;
|
||||
}
|
||||
|
||||
.markdown-body h1,
|
||||
.markdown-body h2 {
|
||||
padding-bottom: .3em;
|
||||
border-bottom: 1px solid #eaecef;
|
||||
}
|
||||
|
||||
.markdown-body h2 {
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
.markdown-body h3 {
|
||||
font-size: 1.25em;
|
||||
}
|
||||
|
||||
.markdown-body h4 {
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
.markdown-body h5 {
|
||||
font-size: .875em;
|
||||
}
|
||||
|
||||
.markdown-body h6 {
|
||||
font-size: .85em;
|
||||
color: #6a737d;
|
||||
}
|
||||
|
||||
.markdown-body ol,
|
||||
.markdown-body ul {
|
||||
padding-left: 2em;
|
||||
}
|
||||
|
||||
.markdown-body ol ol,
|
||||
.markdown-body ol ul,
|
||||
.markdown-body ul ol,
|
||||
.markdown-body ul ul {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.markdown-body li {
|
||||
list-style: initial;
|
||||
}
|
||||
|
||||
.markdown-body li > p {
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.markdown-body li + li {
|
||||
margin-top: .25em;
|
||||
}
|
||||
|
||||
.markdown-body dl {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.markdown-body dl dt {
|
||||
padding: 0;
|
||||
margin-top: 16px;
|
||||
font-size: 1em;
|
||||
font-style: italic;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.markdown-body dl dd {
|
||||
padding: 0 16px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.markdown-body table {
|
||||
display: block;
|
||||
width: 100%;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.markdown-body table th {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.markdown-body table td,
|
||||
.markdown-body table th {
|
||||
padding: 6px 13px;
|
||||
border: 1px solid #dfe2e5;
|
||||
}
|
||||
|
||||
.markdown-body table tr {
|
||||
background-color: #fff;
|
||||
border-top: 1px solid #c6cbd1;
|
||||
}
|
||||
|
||||
.markdown-body table tr:nth-child(2n) {
|
||||
background-color: #f6f8fa;
|
||||
}
|
||||
|
||||
.markdown-body img {
|
||||
max-width: 100%;
|
||||
box-sizing: initial;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.markdown-body img[align=right] {
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
.markdown-body img[align=left] {
|
||||
padding-right: 20px;
|
||||
}
|
||||
|
||||
.markdown-body code {
|
||||
padding: .2em .4em;
|
||||
margin: 0;
|
||||
font-size: 85%;
|
||||
background-color: rgba(27, 31, 35, .05);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.markdown-body pre {
|
||||
word-wrap: normal;
|
||||
}
|
||||
|
||||
.markdown-body pre > code {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
font-size: 100%;
|
||||
word-break: normal;
|
||||
white-space: pre;
|
||||
background: transparent;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.markdown-body .highlight {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.markdown-body .highlight pre {
|
||||
margin-bottom: 0;
|
||||
word-break: normal;
|
||||
}
|
||||
|
||||
.markdown-body .highlight pre,
|
||||
.markdown-body pre {
|
||||
padding: 16px;
|
||||
overflow: auto;
|
||||
font-size: 85%;
|
||||
line-height: 1.45;
|
||||
background-color: #f6f8fa;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.markdown-body pre code {
|
||||
display: inline;
|
||||
max-width: auto;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
overflow: visible;
|
||||
line-height: inherit;
|
||||
word-wrap: normal;
|
||||
background-color: initial;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.markdown-body .commit-tease-sha {
|
||||
display: inline-block;
|
||||
font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace;
|
||||
font-size: 90%;
|
||||
color: #444d56;
|
||||
}
|
||||
|
||||
.markdown-body .full-commit .btn-outline:not(:disabled):hover {
|
||||
color: #005cc5;
|
||||
border-color: #005cc5;
|
||||
}
|
||||
|
||||
.markdown-body .blob-wrapper {
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
.markdown-body .blob-wrapper-embedded {
|
||||
max-height: 240px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.markdown-body .blob-num {
|
||||
width: 1%;
|
||||
min-width: 50px;
|
||||
padding-right: 10px;
|
||||
padding-left: 10px;
|
||||
font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace;
|
||||
font-size: 12px;
|
||||
line-height: 20px;
|
||||
color: rgba(27, 31, 35, .3);
|
||||
text-align: right;
|
||||
white-space: nowrap;
|
||||
vertical-align: top;
|
||||
cursor: pointer;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.markdown-body .blob-num:hover {
|
||||
color: rgba(27, 31, 35, .6);
|
||||
}
|
||||
|
||||
.markdown-body .blob-num:before {
|
||||
content: attr(data-line-number);
|
||||
}
|
||||
|
||||
.markdown-body .blob-code {
|
||||
position: relative;
|
||||
padding-right: 10px;
|
||||
padding-left: 10px;
|
||||
line-height: 20px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.markdown-body .blob-code-inner {
|
||||
overflow: visible;
|
||||
font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace;
|
||||
font-size: 12px;
|
||||
color: #24292e;
|
||||
word-wrap: normal;
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
.markdown-body .pl-token.active,
|
||||
.markdown-body .pl-token:hover {
|
||||
cursor: pointer;
|
||||
background: #ffea7f;
|
||||
}
|
||||
|
||||
.markdown-body .tab-size[data-tab-size="1"] {
|
||||
-moz-tab-size: 1;
|
||||
tab-size: 1;
|
||||
}
|
||||
|
||||
.markdown-body .tab-size[data-tab-size="2"] {
|
||||
-moz-tab-size: 2;
|
||||
tab-size: 2;
|
||||
}
|
||||
|
||||
.markdown-body .tab-size[data-tab-size="3"] {
|
||||
-moz-tab-size: 3;
|
||||
tab-size: 3;
|
||||
}
|
||||
|
||||
.markdown-body .tab-size[data-tab-size="4"] {
|
||||
-moz-tab-size: 4;
|
||||
tab-size: 4;
|
||||
}
|
||||
|
||||
.markdown-body .tab-size[data-tab-size="5"] {
|
||||
-moz-tab-size: 5;
|
||||
tab-size: 5;
|
||||
}
|
||||
|
||||
.markdown-body .tab-size[data-tab-size="6"] {
|
||||
-moz-tab-size: 6;
|
||||
tab-size: 6;
|
||||
}
|
||||
|
||||
.markdown-body .tab-size[data-tab-size="7"] {
|
||||
-moz-tab-size: 7;
|
||||
tab-size: 7;
|
||||
}
|
||||
|
||||
.markdown-body .tab-size[data-tab-size="8"] {
|
||||
-moz-tab-size: 8;
|
||||
tab-size: 8;
|
||||
}
|
||||
|
||||
.markdown-body .tab-size[data-tab-size="9"] {
|
||||
-moz-tab-size: 9;
|
||||
tab-size: 9;
|
||||
}
|
||||
|
||||
.markdown-body .tab-size[data-tab-size="10"] {
|
||||
-moz-tab-size: 10;
|
||||
tab-size: 10;
|
||||
}
|
||||
|
||||
.markdown-body .tab-size[data-tab-size="11"] {
|
||||
-moz-tab-size: 11;
|
||||
tab-size: 11;
|
||||
}
|
||||
|
||||
.markdown-body .tab-size[data-tab-size="12"] {
|
||||
-moz-tab-size: 12;
|
||||
tab-size: 12;
|
||||
}
|
||||
|
||||
.markdown-body .task-list-item {
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
.markdown-body .task-list-item + .task-list-item {
|
||||
margin-top: 3px;
|
||||
}
|
||||
|
||||
.markdown-body .task-list-item input {
|
||||
margin: 0 .2em .25em -1.6em;
|
||||
vertical-align: middle;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user