statistics.vue 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. <template>
  2. <view class="order-statistics">
  3. <view class="select-date">
  4. <u-input
  5. style="flex: 1;"
  6. v-model="timeRange"
  7. type="select"
  8. :selectOpen="show"
  9. border
  10. placeholder="选择时间范围"
  11. @click="show = true"
  12. height="76rpx"
  13. />
  14. <view style="margin-left: 16rpx;"><u-icon name="download" size="48"></u-icon></view>
  15. <u-calendar
  16. v-model="show"
  17. mode="range"
  18. @change="bindDateChange"
  19. startText="开始日期"
  20. endText="结束日期"
  21. active-bg-color="#00C18A"
  22. active-color="#FFFFFF"
  23. range-bg-color="#00C18A"
  24. rangeColor="#FFFFFF"
  25. zIndex="9999999"
  26. >
  27. </u-calendar>
  28. </view>
  29. <!-- 四个框框(统计数据) -->
  30. <view class="overview-data-box">
  31. <view class="data-item" v-for="(item, index) in overviewData" :key="index">
  32. <data-item :dataItem="item" :globalImages="globalImages"/>
  33. </view>
  34. </view>
  35. <u-card v-show="!show" padding="32" full :showHead="false">
  36. <view slot="body" style="width: 100%;height: 400rpx;position: relative;">
  37. <BtnGroup v-model="orderSelect" :defaultVal="2" :options="orderOptions"></BtnGroup>
  38. <uni-ec-canvas class="uni-ec-canvas" id="order-revenue" canvas-id="order-revenue-chart" :ec="ec1" ref="canvas1"></uni-ec-canvas>
  39. </view>
  40. </u-card>
  41. <view></view>
  42. <u-card v-show="!show" padding="32" full :showHead="false">
  43. <view slot="body" style="width: 100%;height: 400rpx;position: relative;">
  44. <BtnGroup v-model="compareSelect" :defaultVal="2" :options="compareOptions"></BtnGroup>
  45. <uni-ec-canvas class="uni-ec-canvas" id="data-compare" canvas-id="data-compare-chart" :ec="ec2" ref="canvas2"></uni-ec-canvas>
  46. </view>
  47. </u-card>
  48. </view>
  49. </template>
  50. <script>
  51. import DataItem from './DataItem.vue'
  52. import BtnGroup from './BtnGroup.vue'
  53. import uniEcCanvas from '@/components/uni-ec-canvas/uni-ec-canvas'
  54. import * as echarts from '@/components/uni-ec-canvas/echarts.js'
  55. import { waitForGlobalImages } from '@/utils/globalImageLoader'
  56. export default {
  57. components: { DataItem, BtnGroup, uniEcCanvas },
  58. data() {
  59. return {
  60. globalImages: null,
  61. // 表示选中的日期,格式为"YYYY-MM-DD"
  62. timeRange: null,
  63. show: false,
  64. overviewData: [
  65. { title: '订单总量', value: '1248', status: 'up', fluctuate: '12.5%', bg: '#E8FBF6', valueColor: '#00C18A' },
  66. { title: '总收入', value: '¥8642', status: 'up', fluctuate: '8.3%', bg: '#FCF6EC', valueColor: '#E6A23C' },
  67. { title: '完成率', value: '98.7%', status: 'up', fluctuate: '1.2%', bg: '#ECF5FF', valueColor: '#409EFF' },
  68. { title: '平均评分', value: '4.9', status: 'down', fluctuate: '0.1', bg: '#FFE9E9', valueColor: '#F56C6C' },
  69. ],
  70. ec1: {
  71. option: {},
  72. },
  73. ec2: {
  74. option: {},
  75. },
  76. a: '',
  77. orderSelect: null,
  78. orderOptions: [
  79. { label: '日', value: 1 },
  80. { label: '周', value: 2 },
  81. { label: '月', value: 3 },
  82. ],
  83. compareSelect: null,
  84. compareOptions: [
  85. { label: '环比', value: 1 },
  86. { label: '同比', value: 2 },
  87. ],
  88. }
  89. },
  90. onLoad(e) {
  91. waitForGlobalImages().then((path) => {
  92. this.globalImages = path
  93. })
  94. setTimeout(() => {
  95. this.$nextTick(() => {
  96. this.$refs.canvas1.init(this.initChart1)
  97. this.$refs.canvas2.init(this.initChart2)
  98. })
  99. }, 20)
  100. },
  101. watch: {
  102. orderSelect(newVal) {
  103. if(newVal) {
  104. this.$refs.canvas1.init(this.initChart1)
  105. }
  106. },
  107. compareSelect(newVal) {
  108. if(newVal) {
  109. this.$refs.canvas2.init(this.initChart2)
  110. }
  111. },
  112. },
  113. methods: {
  114. // { startYear, startMonth, startDay, startDate, startWeek, endYear, endMonth, endDay, endDate, endWeek }
  115. bindDateChange(event) {
  116. this.timeRange = event.startDate + ' - ' + event.endDate
  117. },
  118. initChart1(canvas, width, height, canvasDpr) {
  119. let chart = echarts.init(canvas, null, {
  120. width: width,
  121. height: height,
  122. devicePixelRatio: canvasDpr
  123. })
  124. canvas.setChart(chart)
  125. let option = {
  126. title: {
  127. text: '订单与收入趋势',
  128. left: 0,
  129. top: 0,
  130. textStyle: {
  131. fontSize: 14
  132. },
  133. },
  134. grid: {
  135. top: '36%',
  136. left: '5%',
  137. right: '0%',
  138. bottom: '20%',
  139. containLabel: true,
  140. },
  141. legend: {
  142. bottom: 0,
  143. itemGap: 20,
  144. data: ['订单量', '收入'],
  145. },
  146. xAxis: {
  147. type: 'category',
  148. data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],
  149. boundaryGap: ['20%', '20%'],
  150. axisTick: {
  151. show: false,
  152. },
  153. splitLine: {
  154. show: false,
  155. },
  156. axisLine: {
  157. lineStyle: {
  158. color: '#E4E7ED',
  159. },
  160. },
  161. axisLabel: {
  162. color: '#333333',
  163. }
  164. },
  165. yAxis: [
  166. {
  167. type: 'value',
  168. name: '订单量',
  169. nameGap: 24,
  170. nameLocation: 'end',
  171. nameTextStyle: {
  172. align: 'right',
  173. padding: [0, 10, 0, 0],
  174. color: '#333333',
  175. },
  176. boundaryGap: ['10%', '10%'],
  177. axisTick: {
  178. show: false,
  179. },
  180. axisLine: {
  181. show: false,
  182. },
  183. splitLine: {
  184. lineStyle: {
  185. color: '#E4E7ED',
  186. },
  187. },
  188. axisLabel: {
  189. color: '#333333',
  190. },
  191. splitNumber: 3,
  192. },
  193. {
  194. type: 'value',
  195. name: '收入',
  196. nameGap: 24,
  197. nameLocation: 'end',
  198. nameTextStyle: {
  199. align: 'left',
  200. padding: [0, 0, 0, 20],
  201. color: '#333333',
  202. },
  203. axisLabel: {
  204. formatter: '¥ {value}',
  205. color: '#333333',
  206. },
  207. boundaryGap: ['10%', '10%'],
  208. axisTick: {
  209. show: false,
  210. },
  211. axisLine: {
  212. show: false,
  213. },
  214. splitLine: {
  215. lineStyle: {
  216. color: '#E4E7ED',
  217. },
  218. },
  219. splitNumber: 3,
  220. },
  221. ],
  222. series: [
  223. {
  224. name: '订单量',
  225. data: [120, 200, 150, 80, 70, 110, 130],
  226. type: 'bar',
  227. yAxisIndex: 0,
  228. itemStyle: {
  229. color: '#E8FBF6',
  230. borderRadius: [5, 5, 0, 0]
  231. },
  232. barWidth: 10,
  233. },
  234. {
  235. name: '收入',
  236. data: [120, 200, 150, 80, 70, 110, 130],
  237. type: 'line',
  238. yAxisIndex: 1,
  239. itemStyle: {
  240. color: '#00C18A',
  241. },
  242. // symbolSize: 8,
  243. }
  244. ]
  245. }
  246. chart.setOption(option)
  247. return chart
  248. },
  249. initChart2(canvas, width, height, canvasDpr) {
  250. let chart = echarts.init(canvas, null, {
  251. width: width,
  252. height: height,
  253. devicePixelRatio: canvasDpr
  254. })
  255. canvas.setChart(chart)
  256. let option = {
  257. title: {
  258. text: '数据对比',
  259. left: 0,
  260. top: 0,
  261. textStyle: {
  262. fontSize: 14
  263. },
  264. },
  265. grid: {
  266. top: '36%',
  267. left: '5%',
  268. right: '0%',
  269. bottom: '20%',
  270. containLabel: true,
  271. },
  272. legend: {
  273. bottom: 0,
  274. itemGap: 20,
  275. data: ['本周', '上周'],
  276. icon: 'roundRect',
  277. },
  278. xAxis: {
  279. type: 'category',
  280. data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],
  281. boundaryGap: [50, 50],
  282. axisTick: {
  283. show: false,
  284. },
  285. splitLine: {
  286. show: false,
  287. }
  288. },
  289. yAxis: {
  290. type: 'value',
  291. name: '订单量',
  292. nameGap: 30,
  293. nameLocation: 'end',
  294. nameTextStyle: {
  295. align: 'right',
  296. padding: [0, 10, 0, 0]
  297. },
  298. boundaryGap: ['10%', '10%'],
  299. splitNumber: 4,
  300. axisTick: {
  301. show: false,
  302. },
  303. axisLine: {
  304. show: false,
  305. },
  306. splitLine: {
  307. lineStyle: {
  308. color: '#E4E7ED',
  309. },
  310. },
  311. },
  312. series: [
  313. {
  314. name: '本周',
  315. data: [120, 200, 150, 80, 70, 110, 130],
  316. type: 'bar',
  317. itemStyle: {
  318. color: '#F56C6C',
  319. borderRadius: [5, 5, 0, 0]
  320. },
  321. barWidth: 10,
  322. },
  323. {
  324. name: '上周',
  325. data: [110, 190, 130, 60, 50, 90, 110],
  326. type: 'bar',
  327. itemStyle: {
  328. color: '#00C18A',
  329. borderRadius: [5, 5, 0, 0]
  330. },
  331. barWidth: 10,
  332. }
  333. ]
  334. }
  335. chart.setOption(option)
  336. return chart
  337. },
  338. },
  339. }
  340. </script>
  341. <style lang="scss">
  342. .order-statistics {
  343. width: 100%;
  344. position: relative;
  345. padding: 16rpx 32rpx;
  346. box-sizing: border-box;
  347. .select-date {
  348. display: flex;
  349. justify-content: space-between;
  350. align-items: center;
  351. margin-top: 16rpx;
  352. }
  353. .overview-data-box {
  354. margin-top: 24rpx;
  355. display: flex;
  356. flex-wrap: wrap;
  357. gap: 24rpx; /* 控制间距 */
  358. width: 100%;
  359. .data-item {
  360. flex: 1 1 calc(50% - 24rpx);
  361. position: relative;
  362. }
  363. }
  364. }
  365. </style>