数据分析优化
This commit is contained in:
parent
267a47535d
commit
2ab6b34c2c
|
@ -4,8 +4,8 @@
|
||||||
<template #extra>
|
<template #extra>
|
||||||
<a-cascader v-model:value="collegeMajor" :options="collegeMajorOptions" change-on-select />
|
<a-cascader v-model:value="collegeMajor" :options="collegeMajorOptions" change-on-select />
|
||||||
<a-button style="margin-left: 10px" type="primary" @click="query">查询</a-button>
|
<a-button style="margin-left: 10px" type="primary" @click="query">查询</a-button>
|
||||||
<a-button style="margin-left: 10px" :loading="aiLoading" v-show="resultData != null" type="primary" @click="getAI">分析</a-button>
|
<a-button style="margin-left: 10px" :loading="aiLoading" v-show="resultData != null" type="primary"
|
||||||
<!-- <a-button @click=test()>test</a-button> -->
|
@click="getAI">分析</a-button>
|
||||||
</template>
|
</template>
|
||||||
<a-row :gutter="12">
|
<a-row :gutter="12">
|
||||||
<a-col :xl="12">
|
<a-col :xl="12">
|
||||||
|
@ -13,12 +13,6 @@
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :xl="12">
|
<a-col :xl="12">
|
||||||
<div style="width: 100%; height: 215px" class="piechart" id="pieChart"> </div>
|
<div style="width: 100%; height: 215px" class="piechart" id="pieChart"> </div>
|
||||||
<!--
|
|
||||||
<a-card style="margin-top: 33px; margin-bottom: 12px">
|
|
||||||
</a-card>-->
|
|
||||||
<!--<a-card>
|
|
||||||
<div style="width: 100%; height: 180px" id="map2"> </div>
|
|
||||||
</a-card>-->
|
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
<a-card style="margin-bottom: 10px" class="tip">
|
<a-card style="margin-bottom: 10px" class="tip">
|
||||||
|
@ -26,20 +20,17 @@
|
||||||
<div v-html="aiMessage"></div>
|
<div v-html="aiMessage"></div>
|
||||||
</div>
|
</div>
|
||||||
</a-card>
|
</a-card>
|
||||||
<!-- <div style="height: 300px;">
|
|
||||||
<a-empty style="margin-top: 100px" />
|
|
||||||
</div> -->
|
|
||||||
</a-card>
|
</a-card>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { defHttp } from '/@/utils/http/axios';
|
import { defHttp } from '/@/utils/http/axios';
|
||||||
import * as echarts from 'echarts';
|
import * as echarts from 'echarts';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { marked } from 'marked';
|
import { marked } from 'marked';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
loading: false,
|
loading: false,
|
||||||
|
@ -174,12 +165,12 @@
|
||||||
};
|
};
|
||||||
console.log('params', params);
|
console.log('params', params);
|
||||||
const result = await defHttp.post({ url: this.Url.getAnalyze, params });
|
const result = await defHttp.post({ url: this.Url.getAnalyze, params });
|
||||||
this.resultData = result;
|
this.resultData = result.data;
|
||||||
//生成饼图
|
//生成饼图
|
||||||
console.log(result, 'res');
|
console.log(result, 'res');
|
||||||
const resdata = [];
|
const resdata = [];
|
||||||
// 遍历后端返回的数据
|
// 遍历后端返回的数据
|
||||||
for (const [range, rate] of Object.entries(result.rateByBatch)) {
|
for (const [range, rate] of Object.entries(result.data[0].rateByBatch)) {
|
||||||
// 将数据转换为图表需要的格式
|
// 将数据转换为图表需要的格式
|
||||||
resdata.push({
|
resdata.push({
|
||||||
value: parseFloat(rate), // 将比率转换为数字类型
|
value: parseFloat(rate), // 将比率转换为数字类型
|
||||||
|
@ -198,9 +189,9 @@
|
||||||
//独立修改最后一个数据
|
//独立修改最后一个数据
|
||||||
resdata[4].name = '475分以上人数占比';
|
resdata[4].name = '475分以上人数占比';
|
||||||
const piedata = [];
|
const piedata = [];
|
||||||
piedata.push({ value: result.scoreByBatch.read, name: '阅读' });
|
piedata.push({ value: result.data[0].scoreByBatch.read, name: '阅读' });
|
||||||
piedata.push({ value: result.scoreByBatch.listen, name: '听力' });
|
piedata.push({ value: result.data[0].scoreByBatch.listen, name: '听力' });
|
||||||
piedata.push({ value: result.scoreByBatch.write, name: '写作' });
|
piedata.push({ value: result.data[0].scoreByBatch.write, name: '写作' });
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.drawResChart(resdata);
|
this.drawResChart(resdata);
|
||||||
this.drawPieChart(piedata);
|
this.drawPieChart(piedata);
|
||||||
|
@ -287,25 +278,29 @@
|
||||||
|
|
||||||
async getAI() {
|
async getAI() {
|
||||||
this.aiLoading = true;
|
this.aiLoading = true;
|
||||||
|
this.aiMessage = ''; // 清空之前的内容
|
||||||
|
|
||||||
let validMessages = [
|
let validMessages = [
|
||||||
{
|
{
|
||||||
role: 'user',
|
role: 'user',
|
||||||
content:
|
content:
|
||||||
JSON.stringify(this.resultData) +
|
JSON.stringify(this.resultData) +
|
||||||
'这是我们学校的四级成绩,第一个是分数在400-425区间的人数占比,下面的是听力阅读等模块的平均成绩,我是我们学校英语教研组的,请你给出提升意见',
|
'这是我们学校的四级成绩,在回答时无需再次具体说明数据,batch为批次,总共是最近三个批次的数据,rateByBatch为每个分数段的人数占比,scoreByBatch为四级每个模块的平均分,分别为阅读、写作、听力。我是我们学校英语教研组的,请你进行分析并给出提升意见',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
try {
|
||||||
const response = await fetch('https://api.deepseek.com/v1/chat/completions', {
|
const response = await fetch('https://api.deepseek.com/v1/chat/completions', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
Accept: 'application/json',
|
'Accept': 'application/json',
|
||||||
Authorization: 'Bearer sk-1d3dd761c40045228547efb38ce59754',
|
'Authorization': 'Bearer sk-1d3dd761c40045228547efb38ce59754',
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
model: 'deepseek-chat',
|
model: 'deepseek-chat',
|
||||||
messages: validMessages,
|
messages: validMessages,
|
||||||
stream: false, // 关键修改!关闭流式响应
|
stream: true, // 启用流式响应
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -313,20 +308,41 @@
|
||||||
throw new Error(`API请求失败: ${response.status}`);
|
throw new Error(`API请求失败: ${response.status}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. 获取完整响应
|
const reader = response.body.getReader();
|
||||||
const data = await response.json();
|
const decoder = new TextDecoder();
|
||||||
|
let fullMessage = '(数据分析由deepseek生成,仅供参考)\n\n';
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
const { done, value } = await reader.read();
|
||||||
|
if (done) break;
|
||||||
|
|
||||||
|
const chunk = decoder.decode(value);
|
||||||
|
const lines = chunk.split('\n');
|
||||||
|
|
||||||
|
for (const line of lines) {
|
||||||
|
if (line.startsWith('data: ')) {
|
||||||
|
const data = line.slice(6);
|
||||||
|
if (data === '[DONE]') continue;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const parsed = JSON.parse(data);
|
||||||
|
if (parsed.choices[0].delta?.content) {
|
||||||
|
fullMessage += parsed.choices[0].delta.content;
|
||||||
|
// 更新显示内容
|
||||||
|
this.aiMessage = marked(fullMessage);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error('解析响应数据时出错:', e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取AI分析失败:', error);
|
||||||
|
this.aiMessage = marked('抱歉,分析过程中发生了错误,请稍后重试。');
|
||||||
|
} finally {
|
||||||
this.aiLoading = false;
|
this.aiLoading = false;
|
||||||
const assistantResponse = data.choices[0].message;
|
}
|
||||||
console.log(data, 'data');
|
|
||||||
// 4. 创建助手消息对象
|
|
||||||
const assistantMessage = {
|
|
||||||
role: 'assistant',
|
|
||||||
content: assistantResponse.content,
|
|
||||||
reasoning: assistantResponse.reasoning_content || '', // 如果有思考过程
|
|
||||||
};
|
|
||||||
this.aiMessage = '(数据分析由deepseek生成,仅供参考)\n\n' + assistantMessage.content;
|
|
||||||
this.aiMessage = marked(this.aiMessage);
|
|
||||||
console.log(assistantMessage);
|
|
||||||
},
|
},
|
||||||
drawResChart(piedata) {
|
drawResChart(piedata) {
|
||||||
console.log(this.passRatePie);
|
console.log(this.passRatePie);
|
||||||
|
@ -336,66 +352,6 @@
|
||||||
console.log('xData', xData);
|
console.log('xData', xData);
|
||||||
console.log('Data', Data);
|
console.log('Data', Data);
|
||||||
let myChart = echarts.init(document.getElementById('resChart'));
|
let myChart = echarts.init(document.getElementById('resChart'));
|
||||||
//let option = {
|
|
||||||
// tooltip: {
|
|
||||||
// trigger: 'item',
|
|
||||||
// confine: false,
|
|
||||||
// avoidLabelOverlap: true,
|
|
||||||
// //字体大小
|
|
||||||
// itemStyle: {
|
|
||||||
// fontSize: 100,
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
|
|
||||||
// title: {
|
|
||||||
// text: '四级分数占比',
|
|
||||||
// left: 'left',
|
|
||||||
// top: '0%',
|
|
||||||
// textStyle: {
|
|
||||||
// fontSize: 16,
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// legend: {
|
|
||||||
// top: 'center',
|
|
||||||
// right: '0%',
|
|
||||||
// orient: 'vertical',
|
|
||||||
// },
|
|
||||||
// color: ['#b3cde0', '#6497b1', '#005b96', '#03396c', '#e5e5e5'],
|
|
||||||
|
|
||||||
// series: [
|
|
||||||
// //外圈饼图
|
|
||||||
// {
|
|
||||||
// name: '四级通过率',
|
|
||||||
// type: 'pie',
|
|
||||||
// center: ['30%', '50%'],
|
|
||||||
// radius: ['35%', '70%'],
|
|
||||||
// itemStyle: {
|
|
||||||
// borderRadius: 10,
|
|
||||||
// borderColor: '#fff',
|
|
||||||
// borderWidth: 2,
|
|
||||||
// },
|
|
||||||
// label: {
|
|
||||||
// show: true,
|
|
||||||
// fontSize: 14,
|
|
||||||
// overflow: 'truncate',
|
|
||||||
// minMargin: -1,
|
|
||||||
// },
|
|
||||||
// emphasis: {
|
|
||||||
// itemStyle: {
|
|
||||||
// shadowBlur: 10,
|
|
||||||
// shadowOffsetX: 0,
|
|
||||||
// shadowColor: 'rgba(0, 0, 0, 0.5)',
|
|
||||||
// },
|
|
||||||
// label: {
|
|
||||||
// show: true,
|
|
||||||
// fontSize: 15,
|
|
||||||
// fontWeight: 'bold',
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// data: piedata,
|
|
||||||
// },
|
|
||||||
// ],
|
|
||||||
//};
|
|
||||||
let option = {
|
let option = {
|
||||||
grid: {
|
grid: {
|
||||||
left: '10%', // 增加左侧边距
|
left: '10%', // 增加左侧边距
|
||||||
|
@ -456,66 +412,6 @@
|
||||||
let xData = piedata.map((item) => item.name);
|
let xData = piedata.map((item) => item.name);
|
||||||
let data = piedata.map((item) => item.value);
|
let data = piedata.map((item) => item.value);
|
||||||
let myChart = echarts.init(document.getElementById('pieChart'));
|
let myChart = echarts.init(document.getElementById('pieChart'));
|
||||||
//let option = {
|
|
||||||
// tooltip: {
|
|
||||||
// trigger: 'item',
|
|
||||||
// confine: false,
|
|
||||||
// avoidLabelOverlap: true,
|
|
||||||
// //字体大小
|
|
||||||
// itemStyle: {
|
|
||||||
// fontSize: 100,
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
|
|
||||||
// title: {
|
|
||||||
// text: '四级分数分析',
|
|
||||||
// left: 'left',
|
|
||||||
// top: '0%',
|
|
||||||
// textStyle: {
|
|
||||||
// fontSize: 16,
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// legend: {
|
|
||||||
// top: 'center',
|
|
||||||
// right: '0%',
|
|
||||||
// orient: 'vertical',
|
|
||||||
// },
|
|
||||||
// color: ['#b3cde0', '#6497b1', '#005b96', '#03396c', '#e5e5e5'],
|
|
||||||
|
|
||||||
// series: [
|
|
||||||
// //外圈饼图
|
|
||||||
// {
|
|
||||||
// name: '四级通过率',
|
|
||||||
// type: 'pie',
|
|
||||||
// center: ['30%', '50%'],
|
|
||||||
// radius: ['35%', '70%'],
|
|
||||||
// itemStyle: {
|
|
||||||
// borderRadius: 10,
|
|
||||||
// borderColor: '#fff',
|
|
||||||
// borderWidth: 2,
|
|
||||||
// },
|
|
||||||
// label: {
|
|
||||||
// show: true,
|
|
||||||
// fontSize: 14,
|
|
||||||
// overflow: 'truncate',
|
|
||||||
// minMargin: -1,
|
|
||||||
// },
|
|
||||||
// emphasis: {
|
|
||||||
// itemStyle: {
|
|
||||||
// shadowBlur: 10,
|
|
||||||
// shadowOffsetX: 0,
|
|
||||||
// shadowColor: 'rgba(0, 0, 0, 0.5)',
|
|
||||||
// },
|
|
||||||
// label: {
|
|
||||||
// show: true,
|
|
||||||
// fontSize: 15,
|
|
||||||
// fontWeight: 'bold',
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// data: piedata,
|
|
||||||
// },
|
|
||||||
// ],
|
|
||||||
//};
|
|
||||||
let option = {
|
let option = {
|
||||||
grid: {
|
grid: {
|
||||||
left: '10%', // 增加左侧边距
|
left: '10%', // 增加左侧边距
|
||||||
|
@ -567,21 +463,21 @@
|
||||||
myChart.setOption(option);
|
myChart.setOption(option);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.container {
|
.container {
|
||||||
display: flex;
|
display: flex;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.09);
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.09);
|
||||||
}
|
}
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
font-size: 34px;
|
font-size: 34px;
|
||||||
color: rgb(8, 8, 8);
|
color: rgb(8, 8, 8);
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
Loading…
Reference in New Issue