调整成绩分析
This commit is contained in:
parent
63eca2a0ea
commit
67ab505da5
@ -37,26 +37,13 @@
|
||||
<CjBjTjGl :tjgl-data="tjglData" />
|
||||
|
||||
<!-- 6. 本班与年级平均分对比分析图表 -->
|
||||
<CjBjNjPjf
|
||||
:km-lb="
|
||||
ksccKmLb.map((km) => ({
|
||||
id: km.id,
|
||||
name: km.kmmc,
|
||||
kmmc: km.kmmc,
|
||||
}))
|
||||
"
|
||||
v-model:selected-km-id="xzkmId"
|
||||
:bj-pj-list="bjPjList"
|
||||
:bj-pjf="tjglData.bjpjf"
|
||||
:nj-pjf="tjglData.njpjzf"
|
||||
@change="onKmChange"
|
||||
/>
|
||||
<CjBjNjPjf v-model:selected-km-id="xzkmId" :bj-pj-list="bjPjList" />
|
||||
|
||||
<!-- 7. 总分分数段图表 -->
|
||||
<CjZfFs :fs-duan-lb="fsDuanLb" />
|
||||
<CjZfFs :dj-rs-list="djRsList" />
|
||||
|
||||
<!-- 8. 总分等级段图表 -->
|
||||
<CjZfDj :dj-duan-lb="djDuanLb" />
|
||||
<CjZfDj :dj-rs-list="djRsList" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@ -116,22 +103,15 @@ interface BjPjInfo {
|
||||
njmc: string;
|
||||
fs: number;
|
||||
}
|
||||
interface DjRsInfo {
|
||||
dj: string;
|
||||
rs: number;
|
||||
zgf: string;
|
||||
zdf: string;
|
||||
}
|
||||
|
||||
// --- Static Mock Data ---
|
||||
const staticFsDuanLb: FsDuan[] = [
|
||||
{ name: "240-269", value: 5, color: "#1890ff" },
|
||||
{ name: "210-239", value: 12, color: "#2fc25b" },
|
||||
{ name: "180-210", value: 18, color: "#facc14" },
|
||||
{ name: "180以下", value: 10, color: "#f04864" },
|
||||
];
|
||||
|
||||
const staticDjDuanLb: DjDuan[] = [
|
||||
{ name: "A", value: 5, color: "#1890ff" },
|
||||
{ name: "B", value: 15, color: "#2fc25b" },
|
||||
{ name: "C", value: 18, color: "#facc14" },
|
||||
{ name: "D", value: 10, color: "#f04864" },
|
||||
{ name: "E", value: 2, color: "#999999" },
|
||||
];
|
||||
// 这些静态数据现在不再需要,因为组件直接使用 djRsList
|
||||
|
||||
// --- State ---
|
||||
const xzbjId = ref<string | number | null>(null);
|
||||
@ -150,9 +130,8 @@ const tjglData = ref<TjglData>({
|
||||
jgl: 0,
|
||||
jgrs: 0,
|
||||
});
|
||||
const fsDuanLb = ref<FsDuan[]>([...staticFsDuanLb]);
|
||||
const djDuanLb = ref<DjDuan[]>([...staticDjDuanLb]);
|
||||
const bjPjList = ref<BjPjInfo[]>([]);
|
||||
const djRsList = ref<DjRsInfo[]>([]);
|
||||
|
||||
// --- API Functions ---
|
||||
const getKsccKmLb = async (ksccId: string | number) => {
|
||||
@ -197,6 +176,7 @@ const getBjKscjKmData = async (
|
||||
score: cj.ksfs || 0,
|
||||
bjpm: cj.bjpm || 0, // 使用后端返回的班级排名
|
||||
}));
|
||||
console.log("学生成绩列表:", xsCjLb.value);
|
||||
|
||||
// 处理统计数据
|
||||
tjglData.value.bjrs = res.result.bjRs || 0;
|
||||
@ -211,7 +191,12 @@ const getBjKscjKmData = async (
|
||||
|
||||
// 处理班级平均分列表数据,传递给CjBjNjPjf组件
|
||||
bjPjList.value = res.result.bjPjList || [];
|
||||
|
||||
// 处理等级段数据列表,传递给CjZfFs和CjZfDj组件
|
||||
djRsList.value = res.result.djRsList || [];
|
||||
|
||||
console.log("获取班级科目成绩数据成功:", res.result);
|
||||
console.log("等级人数列表:", djRsList.value);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("获取班级科目成绩数据失败:", error);
|
||||
@ -316,4 +301,24 @@ onMounted(async () => {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.debug-info {
|
||||
background-color: #f0f0f0;
|
||||
padding: 20rpx;
|
||||
margin-top: 20rpx;
|
||||
border-radius: 10rpx;
|
||||
|
||||
.debug-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
margin-bottom: 10rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.debug-item {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
margin-bottom: 5rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -13,18 +13,26 @@
|
||||
<view class="th">班级排名</view>
|
||||
</view>
|
||||
<view class="bg-body">
|
||||
<view class="bg-row" v-for="xs in xsCjLb" :key="xs.id">
|
||||
<view class="bg-row" v-for="xs in displayList" :key="xs.id">
|
||||
<view class="td">{{ xs.name }}</view>
|
||||
<view class="td">{{ xs.score }}</view>
|
||||
<view class="td">{{ xs.bjpm }}</view>
|
||||
</view>
|
||||
<view v-if="!xsCjLb.length" class="bg-empty"> 暂无数据 </view>
|
||||
</view>
|
||||
<view
|
||||
v-if="xsCjLb.length > 5"
|
||||
class="expand-btn-wrap"
|
||||
@click="toggleExpand"
|
||||
>
|
||||
{{ expanded ? "收拢" : "展开全部" }}
|
||||
</view>
|
||||
</view>
|
||||
</uni-section>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, ref } from "vue";
|
||||
// --- Interfaces ---
|
||||
interface XsCj {
|
||||
id: string | number;
|
||||
@ -47,6 +55,22 @@ const props = withDefaults(defineProps<Props>(), {
|
||||
{ id: "st-5", name: "孙七", score: 85, bjpm: 8 },
|
||||
],
|
||||
});
|
||||
|
||||
// 展开/收拢状态
|
||||
const expanded = ref(false);
|
||||
|
||||
// 计算显示的学生列表
|
||||
const displayList = computed(() => {
|
||||
if (expanded.value) {
|
||||
return props.xsCjLb;
|
||||
}
|
||||
return props.xsCjLb.slice(0, 5);
|
||||
});
|
||||
|
||||
// 切换展开/收拢
|
||||
function toggleExpand() {
|
||||
expanded.value = !expanded.value;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@ -100,5 +124,15 @@ const props = withDefaults(defineProps<Props>(), {
|
||||
padding: 40rpx 0;
|
||||
}
|
||||
}
|
||||
|
||||
.expand-btn-wrap {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 16rpx 10rpx;
|
||||
text-align: center;
|
||||
background: #fff;
|
||||
color: #1890ff;
|
||||
border-top: 1rpx solid #f0f0f0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -12,8 +12,9 @@
|
||||
id="GradeAnalysisAreaChart"
|
||||
class="charts"
|
||||
/>
|
||||
<view v-if="isLoading" class="tb-placeholder">
|
||||
图表加载中或无数据...
|
||||
<view v-if="isLoading" class="tb-placeholder"> 图表加载中... </view>
|
||||
<view v-else-if="!hasValidData" class="tb-placeholder">
|
||||
暂无等级段数据
|
||||
</view>
|
||||
</view>
|
||||
</uni-section>
|
||||
@ -21,7 +22,7 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import uCharts from "@/components/charts/u-charts.js";
|
||||
import { nextTick, onMounted, ref } from "vue";
|
||||
import { computed, nextTick, onMounted, ref, watch } from "vue";
|
||||
import { areaOption } from "./cj.data";
|
||||
|
||||
// --- Interfaces ---
|
||||
@ -31,26 +32,72 @@ interface DjDuan {
|
||||
color: string;
|
||||
}
|
||||
|
||||
interface DjRsInfo {
|
||||
dj: string;
|
||||
rs: number;
|
||||
zgf: string;
|
||||
zdf: string;
|
||||
}
|
||||
|
||||
// --- Props ---
|
||||
interface Props {
|
||||
djDuanLb?: DjDuan[];
|
||||
djRsList?: DjRsInfo[];
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
djDuanLb: () => [
|
||||
{ name: "A", value: 5, color: "#1890ff" },
|
||||
{ name: "B", value: 15, color: "#2fc25b" },
|
||||
{ name: "C", value: 18, color: "#facc14" },
|
||||
{ name: "D", value: 10, color: "#f04864" },
|
||||
{ name: "E", value: 2, color: "#999999" },
|
||||
],
|
||||
djRsList: () => [],
|
||||
});
|
||||
|
||||
// --- State ---
|
||||
const isLoading = ref(false);
|
||||
|
||||
// --- Computed ---
|
||||
const hasValidData = computed(() => {
|
||||
return (
|
||||
props.djRsList &&
|
||||
props.djRsList.length > 0 &&
|
||||
props.djRsList.some((item) => item.rs > 0)
|
||||
);
|
||||
});
|
||||
|
||||
const processedData = computed(() => {
|
||||
if (!props.djRsList || props.djRsList.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// 定义等级颜色映射
|
||||
const djColorMap: { [key: string]: string } = {
|
||||
A: "#1890ff",
|
||||
B: "#2fc25b",
|
||||
C: "#facc14",
|
||||
D: "#f04864",
|
||||
E: "#999999",
|
||||
};
|
||||
|
||||
// 过滤掉人数为0的数据,并按等级排序
|
||||
return props.djRsList
|
||||
.filter((item) => item.rs > 0)
|
||||
.map((item) => ({
|
||||
name: item.dj, // 使用 dj 作为等级名称
|
||||
value: item.rs,
|
||||
color: djColorMap[item.dj] || "#666666", // 根据等级分配颜色
|
||||
}))
|
||||
.sort((a, b) => {
|
||||
// 按等级排序(A > B > C > D > E)
|
||||
const levelOrder = { A: 5, B: 4, C: 3, D: 2, E: 1 };
|
||||
const aLevel = levelOrder[a.name as keyof typeof levelOrder] || 0;
|
||||
const bLevel = levelOrder[b.name as keyof typeof levelOrder] || 0;
|
||||
return bLevel - aLevel; // 降序排列
|
||||
});
|
||||
});
|
||||
|
||||
// --- 图表绘制逻辑 ---
|
||||
const drawAreaChart = () => {
|
||||
if (!hasValidData.value) {
|
||||
console.log("没有有效的等级段数据");
|
||||
return;
|
||||
}
|
||||
|
||||
isLoading.value = true;
|
||||
|
||||
setTimeout(() => {
|
||||
@ -73,11 +120,11 @@ const drawAreaChart = () => {
|
||||
const ctx = uni.createCanvasContext("GradeAnalysisAreaChart");
|
||||
|
||||
const areaData = {
|
||||
categories: props.djDuanLb.map((item) => item.name),
|
||||
categories: processedData.value.map((item) => item.name),
|
||||
series: [
|
||||
{
|
||||
name: "人数",
|
||||
data: props.djDuanLb.map((item) => item.value),
|
||||
data: processedData.value.map((item) => item.value),
|
||||
color: "#1890ff",
|
||||
},
|
||||
],
|
||||
@ -120,6 +167,7 @@ const drawAreaChart = () => {
|
||||
}
|
||||
|
||||
console.log("图表数据:", areaData);
|
||||
console.log("处理后的等级段数据:", processedData.value);
|
||||
|
||||
try {
|
||||
new uCharts(newOption);
|
||||
@ -141,9 +189,23 @@ const drawAreaChart = () => {
|
||||
}, 500);
|
||||
};
|
||||
|
||||
// --- Watchers ---
|
||||
watch(
|
||||
() => props.djRsList,
|
||||
() => {
|
||||
console.log("等级段数据变化:", props.djRsList);
|
||||
if (hasValidData.value) {
|
||||
drawAreaChart();
|
||||
}
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
|
||||
// --- Lifecycle ---
|
||||
onMounted(() => {
|
||||
drawAreaChart();
|
||||
if (hasValidData.value) {
|
||||
drawAreaChart();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@ -12,8 +12,9 @@
|
||||
id="GradeAnalysisDonutChart"
|
||||
class="charts"
|
||||
/>
|
||||
<view v-if="isLoading" class="tb-placeholder">
|
||||
图表加载中或无数据...
|
||||
<view v-if="isLoading" class="tb-placeholder"> 图表加载中... </view>
|
||||
<view v-else-if="!hasValidData" class="tb-placeholder">
|
||||
暂无分数段数据
|
||||
</view>
|
||||
</view>
|
||||
</uni-section>
|
||||
@ -21,7 +22,7 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import uCharts from "@/components/charts/u-charts.js";
|
||||
import { nextTick, onMounted, ref } from "vue";
|
||||
import { computed, nextTick, onMounted, ref, watch } from "vue";
|
||||
import { ringOption } from "./cj.data";
|
||||
|
||||
// --- Interfaces ---
|
||||
@ -31,25 +32,71 @@ interface FsDuan {
|
||||
color: string;
|
||||
}
|
||||
|
||||
interface DjRsInfo {
|
||||
dj: string;
|
||||
rs: number;
|
||||
zgf: string;
|
||||
zdf: string;
|
||||
}
|
||||
|
||||
// --- Props ---
|
||||
interface Props {
|
||||
fsDuanLb?: FsDuan[];
|
||||
djRsList?: DjRsInfo[];
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
fsDuanLb: () => [
|
||||
{ name: "240-269", value: 5, color: "#1890ff" },
|
||||
{ name: "210-239", value: 12, color: "#2fc25b" },
|
||||
{ name: "180-210", value: 18, color: "#facc14" },
|
||||
{ name: "180以下", value: 10, color: "#f04864" },
|
||||
],
|
||||
djRsList: () => [],
|
||||
});
|
||||
|
||||
// --- State ---
|
||||
const isLoading = ref(false);
|
||||
|
||||
// --- Computed ---
|
||||
const hasValidData = computed(() => {
|
||||
return (
|
||||
props.djRsList &&
|
||||
props.djRsList.length > 0 &&
|
||||
props.djRsList.some((item) => item.rs > 0)
|
||||
);
|
||||
});
|
||||
|
||||
const processedData = computed(() => {
|
||||
if (!props.djRsList || props.djRsList.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// 定义等级颜色映射
|
||||
const djColorMap: { [key: string]: string } = {
|
||||
A: "#1890ff",
|
||||
B: "#2fc25b",
|
||||
C: "#facc14",
|
||||
D: "#f04864",
|
||||
E: "#999999",
|
||||
};
|
||||
|
||||
// 过滤掉人数为0的数据,并按分数段排序
|
||||
return props.djRsList
|
||||
.filter((item) => item.rs > 0)
|
||||
.map((item) => ({
|
||||
name: `${item.zdf}-${item.zgf}`, // 使用 zdf-zgf 作为分数段名称
|
||||
value: item.rs,
|
||||
color: djColorMap[item.dj] || "#666666", // 根据等级分配颜色
|
||||
}))
|
||||
.sort((a, b) => {
|
||||
// 尝试按分数段排序(假设格式为 "数字-数字")
|
||||
const aNum = parseFloat(a.name.split("-")[0] || "0");
|
||||
const bNum = parseFloat(b.name.split("-")[0] || "0");
|
||||
return bNum - aNum; // 降序排列
|
||||
});
|
||||
});
|
||||
|
||||
// --- 图表绘制逻辑 ---
|
||||
const drawDonutChart = () => {
|
||||
if (!hasValidData.value) {
|
||||
console.log("没有有效的分数段数据");
|
||||
return;
|
||||
}
|
||||
|
||||
isLoading.value = true;
|
||||
|
||||
setTimeout(() => {
|
||||
@ -75,7 +122,7 @@ const drawDonutChart = () => {
|
||||
series: [
|
||||
{
|
||||
name: "总分分数段",
|
||||
data: props.fsDuanLb,
|
||||
data: processedData.value,
|
||||
},
|
||||
],
|
||||
};
|
||||
@ -110,6 +157,7 @@ const drawDonutChart = () => {
|
||||
}
|
||||
|
||||
console.log("图表数据:", donutData);
|
||||
console.log("处理后的分数段数据:", processedData.value);
|
||||
|
||||
try {
|
||||
new uCharts(newOption);
|
||||
@ -131,9 +179,23 @@ const drawDonutChart = () => {
|
||||
}, 500);
|
||||
};
|
||||
|
||||
// --- Watchers ---
|
||||
watch(
|
||||
() => props.djRsList,
|
||||
() => {
|
||||
console.log("分数段数据变化:", props.djRsList);
|
||||
if (hasValidData.value) {
|
||||
drawDonutChart();
|
||||
}
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
|
||||
// --- Lifecycle ---
|
||||
onMounted(() => {
|
||||
drawDonutChart();
|
||||
if (hasValidData.value) {
|
||||
drawDonutChart();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user