1
0
mirror of https://gitee.com/koogua/course-tencent-cloud.git synced 2025-08-03 13:02:55 +08:00

Compare commits

...

219 Commits

Author SHA1 Message Date
xiaochong0302
2c9f3b7577 补充course_user中教师来源类型 2025-06-19 10:02:10 +08:00
xiaochong0302
13b3327b2f 教师可访问其教授课程 2025-06-18 15:45:44 +08:00
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
xiaochong0302
b2eb5d56d3 Merge branch 'koogua/v1.6.9' 2024-05-10 09:41:19 +08:00
xiaochong0302
0c30cda0c3 v1.7.0 2024-05-09 21:40:40 +08:00
xiaochong0302
a0e8e932e1 v1.7.0 2024-05-09 21:37:23 +08:00
xiaochong0302
bd14979e9b 调整编辑器htmlTags属性 2024-05-05 21:52:13 +08:00
xiaochong0302
4e80f3938a 登录后台同时登录前台 2024-05-02 11:04:21 +08:00
xiaochong0302
9addc3debe 调整编辑器条目 2024-04-29 16:26:59 +08:00
xiaochong0302
e24cf1bd1c 1.调整编辑器条目
2.增加代码块复制
2024-04-28 21:17:36 +08:00
xiaochong0302
c355709d03 Merge branch 'koogua/v1.6.9' 2024-04-24 15:42:19 +08:00
xiaochong0302
2b3372c8e8 更新layui-v2.9.8 2024-04-24 15:20:16 +08:00
xiaochong0302
a790cf878b 清理无用的Captcha配置 2024-04-23 22:52:35 +08:00
xiaochong0302
4171039f16 contact改QQ上传二维码图片 2024-04-23 22:12:34 +08:00
xiaochong0302
9a29e21441 contact改QQ上传二维码图片 2024-04-23 22:12:23 +08:00
xiaochong0302
502bd8588d 修正contact二维码图片上传上传 2024-04-23 20:59:15 +08:00
xiaochong0302
621123ee3d 修正contact二维码图片上传上传 2024-04-23 20:58:44 +08:00
xiaochong0302
0d6420ef16 修正logo,favicon上传 2024-04-20 10:50:02 +08:00
xiaochong0302
547bb72910 修正logo,favicon上传 2024-04-20 10:49:37 +08:00
xiaochong0302
046db8877c Merge branch 'koogua/v1.6.9'
# Conflicts:
#	app/Validators/Security.php
2024-04-13 08:05:15 +08:00
xiaochong0302
c968a3a69f v1.6.9 2024-04-10 19:42:48 +08:00
xiaochong0302
d31ae5b7be 1.修正chapter_user中duration重复计数的问题 2024-04-10 18:58:55 +08:00
xiaochong0302
65b0bf1678 补充缺失的CourseUserTrait 2024-04-10 17:10:18 +08:00
xiaochong0302
af4b570681 增加删除和还原用户功能 2024-04-08 10:59:19 +08:00
xiaochong0302
d95b218812 优化CourseUserTrait 2024-04-06 22:27:43 +08:00
xiaochong0302
d3623b2654 优化CategoryTreeList 2024-04-02 10:48:33 +08:00
xiaochong0302
b96c711a6f 更新layui-v2.9.7 2024-03-24 21:00:17 +08:00
xiaochong0302
89145284aa 1.Response增加unauthorized响应
2.open_avatar字段增加长度为255
3.清理无用的代码
2024-03-13 08:57:55 +08:00
xiaochong0302
00cb8bf963 1.拆解migration创建表脚本
2.增加post方式传递csrf_token
3.优化storage上传
2024-02-26 09:56:51 +08:00
xiaochong0302
c304fbd423 1.修正home模块编辑器图片上传
2.精简CsrfToken白名单
2024-02-04 16:59:08 +08:00
xiaochong0302
2506ea4078 1.优化文章和提问搜索条件
2.优化课程详情页排版
2024-02-04 16:57:13 +08:00
xiaochong0302
542e96846f 1.修正home模块编辑器图片上传
2.精简CsrfToken白名单
2024-02-02 20:58:22 +08:00
xiaochong0302
3b18267c6f 1.删除chapter中resource_count,consult_count属性
2.重新统计course中resource_count
2024-01-31 18:06:01 +08:00
xiaochong0302
c4259d78f3 1.删除chapter中resource_count,consult_count属性
2.重新统计course中resource_count
2024-01-31 18:01:25 +08:00
xiaochong0302
6a5c4845dc 修正首页缓存刷新问题 2024-01-30 17:54:32 +08:00
xiaochong0302
9b7a244fa3 修正首页缓存刷新问题 2024-01-30 17:54:09 +08:00
xiaochong0302
d0091f4695 Merge branch 'koogua/v1.6.8'
# Conflicts:
#	app/Http/Admin/Views/chapter/lessons.volt
#	app/Http/Admin/Views/chapter/lessons_live.volt
#	app/Http/Admin/Views/chapter/lessons_offline.volt
#	app/Http/Admin/Views/chapter/lessons_read.volt
#	app/Http/Admin/Views/chapter/lessons_vod.volt
2024-01-30 12:02:00 +08:00
xiaochong0302
01587189cb v1.6.8发布 2024-01-30 11:47:15 +08:00
xiaochong0302
45dfa0d269 去除league/commonmark包 2024-01-25 21:45:01 +08:00
xiaochong0302
56e04fc3a3 优化分类等必选判断 2024-01-22 12:37:58 +08:00
xiaochong0302
3079a9855a 修正course_user中active_time未更新问题 2024-01-11 20:42:54 +08:00
xiaochong0302
ebc609ac19 修正chapter_user表中plan_id=0问题 2024-01-11 20:31:09 +08:00
xiaochong0302
486ac7bd69 修正chapter_user表中plan_id=0问题 2024-01-11 20:30:28 +08:00
xiaochong0302
5e1ca229ec 修正课时评论管理链接 2024-01-11 18:51:52 +08:00
xiaochong0302
680f1cf1bc 修复sync_learning时,course_user未更新active_time问题 2024-01-11 13:00:24 +08:00
xiaochong0302
b67011c041 修复主页simple模式免费课程模块样式问题 2024-01-08 11:21:49 +08:00
xiaochong0302
fd2e8d2aee 1.优化错误处理
2.更新layui2.9.3
2024-01-07 09:31:50 +08:00
xiaochong0302
78d538c816 清理代码 2023-12-30 15:23:53 +08:00
xiaochong0302
5ce45971e6 优化AccountSearchTrait 2023-12-28 21:31:59 +08:00
xiaochong0302
33fc75b9f8 1.精简chapter/lessons.volt
2.使用ServiceTrait精简代码
2023-12-27 16:05:23 +08:00
xiaochong0302
59e27e1443 修正用户active_time搜索条件 2023-12-25 20:18:41 +08:00
xiaochong0302
ce9f0eade0 修正用户active_time搜索条件 2023-12-25 20:18:13 +08:00
xiaochong0302
411ffe8f1c 统一layui-skin=switch属性位置 2023-12-21 09:30:41 +08:00
xiaochong0302
decf80273a 统一layui-skin=switch属性位置 2023-12-21 09:26:48 +08:00
xiaochong0302
db82de6f35 修正plan_id格式问题 2023-12-20 21:54:01 +08:00
xiaochong0302
52aa85b2ae 修正plan_id格式问题 2023-12-20 21:53:47 +08:00
xiaochong0302
6c33dbc724 修正课时发布switch开关问题 2023-12-20 21:39:25 +08:00
xiaochong0302
2714a048f8 修正课时发布switch开关问题 2023-12-20 21:38:27 +08:00
xiaochong0302
dd0c26d6ad v1.6.8 start 2023-12-20 21:17:10 +08:00
xiaochong0302
8e40019939 Merge branch 'koogua/v1.6.7' 2023-12-13 20:54:01 +08:00
xiaochong0302
fb01e61332 去除分类必选限制 2023-12-13 20:20:51 +08:00
xiaochong0302
da0cc73c12 优化变量名和排版 2023-12-13 12:53:35 +08:00
xiaochong0302
b192760deb 优化相关文章和问题 2023-12-12 17:18:24 +08:00
xiaochong0302
e0da7b71b3 调整内容缓存时间 2023-12-12 16:19:04 +08:00
xiaochong0302
56f909b5d2 调整推荐课程缓存时间 2023-12-11 17:47:07 +08:00
xiaochong0302
c859deec44 vip.js -> vip.index.js 2023-12-11 12:56:43 +08:00
xiaochong0302
435bc12035 增加问题推荐 2023-12-11 12:23:42 +08:00
xiaochong0302
dca1ccf79a 优化排版 2023-12-10 20:55:26 +08:00
xiaochong0302
817b32b067 放弃部分地方缓存的使用 2023-12-09 19:02:05 +08:00
xiaochong0302
51428ac97a 补充遗漏的批量删除点击事件 2023-12-09 09:01:18 +08:00
xiaochong0302
8f22cab282 优化批量删除后的跳转 2023-12-08 20:17:39 +08:00
xiaochong0302
982b1d5ca7 删除多余文件 2023-12-07 20:57:25 +08:00
xiaochong0302
f3fcb6956a beta 2023-12-07 17:09:28 +08:00
xiaochong0302
3dd5490bdb 阶段性优化 2023-12-06 20:24:09 +08:00
xiaochong0302
5268e6370c Merge remote-tracking branch 'origin/koogua/v1.6.7' into koogua/v1.6.7 2023-12-04 19:47:11 +08:00
xiaochong0302
79a678fa54 阶段性优化 2023-12-04 19:46:54 +08:00
xiaochong0302
0072b4f5fe 精简代码 2023-10-29 22:30:14 +08:00
koogua
51de0ed94b 字数统计加上图片字数 2023-10-01 11:05:53 +08:00
xiaochong0302
26e3e94881 修正绑定邮箱password未定义错误 2023-09-22 20:42:13 +08:00
xiaochong0302
0a86fc3f05 修正绑定邮箱password未定义错误 2023-09-22 20:41:42 +08:00
xiaochong0302
e905e7cb96 修正课程课件资源列表权限 2023-09-18 06:53:05 +08:00
xiaochong0302
2c881547b4 修正课程课件资源列表权限 2023-09-18 06:52:57 +08:00
xiaochong0302
7d54f0e933 增加匿名评价 2023-09-16 21:44:23 +08:00
xiaochong0302
1bef24f217 1.kg_course表增加索引
2.优化错误页
3.优化富文本内容长度获取
4.优化layer关闭窗口后发布状态同步
2023-09-16 20:51:31 +08:00
xiaochong0302
0dec52806b 优化直播测试的streamName解析 2023-09-04 10:53:47 +08:00
xiaochong0302
241d802fe1 直播页分享地址:full_url->share_url 2023-09-04 10:38:10 +08:00
xiaochong0302
66bd0965d6 去除课时列表中的课件属性 2023-09-03 10:54:55 +08:00
xiaochong0302
40380132a2 Merge branch 'koogua/v1.6.6'
# Conflicts:
#	app/Http/Admin/Services/Resource.php
2023-08-31 17:41:09 +08:00
xiaochong0302
ebd310caa6 v1.6.6 2023-08-31 17:18:05 +08:00
xiaochong0302
138b9d45ce 日常优化 2023-08-28 15:55:40 +08:00
xiaochong0302
504bf6d8e6 去除删除远程COS课件的逻辑 2023-08-11 15:54:11 +08:00
xiaochong0302
65b5190a05 去除删除远程COS课件的逻辑 2023-08-11 15:53:41 +08:00
xiaochong0302
f284a8ef92 修正邮箱注册提交按钮不可用问题 2023-08-03 16:57:15 +08:00
xiaochong0302
c584f25455 修正邮箱注册提交按钮不可用问题 2023-08-03 16:56:18 +08:00
xiaochong0302
85ba7911ac 优化cleanDemoDataTask 2023-08-02 17:59:47 +08:00
xiaochong0302
190117146f 优化tag表migration 2023-08-02 17:18:25 +08:00
xiaochong0302
c0e44a76d0 v1.6.6开始 2023-07-23 18:56:49 +08:00
xiaochong0302
0c9256751d 优化AuthTrait 2023-07-11 09:55:21 +08:00
xiaochong0302
1c0af6fa1e 去除后台登录页的captcha检查 2023-07-10 17:40:18 +08:00
xiaochong0302
4f18d78356 去除后台登录页的无用captcha代码 2023-07-10 15:08:44 +08:00
798 changed files with 12358 additions and 14597 deletions

