1
0
mirror of https://gitee.com/koogua/course-tencent-cloud.git synced 2025-06-18 01:58:25 +08:00

Compare commits

..

120 Commits

Author SHA1 Message Date
xiaochong0302
247050f4ef Merge branch 'koogua/v1.7.8'
# Conflicts:
#	public/static/admin/js/avatar.upload.js
2025-06-15 16:51:20 +08:00
xiaochong0302
57409cb630 v1.7.8 2025-06-15 15:08:42 +08:00
xiaochong0302
4e1e8340b9 1.添加closeLiveTask
2.优化kg-back返回
3.优化统计分析代码位置
2025-06-11 15:01:23 +08:00
xiaochong0302
2ab6ae71cd 1.优化直播状态显示
2.优化关闭注册提示
2025-06-09 22:46:28 +08:00
xiaochong0302
303442f446 搜索结果中图片alt属性增加striptags过滤 2025-06-09 19:08:33 +08:00
xiaochong0302
7281029dd0 sitemap.xml直接写入public目录 2025-06-05 17:53:06 +08:00
xiaochong0302
f5ed2ce239 优化fixbar电话图标 2025-05-26 19:19:12 +08:00
xiaochong0302
2a1b4b69fd fixbar增加电话图标 2025-05-26 10:41:17 +08:00
xiaochong0302
123e1ec97f 后台重置头像->上传头像 2025-05-23 17:03:58 +08:00
xiaochong0302
b2f795eb3b 还原几个不能为空的腾讯云配置 2025-05-22 23:31:26 +08:00
xiaochong0302
12db90d9c1 还原几个不能为空的腾讯云配置 2025-05-22 23:31:12 +08:00
xiaochong0302
59bfe4a765 gitee webhook测试 2025-05-21 11:05:18 +08:00
xiaochong0302
fb0b760e2e 1.优化后台配置默认值
2.后台增加返回顶部功能
3.精简优化逻辑
2025-05-20 18:09:19 +08:00
xiaochong0302
e31b86580d 优化课时列表直播提示 2025-05-20 18:09:15 +08:00
xiaochong0302
f2a446a876 移除Throttle 2025-05-20 18:09:12 +08:00
xiaochong0302
27440fe679 1.优化后台配置默认值
2.后台增加返回顶部功能
3.精简优化逻辑
2025-05-20 18:06:11 +08:00
xiaochong0302
7a9fee5545 优化课时列表直播提示 2025-05-08 17:18:20 +08:00
xiaochong0302
d927e619e8 移除Throttle 2025-05-02 07:55:38 +08:00
xiaochong0302
77cdc594ff 优化layer窗口中表单的跳转 2025-04-20 17:05:30 +08:00
xiaochong0302
0d8b07033a 优化layer窗口中表单的跳转 2025-04-20 17:03:36 +08:00
xiaochong0302
9ad15b72cf 优化倒计时 2025-04-20 17:03:32 +08:00
xiaochong0302
12f0f6dc87 重命令若干路由 2025-04-20 17:03:28 +08:00
xiaochong0302
3efa081e81 LiveChapter -> LiveChat 2025-04-20 17:03:24 +08:00
xiaochong0302
47a6c5cce1 修正workerman中onMessage无法调用问题 2025-04-20 17:03:20 +08:00
xiaochong0302
328aea1e2d 1.优化章节列表UI
2.优化评价UI
2025-04-20 17:03:17 +08:00
xiaochong0302
e5869e1e8f 1.优化课程目录UI
2.优化收藏UI
3.修正收费课程试听问题
2025-04-20 17:03:14 +08:00
xiaochong0302
9fcea65989 1.优化vip页面
2.优化索引管理工具
2025-04-20 17:03:11 +08:00
xiaochong0302
08d3859e38 1.抽离refund.info.js
2.优化获取临时令牌日志
2025-04-03 19:02:48 +08:00
xiaochong0302
02983a27c9 优化微信公众号相关 2025-04-03 19:02:45 +08:00
xiaochong0302
72deb17daa 增强注册验证 2025-04-03 19:02:42 +08:00
xiaochong0302
76edeef591 v1.7.6 2025-03-19 22:09:45 +08:00
xiaochong0302
9c737c7241 更新layui-v2.9.25 2025-03-19 22:09:41 +08:00
xiaochong0302
21f9bdd4b1 去除不必要的deliver阻断 2025-03-19 22:09:36 +08:00
xiaochong0302
9b0700e5c1 统一支付和登录二维码样式 2025-03-19 22:09:23 +08:00
xiaochong0302
054ab77f08 去除多余的引入 2025-03-11 18:51:50 +08:00
xiaochong0302
90ab9bc018 修正文章和问题缓存 2025-03-11 18:48:58 +08:00
xiaochong0302
77b7224901 限制全文搜索长度为50 2025-03-11 18:48:55 +08:00
xiaochong0302
f5665bc94a 修正SiteVisit积分问题 2025-02-25 16:41:48 +08:00
xiaochong0302
2b08bf737d v1.7.5 2025-02-22 16:03:56 +08:00
xiaochong0302
fce99c2472 优化编辑器页 2025-02-20 20:10:24 +08:00
xiaochong0302
5854d86875 整理categoryId相关 2025-02-20 20:10:21 +08:00
xiaochong0302
e22f3b4bdc 精简优化错误处理机制 2025-02-17 20:16:15 +08:00
xiaochong0302
3070231ca8 优化错误处理机制 2025-02-17 12:42:11 +08:00
xiaochong0302
38f8e27c9c 修正用户注册时502 bad gateway 2025-02-16 13:14:34 +08:00
xiaochong0302
fb7301de4c 1.优化Nav导航
2.优化logo样式
2025-02-16 13:14:31 +08:00
xiaochong0302
9206166910 1.优化后台数据统计日期问题
2.优化内容图片放大查看
2025-02-16 13:14:17 +08:00
xiaochong0302
97af1081d3 修正root账号初始数据 2025-01-10 21:14:37 +08:00
xiaochong0302
2d26c2659b 统一规范$this->response->redirect 2025-01-08 17:42:39 +08:00
xiaochong0302
f273e874e7 Merge branch 'koogua/v1.7.5' 2025-01-05 21:34:33 +08:00
xiaochong0302
b919239308 v1.7.5 release 2025-01-05 21:33:29 +08:00
xiaochong0302
9d210deedf 去除过度设计的缓存 2025-01-05 20:51:54 +08:00
xiaochong0302
09723a9d34 优化积分兑换页 2025-01-05 09:21:45 +08:00
xiaochong0302
9d8ed0f863 还原分页中kg_array_object 2025-01-04 17:21:29 +08:00
xiaochong0302
e27a203ac8 精简整理代码 2025-01-02 11:29:06 +08:00
xiaochong0302
c3887845a9 更新QQ支持群 2024-12-28 14:40:18 +08:00
xiaochong0302
4d810eae98 更新QQ支持群 2024-12-28 14:39:29 +08:00
xiaochong0302
601c71b8a4 精简代码 2024-12-27 21:21:29 +08:00
xiaochong0302
3a6d295aa1 精简判断 2024-12-24 10:56:02 +08:00
xiaochong0302
6614cdc8d2 1.优化boostrap
2.优化logger
3.优化contact
2024-12-16 20:27:40 +08:00
xiaochong0302
0f38ce7d62 1.优化搜索索引
2.优化服务状态监控
3.优化ChapterUserTrait
2024-12-13 08:37:31 +08:00
xiaochong0302
6f005f741c Merge remote-tracking branch 'origin/master' 2024-12-08 16:00:41 +08:00
xiaochong0302
9a51f95d26 v1.7.4 release 2024-12-07 18:23:43 +08:00
xiaochong0302
41cb93d6d5 升级layui-v2.9.20 2024-12-07 11:35:57 +08:00
xiaochong0302
978b77a184 优化CourseUserTrait等 2024-12-06 21:56:49 +08:00
xiaochong0302
98cc8da285 1.精简AccountSearchTrait
2.优化CsrfToken
3.优化kg_setting
4.修正CommentInfo
2024-12-02 17:14:31 +08:00
xiaochong0302
a0e7bce18b 优化kg_h5_index_url() 2024-11-14 17:26:35 +08:00
xiaochong0302
9811186434 修正chapter详情页目录中当前课时高亮问题 2024-11-13 21:59:10 +08:00
xiaochong0302
cdc8074f88 联系方式增加抖音二维码 2024-11-10 22:26:37 +08:00
xiaochong0302
0f446fef10 优化课程期限 2024-11-09 20:38:29 +08:00
xiaochong0302
7ff6f470aa 优化定时自动提交 2024-11-09 20:38:15 +08:00
xiaochong0302
5b30d5d880 优化定时自动提交 2024-11-09 20:37:43 +08:00
xiaochong0302
f482a8ec9e 优化课程期限 2024-10-20 19:32:33 +08:00
xiaochong0302
2302f44c03 Merge branch 'koogua/v1.7.3' 2024-10-10 21:01:29 +08:00
xiaochong0302
4ec6f60b06 v1.7.3 release 2024-10-10 21:00:33 +08:00
xiaochong0302
fa8d27d668 v1.7.3 release 2024-10-10 20:59:23 +08:00
xiaochong0302
a24ea6149e 更新layui-v2.9.16 2024-09-21 11:09:49 +08:00
xiaochong0302
978f064e2b 增加编辑器内容自动提交 2024-09-18 10:23:02 +08:00
xiaochong0302
a360ce0f83 1.优化findUserActiveSessions
2.优化findUserActiveTokens
3.修改文章和提问可用tag数量
4.优化用户锁定相关
2024-09-14 08:32:33 +08:00
xiaochong0302
9b37570a78 1.优化默认文件上传
2.上传文件失败抛出异常
2024-08-13 19:47:38 +08:00
xiaochong0302
86efc64651 Merge branch 'koogua/v1.7.2' 2024-08-13 09:29:06 +08:00
xiaochong0302
d5353ff5d2 1.增加log.trace日志配置
2.migration抽象增加saveSetting方法
2024-08-13 09:27:26 +08:00
xiaochong0302
3a703dd0e1 1.redis增加expire()方法
2.精简代码
2024-07-30 20:06:17 +08:00
xiaochong0302
7c5ea7fe34 后台增加客户服务入口 2024-07-27 08:30:03 +08:00
xiaochong0302
17691a6a1b 修正课程列表分类筛选条件 2024-07-25 11:51:28 +08:00
xiaochong0302
759253cfc5 修正TeacherLiveNotice 2024-07-24 14:21:53 +08:00
xiaochong0302
0f5ed61158 更新layui-v2.9.14 2024-07-12 17:46:01 +08:00
xiaochong0302
e39c140d35 整理doc参数 2024-07-05 20:30:56 +08:00
xiaochong0302
91a878ba98 整理doc参数 2024-07-05 20:30:32 +08:00
xiaochong0302
56f94d3ea8 修正邮件内容格式化 2024-07-04 15:31:24 +08:00
xiaochong0302
36ee91c1cf 修正邮件内容格式化 2024-07-04 15:31:00 +08:00
xiaochong0302
8aaed108b9 Merge branch 'koogua/v1.7.1' 2024-07-01 10:03:35 +08:00
xiaochong0302
4a5cc68915 优化公众号关注订阅 2024-07-01 09:24:29 +08:00
xiaochong0302
f0470c027d 优化邮件发送格式化 2024-06-29 21:26:53 +08:00
xiaochong0302
703d5cbc3d 短信发送处理中增加描述对照 2024-06-28 20:41:45 +08:00
xiaochong0302
f04c23e90f 1.添加课程和章节事件监听
2.优化SEO类
2024-06-28 08:26:28 +08:00
xiaochong0302
b55350a9a4 整理文件,去除无用代码 2024-06-23 08:16:59 +08:00
xiaochong0302
0aa07da41b 整理文件,去除无用代码 2024-06-23 08:16:20 +08:00
xiaochong0302
f66dab48ec Merge branch 'koogua/v1.7.1' 2024-06-21 10:06:14 +08:00
xiaochong0302
2014d99c7e 更新layui-v2.9.10 2024-06-21 09:59:13 +08:00
xiaochong0302
3efdc0698e 课程增加是否能够发布检查 2024-06-12 15:52:24 +08:00
xiaochong0302
675ee63674 清理创建kindeditor默认语言文件 2024-06-12 12:37:59 +08:00
xiaochong0302
14534b8461 去除课程打赏 2024-06-08 15:40:09 +08:00
xiaochong0302
30d9b80ca8 更新文件mimeType 2024-06-02 16:50:35 +08:00
xiaochong0302
17b7f64de7 1.优化富文本内容显示样式
2.简化内容图片放大监听
2024-06-01 16:27:15 +08:00
xiaochong0302
8e618b5bc7 更新mimeTypes 2024-05-29 20:49:23 +08:00
xiaochong0302
4467f8748f 优化FileInfo中MimeType检查 2024-05-28 17:31:39 +08:00
xiaochong0302
45125453e0 iconfont资源本地化 2024-05-28 17:19:52 +08:00
xiaochong0302
200a0b0d16 1.优化storage上传mimeType检查
2.增加打开/关闭左侧菜单提示
2024-05-26 11:49:02 +08:00
xiaochong0302
272a3255d2 优化UploadController 2024-05-26 11:48:18 +08:00
xiaochong0302
dfb88ee09e 1.优化storage上传mimeType检查
2.增加打开/关闭左侧菜单提示
2024-05-25 21:55:04 +08:00
xiaochong0302
0c962920de connect_list增加过滤条件 2024-05-18 09:28:39 +08:00
xiaochong0302
b0b28117f5 connect_list增加过滤条件 2024-05-18 09:28:01 +08:00
xiaochong0302
e22a716aa5 1.调整微信公众号模板消息 2024-05-17 15:46:18 +08:00
xiaochong0302
dd469752e1 1.调整微信公众号模板消息 2024-05-17 15:45:58 +08:00
xiaochong0302
f5ba565f99 修正课程列表顶部过滤条件部分无法收缩问题 2024-05-16 21:29:26 +08:00
xiaochong0302
d0921a8afd 修正课程列表顶部过滤条件部分无法收缩问题 2024-05-16 21:29:02 +08:00
xiaochong0302
fba681a4b5 移除consult中多余的chapter_id属性 2024-05-16 16:46:33 +08:00
xiaochong0302
56f66c01bd 调整微信公众号模板消息 2024-05-16 11:29:19 +08:00
xiaochong0302
8a5aa01d1c 支付限额1w->10w 2024-05-13 18:52:57 +08:00
xiaochong0302
a31c991b1c 1.优化ShareUrl
2.第三方登录增加账号可用性判断
3.优化公众号关注相关
2024-05-12 19:17:57 +08:00
420 changed files with 4031 additions and 5319 deletions

View File

