WeiXinOpen.Class.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: phperstar
  5. * Date: 2019/12/2
  6. * Time: 2:37 PM
  7. */
  8. namespace JinDouYun\Controller\Common;
  9. use Mall\Framework\Core\StatusCode;
  10. use Mall\Framework\Factory;
  11. use Mall\Framework\Core\ErrorCode;
  12. use JinDouYun\Controller\BaseController;
  13. use JinDouYun\Model\Enterprise\MEnterprise;
  14. use JinDouYun\Model\System\MEnterpriseBindTemplate;
  15. use JinDouYun\Model\Oem\MOem;
  16. use Util\WeiXin\Oplatform;
  17. use Util\WeiXin\Miniprogram;
  18. class WeiXinOpen extends BaseController
  19. {
  20. /**
  21. * 验证票据(component_verify_ticket)缓存
  22. */
  23. private $component_verify_ticket = 'componentVerifyTicket';
  24. private $location_uri = 'http://'.DOMAIN_WWW.'/#/AuthorizePage';
  25. // 授权回调地址
  26. private $redirect_uri = 'http://'.DOMAIN_WWW.'/AuthorizePage';
  27. /**
  28. * WeiXinOpen constructor.
  29. * @param bool $isCheckAcl
  30. * @param bool $isMustLogin
  31. * @param bool $checkToken
  32. */
  33. public function __construct($isCheckAcl = false, $isMustLogin = false, $checkToken = false)
  34. {
  35. parent::__construct($isCheckAcl, $isMustLogin, $checkToken);
  36. }
  37. /**
  38. * 授权事件接受URl
  39. * 官方文档地址: https://developers.weixin.qq.com/doc/oplatform/Third-party_Platforms/api/component_verify_ticket.html
  40. */
  41. public function notifyAccess()
  42. {
  43. $postStr = file_get_contents('php://input');
  44. file_put_contents('/www/wwwroot/logs/api.junhailan.com/weixinopen.log', date('Y-m-d H:i:s') . '回调数据' . var_export($postStr, true) . PHP_EOL, FILE_APPEND);
  45. if (empty($postStr)) {
  46. exit('faild');
  47. }
  48. $params['timestamp'] = $this->request->param('timestamp');
  49. $params['msg_signature'] = $this->request->param('msg_signature');
  50. $params['nonce'] = $this->request->param('nonce');
  51. foreach ($params as $key => $value) {
  52. if (empty($value) && $value !== 0) {
  53. exit('回调数据有误');
  54. }
  55. }
  56. libxml_disable_entity_loader(true);
  57. // 先做签名校验
  58. $data = json_decode(json_encode(simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
  59. /*
  60. $oplatformConfigData = Factory::config()->getAppoint('weixin', 'oplatform');
  61. if (empty($oplatformConfigData)) {
  62. exit('配置错误');
  63. }*/
  64. $objOem = new MOem();
  65. $oemData = $objOem->getOemInfoByWeiXinOpenAppId($data['AppId']);
  66. if(!$oemData->isSuccess()){
  67. file_put_contents('/www/wwwroot/logs/api.junhailan.com/weixinopen.log', date('Y-m-d H:i:s') . '从oem表获取配置错误' . PHP_EOL, FILE_APPEND);
  68. exit('faild');
  69. }
  70. $oemData = $oemData->getData();
  71. if(empty($oemData)){
  72. file_put_contents('/www/wwwroot/logs/api.junhailan.com/weixinopen.log', date('Y-m-d H:i:s') . '从oem表获取配置为空' . PHP_EOL, FILE_APPEND);
  73. exit('faild');
  74. }
  75. $oplatformConfigData = json_decode($oemData['weixinOpen'], true);
  76. if( empty($oplatformConfigData) ){
  77. file_put_contents('/www/wwwroot/logs/api.junhailan.com/weixinopen.log', date('Y-m-d H:i:s') . '从oem表获取开放平台配置为空' . PHP_EOL, FILE_APPEND);
  78. exit('faild');
  79. }
  80. $objOplatform = new Oplatform($oplatformConfigData['appid'], $oplatformConfigData['token'], $oplatformConfigData['encodingAesKey'], $oplatformConfigData['appSecret']);
  81. $result = $objOplatform->decryptMsg($params['msg_signature'], $params['timestamp'], $params['nonce'], $data);
  82. if (!$result->isSuccess()) {
  83. $this->sendOutput($result->getData(), $result->getErrorCode());
  84. }
  85. $xmlContent = $result->getData();
  86. $data = json_decode(json_encode(simplexml_load_string($xmlContent, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
  87. if (!empty($data) && $data['InfoType'] == 'component_verify_ticket') {
  88. Factory::cache('default')->set($this->component_verify_ticket . ':' . $oplatformConfigData['appid'], $data['ComponentVerifyTicket']);
  89. }
  90. if(!empty($data) && isset($data['notify_third_fasteregister'])){
  91. // 修改当前企业的appid
  92. $enterpriseMd5Key = md5($data['name'].$data['code'].$data['legal_persona_wechat'].$data['legal_persona_name']);
  93. $objMEnterprise = new MEnterprise();
  94. $modelResult = $objMEnterprise->updateEnterprise(['appid' => $data['appid']], ['weChatProgramKey' => $enterpriseMd5Key]);
  95. if(!$modelResult->isSuccess()){
  96. $this->sendOutput($modelResult->getData(), $modelResult->getErrorCode());
  97. }
  98. $result = $objOplatform->apiQueryAuth($data['auth_code']);
  99. if (!$result->isSuccess()) {
  100. $this->sendOutput($result->getData(), $result->getErrorCode());
  101. }
  102. }
  103. exit('success');
  104. }
  105. /**
  106. * 消息与事件接收URL
  107. * 官方文档地址: https://developers.weixin.qq.com/doc/oplatform/Third-party_Platforms/api/component_verify_ticket.html
  108. */
  109. public function notifyMessage()
  110. {
  111. $appid = $this->request->param('request_id');
  112. $postStr = file_get_contents('php://input');
  113. file_put_contents('/www/wwwroot/logs/api.junhailan.com/weixinopen.log', date('Y-m-d H:i:s') . $appid . '回调数据' . var_export($postStr, true) . PHP_EOL, FILE_APPEND);
  114. if (empty($postStr)) {
  115. exit('faild');
  116. }
  117. $params['timestamp'] = $this->request->param('timestamp');
  118. $params['msg_signature'] = $this->request->param('msg_signature');
  119. $params['nonce'] = $this->request->param('nonce');
  120. foreach ($params as $key => $value) {
  121. if (empty($value) && $value !== 0) {
  122. exit('回调数据有误');
  123. }
  124. }
  125. libxml_disable_entity_loader(true);
  126. // 先做签名校验
  127. $data = json_decode(json_encode(simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
  128. /*
  129. $oplatformConfigData = Factory::config()->getAppoint('weixin', 'oplatform');
  130. if (empty($oplatformConfigData)) {
  131. exit('配置错误');
  132. }*/
  133. $objOem = new MOem();
  134. $oemData = $objOem->getOemInfoByWeiXinOpenAppId($data['AppId']);
  135. if(!$oemData->isSuccess()){
  136. file_put_contents('/www/wwwroot/logs/api.junhailan.com/weixinopen.log', date('Y-m-d H:i:s') . '从oem表获取配置错误' . PHP_EOL, FILE_APPEND);
  137. exit('faild');
  138. }
  139. $oemData = $oemData->getData();
  140. if(empty($oemData)){
  141. file_put_contents('/www/wwwroot/logs/api.junhailan.com/weixinopen.log', date('Y-m-d H:i:s') . '从oem表获取配置为空' . PHP_EOL, FILE_APPEND);
  142. exit('faild');
  143. }
  144. $oplatformConfigData = json_decode($oemData['weixinOpen'], true);
  145. if( empty($oplatformConfigData) ){
  146. file_put_contents('/www/wwwroot/logs/api.junhailan.com/weixinopen.log', date('Y-m-d H:i:s') . '从oem表获取开放平台配置为空' . PHP_EOL, FILE_APPEND);
  147. exit('faild');
  148. }
  149. $objOplatform = new Oplatform($oplatformConfigData['appid'], $oplatformConfigData['token'], $oplatformConfigData['encodingAesKey'], $oplatformConfigData['appSecret']);
  150. $result = $objOplatform->decryptMsg($params['msg_signature'], $params['timestamp'], $params['nonce'], $data);
  151. if (!$result->isSuccess()) {
  152. echo($result->getData());exit();
  153. }
  154. $xmlContent = $result->getData();
  155. $data = json_decode(json_encode(simplexml_load_string($xmlContent, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
  156. file_put_contents('/www/wwwroot/logs/api.junhailan.com/weixinopen.log', date('Y-m-d H:i:s') . $appid . '回调数据' . var_export($data, true) . PHP_EOL, FILE_APPEND);
  157. $objMEnterpriseBindTemplate = new MEnterpriseBindTemplate(null, null);
  158. // 事件消息
  159. if (!empty($data) && isset($data['MsgType']) && $data['MsgType'] == 'event') {
  160. // 小程序审核通过事件
  161. if ($data['Event'] == 'weapp_audit_success') {
  162. $data['auditStatus'] = StatusCode::$wxAuditStatus['pass'];
  163. $objMEnterpriseBindTemplate->updateAuditStatus($data);
  164. }
  165. // 小程序审核失败事件
  166. if($data['Event'] == 'weapp_audit_fail'){
  167. $data['reason'] = [
  168. 'reason' => isset($data['Reason']) ? $data['Reason'] : '',
  169. ];
  170. $data['auditStatus'] = StatusCode::$wxAuditStatus['refuse'];
  171. $objMEnterpriseBindTemplate->updateAuditStatus($data);
  172. }
  173. exit('success');
  174. }
  175. // 注册审核时间
  176. if (!empty($data) && isset($data['InfoType']) && $data['InfoType'] == 'notify_third_fasteregister') {
  177. }
  178. // 文本消息
  179. if (!empty($data) && isset($data['MsgType']) && $data['MsgType'] == 'text') {
  180. // 第三方平台验证用的固定回复
  181. if($data['Content'] == 'TESTCOMPONENT_MSG_TYPE_TEXT'){
  182. $reponseData = [
  183. 'ToUserName'=>$data['FromUserName'],
  184. 'FromUserName' =>$data['ToUserName'],
  185. 'CreateTime'=>time(),
  186. 'MsgType' => 'text',
  187. 'Content' => 'TESTCOMPONENT_MSG_TYPE_TEXT_callback',
  188. ];
  189. $reponseData = arrayToWeiXinXml($reponseData);
  190. echo $reponseData;
  191. /*
  192. $result = $objOplatform->encryptMsg($reponseData, $params['timestamp'], $params['nonce']);
  193. if (!$result->isSuccess()) {
  194. echo($result->getData());exit();
  195. }
  196. $xmlContent = $result->getData();
  197. file_put_contents('/www/wwwroot/logs/api.junhailan.com/weixinopen.log', date('Y-m-d H:i:s'). '回调数据' . var_export($xmlContent, true) . PHP_EOL, FILE_APPEND);
  198. */
  199. }
  200. // 第三方平台用的验证客服消息
  201. if(strpos($data['Content'],'QUERY_AUTH_CODE') !== false){
  202. $postContent = explode(':', $data['Content']);
  203. $query_auth_code = $postContent[1];
  204. unset($result);
  205. $result = $objOplatform->apiQueryAuth($query_auth_code);
  206. if (!$result->isSuccess()) {
  207. echo($result->getData());exit();
  208. }
  209. $authorization_info = $result->getData();
  210. $authorizer_appid = $authorization_info['authorizer_appid'];
  211. $authorizer_access_token = $authorization_info['authorizer_access_token'];
  212. $miniprogramConfigData = Factory::config()->getAppoint('weixin','miniprogram');
  213. if(empty($miniprogramConfigData)){
  214. echo('小程序配置项错误');exit();
  215. }
  216. unset($result);
  217. $objMiniprogram = new Miniprogram($miniprogramConfigData['appid'], $miniprogramConfigData['appSecret']);
  218. $sendMessage = $query_auth_code.'_from_api';
  219. $result = $objMiniprogram->messageCustomSend($authorizer_access_token, $sendMessage,$data['FromUserName']);
  220. file_put_contents('/www/wwwroot/logs/api.junhailan.com/weixinopen.log', date('Y-m-d H:i:s'). '回调数据' . var_export($result, true) . PHP_EOL, FILE_APPEND);
  221. if (!$result->isSuccess()) {
  222. echo($result->getData());exit();
  223. }
  224. exit('');
  225. }
  226. }
  227. }
  228. /**
  229. * 获取预授权码(pre_auth_code)
  230. * 官网文档地址: https://developers.weixin.qq.com/doc/oplatform/Third-party_Platforms/Authorization_Process_Technical_Description.html
  231. */
  232. public function preAuthCode()
  233. {
  234. //获取微信配置
  235. $oplatformConfigData = Factory::config()->getAppoint('weixin', 'oplatform');
  236. if (empty($oplatformConfigData)) {
  237. exit('配置错误');
  238. }
  239. $objOplatform = new Oplatform($oplatformConfigData['appid'], $oplatformConfigData['token'], $oplatformConfigData['encodingAesKey'], $oplatformConfigData['appSecret']);
  240. $result = $objOplatform->preAuthCode();
  241. if (!$result->isSuccess()) {
  242. parent::sendOutput($result->getData(), $result->getErrorCode());
  243. }
  244. $pre_auth_code = $result->getData();
  245. $auth_url = 'https://mp.weixin.qq.com/cgi-bin/componentloginpage?component_appid=' . $oplatformConfigData['appid'] . '&pre_auth_code=' . $pre_auth_code . '&redirect_uri=' . $this->redirect_uri . '&auth_type=2';
  246. parent::sendOutput($auth_url);
  247. }
  248. /**
  249. * 接受授权码 authorization_code
  250. */
  251. public function authorizationCode()
  252. {
  253. $params = $this->request->getRawJson();
  254. $authData = [
  255. 'auth_code' => $this->request->param('auth_code'),
  256. 'expires_in' => $this->request->param('expires_in'),
  257. ];
  258. foreach ($authData as $key => $value) {
  259. if (empty($value)) {
  260. parent::sendOutput($key . '参数为空!', ErrorCode::$paramError);
  261. }
  262. }
  263. /*
  264. $oplatformConfigData = Factory::config()->getAppoint('weixin', 'oplatform');
  265. if (empty($oplatformConfigData)) {
  266. parent::sendOutput('微信三方平台配置错误', ErrorCode::$paramError);
  267. }*/
  268. $objMOem = new MOem();
  269. $result = $objMOem->getOemInfoByApiDomain($_SERVER['HTTP_HOST']);
  270. if( !$result->isSuccess() ){
  271. parent::sendOutput($result->getData(), $result->getErrorCode());
  272. }
  273. $oemData = $result->getData();
  274. if( empty($oemData) ){
  275. parent::sendOutput('oem表中获取配置为空', ErrorCode::$contentNotExists);
  276. }
  277. $oplatformConfigData = json_decode($oemData['weixinOpen'], true);
  278. if( empty($oplatformConfigData) ){
  279. parent::sendOutput('oem表中获取微信开放平台配置为空', ErrorCode::$contentNotExists);
  280. }
  281. $objOplatform = new Oplatform($oplatformConfigData['appid'], $oplatformConfigData['token'], $oplatformConfigData['encodingAesKey'], $oplatformConfigData['appSecret']);
  282. $result = $objOplatform->apiQueryAuth($authData['auth_code']);
  283. if (!$result->isSuccess()) {
  284. parent::sendOutput($result->getData(), $result->getErrorCode());
  285. }
  286. echo "<script>location.href='http://".$oemData['domain']."/#/AuthorizePage'</script>";
  287. //parent::sendOutput($result->getData());
  288. }
  289. /**
  290. * 创建小程序接口
  291. */
  292. public function fastregisterweapp()
  293. {
  294. $params = $this->request->getRawJson();
  295. $componentData = [
  296. 'enterpriseId' => isset($params['enterpriseId']) ? $params['enterpriseId'] : '',//企业id
  297. 'name' => isset($params['name']) ? $params['name'] : '', // 企业名称
  298. 'code' => isset($params['code']) ? $params['code'] : '', // 企业代码
  299. 'code_type' => isset($params['code_type']) ? $params['code_type'] : 1, // 企业代码类型(1:统一社会信用代码2:组织机构代码3:营业执照注册号)
  300. 'legal_persona_wechat' => isset($params['legal_persona_wechat']) ? $params['legal_persona_wechat'] : '', // 法人微信
  301. 'legal_persona_name' => isset($params['legal_persona_name']) ? $params['legal_persona_name'] : '', // 法人姓名
  302. 'component_phone' => isset($params['component_phone']) ? $params['component_phone'] : '', // 第三方联系电话
  303. ];
  304. foreach ($componentData as $key => $value) {
  305. if (empty($value)) {
  306. parent::sendOutput($key . '参数为空!', ErrorCode::$paramError);
  307. }
  308. }
  309. //根据企业id保存企业数据
  310. $objMEnterprise = new Menterprise();
  311. $update = [
  312. 'weChatEnterpriseName' => $componentData['name'],//企业名称
  313. 'weChatEnterpriseCode' => $componentData['code'],//企业代码
  314. 'legalPersonaWeChat' => $componentData['legal_persona_wechat'],//法人微信
  315. 'legalPersonaName' => $componentData['legal_persona_name'],//法人姓名
  316. 'weChatProgramKey' => md5($componentData['name'].$componentData['code'].$componentData['legal_persona_wechat'].$componentData['legal_persona_name'])//唯一key
  317. ];
  318. $modelResult = $objMEnterprise->updateEnterprise($update,['id' => $componentData['enterpriseId']]);
  319. if(!$modelResult->isSuccess()){
  320. parent::sendOutput($modelResult->getData(),$modelResult->getErrorCode());
  321. }
  322. unset($componentData['enterpriseId']);
  323. $oplatformConfigData = Factory::config()->getAppoint('weixin', 'oplatform');
  324. if (empty($oplatformConfigData)) {
  325. parent::sendOutput('微信三方平台配置错误', ErrorCode::$paramError);
  326. }
  327. $objOplatform = new Oplatform($oplatformConfigData['appid'], $oplatformConfigData['token'], $oplatformConfigData['encodingAesKey'], $oplatformConfigData['appSecret']);
  328. $result = $objOplatform->fastregisterweappCreate($componentData);
  329. if (!$result->isSuccess()) {
  330. parent::sendOutput($result->getData(), $result->getErrorCode());
  331. }
  332. parent::sendOutput($result->getData());
  333. }
  334. /**
  335. * 微信认证名称检测
  336. */
  337. public function checkwxverifynickname()
  338. {
  339. $params = $this->request->getRawJson();
  340. $data = [
  341. 'appid' => isset($params['appid']) ? $params['appid'] : '',
  342. 'nickName' => isset($params['nickName']) ? $params['nickName'] : '', // 企业名称
  343. ];
  344. foreach ($data as $key => $value) {
  345. if (empty($value)) {
  346. parent::sendOutput($key . '参数为空!', ErrorCode::$paramError);
  347. }
  348. }
  349. $oplatformConfigData = Factory::config()->getAppoint('weixin', 'oplatform');
  350. if (empty($oplatformConfigData)) {
  351. parent::sendOutput('微信三方平台配置错误', ErrorCode::$paramError);
  352. }
  353. $objOplatform = new Oplatform($oplatformConfigData['appid'], $oplatformConfigData['token'], $oplatformConfigData['encodingAesKey'], $oplatformConfigData['appSecret']);
  354. $result = $objOplatform->checkwxverifynickname($data['appid'], $data['nickName']);
  355. if (!$result->isSuccess()) {
  356. parent::sendOutput($result->getData(), $result->getErrorCode());
  357. }
  358. parent::sendOutput($result->getData());
  359. }
  360. /**
  361. * 设置小程序名称
  362. */
  363. public function setnickname()
  364. {
  365. $params = $this->request->getRawJson();
  366. $data = [
  367. 'appid' => isset($params['appid']) ? $params['appid'] : '',
  368. 'nickName' => isset($params['nickName']) ? $params['nickName'] : '', // 企业名称
  369. ];
  370. foreach ($data as $key => $value) {
  371. if (empty($value)) {
  372. parent::sendOutput($key . '参数为空!', ErrorCode::$paramError);
  373. }
  374. }
  375. $oplatformConfigData = Factory::config()->getAppoint('weixin', 'oplatform');
  376. if (empty($oplatformConfigData)) {
  377. parent::sendOutput('微信三方平台配置错误', ErrorCode::$paramError);
  378. }
  379. $objOplatform = new Oplatform($oplatformConfigData['appid'], $oplatformConfigData['token'], $oplatformConfigData['encodingAesKey'], $oplatformConfigData['appSecret']);
  380. $result = $objOplatform->setnickname($data['appid'], $data['nickName']);
  381. if (!$result->isSuccess()) {
  382. parent::sendOutput($result->getData(), $result->getErrorCode());
  383. }
  384. parent::sendOutput($result->getData());
  385. }
  386. }