diff --git a/CHANGELOG.md b/CHANGELOG.md index 44b3b1c5..5690757b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,19 @@ +### [v1.2.4](https://gitee.com/koogua/course-tencent-cloud/releases/v1.2.4)(2021-01-10) + +#### 增加 + +- 后台增加上传logo和favicon图标 +- 后台增加公众号自定义菜单配置 +- 课程页增加咨询 + +### 优化 + +- oauth中state参数为安全base64加解码 +- findById参数类型不对时抛出异常 +- task表增加索引加快数据查找 +- markdown内容解析改由后端完成 +- 公众号应答处理逻辑 + ### [v1.2.3](https://gitee.com/koogua/course-tencent-cloud/releases/v1.2.3)(2021-01-03) #### 增加 diff --git a/README.md b/README.md index c082a651..3e0f415a 100644 --- a/README.md +++ b/README.md @@ -2,16 +2,16 @@ ![酷瓜云网课GPL协议开源](https://images.gitee.com/uploads/images/2020/1127/092621_3805cf8f_23592.png) -#### 项目介绍 +### 项目介绍 酷瓜云课堂,依托腾讯云基础服务架构,采用C扩展框架Phalcon开发,GPL-2.0开源协议,致力开源网课系统,开源网校系统,开源在线教育系统。 -![](https://img.shields.io/static/v1?label=release&message=1.2.3&color=blue) -![](https://img.shields.io/static/v1?label=stars&message=160&color=blue) -![](https://img.shields.io/static/v1?label=forks&message=60&color=blue) +![](https://img.shields.io/static/v1?label=release&message=1.2.4&color=blue) +![](https://img.shields.io/static/v1?label=stars&message=168&color=blue) +![](https://img.shields.io/static/v1?label=forks&message=63&color=blue) ![](https://img.shields.io/static/v1?label=license&message=GPL-2.0&color=blue) -#### 系统功能 +### 系统功能 实现了点播、直播、专栏、会员、微聊等,是一个完整的产品,具体功能我也不想写一大堆,自己体验吧! @@ -21,17 +21,19 @@ - 课程数据来源于网络(无实质内容),切莫购买 - 管理后台已禁止数据提交,私密配置已过滤 -演示帐号:**13507083515 / 123456** (前后台通用) - 桌面端演示: - [前台演示](https://ctc.koogua.com) - [后台演示](https://ctc.koogua.com/admin) +演示帐号:100015@163.com / 123456 (前后台通用) + 移动端演示: ![移动端二维码](https://images.gitee.com/uploads/images/2020/1127/093203_265221a2_23592.png) +演示帐号:13507083515 / 123456 + 支付流程演示: - [MySQL提升课程全面讲解MySQL架构设计(0.01元)](https://ctc.koogua.com/order/confirm?item_id=1390&item_type=1) @@ -40,7 +42,18 @@ Tips: 测试支付请用手机号注册一个新账户,以便接收订单通知,以及避免课程无法购买 -#### 项目组件 +即时通讯演示: + +请使用以下两个帐号在不同终端或者浏览器登录,打开微聊界面 + +- 帐号A:100015@163.com / 123456 +- 帐号B:100065@163.com / 123456 + +微信推送演示: + +Tips: 请用手机注册一个新账号,用户中心 -> 关注订阅,扫码关注公众号。之后的登录、购买、退款、直播、咨询等会有消息推送。 + +### 项目组件 - 后台框架:[phalcon 3.4.5](https://phalcon.io) - 前端框架:[layui 2.5.6](https://layui.com), [layim 3.9.5](https://www.layui.com/layim)(已授权) @@ -48,45 +61,27 @@ Tips: 测试支付请用手机号注册一个新账户,以便接收订单通 - 即时通讯:[workerman 3.5.22](https://workerman.net) - 基础依赖:[php7.3](https://php.net), [mysql5.7](https://mysql.com), [redis5.0](https://redis.io) -#### 安装指南 +### 安装指南 - [运行环境搭建](https://gitee.com/koogua/course-tencent-cloud-docker) - [系统服务配置](https://gitee.com/koogua/course-tencent-cloud/wikis) +- [客户终端配置](https://gitee.com/koogua/course-tencent-cloud-app) -#### 开发计划 - -- 桌面端:进行中 -- 移动端:进行中 -- 小程序:待启动 - -#### 意见反馈 +### 意见反馈 - [在线反馈](https://gitee.com/koogua/course-tencent-cloud/issues)(推荐) +- [官方论坛](https://koogua.com/forum)(推荐) - QQ交流群: 787363898 -#### 通过这个项目能学到什么? - -- 项目规划,phalcon,缓存,JWT,即时通讯,全文检索 -- docker,supervisor,devops -- git,linux,php,mysql,redis,nginx - -#### 有阿里云版吗? +### 有阿里云版吗? 阿里云版规划中,之前阿里云服务过期未续费,所以腾讯云版本先出。 -#### 代码有加密吗? +### 代码有加密吗? 所有代码都公开(授权代码除外,例如layim),没有所谓的商业版和付费插件。 -#### 有商业服务吗? - -生存才能发展,我们目前提供的服务包括: - -- 系统安装 -- 系统定制 -- 企业授权 - -#### 开源助力 +### 开源助力 毫无保留的真开源不容易,如果对你有帮助,请给我们 **STAR** !!! diff --git a/app/Console/Tasks/DeliverTask.php b/app/Console/Tasks/DeliverTask.php index ad7c846b..874401a4 100644 --- a/app/Console/Tasks/DeliverTask.php +++ b/app/Console/Tasks/DeliverTask.php @@ -248,12 +248,12 @@ class DeliverTask extends Task { $itemType = TaskModel::TYPE_DELIVER; $status = TaskModel::STATUS_PENDING; - $tryCount = self::TRY_COUNT; + $createTime = strtotime('-3 days'); return TaskModel::query() ->where('item_type = :item_type:', ['item_type' => $itemType]) ->andWhere('status = :status:', ['status' => $status]) - ->andWhere('try_count < :try_count:', ['try_count' => $tryCount + 1]) + ->andWhere('create_time > :create_time:', ['create_time' => $createTime]) ->orderBy('priority ASC') ->limit($limit) ->execute(); diff --git a/app/Console/Tasks/NoticeTask.php b/app/Console/Tasks/NoticeTask.php index 06841554..b736b80c 100644 --- a/app/Console/Tasks/NoticeTask.php +++ b/app/Console/Tasks/NoticeTask.php @@ -125,12 +125,12 @@ class NoticeTask extends Task $status = TaskModel::STATUS_PENDING; - $tryCount = self::TRY_COUNT; + $createTime = strtotime('-1 days'); return TaskModel::query() ->inWhere('item_type', $itemTypes) ->andWhere('status = :status:', ['status' => $status]) - ->andWhere('try_count < :try_count:', ['try_count' => $tryCount + 1]) + ->andWhere('create_time > :create_time:', ['create_time' => $createTime]) ->orderBy('priority ASC') ->limit($limit) ->execute(); diff --git a/app/Console/Tasks/RefundTask.php b/app/Console/Tasks/RefundTask.php index 1697a4e1..7529c242 100644 --- a/app/Console/Tasks/RefundTask.php +++ b/app/Console/Tasks/RefundTask.php @@ -296,12 +296,12 @@ class RefundTask extends Task { $itemType = TaskModel::TYPE_REFUND; $status = TaskModel::STATUS_PENDING; - $tryCount = self::TRY_COUNT; + $createTime = strtotime('-3 days'); return TaskModel::query() ->where('item_type = :item_type:', ['item_type' => $itemType]) ->andWhere('status = :status:', ['status' => $status]) - ->andWhere('try_count < :try_count:', ['try_count' => $tryCount + 1]) + ->andWhere('create_time > :create_time:', ['create_time' => $createTime]) ->orderBy('priority ASC') ->limit($limit) ->execute(); diff --git a/app/Console/Tasks/UpgradeTask.php b/app/Console/Tasks/UpgradeTask.php index 0dbfa0dc..cfd14aab 100644 --- a/app/Console/Tasks/UpgradeTask.php +++ b/app/Console/Tasks/UpgradeTask.php @@ -80,7 +80,7 @@ class UpgradeTask extends Task $redis->del($statsKey); } - echo "start reset metadata..." . PHP_EOL; + echo "end reset metadata..." . PHP_EOL; } /** diff --git a/app/Http/Admin/Controllers/SettingController.php b/app/Http/Admin/Controllers/SettingController.php index 309d6bd8..7d949a67 100644 --- a/app/Http/Admin/Controllers/SettingController.php +++ b/app/Http/Admin/Controllers/SettingController.php @@ -328,9 +328,9 @@ class SettingController extends Controller } /** - * @Route("/wechat", name="admin.setting.wechat") + * @Route("/wechat/oa", name="admin.setting.wechat_oa") */ - public function wechatAction() + public function wechatOaAction() { $settingService = new SettingService(); @@ -340,7 +340,7 @@ class SettingController extends Controller $data = $this->request->getPost(); - $settingService->updateWechatSettings($section, $data); + $settingService->updateWechatOASettings($section, $data); return $this->jsonSuccess(['msg' => '更新配置成功']); @@ -348,6 +348,7 @@ class SettingController extends Controller $oa = $settingService->getWechatOASettings(); + $this->view->pick('setting/wechat_oa'); $this->view->setVar('oa', $oa); } } diff --git a/app/Http/Admin/Controllers/TestController.php b/app/Http/Admin/Controllers/TestController.php index fb398d11..4db114d2 100644 --- a/app/Http/Admin/Controllers/TestController.php +++ b/app/Http/Admin/Controllers/TestController.php @@ -11,6 +11,7 @@ use App\Services\Mail\Test as TestMailService; use App\Services\MyStorage as StorageService; use App\Services\Sms\Test as TestSmsService; use App\Services\Vod as VodService; +use App\Services\Wechat as WechatService; /** * @RoutePrefix("/admin/test") @@ -54,6 +55,24 @@ class TestController extends Controller } } + /** + * @Post("/wechat/oa", name="admin.test.wechat_oa") + */ + public function wechatOaAction() + { + $wechatService = new WechatService(); + + $oa = $wechatService->getOfficialAccount(); + + $result = $oa->qrcode->temporary('foo', 86400); + + if (isset($result['ticket'])) { + return $this->jsonSuccess(['msg' => '接口返回成功']); + } else { + return $this->jsonError(['msg' => '接口返回失败,请检查相关配置']); + } + } + /** * @Get("/live/push", name="admin.test.live_push") */ diff --git a/app/Http/Admin/Services/AuthNode.php b/app/Http/Admin/Services/AuthNode.php index 89b75942..77104b1d 100644 --- a/app/Http/Admin/Services/AuthNode.php +++ b/app/Http/Admin/Services/AuthNode.php @@ -759,9 +759,9 @@ class AuthNode extends Service ], [ 'id' => '5-1-13', - 'title' => '微信平台', + 'title' => '微信公众号', 'type' => 'menu', - 'route' => 'admin.setting.wechat', + 'route' => 'admin.setting.wechat_oa', ], ], ], diff --git a/app/Http/Admin/Services/Setting.php b/app/Http/Admin/Services/Setting.php index 92ade54d..87e2b6a4 100644 --- a/app/Http/Admin/Services/Setting.php +++ b/app/Http/Admin/Services/Setting.php @@ -5,6 +5,7 @@ namespace App\Http\Admin\Services; use App\Caches\Setting as SettingCache; use App\Repos\Setting as SettingRepo; use App\Repos\Vip as VipRepo; +use App\Services\Wechat as WechatService; class Setting extends Service { @@ -63,6 +64,26 @@ class Setting extends Service $oa['notify_url'] = $oa['notify_url'] ?: kg_full_url(['for' => 'home.wechat.oa.notify']); + $oa['menu'] = json_decode($oa['menu'], true); + + /** + * 构造一个3*5的二维树形菜单 + */ + for ($i = 0; $i < 3; $i++) { + if (!isset($oa['menu'][$i])) { + $oa['menu'][$i] = ['name' => sprintf('菜单%s', $i + 1)]; + } + for ($j = 0; $j < 5; $j++) { + if (!isset($oa['menu'][$i]['children'][$j])) { + $oa['menu'][$i]['children'][$j] = [ + 'type' => 'view', + 'name' => '', + 'url' => '', + ];; + } + } + } + return $oa; } @@ -171,12 +192,36 @@ class Setting extends Service } } - public function updateWechatSettings($section, $settings) + public function updateWechatOASettings($section, $settings) { - if ($section == 'wechat.oa') { - if (isset($settings['notice_template'])) { - $settings['notice_template'] = kg_json_encode($settings['notice_template']); + if (!empty($settings['notice_template'])) { + $settings['notice_template'] = kg_json_encode($settings['notice_template']); + } + + $buttons = []; + + if (!empty($settings['menu'])) { + foreach ($settings['menu'] as $i => $top) { + $buttons[$i]['name'] = $top['name']; + $buttons[$i]['url'] = $top['url']; + $buttons[$i]['type'] = 'view'; + foreach ($top['children'] as $j => $sub) { + if (!empty($sub['name']) && !empty($sub['url'])) { + $buttons[$i]['sub_button'][$j]['name'] = $sub['name']; + $buttons[$i]['sub_button'][$j]['url'] = $sub['url']; + $buttons[$i]['sub_button'][$j]['type'] = 'view'; + } else { + unset($settings['menu'][$i]['children'][$j]); + } + } } + $settings['menu'] = kg_json_encode($settings['menu']); + } + + if (!empty($buttons)) { + $service = new WechatService(); + $oa = $service->getOfficialAccount(); + $oa->menu->create($buttons); } $this->updateSettings($section, $settings); diff --git a/app/Http/Admin/Views/setting/site.volt b/app/Http/Admin/Views/setting/site.volt index 11b91cb5..5067bfc6 100644 --- a/app/Http/Admin/Views/setting/site.volt +++ b/app/Http/Admin/Views/setting/site.volt @@ -31,6 +31,32 @@ +
+
+ +
+ +
+
+
+
+ +
+
+
+
+
+ +
+ +
+
+
+
+ +
+
+
@@ -120,10 +146,11 @@ diff --git a/app/Http/Admin/Views/setting/wechat.volt b/app/Http/Admin/Views/setting/wechat.volt deleted file mode 100644 index a37d7091..00000000 --- a/app/Http/Admin/Views/setting/wechat.volt +++ /dev/null @@ -1,16 +0,0 @@ -{% extends 'templates/main.volt' %} - -{% block content %} - -
-
    -
  • 公众号
  • -
