| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160 |
- <?php
- namespace addons\WechatVideoShop\api\modules\v1\controllers;
- use addons\WechatVideoShop\common\enums\WechatVideoShopEnums;
- use addons\WechatVideoShop\common\expand\sdk\weixin\src\crypto\Crypto;
- use addons\WechatVideoShop\common\logic\WeChatCallbackLogic;
- use addons\WechatVideoShop\common\models\WechatVideoShop;
- use addons\WechatVideoShop\common\models\WechatVideoShopEvents;
- use addons\WechatVideoShop\common\service\ShopService;
- use common\enums\RabbitMqEnum;
- use common\enums\StatusEnum;
- use common\models\mall\Mall;
- use yii\helpers\Json;
- use yii\web\Controller;
- class EventController extends Controller
- {
- public $enableCsrfValidation = false;
- /**
- * Token校验
- * @return bool
- * @throws \Exception
- */
- public function actionIndex()
- {
- $data = $this->request->get();
- $valid = \Yii::$app->services->validate->validate($data, [
- [['signature', 'timestamp', 'nonce', 'echostr'], 'required'],
- ]);
- \Yii::error(__METHOD__ . '->params: ' . var_export($data, true));
- if ($valid === false) return false;
- $signature = $data["signature"];
- $timestamp = $data["timestamp"];
- $nonce = $data["nonce"];
- $mall_ids = Mall::getEnableMallIds();
- foreach ($mall_ids as $mall_id) {
- $config = \Yii::$app->services->setting->addons->get($mall_id, WechatVideoShopEnums::ADDONS_NAME, 'basic');
- if (empty($config['is_enable'])) continue;
- $shop_list = WechatVideoShop::lists(['where' => [['mall_id' => $mall_id], ['status' => [StatusEnum::ENABLED, StatusEnum::DISABLED]]]]);
- if (empty($shop_list)) continue;
- foreach ($shop_list as $val) {
- if(empty($val['wechat_token'])) continue;
-
- $token = $val['wechat_token'];
- $tmpArr = array($token, $timestamp, $nonce);
- sort($tmpArr, SORT_STRING);
- $tmpStr = implode($tmpArr);
- $tmpStr = sha1($tmpStr);
- if ($tmpStr == $signature) {
- // 执行验证
- \Yii::$app->services->rabbitMq->push(RabbitMqEnum::EXCHANGE_TASK, RabbitMqEnum::TASK_QUEUE,
- ['mall_id' => $mall_id], ShopService::class, 'auth');
- return $data['echostr'];
- }
- }
- }
- return false;
- }
-
- public function actionCallback()
- {
- try {
- // 校验token
- if (\Yii::$app->request->isGet && !empty(\Yii::$app->request->get('echostr'))) {
- return $this->actionIndex();
- }
- $params = $this->request->get();
- $encryptData = $this->request->post();
- \Yii::error(__METHOD__ . '->params: ' . var_export($params, true) . '->encryptData: ' . var_export($encryptData, true));
- $save_data['req'] = $params ?? [];
- $save_data['org_post'] = !empty($encryptData) ? var_export($encryptData, true) : '';
- // 解密?
- $mall_ids = Mall::getEnableMallIds();
- $decryptData = null;
- /** @var int|null $current_mall_id */
- $current_mall_id = null;
- /** @var int|null $current_shop_id */
- $current_shop_id = null;
- foreach ($mall_ids as $mall_id) {
- $config = \Yii::$app->services->setting->addons->get($mall_id, WechatVideoShopEnums::ADDONS_NAME, 'basic');
- if (empty($config['is_enable'])) continue;
- $shop_list = WechatVideoShop::lists(['where' => [['mall_id' => $mall_id], ['status' => [StatusEnum::ENABLED, StatusEnum::DISABLED]]]]);
- if (empty($shop_list)) continue;
-
- foreach ($shop_list as $val) {
- if (empty($val['wechat_token']) || empty($val['wechat_secret']) || empty($val['wechat_aes_key'])) continue;
- try {
- $crypto = new Crypto($val['wechat_token'], $val['wechat_aes_key']);
- $ret = $crypto->de($encryptData['Encrypt'], $params['msg_signature'], $params['nonce'], $params['timestamp']);
- if ($ret[0] != StatusEnum::DISABLED) throw new \Exception("解密失败");
- if ($ret[1]['wechat_appid'] != $val['wechat_appid']) throw new \Exception("不属于同一个应用"); // 不属于同一个应用
- $current_mall_id = $mall_id;
- $current_shop_id = $val['id'];
- $decryptData = $ret[1];
- break;
- } catch (\Exception $e) {
- // 有可能是解密失败的 这里不需要管
- }
- }
- }
- // 解密成功 - 不一定要解密
- if (!empty($decryptData)) {
- $decryptData['local_shop_id'] = $current_shop_id;
- $save_data['post'] = $decryptData;
- $save_data['mall_id'] = $current_mall_id;
- $callback = new WeChatCallbackLogic($current_mall_id, $current_shop_id, 0, $decryptData);
- $method = $decryptData['Event'] ?? 'call';
- if (method_exists($callback, $method)) {
- $callback->{$method}([]);
- } else {
- $callback->call([]);
- // $method = 'call';
- }
- // 投递
- // \Yii::$app->services->rabbitMq->delay(600, ['mall_id' => $current_mall_id, 'shop_id' => $current_shop_id, 'data' => $decryptData],
- // WeChatCallbackLogic::class, $method);
- } else {
- $save_data['exception'] = [
- 'msg' => '解密失败'
- ];
- }
- } catch (\Exception $e) {
- $save_data['exception'] = [
- 'file' => $e->getFile(),
- 'code' => $e->getCode(),
- 'line' => $e->getLine(),
- 'msg' => $e->getMessage(),
- ];
- }
- if (empty($save_data['post'])) $save_data['post'] = [];
- if (empty($save_data['exception'])) $save_data['exception'] = [];
- // 记录事件
- $eventModel = new WechatVideoShopEvents();
- if ($eventModel->load($save_data, '')) {
- if ($eventModel->save() && !empty($eventModel->getErrorMessage())) {
- \Yii::error(__METHOD__ . " event model error: {$eventModel->getErrorMessage()}");
- }
- } else {
- \Yii::error(__METHOD__ . " event model error: {$eventModel->getErrorMessage()}");
- }
- return empty($eventModel['exception']) ? 'success' : 'fail';
- }
- }
|