Home.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617
  1. <template>
  2. <div class="home">
  3. <a-alert message="欢迎登录洗车机运营管理平台系统" type="info" showIcon />
  4. <div class="report-page">
  5. <!-- 查询条件 -->
  6. <a-row>
  7. <a-card class="search-panel">
  8. <div class="toolsBar">
  9. <a-form ref="searchForm" :model="searchForm" layout="inline">
  10. <a-form-item props="queryWord" label="统计区间">
  11. <a-range-picker
  12. style="width: 220px;"
  13. @change="dateChange"
  14. v-model.trim="searchForm.queryWord"
  15. :disabledDate="disabledDate"
  16. />
  17. </a-form-item>
  18. <a-form-item props="storeIds" label="洗车网点">
  19. <a-select
  20. allowClear
  21. mode="multiple"
  22. placeholder="选择网点"
  23. v-model="searchForm.storeIdList"
  24. style="width: 200px"
  25. >
  26. <a-select-option v-for="item in storesList" :value="item.id" :key="item.id">
  27. {{ item.name }}
  28. </a-select-option>
  29. </a-select>
  30. </a-form-item>
  31. <a-form-item>
  32. <a-button type="primary" class="search-btn" @click="handleSearch()">查询</a-button>
  33. <a-button type="" style="margin-left: 10px;" @click="handleReset()">重置</a-button>
  34. </a-form-item>
  35. <a-form-item>
  36. 快捷筛选:
  37. <span
  38. :class="['searchItem',curentType==item.type?'active':'']"
  39. v-for="(item,index) in tabList"
  40. :key="index"
  41. @click="getCurentSearchTime(item)">{{ item.name }}</span>
  42. </a-form-item>
  43. </a-form>
  44. </div>
  45. </a-card>
  46. </a-row>
  47. <!-- 洗车量数据 -->
  48. <a-card class="panel" title="洗车量趋势">
  49. <!-- 洗车量趋势图表展示 -->
  50. <chart-line
  51. style="height: 300px;"
  52. color="#6C6FBE"
  53. :yMax="1000"
  54. yUnit="台"
  55. :xAxisRotate="resize"
  56. :xAxisData="XdaysData"
  57. :seriesData="washCarsChartData"
  58. text="" />
  59. <span v-if="isNoData" class="noData">暂无数据</span>
  60. </a-card>
  61. <!-- 各洗车类型数据 -->
  62. <a-card class="panel " title="各洗车类型数据">
  63. <a-row :gutter="24">
  64. <a-col :md="4" :lg="4">
  65. <a-card class="border-radius background-skyblue">
  66. <div class="module-list ">
  67. <span>{{ chartData.KX }}</span>
  68. <p>快速洗车</p>
  69. </div>
  70. </a-card>
  71. </a-col>
  72. <a-col :md="4" :lg="4">
  73. <a-card class="border-radius background-greenBlue">
  74. <div class="module-list ">
  75. <span>{{ chartData.JX }}</span>
  76. <p>精致洗车</p>
  77. </div>
  78. </a-card>
  79. </a-col>
  80. <a-col :md="4" :lg="4">
  81. <a-card class="border-radius background-blackGreen">
  82. <div class="module-list ">
  83. <span>{{ chartData.DLX }}</span>
  84. <p>打蜡精洗</p>
  85. </div>
  86. </a-card>
  87. </a-col>
  88. </a-row>
  89. <!-- 洗车类型数据图表展示 -->
  90. <a-row :gutter="24">
  91. <a-col class="tab-card">
  92. <span :class="['tab-card-item',currentTabChart=='tab1'?'checked-item':'']" @click="currentTabChart='tab1'">详情数据</span>
  93. <span :class="['tab-card-item',currentTabChart=='tab2'?'checked-item':'']" @click="currentTabChart='tab2'">变化趋势</span>
  94. </a-col>
  95. <!-- 详情数据 -->
  96. <a-col span="24" v-if="currentTabChart=='tab1'">
  97. <chart-bar
  98. ref="ChartBar"
  99. style="height: 300px;"
  100. color="#6C6FBE"
  101. :xAxisRotate="resize"
  102. :yMax="1000"
  103. yUnit="台"
  104. :xAxisData="XdaysData"
  105. :seriesData="washTypeBarData"
  106. text="" />
  107. <span v-if="isNoData" class="noData">暂无数据</span>
  108. </a-col>
  109. <!-- 变化趋势 -->
  110. <a-col span="24" v-if="currentTabChart=='tab2'">
  111. <chart-line
  112. ref="ChartLine"
  113. style="height: 300px;"
  114. color="#6C6FBE"
  115. yUnit="台"
  116. :yMax="1000"
  117. :xAxisRotate="resize"
  118. :xAxisData="XdaysData"
  119. :seriesData="washTypeLineData"
  120. text="" />
  121. <span v-if="isNoData" class="noData">暂无数据</span>
  122. </a-col>
  123. </a-row>
  124. </a-card>
  125. <a-card class="panel chart-pie" title="各类型占比">
  126. <a-row :gutter="24">
  127. <a-col span="12">
  128. <chart-pie
  129. ref="chartPie"
  130. class="chartPie-box"
  131. :searchData="XdaysData"
  132. :value="washTypePieData"
  133. title="洗车总量(台)"
  134. :total="chartData.allOrderNum"
  135. :color="washTypePieColor"
  136. :xAxisRotate="resize"
  137. text="" />
  138. </a-col>
  139. <a-col span="12">
  140. <!-- 用券与未用券百分比展示 -->
  141. <chart-pie
  142. ref="serverChartPie"
  143. class="chartPie-box"
  144. :searchData="XdaysData"
  145. :value="couponChartData"
  146. title="洗车总量(台)"
  147. :total="chartData.allOrderNum"
  148. :color="couponColor"
  149. :xAxisRotate="resize"
  150. text="" />
  151. </a-col>
  152. </a-row>
  153. </a-card>
  154. </div>
  155. </div>
  156. </template>
  157. <script>
  158. import {
  159. ChartPie,
  160. ChartBar,
  161. ChartLine
  162. } from '@/components/Echarts'
  163. import _ from 'lodash'
  164. import getDate from '@/libs/getDate'
  165. import moment from 'moment'
  166. import { getOrderstatistics } from '@/api/report-charts.js'
  167. import {
  168. storeList
  169. } from '@/api/order.js'
  170. export default {
  171. name: 'Home',
  172. components: {
  173. ChartPie,
  174. ChartBar,
  175. ChartLine
  176. },
  177. watch: {
  178. screenWidth (val) {
  179. // 为了避免频繁触发resize函数,使用定时器
  180. if (!this.timer) {
  181. this.screenWidth = val
  182. this.timer = true
  183. const that = this
  184. setTimeout(function () {
  185. // that.screenWidth = that.$store.state.canvasWidth
  186. console.log(that.screenWidth)
  187. that.timer = false
  188. }, 400)
  189. }
  190. }
  191. },
  192. computed: {
  193. resize () {
  194. console.log(this.screenWidth, 'this.screenWidth')
  195. if (this.screenWidth < 1640) {
  196. return 40
  197. } else {
  198. return 0
  199. }
  200. },
  201. // 各类型占比总计数据
  202. washTypePieData () {
  203. const data = [{
  204. 'name': '快速洗车',
  205. 'value': this.chartData.KX
  206. }, {
  207. 'name': '精致洗车',
  208. 'value': this.chartData.JX
  209. }, {
  210. 'name': '打蜡精洗',
  211. 'value': this.chartData.DLX
  212. }]
  213. return data
  214. },
  215. // 洗车用券量占比数据
  216. couponChartData () {
  217. const data = [{
  218. 'name': '未用券洗车量',
  219. 'value': this.chartData.notUseCouponOrderNum
  220. }, {
  221. 'name': '用券洗车量',
  222. 'value': this.chartData.useCouponOrderNum
  223. }]
  224. return data
  225. }
  226. },
  227. data () {
  228. return {
  229. screenWidth: document.body.clientWidth, // 这里是给到了一个默认值
  230. timer: false,
  231. form: this.$form.createForm(this, { name: 'searchForm' }),
  232. isNoData: false, // 是否有每天营业额及进店量数据
  233. storesList: [], // 洗车网点列表
  234. searchForm: {
  235. queryWord: null, // 时间查询条件,默认本周
  236. storeIdList: [] // 已选洗车网点
  237. },
  238. chartData: {
  239. KX: 0, // 快洗
  240. JX: 0, // 精洗
  241. DLX: 0, // 打蜡洗
  242. allOrderNum: 0, // 洗车总量
  243. useCouponOrderNum: 0, // 用券洗车量
  244. notUseCouponOrderNum: 0 // 未用券洗车量
  245. },
  246. // 快速删选tab
  247. tabList: [{
  248. name: '今天',
  249. type: 'today'
  250. },
  251. {
  252. name: '本周',
  253. type: 'thisWeek'
  254. },
  255. {
  256. name: '上周',
  257. type: 'lastWeek'
  258. },
  259. {
  260. name: '本月',
  261. type: 'thisMonth'
  262. }
  263. ],
  264. curentType: 'thisWeek', // 当前所选时间查询类型
  265. beginDate: null, // 开始时间
  266. endDate: null, // 结束时间
  267. // 洗车量图表数据
  268. washCarsChartData: [{
  269. name: '全部洗车量',
  270. type: 'line',
  271. data: []
  272. },
  273. {
  274. name: '用券洗车量',
  275. type: 'line',
  276. data: []
  277. }
  278. ],
  279. couponColor: ['#d48265', '#ff55ff'],
  280. // 洗车类型数据
  281. currentTabChart: 'tab1', // 洗车类型详情数据与变化趋势的tab 默认展示详情数据
  282. XdaysData: [], // 图表X轴时间集合
  283. // 洗车类型柱状图表数据
  284. washTypeBarData: [{
  285. name: '快速洗车',
  286. type: 'bar',
  287. data: []
  288. },
  289. {
  290. name: '精致洗车',
  291. type: 'bar',
  292. data: []
  293. },
  294. {
  295. name: '打蜡精洗',
  296. type: 'bar',
  297. data: []
  298. }
  299. ],
  300. // 洗车类型折线图表数据
  301. washTypeLineData: [{
  302. name: '快速洗车',
  303. type: 'line',
  304. data: []
  305. },
  306. {
  307. name: '精致洗车',
  308. type: 'line',
  309. data: []
  310. },
  311. {
  312. name: '打蜡精洗',
  313. type: 'line',
  314. data: []
  315. }
  316. ],
  317. // 各类型占比
  318. washTypePieColor: ['#ffaa00', '#00ff00', '#00aaff', '#ff55ff', '#1dc5d4', '#8465c7', '#00ffff'],
  319. databack: {
  320. couponChartData: [],
  321. washTypePieData: [],
  322. chartData: {}
  323. }
  324. }
  325. },
  326. created () {
  327. },
  328. methods: {
  329. moment,
  330. // 时间改变
  331. dateChange (dates) {
  332. console.log(dates, this.searchForm.queryWord, 'dddddd')
  333. this.curentType = ''
  334. },
  335. // 不可选日期
  336. disabledDate (date) {
  337. return (date && date.valueOf() > Date.now()) || (date.valueOf() < Date.now() - (90 * 24 * 60 * 60 * 1000))
  338. },
  339. // 查询洗车网点
  340. getListStore () {
  341. storeList({ pageNo: 1, pageSize: 1000 }).then(res => {
  342. console.log(res)
  343. this.storesList = res.data.list ? res.data.list : []
  344. })
  345. },
  346. // 页面初始化
  347. pageInit () {
  348. this.form.resetFields()
  349. this.databack = {
  350. couponChartData: _.cloneDeep(this.couponChartData),
  351. washTypePieData: _.cloneDeep(this.washTypePieData),
  352. chartData: _.cloneDeep(this.chartData)
  353. }
  354. },
  355. // 查询
  356. handleSearch () {
  357. this.showChart = false
  358. if (this.searchForm.queryWord != ',' && this.searchForm.queryWord.length) {
  359. const searchTime = this.searchForm.queryWord.toString().split(',')
  360. this.beginDate = this.exitTime(searchTime[0])
  361. this.endDate = this.exitTime(searchTime[1])
  362. this.getPageData()
  363. } else {
  364. this.$message.error('请选择统计区间')
  365. }
  366. },
  367. // 重置
  368. handleReset () {
  369. this.searchForm.storeIdList = []
  370. this.curentType = 'thisWeek'
  371. this.getCurentSearchTime()
  372. },
  373. // 格式化时间
  374. exitTime (time) {
  375. const D = new Date(time)
  376. const RES_DATE = D.getFullYear() + '-' + this.p((D.getMonth() + 1)) + '-' + this.p(D.getDate())
  377. return RES_DATE
  378. },
  379. // p为不够10添加0的函数
  380. p (s) {
  381. return s < 10 ? '0' + s : s
  382. },
  383. // 获取快速查询时间 并 赋值到时间选择框中
  384. getCurentSearchTime (item) {
  385. this.curentType = item ? item.type : this.curentType
  386. const quickType = {
  387. lastMonth: [moment(getDate.getLastMonthDays().starttime), moment(getDate.getLastMonthDays().endtime)],
  388. thisMonth: [moment(getDate.getCurrMonthDays().starttime), moment(getDate.getCurrMonthDays().endtime)],
  389. lastWeek: [moment(getDate.getLastWeekDays().starttime), moment(getDate.getLastWeekDays().endtime)],
  390. thisWeek: [moment(getDate.getCurrWeekDays().starttime), moment(getDate.getCurrWeekDays().endtime)],
  391. yesterday: [moment(getDate.getYesterday().starttime), moment(getDate.getYesterday().endtime)],
  392. today: [moment(getDate.getToday().starttime), moment(getDate.getToday().endtime)]
  393. }
  394. this.searchForm.queryWord = quickType[this.curentType]
  395. this.beginDate = quickType[this.curentType][0].format('YYYY-MM-DD')
  396. this.endDate = quickType[this.curentType][1].format('YYYY-MM-DD')
  397. console.log(this.searchForm.queryWord, '1111111')
  398. this.getPageData()
  399. },
  400. // 根据查询条件获取所有数据
  401. getPageData () {
  402. this.XdaysData = [] // x轴置空
  403. const _date = {
  404. beginDate: this.beginDate,
  405. endDate: this.endDate,
  406. storeIdList: this.searchForm.storeIdList
  407. }
  408. console.log(_date, '_date')
  409. getOrderstatistics(_date).then(res => {
  410. console.log(res, 'rrrrrrr')
  411. if (res.status == 200) {
  412. this.chartData = res.data
  413. if (res.data.dateList && res.data.dateList.length) {
  414. this.isNoData = false
  415. this.filterData(res.data.dateList)
  416. } else {
  417. this.isNoData = true
  418. }
  419. } else {
  420. this.isNoData = true
  421. }
  422. })
  423. },
  424. // 整合图表每天数据
  425. filterData (data) {
  426. const days = [] // 日期合集
  427. const kxData = [] // 快速洗车数据
  428. const jxData = [] // 精致洗车数据
  429. const dlxData = [] // 打蜡洗车数据
  430. const totalData = [] // 全部洗车量数据
  431. const useCouponData = [] // 用券洗车量数据
  432. data.map(item => {
  433. const itemDay = item.date.split('-')
  434. const month = Number(itemDay[1])
  435. const day = Number(itemDay[2])
  436. const time = month + '月' + day + '日'
  437. days.push(time)
  438. kxData.push(item.KX)
  439. jxData.push(item.JX)
  440. dlxData.push(item.DLX)
  441. totalData.push(item.allOrderNum)
  442. useCouponData.push(item.useCouponOrderNum)
  443. })
  444. this.XdaysData = days
  445. const washTypeData = [kxData, jxData, dlxData]
  446. console.log(washTypeData, 'washTypeData')
  447. // 洗车类型柱状图表数据
  448. this.washTypeBarData.map((item, index) => {
  449. item.data = washTypeData[index]
  450. })
  451. // 洗车类型折线图表数据
  452. this.washTypeLineData.map((item, index) => {
  453. item.data = washTypeData[index]
  454. })
  455. // 洗车量图表数据赋值
  456. this.washCarsChartData[0].data = totalData
  457. this.washCarsChartData[1].data = useCouponData
  458. }
  459. },
  460. beforeRouteEnter (to, from, next) {
  461. next(vm => {
  462. vm.pageInit()
  463. vm.getListStore() // 获取网点列表
  464. vm.curentType = 'thisWeek'
  465. vm.getCurentSearchTime()
  466. })
  467. },
  468. // 将 reisze 事件在 vue mounted 的时候 去挂载一下它的方法
  469. mounted () {
  470. const that = this
  471. window.onresize = () => {
  472. return (() => {
  473. window.screenWidth = document.body.clientWidth
  474. that.screenWidth = window.screenWidth
  475. })()
  476. }
  477. }
  478. }
  479. </script>
  480. <style lang="less" scoped>
  481. .home{
  482. width: 100%;
  483. }
  484. .report-page {
  485. margin-top: 10px;
  486. height: calc(100vh - 285px);
  487. overflow-y: scroll;
  488. overflow-x: hidden;
  489. .search-panel {
  490. .ivu-card-body>div {
  491. display: inline-block;
  492. margin-right: 20px;
  493. }
  494. .desc {
  495. color: #999;
  496. }
  497. .searchItem {
  498. padding: 8px 20px;
  499. border: 1px dashed #EEEEEE;
  500. margin: 0 5px;
  501. border-radius: 5px;
  502. }
  503. .active {
  504. background-color: #ff9900;
  505. color: #fff;
  506. border: none;
  507. }
  508. }
  509. .panel {
  510. margin-top: 10px;
  511. background-color: #FFFFFF;
  512. .noData {
  513. background-color: rgba(50, 50, 50, 0.7);
  514. color: #fff;
  515. padding: 15px 30px;
  516. position: absolute;
  517. top: 40%;
  518. left: 40%;
  519. }
  520. .chartPie-box{
  521. height: 300px;
  522. width: 100%;
  523. }
  524. .panel-title {
  525. font-size: 18px;
  526. color: #333;
  527. padding-bottom: 5px;
  528. }
  529. .tab-card {
  530. float: right;
  531. .tab-card-item {
  532. padding: 5px 10px;
  533. border: 1px solid #eee;
  534. cursor: pointer;
  535. }
  536. .checked-item {
  537. border-color: #2d8cf0;
  538. color: #2d8cf0;
  539. }
  540. }
  541. .border-radius {
  542. border-radius: 15px;
  543. }
  544. .background-blue {
  545. background-color: #157edf;
  546. }
  547. .background-green {
  548. background-color: #29aa4f;
  549. }
  550. .background-yellow {
  551. background-color: #dbb211;
  552. }
  553. .background-pop {
  554. background-color: #8544e0;
  555. }
  556. .background-black {
  557. background-color: #1f2c65;
  558. }
  559. .background-pink {
  560. background-color: #d23e57;
  561. }
  562. .background-skyblue {
  563. background-color: #00aaff;
  564. }
  565. .background-greenBlue {
  566. background-color: #1b9eaa;
  567. }
  568. .background-blackGreen {
  569. background-color: #357c09;
  570. }
  571. .background-orange {
  572. background-color: #d2701b;
  573. }
  574. }
  575. .module-list {
  576. display: flex;
  577. justify-content: center;
  578. align-items: center;
  579. flex-direction: column;
  580. color: #FFFFFF;
  581. span {
  582. font-weight: 600;
  583. font-size: 20px;
  584. }
  585. }
  586. .module-icon {
  587. width: 52px;
  588. height: 54px;
  589. }
  590. }
  591. </style>