Wechat.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. <?php namespace App\Http\Controllers\Api;
  2. use App\Facades\Servers\Logs\Log;
  3. use App\Http\Controllers\Api\Api;
  4. use App\Models\City;
  5. use App\Models\Custom;
  6. use App\Facades\Servers\WechatMini\Mini;
  7. use App\Models\RecruitmentActive;
  8. use App\Models\RecruitmentActivePrize;
  9. use App\Models\RecruitmentPrizeRecord;
  10. use App\Models\RecruitmentRecord;
  11. use App\Models\Score\Record;
  12. use App\Models\WeiBan\Tags;
  13. use App\Models\CustomScore;
  14. use Vinkla\Hashids\Facades\Hashids;
  15. /**
  16. * 微信接口
  17. *
  18. * @author 刘相欣
  19. *
  20. * */
  21. class Wechat extends Api{
  22. /**
  23. * 小程序手机号授权 /api/wechat/phone_number
  24. *
  25. * @param string $code 授权码
  26. *
  27. * */
  28. public function phone_number(Custom $Custom,Hashids $Hashids){
  29. // 接口验签
  30. // $this->verify_sign();
  31. // 接收参数
  32. $code = request('code','');
  33. $shareUid = request('share_uid','');
  34. // 授权结果
  35. $result = Mini::getUserPhone($code);
  36. // 如果所需字段不存在
  37. if( isset($result['error']) ) return json_send(['code'=>'error','msg'=>'授权失败','data'=>['error'=>$result['error']]]);
  38. // 如果所需字段不存在
  39. if( empty($result['purePhoneNumber']) ) return json_send(['code'=>'error','msg'=>'未获取到手机号','data'=>['error'=>'未获取到手机号']]);
  40. // 获取不包含区号的手机号(因为绑定手机号字段会有国际区号)
  41. $phone = $result['purePhoneNumber'];
  42. // 查询用户
  43. $custom = $Custom->getOneByPhone($phone);
  44. // 如果用户状态被拉黑,不允许登录
  45. if( !empty($custom['status']) ) return json_send(['code'=>'error','msg'=>'禁用账号','data'=>['error'=>'禁用账号']]);
  46. // 如果没有ID
  47. if( empty($custom['uid']) ) {
  48. // 注册账号
  49. $custom['uid'] = $Custom->add(['phone'=>$phone,'username'=>hide_phone($phone)]);
  50. // 注册失败
  51. if( empty($custom['uid']) ) return json_send(['code'=>'error','msg'=>'注册失败,请重试','data'=>['error'=>'注册失败,请重试']]);
  52. //绑定裂变邀请关系
  53. if($shareUid){
  54. $shareUid = $Hashids::decodeHex($shareUid);
  55. Log::error('recruitment','拉新活动:'.$shareUid);
  56. $this->addRecruitment($custom['uid'],$shareUid);
  57. }
  58. }
  59. // 进行登录
  60. $token = $Custom->createLoginAuthcode($custom['uid'],time());
  61. // 返回结果
  62. return json_send(['code'=>'success','msg'=>'登录成功','data'=>$token]);
  63. }
  64. /**
  65. * 拉新注册赠送奖励
  66. *
  67. * */
  68. public function addRecruitment($uid,$shareUid){
  69. $Custom = new Custom();
  70. $WeiBanTags = new Tags();
  71. $RecruitmentActive = new RecruitmentActive();
  72. // 获取客户城市ID
  73. $custom = $Custom->getOne($shareUid);
  74. //查询拉新活动
  75. if( !$custom['city_id'] ){
  76. Log::error('recruitment','拉新活动,缺少城市:'.json_encode($custom));
  77. return false;
  78. }
  79. // 获取城市ID
  80. $cityId = $custom['city_id'];
  81. // 查询用户标签
  82. $tags = $WeiBanTags->getListByWeibanExtid($custom['weiban_extid']);
  83. $time = time();
  84. $select = [
  85. ['start_time','<=',$time],
  86. ['end_time','>',$time],
  87. ['status','=',0],
  88. ];
  89. try {
  90. $activeList = $RecruitmentActive::query()->whereRaw("find_in_set('$cityId', city_ids)")->where($select)->get();
  91. $activeInfo = [];
  92. $data = [];
  93. if ($activeList) {
  94. foreach ($activeList as $active) {
  95. $allowJoin = 0;
  96. if ($active['tag_scope']) {
  97. // 解析数组
  98. $tag_scope = explode(',', $active['tag_scope']);
  99. // 标签范围限定时,默认不能参与
  100. // 判断标签是不是存在
  101. if ($tags) {
  102. foreach ($tags as $v) {
  103. // 标签范围内,允许参加
  104. if (in_array($v['name'], $tag_scope)) $allowJoin = 1;
  105. }
  106. }
  107. }else{
  108. $allowJoin = 1;
  109. }
  110. if ($active['tag_except']) {
  111. // 解析数组
  112. $tag_except = explode(',', $active['tag_except']);
  113. // 标签范围限定时,默认不能参与
  114. $allowJoin = 0;
  115. // 判断标签是不是存在
  116. if ($tags) {
  117. foreach ($tags as $v) {
  118. // 标签范围内,允许参加
  119. if (in_array($v['name'], $tag_except)) $allowJoin = 0;
  120. }
  121. }
  122. }
  123. if ($allowJoin) {
  124. $activeInfo = $active;
  125. break;
  126. }
  127. }
  128. }else{
  129. Log::error('recruitment','custom_uid:'.$uid.';暂无拉新活动:');
  130. }
  131. if (!empty($activeInfo)){
  132. $data['active_id'] = $activeInfo['id'];
  133. $data['old_uid'] = $shareUid;
  134. $data['new_uid'] = $uid;
  135. $data['insert_time'] = $time;
  136. $data['update_time'] = $time;
  137. //拉新记录
  138. $recordId = RecruitmentRecord::query()->insertGetId($data);
  139. if ($recordId){
  140. Log::info('recruitment','custom_uid:'.$uid.';拉新活动赠送奖励:'.json_encode($activeInfo));
  141. //查询活动奖励配置
  142. $prizeInfo = RecruitmentActivePrize::query()->where('active_id','=',$activeInfo['id'])->first();
  143. if (!$prizeInfo) {
  144. Log::info('recruitment','custom_uid:'.$uid.';拉新活动赠送奖励失败,无奖励配置:'.json_encode($prizeInfo));
  145. return false;
  146. }
  147. //赠送拉新奖励
  148. if ($prizeInfo['old_prize']){
  149. switch ($prizeInfo['old_prize_type']) {
  150. case 1:
  151. //赠送老用户积分
  152. $res = $this->sendScore($shareUid,$prizeInfo['old_prize'],$recordId,1);
  153. if (!$res) Log::error('recruitment','custom_uid:'.$uid.';拉新活动赠送老用户奖励失败:'.json_encode($prizeInfo));
  154. break;
  155. case 2:
  156. //赠送老用户优惠卷
  157. $res = $this->sendCoupon($shareUid,$prizeInfo['old_prize'],$recordId,1);
  158. if (!$res) Log::error('recruitment','custom_uid:'.$uid.';拉新活动赠送老用户奖励失败:'.json_encode($prizeInfo));
  159. break;
  160. }
  161. }
  162. //赠送新用户奖励
  163. if ($prizeInfo['new_prize']){
  164. switch ($prizeInfo['new_prize_type']) {
  165. case 1:
  166. //赠送老用户积分
  167. $res = $this->sendScore($uid,$prizeInfo['new_prize'],$recordId,2);
  168. if (!$res) Log::error('recruitment','custom_uid:'.$uid.';拉新活动赠送新用户奖励失败:'.json_encode($prizeInfo));
  169. break;
  170. case 2:
  171. //赠送老用户优惠卷
  172. $res = $this->sendCoupon($uid,$prizeInfo['new_prize'],$recordId,2);
  173. if (!$res) Log::error('recruitment','custom_uid:'.$uid.';拉新活动赠送新用户奖励失败:'.json_encode($prizeInfo));
  174. break;
  175. }
  176. }
  177. //赠送上级奖励
  178. if ($prizeInfo['higher_prize']){
  179. //查询上级用户
  180. $higherInfo = RecruitmentRecord::query()->where('new_uid','=',$shareUid)->first();
  181. if (!$higherInfo) return true;
  182. switch ($prizeInfo['higher_prize_type']) {
  183. case 1:
  184. //赠送上级积分
  185. $res = $this->sendScore($higherInfo['old_uid'],$prizeInfo['higher_prize'],$recordId,3);
  186. if (!$res) Log::error('recruitment','custom_uid:'.$higherInfo['old_uid'].';拉新活动赠送上级奖励失败:'.json_encode($prizeInfo));
  187. break;
  188. case 2:
  189. //赠送上级优惠卷
  190. $res = $this->sendCoupon($higherInfo['old_uid'],$prizeInfo['higher_prize'],$recordId,3);
  191. if (!$res) Log::error('recruitment','custom_uid:'.$higherInfo['old_uid'].';拉新活动赠送上级奖励失败:'.json_encode($prizeInfo));
  192. break;
  193. }
  194. }
  195. }else{
  196. Log::error('recruitment','custom_uid:'.$uid.';拉新活动新增拉新记录失败:'.json_encode($data));
  197. }
  198. }else{
  199. Log::error('recruitment','custom_uid:'.$uid.';无拉新活动:'.json_encode($activeInfo));
  200. }
  201. }catch (\Exception $e){
  202. Log::error('recruitment','custom_uid:'.$uid.';拉新活动:'.json_encode($e));
  203. return false;
  204. }
  205. return true;
  206. }
  207. public function sendScore($uid,$prize,$recordId,$type=1){
  208. $time = time();
  209. $prize = (int)$prize;
  210. $scoreInfo = CustomScore::query()->where('custom_uid','=',$uid)->first();
  211. if ($scoreInfo){
  212. $res = CustomScore::query()->where('custom_uid','=',$uid)->update(['score'=>$scoreInfo['score']+$prize,'update_time'=>$time]);
  213. }else{
  214. $res = CustomScore::query()->where('custom_uid','=',$uid)->insert(['custom_uid'=>$uid,'score'=>$prize,'update_time'=>$time,'insert_time'=>$time]);
  215. }
  216. if (!$res){
  217. Log::error('recruitment','custom_uid:'.$uid.';拉新活动赠送老用户奖励失败:'.json_encode($prize));
  218. return false;
  219. }
  220. $balance = CustomScore::query()->where('custom_uid','=',$uid)->first('score');
  221. $recordInfo = [
  222. 'score' => $prize,
  223. 'balance' => $balance,
  224. 'buy_type' => 9,
  225. 'pay_type' => 1,
  226. 'description' => '拉新奖励',
  227. 'status' => '1',
  228. 'pay_time' => $time,
  229. 'insert_time' => $time,
  230. 'update_time' => $time,
  231. 'custom_uid' => $uid,
  232. ];
  233. //用户积分记录
  234. $res = Record::query()->insertGetId($recordInfo);
  235. if (!$res){
  236. Log::error('recruitment','积分记录失败;record:'.json_encode($recordInfo));
  237. return false;
  238. }
  239. //拉新奖励记录
  240. $prizeRecordInfo = [
  241. 'recruitment_record_id' => $recordId,
  242. 'custom_uid' => $uid,
  243. 'type' => $type,
  244. 'prize_type' => 1,
  245. 'prize' => $prize,
  246. 'insert_time' => $time,
  247. 'update_time' => $time,
  248. ];
  249. $res = RecruitmentPrizeRecord::query()->insertGetId($prizeRecordInfo);
  250. if (!$res){
  251. Log::error('recruitment','奖励记录失败;record:'.json_encode($prizeRecordInfo));
  252. return false;
  253. }
  254. return true;
  255. }
  256. public function sendCoupon($uid,$prize,$recordId,$type=1){
  257. Log::error('recruitment','custom_uid:'.$uid.';拉新活动赠送优惠卷:'.json_encode($prize));
  258. $time = time();
  259. $Coupon = new \App\Models\Coupon();
  260. $CustomCoupon = new \App\Models\CustomCoupon();
  261. try {
  262. // 获取优惠券的可用时间
  263. $couponData = $Coupon->query()->where([['id','=',$prize],['status','=','0']])->first(['issue_total','status','exp_time']);
  264. // 如果不存在数据,发送失败
  265. if( !$couponData || $couponData['status'] ){
  266. Log::error('recruitment','custom_uid:'.$uid.';优惠卷奖励不存在:'.json_encode($prize));
  267. return false;
  268. }
  269. // 查询总共发放数量
  270. $total = $this->query()->where([['coupon_id','=',$prize]])->count();
  271. // 数量超过的话。不发
  272. if( $total >= $couponData['issue_total'] ) {
  273. Log::error('recruitment','custom_uid:'.$uid.';优惠卷奖励超发:'.json_encode($prize));
  274. return false;
  275. }
  276. // 时间转时间
  277. $expTime = $Coupon->getExpTime($couponData['exp_time']);
  278. // 发送优惠券
  279. $res = $CustomCoupon->add(['coupon_id'=>$prize,'custom_uid'=>$uid,'exp_time'=>$expTime]);
  280. if (!$res){
  281. Log::error('recruitment','custom_uid:'.$uid.';拉新活动赠送优惠卷奖励失败:'.json_encode($prize));
  282. return false;
  283. }
  284. //拉新奖励记录
  285. $prizeRecordInfo = [
  286. 'recruitment_record_id' => $recordId,
  287. 'custom_uid' => $uid,
  288. 'type' => $type,
  289. 'prize_type' => 2,
  290. 'prize' => $prize,
  291. 'insert_time' => $time,
  292. 'update_time' => $time,
  293. ];
  294. $res = RecruitmentPrizeRecord::query()->insertGetId($prizeRecordInfo);
  295. if (!$res){
  296. Log::error('recruitment','奖励记录失败;record:'.json_encode($prizeRecordInfo));
  297. return false;
  298. }
  299. }catch (\Exception $e){
  300. Log::error('recruitment','奖励优惠卷失败;record:'.json_encode($e));
  301. return false;
  302. }
  303. return true;
  304. }
  305. }