KSvideoStatics.vue 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296
  1. <template>
  2. <div class="vsummary">
  3. <div class="xiangmuxuanze" >
  4. <span >项目选择:</span>
  5. <Treeselect :appId.sync="appId" request="2,4" style="display: inline-block;position: relative;margin-left: 0px;"/>
  6. </div>
  7. <div class="timeDiv">
  8. <div style='display:flex;align-items: center;flex-wrap:wrap;'>
  9. <div style="dispaly:inline-block;margin-bottom:15px;">
  10. <span>时间范围:</span>
  11. <span style="display: inline-block;" @click="opendate">
  12. <DatePicker :openOptions='openOptions' :parentDate='dateValue' left='-100px' typemain="ksVideo"></DatePicker>
  13. </span>
  14. </div>
  15. <div style="dispaly:inline-block;margin-bottom:15px;">
  16. <span style="margin-left:15px;">设计负责人:</span>
  17. <span>
  18. <!-- <a-input placeholder="请输入剪辑的名字" v-model="clip" style="width:140px" /> -->
  19. <a-select v-model="leaderId" style="width: 140px" allowClear show-search :filter-option="filterOption">
  20. <a-select-option v-for="item in designList" :key="item.userId" :value='item.userId'>
  21. {{item.companyName +'_'+item.userName }}
  22. </a-select-option>
  23. </a-select>
  24. </span>
  25. </div>
  26. <div style="dispaly:inline-block;margin-bottom:15px;">
  27. <span style="margin-left:15px">剪辑:</span>
  28. <span >
  29. <!-- <a-input placeholder="请输入剪辑的名字" v-model="clip" style="width:140px" /> -->
  30. <a-select v-model="clip" style="width: 140px" allowClear show-search :filter-option="filterOption">
  31. <a-select-option v-for="item in designList" :key="item.userId" :value='item.userId'>
  32. {{item.companyName +'_'+item.userName }}
  33. </a-select-option>
  34. </a-select>
  35. </span>
  36. </div>
  37. <div style="dispaly:inline-block;margin-bottom:15px;">
  38. <span style="margin-left:15px">拍摄:</span>
  39. <span >
  40. <!-- <a-input placeholder="请输入拍摄的名字" v-model="shot" style="width:140px" /> -->
  41. <a-select v-model="shot" style="width: 140px" allowClear show-search :filter-option="filterOption">
  42. <a-select-option v-for="item in designList" :key="item.userId" :value='item.userId'>
  43. {{item.companyName +'_'+item.userName }}
  44. </a-select-option>
  45. </a-select>
  46. </span>
  47. </div>
  48. <div style="dispaly:inline-block;margin-bottom:15px;">
  49. <span style="margin-left:15px">编导:</span>
  50. <span >
  51. <!-- <a-input placeholder="请输入编导的名字" v-model="plan" style="width:140px" /> -->
  52. <a-select v-model="plan" style="width: 140px" allowClear show-search :filter-option="filterOption">
  53. <a-select-option v-for="item in designList" :key="item.userId" :value='item.userId'>
  54. {{item.companyName +'_'+item.userName }}
  55. </a-select-option>
  56. </a-select>
  57. </span>
  58. </div>
  59. <div style="dispaly:inline-block;margin-bottom:15px;">
  60. <span style="margin-left:15px">素材渠道:</span>
  61. <span>
  62. <!-- <a-input placeholder="请输入编导的名字" v-model="plan" style="width:140px" /> -->
  63. <a-select v-model="material" style="width: 140px" allowClear>
  64. <a-select-option value="0">内部</a-select-option>
  65. <a-select-option value="1">素造</a-select-option>
  66. </a-select>
  67. </span>
  68. </div>
  69. </div>
  70. <a-button type="primary" @click="searchRes" :loading='searchLoading'>查询</a-button>
  71. </div>
  72. <!-- <div style="margin:15px 0" class="btndiv">
  73. <a-button type="primary" @click="customColumns">自定义列</a-button>
  74. <a-button type="default" style="float:right" @click="exportExcel" id="mybtn" v-show="exportExcelIsOk">导出报表</a-button>
  75. </div> -->
  76. <!-- <a-modal v-model="visible" title="自定义列" on-ok="handleOk" width="65%">
  77. <template slot="footer">
  78. <a-button key="back" @click="handleCancel">取消</a-button>
  79. <a-button key="submit" type="primary" :loading="loading" @click="handleOk">应用</a-button>
  80. </template>
  81. <a-input-search placeholder="输入要添加的列的名称" style="width: 40%" enter-button @search="onSearch" />
  82. <div class="zhuti">
  83. <div class="addlist">
  84. <p>可添加的列</p>
  85. <div class="selectionList">
  86. <selectComponent
  87. :showCol="listNum"
  88. @getshowlist="getshowlist"
  89. :fixedCol="columnsFixd"
  90. />
  91. </div>
  92. </div>
  93. <div class="listNum">
  94. <p>已选{{listNum.length}}列</p>
  95. <a-button id="btn" type="link" @click="clearAllList">清空全部</a-button>
  96. <ul class="selectlist">
  97. <li v-for="(item,index) in listNum" :key="index">
  98. <span v-if=" index <4">
  99. <a-icon type="lock" />
  100. <span class="listText">{{item.title}}</span>
  101. </span>
  102. <span v-else-if=" index >=4">
  103. <a-icon type="menu" style="color:#ccc" />
  104. <span class="listText">{{item.title}}</span>
  105. <a-icon
  106. type="close"
  107. @click="deleteCol(item,index)"
  108. id="closeStyle"
  109. style="fontSize:12px;"
  110. />
  111. </span>
  112. </li>
  113. </ul>
  114. </div>
  115. </div>
  116. </a-modal> -->
  117. <a-modal v-model="relevantPeopleVisible" title="相关人员" :footer="null" :centered='true'>
  118. <p>编导:{{relevantPeopleData.planName || '暂无数据'}}</p>
  119. <p>剪辑:{{relevantPeopleData.clipName || '暂无数据'}}</p>
  120. <p>拍摄:{{relevantPeopleData.shotName || '暂无数据'}}</p>
  121. </a-modal>
  122. <a-modal v-model="Videovisible" title="视频详情" @ok="videoOk" :footer="null" width="50%">
  123. <video
  124. @click.stop
  125. class="video"
  126. :src="videoUrl"
  127. controls="controls"
  128. style="height:600px;width:100%"
  129. >您的浏览器不支持 video 标签。</video>
  130. </a-modal>
  131. <!-- 报表区域 -->
  132. <div class="tableBox">
  133. <div class="tableTop">
  134. <a-button type="primary" @click="customColumns">自定义列</a-button>
  135. <a-button type="default" style="float:right" @click="exportExcel('exportTable')" id="mybtn" :loading='exportLoading'>导出报表</a-button>
  136. </div>
  137. <a-table
  138. size="middle"
  139. :columns="columns"
  140. :dataSource="data"
  141. bordered
  142. id="outTable"
  143. :pagination="ipagination"
  144. :scroll="{ x: scrollX }"
  145. :loading="loading"
  146. ref="accountTable"
  147. :width="tableWidth"
  148. @change="sort"
  149. style="word-break: break-all;font-size:16px;font-weight:600"
  150. @customHeaderCell="customHeaderCell(columns)"
  151. >
  152. <div slot="coverUrl" slot-scope="test,records">
  153. <!-- {{test}} -->
  154. <img
  155. :src="test"
  156. alt
  157. style="width:80px"
  158. @click="openVideo(records.url)"
  159. />
  160. </div>
  161. <span slot="operation" slot-scope="text, record">
  162. <a href="javascript:;" @click="opendetail(text, record)" style="margin-right:5px">查看明细</a>
  163. </span>
  164. <span slot="ctr" slot-scope="ctr">{{ ctr | toPercentage }}</span>
  165. <span slot="cost" slot-scope="cost">{{ cost | decimalsHandle }}</span>
  166. <span slot="clickMaterial" slot-scope="clickMaterial">{{ clickMaterial | formatCurrency }}</span>
  167. <span slot="showMaterial" slot-scope="showMaterial">{{ showMaterial | formatCurrency }}</span>
  168. <span slot="convertMaterial" slot-scope="convertMaterial">{{ convertMaterial | formatCurrency }}</span>
  169. <span slot="play25FeedBreak" slot-scope="play25FeedBreak">{{ play25FeedBreak | formatCurrency }}</span>
  170. <span slot="play50FeedBreak" slot-scope="play50FeedBreak">{{ play50FeedBreak | formatCurrency }}</span>
  171. <span slot="play75FeedBreak" slot-scope="play75FeedBreak">{{ play75FeedBreak | formatCurrency }}</span>
  172. <span slot="play100FeedBreak" slot-scope="play100FeedBreak">{{ play100FeedBreak | formatCurrency }}</span>
  173. <span slot="nextDayOpen" slot-scope="nextDayOpen">{{ nextDayOpen | formatCurrency }}</span>
  174. <span slot="downloadFinish" slot-scope="downloadFinish">{{ downloadFinish | formatCurrency }}</span>
  175. <span slot="downloadStart" slot-scope="downloadStart">{{ downloadStart | formatCurrency }}</span>
  176. <span slot="likeMaterial" slot-scope="likeMaterial">{{ likeMaterial | formatCurrency }}</span>
  177. <span slot="shareMaterial" slot-scope="shareMaterial">{{ shareMaterial | formatCurrency }}</span>
  178. <span slot="register" slot-scope="register">{{ register | formatCurrency }}</span>
  179. <span slot="follow" slot-scope="follow">{{ follow | formatCurrency }}</span>
  180. <span slot="formCount" slot-scope="formCount">{{ formCount | formatCurrency }}</span>
  181. <span slot="formCountCost" slot-scope="formCountCost">{{ formCountCost | decimalsHandle }}</span>
  182. <span slot="aClick" slot-scope="aClick">{{ aClick | formatCurrency }}</span>
  183. <span slot="photoShow" slot-scope="photoShow">{{ photoShow | formatCurrency }}</span>
  184. <span slot="photoClick" slot-scope="photoClick">{{ photoClick | formatCurrency }}</span>
  185. <span slot="bClick" slot-scope="bClick">{{ bClick | formatCurrency }}</span>
  186. <span slot="active" slot-scope="active">{{ active | formatCurrency }}</span>
  187. <span slot="submit" slot-scope="submit">{{ submit | formatCurrency }}</span>
  188. <span slot="eventCreditGrantLandingPage" slot-scope="eventCreditGrantLandingPage">{{ eventCreditGrantLandingPage | formatCurrency }}</span>
  189. <span slot="submitCost" slot-scope="submitCost">{{ submitCost | decimalsHandle }}</span>
  190. <span slot="eventCreditGrantLandingPageCost" slot-scope="eventCreditGrantLandingPageCost">{{ eventCreditGrantLandingPageCost | decimalsHandle }}</span>
  191. <span slot="submitRate" slot-scope="submitRate">{{ submitRate | toPercentage }}</span>
  192. <span slot="eventCreditGrantLandingPageRate" slot-scope="eventCreditGrantLandingPageRate">{{ eventCreditGrantLandingPageRate | toPercentage }}</span>
  193. <span
  194. slot="play25FeedBreakRate"
  195. slot-scope="play25FeedBreakRate"
  196. >{{ play25FeedBreakRate | toPercentage }}</span>
  197. <span slot="playOverRate" slot-scope="playOverRate">{{ playOverRate | toPercentage }}</span>
  198. <span slot="convertRate" slot-scope="convertRate">{{ convertRate | toPercentage }}</span>
  199. <span slot="nextDayOpenRate" slot-scope="nextDayOpenRate">{{ nextDayOpenRate | toPercentage }}</span>
  200. <span slot="ctr" slot-scope="ctr">{{ ctr | toPercentage }}</span>
  201. <span slot="cpc" slot-scope="cpc">{{ cpc | decimalsHandle }}</span>
  202. <span slot="cpm" slot-scope="cpm">{{ cpm | decimalsHandle }}</span>
  203. <span slot="activeRate" slot-scope="activeRate">{{ activeRate | toPercentage }}</span>
  204. <span
  205. slot="installFinishRate"
  206. slot-scope="installFinishRate"
  207. >{{ installFinishRate | toPercentage }}</span>
  208. <span slot="validPlayRate" slot-scope="validPlayRate">{{ validPlayRate | toPercentage }}</span>
  209. <span slot="activePayCost" slot-scope="activePayCost">{{ activePayCost | decimalsHandle }}</span>
  210. <span slot="nextDayOpenCost" slot-scope="nextDayOpenCost">{{ nextDayOpenCost | decimalsHandle }}</span>
  211. <span slot="validPlayCost" slot-scope="validPlayCost">{{ validPlayCost | decimalsHandle }}</span>
  212. <span slot="activeCost" slot-scope="activeCost">{{ activeCost | decimalsHandle }}</span>
  213. <span
  214. slot="gameAddictionCost"
  215. slot-scope="gameAddictionCost"
  216. >{{ gameAddictionCost | decimalsHandle }}</span>
  217. <span
  218. slot="downloadFinishCost"
  219. slot-scope="downloadFinishCost"
  220. >{{ downloadFinishCost | decimalsHandle }}</span>
  221. <span
  222. slot="downloadStartCost"
  223. slot-scope="downloadStartCost"
  224. >{{ downloadStartCost | decimalsHandle }}</span>
  225. <span
  226. slot="installFinishCost"
  227. slot-scope="installFinishCost"
  228. >{{ installFinishCost | decimalsHandle }}</span>
  229. <span slot="convertCost" slot-scope="convertCost">{{ convertCost | decimalsHandle }}</span>
  230. <span
  231. slot="activeRegisterCost"
  232. slot-scope="activeRegisterCost"
  233. >{{ activeRegisterCost | decimalsHandle }}</span>
  234. <span
  235. slot="downloadStartRate"
  236. slot-scope="downloadStartRate"
  237. >{{ downloadStartRate | toPercentage }}</span>
  238. <!-- <span
  239. slot="downloadFinishRate"
  240. slot-scope="downloadFinishRate"
  241. >{{ downloadFinishRate | toPercentage }}</span>
  242. <span slot="activeRate" slot-scope="activeRate">{{ activeRate | toPercentage }}</span>
  243. <span
  244. slot="activeRegisterRate"
  245. slot-scope="activeRegisterRate"
  246. >{{ activeRegisterRate | toPercentage }}</span> -->
  247. <span
  248. slot="gameAddictionRate"
  249. slot-scope="gameAddictionRate"
  250. >{{ gameAddictionRate | toPercentage }}</span>
  251. <!-- <span slot="nextDayOpenRate" slot-scope="nextDayOpenRate">{{ nextDayOpenRate | toPercentage }}</span> -->
  252. <span slot="relativePeople" slot-scope="text,record">
  253. <!-- <a href="javascript:;" @click.stop="showRelevantPeople(record)">查看相关人员</a> -->
  254. <p>负责人:{{record.designLeader || '无'}}</p>
  255. <p>剪辑:{{record.clip || '无'}}</p>
  256. <p>拍摄:{{record.shot || '无'}}</p>
  257. <p>编导:{{record.plan || '无'}}</p>
  258. </span>
  259. </a-table>
  260. </div>
  261. <customColumn :visible='visible' :listNum='listNum' :fiexColumn='columnsFixd' :mediaType='2' @closeCustomColumn='closeCustomColumn' @changeColumn='changeColumn' />
  262. <!-- 明细表 -->
  263. <a-modal v-model="visibleDetail" title="详细信息" width="50%" :footer="null" >
  264. <a-button type="default" @click="exportExcel('exportDetail')" id="mybtn" >导出报表</a-button>
  265. <a-table
  266. :columns="detailColumn"
  267. :data-source="detailData"
  268. bordered
  269. tableLayout="auto"
  270. :pagination="false"
  271. :loading='detailLoading'
  272. style="word-break: break-all;"
  273. >
  274. <!-- <span slot="huanbi" slot-scope="huanbi">{{ huanbi | toPercentage }}</span> -->
  275. <span slot="advertiserName" slot-scope="text">{{ text || '暂未填写该数据' }}</span>
  276. <span slot="cost" slot-scope="cost">{{ cost | decimalsHandle }}</span>
  277. </a-table>
  278. </a-modal>
  279. </div>
  280. </template>
  281. <script>
  282. import moment from 'moment'
  283. import { JeecgListMixin } from '@/mixins/ipagination'
  284. import { getAction, postAction, downFile, downFilePost } from '@/api/manage'
  285. import selectComponent from './selectComponent'
  286. import Treeselect from '../components/Treeselect'
  287. import DatePicker from '@/components/DatePicker'
  288. import customColumn from '../components/customColumn.vue'
  289. import {mapGetters} from 'vuex';
  290. const columnsFixd = [
  291. {
  292. title: '视频',
  293. dataIndex: 'coverUrl',
  294. align: 'center',
  295. width: 100,
  296. fixed: 'left',
  297. key: 'coverUrl',
  298. scopedSlots: { customRender: 'coverUrl' }
  299. },
  300. {
  301. title: '视频名称',
  302. dataIndex: 'materialName',
  303. align: 'center',
  304. width: 130,
  305. fixed: 'left'
  306. },
  307. {
  308. title: '视频ID',
  309. dataIndex: 'signature',
  310. align: 'center',
  311. width: 150,
  312. fixed: 'left'
  313. },
  314. {
  315. title: '项目名称',
  316. dataIndex: 'projectName',
  317. align: 'center',
  318. width: 150,
  319. fixed: 'left'
  320. },
  321. {
  322. title: '渠道',
  323. dataIndex: 'channel',
  324. align: 'center',
  325. width: 150,
  326. fixed: 'left'
  327. },
  328. {
  329. title:'相关人员',
  330. dataIndex:'relativePeople',
  331. key:'relativePeople',
  332. scopedSlots: { customRender: 'relativePeople' },
  333. align: 'center',
  334. width:150,
  335. fixed: 'left'
  336. },
  337. // {
  338. // title:'操作',
  339. // dataIndex:'operation',
  340. // key:'operation',
  341. // scopedSlots: { customRender: 'operation' },
  342. // align: 'center',
  343. // width:90,
  344. // fixed: 'left'
  345. // },
  346. {
  347. title: '创建时间',
  348. dataIndex: 'createTime',
  349. scopedSlots: { customRender: 'createTime' },
  350. align: 'center',
  351. sorter: () => {}
  352. },
  353. ]
  354. let show = 0
  355. const initVariableColimns=[
  356. {
  357. title: '消耗(元)',
  358. dataIndex: 'cost',
  359. tip: '广告在投放期间的花费总额',
  360. align: 'center',
  361. scopedSlots: { customRender: 'cost' },
  362. sorter: () => {}
  363. },
  364. // {
  365. // title: '折后消耗(元)',
  366. // dataIndex: 'discountCost',
  367. // width:150,
  368. // tip: '广告在投放期间的花费总额',
  369. // align: 'center',
  370. // scopedSlots: { customRender: 'discountCost' },
  371. // sorter: () => {}
  372. // },
  373. {
  374. title: '封面曝光数',
  375. dataIndex: 'photoShow',
  376. tip: '广告在瀑布流被观看次数',
  377. align: 'center',
  378. scopedSlots: { customRender: 'photoShow' },
  379. sorter:() => {}
  380. },
  381. {
  382. title: '封面点击数',
  383. dataIndex: 'photoClick',
  384. tip: '用户点击封面进入视频播放页的次数(数据会进行反作弊去重)',
  385. align: 'center',
  386. scopedSlots: { customRender: 'photoClick' },
  387. sorter: () => {}
  388. },
  389. {
  390. title: '封面点击率',
  391. dataIndex: 'clickRate',
  392. tip: '封面点击数占封面展示数百分比',
  393. align: 'center',
  394. scopedSlots: { customRender: 'clickRate' },
  395. sorter:() => {}
  396. },
  397. {
  398. title: '素材曝光数',
  399. dataIndex: 'aClick',
  400. tip: '用户进入视频播放页观看的次数(数据会进行反作弊去重)',
  401. align: 'center',
  402. scopedSlots: { customRender: 'aClick' },
  403. sorter:() => {}
  404. },
  405. {
  406. title: '行为数',
  407. dataIndex: 'bClick',
  408. tip: '用户在视频播放页单击转化按钮的次数/展示数*100%',
  409. align: 'center',
  410. scopedSlots: { customRender: 'bClick' },
  411. sorter:() => {}
  412. },
  413. {
  414. title: '行为率',
  415. dataIndex: 'bClickRate',
  416. tip: '行为数占素材曝光数百分比',
  417. align: 'center',
  418. scopedSlots: { customRender: 'bClickRate' },
  419. sorter:() => {}
  420. },
  421. {
  422. title: '平均千次封面曝光花费(元)',
  423. dataIndex: 'cpm',
  424. tip: '花费/封面曝光数*1000',
  425. align: 'center',
  426. scopedSlots: { customRender: 'cpm' },
  427. sorter:() => {}
  428. },
  429. {
  430. title: '平均封面点击单价(元)',
  431. dataIndex: 'cpc',
  432. tip: '花费/封面点击数',
  433. align: 'center',
  434. scopedSlots: { customRender: 'cpc' },
  435. sorter:() => {}
  436. },
  437. {
  438. title: '平均行为单价(元)',
  439. dataIndex: 'cpb',
  440. tip: '总花费/行为数',
  441. align: 'center',
  442. scopedSlots: { customRender: 'cpb' },
  443. sorter:() => {}
  444. },
  445. {
  446. title: '3s播放数',
  447. dataIndex: 'play3sCount',
  448. tip: '总花费/行为数',
  449. align: 'center',
  450. scopedSlots: { customRender: 'play3sCount' },
  451. sorter:() => {}
  452. },
  453. {
  454. title: '3s播放率',
  455. dataIndex: 'play3sRate',
  456. tip: '总花费/行为数',
  457. align: 'center',
  458. scopedSlots: { customRender: 'play3sRate' },
  459. sorter:() => {}
  460. },
  461. ]
  462. let detailColumn=[
  463. {
  464. title: '客户',
  465. dataIndex: 'advertiserName',
  466. align: 'center',
  467. scopedSlots: { customRender: 'advertiserName' },
  468. },
  469. {
  470. title: '项目名称',
  471. dataIndex: 'projectName',
  472. align: 'center',
  473. width: 150,
  474. },
  475. {
  476. title: '时间',
  477. dataIndex: 'statDate',
  478. align: 'center',
  479. width: 120
  480. },
  481. {
  482. title: '消耗',
  483. dataIndex: 'cost',
  484. scopedSlots: { customRender: 'cost' },
  485. align: 'center',
  486. },
  487. ]
  488. export default {
  489. data() {
  490. return {
  491. material: '',
  492. searchLoading:false,
  493. designList:[],
  494. detailLoading:false,
  495. clip:undefined,
  496. shot:undefined,
  497. plan:undefined,
  498. leaderId:undefined,
  499. //明细数据
  500. visibleDetail:false,
  501. detailColumn,
  502. detailData: [],
  503. exportLoading:false,
  504. target:'cost',
  505. order:'desc',
  506. type:0,
  507. dateValue:[moment().subtract(1,'days'),moment().subtract(1,'days')],
  508. openOptions:false,
  509. relevantPeopleVisible:false,
  510. relevantPeopleData:{},
  511. roleCode: localStorage.getItem('roleCode'),
  512. //下拉选择框的数据
  513. projectArr:[],
  514. selectValue:'',
  515. appId:[],
  516. //设置表格的列宽
  517. tableWidth: '',
  518. //gudinglie
  519. columnsFixd: columnsFixd,
  520. //是否打开视频
  521. Videovisible: false,
  522. videoUrl: '',
  523. //是否显示导出按钮
  524. exportExcelIsOk: true,
  525. consumeValue: 0,
  526. columns:[...columnsFixd,...initVariableColimns] ,//table的表头
  527. addColumns: [],
  528. data: [],
  529. totalSelect: 0,
  530. daysFlag: false,
  531. dateRange: [],
  532. dataElse: [],
  533. loading: false,
  534. visible: false,
  535. //自定义列的搜索框
  536. searchInput: '',
  537. //弹出框中现实的选中列数
  538. scrollX: 0,
  539. listNum: [],
  540. //
  541. form: [],
  542. videoID: '',
  543. timedata: [],
  544. ipagination: {
  545. current: 1,
  546. pageSize: 10,
  547. showTotal: (total, range) => {
  548. return range[0] + "-" + range[1] + " 共" + total + "条"
  549. },
  550. showQuickJumper: true,
  551. showSizeChanger:true,
  552. pageSizeOptions: ['10', '30', '50'],
  553. total: 0,
  554. onChange: (current, pageSize) => {
  555. // 切换分页时的回调,
  556. // 当在页面定义change事件时,切记要把此处的事件清除,因为这两个事件重叠了,可能到时候会导致一些莫名的bug
  557. this.ipagination.current = current;
  558. this.ipagination.pageSize= pageSize;
  559. }
  560. },
  561. }
  562. },
  563. mixins: [JeecgListMixin],
  564. components: {
  565. selectComponent,
  566. Treeselect,
  567. DatePicker,
  568. customColumn,
  569. },
  570. watch:{
  571. },
  572. methods: {
  573. ...mapGetters(['userInfo']),
  574. filterOption(input, option) {
  575. return (
  576. option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
  577. );
  578. },
  579. //点击查看明细按钮的事件
  580. opendetail(text, record) {
  581. console.log(text, record)
  582. this.visibleDetail = true
  583. this.detailData = []
  584. this.detailLoading=true;
  585. this.signature=record.signature
  586. // console.log(this.signature)
  587. postAction('/ctop/kuaishou/videoReport/detail', {
  588. startDate: this.dateValue[0].format('YYYY-MM-DD'),
  589. endDate: this.dateValue[1].format('YYYY-MM-DD'),
  590. signature: record.signature,
  591. accountIds:this.appId
  592. }).then(res => {
  593. console.log(res)
  594. this.detailLoading=false;
  595. if (res.success) {
  596. let result = res.result
  597. // this.detailData.push({ ...result, key: 1 })
  598. result.map((item, index) => {
  599. item.key = index
  600. })
  601. this.detailData = result
  602. console.log(this.detailData, 'detail----detail');
  603. }
  604. })
  605. },
  606. closeCustomColumn(){
  607. this.visible=false;
  608. },
  609. //自定义之后修改父元素表头
  610. changeColumn(val){
  611. console.log(val)
  612. this.columns=[...val];
  613. if(this.columns.length> this.columnsFixd.length&&this.columns.length<9){
  614. this.scrollX=0;
  615. this.columns.forEach((element,index) => {
  616. if(index<this.columnsFixd.length){
  617. element.width='auto'
  618. element.fixed=false
  619. }
  620. });
  621. // this.scrollX=2000+200*(this.columns.length-this.columnsFixd.length)
  622. }else if(this.columns.length>=9){
  623. this.columns.forEach((element,index) => {
  624. if(index<this.columnsFixd.length-1){
  625. element.width=120
  626. element.fixed='left'
  627. }
  628. });
  629. this.scrollX=1000+200*(this.columns.length-this.columnsFixd.length)
  630. } else{
  631. this.scrollX=0;
  632. this.columns.forEach(element => {
  633. element.width='auto'
  634. element.fixed=false
  635. });
  636. }
  637. },
  638. // 日期的开关
  639. //打开日期框
  640. opendate(){
  641. this.openOptions=!this.openOptions;
  642. // console.log(this.openOptions)
  643. },
  644. opendateClose(){
  645. this.openOptions=false;
  646. // console.log(this.openOptions)
  647. },
  648. // 查看相关人员
  649. showRelevantPeople(record){
  650. this.relevantPeopleVisible=true;
  651. console.log(record)
  652. getAction('/ctop/materialAscription/getDetail',{
  653. code:record.signature
  654. }).then(res=>{
  655. console.log(res);
  656. this.relevantPeopleData=[];
  657. if(res.result&&res.success){
  658. this.relevantPeopleData=res.result
  659. }
  660. })
  661. },
  662. sort(pagination, filters, sorter, { currentDataSource }){
  663. console.log(pagination, filters, sorter)
  664. this.ipagination.current=pagination.current;
  665. this.ipagination.pageSize=pagination.pageSize
  666. if(sorter.order == 'ascend'){
  667. this.order='asc'
  668. this.target=sorter.columnKey;
  669. }else if(sorter.order == 'descend'){
  670. this.order='desc'
  671. this.target=sorter.columnKey;
  672. }else{
  673. this.target='cost',
  674. this.order='desc'
  675. }
  676. this.HttpPost();
  677. },
  678. moment,
  679. //select切换---项目
  680. selectChange(key){
  681. this.selectValue=key;
  682. },
  683. //打开视频
  684. openVideo(val) {
  685. this.Videovisible = true
  686. this.videoUrl = val
  687. },
  688. videoOk() {
  689. this.Videovisible = false
  690. },
  691. disabledDate(current) {
  692. // console.log(current)
  693. return current && current > moment().subtract(1, 'day')
  694. },
  695. consumeOnChange() {},
  696. //查询按钮
  697. searchRes() {
  698. this.date = []
  699. this.ipagination.current=1
  700. this.HttpPost()
  701. },
  702. //网络请求table数据函数
  703. HttpPost(){
  704. this.loading=true;
  705. this.searchLoading=true
  706. show = 0
  707. postAction('/ctop/kuaishou/videoReport/list', {
  708. userId:this.userInfo().id,
  709. startDate: this.dateValue[0].format('YYYY-MM-DD'),
  710. endDate: this.dateValue[1].format('YYYY-MM-DD'),
  711. pageNo:this.ipagination.current,
  712. pageSize:this.ipagination.pageSize,
  713. accountIds:this.appId,
  714. target:this.target,
  715. order:this.order,
  716. clipId:this.clip?this.clip:'',
  717. shotId:this.shot?this.shot:'',
  718. planId:this.plan?this.plan:'',
  719. leaderId:this.leaderId?this.leaderId:'',
  720. channelType: this.material ? Number(this.material) : ''
  721. }).then(res => {
  722. let resArr = []
  723. this.data=[];
  724. this.loading = false;
  725. this.searchLoading=false;
  726. if (res.success) {
  727. // let result = res.result
  728. // this.data.push({ ...result, key: 1 })
  729. // result.map((item, index) => {
  730. // item.key = index
  731. // })
  732. this.data = res.result.list.map((item,index)=>{
  733. return {
  734. ...item,
  735. key:index
  736. }
  737. })
  738. this.ipagination.total = res.result.total
  739. this.loading = false
  740. }else{
  741. this.loading = false
  742. }
  743. })
  744. },
  745. //导出报表
  746. exportExcel(exportType) {
  747. this.exportLoading=true;
  748. let columns=[]
  749. if(exportType=='exportTable'){
  750. let column = this.columns.map((item, index) => {
  751. return item.dataIndex
  752. })
  753. columns=column.splice(this.columnsFixd.length)
  754. }
  755. downFilePost('/ctop/kuaishou/videoReport/excelV2', {
  756. columns,
  757. userId:this.userInfo().id,
  758. target:this.target,
  759. order:this.order,
  760. startDate: this.dateValue[0].format('YYYY-MM-DD'),
  761. endDate: this.dateValue[1].format('YYYY-MM-DD'),
  762. accountIds:this.appId,
  763. exportType,
  764. signature: this.signature,
  765. clipId:this.clip?this.clip:'',
  766. shotId:this.shot?this.shot:'',
  767. planId:this.plan?this.plan:'',
  768. leaderId:this.leaderId?this.leaderId:'',
  769. channelType: this.material ? Number(this.material) : ''
  770. }).then(res => {
  771. this.exportLoading=false;
  772. let blob = new Blob([res], {
  773. type:'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
  774. })
  775. let downloadElement = document.createElement('a')
  776. let href = window.URL.createObjectURL(blob) //创建下载的链接
  777. downloadElement.href = href
  778. downloadElement.download = `${this.dateValue[0].format('YYYY-MM-DD')}~${this.dateValue[1].format('YYYY-MM-DD')}视频汇总.xlsx` //下载后文件名
  779. document.body.appendChild(downloadElement)
  780. downloadElement.click() //点击下载
  781. document.body.removeChild(downloadElement) //下载完成移除元素
  782. window.URL.revokeObjectURL(href) //释放掉blob对象
  783. })
  784. },
  785. //日期选择回调
  786. dateChange(data, dataString) {
  787. if (data.length) {
  788. this.timedata = dataString
  789. this.dateRange[0] = data[0]
  790. this.totalSelect = (data[1]._d - data[0]._d) / (24 * 60 * 60 * 1000) + 1
  791. this.daysFlag = true
  792. if (this.totalSelect > 92) {
  793. this.$message.error('时间跨度太长啦,选小一点好嘛?')
  794. this.daysFlag = false
  795. this.dateRange = []
  796. }
  797. } else {
  798. this.daysFlag = false
  799. this.dateRange = []
  800. }
  801. },
  802. //弹出框打开,自定义列
  803. customColumns() {
  804. this.visible = true
  805. this.listNum = [...this.columns]
  806. console.log(this.listNum, 'this.listNum-this.listNum');
  807. },
  808. tableHandle() {
  809. // this.listNum = [...this.columns]
  810. // console.log(this.listNum.length, this.columns)
  811. // if (this.listNum.length >= 9 || this.columns.length >= 9) {
  812. // this.tableWidth = 160
  813. // this.scrollX = this.columns.length * 160
  814. // // console.log(this.scrollX)
  815. // } else {
  816. // this.scrollX = 2000
  817. // }
  818. },
  819. //弹出框确定
  820. handleOk(e) {
  821. this.loading = false
  822. this.visible = false
  823. if (this.listNum.length >= 10) {
  824. let newlist = this.listNum.slice(columnsFixd.length)
  825. console.log(newlist)
  826. this.columns = [...columnsFixd, ...newlist]
  827. } else {
  828. this.columns = [...this.listNum]
  829. }
  830. if (this.listNum.length == 4) {
  831. // console.log(this.listNum.length)
  832. this.scrollX = 0
  833. this.columns.map((item, index) => {
  834. item.width = 500
  835. })
  836. // console.log(1)
  837. } else {
  838. this.columns.map((item, index) => {
  839. if (index == 2 || index == 0) {
  840. item.width = 150
  841. } else if (index == 1 || index == 2) {
  842. item.width = 100
  843. }
  844. })
  845. // console.log(2)
  846. }
  847. this.tableHandle()
  848. },
  849. //弹出框取消按钮
  850. handleCancel(e) {
  851. this.visible = false
  852. },
  853. loadShow(){
  854. show++
  855. if(this.data.length>0){
  856. if(show == (this.data.length*2)){
  857. this.data = [...this.data]
  858. }
  859. }
  860. },
  861. // 获取设计人员
  862. getDesignList(){
  863. postAction('/ctop/kuaishou/videoReport/getDesignList').then(res=>{
  864. console.log(res, '设计人员');
  865. if(res.success){
  866. this.designList=res.result
  867. }
  868. })
  869. }
  870. },
  871. activated() {
  872. console.log('activated')
  873. // this.getParticipateList()
  874. this.statDate = moment().subtract(1, 'day')
  875. moment().format('YYYY-MM-DD_HH:mm')
  876. postAction('/toutiao/videoReportDaily/getColumnJson', {
  877. columnType: 4
  878. }).then(res => {
  879. console.log(res, 'activated--activated')
  880. if (res.success) {
  881. console.log(JSON.parse(res.result), '-------')
  882. if(res.result){
  883. let columns = JSON.parse(res.result)
  884. if (columns.length) {
  885. if (columns.length >= columnsFixd.length) {
  886. columns.map((item, index) => {
  887. if (index > columnsFixd.length - 1) {
  888. item.sorter = function(a, b) {
  889. }
  890. }
  891. })
  892. columns = columns.slice(columnsFixd.length)
  893. this.columns = [...columnsFixd, ...columns]
  894. // this.tableHandle()
  895. }
  896. // console.log(this.columns)
  897. }
  898. }
  899. this.changeColumn(this.columns)
  900. }
  901. })
  902. },
  903. // deactivated() {
  904. // let arr = JSON.stringify(this.columns)
  905. // console.log(arr)
  906. // postAction('/toutiao/videoReportDaily/saveOrUpdateColumnJson', {
  907. // json: arr,
  908. // columnType: 4
  909. // }).then(res => {
  910. // // console.log(res)
  911. // })
  912. // },
  913. beforeDestroy() {
  914. let arr = JSON.stringify(this.columns)
  915. console.log(arr)
  916. postAction('/toutiao/videoReportDaily/saveOrUpdateColumnJson', {
  917. json: arr,
  918. columnType: 4
  919. }).then(res => {
  920. // console.log(res)
  921. })
  922. },
  923. filters: {
  924. toshowTime(val) {
  925. // console.log(val, this.timedata)
  926. // return this.timedata[0] + '~' + this.timedata[1]
  927. return val
  928. },
  929. toPercentage(val) {
  930. if(val){
  931. if(typeof val != 'string'){
  932. return (val * 100).toFixed(2) + '%'
  933. }else{
  934. return val
  935. }
  936. }else if(typeof val =='string'){
  937. return val
  938. }
  939. else{
  940. return 0
  941. }
  942. },
  943. //保留两位小数并且变成货币格式
  944. decimalsHandle(val){
  945. // console.log(val)
  946. if(val && typeof val !='string'){
  947. if(val>=0){
  948. val=parseFloat(val).toFixed(2);
  949. let numberStr = val.toString()
  950. let str = numberStr.split('.')
  951. let str0=str[0].split('').reverse();
  952. for (let i = 0; i < str0.length; i++) {
  953. if ((i + 1) % 4 === 0) {
  954. str0.splice(i, 0, ',')
  955. }
  956. }
  957. str0.reverse()
  958. let handleResult = ''
  959. for (let j = 0; j < str0.length; j++) {
  960. handleResult += str0[j]
  961. }
  962. return handleResult+'.'+str[1]
  963. }else{
  964. val=parseFloat(val).toFixed(2);
  965. let numberStr = val.toString()
  966. let str = numberStr.split('.')
  967. let str0=str[0].substr(1).split('').reverse();
  968. for (let i = 0; i < str0.length; i++) {
  969. if ((i + 1) % 4 === 0) {
  970. str0.splice(i, 0, ',')
  971. }
  972. }
  973. str0.reverse()
  974. let handleResult = ''
  975. for (let j = 0; j < str0.length; j++) {
  976. handleResult += str0[j]
  977. }
  978. return '-'+handleResult+'.'+str[1]
  979. }
  980. }else if(typeof val =='string'){
  981. return val
  982. }
  983. else{
  984. return 0
  985. }
  986. },
  987. //变成货币格式
  988. formatCurrency(val){
  989. if((val||val==0)&& typeof val !='string'){
  990. let numberStr = val.toString()
  991. let str = numberStr.split('').reverse()
  992. for (let i = 0; i < str.length; i++) {
  993. if ((i + 1) % 4 === 0) {
  994. str.splice(i, 0, ',')
  995. }
  996. }
  997. str.reverse()
  998. let handleResult = ''
  999. for (let j = 0; j < str.length; j++) {
  1000. handleResult += str[j]
  1001. }
  1002. return handleResult
  1003. }else if(typeof val =='string'){
  1004. return val
  1005. }
  1006. else{
  1007. return '-'
  1008. }
  1009. }
  1010. },
  1011. mounted() {
  1012. this.getDesignList()
  1013. //请求自定义列的数据
  1014. postAction('/toutiao/videoReportDaily/videoInfoListTotalExportExcelPermission').then(res => {
  1015. console.log(res, 'mounted-mounted')
  1016. if (res.success) {
  1017. if (res.result) {
  1018. this.exportExcelIsOk = true
  1019. } else {
  1020. this.exportExcelIsOk = false
  1021. }
  1022. }
  1023. })
  1024. //进入页面默认展示昨天到今天的数据
  1025. this.dateRange=[moment().subtract(7,'days'),moment()]
  1026. this.timedata=[moment().subtract(7,'days').format('YYYY-MM-DD'),moment().format('YYYY-MM-DD')]
  1027. // this.loading=true;
  1028. this.HttpPost()
  1029. postAction('/toutiao/videoReportDaily/getColumnJson', {
  1030. columnType: 4
  1031. }).then(res => {
  1032. // console.log(res)
  1033. if (res.success) {
  1034. // console.log(JSON.parse(res.result))
  1035. if(res.result){
  1036. let columns = JSON.parse(res.result)
  1037. if (columns.length) {
  1038. if (columns.length >= columnsFixd.length) {
  1039. columns.map((item, index) => {
  1040. if (index > columnsFixd.length - 1) {
  1041. item.sorter = function(a, b) {
  1042. }
  1043. }
  1044. })
  1045. columns = columns.slice(columnsFixd.length)
  1046. this.columns = [...columnsFixd, ...columns]
  1047. // this.tableHandle()
  1048. }
  1049. // console.log(this.columns)
  1050. }
  1051. }
  1052. this.changeColumn(this.columns)
  1053. }
  1054. })
  1055. }
  1056. }
  1057. </script>
  1058. <style lang="less">
  1059. // .ant-table .ant-table-fixed-left .ant-table-thead {
  1060. // height: 108px !important ;
  1061. // }
  1062. .vsummary{
  1063. .ant-table .ant-table-thead .ant-table-header-column .ant-table-column-title {
  1064. // display:block;
  1065. white-space: normal;
  1066. word-break: break-all;
  1067. }
  1068. }
  1069. </style>
  1070. <style lang="scss" scoped>
  1071. .vsummary {
  1072. width: 100%;
  1073. height: 100%;
  1074. background: white;
  1075. padding: 15px 30px;
  1076. .tableBox{
  1077. background-color: #fff;
  1078. margin: 15px 0px;
  1079. padding: 15px 0px;
  1080. .tableTop{
  1081. position: relative;
  1082. padding-bottom: 15px;
  1083. border-bottom: 1px solid #e0e0e0;
  1084. .selectTime{
  1085. margin-right: 20px;
  1086. }
  1087. .add{
  1088. position: absolute;
  1089. top: 0;
  1090. right: 0;
  1091. }
  1092. }
  1093. }
  1094. }
  1095. .xiangmuxuanze{
  1096. margin-bottom: 20px;
  1097. display: flex;
  1098. align-items: center;
  1099. }
  1100. .timeDiv {
  1101. display: flex;
  1102. justify-content: space-between;
  1103. }
  1104. span {
  1105. margin-left: 5px;
  1106. }
  1107. .myinput {
  1108. width: 40%;
  1109. }
  1110. .addlist {
  1111. float: left;
  1112. width: 70%;
  1113. border: 1px solid #eee;
  1114. .selectionList {
  1115. padding: 10px 15px;
  1116. height: 450px;
  1117. overflow: auto;
  1118. .leibie {
  1119. .leiName {
  1120. font-size: 26px;
  1121. text-align: left;
  1122. }
  1123. }
  1124. .jutixiang {
  1125. display: inline-block;
  1126. width: 32%;
  1127. box-sizing: border-box;
  1128. padding: 10px 3px;
  1129. }
  1130. }
  1131. }
  1132. .listNum {
  1133. float: right;
  1134. width: 28%;
  1135. border: 1px solid #eee;
  1136. position: relative;
  1137. }
  1138. .zhuti {
  1139. margin-top: 15px;
  1140. overflow: hidden;
  1141. p {
  1142. height: 40px;
  1143. line-height: 20px;
  1144. padding: 10px 15px;
  1145. background: rgb(249, 250, 253);
  1146. border-bottom: 1px solid #eee;
  1147. }
  1148. #btn {
  1149. position: absolute;
  1150. right: 0;
  1151. top: 5px;
  1152. }
  1153. .selectlist {
  1154. width: 100%;
  1155. list-style: none;
  1156. margin: 0;
  1157. height: 450px;
  1158. padding: 0 15px 10px;
  1159. overflow: auto;
  1160. li {
  1161. width: 100%;
  1162. padding: 5px 8px;
  1163. margin: 6px 0;
  1164. border-radius: 10px;
  1165. background: rgb(248, 248, 248);
  1166. height: 32px;
  1167. position: relative;
  1168. span {
  1169. width: 80%;
  1170. height: 100%;
  1171. display: inline-block;
  1172. margin: 0 10px;
  1173. // overflow:hidden;
  1174. // text-overflow:ellipsis;
  1175. // white-space: nowrap;
  1176. }
  1177. .listText {
  1178. position: absolute;
  1179. top: 2;
  1180. left: 10;
  1181. width: 40%;
  1182. overflow: hidden;
  1183. white-space: nowrap;
  1184. text-overflow: ellipsis;
  1185. }
  1186. #closeStyle {
  1187. position: absolute;
  1188. top: 9px;
  1189. right: 7px;
  1190. }
  1191. }
  1192. }
  1193. }
  1194. #mybtn {
  1195. margin: 0 10px 15px 0;
  1196. }
  1197. </style>