提交 3df44f93 authored 作者: caijian's avatar caijian

first commit

上级 a7a092f6
{
"compilerOptions": {
"baseUrl": "src",
"paths": {
"@/*": ["*"]
},
"target": "esnext",
"module": "esnext",
"moduleResolution": "node",
"allowJs": true,
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
\ No newline at end of file
...@@ -199,6 +199,60 @@ export const saveEventsTable = async (params) => { ...@@ -199,6 +199,60 @@ export const saveEventsTable = async (params) => {
return data return data
} }
//获取chart prompt
export const getChartPrompt = async (params, type) => {
let data = await request.get(`/api/analysis/${type}?hyper_id=` + params.hyper_id)
return data
}
//保存chart prompt
export const saveChartPrompt = async (params, type) => {
let data = await request({
method: "post",
headers: {
'Content-Type': 'application/json'
},
url: "/api/analysis/" + type,
data: params
})
return data
}
export const getChartNewsList = async (params) => {
let data = await request.get('/api/analysis/get_chart_news_in_rag?hyper_id=' + params.hyper_id)
return data
}
export const getChartData = async (params) => {
let data = await request.get('/api/analysis/analysis_chart_in_rag?hyper_id=' + params.hyper_id)
return data
}
// http://8.140.26.4:10006/tech_hyper/api/analysis/get_matrix_news_in_rag?hyper_id=1
export const getMatrixNewsList = async (params) => {
let data = await request.get('/api/analysis/get_matrix_news_in_rag?hyper_id=' + params.hyper_id)
return data
}
// http://8.140.26.4:10006/tech_hyper/api/analysis/analysis_matrix_in_rag?hyper_id=1
export const getMatrixData = async (params) => {
let data = await request.get('/api/analysis/analysis_matrix_in_rag?hyper_id=' + params.hyper_id)
return data
}
// http://8.140.26.4:10006/tech_hyper/api/analysis/get_event_relation_news_in_rag?hyper_id=1
export const getEventNewsList = async (params) => {
let data = await request.get('/api/analysis/get_event_relation_news_in_rag?hyper_id=' + params.hyper_id)
return data
}
// http://8.140.26.4:10006/tech_hyper/api/analysis/analysis_event_relations_in_rag?hyper_id=1
export const getEventData = async (params) => {
let data = await request.get('/api/analysis/analysis_event_relations_in_rag?hyper_id=' + params.hyper_id)
return data
}
/** /**
* 上传文件,后端解析Excel文件 * 上传文件,后端解析Excel文件
* @param file 文件,表单数据 * @param file 文件,表单数据
......
...@@ -9,7 +9,7 @@ const BASE_API = "/" ...@@ -9,7 +9,7 @@ const BASE_API = "/"
// 创建axios实例 // 创建axios实例
const service = axios.create({ const service = axios.create({
baseURL: BASE_API, //所有的后端接口请求地址前缀部分(没有后端请求不用写) baseURL: BASE_API, //所有的后端接口请求地址前缀部分(没有后端请求不用写)
timeout: 15000 // 请求超时时间,这里15秒 timeout: 50000 // 请求超时时间,这里15秒
//withCredentials: true,// 异步请求携带cookie,true为携带,false为不携带 //withCredentials: true,// 异步请求携带cookie,true为携带,false为不携带
//请求头里面设置通用传参类型 //请求头里面设置通用传参类型
/*headers: { /*headers: {
...@@ -35,6 +35,13 @@ service.interceptors.request.use(config => { ...@@ -35,6 +35,13 @@ service.interceptors.request.use(config => {
service.interceptors.response.use( service.interceptors.response.use(
response => { response => {
//对数据返回做什么 //对数据返回做什么
if (response.data.code == 0) {
ElMessage({
message: response.data.message,
type: 'error',
duration: 3 * 1000
})
}
return response.data return response.data
}, },
error => { error => {
......
...@@ -17,11 +17,14 @@ ...@@ -17,11 +17,14 @@
</div> </div>
</div> </div>
<div class="extra-container"> <div class="extra-container">
<div class="location-text text-ellipsis"> <!-- <div class="location-text text-ellipsis">
<span :title="item.country">{{ item.country }}</span> <span :title="item.country">{{ item.country }}</span>
</div> </div>
<div class="date-text text-ellipsis"> <div class="date-text text-ellipsis">
<span :title="item.date">{{ item.date || '-' }}</span> <span :title="item.date">{{ item.date || '-' }}</span>
</div> -->
<div class="date-text text-ellipsis">
<span :title="item.content" v-if="item.content">{{ item.content.join(',') || '-' }}</span>
</div> </div>
</div> </div>
</div> </div>
......
...@@ -13,13 +13,13 @@ ...@@ -13,13 +13,13 @@
<span>{{ index + 1 }}</span> <span>{{ index + 1 }}</span>
</div> </div>
<div class="name-text text-ellipsis"> <div class="name-text text-ellipsis">
<span :title="item.date + item.country" style="color: #AFD4F5;" >{{ "(" + item.date + "-" + item.country + ") " }}</span> <!-- <span :title="item.date + item.country" style="color: #AFD4F5;" >{{ "(" + item.date + "-" + item.country + ") " }}</span> -->
<span :title="item.title">{{ item.title || '-' }}</span> <span :title="item.title">{{ item.title || '-' }}</span>
</div> </div>
</div> </div>
<div class="extra-container"> <div class="extra-container">
<div class="location-text text-ellipsis"> <div class="location-text text-ellipsis">
<span :title="item.achievement">{{ item.achievement }}</span> <span :title="item.content">{{ item.content.join(',') }}</span>
</div> </div>
</div> </div>
</div> </div>
......
...@@ -16,17 +16,18 @@ ...@@ -16,17 +16,18 @@
<div class="chart-left-panel"> <div class="chart-left-panel">
<div class="chart-datalist-title"> <div class="chart-datalist-title">
<span>事件列表</span> <span>事件列表</span>
<el-button type="primary" size="small" @click="openRagDialog('chart')" style="margin-left: 10px;">RAG</el-button>
</div> </div>
<DataListChart :list="newsListChart" class="chart-datalist"></DataListChart> <DataListChart :list="newsListChart" class="chart-datalist"></DataListChart>
<div class="bottom-button-group"> <div class="bottom-button-group">
<!-- <el-button type="primary" @click="curvatureDrawing()">指标曲线绘制</el-button> --> <!-- <el-button type="primary" @click="curvatureDrawing()">指标曲线绘制</el-button> -->
<!-- <el-button type="primary" @click="curvatureAnalysis()">曲率分析</el-button> --> <!-- <el-button type="primary" @click="curvatureAnalysis()">曲率分析</el-button> -->
<el-checkbox v-model="curDrawing" label="指标曲线绘制" border @change="curvatureDrawing()" style="margin-right: 4px;"/> <el-checkbox v-model="curDrawing" label="指标曲线绘制" border @change="curvatureDrawing()" style="margin-right: 8px;"/>
<el-checkbox v-if="curDrawing" v-model="curAnalysis" label="曲率分析" border @change="curvatureAnalysis()" style="margin-right: 4px;"/> <el-checkbox v-if="curDrawing" v-model="curAnalysis" label="曲率分析" border @change="curvatureAnalysis()" style="margin-right: 8px;"/>
<el-button type="primary" @click="generateConclusion()">生成结论</el-button> <el-button type="primary" @click="generateConclusion()">生成结论</el-button>
</div> </div>
</div> </div>
<div class="main-chart" id="main-chart" ref="middleChartDom"></div> <div class="main-chart" id="main-chart" ref="middleChartDom" v-loading="chartLoading" element-loading-text="正在加载图表数据..." element-loading-background="rgba(0, 0, 0, 0.8)"></div>
<div class="chart-right-panel"> <div class="chart-right-panel">
<div class="conclusionlist-title"> <div class="conclusionlist-title">
<span>结论</span> <span>结论</span>
...@@ -38,7 +39,7 @@ ...@@ -38,7 +39,7 @@
<div v-show="focusBotton == '1'" class="bubble-panel"> <div v-show="focusBotton == '1'" class="bubble-panel">
<el-button type="primary" class="edit-button" @click="editDataFun()">编辑</el-button> <el-button type="primary" class="edit-button" @click="editDataFun()">编辑</el-button>
<div class="bubble-left-panel"> <div class="bubble-left-panel">
<div class="bubble-datalist-select"> <!-- <div class="bubble-datalist-select">
<div class="bubble-datalist-select-top"> <div class="bubble-datalist-select-top">
<span>选择年份:</span> <span>选择年份:</span>
<el-select v-model="selectedYear" multiple placeholder="请选择" collapse-tags collapse-tags-tooltip :max-collapse-tags="2"> <el-select v-model="selectedYear" multiple placeholder="请选择" collapse-tags collapse-tags-tooltip :max-collapse-tags="2">
...@@ -51,9 +52,10 @@ ...@@ -51,9 +52,10 @@
<el-option v-for="item in areaList" :key="item.value" :label="item.label" :value="item.value"></el-option> <el-option v-for="item in areaList" :key="item.value" :label="item.label" :value="item.value"></el-option>
</el-select> </el-select>
</div> </div>
</div> </div> -->
<div class="bubble-datalist-title"> <div class="bubble-datalist-title">
<span>事件列表</span> <span>事件列表</span>
<el-button type="primary" size="small" @click="openRagDialog('bubble')" style="margin-left: 10px;">RAG</el-button>
</div> </div>
<DataList :list="newsListChartBubble" class="bubble-datalist"></DataList> <DataList :list="newsListChartBubble" class="bubble-datalist"></DataList>
<div class="bottom-button-group"> <div class="bottom-button-group">
...@@ -104,7 +106,7 @@ ...@@ -104,7 +106,7 @@
</div> </div>
<div v-show="focusBotton == '2'" class="g6-panel"> <div v-show="focusBotton == '2'" class="g6-panel">
<div class="g6-left-panel"> <div class="g6-left-panel">
<div class="g6-datalist-select"> <!-- <div class="g6-datalist-select">
<div class="g6-datalist-select-top"> <div class="g6-datalist-select-top">
<span>选择模型:</span> <span>选择模型:</span>
<el-select v-model="selectedModel" multiple placeholder="请选择" collapse-tags collapse-tags-tooltip :max-collapse-tags="2"> <el-select v-model="selectedModel" multiple placeholder="请选择" collapse-tags collapse-tags-tooltip :max-collapse-tags="2">
...@@ -117,9 +119,10 @@ ...@@ -117,9 +119,10 @@
<el-option v-for="item in yearListG6" :key="item.value" :label="item.label" :value="item.value"></el-option> <el-option v-for="item in yearListG6" :key="item.value" :label="item.label" :value="item.value"></el-option>
</el-select> </el-select>
</div> </div>
</div> </div> -->
<div class="g6-datalist-title"> <div class="g6-datalist-title">
<span>事件列表</span> <span>事件列表</span>
<el-button type="primary" size="small" @click="openRagDialog('g6')" style="margin-left: 10px;">RAG</el-button>
</div> </div>
<DataList :list="newsListChartG6" class="g6-datalist"></DataList> <DataList :list="newsListChartG6" class="g6-datalist"></DataList>
<div class="bottom-button-group"> <div class="bottom-button-group">
...@@ -129,7 +132,7 @@ ...@@ -129,7 +132,7 @@
</div> </div>
</div> </div>
<div class="g6-center-panel"> <div class="g6-center-panel">
<div id="g6Container" class="g6-panel-main" ref="graphRef"></div> <div id="g6Container" class="g6-panel-main" ref="graphRef" v-loading="graphLoading" element-loading-background="rgba(0, 0, 0, 0.2)"></div>
<div id="g6ContainerBottom" class="g6-bottom-panel-main" ref="graphBottomRef"></div> <div id="g6ContainerBottom" class="g6-bottom-panel-main" ref="graphBottomRef"></div>
</div> </div>
<div class="g6-right-panel"> <div class="g6-right-panel">
...@@ -174,6 +177,12 @@ ...@@ -174,6 +177,12 @@
<el-dialog title="编辑数据" v-model="editDialogEvents.visible" width="80%" :before-close="handleClose2" :close-on-click-modal="false" :modal="false"> <el-dialog title="编辑数据" v-model="editDialogEvents.visible" width="80%" :before-close="handleClose2" :close-on-click-modal="false" :modal="false">
<EditDataG6Comp v-if="editDialogEvents.visible" ref="editDataRef" :editTableData="g6Data" :tabIndex="focusBotton" @saveTableDataItems="saveEditTableDataEvents"></EditDataG6Comp> <EditDataG6Comp v-if="editDialogEvents.visible" ref="editDataRef" :editTableData="g6Data" :tabIndex="focusBotton" @saveTableDataItems="saveEditTableDataEvents"></EditDataG6Comp>
</el-dialog> </el-dialog>
<RagDialog
v-model="ragDialog.visible"
:prompt="ragDialog.prompt"
:hyperId="hyperId"
:focusButton="focusBotton"
@submit="handleRagSubmit" />
</div> </div>
</template> </template>
...@@ -194,7 +203,6 @@ import { ...@@ -194,7 +203,6 @@ import {
getChart, getChart,
getChartEditTable, getChartEditTable,
saveChartTable, saveChartTable,
getMatrix,
getMatrixEditTable, getMatrixEditTable,
saveMatrixTable, saveMatrixTable,
getEvents, getEvents,
...@@ -207,10 +215,19 @@ import EditDataG6Comp from './EditDataG6.vue' ...@@ -207,10 +215,19 @@ import EditDataG6Comp from './EditDataG6.vue'
import DataList from "./DataList.vue" import DataList from "./DataList.vue"
import DataListChart from "./DataListChart.vue" import DataListChart from "./DataListChart.vue"
import ConclusionList from "./ConclusionList.vue" import ConclusionList from "./ConclusionList.vue"
import RagDialog from "./RagDialog.vue"
import newsList from "../data/newsList.json" import newsList from "../data/newsList.json"
import newsListG6 from "../data/newsListG6.json" import newsListG6 from "../data/newsListG6.json"
import lineChartData from "../data/chart.json" import lineChartData from "../data/chart.json"
import gptData from "../data/gpt.json" import gptData from "../data/gpt.json"
import {
getChartNewsList,
getChartData,
getMatrixNewsList,
getMatrixData,
getEventNewsList,
getEventData
} from "@/api/graphApi";
const { const {
appContext appContext
...@@ -219,6 +236,7 @@ const globalProxy = appContext.config.globalProperties; ...@@ -219,6 +236,7 @@ const globalProxy = appContext.config.globalProperties;
let curDrawing = ref(false) let curDrawing = ref(false)
let curAnalysis = ref(false) let curAnalysis = ref(false)
let chartLoading = ref(false)
let graphData = ref({ let graphData = ref({
nodes: {}, nodes: {},
edges: [], edges: [],
...@@ -238,6 +256,11 @@ let editDialog = ref({ ...@@ -238,6 +256,11 @@ let editDialog = ref({
let editDialogEvents = ref({ let editDialogEvents = ref({
visible: false visible: false
}); });
// RAG弹窗相关数据
let ragDialog = ref({
visible: false,
prompt: ''
});
let graphRef = ref(); let graphRef = ref();
let graphBottomRef = ref(); let graphBottomRef = ref();
let editDataRef = ref(); let editDataRef = ref();
...@@ -379,17 +402,65 @@ let g6Data = ref({}) ...@@ -379,17 +402,65 @@ let g6Data = ref({})
let newsListChart = ref([]) let newsListChart = ref([])
let newsListChartBubble = ref([]) let newsListChartBubble = ref([])
let newsListChartG6 = ref([]) let newsListChartG6 = ref([])
newsListChart.value = newsList.data; // newsListChart.value = newsList.data;
newsListChartBubble.value = newsList.data; // newsListChartBubble.value = newsList.data;
newsListChartG6.value = newsListG6.data; // newsListChartG6.value = newsListG6.data;
let conclusionsList = ref([]) let conclusionsList = ref([])
let conListBubble = ref([]) let conListBubble = ref([])
let conListBubbleBottom = ref([]) let conListBubbleBottom = ref([])
let conListG6 = ref([]) let conListG6 = ref([])
let hyperId = ref(null)
async function getNewsList() {
const res = await getChartNewsList({
hyper_id: hyperId.value
})
if (res.code == 1) {
newsListChart.value = res.data
console.log(res.data)
}
}
async function getMatrixNews() {
const res = await getMatrixNewsList({
hyper_id: hyperId.value
})
if (res.code == 1) {
newsListChartBubble.value = res.data;
console.log(res.data)
}
}
async function getEventNews() {
const res = await getEventNewsList({
hyper_id: hyperId.value
})
if (res.code == 1) {
newsListChartG6.value = res.data
console.log(res.data)
}
}
async function getChartLine() {
const res = await getChartData({
hyper_id: hyperId.value
})
if (res.code == 1) {
console.log(res.data)
return res.data
}
return null
}
onMounted(() => { onMounted(() => {
const theme = localStorage.getItem('theme')
hyperId.value = JSON.parse(theme).group_id
getNewsList()
// getMatrixNews()
// getChartLine()
}) })
function handleClose() { function handleClose() {
...@@ -400,8 +471,22 @@ function handleClose2(params) { ...@@ -400,8 +471,22 @@ function handleClose2(params) {
editDialogEvents.value.visible = false; editDialogEvents.value.visible = false;
} }
const graphLoading = ref(false)
// 获取图谱数据列表 // 获取图谱数据列表
function getGraphList() { async function getGraphList() {
graphLoading.value = true
const res = await getEventData({
hyper_id: hyperId.value
})
graphLoading.value = false
if (res.code == 1) {
graphData.value.nodes = res.data.events
graphData.value.edges = res.data.events_relations
graphData.value.time = res.data.events_time
graphData.value.type = res.data.events_type
graphData.value.relation_type = res.data.relation_type
initGraph(graphData.value);
}
// getEvents().then((res) => { // getEvents().then((res) => {
// if (res) { // if (res) {
// graphData.value.nodes = res.data.events // graphData.value.nodes = res.data.events
...@@ -412,12 +497,12 @@ function getGraphList() { ...@@ -412,12 +497,12 @@ function getGraphList() {
// initGraph(graphData.value); // initGraph(graphData.value);
// } // }
// }) // })
graphData.value.nodes = gptData.data.events // graphData.value.nodes = gptData.data.events
graphData.value.edges = gptData.data.events_relations // graphData.value.edges = gptData.data.events_relations
graphData.value.time = gptData.data.events_time // graphData.value.time = gptData.data.events_time
graphData.value.type = gptData.data.events_type // graphData.value.type = gptData.data.events_type
graphData.value.relation_type = gptData.data.relation_type // graphData.value.relation_type = gptData.data.relation_type
initGraph(graphData.value); // initGraph(graphData.value);
} }
...@@ -930,6 +1015,17 @@ function initG6GraphBottom() { ...@@ -930,6 +1015,17 @@ function initG6GraphBottom() {
function handleClick(item) { function handleClick(item) {
focusBotton.value = item.index; focusBotton.value = item.index;
switch(item.index) {
case "0":
getNewsList();
break;
case "1":
getMatrixNews();
break;
case "2":
getEventNews();
break;
}
} }
function editDataFun() { function editDataFun() {
...@@ -959,7 +1055,7 @@ function editDataFun2(params) { ...@@ -959,7 +1055,7 @@ function editDataFun2(params) {
function curvatureDrawing(){ function curvatureDrawing(){
if (curDrawing.value){ if (curDrawing.value){
initChart(); initChartLine();
} else { } else {
curAnalysis.value = false; curAnalysis.value = false;
if (myChart) { if (myChart) {
...@@ -1051,10 +1147,20 @@ function generateConclusionG6(){ ...@@ -1051,10 +1147,20 @@ function generateConclusionG6(){
} }
function initMatrix() { function initMatrix() {
getMatrix().then((res) => { getMatrixData({ hyper_id: hyperId.value }).then((res) => {
if (res.data && res.data.length > 0) { if (res.code === 1 && res.data && res.data.length > 0) {
targetList.value = res.data; // 更新数据结构,将title改为event_title以匹配模板
targetList.value = res.data.map(item => ({
...item,
event_title: item.title
}));
} }
}).catch((error) => {
console.error('获取矩阵数据失败:', error);
globalProxy.$message({
type: "error",
message: "获取矩阵数据失败",
});
}) })
} }
...@@ -1103,6 +1209,33 @@ function saveEditTableDataEvents(params) { ...@@ -1103,6 +1209,33 @@ function saveEditTableDataEvents(params) {
}) })
} }
// RAG相关方法
function openRagDialog(tabType) {
// 根据不同的tab类型设置不同的默认prompt
let defaultPrompt = '';
switch(tabType) {
case 'chart':
defaultPrompt = '请分析图表数据中的关键趋势和模式';
break;
case 'bubble':
defaultPrompt = '请分析气泡图中的数据关系和分布特征';
break;
case 'g6':
defaultPrompt = '请分析机理图中的节点关系和因果链条';
break;
default:
defaultPrompt = '请输入您的分析需求';
}
ragDialog.value.prompt = defaultPrompt;
ragDialog.value.visible = true;
}
function handleRagSubmit(prompt) {
console.log('RAG请求提交:', prompt);
// 这里可以添加额外的处理逻辑
}
function superLongTextHandle(str, maxWidth, fontSize) { function superLongTextHandle(str, maxWidth, fontSize) {
let currentWidth = 0; let currentWidth = 0;
let res = str; let res = str;
...@@ -1280,6 +1413,107 @@ function initChart() { ...@@ -1280,6 +1413,107 @@ function initChart() {
}) })
} }
// 使用真实接口数据绘制折线图
async function initChartLine() {
let chartDom = document.getElementById("main-chart");
if (!myChart) {
myChart = echarts.init(chartDom);
}
// 设置加载状态
chartLoading.value = true;
try {
// 获取真实数据
const chartData = await getChartLine();
if (!chartData) {
globalProxy.$message({
type: "error",
message: "获取图表数据失败",
});
return;
}
// 从接口数据中提取图例数据
let legendListData = chartData.series.map(item => item.name);
let xAxisData = chartData.xAxis.data;
let seriesData = chartData.series;
let option = {
tooltip: {
trigger: 'axis'
},
legend: {
data: legendListData,
textStyle: {
color: "#FFFFFF",
fontSize: 14
}
},
grid: {
left: '10px',
right: '10px',
bottom: '10px',
containLabel: true
},
xAxis: {
type: 'category',
data: xAxisData,
nameTextStyle: {
color: "#FFFFFF",
fontSize: 20,
},
axisLabel: {
color: "#FFFFFF",
fontSize: 20,
fontWeight: 400,
fontFamily: "Source Han Sans CN"
},
},
yAxis: {
type: 'value',
nameTextStyle: {
color: "#FFFFFF",
fontSize: 20,
},
axisLabel: {
color: "#FFFFFF",
fontSize: 20,
interval: 0,
fontWeight: 400,
fontFamily: "Source Han Sans CN"
},
splitLine: {
lineStyle: {
color: 'rgba(106, 110, 126, 0.6)'
}
}
},
series: seriesData
};
option && myChart.setOption(option);
window.addEventListener("resize", function () {
if (myChart) {
myChart.resize();
}
if (curAnalysis.value){
markMaxAngleSegment();
}
})
} catch (error) {
console.error('绘制图表时发生错误:', error);
globalProxy.$message({
type: "error",
message: "绘制图表时发生错误",
});
} finally {
// 无论成功还是失败都要关闭加载状态
chartLoading.value = false;
}
}
// 计算相邻两点之间的倾斜角 // 计算相邻两点之间的倾斜角
function calculateSlopeAngles(points) { function calculateSlopeAngles(points) {
const angles = []; const angles = [];
...@@ -1533,6 +1767,18 @@ function addArrow(rectCenterX, rectBottomY, minY, arrowEndY, arrowWidth, labelOf ...@@ -1533,6 +1767,18 @@ function addArrow(rectCenterX, rectBottomY, minY, arrowEndY, arrowWidth, labelOf
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
.bottom-button-group {
margin-top: 10px;
text-align: left;
background-color: inherit;
padding-top: 10px;
display: flex;
flex-wrap: wrap;
gap: 8px;
.el-button+.el-button {
margin-left: 0;
}
}
.graph-analysis-wrap { .graph-analysis-wrap {
position: relative; position: relative;
margin: 10px; margin: 10px;
...@@ -1597,13 +1843,14 @@ function addArrow(rectCenterX, rectBottomY, minY, arrowEndY, arrowWidth, labelOf ...@@ -1597,13 +1843,14 @@ function addArrow(rectCenterX, rectBottomY, minY, arrowEndY, arrowWidth, labelOf
position: relative; position: relative;
width: 100%; width: 100%;
height: calc(100% - 50px); height: calc(100% - 50px);
overflow: auto; // overflow: auto;
display: flex; display: flex;
.chart-left-panel { .chart-left-panel {
width: calc(20% - 10px); width: calc(20% - 10px);
padding-right: 10px; padding-right: 10px;
border-right: 1px solid #6E87AF; border-right: 1px solid #6E87AF;
position: relative;
.chart-datalist-title { .chart-datalist-title {
height: 40px; height: 40px;
...@@ -1616,17 +1863,10 @@ function addArrow(rectCenterX, rectBottomY, minY, arrowEndY, arrowWidth, labelOf ...@@ -1616,17 +1863,10 @@ function addArrow(rectCenterX, rectBottomY, minY, arrowEndY, arrowWidth, labelOf
} }
.chart-datalist { .chart-datalist {
height: calc(100% - 100px); height: calc(100% - 160px);
overflow-y: auto; overflow-y: auto;
padding: 10px 4px 0 4px; padding: 10px 4px 0 4px;
} }
.bottom-button-group {
margin-top: 10px;
text-align: left;
display: flex;
align-items: center;
}
} }
.main-chart { .main-chart {
...@@ -1664,6 +1904,7 @@ function addArrow(rectCenterX, rectBottomY, minY, arrowEndY, arrowWidth, labelOf ...@@ -1664,6 +1904,7 @@ function addArrow(rectCenterX, rectBottomY, minY, arrowEndY, arrowWidth, labelOf
width: calc(20% - 10px); width: calc(20% - 10px);
padding-right: 10px; padding-right: 10px;
border-right: 1px solid #6E87AF; border-right: 1px solid #6E87AF;
position: relative;
.bubble-datalist-select { .bubble-datalist-select {
.bubble-datalist-select-top { .bubble-datalist-select-top {
...@@ -1685,7 +1926,6 @@ function addArrow(rectCenterX, rectBottomY, minY, arrowEndY, arrowWidth, labelOf ...@@ -1685,7 +1926,6 @@ function addArrow(rectCenterX, rectBottomY, minY, arrowEndY, arrowWidth, labelOf
} }
.bubble-datalist-title { .bubble-datalist-title {
margin-top: 10px;
height: 40px; height: 40px;
font-size: 26px; font-size: 26px;
font-weight: 500; font-weight: 500;
...@@ -1696,15 +1936,10 @@ function addArrow(rectCenterX, rectBottomY, minY, arrowEndY, arrowWidth, labelOf ...@@ -1696,15 +1936,10 @@ function addArrow(rectCenterX, rectBottomY, minY, arrowEndY, arrowWidth, labelOf
} }
.bubble-datalist { .bubble-datalist {
height: calc(100% - 180px); height: calc(100% - 160px);
overflow-y: auto; overflow-y: auto;
padding: 10px 4px 0 4px; padding: 10px 4px 0 4px;
} }
.bottom-button-group {
margin-top: 10px;
text-align: left;
}
} }
.bubble-box { .bubble-box {
...@@ -1720,7 +1955,7 @@ function addArrow(rectCenterX, rectBottomY, minY, arrowEndY, arrowWidth, labelOf ...@@ -1720,7 +1955,7 @@ function addArrow(rectCenterX, rectBottomY, minY, arrowEndY, arrowWidth, labelOf
display: flex; display: flex;
.info { .info {
width: 200px; width: 160px;
.img { .img {
text-align: center; text-align: center;
...@@ -1808,6 +2043,7 @@ function addArrow(rectCenterX, rectBottomY, minY, arrowEndY, arrowWidth, labelOf ...@@ -1808,6 +2043,7 @@ function addArrow(rectCenterX, rectBottomY, minY, arrowEndY, arrowWidth, labelOf
width: calc(20% - 10px); width: calc(20% - 10px);
padding-right: 10px; padding-right: 10px;
border-right: 1px solid #6E87AF; border-right: 1px solid #6E87AF;
position: relative;
.g6-datalist-select { .g6-datalist-select {
.g6-datalist-select-top { .g6-datalist-select-top {
...@@ -1840,15 +2076,10 @@ function addArrow(rectCenterX, rectBottomY, minY, arrowEndY, arrowWidth, labelOf ...@@ -1840,15 +2076,10 @@ function addArrow(rectCenterX, rectBottomY, minY, arrowEndY, arrowWidth, labelOf
} }
.g6-datalist { .g6-datalist {
height: calc(100% - 180px); height: calc(100% - 160px);
overflow-y: auto; overflow-y: auto;
padding: 10px 4px 0 4px; padding: 10px 4px 0 4px;
} }
.bottom-button-group {
margin-top: 10px;
text-align: left;
}
} }
.g6-center-panel { .g6-center-panel {
......
<template>
<el-dialog title="RAG 分析" v-model="visible" width="60%" :close-on-click-modal="false" @close="handleClose">
<el-form :model="form" label-width="80px" label-position="top">
<el-form-item label="Prompt">
<el-input
v-model="form.prompt"
type="textarea"
:rows="6"
placeholder="请输入prompt内容"
/>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="handleClose">取消</el-button>
<el-button type="primary" @click="handleSubmit">确定</el-button>
</span>
</template>
</el-dialog>
</template>
<script setup>
import { ref, watch, getCurrentInstance, onMounted } from 'vue'
import { getChartPrompt, saveChartPrompt } from '@/api/graphApi'
const { appContext } = getCurrentInstance();
const globalProxy = appContext.config.globalProperties;
const props = defineProps({
modelValue: {
type: Boolean,
default: false
},
prompt: {
type: String,
default: ''
},
hyperId: {
type: Number,
default: 1
},
focusButton: {
type: Number,
default: false
}
})
const getUrlMap = {
0: 'get_chart_prompt',
1: 'get_matrix_prompt',
2: 'get_event_relation_prompt'
}
const saveUrlMap = {
0: 'save_chart_prompt',
1: 'save_matrix_prompt',
2: 'save_event_relation_prompt'
}
const emit = defineEmits(['update:modelValue', 'submit'])
const visible = ref(false)
const form = ref({
prompt: ''
})
// 监听props变化
watch(() => props.modelValue, async (newVal) => {
visible.value = newVal
if (newVal) {
// 当对话框打开时,获取prompt数据
await fetchPromptData()
}
})
// 移除对props.prompt的监听,现在直接从接口获取数据
// 监听visible变化,同步到父组件
watch(visible, (newVal) => {
emit('update:modelValue', newVal)
})
function handleClose() {
visible.value = false
}
// 获取prompt数据
async function fetchPromptData() {
try {
const params = {
hyper_id: props.hyperId
}
const response = await getChartPrompt(params, getUrlMap[props.focusButton])
if (response.code === 1 && response.data) {
form.value.prompt = response.data
}
} catch (error) {
console.error('获取prompt失败:', error)
globalProxy.$message({
message: '获取prompt数据失败',
type: 'error'
})
}
}
// 保存prompt数据
async function savePromptData() {
try {
const params = {
hyper_id: props.hyperId,
prompt: form.value.prompt
}
const response = await saveChartPrompt(params, saveUrlMap[props.focusButton])
return response
} catch (error) {
console.error('保存prompt失败:', error)
throw error
}
}
async function handleSubmit() {
console.log('RAG请求参数:', form.value.prompt)
if (!form.value.prompt.trim()) {
globalProxy.$message({
message: '请输入prompt内容',
type: 'warning'
})
return
}
try {
globalProxy.$message({
message: '正在保存prompt...',
type: 'info'
})
await savePromptData()
globalProxy.$message({
message: 'Prompt保存成功!',
type: 'success'
})
visible.value = false
emit('submit', form.value.prompt)
} catch (error) {
globalProxy.$message({
message: '保存prompt失败',
type: 'error'
})
}
}
// 组件挂载时获取数据
onMounted(() => {
if (visible.value) {
fetchPromptData()
}
})
</script>
<style scoped>
.dialog-footer {
display: flex;
justify-content: flex-end;
gap: 10px;
}
</style>
\ No newline at end of file
...@@ -232,6 +232,7 @@ function getEventGraphData(id) { ...@@ -232,6 +232,7 @@ function getEventGraphData(id) {
let paramsObj = { let paramsObj = {
id: id id: id
} }
if (!paramsObj.id) return
getHypermapById(paramsObj).then((res)=>{ getHypermapById(paramsObj).then((res)=>{
let leftTopLon = res.data.bounds.leftTop.lon; let leftTopLon = res.data.bounds.leftTop.lon;
let leftTopLat = res.data.bounds.leftTop.lat; let leftTopLat = res.data.bounds.leftTop.lat;
......
...@@ -185,11 +185,36 @@ function handleConfirmRelation() { ...@@ -185,11 +185,36 @@ function handleConfirmRelation() {
to, to,
relation_name relation_name
} = relationFormState.value; } = relationFormState.value;
if (from && to && relation_name) {
emit("handleConfirmRelation", relationFormState.value); // 详细的表单验证
} else { if (!from) {
globalProxy.$message.error("有未选择项"); globalProxy.$message.error("请选择起始节点");
return;
} }
if (!to) {
globalProxy.$message.error("请选择目标节点");
return;
}
if (!relation_name || relation_name.trim() === '') {
globalProxy.$message.error("请输入关系名称");
return;
}
if (from === to) {
globalProxy.$message.error("起始节点和目标节点不能相同");
return;
}
// 验证关系名称长度
if (relation_name.trim().length > 50) {
globalProxy.$message.error("关系名称不能超过50个字符");
return;
}
// 发送确认事件
emit("handleConfirmRelation", {
...relationFormState.value,
relation_name: relation_name.trim() // 去除首尾空格
});
} }
function handleExchange() { function handleExchange() {
......
...@@ -1198,58 +1198,107 @@ const handleQuery = (e) => { ...@@ -1198,58 +1198,107 @@ const handleQuery = (e) => {
// 建立节点与节点之间的关系 // 建立节点与节点之间的关系
function handleConfirmRelation(e) { function handleConfirmRelation(e) {
console.log("e", e); console.log("新增关系参数:", e);
console.log("graph_data", graph_data.value); console.log("当前图数据:", graph_data.value);
let savedGraph = _.cloneDeep(graph_data.value); try {
let graph = simplifyData(savedGraph); // 验证必要参数
let id = props.eventGraphId; if (!e.from || !e.to || !e.relation_name) {
globalProxy.$message.error("关系参数不完整,请检查起始节点、目标节点和关系名称");
return;
}
console.log("graph", graph); let savedGraph = _.cloneDeep(graph_data.value);
let graph = simplifyData(savedGraph);
let id = props.eventGraphId;
const newEdge = { // 查找源节点和目标节点
date: null, const sourceNode = graph.nodes.find((item) => item.label === e.from);
label: e.relation_name, const targetNode = graph.nodes.find((item) => item.label === e.to);
source: graph.nodes.filter((item) => {
return item.label === e.from;
})[0].id,
target: graph.nodes.filter((item) => {
return item.label === e.to;
})[0].id,
};
graph.edges = [...graph.edges, newEdge]; if (!sourceNode || !targetNode) {
globalProxy.$message.error("未找到对应的节点,请确认节点是否存在");
return;
}
let zoom_center = {}; // 检查是否已存在相同的关系
emit("saveMap", (val) => { const existingEdge = graph.edges.find((edge) =>
zoom_center = val; edge.source === sourceNode.id &&
}); edge.target === targetNode.id &&
edge.label === e.relation_name
);
if (existingEdge) {
globalProxy.$message.warning("该关系已存在,无需重复添加");
handleCloseAddRelation();
return;
}
let params = { // 创建新的关系边
hyper_id: id, const newEdge = {
graph: { id: `edge_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`, // 生成唯一ID
data: graph, date: null,
zoom_center: zoom_center, label: e.relation_name,
}, source: sourceNode.id,
}; target: targetNode.id,
saveHypergraph(params) };
.then((res) => {
if (res.code === 1) { // 添加新关系到图数据
graph.edges = [...graph.edges, newEdge];
console.log("更新后的图数据:", graph);
// 获取当前视图中心点
let zoom_center = {};
emit("saveMap", (val) => {
zoom_center = val;
});
// 构建保存参数
let params = {
hyper_id: id,
graph: {
data: graph,
zoom_center: zoom_center,
},
};
console.log("保存超图参数:", params);
// 调用保存接口
saveHypergraph(params)
.then((res) => {
console.log("保存超图响应:", res);
if (res.code === 1) {
globalProxy.$message({
type: "success",
message: "新增关系成功",
});
// 刷新图谱数据
emit("refreshGraph");
handleCloseAddRelation();
} else {
globalProxy.$message({
type: "error",
message: res.message || "新增关系失败",
});
}
})
.catch((error) => {
console.error("保存超图失败:", error);
globalProxy.$message({ globalProxy.$message({
type: "success", type: "error",
message: "保存成功", message: "网络错误,新增关系失败,请稍后重试",
}); });
emit("refreshGraph");
}
})
.catch(() => {
globalProxy.$message({
type: "error",
message: "保存失败",
}); });
} catch (error) {
console.error("新增关系处理异常:", error);
globalProxy.$message({
type: "error",
message: "处理新增关系时发生异常,请稍后重试",
}); });
handleCloseAddRelation();
handleCloseAddRelation(); }
} }
// 融合图谱数据 // 融合图谱数据
/** /**
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论