Riddle.php 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. <?php namespace App\Http\Controllers\Api\Lottery;
  2. use App\Http\Controllers\Api\Api;
  3. use App\Models\Lottery\Riddle as Model;
  4. use App\Models\Lottery\RiddleUsable;
  5. use App\Models\Custom;
  6. use App\Models\CustomCoupon;
  7. use App\Models\CustomScore;
  8. use App\Models\CustomAmount;
  9. use App\Models\Lottery\RiddleRecord;
  10. use App\Models\Lottery\RiddleReward as RiddleReward;
  11. use Illuminate\Support\Facades\DB;
  12. /**
  13. * 积分抽奖
  14. *
  15. * @author 刘相欣
  16. *
  17. * */
  18. class Riddle extends Api{
  19. /**
  20. * 获取抽奖配置 /api/lottery_riddle/get_detail
  21. *
  22. *
  23. * */
  24. public function get_detail(Model $Model,Custom $Custom,RiddleReward $RiddleReward,RiddleUsable $RiddleUsable){
  25. // 接口验签
  26. // $this->verify_sign();
  27. // 检查登录
  28. $uid = $this->checkLogin();
  29. // 获取客户信息
  30. $custom = $Custom->getOne($uid);
  31. // 如果存在的话
  32. if( !$custom ) return json_send(['code'=>'no_login','msg'=>'请登录','data'=>['error'=>'无对应客户']]);
  33. // 接收参数
  34. $id = request('id',0);
  35. // 获取活动
  36. $data = $Model->getOne($id);
  37. // 如果存在的话
  38. if( !$data ) return json_send(['code'=>'error','msg'=>'暂无活动','data'=>$data]);
  39. // 奖品
  40. $reward = $RiddleReward->getListByLottery($data['id']);
  41. // 活动暂无奖品
  42. if( !$reward ) return json_send(['code'=>'error','msg'=>'活动暂未配置奖品','data'=>$data]);
  43. // logo
  44. $data['logo'] = $data['logo'] ? path_compat($data['logo']) : '';
  45. // 通过活动ID,查询奖品
  46. $data['reward_list'] = [];
  47. // 奖品数据
  48. foreach ($reward as $value) {
  49. // 奖项
  50. $data['reward_list'][] = ['id'=>$value['id'],'name'=>$value['reward_name'],'img'=>$value['reward_thumb'],'reward_type'=>$value['reward_type']];
  51. }
  52. // 查询用户可用抽奖次数
  53. $number = $RiddleUsable->query()->where([['custom_uid','=',$uid],['lottery_id','=',$id]])->value('number');
  54. // 最少为0,避免显示异常
  55. $data['number'] = $number < 0 ? 0 : $number;
  56. // 时间处理
  57. $data['start_date'] = date('Y/m/d H:i',$data['start_time']);
  58. // 时间处理
  59. $data['end_date'] = date('Y/m/d H:i',$data['end_time']);
  60. // 返回结果
  61. return json_send(['code'=>'success','msg'=>'获取成功','data'=>$data]);
  62. }
  63. /**
  64. * 抽奖 /api/lottery_riddle/get_reward
  65. *
  66. * */
  67. public function get_reward(Model $Model,Custom $Custom,RiddleRecord $RiddleRecord,RiddleReward $RiddleReward,CustomCoupon $CustomCoupon,OrderRecord $OrderRecord,CustomScore $CustomScore,RiddleUsable $RiddleUsable,CustomAmount $CustomAmount){
  68. // 接口验签
  69. // $this->verify_sign();
  70. // 检查登录
  71. $uid = $this->checkLogin();
  72. // 获取活动
  73. $lotteryId = request('lottery_id',0);
  74. // 如果存在的话
  75. if( !$lotteryId ) return json_send(['code'=>'error','msg'=>'请选择参与的活动','data'=>['error'=>"抽奖活动ID有误"]]);
  76. // 获取客户信息
  77. $custom = $Custom->getOne($uid);
  78. // 如果存在的话
  79. if( !$custom ) return json_send(['code'=>'no_login','msg'=>'请登录','data'=>['error'=>'无对应客户']]);
  80. // 通过活动ID,查询奖品
  81. $data = $Model->getOne($lotteryId);
  82. // 如果存在的话
  83. if( !$data ) return json_send(['code'=>'error','msg'=>'活动不存在或未开始','data'=>$data]);
  84. // 活动时间判断
  85. if( $data['start_time'] > time() ) return json_send(['code'=>'error','msg'=>'活动暂未开始','data'=>$data]);
  86. // 活动时间判断
  87. if( $data['end_time'] < time() ) return json_send(['code'=>'error','msg'=>'活动已结束','data'=>$data]);
  88. // 奖品
  89. $reward = $RiddleReward->getListByLottery($lotteryId);
  90. // 活动暂无奖品
  91. if( !$reward ) return json_send(['code'=>'error','msg'=>'活动暂未配置奖品','data'=>$data]);
  92. // 查询用户可用抽奖次数
  93. $usable = $RiddleUsable->query()->where([['custom_uid','=',$uid],['lottery_id','=',$lotteryId]])->first();
  94. if (!$usable) return json_send(['code'=>'error','msg'=>'抽奖次数已用完','data'=>['error'=>'抽奖次数已用完']]);
  95. // 最少为0,避免显示异常
  96. $data['join_num'] = $usable['number'] < 0 ? 0 : $usable['number'];
  97. // 如果次数不够
  98. if( $data['join_num'] <= 0 ) return json_send(['code'=>'error','msg'=>'抽奖次数已用完','data'=>['error'=>'抽奖次数已用完']]);
  99. // 查询条件
  100. $map = [['insert_time','>=',$data['start_time']],['insert_time','<=',$data['end_time']]];
  101. // 判断周期
  102. if( !empty($data['freq']) ) {
  103. if( $data['freq'] == 1 ) $map = [['insert_time','>=',now()->startOfDay()->getTimestamp()],['insert_time','<=',now()->endOfDay()->getTimestamp()]];
  104. if( $data['freq'] == 2 ) $map = [['insert_time','>=',now()->startOfWeek()->getTimestamp()],['insert_time','<=',now()->endOfWeek()->getTimestamp()]];
  105. if( $data['freq'] == 3 ) $map = [['insert_time','>=',now()->startOfMonth()->getTimestamp()],['insert_time','<=',now()->endOfMonth()->getTimestamp()]];
  106. }
  107. // 限制中奖则获取中奖次数
  108. $rewarTotal = $data['max_reward'] ? $RiddleRecord->query()->where([['lottery_id','=',$data['id']],['custom_uid','=',$uid],['reward_id','>',0]])->where($map)->count() : 0;
  109. // 中奖上限以后不再中奖, 默认获取未中奖
  110. $rewardResult = ($data['max_reward'] && $rewarTotal >= $data['max_reward']) ? ['reward_list'=>$reward,'index'=>0] : $RiddleReward->getRewardResult($lotteryId);
  111. // 未抽中
  112. if( !$rewardResult ) return json_send(['code'=>'error','msg'=>'谢谢参与','data'=>['error'=>'谢谢参与']]);
  113. // 奖品索引
  114. $rewardIndex = $rewardResult['index'];
  115. // 奖品列表
  116. $reward = $rewardResult['reward_list'];
  117. // 获取奖品信息
  118. $rewardResult = $reward[$rewardIndex];
  119. // 是否记录结果
  120. $record = ['custom_uid'=>$uid,'lottery_id'=>$lotteryId,'reward_id'=>$rewardResult['id'],'reward_name'=>$rewardResult['reward_name'],'status'=>(in_array($rewardResult['reward_type'],[4,5,6]) ? 1 : 8)];
  121. // 实物状态需要填写地址
  122. if( $rewardResult['reward_type'] == 5 ) $record['status'] = 0;
  123. // 组合数据,写入订单表,子表
  124. DB::beginTransaction();
  125. try{
  126. // 扣减次数
  127. $result = $RiddleUsable->query()->where(['lottery_id'=>$data['id'],'custom_uid'=>$uid])->update(['number'=>$usable['number']-1,'use_number'=>$usable['use_number']+1]);
  128. // 如果积分扣减失败
  129. if( !$result ) {
  130. // 回退数据
  131. DB::rollBack();
  132. return json_send(['code'=>'error','msg'=>'抽奖次数扣减失败','data'=>['error'=>'抽奖次数扣减失败']]);
  133. }
  134. // 如果存在奖品
  135. if( $rewardResult['id'] ) {
  136. // 奖品数量减少
  137. $result = $RiddleReward->edit($rewardResult['id'],['reward_total'=>DB::raw('reward_total+-1'),'lottery_id'=>$rewardResult['lottery_id']]);
  138. // 如果奖品数量减少失败
  139. if( !$result ) {
  140. // 回退数据
  141. DB::rollBack();
  142. // 提醒重试
  143. return json_send(['code'=>'error','msg'=>'抽奖失败,请重试','data'=>['error'=>'奖品数量扣减失败']]);
  144. }
  145. }
  146. // 如果是积分
  147. if( $rewardResult['reward_type'] == 1 ){
  148. // 积分大于0
  149. if( $rewardResult['reward_info'] > 0 ){
  150. // 积分发放
  151. $result = $CustomScore->trade($uid,$lotteryId,$rewardResult['reward_info'],7,3);
  152. // 发放失败,改为未中奖
  153. if( isset($result['error']) ) {
  154. // 回退数据
  155. DB::rollBack();
  156. // 通知重试
  157. return json_send(['code'=>'error','msg'=>'出了点小差,请重新抽奖','data'=>$result]);
  158. }
  159. }
  160. }
  161. // 优惠券,先进行发放
  162. if( $rewardResult['reward_type'] == 2 ){
  163. // 优惠券存在ID
  164. if( $rewardResult['reward_info'] > 0 ){
  165. // 积分给与
  166. $result = $CustomCoupon->giveCoupon($rewardResult['reward_info'],$uid);
  167. // 发放失败,改为未中奖
  168. if( isset($result['error']) ) {
  169. // 回退数据
  170. DB::rollBack();
  171. // 通知重试
  172. return json_send(['code'=>'error','msg'=>'出了点小差,请重新抽奖','data'=>$result]);
  173. }
  174. }
  175. }
  176. // 红包
  177. if( $rewardResult['reward_type'] == 3 ){
  178. // 积分大于0
  179. if( $rewardResult['reward_info'] > 0 ){
  180. // 积分发放
  181. $result = $CustomAmount->trade($uid,$lotteryId,$rewardResult['reward_info'],6,1,'下单抽奖');
  182. // 发放失败,改为未中奖
  183. if( isset($result['error']) ) {
  184. // 回退数据
  185. DB::rollBack();
  186. // 通知重试
  187. return json_send(['code'=>'error','msg'=>'出了点小差,请重新抽奖','data'=>$result]);
  188. }
  189. }
  190. }
  191. // 扣减数量
  192. $result = $RiddleRecord->add($record);
  193. // 记录失败
  194. if( !$result ) {
  195. // 回退数据
  196. DB::rollBack();
  197. // 下单失败提示
  198. return json_send(['code'=>'error','msg'=>'抽奖失败,请重试','data'=>['error'=>'奖品记录失败']]);
  199. }
  200. // 提交事务
  201. DB::commit();
  202. // 通过活动ID,查询奖品
  203. $rewardList = [];
  204. // 奖品数据
  205. foreach ($reward as $value) {
  206. $rewardList[] = ['id'=>$value['id'],'name'=>$value['reward_name'],'img'=>$value['reward_thumb'],'reward_type'=>$value['reward_type']];
  207. }
  208. // 返回结果
  209. return json_send(['code'=>'success','msg'=>'抽奖成功','data'=>['reward_list'=>$rewardList,'reward_index'=>$rewardIndex,'join_num'=>$data['join_num']-1]]);
  210. // 异常处理
  211. } catch (\Throwable $th) {
  212. // 回退数据
  213. DB::rollBack();
  214. // 下单失败提示
  215. return json_send(['code'=>'error','msg'=>'抽奖失败,请重试','data'=>['error'=>$th->getMessage().$th->getLine()]]);
  216. }
  217. }
  218. }