index.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456
  1. <template>
  2. <div class="program">
  3. <el-card class="box-card">
  4. <el-form
  5. :model="form"
  6. size="small"
  7. :inline="true"
  8. label-width="120px"
  9. class="demo-form-inline"
  10. >
  11. <el-form-item>
  12. <template v-for="item in pListData" :key="item.platform">
  13. <el-button
  14. :class="
  15. 'colorBtn ' +
  16. btnGroup[item.platform].class +
  17. (form.platform == item.platform
  18. ? ' ' + btnGroup[item.platform].class + 'act'
  19. : '')
  20. "
  21. @click="() => tabChange(item)"
  22. >
  23. <span v-if="item.platform === '微信'" class="icon iconfont"
  24. >&#xe603;</span
  25. >
  26. <span
  27. v-if="item.platform === '微博'"
  28. class="icon iconfont weiboIcon1"
  29. >&#xe67a;</span
  30. >
  31. <span v-if="item.platform === '快手'" class="icon iconfont"
  32. >&#xe8dc;</span
  33. >
  34. <span v-if="item.platform === '抖音'" class="icon iconfont"
  35. >&#xe8db;</span
  36. >
  37. <span v-if="item.platform === 'B站'" class="icon iconfont"
  38. >&#xe61e;</span
  39. >
  40. <span v-if="item.platform === '头条'" class="icon iconfont"
  41. >&#xe607;</span
  42. >
  43. {{ item.platform }}
  44. </el-button>
  45. </template>
  46. </el-form-item>
  47. <el-form-item label="日期">
  48. <el-date-picker
  49. v-model="form.dt"
  50. type="daterange"
  51. start-placeholder="开始时间"
  52. end-placeholder="结束时间"
  53. :disabled-date="time => disabledDate(time)"
  54. placeholder="日期"
  55. >
  56. </el-date-picker>
  57. </el-form-item>
  58. <el-form-item label="关键词">
  59. <el-input v-model="form.match" placeholder="检索关键词" clearable />
  60. </el-form-item>
  61. <el-form-item style="float: right">
  62. <el-button type="primary" @click="onSubmit" :loading="load">
  63. 查询
  64. </el-button>
  65. <el-button type="primary" @click="onExport">导出</el-button>
  66. </el-form-item>
  67. </el-form>
  68. </el-card>
  69. <br />
  70. <el-card class="box-card">
  71. <el-tabs v-model="activeTab" class="demo-tabs">
  72. <el-tab-pane label="传播数据" name="agg">
  73. <el-table
  74. :header-cell-style="{
  75. backgroundColor: '#f4f5f7',
  76. color: '#606266',
  77. }"
  78. ref="table1"
  79. align="center"
  80. :data="tableData"
  81. empty-text="暂无数据"
  82. style="width: 100%"
  83. @sort-change="sort_change"
  84. >
  85. <template v-for="(item, i) in agg" :key="i">
  86. <el-table-column
  87. align="center"
  88. :width="item.width"
  89. show-overflow-tooltip
  90. :prop="item.key"
  91. :label="item.label"
  92. :sortable="item.sortable"
  93. :sort-orders="
  94. item.sortable ? ['ascending', 'descending', null] : []
  95. "
  96. >
  97. <template #default="scope">
  98. {{
  99. item.type == 'number'
  100. ? formatter(scope.row[item.key])
  101. : scope.row[item.key]
  102. }}
  103. </template>
  104. </el-table-column>
  105. </template>
  106. </el-table>
  107. </el-tab-pane>
  108. <el-tab-pane label="稿件数据" name="list">
  109. <el-table
  110. :header-cell-style="{
  111. backgroundColor: '#f4f5f7',
  112. color: '#606266',
  113. }"
  114. ref="table2"
  115. align="center"
  116. empty-text="暂无数据"
  117. :data="tableList"
  118. style="width: 100%"
  119. @sort-change="sort_change"
  120. >
  121. <template v-for="(item, i) in list" :key="i">
  122. <el-table-column
  123. align="center"
  124. :width="item.width"
  125. show-overflow-tooltip
  126. :prop="item.key"
  127. :label="item.label"
  128. :sortable="item.sortable"
  129. :sort-orders="
  130. item.sortable ? ['ascending', 'descending', null] : []
  131. "
  132. >
  133. <template #default="scope">
  134. {{
  135. item.type == 'number'
  136. ? formatter(scope.row[item.key])
  137. : scope.row[item.key]
  138. }}
  139. </template>
  140. </el-table-column>
  141. </template>
  142. </el-table>
  143. <br />
  144. <el-pagination
  145. @current-change="cChange"
  146. background
  147. :page-size="pagesize || 10"
  148. layout="prev, pager, next"
  149. :total="total"
  150. />
  151. <br />
  152. </el-tab-pane>
  153. </el-tabs>
  154. </el-card>
  155. </div>
  156. </template>
  157. <script>
  158. // @ is an alias to /src
  159. const ElLoading = require('element-plus/lib/el-loading/index');
  160. import 'element-plus/lib/theme-chalk/el-loading.css';
  161. import { platformList, platformlistData, platform } from '@/api/index';
  162. import { formatter } from '@/utils/tool';
  163. import config from '@/config/index';
  164. let tableDataListOri = [];
  165. let sort = null;
  166. let sortLib = null;
  167. export default {
  168. name: 'RealData',
  169. data() {
  170. return {
  171. btnGroup: {
  172. 微信: {
  173. color: '#1cc393',
  174. class: 'weixin',
  175. },
  176. 微博: {
  177. color: '#ffb712',
  178. class: 'weibo',
  179. },
  180. 快手: {
  181. color: '#ffb712',
  182. class: 'kuaishou',
  183. },
  184. 抖音: {
  185. color: '#170b1a',
  186. class: 'douyin',
  187. },
  188. 头条: {
  189. color: '#de0517',
  190. class: 'toutiao',
  191. },
  192. B站: {
  193. color: '#ffb712',
  194. class: 'bzhan',
  195. },
  196. },
  197. page: 0,
  198. pagesize: 20,
  199. total: 0,
  200. load: false,
  201. activeTab: 'agg',
  202. form: {
  203. platform: '',
  204. dt: [],
  205. match: '',
  206. },
  207. formRael: { platform: '', dt: [] },
  208. tableData: [],
  209. pListData: [],
  210. };
  211. },
  212. mounted() {
  213. platformList().then(res => {
  214. const first = res[0] || { platform: '', dt: '' };
  215. this.form = {
  216. dt: [first.dt, first.dt],
  217. platform: first.platform,
  218. };
  219. this.formRael = {
  220. dt: [first.dt, first.dt],
  221. platform: first.platform || '',
  222. };
  223. this.pListData = res || [];
  224. this.onSubmit();
  225. });
  226. },
  227. computed: {
  228. agg() {
  229. if (!this.formRael.platform) return [];
  230. return config.tableCol.agg[this.formRael.platform];
  231. },
  232. list() {
  233. if (!this.formRael.platform) return [];
  234. return config.tableCol.list[this.formRael.platform];
  235. },
  236. tableList() {
  237. const out = [];
  238. for (
  239. let i = (this.page - 1) * this.pagesize;
  240. i < this.page * this.pagesize;
  241. i++
  242. ) {
  243. const v = tableDataListOri[i];
  244. v && out.push(v);
  245. }
  246. return out;
  247. },
  248. },
  249. methods: {
  250. formatter,
  251. tabChange(item) {
  252. let p = {
  253. platform: item.platform,
  254. dt: this.form.dt,
  255. match: this.form.match,
  256. };
  257. if (new Date(item.dt) - new Date(p.dt) < 0) p.dt = item.dt;
  258. this.form = p;
  259. this.$refs.table1.clearSort();
  260. this.$refs.table2.clearSort();
  261. sortLib = null;
  262. sort = null;
  263. this.onSubmit();
  264. },
  265. cChange(num) {
  266. this.page = num;
  267. },
  268. onExport() {
  269. if (!this.formRael.dt || this.formRael.dt.length != 2) return;
  270. const startd = this.dateFormat(this.formRael.dt[0] || 0);
  271. const starte = this.dateFormat(this.formRael.dt[1] || 0);
  272. let url =
  273. config.base.url2 +
  274. '/new-media/export?start=' +
  275. [startd.year, startd.month, startd.day].join('-') +
  276. '&end=' +
  277. [starte.year, starte.month, starte.day].join('-');
  278. if (this.formRael.sort) url += '&sort=' + this.formRael.sort;
  279. window.open(url);
  280. },
  281. disabledDate(time) {
  282. return time.getTime() > Date.now() - 86400000;
  283. },
  284. sort_change(type) {
  285. sort = type.prop;
  286. sortLib = type.order;
  287. this.onSubmit();
  288. },
  289. onSubmit() {
  290. const data = this.formatListData();
  291. this.page = 0;
  292. this.tableData = [];
  293. this.total = 0;
  294. this.load = true;
  295. const l = ElLoading.default.service();
  296. Promise.all([platform(data), platformlistData(data)])
  297. .then(list => {
  298. this.formRael = data;
  299. this.formRael.dt = [this.formRael.start, this.formRael.end];
  300. this.tableData = (list[0] || []).map((v, i) => {
  301. v.index = i + 1;
  302. return v;
  303. });
  304. tableDataListOri = (list[1] || []).map((v, i) => {
  305. v.index = i + 1;
  306. return v;
  307. });
  308. this.total = tableDataListOri.length;
  309. this.page = this.page + 1;
  310. this.load = false;
  311. l.close();
  312. })
  313. .catch(() => {
  314. this.load = false;
  315. l.close();
  316. });
  317. },
  318. dateFormat(date) {
  319. let D = new Date(date);
  320. let m = D.getMonth() + 1;
  321. let d = D.getDate();
  322. let h = D.getHours();
  323. let M = D.getMinutes();
  324. let s = D.getSeconds();
  325. m > 9 ? m : (m = '0' + m);
  326. d > 9 ? d : (d = '0' + d);
  327. h > 9 ? h : (h = '0' + h);
  328. M > 9 ? M : (M = '0' + M);
  329. s > 9 ? s : (s = '0' + s);
  330. return {
  331. year: D.getFullYear(),
  332. month: m,
  333. day: d,
  334. hour: h,
  335. minutes: M,
  336. seconds: s,
  337. };
  338. },
  339. formatListData() {
  340. const startd = this.form.dt[0] ? this.dateFormat(this.form.dt[0]) : false;
  341. const starte = this.form.dt[1] ? this.dateFormat(this.form.dt[1]) : false;
  342. const loginname = JSON.parse(
  343. window.parent.localStorage.userinfo || '{}'
  344. ).loginname;
  345. const p = {
  346. platform: this.form.platform || this.pListData[0],
  347. start: startd
  348. ? [startd.year, startd.month, startd.day].join('-')
  349. : undefined,
  350. end: starte
  351. ? [starte.year, starte.month, starte.day].join('-')
  352. : undefined,
  353. match: this.form.match,
  354. userId: loginname,
  355. };
  356. sort && (p.sort = sort);
  357. const sortLibType = {
  358. descending: 1,
  359. ascending: 0,
  360. };
  361. sortLib && (p.order = sortLibType[sortLib]);
  362. return p;
  363. },
  364. },
  365. components: {},
  366. };
  367. </script>
  368. <style>
  369. .colorBtn {
  370. background-color: #fff;
  371. color: #000;
  372. padding: 0 18px;
  373. width: 8em;
  374. height: 38px;
  375. line-height: 38px;
  376. font-size: 14px;
  377. }
  378. .weibo .icon {
  379. color: #ffb712;
  380. }
  381. .weiboact,
  382. .weibo:hover,
  383. .weibo:focus,
  384. .weiboact .icon,
  385. .weibo:hover .icon {
  386. background-color: #ffb712;
  387. border-color: #ffb712;
  388. color: #fff;
  389. }
  390. .toutiao .icon {
  391. color: #f04142;
  392. }
  393. .toutiaoact,
  394. .toutiao:hover,
  395. .toutiao:focus,
  396. .toutiaoact .icon,
  397. .toutiao:hover .icon {
  398. background-color: #f04142;
  399. border-color: #f04142;
  400. color: #fff;
  401. }
  402. .weixin .icon {
  403. color: #1cc393;
  404. }
  405. .weixinact,
  406. .weixin:hover,
  407. .weixin:focus,
  408. .weixinact .icon,
  409. .weixin:hover .icon {
  410. background-color: #1cc393;
  411. border-color: #1cc393;
  412. color: #fff;
  413. }
  414. .kuaishou .icon {
  415. color: #eb3661;
  416. }
  417. .kuaishouact,
  418. .kuaishou:hover,
  419. .kuaishou:focus,
  420. .kuaishou:focus,
  421. .kuaishouact .icon,
  422. .kuaishou:hover .icon {
  423. background-color: #eb3661;
  424. border-color: #eb3661;
  425. color: #fff;
  426. }
  427. .douyin .icon {
  428. color: #170b1a;
  429. }
  430. .douyinact,
  431. .douyin:hover,
  432. .douyin:focus,
  433. .douyinact .icon,
  434. .douyin:hover .icon {
  435. background-color: #170b1a;
  436. border-color: #170b1a;
  437. color: #fff;
  438. }
  439. .bzhan .icon {
  440. color: #fb7299;
  441. }
  442. .bzhanact,
  443. .bzhan:hover,
  444. .bzhan:focus,
  445. .bzhanact .icon,
  446. .bzhan:hover .icon {
  447. background-color: #fb7299;
  448. border-color: #fb7299;
  449. color: #fff;
  450. }
  451. </style>