dbsd_kczx/src/views/kc/wjxWjxxTmlb/components/WjxWjxxTmlbForm.vue

613 lines
27 KiB
Vue

<template>
<a-spin :spinning="loading">
<a-form v-bind="formItemLayout">
<draggable handle="'.dragclass'" @end="end" v-model="tiganData" item-key="id">
<template #item="{ index, element: item }">
<div>
<!-- 单选题 -->
<!-- 单选题 -->
<div style="width: 100%" v-if="(item.wjType == 3 || item.wjType == '3') && item.wjSubtype == null">
<a-card>
<template #title>
<div>
<a-row>
<a-col :span="12">
<span>{{ index + 1 }}、<span style="color: #c2bfbf">[单选题]</span></span>
</a-col>
<a-col :span="12" style="text-align: right;">
<a-tooltip placement="topLeft" title="题目分数" v-if="isShow">
<a-select
style="width: 120px"
v-model:value="item.wjScore"
placeholder="请选择分数"
v-if="item.wjSfqh == '0'"
:disabled="editDisabled"
>
<a-select-option :value="item" v-for="(item) in scoreData">{{item}}</a-select-option>
</a-select>
</a-tooltip>
</a-col>
</a-row>
</div>
<JEditor2 placeholder="请填写文件题题干"
v-model:value="item.wjTitle"
:bordered="false"
:style="{ width: '30rem' }"
:auto-size="{ minRows: 1, maxRows: 5 }"
:disabled="editDisabled" v-if="!editDisabled"/>
<div v-else class="rich-text-container" v-html="item.wjTitle"></div>
<div style="text-align: right;color: #c2bfbf" v-if="isShow">是否加入题库:
<j-dict-select-tag type='radio' v-model:value="item.sftjtk" dictCode="yn" placeholder="是否加入题库" :disabled="editDisabled"/>
</div>
</template>
<a-row v-if="isShow">
<a-col :span="24" style="color: darkgrey; font-size: 13px"> 注:选中即为正确答案 </a-col>
</a-row>
<a-radio-group v-model:value="item.itemSelected" style="width: 100%" size="default" :disabled="!isShow">
<div style="width: 100%" v-for="(tmxx, index) in item.wjxWjxxTmxxList" :key="index">
<a-radio :value="tmxx.itemIndex + ``" style="width: 100%">
<a-input
placeholder="请填写选项"
v-model:value="tmxx.itemTitle"
:style="{ width: '30rem' }"
:bordered="false"
:disabled="editDisabled"
/>
<span style="color: #ecb646" v-if="item.itemSelected == tmxx.itemIndex">(正确答案)</span>
<a-tooltip placement="topLeft" title="在下方添加新的选项"
><Icon
icon="ant-design:plus-circle-outlined"
style="cursor: pointer; margin: 5px; font-size: 20px; color: #1890ff"
@click="handleAddTmxx(tmxx, index, item.wjxWjxxTmxxList)"
v-if="!editDisabled"
/></a-tooltip>
<a-tooltip placement="topLeft" title="删除选项"
><Icon
icon="ant-design:minus-circle-outlined"
style="cursor: pointer; margin: 5px; font-size: 20px; color: #1890ff"
@click="handleRemTmxx(tmxx, index, item.wjxWjxxTmxxList)"
v-if="!editDisabled"
/></a-tooltip>
</a-radio>
</div>
</a-radio-group>
</a-card>
</div>
<!-- 多选题 -->
<div style="width: 100%" v-else-if="item.wjType == 4 || item.wjType == '4'">
<a-card>
<template #title>
<div>
<a-row>
<a-col :span="12">
<span>{{ index + 1 }}、<span style="color: #c2bfbf">[多选题]</span></span>
</a-col>
<a-col :span="12" style="text-align: right;">
<a-tooltip placement="topLeft" title="题目分数" v-if="isShow">
<a-select
style="width: 120px"
v-model:value="item.wjScore"
placeholder="请选择分数"
v-if="item.wjSfqh == '0'"
:disabled="editDisabled"
>
<a-select-option :value="item" v-for="(item) in scoreData">{{item}}</a-select-option>
</a-select>
</a-tooltip>
</a-col>
</a-row>
</div>
<JEditor2 placeholder="请填写多选题题干"
v-model:value="item.wjTitle"
:bordered="false"
:style="{ width: '30rem' }"
:auto-size="{ minRows: 1, maxRows: 5 }"
:disabled="editDisabled" v-if="!editDisabled"/>
<div v-else class="rich-text-container" v-html="item.wjTitle"></div>
<div style="text-align: right;color: #c2bfbf" v-if="isShow">是否加入题库:
<j-dict-select-tag type='radio' v-model:value="item.sftjtk" dictCode="yn" placeholder="是否加入题库" :disabled="editDisabled"/>
</div>
</template>
<a-row v-if="isShow">
<a-col :span="24" style="color: darkgrey; font-size: 13px"> 注:选中即为正确答案 </a-col>
</a-row>
<a-checkbox-group v-model:value="item.itemSelected" style="width: 100%" :disabled="!isShow" @change="handleChecked">
<a-row>
<a-col :span="24" v-for="(tmxx, index) in item.wjxWjxxTmxxList" :key="index">
<!-- -{{item.itemSelected}}-{{tmxx.itemIndex}} -->
<a-checkbox :value="tmxx.itemIndex"
><a-input
placeholder="请填写选项"
v-model:value="tmxx.itemTitle"
:bordered="false"
:style="{ width: '30rem' }"
:disabled="editDisabled"
/></a-checkbox>
<span style="color: #ecb646" v-if="cheGrp(item.itemSelected, tmxx.itemIndex)">(正确答案)</span>
<a-tooltip placement="topLeft" title="在下方添加新的选项"
><Icon
icon="ant-design:plus-circle-outlined"
style="cursor: pointer; margin: 5px; font-size: 20px; color: #1890ff"
@click="handleAddTmxx(tmxx, index, item.wjxWjxxTmxxList)"
v-if="!editDisabled"
/></a-tooltip>
<a-tooltip placement="topLeft" title="删除选项"
><Icon
icon="ant-design:minus-circle-outlined"
style="cursor: pointer; margin: 5px; font-size: 20px; color: #1890ff"
@click="handleRemTmxx(tmxx, index, item.wjxWjxxTmxxList)"
v-if="!editDisabled"
/></a-tooltip>
</a-col>
</a-row>
</a-checkbox-group>
</a-card>
</div>
<!-- 填空题 -->
<div style="width: 100%" v-else-if="(item.wjType == 5 || item.wjType == '5') && item.wjSubtype == null">
<a-card>
<template #title>
<div>
<a-row>
<a-col :span="12">
<span>{{ index + 1 }}、<span style="color: #c2bfbf">[填空题]</span></span>
</a-col>
<a-col :span="12" style="text-align: right;">
<a-tooltip placement="topLeft" title="题目分数" v-if="isShow">
<a-select
style="width: 120px"
v-model:value="item.wjScore"
placeholder="请选择分数"
v-if="item.wjSfqh == '0'"
:disabled="editDisabled"
>
<a-select-option :value="item" v-for="(item) in scoreData">{{item}}</a-select-option>
</a-select>
</a-tooltip>
</a-col>
</a-row>
</div>
<JEditor2 placeholder="请填写填空题题干"
v-model:value="item.wjTitle"
:bordered="false"
:style="{ width: '30rem' }"
:auto-size="{ minRows: 1, maxRows: 5 }"
:disabled="editDisabled" v-if="!editDisabled"/>
<div v-else class="rich-text-container" v-html="item.wjTitle"></div>
<div style="text-align: right;color: #c2bfbf" v-if="isShow">是否加入题库:
<j-dict-select-tag type='radio' v-model:value="item.sftjtk" dictCode="yn" placeholder="是否加入题库" :disabled="editDisabled"/>
</div>
</template>
<a-row >
<a-col :span="24">
<a-textarea
placeholder="请填写答案"
v-model:value="item.wjAnswer"
:bordered="false"
style="width: 100%"
:auto-size="{ minRows: 1, maxRows: 5 }"
:disabled="editDisabled"
/>
</a-col>
</a-row>
</a-card>
</div>
<!-- 文件上传 -->
<div style="width: 100%" v-else-if="item.wjType == 8 || item.wjType == '8'">
<a-card>
<template #title>
<div>
<a-row>
<a-col :span="12">
<span>{{ index + 1 }}、<span style="color: #c2bfbf">[文件题]</span></span>
</a-col>
<a-col :span="12" style="text-align: right;">
<a-tooltip placement="topLeft" title="题目分数" v-if="isShow">
<a-select
style="width: 120px"
v-model:value="item.wjScore"
placeholder="请选择分数"
v-if="item.wjSfqh == '0'"
:disabled="editDisabled"
>
<a-select-option :value="item" v-for="(item) in scoreData">{{item}}</a-select-option>
</a-select>
</a-tooltip>
</a-col>
</a-row>
</div>
<JEditor2 placeholder="请填写文件题题干"
v-model:value="item.wjTitle"
:bordered="false"
:style="{ width: '30rem' }"
:auto-size="{ minRows: 1, maxRows: 5 }"
:disabled="editDisabled" v-if="!editDisabled"/>
<div v-else class="rich-text-container" v-html="item.wjTitle"></div>
<div style="text-align: right;color: #c2bfbf" v-if="isShow">是否加入题库:
<j-dict-select-tag type='radio' v-model:value="item.sftjtk" dictCode="yn" placeholder="是否加入题库" :disabled="editDisabled"/>
</div>
</template>
</a-card>
</div>
<!-- 判断题 -->
<div style="width: 100%" v-else-if="(item.wjType == 3 || item.wjType == '3') && (item.wjSubtype == 305 || item.wjSubtype == '305')">
<a-card>
<template #title>
<div>
<a-row>
<a-col :span="12">
<span>{{ index + 1 }}、<span style="color: #c2bfbf">[判断题]</span></span>
</a-col>
<a-col :span="12" style="text-align: right;">
<a-tooltip placement="topLeft" title="题目分数" v-if="isShow">
<a-select
style="width: 120px"
v-model:value="item.wjScore"
placeholder="请选择分数"
v-if="item.wjSfqh == '0'"
:disabled="editDisabled"
>
<a-select-option :value="item" v-for="(item) in scoreData">{{item}}</a-select-option>
</a-select>
</a-tooltip>
</a-col>
</a-row>
</div>
<JEditor2 placeholder="请填写文件题题干"
v-model:value="item.wjTitle"
:bordered="false"
:style="{ width: '30rem' }"
:auto-size="{ minRows: 1, maxRows: 5 }"
:disabled="editDisabled" v-if="!editDisabled"/>
<div v-else class="rich-text-container" v-html="item.wjTitle"></div>
<div style="text-align: right;color: #c2bfbf" v-if="isShow">是否加入题库:
<j-dict-select-tag type='radio' v-model:value="item.sftjtk" dictCode="yn" placeholder="是否加入题库" :disabled="editDisabled"/>
</div>
</template>
<a-row v-if="isShow">
<a-col :span="24" style="color: darkgrey; font-size: 13px"> 注:选中即为正确答案 </a-col>
</a-row>
<a-radio-group v-model:value="item.itemSelected" style="width: 100%" size="default" :disabled="!isShow">
<div style="width: 100%" v-for="(tmxx, index) in item.wjxWjxxTmxxList" :key="index">
<a-radio :value="tmxx.itemIndex + ``" style="width: 100%">
<a-input
placeholder="请填写选项"
v-model:value="tmxx.itemTitle"
:style="{ width: '30rem' }"
:bordered="false"
:disabled="editDisabled"
/>
<span style="color: #ecb646" v-if="item.itemSelected == tmxx.itemIndex">(正确答案)</span>
<a-tooltip placement="topLeft" title="在下方添加新的选项"
><Icon
icon="ant-design:plus-circle-outlined"
style="cursor: pointer; margin: 5px; font-size: 20px; color: #1890ff"
@click="handleAddTmxx(tmxx, index, item.wjxWjxxTmxxList)"
v-if="!editDisabled"
/></a-tooltip>
<a-tooltip placement="topLeft" title="删除选项"
><Icon
icon="ant-design:minus-circle-outlined"
style="cursor: pointer; margin: 5px; font-size: 20px; color: #1890ff"
@click="handleRemTmxx(tmxx, index, item.wjxWjxxTmxxList)"
v-if="!editDisabled"
/></a-tooltip>
</a-radio>
</div>
</a-radio-group>
</a-card>
</div>
<!-- 简答题 -->
<div style="width: 100%" v-else-if="(item.wjType == 5 || item.wjType == '5') && (item.wjSubtype == 5 || item.wjSubtype == '5')">
<a-card>
<template #title>
<div>
<a-row>
<a-col :span="12">
<span>{{ index + 1 }}<span style="color: #c2bfbf">[简答题]</span></span>
</a-col>
<a-col :span="12" style="text-align: right;">
<a-tooltip placement="topLeft" title="题目分数" v-if="isShow">
<a-select
style="width: 120px"
v-model:value="item.wjScore"
placeholder="请选择分数"
v-if="item.wjSfqh == '0'"
:disabled="editDisabled"
>
<a-select-option :value="item" v-for="(item) in scoreData">{{item}}</a-select-option>
</a-select>
</a-tooltip>
</a-col>
</a-row>
</div>
<JEditor2 placeholder="请填写简答题题干"
v-model:value="item.wjTitle"
:bordered="false"
:style="{ width: '30rem' }"
:auto-size="{ minRows: 1, maxRows: 5 }"
:disabled="editDisabled" v-if="!editDisabled"/>
<div v-else class="rich-text-container" v-html="item.wjTitle"></div>
<div style="text-align: right;color: #c2bfbf" v-if="isShow">是否加入题库:
<j-dict-select-tag type='radio' v-model:value="item.sftjtk" dictCode="yn" placeholder="是否加入题库" :disabled="editDisabled"/>
</div>
</template>
</a-card>
</div>
<div v-else></div>
</div>
</template>
</draggable>
</a-form>
</a-spin>
</template>
<script lang="ts">
import { defineComponent, ref, reactive, computed, toRaw, onMounted } from 'vue';
import { defHttp } from '/@/utils/http/axios';
import { useValidateAntFormAndTable } from '/@/hooks/system/useJvxeMethods';
import { queryWjxWjxxTmxxListByMainId, queryDataById, saveOrUpdate } from '../WjxWjxxTmlb.api';
import { JVxeTable } from '/@/components/jeecg/JVxeTable';
import { wjxWjxxTmxxColumns, wjxWjdcColumns } from '../WjxWjxxTmlb.data';
import { useMessage } from '/@/hooks/web/useMessage';
import { Form } from 'ant-design-vue';
import JEditor2 from '/@/components/Form/src/jeecg/components/JEditor2.vue';
import draggable from 'vuedraggable';
import JDictSelectTag from '/@/components/Form/src/jeecg/components/JDictSelectTag.vue';
import { useScreenSize } from '/src/utils/screenSize/useScreenSize'
const { isSmallScreen } = useScreenSize();
const useForm = Form.useForm;
export default defineComponent({
name: 'WjxWjxxTmlbForm',
components: {
JVxeTable,
draggable,
JEditor2,
JDictSelectTag,
},
props: {
formDisabled: {
type: Boolean,
default: false,
},
formData: { type: Object, default: () => {} },
formBpm: { type: Boolean, default: true },
},
emits: ['success'],
setup(props, { emit }) {
const loading = ref(false);
const wjxWjxxTmxxTableRef = ref();
const activeKey = ref('wjxWjxxTmxx');
const isShow = ref<boolean>(true);
const editDisabled = ref<boolean>(true);
const tiganData = ref<any>([]);
const { createConfirm, createMessage, createWarningModal } = useMessage();
const scoreData = [
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,60,70,80,90,100
]
const formData = reactive<Record<string, any>>({
id: '',
wjTitle: '',
wjScore: '',
});
const wjxWjxxTmxxTable = reactive<Record<string, any>>({
loading: false,
columns: wjxWjxxTmxxColumns,
dataSource: [],
});
//表单验证
const validatorRules = reactive({});
const { resetFields, validate, validateInfos } = useForm(formData, validatorRules, { immediate: true });
const dbData = {};
const formItemLayout = {
labelCol: { xs: { span: 24 }, sm: { span: 5 } },
wrapperCol: { xs: { span: 24 }, sm: { span: 16 } },
};
// 表单禁用
const disabled = computed(() => {
if (props.formBpm === true) {
if (props.formData.disabled === false) {
return false;
} else {
return true;
}
}
return props.formDisabled;
});
function add() {
resetFields();
wjxWjxxTmxxTable.dataSource = [];
}
async function edit(row, formDisabled) {
console.log('😺', formDisabled.value);
console.log('😰', row);
editDisabled.value = formDisabled.value;
defHttp.get({ url: '/wjxWjxxTmlb/wjxWjxxTmlb/getTmxxByTmlbid', params: { id: row.id } }).then((res) => {
console.log('👦', res);
tiganData.value = res;
});
// //主表数据
// await queryMainData(row.id);
// //子表数据
// const wjxWjxxTmxxDataList = await queryWjxWjxxTmxxListByMainId(row['id']);
// wjxWjxxTmxxTable.dataSource = [...wjxWjxxTmxxDataList];
}
async function queryMainData(id) {
const row = await queryDataById(id);
Object.keys(row).map((k) => {
formData[k] = row[k];
});
}
const { getSubFormAndTableData, transformData } = useValidateAntFormAndTable(activeKey, {
wjxWjxxTmxx: wjxWjxxTmxxTableRef,
});
async function getFormData() {
await validate();
return transformData(toRaw(formData));
}
async function submitForm() {
// const mainData = await getFormData();
// const subData = await getSubFormAndTableData();
// const values = Object.assign({}, dbData, mainData, subData);
// console.log('表单提交数据', values);
// const isUpdate = values.id ? true : false;
// await saveOrUpdate(values, isUpdate);
const data = tiganData.value;
if(data.length==0){
createMessage.warning('请添加选项!');
return;
}
console.log('🧝‍♀️', data[0]);
defHttp.post({ url: '/wjxWjxxTmlb/wjxWjxxTmlb/edit', params: data[0] }).then((res) => {
//关闭弹窗
emit('success');
});
}
function setFieldsValue(values) {
if (values) {
Object.keys(values).map((k) => {
formData[k] = values[k];
});
}
}
/**
* 值改变事件触发-树控件回调
* @param key
* @param value
*/
function handleFormChange(key, value) {
formData[key] = value;
}
function handleChecked(record) {
record = record + '';
}
/**
* 拖动结束事件
* @param evt
*/
function end(evt) {
// for (var i = 0; i < tiganData.value.length; i++) {
// tiganData.value[i].wjIndex = i + 1;
// }
}
function cheGrp(a, b) {
var retChe = false;
if (a) {
for (var i = 0; i < a.length; i++) {
if (a[i] == b) {
retChe = true;
break;
}
}
}
return retChe;
}
//添加选项
function handleAddTmxx(record, index, list) {
var itemIndex = 0;
for (var i = 0; i < list.length; i++) {
var lssx = list[i].itemIndex;
if (itemIndex < parseInt(lssx)) {
itemIndex = lssx;
}
}
list.push({ itemTitle: null, itemIndex: parseInt(itemIndex) + 1 });
}
//删除选项
function handleRemTmxx(record, index, list) {
if (list.length <= 2) {
createMessage.error('至少保留两个选项');
} else {
list.splice(index, 1);
}
}
//计算输入框宽度
function handinpwei(value) {
if (!value) {
return '20rem';
} else {
if (String(value).length * 1.1 < 20) {
return '20rem';
} else if (String(value).length * 1.1 > 60) {
return '60rem';
} else {
return String(value).length * 1.1 + 'rem';
}
}
}
//切换题目分数类型
function handleQiehuan(record, type) {
console.log(`🚀 ~ handleQiehuan ~ type:`, type);
console.log(`🚀 ~ handleQiehuan ~ record:`, record);
record.wjSfqh = type;
}
return {
wjxWjxxTmxxTableRef,
wjxWjxxTmxxTable,
validatorRules,
validateInfos,
activeKey,
loading,
formData,
setFieldsValue,
handleFormChange,
formItemLayout,
disabled,
getFormData,
submitForm,
add,
edit,
handinpwei,
handleQiehuan,
handleAddTmxx,
handleRemTmxx,
cheGrp,
end,
handleChecked,
isShow,
tiganData,
editDisabled,
scoreData,
};
},
});
</script>
<style scoped>
.rich-text-container {
white-space: pre-wrap; /* 强制换行 */
word-break: break-all; /* 长单词和 URL 地址换行 */
overflow-wrap: break-word; /* 在长单词内部换行 */
}
</style>