managerStatistics.vue 64 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624
  1. <style>
  2. .materialReport .chart-card-content {
  3. display: none !important;
  4. }
  5. </style>
  6. <style scoped>
  7. .bg {
  8. width: 100%;
  9. height: 100%;
  10. }
  11. .bg:after {
  12. content: '';
  13. width: 110%;
  14. height: 110%;
  15. position: absolute;
  16. left: -5%;
  17. top: -5%;
  18. background: inherit;
  19. filter: blur(10px);
  20. z-index: 2;
  21. background: rgba(0, 0, 0, 0.8);
  22. }
  23. .top-ul-style {
  24. width: 100%;
  25. padding-left: 0;
  26. }
  27. .top-ul-style li {
  28. height: 100px;
  29. border: 1px solid #f2f2f2;
  30. margin-bottom: 5px;
  31. padding: 10px;
  32. display: flex;
  33. justify-content: space-between;
  34. }
  35. .li-cost {
  36. display: flex;
  37. flex-flow: column;
  38. justify-content: center;
  39. align-content: flex-end;
  40. }
  41. .li-cost span {
  42. font-size: 16px;
  43. font-weight: 500;
  44. min-width: 50px;
  45. text-align: right;
  46. }
  47. </style>
  48. <template>
  49. <div class="materialReport">
  50. <div class="card-containers">
  51. <div class="option" style="justify-content: space-between">
  52. <div class="option" style="padding: 0">
  53. <div class="item">
  54. <span>日期选择</span>
  55. <a-range-picker
  56. v-model="dateValue"
  57. :ranges="dateRanges"
  58. :disabled-date="(current) => disabledDate(dateValue, current)"
  59. style="width: 300px"
  60. />
  61. </div>
  62. <div class="item">
  63. <span>媒体维度</span>
  64. <a-radio-group v-model="mediaDimension" @change="mediaDimensionChange">
  65. <a-radio-button value="b">快手</a-radio-button>
  66. <a-radio-button
  67. value="a"
  68. :disabled="
  69. roleCode == 'CompanyManager' &&
  70. !dataDimensionList.filter((item) => item.companyId == dataDimensionValue)[0]
  71. .ttDesignId
  72. "
  73. >头条</a-radio-button
  74. >
  75. </a-radio-group>
  76. </div>
  77. <div class="item">
  78. <span>公司</span>
  79. <a-select
  80. v-model="dataDimensionValue"
  81. style="width: 300px; margin-left: 10px"
  82. :filterOption="filterOption"
  83. showSearch
  84. allowClear
  85. :disabled="roleCode == 'CompanyManager'"
  86. >
  87. <a-select-option
  88. v-for="(item, index) in dataDimensionList"
  89. :key="index + 1"
  90. :value="item.companyId"
  91. :disabled="mediaDimension == 'a' && !item.ttDesignId"
  92. >
  93. {{ item.companyName }}
  94. </a-select-option>
  95. </a-select>
  96. </div>
  97. </div>
  98. <div class="item" style="float: right">
  99. <a-button :loading="searchLoading" type="primary" @click="handleSubmit"> 搜索 </a-button>
  100. <a-button
  101. :disabled="spinning"
  102. :loading="resetLoading"
  103. style="margin-left: 15px"
  104. @click="resetSubmit"
  105. >
  106. 重置
  107. </a-button>
  108. <a-button type="primary" style="margin-left: 15px" @click="dataKanBan">数据看板</a-button>
  109. </div>
  110. </div>
  111. </div>
  112. <a-row :gutter="24" style="margin-top: 20px">
  113. <a-col :span="16">
  114. <a-row :gutter="24">
  115. <a-col :span="12">
  116. <a-spin :spinning="spinning">
  117. <a-card class="material-report-card">
  118. <span slot="title"> 素材产出数量 </span>
  119. <div v-if="materialManyVisible">
  120. <div
  121. id="accountIndexEchartOnePie"
  122. ref="accountIndexEchartOnePie"
  123. style="width: 90%; height: 300px; margin-right: 20px"
  124. :style="{ width: clientWidth / 3 - 48 - 24 + 'px' }"
  125. ></div>
  126. </div>
  127. <a-list v-else :data-source="[]" />
  128. </a-card>
  129. </a-spin>
  130. </a-col>
  131. <a-col :span="12">
  132. <a-spin :spinning="spinningChart">
  133. <a-card class="material-report-card">
  134. <span slot="title"> 运营消耗情况 </span>
  135. <div style="width: 100%; display: flex">
  136. <div style="width: 100%">
  137. <div v-if="operateVisible && barTotal > 0">
  138. <div
  139. id="operateEchartBar"
  140. ref="operateEchartBar"
  141. style="width: 100%; height: 240px; margin-right: 20px"
  142. :style="{ width: clientWidth / 3 - 48 - 24 + 'px' }"
  143. ></div>
  144. </div>
  145. <a-list v-else :data-source="[]" />
  146. </div>
  147. </div>
  148. </a-card>
  149. </a-spin>
  150. </a-col>
  151. </a-row>
  152. <a-row :gutter="24" style="margin-top: 24px">
  153. <a-col :span="12">
  154. <a-spin :spinning="spinningChartPie">
  155. <a-card class="material-report-card">
  156. <span slot="title"> 素材产出消耗 </span>
  157. <div v-if="materialPieVisible">
  158. <div
  159. id="materialPie"
  160. ref="materialPie"
  161. style="width: 90%; height: 300px; margin-right: 20px"
  162. :style="{ width: clientWidth / 3 - 48 - 24 + 'px' }"
  163. ></div>
  164. </div>
  165. <a-list v-else :data-source="[]" />
  166. </a-card>
  167. </a-spin>
  168. </a-col>
  169. <a-col :span="12">
  170. <a-spin :spinning="spinningTarget">
  171. <a-card class="material-report-card">
  172. <span slot="title"> 本月消耗完成度 </span>
  173. <div style="width: 100%; display: flex">
  174. <div style="width: 50%">
  175. <div v-if="completeEchart">
  176. <div
  177. style="
  178. width: 90%;
  179. height: 300px;
  180. margin-right: 20px;
  181. display: flex;
  182. justify-content: center;
  183. align-items: center;
  184. "
  185. >
  186. <a-tooltip :title="totalConsume" slot="action">
  187. <a-progress
  188. type="dashboard"
  189. :percent="completePercent"
  190. :width="160"
  191. style="margin-top: -40px"
  192. />
  193. </a-tooltip>
  194. </div>
  195. </div>
  196. <a-list v-else :data-source="[]" />
  197. </div>
  198. <div
  199. style="width: 50%; display: flex; justify-content: center; align-items: center"
  200. >
  201. <a-input
  202. addon-before="本月目标"
  203. style="margin-top: -40px"
  204. v-model="completeEchartValue"
  205. >
  206. <a slot="addonAfter" @click="okValue">确定</a>
  207. </a-input>
  208. </div>
  209. </div>
  210. </a-card>
  211. </a-spin>
  212. </a-col>
  213. </a-row>
  214. <a-row :gutter="24" style="margin-top: 24px">
  215. <a-col :span="24">
  216. <a-spin :spinning="spinningMedio">
  217. <a-card class="material-report-card">
  218. <span slot="title"> 分媒体投放数据 </span>
  219. <div v-if="medioDataVisible && medioKsData.length > 0">
  220. <div
  221. id="medioDataLine"
  222. ref="medioDataLine"
  223. style="width: 90%; height: 300px; margin-right: 20px"
  224. :style="{ width: clientWidth * 0.6 - 48 - 24 + 'px' }"
  225. ></div>
  226. </div>
  227. <a-list v-else :data-source="[]" />
  228. </a-card>
  229. </a-spin>
  230. </a-col>
  231. </a-row>
  232. </a-col>
  233. <a-col :span="8">
  234. <a-row :gutter="24">
  235. <a-col :span="24">
  236. <a-spin :spinning="spinningAllData">
  237. <a-card class="material-report-card" style="height: 492px">
  238. <span slot="title"> 整体数据概览 </span>
  239. <div v-if="allData" style="margin-top: 10px">
  240. <h4>今日消耗</h4>
  241. <p
  242. style="
  243. width: 90%;
  244. display: flex;
  245. justify-content: space-between;
  246. font-weight: bold;
  247. margin-left: 5%;
  248. "
  249. >
  250. <span style="font-size: 36px; color: rgb(245, 178, 62)">{{
  251. allData.cost | decimalsHandle
  252. }}</span
  253. ><span style="position: relative; top: 20px">
  254. <img
  255. style="width: 20px; position: absolute; right: 70px"
  256. src="./assets/shang.png"
  257. alt=""
  258. v-if="allData.costRatio > 0"
  259. />
  260. <!-- TODO 这个是下降的样式,后续优化 -->
  261. <img
  262. style="width: 20px; position: absolute; right: 70px"
  263. src="./assets/xia.png"
  264. alt=""
  265. v-else
  266. />
  267. {{ allData.costRatio }}%</span
  268. >
  269. </p>
  270. <h4>今日基建数</h4>
  271. <p
  272. style="
  273. width: 90%;
  274. display: flex;
  275. justify-content: space-between;
  276. font-weight: bold;
  277. margin-left: 5%;
  278. "
  279. >
  280. <span style="font-size: 24px; color: rgb(33, 105, 254)">{{
  281. allData.groupNum + '个'
  282. }}</span
  283. ><span style="position: relative; top: 20px">
  284. <img
  285. style="width: 20px; position: absolute; right: 70px"
  286. src="./assets/shang.png"
  287. alt=""
  288. v-if="allData.unitRatio > 0"
  289. />
  290. <!-- TODO 这个是下降的样式,后续优化 -->
  291. <img
  292. style="width: 20px; position: absolute; right: 70px"
  293. src="./assets/xia.png"
  294. alt=""
  295. v-else
  296. />
  297. {{ allData.unitRatio }}%</span
  298. >
  299. </p>
  300. <h4>今日素材产出</h4>
  301. <p
  302. style="
  303. width: 90%;
  304. display: flex;
  305. justify-content: space-between;
  306. font-weight: bold;
  307. margin-left: 5%;
  308. "
  309. >
  310. <span style="font-size: 24px; color: rgb(232, 84, 65)">{{
  311. allData.materialNum + '个'
  312. }}</span
  313. ><span style="position: relative; top: 20px">
  314. <img
  315. style="width: 20px; position: absolute; right: 70px"
  316. src="./assets/shang.png"
  317. alt=""
  318. v-if="allData.materialRatio > 0"
  319. />
  320. <!-- TODO 这个是下降的样式,后续优化 -->
  321. <img
  322. style="width: 20px; position: absolute; right: 70px"
  323. src="./assets/xia.png"
  324. alt=""
  325. v-else
  326. />{{ allData.materialRatio }}%</span
  327. >
  328. </p>
  329. <h4>人效比</h4>
  330. <p
  331. style="
  332. width: 90%;
  333. display: flex;
  334. justify-content: space-between;
  335. font-weight: bold;
  336. margin-left: 5%;
  337. "
  338. >
  339. <span style="font-size: 24px; color: rgb(132, 119, 246)">{{
  340. allData.renXiao
  341. }}</span>
  342. </p>
  343. </div>
  344. <a-list v-else :data-source="[]" />
  345. </a-card>
  346. </a-spin>
  347. </a-col>
  348. <a-col :span="24" style="margin-top: 24px">
  349. <a-spin :spinning="spinningTop">
  350. <a-card class="material-report-card" style="height: 492px">
  351. <span slot="title"> 项目消耗Top10 </span>
  352. <a-radio-group v-model="topType" @change="topTypeChange" slot="extra">
  353. <a-radio-button value="b">柱形图</a-radio-button>
  354. <a-radio-button value="a">表格</a-radio-button>
  355. </a-radio-group>
  356. <div style="margin-top: 10px">
  357. <div v-if="topType == 'b'">
  358. <div v-if="topVisible && topData.length > 0">
  359. <div
  360. id="topEcharts"
  361. ref="topEcharts"
  362. style="width: 100%; height: 380px; margin-right: 20px"
  363. :style="{ width: clientWidth / 3 - 48 - 24 + 'px' }"
  364. ></div>
  365. </div>
  366. <a-list v-else :data-source="[]" />
  367. </div>
  368. <a-table
  369. bordered
  370. :columns="columns"
  371. :data-source="topData"
  372. v-else
  373. :pagination="false"
  374. :scroll="{ y: 300 }"
  375. >
  376. </a-table>
  377. </div>
  378. </a-card>
  379. </a-spin>
  380. </a-col>
  381. </a-row>
  382. </a-col>
  383. </a-row>
  384. </div>
  385. </template>
  386. <script>
  387. import moment from 'moment'
  388. import YoutTable from '@/components/youtTable/YoutTable'
  389. import ChartCard from '@/components/ChartCard'
  390. import Trend from '@/components/Trend'
  391. import { mapGetters } from 'vuex'
  392. import { stopOtherVideo, closeAllVideoFun } from '@/utils/videoControl' // 停止除当前外的其他视频播放,及停止所有视频播放的方法
  393. var echarts = require('echarts')
  394. const columns = [
  395. {
  396. title: '项目名称',
  397. dataIndex: 'projectName',
  398. },
  399. {
  400. title: '消耗',
  401. dataIndex: 'allCost',
  402. },
  403. {
  404. title: '基建数',
  405. dataIndex: 'adNum',
  406. },
  407. ]
  408. function getDaysBetween(dateString1, dateString2) {
  409. var startDate = Date.parse(dateString1)
  410. var endDate = Date.parse(dateString2)
  411. if (startDate > endDate) {
  412. return 0
  413. }
  414. if (startDate == endDate) {
  415. return 1
  416. }
  417. var days = (endDate - startDate) / (1 * 24 * 60 * 60 * 1000)
  418. return days + 1
  419. }
  420. function getArrayValue(array, key) {
  421. var key = key || 'value'
  422. var res = []
  423. if (array) {
  424. array.forEach(function (t) {
  425. res.push(t[key])
  426. })
  427. }
  428. return res
  429. }
  430. function array2obj(array, key) {
  431. var resObj = {}
  432. for (var i = 0; i < array.length; i++) {
  433. resObj[array[i][key]] = array[i]
  434. }
  435. return resObj
  436. }
  437. function getData(data, sumValue) {
  438. var res = {
  439. series: [],
  440. yAxis: [],
  441. }
  442. for (let i = 0; i < data.length; i++) {
  443. res.series.push({
  444. type: 'pie',
  445. clockWise: false, //顺时加载
  446. hoverAnimation: false, //鼠标移入变大
  447. radius: [73 - i * 15 + '%', 65 - i * 15 + '%'],
  448. center: ['25%', '55%'],
  449. label: {
  450. show: false,
  451. },
  452. itemStyle: {
  453. label: {
  454. show: false,
  455. },
  456. labelLine: {
  457. show: false,
  458. },
  459. borderWidth: 5,
  460. },
  461. data: [
  462. {
  463. value: (data[i].value * 0.75).toFixed(3),
  464. name: data[i].name,
  465. },
  466. {
  467. value: sumValue - (data[i].value * 0.75).toFixed(3),
  468. name: '',
  469. itemStyle: {
  470. color: 'rgba(0,0,0,0)',
  471. borderWidth: 0,
  472. },
  473. tooltip: {
  474. show: false,
  475. },
  476. hoverAnimation: false,
  477. },
  478. ],
  479. })
  480. res.series.push({
  481. name: '',
  482. type: 'pie',
  483. silent: true,
  484. z: 1,
  485. clockWise: false, //顺时加载
  486. hoverAnimation: false, //鼠标移入变大
  487. radius: [73 - i * 15 + '%', 65 - i * 15 + '%'],
  488. center: ['25%', '55%'],
  489. label: {
  490. show: false,
  491. },
  492. itemStyle: {
  493. label: {
  494. show: false,
  495. },
  496. labelLine: {
  497. show: false,
  498. },
  499. borderWidth: 5,
  500. },
  501. data: [
  502. {
  503. value: 7.5,
  504. itemStyle: {
  505. color: '#E3F0FF',
  506. borderWidth: 0,
  507. },
  508. tooltip: {
  509. show: false,
  510. },
  511. hoverAnimation: false,
  512. },
  513. {
  514. value: 2.5,
  515. name: '',
  516. itemStyle: {
  517. color: 'rgba(0,0,0,0)',
  518. borderWidth: 0,
  519. },
  520. tooltip: {
  521. show: false,
  522. },
  523. hoverAnimation: false,
  524. },
  525. ],
  526. })
  527. res.yAxis.push(((data[i].value / sumValue) * 100).toFixed(2) + '%')
  528. }
  529. return res
  530. }
  531. export default {
  532. components: {
  533. YoutTable,
  534. ChartCard,
  535. Trend,
  536. },
  537. data() {
  538. return {
  539. userInfoId: false,
  540. roleCode: localStorage.getItem('roleCode'),
  541. noImg: require('@/assets/noImg.png'),
  542. spinning: false,
  543. spinningChart: false,
  544. spinningChartPie: false,
  545. spinningTarget: false,
  546. spinningMedio: false,
  547. spinningAllData: false,
  548. spinningTop: false,
  549. loading: false,
  550. columns,
  551. materialManyVisible: true, //素材产出数量饼图展示
  552. pieData: [], //素材产出数量饼图数据
  553. pieTotal: null, //素材产出数量饼图总数
  554. operateVisible: true, //运营消耗情况
  555. barData: [],
  556. barTotal: null,
  557. materialPieVisible: false,
  558. materialPieData: [],
  559. materialPieTotal: null,
  560. completeEchart: true,
  561. completeEchartValue: 0,
  562. completePercent: 0,
  563. totalConsume: 0,
  564. medioDataVisible: false,
  565. medioKsData: [],
  566. medioTtData: [],
  567. allData: null,
  568. topVisible: false,
  569. topType: 'b',
  570. topData: [],
  571. dateRanges: {
  572. 昨天: [moment().subtract(1, 'days'), moment().subtract(1, 'days')],
  573. 近三天: [moment().subtract(3, 'days'), moment().subtract(1, 'days')],
  574. 近一周: [moment().subtract(7, 'days'), moment().subtract(1, 'days')],
  575. 近14天: [moment().subtract(14, 'days'), moment().subtract(1, 'days')],
  576. 近一月: [moment().subtract(1, 'months'), moment().subtract(1, 'days')],
  577. 近三月: [moment().subtract(3, 'months'), moment().subtract(1, 'days')],
  578. },
  579. dateValue: [moment(), moment()],
  580. dataDimension: 'a',
  581. mediaDimension: 'b',
  582. dataDimensionValue: undefined,
  583. dataDimensionList: [],
  584. specificLoading: false,
  585. clientWidth: 0,
  586. resetLoading: false,
  587. searchLoading: false,
  588. spinningPopularVideoList: false,
  589. }
  590. },
  591. watch: {},
  592. methods: {
  593. ...mapGetters(['userInfo']),
  594. filterOption(input, option) {
  595. return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
  596. },
  597. dataKanBan() {
  598. const a = document.createElement('a')
  599. document.body.appendChild(a)
  600. a.style.display = 'none'
  601. a.href = 'http://adsp.c-top.com.cn/boss-data-kanban'
  602. a.target = '_blank'
  603. a.click()
  604. document.body.removeChild(a)
  605. },
  606. getData() {
  607. if (!!this.dataDimensionValue) {
  608. this.getMetarialList()
  609. this.getOperateList()
  610. this.getMaterialConsumeData()
  611. this.getMedioData()
  612. this.getTotalConsume()
  613. this.getRealTimeData()
  614. this.getRealTimeData()
  615. this.getTopTenData()
  616. this.searchLoading = false
  617. this.resetLoading = false
  618. } else {
  619. this.$message.error('请先选择公司')
  620. }
  621. },
  622. getProjectList() {
  623. this.specificLoading = true
  624. return new Promise((resolve, reject) => {
  625. this.getAction(process.env.VUE_APP_BASE_MATERIAL_URL + '/manager/company/getCompanyList').then(
  626. (res) => {
  627. this.specificLoading = false
  628. if (res.success) {
  629. this.dataDimensionList = res.result
  630. resolve(res.result)
  631. } else {
  632. reject(res.message)
  633. }
  634. }
  635. )
  636. })
  637. },
  638. decimalsHandle(val, num) {
  639. if (val && typeof val != 'string') {
  640. if (val >= 0) {
  641. val = parseFloat(val).toFixed(num)
  642. let numberStr = val.toString()
  643. let str = numberStr.split('.')
  644. let str0 = str[0].split('').reverse()
  645. for (let i = 0; i < str0.length; i++) {
  646. if ((i + 1) % 4 === 0) {
  647. str0.splice(i, 0, ',')
  648. }
  649. }
  650. str0.reverse()
  651. let handleResult = ''
  652. for (let j = 0; j < str0.length; j++) {
  653. handleResult += str0[j]
  654. }
  655. return handleResult + '.' + str[1]
  656. } else {
  657. val = parseFloat(val).toFixed(num)
  658. let numberStr = val.toString()
  659. let str = numberStr.split('.')
  660. let str0 = str[0].substr(1).split('').reverse()
  661. for (let i = 0; i < str0.length; i++) {
  662. if ((i + 1) % 4 === 0) {
  663. str0.splice(i, 0, ',')
  664. }
  665. }
  666. str0.reverse()
  667. let handleResult = ''
  668. for (let j = 0; j < str0.length; j++) {
  669. handleResult += str0[j]
  670. }
  671. return '-' + handleResult + '.' + str[1]
  672. }
  673. } else if (typeof val == 'string') {
  674. return val
  675. } else {
  676. return 0
  677. }
  678. },
  679. handleSubmit() {
  680. if (!!this.dataDimensionValue) {
  681. this.searchLoading = true
  682. this.resetLoading = true
  683. if (this.dateValue.length == 2) {
  684. var between = getDaysBetween(this.dateValue[0], this.dateValue[1])
  685. if (between > 90) {
  686. this.$message.error('时间选择不可超过90天')
  687. } else {
  688. this.topType = 'b'
  689. this.getData()
  690. }
  691. } else {
  692. this.$message.error('时间未选择')
  693. }
  694. } else {
  695. this.$message.error('请先选择公司')
  696. }
  697. },
  698. resetSubmit() {
  699. this.dataDimension = 'a'
  700. this.mediaDimension = 'b'
  701. this.topType = 'b'
  702. this.resetLoading = true
  703. this.getUserCampany().then((res) => {
  704. this.dateValue = [moment(), moment()]
  705. this.getData()
  706. })
  707. },
  708. //获取echart的值
  709. initEchart(idName, optionName) {
  710. let that = this
  711. const chart = this.$refs[idName]
  712. if (chart) {
  713. const myChart = echarts.init(document.getElementById(idName))
  714. myChart.setOption(optionName)
  715. // if (idName === 'materialPie') {
  716. // var i = 0
  717. // // myChart.dispatchAction({ type: 'highlight', seriesIndex: 0, dataIndex: i }) //设置默认选中高亮部分
  718. // setInterval(function () {
  719. // i++
  720. // if (i == optionName.series[0].data.length) {
  721. // i = 0
  722. // }
  723. // myChart.dispatchAction({
  724. // type: 'downplay',
  725. // seriesIndex: 0,
  726. // dataIndex: i == 0 ? optionName.series[0].data.length-2 : i - 1,
  727. // })
  728. // myChart.dispatchAction({ type: 'highlight', seriesIndex: 0, dataIndex: i == optionName.series[0].data.length ? 0 : i }) //设置默认选中高亮部分
  729. // }, 1000)
  730. // }
  731. window.addEventListener('resize', function () {
  732. that.clientWidth = document.documentElement.clientWidth - 224
  733. myChart.resize()
  734. })
  735. }
  736. },
  737. disabledDate(dateValue, current) {
  738. // .subtract(1, 'days')
  739. var startDate = dateValue[0] ? dateValue[0]._d : ''
  740. return (current && current > moment()) || (current && current < moment(startDate).subtract(90, 'days'))
  741. },
  742. mediaDimensionChange(e) {
  743. if (this.roleCode == 'admin') {
  744. this.dataDimensionValue = ''
  745. }
  746. },
  747. getUserCampany() {
  748. var params = {}
  749. params.userId = this.userInfo().id
  750. return new Promise((resolve, reject) => {
  751. this.getAction('/system/userCompany/queryCompanyByUserId', params).then((res) => {
  752. if (res.success) {
  753. this.dataDimensionValue = res.result
  754. resolve()
  755. } else {
  756. reject()
  757. }
  758. })
  759. })
  760. },
  761. parameterData() {
  762. var params = {}
  763. params.startTime = params.startTime =
  764. this.dateValue.length === 2 ? moment(this.dateValue[0]).format('YYYY-MM-DD') : null
  765. params.endTime = this.dateValue.length === 2 ? moment(this.dateValue[1]).format('YYYY-MM-DD') : null
  766. params.companyId = this.dataDimensionValue
  767. params.mediaId = this.mediaDimension === 'a' ? 1 : 2
  768. return params
  769. },
  770. //素材产出数量
  771. getMetarialList() {
  772. // http://localhost:7006/material/manager/company/getMaterialProduce
  773. this.spinning = true
  774. this.getAction(process.env.VUE_APP_BASE_MATERIAL_URL + '/manager/company/getMaterialProduce', {
  775. ...this.parameterData(),
  776. }).then((res) => {
  777. this.spinning = false
  778. if (res.code == 200) {
  779. if (res.result) {
  780. var servicedata = res.result.list
  781. if (servicedata.length > 0) {
  782. this.materialManyVisible = true
  783. this.pieData = []
  784. let num = 0
  785. for (var i = 0; i < servicedata.length; i++) {
  786. var obj = new Object()
  787. obj.name = servicedata[i].depart_name
  788. obj.value = servicedata[i].count
  789. this.pieData[i] = obj
  790. }
  791. this.pieTotal = res.result.total
  792. this.$nextTick(() => {
  793. this.initEchart(
  794. 'accountIndexEchartOnePie',
  795. this.initPieOneData(this.pieData, this.pieTotal)
  796. )
  797. })
  798. } else {
  799. this.materialManyVisible = false
  800. }
  801. } else {
  802. this.pieData = []
  803. this.materialManyVisible = false
  804. }
  805. }
  806. })
  807. },
  808. // 素材产出数量饼图
  809. initPieOneData(pieData, pieTotal) {
  810. const list = pieData
  811. let option = {
  812. tooltip: {
  813. trigger: 'item',
  814. formatter: function (obj) {
  815. return (
  816. obj.name +
  817. ':' +
  818. obj.value +
  819. '(' +
  820. Math.round(pieTotal == 0 ? 0 : (obj.value / pieTotal) * 100) +
  821. '%)'
  822. )
  823. },
  824. },
  825. legend: {
  826. top: '20%',
  827. orient: 'vertical',
  828. right: '0%',
  829. textStyle: {
  830. //图例文字的样式
  831. fontSize: 12,
  832. },
  833. itemGap: 20,
  834. itemWidth: 15,
  835. itemHeight: 10,
  836. padding: [-45, 0, 0, 80],
  837. bottom: '55%',
  838. formatter: function (name) {
  839. //该函数用于设置图例显示后的百分比
  840. var data = list
  841. var total = 0
  842. var value
  843. list.forEach((item) => {
  844. if (item.name == name) {
  845. value = item.value
  846. }
  847. })
  848. var p = pieTotal == 0 ? 0 : Math.round((value / pieTotal) * 100) //求出百分比
  849. return p >= 10
  850. ? p == 11
  851. ? `${name} ${'|'} ${value} ${p}% `
  852. : `${name} ${'|'} ${value} ${p}% `
  853. : `${name} ${'|'} ${value} ${p}% ` //返回出图例所显示的内容是名称+百分比
  854. },
  855. },
  856. color: ['#016DDA', '#23A0E4', '#51C0F0', '#6BE0E0', '#24DFBE', '#04E893'],
  857. series: [
  858. {
  859. name: '',
  860. type: 'pie',
  861. radius: ['65%', '75%'],
  862. avoidLabelOverlap: false,
  863. hoverAnimation: true,
  864. silent: false,
  865. itemStyle: {
  866. borderRadius: 10,
  867. borderColor: 'white',
  868. borderWidth: 2,
  869. },
  870. label: {
  871. show: true,
  872. position: 'center',
  873. fontSize: 16,
  874. formatter: function (param) {
  875. return pieTotal + '\r\n\r\n素材总数'
  876. },
  877. textStyle: {
  878. fontSize: 16,
  879. color: 'black',
  880. },
  881. },
  882. left: 0,
  883. right: '50%',
  884. top: 0,
  885. bottom: '20%',
  886. animation: false,
  887. labelLine: {
  888. show: false,
  889. },
  890. data: list,
  891. },
  892. {
  893. name: '',
  894. type: 'pie',
  895. radius: ['50%', '60%'],
  896. avoidLabelOverlap: false,
  897. hoverAnimation: false,
  898. colorBy: 'series',
  899. silent: false,
  900. itemStyle: {
  901. borderRadius: 10,
  902. borderColor: 'white',
  903. borderWidth: 2,
  904. color: '#f2f2f2',
  905. // normal: { color: '#f2f2f2' },
  906. emphasis: { color: '#f2f2f2' },
  907. },
  908. label: {
  909. show: true,
  910. position: 'center',
  911. fontSize: 16,
  912. formatter: function (param) {
  913. return pieTotal + '\r\n\r\n素材总数'
  914. },
  915. textStyle: {
  916. fontSize: 16,
  917. color: 'black',
  918. },
  919. },
  920. left: 0,
  921. right: '50%',
  922. top: 0,
  923. bottom: '20%',
  924. animation: false,
  925. labelLine: {
  926. show: false,
  927. },
  928. data: list,
  929. },
  930. ],
  931. }
  932. return option
  933. },
  934. //运营消耗情况
  935. getOperateList() {
  936. this.spinningChart = true
  937. this.operateVisible = false
  938. this.getAction(process.env.VUE_APP_BASE_MATERIAL_URL + '/manager/company/getOperaterConsume', {
  939. ...this.parameterData(),
  940. }).then((res) => {
  941. this.spinningChart = false
  942. if (res.code == 200) {
  943. if (res.result) {
  944. var servicedata = res.result.list
  945. if (servicedata.length > 0) {
  946. this.operateVisible = true
  947. this.barData = []
  948. let num = 0
  949. for (var i = 0; i < servicedata.length; i++) {
  950. var obj = new Object()
  951. obj.name = servicedata[i].depart_name
  952. obj.value = servicedata[i].charge
  953. // obj.charge = servicedata[i].charge
  954. this.barData[i] = obj
  955. }
  956. this.barTotal = res.result.totalCharge
  957. this.$nextTick(() => {
  958. this.initEchart(
  959. 'operateEchartBar',
  960. this.initOperateEchartBarData(this.barData, this.barTotal)
  961. )
  962. })
  963. } else {
  964. this.operateVisible = false
  965. }
  966. } else {
  967. this.operateVisible = false
  968. }
  969. }
  970. })
  971. },
  972. //柱状图
  973. // operateEchartBar
  974. initOperateEchartBarData(barData, barTotal) {
  975. var data = barData
  976. var arrName = getArrayValue(data, 'name')
  977. var arrValue = getArrayValue(data, 'value')
  978. var sumValue = eval(arrValue.join('+'))
  979. var objData = array2obj(data, 'name')
  980. var optionData = getData(data, sumValue)
  981. var option = {
  982. backgroundColor: '#fff',
  983. legend: {
  984. show: true,
  985. top: 'center',
  986. left: '55%',
  987. itemGap: 20,
  988. itemWidth: 15,
  989. itemHeight: 10,
  990. data: arrName,
  991. padding: [0, 5],
  992. formatter: function (name) {
  993. return '{title|' + name + '} | {value|' + (objData[name].value / 10000).toFixed(2) + 'w}'
  994. },
  995. textStyle: {
  996. rich: {
  997. title: {
  998. fontSize: 12,
  999. color: 'rgba(0,0,0,.85)',
  1000. },
  1001. value: {
  1002. fontSize: 12,
  1003. color: 'rgba(0,0,0,.85)',
  1004. },
  1005. },
  1006. },
  1007. },
  1008. tooltip: {
  1009. show: true,
  1010. trigger: 'item',
  1011. formatter: function (name) {
  1012. return `${name.name}:${(name.value / 0.75).toFixed(3)}(${(
  1013. (name.value / 0.75 / sumValue) *
  1014. 100
  1015. ).toFixed(2)}%)`
  1016. },
  1017. },
  1018. color: ['#016DDA', '#23A0E4', '#51C0F0', '#6BE0E0', '#24DFBE', '#04E893'],
  1019. grid: {
  1020. top: '18%',
  1021. bottom:
  1022. barData.length == 5
  1023. ? '48%'
  1024. : barData.length == 3
  1025. ? '60%'
  1026. : barData.length == 4
  1027. ? '54%'
  1028. : barData.length == 2
  1029. ? '66%'
  1030. : barData.length == 1
  1031. ? '72%'
  1032. : '48%',
  1033. left: '25%',
  1034. containLabel: false,
  1035. },
  1036. yAxis: [
  1037. {
  1038. type: 'category',
  1039. inverse: true,
  1040. axisLine: {
  1041. show: false,
  1042. },
  1043. axisTick: {
  1044. show: false,
  1045. },
  1046. axisLabel: {
  1047. interval: 0,
  1048. inside: true,
  1049. textStyle: {
  1050. color: '#000',
  1051. fontSize: 10,
  1052. },
  1053. show: true,
  1054. },
  1055. data: optionData.yAxis,
  1056. },
  1057. ],
  1058. xAxis: [
  1059. {
  1060. show: false,
  1061. },
  1062. ],
  1063. series: optionData.series,
  1064. }
  1065. return option
  1066. },
  1067. //素材产出消耗
  1068. getMaterialConsumeData() {
  1069. this.spinningChartPie = true
  1070. this.getAction(process.env.VUE_APP_BASE_MATERIAL_URL + '/manager/company/getMaterialProduceConsume', {
  1071. ...this.parameterData(),
  1072. }).then((res) => {
  1073. this.spinningChartPie = false
  1074. if (res.code == 200) {
  1075. if (res.result) {
  1076. var servicedata = res.result.list
  1077. if (servicedata.length > 0) {
  1078. this.materialPieVisible = true
  1079. this.materialPieData = []
  1080. let num = 0
  1081. for (var i = 0; i < servicedata.length; i++) {
  1082. var obj = new Object()
  1083. obj.name = servicedata[i].depart_name
  1084. obj.value = servicedata[i].charge
  1085. this.materialPieData[i] = obj
  1086. }
  1087. this.materialPieTotal = res.result.totalCharge
  1088. this.$nextTick(() => {
  1089. this.initEchart(
  1090. 'materialPie',
  1091. this.initPieConsumeData(this.materialPieData, this.materialPieTotal)
  1092. )
  1093. })
  1094. } else {
  1095. this.materialPieVisible = false
  1096. }
  1097. } else {
  1098. this.materialPieVisible = false
  1099. }
  1100. }
  1101. })
  1102. },
  1103. // 素材产出消耗饼图
  1104. initPieConsumeData(pieData, pieTotal) {
  1105. const list = pieData
  1106. let option = {
  1107. tooltip: {
  1108. trigger: 'item',
  1109. formatter: function (obj) {
  1110. if (pieTotal == 0) {
  1111. return obj.name + ':' + obj.value + '(0%)'
  1112. } else {
  1113. return obj.name + ':' + obj.value + '(' + Math.round((obj.value / pieTotal) * 100) + '%)'
  1114. }
  1115. },
  1116. },
  1117. legend: {
  1118. top: '20%',
  1119. orient: 'vertical',
  1120. right: '0%',
  1121. textStyle: {
  1122. //图例文字的样式
  1123. fontSize: 12,
  1124. },
  1125. icon: 'circle',
  1126. itemStyle: {
  1127. borderCap: 'round',
  1128. },
  1129. itemGap: 20,
  1130. itemWidth: 15,
  1131. itemHeight: 10,
  1132. padding: [-45, 0, 0, 80],
  1133. bottom: '55%',
  1134. formatter: function (name) {
  1135. //该函数用于设置图例显示后的百分比
  1136. var data = list
  1137. var total = 0
  1138. var value
  1139. list.forEach((item) => {
  1140. total += item.value
  1141. if (item.name == name) {
  1142. value = item.value
  1143. }
  1144. })
  1145. var p = total == 0 ? 0 : Math.round((value / total) * 100) //求出百分比
  1146. return p >= 10
  1147. ? p == 11
  1148. ? `${name} ${'|'} ${p}% `
  1149. : `${name} ${'|'} ${p}% `
  1150. : `${name} ${'|'} ${p}% ` //返回出图例所显示的内容是名称+百分比
  1151. },
  1152. },
  1153. color: ['#FF3300', '#FFCC00', '#6600FF', '#3399FF', '#66FFFF', '#66CC99'],
  1154. series: [
  1155. {
  1156. type: 'pie',
  1157. radius: ['65%', '75%'],
  1158. avoidLabelOverlap: false,
  1159. hoverAnimation: true,
  1160. itemStyle: {
  1161. borderRadius: 10,
  1162. borderColor: '#fff',
  1163. borderWidth: 2,
  1164. },
  1165. // label: {
  1166. // show: false,
  1167. // position: 'center',
  1168. // formatter: function (name) {
  1169. // return name.value
  1170. // },
  1171. // color: 'black',
  1172. // },
  1173. label: {
  1174. show: true,
  1175. position: 'center',
  1176. fontSize: 16,
  1177. formatter: function (param) {
  1178. return (pieTotal / 10000).toFixed(2) + 'w' + '\r\n\r\n素材总消耗'
  1179. },
  1180. textStyle: {
  1181. fontSize: 16,
  1182. color: 'black',
  1183. },
  1184. },
  1185. emphasis: {
  1186. label: {
  1187. show: true,
  1188. fontSize: '16',
  1189. },
  1190. },
  1191. left: 0,
  1192. right: '50%',
  1193. top: 0,
  1194. bottom: '20%',
  1195. labelLine: {
  1196. show: false,
  1197. },
  1198. data: list,
  1199. },
  1200. ],
  1201. }
  1202. return option
  1203. },
  1204. getMedioData() {
  1205. this.spinningMedio = true
  1206. this.getAction(process.env.VUE_APP_BASE_MATERIAL_URL + '/manager/company/getMediaData', {
  1207. companyId: this.parameterData().companyId,
  1208. }).then((res) => {
  1209. this.spinningMedio = false
  1210. if (res.code == 200) {
  1211. if (res.result) {
  1212. this.medioDataVisible = true
  1213. this.medioKsData = res.result.ksdata
  1214. this.medioTtData = res.result.ttdate
  1215. this.$nextTick(() => {
  1216. this.initEchart('medioDataLine', this.initmedioData(this.medioKsData, this.medioTtData))
  1217. })
  1218. } else {
  1219. this.medioDataVisible = false
  1220. }
  1221. }
  1222. })
  1223. },
  1224. initmedioData(ksdata, ttdata) {
  1225. let option = {
  1226. title: {
  1227. text: '',
  1228. },
  1229. color: ['rgb(253,63,152)', 'rgb(102,128,255)', '#FBE6F3', '#E9EDFF', '#8A2BE2', '#3CB371'],
  1230. tooltip: {},
  1231. tooltip: {
  1232. trigger: 'axis',
  1233. position: function (pt) {
  1234. return [pt[0], '10%']
  1235. },
  1236. },
  1237. legend: {
  1238. data: ['快手', '头条'],
  1239. textStyle: {
  1240. fontSize: 12,
  1241. color: '#B0C4DE',
  1242. },
  1243. left: '0%',
  1244. },
  1245. grid: {
  1246. left: 0,
  1247. right: 0,
  1248. containLabel: true,
  1249. },
  1250. xAxis: {
  1251. type: 'category',
  1252. show: false,
  1253. data: ksdata.map((item) => {
  1254. return item.statDate
  1255. }),
  1256. axisLabel: {
  1257. show: true,
  1258. textStyle: {
  1259. color: '#B0C4DE',
  1260. },
  1261. },
  1262. axisLine: {
  1263. //x轴线
  1264. show: true,
  1265. lineStyle: {
  1266. color: '#B0C4DE',
  1267. },
  1268. },
  1269. },
  1270. yAxis: {
  1271. type: 'value',
  1272. show: false,
  1273. axisLabel: {
  1274. show: true,
  1275. textStyle: {
  1276. color: '#B0C4DE',
  1277. },
  1278. },
  1279. axisLine: {
  1280. //x轴线
  1281. show: true,
  1282. lineStyle: {
  1283. color: '#B0C4DE',
  1284. },
  1285. },
  1286. splitLine: {
  1287. show: true,
  1288. lineStyle: {
  1289. color: '#B0C4DE',
  1290. },
  1291. },
  1292. },
  1293. series: [
  1294. {
  1295. name: '快手',
  1296. type: 'line',
  1297. data: ksdata.map((item) => {
  1298. return item.allCost
  1299. }),
  1300. areaStyle: {
  1301. color: '#FBE6F3',
  1302. },
  1303. smooth: true,
  1304. symbol: 'circle',
  1305. symbolSize: 3,
  1306. },
  1307. {
  1308. name: '头条',
  1309. type: 'line',
  1310. data: ttdata.map((item) => {
  1311. return item.allCost
  1312. }),
  1313. areaStyle: {
  1314. color: '#E9EDFF',
  1315. },
  1316. smooth: true,
  1317. symbol: 'circle',
  1318. symbolSize: 3,
  1319. },
  1320. ],
  1321. }
  1322. return option
  1323. },
  1324. //查询本月总消耗
  1325. getTotalConsume() {
  1326. this.spinningTarget = true
  1327. this.getAction(process.env.VUE_APP_BASE_MATERIAL_URL + '/manager/company/getTotalConsume', {
  1328. companyId: this.parameterData().companyId,
  1329. mediaId: this.parameterData().mediaId,
  1330. }).then((res) => {
  1331. this.spinningTarget = false
  1332. if (res.code == 200) {
  1333. if (res.result.targetValue) {
  1334. this.completeEchartValue = parseFloat(res.result.targetValue)
  1335. if (parseFloat(res.result.totalConsume) > parseFloat(res.result.targetValue)) {
  1336. this.completePercent = 100
  1337. } else {
  1338. this.completePercent =
  1339. (parseFloat(res.result.totalConsume) / parseFloat(res.result.targetValue)).toFixed(2) *
  1340. 100
  1341. }
  1342. this.totalConsume = parseFloat(res.result.totalConsume)
  1343. } else {
  1344. this.completePercent = 0
  1345. this.totalConsume = parseFloat(res.result.totalConsume)
  1346. this.completeEchartValue = 0
  1347. }
  1348. }
  1349. })
  1350. },
  1351. okValue() {
  1352. this.getAction(process.env.VUE_APP_BASE_MATERIAL_URL + '/manager/company/setConsumeValue', {
  1353. companyId: this.parameterData().companyId,
  1354. mediaId: this.parameterData().mediaId,
  1355. targetValue: this.completeEchartValue,
  1356. }).then((res) => {
  1357. if (res.code == 200) {
  1358. this.getTotalConsume()
  1359. } else {
  1360. this.$message.error('设置失败')
  1361. }
  1362. })
  1363. },
  1364. getRealTimeData() {
  1365. this.spinningAllData = true
  1366. this.allData = null
  1367. this.getAction(process.env.VUE_APP_BASE_MATERIAL_URL + '/manager/company/getRealTimeData', {
  1368. companyId: this.parameterData().companyId,
  1369. mediaId: this.parameterData().mediaId,
  1370. }).then((res) => {
  1371. this.spinningAllData = false
  1372. if (res.code == 200) {
  1373. if (res.result) {
  1374. this.allData = res.result
  1375. } else {
  1376. this.allData = null
  1377. }
  1378. } else {
  1379. this.$message.error(res.message)
  1380. }
  1381. })
  1382. },
  1383. //TOP10
  1384. getTopTenData() {
  1385. this.spinningTop = true
  1386. this.getAction(process.env.VUE_APP_BASE_MATERIAL_URL + '/manager/company/getProjectConsumeTop', {
  1387. ...this.parameterData(),
  1388. }).then((res) => {
  1389. this.spinningTop = false
  1390. if (res.code == 200) {
  1391. var servicedata = res.result
  1392. // if (servicedata.length > 0) {
  1393. this.topVisible = true
  1394. this.topData = res.result
  1395. let num = 0
  1396. this.$nextTick(() => {
  1397. this.initEchart('topEcharts', this.initTopTenData(this.topData))
  1398. })
  1399. // } else {
  1400. // this.topVisible = false
  1401. // }
  1402. }
  1403. })
  1404. },
  1405. initTopTenData(topDataAll) {
  1406. var topData = JSON.parse(JSON.stringify(topDataAll))
  1407. topData = topData.sort(function (a, b) {
  1408. return a.allCost - b.allCost
  1409. })
  1410. var option = {
  1411. tooltip: {
  1412. trigger: 'axis',
  1413. axisPointer: {
  1414. type: 'shadow',
  1415. },
  1416. },
  1417. grid: {
  1418. left: '0%',
  1419. right: '3%',
  1420. bottom: '3%',
  1421. top: 0,
  1422. containLabel: true,
  1423. },
  1424. color: ['#009726', '#FFA500', '#8A2BE2', '#3CB371'],
  1425. xAxis: {
  1426. type: 'value',
  1427. // boundaryGap: [0, 0.01],
  1428. nameTextStyle: {
  1429. width: 10,
  1430. overflow: 'truncate',
  1431. },
  1432. axisTick: {
  1433. interval: 2,
  1434. },
  1435. axisLabel: {
  1436. show: true,
  1437. interval: 2,
  1438. rotate: 45,
  1439. },
  1440. },
  1441. yAxis: {
  1442. type: 'category',
  1443. data: topData.map((item) => {
  1444. return item.projectName
  1445. }),
  1446. nameTextStyle: {
  1447. width: '10%',
  1448. overflow: 'truncate',
  1449. },
  1450. axisTick: {
  1451. interval: 2,
  1452. },
  1453. },
  1454. series: [
  1455. {
  1456. type: 'bar',
  1457. data: topData.map((item) => {
  1458. return item.allCost
  1459. }),
  1460. showBackground: true,
  1461. backgroundStyle: {
  1462. color: '#E6F5EA',
  1463. },
  1464. barWidth: 15,
  1465. itemStyle: {
  1466. borderRadius: 15,
  1467. },
  1468. },
  1469. ],
  1470. }
  1471. return option
  1472. },
  1473. topTypeChange() {
  1474. if (this.topType == 'b') {
  1475. this.$nextTick(() => {
  1476. this.initEchart('topEcharts', this.initTopTenData(this.topData))
  1477. })
  1478. }
  1479. },
  1480. },
  1481. mounted() {
  1482. this.clientWidth = document.documentElement.clientWidth - 224
  1483. this.$nextTick(() => {
  1484. this.getProjectList()
  1485. this.getUserCampany()
  1486. .then((res) => {
  1487. this.getMetarialList()
  1488. this.getOperateList()
  1489. this.getMaterialConsumeData()
  1490. this.getMedioData()
  1491. this.getTotalConsume()
  1492. this.getRealTimeData()
  1493. this.getRealTimeData()
  1494. this.getTopTenData()
  1495. })
  1496. .catch(() => {
  1497. this.$message.error('未能获取到所属公司,请查看配置后重进页面!')
  1498. })
  1499. // this.getData()
  1500. })
  1501. },
  1502. activated() {
  1503. this.$nextTick(() => {
  1504. this.clientWidth = document.documentElement.clientWidth - 224
  1505. })
  1506. },
  1507. }
  1508. </script>
  1509. <style lang="less" scoped>
  1510. .materialReport {
  1511. .material-report-card-two {
  1512. width: 25%;
  1513. }
  1514. .material-report-card {
  1515. height: 320px;
  1516. ::v-deep .ant-card-body {
  1517. padding-top: 5px;
  1518. }
  1519. .report-card-result {
  1520. height: 88px;
  1521. }
  1522. .report-card-money {
  1523. font-size: 30px;
  1524. font-weight: bold;
  1525. }
  1526. .report-card-msg {
  1527. display: flex;
  1528. justify-content: space-between;
  1529. font-size: 14px;
  1530. margin-top: 20px;
  1531. }
  1532. .report-card-line {
  1533. width: 100%;
  1534. height: 1px;
  1535. margin-top: 20px;
  1536. background: #e8e8e8;
  1537. }
  1538. .report-card-radio {
  1539. display: flex;
  1540. justify-content: space-between;
  1541. margin-top: 12px;
  1542. font-size: 14px;
  1543. }
  1544. }
  1545. .option {
  1546. background: white;
  1547. padding: 20px;
  1548. display: flex;
  1549. justify-content: flex-start;
  1550. flex-wrap: wrap;
  1551. .item {
  1552. margin-right: 15px;
  1553. margin-bottom: 15px;
  1554. height: 32px;
  1555. line-height: 32px;
  1556. flex-shrink: 0;
  1557. span {
  1558. margin-right: 10px;
  1559. }
  1560. }
  1561. }
  1562. .echart {
  1563. margin-top: 20px;
  1564. padding: 0 20px 20px;
  1565. background: white;
  1566. .echart-header {
  1567. padding: 20px 0;
  1568. font-size: 15px;
  1569. font-weight: 600;
  1570. }
  1571. }
  1572. .tableBody {
  1573. margin-top: 20px;
  1574. }
  1575. }
  1576. </style>
  1577. <style>
  1578. .materialReport .card-containers {
  1579. overflow: hidden !important;
  1580. }
  1581. .materialReport .card-containers > .ant-tabs-card > .ant-tabs-content {
  1582. margin-top: -16px !important;
  1583. }
  1584. .materialReport .card-containers > .ant-tabs-card > .ant-tabs-content > .ant-tabs-tabpane {
  1585. background: #fff !important;
  1586. }
  1587. .materialReport .card-containers > .ant-tabs-card > .ant-tabs-bar {
  1588. border-color: #fff !important;
  1589. }
  1590. .materialReport .card-containers > .ant-tabs-card > .ant-tabs-bar .ant-tabs-tab {
  1591. border-color: transparent !important;
  1592. background: transparent !important;
  1593. }
  1594. .materialReport .card-containers > .ant-tabs-card > .ant-tabs-bar .ant-tabs-tab-active {
  1595. border-color: #fff !important;
  1596. background: #fff !important;
  1597. }
  1598. </style>