Recruitment.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. <?php namespace App\Http\Controllers\Api\Lottery;
  2. use App\Http\Controllers\Api\Api;
  3. use App\Models\Lottery\Recruitment as Model;
  4. use App\Models\Custom;
  5. use App\Models\CustomCoupon;
  6. use App\Models\CustomScore;
  7. use App\Models\CustomAmount;
  8. use App\Models\Lottery\RecruitmentRecord;
  9. use App\Models\Lottery\RecruitmentReward as RecruitmentReward;
  10. use Illuminate\Support\Facades\DB;
  11. use App\Models\WeiBan\Tags as WeiBanTags;
  12. /**
  13. * 积分抽奖
  14. *
  15. * @author 刘相欣
  16. *
  17. * */
  18. class Recruitment extends Api{
  19. /**
  20. * 获取抽奖配置 /api/lottery_recruitment/get_detail
  21. *
  22. *
  23. * */
  24. public function get_detail(Model $Model,Custom $Custom,RecruitmentReward $RecruitmentReward,RecruitmentRecord $RecruitmentRecord,WeiBanTags $WeiBanTags){
  25. // 接口验签
  26. // $this->verify_sign();
  27. // 检查登录
  28. $uid = $this->checkLogin();
  29. // 接收参数
  30. $id = request('id',0);
  31. // 获取活动
  32. $data = $Model->getOne($id);
  33. // 如果存在的话
  34. if( !$data ) return json_send(['code'=>'error','msg'=>'暂无活动','data'=>$data]);
  35. // 获取客户信息
  36. $custom = $Custom->getOne($uid);
  37. // 如果存在的话
  38. if( !$custom ) return json_send(['code'=>'no_login','msg'=>'请登录','data'=>['error'=>'无对应客户']]);
  39. // 如果客户注册时间不在活动期间
  40. if( $data['start_time'] > $custom['insert_time'] || $data['end_time'] < $custom['insert_time'] ) return json_send(['code'=>'error','msg'=>'账号不在活动范围','data'=>['error'=>'不在活动时间内注册']]);
  41. // 如果城市限制并且不在在城市范围内,不允许参加
  42. if ( $data['city_ids'] && !in_array($custom['city_id'],explode(',',$data['city_ids'])) ) return json_send(['code'=>'error','msg'=>'账号不在城市范围,请核对您的城市','data'=>['error'=>'不在标签范围内']]);
  43. // 是否需要获取用户标签
  44. $tags = $data['tag_scope'] || $data['tag_except'] ? $WeiBanTags->getTags($uid) : [];
  45. // 获取用户的标签
  46. $tags = $tags ? array_column($tags,'name') : [];
  47. // 判断是不是可以参与
  48. if( $data['tag_scope'] ) {
  49. // 解析数组
  50. $data['tag_scope'] = explode(',',$data['tag_scope']);
  51. // 计算交集
  52. $intersect = count(array_intersect($data['tag_scope'],$tags));
  53. // 判断标签是否必须同时满足
  54. if( $data['tag_scope_type'] == 1 ) {
  55. // 判断用户的标签是否全部满足于标签限制范围内
  56. if( $intersect != count($data['tag_scope']) ) return json_send(['code'=>'error','msg'=>'账号不在标签范围','data'=>['error'=>'不在标签范围内']]);
  57. }else{
  58. // 判断标签限制并且不在标签限制范围内,不允许参加
  59. if( !$intersect ) return json_send(['code'=>'error','msg'=>'账号不在标签范围','data'=>['error'=>'不在标签范围内']]);
  60. }
  61. }
  62. // 判断是不是可以参与
  63. if( $data['tag_except'] ) {
  64. // 解析数组
  65. $data['tag_except'] = explode(',',$data['tag_except']);
  66. // 计算交集
  67. $intersect = count(array_intersect($data['tag_except'],$tags));
  68. // 如果存在交集,在排除范围,即不可参与
  69. if( $intersect ) return json_send(['code'=>'error','msg'=>'账号不在范围','data'=>['error'=>'在标签排除范围内']]);
  70. }
  71. // 奖品
  72. $reward = $RecruitmentReward->getListByLottery($data['id']);
  73. // 活动暂无奖品
  74. if( !$reward ) return json_send(['code'=>'error','msg'=>'活动暂未配置奖品','data'=>$data]);
  75. // 查询条件
  76. $map = [];
  77. // 判断周期
  78. if( !empty($data['freq']) ) {
  79. if( $data['freq'] == 1 ) $map = [['insert_time','>=',now()->startOfDay()->getTimestamp()],['insert_time','<=',now()->endOfDay()->getTimestamp()]];
  80. if( $data['freq'] == 2 ) $map = [['insert_time','>=',now()->startOfWeek()->getTimestamp()],['insert_time','<=',now()->endOfWeek()->getTimestamp()]];
  81. if( $data['freq'] == 3 ) $map = [['insert_time','>=',now()->startOfMonth()->getTimestamp()],['insert_time','<=',now()->endOfMonth()->getTimestamp()]];
  82. }
  83. // logo
  84. $data['logo'] = $data['logo'] ? path_compat($data['logo']) : '';
  85. // 查询用户已参与次数
  86. $data['join_num'] = (int)$RecruitmentRecord->query()->where([['custom_uid','=',$uid],['lottery_id','=',$id]])->where($map)->count();
  87. // 计算剩余次数
  88. $data['number'] = $data['lucky_num'] - $data['join_num'];
  89. // 最少为0,避免显示异常
  90. $data['number'] = $data['number'] < 0 ? 0 : $data['number'];
  91. // 时间处理
  92. $data['start_date'] = date('Y/m/d H:i',$data['start_time']);
  93. // 时间处理
  94. $data['end_date'] = date('Y/m/d H:i',$data['end_time']);
  95. // 通过活动ID,查询奖品
  96. $data['reward_list'] = [];
  97. // 奖品数据
  98. foreach ($reward as $value) {
  99. // 奖项
  100. $data['reward_list'][] = ['id'=>$value['id'],'name'=>$value['reward_name'],'img'=>$value['reward_thumb'],'reward_type'=>$value['reward_type']];
  101. }
  102. // 默认可以参加活动
  103. $data['allow_join'] = 1;
  104. // 返回结果
  105. return json_send(['code'=>'success','msg'=>'获取成功','data'=>$data]);
  106. }
  107. /**
  108. * 抽奖 /api/lottery_recruitment/get_reward
  109. *
  110. * */
  111. public function get_reward(Model $Model,Custom $Custom,RecruitmentRecord $RecruitmentRecord,RecruitmentReward $RecruitmentReward,CustomCoupon $CustomCoupon,CustomScore $CustomScore,CustomAmount $CustomAmount,WeiBanTags $WeiBanTags){
  112. // 接口验签
  113. // $this->verify_sign();
  114. // 检查登录
  115. $uid = $this->checkLogin();
  116. // 获取活动
  117. $lotteryId = request('lottery_id',0);
  118. // 如果存在的话
  119. if( !$lotteryId ) return json_send(['code'=>'error','msg'=>'请选择参与的活动','data'=>['error'=>"抽奖活动ID有误"]]);
  120. // 获取客户信息
  121. $custom = $Custom->getOne($uid);
  122. // 如果存在的话
  123. if( !$custom ) return json_send(['code'=>'no_login','msg'=>'请登录','data'=>['error'=>'无对应客户']]);
  124. // 通过活动ID,查询奖品
  125. $data = $Model->getOne($lotteryId);
  126. // 如果存在的话
  127. if( !$data ) return json_send(['code'=>'error','msg'=>'活动不存在或未开始','data'=>$data]);
  128. // 活动时间判断
  129. if( $data['start_time'] > time() ) return json_send(['code'=>'error','msg'=>'活动暂未开始','data'=>$data]);
  130. // 活动时间判断
  131. if( $data['end_time'] < time() ) return json_send(['code'=>'error','msg'=>'活动已结束','data'=>$data]);
  132. // 如果客户注册时间不在活动期间
  133. if( $data['start_time'] > $custom['insert_time'] || $data['end_time'] < $custom['insert_time'] ) return json_send(['code'=>'error','msg'=>'账号不在活动范围','data'=>['error'=>'不在活动时间内注册']]);
  134. // 如果城市限制并且不在在城市范围内,不允许参加
  135. if ( $data['city_ids'] && !in_array($custom['city_id'],explode(',',$data['city_ids'])) ) return json_send(['code'=>'error','msg'=>'账号不在城市范围,请核对您的城市','data'=>['error'=>'不在标签范围内']]);
  136. // 判断是不是可以参与
  137. if( $data['tag_scope'] ) {
  138. // 解析数组
  139. $data['tag_scope'] = explode(',',$data['tag_scope']);
  140. // 查询用户标签
  141. $tags = $WeiBanTags->getListByWeibanExtid($custom['weiban_extid']);
  142. // 获取用户的标签
  143. $tags = array_column($tags,'name');
  144. $intersect = count(array_intersect($data['tag_scope'],$tags));
  145. // 判断标签是否必须同时满足
  146. if( $data['tag_scope_type'] == 1 ) {
  147. // 判断用户的标签是否全部满足于标签限制范围内
  148. if( $intersect != count($data['tag_scope']) ) return json_send(['code'=>'error','msg'=>'账号不在标签范围','data'=>['error'=>'不在标签范围内']]);
  149. }else{
  150. // 判断标签限制并且不在标签限制范围内,不允许参加
  151. if( !$intersect ) return json_send(['code'=>'error','msg'=>'账号不在标签范围','data'=>['error'=>'不在标签范围内']]);
  152. }
  153. }
  154. // 判断是不是可以参与
  155. if( $data['tag_except'] ) {
  156. // 解析数组
  157. $data['tag_except'] = explode(',',$data['tag_except']);
  158. // 计算交集
  159. $intersect = count(array_intersect($data['tag_except'],$tags));
  160. // 如果存在交集,在排除范围,即不可参与
  161. if( $intersect ) return json_send(['code'=>'error','msg'=>'账号在不可参与范围','data'=>['error'=>'账号在标签排除范围内']]);
  162. }
  163. // 奖品
  164. $reward = $RecruitmentReward->getListByLottery($data['id']);
  165. // 活动暂无奖品
  166. if( !$reward ) return json_send(['code'=>'error','msg'=>'活动暂未配置奖品','data'=>$data]);
  167. // 查询条件
  168. $map = [['insert_time','>=',$data['start_time']],['insert_time','<=',$data['end_time']]];
  169. // 判断周期
  170. if( !empty($data['freq']) ) {
  171. if( $data['freq'] == 1 ) $map = [['insert_time','>=',now()->startOfDay()->getTimestamp()],['insert_time','<=',now()->endOfDay()->getTimestamp()]];
  172. if( $data['freq'] == 2 ) $map = [['insert_time','>=',now()->startOfWeek()->getTimestamp()],['insert_time','<=',now()->endOfWeek()->getTimestamp()]];
  173. if( $data['freq'] == 3 ) $map = [['insert_time','>=',now()->startOfMonth()->getTimestamp()],['insert_time','<=',now()->endOfMonth()->getTimestamp()]];
  174. }
  175. // 查询用户已参与次数
  176. $data['join_num'] = (int)$RecruitmentRecord->query()->where([['custom_uid','=',$uid],['lottery_id','=',$lotteryId]])->where($map)->count();
  177. // 计算剩余次数
  178. $data['join_num'] = $data['lucky_num'] - $data['join_num'];
  179. // 如果次数不够
  180. if( $data['join_num'] <= 0 ) return json_send(['code'=>'error','msg'=>'抽奖次数已用完','data'=>['error'=>'抽奖次数已用完']]);
  181. // 抽奖记录
  182. $record = ['custom_uid'=>$uid,'lottery_id'=>$lotteryId,'reward_id'=>0,'reward_name'=>'谢谢参与','status'=>8];
  183. // 开启事务
  184. DB::beginTransaction();
  185. try{
  186. // 限制中奖则获取中奖次数
  187. $rewarTotal = $data['max_reward'] ? $RecruitmentRecord->query()->where([['lottery_id','=',$data['id']],['custom_uid','=',$uid],['reward_id','>',0]])->where($map)->count() : 0;
  188. // 中奖上限以后不再中奖
  189. $rewardIndex = ($data['max_reward'] && $rewarTotal >= $data['max_reward']) ? 0 : $RecruitmentReward->getRewardResult($reward);
  190. // 如果中奖,下标不是0
  191. if( $rewardIndex ) {
  192. // 获取奖品
  193. $rewardResult = $reward[$rewardIndex];
  194. // 奖品记录ID
  195. if( !empty($rewardResult['id']) ){
  196. // 如果是积分
  197. if( $rewardResult['reward_type'] == 1 ){
  198. // 积分大于0
  199. if( $rewardResult['reward_info'] > 0 ){
  200. // 积分发放
  201. $result = $CustomScore->trade($uid,$lotteryId,$rewardResult['reward_info'],7,5);
  202. // 发放失败,改为未中奖
  203. if( isset($result['error']) ) $rewardIndex = 0;
  204. // 发放成功,状态为已完成
  205. $record['status']= 8;
  206. }
  207. }
  208. // 优惠券,先进行发放
  209. if( $rewardResult['reward_type'] == 2 ){
  210. // 优惠券存在ID
  211. if( $rewardResult['reward_info'] > 0 ){
  212. // 积分给与
  213. $result = $CustomCoupon->giveCoupon($rewardResult['reward_info'],$uid);
  214. // 发放失败,改为未中奖
  215. if( !$result ) $rewardIndex = 0;
  216. // 发放成功,状态为已完成
  217. $record['status']= 8;
  218. }
  219. }
  220. // 红包
  221. if( $rewardResult['reward_type'] == 3 ){
  222. // 积分大于0
  223. if( $rewardResult['reward_info'] > 0 ){
  224. // 积分发放
  225. $result = $CustomAmount->trade($uid,$lotteryId,$rewardResult['reward_info'],7,1,'拉新抽奖');
  226. // 发放失败,改为未中奖
  227. if( isset($result['error']) ) $rewardIndex = 0;
  228. // 发放成功,状态为已完成
  229. $record['status']= 8;
  230. }
  231. }
  232. // 如果是虚拟物品
  233. if( $rewardResult['reward_type'] == 4 ) $record['status'] = 1;
  234. // 如果是实物,要求填写地址,状态设置为0
  235. if( $rewardResult['reward_type'] == 5 ) $record['status'] = 0;
  236. // 如果是其他
  237. if( $rewardResult['reward_type'] == 6 ) $record['status'] = 1;
  238. }
  239. }
  240. // 中奖记录奖品
  241. if( $rewardIndex ) {
  242. // 记录,默认状态为1,进行中
  243. $record['reward_id'] = $reward[$rewardIndex]['id'];
  244. $record['reward_name'] = $reward[$rewardIndex]['reward_name'];
  245. // 扣减次数
  246. $RecruitmentReward->edit($rewardResult['id'],['reward_total'=>DB::raw('reward_total+-1')]);
  247. }
  248. // 写入记录
  249. $result = $RecruitmentRecord->add($record);
  250. // 写入失败
  251. if( !$result ) {
  252. // 回退数据
  253. DB::rollBack();
  254. // 提示
  255. return json_send(['code'=>'error','msg'=>'抽奖记录失败,请重试']);
  256. }
  257. // 提交事务
  258. DB::commit();
  259. // 通过活动ID,查询奖品
  260. $rewardList = [];
  261. // 奖品数据
  262. foreach ($reward as $value) {
  263. $rewardList[] = ['id'=>$value['id'],'name'=>$value['reward_name'],'img'=>$value['reward_thumb'],'reward_type'=>$value['reward_type']];
  264. }
  265. // 默认可以参加活动
  266. $data['allow_join'] = 1;
  267. // 返回结果
  268. return json_send(['code'=>'success','msg'=>'抽奖成功','data'=>['reward_list'=>$rewardList,'reward_index'=>$rewardIndex,'join_num'=>$data['join_num']-1]]);
  269. // 异常处理
  270. } catch (\Throwable $th) {
  271. // 回退数据
  272. DB::rollBack();
  273. // 下单失败提示
  274. return json_send(['code'=>'error','msg'=>'抽奖失败,请重试','data'=>['error'=>$th->getMessage().$th->getLine()]]);
  275. }
  276. }
  277. }