index.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596
  1. <?php
  2. // 数据概况
  3. ?>
  4. <div id="app">
  5. <el-card v-loading="loading" shadow="never" style="border:0;min-width: 800px;" body-style="padding: 10px 0 0;">
  6. <div class="flex text-sm justify-between align-center" slot="header">
  7. <div>
  8. <span class="text-bold">画册数据明细</span>
  9. <span>时间筛选</span>
  10. <el-date-picker @change="dateChanged" value-format="yyyy-MM-dd" v-model="dateline" size="small" type="daterange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期">
  11. </el-date-picker>
  12. </div>
  13. <div>
  14. <el-date-picker size="small" :disabled="true" :value="Date.now()" type="date" placeholder="选择日期">
  15. </el-date-picker>
  16. <el-button size="small" @click="navBack()">返回</el-button>
  17. </div>
  18. </div>
  19. <div class="flex justify-between">
  20. <div ref="visit_chart" class="flex-sub padding-top-xs visit_chart margin-right radius ">
  21. </div>
  22. <div ref="pay_chart" class="flex-sub pay_chart padding-top-xs radius ">
  23. </div>
  24. </div>
  25. <div class="flex">
  26. <div ref="album_chart" class="album_chart padding-top-xs flex-sub radius margin-top"></div>
  27. </div>
  28. <div class="data-tab">
  29. <h3>画册分析</h3>
  30. <el-table header-row-class-name="header-cell" :data="album_stat.list">
  31. <el-table-column align="center" prop="id" label="画册ID"></el-table-column>
  32. <el-table-column align="center" prop="title" width="100" label="画册名称"></el-table-column>
  33. <el-table-column align="center" prop="goods_count" width="100" label="商品数"></el-table-column>
  34. <el-table-column align="center" prop="statistics.stop_time" label="停留时长"></el-table-column>
  35. <el-table-column align="center" prop="statistics.shares_count" label="分享次数"></el-table-column>
  36. <el-table-column align="center" prop="statistics.pay_count" label="支付人数"></el-table-column>
  37. <el-table-column align="center" prop="statistics.order_count" label="支付单数"></el-table-column>
  38. <el-table-column align="center" prop="statistics.goods_amount" label="支付金额"></el-table-column>
  39. </el-table>
  40. <div style="text-align: right;margin: 20px 0;">
  41. <el-pagination v-if="album_stat.pagination" :page-size="album_stat.page_size"
  42. style="display: inline-block;float: right;" background @current-change="pageAlbumChange"
  43. layout="prev, pager, next" :total="album_stat.count" :current-page.sync="album_page">
  44. </el-pagination>
  45. </div>
  46. </div>
  47. <div class="data-tab" style="padding-bottom:100px;">
  48. <h3>
  49. 会员浏览记录
  50. </h3>
  51. <el-table align="center" header-align="center" header-row-class-name="header-cell" :data="user_list">
  52. <el-table-column type="index" align="center" label="序号"></el-table-column>
  53. <el-table-column label="会员" width="180" >
  54. <template slot-scope="scope">
  55. <div class="user_img" v-if="scope.row.user_id>0">
  56. <el-image class="default-avatar" :src="scope.row.user.avatar_url">
  57. <div slot="error" class="image-slot">
  58. <com-image src="/resources/img/common/default-avatar.png"></com-image>
  59. </div>
  60. </el-image>
  61. </div>
  62. <div class="user_img" v-else>
  63. <el-image class="default-avatar" :src="scope.row.user_avatar_url">
  64. <div slot="error" class="image-slot">
  65. <com-image src="/resources/img/common/default-avatar.png"></com-image>
  66. </div>
  67. </el-image>
  68. </div>
  69. <div>
  70. <div style="color:#000;" v-if="scope.row.user_id>0">{{scope.row.user.nickname}}</div>
  71. <div style="color:#000;" v-else>{{scope.row.user_name}}</div>
  72. <div style="font-size: 13px;" v-if="scope.row.user_id>0">{{scope.row.user.mobile}}</div>
  73. </div>
  74. </template>
  75. </el-table-column>
  76. <el-table-column prop="album.id" align="center" label="画册ID"></el-table-column>
  77. <el-table-column prop="album.title" align="center" label="画册名称"></el-table-column>
  78. <el-table-column prop="stay_time" align="center" label="停留时长"></el-table-column>
  79. <el-table-column prop="amount" align="center" label="支付金额"></el-table-column>
  80. <el-table-column prop="share_time" align="center" label="分享次数"></el-table-column>
  81. <el-table-column prop="page_num" align="center" label="翻看页数"></el-table-column>
  82. </el-table>
  83. <div style="text-align: right;margin: 20px 0;">
  84. <el-pagination v-if="pagination" :page-size="pagination.pageSize"
  85. style="display: inline-block;float: right;" background @current-change="pageChange"
  86. layout="prev, pager, next" :total="pagination.total_count">
  87. </el-pagination>
  88. </div>
  89. </div>
  90. </el-card>
  91. </div>
  92. </div>
  93. <style>
  94. /*头像样式 start*/
  95. .default-avatar{
  96. width: 50px;
  97. height: 50px;
  98. border-radius: 50%;
  99. }
  100. .user_img{
  101. float: left;
  102. margin-right: 8px;
  103. height: 50px;
  104. width: 50px;
  105. }
  106. .el-table_1_column_2 .cell { /*-2 表示在第二行*/
  107. display: flex;
  108. }
  109. /*头像样式 end*/
  110. .header-cell>th {
  111. border: 0;
  112. text-align: center;
  113. background-color: #fff;
  114. color: #fff;
  115. font-weight: bold;
  116. }
  117. .album_chart {
  118. height: 340px;
  119. width: 1230px;
  120. }
  121. .visit_chart,
  122. .pay_chart {
  123. height: 320px;
  124. width: 550px;
  125. }
  126. </style>
  127. <script>
  128. new Vue({
  129. el: '#app',
  130. methods: {
  131. navBack() {
  132. window.history.back()
  133. },
  134. renderViews() {
  135. const {
  136. date_list
  137. } = this;
  138. Object.assign(this, {
  139. visit_chart: echarts.init(this.$refs.visit_chart),
  140. pay_chart: echarts.init(this.$refs.pay_chart),
  141. album_chart: echarts.init(this.$refs.album_chart)
  142. })
  143. this.visit_chart.setOption({
  144. color: ['#6395f9', '#59daab', '#657798'],
  145. title: {
  146. padding: [15, 0, 0, 15],
  147. text: '访问概况'
  148. },
  149. tooltip: {
  150. trigger: 'axis',
  151. axisPointer: {
  152. type: 'shadow',
  153. label: {
  154. show: true
  155. }
  156. }
  157. },
  158. toolbox: {
  159. show: true,
  160. feature: {
  161. mark: {
  162. show: true
  163. },
  164. }
  165. },
  166. calculable: true,
  167. // 过滤
  168. legend: {
  169. data: ['访问数', '浏览量'],
  170. itemGap: 5
  171. },
  172. // 布局
  173. grid: {
  174. top: '16%',
  175. left: '5%',
  176. right: '8%',
  177. containLabel: true
  178. },
  179. // x 轴数据
  180. xAxis: [{
  181. min: 0,
  182. max: date_list.length - 1,
  183. type: 'category',
  184. data: date_list.map(e => e.date)
  185. }],
  186. // Y 轴数据
  187. yAxis: [{
  188. step: 10,
  189. type: 'value',
  190. name: '',
  191. axisLabel: {
  192. formatter: function(a) {
  193. a = +a;
  194. return isFinite(a) ?
  195. echarts.format.addCommas(+a) :
  196. '';
  197. }
  198. }
  199. }],
  200. series: [{
  201. name: '访问数',
  202. type: 'bar',
  203. data: date_list.map(e => e.visit_count)
  204. },
  205. {
  206. name: '浏览量',
  207. type: 'bar',
  208. data: date_list.map(e => e.views_count)
  209. }
  210. ]
  211. });
  212. this.pay_chart.setOption({
  213. color: ['#6395f9', '#59daab', '#657798'],
  214. title: {
  215. padding: [15, 0, 0, 15],
  216. text: '支付概况'
  217. },
  218. tooltip: {
  219. trigger: 'axis',
  220. axisPointer: {
  221. type: 'shadow',
  222. label: {
  223. show: true
  224. }
  225. }
  226. },
  227. toolbox: {
  228. show: true,
  229. feature: {
  230. mark: {
  231. show: true
  232. },
  233. }
  234. },
  235. calculable: true,
  236. // 过滤
  237. legend: {
  238. data: ['支付人数', '支付单数', '支付金额'],
  239. itemGap: 5
  240. },
  241. // 布局
  242. grid: {
  243. top: '16%',
  244. left: '5%',
  245. right: '8%',
  246. containLabel: true
  247. },
  248. // x 轴数据
  249. xAxis: [{
  250. min: 0,
  251. max: date_list.length - 1,
  252. type: 'category',
  253. data: date_list.map(e => e.date)
  254. }],
  255. // Y 轴数据
  256. yAxis: [{
  257. step: 5,
  258. type: 'value',
  259. name: '',
  260. axisLabel: {
  261. formatter: function(a) {
  262. a = +a;
  263. return isFinite(a) ?
  264. echarts.format.addCommas(+a) :
  265. '';
  266. }
  267. }
  268. }],
  269. series: [{
  270. name: '支付人数',
  271. type: 'bar',
  272. data: date_list.map(e => e.pay_count)
  273. },
  274. {
  275. name: '支付单数',
  276. type: 'bar',
  277. data: date_list.map(e => e.order_count)
  278. }, {
  279. name: '支付金额',
  280. type: 'bar',
  281. data: date_list.map(e => e.goods_amount)
  282. }
  283. ]
  284. });
  285. console.log(date_list.map(e => e.date))
  286. this.album_chart.setOption({
  287. color: ['#6395f9', '#59daab', '#657798'],
  288. title: {
  289. padding: [15, 0, 0, 15],
  290. text: '画册概况'
  291. },
  292. tooltip: {
  293. trigger: 'axis',
  294. axisPointer: {
  295. type: 'shadow',
  296. label: {
  297. show: true
  298. }
  299. }
  300. },
  301. toolbox: {
  302. show: true,
  303. feature: {
  304. mark: {
  305. show: true
  306. },
  307. }
  308. },
  309. calculable: true,
  310. // 过滤
  311. legend: {
  312. data: ['停留时间', '分享次数'],
  313. itemGap: 5
  314. },
  315. // 布局
  316. grid: {
  317. top: '16%',
  318. left: '5%',
  319. right: '8%',
  320. containLabel: true
  321. },
  322. // x 轴数据
  323. xAxis: [{
  324. min: 0,
  325. max: date_list.length - 1,
  326. type: 'category',
  327. data: date_list.map(e => e.date)
  328. }],
  329. // Y 轴数据
  330. yAxis: [{
  331. step: 5,
  332. type: 'value',
  333. name: '',
  334. axisLabel: {
  335. formatter: function(a) {
  336. a = +a;
  337. return isFinite(a) ?
  338. echarts.format.addCommas(+a) :
  339. '';
  340. }
  341. }
  342. }],
  343. series: [{
  344. name: '停留时间',
  345. type: 'bar',
  346. data: date_list.map(e => e.stop_time)
  347. },
  348. {
  349. name: '分享次数',
  350. type: 'bar',
  351. data: date_list.map(e => e.shares_count)
  352. }
  353. ]
  354. });
  355. },
  356. getStatData() {
  357. if (this.loading) {
  358. return;
  359. }
  360. this.loading = true;
  361. request({
  362. params: {
  363. r: 'album/statistics/index',
  364. begin_date: this.dateline ? this.dateline[0] : '',
  365. end_date: this.dateline ? this.dateline[1] : '',
  366. id: getQuery('id') ? getQuery('id') : 0
  367. }
  368. }).then(e => {
  369. this.loading = false;
  370. this.date_list = e.data.data.stat;
  371. this.album_stat = e.data.data.album;
  372. this.user_list = e.data.data.user.list;
  373. this.pagination = e.data.data.user.pagination;
  374. this.pagination.pageSize = e.data.data.user.page_size;
  375. this.pagination.total_count = e.data.data.user.count;
  376. this.renderViews();
  377. }).catch(e => {
  378. console.log(e);
  379. });
  380. },
  381. pageChange(currentPage) {
  382. let self = this;
  383. self.page = currentPage;
  384. self.getMemberData();
  385. },
  386. pageAlbumChange(){
  387. request({
  388. params: {
  389. r: 'album/statistics/album',
  390. page: this.album_page
  391. }
  392. }).then(e => {
  393. this.album_stat = e.data.data.album;
  394. }).catch(e => {
  395. console.log(e);
  396. });
  397. },
  398. getMemberData() {
  399. request({
  400. params: {
  401. r: 'album/statistics/index',
  402. page: this.page
  403. }
  404. }).then(e => {
  405. this.user_list = e.data.data.user.list;
  406. this.pagination = e.data.data.user.pagination;
  407. this.pagination.pageSize = e.data.data.user.page_size;
  408. this.pagination.total_count = e.data.data.user.count;
  409. }).catch(e => {
  410. console.log(e);
  411. });
  412. },
  413. dateChanged(val) {
  414. this.getStatData()
  415. }
  416. },
  417. data() {
  418. return {
  419. page: 1,
  420. pageSize: 10,
  421. album_page:1,
  422. total: 0,
  423. album_stat:[],
  424. pagination:[],
  425. user_list:[],
  426. loading: false,
  427. album_id: '',
  428. dateline: '',
  429. date_list: {},
  430. album_pages_stat: [],
  431. album_stat: [],
  432. user: []
  433. }
  434. },
  435. created() {
  436. this.getStatData();
  437. },
  438. })
  439. </script>
  440. <style>
  441. /* 下部分可抽离 */
  442. .solid-bottom {
  443. border-bottom: 1px solid #000;
  444. }
  445. .round {
  446. border-radius: 5000px;
  447. }
  448. .radius {
  449. border-radius: 6px;
  450. }
  451. .flex {
  452. display: flex;
  453. }
  454. .basis-xs {
  455. flex-basis: 20%;
  456. }
  457. .basis-sm {
  458. flex-basis: 40%;
  459. }
  460. .basis-df {
  461. flex-basis: 50%;
  462. }
  463. .basis-lg {
  464. flex-basis: 60%;
  465. }
  466. .basis-xl {
  467. flex-basis: 80%;
  468. }
  469. .flex-sub {
  470. flex: 1;
  471. }
  472. .flex-twice {
  473. flex: 2;
  474. }
  475. .flex-treble {
  476. flex: 3;
  477. }
  478. .flex-direction {
  479. flex-direction: column;
  480. }
  481. .flex-wrap {
  482. flex-wrap: wrap;
  483. }
  484. .align-start {
  485. align-items: flex-start;
  486. }
  487. .align-end {
  488. align-items: flex-end;
  489. }
  490. .align-center {
  491. align-items: center;
  492. }
  493. .align-stretch {
  494. align-items: stretch;
  495. }
  496. .self-start {
  497. align-self: flex-start;
  498. }
  499. .self-center {
  500. align-self: flex-center;
  501. }
  502. .self-end {
  503. align-self: flex-end;
  504. }
  505. .self-stretch {
  506. align-self: stretch;
  507. }
  508. .align-stretch {
  509. align-items: stretch;
  510. }
  511. .justify-start {
  512. justify-content: flex-start;
  513. }
  514. .justify-end {
  515. justify-content: flex-end;
  516. }
  517. .justify-center {
  518. justify-content: center;
  519. }
  520. .justify-between {
  521. justify-content: space-between;
  522. }
  523. .justify-around {
  524. justify-content: space-around;
  525. }
  526. .data-tab{
  527. padding: 0 20px;
  528. }
  529. </style>