index.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652
  1. <template>
  2. <div class="statistical-page" ref="container">
  3. <div class="navs">
  4. <div class="list">
  5. <div class="item" :class="time == 'today' ? 'on' : ''" @click="setTime('today')">
  6. 今天
  7. </div>
  8. <div class="item" :class="time == 'yesterday' ? 'on' : ''" @click="setTime('yesterday')">
  9. 昨天
  10. </div>
  11. <div class="item" :class="time == 'seven' ? 'on' : ''" @click="setTime('seven')">
  12. 最近7天
  13. </div>
  14. <div class="item" :class="time == 'month' ? 'on' : ''" @click="setTime('month')">
  15. 本月
  16. </div>
  17. <div class="item" :class="time == 'date' ? 'on' : ''" @click="dateTitle">
  18. <!-- <span class="iconfont icon-xiangxia"></span>
  19. <span v-for="(value, index) in renderValues" :key="index">
  20. {{ value }}</span
  21. > -->
  22. 自定义
  23. </div>
  24. </div>
  25. </div>
  26. <div class="wrapper">
  27. <div class="title">
  28. {{ time == 'date'?'':title }}{{ where.type == 1 ? "营业额(元)" : "订单量(份)" }}
  29. </div>
  30. <div class="money">{{ time_price }}</div>
  31. <div class="increase acea-row row-between-wrapper">
  32. <div>
  33. {{ time == 'date'?'':title }}增长率:<span :class="increase_time_status === 1 ? 'red' : 'green'">{{ increase_time_status === 1 ? "" : "-" }}{{ growth_rate }}%
  34. <span class="iconfont" :class="
  35. increase_time_status === 1
  36. ? 'icon-xiangshang1'
  37. : 'icon-xiangxia2'
  38. "></span></span>
  39. </div>
  40. <div>
  41. {{ time == 'date'?'':title }}增长:<span :class="increase_time_status === 1 ? 'red' : 'green'">{{ increase_time_status === 1 ? "" : "-" }}{{ increase_time }}
  42. <span class="iconfont" :class="
  43. increase_time_status === 1
  44. ? 'icon-xiangshang1'
  45. : 'icon-xiangxia2'
  46. "></span></span>
  47. </div>
  48. </div>
  49. </div>
  50. <div class="chart">
  51. <div class="chart-title">
  52. 单位({{where.type == 1?'元':'份'}})
  53. </div>
  54. <canvas canvas-id="canvasLineA" id="canvasLineA" class="charts" disable-scroll=true @touchstart="touchLineA"
  55. @touchmove="moveLineA" @touchend="touchEndLineA">
  56. </canvas>
  57. </div>
  58. <div class="public-wrapper">
  59. <div class="title">
  60. <span class="iconfont icon-xiangxishuju"></span>详细数据
  61. </div>
  62. <div class="nav acea-row row-between-wrapper">
  63. <div class="data">日期</div>
  64. <div class="browse">订单量</div>
  65. <div class="turnover">成交额</div>
  66. </div>
  67. <div class="conter">
  68. <div class="item acea-row row-between-wrapper" v-for="(item, index) in list" :key="index">
  69. <div class="data">{{ item.time }}</div>
  70. <div class="browse">{{ item.count }}</div>
  71. <div class="turnover">{{ item.price }}</div>
  72. </div>
  73. </div>
  74. </div>
  75. <!-- #ifdef H5 || APP-PLUS -->
  76. <uni-calendar ref="calendar" :date="info.date" :insert="info.insert" :lunar="info.lunar" :startDate="info.startDate" :endDate="info.endDate" :range="info.range" @confirm="confirm" :showMonth="info.showMonth" />
  77. <div class="mask" @touchmove.prevent v-show="current === true" @click="close"></div>
  78. <!-- #endif -->
  79. </div>
  80. </template>
  81. <script>
  82. import uCharts from '../components/ucharts/ucharts'
  83. import uniCalendar from '@/components/uni-calendar/uni-calendar.vue'
  84. var canvaLineA = null;
  85. import {
  86. getStatisticsMonth,
  87. getStatisticsTime
  88. } from "@/api/admin";
  89. const year = new Date().getFullYear();
  90. const month = new Date().getMonth() + 1;
  91. const day = new Date().getDate();
  92. export default {
  93. name: "Statistics",
  94. components: {
  95. uniCalendar
  96. },
  97. props: {},
  98. data: function() {
  99. return {
  100. value: [
  101. [year, month, day - 1],
  102. [year, month, day]
  103. ],
  104. isrange: true,
  105. weekSwitch: false,
  106. ismulti: false,
  107. monFirst: true,
  108. clean: false, //简洁模式
  109. lunar: false, //显示农历
  110. renderValues: [],
  111. monthRange: [],
  112. current: false,
  113. where: {
  114. start: "",
  115. stop: "",
  116. type: ""
  117. },
  118. types: "", //类型|order=订单数|price=营业额
  119. time: "", //时间|today=今天|yesterday=昨天|month=本月
  120. title: "", //时间|today=今天|yesterday=昨天|month=本月
  121. growth_rate: "", //增长率
  122. increase_time: "", //增长率
  123. increase_time_status: "", //增长率
  124. time_price: "", //增长率
  125. loaded: false,
  126. loading: false,
  127. filter: {
  128. page: 1,
  129. limit: 10,
  130. start: "",
  131. stop: ""
  132. },
  133. list: [],
  134. // charts
  135. cWidth: '',
  136. cHeight: '',
  137. pixelRatio: 1,
  138. textarea: '',
  139. "LineA": {
  140. "categories": ["2012", "2013", "2014", "2015", "2016", "2017"],
  141. "series": [{
  142. "data": [35, 8, 25, 37, 4, 20]
  143. }]
  144. },
  145. info: {
  146. startDate: '',
  147. endDate: '',
  148. lunar: false,
  149. range: true,
  150. insert: false,
  151. selected: [],
  152. showMonth:false
  153. },
  154. type: '',
  155. before: '',
  156. after: ''
  157. };
  158. },
  159. watch: {
  160. "$route.params": function(newVal) {
  161. var that = this;
  162. if (newVal != undefined) {
  163. that.setType(newVal.type);
  164. that.setTime(newVal.time);
  165. that.getIndex();
  166. }
  167. }
  168. },
  169. onLoad: function(options) {
  170. this.type = options.type;
  171. if (options.before) {
  172. this.before = options.before;
  173. }
  174. if (options.after) {
  175. this.after = options.after;
  176. }
  177. this.setType(options.type);
  178. this.setTime(options.time);
  179. this.cWidth = uni.upx2px(690);
  180. this.cHeight = uni.upx2px(500);
  181. // this.handelRenderValues();
  182. // this.getIndex();
  183. this.getInfo();
  184. // this.$scroll(this.$refs.container, () => {
  185. // !this.loading && this.getInfo();
  186. // });
  187. },
  188. computed: {
  189. monthRangeText() {
  190. return this.monthRange.length ? "固定" : "指定范围";
  191. }
  192. },
  193. methods: {
  194. getIndex: function() {
  195. let tempDay = []
  196. let tempNum = []
  197. var that = this;
  198. getStatisticsTime(that.where).then(
  199. res => {
  200. var _info = res.data.chart,
  201. day = [],
  202. num = [];
  203. _info.forEach(function(item) {
  204. day.push(item.time);
  205. num.push(item.num);
  206. });
  207. that.growth_rate = res.data.growth_rate;
  208. that.increase_time = res.data.increase_time;
  209. that.increase_time_status = res.data.increase_time_status;
  210. that.time_price = res.data.time;
  211. res.data.chart.forEach((item, index) => {
  212. tempDay.push(item.time)
  213. tempNum.push(item.num)
  214. })
  215. that.LineA.categories = tempDay
  216. that.LineA.series[0].data = tempNum
  217. that.showLineA("canvasLineA", that.LineA);
  218. },
  219. error => {
  220. that.$util.Tips({
  221. title: error
  222. })
  223. }
  224. );
  225. },
  226. setTime: function(time) {
  227. let self = this
  228. this.time = time;
  229. var year = new Date().getFullYear(),
  230. month = new Date().getMonth() + 1,
  231. day = new Date().getDate();
  232. this.list = [];
  233. this.filter.page = 1;
  234. this.loaded = false;
  235. this.loading = false;
  236. switch (time) {
  237. case "today":
  238. this.where.start =
  239. new Date(Date.parse(year + "/" + month + "/" + day)).getTime() /
  240. 1000;
  241. this.where.stop =
  242. new Date(Date.parse(year + "/" + month + "/" + day)).getTime() /
  243. 1000 +
  244. 24 * 60 * 60 -
  245. 1;
  246. this.title = "今日";
  247. this.getIndex();
  248. this.getInfo();
  249. break;
  250. case "yesterday":
  251. this.where.start =
  252. new Date(Date.parse(year + "/" + month + "/" + day)).getTime() /
  253. 1000 -
  254. 24 * 60 * 60;
  255. this.where.stop =
  256. new Date(Date.parse(year + "/" + month + "/" + day)).getTime() /
  257. 1000 -
  258. 1;
  259. this.title = "昨日";
  260. this.getIndex();
  261. this.getInfo();
  262. break;
  263. case "month":
  264. this.where.start =
  265. new Date(year, new Date().getMonth(), 1).getTime() / 1000;
  266. this.where.stop = new Date(year, month, 1).getTime() / 1000 - 1;
  267. this.title = "本月";
  268. this.getIndex();
  269. this.getInfo();
  270. break;
  271. case "seven":
  272. this.where.start =
  273. new Date(Date.parse(year + "/" + month + "/" + day)).getTime() /
  274. 1000 +
  275. 24 * 60 * 60 -
  276. 7 * 3600 * 24;
  277. this.where.stop =
  278. new Date(Date.parse(year + "/" + month + "/" + day)).getTime() /
  279. 1000 +
  280. 24 * 60 * 60 -
  281. 1;
  282. this.title = "七日";
  283. this.getIndex();
  284. this.getInfo();
  285. break;
  286. // #ifdef MP
  287. case "date":
  288. let star = new Date(self.before).getTime()/1000
  289. let stop = new Date(self.after).getTime()/1000
  290. self.where.start = star
  291. self.where.stop = stop
  292. Promise.all([self.getIndex(),self.getInfo()]);
  293. break;
  294. // #endif
  295. }
  296. },
  297. setType: function(type) {
  298. switch (type) {
  299. case "price":
  300. this.where.type = 1;
  301. break;
  302. case "order":
  303. this.where.type = 2;
  304. break;
  305. }
  306. },
  307. dateTitle: function() {
  308. // #ifdef H5 || APP-PLUS
  309. this.$refs.calendar.open()
  310. this.time = 'date'
  311. // #endif
  312. // #ifdef MP
  313. uni.navigateTo({
  314. url: '/pages/admin/custom_date/index?type=' + this.type
  315. });
  316. // #endif
  317. // this.current = true;
  318. },
  319. close: function() {
  320. this.current = false;
  321. },
  322. getInfo: function() {
  323. var that = this;
  324. if (that.loading || that.loaded) return;
  325. that.loading = true;
  326. that.filter.start = that.where.start;
  327. that.filter.stop = that.where.stop;
  328. getStatisticsMonth(that.filter).then(
  329. res => {
  330. that.loading = false;
  331. that.loaded = res.data.length < that.filter.limit;
  332. that.list.push.apply(that.list, res.data);
  333. that.filter.page = that.filter.page + 1;
  334. },
  335. error => {
  336. that.$util.Tips({
  337. title: error
  338. })
  339. }
  340. );
  341. },
  342. // 创建charts
  343. showLineA(canvasId, chartData) {
  344. let _self = this
  345. canvaLineA = new uCharts({
  346. $this: _self,
  347. canvasId: canvasId,
  348. type: 'line',
  349. fontSize: 11,
  350. padding: [15, 15, 0, 15],
  351. legend: {
  352. show: false,
  353. padding: 5,
  354. lineHeight: 11,
  355. margin: 5,
  356. },
  357. dataLabel: true,
  358. dataPointShape: true,
  359. dataPointShapeType: 'hollow',
  360. background: '#FFFFFF',
  361. pixelRatio: _self.pixelRatio,
  362. categories: chartData.categories,
  363. series: chartData.series,
  364. animation: true,
  365. enableScroll: true, //开启图表拖拽功能
  366. xAxis: {
  367. disableGrid: false,
  368. type: 'grid',
  369. gridType: 'dash',
  370. itemCount: 4,
  371. scrollShow: true,
  372. scrollAlign: 'left'
  373. },
  374. yAxis: {
  375. //disabled:true
  376. gridType: 'dash',
  377. splitNumber: 8,
  378. min: 0,
  379. max: 30,
  380. format: (val) => {
  381. return val.toFixed(0)
  382. } //如不写此方法,Y轴刻度默认保留两位小数
  383. },
  384. width: _self.cWidth * _self.pixelRatio,
  385. height: _self.cHeight * _self.pixelRatio,
  386. extra: {
  387. line: {
  388. type: 'straight'
  389. }
  390. },
  391. });
  392. },
  393. // charts触摸事件
  394. touchLineA(e) {
  395. canvaLineA.scrollStart(e);
  396. },
  397. moveLineA(e) {
  398. canvaLineA.scroll(e);
  399. },
  400. touchEndLineA(e) {
  401. canvaLineA.scrollEnd(e);
  402. },
  403. // 日历确定
  404. confirm(e) {
  405. let self = this
  406. if(e.range.after && e.range.before){
  407. let star = new Date(e.range.before+' 00:00:00').getTime()/1000
  408. let stop = new Date(e.range.after+' 23:59:59').getTime()/1000
  409. self.where.start = star
  410. self.where.stop = stop
  411. self.list = [];
  412. self.filter.page = 1;
  413. self.loaded = false;
  414. self.loading = false;
  415. Promise.all([self.getIndex(),self.getInfo()]);
  416. }
  417. },
  418. },
  419. onReachBottom() {
  420. this.getInfo();
  421. }
  422. };
  423. </script>
  424. <style>
  425. /*交易额统计*/
  426. .statistical-page .navs {
  427. width: 100%;
  428. height: 96upx;
  429. background-color: #fff;
  430. overflow: hidden;
  431. line-height: 96upx;
  432. position: fixed;
  433. top: 0;
  434. left: 0;
  435. z-index: 9;
  436. }
  437. .statistical-page .navs .list {
  438. overflow-y: hidden;
  439. overflow-x: auto;
  440. white-space: nowrap;
  441. -webkit-overflow-scrolling: touch;
  442. width: 100%;
  443. }
  444. .statistical-page .navs .item {
  445. font-size: 32upx;
  446. color: #282828;
  447. margin-left: 60upx;
  448. display: inline-block;
  449. }
  450. .statistical-page .navs .item.on {
  451. color: #2291f8;
  452. }
  453. .statistical-page .navs .item .iconfont {
  454. font-size: 25upx;
  455. margin-left: 13upx;
  456. }
  457. .statistical-page .wrapper {
  458. width: 740upx;
  459. background-color: #fff;
  460. border-radius: 10upx;
  461. margin: 119upx auto 0 auto;
  462. padding: 50upx 60upx;
  463. }
  464. .statistical-page .wrapper .title {
  465. font-size: 30upx;
  466. color: #999;
  467. text-align: center;
  468. }
  469. .statistical-page .wrapper .money {
  470. font-size: 72upx;
  471. color: #fba02a;
  472. text-align: center;
  473. margin-top: 10upx;
  474. }
  475. .statistical-page .wrapper .increase {
  476. font-size: 28upx;
  477. color: #999;
  478. margin-top: 20upx;
  479. }
  480. .statistical-page .wrapper .increase .red {
  481. color: #ff6969;
  482. }
  483. .statistical-page .wrapper .increase .green {
  484. color: #1abb1d;
  485. }
  486. .statistical-page .wrapper .increase .iconfont {
  487. font-size: 23upx;
  488. margin-left: 15upx;
  489. }
  490. .statistical-page .chart {
  491. width: 690upx;
  492. background-color: #fff;
  493. border-radius: 10upx;
  494. margin: 23upx auto 0 auto;
  495. /* padding: 25upx 22upx 0 22upx; */
  496. }
  497. .statistical-page .chart .chart-title{
  498. padding:20upx 20upx 10upx;
  499. font-size: 26upx;
  500. color: #999;
  501. }
  502. .statistical-page .chart canvas {
  503. width: 100%;
  504. height: 530rpx;
  505. }
  506. .statistical-page .chart .company {
  507. font-size: 26upx;
  508. color: #999;
  509. }
  510. .yd-confirm {
  511. background-color: #fff;
  512. font-size: unset;
  513. width: 540upx;
  514. height: 250upx;
  515. border-radius: 40upx;
  516. }
  517. .yd-confirm-hd {
  518. text-align: center;
  519. }
  520. .yd-confirm-title {
  521. color: #030303;
  522. font-weight: bold;
  523. font-size: 36upx;
  524. }
  525. .yd-confirm-bd {
  526. text-align: center;
  527. font-size: 28upx;
  528. color: #333333;
  529. }
  530. .yd-confirm-ft {
  531. line-height: 90upx;
  532. margin-top: 14px;
  533. border-top: 1upx solid #eee;
  534. }
  535. .yd-confirm-ft>a {
  536. color: #e93323;
  537. }
  538. .yd-confirm-ft>a.primary {
  539. border-left: 1upx solid #eee;
  540. color: #e93323;
  541. }
  542. .echarts {
  543. width: 100%;
  544. height: 550upx;
  545. }
  546. .calendar-wrapper {
  547. position: fixed;
  548. bottom: 0;
  549. left: 0;
  550. width: 100%;
  551. z-index: 777;
  552. transform: translate3d(0, 100%, 0);
  553. transition: all 0.3s cubic-bezier(0.25, 0.5, 0.5, 0.9);
  554. }
  555. .calendar-wrapper.on {
  556. transform: translate3d(0, 0, 0);
  557. }
  558. .statistical-page .wrapper .increase {
  559. font-size: 26upx;
  560. }
  561. .statistical-page .wrapper .increase .iconfont {
  562. margin-left: 0;
  563. }
  564. .public-wrapper .title {
  565. font-size: 30upx;
  566. color: #282828;
  567. padding: 0 30upx;
  568. margin-bottom: 20upx;
  569. }
  570. .public-wrapper .title .iconfont {
  571. color: #2291f8;
  572. font-size: 40upx;
  573. margin-right: 13upx;
  574. vertical-align: middle;
  575. }
  576. .public-wrapper {
  577. margin: 18upx auto 0 auto;
  578. width: 690upx;
  579. background-color: #fff;
  580. border-radius: 10upx;
  581. padding-top: 25upx;
  582. }
  583. .public-wrapper .nav {
  584. padding: 0 30upx;
  585. height: 70upx;
  586. line-height: 70upx;
  587. font-size: 24upx;
  588. color: #999;
  589. }
  590. .public-wrapper .data {
  591. width: 210upx;
  592. text-align: left;
  593. }
  594. .public-wrapper .browse {
  595. width: 192upx;
  596. text-align: right;
  597. }
  598. .public-wrapper .turnover {
  599. width: 227upx;
  600. text-align: right;
  601. }
  602. .public-wrapper .conter {
  603. padding: 0 30upx;
  604. }
  605. .public-wrapper .conter .item {
  606. border-bottom: 1px solid #f7f7f7;
  607. height: 70upx;
  608. font-size: 24upx;
  609. }
  610. .public-wrapper .conter .item .turnover {
  611. color: #d84242;
  612. }
  613. </style>