提交 50fc6e7d authored 作者: coderBryanFu's avatar coderBryanFu

样式更新

上级 11282794
......@@ -22,7 +22,7 @@ const thinktankRoutes = [
}
},
{
path: "/report/:id",
path: "/thinkTank/report/:id",
name: "ReportDetail",
component: ReportDetail,
meta: {
......
......@@ -514,22 +514,21 @@ onMounted(() => {
display: flex;
position: relative;
.header-left {
margin-top: 20px;
margin-top: 18px;
width: 8px;
height: 16px;
height: 20px;
border-radius: 0 4px 4px 0;
background: var(--color-main-active);
}
.title {
margin-left: 22px;
margin-top: 20px;
height: 16px;
line-height: 16px;
margin-left: 14px;
margin-top: 14px;
height: 26px;
line-height: 26px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 600;
line-height: 16px;
font-size: 20px;
font-weight: 700;
}
.header-btn-box {
position: absolute;
......
......@@ -56,7 +56,7 @@
<div class="search-text">搜索</div>
</div>
</div>
<div class="home-main-header-footer">
<!-- <div class="home-main-header-footer">
<div class="home-main-header-footer-item">
<div class="item-top">3.8T</div>
<div class="item-footer">数据量</div>
......@@ -77,7 +77,7 @@
<div class="item-top">285</div>
<div class="item-footer">分析报告</div>
</div>
</div>
</div> -->
<div class="home-main-header-btn-box">
<div class="btn" @click="handleToPosi('position1')">
<div class="btn-text">{{ "最新动态" }}</div>
......@@ -1601,6 +1601,7 @@ onUnmounted(() => {});
.box1 {
width: 1064px;
height: 450px;
border-radius: 10px;
box-shadow: 0px 0px 15px 0px rgba(22, 119, 255, 0.1);
background: #fff;
box-sizing: border-box;
......@@ -1914,6 +1915,7 @@ onUnmounted(() => {});
.box2 {
width: 520px;
height: 450px;
border-radius: 10px;
box-shadow: 0px 0px 15px 0px rgba(22, 119, 255, 0.1);
background: rgba(255, 255, 255, 1);
position: relative;
......@@ -2079,6 +2081,7 @@ onUnmounted(() => {});
.box3 {
width: 792px;
height: 450px;
border-radius: 10px;
box-shadow: 0px 0px 15px 0px rgba(25, 69, 130, 0.2);
background: rgba(255, 255, 255, 1);
.box3-header {
......@@ -2101,14 +2104,14 @@ onUnmounted(() => {});
}
}
.box3-header-title {
margin-top: 16px;
margin-top: 11px;
margin-left: 19px;
height: 22px;
height: 26px;
color: rgba(20, 89, 187, 1);
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 700;
line-height: 22px;
line-height: 26px;
}
.more {
width: 49px;
......@@ -2197,6 +2200,7 @@ onUnmounted(() => {});
margin-left: 20px;
width: 792px;
height: 450px;
border-radius: 10px;
box-shadow: 0px 0px 15px 0px rgba(25, 69, 130, 0.2);
background: rgba(255, 255, 255, 1);
.box4-header {
......@@ -2217,14 +2221,14 @@ onUnmounted(() => {});
}
}
.header-title {
margin-top: 16px;
margin-top: 11px;
margin-left: 18px;
height: 22px;
height: 26px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 700;
line-height: 22px;
line-height: 26px;
}
.more {
width: 49px;
......@@ -2308,6 +2312,7 @@ onUnmounted(() => {});
.box5 {
width: 1059px;
height: 450px;
border-radius: 10px;
box-shadow: 0px 0px 15px 0px rgba(22, 119, 255, 0.1);
background: rgba(255, 255, 255, 1);
.box5-header {
......@@ -2316,7 +2321,7 @@ onUnmounted(() => {});
margin: 0 auto;
display: flex;
justify-content: space-between;
padding: 0 20px;
padding: 0 27px 0 22px;
.box5-header-left {
display: flex;
.box5-header-icon {
......@@ -2329,14 +2334,14 @@ onUnmounted(() => {});
}
}
.box5-header-title {
margin-top: 16px;
margin-top: 11px;
margin-left: 19px;
height: 22px;
height: 26px;
color: rgba(20, 89, 187, 1);
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 700;
line-height: 22px;
line-height: 26px;
}
}
.box5-header-right {
......@@ -2371,6 +2376,7 @@ onUnmounted(() => {});
margin-left: 20px;
width: 521px;
height: 450px;
border-radius: 10px;
box-shadow: 0px 0px 15px 0px rgba(22, 119, 255, 0.1);
background: rgba(255, 255, 255, 1);
.box6-header {
......@@ -2390,14 +2396,14 @@ onUnmounted(() => {});
}
}
.header-title {
margin-top: 16px;
margin-top: 11px;
margin-left: 18px;
height: 22px;
height: 26px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 700;
line-height: 22px;
line-height: 26px;
}
.box6-header-right {
margin-left: 130px;
......@@ -2448,7 +2454,7 @@ onUnmounted(() => {});
margin: 0 auto;
display: flex;
justify-content: space-between;
padding: 0 20px;
padding: 0 27px 0 22px;
.box7-header-left {
display: flex;
.box7-header-icon {
......@@ -2461,14 +2467,14 @@ onUnmounted(() => {});
}
}
.box7-header-title {
margin-top: 16px;
margin-top: 11px;
margin-left: 19px;
height: 22px;
height: 26px;
color: rgba(20, 89, 187, 1);
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 700;
line-height: 22px;
line-height: 26px;
}
}
.box7-header-right {
......@@ -2520,7 +2526,7 @@ onUnmounted(() => {});
margin: 0 auto;
display: flex;
justify-content: space-between;
padding: 0 20px;
padding: 0 27px 0 22px;
.box8-header-left {
display: flex;
.box8-header-icon {
......@@ -2533,14 +2539,14 @@ onUnmounted(() => {});
}
}
.box8-header-title {
margin-top: 16px;
margin-top: 11px;
margin-left: 19px;
height: 22px;
height: 26px;
color: rgba(20, 89, 187, 1);
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 700;
line-height: 22px;
line-height: 26px;
}
}
.box8-header-right {
......@@ -2673,7 +2679,7 @@ onUnmounted(() => {});
margin: 0 auto;
display: flex;
justify-content: space-between;
padding: 0 20px;
padding: 0 27px 0 22px;
.box9-header-left {
display: flex;
.box9-header-icon {
......@@ -2686,14 +2692,14 @@ onUnmounted(() => {});
}
}
.box9-header-title {
margin-top: 16px;
margin-top: 11px;
margin-left: 19px;
height: 22px;
height: 26px;
color: rgba(20, 89, 187, 1);
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 700;
line-height: 22px;
line-height: 26px;
}
}
.box9-header-right {
......
......@@ -589,22 +589,21 @@ onMounted(async () => {
display: flex;
position: relative;
.header-left {
margin-top: 20px;
margin-top: 18px;
width: 8px;
height: 16px;
height: 20px;
border-radius: 0 4px 4px 0;
background: var(--color-main-active);
}
.title {
margin-left: 22px;
margin-top: 20px;
height: 16px;
line-height: 16px;
margin-left: 14px;
margin-top: 14px;
height: 26px;
line-height: 26px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 600;
line-height: 16px;
font-size: 20px;
font-weight: 700;
}
.header-switch-box {
position: absolute;
......
......@@ -742,22 +742,21 @@ const handleClickDetail = (isShow) => {
display: flex;
position: relative;
.header-left {
margin-top: 20px;
margin-top: 18px;
width: 8px;
height: 16px;
height: 20px;
border-radius: 0 4px 4px 0;
background: var(--color-main-active);
}
.title {
margin-left: 14px;
margin-top: 20px;
height: 16px;
line-height: 16px;
margin-top: 14px;
height: 26px;
line-height: 26px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 600;
line-height: 16px;
font-size: 20px;
font-weight: 700;
}
.header-right {
position: absolute;
......
......@@ -279,26 +279,27 @@ onMounted(() => {});
.sider-btn {
margin-top: 20px;
margin-left: 23px;
width: 112px;
width: 120px;
height: 32px;
display: flex;
line-height: 32px;
border-radius: 16px;
cursor: pointer;
.btn-text {
width: 82px;
width: 90px;
height: 32px;
line-height: 32px;
text-align: left;
box-sizing: border-box;
padding-left: 24px;
font-size: 14px;
font-size: 16px;
font-weight: 400;
font-family: Microsoft YaHei;
color: rgba(95, 101, 108, 1);
}
.btn-icon {
width: 22px;
padding-top: 2px;
padding-top: 4px;
}
}
.siderBtnActive {
......
......@@ -722,22 +722,21 @@ onMounted(async () => {
display: flex;
position: relative;
.header-left {
margin-top: 20px;
margin-top: 18px;
width: 8px;
height: 16px;
height: 20px;
border-radius: 0 4px 4px 0;
background: var(--color-main-active);
}
.title {
margin-left: 22px;
margin-top: 20px;
height: 16px;
line-height: 16px;
margin-left: 14px;
margin-top: 14px;
height: 26px;
line-height: 26px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 600;
line-height: 16px;
font-size: 20px;
font-weight: 700;
}
.header-right {
position: absolute;
......
......@@ -634,22 +634,21 @@ onMounted(() => {
display: flex;
position: relative;
.header-left {
margin-top: 20px;
margin-top: 18px;
width: 8px;
height: 16px;
height: 20px;
border-radius: 0 4px 4px 0;
background: var(--color-main-active);
}
.title {
margin-left: 14px;
margin-top: 20px;
height: 16px;
line-height: 16px;
margin-top: 14px;
height: 26px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 18px;
font-size: 20px;
font-weight: 700;
line-height: 16px;
line-height: 26px;
}
.header-btn-box {
position: absolute;
......
......@@ -603,21 +603,21 @@ onMounted(() => {
display: flex;
position: relative;
.icon {
margin-top: 20px;
margin-top: 18px;
width: 8px;
height: 16px;
height: 20px;
border-radius: 0 4px 4px 0;
background: rgba(10, 87, 166, 1);
}
.title {
margin-left: 16px;
margin-top: 16px;
height: 24px;
margin-left: 14px;
margin-top: 14px;
height: 26px;
color: rgba(10, 87, 166, 1);
font-family: Microsoft YaHei;
font-size: 18px;
font-size: 20px;
font-weight: 700;
line-height: 24px;
line-height: 26px;
}
.header-right {
display: flex;
......
......@@ -446,21 +446,21 @@ onMounted(async () => {
position: relative;
height: 50px;
.box-header-left {
margin-top: 20px;
margin-top: 18px;
width: 8px;
height: 16px;
height: 20px;
border-radius: 0 4px 4px 0;
background: var(--color-main-active);
}
.box-header-title {
margin-left: 22px;
margin-top: 20px;
height: 16px;
margin-left: 14px;
margin-top: 14px;
height: 26px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 600;
line-height: 16px;
font-size: 20px;
font-weight: 700;
line-height: 26px;
letter-spacing: 0px;
text-align: left;
}
......
......@@ -21,7 +21,7 @@
搜索
</div>
</div>
<div class="search-center">
<!-- <div class="search-center">
<div class="search-item">
<div class="search-item-num">32</div>
<div class="search-item-name">相关法案</div>
......@@ -34,7 +34,7 @@
<div class="search-item-num">41</div>
<div class="search-item-name">相关政府公告</div>
</div>
</div>
</div> -->
<div class="search-bottom">
<div class="btn" @click="scrollToTop('position1')">
<div class="btn-text">最新动态</div>
......@@ -160,7 +160,7 @@ const handleBackHome = () => {
padding: 44px 160px 30px 160px;
.search {
width: 960px;
height: 225px;
height: 168px;
margin: 0 auto 68px auto;
.search-main {
......@@ -251,6 +251,7 @@ const handleBackHome = () => {
width: 688px;
height: 48px;
margin: 0 auto;
margin-top: 36px;
display: flex;
justify-content: space-between;
// gap: 16px;
......
......@@ -55,7 +55,7 @@
<div class="search-text">搜索</div>
</div>
</div>
<div class="home-main-header-footer" v-show="!isShow">
<!-- <div class="home-main-header-footer" v-show="!isShow">
<div class="home-main-header-footer-item">
<div class="item-top">3.8T</div>
<div class="item-footer">数据量</div>
......@@ -76,7 +76,7 @@
<div class="item-top">285</div>
<div class="item-footer">分析报告</div>
</div>
</div>
</div> -->
<div class="home-main-header-btn-box" v-show="!isShow">
<div class="btn" @click="handleToPosi('position1')">
<div class="btn-text">{{ "最新动态" }}</div>
......
......@@ -280,22 +280,21 @@ const box2LeftActiveIndex = ref(0);
display: flex;
position: relative;
.header-left {
margin-top: 20px;
margin-top: 18px;
width: 8px;
height: 16px;
height: 20px;
border-radius: 0 4px 4px 0;
background: rgba(10, 87, 166, 1);
}
.title {
margin-left: 22px;
margin-top: 20px;
height: 16px;
line-height: 16px;
margin-left: 14px;
margin-top: 14px;
height: 26px;
line-height: 26px;
color: rgba(10, 87, 166, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 600;
line-height: 16px;
font-size: 20px;
font-weight: 700;
}
.header-btn-box {
position: absolute;
......
......@@ -316,21 +316,21 @@ onMounted(() => {
height: 48px;
position: relative;
.icon {
margin-top: 20px;
margin-top: 18px;
width: 8px;
height: 16px;
height: 20px;
border-radius: 0 4px 4px 0;
background: rgba(10, 87, 166, 1);
background: var(--color-main-active);
}
.title {
height: 24px;
height: 26px;
margin-left: 14px;
margin-top: 16px;
color: rgba(10, 87, 166, 1);
margin-top: 14px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 18px;
font-size: 20px;
font-weight: 700;
line-height: 24px;
line-height: 26px;
}
.header-right {
position: absolute;
......
......@@ -205,22 +205,21 @@ const laws = ref([
display: flex;
position: relative;
.header-left {
margin-top: 20px;
margin-top: 18px;
width: 8px;
height: 16px;
height: 20px;
border-radius: 0 4px 4px 0;
background: rgba(10, 87, 166, 1);
}
.title {
margin-left: 22px;
margin-top: 20px;
height: 16px;
line-height: 16px;
margin-left: 14px;
margin-top: 14px;
height: 26px;
line-height: 26px;
color: rgba(10, 87, 166, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 600;
line-height: 16px;
font-size: 20px;
font-weight: 700;
}
.header-btn-box {
position: absolute;
......
......@@ -248,22 +248,21 @@ const eventList = ref([
display: flex;
position: relative;
.header-left {
margin-top: 20px;
margin-top: 18px;
width: 8px;
height: 16px;
height: 20px;
border-radius: 0 4px 4px 0;
background: rgba(10, 87, 166, 1);
}
.title {
margin-left: 22px;
margin-top: 20px;
height: 16px;
line-height: 16px;
margin-left: 14px;
margin-top: 14px;
height: 26px;
line-height: 26px;
color: rgba(10, 87, 166, 1);
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 700;
line-height: 16px;
}
.header-btn-box {
position: absolute;
......
......@@ -25,7 +25,7 @@
<div class="search-text">搜索</div>
</div>
</div>
<div class="home-main-header-footer">
<!-- <div class="home-main-header-footer">
<div class="home-main-header-footer-item">
<div class="item-top">1096</div>
<div class="item-footer">实体清单</div>
......@@ -38,14 +38,8 @@
<div class="item-top">162</div>
<div class="item-footer">关键和新型技术清单</div>
</div>
</div>
<!-- <div class="home-main-header-footer-link">
<ClickableCard text="最新动态" @click="scrollToTop('position1')" target="_blank" />
<ClickableCard text="资讯要闻" @click="scrollToTop('position2')" target="_blank" />
<ClickableCard text="数据总览" @click="scrollToTop('position3')" target="_blank" />
<ClickableCard text="资源库" @click="scrollToTop('position4')" target="_blank" />
</div> -->
<div class="home-main-header-btn-box">
<div class="home-main-header-btn-box">
<div class="btn" @click="scrollToTop('position1')">
<div class="btn-text">{{ "最新动态" }}</div>
<div class="btn-icon">
......@@ -468,15 +462,15 @@
header-row-class-name="table-header"
row-class-name="table-row"
>
<el-table-column prop="index" label="序号" width="80" align="center">
<!-- <el-table-column prop="index" label="序号" width="80" align="center">
<template #default="scope">
{{ scope.$index + 1 + (currentPage - 1) * pageSize }}
</template>
</el-table-column>
</el-table-column> -->
<el-table-column prop="name" label="实体名称" min-width="200">
<template #default="scope">
<div style="font-weight: 500">{{ scope.row.name }}</div>
<div class="tableName">{{ scope.row.name }}</div>
</template>
</el-table-column>
......@@ -1824,7 +1818,7 @@ onMounted(async () => {
gap: 16px;
padding: 30px 0;
}
.home-main-header-btn-box {
.home-main-header-btn-box {
width: 688px;
margin: 0 auto;
margin-top: 39px;
......@@ -1853,6 +1847,7 @@ onMounted(async () => {
font-weight: 400;
line-height: 48px;
margin-left: 36px;
text-align: center;
}
.btn-icon {
position: absolute;
......@@ -1860,7 +1855,7 @@ onMounted(async () => {
right: 19px;
width: 6px;
height: 12px;
img{
img {
width: 100%;
height: 100%;
}
......@@ -2388,6 +2383,15 @@ onMounted(async () => {
}
}
}
.tableName {
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 700;
line-height: 30px;
letter-spacing: 0px;
text-align: justify;
}
:deep(.el-input__wrapper) {
box-shadow: none;
......
......@@ -25,7 +25,7 @@
<div class="search-text">搜索</div>
</div>
</div>
<div class="home-main-header-footer">
<!-- <div class="home-main-header-footer">
<div class="home-main-header-footer-item">
<div class="item-top">142</div>
<div class="item-footer">实体清单</div>
......@@ -38,7 +38,7 @@
<div class="item-top">326</div>
<div class="item-footer">关键和新型技术清单</div>
</div>
</div>
</div> -->
<div class="home-main-header-btn-box">
<div class="btn" @click="scrollToTop('position1')">
<div class="btn-text">{{ "最新动态" }}</div>
......
......@@ -55,7 +55,7 @@
<div class="search-text">搜索</div>
</div>
</div>
<div class="home-main-header-footer" v-show="!isShow">
<!-- <div class="home-main-header-footer" v-show="!isShow">
<div class="home-main-header-footer-item">
<div class="item-top">142</div>
<div class="item-footer">创新主体数量</div>
......@@ -76,7 +76,7 @@
<div class="item-top">84</div>
<div class="item-footer">重要技术进展数量</div>
</div>
</div>
</div> -->
<div class="home-main-header-btn-box" v-show="!isShow">
<div class="btn" @click="scrollToTop('position1')">
<div class="btn-text">{{ "最新动态" }}</div>
......
......@@ -20,7 +20,7 @@
<div class="search-text">搜索</div>
</div>
</div>
<div class="home-main-header-footer">
<!-- <div class="home-main-header-footer">
<div class="home-main-header-footer-item">
<div class="item-top">142</div>
<div class="item-footer">总调查案件数</div>
......@@ -41,7 +41,7 @@
<div class="item-top">285</div>
<div class="item-footer">分析报告</div>
</div>
</div>
</div> -->
<div class="home-main-header-btn-box">
<div class="btn" @click="scrollToTop('position1')">
<div class="btn-text">{{ "最新动态" }}</div>
......
......@@ -271,22 +271,22 @@ onMounted(() => {
display: flex;
position: relative;
.header-left {
margin-top: 20px;
margin-top: 18px;
width: 8px;
height: 16px;
height: 20px;
border-radius: 0 4px 4px 0;
background: rgba(10, 87, 166, 1);
}
.title {
margin-left: 22px;
margin-top: 20px;
height: 16px;
line-height: 16px;
margin-left: 14px;
margin-top: 14px;
height: 26px;
line-height: 26px;
color: rgba(10, 87, 166, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 600;
line-height: 16px;
font-size: 20px;
font-weight: 700;
}
.header-btn-box {
position: absolute;
......
......@@ -542,15 +542,14 @@ onMounted(() => {
.header-left {
margin-top: 18px;
width: 8px;
height: 16px;
height: 20px;
border-radius: 0 4px 4px 0;
background: rgba(10, 87, 166, 1);
}
.title {
margin-left: 22px;
margin-left: 14px;
margin-top: 14px;
height: 26px;
line-height: 16px;
color: rgba(10, 87, 166, 1);
font-family: Microsoft YaHei;
font-size: 20px;
......
......@@ -313,22 +313,21 @@ onMounted(() => {
display: flex;
position: relative;
.header-left {
margin-top: 20px;
margin-top: 18px;
width: 8px;
height: 16px;
height: 20px;
border-radius: 0 4px 4px 0;
background: rgba(10, 87, 166, 1);
}
.title {
margin-left: 22px;
margin-top: 20px;
height: 16px;
line-height: 16px;
margin-left: 14px;
margin-top: 14px;
height: 26px;
line-height: 26px;
color: rgba(10, 87, 166, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 600;
line-height: 16px;
font-size: 20px;
font-weight: 700;
}
.header-btn-box {
position: absolute;
......
......@@ -21,7 +21,7 @@
搜索
</div>
</div>
<div class="search-center">
<!-- <div class="search-center">
<div class="search-item">
<div class="search-item-num">190</div>
<div class="search-item-name">规则限制政令</div>
......@@ -38,7 +38,7 @@
<div class="search-item-num">12</div>
<div class="search-item-name">排华国家数量</div>
</div>
</div>
</div> -->
<div class="search-bottom">
<div class="btn" @click="scrollToTop('position1')">
<div class="btn-text">最新动态</div>
......@@ -165,7 +165,7 @@ const handleBackHome = () => {
padding: 44px 160px 30px 160px;
.search {
width: 960px;
height: 225px;
height: 168px;
margin: 0 auto 68px auto;
.search-main {
display: flex;
......@@ -255,6 +255,7 @@ const handleBackHome = () => {
width: 688px;
height: 48px;
margin: 0 auto;
margin-top: 36px;
display: flex;
justify-content: space-between;
// gap: 16px;
......
......@@ -21,7 +21,7 @@
搜索
</div>
</div>
<div class="search-center">
<!-- <div class="search-center">
<div class="search-item">
<div class="search-item-num">18</div>
<div class="search-item-name">科研资助机构</div>
......@@ -38,7 +38,7 @@
<div class="search-item-num">15,556</div>
<div class="search-item-name">经费总额(亿美元)</div>
</div>
</div>
</div> -->
<div class="search-bottom">
<div class="btn" @click="scrollToTop('position1')">
<div class="btn-text">最新动态</div>
......@@ -239,7 +239,7 @@ const dataList = ref([
padding: 44px 160px 30px 160px;
.search {
width: 960px;
height: 225px;
height: 168px;
margin: 0 auto 52px auto;
.search-main {
display: flex;
......@@ -329,6 +329,7 @@ const dataList = ref([
width: 688px;
height: 48px;
margin: 0 auto;
margin-top: 36px;
display: flex;
justify-content: space-between;
// gap: 16px;
......
<template>
<div class="effect-analysis">
<div class="placeholder-card">
<div class="card-header">
<CardTitle title="影响分析" />
<el-icon class="expand-icon"><TrendCharts /></el-icon>
</div>
<div class="card-body">
<div class="placeholder-content">
<h3 class="placeholder-title">影响分析功能开发中</h3>
<el-empty description="暂无数据" />
</div>
</div>
</div>
</div>
</template>
<script setup>
import { TrendCharts } from '@element-plus/icons-vue'
import CardTitle from '@/components/CardTitle.vue'
</script>
<style scoped>
.effect-analysis {
/* padding: 20px 0; */
}
.placeholder-card {
background: #fff;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
min-height: 500px;
}
.card-header {
padding: 16px 20px;
border-bottom: 1px solid #f0f0f0;
display: flex;
justify-content: space-between;
align-items: center;
}
.card-body {
padding: 40px 20px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
}
.expand-icon {
color: #999;
}
.placeholder-content {
display: flex;
flex-direction: column;
align-items: center;
max-width: 400px;
}
.placeholder-icon {
margin-bottom: 24px;
color: #d3d3d3;
}
.placeholder-title {
font-size: 20px;
color: #333;
margin: 0 0 16px 0;
}
.placeholder-description {
font-size: 14px;
color: #666;
margin-bottom: 20px;
line-height: 1.6;
}
.feature-list {
list-style: none;
padding: 0;
margin: 0 0 30px 0;
text-align: left;
}
.feature-list li {
padding: 8px 0;
color: #666;
font-size: 14px;
position: relative;
padding-left: 20px;
}
.feature-list li::before {
content: "•";
color: #409eff;
font-weight: bold;
position: absolute;
left: 0;
}
</style>
<template>
<div class="overview-container">
<el-row :gutter="20">
<!-- 左侧内容 -->
<el-col :span="8">
<!-- 内容摘要 -->
<div class="content-card">
<div class="card-header">
<CardTitle title="内容摘要" />
<el-icon class="expand-icon"><ArrowRight /></el-icon>
</div>
<div class="card-body">
<div class="summary-content">
<div v-html="props.reportSummary.summary"></div>
<el-button type="text" class="more-btn">查看更多 ></el-button>
</div>
</div>
</div>
<!-- 涉及科技领域 -->
<div class="content-card tech-fields" style="margin-top: 20px;">
<div class="card-header">
<CardTitle title="涉及科技领域" />
<el-icon class="expand-icon"><ArrowRight /></el-icon>
</div>
<div class="card-body">
<div class="tech-tags">
<el-tag type="primary" size="small" v-for="tag in props.reportSummary.researchTypes" :key="tag">{{ tag }}</el-tag>
</div>
<WordCloud :words="props.reportSummary.researchTypes" />
</div>
</div>
</el-col>
<!-- 右侧主要内容 -->
<el-col :span="16">
<div class="content-card main-content-card">
<div class="card-header">
<CardTitle title="主要内容" />
<div class="content-actions">
<el-button type="plain" size="small">核心发现</el-button>
<el-button type="plain" size="small">政策建议</el-button>
<el-icon class="expand-icon"><Paperclip /></el-icon>
</div>
</div>
<div class="card-body">
<div class="main-content-list">
<div v-for="(item, index) in mainContentList" :key="item.id" class="content-item">
<!-- 左侧:序号 -->
<div class="item-number">{{ item.serialNum }}</div>
<!-- 中间:标题和内容 -->
<div class="item-main">
<h4 class="item-title">{{ item.content }}</h4>
<p class="item-content">{{ item.econtent }}</p>
</div>
<!-- 右侧:标签 -->
<div class="item-tags">
<el-tag
v-for="tag in item.tags"
:key="tag.name"
:type="tag.type"
size="small"
class="content-tag"
>
{{ tag.name }}
</el-tag>
</div>
</div>
</div>
<!-- 分页 -->
<div class="pagination-wrapper">
<el-pagination
v-model:current-page="currentPage"
:page-size="pageSize"
:total="totalElements"
layout="prev, pager, next"
:pager-count="5"
small
/>
<span class="total-info">{{ totalElements }}项结果</span>
</div>
</div>
</div>
</el-col>
</el-row>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { Paperclip } from '@element-plus/icons-vue'
import CardTitle from '@/components/CardTitle.vue'
import { mockMainContentList } from '../mockData'
import WordCloud from './WordCloud.vue'
const props = defineProps({
reportSummary: {
type: Object,
required: true
},
content: {
type: Object,
required: true
}
})
const currentPage = ref(1)
const totalElements = ref(6)
const pageSize = ref(10)
// 标签类型映射 - 根据限制方式设置不同的标签颜色
const getTagType = (tagName) => {
const tagTypeMap = {
'出口管制': 'danger',
'资本管制': 'warning',
'技术封锁': 'danger',
'金融制裁': 'danger',
'对台军售': 'warning',
'关税贸易': 'primary',
'供应链打击': 'warning'
}
return tagTypeMap[tagName] || 'info'
}
// 处理接口数据的方法
const processApiData = (apiResponse) => {
if (!apiResponse || !apiResponse.content) return []
return apiResponse.content.map(item => ({
id: item.id,
title: item.content, // 使用content作为标题
content: item.content, // 内容
econtent: item.econtent,
serialNum: item.serialNum,
tags: item.xzfsList.map(tag => ({
name: tag,
type: getTagType(tag)
}))
}))
}
// 更新分页信息的方法
const updatePagination = (apiResponse) => {
if (apiResponse) {
totalElements.value = apiResponse.totalElements || 0
pageSize.value = apiResponse.size || 10
currentPage.value = (apiResponse.number || 0) + 1 // API返回的是0基础的页码
}
}
const mainContentList = ref(mockMainContentList)
</script>
<style scoped>
.overview-container {
padding: 0;
}
.content-card {
background: #fff;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
}
.card-header {
padding: 16px 20px;
border-bottom: 1px solid #f0f0f0;
display: flex;
justify-content: space-between;
align-items: center;
}
.card-body {
padding: 20px;
}
.expand-icon {
color: #999;
cursor: pointer;
margin-left: 10px;
}
.summary-content {
line-height: 1.8;
color: #666;
}
.summary-content p {
margin-bottom: 16px;
text-align: justify;
}
.more-btn {
color: #409eff;
padding: 0;
}
.tech-tags {
display: flex;
gap: 12px;
flex-wrap: wrap;
margin-bottom: 10px;
}
.tag-row {
display: flex;
gap: 8px;
flex-wrap: wrap;
}
.tech-tag {
background: #f5f7fa;
border: 1px solid #dcdfe6;
color: #606266;
border-radius: 4px;
padding: 4px 8px;
font-size: 12px;
}
.tech-tag.ai-chip {
background: #fff7e6;
border-color: #ffd591;
color: #fa8c16;
}
.content-actions {
display: flex;
align-items: center;
}
.main-content-list {
margin-bottom: 20px;
}
.content-item {
display: flex;
align-items: flex-start;
margin-bottom: 10px;
padding-bottom: 10px;
border-bottom: 1px solid #f0f0f0;
gap: 16px;
}
.content-item:last-child {
border-bottom: none;
margin-bottom: 0;
padding-bottom: 0;
}
.item-number {
width: 28px;
height: 28px;
background: #409eff;
color: white;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 13px;
font-weight: 600;
flex-shrink: 0;
margin-top: 2px;
}
.item-main {
flex: 1;
min-width: 0;
}
.item-title {
margin: 0 0 8px 0;
font-size: 16px;
font-weight: 600;
color: #1f2937;
line-height: 1.4;
}
.item-content {
margin: 0;
line-height: 1.6;
color: #4b5563;
font-size: 14px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.item-tags {
display: flex;
flex-direction: column;
gap: 6px;
flex-shrink: 0;
min-width: 120px;
align-items: flex-end;
}
.content-tag {
font-size: 12px;
height: 22px;
line-height: 20px;
padding: 0 8px;
white-space: nowrap;
}
.pagination-wrapper {
display: flex;
justify-content: space-between;
align-items: center;
padding-top: 20px;
border-top: 1px solid #f0f0f0;
}
.total-info {
font-size: 12px;
color: #999;
}
.pagination-wrapper :deep(.el-pagination) {
--el-pagination-font-size: 12px;
}
.pagination-wrapper :deep(.el-pagination .el-pager li) {
min-width: 28px;
height: 28px;
line-height: 28px;
}
.pagination-wrapper :deep(.el-pagination .btn-prev),
.pagination-wrapper :deep(.el-pagination .btn-next) {
height: 28px;
line-height: 28px;
}
/* 响应式设计 */
@media (max-width: 768px) {
.content-item {
flex-direction: column;
gap: 12px;
margin-bottom: 20px;
padding-bottom: 20px;
}
.item-number {
align-self: flex-start;
}
.item-main {
order: 2;
}
.item-tags {
order: 3;
flex-direction: row;
align-items: flex-start;
flex-wrap: wrap;
min-width: auto;
}
.item-title {
font-size: 15px;
}
.item-content {
font-size: 13px;
}
}
</style>
<template>
<div class="word-cloud-container">
<svg :width="width" :height="height" ref="svgRef">
</svg>
<div v-if="!words || words.length === 0" class="no-data-message">
{{ emptyText }}
</div>
</div>
</template>
<script>
import { defineComponent, ref, watch, onMounted, nextTick } from 'vue';
import * as d3 from 'd3';
import cloud from 'd3-cloud';
// 默认颜色数组,您可以根据需要扩展
const defaultColors = [
'#f56c6c', // 红色
'#e6a23c', // 橙色
'#67c23a', // 绿色
'#409eff', // 蓝色
'#909399', // 灰色
'#b3a2c7', // 紫色
'#49a37e', // 军绿
];
export default defineComponent({
name: 'WordCloud',
props: {
// 词汇数组,例如:['通用人工智能', 'AI芯片', '出口管制']
words: {
type: Array,
required: true,
default: () => [],
},
// 词云容器的宽度
width: {
type: [Number, String],
default: 600,
},
// 词云容器的高度
height: {
type: [Number, String],
default: 400,
},
// 词汇的最小字号
minFontSize: {
type: Number,
default: 16,
},
// 词汇的最大字号
maxFontSize: {
type: Number,
default: 50,
},
// 词汇颜色数组
colors: {
type: Array,
default: () => defaultColors,
},
// 词汇为空时的提示文本
emptyText: {
type: String,
default: '暂无词云数据',
},
},
setup(props) {
const svgRef = ref(null);
/**
* @description 根据词汇数组,计算词频,并转换成d3-cloud所需的格式
* @param {Array<string>} rawWords 原始词汇数组
* @returns {Array<{text: string, size: number}>} 转换后的数据
*/
const prepareData = (rawWords) => {
if (!rawWords || rawWords.length === 0) return [];
// 1. 计算词频
const wordCounts = rawWords.reduce((acc, word) => {
acc[word] = (acc[word] || 0) + 1;
return acc;
}, {});
// 2. 转换为d3-cloud所需的格式,并找出最大/最小词频
let minCount = Infinity;
let maxCount = -Infinity;
const data = Object.entries(wordCounts).map(([text, count]) => {
if (count < minCount) minCount = count;
if (count > maxCount) maxCount = count;
return { text, count };
});
// 3. 将词频映射到字号范围
const sizeScale = d3
.scaleLinear()
.domain([minCount, maxCount])
.range([props.minFontSize, props.maxFontSize]);
return data.map((d) => ({
...d,
size: sizeScale(d.count), // size就是字号
}));
};
/**
* @description 绘制词云
* @param {Array<{text: string, size: number, x: number, y: number, rotate: number}>} words 布局后的词汇数据
*/
const drawCloud = (words) => {
const svg = d3.select(svgRef.value);
// 清空SVG内容
svg.selectAll('*').remove();
// 创建一个<g>元素并平移到中心
const g = svg
.append('g')
.attr(
'transform',
`translate(${props.width / 2}, ${props.height / 2})`
);
// 绑定数据并创建<text>元素
const wordElements = g.selectAll('text').data(words, (d) => d.text);
// 进入(Enter)阶段:添加新的<text>元素
wordElements
.enter()
.append('text')
.style('font-size', (d) => `${d.size}px`)
.style('fill', (_, i) => props.colors[i % props.colors.length]) // 循环使用颜色
.attr('text-anchor', 'middle') // 文本居中
// *********** 关键修改:移除悬浮样式和交互,保持水平布局 ***********
.attr('transform', (d) => `translate(${d.x}, ${d.y})`) // 移除rotate属性
.text((d) => d.text);
// ************************************************************
// 退出(Exit)阶段:移除多余的<text>元素(如果更新时词汇减少)
wordElements.exit().remove();
};
/**
* @description 启动d3-cloud布局引擎
* @param {Array<{text: string, count: number, size: number}>} data 待布局的词汇数据
*/
const generateLayout = (data) => {
if (!data || data.length === 0) {
d3.select(svgRef.value).selectAll('*').remove();
return;
}
const layout = cloud()
.size([props.width, props.height]) // 词云的尺寸
.words(data) // 传入词汇数据
.padding(5) // 词汇之间的最小间距
// *********** 关键修改:固定旋转角度为 0,实现水平布局 ***********
.rotate(0)
// ************************************************************
.font('Impact') // 字体
.fontSize((d) => d.size) // 使用计算出的字号
.on('end', drawCloud); // 布局计算完成后调用drawCloud
layout.start(); // 启动布局
};
/**
* @description 核心渲染函数,处理数据并启动布局
*/
const renderWordCloud = () => {
// 保证在DOM更新后执行
nextTick(() => {
const processedData = prepareData(props.words);
generateLayout(processedData);
});
};
onMounted(renderWordCloud);
// 监听props变化,重新渲染词云
watch(() => [props.words, props.width, props.height, props.minFontSize, props.maxFontSize], () => {
renderWordCloud();
}, { deep: true });
return {
svgRef,
renderWordCloud,
};
},
});
</script>
<style lang="scss">
.word-cloud-container {
display: flex;
justify-content: center;
align-items: center;
position: relative;
width: v-bind(width + 'px'); // 动态绑定宽度
height: v-bind(height + 'px'); // 动态绑定高度
border: 1px solid #ebeef5;
border-radius: 4px;
overflow: hidden;
// 词云SVG的样式
svg {
display: block; // 移除底部空白
}
// 词汇文本的通用样式
text {
font-weight: bold;
// *********** 关键修改:移除transition和cursor,避免交互 ***********
}
.no-data-message {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
font-size: 16px;
color: #909399;
background-color: #f5f7fa;
}
}
</style>
\ No newline at end of file
<template>
<div class="wrap">
<div class="left">
<div class="box1">
<div class="box-header">
<div class="header-left"></div>
<div class="title">内容摘要</div>
<div class="header-right">
<div class="icon">
<img src="@/assets/icons/box-header-icon2.png" alt="" />
</div>
<div class="icon">
<img src="@/assets/icons/box-header-icon3.png" alt="" />
</div>
</div>
</div>
<div class="box1-main">
{{
`包括经济竞争在内的美中竞争自2017年以来一直在定义美国外交政策。这两个经济体是世界上第一和第二大国家经济体,并且深深交织在一起。改变关系,无论多么必要,可能是昂贵的。因此,美国面临着一项挑战,确保其经济在耦合的战略竞争条件下满足国家的需求。
为了应对这一挑战,兰德大学的研究人员对美中竞争进行了经济和制度分析,进行了参与式的远见练习,以了解确保美国经济健康的长期路径,并创建了两个经济竞争游戏,探索多个国家在相互交流的同时确保经济健康的动态...`
}}
</div>
<div class="box1-footer">
<div class="text">{{ "查看更多" }}</div>
<div class="icon">
<img src="@/assets/images/icon-double-down.png" alt="" />
</div>
</div>
</div>
<div class="box2">
<div class="box-header">
<div class="header-left"></div>
<div class="title">涉及科技领域</div>
<div class="header-right">
<div class="icon">
<img src="@/assets/icons/box-header-icon2.png" alt="" />
</div>
<div class="icon">
<img src="@/assets/icons/box-header-icon3.png" alt="" />
</div>
</div>
</div>
<div class="box2-main">
<div class="box2-main-tag-box">
<div class="tag" v-for="(item, index) in areaList" :key="index">{{ item }}</div>
</div>
<div class="box2-content" id="box2Chart"></div>
</div>
</div>
</div>
<div class="right">
<div class="box3">
<div class="box-header">
<div class="header-left"></div>
<div class="title">主要观点</div>
<div class="header-btn-box">
<div class="btn btnActive">
{{ "核心发现" }}
</div>
<div class="btn">
{{ "政策建议" }}
</div>
</div>
<div class="header-right">
<div class="icon">
<img src="@/assets/icons/box-header-icon2.png" alt="" />
</div>
<div class="icon">
<img src="@/assets/icons/box-header-icon3.png" alt="" />
</div>
</div>
</div>
<div class="box3-footer">
<div class="footer-left">
<img src="@/assets/icons/box-footer-left-icon.png" alt="" />
</div>
<div class="footer-center">
{{
`中美经济深度交织,全面脱钩成本高昂且不现实。其核心揭示了三大纽带:生产网络相互依存使强行分离代价巨大;人才双向流动推动创新却成政策博弈焦点;能源领域合作与竞争并存,关乎全球气候治理与经济博弈。报告主张理性竞合,在竞争中找到合作路径。`
}}
</div>
<div class="footer-right">
<img src="@/assets/icons/box-footer-right-icon.png" alt="" />
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref, onMounted } from "vue";
const areaList = ref(["人工智能", "半导体与高科技", "经济与贸易", "地缘政治", "军事与安全", "国际规则与多边体系"]);
</script>
<style lang="scss" scoped>
.wrap {
display: flex;
justify-content: center;
gap: 16px;
.box-header {
width: 100%;
height: 50px;
display: flex;
position: relative;
.header-left {
margin-top: 18px;
width: 8px;
height: 20px;
border-radius: 0 4px 4px 0;
background: var(--color-main-active);
}
.title {
margin-left: 14px;
margin-top: 14px;
height: 26px;
line-height: 26px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 700;
}
.header-btn-box {
position: absolute;
top: 15px;
right: 83px;
display: flex;
justify-content: flex-end;
gap: 8px;
.btn {
height: 28px;
padding: 0 8px;
box-sizing: border-box;
border: 1px solid rgba(230, 231, 232, 1);
border-radius: 4px;
background: rgba(255, 255, 255, 1);
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 28px;
}
.btnActive {
color: var(--color-main-active);
border: 1px solid var(--color-main-active);
}
}
.header-right {
position: absolute;
top: 14px;
right: 12px;
display: flex;
justify-content: flex-end;
gap: 4px;
.icon {
width: 28px;
height: 28px;
img {
width: 100%;
height: 100%;
}
}
}
}
.left {
.box1 {
margin-top: 17px;
width: 480px;
height: 390px;
border: 1px solid rgba(234, 236, 238, 1);
border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background: rgba(255, 255, 255, 1);
.box1-main {
margin: 5px auto;
width: 428px;
height: 282px;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 30px;
letter-spacing: 0px;
text-align: justify;
}
.box1-footer {
margin: 0 auto;
width: 108px;
height: 32px;
display: flex;
align-items: center;
justify-content: center;
gap: 4px;
cursor: pointer;
&:hover {
background: var(--color-bg-hover);
}
.text {
height: 22px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 14px;
font-weight: 400;
line-height: 22px;
letter-spacing: 0px;
text-align: left;
}
.icon {
width: 16px;
height: 16px;
img {
width: 100%;
height: 100%;
}
}
}
}
.box2 {
margin-top: 16px;
width: 480px;
height: 390px;
border: 1px solid rgba(234, 236, 238, 1);
border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background: rgba(255, 255, 255, 1);
.box2-main {
width: 430px;
height: 320px;
margin: 0 auto;
.box2-main-tag-box {
display: flex;
flex-wrap: wrap;
height: 89px;
box-sizing: border-box;
padding: 8px 0;
gap: 8px;
.tag {
height: 28px;
padding: 0 8px;
box-sizing: border-box;
border: 1px solid rgba(230, 231, 232, 1);
border-radius: 4px;
background: rgba(255, 255, 255, 1);
}
}
.box2-content {
width: 430px;
height: 231px;
box-sizing: border-box;
border: 1px solid rgba(234, 236, 238, 1);
border-radius: 4px;
background: rgba(247, 248, 249, 1);
}
}
}
}
.right {
margin-top: 17px;
.box3 {
width: 1103px;
height: 936px;
border: 1px solid rgba(234, 236, 238, 1);
border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background: rgba(255, 255, 255, 1);
position: relative;
.box3-footer {
position: absolute;
left: 22px;
bottom: 19px;
width: 1057px;
height: 64px;
box-sizing: border-box;
border: 1px solid rgba(231, 243, 255, 1);
border-radius: 4px;
background: rgba(246, 250, 255, 1);
display: flex;
align-items: center;
justify-content: center;
gap: 13px;
.footer-left {
width: 19px;
height: 20px;
img {
width: 100%;
height: 100%;
}
}
.footer-center {
width: 964px;
height: 48px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 24px;
letter-spacing: 0px;
text-align: justify;
}
.footer-right {
width: 24px;
height: 24px;
img {
width: 100%;
height: 100%;
}
}
}
}
}
}
</style>
\ No newline at end of file
<template>
<div class="funding-source-container">
<div class="chart-header">
<CardTitle title="经费来源" />
<div class="header-icons">
<el-icon><Coin /></el-icon>
<el-icon><Download /></el-icon>
<el-icon><Star /></el-icon>
</div>
</div>
<div class="chart-body">
<div class="stats-panel">
<div class="stat-card total-card">
<div class="label">总计</div>
<div class="value">4.358亿美元</div>
</div>
<div class="stat-card govt-card">
<div class="label">政府部门</div>
<div class="value">3.271亿美元</div>
</div>
<div class="stat-card other-card">
<div class="label">其他机构</div>
<div class="value">1.087亿美元</div>
</div>
</div>
<div class="chart-panel" ref="chartRef"></div>
</div>
</div>
</template>
<script setup>
import { ref, onMounted, onUnmounted, nextTick } from 'vue';
import * as echarts from 'echarts';
import { Coin, Download, Star } from '@element-plus/icons-vue';
import CardTitle from '@/components/CardTitle.vue';
// 1. 模拟数据
// 注意:为了还原图表,这里的数据是凑出来的近似值,确保比例看起来像截图
const chartData = [
// 右侧数据 (通常从12点顺时针开始)
{ value: 7830, name: '美国国土安全部', percent: '21%' },
{ value: 7290, name: '美国办公室国防部长和...', percent: '21%' },
{ value: 6740, name: '美国卫生与公众服务部...', percent: '18%' },
{ value: 4840, name: '美国空军', percent: '18%' },
{ value: 3880, name: '美国陆军', percent: '16%' },
{ value: 3520, name: '捐款', percent: '16%' },
// 左侧数据
{ value: 3110, name: '基金', percent: '14%' },
{ value: 2905, name: '大学', percent: '12%' },
{ value: 2840, name: '私营部门', percent: '12%' },
{ value: 2400, name: '州和地方政府机构', percent: '12%' },
{ value: 2130, name: '其他非营利组织', percent: '11%' },
{ value: 2060, name: '非美国政府机构和国际...', percent: '8%' },
{ value: 1850, name: '其他联邦机构', percent: '8%' },
{ value: 1200, name: '其他', percent: '8%' },
];
// 颜色盘 (从截图吸取的近似色)
const colorPalette = [
'#8cbbf1', // 浅蓝
'#a5d67d', // 浅绿
'#f6c469', // 橙黄
'#fdf27e', // 黄色
'#94e6d6', // 青绿
'#6b85ef', // 深蓝紫
'#d3d7fd', // 极浅蓝
'#d9f3b2', // 极浅绿
'#eb7d7d', // 红
'#a28ee3', // 紫
'#f4a678', // 橙
'#6ba7f5', // 蓝
'#f5a8a8', // 浅红
];
const chartRef = ref(null);
let myChart = null;
const initChart = () => {
if (!chartRef.value) return;
myChart = echarts.init(chartRef.value);
const option = {
color: colorPalette,
tooltip: {
trigger: 'item',
formatter: '{b}: {c}万 ({d}%)'
},
series: [
{
name: '经费来源',
type: 'pie',
radius: ['45%', '60%'], // 环形图半径
center: ['50%', '50%'], // 居中
data: chartData,
// 标签配置
label: {
show: true,
position: 'outside',
formatter: function (params) {
// 这里的逻辑是为了模仿截图:右边的文字名字在右侧,左边的文字名字在左侧
// 简单的判断逻辑:基于 ECharts 内部计算的 label 角度,或者根据数据索引
// 这里我们构建一个富文本结构
return `{name|${params.name}}\n{val|${params.value}万} {pct|${params.data.percent}}`;
},
// 关键配置:使用 edge 对齐方式让标签像表格一样排列在两侧
alignTo: 'edge',
edgeDistance: 10, // 距离容器边缘的距离
minMargin: 5,
lineHeight: 20,
rich: {
name: {
fontSize: 13,
fontWeight: 'bold',
color: '#333',
padding: [0, 5]
},
val: {
fontSize: 12,
color: '#666'
},
pct: {
fontSize: 12,
color: '#666',
padding: [0, 5]
}
}
},
// 引导线配置
labelLine: {
length: 15,
length2: 60, // 第二段线长一点,以便连接到边缘
maxSurfaceAngle: 80
},
// 每一项的样式
itemStyle: {
borderColor: '#fff',
borderWidth: 2
}
}
]
};
myChart.setOption(option);
};
// 响应式处理
const resizeHandler = () => {
if (myChart) {
myChart.resize();
}
};
onMounted(() => {
nextTick(() => {
initChart();
window.addEventListener('resize', resizeHandler);
});
});
onUnmounted(() => {
window.removeEventListener('resize', resizeHandler);
if (myChart) {
myChart.dispose();
}
});
</script>
<style lang="scss" scoped>
.funding-source-container {
width: 100%;
background: #fff;
border-radius: 8px;
padding: 20px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", Arial, sans-serif;
// 头部样式
.chart-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
.title-wrapper {
display: flex;
align-items: center;
.blue-bar {
width: 4px;
height: 18px;
background-color: #409eff; // Element Plus Primary Blue
margin-right: 8px;
border-radius: 2px;
}
.title-text {
font-size: 18px;
font-weight: 700;
color: #303133;
}
}
.header-icons {
display: flex;
gap: 15px;
color: #909399;
cursor: pointer;
.el-icon {
font-size: 18px;
&:hover {
color: #409eff;
}
}
}
}
// 主体布局
.chart-body {
display: flex;
flex-direction: row;
height: 450px; // 固定一个高度给图表展示
// 左侧统计面板
.stats-panel {
width: 200px;
display: flex;
flex-direction: column;
justify-content: center;
gap: 20px;
flex-shrink: 0;
.stat-card {
padding: 15px;
border-radius: 6px;
display: flex;
flex-direction: column;
gap: 8px;
.label {
font-size: 14px;
}
.value {
font-size: 20px;
font-weight: 800;
}
// 不同卡片的特定样式
&.total-card {
background-color: #eef6ff; // 浅蓝背景
.label { color: #409eff; }
.value { color: #185ebd; }
}
&.govt-card {
background-color: #fff2f2; // 浅红背景
.label { color: #f56c6c; }
.value { color: #c43e3e; }
}
&.other-card {
background-color: #f0f9eb; // 浅绿背景
.label { color: #67c23a; }
.value { color: #3a8e1e; }
}
}
}
// 右侧图表区域
.chart-panel {
flex: 1;
min-width: 0; // 防止 flex 子项溢出
height: 100%;
}
}
}
// 移动端适配微调
@media (max-width: 768px) {
.chart-body {
flex-direction: column !important;
height: auto !important;
.stats-panel {
width: 100% !important;
flex-direction: row !important;
overflow-x: auto;
padding-bottom: 10px;
}
.chart-panel {
height: 400px !important;
}
}
}
</style>
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论