dataDisplayStatistics.vue 39 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385
  1. <style lang="scss" scoped>
  2. .search-bar {
  3. display: flex;
  4. align-items: center;
  5. }
  6. .search-box p {
  7. display: inline-block;
  8. border: 1px solid #f2f2f2;
  9. border-radius: 5px;
  10. margin-right: 10px;
  11. padding: 5px 10px;
  12. cursor: pointer;
  13. }
  14. </style>
  15. <style>
  16. /* .data-display-statistics .ant-card-body {
  17. padding: 0 15px;
  18. } */
  19. .data-display-statistics .ant-col-6 {
  20. margin: 10px 0;
  21. }
  22. .data-display-statistics .ant-col-6 .ant-card-body {
  23. display: flex;
  24. justify-content: center;
  25. }
  26. .data-display-statistics .ant-col-6 p,
  27. .data-display-statistics .ant-col-6 span {
  28. text-align: center;
  29. line-height: 40px;
  30. font-size: 30px;
  31. font-weight: 600;
  32. color: red;
  33. margin: 0;
  34. }
  35. .search-box .ant-card-body {
  36. padding: 5px 15px;
  37. }
  38. .data-display-statistics .ant-col-6 .ant-card-body .styleElse {
  39. line-height: 60px;
  40. height: 40px;
  41. font-size: 16px;
  42. font-weight: 400;
  43. margin-left: 10px;
  44. }
  45. .ant-modal-wrap .yincang .ant-modal-content .ant-modal-footer {
  46. display: none !important;
  47. }
  48. .yincang .ant-col-6 p {
  49. text-align: left;
  50. color: red;
  51. font-size: 16px;
  52. font-weight: 500;
  53. }
  54. .ant-table-thead div {
  55. font-weight: 700;
  56. }
  57. .tool-tip {
  58. position: absolute;
  59. top: 65px;
  60. right: 10px;
  61. }
  62. th div {
  63. white-space: nowrap;
  64. }
  65. </style>
  66. <template>
  67. <div class="data-statistics">
  68. <a-row class="image-list-heading vm-panel">
  69. <a-row type="flex" align="middle" justify="space-between" class="panel-body">
  70. <div class="search-bar" style="width:100%">
  71. <span>账户选择:</span>
  72. <treeselect :appId.sync="appId" />
  73. <span style="margin-left:10px">返点比例:</span>
  74. <a-input-number
  75. :min="1"
  76. :max="10"
  77. :step="0.1"
  78. v-model="discount"
  79. placeholder="请输入折扣"
  80. style="width:100px"
  81. />
  82. <a-button type="primary" style="margin:10px" @click="addUser">搜索</a-button>
  83. <a-button
  84. type="primary"
  85. icon="reload"
  86. @click="getDataReset"
  87. style="background-color:#67c23a;border-color:#67c23a"
  88. >刷新</a-button
  89. >
  90. <a-button type="primary" @click="getDataResetAll" style="color:white;margin-left:10px">重置</a-button>
  91. </div>
  92. </a-row>
  93. <a-row>
  94. <a-col :span="24">
  95. <a-card :bordered="false" class="search-box">
  96. <time-check
  97. @getAdd="getAdd"
  98. :startValue.sync="startValue"
  99. ref="timeCheck"
  100. ></time-check>
  101. </a-card>
  102. </a-col>
  103. </a-row>
  104. </a-row>
  105. <a-row :gutter="16" v-if="kuaishou">
  106. <a-col :sm="24" :md="12" :xl="12" :xxl="5">
  107. <lifting
  108. :kuaishou.sync="kuaishou"
  109. :active.sync="active"
  110. title="总消耗"
  111. typeName="cost"
  112. typeThan="costProportion"
  113. ></lifting>
  114. </a-col>
  115. <a-col :sm="24" :md="12" :xl="12" :xxl="5">
  116. <lifting
  117. :kuaishou.sync="kuaishou"
  118. :active.sync="active"
  119. title="折后消耗"
  120. typeName="discountCost"
  121. typeThan="discountCostProportion"
  122. ></lifting>
  123. </a-col>
  124. <a-col :sm="24" :md="12" :xl="12" :xxl="5">
  125. <lifting
  126. :kuaishou.sync="kuaishou"
  127. :active.sync="active"
  128. title="封面点击数"
  129. typeName="photoClick"
  130. typeThan="photoClickProportion"
  131. ></lifting>
  132. </a-col>
  133. <a-col :sm="24" :md="12" :xl="12" :xxl="5">
  134. <lifting
  135. :kuaishou.sync="kuaishou"
  136. :active.sync="active"
  137. title="封面曝光数"
  138. typeName="photoShow"
  139. typeThan="showProportion"
  140. ></lifting>
  141. </a-col>
  142. <a-col :sm="24" :md="12" :xl="12" :xxl="4">
  143. <lifting
  144. :kuaishou.sync="kuaishou"
  145. :active.sync="active"
  146. title="素材曝光数"
  147. typeName="aclick"
  148. typeThan="aClickProportion"
  149. ></lifting>
  150. </a-col>
  151. </a-row>
  152. <a-row :gutter="10">
  153. <a-col :span="24">
  154. <a-card
  155. style="width:100%"
  156. :tabList="tabListNoTitle"
  157. :activeTabKey="noTitleKey"
  158. @tabChange="key => onTabChange(key, 'noTitleKey')"
  159. >
  160. <div id="chart" style="width:100%;height:500px"></div>
  161. </a-card>
  162. </a-col>
  163. </a-row>
  164. <a-row :gutter="10" style="margin-top:10px">
  165. <a-col :span="24">
  166. <a-card style="width:100%;">
  167. <div
  168. style="display:flex;margin-bottom:15px"
  169. v-show="
  170. role.roleCode == 'operator' ||
  171. role.roleCode == 'kuaishouOperationManager' ||
  172. role.roleCode == 'admin' ||
  173. role.roleCode == 'operationAssistant' ||
  174. role.roleCode == 'touTiaoOperationManager'
  175. "
  176. >
  177. <a-select
  178. style="width: 120px"
  179. v-model="statHour"
  180. @change="getElseData"
  181. allowClear
  182. v-if="active == 1 || active == 2"
  183. >
  184. <a-select-option v-for="item of 24" :key="item - 1" :value="item - 1">{{ item - 1 }}</a-select-option>
  185. </a-select>
  186. <a-button type="primary" @click="exportExcel" style="margin-left:15px">导出</a-button>
  187. </div>
  188. <a-table
  189. :columns="columns"
  190. :dataSource="data"
  191. bordered
  192. id="outTable"
  193. :pagination="false"
  194. :scroll="{ x: 1900 }"
  195. ></a-table>
  196. </a-card>
  197. </a-col>
  198. </a-row>
  199. </div>
  200. </template>
  201. <script>
  202. import ARow from 'ant-design-vue/es/grid/Row'
  203. import ACol from 'ant-design-vue/es/grid/Col'
  204. import countTo from 'vue-count-to'
  205. import moment from 'moment'
  206. import { getAdvertiserList, getReportList, getStatistics } from '@api/statistics'
  207. import axios from 'axios'
  208. import lifting from './components/lifting'
  209. import timeCheck from './components/timeCheck'
  210. import Treeselect from './components/Treeselect.vue'
  211. import { getAction, postAction, postFile } from '@/api/manage'
  212. import { mapGetters } from 'vuex'
  213. // 引入基本模板
  214. let echarts = require('echarts/lib/echarts')
  215. // 引入柱状图组件
  216. require('echarts/lib/chart/bar')
  217. require('echarts/lib/chart/pie')
  218. require('echarts/lib/chart/line')
  219. // 引入提示框和title组件
  220. require('echarts/lib/component/tooltip')
  221. require('echarts/lib/component/title')
  222. require('echarts/lib/component/graphic')
  223. require('echarts/lib/component/toolbox')
  224. require('echarts/lib/component/legend')
  225. var length = 0
  226. var active = 1
  227. const columns = [
  228. {
  229. title: '时间',
  230. dataIndex: 'date',
  231. align: 'center',
  232. width: 150,
  233. customRender: function(text, record, index) {
  234. const obj = {
  235. children: text,
  236. attrs: {}
  237. }
  238. for (let i = 0; i < length; i++) {
  239. if (index == 0 && i == 0) {
  240. obj.attrs.rowSpan = length
  241. } else {
  242. if (index == i) {
  243. obj.attrs.rowSpan = 0
  244. }
  245. }
  246. }
  247. return obj
  248. }
  249. },
  250. {
  251. title: '账户Id',
  252. dataIndex: 'accountId',
  253. align: 'center',
  254. width: 150,
  255. customRender: function(text, record, index) {
  256. const obj = {
  257. children: text,
  258. attrs: {}
  259. }
  260. if (active == 1) {
  261. for (let i = 0; i < length; i++) {
  262. if (index >= length - 3) {
  263. obj.attrs.colSpan = 2
  264. }
  265. }
  266. } else {
  267. for (let i = 0; i < length; i++) {
  268. if (index >= length - 1) {
  269. obj.attrs.colSpan = 2
  270. }
  271. }
  272. }
  273. return obj
  274. }
  275. },
  276. {
  277. title: '账户昵称',
  278. dataIndex: 'accountName',
  279. scopedSlots: { customRender: 'cost' },
  280. align: 'center',
  281. width: 150,
  282. customRender: function(text, record, index) {
  283. const obj = {
  284. children: text,
  285. attrs: {}
  286. }
  287. if (active == 1) {
  288. for (let i = 0; i < length; i++) {
  289. if (index >= length - 3) {
  290. obj.attrs.colSpan = 0
  291. }
  292. }
  293. } else {
  294. for (let i = 0; i < length; i++) {
  295. if (index >= length - 1) {
  296. obj.attrs.colSpan = 0
  297. }
  298. }
  299. }
  300. return obj
  301. }
  302. },
  303. {
  304. title: '消耗(¥)',
  305. dataIndex: 'cost',
  306. scopedSlots: { customRender: 'cost' },
  307. align: 'center'
  308. },
  309. {
  310. title: '折后消耗(¥)',
  311. dataIndex: 'costY',
  312. align: 'center'
  313. },
  314. {
  315. title: '次留数',
  316. dataIndex: 'eventNextDayStay',
  317. scopedSlots: { customRender: 'eventNextDayStay' },
  318. align: 'center'
  319. },
  320. {
  321. title: '次留率',
  322. dataIndex: 'eventNextDayStayRatio',
  323. align: 'center'
  324. },
  325. {
  326. title: '封面展示',
  327. dataIndex: 'photoShow',
  328. align: 'center'
  329. },
  330. {
  331. title: '封面点击',
  332. dataIndex: 'photoClick',
  333. align: 'center'
  334. },
  335. {
  336. title: '素材曝光数',
  337. dataIndex: 'aclick',
  338. align: 'center'
  339. },
  340. {
  341. title: '封面点击率',
  342. dataIndex: 'photoClickRatio',
  343. align: 'center'
  344. },
  345. {
  346. title: 'cvr',
  347. dataIndex: 'cvr',
  348. align: 'center'
  349. },
  350. {
  351. title: 'cpm(¥)',
  352. dataIndex: 'cpm',
  353. align: 'center'
  354. },
  355. {
  356. title: '行为数',
  357. dataIndex: 'bClick',
  358. align: 'center'
  359. },
  360. {
  361. title: '转化数',
  362. dataIndex: 'formCount',
  363. align: 'center'
  364. },
  365. {
  366. title: '折前转化单价(¥)',
  367. dataIndex: 'beforeFormPrice',
  368. align: 'center'
  369. },
  370. {
  371. title: '折后转化单价(¥)',
  372. dataIndex: 'afterFormPrice',
  373. align: 'center'
  374. },
  375. {
  376. title: '注册数',
  377. dataIndex: 'eventRegister',
  378. align: 'center'
  379. },
  380. {
  381. title: '注册成本(¥)',
  382. dataIndex: 'eventRegisterCost',
  383. align: 'center'
  384. },
  385. {
  386. title: '单价区间',
  387. dataIndex: 'price',
  388. align: 'center',
  389. customRender: function(text, record, index) {
  390. const obj = {
  391. children: text,
  392. attrs: {}
  393. }
  394. for (let i = 0; i < length; i++) {
  395. if (index == 0 && i == 0) {
  396. obj.attrs.rowSpan = length
  397. } else {
  398. if (index == i) {
  399. obj.attrs.rowSpan = 0
  400. }
  401. }
  402. }
  403. return obj
  404. }
  405. }
  406. ]
  407. const columnsWu = [
  408. {
  409. title: '时间',
  410. dataIndex: 'date',
  411. align: 'center',
  412. width: 150,
  413. customRender: function(text, record, index) {
  414. const obj = {
  415. children: text,
  416. attrs: {}
  417. }
  418. for (let i = 0; i < length; i++) {
  419. if (index == 0 && i == 0) {
  420. obj.attrs.rowSpan = length
  421. } else {
  422. if (index == i) {
  423. obj.attrs.rowSpan = 0
  424. }
  425. }
  426. }
  427. return obj
  428. }
  429. },
  430. {
  431. title: '账户Id',
  432. dataIndex: 'accountId',
  433. align: 'center',
  434. width: 150,
  435. customRender: function(text, record, index) {
  436. const obj = {
  437. children: text,
  438. attrs: {}
  439. }
  440. if (active == 1) {
  441. for (let i = 0; i < length; i++) {
  442. if (index >= length - 3) {
  443. obj.attrs.colSpan = 2
  444. }
  445. }
  446. } else {
  447. for (let i = 0; i < length; i++) {
  448. if (index >= length - 1) {
  449. obj.attrs.colSpan = 2
  450. }
  451. }
  452. }
  453. return obj
  454. }
  455. },
  456. {
  457. title: '账户昵称',
  458. dataIndex: 'accountName',
  459. scopedSlots: { customRender: 'cost' },
  460. align: 'center',
  461. width: 150,
  462. customRender: function(text, record, index) {
  463. const obj = {
  464. children: text,
  465. attrs: {}
  466. }
  467. if (active == 1) {
  468. for (let i = 0; i < length; i++) {
  469. if (index >= length - 3) {
  470. obj.attrs.colSpan = 0
  471. }
  472. }
  473. } else {
  474. for (let i = 0; i < length; i++) {
  475. if (index >= length - 1) {
  476. obj.attrs.colSpan = 0
  477. }
  478. }
  479. }
  480. return obj
  481. }
  482. },
  483. {
  484. title: '消耗(¥)',
  485. dataIndex: 'cost',
  486. scopedSlots: { customRender: 'cost' },
  487. align: 'center'
  488. },
  489. {
  490. title: '折后消耗(¥)',
  491. dataIndex: 'costY',
  492. align: 'center'
  493. },
  494. {
  495. title: '封面展示',
  496. dataIndex: 'photoShow',
  497. align: 'center'
  498. },
  499. {
  500. title: '封面点击',
  501. dataIndex: 'photoClick',
  502. align: 'center'
  503. },
  504. {
  505. title: '素材曝光数',
  506. dataIndex: 'aclick',
  507. align: 'center'
  508. },
  509. {
  510. title: '封面点击率',
  511. dataIndex: 'photoClickRatio',
  512. align: 'center'
  513. },
  514. {
  515. title: 'cvr',
  516. dataIndex: 'cvr',
  517. align: 'center'
  518. },
  519. {
  520. title: 'cpm(¥)',
  521. dataIndex: 'cpm',
  522. align: 'center'
  523. },
  524. {
  525. title: '行为数',
  526. dataIndex: 'bClick',
  527. align: 'center'
  528. },
  529. {
  530. title: '转化数',
  531. dataIndex: 'formCount',
  532. align: 'center'
  533. },
  534. {
  535. title: '折前转化单价(¥)',
  536. dataIndex: 'beforeFormPrice',
  537. align: 'center'
  538. },
  539. {
  540. title: '折后转化单价(¥)',
  541. dataIndex: 'afterFormPrice',
  542. align: 'center'
  543. },
  544. {
  545. title: '注册数',
  546. dataIndex: 'eventRegister',
  547. align: 'center'
  548. },
  549. {
  550. title: '注册成本(¥)',
  551. dataIndex: 'eventRegisterCost',
  552. align: 'center'
  553. },
  554. {
  555. title: '单价区间',
  556. dataIndex: 'price',
  557. align: 'center',
  558. customRender: function(text, record, index) {
  559. const obj = {
  560. children: text,
  561. attrs: {}
  562. }
  563. for (let i = 0; i < length; i++) {
  564. if (index == 0 && i == 0) {
  565. obj.attrs.rowSpan = length
  566. } else {
  567. if (index == i) {
  568. obj.attrs.rowSpan = 0
  569. }
  570. }
  571. }
  572. return obj
  573. }
  574. }
  575. ]
  576. export default {
  577. name: 'data-display-statistics',
  578. components: {
  579. ACol,
  580. ARow,
  581. countTo,
  582. lifting,
  583. timeCheck,
  584. Treeselect
  585. },
  586. data: function() {
  587. return {
  588. title: '账户数据展示',
  589. show: true,
  590. data: [],
  591. columns:columnsWu,
  592. options: [],
  593. list: [],
  594. appId: [],
  595. statHour: null,
  596. keyValue: null,
  597. keyValueData: [],
  598. active: 1,
  599. startValue: [],
  600. allValue: [],
  601. discount: 1,
  602. duration: 1000,
  603. kuaishou: {
  604. aclick: 0,
  605. aClickProportion: 0,
  606. cost: 0,
  607. costProportion: 0,
  608. photoClick: 0,
  609. photoClickroportion: 0,
  610. photoShow: 0,
  611. showProportion: 0,
  612. discountCost: 0,
  613. discountCostProportion: 0
  614. },
  615. timeList: [
  616. // { label: '今天', value: 1, show: true },
  617. { label: '昨天', value: 2, show: true },
  618. { label: '近一周', value: 3, show: true },
  619. { label: '近十五天', value: 4, show: true },
  620. { label: '近一月', value: 5, show: true },
  621. { label: '近三月', value: 6, show: true },
  622. { label: '近半年', value: 7, show: true },
  623. { label: '所有', value: 8, show: true }
  624. ],
  625. dataDetail: [],
  626. tabListNoTitle: [
  627. {
  628. key: 'cost',
  629. tab: '总消耗'
  630. },
  631. {
  632. key: 'discountCost',
  633. tab: '折后总消耗'
  634. },
  635. {
  636. key: 'photoClick',
  637. tab: '封面点击数'
  638. },
  639. {
  640. key: 'photoShow',
  641. tab: '封面曝光数'
  642. },
  643. {
  644. key: 'aclick',
  645. tab: '素材曝光数'
  646. }
  647. ],
  648. noTitleKey: 'cost',
  649. role: { roleCode: '' },
  650. statDate: ''
  651. }
  652. },
  653. filters: {
  654. formatDate: function(value) {
  655. let date = new Date(value)
  656. let y = date.getFullYear()
  657. let MM = date.getMonth() + 1
  658. MM = MM < 10 ? '0' + MM : MM
  659. let d = date.getDate()
  660. d = d < 10 ? '0' + d : d
  661. let h = date.getHours()
  662. h = h < 10 ? '0' + h : h
  663. let m = date.getMinutes()
  664. m = m < 10 ? '0' + m : m
  665. let s = date.getSeconds()
  666. s = s < 10 ? '0' + s : s
  667. return y + '-' + MM + '-' + d + ' ' + h + ':' + m + ':' + s
  668. }
  669. },
  670. methods: {
  671. moment,
  672. ...mapGetters(['nickname', 'avatar', 'userInfo']),
  673. disabledDate(current) {
  674. return current && current > moment().endOf('day')
  675. },
  676. handleChange(value) {
  677. console.log(value)
  678. // this.appId = value
  679. },
  680. getElseData(value) {
  681. if(value){
  682. this.columns = columnsWu
  683. }else{
  684. this.columns = columns
  685. }
  686. this.getStatistics()
  687. },
  688. handleBlur() {
  689. console.log('blur')
  690. },
  691. handleFocus() {
  692. console.log('focus')
  693. if (this.appId.length > 0) {
  694. this.options = []
  695. for (let i = 0; i < this.list.length; i++) {
  696. for (let j = 0; j < this.appId.length; j++) {
  697. if (this.list[i].accountId == this.appId[j]) {
  698. this.options.push(this.list[i])
  699. }
  700. }
  701. }
  702. } else {
  703. this.options = this.list
  704. }
  705. },
  706. search(value) {
  707. // console.log(value)
  708. this.options = []
  709. if (value != '') {
  710. this.options = this.list.filter(item => {
  711. var data = item.accountId + ' ' + item.authName + ' ' + item.advertiserName + ' ' + item.operationName
  712. return data.toLowerCase().indexOf(value.toLowerCase()) > -1
  713. })
  714. this.options = [...this.options]
  715. console.log(this.options)
  716. } else {
  717. if (this.appId.length > 0) {
  718. this.options = []
  719. for (let i = 0; i < this.list.length; i++) {
  720. for (let j = 0; j < this.appId.length; j++) {
  721. if (this.list[i].accountId == this.appId[j]) {
  722. this.options.push(this.list[i])
  723. }
  724. }
  725. }
  726. } else {
  727. this.options = this.list
  728. }
  729. }
  730. },
  731. getDataReset() {
  732. this.active = 1
  733. this.allValue = []
  734. this.$refs.timeCheck.active = 1
  735. this.addUser()
  736. },
  737. getDataResetAll() {
  738. this.active = 1
  739. this.allValue = []
  740. this.$refs.timeCheck.active = 1
  741. var that = this
  742. that.kuaishou.aclick = 0
  743. that.kuaishou.cost = 0
  744. that.kuaishou.photoClick = 0
  745. that.kuaishou.photoShow = 0
  746. that.kuaishou.discountCost = 0
  747. this.data = []
  748. this.appId = []
  749. this.drawPie(1, [])
  750. },
  751. addUser() {
  752. var that = this
  753. if (this.appId.length > 0) {
  754. if(that.active == 1){
  755. that.columns = columnsWu
  756. }else{
  757. that.columns = columns
  758. }
  759. var params = {}
  760. params.accountIds = JSON.stringify(that.appId)
  761. params.type = that.active
  762. params.discount = that.discount
  763. if (that.active == 9) {
  764. params.startDate = this.allValue[0]
  765. params.endDate = this.allValue[1]
  766. }
  767. getReportList(params).then(res => {
  768. if (res.success) {
  769. if (res.result) {
  770. that.kuaishou = res.result.summary
  771. that.dataDetail = res.result.trend
  772. that.drawPie(that.noTitleKey, res.result.trend)
  773. } else {
  774. that.kuaishou.aclick = 0
  775. that.kuaishou.cost = 0
  776. that.kuaishou.photoClick = 0
  777. that.kuaishou.photoShow = 0
  778. that.kuaishou.discountCost = 0
  779. }
  780. }
  781. })
  782. that.getStatistics()
  783. } else {
  784. this.$message.error('请选择账户')
  785. }
  786. },
  787. getStatistics() {
  788. var params = {}
  789. params.accountIds = JSON.stringify(this.appId)
  790. params.type = this.active
  791. params.statHour = this.statHour
  792. params.discount = this.discount
  793. if (this.active == 9) {
  794. params.startDate = this.allValue[0]
  795. params.endDate = this.allValue[1]
  796. }
  797. this.data = []
  798. getStatistics(params).then(res => {
  799. console.log(res)
  800. if (res.success) {
  801. if (res.result.accountDetail) {
  802. this.statDate = res.result.statDate
  803. this.data = res.result.accountDetail.map((item, index) => {
  804. return {
  805. key: index,
  806. ...item,
  807. photoClickRatio: item.photoClickRatio ? (item.photoClickRatio * 100).toFixed(2) + '%' : 0 + '%',
  808. cpm: item.cpm ? item.cpm.toFixed(2) : 0,
  809. cost: item.cost.toFixed(2),
  810. cvr: item.cvr ? (item.cvr * 100).toFixed(2) + '%' : 0 + '%',
  811. costY: (item.cost / this.discount).toFixed(2),
  812. beforeFormPrice: item.formPrice
  813. ? item.formPrice.toFixed(2)
  814. : item.activationPrice
  815. ? item.activationPrice.toFixed(2)
  816. : 0,
  817. afterFormPrice: item.formPrice
  818. ? (item.formPrice / this.discount).toFixed(2)
  819. : item.activationPrice
  820. ? (item.activationPrice / this.discount).toFixed(2)
  821. : 0,
  822. date: this.statHour ? res.result.statDate + ' ' + this.statHour : res.result.statDate,
  823. formCount: item.formCount > 0 ? item.formCount : item.activationCount,
  824. eventRegister: item.eventRegister,
  825. eventRegisterCost: item.eventRegisterCost.toFixed(2),
  826. eventNextDayStayRatio:item.eventNextDayStayRatio?(item.eventNextDayStayRatio*100).toFixed(2) + '%' : 0 + '%'
  827. }
  828. })
  829. var index = this.data.length
  830. if (this.active == 1) {
  831. var allNow = {
  832. key: index + 1,
  833. ...res.result.now,
  834. photoClickRatio: res.result.now.photoClickRatio
  835. ? (res.result.now.photoClickRatio * 100).toFixed(2) + '%'
  836. : 0 + '%',
  837. cpm: res.result.now.cpm ? res.result.now.cpm.toFixed(2) : 0,
  838. cost: res.result.now.cost.toFixed(2),
  839. cvr: res.result.now.cvr ? (res.result.now.cvr * 100).toFixed(2) + '%' : 0 + '%',
  840. costY: (res.result.now.cost / this.discount).toFixed(2),
  841. accountId: '总计',
  842. beforeFormPrice: res.result.now.formPrice
  843. ? res.result.now.formPrice.toFixed(2)
  844. : res.result.now.activationPrice
  845. ? res.result.now.activationPrice.toFixed(2)
  846. : 0,
  847. afterFormPrice: res.result.now.formPrice
  848. ? (res.result.now.formPrice / this.discount).toFixed(2)
  849. : res.result.now.activationPrice
  850. ? (res.result.now.activationPrice / this.discount).toFixed(2)
  851. : 0,
  852. formCount: res.result.now.conversionNum,
  853. eventRegister: res.result.now.eventRegister,
  854. eventRegisterCost: res.result.now.eventRegisterCost.toFixed(2)
  855. }
  856. var allYesterday = {
  857. key: index + 2,
  858. ...res.result.yesterday,
  859. photoClickRatio: res.result.yesterday.photoClickRatio
  860. ? (res.result.yesterday.photoClickRatio * 100).toFixed(2) + '%'
  861. : 0 + '%',
  862. cpm: res.result.yesterday.cpm ? res.result.yesterday.cpm.toFixed(2) : 0,
  863. cost: res.result.yesterday.cost.toFixed(2),
  864. cvr: res.result.yesterday.cvr ? (res.result.yesterday.cvr * 100).toFixed(2) + '%' : 0 + '%',
  865. costY: (res.result.yesterday.cost / this.discount).toFixed(2),
  866. accountId: '昨日总计',
  867. beforeFormPrice: res.result.yesterday.formPrice
  868. ? res.result.yesterday.formPrice.toFixed(2)
  869. : res.result.yesterday.activationPrice
  870. ? res.result.yesterday.activationPrice.toFixed(2)
  871. : 0,
  872. afterFormPrice: res.result.yesterday.formPrice
  873. ? (res.result.yesterday.formPrice / this.discount).toFixed(2)
  874. : res.result.yesterday.activationPrice
  875. ? (res.result.yesterday.activationPrice / this.discount).toFixed(2)
  876. : 0,
  877. formCount:res.result.yesterday.conversionNum,
  878. eventRegister: res.result.yesterday.eventRegister,
  879. eventRegisterCost: res.result.yesterday.eventRegisterCost.toFixed(2)
  880. }
  881. var chainRatio = {
  882. key: index + 3,
  883. cost: (res.result.chainRatio.costProportion * 100).toFixed(2) + '%',
  884. photoShow: (res.result.chainRatio.showProportion * 100).toFixed(2) + '%',
  885. photoClick: (res.result.chainRatio.photoClickProportion * 100).toFixed(2) + '%',
  886. aclick: (res.result.chainRatio.aClickProportion * 100).toFixed(2) + '%',
  887. photoClickRatio: res.result.chainRatio.photoClickRatioProportion
  888. ? (res.result.chainRatio.photoClickRatioProportion * 100).toFixed(2) + '%'
  889. : 0.0 + '%',
  890. cvr: (res.result.chainRatio.cvrProportion * 100).toFixed(2) + '%',
  891. cpm: (res.result.chainRatio.cpmProportion * 100).toFixed(2) + '%',
  892. bClick: (res.result.chainRatio.bClickProportion * 100).toFixed(2) + '%',
  893. formCount: (res.result.chainRatio.nowConversionNumProportion* 100).toFixed(2) + '%',
  894. beforeFormPrice: (res.result.chainRatio.beforeConversionPriceProportion*100).toFixed(2) + '%',
  895. afterFormPrice: (res.result.chainRatio.afterConversionPriceProportion*100).toFixed(2) + '%',
  896. costY: (res.result.chainRatio.costProportion * 100).toFixed(2) + '%',
  897. eventRegister: (res.result.chainRatio.eventRegisterProportion * 100).toFixed(2) + '%',
  898. eventRegisterCost: (res.result.chainRatio.eventRegisterCostProportion * 100).toFixed(2) + '%',
  899. accountId: '环比'
  900. }
  901. this.data.push(allNow)
  902. this.data.push(allYesterday)
  903. this.data.push(chainRatio)
  904. } else {
  905. var allNow = {
  906. key: index + 1,
  907. ...res.result.ratioJson,
  908. photoClickRatio: res.result.ratioJson.photoClickRatio
  909. ? (res.result.ratioJson.photoClickRatio * 100).toFixed(2) + '%'
  910. : 0 + '%',
  911. cpm: res.result.ratioJson.cpm ? res.result.ratioJson.cpm.toFixed(2) : 0,
  912. cost: res.result.ratioJson.cost?res.result.ratioJson.cost.toFixed(2):0,
  913. cvr: res.result.ratioJson.cvr ? (res.result.ratioJson.cvr * 100).toFixed(2) + '%' : 0 + '%',
  914. costY: (res.result.ratioJson.cost / this.discount).toFixed(2),
  915. accountId: '总计',
  916. beforeFormPrice: res.result.ratioJson.formPrice
  917. ? res.result.ratioJson.formPrice.toFixed(2)
  918. : res.result.ratioJson.activationPrice
  919. ? res.result.ratioJson.activationPrice.toFixed(2)
  920. : 0,
  921. afterFormPrice: res.result.ratioJson.formPrice
  922. ? (res.result.ratioJson.formPrice / this.discount).toFixed(2)
  923. : res.result.ratioJson.activationPrice
  924. ? (res.result.ratioJson.activationPrice / this.discount).toFixed(2)
  925. : 0,
  926. formCount: res.result.ratioJson.conversions,
  927. beforeFormPrice: res.result.ratioJson.conversionPrice.toFixed(2),
  928. afterFormPrice: res.result.ratioJson.discountConversionPrice.toFixed(2),
  929. eventRegister: res.result.ratioJson.eventRegister,
  930. eventRegisterCost: res.result.ratioJson.eventRegisterCost.toFixed(2),
  931. eventNextDayStayRatio:res.result.ratioJson.eventNextDayStayRatio?(res.result.ratioJson.eventNextDayStayRatio*100).toFixed(2) + '%' : 0 + '%'
  932. }
  933. this.data.push(allNow)
  934. this.statDate = res.result.statDate
  935. }
  936. length = this.data.length
  937. } else {
  938. this.$message.error('暂无数据')
  939. }
  940. }
  941. })
  942. },
  943. getAdd(checked) {
  944. if (checked == 9) {
  945. if (this.startValue.length > 0 && this.startValue[0]) {
  946. this.allValue[1] = moment(this.startValue[0]._d).format('YYYY-MM-DD')
  947. this.allValue[0] = moment(this.startValue[1]._d).format('YYYY-MM-DD')
  948. }
  949. } else {
  950. this.startValue = []
  951. this.allValue = []
  952. }
  953. this.active = checked
  954. active = checked
  955. if(this.active == 1){
  956. this.columns = columnsWu
  957. }else{
  958. this.columns = columns
  959. }
  960. this.addUser(checked)
  961. },
  962. onTabChange(key, type) {
  963. console.log(key, type)
  964. this[type] = key
  965. if (type == 'noTitleKey') {
  966. this.drawPie(key, this.dataDetail)
  967. }
  968. },
  969. drawPie(type, data) {
  970. console.log(type)
  971. var dataLegend = []
  972. var dataLength = []
  973. var dataElse = []
  974. var dataDate = []
  975. var that = this
  976. if (this.active == 1 || this.active == 2) {
  977. dataDate = data.map(item => {
  978. return item.statHour
  979. })
  980. } else {
  981. dataDate = data.map(item => {
  982. return item.statDate
  983. })
  984. }
  985. dataLength = data.map(item => {
  986. return item[type]
  987. })
  988. if (type == 'cost') {
  989. dataLegend = ['总消耗']
  990. dataElse = data.map(item => {
  991. if (item.now) {
  992. return { proportion: (item.now.costProportion * 100).toFixed(2) + '%', statHour: item.statHour }
  993. } else {
  994. return { proportion: 0, statHour: item.statHour }
  995. }
  996. })
  997. } else if (type == 'photoClick') {
  998. dataLegend = ['封面点击数']
  999. dataElse = data.map(item => {
  1000. if (item.now) {
  1001. return { proportion: (item.now.photoClickProportion * 100).toFixed(2) + '%', statHour: item.statHour }
  1002. } else {
  1003. return { proportion: 0, statHour: item.statHour }
  1004. }
  1005. })
  1006. } else if (type == 'photoShow') {
  1007. dataLegend = ['封面曝光数']
  1008. dataElse = data.map(item => {
  1009. if (item.now) {
  1010. return { proportion: (item.now.showProportion * 100).toFixed(2) + '%', statHour: item.statHour }
  1011. } else {
  1012. return { proportion: 0, statHour: item.statHour }
  1013. }
  1014. })
  1015. } else if (type == 'aclick') {
  1016. dataLegend = ['素材曝光数']
  1017. dataElse = data.map(item => {
  1018. if (item.now) {
  1019. return { proportion: (item.now.aClickProportion * 100).toFixed(2) + '%', statHour: item.statHour }
  1020. } else {
  1021. return { proportion: 0, statHour: item.statHour }
  1022. }
  1023. })
  1024. } else if (type == 'discountCost') {
  1025. dataLegend = ['折后总消耗']
  1026. dataElse = data.map(item => {
  1027. if (item.now) {
  1028. return { proportion: (item.now.discountCostProportion * 100).toFixed(2) + '%', statHour: item.statHour }
  1029. } else {
  1030. return { proportion: 0, statHour: item.statHour }
  1031. }
  1032. })
  1033. dataLength = data.map(item => {
  1034. return (item.cost / this.discount).toFixed(2)
  1035. })
  1036. }
  1037. console.log(dataLength, 134123)
  1038. var series
  1039. if (this.active == 1) {
  1040. dataLegend = ['今天', '昨天']
  1041. series = [
  1042. {
  1043. name: dataLegend[0],
  1044. type: 'line',
  1045. color: '#9933ff',
  1046. smooth: true,
  1047. symbol: 'circle',
  1048. symbolSize: 1,
  1049. lineStyle: {
  1050. normal: {
  1051. width: 2,
  1052. color: '#9933ff'
  1053. }
  1054. },
  1055. itemStyle: {
  1056. borderColor: '#ffffff',
  1057. borderWidth: 3
  1058. },
  1059. data: data.map(item => {
  1060. if (item.now) {
  1061. return item.now[type]
  1062. } else {
  1063. return 0
  1064. }
  1065. })
  1066. },
  1067. {
  1068. name: dataLegend[1],
  1069. type: 'line',
  1070. color: '#0bcd74',
  1071. smooth: true,
  1072. symbol: 'circle',
  1073. symbolSize: 1,
  1074. lineStyle: {
  1075. normal: {
  1076. width: 2,
  1077. color: '#0bcd74'
  1078. }
  1079. },
  1080. itemStyle: {
  1081. borderColor: '#ffffff',
  1082. borderWidth: 3
  1083. },
  1084. data: dataLength
  1085. }
  1086. ]
  1087. } else {
  1088. series = [
  1089. {
  1090. name: dataLegend[0],
  1091. type: 'line',
  1092. color: '#0bcd74',
  1093. smooth: true,
  1094. symbol: 'circle',
  1095. symbolSize: 1,
  1096. lineStyle: {
  1097. normal: {
  1098. width: 2,
  1099. color: '#0bcd74'
  1100. }
  1101. },
  1102. itemStyle: {
  1103. borderColor: '#ffffff',
  1104. borderWidth: 3
  1105. },
  1106. data: dataLength
  1107. }
  1108. ]
  1109. }
  1110. var option = {
  1111. backgroundColor: '#fff',
  1112. toolbox: {
  1113. show: true,
  1114. feature: {
  1115. dataView: { readOnly: false }
  1116. }
  1117. },
  1118. tooltip: {
  1119. trigger: 'axis',
  1120. formatter: function(params) {
  1121. var index = dataElse.findIndex(v => v.statHour == params[0].name)
  1122. var da = null
  1123. if (index >= 0) {
  1124. da = dataElse[index].proportion
  1125. }
  1126. if (that.active == 1) {
  1127. if (params.length > 1) {
  1128. return `${params[0].marker}今天${params[0].name}时:${params[0].data} <br/>
  1129. ${params[1].marker}昨天${params[1].name}时:${params[1].data} <br/>
  1130. 环比:${da} <br/> `
  1131. } else {
  1132. return `${params[0].marker}时间:${params[0].name} <br/>
  1133. 数值:${params[0].data} `
  1134. }
  1135. } else {
  1136. return `${params[0].marker}时间:${params[0].name} <br/>
  1137. 数值:${params[0].data} `
  1138. }
  1139. }
  1140. },
  1141. legend: {
  1142. data: dataLegend
  1143. },
  1144. grid: {
  1145. left: '2%',
  1146. right: '2%',
  1147. bottom: '2%',
  1148. containLabel: true
  1149. },
  1150. xAxis: {
  1151. type: 'category',
  1152. data: dataDate,
  1153. boundaryGap: false,
  1154. // 坐标轴线
  1155. axisLine: {
  1156. show: false,
  1157. lineStyle: {
  1158. color: '#999'
  1159. }
  1160. },
  1161. // 分割线
  1162. splitLine: {
  1163. show: true,
  1164. lineStyle: {
  1165. type: 'dashed',
  1166. color: '#e5e5e5'
  1167. }
  1168. }
  1169. },
  1170. yAxis: {
  1171. type: 'value',
  1172. axisLine: {
  1173. show: false,
  1174. lineStyle: {
  1175. color: '#999'
  1176. }
  1177. },
  1178. splitLine: {
  1179. lineStyle: {
  1180. type: 'dashed',
  1181. color: '#e5e5e5'
  1182. }
  1183. }
  1184. },
  1185. series: series
  1186. }
  1187. var chart = echarts.init(document.getElementById('chart'))
  1188. chart.clear()
  1189. chart.setOption(option, true)
  1190. window.onresize = function() {
  1191. chart.resize()
  1192. }
  1193. },
  1194. getDate() {
  1195. let date = new Date()
  1196. let y = date.getFullYear()
  1197. let MM = date.getMonth() + 1
  1198. MM = MM < 10 ? '0' + MM : MM
  1199. let d = date.getDate()
  1200. d = d < 10 ? '0' + d : d
  1201. let h = date.getHours() - 1
  1202. h = h < 10 ? '0' + h : h
  1203. if (this.active == 1) {
  1204. if (this.statHour) {
  1205. return y + '-' + MM + '-' + d
  1206. } else {
  1207. return y + '-' + MM + '-' + d + ' ' + h
  1208. }
  1209. } else {
  1210. return y + '-' + MM + '-' + (d - 1)
  1211. }
  1212. },
  1213. exportExcel() {
  1214. var title = ''
  1215. if (this.active == 1) {
  1216. if (this.statHour) {
  1217. title = this.getDate() + ' ' + this.statHour + '时数据报表'
  1218. } else {
  1219. title = this.getDate() + '时数据报表'
  1220. }
  1221. } else if (this.active == 2) {
  1222. title = this.getDate() + '数据报表'
  1223. } else {
  1224. title = this.statDate + '数据报表'
  1225. }
  1226. const borderAll = {
  1227. //单元格外侧框线
  1228. top: {
  1229. style: 'thin'
  1230. },
  1231. bottom: {
  1232. style: 'thin'
  1233. },
  1234. left: {
  1235. style: 'thin'
  1236. },
  1237. right: {
  1238. style: 'thin'
  1239. }
  1240. }
  1241. // var opt = {
  1242. // rowIndex: 4
  1243. // } //开头空4行
  1244. var sheet = XLSX2.utils.table_to_sheet(document.getElementById('outTable'))
  1245. var sheetName = ['D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O']
  1246. // sheet['A2'].s = {
  1247. // alignment: {
  1248. // horizontal: 'center',
  1249. // vertical: 'center'
  1250. // }
  1251. // // fill: {
  1252. // // fgColor: {rgb: "008000"},
  1253. // // },
  1254. // }
  1255. // for (let i = 0; i < 3; i++) {
  1256. // sheet['B' + (length + 1 - i)].s = {
  1257. // alignment: {
  1258. // horizontal: 'center',
  1259. // vertical: 'center'
  1260. // }
  1261. // }
  1262. // }
  1263. // for (let i = 0; i < sheetName.length; i++) {
  1264. // for (let j = 2; j < length + 2; j++) {
  1265. // console.log(sheetName[i] + j + '')
  1266. // var a = sheetName[i] + j + ''
  1267. // console.log(a)
  1268. // sheet[a].t = 'n'
  1269. // }
  1270. // }
  1271. for (var i in sheet) {
  1272. if (i == '!ref' || i == '!merges' || i == '!cols') {
  1273. } else {
  1274. sheet[i + ''].s = {
  1275. border: borderAll,
  1276. alignment: {
  1277. horizontal: 'center',
  1278. vertical: 'center'
  1279. }
  1280. // fill: {
  1281. // fgColor: { rgb: 'FFFF00' }
  1282. // }
  1283. }
  1284. sheet[i + ''].t = 'n'
  1285. }
  1286. }
  1287. //["!merges"]这个属性是专门用来进行单元格合并的
  1288. // sheet['!merges'].push({
  1289. // //如果不为空push 为空 = 赋值
  1290. // //合并单元格 index都从0开始
  1291. // s: {
  1292. // //s开始
  1293. // c: 0, //开始列
  1294. // r: 0 //开始行
  1295. // },
  1296. // e: {
  1297. // //e结束
  1298. // c: 12, //结束列
  1299. // r: 3 //结束行
  1300. // }
  1301. // })
  1302. sheet['!cols'] = [
  1303. {
  1304. wpx: 100
  1305. },
  1306. {
  1307. wpx: 100
  1308. },
  1309. {
  1310. wpx: 100
  1311. },
  1312. {
  1313. wpx: 100
  1314. },
  1315. {
  1316. wpx: 100
  1317. },
  1318. {
  1319. wpx: 100
  1320. },
  1321. {
  1322. wpx: 100
  1323. },
  1324. {
  1325. wpx: 100
  1326. },
  1327. {
  1328. wpx: 100
  1329. },
  1330. {
  1331. wpx: 100
  1332. },
  1333. {
  1334. wpx: 100
  1335. },
  1336. {
  1337. wpx: 100
  1338. },
  1339. {
  1340. wpx: 100
  1341. },
  1342. {
  1343. wpx: 100
  1344. },
  1345. {
  1346. wpx: 100
  1347. },
  1348. {
  1349. wpx: 100
  1350. }
  1351. ] //单元格列宽
  1352. openDownloadDialog(sheet2blob(sheet), title + '.xlsx')
  1353. }
  1354. },
  1355. watch: {},
  1356. distoryed() {},
  1357. mounted: function() {
  1358. this.$nextTick(() => {
  1359. getAction('/sys/user/getRoleInfo', { userId: this.userInfo().id }).then(res => {
  1360. this.role = res
  1361. })
  1362. })
  1363. }
  1364. }
  1365. </script>