liyongli 2 gadi atpakaļ
vecāks
revīzija
67c35bede8

+ 2 - 0
package.json

@@ -12,7 +12,9 @@
     "@wangeditor/editor": "^5.1.22",
     "@wangeditor/editor-for-vue": "^5.1.12",
     "core-js": "^3.6.5",
+    "dayjs": "^1.11.7",
     "element-plus": "^2.2.18",
+    "sha256": "^0.2.0",
     "vue": "^3.0.0",
     "vue-router": "^4.1.6"
   },

+ 29 - 4
pnpm-lock.yaml

@@ -11,9 +11,11 @@ specifiers:
   ali-oss: ^6.17.1
   babel-eslint: ^10.1.0
   core-js: ^3.6.5
+  dayjs: ^1.11.7
   element-plus: ^2.2.18
   eslint: ^6.7.2
   eslint-plugin-vue: ^7.0.0
+  sha256: ^0.2.0
   vue: ^3.0.0
   vue-router: ^4.1.6
 
@@ -22,7 +24,9 @@ dependencies:
   '@wangeditor/editor': registry.npmmirror.com/@wangeditor/editor/5.1.22
   '@wangeditor/editor-for-vue': registry.npmmirror.com/@wangeditor/editor-for-vue/5.1.12_b456bce37a0ed02e7b09198bb628f05c
   core-js: registry.npmmirror.com/core-js/3.25.5
+  dayjs: registry.npmmirror.com/dayjs/1.11.7
   element-plus: registry.npmmirror.com/element-plus/2.2.18_vue@3.2.41
+  sha256: registry.npmmirror.com/sha256/0.2.0
   vue: registry.npmmirror.com/vue/3.2.41
   vue-router: registry.npmmirror.com/vue-router/4.1.6_vue@3.2.41
 
@@ -4402,12 +4406,24 @@ packages:
     engines: {node: '>= 0.6'}
     dev: true
 
+  registry.npmmirror.com/convert-hex/0.1.0:
+    resolution: {integrity: sha512-w20BOb1PiR/sEJdS6wNrUjF5CSfscZFUp7R9NSlXH8h2wynzXVEPFPJECAnkNylZ+cvf3p7TyRUHggDmrwXT9A==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/convert-hex/-/convert-hex-0.1.0.tgz}
+    name: convert-hex
+    version: 0.1.0
+    dev: false
+
   registry.npmmirror.com/convert-source-map/1.9.0:
     resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/convert-source-map/-/convert-source-map-1.9.0.tgz}
     name: convert-source-map
     version: 1.9.0
     dev: true
 
+  registry.npmmirror.com/convert-string/0.1.0:
+    resolution: {integrity: sha512-1KX9ESmtl8xpT2LN2tFnKSbV4NiarbVi8DVb39ZriijvtTklyrT+4dT1wsGMHKD3CJUjXgvJzstm9qL9ICojGA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/convert-string/-/convert-string-0.1.0.tgz}
+    name: convert-string
+    version: 0.1.0
+    dev: false
+
   registry.npmmirror.com/cookie-signature/1.0.6:
     resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/cookie-signature/-/cookie-signature-1.0.6.tgz}
     name: cookie-signature
@@ -4839,10 +4855,10 @@ packages:
     version: 2.2.0
     dev: true
 
-  registry.npmmirror.com/dayjs/1.11.5:
-    resolution: {integrity: sha512-CAdX5Q3YW3Gclyo5Vpqkgpj8fSdLQcRuzfX6mC6Phy0nfJ0eGYOeS7m4mt2plDWLAtA4TqTakvbboHvUxfe4iA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/dayjs/-/dayjs-1.11.5.tgz}
+  registry.npmmirror.com/dayjs/1.11.7:
+    resolution: {integrity: sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/dayjs/-/dayjs-1.11.7.tgz}
     name: dayjs
-    version: 1.11.5
+    version: 1.11.7
     dev: false
 
   registry.npmmirror.com/debug/2.6.9:
@@ -5308,7 +5324,7 @@ packages:
       '@types/lodash-es': registry.npmmirror.com/@types/lodash-es/4.17.6
       '@vueuse/core': registry.npmmirror.com/@vueuse/core/9.3.1_vue@3.2.41
       async-validator: registry.npmmirror.com/async-validator/4.2.5
-      dayjs: registry.npmmirror.com/dayjs/1.11.5
+      dayjs: registry.npmmirror.com/dayjs/1.11.7
       escape-html: registry.npmmirror.com/escape-html/1.0.3
       lodash: registry.npmmirror.com/lodash/4.17.21
       lodash-es: registry.npmmirror.com/lodash-es/4.17.21
@@ -10718,6 +10734,15 @@ packages:
       safe-buffer: registry.npmmirror.com/safe-buffer/5.2.1
     dev: true
 
+  registry.npmmirror.com/sha256/0.2.0:
+    resolution: {integrity: sha512-kTWMJUaez5iiT9CcMv8jSq6kMhw3ST0uRdcIWl3D77s6AsLXNXRp3heeqqfu5+Dyfu4hwpQnMzhqHh8iNQxw0w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/sha256/-/sha256-0.2.0.tgz}
+    name: sha256
+    version: 0.2.0
+    dependencies:
+      convert-hex: registry.npmmirror.com/convert-hex/0.1.0
+      convert-string: registry.npmmirror.com/convert-string/0.1.0
+    dev: false
+
   registry.npmmirror.com/shebang-command/1.2.0:
     resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/shebang-command/-/shebang-command-1.2.0.tgz}
     name: shebang-command

+ 1 - 0
src/App.vue

@@ -13,6 +13,7 @@ export default {
 * {
   margin: 0;
   padding: 0;
+  vertical-align: middle;
   box-sizing: border-box;
 }
 #app {

+ 25 - 0
src/api/index.js

@@ -0,0 +1,25 @@
+import ajax from '../utils/request.js';
+
+/**
+ * 登录
+ * @param {object} ori 
+ * @returns 
+ */
+export function login(ori) {
+    return ajax({
+        api: "/user/login",
+        data: ori.data,
+        method: 'POST',
+    })
+}
+
+export function check(ori) {
+    return ajax({
+        api: "/api/check",
+        data: ori.data,
+        method: 'POST',
+        headers: {
+            Authorization: localStorage.getItem("token")
+        }
+    })
+}

BIN
src/assets/img/hart.png


+ 5 - 0
src/config/index.js

@@ -0,0 +1,5 @@
+export default {
+    base:{
+        origin: "https://open.sxtvs.net",
+    }
+}

+ 4 - 1
src/main.js

@@ -1,6 +1,7 @@
 import { createApp } from "vue";
 import ElementPlus from "element-plus";
 import "element-plus/dist/index.css";
+import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
 
 import router from "./router";
 
@@ -12,5 +13,7 @@ const app = createApp(App).use(router);
 for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
   app.component(key, component);
 }
-app.use(ElementPlus);
+app.use(ElementPlus, {
+    locale: zhCn,
+});
 app.mount("#app");

+ 117 - 0
src/utils/request.js

@@ -0,0 +1,117 @@
+import config from '../config/index';
+import { ElMessage, ElLoading } from 'element-plus';
+
+let loading = undefined;
+
+function ajax(longRange) {
+  return new Promise((resolve, reject) => {
+    var xhttp,
+      url = config.base.origin + longRange.api;
+    if (window.XMLHttpRequest) xhttp = new XMLHttpRequest();
+    else if (window.ActiveXObject)
+      xhttp = new window.ActiveXObject('Microsoft.XMLHTTP');
+    var method = (longRange.method || 'GET').toUpperCase();
+    if (method === 'GET') url += getdata(longRange.data || {});
+    xhttp.open(method, url, true);
+    //   添加头部
+    var headers = headerFunc(longRange.headers);
+    for (const key in headers) {
+      if (!Object.hasOwnProperty.call(headers, key)) continue;
+      xhttp.setRequestHeader(key, headers[key]);
+    }
+    // 添加body
+    xhttp.send(method !== 'GET' ? bodyFunc(longRange.data) : '');
+
+    xhttp.onreadystatechange = function () {
+      if (this.readyState !== 4) return;
+      loading.close();
+      var data = JSON.parse(this.responseText || '{}');
+      if (this.status !== 200 || data.code !== 0) {
+        errorStatus({ ...data, status: this.status });
+        return reject({ ...data, status: this.status });
+      }
+      return resolve(data.data);
+    };
+  });
+}
+
+function fetch(longRange) {
+  return new Promise((resolve, reject) => {
+    window
+      .fetch(config.base.origin + longRange.api, {
+        method: (longRange.method || 'GET').toUpperCase(),
+        body: bodyFunc(longRange.data),
+        headers: headerFunc(longRange.headers),
+      })
+      .then(res => {
+        const json = res.json();
+        if (res.status !== 200) {
+          errorStatus(res);
+          return reject(res);
+        }
+        return json;
+      })
+      .then(res => {
+        loading.close();
+        if (res.code !== 0) {
+          errorStatus(res);
+          return reject(res);
+        }
+
+        return resolve(res.data);
+      });
+  });
+}
+
+function getdata(data) {
+  let text = '';
+  for (const key in data) {
+    text += key + '=' + data[key] + '&';
+  }
+  text ? (text = '?' + text) : '';
+  text = text.replace(/&$/, '');
+  return text;
+}
+
+function errorStatus(err) {
+  if (err.status && err.status !== 200) {
+    return ElMessage({
+      type: 'error',
+      message: err.error || '请稍后再试!',
+    });
+  }
+  if (err.code !== 0) {
+    return ElMessage({
+      type: 'error',
+      message: err.message || '请稍后再试',
+    });
+  }
+}
+
+function bodyFunc(body = {}) {
+  const bodys = {};
+  return JSON.stringify({
+    ...bodys,
+    ...body,
+  });
+}
+
+function headerFunc(headers = {}) {
+  const head = {
+    'Content-Type': 'application/json',
+  };
+  return {
+    ...head,
+    ...headers,
+  };
+}
+
+export default function (longRange) {
+  loading = ElLoading.service({
+    lock: true,
+    text: 'Loading',
+    background: 'rgba(0, 0, 0, 0.1)',
+  });
+  if (window.fetch) return fetch(longRange);
+  return ajax(longRange);
+}

+ 289 - 12
src/view/allMedia/analysis.vue

@@ -1,13 +1,290 @@
 <template>
