金币系统前端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1680 lines
50 KiB

1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
  1. <script setup>
  2. import * as echarts from 'echarts'
  3. import { ref, onMounted, reactive, computed } from 'vue'
  4. import { VscInfo } from 'vue-icons-plus/vsc'
  5. import * as bs from 'vue-icons-plus/bs'
  6. import axios, { all } from 'axios'
  7. import API from '@/util/http'
  8. import moment from 'moment'
  9. import * as math from 'mathjs'
  10. import { getTime } from 'element-plus/es/components/countdown/src/utils.mjs'
  11. // 变量
  12. // 加载对象
  13. const loading = ref(true)
  14. const areaRankLoading = ref(true)
  15. // 总览对象
  16. const getSumCoin = ref({})
  17. const statistics = ref({})
  18. // const getYearConsumeCoin = ref({});
  19. // const getDayConsumeCoin = ref({});
  20. // 中间统计图搜索参数
  21. const changeTimeRatio = ref('allDays')
  22. const searchTime = ref([])
  23. // 月份柱状图
  24. const getMiddleBarObj = ref({
  25. updateType: 0
  26. })
  27. const getMiddleBarData = ref({})
  28. const middleTotalRecharge = ref(0)
  29. const middleTotalFree = ref(0)
  30. const middleTotalTask = ref(0)
  31. const middleCategory = ref([])
  32. const middleRecharge = ref([])
  33. const middleFree = ref([])
  34. const middleTask = ref([])
  35. // 地区排名
  36. const getAreaRankObj = ref({
  37. updateType: 0
  38. })
  39. const getMediumArea = ref([])
  40. const areaRank = ref([])
  41. // 金币概览
  42. const option3Data = ref([])
  43. const option4Data = ref([])
  44. const option5Data = ref([])
  45. // 四大学科类别占比
  46. const platformData = ref([])
  47. const allData = ref([])
  48. const ERPData = ref([])
  49. const HCData = ref([])
  50. const LinkData = ref([])
  51. const goldData = ref([])
  52. // 重构工作台,第一个方框类别
  53. const oneData = ref([])
  54. const twoData = ref([])
  55. const threeData = ref([])
  56. // 搜索对象
  57. const goldType = ref('全部类型')
  58. const platform = ref('全部平台')
  59. //默认高亮标签页
  60. const activeName = ref('recharge')
  61. // 金币分类选项
  62. const gold = [
  63. {
  64. value: '全部类型',
  65. label: '全部类型'
  66. },
  67. {
  68. value: '充值金币',
  69. label: '永久金币'
  70. },
  71. {
  72. value: '免费金币',
  73. label: '免费金币'
  74. },
  75. {
  76. value: '任务金币',
  77. label: '任务金币'
  78. }
  79. ]
  80. const list = ref([])
  81. const token = localStorage.getItem('token')
  82. let rechargeBar = null
  83. // 方法
  84. // 搜索方法
  85. const get = async function () {
  86. try {
  87. getAreaRank()
  88. getMiddleBar()
  89. // 发送POST请求
  90. // const result1 = await API.post(
  91. // "http://54.251.137.151:10702/statistics/getSumCoin",
  92. // {}
  93. // );
  94. const result2 = await API({ url: '/statistics/a', data: {} })
  95. // const result3 = await API.post(
  96. // "http://54.251.137.151:10702/statistics/getYearConsumeCoin",
  97. // {}
  98. // );
  99. // const result4 = await API.post(
  100. // "http://54.251.137.151:10702/statistics/getDayConsumeCoin",
  101. // {}
  102. // );
  103. // const result5 = await API.post(
  104. // "http://192.168.8.93:10010/statistics/getMediumAreaPay",
  105. // {}
  106. // );
  107. // const result6 = await API.post(
  108. // "http://192.168.8.93:10010/statistics/getMediumAreaConsume",
  109. // {}
  110. // );
  111. // const result7 = await API.post(
  112. // "http://192.168.8.93:10010/statistics/getMediuPayCoin",
  113. // {}
  114. // );
  115. // const result8 = await API.post(
  116. // "http://192.168.8.93:10010/statistics/getMediuConsumeCoin",
  117. // {}
  118. // );
  119. const result9 = await API({ url: '/statistics/b', data: {} })
  120. // 重构的工作台
  121. const result10 = await API({
  122. url: '/One/getOne',
  123. data: {
  124. token: token
  125. }
  126. })
  127. const result11 = await API({
  128. url: '/One/getTwo',
  129. data: {
  130. token: token
  131. }
  132. })
  133. const result12 = await API({
  134. url: '/One/getThree',
  135. data: { token: token }
  136. })
  137. oneData.value = result10
  138. twoData.value = result11
  139. threeData.value = result12
  140. console.log('oneData', oneData.value)
  141. // 将响应结果存储到响应式数据中
  142. // getSumCoin.value = result1.data;
  143. statistics.value = result2.data
  144. // getYearConsumeCoin.value = result3.data;
  145. // getDayConsumeCoin.value = result4.data;
  146. platformData.value = result9.data
  147. // console.log("getSumCoin", getSumCoin.value);
  148. console.log('statistics', statistics.value)
  149. // console.log("getYearConsumeCoin", getYearConsumeCoin.value);
  150. // console.log("getDayConsumeCoin", getDayConsumeCoin.value);
  151. console.log('platformData', platformData.value)
  152. option3Data.value = [
  153. {
  154. value: Math.abs(twoData.value.rechargegold),
  155. name: '永久金币' + ' | ' + formatNum(twoData.value.rechargegold / 100)
  156. },
  157. {
  158. value: Math.abs(twoData.value.freegold),
  159. name: '免费金币' + ' | ' + formatNum(twoData.value.freegold / 100)
  160. },
  161. {
  162. value: Math.abs(twoData.value.taskgold),
  163. name: '任务金币' + ' | ' + formatNum(twoData.value.taskgold / 100)
  164. }
  165. ]
  166. option4Data.value = [
  167. {
  168. value: Math.abs(threeData.value.rechargegold),
  169. name:
  170. '永久金币' +
  171. ' | ' +
  172. formatNum(Math.abs(threeData.value.rechargegold / 100))
  173. },
  174. {
  175. value: Math.abs(threeData.value.freegold),
  176. name:
  177. '免费金币' +
  178. ' | ' +
  179. formatNum(Math.abs(threeData.value.freegold / 100))
  180. },
  181. {
  182. value: Math.abs(threeData.value.taskgold),
  183. name:
  184. '任务金币' +
  185. ' | ' +
  186. formatNum(Math.abs(threeData.value.taskgold / 100))
  187. }
  188. ]
  189. console.log('option4Data', option4Data.value)
  190. option5Data.value = [
  191. {
  192. value: Math.abs(oneData.value.rechargegold),
  193. name: '永久金币' + ' | ' + formatNum(oneData.value.rechargegold / 100)
  194. },
  195. {
  196. value: Math.abs(oneData.value.freegold),
  197. name: '免费金币' + ' | ' + formatNum(oneData.value.freegold / 100)
  198. },
  199. {
  200. value: Math.abs(oneData.value.taskgold),
  201. name: '任务金币' + ' | ' + formatNum(oneData.value.taskgold / 100)
  202. }
  203. ]
  204. console.log('option5Data', option5Data.value)
  205. // 平台数据处理
  206. ERPData.value = [
  207. platformData.value.erpsum
  208. .filter((item) => item.subject == '第一学科')
  209. .map((item) => Math.abs(item.totalERPSum)),
  210. platformData.value.erpsum
  211. .filter((item) => item.subject == '第二学科')
  212. .map((item) => Math.abs(item.totalERPSum)),
  213. platformData.value.erpsum
  214. .filter((item) => item.subject == '第三学科')
  215. .map((item) => Math.abs(item.totalERPSum)),
  216. platformData.value.erpsum
  217. .filter((item) => item.subject == '第四学科')
  218. .map((item) => Math.abs(item.totalERPSum))
  219. ]
  220. ERPData.value.forEach((item, index) =>
  221. item == ''
  222. ? (ERPData.value[index] = {
  223. value: 0,
  224. name: '第' + (index + 1) + '学科' + 0
  225. })
  226. : (ERPData.value[index] = {
  227. value: item[0],
  228. name: '第' + (index + 1) + '学科' + item[0]
  229. })
  230. )
  231. console.log('ERPData', ERPData.value)
  232. HCData.value = [
  233. platformData.value.homilyChartSum
  234. .filter((item) => item.subject == '第一学科')
  235. .map((item) => Math.abs(item.totalHomilyChartSum)),
  236. platformData.value.homilyChartSum
  237. .filter((item) => item.subject == '第二学科')
  238. .map((item) => Math.abs(item.totalHomilyChartSum)),
  239. platformData.value.homilyChartSum
  240. .filter((item) => item.subject == '第三学科')
  241. .map((item) => Math.abs(item.totalHomilyChartSum)),
  242. platformData.value.homilyChartSum
  243. .filter((item) => item.subject == '第四学科')
  244. .map((item) => Math.abs(item.totalHomilyChartSum))
  245. ]
  246. HCData.value.forEach((item, index) =>
  247. item == ''
  248. ? (HCData.value[index] = {
  249. value: 0,
  250. name: '第' + (index + 1) + '学科' + 0
  251. })
  252. : (HCData.value[index] = {
  253. value: item[0],
  254. name: '第' + (index + 1) + '学科' + item[0]
  255. })
  256. )
  257. console.log('HCData', HCData.value)
  258. LinkData.value = [
  259. platformData.value.homilyLinkSum
  260. .filter((item) => item.subject == '第一学科')
  261. .map((item) => Math.abs(item.totalHomilyLinkSum)),
  262. platformData.value.homilyLinkSum
  263. .filter((item) => item.subject == '第二学科')
  264. .map((item) => Math.abs(item.totalHomilyLinkSum)),
  265. platformData.value.homilyLinkSum
  266. .filter((item) => item.subject == '第三学科')
  267. .map((item) => Math.abs(item.totalHomilyLinkSum)),
  268. platformData.value.homilyLinkSum
  269. .filter((item) => item.subject == '第四学科')
  270. .map((item) => Math.abs(item.totalHomilyLinkSum))
  271. ]
  272. LinkData.value.forEach((item, index) =>
  273. item == ''
  274. ? (LinkData.value[index] = {
  275. value: 0,
  276. name: '第' + (index + 1) + '学科' + 0
  277. })
  278. : (LinkData.value[index] = {
  279. value: item[0],
  280. name: '第' + (index + 1) + '学科' + item[0]
  281. })
  282. )
  283. console.log('LinkData', LinkData.value)
  284. goldData.value = [
  285. platformData.value.coinSystemSum
  286. .filter((item) => item.subject == '第一学科')
  287. .map((item) => Math.abs(item.totalCoinSystemSum)),
  288. platformData.value.coinSystemSum
  289. .filter((item) => item.subject == '第二学科')
  290. .map((item) => Math.abs(item.totalCoinSystemSum)),
  291. platformData.value.coinSystemSum
  292. .filter((item) => item.subject == '第三学科')
  293. .map((item) => Math.abs(item.totalCoinSystemSum)),
  294. platformData.value.coinSystemSum
  295. .filter((item) => item.subject == '第四学科')
  296. .map((item) => Math.abs(item.totalCoinSystemSum))
  297. ]
  298. goldData.value.forEach((item, index) =>
  299. item == ''
  300. ? (goldData.value[index] = {
  301. value: 0,
  302. name: '第' + (index + 1) + '学科' + 0
  303. })
  304. : (goldData.value[index] = {
  305. value: item[0],
  306. name: '第' + (index + 1) + '学科' + item[0]
  307. })
  308. )
  309. console.log('goldData', goldData.value)
  310. allData.value = [
  311. {
  312. value:
  313. Number(ERPData.value[0].value) +
  314. Number(HCData.value[0].value) +
  315. Number(LinkData.value[0].value) +
  316. Number(goldData.value[0].value),
  317. name:
  318. '第一学科' +
  319. (Number(ERPData.value[0].value) +
  320. Number(HCData.value[0].value) +
  321. Number(LinkData.value[0].value) +
  322. Number(goldData.value[0].value))
  323. },
  324. {
  325. value:
  326. Number(ERPData.value[1].value) +
  327. Number(HCData.value[1].value) +
  328. Number(LinkData.value[1].value) +
  329. Number(goldData.value[1].value),
  330. name:
  331. '第二学科' +
  332. (Number(ERPData.value[1].value) +
  333. Number(HCData.value[1].value) +
  334. Number(LinkData.value[1].value) +
  335. Number(goldData.value[1].value))
  336. },
  337. {
  338. value:
  339. Number(ERPData.value[2].value) +
  340. Number(HCData.value[2].value) +
  341. Number(LinkData.value[2].value) +
  342. Number(goldData.value[2].value),
  343. name:
  344. '第三学科' +
  345. (Number(ERPData.value[2].value) +
  346. Number(HCData.value[2].value) +
  347. Number(LinkData.value[2].value) +
  348. Number(goldData.value[2].value))
  349. },
  350. {
  351. value:
  352. Number(ERPData.value[3].value) +
  353. Number(HCData.value[3].value) +
  354. Number(LinkData.value[3].value) +
  355. Number(goldData.value[3].value),
  356. name:
  357. '第四学科' +
  358. (Number(ERPData.value[3].value) +
  359. Number(HCData.value[3].value) +
  360. Number(LinkData.value[3].value) +
  361. Number(goldData.value[3].value))
  362. }
  363. ]
  364. loading.value = false
  365. console.log('allData', allData.value)
  366. } catch (error) {
  367. console.log('请求失败', error)
  368. loading.value = false
  369. // 在这里可以处理错误逻辑,比如显示错误提示等
  370. }
  371. }
  372. // 获取中间柱状图数据
  373. const getMiddleBar = async function () {
  374. const result = await API({
  375. url: '/statistics/getCoinTime',
  376. data: getMiddleBarObj.value
  377. })
  378. getMiddleBarData.value = result.data
  379. console.log('getMiddleBarData', getMiddleBarData.value)
  380. // 柱状图数据处理
  381. middleCategory.value = getMiddleBarData.value.map((item) =>
  382. item.day == null ? item.month : item.day.substring(5, 10)
  383. )
  384. middleRecharge.value = getMiddleBarData.value.map((item) =>
  385. Math.abs(item.rechargeSumCoin)
  386. )
  387. middleFree.value = getMiddleBarData.value.map((item) =>
  388. Math.abs(item.freeSumCoin)
  389. )
  390. middleTask.value = getMiddleBarData.value.map((item) =>
  391. Math.abs(item.taskSumCoin)
  392. )
  393. middleTotalRecharge.value = 0
  394. middleTotalFree.value = 0
  395. middleTotalTask.value = 0
  396. middleRecharge.value.forEach((number) => {
  397. middleTotalRecharge.value = math.add(
  398. math.bignumber(middleTotalRecharge.value),
  399. math.bignumber(number)
  400. )
  401. })
  402. middleFree.value.forEach((number) => {
  403. middleTotalFree.value = math.add(
  404. math.bignumber(middleTotalFree.value),
  405. math.bignumber(number)
  406. )
  407. })
  408. middleTask.value.forEach((number) => {
  409. middleTotalTask.value = math.add(
  410. math.bignumber(middleTotalTask.value),
  411. math.bignumber(number)
  412. )
  413. })
  414. console.log('middleCategory', middleCategory.value)
  415. console.log('middleRecharge', middleRecharge.value)
  416. console.log('middleFree', middleFree.value)
  417. console.log('middleTask', middleTask.value)
  418. console.log('middleTotalRecharge', middleTotalRecharge.value)
  419. console.log('middleTotalFree', middleTotalFree.value)
  420. console.log('middleTotalTask', middleTotalTask.value)
  421. if (getMiddleBarObj.value.updateType == 0) {
  422. // 基于准备好的dom,初始化echarts实例
  423. updateChart()
  424. // var recharge = echarts.init(document.getElementById('recharge'))
  425. // const option = {
  426. // tooltip: {
  427. // trigger: 'axis',
  428. // axisPointer: {
  429. // type: 'shadow'
  430. // },
  431. // formatter: function (params) {
  432. // let total = 0
  433. // let content = `${params[0].name}<br/>`
  434. // params.forEach((param) => {
  435. // content += `${param.seriesName}: ${param.value}<br/>`
  436. // total += param.value
  437. // })
  438. // content += `总和: ${total}`
  439. // return content
  440. // }
  441. // },
  442. // legend: {
  443. // right: '-5%',
  444. // orient: 'vertical'
  445. // },
  446. // grid: {
  447. // left: '3%',
  448. // right: '4%',
  449. // bottom: '3%',
  450. // containLabel: true
  451. // },
  452. // xAxis: {
  453. // type: 'category',
  454. // data: middleCategory.value
  455. // },
  456. // yAxis: {
  457. // type: 'value'
  458. // },
  459. // series: [
  460. // {
  461. // name: '永久金币',
  462. // color: '#35e383',
  463. // type: 'bar',
  464. // stack: 'total',
  465. // label: {
  466. // show: false
  467. // },
  468. // emphasis: {
  469. // focus: 'series'
  470. // },
  471. // data: middleRecharge.value
  472. // },
  473. // {
  474. // name: '免费金币',
  475. // color: '#5f8ff5',
  476. // type: 'bar',
  477. // stack: 'total',
  478. // label: {
  479. // show: false
  480. // },
  481. // emphasis: {
  482. // focus: 'series'
  483. // },
  484. // data: middleFree.value
  485. // },
  486. // {
  487. // name: '任务金币',
  488. // color: '#ffe733',
  489. // type: 'bar',
  490. // stack: 'total',
  491. // label: {
  492. // show: false
  493. // },
  494. // emphasis: {
  495. // focus: 'series'
  496. // },
  497. // data: middleTask.value
  498. // }
  499. // ]
  500. // }
  501. // // 使用刚指定的配置项和数据显示图表。
  502. // recharge.setOption(option)
  503. } else {
  504. // 基于准备好的dom,初始化echarts实例
  505. var consume = echarts.init(document.getElementById('consume'))
  506. const option = {
  507. tooltip: {
  508. trigger: 'axis',
  509. axisPointer: {
  510. type: 'shadow'
  511. },
  512. formatter: function (params) {
  513. let total = 0
  514. let content = `${params[0].name}<br/>`
  515. params.forEach((param) => {
  516. content += `${param.seriesName}: ${param.value}<br/>`
  517. total += param.value
  518. })
  519. content += `总和: ${total}`
  520. return content
  521. }
  522. },
  523. legend: {
  524. right: '-5%',
  525. orient: 'vertical'
  526. },
  527. grid: {
  528. left: '3%',
  529. right: '4%',
  530. bottom: '3%',
  531. containLabel: true
  532. },
  533. xAxis: {
  534. type: 'category',
  535. data: middleCategory.value
  536. },
  537. yAxis: {
  538. type: 'value'
  539. },
  540. series: [
  541. {
  542. name: '永久金币',
  543. color: '#35e383',
  544. type: 'bar',
  545. stack: 'total',
  546. label: {
  547. show: false
  548. },
  549. emphasis: {
  550. focus: 'series'
  551. },
  552. data: middleRecharge.value
  553. },
  554. {
  555. name: '免费金币',
  556. color: '#5f8ff5',
  557. type: 'bar',
  558. stack: 'total',
  559. label: {
  560. show: false
  561. },
  562. emphasis: {
  563. focus: 'series'
  564. },
  565. data: middleFree.value
  566. },
  567. {
  568. name: '任务金币',
  569. color: '#ffe733',
  570. type: 'bar',
  571. stack: 'total',
  572. label: {
  573. show: false
  574. },
  575. emphasis: {
  576. focus: 'series'
  577. },
  578. data: middleTask.value
  579. }
  580. ]
  581. }
  582. // 使用刚指定的配置项和数据显示图表。
  583. consume.setOption(option)
  584. }
  585. }
  586. // 获取门店排名
  587. const getAreaRank = async function () {
  588. const result = await API({
  589. url: '/statistics/getMee',
  590. data: getAreaRankObj.value
  591. })
  592. getMediumArea.value = result.data
  593. console.log('getMediumArea', getMediumArea.value)
  594. if (getAreaRankObj.value.type == '充值金币') {
  595. areaRank.value = getMediumArea.value.map((item) => ({
  596. value: Math.abs(item.rechargeSumCoin).toFixed(2),
  597. name: item.area
  598. }))
  599. } else if (getAreaRankObj.value.type == '免费金币') {
  600. areaRank.value = getMediumArea.value.map((item) => ({
  601. value: Math.abs(item.freeSumCoin).toFixed(2),
  602. name: item.area
  603. }))
  604. } else if (getAreaRankObj.value.type == '任务金币') {
  605. areaRank.value = getMediumArea.value.map((item) => ({
  606. value: Math.abs(item.taskSumCoin).toFixed(2),
  607. name: item.area
  608. }))
  609. } else {
  610. areaRank.value = getMediumArea.value.map((item) => ({
  611. value: Math.abs(item.totalRechargeSum).toFixed(2),
  612. name: item.area
  613. }))
  614. }
  615. areaRank.value.sort((a, b) => b.value - a.value)
  616. areaRankLoading.value = false
  617. console.log('areaRank', areaRank.value)
  618. }
  619. // 金币类型
  620. const findBsComponent = function (index) {
  621. let iconName
  622. if (index < 3) {
  623. iconName = `bs.Bs${index + 1}CircleFill` // 根据index拼接图标名称
  624. } else {
  625. iconName = `bs.Bs${index + 1}Circle` // 根据index拼接图标名称
  626. }
  627. return eval(iconName) // 动态执行图标名称,返回图标组件
  628. }
  629. // 门店排名下拉框
  630. const changeGoldType = function () {
  631. console.log('changeGoldType', goldType.value)
  632. if (goldType.value == '全部类型') {
  633. getAreaRankObj.value.type = ''
  634. } else if (goldType.value == '充值金币') {
  635. getAreaRankObj.value.type = '充值金币'
  636. } else if (goldType.value == '免费金币') {
  637. getAreaRankObj.value.type = '免费金币'
  638. } else if (goldType.value == '任务金币') {
  639. getAreaRankObj.value.type = '任务金币'
  640. }
  641. areaRankLoading.value = true
  642. getAreaRank()
  643. }
  644. // 点击标签页初始化
  645. const handleChange = function () {
  646. if (activeName.value == 'recharge') {
  647. getMiddleBarObj.value.updateType = 0
  648. getAreaRankObj.value.updateType = 0
  649. } else {
  650. getMiddleBarObj.value.updateType = 1
  651. getAreaRankObj.value.updateType = 1
  652. }
  653. getAreaRankObj.value.type = ''
  654. goldType.value = '全部类型'
  655. getMiddleBar()
  656. areaRankLoading.value = true
  657. getAreaRank()
  658. }
  659. // 时间范围控制
  660. const disabledDate = function (date) {
  661. const currentDate = new Date()
  662. const startDate = new Date(
  663. currentDate.getFullYear(),
  664. currentDate.getMonth() - 1,
  665. 1
  666. )
  667. const endDate = new Date(
  668. currentDate.getFullYear(),
  669. currentDate.getMonth() + 1,
  670. 0
  671. )
  672. if (date >= startDate && date <= endDate) {
  673. return false
  674. }
  675. return true
  676. }
  677. // 本日
  678. const today = function () {
  679. const current = new Date()
  680. const startDate = new Date(
  681. current.getFullYear(),
  682. current.getMonth(),
  683. current.getDate()
  684. )
  685. const endDate = new Date(
  686. current.getFullYear(),
  687. current.getMonth(),
  688. current.getDate()
  689. )
  690. searchTime.value = [startDate, endDate]
  691. search()
  692. // console.log("searchTime", moment(searchTime.value[0]).format("YYYY-MM-DD") + "至" + moment(searchTime.value[1]).format("YYYY-MM-DD"))
  693. }
  694. // 本周
  695. const thisWeek = function () {
  696. const current = new Date()
  697. const dayOfWeek = current.getDay() // 获取今天是星期几(0 表示周日,1 表示周一,以此类推)
  698. const diff = current.getDate() - dayOfWeek + (dayOfWeek === 0 ? -6 : 1) // 计算本周第一天的日期差值
  699. const startDate = new Date(current.getFullYear(), current.getMonth(), diff)
  700. const endDate = new Date()
  701. searchTime.value = [startDate, endDate]
  702. search()
  703. // console.log("searchTime", moment(searchTime.value[0]).format("YYYY-MM-DD") + "至" + moment(searchTime.value[1]).format("YYYY-MM-DD"))
  704. }
  705. // 本月
  706. const thisMonth = function () {
  707. const current = new Date()
  708. const startDate = new Date(current.getFullYear(), current.getMonth(), 1)
  709. const endDate = new Date()
  710. searchTime.value = [startDate, endDate]
  711. search()
  712. // console.log("searchTime", moment(searchTime.value[0]).format("YYYY-MM-DD") + "至" + moment(searchTime.value[1]).format("YYYY-MM-DD"))
  713. }
  714. // 本年
  715. const thisYear = function () {
  716. const current = new Date()
  717. const startDate = new Date(current.getFullYear(), 0, 1)
  718. const endDate = new Date(current.getFullYear(), current.getMonth() + 1, 0)
  719. const year = 1
  720. searchTime.value = [startDate, endDate, year]
  721. search()
  722. // console.log("searchTime", moment(searchTime.value[0]).format("YYYY-MM-DD") + "至" + moment(searchTime.value[1]).format("YYYY-MM-DD"))
  723. }
  724. // 全部
  725. const allTime = function () {
  726. searchTime.value = ['', '']
  727. search()
  728. }
  729. // 时间选择器
  730. const changeTime = function () {
  731. console.log('changeTimeRatio', changeTimeRatio.value)
  732. if (changeTimeRatio.value == 'allDays') {
  733. allTime()
  734. } else if (changeTimeRatio.value == 'week') {
  735. thisWeek()
  736. } else if (changeTimeRatio.value == 'month') {
  737. thisMonth()
  738. } else if (changeTimeRatio.value == 'year') {
  739. thisYear()
  740. } else if (changeTimeRatio.value == 'day') {
  741. today()
  742. }
  743. }
  744. // 根据时间搜索
  745. const search = function () {
  746. console.log(
  747. 'searchTime',
  748. moment(searchTime.value[0]).format('YYYY-MM-DD') +
  749. '至' +
  750. moment(searchTime.value[1]).format('YYYY-MM-DD')
  751. )
  752. getMiddleBarObj.value.searchStartTime = moment(searchTime.value[0]).format(
  753. 'YYYY-MM-DD'
  754. )
  755. getMiddleBarObj.value.searchEndTime = moment(searchTime.value[1]).format(
  756. 'YYYY-MM-DD'
  757. )
  758. if (getMiddleBarObj.value.searchStartTime == 'Invalid date') {
  759. delete getMiddleBarObj.value.searchStartTime
  760. }
  761. if (getMiddleBarObj.value.searchEndTime == 'Invalid date') {
  762. delete getMiddleBarObj.value.searchEndTime
  763. }
  764. console.log('getMiddleBarObj', getMiddleBarObj.value)
  765. getAreaRankObj.value.searchStartTime = moment(searchTime.value[0]).format(
  766. 'YYYY-MM-DD'
  767. )
  768. getAreaRankObj.value.searchEndTime = moment(searchTime.value[1]).format(
  769. 'YYYY-MM-DD'
  770. )
  771. if (getAreaRankObj.value.searchStartTime == 'Invalid date') {
  772. delete getAreaRankObj.value.searchStartTime
  773. }
  774. if (getAreaRankObj.value.searchEndTime == 'Invalid date') {
  775. delete getAreaRankObj.value.searchEndTime
  776. }
  777. console.log('getAreaRankObj', getAreaRankObj.value)
  778. if (searchTime.value[2] == 1) {
  779. getMiddleBarObj.value.year = searchTime.value[2]
  780. } else {
  781. delete getMiddleBarObj.value.year
  782. }
  783. getMiddleBar()
  784. areaRankLoading.value = true
  785. getAreaRank()
  786. }
  787. // 切换平台
  788. const changePlatform = function () {
  789. console.log('changePlatform', platform.value)
  790. if (platform.value == '全部平台') {
  791. // 基于准备好的dom,初始化echarts实例
  792. var all = echarts.init(document.getElementById('all'))
  793. const option6 = {
  794. tooltip: {
  795. trigger: 'item'
  796. },
  797. series: [
  798. {
  799. name: '四大学科类别占比',
  800. type: 'pie',
  801. radius: ['40%', '60%'],
  802. avoidLabelOverlap: false,
  803. data: allData.value
  804. }
  805. ]
  806. }
  807. // 使用刚指定的配置项和数据显示图表。
  808. all.setOption(option6)
  809. } else if (platform.value == 'ERP') {
  810. // 基于准备好的dom,初始化echarts实例
  811. var ERP = echarts.init(document.getElementById('ERP'))
  812. const option7 = {
  813. tooltip: {
  814. trigger: 'item'
  815. },
  816. series: [
  817. {
  818. name: '四大学科类别占比',
  819. type: 'pie',
  820. radius: ['40%', '60%'],
  821. avoidLabelOverlap: false,
  822. data: ERPData.value
  823. }
  824. ]
  825. }
  826. // 使用刚指定的配置项和数据显示图表。
  827. ERP.setOption(option7)
  828. } else if (platform.value == 'HC') {
  829. // 第4-3个饼状图 基于准备好的dom,初始化echarts实例
  830. var HC = echarts.init(document.getElementById('HC'))
  831. const option8 = {
  832. tooltip: {
  833. trigger: 'item'
  834. },
  835. series: [
  836. {
  837. name: '四大学科类别占比',
  838. type: 'pie',
  839. radius: ['40%', '60%'],
  840. avoidLabelOverlap: false,
  841. data: HCData.value
  842. }
  843. ]
  844. }
  845. // 使用刚指定的配置项和数据显示图表。
  846. HC.setOption(option8)
  847. } else if (platform.value == 'Link') {
  848. // 第4-4个饼状图 基于准备好的dom,初始化echarts实例
  849. var Link = echarts.init(document.getElementById('Link'))
  850. const option9 = {
  851. tooltip: {
  852. trigger: 'item'
  853. },
  854. series: [
  855. {
  856. name: '四大学科类别占比',
  857. type: 'pie',
  858. radius: ['40%', '60%'],
  859. avoidLabelOverlap: false,
  860. data: LinkData.value
  861. }
  862. ]
  863. }
  864. // 使用刚指定的配置项和数据显示图表。
  865. Link.setOption(option9)
  866. } else if (platform.value == '金币系统') {
  867. // 第4-5个饼状图 基于准备好的dom,初始化echarts实例
  868. var gold = echarts.init(document.getElementById('gold'))
  869. const option10 = {
  870. tooltip: {
  871. trigger: 'item'
  872. },
  873. series: [
  874. {
  875. name: '四大学科类别占比',
  876. type: 'pie',
  877. radius: ['40%', '60%'],
  878. avoidLabelOverlap: false,
  879. data: goldData.value
  880. }
  881. ]
  882. }
  883. // 使用刚指定的配置项和数据显示图表。
  884. gold.setOption(option10)
  885. }
  886. }
  887. // 计算属性
  888. // 格式化数字 这是一个方法
  889. const formatNum = function (val) {
  890. if (val === undefined) {
  891. return ''
  892. }
  893. const num = parseFloat(val)
  894. // 判断是否为整数
  895. if (Number.isInteger(num)) {
  896. return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')
  897. } else {
  898. // 四舍五入保留两位小数
  899. const roundedVal = num.toFixed(2)
  900. return roundedVal.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')
  901. }
  902. }
  903. function updateChart() {
  904. // 第一个柱状图 基于准备好的dom,初始化echarts实例
  905. rechargeBar = echarts.init(document.getElementById('recharge'))
  906. const option1 = {
  907. tooltip: {
  908. trigger: 'axis',
  909. axisPointer: {
  910. // Use axis to trigger tooltip
  911. type: 'shadow' // 'shadow' as default; can also be 'line' or 'shadow'
  912. }
  913. },
  914. legend: {
  915. right: 0,
  916. orient: 'vertical'
  917. },
  918. grid: {
  919. left: '3%',
  920. right: '4%',
  921. bottom: '3%',
  922. containLabel: true
  923. },
  924. xAxis: {
  925. type: 'category',
  926. data: middleCategory.value
  927. },
  928. yAxis: {
  929. type: 'value'
  930. },
  931. series: [
  932. {
  933. name: '永久金币',
  934. color: '#35e383',
  935. type: 'bar',
  936. stack: 'total',
  937. label: {
  938. show: false
  939. },
  940. emphasis: {
  941. focus: 'series'
  942. },
  943. data: middleRecharge.value
  944. },
  945. {
  946. name: '免费金币',
  947. color: '#5f8ff5',
  948. type: 'bar',
  949. stack: 'total',
  950. label: {
  951. show: false
  952. },
  953. emphasis: {
  954. focus: 'series'
  955. },
  956. data: middleFree.value
  957. },
  958. {
  959. name: '任务金币',
  960. color: '#ffe733',
  961. type: 'bar',
  962. stack: 'total',
  963. label: {
  964. show: false
  965. },
  966. emphasis: {
  967. focus: 'series'
  968. },
  969. data: middleTask.value
  970. }
  971. ]
  972. }
  973. // 使用刚指定的配置项和数据显示图表。
  974. rechargeBar.setOption(option1)
  975. }
  976. onMounted(async function () {
  977. await get()
  978. updateChart()
  979. // 第一个饼状图 基于准备好的dom,初始化echarts实例
  980. var yearRechargePie = echarts.init(document.getElementById('yearRecharge'))
  981. const option3 = {
  982. tooltip: {
  983. trigger: 'item',
  984. position: ['15%', '-3%'],
  985. formatter: function (params) {
  986. return params.seriesName + '<br/>' + params.name
  987. }
  988. },
  989. legend: {
  990. bottom: '-1%',
  991. left: 'center',
  992. orient: 'vertical'
  993. },
  994. series: [
  995. {
  996. name:
  997. '全年累计金币数(个)\n' +
  998. formatNum(Math.abs(twoData.value.totalgold / 100)),
  999. type: 'pie',
  1000. radius: ['60%', '80%'],
  1001. avoidLabelOverlap: false,
  1002. label: {
  1003. show: true,
  1004. position: 'center',
  1005. formatter: '{a}',
  1006. fontSize: 15,
  1007. fontWeight: 'bold'
  1008. },
  1009. labelLine: {
  1010. show: false
  1011. },
  1012. data: option3Data.value,
  1013. color: ['#57a5ff', '#7f29ff', '#f2d113']
  1014. }
  1015. ]
  1016. }
  1017. // 使用刚指定的配置项和数据显示图表。
  1018. yearRechargePie.setOption(option3)
  1019. // 第二个饼状图 基于准备好的dom,初始化echarts实例
  1020. var yearConsumePie = echarts.init(document.getElementById('yearConsume'))
  1021. const option4 = {
  1022. tooltip: {
  1023. trigger: 'item',
  1024. position: ['15%', '-3%'],
  1025. formatter: function (params) {
  1026. return params.seriesName + '<br/>' + params.name
  1027. }
  1028. },
  1029. legend: {
  1030. bottom: '-1%',
  1031. left: 'center',
  1032. orient: 'vertical'
  1033. },
  1034. grid: {
  1035. top: '0%' // 设置图表距离容器顶部的距离为10%,使饼图上移
  1036. },
  1037. series: [
  1038. {
  1039. name:
  1040. '全年累计消耗金币数(个)\n' +
  1041. formatNum(Math.abs(threeData.value.consumeGold / 100)),
  1042. type: 'pie',
  1043. radius: ['60%', '80%'],
  1044. avoidLabelOverlap: false,
  1045. label: {
  1046. show: true,
  1047. position: 'center',
  1048. formatter: '{a}',
  1049. fontSize: 15,
  1050. fontWeight: 'bold'
  1051. },
  1052. labelLine: {
  1053. show: false
  1054. },
  1055. data: option4Data.value,
  1056. color: ['#57a5ff', '#7f29ff', '#f2d113']
  1057. }
  1058. ]
  1059. }
  1060. // 使用刚指定的配置项和数据显示图表。
  1061. yearConsumePie.setOption(option4)
  1062. // 第三个饼状图 基于准备好的dom,初始化echarts实例
  1063. var nowGoldPie = echarts.init(document.getElementById('nowGold'))
  1064. const option5 = {
  1065. tooltip: {
  1066. trigger: 'item',
  1067. position: ['15%', '-3%'],
  1068. formatter: function (params) {
  1069. return (
  1070. params.seriesName +
  1071. '<br/>' +
  1072. params.name +
  1073. (params.value == oneData.value.freegold
  1074. ? '</br>6月到期 | ' +
  1075. oneData.value.sfreegold / 100 +
  1076. ' ; 12月到期 | ' +
  1077. oneData.value.dfreegold / 100
  1078. : '')
  1079. )
  1080. }
  1081. },
  1082. legend: {
  1083. bottom: '-1%',
  1084. left: 'center',
  1085. orient: 'vertical'
  1086. },
  1087. grid: {
  1088. top: '10%' // 设置图表距离容器顶部的距离为10%,使饼图上移
  1089. },
  1090. series: [
  1091. {
  1092. name:
  1093. '当前金币余量(个)\n' +
  1094. formatNum(Math.abs(oneData.value.sumgold / 100)),
  1095. type: 'pie',
  1096. radius: ['60%', '80%'],
  1097. avoidLabelOverlap: false,
  1098. label: {
  1099. show: true,
  1100. position: 'center',
  1101. formatter: '{a}',
  1102. fontSize: 15,
  1103. fontWeight: 'bold'
  1104. },
  1105. labelLine: {
  1106. show: false
  1107. },
  1108. data: option5Data.value,
  1109. color: ['#57a5ff', '#7f29ff', '#f2d113']
  1110. }
  1111. ]
  1112. }
  1113. // 使用刚指定的配置项和数据显示图表。
  1114. nowGoldPie.setOption(option5)
  1115. // 第4-1个饼状图 基于准备好的dom,初始化echarts实例
  1116. var all = echarts.init(document.getElementById('all'))
  1117. const option6 = {
  1118. tooltip: {
  1119. trigger: 'item'
  1120. },
  1121. series: [
  1122. {
  1123. name: '四大学科类别占比',
  1124. type: 'pie',
  1125. radius: ['40%', '60%'],
  1126. avoidLabelOverlap: false,
  1127. data: allData.value
  1128. }
  1129. ]
  1130. }
  1131. // 使用刚指定的配置项和数据显示图表。
  1132. all.setOption(option6)
  1133. })
  1134. </script>
  1135. <template>
  1136. <div v-loading="loading">
  1137. <el-row :gutter="20">
  1138. <el-col :span="6">
  1139. <el-card style="height: 260px">
  1140. <p>当前金币余量</p>
  1141. <p class="head-mid-font">
  1142. {{ formatNum(oneData.sumgold / 100) }}
  1143. </p>
  1144. <p>
  1145. <span v-if="oneData.differr > 0">
  1146. <div class="comparedWithYesterday">
  1147. <span>较前一天 {{ formatNum(oneData.differr / 100) }}</span>
  1148. <span
  1149. class="red-triangle"
  1150. style="margin: 6px 0px 0px 7px"
  1151. ></span>
  1152. </div>
  1153. </span>
  1154. <span v-if="oneData.differr < 0">
  1155. <div class="comparedWithYesterday">
  1156. <span>较前一天 {{ formatNum(oneData.differr / 100) }}</span>
  1157. <span
  1158. class="green-triangle"
  1159. style="margin: 6px 0px 0px 7px"
  1160. ></span>
  1161. </div>
  1162. </span>
  1163. <span v-if="oneData.differr == 0">
  1164. <div class="comparedWithYesterday">
  1165. <span>较前一天 {{ formatNum(oneData.differr / 100) }}</span>
  1166. <span
  1167. class="grey-triangle"
  1168. style="margin: 6px 0px 0px 7px"
  1169. ></span>
  1170. </div>
  1171. </span>
  1172. </p>
  1173. <template #footer>
  1174. <span style="font-size: 15px"
  1175. >永久{{ formatNum(oneData.rechargegold / 100) }} 免费{{
  1176. formatNum(oneData.freegold / 100)
  1177. }}
  1178. 任务{{ formatNum(oneData.taskgold / 100) }}
  1179. </span>
  1180. <p style="font-size: 12px">
  1181. 免费金币6月到期 |
  1182. {{ formatNum(oneData.sfreegold / 100) }} ; 12月到期 |
  1183. {{ formatNum(oneData.dfreegold / 100) }}
  1184. </p>
  1185. </template>
  1186. </el-card>
  1187. </el-col>
  1188. <el-col :span="6">
  1189. <el-card style="height: 260px">
  1190. <p>全年累计金币数</p>
  1191. <p class="head-mid-font">
  1192. {{ formatNum(Math.abs(twoData.totalgold / 100)) }}
  1193. </p>
  1194. <p>
  1195. 折合新币累计金额
  1196. {{ formatNum(Math.abs(twoData.totalcoin / 100)) }}
  1197. </p>
  1198. <template #footer
  1199. >昨日新增
  1200. {{ formatNum(Math.abs(twoData.yesterdaytotal / 100)) }}
  1201. 其中充值{{
  1202. formatNum(Math.abs(twoData.yesterdayrecharge / 100))
  1203. }}</template
  1204. >
  1205. </el-card>
  1206. </el-col>
  1207. <el-col :span="6">
  1208. <el-card style="height: 260px">
  1209. <p>全年累计消耗金币数</p>
  1210. <p class="head-mid-font">
  1211. {{
  1212. formatNum(
  1213. Math.abs((threeData.consumeGold + threeData.refundCoin) / 100)
  1214. )
  1215. }}
  1216. </p>
  1217. <p>
  1218. 消费
  1219. {{ formatNum(Math.abs(threeData.consumeGold / 100)) }}; 退款
  1220. {{ formatNum(Math.abs(threeData.refundCoin / 100)) }}
  1221. </p>
  1222. <template #footer
  1223. >昨日新增消耗{{
  1224. formatNum(
  1225. Math.abs(
  1226. threeData.yesterdayGold + threeData.yesterdayrefund !==
  1227. undefined &&
  1228. threeData.yesterdayGold + threeData.yesterdayrefund !== null
  1229. ? (threeData.yesterdayGold + threeData.yesterdayrefund) /
  1230. 100
  1231. : 0
  1232. )
  1233. )
  1234. }}
  1235. ; 消费{{
  1236. formatNum(
  1237. Math.abs(
  1238. threeData.yesterdayGold !== undefined &&
  1239. threeData.yesterdayGold !== null
  1240. ? threeData.yesterdayGold / 100
  1241. : 0
  1242. )
  1243. )
  1244. }}
  1245. ; 退款{{
  1246. formatNum(
  1247. Math.abs(
  1248. threeData.yesterdayrefund !== undefined &&
  1249. threeData.yesterdayrefund !== null
  1250. ? threeData.yesterdayrefund / 100
  1251. : 0
  1252. )
  1253. )
  1254. }}</template
  1255. >
  1256. </el-card>
  1257. </el-col>
  1258. <el-col :span="6">
  1259. <el-card style="height: 260px">
  1260. <p>全年累计充值人数</p>
  1261. <p class="head-mid-font">
  1262. {{ formatNum(Math.abs(statistics.rechargeCount)) }}
  1263. </p>
  1264. <p style="display: flex">
  1265. <span v-if="statistics.weekOverWeekRate > 0">
  1266. <div class="comparedWithYesterday">
  1267. <span>周同比 {{ statistics.weekOverWeekRate }}%</span>
  1268. <span
  1269. class="red-triangle"
  1270. style="margin: 6px 0px 0px 7px"
  1271. ></span>
  1272. </div>
  1273. </span>
  1274. <span v-if="statistics.weekOverWeekRate < 0">
  1275. <div class="comparedWithYesterday">
  1276. <span>周同比 {{ statistics.weekOverWeekRate }}%</span>
  1277. <span
  1278. class="green-triangle"
  1279. style="margin: 6px 0px 0px 7px"
  1280. ></span>
  1281. </div>
  1282. </span>
  1283. <span v-if="statistics.weekOverWeekRate == 0">
  1284. <div class="comparedWithYesterday">
  1285. <span>周同比 {{ statistics.weekOverWeekRate }}%</span>
  1286. <span
  1287. class="grey-triangle"
  1288. style="margin: 6px 0px 0px 7px"
  1289. ></span>
  1290. </div>
  1291. </span>
  1292. <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
  1293. <span v-if="statistics.dayOverDayRate > 0">
  1294. <div class="comparedWithYesterday">
  1295. <span> 日环比{{ statistics.dayOverDayRate }}%</span>
  1296. <span
  1297. class="red-triangle"
  1298. style="margin: 6px 0px 0px 7px"
  1299. ></span>
  1300. </div>
  1301. </span>
  1302. <span v-if="statistics.dayOverDayRate < 0">
  1303. <div class="comparedWithYesterday">
  1304. <span> 日环比{{ statistics.dayOverDayRate }}%</span>
  1305. <span
  1306. class="green-triangle"
  1307. style="margin: 6px 0px 0px 7px"
  1308. ></span>
  1309. </div>
  1310. </span>
  1311. <span v-if="statistics.dayOverDayRate == 0">
  1312. <div class="comparedWithYesterday">
  1313. <span> 日环比{{ statistics.dayOverDayRate }}%</span>
  1314. <span
  1315. class="grey-triangle"
  1316. style="margin: 6px 0px 0px 7px"
  1317. ></span>
  1318. </div>
  1319. </span>
  1320. </p>
  1321. <template #footer
  1322. >昨日充值人数{{
  1323. formatNum(Math.abs(statistics.rechargeCountYesterday))
  1324. }}
  1325. 其中首充{{
  1326. formatNum(Math.abs(statistics.firstRechargeCountYesterday))
  1327. }}</template
  1328. >
  1329. </el-card>
  1330. </el-col>
  1331. </el-row>
  1332. <el-row :gutter="20">
  1333. <el-col>
  1334. <el-card>
  1335. <div style="margin-right: auto; text-align: right">
  1336. <el-radio-group
  1337. v-model="changeTimeRatio"
  1338. style="margin-right: 10px"
  1339. @change="changeTime()"
  1340. >
  1341. <el-radio-button
  1342. label="全部"
  1343. value="allDays"
  1344. style="border-color: white"
  1345. />
  1346. <el-radio-button
  1347. label="本日"
  1348. value="day"
  1349. style="border-color: white"
  1350. />
  1351. <el-radio-button
  1352. label="本周"
  1353. value="week"
  1354. style="border-color: white"
  1355. />
  1356. <el-radio-button
  1357. label="本月"
  1358. value="month"
  1359. style="border-color: white"
  1360. />
  1361. <el-radio-button
  1362. label="本年"
  1363. value="year"
  1364. style="border-color: white"
  1365. />
  1366. </el-radio-group>
  1367. <!-- <el-button text @click="allTime()" dark=true>全部</el-button>
  1368. <el-button text @click="today()">今日</el-button>
  1369. <el-button text @click="thisWeek()">本周</el-button>
  1370. <el-button text @click="thisMonth()">本月</el-button>
  1371. <el-button text @click="thisYear()">本年</el-button> -->
  1372. <el-date-picker
  1373. v-model="searchTime"
  1374. type="daterange"
  1375. range-separator="→"
  1376. start-placeholder="开始时间"
  1377. end-placeholder="结束时间"
  1378. style="width: 200px"
  1379. :disabled-date="disabledDate"
  1380. @change="search"
  1381. />
  1382. </div>
  1383. <el-tabs
  1384. v-model="activeName"
  1385. class="demo-tabs"
  1386. @tab-change="handleChange"
  1387. >
  1388. <el-tab-pane label="金币充值" name="recharge">
  1389. <div>
  1390. 合计永久金币
  1391. <span class="mid-head-font">{{
  1392. formatNum(middleTotalRecharge)
  1393. }}</span>
  1394. 免费金币
  1395. <span class="mid-head-font">{{
  1396. formatNum(middleTotalFree)
  1397. }}</span>
  1398. 任务金币
  1399. <span class="mid-head-font">{{
  1400. formatNum(middleTotalTask)
  1401. }}</span>
  1402. </div>
  1403. <div class="bar">
  1404. <div id="recharge" style="width: 100%; height: 400px"></div>
  1405. <div style="width: 140px">
  1406. <div class="goldCategory">
  1407. <span>永久金币</span>
  1408. </div>
  1409. <div class="goldCategory">
  1410. <span>免费金币</span>
  1411. </div>
  1412. <div class="goldCategory">
  1413. <span>任务金币</span>
  1414. </div>
  1415. </div>
  1416. <div style="width: 30%">
  1417. <div class="ranking-header">
  1418. <span style="width: 150px">地区金币充值排名</span>
  1419. <el-select
  1420. v-model="goldType"
  1421. placeholder="请选择金币类型"
  1422. size="small"
  1423. style="margin-left: auto; width: 25%"
  1424. @change="changeGoldType"
  1425. >
  1426. <el-option
  1427. v-for="item in gold"
  1428. :key="item.value"
  1429. :label="item.label"
  1430. :value="item.value"
  1431. />
  1432. </el-select>
  1433. </div>
  1434. <div v-loading="areaRankLoading">
  1435. <el-scrollbar height="360px">
  1436. <div
  1437. v-for="(item, index) in areaRank"
  1438. :key="item"
  1439. class="ranking-item"
  1440. >
  1441. <!-- <component :is="findBsComponent(index)" /> -->
  1442. <span style="width: 15px; text-align: center">{{
  1443. index + 1
  1444. }}</span>
  1445. <span style="margin-left: 10px">{{ item.name }}</span>
  1446. <span style="margin-left: auto; margin-right: 10px">{{
  1447. formatNum(item.value)
  1448. }}</span>
  1449. </div>
  1450. </el-scrollbar>
  1451. </div>
  1452. </div>
  1453. </div>
  1454. </el-tab-pane>
  1455. <el-tab-pane label="金币消费" name="consume">
  1456. <div>
  1457. 合计永久金币
  1458. <span class="mid-head-font">{{
  1459. formatNum(middleTotalRecharge)
  1460. }}</span>
  1461. 免费金币
  1462. <span class="mid-head-font">{{
  1463. formatNum(middleTotalFree)
  1464. }}</span>
  1465. 任务金币
  1466. <span class="mid-head-font">{{
  1467. formatNum(middleTotalTask)
  1468. }}</span>
  1469. </div>
  1470. <div class="bar">
  1471. <div id="consume" style="width: 100%; height: 400px"></div>
  1472. <div style="width: 140px">
  1473. <div class="goldCategory">
  1474. <span>永久金币</span>
  1475. </div>
  1476. <div class="goldCategory">
  1477. <span>免费金币</span>
  1478. </div>
  1479. <div class="goldCategory">
  1480. <span>任务金币</span>
  1481. </div>
  1482. </div>
  1483. <div style="width: 310px">
  1484. <div class="ranking-header">
  1485. <span style="margin-right: 90px; width: 150px"
  1486. >地区金币消费排名</span
  1487. >
  1488. <el-select
  1489. v-model="goldType"
  1490. placeholder="请选择金币类型"
  1491. size="small"
  1492. style="width: 90px"
  1493. @change="changeGoldType"
  1494. >
  1495. <el-option
  1496. v-for="item in gold"
  1497. :key="item.value"
  1498. :label="item.label"
  1499. :value="item.value"
  1500. />
  1501. </el-select>
  1502. </div>
  1503. <div v-loading="areaRankLoading">
  1504. <el-scrollbar height="360px">
  1505. <div
  1506. v-for="(item, index) in areaRank"
  1507. :key="item"
  1508. class="ranking-item"
  1509. >
  1510. <!-- <component :is="findBsComponent(index)" /> -->
  1511. <span style="width: 15px; text-align: center">{{
  1512. index + 1
  1513. }}</span>
  1514. <span style="margin-left: 10px">{{ item.name }}</span>
  1515. <span style="margin-left: auto; margin-right: 10px">{{
  1516. formatNum(item.value)
  1517. }}</span>
  1518. </div>
  1519. </el-scrollbar>
  1520. </div>
  1521. </div>
  1522. </div>
  1523. </el-tab-pane>
  1524. </el-tabs>
  1525. </el-card>
  1526. </el-col>
  1527. </el-row>
  1528. <el-row :gutter="20">
  1529. <el-col :span="16">
  1530. <el-card>
  1531. <template #header>
  1532. <div class="card-header">
  1533. <span class="tail-head">金币概览</span>
  1534. </div>
  1535. </template>
  1536. <div class="pie">
  1537. <div id="yearRecharge" style="width: 400px; height: 450px"></div>
  1538. <div id="yearConsume" style="width: 400px; height: 450px"></div>
  1539. <div id="nowGold" style="width: 400px; height: 450px"></div>
  1540. </div>
  1541. </el-card>
  1542. </el-col>
  1543. <!-- <el-col :span="8">
  1544. <el-card>
  1545. <template #header>
  1546. <div class="card-header" style="display: flex">
  1547. <span class="tail-head">四大学科类别占比</span>
  1548. <el-radio-group
  1549. v-model="platform"
  1550. fill="#ffffff"
  1551. text-color="#409eff"
  1552. size="small"
  1553. @change="changePlatform"
  1554. style="margin-left: auto"
  1555. >
  1556. <el-radio-button label="全部平台" value="全部平台" />
  1557. <el-radio-button label="ERP" value="ERP" />
  1558. <el-radio-button label="HC" value="HC" />
  1559. <el-radio-button label="Link" value="Link" />
  1560. <el-radio-button label="金币系统" value="金币系统" />
  1561. </el-radio-group>
  1562. </div>
  1563. </template>
  1564. <span v-if="platform == '全部平台'">
  1565. <div id="all" style="width: 500px; height: 450px"></div>
  1566. </span>
  1567. <span v-if="platform == 'ERP'">
  1568. <div id="ERP" style="width: 500px; height: 450px"></div>
  1569. </span>
  1570. <span v-if="platform == 'HC'">
  1571. <div id="HC" style="width: 500px; height: 450px"></div>
  1572. </span>
  1573. <span v-if="platform == 'Link'">
  1574. <div id="Link" style="width: 500px; height: 450px"></div>
  1575. </span>
  1576. <span v-if="platform == '金币系统'">
  1577. <div id="gold" style="width: 500px; height: 400px"></div>
  1578. </span>
  1579. </el-card>
  1580. </el-col> -->
  1581. </el-row>
  1582. </div>
  1583. </template>
  1584. <style scoped>
  1585. .medium-button {
  1586. display: flex;
  1587. }
  1588. .head-mid-font {
  1589. font-size: 20px;
  1590. font-weight: bold;
  1591. }
  1592. .mid-head-font {
  1593. font-weight: bold;
  1594. color: #5eb7ff;
  1595. }
  1596. .tail-head {
  1597. font-weight: bold;
  1598. }
  1599. .comparedWithYesterday {
  1600. display: flex;
  1601. }
  1602. .ranking-item {
  1603. margin-bottom: 10px;
  1604. display: flex;
  1605. }
  1606. .ranking-header {
  1607. margin-bottom: 10px;
  1608. display: flex;
  1609. }
  1610. .goldCategory {
  1611. margin-bottom: 4px;
  1612. margin-right: 20px;
  1613. display: flex;
  1614. }
  1615. .bar {
  1616. display: flex;
  1617. }
  1618. .pie {
  1619. display: flex;
  1620. }
  1621. .el-row {
  1622. margin-bottom: 20px;
  1623. }
  1624. .el-radio-button {
  1625. border: 1px solid grey;
  1626. }
  1627. </style>