|
@@ -17,11 +17,8 @@
|
|
|
<template v-for="i in data.property.column_number">
|
|
|
<div :key="i" class="fill-form">
|
|
|
<!-- 头部 -->
|
|
|
- <span
|
|
|
- v-if="isEnable(data.property.is_enable_table_header)"
|
|
|
- class="form-header"
|
|
|
- :style="{ paddingLeft: isEnable(data.property.is_enable_number_column) && i === 1 ? '40px' : '0' }"
|
|
|
- >
|
|
|
+ <span v-if="isEnable(data.property.is_enable_table_header)" class="form-header">
|
|
|
+ <span v-if="isEnable(data.property.is_enable_number_column) && i === 1" class="serial-number"></span>
|
|
|
<el-input v-model="data.option_header_list[i - 1].text" placeholder="请输入" />
|
|
|
</span>
|
|
|
|
|
@@ -45,13 +42,50 @@
|
|
|
</template>
|
|
|
</div>
|
|
|
|
|
|
- <el-input
|
|
|
- v-if="isEnable(data.property.is_enable_reference_answer)"
|
|
|
- v-model="data.reference_answer"
|
|
|
- type="textarea"
|
|
|
- rows="3"
|
|
|
- placeholder="输入参考答案"
|
|
|
- />
|
|
|
+ <template v-if="isEnable(data.property.is_enable_reference_answer)">
|
|
|
+ <span class="reference-title">参考答案:</span>
|
|
|
+ <div class="form-wrapper">
|
|
|
+ <div class="form" :style="{ width: `${data.property.form_width}px` }">
|
|
|
+ <div v-if="isEnable(data.property.is_enable_table_header)" class="form-header">
|
|
|
+ <div
|
|
|
+ v-for="(item, i) in data.reference_answer_option_header_list"
|
|
|
+ :key="i"
|
|
|
+ :style="{
|
|
|
+ borderLeft: isEnable(data.property.is_enable_number_column) || i > 0 ? '1px solid #e0e0e0' : 'none',
|
|
|
+ width:
|
|
|
+ isEnable(data.property.is_enable_number_column) && i === 0
|
|
|
+ ? `calc(${item.width}% - 39px)`
|
|
|
+ : `${item.width}%`,
|
|
|
+ marginLeft: isEnable(data.property.is_enable_number_column) && i === 0 ? '39px' : '0',
|
|
|
+ }"
|
|
|
+ class="header-item"
|
|
|
+ >
|
|
|
+ <el-input v-model="item.text" placeholder="请输入" />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div v-for="(item, i) in data.reference_answer_option_list" :key="i" class="form-content">
|
|
|
+ <div
|
|
|
+ v-for="(li, j) in item"
|
|
|
+ :key="li.mark"
|
|
|
+ :style="{ width: `${data.reference_answer_option_header_list[j].width}%` }"
|
|
|
+ class="form-item"
|
|
|
+ >
|
|
|
+ <span v-if="j === 0 && isEnable(data.property.is_enable_number_column)" class="serial-number">
|
|
|
+ {{ i + 1 }}
|
|
|
+ </span>
|
|
|
+ <div class="item-content">
|
|
|
+ <el-input
|
|
|
+ v-model="li.text"
|
|
|
+ class="fill"
|
|
|
+ placeholder="请输入"
|
|
|
+ @blur="handleTone(li.text, i, j, 'reference')"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
@@ -179,41 +213,15 @@ export default {
|
|
|
watch: {
|
|
|
'data.property.row_number': {
|
|
|
handler(val) {
|
|
|
- if (val > this.data.option_list.length) {
|
|
|
- this.data.option_list.push(Array.from({ length: this.data.property.column_number }, () => getOption()));
|
|
|
- } else if (val < this.data.option_list.length) {
|
|
|
- this.data.option_list.pop();
|
|
|
- }
|
|
|
+ this.handleRowNumber(val, 'option');
|
|
|
+ this.handleRowNumber(val, 'reference');
|
|
|
},
|
|
|
immediate: true,
|
|
|
},
|
|
|
'data.property.column_number': {
|
|
|
handler(val) {
|
|
|
- // 列数变化时,需要重新计算每列的宽度
|
|
|
- if (val > this.data.option_header_list.length) {
|
|
|
- let width = 0;
|
|
|
- this.data.option_header_list.forEach((item) => {
|
|
|
- // 平均分配宽度,最小宽度为10
|
|
|
- let w = Math.max((item.width / val) * this.data.option_header_list.length, 10);
|
|
|
- width += item.width - w;
|
|
|
- item.width = w;
|
|
|
- });
|
|
|
- this.data.option_header_list.push({ mark: getRandomNumber(), text: '', width });
|
|
|
- } else if (val < this.data.option_header_list.length) {
|
|
|
- let width = this.data.option_header_list[val].width;
|
|
|
- this.data.option_header_list.pop();
|
|
|
- this.data.option_header_list.forEach((item) => {
|
|
|
- item.width += width / val;
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- this.data.option_list = this.data.option_list.map((item) => {
|
|
|
- const arr = [];
|
|
|
- for (let i = 0; i < val; i++) {
|
|
|
- arr.push(item[i] || getOption());
|
|
|
- }
|
|
|
- return arr;
|
|
|
- });
|
|
|
+ this.handleColumnNumber(val, 'option');
|
|
|
+ this.handleColumnNumber(val, 'reference');
|
|
|
},
|
|
|
immediate: true,
|
|
|
},
|
|
@@ -264,6 +272,16 @@ export default {
|
|
|
list[i - 1].width = Math.min(Math.max(10, list[i - 1].width + w), list[i - 1].width + list[i].width - 10);
|
|
|
list[i].width = Math.min(Math.max(10, list[i].width - w), list[i - 1].width + list[i].width - 10);
|
|
|
|
|
|
+ let referenceList = this.data.reference_answer_option_header_list;
|
|
|
+ referenceList[i - 1].width = Math.min(
|
|
|
+ Math.max(10, referenceList[i - 1].width + w),
|
|
|
+ referenceList[i - 1].width + referenceList[i].width - 10,
|
|
|
+ );
|
|
|
+ referenceList[i].width = Math.min(
|
|
|
+ Math.max(10, referenceList[i].width - w),
|
|
|
+ referenceList[i - 1].width + referenceList[i].width - 10,
|
|
|
+ );
|
|
|
+
|
|
|
startX = endX;
|
|
|
};
|
|
|
|
|
@@ -277,8 +295,10 @@ export default {
|
|
|
target.setCapture && target.setCapture(); // 该函数在属于当前线程的指定窗口里设置鼠标捕获
|
|
|
return false;
|
|
|
},
|
|
|
- handleTone(value, i, j) {
|
|
|
- this.data.option_list[j - 1][i - 1].text = value
|
|
|
+ handleTone(value, i, j, type = 'option') {
|
|
|
+ let option =
|
|
|
+ type === 'reference' ? this.data.reference_answer_option_list[i][j] : this.data.option_list[j - 1][i - 1];
|
|
|
+ let text = value
|
|
|
.trim()
|
|
|
.split(/\s+/)
|
|
|
.map((item) => {
|
|
@@ -289,6 +309,46 @@ export default {
|
|
|
)
|
|
|
.filter((item) => item.length > 0)
|
|
|
.join(' ');
|
|
|
+ this.$set(option, 'text', text);
|
|
|
+ },
|
|
|
+
|
|
|
+ handleRowNumber(val, type = 'option') {
|
|
|
+ let option = type === 'reference' ? this.data.reference_answer_option_list : this.data.option_list;
|
|
|
+ if (val > option.length) {
|
|
|
+ option.push(Array.from({ length: this.data.property.column_number }, () => getOption(type)));
|
|
|
+ } else if (val < option.length) {
|
|
|
+ option.pop();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ handleColumnNumber(val, type) {
|
|
|
+ let header_list =
|
|
|
+ type === 'reference' ? this.data.reference_answer_option_header_list : this.data.option_header_list;
|
|
|
+ // 列数变化时,需要重新计算每列的宽度
|
|
|
+ if (val > header_list.length) {
|
|
|
+ let width = 0;
|
|
|
+ header_list.forEach((item) => {
|
|
|
+ // 平均分配宽度,最小宽度为10
|
|
|
+ let w = Math.max((item.width / val) * header_list.length, 10);
|
|
|
+ width += item.width - w;
|
|
|
+ item.width = w;
|
|
|
+ });
|
|
|
+ header_list.push({ mark: getRandomNumber(), text: '', width });
|
|
|
+ } else if (val < header_list.length) {
|
|
|
+ let width = header_list[val].width;
|
|
|
+ header_list.pop();
|
|
|
+ header_list.forEach((item) => {
|
|
|
+ item.width += width / val;
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ let listName = type === 'reference' ? 'reference_answer_option_list' : 'option_list';
|
|
|
+ this.data[listName] = this.data[listName].map((item) => {
|
|
|
+ const arr = [];
|
|
|
+ for (let i = 0; i < val; i++) {
|
|
|
+ arr.push(item[i] || getOption(type));
|
|
|
+ }
|
|
|
+ return arr;
|
|
|
+ });
|
|
|
},
|
|
|
// 计算选项样式
|
|
|
computedOptionStyle() {
|
|
@@ -309,6 +369,8 @@ export default {
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
+$table-border: 1px solid #e0e0e0;
|
|
|
+
|
|
|
.mask {
|
|
|
position: absolute;
|
|
|
top: 0;
|
|
@@ -320,13 +382,16 @@ export default {
|
|
|
}
|
|
|
|
|
|
.content {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ row-gap: 8px;
|
|
|
width: calc(100vw - 645px);
|
|
|
overflow: auto;
|
|
|
|
|
|
.option-wrapper {
|
|
|
display: grid;
|
|
|
grid-auto-flow: column;
|
|
|
- margin-bottom: 8px;
|
|
|
+ border: $table-border;
|
|
|
|
|
|
.fill-form {
|
|
|
display: flex;
|
|
@@ -336,16 +401,23 @@ export default {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
height: 40px;
|
|
|
- background-color: $fill-color;
|
|
|
+ background-color: #eaeffb;
|
|
|
+ border-bottom: $table-border;
|
|
|
|
|
|
- .header-serial-number {
|
|
|
- padding: 8px 16px;
|
|
|
- font-weight: bold;
|
|
|
+ .serial-number {
|
|
|
+ width: 41px;
|
|
|
+ min-width: 41px;
|
|
|
+ height: 40px;
|
|
|
+ color: #000;
|
|
|
+ border-right: $table-border;
|
|
|
}
|
|
|
|
|
|
:deep .el-input__inner {
|
|
|
font-size: 16px;
|
|
|
font-weight: bold;
|
|
|
+ color: $main-color;
|
|
|
+ text-align: center;
|
|
|
+ background-color: #eaeffb;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -362,11 +434,17 @@ export default {
|
|
|
}
|
|
|
|
|
|
.el-input {
|
|
|
+ border-bottom-width: 0;
|
|
|
+
|
|
|
:deep &__inner {
|
|
|
height: 54px;
|
|
|
font-size: 16px;
|
|
|
line-height: 54px;
|
|
|
+ color: $font-color;
|
|
|
+ text-align: left;
|
|
|
background-color: #fff;
|
|
|
+ border-bottom-width: 0;
|
|
|
+ border-radius: 0;
|
|
|
|
|
|
&:focus {
|
|
|
border-color: #c0c4cc;
|
|
@@ -384,10 +462,98 @@ export default {
|
|
|
width: 2px;
|
|
|
height: 100%;
|
|
|
cursor: col-resize;
|
|
|
- background-color: #165dff;
|
|
|
+ background-color: #e0e0e0;
|
|
|
border-radius: 4px;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ .reference-title {
|
|
|
+ font-size: 14px;
|
|
|
+ color: #000;
|
|
|
+ }
|
|
|
+
|
|
|
+ .form-wrapper {
|
|
|
+ .form {
|
|
|
+ border: $table-border;
|
|
|
+
|
|
|
+ &-header {
|
|
|
+ display: flex;
|
|
|
+ font-weight: bold;
|
|
|
+ color: $main-color;
|
|
|
+ background-color: #eaeffb;
|
|
|
+
|
|
|
+ .header-item {
|
|
|
+ min-height: 40px;
|
|
|
+ padding: 8px 12px;
|
|
|
+ font-size: 16px;
|
|
|
+ text-align: center;
|
|
|
+
|
|
|
+ :deep .el-input__inner {
|
|
|
+ font-size: 16px;
|
|
|
+ font-weight: bold;
|
|
|
+ color: $main-color;
|
|
|
+ text-align: center;
|
|
|
+ background-color: #eaeffb;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ &-header + .form-content {
|
|
|
+ border-top: $table-border;
|
|
|
+ }
|
|
|
+
|
|
|
+ &-content:not(:last-child) {
|
|
|
+ border-bottom: $table-border;
|
|
|
+ }
|
|
|
+
|
|
|
+ &-content {
|
|
|
+ display: flex;
|
|
|
+
|
|
|
+ .form-item:not(:first-child) {
|
|
|
+ border-left: $table-border;
|
|
|
+ }
|
|
|
+
|
|
|
+ .form-item {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ min-height: 48px;
|
|
|
+ overflow: auto;
|
|
|
+
|
|
|
+ .item-content {
|
|
|
+ flex: 1;
|
|
|
+ padding: 8px 12px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .el-input.fill {
|
|
|
+ display: inline-flex;
|
|
|
+ align-items: center;
|
|
|
+ margin: 0 2px;
|
|
|
+
|
|
|
+ :deep input.el-input__inner {
|
|
|
+ padding: 0;
|
|
|
+ font-size: 16px;
|
|
|
+ color: $font-color;
|
|
|
+ text-align: left;
|
|
|
+ background-color: #fff;
|
|
|
+ border-width: 0;
|
|
|
+ border-radius: 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .serial-number {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ width: 40px;
|
|
|
+ min-width: 40px;
|
|
|
+ max-width: 40px;
|
|
|
+ height: 100%;
|
|
|
+ padding: 8px 12px;
|
|
|
+ border-right: $table-border;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
.property {
|