提交 940739d0 authored 作者: huhuiqing's avatar huhuiqing

Merge branch 'master' of http://8.140.26.4:10003/caijian/risk-monitor into dev_hhq

......@@ -103,9 +103,9 @@ const router = useRouter();
const handleToHome = () => {
router.push({
path: '/overview'
})
}
path: "/overview"
});
};
const isShowAiBox = ref(false);
......@@ -307,6 +307,7 @@ body {
position: absolute;
bottom: 20%;
right: 46px;
z-index: 9999;
cursor: pointer;
.icon {
......
差异被折叠。
......@@ -146,6 +146,7 @@ const headerTitleClasses = computed(() => [
}
.header-title {
font-family: $base-font-family;
font-size: $base-font-size;
font-weight: 700;
/* color: var(--color-main-active); */
......
// 人物主页
import CharacterPage from "@/views/characterPage/index.vue";
const characterPageRoutes = [
// 人物主页
{
// 根据不同的type跳转到不同的页面,type=1为科技领袖,2为国会议员,3为智库研究人员
path: "/characterPage/:type?",
name: "CharacterPage",
component: CharacterPage,
meta: {
title: "人物主页"
}
}
]
export default characterPageRoutes
......@@ -3,6 +3,7 @@
$primary-color: var(--el-color-primary);
$base-color: rgba(5, 95, 194, 1);
$base-font-size: 16px;
$base-font-family: "微软雅黑";
// :root {
// --base-color: #{$base-color};
......
......@@ -276,7 +276,7 @@
</div>
<div class="box4-main">
<div class="box4-main-item" v-for="(item, index) in messageList" :key="index">
<div class="left">
<div class="left" @click="handleClcikToCharacter(index)">
<img :src="item.img" alt="" />
</div>
<div class="right">
......@@ -379,7 +379,12 @@
</el-select>
</div>
<div class="box8-main">
<div class="box8-main-item" v-for="(item, index) in box8Data" :key="index">
<div
class="box8-main-item"
v-for="(item, index) in box8Data"
:key="index"
@click="handleClcikToCharacter(0)"
>
<div class="box8-main-item-left">
<img :src="item.img" alt="" />
<div class="left-icon1">
......@@ -558,7 +563,36 @@
</div>
</div>
<div class="right-main">
<div class="right-main-box"></div>
<div class="right-main-box" v-for="(item, index) in footerBillList" :key="index">
<div class="header">
<div class="title">{{ item.name }}</div>
<div class="en-title">{{ item.eName }}</div>
</div>
<div class="main">
<div class="item">
<div class="item-left">{{ "提案人:" }}</div>
<div class="item-right">{{ item.tcr }}</div>
</div>
<div class="item">
<div class="item-left">{{ "委员会:" }}</div>
<div class="item-right">{{ item.wyh }}</div>
</div>
<div class="item">
<div class="item-left">{{ "相关领域:" }}</div>
<div class="item-right1">
<div class="tag" v-for="(val, idx) in item.areaList" :key="idx">{{ val }}</div>
</div>
</div>
<div class="item">
<div class="item-left">{{ "最新动议:" }}</div>
<div class="item-right">{{ item.zxdy }}</div>
</div>
<div class="item">
<div class="item-left">{{ "法案进展:" }}</div>
<div class="item-right2"></div>
</div>
</div>
</div>
<div class="right-main-box"></div>
<div class="right-main-box"></div>
<div class="right-main-box"></div>
......@@ -648,9 +682,29 @@ import Cyy from "@/assets/icons/cyy.png";
import Zyy from "@/assets/icons/zyy.png";
import Ghd from "@/assets/icons/ghd.png";
import Mzd from "@/assets/icons/mzd.png";
import { iteratee } from "lodash";
const searchBillText = ref("");
// 跳转人物主页
const handleClcikToCharacter = index => {
let type;
if (index === 0) {
type = 2;
} else if (index === 1) {
type = 1;
} else {
type = 3;
}
const route = router.resolve({
path: "/characterPage",
query: {
type: type
}
});
window.open(route.href, "_blank");
};
// 返回首页
const handleBackHome = () => {
router.push({
......@@ -1455,6 +1509,36 @@ const footerSelectList2 = ref([
]);
const footerSelect2 = ref("全部提出议员");
const footerBillList = ref([
{
name: "H.R.1-大而美法案",
eName: "One Big Beautiful Bill Act",
tcr: "乔迪·阿灵顿等2人",
wyh: "众议院-预算委员会",
areaList: ["集成电路", "人工智能"],
zxdy: "2025.07.04 成为公法 No: 119-21",
progress: []
},
{
name: "H.R.1-大而美法案",
eName: "One Big Beautiful Bill Act",
tcr: "乔迪·阿灵顿等2人",
wyh: "众议院-预算委员会",
areaList: ["集成电路", "人工智能"],
zxdy: "2025.07.04 成为公法 No: 119-21",
progress: []
},
{
name: "H.R.1-大而美法案",
eName: "One Big Beautiful Bill Act",
tcr: "乔迪·阿灵顿等2人",
wyh: "众议院-预算委员会",
areaList: ["集成电路", "人工智能"],
zxdy: "2025.07.04 成为公法 No: 119-21",
progress: []
}
]);
onMounted(async () => {
handleGetHylyList();
......@@ -2406,6 +2490,7 @@ onUnmounted(() => {});
margin-top: 5px;
width: 36px;
height: 36px;
cursor: pointer;
img {
width: 100%;
height: 100%;
......@@ -2733,12 +2818,17 @@ onUnmounted(() => {});
height: 340px;
.box8-main-item {
margin: 0 auto;
width: 458px;
width: 478px;
height: 51px;
margin-bottom: 16px;
display: flex;
align-items: center;
position: relative;
padding: 0 10px;
cursor: pointer;
&:hover {
background: var(--color-bg-hover);
}
.box8-main-item-left {
position: relative;
width: 42px;
......@@ -2801,7 +2891,7 @@ onUnmounted(() => {});
.box8-main-item-right {
position: absolute;
top: 0;
right: 0;
right: 10px;
width: 92px;
height: 51px;
text-align: right;
......@@ -3001,13 +3091,90 @@ onUnmounted(() => {});
}
.right-main {
height: 1264px;
overflow: hidden;
.right-main-box {
width: 1280px;
height: 300px;
border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
box-shadow: 0px 0px 10px 0px rgba(25, 69, 130, 0.1);
background: rgba(255, 255, 255, 1);
margin-bottom: 16px;
overflow: hidden;
.header {
height: 91px;
width: 1200px;
margin: 0 auto;
border-bottom: 1px solid rgba(234, 236, 238, 1);
.title {
margin-top: 19px;
height: 26px;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 700;
line-height: 26px;
letter-spacing: 0px;
text-align: left;
}
.en-title {
margin-top: 8px;
height: 24px;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 24px;
letter-spacing: 0px;
text-align: left;
}
}
.main {
width: 1200px;
margin: 0 auto;
margin-top: 2px;
.item {
margin-top: 12px;
height: 24px;
display: flex;
.item-left {
width: 91px;
height: 24px;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 700;
line-height: 24px;
letter-spacing: 1px;
text-align: left;
}
.item-right {
margin-left: 10px;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 24px;
letter-spacing: 0px;
text-align: left;
}
.item-right1 {
margin-left: 10px;
display: flex;
gap: 8px;
.tag {
height: 24px;
line-height: 24px;
padding: 0 8px;
border-radius: 4px;
background: rgba(231, 243, 255, 1);
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 14px;
font-weight: 400;
}
}
}
}
}
}
.right-footer {
......
<template>
<div class="character-relationships">
<div class="headerBox">
<span
v-for="(item, index) in list"
:key="index"
class="headerItem"
:class="{ active: item === activeIndex }"
@click="activeIndex = item"
>{{ item }}</span
>
</div>
<div class="headerBtnBox"><img src="./assets/下载按钮.png" alt="" /><img src="./assets/收藏按钮.png" alt="" /></div>
<!-- 主要内容,人物关系图 -->
<div class="mainBox">
<div class="graph" id="relGraph"></div>
</div>
</div>
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount, watch } from "vue";
import * as echarts from "echarts";
import Center from "./assets/约翰·伦道夫·图恩.png";
import P1 from "./assets/唐纳德·特朗普.png";
import P2 from "./assets/约翰·巴拉索.png";
import P3 from "./assets/布里顿·图恩.png";
import P4 from "./assets/金伯利·韦姆斯·图恩.png";
import P5 from "./assets/乔治·S·米克尔森.png";
import P6 from "./assets/哈罗德·理查德·图恩.png";
import P7 from "./assets/伊冯娜·帕特里夏·图恩.png";
import P8 from "./assets/蒂姆·约翰逊.png";
import P9 from "./assets/吉姆·阿布德诺.png";
import P10 from "./assets/汤姆·达施勒.png";
import P11 from "./assets/拉里莎·图恩.png";
import PS from "./assets/拉里·普雷斯勒.png";
const list = ref(["圆形布局", "力导向布局", "树形布局"]);
const activeIndex = ref("圆形布局");
const nodes = [
{
id: "c",
name: "约翰·伦道夫·图恩",
category: 0,
symbolSize: 80,
symbol: `image://${Center}`,
label: {
show: true,
position: "bottom",
formatter: "{n|约翰·伦道夫·图恩}",
rich: {
n: {
color: "rgba(5,95,194,1)",
fontSize: 24,
fontWeight: 700,
fontFamily: "Microsoft YaHei",
lineHeight: 36
}
}
}
},
// 从三点钟方向顺时针排序
{ id: "n11", name: "拉里莎·图恩", category: 1, symbolSize: 80, symbol: `image://${P11}` },
{ id: "n7", name: "伊冯娜·帕特里夏·图恩", category: 1, symbolSize: 80, symbol: `image://${P7}`, r: 80 },
{ id: "n6", name: "哈罗德·理查德·图恩", category: 1, symbolSize: 80, symbol: `image://${P6}` },
{ id: "n9", name: "吉姆·阿布德诺", category: 1, symbolSize: 80, symbol: `image://${P9}` },
{ id: "n12", name: "拉里·普雷斯勒", category: 1, symbolSize: 80, symbol: `image://${PS}` },
{ id: "n5", name: "乔治·S·米克尔森", category: 1, symbolSize: 80, symbol: `image://${P5}`, r: 80 },
{ id: "n8", name: "蒂姆·约翰逊", category: 1, symbolSize: 80, symbol: `image://${P8}` },
{ id: "n10", name: "汤姆·达施勒", category: 1, symbolSize: 80, symbol: `image://${P10}`, r: 80 },
{ id: "n2", name: "约翰·巴拉索", category: 1, symbolSize: 80, symbol: `image://${P2}` },
{ id: "n1", name: "唐纳德・特朗普", category: 1, symbolSize: 80, symbol: `image://${P1}` },
{ id: "n4", name: "金伯利·韦姆斯·图恩", category: 1, symbolSize: 80, symbol: `image://${P4}` },
{ id: "n3", name: "布里顿·图恩", category: 1, symbolSize: 80, symbol: `image://${P3}`, r: 80 }
];
const links = [
{ source: "n11", target: "c", label: { show: true, formatter: "次女" } },
{ source: "n7", target: "c", label: { show: true, formatter: "母亲" } },
{ source: "n6", target: "c", label: { show: true, formatter: "父亲" } },
{ source: "n9", target: "c", label: { show: true, formatter: "" } },
{ source: "n12", target: "c", label: { show: true, formatter: "盟友" } },
{ source: "n5", target: "c", label: { show: true, formatter: "前南达科他州州长" } },
{ source: "n8", target: "c", label: { show: true, formatter: "政治对手" } },
{ source: "n10", target: "c", label: { show: true, formatter: "政治对手" } },
{ source: "n2", target: "c", label: { show: true, formatter: "亲密盟友" } },
{ source: "n1", target: "c", label: { show: true, formatter: "政治盟友" } },
{ source: "n4", target: "c", label: { show: true, formatter: "妻子" } },
{ source: "n3", target: "c", label: { show: true, formatter: "长女" } }
];
let chart;
onMounted(() => {
const el = document.getElementById("relGraph");
if (!el) return;
chart = echarts.init(el);
const setOption = () => {
const rect = el.getBoundingClientRect();
const cx = rect.width / 2;
const cy = rect.height / 2;
const radius = Math.min(cx, cy) - 140;
const dataNodes = nodes.map((n, i) => {
if (n.id === "c") {
return { ...n, x: cx, y: cy, fixed: true };
}
// 均匀环形分布
const idx = i - 1;
const angle = (idx / (nodes.length - 1)) * Math.PI * 2;
const rLocal = radius + (n.r || 0);
const x = cx + rLocal * Math.cos(angle);
const y = cy + rLocal * Math.sin(angle);
return { ...n, x, y };
});
chart.setOption({
tooltip: {},
series: [
{
type: "graph",
layout: activeIndex.value === "圆形布局" ? "none" : "force",
circular: { rotateLabel: true },
force: { repulsion: 800, edgeLength: [80, 160] },
roam: true,
data: activeIndex.value === "圆形布局" ? dataNodes : nodes,
links: links,
edgeSymbol: ["none", "arrow"],
edgeSymbolSize: [4, 10],
lineStyle: { color: "rgba(174,214,255,1)", width: 2, opacity: 0.8 },
edgeLabel: {
show: true,
position: "middle",
distance: -18,
formatter: ({ data }) => data?.label?.formatter || "",
color: "rgb(5, 95, 194)",
fontSize: 12,
fontWeight: 400,
fontFamily: "Microsoft YaHei",
lineHeight: 24,
backgroundColor: "rgba(231, 243, 255, 1)",
borderRadius: 24,
padding: [0, 12]
},
label: { show: true, position: "bottom", color: "rgb(59,65,75)", fontSize: 16 },
itemStyle: { color: "rgba(5,95,194,1)" },
emphasis: { focus: "adjacency" }
}
]
});
};
setOption();
const onResize = () => chart && chart.resize();
window.addEventListener("resize", onResize);
watch(activeIndex, () => setOption());
onBeforeUnmount(() => {
window.removeEventListener("resize", onResize);
chart && chart.dispose();
});
});
</script>
<style lang="scss" scoped>
* {
padding: 0;
margin: 0;
}
.character-relationships {
width: 1600px;
height: 688px;
background-color: #fff;
margin: 0 auto;
position: relative;
border-radius: 4px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
.headerBox {
position: absolute;
top: 14px;
right: 96px;
.headerItem {
padding: 1px 8px;
border-radius: 4px;
font-size: 16px;
font-weight: 400;
line-height: 30px;
cursor: pointer;
color: rgb(59, 65, 75);
font-family: "Microsoft YaHei";
margin-right: 8px;
border: 1px solid rgb(230, 231, 232);
}
.active {
background-color: rgba(246, 250, 255, 1);
border-color: rgb(5, 95, 194);
color: rgb(5, 95, 194);
}
}
.headerBtnBox {
position: absolute;
top: 14px;
right: 12px;
img {
width: 28px;
height: 28px;
margin-right: 4px;
cursor: pointer;
}
}
.mainBox {
width: 100%;
height: 100%;
padding-top: 42px;
.graph {
width: 100%;
height: 100%;
}
}
}
</style>
<template>
<div class="historical-proposal">
<div class="nav">
<el-input placeholder="搜索关键词" v-model="searchText" :suffix-icon="Search" class="search-input"></el-input>
<div class="select-box">
<el-select v-model="value1" placeholder="请选择" class="select">
<el-option label="全部法案" value="全部法案"></el-option>
</el-select>
<el-select v-model="value2" placeholder="请选择" class="select">
<el-option label="全部领域" value="全部领域"></el-option>
</el-select>
</div>
</div>
<div class="main">
<div v-for="item in list" :key="item.id" class="item">
<div class="img-box">
<img :src="item.img" alt="" class="img" />
<div class="info">
<div class="title">{{ item.title }}</div>
<div>
<span
v-for="(tag, index) in item.tie"
:key="tag"
class="tag"
:class="{ 'tag-1': index == 0, 'tag-2': index == 1 }"
>{{ tag }}</span
>
</div>
</div>
</div>
<div class="info-box">
<div class="box">
<div class="label">法案描述:</div>
<div class="content">{{ item.disc }}</div>
</div>
<div class="box">
<div class="label">法案状态:</div>
<div class="content">{{ item.state }}</div>
</div>
<div class="box">
<div class="label">提案日期:</div>
<div class="content">{{ item.time }}</div>
</div>
</div>
</div>
</div>
<!-- 分页 -->
<div class="pagination-container">
<el-pagination
background
layout="prev, pager, next"
:total="100"
v-model:current-page="currentPage"
class="custom-pagination"
/>
</div>
</div>
</template>
<script setup>
import { ref } from "vue";
import { Search } from "@element-plus/icons-vue";
import img from "./assets/img.png";
const searchText = ref("");
const value1 = ref("全部法案");
const value2 = ref("全部领域");
const currentPage = ref(2);
const list = ref([
{
id: 1,
title: "FY2025 National Defense Authorization Act (NDAA, S.4638)",
tie: ["法案", "国防与军事"],
disc: "提供2.82亿美元用于Ellsworth空军基地B-21轰炸机任务和军事建设,包括现代化指令。图恩强调这是其领导的条款,确保南达科他州国防投资。",
state: "2024年12月参议院通过,待总统签署。",
time: "2024年6月",
img: img
},
{
id: 2,
title: "Bipartisan Appropriations Bills",
tie: ["法案", "政府预算"],
disc: "推动农业、商务、司法和军事等四项两党拨款法案,恢复“常规程序”以允许修正案辩论,避免年底“全包”法案或继续决议(CR)。图恩公开敦促民主党合作。",
state: "委员会报告,部分进入辩论阶段。",
time: "2025年7月",
img: img
},
{
id: 3,
title: "Tax Relief, Unemployment Insurance Reauthorization, and Job Creation Act",
tie: ["法案", "税收与经济"],
disc: "续推失业保险和就业创造措施,图恩在2024报告中排名共和党第8位影响力,推动小企业税收减免。",
state: "纳入2024报告卡,影响2025税收辩论",
time: "2024年续推",
img: img
},
{
id: 4,
title: "Farm Bill Renewal Provisions",
tie: ["修正案", "农业与农村"],
disc: "加强农村基础设施和作物保险,支持南达科他州农民。图恩强调两党合作,避免拖延。",
state: "纳入2024 Farm Bill讨论,部分通过",
time: "2024年",
img: img
},
{
id: 5,
title: "Regular Order Restoration",
tie: ["修正案", "能源"],
disc: "承诺恢复委员会起草、修正案辩论和投票规范,避免领导层封闭谈判。图恩表示将允许100多项修正案投票。",
state: "实施中,2025年夏季拨款辩论",
time: "2025年1月",
img: img
},
{
id: 6,
title: "S.Amdt.3946 和 S.Amdt.3947",
tie: ["法案", "政府预算"],
disc: "改进政府资金法案,允许参议员就电话记录扣押提起诉讼,保护国会隐私(源于2020选举调查争议)。图恩提议将法院赔偿退回财政部以调整条款。",
state: "2025年11月10日失败",
time: "2025年11月10日",
img: img
}
]);
</script>
<style scoped lang="scss">
* {
margin: 0;
padding: 0;
}
.historical-proposal {
width: 1600px;
height: 644px;
.nav {
width: 100%;
height: 32px;
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 16px;
.search-input {
width: 300px;
height: 32px;
color: rgb(132, 136, 142);
font-size: 14px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 22px;
}
.select-box {
width: 332px;
height: 32px;
display: flex;
justify-content: space-between;
align-items: center;
.select {
width: 160px;
height: 32px;
color: rgb(132, 136, 142);
font-size: 14px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 22px;
}
}
}
.main {
width: 1600px;
height: 540px;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
align-content: space-between;
.item {
width: 523px;
height: 262px;
background-color: #fff;
border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
padding: 16px 19px 17px 16px;
.img-box {
width: 488px;
height: 77px;
display: flex;
margin-bottom: 12px;
img {
width: 57px;
height: 77px;
margin-right: 15px;
}
.info {
width: 420px;
height: 77px;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: flex-start;
.title {
font-size: 16px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(5, 95, 194);
}
.tag {
display: inline-block;
padding: 1px 8px;
font-size: 14px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 20px;
border-radius: 4px;
border: 1px solid;
margin-right: 8px;
}
.tag-1 {
background-color: rgba(246, 255, 237, 1);
color: rgba(82, 196, 26, 1);
border-color: rgba(217, 247, 190, 1);
}
.tag-2 {
background-color: rgba(255, 251, 230, 1);
color: rgba(250, 173, 20, 1);
border-color: rgba(255, 241, 184, 1);
}
}
}
.info-box {
width: 488px;
height: 140px;
.box {
width: 100%;
margin-bottom: 10px;
display: flex;
.label {
width: 84px;
font-size: 16px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(59, 65, 75);
}
.content {
width:400px;
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(59, 65, 75);
}
}
}
}
}
.pagination-container {
width: 100%;
display: flex;
justify-content: center;
margin-top: 20px;
:deep(.el-pagination.is-background .el-pager li) {
background-color: #fff;
border: 1px solid rgba(229, 230, 235, 1);
border-radius: 4px;
color: rgba(29, 33, 41, 1);
font-weight: 400;
margin: 0 4px;
}
:deep(.el-pagination.is-background .el-pager li.is-active) {
background-color: #fff;
border-color: #165DFF;
color: #165DFF;
}
:deep(.el-pagination.is-background .btn-prev),
:deep(.el-pagination.is-background .btn-next) {
background-color: #fff;
border: 1px solid rgba(229, 230, 235, 1);
border-radius: 4px;
margin: 0 4px;
}
}
}
</style>
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论