DataStatisticsController.php 96 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269
  1. <?php
  2. namespace App\Http\Controllers\Admin;
  3. use App\Filters\BikeFilter;
  4. use App\Filters\CardRidingOrderFilter;
  5. use App\Filters\DepositCardOrderFilter;
  6. use App\Filters\OrderFilter;
  7. use App\Filters\OrderRentFilter;
  8. use App\Filters\RechargeOrderFilter;
  9. use App\Filters\StatisticFilter;
  10. use App\Filters\UserFilter;
  11. use App\Filters\WalletLogFilter;
  12. use App\Filters\WorkOrderFilter;
  13. use App\Models\AdminMerchant;
  14. use App\Models\AdminUser;
  15. use App\Models\AdminUserArea;
  16. use App\Models\Area;
  17. use App\Models\Bike;
  18. use App\Models\CardRidingOrder;
  19. use App\Models\DepositCardOrder;
  20. use App\Models\Model;
  21. use App\Models\Order;
  22. use App\Models\OrderRent;
  23. use App\Models\RechargeOrder;
  24. use App\Models\Statistic;
  25. use App\Models\User;
  26. use App\Models\UserPhoneDetail;
  27. use App\Models\WalletLog;
  28. use App\Models\WorkOrder;
  29. use App\Utils\Admin;
  30. use App\Utils\RedisKeys;
  31. use Carbon\Carbon;
  32. use Illuminate\Http\Request;
  33. use App\Http\Controllers\Controller;
  34. use App\Models\DepositOrder;
  35. use App\Models\DepositRefund;
  36. use Exception;
  37. use Illuminate\Support\Facades\DB;
  38. use Illuminate\Support\Facades\Log;
  39. /**
  40. * 后台 - 控制台 - 统计分析
  41. * Class DataStatisticsController
  42. * @package App\Http\Controllers\Admin
  43. */
  44. class DataStatisticsController extends Controller
  45. {
  46. // 验证是否有该区域的权限
  47. private function validateAreaId($area_id)
  48. {
  49. $area_ids = AdminUser::getAreaIdsByAdminId(Admin::user()->id);
  50. if (count($area_ids) !== 0 && in_array($area_id, $area_ids)) {
  51. return false;
  52. } else {
  53. $id = AdminUserArea::query()->where('admin_id', Admin::user()->id)->value('area_id');
  54. $id = $id ?? 0;
  55. if ($area_id == $id) return false;
  56. }
  57. return true;
  58. }
  59. /**
  60. * 商户列表
  61. * @return \Illuminate\Http\JsonResponse
  62. * @author ht
  63. */
  64. public function adminMerchantList()
  65. {
  66. $data = [];
  67. // 管理员可以获取商户列表
  68. if (Admin::isAdministrator()) {
  69. // status 状态(1正常0暂停)
  70. $data = AdminMerchant::where('status', 1)->select(['id', 'username', 'name'])->get()->toArray();
  71. }
  72. return $this->ok($data);
  73. }
  74. /**
  75. * 区域列表 - 依据所选商户获取对应区域
  76. *
  77. * @param Request $request
  78. * @return \Illuminate\Http\JsonResponse
  79. * @author ht
  80. */
  81. public function areaList(Request $request)
  82. {
  83. $admin_id = Admin::user()->id;
  84. if (Admin::user()->isRole(Admin::ROLE_JISHU_ADMIN)) {
  85. $merchant_id = $request->get('merchant_id') ?? 0;
  86. if ($merchant_id) {
  87. $data = Area::where('status', 1)->where('merchant_id', $merchant_id)->orderByDesc('id')->select(['id', 'name'])->get()->toArray();
  88. } else {
  89. $data = Area::where('status', 1)->orderByDesc('id')->select(['id', 'name'])->get()->toArray();
  90. }
  91. } else {
  92. $area_ids = AdminUser::getAreaIdsByAdminId($admin_id);
  93. $data = Area::whereIn('id', $area_ids)->where('status', 1)->orderByDesc('id')->select(['id', 'name'])->get()->toArray();
  94. }
  95. return $this->ok($data);
  96. }
  97. /**
  98. * topIndex 头部统计数据
  99. *
  100. * @param Request $request
  101. * @return \Illuminate\Http\JsonResponse
  102. * @author ht
  103. *
  104. */
  105. public function topIndex(Request $request)
  106. {
  107. $area_id = $request->get('area_id') ?? '';
  108. if ($area_id) {
  109. $flag = $this->validateAreaId($area_id);
  110. if ($flag) return $this->error('无权限查看该区域');
  111. }
  112. $merchant_id = $request->get('merchant_id') ?? '';
  113. $data = [];
  114. $data['new_order'] = $this->newOrder($area_id, $merchant_id); // 新订单
  115. $data['total_user'] = $this->totalUser($area_id, $merchant_id); // 总用户
  116. $data['total_order'] = $this->totalOrder($area_id, $merchant_id); // 总订单
  117. $data['total_profit'] = $this->totalProfitMonth($area_id, $merchant_id); // 总收益 - 统计本月 和 上月的总收益
  118. $data['cumulative_profit'] = $this->cumulativeDeposit($area_id, $merchant_id); // 统计本月和上月的累计押金
  119. return $this->ok($data);
  120. }
  121. /**
  122. * topIndex 头部统计数据 - 统计本月和上月的累计押金,注意本月的包含当天的累计押金
  123. */
  124. protected function cumulativeDeposit($area_id, $merchant_id)
  125. {
  126. $DepositOrder = DepositOrder::query();
  127. if (!Admin::user()->inRoles([Admin::ROLE_JISHU_ADMIN])) {
  128. if ($merchant_id) {
  129. $DepositOrder->where('merchant_id', $merchant_id);
  130. } else {
  131. $DepositOrder->where(AdminMerchant::getMerchantWhere());
  132. }
  133. }
  134. if ($area_id) {
  135. $DepositOrder->where('area_id', $area_id);
  136. }
  137. $currentMonth = $DepositOrder->where('is_refund', DepositOrder::REFUND_NO)->where('pay_status', DepositOrder::PAY_STATUS_OK)->whereDate('pay_time', '>=', Carbon::now()->firstOfMonth()->toDateString())->sum('money');
  138. $data['cumulative_profit_num'] = floatval($currentMonth);
  139. return $data;
  140. }
  141. // topIndex 头部统计数据 - 新订单
  142. protected function newOrder($area_id = '', $merchant_id = '')
  143. {
  144. $totalOrder = [];
  145. $yesterday = Carbon::yesterday();
  146. $today = Carbon::today();
  147. // 管理员,并且选择了商户
  148. if (Admin::isAdministrator() && $merchant_id) {
  149. $yesterdayOrderNum = Order::query()->where('merchant_id', $merchant_id);
  150. $todayOrderNum = Order::query()->where('merchant_id', $merchant_id);
  151. $yesterdayOrderRentNum = OrderRent::query()->where('merchant_id', $merchant_id);
  152. $todayOrderRentNum = OrderRent::query()->where('merchant_id', $merchant_id);
  153. } else {
  154. $yesterdayOrderNum = Order::query()->where(AdminMerchant::getMerchantWhere());
  155. $todayOrderNum = Order::query()->where(AdminMerchant::getMerchantWhere());
  156. $yesterdayOrderRentNum = OrderRent::query()->where(AdminMerchant::getMerchantWhere());
  157. $todayOrderRentNum = OrderRent::query()->where(AdminMerchant::getMerchantWhere());
  158. }
  159. if (!empty($area_id)) {
  160. $yesterdayOrderNum = $yesterdayOrderNum->where('area_id', $area_id);
  161. $todayOrderNum = $todayOrderNum->where('area_id', $area_id);
  162. $yesterdayOrderRentNum = $yesterdayOrderRentNum->where('area_id', $area_id);
  163. $todayOrderRentNum = $todayOrderRentNum->where('area_id', $area_id);
  164. } else {
  165. $admin_id = Admin::user()->id;
  166. if (!Admin::isAdministrator()) {
  167. $area_ids = AdminUser::getAreaIdsByAdminId($admin_id);
  168. if (count($area_ids) !== 0) {
  169. $yesterdayOrderNum = $yesterdayOrderNum->whereIn('area_id', $area_ids);
  170. $todayOrderNum = $todayOrderNum->whereIn('area_id', $area_ids);
  171. $yesterdayOrderRentNum = $yesterdayOrderRentNum->whereIn('area_id', $area_ids);
  172. $todayOrderRentNum = $todayOrderRentNum->whereIn('area_id', $area_ids);
  173. } else {
  174. $area_id = AdminUserArea::query()->where('admin_id', $admin_id)->value('area_id');
  175. $area_id = $area_id ?? 0;
  176. $yesterdayOrderNum = $yesterdayOrderNum->where('area_id', $area_id);
  177. $todayOrderNum = $todayOrderNum->where('area_id', $area_id);
  178. $yesterdayOrderRentNum = $yesterdayOrderRentNum->where('area_id', $area_id);
  179. $todayOrderRentNum = $todayOrderRentNum->where('area_id', $area_id);
  180. }
  181. }
  182. }
  183. // 昨日新订单数
  184. $yesterdayOrderNum = $yesterdayOrderNum
  185. ->where('pay_time', '>=', $yesterday)
  186. ->where('pay_time', '<=', $today)
  187. ->where('status', Order::STATUS_COMPLETE_ORDER)
  188. ->count('id');
  189. $yesterdayOrderRentNum = $yesterdayOrderRentNum
  190. ->where('pay_time', '>=', $yesterday)
  191. ->where('pay_time', '<=', $today)
  192. ->where('status', OrderRent::STATUS_COMPLETE_ORDER)
  193. ->count('id');
  194. // 今日新订单数
  195. $todayOrderNum = $todayOrderNum
  196. ->where('pay_time', '>=', $today)
  197. ->where('status', Order::STATUS_COMPLETE_ORDER)
  198. ->count('id');
  199. $todayOrderRentNum = $todayOrderRentNum
  200. ->where('pay_time', '>=', $today)
  201. ->where('status', OrderRent::STATUS_COMPLETE_ORDER)
  202. ->count('id');
  203. $orderDifference = (int)$todayOrderNum - (int)$yesterdayOrderNum;
  204. $orderRentDifference = (int)$todayOrderRentNum - (int)$yesterdayOrderRentNum;
  205. $orderDifference += $orderRentDifference;
  206. $totalOrder['new_num'] = $todayOrderNum + $todayOrderRentNum;
  207. if ($orderDifference < 0) {
  208. $totalOrder['diff'] = '1'; // 表示下降
  209. } elseif ($orderDifference === 0) {
  210. $totalOrder['diff'] = '2'; // 表示无变化
  211. } else {
  212. $totalOrder['diff'] = '3'; // 表示上升
  213. }
  214. $totalOrder['difference'] = abs($orderDifference);
  215. return $totalOrder;
  216. }
  217. // topIndex 头部统计数据 - 总用户
  218. protected function totalUser($area_id = '', $merchant_id = '')
  219. {
  220. $totalUser = [];
  221. $yesterday = Carbon::yesterday();
  222. $today = Carbon::today();
  223. // 管理员,并且选择了商户
  224. if (Admin::isAdministrator() && $merchant_id) {
  225. $yesterdayNewUser = User::query()->where('merchant_id', $merchant_id);
  226. $todayNewUser = User::query()->where('merchant_id', $merchant_id);
  227. $total = User::query()->where('merchant_id', $merchant_id);
  228. } else {
  229. $yesterdayNewUser = User::query()->where(AdminMerchant::getMerchantWhere());
  230. $todayNewUser = User::query()->where(AdminMerchant::getMerchantWhere());
  231. $total = User::query()->where(AdminMerchant::getMerchantWhere());
  232. }
  233. if (!empty($area_id)) {
  234. $yesterdayNewUser = $yesterdayNewUser->where('register_area_id', $area_id);
  235. $todayNewUser = $todayNewUser->where('register_area_id', $area_id);
  236. $total = $total->where('register_area_id', $area_id);
  237. } else {
  238. $admin_id = Admin::user()->id;
  239. if (!Admin::isAdministrator()) {
  240. $area_ids = AdminUser::getAreaIdsByAdminId($admin_id);
  241. if (count($area_ids) !== 0) {
  242. $yesterdayNewUser = $yesterdayNewUser->whereIn('register_area_id', $area_ids);
  243. $todayNewUser = $todayNewUser->whereIn('register_area_id', $area_ids);
  244. $total = $total->whereIn('register_area_id', $area_ids);
  245. } else {
  246. $area_id = AdminUserArea::query()->where('admin_id', $admin_id)->value('area_id');
  247. $area_id = $area_id ?? 0;
  248. $yesterdayNewUser = $yesterdayNewUser->where('register_area_id', $area_id);
  249. $todayNewUser = $todayNewUser->where('register_area_id', $area_id);
  250. $total = $total->where('register_area_id', $area_id);
  251. }
  252. }
  253. }
  254. //昨日新增用户数量
  255. $yesterdayNewUser = $yesterdayNewUser->where('created_at', '>=', $yesterday)->where('created_at', '<=', $today)->count('id');
  256. //今日新增用户数量
  257. $todayNewUser = $todayNewUser->where('created_at', '>=', $today)->count('id');
  258. //总用户数量
  259. $totalUser['total_num'] = $total->count('id');
  260. $userDifference = (int)$todayNewUser - (int)$yesterdayNewUser;
  261. if ($userDifference < 0) {
  262. $totalUser['diff'] = '1'; // 表示下降
  263. } elseif ($userDifference === 0) {
  264. $totalUser['diff'] = '2'; // 表示无变化
  265. } else {
  266. $totalUser['diff'] = '3'; // 表示上升
  267. }
  268. $totalUser['difference'] = abs($userDifference);
  269. return $totalUser;
  270. }
  271. // topIndex 头部统计数据 - 总订单
  272. protected function totalOrder($area_id = '', $merchant_id = '')
  273. {
  274. $totalOrder = [];
  275. // 管理员,并且选择了商户
  276. if (Admin::isAdministrator() && $merchant_id) {
  277. $total = Order::query()->where('merchant_id', $merchant_id);
  278. $totalOrderRent = OrderRent::query()->where('merchant_id', $merchant_id);
  279. } else {
  280. $total = Order::query()->where(AdminMerchant::getMerchantWhere());
  281. $totalOrderRent = OrderRent::query()->where(AdminMerchant::getMerchantWhere());
  282. }
  283. if (!empty($area_id)) {
  284. $total = $total->where('area_id', $area_id);
  285. $totalOrderRent = $totalOrderRent->where('area_id', $area_id);
  286. } else {
  287. $admin_id = Admin::user()->id;
  288. if (!Admin::isAdministrator()) {
  289. $area_ids = AdminUser::getAreaIdsByAdminId($admin_id);
  290. if (count($area_ids) !== 0) {
  291. $total = $total->whereIn('area_id', $area_ids);
  292. $totalOrderRent = $totalOrderRent->whereIn('area_id', $area_ids);
  293. } else {
  294. $area_id = AdminUserArea::query()->where('admin_id', $admin_id)->value('area_id');
  295. $area_id = $area_id ?? 0;
  296. $total = $total->where('area_id', $area_id);
  297. $totalOrderRent = $totalOrderRent->where('area_id', $area_id);
  298. }
  299. }
  300. }
  301. // 总订单数
  302. $total = $total->where('status', Order::STATUS_COMPLETE_ORDER)->count('id');
  303. $totalOrderRent = $totalOrderRent->where('status', OrderRent::STATUS_COMPLETE_ORDER)->count('id');
  304. $totalOrder['total_num'] = $total + $totalOrderRent;
  305. /**
  306. * 这个统计没有意义,新订单里已经有了,为了保持数据一致性,就默认写上这两个参数,
  307. * 后期前台可以屏蔽掉 - 同比昨日的显示
  308. */
  309. $totalOrder['diff'] = '2';
  310. $totalOrder['difference'] = 0;
  311. return $totalOrder;
  312. }
  313. /**
  314. * topIndex 头部统计数据 - 总收益 - 今天收益 = 纯收益 + 骑行卡
  315. * profitChart 总收益趋势 - 总收益 - 今天收益 = 纯收益 + 骑行卡
  316. */
  317. protected function todayProfit($area_id = '', $merchant_id = '', $type = 'top')
  318. {
  319. $totalProfit = 0;
  320. // 管理员,并且选择了商户
  321. if ($merchant_id) {
  322. $walletLogProfit = WalletLog::query()->where('merchant_id', $merchant_id);
  323. $changeProfit = WalletLog::query()->where('merchant_id', $merchant_id);
  324. $cardRidingOrdersProfit = CardRidingOrder::query()->where('merchant_id', $merchant_id);
  325. } else {
  326. if (Admin::isAdministrator()) {
  327. $walletLogProfit = WalletLog::query();
  328. $changeProfit = WalletLog::query();
  329. $cardRidingOrdersProfit = CardRidingOrder::query();
  330. } else {
  331. $walletLogProfit = WalletLog::query()->where(AdminMerchant::getMerchantWhere());
  332. $changeProfit = WalletLog::query()->where(AdminMerchant::getMerchantWhere());
  333. $cardRidingOrdersProfit = CardRidingOrder::query()->where(AdminMerchant::getMerchantWhere());
  334. }
  335. }
  336. if (!empty($area_id)) {
  337. $walletLogProfit = $walletLogProfit->where('area_id', $area_id);
  338. $changeProfit = $changeProfit->where('area_id', $area_id);
  339. $cardRidingOrdersProfit = $cardRidingOrdersProfit->where('area_id', $area_id);
  340. } else {
  341. $admin_id = Admin::user()->id;
  342. if (!Admin::isAdministrator()) {
  343. $area_ids = AdminUser::getAreaIdsByAdminId($admin_id);
  344. if (count($area_ids) !== 0) {
  345. $walletLogProfit = $walletLogProfit->whereIn('area_id', $area_ids);
  346. $changeProfit = $changeProfit->whereIn('area_id', $area_ids);
  347. $cardRidingOrdersProfit = $cardRidingOrdersProfit->whereIn('area_id', $area_ids);
  348. } else {
  349. $area_id = AdminUserArea::query()->where('admin_id', $admin_id)->value('area_id');
  350. $area_id = $area_id ?? 0;
  351. $walletLogProfit = $walletLogProfit->where('area_id', $area_id);
  352. $changeProfit = $changeProfit->where('area_id', $area_id);
  353. $cardRidingOrdersProfit = $cardRidingOrdersProfit->where('area_id', $area_id);
  354. }
  355. }
  356. }
  357. // $walletLogProfit;
  358. $walletLogProfit
  359. // ->whereIn('type', WalletLog::$subType) // 交易类型 - subType 存收益
  360. ->whereIn('type', WalletLog::$statisticsType)
  361. ->where('status', WalletLog::STATUS_OK); // 数据状态 - 有效
  362. $cardRidingOrdersProfit = $cardRidingOrdersProfit
  363. ->where('pay_type', CardRidingOrder::PAY_TYPE_WECHAT) // 支付方式 - 微信支付
  364. ->where('pay_status', CardRidingOrder::PAY_STATUS_OK) // 支付状态 - 支付成功
  365. ->where('status', CardRidingOrder::STATUS_OK); // 订单状态 - 成功
  366. if ($type == 'top') { // topIndex 头部统计数据
  367. // 纯收益
  368. // $walletLogProfitMoney = 0;
  369. $walletLogProfitMoney = $walletLogProfit
  370. ->where('created_at', '>=', Carbon::today())
  371. ->select(['area_id', 'money'])->sum('money');
  372. // foreach ($walletLogProfitData as $wv) {
  373. // // 加上充值收益
  374. // $total_money_all = WalletLog::query()
  375. // ->where('created_at', '>=', Carbon::today())
  376. // ->where('type', WalletLog::TYPE_ADD_WECHAT_TO_WALLET)
  377. // ->where('area_id', $wv['area_id'])
  378. // ->select(DB::raw('CAST(SUM(money) as DECIMAL(18,2)) as money_all'))->value('money_all');
  379. // $total_money_all = bcsub(0, $total_money_all, 2);
  380. // $wv['money'] = bcadd($wv['money'], $total_money_all, 2);
  381. //
  382. $change_money = $changeProfit->where('area_id', $area_id)->where('created_at', '>=', Carbon::today())->where('type', WalletLog::TYPE_ADD_WECHAT_TO_WALLET)->sum('money');
  383. $walletLogProfitMoney = bcadd($walletLogProfitMoney, $change_money, 2);
  384. // }
  385. // 骑行卡总收益
  386. $cardRidingOrdersProfitMoney = 0;
  387. $cardRidingOrdersProfitData = $cardRidingOrdersProfit
  388. ->where('pay_time', '>=', Carbon::today())->select('pay_money')->get()->toArray();
  389. // ->sum('pay_money');
  390. foreach ($cardRidingOrdersProfitData as $cv) {
  391. $cardRidingOrdersProfitMoney = bcadd($cardRidingOrdersProfitMoney, $cv['pay_money']);
  392. }
  393. $w = $walletLogProfitMoney ? abs($walletLogProfitMoney) : 0;
  394. $c = $cardRidingOrdersProfitMoney ? abs($cardRidingOrdersProfitMoney) : 0;
  395. $totalProfit = bcadd($w, $c, 2);
  396. return $totalProfit;
  397. } else { // profitChart 总收益趋势
  398. $data = [];
  399. // 口袋钱包纯收益
  400. $da = $this->buildDate($walletLogProfit, 'created_at', 'money');
  401. $da3 = $this->buildDate($cardRidingOrdersProfit);
  402. $data = [];
  403. foreach ($da as $k => $v) {
  404. foreach ($da3 as $k3 => $v3) {
  405. if ($k == $k3) {
  406. $m = bcadd($v, $v3, 2);
  407. $data[$k] = $m;
  408. }
  409. }
  410. if (!isset($data[$k])) {
  411. $data[$k] = $v['value'];
  412. }
  413. }
  414. return $data;
  415. }
  416. }
  417. /**
  418. * topIndex 头部统计数据
  419. * 总收益 - 统计本月 和 上月的总收益 总收益 + 骑行卡
  420. * 本月总收益包含当天收益(纯收益+骑行卡收益)
  421. */
  422. protected function totalProfitMonth($area_id = 0, $merchant_id = 0)
  423. {
  424. $WalletLog = WalletLog::query();
  425. if (!Admin::user()->inRoles([Admin::ROLE_JISHU_ADMIN])) {
  426. if ($merchant_id) {
  427. $WalletLog->where('merchant_id', $merchant_id);
  428. } else {
  429. $WalletLog->where(AdminMerchant::getMerchantWhere());
  430. }
  431. }
  432. if ($area_id) {
  433. $WalletLog->where('area_id', $area_id);
  434. }
  435. $money = $WalletLog->whereDate('created_at', '>=', Carbon::now()->firstOfMonth()->toDateString())->whereIn('type', WalletLog::$subType)->sum('money');
  436. $totalProfit['total_num'] = abs($money);
  437. return $totalProfit;
  438. }
  439. /**
  440. * todoEvent 待办事项 统计数据
  441. *
  442. * @param Request $request
  443. * @param BikeFilter $bikeFilter
  444. * @param OrderFilter $orderFilter
  445. * @param OrderRentFilter $orderRentFilter
  446. * @param WorkOrderFilter $workOrderFilter
  447. * @return \Illuminate\Http\JsonResponse
  448. * @author ht
  449. *
  450. */
  451. public function todoEvent(Request $request, BikeFilter $bikeFilter, OrderFilter $orderFilter, OrderRentFilter $orderRentFilter, WorkOrderFilter $workOrderFilter)
  452. {
  453. $area_id = $request->get('area_id') ?? '';
  454. if ($area_id) {
  455. $flag = $this->validateAreaId($area_id);
  456. if ($flag) return $this->error('无权限查看该区域');
  457. }
  458. $merchant_id = $request->get('merchant_id') ?? '';
  459. $data = [];
  460. // 管理员,并且选择了商户
  461. if (Admin::isAdministrator() && $merchant_id) {
  462. $data['low_battery_num'] = Bike::query()->where('merchant_id', $merchant_id)->filter($bikeFilter);
  463. $data['current_cycling_num'] = Order::query()->where('merchant_id', $merchant_id)->filter($orderFilter);
  464. $current_cycling_num_order_rent = OrderRent::query()->where('merchant_id', $merchant_id)->filter($orderRentFilter);
  465. $data['long_time_no_return_ridding'] = Order::query()->where('merchant_id', $merchant_id)->filter($orderFilter);
  466. $long_time_no_return_ridding_order_rent = OrderRent::query()->where('merchant_id', $merchant_id)->filter($orderRentFilter);
  467. $data['trouble_num'] = Bike::query()->where('merchant_id', $merchant_id)->filter($bikeFilter);
  468. $data['warning_num'] = WorkOrder::query()->where('merchant_id', $merchant_id)->where('type', WorkOrder::TYPE_ALERT)->filter($workOrderFilter);
  469. } else {
  470. $data['low_battery_num'] = Bike::query()->where(AdminMerchant::getMerchantWhere())->filter($bikeFilter);
  471. $data['current_cycling_num'] = Order::query()->where(AdminMerchant::getMerchantWhere())->filter($orderFilter);
  472. $current_cycling_num_order_rent = OrderRent::query()->where(AdminMerchant::getMerchantWhere())->filter($orderRentFilter);
  473. $data['long_time_no_return_ridding'] = Order::query()->where(AdminMerchant::getMerchantWhere())->filter($orderFilter);
  474. $long_time_no_return_ridding_order_rent = OrderRent::query()->where(AdminMerchant::getMerchantWhere())->filter($orderRentFilter);
  475. $data['trouble_num'] = Bike::query()->where(AdminMerchant::getMerchantWhere())->filter($bikeFilter);
  476. $data['warning_num'] = WorkOrder::query()->where(AdminMerchant::getMerchantWhere())->where('type', WorkOrder::TYPE_ALERT)->filter($workOrderFilter);
  477. }
  478. if (!empty($area_id)) {
  479. $data['low_battery_num'] = $data['low_battery_num']->where('put_area_id', $area_id);
  480. $data['current_cycling_num'] = $data['current_cycling_num']->where('area_id', $area_id);
  481. $current_cycling_num_order_rent = $current_cycling_num_order_rent->where('area_id', $area_id);
  482. $data['long_time_no_return_ridding'] = $data['long_time_no_return_ridding']->where('area_id', $area_id);
  483. $long_time_no_return_ridding_order_rent = $long_time_no_return_ridding_order_rent->where('area_id', $area_id);
  484. $data['trouble_num'] = $data['trouble_num']->where('put_area_id', $area_id);
  485. $data['warning_num'] = $data['warning_num']->where('area_id', $area_id);
  486. } else {
  487. $admin_id = Admin::user()->id;
  488. if (!Admin::isAdministrator()) {
  489. $area_ids = AdminUser::getAreaIdsByAdminId($admin_id);
  490. if (count($area_ids) !== 0) {
  491. $data['low_battery_num'] = $data['low_battery_num']->whereIn('put_area_id', $area_ids);
  492. $data['current_cycling_num'] = $data['current_cycling_num']->whereIn('area_id', $area_ids);
  493. $current_cycling_num_order_rent = $current_cycling_num_order_rent->whereIn('area_id', $area_ids);
  494. $data['long_time_no_return_ridding'] = $data['long_time_no_return_ridding']->whereIn('area_id', $area_ids);
  495. $long_time_no_return_ridding_order_rent = $long_time_no_return_ridding_order_rent->whereIn('area_id', $area_ids);
  496. $data['trouble_num'] = $data['trouble_num']->whereIn('put_area_id', $area_ids);
  497. $data['warning_num'] = $data['warning_num']->whereIn('area_id', $area_ids);
  498. } else {
  499. $area_id = AdminUserArea::query()->where('admin_id', $admin_id)->value('area_id');
  500. $area_id = $area_id ?? 0;
  501. $data['low_battery_num'] = $data['low_battery_num']->where('put_area_id', $area_id);
  502. $data['current_cycling_num'] = $data['current_cycling_num']->where('area_id', $area_id);
  503. $current_cycling_num_order_rent = $current_cycling_num_order_rent->where('area_id', $area_id);
  504. $data['long_time_no_return_ridding'] = $data['long_time_no_return_ridding']->where('area_id', $area_id);
  505. $long_time_no_return_ridding_order_rent = $long_time_no_return_ridding_order_rent->where('area_id', $area_id);
  506. $data['trouble_num'] = $data['trouble_num']->where('put_area_id', $area_id);
  507. $data['warning_num'] = $data['warning_num']->where('area_id', $area_id);
  508. }
  509. }
  510. }
  511. // 低电量车辆
  512. $data['low_battery_num'] = $data['low_battery_num']
  513. ->where('is_low_battery_power', Bike::BATTERY_POWER_LOW) // 低电量
  514. ->where('put_status', Bike::PUT_STATUS_YES) // 投放成功
  515. ->count('id');
  516. // 当前骑行车辆
  517. $data['current_cycling_num'] = $data['current_cycling_num']
  518. ->whereIn('status', [Order::STATUS_PAUSE_BIKE, Order::STATUS_RIDE_BIKE]) // 临时停车中 和 骑行中
  519. ->count('id');
  520. $current_cycling_num_order_rent = $current_cycling_num_order_rent
  521. ->where('status', OrderRent::STATUS_RENT_BIKE) // 租车中
  522. ->count('id');
  523. $data['current_cycling_num'] += $current_cycling_num_order_rent;
  524. // 24小时未还车 此处查询订单
  525. $data['long_time_no_return_ridding'] = $data['long_time_no_return_ridding']
  526. ->where(function ($q) {
  527. $q->where('status', Order::STATUS_PAUSE_BIKE)
  528. ->orWhere('status', Order::STATUS_RIDE_BIKE);
  529. })
  530. ->where('start_use_bike_time', '<=', date('Y-m-d H:i:s', strtotime('-1 days', time())))
  531. ->count('id');
  532. $long_time_no_return_ridding_order_rent = $long_time_no_return_ridding_order_rent
  533. ->where(function ($q) {
  534. $q->where('status', OrderRent::STATUS_RENT_BIKE);
  535. })
  536. ->where('start_use_bike_time', '<=', date('Y-m-d H:i:s', strtotime('-1 days', time())))
  537. ->count('id');
  538. $data['long_time_no_return_ridding'] += $long_time_no_return_ridding_order_rent;
  539. //故障车辆
  540. $data['trouble_num'] = $data['trouble_num']
  541. ->where('is_trouble', Bike::TROUBLE_YES) // 有故障
  542. ->count('id');
  543. // 报警信息
  544. $data['warning_num'] = $data['warning_num']
  545. ->where('status', WorkOrder::STATUS_NO) // 未确认
  546. ->count('id');
  547. return $this->ok($data);
  548. }
  549. /**
  550. * profitChart 总收益趋势
  551. *
  552. * @param Request $request
  553. * @param OrderFilter $orderFilter
  554. * @param RechargeOrderFilter $rechargeOrderFilter
  555. * @param CardRidingOrderFilter $cardRidingOrderFilter
  556. * @param DepositCardOrderFilter $depositCardOrderFilter
  557. * @param StatisticFilter $statisticFilter
  558. * @return \Illuminate\Http\JsonResponse
  559. * @author ht
  560. *
  561. */
  562. public function profitChart(Request $request, OrderFilter $orderFilter, RechargeOrderFilter $rechargeOrderFilter, CardRidingOrderFilter $cardRidingOrderFilter, DepositCardOrderFilter $depositCardOrderFilter, StatisticFilter $statisticFilter)
  563. {
  564. $area_id = $request->get('area_id') ?? '';
  565. if ($area_id) {
  566. $flag = $this->validateAreaId($area_id);
  567. if ($flag) return $this->error('无权限查看该区域');
  568. }
  569. $days = $request->get('days') ?? '';
  570. if (empty($days)) return $this->error('缺少参数');
  571. if (!in_array($days, ['today', 'threeDays', 'sevenDays', 'fifteenDays', 'thirtyDays'])) return $this->error('参数错误');
  572. $merchant_id = $request->get('merchant_id') ?? '';
  573. // 管理员,并且选择了商户
  574. if (Admin::isAdministrator() && $merchant_id) {
  575. $ordersChart = $this->profitPolygonalChart($request, $orderFilter, Order::query()->where('merchant_id', $merchant_id));
  576. $ordersDispatchMoneyChart = $this->profitPolygonalChart($request, $orderFilter, Order::query()->where('merchant_id', $merchant_id), 'dispatch_money');
  577. $rechargeOrdersChart = $this->profitPolygonalChart($request, $rechargeOrderFilter, RechargeOrder::query()->where('merchant_id', $merchant_id));
  578. $cardRidingOrdersChart = $this->profitPolygonalChart($request, $cardRidingOrderFilter, CardRidingOrder::query()->where('merchant_id', $merchant_id));
  579. $depositCardOrdersChart = $this->profitPolygonalChart($request, $depositCardOrderFilter, DepositCardOrder::query()->where('merchant_id', $merchant_id));
  580. $depositChart = $this->depositChart($request);
  581. } else {
  582. $ordersChart = $this->profitPolygonalChart($request, $orderFilter, Order::query()->where(AdminMerchant::getMerchantWhere()));
  583. $ordersDispatchMoneyChart = $this->profitPolygonalChart($request, $orderFilter, Order::query()->where(AdminMerchant::getMerchantWhere()), 'dispatch_money');
  584. $rechargeOrdersChart = $this->profitPolygonalChart($request, $rechargeOrderFilter, RechargeOrder::query()->where(AdminMerchant::getMerchantWhere()));
  585. $cardRidingOrdersChart = $this->profitPolygonalChart($request, $cardRidingOrderFilter, CardRidingOrder::query()->where(AdminMerchant::getMerchantWhere()));
  586. $depositCardOrdersChart = $this->profitPolygonalChart($request, $depositCardOrderFilter, DepositCardOrder::query()->where(AdminMerchant::getMerchantWhere()));
  587. $depositChart = $this->depositChart($request);
  588. }
  589. // 总收益 - 避免重复统计,这里计算只统计 口袋钱包纯收益
  590. $total = $this->totalProfitChart($request);
  591. $bikeDailyAverageChart = $this->bikeDailyAverage($request, $statisticFilter);
  592. return $this->ok([
  593. [
  594. 'name' => '普通订单收益',
  595. 'data' => $ordersChart
  596. ],
  597. [
  598. 'name' => '普通订单调度费收益',
  599. 'data' => $ordersDispatchMoneyChart
  600. ],
  601. [
  602. 'name' => '充值收益',
  603. 'data' => $rechargeOrdersChart
  604. ],
  605. [
  606. 'name' => '骑行卡收益',
  607. 'data' => $cardRidingOrdersChart
  608. ],
  609. [
  610. 'name' => '免押金卡收益',
  611. 'data' => $depositCardOrdersChart
  612. ],
  613. [
  614. 'name' => '总收益',
  615. 'data' => $total
  616. ],
  617. [
  618. 'name' => '日均车收益',
  619. 'data' => $bikeDailyAverageChart
  620. ],
  621. [
  622. 'name' => '押金收益',
  623. 'data' => $depositChart
  624. ]
  625. ]);
  626. }
  627. // profitChart 总收益趋势 - 押金收益(净押金) - 今天的押金收益(净收益) = 总押金 - 退回押金
  628. private function todayDeposit($area_id, $merchant_id, $type = '')
  629. {
  630. $DepositOrder = DepositOrder::query();
  631. if (!Admin::user()->inRoles([Admin::ROLE_JISHU_ADMIN])) {
  632. if ($merchant_id) {
  633. $DepositOrder->where('merchant_id', $merchant_id);
  634. } else {
  635. $DepositOrder->where(AdminMerchant::getMerchantWhere());
  636. }
  637. }
  638. if ($area_id) {
  639. $DepositOrder->where('area_id', $area_id);
  640. }
  641. $currentDayMoney = $DepositOrder->where('is_refund', DepositOrder::REFUND_NO)->where('pay_status', DepositOrder::PAY_STATUS_OK)->whereDate('pay_time', '>=', Carbon::now()->toDateString())->sum('money');
  642. $total = $currentDayMoney;
  643. $data[Carbon::now()->toDateString()] = $total;
  644. return ($type == 'total') ? $total : $data;
  645. }
  646. /**
  647. * profitChart 总收益趋势 - 押金收益(净押金)
  648. * 押金统计查询统计表,注意今天的押金统计是每小时统计的,直接查询数据表
  649. * 押金统计,筛选条件大于今天的时候,把今天的也包含进去
  650. */
  651. public function depositChart($request)
  652. {
  653. $days = $request->get('days') ?? '';
  654. $area_id = $request->get('area_id') ?? '';
  655. $merchant_id = $request->get('merchant_id') ?? '';
  656. // 管理员,并且选择了商户
  657. if (Admin::isAdministrator()) {
  658. if ($merchant_id) {
  659. $newOrders = Statistic::query()->where('merchant_id', $merchant_id)->where('slug', Statistic::SLUG_DEPOSIT_STATIC);
  660. } else {
  661. $newOrders = Statistic::query()->where('slug', Statistic::SLUG_DEPOSIT_STATIC);
  662. }
  663. } else {
  664. $newOrders = Statistic::query()->where(AdminMerchant::getMerchantWhere())->where('slug', Statistic::SLUG_DEPOSIT_STATIC);
  665. }
  666. if (!empty($area_id)) {
  667. $newOrders = $newOrders->where('area_id', $area_id);
  668. } else {
  669. // 平台的是 9999 商户的是 0
  670. if (Admin::isAdministrator()) {
  671. $newOrders = $newOrders->where('area_id', config('statistic.all'));
  672. } else {
  673. $newOrders = $newOrders->where('area_id', 0);
  674. }
  675. }
  676. switch ($days) {
  677. case 'today':
  678. // 因为今天的是统计每个小时的押金数据,直接查询押金表即可
  679. $newOrdersKeyVal = $this->todayDeposit($area_id, $merchant_id);
  680. // 为0得数组
  681. $i = Carbon::now()->format('H');
  682. $arr = [];
  683. for ($i; $i >= 0; $i--) {
  684. $str = Carbon::now()->subHours($i)->format('m-d H:00');
  685. $arr[$str] = 0;
  686. }
  687. //合并
  688. $merge = array_merge($arr, $newOrdersKeyVal);
  689. $data = [];
  690. foreach ($merge as $key => $value) {
  691. $data[] = ['date' => $key, 'value' => bcadd($value, 0, 2)];
  692. }
  693. break;
  694. case 'threeDays':
  695. $i = 2;
  696. break;
  697. case 'sevenDays':
  698. $i = 6;
  699. break;
  700. case 'fifteenDays':
  701. $i = 14;
  702. break;
  703. case 'thirtyDays':
  704. $i = 29;
  705. break;
  706. default:
  707. return $this->error('参数错误');
  708. }
  709. if ($days !== 'today') {
  710. $paramDays = Carbon::today()->subDays($i)->format('Y-m-d');
  711. // 赋值一个值为0得数组
  712. $arr = [];
  713. for ($i; $i >= 0; $i--) {
  714. $str = Carbon::today()->subDays($i)->format('Y/m/d');
  715. $arr[$str] = 0;
  716. }
  717. // 有数据得数组
  718. $newOrders = $newOrders->where('date', '>=', $paramDays)
  719. ->selectRaw("DATE_FORMAT(date,'%Y/%m/%d') as date,body")
  720. ->get()->toArray();
  721. $newOrdersKeyVal = [];
  722. if (!empty($newOrders)) {
  723. foreach ($newOrders as $v) {
  724. $body = json_decode($v['body'], true);
  725. $money_all = isset($body['money_all']) ? $body['money_all'] : 0;
  726. $money_refund_all = isset($body['money_refund_all']) ? $body['money_refund_all'] : 0;
  727. $val = bcsub($money_all, $money_refund_all, 2);
  728. if (isset($newOrdersKeyVal[$v['date']])) {
  729. $newOrdersKeyVal[$v['date']] = bcadd($newOrdersKeyVal[$v['date']], $val, 2);
  730. } else {
  731. $newOrdersKeyVal[$v['date']] = $val;
  732. }
  733. }
  734. }
  735. // 合并覆盖0
  736. $merge = array_merge($arr, $newOrdersKeyVal);
  737. // 重组结构
  738. $data = [];
  739. foreach ($merge as $ks => $vs) {
  740. $data[] = ['date' => $ks, 'value' => bcadd($vs, 0, 2)];
  741. }
  742. // 包含今天的统计
  743. $total = $this->todayDeposit($area_id, $merchant_id, 'total');
  744. $data[sizeof($data) - 1]['value'] = bcadd($total, 0, 2);
  745. }
  746. return $data;
  747. }
  748. // profitChart 总收益趋势- [普通订单收益,普通订单调度费收益,充值收益,骑行卡收益,免押金卡收益] 统计数据
  749. public function profitPolygonalChart($request, $filter, $model, $money = 'pay_money')
  750. {
  751. $area_id = $request->get('area_id') ?? '';
  752. $days = $request->get('days') ?? '';
  753. if (empty($days)) return $this->error('缺少参数');
  754. $newOrders = $model->filter($filter)->where('pay_status', 1); // 支付状态 1 已支付
  755. if (!empty($area_id)) {
  756. $newOrders = $newOrders->where('area_id', $area_id);
  757. } else {
  758. $admin_id = Admin::user()->id;
  759. if (!Admin::isAdministrator()) {
  760. $area_ids = AdminUser::getAreaIdsByAdminId($admin_id);
  761. if (count($area_ids) !== 0) {
  762. $newOrders = $newOrders->whereIn('area_id', $area_ids);
  763. } else {
  764. $area_id = AdminUserArea::query()->where('admin_id', $admin_id)->value('area_id');
  765. $area_id = $area_id ?? 0;
  766. $newOrders = $newOrders->where('area_id', $area_id);
  767. }
  768. }
  769. }
  770. // 去掉余额支付
  771. $newOrders = $newOrders->where('pay_type', 1);
  772. switch ($days) {
  773. case 'today':
  774. $today = Carbon::today();
  775. $newOrders = $newOrders->where('pay_time', '>=', $today)
  776. // ->selectRaw("DATE_FORMAT(pay_time,'%m-%d %H:00') as date,sum($money) as value")
  777. ->selectRaw("DATE_FORMAT(pay_time,'%m-%d %H:00') as date,CAST(SUM($money) as DECIMAL(18,2)) as value")
  778. ->groupBy('date')->get()->toArray();
  779. // 有数据得数组
  780. $newOrdersKeyVal = [];
  781. if (!empty($newOrders)) {
  782. foreach ($newOrders as $v) {
  783. $newOrdersKeyVal[$v['date']] = $v['value'];
  784. }
  785. }
  786. // 为0得数组
  787. $i = Carbon::now()->format('H');
  788. $arr = [];
  789. for ($i; $i >= 0; $i--) {
  790. $str = Carbon::now()->subHours($i)->format('m-d H:00');
  791. $arr[$str] = 0;
  792. }
  793. //合并
  794. $merge = array_merge($arr, $newOrdersKeyVal);
  795. $data = [];
  796. foreach ($merge as $key => $value) {
  797. $data[] = ['date' => $key, 'value' => $value];
  798. }
  799. break;
  800. case 'threeDays':
  801. $i = 2;
  802. break;
  803. case 'sevenDays':
  804. $i = 6;
  805. break;
  806. case 'fifteenDays':
  807. $i = 14;
  808. break;
  809. case 'thirtyDays':
  810. $i = 29;
  811. break;
  812. default:
  813. return $this->error('参数错误');
  814. }
  815. if ($days !== 'today') {
  816. $paramDays = Carbon::today()->subDays($i);
  817. // 赋值一个值为0得数组
  818. $arr = [];
  819. for ($i; $i >= 0; $i--) {
  820. $str = Carbon::today()->subDays($i)->format('Y/m/d');
  821. $arr[$str] = 0;
  822. }
  823. // 有数据得数组
  824. $newOrders = $newOrders->where('pay_time', '>=', $paramDays)
  825. ->selectRaw("DATE_FORMAT(pay_time,'%Y/%m/%d') as date,CAST(SUM($money) as DECIMAL(18,2)) as value")
  826. ->groupBy('date')->get()->toArray();
  827. $newOrdersKeyVal = [];
  828. if (!empty($newOrders)) {
  829. foreach ($newOrders as $v) {
  830. $newOrdersKeyVal[$v['date']] = $v['value'];
  831. }
  832. }
  833. // 合并覆盖0
  834. $merge = array_merge($arr, $newOrdersKeyVal);
  835. // 重组结构
  836. $data = [];
  837. foreach ($merge as $ks => $vs) {
  838. $data[] = ['date' => $ks, 'value' => $vs];
  839. }
  840. }
  841. return $data;
  842. }
  843. /**
  844. * profitChart 总收益趋势
  845. * 总收益统计查询统计表,注意今天的押金统计是每小时统计的,直接查询数据表
  846. * 总收益统计,筛选条件大于今天的时候,把今天的也包含进去
  847. */
  848. protected function totalProfitChart($request)
  849. {
  850. $area_id = $request->get('area_id') ?? '';
  851. $days = $request->get('days') ?? '';
  852. $merchant_id = $request->get('merchant_id') ?? '';
  853. // 管理员,并且选择了商户
  854. if (Admin::isAdministrator()) {
  855. if ($merchant_id) {
  856. $newOrders = Statistic::query()->where('merchant_id', $merchant_id)->where('slug', Statistic::SLUG_PROFIT_STATIC);
  857. } else {
  858. $newOrders = Statistic::query()->where('slug', Statistic::SLUG_PROFIT_STATIC);
  859. }
  860. } else {
  861. $newOrders = Statistic::query()->where(AdminMerchant::getMerchantWhere())->where('slug', Statistic::SLUG_PROFIT_STATIC);
  862. }
  863. if (!empty($area_id)) {
  864. $newOrders = $newOrders->where('area_id', $area_id);
  865. } else {
  866. // 平台的是 9999 商户的是 0
  867. if (Admin::isAdministrator()) {
  868. $newOrders = $newOrders->where('area_id', config('statistic.all'));
  869. } else {
  870. $newOrders = $newOrders->where('area_id', 0);
  871. }
  872. }
  873. switch ($days) {
  874. case 'today':
  875. // 因为今天的是统计每个小时的总数据,直接查询数据表即可
  876. $newOrdersKeyVal = $this->todayProfit($area_id, $merchant_id, 'all');
  877. // 为0得数组
  878. $i = Carbon::now()->format('H');
  879. $arr = [];
  880. for ($i; $i >= 0; $i--) {
  881. $str = Carbon::now()->subHours($i)->format('m-d H:00');
  882. $arr[$str] = 0;
  883. }
  884. //合并
  885. $merge = array_merge($arr, $newOrdersKeyVal);
  886. $data = [];
  887. foreach ($merge as $key => $value) {
  888. $data[] = ['date' => $key, 'value' => bcadd($value, 0, 2)];
  889. }
  890. break;
  891. case 'threeDays':
  892. $i = 2;
  893. break;
  894. case 'sevenDays':
  895. $i = 6;
  896. break;
  897. case 'fifteenDays':
  898. $i = 14;
  899. break;
  900. case 'thirtyDays':
  901. $i = 29;
  902. break;
  903. default:
  904. return $this->error('参数错误');
  905. }
  906. if ($days !== 'today') {
  907. $paramDays = Carbon::today()->subDays($i)->toDateString();
  908. // 赋值一个值为0得数组
  909. $arr = [];
  910. for ($i; $i >= 0; $i--) {
  911. $str = Carbon::today()->subDays($i)->format('Y/m/d');
  912. $arr[$str] = 0;
  913. }
  914. // 有数据得数组
  915. $newOrders = $newOrders->whereDate('date', '>=', $paramDays)->get()->toArray();
  916. $newOrdersKeyVal = [];
  917. if (!empty($newOrders)) {
  918. foreach ($newOrders as $v) {
  919. $body = json_decode($v['body'], true);
  920. $profit = isset($body['profit']) ? $body['profit'] : 0;
  921. $card_profit = isset($body['card_profit']) ? $body['card_profit'] : 0;
  922. $val = bcadd($profit, $card_profit, 2);
  923. $day = Carbon::parse($v['date'])->format("Y/m/d");
  924. if (isset($newOrdersKeyVal[$v['date']])) {
  925. $arr[$day] = bcadd($newOrdersKeyVal[$v['date']], $val, 2);
  926. // $newOrdersKeyVal[$v['date']] = bcadd($newOrdersKeyVal[$v['date']], $val, 2);
  927. } else {
  928. $arr[$day] = $val;
  929. // $newOrdersKeyVal[$v['date']] = $val;
  930. }
  931. }
  932. }
  933. // dd($arr);
  934. // 合并覆盖0
  935. // $merge = array_merge($arr, $newOrdersKeyVal);
  936. // 重组结构
  937. $data = [];
  938. foreach ($arr as $ks => $vs) {
  939. $data[] = ['date' => $ks, 'value' => bcadd($vs, 0, 2)];
  940. }
  941. // 包含今天的统计
  942. $total = $this->todayProfit($area_id, $merchant_id, 'top');
  943. $data[sizeof($data) - 1]['value'] = bcadd($total, 0, 2);
  944. }
  945. return $data;
  946. }
  947. // profitChart 总收益趋势 以特定的格式统计数据
  948. private function buildDate($newOrders, $time = 'pay_time', $money = 'pay_money')
  949. {
  950. $newOrdersTotal = $newOrders;
  951. $today = Carbon::today();
  952. $newOrders = $newOrders->where($time, '>=', $today)
  953. ->selectRaw("DATE_FORMAT($time,'%m-%d %H:00') as date,CAST(SUM($money) as DECIMAL(18,2)) as value")
  954. ->groupBy('date')->get()->toArray();
  955. // 有数据得数组
  956. $newOrdersKeyVal = [];
  957. if (!empty($newOrders)) {
  958. foreach ($newOrders as $v) {
  959. if ($time == 'created_at' && $money == 'pay_money') {
  960. // 加上充值收益
  961. $total_money_all = $newOrdersTotal
  962. ->where('created_at', '>=', $today)
  963. ->where('type', WalletLog::TYPE_ADD_WECHAT_TO_WALLET)
  964. ->select(DB::raw('CAST(SUM(money) as DECIMAL(18,2)) as money_all'))->value('money_all');
  965. $total_money_all = bcsub(0, $total_money_all, 2);
  966. $v['value'] = bcadd($v['value'], $total_money_all, 2);
  967. }
  968. $newOrdersKeyVal[$v['date']] = $v['value'];
  969. }
  970. }
  971. // 为0得数组
  972. $i = Carbon::now()->format('H');
  973. $arr = [];
  974. for ($i; $i >= 0; $i--) {
  975. $str = Carbon::now()->subHours($i)->format('m-d H:00');
  976. $arr[$str] = 0;
  977. }
  978. //合并
  979. $merge = array_merge($arr, $newOrdersKeyVal);
  980. return $merge;
  981. }
  982. // profitChart 总收益趋势 日均车收益
  983. private function bikeDailyAverage($request, $statisticFilter)
  984. {
  985. $area_id = $request->get('area_id') ?? '';
  986. $days = $request->get('days') ?? '';
  987. $merchant_id = $request->get('merchant_id') ?? '';
  988. // 管理员,并且选择了商户
  989. if (Admin::isAdministrator()) {
  990. if ($merchant_id) {
  991. $newOrders = Statistic::query()->where('merchant_id', $merchant_id)->filter($statisticFilter);
  992. } else {
  993. $newOrders = Statistic::query()->where('merchant_id', 0)->filter($statisticFilter);
  994. }
  995. } else {
  996. $newOrders = Statistic::query()->where(AdminMerchant::getMerchantWhere())->filter($statisticFilter);
  997. }
  998. if (!empty($area_id)) {
  999. $newOrders = $newOrders->where('area_id', $area_id);
  1000. } else {
  1001. // 平台的是 9999 商户的是 0
  1002. if (Admin::isAdministrator()) {
  1003. $newOrders = $newOrders->where('area_id', config('statistic.all'));
  1004. } else {
  1005. $newOrders = $newOrders->where('area_id', 0);
  1006. }
  1007. }
  1008. switch ($days) {
  1009. case 'today':
  1010. return [];
  1011. break;
  1012. case 'threeDays':
  1013. $i = 2;
  1014. break;
  1015. case 'sevenDays':
  1016. $i = 6;
  1017. break;
  1018. case 'fifteenDays':
  1019. $i = 14;
  1020. break;
  1021. case 'thirtyDays':
  1022. $i = 29;
  1023. break;
  1024. default:
  1025. return $this->error('参数错误');
  1026. }
  1027. if ($days !== 'today') {
  1028. $paramDays = Carbon::today()->subDays($i);
  1029. // 赋值一个值为0得数组
  1030. $arr = [];
  1031. for ($i; $i >= 0; $i--) {
  1032. $str = Carbon::today()->subDays($i)->format('Y/m/d');
  1033. $arr[$str] = 0;
  1034. }
  1035. // 有数据得数组
  1036. $newOrders = $newOrders->where('date', '>=', $paramDays)
  1037. ->where('slug', Statistic::SLUG_PROFIT_STATIC)
  1038. ->select(['date', 'body'])
  1039. ->orderByDesc('date')
  1040. ->get()
  1041. ->toArray();
  1042. $newOrdersKeyVal = [];
  1043. if (!empty($newOrders)) {
  1044. foreach ($newOrders as $v) {
  1045. $profit_statistics_arr = object_array(json_decode($v['body'], true));
  1046. $profit_arr_statistics['profit'] = $profit_statistics_arr['profit'] ?? 0;
  1047. $profit_arr_statistics['put_bikes'] = $profit_statistics_arr['put_bikes'] ?? 0;
  1048. if ($profit_arr_statistics['put_bikes'] == 0) {
  1049. $newOrdersKeyVal[Carbon::parse($v['date'])->format('Y/m/d')] = 0;
  1050. } else {
  1051. // $newOrdersKeyVal[Carbon::parse($v['date'])->format('Y/m/d')] = number_format($profit_arr_statistics['profit'] / $profit_arr_statistics['put_bikes'], 2);
  1052. $newOrdersKeyVal[Carbon::parse($v['date'])->format('Y/m/d')] = bcdiv($profit_arr_statistics['profit'], $profit_arr_statistics['put_bikes'], 2);
  1053. }
  1054. }
  1055. }
  1056. // 合并覆盖
  1057. $merge = array_merge($arr, $newOrdersKeyVal);
  1058. // 重组结构
  1059. $data = [];
  1060. foreach ($merge as $ks => $vs) {
  1061. $data[] = ['date' => $ks, 'value' => $vs];
  1062. }
  1063. }
  1064. return $data;
  1065. }
  1066. /**
  1067. * newUsersChart 新用户增长趋势
  1068. * @param Request $request
  1069. * @param UserFilter $userFilter
  1070. * @return \Illuminate\Http\JsonResponse
  1071. * @author ht
  1072. */
  1073. public function newUsersChart(Request $request, UserFilter $userFilter)
  1074. {
  1075. $area_id = $request->get('area_id') ?? '';
  1076. if ($area_id) {
  1077. $flag = $this->validateAreaId($area_id);
  1078. if ($flag) return $this->error('无权限查看该区域');
  1079. }
  1080. $days = $request->get('days') ?? '';
  1081. if (empty($days)) return $this->error('缺少参数');
  1082. if (!in_array($days, ['today', 'threeDays', 'sevenDays', 'fifteenDays', 'thirtyDays'])) return $this->error('参数错误');
  1083. $usersChart = $this->usersChart($request, $userFilter);
  1084. $usersChartDepositCard = $this->usersChart($request, $userFilter, true, User::DEPOSIT_CARD); // 免押金卡
  1085. $usersChartDepositMoney = $this->usersChart($request, $userFilter, true, User::DEPOSIT_MONEY); // 缴纳押金
  1086. return $this->ok([
  1087. ['name' => '每日增长用户数', 'data' => $usersChart],
  1088. ['name' => '每日增长用户(押金卡)', 'data' => $usersChartDepositCard],
  1089. ['name' => '每日增长用户(缴纳押金)', 'data' => $usersChartDepositMoney]
  1090. ]);
  1091. }
  1092. // 新用户增长趋势 统计数据
  1093. public function usersChart($request, $userFilter, $deposit = false, $deposit_type = User::DEPOSIT_MONEY)
  1094. {
  1095. $area_id = $request->get('area_id') ?? '';
  1096. $days = $request->get('days') ?? '';
  1097. $merchant_id = $request->get('merchant_id') ?? '';
  1098. // 管理员,并且选择了商户
  1099. if (Admin::isAdministrator() && $merchant_id) {
  1100. $newUsers = User::query()
  1101. ->where('merchant_id', $merchant_id)
  1102. ->filter($userFilter)
  1103. ->where('is_bind_mobile', User::BIND_MOBILE_OK); // 认证状态 - 已实名认证
  1104. } else {
  1105. $newUsers = User::query()
  1106. ->where(AdminMerchant::getMerchantWhere())
  1107. ->filter($userFilter)
  1108. ->where('is_bind_mobile', User::BIND_MOBILE_OK); // 认证状态 - 已实名认证
  1109. }
  1110. if ($deposit) {
  1111. $newUsers = $newUsers->where('deposit_type', $deposit_type);// 免押金卡 或 缴纳押金
  1112. }
  1113. if ($area_id) {
  1114. $newUsers = $newUsers->where('register_area_id', $area_id);
  1115. } else {
  1116. $admin_id = Admin::user()->id;
  1117. if (!Admin::isAdministrator()) {
  1118. $area_ids = AdminUser::getAreaIdsByAdminId($admin_id);
  1119. if (count($area_ids) !== 0) {
  1120. $newUsers = $newUsers->whereIn('register_area_id', $area_ids);
  1121. } else {
  1122. $area_id = AdminUserArea::query()->where('admin_id', $admin_id)->value('area_id');
  1123. $area_id = $area_id ?? 0;
  1124. $newUsers = $newUsers->where('register_area_id', $area_id);
  1125. }
  1126. }
  1127. }
  1128. $newOrders = $newUsers;
  1129. switch ($days) {
  1130. case 'today':
  1131. $today = Carbon::today();
  1132. $newOrders = $newOrders->where('created_at', '>=', $today)
  1133. ->selectRaw('DATE_FORMAT(created_at,"%m-%d %H:00") as date,count(id) as value')
  1134. ->groupBy('date')->get()->toArray();
  1135. // 有数据得数组
  1136. $newOrdersKeyVal = [];
  1137. if (!empty($newOrders)) {
  1138. foreach ($newOrders as $v) {
  1139. $newOrdersKeyVal[$v['date']] = $v['value'];
  1140. }
  1141. }
  1142. // 为0得数组
  1143. $i = Carbon::now()->format('H');
  1144. $arr = [];
  1145. for ($i; $i >= 0; $i--) {
  1146. $str = Carbon::now()->subHours($i)->format('m-d H:00');
  1147. $arr[$str] = 0;
  1148. }
  1149. //合并
  1150. $merge = array_merge($arr, $newOrdersKeyVal);
  1151. $data = [];
  1152. foreach ($merge as $key => $value) {
  1153. $data[] = ['date' => $key, 'value' => $value];
  1154. }
  1155. break;
  1156. case 'threeDays':
  1157. $i = 2;
  1158. break;
  1159. case 'sevenDays':
  1160. $i = 6;
  1161. break;
  1162. case 'fifteenDays':
  1163. $i = 14;
  1164. break;
  1165. case 'thirtyDays':
  1166. $i = 29;
  1167. break;
  1168. default:
  1169. return $this->error('参数错误');
  1170. }
  1171. if ($days !== 'today') {
  1172. $paramDays = Carbon::today()->subDays($i);
  1173. // 赋值一个值为0得数组
  1174. $arr = [];
  1175. for ($i; $i >= 0; $i--) {
  1176. $str = Carbon::today()->subDays($i)->format('Y/m/d');
  1177. $arr[$str] = 0;
  1178. }
  1179. // 有数据得数组
  1180. $newOrders = $newOrders->where('created_at', '>=', $paramDays)
  1181. ->selectRaw('DATE_FORMAT(created_at,"%Y/%m/%d") as date,count(id) as value')
  1182. ->groupBy('date')->get()->toArray();
  1183. $newOrdersKeyVal = [];
  1184. if (!empty($newOrders)) {
  1185. foreach ($newOrders as $v) {
  1186. $newOrdersKeyVal[$v['date']] = $v['value'];
  1187. }
  1188. }
  1189. // 合并覆盖0
  1190. $merge = array_merge($arr, $newOrdersKeyVal);
  1191. // 重组结构
  1192. $data = [];
  1193. foreach ($merge as $ks => $vs) {
  1194. $data[] = ['date' => $ks, 'value' => $vs];
  1195. }
  1196. }
  1197. return $data;
  1198. }
  1199. /**
  1200. * newOrderChart 新订单趋势 - 普通订单
  1201. * @param Request $request
  1202. * @param OrderFilter $orderFilter
  1203. * @return \Illuminate\Http\JsonResponse
  1204. * @author ht
  1205. */
  1206. public function newOrderChart(Request $request, OrderFilter $orderFilter)
  1207. {
  1208. $area_id = $request->get('area_id') ?? '';
  1209. if ($area_id) {
  1210. $flag = $this->validateAreaId($area_id);
  1211. if ($flag) return $this->error('无权限查看该区域');
  1212. }
  1213. $days = $request->get('days') ?? '';
  1214. if (empty($days)) return $this->error('缺少参数');
  1215. if (!in_array($days, ['today', 'threeDays', 'sevenDays', 'fifteenDays', 'thirtyDays'])) return $this->error('参数错误');
  1216. $newOrderChart = $this->orderChart($request, $orderFilter);
  1217. $dispatchMoneyNewOrderChart = $this->orderChart($request, $orderFilter, true);
  1218. return $this->ok([
  1219. ['name' => '总订单数', 'data' => $newOrderChart],
  1220. ['name' => '有调度费的订单数', 'data' => $dispatchMoneyNewOrderChart]
  1221. ]);
  1222. }
  1223. // 新订单趋势 统计数据 - 普通订单
  1224. public function orderChart($request, $orderFilter, $dispatch_money = false)
  1225. {
  1226. $area_id = $request->get('area_id') ?? '';
  1227. $days = $request->get('days') ?? '';
  1228. $merchant_id = $request->get('merchant_id') ?? '';
  1229. // 管理员,并且选择了商户
  1230. if (Admin::isAdministrator() && $merchant_id) {
  1231. $newOrders = Order::query()
  1232. ->where('merchant_id', $merchant_id)
  1233. ->filter($orderFilter)
  1234. ->where('status', Order::STATUS_COMPLETE_ORDER); // 订单完成
  1235. } else {
  1236. $newOrders = Order::query()
  1237. ->where(AdminMerchant::getMerchantWhere())
  1238. ->filter($orderFilter)
  1239. ->where('status', Order::STATUS_COMPLETE_ORDER); // 订单完成
  1240. }
  1241. if ($dispatch_money) {
  1242. $newOrders = $newOrders->where('dispatch_money', '>', 0); // 有调度费
  1243. }
  1244. if ($area_id) {
  1245. $newOrders = $newOrders->where('area_id', $area_id);
  1246. } else {
  1247. $admin_id = Admin::user()->id;
  1248. if (!Admin::isAdministrator()) {
  1249. $area_ids = AdminUser::getAreaIdsByAdminId($admin_id);
  1250. if (count($area_ids) !== 0) {
  1251. $newOrders = $newOrders->whereIn('area_id', $area_ids);
  1252. } else {
  1253. $area_id = AdminUserArea::query()->where('admin_id', $admin_id)->value('area_id');
  1254. $area_id = $area_id ?? 0;
  1255. $newOrders = $newOrders->where('area_id', $area_id);
  1256. }
  1257. }
  1258. }
  1259. switch ($days) {
  1260. case 'today':
  1261. $today = Carbon::today();
  1262. $newOrders = $newOrders->where('created_at', '>=', $today)
  1263. ->selectRaw('DATE_FORMAT(created_at,"%m-%d %H:00") as date,count(id) as value')
  1264. ->groupBy('date')->get()->toArray();
  1265. // 有数据得数组
  1266. $newOrdersKeyVal = [];
  1267. if (!empty($newOrders)) {
  1268. foreach ($newOrders as $v) {
  1269. $newOrdersKeyVal[$v['date']] = $v['value'];
  1270. }
  1271. }
  1272. // 为0得数组
  1273. $i = Carbon::now()->format('H');
  1274. $arr = [];
  1275. for ($i; $i >= 0; $i--) {
  1276. $str = Carbon::now()->subHours($i)->format('m-d H:00');
  1277. $arr[$str] = 0;
  1278. }
  1279. //合并
  1280. $merge = array_merge($arr, $newOrdersKeyVal);
  1281. $data = [];
  1282. foreach ($merge as $key => $value) {
  1283. $data[] = ['date' => $key, 'value' => $value];
  1284. }
  1285. break;
  1286. case 'threeDays':
  1287. $i = 2;
  1288. break;
  1289. case 'sevenDays':
  1290. $i = 6;
  1291. break;
  1292. case 'fifteenDays':
  1293. $i = 14;
  1294. break;
  1295. case 'thirtyDays':
  1296. $i = 29;
  1297. break;
  1298. default:
  1299. return [];
  1300. }
  1301. if ($days !== 'today') {
  1302. $paramDays = Carbon::today()->subDays($i);
  1303. // 赋值一个值为0得数组
  1304. $arr = [];
  1305. for ($i; $i >= 0; $i--) {
  1306. $str = Carbon::today()->subDays($i)->format('Y/m/d');
  1307. $arr[$str] = 0;
  1308. }
  1309. // 有数据得数组
  1310. $newOrders = $newOrders->where('created_at', '>=', $paramDays)
  1311. ->selectRaw('DATE_FORMAT(created_at,"%Y/%m/%d") as date,count(id) as value')
  1312. ->groupBy('date')->get()->toArray();
  1313. $newOrdersKeyVal = [];
  1314. if (!empty($newOrders)) {
  1315. foreach ($newOrders as $v) {
  1316. $newOrdersKeyVal[$v['date']] = $v['value'];
  1317. }
  1318. }
  1319. // 合并覆盖0
  1320. $merge = array_merge($arr, $newOrdersKeyVal);
  1321. // 重组结构
  1322. $data = [];
  1323. foreach ($merge as $ks => $vs) {
  1324. $data[] = ['date' => $ks, 'value' => $vs];
  1325. }
  1326. }
  1327. return $data;
  1328. }
  1329. /**
  1330. * newOrderChart 新订单趋势 - 日租订单
  1331. * @param Request $request
  1332. * @param OrderRentFilter $orderRentFilter
  1333. * @return \Illuminate\Http\JsonResponse
  1334. * @author ht
  1335. */
  1336. public function newDayRentOrderChart(Request $request, OrderRentFilter $orderRentFilter)
  1337. {
  1338. $area_id = $request->get('area_id') ?? '';
  1339. if ($area_id) {
  1340. $flag = $this->validateAreaId($area_id);
  1341. if ($flag) return $this->error('无权限查看该区域');
  1342. }
  1343. $days = $request->get('days') ?? '';
  1344. if (empty($days)) return $this->error('缺少参数');
  1345. if (!in_array($days, ['today', 'threeDays', 'sevenDays', 'fifteenDays', 'thirtyDays'])) return $this->error('参数错误');
  1346. $newOrderChart = $this->dayRentOrderChart($request, $orderRentFilter);
  1347. $dispatchMoneyNewOrderChart = $this->dayRentOrderChart($request, $orderRentFilter, true);
  1348. return $this->ok([
  1349. ['name' => '新增日租订单', 'data' => $newOrderChart],
  1350. ['name' => '新增日租订单(调度费大于0)', 'data' => $dispatchMoneyNewOrderChart]
  1351. ]);
  1352. }
  1353. // 新订单趋势 统计数据 - 日租订单
  1354. public function dayRentOrderChart($request, $orderRentFilter, $dispatch_money = false)
  1355. {
  1356. $area_id = $request->get('area_id') ?? '';
  1357. $days = $request->get('days') ?? '';
  1358. $merchant_id = $request->get('merchant_id') ?? '';
  1359. // 管理员,并且选择了商户
  1360. if (Admin::isAdministrator() && $merchant_id) {
  1361. $newOrders = OrderRent::query()
  1362. ->where('merchant_id', $merchant_id)
  1363. ->filter($orderRentFilter)
  1364. ->where('status', OrderRent::STATUS_COMPLETE_ORDER); // 已完成
  1365. } else {
  1366. $newOrders = OrderRent::query()
  1367. ->where(AdminMerchant::getMerchantWhere())
  1368. ->filter($orderRentFilter)
  1369. ->where('status', OrderRent::STATUS_COMPLETE_ORDER); // 已完成
  1370. }
  1371. if ($dispatch_money) {
  1372. $newOrders = $newOrders->where('dispatch_money', '>', 0); // 有调度费
  1373. }
  1374. if ($area_id) {
  1375. $newOrders = $newOrders->where('area_id', $area_id);
  1376. } else {
  1377. $admin_id = Admin::user()->id;
  1378. if (!Admin::isAdministrator()) {
  1379. $area_ids = AdminUser::getAreaIdsByAdminId($admin_id);
  1380. if (count($area_ids) !== 0) {
  1381. $newOrders = $newOrders->whereIn('area_id', $area_ids);
  1382. } else {
  1383. $area_id = AdminUserArea::query()->where('admin_id', $admin_id)->value('area_id');
  1384. $area_id = $area_id ?? 0;
  1385. $newOrders = $newOrders->where('area_id', $area_id);
  1386. }
  1387. }
  1388. }
  1389. switch ($days) {
  1390. case 'today':
  1391. $today = Carbon::today();
  1392. $newOrders = $newOrders->where('created_at', '>=', $today)
  1393. ->selectRaw('DATE_FORMAT(created_at,"%m-%d %H:00") as date,count(id) as value')
  1394. ->groupBy('date')->get()->toArray();
  1395. // 有数据得数组
  1396. $newOrdersKeyVal = [];
  1397. if (!empty($newOrders)) {
  1398. foreach ($newOrders as $v) {
  1399. $newOrdersKeyVal[$v['date']] = $v['value'];
  1400. }
  1401. }
  1402. // 为0得数组
  1403. $i = Carbon::now()->format('H');
  1404. $arr = [];
  1405. for ($i; $i >= 0; $i--) {
  1406. $str = Carbon::now()->subHours($i)->format('m-d H:00');
  1407. $arr[$str] = 0;
  1408. }
  1409. //合并
  1410. $merge = array_merge($arr, $newOrdersKeyVal);
  1411. $data = [];
  1412. foreach ($merge as $key => $value) {
  1413. $data[] = ['date' => $key, 'value' => $value];
  1414. }
  1415. break;
  1416. case 'threeDays':
  1417. $i = 2;
  1418. break;
  1419. case 'sevenDays':
  1420. $i = 6;
  1421. break;
  1422. case 'fifteenDays':
  1423. $i = 14;
  1424. break;
  1425. case 'thirtyDays':
  1426. $i = 29;
  1427. break;
  1428. default:
  1429. return [];
  1430. }
  1431. if ($days !== 'today') {
  1432. $paramDays = Carbon::today()->subDays($i);
  1433. // 赋值一个值为0得数组
  1434. $arr = [];
  1435. for ($i; $i >= 0; $i--) {
  1436. $str = Carbon::today()->subDays($i)->format('Y/m/d');
  1437. $arr[$str] = 0;
  1438. }
  1439. // 有数据得数组
  1440. $newOrders = $newOrders->where('created_at', '>=', $paramDays)
  1441. ->selectRaw('DATE_FORMAT(created_at,"%Y/%m/%d") as date,count(id) as value')
  1442. ->groupBy('date')->get()->toArray();
  1443. $newOrdersKeyVal = [];
  1444. if (!empty($newOrders)) {
  1445. foreach ($newOrders as $v) {
  1446. $newOrdersKeyVal[$v['date']] = $v['value'];
  1447. }
  1448. }
  1449. // 合并覆盖0
  1450. $merge = array_merge($arr, $newOrdersKeyVal);
  1451. // 重组结构
  1452. $data = [];
  1453. foreach ($merge as $ks => $vs) {
  1454. $data[] = ['date' => $ks, 'value' => $vs];
  1455. }
  1456. }
  1457. return $data;
  1458. }
  1459. /**
  1460. * riddingRanking 骑行排行榜 - 普通订单
  1461. * @param Request $request
  1462. * @param OrderFilter $orderFilter
  1463. * @return \Illuminate\Http\JsonResponse
  1464. * @author ht
  1465. */
  1466. public function riddingRanking(Request $request, OrderFilter $orderFilter)
  1467. {
  1468. $area_id = $request->get('area_id') ?? '';
  1469. if ($area_id) {
  1470. $flag = $this->validateAreaId($area_id);
  1471. if ($flag) return $this->error('无权限查看该区域');
  1472. }
  1473. $days = $request->get('days') ?? '';
  1474. if (empty($days)) return $this->error('缺少参数');
  1475. if (!in_array($days, ['today', 'sevenDays', 'oneMonth', 'sixMonth'])) return $this->error('参数错误');
  1476. $merchant_id = $request->get('merchant_id') ?? '';
  1477. // 管理员,并且选择了商户
  1478. if (Admin::isAdministrator() && $merchant_id) {
  1479. $order = Order::query()
  1480. ->where('merchant_id', $merchant_id)
  1481. ->filter($orderFilter)
  1482. ->where('status', Order::STATUS_COMPLETE_ORDER) // 订单完成
  1483. ->with(['users']);
  1484. } else {
  1485. $order = Order::query()
  1486. ->where(AdminMerchant::getMerchantWhere())
  1487. ->filter($orderFilter)
  1488. ->where('status', Order::STATUS_COMPLETE_ORDER) // 订单完成
  1489. ->with(['users']);
  1490. }
  1491. if ($area_id) {
  1492. $order = $order->where('area_id', $area_id);
  1493. } else {
  1494. $admin_id = Admin::user()->id;
  1495. if (!Admin::isAdministrator()) {
  1496. $area_ids = AdminUser::getAreaIdsByAdminId($admin_id);
  1497. if (count($area_ids) !== 0) {
  1498. $order = $order->whereIn('area_id', $area_ids);
  1499. } else {
  1500. $area_id = AdminUserArea::query()->where('admin_id', $admin_id)->value('area_id');
  1501. $area_id = $area_id ?? 0;
  1502. $order = $order->where('area_id', $area_id);
  1503. }
  1504. }
  1505. }
  1506. switch ($days) {
  1507. case 'today':
  1508. $today = Carbon::today();
  1509. $order = $order->where('created_at', '>=', $today);
  1510. break;
  1511. case 'sevenDays':
  1512. $time = Carbon::today()->subDays(7);
  1513. $order = $order->where('created_at', '>=', $time);
  1514. break;
  1515. case 'oneMonth':
  1516. $time = Carbon::today()->subMonth();
  1517. $order = $order->where('created_at', '>=', $time);
  1518. break;
  1519. case 'sixMonth':
  1520. $time = Carbon::today()->subMonths(6);
  1521. $order = $order->where('created_at', '>=', $time);
  1522. break;
  1523. default:
  1524. return $this->error('参数错误');
  1525. }
  1526. $order = $order
  1527. ->groupBy(['user_id'])
  1528. ->select('user_id', DB::raw('count(id) as total_num'))
  1529. ->orderByDesc('total_num')
  1530. ->get()
  1531. ->take(10);
  1532. $i = 0;
  1533. foreach ($order as &$v) {
  1534. $v['username'] = $v->users->nickname ?? '';
  1535. $v['phone'] = $v->users->mobile ?? '';
  1536. $v['ranking'] = ++$i;
  1537. // unset($v);
  1538. }
  1539. return $this->ok($order);
  1540. }
  1541. /**
  1542. * riddingRankingByDayRentOrder 骑行排行榜 - 日租订单
  1543. * @param Request $request
  1544. * @param OrderRentFilter $orderRentFilter
  1545. * @return \Illuminate\Http\JsonResponse
  1546. * @author ht
  1547. */
  1548. public function riddingRankingByDayRentOrder(Request $request, OrderRentFilter $orderRentFilter)
  1549. {
  1550. $area_id = $request->get('area_id') ?? '';
  1551. if ($area_id) {
  1552. $flag = $this->validateAreaId($area_id);
  1553. if ($flag) return $this->error('无权限查看该区域');
  1554. }
  1555. $days = $request->get('days') ?? '';
  1556. if (empty($days)) return $this->error('缺少参数');
  1557. if (!in_array($days, ['today', 'sevenDays', 'oneMonth', 'sixMonth'])) return $this->error('参数错误');
  1558. $merchant_id = $request->get('merchant_id') ?? '';
  1559. // 管理员,并且选择了商户
  1560. if (Admin::isAdministrator() && $merchant_id) {
  1561. $order = OrderRent::query()
  1562. ->where('merchant_id', $merchant_id)
  1563. ->filter($orderRentFilter)
  1564. ->where('status', OrderRent::STATUS_COMPLETE_ORDER) // 已完成
  1565. ->with(['users']);
  1566. } else {
  1567. $order = OrderRent::query()
  1568. ->where(AdminMerchant::getMerchantWhere())
  1569. ->filter($orderRentFilter)
  1570. ->where('status', OrderRent::STATUS_COMPLETE_ORDER) // 已完成
  1571. ->with(['users']);
  1572. }
  1573. if ($area_id) {
  1574. $order = $order->where('area_id', $area_id);
  1575. } else {
  1576. $admin_id = Admin::user()->id;
  1577. if (!Admin::isAdministrator()) {
  1578. $area_ids = AdminUser::getAreaIdsByAdminId($admin_id);
  1579. if (count($area_ids) !== 0) {
  1580. $order = $order->whereIn('area_id', $area_ids);
  1581. } else {
  1582. $area_id = AdminUserArea::query()->where('admin_id', $admin_id)->value('area_id');
  1583. $area_id = $area_id ?? 0;
  1584. $order = $order->where('area_id', $area_id);
  1585. }
  1586. }
  1587. }
  1588. switch ($days) {
  1589. case 'today':
  1590. $today = Carbon::today();
  1591. $order = $order->where('pay_time', '>=', $today);
  1592. break;
  1593. case 'sevenDays':
  1594. $time = Carbon::today()->subDays(7);
  1595. $order = $order->where('pay_time', '>=', $time);
  1596. break;
  1597. case 'oneMonth':
  1598. $time = Carbon::today()->subMonth();
  1599. $order = $order->where('pay_time', '>=', $time);
  1600. break;
  1601. case 'sixMonth':
  1602. $time = Carbon::today()->subMonths(6);
  1603. $order = $order->where('pay_time', '>=', $time);
  1604. break;
  1605. default:
  1606. return [];
  1607. }
  1608. $order = $order
  1609. ->groupBy(['user_id'])
  1610. ->select('user_id', DB::raw('count(id) as total_num'))
  1611. ->orderByDesc('total_num')
  1612. ->get()
  1613. ->take(10);
  1614. if (count($order) == 0) return $this->ok([]);
  1615. $i = 0;
  1616. foreach ($order as &$v) {
  1617. $v['username'] = $v->users->nickname ?? '';
  1618. $v['phone'] = $v->users->mobile ?? '';
  1619. $v['ranking'] = ++$i;
  1620. unset($v);
  1621. }
  1622. return $this->ok($order);
  1623. }
  1624. /**
  1625. * userPhoneChart 手机统计
  1626. * @param Request $request
  1627. * @return \Illuminate\Http\JsonResponse
  1628. * @author ht
  1629. */
  1630. public function userPhoneChart(Request $request)
  1631. {
  1632. $area_id = $request->get('area_id') ?? '';
  1633. if ($area_id) {
  1634. $flag = $this->validateAreaId($area_id);
  1635. if ($flag) return $this->error('无权限查看该区域');
  1636. }
  1637. $days = $request->get('days') ?? '';
  1638. if (empty($days)) return $this->error('缺少参数');
  1639. if (!in_array($days, ['today', 'sevenDays', 'oneMonth', 'sixMonth'])) return $this->error('参数错误');
  1640. $merchant_id = $request->get('merchant_id') ?? '';
  1641. // 管理员,并且选择了商户
  1642. if (Admin::isAdministrator() && $merchant_id) {
  1643. //platform 系统平台 [ios,android]
  1644. $platform = UserPhoneDetail::query()->where('merchant_id', $merchant_id);
  1645. $userPhone = UserPhoneDetail::query()->where('merchant_id', $merchant_id);
  1646. } else {
  1647. //platform 系统平台 [ios,android]
  1648. $platform = UserPhoneDetail::query()->where(AdminMerchant::getMerchantWhere());
  1649. $userPhone = UserPhoneDetail::query()->where(AdminMerchant::getMerchantWhere());
  1650. }
  1651. if (!empty($area_id)) {
  1652. $platform = $platform->whereHas('user', function ($q) use ($area_id) {
  1653. $q->where('register_area_id', $area_id);
  1654. });
  1655. $userPhone = $userPhone->whereHas('user', function ($q) use ($area_id) {
  1656. $q->where('register_area_id', $area_id);
  1657. });
  1658. } else {
  1659. $admin_id = Admin::user()->id;
  1660. if (!Admin::isAdministrator()) {
  1661. $area_ids = AdminUser::getAreaIdsByAdminId($admin_id);
  1662. if (count($area_ids) !== 0) {
  1663. $platform = $platform->whereHas('user', function ($q) use ($area_ids) {
  1664. $q->whereIn('register_area_id', $area_ids);
  1665. });
  1666. $userPhone = $userPhone->whereHas('user', function ($q) use ($area_ids) {
  1667. $q->whereIn('register_area_id', $area_ids);
  1668. });
  1669. } else {
  1670. $area_id = AdminUserArea::query()->where('admin_id', $admin_id)->value('area_id');
  1671. $area_id = $area_id ?? 0;
  1672. $platform = $platform->whereHas('user', function ($q) use ($area_id) {
  1673. $q->where('register_area_id', $area_id);
  1674. });
  1675. $userPhone = $userPhone->whereHas('user', function ($q) use ($area_id) {
  1676. $q->where('register_area_id', $area_id);
  1677. });
  1678. }
  1679. }
  1680. }
  1681. switch ($days) {
  1682. case 'today':
  1683. $param_days = Carbon::today();
  1684. break;
  1685. case 'threeDays':
  1686. $param_days = Carbon::today()->subDays(3);
  1687. break;
  1688. case 'sevenDays':
  1689. $param_days = Carbon::today()->subDays(7);
  1690. break;
  1691. case 'fifteenDays':
  1692. $param_days = Carbon::today()->subDays(15);
  1693. break;
  1694. case 'thirtyDays':
  1695. $param_days = Carbon::today()->subDays(30);
  1696. break;
  1697. case 'oneMonth':
  1698. $param_days = Carbon::today()->subDays(30);
  1699. break;
  1700. case 'sixMonth':
  1701. $param_days = Carbon::today()->subMonths(6);
  1702. break;
  1703. default:
  1704. return [];
  1705. }
  1706. // 饼图
  1707. $platform = $platform->where('created_at', '>', $param_days)
  1708. ->where('platform', '!=', 'devtools')
  1709. ->groupBy(['platform'])
  1710. ->select('platform', DB::raw('count(id) as value'))
  1711. ->get()
  1712. ->toArray();
  1713. // 列表
  1714. $userPhone = $userPhone->where('created_at', '>', $param_days)
  1715. ->groupBy(['model'])
  1716. ->select('model', DB::raw('count(id) as number'))
  1717. ->orderByDesc('number')
  1718. ->limit(10)
  1719. ->get()
  1720. ->toArray();
  1721. $total = UserPhoneDetail::query()->where(AdminMerchant::getMerchantWhere())->count('id');
  1722. if (!empty($platform)) {
  1723. foreach ($platform as &$v) {
  1724. $v['name'] = $v['platform'];
  1725. }
  1726. }
  1727. if (!empty($userPhone)) {
  1728. foreach ($userPhone as &$i) {
  1729. // $i['percent'] = (float)number_format($i['number'] / $total * 100, 2);
  1730. $i['percent'] = bcmul(bcdiv($i['number'], $total, 2), 100, 2);
  1731. }
  1732. }
  1733. return $this->ok(['platform' => $platform, 'userPhone' => $userPhone, 'total' => $total]);
  1734. }
  1735. /**
  1736. * bikeProfitRanking 车辆收益排行榜
  1737. *
  1738. * @param Request $request
  1739. * @param BikeFilter $bikeFilter
  1740. * @return \Illuminate\Http\JsonResponse
  1741. * @author ht
  1742. */
  1743. public function bikeProfitRanking(Request $request, BikeFilter $bikeFilter)
  1744. {
  1745. $area_id = $request->get('area_id') ?? '';
  1746. if ($area_id) {
  1747. $flag = $this->validateAreaId($area_id);
  1748. if ($flag) return $this->error('无权限查看该区域');
  1749. }
  1750. $merchant_id = $request->get('merchant_id') ?? '';
  1751. // 管理员,并且选择了商户
  1752. if (Admin::isAdministrator() && $merchant_id) {
  1753. $bikes = Bike::query()->where('merchant_id', $merchant_id)->filter($bikeFilter);
  1754. } else {
  1755. $bikes = Bike::query()->where(AdminMerchant::getMerchantWhere())->filter($bikeFilter);
  1756. }
  1757. if ($area_id) {
  1758. $bikes = $bikes->where('put_area_id', $area_id);
  1759. } else {
  1760. $admin_id = Admin::user()->id;
  1761. if (!Admin::isAdministrator()) {
  1762. $area_ids = AdminUser::getAreaIdsByAdminId($admin_id);
  1763. if (count($area_ids) !== 0) {
  1764. $bikes = $bikes->whereIn('put_area_id', $area_ids);
  1765. } else {
  1766. $area_id = AdminUserArea::query()->where('admin_id', $admin_id)->value('area_id');
  1767. $area_id = $area_id ?? 0;
  1768. $bikes = $bikes->where('put_area_id', $area_id);
  1769. }
  1770. }
  1771. }
  1772. /**
  1773. * todo
  1774. * 这里可以优化
  1775. * 因为是按照车辆日均收益进行排序的,而数据表里没有日均收益,
  1776. * 所以要全查询之后通过计算得出日均收益,再按照日均收益结果排序取前10条
  1777. * 但是这样的话有一个性能问题,数据表数量越大越影响性能,
  1778. * 所以目前先验证一下当前商户查询的数量是否大于一个值1500,大于的就按照总金额查询,这个数据不是很准确
  1779. *
  1780. * 优化思路:添加一个字段,用来存放日均收益,在统计总收益的时候,可以把日均收益也顺手统计一下
  1781. */
  1782. if ($bikes->count() > 1500) {
  1783. $bikes = $bikes->orderByDesc('total_money')->limit(10)->get();
  1784. } else {
  1785. $bikes = $bikes->get();
  1786. }
  1787. $data = [];
  1788. if (count($bikes) === 0) return $this->ok($data);
  1789. foreach ($bikes as $k => $v) {
  1790. // total_money_time 车辆总收入起始时间
  1791. $bike_insert_time = $v->total_money_time ? date('Y-m-d H:i:s', strtotime($v->total_money_time)) : date('Y-m-d H:i:s', strtotime($v->created_at));
  1792. $days = Carbon::today()->diffInDays($bike_insert_time);
  1793. $per_money = 0;
  1794. if ($days != 0) {
  1795. // $per_money = sprintf("%.2f", substr(sprintf("%.3f", ($v->total_money / $days)), 0, -2));
  1796. $per_money = bcdiv($v->total_money, $days, 2);
  1797. }
  1798. // $v['phone'] = $v->users->mobile ?? '';
  1799. $data[] = [
  1800. 'bike_no' => $v->bike_no ?? '',
  1801. 'put_days' => $days,
  1802. 'total_money' => $v->total_money,
  1803. 'per_money' => $per_money
  1804. ];
  1805. $volume[$k] = $per_money; // 排序依据
  1806. $edition[$k] = $v->bike_no ?? ''; // 排序人
  1807. // $v['ranking'] = ++$i;
  1808. unset($v);
  1809. }
  1810. array_multisort($volume, SORT_DESC, $edition, SORT_ASC, $data);
  1811. if (count($data) > 10) {
  1812. $res = array_slice($data, 0, 10);
  1813. } else {
  1814. $res = $data;
  1815. }
  1816. return $this->ok($res);
  1817. }
  1818. /**
  1819. * shareOutBonus 分红统计
  1820. *
  1821. * @param Request $request
  1822. * @return \Illuminate\Http\JsonResponse
  1823. * @author ht
  1824. */
  1825. public function shareOutBonus(Request $request)
  1826. {
  1827. $area_id = $request->get('area_id') ?? '';
  1828. if ($area_id) {
  1829. $flag = $this->validateAreaId($area_id);
  1830. if ($flag) return $this->error('无权限查看该区域');
  1831. }
  1832. $days = $request->get('days') ?? '';
  1833. if (empty($days)) return $this->error('缺少days参数');
  1834. // [当月=> current_month ,上月 =>last_month ,近一年 => almost_year]
  1835. if (!in_array($days, ['current_month', 'last_month', 'almost_year'])) return $this->error('参数错误');
  1836. $merchant_id = $request->get('merchant_id') ?? '';
  1837. // if (empty($merchant_id)) return $this->error('缺少merchant_id参数');
  1838. if ($merchant_id) {
  1839. /**
  1840. * 查询当月的可以查询 wallet_logs 这个表
  1841. * 查询上个月的查询 statistics
  1842. * 查询近一年的时候,本月之前的查询statistics,本月的还是查询wallet_logs
  1843. */
  1844. switch ($days) {
  1845. case 'current_month':
  1846. $data = $this->monthShare($merchant_id, $area_id);
  1847. break;
  1848. case 'last_month':
  1849. $data = $this->lastMonthShare($merchant_id, $area_id);
  1850. break;
  1851. case 'almost_year':
  1852. $data = $this->yearShare($merchant_id, $area_id);
  1853. break;
  1854. default:
  1855. return [];
  1856. }
  1857. } else {
  1858. $da = [];
  1859. // 没有商户,就统计所有的商户,避免每个商户的分成不一致,就循环统计,然后再合并
  1860. $marr = AdminMerchant::where('status', 1)->pluck('id')->toArray();
  1861. foreach ($marr as $v) {
  1862. /**
  1863. * 查询当月的可以查询 wallet_logs 这个表
  1864. * 查询上个月的查询 statistics
  1865. * 查询近一年的时候,本月之前的查询statistics,本月的还是查询wallet_logs
  1866. */
  1867. switch ($days) {
  1868. case 'current_month':
  1869. $da[] = $this->monthShare($v, $area_id);
  1870. break;
  1871. case 'last_month':
  1872. $da[] = $this->lastMonthShare($v, $area_id);
  1873. break;
  1874. case 'almost_year':
  1875. $da[] = $this->yearShare($v, $area_id);
  1876. break;
  1877. default:
  1878. return [];
  1879. }
  1880. }
  1881. $data = [];
  1882. // 合并数据
  1883. if (isset($da[0])) {
  1884. // foreach($da[0] as $k=>$v){
  1885. // foreach($da as $k1=>$v1){
  1886. // if($k1>0){
  1887. // foreach($v1 as $v2){
  1888. // if($v['date'] == $v2['date']){
  1889. // $data[] = [
  1890. // 'date' => $v['date'],
  1891. // 'value' => bcadd($v['value'],$v2['value'],2),
  1892. // 'share' => bcadd($v['share'],$v2['share'],2)
  1893. // ];
  1894. // }
  1895. // }
  1896. // }
  1897. // }
  1898. // }
  1899. // 优化foreach循环
  1900. $valueArr = [];
  1901. $shareArr = [];
  1902. foreach ($da as $v) {
  1903. $valueArr[] = array_column($v, 'value', 'date');
  1904. $shareArr[] = array_column($v, 'share', 'date');
  1905. }
  1906. // 获取所有的键值
  1907. $keyArr = array_keys($valueArr[0]);
  1908. $valueA = [];
  1909. $shareA = [];
  1910. foreach ($keyArr as $v) {
  1911. foreach ($valueArr as $v1) {
  1912. $valueA[$v][] = $v1[$v];
  1913. }
  1914. foreach ($shareArr as $v2) {
  1915. $shareA[$v][] = $v2[$v];
  1916. }
  1917. }
  1918. // 弃用 array_sum , 采用 bcadd
  1919. $i = 0;
  1920. foreach ($valueA as $k => $v) {
  1921. $value = 0.00;
  1922. foreach ($v as $v1) {
  1923. $value = bcadd($value, $v1, 2);
  1924. }
  1925. $data[$i] = [
  1926. 'date' => $k,
  1927. 'value' => $value
  1928. ];
  1929. $i++;
  1930. }
  1931. $i = 0;
  1932. foreach ($shareA as $k => $v) {
  1933. $share = 0.00;
  1934. foreach ($v as $v1) {
  1935. $share = bcadd($share, $v1, 2);
  1936. }
  1937. $data[$i]['share'] = $share;
  1938. $i++;
  1939. }
  1940. }
  1941. }
  1942. return $data;
  1943. }
  1944. // 当月分红 (纯收益 + 骑行卡收益) 乘以 商户分成比例
  1945. private function monthShare($merchant_id, $area_id)
  1946. {
  1947. // 管理员,并且选择了商户
  1948. if (Admin::isAdministrator() && $merchant_id) {
  1949. $walletLogProfit = WalletLog::query()->where('merchant_id', $merchant_id);
  1950. $cardRidingOrdersProfit = CardRidingOrder::query()->where('merchant_id', $merchant_id);
  1951. } else {
  1952. $walletLogProfit = WalletLog::query()->where(AdminMerchant::getMerchantWhere());
  1953. $cardRidingOrdersProfit = CardRidingOrder::query()->where(AdminMerchant::getMerchantWhere());
  1954. }
  1955. if (!empty($area_id)) {
  1956. $walletLogProfit = $walletLogProfit->where('area_id', $area_id);
  1957. $cardRidingOrdersProfit = $cardRidingOrdersProfit->where('area_id', $area_id);
  1958. } else {
  1959. $admin_id = Admin::user()->id;
  1960. if (!Admin::isAdministrator()) {
  1961. $area_ids = AdminUser::getAreaIdsByAdminId($admin_id);
  1962. if (count($area_ids) !== 0) {
  1963. $walletLogProfit = $walletLogProfit->whereIn('area_id', $area_ids);
  1964. $cardRidingOrdersProfit = $cardRidingOrdersProfit->whereIn('area_id', $area_ids);
  1965. } else {
  1966. $area_id = AdminUserArea::query()->where('admin_id', $admin_id)->value('area_id');
  1967. $area_id = $area_id ?? 0;
  1968. $walletLogProfit = $walletLogProfit->where('area_id', $area_id);
  1969. $cardRidingOrdersProfit = $cardRidingOrdersProfit->where('area_id', $area_id);
  1970. }
  1971. }
  1972. }
  1973. // 口袋钱包纯收益
  1974. $newOrders = $walletLogProfit
  1975. ->whereIn('type', WalletLog::$subType) // 交易类型 - subType 存收益
  1976. ->where('status', WalletLog::STATUS_OK); // 数据状态 - 有效
  1977. $now = Carbon::now();
  1978. $startTime = $now->firstOfMonth();
  1979. $endTime = $now->today()->format('Y-m-d H:i:s');
  1980. $i = (int)date('d') - 1;
  1981. // 赋值一个值为0得数组
  1982. $arr = [];
  1983. for ($i; $i >= 0; $i--) {
  1984. $str = Carbon::today()->subDays($i)->format('Y/m/d');
  1985. $arr[$str] = 0;
  1986. }
  1987. // 有数据得数组
  1988. $newOrders = $newOrders->whereBetween('created_at', [$startTime, $endTime])
  1989. ->selectRaw("DATE_FORMAT(created_at,'%Y/%m/%d') as date,sum(money) as value")
  1990. ->groupBy('date')->get()->toArray();
  1991. $newOrdersKeyVal = [];
  1992. if (!empty($newOrders)) {
  1993. foreach ($newOrders as $v) {
  1994. $newOrdersKeyVal[$v['date']] = abs($v['value']); // 数据表里的是负数,所以要取正
  1995. }
  1996. }
  1997. // 骑行卡收益
  1998. $cardNewOrders = $cardRidingOrdersProfit->whereBetween('pay_time', [$startTime, $endTime])
  1999. ->selectRaw("DATE_FORMAT(pay_time,'%Y/%m/%d') as date,sum(pay_money) as value")
  2000. ->groupBy('date')->get()->toArray();
  2001. if (!empty($cardNewOrders)) {
  2002. foreach ($cardNewOrders as $v) {
  2003. if (isset($newOrdersKeyVal[$v['date']])) {
  2004. $newOrdersKeyVal[$v['date']] = bcadd($newOrdersKeyVal[$v['date']], $v['value'], 2);
  2005. } else {
  2006. $newOrdersKeyVal[$v['date']] = $v['value'];
  2007. }
  2008. }
  2009. }
  2010. // 合并覆盖0
  2011. $merge = array_merge($arr, $newOrdersKeyVal);
  2012. // 重组结构
  2013. $data = [];
  2014. // 该商户的分红比例 proportion
  2015. $proportion = AdminMerchant::where('id', $merchant_id)->value('proportion');
  2016. $proportion = $proportion ? bcdiv($proportion, 100, 2) : 0.00;
  2017. foreach ($merge as $ks => $vs) {
  2018. $data[] = [
  2019. 'date' => $ks,
  2020. 'value' => bcadd($vs, 0, 2),
  2021. 'share' => bcmul($vs, $proportion, 2)
  2022. ];
  2023. }
  2024. return $data;
  2025. }
  2026. // 上月分红
  2027. private function lastMonthShare($merchant_id, $area_id)
  2028. {
  2029. // 管理员,并且选择了商户
  2030. if (Admin::isAdministrator()) {
  2031. if ($merchant_id) {
  2032. $newOrders = Statistic::query()->where('merchant_id', $merchant_id)->where('slug', Statistic::SLUG_PROFIT_STATIC);
  2033. } else {
  2034. $newOrders = Statistic::query()->where('merchant_id', 0)->where('slug', Statistic::SLUG_PROFIT_STATIC);
  2035. }
  2036. } else {
  2037. $newOrders = Statistic::query()->where(AdminMerchant::getMerchantWhere())->where('slug', Statistic::SLUG_PROFIT_STATIC);
  2038. }
  2039. // 区域
  2040. if (!empty($area_id)) {
  2041. $newOrders = $newOrders->where('area_id', $area_id);
  2042. } else {
  2043. // 平台的是 9999 商户的是 0
  2044. if (Admin::isAdministrator()) {
  2045. $newOrders = $newOrders->where('area_id', config('statistic.all'));
  2046. } else {
  2047. $newOrders = $newOrders->where('area_id', 0);
  2048. }
  2049. }
  2050. // 上月时间
  2051. $now = Carbon::now()->subMonth(1);
  2052. $startTime = $now->firstOfMonth()->format('Y-m-d');
  2053. $endTime = $now->lastOfMonth()->format('Y-m-d');
  2054. $i = (int)date('t', strtotime($endTime)) - 1;
  2055. // 赋值一个值为0得数组
  2056. $arr = [];
  2057. for ($i; $i >= 0; $i--) {
  2058. $str = $now->lastOfMonth()->subDays($i)->format('Y/m/d');
  2059. $arr[$str] = 0;
  2060. }
  2061. // 有数据得数组
  2062. $newOrders = $newOrders->whereBetween('date', [$startTime, $endTime])
  2063. ->selectRaw("DATE_FORMAT(date,'%Y/%m/%d') as date,body")
  2064. ->get()->toArray();
  2065. $newOrdersKeyVal = [];
  2066. $totalVal = [];
  2067. if (!empty($newOrders)) {
  2068. foreach ($newOrders as $v) {
  2069. $body = json_decode($v['body'], true);
  2070. // 分红
  2071. $val = (float)$body['share_out_bonus'];
  2072. if (isset($newOrdersKeyVal[$v['date']])) {
  2073. $newOrdersKeyVal[$v['date']] = bcadd($newOrdersKeyVal[$v['date']], $val, 2);
  2074. } else {
  2075. $newOrdersKeyVal[$v['date']] = $val;
  2076. }
  2077. //商户总收益
  2078. $total_val = (float)$body['profit'] + (float)$body['card_profit'];
  2079. if (isset($totalVal[$v['date']])) {
  2080. $totalVal[$v['date']] = bcadd($totalVal[$v['date']], $total_val, 2);
  2081. } else {
  2082. $totalVal[$v['date']] = $total_val;
  2083. }
  2084. }
  2085. }
  2086. // 合并覆盖0
  2087. $merge = array_merge($arr, $newOrdersKeyVal);
  2088. // 重组结构
  2089. $data = [];
  2090. foreach ($merge as $ks => $vs) {
  2091. $data[] = [
  2092. 'date' => $ks,
  2093. 'value' => isset($totalVal[$ks]) ? bcadd($totalVal[$ks], 0, 2) : 0.00,
  2094. 'share' => bcadd($vs, 0, 2)
  2095. ];
  2096. }
  2097. return $data;
  2098. }
  2099. // 近一年分红
  2100. private function yearShare($merchant_id, $area_id)
  2101. {
  2102. // 管理员,并且选择了商户
  2103. if (Admin::isAdministrator()) {
  2104. if ($merchant_id) {
  2105. $newOrders = Statistic::query()->where('merchant_id', $merchant_id)->where('slug', Statistic::SLUG_PROFIT_STATIC);
  2106. } else {
  2107. $newOrders = Statistic::query()->where('merchant_id', 0)->where('slug', Statistic::SLUG_PROFIT_STATIC);
  2108. }
  2109. } else {
  2110. $newOrders = Statistic::query()->where(AdminMerchant::getMerchantWhere())->where('slug', Statistic::SLUG_PROFIT_STATIC);
  2111. }
  2112. // 区域
  2113. if (!empty($area_id)) {
  2114. $newOrders = $newOrders->where('area_id', $area_id);
  2115. } else {
  2116. // 平台的是 9999 商户的是 0
  2117. if (Admin::isAdministrator()) {
  2118. $newOrders = $newOrders->where('area_id', config('statistic.all'));
  2119. } else {
  2120. $newOrders = $newOrders->where('area_id', 0);
  2121. }
  2122. }
  2123. $now = Carbon::now();
  2124. $startTime = $now->startOfYear()->format('Y-m-d');
  2125. $endTime = $now->endOfYear()->format('Y-m-d');
  2126. $i = (int)date('m') - 1;
  2127. // 赋值一个值为0得数组
  2128. $arr = [];
  2129. for ($i; $i >= 0; $i--) {
  2130. $str = Carbon::now()->subMonth($i)->format('Y/m');
  2131. $arr[$str] = 0;
  2132. }
  2133. // 有数据得数组
  2134. $newOrders = $newOrders->whereBetween('date', [$startTime, $endTime])
  2135. ->selectRaw("DATE_FORMAT(date,'%Y/%m') as date,body")
  2136. ->get()->toArray();
  2137. $newOrdersKeyVal = [];
  2138. $totalVal = [];
  2139. if (!empty($newOrders)) {
  2140. foreach ($newOrders as $v) {
  2141. $body = json_decode($v['body'], true);
  2142. $val = (float)$body['share_out_bonus'];
  2143. if (isset($newOrdersKeyVal[$v['date']])) {
  2144. $newOrdersKeyVal[$v['date']] = bcadd($newOrdersKeyVal[$v['date']], $val, 2);
  2145. } else {
  2146. $newOrdersKeyVal[$v['date']] = $val;
  2147. }
  2148. //商户总收益
  2149. $total_val = (float)$body['profit'] + (float)$body['card_profit'];
  2150. if (isset($totalVal[$v['date']])) {
  2151. $totalVal[$v['date']] = bcadd($totalVal[$v['date']], $total_val, 2);
  2152. } else {
  2153. $totalVal[$v['date']] = $total_val;
  2154. }
  2155. }
  2156. }
  2157. // 合并覆盖0
  2158. $merge = array_merge($arr, $newOrdersKeyVal);
  2159. // 重组结构
  2160. $data = [];
  2161. foreach ($merge as $ks => $vs) {
  2162. $data[] = [
  2163. 'date' => $ks,
  2164. 'value' => isset($totalVal[$ks]) ? bcadd($totalVal[$ks], 0, 2) : 0.00,
  2165. 'share' => bcadd($vs, 0, 2)
  2166. ];
  2167. }
  2168. return $data;
  2169. }
  2170. }