YueBao.php 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. <?php
  2. namespace App\Http\Controllers\admin;
  3. use App\Http\Controllers\Controller;
  4. use App\Models\ActivityReward;
  5. use App\Models\YuebaoItem;
  6. use App\Models\YuebaoLog;
  7. use App\Services\ActivityRewardService;
  8. use App\Support\ActivityCatalog;
  9. use Exception;
  10. use App\Constants\HttpStatus;
  11. use Illuminate\Http\JsonResponse;
  12. use Illuminate\Support\Facades\DB;
  13. use Illuminate\Validation\ValidationException;
  14. class YueBao extends Controller
  15. {
  16. /**
  17. * 余额宝持仓列表
  18. */
  19. public function item()
  20. {
  21. try {
  22. $params = request()->validate([
  23. 'page' => ['nullable', 'integer', 'min:1'],
  24. 'limit' => ['nullable', 'integer', 'min:1'],
  25. 'id' => ['nullable', 'integer', 'min:1'],
  26. 'user_id' => ['nullable'],
  27. 'member_id' => ['nullable'],
  28. 'account' => ['nullable', 'string', 'max:64'],
  29. 'first_name' => ['nullable'],
  30. 'start_time' => ['nullable', 'date', 'date_format:Y-m-d', 'required_with:end_time'],
  31. 'end_time' => ['nullable', 'date', 'date_format:Y-m-d', 'required_with:start_time'],
  32. ]);
  33. $page = request()->input('page', 1);
  34. $limit = request()->input('limit', 15);
  35. $query = YuebaoItem::join('users', 'users.user_id', '=', 'yuebao_item.user_id')
  36. ->select("yuebao_item.*", "users.first_name", "users.member_id", "users.account", "users.admin_note as user_admin_note");
  37. if (!empty($params['id'])) {
  38. $query = $query->where('yuebao_item.id', $params['id']);
  39. }
  40. if (!empty($params['user_id'])) {
  41. $query = $query->where('yuebao_item.user_id', $params['user_id']);
  42. }
  43. if (!empty($params['member_id'])) {
  44. $query = $query->where('yuebao_item.user_id', $params['member_id']);
  45. }
  46. if (!empty($params['start_time'])) {
  47. $startTime = strtotime($params['start_time'] . " 00:00:00");
  48. $query = $query->where('yuebao_item.create_time', '>=', $startTime);
  49. }
  50. if (!empty($params['end_time'])) {
  51. $endTime = strtotime($params['end_time'] . " 23:59:59");
  52. $query = $query->where('yuebao_item.create_time', '<=', $endTime);
  53. }
  54. if (!empty($params['account'])) {
  55. $query = $query->where('users.account', 'like', '%' . trim((string)$params['account']) . '%');
  56. }
  57. if (isset($params['first_name']) && !empty($params['first_name'])) {
  58. $query = $query->where('users.first_name', 'like', "%" . $params['first_name'] . "%");
  59. }
  60. $count = $query->count();
  61. $list = $query
  62. ->forPage($page, $limit)
  63. ->orderByDesc('yuebao_item.create_time')
  64. ->get();
  65. } catch (Exception $e) {
  66. return $this->error(HttpStatus::CUSTOM_ERROR,$e->getMessage());
  67. }
  68. return $this->success(['total' => $count, 'data' => $list]);
  69. }
  70. /**
  71. * 余额宝日志列表
  72. */
  73. public function log()
  74. {
  75. try {
  76. $params = request()->validate([
  77. 'page' => ['nullable', 'integer', 'min:1'],
  78. 'limit' => ['nullable', 'integer', 'min:1'],
  79. 'id' => ['nullable', 'integer', 'min:1'],
  80. 'item_id' => ['nullable', 'integer', 'min:1'],
  81. 'user_id' => ['nullable'],
  82. 'type' => ['nullable', 'integer'],
  83. 'start_time' => ['nullable', 'date', 'date_format:Y-m-d', 'required_with:end_time'],
  84. 'end_time' => ['nullable', 'date', 'date_format:Y-m-d', 'required_with:start_time'],
  85. ]);
  86. $page = request()->input('page', 1);
  87. $limit = request()->input('limit', 15);
  88. $query = new YuebaoLog();
  89. if (!empty($params['id'])) {
  90. $query = $query->where('id', $params['id']);
  91. }
  92. if (!empty($params['item_id'])) {
  93. $query = $query->where('item_id', $params['item_id']);
  94. }
  95. if (!empty($params['user_id'])) {
  96. $query = $query->where('user_id', $params['user_id']);
  97. }
  98. if (!empty($params['type'])) {
  99. $query = $query->where('type', $params['type']);
  100. }
  101. if (!empty($params['start_time'])) {
  102. $startTime = strtotime($params['start_time'] . " 00:00:00");
  103. $query = $query->where('create_time', '>=', $startTime);
  104. }
  105. if (!empty($params['end_time'])) {
  106. $endTime = strtotime($params['end_time'] . " 23:59:59");
  107. $query = $query->where('create_time', '<=', $endTime);
  108. }
  109. $count = $query->count();
  110. $list = $query
  111. ->forPage($page, $limit)
  112. ->orderByDesc('create_time')
  113. ->get();
  114. } catch (Exception $e) {
  115. return $this->error(HttpStatus::CUSTOM_ERROR,$e->getMessage());
  116. }
  117. return $this->success(['total' => $count, 'data' => $list]);
  118. }
  119. /** 余额宝配置固定为一条 type=6 活动行;与会员端选取顺序一致取排序最高、ID 最大的一条。 */
  120. private static function configRow(): ?ActivityReward
  121. {
  122. return ActivityReward::where('type', ActivityCatalog::YUEBAO_TYPE)
  123. ->orderByDesc('sort')->orderByDesc('id')->first();
  124. }
  125. /**
  126. * 余额宝配置详情
  127. */
  128. public function config(): JsonResponse
  129. {
  130. $row = self::configRow();
  131. if (!$row) {
  132. return $this->success(null);
  133. }
  134. $data = $row->toArray();
  135. $params = json_decode((string)$row->getRawOriginal('params'), true) ?: [];
  136. $data['daily_interest_rate'] = $params['daily_interest_rate'] ?? null;
  137. $data['number_of_consecutive_days_of_deposit'] = $params['number_of_consecutive_days_of_deposit'] ?? null;
  138. // 活动类型、游戏分类、点击行为、排序不属于余额宝配置。
  139. unset($data['params'], $data['type'], $data['type_name'], $data['game_category'], $data['game_category_name'],
  140. $data['click_type'], $data['link'], $data['link_pc'], $data['link_h5'], $data['click_position'], $data['can_jump'], $data['sort']);
  141. return $this->success($data);
  142. }
  143. /**
  144. * 保存余额宝配置(无则新建)
  145. */
  146. public function saveConfig(): JsonResponse
  147. {
  148. DB::beginTransaction();
  149. try {
  150. $params = request()->validate([
  151. 'title' => ['required', 'string', 'min:1', 'max:140'],
  152. 'sub_title' => ['required', 'string', 'min:1', 'max:140'],
  153. 'start_time' => ['nullable', 'required_with:end_time', 'date'],
  154. 'end_time' => ['nullable', 'required_with:start_time', 'date', 'after_or_equal:start_time'],
  155. 'detail_image' => ['required'],
  156. 'pc_image' => ['required'],
  157. 'status' => ['required', 'integer', 'in:0,1'],
  158. 'lang' => ['required', 'string'],
  159. 'content' => ['nullable', 'string'],
  160. 'daily_interest_rate' => ['required', 'numeric', 'min:0', 'max:100'],
  161. 'number_of_consecutive_days_of_deposit' => ['required', 'integer', 'min:1', 'max:3650'],
  162. ], [
  163. 'start_time.required_with' => '活动开始和结束时间必须同时填写或同时留空',
  164. 'end_time.required_with' => '活动开始和结束时间必须同时填写或同时留空',
  165. 'daily_interest_rate.required' => '请填写日化率',
  166. 'number_of_consecutive_days_of_deposit.required' => '请填写连续存款天数',
  167. ]);
  168. $row = self::configRow();
  169. $stored = $row ? (json_decode((string)$row->getRawOriginal('params'), true) ?: []) : [];
  170. $stored['daily_interest_rate'] = (string)$params['daily_interest_rate'];
  171. $stored['number_of_consecutive_days_of_deposit'] = (int)$params['number_of_consecutive_days_of_deposit'];
  172. unset($params['daily_interest_rate'], $params['number_of_consecutive_days_of_deposit']);
  173. $defaults = ActivityRewardService::configurationDefaults();
  174. unset($defaults['sort']);
  175. $params = array_merge($params, array_intersect_key(request()->all(), $defaults + ['budget' => true]));
  176. $params['type'] = ActivityCatalog::YUEBAO_TYPE;
  177. $params['params'] = json_encode($stored);
  178. if ($row) {
  179. $params['id'] = $row->id;
  180. }
  181. ActivityRewardService::submit($params);
  182. DB::commit();
  183. } catch (ValidationException $e) {
  184. DB::rollBack();
  185. return $this->error(HttpStatus::CUSTOM_ERROR, $e->validator->errors()->first());
  186. } catch (Exception $e) {
  187. DB::rollBack();
  188. return $this->error($e->getCode() ?: HttpStatus::CUSTOM_ERROR, $e->getMessage());
  189. }
  190. return $this->success();
  191. }
  192. }