1
0
mirror of https://gitee.com/koogua/course-tencent-cloud.git synced 2025-06-28 21:31:37 +08:00

Merge branch 'koogua/v1.6.3'

This commit is contained in:
xiaochong0302 2023-05-07 21:00:31 +08:00
commit a581b0d493
46 changed files with 755 additions and 976 deletions

View File

@ -1,4 +1,16 @@
### [v1.6.2](https://gitee.com/koogua/course-tencent-cloud/releases/v1.6.1)(2023-01-12) ### [v1.6.3](https://gitee.com/koogua/course-tencent-cloud/releases/v1.6.3)(2023-05-08)
- 强化文章|提问|课程列表参数检查
- 优化HtmlPurifier内容过滤
- 优化排序条件和分页重复问题
- 优化课程搜索分组条件样式
- 优化课程学习时长同步
- 优化程序语法层面
- 更新Layui-v2.8.2
- 替换ip2region包
- 去除未支付“新鲜”订单检查
- 修正手续费率设置为0无效问题
### [v1.6.2](https://gitee.com/koogua/course-tencent-cloud/releases/v1.6.2)(2023-02-12)
- 增加ServerMonitor监控指标配置 - 增加ServerMonitor监控指标配置
- 同步更新腾讯云短信内容规则 - 同步更新腾讯云短信内容规则

View File

