AccountService.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | LARAVEL8.0 框架 [ LARAVEL ][ RXThinkCMF ]
  4. // +----------------------------------------------------------------------
  5. // | 版权所有 2017~2021 LARAVEL研发中心
  6. // +----------------------------------------------------------------------
  7. // | 官方网站: http://www.laravel.cn
  8. // +----------------------------------------------------------------------
  9. // | Author: laravel开发员 <laravel.qq.com>
  10. // +----------------------------------------------------------------------
  11. namespace App\Services\Common;
  12. use App\Models\AccountLogModel;
  13. use App\Models\ActionLogModel;
  14. use App\Services\BaseService;
  15. use Carbon\Carbon;
  16. use Illuminate\Support\Facades\DB;
  17. /**
  18. * 账户明细管理-服务类
  19. * @author laravel开发员
  20. * @since 2020/11/11
  21. * Class AccountService
  22. * @package App\Services\Common
  23. */
  24. class AccountService extends BaseService
  25. {
  26. public static $instance = null;
  27. /**
  28. * 构造函数
  29. * @author laravel开发员
  30. * @since 2020/11/11
  31. * AccountService constructor.
  32. */
  33. public function __construct()
  34. {
  35. $this->model = new AccountLogModel();
  36. }
  37. /**
  38. * 静态入口
  39. * @return static|null
  40. */
  41. public static function make()
  42. {
  43. if (!self::$instance) {
  44. self::$instance = (new static());
  45. }
  46. return self::$instance;
  47. }
  48. /**
  49. * @param $params
  50. * @param int $pageSize
  51. * @return array
  52. */
  53. public function getDataList($params, $pageSize = 15)
  54. {
  55. $query = $this->getQuery($params);
  56. $model = clone $query;
  57. $counts = [
  58. 'count' => $model->count('a.id'),
  59. 'total' => $model->sum('a.money'),
  60. ];
  61. $list = $query->select(['a.*'])
  62. ->orderBy('a.create_time', 'desc')
  63. ->orderBy('a.id', 'desc')
  64. ->paginate($pageSize > 0 ? $pageSize : 9999999);
  65. $list = $list ? $list->toArray() : [];
  66. if ($list) {
  67. $accountTypes = config('payment.accountTypes');
  68. foreach ($list['data'] as &$item) {
  69. $item['create_time'] = $item['create_time'] ? datetime($item['create_time'], 'Y-m-d H.i.s') : '';
  70. $type = isset($item['type']) ? intval($item['type']) : 0;
  71. $item['type_text'] = isset($item['remark']) ? trim($item['remark']) : '';
  72. $item['member'] = isset($item['member']) ? $item['member'] : [];
  73. if (empty($item['type_text'])) {
  74. $item['type_text'] = isset($accountTypes[$type]) ? $accountTypes[$type] : '收支明细';
  75. }
  76. }
  77. }
  78. return [
  79. 'pageSize' => $pageSize,
  80. 'total' => isset($list['total']) ? $list['total'] : 0,
  81. 'counts' => $counts,
  82. 'list' => isset($list['data']) ? $list['data'] : []
  83. ];
  84. }
  85. /**
  86. * 查询
  87. * @param $params
  88. * @return \Illuminate\Database\Eloquent\Builder
  89. */
  90. public function getQuery($params)
  91. {
  92. $where = ['a.mark' => 1];
  93. $status = isset($params['status']) ? $params['status'] : 0;
  94. $type = isset($params['type']) ? $params['type'] : 0;
  95. if ($status > 0) {
  96. $where['a.status'] = $status;
  97. }
  98. if ($type > 0) {
  99. $where['a.type'] = $type;
  100. }
  101. return $this->model->with(['member'])->from("account_logs as a")
  102. ->leftJoin('member as b', 'b.id', '=', 'a.user_id')
  103. ->where($where)
  104. ->where(function ($query) use ($params) {
  105. $keyword = isset($params['keyword']) ? $params['keyword'] : '';
  106. $userId = isset($params['user_id']) ? $params['user_id'] : 0;
  107. if ($userId) {
  108. $query->where('a.user_id', $userId);
  109. }
  110. if ($keyword) {
  111. $query->where(function ($query) use ($keyword) {
  112. $query->where('b.nickname', 'like', "%{$keyword}%")
  113. ->orWhere('b.mobile', 'like', "%{$keyword}%");
  114. });
  115. }
  116. $orderNo = isset($params['order_no']) ? trim($params['order_no']) : '';
  117. if ($orderNo) {
  118. $query->where(function ($query) use ($orderNo) {
  119. $query->where('a.source_order_no', 'like', "%{$orderNo}%");
  120. });
  121. }
  122. })
  123. ->where(function ($query) use ($params) {
  124. // 日期
  125. $date = isset($params['date']) ? $params['date'] : [];
  126. $start = isset($date[0]) ? $date[0] : '';
  127. $end = isset($date[1]) ? $date[1] : '';
  128. $end = $start >= $end ? '' : $end;
  129. if ($start) {
  130. $query->where('a.create_time', '>=', strtotime($start));
  131. }
  132. if ($end) {
  133. $query->where('a.create_time', '<=', strtotime($end));
  134. }
  135. });
  136. }
  137. /**
  138. * 添加或编辑
  139. * @return array
  140. * @since 2020/11/11
  141. * @author laravel开发员
  142. */
  143. public function edit()
  144. {
  145. $data = request()->all();
  146. return parent::edit($data); // TODO: Change the autogenerated stub
  147. }
  148. /**
  149. * 删除
  150. * @return array
  151. */
  152. public function delete()
  153. {
  154. // 设置日志标题
  155. ActionLogModel::setRecord(session('userId'), ['type' => 1, 'title' => "删除账户明细", 'content' => json_encode(request()->post(), 256), 'module' => 'admin']);
  156. ActionLogModel::record();
  157. $this->model->where('mark', 0)->where('update_time', '<=', time() - 7 * 86400)->delete();
  158. return parent::delete(); // TODO: Change the autogenerated stub
  159. }
  160. /**
  161. * 获取账户日志统计数据
  162. *
  163. * @param string $type 统计类型:today, yesterday, month, last_month, year, all
  164. * @param int|null $status 交易状态:1-已完成,2-待处理,3-失败/取消
  165. * @param int|null $start_time 开始时间戳
  166. * @param int|null $end_time 结束时间戳
  167. * @return array 统计结果
  168. */
  169. public function getStatistics($dateType = 'all', $type = null, $status = null, $start_time = null, $end_time = null)
  170. {
  171. // 基础查询
  172. $query = DB::table('account_logs');
  173. // 时间过滤
  174. if ($start_time && $end_time) {
  175. // 如果提供了开始和结束时间
  176. $query->whereBetween('date', [Carbon::createFromTimestamp($start_time), Carbon::createFromTimestamp($end_time)]);
  177. } else {
  178. // 根据不同的 `type` 筛选时间范围
  179. $currentDate = Carbon::now();
  180. switch ($dateType) {
  181. case 'today':
  182. $query->whereDate('date', '=', $currentDate->toDateString()); // 今日
  183. break;
  184. case 'yesterday':
  185. $query->whereDate('date', '=', $currentDate->subDay()->toDateString()); // 昨日
  186. break;
  187. case 'month':
  188. $query->whereMonth('date', '=', $currentDate->month) // 本月
  189. ->whereYear('date', '=', $currentDate->year);
  190. break;
  191. case 'last_month':
  192. $query->whereMonth('date', '=', $currentDate->subMonth()->month) // 上月
  193. ->whereYear('date', '=', $currentDate->year);
  194. break;
  195. case 'year':
  196. $query->whereYear('date', '=', $currentDate->year); // 本年
  197. break;
  198. case 'all':
  199. // 不进行时间过滤,返回所有数据
  200. break;
  201. default:
  202. break;
  203. }
  204. }
  205. // 如果传入了 status 参数,则加入状态过滤
  206. if ($status !== null) {
  207. $query->where('status', '=', $status);
  208. }
  209. // 如果传入了 status 参数,则加入状态过滤
  210. if ($type !== null) {
  211. $query->where('type', '=', $type);
  212. }
  213. // 获取统计数据
  214. return $query->selectRaw('
  215. count(*) as total_count,
  216. sum(money) as total_money
  217. ')->first();
  218. }
  219. public function getRevenueStats(array $params)
  220. {
  221. $dateType = $params['dateType'] ?? 'day';
  222. $vipType = $params['vip_type'] ?? null; // zg_vip | zsb_vip | video_vip
  223. $status = $params['status'] ?? null;
  224. $type = $params['type'] ?? null;
  225. $page = max(1, (int) ($params['page'] ?? 1));
  226. $limit = max(1, (int) ($params['limit'] ?? 10));
  227. $startTimestamp = !empty($params['start_time']) ? strtotime($params['start_time']) : strtotime('2000-01-01');
  228. $endTimestamp = !empty($params['end_time']) ? strtotime($params['end_time']) : time();
  229. if ($endTimestamp < $startTimestamp) {
  230. $endTimestamp = $startTimestamp;
  231. }
  232. // 日期分组
  233. switch ($dateType) {
  234. case 'year':
  235. $groupRaw = "FROM_UNIXTIME(lev_l.create_time,'%Y')";
  236. break;
  237. case 'month':
  238. $groupRaw = "FROM_UNIXTIME(lev_l.create_time,'%Y-%m')";
  239. break;
  240. case 'week':
  241. $groupRaw = "CONCAT(YEAR(FROM_UNIXTIME(lev_l.create_time)),'-',LPAD(WEEK(FROM_UNIXTIME(lev_l.create_time),1),2,'0'))";
  242. break;
  243. case 'day':
  244. default:
  245. $groupRaw = "FROM_UNIXTIME(lev_l.create_time,'%Y-%m-%d')";
  246. break;
  247. }
  248. $query = DB::table('account_logs as l')
  249. ->join('member as m', 'l.user_id', '=', 'm.id')
  250. ->selectRaw("
  251. {$groupRaw} as stat_date,
  252. COUNT(*) as total_count,
  253. SUM(lev_l.money) as total_money
  254. ")
  255. ->whereBetween('l.create_time', [$startTimestamp, $endTimestamp]);
  256. if ($status !== null) {
  257. $query->where('l.status', $status);
  258. }
  259. // VIP类型筛选
  260. if ($vipType == 'zg_vip') {
  261. $query->where('m.is_zg_vip', 1);
  262. } elseif ($vipType == 'zsb_vip') {
  263. $query->where('m.is_zsb_vip', 1);
  264. } elseif ($vipType == 'video_vip') {
  265. $query->where('m.is_video_vip', 1);
  266. }
  267. if ($type) {
  268. $query->where('l.type', $type);
  269. }
  270. $query->groupBy('stat_date')->orderBy('stat_date', 'desc');
  271. // 总条数
  272. $total = DB::table(DB::raw("({$query->toSql()}) as t"))
  273. ->mergeBindings($query)
  274. ->count();
  275. $list = $query->forPage($page, $limit)->get();
  276. return [
  277. 'list' => $list,
  278. 'total' => $total,
  279. 'page' => $page,
  280. 'limit' => $limit,
  281. ];
  282. }
  283. }