提交 b9aae742 authored 作者: coderBryanFu's avatar coderBryanFu

update

上级 635c86d8
......@@ -19,6 +19,7 @@
"echarts-wordcloud": "^2.1.0",
"element-plus": "^2.4.4",
"highlight.js": "^11.11.1",
"json5": "^2.2.3",
"markdown-it": "^14.1.0",
"vue": "^3.4.0",
"vue-router": "^4.2.5"
......@@ -2899,6 +2900,7 @@
"version": "3.1.0",
"resolved": "https://registry.npmmirror.com/echarts-liquidfill/-/echarts-liquidfill-3.1.0.tgz",
"integrity": "sha512-5Dlqs/jTsdTUAsd+K5LPLLTgrbbNORUSBQyk8PSy1Mg2zgHDWm83FmvA4s0ooNepCJojFYRITTQ4GU1UUSKYLw==",
"license": "MIT",
"peerDependencies": {
"echarts": "^5.0.1"
}
......@@ -4026,6 +4028,18 @@
"sprintf-js": "~1.0.2"
}
},
"node_modules/json5": {
"version": "2.2.3",
"resolved": "https://registry.npmmirror.com/json5/-/json5-2.2.3.tgz",
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
"license": "MIT",
"bin": {
"json5": "lib/cli.js"
},
"engines": {
"node": ">=6"
}
},
"node_modules/jsonfile": {
"version": "4.0.0",
"resolved": "https://registry.npmmirror.com/jsonfile/-/jsonfile-4.0.0.tgz",
......
......@@ -28,6 +28,7 @@
"echarts-wordcloud": "^2.1.0",
"element-plus": "^2.4.4",
"highlight.js": "^11.11.1",
"json5": "^2.2.3",
"markdown-it": "^14.1.0",
"vue": "^3.4.0",
"vue-router": "^4.2.5"
......
......@@ -27,6 +27,7 @@
<el-dropdown-item command="/decree">政令首页</el-dropdown-item>
<el-dropdown-item command="/thinkTank">智库首页</el-dropdown-item>
<el-dropdown-item command="/exportControl">出口管制</el-dropdown-item>
<el-dropdown-item command="/finance">投融资限制</el-dropdown-item>
<el-dropdown-item command="/marketAccessRestrictions">市场准入限制</el-dropdown-item>
</el-dropdown-menu>
</template>
......
......@@ -38,6 +38,52 @@ export function useMarkdownStream() {
)
// 关键配置:自定义图片渲染规则
md.renderer.rules.image = function (tokens, idx, options, env, self) {
const token = tokens[idx];
const src = token.attrs[token.attrIndex('src')][1];
const alt = token.content;
const title = token.attrs[token.attrIndex('title')] ? token.attrs[token.attrIndex('title')][1] : '';
// 获取自定义样式参数
const maxWidth = env.maxWidth || '100%';
const height = env.height || 'auto';
const objectFit = env.objectFit || 'cover';
const borderRadius = env.borderRadius || '0px';
const boxShadow = env.boxShadow || 'none';
const display = env.display || 'block';
const margin = env.margin || '0 auto';
// 构建样式字符串
const style = `
max-width: ${maxWidth};
height: ${height};
object-fit: ${objectFit};
border-radius: ${borderRadius};
box-shadow: ${boxShadow};
display: ${display};
margin: ${margin};
`.replace(/\s+/g, ' ').trim();
return `<img src="${src}" alt="${alt}"${title ? ` title="${title}"` : ''} style="${style}" loading="lazy">`;
};
// 链接图片的特殊处理
md.renderer.rules.link_open = function (tokens, idx, options, env, self) {
const token = tokens[idx];
const href = token.attrs[token.attrIndex('href')][1];
// 检查下一个token是否是图片
const nextToken = tokens[idx + 1];
if (nextToken && nextToken.type === 'image') {
// 为包含图片的链接添加特殊样式
const linkStyle = env.linkStyle || 'text-decoration: none; color: inherit;';
return `<a href="${href}" style="${linkStyle}" target="_blank" rel="noopener">`;
}
return self.renderToken(tokens, idx, options);
};
// 自定义代码块渲染规则
md.renderer.rules.fence = (tokens, idx, options, env, self) => {
const token = tokens[idx]
......
// composables/useMarkdownStream.js
import { ref, computed, nextTick } from 'vue'
import MarkdownIt from 'markdown-it'
import hljs from 'highlight.js'
// 引入 highlight.js 样式
import 'highlight.js/styles/github.css'
import mdKatex from '@traptitech/markdown-it-katex'
export function useStream() {
const rawContent = ref('')
const createMd = () => {
const md = new MarkdownIt(
{
html: true,
breaks: true, // 将换行符转换为 <br>
linkify: true, // 自动链接 URL
typographer: true, // 启用排版扩展
highlight: function (str, lang) {
if (lang && hljs.getLanguage(lang)) {
try {
return '<pre class="hljs" style="fontSize:14px"><code class="language-' + lang + '">' +
hljs.highlight(str, {
language: lang,
ignoreIllegals: true
}).value +
'</code></pre>'
} catch (err) {
console.warn(`代码高亮错误 (${lang}):`, err)
}
}
// 默认处理
return '<pre class="hljs"><code>' + md.utils.escapeHtml(str) + '</code></pre>'
}
}
)
// 自定义代码块渲染规则
md.renderer.rules.fence = (tokens, idx, options, env, self) => {
const token = tokens[idx]
const lang = token.info.trim()
const code = token.content
// 使用 highlight.js 进行高亮
if (lang && hljs.getLanguage(lang)) {
try {
const highlighted = hljs.highlight(code, {
language: lang,
ignoreIllegals: true
})
return `
<div class="code-block-wrapper">
<div class="code-header">
<span class="code-lang">${lang}</span>
</div>
<pre class="hljs"><code class="language-${lang}">${highlighted.value}</code></pre>
</div>
`
} catch (err) {
console.warn(`代码高亮错误 (${lang}):`, err)
}
}
// 默认代码块
return `
<div class="code-block-wrapper">
<div class="code-header">
<span class="code-lang">${lang || 'text'}</span>
<button class="copy-btn" onclick="copyCode(this)">复制</button>
</div>
<pre class="hljs"><code>${md.utils.escapeHtml(code)}</code></pre>
</div>
`
}
// 自定义表格渲染规则
md.renderer.rules.table_open = () =>
'<div class="table-container"><table style="border-collapse: collapse; width: 100%; margin: 1em 0; border: 1px solid #dfe2e5;background: rgb(239 241 243); border-radius: 5px">'
md.renderer.rules.table_close = () => '</table></div>'
md.renderer.rules.thead_open = () => '<thead style="background: #e6e7e8">'
md.renderer.rules.th_open = () =>
'<th style="border: 1px solid #dfe2e5; padding: 12px; text-align: left; font-weight: 600;">'
md.renderer.rules.td_open = () =>
'<td style="border: 1px solid #dfe2e5; padding: 12px; text-align: left; vertical-align: top;">'
md.renderer.rules.th_close = () => '</th>'
md.renderer.rules.td_close = () => '</td>'
md.renderer.rules.tr_open = () => '<tr>'
md.renderer.rules.tr_close = () => '</tr>'
md.renderer.rules.thead_close = () => '</thead>'
md.renderer.rules.tbody_open = () => '<tbody>'
md.renderer.rules.tbody_close = () => '</tbody>'
return md
}
// 渲染 markdown
const renderedProcess = computed(() => {
const md = createMd()
// 预处理内容
return md.render(rawContent.value)
})
// 自动滚动
const scrollToBottom = async (scrollContainer) => {
await nextTick()
if (scrollContainer) {
scrollContainer.scrollTop = scrollContainer.scrollHeight
}
}
// 更新内容并滚动
const updateProcess = async (newContent, scrollContainer) => {
rawContent.value = newContent
await scrollToBottom(scrollContainer)
}
// 清空内容
const clearContent = () => {
rawContent.value = ''
}
return {
rawContent,
renderedProcess,
updateProcess,
clearContent
}
}
\ No newline at end of file
......@@ -20,7 +20,12 @@
</div>
</div>
<div class="header-right">
<img src="./assets/images/header-icon.png" alt="" />
<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">
......@@ -60,7 +65,12 @@
<div class="header-left"></div>
<div class="title">相关事件</div>
<div class="header-right">
<img src="./assets/images/header-icon.png" alt="" />
<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">
......@@ -105,7 +115,12 @@
</div>
</div>
<div class="header-right">
<img src="./assets/images/header-icon.png" alt="" />
<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="background-wrap-right-main">
......@@ -519,7 +534,7 @@ onMounted(() => {
.header-btn-box {
position: absolute;
top: 14px;
right: 52px;
right: 84px;
display: flex;
.btn {
margin-left: 8px;
......@@ -529,14 +544,19 @@ onMounted(() => {
position: absolute;
top: 14px;
right: 12px;
width: 32px;
height: 32px;
img {
display: flex;
justify-content: flex-end;
gap: 4px;
.icon{
width: 28px;
height: 28px;
img{
width: 100%;
height: 100%;
}
}
}
}
.background-wrap-left {
width: 1150px;
margin-top: 16px;
......
......@@ -31,8 +31,13 @@
</div>
<div class="home-box" :class="{ scrollHomeBox: isShow }" ref="containerRef">
<div class="home-header" v-show="!isShow">
<span>国家科技安全 </span>> <span>中美博弈概览 </span>>
<span>科技法案 </span>
<!-- <span>国家科技安全 </span>> <span style="cursor: pointer;">中美博弈概览 </span>>
<span>科技法案 </span> -->
<div class="header-item">国家科技安全</div>
<div class="header-item">></div>
<div class="header-item back-item" @click="handleBackHome">中美博弈概览</div>
<div class="header-item">></div>
<div class="header-item">科技法案</div>
</div>
<div class="home-main">
<div class="home-main-header" v-show="!isShow">
......@@ -566,6 +571,13 @@ import Zyy from "@/assets/icons/zyy.png";
import Ghd from "@/assets/icons/ghd.png";
import Mzd from "@/assets/icons/mzd.png";
// 返回首页
const handleBackHome = () => {
router.push({
path: '/overview'
})
}
const currentPage = ref(1);
// 处理页码改变事件
const handleCurrentChange = page => {
......@@ -1073,79 +1085,77 @@ const box9ChartData = ref([
const box7Data = ref([
[
{
name: '众议院',
name: "众议院",
value: 298
},
{
name: '参议院',
name: "参议院",
value: 149
}
],
[
{
name: '拨款委员会',
name: "拨款委员会",
value: 50,
type: '众议院'
type: "众议院"
},
{
name: '筹款委员会',
name: "筹款委员会",
value: 50,
type: '众议院'
type: "众议院"
},
{
name: '外交事务委员会',
name: "外交事务委员会",
value: 46,
type: '众议院'
type: "众议院"
},
{
name: '国土安全委员会',
name: "国土安全委员会",
value: 40,
type: '众议院'
type: "众议院"
},
{
name: '司法委员会',
name: "司法委员会",
value: 40,
type: '众议院'
type: "众议院"
},
{
name: '军事委员会',
name: "军事委员会",
value: 40,
type: '众议院'
type: "众议院"
},
{
name: '能源和商业委员会',
name: "能源和商业委员会",
value: 32,
type: '众议院'
type: "众议院"
},
{
name: '拨款委员会1',
name: "拨款委员会1",
value: 32,
type: '参议院'
type: "参议院"
},
{
name: '财政委员会',
name: "财政委员会",
value: 31,
type: '参议院'
type: "参议院"
},
{
name: '能源',
name: "能源",
value: 30,
type: '参议院'
type: "参议院"
},
{
name: '能源1',
name: "能源1",
value: 30,
type: '参议院'
type: "参议院"
},
{
name: '其他',
name: "其他",
value: 24,
type: '参议院'
type: "参议院"
}
]
])
]);
const box8Data = ref([
{
......@@ -1203,8 +1213,8 @@ onMounted(async () => {
const wordCloudChart = getWordCloudChart(wordCloudData.value);
setChart(wordCloudChart, "wordCloudChart");
const box7Chart = getDoublePieChart(box7Data.value[0], box7Data.value[1])
setChart(box7Chart, 'box7Chart')
const box7Chart = getDoublePieChart(box7Data.value[0], box7Data.value[1]);
setChart(box7Chart, "box7Chart");
const box9Chart = getPieChart(box9ChartData.value, box9ChartColorList.value);
setChart(box9Chart, "box9Chart");
......@@ -1328,6 +1338,16 @@ onMounted(async () => {
background: url("./assets/images/header-bg.png");
box-sizing: border-box;
padding-left: 160px;
display: flex;
.header-item {
margin: 0 3px;
}
.back-item {
cursor: pointer;
&:hover {
color: #ccc;
}
}
}
.home-main {
width: 1600px;
......@@ -1565,9 +1585,10 @@ onMounted(async () => {
.box1-main-left-info {
margin-top: 17px;
display: flex;
gap: 8px;
.info-box {
height: 30px;
width: 80px;
max-width: 80px;
height: 24px;
text-align: center;
overflow: hidden;
padding: 0 8px;
......@@ -1579,8 +1600,7 @@ onMounted(async () => {
font-family: Microsoft YaHei;
font-size: 14px;
font-weight: 400;
line-height: 30px;
margin-right: 8px;
line-height: 24px;
}
.info1 {
border: 1px solid rgba(135, 232, 222, 1);
......@@ -2335,7 +2355,7 @@ onMounted(async () => {
align-items: center;
justify-content: flex-end;
}
.box7-main{
.box7-main {
height: 340px;
}
}
......@@ -2592,15 +2612,18 @@ onMounted(async () => {
.btn-wrapper {
width: 1300px;
overflow-x: auto;
// background: skyblue;
.btn-box {
display: flex;
gap: 4px;
// justify-content: space-between;
max-width: 2000px;
// background: orange;
.btn {
max-width: 100px;
max-width: 120px;
min-width: 80px;
height: 42px;
margin: 0 5px;
overflow: hidden;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
......@@ -2610,7 +2633,7 @@ onMounted(async () => {
text-align: center;
border-radius: 21px;
background: rgba(20, 89, 187, 0);
padding: 0 16px;
padding: 0 20px;
cursor: pointer;
&:hover {
background: rgba(20, 89, 187, 0.1);
......
......@@ -4,66 +4,21 @@
<div class="box1">
<div class="box-header">
<div class="header-left"></div>
<div class="title">耗时分析</div>
<div
class="header-switch-box"
:class="{ headerSwitchBox1: isShowChartData === 'data' }"
>
<div
class="header-switch-box-left"
@click="handleSwitch('chart')"
></div>
<div
class="header-switch-box-right"
@click="handleSwitch('data')"
></div>
</div>
<div class="header-btn-box">
<div class="btn" @click="handleClickBox1Btn(1)">
<el-button type="primary" plain v-if="box1BtnAvtiveIndex === 1"
>典型阶段耗时</el-button
>
<el-button type="info" plain v-else>典型阶段耗时</el-button>
</div>
<div class="btn" @click="handleClickBox1Btn(2)">
<el-button type="primary" plain v-if="box1BtnAvtiveIndex === 2"
>辩论投票时长</el-button
>
<el-button type="info" plain v-else>辩论投票时长</el-button>
</div>
</div>
<div class="title">典型阶段耗时</div>
<div class="header-right">
<img src="../assets/images/header-icon.png" alt="" />
<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="box1-main">
<div
class="box1-main-center"
id="chart1"
v-show="isShowChartData === 'chart'"
></div>
<div class="box1-main-center" v-show="isShowChartData === 'data'">
<div class="box1-main-table">
<div class="table-name">
<div class="name-item">{{ "" }}</div>
<div class="name-item">{{ dataList[0].data1.name }}</div>
<div class="name-item">{{ dataList[0].data2.name }}</div>
<div class="name-item">{{ dataList[0].data3.name }}</div>
<div class="name-item">{{ dataList[0].data4.name }}</div>
</div>
<div
class="table-item"
v-for="(item, index) in dataList"
:key="index"
>
<div class="item">{{ item.name }}</div>
<div class="item">{{ item.data1.value }}</div>
<div class="item">{{ item.data2.value }}</div>
<div class="item">{{ item.data3.value }}</div>
<div class="item">{{ item.data4.value }}</div>
<div class="icon">
<img src="@/assets/icons/box-header-icon3.png" alt="" />
</div>
</div>
</div>
<div class="box1-main">
<div class="box1-main-center" id="chart1"></div>
<div class="box1-main-footer">
<div class="box-footer-left">
<img src="../assets/icons/right-icon1.png" alt="" />
......@@ -80,132 +35,21 @@
<div class="box2">
<div class="box-header">
<div class="header-left"></div>
<div class="title">政治献金</div>
<div class="header-btn-box">
<div class="btn" @click="handleClickBox2Btn(1)">
<el-button type="primary" plain v-if="box2BtnActiveIndex === 1"
>参议院</el-button
>
<el-button type="info" plain v-else>参议院</el-button>
</div>
<div class="btn" @click="handleClickBox2Btn(2)">
<el-button type="primary" plain v-if="box2BtnActiveIndex === 2"
>众议院</el-button
>
<el-button type="info" plain v-else>众议院</el-button>
</div>
<!-- <div class="btn" @click="handleClickBox2Btn(3)">
<el-button type="primary" plain v-if="box2BtnActiveIndex === 3"
>保险金融</el-button
>
<el-button type="info" plain v-else>保险金融</el-button>
</div>
<div class="btn" @click="handleClickBox2Btn(4)">
<el-button type="primary" plain v-if="box2BtnActiveIndex === 4"
>制造业</el-button
>
<el-button type="info" plain v-else>制造业</el-button>
</div>
<div class="btn" @click="handleClickBox2Btn(5)">
<el-button type="primary" plain v-if="box2BtnActiveIndex === 5"
>快递物流</el-button
>
<el-button type="info" plain v-else>快递物流</el-button>
</div> -->
</div>
<div class="title">辩论投票时长</div>
<div class="header-right">
<img src="../assets/images/header-icon.png" alt="" />
</div>
</div>
<div class="box2-main">
<div class="box2-main-center">
<div class="box2-main-center-left">
<div
class="left-item"
v-for="(item, index) in box2DataList"
:key="index"
>
<div class="left-item-left">
<img :src="item.img" alt="" />
</div>
<div class="left-item-center">
<div class="left-item-center-top">
<div class="name">{{ item.name }}</div>
<div class="icon1">
<img :src="item.icon1" alt="" />
</div>
<div class="icon2">
<img :src="item.icon2" alt="" />
</div>
</div>
<div class="left-item-center-bottom">
{{ item.position }}
</div>
</div>
<div class="left-item-right">
<div class="left-item-right-top">{{ item.money }}</div>
<div class="left-item-right-bottom">{{ item.content }}</div>
</div>
</div>
</div>
<div class="box2-main-center-right">
<div id="chart2"></div>
<div class="info-box">
<div class="item">
<div class="item-top">
<div class="icon">
<img v-if="chart2Data[0].name === '共和党'" src="./assets/images/icon-b.png" alt="" />
<img v-else src="./assets/images/icon-a.png" alt="" />
</div>
<div class="name">{{ chart2Data[0].name }}</div>
</div>
<div class="item-footer">
{{ "$" + chart2Data[0].value * 10000 }}
</div>
<img src="@/assets/icons/box-header-icon1.png" alt="" />
</div>
<div class="item" v-if="chart2Data.length > 1">
<div class="item-top">
<div class="icon">
<img v-if="chart2Data[1].name === '共和党'" src="./assets/images/icon-b.png" alt="" />
<img v-else src="./assets/images/icon-a.png" alt="" />
</div>
<div class="name">{{ chart2Data[1].name }}</div>
</div>
<div class="item-footer1">
{{ "$" + chart2Data[1].value * 10000 }}
</div>
</div>
</div>
</div>
<!-- <div class="box2-main-center-content">
<div
class="box2-item"
v-for="(item, index) in companyList"
:key="index"
>
<div class="box2-item-left">
<img :src="item.icon" alt="" />
</div>
<div class="box2-item-center">
<div class="box2-item-center-top">{{ item.name }}</div>
<div class="box2-item-center-bottom">{{ item.info }}</div>
</div>
<div class="box2-item-right">
<div class="box2-item-right-top">{{ item.money }}</div>
<div class="box2-item-right-bottom">{{ item.content }}</div>
<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 class="box2-main-center-footer">
<el-pagination
background
layout="prev, pager, next"
:total="26"
/>
</div> -->
</div>
<div class="box2-main">
<div class="box2-main-center" id="chart2"></div>
<div class="box2-main-footer">
<div class="box-footer-left">
<img src="../assets/icons/right-icon1.png" alt="" />
......@@ -227,7 +71,15 @@
<div class="header-left"></div>
<div class="title">投票分析</div>
<div class="header-right">
<img src="../assets/images/header-icon.png" alt="" />
<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="box3-main">
......@@ -238,19 +90,13 @@
<div class="box3">平均区间</div>
<div class="box4">占比</div>
<div class="box5">
倒戈人数<span style="font-weight: normal; display: inline-block"
>(平均区间)</span
>
倒戈人数<span style="font-weight: normal; display: inline-block">(平均区间)</span>
</div>
<div class="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="item" v-for="(item, index) in voteAnalysisList1" :key="index">
<div class="box1">
<div class="box1-left">
<div class="icon" v-if="item.nameIcon">
......@@ -267,18 +113,10 @@
</div>
<div class="box1-right">
<div class="box1-right-top">
<el-progress
:percentage="item.supportRate"
:show-text="false"
>
</el-progress>
<el-progress :percentage="item.supportRate" :show-text="false"> </el-progress>
</div>
<div class="box1-right-bottom">
<el-progress
:percentage="item.againistRate"
:show-text="false"
>
</el-progress>
<el-progress :percentage="item.againistRate" :show-text="false"> </el-progress>
</div>
</div>
</div>
......@@ -303,19 +141,13 @@
<img :src="item.keyUser" alt="" />
</div>
<div v-else>
<el-icon size="20" color="#555"
><ArrowDownBold
/></el-icon>
<el-icon size="20" color="#555"><ArrowDownBold /></el-icon>
</div>
</div>
</div>
</div>
<div class="box3-main-center-content-box">
<div
class="item"
v-for="(item, index) in voteAnalysisList2"
:key="index"
>
<div class="item" v-for="(item, index) in voteAnalysisList2" :key="index">
<div class="box1">
<div class="box1-left">
<div class="icon" v-if="item.nameIcon">
......@@ -332,18 +164,10 @@
</div>
<div class="box1-right">
<div class="box1-right-top">
<el-progress
:percentage="item.supportRate"
:show-text="false"
>
</el-progress>
<el-progress :percentage="item.supportRate" :show-text="false"> </el-progress>
</div>
<div class="box1-right-bottom">
<el-progress
:percentage="item.againistRate"
:show-text="false"
>
</el-progress>
<el-progress :percentage="item.againistRate" :show-text="false"> </el-progress>
</div>
</div>
</div>
......@@ -368,19 +192,13 @@
<img :src="item.keyUser" alt="" />
</div>
<div v-else>
<el-icon size="20" color="#555"
><ArrowDownBold
/></el-icon>
<el-icon size="20" color="#555"><ArrowDownBold /></el-icon>
</div>
</div>
</div>
</div>
<div class="box3-main-center-content-box">
<div
class="item"
v-for="(item, index) in voteAnalysisList3"
:key="index"
>
<div class="item" v-for="(item, index) in voteAnalysisList3" :key="index">
<div class="box1">
<div class="box1-left">
<div class="icon" v-if="item.nameIcon">
......@@ -397,18 +215,10 @@
</div>
<div class="box1-right">
<div class="box1-right-top">
<el-progress
:percentage="item.supportRate"
:show-text="false"
>
</el-progress>
<el-progress :percentage="item.supportRate" :show-text="false"> </el-progress>
</div>
<div class="box1-right-bottom">
<el-progress
:percentage="item.againistRate"
:show-text="false"
>
</el-progress>
<el-progress :percentage="item.againistRate" :show-text="false"> </el-progress>
</div>
</div>
</div>
......@@ -433,19 +243,13 @@
<img :src="item.keyUser" alt="" />
</div>
<div v-else>
<el-icon size="20" color="#555"
><ArrowDownBold
/></el-icon>
<el-icon size="20" color="#555"><ArrowDownBold /></el-icon>
</div>
</div>
</div>
</div>
<div class="box3-main-center-content-box">
<div
class="item"
v-for="(item, index) in voteAnalysisList4"
:key="index"
>
<div class="item" v-for="(item, index) in voteAnalysisList4" :key="index">
<div class="box1">
<div class="box1-left">
<div class="icon" v-if="item.nameIcon">
......@@ -462,18 +266,10 @@
</div>
<div class="box1-right">
<div class="box1-right-top">
<el-progress
:percentage="item.supportRate"
:show-text="false"
>
</el-progress>
<el-progress :percentage="item.supportRate" :show-text="false"> </el-progress>
</div>
<div class="box1-right-bottom">
<el-progress
:percentage="item.againistRate"
:show-text="false"
>
</el-progress>
<el-progress :percentage="item.againistRate" :show-text="false"> </el-progress>
</div>
</div>
</div>
......@@ -498,9 +294,7 @@
<img :src="item.keyUser" alt="" />
</div>
<div v-else>
<el-icon size="20" color="#555"
><ArrowDownBold
/></el-icon>
<el-icon size="20" color="#555"><ArrowDownBold /></el-icon>
</div>
</div>
</div>
......@@ -526,12 +320,7 @@
<script setup>
import { ref, onMounted } from "vue";
import {
getBillTimeAnalyze,
getBillXj,
getBillTotalXj,
getBillTp,
} from "@/api/deepdig";
import { getBillTimeAnalyze, getBillXj, getBillTotalXj, getBillTp } from "@/api/deepdig";
import getBoxPlotChcart from "./utils/boxplot";
import * as echarts from "echarts";
......@@ -557,228 +346,12 @@ import userIcon2 from "./assets/images/user-icon2.png";
import getPieChart from "./utils/pieChart";
import CYY from '@/assets/icons/cyy.png'
import ZYY from '@/assets/icons/zyy.png'
import MZD from '@/assets/icons/mzd.png'
import GHD from '@/assets/icons/ghd.png'
const box1BtnAvtiveIndex = ref(1);
const handleClickBox1Btn = (index) => {
if (box1BtnAvtiveIndex.value === index) return;
box1BtnAvtiveIndex.value = index;
let data;
if (index === 1) {
data = chartData1.value;
} else {
data = chartData2.value;
}
let chart1 = getBoxPlotChcart(data);
setChart(chart1, "chart1");
};
const box2BtnActiveIndex = ref(1);
const handleClickBox2Btn = (index) => {
box2BtnActiveIndex.value = index;
if (index === 1) {
handleGetXj("参议院");
handleGetTotalXj("参议院");
} else {
handleGetXj("众议院");
handleGetTotalXj("众议院");
}
};
import CYY from "@/assets/icons/cyy.png";
import ZYY from "@/assets/icons/zyy.png";
import MZD from "@/assets/icons/mzd.png";
import GHD from "@/assets/icons/ghd.png";
const isShowChartData = ref("chart");
const handleSwitch = (data) => {
isShowChartData.value = data;
};
const dataList = ref([
{
name: "众议院通过",
data1: {
name: "中位数",
value: "70天",
},
data2: {
name: "平均耗时",
value: "42-85天",
},
data3: {
name: "最短耗时",
value: "25天",
},
data4: {
name: "本次耗时",
value: "11天",
},
},
{
name: "参议院通过",
data1: {
name: "中位数",
value: "63天",
},
data2: {
name: "平均耗时",
value: "36-110天",
},
data3: {
name: "最短耗时",
value: "31天",
},
data4: {
name: "本次耗时",
value: "12天",
},
},
{
name: "两院协商",
data1: {
name: "中位数",
value: "52天",
},
data2: {
name: "平均耗时",
value: "28-63天",
},
data3: {
name: "最短耗时",
value: "27天",
},
data4: {
name: "本次耗时",
value: "16天",
},
},
{
name: "总统签署",
data1: {
name: "中位数",
value: "27天",
},
data2: {
name: "平均耗时",
value: "32-36天",
},
data3: {
name: "最短耗时",
value: "19天",
},
data4: {
name: "本次耗时",
value: "1天",
},
},
]);
const box2DataList = ref([
{
img: user1,
name: "乔迪·阿灵顿​",
icon1: userIcon1,
icon2: userIcon2,
position: "众议院预算委员会主席",
money: "$1,550,000",
content: "8项游说记录",
},
{
img: user2,
name: "史蒂夫·戴恩斯",
icon1: userIcon1,
icon2: userIcon2,
position: "众议院预算委员会主席",
money: "$820,000",
content: "4项游说记录",
},
{
img: user3,
name: "伯尼·莫雷诺",
icon1: userIcon1,
icon2: userIcon2,
position: "众议院预算委员会主席",
money: "$50,000",
content: "5项游说记录",
},
{
img: user4,
name: "戴夫·麦考密克",
icon1: userIcon1,
icon2: userIcon2,
position: "众议院预算委员会主席",
money: "$50,000",
content: "3项游说记录",
},
{
img: user5,
name: "蒂姆·希伊",
icon1: userIcon1,
icon2: userIcon2,
position: "众议院预算委员会主席",
money: "$35,000",
content: "2项游说记录",
},
]);
const companyList = ref([
{
name: "蓝十字/蓝盾协会",
info: "美国私人医疗保险公司",
icon: icon1,
money: "$18,550,000",
content: "29项游说报告",
},
{
name: "美国医院协会",
info: "美国最大的医院行业性组织",
icon: icon2,
money: "$12,190,000",
content: "17项游说报告",
},
{
name: "美国药品研究和制造商协会",
info: "领先得制药和生物技术研究公司",
icon: icon3,
money: "$9,950,000",
content: "11项游说报告",
},
{
name: "美国奥驰亚集团",
info: "烟草巨头菲利浦·莫里斯母公司",
icon: icon4,
money: "$8,216,000",
content: "10项游说报告",
},
{
name: "康卡斯特公司",
info: "美国第二大互联网服务供应商",
icon: icon5,
money: "$7,720,000",
content: "9项游说报告",
},
{
name: "通用汽车公司",
info: "全球最大汽车集团公司",
icon: icon6,
money: "$6,745,000",
content: "9项游说报告",
},
{
name: "联邦快递公司",
info: "国际性速递集团",
icon: icon7,
money: "$6,320,000",
content: "8项游说报告",
},
{
name: "伯克希尔·哈撒韦公司",
info: "保险和多元化投资集团",
icon: icon8,
money: "$6,100,000",
content: "12项游说报告",
},
]);
const voteAnalysisList1 = ref([
{
......@@ -793,7 +366,7 @@ const voteAnalysisList1 = ref([
supportRate: 51.5,
againistRate: 48.5,
people: "",
keyUser: null,
keyUser: null
},
{
nameIcon: iconA,
......@@ -806,7 +379,7 @@ const voteAnalysisList1 = ref([
againistRate: 92.7,
people: 1,
peopleRank: "0-1",
keyUser: keyUser,
keyUser: keyUser
},
{
nameIcon: iconB,
......@@ -819,8 +392,8 @@ const voteAnalysisList1 = ref([
againistRate: 5.5,
people: 1,
peopleRank: "1-2",
keyUser: keyUser,
},
keyUser: keyUser
}
]);
const voteAnalysisList2 = ref([
......@@ -836,7 +409,7 @@ const voteAnalysisList2 = ref([
supportRate: 50.1,
againistRate: 49.9,
people: "",
keyUser: null,
keyUser: null
},
{
nameIcon: iconA,
......@@ -849,7 +422,7 @@ const voteAnalysisList2 = ref([
againistRate: 92.7,
people: 0,
peopleRank: "0-1",
keyUser: keyUser,
keyUser: keyUser
},
{
nameIcon: iconB,
......@@ -862,8 +435,8 @@ const voteAnalysisList2 = ref([
againistRate: 1.3,
people: 3,
peopleRank: "1-3",
keyUser: keyUser,
},
keyUser: keyUser
}
]);
const voteAnalysisList3 = ref([
......@@ -879,7 +452,7 @@ const voteAnalysisList3 = ref([
supportRate: 50.5,
againistRate: 49.5,
people: "",
keyUser: null,
keyUser: null
},
{
nameIcon: iconA,
......@@ -892,7 +465,7 @@ const voteAnalysisList3 = ref([
againistRate: 92.7,
people: 1,
peopleRank: "0-1",
keyUser: keyUser,
keyUser: keyUser
},
{
nameIcon: iconB,
......@@ -905,8 +478,8 @@ const voteAnalysisList3 = ref([
againistRate: 5.5,
people: 1,
peopleRank: "1-2",
keyUser: keyUser,
},
keyUser: keyUser
}
]);
const voteAnalysisList4 = ref([
......@@ -922,7 +495,7 @@ const voteAnalysisList4 = ref([
supportRate: 51.5,
againistRate: 48.5,
people: "",
keyUser: null,
keyUser: null
},
{
nameIcon: iconA,
......@@ -935,7 +508,7 @@ const voteAnalysisList4 = ref([
againistRate: 92.7,
people: 1,
peopleRank: "0-1",
keyUser: keyUser,
keyUser: keyUser
},
{
nameIcon: iconB,
......@@ -948,8 +521,8 @@ const voteAnalysisList4 = ref([
againistRate: 5.5,
people: 1,
peopleRank: "1-2",
keyUser: keyUser,
},
keyUser: keyUser
}
]);
// 绘制echarts图表
......@@ -964,23 +537,11 @@ const setChart = (option, chartId) => {
const chartData1 = ref({
dataX: ["众议院通过", "参议院通过", "两院协商", "总统签署"],
dataY: [
[
23, 28, 92, 81, 64, 54, 72, 38, 39, 66, 90, 55, 68, 69, 82, 42, 47, 49,
85, 81,
],
[
31, 35, 67, 37, 80, 92, 110, 28, 55, 46, 81, 35, 46, 47, 49, 85, 84, 89,
55, 43,
],
[
20, 18, 62, 51, 33, 37, 39, 48, 59, 35, 36, 38, 60, 49, 42, 32, 25, 39,
55, 41,
],
[
20, 9, 18, 21, 28, 33, 30, 17, 12, 13, 20, 29, 28, 26, 12, 28, 26, 21, 32,
35,
],
],
[23, 28, 92, 81, 64, 54, 72, 38, 39, 66, 90, 55, 68, 69, 82, 42, 47, 49, 85, 81],
[31, 35, 67, 37, 80, 92, 110, 28, 55, 46, 81, 35, 46, 47, 49, 85, 84, 89, 55, 43],
[20, 18, 62, 51, 33, 37, 39, 48, 59, 35, 36, 38, 60, 49, 42, 32, 25, 39, 55, 41],
[20, 9, 18, 21, 28, 33, 30, 17, 12, 13, 20, 29, 28, 26, 12, 28, 26, 21, 32, 35]
]
});
const chartData2 = ref({
......@@ -988,112 +549,38 @@ const chartData2 = ref({
dataY: [
[12, 15, 32, 42, 37, 33, 21, 20, 14, 15, 18, 25, 35, 36, 37, 33, 44],
[23, 33, 21, 16, 18, 25, 28, 36, 33, 31, 30, 15, 16, 25, 23, 24, 20],
[20, 18, 33, 21, 20, 18, 19, 18, 29, 30, 27, 22, 21, 20, 22, 13, 17],
],
[20, 18, 33, 21, 20, 18, 19, 18, 29, 30, 27, 22, 21, 20, 22, 13, 17]
]
});
const chart2Data = ref([
{
name: "共和党",
value: "1550000",
},
{
name: "民主党",
value: "298000",
},
]);
// 耗时分析
const handleGetBillTimeAnalyze = async () => {
const params = {
id: window.sessionStorage.getItem('billId'),
id: window.sessionStorage.getItem("billId")
};
try {
const res = await getBillTimeAnalyze(params);
console.log("耗时分析", res);
chartData1.value.dataX = res.data.map((item) => {
chartData1.value.dataX = res.data.map(item => {
return item.lcmc;
});
chartData1.value.dataY = res.data.map((item) => {
chartData1.value.dataY = res.data.map(item => {
return [item.zdhs, item.zshs, item.pjs, item.pjx, item.zws, item.dysc];
});
dataList.value = res.data.map((item) => {
return {
name: item.lcmc,
data1: {
name: "中位数",
value: item.zws + "天",
},
data2: {
name: "平均耗时",
value: item.pjx + "-" + item.pjs + "天",
},
data3: {
name: "最短耗时",
value: item.zshs + "天",
},
data4: {
name: "本次耗时",
value: item.dysc ? item.dysc : "-" + "天",
},
};
});
} catch (error) {}
};
// 政治献金
const handleGetXj = async (personCongress) => {
const params = {
id: window.sessionStorage.getItem('billId'),
personCongress: personCongress,
};
try {
const res = await getBillXj(params);
console.log("政治献金", res);
box2DataList.value = res.data.map(item => {
return {
personId: item.personid,
name: item.name,
img: user1,
icon1: personCongress === '参议院' ? CYY : ZYY,
icon2: item.dp === '民主党' ? MZD : GHD,
position: item.zw,
money: `$${item.totalJe*10000}`,
content: `${item.totalEventId}项游说记录`
}
})
} catch (error) {}
};
// 党派政治献金
const handleGetTotalXj = async (personCongress) => {
const params = {
id: window.sessionStorage.getItem('billId'),
personCongress: personCongress,
};
try {
const res = await getBillTotalXj(params);
console.log("党派政治献金", res);
chart2Data.value = res.data.map((item) => {
return {
name: item.dp,
value: item.totalJe,
};
});
let chart2 = getPieChart(chart2Data.value);
setChart(chart2, "chart2");
} catch (error) {}
};
// 辩论投票时长
onMounted(async () => {
await handleGetBillTimeAnalyze();
handleGetXj("参议院");
let chart1 = getBoxPlotChcart(chartData1.value);
let chart1 = getBoxPlotChcart(chartData1.value, '天');
setChart(chart1, "chart1");
handleGetTotalXj("参议院");
let chart2 = getBoxPlotChcart(chartData2.value, '小时') ;
setChart(chart2, "chart2");
});
</script>
......@@ -1156,14 +643,19 @@ onMounted(async () => {
position: absolute;
top: 14px;
right: 12px;
width: 32px;
height: 32px;
display: flex;
justify-content: flex-end;
gap: 4px;
.icon {
width: 28px;
height: 28px;
img {
width: 100%;
height: 100%;
}
}
}
}
.left {
margin-top: 16px;
.box1 {
......@@ -1175,9 +667,8 @@ onMounted(async () => {
.box1-main {
height: 359px;
.box1-main-center {
width: 760px;
height: 300px;
margin: 0 50px;
margin: 0 5px;
overflow: hidden;
.box1-main-table {
display: flex;
......@@ -1297,7 +788,7 @@ onMounted(async () => {
height: 359px;
.box2-main-center {
height: 300px;
margin: 0 23px;
margin: 0 5px;
display: flex;
.box2-main-center-left {
width: 480px;
......
const getBoxPlotChcart = (data) => {
const getBoxPlotChcart = (data,unit) => {
let option = {
// title: [
// {
......@@ -34,7 +34,12 @@ const getBoxPlotChcart = (data) => {
},
yAxis: {
type: 'value',
name: '单位:天',
name: `单位:${unit}`,
nameTextStyle: {
padding: [0, 0, 0, 1520], // [上, 右, 下, 左]
verticalAlign: 'middle',
align: 'center'
},
splitArea: {
show: true
}
......
......@@ -4,7 +4,12 @@
<div class="header-left"></div>
<div class="title">流程概要</div>
<div class="header-right">
<img src="./assets/images/header-icon.png" alt="" />
<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="main">
......@@ -758,14 +763,19 @@ const handleClickDetail = (isShow) => {
position: absolute;
top: 14px;
right: 12px;
width: 32px;
height: 32px;
display: flex;
justify-content: flex-end;
gap: 4px;
.icon {
width: 28px;
height: 28px;
img {
width: 100%;
height: 100%;
}
}
}
}
.main {
margin-left: 59px;
height: 680px;
......
......@@ -5,7 +5,15 @@
<div class="header-left"></div>
<div class="title">涉及企业</div>
<div class="header-right">
<img src="../assets/images/header-icon.png" alt="" />
<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="left-top" id="chart1"></div>
......@@ -23,18 +31,16 @@
</div>
</div>
<div class="left-footer">
<div class="item-box">
<div
class="item"
:class="{ itemActive: companyActiveIndex === idx }"
@click="handleClickCompany(idx)"
v-for="(val, idx) in companyList"
v-for="(val, idx) in curCompanyList"
:key="idx"
>
<div class="id">{{ idx + 1 }}</div>
<div
class="title"
:class="{ titleActive: companyActiveIndex === idx }"
>
<div class="title" :class="{ titleActive: companyActiveIndex === idx }">
{{ val.name }}
</div>
<div class="icon">
......@@ -43,13 +49,36 @@
</div>
</div>
</div>
<div class="footer-box">
<div class="left">{{ `共${companyList.length}家企业` }}</div>
<div class="right">
<el-pagination
@current-change="handleCurrentChange"
:pageSize="pageSize"
:current-page="currentPage"
size="small"
background
layout="prev, pager, next"
:total="companyList.length"
/>
</div>
</div>
</div>
</div>
<div class="right">
<div class="box-header">
<div class="header-left"></div>
<div class="title">产业链分析</div>
<div class="header-right">
<img src="../assets/images/header-icon.png" alt="" />
<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-main">
......@@ -131,11 +160,7 @@
<div class="dialog-box1-title">{{ companyInfo.data1.title }}</div>
</div>
<div class="dialog-box1-main">
<div
class="item"
v-for="(val, idx) in companyInfo.data1.list"
:key="idx"
>
<div class="item" v-for="(val, idx) in companyInfo.data1.list" :key="idx">
<div class="item-left">
<!-- <img :src="uncheckIcon" alt=""> -->
<img :src="checkedIcon" alt="" />
......@@ -169,7 +194,7 @@
</template>
<script setup>
import { ref, onMounted, nextTick } from "vue";
import { ref, onMounted, nextTick, computed } from "vue";
import * as echarts from "echarts";
import { getCompanyList, getIndustryHyly, getHylyList } from "@/api/influence";
import getBarChart from "./utils/barChart";
......@@ -216,40 +241,22 @@ const chart1Data = ref({
const industryActiveIndex = ref(0);
const companyActiveIndex = ref(0);
const handleClickCompany = (index) => {
const handleClickCompany = index => {
companyActiveIndex.value = index;
isShowCompanyDialog.value = true;
setTimeout(() => {
const chart2Data = {
dataX: [
"2025-01",
"2025-02",
"2025-03",
"2025-04",
"2025-05",
"2025-06",
"2025-07",
"2025-08",
],
dataY: [1.2, 1.5, 1.4, 1.8, 1.3, 1.5, 1.6, 1.4],
dataX: ["2025-01", "2025-02", "2025-03", "2025-04", "2025-05", "2025-06", "2025-07", "2025-08"],
dataY: [1.2, 1.5, 1.4, 1.8, 1.3, 1.5, 1.6, 1.4]
};
let chart2 = getLineChart(chart2Data.dataX, chart2Data.dataY);
setChart(chart2, "chart2");
const chart3Data = {
name: [
"2023Q3",
"2023Q4",
"2024Q1",
"2024Q2",
"2024Q3",
"2024Q4",
"2025Q1",
"2025Q2",
],
value: [49, 53, 52, 54, 52, 50, 51, 54],
name: ["2023Q3", "2023Q4", "2024Q1", "2024Q2", "2024Q3", "2024Q4", "2025Q1", "2025Q2"],
value: [49, 53, 52, 54, 52, 50, 51, 54]
};
let chart3 = getBarChart1(chart3Data.name, chart3Data.value);
......@@ -257,7 +264,22 @@ const handleClickCompany = (index) => {
}, 100);
};
const companyList = ref([]);
const pageSize = ref(10);
const currentPage = ref(1);
const companyList = ref([]); // 企业列表
// 当前企业列表
const curCompanyList = computed(() => {
const startIndex = (currentPage.value - 1) * pageSize.value;
const endIndex = startIndex + pageSize.value;
return companyList.value.slice(startIndex, endIndex);
});
// 处理页码改变事件
const handleCurrentChange = page => {
currentPage.value = page;
};
const industryList = ref([
// {
......@@ -278,34 +300,25 @@ const companyInfo = ref({
list: [
"严格限制外国敏感实体(FEOC)参与补贴",
"取消电动汽车补贴(2025年底生效)",
"任何实体若与被禁止外国实体签订超100万美元的关键技术许可协议,则不得向其提供联邦补贴",
],
"任何实体若与被禁止外国实体签订超100万美元的关键技术许可协议,则不得向其提供联邦补贴"
]
},
data2: {
icon: icon2,
title: "融资情况",
data: {
time: ["2025-06", "2025-07", "2025-08"],
value: [1.12, 1.42, 1.5],
},
value: [1.12, 1.42, 1.5]
}
},
data3: {
icon: icon3,
title: "研发投入",
data: {
time: [
"2023Q3",
"2023Q4",
"2024Q1",
"2024Q2",
"2024Q3",
"2024Q4",
"2025Q1",
"2025Q2",
],
value: [50, 53, 52, 54, 58, 60, 51, 56, 64],
},
},
time: ["2023Q3", "2023Q4", "2024Q1", "2024Q2", "2024Q3", "2024Q4", "2025Q1", "2025Q2"],
value: [50, 53, 52, 54, 58, 60, 51, 56, 64]
}
}
});
// 获取行业领域列表
......@@ -323,7 +336,7 @@ const curHylyId = ref("");
// 根据行业领域id获取公司列表
const handleGetCompanyListById = async () => {
const params = {
id: curHylyId.value,
id: curHylyId.value
};
try {
const res = await getCompanyList(params);
......@@ -339,15 +352,15 @@ const handleGetCompanyListById = async () => {
// 根据法案ID 获取行业领域统计
const handleGetIndustryHyly = async () => {
const params = {
id: 1,
id: 1
};
try {
const res = await getIndustryHyly(params);
// console.log('行业领域统计', res);
chart1Data.value.name = res.data.map((item) => {
chart1Data.value.name = res.data.map(item => {
return item.hylyName;
});
chart1Data.value.value = res.data.map((item) => {
chart1Data.value.value = res.data.map(item => {
return item.companyNum;
});
} catch (error) {}
......@@ -393,14 +406,19 @@ onMounted(async () => {
position: absolute;
top: 14px;
right: 12px;
width: 32px;
height: 32px;
display: flex;
justify-content: flex-end;
gap: 4px;
.icon {
width: 28px;
height: 28px;
img {
width: 100%;
height: 100%;
}
}
}
}
.left {
margin-top: 16px;
width: 480px;
......@@ -414,11 +432,7 @@ onMounted(async () => {
box-sizing: border-box;
border: 1px solid rgba(231, 241, 255, 1);
border-radius: 4px;
background: linear-gradient(
180deg,
rgba(246, 251, 255, 1),
rgba(246, 251, 255, 0) 100%
);
background: linear-gradient(180deg, rgba(246, 251, 255, 1), rgba(246, 251, 255, 0) 100%);
}
.left-center {
margin-top: 12px;
......@@ -461,13 +475,15 @@ onMounted(async () => {
}
.left-footer {
margin: 0 auto;
margin-top: 5px;
width: 446px;
height: 520px;
overflow: auto;
overflow: hidden;
.item-box {
height: 480px;
overflow: hidden;
.item {
width: 100%;
height: 40px;
height: 48px;
border-radius: 4px;
border-bottom: 1px solid rgba(243, 243, 244, 1);
display: flex;
......@@ -521,6 +537,23 @@ onMounted(async () => {
color: rgba(22, 119, 255, 1) !important;
}
}
.footer-box {
display: flex;
justify-content: space-between;
.left {
width: 100px;
height: 20px;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-size: 14px;
font-weight: 400;
line-height: 20px;
}
.right {
flex: 300px;
}
}
}
}
.right {
margin-top: 16px;
......@@ -690,11 +723,7 @@ onMounted(async () => {
box-sizing: border-box;
border: 1px solid rgba(231, 241, 255, 1);
border-radius: 4px;
background: linear-gradient(
180deg,
rgba(246, 251, 255, 1),
rgba(246, 251, 255, 0) 100%
);
background: linear-gradient(180deg, rgba(246, 251, 255, 1), rgba(246, 251, 255, 0) 100%);
}
}
.dialog-box3 {
......@@ -731,11 +760,7 @@ onMounted(async () => {
box-sizing: border-box;
border: 1px solid rgba(231, 241, 255, 1);
border-radius: 4px;
background: linear-gradient(
180deg,
rgba(246, 251, 255, 1),
rgba(255, 255, 255, 0) 100%
);
background: linear-gradient(180deg, rgba(246, 251, 255, 1), rgba(255, 255, 255, 0) 100%);
}
}
}
......
......@@ -7,55 +7,36 @@
<div class="title">科研仪器依赖</div>
<div class="header-btn-box">
<div class="btn" @click="handleClickBox1Btn(1)">
<el-button type="primary" plain v-if="box1BtnActive === 1"
>仪器数量</el-button
>
<el-button type="primary" plain v-if="box1BtnActive === 1">仪器数量</el-button>
<el-button type="info" plain v-else>仪器数量</el-button>
</div>
<div class="btn" @click="handleClickBox1Btn(2)">
<el-button type="primary" plain v-if="box1BtnActive === 2"
>进口率</el-button
>
<el-button type="primary" plain v-if="box1BtnActive === 2">进口率</el-button>
<el-button type="info" plain v-else>进口率</el-button>
</div>
<div class="btn" @click="handleClickBox1Btn(3)">
<el-button type="primary" plain v-if="box1BtnActive === 3"
>仪器类型</el-button
>
<el-button type="primary" plain v-if="box1BtnActive === 3">仪器类型</el-button>
<el-button type="info" plain v-else>仪器类型</el-button>
</div>
<div class="btn" @click="handleClickBox1Btn(4)">
<el-button type="primary" plain v-if="box1BtnActive === 4"
>进口率变化</el-button
>
<el-button type="primary" plain v-if="box1BtnActive === 4">进口率变化</el-button>
<el-button type="info" plain v-else>进口率变化</el-button>
</div>
</div>
<div class="header-right">
<img src="./assets/images/header-icon.png" alt="" />
<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">
<div
id="chart1"
class="box1-chart"
v-show="box1BtnActive === 1"
></div>
<div
id="chart2"
class="box1-chart"
v-show="box1BtnActive === 2"
></div>
<div
id="chart3"
class="box1-chart"
v-show="box1BtnActive === 3"
></div>
<div
id="chart4"
class="box1-chart"
v-show="box1BtnActive === 4"
></div>
<div id="chart1" class="box1-chart" v-show="box1BtnActive === 1"></div>
<div id="chart2" class="box1-chart" v-show="box1BtnActive === 2"></div>
<div id="chart3" class="box1-chart" v-show="box1BtnActive === 3"></div>
<div id="chart4" class="box1-chart" v-show="box1BtnActive === 4"></div>
</div>
<div class="box1-footer">
......@@ -76,37 +57,29 @@
<div class="title">国际合作情况</div>
<div class="header-btn-box">
<div class="btn" @click="handleClickBox2Btn(1)">
<el-button type="primary" plain v-if="box2BtnActive === 1"
>国际项目</el-button
>
<el-button type="primary" plain v-if="box2BtnActive === 1">国际项目</el-button>
<el-button type="info" plain v-else>国际项目</el-button>
</div>
<div class="btn" @click="handleClickBox2Btn(2)">
<el-button type="primary" plain v-if="box2BtnActive === 2"
>合著论文</el-button
>
<el-button type="primary" plain v-if="box2BtnActive === 2">合著论文</el-button>
<el-button type="info" plain v-else>合著论文</el-button>
</div>
</div>
<div class="header-right">
<img src="./assets/images/header-icon.png" alt="" />
<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-left" id="chart5"></div>
<div class="box2-main-right" id="chart6"></div>
<div class="select-box">
<el-select
v-model="curYear"
placeholder="选择年份"
style="width: 100px"
>
<el-option
v-for="item in yearList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
<el-select v-model="curYear" placeholder="选择年份" style="width: 100px">
<el-option v-for="item in yearList" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</div>
</div>
......@@ -129,7 +102,12 @@
<div class="header-left"></div>
<div class="title">科研人才</div>
<div class="header-right">
<img src="./assets/images/header-icon.png" alt="" />
<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-main">
......@@ -143,35 +121,23 @@
</div>
<div class="box3-main-box1-btn-box">
<div class="btn" @click="handleClickBox3Btn(1)">
<el-button type="primary" plain v-if="box3BtnActive === 1"
>华裔科学家回流</el-button
>
<el-button type="primary" plain v-if="box3BtnActive === 1">华裔科学家回流</el-button>
<el-button type="info" plain v-else>华裔科学家回流</el-button>
</div>
<div class="btn" @click="handleClickBox3Btn(2)">
<el-button type="primary" plain v-if="box3BtnActive === 2"
>赴美STEM专业申请</el-button
>
<el-button type="info" plain v-else
>赴美STEM专业申请</el-button
>
<el-button type="primary" plain v-if="box3BtnActive === 2">赴美STEM专业申请</el-button>
<el-button type="info" plain v-else>赴美STEM专业申请</el-button>
</div>
<div class="btn" @click="handleClickBox3Btn(3)">
<el-button type="primary" plain v-if="box3BtnActive === 3"
>高端人才引进</el-button
>
<el-button type="primary" plain v-if="box3BtnActive === 3">高端人才引进</el-button>
<el-button type="info" plain v-else>高端人才引进</el-button>
</div>
<div class="btn" @click="handleClickBox3Btn(4)">
<el-button type="primary" plain v-if="box3BtnActive === 4"
>STEM专业拒签率</el-button
>
<el-button type="primary" plain v-if="box3BtnActive === 4">STEM专业拒签率</el-button>
<el-button type="info" plain v-else>STEM专业拒签率</el-button>
</div>
<div class="btn" @click="handleClickBox3Btn(5)">
<el-button type="primary" plain v-if="box3BtnActive === 5"
>H-1B中签率</el-button
>
<el-button type="primary" plain v-if="box3BtnActive === 5">H-1B中签率</el-button>
<el-button type="info" plain v-else>H-1B中签率</el-button>
</div>
</div>
......@@ -190,11 +156,7 @@
<div class="text">{{ "高被引学者数量" }}</div>
</div>
<div class="select-box">
<el-select
v-model="curYear"
placeholder="选择年份"
style="width: 100px"
>
<el-select v-model="curYear" placeholder="选择年份" style="width: 100px">
<el-option
v-for="item in yearList"
:key="item.value"
......@@ -236,18 +198,18 @@ import getLineChart from "./utils/lineChart";
import getMultiBarChart from "./utils/multiBarChart";
const box1BtnActive = ref(1);
const box2BtnActive = ref(1)
const box2BtnActive = ref(1);
const box3BtnActive = ref(1);
const handleClickBox2Btn = (index) => {
box2BtnActive.value = index
}
const handleClickBox2Btn = index => {
box2BtnActive.value = index;
};
const handleClickBox3Btn = (index) => {
const handleClickBox3Btn = index => {
box3BtnActive.value = index;
};
const handleClickBox1Btn = (index) => {
const handleClickBox1Btn = index => {
box1BtnActive.value = index;
if (index === 2) {
setTimeout(() => {
......@@ -261,10 +223,7 @@ const handleClickBox1Btn = (index) => {
});
} else if (index === 4) {
setTimeout(() => {
let chart4 = getMultiLineChart(
chart4Data.value.dataX,
chart4Data.value.value
);
let chart4 = getMultiLineChart(chart4Data.value.dataX, chart4Data.value.value);
setChart(chart4, "chart4");
});
} else {
......@@ -289,20 +248,20 @@ const curYear = ref("2025年");
const yearList = ref([
{
label: "2025年",
value: "2025年",
value: "2025年"
},
{
label: "2024年",
value: "2024年",
value: "2024年"
},
{
label: "2023年",
value: "2023年",
value: "2023年"
},
{
label: "2022年",
value: "2022年",
},
value: "2022年"
}
]);
const chart1Data = ref({
......@@ -316,9 +275,9 @@ const chart1Data = ref({
"南京大学",
"西北工业大学",
"北京理工大学",
"哈尔滨工业大学",
"哈尔滨工业大学"
],
value: [109, 95, 79, 66, 61, 54, 50, 48, 34, 32],
value: [109, 95, 79, 66, 61, 54, 50, 48, 34, 32]
});
const chart2Data = ref({
......@@ -332,82 +291,82 @@ const chart2Data = ref({
"计量仪器",
"物理性能测试仪器",
"海洋仪器",
"特种检测仪器",
"特种检测仪器"
],
value: [83.76, 76.72, 73.89, 72.16, 66.24, 65.47, 63.98, 62.12, 44.38, 24.79],
value: [83.76, 76.72, 73.89, 72.16, 66.24, 65.47, 63.98, 62.12, 44.38, 24.79]
});
const chart3Data = ref([
{
name: "大气探测仪器",
value: 24,
value: 24
// per: 8,
},
{
name: "空间与天文仪器",
value: 24,
value: 24
// per: 8,
},
{
name: "医学诊断仪器",
value: 24,
value: 24
// per: 8,
},
{
name: "核仪器",
value: 30,
value: 30
// per: 11,
},
{
name: "工艺试验设备",
value: 31,
value: 31
// per: 12,
},
{
name: "特种检测仪器",
value: 31,
value: 31
// per: 12,
},
{
name: "计算机及配套设备",
value: 31,
value: 31
// per: 12,
},
{
name: "激光器",
value: 32,
value: 32
// per: 14,
},
{
name: "分析仪器",
value: 38,
value: 38
// per: 21,
},
{
name: "物理性能测试仪器",
value: 48,
value: 48
// per: 21,
},
{
name: "计量仪器",
value: 52,
value: 52
// per: 18,
},
{
name: "电子测量仪器",
value: 43,
value: 43
// per: 18,
},
{
name: "海洋仪器",
value: 28,
value: 28
// per: 16,
},
{
name: "地球探测仪器",
value: 35,
value: 35
// per: 16,
},
}
]);
const chart4Data = ref({
......@@ -415,61 +374,61 @@ const chart4Data = ref({
value: [
{
name: "大气探测仪器",
dataY: [23, 35, 53, 42, 21, 12],
dataY: [23, 35, 53, 42, 21, 12]
},
{
name: "空间与天文仪器",
dataY: [34, 42, 46, 37, 26, 18],
dataY: [34, 42, 46, 37, 26, 18]
},
{
name: "医学诊断仪器",
dataY: [46, 55, 68, 72, 42, 33],
dataY: [46, 55, 68, 72, 42, 33]
},
{
name: "激光器",
dataY: [52, 56, 71, 44, 31, 18],
dataY: [52, 56, 71, 44, 31, 18]
},
{
name: "核仪器",
dataY: [14, 32, 45, 32, 27, 11],
dataY: [14, 32, 45, 32, 27, 11]
},
{
name: "工艺实验设备",
dataY: [35, 66, 78, 88, 53, 32],
dataY: [35, 66, 78, 88, 53, 32]
},
{
name: "特种检测仪器",
dataY: [28, 33, 56, 41, 32, 16],
dataY: [28, 33, 56, 41, 32, 16]
},
{
name: "计算机及配套设备",
dataY: [26, 45, 66, 52, 44, 25],
dataY: [26, 45, 66, 52, 44, 25]
},
{
name: "分析仪器",
dataY: [20, 54, 72, 66, 71, 55],
dataY: [20, 54, 72, 66, 71, 55]
},
{
name: "物理性能测试仪器",
dataY: [66, 54, 72, 55, 44, 23],
dataY: [66, 54, 72, 55, 44, 23]
},
{
name: "计量仪器",
dataY: [72, 33, 55, 21, 44, 18],
dataY: [72, 33, 55, 21, 44, 18]
},
{
name: "电子测量仪器",
dataY: [56, 31, 46, 12, 43, 23],
dataY: [56, 31, 46, 12, 43, 23]
},
{
name: "海洋仪器",
dataY: [55, 31, 48, 69, 42, 22],
dataY: [55, 31, 48, 69, 42, 22]
},
{
name: "地球探测仪器",
dataY: [24, 56, 72, 52, 36, 25],
},
],
dataY: [24, 56, 72, 52, 36, 25]
}
]
});
const chart5Data = ref({
name: [
......@@ -482,9 +441,9 @@ const chart5Data = ref({
"北京大学",
"南京大学",
"南开大学",
"天津大学",
"天津大学"
],
value: [35, 32, 28, 19, 17, 17, 17, 17, 17, 17],
value: [35, 32, 28, 19, 17, 17, 17, 17, 17, 17]
});
const chart6Data = ref([
......@@ -496,12 +455,12 @@ const chart6Data = ref([
{ name: "机器人", value: 41 },
{ name: "生命科学", value: 19 },
{ name: "自然科学", value: 14 },
{ name: "生物化学", value: 28 },
{ name: "生物化学", value: 28 }
]);
const chart7Data = ref({
dataX: ["2020", "2021", "2022", "2023", "2024", "2025"],
dataY: [456, 292, 298, 335, 316, 248],
dataY: [456, 292, 298, 335, 316, 248]
});
const chart8Data = ref([
......@@ -513,7 +472,7 @@ const chart8Data = ref([
{ name: "生物科技", value: 18 },
{ name: "人工智能", value: 31 },
{ name: "材料学", value: 33 },
{ name: "机器人", value: 25 },
{ name: "机器人", value: 25 }
]);
const chart9Data = ref({
......@@ -521,25 +480,25 @@ const chart9Data = ref({
value: [
{
name: "美国",
value: [77, 46, 56, 84, 72],
value: [77, 46, 56, 84, 72]
},
{
name: "中国",
value: [58, 65, 72, 80, 76],
value: [58, 65, 72, 80, 76]
},
{
name: "德国",
value: [53, 39, 47, 49, 30],
value: [53, 39, 47, 49, 30]
},
{
name: "日本",
value: [28, 35, 29, 29, 44],
value: [28, 35, 29, 29, 44]
},
{
name: "英国",
value: [27, 44, 32, 36, 35],
},
],
value: [27, 44, 32, 36, 35]
}
]
});
onMounted(() => {
......@@ -549,13 +508,13 @@ onMounted(() => {
let chart5 = getBarChart1(chart5Data.value.name, chart5Data.value.value);
setChart(chart5, "chart5");
let chart6 = getPieChart1(chart6Data.value, '40%', '52%', '30%');
let chart6 = getPieChart1(chart6Data.value, "40%", "52%", "30%");
setChart(chart6, "chart6");
let chart7 = getLineChart(chart7Data.value);
setChart(chart7, "chart7");
let chart8 = getPieChart1(chart8Data.value, '50%', '50%');
let chart8 = getPieChart1(chart8Data.value, "50%", "50%");
setChart(chart8, "chart8");
let chart9 = getMultiBarChart(chart9Data.value.dataX, chart9Data.value.value);
......@@ -593,7 +552,7 @@ onMounted(() => {
.header-btn-box {
position: absolute;
top: 14px;
right: 52px;
right: 84px;
display: flex;
.btn {
margin-left: 20px;
......@@ -603,14 +562,19 @@ onMounted(() => {
position: absolute;
top: 14px;
right: 12px;
width: 32px;
height: 32px;
display: flex;
justify-content: flex-end;
gap: 4px;
.icon {
width: 28px;
height: 28px;
img {
width: 100%;
height: 100%;
}
}
}
}
.left {
.box1 {
margin-top: 16px;
......
......@@ -6,7 +6,12 @@
<div class="header-left"></div>
<div class="title">基本信息</div>
<div class="header-right">
<img src="./assets/images/header-icon.png" alt="" />
<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">
......@@ -16,9 +21,7 @@
<div class="box1-right">
<div class="box1-right-item">
<div class="item-left">提案人:</div>
<div class="item-right">
乔迪·C·阿灵顿​(共和党-得克萨斯州第19选区)
</div>
<div class="item-right">乔迪·C·阿灵顿​(共和党-得克萨斯州第19选区)</div>
</div>
<div class="box1-right-item">
......@@ -41,9 +44,7 @@
<div class="item-left">提案人:</div>
<div class="item-right2">
<div class="right2-item">H. Rept. 119-106, Book 1</div>
<div class="right2-item">
H. Rept. 119-106, Book 2​(两份独立报告)
</div>
<div class="right2-item">H. Rept. 119-106, Book 2​(两份独立报告)</div>
</div>
</div>
<div class="box1-right-item">
......@@ -69,11 +70,7 @@
<el-step title="提交总统" />
<el-step title="法案通过" />
</el-steps> -->
<div
class="step"
v-for="(item, index) in stepList"
:key="index"
>
<div class="step" v-for="(item, index) in stepList" :key="index">
<div class="step-box" v-if="!item.active">
{{ item.title }}
<div class="right-arrow">
......@@ -99,58 +96,43 @@
<div class="header-btn-box">
<div class="btn" @click="handleClcikBox2Btn(1)">
<el-badge :value="warningNum">
<el-button type="primary" plain v-if="box2BtnActive === 1"
>最新进展</el-button
>
<el-button type="primary" plain v-if="box2BtnActive === 1">最新进展</el-button>
<el-button type="info" plain v-else>最新进展</el-button>
</el-badge>
</div>
<div class="btn" @click="handleClcikBox2Btn(2)">
<el-button type="primary" plain v-if="box2BtnActive === 2"
>前期进展</el-button
>
<el-button type="primary" plain v-if="box2BtnActive === 2">前期进展</el-button>
<el-button type="info" plain v-else>前期进展</el-button>
</div>
</div>
<div class="header-right">
<img src="./assets/images/header-icon.png" alt="" />
<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-center">
<STimeline v-if="box2BtnActive == 2" :dataList="timelineData" />
<div class="box2-center-item-box" v-if="box2BtnActive == 1">
<div
class="box2-center-item"
v-for="(item, index) in progressList"
:key="index"
>
<div class="box2-center-item" v-for="(item, index) in progressList" :key="index">
<div class="tip" :class="{ tipActive: item.fxdj }"></div>
<div class="date">{{ item.sjsj }}</div>
<div class="title">{{ item.sjnr }}</div>
<div class="info">
<div
class="info-box danger-box4"
v-if="item.fxdj === '特别重大风险'"
>
<div class="info-box danger-box4" v-if="item.fxdj === '特别重大风险'">
{{ item.fxdj }}
</div>
<div
class="info-box danger-box3"
v-if="item.fxdj === '重大风险'"
>
<div class="info-box danger-box3" v-if="item.fxdj === '重大风险'">
{{ item.fxdj }}
</div>
<div
class="info-box danger-box2"
v-if="item.fxdj === '较大风险'"
>
<div class="info-box danger-box2" v-if="item.fxdj === '较大风险'">
{{ item.fxdj }}
</div>
<div
class="info-box danger-box1"
v-if="item.fxdj === '低风险'"
>
<div class="info-box danger-box1" v-if="item.fxdj === '低风险'">
{{ item.fxdj }}
</div>
</div>
......@@ -173,7 +155,12 @@
<div class="header-left"></div>
<div class="title">提出人</div>
<div class="header-right">
<img src="./assets/images/header-icon.png" alt="" />
<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="introduction-wrap-right-main">
......@@ -185,12 +172,7 @@
style="width: 180px; margin: 0 10px"
@change="handleChangeFaId"
>
<el-option
v-for="item in faList"
:key="item.value"
:label="item.label"
:value="item.id"
/>
<el-option v-for="item in faList" :key="item.value" :label="item.label" :value="item.id" />
</el-select>
<div class="person-box">
<div
......@@ -243,7 +225,7 @@
status0: tag.status === 0,
status1: tag.status === 1,
status2: tag.status === 2,
status3: tag.status === 3,
status3: tag.status === 3
}"
v-for="(tag, index) in tagList"
:key="index"
......@@ -254,10 +236,7 @@
<div class="right-main-box3">
<div class="right-main-box3-header">
<div class="icon">
<img
src="./assets/images/right-main-box3-header-icon.png"
alt=""
/>
<img src="./assets/images/right-main-box3-header-icon.png" alt="" />
</div>
<div class="title">人物动态</div>
</div>
......@@ -335,7 +314,7 @@
status0: tag.status === 0,
status1: tag.status === 1,
status2: tag.status === 2,
status3: tag.status === 3,
status3: tag.status === 3
}"
v-for="(tag, index) in tagList"
:key="index"
......@@ -347,18 +326,10 @@
</div>
<div class="inner-right">
<div class="btn-box">
<div
class="btn"
:class="{ btnActive: dialogBoxBtnActive === 0 }"
@click="handleClcikDialogBoxBtn(0)"
>
<div class="btn" :class="{ btnActive: dialogBoxBtnActive === 0 }" @click="handleClcikDialogBoxBtn(0)">
新闻动态
</div>
<div
class="btn"
:class="{ btnActive: dialogBoxBtnActive === 1 }"
@click="handleClcikDialogBoxBtn(1)"
>
<div class="btn" :class="{ btnActive: dialogBoxBtnActive === 1 }" @click="handleClcikDialogBoxBtn(1)">
任务履历
</div>
</div>
......@@ -411,15 +382,10 @@
import { onMounted, ref } from "vue";
import WordCloudMap from "./WordCloudMap.vue";
import STimeline from "./STimeline.vue";
import {
getBillInfo,
getBillPerson,
getBillEvent,
getBillDyqk,
} from "@/api/bill";
import { getBillInfo, getBillPerson, getBillEvent, getBillDyqk } from "@/api/bill";
const box2BtnActive = ref(1);
const handleClcikBox2Btn = (index) => {
const handleClcikBox2Btn = index => {
box2BtnActive.value = index;
};
......@@ -431,55 +397,55 @@ const handleClcikBox3Btn = (name, index) => {
};
const dialogBoxBtnActive = ref(0);
const handleClcikDialogBoxBtn = (index) => {
const handleClcikDialogBoxBtn = index => {
dialogBoxBtnActive.value = index;
};
const tagList = ref([
{
title: "共和党",
status: 1,
status: 1
},
{
title: "委员会主席",
status: 0,
status: 0
},
{
title: "财政保守",
status: 2,
status: 2
},
{
title: "深红州",
status: 3,
status: 3
},
{
title: "社会政策激进",
status: 2,
status: 2
},
{
title: "预算委员会",
status: 3,
status: 3
},
{
title: "委员会主席",
status: 0,
status: 0
},
{
title: "深红州",
status: 3,
status: 3
},
{
title: "议程主导权",
status: 1,
status: 1
},
{
title: "财政保守",
status: 2,
status: 2
},
{
title: "传统能源",
status: 1,
},
status: 1
}
]);
const selectValue = ref("");
......@@ -495,7 +461,7 @@ const faList = ref([
// },
]);
const handleChangeFaId = (val) => {
const handleChangeFaId = val => {
console.log("val", val);
handleGetBillPerson(val);
};
......@@ -504,28 +470,28 @@ const progressList = ref([
{
sjsj: "7月5日",
sjnr: "特朗普于美国独立日签署法案,​公法编号Pub. L. No. 119-21。白宫举行庆典,B-2轰炸机飞越上空,象征“美国新时代”开启。",
fxdj: "特别重大风险",
fxdj: "特别重大风险"
},
{
sjsj: "7月4日",
sjnr: "众议院最终表决218票赞成 vs 214票反对,修订版法案以4票优势通过,2名共和党议员倒戈,民主党全员反对。",
fxdj: "重大风险",
fxdj: "重大风险"
},
{
sjsj: "7月3日",
sjnr: "民主党领袖杰弗里斯发表 ​8小时45分钟​ 演讲(众议院现代史最长),抗议法案“劫贫济富”,但仍未阻止表决。",
fxdj: "较大风险",
fxdj: "较大风险"
},
{
sjsj: "7月2日",
sjnr: "众议院以 ​219:213​ 通过程序规则,为最终表决铺路。此前4名共和党议员反对程序规则,议长约翰逊紧急游说挽回1票。",
fxdj: "低风险",
fxdj: "低风险"
},
{
sjsj: "7月1日",
sjnr: "参议院最终表决投票51:50​,副总统万斯(JD Vance)投出关键票打破平局。3名共和党参议员倒戈(蒂利斯、保罗、柯林斯)。",
fxdj: "",
},
fxdj: ""
}
]);
const wordCloudData = [
......@@ -540,34 +506,34 @@ const wordCloudData = [
{ name: "强硬边境政策", value: 34 },
{ name: "扩大军费", value: 16 },
{ name: "债务与赤字警告", value: 72 },
{ name: "批评美国债务膨胀", value: 58 },
{ name: "批评美国债务膨胀", value: 58 }
];
const stepList = ref([
{
title: "提出",
active: false,
active: false
},
{
title: "众议院通过",
active: false,
active: false
},
{
title: "参议院通过",
active: false,
active: false
},
{
title: "分歧协调",
active: false,
active: false
},
{
title: "提交总统",
active: false,
active: false
},
{
title: "法案通过",
active: true,
},
active: true
}
]);
const timelineData = ref([]);
......@@ -581,7 +547,7 @@ const handleClickMore2 = () => {
// 获取基本信息
const handleGetBasicInfo = async () => {
const params = {
id: window.sessionStorage.getItem("billId"),
id: window.sessionStorage.getItem("billId")
};
try {
const res = await getBillInfo(params);
......@@ -597,13 +563,13 @@ const warningNum = ref(0);
const handleGetBillEvent = async () => {
warningNum.value = 0;
const params = {
id: window.sessionStorage.getItem("billId"),
id: window.sessionStorage.getItem("billId")
};
try {
const res = await getBillEvent(params);
console.log("最新进展", res);
progressList.value = res.data;
progressList.value.forEach((item) => {
progressList.value.forEach(item => {
if (item.fxdj) {
warningNum.value++;
}
......@@ -616,17 +582,17 @@ const handleGetBillEvent = async () => {
// 法案进展 获取前期进展 --也是提出人左上角列表
const handleGetBillDyqk = async () => {
const params = {
id: window.sessionStorage.getItem("billId"),
id: window.sessionStorage.getItem("billId")
};
try {
const res = await getBillDyqk(params);
console.log("前期进展", res);
timelineData.value = res.data;
faList.value = res.data.map((item) => {
faList.value = res.data.map(item => {
return {
label: item.dyms,
value: item.dyms,
id: item.id,
id: item.id
};
});
selectValue.value = faList.value[0];
......@@ -643,9 +609,9 @@ const curPerson = ref({});
const personEventList = ref([]);
// 提出人 --动议id
const handleGetBillPerson = async (id) => {
const handleGetBillPerson = async id => {
const params = {
id: id,
id: id
};
try {
const res = await getBillPerson(params);
......@@ -696,7 +662,7 @@ onMounted(() => {
.header-btn-box {
position: absolute;
top: 14px;
right: 52px;
right: 86px;
display: flex;
.btn {
margin-left: 20px;
......@@ -706,11 +672,16 @@ onMounted(() => {
position: absolute;
top: 14px;
right: 12px;
width: 32px;
height: 32px;
img {
display: flex;
justify-content: flex-end;
gap: 4px;
.icon{
width: 28px;
height: 28px;
img{
width: 100%;
height: 100%;
}
}
}
}
......
......@@ -4,49 +4,30 @@
<div class="box-header">
<div class="box-header-left"></div>
<div class="box-header-title">主要条款</div>
<div class="box-header-btn-box">
<div class="box-header-btn-box"></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 class="box-header-icon">
<img src="./assets/icons/header-icon.png" alt="" />
</div>
</div>
<div class="left-top">
<el-select
v-model="curBill"
placeholder="请选择"
style="width: 240px"
@change="handleChangeBill"
>
<el-option
v-for="item in billList"
:key="item.value"
:label="item.label"
:value="item.id"
/>
<el-select v-model="curBill" placeholder="请选择" style="width: 240px" @change="handleChangeBill">
<el-option v-for="item in billList" :key="item.value" :label="item.label" :value="item.id" />
</el-select>
<el-checkbox
style="margin-left: 30px"
v-model="checkedValue"
label="只看涉华条款"
size="large"
/>
<el-checkbox style="margin-left: 30px" v-model="checkedValue" label="只看涉华条款" size="large" />
<div class="search" style="width: 240px; margin-left: 475px">
<el-input
v-model="searchValue"
style="width: 240px"
placeholder="搜索条款"
/>
<el-input v-model="searchValue" style="width: 240px" placeholder="搜索条款" />
<div class="icon">
<img src="./assets/icons/search-icon.png" alt="" />
</div>
</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="index">
<div class="id">{{ index + 1 }}</div>
<div class="info">
<div class="title">
......@@ -69,7 +50,7 @@
tag3: val.status === 3,
tag4: val.status === 4,
tag5: val.status === 5,
tag6: val.status === 6,
tag6: val.status === 6
}"
>
{{ val.name }}
......@@ -94,8 +75,16 @@
<div class="box-header">
<div class="box-header-left"></div>
<div class="box-header-title">限制方式</div>
<div class="box-header-icon">
<img src="./assets/icons/header-icon.png" alt="" />
<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>
......@@ -103,9 +92,7 @@
<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-center">通过关税壁垒、技术脱钩、新能源打压、地缘捆绑遏制中国产业链发展</div>
<div class="right-box1-footer-right">
<img src="./assets/icons/arrow-right.png" alt="" />
</div>
......@@ -115,8 +102,16 @@
<div class="box-header">
<div class="box-header-left"></div>
<div class="box-header-title">涉及行业</div>
<div class="box-header-icon">
<img src="./assets/icons/header-icon.png" alt="" />
<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>
......@@ -124,9 +119,7 @@
<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-center">系统性挤压中国新能源、跨境电商及高端制造的在美生存空间。</div>
<div class="right-box2-footer-right">
<img src="./assets/icons/arrow-right.png" alt="" />
</div>
......@@ -140,44 +133,38 @@
import { ref, onMounted } from "vue";
import * as echarts from "echarts";
import getPieChart from "./utils/piechart";
import {
getBillContentId,
getBillContentTk,
getBillContentXzfs,
getBillHyly,
} from "@/api/bill";
import { getBillContentId, getBillContentTk, getBillContentXzfs, getBillHyly } from "@/api/bill";
const curBill = ref("");
const curBillId = ref(null);
const billList = ref([
{
value: "公法(2025年7月4日)",
label: "公法(2025年7月4日)",
label: "公法(2025年7月4日)"
},
{
value: "公法(2025年7月8日)",
label: "公法(2025年7月8日)",
},
label: "公法(2025年7月8日)"
}
]);
const mainTermsList = ref([
{
id: 1,
title:
"废除价值800美元以下进口包裹的免税政策,改为征收30%关税或每件25-50美元费用。",
title: "废除价值800美元以下进口包裹的免税政策,改为征收30%关税或每件25-50美元费用。",
header: "第51255条",
headerEn: "Sec.51225",
content: "Elimination of De Minimis Rule for imports valued below $800.",
tags: [
{
name: "关税",
status: 2,
status: 2
},
{
name: "跨境电商",
status: 1,
},
],
status: 1
}
]
},
{
id: 2,
......@@ -188,14 +175,13 @@ const mainTermsList = ref([
tags: [
{
name: "关税",
status: 2,
},
],
status: 2
}
]
},
{
id: 3,
title:
"第50404条:若美企与中企签订超100万美元技术许可协议,将丧失政府补贴资格。",
title: "第50404条:若美企与中企签订超100万美元技术许可协议,将丧失政府补贴资格。",
header: "第51255条",
headerEn: "Sec.51225",
content:
......@@ -203,50 +189,47 @@ const mainTermsList = ref([
tags: [
{
name: "技术封锁",
status: 6,
},
],
status: 6
}
]
},
{
id: 4,
title: "第4502条:2025年9月30日后终止电动汽车消费者税收抵免。",
header: "第51255条",
headerEn: "Sec.51225",
content:
"Sec.4502. Termination of electric vehicle consumer tax credits after September 30, 2025.",
content: "Sec.4502. Termination of electric vehicle consumer tax credits after September 30, 2025.",
tags: [
{
name: "税收",
status: 2,
status: 2
},
{
name: "新能源",
status: 1,
},
],
status: 1
}
]
},
{
id: 5,
title: "2026年1月1日起对使用进口组件的光伏项目征收15%消费税。",
header: "第51255条",
headerEn: "Sec.51225",
content:
"Imposition of 15% excise tax on solar projects using imported components after January 1, 2026.",
content: "Imposition of 15% excise tax on solar projects using imported components after January 1, 2026.",
tags: [
{
name: "供应链打压",
status: 3,
status: 3
},
{
name: "光伏",
status: 1,
},
],
status: 1
}
]
},
{
id: 6,
title:
"若风电/光伏项目中受关注外国实体(FEOC)组件成本占比超标(如2026年太阳能为40%),则取消税收抵免。",
title: "若风电/光伏项目中受关注外国实体(FEOC)组件成本占比超标(如2026年太阳能为40%),则取消税收抵免。",
header: "第51255条",
headerEn: "Sec.51225",
content:
......@@ -254,18 +237,17 @@ const mainTermsList = ref([
tags: [
{
name: "供应链打压",
status: 3,
status: 3
},
{
name: "光伏",
status: 1,
},
],
status: 1
}
]
},
{
id: 7,
title:
"第50401条:2025年起,若电池中关键矿物由受关注外国实体(FEOC)提取、加工或回收,则该车辆无法享受税收抵免。",
title: "第50401条:2025年起,若电池中关键矿物由受关注外国实体(FEOC)提取、加工或回收,则该车辆无法享受税收抵免。",
header: "第51255条",
headerEn: "Sec.51225",
content:
......@@ -273,18 +255,17 @@ const mainTermsList = ref([
tags: [
{
name: "供应链打压",
status: 3,
status: 3
},
{
name: "新能源",
status: 1,
},
],
status: 1
}
]
},
{
id: 8,
title:
"Sec. 50401. No tax credit shall be allowed for any vehicle placed in service after December 31, 2024, if any of the...",
title: "Sec. 50401. No tax credit shall be allowed for any vehicle placed in service after December 31, 2024, if any of the...",
header: "第51255条",
headerEn: "Sec.51225",
content:
......@@ -292,14 +273,13 @@ const mainTermsList = ref([
tags: [
{
name: "新能源",
status: 1,
},
],
status: 1
}
]
},
{
id: 9,
title:
"第4501条:芯片企业税收抵免提至35%,但禁止在中国大陆扩大先进制程生产。",
title: "第4501条:芯片企业税收抵免提至35%,但禁止在中国大陆扩大先进制程生产。",
header: "第51255条",
headerEn: "Sec.51225",
content:
......@@ -307,13 +287,13 @@ const mainTermsList = ref([
tags: [
{
name: "技术封锁",
status: 5,
status: 5
},
{
name: "半导体",
status: 4,
},
],
status: 4
}
]
},
{
id: 10,
......@@ -325,17 +305,17 @@ const mainTermsList = ref([
tags: [
{
name: "拨款",
status: 2,
status: 2
},
{
name: "军工",
status: 6,
},
],
},
status: 6
}
]
}
]);
const btnActiveIndex = ref(1);
const handleSelectBtn = (index) => {
const handleSelectBtn = index => {
btnActiveIndex.value = index;
};
......@@ -346,25 +326,11 @@ const chart1Data = ref([
{ name: "对台军售", value: 32 },
{ name: "关税贸易", value: 50 },
{ name: "技术封锁", value: 46 },
{ name: "供应链打压", value: 40 },
]);
const chart1ColorList = ref([
"#4096ff",
"#b37feb",
"#ff7875",
"#85a5ff",
"#69b1ff",
"#ffc069",
"#87e8de",
{ name: "供应链打压", value: 40 }
]);
const chart1ColorList = ref(["#4096ff", "#b37feb", "#ff7875", "#85a5ff", "#69b1ff", "#ffc069", "#87e8de"]);
const chart2ColorList = ref([
"#ff7875",
"#85a5ff",
"#95de64",
"#ffc069",
"#85e5db",
]);
const chart2ColorList = ref(["#ff7875", "#85a5ff", "#95de64", "#ffc069", "#85e5db"]);
const chart2Data = ref([
// { name: "军工", value: 85 },
......@@ -384,23 +350,23 @@ const setChart = (option, chartId) => {
};
// 切换原文
const handleChangeBill = (val) => {
const handleChangeBill = val => {
curBillId.value = val;
};
// 获取法案id列表
const handleGetBillList = async () => {
const params = {
id: window.sessionStorage.getItem('billId'),
id: window.sessionStorage.getItem("billId")
};
try {
const res = await getBillContentId(params);
console.log("法案id列表", res);
billList.value = res.data.map((item) => {
billList.value = res.data.map(item => {
return {
label: item.bbmc,
value: item.bbmc,
id: item.ywid,
id: item.ywid
};
});
curBill.value = billList.value[0].label;
......@@ -409,12 +375,12 @@ const handleGetBillList = async () => {
};
// 根据原文ID获取条款列表
const handleGetBillContentTk = async (cRelated) => {
const handleGetBillContentTk = async cRelated => {
const params = {
id: curBillId.value,
cRelated: cRelated,
currentPage: 0,
pageSize: 10,
pageSize: 10
};
try {
const res = await getBillContentTk(params);
......@@ -425,16 +391,16 @@ const handleGetBillContentTk = async (cRelated) => {
// 获取限制方式列表
const handleGetBillContentXzfs = async () => {
const params = {
id: window.sessionStorage.getItem('billId'),
id: window.sessionStorage.getItem("billId")
};
try {
const res = await getBillContentXzfs(params);
console.log("限制方式", res);
chart1Data.value = res.data.map((item) => {
chart1Data.value = res.data.map(item => {
return {
name: item.xzfsmc,
value: item.countTk,
value: item.countTk
};
});
} catch (error) {}
......@@ -443,7 +409,7 @@ const handleGetBillContentXzfs = async () => {
// 行业领域
const handleGetBillHyly = async () => {
const params = {
id: window.sessionStorage.getItem('billId'),
id: window.sessionStorage.getItem("billId")
};
try {
......@@ -452,10 +418,10 @@ const handleGetBillHyly = async () => {
chart2Data.value = res.data.map(item => {
return {
name: item.hylymc,
value: item.countTk,
value: item.countTk
};
});
console.log('chart2Data', chart2Data.value);
console.log("chart2Data", chart2Data.value);
let chart2 = getPieChart(chart2Data.value, chart2ColorList.value);
setChart(chart2, "chart2");
......@@ -509,18 +475,23 @@ onMounted(async () => {
padding: 0;
}
}
.box-header-icon {
.header-right {
position: absolute;
top: 14px;
right: 12px;
width: 32px;
height: 32px;
display: flex;
justify-content: flex-end;
gap: 4px;
.icon {
width: 28px;
height: 28px;
img {
width: 100%;
height: 100%;
}
}
}
}
.left {
margin-top: 16px;
width: 1150px;
......@@ -584,8 +555,8 @@ onMounted(async () => {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
.title-active{
color: var(--color-main-active)
.title-active {
color: var(--color-main-active);
}
}
.content {
......@@ -600,8 +571,8 @@ onMounted(async () => {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
.content-active{
color: var(--color-main-active)
.content-active {
color: var(--color-main-active);
}
}
}
......
<template>
<div class="wrapper">
<div class="header"><span>首页 </span>> <span>综合检索 </span>> <span>智能问答 </span></div>
<div class="header">
<!-- <span>首页 </span>> <span>综合检索 </span>> <span>智能问答 </span> -->
<div class="header-item">首页</div>
<div class="header-item">></div>
<div class="header-item back-item" @click="handleBackHome">综合检索</div>
<div class="header-item">></div>
<div class="header-item">智能问答</div>
</div>
<div class="main">
<div class="left">
<div class="left-header">
......@@ -37,9 +44,20 @@
<div class="icon">
<img src="./assets/images/ai-avator.png" alt="" />
</div>
<div class="text">{{ `已深度思考(用时6秒钟)` }}</div>
<div class="text">{{ `已深度思考` }}</div>
</div>
<div class="content ai-content" v-html="renderMarkdown(message.content)"></div>
<div v-if="message.think" class="think-title">思考内容</div>
<div
v-if="message.think"
class="content think-content"
v-html="renderMarkdown(message.think)"
></div>
<div v-if="message.content" class="answer-title">正文内容</div>
<div
v-if="message.content"
class="content ai-content"
v-html="renderMarkdown(message.content)"
></div>
</div>
<!-- 用户消息 -->
<div v-else class="user-item">
......@@ -67,7 +85,7 @@
</div>
</div>
<div class="right-main-footer">
<el-input type="textarea" placeholder="发送消息" :rows="4" v-model="userInput" />
<el-input @keyup.enter="sendMessage" type="textarea" placeholder="发送消息" :rows="4" v-model="userInput" />
<div class="input-footer">
<div class="icon1">
<el-tooltip effect="dark" content="录音" placement="top">
......@@ -94,11 +112,20 @@
</template>
<script setup>
import { ref, onMounted, onUnmounted } from "vue";
import { ref, onMounted, onUnmounted, nextTick } from "vue";
import { fetchEventSource } from "@microsoft/fetch-event-source";
import MarkdownIt from "markdown-it";
import { ElMessage } from "element-plus";
import { getChat } from "@/api/chat";
import router from "@/router/index";
import json5 from "json5";
// 返回综合检索
const handleBackHome = () => {
router.push({
path: "/comprehensiveSearch"
});
};
const contentContainer = ref(null);
......@@ -149,11 +176,38 @@ const addMessage = (type, content) => {
const updateLastAIMessage = content => {
const lastMessage = messages.value[messages.value.length - 1];
if (lastMessage && lastMessage.type === "ai") {
if (isCurAnswerMessage.value) {
lastMessage.content = content;
} else {
lastMessage.think = content;
}
scrollToBottom();
}
};
let aiMessage = ref("");
const isCurAnswerMessage = ref(false);
function parseOuterOnly(json5String, maxDepth = 1) {
let currentDepth = 0;
return json5.parse(json5String, (key, value) => {
// 检查当前深度
if (currentDepth > maxDepth) {
return value; // 超过最大深度,直接返回值
}
// 如果是对象或数组,增加深度计数
if (typeof value === "object" && value !== null) {
currentDepth++;
}
return value;
});
}
// 使用 fetchEventSource 连接
const connectSSE = async question => {
// 添加用户消息
......@@ -168,68 +222,71 @@ const connectSSE = async question => {
abortController.value = new AbortController();
const params = {
query: "如何检索?",
knowledge_base_name: "kb_test251112",
top_k: 6,
score_threshold: 0.5,
metadata: { year: 2024 }
// question: "川普1期对华制裁领域分布情况"
question: question
// knowledge_base_name: "kb_test251112",
// top_k: 6,
// score_threshold: 0.5,
// metadata: { year: 2024 }
};
try {
await fetchEventSource("/chat/knowledge_base/search_docs", {
fetchEventSource("/sseChat/rag/chat/stream", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(params),
signal: abortController.value.signal,
onopen: async response => {
console.log("SSE 连接已建立", response.status);
if (response.status !== 200) {
throw new Error(`请求失败: ${response.status}`);
}
},
onmessage: event => {
try {
if (event.data === "[DONE]") {
// 流式输出结束
openWhenHidden: true,
async onopen(res) {
isLoading.value = false;
console.log("流式回答开始", res);
},
async onmessage(res) {
console.log("res", res);
let msgData = parseOuterOnly(res.data);
if (res.event === "end_of_workflow") {
ElMessage.success("问答完成!");
abortController.value.abort();
abortController.value = new AbortController();
return;
}
const data = JSON.parse(event.data);
if (data.type === "content" && data.content) {
// 流式更新内容
updateLastAIMessage(prev => prev + data.content);
} else if (data.type === "error") {
throw new Error(data.message || "请求失败");
if (res.event === "start_of_agent" && msgData.agent_name === "answer") {
isCurAnswerMessage.value = true;
aiMessage.value = "";
}
if (res.event === "message") {
let content = msgData.delta.content;
console.log("msgData", msgData);
console.log("content", content);
if (content !== "[DONE]") {
aiMessage.value += content;
updateLastAIMessage(aiMessage.value);
} else {
aiMessage.value = "";
abortController.value.abort();
abortController.value = new AbortController();
}
} catch (error) {
console.error("解析 SSE 数据错误:", error);
}
},
onclose: () => {
console.log("SSE 连接已关闭");
isLoading.value = false;
},
onerror: error => {
console.error("SSE 连接错误:", error);
ElMessage.error("连接失败,请重试");
isLoading.value = false;
// 不要抛出错误,否则会重试
}
onerror(error) {
ElMessage({
message: "问答报错!",
type: "warning"
});
} catch (error) {
console.error("SSE 请求失败:", error);
if (error.name !== "AbortError") {
ElMessage.error(error.message || "请求失败");
}
isLoading.value = false;
abortController.value.abort();
abortController.value = new AbortController();
throw new Error(error);
}
}).catch(error => {
ElMessage({
message: "问答报错!",
type: "warning"
});
abortController.value.abort();
abortController.value = new AbortController();
throw new Error(error);
});
};
const chat = async () => {
......@@ -281,7 +338,7 @@ const chatList = ref([
},
{
id: 3,
title: "列举 2025 年科技产品"
title: "列举2025年科技产品"
},
{
id: 4,
......@@ -368,6 +425,16 @@ onUnmounted(() => {
background: url("../assets/images/header-bg.png");
box-sizing: border-box;
padding-left: 160px;
display: flex;
.header-item {
margin: 0 3px;
}
.back-item {
cursor: pointer;
&:hover {
color: #ccc;
}
}
}
.main {
margin-top: 16px;
......@@ -536,10 +603,27 @@ onUnmounted(() => {
/* 对话内容区域 */
.chat-content {
overflow-x: hidden;
overflow-y: auto;
// padding: 20px;
background: #fff;
width: 926px;
width: 1118px;
padding-right: 192px;
box-sizing: border-box;
height: 620px;
.chat-content::-webkit-scrollbar {
width: 30px;
}
.chat-content::-webkit-scrollbar-thumb {
background: #000;
border-radius: 3px;
}
.chat-content::-webkit-scrollbar-thumb:hover {
background: #555;
}
.message-list {
padding-bottom: 20px;
}
......@@ -569,10 +653,43 @@ onUnmounted(() => {
text-align: left;
}
}
.think-title {
margin-left: 26px;
height: 22px;
color: rgba(132, 136, 142, 1);
font-family: Microsoft YaHei;
font-size: 14px;
font-weight: 400;
line-height: 22px;
letter-spacing: 0px;
text-align: left;
}
.answer-title {
margin-top: 10px;
margin-left: 26px;
height: 22px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 18px;
font-weight: 700;
line-height: 24px;
letter-spacing: 0px;
text-align: left;
}
.think-content {
background: rgba(245, 245, 245, 0.5);
width: 900px;
margin-left: 26px;
padding: 1px 10px;
border-radius: 5px;
}
.ai-content {
margin-top: 10px;
width: 900px;
margin-left: 26px;
background: rgba(246, 250, 255, 1);
padding: 1px 10px;
border-radius: 5px;
}
}
.user-item {
......
<template>
<div class="wrapper">
<div class="header"><span>首页 </span>> <span>综合检索 </span></div>
<div class="header">
<!-- <span>首页 </span>> <span>综合检索 </span> -->
<div class="header-item">首页</div>
<div class="header-item">></div>
<div class="header-item">综合检索</div>
</div>
<div class="main">
<div class="main-header">
<div class="title">{{ "一站式信息智能检索子系统" }}</div>
......@@ -92,7 +97,9 @@
tag2: item.tag.status === 2,
tag3: item.tag.status === 3
}"
>{{ item.tag.name }}</div>
>
{{ item.tag.name }}
</div>
</div>
</div>
</div>
......@@ -112,7 +119,7 @@
<script setup>
import { ref, onMounted } from "vue";
import router from '@/router/index'
import router from "@/router/index";
import getWordCloudChart from "./utils/wordCloud";
import setChart from "@/utils/setChart";
......@@ -122,7 +129,6 @@ import Img3 from "./assets/images/box3-img3.png";
import Img4 from "./assets/images/box3-img4.png";
import Img5 from "./assets/images/box3-img5.png";
const headerInfoList = ref([
{
name: "美国",
......@@ -221,7 +227,6 @@ const box2Data = ref([
{ name: "加强供应链风险管理", value: 73 }
]);
const box3List = ref([
{
img: Img1,
......@@ -282,23 +287,21 @@ const box3List = ref([
// 点击智能问答,进入智能问答页
const handleToChat = () => {
router.push({
path: '/chat'
})
}
path: "/chat"
});
};
// 点击全文搜索,进入搜索结果页
const handleToSearchResults = () => {
router.push({
path: '/searchResults'
})
}
path: "/searchResults"
});
};
onMounted(() => {
const box2Chart = getWordCloudChart(box2Data.value)
setChart(box2Chart, 'box2Chart')
})
const box2Chart = getWordCloudChart(box2Data.value);
setChart(box2Chart, "box2Chart");
});
</script>
<style lang="scss" scoped>
......@@ -354,6 +357,16 @@ onMounted(() => {
background: url("./assets/images/header-bg.png");
box-sizing: border-box;
padding-left: 160px;
display: flex;
.header-item {
margin: 0 3px;
}
.back-item {
cursor: pointer;
&:hover {
color: #ccc;
}
}
}
.main {
width: 100%;
......@@ -602,7 +615,7 @@ onMounted(() => {
border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background: rgba(255, 255, 255, 1);
.box2-main{
.box2-main {
height: 390px;
}
}
......
......@@ -32,8 +32,11 @@
<div class="home-main" :class="{ scrollHomeMain: isShow }" ref="containerRef">
<div class="home-main-header">
<div class="home-main-header-top" v-show="!isShow">
<span>国家科技安全 </span>> <span>中美博弈概览 </span>>
<span>科技政令</span>
<div class="header-item">国家科技安全</div>
<div class="header-item">></div>
<div class="header-item back-item" @click="handleBackHome">中美博弈概览</div>
<div class="header-item">></div>
<div class="header-item">行政令</div>
</div>
<div class="home-main-header-center" v-show="!isShow">
<el-input v-model="input" style="width: 838px; height: 100%" placeholder="搜索科技政令" />
......@@ -638,6 +641,13 @@ import Message1 from "./assets/images/message-icon1.png";
import Message2 from "./assets/images/message-icon2.png";
import Message3 from "./assets/images/message-icon3.png";
// 返回首页
const handleBackHome = () => {
router.push({
path: '/overview'
})
}
const containerRef = ref(null);
const { isShow } = useContainerScroll(containerRef);
const currentPage = ref(1);
......@@ -855,7 +865,6 @@ const keyDecreeList = ref([
}
]);
// 政令重点条款
const wordCloudData = [
{ name: "与马斯克公开冲突", value: 100 },
......@@ -1024,7 +1033,6 @@ const handleClickCate = cate => {
activeCate.value = cate;
};
const calendarData = ref([
["2025-01-01", 20],
["2025-01-05", 120],
......@@ -1205,6 +1213,16 @@ onMounted(async () => {
color: #fff;
box-sizing: border-box;
padding-left: 160px;
display: flex;
.header-item {
margin: 0 3px;
}
.back-item {
cursor: pointer;
&:hover {
color: #ccc;
}
}
}
.home-main-header-center {
margin-top: 48px;
......
......@@ -118,7 +118,7 @@
</div>
</div>
</div>
<div class="tool-box">
<!-- <div class="tool-box">
<div class="tool1">
<img src="./assets/icons/tool-icon1.png" alt="" />
</div>
......@@ -128,7 +128,7 @@
<div class="tool3">
<img src="./assets/icons/tool-icon3.png" alt="" />
</div>
</div>
</div> -->
</div>
</template>
......@@ -622,49 +622,49 @@ onMounted(() => {
}
}
}
.tool-box {
position: fixed;
z-index: 10000;
bottom: 80px;
left: 0;
width: 48px;
height: 144px;
border-radius: 0px 10px 10px 0px;
box-shadow: 0px 0px 15px 0px rgba(22, 119, 255, 0.1);
background: rgba(255, 255, 255, 1);
.tool1 {
width: 17px;
height: 18px;
margin-top: 17px;
margin-left: 16px;
cursor: pointer;
img {
width: 100%;
height: 100%;
}
}
.tool2 {
width: 22px;
height: 20px;
margin-top: 26px;
margin-left: 14px;
cursor: pointer;
img {
width: 100%;
height: 100%;
}
}
.tool3 {
width: 20px;
height: 20px;
margin-top: 25px;
margin-left: 15px;
cursor: pointer;
img {
width: 100%;
height: 100%;
}
}
}
// .tool-box {
// position: fixed;
// z-index: 10000;
// bottom: 80px;
// left: 0;
// width: 48px;
// height: 144px;
// border-radius: 0px 10px 10px 0px;
// box-shadow: 0px 0px 15px 0px rgba(22, 119, 255, 0.1);
// background: rgba(255, 255, 255, 1);
// .tool1 {
// width: 17px;
// height: 18px;
// margin-top: 17px;
// margin-left: 16px;
// cursor: pointer;
// img {
// width: 100%;
// height: 100%;
// }
// }
// .tool2 {
// width: 22px;
// height: 20px;
// margin-top: 26px;
// margin-left: 14px;
// cursor: pointer;
// img {
// width: 100%;
// height: 100%;
// }
// }
// .tool3 {
// width: 20px;
// height: 20px;
// margin-top: 25px;
// margin-left: 15px;
// cursor: pointer;
// img {
// width: 100%;
// height: 100%;
// }
// }
// }
}
</style>
\ No newline at end of file
......@@ -13,7 +13,12 @@
/>
</div>
<div class="header-right">
<img src="./assets/images/header-right-icon.png" alt="" />
<div class="header-right-icon">
<img src="@/assets/icons/box-header-icon2.png" alt="" />
</div>
<div class="header-right-icon">
<img src="@/assets/icons/box-header-icon3.png" alt="" />
</div>
</div>
</div>
<div class="box1-top" id="chart1"></div>
......@@ -65,7 +70,12 @@
<div class="title">{{ "政令举措落实分析" }}</div>
<div class="header-right1"></div>
<div class="header-right">
<img src="./assets/images/header-right-icon.png" alt="" />
<div class="header-right-icon">
<img src="@/assets/icons/box-header-icon2.png" alt="" />
</div>
<div class="header-right-icon">
<img src="@/assets/icons/box-header-icon3.png" alt="" />
</div>
</div>
</div>
......@@ -108,7 +118,12 @@
<div class="title">{{ "历史相似举措及落实情况" }}</div>
<div class="header-right1"></div>
<div class="header-right">
<img src="./assets/images/header-right-icon.png" alt="" />
<div class="header-right-icon">
<img src="@/assets/icons/box-header-icon2.png" alt="" />
</div>
<div class="header-right-icon">
<img src="@/assets/icons/box-header-icon3.png" alt="" />
</div>
</div>
</div>
<div class="box3-main">
......@@ -318,20 +333,25 @@ onMounted(() => {
line-height: 24px;
}
.header-right {
position: absolute;
top: 14px;
right: 12px;
position: absolute;
width: 28px;
display: flex;
justify-content: flex-end;
gap: 4px;
.header-right-icon{
width: 28px;
img {
height: 28px;
img{
width: 100%;
height: 100%;
}
}
}
.header-right1 {
position: absolute;
top: 8px;
right: 60px;
right: 84px;
}
}
.left {
......
<template>
<div class="home-wrapper">
<div class="home-header">
<span>国家科技安全 </span>> <span>中美博弈概览 </span>>
<span>出口管制 </span>
<div class="header-item">国家科技安全</div>
<div class="header-item">></div>
<div class="header-item back-item" @click="handleBackHome">中美博弈概览</div>
<div class="header-item">></div>
<div class="header-item">出口管制</div>
</div>
<div class="home-main">
<div class="home-main-header">
......@@ -655,12 +658,19 @@ import shoushiIcon from "./assets/images/shoushi.png";
import tianyiIcon from "./assets/images/tianyi.png";
import aircasIcon from "./assets/images/aircas.png";
const handleToDetail = () => {
// 返回首页
const handleBackHome = () => {
router.push({
path: '/exportControl/analysis'
path: '/overview'
})
}
const handleToDetail = () => {
router.push({
path: "/exportControl/analysis"
});
};
const billList = ref([]);
const curBillListIndex = ref(0);
......@@ -1591,6 +1601,16 @@ onMounted(async () => {
background: url("@/assets/images/nav-bg.png");
box-sizing: border-box;
padding-left: 160px;
display: flex;
.header-item {
margin: 0 3px;
}
.back-item {
cursor: pointer;
&:hover {
color: #ccc;
}
}
}
.box1 {
......
......@@ -7,7 +7,6 @@
</template>
<script setup>
import { defineProps, defineEmits } from "vue";
import { ArrowRight } from "@element-plus/icons-vue";
import { useRouter } from "vue-router";
......
<template>
<div class="home-wrapper">
<div class="home-header">
<span>国家科技安全 </span>> <span>中美博弈概览 </span>>
<span>投融资限制 </span>
<!-- <span>国家科技安全 </span>> <span>中美博弈概览 </span>>
<span>投融资限制 </span> -->
<div class="header-item">国家科技安全</div>
<div class="header-item">></div>
<div class="header-item back-item" @click="handleBackHome">中美博弈概览</div>
<div class="header-item">></div>
<div class="header-item">投融资限制</div>
</div>
<div class="home-main">
<div class="home-main-header">
......@@ -655,6 +660,13 @@ import shoushiIcon from "./assets/images/shoushi.png";
import tianyiIcon from "./assets/images/tianyi.png";
import aircasIcon from "./assets/images/aircas.png";
// 返回首页
const handleBackHome = () => {
router.push({
path: '/overview'
})
}
const handleToDetail = () => {
router.push({
path: "/exportControl/analysis"
......@@ -1591,6 +1603,16 @@ onMounted(async () => {
background: url("@/assets/images/nav-bg.png");
box-sizing: border-box;
padding-left: 160px;
display: flex;
.header-item {
margin: 0 3px;
}
.back-item {
cursor: pointer;
&:hover {
color: #ccc;
}
}
}
.box1 {
......
......@@ -3,8 +3,13 @@
<div class="home-main">
<div class="home-main-header">
<div class="home-main-header-top">
<span>国家科技安全 </span>> <span>中美博弈概览 </span>>
<span>市场准入限制</span>
<!-- <span>国家科技安全 </span>> <span>中美博弈概览 </span>>
<span>市场准入限制</span> -->
<div class="header-item">国家科技安全</div>
<div class="header-item">></div>
<div class="header-item back-item" @click="handleBackHome">中美博弈概览</div>
<div class="header-item">></div>
<div class="header-item">市场准入限制</div>
</div>
<div class="home-main-header-center">
<el-input v-model="input" style="width: 838px; height: 100%" placeholder="搜索市场准入限制调查" />
......@@ -37,8 +42,65 @@
<div class="item-footer">分析报告</div>
</div>
</div>
<div class="home-main-header-btn-box">
<div class="btn">
<div class="btn-text">{{ "最新动态" }}</div>
<div class="btn-icon">{{ ">" }}</div>
</div>
<div class="btn">
<div class="btn-text">{{ "资讯要闻" }}</div>
<div class="btn-icon">{{ ">" }}</div>
</div>
<div class="btn">
<div class="btn-text">{{ "统计概览" }}</div>
<div class="btn-icon">{{ ">" }}</div>
</div>
<div class="btn">
<div class="btn-text">{{ "资源库" }}</div>
<div class="btn-icon">{{ ">" }}</div>
</div>
</div>
<div class="home-main-header-card-box">
<div class="home-main-header-card-box-box1">
<div class="header">
<div class="header-left">{{ "301调查" }}</div>
<div class="header-right">{{ "52项" }}</div>
</div>
<div class="content-box">
<div class="item">{{ "可能措施: 加征关税、限制进口" }}</div>
<div class="item">
{{ '依据《1974年贸易法》第301条针对"不合理或不公正贸易做法"' }}
</div>
</div>
</div>
<div class="home-main-header-card-box-box2">
<div class="header">
<div class="header-left">{{ "232调查" }}</div>
<div class="header-right">{{ "3项" }}</div>
</div>
<div class="content-box">
<div class="item">{{ "可能措施: 加征关税、限制进口" }}</div>
<div class="item">
{{ "依据《1962年贸易扩展法》第232条评估进口产品对国家安全影响" }}
</div>
</div>
</div>
<div class="home-main-header-card-box-box3">
<div class="header">
<div class="header-left">{{ "337调查" }}</div>
<div class="header-right">{{ "87项" }}</div>
</div>
<div class="content-box">
<div class="item">{{ "可能措施: 排除令、禁止令" }}</div>
<div class="item">
{{ "依据《1930年关税法》第337条针对知识产权侵权行为" }}
</div>
</div>
</div>
</div>
</div>
<div class="home-main-center">
<DivideHeader class="divide-header" :titleText="'最新动态'"></DivideHeader>
<div class="center-top">
<div class="box1">
<div class="box1-left">
......@@ -159,44 +221,58 @@
</div>
</div>
</div>
<DivideHeader class="divide-header" :titleText="'资讯要闻'"></DivideHeader>
<div class="center-center">
<div class="center-center-box1">
<div class="header">
<div class="header-left">{{ "301调查" }}</div>
<div class="header-right">{{ "52项" }}</div>
<div class="box3">
<div class="box3-header">
<div class="box3-header-left">
<div class="box3-header-icon">
<img src="./assets/images/header-news.png" alt="" />
</div>
<div class="content-box">
<div class="item">{{ "可能措施: 加征关税、限制进口" }}</div>
<div class="item">
{{ '依据《1974年贸易法》第301条针对"不合理或不公正贸易做法"' }}
<div class="box3-header-title">{{ "新闻资讯" }}</div>
<div class="more">{{ "更多 +" }}</div>
</div>
</div>
<div class="box3-main">
<div class="box3-item" v-for="(news, index) in newsList" :key="index">
<div class="left">
<img :src="news.img" alt="" />
</div>
<div class="center-center-box2">
<div class="header">
<div class="header-left">{{ "232调查" }}</div>
<div class="header-right">{{ "3项" }}</div>
<div class="right">
<div class="right-top">
<div class="title">{{ news.title }}</div>
<div class="time">{{ news.from }}</div>
</div>
<div class="content-box">
<div class="item">{{ "可能措施: 加征关税、限制进口" }}</div>
<div class="item">
{{ "依据《1962年贸易扩展法》第232条评估进口产品对国家安全影响" }}
<div class="right-footer">{{ news.content }}</div>
</div>
</div>
</div>
<div class="center-center-box3">
<div class="header">
<div class="header-left">{{ "337调查" }}</div>
<div class="header-right">{{ "87项" }}</div>
</div>
<div class="content-box">
<div class="item">{{ "可能措施: 排除令、禁止令" }}</div>
<div class="item">
{{ "依据《1930年关税法》第337条针对知识产权侵权行为" }}
<div class="box4">
<div class="box4-header">
<div class="header-icon">
<img src="./assets/images/header-message.png" alt="" />
</div>
<div class="header-title">{{ "社交媒体" }}</div>
<div class="more">{{ "更多 +" }}</div>
</div>
<div class="box4-main">
<div class="box4-main-item" v-for="(item, index) in messageList" :key="index">
<div class="left">
<img :src="item.img" alt="" />
</div>
<div class="right">
<div class="right-top">
<div class="name">{{ item.name }}</div>
<div class="time">{{ item.time }}</div>
</div>
<div class="content">{{ item.content }}</div>
</div>
</div>
</div>
</div>
</div>
<DivideHeader class="divide-header" :titleText="'数据总览'"></DivideHeader>
<div class="center-footer">
<div class="box3">
<div class="box3-header">
......@@ -240,6 +316,7 @@
</div>
<div class="home-main-footer">
<DivideHeader class="divide-header" :titleText="'资源库'"></DivideHeader>
<div class="home-main-footer-header">
<div class="btn-box">
<div
......@@ -348,10 +425,28 @@
import { onMounted, ref } from "vue";
import * as echarts from "echarts";
import router from "@/router";
import DivideHeader from "@/components/DivideHeader.vue";
import getMultiLineChart from "./utils/multiLineChart";
import getPieChart from "./utils/piechart";
import News1 from "./assets/images/news1.png";
import News2 from "./assets/images/news2.png";
import News3 from "./assets/images/news3.png";
import News4 from "./assets/images/news4.png";
import News5 from "./assets/images/news5.png";
import Message1 from "./assets/images/message-icon1.png";
import Message2 from "./assets/images/message-icon2.png";
import Message3 from "./assets/images/message-icon3.png";
// 返回首页
const handleBackHome = () => {
router.push({
path: '/overview'
})
}
const handleClickToDetail = () => {
router.push("/marketAccessLayout");
};
......@@ -649,6 +744,64 @@ const surveyInfoList = ref([
}
]);
// 新闻资讯
const newsList = ref([
{
img: News1,
title: "美政府停摆仍持续,拨款法案存缺陷,但两党磋商露曙光",
content: `美国政府停摆已持续34天,距离历史上最长的停摆纪录仅差一天,参议院已先后13次尝试...`,
from: "11-4 · 华盛顿邮报"
},
{
img: News2,
title: "美参议院通过决议,要求终止特朗普全球关税政策",
content: `参议院以51票赞成、47票反对通过一项决议,旨在终止特朗普实施的全面关税政策,四名......`,
from: "11-4 · 纽约时报"
},
{
img: News3,
title: "美众院通过950亿美元对外援助法案,包含对台军援",
content: `国会众议院在4月通过了大规模对外援助法案,其中包括为“印太安全”提供资金的条款,......`,
from: "11-3 · 洛杉矶时报"
},
{
img: News4,
title: "“大而美”法案在激烈争议中通过",
content: `特朗普力推的大规模税收与支出法案在国会以微弱优势通过。该法案因大幅削减医疗补助和......`,
from: "11-3 · 今日美国"
},
{
img: News5,
title: "美政府“停摆”追平历史最长纪录,民生多领域受重创",
content: `联邦政府“停摆”进入第35天,追平历史纪录。食品救济项目资金中断,数百万低收入民......`,
from: "11-2 · ​福克斯新闻网"
}
]);
// 社交媒体
const messageList = ref([
{
img: Message1,
name: "唐纳德·特朗普",
time: "15:23 · 发布于真实社交",
content: `埃隆·马斯克在强力支持我竞选总统之前,早就知道我强烈反对‘电动汽车强制令’。这太荒谬了,这一直是我竞选活动的主要部分。电动汽车没问题,但不应该强迫每个人都拥有一辆。埃隆获得的补贴可能远远超过历史上任何一个人。如果没有补贴,埃隆可能不得不关门大吉,回到南非老家。`
},
{
img: Message2,
name: "埃隆·马斯克",
time: "14:49 · 发布于X",
content: `如果这个疯狂的支出法案获得通过,‘美国党’将在第二天成立。`
},
{
img: Message3,
name: "塞巴斯蒂安·马拉比",
time: "11:05 · 发布于X",
content: `提出特朗普政府的AI政策强调技术开放与快速应用,但可能以牺牲安全防范为代价,开启了“潘多拉魔盒”。`
}
]);
// 获取热门法案
onMounted(async () => {
let chart1 = getMultiLineChart(
chart1Data.value.title,
......@@ -693,6 +846,16 @@ onMounted(async () => {
font-weight: 700;
color: #fff;
padding-left: 160px;
display: flex;
.header-item {
margin: 0 3px;
}
.back-item {
cursor: pointer;
&:hover {
color: #ccc;
}
}
}
.home-main-header-center {
margin-top: 48px;
......@@ -737,10 +900,9 @@ onMounted(async () => {
}
.home-main-header-footer {
margin-top: 38px;
width: 960px;
width: 688px;
height: 64px;
box-sizing: border-box;
padding: 0 108px;
display: flex;
justify-content: space-between;
.home-main-header-footer-item {
......@@ -754,14 +916,225 @@ onMounted(async () => {
font-weight: 700;
line-height: 22px;
}
.item-footer {
margin-top: 10px;
height: 30px;
.item-footer {
margin-top: 10px;
height: 30px;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 30px;
}
}
}
.home-main-header-btn-box {
width: 688px;
margin: 0 auto;
margin-top: 39px;
display: flex;
justify-content: space-between;
.btn {
display: flex;
width: 140px;
height: 36px;
border: 1px solid #aed6ff;
box-sizing: border-box;
border-radius: 18px;
justify-content: center;
background: #e7f3ff;
position: relative;
cursor: pointer;
&:hover {
background: #cae3fc;
}
.btn-text {
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 400;
line-height: 36px;
margin-left: 5px;
}
.btn-icon {
height: 20px;
line-height: 20px;
position: absolute;
top: 6px;
right: 8px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 400;
}
}
}
.home-main-header-card-box {
width: 1600px;
margin: 0 auto;
height: 142px;
margin-top: 64px;
display: flex;
justify-content: space-between;
.home-main-header-card-box-box1 {
width: 520px;
height: 142px;
background: #fff;
border-radius: 4px;
box-shadow: 0px 0px 15px 0px rgba(60, 87, 126, 0.2);
position: relative;
&::before {
content: "";
position: absolute;
z-index: 99;
left: 0;
top: 15px;
width: 4px;
height: 111px;
background: rgba(250, 140, 22, 1);
}
.header {
height: 56px;
display: flex;
justify-content: space-between;
.header-left {
margin-left: 30px;
margin-top: 26px;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 700;
line-height: 26px;
}
.header-right {
margin-top: 28px;
margin-right: 35px;
height: 24px;
color: rgba(250, 140, 22, 1);
font-family: Microsoft YaHei;
font-size: 30px;
font-weight: 700;
line-height: 24px;
}
}
.content-box {
margin-left: 30px;
.item {
height: 24px;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 24px;
margin-top: 8px;
}
}
}
.home-main-header-card-box-box2 {
width: 520px;
height: 142px;
background: #fff;
border-radius: 4px;
box-shadow: 0px 0px 15px 0px rgba(60, 87, 126, 0.2);
position: relative;
&::before {
content: "";
position: absolute;
z-index: 99;
left: 0;
top: 15px;
width: 4px;
height: 111px;
background: rgba(114, 46, 209, 1);
}
.header {
height: 56px;
display: flex;
justify-content: space-between;
.header-left {
margin-left: 30px;
margin-top: 26px;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 700;
line-height: 26px;
}
.header-right {
margin-top: 28px;
margin-right: 35px;
height: 24px;
color: rgba(114, 46, 209, 1);
font-family: Microsoft YaHei;
font-size: 30px;
font-weight: 700;
line-height: 24px;
}
}
.content-box {
margin-left: 30px;
.item {
height: 24px;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 24px;
margin-top: 8px;
}
}
}
.home-main-header-card-box-box3 {
width: 520px;
height: 142px;
background: #fff;
border-radius: 4px;
box-shadow: 0px 0px 15px 0px rgba(60, 87, 126, 0.2);
position: relative;
&::before {
content: "";
position: absolute;
z-index: 99;
left: 0;
top: 15px;
width: 4px;
height: 111px;
background: rgba(10, 87, 166, 1);
}
.header {
height: 56px;
display: flex;
justify-content: space-between;
.header-left {
margin-left: 30px;
margin-top: 26px;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 700;
line-height: 26px;
}
.header-right {
margin-top: 28px;
margin-right: 35px;
height: 24px;
color: rgba(10, 87, 166, 1);
font-family: Microsoft YaHei;
font-size: 30px;
font-weight: 700;
line-height: 24px;
}
}
.content-box {
margin-left: 30px;
.item {
height: 24px;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 30px;
line-height: 24px;
margin-top: 8px;
}
}
}
}
......@@ -1131,171 +1504,227 @@ onMounted(async () => {
}
}
.center-center {
width: 1600px;
margin: 24px auto;
height: 142px;
margin-top: 24px;
margin-top: 21px;
height: 450px;
display: flex;
justify-content: center;
.box3 {
width: 792px;
height: 450px;
box-shadow: 0px 0px 15px 0px rgba(25, 69, 130, 0.2);
background: rgba(255, 255, 255, 1);
.box3-header {
height: 48px;
border-bottom: 1px solid rgba(240, 242, 244, 1);
margin: 0 auto;
display: flex;
justify-content: space-between;
.center-center-box1 {
width: 520px;
height: 142px;
background: #fff;
border-radius: 4px;
box-shadow: 0px 0px 15px 0px rgba(60, 87, 126, 0.2);
padding: 0 20px;
position: relative;
&::before {
content: "";
position: absolute;
z-index: 99;
left: 0;
top: 15px;
width: 4px;
height: 111px;
background: rgba(250, 140, 22, 1);
}
.header {
height: 56px;
.box3-header-left {
display: flex;
justify-content: space-between;
.header-left {
margin-left: 30px;
margin-top: 26px;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 700;
line-height: 26px;
.box3-header-icon {
margin-top: 16px;
width: 19px;
height: 19px;
img {
width: 100%;
height: 100%;
}
.header-right {
margin-top: 28px;
margin-right: 35px;
height: 24px;
color: rgba(250, 140, 22, 1);
}
.box3-header-title {
margin-top: 16px;
margin-left: 19px;
height: 22px;
color: rgba(20, 89, 187, 1);
font-family: Microsoft YaHei;
font-size: 30px;
font-size: 20px;
font-weight: 700;
line-height: 24px;
}
line-height: 22px;
}
.content-box {
margin-left: 30px;
.item {
.more {
width: 49px;
height: 24px;
color: rgba(95, 101, 108, 1);
position: absolute;
top: 14px;
right: 27px;
color: rgba(20, 89, 187, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 24px;
margin-top: 8px;
cursor: pointer;
}
}
}
.center-center-box2 {
width: 520px;
height: 142px;
background: #fff;
border-radius: 4px;
box-shadow: 0px 0px 15px 0px rgba(60, 87, 126, 0.2);
position: relative;
&::before {
content: "";
position: absolute;
z-index: 99;
left: 0;
top: 15px;
width: 4px;
height: 111px;
background: rgba(114, 46, 209, 1);
.box3-main {
height: 402px;
overflow-y: auto;
overflow-x: hidden;
padding-top: 6px;
.box3-item {
display: flex;
height: 77px;
width: 749px;
margin-left: 21px;
border-bottom: 1px solid rgba(240, 242, 244, 1);
.left {
width: 72px;
height: 48px;
margin-top: 15px;
img {
width: 100%;
height: 100%;
}
.header {
height: 56px;
}
.right {
width: 657px;
margin-left: 20px;
.right-top {
width: 657px;
display: flex;
justify-content: space-between;
.header-left {
margin-left: 30px;
margin-top: 26px;
.title {
margin-top: 13px;
width: 520px;
height: 24px;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 20px;
font-size: 16px;
font-weight: 700;
line-height: 26px;
line-height: 24px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.header-right {
margin-top: 28px;
margin-right: 35px;
height: 24px;
color: rgba(114, 46, 209, 1);
.time {
flex: 1;
text-align: right;
height: 22px;
margin-top: 19px;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-size: 30px;
font-weight: 700;
line-height: 24px;
font-size: 14px;
font-weight: 400;
line-height: 22px;
}
}
.content-box {
margin-left: 30px;
.item {
.right-footer {
width: 657px;
height: 24px;
color: rgba(95, 101, 108, 1);
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 24px;
margin-top: 8px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
}
.center-center-box3 {
width: 520px;
height: 142px;
background: #fff;
border-radius: 4px;
box-shadow: 0px 0px 15px 0px rgba(60, 87, 126, 0.2);
position: relative;
&::before {
content: "";
position: absolute;
z-index: 99;
left: 0;
top: 15px;
width: 4px;
height: 111px;
background: rgba(10, 87, 166, 1);
}
.header {
height: 56px;
}
.box4 {
margin-left: 20px;
width: 792px;
height: 450px;
box-shadow: 0px 0px 15px 0px rgba(25, 69, 130, 0.2);
background: rgba(255, 255, 255, 1);
.box4-header {
width: 792px;
height: 48px;
border-bottom: 1px solid rgba(240, 242, 244, 1);
display: flex;
justify-content: space-between;
.header-left {
margin-left: 30px;
margin-top: 26px;
color: rgba(59, 65, 75, 1);
box-sizing: border-box;
padding-left: 22px;
position: relative;
.header-icon {
margin-top: 15px;
width: 20px;
height: 20px;
img {
width: 100%;
height: 100%;
}
}
.header-title {
margin-top: 16px;
margin-left: 18px;
height: 22px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 700;
line-height: 26px;
line-height: 22px;
}
.header-right {
margin-top: 28px;
margin-right: 35px;
.more {
width: 49px;
height: 24px;
color: rgba(10, 87, 166, 1);
position: absolute;
top: 14px;
right: 27px;
color: rgba(20, 89, 187, 1);
font-family: Microsoft YaHei;
font-size: 30px;
font-weight: 700;
font-size: 16px;
font-weight: 400;
line-height: 24px;
cursor: pointer;
}
}
.content-box {
margin-left: 30px;
.item {
.box4-main {
height: 402px;
overflow-y: auto;
box-sizing: border-box;
padding-top: 8px;
.box4-main-item {
margin-top: 16px;
display: flex;
margin-left: 21px;
.left {
margin-top: 5px;
width: 36px;
height: 36px;
img {
width: 100%;
height: 100%;
}
}
.right {
margin-left: 10px;
width: 690px;
box-sizing: border-box;
border: 1px solid rgba(231, 243, 255, 1);
background: rgba(246, 250, 255, 1);
padding: 10px 15px;
.right-top {
display: flex;
justify-content: space-between;
.name {
height: 24px;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 700;
line-height: 24px;
}
.time {
height: 30px;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 30px;
}
}
.content {
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 24px;
margin-top: 8px;
}
}
}
}
}
......@@ -1321,22 +1750,23 @@ onMounted(async () => {
display: flex;
.box3-header-icon {
margin-top: 15px;
width: 13px;
height: 13px;
margin-left: 2px;
width: 19px;
height: 19px;
img {
width: 100%;
height: 100%;
}
}
.box3-header-title {
margin-top: 16px;
margin-left: 22px;
height: 22px;
margin-top: 12px;
margin-left: 19px;
height: 26px;
color: rgba(20, 89, 187, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-size: 20px;
font-weight: 700;
line-height: 22px;
line-height: 26px;
}
}
.box3-header-right {
......@@ -1385,8 +1815,8 @@ onMounted(async () => {
position: relative;
.header-icon {
margin-top: 18px;
width: 18px;
height: 18px;
width: 19px;
height: 19px;
img {
width: 100%;
height: 100%;
......@@ -1398,7 +1828,7 @@ onMounted(async () => {
height: 22px;
color: rgba(20, 89, 187, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-size: 20px;
font-weight: 700;
line-height: 22px;
}
......@@ -1418,8 +1848,9 @@ onMounted(async () => {
}
.home-main-footer {
// width: 100%;
height: 1059px;
height: 1149px;
background: rgba(248, 249, 250, 1);
overflow: hidden;
.home-main-footer-header {
width: 1600px;
height: 42px;
......@@ -1723,6 +2154,11 @@ onMounted(async () => {
}
}
}
.divide-header {
margin: 0 auto;
margin-top: 52px;
margin-bottom: 36px;
}
:deep(.el-input__wrapper) {
box-shadow: none;
}
......
......@@ -26,9 +26,16 @@
<div class="box-header">
<div class="header-left"></div>
<div class="title">美国对华337调查年度趋势</div>
<div class="header-right">
<img src="../assets/images/header-icon.png" alt="" />
<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="box1-main" id="chart1"></div>
......@@ -37,9 +44,16 @@
<div class="box-header">
<div class="header-left"></div>
<div class="title">调查案件领域分布</div>
<div class="header-right">
<img src="../assets/images/header-icon.png" alt="" />
<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="box2-main" id="chart2"></div>
......@@ -67,21 +81,21 @@
</div>
</div>
<div class="header-right">
<img src="../assets/images/header-icon.png" alt="" />
<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
v-show="btnActiveName === '调查次数'"
class="box3-main"
id="chart3"
></div>
<div class="icon">
<img src="@/assets/icons/box-header-icon3.png" alt="" />
</div>
</div>
</div>
<div v-show="btnActiveName === '调查次数'" class="box3-main" id="chart3"></div>
<div v-show="btnActiveName === '注册地分布'" class="box3-main1">
<div class="box3-main1-left">
<div
class="box3-main1-left-item"
v-for="(item, index) in mapData"
:key="index"
>
<div class="box3-main1-left-item" v-for="(item, index) in mapData" :key="index">
<div class="box3-main1-left-item-left">{{ index + 1 }}</div>
<div class="box3-main1-left-item-center">{{ item.name }}</div>
<div class="box3-main1-left-item-right">
......@@ -96,9 +110,16 @@
<div class="box-header">
<div class="header-left"></div>
<div class="title">调查结果分布</div>
<div class="header-right">
<img src="../assets/images/header-icon.png" alt="" />
<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="box4-main" id="chart4"></div>
......@@ -127,7 +148,7 @@ const setChart = (option, chartId) => {
};
const btnActiveName = ref("注册地分布");
const handleClickBox3Btn = (name) => {
const handleClickBox3Btn = name => {
btnActiveName.value = name;
if (name === "调查次数") {
nextTick(() => {
......@@ -143,26 +164,13 @@ const handleClickBox3Btn = (name) => {
};
const chart1Data = ref({
title: [
"2014",
"2015",
"2016",
"2017",
"2018",
"2019",
"2020",
"2021",
"2022",
"2023",
"2024",
"2025",
],
title: ["2014", "2015", "2016", "2017", "2018", "2019", "2020", "2021", "2022", "2023", "2024", "2025"],
data: [
{
name: "提出法案",
value: [145, 52, 84, 99, 71, 96, 128, 144, 140, 168, 188, 172],
},
],
value: [145, 52, 84, 99, 71, 96, 128, 144, 140, 168, 188, 172]
}
]
});
const chart2Data = ref([
......@@ -173,18 +181,9 @@ const chart2Data = ref([
{ name: "通信设备", value: 31 },
{ name: "汽车", value: 31 },
{ name: "轻工业制造", value: 30 },
{ name: "其他", value: 24 },
]);
const chart2ColorList = ref([
"#69B1FF",
"#FFC069",
"#87E8DE",
"#597EF7",
"#D6E4FF",
"#FF7875",
"#B37FEB",
"#FFA39E",
{ name: "其他", value: 24 }
]);
const chart2ColorList = ref(["#69B1FF", "#FFC069", "#87E8DE", "#597EF7", "#D6E4FF", "#FF7875", "#B37FEB", "#FFA39E"]);
const chart3Data = ref({
name: [
......@@ -195,9 +194,9 @@ const chart3Data = ref({
"联想集团",
"比亚迪集团",
"宁德时代新能源科技股份有限公司",
"晶科智能科技有限公司",
"晶科智能科技有限公司"
],
value: [42, 35, 28, 19, 15, 12, 11, 8],
value: [42, 35, 28, 19, 15, 12, 11, 8]
});
const mapData = ref([
......@@ -208,7 +207,7 @@ const mapData = ref([
{ name: "浙江", value: 20, coord: [120.19, 30.26] },
{ name: "四川", value: 4, coord: [104.06, 30.67] },
{ name: "陕西", value: 1, coord: [108.95, 34.27] },
{ name: "辽宁", value: 3, coord: [123.38, 41.8] },
{ name: "辽宁", value: 3, coord: [123.38, 41.8] }
// { name: "湖北", value: 2, coord: [114.31, 30.52] },
// { name: "山东", value: 12, coord: [117.0, 36.65] },
]);
......@@ -218,21 +217,12 @@ const chart4Data = ref([
{ name: "裁定不侵权", value: 46 },
{ name: "裁定侵权", value: 40 },
{ name: "申诉方撤诉", value: 31 },
{ name: "其他", value: 24 },
]);
const chart4ColorList = ref([
"#69B1FF",
"#FFC069",
"#87E8DE",
"#D6E4FF",
"#FFA39E",
{ name: "其他", value: 24 }
]);
const chart4ColorList = ref(["#69B1FF", "#FFC069", "#87E8DE", "#D6E4FF", "#FFA39E"]);
onMounted(() => {
let chart1 = getMultiLineChart(
chart1Data.value.title,
chart1Data.value.data[0].value
);
let chart1 = getMultiLineChart(chart1Data.value.title, chart1Data.value.data[0].value);
setChart(chart1, "chart1");
let chart2 = getPieChart(chart2Data.value, chart2ColorList.value);
......@@ -343,7 +333,7 @@ onMounted(() => {
.header-btn-box {
position: absolute;
top: 14px;
right: 52px;
right: 120px;
display: flex;
.btn {
margin-left: 8px;
......@@ -371,14 +361,19 @@ onMounted(() => {
position: absolute;
top: 14px;
right: 12px;
width: 32px;
height: 32px;
display: flex;
justify-content: flex-end;
gap: 4px;
.icon {
width: 28px;
height: 28px;
img {
width: 100%;
height: 100%;
}
}
}
}
.center {
display: flex;
justify-content: space-between;
......
......@@ -9,7 +9,15 @@
<div class="btn btnActive">{{ "半导体" }}</div>
</div>
<div class="header-right">
<img src="../assets/images/header-icon.png" alt="" />
<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="box1-main" id="chart1"></div>
......@@ -35,7 +43,15 @@
<div class="btn btnActive">{{ "半导体" }}</div>
</div>
<div class="header-right">
<img src="../assets/images/header-icon.png" alt="" />
<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="box2-main" id="chart2"></div>
......@@ -71,7 +87,15 @@
</div>
</div>
<div class="header-right">
<img src="../assets/images/header-icon.png" alt="" />
<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="box3-main">
......@@ -100,7 +124,15 @@
<div class="btn btnActive">{{ "半导体" }}</div>
</div>
<div class="header-right">
<img src="../assets/images/header-icon.png" alt="" />
<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="box4-main">
......@@ -342,7 +374,7 @@ onMounted(() => {
.header-btn-box {
position: absolute;
top: 14px;
right: 52px;
right: 116px;
display: flex;
.btn {
margin-left: 8px;
......@@ -366,44 +398,23 @@ onMounted(() => {
color: rgba(10, 87, 166, 1);
}
}
.header-info {
height: 22px;
position: absolute;
right: 56px;
top: 17px;
display: flex;
justify-content: flex-end;
.icon {
margin-top: 3px;
width: 14px;
height: 14px;
margin-right: 8px;
img {
width: 100%;
height: 100%;
}
}
.text {
height: 22px;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-size: 14px;
font-weight: 400;
line-height: 22px;
}
}
.header-right {
position: absolute;
top: 14px;
right: 12px;
width: 32px;
height: 32px;
img {
display: flex;
justify-content: flex-end;
gap: 4px;
.icon{
width: 28px;
height: 28px;
img{
width: 100%;
height: 100%;
}
}
}
}
.box {
width: 792px;
height: 410px;
......
......@@ -5,9 +5,16 @@
<div class="box-header">
<div class="header-left"></div>
<div class="title">基本信息</div>
<div class="header-right">
<img src="../assets/images/header-icon.png" alt="" />
<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="box1-main">
......@@ -67,9 +74,13 @@
<div class="box-header">
<div class="header-left"></div>
<div class="title">原告信息</div>
<div class="header-right">
<img src="../assets/images/header-icon.png" alt="" />
<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">
......@@ -114,7 +125,12 @@
<div class="text">{{ '以下为列名被告企业及其关联公司' }}</div>
</div>
<div class="header-right">
<img src="../assets/images/header-icon.png" alt="" />
<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-main">
......@@ -137,128 +153,126 @@
<script setup>
import { ref, onMounted } from "vue";
import Logo1 from './assets/images/logo1.png'
import Logo2 from './assets/images/logo2.png'
import Logo3 from './assets/images/logo3.png'
import Logo4 from './assets/images/logo4.png'
import Logo5 from './assets/images/logo5.png'
import Logo6 from './assets/images/logo6.png'
import Logo1 from "./assets/images/logo1.png";
import Logo2 from "./assets/images/logo2.png";
import Logo3 from "./assets/images/logo3.png";
import Logo4 from "./assets/images/logo4.png";
import Logo5 from "./assets/images/logo5.png";
import Logo6 from "./assets/images/logo6.png";
const processList = ref([
{
time: "2025-02-18",
title: "申请立案",
title: "申请立案"
},
{
time: "2025-03-21",
title: "立案",
title: "立案"
},
{
time: "2025-08-14",
title: "部分仲裁",
title: "部分仲裁"
},
{
time: "2025-09-18",
title: "部分终裁",
},
title: "部分终裁"
}
]);
const caseList = ref([
{
title:'一加(OnePlus)及相关企业',
title: "一加(OnePlus)及相关企业",
companyList: [
{
name: '深圳市万普拉斯科技有限公司 (中国广东)',
name: "深圳市万普拉斯科技有限公司 (中国广东)",
logo: Logo1
},
{
name: 'OnePlus USA Corp. (美国德州欧文)',
name: "OnePlus USA Corp. (美国德州欧文)",
logo: Logo1
},
}
]
},
{
title:'联想(Lenovo)及相关企业',
title: "联想(Lenovo)及相关企业",
companyList: [
{
name: '联想集团 (中国北京)',
name: "联想集团 (中国北京)",
logo: Logo2
},
{
name: 'Lenovo (United States) Inc. (美国北卡罗来纳州)',
name: "Lenovo (United States) Inc. (美国北卡罗来纳州)",
logo: Logo2
},
{
name: 'Motorola Mobility LLC (美国伊利诺伊州)',
name: "Motorola Mobility LLC (美国伊利诺伊州)",
logo: Logo2
},
}
]
},
{
title:'TCL及相关企业',
title: "TCL及相关企业",
companyList: [
{
name: 'TCL实业控股股份有限公司 (中国广东)',
name: "TCL实业控股股份有限公司 (中国广东)",
logo: Logo3
},
{
name: 'TCL Electronics Holdings Ltd. (中国香港)',
name: "TCL Electronics Holdings Ltd. (中国香港)",
logo: Logo3
},
{
name: 'TCL Communication Ltd. (中国香港)',
name: "TCL Communication Ltd. (中国香港)",
logo: Logo3
},
{
name: 'TCL Communication Ltd. (中国香港)',
name: "TCL Communication Ltd. (中国香港)",
logo: Logo3
},
{
name: 'TCL Communication Technology Holdings Ltd. (中国广东)',
name: "TCL Communication Technology Holdings Ltd. (中国广东)",
logo: Logo3
},
{
name: 'TCL Mobile International Ltd. (中国香港)',
name: "TCL Mobile International Ltd. (中国香港)",
logo: Logo3
},
{
name: '惠州TCL移动通信有限公司 (中国广东)',
name: "惠州TCL移动通信有限公司 (中国广东)",
logo: Logo3
},
{
name: 'TCL Mobile Communication (HK) Company Ltd. (中国香港)',
name: "TCL Mobile Communication (HK) Company Ltd. (中国香港)",
logo: Logo3
},
}
]
},
{
title:'其他相关企业',
title: "其他相关企业",
companyList: [
{
name: 'Tinno USA, Inc. (美国德州普莱诺)',
name: "Tinno USA, Inc. (美国德州普莱诺)",
logo: Logo4
},
{
name: '深圳市天珑移动技术有限公司 (中国广东)',
name: "深圳市天珑移动技术有限公司 (中国广东)",
logo: Logo5
},
{
name: 'HMD Global (芬兰)',
name: "HMD Global (芬兰)",
logo: Logo6
},
{
name: 'HMD Global OY (芬兰)',
name: "HMD Global OY (芬兰)",
logo: Logo6
},
{
name: 'HMD America, Inc. (美国佛罗里达州迈阿密)',
name: "HMD America, Inc. (美国佛罗里达州迈阿密)",
logo: Logo6
},
}
]
},
])
}
]);
</script>
<style lang="scss" scoped>
......@@ -318,7 +332,7 @@ const caseList = ref([
.header-info {
height: 22px;
position: absolute;
right: 56px;
right: 84px;
top: 17px;
display: flex;
justify-content: flex-end;
......@@ -345,14 +359,19 @@ const caseList = ref([
position: absolute;
top: 14px;
right: 12px;
width: 32px;
height: 32px;
display: flex;
justify-content: flex-end;
gap: 4px;
.icon {
width: 28px;
height: 28px;
img {
width: 100%;
height: 100%;
}
}
}
}
.left {
width: 520px;
.box1 {
......@@ -589,7 +608,7 @@ const caseList = ref([
width: 24px;
height: 24px;
margin-top: 3px;
img{
img {
width: 100%;
height: 100%;
}
......
......@@ -21,7 +21,7 @@
<div class="item-header-text">打压遏制手段分布</div>
</div>
<div class="item-header-divider"></div>
<div style="display: flex;height: calc(100% - 60px);">
<div style="display: flex; justify-content: space-between; width: 100%; height: calc(100% - 60px);">
<div class="thematic-btn-left" @click="changeBtn('left')">
<img class="thematic-btn-icon" src="@/assets/images/icon/card-btn-left.png"></img>
</div>
......@@ -29,7 +29,10 @@
<div class="cup-box" style="display: flex;">
<div v-for="item in distributionColor" class="cup-item-box" :style="{
color: `hsla(${item.color[0]}, ${item.color[1]}%, ${item.color[2]}%, ${1})`
}">
}"
@click="handleClickItem(item)"
>
<div class="cup-title">
{{ item.titlle }}
</div>
......@@ -94,177 +97,175 @@
<script setup>
import { onMounted, ref, computed } from "vue";
import router from '@/router/index'
import * as echarts from "echarts";
import DivideHeader from "@/components/DivideHeader.vue";
import Timeline from '../component/Timeline.vue'
import WaveBall from '../component/WaveBall.vue'
import getBarChart from '../js/barChart.js'
import radarChart from '../js/radarChart.js'
import Timeline from "../component/Timeline.vue";
import WaveBall from "../component/WaveBall.vue";
import getBarChart from "../js/barChart.js";
import radarChart from "../js/radarChart.js";
//对华打压历程
const course = ref([
{
time: '2025年1月',
title: '《AI扩散暂行最终规则》发布',
content: '拜登政府发布《AI扩散暂行最终规则》,建立三级许可制度。'
time: "2025年1月",
title: "《AI扩散暂行最终规则》发布",
content: "拜登政府发布《AI扩散暂行最终规则》,建立三级许可制度。"
},
{
time: '2025年1月',
title: '特朗普宣布撤销拜登AI规则',
content: '拜登政府发布《AI扩散暂行最终规则》,建立三级许可制度。'
time: "2025年1月",
title: "特朗普宣布撤销拜登AI规则",
content: "拜登政府发布《AI扩散暂行最终规则》,建立三级许可制度。"
},
{
time: '2025年1月',
title: '特朗普签署EO 143202',
content: '特朗普政府宣布撤销拜登AI规则,计划'
time: "2025年1月",
title: "特朗普签署EO 143202",
content: "特朗普政府宣布撤销拜登AI规则,计划"
},
{
time: '2025年1月',
title: '中国网信办约谈英伟达',
content: '中国网信办约谈英伟达,要求就H20算力芯片漏洞后门安全风险问题进行说明。'
time: "2025年1月",
title: "中国网信办约谈英伟达",
content: "中国网信办约谈英伟达,要求就H20算力芯片漏洞后门安全风险问题进行说明。"
},
{
time: '2025年7月23日',
title: '英伟达H20发放出口许可证',
content: '美国商务部为4月份被实质禁售的英伟达H20发放出口许可证。'
time: "2025年7月23日",
title: "英伟达H20发放出口许可证",
content: "美国商务部为4月份被实质禁售的英伟达H20发放出口许可证。"
},
{
time: '2025年1月',
title: '《AI扩散暂行最终规则》发布',
content: '拜登政府发布《AI扩散暂行最终规则》,建立三级许可制度。'
time: "2025年1月",
title: "《AI扩散暂行最终规则》发布",
content: "拜登政府发布《AI扩散暂行最终规则》,建立三级许可制度。"
},
{
time: '2025年1月',
title: '特朗普宣布撤销拜登AI规则',
content: '拜登政府发布《AI扩散暂行最终规则》,建立三级许可制度。'
time: "2025年1月",
title: "特朗普宣布撤销拜登AI规则",
content: "拜登政府发布《AI扩散暂行最终规则》,建立三级许可制度。"
},
{
time: '2025年1月',
title: '特朗普签署EO 143202',
content: '特朗普政府宣布撤销拜登AI规则,计划'
time: "2025年1月",
title: "特朗普签署EO 143202",
content: "特朗普政府宣布撤销拜登AI规则,计划"
},
{
time: '2025年1月',
title: '中国网信办约谈英伟达',
content: '中国网信办约谈英伟达,要求就H20算力芯片漏洞后门安全风险问题进行说明。'
time: "2025年1月",
title: "中国网信办约谈英伟达",
content: "中国网信办约谈英伟达,要求就H20算力芯片漏洞后门安全风险问题进行说明。"
},
{
time: '2025年7月23日',
title: '英伟达H20发放出口许可证',
content: '美国商务部为4月份被实质禁售的英伟达H20发放出口许可证。'
},
])
time: "2025年7月23日",
title: "英伟达H20发放出口许可证",
content: "美国商务部为4月份被实质禁售的英伟达H20发放出口许可证。"
}
]);
//打压遏制手段分布
const distribution = ref([
{
"titlle": "法案",
"value": 80,
"text": "1626",
"unit": "个",
"change": "较上个月+3"
titlle: "法案",
value: 80,
text: "1626",
unit: "个",
change: "较上个月+3",
path: '/billHome'
},
{
"titlle": "行政令",
"value": 20,
"text": "1626",
"unit": "个",
"change": "较上个月+1"
titlle: "行政令",
value: 20,
text: "1626",
unit: "个",
change: "较上个月+1",
path: '/decree'
},
{
"titlle": "科技智库",
"value": 10,
"text": "66",
"unit": "次",
"change": "较上个月+2"
titlle: "科技智库",
value: 10,
text: "66",
unit: "次",
change: "较上个月+2",
path: '/thinkTank'
},
{
"titlle": "出口管制",
"value": 33,
"text": "66",
"unit": "次",
"change": "较上个月+1"
titlle: "出口管制",
value: 33,
text: "66",
unit: "次",
change: "较上个月+1",
path: '/exportControl'
},
{
"titlle": "投融资限制",
"value": 80,
"text": "119",
"unit": "次",
"change": "较上个月+1"
titlle: "投融资限制",
value: 80,
text: "119",
unit: "次",
change: "较上个月+1",
path: '/finance'
},
{
"titlle": "市场准入",
"value": 50,
"text": "223",
"unit": "次",
"change": "较上个月+1"
titlle: "市场准入",
value: 50,
text: "223",
unit: "次",
change: "较上个月+1",
path: '/marketAccessRestrictions'
}
])
]);
//随机生成颜色
const makeColors = () => {
let A = Math.floor(Math.random() * 360) // 随机色相
let B = 70 // 固定饱和度
let C = 50 // 固定亮度
return [A, B, C]
}
let A = Math.floor(Math.random() * 360); // 随机色相
let B = 70; // 固定饱和度
let C = 50; // 固定亮度
return [A, B, C];
};
// 计算属性
const distributionColor = computed(() => {
for (let item in distribution.value) {
distribution.value[item].color = makeColors()
distribution.value[item].color = makeColors();
}
return distribution.value
})
const timeIndex = ref(0)
return distribution.value;
});
const timeIndex = ref(0);
//遏制手段分布按钮
function changeBtn(type) {
if (type === 'left') {
timeIndex.value === 0 ? '' : timeIndex.value = timeIndex.value - 1
if (type === "left") {
timeIndex.value === 0 ? "" : (timeIndex.value = timeIndex.value - 1);
} else {
(timeIndex.value.length - timeIndex.value <= 4) ? '' : timeIndex.value = timeIndex.value + 1
timeIndex.value.length - timeIndex.value <= 4 ? "" : (timeIndex.value = timeIndex.value + 1);
}
}
//打压遏制强度变化
const chart1Data = ref({
name: [
"2024-12",
"2025-1",
"2025-2", "2025-3", "2025-4", "2025-5", "2025-6", "2025-7",
],
value: [83.76, 76.72, 73.89, 72.16, 66.24, 65.47, 63.98, 62.12, 44.38, 24.79],
name: ["2024-12", "2025-1", "2025-2", "2025-3", "2025-4", "2025-5", "2025-6", "2025-7"],
value: [83.76, 76.72, 73.89, 72.16, 66.24, 65.47, 63.98, 62.12, 44.38, 24.79]
});
const strengthBtn = ref('all')
function handleStrengthBtn() {
}
const strengthBtn = ref("all");
function handleStrengthBtn() {}
//打压遏制强度变化时间选择器
const strengthSelect = ref("近一年");
const strengthTimeList = ref([
{
label: "近半年",
value: "近半年",
value: "近半年"
},
{
label: "近一年",
value: "近一年",
value: "近一年"
},
{
label: "近两年",
value: "近两年",
value: "近两年"
},
{
label: "近三年",
value: "近三年",
value: "近三年"
},
{
label: "近五年",
value: "近五年",
},
value: "近五年"
}
]);
//打压遏制领域分布
......@@ -272,33 +273,40 @@ const areaSelect = ref("2025");
const areaTimeList = ref([
{
label: "2025",
value: "2025",
value: "2025"
},
{
label: "2024",
value: "2024",
value: "2024"
},
{
label: "2023",
value: "2023",
},
value: "2023"
}
]);
// 绘制echarts图表
const setChart = (option, chartId) => {
let chartDom = document.getElementById(chartId);
console.log(chartDom, 'chartDomchartDomchartDom')
console.log(chartDom, "chartDomchartDomchartDom");
chartDom.removeAttribute("_echarts_instance_");
let chart = echarts.init(chartDom);
chart.setOption(option);
return chart;
};
// 点击打压遏制手段分布 跳转到各个页面
const handleClickItem = (item) => {
router.push({
path: item.path
})
}
onMounted(() => {
let char1 = getBarChart(chart1Data.value.name, chart1Data.value.value, true);
setChart(char1, "chart1");
let char2 = radarChart()
let char2 = radarChart();
setChart(char2, "char2");
});
</script>
......@@ -306,13 +314,12 @@ onMounted(() => {
<style lang="scss" scoped>
.cup-box {
overflow-x: auto;
.cup-item-box {
width: 220px;
width: 240px;
text-align: center;
box-sizing: border-box;
border: 1px solid rgba(234, 236, 238, 1);
border-radius: var(---, 10px);
border-radius: 10px;
margin: 20px;
padding: 20px;
......@@ -328,7 +335,6 @@ onMounted(() => {
}
}
/* 百分比文字 */
.txt {
position: absolute;
......@@ -341,6 +347,8 @@ onMounted(() => {
}
.thematic-box {
// margin: 0 auto;
// width: 1600px;
height: 1500px;
.divide {
......@@ -375,8 +383,6 @@ onMounted(() => {
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background: rgba(255, 255, 255, 1);
.item-header {
height: 48px;
width: 100%;
......@@ -394,12 +400,11 @@ onMounted(() => {
font-weight: 700;
line-height: 26px;
background: rgba(255, 255, 255, 0.65);
color: #055FC2;
color: #055fc2;
font-family: Microsoft YaHei;
font-size: 20px;
line-height: 48px;
text-align: left;
}
.item-header-right {
......@@ -423,7 +428,6 @@ onMounted(() => {
height: 100%;
width: calc(100% - 50px);
.time-item-box {
width: 30%;
height: 165px;
......@@ -454,6 +458,5 @@ onMounted(() => {
width: 100%;
margin-top: calc(50% - 24px);
}
}
</style>
......@@ -12,7 +12,7 @@
<div class="box">
<div class="item left">
<div class="item-header">
<img class="item-header-icon" src="@/assets/images/icon/overview-card-header-icon.png"></img>
<img class="item-header-icon" src="@/assets/images/icon/overview-card-header-icon.png" />
<div class="item-header-text">机构动态</div>
<div class="item-header-more">更多 +</div>
</div>
......@@ -20,7 +20,7 @@
<div class="item-content">
<div class="item-card" style="">
<div class="item-card-btn-left" @click="changeOrganizationNews('left')">
<img class="item-btn-icon" src="@/assets/images/icon/card-btn-left.png"></img>
<img class="item-btn-icon" src="@/assets/images/icon/card-btn-left.png" />
</div>
<!-- 机构动态内容-->
......@@ -31,7 +31,7 @@
{{ organizationNews[organizationNewsShow].title }}
</div>
<div class="item-card-content-title-small">
{{ organizationNews[organizationNewsShow].time, organizationNews[organizationNewsShow].adress }}
{{ organizationNews[organizationNewsShow].time + ' ' + organizationNews[organizationNewsShow].adress }}
</div>
</div>
<img class="item-card-content-title-image" :src="organizationNews[organizationNewsShow].image" alt="">
......@@ -41,20 +41,20 @@
{{ organizationNews[organizationNewsShow].content }}
</div>
<div style="display: flex">
<div class="item-card-content-tag" v-for="tag in organizationNews[organizationNewsShow].tag"
<div class="item-card-content-tag" v-for="tag,index in organizationNews[organizationNewsShow].tag" :key="index"
:style="{ color: tag.textColor, background: tag.color, borderColor: tag.color }">
{{ tag.text }}
</div>
</div>
</div>
<div class="item-card-btn-right" @click="changeOrganizationNews('right')">
<img class="item-btn-icon" src="@/assets/images/icon/card-btn-right.png"></img>
<img class="item-btn-icon" src="@/assets/images/icon/card-btn-right.png" />
</div>
</div>
<div class="item-card-right ">
<div class="item-list">
<div v-for="organizationItem in organizationList" style="height: 40px">
<div v-for="organizationItem,index in organizationList" :key="index" style="height: 40px">
<div style="display: flex;margin: 10px">
<div class="item-list-punblier">
{{ organizationItem.punblier }}
......@@ -76,7 +76,7 @@
<!--风险信号-->
<div class="item left">
<div class="item-header">
<img class="item-header-icon" src="@/assets/images/icon/waring-card-header-icon.png"></img>
<img class="item-header-icon" src="@/assets/images/icon/waring-card-header-icon.png" />
<div class="item-header-text" style="background-color: #CE4F51;">风险信号</div>
</div>
<div class="item-header-divider"></div>
......@@ -106,15 +106,15 @@
<!--新闻资讯-->
<div class="item right">
<div class="item-header">
<img class="item-header-icon" src="@/assets/images/icon/news-card-header-icon.png"></img>
<img class="item-header-icon" src="@/assets/images/icon/news-card-header-icon.png" />
<div class="item-header-text" style="background: rgba(255, 255, 255, 0.65) ;color:#055FC2">新闻资讯</div>
<div class="item-header-more" style=" color:#055FC2">更多 +</div>
</div>
<div class="item-header-divider"></div>
<div class="news-box">
<div v-for="item in newsList" class="news-box-item">
<div v-for="item,index in newsList" :key="index" class="news-box-item">
<div style=" display: flex;">
<img :src="item.image"></img>
<img :src="item.image" />
<div style="padding: 0 10px ;">
<div class="news-box-title">
{{ item.title }}
......@@ -130,14 +130,14 @@
<!--人物动态-->
<div class="item right">
<div class="item-header">
<img class="item-header-icon" src="@/assets/images/icon/people-card-header-icon.png"></img>
<img class="item-header-icon" src="@/assets/images/icon/people-card-header-icon.png" />
<div class="item-header-text" style="background: rgba(255, 255, 255, 0.65) ;color:#055FC2">人物动态</div>
<div class="item-header-more" style=" color:#055FC2">更多 +</div>
</div>
<div class="item-header-divider"></div>
<div class="character-box">
<div class="character-item" v-for="item in characterDynamics">
<img :src="item.image" class="character-image"></img>
<div class="character-item" v-for="item,index in characterDynamics" :key="index">
<img :src="item.image" class="character-image" />
<div class="talk-box">
<div style="display: flex;">
<div class="talk-title">
......@@ -166,93 +166,104 @@
<script setup>
import { onMounted, ref } from "vue";
import Thematicanalysis from './component/Thematicanalysis.vue'
import ResourceSupport from './component/ResourceSupport.vue'
import strengthComparison from './component/strengthComparison.vue'
import Thematicanalysis from "./component/Thematicanalysis.vue";
import ResourceSupport from "./component/ResourceSupport.vue";
import strengthComparison from "./component/strengthComparison.vue";
import router from "@/router";
import { color } from "echarts";
const organizationNews = ref([
{
title: '1美国白宫发布关于进一步延长TikTok执法宽限期的行政令',
time: '2025年9月16日',
adress: '美国白宫',
image: '/testData/organizationNews-image1.png',
content: '9月16日,美国白宫官方网站发布总统政令,再次推迟(第四次)对TikTok禁令的执法,新的宽限期截止日为2025年12月16日​。在宽限期内及对于宽限期前的行为,司法部不得强制执行​《保护美国人免受外国对手控制应用程序法》或因此处罚相关实体​(如TikTok及其分发平台)。司法部还需',
tag: [{
color: '#FFF1F0',
textColor: ' rgba(245, 34, 45, 1)',
text: '人工智能'
}, {
color: '#E6F4FF',
textColor: ' rgba(22, 119, 255, 1)',
text: '通信网络'
}]
title: "1美国白宫发布关于进一步延长TikTok执法宽限期的行政令",
time: "2025年9月16日",
adress: "美国白宫",
image: "/testData/organizationNews-image1.png",
content:
"9月16日,美国白宫官方网站发布总统政令,再次推迟(第四次)对TikTok禁令的执法,新的宽限期截止日为2025年12月16日​。在宽限期内及对于宽限期前的行为,司法部不得强制执行​《保护美国人免受外国对手控制应用程序法》或因此处罚相关实体​(如TikTok及其分发平台)。司法部还需",
tag: [
{
color: "#FFF1F0",
textColor: " rgba(245, 34, 45, 1)",
text: "人工智能"
},
{
color: "#E6F4FF",
textColor: " rgba(22, 119, 255, 1)",
text: "通信网络"
}
]
},
{
title: "2美国白宫发布关于进一步延长TikTok执法宽限期的行政令",
time: "2025年9月16日",
adress: "美国白宫",
image: "/testData/organizationNews-image1.png",
content:
"9月16日,美国白宫官方网站发布总统政令,再次推迟(第四次)对TikTok禁令的执法,新的宽限期截止日为2025年12月16日​。在宽限期内及对于宽限期前的行为,司法部不得强制执行​《保护美国人免受外国对手控制应用程序法》或因此处罚相关实体​(如TikTok及其分发平台)。司法部还需",
tag: [
{
color: "#F5222D",
textColor: " #FFF1F0",
text: "人工智能"
},
{
color: "#E6F4FF",
textColor: " #1677FF",
text: "通信网络"
}
]
},
{
title: '2美国白宫发布关于进一步延长TikTok执法宽限期的行政令',
time: '2025年9月16日',
adress: '美国白宫',
image: '/testData/organizationNews-image1.png',
content: '9月16日,美国白宫官方网站发布总统政令,再次推迟(第四次)对TikTok禁令的执法,新的宽限期截止日为2025年12月16日​。在宽限期内及对于宽限期前的行为,司法部不得强制执行​《保护美国人免受外国对手控制应用程序法》或因此处罚相关实体​(如TikTok及其分发平台)。司法部还需',
tag: [{
color: '#F5222D',
textColor: ' #FFF1F0',
text: '人工智能'
}, {
color: '#E6F4FF',
textColor: ' #1677FF',
text: '通信网络'
}]
}
,
title: "3美国白宫发布关于进一步延长TikTok执法宽限期的行政令",
time: "2025年9月16日",
adress: "美国白宫",
image: "/testData/organizationNews-image1.png",
content:
"9月16日,美国白宫官方网站发布总统政令,再次推迟(第四次)对TikTok禁令的执法,新的宽限期截止日为2025年12月16日​。在宽限期内及对于宽限期前的行为,司法部不得强制执行​《保护美国人免受外国对手控制应用程序法》或因此处罚相关实体​(如TikTok及其分发平台)。司法部还需",
tag: [
{
color: "#FFF1F0",
textColor: " rgba(245, 34, 45, 1)",
text: "人工智能"
},
{
title: '3美国白宫发布关于进一步延长TikTok执法宽限期的行政令',
time: '2025年9月16日',
adress: '美国白宫',
image: '/testData/organizationNews-image1.png',
content: '9月16日,美国白宫官方网站发布总统政令,再次推迟(第四次)对TikTok禁令的执法,新的宽限期截止日为2025年12月16日​。在宽限期内及对于宽限期前的行为,司法部不得强制执行​《保护美国人免受外国对手控制应用程序法》或因此处罚相关实体​(如TikTok及其分发平台)。司法部还需',
tag: [{
color: '#FFF1F0',
textColor: ' rgba(245, 34, 45, 1)',
text: '人工智能'
}, {
color: '#E6F4FF',
textColor: ' rgba(22, 119, 255, 1)',
text: '通信网络'
}]
}
])//机构动态
const organizationNewsShow = ref(0)//机构动态当前展示条目
color: "#E6F4FF",
textColor: " rgba(22, 119, 255, 1)",
text: "通信网络"
}
]
}
]); //机构动态
const organizationNewsShow = ref(0); //机构动态当前展示条目
const organizationList = ref([
{
time: "1小时前",
content: "特朗普于美国独立日签署法案,​公法编号Pub. L. No. 119-21。白宫举行庆典,B-2轰炸机飞越上空,象征“美国新时代”开启。",
punblier: "国会",
content:
"特朗普于美国独立日签署法案,​公法编号Pub. L. No. 119-21。白宫举行庆典,B-2轰炸机飞越上空,象征“美国新时代”开启。",
punblier: "国会"
},
{
time: "10小时前",
content: "众议院最终表决218票赞成 vs 214票反对,修订版法案以4票优势通过,2名共和党议员倒戈,民主党全员反对。",
punblier: "商务部",
punblier: "商务部"
},
{
time: "11小时前",
content: "民主党领袖杰弗里斯发表 ​8小时45分钟​ 演讲(众议院现代史最长),抗议法案“劫贫济富”,但仍未阻止表决。",
punblier: "财政部",
punblier: "财政部"
},
{
time: "一天前",
content: "众议院以 ​219:213​ 通过程序规则,为最终表决铺路。此前4名共和党议员反对程序规则,议长约翰逊紧急游说挽回1票。",
punblier: "FCC",
punblier: "FCC"
},
{
time: "周三",
content: "参议院最终表决投票51:50​,副总统万斯(JD Vance)投出关键票打破平局。3名共和党参议员倒戈(蒂利斯、保罗、柯林斯)。",
punblier: "白宫",
},
])//机构动态
content:
"参议院最终表决投票51:50​,副总统万斯(JD Vance)投出关键票打破平局。3名共和党参议员倒戈(蒂利斯、保罗、柯林斯)。",
punblier: "白宫"
}
]); //机构动态
//风险信号
const warningList = ref([
......@@ -286,72 +297,78 @@ const warningList = ref([
//新闻资讯
const newsList = ref([
{
image: '/testData/news-1.png',
title: ' 美国联邦政府停摆持续临时拨款法案再次“闯关”失败美政府即将刷新“停摆”纪录 ',
time: '11-4',
publier: '华盛顿纽约'
}, {
image: '/testData/news-1.png',
title: ' 美国联邦政府停摆持续临时拨款法案再次“闯关”失败美政府即将刷新“停摆”纪录 ',
time: '11-4',
publier: '华盛顿纽约'
}, {
image: '/testData/news-1.png',
title: ' 美国联邦政府停摆持续临时拨款法案再次“闯关”失败美政府即将刷新“停摆”纪录 ',
time: '11-4',
publier: '华盛顿纽约'
}, {
image: '/testData/news-1.png',
title: ' 美国联邦政府停摆持续临时拨款法案再次“闯关”失败美政府即将刷新“停摆”纪录 ',
time: '11-4',
publier: '华盛顿纽约'
}, {
image: '/testData/news-1.png',
title: ' 美国联邦政府停摆持续临时拨款法案再次“闯关”失败美政府即将刷新“停摆”纪录 ',
time: '11-4',
publier: '华盛顿纽约'
}, {
image: '/testData/news-1.png',
title: ' 美国联邦政府停摆持续临时拨款法案再次“闯关”失败美政府即将刷新“停摆”纪录 ',
time: '11-4',
publier: '华盛顿纽约'
}
])
image: "/testData/news-1.png",
title: " 美国联邦政府停摆持续临时拨款法案再次“闯关”失败美政府即将刷新“停摆”纪录 ",
time: "11-4",
publier: "华盛顿纽约"
},
{
image: "/testData/news-1.png",
title: " 美国联邦政府停摆持续临时拨款法案再次“闯关”失败美政府即将刷新“停摆”纪录 ",
time: "11-4",
publier: "华盛顿纽约"
},
{
image: "/testData/news-1.png",
title: " 美国联邦政府停摆持续临时拨款法案再次“闯关”失败美政府即将刷新“停摆”纪录 ",
time: "11-4",
publier: "华盛顿纽约"
},
{
image: "/testData/news-1.png",
title: " 美国联邦政府停摆持续临时拨款法案再次“闯关”失败美政府即将刷新“停摆”纪录 ",
time: "11-4",
publier: "华盛顿纽约"
},
{
image: "/testData/news-1.png",
title: " 美国联邦政府停摆持续临时拨款法案再次“闯关”失败美政府即将刷新“停摆”纪录 ",
time: "11-4",
publier: "华盛顿纽约"
},
{
image: "/testData/news-1.png",
title: " 美国联邦政府停摆持续临时拨款法案再次“闯关”失败美政府即将刷新“停摆”纪录 ",
time: "11-4",
publier: "华盛顿纽约"
}
]);
//人物动态
const characterDynamics = ref([
{
image: '/testData/united_states 1.png',
name: '詹姆斯·刘易斯',
position: '商务部某办公室主任',
time: '一天前',
talk: '指出美国在AI赋能科学,特别是“自驱实验室”等自动化科研设施上的投资不足,呼吁进行系统性战略投资'
image: "/testData/united_states 1.png",
name: "詹姆斯·刘易斯",
position: "商务部某办公室主任",
time: "一天前",
talk: "指出美国在AI赋能科学,特别是“自驱实验室”等自动化科研设施上的投资不足,呼吁进行系统性战略投资"
},
{
image: '/testData/united_states 2.png',
name: '迈克尔·霍洛维茨',
position: '某计划署主席',
time: '一天前',
talk: '评价特朗普政府《AI国家行动计划》,认为其关键在于通过技术出口和基础设施建设主动抢占全球AI主导权。'
image: "/testData/united_states 2.png",
name: "迈克尔·霍洛维茨",
position: "某计划署主席",
time: "一天前",
talk: "评价特朗普政府《AI国家行动计划》,认为其关键在于通过技术出口和基础设施建设主动抢占全球AI主导权。"
},
{
image: '/testData/united_states 1.png',
name: '詹姆斯·戴维·万斯',
position: '副总统',
time: '一天前',
talk: '提出特朗普政府的AI政策强调技术开放与快速应用,但可能以牺牲安全防范为代价,开启了“潘多拉魔盒”。'
},
])
image: "/testData/united_states 1.png",
name: "詹姆斯·戴维·万斯",
position: "副总统",
time: "一天前",
talk: "提出特朗普政府的AI政策强调技术开放与快速应用,但可能以牺牲安全防范为代价,开启了“潘多拉魔盒”。"
}
]);
function changeOrganizationNews(type) {
if (type === 'left') {
organizationNewsShow.value === 0 ? '' : organizationNewsShow.value = organizationNewsShow.value - 1
if (type === "left") {
organizationNewsShow.value === 0 ? "" : (organizationNewsShow.value = organizationNewsShow.value - 1);
} else {
organizationNews.value === organizationNews.value.length - 1 ? '' : organizationNewsShow.value = organizationNewsShow.value + 1
organizationNews.value === organizationNews.value.length - 1
? ""
: (organizationNewsShow.value = organizationNewsShow.value + 1);
}
}
onMounted(() => { });
onMounted(() => {});
</script>
<style lang="scss" scoped>
......@@ -432,13 +449,12 @@ onMounted(() => { });
.item-header-text {
width: 112px;
background: #055FC2;
background: #055fc2;
color: #ffffff;
font-family: Microsoft YaHei;
font-size: 20px;
line-height: 48px;
text-align: center;
}
.item-header-more {
......@@ -533,7 +549,6 @@ onMounted(() => { });
line-height: 24px;
letter-spacing: 0px;
text-align: left;
}
}
......@@ -572,8 +587,6 @@ onMounted(() => { });
width: 24px;
padding-top: calc(50% - 20px);
}
}
.item-card-right {
......@@ -581,10 +594,7 @@ onMounted(() => { });
height: 100%;
display: flex;
.item-list {
padding: 10px;
.item-list-punblier {
......@@ -627,12 +637,9 @@ onMounted(() => { });
}
}
}
}
.waring-item {
.waring-status {
width: 40px;
height: 40px;
......@@ -712,8 +719,6 @@ onMounted(() => { });
/* 矩形 265 */
width: 96px;
height: 72px;
}
.news-box-title {
......@@ -798,7 +803,6 @@ onMounted(() => { });
}
}
}
}
}
</style>
......@@ -93,12 +93,12 @@
<div class="submit-text">生成报文</div>
</div>
</div>
<!-- <div class="process-box">
<div class="back">
<div class="process-box" v-if="isShowProcess">
<div class="back" @click="handleBack">
{{ "< 返回" }}
</div>
<div class="process-main-box">
<div class="analysis-box">
<!-- <div class="analysis-box">
<div class="analysis-header">
<div class="icon">
<img src="./assets/images/right-arrow.png" alt="" />
......@@ -110,7 +110,7 @@
"用户需求属于态势要图制图任务,需要围绕“伊以冲突”主题生成关键词、搜索相关新闻、抽取并聚类事件、获取地理位置信息,最终完成事件和地点的可视化标绘"
}}
</div>
</div>
</div> -->
<div class="steps-box">
<div class="steps-header">
<div class="icon">
......@@ -118,19 +118,14 @@
</div>
<div class="text">{{ "执行步骤:" }}</div>
</div>
<div class="steps-content">
<div class="steps" v-for="(step, index) in steps" :key="index">
<div class="steps-id">{{ step.id }}</div>
<div class="steps-content">{{ step.content }}</div>
</div>
<div class="steps-content" ref="scrollProcessContainer" v-html="renderedProcess"></div>
</div>
</div>
<div class="doing-box">
<!-- <div class="doing-box">
{{ "正在执行步骤1/7:根据制图主题生成关键词" }}
</div>
</div> -->
<div class="tool-box">
<div class="tool-header">{{ '工具调用' }}</div>
<div class="tool-main"></div>
<div class="tool-header">{{ "工具调用" }}</div>
<div class="tool-main">当前智能体工具:{{ curAgentTool ? curAgentTool : "无" }}</div>
</div>
</div>
<div class="process-tips-box">
......@@ -141,14 +136,14 @@
</div>
<div class="process-footer-box">
<div class="footer-left">
{{ "报文生成中..." }}
{{ isGenerating ? "报文生成中..." : "报文已生成" }}
</div>
<div class="footer-right">
<div class="icon"></div>
<div class="text">{{ "停止" }}</div>
<div class="text" @click="handleGenerate">{{ "停止" }}</div>
</div>
</div>
</div>
</div> -->
<div class="main-box">
<div v-if="isEditMode" class="edit-panel">
<v-md-editor
......@@ -170,6 +165,7 @@
<script setup>
import { ref, onMounted, onUnmounted } from "vue";
import { useMarkdownStream } from "@/hooks/useMarkdownStream";
import { useStream } from "@/hooks/useStream";
import { fetchEventSource } from "@microsoft/fetch-event-source";
import VMdEditor from "@kangc/v-md-editor";
......@@ -184,6 +180,13 @@ VMdEditor.use(vuepressTheme, {
Prism
});
const isGenerating = ref(false);
const isShowProcess = ref(false);
const handleBack = () => {
isShowProcess.value = false;
};
const steps = [
{
id: 1,
......@@ -245,13 +248,26 @@ const saveToLocalStorage = text => {
const abortController = ref(null);
const scrollContainer = ref(null);
const { renderedContent, updateContent } = useMarkdownStream();
const { renderedProcess, updateProcess } = useStream();
// 流程
const scrollProcessContainer = ref(null);
const processContent = ref("");
// 报文
const scrollContainer = ref(null);
const reportContent = ref("");
const curTempTitle = ref("法案");
// 停止生成
const handleGenerate = () => {
abortController.value.abort();
};
// 当前调用工具
const curAgentTool = ref("报告整体优化工具");
const getStreamChat = async (search, inputValue) => {
const params = {
query: writtingTitle.value, // "输出一篇报文"
......@@ -261,7 +277,7 @@ const getStreamChat = async (search, inputValue) => {
abortController.value = new AbortController();
fetchEventSource("/sse/api/v1/chat/stream", {
fetchEventSource("/sseWrite/api/v1/workflow/invoke", {
method: "POST",
headers: {
"Content-Type": "application/json"
......@@ -271,22 +287,38 @@ const getStreamChat = async (search, inputValue) => {
openWhenHidden: true,
async onopen(res) {
console.log("流式回答开始", res);
isGenerating.value = true;
isShowProcess.value = true;
},
async onmessage(res) {
let msgData = JSON.parse(res.data);
console.log("resss", msgData.content);
let str = msgData.content;
console.log("resss", msgData.data);
console.log("msgData", msgData);
let str = msgData.data;
if (msgData.event_type === "stream_agent_out") {
if (str !== "[DONE]") {
reportContent.value += str;
if (reportContent.value.includes("./out/img")) {
reportContent.value = reportContent.value.replaceAll("./out/img", "http://192.168.26.70:8000/out/img");
console.log(111, reportContent.value);
reportContent.value = reportContent.value.replaceAll("./out/img", "http://192.168.61.70:8000/out/img");
// console.log(111, reportContent.value);
}
updateContent(reportContent.value, scrollContainer.value);
} else {
isGenerating.value = false;
ElMessage.success("报文生成结束");
abortController.value.abort();
abortController.value = new AbortController();
}
} else if (msgData.event_type === "workflow_complete") {
ElMessage.success("报文生成结束");
isGenerating.value = false;
abortController.value.abort();
abortController.value = new AbortController();
} else if (msgData.event_type.toLowerCase().includes("error")) {
} else {
processContent.value += str;
curAgentTool.value = msgData.tool;
updateProcess(processContent.value, scrollProcessContainer.value);
}
},
onerror(error) {
......@@ -362,10 +394,7 @@ const exportContent = () => {
URL.revokeObjectURL(url);
};
onMounted(() => {
// const str = '# 欢迎使用 Markdown 编辑器\n\n这是一个功能丰富的 Markdown 编辑器示例。\n\n## 功能特性\n\n- ✨ **实时预览**\n- 🎨 **代码高亮**\n- 📁 **图片上传**\n- 📊 **表格支持**\n- 🔗 **链接管理**\n\n```javascript\n// 示例代码\nconst message = "Hello Markdown!";\nconsole.log(message);\n```'
// updateContent(str, scrollContainer.value);
});
onMounted(() => {});
onUnmounted(() => {
if (abortController.value) {
......@@ -540,32 +569,31 @@ onUnmounted(() => {
}
}
.steps-content {
max-height: 500px;
height: 560px;
width: 100%;
background: skyblue;
overflow-x: hidden;
overflow-y: auto;
.steps {
display: flex;
width: 410px;
margin-left: 40px;
color: #555;
font-family: Microsoft YaHei;
line-height: 35px;
.steps-id {
width: 20px;
font-size: 18px;
font-weight: 700;
}
.steps-content {
font-size: 16px;
font-weight: 400;
width: 430px;
word-wrap: break-word;
}
}
// .steps {
// display: flex;
// width: 410px;
// margin-left: 40px;
// color: #555;
// font-family: Microsoft YaHei;
// line-height: 35px;
// .steps-id {
// width: 20px;
// font-size: 18px;
// font-weight: 700;
// }
// .steps-content {
// font-size: 16px;
// font-weight: 400;
// width: 430px;
// word-wrap: break-word;
// }
// }
}
}
.doing-box {
......@@ -594,6 +622,11 @@ onUnmounted(() => {
width: 400px;
margin: 0 auto;
background: #fff;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 40px;
}
}
}
......@@ -890,6 +923,10 @@ onUnmounted(() => {
line-height: 1.7;
// font-size: 20px;
font-size: 16px;
img{
width: 300px;
height: auto;
}
}
}
}
......
......@@ -31,6 +31,7 @@ export default defineConfig({
}
},
server: {
host: '0.0.0.0', // 监听所有网络接口
port: 3000,
open: true,
proxy: {
......@@ -39,10 +40,15 @@ export default defineConfig({
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '')
},
'/sse': {
target: 'http://192.168.26.70:8000',
'/sseChat': {
target: 'http://192.168.26.115:8000',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/sse/, '')
rewrite: (path) => path.replace(/^\/sseChat/, '')
},
'/sseWrite': {
target: 'http://192.168.61.70:8000',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/sseWrite/, '')
},
'/aichat': {
target: 'http://192.168.184.24:7861/',
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论