HomeController.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636
  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 {get} /api/home/getbasedata 获取可选批次及省份
  159. * @apiDescription 获取可选批次及省份
  160. * @apiGroup 高考助手
  161. * @apiPermission none
  162. * @apiVersion 0.1.0
  163. * @apiSuccessExample {json} Success-Response:
  164. * HTTP/1.1 200 OK
  165. * {
  166. * "status": true,
  167. * "status_code": 0,
  168. * "message": "",
  169. * "data": {
  170. * "batchs": [
  171. *
  172. * ],
  173. * "provinces":[
  174. *
  175. * ]
  176. *
  177. * }
  178. * }
  179. * @apiErrorExample {json} Error-Response:
  180. * HTTP/1.1 400 Bad Request
  181. * {
  182. * "state": false,
  183. * "code": 1000,
  184. * "message": "传入参数不正确",
  185. * "data": null or []
  186. * }
  187. * 可能出现的错误代码:
  188. * 1000 CLIENT_WRONG_PARAMS 传入参数不正确
  189. */
  190. public function getBaseData()
  191. {
  192. $batchs = MajorInfoModel::groupBy('batch')->pluck('batch');
  193. $provinces = [
  194. "全部省份", "安徽", "澳门", "北京", "重庆", "福建", "甘肃", "广东", "广西", "贵州", "海南", "河北", "河南", "黑龙江", "湖北", "湖南", "吉林", "江苏", "江西", "辽宁", "内蒙古", "宁夏", "青海", "山东", "山西", "陕西", "上海", "四川", "台湾", "天津", "西藏", "香港", "新疆", "云南", "浙江"
  195. ];
  196. return $this->api(compact('batchs', 'provinces'));
  197. }
  198. /**
  199. * @api {post} /api/home/getphonenumber 获取手机号
  200. * @apiDescription 获取手机号
  201. * @apiGroup 高考助手
  202. * @apiPermission none
  203. * @apiVersion 0.1.0
  204. * @apiParam {string} [code] code(必填)
  205. * @apiParam {string} [iv] iv(必填)
  206. * @apiParam {string} [encryptData] encryptData(必填)
  207. * @apiSuccessExample {json} Success-Response:
  208. * HTTP/1.1 200 OK
  209. * {
  210. * "status": true,
  211. * "status_code": 0,
  212. * "message": "",
  213. * "data": {
  214. * "decryptedData": [
  215. *
  216. * ]
  217. *
  218. * }
  219. * }
  220. * @apiErrorExample {json} Error-Response:
  221. * HTTP/1.1 400 Bad Request
  222. * {
  223. * "state": false,
  224. * "code": 1000,
  225. * "message": "传入参数不正确",
  226. * "data": null or []
  227. * }
  228. * 可能出现的错误代码:
  229. * 1000 CLIENT_WRONG_PARAMS 传入参数不正确
  230. */
  231. public function getPhoneNumber(Request $request){
  232. $code = $request->get('code');
  233. $iv = $request->get('iv');
  234. $encryptData = $request->get('encryptData');
  235. $session = $this->app->auth->session($code);
  236. $decryptedData = $this->app->encryptor->decryptData($session, $iv, $encryptData);
  237. return $this->api(compact('decryptedData'));
  238. }
  239. /**
  240. * @api {post} /api/home/getqueried 查询免费信息
  241. * @apiDescription 查询免费信息
  242. * @apiGroup 高考助手
  243. * @apiPermission none
  244. * @apiVersion 0.1.0
  245. * @apiParam {int} [userid] 用户ID(必填)
  246. * @apiParam {string} [username] 考生姓名(必填)
  247. * @apiParam {string} [cnumber] 考号(必填)
  248. * @apiParam {string} [class] 科类(必填)
  249. * @apiParam {int} [grade] 高考成绩(必填)
  250. * @apiParam {int} [mobile] 手机号(必填)
  251. * @apiParam {string} [batch] 批次(必填)
  252. * @apiParam {string} [province] 省份(必填)
  253. * @apiParam {string} [code] 推荐码(选填)
  254. * @apiSuccessExample {json} Success-Response:
  255. * HTTP/1.1 200 OK
  256. * {
  257. * "status": true,
  258. * "status_code": 0,
  259. * "message": "",
  260. * "data": {
  261. * "rank": ""
  262. * "grade": ""
  263. * "college_count": ""
  264. *
  265. * }
  266. * }
  267. * @apiErrorExample {json} Error-Response:
  268. * HTTP/1.1 400 Bad Request
  269. * {
  270. * "state": false,
  271. * "code": 1000,
  272. * "message": "传入参数不正确",
  273. * "data": null or []
  274. * }
  275. * 可能出现的错误代码:
  276. * 1000 CLIENT_WRONG_PARAMS 传入参数不正确
  277. */
  278. public function getQueried(Request $request)
  279. {
  280. $validator = Validator::make($request->all(),
  281. [
  282. 'cnumber' => 'required',
  283. 'username' => 'required',
  284. 'grade' => 'required|integer',
  285. 'mobile' => 'required'
  286. ],
  287. [
  288. 'cnumber.required' => '考号不能为空!',
  289. 'username.required' => '姓名不能为空!',
  290. 'username.required' => '姓名不能为空!',
  291. 'mobile.required' => '手机号不能为空!',
  292. 'grade.required' => '成绩不能为空!',
  293. 'grade.integer' => '请输入正确格式的成绩!',
  294. ]
  295. );
  296. if ($validator->fails()) {
  297. return $this->error(ErrorCode::CLIENT_WRONG_PARAMS, '传入参数不正确!', $validator->messages());
  298. }
  299. /*更新用户的信息*/
  300. $this->updateUserinfo();
  301. $year = date('Y');
  302. $grade = $request->get('grade');
  303. $batch = $request->get('batch');
  304. $class = $request->get('class');
  305. $province = $request->get('province');
  306. $maxgrade = StudentCountModel::where('year', $year)->orderBy('grade', 'desc')->first()->grade;
  307. if ($grade > $maxgrade) {
  308. $rank = "前10";
  309. } else {
  310. $rank = StudentCountModel::where('year', $year)->where('grade', $grade)->first(['total'])->total;
  311. }
  312. if ($province == "全部省份") {
  313. $college = MajorInfoModel::where('year', $year)->where('batch', $batch)->where('class', $class)->where('min_grade', "<=", $grade)->groupBy('college')->get();
  314. } else {
  315. $college = MajorInfoModel::where('year', $year)->where('batch', $batch)->where('class', $class)->where('province', 'like', '%' . $province . '%')->where('min_grade', "<=", $grade)->groupBy('college')->get();
  316. }
  317. $college_count = count($college);
  318. /*创建查询记录*/
  319. $user = UserInfoModel::find(request('userid'));
  320. $this->createQueryInfo($user);
  321. return $this->api(compact('rank', 'grade', 'province', 'college_count', 'batch'));
  322. }
  323. /**
  324. * @api {post} /api/home/getpaidmajors 查询付费信息
  325. * @apiDescription 查询付费信息
  326. * @apiGroup 高考助手
  327. * @apiPermission none
  328. * @apiVersion 0.1.0
  329. * @apiParam {int} [userid] 用户ID(必填)
  330. * @apiParam {string} [username] 考生姓名(必填)
  331. * @apiParam {string} [batch] 批次(必填)
  332. * @apiParam {string} [province] 省份(必填)
  333. * @apiParam {string} [class] 科类(必填)
  334. * @apiSuccessExample {json} Success-Response:
  335. * HTTP/1.1 200 OK 已付费查看过,显示匹配信息
  336. * {
  337. * "status": true,
  338. * "status_code": 0,
  339. * "message": "",
  340. * "data": {
  341. * "count": ""
  342. * "major":[
  343. * ]
  344. *
  345. * }
  346. * }
  347. *
  348. *HTTP/1.1 200 OK 未曾付费,跳转到支付页面
  349. * {
  350. * "status": true,
  351. * "status_code": 0,
  352. * "message": "",
  353. * "data": {
  354. * "msg": "need to pay",
  355. * "price": ""
  356. * }
  357. * }
  358. * @apiErrorExample {json} Error-Response:
  359. * HTTP/1.1 400 Bad Request
  360. * {
  361. * "state": false,
  362. * "code": 1000,
  363. * "message": "传入参数不正确",
  364. * "data": null or []
  365. * }
  366. * 可能出现的错误代码:
  367. * 1000 CLIENT_WRONG_PARAMS 传入参数不正确
  368. */
  369. public function getPaidMajors(Request $request)
  370. {
  371. $validator = Validator::make($request->all(),
  372. [
  373. 'userid' => 'required',
  374. 'batch' => 'required',
  375. 'province' => 'required',
  376. 'class' => 'required'
  377. ],
  378. [
  379. 'userid.required' => 'userid不能为空!',
  380. 'batch.required' => 'batch不能为空!',
  381. 'province.required' => 'province不能为空!',
  382. 'class.required' => 'class不能为空!',
  383. ]
  384. );
  385. if ($validator->fails()) {
  386. return $this->error(ErrorCode::CLIENT_WRONG_PARAMS, '传入参数不正确!', $validator->messages());
  387. }
  388. if ($this->checkPaid()) {
  389. $year = date('Y');
  390. $batch = $request->get('batch');
  391. $province = $request->get('province');
  392. $class = request('class');
  393. $userid = request('userid');
  394. $_user = UserInfoModel::find($userid);
  395. $grade = $_user->grade;
  396. if ($province == "全部省份") {
  397. $major = MajorInfoModel::where('year', $year)->where('batch', $batch)->where('class', $class)->where('min_grade', "<=", $grade)->get();
  398. } else {
  399. $major = MajorInfoModel::where('year', $year)->where('batch', $batch)->where('class', $class)->where('province', 'like', '%' . $province . '%')->where('min_grade', "<=", $grade)->get();
  400. }
  401. $count = count($major);
  402. $this->createQueryInfo($_user, 1);
  403. return $this->api(compact('count', 'major'));
  404. } else {
  405. $price = PaidSettingModel::first();
  406. $msg = 'need to pay';
  407. $price = $price->price;
  408. return $this->api(compact('msg', 'price'));
  409. }
  410. }
  411. /**
  412. * @api {post} /api/home/pay 获取微信支付签名信息
  413. * @apiDescription 获取微信支付签名信息
  414. * @apiGroup 高考助手
  415. * @apiPermission none
  416. * @apiVersion 0.1.0
  417. * @apiParam {int} [userid] 用户ID(必填)
  418. * @apiParam {string} [price] 付费金额(必填)
  419. * @apiSuccessExample {json} Success-Response:
  420. * HTTP/1.1 200 OK
  421. * {
  422. * "status": true,
  423. * "status_code": 0,
  424. * "message": "",
  425. * "data": {
  426. * "appId":"wx1c2357232cd25f65",
  427. * "timeStamp":"1524907589",
  428. * "nonceStr":"5ae43e45eb499",
  429. * "package":"prepay_id=wx28172629917401724160128f0238805782",
  430. * "signType":"MD5",
  431. * "paySign":"8E9CF26B2B83C22471D023CBBDC36EDF"
  432. * }
  433. * }
  434. * @apiErrorExample {json} Error-Response:
  435. * HTTP/1.1 400 Bad Request
  436. * {
  437. * "state": false,
  438. * "code": 1000,
  439. * "message": "传入参数不正确",
  440. * "data": null or []
  441. * }
  442. * 可能出现的错误代码:
  443. * 1000 CLIENT_WRONG_PARAMS 传入参数不正确
  444. */
  445. public function pay(Request $request)
  446. {
  447. $validator = Validator::make($request->all(),
  448. [
  449. 'userid' => 'required',
  450. 'price' => 'required',
  451. ],
  452. [
  453. 'userid.required' => 'userid不能为空!',
  454. 'price.required' => 'price不能为空!',
  455. ]
  456. );
  457. if ($validator->fails()) {
  458. return $this->error(ErrorCode::CLIENT_WRONG_PARAMS, '传入参数不正确!', $validator->messages());
  459. }
  460. $money = $request->input('price');
  461. $user = UserInfoModel::find(request('userid'));
  462. $trade_no = date("YmdHis");
  463. \Log::info($this->options());
  464. $app = Factory::payment($this->options());
  465. $result = $app->order->unify([
  466. 'body' => '高考志愿助手 - 付费查询',
  467. 'out_trade_no' => $trade_no,
  468. 'total_fee' => $money * 100,
  469. 'trade_type' => 'JSAPI',
  470. 'notify_url' => url('/api/home/notify'),
  471. 'openid' => $user->openid
  472. ]);
  473. \Log::info($result);
  474. if ($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS') {
  475. $payment = Factory::payment($this->options());
  476. $jssdk = $payment->jssdk;
  477. $json = $jssdk->bridgeConfig($result['prepay_id']);
  478. \Log::info($json);
  479. return $this->api(compact('json'));
  480. }else{
  481. $msg = "签名失败,请稍后再试!";
  482. return $this->api(compact('msg'));
  483. }
  484. }
  485. //下面是回调函数
  486. public function notify()
  487. {
  488. $app = Factory::payment($this->options());
  489. \Log::info("wechat notify start!");
  490. return $app->handlePaidNotify(function ($notify, $successful) {
  491. \Log::info($notify);
  492. if ($notify['result_code'] == 'SUCCESS') {
  493. $user = UserInfoModel::where('openid',$notify['openid'])->first();
  494. $data['order_no'] = $notify['out_trade_no'];
  495. $data['price'] = $notify['total_fee'] / 100;
  496. $data['user_id'] = $user->id;
  497. $data['code'] = $user->code;
  498. $user->paid_end_time = Carbon::parse("+1 year")->toDateTimeString();
  499. $this->createQueryInfo($user,1);
  500. OrderInfoModel::create($data);
  501. $user->save();
  502. } else {
  503. return $successful('通信失败,请稍后再通知我');
  504. }
  505. $msg = "支付成功";
  506. return $this->api(compact('msg'));
  507. });
  508. }
  509. public function checkPaid()
  510. {
  511. $userid = request('userid');
  512. $_user = UserInfoModel::find($userid);
  513. $hasPaid = QueryInfoModel::where('user_id', $_user->id)->where('grade', $_user->grade)->where('is_paid', 1)->count();
  514. $not_expire = Carbon::now() < $_user->paid_end_time;
  515. if($hasPaid && $not_expire){
  516. return 1;
  517. }else{
  518. return 0;
  519. }
  520. }
  521. public function updateUserinfo()
  522. {
  523. $userid = request('userid');
  524. $data['username'] = request('username');
  525. $data['mobile'] = request('mobile');
  526. $data['grade'] = request('grade');
  527. $data['code'] = request('code');
  528. $res = UserInfoModel::where('id', $userid)->update($data);
  529. }
  530. public function createQueryInfo($userinfo, $ispaid = 0)
  531. {
  532. $data['is_paid'] = $ispaid;
  533. $data['user_id'] = $userinfo->id;
  534. $data['cnumber'] = $userinfo->cnumber;
  535. $data['grade'] = $userinfo->grade;
  536. $data['code'] = $userinfo->code;
  537. $data['mobile'] = $userinfo->mobile;
  538. QueryInfoModel::create($data);
  539. }
  540. public function options()
  541. {
  542. return [
  543. 'app_id' => "wxea7a26e5da5b46f2",
  544. 'mch_id' => "1398823402",
  545. 'key' => "c1891122765718911227657189112276",
  546. 'notify_url' => url('/api/home/pay'),
  547. 'sandbox' => false,
  548. ];
  549. }
  550. }