accountReport.vue 77 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714
  1. <style lang="less" scoped>
  2. @import 'kuaishouReport';
  3. ::v-deep.vue-treeselect__control {
  4. line-height: 20px !important;
  5. }
  6. </style>
  7. <template>
  8. <div class="account-report">
  9. <div class="directional-content">
  10. <div class="table-page-search-wrapper">
  11. <a-form layout="inline" :form="form" hide-required-mark :selfUpdate="true" @submit="handleQueryList">
  12. <a-row :gutter="24">
  13. <a-col :md="16" :sm="16" :xxl="16">
  14. <a-form-item label="账户名称">
  15. <selectTreeAccount
  16. v-decorator="['accountIds', { initialValue: [] }]"
  17. multiple
  18. style="width:100%"
  19. :reqUrl="reqUrl"
  20. :limit="1"
  21. />
  22. </a-form-item>
  23. </a-col>
  24. </a-row>
  25. <a-row :gutter="24">
  26. <!-- v-decorator="[
  27. 'dateValue',
  28. { initialValue: [moment().subtract(7, 'days'), moment().subtract(1, 'days')] }
  29. ]" -->
  30. <a-col :md="8" :sm="8" :xxl="6">
  31. <a-form-item label="时间选择">
  32. <a-range-picker
  33. v-model="dateValue"
  34. :ranges="dateRanges"
  35. :disabled-date="disabledDate"
  36. />
  37. </a-form-item>
  38. </a-col>
  39. <a-col :md="8" :sm="8" :xxl="6">
  40. <a-form-item label="返点比例">
  41. <a-input-number
  42. :min="0.1"
  43. :max="10"
  44. :step="0.1"
  45. v-decorator="['disscount', { initialValue: 1 }]"
  46. :disabled="rebatePropDisabled"
  47. @change="rebatePropChange"
  48. />
  49. </a-form-item>
  50. </a-col>
  51. <a-col :md="8" :sm="8" :xxl="12" style="display: flex;justify-content: flex-end;">
  52. <span style="float: left; overflow: hidden" class="table-page-search-submitButtons">
  53. <a-button type="primary" icon="search" @click="handleQueryList">查询</a-button>
  54. <!-- <a-button type="primary" @click="handleResetForm" icon="reload" class="middle-button"
  55. >重置</a-button
  56. > -->
  57. </span>
  58. </a-col>
  59. </a-row>
  60. </a-form>
  61. </div>
  62. </div>
  63. <div class="show">
  64. <div class="showBox">
  65. <div class="title">
  66. <div class="infotitle">总消耗</div>
  67. <a-tooltip v-if="dateValue[0].format('YYYY-MM-DD') == dateValue[1].format('YYYY-MM-DD')">
  68. <template slot="title">{{ dateValue[0].format('HH:00') }}点之前所有数据对比</template>
  69. <span class="icon">
  70. <a-icon type="exclamation-circle" />
  71. </span>
  72. </a-tooltip>
  73. </div>
  74. <div class="infoNum">
  75. <span class="red">{{ costLink.cost | decimalsHandle }}</span>
  76. <span class="green" v-if="dateValue[0].format('YYYY-MM-DD') == dateValue[1].format('YYYY-MM-DD')"
  77. ><span class="huanbi">环比: </span> {{ costLink.CostSumLink | toPercentage }}</span
  78. >
  79. </div>
  80. </div>
  81. <div class="showBox">
  82. <div class="title">
  83. <div class="infotitle">折后消耗</div>
  84. <a-tooltip v-if="dateValue[0].format('YYYY-MM-DD') == dateValue[1].format('YYYY-MM-DD')">
  85. <template slot="title">{{ dateValue[0].format('HH:00') }}点之前所有数据对比</template>
  86. <span class="icon">
  87. <a-icon type="exclamation-circle" />
  88. </span>
  89. </a-tooltip>
  90. </div>
  91. <div class="infoNum">
  92. <span class="red">{{ discountCostLink.discountCost | decimalsHandle }}</span>
  93. <span class="green" v-if="dateValue[0].format('YYYY-MM-DD') == dateValue[1].format('YYYY-MM-DD')"
  94. ><span class="huanbi">环比: </span> {{ discountCostLink.discountCostLink | toPercentage }}</span
  95. >
  96. </div>
  97. </div>
  98. <div class="showBox">
  99. <div class="title">
  100. <div class="infotitle">封面点击数</div>
  101. <a-tooltip v-if="dateValue[0].format('YYYY-MM-DD') == dateValue[1].format('YYYY-MM-DD')">
  102. <template slot="title">{{ dateValue[0].format('HH:00') }}点之前所有数据对比</template>
  103. <span class="icon">
  104. <a-icon type="exclamation-circle" />
  105. </span>
  106. </a-tooltip>
  107. </div>
  108. <div class="infoNum">
  109. <span class="red">{{ photoClickLink.photoClick | formatCurrency }}</span>
  110. <span class="green" v-if="dateValue[0].format('YYYY-MM-DD') == dateValue[1].format('YYYY-MM-DD')"
  111. ><span class="huanbi">环比: </span> {{ photoClickLink.photoClickLink | toPercentage }}</span
  112. >
  113. </div>
  114. </div>
  115. <div class="showBox">
  116. <div class="title">
  117. <div class="infotitle">封面曝光数</div>
  118. <a-tooltip v-if="dateValue[0].format('YYYY-MM-DD') == dateValue[1].format('YYYY-MM-DD')">
  119. <template slot="title">{{ dateValue[0].format('HH:00') }}点之前所有数据对比</template>
  120. <span class="icon">
  121. <a-icon type="exclamation-circle" />
  122. </span>
  123. </a-tooltip>
  124. </div>
  125. <div class="infoNum">
  126. <span class="red">{{ photoShowLink.photoShow | formatCurrency }}</span>
  127. <span class="green" v-if="dateValue[0].format('YYYY-MM-DD') == dateValue[1].format('YYYY-MM-DD')"
  128. ><span class="huanbi">环比: </span> {{ photoShowLink.photoShowLink | toPercentage }}</span
  129. >
  130. </div>
  131. </div>
  132. <div class="showBox">
  133. <div class="title">
  134. <div class="infotitle">素材曝光数</div>
  135. <a-tooltip v-if="dateValue[0].format('YYYY-MM-DD') == dateValue[1].format('YYYY-MM-DD')">
  136. <template slot="title">{{ dateValue[0].format('HH:00') }}点之前所有数据对比</template>
  137. <span class="icon">
  138. <a-icon type="exclamation-circle" />
  139. </span>
  140. </a-tooltip>
  141. </div>
  142. <div class="infoNum">
  143. <span class="red">{{ aClickLink.aClick | formatCurrency }}</span>
  144. <span class="green" v-if="dateValue[0].format('YYYY-MM-DD') == dateValue[1].format('YYYY-MM-DD')"
  145. ><span class="huanbi">环比: </span> {{ aClickLink.aClickLink | toPercentage }}</span
  146. >
  147. </div>
  148. </div>
  149. </div>
  150. <div class="chartBox">
  151. <a-tabs default-active-key="cost" @change="callback">
  152. <a-tab-pane key="cost" tab="总消耗"> </a-tab-pane>
  153. <a-tab-pane key="discountCost" tab="折后消耗"> </a-tab-pane>
  154. <a-tab-pane key="photoClick" tab="封面点击数"> </a-tab-pane>
  155. <a-tab-pane key="photoShow" tab="封面曝光数"> </a-tab-pane>
  156. <a-tab-pane key="zhuanhua" tab="素材曝光数"> </a-tab-pane>
  157. </a-tabs>
  158. <div id="sectionChart" style="width:100%;height:300px" ref="sectionChart"></div>
  159. <!-- <div id="noData" v-else style='width:100%;height:300px'>暂无数据</div> -->
  160. </div>
  161. <div class="tableBox">
  162. <div class="tableTop">
  163. <a-tooltip>
  164. <template slot="title">
  165. 日期选择具体某一天之后,这里可以查看具体的时间段数据哦~
  166. </template>
  167. <!-- v-show="dateValue[0].format('YYYY-MM-DD')==dateValue[1].format('YYYY-MM-DD')" -->
  168. <a-select
  169. placeholder="请选择具体时间段"
  170. style="width: 160px"
  171. @change="timeChange"
  172. v-model="timeDefaultValue"
  173. label-in-value
  174. class="selectTime"
  175. v-show="dateValue[1].format('YYYY-MM-DD') == moment().format('YYYY-MM-DD')"
  176. >
  177. <a-select-option v-for="(i, index) in 24" :key="index" :value="index">{{
  178. index >= 10 ? `00:00-${index}:59` : `00:00-0${index}:59`
  179. }}</a-select-option>
  180. </a-select>
  181. </a-tooltip>
  182. <a-button
  183. type="primary"
  184. class="export"
  185. @click="exportExcel"
  186. :disabled="!!!getFormData('accountIds') || getFormData('accountIds').length == 0"
  187. >导出报表</a-button
  188. >
  189. <a-button type="primary" class="add" @click="customColumns">自定义列</a-button>
  190. </div>
  191. <a-table
  192. size="middle"
  193. :columns="columns"
  194. :dataSource="tableData"
  195. bordered
  196. id="outTable"
  197. :pagination="false"
  198. :scroll="{ x: scrollX }"
  199. :loading="dataLoading"
  200. ref="accountTable"
  201. :width="tableWidth"
  202. @change="sort"
  203. style="word-break: break-all;font-size:16px;font-weight:600"
  204. >
  205. <span slot="statDate" slot-scope="text, records">
  206. {{
  207. text
  208. ? text == '总计'
  209. ? text
  210. : ('' + text).substr(0, 4) +
  211. '-' +
  212. ('' + text).substr(4, 2) +
  213. '-' +
  214. ('' + text).substr(6, 2)
  215. : '-'
  216. }}
  217. </span>
  218. <span slot="ctr" slot-scope="ctr">{{ ctr | toPercentage }}</span>
  219. <span slot="cost" slot-scope="cost">{{ cost | decimalsHandle }}</span>
  220. <span slot="clickMaterial" slot-scope="clickMaterial">{{ clickMaterial | formatCurrency }}</span>
  221. <span slot="showMaterial" slot-scope="showMaterial">{{ showMaterial | formatCurrency }}</span>
  222. <span slot="convertMaterial" slot-scope="convertMaterial">{{ convertMaterial | formatCurrency }}</span>
  223. <span slot="play25FeedBreak" slot-scope="play25FeedBreak">{{ play25FeedBreak | formatCurrency }}</span>
  224. <span slot="play50FeedBreak" slot-scope="play50FeedBreak">{{ play50FeedBreak | formatCurrency }}</span>
  225. <span slot="play75FeedBreak" slot-scope="play75FeedBreak">{{ play75FeedBreak | formatCurrency }}</span>
  226. <span slot="play100FeedBreak" slot-scope="play100FeedBreak">{{
  227. play100FeedBreak | formatCurrency
  228. }}</span>
  229. <span slot="nextDayOpen" slot-scope="nextDayOpen">{{ nextDayOpen | formatCurrency }}</span>
  230. <span slot="downloadFinish" slot-scope="downloadFinish">{{ downloadFinish | formatCurrency }}</span>
  231. <span slot="downloadStart" slot-scope="downloadStart">{{ downloadStart | formatCurrency }}</span>
  232. <span slot="likeMaterial" slot-scope="likeMaterial">{{ likeMaterial | formatCurrency }}</span>
  233. <span slot="shareMaterial" slot-scope="shareMaterial">{{ shareMaterial | formatCurrency }}</span>
  234. <span slot="register" slot-scope="register">{{ register | formatCurrency }}</span>
  235. <span slot="follow" slot-scope="follow">{{ follow | formatCurrency }}</span>
  236. <span slot="formCount" slot-scope="formCount">{{ formCount | formatCurrency }}</span>
  237. <span slot="formCountCost" slot-scope="formCountCost">{{ formCountCost | decimalsHandle }}</span>
  238. <span slot="aClick" slot-scope="aClick">{{ aClick | formatCurrency }}</span>
  239. <span slot="photoShow" slot-scope="photoShow">{{ photoShow | formatCurrency }}</span>
  240. <span slot="photoClick" slot-scope="photoClick">{{ photoClick | formatCurrency }}</span>
  241. <span slot="bClick" slot-scope="bClick">{{ bClick | formatCurrency }}</span>
  242. <span slot="active" slot-scope="active">{{ active | formatCurrency }}</span>
  243. <span slot="submit" slot-scope="submit">{{ submit | formatCurrency }}</span>
  244. <span slot="nextDayOpen" slot-scope="nextDayOpen">{{ nextDayOpen | formatCurrency }}</span>
  245. <span slot="eventCreditGrantLandingPage" slot-scope="eventCreditGrantLandingPage">{{
  246. eventCreditGrantLandingPage | formatCurrency
  247. }}</span>
  248. <span slot="submitCost" slot-scope="submitCost">{{ submitCost | decimalsHandle }}</span>
  249. <span slot="eventCreditGrantLandingPageCost" slot-scope="eventCreditGrantLandingPageCost">{{
  250. eventCreditGrantLandingPageCost | decimalsHandle
  251. }}</span>
  252. <span slot="submitRate" slot-scope="submitRate">{{ submitRate | toPercentage }}</span>
  253. <span slot="eventCreditGrantLandingPageRate" slot-scope="eventCreditGrantLandingPageRate">{{
  254. eventCreditGrantLandingPageRate | toPercentage
  255. }}</span>
  256. <span slot="play25FeedBreakRate" slot-scope="play25FeedBreakRate">{{
  257. play25FeedBreakRate | toPercentage
  258. }}</span>
  259. <span slot="playOverRate" slot-scope="playOverRate">{{ playOverRate | toPercentage }}</span>
  260. <!-- 新加数据 -->
  261. <span slot="clickRate" slot-scope="clickRate">{{ clickRate | toPercentage }}</span>
  262. <span slot="bClickRate" slot-scope="bClickRate">{{ bClickRate | toPercentage }}</span>
  263. <span slot="convertRate" slot-scope="convertRate">{{ convertRate | toPercentage }}</span>
  264. <span slot="nextDayOpenRate" slot-scope="nextDayOpenRate">{{ nextDayOpenRate | toPercentage }}</span>
  265. <span slot="ctr" slot-scope="ctr">{{ ctr | toPercentage }}</span>
  266. <span slot="cpc" slot-scope="cpc">{{ cpc | decimalsHandle }}</span>
  267. <span slot="cpm" slot-scope="cpm">{{ cpm | decimalsHandle }}</span>
  268. <span slot="installFinishRate" slot-scope="installFinishRate">{{
  269. installFinishRate | toPercentage
  270. }}</span>
  271. <span slot="validPlayRate" slot-scope="validPlayRate">{{ validPlayRate | toPercentage }}</span>
  272. <span slot="activePayCost" slot-scope="activePayCost">{{ activePayCost | decimalsHandle }}</span>
  273. <span slot="nextDayOpenCost" slot-scope="nextDayOpenCost">{{ nextDayOpenCost | decimalsHandle }}</span>
  274. <span slot="validPlayCost" slot-scope="validPlayCost">{{ validPlayCost | decimalsHandle }}</span>
  275. <span slot="activeCost" slot-scope="activeCost">{{ activeCost | decimalsHandle }}</span>
  276. <span slot="nextDayOpenCost" slot-scope="nextDayOpenCost">{{ nextDayOpenCost | decimalsHandle }}</span>
  277. <span slot="gameAddictionCost" slot-scope="gameAddictionCost">{{
  278. gameAddictionCost | decimalsHandle
  279. }}</span>
  280. <span slot="downloadFinishCost" slot-scope="downloadFinishCost">{{
  281. downloadFinishCost | decimalsHandle
  282. }}</span>
  283. <span slot="downloadStartCost" slot-scope="downloadStartCost">{{
  284. downloadStartCost | decimalsHandle
  285. }}</span>
  286. <span slot="installFinishCost" slot-scope="installFinishCost">{{
  287. installFinishCost | decimalsHandle
  288. }}</span>
  289. <span slot="convertCost" slot-scope="convertCost">{{ convertCost | decimalsHandle }}</span>
  290. <!-- -->
  291. <span slot="downloadStartRate" slot-scope="downloadStartRate">{{
  292. downloadStartRate | toPercentage
  293. }}</span>
  294. <span slot="downloadFinishRate" slot-scope="downloadFinishRate">{{
  295. downloadFinishRate | toPercentage
  296. }}</span>
  297. <span slot="activeRate" slot-scope="activeRate">{{ activeRate | toPercentage }}</span>
  298. <span slot="activeRegisterRate" slot-scope="activeRegisterRate">{{
  299. activeRegisterRate | toPercentage
  300. }}</span>
  301. <span slot="gameAddictionRate" slot-scope="gameAddictionRate">{{
  302. gameAddictionRate | toPercentage
  303. }}</span>
  304. <span slot="nextDayOpenRate" slot-scope="nextDayOpenRate">{{ nextDayOpenRate | toPercentage }}</span>
  305. <span slot="eventCreditGrantAppRate" slot-scope="eventCreditGrantAppRate">{{
  306. eventCreditGrantAppRate | toPercentage
  307. }}</span>
  308. <span slot="play3sRate" slot-scope="play3sRate">{{ play3sRate | toPercentage }}</span>
  309. <span slot="formCountRate" slot-scope="formCountRate">{{ formCountRate | toPercentage }}</span>
  310. <!-- <span slot="nextDayOpenRate" slot-scope="nextDayOpenRate">{{ nextDayOpenRate | toPercentage }}</span> -->
  311. </a-table>
  312. </div>
  313. <customColumn
  314. :visible="visible"
  315. :listNum="listNum"
  316. :fiexColumn="columnsFixd"
  317. :mediaType="2"
  318. @closeCustomColumn="closeCustomColumn"
  319. @changeColumn="changeColumn"
  320. />
  321. </div>
  322. </template>
  323. <script>
  324. import moment from 'moment'
  325. import { mapGetters } from 'vuex'
  326. import { getAction, postAction, downFile, downFilePost } from '@/api/manage'
  327. import { TreeSelect } from 'ant-design-vue'
  328. const SHOW_PARENT = TreeSelect.SHOW_PARENT
  329. // const SHOW_PARENT = TreeSelect.SHOW_ALL;
  330. import DatePicker from '@/components/DatePicker.vue'
  331. import customColumn from '../components/customColumn.vue'
  332. import selectTreeAccount from '@/components/formComponents/selectAccount.vue'
  333. // 引入基本模板
  334. var echarts = require('echarts')
  335. // 引入柱状图组件
  336. require('echarts/lib/chart/bar')
  337. require('echarts/lib/chart/pie')
  338. require('echarts/lib/chart/line')
  339. // 引入提示框和title组件
  340. require('echarts/lib/component/tooltip')
  341. require('echarts/lib/component/title')
  342. require('echarts/lib/component/graphic')
  343. require('echarts/lib/component/toolbox')
  344. require('echarts/lib/component/legend')
  345. let sectionOption = {
  346. tooltip: {
  347. trigger: 'axis',
  348. axisPointer: {
  349. // 坐标轴指示器,坐标轴触发有效
  350. type: 'line' // 默认为直线,可选为:'line' | 'shadow',
  351. }
  352. },
  353. legend: {
  354. data: []
  355. },
  356. grid: {
  357. left: '2%',
  358. right: '2%',
  359. bottom: '0%',
  360. top: '12%',
  361. containLabel: true
  362. },
  363. xAxis: [
  364. {
  365. type: 'category',
  366. data: [],
  367. axisTick: {
  368. alignWithLabel: true
  369. }
  370. }
  371. ],
  372. yAxis: [
  373. {
  374. type: 'value',
  375. show: true
  376. }
  377. ],
  378. series: [
  379. {
  380. name: '',
  381. type: 'line',
  382. smooth: true,
  383. data: [],
  384. color: '#32CD32'
  385. },
  386. {
  387. name: '',
  388. type: 'line',
  389. smooth: true,
  390. data: [],
  391. color: '#8A2BE2'
  392. },
  393. {
  394. name: '环比',
  395. type: 'line',
  396. smooth: true,
  397. data: [],
  398. color: 'rgba(0,0,0,0)'
  399. }
  400. ]
  401. }
  402. let length = 0
  403. const columnsFixd = [
  404. {
  405. title: '时间',
  406. dataIndex: 'statDate',
  407. scopedSlots: { customRender: 'statDate' },
  408. align: 'center',
  409. key: 'statDate',
  410. width: 200,
  411. fixed: 'left'
  412. },
  413. {
  414. title: '账户ID',
  415. dataIndex: 'accountId',
  416. align: 'center',
  417. width: 200,
  418. fixed: 'left',
  419. scopedSlots: { customRender: 'accountId' }
  420. },
  421. {
  422. title: '账户昵称',
  423. dataIndex: 'authName',
  424. align: 'center',
  425. width: 200,
  426. fixed: 'left'
  427. }
  428. ]
  429. const initVariableColimns = [
  430. {
  431. title: '消耗(元)',
  432. dataIndex: 'cost',
  433. width: 150,
  434. tip: '广告在投放期间的花费总额',
  435. align: 'center',
  436. scopedSlots: { customRender: 'cost' },
  437. sorter: () => {}
  438. },
  439. // {
  440. // title: '折后消耗(元)',
  441. // dataIndex: 'discountCost',
  442. // width:150,
  443. // tip: '广告在投放期间的花费总额',
  444. // align: 'center',
  445. // scopedSlots: { customRender: 'discountCost' },
  446. // sorter: () => {}
  447. // },
  448. {
  449. title: '封面曝光数',
  450. dataIndex: 'photoShow',
  451. tip: '广告在瀑布流被观看次数',
  452. align: 'center',
  453. scopedSlots: { customRender: 'photoShow' },
  454. sorter: () => {}
  455. },
  456. {
  457. title: '封面点击数',
  458. dataIndex: 'photoClick',
  459. tip: '用户点击封面进入视频播放页的次数(数据会进行反作弊去重)',
  460. align: 'center',
  461. scopedSlots: { customRender: 'photoClick' },
  462. sorter: () => {}
  463. },
  464. {
  465. title: '封面点击率',
  466. dataIndex: 'clickRate',
  467. tip: '封面点击数占封面展示数百分比',
  468. align: 'center',
  469. scopedSlots: { customRender: 'clickRate' },
  470. sorter: () => {}
  471. },
  472. {
  473. title: '素材曝光数',
  474. dataIndex: 'aClick',
  475. tip: '用户进入视频播放页观看的次数(数据会进行反作弊去重)',
  476. align: 'center',
  477. scopedSlots: { customRender: 'aClick' },
  478. sorter: () => {}
  479. },
  480. {
  481. title: '行为数',
  482. dataIndex: 'bClick',
  483. tip: '用户在视频播放页单击转化按钮的次数/展示数*100%',
  484. align: 'center',
  485. scopedSlots: { customRender: 'bClick' },
  486. sorter: () => {}
  487. },
  488. {
  489. title: '行为率',
  490. dataIndex: 'bClickRate',
  491. tip: '行为数占素材曝光数百分比',
  492. align: 'center',
  493. scopedSlots: { customRender: 'bClickRate' },
  494. sorter: () => {}
  495. },
  496. {
  497. title: '平均千次封面曝光花费(元)',
  498. dataIndex: 'cpm',
  499. tip: '花费/封面曝光数*1000',
  500. align: 'center',
  501. scopedSlots: { customRender: 'cpm' },
  502. sorter: () => {}
  503. },
  504. {
  505. title: '平均封面点击单价(元)',
  506. dataIndex: 'cpc',
  507. tip: '花费/封面点击数',
  508. align: 'center',
  509. scopedSlots: { customRender: 'cpc' },
  510. sorter: () => {}
  511. },
  512. {
  513. title: '平均行为单价(元)',
  514. dataIndex: 'cpb',
  515. tip: '总花费/行为数',
  516. align: 'center',
  517. scopedSlots: { customRender: 'cpb' },
  518. sorter: () => {}
  519. }
  520. ]
  521. let initDay = {
  522. x: [],
  523. today: {
  524. y: [],
  525. name: '今天'
  526. },
  527. yesterday: {
  528. y: [],
  529. name: '昨天'
  530. },
  531. huanbi: {
  532. name: '环比',
  533. y: []
  534. }
  535. }
  536. export default {
  537. components: {
  538. DatePicker,
  539. customColumn,
  540. selectTreeAccount
  541. },
  542. data() {
  543. return {
  544. moment,
  545. //账户的数据
  546. accountId: [],
  547. mediaId: '', //媒体类型
  548. //折扣数值
  549. discountSelect: 1.0,
  550. discountDisabled: false,
  551. //返点比例
  552. rebateProp: 1.0,
  553. rebatePropDisabled: false,
  554. discount: 1,
  555. left: 0,
  556. //treeselect的参数
  557. treeValue: [],
  558. treeData: [],
  559. SHOW_PARENT,
  560. //top区域数据
  561. discountCostLink: {},
  562. photoShowLink: {},
  563. photoClickLink: {},
  564. costLink: {},
  565. aClickLink: {},
  566. //日期矿打开
  567. openOptions: false,
  568. //子元素的数据存储
  569. type: 1, //这个没用但是不能删 请求类型
  570. dateValue: [moment().subtract(7, 'days'), moment().subtract(1, 'days')],
  571. //处理按钮禁用
  572. searchDisabled: false,
  573. refreshDisabled: false,
  574. resetDisabled: false,
  575. //echart区域的tab
  576. tabKey: 'cost',
  577. sectionOption: JSON.parse(JSON.stringify(sectionOption)),
  578. tabCost: {},
  579. tabPhotoClick: {}, //封面点击数
  580. tabPhotoShow: {},
  581. tabDiscountCost: {},
  582. tabAClick: {},
  583. //table的数据
  584. timeSelectValue: 23, //table上选择时间
  585. timeValueString: '',
  586. timeDefaultValue: undefined,
  587. visible: false, //自定义页面的打开
  588. columns: [...columnsFixd, ...initVariableColimns], //table的表头
  589. columnsFixd,
  590. tableData: [],
  591. scrollX: 1000,
  592. tableWidth: '', //设置表格的列宽
  593. loading: false,
  594. target: 'cost', //默认消耗排序
  595. order: 'desc', //默认降序
  596. listNum: [],
  597. myChart: {},
  598. chartData: [],
  599. form: this.$form.createForm(this),
  600. reqUrl: process.env.VUE_APP_BASE_REPORT_URL + '/account/report/getProjectAccountByUserId',
  601. accountListUrl: process.env.VUE_APP_BASE_REPORT_URL + '/account/report/kuaishou/list',
  602. charUrl: process.env.VUE_APP_BASE_REPORT_URL + '/account/report/kuaishou/chart',
  603. dataLoading: false,
  604. dateRanges: {
  605. 昨天: [moment().subtract(1, 'days'), moment().subtract(1, 'days')],
  606. 近三天: [moment().subtract(3, 'days'), moment().subtract(1, 'days')],
  607. 近一周: [moment().subtract(7, 'days'), moment().subtract(1, 'days')],
  608. 近14天: [moment().subtract(14, 'days'), moment().subtract(1, 'days')],
  609. 近一月: [moment().subtract(1, 'months'), moment().subtract(1, 'days')],
  610. 近半年: [moment().subtract(6, 'months'), moment().subtract(1, 'days')],
  611. 近一年: [moment().subtract(12, 'months'), moment().subtract(1, 'days')]
  612. }
  613. }
  614. },
  615. watch: {
  616. type(n, o) {},
  617. dateValue(newName, oldName) {
  618. // console.log(newName,oldName)
  619. this.timeValueString = undefined
  620. this.timeSelectValue = 23
  621. this.timeDefaultValue = ''
  622. if (
  623. newName[0].format('YYYY-MM-DD') == oldName[0].format('YYYY-MM-DD') ||
  624. newName[0].format('YYYY-MM-DD') == moment().format('YYYY-MM-DD')
  625. ) {
  626. } else {
  627. this.handleQueryList()
  628. }
  629. }
  630. },
  631. methods: {
  632. ...mapGetters(['userInfo']),
  633. //table选择时间函数
  634. timeChange(value) {
  635. this.timeSelectValue = value.key
  636. this.timeValueString = value.label
  637. this.handleQueryList()
  638. },
  639. handleQueryList() {
  640. // this.ipagination.current = 1
  641. // event.preventDefault()
  642. const paramsData = this.form.getFieldsValue()
  643. console.log(paramsData)
  644. this.handleGetTableList(paramsData)
  645. },
  646. handleResetForm() {
  647. // this.ipagination.current = 1
  648. this.form.resetFields()
  649. this.handleGetTableList({})
  650. },
  651. handleGetTableList(data) {
  652. if (data.accountIds && data.accountIds.length > 0) {
  653. const paramsData = {
  654. ...data,
  655. startDate: this.dateValue.length === 2 ? moment(this.dateValue[0]).format('YYYY-MM-DD') : null,
  656. endDate: this.dateValue.length === 2 ? moment(this.dateValue[1]).format('YYYY-MM-DD') : null,
  657. userId: this.userInfo().id,
  658. hour: this.timeSelectValue,
  659. target: this.target, //默认消耗排序
  660. order: this.order //默认降序
  661. // pageNo: this.ipagination.current,
  662. // pageSize: this.ipagination.pageSize
  663. }
  664. this.tableData = []
  665. this.dataLoading = true
  666. postAction(this.accountListUrl, paramsData)
  667. .then(res => {
  668. this.dataLoading = false
  669. if (res.success) {
  670. this.tableData = res.result
  671. // this.ipagination.total = result.result.total || 0
  672. if (this.dateValue[0].format('YYYY-MM-DD') == this.dateValue[1].format('YYYY-MM-DD')) {
  673. for (let i = res.result.length - 1; i > res.result.length - 4; i--) {
  674. res.result[i].authName = '-'
  675. res.result[i].accountId = '-'
  676. res.result[i].statDate = '总计'
  677. }
  678. for (let key in res.result[res.result.length - 1]) {
  679. if (res.result[res.result.length - 1][key] < 1) {
  680. res.result[res.result.length - 1][key] =
  681. (res.result[res.result.length - 1][key] * 100).toFixed(2) + '%'
  682. }
  683. }
  684. res.result[res.result.length - 1].statDate = '环比'
  685. res.result[res.result.length - 2].statDate = '昨日总计(相对)'
  686. this.tableData = res.result
  687. length = this.tableData.length - 3
  688. } else {
  689. res.result[res.result.length - 1].statDate = '总计'
  690. res.result[res.result.length - 1].authName = '-'
  691. res.result[res.result.length - 1].accountId = '-'
  692. this.tableData = res.result
  693. length = this.tableData.length - 1
  694. }
  695. } else {
  696. this.$message.error(res.message)
  697. }
  698. })
  699. .catch(error => {
  700. this.dataLoading = false
  701. console.log(error, 'eeee')
  702. })
  703. postAction(this.charUrl, { ...paramsData, mediaId: 2 }).then(res => {
  704. if (res.success) {
  705. if (res.result.sumData.discountCostLink) {
  706. this.discountCostLink = res.result.sumData.discountCostLink
  707. this.photoShowLink = res.result.sumData.photoShowLink
  708. this.photoClickLink = res.result.sumData.photoClickLink
  709. this.costLink = res.result.sumData.costLink
  710. this.aClickLink = res.result.sumData.aClickLink
  711. }
  712. this.tabCost = JSON.parse(JSON.stringify(initDay))
  713. this.tabPhotoClick = JSON.parse(JSON.stringify(initDay))
  714. this.tabPhotoShow = JSON.parse(JSON.stringify(initDay))
  715. this.tabDiscountCost = JSON.parse(JSON.stringify(initDay))
  716. this.tabAClick = JSON.parse(JSON.stringify(initDay))
  717. let chartData = res.result.chartData
  718. chartData.map((item, index) => {
  719. if (item.statHour || item.statHour == 0) {
  720. //说明是查询 天 数据;
  721. // console.log('day')
  722. item.statHour = item.statHour >= 10 ? `${item.statHour}:00` : `0${item.statHour}:00`
  723. if (this.dateValue[0].format('YYYY-MM-DD') == moment().format('YYYY-MM-DD')) {
  724. //说明是今天
  725. this.tabPhotoClick.yesterday.y.push(item.photoClick)
  726. this.tabCost.yesterday.y.push(item.cost)
  727. this.tabPhotoShow.yesterday.y.push(item.photoShow)
  728. this.tabDiscountCost.yesterday.y.push(item.discountCost)
  729. this.tabAClick.yesterday.y.push(item.aClick)
  730. this.tabPhotoClick.x.push(item.statHour)
  731. this.tabCost.x.push(item.statHour)
  732. this.tabPhotoShow.x.push(item.statHour)
  733. this.tabDiscountCost.x.push(item.statHour)
  734. this.tabAClick.x.push(item.statHour)
  735. if (item.afterData) {
  736. this.tabPhotoClick.today.y.push(item.afterData.photoClick)
  737. this.tabCost.today.y.push(item.afterData.cost)
  738. this.tabPhotoShow.today.y.push(item.afterData.photoShow)
  739. this.tabDiscountCost.today.y.push(item.afterData.discountCost)
  740. this.tabAClick.today.y.push(item.afterData.aClick)
  741. //环比
  742. this.tabPhotoClick.huanbi.y.push(item.afterData.photoClickProportion)
  743. // console.log((item.afterData.photoClickProportion*100).toFixed(2)+'%')
  744. this.tabCost.huanbi.y.push(item.afterData.costProportion)
  745. this.tabPhotoShow.huanbi.y.push(item.afterData.photoShowProportion)
  746. this.tabDiscountCost.huanbi.y.push(item.afterData.costProportion)
  747. this.tabAClick.huanbi.y.push(item.afterData.aClickProportion)
  748. } else {
  749. this.tabPhotoClick.today.y.push(0)
  750. this.tabCost.today.y.push(0)
  751. this.tabPhotoShow.today.y.push(0)
  752. this.tabDiscountCost.today.y.push(0)
  753. this.tabAClick.today.y.push(0)
  754. this.tabPhotoClick.huanbi.y.push(0)
  755. this.tabCost.huanbi.y.push(0)
  756. this.tabPhotoShow.huanbi.y.push(0)
  757. this.tabDiscountCost.huanbi.y.push(0)
  758. this.tabAClick.huanbi.y.push(0)
  759. }
  760. } else {
  761. if (item.afterData) {
  762. this.tabPhotoClick.yesterday.y.push(item.afterData.photoClick)
  763. this.tabCost.yesterday.y.push(item.afterData.cost)
  764. this.tabPhotoShow.yesterday.y.push(item.afterData.photoShow)
  765. this.tabDiscountCost.yesterday.y.push(item.afterData.discountCost)
  766. this.tabAClick.yesterday.y.push(item.afterData.aClick)
  767. this.tabPhotoClick.x.push(item.afterData.statHour)
  768. this.tabCost.x.push(item.afterData.statHour)
  769. this.tabPhotoShow.x.push(item.afterData.statHour)
  770. this.tabDiscountCost.x.push(item.afterData.statHour)
  771. this.tabAClick.x.push(item.afterData.statHour)
  772. }
  773. }
  774. } else if (item.statDate) {
  775. // console.log('date')
  776. this.tabPhotoClick.yesterday.y.push(item.photoClick)
  777. this.tabCost.yesterday.y.push(item.cost)
  778. this.tabPhotoShow.yesterday.y.push(item.photoShow)
  779. this.tabDiscountCost.yesterday.y.push(item.discountCost)
  780. this.tabAClick.yesterday.y.push(item.aClick)
  781. let data =
  782. ('' + item.statDate).substr(0, 4) +
  783. '-' +
  784. ('' + item.statDate).substr(4, 2) +
  785. '-' +
  786. ('' + item.statDate).substr(6, 2)
  787. this.tabPhotoClick.x.push(data)
  788. this.tabCost.x.push(data)
  789. this.tabPhotoShow.x.push(data)
  790. this.tabDiscountCost.x.push(data)
  791. this.tabAClick.x.push(data)
  792. }
  793. })
  794. this.callback(this.tabKey)
  795. }
  796. })
  797. } else {
  798. this.$message.error('请选择账户')
  799. }
  800. },
  801. treeSearch() {
  802. console.log(arguments)
  803. },
  804. treeSelect() {
  805. // console.log(arguments);
  806. // this.treeValue=arguments[0].value
  807. },
  808. //项目改变后的事件
  809. treeChange(val) {
  810. // console.log(this.treeData)
  811. console.log(val)
  812. this.accountId = []
  813. //选择一个后禁用其他
  814. if (val.length == 1) {
  815. if (val[0] * 1) {
  816. let selectindex = 0
  817. this.treeData.forEach((ele, index) => {
  818. if (ele.children) {
  819. ele.children.map((item, ind) => {
  820. if (item.value == val[0]) {
  821. selectindex = index
  822. this.mediaId = ele.mediaId
  823. }
  824. })
  825. }
  826. })
  827. // console.log(selectindex)
  828. if (selectindex || selectindex == 0) {
  829. this.treeData.forEach((ele, index) => {
  830. if (index != selectindex) {
  831. ele.disableCheckbox = true
  832. if (ele.children) {
  833. ele.children.map((item, ind) => {
  834. item.disableCheckbox = true
  835. })
  836. }
  837. }
  838. })
  839. }
  840. } else {
  841. // console.log(1)
  842. this.treeData.forEach((ele, index) => {
  843. if (ele.value != val[0]) {
  844. ele.disableCheckbox = true
  845. if (ele.children) {
  846. ele.children.forEach((item, ind) => {
  847. item.disableCheckbox = true
  848. })
  849. }
  850. }
  851. if (ele.value == val[0]) {
  852. this.mediaId = ele.mediaId
  853. }
  854. })
  855. }
  856. // console.log(this.mediaId)
  857. // if(this.mediaId=='2'){
  858. // this.discountDisabled=true;
  859. // this.rebatePropDisabled=false;
  860. // this.discount=this.rebateProp;
  861. // }else{
  862. // this.rebatePropDisabled=true;
  863. // this.discountDisabled=false;
  864. // this.discount=this.discountSelect;
  865. // }
  866. }
  867. if (val.length == 0) {
  868. this.treeData.forEach((ele, index) => {
  869. ele.disableCheckbox = false
  870. this.mediaId = ele.mediaId
  871. if (ele.children) {
  872. ele.children.forEach((item, ind) => {
  873. item.disableCheckbox = false
  874. })
  875. }
  876. })
  877. this.rebatePropDisabled = false
  878. this.discountDisabled = false
  879. this.discount = 1.0
  880. }
  881. if (val) {
  882. val.forEach((ele, index) => {
  883. if (ele * 1) {
  884. this.accountId.push(ele)
  885. } else {
  886. let projectArr = this.treeData.filter(item => {
  887. return item.value == ele
  888. })
  889. // console.log(projectArr)
  890. projectArr[0].children.forEach(element => {
  891. this.accountId.push(element.value)
  892. })
  893. }
  894. })
  895. }
  896. console.log(this.accountId)
  897. },
  898. disabledDate(current) {
  899. // console.log(current)
  900. return current && current > moment().subtract(1, 'day')
  901. },
  902. filterOption(input, option) {
  903. console.log(input, option)
  904. return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
  905. },
  906. //查询按钮的事件
  907. searchgetData() {
  908. this.myChart.clear()
  909. if (this.accountId.length > 0) {
  910. // console.log();
  911. this.loading = true
  912. this.searchDisabled = true
  913. this.discountCostLink = {}
  914. this.photoShowLink = {}
  915. this.photoClickLink = {}
  916. this.costLink = {}
  917. this.aClickLink = {}
  918. this.tabCost = {}
  919. this.tabPhotoClick = {}
  920. ;(this.tabPhotoShow = {}), (this.tabDiscountCost = {})
  921. this.tabAClick = {}
  922. this.chartHttp({
  923. mediaId: this.mediaId,
  924. discount: this.discount,
  925. accountIds: this.accountId,
  926. startDate: this.dateValue[0].format('YYYY-MM-DD'),
  927. endDate: this.dateValue[1].format('YYYY-MM-DD')
  928. })
  929. if (
  930. this.accountId.length == 1 &&
  931. this.dateValue[0].format('YYYY.MM.DD') != this.dateValue[1].format('YYYY.MM.DD')
  932. ) {
  933. ;(this.target = 'statDate'), (this.order = 'asc')
  934. } else {
  935. ;(this.target = 'cost'), (this.order = 'desc')
  936. }
  937. this.tableHttp()
  938. } else {
  939. this.$message.error('请选择账户后再查询!')
  940. }
  941. },
  942. //重置
  943. resetgetData() {
  944. this.loading = false
  945. // this.resetDisabled=true;
  946. this.searchDisabled = false
  947. this.refreshDisabled = false
  948. this.treeValue = []
  949. // this.treeData=[];
  950. this.discountSelect = 1.0
  951. this.discountDisabled = false
  952. this.rebatePropDisabled = false
  953. this.rebateProp = 1.0
  954. this.treeChange([])
  955. this.tabCost = {}
  956. this.tabPhotoClick = {}
  957. ;(this.tabPhotoShow = {}), (this.tabDiscountCost = {})
  958. this.tabAClick = {}
  959. this.tableData = []
  960. this.discountCostLink = {}
  961. this.photoShowLink = {}
  962. this.photoClickLink = {}
  963. this.costLink = {}
  964. this.aClickLink = {}
  965. this.myChart.clear()
  966. this.dateValue = [moment(), moment()]
  967. },
  968. //打开日期框
  969. opendate() {
  970. this.openOptions = !this.openOptions
  971. // console.log(this.openOptions)
  972. },
  973. opendateClose() {
  974. this.openOptions = false
  975. // console.log(this.openOptions)
  976. },
  977. //请求chart数据
  978. chartHttp(params) {
  979. return new Promise((resolve, reject) => {
  980. postAction('/ctop/kuaishou/dailyPage/report/chart', params).then(res => {
  981. // console.log(res)
  982. if (res.success) {
  983. this.loading = false
  984. this.refreshDisabled = false
  985. this.resetDisabled = false
  986. this.searchDisabled = false
  987. // 待处理问题
  988. this.cost = res.result.costWeekLink
  989. this.click = res.result.clickWeekLink
  990. this.showNum = res.result.showNumWeekLink
  991. //展示的五个块的数据
  992. this.discountCostLink = res.result.sumData.Sum.discountCostLink
  993. this.photoShowLink = res.result.sumData.Sum.photoShowLink
  994. this.photoClickLink = res.result.sumData.Sum.photoClickLink
  995. this.costLink = res.result.sumData.Sum.costLink
  996. this.aClickLink = res.result.sumData.Sum.aClickLink
  997. //chart的数据
  998. this.tabCost = JSON.parse(JSON.stringify(initDay))
  999. this.tabPhotoClick = JSON.parse(JSON.stringify(initDay))
  1000. this.tabPhotoShow = JSON.parse(JSON.stringify(initDay))
  1001. this.tabDiscountCost = JSON.parse(JSON.stringify(initDay))
  1002. this.tabAClick = JSON.parse(JSON.stringify(initDay))
  1003. let chartData = res.result.chartData
  1004. chartData.map((item, index) => {
  1005. if (item.statHour || item.statHour == 0) {
  1006. //说明是查询 天 数据;
  1007. // console.log('day')
  1008. item.statHour = item.statHour >= 10 ? `${item.statHour}:00` : `0${item.statHour}:00`
  1009. if (this.dateValue[0].format('YYYY-MM-DD') == moment().format('YYYY-MM-DD')) {
  1010. //说明是今天
  1011. this.tabPhotoClick.yesterday.y.push(item.photoClick)
  1012. this.tabCost.yesterday.y.push(item.cost)
  1013. this.tabPhotoShow.yesterday.y.push(item.photoShow)
  1014. this.tabDiscountCost.yesterday.y.push(item.discountCost)
  1015. this.tabAClick.yesterday.y.push(item.aClick)
  1016. this.tabPhotoClick.x.push(item.statHour)
  1017. this.tabCost.x.push(item.statHour)
  1018. this.tabPhotoShow.x.push(item.statHour)
  1019. this.tabDiscountCost.x.push(item.statHour)
  1020. this.tabAClick.x.push(item.statHour)
  1021. if (item.afterData) {
  1022. this.tabPhotoClick.today.y.push(item.afterData.photoClick)
  1023. this.tabCost.today.y.push(item.afterData.cost)
  1024. this.tabPhotoShow.today.y.push(item.afterData.photoShow)
  1025. this.tabDiscountCost.today.y.push(item.afterData.discountCost)
  1026. this.tabAClick.today.y.push(item.afterData.aClick)
  1027. //环比
  1028. this.tabPhotoClick.huanbi.y.push(item.afterData.photoClickProportion)
  1029. // console.log((item.afterData.photoClickProportion*100).toFixed(2)+'%')
  1030. this.tabCost.huanbi.y.push(item.afterData.costProportion)
  1031. this.tabPhotoShow.huanbi.y.push(item.afterData.photoShowProportion)
  1032. this.tabDiscountCost.huanbi.y.push(item.afterData.costProportion)
  1033. this.tabAClick.huanbi.y.push(item.afterData.aClickProportion)
  1034. } else {
  1035. this.tabPhotoClick.today.y.push(0)
  1036. this.tabCost.today.y.push(0)
  1037. this.tabPhotoShow.today.y.push(0)
  1038. this.tabDiscountCost.today.y.push(0)
  1039. this.tabAClick.today.y.push(0)
  1040. this.tabPhotoClick.huanbi.y.push(0)
  1041. this.tabCost.huanbi.y.push(0)
  1042. this.tabPhotoShow.huanbi.y.push(0)
  1043. this.tabDiscountCost.huanbi.y.push(0)
  1044. this.tabAClick.huanbi.y.push(0)
  1045. }
  1046. } else {
  1047. if (item.afterData) {
  1048. this.tabPhotoClick.yesterday.y.push(item.afterData.photoClick)
  1049. this.tabCost.yesterday.y.push(item.afterData.cost)
  1050. this.tabPhotoShow.yesterday.y.push(item.afterData.photoShow)
  1051. this.tabDiscountCost.yesterday.y.push(item.afterData.discountCost)
  1052. this.tabAClick.yesterday.y.push(item.afterData.aClick)
  1053. this.tabPhotoClick.x.push(item.afterData.statHour)
  1054. this.tabCost.x.push(item.afterData.statHour)
  1055. this.tabPhotoShow.x.push(item.afterData.statHour)
  1056. this.tabDiscountCost.x.push(item.afterData.statHour)
  1057. this.tabAClick.x.push(item.afterData.statHour)
  1058. }
  1059. }
  1060. } else if (item.statDate) {
  1061. // console.log('date')
  1062. this.tabPhotoClick.yesterday.y.push(item.photoClick)
  1063. this.tabCost.yesterday.y.push(item.cost)
  1064. this.tabPhotoShow.yesterday.y.push(item.photoShow)
  1065. this.tabDiscountCost.yesterday.y.push(item.discountCost)
  1066. this.tabAClick.yesterday.y.push(item.aClick)
  1067. this.tabPhotoClick.x.push(item.statDate)
  1068. this.tabCost.x.push(item.statDate)
  1069. this.tabPhotoShow.x.push(item.statDate)
  1070. this.tabDiscountCost.x.push(item.statDate)
  1071. this.tabAClick.x.push(item.statDate)
  1072. }
  1073. })
  1074. }
  1075. this.callback(this.tabKey)
  1076. })
  1077. })
  1078. },
  1079. //请求项目和账户内容
  1080. accountHttp() {
  1081. this.treeData = []
  1082. this.treeValue = []
  1083. getAction(
  1084. '/ctop/projectMember/getProjectAccountByUserId?mediaType=2&userId=' + this.userInfo().id,
  1085. {}
  1086. ).then(res => {
  1087. if (res.success) {
  1088. // console.log(res);
  1089. if (res.result) {
  1090. res.result.forEach((element, index) => {
  1091. if (element) {
  1092. this.treeData.push({})
  1093. this.treeData[index].title =
  1094. element.project.projectName + '_(' + element.project.advertiserName + ')'
  1095. this.treeData[index].value = 'project' + element.project.projectId
  1096. this.treeData[index].key = element.project.projectId
  1097. this.treeData[index].mediaId = element.project.mediaId
  1098. this.treeData[index].children = []
  1099. if (element.account.length) {
  1100. element.account.forEach((ele, i) => {
  1101. this.treeData[index].children.push({})
  1102. this.treeData[index].children[i].title =
  1103. ele.userName +
  1104. '_' +
  1105. ele.authName +
  1106. '_' +
  1107. element.project.projectName +
  1108. '_(' +
  1109. (ele.accountStatus ? '已停投' : '投放中') +
  1110. ')'
  1111. this.treeData[index].children[i].value = ele.accountId
  1112. this.treeData[index].children[i].key = ele.accountId
  1113. this.treeData[index].children[i].accountStatus = ele.accountStatus
  1114. })
  1115. }
  1116. }
  1117. })
  1118. // console.log(this.treeData)
  1119. }
  1120. }
  1121. })
  1122. },
  1123. //初始化echart
  1124. getEchartData(idName, optionName) {
  1125. const chart = this.$refs[idName]
  1126. // console.log(chart)
  1127. if (chart) {
  1128. var myChart = echarts.init(document.getElementById(idName))
  1129. myChart.clear()
  1130. myChart.setOption(optionName)
  1131. window.addEventListener('resize', function() {
  1132. myChart.resize()
  1133. })
  1134. this.myChart = myChart
  1135. }
  1136. },
  1137. //tab切换页的事件
  1138. callback(key) {
  1139. // console.log(key);
  1140. this.tabKey = key
  1141. this.sectionOption = JSON.parse(JSON.stringify(sectionOption))
  1142. if (key == 'cost') {
  1143. if (this.dateValue[0].format('YYYY-MM-DD') == moment().format('YYYY-MM-DD')) {
  1144. this.sectionOption.legend.data = ['今天', '昨天']
  1145. this.sectionOption.xAxis[0].data = this.tabCost.x
  1146. this.sectionOption.series[0].data = this.tabCost.today.y
  1147. this.sectionOption.series[0].name = this.tabCost.today.name
  1148. this.sectionOption.series[1].data = this.tabCost.yesterday.y
  1149. this.sectionOption.series[1].name = this.tabCost.yesterday.name
  1150. this.sectionOption.series[2].data = this.tabCost.huanbi.y
  1151. this.sectionOption.series[2].name = this.tabCost.huanbi.name
  1152. this.sectionOption.tooltip.formatter = params => {
  1153. // console.log(params)
  1154. params[2].data = (params[2].data * 100).toFixed(2) + '%'
  1155. return `
  1156. ${params[0].marker}今天:${params[0].data}<br />
  1157. ${params[1].marker}昨天:${params[1].data}<br />
  1158. ${params[2].marker}环比:${params[2].data}
  1159. `
  1160. }
  1161. } else {
  1162. this.sectionOption.legend.data = ['总消耗']
  1163. this.sectionOption.xAxis[0].data = this.tabCost.x
  1164. this.sectionOption.series[0].data = this.tabCost.yesterday.y
  1165. this.sectionOption.series[0].name = '总消耗'
  1166. }
  1167. } else if (key == 'photoClick') {
  1168. if (this.dateValue[0].format('YYYY-MM-DD') == moment().format('YYYY-MM-DD')) {
  1169. this.sectionOption.legend.data = ['今天', '昨天']
  1170. this.sectionOption.xAxis[0].data = this.tabPhotoClick.x
  1171. this.sectionOption.series[0].data = this.tabPhotoClick.today.y
  1172. this.sectionOption.series[0].name = this.tabPhotoClick.today.name
  1173. this.sectionOption.series[1].data = this.tabPhotoClick.yesterday.y
  1174. this.sectionOption.series[1].name = this.tabPhotoClick.yesterday.name
  1175. this.sectionOption.series[2].data = this.tabPhotoClick.huanbi.y
  1176. this.sectionOption.series[2].name = this.tabPhotoClick.huanbi.name
  1177. this.sectionOption.tooltip.formatter = params => {
  1178. // console.log(params)
  1179. params[2].data = (params[2].data * 100).toFixed(2) + '%'
  1180. return `
  1181. ${params[0].marker}今天:${params[0].data}<br />
  1182. ${params[1].marker}昨天:${params[1].data}<br />
  1183. ${params[2].marker}环比:${params[2].data}
  1184. `
  1185. }
  1186. } else {
  1187. this.sectionOption.legend.data = ['封面点击数']
  1188. this.sectionOption.xAxis[0].data = this.tabPhotoClick.x
  1189. this.sectionOption.series[0].data = this.tabPhotoClick.yesterday.y
  1190. this.sectionOption.series[0].name = '封面点击数'
  1191. }
  1192. } else if (key == 'photoShow') {
  1193. if (this.dateValue[0].format('YYYY-MM-DD') == moment().format('YYYY-MM-DD')) {
  1194. this.sectionOption.legend.data = ['今天', '昨天']
  1195. this.sectionOption.xAxis[0].data = this.tabPhotoShow.x
  1196. this.sectionOption.series[0].data = this.tabPhotoShow.today.y
  1197. this.sectionOption.series[0].name = this.tabPhotoShow.today.name
  1198. this.sectionOption.series[1].data = this.tabPhotoShow.yesterday.y
  1199. this.sectionOption.series[1].name = this.tabPhotoShow.yesterday.name
  1200. this.sectionOption.series[2].data = this.tabPhotoShow.huanbi.y
  1201. this.sectionOption.series[2].name = this.tabPhotoShow.huanbi.name
  1202. this.sectionOption.tooltip.formatter = params => {
  1203. // console.log(params)
  1204. params[2].data = (params[2].data * 100).toFixed(2) + '%'
  1205. return `
  1206. ${params[0].marker}今天:${params[0].data}<br />
  1207. ${params[1].marker}昨天:${params[1].data}<br />
  1208. ${params[2].marker}环比:${params[2].data}
  1209. `
  1210. }
  1211. } else {
  1212. this.sectionOption.legend.data = ['封面曝光数']
  1213. this.sectionOption.xAxis[0].data = this.tabPhotoShow.x
  1214. this.sectionOption.series[0].data = this.tabPhotoShow.yesterday.y
  1215. this.sectionOption.series[0].name = '封面曝光数'
  1216. }
  1217. } else if (key == 'discountCost') {
  1218. if (this.dateValue[0].format('YYYY-MM-DD') == moment().format('YYYY-MM-DD')) {
  1219. this.sectionOption.legend.data = ['今天', '昨天']
  1220. this.sectionOption.xAxis[0].data = this.tabDiscountCost.x
  1221. this.sectionOption.series[0].data = this.tabDiscountCost.today.y
  1222. this.sectionOption.series[0].name = this.tabDiscountCost.today.name
  1223. this.sectionOption.series[1].data = this.tabDiscountCost.yesterday.y
  1224. this.sectionOption.series[1].name = this.tabDiscountCost.yesterday.name
  1225. this.sectionOption.series[2].data = this.tabDiscountCost.huanbi.y
  1226. this.sectionOption.series[2].name = this.tabDiscountCost.huanbi.name
  1227. this.sectionOption.tooltip.formatter = params => {
  1228. // console.log(params)
  1229. params[2].data = (params[2].data * 100).toFixed(2) + '%'
  1230. return `
  1231. ${params[0].marker}今天:${params[0].data}<br />
  1232. ${params[1].marker}昨天:${params[1].data}<br />
  1233. ${params[2].marker}环比:${params[2].data}
  1234. `
  1235. }
  1236. } else {
  1237. this.sectionOption.legend.data = ['折后消耗']
  1238. this.sectionOption.xAxis[0].data = this.tabDiscountCost.x
  1239. this.sectionOption.series[0].data = this.tabDiscountCost.yesterday.y
  1240. this.sectionOption.series[0].name = '折后消耗'
  1241. }
  1242. } else {
  1243. if (this.dateValue[0].format('YYYY-MM-DD') == moment().format('YYYY-MM-DD')) {
  1244. this.sectionOption.legend.data = ['今天', '昨天']
  1245. this.sectionOption.xAxis[0].data = this.tabAClick.x
  1246. this.sectionOption.series[0].data = this.tabAClick.today.y
  1247. this.sectionOption.series[0].name = this.tabAClick.today.name
  1248. this.sectionOption.series[1].data = this.tabAClick.yesterday.y
  1249. this.sectionOption.series[1].name = this.tabAClick.yesterday.name
  1250. this.sectionOption.series[2].data = this.tabAClick.huanbi.y
  1251. this.sectionOption.series[2].name = this.tabAClick.huanbi.name
  1252. this.sectionOption.tooltip.formatter = params => {
  1253. // console.log(params)
  1254. params[2].data = (params[2].data * 100).toFixed(2) + '%'
  1255. return `
  1256. ${params[0].marker}今天:${params[0].data}<br />
  1257. ${params[1].marker}昨天:${params[1].data}<br />
  1258. ${params[2].marker}环比:${params[2].data}
  1259. `
  1260. }
  1261. } else {
  1262. this.sectionOption.legend.data = ['素材曝光数']
  1263. this.sectionOption.xAxis[0].data = this.tabAClick.x
  1264. this.sectionOption.series[0].data = this.tabAClick.yesterday.y
  1265. this.sectionOption.series[0].name = '素材曝光数'
  1266. }
  1267. }
  1268. this.getEchartData('sectionChart', this.sectionOption)
  1269. },
  1270. //请求table的数据
  1271. tableHttp(params) {
  1272. this.loading = true
  1273. this.tableData = []
  1274. postAction('/ctop/kuaishou/dailyPage/report/list', {
  1275. mediaId: this.mediaId,
  1276. discount: this.discount,
  1277. accountIds: this.accountId,
  1278. startDate: this.dateValue[0].format('YYYY-MM-DD'),
  1279. endDate: this.dateValue[1].format('YYYY-MM-DD'),
  1280. hour: this.timeSelectValue,
  1281. target: this.target,
  1282. order: this.order
  1283. }).then(res => {
  1284. if (res.success) {
  1285. this.loading = false
  1286. // console.log(res)
  1287. res.result.forEach(element => {
  1288. if (this.timeValueString) {
  1289. element.date = this.dateValue[0].format('YYYY.MM.DD') + '—' + this.timeValueString
  1290. } else {
  1291. if (
  1292. this.accountId.length == 1 &&
  1293. this.dateValue[0].format('YYYY.MM.DD') != this.dateValue[1].format('YYYY.MM.DD')
  1294. ) {
  1295. element.date = element.statDate
  1296. } else {
  1297. element.date =
  1298. this.dateValue[0].format('YYYY.MM.DD') +
  1299. '-' +
  1300. this.dateValue[1].format('YYYY.MM.DD')
  1301. }
  1302. }
  1303. })
  1304. if (this.dateValue[0].format('YYYY-MM-DD') == this.dateValue[1].format('YYYY-MM-DD')) {
  1305. for (let i = res.result.length - 1; i > res.result.length - 4; i--) {
  1306. res.result[i].authName = '-'
  1307. res.result[i].accountId = '-'
  1308. res.result[i].statDate = '总计'
  1309. }
  1310. for (let key in res.result[res.result.length - 1]) {
  1311. if (res.result[res.result.length - 1][key] < 1) {
  1312. res.result[res.result.length - 1][key] =
  1313. (res.result[res.result.length - 1][key] * 100).toFixed(2) + '%'
  1314. }
  1315. }
  1316. res.result[res.result.length - 1].statDate = '环比'
  1317. res.result[res.result.length - 2].statDate = '昨日总计(相对)'
  1318. this.tableData = res.result
  1319. length = this.tableData.length - 3
  1320. } else {
  1321. res.result[res.result.length - 1].statDate = '总计'
  1322. res.result[res.result.length - 1].authName = '-'
  1323. res.result[res.result.length - 1].accountId = '-'
  1324. this.tableData = res.result
  1325. length = this.tableData.length - 1
  1326. }
  1327. }
  1328. })
  1329. },
  1330. //导出报表
  1331. exportExcel() {
  1332. let column = this.columns.map((item, index) => {
  1333. return item.dataIndex
  1334. })
  1335. let columns = column.splice(3)
  1336. // console.log(columns)
  1337. downFilePost('/ctop/kuaishou/dailyPage/report/excel', {
  1338. mediaId: this.mediaId,
  1339. discount: this.discount,
  1340. accountIds: this.accountId,
  1341. startDate: this.dateValue[0].format('YYYY-MM-DD'),
  1342. endDate: this.dateValue[1].format('YYYY-MM-DD'),
  1343. hour: this.timeSelectValue,
  1344. target: this.target,
  1345. order: this.order,
  1346. columns
  1347. }).then(res => {
  1348. let blob = new Blob([res], {
  1349. type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
  1350. })
  1351. let downloadElement = document.createElement('a')
  1352. let href = window.URL.createObjectURL(blob) //创建下载的链接
  1353. downloadElement.href = href
  1354. downloadElement.download = moment().format('YYYY-MM-DD') + '账户报表.xlsx' //下载后文件名
  1355. document.body.appendChild(downloadElement)
  1356. downloadElement.click() //点击下载
  1357. document.body.removeChild(downloadElement) //下载完成移除元素
  1358. window.URL.revokeObjectURL(href) //释放掉blob对象
  1359. })
  1360. },
  1361. //弹出框打开,自定义列
  1362. customColumns() {
  1363. this.visible = true
  1364. this.listNum = [...this.columns]
  1365. },
  1366. getFormData(className) {
  1367. return this.form.getFieldValue(className)
  1368. },
  1369. //table 排序
  1370. sort(pagination, filters, sorter, { currentDataSource }) {
  1371. if (this.getFormData('accountIds') && this.getFormData('accountIds').length > 0) {
  1372. if (sorter.order == 'ascend') {
  1373. this.order = 'asc'
  1374. this.target = sorter.columnKey
  1375. } else if (sorter.order == 'descend') {
  1376. this.order = 'desc'
  1377. this.target = sorter.columnKey
  1378. } else {
  1379. if (
  1380. this.accountId.length == 1 &&
  1381. this.dateValue[0].format('YYYY.MM.DD') != this.dateValue[1].format('YYYY.MM.DD')
  1382. ) {
  1383. ;(this.target = 'statDate'), (this.order = 'asc')
  1384. } else {
  1385. ;(this.target = 'cost'), (this.order = 'desc')
  1386. }
  1387. }
  1388. this.handleQueryList()
  1389. }
  1390. },
  1391. closeCustomColumn() {
  1392. this.visible = false
  1393. },
  1394. //
  1395. discountChange() {
  1396. // console.log(this.discountSelect);
  1397. this.discount = this.discountSelect
  1398. },
  1399. rebatePropChange() {
  1400. // console.log(this.rebateProp)
  1401. this.discount = this.rebateProp
  1402. },
  1403. //自定义之后修改父元素表头
  1404. changeColumn(val) {
  1405. this.columns = [...val]
  1406. this.columns = [...val]
  1407. if (this.columns.length > this.columnsFixd.length && this.columns.length < 8) {
  1408. this.columns.forEach((element, index) => {
  1409. if (index < this.columns.length - 1) {
  1410. element.width = 'auto'
  1411. element.fixed = false
  1412. }
  1413. })
  1414. // this.scrollX=2000+200*(this.columns.length-this.columnsFixd.length)
  1415. } else if (this.columns.length >= 8) {
  1416. this.columns.forEach((element, index) => {
  1417. if (index < this.columnsFixd.length) {
  1418. element.width = 200
  1419. element.fixed = 'left'
  1420. }
  1421. })
  1422. this.scrollX = 1000 + 200 * (this.columns.length - this.columnsFixd.length)
  1423. } else {
  1424. this.scrollX = 0
  1425. this.columns.forEach(element => {
  1426. element.width = 'auto'
  1427. element.fixed = false
  1428. })
  1429. }
  1430. },
  1431. tableHandle() {
  1432. // this.listNum = [...this.columns]
  1433. // console.log(this.listNum.length, this.columns)
  1434. if (this.listNum.length >= 9 || this.columns.length >= 9) {
  1435. this.tableWidth = 160
  1436. this.scrollX = this.columns.length * 160
  1437. // console.log(this.scrollX)
  1438. } else {
  1439. this.scrollX = 2000
  1440. }
  1441. }
  1442. },
  1443. mounted() {
  1444. this.$nextTick(() => {
  1445. setTimeout(() => {
  1446. this.handleQueryList()
  1447. }, 1000)
  1448. })
  1449. // this.accountHttp()
  1450. new Promise((resolve, reject) => {
  1451. this.getEchartData('sectionChart', this.sectionOption)
  1452. resolve()
  1453. }).then(() => {
  1454. this.myChart.clear()
  1455. })
  1456. postAction('/toutiao/videoReportDaily/getColumnJson', {
  1457. columnType: 2
  1458. }).then(res => {
  1459. // console.log(res)
  1460. if (res.success) {
  1461. // console.log(JSON.parse(res.result))
  1462. if (res.result) {
  1463. let columns = JSON.parse(res.result)
  1464. if (columns.length) {
  1465. if (columns.length >= columnsFixd.length) {
  1466. columns.map((item, index) => {
  1467. if (index > columnsFixd.length - 1) {
  1468. item.sorter = function(a, b) {}
  1469. }
  1470. })
  1471. columns = columns.slice(columnsFixd.length)
  1472. this.columns = [...columnsFixd, ...columns]
  1473. }
  1474. }
  1475. }
  1476. this.changeColumn(this.columns)
  1477. }
  1478. })
  1479. },
  1480. beforeDestroy() {
  1481. let arr = JSON.stringify(this.columns)
  1482. postAction('/toutiao/videoReportDaily/saveOrUpdateColumnJson', {
  1483. json: arr,
  1484. columnType: 2
  1485. }).then(res => {
  1486. // console.log(res)
  1487. })
  1488. },
  1489. filters: {
  1490. toPercentage(val) {
  1491. if (val) {
  1492. if (typeof val != 'string') {
  1493. return (val * 100).toFixed(2) + '%'
  1494. } else {
  1495. return val
  1496. }
  1497. } else if (typeof val == 'string') {
  1498. return val
  1499. } else {
  1500. return 0
  1501. }
  1502. },
  1503. //保留两位小数并且变成货币格式
  1504. decimalsHandle(val) {
  1505. if (val && typeof val != 'string') {
  1506. if (val >= 0) {
  1507. val = parseFloat(val).toFixed(2)
  1508. let numberStr = val.toString()
  1509. let str = numberStr.split('.')
  1510. let str0 = str[0].split('').reverse()
  1511. for (let i = 0; i < str0.length; i++) {
  1512. if ((i + 1) % 4 === 0) {
  1513. str0.splice(i, 0, ',')
  1514. }
  1515. }
  1516. str0.reverse()
  1517. let handleResult = ''
  1518. for (let j = 0; j < str0.length; j++) {
  1519. handleResult += str0[j]
  1520. }
  1521. return handleResult + '.' + str[1]
  1522. } else {
  1523. val = parseFloat(val).toFixed(2)
  1524. let numberStr = val.toString()
  1525. let str = numberStr.split('.')
  1526. let str0 = str[0]
  1527. .substr(1)
  1528. .split('')
  1529. .reverse()
  1530. for (let i = 0; i < str0.length; i++) {
  1531. if ((i + 1) % 4 === 0) {
  1532. str0.splice(i, 0, ',')
  1533. }
  1534. }
  1535. str0.reverse()
  1536. let handleResult = ''
  1537. for (let j = 0; j < str0.length; j++) {
  1538. handleResult += str0[j]
  1539. }
  1540. return '-' + handleResult + '.' + str[1]
  1541. }
  1542. } else if (typeof val == 'string') {
  1543. return val
  1544. } else {
  1545. return 0
  1546. }
  1547. },
  1548. //变成货币格式
  1549. formatCurrency(val) {
  1550. if ((val || val == 0) && typeof val != 'string') {
  1551. let numberStr = val.toString()
  1552. let str = numberStr.split('').reverse()
  1553. for (let i = 0; i < str.length; i++) {
  1554. if ((i + 1) % 4 === 0) {
  1555. str.splice(i, 0, ',')
  1556. }
  1557. }
  1558. str.reverse()
  1559. let handleResult = ''
  1560. for (let j = 0; j < str.length; j++) {
  1561. handleResult += str[j]
  1562. }
  1563. return handleResult
  1564. } else if (typeof val == 'string') {
  1565. return val
  1566. } else {
  1567. return '-'
  1568. }
  1569. }
  1570. }
  1571. }
  1572. </script>
  1573. <style lang="scss">
  1574. .ant-tooltip-inner,
  1575. .ant-tooltip-arrow::before {
  1576. background-color: #fff;
  1577. color: #333;
  1578. }
  1579. </style>
  1580. <style lang="scss" scoped>
  1581. .accountReport {
  1582. .circul {
  1583. width: 5px;
  1584. height: 5px;
  1585. border-radius: 50%;
  1586. background-color: #32cd32;
  1587. }
  1588. .optionLine:hover {
  1589. box-shadow: 0 0 15px rgba(0, 0, 0, 0.15);
  1590. border-radius: 10px;
  1591. }
  1592. .optionLine {
  1593. box-sizing: border-box;
  1594. padding: 15px 15px;
  1595. position: relative;
  1596. // margin: 20px 10px 15px;
  1597. margin-bottom: 15px;
  1598. background-color: #fff;
  1599. // border: 1px solid #ccc;
  1600. .optionTow {
  1601. margin-top: 15px;
  1602. position: relative;
  1603. .optItem {
  1604. display: inline-block;
  1605. margin-right: 15px;
  1606. span {
  1607. display: inline-block;
  1608. padding: 0 3px;
  1609. }
  1610. }
  1611. }
  1612. .btn {
  1613. position: absolute;
  1614. right: 0px;
  1615. top: 0px;
  1616. .mybtn {
  1617. margin-left: 10px;
  1618. }
  1619. }
  1620. }
  1621. }
  1622. </style>