home.vue 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655
  1. <template>
  2. <div>
  3. <el-row :gutter="10">
  4. <el-col :span="24">
  5. <el-card class="box-card" shadow="none">
  6. <div class="htitle">活动概览</div>
  7. <div class="nums adf">
  8. <div class="nums-pre adffc">
  9. <div class="nums-pre-title adfac">
  10. <img src="@/assets/img/home_activity1.png">
  11. <span>活动总数</span>
  12. </div>
  13. <div class="nums-pre-sz">{{ 458 }}</div>
  14. <div class="nums-pre-text adfac">较昨日<i class="el-icon-bottom xj"></i>{{ 23 }}</div>
  15. </div>
  16. <div class="nums-pre adffc">
  17. <div class="nums-pre-title adfac">
  18. <img src="@/assets/img/home_activity2.png">
  19. <span>未开始活动</span>
  20. </div>
  21. <div class="nums-pre-sz">{{ 158 }}</div>
  22. <div class="nums-pre-text adfac">较昨日<i class="el-icon-bottom xj"></i>{{ 0 }}</div>
  23. </div>
  24. <div class="nums-pre adffc">
  25. <div class="nums-pre-title adfac">
  26. <img src="@/assets/img/home_activity3.png">
  27. <span>进行中活动</span>
  28. </div>
  29. <div class="nums-pre-sz">{{ 140 }}</div>
  30. <div class="nums-pre-text adfac">较昨日<i class="el-icon-bottom xj"></i>{{ 23 }}</div>
  31. </div>
  32. <div class="nums-pre adffc">
  33. <div class="nums-pre-title adfac">
  34. <img src="@/assets/img/home_activity4.png">
  35. <span>已结束活动</span>
  36. </div>
  37. <div class="nums-pre-sz">{{ 546 }}</div>
  38. <div class="nums-pre-text adfac">较昨日<i class="el-icon-top ss"></i>{{ 2 }}</div>
  39. </div>
  40. <div class="nums-pre adffc">
  41. <div class="nums-pre-title adfac">
  42. <img src="@/assets/img/home_activity5.png">
  43. <span>累计报名人数</span>
  44. </div>
  45. <div class="nums-pre-sz">{{ 5098 }}</div>
  46. <div class="nums-pre-text adfac">较昨日<i class="el-icon-top ss"></i>{{ 280 }}</div>
  47. </div>
  48. <div class="nums-pre adffc">
  49. <div class="nums-pre-title adfac">
  50. <img src="@/assets/img/home_activity6.png">
  51. <span>活动参与率</span>
  52. </div>
  53. <div class="nums-pre-sz">{{ 89 }}%</div>
  54. <div class="nums-pre-text adfac">较昨日<i class="el-icon-top ss"></i>{{ 100 }}</div>
  55. </div>
  56. <div class="nums-pre adffc">
  57. <div class="nums-pre-title adfac">
  58. <img src="@/assets/img/home_activity7.png">
  59. <span>累计导入爱心值总额</span>
  60. </div>
  61. <div class="nums-pre-sz">{{ 985000 }}</div>
  62. <div class="nums-pre-text adfac">较昨日<i class="el-icon-top ss"></i>{{ 8000 }}</div>
  63. </div>
  64. </div>
  65. </el-card>
  66. </el-col>
  67. </el-row>
  68. <el-row :gutter="10" style="margin-top: 10px;">
  69. <el-col :span="8">
  70. <el-card class="box-card" shadow="none">
  71. <div class="htitle">用户来源</div>
  72. <div class="chartbox">
  73. <div ref="yhlyRef" style="width: 100%;height: 100%;"></div>
  74. </div>
  75. </el-card>
  76. </el-col>
  77. <el-col :span="8">
  78. <el-card class="box-card" shadow="none">
  79. <div class="htitle">男女比例</div>
  80. <div class="chartbox">
  81. <div ref="nnblRef" style="width: 100%;height: 100%;"></div>
  82. </div>
  83. </el-card>
  84. </el-col>
  85. <el-col :span="8">
  86. <el-card class="box-card" shadow="none">
  87. <div class="htitle">活动成员年龄分布</div>
  88. <div class="chartbox">
  89. <div ref="nlfbRef" style="width: 100%;height: 100%;"></div>
  90. </div>
  91. </el-card>
  92. </el-col>
  93. </el-row>
  94. <el-row :gutter="10" style="margin-top: 10px;">
  95. <el-col :span="8">
  96. <el-card class="box-card" shadow="none">
  97. <div class="htitle">爱心值变化趋势</div>
  98. <div class="chartbox two">
  99. <div class="query adfac">
  100. <el-select v-model="year" placeholder="年份" style="width: 82px;margin-left: 8px;">
  101. <el-option v-for="item in yearList" :label="item" :value="item" :key="item"></el-option>
  102. </el-select>
  103. <el-select v-model="month" placeholder="月份" style="width: 82px;margin-left: 8px;">
  104. <el-option v-for="item in 12" :label="item+'月'" :value="item" :key="item"></el-option>
  105. </el-select>
  106. <el-select v-model="quarter" placeholder="季度" style="width: 82px;margin-left: 8px;">
  107. <el-option v-for="item in 4" :label="item+'季度'" :value="item" :key="item"></el-option>
  108. </el-select>
  109. </div>
  110. <div ref="bhqsRef" style="width: 100%;height: 100%;"></div>
  111. </div>
  112. </el-card>
  113. </el-col>
  114. <el-col :span="8">
  115. <el-card class="box-card" shadow="none">
  116. <div class="htitle">活动参与用户排行榜</div>
  117. <div class="chartbox two adffc">
  118. <div class="th adf">
  119. <div class="th-pre tp1">排名</div>
  120. <div class="th-pre tp2">姓名</div>
  121. <div class="th-pre tp3">渠道</div>
  122. <div class="th-pre tp4">参与次数</div>
  123. </div>
  124. <div class="list">
  125. <div class="list-item adf" v-for="(item,index) in 8" :key="index">
  126. <div class="list-item-pre lip1 adfacjc">
  127. <div :class="{'red':index===0,'yellow':index===1,'green':index===2}">{{ index + 1 }}</div>
  128. </div>
  129. <div class="list-item-pre lip2">{{ '周晓瑾' }}</div>
  130. <div class="list-item-pre lip3">{{ '建设银行' }}</div>
  131. <div class="list-item-pre lip4">{{ '999次' }}</div>
  132. </div>
  133. </div>
  134. </div>
  135. </el-card>
  136. </el-col>
  137. <el-col :span="8">
  138. <el-card class="box-card" shadow="none">
  139. <div class="htitle">热门活动排名</div>
  140. <div class="chartbox two adffc">
  141. <div class="th adf">
  142. <div class="th-pre tp1">排名</div>
  143. <div class="th-pre tp2">活动名称</div>
  144. <div class="th-pre tp3">爱心值捐赠量</div>
  145. <div class="th-pre tp4">参与人数</div>
  146. </div>
  147. <div class="list">
  148. <div class="list-item adf" v-for="(item,index) in 8" :key="index">
  149. <div class="list-item-pre lip1 adfacjc">
  150. <div :class="{'red':index===0,'yellow':index===1,'green':index===2}">{{ index + 1 }}</div>
  151. </div>
  152. <div class="list-item-pre lip2">{{ '环保知识知多少' }}</div>
  153. <div class="list-item-pre lip3">{{ '9527' }}</div>
  154. <div class="list-item-pre lip4">{{ '888人' }}</div>
  155. </div>
  156. </div>
  157. </div>
  158. </el-card>
  159. </el-col>
  160. </el-row>
  161. </div>
  162. </template>
  163. <script>
  164. import * as echarts from 'echarts'
  165. export default {
  166. data () {
  167. return {
  168. year: '',
  169. yearList: [new Date().getFullYear(), new Date().getFullYear() - 1, new Date().getFullYear() - 2, new Date().getFullYear() - 3, new Date().getFullYear() - 4],
  170. month: '',
  171. quarter: ''
  172. }
  173. },
  174. mounted () {
  175. this.initYhlyChart()
  176. this.initNnblChart()
  177. this.initNlfbChart()
  178. this.initBhqsChart()
  179. },
  180. methods: {
  181. initYhlyChart () {
  182. let myChart = echarts.init(this.$refs.yhlyRef)
  183. let echartData = [
  184. {
  185. value: 899,
  186. name: '中国银行'
  187. },
  188. {
  189. value: 899,
  190. name: '平安银行'
  191. },
  192. {
  193. value: 1889,
  194. name: '招商银行'
  195. },
  196. {
  197. value: 1199,
  198. name: '建设银行'
  199. },
  200. {
  201. value: 599,
  202. name: '工商银行'
  203. },
  204. {
  205. value: 399,
  206. name: '浦发银行'
  207. }
  208. ]
  209. let seriesData = echartData.map((item, index) => {
  210. return {
  211. ...item,
  212. actValue: item.value,
  213. label: {
  214. show: true,
  215. position: 'outside',
  216. borderRadius: 50,
  217. padding: [10, -10, 3, -3],
  218. textStyle: {
  219. fontSize: 10
  220. },
  221. formatter: '{white|{b}}\n{three| {d}人}',
  222. rich: {
  223. test: {},
  224. white: {
  225. align: 'center',
  226. color: '#989998',
  227. fontSize: 14
  228. },
  229. three: {
  230. color: '#252525',
  231. align: 'center',
  232. padding: [6, 0],
  233. fontSize: 14,
  234. fontWeight: 600
  235. }
  236. }
  237. }
  238. }
  239. })
  240. let option = {
  241. title: {
  242. show: true,
  243. text: '总人数',
  244. itemGap: 10,
  245. x: 'center',
  246. y: '130',
  247. subtext: '3897',
  248. textStyle: {
  249. fontSize: 14,
  250. color: '#989998'
  251. },
  252. subtextStyle: {
  253. fontSize: 14,
  254. color: '#252525',
  255. fontWeight: 600
  256. }
  257. },
  258. tooltip: {
  259. trigger: 'item',
  260. formatter: '{b}<br/>{c} 人',
  261. textStyle: {
  262. fontSize: 16,
  263. color: '#252525'
  264. }
  265. },
  266. series: [
  267. {
  268. name: 'pie',
  269. type: 'pie',
  270. radius: ['30%', '70%'],
  271. hoverAnimation: false,
  272. color: ['#0370F2', '#488CF6', '#4CAFF9', '#39CAFB', '#49DECA', '#16AECA'],
  273. itemStyle: {
  274. normal: {
  275. borderColor: '#fff',
  276. borderWidth: 2
  277. }
  278. },
  279. labelLine: {
  280. length: 10,
  281. length2: 70,
  282. lineStyle: {
  283. color: '#4CAFF9'
  284. }
  285. },
  286. data: seriesData
  287. }
  288. ]
  289. }
  290. myChart.setOption(option)
  291. this.resizeEcharts(this.$refs.yhlyRef)
  292. },
  293. initNnblChart () {
  294. let myChart = echarts.init(this.$refs.nnblRef)
  295. let echartsData = [{ value: 45, name: '女性' }, { value: 55, name: '男性' }]
  296. let colorList = ['#F4657A', '#49DECA']
  297. let option = {
  298. backgroundColor: '#FFF',
  299. color: colorList,
  300. tooltip: {
  301. trigger: 'item'
  302. },
  303. legend: {
  304. itemWidth: 10, // 图例标记的图形宽度
  305. itemHeight: 10, // 图例标记的图形高度
  306. icon: 'circle', // 图例项的 icon
  307. top: 'bottom', // 图例组件离容器右侧的距离
  308. itemGap: 50,
  309. data: echartsData, // 图例的数据数组
  310. formatter: (name) => { // 用来格式化图例文本
  311. const value = echartsData.find(item => item.name === name).value
  312. const sum = echartsData.reduce((total, item) => total + item.value, 0)
  313. return `{name|${name}}:{value|${value}人} {bl|${((value / sum) * 100).toFixed(0)}%}`
  314. },
  315. textStyle: {
  316. rich: {
  317. name: {
  318. color: '#6B7280',
  319. fontSize: 14
  320. },
  321. value: {
  322. color: '#252525',
  323. fontSize: 14,
  324. padding: [0, 4],
  325. fontWeight: 600
  326. },
  327. bl: {
  328. fontSize: 14,
  329. padding: [0, 4]
  330. }
  331. }
  332. }
  333. },
  334. series: [{
  335. name: '',
  336. type: 'pie',
  337. radius: ['30%', '70%'],
  338. center: ['50%', '50%'],
  339. roseType: 'radius',
  340. label: {
  341. show: true,
  342. position: 'outside',
  343. fontSize: 16,
  344. formatter: (params) => {
  345. return `{a|${params.name}${params.value}%}`
  346. },
  347. rich: {
  348. a: {
  349. align: 'left',
  350. fontSize: 14,
  351. color: '#252525'
  352. }
  353. }
  354. },
  355. labelLine: {
  356. length: 10,
  357. length2: 30
  358. },
  359. data: echartsData.map((item, index) => {
  360. return {
  361. ...item,
  362. label: {
  363. color: colorList[index]
  364. }
  365. }
  366. })
  367. }]
  368. }
  369. myChart.setOption(option)
  370. this.resizeEcharts(this.$refs.nnblRef)
  371. },
  372. initNlfbChart () {
  373. let myChart = echarts.init(this.$refs.nlfbRef)
  374. const dataValues = [24, 34, 16, 20, 6]
  375. const totalSum = dataValues.reduce((a, b) => a + b, 0)
  376. let option = {
  377. color: ['#05A9FE'],
  378. xAxis: {
  379. type: 'category',
  380. data: ['10岁以下', '10-20岁', '20-40岁', '40-60岁', '60岁以上']
  381. },
  382. yAxis: {
  383. type: 'value'
  384. },
  385. grid: {
  386. left: '2%',
  387. right: '2%',
  388. top: '16%',
  389. bottom: '2%'
  390. },
  391. series: [
  392. {
  393. data: dataValues,
  394. type: 'bar',
  395. label: {
  396. show: true,
  397. position: 'top',
  398. formatter: function (params) {
  399. const percentage = ((params.value / totalSum) * 100).toFixed(1)
  400. return percentage + '%'
  401. },
  402. color: '#252525',
  403. fontSize: 12
  404. },
  405. barMaxWidth: 25
  406. }
  407. ]
  408. }
  409. myChart.setOption(option)
  410. this.resizeEcharts(this.$refs.nlfbRef)
  411. },
  412. initBhqsChart () {
  413. let myChart = echarts.init(this.$refs.bhqsRef)
  414. let option = {
  415. color: ['#74E1F9', '#7C75FF'],
  416. xAxis: {
  417. type: 'category',
  418. boundaryGap: false,
  419. data: ['11-01', '11-02', '11-03', '11-04', '11-05', '11-06', '11-07']
  420. },
  421. yAxis: {
  422. type: 'value'
  423. },
  424. grid: {
  425. left: '1%',
  426. right: '1%',
  427. top: '20%',
  428. bottom: '1%',
  429. containLabel: true
  430. },
  431. legend: {
  432. data: ['累计导入', '累计捐赠'],
  433. top: '5%',
  434. left: '1%'
  435. },
  436. tooltip: {
  437. trigger: 'axis',
  438. axisPointer: {
  439. type: 'cross',
  440. label: {
  441. backgroundColor: '#6a7985'
  442. }
  443. }
  444. },
  445. series: [
  446. {
  447. name: '累计导入',
  448. data: [30, 170, 30, 80, 50, 160, 20],
  449. type: 'line',
  450. smooth: true,
  451. lineStyle: {
  452. width: 2
  453. },
  454. areaStyle: {
  455. opacity: 0.2,
  456. color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
  457. {
  458. offset: 0,
  459. color: '#74E1F9'
  460. },
  461. {
  462. offset: 1,
  463. color: '#4FEDDB'
  464. }
  465. ])
  466. },
  467. showSymbol: false
  468. },
  469. {
  470. name: '累计捐赠',
  471. data: [200, 90, 130, 90, 220, 60, 80],
  472. type: 'line',
  473. smooth: true,
  474. lineStyle: {
  475. width: 2
  476. },
  477. areaStyle: {
  478. opacity: 0.2,
  479. color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
  480. {
  481. offset: 0,
  482. color: '#7C75FF'
  483. },
  484. {
  485. offset: 1,
  486. color: '#3EB1E8'
  487. }
  488. ])
  489. },
  490. showSymbol: false
  491. }
  492. ]
  493. }
  494. myChart.setOption(option)
  495. this.resizeEcharts(this.$refs.bhqsRef)
  496. },
  497. resizeEcharts (ele) {
  498. let rate = 1920 / window.innerWidth
  499. if (ele.style) {
  500. ele.style.zoom = 1 * rate
  501. ele.style.transform = `scale(${1 / rate})`
  502. ele.style.transformOrigin = 'top left'
  503. }
  504. }
  505. }
  506. }
  507. </script>
  508. <style scoped lang="scss">
  509. .htitle {
  510. font-family: PingFang-SC, PingFang-SC;
  511. font-weight: bold;
  512. font-size: 16px;
  513. color: #252525;
  514. line-height: 16px;
  515. }
  516. .nums{
  517. margin-top: 26px;
  518. &-pre{
  519. width: calc(100% / 7);
  520. border-left: 1px solid #ECEEF5;
  521. padding-left: 16px;
  522. box-sizing: border-box;
  523. &:first-child{
  524. border: none;
  525. padding: 0;
  526. }
  527. &-title{
  528. img{
  529. width: 14px;height: 16px;
  530. }
  531. span{
  532. font-family: PingFangSC, PingFang SC;
  533. font-weight: 400;
  534. font-size: 14px;
  535. color: #6B7280;
  536. line-height: 14px;
  537. margin-left: 6px;
  538. }
  539. }
  540. &-sz{
  541. font-family: DINAlternate, DINAlternate;
  542. font-weight: bold;
  543. font-size: 28px;
  544. color: #252525;
  545. line-height: 28px;
  546. margin-top: 16px;
  547. }
  548. &-text{
  549. font-family: PingFangSC, PingFang SC;
  550. font-weight: 400;
  551. font-size: 12px;
  552. color: #6B7280;
  553. line-height: 12px;
  554. margin-top: 16px;
  555. i{
  556. margin: 0 3px 0 7px;
  557. font-size: 14px;
  558. font-weight: bolder;
  559. &.xj{color: #67C23A;}
  560. &.ss{color: #F4657A;}
  561. }
  562. }
  563. }
  564. }
  565. .chartbox{
  566. width: 100%;
  567. height: 300px;
  568. position: relative;
  569. &.two{
  570. height: 350px;
  571. }
  572. .th{
  573. height: 36px;
  574. background: #F7F7F7;
  575. margin-top: 20px;
  576. &-pre{
  577. font-family: PingFangSC, PingFang SC;
  578. font-weight: 400;
  579. font-size: 14px;
  580. color: #646464;
  581. line-height: 36px;
  582. text-align: center;
  583. &.tp1{
  584. width: 50px;
  585. }
  586. &.tp2,&.tp3,&.tp4{
  587. width: calc((100% - 50px) / 3);
  588. }
  589. }
  590. }
  591. .list{
  592. flex: 1;
  593. overflow-y: auto;
  594. &-item{
  595. margin-top: 15px;
  596. &-pre{
  597. font-family: PingFangSC, PingFang SC;
  598. font-weight: 400;
  599. font-size: 14px;
  600. color: #252525;
  601. line-height: 20px;
  602. text-align: center;
  603. &.lip1{
  604. width: 50px;
  605. &>div{
  606. width: 16px;
  607. height: 16px;
  608. border-radius: 50%;
  609. background: #C1C7D2;
  610. font-family: PingFangSC, PingFang SC;
  611. font-weight: 400;
  612. font-size: 12px;
  613. color: #FFFFFF;
  614. line-height: 16px;
  615. text-align: center;
  616. &.red{
  617. background: #FF4943;
  618. }
  619. &.yellow{
  620. background: #FFC00A;
  621. }
  622. &.green{
  623. background: #00AE57;
  624. }
  625. }
  626. }
  627. &.lip2,&.lip3,&.lip4{
  628. width: calc((100% - 50px) / 3);
  629. }
  630. }
  631. }
  632. }
  633. .query{
  634. position: absolute;
  635. top: 15px;
  636. right: 11px;
  637. z-index: 1000;
  638. }
  639. }
  640. ::v-deep .el-input__inner{
  641. height: 24px !important;
  642. line-height: 24px !important;
  643. }
  644. ::v-deep .el-input__icon{
  645. line-height: 24px !important;
  646. }
  647. </style>