-
-
- {{ partial('setting/wechat_oa') }} -
-
-
- -{% endblock %} \ No newline at end of file diff --git a/app/Http/Admin/Views/setting/wechat_oa.volt b/app/Http/Admin/Views/setting/wechat_oa.volt index 97702aa3..faad9ad7 100644 --- a/app/Http/Admin/Views/setting/wechat_oa.volt +++ b/app/Http/Admin/Views/setting/wechat_oa.volt @@ -1,104 +1,24 @@ -{% set notice_template = oa.notice_template|json_decode %} +{% extends 'templates/main.volt' %} -
-
- -
- - +{% block content %} + +
+
    +
  • 基本设置
  • +
  • 模板消息
  • +
  • 自定义菜单
  • +
+
+
+ {{ partial('setting/wechat_oa_basic') }} +
+
+ {{ partial('setting/wechat_oa_notice') }} +
+
+ {{ partial('setting/wechat_oa_menu') }} +
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- - - -
-
- -
- 模板配置 -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
名称模板编号
登录成功通知
购买成功提醒
退款成功通知
课程直播提醒
咨询结果通知
-
-
- -
- - - -
-
-
\ No newline at end of file + +{% endblock %} \ No newline at end of file diff --git a/app/Http/Admin/Views/setting/wechat_oa_basic.volt b/app/Http/Admin/Views/setting/wechat_oa_basic.volt new file mode 100644 index 00000000..84e952c5 --- /dev/null +++ b/app/Http/Admin/Views/setting/wechat_oa_basic.volt @@ -0,0 +1,66 @@ +
+
+ +
+ + +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ + + +
+
+
+ +
+
+ 接口测试 +
+
+ +
+ +
+
+
+ +
+ + +
+
+
\ No newline at end of file diff --git a/app/Http/Admin/Views/setting/wechat_oa_menu.volt b/app/Http/Admin/Views/setting/wechat_oa_menu.volt new file mode 100644 index 00000000..0c34b148 --- /dev/null +++ b/app/Http/Admin/Views/setting/wechat_oa_menu.volt @@ -0,0 +1,42 @@ +
+ + + + + + + + + + + + + + + {% for i,top in oa.menu %} + + + + + + {% for j,sub in top.children %} + + + + + + {% endfor %} + {% endfor %} + +
层级名称链接
├──
├──
+
+
+ +
+ + + +
+
+
+ diff --git a/app/Http/Admin/Views/setting/wechat_oa_notice.volt b/app/Http/Admin/Views/setting/wechat_oa_notice.volt new file mode 100644 index 00000000..0b7eee16 --- /dev/null +++ b/app/Http/Admin/Views/setting/wechat_oa_notice.volt @@ -0,0 +1,47 @@ +{% set notice_template = oa.notice_template|json_decode %} + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
模板名称模板编号
登录成功通知
购买成功提醒
退款成功通知
课程直播提醒
咨询结果通知
+
+
+ +
+ + + +
+
+
\ No newline at end of file diff --git a/app/Http/Home/Controllers/ErrorController.php b/app/Http/Home/Controllers/ErrorController.php index a0155342..dfa6f7e1 100644 --- a/app/Http/Home/Controllers/ErrorController.php +++ b/app/Http/Home/Controllers/ErrorController.php @@ -2,6 +2,8 @@ namespace App\Http\Home\Controllers; +use App\Models\User as UserModel; +use App\Services\Auth\Home as HomeAuth; use App\Services\Service as AppService; use App\Traits\Response as ResponseTrait; @@ -11,8 +13,27 @@ use App\Traits\Response as ResponseTrait; class ErrorController extends \Phalcon\Mvc\Controller { + /** + * @var array + */ + protected $siteInfo; + + /** + * @var UserModel + */ + protected $authUser; + use ResponseTrait; + public function initialize() + { + $this->siteInfo = $this->getSiteInfo(); + $this->authUser = $this->getAuthUser(); + + $this->view->setVar('site_info', $this->siteInfo); + $this->view->setVar('auth_user', $this->authUser); + } + /** * @Get("/400", name="home.error.400") */ @@ -82,4 +103,21 @@ class ErrorController extends \Phalcon\Mvc\Controller $this->view->setVar('message', $siteInfo['closed_tips']); } + protected function getSiteInfo() + { + $appService = new AppService(); + + return $appService->getSettings('site'); + } + + protected function getAuthUser() + { + /** + * @var HomeAuth $auth + */ + $auth = $this->getDI()->get('auth'); + + return $auth->getCurrentUser(); + } + } diff --git a/app/Http/Home/Controllers/HelpController.php b/app/Http/Home/Controllers/HelpController.php index d525a80a..22d7bc29 100644 --- a/app/Http/Home/Controllers/HelpController.php +++ b/app/Http/Home/Controllers/HelpController.php @@ -2,6 +2,7 @@ namespace App\Http\Home\Controllers; +use App\Http\Home\Services\Index as IndexService; use App\Services\Logic\Help\HelpInfo as HelpInfoService; use App\Services\Logic\Help\HelpList as HelpListService; @@ -12,7 +13,7 @@ class HelpController extends Controller { /** - * @Get("/index", name="home.help.index") + * @Get("/", name="home.help.index") */ public function indexAction() { @@ -34,9 +35,19 @@ class HelpController extends Controller $help = $service->handle($id); + $featuredCourses = $this->getFeaturedCourses(); + $this->seo->prependTitle(['帮助', $help['title']]); $this->view->setVar('help', $help); + $this->view->setVar('featured_courses', $featuredCourses); + } + + protected function getFeaturedCourses() + { + $service = new IndexService(); + + return $service->getSimpleFeaturedCourses(); } } diff --git a/app/Http/Home/Controllers/LayerController.php b/app/Http/Home/Controllers/LayerController.php index 2d15d84b..7a57aacf 100644 --- a/app/Http/Home/Controllers/LayerController.php +++ b/app/Http/Home/Controllers/LayerController.php @@ -4,6 +4,7 @@ namespace App\Http\Home\Controllers; use App\Models\User as UserModel; use App\Services\Auth\Home as HomeAuth; +use App\Services\Service as AppService; use App\Traits\Response as ResponseTrait; use App\Traits\Security as SecurityTrait; use Phalcon\Mvc\Dispatcher; @@ -11,6 +12,11 @@ use Phalcon\Mvc\Dispatcher; class LayerController extends \Phalcon\Mvc\Controller { + /** + * @var array + */ + protected $siteInfo; + /** * @var UserModel */ @@ -33,11 +39,20 @@ class LayerController extends \Phalcon\Mvc\Controller public function initialize() { + $this->siteInfo = $this->getSiteInfo(); $this->authUser = $this->getAuthUser(); + $this->view->setVar('site_info', $this->siteInfo); $this->view->setVar('auth_user', $this->authUser); } + protected function getSiteInfo() + { + $appService = new AppService(); + + return $appService->getSettings('site'); + } + protected function getAuthUser() { /** diff --git a/app/Http/Home/Controllers/PageController.php b/app/Http/Home/Controllers/PageController.php index 6796d63d..38b31f97 100644 --- a/app/Http/Home/Controllers/PageController.php +++ b/app/Http/Home/Controllers/PageController.php @@ -2,6 +2,7 @@ namespace App\Http\Home\Controllers; +use App\Http\Home\Services\Index as IndexService; use App\Services\Logic\Page\PageInfo as PageInfoService; /** @@ -19,9 +20,19 @@ class PageController extends Controller $page = $service->handle($id); - $this->seo->prependTitle(['单页', $page['title']]); + $featuredCourses = $this->getFeaturedCourses(); + + $this->seo->prependTitle($page['title']); $this->view->setVar('page', $page); + $this->view->setVar('featured_courses', $featuredCourses); + } + + protected function getFeaturedCourses() + { + $service = new IndexService(); + + return $service->getSimpleFeaturedCourses(); } } diff --git a/app/Http/Home/Services/WechatOfficialAccount.php b/app/Http/Home/Services/WechatOfficialAccount.php index ea19fd02..6fd0e48c 100644 --- a/app/Http/Home/Services/WechatOfficialAccount.php +++ b/app/Http/Home/Services/WechatOfficialAccount.php @@ -3,9 +3,9 @@ namespace App\Http\Home\Services; use App\Models\WechatSubscribe as WechatSubscribeModel; +use App\Repos\User as UserRepo; use App\Repos\WechatSubscribe as WechatSubscribeRepo; use App\Services\Wechat as WechatService; -use App\Validators\User as UserValidator; use EasyWeChat\Kernel\Messages\Text as TextMessage; class WechatOfficialAccount extends Service @@ -50,7 +50,7 @@ class WechatOfficialAccount extends Service { $service = new WechatService(); - $service->logger->debug('Received Message ' . json_encode($message)); + $service->logger->info('Received Message ' . json_encode($message)); switch ($message['MsgType']) { case 'event': @@ -74,7 +74,7 @@ class WechatOfficialAccount extends Service return $this->handleLocationEvent($message); break; default: - return $this->emptyReplyMessage(); + return $this->noMatchReply(); break; } break; @@ -100,7 +100,7 @@ class WechatOfficialAccount extends Service return $this->handleLinkReply($message); break; default: - return $this->emptyReplyMessage(); + return $this->noMatchReply(); break; } } @@ -108,16 +108,16 @@ class WechatOfficialAccount extends Service protected function handleSubscribeEvent($message) { $openId = $message['FromUserName'] ?? ''; - $eventKey = $message['EventKey'] ?? ''; - if (!$eventKey) { - return $this->emptyReplyMessage(); + $subscribeRepo = new WechatSubscribeRepo(); + + $subscribe = $subscribeRepo->findByOpenId($openId); + + if ($subscribe && $subscribe->deleted == 1) { + $subscribe->deleted = 0; + $subscribe->update(); } - $userId = str_replace('qrscene_', '', $eventKey); - - $this->handleSubscribeRelation($userId, $openId); - return new TextMessage('开心呀,我们又多了一个小伙伴!'); } @@ -129,7 +129,7 @@ class WechatOfficialAccount extends Service $subscribe = $subscribeRepo->findByOpenId($openId); - if ($subscribe) { + if ($subscribe && $subscribe->deleted == 0) { $subscribe->deleted = 1; $subscribe->update(); } @@ -139,100 +139,95 @@ class WechatOfficialAccount extends Service protected function handleScanEvent($message) { - /** - * 注意:当已关注过用户扫码时,"EventKey"没有带"qrscene_"前缀 - */ $openId = $message['FromUserName'] ?? ''; $eventKey = $message['EventKey'] ?? ''; - $userId = $eventKey; - $this->handleSubscribeRelation($userId, $openId); - } + $userId = str_replace('qrscene_', '', $eventKey); - protected function handleClickEvent($message) - { - $this->defaultReplyMessage(); - } + $userRepo = new UserRepo(); - protected function handleViewEvent($message) - { - $this->defaultReplyMessage(); - } + $user = $userRepo->findById($userId); - protected function handleLocationEvent($message) - { - $this->defaultReplyMessage(); - } - - protected function handleTextReply($message) - { - return $this->defaultReplyMessage(); - } - - protected function handleImageReply($message) - { - return $this->defaultReplyMessage(); - } - - protected function handleVoiceReply($message) - { - return $this->defaultReplyMessage(); - } - - protected function handleVideoReply($message) - { - return $this->defaultReplyMessage(); - } - - protected function handleShortVideoReply($message) - { - return $this->defaultReplyMessage(); - } - - protected function handleLocationReply($message) - { - return $this->defaultReplyMessage(); - } - - protected function handleLinkReply($message) - { - return $this->defaultReplyMessage(); - } - - protected function emptyReplyMessage() - { - return new TextMessage(''); - } - - protected function defaultReplyMessage() - { - return new TextMessage('没有匹配的服务,如有需要请联系客服!'); - } - - protected function handleSubscribeRelation($userId, $openId) - { - $validator = new UserValidator(); - - $validator->checkUser($userId); + if (!$user) return; $subscribeRepo = new WechatSubscribeRepo(); $subscribe = $subscribeRepo->findByOpenId($openId); if ($subscribe) { + if ($subscribe->user_id != $userId) { + $subscribe->user_id = $userId; + } if ($subscribe->deleted == 1) { $subscribe->deleted = 0; - $subscribe->update(); } + $subscribe->update(); } else { - $subscribe = $subscribeRepo->findSubscribe($userId, $openId); - if (!$subscribe) { - $subscribe = new WechatSubscribeModel(); - $subscribe->user_id = $userId; - $subscribe->open_id = $openId; - $subscribe->create(); - } + $subscribe = new WechatSubscribeModel(); + $subscribe->user_id = $userId; + $subscribe->open_id = $openId; + $subscribe->create(); } } + protected function handleClickEvent($message) + { + return $this->emptyReply(); + } + + protected function handleViewEvent($message) + { + return $this->emptyReply(); + } + + protected function handleLocationEvent($message) + { + return $this->emptyReply(); + } + + protected function handleTextReply($message) + { + return $this->emptyReply(); + } + + protected function handleImageReply($message) + { + return $this->emptyReply(); + } + + protected function handleVoiceReply($message) + { + return $this->emptyReply(); + } + + protected function handleVideoReply($message) + { + return $this->emptyReply(); + } + + protected function handleShortVideoReply($message) + { + return $this->emptyReply(); + } + + protected function handleLocationReply($message) + { + return $this->emptyReply(); + } + + protected function handleLinkReply($message) + { + return $this->emptyReply(); + } + + protected function emptyReply() + { + return null; + } + + protected function noMatchReply() + { + return new TextMessage('没有匹配的服务哦!'); + } + } diff --git a/app/Http/Home/Views/consult/add.volt b/app/Http/Home/Views/consult/add.volt index 17b792ee..6e1f5706 100644 --- a/app/Http/Home/Views/consult/add.volt +++ b/app/Http/Home/Views/consult/add.volt @@ -21,6 +21,7 @@ +
diff --git a/app/Http/Home/Views/consult/show.volt b/app/Http/Home/Views/consult/show.volt index 76a730b9..b9b6d0d5 100644 --- a/app/Http/Home/Views/consult/show.volt +++ b/app/Http/Home/Views/consult/show.volt @@ -4,24 +4,24 @@ {% set consult.answer = consult.answer ? consult.answer : '请耐心等待回复吧' %} -
+
{% if consult.course.id is defined %} -
+
课程:
{{ consult.course.title }}
{% endif %} {% if consult.chapter.id is defined %} -
+
章节:
{{ consult.chapter.title }}
{% endif %} -
+
咨询:
{{ consult.question }}
-
+
回复:
{{ consult.answer }}
diff --git a/app/Http/Home/Views/course/show.volt b/app/Http/Home/Views/course/show.volt index 6f24937c..e10584ed 100644 --- a/app/Http/Home/Views/course/show.volt +++ b/app/Http/Home/Views/course/show.volt @@ -4,10 +4,11 @@ {{ partial('macros/course') }} - {% set favorite_title = course.me.favorited ? '取消收藏' : '收藏' %} + {% set favorite_title = course.me.favorited ? '取消收藏' : '收藏课程' %} {% set favorite_star = course.me.favorited ? 'layui-icon-star-fill' : 'layui-icon-star' %} {% set full_course_url = full_url({'for':'home.course.show','id':course.id}) %} {% set favorite_url = url({'for':'home.course.favorite','id':course.id}) %} + {% set consult_url = url({'for':'home.consult.add'},{'course_id':course.id}) %} {% set qrcode_url = url({'for':'home.qrcode'},{'text':full_course_url}) %}
-
{{ course.details }}
+
{{ course.details }}
{% if show_tab_packages %} {% set packages_url = url({'for':'home.course.packages','id':course.id}) %} @@ -108,14 +112,12 @@ {% block link_css %} - {{ css_link('https://cdn.jsdelivr.net/npm/vditor/dist/index.css', false) }} + {{ css_link('home/css/markdown.css') }} {% endblock %} {% block include_js %} - {{ js_include('https://cdn.jsdelivr.net/npm/vditor/dist/method.min.js', false) }} - {{ js_include('home/js/markdown.preview.js') }} {{ js_include('home/js/course.show.js') }} {{ js_include('home/js/course.share.js') }} diff --git a/app/Http/Home/Views/course/show_order.volt b/app/Http/Home/Views/course/show_order.volt index c7420072..ea89b2c9 100644 --- a/app/Http/Home/Views/course/show_order.volt +++ b/app/Http/Home/Views/course/show_order.volt @@ -1,8 +1,12 @@ {% if course.me.owned == 0 and course.market_price > 0 %} {% set order_url = url({'for':'home.order.confirm'},{'item_id':course.id,'item_type':1}) %} - + {% set live_model_ok = course.model == 2 and course.attrs.end_date < date('Y-m-d') %} + {% set other_model_ok = course.model != 2 %} + {% if live_model_ok or other_model_ok %} + + {% endif %} {% endif %} {% if course.market_price == 0 %} diff --git a/app/Http/Home/Views/help/show.volt b/app/Http/Home/Views/help/show.volt index 79acca71..b6682c6e 100644 --- a/app/Http/Home/Views/help/show.volt +++ b/app/Http/Home/Views/help/show.volt @@ -2,6 +2,8 @@ {% block content %} + {{ partial('macros/course') }} + -
-
{{ help.content }}
+
+
+
+
{{ help.content }}
+
+
+
+ {% if featured_courses %} + + {% endif %} +
{% endblock %} {% block link_css %} - {{ css_link('https://cdn.jsdelivr.net/npm/vditor/dist/index.css', false) }} - -{% endblock %} - -{% block include_js %} - - {{ js_include('https://cdn.jsdelivr.net/npm/vditor/dist/method.min.js', false) }} - {{ js_include('home/js/markdown.preview.js') }} + {{ css_link('home/css/markdown.css') }} {% endblock %} \ No newline at end of file diff --git a/app/Http/Home/Views/page/show.volt b/app/Http/Home/Views/page/show.volt index 231f2885..023dfa76 100644 --- a/app/Http/Home/Views/page/show.volt +++ b/app/Http/Home/Views/page/show.volt @@ -2,29 +2,41 @@ {% block content %} + {{ partial('macros/course') }} + -
-
{{ page.content }}
+
+
+
+
{{ page.content }}
+
+
+
+ {% if featured_courses %} + + {% endif %} +
{% endblock %} {% block link_css %} - {{ css_link('https://cdn.jsdelivr.net/npm/vditor/dist/index.css', false) }} - -{% endblock %} - -{% block include_js %} - - {{ js_include('https://cdn.jsdelivr.net/npm/vditor/dist/method.min.js', false) }} - {{ js_include('home/js/markdown.preview.js') }} + {{ css_link('home/css/markdown.css') }} {% endblock %} \ No newline at end of file diff --git a/app/Http/Home/Views/partials/header.volt b/app/Http/Home/Views/partials/header.volt index fbb2232b..1222e867 100644 --- a/app/Http/Home/Views/partials/header.volt +++ b/app/Http/Home/Views/partials/header.volt @@ -1,4 +1,10 @@ - +