diff --git a/.env b/.env
index faf5ccf..5910943 100644
--- a/.env
+++ b/.env
@@ -1,5 +1,5 @@
#VITE_HOST = http://192.168.0.114:9053
-VITE_HOST = http://43.136.52.196:9053
-#VITE_HOST= https://ai.xuexiaole.com
+#VITE_HOST = http://43.136.52.196:9053
+VITE_HOST= https://ai.xuexiaole.com
VITE_OSS_HOST = https://xxl-1313840333.cos.ap-guangzhou.myqcloud.com
VITE_WS_URL = wss://test.qiaoying.vip/wss/websocket
\ No newline at end of file
diff --git a/src/pages/doWork/components/Question.vue b/src/pages/doWork/components/Question.vue
index a188a62..fdec043 100644
--- a/src/pages/doWork/components/Question.vue
+++ b/src/pages/doWork/components/Question.vue
@@ -29,12 +29,47 @@
mode="aspectFit"
/>
-
-
+
+
+
+
+
+
+
+ {{ sIdx + 1 }}.
+
+
+
+
+
+
+ {{ opt.label }}.
+
+
+
+
+
+
+
+
+
+
+
+ {{ sIdx + 1 }}
+
+
+ {{ opt.label }}.
+
+
+
+
+
+
+
@@ -131,6 +166,32 @@
+
+
+
+
+ 答题卡
+
+
+ {{ sIdx + 1 }}
+
+
+ {{ opt.label }}
+
+
+
+
+
+
@@ -718,14 +779,27 @@ const collectAllRawHtml = (data: any): string[] => {
if (data.children?.length) {
data.children.forEach((c: any) => { if (c.title) htmls.push(c.title); });
}
- // 选项
+ // 选项(支持平铺和嵌套两种结构)
try {
let opts = data.optionsMu ?? data.options;
if (typeof opts === 'string') opts = JSON.parse(opts);
if (Array.isArray(opts)) {
opts.forEach((item: any) => {
- const v = typeof item === 'string' ? item : (item?.value ?? item?.optionValue ?? '');
- if (v) htmls.push(String(v));
+ if (typeof item === 'string') {
+ if (item) htmls.push(item);
+ } else if (item?.stem || item?.options) {
+ // 阅读理解/完形填空:嵌套结构 { stem, options: [...] }
+ if (item.stem) htmls.push(String(item.stem));
+ if (Array.isArray(item.options)) {
+ item.options.forEach((sub: any) => {
+ const sv = typeof sub === 'string' ? sub : (sub?.value ?? sub?.optionValue ?? '');
+ if (sv) htmls.push(String(sv));
+ });
+ }
+ } else {
+ const v = item?.value ?? item?.optionValue ?? '';
+ if (v) htmls.push(String(v));
+ }
});
}
} catch { /* ignore parse error */ }
@@ -835,11 +909,86 @@ const fillBlankNum = computed(() => {
return props.data?.fillBlankNum || 0;
});
+// ========== 阅读理解 / 完形填空检测 ==========
+
+// 解析原始 options 数据(保留嵌套结构,不做展平),与 admin 端 normalizedOptions 对齐
+const rawParsedOptions = computed(() => {
+ const data = props.data;
+ let raw = data?.optionsMu != null ? data.optionsMu
+ : data?.options != null ? data.options : null;
+ if (typeof raw === 'string') {
+ try { raw = JSON.parse(raw); } catch { raw = null; }
+ }
+ if (!Array.isArray(raw)) return [];
+ // 解包多余嵌套 [[...]] → [...]
+ let list = raw;
+ while (Array.isArray(list) && list.length === 1 && Array.isArray(list[0])) {
+ list = list[0];
+ }
+ return list;
+});
+
+// 是否为阅读理解(选项含 stem + options 子结构)
+const isYueDu = computed(() => {
+ const list = rawParsedOptions.value;
+ if (!list.length) return false;
+ return list.some((item: any) => item?.options && item?.stem);
+});
+
+// 是否为完形填空(选项含 options 子结构但无 stem)
+const isWanXing = computed(() => {
+ if (isYueDu.value) return false;
+ const list = rawParsedOptions.value;
+ if (!list.length) return false;
+ return list.some((item: any) => item?.options && !item?.stem);
+});
+
+// 阅读理解 / 完形填空:子题列表(统一格式:{ index, stem, options: [{label, value}] })
+const yueDuList = computed(() => {
+ if (!isYueDu.value && !isWanXing.value) return [];
+ return rawParsedOptions.value.map((item: any, idx: number) => {
+ // 子选项
+ const rawSubOpts = Array.isArray(item.options) ? item.options : [];
+ const subOpts = rawSubOpts.map((opt: any, oIdx: number) => {
+ let v = typeof opt === 'string' ? opt : (opt?.value ?? opt?.optionValue ?? '');
+ v = v != null ? String(v) : '';
+ v = fixMathSymbolsInHtml(v);
+ v = processFormula(v, failedFormulaUrls.value);
+ v = v.replace(/http:\/\//gi, 'https://');
+ return {
+ label: (typeof opt === 'string') ? String.fromCharCode(65 + oIdx) : (opt?.label || opt?.optionKey || String.fromCharCode(65 + oIdx)),
+ value: v,
+ };
+ });
+ // 子题题干
+ let stem = '';
+ if (item.stem) {
+ stem = String(item.stem);
+ stem = fixMathSymbolsInHtml(stem);
+ stem = processFormula(stem, failedFormulaUrls.value);
+ stem = stem.replace(/http:\/\//gi, 'https://');
+ }
+ // 判断选项是否适合水平排列(所有选项文本长度 < 10 个字符)
+ let horizontal = false;
+ if (subOpts.length > 0) {
+ const maxLen = Math.max(...subOpts.map((o: any) => String(o.value || '').replace(/<[^>]*>/g, '').length));
+ horizontal = maxLen < 10;
+ }
+ return { index: idx, stem, options: subOpts, horizontal };
+ });
+});
+
// 题目类型
const questionType = computed(() => {
const data = props.data;
if (!data) return 'other';
+ // 阅读理解(优先判断,避免被单选题误匹配)
+ if (isYueDu.value) return 'yuedu';
+
+ // 完形填空
+ if (isWanXing.value) return 'wanxing';
+
// 判断题
if (['判断', '判断题'].includes(data.titleChannelTypeName)) {
return 'judgment';
@@ -941,6 +1090,61 @@ const selectJudgment = (value: string) => {
emit('submit', { submitAnswer: value, toNext: true });
};
+// ========== 阅读理解 / 完形填空答题 ==========
+
+// 将 submitAnswer(逗号分隔字符串)拆为每个子题的答案数组
+const yueDuAnswerList = computed(() => {
+ if (!submitAnswer.value) return [];
+ return submitAnswer.value.split(',');
+});
+
+// 获取某个子题的已选答案
+const getYueDuAnswer = (sIdx: number): string => {
+ return yueDuAnswerList.value[sIdx] || '';
+};
+
+// 选择阅读理解某个子题的答案
+const selectYueDuOption = (sIdx: number, key: string) => {
+ if (props.reportFlag) return;
+ const answers = [...yueDuAnswerList.value];
+ // 确保数组长度覆盖当前子题索引
+ while (answers.length <= sIdx) answers.push('');
+ answers[sIdx] = key;
+ submitAnswer.value = answers.join(',');
+ emit('submit', { submitAnswer: submitAnswer.value });
+};
+
+// 报告模式:解析正确答案为数组
+const correctAnswerList = computed(() => {
+ const raw = props.data?.answer;
+ if (!raw) return [];
+ if (Array.isArray(raw)) return raw.map(String);
+ if (typeof raw === 'string') {
+ // 尝试 JSON 解析 ["A","B"]
+ try {
+ const parsed = JSON.parse(raw);
+ if (Array.isArray(parsed)) return parsed.map(String);
+ } catch { /* not JSON */ }
+ // 逗号分隔 "A,B,C"
+ return raw.split(',').map((s: string) => s.trim());
+ }
+ return [];
+});
+
+// 报告模式:某子题的某选项是否为正确答案
+const showYueDuCorrect = (sIdx: number, key: string): boolean => {
+ if (!props.reportFlag) return false;
+ return correctAnswerList.value[sIdx] === key;
+};
+
+// 报告模式:某子题的某选项是否为错选
+const showYueDuWrong = (sIdx: number, key: string): boolean => {
+ if (!props.reportFlag) return false;
+ const myAnswer = yueDuAnswerList.value[sIdx];
+ const correctAnswer = correctAnswerList.value[sIdx];
+ return myAnswer === key && myAnswer !== correctAnswer;
+};
+
// 填空题
const getInputValue = (idx: number) => {
const answers = submitAnswer.value.split(',');
@@ -1285,6 +1489,179 @@ onUnmounted(() => {
margin-bottom: 16rpx;
}
}
+
+ // 阅读理解:子题题干 + 选项(纵向布局)
+ .left-yuedu {
+ margin-top: 16rpx;
+ padding: 0 10rpx;
+
+ .left-yuedu-item {
+ margin-bottom: 16rpx;
+ padding: 10rpx 12rpx;
+ background: rgba(79, 142, 247, 0.04);
+ border-radius: 10rpx;
+ border-left: 4rpx solid #8fb5ff;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+ }
+
+ .left-yuedu-stem {
+ display: flex;
+ align-items: flex-start;
+ margin-bottom: 6rpx;
+
+ .left-yuedu-idx {
+ font-family: $font-special;
+ font-size: 12rpx;
+ font-weight: 700;
+ color: #4F8EF7;
+ margin-right: 4rpx;
+ flex-shrink: 0;
+ line-height: 1.6;
+ }
+
+ .left-yuedu-stem-text {
+ flex: 1;
+ font-size: 12rpx;
+ color: $font-color;
+ line-height: 1.6;
+
+ :deep(image) {
+ max-width: 100%;
+ height: auto;
+ }
+
+ :deep(.formula-text) {
+ font-size: 13rpx;
+ font-family: 'Times New Roman', 'STIXGeneral', Georgia, serif;
+ font-style: italic;
+ color: #1a1a1a;
+ }
+ }
+ }
+
+ .left-yuedu-opts {
+ padding-left: 16rpx;
+ display: flex;
+ flex-wrap: wrap;
+ gap: 2rpx 16rpx;
+
+ // 选项文本较长时纵向排列
+ &.vertical {
+ flex-direction: column;
+ gap: 2rpx;
+
+ .left-yuedu-opt {
+ width: 100%;
+ }
+ }
+
+ .left-yuedu-opt {
+ display: flex;
+ align-items: flex-start;
+ line-height: 1.6;
+
+ .left-yuedu-opt-label {
+ font-size: 12rpx;
+ color: #8f9df7;
+ font-weight: 600;
+ margin-right: 3rpx;
+ flex-shrink: 0;
+ }
+
+ .left-yuedu-opt-value {
+ font-size: 12rpx;
+ color: $font-color;
+
+ :deep(image) {
+ max-width: 100%;
+ height: auto;
+ }
+
+ :deep(.formula-text) {
+ font-size: 13rpx;
+ font-family: 'Times New Roman', 'STIXGeneral', Georgia, serif;
+ font-style: italic;
+ color: #1a1a1a;
+ }
+ }
+ }
+ }
+ }
+
+ // 完形填空:序号 + 选项(横向紧凑,无题干,与 admin 对齐)
+ .left-wanxing {
+ margin-top: 16rpx;
+ padding: 0 10rpx;
+
+ .left-wanxing-row {
+ display: flex;
+ align-items: flex-start;
+ gap: 8rpx;
+ margin-bottom: 8rpx;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+ }
+
+ .left-wanxing-idx {
+ min-width: 20rpx;
+ height: 20rpx;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 0 4rpx;
+ border-radius: 4rpx;
+ background: #f0f4ff;
+ font-family: $font-special;
+ font-size: 11rpx;
+ font-weight: 700;
+ color: #4F8EF7;
+ flex-shrink: 0;
+ line-height: 20rpx;
+ }
+
+ .left-wanxing-opts {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 2rpx 14rpx;
+ flex: 1;
+ }
+
+ .left-wanxing-opt {
+ display: flex;
+ align-items: flex-start;
+ line-height: 1.6;
+
+ .left-wanxing-opt-label {
+ font-size: 12rpx;
+ color: #8f9df7;
+ font-weight: 600;
+ margin-right: 2rpx;
+ flex-shrink: 0;
+ }
+
+ .left-wanxing-opt-value {
+ font-size: 12rpx;
+ color: $font-color;
+
+ :deep(image) {
+ max-width: 100%;
+ height: auto;
+ }
+
+ :deep(.formula-text) {
+ font-size: 13rpx;
+ font-family: 'Times New Roman', 'STIXGeneral', Georgia, serif;
+ font-style: italic;
+ color: #1a1a1a;
+ }
+ }
+ }
+ }
}
.right {
@@ -1452,6 +1829,107 @@ onUnmounted(() => {
}
}
+// 阅读理解 / 完形填空:右侧答题卡
+.yuedu-answer-card {
+ .yuedu-card-title {
+ text-align: center;
+ margin-bottom: 12rpx;
+ padding-bottom: 8rpx;
+ border-bottom: 2rpx solid #e8ecf4;
+
+ text {
+ font-family: $font-special;
+ font-size: 13rpx;
+ font-weight: 700;
+ color: #8f9df7;
+ letter-spacing: 2rpx;
+ }
+ }
+
+ .yuedu-card-row {
+ display: flex;
+ align-items: center;
+ margin-bottom: 10rpx;
+ gap: 8rpx;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+ }
+
+ .yuedu-card-num {
+ width: 22rpx;
+ height: 22rpx;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border-radius: 6rpx;
+ background: #f0f4ff;
+ font-family: $font-special;
+ font-size: 11rpx;
+ font-weight: 700;
+ color: #4F8EF7;
+ flex-shrink: 0;
+ }
+
+ .yuedu-card-btns {
+ display: flex;
+ gap: 8rpx;
+ flex: 1;
+ flex-wrap: wrap;
+ }
+
+ .yuedu-card-btn {
+ width: 32rpx;
+ height: 32rpx;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border-radius: 50%;
+ background: #f5f7fa;
+ border: 2rpx solid #e0e4ea;
+ transition: all 0.2s ease;
+ box-shadow: 0 1rpx 4rpx rgba(0, 0, 0, 0.05);
+
+ text {
+ font-family: $font-special;
+ font-size: 13rpx;
+ font-weight: 600;
+ color: #666;
+ }
+
+ &.active {
+ background: linear-gradient(135deg, #7eacfe 0%, #5b8def 100%);
+ border-color: #5b8def;
+ box-shadow: 0 2rpx 8rpx rgba(91, 141, 239, 0.35);
+
+ text {
+ color: #fff;
+ }
+ }
+
+ &.correct {
+ background: linear-gradient(135deg, #6dd5a0 0%, #4cd964 100%);
+ border-color: #4cd964;
+ box-shadow: 0 2rpx 8rpx rgba(76, 217, 100, 0.35);
+
+ text {
+ color: #fff;
+ }
+ }
+
+ &.wrong {
+ background: linear-gradient(135deg, #ff7875 0%, #ff4d4f 100%);
+ border-color: #ff4d4f;
+ box-shadow: 0 2rpx 8rpx rgba(255, 77, 79, 0.35);
+
+ text {
+ color: #fff;
+ }
+ }
+ }
+}
+
.judgment-list {
display: flex;
justify-content: center;