-    <el-scrollbar>
-        123
-    </el-scrollbar>
-  </template>
-  
-  <script setup>
-  
-  </script>
-  
-  <style scoped>
-  </style>
-  
+  <el-scrollbar class="analysis">
+    <div class="head">
+      <div class="title">分类舆情</div>
+      <div class="searchRow">
+        <div class="searchCol searchTitle">分类:</div>
+        <div
+          :class="{
+            searchCol: true,
+            searchActive: searchActive.classification === optionindex,
+          }"
+          v-for="(optionitem, optionindex) in classification"
+          :key="optionindex + 'option'"
+          v-text="optionitem.name"
+          @click="() => clickSelect('classification', optionindex)"
+        ></div>
+      </div>
+      <div class="searchRow">
+        <div class="searchCol searchTitle">时间:</div>
+        <div
+          :class="{
+            searchCol: true,
+            searchActive: searchActive.time === optionindex,
+          }"
+          v-for="(optionitem, optionindex) in time"
+          :key="optionindex + 'option'"
+          v-text="optionitem.name"
+          @click="() => clickSelect('time', optionindex)"
+        ></div>
+        <div
+          :class="{
+            searchCol: true,
+            searchActive: searchActive[1] === -1,
+          }"
+          @click="() => clickSelect('time', -1)"
+        >
+          自定义
+        </div>
+        <div class="searchCol">
+          <el-date-picker
+            v-model="date"
+            :disabled="searchActive.time !== -1"
+            type="daterange"
+            range-separator="-"
+            start-placeholder="开始时间"
+            end-placeholder="结束时间"
+          />
+        </div>
+      </div>
+      <div class="searchRow">
+        <div class="searchCol searchTitle">搜索:</div>
+        <div class="searchCol">
+          <el-input
+            v-model="searchText"
+            placeholder="搜索文章"
+            :suffix-icon="Search"
+          />
+        </div>
+      </div>
+    </div>
+    <div class="body">
+      <div class="mainTitle">
+        <div class="mainTitleTool">
+          <el-checkbox v-model="removal" label="去重" @change="changeBox" />
+          <el-select
+            v-model="selectValue"
+            class="m-2"
+            placeholder="Select"
+            @change="changeSelect"
+          >
+            <el-option
+              v-for="item in selectlist"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            />
+          </el-select>
+        </div>
+        文章列表
+      </div>
+      <br />
+      <div class="lists">
+        <div class="list">
+          <div class="listHead">
+            #唐嫣何广智说脱口秀# 《我们的客栈》唐嫣何广智说脱口...
+          </div>
+          <div class="listSubtitle">
+            #唐嫣何广智说脱口秀# 《我们的客栈》唐嫣何广智说脱口秀好期待!
+          </div>
+          <el-row>
+            <el-col :span="12">
+              <el-icon><Clock /></el-icon> 2023-02-16 16:11:49
+            </el-col>
+            <el-col :span="12" style="text-align: right"> 2 </el-col>
+          </el-row>
+        </div>
+      </div>
+    </div>
+  </el-scrollbar>
+</template>
+
+<script setup>
+import { ref, reactive } from 'vue';
+import { Search } from '@element-plus/icons-vue';
+const searchActive = ref({
+  classification: 0,
+  time: 0,
+});
+const classification = ref([
+  {
+    type: 'option',
+    name: '全部',
+    id: 0,
+  },
+  {
+    type: 'option',
+    name: '综合',
+    id: 1,
+  },
+  {
+    type: 'option',
+    name: '国际',
+    id: 2,
+  },
+  {
+    type: 'option',
+    name: '时事',
+    id: 3,
+  },
+  {
+    type: 'option',
+    name: '教育',
+    id: 4,
+  },
+]);
+const time = ref([
+  {
+    type: 'option',
+    name: '全部',
+    id: 0,
+  },
+  {
+    type: 'option',
+    name: '24小时',
+    id: 1,
+  },
+  {
+    type: 'option',
+    name: '48小时',
+    id: 2,
+  },
+  {
+    type: 'option',
+    name: '近7天',
+    id: 3,
+  },
+  {
+    type: 'option',
+    name: '近30天',
+    id: 4,
+  },
+]);
+const searchText = ref('');
+const removal = ref(false);
+const selectlist = reactive([
+  {
+    label: '按发布时间降序',
+    value: 0,
+  },
+  {
+    label: '按发布时间升序',
+    value: 1,
+  },
+  {
+    label: '按发情感值升序',
+    value: 2,
+  },
+  {
+    label: '按发情感值降序',
+    value: 3,
+  },
+]);
+const selectValue = ref(0);
+const date = ref([]);
+
+const clickSelect = (select, index) => {
+  searchActive.value[select] = index;
+  console.log(select, index);
+};
+
+const changeSelect = () => {
+  console.log(selectValue.value);
+};
+const changeBox = () => {
+  console.log(removal.value);
+};
+</script>
+
+<style scoped>
+.analysis {
+  height: 100%;
+}
+.analysis .head,
+.analysis .body {
+  margin: 0 1em;
+}
+
+.analysis .body {
+  border: 1px solid #f3f3f3;
+  margin: 1em;
+}
+
+.title {
+  font-size: 18px;
+  font-weight: 600;
+  height: 49px;
+  line-height: 49px;
+  padding-left: 8px;
+  border-bottom: 1px solid #f5f5f5;
+}
+
+.searchRow {
+  margin: 0.5em 0;
+}
+
+.searchCol {
+  display: inline-block;
+  margin: 0 0.5em;
+  padding: 0 0.5em;
+  height: 35px;
+  line-height: 35px;
+  cursor: pointer;
+}
+.searchCol:hover {
+  color: rgb(64, 158, 255);
+}
+
+.searchActive {
+  font-weight: 600;
+  color: rgb(64, 158, 255);
+  border-radius: 5px;
+  background-color: rgba(64, 158, 255, 0.1);
+}
+
+.searchRow .searchTitle {
+  color: #b9c0d3;
+}
+
+.body .mainTitle {
+  padding: 0 20px;
+  position: relative;
+  line-height: 60px;
+  border-bottom: 1px solid #f5f5f5;
+}
+.body .mainTitleTool {
+  position: absolute;
+  right: 20px;
+  line-height: 60px;
+  top: 0;
+  text-align: right;
+}
+.body .el-checkbox {
+  margin-right: 15px;
+}
+
+.listHead,
+.listSubtitle {
+  overflow: hidden;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+}
+
+.lists {
+  padding: 0.5em;
+}
+
+.list {
+  border-radius: 5px;
+  padding: 0.5em;
+  cursor: pointer;
+  line-height: 1.8em;
+  font-size: 16px;
+}
+.list:hover {
+  background-color: rgba(64, 158, 255, 0.1);
+}
+.listSubtitle {
+  color: #b9c0d3;
+}
+</style>

