revenue.vue 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. <template>
  2. <view class="revenue-statistics">
  3. <view><date-selector ref="dateSelector" @dateChange="handleDateChange"></date-selector></view>
  4. <u-card padding="32" full :showHead="false" borderRadius="30">
  5. <view slot="body" >
  6. <view style="font-size: 28rpx;line-height: 40rpx;color: #333333;">总收入</view>
  7. <view style="display: flex;color: #00C18A;justify-content: space-between;align-items: flex-end;margin-top: 8rpx;">
  8. <view style="font-size: 60rpx;line-height: 72rpx;font-weight: 700;text-indent: -10rpx;">¥{{ formatNumberWithCommas(top1Data.total) }}</view>
  9. <view style="font-size: 28rpx;line-height: 40rpx;font-weight: 500;">{{ top1Data.ratio }}%</view>
  10. </view>
  11. <view style="margin-top: 24rpx;color: #333333;font-size: 28rpx;display: flex;justify-content: space-between;">
  12. <view>
  13. <view>订单数量</view>
  14. <view style="margin-top: 8rpx;">{{ top1Data.orderCount }}单</view>
  15. </view>
  16. <view style="text-align: right;">
  17. <view>在线时长</view>
  18. <view style="margin-top: 8rpx;font-weight: 600;">{{ top1Data.online }}小时</view>
  19. </view>
  20. </view>
  21. </view>
  22. </u-card>
  23. <u-card padding="32" full :showHead="false" borderRadius="30">
  24. <view slot="body" >
  25. <view class="chart">
  26. <uni-ec-canvas id="revenue" canvas-id="revenue" :ec="ec" ref="canvas"></uni-ec-canvas>
  27. </view>
  28. <view class="chart-bottom">
  29. <view class="chart-bottom-item" v-for="(value, key) in revenueData" :key="key">
  30. <view style="display: flex;align-items: center;">
  31. <view :style="{ backgroundColor: colors[key] }" style="height: 24rpx;width: 24rpx;border-radius: 50%;"></view>
  32. <view style="margin-left: 16rpx;font-size: 28rpx;line-height: 40rpx;color: #333333;">{{ value.title }}</view>
  33. </view>
  34. <view style="display: flex;">
  35. <view style="font-weight: 700;font-size: 28rpx;line-height: 40rpx;">¥{{ formatNumberWithCommas(value.total) }}</view>
  36. <view style="margin-left: 8rpx;font-size: 24rpx;line-height: 40rpx;color: #666666;">{{ value.ratio }}%</view>
  37. </view>
  38. </view>
  39. </view>
  40. </view>
  41. </u-card>
  42. <u-card padding="32" full borderRadius="30" :bodyStyle="{ padding: '0 32rpx' }">
  43. <view slot="head" style="display: flex;justify-content: space-between;align-items: center;position: relative;">
  44. <view style="font-size: 28rpx;line-height: 48rpx;color: #333333;">每日明细</view>
  45. <view>
  46. <btn-group v-model="currentBtn" :defaultVal="1" :options="selectOption"></btn-group>
  47. </view>
  48. </view>
  49. <view slot="body" >
  50. <detail-item v-for="(item, index) in detailDataList" :key="index"></detail-item>
  51. <u-empty v-if="!(detailDataList.length) && loadmore =='nomore'" mode="list" height="280" marginTop="50"></u-empty>
  52. <u-loadmore :status="loadmore" v-if="detailDataList.length" line icon-color="#00C18A" marginTop="20"/>
  53. </view>
  54. </u-card>
  55. </view>
  56. </template>
  57. <!-- 收入统计 -->
  58. <script>
  59. import DateSelector from './DateSelector.vue'
  60. import BtnGroup from './BtnGroup.vue'
  61. import uniEcCanvas from '@/components/uni-ec-canvas/uni-ec-canvas'
  62. import * as echarts from '@/components/uni-ec-canvas/echarts.js'
  63. import DetailItem from './DetailItem.vue'
  64. export default {
  65. name: 'Revenue',
  66. components: { DateSelector, BtnGroup, uniEcCanvas, DetailItem },
  67. data() {
  68. return {
  69. top1Data: {
  70. total: 2856.50,
  71. ratio: 12.5,
  72. orderCount: 87,
  73. online: 32.5,
  74. },
  75. colors: ['#00C18A', '#F56C6C', '#E6A23C'],
  76. ec: {
  77. option: {},
  78. },
  79. revenueData: {
  80. 0: { title: '基础车费', total: 2156.50, ratio: 75.5 },
  81. 1: { title: '高峰奖励', total: 420.00, ratio: 14.7 },
  82. 2: { title: '活动奖励', total: 280.00, ratio: 9.8 }
  83. },
  84. currentBtn: null,
  85. selectOption: [
  86. { label: '全 部', value: 1 },
  87. { label: '已完成', value: 2 },
  88. { label: '已取消', value: 3 },
  89. ],
  90. current: 1, //当前页数
  91. pageSize: 10, //页数大小
  92. totalPage: 3, //总页数
  93. loadmore: 'loadmore',
  94. detailDataList: [1,2],
  95. }
  96. },
  97. onLoad() {
  98. this.$nextTick(() => {
  99. this.$refs.dateSelector.initDate(new Date())
  100. })
  101. },
  102. watch: {
  103. currentBtn: {
  104. handler(newVal) {
  105. this.fetchDetailData()
  106. },
  107. },
  108. },
  109. onReachBottom() {
  110. // 如果当前页数大于等于总页数,状态修改为没有更多了,不再继续往下执行代码
  111. if(this.current >= this.totalPage) {
  112. this.loadmore = 'nomore'
  113. return
  114. }
  115. this.loadmore = 'loading'//状态改为加载中
  116. this.current = ++ this.current//页面新增一页
  117. this.fetchDetailData()//修改页数后,重新获取数据
  118. },
  119. methods: {
  120. handleDateChange(dates) {
  121. console.log('发送请求, 获取数据 ... 参数 => ', dates)
  122. this.$nextTick(() => {
  123. this.$refs.canvas.init(this.initChart)
  124. })
  125. this.fetchDetailData()
  126. },
  127. initChart(canvas, width, height, canvasDpr) {
  128. let chart = echarts.init(canvas, null, {
  129. width: width,
  130. height: height,
  131. devicePixelRatio: canvasDpr
  132. })
  133. canvas.setChart(chart)
  134. let option = {
  135. title: {
  136. text: '收入构成',
  137. left: 0,
  138. top: 0,
  139. textStyle: {
  140. fontSize: 14,
  141. fontWeight: 500,
  142. },
  143. },
  144. grid: {
  145. top: '20%',
  146. left: '2%',
  147. right: '0%',
  148. bottom: '0%',
  149. containLabel: true,
  150. },
  151. xAxis: {
  152. type: 'category',
  153. data: ['基础车费', '高峰奖励', '活动奖励'],
  154. boundaryGap: [50, 50],
  155. axisTick: {
  156. show: false,
  157. },
  158. splitLine: {
  159. show: false,
  160. },
  161. axisLine: {
  162. lineStyle: {
  163. color: '#E4E7ED',
  164. },
  165. },
  166. axisLabel: {
  167. color: '#333333',
  168. }
  169. },
  170. yAxis: {
  171. type: 'value',
  172. boundaryGap: ['10%', '10%'],
  173. splitNumber: 4,
  174. axisTick: {
  175. show: false,
  176. },
  177. axisLine: {
  178. show: false,
  179. },
  180. splitLine: {
  181. lineStyle: {
  182. color: '#E4E7ED',
  183. },
  184. },
  185. },
  186. series: [
  187. {
  188. data: [2500, 800, 600],
  189. type: 'bar',
  190. barWidth: 30,
  191. itemStyle: {
  192. borderRadius: [10, 10, 0, 0],
  193. color: param => this.colors[param.dataIndex]
  194. },
  195. },
  196. ]
  197. }
  198. chart.setOption(option)
  199. return chart
  200. },
  201. formatNumberWithCommas(number) {
  202. return new Intl.NumberFormat().format(number)
  203. },
  204. fetchDetailData() {
  205. console.log('获取每日明细数据', this.current, this.pageSize)
  206. // this.$api.getList(this.current, this.pageSize, res => {
  207. // let data = res.data;
  208. // this.detailDataList.push(...data.list);//在列表后面新增新获取的数据
  209. // this.totalPage = data.total;//获取数据总页数
  210. // })
  211. const timeout = setTimeout(() => {
  212. this.loadmore = 'loadmore'
  213. clearTimeout(timeout)
  214. }, 3000)
  215. },
  216. },
  217. }
  218. </script>
  219. <style lang="scss">
  220. .revenue-statistics {
  221. width: 100%;
  222. position: relative;
  223. padding: 16rpx 32rpx;
  224. box-sizing: border-box;
  225. .chart {
  226. width: 100%;
  227. height: 400rpx;
  228. }
  229. .chart-bottom {
  230. margin-top: 40rpx;
  231. .chart-bottom-item {
  232. margin: 16rpx 0;
  233. display: flex;
  234. justify-content: space-between;
  235. align-items: center;
  236. }
  237. }
  238. }
  239. </style>