View File

@ -1,3 +1,171 @@
### [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
- 调整html编辑器属性
- 增加代码块内容复制
- 清理无用的Captcha配置
- 联系人QQ改为上传二维码图片
- 修正logo,favicon上传路径
- 登录后台同时登录前台
- 移动端修正评论发表
### [v1.6.9](https://gitee.com/koogua/course-tencent-cloud/releases/v1.6.9)(2024-04-15)
- 增加用户删除和还原功能
- 增加unauthorized响应
- 增加post方式传递csrf_token
- 删除chapter中resource_count,consult_count属性
- 精简csrf_token白名单
- 拆解优化migrations创建表脚本
- 修正chapter_user时长重复计数问题
- 修正后台刷新首页缓存问题
- 修正home模块中编辑器图片上传
- 优化文章和提问搜索条件
- 优化课程详情页排版
- 优化storage上传
- 优化CategoryTreeList
- 优化CourseUserTrait
- 更新layui-v2.9.7
### [v1.6.8](https://gitee.com/koogua/course-tencent-cloud/releases/v1.6.8)(2024-01-30)
- 修正course_user中active_time未更新问题
- 修正主页simple模式免费课程模块样式问题
- 修正chapter_user中plan_id=0问题
- 修正课时评论管理链接
- 修正用户active_time搜索条件
- 修正课时发布switch开关
- 精简chapter/lessons.volt
- 去除league/commonmark包
- 去除分类等必选判断
- 更新layui-v2.9.3
- 使用ServiceTrait精简代码
- 优化AccountTrait
- 优化错误处理
### [v1.6.7](https://gitee.com/koogua/course-tencent-cloud/releases/v1.6.7)(2023-12-15)
- 增加文章分类功能
- 增加问题分类功能
- 增加审核等批量功能
- 增加若干业务插件埋点
- 精简重构大量业务逻辑
- 移除秒杀营销功能
- 已发现的问题修复
### [v1.6.6](https://gitee.com/koogua/course-tencent-cloud/releases/v1.6.6)(2023-08-30)
- 还原意外删除的AnswerList.php文件
- 修正邮箱注册提交按钮不可用问题
- 去除删除远程课件逻辑
- 增加课程课件资料总览
- 优化cleanDemoDataTask脚本
- 优化tag表migration脚本
- 命名结构等常规优化
### [v1.6.5](https://gitee.com/koogua/course-tencent-cloud/releases/v1.6.5)(2023-07-15)
- 升级layui-v2.8.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)
### 系统介绍
@ -13,11 +13,11 @@
### 系统功能
实现了点播、直播、专栏、面授、问答、会员、积分、秒杀等。
实现了点播、直播、专栏、问答、会员、积分等。
友情提示:
- 演示系统配置低(1Core1G1M 跑多个容器)切莫压测
- 演示系统配置低(2核2G1M 跑多个容器)切莫压测
- 课程数据来源于网络(无实质内容)切莫购买
- 管理后台已禁止数据提交,私密配置已过滤
@ -34,12 +34,6 @@ H5手机端演示
演示账号13507083515 / 123456
微信公众号演示:
![公众号二维码](https://portal-1255691183.file.myqcloud.com/img/content/616f998270eca.png)
演示账号13507083515 / 123456
支付流程演示:
- [MySQL提升课程全面讲解MySQL架构设计0.01元)](https://ctc.koogua.com/order/confirm?item_id=1390&item_type=1)
@ -54,10 +48,9 @@ Tips: 请用手机注册一个新账号,用户中心 -> 关注订阅,扫码
### 项目组件
- 后台框架:[phalcon 3.4.5](https://phalcon.io)
- 前端框架:[layui 2.8.8](https://layui.com)
- 全文检索:[xunsearch 1.4.9](http://www.xunsearch.com)
- 即时通讯:[workerman 3.5.22](https://workerman.net)
- 后台框架:[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

@ -7,9 +7,8 @@
namespace App\Builders;
use App\Caches\CategoryList as CategoryListCache;
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;
@ -47,7 +46,7 @@ class ArticleList extends Builder
public function getCategories()
{
$cache = new CategoryListCache();
$cache = new CategoryAllListCache();
$items = $cache->get(CategoryModel::TYPE_ARTICLE);
@ -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

@ -8,15 +8,16 @@
namespace App\Builders;
use App\Models\Category as CategoryModel;
use Phalcon\Mvc\Model\Resultset;
use Phalcon\Mvc\Model\ResultsetInterface;
use App\Repos\Category as CategoryRepo;
class CategoryTreeList extends Builder
{
public function handle($type)
{
$topCategories = $this->findTopCategories($type);
$categoryRepo = new CategoryRepo();
$topCategories = $categoryRepo->findTopCategories($type);
if ($topCategories->count() == 0) {
return [];
@ -39,7 +40,9 @@ class CategoryTreeList extends Builder
protected function handleChildren(CategoryModel $category)
{
$subCategories = $this->findChildCategories($category->id);
$categoryRepo = new CategoryRepo();
$subCategories = $categoryRepo->findChildCategories($category->id);
if ($subCategories->count() == 0) {
return [];
@ -59,37 +62,4 @@ class CategoryTreeList extends Builder
return $list;
}
/**
* @param int $type
* @return ResultsetInterface|Resultset|CategoryModel[]
*/
protected function findTopCategories($type)
{
$query = CategoryModel::query();
$query->where('parent_id = 0');
$query->andWhere('published = 1');
$query->andWhere('deleted = 0');
$query->andWhere('type = :type:', ['type' => $type]);
$query->orderBy('priority ASC');
return $query->execute();
}
/**
* @param int $parentId
* @return ResultsetInterface|Resultset|CategoryModel[]
*/
protected function findChildCategories($parentId)
{
$query = CategoryModel::query();
$query->where('parent_id = :parent_id:', ['parent_id' => $parentId]);
$query->andWhere('published = 1');
$query->andWhere('deleted = 0');
$query->orderBy('priority ASC');
return $query->execute();
}
}

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

@ -7,9 +7,8 @@
namespace App\Builders;
use App\Caches\CategoryList as CategoryListCache;
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;
@ -38,7 +37,7 @@ class CourseList extends Builder
public function getCategories()
{
$cache = new CategoryListCache();
$cache = new CategoryAllListCache();
$items = $cache->get(CategoryModel::TYPE_COURSE);
@ -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

@ -1,104 +0,0 @@
<?php
/**
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.koogua.com
*/
namespace App\Builders;
use App\Repos\Chapter as ChapterRepo;
use App\Repos\Course as CourseRepo;
use App\Repos\User as UserRepo;
class DanmuList extends Builder
{
public function handleCourses(array $danmus)
{
$courses = $this->getCourses($danmus);
foreach ($danmus as $key => $danmu) {
$danmus[$key]['course'] = $courses[$danmu['course_id']] ?? new \stdClass();
}
return $danmus;
}
public function handleChapters(array $danmus)
{
$chapters = $this->getChapters($danmus);
foreach ($danmus as $key => $danmu) {
$danmus[$key]['chapter'] = $chapters[$danmu['chapter_id']] ?? new \stdClass();
}
return $danmus;
}
public function handleUsers(array $danmus)
{
$users = $this->getUsers($danmus);
foreach ($danmus as $key => $danmu) {
$danmus[$key]['owner'] = $users[$danmu['owner_id']] ?? new \stdClass();
}
return $danmus;
}
public function getCourses(array $danmus)
{
$ids = kg_array_column($danmus, 'course_id');
$courseRepo = new CourseRepo();
$courses = $courseRepo->findByIds($ids, ['id', 'title']);
$result = [];
foreach ($courses->toArray() as $course) {
$result[$course['id']] = $course;
}
return $result;
}
public function getChapters(array $danmus)
{
$ids = kg_array_column($danmus, '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 $danmus)
{
$ids = kg_array_column($danmus, '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;
}
}

View File

@ -7,7 +7,7 @@
namespace App\Builders;
use App\Caches\CategoryList as CategoryListCache;
use App\Caches\CategoryAllList as CategoryAllListCache;
use App\Models\Category as CategoryModel;
class HelpList extends Builder
@ -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;
@ -26,7 +26,7 @@ class HelpList extends Builder
public function getCategories()
{
$cache = new CategoryListCache();
$cache = new CategoryAllListCache();
$items = $cache->get(CategoryModel::TYPE_HELP);

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

@ -7,9 +7,8 @@
namespace App\Builders;
use App\Caches\CategoryList as CategoryListCache;
use App\Caches\CategoryAllList as CategoryAllListCache;
use App\Models\Category as CategoryModel;
use App\Repos\User as UserRepo;
class QuestionList extends Builder
{
@ -27,8 +26,8 @@ class QuestionList extends Builder
{
$categories = $this->getCategories();
foreach ($questions as $key => $article) {
$questions[$key]['category'] = $categories[$article['category_id']] ?? new \stdClass();
foreach ($questions as $key => $question) {
$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;
@ -48,7 +47,7 @@ class QuestionList extends Builder
public function getCategories()
{
$cache = new CategoryListCache();
$cache = new CategoryAllListCache();
$items = $cache->get(CategoryModel::TYPE_QUESTION);
@ -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

@ -8,6 +8,7 @@
namespace App\Builders;
use App\Models\User as UserModel;
use App\Repos\Account as AccountRepo;
use App\Repos\Role as RoleRepo;
class UserList extends Builder
@ -24,6 +25,17 @@ class UserList extends Builder
return $users;
}
public function handleAccounts(array $users)
{
$accounts = $this->getAccounts($users);
foreach ($users as $key => $user) {
$users[$key]['account'] = $accounts[$user['id']] ?? null;
}
return $users;
}
public function handleAdminRoles(array $users)
{
$roles = $this->getAdminRoles($users);
@ -46,6 +58,26 @@ class UserList extends Builder
return $users;
}
protected function getAccounts(array $users)
{
$ids = kg_array_column($users, 'id');
$accountRepo = new AccountRepo();
$accounts = $accountRepo->findByIds($ids);
$result = [];
foreach ($accounts as $account) {
$result[$account->id] = [
'phone' => $account->phone,
'email' => $account->email,
];
}
return $result;
}
protected function getAdminRoles(array $users)
{
$ids = kg_array_column($users, 'admin_role');

View File

@ -27,10 +27,10 @@ class AppInfo extends Cache
$appInfo = new \App\Library\AppInfo();
return [
'name' => $appInfo->name,
'alias' => $appInfo->alias,
'link' => $appInfo->link,
'version' => $appInfo->version,
'name' => $appInfo->get('name'),
'alias' => $appInfo->get('alias'),
'link' => $appInfo->get('link'),
'version' => $appInfo->get('version'),
];
}

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

@ -0,0 +1,46 @@
<?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 Phalcon\Mvc\Model\Resultset;
class CategoryAllList extends Cache
{
protected $lifetime = 365 * 86400;
public function getLifetime()
{
return $this->lifetime;
}
public function getKey($id = null)
{
return "category_all_list:{$id}";
}
public function getContent($id = null)
{
/**
* @var Resultset $categories
*/
$categories = CategoryModel::query()
->columns(['id', 'parent_id', 'name', 'priority', 'level', 'path'])
->where('type = :type:', ['type' => $id])
->orderBy('level ASC, priority ASC')
->execute();
if ($categories->count() == 0) {
return [];
}
return $categories->toArray();
}
}

View File

@ -25,10 +25,6 @@ class CategoryList extends Cache
return "category_list:{$id}";
}
/**
* @param null $id
* @return array
*/
public function getContent($id = null)
{
/**

View File

@ -9,6 +9,7 @@ namespace App\Caches;
use App\Library\Cache\Backend\Redis as RedisCache;
use Phalcon\Di\Injectable;
use Redis;
abstract class Counter extends Injectable
{
@ -19,7 +20,7 @@ abstract class Counter extends Injectable
protected $cache;
/**
* @var \Redis
* @var Redis
*/
protected $redis;
@ -30,19 +31,13 @@ abstract class Counter extends Injectable
$this->redis = $this->cache->getRedis();
}
/**
* 获取缓存内容
*
* @param mixed $id
* @return array
*/
public function get($id = null)
{
$key = $this->getKey($id);
$content = $this->redis->hGetAll($key);
if (!$this->cache->exists($key)) {
if (!$this->redis->exists($key)) {
$content = $this->getContent($id);
$lifetime = $this->getLifetime();
@ -54,23 +49,13 @@ abstract class Counter extends Injectable
return $content;
}
/**
* 删除缓存内容
*
* @param mixed $id
*/
public function delete($id = null)
{
$key = $this->getKey($id);
$this->cache->delete($key);
$this->redis->del($key);
}
/**
* 重建缓存内容
*
* @param mixed $id
*/
public function rebuild($id = null)
{
$this->delete($id);

View File

@ -1,59 +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\Repos\Course as CourseRepo;
class CourseCategoryList extends Cache
{
protected $lifetime = 86400;
public function getLifetime()
{
return $this->lifetime;
}
public function getKey($id = null)
{
return "course_category_list:{$id}";
}
public function getContent($id = null)
{
$courseRepo = new CourseRepo();
$categories = $courseRepo->findCategories($id);
if ($categories->count() == 0) {
return [];
}
return $this->handleContent($categories);
}
/**
* @param CategoryModel[] $categories
* @return array
*/
public function handleContent($categories)
{
$result = [];
foreach ($categories as $category) {
$result[] = [
'id' => $category->id,
'name' => $category->name,
];
}
return $result;
}
}

View File

@ -1,90 +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\Course as CourseModel;
use Phalcon\Mvc\Model\Resultset;
use Phalcon\Mvc\Model\ResultsetInterface;
class CourseRecommendedList extends Cache
{
protected $lifetime = 86400;
public function getLifetime()
{
return $this->lifetime;
}
public function getKey($id = null)
{
return "course_recommended_list:{$id}";
}
public function getContent($id = null)
{
$courses = $this->findCourses(5);
if ($courses->count() == 0) {
return [];
}
return $this->handleContent($courses);
}
/**
* @param CourseModel[] $courses
* @return array
*/
public function handleContent($courses)
{
$result = [];
foreach ($courses as $course) {
$userCount = $course->user_count;
if ($course->fake_user_count > $course->user_count) {
$userCount = $course->fake_user_count;
}
$result[] = [
'id' => $course->id,
'title' => $course->title,
'cover' => $course->cover,
'model' => $course->model,
'level' => $course->level,
'rating' => round($course->rating, 1),
'market_price' => (float)$course->market_price,
'vip_price' => (float)$course->vip_price,
'user_count' => $userCount,
'lesson_count' => $course->lesson_count,
'review_count' => $course->review_count,
'favorite_count' => $course->favorite_count,
];
}
return $result;
}
/**
* @param int $limit
* @return ResultsetInterface|Resultset|CourseModel[]
*/
public function findCourses($limit = 5)
{
return CourseModel::query()
->where('market_price > 0')
->andWhere('published = 1')
->andWhere('deleted = 0')
->orderBy('RAND()')
->limit($limit)
->execute();
}
}

View File

@ -1,63 +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\User as UserModel;
use App\Repos\Course as CourseRepo;
class CourseTeacherList extends Cache
{
protected $lifetime = 86400;
public function getLifetime()
{
return $this->lifetime;
}
public function getKey($id = null)
{
return "course_teacher_list:{$id}";
}
public function getContent($id = null)
{
$courseRepo = new CourseRepo();
$users = $courseRepo->findTeachers($id);
if ($users->count() == 0) {
return [];
}
return $this->handleContent($users);
}
/**
* @param UserModel[] $users
* @return array
*/
public function handleContent($users)
{
$result = [];
foreach ($users as $user) {
$result[] = [
'id' => $user->id,
'name' => $user->name,
'avatar' => $user->avatar,
'vip' => $user->vip,
'title' => $user->title,
'about' => $user->about,
];
}
return $result;
}
}

View File

@ -14,13 +14,13 @@ use Phalcon\Mvc\Model\ResultsetInterface;
class FeaturedArticleList extends Cache
{
protected $lifetime = 86400;
protected $lifetime = 3600;
protected $limit = 5;
public function getLifetime()
{
$tomorrow = strtotime('tomorrow');
return $tomorrow - time();
return $this->lifetime;
}
public function getKey($id = null)
@ -30,9 +30,7 @@ class FeaturedArticleList extends Cache
public function getContent($id = null)
{
$limit = 8;
$articles = $this->findArticles($limit);
$articles = $this->findArticles($this->limit);
if ($articles->count() == 0) {
return [];
@ -41,20 +39,10 @@ class FeaturedArticleList extends Cache
$result = [];
foreach ($articles as $article) {
$userCount = $article->user_count;
if ($article->fake_user_count > $article->user_count) {
$userCount = $article->fake_user_count;
}
$result[] = [
'id' => $article->id,
'title' => $article->title,
'cover' => $article->cover,
'market_price' => (float)$article->market_price,
'vip_price' => (float)$article->vip_price,
'user_count' => $userCount,
'favorite_count' => $article->favorite_count,
'comment_count' => $article->comment_count,
'view_count' => $article->view_count,
@ -69,13 +57,13 @@ class FeaturedArticleList extends Cache
* @param int $limit
* @return ResultsetInterface|Resultset|ArticleModel[]
*/
protected function findArticles($limit = 8)
protected function findArticles($limit = 5)
{
return ArticleModel::query()
->where('featured = 1')
->andWhere('published = 1')
->andWhere('published = :published:', ['published' => ArticleModel::PUBLISH_APPROVED])
->andWhere('deleted = 0')
->orderBy('id DESC')
->orderBy('RAND()')
->limit($limit)
->execute();
}

View File

@ -14,13 +14,13 @@ use Phalcon\Mvc\Model\ResultsetInterface;
class FeaturedCourseList extends Cache
{
protected $lifetime = 86400;
protected $lifetime = 3600;
protected $limit = 5;
public function getLifetime()
{
$tomorrow = strtotime('tomorrow');
return $tomorrow - time();
return $this->lifetime;
}
public function getKey($id = null)
@ -30,9 +30,7 @@ class FeaturedCourseList extends Cache
public function getContent($id = null)
{
$limit = 8;
$courses = $this->findCourses($limit);
$courses = $this->findCourses($this->limit);
if ($courses->count() == 0) {
return [];
@ -71,13 +69,13 @@ class FeaturedCourseList extends Cache
* @param int $limit
* @return ResultsetInterface|Resultset|CourseModel[]
*/
protected function findCourses($limit = 8)
protected function findCourses($limit = 5)
{
return CourseModel::query()
->where('featured = 1')
->andWhere('published = 1')
->andWhere('deleted = 0')
->orderBy('id DESC')
->orderBy('RAND()')
->limit($limit)
->execute();
}

View File

@ -0,0 +1,72 @@
<?php
/**
* @copyright Copyright (c) 2023 深圳市酷瓜软件有限公司
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.koogua.com
*/
namespace App\Caches;
use App\Models\Question as QuestionModel;
use Phalcon\Mvc\Model\Resultset;
use Phalcon\Mvc\Model\ResultsetInterface;
class FeaturedQuestionList extends Cache
{
protected $lifetime = 3600;
protected $limit = 5;
public function getLifetime()
{
return $this->lifetime;
}
public function getKey($id = null)
{
return 'featured_question_list';
}
public function getContent($id = null)
{
$questions = $this->findQuestions($this->limit);
if ($questions->count() == 0) {
return [];
}
$result = [];
foreach ($questions as $question) {
$result[] = [
'id' => $question->id,
'title' => $question->title,
'cover' => $question->cover,
'favorite_count' => $question->favorite_count,
'answer_count' => $question->answer_count,
'view_count' => $question->view_count,
'like_count' => $question->like_count,
];
}
return $result;
}
/**
* @param int $limit
* @return ResultsetInterface|Resultset|QuestionModel[]
*/
protected function findQuestions($limit = 5)
{
return QuestionModel::query()
->where('featured = 1')
->andWhere('published = :published:', ['published' => QuestionModel::PUBLISH_APPROVED])
->andWhere('deleted = 0')
->orderBy('RAND()')
->limit($limit)
->execute();
}
}

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\FlashSale as FlashSaleRepo;
class FlashSale extends Cache
{
protected $lifetime = 86400;
public function getLifetime()
{
return $this->lifetime;
}
public function getKey($id = null)
{
return "flash_sale:{$id}";
}
public function getContent($id = null)
{
$saleRepo = new FlashSaleRepo();
$sale = $saleRepo->findById($id);
return $sale ?: 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 = 365 * 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

@ -14,13 +14,11 @@ use Phalcon\Mvc\Model\ResultsetInterface;
class HotQuestionList extends Cache
{
protected $lifetime = 86400;
protected $lifetime = 3600;
public function getLifetime()
{
$tomorrow = strtotime('tomorrow');
return $tomorrow - time();
return $this->lifetime;
}
public function getKey($id = null)

View File

@ -14,7 +14,7 @@ use App\Services\Logic\Article\ArticleList as ArticleListService;
class IndexArticleList extends Cache
{
protected $lifetime = 15 * 60;
protected $lifetime = 3600;
public function getLifetime()
{

View File

@ -19,7 +19,7 @@ use Phalcon\Mvc\Model\ResultsetInterface;
class IndexFeaturedCourseList extends Cache
{
protected $lifetime = 86400;
protected $lifetime = 3600;
public function getLifetime()
{

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\Services\Logic\FlashSale\SaleList;
class IndexFlashSaleList extends Cache
{
protected $lifetime = 86400;
public function getLifetime()
{
return strtotime('tomorrow') - time();
}
public function getKey($id = null)
{
return 'index_flash_sale_list';
}
public function getContent($id = null)
{
$service = new SaleList();
$sales = $service->handle();
return $sales[0]['items'] ?? [];
}
}

View File

@ -19,7 +19,7 @@ use Phalcon\Mvc\Model\ResultsetInterface;
class IndexFreeCourseList extends Cache
{
protected $lifetime = 86400;
protected $lifetime = 3600;
public function getLifetime()
{

View File

@ -18,7 +18,7 @@ use Phalcon\Mvc\Model\ResultsetInterface;
class IndexLiveList extends Cache
{
protected $lifetime = 86400;
protected $lifetime = 3600;
public function getLifetime()
{

View File

@ -19,7 +19,7 @@ use Phalcon\Mvc\Model\ResultsetInterface;
class IndexNewCourseList extends Cache
{
protected $lifetime = 86400;
protected $lifetime = 3600;
public function getLifetime()
{

View File

@ -14,7 +14,7 @@ use App\Services\Logic\Question\QuestionList as QuestionListService;
class IndexQuestionList extends Cache
{
protected $lifetime = 15 * 60;
protected $lifetime = 3600;
public function getLifetime()
{

View File

@ -17,7 +17,7 @@ use Phalcon\Mvc\Model\ResultsetInterface;
class IndexSimpleFeaturedCourseList extends Cache
{
protected $lifetime = 86400;
protected $lifetime = 3600;
public function getLifetime()
{

View File

@ -17,7 +17,7 @@ use Phalcon\Mvc\Model\ResultsetInterface;
class IndexSimpleFreeCourseList extends Cache
{
protected $lifetime = 86400;
protected $lifetime = 3600;
public function getLifetime()
{

View File

@ -17,7 +17,7 @@ use Phalcon\Mvc\Model\ResultsetInterface;
class IndexSimpleNewCourseList extends Cache
{
protected $lifetime = 86400;
protected $lifetime = 3600;
public function getLifetime()
{

View File

@ -17,7 +17,7 @@ use Phalcon\Mvc\Model\ResultsetInterface;
class IndexSimpleVipCourseList extends Cache
{
protected $lifetime = 86400;
protected $lifetime = 3600;
public function getLifetime()
{

View File

@ -14,7 +14,7 @@ use Phalcon\Mvc\Model\ResultsetInterface;
class IndexSlideList extends Cache
{
protected $lifetime = 365 * 86400;
protected $lifetime = 3600;
public function getLifetime()
{

View File

@ -19,7 +19,7 @@ use Phalcon\Mvc\Model\ResultsetInterface;
class IndexVipCourseList extends Cache
{
protected $lifetime = 86400;
protected $lifetime = 3600;
public function getLifetime()
{

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\FlashSale as FlashSaleModel;
class MaxFlashSaleId extends Cache
{
protected $lifetime = 365 * 86400;
public function getLifetime()
{
return $this->lifetime;
}
public function getKey($id = null)
{
return 'max_flash_sale_id';
}
public function getContent($id = null)
{
$sale = FlashSaleModel::findFirst(['order' => 'id DESC']);
return $sale->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

@ -13,9 +13,9 @@ use App\Repos\Article as ArticleRepo;
class TaggedArticleList extends Cache
{
protected $limit = 5;
protected $limit = 15;
protected $lifetime = 86400;
protected $lifetime = 3600;
public function getLifetime()
{

View File

@ -13,9 +13,9 @@ use App\Repos\Question as QuestionRepo;
class TaggedQuestionList extends Cache
{
protected $limit = 5;
protected $limit = 15;
protected $lifetime = 86400;
protected $lifetime = 3600;
public function getLifetime()
{

View File

@ -16,7 +16,7 @@ use Phalcon\Mvc\Model\ResultsetInterface;
class TopAnswererList extends Cache
{
protected $lifetime = 86400;
protected $lifetime = 3600;
public function getLifetime()
{

View File

@ -16,7 +16,7 @@ use Phalcon\Mvc\Model\ResultsetInterface;
class TopAuthorList extends Cache
{
protected $lifetime = 86400;
protected $lifetime = 3600;
public function getLifetime()
{

View File

@ -10,8 +10,6 @@ namespace App\Caches;
class UserDailyCounter extends Counter
{
protected $lifetime = 86400;
public function getLifetime()
{
$tomorrow = strtotime('tomorrow');

View File

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

@ -1,162 +0,0 @@
<?php
/**
* @copyright Copyright (c) 2022 深圳市酷瓜软件有限公司
* @license https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* @link https://www.koogua.com
*/
namespace App\Console\Migrations;
use App\Models\Answer as AnswerModel;
use App\Models\Article as ArticleModel;
use App\Models\Course as CourseModel;
use App\Models\Help as HelpModel;
use App\Models\Page as PageModel;
use App\Models\PointGift as PointGiftModel;
use App\Models\Question as QuestionModel;
use League\CommonMark\GithubFlavoredMarkdownConverter;
use Phalcon\Mvc\Model\Resultset;
class V202207291145 extends Migration
{
/**
* @var GithubFlavoredMarkdownConverter
*/
protected $markdownConverter;
public function run()
{
$this->initMarkdownConverter();
$this->courseMarkdownToHtml();
$this->articleMarkdownToHtml();
$this->questionMarkdownToHtml();
$this->answerMarkdownToHtml();
$this->pageMarkdownToHtml();
$this->helpMarkdownToHtml();
$this->pointGiftMarkdownToHtml();
}
protected function initMarkdownConverter()
{
$this->markdownConverter = new GithubFlavoredMarkdownConverter([
'html_input' => 'escape',
'allow_unsafe_links' => false,
]);
}
protected function articleMarkdownToHtml()
{
/**
* @var $articles Resultset|ArticleModel[]
*/
$articles = ArticleModel::query()->execute();
if ($articles->count() == 0) return;
foreach ($articles as $article) {
$content = $this->markdownConverter->convertToHtml($article->content);
$article->content = $content;
$article->update();
}
}
protected function courseMarkdownToHtml()
{
/**
* @var $courses Resultset|CourseModel[]
*/
$courses = CourseModel::query()->execute();
if ($courses->count() == 0) return;
foreach ($courses as $course) {
$details = $this->markdownConverter->convertToHtml($course->details);
$course->details = $details;
$course->update();
}
}
protected function questionMarkdownToHtml()
{
/**
* @var $questions Resultset|QuestionModel[]
*/
$questions = QuestionModel::query()->execute();
if ($questions->count() == 0) return;
foreach ($questions as $question) {
$content = $this->markdownConverter->convertToHtml($question->content);
$question->content = $content;
$question->update();
}
}
protected function answerMarkdownToHtml()
{
/**
* @var $answers Resultset|AnswerModel[]
*/
$answers = AnswerModel::query()->execute();
if ($answers->count() == 0) return;
foreach ($answers as $answer) {
$content = $this->markdownConverter->convertToHtml($answer->content);
$answer->content = $content;
$answer->update();
}
}
protected function pageMarkdownToHtml()
{
/**
* @var $pages Resultset|PageModel[]
*/
$pages = PageModel::query()->execute();
if ($pages->count() == 0) return;
foreach ($pages as $page) {
$content = $this->markdownConverter->convertToHtml($page->content);
$page->content = $content;
$page->update();
}
}
protected function helpMarkdownToHtml()
{
/**
* @var $helps Resultset|HelpModel[]
*/
$helps = HelpModel::query()->execute();
if ($helps->count() == 0) return;
foreach ($helps as $help) {
$content = $this->markdownConverter->convertToHtml($help->content);
$help->content = $content;
$help->update();
}
}
protected function pointGiftMarkdownToHtml()
{
/**
* @var $gifts Resultset|PointGiftModel[]
*/
$gifts = PointGiftModel::query()
->where('type = :type:', ['type' => PointGiftModel::TYPE_GOODS])
->execute();
if ($gifts->count() == 0) return;
foreach ($gifts as $gift) {
$details = $this->markdownConverter->convertToHtml($gift->details);
$gift->details = $details;
$gift->update();
}
}
}

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,13 +7,14 @@
namespace App\Console\Tasks;
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;
use App\Models\Category as CategoryModel;
use App\Repos\User as UserRepo;
use App\Services\Utils\IndexCourseCache as IndexCourseCacheUtil;
use App\Services\Utils\IndexPageCache as IndexPageCacheUtil;
class CleanDemoDataTask extends Task
{
@ -38,8 +39,8 @@ class CleanDemoDataTask extends Task
echo '------ start truncate tables ------' . PHP_EOL;
$excludeTables = [
'kg_area', 'kg_migration', '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();
@ -81,17 +82,19 @@ class CleanDemoDataTask extends Task
protected function cleanCache()
{
$util = new IndexCourseCacheUtil();
$util = new IndexPageCacheUtil();
$util->rebuild();
$slideListCache = new IndexSlideListCache();
$slideListCache->rebuild();
$categoryListCache = new CategoryListCache();
$categoryAllListCache = new CategoryAllListCache();
$categoryTreeListCache = new CategoryTreeListCache();
foreach (CategoryModel::types() as $key => $value) {
$categoryListCache->rebuild($key);
$categoryAllListCache->rebuild($key);
$categoryTreeListCache->rebuild($key);
}
}
@ -114,7 +117,7 @@ class CleanDemoDataTask extends Task
$user = $userRepo->findById(100015);
return $user ? true : false;
return (bool)$user;
}
}

View File

@ -1,86 +0,0 @@
<?php
/**
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.koogua.com
*/
namespace App\Console\Tasks;
use App\Models\Order as OrderModel;
use App\Repos\FlashSale as FlashSaleRepo;
use App\Services\Logic\FlashSale\Queue as FlashSaleQueue;
use App\Services\Logic\FlashSale\UserOrderCache;
use Phalcon\Mvc\Model\Resultset;
use Phalcon\Mvc\Model\ResultsetInterface;
class CloseFlashSaleOrderTask extends Task
{
public function mainAction()
{
$orders = $this->findOrders();
echo sprintf('pending orders: %s', $orders->count()) . PHP_EOL;
if ($orders->count() == 0) return;
echo '------ start close order task ------' . PHP_EOL;
foreach ($orders as $order) {
$this->incrFlashSaleStock($order->promotion_id);
$this->pushFlashSaleQueue($order->promotion_id);
$this->deleteUserOrderCache($order->owner_id, $order->promotion_id);
$order->status = OrderModel::STATUS_CLOSED;
$order->update();
}
echo '------ end close order task ------' . PHP_EOL;
}
protected function incrFlashSaleStock($saleId)
{
$flashSaleRepo = new FlashSaleRepo();
$flashSale = $flashSaleRepo->findById($saleId);
$flashSale->stock += 1;
$flashSale->update();
}
protected function pushFlashSaleQueue($saleId)
{
$queue = new FlashSaleQueue();
$queue->push($saleId);
}
protected function deleteUserOrderCache($userId, $saleId)
{
$cache = new UserOrderCache();
$cache->delete($userId, $saleId);
}
/**
* 查找待关闭订单
*
* @param int $limit
* @return ResultsetInterface|Resultset|OrderModel[]
*/
protected function findOrders($limit = 1000)
{
$status = OrderModel::STATUS_PENDING;
$type = OrderModel::PROMOTION_FLASH_SALE;
$time = time() - 15 * 60;
return OrderModel::query()
->where('status = :status:', ['status' => $status])
->andWhere('promotion_type = :type:', ['type' => $type])
->andWhere('create_time < :time:', ['time' => $time])
->limit($limit)
->execute();
}
}

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

@ -42,11 +42,9 @@ class CloseOrderTask extends Task
{
$status = OrderModel::STATUS_PENDING;
$time = time() - 12 * 3600;
$type = 0;
return OrderModel::query()
->where('status = :status:', ['status' => $status])
->andWhere('promotion_type = :type:', ['type' => $type])
->andWhere('create_time < :time:', ['time' => $time])
->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);
@ -172,9 +165,7 @@ class DeliverTask extends Task
];
foreach ($orders as $order) {
$case1 = in_array($order->item_type, $itemTypes);
$case2 = $order->promotion_type == 0;
if ($case1 && $case2) {
if (in_array($order->item_type, $itemTypes)) {
$order->status = OrderModel::STATUS_CLOSED;
$order->update();
}

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;
@ -168,7 +165,8 @@ class RefundTask extends Task
protected function handleCourseOrderRefund(OrderModel $order)
{
$courseUserRepo = new CourseUserRepo();
$courseUser = $courseUserRepo->findCourseStudent($order->item_id, $order->owner_id);
$courseUser = $courseUserRepo->findCourseUser($order->item_id, $order->owner_id);
if ($courseUser) {
$courseUser->deleted = 1;
@ -191,7 +189,7 @@ class RefundTask extends Task
foreach ($itemInfo['courses'] as $course) {
$courseUser = $courseUserRepo->findCourseStudent($course['id'], $order->owner_id);
$courseUser = $courseUserRepo->findCourseUser($course['id'], $order->owner_id);
if ($courseUser) {
$courseUser->deleted = 1;
@ -229,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,9 +13,11 @@ use GuzzleHttp\Client;
class SyncAppInfoTask extends Task
{
const API_BASE_URL = 'https://www.koogua.com/api';
public function mainAction()
{
$url = 'https://www.koogua.com/api/instance/collect';
echo '------ start sync app info ------' . PHP_EOL;
$site = $this->getSettings('site');
@ -36,7 +38,11 @@ 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

@ -69,7 +69,7 @@ class SyncLearningTask extends Task
} else {
$dbLearning->duration += $cacheLearning->duration;
$dbLearning->duration = $cacheLearning->duration;
$dbLearning->position = $cacheLearning->position;
$dbLearning->active_time = $cacheLearning->active_time;
@ -188,6 +188,7 @@ class SyncLearningTask extends Task
$courseUser->progress = $progress;
$courseUser->duration = $duration;
$courseUser->active_time = $learning->active_time;
$courseUser->update();
}

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

@ -61,12 +61,15 @@ class AnswerController extends Controller
{
$answerService = new AnswerService();
$publishTypes = $answerService->getPublishTypes();
$answer = $answerService->getAnswer($id);
$questionService = new QuestionService();
$question = $questionService->getQuestion($answer->question_id);
$this->view->setVar('publish_types', $publishTypes);
$this->view->setVar('question', $question);
$this->view->setVar('answer', $answer);
}
@ -219,4 +222,40 @@ class AnswerController extends Controller
$this->view->setVar('reports', $reports);
}
/**
* @Post("/moderate/batch", name="admin.answer.batch_moderate")
*/
public function batchModerateAction()
{
$answerService = new AnswerService();
$answerService->batchModerate();
$location = $this->url->get(['for' => 'admin.mod.answers']);
$content = [
'location' => $location,
'msg' => '批量审核成功',
];
return $this->jsonSuccess($content);
}
/**
* @Post("/delete/batch", name="admin.answer.batch_delete")
*/
public function batchDeleteAction()
{
$answerService = new AnswerService();
$answerService->batchDelete();
$content = [
'location' => $this->request->getHTTPReferer(),
'msg' => '批量删除成功',
];
return $this->jsonSuccess($content);
}
}

View File

@ -38,12 +38,12 @@ class ArticleController extends Controller
$publishTypes = $articleService->getPublishTypes();
$sourceTypes = $articleService->getSourceTypes();
$categories = $articleService->getCategories();
$categoryOptions = $articleService->getCategoryOptions();
$xmTags = $articleService->getXmTags(0);
$this->view->setVar('publish_types', $publishTypes);
$this->view->setVar('source_types', $sourceTypes);
$this->view->setVar('categories', $categories);
$this->view->setVar('category_options', $categoryOptions);
$this->view->setVar('xm_tags', $xmTags);
}
@ -64,11 +64,7 @@ class ArticleController extends Controller
*/
public function addAction()
{
$articleService = new ArticleService();
$categories = $articleService->getCategories();
$this->view->setVar('categories', $categories);
}
/**
@ -80,14 +76,14 @@ class ArticleController extends Controller
$publishTypes = $articleService->getPublishTypes();
$sourceTypes = $articleService->getSourceTypes();
$categories = $articleService->getCategories();
$categoryOptions = $articleService->getCategoryOptions();
$article = $articleService->getArticle($id);
$xmTags = $articleService->getXmTags($id);
$this->view->setVar('article', $article);
$this->view->setVar('publish_types', $publishTypes);
$this->view->setVar('source_types', $sourceTypes);
$this->view->setVar('categories', $categories);
$this->view->setVar('article', $article);
$this->view->setVar('category_options', $categoryOptions);
$this->view->setVar('xm_tags', $xmTags);
}
@ -229,4 +225,40 @@ class ArticleController extends Controller
$this->view->setVar('article', $article);
}
/**
* @Post("/moderate/batch", name="admin.article.batch_moderate")
*/
public function batchModerateAction()
{
$articleService = new ArticleService();
$articleService->batchModerate();
$location = $this->url->get(['for' => 'admin.mod.articles']);
$content = [
'location' => $location,
'msg' => '批量审核成功',
];
return $this->jsonSuccess($content);
}
/**
* @Post("/delete/batch", name="admin.article.batch_delete")
*/
public function batchDeleteAction()
{
$articleService = new ArticleService();
$articleService->batchDelete();
$content = [
'location' => $this->request->getHTTPReferer(),
'msg' => '批量删除成功',
];
return $this->jsonSuccess($content);
}
}

View File

@ -20,19 +20,6 @@ use Phalcon\Mvc\View;
class ChapterController extends Controller
{
/**
* @Get("/{id:[0-9]+}/resources", name="admin.chapter.resources")
*/
public function resourcesAction($id)
{
$chapterService = new ChapterService();
$resources = $chapterService->getResources($id);
$this->view->setRenderLevel(View::LEVEL_ACTION_VIEW);
$this->view->setVar('resources', $resources);
}
/**
* @Get("/{id:[0-9]+}/lessons", name="admin.chapter.lessons")
*/

View File

@ -139,4 +139,40 @@ class CommentController extends Controller
$this->view->setVar('reports', $reports);
}
/**
* @Post("/moderate/batch", name="admin.comment.batch_moderate")
*/
public function batchModerateAction()
{
$commentService = new CommentService();
$commentService->batchModerate();
$location = $this->url->get(['for' => 'admin.mod.comments']);
$content = [
'location' => $location,
'msg' => '批量审核成功',
];
return $this->jsonSuccess($content);
}
/**
* @Post("/delete/batch", name="admin.comment.batch_delete")
*/
public function batchDeleteAction()
{
$commentService = new CommentService();
$commentService->batchDelete();
$content = [
'location' => $this->request->getHTTPReferer(),
'msg' => '批量删除成功',
];
return $this->jsonSuccess($content);
}
}

View File

@ -23,8 +23,10 @@ class ConsultController extends Controller
$consultService = new ConsultService();
$publishTypes = $consultService->getPublishTypes();
$xmCourses = $consultService->getXmCourses();
$this->view->setVar('publish_types', $publishTypes);
$this->view->setVar('xm_courses', $xmCourses);
}
/**
@ -55,8 +57,11 @@ class ConsultController extends Controller
{
$consultService = new ConsultService();
$publishTypes = $consultService->getPublishTypes();
$consult = $consultService->getConsult($id);
$this->view->setVar('publish_types', $publishTypes);
$this->view->setVar('consult', $consult);
}
@ -135,9 +140,47 @@ class ConsultController extends Controller
return $this->jsonSuccess($content);
}
$reasons = $consultService->getReasons();
$consult = $consultService->getConsultInfo($id);
$this->view->setVar('reasons', $reasons);
$this->view->setVar('consult', $consult);
}
/**
* @Post("/moderate/batch", name="admin.consult.batch_moderate")
*/
public function batchModerateAction()
{
$consultService = new ConsultService();
$consultService->batchModerate();
$location = $this->url->get(['for' => 'admin.mod.consults']);
$content = [
'location' => $location,
'msg' => '批量审核成功',
];
return $this->jsonSuccess($content);
}
/**
* @Post("/delete/batch", name="admin.consult.batch_delete")
*/
public function batchDeleteAction()
{
$consultService = new ConsultService();
$consultService->batchDelete();
$content = [
'location' => $this->request->getHTTPReferer(),
'msg' => '批量删除成功',
];
return $this->jsonSuccess($content);
}
}

View File

@ -8,7 +8,10 @@
namespace App\Http\Admin\Controllers;
use App\Http\Admin\Services\Course as CourseService;
use App\Http\Admin\Services\CourseLearning as CourseLearningService;
use App\Http\Admin\Services\CourseUser as CourseUserService;
use App\Models\Category as CategoryModel;
use Phalcon\Mvc\View;
/**
* @RoutePrefix("/admin/course")
@ -36,13 +39,13 @@ class CourseController extends Controller
{
$courseService = new CourseService();
$xmCategories = $courseService->getXmCategories(0);
$xmTeachers = $courseService->getXmTeachers(0);
$categoryOptions = $courseService->getCategoryOptions();
$teacherOptions = $courseService->getTeacherOptions();
$modelTypes = $courseService->getModelTypes();
$levelTypes = $courseService->getLevelTypes();
$this->view->setVar('xm_categories', $xmCategories);
$this->view->setVar('xm_teachers', $xmTeachers);
$this->view->setVar('category_options', $categoryOptions);
$this->view->setVar('teacher_options', $teacherOptions);
$this->view->setVar('model_types', $modelTypes);
$this->view->setVar('level_types', $levelTypes);
}
@ -100,17 +103,23 @@ class CourseController extends Controller
{
$courseService = new CourseService();
$cos = $courseService->getSettings('cos');
$course = $courseService->getCourse($id);
$xmTeachers = $courseService->getXmTeachers($id);
$xmCategories = $courseService->getXmCategories($id);
$xmTags = $courseService->getXmTags($id);
$xmCourses = $courseService->getXmCourses($id);
$levelTypes = $courseService->getLevelTypes();
$categoryOptions = $courseService->getCategoryOptions();
$teacherOptions = $courseService->getTeacherOptions();
$studyExpiryOptions = $courseService->getStudyExpiryOptions();
$refundExpiryOptions = $courseService->getRefundExpiryOptions();
$this->view->setVar('cos', $cos);
$this->view->setVar('course', $course);
$this->view->setVar('xm_teachers', $xmTeachers);
$this->view->setVar('xm_categories', $xmCategories);
$this->view->setVar('xm_tags', $xmTags);
$this->view->setVar('xm_courses', $xmCourses);
$this->view->setVar('level_types', $levelTypes);
$this->view->setVar('category_options', $categoryOptions);
$this->view->setVar('teacher_options', $teacherOptions);
$this->view->setVar('study_expiry_options', $studyExpiryOptions);
$this->view->setVar('refund_expiry_options', $refundExpiryOptions);
}
@ -177,4 +186,91 @@ class CourseController extends Controller
$this->view->setVar('chapters', $chapters);
}
/**
* @Get("/{id:[0-9]+}/resources", name="admin.course.resources")
*/
public function resourcesAction($id)
{
$courseService = new CourseService();
$resources = $courseService->getResources($id);
$this->view->setRenderLevel(View::LEVEL_ACTION_VIEW);
$this->view->setVar('resources', $resources);
}
/**
* @Get("/{id:[0-9]+}/learnings", name="admin.course.learnings")
*/
public function learningsAction($id)
{
$service = new CourseLearningService();
$pager = $service->getLearnings($id);
$this->view->setVar('pager', $pager);
}
/**
* @Get("/{id:[0-9]+}/users", name="admin.course.users")
*/
public function usersAction($id)
{
$service = new CourseService();
$course = $service->getCourse($id);
$service = new CourseUserService();
$pager = $service->getUsers($id);
$this->view->setVar('course', $course);
$this->view->setVar('pager', $pager);
}
/**
* @Get("/{id:[0-9]+}/user/search", name="admin.course.search_user")
*/
public function searchUserAction($id)
{
$service = new CourseService();
$course = $service->getCourse($id);
$service = new CourseUserService();
$sourceTypes = $service->getSourceTypes();
$this->view->pick('course/search_user');
$this->view->setVar('source_types', $sourceTypes);
$this->view->setVar('course', $course);
}
/**
* @Get("/{id:[0-9]+}/user/add", name="admin.course.add_user")
*/
public function addUserAction($id)
{
$service = new CourseService();
$course = $service->getCourse($id);
$this->view->pick('course/add_user');
$this->view->setVar('course', $course);
}
/**
* @Post("/{id:[0-9]+}/user/create", name="admin.course.create_user")
*/
public function createUserAction($id)
{
$service = new CourseUserService();
$service->create($id);
$location = $this->url->get(['for' => 'admin.course.users']);
$content = [
'location' => $location,
'msg' => '添加学员成功',
];
return $this->jsonSuccess($content);
}
}

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