mirror of
https://gitee.com/koogua/course-tencent-cloud.git
synced 2025-07-13 03:49:11 +08:00
Merge branch 'koogua/v1.7.1' into demo
# Conflicts: # app/Library/AppInfo.php
This commit is contained in:
commit
fa17b8917d
13
CHANGELOG.md
13
CHANGELOG.md
@ -1,3 +1,16 @@
|
|||||||
|
### [v1.7.1](https://gitee.com/koogua/course-tencent-cloud/releases/v1.7.1)(2024-06-15)
|
||||||
|
|
||||||
|
### [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)
|
### [v1.6.9](https://gitee.com/koogua/course-tencent-cloud/releases/v1.6.9)(2024-04-15)
|
||||||
|
|
||||||
- 增加用户删除和还原功能
|
- 增加用户删除和还原功能
|
||||||
|
@ -15,6 +15,8 @@ class SyncAppInfoTask extends Task
|
|||||||
|
|
||||||
public function mainAction()
|
public function mainAction()
|
||||||
{
|
{
|
||||||
|
echo '------ start sync app info ------' . PHP_EOL;
|
||||||
|
|
||||||
$url = 'https://www.koogua.com/api/instance/collect';
|
$url = 'https://www.koogua.com/api/instance/collect';
|
||||||
|
|
||||||
$site = $this->getSettings('site');
|
$site = $this->getSettings('site');
|
||||||
@ -37,6 +39,8 @@ class SyncAppInfoTask extends Task
|
|||||||
$client = new Client();
|
$client = new Client();
|
||||||
|
|
||||||
$client->request('POST', $url, ['form_params' => $params]);
|
$client->request('POST', $url, ['form_params' => $params]);
|
||||||
|
|
||||||
|
echo '------ end sync app info ------' . PHP_EOL;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
namespace App\Http\Admin\Services;
|
namespace App\Http\Admin\Services;
|
||||||
|
|
||||||
use App\Services\Auth\Admin as AdminAuth;
|
use App\Services\Auth\Admin as AdminAuth;
|
||||||
|
use App\Services\Auth\Home as HomeAuth;
|
||||||
use App\Validators\Account as AccountValidator;
|
use App\Validators\Account as AccountValidator;
|
||||||
|
|
||||||
class Session extends Service
|
class Session extends Service
|
||||||
@ -35,6 +36,8 @@ class Session extends Service
|
|||||||
|
|
||||||
$this->auth->saveAuthInfo($user);
|
$this->auth->saveAuthInfo($user);
|
||||||
|
|
||||||
|
$this->loginHome($user);
|
||||||
|
|
||||||
$this->eventsManager->fire('Account:afterLogin', $this, $user);
|
$this->eventsManager->fire('Account:afterLogin', $this, $user);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,4 +50,11 @@ class Session extends Service
|
|||||||
$this->eventsManager->fire('Account:afterLogout', $this, $user);
|
$this->eventsManager->fire('Account:afterLogout', $this, $user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function loginHome($user)
|
||||||
|
{
|
||||||
|
$auth = new HomeAuth();
|
||||||
|
|
||||||
|
$auth->saveAuthInfo($user);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -47,6 +47,7 @@
|
|||||||
</td>
|
</td>
|
||||||
<td><input class="layui-input" type="text" name="notice_template[refund_finish][id]" value="{{ notice_template.refund_finish.id }}" lay-verify="required"></td>
|
<td><input class="layui-input" type="text" name="notice_template[refund_finish][id]" value="{{ notice_template.refund_finish.id }}" lay-verify="required"></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<!--
|
||||||
<tr>
|
<tr>
|
||||||
<td>课程直播提醒</td>
|
<td>课程直播提醒</td>
|
||||||
<td>
|
<td>
|
||||||
@ -63,6 +64,7 @@
|
|||||||
</td>
|
</td>
|
||||||
<td><input class="layui-input" type="text" name="notice_template[consult_reply][id]" value="{{ notice_template.consult_reply.id }}" lay-verify="required"></td>
|
<td><input class="layui-input" type="text" name="notice_template[consult_reply][id]" value="{{ notice_template.consult_reply.id }}" lay-verify="required"></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
-->
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<br>
|
<br>
|
||||||
|
@ -29,7 +29,7 @@ class ConnectController extends Controller
|
|||||||
$service->setWechatRedirectCache($redirect);
|
$service->setWechatRedirectCache($redirect);
|
||||||
}
|
}
|
||||||
|
|
||||||
$url = $service->getAuthorizeUrl(ConnectModel::PROVIDER_WECHAT);
|
$url = $service->getAuthorizeUrl(ConnectModel::PROVIDER_WECHAT_OA);
|
||||||
|
|
||||||
return $this->response->redirect($url, true);
|
return $this->response->redirect($url, true);
|
||||||
}
|
}
|
||||||
@ -41,7 +41,7 @@ class ConnectController extends Controller
|
|||||||
{
|
{
|
||||||
$service = new ConnectService();
|
$service = new ConnectService();
|
||||||
|
|
||||||
$data = $service->handleCallback(ConnectModel::PROVIDER_WECHAT);
|
$data = $service->handleCallback(ConnectModel::PROVIDER_WECHAT_OA);
|
||||||
|
|
||||||
$redirect = $service->getWechatRedirectCache();
|
$redirect = $service->getWechatRedirectCache();
|
||||||
|
|
||||||
|
@ -8,12 +8,12 @@
|
|||||||
namespace App\Http\Home\Controllers;
|
namespace App\Http\Home\Controllers;
|
||||||
|
|
||||||
use App\Http\Home\Services\Account as AccountService;
|
use App\Http\Home\Services\Account as AccountService;
|
||||||
use App\Http\Home\Services\FullH5Url as FullH5UrlService;
|
|
||||||
use App\Services\Logic\Account\EmailUpdate as EmailUpdateService;
|
use App\Services\Logic\Account\EmailUpdate as EmailUpdateService;
|
||||||
use App\Services\Logic\Account\OAuthProvider as OAuthProviderService;
|
use App\Services\Logic\Account\OAuthProvider as OAuthProviderService;
|
||||||
use App\Services\Logic\Account\PasswordReset as PasswordResetService;
|
use App\Services\Logic\Account\PasswordReset as PasswordResetService;
|
||||||
use App\Services\Logic\Account\PasswordUpdate as PasswordUpdateService;
|
use App\Services\Logic\Account\PasswordUpdate as PasswordUpdateService;
|
||||||
use App\Services\Logic\Account\PhoneUpdate as PhoneUpdateService;
|
use App\Services\Logic\Account\PhoneUpdate as PhoneUpdateService;
|
||||||
|
use App\Services\Logic\Url\FullH5Url as FullH5UrlService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @RoutePrefix("/account")
|
* @RoutePrefix("/account")
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
namespace App\Http\Home\Controllers;
|
namespace App\Http\Home\Controllers;
|
||||||
|
|
||||||
use App\Http\Home\Services\Answer as AnswerService;
|
use App\Http\Home\Services\Answer as AnswerService;
|
||||||
use App\Http\Home\Services\FullH5Url as FullH5UrlService;
|
|
||||||
use App\Http\Home\Services\Question as QuestionService;
|
use App\Http\Home\Services\Question as QuestionService;
|
||||||
use App\Models\Answer as AnswerModel;
|
use App\Models\Answer as AnswerModel;
|
||||||
use App\Services\Logic\Answer\AnswerAccept as AnswerAcceptService;
|
use App\Services\Logic\Answer\AnswerAccept as AnswerAcceptService;
|
||||||
@ -17,6 +16,7 @@ use App\Services\Logic\Answer\AnswerDelete as AnswerDeleteService;
|
|||||||
use App\Services\Logic\Answer\AnswerInfo as AnswerInfoService;
|
use App\Services\Logic\Answer\AnswerInfo as AnswerInfoService;
|
||||||
use App\Services\Logic\Answer\AnswerLike as AnswerLikeService;
|
use App\Services\Logic\Answer\AnswerLike as AnswerLikeService;
|
||||||
use App\Services\Logic\Answer\AnswerUpdate as AnswerUpdateService;
|
use App\Services\Logic\Answer\AnswerUpdate as AnswerUpdateService;
|
||||||
|
use App\Services\Logic\Url\FullH5Url as FullH5UrlService;
|
||||||
use Phalcon\Mvc\View;
|
use Phalcon\Mvc\View;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -9,7 +9,6 @@ namespace App\Http\Home\Controllers;
|
|||||||
|
|
||||||
use App\Http\Home\Services\Article as ArticleService;
|
use App\Http\Home\Services\Article as ArticleService;
|
||||||
use App\Http\Home\Services\ArticleQuery as ArticleQueryService;
|
use App\Http\Home\Services\ArticleQuery as ArticleQueryService;
|
||||||
use App\Http\Home\Services\FullH5Url as FullH5UrlService;
|
|
||||||
use App\Models\Article as ArticleModel;
|
use App\Models\Article as ArticleModel;
|
||||||
use App\Services\Logic\Article\ArticleClose as ArticleCloseService;
|
use App\Services\Logic\Article\ArticleClose as ArticleCloseService;
|
||||||
use App\Services\Logic\Article\ArticleCreate as ArticleCreateService;
|
use App\Services\Logic\Article\ArticleCreate as ArticleCreateService;
|
||||||
@ -20,6 +19,7 @@ use App\Services\Logic\Article\ArticleLike as ArticleLikeService;
|
|||||||
use App\Services\Logic\Article\ArticleList as ArticleListService;
|
use App\Services\Logic\Article\ArticleList as ArticleListService;
|
||||||
use App\Services\Logic\Article\ArticleUpdate as ArticleUpdateService;
|
use App\Services\Logic\Article\ArticleUpdate as ArticleUpdateService;
|
||||||
use App\Services\Logic\Article\RelatedArticleList as RelatedArticleListService;
|
use App\Services\Logic\Article\RelatedArticleList as RelatedArticleListService;
|
||||||
|
use App\Services\Logic\Url\FullH5Url as FullH5UrlService;
|
||||||
use Phalcon\Mvc\View;
|
use Phalcon\Mvc\View;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -7,7 +7,6 @@
|
|||||||
|
|
||||||
namespace App\Http\Home\Controllers;
|
namespace App\Http\Home\Controllers;
|
||||||
|
|
||||||
use App\Http\Home\Services\FullH5Url as FullH5UrlService;
|
|
||||||
use App\Models\ChapterLive as LiveModel;
|
use App\Models\ChapterLive as LiveModel;
|
||||||
use App\Models\Course as CourseModel;
|
use App\Models\Course as CourseModel;
|
||||||
use App\Services\Logic\Chapter\ChapterInfo as ChapterInfoService;
|
use App\Services\Logic\Chapter\ChapterInfo as ChapterInfoService;
|
||||||
@ -15,6 +14,7 @@ use App\Services\Logic\Chapter\ChapterLike as ChapterLikeService;
|
|||||||
use App\Services\Logic\Chapter\Learning as ChapterLearningService;
|
use App\Services\Logic\Chapter\Learning as ChapterLearningService;
|
||||||
use App\Services\Logic\Course\BasicInfo as CourseInfoService;
|
use App\Services\Logic\Course\BasicInfo as CourseInfoService;
|
||||||
use App\Services\Logic\Course\ChapterList as CourseChapterListService;
|
use App\Services\Logic\Course\ChapterList as CourseChapterListService;
|
||||||
|
use App\Services\Logic\Url\FullH5Url as FullH5UrlService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @RoutePrefix("/chapter")
|
* @RoutePrefix("/chapter")
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
namespace App\Http\Home\Controllers;
|
namespace App\Http\Home\Controllers;
|
||||||
|
|
||||||
use App\Http\Home\Services\CourseQuery as CourseQueryService;
|
use App\Http\Home\Services\CourseQuery as CourseQueryService;
|
||||||
use App\Http\Home\Services\FullH5Url as FullH5UrlService;
|
|
||||||
use App\Services\Logic\Course\ChapterList as CourseChapterListService;
|
use App\Services\Logic\Course\ChapterList as CourseChapterListService;
|
||||||
use App\Services\Logic\Course\ConsultList as CourseConsultListService;
|
use App\Services\Logic\Course\ConsultList as CourseConsultListService;
|
||||||
use App\Services\Logic\Course\CourseFavorite as CourseFavoriteService;
|
use App\Services\Logic\Course\CourseFavorite as CourseFavoriteService;
|
||||||
@ -20,6 +19,7 @@ use App\Services\Logic\Course\ResourceList as CourseResourceListService;
|
|||||||
use App\Services\Logic\Course\ReviewList as CourseReviewListService;
|
use App\Services\Logic\Course\ReviewList as CourseReviewListService;
|
||||||
use App\Services\Logic\Course\TopicList as CourseTopicListService;
|
use App\Services\Logic\Course\TopicList as CourseTopicListService;
|
||||||
use App\Services\Logic\Reward\OptionList as RewardOptionList;
|
use App\Services\Logic\Reward\OptionList as RewardOptionList;
|
||||||
|
use App\Services\Logic\Url\FullH5Url as FullH5UrlService;
|
||||||
use Phalcon\Mvc\View;
|
use Phalcon\Mvc\View;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -7,9 +7,9 @@
|
|||||||
|
|
||||||
namespace App\Http\Home\Controllers;
|
namespace App\Http\Home\Controllers;
|
||||||
|
|
||||||
use App\Http\Home\Services\FullH5Url as FullH5UrlService;
|
|
||||||
use App\Services\Logic\Help\HelpInfo as HelpInfoService;
|
use App\Services\Logic\Help\HelpInfo as HelpInfoService;
|
||||||
use App\Services\Logic\Help\HelpList as HelpListService;
|
use App\Services\Logic\Help\HelpList as HelpListService;
|
||||||
|
use App\Services\Logic\Url\FullH5Url as FullH5UrlService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @RoutePrefix("/help")
|
* @RoutePrefix("/help")
|
||||||
|
@ -7,8 +7,8 @@
|
|||||||
|
|
||||||
namespace App\Http\Home\Controllers;
|
namespace App\Http\Home\Controllers;
|
||||||
|
|
||||||
use App\Http\Home\Services\FullH5Url as FullH5UrlService;
|
|
||||||
use App\Http\Home\Services\Index as IndexService;
|
use App\Http\Home\Services\Index as IndexService;
|
||||||
|
use App\Services\Logic\Url\FullH5Url as FullH5UrlService;
|
||||||
|
|
||||||
class IndexController extends Controller
|
class IndexController extends Controller
|
||||||
{
|
{
|
||||||
|
@ -7,9 +7,9 @@
|
|||||||
|
|
||||||
namespace App\Http\Home\Controllers;
|
namespace App\Http\Home\Controllers;
|
||||||
|
|
||||||
use App\Http\Home\Services\FullH5Url as FullH5UrlService;
|
|
||||||
use App\Http\Home\Services\Index as IndexService;
|
use App\Http\Home\Services\Index as IndexService;
|
||||||
use App\Services\Logic\Page\PageInfo as PageInfoService;
|
use App\Services\Logic\Page\PageInfo as PageInfoService;
|
||||||
|
use App\Services\Logic\Url\FullH5Url as FullH5UrlService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @RoutePrefix("/page")
|
* @RoutePrefix("/page")
|
||||||
|
@ -11,6 +11,7 @@ use App\Services\Logic\Point\GiftInfo as GiftInfoService;
|
|||||||
use App\Services\Logic\Point\GiftList as GiftListService;
|
use App\Services\Logic\Point\GiftList as GiftListService;
|
||||||
use App\Services\Logic\Point\GiftRedeem as GiftRedeemService;
|
use App\Services\Logic\Point\GiftRedeem as GiftRedeemService;
|
||||||
use App\Services\Logic\Point\HotGiftList as HotGiftListService;
|
use App\Services\Logic\Point\HotGiftList as HotGiftListService;
|
||||||
|
use App\Services\Logic\Url\FullH5Url as FullH5UrlService;
|
||||||
use App\Services\Logic\User\Console\BalanceInfo as BalanceInfoService;
|
use App\Services\Logic\User\Console\BalanceInfo as BalanceInfoService;
|
||||||
use Phalcon\Mvc\Dispatcher;
|
use Phalcon\Mvc\Dispatcher;
|
||||||
use Phalcon\Mvc\View;
|
use Phalcon\Mvc\View;
|
||||||
@ -38,6 +39,13 @@ class PointGiftController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function listAction()
|
public function listAction()
|
||||||
{
|
{
|
||||||
|
$service = new FullH5UrlService();
|
||||||
|
|
||||||
|
if ($service->isMobileBrowser() && $service->h5Enabled()) {
|
||||||
|
$location = $service->getPointGiftListUrl();
|
||||||
|
return $this->response->redirect($location);
|
||||||
|
}
|
||||||
|
|
||||||
$this->seo->prependTitle('积分商城');
|
$this->seo->prependTitle('积分商城');
|
||||||
|
|
||||||
$this->view->pick('point/gift/list');
|
$this->view->pick('point/gift/list');
|
||||||
|
@ -7,10 +7,11 @@
|
|||||||
|
|
||||||
namespace App\Http\Home\Controllers;
|
namespace App\Http\Home\Controllers;
|
||||||
|
|
||||||
use App\Http\Home\Services\ShareUrl as ShareUrlService;
|
|
||||||
use App\Library\CsrfToken as CsrfTokenService;
|
use App\Library\CsrfToken as CsrfTokenService;
|
||||||
use App\Repos\Upload as UploadRepo;
|
use App\Repos\Upload as UploadRepo;
|
||||||
use App\Services\LiveNotify as LiveNotifyService;
|
use App\Services\LiveNotify as LiveNotifyService;
|
||||||
|
use App\Services\Logic\Url\ShareUrl as ShareUrlService;
|
||||||
|
use App\Services\Logic\WeChat\OfficialAccount as WeChatOAService;
|
||||||
use App\Services\Pay\Alipay as AlipayService;
|
use App\Services\Pay\Alipay as AlipayService;
|
||||||
use App\Services\Pay\Wxpay as WxpayService;
|
use App\Services\Pay\Wxpay as WxpayService;
|
||||||
use App\Services\Storage as StorageService;
|
use App\Services\Storage as StorageService;
|
||||||
@ -150,6 +151,42 @@ class PublicController extends \Phalcon\Mvc\Controller
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Get("/wechat/oa/notify", name="home.wechat_oa.verify")
|
||||||
|
*/
|
||||||
|
public function wechatOaVerifyAction()
|
||||||
|
{
|
||||||
|
$service = new WeChatOAService();
|
||||||
|
|
||||||
|
$app = $service->getOfficialAccount();
|
||||||
|
|
||||||
|
$response = $app->server->serve();
|
||||||
|
|
||||||
|
$response->send();
|
||||||
|
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Post("/wechat/oa/notify", name="home.wechat_oa.notify")
|
||||||
|
*/
|
||||||
|
public function wechatOaNotifyAction()
|
||||||
|
{
|
||||||
|
$service = new WeChatOAService();
|
||||||
|
|
||||||
|
$app = $service->getOfficialAccount();
|
||||||
|
|
||||||
|
$app->server->push(function ($message) use ($service) {
|
||||||
|
return $service->handleNotify($message);
|
||||||
|
});
|
||||||
|
|
||||||
|
$response = $app->server->serve();
|
||||||
|
|
||||||
|
$response->send();
|
||||||
|
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Post("/live/notify", name="home.live_notify")
|
* @Post("/live/notify", name="home.live_notify")
|
||||||
*/
|
*/
|
||||||
|
@ -7,7 +7,6 @@
|
|||||||
|
|
||||||
namespace App\Http\Home\Controllers;
|
namespace App\Http\Home\Controllers;
|
||||||
|
|
||||||
use App\Http\Home\Services\FullH5Url as FullH5UrlService;
|
|
||||||
use App\Http\Home\Services\Question as QuestionService;
|
use App\Http\Home\Services\Question as QuestionService;
|
||||||
use App\Http\Home\Services\QuestionQuery as QuestionQueryService;
|
use App\Http\Home\Services\QuestionQuery as QuestionQueryService;
|
||||||
use App\Models\Question as QuestionModel;
|
use App\Models\Question as QuestionModel;
|
||||||
@ -20,6 +19,7 @@ use App\Services\Logic\Question\QuestionLike as QuestionLikeService;
|
|||||||
use App\Services\Logic\Question\QuestionList as QuestionListService;
|
use App\Services\Logic\Question\QuestionList as QuestionListService;
|
||||||
use App\Services\Logic\Question\QuestionUpdate as QuestionUpdateService;
|
use App\Services\Logic\Question\QuestionUpdate as QuestionUpdateService;
|
||||||
use App\Services\Logic\Question\RelatedQuestionList as RelatedQuestionListService;
|
use App\Services\Logic\Question\RelatedQuestionList as RelatedQuestionListService;
|
||||||
|
use App\Services\Logic\Url\FullH5Url as FullH5UrlService;
|
||||||
use Phalcon\Mvc\View;
|
use Phalcon\Mvc\View;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -7,9 +7,9 @@
|
|||||||
|
|
||||||
namespace App\Http\Home\Controllers;
|
namespace App\Http\Home\Controllers;
|
||||||
|
|
||||||
use App\Http\Home\Services\FullH5Url as FullH5UrlService;
|
|
||||||
use App\Services\Logic\Teacher\CourseList as TeacherCourseListService;
|
use App\Services\Logic\Teacher\CourseList as TeacherCourseListService;
|
||||||
use App\Services\Logic\Teacher\TeacherList as TeacherListService;
|
use App\Services\Logic\Teacher\TeacherList as TeacherListService;
|
||||||
|
use App\Services\Logic\Url\FullH5Url as FullH5UrlService;
|
||||||
use App\Services\Logic\User\UserInfo as UserInfoService;
|
use App\Services\Logic\User\UserInfo as UserInfoService;
|
||||||
use Phalcon\Mvc\View;
|
use Phalcon\Mvc\View;
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
namespace App\Http\Home\Controllers;
|
namespace App\Http\Home\Controllers;
|
||||||
|
|
||||||
use App\Http\Home\Services\FullH5Url as FullH5UrlService;
|
use App\Services\Logic\Url\FullH5Url as FullH5UrlService;
|
||||||
use App\Services\Logic\User\AnswerList as UserAnswerListService;
|
use App\Services\Logic\User\AnswerList as UserAnswerListService;
|
||||||
use App\Services\Logic\User\ArticleList as UserArticleListService;
|
use App\Services\Logic\User\ArticleList as UserArticleListService;
|
||||||
use App\Services\Logic\User\CourseList as UserCourseListService;
|
use App\Services\Logic\User\CourseList as UserCourseListService;
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
namespace App\Http\Home\Controllers;
|
namespace App\Http\Home\Controllers;
|
||||||
|
|
||||||
use App\Http\Home\Services\FullH5Url as FullH5UrlService;
|
use App\Services\Logic\Url\FullH5Url as FullH5UrlService;
|
||||||
use App\Services\Logic\Vip\CourseList as VipCourseListService;
|
use App\Services\Logic\Vip\CourseList as VipCourseListService;
|
||||||
use App\Services\Logic\Vip\OptionList as VipOptionListService;
|
use App\Services\Logic\Vip\OptionList as VipOptionListService;
|
||||||
use App\Services\Logic\Vip\UserList as VipUserListService;
|
use App\Services\Logic\Vip\UserList as VipUserListService;
|
||||||
|
@ -7,31 +7,59 @@
|
|||||||
|
|
||||||
namespace App\Http\Home\Controllers;
|
namespace App\Http\Home\Controllers;
|
||||||
|
|
||||||
use App\Http\Home\Services\WeChatOfficialAccount as WeChatOAService;
|
use App\Http\Home\Services\WeChatOfficialAccount as HomeWeChatOAService;
|
||||||
|
use App\Services\Logic\WeChat\OfficialAccount as WeChatOAService;
|
||||||
use App\Traits\Response as ResponseTrait;
|
use App\Traits\Response as ResponseTrait;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @RoutePrefix("/wechat/oa")
|
* @RoutePrefix("/wechat/oa")
|
||||||
*/
|
*/
|
||||||
class WeChatOfficialAccountController extends \Phalcon\Mvc\Controller
|
class WeChatOfficialAccountController extends Controller
|
||||||
{
|
{
|
||||||
|
|
||||||
use ResponseTrait;
|
use ResponseTrait;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Get("/subscribe/status", name="home.wechat_oa.sub_status")
|
* @Get("/bind", name="home.wechat_oa.bind")
|
||||||
*/
|
*/
|
||||||
public function subscribeStatusAction()
|
public function bindAction()
|
||||||
{
|
{
|
||||||
$service = new WeChatOAService();
|
$captcha = $this->getSettings('captcha');
|
||||||
|
|
||||||
$status = $service->getSubscribeStatus();
|
$this->seo->prependTitle('绑定帐号');
|
||||||
|
|
||||||
return $this->jsonSuccess(['status' => $status]);
|
$this->view->pick('wechat/oa/bind');
|
||||||
|
$this->view->setVar('captcha', $captcha);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Get("/subscribe/qrcode", name="home.wechat_oa.sub_qrcode")
|
* @Get("/login/qrcode", name="home.wechat_oa.login_qrcode")
|
||||||
|
*/
|
||||||
|
public function loginQrCodeAction()
|
||||||
|
{
|
||||||
|
$service = new WeChatOAService();
|
||||||
|
|
||||||
|
$qrcode = $service->createLoginQrCode();
|
||||||
|
|
||||||
|
return $this->jsonSuccess(['qrcode' => $qrcode]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Get("/login/status", name="home.wechat_oa.lgoin_status")
|
||||||
|
*/
|
||||||
|
public function loginStatusAction()
|
||||||
|
{
|
||||||
|
$ticket = $this->request->getQuery('ticket');
|
||||||
|
|
||||||
|
$service = new WeChatOAService();
|
||||||
|
|
||||||
|
$data = $service->getLoginStatus($ticket);
|
||||||
|
|
||||||
|
return $this->jsonSuccess(['data' => $data]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Get("/subscribe/qrcode", name="home.wechat_oa.subscribe_qrcode")
|
||||||
*/
|
*/
|
||||||
public function subscribeQrCodeAction()
|
public function subscribeQrCodeAction()
|
||||||
{
|
{
|
||||||
@ -43,39 +71,63 @@ class WeChatOfficialAccountController extends \Phalcon\Mvc\Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Get("/notify", name="home.wechat_oa.verify")
|
* @Get("/subscribe/status", name="home.wechat_oa.subscribe_status")
|
||||||
*/
|
*/
|
||||||
public function verifyAction()
|
public function subscribeStatusAction()
|
||||||
{
|
{
|
||||||
$service = new WeChatOAService();
|
$service = new WeChatOAService();
|
||||||
|
|
||||||
$app = $service->getOfficialAccount();
|
$status = $service->getSubscribeStatus();
|
||||||
|
|
||||||
$response = $app->server->serve();
|
return $this->jsonSuccess(['status' => $status]);
|
||||||
|
|
||||||
$response->send();
|
|
||||||
|
|
||||||
exit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Post("/notify", name="home.wechat_oa.notify")
|
* @Post("/auth/login", name="home.wechat_oa.auth_login")
|
||||||
*/
|
*/
|
||||||
public function notifyAction()
|
public function authLoginAction()
|
||||||
{
|
{
|
||||||
$service = new WeChatOAService();
|
$service = new HomeWeChatOAService();
|
||||||
|
|
||||||
$app = $service->getOfficialAccount();
|
$service->authLogin();
|
||||||
|
|
||||||
$app->server->push(function ($message) use ($service) {
|
$returnUrl = $this->request->getPost('return_url', 'string');
|
||||||
return $service->handleNotify($message);
|
|
||||||
});
|
|
||||||
|
|
||||||
$response = $app->server->serve();
|
$location = $returnUrl ?: $this->url->get(['for' => 'home.index']);
|
||||||
|
|
||||||
$response->send();
|
return $this->jsonSuccess(['location' => $location]);
|
||||||
|
}
|
||||||
|
|
||||||
exit;
|
/**
|
||||||
|
* @Post("/bind/login", name="home.wechat_oa.bind_login")
|
||||||
|
*/
|
||||||
|
public function bindLoginAction()
|
||||||
|
{
|
||||||
|
$service = new HomeWeChatOAService();
|
||||||
|
|
||||||
|
$service->bindLogin();
|
||||||
|
|
||||||
|
$returnUrl = $this->request->getPost('return_url', 'string');
|
||||||
|
|
||||||
|
$location = $returnUrl ?: $this->url->get(['for' => 'home.index']);
|
||||||
|
|
||||||
|
return $this->jsonSuccess(['location' => $location]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Post("/bind/register", name="home.wechat_oa.bind_register")
|
||||||
|
*/
|
||||||
|
public function bindRegisterAction()
|
||||||
|
{
|
||||||
|
$service = new HomeWeChatOAService();
|
||||||
|
|
||||||
|
$service->bindRegister();
|
||||||
|
|
||||||
|
$returnUrl = $this->request->getPost('return_url', 'string');
|
||||||
|
|
||||||
|
$location = $returnUrl ?: $this->url->get(['for' => 'home.index']);
|
||||||
|
|
||||||
|
return $this->jsonSuccess(['location' => $location]);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -101,6 +101,10 @@ class Connect extends Service
|
|||||||
|
|
||||||
$user = $userRepo->findById($connect->user_id);
|
$user = $userRepo->findById($connect->user_id);
|
||||||
|
|
||||||
|
$validator = new AccountValidator();
|
||||||
|
|
||||||
|
$validator->checkIfAllowLogin($user);
|
||||||
|
|
||||||
$this->handleLoginNotice($user);
|
$this->handleLoginNotice($user);
|
||||||
|
|
||||||
$auth = $this->getAppAuth();
|
$auth = $this->getAppAuth();
|
||||||
|
@ -1,153 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
|
|
||||||
* @license https://opensource.org/licenses/GPL-2.0
|
|
||||||
* @link https://www.koogua.com
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace App\Http\Home\Services;
|
|
||||||
|
|
||||||
use App\Models\Course as CourseModel;
|
|
||||||
use App\Repos\Chapter as ChapterRepo;
|
|
||||||
use App\Traits\Client as ClientTrait;
|
|
||||||
|
|
||||||
class FullH5Url extends Service
|
|
||||||
{
|
|
||||||
|
|
||||||
protected $baseUrl;
|
|
||||||
|
|
||||||
use ClientTrait;
|
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
$this->baseUrl = $this->getBaseUrl();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getHomeUrl()
|
|
||||||
{
|
|
||||||
return sprintf('%s/index/index', $this->baseUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getAccountRegisterUrl()
|
|
||||||
{
|
|
||||||
return sprintf('%s/account/register', $this->baseUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getAccountLoginUrl()
|
|
||||||
{
|
|
||||||
return sprintf('%s/account/login', $this->baseUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getAccountForgetUrl()
|
|
||||||
{
|
|
||||||
return sprintf('%s/account/forget', $this->baseUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getVipIndexUrl()
|
|
||||||
{
|
|
||||||
return sprintf('%s/vip/index', $this->baseUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getHelpIndexUrl()
|
|
||||||
{
|
|
||||||
return sprintf('%s/help/index', $this->baseUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getCourseListUrl()
|
|
||||||
{
|
|
||||||
return sprintf('%s/course/list', $this->baseUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getArticleListUrl()
|
|
||||||
{
|
|
||||||
return sprintf('%s/article/list', $this->baseUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getQuestionListUrl()
|
|
||||||
{
|
|
||||||
return sprintf('%s/question/list', $this->baseUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getLiveListUrl()
|
|
||||||
{
|
|
||||||
return sprintf('%s/discovery/index', $this->baseUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getTeacherListUrl()
|
|
||||||
{
|
|
||||||
return sprintf('%s/discovery/index', $this->baseUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getPointGiftListUrl()
|
|
||||||
{
|
|
||||||
return sprintf('%s/point/gift/list', $this->baseUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getPageInfoUrl($id)
|
|
||||||
{
|
|
||||||
return sprintf('%s/page/info?id=%s', $this->baseUrl, $id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getHelpInfoUrl($id)
|
|
||||||
{
|
|
||||||
return sprintf('%s/help/info?id=%s', $this->baseUrl, $id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getArticleInfoUrl($id)
|
|
||||||
{
|
|
||||||
return sprintf('%s/article/info?id=%s', $this->baseUrl, $id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getQuestionInfoUrl($id)
|
|
||||||
{
|
|
||||||
return sprintf('%s/question/info?id=%s', $this->baseUrl, $id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getAnswerInfoUrl($id)
|
|
||||||
{
|
|
||||||
return sprintf('%s/answer/info?id=%s', $this->baseUrl, $id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getCourseInfoUrl($id)
|
|
||||||
{
|
|
||||||
return sprintf('%s/course/info?id=%s', $this->baseUrl, $id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getChapterInfoUrl($id)
|
|
||||||
{
|
|
||||||
$chapterRepo = new ChapterRepo();
|
|
||||||
|
|
||||||
$chapter = $chapterRepo->findById($id);
|
|
||||||
|
|
||||||
if ($chapter->model == CourseModel::MODEL_VOD) {
|
|
||||||
return sprintf('%s/chapter/vod?id=%s', $this->baseUrl, $id);
|
|
||||||
} elseif ($chapter->model == CourseModel::MODEL_LIVE) {
|
|
||||||
return sprintf('%s/chapter/live?id=%s', $this->baseUrl, $id);
|
|
||||||
} elseif ($chapter->model == CourseModel::MODEL_READ) {
|
|
||||||
return sprintf('%s/chapter/read?id=%s', $this->baseUrl, $id);
|
|
||||||
} else {
|
|
||||||
return $this->getHomeUrl();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getUserIndexUrl($id)
|
|
||||||
{
|
|
||||||
return sprintf('%s/user/index?id=%s', $this->baseUrl, $id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getTeacherIndexUrl($id)
|
|
||||||
{
|
|
||||||
return sprintf('%s/teacher/index?id=%s', $this->baseUrl, $id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getPointGiftInfoUrl($id)
|
|
||||||
{
|
|
||||||
return sprintf('%s/point/gift/info?id=%s', $this->baseUrl, $id);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getBaseUrl()
|
|
||||||
{
|
|
||||||
return sprintf('%s/h5/#/pages', kg_site_url());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,79 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
|
|
||||||
* @license https://opensource.org/licenses/GPL-2.0
|
|
||||||
* @link https://www.koogua.com
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace App\Http\Home\Services;
|
|
||||||
|
|
||||||
class FullWebUrl extends Service
|
|
||||||
{
|
|
||||||
|
|
||||||
protected $baseUrl;
|
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
$this->baseUrl = $this->getBaseUrl();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getHomeUrl()
|
|
||||||
{
|
|
||||||
return $this->baseUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getArticleShowUrl($id)
|
|
||||||
{
|
|
||||||
$route = $this->url->get(['for' => 'home.article.show', 'id' => $id]);
|
|
||||||
|
|
||||||
return $this->baseUrl . $route;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getQuestionShowUrl($id)
|
|
||||||
{
|
|
||||||
$route = $this->url->get(['for' => 'home.question.show', 'id' => $id]);
|
|
||||||
|
|
||||||
return $this->baseUrl . $route;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getCourseShowUrl($id)
|
|
||||||
{
|
|
||||||
$route = $this->url->get(['for' => 'home.course.show', 'id' => $id]);
|
|
||||||
|
|
||||||
return $this->baseUrl . $route;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getChapterShowUrl($id)
|
|
||||||
{
|
|
||||||
$route = $this->url->get(['for' => 'home.chapter.show', 'id' => $id]);
|
|
||||||
|
|
||||||
return $this->baseUrl . $route;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getUserShowUrl($id)
|
|
||||||
{
|
|
||||||
$route = $this->url->get(['for' => 'home.user.show', 'id' => $id]);
|
|
||||||
|
|
||||||
return $this->baseUrl . $route;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getTeacherShowUrl($id)
|
|
||||||
{
|
|
||||||
$route = $this->url->get(['for' => 'home.teacher.show', 'id' => $id]);
|
|
||||||
|
|
||||||
return $this->baseUrl . $route;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getPointGiftShowUrl($id)
|
|
||||||
{
|
|
||||||
$route = $this->url->get(['for' => 'home.point_gift.show', 'id' => $id]);
|
|
||||||
|
|
||||||
return $this->baseUrl . $route;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getBaseUrl()
|
|
||||||
{
|
|
||||||
return kg_site_url();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,123 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
|
|
||||||
* @license https://opensource.org/licenses/GPL-2.0
|
|
||||||
* @link https://www.koogua.com
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace App\Http\Home\Services;
|
|
||||||
|
|
||||||
use App\Traits\Client as ClientTrait;
|
|
||||||
|
|
||||||
class ShareUrl extends Service
|
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
|
||||||
* WEB站点URL
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $fullWebUrl;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* H5站点URL
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $fullH5Url;
|
|
||||||
|
|
||||||
use ClientTrait;
|
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
$this->fullWebUrl = new FullWebUrl();
|
|
||||||
$this->fullH5Url = new FullH5Url();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function handle($id, $type)
|
|
||||||
{
|
|
||||||
if ($type == 'article') {
|
|
||||||
$result = $this->getArticleUrl($id);
|
|
||||||
} elseif ($type == 'question') {
|
|
||||||
$result = $this->getQuestionUrl($id);
|
|
||||||
} elseif ($type == 'course') {
|
|
||||||
$result = $this->getCourseUrl($id);
|
|
||||||
} elseif ($type == 'chapter') {
|
|
||||||
$result = $this->getChapterUrl($id);
|
|
||||||
} elseif ($type == 'user') {
|
|
||||||
$result = $this->getUserUrl($id);
|
|
||||||
} elseif ($type == 'teacher') {
|
|
||||||
$result = $this->getTeacherUrl($id);
|
|
||||||
} else {
|
|
||||||
$result = $this->getHomeUrl();
|
|
||||||
}
|
|
||||||
|
|
||||||
$gotoH5 = $this->h5Enabled() && $this->isMobileBrowser();
|
|
||||||
|
|
||||||
return $gotoH5 ? $result['h5'] : $result['web'];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getHomeUrl()
|
|
||||||
{
|
|
||||||
$webUrl = $this->fullWebUrl->getHomeUrl();
|
|
||||||
|
|
||||||
$h5Url = $this->fullH5Url->getHomeUrl();
|
|
||||||
|
|
||||||
return ['web' => $webUrl, 'h5' => $h5Url];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getArticleUrl($id = 0)
|
|
||||||
{
|
|
||||||
$webUrl = $this->fullWebUrl->getArticleShowUrl($id);
|
|
||||||
|
|
||||||
$h5Url = $this->fullH5Url->getArticleInfoUrl($id);
|
|
||||||
|
|
||||||
return ['web' => $webUrl, 'h5' => $h5Url];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getQuestionUrl($id = 0)
|
|
||||||
{
|
|
||||||
$webUrl = $this->fullWebUrl->getQuestionShowUrl($id);
|
|
||||||
|
|
||||||
$h5Url = $this->fullH5Url->getQuestionInfoUrl($id);
|
|
||||||
|
|
||||||
return ['web' => $webUrl, 'h5' => $h5Url];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getCourseUrl($id = 0)
|
|
||||||
{
|
|
||||||
$webUrl = $this->fullWebUrl->getCourseShowUrl($id);
|
|
||||||
|
|
||||||
$h5Url = $this->fullH5Url->getCourseInfoUrl($id);
|
|
||||||
|
|
||||||
return ['web' => $webUrl, 'h5' => $h5Url];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getChapterUrl($id = 0)
|
|
||||||
{
|
|
||||||
$webUrl = $this->fullWebUrl->getChapterShowUrl($id);
|
|
||||||
|
|
||||||
$h5Url = $this->fullH5Url->getChapterInfoUrl($id);
|
|
||||||
|
|
||||||
return ['web' => $webUrl, 'h5' => $h5Url];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getUserUrl($id = 0)
|
|
||||||
{
|
|
||||||
$webUrl = $this->fullWebUrl->getUserShowUrl($id);
|
|
||||||
|
|
||||||
$h5Url = $this->fullH5Url->getUserIndexUrl($id);
|
|
||||||
|
|
||||||
return ['web' => $webUrl, 'h5' => $h5Url];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getTeacherUrl($id = 0)
|
|
||||||
{
|
|
||||||
$webUrl = $this->fullWebUrl->getTeacherShowUrl($id);
|
|
||||||
|
|
||||||
$h5Url = $this->fullH5Url->getTeacherIndexUrl($id);
|
|
||||||
|
|
||||||
return ['web' => $webUrl, 'h5' => $h5Url];
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -7,242 +7,119 @@
|
|||||||
|
|
||||||
namespace App\Http\Home\Services;
|
namespace App\Http\Home\Services;
|
||||||
|
|
||||||
use App\Models\WeChatSubscribe as WeChatSubscribeModel;
|
use App\Models\Connect as ConnectModel;
|
||||||
|
use App\Models\User as UserModel;
|
||||||
|
use App\Repos\Connect as ConnectRepo;
|
||||||
use App\Repos\User as UserRepo;
|
use App\Repos\User as UserRepo;
|
||||||
use App\Repos\WeChatSubscribe as WeChatSubscribeRepo;
|
use App\Services\Auth\Home as AuthService;
|
||||||
use App\Services\WeChat as WeChatService;
|
use App\Services\Logic\Account\Register as RegisterService;
|
||||||
use EasyWeChat\Kernel\Messages\Text as TextMessage;
|
use App\Services\Logic\Notice\External\AccountLogin as AccountLoginNotice;
|
||||||
|
use App\Validators\Account as AccountValidator;
|
||||||
|
use App\Validators\WeChatOfficialAccount as WeChatOAValidator;
|
||||||
|
|
||||||
class WeChatOfficialAccount extends Service
|
class WeChatOfficialAccount extends Service
|
||||||
{
|
{
|
||||||
|
|
||||||
public function getOfficialAccount()
|
public function authLogin()
|
||||||
{
|
{
|
||||||
$service = new WeChatService();
|
$ticket = $this->request->getPost('ticket');
|
||||||
|
|
||||||
return $service->getOfficialAccount();
|
$validator = new WeChatOAValidator();
|
||||||
}
|
|
||||||
|
|
||||||
public function createSubscribeQrCode()
|
$openId = $validator->checkLoginOpenId($ticket);
|
||||||
{
|
|
||||||
$user = $this->getLoginUser();
|
|
||||||
|
|
||||||
$app = $this->getOfficialAccount();
|
$connectRepo = new ConnectRepo();
|
||||||
|
|
||||||
$result = $app->qrcode->temporary($user->id);
|
$connect = $connectRepo->findByOpenId($openId, ConnectModel::PROVIDER_WECHAT_OA);
|
||||||
|
|
||||||
return $app->qrcode->url($result['ticket']);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getSubscribeStatus()
|
|
||||||
{
|
|
||||||
$user = $this->getLoginUser();
|
|
||||||
|
|
||||||
$subscribeRepo = new WeChatSubscribeRepo();
|
|
||||||
|
|
||||||
$subscribe = $subscribeRepo->findByUserId($user->id);
|
|
||||||
|
|
||||||
return $subscribe ? 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function handleNotify($message)
|
|
||||||
{
|
|
||||||
$service = new WeChatService();
|
|
||||||
|
|
||||||
$service->logger->debug('Received Message ' . json_encode($message));
|
|
||||||
|
|
||||||
switch ($message['MsgType']) {
|
|
||||||
case 'event':
|
|
||||||
switch ($message['Event']) {
|
|
||||||
case 'subscribe':
|
|
||||||
return $this->handleSubscribeEvent($message);
|
|
||||||
case 'unsubscribe':
|
|
||||||
return $this->handleUnsubscribeEvent($message);
|
|
||||||
case 'SCAN':
|
|
||||||
return $this->handleScanEvent($message);
|
|
||||||
case 'CLICK':
|
|
||||||
return $this->handleClickEvent($message);
|
|
||||||
case 'VIEW':
|
|
||||||
return $this->handleViewEvent($message);
|
|
||||||
case 'LOCATION':
|
|
||||||
return $this->handleLocationEvent($message);
|
|
||||||
default:
|
|
||||||
return $this->noMatchReply();
|
|
||||||
}
|
|
||||||
case 'text':
|
|
||||||
return $this->handleTextReply($message);
|
|
||||||
case 'image':
|
|
||||||
return $this->handleImageReply($message);
|
|
||||||
case 'voice':
|
|
||||||
return $this->handleVoiceReply($message);
|
|
||||||
case 'video':
|
|
||||||
return $this->handleVideoReply($message);
|
|
||||||
case 'shortvideo':
|
|
||||||
return $this->handleShortVideoReply($message);
|
|
||||||
case 'location':
|
|
||||||
return $this->handleLocationReply($message);
|
|
||||||
case 'link':
|
|
||||||
return $this->handleLinkReply($message);
|
|
||||||
default:
|
|
||||||
return $this->noMatchReply();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function handleSubscribeEvent($message)
|
|
||||||
{
|
|
||||||
$openId = $message['FromUserName'] ?? '';
|
|
||||||
$eventKey = $message['EventKey'] ?? '';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 带场景值的关注事件
|
|
||||||
*/
|
|
||||||
$userId = str_replace('qrscene_', '', $eventKey);
|
|
||||||
|
|
||||||
if ($userId && $openId) {
|
|
||||||
$this->saveWechatSubscribe($userId, $openId);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new TextMessage('开心呀,我们又多了一个小伙伴!');
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function handleUnsubscribeEvent($message)
|
|
||||||
{
|
|
||||||
$openId = $message['FromUserName'] ?? '';
|
|
||||||
|
|
||||||
$subscribeRepo = new WeChatSubscribeRepo();
|
|
||||||
|
|
||||||
$subscribe = $subscribeRepo->findByOpenId($openId);
|
|
||||||
|
|
||||||
if ($subscribe) {
|
|
||||||
$subscribe->deleted = 1;
|
|
||||||
$subscribe->update();
|
|
||||||
}
|
|
||||||
|
|
||||||
return new TextMessage('伤心呀,我们又少了一个小伙伴!');
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function handleScanEvent($message)
|
|
||||||
{
|
|
||||||
$openId = $message['FromUserName'] ?? '';
|
|
||||||
$eventKey = $message['EventKey'] ?? '';
|
|
||||||
|
|
||||||
$userId = str_replace('qrscene_', '', $eventKey);
|
|
||||||
|
|
||||||
if ($userId && $openId) {
|
|
||||||
$userInfo = $this->getUserInfo($openId);
|
|
||||||
$unionId = $userInfo['unionid'] ?: '';
|
|
||||||
$this->saveWechatSubscribe($userId, $openId, $unionId);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->emptyReply();
|
|
||||||
}
|
|
||||||
|
|
||||||
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('没有匹配的服务哦!');
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function saveWechatSubscribe($userId, $openId, $unionId = '')
|
|
||||||
{
|
|
||||||
if (!$userId || !$openId) return;
|
|
||||||
|
|
||||||
$userRepo = new UserRepo();
|
$userRepo = new UserRepo();
|
||||||
|
|
||||||
$user = $userRepo->findById($userId);
|
$user = $userRepo->findById($connect->user_id);
|
||||||
|
|
||||||
if (!$user) return;
|
$validator = new AccountValidator();
|
||||||
|
|
||||||
$subscribeRepo = new WeChatSubscribeRepo();
|
$validator->checkIfAllowLogin($user);
|
||||||
|
|
||||||
$subscribe = $subscribeRepo->findByOpenId($openId);
|
$this->handleLoginNotice($user);
|
||||||
|
|
||||||
if ($subscribe) {
|
$auth = $this->getAppAuth();
|
||||||
if ($subscribe->user_id != $userId) {
|
|
||||||
$subscribe->user_id = $userId;
|
$auth->saveAuthInfo($user);
|
||||||
}
|
|
||||||
if (empty($subscribe->union_id) && !empty($unionId)) {
|
|
||||||
$subscribe->union_id = $unionId;
|
|
||||||
}
|
|
||||||
if ($subscribe->deleted == 1) {
|
|
||||||
$subscribe->deleted = 0;
|
|
||||||
}
|
|
||||||
$subscribe->update();
|
|
||||||
} else {
|
|
||||||
$subscribe = new WeChatSubscribeModel();
|
|
||||||
$subscribe->user_id = $userId;
|
|
||||||
$subscribe->open_id = $openId;
|
|
||||||
$subscribe->union_id = $unionId;
|
|
||||||
$subscribe->create();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getUserInfo($openId)
|
public function bindLogin()
|
||||||
{
|
{
|
||||||
$app = $this->getOfficialAccount();
|
$post = $this->request->getPost();
|
||||||
|
|
||||||
return $app->user->get($openId);
|
$validator = new AccountValidator();
|
||||||
|
|
||||||
|
$user = $validator->checkUserLogin($post['account'], $post['password']);
|
||||||
|
|
||||||
|
$validator = new WeChatOAValidator();
|
||||||
|
|
||||||
|
$openId = $validator->checkLoginOpenId($post['ticket']);
|
||||||
|
|
||||||
|
$connect = new ConnectModel();
|
||||||
|
|
||||||
|
$connect->user_id = $user->id;
|
||||||
|
$connect->open_id = $openId;
|
||||||
|
$connect->provider = ConnectModel::PROVIDER_WECHAT_OA;
|
||||||
|
|
||||||
|
$connect->create();
|
||||||
|
|
||||||
|
$this->handleLoginNotice($user);
|
||||||
|
|
||||||
|
$auth = $this->getAppAuth();
|
||||||
|
|
||||||
|
$auth->saveAuthInfo($user);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getWechatLogger()
|
public function bindRegister()
|
||||||
{
|
{
|
||||||
$service = new WeChatService();
|
$post = $this->request->getPost();
|
||||||
|
|
||||||
return $service->logger;
|
$validator = new WeChatOAValidator();
|
||||||
|
|
||||||
|
$openId = $validator->checkLoginOpenId($post['ticket']);
|
||||||
|
|
||||||
|
$registerService = new RegisterService();
|
||||||
|
|
||||||
|
$account = $registerService->handle();
|
||||||
|
|
||||||
|
$userRepo = new UserRepo();
|
||||||
|
|
||||||
|
$user = $userRepo->findById($account->id);
|
||||||
|
|
||||||
|
$connect = new ConnectModel();
|
||||||
|
|
||||||
|
$connect->user_id = $user->id;
|
||||||
|
$connect->open_id = $openId;
|
||||||
|
$connect->provider = ConnectModel::PROVIDER_WECHAT_OA;
|
||||||
|
|
||||||
|
$connect->create();
|
||||||
|
|
||||||
|
$this->handleLoginNotice($user);
|
||||||
|
|
||||||
|
$auth = $this->getAppAuth();
|
||||||
|
|
||||||
|
$auth->saveAuthInfo($user);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getAppAuth()
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var $auth AuthService
|
||||||
|
*/
|
||||||
|
$auth = $this->getDI()->get('auth');
|
||||||
|
|
||||||
|
return $auth;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function handleLoginNotice(UserModel $user)
|
||||||
|
{
|
||||||
|
$notice = new AccountLoginNotice();
|
||||||
|
|
||||||
|
$notice->createTask($user);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ class AppInfo
|
|||||||
|
|
||||||
protected $link = 'https://www.koogua.com';
|
protected $link = 'https://www.koogua.com';
|
||||||
|
|
||||||
protected $version = '1.7.0';
|
protected $version = '1.7.1';
|
||||||
|
|
||||||
public function __get($name)
|
public function __get($name)
|
||||||
{
|
{
|
||||||
|
@ -42,7 +42,7 @@ class XunSearch extends PaginatorAdapter
|
|||||||
|
|
||||||
public function __construct(array $config)
|
public function __construct(array $config)
|
||||||
{
|
{
|
||||||
if (!isset($config['xs']) || ($config['xs'] instanceof \XS) == false) {
|
if (!isset($config['xs']) || !($config['xs'] instanceof \XS)) {
|
||||||
throw new PaginatorException('Invalid xs parameter');
|
throw new PaginatorException('Invalid xs parameter');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,9 @@ class Connect extends Model
|
|||||||
const PROVIDER_QQ = 1; // QQ
|
const PROVIDER_QQ = 1; // QQ
|
||||||
const PROVIDER_WEIXIN = 2; // 微信扫码
|
const PROVIDER_WEIXIN = 2; // 微信扫码
|
||||||
const PROVIDER_WEIBO = 3; // 新浪微博
|
const PROVIDER_WEIBO = 3; // 新浪微博
|
||||||
const PROVIDER_WECHAT = 4; // 公众号网页
|
const PROVIDER_WECHAT_OA = 4; // 微信公众号
|
||||||
|
const PROVIDER_WECHAT_MINI = 5; // 微信小程序
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 主键编号
|
* 主键编号
|
||||||
|
@ -67,4 +67,17 @@ class Connect extends Repository
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $userId
|
||||||
|
* @param int $provider
|
||||||
|
* @return ConnectModel|Model|bool
|
||||||
|
*/
|
||||||
|
public function findByUserId($userId, $provider)
|
||||||
|
{
|
||||||
|
return ConnectModel::findFirst([
|
||||||
|
'conditions' => 'user_id = ?1 AND provider = ?2 AND deleted = 0',
|
||||||
|
'bind' => [1 => $userId, 2 => $provider],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -43,10 +43,10 @@ class AccountLogin extends WeChatNotice
|
|||||||
$params = [
|
$params = [
|
||||||
'first' => $first,
|
'first' => $first,
|
||||||
'remark' => $remark,
|
'remark' => $remark,
|
||||||
'keyword1' => $loginUser,
|
'thing3' => $loginUser,
|
||||||
'keyword2' => $loginTime,
|
'time2' => $loginTime,
|
||||||
'keyword3' => $loginRegion,
|
'thing7' => $loginRegion,
|
||||||
'keyword4' => $loginIp,
|
'character_string8' => $loginIp,
|
||||||
];
|
];
|
||||||
|
|
||||||
$templateId = $this->getTemplateId($this->templateCode);
|
$templateId = $this->getTemplateId($this->templateCode);
|
||||||
|
@ -33,9 +33,9 @@ class GoodsDeliver extends WeChatNotice
|
|||||||
$params = [
|
$params = [
|
||||||
'first' => $first,
|
'first' => $first,
|
||||||
'remark' => $remark,
|
'remark' => $remark,
|
||||||
'keyword1' => $params['order_sn'],
|
'character_string12' => $params['order_sn'],
|
||||||
'keyword2' => $params['goods_name'],
|
'thing14' => $params['goods_name'],
|
||||||
'keyword3' => date('Y-m-d H:i', $params['deliver_time']),
|
'time3' => date('Y-m-d H:i', $params['deliver_time']),
|
||||||
];
|
];
|
||||||
|
|
||||||
$templateId = $this->getTemplateId($this->templateCode);
|
$templateId = $this->getTemplateId($this->templateCode);
|
||||||
|
@ -33,9 +33,9 @@ class OrderFinish extends WeChatNotice
|
|||||||
$params = [
|
$params = [
|
||||||
'first' => $first,
|
'first' => $first,
|
||||||
'remark' => $remark,
|
'remark' => $remark,
|
||||||
'keyword1' => sprintf('%s元', $params['order']['amount']),
|
'amount3' => sprintf('%s元', $params['order']['amount']),
|
||||||
'keyword2' => $params['order']['subject'],
|
'thing1' => $params['order']['subject'],
|
||||||
'keyword3' => date('Y-m-d H:i', $params['order']['update_time']),
|
'time4' => date('Y-m-d H:i', $params['order']['update_time']),
|
||||||
];
|
];
|
||||||
|
|
||||||
$templateId = $this->getTemplateId($this->templateCode);
|
$templateId = $this->getTemplateId($this->templateCode);
|
||||||
|
@ -33,10 +33,10 @@ class RefundFinish extends WeChatNotice
|
|||||||
$params = [
|
$params = [
|
||||||
'first' => $first,
|
'first' => $first,
|
||||||
'remark' => $remark,
|
'remark' => $remark,
|
||||||
'keyword1' => $params['refund']['sn'],
|
'character_string5' => $params['refund']['sn'],
|
||||||
'keyword2' => $params['refund']['subject'],
|
'thing1' => $params['refund']['subject'],
|
||||||
'keyword3' => sprintf('%s元', $params['refund']['amount']),
|
'amount2' => sprintf('%s元', $params['refund']['amount']),
|
||||||
'keyword4' => date('Y-m-d H:i', $params['refund']['update_time']),
|
'time4' => date('Y-m-d H:i', $params['refund']['update_time']),
|
||||||
];
|
];
|
||||||
|
|
||||||
$templateId = $this->getTemplateId($this->templateCode);
|
$templateId = $this->getTemplateId($this->templateCode);
|
||||||
|
@ -116,11 +116,6 @@ class FullH5Url extends AppService
|
|||||||
return $this->getFullUrl('/question/info', ['id' => $id]);
|
return $this->getFullUrl('/question/info', ['id' => $id]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getAnswerInfoUrl($id)
|
|
||||||
{
|
|
||||||
return $this->getFullUrl('/answer/info', ['id' => $id]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getTopicInfoUrl($id)
|
public function getTopicInfoUrl($id)
|
||||||
{
|
{
|
||||||
return $this->getFullUrl('/topic/info', ['id' => $id]);
|
return $this->getFullUrl('/topic/info', ['id' => $id]);
|
||||||
|
@ -48,6 +48,8 @@ class ShareUrl extends AppService
|
|||||||
$result = $this->getArticleUrl($id);
|
$result = $this->getArticleUrl($id);
|
||||||
} elseif ($type == 'page') {
|
} elseif ($type == 'page') {
|
||||||
$result = $this->getPageUrl($id);
|
$result = $this->getPageUrl($id);
|
||||||
|
} elseif ($type == 'help') {
|
||||||
|
$result = $this->getHelpUrl($id);
|
||||||
} elseif ($type == 'question') {
|
} elseif ($type == 'question') {
|
||||||
$result = $this->getQuestionUrl($id);
|
$result = $this->getQuestionUrl($id);
|
||||||
} elseif ($type == 'course') {
|
} elseif ($type == 'course') {
|
||||||
|
317
app/Services/Logic/WeChat/OfficialAccount.php
Normal file
317
app/Services/Logic/WeChat/OfficialAccount.php
Normal file
@ -0,0 +1,317 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
|
||||||
|
* @license https://opensource.org/licenses/GPL-2.0
|
||||||
|
* @link https://www.koogua.com
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Services\Logic\WeChat;
|
||||||
|
|
||||||
|
use App\Models\Connect as ConnectModel;
|
||||||
|
use App\Repos\Connect as ConnectRepo;
|
||||||
|
use App\Services\Service as AppService;
|
||||||
|
use App\Services\WeChat as WeChatService;
|
||||||
|
use EasyWeChat\Kernel\Messages\Text as TextMessage;
|
||||||
|
use Phalcon\Text;
|
||||||
|
|
||||||
|
class OfficialAccount extends AppService
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 二维码场景类型
|
||||||
|
*/
|
||||||
|
const QR_SCENE_LOGIN = 'login';
|
||||||
|
const QR_SCENE_SUBSCRIBE = 'subscribe';
|
||||||
|
|
||||||
|
public function getOfficialAccount()
|
||||||
|
{
|
||||||
|
$service = new WeChatService();
|
||||||
|
|
||||||
|
return $service->getOfficialAccount();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function createSubscribeQrCode()
|
||||||
|
{
|
||||||
|
$user = $this->getLoginUser();
|
||||||
|
|
||||||
|
$app = $this->getOfficialAccount();
|
||||||
|
|
||||||
|
$sceneValue = sprintf('%s%s', self::QR_SCENE_SUBSCRIBE, $user->id);
|
||||||
|
|
||||||
|
$result = $app->qrcode->temporary($sceneValue);
|
||||||
|
|
||||||
|
$url = $app->qrcode->url($result['ticket']);
|
||||||
|
|
||||||
|
return ['url' => $url];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function createLoginQrCode()
|
||||||
|
{
|
||||||
|
$app = $this->getOfficialAccount();
|
||||||
|
|
||||||
|
$ticket = Text::random(0, 16);
|
||||||
|
|
||||||
|
$sceneValue = sprintf('%s%s', self::QR_SCENE_LOGIN, $ticket);
|
||||||
|
|
||||||
|
$result = $app->qrcode->temporary($sceneValue);
|
||||||
|
|
||||||
|
$keyName = $this->getLoginCacheKey($ticket);
|
||||||
|
|
||||||
|
$content = [
|
||||||
|
'action' => '',
|
||||||
|
'open_id' => '',
|
||||||
|
];
|
||||||
|
|
||||||
|
$this->getCache()->save($keyName, $content, 30 * 60);
|
||||||
|
|
||||||
|
$url = $app->qrcode->url($result['ticket']);
|
||||||
|
|
||||||
|
return [
|
||||||
|
'ticket' => $ticket,
|
||||||
|
'url' => $url,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLoginStatus($ticket)
|
||||||
|
{
|
||||||
|
$keyName = $this->getLoginCacheKey($ticket);
|
||||||
|
|
||||||
|
return $this->getCache()->get($keyName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSubscribeStatus()
|
||||||
|
{
|
||||||
|
$user = $this->getLoginUser();
|
||||||
|
|
||||||
|
$connectRepo = new ConnectRepo();
|
||||||
|
|
||||||
|
$connect = $connectRepo->findByUserId($user->id, ConnectModel::PROVIDER_WECHAT_OA);
|
||||||
|
|
||||||
|
return $connect ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLoginOpenId($ticket)
|
||||||
|
{
|
||||||
|
$keyName = $this->getLoginCacheKey($ticket);
|
||||||
|
|
||||||
|
$content = $this->getCache()->get($keyName);
|
||||||
|
|
||||||
|
return $content['open_id'] ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLoginCacheKey($key)
|
||||||
|
{
|
||||||
|
return "wechat_oa_login:{$key}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleNotify($message)
|
||||||
|
{
|
||||||
|
$logger = $this->getWeChatLogger();
|
||||||
|
|
||||||
|
$logger->debug('Received Message: ' . json_encode($message));
|
||||||
|
|
||||||
|
switch ($message['MsgType']) {
|
||||||
|
case 'event':
|
||||||
|
switch ($message['Event']) {
|
||||||
|
case 'subscribe':
|
||||||
|
return $this->handleSubscribeEvent($message);
|
||||||
|
case 'unsubscribe':
|
||||||
|
return $this->handleUnsubscribeEvent($message);
|
||||||
|
case 'SCAN':
|
||||||
|
return $this->handleScanEvent($message);
|
||||||
|
case 'CLICK':
|
||||||
|
return $this->handleClickEvent($message);
|
||||||
|
case 'VIEW':
|
||||||
|
return $this->handleViewEvent($message);
|
||||||
|
case 'LOCATION':
|
||||||
|
return $this->handleLocationEvent($message);
|
||||||
|
default:
|
||||||
|
return $this->noMatchReply();
|
||||||
|
}
|
||||||
|
case 'text':
|
||||||
|
return $this->handleTextReply($message);
|
||||||
|
case 'image':
|
||||||
|
return $this->handleImageReply($message);
|
||||||
|
case 'voice':
|
||||||
|
return $this->handleVoiceReply($message);
|
||||||
|
case 'video':
|
||||||
|
return $this->handleVideoReply($message);
|
||||||
|
case 'shortvideo':
|
||||||
|
return $this->handleShortVideoReply($message);
|
||||||
|
case 'location':
|
||||||
|
return $this->handleLocationReply($message);
|
||||||
|
case 'link':
|
||||||
|
return $this->handleLinkReply($message);
|
||||||
|
default:
|
||||||
|
return $this->noMatchReply();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function handleSubscribeEvent($message)
|
||||||
|
{
|
||||||
|
$openId = $message['FromUserName'] ?? '';
|
||||||
|
|
||||||
|
if (empty($openId)) return null;
|
||||||
|
|
||||||
|
return new TextMessage('开心呀,我们又多了一个小伙伴!');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function handleUnsubscribeEvent($message)
|
||||||
|
{
|
||||||
|
$openId = $message['FromUserName'] ?? '';
|
||||||
|
|
||||||
|
if (empty($openId)) return null;
|
||||||
|
|
||||||
|
$connectRepo = new ConnectRepo();
|
||||||
|
|
||||||
|
$connect = $connectRepo->findByOpenId($openId, ConnectModel::PROVIDER_WECHAT_OA);
|
||||||
|
|
||||||
|
if ($connect) {
|
||||||
|
$connect->deleted = 1;
|
||||||
|
$connect->update();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new TextMessage('伤心呀,我们又少了一个小伙伴!');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function handleScanEvent($message)
|
||||||
|
{
|
||||||
|
$openId = $message['FromUserName'] ?? '';
|
||||||
|
$eventKey = $message['EventKey'] ?? '';
|
||||||
|
|
||||||
|
if (Text::startsWith($eventKey, self::QR_SCENE_LOGIN)) {
|
||||||
|
return $this->handleLoginScanEvent($eventKey, $openId);
|
||||||
|
} elseif (Text::startsWith($eventKey, self::QR_SCENE_SUBSCRIBE)) {
|
||||||
|
return $this->handleSubscribeScanEvent($eventKey, $openId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->emptyReply();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function handleLoginScanEvent($eventKey, $openId)
|
||||||
|
{
|
||||||
|
$ticket = str_replace(self::QR_SCENE_LOGIN, '', $eventKey);
|
||||||
|
|
||||||
|
if (empty($ticket) || empty($openId)) return null;
|
||||||
|
|
||||||
|
$connectRepo = new ConnectRepo();
|
||||||
|
|
||||||
|
$connect = $connectRepo->findByOpenId($openId, ConnectModel::PROVIDER_WECHAT_OA);
|
||||||
|
|
||||||
|
$keyName = $this->getLoginCacheKey($ticket);
|
||||||
|
|
||||||
|
$cache = $this->getCache();
|
||||||
|
|
||||||
|
$content = [
|
||||||
|
'action' => $connect ? 'login' : 'bind',
|
||||||
|
'open_id' => $openId,
|
||||||
|
];
|
||||||
|
|
||||||
|
$cache->save($keyName, $content, 30 * 60);
|
||||||
|
|
||||||
|
return $this->emptyReply();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function handleSubscribeScanEvent($eventKey, $openId)
|
||||||
|
{
|
||||||
|
$userId = str_replace(self::QR_SCENE_SUBSCRIBE, '', $eventKey);
|
||||||
|
|
||||||
|
if (empty($userId) || empty($openId)) return null;
|
||||||
|
|
||||||
|
$userInfo = $this->getUserInfo($openId);
|
||||||
|
|
||||||
|
$unionId = $userInfo['unionid'] ?: '';
|
||||||
|
|
||||||
|
$connectRepo = new ConnectRepo();
|
||||||
|
|
||||||
|
$connect = $connectRepo->findByOpenId($openId, ConnectModel::PROVIDER_WECHAT_OA);
|
||||||
|
|
||||||
|
if ($connect) return null;
|
||||||
|
|
||||||
|
$connect = new ConnectModel();
|
||||||
|
|
||||||
|
$connect->user_id = $userId;
|
||||||
|
$connect->open_id = $openId;
|
||||||
|
$connect->union_id = $unionId;
|
||||||
|
$connect->provider = ConnectModel::PROVIDER_WECHAT_OA;
|
||||||
|
|
||||||
|
$connect->create();
|
||||||
|
|
||||||
|
return $this->emptyReply();
|
||||||
|
}
|
||||||
|
|
||||||
|
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('没有匹配的服务哦!');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getUserInfo($openId)
|
||||||
|
{
|
||||||
|
$app = $this->getOfficialAccount();
|
||||||
|
|
||||||
|
return $app->user->get($openId);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getWeChatLogger()
|
||||||
|
{
|
||||||
|
$service = new WeChatService();
|
||||||
|
|
||||||
|
return $service->logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -91,7 +91,7 @@ class WeChat extends OAuth
|
|||||||
$userInfo['name'] = $data['nickname'];
|
$userInfo['name'] = $data['nickname'];
|
||||||
$userInfo['avatar'] = $data['headimgurl'];
|
$userInfo['avatar'] = $data['headimgurl'];
|
||||||
$userInfo['unionid'] = $data['unionid'] ?? '';
|
$userInfo['unionid'] = $data['unionid'] ?? '';
|
||||||
$userInfo['provider'] = ConnectModel::PROVIDER_WECHAT;
|
$userInfo['provider'] = ConnectModel::PROVIDER_WECHAT_OA;
|
||||||
|
|
||||||
return $userInfo;
|
return $userInfo;
|
||||||
}
|
}
|
||||||
|
@ -118,7 +118,7 @@ class Order extends Validator
|
|||||||
{
|
{
|
||||||
$value = $this->filter->sanitize($amount, ['trim', 'float']);
|
$value = $this->filter->sanitize($amount, ['trim', 'float']);
|
||||||
|
|
||||||
if ($value < 0.01 || $value > 10000) {
|
if ($value < 0.01 || $value > 100000) {
|
||||||
throw new BadRequestException('order.invalid_pay_amount');
|
throw new BadRequestException('order.invalid_pay_amount');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
29
app/Validators/WeChatOfficialAccount.php
Normal file
29
app/Validators/WeChatOfficialAccount.php
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
|
||||||
|
* @license https://opensource.org/licenses/GPL-2.0
|
||||||
|
* @link https://www.koogua.com
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Validators;
|
||||||
|
|
||||||
|
use App\Exceptions\BadRequest as BadRequestException;
|
||||||
|
use App\Services\Logic\WeChat\OfficialAccount as WeChatOfficeAccount;
|
||||||
|
|
||||||
|
class WeChatOfficialAccount extends Validator
|
||||||
|
{
|
||||||
|
|
||||||
|
public function checkLoginOpenId($ticket)
|
||||||
|
{
|
||||||
|
$service = new WeChatOfficeAccount();
|
||||||
|
|
||||||
|
$openId = $service->getLoginOpenId($ticket);
|
||||||
|
|
||||||
|
if (!$openId) {
|
||||||
|
throw new BadRequestException('wechat_oa.invalid_login_ticket');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $openId;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -6,18 +6,31 @@ layui.use(['jquery'], function () {
|
|||||||
|
|
||||||
var options = {
|
var options = {
|
||||||
uploadJson: '/admin/upload/content/img',
|
uploadJson: '/admin/upload/content/img',
|
||||||
cssPath: '/static/lib/kindeditor/content.css',
|
cssPath: '/static/home/css/content.css',
|
||||||
width: '100%',
|
width: '100%',
|
||||||
height: '300px',
|
height: '300px',
|
||||||
items: [
|
items: [
|
||||||
'selectall', '|',
|
'selectall', '|',
|
||||||
'undo', 'redo', '|',
|
'undo', 'redo', '|',
|
||||||
'copy', 'plainpaste', 'wordpaste', '|',
|
'formatblock', 'forecolor', 'hilitecolor', 'bold', 'italic', 'underline', 'strikethrough', 'removeformat', '|',
|
||||||
'formatblock', 'forecolor', 'hilitecolor', 'bold', 'italic', 'underline', 'removeformat', '|',
|
'insertorderedlist', 'insertunorderedlist', 'table', 'code', '|',
|
||||||
'insertorderedlist', 'insertunorderedlist', 'table', '|',
|
'image', 'link', 'unlink', '|',
|
||||||
'superscript', 'subscript', '|', 'image', 'link', 'unlink', '|',
|
|
||||||
'source', 'about'
|
'source', 'about'
|
||||||
],
|
],
|
||||||
|
htmlTags: {
|
||||||
|
span: ['.color', '.background-color'],
|
||||||
|
a: ['id', 'class', 'href', 'target', 'name'],
|
||||||
|
img: ['id', 'class', 'src', 'width', 'height', 'alt', 'title'],
|
||||||
|
table: ['id', 'class'],
|
||||||
|
div: ['id', 'class'],
|
||||||
|
pre: ['id', 'class'],
|
||||||
|
hr: ['id', 'class'],
|
||||||
|
embed: ['id', 'class', 'src', 'width', 'height', 'type', 'loop', 'autostart', 'quality', 'align', 'wmode'],
|
||||||
|
iframe: ['id', 'class', 'src', 'width', 'height'],
|
||||||
|
'td,th': ['id', 'class'],
|
||||||
|
'p,ol,ul,li,blockquote,h1,h2,h3,h4,h5,h6': ['id', 'class'],
|
||||||
|
'br,tbody,tr,strong,b,sub,sup,em,i,u,strike,s,del': ['id', 'class'],
|
||||||
|
},
|
||||||
extraFileUploadParams: {
|
extraFileUploadParams: {
|
||||||
csrf_token: $('meta[name="csrf-token"]').attr('content')
|
csrf_token: $('meta[name="csrf-token"]').attr('content')
|
||||||
}
|
}
|
||||||
|
@ -178,7 +178,8 @@
|
|||||||
font-family: Consolas, Monaco, Andale Mono, monospace;
|
font-family: Consolas, Monaco, Andale Mono, monospace;
|
||||||
line-height: 1.7em;
|
line-height: 1.7em;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
padding: 6px 10px;
|
padding: 15px 10px;
|
||||||
|
margin-bottom: 15px;
|
||||||
border-left: 5px solid #6CE26C;
|
border-left: 5px solid #6CE26C;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,4 +219,25 @@
|
|||||||
|
|
||||||
.ke-content blockquote p {
|
.ke-content blockquote p {
|
||||||
color: #666;
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ke-content pre {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ke-content pre > span.kg-copy {
|
||||||
|
position: absolute;
|
||||||
|
top: 10px;
|
||||||
|
right: 10px;
|
||||||
|
padding: 0 10px;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 12px;
|
||||||
|
border-radius: 3px;
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
cursor: pointer;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ke-content pre:hover > span.kg-copy {
|
||||||
|
display: block;
|
||||||
}
|
}
|
@ -12,12 +12,23 @@ layui.use(['jquery'], function () {
|
|||||||
items: [
|
items: [
|
||||||
'selectall', '|',
|
'selectall', '|',
|
||||||
'undo', 'redo', '|',
|
'undo', 'redo', '|',
|
||||||
'copy', 'plainpaste', 'wordpaste', '|',
|
'formatblock', 'formatblock', 'forecolor', 'hilitecolor', 'bold', 'italic', 'underline', 'strikethrough', 'removeformat', '|',
|
||||||
'formatblock', 'forecolor', 'hilitecolor', 'bold', 'italic', 'underline', 'removeformat', '|',
|
'insertorderedlist', 'insertunorderedlist', 'table', 'code', '|',
|
||||||
'insertorderedlist', 'insertunorderedlist', 'table', '|',
|
'image', 'link', 'unlink', '|',
|
||||||
'superscript', 'subscript', '|', 'image', 'link', 'unlink', '|',
|
|
||||||
'source', 'about'
|
'source', 'about'
|
||||||
],
|
],
|
||||||
|
htmlTags: {
|
||||||
|
span: ['.color', '.background-color'],
|
||||||
|
a: ['id', 'class', 'href', 'target', 'name'],
|
||||||
|
img: ['id', 'class', 'src', 'width', 'height', 'alt', 'title'],
|
||||||
|
table: ['id', 'class'],
|
||||||
|
div: ['id', 'class'],
|
||||||
|
pre: ['id', 'class'],
|
||||||
|
hr: ['id', 'class'],
|
||||||
|
'td,th': ['id', 'class'],
|
||||||
|
'p,ol,ul,li,blockquote,h1,h2,h3,h4,h5,h6': ['id', 'class'],
|
||||||
|
'br,tbody,tr,strong,b,sub,sup,em,i,u,strike,s,del': ['id', 'class'],
|
||||||
|
},
|
||||||
extraFileUploadParams: {
|
extraFileUploadParams: {
|
||||||
csrf_token: $('meta[name="csrf-token"]').attr('content')
|
csrf_token: $('meta[name="csrf-token"]').attr('content')
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,22 @@
|
|||||||
layui.use(['layer'], function () {
|
layui.use(['jquery','layer'], function () {
|
||||||
|
|
||||||
|
var $ = layui.jquery;
|
||||||
var layer = layui.layer;
|
var layer = layui.layer;
|
||||||
|
|
||||||
|
if ($('.ke-content').length > 0) {
|
||||||
|
var kePres = $('pre');
|
||||||
|
if (kePres.length > 0) {
|
||||||
|
kePres.each(function () {
|
||||||
|
var text = $(this).text();
|
||||||
|
var btn = $('<span class="kg-copy">复制</span>').attr('data-clipboard-text', text);
|
||||||
|
$(this).prepend(btn);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var clipboard = new ClipboardJS('.kg-copy');
|
var clipboard = new ClipboardJS('.kg-copy');
|
||||||
|
|
||||||
clipboard.on('success', function (e) {
|
clipboard.on('success', function () {
|
||||||
layer.msg('内容已经复制到剪贴板');
|
layer.msg('内容已经复制到剪贴板');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user