Setting.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  1. <?php
  2. /**
  3. * @copyright Copyright (c) 2017 https://www.sapixx.com All rights reserved.
  4. * @license Licensed (http://www.apache.org/licenses/LICENSE-2.0).
  5. * @author pillar<ltmn@qq.com>
  6. * 应用设置
  7. */
  8. namespace app\system\controller\passport;
  9. use app\common\model\SystemMemberMiniapp;
  10. use app\common\model\SystemMemberPayment;
  11. use app\common\model\SystemMemberMiniappToken;
  12. use app\common\model\SystemMemberMiniappOrder;
  13. use app\common\model\SystemMemberWechatTpl;
  14. use app\common\model\SystemMemberMiniappCode;
  15. use app\common\facade\WechatMp;
  16. use app\common\facade\WechatProgram;
  17. use think\facade\Request;
  18. use Exception;
  19. class Setting extends Common{
  20. public function initialize(){
  21. parent::initialize();
  22. if($this->user->lock_config){
  23. $this->error('你账户锁定配置权限');
  24. }
  25. if($this->user->parent_id){
  26. $this->error('仅创始人有权限访问');
  27. }
  28. if(!$this->member_miniapp_id){
  29. $this->error('未找到所属应用,请先开通应用.');
  30. }
  31. $tabs[] = ['name' =>'关于应用','url' =>url('passport.setting/index')];
  32. $tabs[] = ['name' =>'应用配置','url' =>url('passport.setting/edit')];
  33. if ($this->member_miniapp->miniapp->is_wechat_pay){
  34. $tabs[] = ['name' =>'微信支付','url' =>url('passport.setting/wepay')];
  35. }
  36. if ($this->member_miniapp->miniapp->is_alipay_pay){
  37. $tabs[] = ['name' =>'支付宝','url' =>url('passport.setting/alipay')];
  38. }
  39. if ($this->member_miniapp->mp_appid || $this->member_miniapp->miniapp_appid){
  40. $tabs[] = ['name' =>'模板消息','url' =>url('passport.setting/tplmsg')];
  41. }
  42. $this->assign('tabs',$tabs);
  43. $this->assign('pathMaps',[['name'=>$this->member_miniapp->appname,'url'=>'javascript:;'],['name'=>'应用管理','url'=>url("system/passport.setting/index")]]);
  44. }
  45. /**
  46. * 列表
  47. * @access public
  48. */
  49. public function index(){
  50. if(empty($this->member_miniapp->head_img)){
  51. switch ($this->member_miniapp->miniapp->types) {
  52. case 'mp':
  53. $head_img = $this->member_miniapp->mp_head_img;
  54. break;
  55. case 'program':
  56. $head_img = $this->member_miniapp->miniapp_head_img;
  57. break;
  58. case 'app':
  59. $head_img = $this->member_miniapp->head_img;
  60. break;
  61. default:
  62. $head_img = empty($this->member_miniapp->mp_head_img) ? $this->member_miniapp->mp_head_img : $this->member_miniapp->miniapp_head_img;
  63. break;
  64. }
  65. }else{
  66. $head_img = $this->member_miniapp->head_img;;
  67. }
  68. $view['logo'] = empty($head_img) ? "/static/{$this->member_miniapp->miniapp->miniapp_dir}/logo.png" : $head_img;
  69. $view['miniapp'] = SystemMemberMiniappOrder::where(['member_id' => $this->user->id,'miniapp_id' => $this->member_miniapp->miniapp->id])->count();
  70. /**
  71. * 开放平台信息小程序管理
  72. * is_commit = 1、2、3、4
  73. * 1、基础信息设置
  74. * 2、上传代码
  75. * 3、提交审核
  76. * 4、发布小程序
  77. */
  78. $view['is_authorize'] = 0;
  79. $view['code']['is_commit'] = 1;
  80. $view['code']['state'] = 0;
  81. if(!$this->member_miniapp->miniapp->is_openapp && $this->member_miniapp->miniapp_appid){
  82. $miniapp = WechatProgram::isTypes($this->member_miniapp_id);
  83. if($miniapp){
  84. $view['is_authorize'] = 1;
  85. $view['auditid']['status'] = -1;
  86. $code = SystemMemberMiniappCode::where(['member_miniapp_id'=>$this->member_miniapp_id,'member_id' => $this->user->id])->find(); //查询状态
  87. if($code){
  88. $view['code'] = $code;
  89. //查询审核状态 is_commit = 3 && state = 1
  90. if($view['code']['is_commit'] == 3 && $view['code']['state'] == 1){
  91. $rel = $miniapp->code->getLatestAuditStatus();
  92. if($rel['errcode'] == 0){
  93. $view['auditid'] = $rel;
  94. if($rel['status'] == 1){
  95. $view['code']->state = 0;
  96. $view['code']->is_commit = 2;
  97. $view['code']->save();
  98. }
  99. }
  100. }
  101. //已发布的代码 is_commit = 4 && state = 0
  102. $view['update_var'] = 0;
  103. if($view['code']['is_commit'] == 4 && $view['code']['state'] == 0){
  104. $var = SystemMemberMiniappOrder::where(['id' => $this->member_miniapp->miniapp_order_id])->field('update_var')->find();
  105. if($this->member_miniapp->miniapp->template_id > $var->update_var){
  106. $view['update_var'] = 1;
  107. $view['code']['is_commit'] = 2;
  108. }
  109. }
  110. if(!file_exists(PATH_PUBLIC.$view['code']['trial_qrcode'])){
  111. $view['code']['trial_qrcode'] = '';
  112. }
  113. }
  114. }
  115. }
  116. return view()->assign($view);
  117. }
  118. /**
  119. * 编辑授权
  120. */
  121. public function edit(){
  122. if(request()->isAjax()){
  123. $data = [
  124. 'id' => Request::param('id/d'),
  125. 'member_id' => $this->user['id'],
  126. 'appname' => Request::param('appname/s'),
  127. 'is_psp' => Request::param('is_psp/d'),
  128. 'psp_appid' => Request::param('psp_appid/s'),
  129. 'miniapp_appid' => Request::param('miniapp_appid/s'),
  130. 'miniapp_secret' => Request::param('miniapp_secret/s'),
  131. 'sdk_url' => Request::param('sdk_url/s'),
  132. 'sdk_app_id' => Request::param('sdk_app_id/s'),
  133. 'mp_appid' => Request::param('mp_appid/s'),
  134. 'mp_secret' => Request::param('mp_secret/s'),
  135. 'mp_token' => Request::param('mp_token/s'),
  136. 'mp_aes_key' => Request::param('mp_aes_key/s'),
  137. 'navbar_color' => Request::param('navbar_color/s'),
  138. 'navbar_style' => Request::param('navbar_style/s'),
  139. ];
  140. if($this->member_miniapp->miniapp->is_openapp){
  141. switch ($this->member_miniapp->miniapp->types) {
  142. case 'mp':
  143. $validate = $this->validate($data,'miniapp.editOfficia');
  144. break;
  145. case 'program':
  146. $validate = $this->validate($data,'miniapp.editProgram');
  147. break;
  148. case 'app':
  149. $validate = $this->validate($data,'miniapp.editApp');
  150. break;
  151. default:
  152. $validate = $this->validate($data,'miniapp.editMiniapp');
  153. break;
  154. }
  155. }else{
  156. $validate = $this->validate($data,'miniapp.editApp');
  157. }
  158. if(true !== $validate){
  159. return enjson(0,$validate);
  160. }
  161. if($data['is_psp'] == 1){
  162. if(empty($data['psp_appid'])){
  163. return enjson(0,'服务商支付开启的,必须填写服务商AppID');
  164. }
  165. }else{
  166. $data['psp_appid'] = '0';
  167. }
  168. $result = SystemMemberMiniapp::editer($data);
  169. if($result){
  170. return enjson(200,'成功',['url' => url('system/passport.setting/edit')]);
  171. }
  172. return enjson(0);
  173. }else{
  174. return view();
  175. }
  176. }
  177. /**
  178. * 微信支付
  179. * @return void
  180. */
  181. public function wepay(){
  182. if($this->member_miniapp->miniapp->is_wechat_pay == 0){
  183. return $this->error("应用没有微信支付服务");
  184. }
  185. if(request()->isPost()){
  186. $rules = [
  187. 'id' => Request::param('id/d'),
  188. 'mch_id' => Request::param('mch_id/s'),
  189. 'key' => Request::param('key/s'),
  190. 'cert_path' => Request::param('cert_path/s'),
  191. 'key_path' => Request::param('key_path/s'),
  192. ];
  193. $validate = $this->validate($rules,'Payment.wechat');
  194. if(true !== $validate){
  195. return json(['code'=>0,'msg'=>$validate]);
  196. }
  197. $rel = SystemMemberPayment::where(['apiname'=>'wepay','member_miniapp_id'=>$this->member_miniapp_id])->find();
  198. $config = json_encode(['mch_id' => $rules['mch_id'],'key'=>$rules['key'],'cert_path' => $rules['cert_path'],'key_path' => $rules['key_path']]);
  199. if($rel){
  200. $rel->config = $config;
  201. $rel->update_time = time();
  202. $result = $rel->save();
  203. }else{
  204. $data['config'] = $config;
  205. $data['update_time'] = time();
  206. $data['member_miniapp_id'] = $this->member_miniapp_id;
  207. $data['member_id'] = $this->user->id;
  208. $data['apiname'] = 'wepay';
  209. $result = SystemMemberPayment::insert($data);
  210. }
  211. if($result){
  212. return enjson(200,'成功',['url' => url('system/passport.setting/wepay')]);
  213. }
  214. return enjson(0);
  215. }else{
  216. $rel = SystemMemberPayment::where(['apiname'=>'wepay','member_miniapp_id'=>$this->member_miniapp_id])->find();
  217. $view['config'] = json_decode($rel['config'],true);
  218. return view()->assign($view);
  219. }
  220. }
  221. /**
  222. * 支付宝支付
  223. * @return void
  224. */
  225. public function alipay(){
  226. if($this->member_miniapp->miniapp->is_alipay_pay == 0){
  227. return $this->error("应用没有支付宝支付服务");
  228. }
  229. if(request()->isPost()){
  230. $rules = [
  231. 'id' => Request::param('id/d'),
  232. 'app_id' => Request::param('app_id/s'),
  233. 'public_key' => Request::param('public_key/s'),
  234. 'private_key' => Request::param('private_key/s'),
  235. ];
  236. $validate = $this->validate($rules,'Payment.alipay');
  237. if(true !== $validate){
  238. return json(['code'=>0,'msg'=>$validate]);
  239. }
  240. $rel = SystemMemberPayment::where(['apiname'=>'alipay','member_miniapp_id'=>$this->member_miniapp_id])->find();
  241. $config = json_encode(['app_id' => $rules['app_id'],'public_key'=>$rules['public_key'],'private_key' => $rules['private_key']]);
  242. if($rel){
  243. $rel->config = $config;
  244. $rel->update_time = time();
  245. $result = $rel->save();
  246. }else{
  247. $data['config'] = $config;
  248. $data['member_miniapp_id'] = $this->member_miniapp_id;
  249. $data['member_id'] = $this->user->id;
  250. $data['apiname'] = 'alipay';
  251. $data['update_time'] = time();
  252. $result = SystemMemberPayment::insert($data);
  253. }
  254. if($result){
  255. return enjson(200,'成功',['url' => url('system/passport.setting/alipay')]);
  256. }
  257. return enjson(0);
  258. }else{
  259. $rel = SystemMemberPayment::where(['apiname'=>'alipay','member_miniapp_id'=>$this->member_miniapp_id])->find();
  260. $view['config'] = json_decode($rel['config'],true);
  261. return view()->assign($view);
  262. }
  263. }
  264. //微信模板消息
  265. public function tplmsg(){
  266. if(request()->isPost()){
  267. $rules = [
  268. 'tplmsg_common_wechat' => $this->request->param('tplmsg_common_wechat/s'),
  269. 'tplmsg_common_app' => $this->request->param('tplmsg_common_app/s'),
  270. ];
  271. $rel = SystemMemberWechatTpl::where(['member_miniapp_id'=>$this->member_miniapp_id])->find();
  272. if($rel){
  273. $rel->tplmsg_common_wechat = $rules['tplmsg_common_wechat'];
  274. $rel->tplmsg_common_app = $rules['tplmsg_common_app'];
  275. $result = $rel->save();
  276. }else{
  277. $result = SystemMemberWechatTpl::create(['member_miniapp_id'=>$this->member_miniapp_id,'tplmsg_common_wechat' => $rules['tplmsg_common_wechat'],'tplmsg_common_app' => $rules['tplmsg_common_app']]);
  278. }
  279. if($result){
  280. return enjson(200,'成功',['url' => url('system/passport.setting/tplmsg')]);
  281. }
  282. return enjson(0);
  283. }else{
  284. $view['info'] = SystemMemberWechatTpl::where(['member_miniapp_id'=>$this->member_miniapp_id])->find();
  285. return view()->assign($view);
  286. }
  287. }
  288. /**
  289. * 以下部分是微信小程序官方操作
  290. * ###########################################
  291. * 发起授权
  292. * @return json
  293. */
  294. public function pushAuth(string $types){
  295. //在此查询看看当前应用是公众号还是小程序
  296. if($this->member_miniapp->is_lock == 1){
  297. $this->error('当前应用已停止服务');
  298. }
  299. if($this->member_miniapp->miniapp->is_openapp){
  300. $this->error('应用不支持扫码授权,请手动配置',url('system/passport.setting/edit'));
  301. }
  302. //查询授权是否过期
  303. $appid = $types == 'mp' ? $this->member_miniapp->mp_appid : $this->member_miniapp->miniapp_appid;
  304. if(!empty($appid)){
  305. try {
  306. $assess = SystemMemberMiniappToken::accessToken($this->member_miniapp_id,$appid);
  307. }catch (Exception $e) {
  308. $this->error($e->getMessage());
  309. }
  310. if ($assess) {
  311. $url = $types == 'mp' ? url('system/passport.official/index'):url('system/passport.miniapp/edit');
  312. $this->success('授权未过期,请10分钟后再试。',$url);
  313. }
  314. }
  315. try {
  316. $url = WechatMp::openConfig()->getPreAuthorizationUrl(url('system/passport.setting/authCallback',['id' => $this->member_miniapp_id],true,true));
  317. }catch (Exception $e) {
  318. $this->error($e->getMessage());
  319. }
  320. return redirect($url);
  321. }
  322. /**
  323. * 微信开放平台推送车票(1次/10分钟)
  324. * 有了车票要保存下来,获取授权时要用
  325. * @return json
  326. */
  327. public function authCallback(){
  328. //在此查询看看当前应用是公众号还是小程序
  329. if($this->member_miniapp->is_lock == 1){
  330. $this->error('当前应用已停止服务');
  331. }
  332. if($this->member_miniapp->miniapp->is_openapp){
  333. $this->error('应用不支持扫码授权,请手动配置',url('system/passport.setting/edit'));
  334. }
  335. if(Request::get('state/s') == 'STATE'){
  336. $this->error('您禁止了微信授权,所以暂时无权创建应用',url('system/passport.setting/index'));
  337. }
  338. $openPlatform = WechatMp::openConfig();
  339. if(empty($openPlatform)){
  340. $this->error('应用未配置开放平台授权信息');
  341. }
  342. try {
  343. $appinfo = $openPlatform->handleAuthorize();
  344. }catch (Exception $e) {
  345. $this->error($e->getMessage());
  346. }
  347. if(!empty($appinfo['errcode'])){
  348. $this->error($appinfo['errmsg']);
  349. }
  350. $appid = $appinfo['authorization_info']['authorizer_appid'];
  351. //根据凭证获取的应用信息
  352. $miniProgram = $openPlatform->getAuthorizer($appid);
  353. if(empty($miniProgram['authorizer_info'])){
  354. $this->error('授权信息读取失败');
  355. }
  356. $head_img = $miniProgram['authorizer_info']['head_img'] ?? '';
  357. if(empty($miniProgram['authorizer_info']['MiniProgramInfo'])){
  358. if($miniProgram['authorizer_info']['service_type_info']['id'] != 2){
  359. $this->error('不支持订阅号');
  360. }
  361. if($miniProgram['authorizer_info']['verify_type_info']['id'] < 0){
  362. $this->error('未通过微信认证的服务号禁止接入');
  363. }
  364. $app_data['mp_appid'] = $appid; //公众号
  365. $app_data['mp_head_img'] = $head_img;
  366. $app_data['mp_qrcode_url'] = $miniProgram['authorizer_info']['qrcode_url'];
  367. }else{
  368. if($miniProgram['authorizer_info']['verify_type_info']['id'] < 0){
  369. $this->error('未通过微信认证的小程序禁止接入');
  370. }
  371. $app_data['miniapp_appid'] = $appid; //小程序
  372. $app_data['miniapp_head_img'] = $head_img;
  373. $app_data['miniapp_qrcode_url'] = $miniProgram['authorizer_info']['qrcode_url'];
  374. }
  375. $app_data['is_open'] = 1;
  376. SystemMemberMiniapp::where(['id' => $this->member_miniapp_id])->update($app_data);
  377. //更新授权信息
  378. $at['member_miniapp_id'] = $this->member_miniapp_id;
  379. $at['appid'] = $appid;
  380. $at['access_token'] = $appinfo['authorization_info']['authorizer_access_token'];
  381. $at['expires_in'] = $appinfo['authorization_info']['expires_in'];
  382. $at['refresh_token'] = $appinfo['authorization_info']['authorizer_refresh_token'];
  383. SystemMemberMiniappToken::edit($at);
  384. //设置授权域名
  385. if(!empty($miniProgram['authorizer_info']['MiniProgramInfo'])){
  386. $url['action'] = 'set';
  387. $url['requestdomain'] = ['https://res.'.Request::rootDomain(),'https://'.$this->web->url];
  388. $url['wsrequestdomain'] = ['wss://res.'.Request::rootDomain(),'wss://'.$this->web->url];
  389. $url['uploaddomain'] = $url['requestdomain'];
  390. $url['downloaddomain'] = $url['requestdomain'];
  391. $domain = WechatProgram::isTypes($this->member_miniapp_id)->domain;
  392. $domain->modify($url);
  393. $domain->setWebviewDomain([Request::scheme().'://'.Request::rootDomain()]); //设置业务域名
  394. }
  395. return redirect('system/passport.setting/index');
  396. }
  397. }