提交 75e4f208 authored 作者: coderBryanFu's avatar coderBryanFu

update

上级 dcb35cb3
...@@ -7,7 +7,7 @@ import request from "@/api/request.js"; ...@@ -7,7 +7,7 @@ import request from "@/api/request.js";
export function getBillInfo(params) { export function getBillInfo(params) {
return request({ return request({
method: 'GET', method: 'GET',
url: `/billInfoBean/info/${params.id}`, url: `/api/billInfoBean/info/${params.id}`,
params, params,
}) })
} }
...@@ -20,7 +20,7 @@ export function getBillInfo(params) { ...@@ -20,7 +20,7 @@ export function getBillInfo(params) {
export function getBillPerson(params) { export function getBillPerson(params) {
return request({ return request({
method: 'GET', method: 'GET',
url: `/billInfoBean/person/${params.id}`, url: `/api/billInfoBean/person/${params.id}`,
params, params,
}) })
} }
...@@ -33,7 +33,7 @@ export function getBillPerson(params) { ...@@ -33,7 +33,7 @@ export function getBillPerson(params) {
export function getBillEvent(params) { export function getBillEvent(params) {
return request({ return request({
method: 'GET', method: 'GET',
url: `/billInfoBean/event/${params.id}`, url: `/api/billInfoBean/event/${params.id}`,
params, params,
}) })
} }
...@@ -46,7 +46,7 @@ export function getBillEvent(params) { ...@@ -46,7 +46,7 @@ export function getBillEvent(params) {
export function getBillDyqk(params) { export function getBillDyqk(params) {
return request({ return request({
method: 'GET', method: 'GET',
url: `/billInfoBean/dyqk/${params.id}`, url: `/api/billInfoBean/dyqk/${params.id}`,
params, params,
}) })
} }
...@@ -59,7 +59,7 @@ export function getBillDyqk(params) { ...@@ -59,7 +59,7 @@ export function getBillDyqk(params) {
export function getBillBackground(params) { export function getBillBackground(params) {
return request({ return request({
method: 'GET', method: 'GET',
url: `/billInfoBean/background/${params.id}`, url: `/api/billInfoBean/background/${params.id}`,
params, params,
}) })
} }
...@@ -72,7 +72,7 @@ export function getBillBackground(params) { ...@@ -72,7 +72,7 @@ export function getBillBackground(params) {
export function getBillPersonAnalyze(params) { export function getBillPersonAnalyze(params) {
return request({ return request({
method: 'GET', method: 'GET',
url: `/billInfoBean/personAnalyze/${params.id}`, url: `/api/billInfoBean/personAnalyze/${params.id}`,
params, params,
}) })
} }
...@@ -85,7 +85,7 @@ export function getBillPersonAnalyze(params) { ...@@ -85,7 +85,7 @@ export function getBillPersonAnalyze(params) {
export function getBillContentId(params) { export function getBillContentId(params) {
return request({ return request({
method: 'GET', method: 'GET',
url: `/billInfoBean/contentId/${params.id}`, url: `/api/billInfoBean/contentId/${params.id}`,
params, params,
}) })
} }
...@@ -98,7 +98,7 @@ export function getBillContentId(params) { ...@@ -98,7 +98,7 @@ export function getBillContentId(params) {
export function getBillContentTk(params) { export function getBillContentTk(params) {
return request({ return request({
method: 'GET', method: 'GET',
url: `/billInfoBean/content/tk/${params.id}`, url: `/api/billInfoBean/content/tk/${params.id}`,
params, params,
}) })
} }
...@@ -111,7 +111,7 @@ export function getBillContentTk(params) { ...@@ -111,7 +111,7 @@ export function getBillContentTk(params) {
export function getBillContentXzfs(params) { export function getBillContentXzfs(params) {
return request({ return request({
method: 'GET', method: 'GET',
url: `/billInfoBean/content/xzfs/${params.id}`, url: `/api/billInfoBean/content/xzfs/${params.id}`,
params, params,
}) })
} }
...@@ -124,7 +124,7 @@ export function getBillContentXzfs(params) { ...@@ -124,7 +124,7 @@ export function getBillContentXzfs(params) {
export function getBillHyly(params) { export function getBillHyly(params) {
return request({ return request({
method: 'GET', method: 'GET',
url: `/billInfoBean/content/hyly/${params.id}`, url: `/api/billInfoBean/content/hyly/${params.id}`,
params, params,
}) })
} }
\ No newline at end of file
import request from "@/api/chatRequest";
export function getChat(params) {
return request({
method: 'POST',
url: `/aichat/chat/chat/completions`,
data: params,
})
}
\ No newline at end of file
//引入axios请求
import axios from 'axios'
//引入element-plus里面的消息提示
import {
ElMessage
} from 'element-plus'
// Token管理
const TOKEN_KEY = 'auth_token'
// 获取token
const getToken = () => {
return 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJkYXRhLWNlbnRlciIsImF1ZCI6IndlYiIsImlzcyI6ImRhdGEtY2VudGVyIiwiZXhwIjozODI1ODM1NTkxLCJpYXQiOjE2NzgzNTE5NTMsImp0aSI6IjI4YmY1NTZjMTc0MDQ3YjJiNTExNWM3NzVhYjhlNWRmIiwidXNlcm5hbWUiOiJzdXBlcl91c2VyIn0.zHyVzsleX2lEqjDBYRpwluu_wy2nZKGl0dw3IUGnKNw'
// return localStorage.getItem(TOKEN_KEY)
}
// 设置token
const setToken = (token) => {
localStorage.setItem(TOKEN_KEY, token)
}
// 移除token
const removeToken = () => {
localStorage.removeItem(TOKEN_KEY)
}
// 导出token管理方法
export { getToken, setToken, removeToken }
// const BASE_API = import.meta.env.VITE_BASE_API
// 创建axios实例
const service = axios.create({
// baseURL: BASE_API, //所有的后端接口请求地址前缀部分(没有后端请求不用写)
timeout: 60000*5 // 请求超时时间,这里15秒
//withCredentials: true,// 异步请求携带cookie,true为携带,false为不携带
//请求头里面设置通用传参类型
/*headers: {
//设置后端需要的传参类型
'Content-Type': 'application/json',
'token': 'x-auth-token',//一开始就要token
'X-Requested-With': 'XMLHttpRequest',
}*/
})
// request拦截器
service.interceptors.request.use(config => {
// 获取token并添加到请求头
// const token = getToken()
// if (token) {
// // 根据curl命令,后端接受的是token字段名,而不是Authorization
// config.headers['token'] = token
// // config.headers['Authorization'] = `Bearer ${token}` // 如果后端需要Bearer格式可以使用这个
// }
return config
}, error => {
console.log(error)
return Promise.reject(error)
})
// response拦截器
service.interceptors.response.use(
response => {
//对数据返回做什么
if (response.data.code == 0) {
ElMessage({
message: response.data.message,
type: 'error',
duration: 3 * 1000
})
}
return response.data
},
error => {
console.log('err' + error)
// 处理token过期或无效的情况
if (error.response && (error.response.status === 401 || error.response.status === 403)) {
ElMessage({
message: 'Token已过期,请重新登录',
type: 'error',
duration: 3 * 1000
})
// 清除无效的token
removeToken()
// 可以在这里跳转到登录页
// router.push('/login')
} else {
ElMessage({
message: error.message,
type: 'error',
duration: 3 * 1000
})
}
return Promise.reject(error)
}
)
export default service
\ No newline at end of file
...@@ -7,7 +7,7 @@ import request from "@/api/request.js"; ...@@ -7,7 +7,7 @@ import request from "@/api/request.js";
export function getBillTimeAnalyze(params) { export function getBillTimeAnalyze(params) {
return request({ return request({
method: 'GET', method: 'GET',
url: `/billDeepDive/processAnalyze/time/${params.id}`, url: `/api/billDeepDive/processAnalyze/time/${params.id}`,
params, params,
}) })
} }
...@@ -19,7 +19,7 @@ export function getBillTimeAnalyze(params) { ...@@ -19,7 +19,7 @@ export function getBillTimeAnalyze(params) {
export function getBillTotalXj(params) { export function getBillTotalXj(params) {
return request({ return request({
method: 'GET', method: 'GET',
url: `/billDeepDive/processAnalyze/totalxj/${params.id}`, url: `/api/billDeepDive/processAnalyze/totalxj/${params.id}`,
params, params,
}) })
} }
...@@ -31,7 +31,7 @@ export function getBillTotalXj(params) { ...@@ -31,7 +31,7 @@ export function getBillTotalXj(params) {
export function getBillTp(params) { export function getBillTp(params) {
return request({ return request({
method: 'GET', method: 'GET',
url: `/billDeepDive/processAnalyze/tp/${params.id}`, url: `/api/billDeepDive/processAnalyze/tp/${params.id}`,
params, params,
}) })
} }
...@@ -43,7 +43,7 @@ export function getBillTp(params) { ...@@ -43,7 +43,7 @@ export function getBillTp(params) {
export function getBillXj(params) { export function getBillXj(params) {
return request({ return request({
method: 'GET', method: 'GET',
url: `/billDeepDive/processAnalyze/xj/${params.id}`, url: `/api/billDeepDive/processAnalyze/xj/${params.id}`,
params, params,
}) })
} }
...@@ -55,7 +55,7 @@ export function getBillXj(params) { ...@@ -55,7 +55,7 @@ export function getBillXj(params) {
export function getProcessSummaryDetail(params) { export function getProcessSummaryDetail(params) {
return request({ return request({
method: 'GET', method: 'GET',
url: `/billDeepDive/processSummary/detail/${params.id}`, url: `/api/billDeepDive/processSummary/detail/${params.id}`,
params, params,
}) })
} }
...@@ -67,7 +67,7 @@ export function getProcessSummaryDetail(params) { ...@@ -67,7 +67,7 @@ export function getProcessSummaryDetail(params) {
export function getProcessSummaryTk(params) { export function getProcessSummaryTk(params) {
return request({ return request({
method: 'GET', method: 'GET',
url: `/billDeepDive/processSummary/tk/${params.id}`, url: `/api/billDeepDive/processSummary/tk/${params.id}`,
params, params,
}) })
} }
...@@ -79,7 +79,7 @@ export function getProcessSummaryTk(params) { ...@@ -79,7 +79,7 @@ export function getProcessSummaryTk(params) {
export function getProcessSummary(params) { export function getProcessSummary(params) {
return request({ return request({
method: 'GET', method: 'GET',
url: `/billDeepDive/processSummary/${params.id}`, url: `/api/billDeepDive/processSummary/${params.id}`,
params, params,
}) })
} }
\ No newline at end of file
...@@ -4,7 +4,7 @@ import request from "@/api/request.js"; ...@@ -4,7 +4,7 @@ import request from "@/api/request.js";
export function getHotBills() { export function getHotBills() {
return request({ return request({
method: 'GET', method: 'GET',
url: '/BillOverview/hotBills', url: '/api/BillOverview/hotBills',
}) })
} }
...@@ -15,7 +15,7 @@ export function getHotBills() { ...@@ -15,7 +15,7 @@ export function getHotBills() {
export function getBillsByType(params) { export function getBillsByType(params) {
return request({ return request({
method: 'GET', method: 'GET',
url: '/BillOverview/bills', url: '/api/BillOverview/bills',
params, params,
}) })
} }
...@@ -24,6 +24,6 @@ export function getBillsByType(params) { ...@@ -24,6 +24,6 @@ export function getBillsByType(params) {
export function getHylyList() { export function getHylyList() {
return request({ return request({
method: 'GET', method: 'GET',
url: `/billImpactAnalysis/industry/hylyList`, url: `/api/billImpactAnalysis/industry/hylyList`,
}) })
} }
\ No newline at end of file
...@@ -7,7 +7,7 @@ import request from "@/api/request.js"; ...@@ -7,7 +7,7 @@ import request from "@/api/request.js";
export function getCompanyList(params) { export function getCompanyList(params) {
return request({ return request({
method: 'GET', method: 'GET',
url: `/billImpactAnalysis/industry/company/${params.id}`, url: `/api/billImpactAnalysis/industry/company/${params.id}`,
params, params,
}) })
} }
...@@ -19,7 +19,7 @@ export function getCompanyList(params) { ...@@ -19,7 +19,7 @@ export function getCompanyList(params) {
export function getIndustryHyly(params) { export function getIndustryHyly(params) {
return request({ return request({
method: 'GET', method: 'GET',
url: `/billImpactAnalysis/industry/hyly/${params.id}`, url: `/api/billImpactAnalysis/industry/hyly/${params.id}`,
params, params,
}) })
} }
...@@ -28,6 +28,6 @@ export function getIndustryHyly(params) { ...@@ -28,6 +28,6 @@ export function getIndustryHyly(params) {
export function getHylyList() { export function getHylyList() {
return request({ return request({
method: 'GET', method: 'GET',
url: `/billImpactAnalysis/industry/hylyList`, url: `/api/billImpactAnalysis/industry/hylyList`,
}) })
} }
\ No newline at end of file
...@@ -27,10 +27,10 @@ const removeToken = () => { ...@@ -27,10 +27,10 @@ const removeToken = () => {
// 导出token管理方法 // 导出token管理方法
export { getToken, setToken, removeToken } export { getToken, setToken, removeToken }
const BASE_API = import.meta.env.VITE_BASE_API // const BASE_API = import.meta.env.VITE_BASE_API
// 创建axios实例 // 创建axios实例
const service = axios.create({ const service = axios.create({
baseURL: BASE_API, //所有的后端接口请求地址前缀部分(没有后端请求不用写) // baseURL: BASE_API, //所有的后端接口请求地址前缀部分(没有后端请求不用写)
timeout: 60000*5 // 请求超时时间,这里15秒 timeout: 60000*5 // 请求超时时间,这里15秒
//withCredentials: true,// 异步请求携带cookie,true为携带,false为不携带 //withCredentials: true,// 异步请求携带cookie,true为携带,false为不携带
//请求头里面设置通用传参类型 //请求头里面设置通用传参类型
......
...@@ -51,7 +51,7 @@ ...@@ -51,7 +51,7 @@
</div> </div>
</div> </div>
<div class="footer"> <div class="footer">
<el-input type="textarea" :rows="3" v-model="question" placeholder="请输入问题开启智能问答" /> <el-input type="textarea" :rows="3" v-model="userInput" placeholder="请输入问题开启智能问答" />
<div class="btn"> <div class="btn">
<div class="icon"> <div class="icon">
<img src="@/assets/icons/aiBox/idea.png" alt="" /> <img src="@/assets/icons/aiBox/idea.png" alt="" />
...@@ -71,6 +71,8 @@ import { fetchEventSource } from "@microsoft/fetch-event-source"; ...@@ -71,6 +71,8 @@ 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";
const contentContainer = ref(null); const contentContainer = ref(null);
const userInput = ref(""); const userInput = ref("");
const isLoading = ref(false); const isLoading = ref(false);
...@@ -86,7 +88,6 @@ const messages = ref([ ...@@ -86,7 +88,6 @@ const messages = ref([
type: "ai", type: "ai",
content: "您好!我是AI助手,有什么可以帮助您的吗?" content: "您好!我是AI助手,有什么可以帮助您的吗?"
} }
]); ]);
// Markdown 渲染器 // Markdown 渲染器
...@@ -138,18 +139,22 @@ const connectSSE = async question => { ...@@ -138,18 +139,22 @@ const connectSSE = async question => {
// 创建 AbortController 用于取消请求 // 创建 AbortController 用于取消请求
abortController.value = new AbortController(); abortController.value = new AbortController();
const params = {
query: "如何检索?",
knowledge_base_name: "kb_test251112",
top_k: 6,
score_threshold: 0.5,
metadata: { year: 2024 }
};
try { try {
await fetchEventSource("/api/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({ body: JSON.stringify(params),
question: question
// 其他参数...
}),
signal: abortController.value.signal, signal: abortController.value.signal,
onopen: async response => { onopen: async response => {
console.log("SSE 连接已建立", response.status); console.log("SSE 连接已建立", response.status);
if (response.status !== 200) { if (response.status !== 200) {
...@@ -199,6 +204,23 @@ const connectSSE = async question => { ...@@ -199,6 +204,23 @@ const connectSSE = async question => {
} }
}; };
const chat = async () => {
const params = {
query: "如何检索?",
knowledge_base_name: "kb_test251112",
top_k: 6,
score_threshold: 0.5,
metadata: { year: 2024 }
};
try {
const res = await getChat(params);
console.log("chat", res);
} catch (error) {
console.error(error);
}
};
// 发送消息 // 发送消息
const sendMessage = async () => { const sendMessage = async () => {
const question = userInput.value.trim(); const question = userInput.value.trim();
...@@ -214,6 +236,7 @@ const sendMessage = async () => { ...@@ -214,6 +236,7 @@ const sendMessage = async () => {
userInput.value = ""; userInput.value = "";
// await connectSSE(question); // await connectSSE(question);
chat();
}; };
// 停止生成 // 停止生成
......
<template>
<div class="header-wrapper">
<div class="icon"></div>
<div class="title"></div>
<div class="btn-box"></div>
</div>
</template>
\ No newline at end of file
...@@ -15,7 +15,7 @@ import BillTemplate from '@/views/bill/template/index.vue' ...@@ -15,7 +15,7 @@ import BillTemplate from '@/views/bill/template/index.vue'
import BillDeepDigLayout from '@/views/bill/deepDig/index.vue' import BillDeepDigLayout from '@/views/bill/deepDig/index.vue'
import BillDeepDigProcessOverview from '@/views/bill/deepDig/processOverview/index.vue' import BillDeepDigProcessOverview from '@/views/bill/deepDig/processOverview/index.vue'
import BillDeepDigProcessAnalysis from '@/views/bill/deepDig/processAnalysis/index.vue' import BillDeepDigProcessAnalysis from '@/views/bill/deepDig/processAnalysis/index.vue'
import BillDeepDigProgressOverview from '@/views/bill/deepDig/progressAnalysis/index.vue' import BillDeepDigPoliContribution from '@/views/bill/deepDig/poliContribution/index.vue'
import BillInfluenceLayout from '@/views/bill/influence/index.vue' import BillInfluenceLayout from '@/views/bill/influence/index.vue'
import BillInfluenceIndustry from '@/views/bill/influence/industry/index.vue' import BillInfluenceIndustry from '@/views/bill/influence/industry/index.vue'
import BillInfluenceScientificResearch from '@/views/bill/influence/scientificResearch/index.vue' import BillInfluenceScientificResearch from '@/views/bill/influence/scientificResearch/index.vue'
...@@ -161,10 +161,10 @@ const routes = [ ...@@ -161,10 +161,10 @@ const routes = [
meta: { title: '流程分析' } meta: { title: '流程分析' }
}, },
{ {
path: 'progressAnalysis', path: 'poliContribution',
name: 'DeepDigProgressAnalysis', name: 'BillDeepDigPoliContribution',
component: BillDeepDigProgressOverview, component: BillDeepDigPoliContribution,
meta: { title: '进程分析' } meta: { title: '政治献金' }
}, },
] ]
}, },
......
// 绘制echarts图表
import * as echarts from 'echarts'
const setChart = (option, chartId) => {
let chartDom = document.getElementById(chartId);
chartDom.removeAttribute("_echarts_instance_");
let chart = echarts.init(chartDom);
chart.setOption(option);
return chart;
};
export default setChart
\ No newline at end of file
const getDoublePieChart = (data) => {
const colorList = ['#8AC4FF','#FFD591']
const colorList1 = ['#055FC2','#FFA940']
let option = {
series: [
{
type: 'pie',
radius: [70, 100],
height: '100%',
left: 'center',
width: '100%',
itemStyle: {
borderColor: '#fff',
borderWidth: 1
},
label: {
alignTo: 'edge',
formatter: '{name|{b}}\n{time|{c} 条 {d}%}',
minMargin: 5,
edgeDistance: 10,
lineHeight: 15,
rich: {
time: {
fontSize: 10,
color: '#999'
}
}
},
labelLine: {
length: 15,
length2: 0,
maxSurfaceAngle: 80
},
labelLayout: function (params) {
const isLeft = params.labelRect.x < 556 / 2;
const points = params.labelLinePoints;
// Update the end point.
points[2][0] = isLeft
? params.labelRect.x
: params.labelRect.x + params.labelRect.width;
return {
labelLinePoints: points
};
},
data: data
}]
}
return option
}
export default getDoublePieChart;
\ No newline at end of file
const getPieChart = (data,colorList) => {
let option = {
color: colorList,
series: [
{
type: 'pie',
radius: [70, 100],
height: '100%',
left: 'center',
width: '100%',
itemStyle: {
borderColor: '#fff',
borderWidth: 1
},
label: {
alignTo: 'edge',
formatter: '{name|{b}}\n{time|{c} 条 {d}%}',
minMargin: 5,
edgeDistance: 10,
lineHeight: 15,
rich: {
time: {
fontSize: 10,
color: '#999'
}
}
},
labelLine: {
length: 15,
length2: 0,
maxSurfaceAngle: 80
},
labelLayout: function (params) {
const isLeft = params.labelRect.x < 556 / 2;
const points = params.labelLinePoints;
// Update the end point.
points[2][0] = isLeft
? params.labelRect.x
: params.labelRect.x + params.labelRect.width;
return {
labelLinePoints: points
};
},
data: data
}]
}
return option
}
export default getPieChart;
\ No newline at end of file
...@@ -38,9 +38,9 @@ const siderBtnList = ref([ ...@@ -38,9 +38,9 @@ const siderBtnList = ref([
path: "/billLayout/deepDig/processAnalysis", path: "/billLayout/deepDig/processAnalysis",
}, },
{ {
name: "进程分析", name: "政治献金",
isActive: false, isActive: false,
path: "/billLayout/deepDig/progressAnalysis", path: "/billLayout/deepDig/poliContribution",
}, },
]); ]);
......
const getPieChart = (data,colorList) => {
let option = {
color: colorList,
series: [
{
type: 'pie',
radius: [70, 100],
height: '100%',
left: 'center',
width: '100%',
itemStyle: {
borderColor: '#fff',
borderWidth: 1
},
label: {
alignTo: 'edge',
formatter: '{name|{b}}\n{time|{c} 条 {d}%}',
minMargin: 5,
edgeDistance: 10,
lineHeight: 15,
rich: {
time: {
fontSize: 10,
color: '#999'
}
}
},
labelLine: {
length: 15,
length2: 0,
maxSurfaceAngle: 80
},
labelLayout: function (params) {
const isLeft = params.labelRect.x < 556 / 2;
const points = params.labelLinePoints;
// Update the end point.
points[2][0] = isLeft
? params.labelRect.x
: params.labelRect.x + params.labelRect.width;
return {
labelLinePoints: points
};
},
data: data
}]
}
return option
}
export default getPieChart;
\ No newline at end of file
const getSankeyChart = () => {
const option = {
series: {
type: 'sankey',
layout: 'none',
left: '5%',
right: '5%',
top: '5%',
bottom: '5%',
emphasis: {
focus: 'adjacency'
},
nodeWidth: 50,
label: {
show: true,
formatter: function (params) {
return `${params.name} $${params.value}`;
},
position: 'right',
textStyle: {
fontSize: '16px',
color: '#555'
}
},
data: [
{
name: '马尔科·卢比奥',
label: {
position: 'left'
}
},
{
name: '成长俱乐部'
},
{
name: '埃利奥特管理公司'
},
{
name: '高盛集团'
},
{
name: '黑石集团'
},
{
name: '佛罗里达水晶'
},
{
name: '美国银行'
}
],
links: [
{
source: '成长俱乐部',
target: '马尔科·卢比奥',
value: 680751
},
{
source: '埃利奥特管理公司',
target: '马尔科·卢比奥',
value: 440120
},
{
source: '高盛集团',
target: '马尔科·卢比奥',
value: 371517
},
{
source: '黑石集团',
target: '马尔科·卢比奥',
value: 259321
},
{
source: '佛罗里达水晶',
target: '马尔科·卢比奥',
value: 203775
},
{
source: '美国银行',
target: '马尔科·卢比奥',
value: 150892
}
]
}
};
return option
}
export default getSankeyChart
\ No newline at end of file
<template>
<div>我是进程分析</div>
</template>
<script setup>
</script>
<style lang="scss" scoped>
</style>
<template> <template>
<div class="wrap"> <div class="wrap">
<div class="box1"> <!-- <div class="box1">
<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>
...@@ -46,13 +46,18 @@ ...@@ -46,13 +46,18 @@
<img src="./assets/icons/box1-icon3.png" alt="" /> <img src="./assets/icons/box1-icon3.png" alt="" />
</div> </div>
</div> </div>
</div> </div> -->
<div class="box2"> <div class="box2">
<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/icons/header-icon.png" alt="" /> <div class="icon">
<img src="../assets/icons/header-right-icon1.png" alt="" />
</div>
<div class="icon">
<img src="../assets/icons/header-right-icon2.png" alt="" />
</div>
</div> </div>
</div> </div>
<div class="box2-main"> <div class="box2-main">
...@@ -113,11 +118,7 @@ ...@@ -113,11 +118,7 @@
<div class="title">{{ "政令主要内容" }}</div> <div class="title">{{ "政令主要内容" }}</div>
</div> </div>
<div class="list-main"> <div class="list-main">
<div <div class="list-item" v-for="(val, idx) in decreeList[box2LeftActiveIndex].list" :key="idx">
class="list-item"
v-for="(val, idx) in decreeList[box2LeftActiveIndex].list"
:key="idx"
>
<div class="id">{{ idx + 1 }}</div> <div class="id">{{ idx + 1 }}</div>
<div class="title">{{ val.title }}</div> <div class="title">{{ val.title }}</div>
<div class="open"> <div class="open">
...@@ -126,6 +127,21 @@ ...@@ -126,6 +127,21 @@
</div> </div>
</div> </div>
</div> </div>
<div class="list-footer">
<div class="footer-left">
{{ `共${decreeList[box2LeftActiveIndex].list.length}项动态` }}
</div>
<div class="footer-right">
<el-pagination
@current-change="handleCurrentChange"
:pageSize="pageSize"
:current-page="currentPage"
background
layout="prev, pager, next"
:total="decreeList[box2LeftActiveIndex].list.length"
/>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
...@@ -136,35 +152,38 @@ ...@@ -136,35 +152,38 @@
import { ref, onMounted } from "vue"; import { ref, onMounted } from "vue";
import box2InfoImg from "./assets/icons/box2-info.png"; import box2InfoImg from "./assets/icons/box2-info.png";
const pageSize = ref(10);
const currentPage = ref(1);
const box1BtnActive = ref(1); const box1BtnActive = ref(1);
const timeLineList = ref([ const timeLineList = ref([
{ {
time: "2025年1月", time: "2025年1月",
title: "《AI扩散暂行最终规则》发布", title: "《AI扩散暂行最终规则》发布",
content: "拜登政府发布《AI扩散暂行最终规则》,建立三级许可制度。", content: "拜登政府发布《AI扩散暂行最终规则》,建立三级许可制度。"
}, },
{ {
time: "2025年5月", time: "2025年5月",
title: "特朗普宣布撤销拜登AI规则", title: "特朗普宣布撤销拜登AI规则",
content: "特朗普政府宣布撤销拜登AI规则,计划推出新规。", content: "特朗普政府宣布撤销拜登AI规则,计划推出新规。"
}, },
{ {
time: "2025年7月23日", time: "2025年7月23日",
title: "特朗普签署EO 14320", title: "特朗普签署EO 14320",
content: "特朗普签署EO 14320,推动美国AI技术栈出口。", content: "特朗普签署EO 14320,推动美国AI技术栈出口。"
}, },
{ {
time: "2025年7月31日", time: "2025年7月31日",
title: "中国网信办约谈英伟达", title: "中国网信办约谈英伟达",
content: content: "中国网信办约谈英伟达,要求就H20算力芯片漏洞后门安全风险问题进行说明。"
"中国网信办约谈英伟达,要求就H20算力芯片漏洞后门安全风险问题进行说明。",
}, },
{ {
time: "2025年8月", time: "2025年8月",
title: "英伟达H20发放出口许可证", title: "英伟达H20发放出口许可证",
content: "美国商务部为4月份被实质禁售的英伟达H20发放出口许可证。", content: "美国商务部为4月份被实质禁售的英伟达H20发放出口许可证。"
}, }
]); ]);
const decreeList = ref([ const decreeList = ref([
...@@ -173,43 +192,41 @@ const decreeList = ref([ ...@@ -173,43 +192,41 @@ const decreeList = ref([
title: "拜登人工智能政令", title: "拜登人工智能政令",
img: box2InfoImg, img: box2InfoImg,
totalTitle: "关于安全、可靠和可信地开发和使用人工智能的行政命令", totalTitle: "关于安全、可靠和可信地开发和使用人工智能的行政命令",
eTotalTitle: eTotalTitle: "Executive Order on the Safe, Secure, and Trustworthy Development and Use of Artificial Intelligence",
"Executive Order on the Safe, Secure, and Trustworthy Development and Use of Artificial Intelligence",
signTime: "2025年7月23日", signTime: "2025年7月23日",
signPerson: "乔·拜登(Joe Biden)", signPerson: "乔·拜登(Joe Biden)",
list: [ list: [
{ {
title: title: "要求强大AI系统开发者与政府分享安全测试结果(“红队测试”);制定生物合成筛查标准防范风险;建立AI生成内容鉴别标准"
"要求强大AI系统开发者与政府分享安全测试结果(“红队测试”);制定生物合成筛查标准防范风险;建立AI生成内容鉴别标准", },
{
title: "优先支持隐私保护技术(PET)研发;评估各机构如何收集和使用商业信息;制定评估隐私保护技术有效性的指南。"
}, },
{ {
title: title: "为解决算法歧视提供明确指导;确保刑事司法系统中AI使用的公平性;协调调查和起诉AI相关的民权侵犯行为。"
"优先支持隐私保护技术(PET)研发;评估各机构如何收集和使用商业信息;制定评估隐私保护技术有效性的指南。",
}, },
{ {
title: title: "推动医疗保健领域负责任地使用AI;创造资源支持教育工作者部署AI教育工具。"
"为解决算法歧视提供明确指导;确保刑事司法系统中AI使用的公平性;协调调查和起诉AI相关的民权侵犯行为。",
}, },
{ {
title: title: "制定减轻AI对工人潜在危害的原则和最佳实践;编写AI对劳动力市场潜在影响的报告。"
"推动医疗保健领域负责任地使用AI;创造资源支持教育工作者部署AI教育工具。",
}, },
{ {
title: title: "通过“国家AI研究资源”(NAIRR)试点促进研究;为小型开发者和企业家提供技术援助和资源;简化相关领域高技能人才的签证流程。"
"制定减轻AI对工人潜在危害的原则和最佳实践;编写AI对劳动力市场潜在影响的报告。",
}, },
{ {
title: title: "扩大在AI领域的国际合作;与国际伙伴和标准组织加速制定AI标准。"
"通过“国家AI研究资源”(NAIRR)试点促进研究;为小型开发者和企业家提供技术援助和资源;简化相关领域高技能人才的签证流程。",
}, },
{ {
title: "扩大在AI领域的国际合作;与国际伙伴和标准组织加速制定AI标准。", title: "发布政府机构使用AI的指南;加快招聘AI专业人才并为相关领域员工提供培训。"
}, },
{ {
title: title: "发布政府机构使用AI的指南;加快招聘AI专业人才并为相关领域员工提供培训。"
"发布政府机构使用AI的指南;加快招聘AI专业人才并为相关领域员工提供培训。",
}, },
], {
title: "发布政府机构使用AI的指南;加快招聘AI专业人才并为相关领域员工提供培训。"
}
]
}, },
{ {
time: "2023", time: "2023",
...@@ -219,7 +236,7 @@ const decreeList = ref([ ...@@ -219,7 +236,7 @@ const decreeList = ref([
eTotalTitle: "", eTotalTitle: "",
signTime: "", signTime: "",
signPerson: "", signPerson: "",
list: [], list: []
}, },
{ {
time: "2025", time: "2025",
...@@ -229,7 +246,7 @@ const decreeList = ref([ ...@@ -229,7 +246,7 @@ const decreeList = ref([
eTotalTitle: "", eTotalTitle: "",
signTime: "", signTime: "",
signPerson: "", signPerson: "",
list: [], list: []
}, },
{ {
time: "2023", time: "2023",
...@@ -239,7 +256,7 @@ const decreeList = ref([ ...@@ -239,7 +256,7 @@ const decreeList = ref([
eTotalTitle: "", eTotalTitle: "",
signTime: "", signTime: "",
signPerson: "", signPerson: "",
list: [], list: []
}, },
{ {
time: "2024", time: "2024",
...@@ -249,8 +266,8 @@ const decreeList = ref([ ...@@ -249,8 +266,8 @@ const decreeList = ref([
eTotalTitle: "", eTotalTitle: "",
signTime: "", signTime: "",
signPerson: "", signPerson: "",
list: [], list: []
}, }
]); ]);
const box2LeftActiveIndex = ref(0); const box2LeftActiveIndex = ref(0);
...@@ -293,14 +310,19 @@ const box2LeftActiveIndex = ref(0); ...@@ -293,14 +310,19 @@ const box2LeftActiveIndex = ref(0);
position: absolute; position: absolute;
top: 14px; top: 14px;
right: 12px; right: 12px;
width: 32px; height: 28px;
height: 32px; display: flex;
gap: 4px;
.icon {
width: 28px;
height: 28px;
img { img {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
} }
} }
}
.box1 { .box1 {
margin: 27px auto 16px; margin: 27px auto 16px;
width: 1600px; width: 1600px;
...@@ -453,9 +475,9 @@ const box2LeftActiveIndex = ref(0); ...@@ -453,9 +475,9 @@ const box2LeftActiveIndex = ref(0);
} }
} }
.box2 { .box2 {
margin: 0 auto 10px; margin: 16px auto;
width: 1600px; width: 1600px;
height: 751px; height: 898px;
border-radius: 4px; border-radius: 4px;
box-shadow: 0px 0px 15px 0px rgba(60, 87, 126, 0.2); box-shadow: 0px 0px 15px 0px rgba(60, 87, 126, 0.2);
background: rgba(255, 255, 255, 1); background: rgba(255, 255, 255, 1);
...@@ -514,7 +536,6 @@ const box2LeftActiveIndex = ref(0); ...@@ -514,7 +536,6 @@ const box2LeftActiveIndex = ref(0);
.right { .right {
margin-left: 36px; margin-left: 36px;
.info-box { .info-box {
margin-top: 25px;
margin-left: 28px; margin-left: 28px;
width: 1180px; width: 1180px;
height: 188px; height: 188px;
...@@ -610,7 +631,7 @@ const box2LeftActiveIndex = ref(0); ...@@ -610,7 +631,7 @@ const box2LeftActiveIndex = ref(0);
} }
} }
.list-main { .list-main {
height: 400px; height: 540px;
overflow-x: hidden; overflow-x: hidden;
overflow-y: auto; overflow-y: auto;
.list-item { .list-item {
...@@ -655,6 +676,20 @@ const box2LeftActiveIndex = ref(0); ...@@ -655,6 +676,20 @@ const box2LeftActiveIndex = ref(0);
} }
} }
} }
.list-footer {
margin-left: 35px;
height: 32px;
margin-top: 10px;
display: flex;
justify-content: space-between;
.footer-left {
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 32px;
}
}
} }
} }
} }
......
...@@ -7,28 +7,25 @@ ...@@ -7,28 +7,25 @@
<div class="title">提出背景</div> <div class="title">提出背景</div>
<div class="header-btn-box"> <div class="header-btn-box">
<div class="btn" @click="handleClickBox1Btn(1)"> <div class="btn" @click="handleClickBox1Btn(1)">
<el-button type="primary" plain v-if="box1BtnActive === 1" <el-button type="primary" plain v-if="box1BtnActive === 1">涉华背景</el-button>
>涉华背景</el-button
>
<el-button type="info" plain v-else>涉华背景</el-button> <el-button type="info" plain v-else>涉华背景</el-button>
</div> </div>
<div class="btn" @click="handleClickBox1Btn(2)"> <div class="btn" @click="handleClickBox1Btn(2)">
<el-button type="primary" plain v-if="box1BtnActive === 2" <el-button type="primary" plain v-if="box1BtnActive === 2">全部背景</el-button>
>全部背景</el-button
>
<el-button type="info" plain v-else>全部背景</el-button> <el-button type="info" plain v-else>全部背景</el-button>
</div> </div>
</div> </div>
<div class="header-right"> <div class="header-right">
<img src="../assets/icons/header-icon.png" alt="" /> <div class="icon">
<img src="../assets/icons/header-right-icon1.png" alt="" />
</div>
<div class="icon">
<img src="../assets/icons/header-right-icon2.png" alt="" />
</div>
</div> </div>
</div> </div>
<div class="box1-main"> <div class="box1-main">
<div <div class="box1-item" v-for="(item, index) in backgroundList" :key="index">
class="box1-item"
v-for="(item, index) in backgroundList"
:key="index"
>
<div class="id">{{ index + 1 }}</div> <div class="id">{{ index + 1 }}</div>
<div class="title">{{ item.title }}</div> <div class="title">{{ item.title }}</div>
<div class="open"> <div class="open">
...@@ -39,12 +36,7 @@ ...@@ -39,12 +36,7 @@
<div class="box1-footer"> <div class="box1-footer">
<div class="box1-footer-left">{{ "共计10条指令" }}</div> <div class="box1-footer-left">{{ "共计10条指令" }}</div>
<div class="box1-footer-right"> <div class="box1-footer-right">
<el-pagination <el-pagination :page-size="5" background layout="prev, pager, next" :total="10" />
:page-size="5"
background
layout="prev, pager, next"
:total="10"
/>
</div> </div>
</div> </div>
</div> </div>
...@@ -53,15 +45,16 @@ ...@@ -53,15 +45,16 @@
<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/icons/header-icon.png" alt="" /> <div class="icon">
<img src="../assets/icons/header-right-icon1.png" alt="" />
</div>
<div class="icon">
<img src="../assets/icons/header-right-icon2.png" alt="" />
</div>
</div> </div>
</div> </div>
<div class="box2-main"> <div class="box2-main">
<div <div class="box2-item" v-for="(item, index) in relatedEvents" :key="index">
class="box2-item"
v-for="(item, index) in relatedEvents"
:key="index"
>
<div class="item-left"> <div class="item-left">
<img :src="item.image" alt="" /> <img :src="item.image" alt="" />
</div> </div>
...@@ -84,7 +77,12 @@ ...@@ -84,7 +77,12 @@
<div class="title">法律依据</div> <div class="title">法律依据</div>
<div class="header-right"> <div class="header-right">
<img src="../assets/icons/header-icon.png" alt="" /> <div class="icon">
<img src="../assets/icons/header-right-icon1.png" alt="" />
</div>
<div class="icon">
<img src="../assets/icons/header-right-icon2.png" alt="" />
</div>
</div> </div>
</div> </div>
<div class="box3-main"> <div class="box3-main">
...@@ -115,23 +113,20 @@ const box1BtnActive = ref(1); ...@@ -115,23 +113,20 @@ const box1BtnActive = ref(1);
const backgroundList = ref([ const backgroundList = ref([
{ {
title: title: "认为人工智能(AI)是一项将决定未来几十年经济增长、国家安全和全球竞争力的基础性技术"
"认为人工智能(AI)是一项将决定未来几十年经济增长、国家安全和全球竞争力的基础性技术",
}, },
{ {
title: title: "要求美国不仅必须在开发通用和前沿AI能力方面领先,还必须确保美国的人工智能技术、标准和治理模式在全球范围内被采用"
"要求美国不仅必须在开发通用和前沿AI能力方面领先,还必须确保美国的人工智能技术、标准和治理模式在全球范围内被采用",
}, },
{ {
title: "要求加强与盟友的关系并确保我们持续的技术主导地位", title: "要求加强与盟友的关系并确保我们持续的技术主导地位"
}, },
{ {
title: title: "计划通过支持美国原产人工智能技术的全球部署,以维护和扩大美国在人工智能领域的领导地位"
"计划通过支持美国原产人工智能技术的全球部署,以维护和扩大美国在人工智能领域的领导地位",
}, },
{ {
title: "目的为减少国际社会对由中国开发的人工智能技术的依赖", title: "目的为减少国际社会对由中国开发的人工智能技术的依赖"
}, }
]); ]);
const relatedEvents = ref([ const relatedEvents = ref([
...@@ -140,36 +135,34 @@ const relatedEvents = ref([ ...@@ -140,36 +135,34 @@ const relatedEvents = ref([
title: "中美AI模型性能差距迅速缩小", title: "中美AI模型性能差距迅速缩小",
content: content:
"斯坦福大学《2025年人工智能指数报告》显示,中美顶尖AI模型在MMLU(大规模多任务语言理解)等主流基准测试中的性能...", "斯坦福大学《2025年人工智能指数报告》显示,中美顶尖AI模型在MMLU(大规模多任务语言理解)等主流基准测试中的性能...",
time: "2025-08-30", time: "2025-08-30"
}, },
{ {
image: Img2, image: Img2,
title: "中国模型以更低成本实现高性能", title: "中国模型以更低成本实现高性能",
content: content: "2025年1月,中国公司深度求索(DeepSeek)发布高性能AI推理模型R1,以其极低的训练成本和媲美顶级模型的推理能力受...",
"2025年1月,中国公司深度求索(DeepSeek)发布高性能AI推理模型R1,以其极低的训练成本和媲美顶级模型的推理能力受...", time: "2025-05-16"
time: "2025-05-16",
}, },
{ {
image: Img3, image: Img3,
title: "美国发布《赢得AI竞赛:美国AI行动计划》​", title: "美国发布《赢得AI竞赛:美国AI行动计划》​",
content: content:
"特朗普政府发布该计划,核心包括加速创新​(解除监管)、建设AI基础设施​(加速数据中心审批、保障能源供应)和引领国际...", "特朗普政府发布该计划,核心包括加速创新​(解除监管)、建设AI基础设施​(加速数据中心审批、保障能源供应)和引领国际...",
time: "2025-07-23", time: "2025-07-23"
}, },
{ {
image: Img4, image: Img4,
title: "中国深入推进“人工智能+”行动", title: "中国深入推进“人工智能+”行动",
content: content: "中国国务院常务会议审议通过《关于深入实施“人工智能+”行动的意见》,大力推进AI在各领域的规模化商业化应用和和深...",
"中国国务院常务会议审议通过《关于深入实施“人工智能+”行动的意见》,大力推进AI在各领域的规模化商业化应用和和深...", time: "2025-07-31"
time: "2025-07-31",
}, },
{ {
image: Img5, image: Img5,
title: "美国对华AI芯片出口管制持续升级", title: "美国对华AI芯片出口管制持续升级",
content: content:
"美国商务部宣布撤销拜登时期的《AI扩散规则》,要求全球使用美国技术的芯片厂商停止向中国出口AI芯片,直接影响英伟达...", "美国商务部宣布撤销拜登时期的《AI扩散规则》,要求全球使用美国技术的芯片厂商停止向中国出口AI芯片,直接影响英伟达...",
time: "2025-05-20", time: "2025-05-20"
}, }
]); ]);
const laws = ref([ const laws = ref([
...@@ -177,32 +170,30 @@ const laws = ref([ ...@@ -177,32 +170,30 @@ const laws = ref([
name: "《美国法典》", name: "《美国法典》",
info: "第3编第301条", info: "第3编第301条",
content: content:
"允许总统通过行政命令(Executive Order)​​ 或其它书面形式授权行政部门或机构的负责人​(如国务卿、财政部长等)代行本属于总统的法定职能(由国会立法授予总统的职能)。", "允许总统通过行政命令(Executive Order)​​ 或其它书面形式授权行政部门或机构的负责人​(如国务卿、财政部长等)代行本属于总统的法定职能(由国会立法授予总统的职能)。"
}, },
{ {
name: "《出口管制改革法案》", name: "《出口管制改革法案》",
info: "", info: "",
content: content:
"该法案授权政府出于国家安全和外交政策目的对特定技术、商品和软件的出口进行管制。确保AI技术不流向“对手国家”是其题中应有之义。", "该法案授权政府出于国家安全和外交政策目的对特定技术、商品和软件的出口进行管制。确保AI技术不流向“对手国家”是其题中应有之义。"
}, },
{ {
name: "《国际紧急经济权力法》", name: "《国际紧急经济权力法》",
info: "", info: "",
content: content:
"授予总统在应对“不寻常且极其严重的威胁”时,监管商业和金融交易的广泛权力,包括实施出口管制。这在以往的贸易和科技管制中常被引用。", "授予总统在应对“不寻常且极其严重的威胁”时,监管商业和金融交易的广泛权力,包括实施出口管制。这在以往的贸易和科技管制中常被引用。"
}, },
{ {
name: "《2019年通过外交捍卫美国商业法》", name: "《2019年通过外交捍卫美国商业法》",
info: "第708(c)(3)条", info: "第708(c)(3)条",
content: content: "授权小企业管理局局长和OSTP主任任命其各自行政部门和机构的高级官员担任EDAG成员。"
"授权小企业管理局局长和OSTP主任任命其各自行政部门和机构的高级官员担任EDAG成员。",
}, },
{ {
name: "《关于安全、可靠和可信地开发和使用人工智能的行政命令》", name: "《关于安全、可靠和可信地开发和使用人工智能的行政命令》",
info: "", info: "",
content: content: "要求强大AI系统的开发者与政府共享安全测试结果,并为AI安全、隐私保护、公平权利及创新竞争等方面制定标准。"
"要求强大AI系统的开发者与政府共享安全测试结果,并为AI安全、隐私保护、公平权利及创新竞争等方面制定标准。", }
},
]); ]);
</script> </script>
...@@ -234,7 +225,7 @@ const laws = ref([ ...@@ -234,7 +225,7 @@ const laws = ref([
.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;
...@@ -244,14 +235,19 @@ const laws = ref([ ...@@ -244,14 +235,19 @@ const laws = ref([
position: absolute; position: absolute;
top: 14px; top: 14px;
right: 12px; right: 12px;
width: 32px; height: 28px;
height: 32px; display: flex;
gap: 4px;
.icon {
width: 28px;
height: 28px;
img { img {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
} }
} }
}
.left { .left {
width: 1150px; width: 1150px;
.box1 { .box1 {
......
...@@ -771,11 +771,11 @@ onMounted(async () => { ...@@ -771,11 +771,11 @@ onMounted(async () => {
.search { .search {
position: absolute; position: absolute;
right: 1px; right: 1px;
top: 1px; top: 2px;
width: 120px; width: 120px;
height: 44px; height: 44px;
border-radius: 4px; border-radius: 10px;
background: rgba(22, 119, 255, 1); background: var(--color-main-active);
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
......
...@@ -43,6 +43,11 @@ export default defineConfig({ ...@@ -43,6 +43,11 @@ export default defineConfig({
target: 'http://192.168.26.70:8000', target: 'http://192.168.26.70:8000',
changeOrigin: true, changeOrigin: true,
rewrite: (path) => path.replace(/^\/sse/, '') rewrite: (path) => path.replace(/^\/sse/, '')
},
'/aichat': {
target: 'http://192.168.184.24:7861/',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/aichat/, '')
} }
} }
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论