feat:对接舆情监测相关接口

This commit is contained in:
zjc
2024-12-25 18:17:00 +08:00
parent 45c85763dd
commit 50a6b06381
23 changed files with 532 additions and 214 deletions

233
package-lock.json generated
View File

@@ -14,6 +14,7 @@
"element-plus": "^2.9.0", "element-plus": "^2.9.0",
"flv.js": "^1.6.2", "flv.js": "^1.6.2",
"pinia": "^2.2.6", "pinia": "^2.2.6",
"qs": "^6.13.1",
"vue": "^3.5.13", "vue": "^3.5.13",
"vue-countup-v3": "^1.4.2", "vue-countup-v3": "^1.4.2",
"vue-echarts": "^7.0.3", "vue-echarts": "^7.0.3",
@@ -1437,6 +1438,33 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/call-bind-apply-helpers": {
"version": "1.0.1",
"resolved": "https://registry.npmmirror.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz",
"integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==",
"dependencies": {
"es-errors": "^1.3.0",
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/call-bound": {
"version": "1.0.3",
"resolved": "https://registry.npmmirror.com/call-bound/-/call-bound-1.0.3.tgz",
"integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==",
"dependencies": {
"call-bind-apply-helpers": "^1.0.1",
"get-intrinsic": "^1.2.6"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/caniuse-lite": { "node_modules/caniuse-lite": {
"version": "1.0.30001685", "version": "1.0.30001685",
"resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001685.tgz", "resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001685.tgz",
@@ -1649,6 +1677,19 @@
"node": ">=0.10" "node": ">=0.10"
} }
}, },
"node_modules/dunder-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmmirror.com/dunder-proto/-/dunder-proto-1.0.1.tgz",
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
"dependencies": {
"call-bind-apply-helpers": "^1.0.1",
"es-errors": "^1.3.0",
"gopd": "^1.2.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/echarts": { "node_modules/echarts": {
"version": "5.5.1", "version": "5.5.1",
"resolved": "https://registry.npmmirror.com/echarts/-/echarts-5.5.1.tgz", "resolved": "https://registry.npmmirror.com/echarts/-/echarts-5.5.1.tgz",
@@ -1740,6 +1781,22 @@
"url": "https://github.com/sponsors/antfu" "url": "https://github.com/sponsors/antfu"
} }
}, },
"node_modules/es-define-property": {
"version": "1.0.1",
"resolved": "https://registry.npmmirror.com/es-define-property/-/es-define-property-1.0.1.tgz",
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-errors": {
"version": "1.3.0",
"resolved": "https://registry.npmmirror.com/es-errors/-/es-errors-1.3.0.tgz",
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-module-lexer": { "node_modules/es-module-lexer": {
"version": "1.5.4", "version": "1.5.4",
"resolved": "https://registry.npmmirror.com/es-module-lexer/-/es-module-lexer-1.5.4.tgz", "resolved": "https://registry.npmmirror.com/es-module-lexer/-/es-module-lexer-1.5.4.tgz",
@@ -1747,6 +1804,17 @@
"dev": true, "dev": true,
"peer": true "peer": true
}, },
"node_modules/es-object-atoms": {
"version": "1.0.0",
"resolved": "https://registry.npmmirror.com/es-object-atoms/-/es-object-atoms-1.0.0.tgz",
"integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==",
"dependencies": {
"es-errors": "^1.3.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es6-promise": { "node_modules/es6-promise": {
"version": "4.2.8", "version": "4.2.8",
"resolved": "https://registry.npmmirror.com/es6-promise/-/es6-promise-4.2.8.tgz", "resolved": "https://registry.npmmirror.com/es6-promise/-/es6-promise-4.2.8.tgz",
@@ -2040,6 +2108,14 @@
"node": ">=14.14" "node": ">=14.14"
} }
}, },
"node_modules/function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/gensync": { "node_modules/gensync": {
"version": "1.0.0-beta.2", "version": "1.0.0-beta.2",
"resolved": "https://registry.npmmirror.com/gensync/-/gensync-1.0.0-beta.2.tgz", "resolved": "https://registry.npmmirror.com/gensync/-/gensync-1.0.0-beta.2.tgz",
@@ -2049,6 +2125,29 @@
"node": ">=6.9.0" "node": ">=6.9.0"
} }
}, },
"node_modules/get-intrinsic": {
"version": "1.2.6",
"resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.2.6.tgz",
"integrity": "sha512-qxsEs+9A+u85HhllWJJFicJfPDhRmjzoYdl64aMWW9yRIJmSyxdn8IEkuIM530/7T+lv0TIHd8L6Q/ra0tEoeA==",
"dependencies": {
"call-bind-apply-helpers": "^1.0.1",
"dunder-proto": "^1.0.0",
"es-define-property": "^1.0.1",
"es-errors": "^1.3.0",
"es-object-atoms": "^1.0.0",
"function-bind": "^1.1.2",
"gopd": "^1.2.0",
"has-symbols": "^1.1.0",
"hasown": "^2.0.2",
"math-intrinsics": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/get-stream": { "node_modules/get-stream": {
"version": "9.0.1", "version": "9.0.1",
"resolved": "https://registry.npmmirror.com/get-stream/-/get-stream-9.0.1.tgz", "resolved": "https://registry.npmmirror.com/get-stream/-/get-stream-9.0.1.tgz",
@@ -2093,6 +2192,17 @@
"node": ">=4" "node": ">=4"
} }
}, },
"node_modules/gopd": {
"version": "1.2.0",
"resolved": "https://registry.npmmirror.com/gopd/-/gopd-1.2.0.tgz",
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/graceful-fs": { "node_modules/graceful-fs": {
"version": "4.2.11", "version": "4.2.11",
"resolved": "https://registry.npmmirror.com/graceful-fs/-/graceful-fs-4.2.11.tgz", "resolved": "https://registry.npmmirror.com/graceful-fs/-/graceful-fs-4.2.11.tgz",
@@ -2109,6 +2219,28 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/has-symbols": {
"version": "1.1.0",
"resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.1.0.tgz",
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/hasown": {
"version": "2.0.2",
"resolved": "https://registry.npmmirror.com/hasown/-/hasown-2.0.2.tgz",
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
"dependencies": {
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/hookable": { "node_modules/hookable": {
"version": "5.5.3", "version": "5.5.3",
"resolved": "https://registry.npmmirror.com/hookable/-/hookable-5.5.3.tgz", "resolved": "https://registry.npmmirror.com/hookable/-/hookable-5.5.3.tgz",
@@ -2481,6 +2613,14 @@
"@jridgewell/sourcemap-codec": "^1.5.0" "@jridgewell/sourcemap-codec": "^1.5.0"
} }
}, },
"node_modules/math-intrinsics": {
"version": "1.1.0",
"resolved": "https://registry.npmmirror.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/memoize-one": { "node_modules/memoize-one": {
"version": "6.0.0", "version": "6.0.0",
"resolved": "https://registry.npmmirror.com/memoize-one/-/memoize-one-6.0.0.tgz", "resolved": "https://registry.npmmirror.com/memoize-one/-/memoize-one-6.0.0.tgz",
@@ -2681,6 +2821,17 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/object-inspect": {
"version": "1.13.3",
"resolved": "https://registry.npmmirror.com/object-inspect/-/object-inspect-1.13.3.tgz",
"integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/open": { "node_modules/open": {
"version": "10.1.0", "version": "10.1.0",
"resolved": "https://registry.npmmirror.com/open/-/open-10.1.0.tgz", "resolved": "https://registry.npmmirror.com/open/-/open-10.1.0.tgz",
@@ -2866,6 +3017,20 @@
"node": ">=6" "node": ">=6"
} }
}, },
"node_modules/qs": {
"version": "6.13.1",
"resolved": "https://registry.npmmirror.com/qs/-/qs-6.13.1.tgz",
"integrity": "sha512-EJPeIn0CYrGu+hli1xilKAPXODtJ12T0sP63Ijx2/khC2JtuaN3JyNIpvmnkmaEtha9ocbG4A4cMcr+TvqvwQg==",
"dependencies": {
"side-channel": "^1.0.6"
},
"engines": {
"node": ">=0.6"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/queue-microtask": { "node_modules/queue-microtask": {
"version": "1.2.3", "version": "1.2.3",
"resolved": "https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz", "resolved": "https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz",
@@ -3151,6 +3316,74 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/side-channel": {
"version": "1.1.0",
"resolved": "https://registry.npmmirror.com/side-channel/-/side-channel-1.1.0.tgz",
"integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
"dependencies": {
"es-errors": "^1.3.0",
"object-inspect": "^1.13.3",
"side-channel-list": "^1.0.0",
"side-channel-map": "^1.0.1",
"side-channel-weakmap": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/side-channel-list": {
"version": "1.0.0",
"resolved": "https://registry.npmmirror.com/side-channel-list/-/side-channel-list-1.0.0.tgz",
"integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
"dependencies": {
"es-errors": "^1.3.0",
"object-inspect": "^1.13.3"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/side-channel-map": {
"version": "1.0.1",
"resolved": "https://registry.npmmirror.com/side-channel-map/-/side-channel-map-1.0.1.tgz",
"integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
"dependencies": {
"call-bound": "^1.0.2",
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.5",
"object-inspect": "^1.13.3"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/side-channel-weakmap": {
"version": "1.0.2",
"resolved": "https://registry.npmmirror.com/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
"integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
"dependencies": {
"call-bound": "^1.0.2",
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.5",
"object-inspect": "^1.13.3",
"side-channel-map": "^1.0.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/signal-exit": { "node_modules/signal-exit": {
"version": "4.1.0", "version": "4.1.0",
"resolved": "https://registry.npmmirror.com/signal-exit/-/signal-exit-4.1.0.tgz", "resolved": "https://registry.npmmirror.com/signal-exit/-/signal-exit-4.1.0.tgz",

View File

@@ -15,6 +15,7 @@
"element-plus": "^2.9.0", "element-plus": "^2.9.0",
"flv.js": "^1.6.2", "flv.js": "^1.6.2",
"pinia": "^2.2.6", "pinia": "^2.2.6",
"qs": "^6.13.1",
"vue": "^3.5.13", "vue": "^3.5.13",
"vue-countup-v3": "^1.4.2", "vue-countup-v3": "^1.4.2",
"vue-echarts": "^7.0.3", "vue-echarts": "^7.0.3",

View File

@@ -1,7 +1,9 @@
import axios from 'axios' import axios from 'axios'
import qs from 'qs' import qs from 'qs'
import router from '@/router' import { useRouter } from 'vue-router'
import { Message } from 'element-ui' import { ElMessage } from 'element-plus'
const router = useRouter()
const CODE_MESSAGE = { const CODE_MESSAGE = {
200: '服务器成功返回请求数据', 200: '服务器成功返回请求数据',
@@ -79,7 +81,7 @@ const handleData = async ({ data, status, statusText }) => {
} else { } else {
// 是否显示高亮错误(与errorHandler钩子触发逻辑一致) // 是否显示高亮错误(与errorHandler钩子触发逻辑一致)
// $baseMessage(errMsg, 'error', 'vab-hey-message-error', false) // $baseMessage(errMsg, 'error', 'vab-hey-message-error', false)
Message({ ElMessage({
message: errMsg, message: errMsg,
type: 'error', type: 'error',
duration: 5 * 1000 duration: 5 * 1000
@@ -92,7 +94,7 @@ const handleData = async ({ data, status, statusText }) => {
* @description axios初始化 * @description axios初始化
*/ */
const instance = axios.create({ const instance = axios.create({
baseURL: '/dq_api', baseURL: 'http://36.138.38.16:8001/fjtcc-api',
timeout: 100000, timeout: 100000,
headers: { headers: {
'Content-Type': 'application/json;charset=UTF-8' 'Content-Type': 'application/json;charset=UTF-8'

57
src/api/sentiment.js Normal file
View 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'
})
}

View File

@@ -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,
})
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 710 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 497 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 650 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 662 B

View File

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 6.7 KiB

View File

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

View File

@@ -20,8 +20,8 @@
</template> </template>
<script setup> <script setup>
import primary from '@/assets/images/item-1.png' import primary from '@/assets/images/item-primary.png'
import error from '@/assets/images/item-2.png' import error from '@/assets/images/item-error.png'
let loading = ref(true) let loading = ref(true)
let list = ref(0) let list = ref(0)
onMounted(() => { onMounted(() => {

View File

@@ -6,9 +6,9 @@
</div> </div>
<div class="count"> <div class="count">
<img class="bg" src="@/assets/images/mask-success.png" /> <img class="bg" src="@/assets/images/mask-success.png" />
<div class="flex align-center" :style="{ color }"> <div class="flex align-center">
<countup class="value" :end-val="count" /> <countup class="value" :end-val="count" :style="{ color: color }" />
<span class="suffix">{{ suffix }}</span> <span class="suffix" :style="{ color: color }">{{ suffix }}</span>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -28,20 +28,16 @@
default: () => { default: () => {
return {} return {}
} }
},
dataList: {
type: Array,
default: () => []
} }
}) })
let id = ref(guid()) let id = ref(guid())
let pieChart = null let pieChart = null
var colorList = ['#FDC40A', '#FF5232', '#50F0A6', '#5FDFFA', ''] 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 = { var defaultCofig = {
color: colorList, color: colorList,
@@ -49,7 +45,7 @@
orient: 'vertical', orient: 'vertical',
bottom: 'center', bottom: 'center',
left: '70%', left: '70%',
data: dataList, data: [],
itemWidth: fitChartSize(16), itemWidth: fitChartSize(16),
itemHeight: fitChartSize(16), itemHeight: fitChartSize(16),
itemGap: fitChartSize(10), itemGap: fitChartSize(10),
@@ -93,13 +89,15 @@
labelLine: { labelLine: {
show: false show: false
}, },
data: dataList data: []
} }
] ]
} }
const init = () => {
const initChart = () => {
const dom = document.getElementById(id.value) const dom = document.getElementById(id.value)
pieChart = echarts.init(dom) pieChart = echarts.init(dom)
defaultCofig.series[0].data = props.dataList
pieChart.setOption({ pieChart.setOption({
...defaultCofig, ...defaultCofig,
...props.config ...props.config
@@ -111,12 +109,20 @@
if (pieChart) { if (pieChart) {
pieChart.dispose() pieChart.dispose()
pieChart = null pieChart = null
init() initChart()
} }
} }
onMounted(() => { watch(
init() () => props.dataList,
(newVal) => {
if (newVal.length > 0) {
nextTick(() => {
initChart()
}) })
}
},
{ immediate: true }
)
</script> </script>
<style scoped lang="scss"></style> <style scoped lang="scss"></style>

View File

@@ -72,7 +72,7 @@
/*滚动数字设置*/ /*滚动数字设置*/
.number-item { .number-item {
width: vw(40); width: vw(40);
height: vh(40); height: vw(40);
margin-right: vw(4); margin-right: vw(4);
border-radius: vw(4); border-radius: vw(4);
color: #ffffff; color: #ffffff;

View File

@@ -40,7 +40,17 @@
</div> </div>
</div> </div>
</div> </div>
<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 /> <Map />
</div>
<div class="footer"> <div class="footer">
<div class="left"> <div class="left">
<div> <div>
@@ -112,7 +122,30 @@
<script setup> <script setup>
import countup from 'vue-countup-v3' import countup from 'vue-countup-v3'
import ScrollNumber from '@/components/ScrollNumber/index.vue' 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 count = ref('6945959')
let list = ref([
{
label: '安全异常',
icon: icon8
},
{
label: '排队异常',
icon: icon9
},
{
label: '停车异常',
icon: icon10
},
{
label: '舆论异常',
icon: icon11
}
])
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@@ -141,7 +174,7 @@
.item { .item {
flex: 1; flex: 1;
.label { .label {
margin-bottom: vh(10); margin-bottom: vh(20);
font-weight: 400; font-weight: 400;
font-size: vw(16); font-size: vw(16);
color: rgba(255, 255, 255, 0.9); color: rgba(255, 255, 255, 0.9);
@@ -168,6 +201,29 @@
background: linear-gradient(180deg, #00b7ff 0%, #0033ff 100%); 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 { .footer {
display: flex; display: flex;
width: 100%; width: 100%;

View File

@@ -22,5 +22,30 @@
{ name: '舆情', path: '/sentiment' }, { name: '舆情', path: '/sentiment' },
{ name: '酒店' } { 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> </script>

View File

@@ -1,15 +1,18 @@
<template> <template>
<div class="emotion" id="emotion" /> <div class="area" id="area" />
</template> </template>
<script setup> <script setup>
import * as echarts from 'echarts' import * as echarts from 'echarts'
import { fitChartSize } from '@/utils/dataUtil' import { fitChartSize } from '@/utils/dataUtil'
let emotionChart = null import { getAreaApi } from '@/api/sentiment.js'
const initChart = () => {
const dom = document.getElementById('emotion') let areaChart = null
emotionChart = echarts.init(dom) const initChart = async () => {
emotionChart.setOption({ const dom = document.getElementById('area')
areaChart = echarts.init(dom)
let res = await getAreaApi()
areaChart.setOption({
legend: { legend: {
top: 'top', top: 'top',
itemWidth: fitChartSize(30), itemWidth: fitChartSize(30),
@@ -23,30 +26,27 @@
{ {
name: 'Nightingale Chart', name: 'Nightingale Chart',
type: 'pie', type: 'pie',
radius: ['10%', '70%'], radius: ['30%', '60%'],
center: ['50%', '56%'], center: ['50%', '56%'],
roseType: 'area', roseType: 'area',
labelLine: {
normal: {
show: true,
length: 1
}
},
itemStyle: { itemStyle: {
borderRadius: fitChartSize(10) borderRadius: fitChartSize(10)
}, },
data: [ data: res.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' }
]
} }
] ]
}) })
} }
const resize = () => { const resize = () => {
if (emotionChart) { if (areaChart) {
emotionChart.dispose() areaChart.dispose()
emotionChart = null areaChart = null
initChart() initChart()
} }
} }
@@ -57,7 +57,7 @@
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.emotion { .area {
width: vw(740); width: vw(740);
height: vh(400); height: vh(400);
} }

View File

@@ -8,18 +8,44 @@
<p>敏感舆情</p> <p>敏感舆情</p>
</div> </div>
<div class="list"> <div class="list">
<div class="cell" v-for="(item, index) in 10" :key="index"> <div class="cell" v-for="(item, index) in list" :key="index">
<p><span class="index">排名</span></p> <p>
<p><span class="name">手机新浪网</span></p> <span
<p><span class="name">新闻</span></p> class="index"
<p><span class="number">580</span></p> :class="{ first: item.rank == 1, second: item.rank == 2, third: item.rank == 3 }"
<p><span class="status">1000</span></p> >
{{ 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> </div>
</div> </div>
</template> </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"> <style scoped lang="scss">
.table { .table {
@@ -84,6 +110,18 @@
border-radius: vw(2); border-radius: vw(2);
background-color: #495c77; background-color: #495c77;
} }
.first {
@extend .index;
background-color: #d9011b;
}
.second {
@extend .index;
background-color: #feae00;
}
.third {
@extend .index;
background-color: #2380fb;
}
.name { .name {
font-weight: 400; font-weight: 400;
font-size: vw(15); font-size: vw(15);

View File

@@ -6,11 +6,13 @@
import * as echarts from 'echarts' import * as echarts from 'echarts'
import 'echarts-wordcloud' import 'echarts-wordcloud'
import { fitChartSize } from '@/utils/dataUtil' import { fitChartSize } from '@/utils/dataUtil'
import { getHotWordApi } from '@/api/sentiment'
let wordChart = null let wordChart = null
const initChart = () => { const initChart = async () => {
const dom = document.getElementById('wordCloud') const dom = document.getElementById('wordCloud')
wordChart = echarts.init(dom) wordChart = echarts.init(dom)
let res = await getHotWordApi()
wordChart.setOption({ wordChart.setOption({
//你的代码 //你的代码
series: [ series: [
@@ -45,56 +47,7 @@
padding: fitChartSize(10), padding: fitChartSize(10),
backgroundColor: 'rgba(0,255,255,.2)' backgroundColor: 'rgba(0,255,255,.2)'
}, },
data: [ data: res.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: '空转走单'
}
]
} }
] ]
}) })
@@ -115,6 +68,6 @@
<style scoped lang="scss"> <style scoped lang="scss">
.wordCloud { .wordCloud {
width: vw(760); width: vw(760);
height: vh(420); height: vh(410);
} }
</style> </style>

View File

@@ -6,36 +6,36 @@
<div class="box-1 mr-10"> <div class="box-1 mr-10">
<Title1 title="最新舆情" /> <Title1 title="最新舆情" />
<div class="list"> <div class="list">
<div class="item" v-for="item in 20"> <div class="item" v-for="(item, index) in hotNewList" :key="index">
<p class="status status-error">负面</p> <p class="status status-error">{{ item.type }}</p>
<p class="content"> <p class="content">
这是一条关于三侠之颠旅游舆情的负面新闻这是一条关于三侠之颠旅游舆情的负面这是一条关于三侠之颠旅游舆情的负面新闻这是一条关于三侠之颠旅游舆情的负面 {{ item.title }}
</p> </p>
<p class="date">2024-12.16 23:58</p> <p class="date">{{ item.time }}</p>
</div> </div>
</div> </div>
</div> </div>
<div class="box-2 mr-10"> <div class="box-2 mr-10">
<div class="flex justify-center"> <div class="flex justify-center">
<div class="top flex justify-evenly"> <div class="top flex justify-evenly">
<count-item label="今日舆情总数" :count="35600" suffix="条" color="#fff" /> <count-item label="今日舆情总数" :count="total" suffix="条" color="#ffffff" />
<count-item label="今日正面舆情" :count="35600" suffix="条" color="#fff" /> <count-item label="今日正面舆情" :count="sensitive" suffix="条" color="#ffffff" />
<count-item label="今日负面舆情" :count="35600" suffix="条" color="#fff" /> <count-item label="今日负面舆情" :count="unsensitive" suffix="条" color="#ffffff" />
</div> </div>
</div> </div>
<div class="flex mt-20 gap-8 ml-8 mr-8"> <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="山峡之巅" /> <Title3 title="山峡之巅" />
<pie-row :width="500" :height="330" /> <pie-row :width="500" :height="330" />
</div> </div>
<div class="border flex-1"> <div class="border flex-1">
<Title3 title="山峡之巅" /> <Title3 title="山峡之巅" />
<pie-row :width="500" :height="330" /> <pie-row :width="500" :height="330" />
</div> </div> -->
<div class="border flex-1">
<Title3 title="山峡之巅" />
<pie-row :width="500" :height="330" />
</div>
</div> </div>
</div> </div>
<div class="box-1"> <div class="box-1">
@@ -49,23 +49,14 @@
<Line <Line
:width="1560" :width="1560"
:height="400" :height="400"
:data="[ :data="seriesData"
{
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]
}
]"
:xAxisData="xAxisData" :xAxisData="xAxisData"
:seriesConfig="{ smooth: false, symbol: 'circle' }" :seriesConfig="{ smooth: false, symbol: 'circle' }"
/> />
</div> </div>
<div class="box-1 mr-10"> <div class="box-1 mr-10">
<Title1 title="情感分布" /> <Title1 title="地域分析" />
<emotion /> <Area />
</div> </div>
<div class="box-1 mr-10"> <div class="box-1 mr-10">
<Title1 title="词频分析" /> <Title1 title="词频分析" />
@@ -77,27 +68,45 @@
</template> </template>
<script setup> <script setup>
import emotion from './components/emotion.vue' import Area from './components/area.vue'
import wordCloud from './components/wordCloud.vue' import wordCloud from './components/wordCloud.vue'
import dataSource from './components/dataSource.vue' import dataSource from './components/dataSource.vue'
let xAxisData = ref([ import { getHotNewApi, getLineChartApi, getStateApi, getTotalApi } from '@/api/sentiment.js'
'12-16 10:00',
'12-16 14:00', let seriesData = ref([])
'12-16 16:00', let xAxisData = ref([])
'12-16 22:00', let hotNewList = ref([])
'12-17 02:00', let total = ref(0)
'12-17 06:00', let sensitive = ref(0)
'12-17 10:00', let unsensitive = ref(0)
'12-17 14:00', let stateList = ref([])
'12-17 16:00',
'12-16 22:00', const getTotal = async () => {
'12-18 02:00', let res = await getTotalApi()
'12-18 06:00', total.value = res.data.total
'12-8 10:00', sensitive.value = res.data.sensitive
'12-18 14:00', unsensitive.value = res.data.unsensitive
'12-18 16:00', }
'12-18 20:00' 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> </script>
<style scoped lang="scss"> <style scoped lang="scss">