|
@@ -14,9 +14,9 @@
|
|
|
|
|
|
<a-collapse v-model:activeKey="activeKey">
|
|
|
<a-collapse-panel
|
|
|
- v-for="(item, index) in data"
|
|
|
+ v-for="(course, index) in courses"
|
|
|
:key="index"
|
|
|
- :header="item.courseName + '(' + item.courseCode + ')'"
|
|
|
+ :header="course.courseName + '(' + course.courseCode + ')'"
|
|
|
>
|
|
|
<div class="tw-flex tw-justify-between tw-items-center tw-my-4">
|
|
|
<h3 class="section-title">等距({{ scoreGap }}分)分组频数分布</h3>
|
|
@@ -31,64 +31,25 @@
|
|
|
<th>累计频数</th>
|
|
|
<th>累计频数(%)</th>
|
|
|
</tr>
|
|
|
- <tr
|
|
|
- v-for="(item2, index) in Math.round(item.totalScore / scoreGap)"
|
|
|
- :key="index"
|
|
|
- >
|
|
|
- <td>{{ (item2 - 1) * scoreGap }}-</td>
|
|
|
- <td>
|
|
|
- {{
|
|
|
- item.scoreRangeAcc[item2 * scoreGap] -
|
|
|
- item.scoreRangeAcc[(item2 - 1) * scoreGap]
|
|
|
- }}
|
|
|
- </td>
|
|
|
- <td>
|
|
|
- {{
|
|
|
- (item.scoreRangeAcc[item2 * scoreGap] -
|
|
|
- item.scoreRangeAcc[(item2 - 1) * scoreGap]) /
|
|
|
- item.scoreRangeTotal
|
|
|
- }}
|
|
|
- </td>
|
|
|
- <td>{{ item.scoreRangeAcc[item2 * scoreGap] }}</td>
|
|
|
- <td>
|
|
|
- {{
|
|
|
- item.scoreRangeAcc[item2 * scoreGap] / item.scoreRangeTotal
|
|
|
- }}
|
|
|
- </td>
|
|
|
- </tr>
|
|
|
- <tr v-if="item.totalScore % scoreGap">
|
|
|
- <td>
|
|
|
- {{
|
|
|
- item.scoreRangeAcc[item.scoreRangeAcc.length - 1] -
|
|
|
- item.scoreRangeAcc[
|
|
|
- item.scoreRangeAcc.length - 1 - (item.totalScore % scoreGap)
|
|
|
- ]
|
|
|
- }}
|
|
|
- </td>
|
|
|
- <td>
|
|
|
- {{
|
|
|
- (item.scoreRangeAcc[item.scoreRangeAcc.length - 1] -
|
|
|
- item.scoreRangeAcc[
|
|
|
- item.scoreRangeAcc.length -
|
|
|
- 1 -
|
|
|
- (item.totalScore % scoreGap)
|
|
|
- ]) /
|
|
|
- item.scoreRangeTotal
|
|
|
- }}
|
|
|
- </td>
|
|
|
- <td>{{ item.scoreRangeAcc[item.scoreRangeAcc.length - 1] }}</td>
|
|
|
- <td>100%</td>
|
|
|
+ <tr v-for="(seg, index) in course.segements" :key="index">
|
|
|
+ <td>{{ seg[0] }}-</td>
|
|
|
+ <td>{{ seg[1] }}</td>
|
|
|
+ <td>{{ Math.round(seg[2] * 100) }}%</td>
|
|
|
+ <td>{{ seg[3] }}</td>
|
|
|
+ <td>{{ Math.round(seg[4] * 100) }}%</td>
|
|
|
</tr>
|
|
|
</table>
|
|
|
|
|
|
<div class="tw-flex tw-justify-between tw-items-center tw-my-4">
|
|
|
<h3 class="section-title">科目分数线分组的频数分布</h3>
|
|
|
<div class="tw-flex tw-gap-2">
|
|
|
- <a-button @click="openRangeConfigModal(item)">分段设置</a-button>
|
|
|
+ <a-button @click="openRangeConfigModal(course)">
|
|
|
+ 分段设置
|
|
|
+ </a-button>
|
|
|
<a-button @click="openModal2">说明</a-button>
|
|
|
</div>
|
|
|
</div>
|
|
|
- <div v-if="item.rangeConfig">
|
|
|
+ <div v-if="course.rangeConfig">
|
|
|
<table class="custom-table">
|
|
|
<tr>
|
|
|
<th>分数段</th>
|
|
@@ -97,52 +58,12 @@
|
|
|
<th>累计频数</th>
|
|
|
<th>累计频数(%)</th>
|
|
|
</tr>
|
|
|
- <tr v-for="(item2, index) in item.rangeConfig" :key="index">
|
|
|
- <td>
|
|
|
- {{ scoreTitle(item.rangeConfig[index]) }}
|
|
|
- </td>
|
|
|
- <td>
|
|
|
- {{
|
|
|
- (item.rangeConfig[index + 1]
|
|
|
- ? item.scoreRangeAcc[
|
|
|
- item.rangeConfig[index + 1].baseScore +
|
|
|
- item.rangeConfig[index + 1].adjustScore
|
|
|
- ]
|
|
|
- : 0) -
|
|
|
- item.scoreRangeAcc[item2.baseScore + item2.adjustScore] ||
|
|
|
- 0
|
|
|
- }}
|
|
|
- </td>
|
|
|
- <td>
|
|
|
- {{
|
|
|
- ((item.rangeConfig[index + 1]
|
|
|
- ? item.scoreRangeAcc[
|
|
|
- item.rangeConfig[index + 1].baseScore +
|
|
|
- item.rangeConfig[index + 1].adjustScore
|
|
|
- ]
|
|
|
- : 0) -
|
|
|
- item.scoreRangeAcc[item2.baseScore + item2.adjustScore] ||
|
|
|
- 0) / item.scoreRangeTotal
|
|
|
- }}
|
|
|
- </td>
|
|
|
- <td>
|
|
|
- {{
|
|
|
- item2.baseScore + item2.adjustScore >=
|
|
|
- item.scoreRangeAcc.length
|
|
|
- ? item.scoreRangeAcc[item.scoreRangeAcc.length - 1]
|
|
|
- : item.scoreRangeAcc[item2.baseScore + item2.adjustScore]
|
|
|
- }}
|
|
|
- </td>
|
|
|
- <td>
|
|
|
- {{
|
|
|
- item2.baseScore + item2.adjustScore >=
|
|
|
- item.scoreRangeAcc.length
|
|
|
- ? 1
|
|
|
- : item.scoreRangeAcc[
|
|
|
- item2.baseScore + item2.adjustScore
|
|
|
- ] / item.scoreRangeTotal
|
|
|
- }}
|
|
|
- </td>
|
|
|
+ <tr v-for="(seg, index) in course.rangeSegements" :key="index">
|
|
|
+ <td>{{ seg[0] }}-</td>
|
|
|
+ <td>{{ seg[1] }}</td>
|
|
|
+ <td>{{ Math.round(seg[2] * 100) }}%</td>
|
|
|
+ <td>{{ seg[3] }}</td>
|
|
|
+ <td>{{ Math.round(seg[4] * 100) }}%</td>
|
|
|
</tr>
|
|
|
</table>
|
|
|
</div>
|
|
@@ -162,7 +83,7 @@
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
import { useMainStore } from "@/store";
|
|
|
-import { onMounted } from "vue-demi";
|
|
|
+import { onMounted, watch } from "vue-demi";
|
|
|
import { useRoute } from "vue-router";
|
|
|
import {
|
|
|
getSasCourseList,
|
|
@@ -181,7 +102,7 @@ let courseId = $ref(undefined as undefined | number);
|
|
|
const route = useRoute();
|
|
|
const projectId = +route.params.projectId;
|
|
|
|
|
|
-let data = $ref([]);
|
|
|
+let courses = $ref([]);
|
|
|
async function fetchData() {
|
|
|
const res = await getSasCourseList({
|
|
|
projectId,
|
|
@@ -212,7 +133,7 @@ async function fetchData() {
|
|
|
return v;
|
|
|
});
|
|
|
console.log(res.data);
|
|
|
- data = res.data;
|
|
|
+ courses = res.data;
|
|
|
}
|
|
|
|
|
|
onMounted(async () => {
|
|
@@ -222,6 +143,77 @@ onMounted(async () => {
|
|
|
|
|
|
let scoreGap = $ref(10);
|
|
|
|
|
|
+watch(
|
|
|
+ () => [scoreGap, courses],
|
|
|
+ () => {
|
|
|
+ for (const course of courses) {
|
|
|
+ course.segements = [];
|
|
|
+ const validSeg = Math.round(course.totalScore / scoreGap);
|
|
|
+ for (let score = 0; score < validSeg; score++) {
|
|
|
+ const row = [];
|
|
|
+ row[0] = score * scoreGap;
|
|
|
+ let nextScore = score + 1 > validSeg ? course.totalScore : score + 1;
|
|
|
+ // row[1] =
|
|
|
+ // course.scoreRangeAcc[nextScore * scoreGap - 1] -
|
|
|
+ // course.scoreRangeAcc[score * scoreGap];
|
|
|
+ row[1] = course.scoreRange
|
|
|
+ .slice(row[0], nextScore * scoreGap)
|
|
|
+ .reduce((p, c) => p + c, 0);
|
|
|
+ row[2] = row[1] / course.scoreRangeAcc[course.totalScore];
|
|
|
+ row[3] = course.scoreRangeAcc[nextScore * scoreGap - 1];
|
|
|
+ row[4] = row[3] / course.scoreRangeAcc[course.totalScore];
|
|
|
+ course.segements.push(row);
|
|
|
+ }
|
|
|
+ if (validSeg * scoreGap === course.totalScore) {
|
|
|
+ course.segements.push([
|
|
|
+ course.totalScore,
|
|
|
+ course.scoreRange[course.totalScore],
|
|
|
+ course.scoreRange[course.totalScore] /
|
|
|
+ course.scoreRangeAcc[course.totalScore],
|
|
|
+ course.scoreRangeAcc[course.totalScore],
|
|
|
+ 1,
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+
|
|
|
+ course.rangeSegements = [];
|
|
|
+ for (let i = 0; i < course.rangeConfig.length; i++) {
|
|
|
+ const range = course.rangeConfig[i];
|
|
|
+ const nextRange =
|
|
|
+ i === course.rangeConfig.length - 1
|
|
|
+ ? { baseScore: course.totalScore, adjustScore: 0 }
|
|
|
+ : course.rangeConfig[i + 1];
|
|
|
+ const row = [];
|
|
|
+ row[0] = scoreTitle(range);
|
|
|
+ row[1] =
|
|
|
+ course.scoreRange
|
|
|
+ .slice(
|
|
|
+ range.baseScore + range.adjustScore,
|
|
|
+ nextRange.baseScore + nextRange.adjustScore
|
|
|
+ )
|
|
|
+ .reduce((p, c) => p + c, 0) || 0;
|
|
|
+ row[2] = row[1] / course.scoreRangeTotal;
|
|
|
+ row[3] =
|
|
|
+ course.scoreRangeAcc[
|
|
|
+ nextRange.baseScore + nextRange.adjustScore - 1
|
|
|
+ ] || 0;
|
|
|
+ if (
|
|
|
+ nextRange.baseScore + nextRange.adjustScore >=
|
|
|
+ course.scoreRangeAcc.length
|
|
|
+ ) {
|
|
|
+ row[3] = course.scoreRangeAcc[course.scoreRangeAcc.length - 1];
|
|
|
+ }
|
|
|
+ row[4] = row[3] / course.scoreRangeTotal;
|
|
|
+
|
|
|
+ course.rangeSegements.push(row);
|
|
|
+ }
|
|
|
+ // console.log(course);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ immediate: true,
|
|
|
+ }
|
|
|
+);
|
|
|
+
|
|
|
// let scores = [];
|
|
|
// const scoreComputed = computed(() => {
|
|
|
// const s = {};
|