convergence.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456
  1. <template>
  2. <div class="convergence">
  3. <el-form :inline="true" :model="condition" size="large">
  4. <el-form-item prop="platform">
  5. <el-button
  6. v-for="(item, index) in btns"
  7. :class="{
  8. [item.platform]: true,
  9. [item.platform + '_active']: condition.platform === index,
  10. }"
  11. :key="item.id"
  12. @click="() => selectPlatform(item, index)"
  13. >
  14. <span
  15. :class="{ icon: true, iconfont: true, [item.class]: true }"
  16. style="margin-right: 5px"
  17. >
  18. </span>
  19. {{ item.text }}
  20. </el-button>
  21. </el-form-item>
  22. <br />
  23. <el-form-item label="日期" prop="dt">
  24. <el-date-picker
  25. v-model="condition.dt"
  26. type="daterange"
  27. start-placeholder="开始时间"
  28. end-placeholder="结束时间"
  29. />
  30. </el-form-item>
  31. <el-form-item label="关键词" prop="keyword">
  32. <el-input v-model="condition.keyword" placeholder="请输入关键词" />
  33. </el-form-item>
  34. <el-form-item>
  35. <el-button type="primary" @click="onSubmit">查询</el-button>
  36. <el-button type="primary" @click="onExport">导出</el-button>
  37. <el-button type="primary" @click="binding">绑定账号</el-button>
  38. </el-form-item>
  39. </el-form>
  40. <br />
  41. <el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick">
  42. <el-tab-pane label="传播数据" name="T1">
  43. <el-table
  44. :data="disseminateData.list"
  45. style="width: 100%"
  46. :header-cell-style="{
  47. backgroundColor: '#f4f5f7',
  48. color: '#606266',
  49. }"
  50. ref="table1"
  51. align="center"
  52. empty-text="暂无数据"
  53. @sort-change="e => sort_change(e, 'disseminate')"
  54. >
  55. <template
  56. v-for="(item, i) in config.tableCol.agg[
  57. btns[condition.platform].text
  58. ]"
  59. :key="i"
  60. >
  61. <el-table-column
  62. align="center"
  63. :width="item.width"
  64. show-overflow-tooltip
  65. :prop="item.key"
  66. :label="item.label"
  67. :sortable="item.sortable"
  68. :sort-orders="
  69. item.sortable ? ['ascending', 'descending', null] : []
  70. "
  71. >
  72. <template #default="scope">
  73. {{
  74. item.type == 'number'
  75. ? formatter(scope.row[item.key])
  76. : scope.row[item.key]
  77. }}
  78. </template>
  79. </el-table-column>
  80. </template>
  81. </el-table>
  82. <el-pagination
  83. @current-change="e => changePageDisseminate(e)"
  84. background
  85. layout="prev, pager, next"
  86. :page-count="
  87. Math.ceil(disseminateData.total / condition.disseminate.size) || 1
  88. "
  89. />
  90. </el-tab-pane>
  91. <el-tab-pane label="稿件数据" name="T2">
  92. <el-table
  93. :data="manuscriptData.list"
  94. style="width: 100%"
  95. :header-cell-style="{
  96. backgroundColor: '#f4f5f7',
  97. color: '#606266',
  98. }"
  99. ref="table1"
  100. align="center"
  101. empty-text="暂无数据"
  102. @sort-change="e => sort_change(e, 'manuscript')"
  103. >
  104. <template
  105. v-for="(item, i) in config.tableCol.list[
  106. btns[condition.platform].text
  107. ]"
  108. :key="i"
  109. >
  110. <el-table-column
  111. align="center"
  112. :width="item.width"
  113. show-overflow-tooltip
  114. :prop="item.key"
  115. :label="item.label"
  116. :sortable="item.sortable"
  117. :sort-orders="
  118. item.sortable ? ['ascending', 'descending', null] : []
  119. "
  120. >
  121. <template #default="scope">
  122. {{
  123. item.type == 'number'
  124. ? formatter(scope.row[item.key])
  125. : scope.row[item.key]
  126. }}
  127. </template>
  128. </el-table-column>
  129. </template>
  130. </el-table>
  131. <el-pagination
  132. @current-change="e => changePageManuscript(e)"
  133. background
  134. layout="prev, pager, next"
  135. :page-count="
  136. Math.ceil(manuscriptData.total / condition.manuscript.size) || 1
  137. "
  138. />
  139. </el-tab-pane>
  140. </el-tabs>
  141. </div>
  142. </template>
  143. <script setup>
  144. import { ref } from 'vue';
  145. import { getAccountList, getUpdateTime, getAccountData } from '@/api/index';
  146. import dayjs from 'dayjs';
  147. import config from '../../config/index';
  148. import { formatter } from '../../utils/tool';
  149. const condition = ref({
  150. platform: 0,
  151. keyword: '',
  152. dt: [],
  153. sort: '',
  154. order: '',
  155. manuscript: {
  156. page: 1,
  157. size: 10,
  158. },
  159. disseminate: {
  160. page: 1,
  161. size: 10,
  162. },
  163. });
  164. const activeName = ref('T1');
  165. const btns = [
  166. {
  167. text: '微博',
  168. platform: 'weibo',
  169. class: 'icon-weibo',
  170. },
  171. {
  172. text: '微信',
  173. platform: 'weixin',
  174. class: 'icon-weixin',
  175. },
  176. {
  177. text: '抖音',
  178. platform: 'douyin',
  179. class: 'icon-douyin',
  180. },
  181. {
  182. text: '快手',
  183. platform: 'kuaishou',
  184. class: 'icon-kuaishou',
  185. },
  186. {
  187. text: '头条',
  188. platform: 'jinritoutiao',
  189. class: 'icon-jinritoutiao',
  190. },
  191. {
  192. text: 'B站',
  193. platform: 'bzhan',
  194. class: 'icon-bzhan',
  195. },
  196. // {
  197. // text: '闪视频',
  198. // platform: 'ssp',
  199. // class: 'icon-ssp',
  200. // },
  201. // {
  202. // text: '头条',
  203. // platform: 'sxtt',
  204. // class: 'icon-sxtt',
  205. // },
  206. ];
  207. const manuscriptData = ref({ list: [], total: 0 });
  208. const disseminateData = ref({ list: [], total: 0 });
  209. let defaultTime = [];
  210. const selectPlatform = (item, index) => {
  211. condition.value.platform = index;
  212. for (let i = 0; i < defaultTime.length; i++) {
  213. const v = defaultTime[i];
  214. if (v.platform === item.text) {
  215. condition.value.dt = [v.dt, v.dt];
  216. break;
  217. }
  218. }
  219. // 页码和条数重置
  220. condition.value.sort = undefined;
  221. condition.value.order = undefined;
  222. condition.value.manuscript.page = 1;
  223. condition.value.manuscript.size = 10;
  224. condition.value.manuscript.total = 0;
  225. condition.value.disseminate.page = 1;
  226. condition.value.disseminate.size = 10;
  227. condition.value.disseminate.total = 0;
  228. getData();
  229. };
  230. const onSubmit = () => {
  231. getData();
  232. };
  233. const sort_change = (e, type) => {
  234. if (e.order) {
  235. condition.value.sort = e.prop;
  236. condition.value.order = e.order == 'descending' ? 1 : 0;
  237. } else {
  238. condition.value.sort = undefined;
  239. condition.value.order = undefined;
  240. }
  241. if (type == 'manuscript') changePageManuscript();
  242. else if (type == 'disseminate') changePageDisseminate();
  243. };
  244. const onExport = () => {
  245. if (!condition.value.dt || condition.value.dt.length != 2) return;
  246. let start = undefined;
  247. let end = undefined;
  248. if (condition.value.dt[0])
  249. start = dayjs(condition.value.dt[0]).format('YYYY-MM-DD');
  250. if (condition.value.dt[1])
  251. end = dayjs(condition.value.dt[1]).format('YYYY-MM-DD');
  252. let url =
  253. config.base.origin + '/new-media/export?start=' + start + '&end=' + end;
  254. if (condition.value.sort) url += '&sort=' + condition.value.sort;
  255. if (condition.value.order) url += '&order=' + condition.value.order;
  256. window.open(url);
  257. };
  258. const binding = () => {
  259. window.open(
  260. '#/authorization',
  261. 'newwindow',
  262. 'toolbar=no,location=no,resizable=no,height=550,width=750,scrollbars=yes,left=380,top=100'
  263. );
  264. };
  265. const handleClick = () => {};
  266. const getData = () => {
  267. let start = undefined;
  268. let end = undefined;
  269. if (condition.value.dt[0])
  270. start = dayjs(condition.value.dt[0]).format('YYYY-MM-DD');
  271. if (condition.value.dt[1])
  272. end = dayjs(condition.value.dt[1]).format('YYYY-MM-DD');
  273. getAccountList({
  274. data: {
  275. platform: btns[condition.value.platform].text,
  276. start,
  277. end,
  278. page: condition.value.manuscript.page,
  279. size: condition.value.manuscript.size,
  280. match: condition.value.keyword,
  281. sort: condition.value.sort,
  282. order: condition.value.order,
  283. },
  284. }).then(res => {
  285. const resData = res || { records: [], total: 0 };
  286. manuscriptData.value.list = resData.records;
  287. manuscriptData.value.total = resData.total;
  288. });
  289. getAccountData({
  290. data: {
  291. platform: btns[condition.value.platform].text,
  292. start,
  293. end,
  294. page: condition.value.disseminate.page,
  295. size: condition.value.disseminate.size,
  296. match: condition.value.keyword,
  297. sort: condition.value.sort,
  298. order: condition.value.order,
  299. },
  300. }).then(res => {
  301. const resData = res || { records: [], total: 0 };
  302. disseminateData.value.list = resData.records;
  303. disseminateData.value.total = resData.total;
  304. });
  305. };
  306. const changePageDisseminate = e => {
  307. if (e) condition.value.disseminate.page = e;
  308. let start = undefined;
  309. let end = undefined;
  310. if (condition.value.dt[0])
  311. start = dayjs(condition.value.dt[0]).format('YYYY-MM-DD');
  312. if (condition.value.dt[1])
  313. end = dayjs(condition.value.dt[1]).format('YYYY-MM-DD');
  314. getAccountData({
  315. data: {
  316. platform: btns[condition.value.platform].text,
  317. start,
  318. end,
  319. page: condition.value.disseminate.page,
  320. size: condition.value.disseminate.size,
  321. match: condition.value.keyword,
  322. sort: condition.value.sort,
  323. order: condition.value.order,
  324. },
  325. }).then(res => {
  326. const resData = res || { records: [], total: 0 };
  327. disseminateData.value.list = resData.records;
  328. disseminateData.value.total = resData.total;
  329. });
  330. // 切页
  331. };
  332. const changePageManuscript = e => {
  333. if (e) condition.value.manuscript.page = e;
  334. let start = undefined;
  335. let end = undefined;
  336. if (condition.value.dt[0])
  337. start = dayjs(condition.value.dt[0]).format('YYYY-MM-DD');
  338. if (condition.value.dt[1])
  339. end = dayjs(condition.value.dt[1]).format('YYYY-MM-DD');
  340. getAccountList({
  341. data: {
  342. platform: btns[condition.value.platform].text,
  343. start,
  344. end,
  345. page: condition.value.manuscript.page,
  346. size: condition.value.manuscript.size,
  347. match: condition.value.keyword,
  348. sort: condition.value.sort,
  349. order: condition.value.order,
  350. },
  351. }).then(res => {
  352. const resData = res || { records: [], total: 0 };
  353. manuscriptData.value.list = resData.records;
  354. manuscriptData.value.total = resData.total;
  355. });
  356. // 切页
  357. };
  358. getUpdateTime({ data: {} }).then(res => {
  359. defaultTime = res || [];
  360. for (let i = 0; i < btns.length; i++) {
  361. const v = btns[i];
  362. if (v.text === defaultTime[0].platform) {
  363. condition.value.dt = [defaultTime[0].dt, defaultTime[0].dt];
  364. break;
  365. }
  366. }
  367. getData();
  368. });
  369. </script>
  370. <style scoped>
  371. .convergence {
  372. height: 100%;
  373. overflow: auto;
  374. padding: 1em;
  375. }
  376. .convergence .platform {
  377. width: 8em;
  378. }
  379. .convergence .el-form {
  380. border-bottom: 1px solid #f3f3f3;
  381. }
  382. </style>
  383. <style>
  384. .convergence .el-form-item .weixin_active,
  385. .convergence .el-form-item .weixin:hover,
  386. .convergence .el-form-item .weixin:focus {
  387. background-color: #1cc393;
  388. border-color: #1cc393;
  389. color: #ffffff;
  390. }
  391. .convergence .el-form-item .weibo_active,
  392. .convergence .el-form-item .weibo:hover,
  393. .convergence .el-form-item .weibo:focus {
  394. background-color: #ffb712;
  395. border-color: #ffb712;
  396. color: #ffffff;
  397. }
  398. .convergence .el-form-item .kuaishou_active,
  399. .convergence .el-form-item .kuaishou:hover,
  400. .convergence .el-form-item .kuaishou:focus {
  401. background-color: #eb3661;
  402. border-color: #eb3661;
  403. color: #ffffff;
  404. }
  405. .convergence .el-form-item .douyin_active,
  406. .convergence .el-form-item .douyin:hover,
  407. .convergence .el-form-item .douyin:focus {
  408. background-color: #170b1a;
  409. border-color: #170b1a;
  410. color: #ffffff;
  411. }
  412. .convergence .el-form-item .bzhan_active,
  413. .convergence .el-form-item .bzhan:hover,
  414. .convergence .el-form-item .bzhan:focus {
  415. background-color: #fb7299;
  416. border-color: #fb7299;
  417. color: #ffffff;
  418. }
  419. .convergence .el-form-item .jinritoutiao_active,
  420. .convergence .el-form-item .jinritoutiao:hover,
  421. .convergence .el-form-item .jinritoutiao:focus {
  422. background-color: #f04142;
  423. border-color: #f04142;
  424. color: #ffffff;
  425. }
  426. .convergence .el-form-item .ssp_active,
  427. .convergence .el-form-item .ssp:hover,
  428. .convergence .el-form-item .ssp:focus {
  429. background-color: #c11616;
  430. border-color: #c11616;
  431. color: #ffffff;
  432. }
  433. .convergence .el-form-item .sxtt_active,
  434. .convergence .el-form-item .sxtt:hover,
  435. .convergence .el-form-item .sxtt:focus {
  436. background-color: #0083eb;
  437. border-color: #0083eb;
  438. color: #ffffff;
  439. }
  440. </style>