dataDisplayStatistics.vue 40 KB

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