Commit 929dfd03 authored by 李维's avatar 李维

添加文字输入组题型

parent 1cb77cb0
......@@ -24,6 +24,7 @@ const RIGHT_OR_WRONG = "8";
const CROSSWORD_PUZZLE = "9";
const SORT_WORDS = "10";
const CONNECTION_CHOICE = "11";
const TEXTINPUT_GROUP = "12";
// 评分体系
const RS_15_5L_FAF = "0";
......@@ -561,6 +562,11 @@ export default class SceneComponent extends MyCocosSceneComponent {
validater = this.setConnectionChoice(configItem, isDebug);
this.scoreValidater.push(validater);
break;
// 文字输入区
case TEXTINPUT_GROUP:
validater = this.setTextInputGroup(configItem, isDebug);
this.scoreValidater.push(validater);
break;
}
});
......@@ -1761,7 +1767,6 @@ export default class SceneComponent extends MyCocosSceneComponent {
return validater
}
// 设置文字输入热区
setTextInput(contentData, hotZoneItemData, debugMode=false) {
const resultRect = this.newRectNode(hotZoneItemData, layer_2, debugMode);
......@@ -1875,6 +1880,130 @@ export default class SceneComponent extends MyCocosSceneComponent {
return validater
}
// 设置文字输入组
setTextInputGroup(contentData, debugMode=false) {
const allInputResults = [];
let validater = () => {
const allMatchedIndex = [];
const results = [];
allInputResults.forEach(resultItem => {
let right = false;
let userInputText = resultItem.detail.currentInputText;
contentData.contentList.forEach((option, index) => {
if(!right) {
let configInputText = option.inputText;
if(option.keyWordMatch) {
// 关键词匹配,只有回答文字中包含全部关键词,就算对
right = this.fuzzyMatchingString(userInputText, configInputText, option.isCaseInsensitive);
} else if(option.openAnswer) {
// 开放型回答 只要有内容就算对
right = userInputText != "";
} else {
// 除特殊配置, 默认进行缩写通配符替换
if(!option.notAdaptContraction) {
userInputText = this.adaptContraction(userInputText);
configInputText = this.adaptContraction(configInputText);
}
if(option.isCaseInsensitive) {
// 不区分大小写
right = userInputText.toLowerCase().trim() == configInputText.toLowerCase().trim();
} else {
// 区分大小写 完全相等
right = userInputText.trim() == configInputText.trim();
}
}
// 检查当前匹配成功的答案 是否有其他选项匹配过
if(allMatchedIndex.indexOf(index) != -1) {
right = false;
}
if(right) {
// 正确 返回分数
allMatchedIndex.push(index); // 将匹配成功的序号放进数组
resultItem.detail.correctText = option.inputText;
resultItem.score = option.score && !isNaN(Number(option.score)) ? Number(option.score) : 0;
results.push(resultItem)
}
}
})
if(!right) {
// 如果遍历了所有答案一轮也没有找到符合的正确答案,则为错误
resultItem.allRight = false;
resultItem.detail.right = false;
results.push(resultItem)
}
})
return results
}
contentData.contentList.forEach((option, index) => {
const hotZoneItemData = this.data.hotZoneItemArr[option.selectHotZoneIndex];
const resultRect = this.newRectNode(hotZoneItemData, layer_2, debugMode);
this.newDecorativeFrame(hotZoneItemData, layer_1, "#FFFFFF", "#6dbef6", debugMode);
const rect = this.newRectNode(hotZoneItemData, layer_4, debugMode);
const result = {
detail: {
contentType: TEXTINPUT_GROUP,
configIndex: contentData.index,
contentIndex: -1,
currentInputText: "",
correctText: "",
right: true
},
configIndex: contentData.index,
rect: resultRect,
allRight: true,
score: 0
}
allInputResults.push(result);
rect.on("click", async () => {
if(this.submitted) {
return;
}
this.currentInputTarget = rect;
const optionList = [];
contentData.contentList.forEach(option => {
optionList.push({
label: option.text,
value: option.text
})
});
// 取得上次输入文字 传到键盘中 作为默认显示 - 清空当前文字节点
let lastText = "";
if(rect.cleanLast) {
lastText = rect.cleanLast()
}
let text = await this.asyncShowKeyboardModal(lastText);
const inputLabel = this.newInputTextNode(text, 0);
inputLabel.x = rect.width / 2;
inputLabel.y = rect.height / 2;
result.detail.currentInputText = text;
// 更新清除方法
rect.cleanLast = () => {
inputLabel.destroy();
return text;
}
// 校验必须在上面更新了校验器之后进行 否则本次选择不会生效
// this.checkCanSubmit();
rect.addChild(inputLabel);
})
});
return validater
}
// 设置单词排序题
setSortWords(contentData, hotZoneItemData, debugMode=false) {
// 该题型需要配置一个显示正确错误符号的热区
......
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -63,6 +63,7 @@
<nz-option [nzValue]="SORT_WORDS" nzLabel="单词排序"></nz-option>
<nz-option [nzValue]="PRONUNCIATION_ASSESSMENT" nzLabel="语音评测"></nz-option>
<nz-option [nzValue]="CONNECTION_CHOICE" nzLabel="连线选择题"></nz-option>
<nz-option [nzValue]="TEXTINPUT_GROUP" nzLabel="文字输入组"></nz-option>
<nz-option [nzValue]="IMAGE_SELECT" nzLabel="图片选项" nzDisabled></nz-option>
</nz-select>
<label *ngIf="it.hotZoneType == TEXT_SELECT" nz-checkbox [(ngModel)]="it.useSelectOptionList" (ngModelChange)="handleUserSelectOptionListChange(it)" style="margin-left: 10px;">使用独立选项清单</label>
......@@ -421,6 +422,45 @@
</tbody>
</nz-table>
<!-- 文字输入组 -->
<nz-table *ngIf="it.hotZoneType == TEXTINPUT_GROUP" #contentTable [nzData]="it.contentList" [nzFrontPagination]="false" [nzShowPagination]="false">
<thead>
<tr>
<th nzWidth="100px" nzAlign="center">序号</th>
<th nzWidth="100px" nzAlign="center">分数</th>
<th nzAlign="center">文字</th>
<th nzWidth="100px" >热区索引</th>
<th nzWidth="150px" nzAlign="center">操作</th>
</thead>
<tbody>
<tr *ngFor="let data of contentTable.data; let i = index;">
<td nzWidth="100px" nzAlign="center">{{ i + 1 }}</td>
<td nzWidth="100px">
<input type="text" nz-input [(ngModel)]="data.score" (blur)="save()"/>
</td>
<td nzAlign="center">
<input type="text" nz-input [(ngModel)]="data.inputText" (blur)="save()" style="display: inline-block;">
<div>
<label nz-checkbox [(ngModel)]="data.keyWordMatch" (ngModelChange)="save()" style="margin-left: 10px;">关键词匹配</label>
<label nz-checkbox [(ngModel)]="data.keyWordMatchInOrder" (ngModelChange)="save()" style="margin-left: 10px;">有序关键词</label>
<label nz-checkbox [(ngModel)]="data.isCaseInsensitive" (ngModelChange)="save()" style="margin-left: 10px;">不区分大小写</label>
<label nz-checkbox [(ngModel)]="data.openAnswer" (ngModelChange)="save()" style="margin-left: 10px;">开放性答案</label>
<label nz-checkbox [(ngModel)]="data.capitalizedFirstLetter" (ngModelChange)="save()" style="margin-left: 10px;">首字母大写</label>
<label nz-checkbox [(ngModel)]="data.notAdaptContraction" (ngModelChange)="save()" style="margin-left: 10px;">不进行缩写适配</label>
</div>
</td>
<td nzWidth="100px" >
<nz-select nzShowSearch nzAllowClear [(ngModel)]="data.selectHotZoneIndex" style="width: 180px;" (ngModelChange)="save()">
<nz-option *ngFor="let itOption of item.hotZoneItemArr" [nzValue]="itOption.index" [nzLabel]="itOption.itemName"></nz-option>
</nz-select>
</td>
<td nzWidth="10%" nzAlign="center">
<a nz-popconfirm nzPopconfirmTitle="删除后不可恢复,确定删除吗?" (nzOnConfirm)="deleteHotZoneConfigItem(it, i)">删除</a>
</td>
</tr>
</tbody>
</nz-table>
</div>
<div *ngIf="it.hotZoneType == AUDIO_PLAY" style="padding: 20px 0 10px 150px;">
<app-audio-recorder
......@@ -468,7 +508,7 @@
<label nz-checkbox [(ngModel)]="it.notAdaptContraction" (ngModelChange)="save()" style="margin-left: 10px;">不进行缩写适配</label>
</div>
<div *ngIf="it.hotZoneType != '' && it.hotZoneType != CROSSWORD_PUZZLE && it.hotZoneType != HOT_ZONE_RADIO && it.hotZoneType != HOT_ZONE_CHECKBOX && it.hotZoneType != CONNECTION && it.hotZoneType != TEXT_SELECT && it.hotZoneType != RIGHT_OR_WRONG" style="margin: 10px 10px;">
<div *ngIf="it.hotZoneType != '' && it.hotZoneType != CROSSWORD_PUZZLE && it.hotZoneType != HOT_ZONE_RADIO && it.hotZoneType != HOT_ZONE_CHECKBOX && it.hotZoneType != CONNECTION && it.hotZoneType != TEXT_SELECT && it.hotZoneType != RIGHT_OR_WRONG && it.hotZoneType != TEXTINPUT_GROUP" style="margin: 10px 10px;">
<span style="display: inline-block; text-align: right; width: 150px;">关联热区:</span>
<nz-select nzShowSearch nzAllowClear [(ngModel)]="it.linkHotZoneIndex" style="width: 300px;" (ngModelChange)="save()">
<nz-option *ngFor="let itOption of item.hotZoneItemArr" [nzValue]="itOption.index" [nzLabel]="itOption.itemName"></nz-option>
......@@ -489,7 +529,7 @@
</nz-select>
</div>
<div *ngIf="it.hotZoneType != ''&& it.hotZoneType != AUDIO_PLAY && it.hotZoneType != HOT_ZONE_CHECKBOX && it.hotZoneType != CONNECTION && it.hotZoneType != TEXT_SELECT && it.hotZoneType != RIGHT_OR_WRONG" style="margin: 10px 10px;">
<div *ngIf="it.hotZoneType != ''&& it.hotZoneType != AUDIO_PLAY && it.hotZoneType != HOT_ZONE_CHECKBOX && it.hotZoneType != CONNECTION && it.hotZoneType != TEXT_SELECT && it.hotZoneType != RIGHT_OR_WRONG && it.hotZoneType != TEXTINPUT_GROUP" style="margin: 10px 10px;">
<span style="display: inline-block; text-align: right; width: 150px;">分数:</span>
<input type="text" nz-input [(ngModel)]="it.score" (blur)="save()" style="display: inline-block; width: 300px;">
</div>
......
......@@ -54,6 +54,7 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy, AfterViewIni
CROSSWORD_PUZZLE = "9";
SORT_WORDS = "10";
CONNECTION_CHOICE = "11";
TEXTINPUT_GROUP = "12";
// 评分体系
RS_15_5L_FAF = "0";
......@@ -229,6 +230,14 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy, AfterViewIni
selectStartHotZoneIndex: null, // 起点热区索引 [连线题]
selectEndHotZoneIndex: null, // 终点热区索引 [连线题]
selectEndHotZoneShowIndex: null, // 被连接后 需要显示内容的热区 [连线题]
inputText: "", // 输入文字 [文字输入组]
keyWordMatch: false, // 关键词匹配 [文字输入组]
keyWordMatchInOrder: false, // 有序关键词 [文字输入组]
isCaseInsensitive: false, // 大小写不敏感 [文字输入组]
openAnswer: false, // 开放性答案 [文字输入组]
capitalizedFirstLetter: false, // 首字母大写 [文字输入组]
notAdaptContraction: false, // 不进行缩写适配 [文字输入组]
}
}
......@@ -491,6 +500,21 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy, AfterViewIni
}
});
break;
// 文字输入组
case this.TEXTINPUT_GROUP:
hotZoneConfg.contentList.forEach((contentItem, contentIndex) => {
// 分数检查
if(contentItem.score != null && !isNaN(Number(contentItem.score)) && Number(contentItem.score) > 0) {
totalScore += Number(contentItem.score);
} else {
scoreConfigErr.push(`内容${hotZoneConfigIndex+1} - 内容清单${contentIndex+1}: 分数配置为0或者有异常`)
}
// 热区配置检查
if(contentItem.selectHotZoneIndex == null || contentItem.selectHotZoneIndex == undefined || contentItem.selectHotZoneIndex < 0) {
hotZoneIndexErr.push(`内容${hotZoneConfigIndex+1} - 内容清单${contentIndex+1}: 关联热区为空`)
}
});
break;
default:;
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment