diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d08a790..6cb084df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,24 @@ +### [v1.2.7](https://gitee.com/koogua/course-tencent-cloud/releases/v1.2.7)(2021-02-26) + +### 新增 + +- 钉钉机器人群消息通知 +- demo分支重置演示帐号计划任务 +- 添加学员自动加入相关课程群组 +- 后台查看积分记录 + +### 更新 + +- 路由重命名 admin.group -> admin.im_group +- 路由重命名 home.group -> home.im_group +- 样式重命名 sidebar-teacher-card -> sidebar-user-card +- 去除顶部积分导航 +- 用户中心部分样式调整 +- 后台部分导航调整 +- 不能删除课程教师问题 +- 积分模块可通过后台控制是否启用 +- 解除好友关系后好友数量未递减 + ### [v1.2.6](https://gitee.com/koogua/course-tencent-cloud/releases/v1.2.6)(2021-02-20) ### 新增 diff --git a/app/Console/Tasks/CleanLogTask.php b/app/Console/Tasks/CleanLogTask.php index e198d702..581d6163 100644 --- a/app/Console/Tasks/CleanLogTask.php +++ b/app/Console/Tasks/CleanLogTask.php @@ -26,6 +26,7 @@ class CleanLogTask extends Task $this->cleanOrderLog(); $this->cleanRefundLog(); $this->cleanPointLog(); + $this->cleanDingTalkLog(); $this->cleanNoticeLog(); $this->cleanOtherLog(); } @@ -234,6 +235,18 @@ class CleanLogTask extends Task $this->whitelist[] = $type; } + /** + * 清理钉钉日志 + */ + protected function cleanDingTalkLog() + { + $type = 'dingtalk'; + + $this->cleanLog($type, 7); + + $this->whitelist[] = $type; + } + /** * 清理通知日志 */ diff --git a/app/Console/Tasks/DeliverTask.php b/app/Console/Tasks/DeliverTask.php index d41a22b7..e15007da 100644 --- a/app/Console/Tasks/DeliverTask.php +++ b/app/Console/Tasks/DeliverTask.php @@ -21,17 +21,13 @@ use Phalcon\Mvc\Model\ResultsetInterface; class DeliverTask extends Task { - const TRY_COUNT = 3; - public function mainAction() { $logger = $this->getLogger('order'); $tasks = $this->findTasks(30); - if ($tasks->count() == 0) { - return; - } + if ($tasks->count() == 0) return; $orderRepo = new OrderRepo(); @@ -84,7 +80,7 @@ class DeliverTask extends Task $task->try_count += 1; $task->priority += 1; - if ($task->try_count > self::TRY_COUNT) { + if ($task->try_count > $task->max_try_count) { $task->status = TaskModel::STATUS_FAILED; } diff --git a/app/Console/Tasks/NoticeTask.php b/app/Console/Tasks/NoticeTask.php index 7d17318d..8d3abe45 100644 --- a/app/Console/Tasks/NoticeTask.php +++ b/app/Console/Tasks/NoticeTask.php @@ -3,6 +3,10 @@ namespace App\Console\Tasks; use App\Models\Task as TaskModel; +use App\Services\DingTalk\Notice\ConsultCreate as ConsultCreateNotice; +use App\Services\DingTalk\Notice\CustomService as CustomServiceNotice; +use App\Services\DingTalk\Notice\ServerMonitor as ServerMonitorNotice; +use App\Services\DingTalk\Notice\TeacherLive as TeacherLiveNotice; use App\Services\Logic\Notice\AccountLogin as AccountLoginNotice; use App\Services\Logic\Notice\ConsultReply as ConsultReplyNotice; use App\Services\Logic\Notice\LiveBegin as LiveBeginNotice; @@ -14,8 +18,6 @@ use Phalcon\Mvc\Model\ResultsetInterface; class NoticeTask extends Task { - const TRY_COUNT = 3; - public function mainAction() { $logger = $this->getLogger('notice'); @@ -46,6 +48,18 @@ class NoticeTask extends Task case TaskModel::TYPE_NOTICE_CONSULT_REPLY: $this->handleConsultReplyNotice($task); break; + case TaskModel::TYPE_NOTICE_CONSULT_CREATE: + $this->handleConsultCreateNotice($task); + break; + case TaskModel::TYPE_NOTICE_TEACHER_LIVE: + $this->handleTeacherLiveNotice($task); + break; + case TaskModel::TYPE_NOTICE_SERVER_MONITOR: + $this->handleServerMonitorNotice($task); + break; + case TaskModel::TYPE_NOTICE_CUSTOM_SERVICE: + $this->handleCustomServiceNotice($task); + break; } $task->status = TaskModel::STATUS_FINISHED; @@ -57,7 +71,7 @@ class NoticeTask extends Task $task->try_count += 1; $task->priority += 1; - if ($task->try_count > self::TRY_COUNT) { + if ($task->try_count >= $task->max_try_count) { $task->status = TaskModel::STATUS_FAILED; } @@ -77,42 +91,70 @@ class NoticeTask extends Task { $notice = new AccountLoginNotice(); - return $notice->handleTask($task); + $notice->handleTask($task); } protected function handleLiveBeginNotice(TaskModel $task) { $notice = new LiveBeginNotice(); - return $notice->handleTask($task); + $notice->handleTask($task); } protected function handleOrderFinishNotice(TaskModel $task) { $notice = new OrderFinishNotice(); - return $notice->handleTask($task); + $notice->handleTask($task); } protected function handleRefundFinishNotice(TaskModel $task) { $notice = new RefundFinishNotice(); - return $notice->handleTask($task); + $notice->handleTask($task); } protected function handleConsultReplyNotice(TaskModel $task) { $notice = new ConsultReplyNotice(); - return $notice->handleTask($task); + $notice->handleTask($task); + } + + protected function handleConsultCreateNotice(TaskModel $task) + { + $notice = new ConsultCreateNotice(); + + $notice->handleTask($task); + } + + protected function handleTeacherLiveNotice(TaskModel $task) + { + $notice = new TeacherLiveNotice(); + + $notice->handleTask($task); + } + + protected function handleServerMonitorNotice(TaskModel $task) + { + $notice = new ServerMonitorNotice(); + + $notice->handleTask($task); + } + + protected function handleCustomServiceNotice(TaskModel $task) + { + $notice = new CustomServiceNotice(); + + $notice->handleTask($task); } /** * @param int $limit * @return ResultsetInterface|Resultset|TaskModel[] */ - protected function findTasks($limit = 100) + protected function findTasks($limit = 300) { $itemTypes = [ TaskModel::TYPE_NOTICE_ACCOUNT_LOGIN, @@ -120,6 +162,10 @@ class NoticeTask extends Task TaskModel::TYPE_NOTICE_ORDER_FINISH, TaskModel::TYPE_NOTICE_REFUND_FINISH, TaskModel::TYPE_NOTICE_CONSULT_REPLY, + TaskModel::TYPE_NOTICE_CONSULT_CREATE, + TaskModel::TYPE_NOTICE_TEACHER_LIVE, + TaskModel::TYPE_NOTICE_SERVER_MONITOR, + TaskModel::TYPE_NOTICE_CUSTOM_SERVICE, ]; $status = TaskModel::STATUS_PENDING; diff --git a/app/Console/Tasks/OptimizeTableTask.php b/app/Console/Tasks/OptimizeTableTask.php new file mode 100644 index 00000000..7143c0b7 --- /dev/null +++ b/app/Console/Tasks/OptimizeTableTask.php @@ -0,0 +1,71 @@ +optimizeImMessageTable(); + $this->optimizeLearningTable(); + $this->optimizeTaskTable(); + } + + protected function optimizeImMessageTable() + { + $count = ImMessageModel::count(); + + if ($count < 1000000) return; + + $messageModel = new ImMessageModel(); + + $tableName = $messageModel->getSource(); + + $this->db->delete($tableName, "create_time < :create_time", [ + 'create_time' => strtotime('-6 months'), + ]); + + $this->db->execute("OPTIMIZE TABLE {$tableName}"); + } + + protected function optimizeLearningTable() + { + $count = LearningModel::count(); + + if ($count < 1000000) return; + + $learningModel = new LearningModel(); + + $tableName = $learningModel->getSource(); + + $this->db->delete($tableName, "create_time < :create_time", [ + 'create_time' => strtotime('-6 months'), + ]); + + $this->db->execute("OPTIMIZE TABLE {$tableName}"); + } + + protected function optimizeTaskTable() + { + $count = TaskModel::count(); + + if ($count < 1000000) return; + + $taskModel = new TaskModel(); + + $tableName = $taskModel->getSource(); + + $this->db->delete($tableName, "create_time < :create_time AND status > :status", [ + 'create_time' => strtotime('-6 months'), + 'status' => TaskModel::STATUS_PENDING, + ]); + + $this->db->execute("OPTIMIZE TABLE {$tableName}"); + } + +} \ No newline at end of file diff --git a/app/Console/Tasks/PointGiftDeliverTask.php b/app/Console/Tasks/PointGiftDeliverTask.php index 0f8baac9..1af243e7 100644 --- a/app/Console/Tasks/PointGiftDeliverTask.php +++ b/app/Console/Tasks/PointGiftDeliverTask.php @@ -13,6 +13,7 @@ use App\Repos\ImGroup as ImGroupRepo; use App\Repos\ImGroupUser as ImGroupUserRepo; use App\Repos\PointGift as PointGiftRepo; use App\Repos\PointRedeem as PointRedeemRepo; +use App\Services\DingTalk\Notice\PointRedeem as PointRedeemNotice; use App\Services\Logic\Point\PointHistory as PointHistoryService; use Phalcon\Mvc\Model\Resultset; use Phalcon\Mvc\Model\ResultsetInterface; @@ -20,17 +21,13 @@ use Phalcon\Mvc\Model\ResultsetInterface; class PointGiftDeliverTask extends Task { - const TRY_COUNT = 3; - public function mainAction() { $logger = $this->getLogger('point'); $tasks = $this->findTasks(30); - if ($tasks->count() == 0) { - return; - } + if ($tasks->count() == 0) return; $redeemRepo = new PointRedeemRepo(); @@ -77,7 +74,7 @@ class PointGiftDeliverTask extends Task $task->try_count += 1; $task->priority += 1; - if ($task->try_count > self::TRY_COUNT) { + if ($task->try_count > $task->max_try_count) { $task->status = TaskModel::STATUS_FAILED; } @@ -167,7 +164,9 @@ class PointGiftDeliverTask extends Task protected function handleGoodsRedeem(PointRedeemModel $redeem) { + $notice = new PointRedeemNotice(); + $notice->createTask($redeem); } protected function handleCashRedeem(PointRedeemModel $redeem) diff --git a/app/Console/Tasks/RefundTask.php b/app/Console/Tasks/RefundTask.php index 41e04a51..9689542c 100644 --- a/app/Console/Tasks/RefundTask.php +++ b/app/Console/Tasks/RefundTask.php @@ -20,20 +20,13 @@ use Phalcon\Mvc\Model\ResultsetInterface; class RefundTask extends Task { - /** - * 重试次数 - */ - const TRY_COUNT = 3; - public function mainAction() { $logger = $this->getLogger('refund'); $tasks = $this->findTasks(30); - if ($tasks->count() == 0) { - return; - } + if ($tasks->count() == 0) return; $tradeRepo = new TradeRepo(); $orderRepo = new OrderRepo(); @@ -96,7 +89,7 @@ class RefundTask extends Task $task->try_count += 1; $task->priority += 1; - if ($task->try_count > self::TRY_COUNT) { + if ($task->try_count > $task->max_try_count) { $task->status = TaskModel::STATUS_FAILED; } diff --git a/app/Console/Tasks/ServerMonitorTask.php b/app/Console/Tasks/ServerMonitorTask.php new file mode 100644 index 00000000..7eff21ca --- /dev/null +++ b/app/Console/Tasks/ServerMonitorTask.php @@ -0,0 +1,220 @@ +getSettings('dingtalk.robot'); + + if ($robot['enabled'] == 0) return; + + $items = [ + 'cpu' => $this->checkCpu(), + 'memory' => $this->checkMemory(), + 'disk' => $this->checkDisk(), + 'mysql' => $this->checkMysql(), + 'redis' => $this->checkRedis(), + 'xunsearch' => $this->checkXunsearch(), + 'websocket' => $this->checkWebsocket(), + ]; + + foreach ($items as $key => $value) { + if (empty($value)) { + unset($items[$key]); + } + } + + if (empty($items)) return; + + $content = implode("\n", $items); + + $notice = new ServerMonitorNotice(); + + $notice->createTask($content); + } + + protected function checkCpu() + { + $cpuCount = $this->getCpuCount(); + + $load = sys_getloadavg(); + + if ($load[1] > $cpuCount * 0.8) { + return sprintf("cpu负载超过%s", $load[1]); + } + } + + protected function checkMemory() + { + $memInfo = file_get_contents('/proc/meminfo'); + + $total = null; + + if (preg_match('/MemTotal\:\s+(\d+) kB/', $memInfo, $totalMatches)) { + $total = $totalMatches[1]; + } + + if ($total === null) return; + + $available = null; + + if (preg_match('/MemAvailable\:\s+(\d+) kB/', $memInfo, $avaMatches)) { + $available = $avaMatches[1]; + } + + if ($available === null) return; + + $left = 100 * ($available / $total); + + if ($left < 20) { + return sprintf("memory剩余不足%s%%", round($left)); + } + } + + protected function checkDisk() + { + $free = disk_free_space('/'); + $total = disk_total_space('/'); + + $left = 100 * $free / $total; + + if ($left < 20) { + return sprintf("disk剩余不足%s%%", round($left)); + } + } + + protected function checkMysql() + { + try { + + $benchmark = new Benchmark(); + + $benchmark->start(); + + $user = UserModel::findFirst(); + + $benchmark->stop(); + + $elapsedTime = $benchmark->getElapsedTime(); + + if ($user === false) { + return sprintf("mysql查询失败"); + } + + if ($elapsedTime > 1) { + return sprintf("mysql查询响应超过%s秒", round($elapsedTime, 2)); + } + + } catch (\Exception $e) { + return sprintf("mysql可能存在异常"); + } + } + + protected function checkRedis() + { + try { + + $benchmark = new Benchmark(); + + $benchmark->start(); + + $site = $this->getSettings('site'); + + $benchmark->stop(); + + $elapsedTime = $benchmark->getElapsedTime(); + + if (empty($site)) { + return sprintf("redis查询失败"); + } + + if ($elapsedTime > 1) { + return sprintf("redis查询响应超过%s秒", round($elapsedTime, 2)); + } + + } catch (\Exception $e) { + return sprintf("redis可能存在异常"); + } + } + + protected function checkXunsearch() + { + try { + + $benchmark = new Benchmark(); + + $benchmark->start(); + + $searcher = new UserSearcher(); + + $user = $searcher->search('id:10000'); + + $benchmark->stop(); + + $elapsedTime = $benchmark->getElapsedTime(); + + if (empty($user)) { + return sprintf("xunsearch搜索失败"); + } + + if ($elapsedTime > 1) { + return sprintf("xunsearch搜索响应超过%s秒", round($elapsedTime, 2)); + } + + } catch (\Exception $e) { + return sprintf("xunsearch可能存在异常"); + } + } + + protected function checkWebsocket() + { + try { + + $benchmark = new Benchmark(); + + $config = $this->getConfig(); + + Gateway::$registerAddress = $config->path('websocket.register_address'); + + $benchmark->start(); + + Gateway::isUidOnline(10000); + + $benchmark->stop(); + + $elapsedTime = $benchmark->getElapsedTime(); + + if ($elapsedTime > 1) { + return sprintf("websocket响应超过%s秒", round($elapsedTime, 2)); + } + + } catch (\Exception $e) { + return sprintf("websocket可能存在异常"); + } + } + + protected function getCpuCount() + { + $cpuInfo = file_get_contents('/proc/cpuinfo'); + + preg_match("/^cpu cores\s:\s(\d+)/m", $cpuInfo, $matches); + + $coreCount = intval($matches[1]); + + preg_match_all("/^processor/m", $cpuInfo, $matches); + + $processorCount = count($matches[0]); + + return $coreCount * $processorCount; + } + +} \ No newline at end of file diff --git a/app/Console/Tasks/TeacherLiveNoticeTask.php b/app/Console/Tasks/TeacherLiveNoticeTask.php new file mode 100644 index 00000000..fac00d68 --- /dev/null +++ b/app/Console/Tasks/TeacherLiveNoticeTask.php @@ -0,0 +1,81 @@ +findLives(); + + if ($lives->count() == 0) return; + + $redis = $this->getRedis(); + + $keyName = $this->getCacheKeyName(); + + foreach ($lives as $live) { + $redis->sAdd($keyName, $live->chapter_id); + } + + $redis->expire($keyName, 86400); + } + + /** + * 消费讲师提醒 + */ + public function consumeAction() + { + $redis = $this->getRedis(); + + $keyName = $this->getCacheKeyName(); + + $liveIds = $redis->sMembers($keyName); + + if (count($liveIds) == 0) return; + + $liveRepo = new ChapterLiveRepo(); + + $notice = new TeacherLiveNotice(); + + foreach ($liveIds as $liveId) { + + $live = $liveRepo->findById($liveId); + + if ($live->start_time - time() < 30 * 60) { + + $notice->createTask($live); + + $redis->sRem($keyName, $liveId); + } + } + } + + /** + * @return ResultsetInterface|Resultset|ChapterLiveModel[] + */ + protected function findLives() + { + $today = strtotime(date('Ymd')); + + return ChapterLiveModel::query() + ->betweenWhere('start_time', $today, $today + 86400) + ->execute(); + } + + protected function getCacheKeyName() + { + return 'teacher_live_notice_task'; + } + +} \ No newline at end of file diff --git a/app/Http/Admin/Controllers/CourseController.php b/app/Http/Admin/Controllers/CourseController.php index 587e3e89..9b927b52 100644 --- a/app/Http/Admin/Controllers/CourseController.php +++ b/app/Http/Admin/Controllers/CourseController.php @@ -33,9 +33,13 @@ class CourseController extends Controller $xmCategories = $courseService->getXmCategories(0); $xmTeachers = $courseService->getXmTeachers(0); + $modelTypes = $courseService->getModelTypes(); + $levelTypes = $courseService->getLevelTypes(); $this->view->setVar('xm_categories', $xmCategories); $this->view->setVar('xm_teachers', $xmTeachers); + $this->view->setVar('model_types', $modelTypes); + $this->view->setVar('level_types', $levelTypes); } /** diff --git a/app/Http/Admin/Controllers/ImGroupController.php b/app/Http/Admin/Controllers/ImGroupController.php index 7be26303..e1f73991 100644 --- a/app/Http/Admin/Controllers/ImGroupController.php +++ b/app/Http/Admin/Controllers/ImGroupController.php @@ -11,7 +11,7 @@ class ImGroupController extends Controller { /** - * @Get("/list", name="admin.group.list") + * @Get("/list", name="admin.im_group.list") */ public function listAction() { @@ -25,15 +25,20 @@ class ImGroupController extends Controller } /** - * @Get("/search", name="admin.group.search") + * @Get("/search", name="admin.im_group.search") */ public function searchAction() { + $groupService = new ImGroupService(); + + $types = $groupService->getGroupTypes(); + $this->view->pick('im/group/search'); + $this->view->setVar('types', $types); } /** - * @Get("/add", name="admin.group.add") + * @Get("/add", name="admin.im_group.add") */ public function addAction() { @@ -41,7 +46,7 @@ class ImGroupController extends Controller } /** - * @Get("/{id:[0-9]+}/edit", name="admin.group.edit") + * @Get("/{id:[0-9]+}/edit", name="admin.im_group.edit") */ public function editAction($id) { @@ -55,7 +60,7 @@ class ImGroupController extends Controller } /** - * @Post("/create", name="admin.group.create") + * @Post("/create", name="admin.im_group.create") */ public function createAction() { @@ -64,7 +69,7 @@ class ImGroupController extends Controller $group = $groupService->createGroup(); $location = $this->url->get([ - 'for' => 'admin.group.edit', + 'for' => 'admin.im_group.edit', 'id' => $group->id, ]); @@ -77,7 +82,7 @@ class ImGroupController extends Controller } /** - * @Post("/{id:[0-9]+}/update", name="admin.group.update") + * @Post("/{id:[0-9]+}/update", name="admin.im_group.update") */ public function updateAction($id) { @@ -85,7 +90,7 @@ class ImGroupController extends Controller $groupService->updateGroup($id); - $location = $this->url->get(['for' => 'admin.group.list']); + $location = $this->url->get(['for' => 'admin.im_group.list']); $content = [ 'location' => $location, @@ -96,7 +101,7 @@ class ImGroupController extends Controller } /** - * @Post("/{id:[0-9]+}/delete", name="admin.group.delete") + * @Post("/{id:[0-9]+}/delete", name="admin.im_group.delete") */ public function deleteAction($id) { @@ -115,7 +120,7 @@ class ImGroupController extends Controller } /** - * @Post("/{id:[0-9]+}/restore", name="admin.group.restore") + * @Post("/{id:[0-9]+}/restore", name="admin.im_group.restore") */ public function restoreAction($id) { diff --git a/app/Http/Admin/Controllers/IndexController.php b/app/Http/Admin/Controllers/IndexController.php index 7b7b9da2..c5ff04b4 100644 --- a/app/Http/Admin/Controllers/IndexController.php +++ b/app/Http/Admin/Controllers/IndexController.php @@ -39,12 +39,23 @@ class IndexController extends Controller $todayStat = $indexService->getTodayStat(); $appInfo = $indexService->getAppInfo(); $serverInfo = $indexService->getServerInfo(); - $releases = $indexService->getReleases(); $this->view->setVar('global_stat', $globalStat); $this->view->setVar('today_stat', $todayStat); $this->view->setVar('app_info', $appInfo); $this->view->setVar('server_info', $serverInfo); + } + + /** + * @Get("/releases", name="admin.releases") + */ + public function releasesAction() + { + $indexService = new IndexService(); + + $releases = $indexService->getReleases(); + + $this->view->setRenderLevel(View::LEVEL_ACTION_VIEW); $this->view->setVar('releases', $releases); } diff --git a/app/Http/Admin/Controllers/OrderController.php b/app/Http/Admin/Controllers/OrderController.php index 54597b42..c243e430 100644 --- a/app/Http/Admin/Controllers/OrderController.php +++ b/app/Http/Admin/Controllers/OrderController.php @@ -15,7 +15,13 @@ class OrderController extends Controller */ public function searchAction() { + $orderService = new OrderService(); + $itemTypes = $orderService->getItemTypes(); + $statusTypes = $orderService->getStatusTypes(); + + $this->view->setVar('item_types', $itemTypes); + $this->view->setVar('status_types', $statusTypes); } /** diff --git a/app/Http/Admin/Controllers/PointHistoryController.php b/app/Http/Admin/Controllers/PointHistoryController.php new file mode 100644 index 00000000..cce0f88c --- /dev/null +++ b/app/Http/Admin/Controllers/PointHistoryController.php @@ -0,0 +1,40 @@ +getEventTypes(); + + $this->view->pick('point/history/search'); + $this->view->setVar('event_types', $eventTypes); + } + + /** + * @Get("/list", name="admin.point_history.list") + */ + public function listAction() + { + $historyService = new PointHistoryService(); + + $pager = $historyService->getHistories(); + + $this->view->pick('point/history/list'); + + $this->view->setVar('pager', $pager); + } + +} \ No newline at end of file diff --git a/app/Http/Admin/Controllers/RefundController.php b/app/Http/Admin/Controllers/RefundController.php index 7271f416..3799e23e 100644 --- a/app/Http/Admin/Controllers/RefundController.php +++ b/app/Http/Admin/Controllers/RefundController.php @@ -15,7 +15,11 @@ class RefundController extends Controller */ public function searchAction() { + $refundService = new RefundService(); + $statusTypes = $refundService->getStatusTypes(); + + $this->view->setVar('status_types', $statusTypes); } /** diff --git a/app/Http/Admin/Controllers/SettingController.php b/app/Http/Admin/Controllers/SettingController.php index 76cff636..c7734972 100644 --- a/app/Http/Admin/Controllers/SettingController.php +++ b/app/Http/Admin/Controllers/SettingController.php @@ -378,4 +378,30 @@ class SettingController extends Controller } } + /** + * @Route("/dingtalk/robot", name="admin.setting.dingtalk_robot") + */ + public function dingtalkRobotAction() + { + $section = 'dingtalk.robot'; + + $settingService = new SettingService(); + + if ($this->request->isPost()) { + + $data = $this->request->getPost(); + + $settingService->updatePointSettings($section, $data); + + return $this->jsonSuccess(['msg' => '更新配置成功']); + + } else { + + $robot = $settingService->getSettings($section); + + $this->view->pick('setting/dingtalk_robot'); + $this->view->setVar('robot', $robot); + } + } + } diff --git a/app/Http/Admin/Controllers/StudentController.php b/app/Http/Admin/Controllers/StudentController.php index 9b2707fb..e72a01a3 100644 --- a/app/Http/Admin/Controllers/StudentController.php +++ b/app/Http/Admin/Controllers/StudentController.php @@ -15,7 +15,11 @@ class StudentController extends Controller */ public function searchAction() { + $studentService = new StudentService(); + $sourceTypes = $studentService->getSourceTypes(); + + $this->view->setVar('source_types', $sourceTypes); } /** diff --git a/app/Http/Admin/Controllers/TestController.php b/app/Http/Admin/Controllers/TestController.php index 4db114d2..d159935d 100644 --- a/app/Http/Admin/Controllers/TestController.php +++ b/app/Http/Admin/Controllers/TestController.php @@ -6,6 +6,7 @@ use App\Http\Admin\Services\AlipayTest as AlipayTestService; use App\Http\Admin\Services\Setting as SettingService; use App\Http\Admin\Services\WxpayTest as WxpayTestService; use App\Services\Captcha as CaptchaService; +use App\Services\DingTalkNotice as DingTalkNoticeService; use App\Services\Live as LiveService; use App\Services\Mail\Test as TestMailService; use App\Services\MyStorage as StorageService; @@ -250,4 +251,20 @@ class TestController extends Controller return $this->jsonSuccess(['status' => $status]); } + /** + * @Post("/dingtalk/robot", name="admin.test.dingtalk_robot") + */ + public function dingTalkRobotAction() + { + $noticeService = new DingTalkNoticeService(); + + $result = $noticeService->test(); + + if ($result) { + return $this->jsonSuccess(['msg' => '发送消息成功,请到钉钉确认']); + } else { + return $this->jsonError(['msg' => '发送消息失败,请检查配置']); + } + } + } \ No newline at end of file diff --git a/app/Http/Admin/Controllers/TopicController.php b/app/Http/Admin/Controllers/TopicController.php index 02d08f30..087580e7 100644 --- a/app/Http/Admin/Controllers/TopicController.php +++ b/app/Http/Admin/Controllers/TopicController.php @@ -22,6 +22,14 @@ class TopicController extends Controller $this->view->setVar('pager', $pager); } + /** + * @Get("/search", name="admin.topic.search") + */ + public function searchAction() + { + + } + /** * @Get("/add", name="admin.topic.add") */ diff --git a/app/Http/Admin/Controllers/TradeController.php b/app/Http/Admin/Controllers/TradeController.php index b4781320..2600351f 100644 --- a/app/Http/Admin/Controllers/TradeController.php +++ b/app/Http/Admin/Controllers/TradeController.php @@ -15,7 +15,13 @@ class TradeController extends Controller */ public function searchAction() { + $tradeService = new TradeService(); + $channelTypes = $tradeService->getChannelTypes(); + $statusTypes = $tradeService->getStatusTypes(); + + $this->view->setVar('channel_types', $channelTypes); + $this->view->setVar('status_types', $statusTypes); } /** diff --git a/app/Http/Admin/Controllers/UserController.php b/app/Http/Admin/Controllers/UserController.php index d1482164..5d106768 100644 --- a/app/Http/Admin/Controllers/UserController.php +++ b/app/Http/Admin/Controllers/UserController.php @@ -18,9 +18,11 @@ class UserController extends Controller { $userService = new UserService(); - $roles = $userService->getRoles(); + $eduRoleTypes = $userService->getEduRoleTypes(); + $adminRoles = $userService->getAdminRoles(); - $this->view->setVar('roles', $roles); + $this->view->setVar('edu_role_types', $eduRoleTypes); + $this->view->setVar('admin_roles', $adminRoles); } /** @@ -42,9 +44,9 @@ class UserController extends Controller { $userService = new UserService(); - $roles = $userService->getRoles(); + $adminRoles = $userService->getAdminRoles(); - $this->view->setVar('roles', $roles); + $this->view->setVar('admin_roles', $adminRoles); } /** @@ -81,7 +83,7 @@ class UserController extends Controller $user = $userService->getUser($id); $account = $userService->getAccount($id); - $roles = $userService->getRoles(); + $adminRoles = $userService->getAdminRoles(); if ($user->admin_role == RoleModel::ROLE_ROOT) { $this->response->redirect(['for' => 'admin.user.list']); @@ -89,7 +91,7 @@ class UserController extends Controller $this->view->setVar('user', $user); $this->view->setVar('account', $account); - $this->view->setVar('roles', $roles); + $this->view->setVar('admin_roles', $adminRoles); } /** diff --git a/app/Http/Admin/Services/AuthNode.php b/app/Http/Admin/Services/AuthNode.php index 20dedbb5..a0978c90 100644 --- a/app/Http/Admin/Services/AuthNode.php +++ b/app/Http/Admin/Services/AuthNode.php @@ -149,6 +149,12 @@ class AuthNode extends Service 'type' => 'menu', 'route' => 'admin.topic.list', ], + [ + 'id' => '1-4-5', + 'title' => '搜索话题', + 'type' => 'menu', + 'route' => 'admin.topic.search', + ], [ 'id' => '1-4-2', 'title' => '添加话题', @@ -349,31 +355,31 @@ class AuthNode extends Service 'id' => '2-4-1', 'title' => '群组列表', 'type' => 'menu', - 'route' => 'admin.group.list', + 'route' => 'admin.im_group.list', ], [ 'id' => '2-4-2', 'title' => '搜索群组', 'type' => 'menu', - 'route' => 'admin.group.search', + 'route' => 'admin.im_group.search', ], [ 'id' => '2-4-3', 'title' => '添加群组', 'type' => 'menu', - 'route' => 'admin.group.add', + 'route' => 'admin.im_group.add', ], [ 'id' => '2-4-4', 'title' => '编辑群组', 'type' => 'button', - 'route' => 'admin.group.edit', + 'route' => 'admin.im_group.edit', ], [ 'id' => '2-4-5', 'title' => '删除群组', 'type' => 'button', - 'route' => 'admin.group.delete', + 'route' => 'admin.im_group.delete', ], ], ], @@ -493,6 +499,12 @@ class AuthNode extends Service 'type' => 'menu', 'route' => 'admin.point_redeem.list', ], + [ + 'id' => '2-8-6', + 'title' => '积分记录', + 'type' => 'menu', + 'route' => 'admin.point_history.list', + ], [ 'id' => '2-8-3', 'title' => '添加礼品', @@ -800,6 +812,12 @@ class AuthNode extends Service 'type' => 'menu', 'route' => 'admin.setting.wechat_oa', ], + [ + 'id' => '5-1-15', + 'title' => '钉钉机器人', + 'type' => 'menu', + 'route' => 'admin.setting.dingtalk_robot', + ], [ 'id' => '5-1-14', 'title' => '积分设置', diff --git a/app/Http/Admin/Services/Course.php b/app/Http/Admin/Services/Course.php index 1767f553..1768f428 100644 --- a/app/Http/Admin/Services/Course.php +++ b/app/Http/Admin/Services/Course.php @@ -232,6 +232,16 @@ class Course extends Service return $course; } + public function getModelTypes() + { + return CourseModel::modelTypes(); + } + + public function getLevelTypes() + { + return CourseModel::levelTypes(); + } + public function getStudyExpiryOptions() { return CourseModel::studyExpiryOptions(); diff --git a/app/Http/Admin/Services/ImGroup.php b/app/Http/Admin/Services/ImGroup.php index a24cd560..9f4af997 100644 --- a/app/Http/Admin/Services/ImGroup.php +++ b/app/Http/Admin/Services/ImGroup.php @@ -14,6 +14,11 @@ use App\Validators\ImGroup as ImGroupValidator; class ImGroup extends Service { + public function getGroupTypes() + { + return ImGroupModel::types(); + } + public function getGroups() { $pagerQuery = new PagerQuery(); diff --git a/app/Http/Admin/Services/Index.php b/app/Http/Admin/Services/Index.php index 9febad0f..b67928c3 100644 --- a/app/Http/Admin/Services/Index.php +++ b/app/Http/Admin/Services/Index.php @@ -59,7 +59,7 @@ class Index extends Service $client = new Client(); - $response = $client->get($url, ['timeout' => 3]); + $response = $client->get($url); $content = json_decode($response->getBody(), true); diff --git a/app/Http/Admin/Services/Order.php b/app/Http/Admin/Services/Order.php index d43adf42..05ebb525 100644 --- a/app/Http/Admin/Services/Order.php +++ b/app/Http/Admin/Services/Order.php @@ -4,6 +4,7 @@ namespace App\Http\Admin\Services; use App\Builders\OrderList as OrderListBuilder; use App\Library\Paginator\Query as PaginateQuery; +use App\Models\Order as OrderModel; use App\Repos\Account as AccountRepo; use App\Repos\Order as OrderRepo; use App\Repos\User as UserRepo; @@ -12,6 +13,16 @@ use App\Validators\Order as OrderValidator; class Order extends Service { + public function getItemTypes() + { + return OrderModel::itemTypes(); + } + + public function getStatusTypes() + { + return OrderModel::statusTypes(); + } + public function getOrders() { $pageQuery = new PaginateQuery(); diff --git a/app/Http/Admin/Services/PointHistory.php b/app/Http/Admin/Services/PointHistory.php new file mode 100644 index 00000000..83b0bc99 --- /dev/null +++ b/app/Http/Admin/Services/PointHistory.php @@ -0,0 +1,32 @@ +getParams(); + + $sort = $pagerQuery->getSort(); + $page = $pagerQuery->getPage(); + $limit = $pagerQuery->getLimit(); + + $historyRepo = new PointHistoryRepo(); + + return $historyRepo->paginate($params, $sort, $page, $limit); + } + + public function getEventTypes() + { + return PointHistoryModel::eventTypes(); + } + +} \ No newline at end of file diff --git a/app/Http/Admin/Services/Refund.php b/app/Http/Admin/Services/Refund.php index 89efeb70..2617f4fa 100644 --- a/app/Http/Admin/Services/Refund.php +++ b/app/Http/Admin/Services/Refund.php @@ -16,6 +16,11 @@ use App\Validators\Refund as RefundValidator; class Refund extends Service { + public function getStatusTypes() + { + return RefundModel::statusTypes(); + } + public function getRefunds() { $pageQuery = new PaginateQuery(); diff --git a/app/Http/Admin/Services/Student.php b/app/Http/Admin/Services/Student.php index 9ecceade..2e8b9b4f 100644 --- a/app/Http/Admin/Services/Student.php +++ b/app/Http/Admin/Services/Student.php @@ -7,9 +7,11 @@ use App\Builders\LearningList as LearningListBuilder; use App\Library\Paginator\Query as PagerQuery; use App\Models\Course as CourseModel; use App\Models\CourseUser as CourseUserModel; +use App\Models\ImGroupUser as ImGroupUserModel; use App\Models\User as UserModel; use App\Repos\Course as CourseRepo; use App\Repos\CourseUser as CourseUserRepo; +use App\Repos\ImGroupUser as ImGroupUserRepo; use App\Repos\Learning as LearningRepo; use App\Repos\User as UserRepo; use App\Validators\CourseUser as CourseUserValidator; @@ -17,6 +19,11 @@ use App\Validators\CourseUser as CourseUserValidator; class Student extends Service { + public function getSourceTypes() + { + return CourseUserModel::sourceTypes(); + } + public function getCourse($id) { $repo = new CourseRepo(); @@ -100,9 +107,13 @@ class Student extends Service $courseUser->create($data); - $this->incrCourseUserCount($course); + $course->user_count += 1; + $course->update(); - $this->incrUserCourseCount($user); + $user->course_count += 1; + $user->update(); + + $this->handleImGroupUser($course, $user); return $courseUser; } @@ -126,18 +137,33 @@ class Student extends Service return $relation; } - protected function incrCourseUserCount(CourseModel $course) + protected function handleImGroupUser(CourseModel $course, UserModel $user) { - $course->user_count += 1; + $courseRepo = new CourseRepo(); - $course->update(); - } + $imGroup = $courseRepo->findImGroup($course->id); - protected function incrUserCourseCount(UserModel $user) - { - $user->course_count += 1; + $userRepo = new UserRepo(); - $user->update(); + $imUser = $userRepo->findImUser($user->id); + + $imGroupUserRepo = new ImGroupUserRepo(); + + $imGroupUser = $imGroupUserRepo->findGroupUser($imGroup->id, $user->id); + + if ($imGroupUser) return; + + $imGroupUser = new ImGroupUserModel(); + + $imGroupUser->group_id = $imGroup->id; + $imGroupUser->user_id = $imUser->id; + $imGroupUser->create(); + + $imUser->group_count += 1; + $imUser->update(); + + $imGroup->user_count += 1; + $imGroup->update(); } protected function findOrFail($id) diff --git a/app/Http/Admin/Services/Trade.php b/app/Http/Admin/Services/Trade.php index 7205ce6c..9b818a81 100644 --- a/app/Http/Admin/Services/Trade.php +++ b/app/Http/Admin/Services/Trade.php @@ -5,6 +5,7 @@ namespace App\Http\Admin\Services; use App\Builders\TradeList as TradeListBuilder; use App\Library\Paginator\Query as PaginateQuery; use App\Models\Refund as RefundModel; +use App\Models\Trade as TradeModel; use App\Repos\Account as AccountRepo; use App\Repos\Order as OrderRepo; use App\Repos\Trade as TradeRepo; @@ -14,6 +15,16 @@ use App\Validators\Trade as TradeValidator; class Trade extends Service { + public function getChannelTypes() + { + return TradeModel::channelTypes(); + } + + public function getStatusTypes() + { + return TradeModel::statusTypes(); + } + public function getTrades() { $pageQuery = new PaginateQuery(); diff --git a/app/Http/Admin/Services/User.php b/app/Http/Admin/Services/User.php index 91d2a06c..539fcb32 100644 --- a/app/Http/Admin/Services/User.php +++ b/app/Http/Admin/Services/User.php @@ -18,7 +18,12 @@ use App\Validators\User as UserValidator; class User extends Service { - public function getRoles() + public function getEduRoleTypes() + { + return UserModel::eduRoleTypes(); + } + + public function getAdminRoles() { $roleRepo = new RoleRepo(); diff --git a/app/Http/Admin/Views/audit/list.volt b/app/Http/Admin/Views/audit/list.volt index 6c43fbb5..b1b739d7 100644 --- a/app/Http/Admin/Views/audit/list.volt +++ b/app/Http/Admin/Views/audit/list.volt @@ -2,12 +2,19 @@ {% block content %} + {% set search_url = url({'for':'admin.audit.search'}) %} +