liyongli 2 lat temu
rodzic
commit
0c4921d692

BIN
src/assets/img/bq.png


BIN
src/assets/img/hot.png


+ 14 - 0
src/router/allMedia.js

@@ -13,6 +13,20 @@ export default [
         /* webpackChunkName: "authorization" */ '../view/allMedia/authorization.vue'
       ),
   },
+  {
+    path: '/copyright',
+    component: () =>
+      import(
+        /* webpackChunkName: "copyright" */ '../view/allMedia/copyright.vue'
+      ),
+  },
+  {
+    path: '/analysis_detail',
+    component: () =>
+      import(
+        /* webpackChunkName: "analysis_detail" */ '../view/allMedia/analysis_detail.vue'
+      ),
+  },
   // 主页
   {
     path: '/main_home',

+ 190 - 44
src/view/allMedia/analysis.vue

@@ -1,5 +1,5 @@
 <template>
-  <el-scrollbar class="analysis">
+  <el-scrollbar ref="scrollbar" class="analysis" @scroll="scroll">
     <div class="head">
       <div class="title">分类舆情</div>
       <div class="searchRow">
@@ -40,7 +40,10 @@
           <el-date-picker
             v-model="date"
             :disabled="searchActive.time !== -1"
+            @change="change"
             type="daterange"
+            :clearable="false"
+            value-format="YYYY-MM-DD"
             range-separator="-"
             start-placeholder="开始时间"
             end-placeholder="结束时间"
@@ -50,17 +53,17 @@
       <div class="searchRow">
         <div class="searchCol searchTitle">搜索:</div>
         <div class="searchCol">
-          <el-input
-            v-model="searchText"
-            placeholder="搜索文章"
-            :suffix-icon="Search"
-          />
+          <el-input v-model="searchText" placeholder="搜索文章">
+            <template #suffix>
+              <el-icon @click="search"><Search /></el-icon>
+            </template>
+          </el-input>
         </div>
       </div>
     </div>
     <div class="body">
       <div class="mainTitle">
-        <div class="mainTitleTool">
+        <div class="mainTitleTool" v-if="selectlist.length">
           <el-select
             v-model="selectValue"
             class="m-2"
@@ -79,7 +82,12 @@
       </div>
       <br />
       <div class="lists">
-        <div class="list" v-for="item in listTable" :key="item.title">
+        <div
+          class="list"
+          v-for="item in listTable"
+          :key="item.title"
+          @click="() => toDetail(item)"
+        >
           <div
             class="listHead"
             v-text="item.raw ? item.raw.title || '' : ''"
@@ -101,16 +109,45 @@
         </div>
       </div>
     </div>
+
+    <div class="hotList">
+      <div class="title">
+        <img :src="hotIcon" style="width: 18px; height: 18px" />
+        热度排行
+      </div>
+      <div
+        class="hotItem"
+        v-for="(item, index) in listHot"
+        :key="item.rk"
+        @click="() => searchHot(item.content)"
+      >
+        <span
+          :style="{ color: colorRanking[index] || '#999', 'font-size': '14px' }"
+          >{{ index + 1 }}</span
+        >
+        {{ item.content }}
+      </div>
+    </div>
+
+    <el-icon :size="45" class="upload" v-show="showUpload" @click="upload"
+      ><Upload
+    /></el-icon>
   </el-scrollbar>
 </template>
 
 <script setup>
 import dayjs from 'dayjs';
 import { ref } from 'vue';
-import { Search } from '@element-plus/icons-vue';
+import { useRouter } from 'vue-router';
 import { hotRank, searchData } from '../../api/index';
 
+import hotIcon from '../../assets/img/hot.png';
+
+const router = useRouter();
+const colorRanking = ['#FE2D46', '#F60', '#FAA90E'];
 const nowTime = Date.now();
+const scrollbar = ref();
+const showUpload = ref(false);
 const searchActive = ref({
   classification: 0,
   time: 0,
@@ -170,75 +207,151 @@ const time = [
 ];
 const searchText = ref('');
 const selectlist = [
-  {
-    label: '按发布时间降序',
-    value: 0,
-  },
-  {
-    label: '按发布时间升序',
-    value: 1,
-  },
-  {
-    label: '按发情感值升序',
-    value: 2,
-  },
-  {
-    label: '按发情感值降序',
-    value: 3,
-  },
+  //   {
+  //     label: '按发布时间降序',
+  //     value: 0,
+  //   },
+  //   {
+  //     label: '按发布时间升序',
+  //     value: 1,
+  //   },
+  //   {
+  //     label: '按发情感值升序',
+  //     value: 2,
+  //   },
+  //   {
+  //     label: '按发情感值降序',
+  //     value: 3,
+  //   },
 ];
 const selectValue = ref(0);
 const date = ref([]);
 
 const listTable = ref([]);
+const listHot = ref([]);
+
+const pageSize = 10;
+let page = 1;
+let total = -1;
+let T = undefined;
 
 hotRank({}).then(res => {
-  console.log(res);
+  listHot.value = res || [];
 });
 
+const toDetail = item => {
+  router.push({
+    path: '/analysis_detail',
+    query: {
+      detail: JSON.stringify(item),
+    },
+  });
+};
+
 const getList = () => {
-  console.log(date.value);
   const search = {
     category:
       classification[searchActive.value.classification].name || undefined,
-    city: '城市',
-    start: time[searchActive.value['time']].time,
-    end: dayjs().format('YYYY-MM-DD HH:mm:ss'),
-    page: 1,
-    pageSize: 10,
+    city: undefined,
+    keywords: searchText.value,
+    page: page++,
+    pageSize,
   };
   search.category === '全部' ? (search.category = '') : '';
+  // 时间区间
+  if (searchActive.value['time'] === -1) {
+    search.start = date.value[0];
+    search.end = date.value[1];
+  } else {
+    search.start = dayjs(time[searchActive.value['time']].time).format(
+      'YYYY-MM-DD HH:mm:ss'
+    );
+    search.end = dayjs(nowTime).format('YYYY-MM-DD HH:mm:ss');
+  }
   searchData({
     data: search,
-  }).then(res => {
-    console.log(res.records);
-    listTable.value = res.records || [];
-  });
+  })
+    .then(res => {
+      const li = res.records || [];
+      listTable.value.push(...li);
+      total = res.total || 0;
+      if (T) T = window.clearTimeout(T);
+    })
+    .catch(() => {
+      if (T) T = window.clearTimeout(T);
+    });
 };
-getList();
 
 const clickSelect = (select, index) => {
   searchActive.value[select] = index;
-  console.log(searchActive.value, select, index);
-  const searchDate = {
-    start: time[index].time,
-    end: dayjs().format('YYYY-MM-DD HH:mm:ss'),
-  }
-  getList(searchDate);
+  if (index === -1) return;
+  page = 1;
+  listTable.value = [];
+  changeInput();
 };
 const changeSelect = () => {
   // 更改排序
   console.log(selectValue.value);
 };
+
+const change = () => {
+  date.value = [date.value[0] + ' 00:00:00', date.value[1] + ' 23:59:59'];
+  page = 1;
+  listTable.value = [];
+  changeInput();
+};
+
+const changeInput = () => {
+  if (total === 0 || total < page * pageSize) return;
+  if (T) T = window.clearTimeout(T);
+  T = window.setTimeout(() => {
+    getList();
+  }, 200);
+};
+
+const search = () => {
+  page = 1;
+  listTable.value = [];
+  changeInput();
+};
+
+const searchHot = text => {
+  searchText.value = text;
+  page = 1;
+  listTable.value = [];
+  changeInput();
+};
+
+const scroll = e => {
+  const height =
+    document.querySelector('.analysis .head').offsetHeight +
+    document.querySelector('.analysis .body').offsetHeight -
+    document.querySelector('.analysis').offsetHeight;
+  const scrollNum = e.scrollTop.toFixed(2) - 0;
+  if (!showUpload.value && scrollNum > 180) showUpload.value = true;
+  else if (scrollNum <= 180) showUpload.value = false;
+  if (height - scrollNum > 0 || T) return;
+  changeInput();
+};
+
+const upload = () => {
+  scrollbar.value.setScrollTop(0)
+};
+
+getList();
 </script>
 
 <style scoped>
 .analysis {
   height: 100%;
+  min-width: 1305px;
+  position: relative;
 }
 .analysis .head,
 .analysis .body {
   margin: 0 1em;
+  width: calc(100% - 400px);
+  min-width: 855px;
 }
 
 .analysis .body {
@@ -246,6 +359,13 @@ const changeSelect = () => {
   margin: 1em;
 }
 
+.analysis .hotList {
+  position: absolute;
+  width: 300px;
+  right: 50px;
+  top: 100px;
+}
+
 .title {
   font-size: 18px;
   font-weight: 600;
@@ -271,11 +391,13 @@ const changeSelect = () => {
   color: rgb(64, 158, 255);
 }
 
-.searchActive {
+.searchActive,
+.hotItem:hover {
   font-weight: 600;
   color: rgb(64, 158, 255);
   border-radius: 5px;
   background-color: rgba(64, 158, 255, 0.1);
+  border-bottom: none;
 }
 
 .searchRow .searchTitle {
@@ -330,4 +452,28 @@ const changeSelect = () => {
 .source {
   color: #22ac38;
 }
+
+.hotItem {
+  line-height: 1em;
+  font-size: 16px;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  cursor: pointer;
+  padding: 0.6em;
+}
+
+.hotItem:not(:last-child) {
+  border-bottom: 1px dashed #e9e9e9;
+}
+
+.upload {
+  position: absolute;
+  right: 25px;
+  bottom: 25px;
+  background-color: #e9e9e990;
+  border-radius: 50%;
+  padding: 5px;
+  cursor: pointer;
+}
 </style>

+ 58 - 0
src/view/allMedia/analysis_detail.vue

@@ -0,0 +1,58 @@
+<template>
+  <el-scrollbar class="analysis_detail">
+    <div class="title" v-text="raw.title || ''"></div>
+    <div class="subtitle">
+      <el-icon><Clock /></el-icon>
+      {{ raw.publishTime }}
+      <span style="vertical-align: middle;">来源:</span>
+      <span style="color: #22ac38;vertical-align: middle;" v-text="raw.sourceWebsite"> </span>
+    </div>
+    <div v-html="detail"></div>
+  </el-scrollbar>
+</template>
+
+<script setup>
+import { ref } from 'vue';
+import { useRoute } from 'vue-router';
+const route = useRoute();
+const detail = ref('');
+const raw = ref({});
+const D = JSON.parse(route.query.detail || '{}');
+console.log(D);
+detail.value = D.content || '';
+raw.value = D.raw || {};
+</script>
+
+<style>
+.analysis_detail {
+  padding: 2em 50px;
+  font-size: 18px;
+}
+.analysis_detail * {
+  line-height: 1.5em;
+  text-indent: 2em;
+}
+.analysis_detail img {
+  width: 80%;
+  display: block;
+  margin: 3px auto;
+}
+.analysis_detail .title {
+  font-size: 18px;
+  font-weight: 600;
+  height: 60px;
+  line-height: 60px;
+  padding-left: 8px;
+  text-align: center;
+}
+
+.analysis_detail .subtitle {
+  border-bottom: 1px solid #f5f5f5;
+  font-weight: 500;
+  height: 40px;
+  line-height: 40px;
+  font-size: 16px;
+  margin-bottom: 2em;
+  text-align: center;
+}
+</style>

+ 81 - 0
src/view/allMedia/copyright.vue

@@ -0,0 +1,81 @@
+<template>
+  <div class="copyright">
+    <div class="copyHead">1</div>
+    <div class="copyBody">2</div>
+    <div class="searchInput">
+      <el-input  size="large" v-model="search.input" placeholder="请输入关键词">
+        <template #suffix>
+            <el-icon class="fileIcon" @click="fileClick"><VideoCameraFilled /></el-icon>
+        </template>
+        <template #append>搜 索</template>
+      </el-input>
+      <el-upload
+        v-if="showUpLoad"
+        class="upload_video_image"
+        drag
+        action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15"
+        multiple
+      >
+        <el-icon class="el-icon--upload"><upload-filled /></el-icon>
+        <div class="el-upload__text">
+          将文件拖拽至此处或<em>点击上传</em>
+        </div>
+      </el-upload>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { ref } from 'vue';
+const showUpLoad = ref(false);
+const search = ref({
+  input: '',
+});
+
+const fileClick = () => {
+    showUpLoad.value = !showUpLoad.value;
+}
+</script>
+
+<style scoped>
+.copyright {
+  width: 100%;
+  height: 100%;
+  display: flex;
+  position: relative;
+  flex-direction: column;
+}
+
+.searchInput{
+    top: 50%;
+    left: 50%;
+    transform: translate(-50%,-50%);
+    width: 40em;
+    position: absolute;
+}
+
+.upload_video_image{
+    margin-top: 1em;
+}
+
+.copyBody {
+  flex: 1;
+}
+
+.copyHead {
+  height: 200px;
+  flex-basis: 200px;
+  flex-shrink: 0;
+}
+.fileIcon{
+    cursor: pointer;
+}
+</style>
+
+<style>
+.copyright .el-input-group__append{
+    color: #fff;
+    cursor: pointer;
+    background-color: #4e6ef2;
+}
+</style>