store.vue 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447
  1. <template>
  2. <view class="pagebox">
  3. <!-- #ifdef MP || APP-PLUS -->
  4. <NavBar titleText="数据统计" :iconColor="iconColor" :textColor="iconColor" :isScrolling="isScrolling" showBack></NavBar>
  5. <!-- #endif -->
  6. <view class="headerBg">
  7. <view :style="{ height: `${getHeight.barTop}px` }"></view>
  8. <view :style="{ height: `${getHeight.barHeight}px` }"></view>
  9. <view class="inner"></view>
  10. </view>
  11. <view class="order-index" ref="container">
  12. <view class="wrapper">
  13. <view class="header acea-row row-between-wrapper">
  14. <view class="title">数据统计</view>
  15. <view class="tab">
  16. <view class="box" :class="item.id== current ? 'on':''" v-for="item in dataList" @click="detailtab(item.id)">{{item.name}}</view>
  17. </view>
  18. </view>
  19. <view class="list acea-row">
  20. <view class="item" :class="orderType == item.type?'on':''" v-if="item.isManager" @click="orderNum(item.type)" v-for="item in statistics">
  21. <view>{{item.name}}</view>
  22. <view class="num">{{ item.price }}</view>
  23. </view>
  24. </view>
  25. <view class="canvas">
  26. <canvas canvas-id="canvasMix" id="canvasMix" class="charts" disable-scroll @touchstart="touchMix" @touchmove="moveMix" @touchend="touchEndMix">
  27. </canvas>
  28. </view>
  29. </view>
  30. <view class="public-wrapper">
  31. <view class="title">
  32. 详细数据
  33. </view>
  34. <view class="nav acea-row row-between-wrapper">
  35. <view class="num">日期</view>
  36. <view class="num" :class="[3,9,10].indexOf(orderType) == -1?'on':''">数量</view>
  37. <view class="num price" v-if="[3,9,10].indexOf(orderType) == -1">金额</view>
  38. </view>
  39. <view class="conter">
  40. <view class="item acea-row row-between-wrapper" v-for="(item, index) in list" :key="index">
  41. <view class="num">{{item.day}}</view>
  42. <view class="num" :class="[3,9,10].indexOf(orderType) == -1?'on':''">{{item.count}}</view>
  43. <view class="num price" v-if="[3,9,10].indexOf(orderType) == -1">{{item.price}}</view>
  44. </view>
  45. </view>
  46. </view>
  47. </view>
  48. <view class="safe-area-inset-bottom"></view>
  49. </view>
  50. </template>
  51. <script>
  52. let _self;
  53. let canvaMix = null;
  54. import {
  55. statisticsMenuApi,
  56. getStoreChart,
  57. getStatisticsListApi
  58. } from "@/api/admin";
  59. import uCharts from '../components/ucharts/ucharts'
  60. // #ifdef MP || APP-PLUS
  61. import NavBar from '@/components/NavBar.vue';
  62. // #endif
  63. export default {
  64. name: 'adminOrder',
  65. components: {
  66. // #ifdef MP ||APP-PLUS
  67. NavBar,
  68. // #endif
  69. },
  70. data() {
  71. return {
  72. iconColor: '#FFFFFF',
  73. isScrolling: false,
  74. getHeight: this.$util.getWXStatusHeight(),
  75. dataList:[
  76. {id:'today',name:'今日'},
  77. {id:'yesterday',name:'昨日'},
  78. {id:'month',name:'本月'}
  79. ],
  80. current:'today',
  81. statistics:[],
  82. isManager:0,
  83. orderType:1,
  84. cWidth: '',
  85. cHeight: '',
  86. list: [],
  87. pixelRatio: 1
  88. }
  89. },
  90. onLoad(options) {
  91. this.isManager = parseInt(options.isManager);
  92. this.getstatisticsMenu();
  93. this.getOrderChart();
  94. this.cWidth = uni.upx2px(710);
  95. this.cHeight = uni.upx2px(500);
  96. this.getList();
  97. },
  98. onPageScroll(e) {
  99. // #ifdef MP
  100. if (e.scrollTop > 50) {
  101. this.isScrolling = true;
  102. this.iconColor = '#333333';
  103. } else if (e.scrollTop < 50) {
  104. this.isScrolling = false;
  105. this.iconColor = '#FFFFFF';
  106. }
  107. // #endif
  108. },
  109. beforeMount() {
  110. canvaMix = null
  111. },
  112. methods: {
  113. orderNum(num){
  114. this.orderType = num;
  115. this.getOrderChart();
  116. this.getList();
  117. },
  118. getstatisticsMenu(){
  119. let data = {
  120. is_manager:this.isManager,
  121. data:this.current
  122. }
  123. statisticsMenuApi(data).then(res=>{
  124. let data = res.data;
  125. this.statistics = [
  126. {name:'销售额',price:data.price,type:1,isManager:1},
  127. {name:'配送订单额',price:data.send_price,type:2,isManager:this.isManager},
  128. {name:'收银订单额',price:data.cashier_price,type:5,isManager:1},
  129. {name:'核销订单额',price:data.writeoff_price,type:6,isManager:1},
  130. {name:'配送订单数',price:data.send_count,type:3,isManager:this.isManager},
  131. {name:'付费会员额',price:data.svip_price,type:7,isManager:1},
  132. {name:'充值订单额',price:data.recharge_price,type:8,isManager:1},
  133. {name:'退款订单额',price:data.refund_price,type:4,isManager:this.isManager},
  134. {name:'推广用户数',price:data.spread_count,type:9,isManager:1},
  135. {name:'激活会员卡',price:data.card_count,type:10,isManager:1}
  136. ]
  137. }).catch(err=>{
  138. this.$util.Tips({
  139. title: err
  140. });
  141. })
  142. },
  143. getOrderChart() {
  144. let data = {
  145. is_manager:this.isManager,
  146. time:this.current
  147. }
  148. getStoreChart(this.orderType,data).then(res => {
  149. const data = res.data;
  150. let Mix = {
  151. categories: [],
  152. series: []
  153. };
  154. let series = [{
  155. "name": '销售额',
  156. "type": "line",
  157. "data": [],
  158. }];
  159. data.forEach(({
  160. num,
  161. number,
  162. time
  163. }) => {
  164. series[0].data.push(number);
  165. Mix.categories.push(time);
  166. });
  167. Mix.series = series;
  168. this.chartData = data;
  169. if (canvaMix) {
  170. canvaMix.updateData(Mix);
  171. } else {
  172. this.showLineA("canvasMix", Mix);
  173. }
  174. });
  175. },
  176. // 创建charts
  177. showLineA(canvasId, chartData) {
  178. let _self = this
  179. canvaMix = new uCharts({
  180. $this: _self,
  181. canvasId: canvasId,
  182. type: 'line',
  183. fontSize: 11,
  184. padding: [5, 5, 0, 5],
  185. legend: {
  186. show: true,
  187. position: 'bottom',
  188. float: 'center',
  189. padding: 5,
  190. lineHeight: 11,
  191. margin: 6,
  192. },
  193. background: '#FFFFFF',
  194. pixelRatio: _self.pixelRatio,
  195. categories: chartData.categories,
  196. series: chartData.series,
  197. animation: true,
  198. enableScroll: true, //开启图表拖拽功能
  199. xAxis: {
  200. disableGrid: false,
  201. type: 'grid',
  202. gridType: 'dash',
  203. itemCount: 6,
  204. scrollShow: true,
  205. scrollAlign: 'left',
  206. },
  207. yAxis: {
  208. data: [{
  209. calibration: true,
  210. position: 'left',
  211. title: '销售额(元)',
  212. titleFontSize: 12,
  213. format: (val) => {
  214. return val.toFixed(0)
  215. }
  216. }, ],
  217. showTitle: true,
  218. gridType: 'dash',
  219. dashLength: 4,
  220. splitNumber: 7,
  221. },
  222. width: _self.cWidth * _self.pixelRatio,
  223. height: _self.cHeight * _self.pixelRatio,
  224. dataLabel: true,
  225. dataPointShape: true,
  226. });
  227. },
  228. touchMix(e) {
  229. canvaMix.scrollStart(e);
  230. },
  231. moveMix(e) {
  232. canvaMix.scroll(e);
  233. },
  234. touchEndMix(e) {
  235. var index = canvaMix.getCurrentDataIndex(e);
  236. canvaMix.scrollEnd(e);
  237. //下面是toolTip事件,如果滚动后不需要显示,可不填写
  238. canvaMix.touchLegend(e);
  239. canvaMix.showToolTip(e, {
  240. textList: [{
  241. text: this.chartData[index].time,
  242. color: null
  243. },
  244. {
  245. text: "销售额:" + this.chartData[index].price,
  246. color: "#1890FF"
  247. },
  248. {
  249. text: "订单量:" + this.chartData[index].num,
  250. color: "#91CB74"
  251. }
  252. ]
  253. });
  254. },
  255. // 统计菜单
  256. detailtab: function(type) {
  257. this.current = type
  258. this.getstatisticsMenu();
  259. this.getOrderChart();
  260. this.getList()
  261. },
  262. getList: function() {
  263. let data = {
  264. is_manager:this.isManager,
  265. time:this.current
  266. }
  267. getStatisticsListApi(this.orderType,data).then(res=>{
  268. this.list = res.data;
  269. }).catch(err=>{
  270. this.$util.Tips({
  271. title: err
  272. })
  273. })
  274. }
  275. }
  276. }
  277. </script>
  278. <style lang="scss" scoped>
  279. .pagebox {
  280. position: relative;
  281. overflow: hidden;
  282. }
  283. .safe-area-inset-bottom {
  284. height: 0;
  285. height: constant(safe-area-inset-bottom);
  286. height: env(safe-area-inset-bottom);
  287. }
  288. .headerBg {
  289. position: absolute;
  290. top: 0;
  291. left: -25%;
  292. width: 150%;
  293. border-bottom-right-radius: 100%;
  294. border-bottom-left-radius: 100%;
  295. background: linear-gradient(270deg, #01ABF8 0%, #2A7EFB 100%);
  296. .inner {
  297. height: 356rpx;
  298. }
  299. }
  300. /*订单首页*/
  301. .order-index {
  302. position: relative;
  303. padding: 0 20rpx;
  304. }
  305. .order-index .wrapper {
  306. background-color: #fff;
  307. border-radius: 24rpx;
  308. padding-top: 30rpx;
  309. margin-top: 40rpx;
  310. .canvas{
  311. padding: 0 40rpx;
  312. margin-top: 26rpx;
  313. }
  314. .header{
  315. padding: 0 24rpx;
  316. .title{
  317. font-size: 30rpx;
  318. font-weight: 500;
  319. }
  320. .tab{
  321. width: 288rpx;
  322. height: 48rpx;
  323. background: #F5F5F5;
  324. border-radius: 24rpx;
  325. display: flex;
  326. justify-content: space-between;
  327. font-weight: 400;
  328. color: #999999;
  329. font-size: 24rpx;
  330. .box{
  331. width: 96rpx;
  332. height: 100%;
  333. border-radius: 24rpx;
  334. text-align: center;
  335. line-height: 48rpx;
  336. }
  337. .on{
  338. background: #1890FF;
  339. color: #FFFFFF;
  340. }
  341. }
  342. }
  343. .chart-title {
  344. padding: 40rpx 0 6rpx 42rpx;
  345. font-size: 22rpx;
  346. line-height: 26rpx;
  347. color: #999999;
  348. }
  349. .charts {
  350. width: 100%;
  351. height: 514rpx;
  352. }
  353. }
  354. .order-index .wrapper .list{
  355. margin-top: 16rpx;
  356. padding: 0 40rpx;
  357. }
  358. .order-index .wrapper .list .item {
  359. padding: 24rpx 0;
  360. text-align: left;
  361. font-size: 24rpx;
  362. line-height: 34rpx;
  363. color: #999;
  364. width: 150rpx;
  365. margin-right: 90rpx;
  366. &:nth-of-type(3n){
  367. margin-right: 0;
  368. }
  369. &.on{
  370. color: #2A7EFB;
  371. .num{
  372. color: #2A7EFB;
  373. }
  374. }
  375. }
  376. .order-index .wrapper .list .item .num {
  377. margin-top: 12rpx;
  378. font-family: SemiBold;
  379. font-size: 36rpx;
  380. color: #333;
  381. }
  382. .public-wrapper .title {
  383. font-weight: 500;
  384. font-size: 30rpx;
  385. line-height: 42rpx;
  386. color: #333333;
  387. padding: 32rpx 0 40rpx 24rpx;
  388. }
  389. .public-wrapper {
  390. background-color: #fff;
  391. border-radius: 24rpx;
  392. margin-top: 20rpx;
  393. }
  394. .public-wrapper .nav {
  395. padding: 0 40rpx;
  396. line-height: 34rpx;
  397. font-size: 24rpx;
  398. color: #999;
  399. }
  400. .public-wrapper .conter {
  401. padding: 0 40rpx;
  402. }
  403. .public-wrapper .conter .item,.public-wrapper .nav {
  404. border-bottom: 1px solid #F1F1F1;
  405. height: 74rpx;
  406. font-size: 24rpx;
  407. .num {
  408. flex: 1;
  409. word-break: break-all;
  410. &.price{
  411. text-align: right;
  412. }
  413. &.on{
  414. text-align: center;
  415. }
  416. }
  417. }
  418. .cover-view {
  419. position: fixed;
  420. top: 0;
  421. right: 0;
  422. bottom: 0;
  423. left: 0;
  424. }
  425. </style>