OpenPlatformService.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: Bear
  5. * Date: 2018/11/29
  6. * Time: 上午10:41
  7. */
  8. namespace app\main\service;
  9. use app\common\library\Redis;
  10. use app\common\model\Platform;
  11. use app\main\constants\ErrorCodeConstants;
  12. use app\main\constants\OpenPlatformConstants;
  13. use EasyWeChat\Factory;
  14. use EasyWeChat\OpenPlatform\Authorizer\Auth\AccessToken;
  15. use GuzzleHttp\Client;
  16. use Symfony\Component\Cache\Simple\RedisCache;
  17. use think\Config;
  18. use think\Log;
  19. /**
  20. * 公众平台
  21. * Class OpenPlatformService
  22. * @package app\main\service
  23. */
  24. class OpenPlatformService extends BaseService
  25. {
  26. /**
  27. * @var OpenPlatformService
  28. */
  29. protected static $self = NULL;
  30. /**
  31. * @var \EasyWeChat\OpenPlatform\Application
  32. */
  33. public $openPlatform = NULL;
  34. /**
  35. * @var \EasyWeChat\OpenPlatform\Authorizer\OfficialAccount\Application
  36. */
  37. public $officialAccount;
  38. /**
  39. * @var string
  40. */
  41. public $sourceDomain;
  42. //平台ID对应的代理IP
  43. private $_proxy = [];
  44. /**
  45. * @return $this|OpenPlatformService
  46. */
  47. public static function instance()
  48. {
  49. if (self::$self == NULL) {
  50. self::$self = new self();
  51. }
  52. return self::$self;
  53. }
  54. /**
  55. * @return Platform
  56. */
  57. public function getPlatformModel()
  58. {
  59. return model('Platform');
  60. }
  61. /**
  62. * @return bool|\EasyWeChat\OpenPlatform\Application
  63. */
  64. public function getOpenPlatform()
  65. {
  66. try {
  67. if (!$this->openPlatform) {
  68. $pt_id = Config::get('wechat.platform_id');
  69. if ($proxy = $this->getProxy($pt_id)) {
  70. $httpConfig = array_merge(Config::get('wechat.http'), ['proxy' => $proxy]);
  71. Config::set('wechat.http', $httpConfig);
  72. }
  73. $this->openPlatform = Factory::openPlatform(Config::get('wechat'));
  74. $this->openPlatform['cache'] = new RedisCache(Redis::instanceCache());
  75. }
  76. return $this->openPlatform;
  77. } catch (\Exception $e) {
  78. LogService::exception($e);
  79. return false;
  80. }
  81. }
  82. /**
  83. * @param string $appId
  84. * @param string|null $refreshToken
  85. * @param AccessToken|null $accessToken
  86. * @return \EasyWeChat\OpenPlatform\Authorizer\OfficialAccount\Application
  87. * @throws \Exception
  88. */
  89. public function getOfficialAccount(string $appId = "", string $refreshToken = null, AccessToken $accessToken = null)
  90. {
  91. if (!$appId) {
  92. if (Config::get('wechat.platform_id')) {
  93. if ($proxy = $this->getProxy(Config::get('wechat.platform_id'))) {
  94. $httpConfig = array_merge(Config::get('wechat.http'), ['proxy' => $proxy]);
  95. Config::set('wechat.http', $httpConfig);
  96. }
  97. }
  98. $this->officialAccount = Factory::officialAccount(Config::get('wechat'));
  99. if (isset($proxy) && $proxy) {
  100. $httpConfig = array_merge(Config::get('wechat.http'), ['proxy' => $proxy]);
  101. $this->officialAccount['http_client'] = new Client($httpConfig);
  102. }
  103. } else {
  104. $this->officialAccount = $this->getOpenPlatform()->officialAccount($appId, $refreshToken, $accessToken);
  105. $adminConfig = AdminService::instance()->getAdminConfigModel()->getAdminInfoByAppId($appId);
  106. $config_platform_id = $pt_id = Config::get('wechat.platform_id');
  107. if ($config_platform_id == $adminConfig['menu_platform_id']) {
  108. $pt_id = $adminConfig['menu_platform_id'];
  109. } else {
  110. $pt_id = $adminConfig['platform_id'];
  111. }
  112. if ($proxy = $this->getProxy($pt_id)) {
  113. $httpConfig = array_merge(Config::get('wechat.http'), ['proxy' => $proxy]);
  114. $this->officialAccount['http_client'] = new Client($httpConfig);
  115. }
  116. }
  117. $this->officialAccount['cache'] = new RedisCache(Redis::instanceCache());
  118. return $this->officialAccount;
  119. }
  120. /**
  121. * @param string $sourceDomain
  122. * @return string
  123. */
  124. public function setSourceDomain(string $sourceDomain)
  125. {
  126. return $this->sourceDomain = $sourceDomain;
  127. }
  128. /**
  129. * @return string
  130. */
  131. public function getSourceDomain()
  132. {
  133. return $this->sourceDomain;
  134. }
  135. /**
  136. * @return \app\main\model\object\ReturnObject
  137. */
  138. public function initWxParams()
  139. {
  140. try {
  141. $adminconfig = UserService::instance()->getRunTimeObject()->adminConfig;
  142. switch (UserService::instance()->getRunTimeObject()->urlType) {
  143. case OpenPlatformConstants::URL_TYPE_ADMIN: // 后台首页
  144. break;
  145. case OpenPlatformConstants::URL_TYPE_PAY: // 充值页
  146. $host = get_host_no_port();
  147. $payHosts = OfficialAccountsService::instance()->getWxpayModel()->getHosts();
  148. if (in_array($host, $payHosts)) {
  149. $pay_hosts = OfficialAccountsService::instance()->getWxpayModel()->getInfoByHost($host);
  150. $payInfo = OfficialAccountsService::instance()->getWxpayModel()->getInfo($pay_hosts['platform_id'], $pay_hosts['id']);
  151. Config::set('wechat.app_id', $payInfo['appid']);
  152. Config::set('wechat.secret', $payInfo['secret']);
  153. Config::set('wechat.mch_id', $payInfo['mcid']);
  154. Config::set('wechat.key', $payInfo['apikey']);
  155. Config::set('wechat.platform_id', $payInfo['platform_id']);
  156. } else {
  157. Config::set('wechat.app_id', $adminconfig['wxpay_appid']);
  158. Config::set('wechat.secret', $adminconfig['wxpay_secret']);
  159. Config::set('wechat.mch_id', $adminconfig['wxpay_mcid']);
  160. Config::set('wechat.key', $adminconfig['wxpay_apikey']);
  161. Config::set('wechat.platform_id', $adminconfig['platform_id']);
  162. }
  163. $arr = Config::get('wechat.http');
  164. $arr['base_uri'] = 'https://api.mch.weixin.qq.com/';
  165. Config::set('wechat.http', $arr);
  166. break;
  167. case OpenPlatformConstants::URL_TYPE_SPREAD: // 推广页
  168. //获取域名平台,先用顶级查找,顶级找不到使用全域名进行查找
  169. $host = get_host_no_port();
  170. $hostArr = explode(".", $host);
  171. array_shift($hostArr);
  172. $topHost = implode(".", $hostArr);
  173. if (!$ophost = OfficialAccountsService::instance()->getOphostModel()->getInfoByHost($topHost)) {
  174. $ophost = OfficialAccountsService::instance()->getOphostModel()->getInfoByHost($host);
  175. }
  176. //获取微信平台信息
  177. if ($ophost) {
  178. $platform_info = OpenPlatformService::instance()->getPlatformModel()->getInfo($ophost['platform_id']);
  179. Config::set('wechat.app_id', $platform_info['appid']);
  180. Config::set('wechat.secret', $platform_info['secret']);
  181. Config::set('wechat.token', $platform_info['token']);
  182. Config::set('wechat.aes_key', $platform_info['aes_key']);
  183. Config::set('wechat.platform_id', $ophost['platform_id']);
  184. } else {
  185. Config::set('wechat.app_id', $adminconfig['platform_appid']);
  186. Config::set('wechat.secret', $adminconfig['platform_secret']);
  187. Config::set('wechat.token', $adminconfig['platform_token']);
  188. Config::set('wechat.aes_key', $adminconfig['platform_aes_key']);
  189. Config::set('wechat.platform_id', $adminconfig['platform_id']);
  190. }
  191. break;
  192. default: //默认
  193. break;
  194. }
  195. return $this->getReturn();
  196. } catch (\Exception $e) {
  197. return $this->getExceptionReturn($e);
  198. }
  199. }
  200. /**
  201. * 获取服务号的refresh_token
  202. * @param $channelId
  203. * @return mixed
  204. * @throws \think\Exception
  205. * @throws \think\db\exception\DataNotFoundException
  206. * @throws \think\db\exception\ModelNotFoundException
  207. * @throws \think\exception\DbException
  208. */
  209. public function getRefreshToken($channelId)
  210. {
  211. $adminConfig = AdminService::instance()->getAdminConfigModel()->getAdminInfoAll($channelId);
  212. $config_platform_id = Config::get('wechat.platform_id');
  213. if ($config_platform_id == $adminConfig['menu_platform_id']) {
  214. if (!isset($adminConfig['menu_refresh_token'])) {
  215. $adminConfig['menu_refresh_token'] = model('Ptoken')->where(['platform_id' => $config_platform_id, 'admin_id' => $adminConfig['admin_id']])->value('refresh_token');
  216. }
  217. $refresh_token = $adminConfig['menu_refresh_token'];
  218. } else {
  219. $refresh_token = $adminConfig['refresh_token'];
  220. }
  221. return $refresh_token;
  222. }
  223. /**
  224. * 使用appid初始化平台
  225. * @param $appid
  226. * @return \app\main\model\object\ReturnObject
  227. */
  228. public function initPlatformByAppId($appid)
  229. {
  230. $platformData = OpenPlatformService::instance()->getPlatformModel()->where(['appid'=>$appid])->find();
  231. if($platformData){
  232. Config::set('wechat.app_id', $platformData['appid']);
  233. Config::set('wechat.secret', $platformData['secret']);
  234. Config::set('wechat.token', $platformData['token']);
  235. Config::set('wechat.aes_key', $platformData['aes_key']);
  236. Config::set('wechat.platform_id', $platformData['id']);
  237. LogService::info('API_LOG Platform:' . var_export($platformData, true));
  238. if (!OpenPlatformService::instance()->getOpenPlatform()) {
  239. return $this->setMsg('平台配置有误')->setCode(ErrorCodeConstants::PARAMS_ERROR_INVALID)->getReturn();
  240. }
  241. }else{
  242. return $this->setMsg('平台配置有误')->setCode(ErrorCodeConstants::PARAMS_ERROR_INVALID)->getReturn();
  243. }
  244. return $this->getReturn();
  245. }
  246. /**
  247. * 使用平台id初始化平台
  248. * @param $pt_id
  249. * @return \app\main\model\object\ReturnObject
  250. */
  251. public function initPlatformById($pt_id)
  252. {
  253. $platformData = OpenPlatformService::instance()->getPlatformModel()->getInfo($pt_id);
  254. if($platformData){
  255. Config::set('wechat.app_id', $platformData['appid']);
  256. Config::set('wechat.secret', $platformData['secret']);
  257. Config::set('wechat.token', $platformData['token']);
  258. Config::set('wechat.aes_key', $platformData['aes_key']);
  259. Config::set('wechat.platform_id', $platformData['id']);
  260. LogService::info('API_LOG Platform:' . var_export($platformData, true));
  261. if (!OpenPlatformService::instance()->getOpenPlatform()) {
  262. return $this->setMsg('平台配置有误')->setCode(ErrorCodeConstants::PARAMS_ERROR_INVALID)->getReturn();
  263. }
  264. }else{
  265. return $this->setMsg('平台配置有误')->setCode(ErrorCodeConstants::PARAMS_ERROR_INVALID)->getReturn();
  266. }
  267. return $this->getReturn();
  268. }
  269. /**
  270. * 返回平台代理IP 多个时随机返回一个
  271. * @param null $pt_id
  272. * @return null
  273. */
  274. public function getProxyconfigById($pt_id = null, $field = 'proxy_config', $all = false)
  275. {
  276. //$this->getPlatformModel()->delCacheAll($pt_id);
  277. $platformInfo = $this->getPlatformModel()->getInfo($pt_id);
  278. if (isset($platformInfo[$field])) {
  279. if ($proxyConfig = trim($platformInfo[$field])) {
  280. $arr = explode(",", str_replace([" ", " ", "\s", "\r", "\n"], [",", ",", ",", ",", ","], $proxyConfig));
  281. $arr = array_values(array_filter($arr));
  282. if ($all) {
  283. return $arr;
  284. }
  285. $proxy = $arr[array_rand($arr,1)];
  286. Log::info("三方平台代理IP:{$proxy}");
  287. return $proxy;
  288. }
  289. }
  290. return null;
  291. }
  292. /**
  293. * 获取渠道的平台的代理IP
  294. * @param null $channel_id
  295. * @param null $app_id
  296. * @return null|string
  297. */
  298. public function getProxyconfigByChannel($channel_id = null, $app_id = null, $field = 'proxy_config', $all = false)
  299. {
  300. if (empty($channel_id) && empty($app_id)) {
  301. return null;
  302. }
  303. if ($channel_id) {
  304. $adminInfo = AdminService::instance()->getAdminConfigModel()->getAdminInfoAll($channel_id);
  305. } else {
  306. $adminInfo = AdminService::instance()->getAdminConfigModel()->getAdminInfoByAppId($app_id);
  307. }
  308. return $this->getProxyconfigById($adminInfo['platform_id'], $field, $all);
  309. }
  310. /**
  311. * 返回平台对应的代理IP
  312. * @param $pt_id
  313. * @return mixed
  314. */
  315. public function getProxy($pt_id)
  316. {
  317. $modulename = request()->module();
  318. if (isset($this->_proxy[$pt_id]) && $modulename != 'admin') {
  319. return $this->_proxy[$pt_id];
  320. } else {
  321. $this->_proxy[$pt_id] = $this->getProxyconfigById($pt_id);
  322. }
  323. return $this->_proxy[$pt_id];
  324. }
  325. }