提交 52826e66 authored 作者: yanpeng's avatar yanpeng

Merge branch 'master' into yp-dev

......@@ -34,4 +34,16 @@ export function getDecreeOrganization(params) {
url: `/api/administrativeOrderInfo/organization/${params.id}`,
params
})
}
// 获取全局信息
/**
* @param {id}
*/
export function getDecreeSummary(params) {
return request({
method: 'GET',
url: `/api/administrativeOrderInfo/summary/${params.id}`,
params
})
}
\ No newline at end of file
......@@ -94,4 +94,39 @@ export function getProcessSummary(params) {
url: `/api/billDeepDive/processSummary/${params.id}`,
params,
})
}
\ No newline at end of file
}
// 获取党派政治献金
/**
* @param {id, personCongress}
*/
export function getBillPoliContribution(params) {
return request({
method: 'GET',
url: `/api/billDeepDive/processAnalyze/totalxj/${params.id}`,
params
})
}
// 获取主要议员政治献金
/**
* @param {id, personCongress}
*/
export function getBillMainPoliContribution(params) {
return request({
method: 'GET',
url: `/api/billDeepDive/processAnalyze/xj/${params.id}`,
params
})
}
// 根据法案ID获取人员政治献金来源及行业领域分布
/**
* @param {id, personId}
*/
export function getBillPersonPoliContribution(params) {
return request({
method: 'GET',
url: `/api/billDeepDive/processAnalyze/xj/${params.id}/${params.personId}`
})
}
......@@ -30,4 +30,17 @@ export function getHylyList() {
method: 'GET',
url: `/api/billImpactAnalysis/industry/hylyList`,
})
}
// 获取公司详情
/**
* @param {billId,companyId,id}
*/
export function getCompanyDetail(params) {
return request({
method: 'GET',
url: `/api/billImpactAnalysis/industry/companyDetail/${params.billId}/${params.id}/${params.companyId}`,
params,
})
}
\ No newline at end of file
......@@ -10,6 +10,15 @@ export function getThinkTankList() {
})
}
//智库概览:获取智库发布
export function getNewReport() {
return request({
method: 'GET',
url: `/api/thinkTankOverview/newReport`,
})
}
// 风险信号
export function getThinkTankRiskSignal() {
return request({
......@@ -20,10 +29,10 @@ export function getThinkTankRiskSignal() {
}
// 政策建议趋势分布
export function getThinkTankPolicyIndustryChange() {
export function getThinkTankPolicyIndustryChange(params) {
return request({
method: 'GET',
url: `/api/thinkTankOverview/policyIndustryChange`,
url: `/api/thinkTankOverview/policyIndustryChange/${params}`,
})
}
......@@ -44,4 +53,189 @@ export function getThinkTankDonation() {
url: `/api/thinkTankOverview/donation`,
})
}
\ No newline at end of file
}
//智库概览:获取智库研究热点
export function getThinkTankHot(params) {
return request({
method: 'GET',
url: `/api/thinkTankOverview/research/hot/${params}`,
})
}
// 行业领域字典列表
export function getHylyList() {
return request({
method: 'GET',
url: `/api/billImpactAnalysis/industry/hylyList`,
})
}
//获取智库报告
export function getThinkTankReport(params) {
return request({
method: 'GET',
url: `/api/thinkTankOverview/report`,
params: params
})
}
/********* 智库信息 */
//智库百科:获取全局信息
export function getThinkTankSummary(params) {
return request({
method: 'GET',
url: `/api/thinkTankInfo/summary/${params.id}`,
})
}
//智库报告:获取智库报告类型
export function getThinkDynamicsReportType() {
return request({
method: 'GET',
url: `/api/thinkTankInfo/reportType`,
})
}
//智库动态:获取智库报告
export function getThinkDynamicsReport(params) {
return request({
method: 'GET',
url: `/api/thinkTankInfo/report/${params.id}/${params.startDate}`,
params: params.parmas
})
}
//提出建议领域分布
export function getThinkPolicyIndustry(params) {
return request({
method: 'GET',
url: `/api/thinkTankInfo/policyIndustry/${params.id}/${params.year}`,
})
}
//获取相关政策领域分布
export function getThinkPolicyIndustryTotal(params) {
return request({
method: 'GET',
url: `/api/thinkTankInfo/policyIndustryTotal/${params.id}/${params.year}`,
})
}
//获取热门研究方向变化趋势
export function getThinkPolicyIndustryChange(params) {
return request({
method: 'GET',
url: `/api/thinkTankInfo/policyIndustryChange/${params.id}/${params.year}`,
})
}
//获取智库政策
export function getThinkPolicy(params) {
return request({
method: 'GET',
url: `/api/thinkTankInfo/policy/${params.id}/${params.startDate}`,
params
})
}
//智库百科基本信息
export function getThinkTankInfoBasic(params) {
return request({
method: 'GET',
url: `/api/thinkTankInfo/basic/${params}`,
})
}
//获取全球分支机构
export function getThinkTankInfoBranch(params) {
return request({
method: 'GET',
url: `/api/thinkTankInfo/branch/${params}`,
})
}
//获取经费来源统计
export function getThinkTankFundsTotal(params) {
return request({
method: 'GET',
url: `/api/thinkTankInfo/fundsTotal/${params}`,
})
}
//获取经费来源
export function getThinkTankFundsSource(params) {
return request({
method: 'GET',
url: `/api/thinkTankInfo/fundsSource/${params}`,
})
}
//获取研究领域演变
export function getThinkTankResearchAreae(params) {
return request({
method: 'GET',
url: `/api/thinkTankInfo/researchArea/${params}`,
})
}
//获取核心研究人员
export function getThinkTankPerson(params) {
return request({
method: 'GET',
url: `/api/thinkTankInfo/person/${params}`,
})
}
//获取报告内容摘要
export function getThinkTankReportAbstract(params) {
return request({
method: 'GET',
url: `/api/thinkTankReport/abstract/${params}`,
})
}
//获取报告主要观点
export function getThinkTankReportContent(params) {
return request({
method: 'GET',
url: `/api/thinkTankReport/content/${params}`,
})
}
//获取涉及科技领域
export function getThinkTankReportIndustry(params) {
return request({
method: 'GET',
url: `/api/thinkTankReport/industry/${'Rand_RRA3572-1'}`,
})
}
//获取科技领域词云
export function getThinkTankReportIndustryCloud(params) {
return request({
method: 'GET',
url: `/api/thinkTankReport/industry/${params.id}/${params.industryId}`,
})
}
//获取政策建议落实情况
export function getThinkTankReportPolicy(params) {
return request({
method: 'GET',
url: `/api/thinkTankReport/policy/${params}`,
})
}
//获取相关政策动态
export function getThinkTankReportPolicyAction(params) {
return request({
method: 'GET',
url: `/api/thinkTankReport/policyAction/${params}`,
})
}
......@@ -2523,6 +2523,7 @@ onUnmounted(() => {});
font-size: 14px;
font-weight: 400;
line-height: 22px;
overflow: hidden;
}
}
.right-footer {
......@@ -2606,6 +2607,7 @@ onUnmounted(() => {});
img {
width: 100%;
height: 100%;
border-radius: 50%;
}
}
.right {
......
......@@ -212,7 +212,7 @@ onMounted(() => {
height: 1016px;
background: rgba(249, 250, 252, 1);
position: relative;
margin: 0 auto;
// margin: 0 auto;
.layout-header {
width: 1920px;
height: 64px;
......
......@@ -14,14 +14,19 @@ const getPieChart = (data,colorList) => {
},
label: {
alignTo: 'edge',
formatter: '{name|{b}}\n{time|{c} 条 {d}%}',
formatter: '{name|{b}}\n{time|{d}%}',
minMargin: 5,
edgeDistance: 10,
lineHeight: 15,
rich: {
time: {
fontSize: 10,
color: '#999'
fontSize: 12,
color: '#666'
},
name: {
fontSize: 14,
color: '#333',
fontWeight: 'bold'
}
}
},
......
const getSankeyChart = () => {
const getSankeyChart = (data = [], links = []) => {
const option = {
tooltip: {
trigger: 'item',
triggerOn: 'mousemove'
},
series: {
type: 'sankey',
layout: 'none',
left: '5%',
right: '5%',
left: '1%',
right: '1%',
top: '5%',
bottom: '5%',
emphasis: {
focus: 'adjacency'
},
nodeWidth: 50,
nodeGap: 2,
layoutIterations: 32,
lineStyle: {
color: 'source',
curveness: 0.5
},
label: {
show: true,
formatter: function (params) {
return `${params.name} $${params.value}`;
return `${params.name} $${params.value.toLocaleString()}`;
},
position: 'right',
textStyle: {
fontSize: '16px',
color: '#555'
}
fontSize: 16,
color: '#555'
},
data: [
{
name: '马尔科·卢比奥',
label: {
position: 'left'
}
},
{
name: '成长俱乐部'
},
{
name: '埃利奥特管理公司'
},
{
name: '高盛集团'
},
{
name: '黑石集团'
},
{
name: '佛罗里达水晶'
},
{
name: '美国银行'
}
],
links: [
{
source: '成长俱乐部',
target: '马尔科·卢比奥',
value: 680751
},
{
source: '埃利奥特管理公司',
target: '马尔科·卢比奥',
value: 440120
},
{
source: '高盛集团',
target: '马尔科·卢比奥',
value: 371517
},
{
source: '黑石集团',
target: '马尔科·卢比奥',
value: 259321
},
{
source: '佛罗里达水晶',
target: '马尔科·卢比奥',
value: 203775
},
{
source: '美国银行',
target: '马尔科·卢比奥',
value: 150892
}
]
data: data,
links: links
}
};
......
......@@ -95,58 +95,117 @@
<div class="box3-main-center-header-box6">关键议员</div>
</div>
<div class="box3-main-center-content">
<div class="box3-main-center-content-box">
<div class="item" v-for="(item, index) in voteAnalysisList1" :key="index">
<div class="box3-main-center-content-box" v-for="item in voteAnalysisList" :key="item.actionId">
<div class="item">
<div class="item-box1">
<div class="box1-left">
<div class="icon" v-if="item.nameIcon">
<img :src="item.nameIcon" alt="" />
</div>
<div style="height: 80px;">
<div class="name" :class="{ nameBlod: item.nameBold }">
{{ item.name }}
<div style="width: 100%; display: flex; flex-direction: column; align-items: flex-end;">
<div class="name nameBlod" :title="item.actionTitle" style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%;">
{{ item.actionTitle }}
</div>
<div class="time">
{{ item.time }}
{{ formatDate(item.actionDate) }}
</div>
</div>
</div>
<div class="box1-right">
<div class="box1-right-top">
<el-progress :percentage="item.supportRate" :show-text="false"> </el-progress>
<el-progress :percentage="Number(item.agreePercent)" :show-text="false" color="#1677FF"> </el-progress>
</div>
<div class="box1-right-bottom">
<el-progress :percentage="item.againistRate" :show-text="false"> </el-progress>
<el-progress :percentage="Number(item.againstPercent)" :show-text="false" color="#FF9054"> </el-progress>
</div>
</div>
</div>
<div class="item-box2">
<div class="box2-1">{{ item.support + "票" }}</div>
<div class="box2-2">{{ item.againist + "票" }}</div>
<div class="box2-1" style="color: #1677FF">{{ item.agreeCount + "票" }}</div>
<div class="box2-2" style="color: #FF9054">{{ item.againstCount + "票" }}</div>
</div>
<div class="item-box3">
<div class="box3-1">{{ item.supportRank }}</div>
<div class="box3-2">{{ item.againistRank }}</div>
<div class="box3-1"></div>
<div class="box3-2"></div>
</div>
<div class="item-box4">
<div class="box4-1">{{ item.supportRate + "%" }}</div>
<div class="box4-2">{{ item.againistRate + "%" }}</div>
<div class="box4-1" style="color: #1677FF">{{ item.agreePercent + "%" }}</div>
<div class="box4-2" style="color: #FF9054">{{ item.againstPercent + "%" }}</div>
</div>
<div class="item-box5"></div>
<div class="item-box6">
<el-icon size="20" color="#555"><ArrowDownBold /></el-icon>
</div>
</div>
<div class="item">
<div class="item-box1">
<div class="box1-left">
<div class="icon">
<img :src="MZD" alt="" />
</div>
<div class="name">民主党</div>
</div>
<div class="box1-right">
<div class="box1-right-top">
<el-progress :percentage="Number(item.dagreePercent)" :show-text="false" color="#85b4ff"> </el-progress>
</div>
<div class="box1-right-bottom">
<el-progress :percentage="Number(item.dagainstPercent)" :show-text="false" color="#FF9054"> </el-progress>
</div>
</div>
</div>
<div class="item-box2">
<div class="box2-1" style="color: #1677FF">{{ item.dagreeCount + "票" }}</div>
<div class="box2-2" style="color: #FF9054">{{ item.dagainstCount + "票" }}</div>
</div>
<div class="item-box3"></div>
<div class="item-box4">
<div class="box4-1" style="color: #1677FF">{{ item.dagreePercent + "%" }}</div>
<div class="box4-2" style="color: #FF9054">{{ item.dagainstPercent + "%" }}</div>
</div>
<div class="item-box5">
<div class="box5-1" v-if="item.people">{{ item.people+' 人' }}</div>
<div class="box5-2" v-if="item.peopleRank">{{ `( ${item.peopleRank} )` }}</div>
<div class="box5-1" style="color: #CE4F51">{{ item.dreverseCount + "人" }}</div>
</div>
<div class="item-box6">
<div class="img-box" v-if="item.keyUser">
<img :src="item.keyUser" alt="" />
<div class="img-box" v-if="item.dpersonImageUrl">
<img :src="item.dpersonImageUrl" alt="" />
</div>
<div v-else>
<el-icon size="20" color="#555"><ArrowDownBold /></el-icon>
</div>
</div>
<div class="item">
<div class="item-box1">
<div class="box1-left">
<div class="icon">
<img :src="GHD" alt="" />
</div>
<div class="name">共和党</div>
</div>
<div class="box1-right">
<div class="box1-right-top">
<el-progress :percentage="Number(item.ragreePercent)" :show-text="false" color="#1677FF"> </el-progress>
</div>
<div class="box1-right-bottom">
<el-progress :percentage="Number(item.ragainstPercent)" :show-text="false" color="#ffdcc8"> </el-progress>
</div>
</div>
</div>
<div class="item-box2">
<div class="box2-1" style="color: #1677FF">{{ item.ragreeCount + "票" }}</div>
<div class="box2-2" style="color: #FF9054">{{ item.ragainstCount + "票" }}</div>
</div>
<div class="item-box3"></div>
<div class="item-box4">
<div class="box4-1" style="color: #1677FF">{{ item.ragreePercent + "%" }}</div>
<div class="box4-2" style="color: #FF9054">{{ item.ragainstPercent + "%" }}</div>
</div>
<div class="item-box5">
<div class="box5-1" style="color: #CE4F51">{{ item.rreverseCount + "人" }}</div>
</div>
<div class="item-box6">
<div class="img-box" v-if="item.rpersonImageUrl">
<img :src="item.rpersonImageUrl" alt="" />
</div>
</div>
</div>
</div>
<div class="box3-main-center-content-box">
<!-- <div class="box3-main-center-content-box">
<div class="item" v-for="(item, index) in voteAnalysisList2" :key="index">
<div class="item-box1">
<div class="box1-left">
......@@ -196,8 +255,8 @@
</div>
</div>
</div>
</div>
<div class="box3-main-center-content-box">
</div> -->
<!-- <div class="box3-main-center-content-box">
<div class="item" v-for="(item, index) in voteAnalysisList3" :key="index">
<div class="item-box1">
<div class="box1-left">
......@@ -298,7 +357,7 @@
</div>
</div>
</div>
</div>
</div> -->
</div>
</div>
<div class="box3-main-footer">
......@@ -597,6 +656,15 @@ const handleGetBillAmeAnalyzeCount = async () => {
};
// 获取投票分析
const voteAnalysisList = ref([]);
const formatDate = (dateStr) => {
if (!dateStr) return "";
const date = new Date(dateStr);
const y = date.getFullYear();
const m = date.getMonth() + 1;
const d = date.getDate();
return `${y}年${m}月${d}日`;
};
const handleGetBillVoteAnalyze = async () => {
const params = {
id: window.sessionStorage.getItem("billId")
......@@ -604,6 +672,7 @@ const handleGetBillVoteAnalyze = async () => {
try {
const res = await getBillTp(params);
console.log("投票分析", res);
voteAnalysisList.value = res.data;
} catch (error) {
console.error("投票分析 error", error);
}
......@@ -1152,8 +1221,10 @@ onMounted(async () => {
}
}
.box3-main-center-content {
height: 682px;
overflow: auto;
.box3-main-center-content-box {
width: 830px;
width: 805px;
height: 160px;
box-sizing: border-box;
border: 1px solid rgba(243, 243, 244, 1);
......
......@@ -3,24 +3,65 @@ import * as echarts from "echarts";
const getBarChart = (nameList, valueList) => {
const colorList = ['#b37feb', '#ffc53e', '#36cfc9', '#5c80f7', '#ff7d7a', '#4a9cff']
const option = {
tooltip: {},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
grid: {
top: '3%',
right: '7%',
bottom: '1%',
left: '1%',
top: '5%',
right: '15%',
bottom: '5%',
left: '3%',
containLabel: true
},
dataZoom: [
{
type: 'slider',
show: valueList.length > 5,
yAxisIndex: 0,
width: 8,
right: 10,
top: 20,
bottom: 20,
startValue: 0,
endValue: 4, // Show 5 items (0-4)
fillerColor: 'rgba(167,183,204,0.4)',
borderColor: 'transparent',
handleSize: 0,
showDetail: false,
brushSelect: false
},
{
type: 'inside',
yAxisIndex: 0,
startValue: 0,
endValue: 4,
zoomOnMouseWheel: false,
moveOnMouseWheel: true,
moveOnTouch: true
}
],
xAxis: {
type: 'value',
splitLine: {
show: false
},
show: false
axisLine: {
show: false
},
axisTick: {
show: false
},
axisLabel: {
show: false
}
},
yAxis: {
type: 'category',
data: nameList,
inverse: true, // Display from top to bottom
splitLine: {
show: false
},
......@@ -31,60 +72,43 @@ const getBarChart = (nameList, valueList) => {
show: false
},
axisLabel: {
show: true
show: true,
color: '#333',
fontSize: 14,
width: 100, // Limit width to handle long names
overflow: 'truncate',
ellipsis: '...'
}
},
series: [{
type: 'bar',
data: valueList.map((item,index) => {
data: valueList.map((item, index) => {
// Cycle through colors if more data than colors
const colorIndex = index % colorList.length;
const color = colorList[colorIndex];
return {
value: item,
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
{ offset: 0, color: 'rgba(255,255,255,0)' }, // Transparent start
{ offset: 1, color: color } // Solid end
]),
borderRadius: [0, 10, 10, 0]
},
label: {
textStyle: {
color: colorList[index]
}
show: true,
position: 'right',
color: color,
fontSize: 16,
offset: [5, 0] // Add some space between bar and label
}
};
}
),
barWidth: 8,
label: {
show: true,
position: [365, 0],
formatter: function(params) {
return params.value
}
},
itemStyle: {
color: function (params) {
var colorList = [
['#fff', '#b37feb'],
['#fff', '#ffc53e'],
['#fff', '#36cfc9'],
['#fff', '#5c80f7'],
['#fff', '#ff7d7a'],
['#fff', '#4a9cff'],
];
var index = params.dataIndex;
if (params.dataIndex >= colorList.length) {
index = params.dataIndex - colorList.length;
}
return new echarts.graphic.LinearGradient(0, 0, 1, 0,
[{
offset: 0,
color: colorList[index][0]
},
{
offset: 1,
color: colorList[index][1]
}
]);
},
barBorderRadius: 4,
}
}),
barWidth: 10,
showBackground: false
}]
}
return option
}
export default getBarChart
\ No newline at end of file
export default getBarChart
......@@ -49,7 +49,7 @@ const getBarChart1 = (nameList, valueList) => {
offset: 1,
color: 'rgba(22,119,255,0)' // 结束颜色:浅色且透明度降低
}]),
barBorderRadius: 4,
borderRadius: 4,
}
}]
}
......
......@@ -41,7 +41,7 @@ const getGraphChart = (nodes, links) => {
itemStyle: {
color: '#73C0DE'
},
layout: 'force',
layout: 'none',
data: nodes,
links: links,
// categories: categories,
......
......@@ -319,7 +319,7 @@
新闻动态
</div>
<div class="btn" :class="{ btnActive: dialogBoxBtnActive === 1 }" @click="handleClcikDialogBoxBtn(1)">
任务履历
人物履历
</div>
</div>
<div class="inner-right-main">
......@@ -1411,6 +1411,11 @@ onMounted(() => {
font-size: 14px;
font-weight: 400;
line-height: 22px;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
overflow: hidden;
text-overflow: ellipsis;
}
.timeline-content1 {
color: rgba(132, 136, 142, 1);
......
......@@ -6,8 +6,8 @@ const getBarChart = (nameList, valueList) => {
grid: {
top: '3%',
right: '3%',
bottom: '1%',
left: '1%',
bottom: '3%',
left: '3%',
containLabel: true
},
yAxis: {
......@@ -18,7 +18,12 @@ const getBarChart = (nameList, valueList) => {
axisLine: {
show: false
},
show: true
show: true,
textStyle: {
color: 'rgba(95, 101, 108, 1)',
fontFamily: 'Microsoft YaHei',
fontsize: 14,
}
},
xAxis: {
type: 'category',
......@@ -33,7 +38,12 @@ const getBarChart = (nameList, valueList) => {
show: true
},
axisLabel: {
show: true
show: true,
textStyle: {
color: 'rgba(95, 101, 108, 1)',
fontFamily: 'Microsoft YaHei',
fontsize: 14,
}
}
},
series: [{
......
......@@ -2,46 +2,53 @@ const getPieChart = (data) => {
let option = {
series: [
{
type: 'pie',
radius: [110, 143],
height: '100%',
left: 'center',
width: '100%',
itemStyle: {
borderColor: '#fff',
borderWidth: 1
},
label: {
alignTo: 'edge',
formatter: '{name|{b}}\n{time|{c} 条 {d}%}',
minMargin: 5,
edgeDistance: 10,
lineHeight: 24,
rich: {
time: {
fontSize: 16,
color: '#999'
type: 'pie',
radius: [110, 143],
height: '100%',
left: 'center',
width: '95%',
itemStyle: {
borderColor: '#fff',
borderWidth: 1
},
label: {
alignTo: 'edge',
formatter: '{name|{b}}\n{time|{c} 条 {d}%}',
minMargin: 5,
edgeDistance: 10,
lineHeight: 24,
rich: {
name: {
color: 'rgba(59, 65, 75, 1)',
fontFamily: 'Microsoft YaHei',
fontSize: 16,
fontWeight: 'bold',
},
time: {
fontSize: 16,
fontFamily: 'Microsoft YaHei',
color: '#rgba(95, 101, 108, 1)'
}
}
}
},
labelLine: {
length: 15,
length2: 0,
maxSurfaceAngle: 80
},
labelLayout: function (params) {
const isLeft = params.labelRect.x < 556 / 2;
const points = params.labelLinePoints;
// Update the end point.
points[2][0] = isLeft
? params.labelRect.x
: params.labelRect.x + params.labelRect.width;
return {
labelLinePoints: points
};
},
data: data
}]
},
labelLine: {
length: 15,
length2: 0,
maxSurfaceAngle: 80
},
labelLayout: function (params) {
const isLeft = params.labelRect.x < 556 / 2;
const points = params.labelLinePoints;
// Update the end point.
points[2][0] = isLeft
? params.labelRect.x
: params.labelRect.x + params.labelRect.width;
return {
labelLinePoints: points
};
},
data: data
}]
}
return option
}
......
......@@ -129,26 +129,26 @@ const showList = computed(() => {
});
const siderList = ref([
{
time: "2023",
title: "拜登人工智能政令"
},
{
time: "2023",
title: "拜登人工智能政令"
},
{
time: "2025",
title: "特朗普撤销拜登AI规则"
},
{
time: "2023",
title: "美国AI行动计划"
},
{
time: "2024",
title: "对中国AI芯片限制"
}
// {
// time: "",
// title: ""
// },
// {
// time: "2023",
// title: "拜登人工智能政令"
// },
// {
// time: "2025",
// title: "特朗普撤销拜登AI规则"
// },
// {
// time: "2023",
// title: "美国AI行动计划"
// },
// {
// time: "2024",
// title: "对中国AI芯片限制"
// }
]);
const siderActiveIndex = ref(0);
const handleClickSider = async index => {
......@@ -178,22 +178,22 @@ const handleClickSider = async index => {
};
const decreeInfo = ref({
img: box2InfoImg,
totalTitle: "关于安全、可靠和可信地开发和使用人工智能的行政命令",
eTotalTitle: "Executive Order on the Safe, Secure, and Trustworthy Development and Use of Artificial Intelligence",
signTime: "2025年7月23日",
signOrg: "乔·拜登(Joe Biden)",
img: "",
totalTitle: "",
eTotalTitle: "",
signTime: "",
signOrg: "",
list: [
{
content:
"要求强大AI系统开发者与政府分享安全测试结果(“红队测试”);制定生物合成筛查标准防范风险;建立AI生成内容鉴别标准"
},
{
content: "优先支持隐私保护技术(PET)研发;评估各机构如何收集和使用商业信息;制定评估隐私保护技术有效性的指南。"
},
{
content: "为解决算法歧视提供明确指导;确保刑事司法系统中AI使用的公平性;协调调查和起诉AI相关的民权侵犯行为。"
}
// {
// content:
// "要求强大AI系统开发者与政府分享安全测试结果(“红队测试”);制定生物合成筛查标准防范风险;建立AI生成内容鉴别标准"
// },
// {
// content: "优先支持隐私保护技术(PET)研发;评估各机构如何收集和使用商业信息;制定评估隐私保护技术有效性的指南。"
// },
// {
// content: "为解决算法歧视提供明确指导;确保刑事司法系统中AI使用的公平性;协调调查和起诉AI相关的民权侵犯行为。"
// }
]
});
......
......@@ -6,16 +6,16 @@
<div class="layout-main-header-left-box">
<div class="left-box-top">
<div class="icon">
<img src="./assets/images/USA-logo.png" alt="" />
<img :src="summaryInfo.officialUrl" alt="" />
</div>
<div class="info">
<div class="info-box1">{{ "EO 14320-推动美国人工智能技术栈的出口" }}</div>
<div class="info-box1">{{ summaryInfo.name }}</div>
<div class="info-box2">
<div class="info-box2-item">{{ "总统行动" }}</div>
<div class="info-box2-item">{{ summaryInfo.order }}</div>
|
<div class="info-box2-item">{{ "行政命令" }}</div>
<div class="info-box2-item">{{ summaryInfo.type }}</div>
|
<div class="info-box2-item">{{ "Promoting the Export of the American AI Technology Stack" }}</div>
<div class="info-box2-item">{{ summaryInfo.ename }}</div>
</div>
</div>
</div>
......@@ -39,13 +39,14 @@
</div>
<div class="layout-main-header-right-box">
<div class="right-box-top">
<div class="time">{{ "2025年7月23日" }}</div>
<div class="name">{{ "唐纳德·约翰·特朗普(Donald John Trump)" }}</div>
<div class="time">{{ summaryInfo.postDate }}</div>
<div class="name">{{ summaryInfo.orgName }}</div>
</div>
<div class="right-box-bottom">
<el-button type="plain" size="large" icon="Search" @click="handleSwitchActiveName('法案原文')"
<!-- <el-button type="plain" size="large" icon="Search" @click="handleSwitchActiveName('法案原文')"
>政令原文</el-button
>
> -->
<el-button type="plain" size="large" icon="Search">政令原文</el-button>
<el-button type="primary" size="large" icon="EditPen">分析报告</el-button>
</div>
</div>
......@@ -123,6 +124,7 @@
import { ref, onMounted, onUnmounted } from "vue";
import router from "@/router";
import { useRoute } from "vue-router";
import { getDecreeSummary } from "@/api/decree/introduction";
import search from "./assets/images/search.png";
import icon1 from "./assets/icons/icon1.png";
......@@ -132,12 +134,16 @@ import icon2Active from "./assets/icons/icon2_active.png";
import icon3 from "./assets/icons/icon3.png";
import icon3Active from "./assets/icons/icon3_active.png";
import DefaultIcon2 from '@/assets/icons/default-icon2.png'
const route = useRoute();
const decreeId = ref(route.query.id);
const activeName = ref("分析报告");
const summaryInfo = ref({});
const handleSwitchActiveName = name => {
activeName.value = name;
};
......@@ -189,7 +195,22 @@ const handleClickMainHeaderBtn = item => {
});
};
// 获取全局信息
const handleGetSummary = async () => {
const params = {
id: route.query.id
};
try {
const res = await getDecreeSummary(params);
console.log("全局信息", res);
if (res.code === 200 && res.data) {
summaryInfo.value = res.data;
}
} catch (error) {}
};
onMounted(() => {
handleGetSummary();
if (window.sessionStorage.getItem("activeTitle")) {
activeTitle.value = window.sessionStorage.getItem("activeTitle");
}
......@@ -217,7 +238,7 @@ onUnmounted(() => {
display: flex;
justify-content: space-between;
.layout-main-header-left-box {
width: 800px;
width: 1100px;
margin-left: 160px;
margin-top: 13px;
.left-box-top {
......@@ -226,6 +247,10 @@ onUnmounted(() => {
.icon {
width: 64px;
height: 64px;
img{
width: 100%;
height: 100%;
}
}
.info {
margin-left: 9px;
......@@ -334,7 +359,7 @@ onUnmounted(() => {
}
.layout-main-center {
// height: calc(100% - 137px);
overflow: hidden;
overflow: hidden;
}
}
.layout-report-box {
......
......@@ -30,11 +30,11 @@
</div>
</div>
<div class="box1-list-box">
<div class="box1-item" v-for="(item, index) in showCompanyList" :key="index">
<div class="box1-item" v-for="(item, index) in showCompanyList" :key="index" @click="handleToCompanyDetail">
<div class="id">{{ index + 1 }}</div>
<div class="title">{{ item.name }}</div>
<div class="icon">
<img v-if="item.status === 'up'" src="./assets/images/up.png" alt="" />
<img v-if="item.status >= 0" src="./assets/images/up.png" alt="" />
<img v-else src="./assets/images/down.png" alt="" />
</div>
</div>
......@@ -72,7 +72,7 @@
</div>
<div class="box2-main">
<div class="box2-line-box"></div>
<div class="box2-line-box" v-if="timeLineList.length"></div>
<div
class="box2-item"
:class="{ box2ItemFooter: index % 2 }"
......@@ -156,15 +156,21 @@
</template>
<script setup>
import { ref, computed,watch, onMounted } from "vue";
import { ref, computed, watch, onMounted } from "vue";
import { useRoute } from "vue-router";
import router from "@/router";
import setChart from "@/utils/setChart";
import * as echarts from "echarts";
import getBarChart from "./utils/barChart";
import { getDecreeIndustry, getDecreehylyList, getDecreeCompany, getDecreeAction } from "@/api/decree/influence";
const route = useRoute();
// 跳转企业详情
const handleToCompanyDetail = () => {
const route = router.resolve("/companyPages");
window.open(route.href, "_blank");
};
// 企业影响分析
const companyTotalNum = ref(0); // 企业数量
const isCRelated = ref(false); // 只看中国企业
......@@ -208,7 +214,13 @@ const handelBox1 = async () => {
const box1BtnActiveName = ref("");
const curAreaId = ref(0);
const box1BtnList = ref(["集成电路", "新能源", "人工智能", "先进制造", "量子科技"]);
const box1BtnList = ref([
// "集成电路",
// "新能源",
// "人工智能",
// "先进制造",
// "量子科技"
]);
const handleClickBox1Btn = btn => {
box1BtnActiveName.value = btn.name;
curAreaId.value = btn.id;
......@@ -224,51 +236,32 @@ const handleGetHylyList = async () => {
box1BtnList.value = res.data;
box1BtnActiveName.value = box1BtnList.value[0].name;
curAreaId.value = box1BtnList.value[0].id;
handleGetCompanyListByArea();
}
} catch (error) {}
};
const companyList = ref([
{
name: "宁德时代新能源科技股份有限公司",
status: "down"
},
{
name: "比亚迪股份有限公司",
status: "down"
},
{
name: "隆基绿能科技股份有限公司",
status: "down"
},
{
name: "晶科能源控股有限公司",
status: "down"
},
{
name: "厦门海辰储能科技股份有限公司",
status: "down"
},
{
name: "国轩高科股份有限公司",
status: "up"
},
{
name: "远景科技集团",
status: "down"
},
{
name: "惠州亿纬锂能股份有限公司",
status: "down"
},
{
name: "天合光能股份有限公司",
status: "down"
},
{
name: "晶澳太阳能科技股份有限公司",
status: "up"
}
// {
// name: "宁德时代新能源科技股份有限公司",
// status: "down"
// },
// {
// name: "比亚迪股份有限公司",
// status: "down"
// },
// {
// name: "隆基绿能科技股份有限公司",
// status: "down"
// },
// {
// name: "晶科能源控股有限公司",
// status: "down"
// },
// {
// name: "厦门海辰储能科技股份有限公司",
// status: "down"
// }
]);
const currentPage = ref(1);
const pageSize = ref(10);
......@@ -296,7 +289,7 @@ const handleGetCompanyListByArea = async () => {
return {
name: item.name,
id: item.id,
status: "up"
status: item.marketChange
};
});
companyTotalNum.value = companyList.value.length;
......@@ -312,26 +305,14 @@ const handleGetCompanyListByArea = async () => {
// 政令举措落实分析
const timeLineList = ref([
{
time: "2025年7月25日",
content: "商务部已成立AI出口计划办公室,并开始招募专业人员。"
},
{
time: "2025年7月31日",
content: "英伟达、微软、谷歌等企业已提交初步技术栈提案。"
},
{
time: "2025年8月5日",
content: "国务院开始与盟友国家进行初步磋商。"
},
{
time: "2025年8月9日",
content: "国防部、能源部安全审查流程尚未最终确定。"
},
{
time: "2025年8月12日",
content: "商务部已成立AI出口计划办公室,并开始招募专业人员。"
}
// {
// time: "2025年7月25日",
// content: "商务部已成立AI出口计划办公室,并开始招募专业人员。"
// },
// {
// time: "2025年7月31日",
// content: "英伟达、微软、谷歌等企业已提交初步技术栈提案。"
// }
]);
const handleGetAction = async () => {
......@@ -358,48 +339,48 @@ const handleGetAction = async () => {
// 历史相似举措及落实情况
const box3List = ref([
{
type: "科技法案",
title: "瓦森纳安排",
content: "落实情况:持续有效,但面临技术快速迭代挑战。",
time: "1996-至今",
tag: "人工智能"
},
{
type: "科技法案",
title: "云计算出口管制",
content: "落实情况:部分有效,但执行难度大。",
time: "1996-至今",
tag: "人工智能"
},
{
type: "科技法案",
title: "芯片与科学法案",
content: "落实情况:正在实施,效果待观察。",
time: "2022-至今",
tag: "人工智能"
},
{
type: "科技法案",
title: "AI芯片出口管制",
content: "落实情况:部分有效,但催生中国自主创新。",
time: "1996-至今",
tag: "人工智能"
},
{
type: "科技法案",
title: "瓦森纳安排",
content: "落实情况:持续有效,但面临技术快速迭代挑战。",
time: "1996-至今",
tag: "人工智能"
},
{
type: "科技法案",
title: "瓦森纳安排",
content: "落实情况:持续有效,但面临技术快速迭代挑战。",
time: "1996-至今",
tag: "人工智能"
}
// {
// type: "科技法案",
// title: "瓦森纳安排",
// content: "落实情况:持续有效,但面临技术快速迭代挑战。",
// time: "1996-至今",
// tag: "人工智能"
// },
// {
// type: "科技法案",
// title: "云计算出口管制",
// content: "落实情况:部分有效,但执行难度大。",
// time: "1996-至今",
// tag: "人工智能"
// },
// {
// type: "科技法案",
// title: "芯片与科学法案",
// content: "落实情况:正在实施,效果待观察。",
// time: "2022-至今",
// tag: "人工智能"
// },
// {
// type: "科技法案",
// title: "AI芯片出口管制",
// content: "落实情况:部分有效,但催生中国自主创新。",
// time: "1996-至今",
// tag: "人工智能"
// },
// {
// type: "科技法案",
// title: "瓦森纳安排",
// content: "落实情况:持续有效,但面临技术快速迭代挑战。",
// time: "1996-至今",
// tag: "人工智能"
// },
// {
// type: "科技法案",
// title: "瓦森纳安排",
// content: "落实情况:持续有效,但面临技术快速迭代挑战。",
// time: "1996-至今",
// tag: "人工智能"
// }
]);
watch(
......@@ -411,7 +392,6 @@ watch(
);
onMounted(() => {
handleGetCompanyListByArea();
handleGetChart1Data();
handleGetHylyList();
handleGetAction();
......@@ -529,6 +509,10 @@ onMounted(() => {
border-bottom: 1px solid rgba(234, 236, 238, 1);
border-radius: 4px;
display: flex;
cursor: pointer;
&:hover {
background: var(--color-bg-hover);
}
.id {
width: 24px;
height: 24px;
......
......@@ -31,7 +31,12 @@ const getBarChart = (nameList, valueList) => {
show: false
},
axisLabel: {
show: true
show: true,
textStyle: {
fontSize: 16,
fontFamily: 'Microsoft YaHei',
color: 'rgba(59, 65, 75, 1)'
}
}
},
series: [{
......
......@@ -126,12 +126,12 @@ const handleClickBox1Btn = btn => {
};
const backgroundListNum = ref(0);
const backgroundList = ref([
{
content: "认为人工智能(AI)是一项将决定未来几十年经济增长、国家安全和全球竞争力的基础性技术"
},
{
content: "要求美国不仅必须在开发通用和前沿AI能力方面领先,还必须确保美国的人工智能技术、标准和治理模式在全球范围内被采用"
},
// {
// content: "认为人工智能(AI)是一项将决定未来几十年经济增长、国家安全和全球竞争力的基础性技术"
// },
// {
// content: "要求美国不仅必须在开发通用和前沿AI能力方面领先,还必须确保美国的人工智能技术、标准和治理模式在全球范围内被采用"
// },
]);
const handleGetBackground = async () => {
const params = {
......@@ -155,39 +155,14 @@ const handleGetBackground = async () => {
// 相关事件
const relatedEvents = ref([
{
image: Img1,
title: "中美AI模型性能差距迅速缩小",
content:
"斯坦福大学《2025年人工智能指数报告》显示,中美顶尖AI模型在MMLU(大规模多任务语言理解)等主流基准测试中的性能...",
time: "2025-08-30"
},
{
image: Img2,
title: "中国模型以更低成本实现高性能",
content: "2025年1月,中国公司深度求索(DeepSeek)发布高性能AI推理模型R1,以其极低的训练成本和媲美顶级模型的推理能力受...",
time: "2025-05-16"
},
{
image: Img3,
title: "美国发布《赢得AI竞赛:美国AI行动计划》​",
content:
"特朗普政府发布该计划,核心包括加速创新​(解除监管)、建设AI基础设施​(加速数据中心审批、保障能源供应)和引领国际...",
time: "2025-07-23"
},
{
image: Img4,
title: "中国深入推进“人工智能+”行动",
content: "中国国务院常务会议审议通过《关于深入实施“人工智能+”行动的意见》,大力推进AI在各领域的规模化商业化应用和和深...",
time: "2025-07-31"
},
{
image: Img5,
title: "美国对华AI芯片出口管制持续升级",
content:
"美国商务部宣布撤销拜登时期的《AI扩散规则》,要求全球使用美国技术的芯片厂商停止向中国出口AI芯片,直接影响英伟达...",
time: "2025-05-20"
}
// {
// image: Img1,
// title: "中美AI模型性能差距迅速缩小",
// content:
// "斯坦福大学《2025年人工智能指数报告》显示,中美顶尖AI模型在MMLU(大规模多任务语言理解)等主流基准测试中的性能...",
// time: "2025-08-30"
// }
]);
const handleGetRelateEvents = async () => {
const params = {
......@@ -215,34 +190,19 @@ const handleGetRelateEvents = async () => {
// 法律依据
const laws = ref([
{
name: "《美国法典》",
info: "第3编第301条",
content:
"允许总统通过行政命令(Executive Order)​​ 或其它书面形式授权行政部门或机构的负责人​(如国务卿、财政部长等)代行本属于总统的法定职能(由国会立法授予总统的职能)。"
},
{
name: "《出口管制改革法案》",
info: "",
content:
"该法案授权政府出于国家安全和外交政策目的对特定技术、商品和软件的出口进行管制。确保AI技术不流向“对手国家”是其题中应有之义。"
},
{
name: "《国际紧急经济权力法》",
info: "",
content:
"授予总统在应对“不寻常且极其严重的威胁”时,监管商业和金融交易的广泛权力,包括实施出口管制。这在以往的贸易和科技管制中常被引用。"
},
{
name: "《2019年通过外交捍卫美国商业法》",
info: "第708(c)(3)条",
content: "授权小企业管理局局长和OSTP主任任命其各自行政部门和机构的高级官员担任EDAG成员。"
},
{
name: "《关于安全、可靠和可信地开发和使用人工智能的行政命令》",
info: "",
content: "要求强大AI系统的开发者与政府共享安全测试结果,并为AI安全、隐私保护、公平权利及创新竞争等方面制定标准。"
}
// {
// name: "《美国法典》",
// info: "第3编第301条",
// content:
// "允许总统通过行政命令(Executive Order)​​ 或其它书面形式授权行政部门或机构的负责人​(如国务卿、财政部长等)代行本属于总统的法定职能(由国会立法授予总统的职能)。"
// },
// {
// name: "《出口管制改革法案》",
// info: "",
// content:
// "该法案授权政府出于国家安全和外交政策目的对特定技术、商品和软件的出口进行管制。确保AI技术不流向“对手国家”是其题中应有之义。"
// }
]);
const handleGetLaws = async () => {
const params = {
......
......@@ -127,7 +127,7 @@
<div class="box3-top">
<div class="box3-top-top">
<div class="left">
<img :src="box3TopData.logo" alt="" />
<img :src="box3TopData.logo?box3TopData.logo:DefaultIcon2" alt="" />
</div>
<div class="right">
<div class="name">{{ box3TopData.name }}</div>
......@@ -147,13 +147,6 @@
<div class="item-left">{{ "成立时间:" }}</div>
<div class="item-right">{{ box3TopData.clsj }}</div>
</div>
<div class="main-item">
<div class="item-icon"></div>
<div class="item-left">{{ "主要职责:" }}</div>
<div class="item-right">
{{ box3TopData.zyzz }}
</div>
</div>
<div class="main-item">
<div class="item-icon"></div>
<div class="item-left">{{ "总部地址:" }}</div>
......@@ -206,20 +199,23 @@ import box1Img from "./assets/images/box1-img.png";
import Box3Logo from "./assets/images/box3-img.png";
import { getDecreeBasicInfo, getDecreeMainContent, getDecreeOrganization } from "@/api/decree/introduction";
import DefaultIcon1 from '@/assets/icons/default-icon1.png'
import DefaultIcon2 from '@/assets/icons/default-icon2.png'
const route = useRoute();
const decreeId = ref(route.query.id);
// 基本信息
const basicInfo = ref({
img: box1Img,
name: "推动美国人工智能技术栈出口",
eName: "Promoting the Export of the American AI Technology Stack",
areaList: ["人工智能", "出口管制", "半导体产业", "关税", "光伏产业"],
signTime: "2025年7月23日",
signPeople: "唐纳德·约翰·特朗普(Donald John Trump)",
bh: "第14320号行政命令 (EO 14320)",
deadline: "签署后90天内建立机制并开始实施"
img: "",
name: "",
eName: "",
areaList: [],
signTime: "",
signPeople: "",
bh: "",
deadline: ""
});
const handleGetBasicInfo = async () => {
......@@ -246,10 +242,10 @@ handleGetBasicInfo();
// 主要指令
const majorList = ref([
{
id: 1,
content: '要求商务部在90天内建立"全栈式"美国AI出口机制。'
}
// {
// id: 1,
// content: '要求商务部在90天内建立"全栈式"美国AI出口机制。'
// }
]);
const currentPage = ref(1);
const pageSize = ref(5);
......@@ -285,8 +281,8 @@ const handleMajorList = async () => {
handleMajorList();
// 执行机构
const box3BtnList = ref(["商务部", "经济外交行动组"]);
const box3ActiveBtn = ref("商务部");
const box3BtnList = ref([]);
const box3ActiveBtn = ref("");
const box3BtnActiveIndex = ref(0);
const handleClickBox3Btn = (btn, index) => {
box3ActiveBtn.value = btn;
......@@ -296,7 +292,6 @@ const handleClickBox3Btn = (btn, index) => {
box3TopData.value.name = box3Data.value[index].name;
box3TopData.value.eName = box3Data.value[index].ename;
box3TopData.value.clsj = box3Data.value[index].foundingDate;
box3TopData.value.zyzz = "暂无数据";
box3TopData.value.zbdz = box3Data.value[index].address;
box3TopData.value.bz = box3Data.value[index].leaderName;
eventList.value = box3Data.value[index].newsList.map(val => {
......@@ -310,32 +305,29 @@ const handleClickBox3Btn = (btn, index) => {
const box3Data = ref([]);
const box3TopData = ref({
logo: Box3Logo,
name: "美国商务部",
eName: "United States Department of Commerce",
clsj: "1903年2月14日",
zbdz: "华盛顿宪法大道1401号胡佛大楼",
bz: "霍华德·卢特尼克"
logo: "",
name: "",
eName: "",
clsj: "",
zbdz: "",
bz: ""
});
// 机构动态
const eventList = ref([
{
time: "2025-07-31",
title: "美商务部发布指南,警告全球企业使用华为昇腾芯片可能违反美国出口管制。意在限制中国AI产业发展,阻碍其获得先进算力。"
},
{
time: "2025-07-25",
title: "美商务部持续对多种中国产品发起“双反”(反倾销、反补贴)调查并作出裁决,涉及产品从工业原料到日常用品,且裁定的税率普遍较高。"
},
{
time: "2025-07-21",
title: "美商务部进一步收紧对华先进半导体出口管制,将更多中国实体列入“实体清单”。限制14纳米及以下先进芯片、DRAM等对华出口"
},
{
time: "2025-07-12",
title: "美商务部发起第三次反倾销和反补贴日落复审调查。"
}
// {
// time: "2025-07-31",
// title: "美商务部发布指南,警告全球企业使用华为昇腾芯片可能违反美国出口管制。意在限制中国AI产业发展,阻碍其获得先进算力。"
// },
// {
// time: "2025-07-25",
// title: "美商务部持续对多种中国产品发起“双反”(反倾销、反补贴)调查并作出裁决,涉及产品从工业原料到日常用品,且裁定的税率普遍较高。"
// },
// {
// time: "2025-07-21",
// title: "美商务部进一步收紧对华先进半导体出口管制,将更多中国实体列入“实体清单”。限制14纳米及以下先进芯片、DRAM等对华出口"
// }
]);
const handleGetOrgnization = async () => {
......@@ -356,6 +348,7 @@ const handleGetOrgnization = async () => {
box3TopData.value.clsj = res.data[0].foundingDate;
box3TopData.value.zbdz = res.data[0].address;
box3TopData.value.bz = res.data[0].leaderName;
box3ActiveBtn.value = res.data[0].name;
eventList.value = res.data[0].newsList.map(val => {
return {
time: val.newsDate,
......
......@@ -177,7 +177,7 @@ export default {
/* 向上节点:线往下伸 */
.dot.up::after {
bottom: 100%;
height: 180px;
height: 165px;
/* 圆环底部 → 卡片顶 */
}
......@@ -185,15 +185,15 @@ export default {
.dot.down::after {
top: 100%;
height: 180px;
height: 165px;
}
.card {
position: absolute;
height: 180px;
width:320px;
height: 165px;
width: 320px;
padding: 8px 12px;
text-align: left;
cursor: pointer;
......@@ -208,6 +208,7 @@ export default {
line-height: 26px;
letter-spacing: 0px;
text-align: justify;
margin-bottom: 10px;
}
.title {
......@@ -218,6 +219,7 @@ export default {
line-height: 26px;
letter-spacing: 0px;
text-align: justify;
margin-bottom: 10px;
}
.content {
......
......@@ -52,27 +52,20 @@
}}
</div>
</div>
<img
class="item-card-content-title-image"
:src="organizationNews[organizationNewsShow].image"
alt=""
/>
<img class="item-card-content-title-image" :src="organizationNews[organizationNewsShow].image"
alt="" />
</div>
<div class="item-header-divider"></div>
<div class="item-card-content-text">
{{ organizationNews[organizationNewsShow].content }}
</div>
<div style="display: flex; margin-top: 30px">
<div
class="item-card-content-tag"
v-for="(tag, index) in organizationNews[organizationNewsShow].tag"
:key="index"
:style="{
<div class="item-card-content-tag" v-for="(tag, index) in organizationNews[organizationNewsShow].tag"
:key="index" :style="{
color: tag.textColor,
background: tag.color,
border: `1px solid ${tag.textColor}`
}"
>
}">
{{ tag.text }}
</div>
</div>
......@@ -114,13 +107,10 @@
<div style="padding: 30px 23px; height: 400px">
<div class="waring-item" v-for="(item, index) in warningList" :key="index">
<div style="display: flex; height: 47px">
<div
class="waring-status"
:style="{
color: item.status === 0 ? '#CE4F51' : item.status === 1 ? '#FA8C16' : '#52C41A',
backgroundColor: item.status === 0 ? '#FFF1F0' : item.status === 1 ? '#FFF7E6' : '#F6FFED'
}"
>
<div class="waring-status" :style="{
color: item.status === 0 ? '#CE4F51' : item.status === 1 ? '#FA8C16' : '#52C41A',
backgroundColor: item.status === 0 ? '#FFF1F0' : item.status === 1 ? '#FFF7E6' : '#F6FFED'
}">
{{ item.status === 0 ? "特别重大" : item.status === 1 ? "重大风险" : "一般风险" }}
</div>
<div class="waring-text">
......@@ -424,7 +414,7 @@ function changeOrganizationNews(type) {
: (organizationNewsShow.value = organizationNewsShow.value + 1);
}
}
onMounted(() => {});
onMounted(() => { });
</script>
<style lang="scss" scoped>
......@@ -450,6 +440,7 @@ onMounted(() => {});
box-sizing: border-box;
padding-left: 160px;
position: relative;
.header-search-box {
position: absolute;
top: 14px;
......@@ -457,6 +448,7 @@ onMounted(() => {});
display: flex;
gap: 12px;
justify-content: flex-end;
.header-search-left {
width: 360px;
height: 36px;
......@@ -464,18 +456,22 @@ onMounted(() => {});
border-radius: 4px;
background: rgba(255, 255, 255, 0.3);
display: flex;
.input-box {
width: 324px;
}
.icon {
width: 36px;
height: 36px;
img {
width: 100%;
height: 100%;
}
}
}
.header-search-right {
width: 36px;
height: 36px;
......@@ -483,10 +479,12 @@ onMounted(() => {});
border-radius: 4px;
background: rgba(255, 255, 255, 0.3);
cursor: pointer;
.header-img-box {
width: 19px;
height: 24px;
margin: 4px auto;
img {
width: 100%;
height: 100%;
......@@ -590,6 +588,7 @@ onMounted(() => {});
font-size: 14px;
}
}
.item-header-text-1 {
// width: 150px;
height: 48px;
......@@ -641,7 +640,7 @@ onMounted(() => {});
}
.item-card-content-tag {
width: 74px;
width: 76px;
height: 24px;
padding: 1px 8px 1px 8px;
margin: 2px;
......@@ -682,7 +681,7 @@ onMounted(() => {});
.item-card-content {
height: 100%;
width: calc(100% - 50px);
width: 454px;
padding: 20px;
.item-card-content-header {
......@@ -1002,10 +1001,12 @@ onMounted(() => {});
}
}
}
:deep(.el-input__wrapper) {
box-shadow: none;
background: none;
}
:deep(.el-input__wrapper:hover) {
box-shadow: none !important;
}
......@@ -1013,6 +1014,7 @@ onMounted(() => {});
:deep(.el-input__wrapper.is-focus) {
box-shadow: none !important;
}
:deep(.el-input__inner::placeholder) {
color: rgba(132, 136, 142, 1);
font-family: Microsoft YaHei;
......
......@@ -63,10 +63,10 @@
</div>
</div>
</div>
<div class="main">
<ReportAnalysis v-if="tabActiveName === '报告分析'"></ReportAnalysis>
<div class="main">
<ReportAnalysis v-if="tabActiveName === '报告分析'"></ReportAnalysis>
<PolicyTracking v-else></PolicyTracking>
</div>
</div>
</div>
</template>
......@@ -86,7 +86,8 @@ const switchTab = name => {
<style lang="scss" scoped>
.wrap {
width: 1920px;
height: 984px;
// height: 984px;
.header {
width: 1920px;
height: 188px;
......@@ -95,12 +96,14 @@ const switchTab = name => {
border-top: 1px solid rgba(234, 236, 238, 1);
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background: rgba(255, 255, 255, 1);
.header-top {
margin-top: 20px;
margin-left: 248px;
display: flex;
justify-content: space-between;
margin-right: 160px;
.header-top-left {
.title {
height: 26px;
......@@ -112,6 +115,7 @@ const switchTab = name => {
letter-spacing: 0px;
text-align: left;
}
.en-title {
height: 24px;
color: rgba(95, 101, 108, 1);
......@@ -122,10 +126,12 @@ const switchTab = name => {
letter-spacing: 0px;
text-align: left;
}
.tag-box {
margin-top: 11px;
display: flex;
gap: 8px;
.tag {
height: 26px;
padding: 0 8px;
......@@ -143,6 +149,7 @@ const switchTab = name => {
}
}
}
.header-top-right {
.name {
height: 24px;
......@@ -154,6 +161,7 @@ const switchTab = name => {
letter-spacing: 0px;
text-align: right;
}
.time {
height: 24px;
margin-top: 5px;
......@@ -167,6 +175,7 @@ const switchTab = name => {
}
}
}
.header-bottom {
margin: 0 auto;
margin-top: 30px;
......@@ -174,13 +183,15 @@ const switchTab = name => {
height: 48px;
display: flex;
justify-content: space-between;
.tab-box {
width: 224px;
height: 48px;
display: flex;
gap: 24px;
.tab {
width: 92px;
width: 94px;
height: 48px;
display: flex;
align-items: center;
......@@ -188,14 +199,17 @@ const switchTab = name => {
gap: 4px;
cursor: pointer;
border-bottom: 2px solid transparent;
.icon {
width: 16px;
height: 16px;
img {
width: 100%;
height: 100%;
}
}
.text {
height: 24px;
color: rgba(59, 65, 75, 1);
......@@ -204,18 +218,22 @@ const switchTab = name => {
font-weight: 400;
line-height: 24px;
}
.textActive {
color: rgba(5, 95, 194, 1);
font-weight: 700;
}
}
.tabActive {
border-bottom: 2px solid rgba(5, 95, 194, 1);
}
}
.btn-box {
display: flex;
gap: 12px;
.btn {
width: 120px;
height: 36px;
......@@ -227,16 +245,19 @@ const switchTab = name => {
align-items: center;
justify-content: center;
gap: 8px;
.icon {
width: 16px;
height: 16px;
img {
width: 100%;
height: 100%;
}
}
.text {
width: 64px;
width: 66px;
height: 22px;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
......@@ -247,18 +268,21 @@ const switchTab = name => {
text-align: center;
}
}
.btn1 {
border-radius: 6px;
background: var(--color-main-active);
.text{
color: rgba(255,255,255,1);
}
.text {
color: rgba(255, 255, 255, 1);
}
}
}
}
}
.main{
width: 100%;
}
.main {
width: 100%;
}
}
</style>
\ No newline at end of file
......@@ -17,10 +17,10 @@
<div class="box1-main">
<div class="box1-item" v-for="(item, index) in box1Data" :key="index">
<div class="left">
{{ item.id }}
{{ index + 1 }}
</div>
<div class="center">
<div class="title">{{ item.title }}</div>
<div class="title">{{ item.content }}</div>
<div class="tag-box">
<div class="tag" v-for="(val, idx) in item.tagList" :key="idx">
{{ val }}
......@@ -28,8 +28,15 @@
</div>
<div class="file-box">
<div class="file-item" v-for="(vall, idxx) in item.fileList" :key="idxx">
<div class="file-item-left">{{ vall.type }}</div>
<div class="file-item-center">{{ vall.name }}</div>
<div class="file-item-left">法案</div>
<div class="file-item-center">{{ vall.relationBillsList }}</div>
<div class="file-item-right">
<img src="@/assets/images/icon-right-circle.png" alt="" />
</div>
</div>
<div class="file-item" v-for="(vall, idxx) in item.fileList" :key="idxx">
<div class="file-item-left">政令</div>
<div class="file-item-center">{{ vall.relationAdList }}</div>
<div class="file-item-right">
<img src="@/assets/images/icon-right-circle.png" alt="" />
</div>
......@@ -46,14 +53,7 @@
</div>
</div>
</div>
<div class="box1-footer">
<div class="info">
{{ `共105项调查` }}
</div>
<div class="page-box">
<el-pagination :page-size="10" background layout="prev, pager, next" :total="120" />
</div>
</div>
</div>
</div>
......@@ -79,13 +79,13 @@
<div class="line" v-if="index < 5"></div>
</div>
<div class="box2-item-center">
<div class="title">{{ item.title }}</div>
<div class="content">{{ item.content }}</div>
<div class="title">{{ item.sjbt }}</div>
<div class="content">{{ item.sjnr }}</div>
</div>
<div class="box2-item-right">
<div class="time">{{ item.time }}</div>
<div class="img-box">
<img :src="item.img" alt="" />
<img :src="item.imageUrl" alt="" />
</div>
</div>
</div>
......@@ -102,7 +102,12 @@
<script setup>
import { ref, onMounted } from "vue";
import {
getThinkTankReportPolicy,
getThinkTankReportPolicyAction
} from "@/api/thinkTank/overview";
import { useRouter } from "vue-router";
const router = useRouter();
// 政策建议落实情况
const box1Data = ref([
{
......@@ -257,6 +262,19 @@ const box1Data = ref([
}
]);
const handleGetThinkTankReportPolicy = async () => {
try {
const res = await getThinkTankReportPolicy(router.currentRoute._value.params.id);
console.log("政策建议落实情况", res);
if (res.code === 200 && res.data) {
box1Data.value = res.data
}
} catch (error) {
console.error("获取政策建议落实情况rror", error);
}
};
// 相关政策动态
const box2Data = ref([
{
......@@ -296,6 +314,24 @@ const box2Data = ref([
img: 1
}
]);
const handleGetThinkTankReportPolicyAction = async () => {
try {
const res = await getThinkTankReportPolicyAction(router.currentRoute._value.params.id);
console.log("相关政策动态", res);
if (res.code === 200 && res.data) {
box2Data.value = res.data
}
} catch (error) {
console.error("获取相关政策动态rror", error);
}
};
onMounted(async () => {
handleGetThinkTankReportPolicy()
handleGetThinkTankReportPolicyAction()
});
</script>
<style lang="scss" scoped>
......@@ -303,11 +339,14 @@ const box2Data = ref([
display: flex;
justify-content: center;
gap: 16px;
height: 100%;
.box-header {
width: 100%;
height: 50px;
display: flex;
position: relative;
.header-left {
margin-top: 18px;
width: 8px;
......@@ -315,6 +354,7 @@ const box2Data = ref([
border-radius: 0 4px 4px 0;
background: var(--color-main-active);
}
.title {
margin-left: 14px;
margin-top: 14px;
......@@ -325,6 +365,7 @@ const box2Data = ref([
font-size: 20px;
font-weight: 700;
}
.header-btn-box {
position: absolute;
top: 15px;
......@@ -332,6 +373,7 @@ const box2Data = ref([
display: flex;
justify-content: flex-end;
gap: 8px;
.btn {
height: 28px;
padding: 0 8px;
......@@ -345,11 +387,13 @@ const box2Data = ref([
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;
......@@ -357,9 +401,11 @@ const box2Data = ref([
display: flex;
justify-content: flex-end;
gap: 4px;
.icon {
width: 28px;
height: 28px;
img {
width: 100%;
height: 100%;
......@@ -367,26 +413,33 @@ const box2Data = ref([
}
}
}
.left {
height: 1442px;
height: 100%;
.box1 {
margin-top: 16px;
width: 1104px;
height: 1405px;
height: 100%;
margin-bottom: 16px;
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 {
width: 1056px;
height: 1280px;
margin: 0 auto;
overflow: hidden;
overflow-y: auto;
.box1-item {
height: 128px;
border-bottom: 1px solid rgba(234, 236, 238, 1);
display: flex;
position: relative;
.left {
width: 28px;
height: 28px;
......@@ -402,8 +455,11 @@ const box2Data = ref([
font-weight: 400;
letter-spacing: 0px;
}
.center {
width: 850px;
margin-left: 18px;
.title {
margin-top: 16px;
height: 24px;
......@@ -415,10 +471,12 @@ const box2Data = ref([
letter-spacing: 0px;
text-align: left;
}
.tag-box {
display: flex;
margin-top: 7px;
gap: 8px;
.tag {
height: 22px;
padding: 0 8px;
......@@ -435,10 +493,12 @@ const box2Data = ref([
text-align: left;
}
}
.file-box {
margin-top: 7px;
display: flex;
gap: 8px;
.file-item {
height: 32px;
padding: 0 8px;
......@@ -446,6 +506,7 @@ const box2Data = ref([
background: rgba(246, 250, 255, 1);
display: flex;
align-items: center;
.file-item-left {
height: 22px;
padding: 0 4px;
......@@ -460,6 +521,7 @@ const box2Data = ref([
letter-spacing: 0px;
text-align: left;
}
.file-item-center {
margin-left: 12px;
color: var(--color-main-active);
......@@ -470,10 +532,12 @@ const box2Data = ref([
letter-spacing: 0px;
text-align: left;
}
.file-item-right {
margin-left: 12px;
width: 20px;
height: 20px;
img {
width: 100%;
height: 100%;
......@@ -482,6 +546,7 @@ const box2Data = ref([
}
}
}
.right {
position: absolute;
top: 16px;
......@@ -491,6 +556,7 @@ const box2Data = ref([
justify-content: flex-end;
align-items: center;
gap: 9px;
.text {
height: 24px;
font-family: Microsoft YaHei;
......@@ -501,9 +567,11 @@ const box2Data = ref([
letter-spacing: 0px;
text-align: right;
}
.icon {
width: 16px;
height: 16px;
img {
width: 100%;
height: 100%;
......@@ -512,12 +580,14 @@ const box2Data = ref([
}
}
}
.box1-footer {
height: 50px;
display: flex;
justify-content: space-between;
box-sizing: border-box;
padding: 20px;
.info {
color: rgba(132, 136, 142, 1);
font-family: Microsoft YaHei;
......@@ -539,24 +609,30 @@ const box2Data = ref([
border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background: rgba(255, 255, 255, 1);
.box2-main {
margin: 0 auto;
margin-top: 15px;
width: 459px;
height: 654px;
overflow: hidden;
.box2-item {
height: 109px;
display: flex;
.box2-item-left {
.point {
margin-left: 14px;
width: 10px;
height: 10px;
img {
width: 100%;
height: 100%;
}
}
.line {
width: 2px;
height: 109px;
......@@ -564,8 +640,10 @@ const box2Data = ref([
margin-left: 18px;
}
}
.box2-item-center {
margin-left: 11px;
.title {
width: 314px;
height: 24px;
......@@ -580,6 +658,7 @@ const box2Data = ref([
text-overflow: ellipsis;
white-space: nowrap;
}
.content {
width: 314px;
height: 48px;
......@@ -593,8 +672,10 @@ const box2Data = ref([
overflow: hidden;
}
}
.box2-item-right {
margin-left: 18px;
.time {
height: 22px;
color: rgba(95, 101, 108, 1);
......@@ -608,11 +689,13 @@ const box2Data = ref([
text-overflow: ellipsis;
white-space: nowrap;
}
.img-box {
margin-top: 14px;
width: 78px;
height: 50px;
border-radius: 2px;
img {
width: 100%;
height: 100%;
......@@ -621,6 +704,7 @@ const box2Data = ref([
}
}
}
.box2-footer {
margin: 10px auto;
width: 108px;
......@@ -630,9 +714,11 @@ const box2Data = ref([
justify-content: center;
gap: 4px;
cursor: pointer;
&:hover {
background: var(--color-bg-hover);
}
.text {
color: var(--color-main-active);
height: 22px;
......@@ -642,9 +728,11 @@ const box2Data = ref([
line-height: 22px;
letter-spacing: 0px;
}
.icon {
width: 16px;
height: 16px;
img {
width: 100%;
height: 100%;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论