DrawRecord.php 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. <?php
  2. namespace app\admin\controller\lottery;
  3. use app\common\controller\Backend;
  4. use app\common\Enum\StatusEnum;
  5. use app\common\Enum\LotteryEnum;
  6. /**
  7. * 抽奖记录管理
  8. *
  9. * @icon fa fa-list
  10. */
  11. class DrawRecord extends Backend
  12. {
  13. /**
  14. * DrawRecord模型对象
  15. * @var \app\admin\model\lottery\DrawRecord
  16. */
  17. protected $model = null;
  18. protected $relationSearch = true;
  19. public function _initialize()
  20. {
  21. parent::_initialize();
  22. $this->model = new \app\admin\model\lottery\DrawRecord;
  23. // 获取枚举值列表
  24. $this->view->assign([
  25. "triggerTypeList" => $this->model->getTriggerTypeList(),
  26. "statusList" => StatusEnum::getMap(),
  27. "isWinList" => LotteryEnum::getIsWinMap(),
  28. "deliverStatusList" => LotteryEnum::getDeliverStatusMap(),
  29. ]);
  30. $this->assignconfig("triggerTypeList", json_encode($this->model->getTriggerTypeList()));
  31. $this->assignconfig("statusList", json_encode(StatusEnum::getMap()));
  32. $this->assignconfig("isWinList", json_encode(LotteryEnum::getIsWinMap()));
  33. $this->assignconfig("deliverStatusList", json_encode(LotteryEnum::getDeliverStatusMap()));
  34. // 奖品类型配置
  35. $this->view->assign("prizeTypeList", LotteryEnum::getPrizeTypeMap());
  36. $this->assignconfig("prizeTypeList", json_encode(LotteryEnum::getPrizeTypeMap()));
  37. $this->assignconfig("prizeTypeList", json_encode(LotteryEnum::getPrizeTypeMap()));
  38. // 发放状态
  39. $this->view->assign("deliverStatusList", LotteryEnum::getDeliverStatusMap());
  40. $this->assignconfig("deliverStatusList", json_encode(LotteryEnum::getDeliverStatusMap()));
  41. // 抽奖类型
  42. $this->view->assign("lotteryTypeList", LotteryEnum::getLotteryTypeMap());
  43. $this->assignconfig("lotteryTypeList", json_encode(LotteryEnum::getLotteryTypeMap()));
  44. // 抽奖方式
  45. $this->view->assign("lotteryTypeList", LotteryEnum::getLotteryTypeMap());
  46. $this->assignconfig("lotteryTypeList", json_encode(LotteryEnum::getLotteryTypeMap()));
  47. }
  48. /**
  49. * 查看
  50. */
  51. public function index()
  52. {
  53. //当前是否为关联查询
  54. $this->relationSearch = true;
  55. //设置过滤方法
  56. $this->request->filter(['strip_tags', 'trim']);
  57. if ($this->request->isAjax()) {
  58. //如果发送的来源是Selectpage,则转发到Selectpage
  59. if ($this->request->request('keyField')) {
  60. return $this->selectpage();
  61. }
  62. list($where, $sort, $order, $offset, $limit) = $this->buildparams();
  63. $list = $this->model
  64. ->with(['activity', 'user', 'prize'])
  65. ->where($where)
  66. ->order($sort, $order)
  67. ->paginate($limit);
  68. // where in 查询 中奖记录
  69. $drawRecordIds = $list->column('id');
  70. $winRecord = new \app\admin\model\lottery\WinRecord;
  71. $objWinRecord = $winRecord->where('draw_record_id', 'in', $drawRecordIds)
  72. ->select();
  73. $winRecordList = collection($objWinRecord)->toArray();
  74. $winRecordMap = [];
  75. foreach ($winRecordList as $item) {
  76. $winRecordMap[$item['draw_record_id']] = $item;
  77. }
  78. $list->each(function($row) use ($winRecordMap) {
  79. $row->winRecord = $winRecordMap[$row->id] ?? null;
  80. });
  81. foreach ($list as $row) {
  82. $row->visible([
  83. 'id', 'activity_id', 'user_id', 'prize_id', 'is_win',
  84. 'trigger_type', 'trigger_order_id', 'trigger_amount',
  85. 'draw_ip', 'draw_time', 'device_info', 'status', 'createtime'
  86. ]);
  87. $row->visible(['activity', 'user', 'prize', 'winRecord']);
  88. // 处理关联数据
  89. if ($row->getRelation('activity')) {
  90. $row->getRelation('activity')->visible(['id', 'name', 'type','lottery_type','lottery_time']);
  91. }
  92. if ($row->getRelation('user')) {
  93. $row->getRelation('user')->visible(['id', 'username', 'mobile','avatar']);
  94. }
  95. if ($row->getRelation('prize')) {
  96. $row->getRelation('prize')->visible(['id', 'name', 'type', 'image']);
  97. }
  98. }
  99. $result = array("total" => $list->total(), "rows" => $list->items());
  100. return json($result);
  101. }
  102. return $this->view->fetch();
  103. }
  104. /**
  105. * 详情
  106. */
  107. public function detail($ids = null)
  108. {
  109. $row = $this->model->with(['activity', 'user', 'prize', 'winRecord'])->find($ids);
  110. if (!$row) {
  111. $this->error(__('No Results were found'));
  112. }
  113. // 解析win_info JSON数据
  114. if ($row->win_info) {
  115. $row->win_info_data = json_decode($row->win_info, true);
  116. }
  117. // 解析设备信息
  118. if ($row->device_info) {
  119. $row->device_info_data = json_decode($row->device_info, true);
  120. }
  121. $this->view->assign("row", $row);
  122. return $this->view->fetch('lottery/draw_record/detail');
  123. }
  124. /**
  125. * 统计数据
  126. */
  127. public function statistics()
  128. {
  129. $stats = [];
  130. // 总抽奖次数
  131. $stats['total_draws'] = $this->model->count();
  132. // 中奖次数
  133. $stats['total_wins'] = $this->model->where('is_win', 1)->count();
  134. // 中奖率
  135. $stats['win_rate'] = $stats['total_draws'] > 0 ?
  136. round($stats['total_wins'] / $stats['total_draws'] * 100, 2) : 0;
  137. // 按触发类型统计
  138. $stats['by_trigger_type'] = $this->model
  139. ->field('trigger_type, COUNT(*) as count')
  140. ->group('trigger_type')
  141. ->select()
  142. ->toArray();
  143. // 按奖品类型统计中奖情况
  144. $stats['by_prize_type'] = $this->model
  145. ->alias('dr')
  146. ->join('shop_lottery_prize p', 'dr.prize_id = p.id')
  147. ->field('p.type, COUNT(*) as total_count, SUM(dr.is_win) as win_count')
  148. ->group('p.type')
  149. ->select()
  150. ->toArray();
  151. // 最近7天抽奖趋势
  152. $stats['recent_trend'] = [];
  153. for ($i = 6; $i >= 0; $i--) {
  154. $date = date('Y-m-d', strtotime("-{$i} days"));
  155. $start_time = strtotime($date);
  156. $end_time = strtotime($date . ' 23:59:59');
  157. $daily_draws = $this->model
  158. ->where('draw_time', 'between', [$start_time, $end_time])
  159. ->count();
  160. $daily_wins = $this->model
  161. ->where('draw_time', 'between', [$start_time, $end_time])
  162. ->where('is_win', 1)
  163. ->count();
  164. $stats['recent_trend'][] = [
  165. 'date' => $date,
  166. 'draws' => $daily_draws,
  167. 'wins' => $daily_wins,
  168. 'rate' => $daily_draws > 0 ? round($daily_wins / $daily_draws * 100, 2) : 0
  169. ];
  170. }
  171. return json(['code' => 1, 'data' => $stats]);
  172. }
  173. /**
  174. * 导出记录
  175. */
  176. public function export()
  177. {
  178. // 获取导出参数
  179. $filter = $this->request->get('filter', '');
  180. $where = [];
  181. if ($filter) {
  182. $where = json_decode($filter, true);
  183. }
  184. $list = $this->model->with(['activity', 'user', 'prize', 'winRecord'])
  185. ->where($where)
  186. ->order('createtime', 'desc')
  187. ->select();
  188. $header = [
  189. 'ID', '活动名称', '用户昵称', '用户手机', '奖品名称', '奖品类型',
  190. '是否中奖', '触发类型', '触发金额', '抽奖IP', '抽奖时间',
  191. '发放状态', '收货人', '快递单号', '创建时间'
  192. ];
  193. $data = [];
  194. foreach ($list as $item) {
  195. $data[] = [
  196. $item->id,
  197. $item->activity->name ?? '',
  198. $item->user->nickname ?? '',
  199. $item->user->mobile ?? '',
  200. $item->prize->name ?? '',
  201. $item->prize->type_text ?? '',
  202. $item->is_win ? '是' : '否',
  203. $item->trigger_type_text,
  204. $item->trigger_amount ?? '',
  205. $item->draw_ip ?? '',
  206. date('Y-m-d H:i:s', $item->draw_time),
  207. $item->winRecord->deliver_status_text ?? '',
  208. $item->winRecord->receiver_name ?? '',
  209. $item->winRecord->express_number ?? '',
  210. date('Y-m-d H:i:s', $item->createtime)
  211. ];
  212. }
  213. // 这里可以集成Excel导出功能
  214. $this->success('导出成功', '', ['header' => $header, 'data' => $data]);
  215. }
  216. /**
  217. * 批量处理中奖发放
  218. */
  219. public function batchDeliver()
  220. {
  221. $ids = $this->request->post('ids');
  222. if (!$ids) {
  223. $this->error('请选择要处理的记录');
  224. }
  225. $count = 0;
  226. foreach ($ids as $id) {
  227. $record = $this->model->with('winRecord')->get($id);
  228. if ($record && $record->is_win && $record->winRecord) {
  229. // 这里可以调用具体的发放逻辑
  230. $count++;
  231. }
  232. }
  233. $this->success("成功处理 {$count} 条记录");
  234. }
  235. }