@ -39,7 +39,7 @@ class LiveController extends Controller
$stats = $service->getStats($id); $stats = $service->getStats($id);
return $this->jsonSuccess($stats); return $this->jsonSuccess(['stats' => $stats]);
} }
/** /**

View File

@ -7,7 +7,9 @@
namespace App\Http\Home\Services; namespace App\Http\Home\Services;
use App\Models\Category as CategoryModel;
use App\Models\Question as QuestionModel; use App\Models\Question as QuestionModel;
use App\Services\Category as CategoryService;
use App\Validators\QuestionQuery as QuestionQueryValidator; use App\Validators\QuestionQuery as QuestionQueryValidator;
class QuestionQuery extends Service class QuestionQuery extends Service
@ -20,6 +22,40 @@ class QuestionQuery extends Service
$this->baseUrl = $this->url->get(['for' => 'home.question.list']); $this->baseUrl = $this->url->get(['for' => 'home.question.list']);
} }
public function handleCategories()
{
$params = $this->getParams();
if (isset($params['category_id'])) {
unset($params['category_id']);
}
$defaultItem = [
'id' => 'all',
'name' => '全部',
'url' => $this->baseUrl . $this->buildParams($params),
];
$result = [];
$result[] = $defaultItem;
$categoryService = new CategoryService();
$topCategories = $categoryService->getChildCategories(CategoryModel::TYPE_QUESTION, 0);
foreach ($topCategories as $key => $category) {
$params['category_id'] = $category['id'];
$result[] = [
'id' => $category['id'],
'name' => $category['name'],
'url' => $this->baseUrl . $this->buildParams($params),
];
}
return $result;
}
public function handleSorts() public function handleSorts()
{ {
$params = $this->getParams(); $params = $this->getParams();
@ -48,6 +84,11 @@ class QuestionQuery extends Service
$validator = new QuestionQueryValidator(); $validator = new QuestionQueryValidator();
if (isset($query['category_id']) && $query['category_id'] != 'all') {
$validator->checkCategory($query['category_id']);
$params['category_id'] = $query['category_id'];
}
if (isset($query['tag_id'])) { if (isset($query['tag_id'])) {
$validator->checkTag($query['tag_id']); $validator->checkTag($query['tag_id']);
$params['tag_id'] = $query['tag_id']; $params['tag_id'] = $query['tag_id'];

View File

@ -68,10 +68,14 @@
</div> </div>
{% endif %} {% endif %}
{% if article.source_type == 1 %} {% if article.source_type == 1 %}
<div class="source-tips">本作品系原创,转载请注明出处</div> <div class="source-tips">
<i class="layui-icon layui-icon-tips"></i> 本文系原创,转载请注明出处
</div>
{% elseif article.source_url %} {% elseif article.source_url %}
<div class="source-tips"> <div class="source-tips">
<a href="{{ article.source_url }}" target="_blank">前往阅读原文</a> <a href="{{ article.source_url }}" target="_blank">
<i class="layui-icon layui-icon-website"></i> 本文系转载,前往阅读原文
</a>
</div> </div>
{% endif %} {% endif %}
</div> </div>

View File

@ -62,8 +62,8 @@
</div> </div>
<div id="answer-anchor"></div> <div id="answer-anchor"></div>
{% if question.closed == 1 %} {% if question.closed == 1 %}
<div class="answer-wrap wrap"> <div class="wrap center gray">
<button class="layui-btn layui-btn-fluid layui-btn-disabled">问题已关闭</button> <i class="layui-icon layui-icon-close-fill"></i> 问题已关闭
</div> </div>
{% endif %} {% endif %}
{% if answer_id > 0 %} {% if answer_id > 0 %}

View File

@ -16,7 +16,7 @@ class AppInfo
protected $link = 'https://www.koogua.com'; protected $link = 'https://www.koogua.com';
protected $version = '1.6.2'; protected $version = '1.6.3';
public function __get($name) public function __get($name)
{ {

View File

@ -124,15 +124,15 @@ function kg_object_array($object)
} }
/** /**
* ip to region * ip地址转区域
* *
* @param $ip * @param $ip string
* @param string $dbFile
* @return array * @return array
* @throws Exception
*/ */
function kg_ip2region($ip, $dbFile = null) function kg_ip2region($ip)
{ {
$searcher = new Ip2RegionSearcher($dbFile); $searcher = new Ip2Region();
$ip2region = $searcher->btreeSearch($ip); $ip2region = $searcher->btreeSearch($ip);

View File

@ -57,7 +57,7 @@ class Purifier
$serializerPath = cache_path('purifier'); $serializerPath = cache_path('purifier');
if (file_exists($serializerPath) == false) { if (!file_exists($serializerPath)) {
mkdir($serializerPath, 0777); mkdir($serializerPath, 0777);
} }

View File

@ -81,30 +81,30 @@ class Common
public static function phone($str) public static function phone($str)
{ {
$pattern = '/^1(3|4|5|6|7|8|9)[0-9]{9}$/'; $pattern = '/^1[2-9][0-9]{9}$/';
return preg_match($pattern, $str) ? true : false; return (bool)preg_match($pattern, $str);
} }
public static function name($str) public static function name($str)
{ {
$pattern = '/^[\x{4e00}-\x{9fa5}A-Za-z0-9]{2,15}$/u'; $pattern = '/^[\x{4e00}-\x{9fa5}A-Za-z0-9]{2,15}$/u';
return preg_match($pattern, $str) ? true : false; return (bool)preg_match($pattern, $str);
} }
public static function password($str) public static function password($str)
{ {
$pattern = '/^[[:graph:]]{6,16}$/'; $pattern = '/^[[:graph:]]{6,16}$/';
return preg_match($pattern, $str) ? true : false; return (bool)preg_match($pattern, $str);
} }
public static function birthday($str) public static function birthday($str)
{ {
$pattern = '/^(19|20)\d{2}-(1[0-2]|0[1-9])-(0[1-9]|[1-2][0-9]|3[0-1])$/'; $pattern = '/^(19|20)\d{2}-(1[0-2]|0[1-9])-(0[1-9]|[1-2][0-9]|3[0-1])$/';
return preg_match($pattern, $str) ? true : false; return (bool)preg_match($pattern, $str);
} }
public static function date($str, $format = 'Y-m-d') public static function date($str, $format = 'Y-m-d')

View File

@ -222,9 +222,14 @@ class Chapter extends Model
public function beforeCreate() public function beforeCreate()
{ {
/**
* @var Course $course
*/
$course = Course::findFirst($this->course_id); $course = Course::findFirst($this->course_id);
$this->model = $course->model; if (empty($this->model)) {
$this->model = $course->model;
}
if ($this->parent_id > 0) { if ($this->parent_id > 0) {
if (empty($this->attrs)) { if (empty($this->attrs)) {

View File

@ -56,10 +56,10 @@ class Answer extends Repository
switch ($sort) { switch ($sort) {
case 'popular': case 'popular':
$orderBy = 'like_count DESC'; $orderBy = 'like_count DESC, id DESC';
break; break;
case 'accepted': case 'accepted':
$orderBy = 'accepted DESC, like_count DESC'; $orderBy = 'accepted DESC, id DESC';
break; break;
case 'oldest': case 'oldest':
$orderBy = 'id ASC'; $orderBy = 'id ASC';

View File

@ -107,10 +107,10 @@ class Article extends Repository
switch ($sort) { switch ($sort) {
case 'like': case 'like':
$orderBy = 'like_count DESC'; $orderBy = 'like_count DESC, id DESC';
break; break;
case 'popular': case 'popular':
$orderBy = 'score DESC'; $orderBy = 'score DESC, id DESC';
break; break;
case 'oldest': case 'oldest':
$orderBy = 'id ASC'; $orderBy = 'id ASC';

View File

@ -66,7 +66,7 @@ class Comment extends Repository
switch ($sort) { switch ($sort) {
case 'popular': case 'popular':
$orderBy = 'like_count DESC'; $orderBy = 'like_count DESC, id DESC';
break; break;
case 'oldest': case 'oldest':
$orderBy = 'id ASC'; $orderBy = 'id ASC';

View File

@ -119,13 +119,13 @@ class Course extends Repository
switch ($sort) { switch ($sort) {
case 'score': case 'score':
$orderBy = 'score DESC'; $orderBy = 'score DESC, id DESC';
break; break;
case 'rating': case 'rating':
$orderBy = 'rating DESC'; $orderBy = 'rating DESC, id DESC';
break; break;
case 'popular': case 'popular':
$orderBy = 'user_count DESC'; $orderBy = 'user_count DESC, id DESC';
break; break;
case 'oldest': case 'oldest':
$orderBy = 'id ASC'; $orderBy = 'id ASC';

View File

@ -50,7 +50,7 @@ class PointGift extends Repository
switch ($sort) { switch ($sort) {
case 'popular': case 'popular':
$orderBy = 'redeem_count DESC'; $orderBy = 'redeem_count DESC, id DESC';
break; break;
case 'oldest': case 'oldest':
$orderBy = 'id ASC'; $orderBy = 'id ASC';

View File

@ -100,10 +100,10 @@ class Question extends Repository
switch ($sort) { switch ($sort) {
case 'active': case 'active':
$orderBy = 'last_reply_time DESC'; $orderBy = 'last_reply_time DESC, id DESC';
break; break;
case 'score': case 'score':
$orderBy = 'score DESC'; $orderBy = 'score DESC, id DESC';
break; break;
case 'oldest': case 'oldest':
$orderBy = 'id ASC'; $orderBy = 'id ASC';

View File

@ -45,8 +45,14 @@ class Slide extends Repository
} }
switch ($sort) { switch ($sort) {
case 'oldest':
$orderBy = 'id ASC';
break;
case 'latest':
$orderBy = 'id DESC';
break;
default: default:
$orderBy = 'priority ASC'; $orderBy = 'priority ASC, id DESC';
break; break;
} }

95
app/Repos/Task.php Normal file
View File

@ -0,0 +1,95 @@
<?php
/**
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.koogua.com
*/
namespace App\Repos;
use App\Library\Paginator\Adapter\QueryBuilder as PagerQueryBuilder;
use App\Models\Task as TaskModel;
use Phalcon\Mvc\Model;
use Phalcon\Mvc\Model\Resultset;
use Phalcon\Mvc\Model\ResultsetInterface;
class Task extends Repository
{
public function paginate($where = [], $sort = 'latest', $page = 1, $limit = 15)
{
$builder = $this->modelsManager->createBuilder();
$builder->from(TaskModel::class);
$builder->where('1 = 1');
if (!empty($where['id'])) {
$builder->andWhere('id = :id:', ['id' => $where['id']]);
}
if (!empty($where['item_id'])) {
$builder->andWhere('item_id = :item_id:', ['item_id' => $where['item_id']]);
}
if (!empty($where['item_type'])) {
$builder->andWhere('item_type = :item_type:', ['item_type' => $where['item_type']]);
}
if (!empty($where['status'])) {
$builder->andWhere('status = :status:', ['status' => $where['status']]);
}
if (isset($where['locked'])) {
$builder->andWhere('locked = :locked:', ['locked' => $where['locked']]);
}
switch ($sort) {
case 'oldest':
$orderBy = 'id ASC';
break;
case 'latest':
$orderBy = 'id DESC';
break;
default:
$orderBy = 'priority ASC, id ASC';
break;
}
$builder->orderBy($orderBy);
$pager = new PagerQueryBuilder([
'builder' => $builder,
'page' => $page,
'limit' => $limit,
]);
return $pager->paginate();
}
/**
* @param int $id
* @return TaskModel|Model|bool
*/
public function findById($id)
{
return TaskModel::findFirst([
'conditions' => 'id = :id:',
'bind' => ['id' => $id],
]);
}
/**
* @param array $ids
* @param array|string $columns
* @return ResultsetInterface|Resultset|TaskModel[]
*/
public function findByIds($ids, $columns = '*')
{
return TaskModel::query()
->columns($columns)
->inWhere('id', $ids)
->execute();
}
}

View File

@ -76,6 +76,7 @@ class ChapterInfo extends LogicService
$result['course'] = $service->handleCourseInfo($this->course); $result['course'] = $service->handleCourseInfo($this->course);
$me = [ $me = [
'role_type' => 0,
'plan_id' => 0, 'plan_id' => 0,
'position' => 0, 'position' => 0,
'joined' => 0, 'joined' => 0,
@ -83,8 +84,13 @@ class ChapterInfo extends LogicService
'liked' => 0, 'liked' => 0,
]; ];
$me['joined'] = $this->joinedChapter ? 1 : 0; if ($this->joinedChapter) {
$me['owned'] = $this->ownedChapter ? 1 : 0; $me['joined'] = 1;
}
if ($this->ownedChapter) {
$me['owned'] = 1;
}
if ($user->id > 0) { if ($user->id > 0) {
@ -97,6 +103,7 @@ class ChapterInfo extends LogicService
} }
if ($this->courseUser) { if ($this->courseUser) {
$me['role_type'] = $this->courseUser->role_type;
$me['plan_id'] = $this->courseUser->plan_id; $me['plan_id'] = $this->courseUser->plan_id;
} }

View File

@ -46,23 +46,35 @@ class CourseInfo extends LogicService
'progress' => 0, 'progress' => 0,
]; ];
$me['joined'] = $this->joinedCourse ? 1 : 0; if ($this->joinedCourse) {
$me['owned'] = $this->ownedCourse ? 1 : 0; $me['joined'] = 1;
}
if ($this->ownedCourse) {
$me['owned'] = 1;
}
$caseOwned = $this->ownedCourse == false; $caseOwned = $this->ownedCourse == false;
$casePrice = $course->market_price > 0; $casePrice = $course->market_price > 0;
$caseModel = true;
/** /**
* 过期直播不允许购买 * 过期直播不允许购买
*/ */
if ($course->model == CourseModel::MODEL_LIVE) { if ($course->model == CourseModel::MODEL_LIVE) {
$caseModel = $course->attrs['end_date'] < date('Y-m-d'); $caseModel = $course->attrs['end_date'] < date('Y-m-d');
} else {
$caseModel = true;
} }
$me['allow_order'] = $caseOwned && $casePrice && $caseModel ? 1 : 0; if ($caseOwned && $casePrice && $caseModel) {
$me['allow_reward'] = $course->market_price == 0 ? 1 : 0; $me['allow_order'] = 1;
}
/**
* 付款课程不允许打赏
*/
if ($course->market_price == 0) {
$me['allow_reward'] = 1;
}
if ($user->id > 0) { if ($user->id > 0) {

View File

@ -78,7 +78,7 @@ class SaleList extends LogicService
$item = [ $item = [
'id' => $sale->id, 'id' => $sale->id,
'stock' => $sale->stock, 'stock' => $sale->stock,
'price' => $sale->price, 'price' => (float)$sale->price,
'item_id' => $sale->item_id, 'item_id' => $sale->item_id,
'item_type' => $sale->item_type, 'item_type' => $sale->item_type,
'item_info' => $sale->item_info, 'item_info' => $sale->item_info,

View File

@ -13,7 +13,6 @@ use App\Models\Package as PackageModel;
use App\Models\Reward as RewardModel; use App\Models\Reward as RewardModel;
use App\Models\User as UserModel; use App\Models\User as UserModel;
use App\Models\Vip as VipModel; use App\Models\Vip as VipModel;
use App\Repos\Order as OrderRepo;
use App\Repos\Package as PackageRepo; use App\Repos\Package as PackageRepo;
use App\Services\Logic\Service as LogicService; use App\Services\Logic\Service as LogicService;
use App\Traits\Client as ClientTrait; use App\Traits\Client as ClientTrait;
@ -59,14 +58,7 @@ class OrderCreate extends LogicService
$orderValidator->checkItemType($post['item_type']); $orderValidator->checkItemType($post['item_type']);
$orderRepo = new OrderRepo(); $order = null;
$order = $orderRepo->findUserLastPendingOrder($user->id, $post['item_id'], $post['item_type']);
/**
* 存在新鲜的未支付订单直接返回(减少订单记录)
*/
if ($order) return $order;
if ($post['item_type'] == OrderModel::ITEM_COURSE) { if ($post['item_type'] == OrderModel::ITEM_COURSE) {

View File

@ -174,10 +174,10 @@ class Refund extends Service
switch ($trade->channel) { switch ($trade->channel) {
case TradeModel::CHANNEL_ALIPAY: case TradeModel::CHANNEL_ALIPAY:
$serviceRate = $alipay['service_rate'] ?: $serviceRate; $serviceRate = $alipay['service_rate'] ?? $serviceRate;
break; break;
case TradeModel::CHANNEL_WXPAY: case TradeModel::CHANNEL_WXPAY:
$serviceRate = $wxpay['service_rate'] ?: $serviceRate; $serviceRate = $wxpay['service_rate'] ?? $serviceRate;
break; break;
} }

View File

@ -59,10 +59,6 @@ class Learning extends AppService
$key = $this->getSyncKey(); $key = $this->getSyncKey();
$redis->sAdd($key, $learning->request_id); $redis->sAdd($key, $learning->request_id);
if ($redis->sCard($key) == 1) {
$redis->expire($key, $this->lifetime);
}
} }
public function getItemKey($id) public function getItemKey($id)

View File

@ -7,7 +7,6 @@
namespace App\Validators; namespace App\Validators;
use App\Caches\Category as CategoryCache;
use App\Caches\Tag as TagCache; use App\Caches\Tag as TagCache;
use App\Exceptions\BadRequest as BadRequestException; use App\Exceptions\BadRequest as BadRequestException;
use App\Models\Article as ArticleModel; use App\Models\Article as ArticleModel;
@ -17,9 +16,9 @@ class ArticleQuery extends Validator
public function checkCategory($id) public function checkCategory($id)
{ {
$categoryCache = new CategoryCache(); $validator = new Category();
$category = $categoryCache->get($id); $category = $validator->checkCategoryCache($id);
if (!$category) { if (!$category) {
throw new BadRequestException('article_query.invalid_category'); throw new BadRequestException('article_query.invalid_category');

View File

@ -16,9 +16,9 @@ class CourseQuery extends Validator
public function checkTopCategory($id) public function checkTopCategory($id)
{ {
$categoryCache = new CategoryCache(); $validator = new Category();
$category = $categoryCache->get($id); $category = $validator->checkCategoryCache($id);
if (!$category) { if (!$category) {
throw new BadRequestException('course_query.invalid_top_category'); throw new BadRequestException('course_query.invalid_top_category');

View File

@ -14,6 +14,19 @@ use App\Models\Question as QuestionModel;
class QuestionQuery extends Validator class QuestionQuery extends Validator
{ {
public function checkCategory($id)
{
$validator = new Category();
$category = $validator->checkCategoryCache($id);
if (!$category) {
throw new BadRequestException('question_query.invalid_category');
}
return $category->id;
}
public function checkTag($id) public function checkTag($id)
{ {
$tagCache = new TagCache(); $tagCache = new TagCache();

View File

@ -16,12 +16,12 @@
"workerman/gatewayclient": "^3.0", "workerman/gatewayclient": "^3.0",
"whichbrowser/parser": "^2.0", "whichbrowser/parser": "^2.0",
"hightman/xunsearch": "^1.4", "hightman/xunsearch": "^1.4",
"xiaochong0302/ip2region": "^1.0",
"robmorgan/phinx": "^0.12", "robmorgan/phinx": "^0.12",
"overtrue/wechat": "^4.2", "overtrue/wechat": "^4.2",
"endroid/qr-code": "^3.9", "endroid/qr-code": "^3.9",
"league/commonmark": "^1.5", "league/commonmark": "^1.5",
"ezyang/htmlpurifier": "^4.14" "ezyang/htmlpurifier": "^4.14",
"zoujingli/ip2region": "^2.0"
}, },
"require-dev": { "require-dev": {
"odan/phinx-migrations-generator": "^5.3", "odan/phinx-migrations-generator": "^5.3",

105
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "b5eaf9b151226966d37ce2703e2e1efc", "content-hash": "a5d21272eaa0df8bfcd5a3cea6d61fad",
"packages": [ "packages": [
{ {
"name": "bacon/bacon-qr-code", "name": "bacon/bacon-qr-code",
@ -5255,55 +5255,6 @@
], ],
"time": "2022-09-19T04:08:49+00:00" "time": "2022-09-19T04:08:49+00:00"
}, },
{
"name": "xiaochong0302/ip2region",
"version": "v1.0.2",
"source": {
"type": "git",
"url": "https://github.com/xiaochong0302/ip2region.git",
"reference": "de2fbcb236cce91dfa1be2ff65516a46571b3565"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/xiaochong0302/ip2region/zipball/de2fbcb236cce91dfa1be2ff65516a46571b3565",
"reference": "de2fbcb236cce91dfa1be2ff65516a46571b3565",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"php": ">=7.0"
},
"type": "library",
"autoload": {
"psr-4": {
"Koogua\\Ip2Region\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "xiaochong0302",
"email": "xiaochong0302@gmail.com"
}
],
"description": "ip2region扩展包",
"keywords": [
"Ip2Region"
],
"support": {
"issues": "https://github.com/xiaochong0302/ip2region/issues",
"source": "https://github.com/xiaochong0302/ip2region/tree/v1.0.2"
},
"time": "2022-04-27T02:45:22+00:00"
},
{ {
"name": "yansongda/pay", "name": "yansongda/pay",
"version": "v2.10.5", "version": "v2.10.5",
@ -5432,6 +5383,58 @@
"source": "https://github.com/yansongda/supports" "source": "https://github.com/yansongda/supports"
}, },
"time": "2020-10-14T08:17:18+00:00" "time": "2020-10-14T08:17:18+00:00"
},
{
"name": "zoujingli/ip2region",
"version": "v2.0.4",
"source": {
"type": "git",
"url": "https://github.com/zoujingli/ip2region.git",
"reference": "21ed5393a93ea62c277d91ee739b2373d60bf16d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/zoujingli/ip2region/zipball/21ed5393a93ea62c277d91ee739b2373d60bf16d",
"reference": "21ed5393a93ea62c277d91ee739b2373d60bf16d",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"php": ">=5.4"
},
"type": "library",
"autoload": {
"classmap": [
"Ip2Region.php",
"XdbSearcher.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"Apache-2.0"
],
"authors": [
{
"name": "Anyon",
"email": "zoujingli@qq.com",
"homepage": "https://thinkadmin.top"
}
],
"description": "Ip2Region for PHP",
"homepage": "https://github.com/zoujingli/Ip2Region",
"keywords": [
"Ip2Region"
],
"support": {
"issues": "https://github.com/zoujingli/ip2region/issues",
"source": "https://github.com/zoujingli/ip2region/tree/v2.0.4"
},
"time": "2023-03-28T02:20:00+00:00"
} }
], ],
"packages-dev": [ "packages-dev": [
@ -5638,5 +5641,5 @@
"ext-fileinfo": "*" "ext-fileinfo": "*"
}, },
"platform-dev": [], "platform-dev": [],
"plugin-api-version": "2.0.0" "plugin-api-version": "2.3.0"
} }

View File

@ -403,7 +403,7 @@ final class V20210324064239 extends AbstractMigration
]) ])
->addColumn('tags', 'string', [ ->addColumn('tags', 'string', [
'null' => false, 'null' => false,
'default' => '', 'default' => '[]',
'limit' => 255, 'limit' => 255,
'collation' => 'utf8mb4_general_ci', 'collation' => 'utf8mb4_general_ci',
'encoding' => 'utf8mb4', 'encoding' => 'utf8mb4',
@ -4484,7 +4484,7 @@ final class V20210324064239 extends AbstractMigration
]) ])
->addColumn('tags', 'string', [ ->addColumn('tags', 'string', [
'null' => false, 'null' => false,
'default' => '', 'default' => '[]',
'limit' => 255, 'limit' => 255,
'collation' => 'utf8mb4_general_ci', 'collation' => 'utf8mb4_general_ci',
'encoding' => 'utf8mb4', 'encoding' => 'utf8mb4',

View File

@ -88,10 +88,10 @@ final class V20210720153027 extends AbstractMigration
{ {
$table = $this->table('kg_course'); $table = $this->table('kg_course');
if ($table->hasColumn('tags') == false) { if (!$table->hasColumn('tags')) {
$table->addColumn('tags', 'string', [ $table->addColumn('tags', 'string', [
'null' => false, 'null' => false,
'default' => '', 'default' => '[]',
'limit' => 255, 'limit' => 255,
'collation' => 'utf8mb4_general_ci', 'collation' => 'utf8mb4_general_ci',
'encoding' => 'utf8mb4', 'encoding' => 'utf8mb4',
@ -107,7 +107,7 @@ final class V20210720153027 extends AbstractMigration
{ {
$table = $this->table('kg_category'); $table = $this->table('kg_category');
if ($table->hasColumn('alias') == false) { if (!$table->hasColumn('alias')) {
$table->addColumn('alias', 'string', [ $table->addColumn('alias', 'string', [
'null' => false, 'null' => false,
'default' => '', 'default' => '',
@ -119,7 +119,7 @@ final class V20210720153027 extends AbstractMigration
]); ]);
} }
if ($table->hasColumn('icon') == false) { if (!$table->hasColumn('icon')) {
$table->addColumn('icon', 'string', [ $table->addColumn('icon', 'string', [
'null' => false, 'null' => false,
'default' => '', 'default' => '',
@ -138,8 +138,7 @@ final class V20210720153027 extends AbstractMigration
{ {
$table = $this->table('kg_tag'); $table = $this->table('kg_tag');
if ($table->hasColumn('scopes') == false) { if (!$table->hasColumn('scopes')) {
$table->addColumn('scopes', 'string', [ $table->addColumn('scopes', 'string', [
'null' => false, 'null' => false,
'default' => '', 'default' => '',
@ -151,7 +150,7 @@ final class V20210720153027 extends AbstractMigration
]); ]);
} }
if ($table->hasColumn('course_count') == false) { if (!$table->hasColumn('course_count')) {
$table->addColumn('course_count', 'integer', [ $table->addColumn('course_count', 'integer', [
'null' => false, 'null' => false,
'default' => '0', 'default' => '0',
@ -162,7 +161,7 @@ final class V20210720153027 extends AbstractMigration
]); ]);
} }
if ($table->hasColumn('article_count') == false) { if (!$table->hasColumn('article_count')) {
$table->addColumn('article_count', 'integer', [ $table->addColumn('article_count', 'integer', [
'null' => false, 'null' => false,
'default' => '0', 'default' => '0',
@ -173,7 +172,7 @@ final class V20210720153027 extends AbstractMigration
]); ]);
} }
if ($table->hasColumn('question_count') == false) { if (!$table->hasColumn('question_count')) {
$table->addColumn('question_count', 'integer', [ $table->addColumn('question_count', 'integer', [
'null' => false, 'null' => false,
'default' => '0', 'default' => '0',

View File

@ -19,7 +19,7 @@ final class V20210802021814 extends AbstractMigration
{ {
$table = $this->table('kg_page'); $table = $this->table('kg_page');
if ($table->hasColumn('alias') == false) { if (!$table->hasColumn('alias')) {
$table->addColumn('alias', 'string', [ $table->addColumn('alias', 'string', [
'null' => false, 'null' => false,
'default' => '', 'default' => '',

View File

@ -20,7 +20,7 @@ final class V20211017085325 extends AbstractMigration
{ {
$table = $this->table('kg_course'); $table = $this->table('kg_course');
if ($table->hasColumn('fake_user_count') == false) { if (!$table->hasColumn('fake_user_count')) {
$table->addColumn('fake_user_count', 'integer', [ $table->addColumn('fake_user_count', 'integer', [
'null' => false, 'null' => false,
'default' => '0', 'default' => '0',

View File

@ -21,7 +21,7 @@ final class V20211019093522 extends AbstractMigration
{ {
$table = $this->table('kg_user_session'); $table = $this->table('kg_user_session');
if ($table->hasColumn('deleted') == false) { if (!$table->hasColumn('deleted')) {
$table->addColumn('deleted', 'integer', [ $table->addColumn('deleted', 'integer', [
'null' => false, 'null' => false,
'default' => '0', 'default' => '0',
@ -39,7 +39,7 @@ final class V20211019093522 extends AbstractMigration
{ {
$table = $this->table('kg_user_token'); $table = $this->table('kg_user_token');
if ($table->hasColumn('deleted') == false) { if (!$table->hasColumn('deleted')) {
$table->addColumn('deleted', 'integer', [ $table->addColumn('deleted', 'integer', [
'null' => false, 'null' => false,
'default' => '0', 'default' => '0',

View File

@ -29,7 +29,7 @@ final class V20220915084746 extends AbstractMigration
{ {
$table = $this->table('kg_article'); $table = $this->table('kg_article');
if ($table->hasColumn('keywords') == false) { if (!$table->hasColumn('keywords')) {
$table->addColumn('keywords', 'string', [ $table->addColumn('keywords', 'string', [
'null' => false, 'null' => false,
'default' => '', 'default' => '',
@ -48,7 +48,7 @@ final class V20220915084746 extends AbstractMigration
{ {
$table = $this->table('kg_question'); $table = $this->table('kg_question');
if ($table->hasColumn('keywords') == false) { if (!$table->hasColumn('keywords')) {
$table->addColumn('keywords', 'string', [ $table->addColumn('keywords', 'string', [
'null' => false, 'null' => false,
'default' => '', 'default' => '',
@ -67,7 +67,7 @@ final class V20220915084746 extends AbstractMigration
{ {
$table = $this->table('kg_page'); $table = $this->table('kg_page');
if ($table->hasColumn('keywords') == false) { if (!$table->hasColumn('keywords')) {
$table->addColumn('keywords', 'string', [ $table->addColumn('keywords', 'string', [
'null' => false, 'null' => false,
'default' => '', 'default' => '',
@ -86,7 +86,7 @@ final class V20220915084746 extends AbstractMigration
{ {
$table = $this->table('kg_help'); $table = $this->table('kg_help');
if ($table->hasColumn('keywords') == false) { if (!$table->hasColumn('keywords')) {
$table->addColumn('keywords', 'string', [ $table->addColumn('keywords', 'string', [
'null' => false, 'null' => false,
'default' => '', 'default' => '',
@ -105,7 +105,7 @@ final class V20220915084746 extends AbstractMigration
{ {
$table = $this->table('kg_topic'); $table = $this->table('kg_topic');
if ($table->hasColumn('cover') == false) { if (!$table->hasColumn('cover')) {
$table->addColumn('cover', 'string', [ $table->addColumn('cover', 'string', [
'null' => false, 'null' => false,
'default' => '', 'default' => '',

View File

@ -22,7 +22,7 @@ final class V20221021035953 extends AbstractMigration
{ {
$table = $this->table('kg_page'); $table = $this->table('kg_page');
if ($table->hasColumn('view_count') == false) { if (!$table->hasColumn('view_count')) {
$table->addColumn('view_count', 'integer', [ $table->addColumn('view_count', 'integer', [
'null' => false, 'null' => false,
'default' => '0', 'default' => '0',
@ -40,7 +40,7 @@ final class V20221021035953 extends AbstractMigration
{ {
$table = $this->table('kg_help'); $table = $this->table('kg_help');
if ($table->hasColumn('view_count') == false) { if (!$table->hasColumn('view_count')) {
$table->addColumn('view_count', 'integer', [ $table->addColumn('view_count', 'integer', [
'null' => false, 'null' => false,
'default' => '0', 'default' => '0',
@ -58,7 +58,7 @@ final class V20221021035953 extends AbstractMigration
{ {
$table = $this->table('kg_user'); $table = $this->table('kg_user');
if ($table->hasColumn('notice_count') == false) { if (!$table->hasColumn('notice_count')) {
$table->addColumn('notice_count', 'integer', [ $table->addColumn('notice_count', 'integer', [
'null' => false, 'null' => false,
'default' => '0', 'default' => '0',

View File

@ -863,21 +863,17 @@
} }
.filter-group { .filter-group {
padding-bottom: 5px; display: flex;
height: 40px; height: 40px;
line-height: 40px; line-height: 40px;
padding-bottom: 5px;
} }
.filter-group .title { .filter-group .title {
float: left;
width: 50px; width: 50px;
font-weight: 700; font-weight: 700;
} }
.filter-group .content {
float: left;
}
.filter-group .content a { .filter-group .content a {
margin-right: 15px; margin-right: 15px;
} }

View File

@ -97,7 +97,7 @@ layui.use(['jquery', 'form', 'helper'], function () {
function refreshLiveStats() { function refreshLiveStats() {
var $count = $('#toolbar-online > .text'); var $count = $('#toolbar-online > .text');
$.get(liveStatsUrl, function (res) { $.get(liveStatsUrl, function (res) {
$count.text(res.client_count); $count.text(res.stats.client_count);
}); });
} }

View File

@ -29,6 +29,33 @@ layui.use(['jquery', 'helper', 'util'], function () {
}); });
} }
var bars = [];
if (window.contact.qq) {
bars.push({
type: 'qq',
icon: 'layui-icon-login-qq',
});
}
if (window.contact.wechat) {
bars.push({
type: 'wechat',
icon: 'layui-icon-login-wechat',
});
}
util.fixbar({
bars: bars,
click: function (type) {
if (type === 'qq') {
showQQDialog();
} else if (type === 'wechat') {
showWechatCode();
}
}
});
$('.icon-wechat').on('click', function () { $('.icon-wechat').on('click', function () {
showWechatCode(); showWechatCode();
}); });
@ -37,16 +64,4 @@ layui.use(['jquery', 'helper', 'util'], function () {
showTouTiaoCode(); showTouTiaoCode();
}); });
util.fixbar({
bar1: window.contact.qq ? '&#xe676;' : false,
bar2: window.contact.wechat ? '&#xe677;' : false,
click: function (type) {
if (type === 'bar1') {
showQQDialog();
} else if (type === 'bar2') {
showWechatCode();
}
}
});
}); });

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 301 KiB

After

Width:  |  Height:  |  Size: 322 KiB

File diff suppressed because one or more lines are too long