提交 1a8ab6e3 authored 作者: yanpeng's avatar yanpeng

merge

......@@ -129,3 +129,42 @@ export function getSupplyList(params) {
params,
})
}
// 企业市值:市值变化
export function getMarketCapList(params) {
return request({
method: 'GET',
url: `/api/enterprisePage/marketCap/${params}`,
})
}
// 企业发展:营收折线图
export function getRevenueList(params) {
return request({
method: 'GET',
url: `/api/enterprisePage/revenue/${params}`,
})
}
// 企业发展:净利润折线图
export function getNetProfitList(params) {
return request({
method: 'GET',
url: `/api/enterprisePage/netProfit/${params}`,
})
}
// 企业发展:人员情况折线图
export function getPersonnelList(params) {
return request({
method: 'GET',
url: `/api/enterprisePage/personnel/${params}`,
})
}
// 企业发展: 市场占比折线图
export function getMarketShareList(params) {
return request({
method: 'GET',
url: `/api/enterprisePage/marketShare/${params}`,
})
}
\ No newline at end of file
......@@ -222,9 +222,14 @@ export function getThinkTankReportAbstract(params) {
//获取报告主要观点
export function getThinkTankReportContent(params) {
const { id, currentPage, pageSize } = params
return request({
method: 'GET',
url: `/api/thinkTankReport/content/${params}`,
url: `/api/thinkTankReport/content/${id}`,
params: {
currentPage,
pageSize,
}
})
}
......
......@@ -10,23 +10,20 @@
</div>
</div>
<div class="box3-main">
<div class="box3-item" v-for="(news, index) in list" :key="index" @click="handleClickToNewsDetail(news)">
<div class="box3-item" v-for="(news, index) in normalizedList" :key="index"
@click="handleClickToNewsDetail(news)">
<div class="left">
<img
:src="getProxyUrl(news.newsImage) || defaultImg"
alt=""
referrerpolicy="no-referrer"
@error="e => (e.target.src = errImg||News1)"
/>
<img :src="getProxyUrl(news.newsImage) || defaultImg" alt="" referrerpolicy="no-referrer"
@error="e => (e.target.src = errImg || News1)" />
</div>
<div class="right">
<div class="right-top">
<div class="title">{{ news.newsTitle||news.title }}</div>
<div class="title">{{ news.newsTitle || news.title }}</div>
<div class="time">
{{ news.newsDate ? news.newsDate.slice(5) : "" }} {{ news.newsOrg ? "-" + news.newsOrg : "" }}
</div>
</div>
<div class="right-footer">{{ news.newsContent||news.description }}</div>
<div class="right-footer">{{ news.newsContent || news.description }}</div>
</div>
</div>
</div>
......@@ -34,15 +31,21 @@
</template>
<script setup>
import { computed } from "vue";
import router from "@/router/index";
import News1 from "@/assets/images/news1.png"; // 错误图片
import defaultNew from "@/assets/images/default-icon-news.png"; // 默认图片
let { list,errImg,defaultImg } = defineProps({
let { list, newsList, errImg, defaultImg } = defineProps({
list: {
type: Array,
default: () => []
},
// 兼容历史用法:部分页面使用 newsList 作为入参
newsList: {
type: Array,
default: undefined
},
defaultImg: {
type: String,
default: defaultNew
......@@ -53,6 +56,11 @@ let { list,errImg,defaultImg } = defineProps({
}
});
// 统一对外渲染数据源:优先使用 list,其次兼容 newsList
const normalizedList = computed(() => {
return (Array.isArray(list) && list.length ? list : newsList) || [];
});
// 处理图片代理
const getProxyUrl = url => {
if (!url) return "";
......@@ -74,7 +82,7 @@ const handleClickToNewsDetail = news => {
const route = router.resolve({
path: "/newsAnalysis",
query: {
newsId: news.newsId
newsId: news.newsId ?? news.id
}
});
window.open(route.href, "_blank");
......@@ -183,9 +191,11 @@ const handleToMoreNews = () => {
width: 657px;
display: flex;
justify-content: space-between;
&:hover {
text-decoration: underline;
color: var(--color-main-active);
.title {
color: var(--color-main-active);
}
......
......@@ -67,7 +67,7 @@ const handleCollect = () => {
}
const emit = defineEmits(['save','download','collect'])
const emit = defineEmits(['save', 'download', 'collect'])
</script>
......
//样式主页
const StylePages = () => import("@/components/devStyle/components/index.vue");
const StylePages = () => import("@/styles/components/index.vue");
const stylePagesRoutes = [
// 智库系统的主要路由
......
<script setup lang="ts">
import { ElRow, ElCol } from 'element-plus';
import '@/styles/common.scss'
const span = 12
</script>
<template>
<el-row class="wrapper">
<el-col :span="span">
<pre>
{{ `import '@/styles/common.scss';
<template>
<div class="background-as-card"></div>
</template>
`}}
</pre>
<div class="background-as-card">
<div v-for="item in [1, 2, 3, 4]" :key="item">
{{ item }}
</div>
</div>
</el-col>
</el-row>
</template>
<style lang="scss" scoped>
.wrapper {
background-color: rgba(0, 0, 0, 0.068);
padding: 10px;
}
</style>
\ No newline at end of file
<script setup lang="ts">
import { ElRadioGroup, ElRadioButton, ElRow, ElCol } from 'element-plus';
import { ref } from 'vue';
import '@/styles/radio.scss';
const radio = ref(1)
const span = 12
</script>
<template>
<el-row>
<el-col :span="span">
<pre>
{{ `import '@/styles/radio.scss';
<template>
<el-radio-group class="radio-group-as-gap-btn">
</el-radio-group>
</template>
`}}
</pre>
<el-radio-group v-model="radio" class="radio-group-as-gap-btn">
<el-radio-button :value="1">选项1</el-radio-button>
<el-radio-button :value="2">选项2</el-radio-button>
<el-radio-button :value="3">选项3</el-radio-button>
</el-radio-group>
</el-col>
</el-row>
</template>
<style lang="scss" scoped></style>
\ No newline at end of file
<script setup lang="ts">
import { ElTabs, ElTabPane, ElSpace, ElRow, ElCol } from 'element-plus';
import { ref } from 'vue';
import '@/styles/tabs.scss'
const span = 12
</script>
<template>
<el-row>
<el-col :span="span">
<pre>
{{ `import '@/styles/tabs.scss';
<template>
<el-tabs stretch class="tabs-header-as-card tabs-nav-no-wrap tabs-bar-as-btn">
</el-tabs>
</template>
`}}
</pre>
<el-tabs stretch class="tabs-header-as-card tabs-nav-no-wrap tabs-bar-as-btn">
<el-tab-pane label="tab1">tab1</el-tab-pane>
<el-tab-pane label="tab2">tab2</el-tab-pane>
<el-tab-pane label="tab3">tab3</el-tab-pane>
</el-tabs>
</el-col>
</el-row>
</template>
<style lang="scss" scoped></style>
\ No newline at end of file
<template>
<el-scrollbar>
<div class="common-page">
<el-space direction="vertical" :size="20" alignment="flex-start">
<el-space direction="vertical" :size="20" alignment="flex-start" fill>
<div class="text-title-0-show">开发样式</div>
<div class="text-title-1-show">样式变量</div>
<ConstStyle />
<div class="text-title-1-show">文字样式</div>
<TextStyle />
<div class="text-title-1-show">通用样式/组件</div>
<el-tabs tabPosition="left">
<el-tab-pane label="通用" lazy>
<common-page />
</el-tab-pane>
<el-tab-pane label="单选框" lazy>
<radio-page />
</el-tab-pane>
<el-tab-pane label="选项卡" lazy>
<tabs-page />
</el-tab-pane>
</el-tabs>
</el-space>
</div>
</el-scrollbar>
......@@ -16,5 +28,10 @@
import "@/styles/container.scss"
import TextStyle from './textStyle.vue';
import ConstStyle from './constStyle.vue';
import { ElTabs, ElTabPane, ElSpace } from "element-plus";
import RadioPage from './RadioPage/index.vue';
import TabsPage from './TabsPage/index.vue';
import CommonPage from './CommonPage/index.vue';
</script>
<style lang="scss" scoped></style>
\ No newline at end of file
@use '@/styles/common.scss';
.radio-group-as-gap-btn {
@extend .text-tip-1;
.el-radio-button {
--el-radio-button-checked-bg-color: var(--bg-white-100);
--el-radio-button-checked-border-color: var(--bg-black-10);
border-radius: 4px;
}
.el-radio-button.is-active {
--el-radio-button-checked-text-color: var(--color-primary-100);
--el-radio-button-checked-bg-color: var(--color-primary-10);
--el-radio-button-checked-border-color: var(--color-primary-5);
border-radius: 4px;
}
}
\ No newline at end of file
......@@ -148,11 +148,12 @@
</div>
</div> -->
<AnalysisBox title="政治献金流向">
<div class="box2-main">
<div class="box2-main" :class="{ 'box2-main-no-footer': !showHardcodedTips }">
<el-empty v-if="!fullSourceList.length" description="暂无数据" :image-size="100" />
<div v-else class="chart-box2" id="chart1"></div>
</div>
<div class="box-footer">
<!-- 该提示文案后续改为接口返回,当前按需求先隐藏展示 -->
<div v-if="showHardcodedTips" class="box-footer">
<div class="box-footer-left">
<img src="@/assets/icons/box-footer-left-icon.png" alt="" />
</div>
......@@ -210,7 +211,7 @@
</div>
</div> -->
<AnalysisBox title="政治献金领域分布">
<div class="box3-main">
<div class="box3-main" :class="{ 'box3-main-no-footer': !showHardcodedTips }">
<div class="box3-main-left" id="chart2"></div>
<div class="box3-main-right">
<el-empty v-if="!areaList.length" description="暂无数据" :image-size="100" />
......@@ -225,7 +226,8 @@
</div>
</div>
</div>
<div class="box-footer">
<!-- 该提示文案后续改为接口返回,当前按需求先隐藏展示 -->
<div v-if="showHardcodedTips" class="box-footer">
<div class="box-footer-left">
<img src="@/assets/icons/box-footer-left-icon.png" alt="" />
</div>
......@@ -271,6 +273,9 @@ import Mzd from "@/assets/icons/mzd.png";
const activeBtnIndex = ref(0);
const itemActiveIndex = ref(0);
// 写死提示文案先保留逻辑,默认不展示;后续接口完成后改为 true 或替换为接口控制
const showHardcodedTips = ref(false);
const currentPersonName = computed(() => {
if (mainPoliContribution.value && mainPoliContribution.value[itemActiveIndex.value]) {
return mainPoliContribution.value[itemActiveIndex.value].name;
......@@ -631,7 +636,7 @@ const renderSankeyChart = () => {
}
},
...sourceList.map((item, index) => ({
name: item.orgName,
name: item.orgNameZh,
value: item.amount,
itemStyle: {
color: sankeyColors[index % sankeyColors.length]
......@@ -640,7 +645,7 @@ const renderSankeyChart = () => {
];
const links = sourceList.map(item => ({
source: item.orgName,
source: item.orgNameZhZh,
target: personName,
value: item.amount
}));
......@@ -1104,6 +1109,14 @@ onMounted(() => {
margin: 0 auto;
margin-bottom: 9px;
&.box2-main-no-footer {
height: 351px;
.chart-box2 {
height: 351px;
}
}
.chart-box2 {
width: 1020px;
height: 302px;
......@@ -1128,6 +1141,10 @@ onMounted(() => {
margin-bottom: 9px;
display: flex;
&.box3-main-no-footer {
height: 349px;
}
.box3-main-left {
width: 492px;
}
......
......@@ -32,14 +32,14 @@
</div>
</div> -->
<AnalysisBox title="典型阶段耗时">
<div class="box1-main">
<div class="box1-main" :class="{ 'box1-main--full': !timeFooterText }">
<div class="box1-main-center" id="chart1"></div>
<div class="box1-main-footer">
<div v-if="timeFooterText" class="box1-main-footer">
<div class="box-footer-left">
<img src="@/assets/icons/box-footer-left-icon.png" alt="" />
</div>
<div class="box-footer-center">
从立法耗时角度分析,大而美法案从提交到签署仅39天,远快于历史同类法案(通常需6个月以上),立法速度极快。
{{ timeFooterText }}
</div>
<div class="box-footer-right">
<img src="../assets/icons/arrow-right.png" alt="" />
......@@ -80,15 +80,14 @@
</div>
</div> -->
<AnalysisBox title="修正案次数分析">
<div class="box2-main">
<div class="box2-main" :class="{ 'box2-main--full': !amendFooterText }">
<div class="box2-main-center" id="chart2"></div>
<div class="box2-main-footer">
<div v-if="amendFooterText" class="box2-main-footer">
<div class="box-footer-left">
<img src="@/assets/icons/box-footer-left-icon.png" alt="" />
</div>
<div class="box-footer-center">
法案本质是共和党与资本集团的深度联盟,共和党获超
​80%利益集团献金,以减税、松监管、军工扩张为核心回报。
{{ amendFooterText }}
</div>
<div class="box-footer-right">
<img src="../assets/icons/arrow-right.png" alt="" />
......@@ -367,7 +366,17 @@
</div>
</div> -->
<AnalysisBox title="投票分析">
<div class="box3-main">
<div class="vote-legend">
<div class="vote-legend-item">
<span class="vote-legend-dot agree"></span>
<span>赞成票</span>
</div>
<div class="vote-legend-item">
<span class="vote-legend-dot against"></span>
<span>反对票</span>
</div>
</div>
<div class="box3-main" :class="{ 'box3-main--full': !voteFooterText }">
<div class="box3-main-center">
<div class="box3-main-center-header">
<div class="box3-main-center-header-box1">立法阶段</div>
......@@ -658,12 +667,12 @@
</div> -->
</div>
</div>
<div class="box3-main-footer">
<div v-if="voteFooterText" class="box3-main-footer">
<div class="box-footer-left">
<img src="@/assets/icons/box-footer-left-icon.png" alt="" />
</div>
<div class="box-footer-center">
法案以218:214​(众议院)和51:50​(副总统决胜票)微弱优势强行通过,暴露两党极端对立、党内倒戈频发的特点。
{{ voteFooterText }}
</div>
<div class="box-footer-right">
<img src="../assets/icons/arrow-right.png" alt="" />
......@@ -881,6 +890,11 @@ const voteAnalysisList4 = ref([
}
]);
// 底部说明文案(接口预留,默认不展示)
const timeFooterText = ref("");
const amendFooterText = ref("");
const voteFooterText = ref("");
// 绘制echarts图表
const setChart = (option, chartId) => {
let chartDom = document.getElementById(chartId);
......@@ -1091,6 +1105,12 @@ onMounted(async () => {
.box1-main {
height: 368px;
&.box1-main--full {
.box1-main-center {
height: 340px;
}
}
.box1-main-center {
width: 792px;
height: 300px;
......@@ -1230,6 +1250,12 @@ onMounted(async () => {
.box2-main {
height: 359px;
&.box2-main--full {
.box2-main-center {
height: 340px;
}
}
.box2-main-center {
height: 300px;
margin: 0 5px;
......@@ -1345,7 +1371,7 @@ onMounted(async () => {
#chart2 {
position: relative;
width: 330px;
height: 300px;
height: 340px;
z-index: 0;
}
......@@ -1471,9 +1497,52 @@ onMounted(async () => {
.box3 {
width: 100%;
height: 100%;
position: relative;
.vote-legend {
position: absolute;
top: 15px;
left: 50%;
transform: translateX(-50%);
display: inline-flex;
align-items: center;
gap: 20px;
z-index: 2;
.vote-legend-item {
display: inline-flex;
align-items: center;
gap: 8px;
font-size: 14px;
color: rgba(95, 101, 108, 1);
line-height: 22px;
}
.vote-legend-dot {
display: inline-block;
width: 12px;
height: 12px;
border-radius: 50%;
&.agree {
background: rgb(33, 129, 57);
}
&.against {
background: rgb(206, 79, 81);
}
}
}
.box3-main {
height: 791px;
&.box3-main--full {
.box3-main-center {
height: 772px;
}
}
.box3-main-center {
height: 732px;
margin: 0 20px;
......@@ -1529,7 +1598,7 @@ onMounted(async () => {
}
.box3-main-center-content {
height: 682px;
height: 722px;
overflow-y: auto;
overflow-x: hidden;
......
......@@ -16,10 +16,10 @@
>
<div class="item-title">{{ item.actionTitle }}</div>
</el-tooltip>
<!-- <div class="right">
<div class="risk-tag" :class="item.riskClass">{{ item.riskText }}</div>
<div class="right">
<div v-if="item.riskText" class="risk-tag" :class="item.riskClass">{{ item.riskText }}</div>
<div class="arrow">></div>
</div> -->
</div>
</div>
</div>
......@@ -41,6 +41,27 @@ const RISK_CLASS_MAP = {
"低风险": "risk-low"
};
const normalizeRiskSignal = riskSignal => {
if (riskSignal === null || riskSignal === undefined) return "";
if (typeof riskSignal === "number" && Number.isFinite(riskSignal)) {
const idx = Math.max(0, Math.min(RISK_LEVELS.length - 1, Math.floor(riskSignal)));
return RISK_LEVELS[idx];
}
const text = String(riskSignal).trim();
if (!text) return "";
if (RISK_CLASS_MAP[text]) return text;
const numeric = Number(text);
if (Number.isFinite(numeric)) {
const idx = Math.max(0, Math.min(RISK_LEVELS.length - 1, Math.floor(numeric)));
return RISK_LEVELS[idx];
}
return text;
};
export default {
name: "SBillProgressList",
data() {
......@@ -81,7 +102,7 @@ export default {
formattedDate = `${dateObj.getMonth() + 1}${dateObj.getDate()}日`;
}
const riskText = RISK_LEVELS[Math.min(index, RISK_LEVELS.length - 1)];
const riskText = normalizeRiskSignal(item?.level);
const riskClass = RISK_CLASS_MAP[riskText] || "risk-low";
return {
......
<template>
<div class="temp-wrap">
<div class="left">
<div class="side">
<div class="side-box side-box-domain">
<AnalysisBox title="涉及领域" width="520px" height="415px">
<div :class="['right-box2-main', { 'right-box-main--full': !domainFooterText }]" id="chart2"></div>
<div v-if="domainFooterText" class="right-box2-footer">
<div class="right-box2-footer-left">
<img src="./assets/icons/right-icon1.png" alt="" />
</div>
<div class="right-box2-footer-center">
{{ domainFooterText }}
</div>
<div class="right-box2-footer-right">
<img src="./assets/icons/arrow-right.png" alt="" />
</div>
</div>
</AnalysisBox>
</div>
<div class="side-box side-box-limit">
<AnalysisBox title="限制手段" width="520px" height="415px">
<div :class="['right-box1-main', { 'right-box-main--full': !limitFooterText }]" id="chart1"></div>
<div v-if="limitFooterText" class="right-box1-footer">
<div class="right-box1-footer-left">
<img src="./assets/icons/right-icon1.png" alt="" />
</div>
<div class="right-box1-footer-center">
{{ limitFooterText }}
</div>
<div class="right-box1-footer-right">
<img src="./assets/icons/arrow-right.png" alt="" />
</div>
</div>
</AnalysisBox>
</div>
</div>
<div class="terms">
<!-- <div class="box-header">
<div class="box-header-left"></div>
<div class="box-header-title">主要条款</div>
......@@ -91,7 +125,7 @@
</div>
</div>
<div class="left-main">
<div class="left-main-item" v-for="(term, index) in mainTermsList" :key="index">
<div class="left-main-item" v-for="(term, index) in mainTermsList" :key="getTermKey(term, index)">
<div class="id">{{ (currentPage - 1) * pageSize + index + 1 }}</div>
<div class="info">
<div class="title">
......@@ -104,7 +138,7 @@
</div>
</div>
<div class="tags-box">
<div class="tag" v-for="(val, idx) in (term.hylyList || []).slice(0, 2)" :key="idx" :class="{
<div class="tag" v-for="(val, idx) in (term.hylyList || []).slice(0, 2)" :key="getTagKey(val, idx)" :class="{
tag1: val === '人工智能',
tag2: val === '新一代信息技术' || !['人工智能', '政治', '经济', '军事', '科技'].includes(val),
tag3: val === '政治',
......@@ -131,86 +165,6 @@
</div>
</AnalysisBox>
</div>
<div class="right">
<div class="right-box1">
<!-- <div class="box-header">
<div class="box-header-left"></div>
<div class="box-header-title">限制手段</div>
<div class="header-right">
<div class="icon">
<img src="@/assets/icons/box-header-icon1.png" alt="" />
</div>
<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="right-box1-main" id="chart1"></div>
<div class="right-box1-footer">
<div class="right-box1-footer-left">
<img src="./assets/icons/right-icon1.png" alt="" />
</div>
<div class="right-box1-footer-center">通过关税壁垒、技术脱钩、新能源打压、地缘捆绑遏制中国产业链发展</div>
<div class="right-box1-footer-right">
<img src="./assets/icons/arrow-right.png" alt="" />
</div>
</div> -->
<AnalysisBox title="限制手段">
<div class="right-box1-main" id="chart1"></div>
<div class="right-box1-footer">
<div class="right-box1-footer-left">
<img src="./assets/icons/right-icon1.png" alt="" />
</div>
<div class="right-box1-footer-center">通过关税壁垒、技术脱钩、新能源打压、地缘捆绑遏制中国产业链发展</div>
<div class="right-box1-footer-right">
<img src="./assets/icons/arrow-right.png" alt="" />
</div>
</div>
</AnalysisBox>
</div>
<div class="right-box2">
<!-- <div class="box-header">
<div class="box-header-left"></div>
<div class="box-header-title">涉及领域</div>
<div class="header-right">
<div class="icon">
<img src="@/assets/icons/box-header-icon1.png" alt="" />
</div>
<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="right-box2-main" id="chart2"></div>
<div class="right-box2-footer">
<div class="right-box2-footer-left">
<img src="./assets/icons/right-icon1.png" alt="" />
</div>
<div class="right-box2-footer-center">系统性挤压中国新能源、跨境电商及高端制造的在美生存空间。</div>
<div class="right-box2-footer-right">
<img src="./assets/icons/arrow-right.png" alt="" />
</div>
</div> -->
<AnalysisBox title="涉及领域">
<div class="right-box2-main" id="chart2"></div>
<div class="right-box2-footer">
<div class="right-box2-footer-left">
<img src="./assets/icons/right-icon1.png" alt="" />
</div>
<div class="right-box2-footer-center">系统性挤压中国新能源、跨境电商及高端制造的在美生存空间。</div>
<div class="right-box2-footer-right">
<img src="./assets/icons/arrow-right.png" alt="" />
</div>
</div>
</AnalysisBox>
</div>
</div>
</div>
</template>
......@@ -234,11 +188,21 @@ const pageSize = ref(10);
const total = ref(0);
const mainTermsList = ref([]);
const domainFooterText = ref("");
const limitFooterText = ref("");
const btnActiveIndex = ref(1);
const handleSelectBtn = index => {
btnActiveIndex.value = index;
};
const getTermKey = (term, index) => {
return term?.ywid ?? term?.id ?? term?.tkxh ?? index;
};
const getTagKey = (val, idx) => {
return `${val}-${idx}`;
};
const chart1Data = ref([]);
const chart1ColorList = ref(["#4096ff", "#b37feb", "#ff7875", "#85a5ff", "#69b1ff", "#ffc069", "#87e8de"]);
......@@ -478,8 +442,9 @@ onMounted(async () => {
}
}
.left {
.terms {
margin-top: 16px;
margin-left: 16px;
width: 1064px;
height: 845px;
.left-top {
......@@ -668,12 +633,16 @@ onMounted(async () => {
}
}
.right {
.side {
width: 520px;
margin-top: 16px;
margin-left: 16px;
.right-box1 {
.side-box {
width: 520px;
}
.side-box-limit {
margin-top: 15px;
width: 520px;
height: 415px;
.right-box1-main {
......@@ -682,6 +651,10 @@ onMounted(async () => {
padding: 16px;
}
.right-box-main--full {
height: 375px;
}
.right-box1-footer {
width: 493px;
height: 40px;
......@@ -735,8 +708,7 @@ onMounted(async () => {
}
}
.right-box2 {
margin-top: 15px;
.side-box-domain {
width: 520px;
height: 415px;
.right-box2-main {
......@@ -745,6 +717,10 @@ onMounted(async () => {
padding: 16px;
}
.right-box-main--full {
height: 375px;
}
.right-box2-footer {
width: 493px;
height: 40px;
......
......@@ -38,7 +38,7 @@
import AnalysisBox from '@/components/base/boxBackground/analysisBox.vue';
import { ref, watch } from 'vue';
import { getEnterpriseBranch, getEnterpriseKeyPerson } from '@/api/companyPages';
import PersonAvatar from '@/components/base/people/personAvatar.vue';
import PersonAvatar from '@/components/base/people/PersonAvatar.vue';
import { ElDescriptions, ElDescriptionsItem, ElDivider, ElImage, ElSpace } from 'element-plus';
import '@/styles/descriptions.scss'
......
<template>
<sanctions-situation :enterprise-info="enterpriseInfo" :line-data="lineData"></sanctions-situation>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { getNetProfitList, getPersonnelList, getRevenueList } from '@/api/companyPages';
import SanctionsSituation, { LineDataItem } from './SanctionsSituation.vue';
// 定义组件属性
const props = defineProps({
enterpriseInfo: {
type: Object,
default: {}
}
});
const lineData = ref<LineDataItem[]>([])
onMounted(async () => {
await intData()
})
async function intData() {
let { data: revenue } = await getRevenueList(props.enterpriseInfo.id)
revenue = revenue?.map(item => ({
time: new Date(item.year, 1, 1),
value: item.value,
type: '营收',
unit: item.unit ?? '亿元'
})) ?? []
let { data: netProfit } = await getNetProfitList(props.enterpriseInfo.id)
netProfit = netProfit?.map(item => ({
time: new Date(item.year, 1, 1),
value: item.value,
type: '净利润',
unit: item.unit ?? '亿元'
})) ?? []
let { data: personnel } = await getPersonnelList(props.enterpriseInfo.id)
personnel = personnel?.map(item => ({
time: new Date(item.year, 1, 1),
value: item.value,
type: '人员',
unit: item.unit ?? '亿元'
})) ?? []
lineData.value = [...revenue, ...netProfit, ...personnel]
}
</script>
\ No newline at end of file
<template>
<sanctions-situation :enterprise-info="enterpriseInfo" :line-data="lineData"></sanctions-situation>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { getMarketShareList } from '@/api/companyPages';
import SanctionsSituation, { LineDataItem } from './SanctionsSituation.vue';
// 定义组件属性
const props = defineProps({
enterpriseInfo: {
type: Object,
default: {}
}
});
const lineData = ref<LineDataItem[]>([])
onMounted(async () => {
await intData()
})
async function intData() {
const { data } = await getMarketShareList(props.enterpriseInfo.id)
lineData.value = data?.map(item => ({
time: new Date(item.year, 1, 1),
value: item.value,
unit: item.unit ?? '亿元'
})) ?? []
}
</script>
\ No newline at end of file
<template>
<sanctions-situation :enterprise-info="enterpriseInfo" :line-data="lineData"></sanctions-situation>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { getMarketCapList } from '@/api/companyPages';
import SanctionsSituation, { LineDataItem } from './SanctionsSituation.vue';
// 定义组件属性
const props = defineProps({
enterpriseInfo: {
type: Object,
default: {}
}
});
const lineData = ref<LineDataItem[]>([])
onMounted(async () => {
await intData()
})
async function intData() {
const { data } = await getMarketCapList(props.enterpriseInfo.id)
lineData.value = data?.map(item => ({
time: new Date(item.year, 1, 1),
value: item.value,
type: '市值变化',
unit: item.unit ?? '亿元'
})) ?? []
}
</script>
\ No newline at end of file
<template>
<sanctions-situation :enterprise-info="enterpriseInfo" :line-data="lineData"></sanctions-situation>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { getMarketCapList, getStudyList } from '@/api/companyPages';
import SanctionsSituation, { LineDataItem } from './SanctionsSituation.vue';
// 定义组件属性
const props = defineProps({
enterpriseInfo: {
type: Object,
default: {}
}
});
const lineData = ref<LineDataItem[]>([])
onMounted(async () => {
await intData()
})
async function intData() {
const { data } = await getStudyList(props.enterpriseInfo.id)
lineData.value = data?.map(item => ({
time: new Date(item.year, 1, 1),
value: item.currentValue,
type: item.type,
unit: item.unit ?? '亿元'
})) ?? []
}
</script>
\ No newline at end of file
<script setup lang="ts">
import '@/styles/tabs.scss'
import { ElTabPane, ElTabs } from 'element-plus';
import SanctionsSituation from './SanctionsSituation.vue';
import EnterpriseScale from './EnterpriseScale.vue';
import MarketShare from './MarketShare.vue';
import MarketValue from './MarketValue.vue';
import ResearchAndDevelopment from './ResearchAndDevelopment.vue';
// 定义组件属性
const props = defineProps({
......@@ -15,12 +18,18 @@ const props = defineProps({
<template>
<div style="overflow: visible;">
<el-tabs tabPosition="left" class="disinheritance tabs-nav-no-wrap left-float-nav-tabs">
<el-tab-pane label="企业规模">
<sanctions-situation :enterprise-info="enterpriseInfo"></sanctions-situation>
<el-tab-pane label="企业规模" lazy>
<enterprise-scale :enterprise-info="enterpriseInfo"></enterprise-scale>
</el-tab-pane>
<el-tab-pane label="市值变化" lazy>
<market-value :enterprise-info="enterpriseInfo"></market-value>
</el-tab-pane>
<el-tab-pane label="研发投入" lazy>
<research-and-development :enterprise-info="enterpriseInfo"></research-and-development>
</el-tab-pane>
<el-tab-pane label="市场占比" lazy>
<market-share :enterprise-info="enterpriseInfo"></market-share>
</el-tab-pane>
<!-- <el-tab-pane label="市值变化"></el-tab-pane>
<el-tab-pane label="研发投入"></el-tab-pane>
<el-tab-pane label="市场占比"></el-tab-pane> -->
</el-tabs>
</div>
</template>
\ No newline at end of file
......@@ -30,7 +30,7 @@ import { getSupplyAreaList } from '@/api/companyPages';
import { ref, watch } from 'vue';
import { ElSpace } from 'element-plus';
// 导入自定义组件
import CapitalScale from './capitalScale.vue'
import CapitalScale from './CapitalScale.vue'
// 响应式数据
const areas = ref([]) // 供应区域列表
......
......@@ -29,10 +29,10 @@
import { ref, onMounted } from 'vue';
import { useRoute } from 'vue-router';
import { getEnterprisePageInfo } from '@/api/companyPages';
import TitlePane from './component/titlePane.vue';
import NewsPane from './component/detailsPages/newsPane.vue';
import BaseInfo from './component/detailsPages/baseInfo.vue';
import OperatingPages from './component/operatingPages/index.vue';
import TitlePane from './component/TitlePane.vue';
import NewsPane from './component/DetailsPages/NewsPane.vue';
import BaseInfo from './component/DetailsPages/BaseInfo.vue';
import OperatingPages from './component/OperatingPages/index.vue';
import '@/styles/tabs.scss'
import '@/styles/container.scss'
import { ElScrollbar, ElSpace, ElTabs, ElTabPane } from 'element-plus';
......
......@@ -50,14 +50,10 @@
</template>
<script setup>
import NewsList from "@/components/base/NewsList/index.vue";
import NewsList from "@/components/NewsList.vue";
import { ref, onMounted } from "vue";
import router from '@/router'
import { getCoopRestrictionNews, getCoopRestrictionSocial } from '@/api/coopRestriction/coopRestriction'
import CommonPrompt from "../../commonPrompt/index.vue";
import defaultNews from "../../assets/images/default-icon-news.png"
import defaultAvatar from "../../assets/images/default-icon1.png"
import title01 from './assets/title01.png'
import title02 from './assets/title02.png'
import title03 from './assets/title03.png'
......@@ -92,7 +88,7 @@ const getCoopRestrictionSocialData = async () => {
console.error("获取合作限制社交媒体数据失败:", error);
}
};
const leftList = ref([])
// 合作限制-查询新闻资讯接口
const getCoopRestrictionNewsData = async () => {
......@@ -114,7 +110,7 @@ const getCoopRestrictionNewsData = async () => {
};
const leftList = ref([])
const rightList = ref([])
......
......@@ -673,7 +673,7 @@ const newsList = ref([
]);
const handleGetNews = async () => {
const params = {
moduleId: "0100"
moduleId: "0101"
};
try {
const res = await getNews(params);
......@@ -723,7 +723,7 @@ const messageList = ref([
]);
const handleGetMessage = async () => {
const params = {
moduleId: "0100"
moduleId: "0101"
};
try {
const res = await getSocialMedia(params);
......
......@@ -701,7 +701,7 @@
</template>
<script setup>
import NewsList from "@/components/base/newsList/index.vue";
import NewsList from "@/components/NewsList.vue";
import RiskSignal from "@/components/RiskSignal/RiskSignal.vue";
import { onMounted, ref, computed, reactive, shallowRef, watch, nextTick } from "vue";
import { useContainerScroll } from "@/hooks/useScrollShow";
......
......@@ -934,7 +934,7 @@ onMounted(() => {
:deep(.el-table__header-wrapper) {
th {
background-color: rgb(59, 65, 75) !important;
background-color: var(--color-primary-100) !important;
height: 48px;
padding: 0;
color: #fff;
......
......@@ -477,7 +477,7 @@ import CustomContainer from "@/components/Container/index.vue";
import ClickableCard from "./components/link.vue";
import InfoCard from "./components/info.vue";
import CustomTitle from "./components/title.vue";
import NewsList from "@/components/base/NewsList/index.vue";
import NewsList from "@/components/NewsList.vue";
import trumpAvatar from "@/assets/images/icon-trump.png";
import elongAvatar from "@/assets/images/icon-elong.png";
......
......@@ -374,18 +374,13 @@
<script setup>
import RiskSignal from "@/components/base/RiskSignal/index.vue";
import NewsList from "@/components/base/NewsList/index.vue";
import RiskSignal from "@/components/RiskSignal/RiskSignal.vue";
import NewsList from "@/components/NewsList.vue";
import { onMounted, ref, computed } from "vue";
import * as echarts from "echarts";
import router from "@/router";
import DivideHeader from "@/components/DivideHeader.vue";
import scrollToTop from "@/utils/scrollToTop";
import { useContainerScroll } from "@/hooks/useScrollShow";
import getBarChart from "./utils/barChart";
import getPieChart from "./utils/piechart";
import getCalendarHeatChart from "./utils/cleandarHeat";
import EChart from "@/components/Chart/index.vue";
import { pieOption, raderOption } from "./utils/charts";
import {
......
......@@ -436,9 +436,9 @@
</template>
<script setup>
import RiskSignal from "@/components/RiskSignal/RiskSignal.vue";
import { onMounted, ref } from "vue";
import NewsList from "@/components/base/NewsList/index.vue";
import RiskSignal from "@/components/base/RiskSignal/index.vue";
import DivideHeader from "@/components/DivideHeader.vue";
import setChart from "@/utils/setChart";
import router from "@/router";
......@@ -1802,6 +1802,7 @@ onMounted(async () => {
.box1 {
width: 1064px;
height: 450px;
.box1-left {
position: absolute;
left: 0;
......
......@@ -61,7 +61,7 @@
</template>
<script setup>
import NewsList from "@/components/base/NewsList/index.vue";
import NewsList from "@/components/NewsList.vue";
import { ref, onBeforeMount } from "vue";
import router from "@/router"
......
......@@ -53,7 +53,7 @@
</template>
<script setup>
import NewsList from "@/components/base/NewsList/index.vue";
import NewsList from "@/components/NewsList.vue";
import { ref, onMounted } from "vue";
import {
......
......@@ -95,6 +95,7 @@ const handleGetThinkTankReportSummary = async () => {
if (res.code === 200 && res.data) {
reportUrl.value = res.data.reportUrl;
thinkInfo.value = res.data;
console.log(reportUrl.value, 'reportUrl.value')
}
} catch (error) {
console.error("获取报告全局信息error", error);
......
......@@ -57,24 +57,32 @@
</div>
<div class="center">
<div class="title">{{ item.content }}</div>
<div>
<img
src="../images/image-open.png"
alt=""
class="center-image"
@click="handleOpenReportOriginal(item)"
/>
</div>
<!-- <div class="desc">{{ item.econtent }}</div> -->
</div>
<div class="right">
<!-- <div class="right"> -->
<!-- <div class="tag" v-for="(val, idx) in item.hylyList" :key="idx">
{{ val }}
</div>
<div class="tag" v-for="(val, idx) in item.serialNum" :key="idx">
{{ val }}
</div> -->
<AreaTag v-for="(val, idx) in item.hylyList" :key="idx" :tagName="val"></AreaTag>
</div>
<!-- <AreaTag v-for="(val, idx) in item.hylyList" :key="idx" :tagName="val"></AreaTag>
</div> -->
<!-- <div class="more">
<img src="@/assets/icons/open.png" alt="" />
</div> -->
</div>
</div>
<div class="box3-main-footer">
<div class="info"> {{ total }}</div>
<div class="info">{{ total }}条核心论点</div>
<div class="page-box">
<el-pagination
:page-size="12"
......@@ -87,19 +95,6 @@
</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>
</AnalysisBox>
</div>
</div>
......@@ -247,22 +242,49 @@ const majorOpinions = ref([
]
}
]);
//处理点击详情页事件
const handleOpenReportOriginal = item => {
const route = router.resolve({
name: "ReportOriginal",
params: {
id: router.currentRoute._value.params.id
},
query: {
currentPage: currentPage.value,
pageSize: pageSize.value,
opinionId: item?.id ?? "",
opinionContent: item?.content ?? ""
}
});
window.open(route.href, "_blank");
};
const tabActiveName = ref("报告分析");
const switchTab = name => {
tabActiveName.value = name;
};
// 处理页码改变事件
const currentPage = ref(1);
const pageSize = ref(10);
const total = ref(0);
const handleCurrentChange = page => {
currentPage.value = page;
handleGetThinkDynamicsReport();
handleGetThinkTankReportContent();
};
//获取报告主要观点
const handleGetThinkTankReportContent = async () => {
try {
const res = await getThinkTankReportContent(router.currentRoute._value.params.id);
const params = {
id: router.currentRoute._value.params.id,
currentPage: currentPage.value - 1,
pageSize: pageSize.value
};
const res = await getThinkTankReportContent(params);
console.log("主要观点", res.data);
if (res.code === 200 && res.data) {
majorOpinions.value = res.data.content;
majorOpinions.value = res.data.content || [];
handleGetBox3AnalysisContent(majorOpinions.value);
total.value = res.data.totalElements;
total.value = res.data.totalElements || 0;
}
} catch (error) {
console.error("获取主要观点error", error);
......@@ -495,7 +517,7 @@ onMounted(() => {
.box3 {
width: 1103px;
height: 946px;
height: 965px;
// border: 1px solid rgba(234, 236, 238, 1);
// border-radius: 10px;
// box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
......@@ -504,11 +526,11 @@ onMounted(() => {
.box3-main {
width: 1057px;
height: 800px;
margin: 0 auto;
.box3-main-main {
height: 720px;
height: 767px;
overflow: hidden;
.box3-item {
......@@ -547,6 +569,7 @@ onMounted(() => {
.title {
margin-top: 12px;
width: 918px;
// height: 55px;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
......@@ -564,6 +587,13 @@ onMounted(() => {
overflow: hidden;
}
.center-image {
width: 16px;
height: 24px;
margin-top: 12px;
margin-left: 18px;
}
.desc {
height: 22px;
color: rgba(95, 101, 108, 1);
......
......@@ -200,7 +200,15 @@
<div class="item-right">
<div>
<div class="title">{{ item.content }}</div>
<div class="info">{{ item.times }} · {{ item.name }}</div>
<div class="info">
{{ item.times }} · {{ item.name }}
<div class="more" @click="toDetail(item)">
<img
src="@/views/thinkTank/ThinkTankDetail/thinkDynamics/images/image open.png"
alt=""
/>
</div>
</div>
<div class="tag-box">
<AreaTag v-for="(tag, idx) in item.tagList" :key="idx" :tagName="tag"></AreaTag>
</div>
......@@ -221,16 +229,12 @@
</div>
</div>
</div>
<div>
<div class="more" @click="toDetail(item)">
<img src="@/assets/icons/open.png" alt="" />
</div>
</div>
<div></div>
</div>
</div>
</div>
<div class="right-footer">
<div class="info"> {{ total }} 项</div>
<div class="info">{{ total }}条政策建议</div>
<div class="page-box">
<el-pagination
:page-size="12"
......@@ -307,7 +311,8 @@ const box1Data = ref([
// color: "#D6E4FF"
// }
]);
const relationBillsList = ref([{ billName: "2025《人工智能安全与评估法案》" }]);
const relationAdList = ref([{ adName: "2025《人工智能安全与评估法案》" }]);
const box1SelectYear = ref("2025");
const box1YearList = ref([
{
......@@ -621,7 +626,11 @@ const handleGetThinkPolicy = async () => {
const res = await getThinkPolicy(parmas);
console.log("智库政策", res);
if (res.code === 200 && res.data) {
policyList.value = res.data.content;
policyList.value = res.data.content.map(item => ({
...item,
relationBillsList: relationBillsList.value,
relationAdList: relationAdList.value
}));
total.value = res.data.totalElements;
}
} catch (error) {
......@@ -656,6 +665,7 @@ onMounted(() => {
margin: 16px 0;
display: flex;
gap: 16px;
.box {
width: 520px;
height: 420px;
......@@ -1157,21 +1167,29 @@ onMounted(() => {
background: rgba(255, 255, 255, 1);
.right-main {
margin: 17px auto;
width: 1209px;
margin-top: 17px;
margin-left: 0;
width: 100%;
box-sizing: border-box;
padding-left: 37px;
padding-right: 0;
max-height: 1540px;
.right-main-item {
// height: 154px;
box-sizing: border-box;
padding-top: 8px;
padding-top: 16px;
padding-bottom: 16px;
margin-left: -37px;
padding-left: 37px;
padding-right: 36px;
width: calc(100% + 37px - 36px);
border-bottom: 1px solid rgba(234, 236, 238, 1);
display: flex;
.item-left {
width: 57px;
height: 77px;
margin-top: 3px;
img {
width: 100%;
......@@ -1188,7 +1206,7 @@ onMounted(() => {
.title {
// height: 24px;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-family: "Source Han Sans CN";
font-size: 18px;
font-weight: 700;
line-height: 24px;
......@@ -1200,12 +1218,25 @@ onMounted(() => {
margin-top: 7px;
height: 22px;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-family: "Source Han Sans CN";
font-size: 14px;
font-weight: 400;
line-height: 22px;
letter-spacing: 0px;
text-align: left;
display: flex;
.more {
width: 16px;
height: 16px;
margin-top: 3px;
margin-left: 9px;
img {
width: 100%;
height: 100%;
}
}
}
.tag-box {
......@@ -1235,30 +1266,30 @@ onMounted(() => {
.file {
height: 32px;
padding: 0 8px;
padding: 4px 8px;
display: flex;
justify-content: center;
align-items: center;
gap: 8px;
gap: 12px;
border-radius: 4px;
background: rgba(246, 250, 255, 1);
.type {
height: 22px;
margin-top: 1px;
padding: 0 4px;
border-radius: 4px;
background: rgba(231, 243, 255, 1);
color: rgba(5, 95, 194, 1);
font-family: Microsoft YaHei;
font-family: "Source Han Sans CN";
font-size: 14px;
font-weight: 400;
line-height: 22px;
}
.title {
height: 24px;
color: rgba(5, 95, 194, 1);
font-family: Microsoft YaHei;
font-family: "Source Han Sans CN";
font-size: 16px;
font-weight: 400;
line-height: 24px;
......@@ -1267,8 +1298,10 @@ onMounted(() => {
.more {
width: 20px;
height: 20px;
display: flex;
margin-top: 2px;
img {
.img {
width: 100%;
height: 100%;
}
......@@ -1280,21 +1313,30 @@ onMounted(() => {
}
.right-footer {
margin: 0 auto;
width: 1209px;
height: 96px;
height: 86px;
display: flex;
justify-content: space-between;
margin-top: 17px;
.info {
margin-top: 29px;
margin-left: 39px;
color: rgba(132, 136, 142, 1);
font-family: Microsoft YaHei;
font-size: 14px;
height: 19px;
font-weight: 400;
line-height: 18px;
letter-spacing: 0px;
text-align: left;
}
.page-box {
margin-top: 23px;
margin-right: 36px;
height: 32px;
}
}
}
}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论