Dashboard.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404
  1. <?php
  2. namespace app\admin\controller;
  3. use addons\fastchat\library\Chat;
  4. use app\admin\model\Admin;
  5. use app\admin\model\dynamic\Dynamic;
  6. use app\admin\model\massager\Comment;
  7. use app\admin\model\massager\Massager;
  8. use app\admin\model\massager\Visa;
  9. use app\admin\model\Order;
  10. use app\admin\model\profit\Bill;
  11. use app\admin\model\Store;
  12. use app\admin\model\system\Feedback;
  13. use app\admin\model\User;
  14. use app\admin\model\user\Wallet;
  15. use app\api\model\deposit\Record;
  16. use app\api\model\ThirdPayLog;
  17. use app\common\controller\Backend;
  18. use app\common\model\Attachment;
  19. use fast\Date;
  20. use think\Db;
  21. use think\Request;
  22. /**
  23. * 控制台
  24. * @icon fa fa-dashboard
  25. * @remark 用于展示当前系统中的统计数据、统计报表及重要实时数据
  26. */
  27. class Dashboard extends Backend
  28. {
  29. public function __construct(Request $request = null)
  30. {
  31. parent::__construct($request);
  32. $admin = $this->auth->getUserInfo();
  33. $this->view->assign([
  34. "areas" => (new \app\admin\model\Area())->findAreaByAdmin($admin),
  35. "area_code" => $request->param("area_code"),
  36. "daterange" => $request->param("daterange"),
  37. "admin_type" => $admin["type"]
  38. ]);
  39. }
  40. private function fetchWhere()
  41. {
  42. $admin = $this->auth->getUserInfo();
  43. if (!$admin)
  44. $this->error("error");
  45. $p_where = [];
  46. if (\E_ADMIN_TYPE::Store === $admin["type"]) {
  47. array_push($p_where, ["store_id", "=", $admin["store_id"]]);
  48. } else if (\E_ADMIN_TYPE::Agency === $admin["type"]) {
  49. array_push($p_where, ["city_code", "in", is_null($admin["city_codes"]) ? [] : explode(",", $admin["city_codes"])]);
  50. }
  51. return $p_where;
  52. }
  53. private function fmt_params(array $params)
  54. {
  55. $area_code = null;
  56. $daterange = [0, time()];
  57. if (isset($params["area_code"]) && $params["area_code"] > 0) {
  58. $area_code = $params["area_code"];
  59. }
  60. if (isset($params["daterange"]) && strlen($params["daterange"]) > 0) {
  61. $daterange = array_map(function ($data) {
  62. return strtotime($data);
  63. }, explode(" - ", $params["daterange"]));
  64. }
  65. return [
  66. "area_code" => $area_code,
  67. "daterange" => $daterange
  68. ];
  69. }
  70. /**
  71. * @param null $area_code
  72. * @return string|\think\response\Json
  73. * @throws \think\Exception
  74. * @throws \think\db\exception\DataNotFoundException
  75. * @throws \think\db\exception\ModelNotFoundException
  76. * @throws \think\exception\DbException
  77. */
  78. public function index()
  79. {
  80. $p_where = $this->fetchWhere();
  81. $rows = [
  82. ["available" => [\E_ADMIN_TYPE::Platform], "title" => "代理商申请", "num" => \app\admin\model\Agency::where("status", \E_BASE_STATUS::Checking)->count(), "url" => "/backstage.php/agency?ref=addtabs"],
  83. ["available" => [\E_ADMIN_TYPE::Platform, \E_ADMIN_TYPE::Agency], "title" => "球房申请", "num" => Store::where("status", \E_BASE_STATUS::Checking)->count(), "url" => "/backstage.php/store/store/index"],
  84. ["available" => [\E_ADMIN_TYPE::Platform, \E_ADMIN_TYPE::Agency], "title" => "系统投诉", "num" => Feedback::where([
  85. "type" => "complaint",
  86. "status" => \E_BASE_STATUS::Default
  87. ])->count(), "url" => "/backstage.php/system/feedback?ref=addtabs"],
  88. ["available" => [\E_ADMIN_TYPE::Platform, \E_ADMIN_TYPE::Agency], "title" => "申述订单", "num" => Order::where("is_appeal", 1)->where("status", "<>", \E_ORDER_STATUS::Finish)->count(), "url" => "/backstage.php/order/order?ref=addtabs"],
  89. ["available" => [\E_ADMIN_TYPE::Platform, \E_ADMIN_TYPE::Agency], "title" => "异地签证", "num" => Visa::where("status", \E_BASE_STATUS::Default)->count(), "url" => "/backstage.php/massager/visa?ref=addtabs"],
  90. ["available" => [\E_ADMIN_TYPE::Platform, \E_ADMIN_TYPE::Agency], "title" => "助教申请", "num" => Massager::where("status", \E_BASE_STATUS::Checking)->count(), "url" => "/backstage.php/massager/massager?ref=addtabs"],
  91. ["available" => [\E_ADMIN_TYPE::Platform, \E_ADMIN_TYPE::Agency], "title" => "助教评论申述", "num" => Comment::where(["allegedly" => 1, "allegedly_status" => \E_BASE_STATUS::Default])->count(), "url" => "/backstage.php/massager/comment?ref=addtabs"],
  92. ["available" => [\E_ADMIN_TYPE::Platform], "title" => "动态审核", "num" => Dynamic::where(["status" => \E_BASE_STATUS::Checking])->count(), "url" => "/backstage.php/dynamic/dynamic?ref=addtabs"],
  93. ["available" => [\E_ADMIN_TYPE::Platform], "title" => "动态评论审核", "num" => \app\admin\model\dynamic\Comment::where("status", \E_BASE_STATUS::Checking)->count(), "url" => "/backstage.php/dynamic/comment?ref=addtabs"],
  94. ["available" => [\E_ADMIN_TYPE::Platform], "title" => "提现审核", "num" => \app\admin\model\deposit\Record::where("apply_status", \E_BASE_STATUS::Default)->count(), "url" => "/backstage.php/deposit/record?ref=addtabs"],
  95. ["available" => [\E_ADMIN_TYPE::Platform, \E_ADMIN_TYPE::Agency, \E_ADMIN_TYPE::Store], "title" => "待服务订单", "num" => Order::where("status", "in", [
  96. \E_ORDER_STATUS::Purchase,
  97. ])->where(count($p_where) > 0 ? $p_where[0][0] : "id", count($p_where) > 0 ? $p_where[0][1] : ">", count($p_where) > 0 ? $p_where[0][2] : 0)
  98. ->where("store_id", ">", 0)
  99. ->count(), "url" => "/backstage.php/order/order?ref=addtabs"],
  100. ];
  101. $this->view->assign("rows", $rows);
  102. return $this->view->fetch();
  103. }
  104. public function wait()
  105. {
  106. $this->view->assign([
  107. "totaluser" => User::count(),
  108. "sevendnu" => User::whereTime('jointime', '-7 days')->count(),
  109. "totalmassger" => Massager::count(),
  110. "totalagency" => Admin::where(["type" => \E_IDENTITY_TYPE::Agency])->count(),
  111. "totalstore" => Store::count(),
  112. "totalorder" => Order::count(),
  113. "totaluserresiduemoney" => Wallet::sum("money") + Wallet::sum("give_money"),
  114. "totalmassagerresiduemoney" => \app\admin\model\massager\Wallet::sum("profit_amount"),
  115. "totalagencyresiduemoney" => Admin::where(["type" => \E_IDENTITY_TYPE::Agency])->sum("profit_amount"),
  116. "totalstoreresiduemoney" => Store::sum("profit_amount"),
  117. "channeltotaluser" => User::where("parent_id", ">", 0)->count()
  118. ]);
  119. return $this->view->fetch();
  120. }
  121. public function massager()
  122. {
  123. $fmt = $this->fmt_params(input());
  124. $area_code = $fmt["area_code"];
  125. $daterange = $fmt["daterange"];
  126. $where = ["city_code", $area_code ? "=" : ">", $area_code ? $area_code : 0];
  127. $this->view->assign([
  128. "totalmassger" => Massager::where($where[0], $where[1], $where[2])->where("createtime", "BETWEEN", join(",", $daterange))->count(),
  129. "goodcomment" => Comment::where($where[0], $where[1], $where[2])->where("star", ">=", 3)->where("createtime", "BETWEEN", join(",", $daterange))->count(),
  130. "negativecomment" => Comment::where($where[0], $where[1], $where[2])->where("star", "<=", 3)->where("createtime", "BETWEEN", join(",", $daterange))->count(),
  131. "totalmassagerresiduemoney" => \app\admin\model\massager\Wallet::sum("profit_amount"),
  132. "totalmassageruseresiduemoney" => Record::where([
  133. "apply_status" => 'pass',
  134. "deposit_status" => 'success'
  135. ])
  136. ->where("massager_id", ">", 0)
  137. ->where("createtime", "BETWEEN", join(",", $daterange))
  138. ->where($where[0], $where[1], $where[2])
  139. ->sum("deposit_amount"),
  140. "topbyworkduration" => Db::query("SELECT w . massager_id,m . `name`,SUM(w . duration) as total_duration
  141. FROM `ma_massager_work` w JOIN ma_massager m ON w . massager_id = m . id
  142. WHERE w . clock_in_time BETWEEN {$daterange[0]} and $daterange[1]
  143. and w . clock_off_time BETWEEN {$daterange[0]} and $daterange[1]
  144. and m . city_code {$where[1]} {$where[2]}
  145. GROUP BY
  146. w . massager_id
  147. ORDER BY
  148. total_duration DESC
  149. LIMIT 20"),
  150. "topbynegative" => Db::query("SELECT
  151. c . massager_id,
  152. m . `name`,
  153. count(*) as total_count
  154. FROM
  155. `ma_massager_comment` c
  156. JOIN ma_massager m ON c . massager_id = m . id
  157. WHERE c . updatetime BETWEEN {$daterange[0]} and $daterange[1]
  158. and m . city_code {$where[1]} {$where[2]}
  159. and c . negative = 1
  160. GROUP BY
  161. c . massager_id
  162. ORDER BY
  163. total_count DESC
  164. LIMIT 20"),
  165. ]);
  166. return $this->view->fetch();
  167. }
  168. public function agency()
  169. {
  170. $fmt = $this->fmt_params(input());
  171. $daterange = $fmt["daterange"];
  172. $this->view->assign([
  173. "totalagency" => Admin::where(["type" => \E_IDENTITY_TYPE::Agency])->where("createtime", "BETWEEN", join(',', $daterange))->count(),
  174. "totalagencyresiduemoney" => Admin::where("type", \E_IDENTITY_TYPE::Agency)->sum("profit_amount"),
  175. "totalagencyuseresiduemoney" => Record::where([
  176. "apply_status" => 'pass',
  177. "deposit_status" => 'success'
  178. ])
  179. ->where("agency_id", ">", 0)
  180. ->where("createtime", "BETWEEN", join(",", $daterange))
  181. ->sum("deposit_amount"),
  182. ]);
  183. return $this->view->fetch();
  184. }
  185. public function store()
  186. {
  187. $fmt = $this->fmt_params(input());
  188. $area_code = $fmt["area_code"];
  189. $daterange = $fmt["daterange"];
  190. $this->view->assign([
  191. "totalstore" => Store::count(),
  192. "totalstoreresiduemoney" => Store::sum("profit_amount"),
  193. "totalstoreuseresiduemoney" => Record::where([
  194. "apply_status" => 'pass',
  195. "deposit_status" => 'success'
  196. ])
  197. ->where("store_id", ">", 0)
  198. ->where("createtime", "BETWEEN", join(",", $daterange))
  199. ->sum("deposit_amount"),
  200. ]);
  201. return $this->view->fetch();
  202. }
  203. public function order()
  204. {
  205. $fmt = $this->fmt_params(input());
  206. $area_code = $fmt["area_code"];
  207. $daterange = $fmt["daterange"];
  208. $where = ["city_code", $area_code ? "=" : ">", $area_code ? $area_code : 0];
  209. $this->view->assign([
  210. "totalorder" => Order::where("status", "in", [
  211. \E_ORDER_STATUS::Purchase,
  212. \E_ORDER_STATUS::Proceed,
  213. \E_ORDER_STATUS::WaitFeedback
  214. , \E_ORDER_STATUS::Finish
  215. ])->where($where[0], $where[1], $where[2])
  216. ->where("createtime", "BETWEEN", join(",", $daterange))
  217. ->count(),
  218. "apptotalorder" => Order::where("status", "in", [
  219. \E_ORDER_STATUS::Purchase,
  220. \E_ORDER_STATUS::Proceed,
  221. \E_ORDER_STATUS::WaitFeedback
  222. , \E_ORDER_STATUS::Finish
  223. ])->where($where[0], $where[1], $where[2])
  224. ->where("createtime", "BETWEEN", join(",", $daterange))
  225. ->where("massager_id", ">", 0)
  226. ->count(),
  227. "storetotalorder" => Order::where("status", "in", [
  228. \E_ORDER_STATUS::Purchase,
  229. \E_ORDER_STATUS::Proceed,
  230. \E_ORDER_STATUS::WaitFeedback
  231. , \E_ORDER_STATUS::Finish
  232. ])->where($where[0], $where[1], $where[2])
  233. ->where("createtime", "BETWEEN", join(",", $daterange))
  234. ->where("store_id", ">", 0)
  235. ->count(),
  236. "totalchannlorder" => Order::where("status", "in", [
  237. \E_ORDER_STATUS::Purchase,
  238. \E_ORDER_STATUS::Proceed,
  239. \E_ORDER_STATUS::WaitFeedback
  240. , \E_ORDER_STATUS::Finish
  241. ])->where($where[0], $where[1], $where[2])
  242. ->where("channel_id", ">", 0)
  243. ->where("createtime", "BETWEEN", join(",", $daterange))
  244. ->count(),
  245. "totalturnover" => Order::where("status", "in", [
  246. \E_ORDER_STATUS::Purchase,
  247. \E_ORDER_STATUS::Proceed,
  248. \E_ORDER_STATUS::WaitFeedback
  249. , \E_ORDER_STATUS::Finish
  250. ])->where($where[0], $where[1], $where[2])
  251. ->where("createtime", "BETWEEN", join(",", $daterange))
  252. ->sum("total_real_amount"),
  253. "apptotalturnover" => Order::where("status", "in", [
  254. \E_ORDER_STATUS::Purchase,
  255. \E_ORDER_STATUS::Proceed,
  256. \E_ORDER_STATUS::WaitFeedback
  257. , \E_ORDER_STATUS::Finish
  258. ])->where($where[0], $where[1], $where[2])
  259. ->where("createtime", "BETWEEN", join(",", $daterange))
  260. ->where("massager_id", ">", 0)
  261. ->sum("total_real_amount"),
  262. "storetotalturnover" => Order::where("status", "in", [
  263. \E_ORDER_STATUS::Purchase,
  264. \E_ORDER_STATUS::Proceed,
  265. \E_ORDER_STATUS::WaitFeedback,
  266. \E_ORDER_STATUS::Finish
  267. ])->where($where[0], $where[1], $where[2])
  268. ->where("createtime", "BETWEEN", join(",", $daterange))
  269. ->where("store_id", ">", 0)
  270. ->sum("total_real_amount"),
  271. ]);
  272. return $this->view->fetch();
  273. }
  274. public function finance()
  275. {
  276. $fmt = $this->fmt_params(input());
  277. $area_code = $fmt["area_code"];
  278. $daterange = $fmt["daterange"];
  279. $where = ["city_code", $area_code ? "=" : ">", $area_code ? $area_code : 0];
  280. // 开通会员订单金额
  281. $vip_amount = ThirdPayLog::where([
  282. "reason" => "充值会员",
  283. "status" => \E_BASE_STATUS::Normal
  284. ])
  285. ->where("createtime", "BETWEEN", join(",", $daterange))
  286. ->sum("amount");
  287. $record = \db()->query("
  288. SELECT
  289. SUM( `change` ) AS tp_sum
  290. FROM
  291. `ma_massager_bill`
  292. WHERE
  293. `createtime` BETWEEN {$daterange[0]}
  294. AND {$daterange[1]}
  295. AND `change_type` = '102'
  296. AND `currency_type` = 'money'
  297. LIMIT 1
  298. ");
  299. $trip_amount = $record[0]["tp_sum"] ?? 0;
  300. $this->view->assign([
  301. "total_order_amount" => $this->order_amount($where, $daterange),
  302. "total_app_amount" => $this->order_amount($where, $daterange, ["massager_id", ">", 0]),
  303. "total_store_amount" => $this->order_amount($where, $daterange, ["massager_id", "=", null]),
  304. "total_trip_amount" => $trip_amount,
  305. "total_vip_amount" => $vip_amount,
  306. "platform_profit_amount" => $this->profit_amount($where, $daterange, \E_IDENTITY_TYPE::Platform),
  307. "agency_profit_amount" => $this->profit_amount($where, $daterange, \E_IDENTITY_TYPE::Agency),
  308. "store_profit_amount" => $this->profit_amount($where, $daterange, \E_IDENTITY_TYPE::Store),
  309. "massager_profit_amount" => $this->profit_amount($where, $daterange, \E_IDENTITY_TYPE::Massager) + $this->profit_amount($where, $daterange, \E_IDENTITY_TYPE::Massager, \E_PROFIT_BILL_CHANGE_TYPE::ChannelExpend),
  310. "platform_invite_profit_amount" => $this->profit_amount($where, $daterange, \E_IDENTITY_TYPE::Platform, \E_PROFIT_BILL_CHANGE_TYPE::ChannelIncome),
  311. "user_invite_profit_amount" => $this->profit_amount($where, $daterange, \E_IDENTITY_TYPE::User, \E_PROFIT_BILL_CHANGE_TYPE::ChannelIncome),
  312. "profit_deduction_amount" => Order::where("createtime", "BETWEEN", join(",", $daterange))
  313. ->where($where[0],$where[1],$where[2])
  314. ->where("payment_type", "<>", \E_ORDER_PAY_TYPE::Balance)
  315. ->sum('balance_deduction'),
  316. "user_profit_amount" => Record::where("createtime", "BETWEEN", join(",", $daterange))
  317. ->where([
  318. "identity_type" => \E_IDENTITY_TYPE::User,
  319. "apply_status" => "pass",
  320. "deposit_status" => "success"
  321. ])->sum("deposit_amount")
  322. ]);
  323. return $this->view->fetch();
  324. }
  325. private function profit_amount($where, $daterange, $identity_type, $change_type = \E_PROFIT_BILL_CHANGE_TYPE::Profit)
  326. {
  327. $record = \db()->query("
  328. SELECT
  329. SUM( `change` ) AS tp_sum
  330. FROM
  331. `ma_profit_bill`
  332. WHERE
  333. {$where[0]} {$where[1]} {$where[2]}
  334. AND `createtime` BETWEEN {$daterange[0]}
  335. AND {$daterange[1]}
  336. AND `change_type` = '{$change_type}'
  337. AND `identity_type` = '{$identity_type}'
  338. LIMIT 1
  339. ");
  340. return $record[0]["tp_sum"] ?? 0;
  341. }
  342. private function order_amount($where, $daterange, $Q = [])
  343. {
  344. // 总订单金额
  345. $q_1 = Order::where("status", "in", [
  346. \E_ORDER_STATUS::Finish
  347. ])->where($where[0], $where[1], $where[2])
  348. ->where("createtime", "BETWEEN", join(",", $daterange));
  349. if (count($Q) > 0)
  350. $q_1->where($Q[0], $Q[1], $Q[2]);
  351. $totalOrderAmount = $q_1->sum("total_real_amount");
  352. // 退款金额
  353. $q_2 = Order::where("status", "in", [
  354. \E_ORDER_STATUS::Finish
  355. ])->where($where[0], $where[1], $where[2])
  356. ->where([
  357. "is_appeal" => 1
  358. ])
  359. ->where("createtime", "BETWEEN", join(",", $daterange));
  360. if (count($Q) > 0)
  361. $q_2->where($Q[0], $Q[1], $Q[2]);
  362. $totalOrderRefundAmount = $q_2
  363. ->sum("refund_amount");
  364. // 出行费退款金额
  365. $q_3 = Order::where("status", "in", [
  366. \E_ORDER_STATUS::Finish
  367. ])->where($where[0], $where[1], $where[2])
  368. // ->where([
  369. // "is_refund_trip" => 1,
  370. // "is_appeal" => 1
  371. // ])
  372. ->where("createtime", "BETWEEN", join(",", $daterange));
  373. if (count($Q) > 0)
  374. $q_3->where($Q[0], $Q[1], $Q[2]);
  375. $totalOrderTripAmount = $q_3
  376. ->sum("trip_amount");
  377. return $totalOrderAmount - $totalOrderRefundAmount - $totalOrderTripAmount;
  378. }
  379. }