@ -1,3 +1,106 @@
### [v1.7.8](https://gitee.com/koogua/course-tencent-cloud/releases/v1.7.8)(2025-06-20)
- 移除ThrottleLimit
- 增加CloseLiveTask
- 增加搜索页图片alt属性striptags过滤
- 后台增加返回顶部快捷方式
- 前台fixbar增加联系电话
- 优化安装脚本
- 优化课时列表直播提示
- 优化后台返回链接
- 优化统计分析代码位置
- 直播回调后更新课时缓存
- 后台清空头像->上传头像
- sitemap.xml直接写入网站根目录
### [v1.7.7](https://gitee.com/koogua/course-tencent-cloud/releases/v1.7.7)(2025-04-20)
- 优化索引管理工具
- 优化章节等页面UI
- 修正workerman中onMessage问题
- 修正非免费课程试听问题
- 优化layer窗口中的表单跳转
- 文件清理以及命名优化
- 优化倒计时
### [v1.7.6](https://gitee.com/koogua/course-tencent-cloud/releases/v1.7.6)(2025-03-22)
- 升级layui-v2.9.25
- 去除发货中不必要的异常抛出
- 去除文章和问题缓存重建
- 去除多余的文件引用
- 修正每日访问站点积分问题
- 限制全文搜索关键字长度
- 统一规划二维码样式
### [v1.7.5](https://gitee.com/koogua/course-tencent-cloud/releases/v1.7.5)(2025-02-22)
- 优化后台统计图表
- 优化图片放大查看
- 优化错误处理机制
- 优化前台编辑器页面
- 去除一些过度的设计
- 精简属性空判断
- 规整redirect
- 优化bootstrap
- 优化logger
- 优化contact
- 优化logo
- 优化nav
### [v1.7.4](https://gitee.com/koogua/course-tencent-cloud/releases/v1.7.4)(2024-12-10)
- 更新layui-v2.9.20
- 优化编辑器内容自动提交
- 修正课时详情页目录高亮问题
- 修正CommentInfo中点赞判断
- 精简AccountSearchTrait
- 优化kg_h5_index_url()
- 优化CourseUserTrait
- 优化kg_setting()
- 优化CsrfToken
### [v1.7.3](https://gitee.com/koogua/course-tencent-cloud/releases/v1.7.3)(2024-10-10)
- 更新layui-v2.9.16
- 增加编辑器内容自动提交
- 修改文章和提问可用tag数量
- 优化findUserActiveSessions
- 优化findUserActiveTokens
- 优化上传文件失败抛出异常
- 优化默认文件上传
- 优化用户锁定相关
### [v1.7.2](https://gitee.com/koogua/course-tencent-cloud/releases/v1.7.2)(2024-07-31)
- 更新layui-v2.9.14
- 优化docker自动化脚本
- 修正教师直播通知
- 修正课程分类删选问题
- 后台增加客户服务入口
- redis增加expire方法
- 日志记录增加log.trace参数
- 精简代码
### [v1.7.1](https://gitee.com/koogua/course-tencent-cloud/releases/v1.7.1)(2024-06-31)
- 更新layui-v2.9.10
- 更新docker国内镜像地址
- 增加导入镜像构建容器的方式
- 调整微信公众号模板消息
- 移除加载富文本编辑器初始化的语言文件
- 移除consult中多余的chapter_id属性
- 修正课程列表顶部过滤条件区块不能收缩问题
- 用户中心第三方登录列表增加过滤条件
- 后台增加打开/关闭左侧菜单提示
- 优化整理文件mimeType
- iconfont资源本地化
- 优化UploadController
- 优化富文本内容显示样式
- 简化内容图片放大监听
- 去除课程打赏相关内容
- 课程增加能否发布检查
### [v1.7.0](https://gitee.com/koogua/course-tencent-cloud/releases/v1.7.0)(2024-05-15)
- 升级layui-2.9.8

View File

