index.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863
  1. <template>
  2. <div class="asj-container">
  3. <div class="container-main">
  4. <!-- 卡片内容 不要删除这个类 -->
  5. <div class="home-container" style="margin-top: 8px" v-loading="cardLoading">
  6. <el-row :gutter="15" class="home-card-one mb15">
  7. <el-col
  8. :xs="24"
  9. :sm="12"
  10. :md="12"
  11. :lg="6"
  12. :xl="6"
  13. v-for="(v, k) in state.homeOne"
  14. :key="k"
  15. :class="{ 'home-media home-media-lg': k > 1, 'home-media-sm': k === 1 }"
  16. >
  17. <div class="home-card-item flex">
  18. <div class="flex-margin flex w100" :class="` home-one-animation${k}`">
  19. <div class="flex-auto" style="margin-top: -10px">
  20. <div class="mt10">{{ v.cardTitle }}</div>
  21. <div class="font30">{{ v.num1 }}</div>
  22. <div style="display: inline-block; margin-right: 10px; margin-left: 3px;">
  23. {{ v.compareNum }}
  24. </div>
  25. <el-icon :style="{ color: String(v.num2).includes('-') ? '#59b939' : '#e36f53' }" style="display: inline-block; padding-top: 2px">
  26. <template v-if="String(v.num2).includes('-')">
  27. <Bottom/> <!-- num2 是负数时显示向下箭头 -->
  28. </template>
  29. <template v-else>
  30. <Top/> <!-- num2 不是负数时显示向上箭头 -->
  31. </template>
  32. </el-icon>
  33. <span class="ml5 font16" :style="{ color: String(v.num2).includes('-') ? '#59b939' : '#e36f53' }">{{ v.num2 }}%</span>
  34. </div>
  35. <div class="home-card-item-icon flex" :style="{ background: `var(${v.color2})` }">
  36. <i class="flex-margin font32" :class="v.num4" :style="{ color: `var(${v.color3})` }"></i>
  37. </div>
  38. </div>
  39. </div>
  40. </el-col>
  41. </el-row>
  42. </div>
  43. <!-- 折线图 -->
  44. <el-card v-loading="loading" style="margin-top: -5px;">
  45. <div style="height: 350px;" ref="chartRefOne"></div>
  46. </el-card>
  47. <el-row :gutter="5" style="margin-top: 10px">
  48. <el-col :span="12">
  49. <el-card v-loading="loading">
  50. <div style="height: 350px;" ref="chartRefAcos"></div>
  51. </el-card>
  52. </el-col>
  53. <el-col :span="12">
  54. <el-card v-loading="loading">
  55. <div style="height: 350px;" ref="chartRefCPCandCTR"></div>
  56. </el-card>
  57. </el-col>
  58. </el-row>
  59. <el-row :gutter="5" style="margin-top: 10px">
  60. <el-col :span="12">
  61. <el-card v-loading="loading">
  62. <div style="height: 350px;" ref="chartRefTotalPurchases"></div>
  63. </el-card>
  64. </el-col>
  65. <el-col :span="12">
  66. <el-card v-loading="loading">
  67. <div style="height: 350px;" ref="chartRefImpandCli"></div>
  68. </el-card>
  69. </el-col>
  70. </el-row>
  71. </div>
  72. <!--<el-button @click="changeCardData">按钮</el-button>-->
  73. </div>
  74. </template>
  75. <script lang="ts" setup>
  76. import {onMounted, reactive, ref, watch} from 'vue'
  77. import * as echarts from 'echarts'
  78. import {useShopInfo} from '/@/stores/shopInfo'
  79. import {usePublicData} from '/@/stores/publicData'
  80. import {storeToRefs} from 'pinia'
  81. import {createCrudOptions} from '/@/views/adManage/sp/targets/crud'
  82. import {useFs} from '@fast-crud/fast-crud'
  83. import {getCardTotalData, getChartTotalData} from '/src/views/adManage/ad-overview/total/api'
  84. const loading = ref(true)
  85. const cardLoading = ref(true)
  86. const publicData = usePublicData()
  87. const {dateRange} = storeToRefs(publicData)
  88. const shopInfo = useShopInfo()
  89. const { profile } = storeToRefs(shopInfo)
  90. const tabActiveName = ref('Campaigns')
  91. const queryParams = ref({
  92. profileId: profile.value.profile_id,
  93. dateRange
  94. })
  95. const {crudBinding, crudRef, crudExpose} = useFs({createCrudOptions, context: queryParams})
  96. // 发送请求获取数据
  97. async function setTotalData() {
  98. try {
  99. cardLoading.value = true
  100. const resp = await getCardTotalData({ startDate: dateRange.value[0], endDate: dateRange.value[1], profileId: queryParams.value.profileId })
  101. console.log('resp.data', resp.data)
  102. state.homeOne[0].num1 = resp.data.Spend
  103. state.homeOne[0].compareNum = resp.data.prevSpend
  104. state.homeOne[0].num2 = resp.data.gapSpend
  105. state.homeOne[1].num1 = resp.data.TotalSales
  106. state.homeOne[1].compareNum = resp.data.prevTotalSales
  107. state.homeOne[1].num2 = resp.data.gapTotalSales
  108. state.homeOne[2].num1 = resp.data.TotalPurchases
  109. state.homeOne[2].compareNum = resp.data.prevTotalPurchases
  110. state.homeOne[2].num2 = resp.data.gapTotalPurchases
  111. state.homeOne[3].num1 = resp.data.ACOS
  112. state.homeOne[3].compareNum = resp.data.prevACOS
  113. state.homeOne[3].num2 = resp.data.gapACOS
  114. } catch (error) {
  115. console.log('获取数据失败:', error)
  116. } finally {
  117. cardLoading.value = false
  118. }
  119. }
  120. let optionSource
  121. async function setChartTotalData() {
  122. try {
  123. loading.value = true
  124. const resp = await getChartTotalData({ startDate: dateRange.value[0], endDate: dateRange.value[1], profileId: queryParams.value.profileId })
  125. optionSource = resp.data
  126. await setChartOptions()
  127. return resp.data
  128. } catch (error) {
  129. console.log('获取数据失败:', error)
  130. } finally {
  131. loading.value = false
  132. }
  133. }
  134. onMounted(async () => {
  135. // crudExpose.doRefresh()
  136. await setTotalData()
  137. await setChartTotalData()
  138. })
  139. watch(queryParams, async() => {
  140. try {
  141. loading.value = true
  142. console.log('queryParams.value', queryParams.value)
  143. await setTotalData()
  144. await setChartTotalData()
  145. loading.value = false
  146. } catch (error) {
  147. console.log(error)
  148. }
  149. }, {deep: true})
  150. // 卡片相关功能
  151. const state = reactive({
  152. homeOne: [
  153. {
  154. num1: '',
  155. compareNum: '',
  156. num2: '',
  157. cardTitle: '花费',
  158. num4: 'fa fa-meetup',
  159. // color1: '#FF6462',
  160. color2: '--next-color-primary-lighter',
  161. color3: '--el-color-primary',
  162. },
  163. {
  164. num1: '',
  165. compareNum: '',
  166. num2: '',
  167. cardTitle: '销售额',
  168. num4: 'iconfont icon-ditu',
  169. color2: '--next-color-success-lighter',
  170. color3: '--el-color-success',
  171. },
  172. {
  173. num1: '',
  174. compareNum: '',
  175. num2: '',
  176. cardTitle: '订单数',
  177. num4: 'iconfont icon-zaosheng',
  178. color2: '--next-color-warning-lighter',
  179. color3: '--el-color-warning',
  180. },
  181. {
  182. num1: '',
  183. compareNum: '',
  184. num2: '',
  185. cardTitle: 'ACOS',
  186. num4: 'fa fa-github-alt',
  187. color2: '--next-color-danger-lighter',
  188. color3: '--el-color-danger',
  189. },
  190. ],
  191. myCharts: [],
  192. charts: {
  193. theme: '',
  194. bgColor: '',
  195. color: '#303133',
  196. },
  197. })
  198. // 折线图相关功能
  199. const chartRefOne = ref()
  200. let chartObjOne
  201. const option = {
  202. title: {text: '花费 & 销售额'},
  203. dataset: {
  204. source: []
  205. },
  206. tooltip: {
  207. trigger: 'axis',
  208. axisPointer: {
  209. label: {
  210. backgroundColor: '#6a7985'
  211. }
  212. }
  213. },
  214. legend: {
  215. selected: {}, // 控制显隐
  216. data: ['花费', '销售额'],
  217. show: true
  218. },
  219. grid: {
  220. top: 50, right: 65, bottom: 30, left: 65,
  221. },
  222. xAxis: {
  223. type: 'category',
  224. // boundaryGap: false,
  225. },
  226. yAxis: [
  227. {
  228. type: 'value',
  229. axisLine: {
  230. show: true,
  231. lineStyle: {
  232. color: '#3a83f7' // 第一个 Y 轴的颜色
  233. }
  234. }
  235. },
  236. {
  237. type: 'value',
  238. splitLine: {
  239. show: false
  240. },
  241. axisLine: {
  242. show: true,
  243. lineStyle: {
  244. color: '#f19a37' // 第二个 Y 轴的颜色
  245. }
  246. }
  247. }
  248. ],
  249. series: [
  250. {
  251. name: '花费',
  252. yAxisIndex: 0,
  253. encode: {
  254. x: 'Name',
  255. y: 'Spend',
  256. },
  257. type: 'line',
  258. smooth: true,
  259. itemStyle: {
  260. color: '#3a83f7',
  261. },
  262. areaStyle: {
  263. color: {
  264. type: 'linear',
  265. x: 0,
  266. y: 0,
  267. x2: 0,
  268. y2: 1,
  269. colorStops: [{
  270. offset: 0, color: 'rgba(58, 131, 247, 0.5)' // 顶部不透明
  271. }, {
  272. offset: 0.2, color: 'rgba(58, 131, 247, 0.2)' // 中间更透明
  273. }, {
  274. offset: 1, color: 'rgba(58, 131, 247, 0)' // 底部完全透明
  275. }],
  276. global: false // 缺省为 false
  277. }
  278. }
  279. },
  280. {
  281. name: '销售额',
  282. yAxisIndex: 1,
  283. encode: {
  284. x: 'Name',
  285. y: 'TotalSales',
  286. },
  287. type: 'line',
  288. smooth: true,
  289. lineStyle: {
  290. type: 'dashed'
  291. },
  292. itemStyle: {
  293. color: '#f19a37',
  294. },
  295. areaStyle: {
  296. color: {
  297. type: 'linear',
  298. x: 0,
  299. y: 0,
  300. x2: 0,
  301. y2: 1,
  302. colorStops: [{
  303. offset: 0, color: 'rgba(241, 154, 55, 0.5)' // 顶部半透明
  304. }, {
  305. offset: 0.2, color: 'rgba(241, 154, 55, 0.2)' // 中间更透明
  306. }, {
  307. offset: 1, color: 'rgba(241, 154, 55, 0)' // 底部完全透明
  308. }],
  309. global: false // 缺省为 false
  310. }
  311. }
  312. },
  313. ]
  314. }
  315. const chartRefAcos = ref()
  316. let chartObjAcos
  317. const option2 = {
  318. title: {text: 'Acos'},
  319. dataset: {
  320. source: []
  321. },
  322. tooltip: {
  323. trigger: 'axis',
  324. axisPointer: {
  325. label: {
  326. backgroundColor: '#6a7985'
  327. }
  328. }
  329. },
  330. legend: {
  331. selected: {}, // 控制显隐
  332. data: ['Acos'],
  333. show: true
  334. },
  335. grid: {
  336. top: 50, right: 65, bottom: 30, left: 65,
  337. },
  338. xAxis: {
  339. type: 'category',
  340. // boundaryGap: false,
  341. },
  342. yAxis: [
  343. {
  344. type: 'value',
  345. axisLine: {
  346. show: true,
  347. lineStyle: {
  348. color: '#3a83f7'
  349. }
  350. }
  351. }
  352. ],
  353. series: [
  354. {
  355. name: 'Acos',
  356. yAxisIndex: 0,
  357. encode: {
  358. x: 'Name',
  359. y: 'Acos',
  360. },
  361. type: 'line',
  362. smooth: true,
  363. lineStyle: {
  364. type: 'dashed'
  365. },
  366. legendHoverLink: false,
  367. itemStyle: {
  368. color: '#3a83f7',
  369. },
  370. areaStyle: {
  371. color: {
  372. type: 'linear',
  373. x: 0,
  374. y: 0,
  375. x2: 0,
  376. y2: 1,
  377. colorStops: [{
  378. offset: 0, color: 'rgba(58, 131, 247, 0.5)' // 顶部不透明
  379. }, {
  380. offset: 0.2, color: 'rgba(58, 131, 247, 0.2)' // 中间更透明
  381. }, {
  382. offset: 1, color: 'rgba(58, 131, 247, 0)' // 底部完全透明
  383. }],
  384. global: false // 缺省为 false
  385. }
  386. }
  387. },
  388. ]
  389. }
  390. const chartRefCPCandCTR = ref()
  391. let chartObjCPCandCTR
  392. const option3 = {
  393. title: {text: '点击成本 & 点击率'},
  394. dataset: {
  395. source: []
  396. },
  397. tooltip: {
  398. trigger: 'axis',
  399. axisPointer: {
  400. label: {
  401. backgroundColor: '#6a7985'
  402. }
  403. }
  404. },
  405. legend: {
  406. selected: {}, // 控制显隐
  407. data: ['点击成本', '点击率'],
  408. show: true
  409. },
  410. grid: {
  411. top: 50, right: 65, bottom: 30, left: 65,
  412. },
  413. xAxis: {
  414. type: 'category',
  415. // boundaryGap: false,
  416. },
  417. yAxis: [
  418. {
  419. type: 'value',
  420. axisLine: {
  421. show: true,
  422. lineStyle: {
  423. color: '#3a83f7' // 第一个 Y 轴的颜色
  424. }
  425. }
  426. },
  427. {
  428. type: 'value',
  429. splitLine: {
  430. show: false
  431. },
  432. axisLine: {
  433. show: true,
  434. lineStyle: {
  435. color: '#f19a37' // 第二个 Y 轴的颜色
  436. }
  437. }
  438. }
  439. ],
  440. series: [
  441. {
  442. name: '点击成本',
  443. yAxisIndex: 0,
  444. encode: {
  445. x: 'Name',
  446. y: 'CPC',
  447. },
  448. type: 'line',
  449. smooth: true,
  450. itemStyle: {
  451. color: '#3a83f7',
  452. },
  453. areaStyle: {
  454. color: {
  455. type: 'linear',
  456. x: 0,
  457. y: 0,
  458. x2: 0,
  459. y2: 1,
  460. colorStops: [{
  461. offset: 0, color: 'rgba(58, 131, 247, 0.5)' // 顶部不透明
  462. }, {
  463. offset: 0.2, color: 'rgba(58, 131, 247, 0.2)' // 中间更透明
  464. }, {
  465. offset: 1, color: 'rgba(58, 131, 247, 0)' // 底部完全透明
  466. }],
  467. global: false // 缺省为 false
  468. }
  469. }
  470. },
  471. {
  472. name: '点击率',
  473. yAxisIndex: 1,
  474. encode: {
  475. x: 'Name',
  476. y: 'CTR',
  477. },
  478. type: 'line',
  479. smooth: true,
  480. itemStyle: {
  481. color: '#f19a37',
  482. },
  483. areaStyle: {
  484. color: {
  485. type: 'linear',
  486. x: 0,
  487. y: 0,
  488. x2: 0,
  489. y2: 1,
  490. colorStops: [{
  491. offset: 0, color: 'rgba(241, 154, 55, 0.5)' // 顶部半透明
  492. }, {
  493. offset: 0.2, color: 'rgba(241, 154, 55, 0.2)' // 中间更透明
  494. }, {
  495. offset: 1, color: 'rgba(241, 154, 55, 0)' // 底部完全透明
  496. }],
  497. global: false // 缺省为 false
  498. }
  499. }
  500. },
  501. ]
  502. }
  503. const chartRefTotalPurchases = ref()
  504. let chartObjTotalPurchases
  505. const option4 = {
  506. title: {text: '订单数'},
  507. dataset: {
  508. source: []
  509. },
  510. tooltip: {
  511. trigger: 'axis',
  512. axisPointer: {
  513. label: {
  514. backgroundColor: '#6a7985'
  515. }
  516. }
  517. },
  518. legend: {
  519. selected: {}, // 控制显隐
  520. data: ['订单数'],
  521. show: true
  522. },
  523. grid: {
  524. top: 50, right: 65, bottom: 30, left: 65,
  525. },
  526. xAxis: {
  527. type: 'category',
  528. // boundaryGap: false,
  529. },
  530. yAxis: [
  531. {
  532. type: 'value',
  533. axisLine: {
  534. show: true,
  535. lineStyle: {
  536. color: '#3a83f7'
  537. }
  538. }
  539. }
  540. ],
  541. series: [
  542. {
  543. name: '订单数',
  544. yAxisIndex: 0,
  545. encode: {
  546. x: 'Name',
  547. y: 'TotalPurchases',
  548. },
  549. type: 'line',
  550. smooth: true,
  551. lineStyle: {
  552. type: 'dashed'
  553. },
  554. legendHoverLink: false,
  555. itemStyle: {
  556. color: '#3a83f7',
  557. },
  558. areaStyle: {
  559. color: {
  560. type: 'linear',
  561. x: 0,
  562. y: 0,
  563. x2: 0,
  564. y2: 1,
  565. colorStops: [{
  566. offset: 0, color: 'rgba(58, 131, 247, 0.5)' // 顶部不透明
  567. }, {
  568. offset: 0.2, color: 'rgba(58, 131, 247, 0.2)' // 中间更透明
  569. }, {
  570. offset: 1, color: 'rgba(58, 131, 247, 0)' // 底部完全透明
  571. }],
  572. global: false // 缺省为 false
  573. }
  574. }
  575. },
  576. ]
  577. }
  578. const chartRefImpandCli = ref()
  579. let chartObjImpandCli
  580. const option5 = {
  581. title: {text: '曝光量 & 点击量'},
  582. dataset: {
  583. source: []
  584. },
  585. tooltip: {
  586. trigger: 'axis',
  587. axisPointer: {
  588. label: {
  589. backgroundColor: '#6a7985'
  590. }
  591. }
  592. },
  593. legend: {
  594. selected: {}, // 控制显隐
  595. data: ['曝光量', '点击量'],
  596. show: true
  597. },
  598. grid: {
  599. top: 50, right: 65, bottom: 30, left: 65,
  600. },
  601. xAxis: {
  602. type: 'category',
  603. // boundaryGap: false,
  604. },
  605. yAxis: [
  606. {
  607. type: 'value',
  608. axisLine: {
  609. show: true,
  610. lineStyle: {
  611. color: '#3a83f7' // 第一个 Y 轴的颜色
  612. }
  613. }
  614. },
  615. {
  616. type: 'value',
  617. splitLine: {
  618. show: false
  619. },
  620. axisLine: {
  621. show: true,
  622. lineStyle: {
  623. color: '#f19a37' // 第二个 Y 轴的颜色
  624. }
  625. }
  626. }
  627. ],
  628. series: [
  629. {
  630. name: '曝光量',
  631. yAxisIndex: 0,
  632. encode: {
  633. x: 'Name',
  634. y: 'Impression',
  635. },
  636. type: 'line',
  637. smooth: true,
  638. itemStyle: {
  639. color: '#3a83f7',
  640. },
  641. areaStyle: {
  642. color: {
  643. type: 'linear',
  644. x: 0,
  645. y: 0,
  646. x2: 0,
  647. y2: 1,
  648. colorStops: [{
  649. offset: 0, color: 'rgba(58, 131, 247, 0.5)' // 顶部不透明
  650. }, {
  651. offset: 0.2, color: 'rgba(58, 131, 247, 0.2)' // 中间更透明
  652. }, {
  653. offset: 1, color: 'rgba(58, 131, 247, 0)' // 底部完全透明
  654. }],
  655. global: false // 缺省为 false
  656. }
  657. }
  658. },
  659. {
  660. name: '点击量',
  661. yAxisIndex: 1,
  662. encode: {
  663. x: 'Name',
  664. y: 'Click',
  665. },
  666. type: 'line',
  667. smooth: true,
  668. itemStyle: {
  669. color: '#f19a37',
  670. },
  671. areaStyle: {
  672. color: {
  673. type: 'linear',
  674. x: 0,
  675. y: 0,
  676. x2: 0,
  677. y2: 1,
  678. colorStops: [{
  679. offset: 0, color: 'rgba(241, 154, 55, 0.5)' // 顶部半透明
  680. }, {
  681. offset: 0.2, color: 'rgba(241, 154, 55, 0.2)' // 中间更透明
  682. }, {
  683. offset: 1, color: 'rgba(241, 154, 55, 0)' // 底部完全透明
  684. }],
  685. global: false // 缺省为 false
  686. }
  687. }
  688. },
  689. ]
  690. }
  691. function initLine() {
  692. chartObjOne = echarts.init(chartRefOne.value)
  693. chartObjAcos = echarts.init(chartRefAcos.value)
  694. chartObjCPCandCTR = echarts.init(chartRefCPCandCTR.value)
  695. chartObjTotalPurchases = echarts.init(chartRefTotalPurchases.value)
  696. chartObjImpandCli = echarts.init(chartRefImpandCli.value)
  697. }
  698. function setChartOptions() {
  699. const chartOptions = [
  700. { chart: chartObjOne, option: option },
  701. { chart: chartObjAcos, option: option2 },
  702. { chart: chartObjCPCandCTR, option: option3 },
  703. { chart: chartObjTotalPurchases, option: option4 },
  704. { chart: chartObjImpandCli, option: option5 }
  705. ];
  706. chartOptions.forEach(chartOption => {
  707. try {
  708. chartOption.option.dataset.source = optionSource
  709. chartOption.chart.setOption(chartOption.option)
  710. } catch (error) {
  711. console.error('设置图表选项失败:', error)
  712. }
  713. })
  714. }
  715. function resizeChart() {
  716. chartObjOne.resize()
  717. chartObjAcos.resize()
  718. chartObjCPCandCTR.resize()
  719. chartObjTotalPurchases.resize()
  720. chartObjImpandCli.resize()
  721. }
  722. onMounted(async () => {
  723. initLine()
  724. window.addEventListener('resize', resizeChart) // 监听窗口大小变化,调整图表大小
  725. setTimeout(() => {
  726. resizeChart()
  727. }, 10)
  728. })
  729. </script>
  730. <style scoped lang="scss">
  731. $homeNavLengh: 8;
  732. .home-container {
  733. overflow: hidden;
  734. margin-top: 10px;
  735. .home-card-one,
  736. .home-card-two,
  737. .home-card-three {
  738. .home-card-item {
  739. width: 100%;
  740. height: 130px;
  741. border-radius: 4px;
  742. transition: all ease 0.3s;
  743. padding: 20px;
  744. overflow: hidden;
  745. background: #ffffff;
  746. box-shadow: var(--el-box-shadow-light);
  747. color: var(--el-text-color-primary);
  748. border: 1px solid var(--next-border-color-light);
  749. &:hover {
  750. box-shadow: 0 2px 12px var(--next-color-dark-hover);
  751. transition: all ease 0.3s;
  752. }
  753. &-icon {
  754. width: 70px;
  755. height: 70px;
  756. border-radius: 100%;
  757. flex-shrink: 1;
  758. i {
  759. color: var(--el-text-color-placeholder);
  760. }
  761. }
  762. &-title {
  763. font-size: 15px;
  764. font-weight: bold;
  765. height: 30px;
  766. }
  767. }
  768. }
  769. .home-card-one {
  770. @for $i from 0 through 3 {
  771. .home-one-animation#{$i} {
  772. opacity: 0;
  773. animation-name: error-num;
  774. animation-duration: 0.5s;
  775. animation-fill-mode: forwards;
  776. animation-delay: calc($i/10) + s;
  777. }
  778. }
  779. }
  780. .home-card-two,
  781. .home-card-three {
  782. .home-card-item {
  783. height: 400px;
  784. width: 100%;
  785. overflow: hidden;
  786. .home-monitor {
  787. height: 100%;
  788. .flex-warp-item {
  789. width: 25%;
  790. height: 111px;
  791. display: flex;
  792. .flex-warp-item-box {
  793. margin: auto;
  794. text-align: center;
  795. color: var(--el-text-color-primary);
  796. display: flex;
  797. border-radius: 5px;
  798. background: var(--next-bg-color);
  799. cursor: pointer;
  800. transition: all 0.3s ease;
  801. &:hover {
  802. background: var(--el-color-primary-light-9);
  803. transition: all 0.3s ease;
  804. }
  805. }
  806. @for $i from 0 through $homeNavLengh {
  807. .home-animation#{$i} {
  808. opacity: 0;
  809. animation-name: error-num;
  810. animation-duration: 0.5s;
  811. animation-fill-mode: forwards;
  812. animation-delay: calc($i/10) + s;
  813. }
  814. }
  815. }
  816. }
  817. }
  818. }
  819. }
  820. .down {
  821. margin-top: 10px;
  822. }
  823. </style>