数据分析优化

This commit is contained in:
Xubx 2025-04-27 15:34:34 +08:00
parent 267a47535d
commit 2ab6b34c2c
1 changed files with 422 additions and 526 deletions

View File

@ -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>