@ -1,6 +1,6 @@
## 酷瓜云课堂
![酷瓜云课堂](https://portal-1255691183.file.myqcloud.com/img/content/61dd395c053e5.png)
[![酷瓜云课堂-开源知识付费解决方案](https://portal-1255691183.file.myqcloud.com/img/content/63ec392618bd5.png)](https://www.koogua.com)
### 系统介绍
@ -17,7 +17,7 @@
友情提示:
- 演示系统配置低(1Core1G1M 跑多个容器)切莫压测
- 演示系统配置低(2核2G1M 跑多个容器)切莫压测
- 课程数据来源于网络(无实质内容)切莫购买
- 管理后台已禁止数据提交,私密配置已过滤
@ -48,9 +48,9 @@ Tips: 请用手机注册一个新账号,用户中心 -> 关注订阅,扫码
### 项目组件
- 后台框架:[phalcon 3.4.5](https://phalcon.io)
- 前端框架:[layui 2.9.3](https://layui.dev)
- 全文检索:[xunsearch 1.4.17](http://www.xunsearch.com)
- 后台框架:[phalcon 3.4](https://phalcon.io)
- 前端框架:[layui 2.9](https://layui.dev)
- 全文检索:[xunsearch 1.4](http://www.xunsearch.com)
- 基础依赖:[php7.3](https://php.net) [mysql5.7](https://mysql.com) [redis5.0](https://redis.io)
### 项目文档

View File

@ -8,7 +8,6 @@
namespace App\Builders;
use App\Repos\Question as QuestionRepo;
use App\Repos\User as UserRepo;
class AnswerList extends Builder
{
@ -18,7 +17,7 @@ class AnswerList extends Builder
$questions = $this->getQuestions($answers);
foreach ($answers as $key => $answer) {
$answers[$key]['question'] = $questions[$answer['question_id']] ?? new \stdClass();
$answers[$key]['question'] = $questions[$answer['question_id']] ?? null;
}
return $answers;
@ -29,7 +28,7 @@ class AnswerList extends Builder
$users = $this->getUsers($answers);
foreach ($answers as $key => $answer) {
$answers[$key]['owner'] = $users[$answer['owner_id']] ?? new \stdClass();
$answers[$key]['owner'] = $users[$answer['owner_id']] ?? null;
}
return $answers;
@ -56,20 +55,7 @@ class AnswerList extends Builder
{
$ids = kg_array_column($answers, 'owner_id');
$userRepo = new UserRepo();
$users = $userRepo->findShallowUserByIds($ids);
$baseUrl = kg_cos_url();
$result = [];
foreach ($users->toArray() as $user) {
$user['avatar'] = $baseUrl . $user['avatar'];
$result[$user['id']] = $user;
}
return $result;
return $this->getShallowUserByIds($ids);
}
}

View File

@ -8,7 +8,6 @@
namespace App\Builders;
use App\Repos\Article as ArticleRepo;
use App\Repos\User as UserRepo;
use Phalcon\Text;
class ArticleFavoriteList extends Builder
@ -19,7 +18,7 @@ class ArticleFavoriteList extends Builder
$articles = $this->getArticles($relations);
foreach ($relations as $key => $value) {
$relations[$key]['article'] = $articles[$value['article_id']] ?? new \stdClass();
$relations[$key]['article'] = $articles[$value['article_id']] ?? null;
}
return $relations;
@ -30,7 +29,7 @@ class ArticleFavoriteList extends Builder
$users = $this->getUsers($relations);
foreach ($relations as $key => $value) {
$relations[$key]['user'] = $users[$value['user_id']] ?? new \stdClass();
$relations[$key]['user'] = $users[$value['user_id']] ?? null;
}
return $relations;
@ -70,20 +69,7 @@ class ArticleFavoriteList extends Builder
{
$ids = kg_array_column($relations, 'user_id');
$userRepo = new UserRepo();
$users = $userRepo->findByIds($ids, ['id', 'name', 'avatar']);
$baseUrl = kg_cos_url();
$result = [];
foreach ($users->toArray() as $user) {
$user['avatar'] = $baseUrl . $user['avatar'];
$result[$user['id']] = $user;
}
return $result;
return $this->getShallowUserByIds($ids);
}
}

View File

@ -9,7 +9,6 @@ namespace App\Builders;
use App\Caches\CategoryAllList as CategoryAllListCache;
use App\Models\Category as CategoryModel;
use App\Repos\User as UserRepo;
class ArticleList extends Builder
{
@ -28,7 +27,7 @@ class ArticleList extends Builder
$categories = $this->getCategories();
foreach ($articles as $key => $article) {
$articles[$key]['category'] = $categories[$article['category_id']] ?? new \stdClass();
$articles[$key]['category'] = $categories[$article['category_id']] ?? null;
}
return $articles;
@ -39,7 +38,7 @@ class ArticleList extends Builder
$users = $this->getUsers($articles);
foreach ($articles as $key => $article) {
$articles[$key]['owner'] = $users[$article['owner_id']] ?? new \stdClass();
$articles[$key]['owner'] = $users[$article['owner_id']] ?? null;
}
return $articles;
@ -69,20 +68,7 @@ class ArticleList extends Builder
{
$ids = kg_array_column($articles, 'owner_id');
$userRepo = new UserRepo();
$users = $userRepo->findShallowUserByIds($ids);
$baseUrl = kg_cos_url();
$result = [];
foreach ($users->toArray() as $user) {
$user['avatar'] = $baseUrl . $user['avatar'];
$result[$user['id']] = $user;
}
return $result;
return $this->getShallowUserByIds($ids);
}
}

View File

@ -7,6 +7,7 @@
namespace App\Builders;
use App\Repos\User as UserRepo;
use Phalcon\Di\Injectable;
class Builder extends Injectable
@ -17,4 +18,22 @@ class Builder extends Injectable
return kg_array_object($items);
}
protected function getShallowUserByIds(array $ids)
{
$userRepo = new UserRepo();
$users = $userRepo->findShallowUserByIds($ids);
$baseUrl = kg_cos_url();
$result = [];
foreach ($users->toArray() as $user) {
$user['avatar'] = $baseUrl . $user['avatar'];
$result[$user['id']] = $user;
}
return $result;
}
}

View File

@ -7,8 +7,6 @@
namespace App\Builders;
use App\Repos\User as UserRepo;
class CommentList extends Builder
{
@ -17,8 +15,8 @@ class CommentList extends Builder
$users = $this->getUsers($comments);
foreach ($comments as $key => $comment) {
$comments[$key]['owner'] = $users[$comment['owner_id']] ?? new \stdClass();
$comments[$key]['to_user'] = $users[$comment['to_user_id']] ?? new \stdClass();
$comments[$key]['owner'] = $users[$comment['owner_id']] ?? null;
$comments[$key]['to_user'] = $users[$comment['to_user_id']] ?? null;
}
return $comments;
@ -30,20 +28,7 @@ class CommentList extends Builder
$toUserIds = kg_array_column($comments, 'to_user_id');
$ids = array_merge($ownerIds, $toUserIds);
$userRepo = new UserRepo();
$users = $userRepo->findShallowUserByIds($ids);
$baseUrl = kg_cos_url();
$result = [];
foreach ($users->toArray() as $user) {
$user['avatar'] = $baseUrl . $user['avatar'];
$result[$user['id']] = $user;
}
return $result;
return $this->getShallowUserByIds($ids);
}
}

View File

@ -7,9 +7,7 @@
namespace App\Builders;
use App\Repos\Chapter as ChapterRepo;
use App\Repos\Course as CourseRepo;
use App\Repos\User as UserRepo;
class ConsultList extends Builder
{
@ -19,7 +17,7 @@ class ConsultList extends Builder
$courses = $this->getCourses($consults);
foreach ($consults as $key => $consult) {
$consults[$key]['course'] = $courses[$consult['course_id']] ?? new \stdClass();
$consults[$key]['course'] = $courses[$consult['course_id']] ?? null;
}
return $consults;
@ -30,8 +28,8 @@ class ConsultList extends Builder
$users = $this->getUsers($consults);
foreach ($consults as $key => $consult) {
$consults[$key]['owner'] = $users[$consult['owner_id']] ?? new \stdClass();
$consults[$key]['replier'] = $users[$consult['replier_id']] ?? new \stdClass();
$consults[$key]['owner'] = $users[$consult['owner_id']] ?? null;
$consults[$key]['replier'] = $users[$consult['replier_id']] ?? null;
}
return $consults;
@ -54,43 +52,13 @@ class ConsultList extends Builder
return $result;
}
public function getChapters(array $consults)
{
$ids = kg_array_column($consults, 'chapter_id');
$chapterRepo = new ChapterRepo();
$chapters = $chapterRepo->findByIds($ids, ['id', 'title']);
$result = [];
foreach ($chapters->toArray() as $chapter) {
$result[$chapter['id']] = $chapter;
}
return $result;
}
public function getUsers(array $consults)
{
$ownerIds = kg_array_column($consults, 'owner_id');
$replierIds = kg_array_column($consults, 'replier_id');
$ids = array_merge($ownerIds, $replierIds);
$userRepo = new UserRepo();
$users = $userRepo->findShallowUserByIds($ids);
$baseUrl = kg_cos_url();
$result = [];
foreach ($users->toArray() as $user) {
$user['avatar'] = $baseUrl . $user['avatar'];
$result[$user['id']] = $user;
}
return $result;
return $this->getShallowUserByIds($ids);
}
}

View File

@ -8,7 +8,6 @@
namespace App\Builders;
use App\Repos\Course as CourseRepo;
use App\Repos\User as UserRepo;
class CourseFavoriteList extends Builder
{
@ -18,7 +17,7 @@ class CourseFavoriteList extends Builder
$courses = $this->getCourses($relations);
foreach ($relations as $key => $value) {
$relations[$key]['course'] = $courses[$value['course_id']] ?? new \stdClass();
$relations[$key]['course'] = $courses[$value['course_id']] ?? null;
}
return $relations;
@ -29,7 +28,7 @@ class CourseFavoriteList extends Builder
$users = $this->getUsers($relations);
foreach ($relations as $key => $value) {
$relations[$key]['user'] = $users[$value['user_id']] ?? new \stdClass();
$relations[$key]['user'] = $users[$value['user_id']] ?? null;
}
return $relations;
@ -70,20 +69,7 @@ class CourseFavoriteList extends Builder
{
$ids = kg_array_column($relations, 'user_id');
$userRepo = new UserRepo();
$users = $userRepo->findByIds($ids, ['id', 'name', 'avatar']);
$baseUrl = kg_cos_url();
$result = [];
foreach ($users->toArray() as $user) {
$user['avatar'] = $baseUrl . $user['avatar'];
$result[$user['id']] = $user;
}
return $result;
return $this->getShallowUserByIds($ids);
}
}

View File

@ -9,7 +9,6 @@ namespace App\Builders;
use App\Caches\CategoryAllList as CategoryAllListCache;
use App\Models\Category as CategoryModel;
use App\Repos\User as UserRepo;
class CourseList extends Builder
{
@ -19,7 +18,7 @@ class CourseList extends Builder
$categories = $this->getCategories();
foreach ($courses as $key => $course) {
$courses[$key]['category'] = $categories[$course['category_id']] ?? new \stdClass();
$courses[$key]['category'] = $categories[$course['category_id']] ?? null;
}
return $courses;
@ -30,7 +29,7 @@ class CourseList extends Builder
$teachers = $this->getTeachers($courses);
foreach ($courses as $key => $course) {
$courses[$key]['teacher'] = $teachers[$course['teacher_id']] ?? new \stdClass();
$courses[$key]['teacher'] = $teachers[$course['teacher_id']] ?? null;
}
return $courses;
@ -60,20 +59,7 @@ class CourseList extends Builder
{
$ids = kg_array_column($courses, 'teacher_id');
$userRepo = new UserRepo();
$users = $userRepo->findShallowUserByIds($ids);
$baseUrl = kg_cos_url();
$result = [];
foreach ($users->toArray() as $user) {
$user['avatar'] = $baseUrl . $user['avatar'];
$result[$user['id']] = $user;
}
return $result;
return $this->getShallowUserByIds($ids);
}
}

View File

@ -18,7 +18,7 @@ class CourseTopicList extends Builder
$courses = $this->getCourses($relations);
foreach ($relations as $key => $value) {
$relations[$key]['course'] = $courses[$value['course_id']] ?? new \stdClass();
$relations[$key]['course'] = $courses[$value['course_id']] ?? null;
}
return $relations;
@ -29,7 +29,7 @@ class CourseTopicList extends Builder
$topics = $this->getTopics($relations);
foreach ($relations as $key => $value) {
$relations[$key]['topic'] = $topics[$value['topic_id']] ?? new \stdClass();
$relations[$key]['topic'] = $topics[$value['topic_id']] ?? null;
}
return $relations;

View File

@ -8,7 +8,6 @@
namespace App\Builders;
use App\Repos\Course as CourseRepo;
use App\Repos\User as UserRepo;
class CourseUserList extends Builder
{
@ -18,7 +17,7 @@ class CourseUserList extends Builder
$courses = $this->getCourses($relations);
foreach ($relations as $key => $value) {
$relations[$key]['course'] = $courses[$value['course_id']] ?? new \stdClass();
$relations[$key]['course'] = $courses[$value['course_id']] ?? null;
}
return $relations;
@ -29,7 +28,7 @@ class CourseUserList extends Builder
$users = $this->getUsers($relations);
foreach ($relations as $key => $value) {
$relations[$key]['user'] = $users[$value['user_id']] ?? new \stdClass();
$relations[$key]['user'] = $users[$value['user_id']] ?? null;
}
return $relations;
@ -74,20 +73,7 @@ class CourseUserList extends Builder
{
$ids = kg_array_column($relations, 'user_id');
$userRepo = new UserRepo();
$users = $userRepo->findByIds($ids, ['id', 'name', 'avatar']);
$baseUrl = kg_cos_url();
$result = [];
foreach ($users->toArray() as $user) {
$user['avatar'] = $baseUrl . $user['avatar'];
$result[$user['id']] = $user;
}
return $result;
return $this->getShallowUserByIds($ids);
}
}

View File

@ -18,7 +18,7 @@ class HelpList extends Builder
$categories = $this->getCategories();
foreach ($helps as $key => $help) {
$helps[$key]['category'] = $categories[$help['category_id']] ?? new \stdClass();
$helps[$key]['category'] = $categories[$help['category_id']] ?? null;
}
return $helps;

View File

@ -9,7 +9,6 @@ namespace App\Builders;
use App\Repos\Chapter as ChapterRepo;
use App\Repos\Course as CourseRepo;
use App\Repos\User as UserRepo;
class LearningList extends Builder
{
@ -19,7 +18,7 @@ class LearningList extends Builder
$courses = $this->getCourses($relations);
foreach ($relations as $key => $value) {
$relations[$key]['course'] = $courses[$value['course_id']] ?? new \stdClass();
$relations[$key]['course'] = $courses[$value['course_id']] ?? null;
}
return $relations;
@ -30,7 +29,7 @@ class LearningList extends Builder
$chapters = $this->getChapters($relations);
foreach ($relations as $key => $value) {
$relations[$key]['chapter'] = $chapters[$value['chapter_id']] ?? new \stdClass();
$relations[$key]['chapter'] = $chapters[$value['chapter_id']] ?? null;
}
return $relations;
@ -41,7 +40,7 @@ class LearningList extends Builder
$users = $this->getUsers($relations);
foreach ($relations as $key => $value) {
$relations[$key]['user'] = $users[$value['user_id']] ?? new \stdClass();
$relations[$key]['user'] = $users[$value['user_id']] ?? null;
}
return $relations;
@ -85,17 +84,7 @@ class LearningList extends Builder
{
$ids = kg_array_column($relations, 'user_id');
$userRepo = new UserRepo();
$users = $userRepo->findByIds($ids, ['id', 'name']);
$result = [];
foreach ($users->toArray() as $user) {
$result[$user['id']] = $user;
}
return $result;
return $this->getShallowUserByIds($ids);
}
}

View File

@ -19,7 +19,7 @@ class LiveList extends Builder
$courses = $this->getCourses($lives);
foreach ($lives as $key => $live) {
$lives[$key]['course'] = $courses[$live['course_id']] ?? new \stdClass();
$lives[$key]['course'] = $courses[$live['course_id']] ?? null;
}
return $lives;
@ -30,7 +30,7 @@ class LiveList extends Builder
$chapters = $this->getChapters($lives);
foreach ($lives as $key => $live) {
$lives[$key]['chapter'] = $chapters[$live['chapter_id']] ?? new \stdClass();
$lives[$key]['chapter'] = $chapters[$live['chapter_id']] ?? null;
}
return $lives;
@ -63,7 +63,7 @@ class LiveList extends Builder
foreach ($courses->toArray() as $course) {
$course['cover'] = $baseUrl . $course['cover'];
$course['teacher'] = $teachers[$course['teacher_id']] ?? new \stdClass();
$course['teacher'] = $teachers[$course['teacher_id']] ?? null;
$result[$course['id']] = [
'id' => $course['id'],
'title' => $course['title'],

View File

@ -7,8 +7,6 @@
namespace App\Builders;
use App\Repos\User as UserRepo;
class NotificationList extends Builder
{
@ -17,8 +15,8 @@ class NotificationList extends Builder
$users = $this->getUsers($notifications);
foreach ($notifications as $key => $notification) {
$notifications[$key]['sender'] = $users[$notification['sender_id']] ?? new \stdClass();
$notifications[$key]['receiver'] = $users[$notification['receiver_id']] ?? new \stdClass();
$notifications[$key]['sender'] = $users[$notification['sender_id']] ?? null;
$notifications[$key]['receiver'] = $users[$notification['receiver_id']] ?? null;
}
return $notifications;
@ -30,20 +28,7 @@ class NotificationList extends Builder
$receiverIds = kg_array_column($notifications, 'receiver_id');
$ids = array_merge($senderIds, $receiverIds);
$userRepo = new UserRepo();
$users = $userRepo->findShallowUserByIds($ids);
$baseUrl = kg_cos_url();
$result = [];
foreach ($users->toArray() as $user) {
$user['avatar'] = $baseUrl . $user['avatar'];
$result[$user['id']] = $user;
}
return $result;
return $this->getShallowUserByIds($ids);
}
}

View File

@ -9,7 +9,6 @@ namespace App\Builders;
use App\Models\Course as CourseModel;
use App\Models\Order as OrderModel;
use App\Repos\User as UserRepo;
class OrderList extends Builder
{
@ -30,7 +29,7 @@ class OrderList extends Builder
$users = $this->getUsers($orders);
foreach ($orders as $key => $order) {
$orders[$key]['owner'] = $users[$order['owner_id']] ?? new \stdClass();
$orders[$key]['owner'] = $users[$order['owner_id']] ?? null;
}
return $orders;
@ -113,8 +112,13 @@ class OrderList extends Builder
$me['allow_refund'] = $refundStatusOk && $refundTimeOk ? 1 : 0;
}
$me['allow_pay'] = $payStatusOk;
$me['allow_cancel'] = $cancelStatusOk;
if ($payStatusOk == 1) {
$me['allow_pay'] = 1;
}
if ($cancelStatusOk == 1) {
$me['allow_cancel'] = 1;
}
return $me;
}
@ -149,20 +153,6 @@ class OrderList extends Builder
return $itemInfo;
}
/**
* @param string $itemInfo
* @return mixed
*/
protected function handleRewardInfo($itemInfo)
{
if (!empty($itemInfo) && is_string($itemInfo)) {
$itemInfo = json_decode($itemInfo, true);
$itemInfo['course']['cover'] = $this->imgBaseUrl . $itemInfo['course']['cover'];
}
return $itemInfo;
}
/**
* @param string $itemInfo
* @return mixed
@ -184,17 +174,7 @@ class OrderList extends Builder
{
$ids = kg_array_column($orders, 'owner_id');
$userRepo = new UserRepo();
$users = $userRepo->findShallowUserByIds($ids);
$result = [];
foreach ($users->toArray() as $user) {
$result[$user['id']] = $user;
}
return $result;
return $this->getShallowUserByIds($ids);
}
}

View File

@ -8,7 +8,6 @@
namespace App\Builders;
use App\Repos\Question as QuestionRepo;
use App\Repos\User as UserRepo;
use Phalcon\Text;
class QuestionFavoriteList extends Builder
@ -19,7 +18,7 @@ class QuestionFavoriteList extends Builder
$questions = $this->getQuestions($relations);
foreach ($relations as $key => $value) {
$relations[$key]['question'] = $questions[$value['question_id']] ?? new \stdClass();
$relations[$key]['question'] = $questions[$value['question_id']] ?? null;
}
return $relations;
@ -30,7 +29,7 @@ class QuestionFavoriteList extends Builder
$users = $this->getUsers($relations);
foreach ($relations as $key => $value) {
$relations[$key]['user'] = $users[$value['user_id']] ?? new \stdClass();
$relations[$key]['user'] = $users[$value['user_id']] ?? null;
}
return $relations;
@ -70,20 +69,7 @@ class QuestionFavoriteList extends Builder
{
$ids = kg_array_column($relations, 'user_id');
$userRepo = new UserRepo();
$users = $userRepo->findShallowUserByIds($ids);
$baseUrl = kg_cos_url();
$result = [];
foreach ($users->toArray() as $user) {
$user['avatar'] = $baseUrl . $user['avatar'];
$result[$user['id']] = $user;
}
return $result;
return $this->getShallowUserByIds($ids);
}
}

View File

@ -9,7 +9,6 @@ namespace App\Builders;
use App\Caches\CategoryAllList as CategoryAllListCache;
use App\Models\Category as CategoryModel;
use App\Repos\User as UserRepo;
class QuestionList extends Builder
{
@ -28,7 +27,7 @@ class QuestionList extends Builder
$categories = $this->getCategories();
foreach ($questions as $key => $question) {
$questions[$key]['category'] = $categories[$question['category_id']] ?? new \stdClass();
$questions[$key]['category'] = $categories[$question['category_id']] ?? null;
}
return $questions;
@ -39,8 +38,8 @@ class QuestionList extends Builder
$users = $this->getUsers($questions);
foreach ($questions as $key => $question) {
$questions[$key]['owner'] = $users[$question['owner_id']] ?? new \stdClass();
$questions[$key]['last_replier'] = $users[$question['last_replier_id']] ?? new \stdClass();
$questions[$key]['owner'] = $users[$question['owner_id']] ?? null;
$questions[$key]['last_replier'] = $users[$question['last_replier_id']] ?? null;
}
return $questions;
@ -72,20 +71,7 @@ class QuestionList extends Builder
$lastReplierIds = kg_array_column($questions, 'last_replier_id');
$ids = array_merge($ownerIds, $lastReplierIds);
$userRepo = new UserRepo();
$users = $userRepo->findShallowUserByIds($ids);
$baseUrl = kg_cos_url();
$result = [];
foreach ($users->toArray() as $user) {
$user['avatar'] = $baseUrl . $user['avatar'];
$result[$user['id']] = $user;
}
return $result;
return $this->getShallowUserByIds($ids);
}
}

View File

@ -9,7 +9,6 @@ namespace App\Builders;
use App\Models\Refund as RefundModel;
use App\Repos\Order as OrderRepo;
use App\Repos\User as UserRepo;
class RefundList extends Builder
{
@ -19,7 +18,7 @@ class RefundList extends Builder
$orders = $this->getOrders($trades);
foreach ($trades as $key => $trade) {
$trades[$key]['order'] = $orders[$trade['order_id']] ?? new \stdClass();
$trades[$key]['order'] = $orders[$trade['order_id']] ?? null;
}
return $trades;
@ -30,7 +29,7 @@ class RefundList extends Builder
$users = $this->getUsers($refunds);
foreach ($refunds as $key => $refund) {
$refunds[$key]['owner'] = $users[$refund['owner_id']] ?? new \stdClass();
$refunds[$key]['owner'] = $users[$refund['owner_id']] ?? null;
}
return $refunds;
@ -75,20 +74,7 @@ class RefundList extends Builder
{
$ids = kg_array_column($refunds, 'owner_id');
$userRepo = new UserRepo();
$users = $userRepo->findShallowUserByIds($ids);
$baseUrl = kg_cos_url();
$result = [];
foreach ($users->toArray() as $user) {
$user['avatar'] = $baseUrl . $user['avatar'];
$result[$user['id']] = $user;
}
return $result;
return $this->getShallowUserByIds($ids);
}
}

View File

@ -7,8 +7,6 @@
namespace App\Builders;
use App\Repos\User as UserRepo;
class ReportList extends Builder
{
@ -17,7 +15,7 @@ class ReportList extends Builder
$users = $this->getUsers($reports);
foreach ($reports as $key => $report) {
$reports[$key]['owner'] = $users[$report['owner_id']] ?? new \stdClass();
$reports[$key]['owner'] = $users[$report['owner_id']] ?? null;
}
return $reports;
@ -27,20 +25,7 @@ class ReportList extends Builder
{
$ids = kg_array_column($reports, 'owner_id');
$userRepo = new UserRepo();
$users = $userRepo->findShallowUserByIds($ids);
$baseUrl = kg_cos_url();
$result = [];
foreach ($users->toArray() as $user) {
$user['avatar'] = $baseUrl . $user['avatar'];
$result[$user['id']] = $user;
}
return $result;
return $this->getShallowUserByIds($ids);
}
}

View File

@ -17,7 +17,7 @@ class ResourceList extends Builder
$uploads = $this->getUploads($relations);
foreach ($relations as $key => $value) {
$relations[$key]['upload'] = $uploads[$value['upload_id']] ?? new \stdClass();
$relations[$key]['upload'] = $uploads[$value['upload_id']] ?? null;
}
return $relations;

View File

@ -8,7 +8,6 @@
namespace App\Builders;
use App\Repos\Course as CourseRepo;
use App\Repos\User as UserRepo;
class ReviewList extends Builder
{
@ -18,7 +17,7 @@ class ReviewList extends Builder
$courses = $this->getCourses($reviews);
foreach ($reviews as $key => $review) {
$reviews[$key]['course'] = $courses[$review['course_id']] ?? new \stdClass();
$reviews[$key]['course'] = $courses[$review['course_id']] ?? null;
}
return $reviews;
@ -29,7 +28,7 @@ class ReviewList extends Builder
$users = $this->getUsers($reviews);
foreach ($reviews as $key => $review) {
$reviews[$key]['owner'] = $users[$review['owner_id']] ?? new \stdClass();
$reviews[$key]['owner'] = $users[$review['owner_id']] ?? null;
}
return $reviews;
@ -56,20 +55,7 @@ class ReviewList extends Builder
{
$ids = kg_array_column($reviews, 'owner_id');
$userRepo = new UserRepo();
$users = $userRepo->findShallowUserByIds($ids);
$baseUrl = kg_cos_url();
$result = [];
foreach ($users->toArray() as $user) {
$user['avatar'] = $baseUrl . $user['avatar'];
$result[$user['id']] = $user;
}
return $result;
return $this->getShallowUserByIds($ids);
}
}

View File

@ -8,7 +8,6 @@
namespace App\Builders;
use App\Repos\Tag as TagRepo;
use App\Repos\User as UserRepo;
class TagFollowList extends Builder
{
@ -18,7 +17,7 @@ class TagFollowList extends Builder
$tags = $this->getTags($relations);
foreach ($relations as $key => $value) {
$relations[$key]['tag'] = $tags[$value['tag_id']] ?? new \stdClass();
$relations[$key]['tag'] = $tags[$value['tag_id']] ?? null;
}
return $relations;
@ -29,7 +28,7 @@ class TagFollowList extends Builder
$users = $this->getUsers($relations);
foreach ($relations as $key => $value) {
$relations[$key]['user'] = $users[$value['user_id']] ?? new \stdClass();
$relations[$key]['user'] = $users[$value['user_id']] ?? null;
}
return $relations;
@ -61,20 +60,7 @@ class TagFollowList extends Builder
{
$ids = kg_array_column($relations, 'user_id');
$userRepo = new UserRepo();
$users = $userRepo->findByIds($ids, ['id', 'name', 'avatar']);
$baseUrl = kg_cos_url();
$result = [];
foreach ($users->toArray() as $user) {
$user['avatar'] = $baseUrl . $user['avatar'];
$result[$user['id']] = $user;
}
return $result;
return $this->getShallowUserByIds($ids);
}
}

View File

@ -8,7 +8,6 @@
namespace App\Builders;
use App\Repos\Order as OrderRepo;
use App\Repos\User as UserRepo;
class TradeList extends Builder
{
@ -18,7 +17,7 @@ class TradeList extends Builder
$orders = $this->getOrders($trades);
foreach ($trades as $key => $trade) {
$trades[$key]['order'] = $orders[$trade['order_id']] ?? new \stdClass();
$trades[$key]['order'] = $orders[$trade['order_id']] ?? null;
}
return $trades;
@ -29,7 +28,7 @@ class TradeList extends Builder
$users = $this->getUsers($trades);
foreach ($trades as $key => $trade) {
$trades[$key]['owner'] = $users[$trade['owner_id']] ?? new \stdClass();
$trades[$key]['owner'] = $users[$trade['owner_id']] ?? null;
}
return $trades;
@ -56,20 +55,7 @@ class TradeList extends Builder
{
$ids = kg_array_column($trades, 'owner_id');
$userRepo = new UserRepo();
$users = $userRepo->findShallowUserByIds($ids);
$baseUrl = kg_cos_url();
$result = [];
foreach ($users->toArray() as $user) {
$user['avatar'] = $baseUrl . $user['avatar'];
$result[$user['id']] = $user;
}
return $result;
return $this->getShallowUserByIds($ids);
}
}

View File

@ -30,7 +30,7 @@ class UserList extends Builder
$accounts = $this->getAccounts($users);
foreach ($users as $key => $user) {
$users[$key]['account'] = $accounts[$user['id']] ?? new \stdClass();
$users[$key]['account'] = $accounts[$user['id']] ?? null;
}
return $users;

View File

@ -1,36 +0,0 @@
<?php
/**
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.koogua.com
*/
namespace App\Caches;
use App\Repos\Article as ArticleRepo;
class Article extends Cache
{
protected $lifetime = 86400;
public function getLifetime()
{
return $this->lifetime;
}
public function getKey($id = null)
{
return "article:{$id}";
}
public function getContent($id = null)
{
$articleRepo = new ArticleRepo();
$article = $articleRepo->findById($id);
return $article ?: null;
}
}

View File

@ -1,36 +0,0 @@
<?php
/**
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.koogua.com
*/
namespace App\Caches;
use App\Repos\Help as HelpRepo;
class Help extends Cache
{
protected $lifetime = 7 * 86400;
public function getLifetime()
{
return $this->lifetime;
}
public function getKey($id = null)
{
return "help:{$id}";
}
public function getContent($id = null)
{
$helpRepo = new HelpRepo();
$help = $helpRepo->findById($id);
return $help ?: null;
}
}

View File

@ -1,97 +0,0 @@
<?php
/**
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.koogua.com
*/
namespace App\Caches;
use App\Models\Category as CategoryModel;
use App\Models\Help as HelpModel;
use Phalcon\Mvc\Model\Resultset;
use Phalcon\Mvc\Model\ResultsetInterface;
class HelpList extends Cache
{
protected $lifetime = 7 * 86400;
public function getLifetime()
{
return $this->lifetime;
}
public function getKey($id = null)
{
return 'help_list';
}
public function getContent($id = null)
{
$categories = $this->findCategories();
if ($categories->count() == 0) {
return [];
}
$result = [];
foreach ($categories as $category) {
$item = [];
$item['category'] = [
'id' => $category->id,
'name' => $category->name,
];
$item['helps'] = [];
$helps = $this->findHelps($category->id);
if ($helps->count() > 0) {
foreach ($helps as $help) {
$item['helps'][] = [
'id' => $help->id,
'title' => $help->title,
];
}
}
$result[] = $item;
}
return $result;
}
/**
* @return ResultsetInterface|Resultset|CategoryModel[]
*/
protected function findCategories()
{
return CategoryModel::query()
->where('type = :type:', ['type' => CategoryModel::TYPE_HELP])
->andWhere('level = 1')
->andWhere('published = 1')
->andWhere('deleted = 0')
->orderBy('priority ASC')
->execute();
}
/**
* @param int $categoryId
* @return ResultsetInterface|Resultset|CategoryModel[]
*/
protected function findHelps($categoryId)
{
return HelpModel::query()
->where('category_id = :category_id:', ['category_id' => $categoryId])
->andWhere('published = 1')
->andWhere('deleted = 0')
->orderBy('priority ASC')
->execute();
}
}

View File

@ -1,34 +0,0 @@
<?php
/**
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.koogua.com
*/
namespace App\Caches;
use App\Models\Answer as AnswerModel;
class MaxAnswerId extends Cache
{
protected $lifetime = 365 * 86400;
public function getLifetime()
{
return $this->lifetime;
}
public function getKey($id = null)
{
return 'max_answer_id';
}
public function getContent($id = null)
{
$answer = AnswerModel::findFirst(['order' => 'id DESC']);
return $answer->id ?? 0;
}
}

View File

@ -1,34 +0,0 @@
<?php
/**
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.koogua.com
*/
namespace App\Caches;
use App\Models\Article as ArticleModel;
class MaxArticleId extends Cache
{
protected $lifetime = 365 * 86400;
public function getLifetime()
{
return $this->lifetime;
}
public function getKey($id = null)
{
return 'max_article_id';
}
public function getContent($id = null)
{
$article = ArticleModel::findFirst(['order' => 'id DESC']);
return $article->id ?? 0;
}
}

View File

@ -1,34 +0,0 @@
<?php
/**
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.koogua.com
*/
namespace App\Caches;
use App\Models\Comment as CommentModel;
class MaxCommentId extends Cache
{
protected $lifetime = 365 * 86400;
public function getLifetime()
{
return $this->lifetime;
}
public function getKey($id = null)
{
return 'max_comment_id';
}
public function getContent($id = null)
{
$comment = CommentModel::findFirst(['order' => 'id DESC']);
return $comment->id ?? 0;
}
}

View File

@ -1,34 +0,0 @@
<?php
/**
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.koogua.com
*/
namespace App\Caches;
use App\Models\Help as HelpModel;
class MaxHelpId extends Cache
{
protected $lifetime = 365 * 86400;
public function getLifetime()
{
return $this->lifetime;
}
public function getKey($id = null)
{
return 'max_help_id';
}
public function getContent($id = null)
{
$help = HelpModel::findFirst(['order' => 'id DESC']);
return $help->id ?? 0;
}
}

View File

@ -1,34 +0,0 @@
<?php
/**
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.koogua.com
*/
namespace App\Caches;
use App\Models\Page as PageModel;
class MaxPageId extends Cache
{
protected $lifetime = 365 * 86400;
public function getLifetime()
{
return $this->lifetime;
}
public function getKey($id = null)
{
return 'max_page_id';
}
public function getContent($id = null)
{
$page = PageModel::findFirst(['order' => 'id DESC']);
return $page->id ?? 0;
}
}

View File

@ -1,34 +0,0 @@
<?php
/**
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.koogua.com
*/
namespace App\Caches;
use App\Models\PointGift as PointGiftModel;
class MaxPointGiftId extends Cache
{
protected $lifetime = 365 * 86400;
public function getLifetime()
{
return $this->lifetime;
}
public function getKey($id = null)
{
return 'max_point_gift_id';
}
public function getContent($id = null)
{
$gift = PointGiftModel::findFirst(['order' => 'id DESC']);
return $gift->id ?? 0;
}
}

View File

@ -1,34 +0,0 @@
<?php
/**
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.koogua.com
*/
namespace App\Caches;
use App\Models\Question as QuestionModel;
class MaxQuestionId extends Cache
{
protected $lifetime = 365 * 86400;
public function getLifetime()
{
return $this->lifetime;
}
public function getKey($id = null)
{
return 'max_question_id';
}
public function getContent($id = null)
{
$question = QuestionModel::findFirst(['order' => 'id DESC']);
return $question->id ?? 0;
}
}

View File

@ -1,34 +0,0 @@
<?php
/**
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.koogua.com
*/
namespace App\Caches;
use App\Models\Upload as UploadModel;
class MaxUploadId extends Cache
{
protected $lifetime = 365 * 86400;
public function getLifetime()
{
return $this->lifetime;
}
public function getKey($id = null)
{
return 'max_upload_id';
}
public function getContent($id = null)
{
$upload = UploadModel::findFirst(['order' => 'id DESC']);
return $upload->id ?? 0;
}
}

View File

@ -1,44 +0,0 @@
<?php
/**
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.koogua.com
*/
namespace App\Caches;
use App\Repos\Stat as StatRepo;
class ModerationStat extends Cache
{
protected $lifetime = 15 * 60;
public function getLifetime()
{
return $this->lifetime;
}
public function getKey($id = null)
{
return 'moderation_stat';
}
public function getContent($id = null)
{
$statRepo = new StatRepo();
$articleCount = $statRepo->countPendingArticles();
$questionCount = $statRepo->countPendingQuestions();
$answerCount = $statRepo->countPendingAnswers();
$commentCount = $statRepo->countPendingComments();
return [
'article_count' => $articleCount,
'question_count' => $questionCount,
'answer_count' => $answerCount,
'comment_count' => $commentCount,
];
}
}

View File

@ -1,36 +0,0 @@
<?php
/**
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.koogua.com
*/
namespace App\Caches;
use App\Repos\Page as PageRepo;
class Page extends Cache
{
protected $lifetime = 7 * 86400;
public function getLifetime()
{
return $this->lifetime;
}
public function getKey($id = null)
{
return "page:{$id}";
}
public function getContent($id = null)
{
$pageRepo = new PageRepo();
$page = $pageRepo->findById($id);
return $page ?: null;
}
}

View File

@ -1,36 +0,0 @@
<?php
/**
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.koogua.com
*/
namespace App\Caches;
use App\Repos\PointGift as PointGiftRepo;
class PointGift extends Cache
{
protected $lifetime = 86400;
public function getLifetime()
{
return $this->lifetime;
}
public function getKey($id = null)
{
return "point_gift:{$id}";
}
public function getContent($id = null)
{
$giftRepo = new PointGiftRepo();
$gift = $giftRepo->findById($id);
return $gift ?: null;
}
}

View File

@ -1,36 +0,0 @@
<?php
/**
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.koogua.com
*/
namespace App\Caches;
use App\Repos\Question as QuestionRepo;
class Question extends Cache
{
protected $lifetime = 86400;
public function getLifetime()
{
return $this->lifetime;
}
public function getKey($id = null)
{
return "question:{$id}";
}
public function getContent($id = null)
{
$questionRepo = new QuestionRepo();
$question = $questionRepo->findById($id);
return $question ?: null;
}
}

View File

@ -7,11 +7,36 @@
namespace App\Console\Migrations;
use App\Models\Setting as SettingModel;
use App\Repos\Setting as SettingRepo;
use App\Traits\Service as ServiceTrait;
abstract class Migration
{
use ServiceTrait;
abstract public function run();
}
protected function saveSettings(array $settings)
{
foreach ($settings as $setting) {
$this->saveSetting($setting);
}
}
protected function saveSetting(array $setting)
{
$settingRepo = new SettingRepo();
$item = $settingRepo->findItem($setting['section'], $setting['item_key']);
if (!$item) {
$item = new SettingModel();
$item->create($setting);
} else {
$item->update($setting);
}
}
}

View File

@ -0,0 +1,48 @@
<?php
/**
* @copyright Copyright (c) 2024 深圳市酷瓜软件有限公司
* @license https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* @link https://www.koogua.com
*/
namespace App\Console\Migrations;
use App\Models\Chapter as ChapterModel;
use App\Models\Course as CourseModel;
use Phalcon\Mvc\Model\Resultset;
class V20240608145810 extends Migration
{
public function run()
{
$this->handleReadChapters();
}
protected function handleReadChapters()
{
/**
* @var $chapters Resultset|ChapterModel[]
*/
$chapters = ChapterModel::query()
->where('model = :model:', ['model' => CourseModel::MODEL_READ])
->andWhere('parent_id > 0')
->execute();
if ($chapters->count() == 0) return;
foreach ($chapters as $chapter) {
$attrs = $chapter->attrs;
if (isset($attrs['format'])) continue;
$attrs['format'] = 'html';
$chapter->attrs = $attrs;
$chapter->update();
}
}
}

View File

@ -0,0 +1,29 @@
<?php
/**
* @copyright Copyright (c) 2024 深圳市酷瓜软件有限公司
* @license https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* @link https://www.koogua.com
*/
namespace App\Console\Migrations;
class V20241110191316 extends Migration
{
public function run()
{
$this->handleContactSettings();
}
protected function handleContactSettings()
{
$setting = [
'section' => 'contact',
'item_key' => 'douyin',
'item_value' => '',
];
$this->saveSetting($setting);
}
}

View File

@ -0,0 +1,41 @@
<?php
/**
* @copyright Copyright (c) 2025 深圳市酷瓜软件有限公司
* @license https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* @link https://www.koogua.com
*/
namespace App\Console\Migrations;
use App\Models\UserBalance;
use App\Repos\User as UserRepo;
class V20250110191618 extends Migration
{
public function run()
{
$this->handleRootUserBalance();
}
/**
* 之前migration初始化root账号缺少user_balance数据
*/
protected function handleRootUserBalance()
{
$userId = 10000;
$userRepo = new UserRepo();
$userBalance = $userRepo->findUserBalance($userId);
if ($userBalance) return;
$userBalance = new UserBalance();
$userBalance->user_id = $userId;
$userBalance->create();
}
}

View File

@ -20,8 +20,6 @@ class ArticleIndexTask extends Task
* 搜索测试
*
* @command: php console.php article_index search {query}
* @param array $params
* @throws \XSException
*/
public function searchAction($params)
{
@ -31,7 +29,9 @@ class ArticleIndexTask extends Task
exit('please special a query word' . PHP_EOL);
}
$result = $this->searchArticles($query);
$handler = new ArticleSearcher();
$result = $handler->search($query);
var_export($result);
}
@ -42,24 +42,6 @@ class ArticleIndexTask extends Task
* @command: php console.php article_index clean
*/
public function cleanAction()
{
$this->cleanArticleIndex();
}
/**
* 重建索引
*
* @command: php console.php article_index rebuild
*/
public function rebuildAction()
{
$this->rebuildArticleIndex();
}
/**
* 清空索引
*/
protected function cleanArticleIndex()
{
$handler = new ArticleSearcher();
@ -74,8 +56,10 @@ class ArticleIndexTask extends Task
/**
* 重建索引
*
* @command: php console.php article_index rebuild
*/
protected function rebuildArticleIndex()
public function rebuildAction()
{
$articles = $this->findArticles();
@ -83,7 +67,7 @@ class ArticleIndexTask extends Task
$handler = new ArticleSearcher();
$documenter = new ArticleDocument();
$doc = new ArticleDocument();
$index = $handler->getXS()->getIndex();
@ -92,7 +76,7 @@ class ArticleIndexTask extends Task
$index->beginRebuild();
foreach ($articles as $article) {
$document = $documenter->setDocument($article);
$document = $doc->setDocument($article);
$index->add($document);
}
@ -102,17 +86,39 @@ class ArticleIndexTask extends Task
}
/**
* 搜索文章
* 刷新索引缓存
*
* @param string $query
* @return array
* @throws \XSException
* @command: php console.php article_index flush_index
*/
protected function searchArticles($query)
public function flushIndexAction()
{
$handler = new ArticleSearcher();
return $handler->search($query);
$index = $handler->getXS()->getIndex();
echo '------ start flush article index ------' . PHP_EOL;
$index->flushIndex();
echo '------ end flush article index ------' . PHP_EOL;
}
/**
* 刷新搜索日志
*
* @command: php console.php article_index flush_logging
*/
public function flushLoggingAction()
{
$handler = new ArticleSearcher();
$index = $handler->getXS()->getIndex();
echo '------ start flush article logging ------' . PHP_EOL;
$index->flushLogging();
echo '------ end flush article logging ------' . PHP_EOL;
}
/**

View File

@ -7,8 +7,8 @@
namespace App\Console\Tasks;
use App\Caches\CategoryList as CategoryListCache;
use App\Caches\CategoryAllList as CategoryAllListCache;
use App\Caches\CategoryList as CategoryListCache;
use App\Caches\CategoryTreeList as CategoryTreeListCache;
use App\Caches\IndexSlideList as IndexSlideListCache;
use App\Models\Account as AccountModel;
@ -39,8 +39,8 @@ class CleanDemoDataTask extends Task
echo '------ start truncate tables ------' . PHP_EOL;
$excludeTables = [
'kg_area', 'kg_migration', 'kg_migration_task', 'kg_nav', 'kg_page',
'kg_reward', 'kg_role', 'kg_setting', 'kg_vip',
'kg_area', 'kg_migration', 'kg_migration_task', 'kg_nav',
'kg_page', 'kg_role', 'kg_setting', 'kg_vip',
];
$tables = $this->db->listTables();

View File

@ -0,0 +1,72 @@
<?php
/**
* @copyright Copyright (c) 2024 深圳市酷瓜软件有限公司
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.koogua.com
*/
namespace App\Console\Tasks;
use App\Caches\CourseChapterList as CourseChapterListCache;
use App\Models\Chapter as ChapterModel;
use App\Models\ChapterLive as ChapterLiveModel;
use App\Repos\Chapter as ChapterRepo;
use Phalcon\Mvc\Model\Resultset;
use Phalcon\Mvc\Model\ResultsetInterface;
class CloseLiveTask extends Task
{
public function mainAction()
{
$chapterLives = $this->findChapterLives();
echo sprintf('pending lives: %s', $chapterLives->count()) . PHP_EOL;
if ($chapterLives->count() == 0) return;
echo '------ start close live task ------' . PHP_EOL;
foreach ($chapterLives as $chapterLive) {
$chapterLive->status = ChapterLiveModel::STATUS_INACTIVE;
$chapterLive->update();
$chapterRepo = new ChapterRepo();
$chapter = $chapterRepo->findById($chapterLive->chapter_id);
$attrs = $chapter->attrs;
$attrs['stream']['status'] = ChapterModel::SS_INACTIVE;
$chapter->attrs = $attrs;
$chapter->update();
$cache = new CourseChapterListCache();
$cache->rebuild($chapterLive->course_id);
}
echo '------ end close live task ------' . PHP_EOL;
}
/**
* 查找待关闭直播
*
* @param int $limit
* @return ResultsetInterface|Resultset|ChapterLiveModel[]
*/
protected function findChapterLives(int $limit = 100)
{
$status = ChapterLiveModel::STATUS_ACTIVE;
$endTime = time() - 3600;
return ChapterLiveModel::query()
->where('status = :status:', ['status' => $status])
->andWhere('end_time < :end_time:', ['end_time' => $endTime])
->limit($limit)
->execute();
}
}

View File

@ -20,8 +20,6 @@ class CourseIndexTask extends Task
* 搜索测试
*
* @command: php console.php course_index search {query}
* @param array $params
* @throws \XSException
*/
public function searchAction($params)
{
@ -31,7 +29,9 @@ class CourseIndexTask extends Task
exit('please special a query word' . PHP_EOL);
}
$result = $this->searchCourses($query);
$handler = new CourseSearcher();
$result = $handler->search($query);
var_export($result);
}
@ -42,24 +42,6 @@ class CourseIndexTask extends Task
* @command: php console.php course_index clean
*/
public function cleanAction()
{
$this->cleanCourseIndex();
}
/**
* 重建索引
*
* @command: php console.php course_index rebuild
*/
public function rebuildAction()
{
$this->rebuildCourseIndex();
}
/**
* 清空索引
*/
protected function cleanCourseIndex()
{
$handler = new CourseSearcher();
@ -74,8 +56,10 @@ class CourseIndexTask extends Task
/**
* 重建索引
*
* @command: php console.php course_index rebuild
*/
protected function rebuildCourseIndex()
public function rebuildAction()
{
$courses = $this->findCourses();
@ -83,7 +67,7 @@ class CourseIndexTask extends Task
$handler = new CourseSearcher();
$documenter = new CourseDocument();
$doc = new CourseDocument();
$index = $handler->getXS()->getIndex();
@ -92,7 +76,7 @@ class CourseIndexTask extends Task
$index->beginRebuild();
foreach ($courses as $course) {
$document = $documenter->setDocument($course);
$document = $doc->setDocument($course);
$index->add($document);
}
@ -102,17 +86,39 @@ class CourseIndexTask extends Task
}
/**
* 搜索课程
* 刷新索引缓存
*
* @param string $query
* @return array
* @throws \XSException
* @command: php console.php course_index flush_index
*/
protected function searchCourses($query)
public function flushIndexAction()
{
$handler = new CourseSearcher();
return $handler->search($query);
$index = $handler->getXS()->getIndex();
echo '------ start flush course index ------' . PHP_EOL;
$index->flushIndex();
echo '------ end flush course index ------' . PHP_EOL;
}
/**
* 刷新搜索日志
*
* @command: php console.php course_index flush_logging
*/
public function flushLoggingAction()
{
$handler = new CourseSearcher();
$index = $handler->getXS()->getIndex();
echo '------ start flush course logging ------' . PHP_EOL;
$index->flushLogging();
echo '------ end flush course logging ------' . PHP_EOL;
}
/**
@ -124,7 +130,7 @@ class CourseIndexTask extends Task
{
return CourseModel::query()
->where('published = 1')
->where('deleted = 0')
->andWhere('deleted = 0')
->execute();
}

View File

@ -58,8 +58,6 @@ class DeliverTask extends Task
case OrderModel::ITEM_VIP:
$this->handleVipOrder($order);
break;
default:
$this->noMatchedHandler($order);
}
$order->status = OrderModel::STATUS_FINISHED;
@ -155,11 +153,6 @@ class DeliverTask extends Task
$this->closePendingOrders($user->id);
}
protected function noMatchedHandler(OrderModel $order)
{
throw new \RuntimeException("No Matched Handler For Order: {$order->id}");
}
protected function closePendingOrders($userId)
{
$orders = $this->findUserPendingOrders($userId);

View File

@ -10,7 +10,7 @@ namespace App\Console\Tasks;
use App\Http\Admin\Services\Setting as SettingService;
use App\Library\Utils\Password as PasswordUtil;
use App\Models\ChapterVod as ChapterVodModel;
use App\Services\Utils\IndexCourseCache as IndexCourseCacheUtil;
use App\Services\Utils\IndexPageCache as IndexPageCacheUtil;
use App\Validators\Account as AccountValidator;
class MaintainTask extends Task
@ -26,7 +26,7 @@ class MaintainTask extends Task
{
$section = $params[0] ?? null;
$util = new IndexCourseCacheUtil();
$util = new IndexPageCacheUtil();
$util->rebuild($section);
@ -64,34 +64,6 @@ class MaintainTask extends Task
echo '------ reset password success ------' . PHP_EOL;
}
/**
* 关闭验证码
*
* @command: php console.php maintain disable_captcha
*/
public function disableCaptchaAction()
{
$service = new SettingService();
$service->updateSettings('captcha', ['enabled' => 0]);
echo '------ disable captcha success ------' . PHP_EOL;
}
/**
* 启用验证码
*
* @command: php console.php maintain enable_captcha
*/
public function enableCaptchaAction()
{
$service = new SettingService();
$service->updateSettings('captcha', ['enabled' => 1]);
echo '------ enable captcha success ------' . PHP_EOL;
}
/**
* 关闭站点
*

View File

@ -20,8 +20,6 @@ class QuestionIndexTask extends Task
* 搜索测试
*
* @command: php console.php question_index search {query}
* @param array $params
* @throws \XSException
*/
public function searchAction($params)
{
@ -31,7 +29,9 @@ class QuestionIndexTask extends Task
exit('please special a query word' . PHP_EOL);
}
$result = $this->searchQuestions($query);
$handler = new QuestionSearcher();
$result = $handler->search($query);
var_export($result);
}
@ -42,24 +42,6 @@ class QuestionIndexTask extends Task
* @command: php console.php question_index clean
*/
public function cleanAction()
{
$this->cleanQuestionIndex();
}
/**
* 重建索引
*
* @command: php console.php question_index rebuild
*/
public function rebuildAction()
{
$this->rebuildQuestionIndex();
}
/**
* 清空索引
*/
protected function cleanQuestionIndex()
{
$handler = new QuestionSearcher();
@ -74,8 +56,10 @@ class QuestionIndexTask extends Task
/**
* 重建索引
*
* @command: php console.php question_index rebuild
*/
protected function rebuildQuestionIndex()
public function rebuildAction()
{
$questions = $this->findQuestions();
@ -83,7 +67,7 @@ class QuestionIndexTask extends Task
$handler = new QuestionSearcher();
$documenter = new QuestionDocument();
$doc = new QuestionDocument();
$index = $handler->getXS()->getIndex();
@ -92,7 +76,7 @@ class QuestionIndexTask extends Task
$index->beginRebuild();
foreach ($questions as $question) {
$document = $documenter->setDocument($question);
$document = $doc->setDocument($question);
$index->add($document);
}
@ -102,17 +86,39 @@ class QuestionIndexTask extends Task
}
/**
* 搜索文章
* 刷新索引缓存
*
* @param string $query
* @return array
* @throws \XSException
* @command: php console.php question_index flush_index
*/
protected function searchQuestions($query)
public function flushIndexAction()
{
$handler = new QuestionSearcher();
return $handler->search($query);
$index = $handler->getXS()->getIndex();
echo '------ start flush question index ------' . PHP_EOL;
$index->flushIndex();
echo '------ end flush question index ------' . PHP_EOL;
}
/**
* 刷新搜索日志
*
* @command: php console.php question_index flush_logging
*/
public function flushLoggingAction()
{
$handler = new QuestionSearcher();
$index = $handler->getXS()->getIndex();
echo '------ start flush question logging ------' . PHP_EOL;
$index->flushLogging();
echo '------ end flush question logging ------' . PHP_EOL;
}
/**

View File

@ -151,9 +151,6 @@ class RefundTask extends Task
case OrderModel::ITEM_VIP:
$this->handleVipOrderRefund($order);
break;
case OrderModel::ITEM_REWARD:
$this->handleRewardOrderRefund($order);
break;
case OrderModel::ITEM_TEST:
$this->handleTestOrderRefund($order);
break;
@ -230,16 +227,6 @@ class RefundTask extends Task
}
}
/**
* 处理赞赏订单退款
*
* @param OrderModel $order
*/
protected function handleRewardOrderRefund(OrderModel $order)
{
}
/**
* 处理测试订单退款
*

View File

@ -177,13 +177,13 @@ class ServerMonitorTask extends Task
$searcher = new CourseSearcher();
$user = $searcher->search('id:1');
$course = $searcher->search('id:1');
$benchmark->stop();
$elapsedTime = $benchmark->getElapsedTime();
if (empty($user)) {
if (empty($course)) {
return "xunsearch搜索失败";
}
@ -242,4 +242,4 @@ class ServerMonitorTask extends Task
return $coreCount * $processorCount;
}
}
}

View File

@ -37,7 +37,7 @@ class SitemapTask extends Task
$this->sitemap = new Sitemap();
$filename = tmp_path('sitemap.xml');
$filename = public_path('sitemap.xml');
echo '------ start sitemap task ------' . PHP_EOL;

View File

@ -13,12 +13,12 @@ use GuzzleHttp\Client;
class SyncAppInfoTask extends Task
{
const API_BASE_URL = 'https://www.koogua.com/api';
public function mainAction()
{
echo '------ start sync app info ------' . PHP_EOL;
$url = 'https://www.koogua.com/api/instance/collect';
$site = $this->getSettings('site');
$serverHost = parse_url($site['url'], PHP_URL_HOST);
@ -38,6 +38,8 @@ class SyncAppInfoTask extends Task
$client = new Client();
$url = sprintf('%s/instance/collect', self::API_BASE_URL);
$client->request('POST', $url, ['form_params' => $params]);
echo '------ end sync app info ------' . PHP_EOL;

View File

@ -30,7 +30,7 @@ class TeacherLiveNoticeTask extends Task
$keyName = $this->getCacheKeyName();
foreach ($lives as $live) {
$redis->sAdd($keyName, $live->chapter_id);
$redis->sAdd($keyName, $live->id);
}
$redis->expire($keyName, 86400);

View File

@ -0,0 +1,41 @@
<?php
/**
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.koogua.com
*/
namespace App\Http\Admin\Controllers;
use App\Traits\Response as ResponseTrait;
/**
* @RoutePrefix("/admin/koogua")
*/
class KooguaController extends \Phalcon\Mvc\Controller
{
use ResponseTrait;
/**
* @Get("/wiki", name="admin.koogua.wiki")
*/
public function wikiAction()
{
$url = 'https://www.koogua.com/page/wiki';
$this->response->redirect($url, true);
}
/**
* @Get("/community", name="admin.koogua.community")
*/
public function communityAction()
{
$url = 'https://www.koogua.com/question/list';
return $this->response->redirect($url, true);
}
}

View File

@ -7,6 +7,7 @@
namespace App\Http\Admin\Controllers;
use App\Http\Admin\Services\Upload as UploadService;
use App\Services\MyStorage as StorageService;
use App\Services\Vod as VodService;
use App\Validators\Validator as AppValidator;
@ -40,8 +41,9 @@ class UploadController extends Controller
}
$data = [
'id' => $file->id,
'name' => $file->name,
'url' => $service->getImageUrl($file->path),
'title' => $file->name,
];
return $this->jsonSuccess(['data' => $data]);
@ -61,29 +63,9 @@ class UploadController extends Controller
}
$data = [
'id' => $file->id,
'name' => $file->name,
'url' => $service->getImageUrl($file->path),
'title' => $file->name,
];
return $this->jsonSuccess(['data' => $data]);
}
/**
* @Post("/avatar/img", name="admin.upload.avatar_img")
*/
public function uploadAvatarImageAction()
{
$service = new StorageService();
$file = $service->uploadAvatarImage();
if (!$file) {
return $this->jsonError(['msg' => '上传文件失败']);
}
$data = [
'url' => $service->getImageUrl($file->path),
'title' => $file->name,
];
return $this->jsonSuccess(['data' => $data]);
@ -100,7 +82,7 @@ class UploadController extends Controller
if (!$file) {
return $this->jsonError([
'message' => '上传图片失败',
'message' => '上传文件失败',
'error' => 1,
]);
}
@ -116,20 +98,25 @@ class UploadController extends Controller
*/
public function uploadDefaultImageAction()
{
$service = new StorageService();
$service = new UploadService();
$items = [];
$items['category_icon'] = $service->uploadDefaultCategoryIcon();
$items['user_avatar'] = $service->uploadDefaultUserAvatar();
$items['article_cover'] = $service->uploadDefaultArticleCover();
$items['course_cover'] = $service->uploadDefaultCourseCover();
$items['package_cover'] = $service->uploadDefaultPackageCover();
$items['topic_cover'] = $service->uploadDefaultTopicCover();
$items['slide_cover'] = $service->uploadDefaultSlideCover();
$items['gift_cover'] = $service->uploadDefaultGiftCover();
$items['vip_cover'] = $service->uploadDefaultVipCover();
$items['category_icon'] = $service->uploadDefaultCategoryIcon();
foreach ($items as $item) {
if (!$item) return $this->jsonError(['msg' => '上传文件失败']);
foreach ($items as $key => $item) {
$msg = sprintf('上传文件失败: %s', $key);
if (!$item) {
return $this->jsonError(['msg' => $msg]);
}
}
return $this->jsonSuccess(['msg' => '上传文件成功']);

View File

@ -9,10 +9,8 @@ namespace App\Http\Admin\Services;
use App\Builders\ArticleList as ArticleListBuilder;
use App\Builders\ReportList as ReportListBuilder;
use App\Caches\Article as ArticleCache;
use App\Http\Admin\Services\Traits\AccountSearchTrait;
use App\Library\Paginator\Query as PagerQuery;
use App\Library\Utils\Word as WordUtil;
use App\Models\Article as ArticleModel;
use App\Models\Category as CategoryModel;
use App\Models\Reason as ReasonModel;
@ -74,10 +72,6 @@ class Article extends Service
$params = $this->handleAccountSearchParams($params);
if (!empty($params['xm_tag_ids'])) {
$params['tag_id'] = explode(',', $params['xm_tag_ids']);
}
$params['deleted'] = $params['deleted'] ?? 0;
$sort = $pagerQuery->getSort();
@ -141,7 +135,6 @@ class Article extends Service
$article->create();
$this->saveDynamicAttrs($article);
$this->rebuildArticleCache($article);
$this->rebuildArticleIndex($article);
$this->recountUserArticles($user);
@ -199,9 +192,8 @@ class Article extends Service
$data['published'] = $validator->checkPublishStatus($post['published']);
}
if (isset($post['category_id']) && !empty($post['category_id'])) {
$category = $validator->checkCategory($post['category_id']);
$data['category_id'] = $category->id;
if (isset($post['category_id'])) {
$data['category_id'] = $validator->checkCategoryId($post['category_id']);
}
if (isset($post['xm_tag_ids'])) {
@ -213,7 +205,6 @@ class Article extends Service
$owner = $this->findUser($article->owner_id);
$this->saveDynamicAttrs($article);
$this->rebuildArticleCache($article);
$this->rebuildArticleIndex($article);
$this->recountUserArticles($owner);
@ -233,7 +224,6 @@ class Article extends Service
$owner = $this->findUser($article->owner_id);
$this->saveDynamicAttrs($article);
$this->rebuildArticleCache($article);
$this->rebuildArticleIndex($article);
$this->recountUserArticles($owner);
@ -253,7 +243,6 @@ class Article extends Service
$owner = $this->findUser($article->owner_id);
$this->saveDynamicAttrs($article);
$this->rebuildArticleCache($article);
$this->rebuildArticleIndex($article);
$this->recountUserArticles($owner);
@ -292,7 +281,6 @@ class Article extends Service
$owner = $this->findUser($article->owner_id);
$this->rebuildArticleCache($article);
$this->rebuildArticleIndex($article);
$this->recountUserArticles($owner);
@ -328,7 +316,6 @@ class Article extends Service
$owner = $this->findUser($article->owner_id);
$this->rebuildArticleCache($article);
$this->rebuildArticleIndex($article);
$this->recountUserArticles($owner);
}
@ -367,7 +354,6 @@ class Article extends Service
$owner = $this->findUser($article->owner_id);
$this->recountUserArticles($owner);
$this->rebuildArticleCache($article);
$this->rebuildArticleIndex($article);
}
}
@ -394,7 +380,6 @@ class Article extends Service
$owner = $this->findUser($article->owner_id);
$this->recountUserArticles($owner);
$this->rebuildArticleCache($article);
$this->rebuildArticleIndex($article);
}
}
@ -413,13 +398,6 @@ class Article extends Service
return $userRepo->findById($id);
}
protected function rebuildArticleCache(ArticleModel $article)
{
$cache = new ArticleCache();
$cache->rebuild($article->id);
}
protected function rebuildArticleIndex(ArticleModel $article)
{
$sync = new ArticleIndexSync();

View File

@ -37,10 +37,6 @@ class Course extends Service
$params = $pagerQuery->getParams();
if (!empty($params['xm_tag_ids'])) {
$params['tag_id'] = explode(',', $params['xm_tag_ids']);
}
$params['deleted'] = $params['deleted'] ?? 0;
$sort = $pagerQuery->getSort();
@ -163,16 +159,17 @@ class Course extends Service
if (isset($post['published'])) {
$data['published'] = $validator->checkPublishStatus($post['published']);
if ($post['published'] == 1) {
$validator->checkPublishAbility($course);
}
}
if (isset($post['category_id']) && !empty($post['category_id'])) {
$category = $validator->checkCategory($post['category_id']);
$data['category_id'] = $category->id;
if (isset($post['category_id'])) {
$data['category_id'] = $validator->checkCategoryId($post['category_id']);
}
if (isset($post['teacher_id']) && !empty($post['teacher_id'])) {
$teacher = $validator->checkTeacher($post['teacher_id']);
$data['teacher_id'] = $teacher->id;
if (isset($post['teacher_id'])) {
$data['teacher_id'] = $validator->checkTeacherId($post['teacher_id']);
}
if (isset($post['xm_tag_ids'])) {

View File

@ -40,7 +40,7 @@ class CourseUser extends Service
$sourceType = CourseUserModel::SOURCE_MANUAL;
return $this->assignUserCourse($course, $user, $expiryTime, $sourceType);
$this->assignUserCourse($course, $user, $expiryTime, $sourceType);
}
public function getUsers($id)

View File

@ -8,8 +8,6 @@
namespace App\Http\Admin\Services;
use App\Builders\HelpList as HelpListBuilder;
use App\Caches\Help as HelpCache;
use App\Caches\HelpList as HelpListCache;
use App\Models\Category as CategoryModel;
use App\Models\Help as HelpModel;
use App\Repos\Category as CategoryRepo;
@ -65,20 +63,15 @@ class Help extends Service
$data = [];
$category = $validator->checkCategory($post['category_id']);
$data['title'] = $validator->checkTitle($post['title']);
$data['content'] = $validator->checkContent($post['content']);
$data['priority'] = $validator->checkPriority($post['priority']);
$data['category_id'] = $category->id;
$data['category_id'] = $validator->checkCategoryId($post['category_id']);
$help = new HelpModel();
$help->create($data);
$this->rebuildHelpCache($help);
$this->rebuildHelpListCache();
return $help;
}
@ -93,8 +86,7 @@ class Help extends Service
$data = [];
if (isset($post['category_id'])) {
$category = $validator->checkCategory($post['category_id']);
$data['category_id'] = $category->id;
$data['category_id'] = $validator->checkCategoryId($post['category_id']);
}
if (isset($post['title'])) {
@ -119,9 +111,6 @@ class Help extends Service
$help->update($data);
$this->rebuildHelpCache($help);
$this->rebuildHelpListCache();
return $help;
}
@ -133,9 +122,6 @@ class Help extends Service
$help->update();
$this->rebuildHelpCache($help);
$this->rebuildHelpListCache();
return $help;
}
@ -147,9 +133,6 @@ class Help extends Service
$help->update();
$this->rebuildHelpCache($help);
$this->rebuildHelpListCache();
return $help;
}
@ -160,20 +143,6 @@ class Help extends Service
return $validator->checkHelp($id);
}
protected function rebuildHelpCache(HelpModel $help)
{
$cache = new HelpCache();
$cache->rebuild($help->id);
}
protected function rebuildHelpListCache()
{
$cache = new HelpListCache();
$cache->rebuild();
}
/**
* @param Resultset $helps
* @return array|object

View File

@ -85,6 +85,7 @@ class Nav extends Service
if ($parent) {
$nav->path = $parent->path . $nav->id . ',';
$nav->level = $parent->level + 1;
$nav->position = $parent->position;
} else {
$nav->path = ',' . $nav->id . ',';
$nav->level = 1;
@ -140,6 +141,11 @@ class Nav extends Service
}
}
if ($nav->parent_id > 0) {
$parent = $this->findOrFail($nav->parent_id);
$data['position'] = $parent->position;
}
$nav->update($data);
$this->updateNavStats($nav);

View File

@ -59,9 +59,8 @@ class Package extends Service
$result = [];
foreach ($items as $item) {
$price = $item->market_price > 0 ? sprintf("¥%0.2f", $item->market_price) : '免费';
$result[] = [
'name' => sprintf('%s - %s¥%0.2f', $item->id, $item->title, $price),
'name' => sprintf('%s - %s¥%0.2f', $item->id, $item->title, $item->market_price),
'value' => $item->id,
'selected' => in_array($item->id, $courseIds),
];
@ -152,7 +151,7 @@ class Package extends Service
$package->update($data);
$this->handlePackagedCourses($package->id);
$this->updatePackageCourseCount($package->id);
$this->recountPackageCourses($package->id);
$this->rebuildPackageCache($package->id);
return $package;
@ -217,7 +216,7 @@ class Package extends Service
'course_id' => $courseId,
'package_id' => $package->id,
]);
$this->updateCoursePackageCount($courseId);
$this->recountCoursePackages($courseId);
$this->rebuildCoursePackageCache($courseId);
}
}
@ -229,7 +228,7 @@ class Package extends Service
foreach ($deletedCourseIds as $courseId) {
$coursePackage = $coursePackageRepo->findCoursePackage($courseId, $package->id);
$coursePackage->delete();
$this->updateCoursePackageCount($courseId);
$this->recountCoursePackages($courseId);
$this->rebuildCoursePackageCache($courseId);
}
}
@ -249,7 +248,7 @@ class Package extends Service
}
}
protected function updatePackageCourseCount($packageId)
protected function recountPackageCourses($packageId)
{
$packageRepo = new PackageRepo();
@ -262,7 +261,7 @@ class Package extends Service
$package->update();
}
protected function updateCoursePackageCount($courseId)
protected function recountCoursePackages($courseId)
{
$courseRepo = new CourseRepo();
@ -293,15 +292,4 @@ class Package extends Service
$cache->rebuild($courseId);
}
protected function recountCoursePackages($courseId)
{
$courseRepo = new CourseRepo();
$course = $courseRepo->findById($courseId);
$course->package_count = $courseRepo->countPackages($courseId);
$course->update();
}
}

View File

@ -7,7 +7,6 @@
namespace App\Http\Admin\Services;
use App\Caches\Page as PageCache;
use App\Library\Paginator\Query as PagerQuery;
use App\Models\Page as PageModel;
use App\Repos\Page as PageRepo;
@ -53,8 +52,6 @@ class Page extends Service
$page->create($data);
$this->rebuildPageCache($page);
return $page;
}
@ -96,8 +93,6 @@ class Page extends Service
$page->update($data);
$this->rebuildPageCache($page);
return $page;
}
@ -109,8 +104,6 @@ class Page extends Service
$page->update();
$this->rebuildPageCache($page);
return $page;
}
@ -122,8 +115,6 @@ class Page extends Service
$page->update();
$this->rebuildPageCache($page);
return $page;
}
@ -134,11 +125,4 @@ class Page extends Service
return $validator->checkPage($id);
}
protected function rebuildPageCache(PageModel $page)
{
$cache = new PageCache();
$cache->rebuild($page->id);
}
}

View File

@ -7,7 +7,6 @@
namespace App\Http\Admin\Services;
use App\Caches\PointGift as PointGiftCache;
use App\Library\Paginator\Query as PagerQuery;
use App\Models\PointGift as PointGiftModel;
use App\Repos\Course as CourseRepo;
@ -116,8 +115,6 @@ class PointGift extends Service
break;
}
$this->rebuildPointGiftCache($gift);
return $gift;
}
@ -165,8 +162,6 @@ class PointGift extends Service
$gift->update($data);
$this->rebuildPointGiftCache($gift);
return $gift;
}
@ -178,8 +173,6 @@ class PointGift extends Service
$gift->update();
$this->rebuildPointGiftCache($gift);
return $gift;
}
@ -191,8 +184,6 @@ class PointGift extends Service
$gift->update();
$this->rebuildPointGiftCache($gift);
return $gift;
}
@ -203,13 +194,6 @@ class PointGift extends Service
return $validator->checkPointGift($id);
}
protected function rebuildPointGiftCache(PointGiftModel $gift)
{
$cache = new PointGiftCache();
$cache->rebuild($gift->id);
}
protected function createCoursePointGift($post)
{
$validator = new PointGiftValidator();

View File

@ -9,7 +9,6 @@ namespace App\Http\Admin\Services;
use App\Builders\QuestionList as QuestionListBuilder;
use App\Builders\ReportList as ReportListBuilder;
use App\Caches\Question as QuestionCache;
use App\Http\Admin\Services\Traits\AccountSearchTrait;
use App\Library\Paginator\Query as PagerQuery;
use App\Models\Category as CategoryModel;
@ -68,10 +67,6 @@ class Question extends Service
$params = $this->handleAccountSearchParams($params);
if (!empty($params['xm_tag_ids'])) {
$params['tag_id'] = explode(',', $params['xm_tag_ids']);
}
$params['deleted'] = $params['deleted'] ?? 0;
$sort = $pagerQuery->getSort();
@ -135,7 +130,6 @@ class Question extends Service
$question->create();
$this->saveDynamicAttrs($question);
$this->rebuildQuestionCache($question);
$this->rebuildQuestionIndex($question);
$this->recountUserQuestions($user);
@ -186,9 +180,8 @@ class Question extends Service
$data['published'] = $validator->checkPublishStatus($post['published']);
}
if (isset($post['category_id']) && !empty($post['category_id'])) {
$category = $validator->checkCategory($post['category_id']);
$data['category_id'] = $category->id;
if (isset($post['category_id'])) {
$data['category_id'] = $validator->checkCategoryId($post['category_id']);
}
if (isset($post['xm_tag_ids'])) {
@ -200,7 +193,6 @@ class Question extends Service
$owner = $this->findUser($question->owner_id);
$this->saveDynamicAttrs($question);
$this->rebuildQuestionCache($question);
$this->rebuildQuestionIndex($question);
$this->recountUserQuestions($owner);
@ -224,7 +216,6 @@ class Question extends Service
$owner = $this->findUser($question->owner_id);
$this->saveDynamicAttrs($question);
$this->rebuildQuestionCache($question);
$this->rebuildQuestionIndex($question);
$this->recountUserQuestions($owner);
@ -243,7 +234,6 @@ class Question extends Service
$owner = $this->findUser($question->owner_id);
$this->rebuildQuestionCache($question);
$this->rebuildQuestionIndex($question);
$this->recountUserQuestions($owner);
@ -283,7 +273,6 @@ class Question extends Service
$owner = $this->findUser($question->owner_id);
$this->recountUserQuestions($owner);
$this->rebuildQuestionCache($question);
$this->rebuildQuestionIndex($question);
return $question;
@ -318,7 +307,6 @@ class Question extends Service
$owner = $this->findUser($question->owner_id);
$this->rebuildQuestionCache($question);
$this->rebuildQuestionIndex($question);
$this->recountUserQuestions($owner);
}
@ -357,7 +345,6 @@ class Question extends Service
$owner = $this->findUser($question->owner_id);
$this->recountUserQuestions($owner);
$this->rebuildQuestionCache($question);
$this->rebuildQuestionIndex($question);
}
}
@ -384,7 +371,6 @@ class Question extends Service
$owner = $this->findUser($question->owner_id);
$this->recountUserQuestions($owner);
$this->rebuildQuestionCache($question);
$this->rebuildQuestionIndex($question);
}
}
@ -403,13 +389,6 @@ class Question extends Service
return $userRepo->findById($id);
}
protected function rebuildQuestionCache(QuestionModel $question)
{
$cache = new QuestionCache();
$cache->rebuild($question->id);
}
protected function rebuildQuestionIndex(QuestionModel $question)
{
$sync = new QuestionIndexSync();

View File

@ -45,7 +45,7 @@ class Resource extends Service
$this->recountCourseResources($course);
return $upload;
return $resource;
}
public function updateResource($id)
@ -67,6 +67,8 @@ class Resource extends Service
$upload->update($data);
$resource->update();
return $resource;
}
public function deleteResource($id)
@ -80,6 +82,8 @@ class Resource extends Service
$resource->delete();
$this->recountCourseResources($course);
return $resource;
}
protected function findOrFail($id)

View File

@ -52,8 +52,8 @@ class Setting extends Service
{
$alipay = $this->getSettings('pay.alipay');
$alipay['return_url'] = $alipay['return_url'] ?: kg_full_url(['for' => 'home.alipay_callback']);
$alipay['notify_url'] = $alipay['notify_url'] ?: kg_full_url(['for' => 'home.alipay_notify']);
$alipay['return_url'] = $alipay['return_url'] ?: kg_full_url(['for' => 'home.alipay.callback']);
$alipay['notify_url'] = $alipay['notify_url'] ?: kg_full_url(['for' => 'home.alipay.notify']);
return $alipay;
}
@ -62,8 +62,8 @@ class Setting extends Service
{
$wxpay = $this->getSettings('pay.wxpay');
$wxpay['return_url'] = $wxpay['return_url'] ?: kg_full_url(['for' => 'home.wxpay_callback']);
$wxpay['notify_url'] = $wxpay['notify_url'] ?: kg_full_url(['for' => 'home.wxpay_notify']);
$wxpay['return_url'] = $wxpay['return_url'] ?: kg_full_url(['for' => 'home.wxpay.callback']);
$wxpay['notify_url'] = $wxpay['notify_url'] ?: kg_full_url(['for' => 'home.wxpay.notify']);
return $wxpay;
}
@ -109,11 +109,11 @@ class Setting extends Service
$result = $this->getSettings($section);
if ($section == 'live.notify') {
$result['stream_begin_url'] = $result['stream_begin_url'] ?: kg_full_url(['for' => 'home.live_notify'], ['action' => 'streamBegin']);
$result['stream_end_url'] = $result['stream_end_url'] ?: kg_full_url(['for' => 'home.live_notify'], ['action' => 'streamEnd']);
$result['record_url'] = $result['record_url'] ?: kg_full_url(['for' => 'home.live_notify'], ['action' => 'record']);
$result['snapshot_url'] = $result['snapshot_url'] ?: kg_full_url(['for' => 'home.live_notify'], ['action' => 'snapshot']);
$result['porn_url'] = $result['porn_url'] ?: kg_full_url(['for' => 'home.live_notify'], ['action' => 'porn']);
$result['stream_begin_url'] = $result['stream_begin_url'] ?: kg_full_url(['for' => 'home.live.notify'], ['action' => 'streamBegin']);
$result['stream_end_url'] = $result['stream_end_url'] ?: kg_full_url(['for' => 'home.live.notify'], ['action' => 'streamEnd']);
$result['record_url'] = $result['record_url'] ?: kg_full_url(['for' => 'home.live.notify'], ['action' => 'record']);
$result['snapshot_url'] = $result['snapshot_url'] ?: kg_full_url(['for' => 'home.live.notify'], ['action' => 'snapshot']);
$result['porn_url'] = $result['porn_url'] ?: kg_full_url(['for' => 'home.live.notify'], ['action' => 'porn']);
}
return $result;

View File

@ -23,11 +23,11 @@ class Stat extends Service
return [
[
'title' => "{$year}-{$month}",
'title' => sprintf('%02d-%02d', $year, $month),
'sales' => $this->handleHotSales($type, $year, $month),
],
[
'title' => "{$prev['year']}-{$prev['month']}",
'title' => sprintf('%02d-%02d', $prev['year'], $prev['month']),
'sales' => $this->handleHotSales($type, $prev['year'], $prev['month']),
],
];
@ -42,12 +42,13 @@ class Stat extends Service
$currSales = $this->handleSales($year, $month);
$prevSales = $this->handleSales($prev['year'], $prev['month']);
$currMonth = sprintf('%02d-%02d', $year, $month);
$prevMonth = sprintf('%02d-%02d', $prev['year'], $prev['month']);
$items = [];
foreach (range(1, 31) as $day) {
$date = sprintf('%02d', $day);
$prevMonth = "{$prev['year']}-{$prev['month']}";
$currMonth = "{$year}-{$month}";
$items[] = [
'date' => $date,
$currMonth => $currSales[$date] ?? 0,
@ -67,12 +68,13 @@ class Stat extends Service
$currRefunds = $this->handleRefunds($year, $month);
$prevRefunds = $this->handleRefunds($prev['year'], $prev['month']);
$currMonth = sprintf('%02d-%02d', $year, $month);
$prevMonth = sprintf('%02d-%02d', $prev['year'], $prev['month']);
$items = [];
foreach (range(1, 31) as $day) {
$date = sprintf('%02d', $day);
$prevMonth = "{$prev['year']}-{$prev['month']}";
$currMonth = "{$year}-{$month}";
$items[] = [
'date' => $date,
$currMonth => $currRefunds[$date] ?? 0,
@ -92,12 +94,13 @@ class Stat extends Service
$currUsers = $this->handleRegisteredUsers($year, $month);
$prevUsers = $this->handleRegisteredUsers($prev['year'], $prev['month']);
$currMonth = sprintf('%02d-%02d', $year, $month);
$prevMonth = sprintf('%02d-%02d', $prev['year'], $prev['month']);
$items = [];
foreach (range(1, 31) as $day) {
$date = sprintf('%02d', $day);
$prevMonth = "{$prev['year']}-{$prev['month']}";
$currMonth = "{$year}-{$month}";
$items[] = [
'date' => $date,
$currMonth => $currUsers[$date] ?? 0,
@ -117,12 +120,13 @@ class Stat extends Service
$currUsers = $this->handleOnlineUsers($year, $month);
$prevUsers = $this->handleOnlineUsers($prev['year'], $prev['month']);
$currMonth = sprintf('%02d-%02d', $year, $month);
$prevMonth = sprintf('%02d-%02d', $prev['year'], $prev['month']);
$items = [];
foreach (range(1, 31) as $day) {
$date = sprintf('%02d', $day);
$prevMonth = "{$prev['year']}-{$prev['month']}";
$currMonth = "{$year}-{$month}";
$items[] = [
'date' => $date,
$currMonth => $currUsers[$date] ?? 0,
@ -154,7 +158,10 @@ class Stat extends Service
protected function isCurrMonth($year, $month)
{
return date('Y-m') == "{$year}-{$month}";
$yearOk = date('Y') == $year;
$monthOk = date('m') == $month;
return $yearOk && $monthOk;
}
protected function getLifetime()

View File

@ -15,31 +15,28 @@ trait AccountSearchTrait
protected function handleAccountSearchParams($params)
{
$key = null;
if (isset($params['user_id'])) {
$key = 'user_id';
} elseif (isset($params['owner_id'])) {
$key = 'owner_id';
}
if ($key == null) return $params;
$accountRepo = new AccountRepo();
/**
* 兼容用户编号|手机号码|邮箱地址查询
*/
if (!empty($params['user_id'])) {
if (CommonValidator::phone($params['user_id'])) {
$account = $accountRepo->findByPhone($params['user_id']);
$params['user_id'] = $account ? $account->id : -1000;
} elseif (CommonValidator::email($params['user_id'])) {
$account = $accountRepo->findByEmail($params['user_id']);
$params['user_id'] = $account ? $account->id : -1000;
}
}
/**
* 兼容用户编号|手机号码|邮箱地址查询
*/
if (!empty($params['owner_id'])) {
if (CommonValidator::phone($params['owner_id'])) {
$account = $accountRepo->findByPhone($params['owner_id']);
$params['owner_id'] = $account ? $account->id : -1000;
} elseif (CommonValidator::email($params['owner_id'])) {
$account = $accountRepo->findByEmail($params['owner_id']);
$params['owner_id'] = $account ? $account->id : -1000;
if (!empty($params[$key])) {
if (CommonValidator::phone($params[$key])) {
$account = $accountRepo->findByPhone($params[$key]);
$params[$key] = $account ? $account->id : -1000;
} elseif (CommonValidator::email($params[$key])) {
$account = $accountRepo->findByEmail($params[$key]);
$params[$key] = $account ? $account->id : -1000;
}
}

View File

@ -0,0 +1,153 @@
<?php
/**
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.koogua.com
*/
namespace App\Http\Admin\Services;
use App\Services\MyStorage;
class Upload extends Service
{
/**
* @var MyStorage
*/
protected $storage;
public function __construct()
{
$this->storage = new MyStorage();
}
/**
* 上传默认用户头像
*
* @return false|mixed|string
*/
public function uploadDefaultUserAvatar()
{
$filename = static_path('admin/img/default/user_avatar.png');
$key = '/img/default/user_avatar.png';
return $this->storage->putFile($key, $filename);
}
/**
* 上传默认课程封面
*
* @return false|mixed|string
*/
public function uploadDefaultCourseCover()
{
$filename = static_path('admin/img/default/course_cover.png');
$key = '/img/default/course_cover.png';
return $this->storage->putFile($key, $filename);
}
/**
* 上传默认套餐封面
*
* @return false|mixed|string
*/
public function uploadDefaultPackageCover()
{
$filename = static_path('admin/img/default/package_cover.png');
$key = '/img/default/package_cover.png';
return $this->storage->putFile($key, $filename);
}
/**
* 上传默认话题封面
*
* @return false|mixed|string
*/
public function uploadDefaultTopicCover()
{
$filename = static_path('admin/img/default/topic_cover.png');
$key = '/img/default/topic_cover.png';
return $this->storage->putFile($key, $filename);
}
/**
* 上传默认会员封面
*
* @return false|mixed|string
*/
public function uploadDefaultVipCover()
{
$filename = static_path('admin/img/default/vip_cover.png');
$key = '/img/default/vip_cover.png';
return $this->storage->putFile($key, $filename);
}
/**
* 上传默认专栏封面
*
* @return false|mixed|string
*/
public function uploadDefaultArticleCover()
{
$filename = static_path('admin/img/default/article_cover.png');
$key = '/img/default/article_cover.png';
return $this->storage->putFile($key, $filename);
}
/**
* 上传默认礼品封面
*
* @return false|mixed|string
*/
public function uploadDefaultGiftCover()
{
$filename = static_path('admin/img/default/gift_cover.png');
$key = '/img/default/gift_cover.png';
return $this->storage->putFile($key, $filename);
}
/**
* 上传默认轮播图片
*
* @return false|mixed|string
*/
public function uploadDefaultSlideCover()
{
$filename = static_path('admin/img/default/slide_cover.png');
$key = '/img/default/slide_cover.png';
return $this->storage->putFile($key, $filename);
}
/**
* 上传默认分类图标
*
* @return false|mixed|string
*/
public function uploadDefaultCategoryIcon()
{
$filename = static_path('admin/img/default/category_icon.png');
$key = '/img/default/category_icon.png';
return $this->storage->putFile($key, $filename);
}
}

View File

@ -142,7 +142,7 @@ class User extends Service
$this->db->commit();
if ($adminRole > 0) {
$this->updateAdminUserCount($adminRole);
$this->recountRoleUsers($adminRole);
}
$this->rebuildUserCache($user);
@ -204,6 +204,10 @@ class User extends Service
$data['vip'] = $validator->checkVipStatus($post['vip']);
}
if (isset($post['locked'])) {
$data['locked'] = $validator->checkLockStatus($post['locked']);
}
if (!empty($post['vip_expiry_time'])) {
$data['vip_expiry_time'] = $validator->checkVipExpiryTime($post['vip_expiry_time']);
if ($data['vip_expiry_time'] < time()) {
@ -211,10 +215,6 @@ class User extends Service
}
}
if (isset($post['locked'])) {
$data['locked'] = $validator->checkLockStatus($post['locked']);
}
if (!empty($post['lock_expiry_time'])) {
$data['lock_expiry_time'] = $validator->checkLockExpiryTime($post['lock_expiry_time']);
if ($data['lock_expiry_time'] < time()) {
@ -231,11 +231,11 @@ class User extends Service
}
if ($oldAdminRole > 0) {
$this->updateAdminUserCount($oldAdminRole);
$this->recountRoleUsers($oldAdminRole);
}
if ($user->admin_role > 0) {
$this->updateAdminUserCount($user->admin_role);
$this->recountRoleUsers($user->admin_role);
}
$this->rebuildUserCache($user);
@ -347,7 +347,7 @@ class User extends Service
$apiAuth->logoutClients($user->id);
}
protected function updateAdminUserCount($roleId)
protected function recountRoleUsers($roleId)
{
$roleRepo = new RoleRepo();

View File

@ -29,7 +29,6 @@
{% block include_js %}
{{ js_include('lib/kindeditor/kindeditor.min.js') }}
{{ js_include('lib/kindeditor/lang/zh-CN.js') }}
{{ js_include('admin/js/content.editor.js') }}
{% endblock %}

View File

@ -39,7 +39,6 @@
{% block include_js %}
{{ js_include('lib/kindeditor/kindeditor.min.js') }}
{{ js_include('lib/kindeditor/lang/zh-CN.js') }}
{{ js_include('admin/js/content.editor.js') }}
{% endblock %}

View File

@ -14,7 +14,7 @@
<span><a href="{{ owner_url }}" target="_blank">{{ answer.owner.name }}</a></span>
<span>{{ date('Y-m-d H:i:s',answer.create_time) }}</span>
</div>
<div class="content ke-content">{{ answer.content }}</div>
<div class="content ke-content kg-zoom">{{ answer.content }}</div>
</div>
<fieldset class="layui-elem-field layui-field-title">

View File

@ -25,7 +25,7 @@
<span><a href="{{ owner_url }}" target="_blank">{{ answer.owner.name }}</a></span>
<span>{{ date('Y-m-d H:i:s',answer.create_time) }}</span>
</div>
<div class="content ke-content">{{ answer.content }}</div>
<div class="content ke-content kg-zoom">{{ answer.content }}</div>
</div>
</div>
<div class="layui-tab-item">

View File

@ -33,7 +33,6 @@
{{ js_include('lib/xm-select.js') }}
{{ js_include('lib/kindeditor/kindeditor.min.js') }}
{{ js_include('lib/kindeditor/lang/zh-CN.js') }}
{{ js_include('admin/js/content.editor.js') }}
{{ js_include('admin/js/cover.upload.js') }}
@ -48,9 +47,9 @@
xmSelect.render({
el: '#xm-tag-ids',
name: 'xm_tag_ids',
max: 3,
max: 5,
filterable: true,
filterMethod: function (val, item, index, prop) {
filterMethod: function (val, item) {
return item.name.toLowerCase().indexOf(val.toLowerCase()) !== -1;
},
data: {{ xm_tags|json_encode }}
@ -72,4 +71,4 @@
</script>
{% endblock %}
{% endblock %}

View File

@ -17,7 +17,7 @@
<span><a href="{{ owner_url }}" target="_blank">{{ article.owner.name }}</a></span>
<span>{{ date('Y-m-d H:i:s',article.create_time) }}</span>
</div>
<div class="content ke-content">{{ article.content }}</div>
<div class="content ke-content kg-zoom">{{ article.content }}</div>
{% if article.tags %}
<div class="tags">
{% for item in article.tags %}

View File

@ -26,7 +26,7 @@
<span><a href="{{ owner_url }}" target="_blank">{{ article.owner.name }}</a></span>
<span>{{ date('Y-m-d H:i:s',article.create_time) }}</span>
</div>
<div class="content ke-content">{{ article.content }}</div>
<div class="content ke-content kg-zoom">{{ article.content }}</div>
{% if article.tags %}
<div class="tags">
{% for item in article.tags %}

View File

@ -34,8 +34,8 @@
<th>用户IP</th>
<th>请求路由</th>
<th>请求路径</th>
<th>请求时间</th>
<th>请求内容</th>
<th>创建时间</th>
<th>操作</th>
</tr>
</thead>
<tbody>
@ -91,4 +91,4 @@
</script>
{% endblock %}
{% endblock %}

View File

@ -13,9 +13,9 @@
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">用户名称</label>
<label class="layui-form-label">用户IP</label>
<div class="layui-input-block">
<input class="layui-input" type="text" name="user_name" placeholder="用户名称精确匹配">
<input class="layui-input" type="text" name="user_ip" placeholder="用户IP精确匹配">
</div>
</div>
<div class="layui-form-item">
@ -31,7 +31,7 @@
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">请求时间</label>
<label class="layui-form-label">创建时间</label>
<div class="layui-input-inline">
<input class="layui-input time-range" type="text" name="start_time" autocomplete="off">
</div>
@ -70,4 +70,4 @@
</script>
{% endblock %}
{% endblock %}

View File

@ -9,7 +9,7 @@
<div class="kg-nav-left">
<span class="layui-breadcrumb">
{% if parent.id > 0 %}
<a class="kg-back" href="{{ back_url }}"><i class="layui-icon layui-icon-return"></i>返回</a>
<a href="{{ back_url }}"><i class="layui-icon layui-icon-return"></i>返回</a>
<a><cite>{{ parent.name }}</cite></a>
{% endif %}
<a><cite>分类管理</cite></a>
@ -87,4 +87,4 @@
</tbody>
</table>
{% endblock %}
{% endblock %}

View File

@ -48,7 +48,6 @@
{% if chapter.model == 3 %}
{{ js_include('lib/kindeditor/kindeditor.min.js') }}
{{ js_include('lib/kindeditor/lang/zh-CN.js') }}
{{ js_include('admin/js/content.editor.js') }}
{% elseif chapter.model == 1 %}
@ -89,7 +88,7 @@
layer.open({
type: 2,
title: '推流测试',
area: ['720px', '500px'],
area: ['720px', '540px'],
content: [url, 'no']
});
});
@ -98,4 +97,4 @@
</script>
{% endblock %}
{% endblock %}

View File

@ -43,7 +43,7 @@
<div class="kg-nav">
<div class="kg-nav-left">
<span class="layui-breadcrumb">
<a class="kg-back" href="{{ back_url }}"><i class="layui-icon layui-icon-return"></i>返回</a>
<a href="{{ back_url }}"><i class="layui-icon layui-icon-return"></i>返回</a>
<a><cite>{{ course.title }}</cite></a>
<a><cite>{{ chapter.title }}</cite></a>
<a><cite>课时管理</cite></a>
@ -126,4 +126,4 @@
</tbody>
</table>
{% endblock %}
{% endblock %}

View File

@ -15,7 +15,7 @@
<span><a href="{{ owner_url }}" target="_blank">{{ comment.owner.name }}</a></span>
<span>{{ date('Y-m-d H:i:s',comment.create_time) }}</span>
</div>
<div class="content ke-content">{{ comment.content }}</div>
<div class="content">{{ comment.content }}</div>
</div>
<fieldset class="layui-elem-field layui-field-title">

View File

@ -24,7 +24,7 @@
<span><a href="{{ owner_url }}" target="_blank">{{ comment.owner.name }}</a></span>
<span>{{ date('Y-m-d H:i:s',comment.create_time) }}</span>
</div>
<div class="content ke-content">{{ comment.content }}</div>
<div class="content">{{ comment.content }}</div>
</div>
</div>
<div class="layui-tab-item">

View File

@ -84,7 +84,7 @@
name: 'course_id',
filterable: true,
radio: true,
filterMethod: function (val, item, index, prop) {
filterMethod: function (val, item) {
return item.name.toLowerCase().indexOf(val.toLowerCase()) !== -1;
},
data: {{ xm_courses|json_encode }}
@ -102,4 +102,4 @@
</script>
{% endblock %}
{% endblock %}

View File

@ -9,7 +9,7 @@
<div class="kg-nav">
<div class="kg-nav-left">
<span class="layui-breadcrumb">
<a class="kg-back" href="{{ back_url }}"><i class="layui-icon layui-icon-return"></i>返回</a>
<a href="{{ back_url }}"><i class="layui-icon layui-icon-return"></i>返回</a>
<a><cite>{{ course.title }}</cite></a>
<a><cite>章节管理</cite></a>
</span>
@ -79,4 +79,4 @@
</tbody>
</table>
{% endblock %}
{% endblock %}

View File

@ -50,7 +50,6 @@
{{ js_include('lib/xm-select.js') }}
{{ js_include('lib/cos-js-sdk-v5.min.js') }}
{{ js_include('lib/kindeditor/kindeditor.min.js') }}
{{ js_include('lib/kindeditor/lang/zh-CN.js') }}
{{ js_include('admin/js/content.editor.js') }}
{{ js_include('admin/js/cover.upload.js') }}
{{ js_include('admin/js/course.resource.js') }}
@ -66,7 +65,7 @@
name: 'xm_tag_ids',
max: 5,
filterable: true,
filterMethod: function (val, item, index, prop) {
filterMethod: function (val, item) {
return item.name.toLowerCase().indexOf(val.toLowerCase()) !== -1;
},
data: {{ xm_tags|json_encode }}
@ -78,7 +77,7 @@
max: 10,
autoRow: true,
filterable: true,
filterMethod: function (val, item, index, prop) {
filterMethod: function (val, item) {
return item.name.toLowerCase().indexOf(val.toLowerCase()) !== -1;
},
data: {{ xm_courses|json_encode }}
@ -108,4 +107,4 @@
</script>
{% endblock %}
{% endblock %}

View File

@ -16,7 +16,7 @@
</div>
<div class="kg-nav-right">
<a class="layui-btn layui-btn-sm" href="{{ category_url }}">
<i class="layui-icon layui-icon-add-1"></i>分类管理
<i class="layui-icon layui-icon-add-1"></i>课程分类
</a>
<a class="layui-btn layui-btn-sm" href="{{ add_url }}">
<i class="layui-icon layui-icon-add-1"></i>添加课程
@ -124,4 +124,4 @@
{{ partial('partials/pager') }}
{% endblock %}
{% endblock %}

View File

@ -3,7 +3,6 @@
<table class="kg-table layui-table">
<tr>
<th>名称</th>
<th>类型</th>
<th>大小</th>
<th>日期</th>
<th width="15%">操作</th>
@ -13,7 +12,6 @@
{% set delete_url = url({'for':'admin.resource.delete','id':item.id}) %}
<tr>
<td><input class="layui-input res-name" type="text" value="{{ item.upload.name }}" data-url="{{ update_url }}"></td>
<td>{{ item.upload.mime }}</td>
<td>{{ item.upload.size|human_size }}</td>
<td>{{ date('Y-m-d H:i:s',item.create_time) }}</td>
<td>
@ -27,4 +25,4 @@
{% else %}
<div class="kg-center">没有相关资料</div>
<br>
{% endif %}
{% endif %}

View File

@ -49,7 +49,6 @@
{% block include_js %}
{{ js_include('lib/kindeditor/kindeditor.min.js') }}
{{ js_include('lib/kindeditor/lang/zh-CN.js') }}
{{ js_include('admin/js/content.editor.js') }}
{% endblock %}

View File

@ -62,7 +62,6 @@
{% block include_js %}
{{ js_include('lib/kindeditor/kindeditor.min.js') }}
{{ js_include('lib/kindeditor/lang/zh-CN.js') }}
{{ js_include('admin/js/content.editor.js') }}
{% endblock %}

View File

@ -15,7 +15,7 @@
<div class="layui-header">
<div class="layui-logo">{{ site_info.title }}</div>
<div class="kg-side-menu-bar">
<a href="javascript:"><i class="layui-icon layui-icon-spread-left"></i></a>
<a href="javascript:" title="关闭左侧菜单"><i class="layui-icon layui-icon-spread-left"></i></a>
</div>
<ul class="layui-nav layui-layout-left kg-nav-module">
<li class="layui-nav-item">
@ -28,6 +28,16 @@
{% endfor %}
</ul>
<ul class="layui-nav layui-layout-right">
<li class="layui-nav-item">
<a href="{{ url({'for':'home.index'}) }}" target="_blank">前台首页</a>
</li>
<li class="layui-nav-item">
<a href="javascript:">用户服务</a>
<dl class="layui-nav-child">
<dd><a href="{{ url({'for':'admin.koogua.wiki'}) }}" target="_blank">系统文档</a></dd>
<dd><a href="{{ url({'for':'admin.koogua.community'}) }}" target="_blank">开源社区</a></dd>
</dl>
</li>
<li class="layui-nav-item">
<a href="javascript:">{{ auth_user.name }}</a>
<dl class="layui-nav-child">
@ -36,9 +46,6 @@
<dd><a href="{{ url({'for':'admin.logout'}) }}">退出登录</a></dd>
</dl>
</li>
<li class="layui-nav-item">
<a href="{{ url({'for':'home.index'}) }}" target="_blank">前台</a>
</li>
</ul>
</div>
<div class="layui-side layui-bg-black">

View File

@ -6,7 +6,7 @@
<div class="layui-card-body">
<table class="layui-table">
<colgroup>
<col width="100">
<col width="25%">
<col>
</colgroup>
<tbody>
@ -24,4 +24,4 @@
</tbody>
</table>
</div>
</div>
</div>

View File

@ -1,9 +1,9 @@
<div class="layui-card layui-text" xmlns="http://www.w3.org/1999/html">
<div class="layui-card layui-text">
<div class="layui-card-header">服务器信息</div>
<div class="layui-card-body">
<table class="layui-table">
<colgroup>
<col width="100">
<col width="25%">
<col>
</colgroup>
<tbody>
@ -22,4 +22,4 @@
</tbody>
</table>
</div>
</div>
</div>

View File

@ -3,7 +3,7 @@
<div class="layui-card-body">
<table class="layui-table">
<colgroup>
<col width="100">
<col width="25%">
<col>
</colgroup>
<tbody>
@ -26,4 +26,4 @@
</tbody>
</table>
</div>
</div>
</div>

View File

@ -5,8 +5,8 @@
H5
{% elseif value == 3 %}
APP
{% elseif value == 4 %}
小程序
{% elseif value == 5 %}
微信小程序
{% else %}
N/A
{% endif %}

Some files were not shown because too many files have changed in this diff Show More