Kaynağa Gözat

rename DESCRIBE

Michael Wang 3 yıl önce
ebeveyn
işleme
d02db5e81e

+ 27 - 17
src/constants/constants.ts

@@ -32,23 +32,33 @@ export const PROJECT_STATUS = [
 ];
 
 export const ORG_GLOSSARY = {
-  DESCRIBE01: "整体分析——试卷特征量数",
-  DESCRIBE02: "整体分析——等距(10分)分组频数分布",
-  DESCRIBE03: "整体分析——科目分数线分组的频数分布",
-  DESCRIBE04: "整体分析——科目成绩占初试总分权重",
-  DESCRIBE05: "试卷分析——试卷题目编排",
-  DESCRIBE06: "试卷分析——试题特征量数",
-  DESCRIBE07: "试卷分析——题型题目难度等级构成分布",
-  DESCRIBE08: "试卷分析——内容题目难度等级构成分布",
-  DESCRIBE09: "试卷分析——能力题目难度等级构成分布(一)",
-  DESCRIBE10: "试卷分析——能力题目难度等级构成分布(二)",
-  DESCRIBE11: "试卷分析——题型题目区分度等级构成分布",
-  DESCRIBE12: "试卷分析——内容题目区分度等级构成分布",
-  DESCRIBE13: "试卷分析——能力题目区分度等级构成分布(一)",
-  DESCRIBE14: "试卷分析——能力题目区分度等级构成分布(二)",
-  DESCRIBE15: "试卷分析——试题难度分组分布(按本科目成绩分组)",
-  DESCRIBE16: "试卷分析——试题难度分组分布(按初试总分分组)",
-  DESCRIBE17: "试卷分析——客观题选项选择比率分布",
+  DESCRIBE010: "整体分析——试卷特征量数",
+  DESCRIBE020: "整体分析——等距(10分)分组频数分布",
+  DESCRIBE030: "整体分析——科目分数线分组的频数分布",
+  DESCRIBE040: "整体分析——科目成绩占初试总分权重",
+  DESCRIBE050: "试卷分析——试卷题目编排",
+  DESCRIBE060: "试卷分析——试题特征量数",
+  DESCRIBE070: "试卷分析——题型题目难度等级构成分布(一)",
+  DESCRIBE080: "试卷分析——题型题目难度等级构成分布(二)",
+  DESCRIBE090: "试卷分析——题型题目难度等级构成分布(三)",
+  DESCRIBE100: "试卷分析——内容题目难度等级构成分布(一)",
+  DESCRIBE110: "试卷分析——内容题目难度等级构成分布(二)",
+  DESCRIBE120: "试卷分析——内容题目难度等级构成分布(三)",
+  DESCRIBE130: "试卷分析——能力题目难度等级构成分布(一)",
+  DESCRIBE140: "试卷分析——能力题目难度等级构成分布(二)",
+  DESCRIBE150: "试卷分析——能力题目难度等级构成分布(三)",
+  DESCRIBE160: "试卷分析——题型题目区分度等级构成分布(一)",
+  DESCRIBE170: "试卷分析——题型题目区分度等级构成分布(二)",
+  DESCRIBE180: "试卷分析——题型题目区分度等级构成分布(三)",
+  DESCRIBE190: "试卷分析——内容题目区分度等级构成分布(一)",
+  DESCRIBE200: "试卷分析——内容题目区分度等级构成分布(二)",
+  DESCRIBE210: "试卷分析——内容题目区分度等级构成分布(三)",
+  DESCRIBE220: "试卷分析——能力题目区分度等级构成分布(一)",
+  DESCRIBE230: "试卷分析——能力题目区分度等级构成分布(二)",
+  DESCRIBE240: "试卷分析——能力题目区分度等级构成分布(三)",
+  DESCRIBE250: "试卷分析——试题难度分组分布(按本科目成绩分组)",
+  DESCRIBE260: "试卷分析——试题难度分组分布(按初试总分分组)",
+  DESCRIBE270: "试卷分析——客观题选项选择比率分布",
 };
 
 export const RANGE_POINT_TYPE = {

+ 1 - 1
src/features/allAnalysis/AllAnalysis2.vue

@@ -175,6 +175,6 @@ function goProjectPapers(id: number) {
 }
 
 function openModal() {
-  EventBus.emit("SHOW_SETTING", "DESCRIBE01");
+  EventBus.emit("SHOW_SETTING", "DESCRIBE010");
 }
 </script>

+ 1 - 1
src/features/allAnalysis/ScoreFirstTryRate.vue

@@ -137,7 +137,7 @@ function scoreTitle(rangeConfig: any) {
 }
 
 function openModal1() {
-  EventBus.emit("SHOW_SETTING", "DESCRIBE04");
+  EventBus.emit("SHOW_SETTING", "DESCRIBE040");
 }
 </script>
 

+ 2 - 2
src/features/allAnalysis/ScoreRate.vue

@@ -254,11 +254,11 @@ function scoreTitle(rangeConfig: any) {
 }
 
 function openModal1() {
-  EventBus.emit("SHOW_SETTING", "DESCRIBE02");
+  EventBus.emit("SHOW_SETTING", "DESCRIBE020");
 }
 
 function openModal2() {
-  EventBus.emit("SHOW_SETTING", "DESCRIBE03");
+  EventBus.emit("SHOW_SETTING", "DESCRIBE030");
 }
 </script>
 

+ 8 - 1
src/features/paperAnalysis/PaperAnalysis.vue

@@ -29,7 +29,7 @@
         <a-radio-button value="1">试卷题目编排</a-radio-button>
         <a-radio-button value="2">试题特征量数</a-radio-button>
         <a-radio-button value="3">题型难度分布</a-radio-button>
-        <a-radio-button value="4">试题难度分组分布</a-radio-button>
+        <a-radio-button value="4">题型区分度分布</a-radio-button>
         <a-radio-button value="5">试题难度分组分布</a-radio-button>
       </a-radio-group>
       <div class="tw-my-4"></div>
@@ -46,6 +46,12 @@
           :questions="paperQuestionGroups"
         />
       </div>
+      <div v-if="activeTab === '4'">
+        <QuestionTypeDiscrimination
+          :project-id="projectId"
+          :questions="paperQuestionGroups"
+        />
+      </div>
       <div v-if="activeTab === '5'">
         <QuestionDifficultyGroup
           :questions="paperQuestions"
@@ -76,6 +82,7 @@ import QuestionBianPai from "./QuestionBianPai.vue";
 import QuestionAttr from "./QuestionAttr.vue";
 import QuestionDifficultyGroup from "./QuestionDifficultyGroup.vue";
 import QuestionTypeDifficulty from "./QuestionTypeDifficulty.vue";
+import QuestionTypeDiscrimination from "./QuestionTypeDiscrimination.vue";
 
 const store = useMainStore();
 store.currentLocation = "项目管理 / 项目列表 / 试卷分析";

+ 1 - 1
src/features/paperAnalysis/QuestionAttr.vue

@@ -89,6 +89,6 @@ const columns = [
 ];
 
 function openModal() {
-  EventBus.emit("SHOW_SETTING", "DESCRIBE06");
+  EventBus.emit("SHOW_SETTING", "DESCRIBE060");
 }
 </script>

+ 1 - 1
src/features/paperAnalysis/QuestionBianPai.vue

@@ -36,6 +36,6 @@ const columns = [
 ];
 
 function openModal() {
-  EventBus.emit("SHOW_SETTING", "DESCRIBE05");
+  EventBus.emit("SHOW_SETTING", "DESCRIBE050");
 }
 </script>

+ 2 - 2
src/features/paperAnalysis/QuestionDifficultyGroup.vue

@@ -83,11 +83,11 @@ const props = defineProps<{
 }>();
 
 function openModal1() {
-  EventBus.emit("SHOW_SETTING", "DESCRIBE15");
+  EventBus.emit("SHOW_SETTING", "DESCRIBE250");
 }
 
 function openModal2() {
-  EventBus.emit("SHOW_SETTING", "DESCRIBE16");
+  EventBus.emit("SHOW_SETTING", "DESCRIBE260");
 }
 
 let rangeConfigRef = $ref(null);

+ 35 - 11
src/features/paperAnalysis/QuestionTypeDifficulty.vue

@@ -6,7 +6,7 @@
       <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="openModal07">说明</a-button>
+          <a-button @click="openModalDESCRIBE070">说明</a-button>
         </div>
       </div>
 
@@ -21,7 +21,7 @@
       <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="openModal07">说明</a-button>
+          <a-button @click="openModalDESCRIBE080">说明</a-button>
         </div>
       </div>
 
@@ -36,7 +36,7 @@
       <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="openModal07">说明</a-button>
+          <a-button @click="openModalDESCRIBE090">说明</a-button>
         </div>
       </div>
 
@@ -51,7 +51,7 @@
       <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="openModal07">说明</a-button>
+          <a-button @click="openModalDESCRIBE100">说明</a-button>
         </div>
       </div>
 
@@ -66,7 +66,7 @@
       <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="openModal07">说明</a-button>
+          <a-button @click="openModalDESCRIBE110">说明</a-button>
         </div>
       </div>
 
@@ -81,7 +81,7 @@
       <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="openModal07">说明</a-button>
+          <a-button @click="openModalDESCRIBE120">说明</a-button>
         </div>
       </div>
 
@@ -96,7 +96,7 @@
       <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="openModal07">说明</a-button>
+          <a-button @click="openModalDESCRIBE130">说明</a-button>
         </div>
       </div>
 
@@ -111,7 +111,7 @@
       <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="openModal07">说明</a-button>
+          <a-button @click="openModalDESCRIBE140">说明</a-button>
         </div>
       </div>
 
@@ -126,7 +126,7 @@
       <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="openModal07">说明</a-button>
+          <a-button @click="openModalDESCRIBE150">说明</a-button>
         </div>
       </div>
 
@@ -168,8 +168,32 @@ import DistriTable from "./DistriTable.vue";
 
 const props = defineProps<{ questions: QuestionGroup[]; projectId: number }>();
 
-function openModal07() {
-  EventBus.emit("SHOW_SETTING", "DESCRIBE07");
+function openModalDESCRIBE070() {
+  EventBus.emit("SHOW_SETTING", "DESCRIBE070");
+}
+function openModalDESCRIBE080() {
+  EventBus.emit("SHOW_SETTING", "DESCRIBE080");
+}
+function openModalDESCRIBE090() {
+  EventBus.emit("SHOW_SETTING", "DESCRIBE090");
+}
+function openModalDESCRIBE100() {
+  EventBus.emit("SHOW_SETTING", "DESCRIBE100");
+}
+function openModalDESCRIBE110() {
+  EventBus.emit("SHOW_SETTING", "DESCRIBE110");
+}
+function openModalDESCRIBE120() {
+  EventBus.emit("SHOW_SETTING", "DESCRIBE120");
+}
+function openModalDESCRIBE130() {
+  EventBus.emit("SHOW_SETTING", "DESCRIBE130");
+}
+function openModalDESCRIBE140() {
+  EventBus.emit("SHOW_SETTING", "DESCRIBE140");
+}
+function openModalDESCRIBE150() {
+  EventBus.emit("SHOW_SETTING", "DESCRIBE150");
 }
 
 /** <handleImport> */

+ 220 - 0
src/features/paperAnalysis/QuestionTypeDiscrimination.vue

@@ -0,0 +1,220 @@
+<template>
+  <div>
+    <a-button @click="importModalVisible = true">题型分布设置</a-button>
+
+    <div v-if="props.questions.some((q) => q.type === 'TYPE1')">
+      <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="openModalDESCRIBE160">说明</a-button>
+        </div>
+      </div>
+
+      <DistriTable
+        :questions="
+          props.questions.filter((q) => q.type === 'TYPE1' || !q.type)
+        "
+      />
+    </div>
+
+    <div v-if="props.questions.some((q) => q.type === 'TYPE2')">
+      <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="openModalDESCRIBE170">说明</a-button>
+        </div>
+      </div>
+
+      <DistriTable
+        :questions="
+          props.questions.filter((q) => q.type === 'TYPE2' || !q.type)
+        "
+      />
+    </div>
+
+    <div v-if="props.questions.some((q) => q.type === 'TYPE3')">
+      <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="openModalDESCRIBE180">说明</a-button>
+        </div>
+      </div>
+
+      <DistriTable
+        :questions="
+          props.questions.filter((q) => q.type === 'TYPE3' || !q.type)
+        "
+      />
+    </div>
+
+    <div v-if="props.questions.some((q) => q.type === 'CONTENT1')">
+      <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="openModalDESCRIBE190">说明</a-button>
+        </div>
+      </div>
+
+      <DistriTable
+        :questions="
+          props.questions.filter((q) => q.type === 'CONTENT1' || !q.type)
+        "
+      />
+    </div>
+
+    <div v-if="props.questions.some((q) => q.type === 'CONTENT2')">
+      <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="openModalDESCRIBE200">说明</a-button>
+        </div>
+      </div>
+
+      <DistriTable
+        :questions="
+          props.questions.filter((q) => q.type === 'CONTENT2' || !q.type)
+        "
+      />
+    </div>
+
+    <div v-if="props.questions.some((q) => q.type === 'CONTENT3')">
+      <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="openModalDESCRIBE210">说明</a-button>
+        </div>
+      </div>
+
+      <DistriTable
+        :questions="
+          props.questions.filter((q) => q.type === 'CONTENT3' || !q.type)
+        "
+      />
+    </div>
+
+    <div v-if="props.questions.some((q) => q.type === 'ABILITY1')">
+      <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="openModalDESCRIBE220">说明</a-button>
+        </div>
+      </div>
+
+      <DistriTable
+        :questions="
+          props.questions.filter((q) => q.type === 'ABILITY1' || !q.type)
+        "
+      />
+    </div>
+
+    <div v-if="props.questions.some((q) => q.type === 'ABILITY2')">
+      <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="openModalDESCRIBE230">说明</a-button>
+        </div>
+      </div>
+
+      <DistriTable
+        :questions="
+          props.questions.filter((q) => q.type === 'ABILITY2' || !q.type)
+        "
+      />
+    </div>
+
+    <div v-if="props.questions.some((q) => q.type === 'ABILITY3')">
+      <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="openModalDESCRIBE240">说明</a-button>
+        </div>
+      </div>
+
+      <DistriTable
+        :questions="
+          props.questions.filter((q) => q.type === 'ABILITY3' || !q.type)
+        "
+      />
+    </div>
+
+    <a-modal
+      v-model:visible="importModalVisible"
+      title="题型设置导入"
+      @ok="handleImport"
+      ok-text="确定"
+      cancel-text="取消"
+    >
+      <a-form>
+        <a-form-item label="文件地址">
+          <input id="file-input" :multiple="false" type="file" />
+        </a-form-item>
+        <a-form-item label="下载模板">
+          <a-button class="download-tpl-btn" @click="downloadTpl">
+            下载模板
+          </a-button>
+        </a-form-item>
+      </a-form>
+    </a-modal>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { importQuestionGroups } from "@/api/paperAnalysisPage";
+import EventBus from "@/plugins/eventBus";
+import { QuestionGroup } from "@/types";
+import { downloadFileURL } from "@/utils/utils";
+import { message } from "ant-design-vue";
+import DistriTable from "./DistriTable.vue";
+
+const props = defineProps<{ questions: QuestionGroup[]; projectId: number }>();
+
+function openModalDESCRIBE160() {
+  EventBus.emit("SHOW_SETTING", "DESCRIBE160");
+}
+function openModalDESCRIBE170() {
+  EventBus.emit("SHOW_SETTING", "DESCRIBE170");
+}
+function openModalDESCRIBE180() {
+  EventBus.emit("SHOW_SETTING", "DESCRIBE180");
+}
+function openModalDESCRIBE190() {
+  EventBus.emit("SHOW_SETTING", "DESCRIBE190");
+}
+function openModalDESCRIBE200() {
+  EventBus.emit("SHOW_SETTING", "DESCRIBE200");
+}
+function openModalDESCRIBE210() {
+  EventBus.emit("SHOW_SETTING", "DESCRIBE210");
+}
+function openModalDESCRIBE220() {
+  EventBus.emit("SHOW_SETTING", "DESCRIBE220");
+}
+function openModalDESCRIBE230() {
+  EventBus.emit("SHOW_SETTING", "DESCRIBE230");
+}
+function openModalDESCRIBE240() {
+  EventBus.emit("SHOW_SETTING", "DESCRIBE240");
+}
+
+/** <handleImport> */
+let importModalVisible = $ref<boolean>(false);
+async function handleImport() {
+  const files = (document.querySelector("#file-input") as HTMLInputElement)
+    .files;
+  const fileToImport = files && files[0];
+  if (!fileToImport) {
+    message.warn({ content: "请选择文件" });
+    return;
+  }
+
+  await importQuestionGroups(props.projectId, fileToImport);
+  message.success({ content: "导入成功" });
+}
+/** </handleImport> */
+
+async function downloadTpl() {
+  downloadFileURL("/api/ess/sasQuestionGroup/template");
+}
+</script>
+
+<style scoped></style>