提交 6c85608e authored 作者: huhuiqing's avatar huhuiqing

Merge branch 'master' of http://8.140.26.4:10003/caijian/risk-monitor into dev_hhq

# Conflicts: # src/views/gjOverView/index.vue
<template>
<div class="button" @click="emit('click')" :class="{ activeButton: isActive }">
<slot name="default"></slot>
</div>
</template>
<script setup>
const props = defineProps({
isActive: {
type: Boolean,
default: false
}
});
const emit = defineEmits(["click"]);
</script>
<style lang="scss" scoped>
.button {
/* 复选标签 */
height: 28px;
/* 自动布局 */
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
border: 1px solid rgb(230, 231, 232);
border-radius: 4px;
background-color: rgb(255, 255, 255);
color: rgb(59, 65, 75);
font-size: 16px;
font-weight: 400;
cursor: pointer;
padding-left: 8px;
padding-right: 8px;
}
.activeButton {
border: 1px solid rgb(10, 87, 166);
background: rgb(246, 250, 255);
color: rgb(10, 87, 166);
}
</style>
<template>
<div class="buttonList" :style="{ gap: gap + 'px' }">
<Button class="button" @click="setActiveIndex(item)" :is-active="isActive(item)" v-for="item in list" :key="item.id">
<slot name="item" :item="item">
{{ item.text }}
</slot>
</Button>
</div>
</template>
<script setup>
import { ref } from "vue";
import Button from "../button/button.vue";
const props = defineProps({
activeId: {
type: [Number, Array],
default: 0
},
gap: {
type: Number,
default: 8
},
multiple: {
type: Boolean,
default: false
},
list: {
type: Array,
default: function () {
return [];
}
}
});
const emit = defineEmits(["click"]);
const isActive = item => {
if (!props.multiple) {
return item.id === props.activeId;
} else {
return props.activeId.includes(item.id);
}
};
function setActiveIndex(item) {
if (!props.multiple) {
if (props.activeId === item.id) {
return;
}
emit("click", item.id);
} else {
let idList;
if (props.activeId.includes(item.id)) {
idList = props.activeId.filter(currentId => currentId !== item.id);
} else {
idList = props.activeId.concat(item.id);
}
emit("click", idList);
}
}
</script>
<style lang="scss" scoped>
.buttonList {
display: flex;
gap: 8px;
}
</style>
差异被折叠。
// 法案相关
import BillHome from "@/views/bill/billHome/index.vue";
import BillLayoutContainer from "@/views/bill/billLayout/index.vue";
import BillLayout from "@/views/bill/index.vue";
import BillIntroduction from "@/views/bill/introdoction/index.vue";
import BillBackground from "@/views/bill/background/index.vue";
import BillTemplate from "@/views/bill/template/index.vue";
import BillDeepDigLayout from "@/views/bill/deepDig/index.vue";
import BillDeepDigProcessOverview from "@/views/bill/deepDig/processOverview/index.vue";
import BillDeepDigProcessAnalysis from "@/views/bill/deepDig/processAnalysis/index.vue";
import BillDeepDigPoliContribution from "@/views/bill/deepDig/poliContribution/index.vue";
import BillInfluenceLayout from "@/views/bill/influence/index.vue";
import BillInfluenceIndustry from "@/views/bill/influence/industry/index.vue";
import BillInfluenceScientificResearch from "@/views/bill/influence/scientificResearch/index.vue";
import BillRelevantCircumstance from "@/views/bill/relevantCircumstance/index.vue";
const billRoutes = [
// 法案系统路由
{
path: "/billHome",
name: "BillHome",
component: BillHome,
meta: {
title: "法案首页"
}
},
{
path: "/billLayout",
name: "BillLayoutContainer",
component: BillLayoutContainer,
redirect: "/billLayout/bill",
meta: {
title: "法案布局"
},
children: [
// 法案分析路由
{
path: "bill",
name: "BillLayout",
component: BillLayout,
redirect: "/billLayout/bill/introduction",
meta: {
title: "法案分析"
},
children: [
{
path: "introduction",
name: "BillIntroduction",
component: BillIntroduction,
meta: { title: "法案简介" }
},
{
path: "background",
name: "BillBackground",
component: BillBackground,
meta: { title: "法案背景" }
},
{
path: "template",
name: "BillTemplate",
component: BillTemplate,
meta: { title: "内容概要" }
}
]
},
// 深度挖掘路由
{
path: "deepDig",
name: "BillDeepDigLayout",
component: BillDeepDigLayout,
redirect: "/billLayout/deepDig/processOverview",
meta: {
title: "深度挖掘"
},
children: [
{
path: "processOverview",
name: "BillDeepDigProcessOverview",
component: BillDeepDigProcessOverview,
meta: { title: "流程概要" }
},
{
path: "processAnalysis",
name: "BillDeepDigProcessAnalysis",
component: BillDeepDigProcessAnalysis,
meta: { title: "流程分析" }
},
{
path: "poliContribution",
name: "BillDeepDigPoliContribution",
component: BillDeepDigPoliContribution,
meta: { title: "政治献金" }
}
]
},
// 影响分析路由
{
path: "influence",
name: "BillInfluenceLayout",
component: BillInfluenceLayout,
redirect: "/billLayout/influence/industry",
meta: {
title: "影响分析"
},
children: [
{
path: "industry",
name: "BillInfluenceIndustry",
component: BillInfluenceIndustry,
meta: { title: "对华产业影响" }
},
{
path: "scientificResearch",
name: "BillInfluenceScientificResearch",
component: BillInfluenceScientificResearch,
meta: { title: "对华科研影响" }
}
]
},
{
path: "relevantCircumstance",
name: "BillRelevantCircumstance",
component: BillRelevantCircumstance,
meta: {
title: "相关情况"
}
}
]
},
]
export default billRoutes
\ No newline at end of file
// 综合搜索
import ComprehensiveSearch from '@/views/comprehensiveSearch/index.vue'
import SearchResults from '@/views/comprehensiveSearch/searchResults/index.vue'
import Chat from '@/views/comprehensiveSearch/chat/index.vue'
const comprehensiveSearchRoutes = [
// 综合搜索
{
path: "/comprehensiveSearch",
name: "comprehensiveSearch",
component: ComprehensiveSearch,
meta: {
title: "综合搜索"
}
},
{
path: "/searchResults",
name: "searchResults",
component: SearchResults,
meta: {
title: "搜索结果"
}
},
{
path: "/chat",
name: "chat",
component: Chat,
meta: {
title: "智能问答"
}
},
]
export default comprehensiveSearchRoutes
\ No newline at end of file
// 合作限制
import CooperationRestrictions from "@/views/coopRestriction/index.vue";
import CooperationRestrictionsDetail from "@/views/coopRestriction/detail/index.vue";
const cooperationRestrictionsRoutes = [
// 合作限制
{
path: "/cooperationRestrictions",
name: "CooperationRestrictions",
component: CooperationRestrictions,
meta: {
title: "合作限制"
}
},
// 合作限制详情
{
path: "/coopRestriction/detail",
name: "CooperationRestrictionsDetail",
component: CooperationRestrictionsDetail,
meta: {
title: "合作限制详情"
}
},
]
export default cooperationRestrictionsRoutes
\ No newline at end of file
// 政令
import Decree from "@/views/decree/decreeHome/index.vue";
import DecreeLayoutContainer from "@/views/decree/decreeLayout/index.vue";
import DecreeOverviewLayout from "@/views/decree/decreeLayout/overview/index.vue";
import DecreeIntroduction from "@/views/decree/decreeLayout/overview/introduction/index.vue";
import DecreeBackground from "@/views/decree/decreeLayout/overview/background/index.vue";
import DecreeDeepDig from "@/views/decree/decreeLayout/deepdig/index.vue";
import DecreeInfluence from "@/views/decree/decreeLayout/influence/index.vue";
import Institution from "@/views/decree/institution/index.vue"
const decreeRoutes = [
// 政令首页
{
path: "/decree",
name: "Decree",
component: Decree,
meta: {
title: "政令"
}
},
{
path: "/decreeLayout",
name: "DecreeLayoutContainer",
component: DecreeLayoutContainer,
redirect: "/decreeLayout/overview",
meta: {
title: "政令布局"
},
children: [
{
path: "overview",
name: "DecreeOverviewLayout",
component: DecreeOverviewLayout,
redirect: "/decreeLayout/overview/introduction",
meta: {
title: "政令概况"
},
children: [
{
path: "introduction",
name: "DecreeIntroduction",
component: DecreeIntroduction,
meta: { title: "政令简介" }
},
{
path: "background",
name: "DecreeBackground",
component: DecreeBackground,
meta: { title: "政令背景" }
}
]
},
// 深度挖掘路由
{
path: "deepDig",
name: "DeepDig",
component: DecreeDeepDig,
meta: {
title: "深度挖掘"
}
},
// 影响分析路由
{
path: "influence",
name: "DecreeInfluence",
component: DecreeInfluence,
meta: {
title: "影响分析"
}
}
]
},
{
path: "/institution",
name: "Institution",
component: Institution,
meta: {
title: "行政机构主页"
}
}
]
export default decreeRoutes
\ No newline at end of file
// 出口管制
import ExportControl from "@/views/exportControl/index.vue";
const exportControlRoutes = [
// 出口管制首页
{
path: "/exportControl",
name: "ExportControl",
component: ExportControl,
meta: {
title: "出口管制"
}
},
{
path: "/exportControlAnalysis",
name: "exportControlAnalysis",
component: () => import("@/views/exportControl/analysis/index.vue"),
redirect: "/exportControlAnalysis/overview",
meta: {
title: "分析页"
},
children: [
{
path: "overview",
name: "exportControlAnalysisOverview",
component: () => import("@/views/exportControl/analysis/content/overview.vue"),
meta: {
title: "制裁概况"
}
},
{
path: "deepDig",
name: "exportControlAnalysisDeepDig",
component: () => import("@/views/exportControl/analysis/content/deepDig.vue"),
meta: {
title: "深度挖掘"
}
},
{
path: "influence",
name: "exportControlAnalysisInfluence",
component: () => import("@/views/exportControl/analysis/content/influence.vue"),
meta: {
title: "影响分析"
}
},
]
},
{
path: "/exportControl/analysis",
name: "analysis",
component: () => import("@/views/exportControl/analysis/index.vue"),
meta: {
title: "分析页"
}
},
{
path: "/exportControl/infoplatform",
name: "infoplatform",
component: () => import("@/views/exportControl/infoPlatform/index.vue"),
meta: {
title: "信息平台"
}
},
{
path: "/exportControl/rulelimit",
name: "rulelimit",
component: () => import("@/views/exportControl/ruleLimit/index.vue"),
meta: {
title: "规则限制"
}
},
{
path: "/exportControl/ruledetail",
name: "ruledetail",
component: () => import("@/views/exportControl/ruleDetail/index.vue"),
meta: {
title: "规则详情"
}
},
{
path: "/exportControl/researchfunding",
name: "researchfunding",
component: () => import("@/views/exportControl/researchFunding/index.vue"),
meta: {
title: "科研资助"
}
},
]
export default exportControlRoutes
\ No newline at end of file
// 投融资限制
import Finance from "@/views/finance/index.vue";
const financeRoutes = [
// 投融资限制
{
path: "/finance",
name: "finance",
component: Finance,
meta: {
title: "投融资限制"
}
},
]
export default financeRoutes
\ No newline at end of file
// 市场准入限制
import MarketAccessRestrictions from "@/views/marketAccessRestrictions/marketAccessHome/index.vue";
import MarketAccessLayout from "@/views/marketAccessRestrictions/marketAccessLayout/index.vue";
import MarketAccessOverview from "@/views/marketAccessRestrictions/marketAccessLayout/overview/index.vue";
import MarketAccessCase from "@/views/marketAccessRestrictions/marketAccessLayout/case/index.vue";
import MarketSingleCaseLayout from "@/views/marketAccessRestrictions/singleCaseLayout/index.vue";
import MarketSingleCaseOverview from "@/views/marketAccessRestrictions/singleCaseLayout/overview/index.vue";
import MarketSingleCaseDeepdig from "@/views/marketAccessRestrictions/singleCaseLayout/deepdig/index.vue";
const marketAccessRestrictionsRoutes = [
// 市场准入限制首页
{
path: "/marketAccessRestrictions",
name: "MarketAccessRestrictions",
component: MarketAccessRestrictions,
meta: {
title: "市场准入限制"
}
},
{
path: "/marketAccessLayout",
name: "MarketAccessLayout",
component: MarketAccessLayout,
redirect: "/marketAccessLayout/overview",
meta: {
title: "市场准入限制布局"
},
children: [
{
path: "overview",
name: "MarketAccessOverview",
component: MarketAccessOverview,
meta: {
title: "调查概况"
}
},
{
path: "case",
name: "MarketAccessCase",
component: MarketAccessCase,
meta: {
title: "调查案件"
}
},
]
},
{
path: "/marketSingleCaseLayout",
name: "MarketSingleCaseLayout",
component: MarketSingleCaseLayout,
redirect: "/marketSingleCaseLayout/overview",
meta: {
title: "单次调查案件布局"
},
children: [
{
path: "overview",
name: "MarketSingleCaseOverview",
component: MarketSingleCaseOverview,
meta: {
title: "调查简介"
}
},
{
path: "deepdig",
name: "MarketSingleCaseDeepdig",
component: MarketSingleCaseDeepdig,
meta: {
title: "深度挖掘"
}
}
]
},
]
export default marketAccessRestrictionsRoutes
\ No newline at end of file
//新闻速览
import newsBrief from "@/views/newsBrief/index.vue"
// 新闻事件分析
import NewsAnalysis from "@/views/newsAnalysis/index.vue";
const newsRoutes = [
//新闻速览页面路由
{
path: "/newsBrief",
name: "newsBrief",
component: newsBrief,
meta: {
title: "新闻速览"
}
},
// 新闻事件分析
{
path: "/newsAnalysis",
name: "newsAnalysis",
component: NewsAnalysis,
meta: {
title: "新闻事件分析"
}
},
]
export default newsRoutes
\ No newline at end of file
//中美博弈概览
import overView from "@/views/overView/index.vue";
//GJ概览
import gjOverView from "@/views/gjOverView/index.vue";
const overViewRoutes = [
// 中美博弈概览页面路由
{
path: "/",
redirect: "/overView"
},
{
path: "/overView",
name: "overView",
component: overView,
meta: {
title: "中美博弈概览"
}
},
// GJ概览页面路由
{
path: "/gjOverView",
name: "gjOverView",
component: gjOverView,
meta: {
title: "国家概览"
}
},
]
export default overViewRoutes
\ No newline at end of file
// 门户
import Portal from "@/views/portals/portal/index.vue";
const portalRoutes = [
// 门户
{
path: "/portal",
name: "portal",
component: Portal,
meta: {
title: "门户"
}
},
]
export default portalRoutes
\ No newline at end of file
// 风险信号
import RiskSignal from "@/views/riskSignal/index.vue"
const riskSignalRoutes = [
//风险信号页面路由
{
path: "/riskSignal",
name: "riskSignal",
component: RiskSignal,
meta: {
title: "风险信号"
}
},
]
export default riskSignalRoutes
\ No newline at end of file
// 智库相关
import thinkTank from "@/views/thinkTank/index.vue";
import ThinkTankDetail from "@/views/thinkTank/ThinkTankDetail/index.vue";
import ReportDetail from "@/views/thinkTank/ReportDetail/index.vue";
const thinktankRoutes = [
// 智库系统的主要路由
{
path: "/thinkTank",
name: "thinkTank",
component: thinkTank,
meta: {
title: "首页"
}
},
{
path: "/think-tank/:id",
name: "ThinkTankDetail",
component: ThinkTankDetail,
meta: {
title: "智库详情"
}
},
{
path: "/report/:id",
name: "ReportDetail",
component: ReportDetail,
meta: {
title: "报告详情"
}
},
]
export default thinktankRoutes
\ No newline at end of file
// 智能写报
import WrittingAsstaint from "@/views/writtingAsstaint/index.vue";
const writtingRoutes = [
// 法案系统路由
{
path: "/writtingAsstaint",
name: "writtingAsstaint",
component: WrittingAsstaint,
meta: {
title: "智能写报"
}
}
]
export default writtingRoutes
\ No newline at end of file
......@@ -626,7 +626,7 @@ const curBill = ref({
// 查看详情
const handleClickToDetail = () => {
window.sessionStorage.setItem("billId", curBill.value.billId);
// window.sessionStorage.setItem("billId", curBill.value.billId);
// router.push("/billLayout");
const route = router.resolve("/billLayout");
window.open(route.href, "_blank");
......
......@@ -40,18 +40,27 @@
<div v-for="(message, index) in messages" :key="index">
<!-- AI 消息 -->
<div v-if="message.type === 'ai'" class="ai-item">
<div class="ai-header">
<div class="ai-header" v-if="!isLoading">
<div class="icon">
<img src="./assets/images/ai-avator.png" alt="" />
</div>
<div class="text">{{ `已深度思考` }}</div>
</div>
<div v-if="message.think" class="think-title">思考内容</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> -->
<div v-if="message.source" class="source-title">知识库检索结果:</div>
<div v-if="message.source" class="content source-content">
<div
class="source-item"
v-for="(item, index) in message.source"
:key="index"
v-html="item"
></div>
</div>
<div v-if="message.content" class="answer-title">正文内容</div>
<div
v-if="message.content"
......@@ -85,7 +94,13 @@
</div>
</div>
<div class="right-main-footer">
<el-input @keyup.enter="sendMessage" 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">
......@@ -135,14 +150,14 @@ const abortController = ref(null);
// 消息数据
const messages = ref([
{
type: "user",
content: "你好"
},
{
type: "ai",
content: "您好!我是AI助手,有什么可以帮助您的吗?"
}
// {
// type: "user",
// content: "你好"
// },
// {
// type: "ai",
// content: "您好!我是AI助手,有什么可以帮助您的吗?"
// }
]);
// Markdown 渲染器
......@@ -209,10 +224,109 @@ function parseOuterOnly(json5String, maxDepth = 1) {
}
// 使用 fetchEventSource 连接
// const connectSSE = async question => {
// // 添加用户消息
// addMessage("user", question);
// // 添加空的 AI 消息用于流式更新
// addMessage("ai", "");
// isLoading.value = true;
// // 创建 AbortController 用于取消请求
// abortController.value = new AbortController();
// const params = {
// // question: "川普1期对华制裁领域分布情况"
// question: question
// // knowledge_base_name: "kb_test251112",
// // top_k: 6,
// // score_threshold: 0.5,
// // metadata: { year: 2024 }
// };
// fetchEventSource("/sseChat/rag/chat/stream", {
// method: "POST",
// headers: {
// "Content-Type": "application/json"
// },
// body: JSON.stringify(params),
// signal: abortController.value.signal,
// 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;
// }
// 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();
// }
// }
// },
// onerror(error) {
// ElMessage({
// message: "问答报错!",
// type: "warning"
// });
// 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);
// });
// };
// 定义正则替换
function removeHttpParentheses(str) {
// 匹配 (http://... 开头,以 ) 结尾的内容
return str.replace(/\(http:\/\/[^)]*\)/g, "");
}
// 将字符串中符合以'['开头以'.txt]'结尾的字符串中的'.txt'替换为空
function removeTxtInBrackets(str) {
// 匹配 [开头,.txt]结尾的内容,并替换其中的.txt为空
return str.replace(/\[([^[\]]*)\.txt\]/g, '[$1]');
}
const connectSSE = async question => {
// 添加用户消息
addMessage("user", question);
let mesParam = messages.value.map(item => {
return {
role: item.type,
content: item.content
};
});
// 添加空的 AI 消息用于流式更新
addMessage("ai", "");
......@@ -222,15 +336,17 @@ const connectSSE = async question => {
abortController.value = new AbortController();
const params = {
// question: "川普1期对华制裁领域分布情况"
question: question
// knowledge_base_name: "kb_test251112",
// top_k: 6,
// score_threshold: 0.5,
// metadata: { year: 2024 }
model: "qwen-plus",
messages: mesParam,
stream: true,
temperature: 0.3,
top_k: 9,
score_threshold: 0.1,
prompt_name: "default",
return_direct: false
};
fetchEventSource("/sseChat/rag/chat/stream", {
fetchEventSource("/sseChat/knowledge_base/local_kb/bills-500/chat/completions", {
method: "POST",
headers: {
"Content-Type": "application/json"
......@@ -244,30 +360,50 @@ const connectSSE = async question => {
},
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;
let msgData = JSON.parse(res.data);
if (msgData.docs) {
console.log("docs", msgData.docs);
const lastMessage = messages.value[messages.value.length - 1];
if (lastMessage && lastMessage.type === "ai") {
let newDocs = msgData.docs.map(item => {
return removeHttpParentheses(item);
}).map(val => {
return removeTxtInBrackets(val)
})
lastMessage.source = newDocs;
scrollToBottom();
}
}
if (res.event === "start_of_agent" && msgData.agent_name === "answer") {
if (msgData.choices) {
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();
}
let content = msgData.choices[0].delta.content;
aiMessage.value += content;
updateLastAIMessage(aiMessage.value);
}
// if (res.event === "end_of_workflow") {
// ElMessage.success("问答完成!");
// abortController.value.abort();
// abortController.value = new AbortController();
// return;
// }
// 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();
// }
// }
},
onerror(error) {
ElMessage({
......@@ -441,6 +577,7 @@ onUnmounted(() => {
display: flex;
justify-content: center;
gap: 16px;
margin-bottom: 10px;
.left {
width: 300px;
height: 880px;
......@@ -683,6 +820,31 @@ onUnmounted(() => {
padding: 1px 10px;
border-radius: 5px;
}
.source-title {
margin-left: 26px;
height: 22px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 14px;
font-weight: 400;
line-height: 22px;
letter-spacing: 0px;
text-align: left;
}
.source-content {
background: rgba(245, 245, 245, 0.5);
width: 900px;
margin-left: 26px;
padding: 1px 10px;
border-radius: 5px;
// max-height: 300px;
// overflow-y: auto;
.source-item {
text-indent: 30px;
line-height: 30px;
color: #333;
}
}
.ai-content {
margin-top: 10px;
width: 900px;
......
......@@ -2,7 +2,7 @@
<div class="wrapper">
<div class="header">
<!-- <span>首页 </span>> <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>
......@@ -129,6 +129,13 @@ 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 handleBackHome = () => {
router.push({
path: "/overview"
});
};
const headerInfoList = ref([
{
name: "美国",
......
<template>
<div class="com-title">
<div class="cl1"></div>
<div class="cl2"></div>
<div class="title">{{ title }}</div>
<div class="cl3"></div>
</div>
</template>
<script setup>
import { ref } from "vue";
// 传入的title数据
const props = defineProps({
title: {
type: String,
default: ""
}
});
</script>
<style scoped lang="scss">
* {
margin: 0;
padding: 0;
}
.com-title {
width: 1575px;
height: 42px;
display: flex;
align-items: center;
.cl1 {
width: 24px;
height: 30px;
background-color: rgba(174, 214, 255, 1);
margin-right: 8px;
}
.cl2 {
width: 8px;
height: 30px;
background-color: rgba(174, 214, 255, 1);
margin-right: 8px;
}
.title {
width: 152px;
height: 42px;
text-align: center;
font-size: 32px;
font-weight: 700;
font-family: 'Microsoft YaHei';
line-height: 42px;
margin-right: 8px;
}
.cl3 {
width: 1367px;
height: 1px;
background-color: rgba(174, 214, 255, 1);
box-sizing: border-box;
}
}
</style>
<template>
<div class="data-new">
<div class="left">
<img src="./assets/leftbtn.png" alt="" class="left-btn" />
<img src="./assets/rightbtn.png" alt="" class="right-btn" />
<div class="left-top">
<img src="./assets/icon01.png" alt="" />
<div class="left-top-title">合作限制动态</div>
<span>查看详情 ></span>
</div>
<div class="left-center">
<img src="./assets/usImg.png" alt="" />
<div class="left-center-main">
<div class="left-center-main-title">保护美国资金与专业知识免受敌对研究利用法案</div>
<div class="left-center-main-ul">
<ul>
<li>
<span class="ul-title">数据来源:</span>
<span class="ul-content">美国国会</span>
</li>
<li>
<span class="ul-title">合作限制类型:</span>
<span class="ul-content">科研合作限制</span>
</li>
<li>
<span class="ul-title">发布日期:</span>
<span class="ul-content">2025年10月7日</span>
</li>
<li>
<span class="ul-title">涉及领域</span>
<span class="ul-pie cl1">航空航天</span>
<span class="ul-pie cl2">人工智能</span>
<span class="ul-pie cl3">集成电路</span>
</li>
</ul>
</div>
</div>
<div class="left-center-title">国会法案</div>
</div>
<div class="left-bottom">
<ul>
<li class="left-bottom-li">内容摘要:</li>
</ul>
<div class="left-bottom-content">
该法案已被纳入《国防授权法案》(NDAA)的讨论范畴,并已在参议院通过审议
。该法案规定,将禁止任何与中国等被视为“敌对国”有合作关系的科学家获得联邦资助
。其限制范围极其宽泛,从联合研究、合著论文到指导研究生或博士后几乎全覆盖
。更严厉的是,该条款具有追溯效力,可追溯至过去5年的合作。
</div>
</div>
</div>
<div class="right">
<div class="right-top">
<img src="./assets/icon02.png" alt="" />
<div class="right-top-title">
风险信号
<span>4</span>
</div>
</div>
<div style="margin: 6px 34px 0 23px">
<div v-for="item in list" :key="item.id" class="right-main">
<div class="main-left" :class="{ cl4: item.title === '特别重大', cl5: item.title === '重大风险' }">
{{ item.title }}
</div>
<div class="main-center">{{ item.content }}</div>
<div class="main-right">{{ item.time }}</div>
</div>
</div>
<div class="right-mainbtn">
<img src="./assets/btn.png" alt="" />
查看更多
</div>
</div>
</div>
</template>
<script setup>
import { ref } from "vue";
const list = ref([
{
id: 1,
title: "特别重大",
content: "保护美国资金与专业知识免受敌对研究利用法案",
time: "一天前"
},
{
id: 2,
title: "特别重大",
content: "美国国土安全部终止哈佛大学SEVP认证",
time: "一天前"
},
{
id: 3,
title: "重大风险",
content: "众议院“美中战略竞争特别委员会”向国会提...",
time: "一天前"
},
{
id: 4,
title: "重大风险",
content: '2026财年拨款法案要求重启"中国行动计划"',
time: "一天前"
}
]);
</script>
<style scoped lang="scss">
* {
margin: 0;
padding: 0;
}
.data-new {
width: 1600px;
height: 460px;
display: flex;
justify-content: space-between;
.left {
width: 1064px;
height: 460px;
margin-right: 16px;
border-radius: 10px;
background-color: #fff;
border: 1px solid rgb(234, 236, 238);
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
position: relative;
.left-btn {
width: 24px;
height: 48px;
position: absolute;
top: 223px;
left: 0px;
cursor: pointer;
}
.right-btn {
width: 24px;
height: 48px;
position: absolute;
top: 223px;
right: 0px;
cursor: pointer;
}
.left-top {
width: 100%;
height: 48px;
position: relative;
border-bottom: 1px solid rgb(234, 236, 238);
img {
width: 18px;
height: 18px;
position: absolute;
top: 15px;
left: 23px;
}
span {
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
position: absolute;
top: 19px;
right: 40px;
color: rgb(5, 95, 194);
cursor: pointer;
}
.left-top-title {
margin-left: 60px;
width: 152px;
height: 48px;
background-color: rgb(5, 95, 194);
color: #fff;
font-size: 20px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 26px;
text-align: center;
padding: 11px 16px;
}
}
.left-center {
width: 967px;
height: 208px;
margin-top: 33px;
margin-left: 62px;
border-bottom: 1px solid rgb(234, 236, 238);
position: relative;
img {
width: 148px;
height: 148px;
margin-right: 21px;
}
display: flex;
.left-center-main {
width: 439px;
height: 175px;
.left-center-main-title {
margin-left: 19px;
margin-bottom: 17px;
font-size: 20px;
font-weight: 700;
font-family: "Microsoft YaHei";
color: rgb(5, 95, 194);
}
.left-center-main-ul {
width: 439px;
height: 132px;
ul {
list-style-position: inside;
li {
width: 100%;
height: 24px;
margin-bottom: 12px;
.ul-title {
display: inline-block;
width: 120px;
height: 24px;
font-size: 16px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(59, 65, 75);
}
.ul-content {
color: rgb(59, 65, 75);
font-family: "Microsoft YaHei";
font-size: 16px;
font-weight: 400;
line-height: 24px;
}
.ul-pie {
display: inline-block;
box-sizing: border-box;
padding: 2px 8px;
border: 1px solid;
border-radius: 4px;
margin-right: 8px;
}
.cl1 {
border-color: rgba(186, 224, 255, 1);
background-color: rgba(230, 244, 255, 1);
color: rgba(22, 119, 255, 1);
}
.cl2 {
border-color: rgba(255, 163, 158, 1);
background-color: rgba(255, 241, 240, 1);
color: rgba(245, 34, 45, 1);
}
.cl3 {
border-color: rgba(135, 232, 222, 1);
background-color: rgba(230, 255, 251, 1);
color: rgba(19, 168, 168, 1);
}
}
}
}
}
.left-center-title {
padding: 3px 8px 5px;
height: 32px;
border-radius: 4px;
background-color: rgba(231, 243, 255, 1);
font-size: 18px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(5, 95, 194);
position: absolute;
right: 0px;
top: -1px;
}
}
.left-bottom {
margin: 17px 0 0 62px;
ul {
list-style-position: inside;
.left-bottom-li {
font-size: 16px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(59, 65, 75);
margin-bottom: 10px;
}
}
.left-bottom-content {
width: 943px;
margin-left: 22px;
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 30px;
color: rgb(59, 65, 75);
}
}
}
.right {
width: 520px;
height: 460px;
border-radius: 10px;
background-color: #fff;
border: 1px solid rgb(234, 236, 238);
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
position: relative;
.right-top {
width: 520px;
height: 48px;
border-bottom: 1px solid rgb(234, 236, 238);
position: relative;
img {
width: 21px;
height: 16.84px;
position: absolute;
top: 15.1px;
left: 19.5px;
}
.right-top-title {
padding: 11px 16px;
width: 148px;
height: 48px;
background-color: rgb(206, 79, 81);
font-size: 20px;
font-family: "Microsoft YaHei";
font-weight: 700;
line-height: 26px;
text-align: center;
color: #fff;
margin-left: 60px;
span {
display: inline-block;
width: 24px;
height: 20px;
background-color: rgba(255, 255, 255, 0.3);
font-size: 14px;
font-family: "Microsoft YaHei";
font-weight: 400;
line-height: 22px;
text-align: center;
color: #fff;
border-radius: 100px;
}
}
}
.right-main {
width: 463px;
height: 47px;
border-radius: 2px;
display: flex;
align-items: center;
.main-left {
width: 40px;
height: 40px;
margin: 4px 13px 3px 2px;
border-radius: 50%;
font-size: 12px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 14px;
padding: 6px 4px;
text-align: center;
}
.cl4 {
background-color: rgba(255, 241, 240, 1);
color: rgb(206, 79, 81);
}
.cl5 {
background-color: rgba(255, 247, 230, 1);
color: rgba(250, 140, 22, 1);
}
.main-center {
width: 347px;
height: 30px;
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 30px;
color: rgb(59, 65, 75);
margin-right: 2px;
}
.main-right {
width: 60px;
height: 24px;
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(132, 136, 142);
text-align: right;
}
}
.right-mainbtn {
width: 460px;
height: 42px;
border-radius: 6px;
position: absolute;
left: 26px;
bottom: 21px;
background-color: rgb(5, 95, 194);
color: #fff;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
img {
width: 16px;
height: 16px;
margin-right: 8px;
}
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 24px;
}
}
}
</style>
差异被折叠。
<template>
<div class="coop-page">
<!-- 面包屑 -->
<div class="breadcrumb">
<div class="breadcrumb-box">
<div class="breadcrumb-item">国家科技安全</div>
<div class="breadcrumb-item">&nbsp;>&nbsp;</div>
<div class="breadcrumb-item back-item" @click="handleBackHome">中美博弈概览</div>
<div class="breadcrumb-item">&nbsp;>&nbsp;</div>
<div class="breadcrumb-item">合作限制</div>
</div>
</div>
<!-- 主页面 -->
<div class="main-content">
<!-- 搜索栏部分 -->
<div class="search">
<div class="search-main">
<input v-model="input" placeholder="搜索合作限制" class="search-input" />
<div class="search-btn">
<img src="./assets/icons/search-icon.png" alt="" />
搜索
</div>
</div>
<div class="search-center">
<div class="search-item">
<div class="search-item-num">32</div>
<div class="search-item-name">相关法案</div>
</div>
<div class="search-item">
<div class="search-item-num">9</div>
<div class="search-item-name">相关政令</div>
</div>
<div class="search-item">
<div class="search-item-num">41</div>
<div class="search-item-name">相关政府公告</div>
</div>
</div>
<div class="search-bottom">
<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>
<!-- 最新动态 -->
<div class="newdata">
<com-title title="最新动态" />
<div class="newdata-main">
<newData />
</div>
</div>
<!-- 资讯要问 -->
<div class="ask">
<com-title title="咨询要闻" />
<div class="ask-main">
<askPage />
</div>
</div>
<!-- 数据总览 -->
<div class="datasub">
<com-title title="数据总览" />
<div class="datasub-main">
<dataSub />
</div>
</div>
<!-- 资源库 -->
<div class="reslib">
<com-title title="资源库" />
<div class="reslib-main">
<resLib />
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref } from "vue";
import { useRouter } from "vue-router";
import comTitle from "./common/comTitle.vue";
import newData from "./components/dataNew/index.vue";
import askPage from "./components/askPage/index.vue";
import dataSub from "./components/dataSub/index.vue";
import resLib from "./components/resLib/index.vue";
import { useContainerScroll } from "@/hooks/useScrollShow";
// 搜索框
const input = ref("");
const router = useRouter();
// 返回首页
const handleBackHome = () => {
router.push({
path: "/overview"
});
};
</script>
<style scoped lang="scss">
* {
margin: 0;
padding: 0;
}
.coop-page {
width: 100%;
height: 100%;
.breadcrumb {
width: 100%;
height: 64px;
background-image: url("./assets/images/bread-bg.png");
background-size: cover;
padding: 17px 0px 21px 0px;
.breadcrumb-box {
margin-left: 160px;
display: flex;
// align-items: center;
.breadcrumb-item {
font-size: 20px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 30px;
color: #fff;
}
.back-item {
cursor: pointer;
&:hover {
color: #999;
}
}
}
}
.main-content {
overflow: auto;
width: 100%;
height: calc(100% - 64px);
background: url("./assets/images/background.png");
background-size: 100% 100%;
padding: 44px 160px 30px 160px;
.search {
width: 960px;
height: 225px;
margin: 0 auto 68px auto;
.search-main {
display: flex;
padding-right: 3px;
align-items: center;
justify-content: space-between;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
width: 960px;
height: 48px;
background-color: rgba(255, 255, 255, 0.65);
border-radius: 10px;
border: 1px solid #fff;
.search-input {
border: none;
outline: none;
width: 800px;
height: 48px;
background-color: transparent;
font-size: 16px;
padding: 12px 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(132, 136, 142);
}
.search-btn {
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
width: 120px;
height: 42px;
border-radius: 8px;
background-color: rgb(5, 95, 194);
font-size: 18px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 24px;
color: #fff;
img {
width: 22px;
height: 22px;
margin-right: 8px;
}
}
}
.search-center {
width: 440px;
height: 57px;
margin: 36px auto;
display: flex;
align-items: center;
justify-content: space-between;
.search-item {
box-sizing: border-box;
width: 120px;
height: 57px;
.search-item-num {
width: 120px;
height: 22px;
font-size: 36px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 22px;
color: rgb(5, 95, 194);
text-align: center;
cursor: pointer;
}
.search-item-name {
width: 120px;
height: 24px;
margin-top: 11px;
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(95, 101, 108);
text-align: center;
}
}
}
.search-bottom {
width: 688px;
height: 48px;
margin: 0 auto;
display: flex;
justify-content: space-between;
// gap: 16px;
.btn {
display: flex;
width: 160px;
height: 48px;
border: 1px solid rgba(174, 214, 255, 1);
box-sizing: border-box;
border-radius: 32px;
justify-content: center;
align-items: center;
background: rgba(231, 243, 255, 1);
position: relative;
cursor: pointer;
padding: 10px 40px 12px 36px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
&:hover {
background: #cae3fc;
}
.btn-text {
color: rgb(5, 95, 194);
font-family: "Microsoft YaHei";
font-size: 20px;
font-weight: 400;
line-height: 26px;
height: 26px;
}
.btn-icon {
position: absolute;
top: 14px;
right: 19px;
color: rgb(5, 95, 194);
font-size: 20px;
font-weight: 400;
}
}
}
}
.newdata {
width: 1600px;
height: 538px;
margin: 36px auto 64px auto;
.newdata-main {
width: 1600px;
height: 460px;
margin-top: 36px;
}
}
.ask {
width: 1600px;
height: 528px;
margin: 0 auto 64px auto;
.ask-main {
width: 1600px;
height: 450px;
margin-top: 36px;
}
}
.datasub {
width: 1600px;
height: 538px;
margin: 0 auto 88px auto;
.datasub-main {
width: 1600px;
height: 460px;
margin-top: 36px;
}
}
.reslib {
width: 1600px;
height: 1633px;
margin: 0 auto 0px auto;
.reslib-main {
width: 1600px;
height: 1565px;
margin-top: 26px;
}
}
}
}
</style>
......@@ -88,7 +88,7 @@
</div>
</div>
<div class="home-main-header-item-box">
<div class="item" v-for="(item, index) in govInsList" :key="index">
<div class="item" v-for="(item, index) in govInsList" :key="index" @click="handleToInstitution(item)">
<div class="item-left">
<img :src="item.img" alt="" />
</div>
......@@ -646,6 +646,14 @@ 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 handleToInstitution = item => {
if (item.name === "美国商务部") {
const curRoute = router.resolve("/institution");
window.open(curRoute.href, "_blank");
}
};
// 返回首页
const handleBackHome = () => {
router.push({
......@@ -2766,7 +2774,7 @@ onMounted(async () => {
height: 84px;
border-bottom: 1px solid rgba(234, 236, 238, 1);
cursor: pointer;
&:hover{
&:hover {
background: var(--color-bg-hover);
}
.main-item-left {
......
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论