Lottery.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. <?php
  2. namespace app\api\controller;
  3. use app\common\controller\Api;
  4. use app\common\Service\LotteryService;
  5. use app\common\Service\LotteryChanceService;
  6. use app\common\model\lottery\LotteryActivity;
  7. use app\common\model\lottery\LotteryPrize;
  8. use app\common\model\lottery\LotteryDrawRecord;
  9. use app\common\model\lottery\LotteryWinRecord;
  10. use app\common\model\lottery\LotteryUserChance;
  11. use app\common\library\Auth;
  12. use think\Exception;
  13. /**
  14. * 抽奖API控制器
  15. */
  16. class Lottery extends Api
  17. {
  18. protected $noNeedLogin = ['activityList', 'activityDetail'];
  19. protected $noNeedRight = ['*'];
  20. /**
  21. * 获取抽奖活动列表
  22. */
  23. public function activityList()
  24. {
  25. $page = $this->request->param('page/d', 1);
  26. $limit = $this->request->param('limit/d', 10);
  27. $status = $this->request->param('status/d', 1); // 默认只返回进行中的活动
  28. $where = [];
  29. if ($status !== '') {
  30. $where['status'] = $status;
  31. }
  32. // 只返回进行中且在时间范围内的活动
  33. $now = time();
  34. $where['start_time'] = ['<=', $now];
  35. $where['end_time'] = ['>=', $now];
  36. $activities = LotteryActivity::where($where)
  37. ->field('id,name,description,cover_image,type,status,start_time,end_time,lottery_type,guide_image,guide_text,intro_content')
  38. ->order('createtime desc')
  39. ->page($page, $limit)
  40. ->select();
  41. $list = [];
  42. foreach ($activities as $activity) {
  43. $item = $activity->toArray();
  44. // 获取奖品信息
  45. $prizes = LotteryPrize::where('activity_id', $activity->id)
  46. ->where('status', 1)
  47. ->where('type', '>', 1) // 排除未中奖类型
  48. ->field('id,name,type,image,probability')
  49. ->order('sort_order asc')
  50. ->select();
  51. $item['prizes'] = $prizes;
  52. // 统计信息
  53. $item['total_participants'] = LotteryUserChance::where('activity_id', $activity->id)->count();
  54. $list[] = $item;
  55. }
  56. $this->success('获取成功', [
  57. 'list' => $list,
  58. 'total' => LotteryActivity::where($where)->count()
  59. ]);
  60. }
  61. /**
  62. * 获取活动详情
  63. */
  64. public function activityDetail()
  65. {
  66. $activityId = $this->request->param('activity_id/d');
  67. if (!$activityId) {
  68. $this->error('参数错误');
  69. }
  70. $activity = LotteryActivity::find($activityId);
  71. if (!$activity) {
  72. $this->error('活动不存在');
  73. }
  74. $detail = $activity->toArray();
  75. // 获取奖品列表
  76. $prizes = LotteryPrize::where('activity_id', $activityId)
  77. ->where('status', 1)
  78. ->field('id,name,type,image,description,probability,total_stock,remain_stock,win_prompt,sort_order,unlock_people_num')
  79. ->order('sort_order asc')
  80. ->select();
  81. // 检查奖品是否已解锁(如果开启按人数解锁)
  82. if ($activity->unlock_by_people) {
  83. $currentPeopleCount = LotteryUserChance::where('activity_id', $activityId)->count();
  84. foreach ($prizes as &$prize) {
  85. $prize['is_unlocked'] = $prize->isUnlocked($currentPeopleCount);
  86. }
  87. } else {
  88. foreach ($prizes as &$prize) {
  89. $prize['is_unlocked'] = true;
  90. }
  91. }
  92. $detail['prizes'] = $prizes;
  93. // 统计信息
  94. $detail['total_participants'] = LotteryUserChance::where('activity_id', $activityId)->count();
  95. // 如果用户已登录,返回用户相关信息
  96. if (Auth::instance()->isLogin()) {
  97. $userId = Auth::instance()->id;
  98. $detail['user_chances'] = LotteryService::getUserChances($activityId, $userId);
  99. $detail['user_draw_count'] = LotteryDrawRecord::getUserDrawCount($activityId, $userId);
  100. $detail['user_win_count'] = LotteryDrawRecord::getUserWinCount($activityId, $userId);
  101. }
  102. $this->success('获取成功', $detail);
  103. }
  104. /**
  105. * 执行抽奖
  106. */
  107. public function draw()
  108. {
  109. $activityId = $this->request->param('activity_id/d');
  110. if (!$activityId) {
  111. $this->error('参数错误');
  112. }
  113. $userId = Auth::instance()->id;
  114. if (!$userId) {
  115. $this->error('请先登录');
  116. }
  117. try {
  118. $result = LotteryService::drawLottery($activityId, $userId);
  119. $this->success('抽奖成功', $result);
  120. } catch (Exception $e) {
  121. $this->error($e->getMessage());
  122. }
  123. }
  124. /**
  125. * 获取用户抽奖机会
  126. */
  127. public function getUserChances()
  128. {
  129. $activityId = $this->request->param('activity_id/d');
  130. if (!$activityId) {
  131. $this->error('参数错误');
  132. }
  133. $userId = Auth::instance()->id;
  134. if (!$userId) {
  135. $this->error('请先登录');
  136. }
  137. $chances = LotteryChanceService::getUserChanceDetail($activityId, $userId);
  138. $this->success('获取成功', $chances);
  139. }
  140. /**
  141. * 获取用户抽奖记录
  142. */
  143. public function getDrawRecords()
  144. {
  145. $activityId = $this->request->param('activity_id/d');
  146. $page = $this->request->param('page/d', 1);
  147. $limit = $this->request->param('limit/d', 20);
  148. $userId = Auth::instance()->id;
  149. if (!$userId) {
  150. $this->error('请先登录');
  151. }
  152. $where = ['user_id' => $userId];
  153. if ($activityId) {
  154. $where['activity_id'] = $activityId;
  155. }
  156. $records = LotteryDrawRecord::where($where)
  157. ->with(['activity', 'prize'])
  158. ->order('createtime desc')
  159. ->page($page, $limit)
  160. ->select();
  161. $list = [];
  162. foreach ($records as $record) {
  163. $item = [
  164. 'id' => $record->id,
  165. 'activity_id' => $record->activity_id,
  166. 'activity_name' => $record->activity->name ?? '',
  167. 'prize_id' => $record->prize_id,
  168. 'prize_name' => $record->prize->name ?? '',
  169. 'prize_type' => $record->prize->type ?? 0,
  170. 'prize_image' => $record->prize->image ?? '',
  171. 'is_win' => $record->is_win,
  172. 'draw_time' => $record->draw_time,
  173. 'trigger_type_text' => $record->trigger_type_text
  174. ];
  175. // 如果中奖,获取中奖记录详情
  176. if ($record->is_win && $record->winRecord) {
  177. $item['win_record'] = [
  178. 'id' => $record->winRecord->id,
  179. 'deliver_status' => $record->winRecord->deliver_status,
  180. 'deliver_status_text' => $record->winRecord->deliver_status_text,
  181. 'deliver_time' => $record->winRecord->deliver_time,
  182. 'exchange_code' => $record->winRecord->exchange_code
  183. ];
  184. }
  185. $list[] = $item;
  186. }
  187. $this->success('获取成功', [
  188. 'list' => $list,
  189. 'total' => LotteryDrawRecord::where($where)->count()
  190. ]);
  191. }
  192. /**
  193. * 获取用户中奖记录
  194. */
  195. public function getWinRecords()
  196. {
  197. $page = $this->request->param('page/d', 1);
  198. $limit = $this->request->param('limit/d', 20);
  199. $userId = Auth::instance()->id;
  200. if (!$userId) {
  201. $this->error('请先登录');
  202. }
  203. $records = LotteryWinRecord::getUserWinRecords($userId, $page, $limit);
  204. $list = [];
  205. foreach ($records as $record) {
  206. $item = [
  207. 'id' => $record->id,
  208. 'activity_id' => $record->activity_id,
  209. 'activity_name' => $record->activity->name ?? '',
  210. 'prize_id' => $record->prize_id,
  211. 'prize_name' => $record->prize_name,
  212. 'prize_type' => $record->prize_type,
  213. 'deliver_status' => $record->deliver_status,
  214. 'deliver_status_text' => $record->deliver_status_text,
  215. 'deliver_time' => $record->deliver_time,
  216. 'exchange_code' => $record->exchange_code,
  217. 'createtime' => $record->createtime
  218. ];
  219. // 根据奖品类型返回特定信息
  220. $prizeValue = $record->prize_value_data;
  221. switch ($record->prize_type) {
  222. case LotteryPrize::TYPE_RED_PACKET:
  223. $item['amount'] = $prizeValue['amount'] ?? 0;
  224. break;
  225. case LotteryPrize::TYPE_COUPON:
  226. $item['coupon_id'] = $prizeValue['coupon_id'] ?? 0;
  227. break;
  228. case LotteryPrize::TYPE_GOODS:
  229. $item['goods_id'] = $prizeValue['goods_id'] ?? 0;
  230. $item['goods_sku_id'] = $prizeValue['goods_sku_id'] ?? 0;
  231. break;
  232. }
  233. $list[] = $item;
  234. }
  235. $this->success('获取成功', [
  236. 'list' => $list,
  237. 'total' => LotteryWinRecord::where('user_id', $userId)->count()
  238. ]);
  239. }
  240. /**
  241. * 设置中奖记录收货地址
  242. */
  243. public function setWinRecordAddress()
  244. {
  245. $winRecordId = $this->request->param('win_record_id/d');
  246. $receiverName = $this->request->param('receiver_name');
  247. $receiverMobile = $this->request->param('receiver_mobile');
  248. $receiverAddress = $this->request->param('receiver_address');
  249. if (!$winRecordId || !$receiverName || !$receiverMobile || !$receiverAddress) {
  250. $this->error('参数不完整');
  251. }
  252. $userId = Auth::instance()->id;
  253. if (!$userId) {
  254. $this->error('请先登录');
  255. }
  256. $winRecord = LotteryWinRecord::where('id', $winRecordId)
  257. ->where('user_id', $userId)
  258. ->find();
  259. if (!$winRecord) {
  260. $this->error('中奖记录不存在');
  261. }
  262. if ($winRecord->deliver_status != LotteryWinRecord::DELIVER_STATUS_PENDING) {
  263. $this->error('该奖品已处理,无法修改地址');
  264. }
  265. try {
  266. $winRecord->setDeliveryAddress($receiverName, $receiverMobile, $receiverAddress);
  267. $this->success('设置成功');
  268. } catch (Exception $e) {
  269. $this->error('设置失败:' . $e->getMessage());
  270. }
  271. }
  272. /**
  273. * 获取活动排行榜(中奖次数)
  274. */
  275. public function getRanking()
  276. {
  277. $activityId = $this->request->param('activity_id/d');
  278. $page = $this->request->param('page/d', 1);
  279. $limit = $this->request->param('limit/d', 50);
  280. if (!$activityId) {
  281. $this->error('参数错误');
  282. }
  283. // 统计用户中奖次数
  284. $ranking = LotteryWinRecord::where('activity_id', $activityId)
  285. ->field('user_id, count(*) as win_count')
  286. ->with('user')
  287. ->group('user_id')
  288. ->order('win_count desc')
  289. ->page($page, $limit)
  290. ->select();
  291. $list = [];
  292. $rank = ($page - 1) * $limit + 1;
  293. foreach ($ranking as $item) {
  294. $list[] = [
  295. 'rank' => $rank++,
  296. 'user_id' => $item->user_id,
  297. 'nickname' => $item->user->nickname ?? '匿名用户',
  298. 'avatar' => $item->user->avatar ?? '',
  299. 'win_count' => $item->win_count
  300. ];
  301. }
  302. $this->success('获取成功', $list);
  303. }
  304. }