UserMp.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. <?php
  2. /**
  3. * @package merchant
  4. *
  5. * @author xaboy
  6. * @day 2020/6/18
  7. *
  8. *
  9. */
  10. namespace app\controller\api\user;
  11. use app\common\dao\user\UnionUsersDao;
  12. use app\common\repositories\article\AgreementRepository;
  13. use app\common\repositories\merchant\order\OrderMerchantRepository;
  14. use app\common\repositories\user\UnionUsersRepository;
  15. use applet\WXBizDataCrypt;
  16. use crmeb\basic\BaseController;
  17. use app\common\repositories\user\UserRepository;
  18. use crmeb\services\MiniProgramService;
  19. use think\App;
  20. use think\Exception;
  21. use think\facade\Cache;
  22. use think\facade\Db;
  23. use think\facade\Log;
  24. class UserMp extends BaseController
  25. {
  26. public $repository;
  27. private $appid;
  28. private $secret;
  29. protected $merId;
  30. protected $source;
  31. public function __construct(App $app, UserRepository $repository)
  32. {
  33. parent::__construct($app);
  34. $this->repository = $repository;
  35. $this->source = $this->request->header('source');
  36. $this->merId = $this->request->header('merId');
  37. //点餐小程序
  38. // $this->appid = 'wx10669a2eca032216';
  39. // $this->secret = '0e71d5c636fdb9bf1c79c403db70f739';
  40. // $this->appid = 'wx7b4d857deb0447f3';
  41. // $this->secret = '643efbd7f3cd6398df1e7adb441afceb';
  42. $this->appid = 'wx9082e5ac2fdb513f';
  43. $this->secret = 'e334c41e1c4aa962f65d1882092fbda6';
  44. }
  45. public function getUserUnionid(){
  46. $data = $this->request->params(['code','source']);
  47. if(!$data['code'] || $data['code'] == '' || $data['code'] =='undefined') {
  48. return app('json')->fail("异常操作");
  49. }
  50. // $appid = 'wx7b4d857deb0447f3';
  51. // $secret = '643efbd7f3cd6398df1e7adb441afceb';
  52. $appid = 'wx9082e5ac2fdb513f';
  53. $secret = 'e334c41e1c4aa962f65d1882092fbda6';
  54. $url = "https://api.weixin.qq.com/sns/jscode2session?appid=".$appid."&secret=".$secret."&js_code=".$data['code']."&grant_type=authorization_code";
  55. $get = curlGet($url);
  56. if(!$get){
  57. return app('json')->fail($url);
  58. }
  59. $get['cache_key'] = md5(time() . $data['code']);
  60. try {
  61. Cache::set('mp_code_' . $get['cache_key'], $get['session_key'], 86400);
  62. }catch (\Exception $exception) {
  63. Log::error($exception->getMessage());
  64. }
  65. return app('json')->success($get);
  66. }
  67. /**
  68. * 小程序一键登录(合并 getUserUnionid + applet_phone)
  69. * 接收 code、encryptedData、iv,内部调用微信接口获取 session_key,解密手机号后注册/登录
  70. * @param UserRepository $repository
  71. * @return \think\response\Json
  72. */
  73. public function mpLogin(UserRepository $repository)
  74. {
  75. try {
  76. $data = $this->request->params(['code', 'encryptedData', 'iv', 'share_id', 'source']);
  77. if (!$data['code'] || $data['code'] == '' || $data['code'] == 'undefined') {
  78. return app('json')->fail('code参数缺失');
  79. }
  80. if (!$data['encryptedData'] || $data['encryptedData'] == '') {
  81. return app('json')->fail('encryptedData参数缺失');
  82. }
  83. if (!$data['iv'] || $data['iv'] == '') {
  84. return app('json')->fail('iv参数缺失');
  85. }
  86. $appid = 'wx9082e5ac2fdb513f';
  87. $secret = 'e334c41e1c4aa962f65d1882092fbda6';
  88. // 1. 调用微信 jscode2session 接口获取 session_key
  89. $url = "https://api.weixin.qq.com/sns/jscode2session?appid=" . $appid . "&secret=" . $secret . "&js_code=" . $data['code'] . "&grant_type=authorization_code";
  90. $wxResult = curlGet($url);
  91. if (!$wxResult || !isset($wxResult['session_key'])) {
  92. Log::error('mpLogin jscode2session失败: ' . json_encode($wxResult));
  93. return app('json')->fail('微信登录凭证校验失败');
  94. }
  95. $sessionKey = $wxResult['session_key'];
  96. // 2. 解密手机号
  97. $sessionKey = str_replace(' ', '+', $sessionKey);
  98. $encryptedData = str_replace(' ', '+', $data['encryptedData']);
  99. $iv = str_replace(' ', '+', $data['iv']);
  100. $pc = new WXBizDataCrypt($appid, $sessionKey);
  101. $errCode = $pc->decryptData($encryptedData, $iv, $decryptData);
  102. if ($errCode != 0) {
  103. return app('json')->fail('手机号解密失败');
  104. }
  105. Db::name('log')->insert(['data' => 'mpLogin一键登录获取的数据:' . $decryptData]);
  106. $decryptData = json_decode($decryptData, true);
  107. $phone = $decryptData['purePhoneNumber'] ?? '';
  108. if ($phone == '') {
  109. return app('json')->fail('未获取到手机号');
  110. }
  111. if (!preg_match("/^1[3456789]{1}\d{9}$/", $phone) && !preg_match("/^[569]\d{7}$/", $phone)) {
  112. return app('json')->fail('手机号格式错误');
  113. }
  114. // 3. 注册或登录
  115. $userRes = Db::name('user')->where('account', $phone)->find();
  116. $isnew = false;
  117. if (!$userRes) {
  118. $spreadUid = 0;
  119. if (!empty($data['share_id'])) {
  120. $spreadUid = Db::name('product_share')->where('id', $data['share_id'])->value('uid');
  121. if (!intval($spreadUid)) {
  122. $spreadUid = 0;
  123. }
  124. }
  125. $repository->registr($phone, 123456, 'APP', '', '', '', $spreadUid);
  126. $isnew = true;
  127. }
  128. $user = $repository->accountByUser($phone);
  129. // 企业用户关联逻辑(与 Auth::applet_phone 保持一致)
  130. if ($this->source == 'yhc' && $this->merId) {
  131. $where = ['mer_id' => $this->merId, 'uid' => $user['uid']];
  132. $count = Db::name('enterprise_user')->where($where)->count();
  133. if ($count < 1) {
  134. $insert = ['mer_id' => $this->merId, 'uid' => $user['uid']];
  135. $epData = $this->request->params(['spread', 'share_id']);
  136. if (isset($epData['spread']) && $epData['spread']) {
  137. $insert['puid'] = $epData['spread'];
  138. $insert['node_uid'] = $epData['spread'];
  139. } else if (isset($epData['share_id']) && $epData['share_id']) {
  140. $spreadUid = Db::name('product_share')->where('id', $epData['share_id'])->value('uid');
  141. $insert['puid'] = $spreadUid;
  142. $insert['node_uid'] = $spreadUid;
  143. }
  144. if (!isset($insert['node_uid']) || !$insert['node_uid']) {
  145. return app('json')->fail('必须要有邀请人才能注册', ['is' => 1]);
  146. }
  147. if (isset($epData['spread']) && isset($zhuce)) {
  148. $insert['puid'] = $epData['spread'];
  149. $insert['node_uid'] = $epData['spread'];
  150. }
  151. Db::name('enterprise_user')->insert($insert);
  152. }
  153. }
  154. $user = $repository->mainUser($user);
  155. $tokenInfo = $repository->createToken($user);
  156. $repository->loginAfter($user);
  157. return app('json')->success(array_merge($repository->returnToken($user, $tokenInfo), ['is_new' => $isnew ? 1 : 0]));
  158. } catch (\Exception $e) {
  159. Db::name('log')->insert(['data' => 'mpLogin出错:' . $e->getFile() . ':' . $e->getLine() . '【' . $e->getMessage() . '】']);
  160. return app('json')->fail('登录失败');
  161. }
  162. }
  163. public function getPhoneToBind(){
  164. $data = $this->request->params([
  165. 'cache_key',
  166. 'iv',
  167. 'encryptedData',
  168. 'third_user_id',
  169. 'source'
  170. ]);
  171. $session_key = Cache::get('mp_code_' . $data['cache_key']);
  172. $appid = $this -> appid;
  173. $secret = $this -> secret;
  174. if($data['source'] && $data['source'] == 'cxb'){
  175. $appid = env('WECHAT_MP.APPID');
  176. $secret = env('WECHAT_MP.SECRET');
  177. }
  178. //解密获取用户信息urldecode
  179. $returnCode = $this -> decryptData($session_key,$data['encryptedData'],$data['iv'],$userInfo,$appid);
  180. if($returnCode != 0){
  181. return app('json')->fail($returnCode);
  182. }
  183. $userInfo = json_decode($userInfo,true);
  184. if (!$userInfo || !isset($userInfo['purePhoneNumber'])) return app('json')->fail('手机号码获取失败');
  185. $phone = $userInfo['purePhoneNumber'];
  186. $repository = app()->make(UserRepository::class);
  187. $user = $repository->thirdBinding($phone, false,'MP',$data['third_user_id'],1,"http://". $this->request->host(true));//2222
  188. if($user){
  189. $userRepository = app()->make(UserRepository::class);
  190. $userInfo1 = $userRepository->getOne(['uid' => $user['uid']]);
  191. //绑定线下充值金额
  192. $unionUsersRepository = app()->make(UnionUsersRepository::class);
  193. $orderMerchantRepository = app()->make(OrderMerchantRepository::class);
  194. $notBind = $unionUsersRepository->getAllNotBind($data['third_user_id']);
  195. if ($notBind) {
  196. $orderMerchantRepository->doBindUser($userInfo1, 1);
  197. $userAccount = Db::name("UserAccount");
  198. $userAccount -> insert(['type'=>1,'uid'=>$user['uid'],'nickname'=>$notBind['nickname'],'avater'=>$notBind['avatar']]);
  199. }
  200. $user = $repository->accountByUser($userInfo['purePhoneNumber']);
  201. $tokenInfo = $repository->createToken($user);
  202. $repository->loginAfter($user);
  203. return app('json')->success($repository->returnToken($user, $tokenInfo));
  204. }else{
  205. return app('json')->fail("绑定失败");
  206. }
  207. }
  208. public function getUser(){
  209. $data = $this->request->params(['unionid','nickname','avatar']);
  210. if(!$data['unionid'] || $data['unionid'] == '' || $data['unionid'] =='undefined'){
  211. return app('json')->fail("异常操作");
  212. }
  213. $repository = app()->make(UserRepository::class);
  214. $result = $repository ->wechatCheck($data['unionid']);
  215. if(isset($result['code']) && $result['code'] == 200){
  216. //用户已注册并绑定了手机号码
  217. $user = $repository->accountByUser($result['user']['account']);
  218. $tokenInfo = $repository->createToken($user);
  219. $repository->loginAfter($user);
  220. return app('json')->success($repository->returnToken($user, $tokenInfo));
  221. }
  222. else{
  223. try {
  224. if($data['avatar'] && $data['avatar'] != ''){
  225. $data['avatar'] = str_replace('"', '', $data['avatar']);
  226. }
  227. Db::transaction(function () use ($data,$repository) {
  228. $unionData = [
  229. 'unionid' => $data['unionid'],
  230. 'nickname' => $data['nickname'] ? : time(),
  231. 'avatar' => $data['avatar'] ? : 'https://cdn.bjtdba.com/vod/image/2025-01-21/20250121180855764.png',
  232. 'is_lock' => 1,
  233. 'lock_time' => date('Y-m-d H:i:s'),
  234. 'balance' => 0,
  235. 'give_money' => 0,
  236. 'pension' => 0,
  237. 'type' => 1,
  238. ];
  239. $unionUsersDao = app()->make(UnionUsersDao::class);
  240. $unionUsersRepository = app()->make(UnionUsersRepository::class);
  241. $unionUser = $unionUsersRepository->getWhere(['unionid' => $data['unionid']]);
  242. if (!$unionUser) {
  243. $unionUsersDao->create($unionData);
  244. } else {
  245. $updateData = [
  246. 'nickname' => $data['nickname'] ? : time(),
  247. 'avatar' => $data['avatar'] ? : 'https://cdn.bjtdba.com/vod/image/2025-01-21/20250121180855764.png',
  248. 'update_time' => date('Y-m-d H:i:s')
  249. ];
  250. $unionUsersDao->update($unionUser->id, $updateData);
  251. }
  252. });
  253. } catch (\Throwable $e) {
  254. Log::info($e->getMessage());
  255. }
  256. }
  257. return app("json")->fail($result['msg']);
  258. }
  259. /**
  260. * 检验数据的真实性,并且获取解密后的明文.
  261. * @param $sessionKey string sessionKey
  262. * @param $encryptedData string 加密的用户数据
  263. * @param $iv string 与用户数据一同返回的初始向量
  264. * @param $data string 解密后的原文
  265. *
  266. * @return int 成功0,失败返回对应的错误码
  267. */
  268. public function decryptData($sessionKey,$encryptedData, $iv, &$data, $appid)
  269. {
  270. if (strlen($sessionKey) != 24) {
  271. return -41001;
  272. }
  273. $aesKey=base64_decode($sessionKey);
  274. if (strlen($iv) != 24) {
  275. return -41002;
  276. }
  277. $aesIV=base64_decode($iv);
  278. $aesCipher=base64_decode($encryptedData);
  279. $result=openssl_decrypt( $aesCipher, "AES-128-CBC", $aesKey, 1, $aesIV);
  280. $dataObj=json_decode( $result );
  281. if( $dataObj == NULL )
  282. {
  283. return -41003;
  284. }
  285. if( $dataObj->watermark->appid != $appid )
  286. {
  287. return -41003;
  288. }
  289. $data = $result;
  290. return 0;
  291. }
  292. }