+ 15 - 11
src/view/allMedia/login.vue

@@ -1,12 +1,6 @@
 <template>
   <div class="login">
-    <el-form
-      ref="formEle"
-      :model="form"
-      size="large"
-      class="mo"
-      :rules="rules"
-    >
+    <el-form ref="formEle" :model="form" size="large" class="mo" :rules="rules">
       <el-form-item label="账号" prop="name">
         <el-input placeholder="请输入账号" v-model="form.name" />
       </el-form-item>
@@ -27,7 +21,9 @@
 
 <script setup>
 import { reactive, ref } from 'vue';
+import sha256 from 'sha256';
 import { useRouter, useRoute } from 'vue-router';
+import { login } from '../../api/index';
 const router = useRouter();
 const route = useRoute();
 const formEle = ref(null);
@@ -43,11 +39,19 @@ const rules = reactive({
 async function onSubmit() {
   await formEle.value.validate((valid, fields) => {
     if (!valid) return console.log('error submit!', fields);
-    router.replace({
-      path: '/main_home/proofread',
-      query: {
-        ...route.query,
+    login({
+      data: {
+        loginName: form.name,
+        loginPassword: sha256(form.pwd),
       },
+    }).then(r => {
+      localStorage.setItem('token', r.token);
+      router.replace({
+        path: '/main_home/proofread',
+        query: {
+          ...route.query,
+        },
+      });
     });
   });
 }

+ 5 - 1
src/view/allMedia/main.vue

@@ -38,6 +38,11 @@ const menu = ref([
     icon: require('../../assets/img/sj.png'),
     path: '/main_home/analysis',
   },
+  {
+    title: '数据汇聚',
+    icon: require('../../assets/img/sj.png'),
+    path: '/main_home/convergence',
+  },
 ]);
 
 const selectMenuFunc = item => {
@@ -72,7 +77,6 @@ const selectMenuFunc = item => {
 
 .main .icon {
   width: 1.8em;
-  vertical-align: middle;
   margin-right: 6px;
 }
 

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 421 - 439
src/view/allMedia/proofread.vue


Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels