welcome.blade.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440
  1. @extends('admin.layout-content')
  2. @section('header')
  3. <script src="https://cdn.jsdelivr.net/npm/echarts@4.9.0/dist/echarts.min.js"></script>
  4. <style>
  5. .sg-top-card {
  6. color: #87888A;
  7. }
  8. .sg-top-card .layui-card-body {
  9. display: flex;
  10. align-items: center;
  11. justify-content: space-between;
  12. }
  13. .sg-top-card .sg-top-left {
  14. display: flex;
  15. align-items: flex-end;
  16. }
  17. .sg-top-card .sg-top-left .sg-name {
  18. margin-left: 30px;
  19. }
  20. .sg-top-card .sg-top-left .sg-avatar {
  21. width: 50px;
  22. height: 50px;
  23. }
  24. .sg-top-right .sg-list {
  25. display: flex;
  26. align-items: center;
  27. }
  28. .sg-top-right .sg-list .sg-item {
  29. text-align: center;
  30. }
  31. .sg-divider {
  32. border-left: 1px solid rgba(233, 233, 233, 100);
  33. height: 30px;
  34. }
  35. .sg-top-right .sg-list .sg-item {
  36. margin: 15px;
  37. }
  38. .sg-top-right .sg-list .sg-item .sg-name {
  39. margin-top: 15px;
  40. }
  41. .sg-top-right .sg-list .sg-item .sg-name span {
  42. font-size: 2rem;
  43. font-weight: bold;
  44. color: rgba(38, 38, 38, 100);
  45. }
  46. .sg-project-list {
  47. display: flex;
  48. flex-wrap: wrap;
  49. }
  50. .sg-project-list .sg-item {
  51. width: 33%;
  52. border-top: 1px solid #e9e9e9;
  53. border-right: 1px solid #e9e9e9;
  54. padding: 15px;
  55. box-sizing: border-box;
  56. }
  57. .sg-project-list .sg-item:nth-child(3n) {
  58. border-right-width: 0;
  59. }
  60. .sg-project-list .sg-item .sg-header,
  61. .sg-project-list .sg-item .sg-footer {
  62. display: flex;
  63. align-items: center;
  64. justify-content: space-between;
  65. }
  66. .sg-project-list .sg-item .sg-desp {
  67. margin: 15px 0;
  68. }
  69. .sg-project-list .sg-item .sg-footer {
  70. color: #87888A;
  71. }
  72. .sg-project-header {
  73. display: flex;
  74. align-items: center;
  75. justify-content: space-between;
  76. }
  77. .sg-project-header .sg-right {
  78. color: #1990FF;
  79. }
  80. .sg-quick-list {
  81. display: flex;
  82. align-items: center;
  83. justify-content: space-around;
  84. color: #101010;
  85. }
  86. .sg-quick-list .sg-quick-item .sg-icon,
  87. .sg-quick-list .sg-quick-item {
  88. display: flex;
  89. flex-direction: column;
  90. align-items: center;
  91. justify-content: center;
  92. }
  93. .sg-quick-list .sg-quick-item .sg-icon {
  94. border-radius: 50%;
  95. height: 50px;
  96. width: 50px;
  97. line-height: 50px;
  98. color: white;
  99. }
  100. .sg-quick-list .sg-quick-item .sg-name {
  101. margin-top: 10px;
  102. font-size: 0.8rem;
  103. }
  104. .sg-icon.sg-create {
  105. background: #3894FF;
  106. }
  107. .sg-icon.sg-draft {
  108. background: #85888E;
  109. }
  110. .sg-icon.sg-point {
  111. background: #E29836;
  112. }
  113. .sg-icon.sg-revise {
  114. background: #4CA3AD;
  115. }
  116. .sg-zone-list .sg-zone-item {
  117. display: flex;
  118. align-items: center;
  119. width: 100%;
  120. color: #505559;
  121. margin: 15px 0;
  122. }
  123. .sg-zone-list .sg-zone-item .sg-process-bar {
  124. background: #0095D8;
  125. height: 16px;
  126. border-radius: 8px;
  127. margin: 0 15px;
  128. }
  129. .sg-zone-list .sg-zone-item .sg-process {
  130. display: flex;
  131. align-items: center;
  132. }
  133. .sg-zone-list .sg-zone-item .sg-zone-name {
  134. width: 100px;
  135. }
  136. .sg-project-2-list {
  137. display: flex;
  138. flex-wrap: wrap;
  139. }
  140. .sg-project-2-list .sg-item {
  141. display: flex;
  142. align-items: center;
  143. justify-content: space-around;
  144. flex-direction: column;
  145. margin: 20px;
  146. padding: 20px;
  147. width: calc(50% - 40px);
  148. box-sizing: border-box;
  149. color: white;
  150. border-radius: 20px;
  151. }
  152. .sg-project-2-list .sg-item div:first-child {
  153. margin-bottom: 20px;
  154. }
  155. .sg-gray-bg {
  156. background: grey;
  157. }
  158. .sg-font-lg {
  159. font-size: 2rem;
  160. }
  161. #sg-search-form .layui-form-item .layui-inline {
  162. margin-bottom: 0;
  163. }
  164. </style>
  165. @endsection
  166. @section('content')
  167. <div class="sg-index-container">
  168. <div class="layui-card sg-top-card">
  169. <div class="layui-card-body">
  170. <div class="sg-top-left">
  171. <img src="/images/avatar.png" class="sg-avatar">
  172. <div class="sg-name">{{ $_user->name }}|管理员</div>
  173. </div>
  174. <div class="sg-top-right">
  175. <div class="sg-list">
  176. <div class="sg-item">
  177. <div class="sg-label">项目数</div>
  178. <div class="sg-name">
  179. <span>{{$total_project}}</span>
  180. </div>
  181. </div>
  182. <div class="sg-item">
  183. <div class="sg-divider"></div>
  184. </div>
  185. <div class="sg-item">
  186. <div class="sg-label">内部设备总数</div>
  187. <div class="sg-name">
  188. <span>{{$total_device}}</span>
  189. </div>
  190. </div>
  191. <div class="sg-item">
  192. <div class="sg-divider"></div>
  193. </div>
  194. <div class="sg-item">
  195. <div class="sg-label">累计花费总金额</div>
  196. <div class="sg-name">
  197. <span>{{$total_money}}</span>
  198. </div>
  199. </div>
  200. </div>
  201. </div>
  202. </div>
  203. </div>
  204. <div class="layui-row layui-col-space15">
  205. <div class="layui-col-xs12 layui-col-sm12 layui-col-md8">
  206. <div class="layui-card">
  207. <div class="layui-card-header" style="display: flex; align-items: center; justify-content: space-between">
  208. <div>项目数据一览图</div>
  209. <form class="layui-form" id="sg-search-form">
  210. <div class="layui-form-item layui-row" style="margin-bottom: 0">
  211. <div class="layui-inline">
  212. <div class="layui-input-inline">
  213. <select name="year">
  214. @foreach($year_options as $option)
  215. <option value="{{ $option['id'] }}" {{ $select_year == $option['id'] ? 'selected' : '' }}>{{ $option['name'] }}</option>
  216. @endforeach
  217. </select>
  218. </div>
  219. </div>
  220. <div class="layui-inline">
  221. <div class="layui-input-inline">
  222. <select name="month">
  223. @foreach($month_options as $option)
  224. <option value="{{ $option['id'] }}" {{ $select_month == $option['id'] ? 'selected' : '' }}>{{ $option['name'] }}</option>
  225. @endforeach
  226. </select>
  227. </div>
  228. </div>
  229. </div>
  230. </form>
  231. </div>
  232. <div class="layui-card-body">
  233. <div id="my-chart" style="width: 100%;height:400px;"></div>
  234. </div>
  235. </div>
  236. <div class="layui-card">
  237. <div class="layui-card-header">
  238. <div class="sg-project-header">
  239. <div class="sg-left">待授权用户</div>
  240. <a class="sg-right" href="/admin/UserAuth/index">全部待授权用户</a>
  241. </div>
  242. </div>
  243. <div class="layui-card-body">
  244. <div class="sg-list sg-project-list">
  245. @foreach($user_auths as $item)
  246. <a class="sg-item" href="/admin/UserAuth/index">
  247. <div class="sg-header">
  248. <h3 class="sg-name">
  249. <b>{{ $item->name }}</b>
  250. </h3>
  251. <span class="layui-badge layui-bg-orange">待授权</span>
  252. </div>
  253. <div class="sg-desp">{{ $item->remark }}</div>
  254. <div class="sg-footer">
  255. <div class="sg-zone">{{ $item->project ? $item->project->name : '' }}</div>
  256. <div class="sg-date">{{ substr($item->updated_at, 0, 10) }}</div>
  257. </div>
  258. </a>
  259. @endforeach
  260. </div>
  261. </div>
  262. </div>
  263. </div>
  264. <div class="layui-col-xs12 layui-col-sm12 layui-col-md4">
  265. <div class="layui-card">
  266. <div class="layui-card-header">快速开始 / 便捷导航</div>
  267. <div class="layui-card-body">
  268. <div class="sg-quick-list">
  269. <a class="sg-quick-item" href="/admin/UserAuth/index">
  270. <div class="sg-icon sg-create"><i class="iconfont iconbi"></i></div>
  271. <div class="sg-name">用户授权</div>
  272. </a>
  273. <a class="sg-quick-item" href="/admin/InnerDevice/index">
  274. <div class="sg-icon sg-draft"><i class="iconfont iconyouxiang"></i></div>
  275. <div class="sg-name">设备管理</div>
  276. </a>
  277. <a class="sg-quick-item" href="/admin/Project/index">
  278. <div class="sg-icon sg-point"><i class="iconfont iconxingxing"></i></div>
  279. <div class="sg-name">项目管理</div>
  280. </a>
  281. <a class="sg-quick-item" href="#">
  282. <div class="sg-icon sg-revise"><i class="iconfont iconduihao"></i></div>
  283. <div class="sg-name">尽情期待</div>
  284. </a>
  285. </div>
  286. </div>
  287. </div>
  288. <div class="layui-card">
  289. <div class="layui-card-header">用户人数</div>
  290. <div class="layui-card-body">
  291. <div class="sg-zone-list">
  292. <div class="sg-zone-item">
  293. <div class="sg-zone-name">注册总人数</div>
  294. <div class="sg-process">
  295. <div class="sg-process-bar" style="width: 100px"></div>
  296. <div class="sg-total">{{ $users_total }}个</div>
  297. </div>
  298. </div>
  299. <div class="sg-zone-item">
  300. <div class="sg-zone-name">待授权人数</div>
  301. <div class="sg-process">
  302. <div class="sg-process-bar" style="width: {{ $users_not_auth_total / $users_total * 100 }}px"></div>
  303. <div class="sg-total">{{ $users_not_auth_total }}个</div>
  304. </div>
  305. </div>
  306. </div>
  307. </div>
  308. </div>
  309. <div class="layui-card">
  310. <div class="layui-card-header">内部设备情况</div>
  311. <div class="layui-card-body">
  312. <div class="sg-project-2-list">
  313. <div class="sg-item sg-device-card sg-green-bg">
  314. <div>闲置</div>
  315. <div class="sg-font-lg">{{ $device_stat['free'] }}</div>
  316. </div>
  317. <div class="sg-item sg-device-card sg-red-bg">
  318. <div>在用</div>
  319. <div class="sg-font-lg">{{ $device_stat['using'] }}</div>
  320. </div>
  321. <div class="sg-item sg-device-card sg-orange-bg">
  322. <div>维修</div>
  323. <div class="sg-font-lg">{{ $device_stat['repair'] }}</div>
  324. </div>
  325. <div class="sg-item sg-device-card sg-gray-bg">
  326. <div>报废</div>
  327. <div class="sg-font-lg">{{ $device_stat['scrap'] }}</div>
  328. </div>
  329. </div>
  330. </div>
  331. </div>
  332. </div>
  333. </div>
  334. </div>
  335. @endsection
  336. @section('footer')
  337. <script>
  338. $(function() {
  339. layui.use(['table', 'layer'], function() {
  340. var form = layui.form,
  341. top_window = window;
  342. var myChart = echarts.init(document.getElementById('my-chart'));
  343. form.on('select()', function(){
  344. getChartData();
  345. });
  346. getChartData();
  347. function transformToJson(formData){
  348. var obj={};
  349. for (var i in formData) {
  350. obj[formData[i].name]=formData[i]['value'];
  351. }
  352. return obj;
  353. }
  354. function getChartData() {
  355. $.ajax({
  356. method: 'POST',
  357. url: '/admin/Project/getStat',
  358. headers: {
  359. 'X-CSRF-TOKEN': '{{ csrf_token() }}'
  360. },
  361. data: transformToJson($('#sg-search-form').serializeArray()),
  362. success: function (data) {
  363. if(data.status === 'success') {
  364. // console.log(data.data);
  365. updateChart(data.data);
  366. }
  367. },
  368. error: function () {
  369. }
  370. });
  371. }
  372. function updateChart(data) {
  373. // 指定图表的配置项和数据
  374. var option = {
  375. color: ['#71D4D4', '#C3B6E6'],
  376. legend: {
  377. data: ['订单数', '订单金额']
  378. },
  379. tooltip: {},
  380. xAxis: [
  381. {
  382. type: 'category',
  383. data: data['names']
  384. }
  385. ],
  386. yAxis: [{
  387. type: 'value',
  388. name: '订单数',
  389. splitLine: {
  390. show: false
  391. }
  392. }, {
  393. type: 'value',
  394. name: '订单金额',
  395. splitLine: {
  396. show: false
  397. }
  398. }],
  399. // Declare several bar series, each will be mapped
  400. // to a column of dataset.source by default.
  401. series: [
  402. {
  403. name: '订单数',
  404. type: 'bar',
  405. label: {
  406. show: true,
  407. position: 'top'
  408. },
  409. data: data.data[0]
  410. },
  411. {
  412. name: '订单金额',
  413. type: 'bar',
  414. label: {
  415. show: true,
  416. position: 'top'
  417. },
  418. yAxisIndex: 1,
  419. data: data.data[1]
  420. }
  421. ]
  422. };
  423. // 使用刚指定的配置项和数据显示图表。
  424. myChart.setOption(option);
  425. }
  426. });
  427. })
  428. </script>
  429. @endsection