提交 d8ab6319 authored 作者: huhuiqing's avatar huhuiqing

今日风险

上级 1791c84c
<template>
<div ref="ballDom" class="ball-box" :style="{ width: '128px', height: '128px' }" />
</template>
<script setup>
/**
* Vue3 水波进度球
* 用法:<WaterBall :percent="67" :size="200" />
*/
import { ref, watch, onMounted } from 'vue'
import * as echarts from 'echarts'
import 'echarts-liquidfill'
/* props */
const props = defineProps({
percent: { type: Number, default: 60 }, // 0~100
size: { type: Number, default: 200 }, // 画布宽高
data: { type: Object, default: {} },
color: { type: Array, default: [] },
})
/* dom */
const ballDom = ref(null)
let instance = null
// const color = ref([0, 0, 0])
// const makeColors = () => {
// props.color[0] = Math.floor(Math.random() * 360) // 随机色相
// props.color[1] = 70 // 固定饱和度
// props.color[2] = 50 // 固定亮度
// }
/* 颜色映射 */
/* 配置项 */
const makeOption = () => {
const p = Math.min(100, Math.max(0, props.percent)) / 100
console.log(props.color, 'colorcolorcolor')
return {
series: [{
type: 'liquidFill',
radius: '90%',
data: [
{ value: p, direction: 'right' },
{ value: p, direction: 'left' } // 两层波浪反向
],
color: [` ${props.color[1]}`, ` ${props.color[0]}`],
waveAnimation: true,
animationEasingUpdate: 'cubicOut',
outline: {
show: true,
borderDistance: 2, // 第一层边框
itemStyle: {
shadowBlur: 0, // 同样设为 0
borderWidth: 1,
borderColor: `${props.color[0]}`,
shadowColor: 'transparent'
}
},
// 1. 关掉波浪的阴影
itemStyle: {
shadowBlur: 0, // 关键:阴影范围设为 0
shadowColor: 'transparent'
},
backgroundStyle: {
color: `${props.color[2]}`,
borderWidth: 1,
borderColor: `${props.color[1]}`, // 中间区域保持透明
shadowBlur: 0
},
label: {
show: true,
formatter: `${props.data.change}` + `${props.data.unit}`,
fontSize: 24,
color: `${props.color[3]}`,
insideColor: `${props.color[3]}`,
}
}]
}
}
/* 初始化 */
const init = () => {
if (instance) instance.dispose()
instance = echarts.init(ballDom.value)
instance.setOption(makeOption())
}
/* 自动更新 */
watch(() => props.percent, () => {
instance?.setOption(makeOption())
})
onMounted(init)
</script>
<style scoped>
.ball-box {
margin: 0 auto;
}
</style>
\ No newline at end of file
<!--今日风险-->
<template>
<div class="content-wrapper">
今日风险
<div class="policy-monitoring">
<div class="header">
<div class="section" v-for="(section, index) in sectionTab" :key="index"
:style="sections[index].length === 2 ? 'width: 350px' : 'width:503px'">
<img class="section-title" :src="`/public/icon/riskToday/btn-` + index + `.png`" />
<div class="stats">
<div v-for="value in sections[index].waveBall">
<WaveBall :percent="value.percent" :data="value" :color="section.waterColor" :size="128" />
<div class="waveBall-text">{{ value.title }}</div>
</div>
</div>
<div class="bottm-box">
<img src="./icon/title-icon-1.png" />
<div style="width: 225px">
{{ sections[index].title }}
</div>
<div style="width: 50px; color: rgba(132, 136, 142, 1)">
{{ sections[index].date }}
</div>
</div>
</div>
</div>
<div class="content">
<div class="content-title">
<img class="section-title" src="./icon/title-icon-2.png" />
<div>风险信号</div>
<div class="num">12</div>
</div>
<div style="display: flex">
<div class="risk-signals">
<div class="risk-signals-item" v-for="(item, index) in warningList" :key="index"
@click="handleClickToDetailO(item)">
<div class="item-left" :class="{
itemLeftStatus1: item.signalLevel === '特别重大',
itemLeftStatus2: item.signalLevel === '重大风险'
}">
{{ item.signalLevel ? item.signalLevel : "一般风险" }}
</div>
<div class="item-right">
<div class="text">
{{ item.signalTitle }}
</div>
<div class="time">{{ item.signalTime }}</div>
</div>
</div>
</div>
<div class="news">
<div class="box1-left" @click="handleSwithCurNews('left')">
<div class="icon">
<img src="./icon/box1-left.png" alt="" />
</div>
</div>
<div class="box1-right" @click="handleSwithCurNews('right')">
<div class="icon">
<img src="./icon/box1-right.png" alt="" />
</div>
</div>
<el-carousel ref="carouselRef" style="height: 412px; width: 736px" :autoplay="true" :interval="3000"
arrow="never" indicator-position="none" @change="handleCarouselChange">
<el-carousel-item v-for="(News, NewsIndex) in hotNewsList" :key="NewsIndex">
<div class="carousel-item">
<div class="carousel-title">
<div class="title-text">
{{ News.title }}
</div>
<div class="title-tag">
{{ News.category }}
</div>
</div>
<div style="/* 矩形 351 */ width: 664px; height: 1px; background: rgba(234, 236, 238, 1)"></div>
<div class="carousel-content">{{ News.content }}</div>
<div style="/* 矩形 351 */ width: 664px; height: 1px; background: rgba(234, 236, 238, 1)"></div>
<div class="carousel-bottom">
<div class="carousel-bottom">{{ News.date + News.source }}</div>
</div>
</div>
</el-carousel-item>
</el-carousel>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { color } from "echarts";
import { onMounted, ref, computed } from "vue";
import WaveBall from "./WaveBall.vue";
import { getBillRiskSignal } from "@/api/bill/billHome";
const sectionTab = [
{
textColor: "rgba(9, 88, 217, 1)",
borderColor: "rgba(186, 224, 255, 1)",
waterColor: ["#A6CCFF", "#C2DEFF", "#ECF7FF", "#0758D9"],
title: "政策法规"
},
{
textColor: "rgba(9, 88, 217, 1)",
borderColor: "rgba(186, 224, 255, 1)",
waterColor: ["#A6CCFF", "#C2DEFF", "#ECF7FF", "#0758D9"],
title: "出口管制"
},
{
textColor: "rgba(9, 88, 217, 1)",
borderColor: "rgba(186, 224, 255, 1)",
waterColor: ["#A6CCFF", "#C2DEFF", "#ECF7FF", "#0758D9"],
title: "投融资限制"
},
{
textColor: "rgba(9, 88, 217, 1)",
borderColor: "rgba(186, 224, 255, 1)",
waterColor: ["#A6CCFF", "#C2DEFF", "#ECF7FF", "#0758D9"],
title: "市场准入"
}
];
// 模拟从后端获取的数据
const sections = ref([
{
title: "政令:确保美国太空优势",
date: "12-18",
waveBall: [
{
percent: 30, // 估算的百分比
count: 1626,
change: "+3",
unit: "项",
title: "法案(提出)"
},
{
percent: 20, // 估算的百分比
count: 69,
change: "+2",
unit: "个",
title: "政令"
}
]
},
{
title: "对实体清单的更新及修订",
date: "12-18",
waveBall: [
{
percent: 10, // 估算的百分比
count: 128,
change: "+1",
unit: "次",
title: "实体清单"
},
{
percent: 20, // 估算的百分比
count: 69,
change: "+1",
unit: "次",
title: "CCL"
}
]
},
{
title: "SDN清单更新",
waveBall: [
{
percent: 15, // 估算的百分比
count: 35,
change: "+1",
unit: "次",
title: "SDN"
},
{
percent: 5, // 估算的百分比
count: 28,
change: "+1",
unit: "家",
title: "涉军企业"
}
]
},
{
title: "232调查:商用飞机和喷气发动机进口对国家安全的...",
date: "12-18",
waveBall: [
{
percent: 3, // 估算的百分比
count: 215,
change: "+1",
unit: "次",
title: "337调查"
},
{
percent: 3, // 估算的百分比
count: 14,
change: "无新增",
unit: "次",
title: "230调查"
},
{
percent: 3, // 估算的百分比
count: 9,
change: "无新增",
unit: "次",
title: "301调查"
}
]
}
]);
// 风险信号
const warningList = ref([]);
// 获取法案风险信号
const handlegetBillRiskSignal = async () => {
const params = {
moduleId: "0100"
};
try {
const res = await getBillRiskSignal(params);
console.log("法案风险信号", res);
if (res.code === 200) {
warningList.value = res.data;
}
} catch (error) { }
};
const hotNewsList = ref([
{
title: "美国白宫发布关于进一步延长TikTok执法宽限期的行政令",
category: "政策及立法打压风险",
content:
"2025年1月20日第14166号行政命令第2(a)条(《保护美国免受外国对抗者控制应用法案》对TikTok的适用)规定的执行延迟,并由2025年4月4日第14258号行政命令(延长TikTok执法延迟)和2025年6月19日第14310号行政命令(进一步延长TikTok执法延迟)所延长,进一步延长至2025年12月16日。在此期间,司法部不得采取任何行动执行《保护美国人免受外国对抗者控制应用法案》(以下简称“法案”)(公共法118-50,H部),也不得对任何违反该法案的实体处以任何处罚,包括分发、维护、更新(或促成分发,维护或更新任何外国对手控制的应用,如本法所定义。鉴于本指示,即使在上述规定期限届满后,司法部也应继续与相关部门合作,以确保美国国家安全和公民隐私权利不受威胁。",
date: "2025年9月16日",
source: "美国白宫·总统行政令"
},
{
title: "美国白宫发布关于进一步延长TikTok执法宽限期的行政令",
category: "政策及立法打压风险",
content:
"2025年1月20日第14166号行政命令第2(a)条(《保护美国免受外国对抗者控制应用法案》对TikTok的适用)规定的执行延迟,并由2025年4月4日第14258号行政命令(延长TikTok执法延迟)和2025年6月19日第14310号行政命令(进一步延长TikTok执法延迟)所延长,进一步延长至2025年12月16日。在此期间,司法部不得采取任何行动执行《保护美国人免受外国对抗者控制应用法案》(以下简称“法案”)(公共法118-50,H部),也不得对任何违反该法案的实体处以任何处罚,包括分发、维护、更新(或促成分发,维护或更新任何外国对手控制的应用,如本法所定义。鉴于本指示,即使在上述规定期限届满后,司法部也应继续与相关部门合作,以确保美国国家安全和公民隐私权利不受威胁。",
date: "2025年9月16日",
source: "美国白宫·总统行政令"
}
]);
const curNews = ref({});
const carouselRef = ref(null);
const curHotNewsListIndex = ref(0);
const handleCarouselChange = index => {
curHotNewsListIndex.value = index;
if (hotNewsList.value && hotNewsList.value.length > 0) {
curNews.value = hotNewsList.value[index];
}
};
const handleSwithCurNews = name => {
if (name === "left") {
carouselRef.value.prev();
} else {
carouselRef.value.next();
}
};
onMounted(() => {
// 这里可以添加从后端获取数据的代码
handlegetBillRiskSignal();
console.log("页面加载完成,可以获取数据了");
});
</script>
<style lang="scss" scoped>
......@@ -16,5 +269,368 @@ import { onMounted, ref, computed } from "vue";
width: 100%;
height: 100%;
.policy-monitoring {
font-family: Arial, sans-serif;
}
.header {
display: flex;
justify-content: space-around;
margin-bottom: 20px;
}
.content {
/* 容器 83 */
width: 1601px;
height: 495px;
box-sizing: border-box;
border: 1px solid rgba(255, 255, 255, 1);
border-radius: var(---10, 10px);
/* 业务系统/模块阴影 */
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background: rgba(255, 255, 255, 0.65);
.content-title {
/* 块级标题 */
width: 1602px;
height: 48px;
box-sizing: border-box;
border-bottom: 1px solid rgba(255, 255, 255, 1);
background: linear-gradient(180deg, rgba(255, 241, 240, 0.5), rgba(255, 241, 240, 0) 100%);
color: rgba(206, 79, 81, 1);
font-family: YouSheBiaoTiHei;
font-style: Regular;
font-size: 24px;
font-weight: 400;
line-height: 31px;
letter-spacing: 0px;
text-align: left;
display: flex;
img {
/* 矢量 347 */
width: 22px;
height: 18px;
}
.num {
/* 数据展示/Badge徽标数/亮色/数字 */
height: 22px;
/* 自动布局 */
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: flex-start;
gap: 10;
padding: 0px 8px 0px 8px;
border-radius: 100px;
background: rgba(206, 79, 81, 1);
color: rgba(255, 255, 255, 1);
margin: 12px;
font-family: Microsoft YaHei;
font-style: Regular;
font-size: 14px;
font-weight: 400;
line-height: 22px;
letter-spacing: 0px;
text-align: center;
}
}
}
.section {
/* 容器 535 */
width: 350px;
height: 320px;
box-sizing: border-box;
border: 1px solid rgba(255, 255, 255, 1);
border-radius: var(---10, 10px);
/* 业务系统/模块阴影 */
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background: rgba(255, 255, 255, 0.65);
}
.section-title {
margin: 8px 16px;
/* 容器 1559 */
width: 125px;
height: 31px;
}
.stats {
/* 容器 519 */
height: 210px;
display: flex;
justify-content: left;
margin-top: 10px;
.waveBall-text {
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-style: Bold;
font-size: 20px;
font-weight: 700;
line-height: 26px;
letter-spacing: 0px;
text-align: center;
}
}
.bottm-box {
/* 容器 1561 */
display: flex;
width: 350px;
height: 48px;
/* 自动布局 */
flex-direction: row;
justify-content: flex-start;
align-items: center;
// gap: 15;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-style: Regular;
font-size: 16px;
font-weight: 400;
line-height: 24px;
letter-spacing: 0px;
text-align: left;
img {
/* 矢量 1667 */
width: 12px;
height: 16px;
margin: 16px 20px;
}
}
.risk-signals {
width: 780px;
height: 330px;
overflow-y: auto;
overflow-x: hidden;
box-sizing: border-box;
padding-right: 20px;
.risk-signals-item {
margin-left: 23px;
height: 47px;
width: 780px;
display: flex;
cursor: pointer;
&:hover {
background: var(--color-bg-hover);
}
.itemLeftStatus1 {
color: rgba(245, 34, 45, 1) !important;
background: rgba(255, 241, 240) !important;
}
.itemLeftStatus2 {
color: rgba(250, 140, 22, 1) !important;
background: rgba(255, 247, 230, 1) !important;
}
.item-left {
margin-top: 4px;
margin-left: 2px;
width: 40px;
height: 40px;
border-radius: 20px;
color: rgba(82, 196, 26, 1);
background: rgba(246, 255, 237, 1);
font-family: Microsoft YaHei;
font-size: 12px;
font-weight: 400;
line-height: 14px;
box-sizing: border-box;
padding: 6px 4px;
text-align: center;
}
.item-right {
margin-left: 13px;
width: 722px;
height: 47px;
border-bottom: 1px solid rgba(240, 242, 244, 1);
display: flex;
.text {
width: 653px;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 47px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.time {
width: 88px;
margin-left: 5px;
line-height: 47px;
color: rgba(132, 136, 142, 1);
font-family: Microsoft YaHei;
font-size: 14px;
font-weight: 400;
text-align: center;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
}
}
.news {
/* 容器 1567 */
width: 760px;
height: 491px;
/* 自动布局 */
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: flex-start;
gap: 16;
padding: 24px 48px 24px 48px;
box-sizing: border-box;
border: 1px solid rgba(234, 236, 238, 1);
border-radius: 10px;
background: rgba(255, 255, 255, 0.65);
position: relative;
.box1-left {
position: absolute;
left: 0;
top: 200px;
width: 24px;
height: 48px;
background: #e7f1ff;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
z-index: 10;
.icon {
width: 11px;
height: 18px;
img {
width: 100%;
height: 100%;
}
}
}
.box1-right {
position: absolute;
right: 0;
top: 200px;
width: 24px;
height: 48px;
background: #e7f1ff;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
z-index: 10;
.icon {
width: 11px;
height: 18px;
img {
width: 100%;
height: 100%;
}
}
}
.carousel-item {
height: 480px;
width: 736px;
.carousel-title {
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-style: Bold;
font-size: 20px;
font-weight: 700;
line-height: 26px;
letter-spacing: 0px;
text-align: justify;
.title-text {
/* 美国白宫发布关于进一步延长TikTok执法宽限期的行政令 */
width: 547px;
height: 26px;
}
.title-tag {
/* 容器 1563 */
width: 190px;
height: 30px;
/* 自动布局 */
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: flex-start;
gap: 10;
padding: 0px 12px 0px 12px;
border-radius: 20px;
background: rgba(206, 79, 81, 0.1);
color: rgba(206, 79, 81, 1);
font-family: Microsoft YaHei;
font-style: Regular;
font-size: 16px;
font-weight: 400;
line-height: 30px;
letter-spacing: 0px;
text-align: justify;
}
}
.carousel-content {
width: 664px;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-style: Regular;
font-size: 16px;
font-weight: 400;
line-height: 30px;
letter-spacing: 0px;
text-align: justify;
}
}
}
h3 {
margin-bottom: 10px;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: flex;
justify-content: space-between;
margin-bottom: 5px;
}
}
</style>
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论