feat:对接舆情监测相关接口
@@ -1,7 +1,9 @@
|
||||
import axios from 'axios'
|
||||
import qs from 'qs'
|
||||
import router from '@/router'
|
||||
import { Message } from 'element-ui'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { ElMessage } from 'element-plus'
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
const CODE_MESSAGE = {
|
||||
200: '服务器成功返回请求数据',
|
||||
@@ -79,7 +81,7 @@ const handleData = async ({ data, status, statusText }) => {
|
||||
} else {
|
||||
// 是否显示高亮错误(与errorHandler钩子触发逻辑一致)
|
||||
// $baseMessage(errMsg, 'error', 'vab-hey-message-error', false)
|
||||
Message({
|
||||
ElMessage({
|
||||
message: errMsg,
|
||||
type: 'error',
|
||||
duration: 5 * 1000
|
||||
@@ -92,7 +94,7 @@ const handleData = async ({ data, status, statusText }) => {
|
||||
* @description axios初始化
|
||||
*/
|
||||
const instance = axios.create({
|
||||
baseURL: '/dq_api',
|
||||
baseURL: 'http://36.138.38.16:8001/fjtcc-api',
|
||||
timeout: 100000,
|
||||
headers: {
|
||||
'Content-Type': 'application/json;charset=UTF-8'
|
||||
|
||||
57
src/api/sentiment.js
Normal file
@@ -0,0 +1,57 @@
|
||||
import request from './request'
|
||||
|
||||
// 最新舆情
|
||||
export function getHotNewApi() {
|
||||
return request({
|
||||
url: '/api/largeScreen/gsdata/hotNew',
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
|
||||
// 数据来源分析
|
||||
export function getMediaTypeApi() {
|
||||
return request({
|
||||
url: '/api/largeScreen/gsdata/mediaType',
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
|
||||
// 景区统计
|
||||
export function getStateApi() {
|
||||
return request({
|
||||
url: '/api/largeScreen/gsdata/state',
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
|
||||
// 舆情统计
|
||||
export function getTotalApi() {
|
||||
return request({
|
||||
url: '/api/largeScreen/gsdata/total',
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
|
||||
// 词频分析
|
||||
export function getHotWordApi() {
|
||||
return request({
|
||||
url: '/api/largeScreen/gsdata/hotWord',
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
|
||||
// 舆情指数
|
||||
export function getLineChartApi() {
|
||||
return request({
|
||||
url: '/api/largeScreen/gsdata/lineChart',
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
|
||||
// 地域分析
|
||||
export function getAreaApi() {
|
||||
return request({
|
||||
url: '/api/largeScreen/gsdata/area',
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
// qrcode/service/qrcode/getQrcodeContent
|
||||
|
||||
import request from './request'
|
||||
|
||||
// 根据code获取二维码信息
|
||||
export function reqQrCodeInfo(data) {
|
||||
return request({
|
||||
url: `/qrcode/service/qrcode/getQrcodeContent/${data.code}`,
|
||||
method: 'get',
|
||||
data,
|
||||
})
|
||||
}
|
||||
|
||||
// 获取人员信息
|
||||
export function reqUserInfo(data) {
|
||||
return request({
|
||||
url: `/dq/goods/screen/getUserDetail`,
|
||||
method: 'post',
|
||||
data,
|
||||
})
|
||||
}
|
||||
BIN
src/assets/images/bg-alarm.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
@@ -1,41 +0,0 @@
|
||||
<svg width="100" height="30" viewBox="0 0 100 30" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="Mask group">
|
||||
<mask id="mask0_365_11091" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="100" height="30">
|
||||
<rect id="Rectangle 711" width="100" height="30" fill="#D9D9D9"/>
|
||||
</mask>
|
||||
<g mask="url(#mask0_365_11091)">
|
||||
<g id="Group 1349">
|
||||
<g id="Rectangle 704" filter="url(#filter0_f_365_11091)">
|
||||
<path d="M6.25005 3H100V27H2.77783L6.25005 3Z" fill="url(#paint0_linear_365_11091)"/>
|
||||
<path d="M3.35538 26.5L6.68292 3.5H99.5001V26.5H3.35538Z" stroke="url(#paint1_linear_365_11091)"/>
|
||||
</g>
|
||||
<path id="Rectangle 710" d="M3.35538 23.5L6.68292 0.5H99.5001V23.5H3.35538Z" fill="url(#paint2_linear_365_11091)" stroke="url(#paint3_linear_365_11091)"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="filter0_f_365_11091" x="-1.22217" y="-1" width="105.222" height="32" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="2" result="effect1_foregroundBlur_365_11091"/>
|
||||
</filter>
|
||||
<linearGradient id="paint0_linear_365_11091" x1="2.77783" y1="15" x2="100" y2="15" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#0096FF" stop-opacity="0.7"/>
|
||||
<stop offset="1" stop-color="#08305F" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_365_11091" x1="2.77783" y1="28.44" x2="20.0456" y2="8.62646" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0.005" stop-color="white"/>
|
||||
<stop offset="0.261149" stop-color="#02F9FA"/>
|
||||
<stop offset="1" stop-color="#0096FF" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint2_linear_365_11091" x1="2.77783" y1="12" x2="100" y2="12" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#0096FF" stop-opacity="0.7"/>
|
||||
<stop offset="1" stop-color="#08305F" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint3_linear_365_11091" x1="2.77783" y1="25.44" x2="20.0456" y2="5.62646" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0.005" stop-color="white"/>
|
||||
<stop offset="0.261149" stop-color="#02F9FA"/>
|
||||
<stop offset="1" stop-color="#0096FF" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 2.2 KiB |
BIN
src/assets/images/icon-10.png
Normal file
|
After Width: | Height: | Size: 710 B |
BIN
src/assets/images/icon-11.png
Normal file
|
After Width: | Height: | Size: 497 B |
BIN
src/assets/images/icon-8.png
Normal file
|
After Width: | Height: | Size: 650 B |
BIN
src/assets/images/icon-9.png
Normal file
|
After Width: | Height: | Size: 662 B |
|
Before Width: | Height: | Size: 6.7 KiB After Width: | Height: | Size: 6.7 KiB |
|
Before Width: | Height: | Size: 7.0 KiB After Width: | Height: | Size: 7.0 KiB |
@@ -20,8 +20,8 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import primary from '@/assets/images/item-1.png'
|
||||
import error from '@/assets/images/item-2.png'
|
||||
import primary from '@/assets/images/item-primary.png'
|
||||
import error from '@/assets/images/item-error.png'
|
||||
let loading = ref(true)
|
||||
let list = ref(0)
|
||||
onMounted(() => {
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
</div>
|
||||
<div class="count">
|
||||
<img class="bg" src="@/assets/images/mask-success.png" />
|
||||
<div class="flex align-center" :style="{ color }">
|
||||
<countup class="value" :end-val="count" />
|
||||
<span class="suffix">{{ suffix }}</span>
|
||||
<div class="flex align-center">
|
||||
<countup class="value" :end-val="count" :style="{ color: color }" />
|
||||
<span class="suffix" :style="{ color: color }">{{ suffix }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -28,20 +28,16 @@
|
||||
default: () => {
|
||||
return {}
|
||||
}
|
||||
},
|
||||
dataList: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
})
|
||||
|
||||
let id = ref(guid())
|
||||
let pieChart = null
|
||||
var colorList = ['#FDC40A', '#FF5232', '#50F0A6', '#5FDFFA', '']
|
||||
var title = ['企业', '农业', '工业', '纺织']
|
||||
var dataValue = ['15', '30', '35', '20']
|
||||
var dataList = title.map((item, index) => {
|
||||
return {
|
||||
name: item,
|
||||
value: dataValue[index]
|
||||
}
|
||||
})
|
||||
|
||||
var defaultCofig = {
|
||||
color: colorList,
|
||||
@@ -49,7 +45,7 @@
|
||||
orient: 'vertical',
|
||||
bottom: 'center',
|
||||
left: '70%',
|
||||
data: dataList,
|
||||
data: [],
|
||||
itemWidth: fitChartSize(16),
|
||||
itemHeight: fitChartSize(16),
|
||||
itemGap: fitChartSize(10),
|
||||
@@ -93,13 +89,15 @@
|
||||
labelLine: {
|
||||
show: false
|
||||
},
|
||||
data: dataList
|
||||
data: []
|
||||
}
|
||||
]
|
||||
}
|
||||
const init = () => {
|
||||
|
||||
const initChart = () => {
|
||||
const dom = document.getElementById(id.value)
|
||||
pieChart = echarts.init(dom)
|
||||
defaultCofig.series[0].data = props.dataList
|
||||
pieChart.setOption({
|
||||
...defaultCofig,
|
||||
...props.config
|
||||
@@ -111,12 +109,20 @@
|
||||
if (pieChart) {
|
||||
pieChart.dispose()
|
||||
pieChart = null
|
||||
init()
|
||||
initChart()
|
||||
}
|
||||
}
|
||||
onMounted(() => {
|
||||
init()
|
||||
})
|
||||
watch(
|
||||
() => props.dataList,
|
||||
(newVal) => {
|
||||
if (newVal.length > 0) {
|
||||
nextTick(() => {
|
||||
initChart()
|
||||
})
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
)
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
/*滚动数字设置*/
|
||||
.number-item {
|
||||
width: vw(40);
|
||||
height: vh(40);
|
||||
height: vw(40);
|
||||
margin-right: vw(4);
|
||||
border-radius: vw(4);
|
||||
color: #ffffff;
|
||||
|
||||
@@ -40,7 +40,17 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Map />
|
||||
<div class="rela">
|
||||
<div class="alarm-box">
|
||||
<ul class="flex">
|
||||
<li class="alarm-item" v-for="(item, index) in list" :key="index">
|
||||
<img class="icon" :src="item.icon" />
|
||||
<span>{{ item.label }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<Map />
|
||||
</div>
|
||||
<div class="footer">
|
||||
<div class="left">
|
||||
<div>
|
||||
@@ -112,7 +122,30 @@
|
||||
<script setup>
|
||||
import countup from 'vue-countup-v3'
|
||||
import ScrollNumber from '@/components/ScrollNumber/index.vue'
|
||||
import icon8 from '@/assets/images/icon-8.png'
|
||||
import icon9 from '@/assets/images/icon-9.png'
|
||||
import icon10 from '@/assets/images/icon-10.png'
|
||||
import icon11 from '@/assets/images/icon-11.png'
|
||||
|
||||
let count = ref('6945959')
|
||||
let list = ref([
|
||||
{
|
||||
label: '安全异常',
|
||||
icon: icon8
|
||||
},
|
||||
{
|
||||
label: '排队异常',
|
||||
icon: icon9
|
||||
},
|
||||
{
|
||||
label: '停车异常',
|
||||
icon: icon10
|
||||
},
|
||||
{
|
||||
label: '舆论异常',
|
||||
icon: icon11
|
||||
}
|
||||
])
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@@ -141,7 +174,7 @@
|
||||
.item {
|
||||
flex: 1;
|
||||
.label {
|
||||
margin-bottom: vh(10);
|
||||
margin-bottom: vh(20);
|
||||
font-weight: 400;
|
||||
font-size: vw(16);
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
@@ -168,6 +201,29 @@
|
||||
background: linear-gradient(180deg, #00b7ff 0%, #0033ff 100%);
|
||||
}
|
||||
}
|
||||
.alarm-box {
|
||||
position: absolute;
|
||||
top: vw(20);
|
||||
left: vw(20);
|
||||
z-index: 99999;
|
||||
.alarm-item {
|
||||
width: vw(110);
|
||||
height: vh(40);
|
||||
margin-right: vw(4);
|
||||
font-weight: 400;
|
||||
font-size: vw(14);
|
||||
color: #ffffff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: linear-gradient(to bottom, rgba(238, 44, 44, 0) 0%, #ee2c2c 100%);
|
||||
.icon {
|
||||
width: vw(20);
|
||||
height: vw(20);
|
||||
margin-right: vw(4);
|
||||
}
|
||||
}
|
||||
}
|
||||
.footer {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
|
||||
@@ -22,5 +22,30 @@
|
||||
{ name: '舆情', path: '/sentiment' },
|
||||
{ name: '酒店' }
|
||||
]
|
||||
onMounted(() => {})
|
||||
onMounted(() => {
|
||||
let socket = new WebSocket('ws://36.138.38.16:81/ws/third-party', 'echo-protocol', {
|
||||
headers: {
|
||||
Authorization:
|
||||
'eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6ImE1OWFmNWYwLTU3OWItNDJkNy1hZDJhLTY0Y2JlODA5ZWI1NiJ9.BTxvu6jUWbN0qONWf5K6VzXopE8T8qXzKuX-mij21VJT4U0LdgnqToyqeNDQ2OyJ6cvpdJBzQ9mEEb-dnwrTpQ'
|
||||
}
|
||||
})
|
||||
socket.onopen = () => {
|
||||
console.log('WebSocket connected')
|
||||
socket.send(
|
||||
JSON.stringify({
|
||||
action: 'start',
|
||||
type: 'index'
|
||||
})
|
||||
)
|
||||
}
|
||||
socket.onerror = (error) => {
|
||||
console.error('WebSocket error:', error)
|
||||
}
|
||||
socket.onmessage = (message) => {
|
||||
console.log('Received message:', message.data)
|
||||
let data = JSON.parse(message.data)
|
||||
console.log('Received message:', data)
|
||||
}
|
||||
socket.onclose = () => {}
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
<template>
|
||||
<div class="emotion" id="emotion" />
|
||||
<div class="area" id="area" />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import * as echarts from 'echarts'
|
||||
import { fitChartSize } from '@/utils/dataUtil'
|
||||
let emotionChart = null
|
||||
const initChart = () => {
|
||||
const dom = document.getElementById('emotion')
|
||||
emotionChart = echarts.init(dom)
|
||||
emotionChart.setOption({
|
||||
import { getAreaApi } from '@/api/sentiment.js'
|
||||
|
||||
let areaChart = null
|
||||
const initChart = async () => {
|
||||
const dom = document.getElementById('area')
|
||||
areaChart = echarts.init(dom)
|
||||
let res = await getAreaApi()
|
||||
areaChart.setOption({
|
||||
legend: {
|
||||
top: 'top',
|
||||
itemWidth: fitChartSize(30),
|
||||
@@ -23,30 +26,27 @@
|
||||
{
|
||||
name: 'Nightingale Chart',
|
||||
type: 'pie',
|
||||
radius: ['10%', '70%'],
|
||||
radius: ['30%', '60%'],
|
||||
center: ['50%', '56%'],
|
||||
roseType: 'area',
|
||||
labelLine: {
|
||||
normal: {
|
||||
show: true,
|
||||
length: 1
|
||||
}
|
||||
},
|
||||
itemStyle: {
|
||||
borderRadius: fitChartSize(10)
|
||||
},
|
||||
data: [
|
||||
{ value: 40, name: 'rose 1' },
|
||||
{ value: 38, name: 'rose 2' },
|
||||
{ value: 32, name: 'rose 3' },
|
||||
{ value: 30, name: 'rose 4' },
|
||||
{ value: 28, name: 'rose 5' },
|
||||
{ value: 26, name: 'rose 6' },
|
||||
{ value: 22, name: 'rose 7' },
|
||||
{ value: 18, name: 'rose 8' }
|
||||
]
|
||||
data: res.data
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
const resize = () => {
|
||||
if (emotionChart) {
|
||||
emotionChart.dispose()
|
||||
emotionChart = null
|
||||
if (areaChart) {
|
||||
areaChart.dispose()
|
||||
areaChart = null
|
||||
initChart()
|
||||
}
|
||||
}
|
||||
@@ -57,7 +57,7 @@
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.emotion {
|
||||
.area {
|
||||
width: vw(740);
|
||||
height: vh(400);
|
||||
}
|
||||
@@ -8,18 +8,44 @@
|
||||
<p>敏感舆情</p>
|
||||
</div>
|
||||
<div class="list">
|
||||
<div class="cell" v-for="(item, index) in 10" :key="index">
|
||||
<p><span class="index">排名</span></p>
|
||||
<p><span class="name">手机新浪网</span></p>
|
||||
<p><span class="name">新闻</span></p>
|
||||
<p><span class="number">580</span></p>
|
||||
<p><span class="status">1000</span></p>
|
||||
<div class="cell" v-for="(item, index) in list" :key="index">
|
||||
<p>
|
||||
<span
|
||||
class="index"
|
||||
:class="{ first: item.rank == 1, second: item.rank == 2, third: item.rank == 3 }"
|
||||
>
|
||||
{{ item.rank }}
|
||||
</span>
|
||||
</p>
|
||||
<p>
|
||||
<span class="name">{{ item.title }}</span>
|
||||
</p>
|
||||
<p>
|
||||
<span class="name">{{ item.type }}</span>
|
||||
</p>
|
||||
<p>
|
||||
<span class="number">{{ item.num }}</span>
|
||||
</p>
|
||||
<p>
|
||||
<span class="status">{{ item.num_sensitive }}</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup></script>
|
||||
<script setup>
|
||||
import { getMediaTypeApi } from '@/api/sentiment.js'
|
||||
|
||||
let list = ref([])
|
||||
const getMediaType = async () => {
|
||||
let res = await getMediaTypeApi()
|
||||
list.value = res.data
|
||||
}
|
||||
onMounted(() => {
|
||||
getMediaType()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.table {
|
||||
@@ -84,6 +110,18 @@
|
||||
border-radius: vw(2);
|
||||
background-color: #495c77;
|
||||
}
|
||||
.first {
|
||||
@extend .index;
|
||||
background-color: #d9011b;
|
||||
}
|
||||
.second {
|
||||
@extend .index;
|
||||
background-color: #feae00;
|
||||
}
|
||||
.third {
|
||||
@extend .index;
|
||||
background-color: #2380fb;
|
||||
}
|
||||
.name {
|
||||
font-weight: 400;
|
||||
font-size: vw(15);
|
||||
|
||||
@@ -6,11 +6,13 @@
|
||||
import * as echarts from 'echarts'
|
||||
import 'echarts-wordcloud'
|
||||
import { fitChartSize } from '@/utils/dataUtil'
|
||||
import { getHotWordApi } from '@/api/sentiment'
|
||||
|
||||
let wordChart = null
|
||||
const initChart = () => {
|
||||
const initChart = async () => {
|
||||
const dom = document.getElementById('wordCloud')
|
||||
wordChart = echarts.init(dom)
|
||||
let res = await getHotWordApi()
|
||||
wordChart.setOption({
|
||||
//你的代码
|
||||
series: [
|
||||
@@ -45,56 +47,7 @@
|
||||
padding: fitChartSize(10),
|
||||
backgroundColor: 'rgba(0,255,255,.2)'
|
||||
},
|
||||
data: [
|
||||
{
|
||||
value: 2,
|
||||
name: '体外循环'
|
||||
},
|
||||
{
|
||||
value: 1,
|
||||
name: '偏好现金'
|
||||
},
|
||||
{
|
||||
value: 7.75434839431,
|
||||
name: '新成立公司'
|
||||
},
|
||||
{
|
||||
value: 11.3865516372,
|
||||
name: '相同董监高'
|
||||
},
|
||||
{
|
||||
value: 7.75434839431,
|
||||
name: '司法风险'
|
||||
},
|
||||
{
|
||||
value: 5.83541244308,
|
||||
name: '小微企业'
|
||||
},
|
||||
{
|
||||
value: 15.83541244308,
|
||||
name: '同名称交易'
|
||||
},
|
||||
{
|
||||
value: 2.83541244308,
|
||||
name: '高频交易'
|
||||
},
|
||||
{
|
||||
value: 5.83541244308,
|
||||
name: '大额交易'
|
||||
},
|
||||
{
|
||||
value: 10.83541244308,
|
||||
name: '贸易公司'
|
||||
},
|
||||
{
|
||||
value: 5.83541244308,
|
||||
name: '票据偏好'
|
||||
},
|
||||
{
|
||||
value: 5.83541244308,
|
||||
name: '空转走单'
|
||||
}
|
||||
]
|
||||
data: res.data
|
||||
}
|
||||
]
|
||||
})
|
||||
@@ -115,6 +68,6 @@
|
||||
<style scoped lang="scss">
|
||||
.wordCloud {
|
||||
width: vw(760);
|
||||
height: vh(420);
|
||||
height: vh(410);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -6,36 +6,36 @@
|
||||
<div class="box-1 mr-10">
|
||||
<Title1 title="最新舆情" />
|
||||
<div class="list">
|
||||
<div class="item" v-for="item in 20">
|
||||
<p class="status status-error">负面</p>
|
||||
<div class="item" v-for="(item, index) in hotNewList" :key="index">
|
||||
<p class="status status-error">{{ item.type }}</p>
|
||||
<p class="content">
|
||||
这是一条关于三侠之颠旅游舆情的负面新闻这是一条关于三侠之颠旅游舆情的负面这是一条关于三侠之颠旅游舆情的负面新闻这是一条关于三侠之颠旅游舆情的负面
|
||||
{{ item.title }}
|
||||
</p>
|
||||
<p class="date">2024-12.16 23:58</p>
|
||||
<p class="date">{{ item.time }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-2 mr-10">
|
||||
<div class="flex justify-center">
|
||||
<div class="top flex justify-evenly">
|
||||
<count-item label="今日舆情总数" :count="35600" suffix="条" color="#fff" />
|
||||
<count-item label="今日正面舆情" :count="35600" suffix="条" color="#fff" />
|
||||
<count-item label="今日负面舆情" :count="35600" suffix="条" color="#fff" />
|
||||
<count-item label="今日舆情总数" :count="total" suffix="条" color="#ffffff" />
|
||||
<count-item label="今日正面舆情" :count="sensitive" suffix="条" color="#ffffff" />
|
||||
<count-item label="今日负面舆情" :count="unsensitive" suffix="条" color="#ffffff" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex mt-20 gap-8 ml-8 mr-8">
|
||||
<div class="border flex-1">
|
||||
<div v-for="(item, index) in stateList" class="border flex-1">
|
||||
<Title3 :title="index" />
|
||||
<pie-row :width="500" :height="330" :dataList="item" />
|
||||
</div>
|
||||
<!-- <div class="border flex-1">
|
||||
<Title3 title="山峡之巅" />
|
||||
<pie-row :width="500" :height="330" />
|
||||
</div>
|
||||
<div class="border flex-1">
|
||||
<Title3 title="山峡之巅" />
|
||||
<pie-row :width="500" :height="330" />
|
||||
</div>
|
||||
<div class="border flex-1">
|
||||
<Title3 title="山峡之巅" />
|
||||
<pie-row :width="500" :height="330" />
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-1">
|
||||
@@ -49,23 +49,14 @@
|
||||
<Line
|
||||
:width="1560"
|
||||
:height="400"
|
||||
:data="[
|
||||
{
|
||||
name: '企业数',
|
||||
data: [64, 159, 112, 86, 151, 131, 118, 232, 23, 64, 159, 112, 86, 151, 131, 118]
|
||||
},
|
||||
{
|
||||
name: '交易量',
|
||||
data: [124, 30, 77, 97, 67, 75, 70, 334, 123, 124, 30, 77, 97, 67, 75, 70]
|
||||
}
|
||||
]"
|
||||
:data="seriesData"
|
||||
:xAxisData="xAxisData"
|
||||
:seriesConfig="{ smooth: false, symbol: 'circle' }"
|
||||
/>
|
||||
</div>
|
||||
<div class="box-1 mr-10">
|
||||
<Title1 title="情感分布" />
|
||||
<emotion />
|
||||
<Title1 title="地域分析" />
|
||||
<Area />
|
||||
</div>
|
||||
<div class="box-1 mr-10">
|
||||
<Title1 title="词频分析" />
|
||||
@@ -77,27 +68,45 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import emotion from './components/emotion.vue'
|
||||
import Area from './components/area.vue'
|
||||
import wordCloud from './components/wordCloud.vue'
|
||||
import dataSource from './components/dataSource.vue'
|
||||
let xAxisData = ref([
|
||||
'12-16 10:00',
|
||||
'12-16 14:00',
|
||||
'12-16 16:00',
|
||||
'12-16 22:00',
|
||||
'12-17 02:00',
|
||||
'12-17 06:00',
|
||||
'12-17 10:00',
|
||||
'12-17 14:00',
|
||||
'12-17 16:00',
|
||||
'12-16 22:00',
|
||||
'12-18 02:00',
|
||||
'12-18 06:00',
|
||||
'12-8 10:00',
|
||||
'12-18 14:00',
|
||||
'12-18 16:00',
|
||||
'12-18 20:00'
|
||||
])
|
||||
import { getHotNewApi, getLineChartApi, getStateApi, getTotalApi } from '@/api/sentiment.js'
|
||||
|
||||
let seriesData = ref([])
|
||||
let xAxisData = ref([])
|
||||
let hotNewList = ref([])
|
||||
let total = ref(0)
|
||||
let sensitive = ref(0)
|
||||
let unsensitive = ref(0)
|
||||
let stateList = ref([])
|
||||
|
||||
const getTotal = async () => {
|
||||
let res = await getTotalApi()
|
||||
total.value = res.data.total
|
||||
sensitive.value = res.data.sensitive
|
||||
unsensitive.value = res.data.unsensitive
|
||||
}
|
||||
const getState = async () => {
|
||||
let res = await getStateApi()
|
||||
stateList.value = res.data
|
||||
console.log(stateList.value, '------')
|
||||
}
|
||||
const getLineChart = async () => {
|
||||
let res = await getLineChartApi()
|
||||
xAxisData.value = res.data.data
|
||||
seriesData.value = res.data.series
|
||||
}
|
||||
const getHotNew = async () => {
|
||||
let res = await getHotNewApi()
|
||||
hotNewList.value = res.data
|
||||
}
|
||||
onMounted(() => {
|
||||
getHotNew()
|
||||
getTotal()
|
||||
getState()
|
||||
getLineChart()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||