analysis.vue 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. <template>
  2. <div>
  3. <header_local />
  4. <el-scrollbar ref="scrollbar" class="analysis" @scroll="scroll">
  5. <div class="head">
  6. <div class="title">账号分析</div>
  7. <div class="searchRow">
  8. <div class="searchCol searchTitle">分类:</div>
  9. <div
  10. :class="{
  11. searchCol: true,
  12. searchActive: searchActive.classification === optionindex,
  13. }"
  14. v-for="(optionitem, optionindex) in classification"
  15. :key="optionindex + 'option'"
  16. v-text="optionitem.name"
  17. @click="() => clickSelect('classification', optionindex)"
  18. ></div>
  19. </div>
  20. <div class="searchRow">
  21. <div class="searchCol searchTitle">时间:</div>
  22. <div
  23. :class="{
  24. searchCol: true,
  25. searchActive: searchActive.time === optionindex,
  26. }"
  27. v-for="(optionitem, optionindex) in time"
  28. :key="optionindex + 'option'"
  29. v-text="optionitem.name"
  30. @click="() => clickSelect('time', optionindex)"
  31. ></div>
  32. <div
  33. :class="{
  34. searchCol: true,
  35. searchActive: searchActive.time === -1,
  36. }"
  37. @click="() => clickSelect('time', -1)"
  38. >
  39. 自定义
  40. </div>
  41. <div class="searchCol">
  42. <el-date-picker
  43. v-model="date"
  44. :disabled="searchActive.time !== -1"
  45. @change="change"
  46. :disabled-date="disDate"
  47. type="daterange"
  48. :clearable="false"
  49. value-format="YYYY-MM-DD"
  50. range-separator="-"
  51. start-placeholder="开始时间"
  52. end-placeholder="结束时间"
  53. />
  54. </div>
  55. </div>
  56. <div class="searchRow">
  57. <div class="searchCol searchTitle">搜索:</div>
  58. <div class="searchCol">
  59. <el-input v-model="searchText" placeholder="搜索文章">
  60. <template #suffix>
  61. <el-icon @click="search"><Search /></el-icon>
  62. </template>
  63. </el-input>
  64. </div>
  65. </div>
  66. </div>
  67. <div class="body">
  68. <analysisList ref="analysisListEle" />
  69. </div>
  70. <analysisHotList @changeSearch="hotList" province="" />
  71. <el-icon :size="45" class="upload" v-show="showUpload" @click="upload"
  72. ><Upload
  73. /></el-icon>
  74. </el-scrollbar>
  75. </div>
  76. </template>
  77. <script setup>
  78. import header_local from './components/header.vue';
  79. import dayjs from 'dayjs';
  80. import { ref, onMounted } from 'vue';
  81. import { getClass } from '../../api/index';
  82. import analysisList from './components/analysis_list.vue';
  83. import analysisHotList from './components/analysis_hot_list.vue';
  84. const nowTime = Date.now();
  85. const scrollbar = ref();
  86. const analysisListEle = ref();
  87. const showUpload = ref(false);
  88. const searchActive = ref({
  89. classification: 0,
  90. time: 0,
  91. area: 0,
  92. areaSon: 0,
  93. });
  94. const defaultOption = {
  95. type: 'option',
  96. name: '全部',
  97. id: 0,
  98. };
  99. const classification = ref([defaultOption]);
  100. const time = [
  101. {
  102. type: 'option',
  103. time: nowTime - 86400000,
  104. name: '24小时',
  105. id: 1,
  106. },
  107. {
  108. type: 'option',
  109. time: nowTime - 172800000,
  110. name: '48小时',
  111. id: 2,
  112. },
  113. {
  114. type: 'option',
  115. time: nowTime - 604800000,
  116. name: '近7天',
  117. id: 3,
  118. },
  119. {
  120. type: 'option',
  121. time: nowTime - 2592000000,
  122. name: '近30天',
  123. id: 4,
  124. },
  125. ];
  126. const searchText = ref('');
  127. const date = ref([]);
  128. const pageSize = 10;
  129. let page = 1;
  130. onMounted(() => {
  131. getList();
  132. });
  133. getClass({}).then(res => {
  134. const li = res || [];
  135. const l = [];
  136. for (let i = 0; i < li.length; i++) {
  137. const v = li[i];
  138. l.push({
  139. type: 'option',
  140. name: v,
  141. });
  142. }
  143. classification.value.push(...l);
  144. });
  145. const getList = () => {
  146. const search = {
  147. category:
  148. classification.value[searchActive.value.classification].name || undefined,
  149. keywords: searchText.value,
  150. page: page++,
  151. pageSize,
  152. };
  153. search.category === '全部' ? (search.category = '') : '';
  154. search.city === '全部' ? (search.city = '') : '';
  155. // 时间区间
  156. if (searchActive.value['time'] === -1) {
  157. search.start = date.value[0];
  158. search.end = date.value[1];
  159. } else {
  160. search.start = dayjs(time[searchActive.value['time']].time).format(
  161. 'YYYY-MM-DD HH:mm:ss'
  162. );
  163. search.end = dayjs(nowTime).format('YYYY-MM-DD HH:mm:ss');
  164. }
  165. analysisListEle.value.getlist(search);
  166. };
  167. const clickSelect = (select, index) => {
  168. searchActive.value[select] = index;
  169. if (index === -1) return;
  170. page = 1;
  171. getList();
  172. };
  173. const change = () => {
  174. date.value = [date.value[0] + ' 00:00:00', date.value[1] + ' 23:59:59'];
  175. page = 1;
  176. getList();
  177. };
  178. const search = () => {
  179. page = 1;
  180. getList();
  181. };
  182. const hotList = searchTextHot => {
  183. if (!searchTextHot) return;
  184. page = 1;
  185. searchText.value = searchTextHot;
  186. getList();
  187. };
  188. const scroll = e => {
  189. const height =
  190. document.querySelector('.analysis .head').offsetHeight +
  191. document.querySelector('.analysis .body').offsetHeight -
  192. document.querySelector('.analysis').offsetHeight;
  193. const scrollNum = e.scrollTop.toFixed(2) - 0;
  194. if (!showUpload.value && scrollNum > 180) showUpload.value = true;
  195. else if (scrollNum <= 180) showUpload.value = false;
  196. if (height - scrollNum > 0) return;
  197. getList();
  198. };
  199. const upload = () => {
  200. scrollbar.value.setScrollTop(0);
  201. };
  202. const nowT = Date.now();
  203. const disDate = date => {
  204. return date.getTime() > nowT;
  205. };
  206. </script>
  207. <style scoped>
  208. .analysis {
  209. height: 100%;
  210. /* min-width: 1305px; */
  211. position: relative;
  212. }
  213. .analysis .head,
  214. .analysis .body {
  215. margin: 0 1em;
  216. width: calc(100% - 400px);
  217. min-width: 855px;
  218. }
  219. .analysis .body {
  220. border: 1px solid #f3f3f3;
  221. margin: 1em;
  222. }
  223. .title {
  224. font-size: 16px;
  225. font-weight: 600;
  226. height: 49px;
  227. line-height: 49px;
  228. padding-left: 8px;
  229. border-bottom: 1px solid #f5f5f5;
  230. }
  231. .searchRow {
  232. margin: 0.5em 0;
  233. }
  234. .searchCol {
  235. display: inline-block;
  236. margin: 0 0.5em;
  237. padding: 0 0.5em;
  238. height: 35px;
  239. line-height: 35px;
  240. cursor: pointer;
  241. }
  242. .searchCol:hover {
  243. color: rgb(64, 158, 255);
  244. }
  245. .searchActive {
  246. font-weight: 600;
  247. color: rgb(64, 158, 255);
  248. border-radius: 5px;
  249. background-color: rgba(64, 158, 255, 0.1);
  250. border-bottom: none;
  251. }
  252. .searchRow .searchTitle {
  253. color: #b9c0d3;
  254. }
  255. .body .el-checkbox {
  256. margin-right: 15px;
  257. }
  258. .source {
  259. color: #22ac38;
  260. }
  261. .upload {
  262. position: absolute;
  263. right: 25px;
  264. bottom: 25px;
  265. background-color: #e9e9e990;
  266. border-radius: 50%;
  267. padding: 5px;
  268. cursor: pointer;
  269. }
  270. </style>