HomeController.php 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660
  1. <?php
  2. namespace App\Http\Controllers\Api\V1;
  3. use App\Models\IntroductionInfoModel;
  4. use App\Models\MajorInfoModel;
  5. use App\Models\OrderInfoModel;
  6. use App\Models\PaidSettingModel;
  7. use App\Models\QueryInfoModel;
  8. use App\Models\StudentCountModel;
  9. use App\Models\UserInfoModel;
  10. use Carbon\Carbon;
  11. use Illuminate\Http\Request;
  12. use App\Services\Base\ErrorCode;
  13. use Validator, Response;
  14. use EasyWeChat\Factory;
  15. class HomeController extends Controller
  16. {
  17. protected $app;
  18. public function __construct()
  19. {
  20. $config = [
  21. 'app_id' => 'wxea7a26e5da5b46f2',
  22. 'secret' => '769802a6f23aac585e355ce0e326aa03',
  23. // 指定 API 调用返回结果的类型:array(default)/collection/object/raw/自定义类名
  24. 'response_type' => 'array',
  25. ];
  26. $this->app = Factory::miniProgram($config);
  27. }
  28. /**
  29. * @api {post} /api/home/login 登陆(login)
  30. * @apiDescription 登陆(login)
  31. * @apiGroup 高考助手
  32. * @apiPermission none
  33. * @apiVersion 0.1.0
  34. * @apiParam {string} [code](必填)
  35. * @apiParam {string} [nickName]
  36. * @apiParam {string} [avatar]
  37. * @apiSuccessExample {json} Success-Response:
  38. * HTTP/1.1 200 OK
  39. * {
  40. * "status": true,
  41. * "status_code": 0,
  42. * "message": "",
  43. * "data": {
  44. * "userinfo": {
  45. * "id": "",
  46. * "nickname": "",
  47. * "openid": "",
  48. * "has_agreed": "" //1:已同意说明,进入主页面;0:为同意协议,进入协议说明页面
  49. * }
  50. *
  51. * }
  52. * }
  53. * @apiErrorExample {json} Error-Response:
  54. * HTTP/1.1 400 Bad Request
  55. * {
  56. * "state": false,
  57. * "code": 1000,
  58. * "message": "传入参数不正确",
  59. * "data": null or []
  60. * }
  61. * 可能出现的错误代码:
  62. * 1000 CLIENT_WRONG_PARAMS 传入参数不正确
  63. */
  64. public function login(Request $request)
  65. {
  66. $code = $request->get('code');
  67. $session = $this->app->auth->session($code);
  68. $openid = $session['openid'];
  69. $userinfo = UserInfoModel::where('openid', $openid)->first(['id', 'nickname', 'openid', 'has_agreed']);
  70. if ($userinfo) {
  71. return $this->api(compact('userinfo'));
  72. } else {
  73. $data['openid'] = $openid;
  74. $data['nickname'] = $request->get('nickName');
  75. $data['avatar'] = $request->get('avatar');
  76. $data['has_agreed'] = 0;
  77. $userinfo = UserInfoModel::create($data);
  78. return $this->api(compact('userinfo'));
  79. }
  80. }
  81. /**
  82. * @api {get} /api/home/getintroduction 获取使用说用及协议
  83. * @apiDescription 获取使用说用及协议
  84. * @apiGroup 高考助手
  85. * @apiPermission none
  86. * @apiVersion 0.1.0
  87. * @apiSuccessExample {json} Success-Response:
  88. * HTTP/1.1 200 OK
  89. * {
  90. * "status": true,
  91. * "status_code": 0,
  92. * "message": "",
  93. * "data": {
  94. * "list": [
  95. *
  96. * ]
  97. *
  98. * }
  99. * }
  100. * @apiErrorExample {json} Error-Response:
  101. * HTTP/1.1 400 Bad Request
  102. * {
  103. * "state": false,
  104. * "code": 1000,
  105. * "message": "传入参数不正确",
  106. * "data": null or []
  107. * }
  108. * 可能出现的错误代码:
  109. * 1000 CLIENT_WRONG_PARAMS 传入参数不正确
  110. */
  111. public function getIntroduction()
  112. {
  113. $list = IntroductionInfoModel::get(['title', 'content', 'type']);
  114. return $this->api(compact('list'));
  115. }
  116. /**
  117. * @api {post} /api/home/agreeintroduction 同意使用说用及协议
  118. * @apiDescription 同意使用说用及协议
  119. * @apiGroup 高考助手
  120. * @apiPermission none
  121. * @apiVersion 0.1.0
  122. * @apiParam {int} [userid] 用户ID(必填)
  123. * @apiSuccessExample {json} Success-Response:
  124. * HTTP/1.1 200 OK
  125. * {
  126. * "status": true,
  127. * "status_code": 0,
  128. * "message": "",
  129. * "data": {
  130. * "userinfo": [
  131. *
  132. * ]
  133. *
  134. * }
  135. * }
  136. * @apiErrorExample {json} Error-Response:
  137. * HTTP/1.1 400 Bad Request
  138. * {
  139. * "state": false,
  140. * "code": 1000,
  141. * "message": "传入参数不正确",
  142. * "data": null or []
  143. * }
  144. * 可能出现的错误代码:
  145. * 1000 CLIENT_WRONG_PARAMS 传入参数不正确
  146. */
  147. public function agreeIntroduction(Request $request)
  148. {
  149. $userid = $request->get('userid');
  150. $data['has_agreed'] = 1;
  151. $res = UserInfoModel::where('id', $userid)->update($data);
  152. if ($res) {
  153. $userinfo = UserInfoModel::where('id', $userid)->first(['id', 'nickname', 'openid', 'has_agreed']);
  154. }
  155. return $this->api(compact('userinfo'));
  156. }
  157. /**
  158. * @api {post} /api/home/getbasedata 获取可基础数据
  159. * @apiDescription 获取基础数据
  160. * @apiGroup 高考助手
  161. * @apiPermission none
  162. * @apiVersion 0.1.0
  163. * @apiParam {int} [userid] 用户ID(必填)
  164. * @apiSuccessExample {json} Success-Response:
  165. * HTTP/1.1 200 OK
  166. * {
  167. * "status": true,
  168. * "status_code": 0,
  169. * "message": "",
  170. * "data": {
  171. * "userinfo":[
  172. *
  173. * ]
  174. * "batchs": [
  175. *
  176. * ],
  177. * "provinces":[
  178. *
  179. * ]
  180. *
  181. * }
  182. * }
  183. * @apiErrorExample {json} Error-Response:
  184. * HTTP/1.1 400 Bad Request
  185. * {
  186. * "state": false,
  187. * "code": 1000,
  188. * "message": "传入参数不正确",
  189. * "data": null or []
  190. * }
  191. * 可能出现的错误代码:
  192. * 1000 CLIENT_WRONG_PARAMS 传入参数不正确
  193. */
  194. public function getBaseData(Request $request)
  195. {
  196. $validator = Validator::make($request->all(),
  197. [
  198. 'userid' => 'required',
  199. ],
  200. [
  201. 'userid.required' => 'userid不能为空!',
  202. ]
  203. );
  204. if ($validator->fails()) {
  205. return $this->error(ErrorCode::CLIENT_WRONG_PARAMS, '传入参数不正确!', $validator->messages());
  206. }
  207. $batchs = MajorInfoModel::groupBy('batch')->pluck('batch');
  208. $provinces = [
  209. "全部省份", "安徽", "澳门", "北京", "重庆", "福建", "甘肃", "广东", "广西", "贵州", "海南", "河北", "河南", "黑龙江", "湖北", "湖南", "吉林", "江苏", "江西", "辽宁", "内蒙古", "宁夏", "青海", "山东", "山西", "陕西", "上海", "四川", "台湾", "天津", "西藏", "香港", "新疆", "云南", "浙江"
  210. ];
  211. $userinfo = UserInfoModel::select(['id','username','code','cnumber','class','grade','mobile'])->find(request('userid'));
  212. return $this->api(compact('userinfo','batchs', 'provinces'));
  213. }
  214. /**
  215. * @api {post} /api/home/getphonenumber 获取手机号
  216. * @apiDescription 获取手机号
  217. * @apiGroup 高考助手
  218. * @apiPermission none
  219. * @apiVersion 0.1.0
  220. * @apiParam {string} [code] code(必填)
  221. * @apiParam {string} [iv] iv(必填)
  222. * @apiParam {string} [encryptData] encryptData(必填)
  223. * @apiSuccessExample {json} Success-Response:
  224. * HTTP/1.1 200 OK
  225. * {
  226. * "status": true,
  227. * "status_code": 0,
  228. * "message": "",
  229. * "data": {
  230. * "decryptedData": [
  231. *
  232. * ]
  233. *
  234. * }
  235. *
  236. * }
  237. * @apiErrorExample {json} Error-Response:
  238. * HTTP/1.1 400 Bad Request
  239. * {
  240. * "state": false,
  241. * "code": 1000,
  242. * "message": "传入参数不正确",
  243. * "data": null or []
  244. * }
  245. * 可能出现的错误代码:
  246. * 1000 CLIENT_WRONG_PARAMS 传入参数不正确
  247. */
  248. public function getPhoneNumber(Request $request){
  249. $code = $request->get('code');
  250. $iv = $request->get('iv');
  251. $encryptData = $request->get('encryptData');
  252. $session = $this->app->auth->session($code);
  253. \Log::info($session);
  254. $decryptedData = $this->app->encryptor->decryptData($session['session_key'], $iv, $encryptData);
  255. return $this->api(compact('decryptedData'));
  256. }
  257. /**
  258. * @api {post} /api/home/getqueried 查询免费信息
  259. * @apiDescription 查询免费信息
  260. * @apiGroup 高考助手
  261. * @apiPermission none
  262. * @apiVersion 0.1.0
  263. * @apiParam {int} [userid] 用户ID(必填)
  264. * @apiParam {string} [username] 考生姓名(必填)
  265. * @apiParam {string} [cnumber] 考号(必填)
  266. * @apiParam {string} [class] 科类(必填)
  267. * @apiParam {int} [grade] 高考成绩(必填)
  268. * @apiParam {int} [mobile] 手机号(必填)
  269. * @apiParam {string} [batch] 批次(必填)
  270. * @apiParam {string} [province] 省份(必填)
  271. * @apiParam {string} [code] 推荐码(选填)
  272. * @apiSuccessExample {json} Success-Response:
  273. * HTTP/1.1 200 OK
  274. * {
  275. * "status": true,
  276. * "status_code": 0,
  277. * "message": "",
  278. * "data": {
  279. * "rank": ""
  280. * "grade": ""
  281. * "college_count": ""
  282. *
  283. * }
  284. * }
  285. * @apiErrorExample {json} Error-Response:
  286. * HTTP/1.1 400 Bad Request
  287. * {
  288. * "state": false,
  289. * "code": 1000,
  290. * "message": "传入参数不正确",
  291. * "data": null or []
  292. * }
  293. * 可能出现的错误代码:
  294. * 1000 CLIENT_WRONG_PARAMS 传入参数不正确
  295. */
  296. public function getQueried(Request $request)
  297. {
  298. $validator = Validator::make($request->all(),
  299. [
  300. 'cnumber' => 'required',
  301. 'username' => 'required',
  302. 'grade' => 'required|integer',
  303. 'mobile' => 'required'
  304. ],
  305. [
  306. 'cnumber.required' => '考号不能为空!',
  307. 'username.required' => '姓名不能为空!',
  308. 'username.required' => '姓名不能为空!',
  309. 'mobile.required' => '手机号不能为空!',
  310. 'grade.required' => '成绩不能为空!',
  311. 'grade.integer' => '请输入正确格式的成绩!',
  312. ]
  313. );
  314. if ($validator->fails()) {
  315. return $this->error(ErrorCode::CLIENT_WRONG_PARAMS, '传入参数不正确!', $validator->messages());
  316. }
  317. /*更新用户的信息*/
  318. $this->updateUserinfo();
  319. $year = date('Y');
  320. $grade = $request->get('grade');
  321. $batch = $request->get('batch');
  322. $class = $request->get('class');
  323. $province = $request->get('province');
  324. $maxgrade = StudentCountModel::where('year', $year)->orderBy('grade', 'desc')->first()->grade;
  325. if ($grade > $maxgrade) {
  326. $rank = "前10";
  327. } else {
  328. $rank = StudentCountModel::where('year', $year)->where('grade', $grade)->first(['total'])->total;
  329. }
  330. if ($province == "全部省份") {
  331. $college = MajorInfoModel::where('year', $year)->where('batch', $batch)->where('class', $class)->where('min_grade', "<=", $grade)->groupBy('college')->get();
  332. } else {
  333. $college = MajorInfoModel::where('year', $year)->where('batch', $batch)->where('class', $class)->where('province', 'like', '%' . $province . '%')->where('min_grade', "<=", $grade)->groupBy('college')->get();
  334. }
  335. $college_count = count($college);
  336. /*创建查询记录*/
  337. $user = UserInfoModel::find(request('userid'));
  338. $this->createQueryInfo($user);
  339. return $this->api(compact('rank', 'grade', 'province', 'college_count', 'batch'));
  340. }
  341. /**
  342. * @api {post} /api/home/getpaidmajors 查询付费信息
  343. * @apiDescription 查询付费信息
  344. * @apiGroup 高考助手
  345. * @apiPermission none
  346. * @apiVersion 0.1.0
  347. * @apiParam {int} [userid] 用户ID(必填)
  348. * @apiParam {string} [username] 考生姓名(必填)
  349. * @apiParam {string} [batch] 批次(必填)
  350. * @apiParam {string} [province] 省份(必填)
  351. * @apiParam {string} [class] 科类(必填)
  352. * @apiSuccessExample {json} Success-Response:
  353. * HTTP/1.1 200 OK 已付费查看过,显示匹配信息
  354. * {
  355. * "status": true,
  356. * "status_code": 0,
  357. * "message": "",
  358. * "data": {
  359. * "count": ""
  360. * "major":[
  361. * ]
  362. *
  363. * }
  364. * }
  365. *
  366. *HTTP/1.1 200 OK 未曾付费,跳转到支付页面
  367. * {
  368. * "status": true,
  369. * "status_code": 0,
  370. * "message": "",
  371. * "data": {
  372. * "msg": "need to pay",
  373. * "price": ""
  374. * }
  375. * }
  376. * @apiErrorExample {json} Error-Response:
  377. * HTTP/1.1 400 Bad Request
  378. * {
  379. * "state": false,
  380. * "code": 1000,
  381. * "message": "传入参数不正确",
  382. * "data": null or []
  383. * }
  384. * 可能出现的错误代码:
  385. * 1000 CLIENT_WRONG_PARAMS 传入参数不正确
  386. */
  387. public function getPaidMajors(Request $request)
  388. {
  389. $validator = Validator::make($request->all(),
  390. [
  391. 'userid' => 'required',
  392. 'batch' => 'required',
  393. 'province' => 'required',
  394. 'class' => 'required'
  395. ],
  396. [
  397. 'userid.required' => 'userid不能为空!',
  398. 'batch.required' => 'batch不能为空!',
  399. 'province.required' => 'province不能为空!',
  400. 'class.required' => 'class不能为空!',
  401. ]
  402. );
  403. if ($validator->fails()) {
  404. return $this->error(ErrorCode::CLIENT_WRONG_PARAMS, '传入参数不正确!', $validator->messages());
  405. }
  406. if ($this->checkPaid()) {
  407. $year = date('Y');
  408. $batch = $request->get('batch');
  409. $province = $request->get('province');
  410. $class = request('class');
  411. $userid = request('userid');
  412. $_user = UserInfoModel::find($userid);
  413. $grade = $_user->grade;
  414. if ($province == "全部省份") {
  415. $major = MajorInfoModel::where('year', $year)->where('batch', $batch)->where('class', $class)->where('min_grade', "<=", $grade)->get();
  416. } else {
  417. $major = MajorInfoModel::where('year', $year)->where('batch', $batch)->where('class', $class)->where('province', 'like', '%' . $province . '%')->where('min_grade', "<=", $grade)->get();
  418. }
  419. $count = count($major);
  420. $this->createQueryInfo($_user, 1);
  421. return $this->api(compact('count', 'major'));
  422. } else {
  423. $price = PaidSettingModel::first();
  424. $msg = 'need to pay';
  425. $price = $price->price;
  426. return $this->api(compact('msg', 'price'));
  427. }
  428. }
  429. /**
  430. * @api {post} /api/home/pay 获取微信支付签名信息
  431. * @apiDescription 获取微信支付签名信息
  432. * @apiGroup 高考助手
  433. * @apiPermission none
  434. * @apiVersion 0.1.0
  435. * @apiParam {int} [userid] 用户ID(必填)
  436. * @apiParam {string} [price] 付费金额(必填)
  437. * @apiSuccessExample {json} Success-Response:
  438. * HTTP/1.1 200 OK
  439. * {
  440. * "status": true,
  441. * "status_code": 0,
  442. * "message": "",
  443. * "data": {
  444. * "appId":"wx1c2357232cd25f65",
  445. * "timeStamp":"1524907589",
  446. * "nonceStr":"5ae43e45eb499",
  447. * "package":"prepay_id=wx28172629917401724160128f0238805782",
  448. * "signType":"MD5",
  449. * "paySign":"8E9CF26B2B83C22471D023CBBDC36EDF"
  450. * }
  451. * }
  452. * @apiErrorExample {json} Error-Response:
  453. * HTTP/1.1 400 Bad Request
  454. * {
  455. * "state": false,
  456. * "code": 1000,
  457. * "message": "传入参数不正确",
  458. * "data": null or []
  459. * }
  460. * 可能出现的错误代码:
  461. * 1000 CLIENT_WRONG_PARAMS 传入参数不正确
  462. */
  463. public function pay(Request $request)
  464. {
  465. $validator = Validator::make($request->all(),
  466. [
  467. 'userid' => 'required',
  468. 'price' => 'required',
  469. ],
  470. [
  471. 'userid.required' => 'userid不能为空!',
  472. 'price.required' => 'price不能为空!',
  473. ]
  474. );
  475. if ($validator->fails()) {
  476. return $this->error(ErrorCode::CLIENT_WRONG_PARAMS, '传入参数不正确!', $validator->messages());
  477. }
  478. $money = $request->input('price');
  479. $user = UserInfoModel::find(request('userid'));
  480. $trade_no = date("YmdHis");
  481. \Log::info($this->options());
  482. $app = Factory::payment($this->options());
  483. $result = $app->order->unify([
  484. 'body' => '高考志愿助手 - 付费查询',
  485. 'out_trade_no' => $trade_no,
  486. 'total_fee' => $money * 100,
  487. 'trade_type' => 'JSAPI',
  488. 'notify_url' => url('/api/home/notify'),
  489. 'openid' => $user->openid
  490. ]);
  491. \Log::info($result);
  492. if ($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS') {
  493. $payment = Factory::payment($this->options());
  494. $jssdk = $payment->jssdk;
  495. $json = $jssdk->bridgeConfig($result['prepay_id']);
  496. \Log::info($json);
  497. return $this->api(compact('json'));
  498. }else{
  499. $msg = "签名失败,请稍后再试!";
  500. return $this->api(compact('msg'));
  501. }
  502. }
  503. //下面是回调函数
  504. public function notify()
  505. {
  506. $app = Factory::payment($this->options());
  507. \Log::info("wechat notify start!");
  508. return $app->handlePaidNotify(function ($notify, $successful) {
  509. \Log::info($notify);
  510. if ($notify['result_code'] == 'SUCCESS') {
  511. $user = UserInfoModel::where('openid',$notify['openid'])->first();
  512. $data['order_no'] = $notify['out_trade_no'];
  513. $data['price'] = $notify['total_fee'] / 100;
  514. $data['user_id'] = $user->id;
  515. $data['code'] = $user->code;
  516. \Log::info($data);
  517. $user->paid_end_time = Carbon::parse("+1 year")->toDateTimeString();
  518. $this->createQueryInfo($user,1);
  519. OrderInfoModel::create($data);
  520. $user->save();
  521. } else {
  522. return $successful('通信失败,请稍后再通知我');
  523. }
  524. return true;
  525. });
  526. }
  527. public function checkPaid()
  528. {
  529. $userid = request('userid');
  530. $_user = UserInfoModel::find($userid);
  531. $hasPaid = QueryInfoModel::where('user_id', $_user->id)->where('grade', $_user->grade)->where('is_paid', 1)->count();
  532. $not_expire = Carbon::now() < $_user->paid_end_time;
  533. if($hasPaid && $not_expire){
  534. return 1;
  535. }else{
  536. return 0;
  537. }
  538. }
  539. public function updateUserinfo()
  540. {
  541. $userid = request('userid');
  542. $data['username'] = request('username');
  543. $data['cnumber'] = request('cnumber');
  544. $data['mobile'] = request('mobile');
  545. $data['grade'] = request('grade');
  546. $data['code'] = request('code');
  547. $data['class'] = request('class');
  548. $res = UserInfoModel::where('id', $userid)->update($data);
  549. }
  550. public function createQueryInfo($userinfo, $ispaid = 0)
  551. {
  552. $data['is_paid'] = $ispaid;
  553. $data['user_id'] = $userinfo->id;
  554. $data['cnumber'] = $userinfo->cnumber;
  555. $data['grade'] = $userinfo->grade;
  556. $data['code'] = $userinfo->code;
  557. $data['mobile'] = $userinfo->mobile;
  558. $data['class'] = $userinfo->class;
  559. \Log::info($data);
  560. QueryInfoModel::create($data);
  561. }
  562. public function options()
  563. {
  564. return [
  565. 'app_id' => "wxea7a26e5da5b46f2",
  566. 'mch_id' => "1398823402",
  567. 'key' => "c1891122765718911227657189112276",
  568. 'notify_url' => url('/api/home/pay'),
  569. 'sandbox' => false,
  570. ];
  571. }
  572. }