ShareQrcode.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422
  1. <?php
  2. /**
  3. * 重庆赤晓店信息科技有限公司
  4. * https://www.chixiaodian.com
  5. * Copyright (c) 2023 赤店商城 All rights reserved.
  6. */
  7. namespace app\utils;
  8. use AopClient;
  9. use app\models\Option;
  10. use app\models\Store;
  11. use app\models\StoreAliMini;
  12. use app\models\WechatConfig;
  13. use app\utils\Alipay\alipaySdk\aop\request\AlipayOpenAppQrcodeCreateRequest;
  14. use EasyWeChat\Factory;
  15. use Yii;
  16. use yii\helpers\Json;
  17. include_once \Yii::$app->basePath . "/utils/Alipay/alipaySdk/aop/AopClient.php";;
  18. class ShareQrcode
  19. {
  20. /**
  21. * 二维码类型
  22. */
  23. public $type = 0;
  24. public static function wxQrcodeByPlatform($page, $scene, $width = 600)
  25. {
  26. return self::wxQrcode($page, $scene, $width, true);
  27. }
  28. /**
  29. * 获取小程序码
  30. * @param $page
  31. * @param $scene
  32. * @param int $width
  33. * @return array
  34. * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
  35. * @throws \EasyWeChat\Kernel\Exceptions\RuntimeException
  36. */
  37. public static function wxQrcode($page, $scene, $width = 600, $is_platform = false, $is_server = false, $store_id = 0)
  38. {
  39. $store_id = $store_id != 0 ? $store_id : get_store_id();
  40. $file_name = md5($page.$scene.$store_id);
  41. // 保存小程序码到文件
  42. $dir = \Yii::$app->runtimePath . '/image/wx_qrcode';
  43. if (! is_dir($dir)) {
  44. mkdir($dir, 0777, true);
  45. }
  46. $url = str_replace('http://', 'https://', \Yii::$app->request->hostInfo . '/runtime/image/wx_qrcode/' . $file_name);
  47. // if (file_exists($dir. '/' .$file_name . '.jpg')) {
  48. // return [
  49. // 'code' => 0,
  50. // 'root_path' => $dir . '/' . $file_name . '.jpg',
  51. // 'url_path' => $url . '.jpg',
  52. // ];
  53. // }
  54. if($store_id == -1){
  55. $storeInfo = [];
  56. }else{
  57. $storeInfo = Store::findOne($store_id);
  58. }
  59. if (((is_h5()) && $store_id > -1) || is_alipay_platform() || !is_wechat_platform() || is_app_platform()) {
  60. // $page = \Yii::$app->request->hostInfo . '/h5/#/' . $page . '?scene=' . $scene;
  61. $page .= '?scene=' . \urlencode($scene);
  62. QrCode::image($page, $width, false, 'L', 'JPEG', 0, ['255,255,255', '0,0,0'], 1, false, $dir. '/' .$file_name . '.jpg');
  63. return [
  64. 'code' => 0,
  65. 'root_path' => $dir . '/' . $file_name . '.jpg',
  66. 'url_path' => $url . '.jpg',
  67. ];
  68. }
  69. // $plugin = \Yii::$app->getAttr('plugin');
  70. // $open = false;
  71. // if (in_array('duli_store', $plugin['union'])) {
  72. // $open = true;
  73. // }
  74. // $self_mini = Option::get('self_mini', $store_id,'store', 0)['value'];
  75. // if (\Yii::$app->prod_is_dandianpu() && (!$self_mini || !$open)) {
  76. // $app = self::setSingleStoreWechat($is_platform);
  77. // } else {
  78. // if((isset($storeInfo->business_model) && $storeInfo->business_model != 1) || !$storeInfo || $is_platform){
  79. // $app = self::setBussinessWechat();
  80. // }else{
  81. // // if (is_alipay_platform()) {
  82. // // if (is_alipay_platform()) {
  83. // // $request = new AlipayOpenAppQrcodeCreateRequest();
  84. // // $param = [
  85. // // 'url_param' => 'user/clerk/clerk',
  86. // // 'query_param' => $scene,
  87. // // 'describe' => "小程序开发上线使用"
  88. // // ];
  89. // // $aliConfigQr = self::aliConfigQr($request, $param);
  90. // // $url_path = "";
  91. // // if ($aliConfigQr->code === "10000") {
  92. // // $url_path = $aliConfigQr->qr_code_url_circle_blue;
  93. // // }
  94. // // }
  95. // // }
  96. // if (is_wechat_platform()) {
  97. // $app = self::setWechat();
  98. // }
  99. // }
  100. // }
  101. $app = \app\utils\Wechat\WechatMini::getWechatConfig($store_id, 0, 0, $is_platform, $is_server);
  102. if (!$app) {
  103. return [
  104. 'code' => 1,
  105. 'msg' => '获取小程序信息失败',
  106. ];
  107. }
  108. $app = $app->app_code;
  109. // 服务端小程序 (商家端)
  110. // if ($is_server) {
  111. // $app = self::serServerWechat();
  112. // }
  113. if (is_wechat_platform()) {
  114. $response = $app->getUnlimit($scene, [
  115. 'width' => $width,
  116. 'page' => $page
  117. ]);
  118. if ($response instanceof \EasyWeChat\Kernel\Http\StreamResponse) {
  119. $filename = $response->save($dir, $file_name);
  120. } else {
  121. return [
  122. 'code' => 1,
  123. 'response' => $response,
  124. ];
  125. }
  126. $file_path = $dir. '/' .$file_name . '.jpg';
  127. $root_path = $url_path = '';
  128. if(file_exists($file_path)){
  129. $root_path = $file_path;
  130. $url_path = $url . '.jpg';
  131. }else{
  132. $root_path = $dir. '/' .$file_name ;
  133. $url_path = $url;
  134. }
  135. }
  136. return [
  137. 'code' => 0,
  138. 'root_path' => $root_path,
  139. 'url_path' => $url_path
  140. ];
  141. }
  142. //获取支付宝码
  143. public static function getAlipayQrcode($url_param, $query_param) {
  144. try {
  145. $store_mini = StoreAliMini::findOne(['store_id' => get_store_id(), 'is_cancel' => 0, 'is_use' => 1]);
  146. if (\Yii::$app->isSaas() && $store_mini) {
  147. $appid = Option::get("alipay_appid", 0, 'saas')['value'];
  148. $private_key = Option::get("alipay_app_private_key", 0, 'saas')['value'];
  149. $public_key = Option::get("alipay_public_key", 0, 'saas')['value'];
  150. $alipay_aes_key = Option::get("alipay_aes_key", 0, 'saas')['value'];
  151. } elseif (\Yii::$app->prod_is_dandianpu() && !Store::hasIncoming(get_store_id()) && self_mini() === false) {
  152. $alipay_config = Json::decode(Option::get('one_store_alipay_config', 0, 'saas', '')['value']);
  153. $appid = $alipay_config['app_id'];
  154. $private_key = $alipay_config['app_private_key'];
  155. $public_key = $alipay_config['alipay_public_key'];
  156. $alipay_aes_key = $alipay_config['aes_key'];
  157. }
  158. if (!\Yii::$app->isSaas()) {
  159. $alipay_config = Option::get(Option::OPTOPN_KEY, get_store_id(), 'alipay')['value'];
  160. $alipay_config = json_decode($alipay_config, true);
  161. $alipay_aes_key = $alipay_config['aes_key'];
  162. $appid = $alipay_config['app_id'];
  163. $public_key = $alipay_config['alipay_public_key'];
  164. // $public_key = $alipay_config['app_public_key'];
  165. $private_key = $alipay_config['app_private_key'];
  166. }
  167. //换取token
  168. $aop = new AopClient();
  169. $aop->appId = $appid;
  170. $aop->rsaPrivateKey = $private_key;
  171. $aop->alipayrsaPublicKey = $public_key;
  172. $aop->encryptKey = $alipay_aes_key;
  173. $aop->encryptType = "AES";
  174. $aop->apiVersion = '1.0';
  175. $aop->signType = 'RSA2';
  176. $aop->postCharset = 'utf-8';
  177. $param = [
  178. 'url_param' => $url_param,
  179. 'query_param' => 'scene=' . $query_param,
  180. 'describe' => "小程序开发上线使用"
  181. ];
  182. $request = new AlipayOpenAppQrcodeCreateRequest();
  183. $request->setBizContent(json_encode($param));
  184. if ($store_mini) {
  185. $result = $aop->execute($request, null, $store_mini->auth_token);
  186. } else {
  187. $result = $aop->execute($request);
  188. }
  189. \Yii::error($result);
  190. $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
  191. $result = $result->$responseNode;
  192. if (empty($result->code) || $result->code != 10000) {
  193. throw new \Exception($result->sub_msg);
  194. }
  195. $result->root_path = self::saveTempImage($result->qr_code_url_circle_blue);
  196. return json_decode(json_encode($result), true);
  197. } catch (\Exception $e) {
  198. return [
  199. 'code' => 1,
  200. 'msg' => $e->getMessage()
  201. ];
  202. }
  203. }
  204. //获取网络图片到临时目录
  205. public static function saveTempImage($url)
  206. {
  207. if (strpos($url, 'http') === false) {
  208. $url = 'http:' . trim($url);
  209. }
  210. if (!is_dir(\Yii::$app->runtimePath . '/image')) {
  211. mkdir(\Yii::$app->runtimePath . '/image');
  212. }
  213. $save_path = \Yii::$app->runtimePath . '/image/' . md5($url) . '.jpg';
  214. CurlHelper::download($url, $save_path);
  215. return $save_path;
  216. }
  217. // 单店铺
  218. public static function setSingleStoreWechat($is_platform = false)
  219. {
  220. if($is_platform){
  221. // 证书
  222. if (!is_dir(\Yii::$app->runtimePath . '/pem_dandianpu')) {
  223. mkdir(\Yii::$app->runtimePath . '/pem_dandianpu');
  224. file_put_contents(\Yii::$app->runtimePath . '/pem_dandianpu/index.html', '');
  225. }
  226. $config = [
  227. 'app_id' => Option::get('platform_mch_appid', 0, 'saas', '')['value'],
  228. 'secret' => Option::get('platform_mch_key', 0, 'saas', '')['value'],
  229. 'response_type' => 'array'
  230. ];
  231. $wechatMini = Factory::miniProgram($config);
  232. return $wechatMini->app_code;
  233. }
  234. // 证书
  235. if (!is_dir(\Yii::$app->runtimePath . '/pem')) {
  236. mkdir(\Yii::$app->runtimePath . '/pem');
  237. file_put_contents(\Yii::$app->runtimePath . '/pem/index.html', '');
  238. }
  239. $config = [
  240. 'app_id' => Option::get('one_store_wechat_appid', 0, 'saas', '')['value'],
  241. 'secret' => Option::get('one_store_wechat_secret', 0, 'saas', '')['value'],
  242. 'response_type' => 'array'
  243. ];
  244. $wechatMini = Factory::miniProgram($config);
  245. return $wechatMini->app_code;
  246. }
  247. public static function setWechat()
  248. {
  249. // 证书
  250. if (!is_dir(\Yii::$app->runtimePath . '/pem')) {
  251. mkdir(\Yii::$app->runtimePath . '/pem');
  252. file_put_contents(\Yii::$app->runtimePath . '/pem/index.html', '');
  253. }
  254. $store = Store::findOne(get_store_id());
  255. if ((int)$store->business_model !== 1) {
  256. $config = [
  257. 'app_id' => Option::get('platform_appid', 0, 'saas')['value'],
  258. 'secret' => Option::get('platform_key', 0, 'saas')['value'],
  259. 'response_type' => 'array'
  260. ];
  261. } else {
  262. // 判断是否授权第三方
  263. $wechat_config = WechatConfig::findOne(['store_id' => get_store_id(), 'type' => 1]);
  264. if (is_open_platform() && $wechat_config->app_id) {
  265. $platform_third_appid = Option::get('platform_third_appid', 0, 'saas')['value'];
  266. $platform_third_secret = Option::get('platform_third_secret', 0, 'saas')['value'];
  267. $platform_encodingAesKey = Option::get('platform_encodingAesKey', 0, 'saas')['value'];
  268. $platform_token = Option::get('platform_token', 0, 'saas')['value'];
  269. $config = [
  270. 'app_id' => $platform_third_appid,
  271. 'secret' => $platform_third_secret,
  272. 'token' => $platform_token,
  273. 'aes_key' => $platform_encodingAesKey
  274. ];
  275. $openPlatform = Factory::openPlatform($config);
  276. $wechat_config = WechatConfig::findOne(['store_id' => get_store_id(), 'type' => 1]);
  277. $bese_info = $openPlatform->getAuthorizer($wechat_config->app_id);
  278. $wechatMini = $openPlatform->miniProgram($wechat_config->app_id, $bese_info['authorization_info']['authorizer_refresh_token']);
  279. return $wechatMini->app_code;
  280. } else {
  281. $wechat_config = WechatConfig::findOne(['store_id' => get_store_id(), 'type' => 1]);
  282. if ((int)get_store_id() === -1) {
  283. $wechat_config = [];
  284. $wechat_config['app_id'] = Option::get('platform_appid', 0, 'saas')['value'];//platform_key platform_pay_key platform_mch_id platform_apiclient_cert platform_apiclient_key
  285. $wechat_config['app_secret'] = Option::get('platform_key', 0, 'saas')['value'];
  286. $wechat_config['pay_key'] = Option::get('platform_pay_key', 0, 'saas')['value'];
  287. $wechat_config['mch_id'] = Option::get('platform_mch_id', 0, 'saas')['value'];
  288. $wechat_config['cert_pem'] = Option::get('platform_apiclient_cert', 0, 'saas')['value'];
  289. $wechat_config['key_pem'] = Option::get('platform_apiclient_key', 0, 'saas')['value'];
  290. $wechat_config = (object)$wechat_config;
  291. }
  292. $cert_pem_file = null;
  293. if (isset($wechat_config->cert_pem)) {
  294. $cert_pem_file = \Yii::$app->runtimePath . '/pem/' . md5($wechat_config->cert_pem);
  295. if (!file_exists($cert_pem_file)) {
  296. file_put_contents($cert_pem_file, $wechat_config->cert_pem);
  297. }
  298. }
  299. $key_pem_file = null;
  300. if (isset($wechat_config->key_pem)) {
  301. $key_pem_file = \Yii::$app->runtimePath . '/pem/' . md5($wechat_config->key_pem);
  302. if (!file_exists($key_pem_file)) {
  303. file_put_contents($key_pem_file, $wechat_config->key_pem);
  304. }
  305. }
  306. $config = [
  307. 'app_id' => $wechat_config->app_id,
  308. 'secret' => $wechat_config->app_secret,
  309. 'key' => $wechat_config->pay_key,
  310. 'mch_id' => $wechat_config->mch_id,
  311. 'cert_path' => $cert_pem_file,
  312. 'key_path' => $key_pem_file,
  313. 'response_type' => 'array'
  314. ];
  315. }
  316. }
  317. $wechatMini = Factory::miniProgram($config);
  318. return $wechatMini->app_code;
  319. }
  320. public static function setBussinessWechat()
  321. {
  322. // 证书
  323. if (!is_dir(\Yii::$app->runtimePath . '/pem')) {
  324. mkdir(\Yii::$app->runtimePath . '/pem');
  325. file_put_contents(\Yii::$app->runtimePath . '/pem/index.html', '');
  326. }
  327. $config = [
  328. 'app_id' => Option::get('platform_appid', 0, 'saas')['value'],
  329. 'secret' => Option::get('platform_key', 0, 'saas')['value'],
  330. 'response_type' => 'array'
  331. ];
  332. if (\Yii::$app->prod_is_dandianpu()) {
  333. $config['app_id'] = Option::get('one_store_wechat_appid', 0, 'saas')['value'];
  334. $config['secret'] = Option::get('one_store_wechat_secret', 0, 'saas')['value'];
  335. }
  336. $wechatMini = Factory::miniProgram($config);
  337. return $wechatMini->app_code;
  338. }
  339. // 服务端小程序(商家端小程序)
  340. public static function serServerWechat()
  341. {
  342. $config = [
  343. 'app_id' => Option::get('platform_mch_appid', 0, 'saas')['value'],
  344. 'secret' => Option::get('platform_mch_key', 0, 'saas')['value'],
  345. 'response_type' => 'array'
  346. ];
  347. $wechatMini = Factory::miniProgram($config);
  348. return $wechatMini->app_code;
  349. }
  350. public static function aliConfigQr($request, $data = [])
  351. {
  352. try {
  353. $third_appid = Option::get("alipay_appid", 0, 'saas')['value'];
  354. $third_private_key = Option::get("alipay_app_private_key", 0, 'saas')['value'];
  355. $third_public_key = Option::get("alipay_public_key", 0, 'saas')['value'];
  356. $data = json_encode($data);
  357. $config_ali = Option::get(Option::OPTOPN_KEY, get_store_id(), 'alipay')['value'];
  358. $config_ali = json_decode($config_ali, true);
  359. $aop = new AopClient();
  360. //如果商城的支付宝小程序信息存在,则使用支付宝小程序的配置信息
  361. if (!empty($config_ali['app_id']) && !empty($config_ali['app_private_key']) && !empty($config_ali['app_public_key'])) {
  362. $aop->appId = $config_ali['app_id'];
  363. $aop->rsaPrivateKey = $config_ali['app_private_key'];
  364. $aop->encryptKey = $config_ali['aes_key'];
  365. $aop->alipayrsaPublicKey = $config_ali['alipay_public_key'];
  366. } else {
  367. //使用三方的配置信息
  368. $aop->appId = $third_appid;
  369. $aop->rsaPrivateKey = $third_private_key;
  370. $aop->alipayrsaPublicKey = $third_public_key;
  371. $ali_mini = StoreAliMini::find()->where(['auth_app_id' => $config_ali['app_id'], 'is_cancel' => 0, 'store_id' => get_store_id()])->asArray()->one();
  372. if (empty($ali_mini)) {
  373. throw new \Exception("查找小程序信息失败");
  374. }
  375. $token = $ali_mini['auth_token'];
  376. }
  377. $aop->encryptType = "AES";
  378. $aop->apiVersion = '1.0';
  379. $aop->signType = 'RSA2';
  380. $aop->postCharset = 'utf-8';
  381. $aop->format = 'json';
  382. $request->setBizContent($data);
  383. if (!empty($token)) {
  384. $result = $aop->execute ($request, null, $token);
  385. } else {
  386. $result = $aop->execute ($request);
  387. }
  388. $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
  389. return $result->$responseNode;
  390. } catch (\Exception $e) {
  391. return [
  392. 'code' => 1,
  393. 'msg' => $e->getMessage()
  394. ];
  395. }
  396. }
  397. }