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

update

上级 635c86d8
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
"echarts-wordcloud": "^2.1.0", "echarts-wordcloud": "^2.1.0",
"element-plus": "^2.4.4", "element-plus": "^2.4.4",
"highlight.js": "^11.11.1", "highlight.js": "^11.11.1",
"json5": "^2.2.3",
"markdown-it": "^14.1.0", "markdown-it": "^14.1.0",
"vue": "^3.4.0", "vue": "^3.4.0",
"vue-router": "^4.2.5" "vue-router": "^4.2.5"
...@@ -2899,6 +2900,7 @@ ...@@ -2899,6 +2900,7 @@
"version": "3.1.0", "version": "3.1.0",
"resolved": "https://registry.npmmirror.com/echarts-liquidfill/-/echarts-liquidfill-3.1.0.tgz", "resolved": "https://registry.npmmirror.com/echarts-liquidfill/-/echarts-liquidfill-3.1.0.tgz",
"integrity": "sha512-5Dlqs/jTsdTUAsd+K5LPLLTgrbbNORUSBQyk8PSy1Mg2zgHDWm83FmvA4s0ooNepCJojFYRITTQ4GU1UUSKYLw==", "integrity": "sha512-5Dlqs/jTsdTUAsd+K5LPLLTgrbbNORUSBQyk8PSy1Mg2zgHDWm83FmvA4s0ooNepCJojFYRITTQ4GU1UUSKYLw==",
"license": "MIT",
"peerDependencies": { "peerDependencies": {
"echarts": "^5.0.1" "echarts": "^5.0.1"
} }
...@@ -4026,6 +4028,18 @@ ...@@ -4026,6 +4028,18 @@
"sprintf-js": "~1.0.2" "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": { "node_modules/jsonfile": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmmirror.com/jsonfile/-/jsonfile-4.0.0.tgz", "resolved": "https://registry.npmmirror.com/jsonfile/-/jsonfile-4.0.0.tgz",
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
"echarts-wordcloud": "^2.1.0", "echarts-wordcloud": "^2.1.0",
"element-plus": "^2.4.4", "element-plus": "^2.4.4",
"highlight.js": "^11.11.1", "highlight.js": "^11.11.1",
"json5": "^2.2.3",
"markdown-it": "^14.1.0", "markdown-it": "^14.1.0",
"vue": "^3.4.0", "vue": "^3.4.0",
"vue-router": "^4.2.5" "vue-router": "^4.2.5"
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
<el-dropdown-item command="/decree">政令首页</el-dropdown-item> <el-dropdown-item command="/decree">政令首页</el-dropdown-item>
<el-dropdown-item command="/thinkTank">智库首页</el-dropdown-item> <el-dropdown-item command="/thinkTank">智库首页</el-dropdown-item>
<el-dropdown-item command="/exportControl">出口管制</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-item command="/marketAccessRestrictions">市场准入限制</el-dropdown-item>
</el-dropdown-menu> </el-dropdown-menu>
</template> </template>
......
...@@ -38,6 +38,52 @@ export function useMarkdownStream() { ...@@ -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) => { md.renderer.rules.fence = (tokens, idx, options, env, self) => {
const token = tokens[idx] 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 @@ ...@@ -20,7 +20,12 @@
</div> </div>
</div> </div>
<div class="header-right"> <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> </div>
<div class="box1-main"> <div class="box1-main">
...@@ -60,7 +65,12 @@ ...@@ -60,7 +65,12 @@
<div class="header-left"></div> <div class="header-left"></div>
<div class="title">相关事件</div> <div class="title">相关事件</div>
<div class="header-right"> <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> </div>
<div class="box2-main"> <div class="box2-main">
...@@ -105,7 +115,12 @@ ...@@ -105,7 +115,12 @@
</div> </div>
</div> </div>
<div class="header-right"> <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> </div>
<div class="background-wrap-right-main"> <div class="background-wrap-right-main">
...@@ -519,7 +534,7 @@ onMounted(() => { ...@@ -519,7 +534,7 @@ onMounted(() => {
.header-btn-box { .header-btn-box {
position: absolute; position: absolute;
top: 14px; top: 14px;
right: 52px; right: 84px;
display: flex; display: flex;
.btn { .btn {
margin-left: 8px; margin-left: 8px;
...@@ -529,14 +544,19 @@ onMounted(() => { ...@@ -529,14 +544,19 @@ onMounted(() => {
position: absolute; position: absolute;
top: 14px; top: 14px;
right: 12px; right: 12px;
width: 32px; display: flex;
height: 32px; justify-content: flex-end;
img { gap: 4px;
.icon{
width: 28px;
height: 28px;
img{
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
} }
} }
}
.background-wrap-left { .background-wrap-left {
width: 1150px; width: 1150px;
margin-top: 16px; margin-top: 16px;
......
...@@ -31,8 +31,13 @@ ...@@ -31,8 +31,13 @@
</div> </div>
<div class="home-box" :class="{ scrollHomeBox: isShow }" ref="containerRef"> <div class="home-box" :class="{ scrollHomeBox: isShow }" ref="containerRef">
<div class="home-header" v-show="!isShow"> <div class="home-header" v-show="!isShow">
<span>国家科技安全 </span>> <span>中美博弈概览 </span>> <!-- <span>国家科技安全 </span>> <span style="cursor: pointer;">中美博弈概览 </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>
<div class="home-main"> <div class="home-main">
<div class="home-main-header" v-show="!isShow"> <div class="home-main-header" v-show="!isShow">
...@@ -566,6 +571,13 @@ import Zyy from "@/assets/icons/zyy.png"; ...@@ -566,6 +571,13 @@ import Zyy from "@/assets/icons/zyy.png";
import Ghd from "@/assets/icons/ghd.png"; import Ghd from "@/assets/icons/ghd.png";
import Mzd from "@/assets/icons/mzd.png"; import Mzd from "@/assets/icons/mzd.png";
// 返回首页
const handleBackHome = () => {
router.push({
path: '/overview'
})
}
const currentPage = ref(1); const currentPage = ref(1);
// 处理页码改变事件 // 处理页码改变事件
const handleCurrentChange = page => { const handleCurrentChange = page => {
...@@ -1073,79 +1085,77 @@ const box9ChartData = ref([ ...@@ -1073,79 +1085,77 @@ const box9ChartData = ref([
const box7Data = ref([ const box7Data = ref([
[ [
{ {
name: '众议院', name: "众议院",
value: 298 value: 298
}, },
{ {
name: '参议院', name: "参议院",
value: 149 value: 149
} }
], ],
[ [
{ {
name: '拨款委员会', name: "拨款委员会",
value: 50, value: 50,
type: '众议院' type: "众议院"
}, },
{ {
name: '筹款委员会', name: "筹款委员会",
value: 50, value: 50,
type: '众议院' type: "众议院"
}, },
{ {
name: '外交事务委员会', name: "外交事务委员会",
value: 46, value: 46,
type: '众议院' type: "众议院"
}, },
{ {
name: '国土安全委员会', name: "国土安全委员会",
value: 40, value: 40,
type: '众议院' type: "众议院"
}, },
{ {
name: '司法委员会', name: "司法委员会",
value: 40, value: 40,
type: '众议院' type: "众议院"
}, },
{ {
name: '军事委员会', name: "军事委员会",
value: 40, value: 40,
type: '众议院' type: "众议院"
}, },
{ {
name: '能源和商业委员会', name: "能源和商业委员会",
value: 32, value: 32,
type: '众议院' type: "众议院"
}, },
{ {
name: '拨款委员会1', name: "拨款委员会1",
value: 32, value: 32,
type: '参议院' type: "参议院"
}, },
{ {
name: '财政委员会', name: "财政委员会",
value: 31, value: 31,
type: '参议院' type: "参议院"
}, },
{ {
name: '能源', name: "能源",
value: 30, value: 30,
type: '参议院' type: "参议院"
}, },
{ {
name: '能源1', name: "能源1",
value: 30, value: 30,
type: '参议院' type: "参议院"
}, },
{ {
name: '其他', name: "其他",
value: 24, value: 24,
type: '参议院' type: "参议院"
} }
] ]
]) ]);
const box8Data = ref([ const box8Data = ref([
{ {
...@@ -1203,8 +1213,8 @@ onMounted(async () => { ...@@ -1203,8 +1213,8 @@ onMounted(async () => {
const wordCloudChart = getWordCloudChart(wordCloudData.value); const wordCloudChart = getWordCloudChart(wordCloudData.value);
setChart(wordCloudChart, "wordCloudChart"); setChart(wordCloudChart, "wordCloudChart");
const box7Chart = getDoublePieChart(box7Data.value[0], box7Data.value[1]) const box7Chart = getDoublePieChart(box7Data.value[0], box7Data.value[1]);
setChart(box7Chart, 'box7Chart') setChart(box7Chart, "box7Chart");
const box9Chart = getPieChart(box9ChartData.value, box9ChartColorList.value); const box9Chart = getPieChart(box9ChartData.value, box9ChartColorList.value);
setChart(box9Chart, "box9Chart"); setChart(box9Chart, "box9Chart");
...@@ -1328,6 +1338,16 @@ onMounted(async () => { ...@@ -1328,6 +1338,16 @@ onMounted(async () => {
background: url("./assets/images/header-bg.png"); background: url("./assets/images/header-bg.png");
box-sizing: border-box; box-sizing: border-box;
padding-left: 160px; padding-left: 160px;
display: flex;
.header-item {
margin: 0 3px;
}
.back-item {
cursor: pointer;
&:hover {
color: #ccc;
}
}
} }
.home-main { .home-main {
width: 1600px; width: 1600px;
...@@ -1565,9 +1585,10 @@ onMounted(async () => { ...@@ -1565,9 +1585,10 @@ onMounted(async () => {
.box1-main-left-info { .box1-main-left-info {
margin-top: 17px; margin-top: 17px;
display: flex; display: flex;
gap: 8px;
.info-box { .info-box {
height: 30px; max-width: 80px;
width: 80px; height: 24px;
text-align: center; text-align: center;
overflow: hidden; overflow: hidden;
padding: 0 8px; padding: 0 8px;
...@@ -1579,8 +1600,7 @@ onMounted(async () => { ...@@ -1579,8 +1600,7 @@ onMounted(async () => {
font-family: Microsoft YaHei; font-family: Microsoft YaHei;
font-size: 14px; font-size: 14px;
font-weight: 400; font-weight: 400;
line-height: 30px; line-height: 24px;
margin-right: 8px;
} }
.info1 { .info1 {
border: 1px solid rgba(135, 232, 222, 1); border: 1px solid rgba(135, 232, 222, 1);
...@@ -2335,7 +2355,7 @@ onMounted(async () => { ...@@ -2335,7 +2355,7 @@ onMounted(async () => {
align-items: center; align-items: center;
justify-content: flex-end; justify-content: flex-end;
} }
.box7-main{ .box7-main {
height: 340px; height: 340px;
} }
} }
...@@ -2592,15 +2612,18 @@ onMounted(async () => { ...@@ -2592,15 +2612,18 @@ onMounted(async () => {
.btn-wrapper { .btn-wrapper {
width: 1300px; width: 1300px;
overflow-x: auto; overflow-x: auto;
// background: skyblue;
.btn-box { .btn-box {
display: flex; display: flex;
gap: 4px;
// justify-content: space-between; // justify-content: space-between;
max-width: 2000px; max-width: 2000px;
// background: orange;
.btn { .btn {
max-width: 100px; max-width: 120px;
min-width: 80px; min-width: 80px;
height: 42px; height: 42px;
margin: 0 5px;
overflow: hidden; overflow: hidden;
color: rgba(95, 101, 108, 1); color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei; font-family: Microsoft YaHei;
...@@ -2610,7 +2633,7 @@ onMounted(async () => { ...@@ -2610,7 +2633,7 @@ onMounted(async () => {
text-align: center; text-align: center;
border-radius: 21px; border-radius: 21px;
background: rgba(20, 89, 187, 0); background: rgba(20, 89, 187, 0);
padding: 0 16px; padding: 0 20px;
cursor: pointer; cursor: pointer;
&:hover { &:hover {
background: rgba(20, 89, 187, 0.1); background: rgba(20, 89, 187, 0.1);
......
const getBoxPlotChcart = (data) => { const getBoxPlotChcart = (data,unit) => {
let option = { let option = {
// title: [ // title: [
// { // {
...@@ -34,7 +34,12 @@ const getBoxPlotChcart = (data) => { ...@@ -34,7 +34,12 @@ const getBoxPlotChcart = (data) => {
}, },
yAxis: { yAxis: {
type: 'value', type: 'value',
name: '单位:天', name: `单位:${unit}`,
nameTextStyle: {
padding: [0, 0, 0, 1520], // [上, 右, 下, 左]
verticalAlign: 'middle',
align: 'center'
},
splitArea: { splitArea: {
show: true show: true
} }
......
...@@ -4,7 +4,12 @@ ...@@ -4,7 +4,12 @@
<div class="header-left"></div> <div class="header-left"></div>
<div class="title">流程概要</div> <div class="title">流程概要</div>
<div class="header-right"> <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> </div>
<div class="main"> <div class="main">
...@@ -758,14 +763,19 @@ const handleClickDetail = (isShow) => { ...@@ -758,14 +763,19 @@ const handleClickDetail = (isShow) => {
position: absolute; position: absolute;
top: 14px; top: 14px;
right: 12px; right: 12px;
width: 32px; display: flex;
height: 32px; justify-content: flex-end;
gap: 4px;
.icon {
width: 28px;
height: 28px;
img { img {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
} }
} }
}
.main { .main {
margin-left: 59px; margin-left: 59px;
height: 680px; height: 680px;
......
...@@ -5,7 +5,15 @@ ...@@ -5,7 +5,15 @@
<div class="header-left"></div> <div class="header-left"></div>
<div class="title">涉及企业</div> <div class="title">涉及企业</div>
<div class="header-right"> <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> </div>
<div class="left-top" id="chart1"></div> <div class="left-top" id="chart1"></div>
...@@ -23,18 +31,16 @@ ...@@ -23,18 +31,16 @@
</div> </div>
</div> </div>
<div class="left-footer"> <div class="left-footer">
<div class="item-box">
<div <div
class="item" class="item"
:class="{ itemActive: companyActiveIndex === idx }" :class="{ itemActive: companyActiveIndex === idx }"
@click="handleClickCompany(idx)" @click="handleClickCompany(idx)"
v-for="(val, idx) in companyList" v-for="(val, idx) in curCompanyList"
:key="idx" :key="idx"
> >
<div class="id">{{ idx + 1 }}</div> <div class="id">{{ idx + 1 }}</div>
<div <div class="title" :class="{ titleActive: companyActiveIndex === idx }">
class="title"
:class="{ titleActive: companyActiveIndex === idx }"
>
{{ val.name }} {{ val.name }}
</div> </div>
<div class="icon"> <div class="icon">
...@@ -43,13 +49,36 @@ ...@@ -43,13 +49,36 @@
</div> </div>
</div> </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>
<div class="right"> <div class="right">
<div class="box-header"> <div class="box-header">
<div class="header-left"></div> <div class="header-left"></div>
<div class="title">产业链分析</div> <div class="title">产业链分析</div>
<div class="header-right"> <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> </div>
<div class="right-main"> <div class="right-main">
...@@ -131,11 +160,7 @@ ...@@ -131,11 +160,7 @@
<div class="dialog-box1-title">{{ companyInfo.data1.title }}</div> <div class="dialog-box1-title">{{ companyInfo.data1.title }}</div>
</div> </div>
<div class="dialog-box1-main"> <div class="dialog-box1-main">
<div <div class="item" v-for="(val, idx) in companyInfo.data1.list" :key="idx">
class="item"
v-for="(val, idx) in companyInfo.data1.list"
:key="idx"
>
<div class="item-left"> <div class="item-left">
<!-- <img :src="uncheckIcon" alt=""> --> <!-- <img :src="uncheckIcon" alt=""> -->
<img :src="checkedIcon" alt="" /> <img :src="checkedIcon" alt="" />
...@@ -169,7 +194,7 @@ ...@@ -169,7 +194,7 @@
</template> </template>
<script setup> <script setup>
import { ref, onMounted, nextTick } from "vue"; import { ref, onMounted, nextTick, computed } from "vue";
import * as echarts from "echarts"; import * as echarts from "echarts";
import { getCompanyList, getIndustryHyly, getHylyList } from "@/api/influence"; import { getCompanyList, getIndustryHyly, getHylyList } from "@/api/influence";
import getBarChart from "./utils/barChart"; import getBarChart from "./utils/barChart";
...@@ -216,40 +241,22 @@ const chart1Data = ref({ ...@@ -216,40 +241,22 @@ const chart1Data = ref({
const industryActiveIndex = ref(0); const industryActiveIndex = ref(0);
const companyActiveIndex = ref(0); const companyActiveIndex = ref(0);
const handleClickCompany = (index) => { const handleClickCompany = index => {
companyActiveIndex.value = index; companyActiveIndex.value = index;
isShowCompanyDialog.value = true; isShowCompanyDialog.value = true;
setTimeout(() => { setTimeout(() => {
const chart2Data = { const chart2Data = {
dataX: [ dataX: ["2025-01", "2025-02", "2025-03", "2025-04", "2025-05", "2025-06", "2025-07", "2025-08"],
"2025-01", dataY: [1.2, 1.5, 1.4, 1.8, 1.3, 1.5, 1.6, 1.4]
"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); let chart2 = getLineChart(chart2Data.dataX, chart2Data.dataY);
setChart(chart2, "chart2"); setChart(chart2, "chart2");
const chart3Data = { const chart3Data = {
name: [ name: ["2023Q3", "2023Q4", "2024Q1", "2024Q2", "2024Q3", "2024Q4", "2025Q1", "2025Q2"],
"2023Q3", value: [49, 53, 52, 54, 52, 50, 51, 54]
"2023Q4",
"2024Q1",
"2024Q2",
"2024Q3",
"2024Q4",
"2025Q1",
"2025Q2",
],
value: [49, 53, 52, 54, 52, 50, 51, 54],
}; };
let chart3 = getBarChart1(chart3Data.name, chart3Data.value); let chart3 = getBarChart1(chart3Data.name, chart3Data.value);
...@@ -257,7 +264,22 @@ const handleClickCompany = (index) => { ...@@ -257,7 +264,22 @@ const handleClickCompany = (index) => {
}, 100); }, 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([ const industryList = ref([
// { // {
...@@ -278,34 +300,25 @@ const companyInfo = ref({ ...@@ -278,34 +300,25 @@ const companyInfo = ref({
list: [ list: [
"严格限制外国敏感实体(FEOC)参与补贴", "严格限制外国敏感实体(FEOC)参与补贴",
"取消电动汽车补贴(2025年底生效)", "取消电动汽车补贴(2025年底生效)",
"任何实体若与被禁止外国实体签订超100万美元的关键技术许可协议,则不得向其提供联邦补贴", "任何实体若与被禁止外国实体签订超100万美元的关键技术许可协议,则不得向其提供联邦补贴"
], ]
}, },
data2: { data2: {
icon: icon2, icon: icon2,
title: "融资情况", title: "融资情况",
data: { data: {
time: ["2025-06", "2025-07", "2025-08"], time: ["2025-06", "2025-07", "2025-08"],
value: [1.12, 1.42, 1.5], value: [1.12, 1.42, 1.5]
}, }
}, },
data3: { data3: {
icon: icon3, icon: icon3,
title: "研发投入", title: "研发投入",
data: { data: {
time: [ time: ["2023Q3", "2023Q4", "2024Q1", "2024Q2", "2024Q3", "2024Q4", "2025Q1", "2025Q2"],
"2023Q3", value: [50, 53, 52, 54, 58, 60, 51, 56, 64]
"2023Q4", }
"2024Q1", }
"2024Q2",
"2024Q3",
"2024Q4",
"2025Q1",
"2025Q2",
],
value: [50, 53, 52, 54, 58, 60, 51, 56, 64],
},
},
}); });
// 获取行业领域列表 // 获取行业领域列表
...@@ -323,7 +336,7 @@ const curHylyId = ref(""); ...@@ -323,7 +336,7 @@ const curHylyId = ref("");
// 根据行业领域id获取公司列表 // 根据行业领域id获取公司列表
const handleGetCompanyListById = async () => { const handleGetCompanyListById = async () => {
const params = { const params = {
id: curHylyId.value, id: curHylyId.value
}; };
try { try {
const res = await getCompanyList(params); const res = await getCompanyList(params);
...@@ -339,15 +352,15 @@ const handleGetCompanyListById = async () => { ...@@ -339,15 +352,15 @@ const handleGetCompanyListById = async () => {
// 根据法案ID 获取行业领域统计 // 根据法案ID 获取行业领域统计
const handleGetIndustryHyly = async () => { const handleGetIndustryHyly = async () => {
const params = { const params = {
id: 1, id: 1
}; };
try { try {
const res = await getIndustryHyly(params); const res = await getIndustryHyly(params);
// console.log('行业领域统计', res); // console.log('行业领域统计', res);
chart1Data.value.name = res.data.map((item) => { chart1Data.value.name = res.data.map(item => {
return item.hylyName; return item.hylyName;
}); });
chart1Data.value.value = res.data.map((item) => { chart1Data.value.value = res.data.map(item => {
return item.companyNum; return item.companyNum;
}); });
} catch (error) {} } catch (error) {}
...@@ -393,14 +406,19 @@ onMounted(async () => { ...@@ -393,14 +406,19 @@ onMounted(async () => {
position: absolute; position: absolute;
top: 14px; top: 14px;
right: 12px; right: 12px;
width: 32px; display: flex;
height: 32px; justify-content: flex-end;
gap: 4px;
.icon {
width: 28px;
height: 28px;
img { img {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
} }
} }
}
.left { .left {
margin-top: 16px; margin-top: 16px;
width: 480px; width: 480px;
...@@ -414,11 +432,7 @@ onMounted(async () => { ...@@ -414,11 +432,7 @@ onMounted(async () => {
box-sizing: border-box; box-sizing: border-box;
border: 1px solid rgba(231, 241, 255, 1); border: 1px solid rgba(231, 241, 255, 1);
border-radius: 4px; border-radius: 4px;
background: linear-gradient( background: linear-gradient(180deg, rgba(246, 251, 255, 1), rgba(246, 251, 255, 0) 100%);
180deg,
rgba(246, 251, 255, 1),
rgba(246, 251, 255, 0) 100%
);
} }
.left-center { .left-center {
margin-top: 12px; margin-top: 12px;
...@@ -461,13 +475,15 @@ onMounted(async () => { ...@@ -461,13 +475,15 @@ onMounted(async () => {
} }
.left-footer { .left-footer {
margin: 0 auto; margin: 0 auto;
margin-top: 5px;
width: 446px; width: 446px;
height: 520px; height: 520px;
overflow: auto; overflow: hidden;
.item-box {
height: 480px;
overflow: hidden;
.item { .item {
width: 100%; width: 100%;
height: 40px; height: 48px;
border-radius: 4px; border-radius: 4px;
border-bottom: 1px solid rgba(243, 243, 244, 1); border-bottom: 1px solid rgba(243, 243, 244, 1);
display: flex; display: flex;
...@@ -521,6 +537,23 @@ onMounted(async () => { ...@@ -521,6 +537,23 @@ onMounted(async () => {
color: rgba(22, 119, 255, 1) !important; 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 { .right {
margin-top: 16px; margin-top: 16px;
...@@ -690,11 +723,7 @@ onMounted(async () => { ...@@ -690,11 +723,7 @@ onMounted(async () => {
box-sizing: border-box; box-sizing: border-box;
border: 1px solid rgba(231, 241, 255, 1); border: 1px solid rgba(231, 241, 255, 1);
border-radius: 4px; border-radius: 4px;
background: linear-gradient( background: linear-gradient(180deg, rgba(246, 251, 255, 1), rgba(246, 251, 255, 0) 100%);
180deg,
rgba(246, 251, 255, 1),
rgba(246, 251, 255, 0) 100%
);
} }
} }
.dialog-box3 { .dialog-box3 {
...@@ -731,11 +760,7 @@ onMounted(async () => { ...@@ -731,11 +760,7 @@ onMounted(async () => {
box-sizing: border-box; box-sizing: border-box;
border: 1px solid rgba(231, 241, 255, 1); border: 1px solid rgba(231, 241, 255, 1);
border-radius: 4px; border-radius: 4px;
background: linear-gradient( background: linear-gradient(180deg, rgba(246, 251, 255, 1), rgba(255, 255, 255, 0) 100%);
180deg,
rgba(246, 251, 255, 1),
rgba(255, 255, 255, 0) 100%
);
} }
} }
} }
......
<template> <template>
<div class="wrapper"> <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="main">
<div class="left"> <div class="left">
<div class="left-header"> <div class="left-header">
...@@ -37,9 +44,20 @@ ...@@ -37,9 +44,20 @@
<div class="icon"> <div class="icon">
<img src="./assets/images/ai-avator.png" alt="" /> <img src="./assets/images/ai-avator.png" alt="" />
</div> </div>
<div class="text">{{ `已深度思考(用时6秒钟)` }}</div> <div class="text">{{ `已深度思考` }}</div>
</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>
<!-- 用户消息 --> <!-- 用户消息 -->
<div v-else class="user-item"> <div v-else class="user-item">
...@@ -67,7 +85,7 @@ ...@@ -67,7 +85,7 @@
</div> </div>
</div> </div>
<div class="right-main-footer"> <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="input-footer">
<div class="icon1"> <div class="icon1">
<el-tooltip effect="dark" content="录音" placement="top"> <el-tooltip effect="dark" content="录音" placement="top">
...@@ -94,11 +112,20 @@ ...@@ -94,11 +112,20 @@
</template> </template>
<script setup> <script setup>
import { ref, onMounted, onUnmounted } from "vue"; import { ref, onMounted, onUnmounted, nextTick } from "vue";
import { fetchEventSource } from "@microsoft/fetch-event-source"; import { fetchEventSource } from "@microsoft/fetch-event-source";
import MarkdownIt from "markdown-it"; import MarkdownIt from "markdown-it";
import { ElMessage } from "element-plus"; import { ElMessage } from "element-plus";
import { getChat } from "@/api/chat"; import { getChat } from "@/api/chat";
import router from "@/router/index";
import json5 from "json5";
// 返回综合检索
const handleBackHome = () => {
router.push({
path: "/comprehensiveSearch"
});
};
const contentContainer = ref(null); const contentContainer = ref(null);
...@@ -149,11 +176,38 @@ const addMessage = (type, content) => { ...@@ -149,11 +176,38 @@ const addMessage = (type, content) => {
const updateLastAIMessage = content => { const updateLastAIMessage = content => {
const lastMessage = messages.value[messages.value.length - 1]; const lastMessage = messages.value[messages.value.length - 1];
if (lastMessage && lastMessage.type === "ai") { if (lastMessage && lastMessage.type === "ai") {
if (isCurAnswerMessage.value) {
lastMessage.content = content; lastMessage.content = content;
} else {
lastMessage.think = content;
}
scrollToBottom(); 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 连接 // 使用 fetchEventSource 连接
const connectSSE = async question => { const connectSSE = async question => {
// 添加用户消息 // 添加用户消息
...@@ -168,68 +222,71 @@ const connectSSE = async question => { ...@@ -168,68 +222,71 @@ const connectSSE = async question => {
abortController.value = new AbortController(); abortController.value = new AbortController();
const params = { const params = {
query: "如何检索?", // question: "川普1期对华制裁领域分布情况"
knowledge_base_name: "kb_test251112", question: question
top_k: 6, // knowledge_base_name: "kb_test251112",
score_threshold: 0.5, // top_k: 6,
metadata: { year: 2024 } // score_threshold: 0.5,
// metadata: { year: 2024 }
}; };
try { fetchEventSource("/sseChat/rag/chat/stream", {
await fetchEventSource("/chat/knowledge_base/search_docs", {
method: "POST", method: "POST",
headers: { headers: {
"Content-Type": "application/json" "Content-Type": "application/json"
}, },
body: JSON.stringify(params), body: JSON.stringify(params),
signal: abortController.value.signal, signal: abortController.value.signal,
onopen: async response => { openWhenHidden: true,
console.log("SSE 连接已建立", response.status); async onopen(res) {
if (response.status !== 200) {
throw new Error(`请求失败: ${response.status}`);
}
},
onmessage: event => {
try {
if (event.data === "[DONE]") {
// 流式输出结束
isLoading.value = false; 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; return;
} }
if (res.event === "start_of_agent" && msgData.agent_name === "answer") {
const data = JSON.parse(event.data); isCurAnswerMessage.value = true;
aiMessage.value = "";
if (data.type === "content" && data.content) { }
// 流式更新内容 if (res.event === "message") {
updateLastAIMessage(prev => prev + data.content); let content = msgData.delta.content;
} else if (data.type === "error") { console.log("msgData", msgData);
throw new Error(data.message || "请求失败"); 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);
} }
}, },
onerror(error) {
onclose: () => { ElMessage({
console.log("SSE 连接已关闭"); message: "问答报错!",
isLoading.value = false; type: "warning"
},
onerror: error => {
console.error("SSE 连接错误:", error);
ElMessage.error("连接失败,请重试");
isLoading.value = false;
// 不要抛出错误,否则会重试
}
}); });
} catch (error) { abortController.value.abort();
console.error("SSE 请求失败:", error); abortController.value = new AbortController();
if (error.name !== "AbortError") { throw new Error(error);
ElMessage.error(error.message || "请求失败");
}
isLoading.value = false;
} }
}).catch(error => {
ElMessage({
message: "问答报错!",
type: "warning"
});
abortController.value.abort();
abortController.value = new AbortController();
throw new Error(error);
});
}; };
const chat = async () => { const chat = async () => {
...@@ -281,7 +338,7 @@ const chatList = ref([ ...@@ -281,7 +338,7 @@ const chatList = ref([
}, },
{ {
id: 3, id: 3,
title: "列举 2025 年科技产品" title: "列举2025年科技产品"
}, },
{ {
id: 4, id: 4,
...@@ -368,6 +425,16 @@ onUnmounted(() => { ...@@ -368,6 +425,16 @@ onUnmounted(() => {
background: url("../assets/images/header-bg.png"); background: url("../assets/images/header-bg.png");
box-sizing: border-box; box-sizing: border-box;
padding-left: 160px; padding-left: 160px;
display: flex;
.header-item {
margin: 0 3px;
}
.back-item {
cursor: pointer;
&:hover {
color: #ccc;
}
}
} }
.main { .main {
margin-top: 16px; margin-top: 16px;
...@@ -536,10 +603,27 @@ onUnmounted(() => { ...@@ -536,10 +603,27 @@ onUnmounted(() => {
/* 对话内容区域 */ /* 对话内容区域 */
.chat-content { .chat-content {
overflow-x: hidden;
overflow-y: auto; overflow-y: auto;
// padding: 20px; // padding: 20px;
background: #fff; 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 { .message-list {
padding-bottom: 20px; padding-bottom: 20px;
} }
...@@ -569,10 +653,43 @@ onUnmounted(() => { ...@@ -569,10 +653,43 @@ onUnmounted(() => {
text-align: left; 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 { .ai-content {
margin-top: 10px; margin-top: 10px;
width: 900px; width: 900px;
margin-left: 26px; margin-left: 26px;
background: rgba(246, 250, 255, 1);
padding: 1px 10px;
border-radius: 5px;
} }
} }
.user-item { .user-item {
......
<template> <template>
<div class="wrapper"> <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">
<div class="main-header"> <div class="main-header">
<div class="title">{{ "一站式信息智能检索子系统" }}</div> <div class="title">{{ "一站式信息智能检索子系统" }}</div>
...@@ -92,7 +97,9 @@ ...@@ -92,7 +97,9 @@
tag2: item.tag.status === 2, tag2: item.tag.status === 2,
tag3: item.tag.status === 3 tag3: item.tag.status === 3
}" }"
>{{ item.tag.name }}</div> >
{{ item.tag.name }}
</div>
</div> </div>
</div> </div>
</div> </div>
...@@ -112,7 +119,7 @@ ...@@ -112,7 +119,7 @@
<script setup> <script setup>
import { ref, onMounted } from "vue"; import { ref, onMounted } from "vue";
import router from '@/router/index' import router from "@/router/index";
import getWordCloudChart from "./utils/wordCloud"; import getWordCloudChart from "./utils/wordCloud";
import setChart from "@/utils/setChart"; import setChart from "@/utils/setChart";
...@@ -122,7 +129,6 @@ import Img3 from "./assets/images/box3-img3.png"; ...@@ -122,7 +129,6 @@ import Img3 from "./assets/images/box3-img3.png";
import Img4 from "./assets/images/box3-img4.png"; import Img4 from "./assets/images/box3-img4.png";
import Img5 from "./assets/images/box3-img5.png"; import Img5 from "./assets/images/box3-img5.png";
const headerInfoList = ref([ const headerInfoList = ref([
{ {
name: "美国", name: "美国",
...@@ -221,7 +227,6 @@ const box2Data = ref([ ...@@ -221,7 +227,6 @@ const box2Data = ref([
{ name: "加强供应链风险管理", value: 73 } { name: "加强供应链风险管理", value: 73 }
]); ]);
const box3List = ref([ const box3List = ref([
{ {
img: Img1, img: Img1,
...@@ -282,23 +287,21 @@ const box3List = ref([ ...@@ -282,23 +287,21 @@ const box3List = ref([
// 点击智能问答,进入智能问答页 // 点击智能问答,进入智能问答页
const handleToChat = () => { const handleToChat = () => {
router.push({ router.push({
path: '/chat' path: "/chat"
}) });
} };
// 点击全文搜索,进入搜索结果页 // 点击全文搜索,进入搜索结果页
const handleToSearchResults = () => { const handleToSearchResults = () => {
router.push({ router.push({
path: '/searchResults' path: "/searchResults"
}) });
} };
onMounted(() => { onMounted(() => {
const box2Chart = getWordCloudChart(box2Data.value) const box2Chart = getWordCloudChart(box2Data.value);
setChart(box2Chart, 'box2Chart') setChart(box2Chart, "box2Chart");
}) });
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
...@@ -354,6 +357,16 @@ onMounted(() => { ...@@ -354,6 +357,16 @@ onMounted(() => {
background: url("./assets/images/header-bg.png"); background: url("./assets/images/header-bg.png");
box-sizing: border-box; box-sizing: border-box;
padding-left: 160px; padding-left: 160px;
display: flex;
.header-item {
margin: 0 3px;
}
.back-item {
cursor: pointer;
&:hover {
color: #ccc;
}
}
} }
.main { .main {
width: 100%; width: 100%;
...@@ -602,7 +615,7 @@ onMounted(() => { ...@@ -602,7 +615,7 @@ onMounted(() => {
border-radius: 10px; border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1); box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background: rgba(255, 255, 255, 1); background: rgba(255, 255, 255, 1);
.box2-main{ .box2-main {
height: 390px; height: 390px;
} }
} }
......
...@@ -32,8 +32,11 @@ ...@@ -32,8 +32,11 @@
<div class="home-main" :class="{ scrollHomeMain: isShow }" ref="containerRef"> <div class="home-main" :class="{ scrollHomeMain: isShow }" ref="containerRef">
<div class="home-main-header"> <div class="home-main-header">
<div class="home-main-header-top" v-show="!isShow"> <div class="home-main-header-top" v-show="!isShow">
<span>国家科技安全 </span>> <span>中美博弈概览 </span>> <div class="header-item">国家科技安全</div>
<span>科技政令</span> <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>
<div class="home-main-header-center" v-show="!isShow"> <div class="home-main-header-center" v-show="!isShow">
<el-input v-model="input" style="width: 838px; height: 100%" placeholder="搜索科技政令" /> <el-input v-model="input" style="width: 838px; height: 100%" placeholder="搜索科技政令" />
...@@ -638,6 +641,13 @@ import Message1 from "./assets/images/message-icon1.png"; ...@@ -638,6 +641,13 @@ import Message1 from "./assets/images/message-icon1.png";
import Message2 from "./assets/images/message-icon2.png"; import Message2 from "./assets/images/message-icon2.png";
import Message3 from "./assets/images/message-icon3.png"; import Message3 from "./assets/images/message-icon3.png";
// 返回首页
const handleBackHome = () => {
router.push({
path: '/overview'
})
}
const containerRef = ref(null); const containerRef = ref(null);
const { isShow } = useContainerScroll(containerRef); const { isShow } = useContainerScroll(containerRef);
const currentPage = ref(1); const currentPage = ref(1);
...@@ -855,7 +865,6 @@ const keyDecreeList = ref([ ...@@ -855,7 +865,6 @@ const keyDecreeList = ref([
} }
]); ]);
// 政令重点条款 // 政令重点条款
const wordCloudData = [ const wordCloudData = [
{ name: "与马斯克公开冲突", value: 100 }, { name: "与马斯克公开冲突", value: 100 },
...@@ -1024,7 +1033,6 @@ const handleClickCate = cate => { ...@@ -1024,7 +1033,6 @@ const handleClickCate = cate => {
activeCate.value = cate; activeCate.value = cate;
}; };
const calendarData = ref([ const calendarData = ref([
["2025-01-01", 20], ["2025-01-01", 20],
["2025-01-05", 120], ["2025-01-05", 120],
...@@ -1205,6 +1213,16 @@ onMounted(async () => { ...@@ -1205,6 +1213,16 @@ onMounted(async () => {
color: #fff; color: #fff;
box-sizing: border-box; box-sizing: border-box;
padding-left: 160px; padding-left: 160px;
display: flex;
.header-item {
margin: 0 3px;
}
.back-item {
cursor: pointer;
&:hover {
color: #ccc;
}
}
} }
.home-main-header-center { .home-main-header-center {
margin-top: 48px; margin-top: 48px;
......
...@@ -118,7 +118,7 @@ ...@@ -118,7 +118,7 @@
</div> </div>
</div> </div>
</div> </div>
<div class="tool-box"> <!-- <div class="tool-box">
<div class="tool1"> <div class="tool1">
<img src="./assets/icons/tool-icon1.png" alt="" /> <img src="./assets/icons/tool-icon1.png" alt="" />
</div> </div>
...@@ -128,7 +128,7 @@ ...@@ -128,7 +128,7 @@
<div class="tool3"> <div class="tool3">
<img src="./assets/icons/tool-icon3.png" alt="" /> <img src="./assets/icons/tool-icon3.png" alt="" />
</div> </div>
</div> </div> -->
</div> </div>
</template> </template>
...@@ -622,49 +622,49 @@ onMounted(() => { ...@@ -622,49 +622,49 @@ onMounted(() => {
} }
} }
} }
.tool-box { // .tool-box {
position: fixed; // position: fixed;
z-index: 10000; // z-index: 10000;
bottom: 80px; // bottom: 80px;
left: 0; // left: 0;
width: 48px; // width: 48px;
height: 144px; // height: 144px;
border-radius: 0px 10px 10px 0px; // border-radius: 0px 10px 10px 0px;
box-shadow: 0px 0px 15px 0px rgba(22, 119, 255, 0.1); // box-shadow: 0px 0px 15px 0px rgba(22, 119, 255, 0.1);
background: rgba(255, 255, 255, 1); // background: rgba(255, 255, 255, 1);
.tool1 { // .tool1 {
width: 17px; // width: 17px;
height: 18px; // height: 18px;
margin-top: 17px; // margin-top: 17px;
margin-left: 16px; // margin-left: 16px;
cursor: pointer; // cursor: pointer;
img { // img {
width: 100%; // width: 100%;
height: 100%; // height: 100%;
} // }
} // }
.tool2 { // .tool2 {
width: 22px; // width: 22px;
height: 20px; // height: 20px;
margin-top: 26px; // margin-top: 26px;
margin-left: 14px; // margin-left: 14px;
cursor: pointer; // cursor: pointer;
img { // img {
width: 100%; // width: 100%;
height: 100%; // height: 100%;
} // }
} // }
.tool3 { // .tool3 {
width: 20px; // width: 20px;
height: 20px; // height: 20px;
margin-top: 25px; // margin-top: 25px;
margin-left: 15px; // margin-left: 15px;
cursor: pointer; // cursor: pointer;
img { // img {
width: 100%; // width: 100%;
height: 100%; // height: 100%;
} // }
} // }
} // }
} }
</style> </style>
\ No newline at end of file
...@@ -13,7 +13,12 @@ ...@@ -13,7 +13,12 @@
/> />
</div> </div>
<div class="header-right"> <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> </div>
<div class="box1-top" id="chart1"></div> <div class="box1-top" id="chart1"></div>
...@@ -65,7 +70,12 @@ ...@@ -65,7 +70,12 @@
<div class="title">{{ "政令举措落实分析" }}</div> <div class="title">{{ "政令举措落实分析" }}</div>
<div class="header-right1"></div> <div class="header-right1"></div>
<div class="header-right"> <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> </div>
...@@ -108,7 +118,12 @@ ...@@ -108,7 +118,12 @@
<div class="title">{{ "历史相似举措及落实情况" }}</div> <div class="title">{{ "历史相似举措及落实情况" }}</div>
<div class="header-right1"></div> <div class="header-right1"></div>
<div class="header-right"> <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> </div>
<div class="box3-main"> <div class="box3-main">
...@@ -318,20 +333,25 @@ onMounted(() => { ...@@ -318,20 +333,25 @@ onMounted(() => {
line-height: 24px; line-height: 24px;
} }
.header-right { .header-right {
position: absolute;
top: 14px; top: 14px;
right: 12px; right: 12px;
position: absolute; display: flex;
width: 28px; justify-content: flex-end;
gap: 4px;
.header-right-icon{
width: 28px; width: 28px;
img { height: 28px;
img{
width: 100%; width: 100%;
height: 100%; height: 100%;
}
} }
} }
.header-right1 { .header-right1 {
position: absolute; position: absolute;
top: 8px; top: 8px;
right: 60px; right: 84px;
} }
} }
.left { .left {
......
<template> <template>
<div class="home-wrapper"> <div class="home-wrapper">
<div class="home-header"> <div class="home-header">
<span>国家科技安全 </span>> <span>中美博弈概览 </span>> <div class="header-item">国家科技安全</div>
<span>出口管制 </span> <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>
<div class="home-main"> <div class="home-main">
<div class="home-main-header"> <div class="home-main-header">
...@@ -655,12 +658,19 @@ import shoushiIcon from "./assets/images/shoushi.png"; ...@@ -655,12 +658,19 @@ import shoushiIcon from "./assets/images/shoushi.png";
import tianyiIcon from "./assets/images/tianyi.png"; import tianyiIcon from "./assets/images/tianyi.png";
import aircasIcon from "./assets/images/aircas.png"; import aircasIcon from "./assets/images/aircas.png";
const handleToDetail = () => { // 返回首页
const handleBackHome = () => {
router.push({ router.push({
path: '/exportControl/analysis' path: '/overview'
}) })
} }
const handleToDetail = () => {
router.push({
path: "/exportControl/analysis"
});
};
const billList = ref([]); const billList = ref([]);
const curBillListIndex = ref(0); const curBillListIndex = ref(0);
...@@ -1591,6 +1601,16 @@ onMounted(async () => { ...@@ -1591,6 +1601,16 @@ onMounted(async () => {
background: url("@/assets/images/nav-bg.png"); background: url("@/assets/images/nav-bg.png");
box-sizing: border-box; box-sizing: border-box;
padding-left: 160px; padding-left: 160px;
display: flex;
.header-item {
margin: 0 3px;
}
.back-item {
cursor: pointer;
&:hover {
color: #ccc;
}
}
} }
.box1 { .box1 {
......
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
</template> </template>
<script setup> <script setup>
import { defineProps, defineEmits } from "vue";
import { ArrowRight } from "@element-plus/icons-vue"; import { ArrowRight } from "@element-plus/icons-vue";
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
......
<template> <template>
<div class="home-wrapper"> <div class="home-wrapper">
<div class="home-header"> <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>
<div class="home-main"> <div class="home-main">
<div class="home-main-header"> <div class="home-main-header">
...@@ -655,6 +660,13 @@ import shoushiIcon from "./assets/images/shoushi.png"; ...@@ -655,6 +660,13 @@ import shoushiIcon from "./assets/images/shoushi.png";
import tianyiIcon from "./assets/images/tianyi.png"; import tianyiIcon from "./assets/images/tianyi.png";
import aircasIcon from "./assets/images/aircas.png"; import aircasIcon from "./assets/images/aircas.png";
// 返回首页
const handleBackHome = () => {
router.push({
path: '/overview'
})
}
const handleToDetail = () => { const handleToDetail = () => {
router.push({ router.push({
path: "/exportControl/analysis" path: "/exportControl/analysis"
...@@ -1591,6 +1603,16 @@ onMounted(async () => { ...@@ -1591,6 +1603,16 @@ onMounted(async () => {
background: url("@/assets/images/nav-bg.png"); background: url("@/assets/images/nav-bg.png");
box-sizing: border-box; box-sizing: border-box;
padding-left: 160px; padding-left: 160px;
display: flex;
.header-item {
margin: 0 3px;
}
.back-item {
cursor: pointer;
&:hover {
color: #ccc;
}
}
} }
.box1 { .box1 {
......
差异被折叠。
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论