北斗应用技术培训考试管理系统
This commit is contained in:
163
src/components/addNewData/adminForm/adminForm.vue
Normal file
163
src/components/addNewData/adminForm/adminForm.vue
Normal file
@@ -0,0 +1,163 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:show-close="false"
|
||||
style="width: 80%"
|
||||
center
|
||||
align-center
|
||||
:before-close="resetCheckForm"
|
||||
>
|
||||
<template #header="{ titleId, titleClass }">
|
||||
<div
|
||||
style="font-size: 2rem"
|
||||
class="w-full font-bold"
|
||||
:id="titleId"
|
||||
:class="titleClass"
|
||||
>
|
||||
{{ title }}
|
||||
</div>
|
||||
<div
|
||||
@click="resetCheckForm"
|
||||
class="bg-gray-400 hover:bg-red-600 text-3xl absolute top-0 right-0 cursor-pointer flex justify-center items-center"
|
||||
>
|
||||
<el-icon>
|
||||
<CloseBold />
|
||||
</el-icon>
|
||||
</div>
|
||||
</template>
|
||||
<FormTools @showTools="showTools" :dialogObj="adminMsgActive" />
|
||||
<SingleAdd
|
||||
ref="singleAddRef"
|
||||
v-if="dialogSingleVisible"
|
||||
:addData="addData"
|
||||
@addAdmin="addAdmin"
|
||||
/>
|
||||
<MultipleAdd
|
||||
ref="multipleAddRef"
|
||||
v-if="dialogMultipleVisible"
|
||||
:checkNeed="true"
|
||||
:addData="addData"
|
||||
@addAdmin="addAdmin"
|
||||
/>
|
||||
<ExcleAdd ref="excleAddRef" v-if="dialogExcleVisible" @addAdmin="addAdmin" />
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button style="font-weight: bold" @click="resetCheckForm"> 取消 </el-button>
|
||||
<el-button style="font-weight: bold" type="primary" @click="confirm">
|
||||
确定
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { CloseBold } from "@element-plus/icons-vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import FormTools from "../../operate/formTools.vue";
|
||||
import SingleAdd from "./singleAdd.vue";
|
||||
import MultipleAdd from "./multipleAdd.vue";
|
||||
import ExcleAdd from "./excleAdd.vue";
|
||||
|
||||
import adminActiveStore from "../../../stores/adminMsg";
|
||||
|
||||
import $http from "../../../api/index";
|
||||
import $url from "../../../api/url";
|
||||
|
||||
import { encrypt } from "../../../utils/aes";
|
||||
|
||||
const adminMsgActive = adminActiveStore();
|
||||
|
||||
const dialogVisible = ref(false);
|
||||
const singleAddRef = ref(null);
|
||||
const multipleAddRef = ref(null);
|
||||
const excleAddRef = ref(null);
|
||||
const dialogSingleVisible = ref(true);
|
||||
const dialogMultipleVisible = ref(false);
|
||||
const dialogExcleVisible = ref(false);
|
||||
|
||||
const props = defineProps({
|
||||
title: String,
|
||||
addData: Object,
|
||||
});
|
||||
|
||||
const emit = defineEmits(["reloadData"]);
|
||||
|
||||
const showTools = (operateType) => {
|
||||
switch (operateType) {
|
||||
case "single":
|
||||
dialogSingleVisible.value = true;
|
||||
dialogMultipleVisible.value = false;
|
||||
dialogExcleVisible.value = false;
|
||||
adminMsgActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
adminMsgActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
adminMsgActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
case "multiple":
|
||||
dialogSingleVisible.value = false;
|
||||
dialogMultipleVisible.value = true;
|
||||
dialogExcleVisible.value = false;
|
||||
adminMsgActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
adminMsgActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
adminMsgActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
case "excle":
|
||||
dialogSingleVisible.value = false;
|
||||
dialogMultipleVisible.value = false;
|
||||
dialogExcleVisible.value = true;
|
||||
adminMsgActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
adminMsgActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
adminMsgActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (dialogSingleVisible.value) {
|
||||
singleAddRef.value.resetCheckForm();
|
||||
} else if (dialogMultipleVisible.value) {
|
||||
multipleAddRef.value.resetCheckForm();
|
||||
} else if (dialogExcleVisible.value) {
|
||||
excleAddRef.value.resetCheckForm();
|
||||
}
|
||||
dialogVisible.value = false;
|
||||
};
|
||||
|
||||
const confirm = () => {
|
||||
if (dialogSingleVisible.value) {
|
||||
singleAddRef.value.confirm();
|
||||
} else if (dialogMultipleVisible.value) {
|
||||
multipleAddRef.value.confirm();
|
||||
} else if (dialogExcleVisible.value) {
|
||||
excleAddRef.value.confirm();
|
||||
}
|
||||
};
|
||||
|
||||
const addAdmin = (requestMsg) => {
|
||||
requestMsg.forEach((element) => {
|
||||
element.account_name = encrypt(String(element.account_name));
|
||||
element.role = encrypt(String(element.role));
|
||||
});
|
||||
const data = { requestMsg };
|
||||
$http.post($url.addAdmin, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
resetCheckForm();
|
||||
ElMessage({
|
||||
message: "新增普通管理员成功!",
|
||||
type: "success",
|
||||
});
|
||||
emit("reloadData");
|
||||
} else {
|
||||
ElMessage.error("新增普通管理员失败!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ dialogVisible });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
92
src/components/addNewData/adminForm/excleAdd.vue
Normal file
92
src/components/addNewData/adminForm/excleAdd.vue
Normal file
@@ -0,0 +1,92 @@
|
||||
<template>
|
||||
<UploadFile
|
||||
ref="uploadFileRef"
|
||||
:options="options"
|
||||
:relatedRules="relatedRules"
|
||||
:relatedOptions="relatedOptions"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import UploadFile from "../../operate/uploadFile.vue";
|
||||
|
||||
const uploadFileRef = ref(null);
|
||||
const formClone = ref([]);
|
||||
|
||||
const options = {
|
||||
limit: 1,
|
||||
accept: ".xlsx",
|
||||
action: "",
|
||||
multiple: false,
|
||||
listType: "text",
|
||||
autoUpload: false,
|
||||
};
|
||||
|
||||
const relatedRules = {
|
||||
account_name: {
|
||||
value: "",
|
||||
label: "账号名",
|
||||
},
|
||||
role: {
|
||||
value: "",
|
||||
label: "权限等级",
|
||||
},
|
||||
};
|
||||
|
||||
const relatedOptions = [
|
||||
{
|
||||
value: "0",
|
||||
label: "账号名",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "1",
|
||||
label: "权限等级",
|
||||
disabled: false,
|
||||
},
|
||||
];
|
||||
|
||||
const emit = defineEmits(["addAdmin"]);
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!uploadFileRef) return;
|
||||
uploadFileRef.value.handleExceed();
|
||||
};
|
||||
|
||||
const confirm = async () => {
|
||||
if (!uploadFileRef) return;
|
||||
formClone.value = [];
|
||||
const length = uploadFileRef.value.loadData.length;
|
||||
if (length == 0) return ElMessage.error("请先上传文件!");
|
||||
const flag = await uploadFileRef.value.confirm();
|
||||
if (!flag) return ElMessage.error("请先选择表格关联项!");
|
||||
ElMessage({
|
||||
message: `正在上传数据中,请稍等...`,
|
||||
type: "success",
|
||||
});
|
||||
setTimeout(() => {
|
||||
uploadFileRef.value.loadData.forEach((ExcleForm) => {
|
||||
ExcleForm.forEach((worksheet) => {
|
||||
let context = [...worksheet];
|
||||
context.shift();
|
||||
context.forEach((item) => {
|
||||
if (item.length != 0) {
|
||||
formClone.value.push({
|
||||
account_name: item[relatedRules.account_name.value],
|
||||
role: item[relatedRules.role.value],
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
emit("addAdmin", formClone.value);
|
||||
}, 3000);
|
||||
};
|
||||
|
||||
defineExpose({ resetCheckForm, confirm, formClone });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
116
src/components/addNewData/adminForm/multipleAdd.vue
Normal file
116
src/components/addNewData/adminForm/multipleAdd.vue
Normal file
@@ -0,0 +1,116 @@
|
||||
<template>
|
||||
<div>
|
||||
<div
|
||||
style="font-size: 2rem"
|
||||
class="flex flex-warp justify-center items-center font-bold"
|
||||
>
|
||||
<div style="font-size: 1rem">请输入要导入的数据数量:</div>
|
||||
<el-input-number v-model="singleFormNum" :min="1" :max="10" @change="createForm" />
|
||||
<div v-if="checkNeed"> </div>
|
||||
<el-checkbox
|
||||
v-if="checkNeed"
|
||||
v-model="checked"
|
||||
label="为所有表单进行相同操作"
|
||||
size="large"
|
||||
/>
|
||||
</div>
|
||||
<el-scrollbar max-height="40rem">
|
||||
<div class="mt-2 border-2 border-gray-300" v-for="item in input">
|
||||
<div style="font-size: 1.2rem" class="w-full text-center font-bold">
|
||||
{{ item.label }}
|
||||
</div>
|
||||
<SingleAdd ref="singleAddRef" :addData="addData" />
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import SingleAdd from "./singleAdd.vue";
|
||||
|
||||
const singleFormNum = ref(1);
|
||||
const checked = ref(true);
|
||||
const input = ref([{ label: "管理员1" }]);
|
||||
const singleAddRef = ref(null);
|
||||
const formClone = ref([]);
|
||||
|
||||
const props = defineProps({
|
||||
checkNeed: Boolean,
|
||||
addData: Object,
|
||||
});
|
||||
|
||||
const emit = defineEmits(["addAdmin"]);
|
||||
|
||||
const initData = () => {
|
||||
setTimeout(() => {
|
||||
singleAddRef.value.forEach((item) => {
|
||||
item.ruleForm.role = singleAddRef.value[0].ruleForm.role;
|
||||
});
|
||||
}, 100);
|
||||
};
|
||||
|
||||
const createForm = () => {
|
||||
let difference = Math.abs(singleFormNum.value - input.value.length);
|
||||
for (let i = 0; i < difference; i++) {
|
||||
if (singleFormNum.value > input.value.length) {
|
||||
input.value.push({ label: `管理员${input.value.length + 1}` });
|
||||
} else if (singleFormNum.value < input.value.length) {
|
||||
input.value.pop();
|
||||
}
|
||||
}
|
||||
if (checked.value) {
|
||||
initData();
|
||||
}
|
||||
};
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!singleAddRef) return;
|
||||
singleAddRef.value.forEach((element) => {
|
||||
element.resetCheckForm();
|
||||
});
|
||||
singleFormNum.value = 1;
|
||||
createForm();
|
||||
};
|
||||
|
||||
const confirm = () => {
|
||||
if (!singleAddRef) return;
|
||||
let valid = true;
|
||||
formClone.value = [];
|
||||
singleAddRef.value.forEach((element) => {
|
||||
element.validate().then((result) => {
|
||||
if (result) {
|
||||
formClone.value.push({ ...element.ruleForm });
|
||||
} else {
|
||||
valid = result;
|
||||
}
|
||||
});
|
||||
});
|
||||
setTimeout(() => {
|
||||
if (valid) {
|
||||
emit("addAdmin", formClone.value);
|
||||
singleAddRef.value.forEach((item) => {
|
||||
item.resetCheckForm();
|
||||
});
|
||||
ElMessage({
|
||||
message: `提交成功!`,
|
||||
type: "success",
|
||||
});
|
||||
} else {
|
||||
ElMessage.error("提交失败!");
|
||||
}
|
||||
}, 100);
|
||||
};
|
||||
|
||||
defineExpose({ resetCheckForm, confirm, formClone });
|
||||
|
||||
watch(checked, (value) => {
|
||||
if (value) {
|
||||
initData();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
110
src/components/addNewData/adminForm/singleAdd.vue
Normal file
110
src/components/addNewData/adminForm/singleAdd.vue
Normal file
@@ -0,0 +1,110 @@
|
||||
<template>
|
||||
<el-form
|
||||
ref="ruleFormRef"
|
||||
style="max-width: 600px"
|
||||
:model="ruleForm"
|
||||
:rules="rules"
|
||||
label-width="auto"
|
||||
size="default"
|
||||
status-icon
|
||||
class="mx-auto"
|
||||
>
|
||||
<el-form-item class="mx-1 font-bold" label="账号名" prop="account_name">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入账号名"
|
||||
minlength="2"
|
||||
maxlength="5"
|
||||
v-model="ruleForm.account_name"
|
||||
@input="filter(ruleForm.account_name, 'account_name')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="权限等级" prop="role">
|
||||
<el-select
|
||||
clearable
|
||||
size="small"
|
||||
placeholder="请选择权限等级"
|
||||
autocomplete="off"
|
||||
v-model="ruleForm.role"
|
||||
style="width: 100%; font-size: 1rem"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in addData.roleOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
class="text-center"
|
||||
:style="item.style"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
const ruleFormRef = ref(null);
|
||||
|
||||
const ruleForm = reactive({
|
||||
account_name: "",
|
||||
role: "",
|
||||
});
|
||||
|
||||
const formClone = ref({});
|
||||
|
||||
const rules = reactive({
|
||||
account_name: [{ required: true, message: "请输入账号名", trigger: "blur" }],
|
||||
role: [{ required: true, message: "请选择权限等级", trigger: "change" }],
|
||||
});
|
||||
|
||||
const emit = defineEmits(["addAdmin"]);
|
||||
|
||||
const filter = (value, label) => {
|
||||
if (/[=\s"'+-]/.test(value)) {
|
||||
if (ruleForm[label]) {
|
||||
ruleForm[label] = value.replace(/[=\s"'+-]/g, "");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const props = defineProps({
|
||||
addData: Object,
|
||||
});
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!ruleFormRef) return;
|
||||
ruleFormRef.value.resetFields();
|
||||
};
|
||||
|
||||
const confirm = async () => {
|
||||
if (!ruleFormRef) return;
|
||||
await ruleFormRef.value.validate((valid) => {
|
||||
if (valid) {
|
||||
formClone.value = { ...ruleForm };
|
||||
emit("addAdmin", [formClone.value]);
|
||||
ruleFormRef.value.resetFields();
|
||||
ElMessage({
|
||||
message: `提交成功!`,
|
||||
type: "success",
|
||||
});
|
||||
} else {
|
||||
ElMessage.error("提交失败!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const validate = () => {
|
||||
if (!ruleFormRef) return Promise.resolve(false);
|
||||
return new Promise((resolve) => {
|
||||
ruleFormRef.value.validate((valid) => {
|
||||
resolve(valid);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ resetCheckForm, confirm, validate, ruleForm, formClone });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
179
src/components/addNewData/applicationForm/applicationForm.vue
Normal file
179
src/components/addNewData/applicationForm/applicationForm.vue
Normal file
@@ -0,0 +1,179 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:show-close="false"
|
||||
style="width: 80%"
|
||||
center
|
||||
align-center
|
||||
:before-close="resetCheckForm"
|
||||
>
|
||||
<template #header="{ titleId, titleClass }">
|
||||
<div
|
||||
style="font-size: 2rem"
|
||||
class="w-full font-bold"
|
||||
:id="titleId"
|
||||
:class="titleClass"
|
||||
>
|
||||
{{ title }}
|
||||
</div>
|
||||
<div
|
||||
@click="resetCheckForm"
|
||||
class="bg-gray-400 hover:bg-red-600 text-3xl absolute top-0 right-0 cursor-pointer flex justify-center items-center"
|
||||
>
|
||||
<el-icon>
|
||||
<CloseBold />
|
||||
</el-icon>
|
||||
</div>
|
||||
</template>
|
||||
<FormTools @showTools="showTools" :dialogObj="applicationMsgActive" />
|
||||
<SingleAdd
|
||||
ref="singleAddRef"
|
||||
v-if="dialogSingleVisible"
|
||||
:addData="addData"
|
||||
@addApplication="addApplication"
|
||||
/>
|
||||
<MultipleAdd
|
||||
ref="multipleAddRef"
|
||||
v-if="dialogMultipleVisible"
|
||||
:checkNeed="true"
|
||||
:addData="addData"
|
||||
@addApplication="addApplication"
|
||||
/>
|
||||
<ExcleAdd
|
||||
ref="excleAddRef"
|
||||
v-if="dialogExcleVisible"
|
||||
@addApplication="addApplication"
|
||||
/>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button style="font-weight: bold" @click="resetCheckForm"> 取消 </el-button>
|
||||
<el-button style="font-weight: bold" type="primary" @click="confirm">
|
||||
确定
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { CloseBold } from "@element-plus/icons-vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import FormTools from "../../operate/formTools.vue";
|
||||
import SingleAdd from "./singleAdd.vue";
|
||||
import MultipleAdd from "./multipleAdd.vue";
|
||||
import ExcleAdd from "./excleAdd.vue";
|
||||
|
||||
import applicationActiveStore from "../../../stores/applicationMsg";
|
||||
|
||||
import $http from "../../../api/index";
|
||||
import $url from "../../../api/url";
|
||||
|
||||
import { encrypt } from "../../../utils/aes";
|
||||
|
||||
const applicationMsgActive = applicationActiveStore();
|
||||
|
||||
const dialogVisible = ref(false);
|
||||
const singleAddRef = ref(null);
|
||||
const multipleAddRef = ref(null);
|
||||
const excleAddRef = ref(null);
|
||||
const dialogSingleVisible = ref(true);
|
||||
const dialogMultipleVisible = ref(false);
|
||||
const dialogExcleVisible = ref(false);
|
||||
|
||||
const props = defineProps({
|
||||
title: String,
|
||||
addData: Object,
|
||||
});
|
||||
|
||||
const emit = defineEmits(["reloadData"]);
|
||||
|
||||
const showTools = (operateType) => {
|
||||
switch (operateType) {
|
||||
case "single":
|
||||
dialogSingleVisible.value = true;
|
||||
dialogMultipleVisible.value = false;
|
||||
dialogExcleVisible.value = false;
|
||||
applicationMsgActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
applicationMsgActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
applicationMsgActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
case "multiple":
|
||||
dialogSingleVisible.value = false;
|
||||
dialogMultipleVisible.value = true;
|
||||
dialogExcleVisible.value = false;
|
||||
applicationMsgActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
applicationMsgActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
applicationMsgActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
case "excle":
|
||||
dialogSingleVisible.value = false;
|
||||
dialogMultipleVisible.value = false;
|
||||
dialogExcleVisible.value = true;
|
||||
applicationMsgActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
applicationMsgActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
applicationMsgActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (dialogSingleVisible.value) {
|
||||
singleAddRef.value.resetCheckForm();
|
||||
} else if (dialogMultipleVisible.value) {
|
||||
multipleAddRef.value.resetCheckForm();
|
||||
} else if (dialogExcleVisible.value) {
|
||||
excleAddRef.value.resetCheckForm();
|
||||
}
|
||||
dialogVisible.value = false;
|
||||
};
|
||||
|
||||
const confirm = () => {
|
||||
if (dialogSingleVisible.value) {
|
||||
singleAddRef.value.confirm();
|
||||
} else if (dialogMultipleVisible.value) {
|
||||
multipleAddRef.value.confirm();
|
||||
} else if (dialogExcleVisible.value) {
|
||||
excleAddRef.value.confirm();
|
||||
}
|
||||
};
|
||||
|
||||
const addApplication = (requestMsg) => {
|
||||
requestMsg.forEach((element) => {
|
||||
element.identity_card = encrypt(String(element.identity_card));
|
||||
element.user_name = encrypt(String(element.user_name));
|
||||
element.exam_uid = encrypt(String(element.exam_uid));
|
||||
element.source = encrypt(String(element.source));
|
||||
element.status = encrypt(String(element.status));
|
||||
element.pay_status = encrypt(String(element.pay_status));
|
||||
element.result = encrypt(String(element.result));
|
||||
});
|
||||
const data = { requestMsg };
|
||||
$http.post($url.addApplication, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
resetCheckForm();
|
||||
ElMessage({
|
||||
message: "新增考生报名信息成功!",
|
||||
type: "success",
|
||||
});
|
||||
emit("reloadData");
|
||||
} else if (res.data.code === 300) {
|
||||
resetCheckForm();
|
||||
ElMessage({
|
||||
message: "新增部分考生报名信息成功,请查看新增失败的数据以查找原因!",
|
||||
type: "warning",
|
||||
});
|
||||
emit("reloadData");
|
||||
} else {
|
||||
ElMessage.error("新增考生报名信息失败!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ dialogVisible });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
142
src/components/addNewData/applicationForm/excleAdd.vue
Normal file
142
src/components/addNewData/applicationForm/excleAdd.vue
Normal file
@@ -0,0 +1,142 @@
|
||||
<template>
|
||||
<UploadFile
|
||||
ref="uploadFileRef"
|
||||
:options="options"
|
||||
:relatedRules="relatedRules"
|
||||
:relatedOptions="relatedOptions"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import UploadFile from "../../operate/uploadFile.vue";
|
||||
|
||||
const uploadFileRef = ref(null);
|
||||
const formClone = ref([]);
|
||||
|
||||
const options = {
|
||||
limit: 1,
|
||||
accept: ".xlsx",
|
||||
action: "",
|
||||
multiple: false,
|
||||
listType: "text",
|
||||
autoUpload: false,
|
||||
};
|
||||
|
||||
const relatedRules = {
|
||||
identity_card: {
|
||||
value: "",
|
||||
label: "考生身份证号",
|
||||
},
|
||||
user_name: {
|
||||
value: "",
|
||||
label: "考生姓名",
|
||||
},
|
||||
exam_uid: {
|
||||
value: "",
|
||||
label: "考试uid",
|
||||
},
|
||||
source: {
|
||||
value: "",
|
||||
label: "报名来源",
|
||||
},
|
||||
status: {
|
||||
value: "",
|
||||
label: "报名状态",
|
||||
},
|
||||
pay_status: {
|
||||
value: "",
|
||||
label: "缴费状态",
|
||||
},
|
||||
result: {
|
||||
value: "",
|
||||
label: "报名结果说明",
|
||||
},
|
||||
};
|
||||
|
||||
const relatedOptions = [
|
||||
{
|
||||
value: "0",
|
||||
label: "考生身份证号",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "1",
|
||||
label: "考生姓名",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "2",
|
||||
label: "考试uid",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "3",
|
||||
label: "报名来源",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "4",
|
||||
label: "报名状态",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "5",
|
||||
label: "缴费状态",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "6",
|
||||
label: "报名结果说明",
|
||||
disabled: false,
|
||||
},
|
||||
];
|
||||
|
||||
const emit = defineEmits(["addApplication"]);
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!uploadFileRef) return;
|
||||
uploadFileRef.value.handleExceed();
|
||||
};
|
||||
|
||||
const confirm = async () => {
|
||||
if (!uploadFileRef) return;
|
||||
formClone.value = [];
|
||||
const length = uploadFileRef.value.loadData.length;
|
||||
if (length == 0) return ElMessage.error("请先上传文件!");
|
||||
const flag = await uploadFileRef.value.confirm();
|
||||
if (!flag) return ElMessage.error("请先选择表格关联项!");
|
||||
ElMessage({
|
||||
message: `正在上传数据中,请稍等...`,
|
||||
type: "success",
|
||||
});
|
||||
setTimeout(() => {
|
||||
uploadFileRef.value.loadData.forEach((ExcleForm) => {
|
||||
ExcleForm.forEach((worksheet) => {
|
||||
let context = [...worksheet];
|
||||
context.shift();
|
||||
context.forEach((item) => {
|
||||
if (item.length != 0) {
|
||||
formClone.value.push({
|
||||
identity_card: item[relatedRules.identity_card.value],
|
||||
user_name: item[relatedRules.user_name.value],
|
||||
exam_uid: item[relatedRules.exam_uid.value],
|
||||
source: item[relatedRules.source.value],
|
||||
status: item[relatedRules.status.value],
|
||||
pay_status: item[relatedRules.pay_status.value],
|
||||
result: item[relatedRules.result.value],
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
emit("addApplication", formClone.value);
|
||||
}, 3000);
|
||||
};
|
||||
|
||||
defineExpose({ resetCheckForm, confirm, formClone });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
119
src/components/addNewData/applicationForm/multipleAdd.vue
Normal file
119
src/components/addNewData/applicationForm/multipleAdd.vue
Normal file
@@ -0,0 +1,119 @@
|
||||
<template>
|
||||
<div>
|
||||
<div
|
||||
style="font-size: 2rem"
|
||||
class="flex flex-warp justify-center items-center font-bold"
|
||||
>
|
||||
<div style="font-size: 1rem">请输入要导入的数据数量:</div>
|
||||
<el-input-number v-model="singleFormNum" :min="1" :max="10" @change="createForm" />
|
||||
<div v-if="checkNeed"> </div>
|
||||
<el-checkbox
|
||||
v-if="checkNeed"
|
||||
v-model="checked"
|
||||
label="为所有表单进行相同操作"
|
||||
size="large"
|
||||
/>
|
||||
</div>
|
||||
<el-scrollbar max-height="40rem">
|
||||
<div class="mt-2 border-2 border-gray-300" v-for="item in input">
|
||||
<div style="font-size: 1.2rem" class="w-full text-center font-bold">
|
||||
{{ item.label }}
|
||||
</div>
|
||||
<SingleAdd ref="singleAddRef" :addData="addData" />
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import SingleAdd from "./singleAdd.vue";
|
||||
|
||||
const singleFormNum = ref(1);
|
||||
const checked = ref(true);
|
||||
const input = ref([{ label: "报名数据1" }]);
|
||||
const singleAddRef = ref(null);
|
||||
const formClone = ref([]);
|
||||
|
||||
const props = defineProps({
|
||||
checkNeed: Boolean,
|
||||
addData: Object,
|
||||
});
|
||||
|
||||
const emit = defineEmits(["addApplication"]);
|
||||
|
||||
const initData = () => {
|
||||
setTimeout(() => {
|
||||
singleAddRef.value.forEach((item) => {
|
||||
item.ruleForm.source = singleAddRef.value[0].ruleForm.source;
|
||||
item.ruleForm.status = singleAddRef.value[0].ruleForm.status;
|
||||
item.ruleForm.pay_status = singleAddRef.value[0].ruleForm.pay_status;
|
||||
item.ruleForm.result = singleAddRef.value[0].ruleForm.result;
|
||||
});
|
||||
}, 100);
|
||||
};
|
||||
|
||||
const createForm = () => {
|
||||
let difference = Math.abs(singleFormNum.value - input.value.length);
|
||||
for (let i = 0; i < difference; i++) {
|
||||
if (singleFormNum.value > input.value.length) {
|
||||
input.value.push({ label: `报名数据${input.value.length + 1}` });
|
||||
} else if (singleFormNum.value < input.value.length) {
|
||||
input.value.pop();
|
||||
}
|
||||
}
|
||||
if (checked.value) {
|
||||
initData();
|
||||
}
|
||||
};
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!singleAddRef) return;
|
||||
singleAddRef.value.forEach((element) => {
|
||||
element.resetCheckForm();
|
||||
});
|
||||
singleFormNum.value = 1;
|
||||
createForm();
|
||||
};
|
||||
|
||||
const confirm = () => {
|
||||
if (!singleAddRef) return;
|
||||
let valid = true;
|
||||
formClone.value = [];
|
||||
singleAddRef.value.forEach((element) => {
|
||||
element.validate().then((result) => {
|
||||
if (result) {
|
||||
formClone.value.push({ ...element.ruleForm });
|
||||
} else {
|
||||
valid = result;
|
||||
}
|
||||
});
|
||||
});
|
||||
setTimeout(() => {
|
||||
if (valid) {
|
||||
emit("addApplication", formClone.value);
|
||||
singleAddRef.value.forEach((item) => {
|
||||
item.resetCheckForm();
|
||||
});
|
||||
ElMessage({
|
||||
message: `提交成功!`,
|
||||
type: "success",
|
||||
});
|
||||
} else {
|
||||
ElMessage.error("提交失败!");
|
||||
}
|
||||
}, 100);
|
||||
};
|
||||
|
||||
defineExpose({ resetCheckForm, confirm, formClone });
|
||||
|
||||
watch(checked, (value) => {
|
||||
if (value) {
|
||||
initData();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
282
src/components/addNewData/applicationForm/singleAdd.vue
Normal file
282
src/components/addNewData/applicationForm/singleAdd.vue
Normal file
@@ -0,0 +1,282 @@
|
||||
<template>
|
||||
<el-form
|
||||
ref="ruleFormRef"
|
||||
style="max-width: 600px"
|
||||
:model="ruleForm"
|
||||
:rules="rules"
|
||||
label-width="auto"
|
||||
size="default"
|
||||
status-icon
|
||||
class="mx-auto"
|
||||
>
|
||||
<el-form-item class="mx-1 font-bold" label="考生姓名" prop="user_name">
|
||||
<el-autocomplete
|
||||
:fetch-suggestions="searchUserName"
|
||||
clearable
|
||||
placeholder="请输入考生姓名"
|
||||
minlength="1"
|
||||
maxlength="6"
|
||||
v-model="ruleForm.user_name"
|
||||
@input="filter(ruleForm.user_name, 'user_name')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="身份证号" prop="identity_card">
|
||||
<el-autocomplete
|
||||
:fetch-suggestions="searchIdentityCard"
|
||||
clearable
|
||||
placeholder="请输入身份证号"
|
||||
minlength="18"
|
||||
maxlength="18"
|
||||
v-model="ruleForm.identity_card"
|
||||
@input="filter(ruleForm.identity_card, 'identity_card')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="考试uid" prop="exam_uid">
|
||||
<el-autocomplete
|
||||
:fetch-suggestions="searchExamUid"
|
||||
clearable
|
||||
placeholder="请输入考试uid"
|
||||
minlength="10"
|
||||
maxlength="10"
|
||||
v-model="ruleForm.exam_uid"
|
||||
@input="filter(ruleForm.exam_uid, 'exam_uid')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="报名来源" prop="source">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入报名来源"
|
||||
maxlength="24"
|
||||
v-model="ruleForm.source"
|
||||
@input="filter(ruleForm.source, 'source')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="报名状态" prop="status">
|
||||
<el-select
|
||||
clearable
|
||||
size="small"
|
||||
placeholder="请选择报名状态"
|
||||
autocomplete="off"
|
||||
v-model="ruleForm.status"
|
||||
style="width: 100%; font-size: 1rem"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in addData.statusOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
class="text-center"
|
||||
:style="item.style"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="缴费状态" prop="pay_status">
|
||||
<el-select
|
||||
clearable
|
||||
size="small"
|
||||
placeholder="请选择缴费状态"
|
||||
autocomplete="off"
|
||||
v-model="ruleForm.pay_status"
|
||||
style="width: 100%; font-size: 1rem"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in addData.payStatusOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
class="text-center"
|
||||
:style="item.style"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="报名结果说明" prop="result">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入报名结果说明"
|
||||
maxlength="24"
|
||||
v-model="ruleForm.result"
|
||||
@input="filter(ruleForm.result, 'result')"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import $http from "../../../api/index";
|
||||
import $url from "../../../api/url";
|
||||
|
||||
const ruleFormRef = ref(null);
|
||||
|
||||
const ruleForm = reactive({
|
||||
user_name: "",
|
||||
identity_card: "",
|
||||
exam_uid: "",
|
||||
source: "",
|
||||
status: "",
|
||||
pay_status: "",
|
||||
result: "",
|
||||
});
|
||||
|
||||
const formClone = ref({});
|
||||
|
||||
const identityCardRegex = /^[1-9](?:\d{5})(?:19|20)?\d{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12]\d|3[01])\d{3}(?:\d|X|x)$/;
|
||||
|
||||
const searchUserName = (value, cb) => {
|
||||
const data = {
|
||||
user_name: value,
|
||||
};
|
||||
$http.post($url.searchUserName, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
cb(res.data.data);
|
||||
} else {
|
||||
cb([]);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const validateUserName = (rule, value, callback) => {
|
||||
if (value === "") {
|
||||
callback(new Error("请输入考生姓名"));
|
||||
} else {
|
||||
const data = {
|
||||
user_name: value,
|
||||
};
|
||||
$http.post($url.findUserName, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
callback();
|
||||
} else {
|
||||
callback(new Error("该考生不存在!"));
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const searchIdentityCard = (value, cb) => {
|
||||
const data = {
|
||||
identity_card: value,
|
||||
};
|
||||
$http.post($url.searchIdentityCard, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
cb(res.data.data);
|
||||
} else {
|
||||
cb([]);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const validateIdentityCard = (rule, value, callback) => {
|
||||
if (value === "") {
|
||||
callback(new Error("请输入身份证号"));
|
||||
} else if (!identityCardRegex.test(value)) {
|
||||
callback(new Error("身份证格式不正确,请重新输入!"));
|
||||
} else if (ruleForm.user_name == "") {
|
||||
callback(new Error("请输入考生姓名"));
|
||||
} else {
|
||||
const data = {
|
||||
identity_card: value,
|
||||
user_name: ruleForm.user_name,
|
||||
};
|
||||
$http.post($url.findIdentityCard, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
callback();
|
||||
} else if (res.data.code === 303) {
|
||||
callback(new Error("考生身份证号码与考生姓名不匹配!"));
|
||||
} else {
|
||||
callback(new Error("该考生身份证号未注册!"));
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const searchExamUid = (value, cb) => {
|
||||
const data = {
|
||||
exam_uid: value,
|
||||
};
|
||||
$http.post($url.searchExamUid, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
cb(res.data.data);
|
||||
} else {
|
||||
cb([]);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const validateExamUid = (rule, value, callback) => {
|
||||
if (value === "") {
|
||||
callback(new Error("请输入考试uid"));
|
||||
} else {
|
||||
const data = {
|
||||
exam_uid: value,
|
||||
};
|
||||
$http.post($url.findExamUid, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
callback();
|
||||
} else {
|
||||
callback(new Error("该考试不存在!"));
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const rules = reactive({
|
||||
identity_card: [{ required: true, validator: validateIdentityCard, trigger: "blur" }],
|
||||
user_name: [{ required: true, validator: validateUserName, trigger: "blur" }],
|
||||
exam_uid: [{ required: true, validator: validateExamUid, trigger: "blur" }],
|
||||
source: [{ required: true, message: "请输入报名来源", trigger: "blur" }],
|
||||
status: [{ required: true, message: "请选择报名状态", trigger: "change" }],
|
||||
pay_status: [{ required: true, message: "请选择缴费状态", trigger: "change" }],
|
||||
result: [{ required: true, message: "请输入报名结果说明", trigger: "blur" }],
|
||||
});
|
||||
|
||||
const emit = defineEmits(["addApplication"]);
|
||||
|
||||
const filter = (value, label) => {
|
||||
if (/[=\s"'+-]/.test(value)) {
|
||||
if (ruleForm[label]) {
|
||||
ruleForm[label] = value.replace(/[=\s"'+-]/g, "");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const props = defineProps({
|
||||
addData: Object,
|
||||
});
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!ruleFormRef) return;
|
||||
ruleFormRef.value.resetFields();
|
||||
};
|
||||
|
||||
const confirm = async () => {
|
||||
if (!ruleFormRef) return;
|
||||
await ruleFormRef.value.validate((valid) => {
|
||||
if (valid) {
|
||||
formClone.value = { ...ruleForm };
|
||||
emit("addApplication", [formClone.value]);
|
||||
ruleFormRef.value.resetFields();
|
||||
ElMessage({
|
||||
message: `提交成功!`,
|
||||
type: "success",
|
||||
});
|
||||
} else {
|
||||
ElMessage.error("提交失败!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const validate = () => {
|
||||
if (!ruleFormRef) return Promise.resolve(false);
|
||||
return new Promise((resolve) => {
|
||||
ruleFormRef.value.validate((valid) => {
|
||||
resolve(valid);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ resetCheckForm, confirm, validate, ruleForm, formClone });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
168
src/components/addNewData/examForm/examForm.vue
Normal file
168
src/components/addNewData/examForm/examForm.vue
Normal file
@@ -0,0 +1,168 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:show-close="false"
|
||||
style="width: 80%"
|
||||
center
|
||||
align-center
|
||||
:before-close="resetCheckForm"
|
||||
>
|
||||
<template #header="{ titleId, titleClass }">
|
||||
<div
|
||||
style="font-size: 2rem"
|
||||
class="w-full font-bold"
|
||||
:id="titleId"
|
||||
:class="titleClass"
|
||||
>
|
||||
{{ title }}
|
||||
</div>
|
||||
<div
|
||||
@click="resetCheckForm"
|
||||
class="bg-gray-400 hover:bg-red-600 text-3xl absolute top-0 right-0 cursor-pointer flex justify-center items-center"
|
||||
>
|
||||
<el-icon>
|
||||
<CloseBold />
|
||||
</el-icon>
|
||||
</div>
|
||||
</template>
|
||||
<FormTools @showTools="showTools" :dialogObj="examMsgActive" />
|
||||
<SingleAdd
|
||||
ref="singleAddRef"
|
||||
v-if="dialogSingleVisible"
|
||||
:addData="addData"
|
||||
@addExam="addExam"
|
||||
/>
|
||||
<MultipleAdd
|
||||
ref="multipleAddRef"
|
||||
v-if="dialogMultipleVisible"
|
||||
:checkNeed="true"
|
||||
:addData="addData"
|
||||
@addExam="addExam"
|
||||
/>
|
||||
<ExcleAdd ref="excleAddRef" v-if="dialogExcleVisible" @addExam="addExam" />
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button style="font-weight: bold" @click="resetCheckForm"> 取消 </el-button>
|
||||
<el-button style="font-weight: bold" type="primary" @click="confirm">
|
||||
确定
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { CloseBold } from "@element-plus/icons-vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import FormTools from "../../operate/formTools.vue";
|
||||
import SingleAdd from "./singleAdd.vue";
|
||||
import MultipleAdd from "./multipleAdd.vue";
|
||||
import ExcleAdd from "./excleAdd.vue";
|
||||
|
||||
import examActiveStore from "../../../stores/examMsg";
|
||||
|
||||
import $http from "../../../api/index";
|
||||
import $url from "../../../api/url";
|
||||
|
||||
import { encrypt } from "../../../utils/aes";
|
||||
|
||||
const examMsgActive = examActiveStore();
|
||||
|
||||
const dialogVisible = ref(false);
|
||||
const singleAddRef = ref(null);
|
||||
const multipleAddRef = ref(null);
|
||||
const excleAddRef = ref(null);
|
||||
const dialogSingleVisible = ref(true);
|
||||
const dialogMultipleVisible = ref(false);
|
||||
const dialogExcleVisible = ref(false);
|
||||
|
||||
const props = defineProps({
|
||||
title: String,
|
||||
addData: Object,
|
||||
});
|
||||
|
||||
const emit = defineEmits(["reloadData"]);
|
||||
|
||||
const showTools = (operateType) => {
|
||||
switch (operateType) {
|
||||
case "single":
|
||||
dialogSingleVisible.value = true;
|
||||
dialogMultipleVisible.value = false;
|
||||
dialogExcleVisible.value = false;
|
||||
examMsgActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
examMsgActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
examMsgActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
case "multiple":
|
||||
dialogSingleVisible.value = false;
|
||||
dialogMultipleVisible.value = true;
|
||||
dialogExcleVisible.value = false;
|
||||
examMsgActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
examMsgActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
examMsgActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
case "excle":
|
||||
dialogSingleVisible.value = false;
|
||||
dialogMultipleVisible.value = false;
|
||||
dialogExcleVisible.value = true;
|
||||
examMsgActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
examMsgActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
examMsgActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (dialogSingleVisible.value) {
|
||||
singleAddRef.value.resetCheckForm();
|
||||
} else if (dialogMultipleVisible.value) {
|
||||
multipleAddRef.value.resetCheckForm();
|
||||
} else if (dialogExcleVisible.value) {
|
||||
excleAddRef.value.resetCheckForm();
|
||||
}
|
||||
dialogVisible.value = false;
|
||||
};
|
||||
|
||||
const confirm = () => {
|
||||
if (dialogSingleVisible.value) {
|
||||
singleAddRef.value.confirm();
|
||||
} else if (dialogMultipleVisible.value) {
|
||||
multipleAddRef.value.confirm();
|
||||
} else if (dialogExcleVisible.value) {
|
||||
excleAddRef.value.confirm();
|
||||
}
|
||||
};
|
||||
|
||||
const addExam = (requestMsg) => {
|
||||
requestMsg.forEach((element) => {
|
||||
element.uid = encrypt(String(element.uid));
|
||||
element.exam_name = encrypt(String(element.exam_name));
|
||||
element.status = encrypt(String(element.status));
|
||||
element.application_start = new Date(element.application_start);
|
||||
element.application_end = new Date(element.application_end);
|
||||
element.exam_start = new Date(element.exam_start);
|
||||
element.exam_end = new Date(element.exam_end);
|
||||
});
|
||||
const data = { requestMsg };
|
||||
$http.post($url.addExam, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
resetCheckForm();
|
||||
ElMessage({
|
||||
message: "新增考试信息成功!",
|
||||
type: "success",
|
||||
});
|
||||
emit("reloadData");
|
||||
} else {
|
||||
ElMessage.error("新增考试信息失败!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ dialogVisible });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
142
src/components/addNewData/examForm/excleAdd.vue
Normal file
142
src/components/addNewData/examForm/excleAdd.vue
Normal file
@@ -0,0 +1,142 @@
|
||||
<template>
|
||||
<UploadFile
|
||||
ref="uploadFileRef"
|
||||
:options="options"
|
||||
:relatedRules="relatedRules"
|
||||
:relatedOptions="relatedOptions"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import UploadFile from "../../operate/uploadFile.vue";
|
||||
|
||||
const uploadFileRef = ref(null);
|
||||
const formClone = ref([]);
|
||||
|
||||
const options = {
|
||||
limit: 1,
|
||||
accept: ".xlsx",
|
||||
action: "",
|
||||
multiple: false,
|
||||
listType: "text",
|
||||
autoUpload: false,
|
||||
};
|
||||
|
||||
const relatedRules = {
|
||||
uid: {
|
||||
value: "",
|
||||
label: "考试uid",
|
||||
},
|
||||
exam_name: {
|
||||
value: "",
|
||||
label: "考试名称",
|
||||
},
|
||||
status: {
|
||||
value: "",
|
||||
label: "考试状态",
|
||||
},
|
||||
application_start: {
|
||||
value: "",
|
||||
label: "报名开始时间",
|
||||
},
|
||||
application_end: {
|
||||
value: "",
|
||||
label: "报名结束时间",
|
||||
},
|
||||
exam_start: {
|
||||
value: "",
|
||||
label: "考试开始时间",
|
||||
},
|
||||
exam_end: {
|
||||
value: "",
|
||||
label: "考试结束时间",
|
||||
},
|
||||
};
|
||||
|
||||
const relatedOptions = [
|
||||
{
|
||||
value: "0",
|
||||
label: "考试uid",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "1",
|
||||
label: "考试名称",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "2",
|
||||
label: "考试状态",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "3",
|
||||
label: "报名开始时间",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "4",
|
||||
label: "报名结束时间",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "5",
|
||||
label: "考试开始时间",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "6",
|
||||
label: "考试结束时间",
|
||||
disabled: false,
|
||||
},
|
||||
];
|
||||
|
||||
const emit = defineEmits(["addExam"]);
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!uploadFileRef) return;
|
||||
uploadFileRef.value.handleExceed();
|
||||
};
|
||||
|
||||
const confirm = async () => {
|
||||
if (!uploadFileRef) return;
|
||||
formClone.value = [];
|
||||
const length = uploadFileRef.value.loadData.length;
|
||||
if (length == 0) return ElMessage.error("请先上传文件!");
|
||||
const flag = await uploadFileRef.value.confirm();
|
||||
if (!flag) return ElMessage.error("请先选择表格关联项!");
|
||||
ElMessage({
|
||||
message: `正在上传数据中,请稍等...`,
|
||||
type: "success",
|
||||
});
|
||||
setTimeout(() => {
|
||||
uploadFileRef.value.loadData.forEach((ExcleForm) => {
|
||||
ExcleForm.forEach((worksheet) => {
|
||||
let context = [...worksheet];
|
||||
context.shift();
|
||||
context.forEach((item) => {
|
||||
if (item.length != 0) {
|
||||
formClone.value.push({
|
||||
uid: item[relatedRules.uid.value],
|
||||
exam_name: item[relatedRules.exam_name.value],
|
||||
status: item[relatedRules.status.value],
|
||||
application_start: item[relatedRules.application_start.value],
|
||||
application_end: item[relatedRules.application_end.value],
|
||||
exam_start: item[relatedRules.exam_start.value],
|
||||
exam_end: item[relatedRules.exam_end.value],
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
emit("addExam", formClone.value);
|
||||
}, 3000);
|
||||
};
|
||||
|
||||
defineExpose({ resetCheckForm, confirm, formClone });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
116
src/components/addNewData/examForm/multipleAdd.vue
Normal file
116
src/components/addNewData/examForm/multipleAdd.vue
Normal file
@@ -0,0 +1,116 @@
|
||||
<template>
|
||||
<div>
|
||||
<div
|
||||
style="font-size: 2rem"
|
||||
class="flex flex-warp justify-center items-center font-bold"
|
||||
>
|
||||
<div style="font-size: 1rem">请输入要导入的数据数量:</div>
|
||||
<el-input-number v-model="singleFormNum" :min="1" :max="10" @change="createForm" />
|
||||
<div v-if="checkNeed"> </div>
|
||||
<el-checkbox
|
||||
v-if="checkNeed"
|
||||
v-model="checked"
|
||||
label="为所有表单进行相同操作"
|
||||
size="large"
|
||||
/>
|
||||
</div>
|
||||
<el-scrollbar max-height="40rem">
|
||||
<div class="mt-2 border-2 border-gray-300" v-for="item in input">
|
||||
<div style="font-size: 1.2rem" class="w-full text-center font-bold">
|
||||
{{ item.label }}
|
||||
</div>
|
||||
<SingleAdd ref="singleAddRef" :addData="addData" />
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import SingleAdd from "./singleAdd.vue";
|
||||
|
||||
const singleFormNum = ref(1);
|
||||
const checked = ref(true);
|
||||
const input = ref([{ label: "考试1" }]);
|
||||
const singleAddRef = ref(null);
|
||||
const formClone = ref([]);
|
||||
|
||||
const props = defineProps({
|
||||
checkNeed: Boolean,
|
||||
addData: Object,
|
||||
});
|
||||
|
||||
const emit = defineEmits(["addExam"]);
|
||||
|
||||
const initData = () => {
|
||||
setTimeout(() => {
|
||||
singleAddRef.value.forEach((item) => {
|
||||
item.ruleForm.status = singleAddRef.value[0].ruleForm.status;
|
||||
});
|
||||
}, 100);
|
||||
};
|
||||
|
||||
const createForm = () => {
|
||||
let difference = Math.abs(singleFormNum.value - input.value.length);
|
||||
for (let i = 0; i < difference; i++) {
|
||||
if (singleFormNum.value > input.value.length) {
|
||||
input.value.push({ label: `考试${input.value.length + 1}` });
|
||||
} else if (singleFormNum.value < input.value.length) {
|
||||
input.value.pop();
|
||||
}
|
||||
}
|
||||
if (checked.value) {
|
||||
initData();
|
||||
}
|
||||
};
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!singleAddRef) return;
|
||||
singleAddRef.value.forEach((element) => {
|
||||
element.resetCheckForm();
|
||||
});
|
||||
singleFormNum.value = 1;
|
||||
createForm();
|
||||
};
|
||||
|
||||
const confirm = () => {
|
||||
if (!singleAddRef) return;
|
||||
let valid = true;
|
||||
formClone.value = [];
|
||||
singleAddRef.value.forEach((element) => {
|
||||
element.validate().then((result) => {
|
||||
if (result) {
|
||||
formClone.value.push({ ...element.ruleForm });
|
||||
} else {
|
||||
valid = result;
|
||||
}
|
||||
});
|
||||
});
|
||||
setTimeout(() => {
|
||||
if (valid) {
|
||||
emit("addExam", formClone.value);
|
||||
singleAddRef.value.forEach((item) => {
|
||||
item.resetCheckForm();
|
||||
});
|
||||
ElMessage({
|
||||
message: `提交成功!`,
|
||||
type: "success",
|
||||
});
|
||||
} else {
|
||||
ElMessage.error("提交失败!");
|
||||
}
|
||||
}, 100);
|
||||
};
|
||||
|
||||
defineExpose({ resetCheckForm, confirm, formClone });
|
||||
|
||||
watch(checked, (value) => {
|
||||
if (value) {
|
||||
initData();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
187
src/components/addNewData/examForm/singleAdd.vue
Normal file
187
src/components/addNewData/examForm/singleAdd.vue
Normal file
@@ -0,0 +1,187 @@
|
||||
<template>
|
||||
<el-form
|
||||
ref="ruleFormRef"
|
||||
style="max-width: 600px"
|
||||
:model="ruleForm"
|
||||
:rules="rules"
|
||||
label-width="auto"
|
||||
size="default"
|
||||
status-icon
|
||||
class="mx-auto"
|
||||
>
|
||||
<el-form-item class="mx-1 font-bold" label="考试uid" prop="uid">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入考试uid"
|
||||
minlength="10"
|
||||
maxlength="10"
|
||||
v-model="ruleForm.uid"
|
||||
@input="filter(ruleForm.uid, 'uid')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="考试名称" prop="exam_name">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入考试名称"
|
||||
maxlength="60"
|
||||
v-model="ruleForm.exam_name"
|
||||
@input="filter(ruleForm.exam_name, 'exam_name')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="考试状态" prop="status">
|
||||
<el-select
|
||||
clearable
|
||||
size="small"
|
||||
placeholder="请选择考试状态"
|
||||
autocomplete="off"
|
||||
v-model="ruleForm.status"
|
||||
style="width: 100%; font-size: 1rem"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in addData.statusOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
class="text-center"
|
||||
:style="item.style"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="报名起止时间">
|
||||
<el-col :span="11">
|
||||
<el-form-item prop="application_start">
|
||||
<el-date-picker
|
||||
v-model="ruleForm.application_start"
|
||||
type="datetime"
|
||||
placeholder="请选择报名开始时间"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="2" class="text-center">
|
||||
<span class="text-gray-500">-</span>
|
||||
</el-col>
|
||||
<el-col :span="11">
|
||||
<el-form-item prop="application_end">
|
||||
<el-date-picker
|
||||
v-model="ruleForm.application_end"
|
||||
type="datetime"
|
||||
placeholder="请选择报名结束时间"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-form-item>
|
||||
<el-form-item label="考试起止时间">
|
||||
<el-col :span="11">
|
||||
<el-form-item prop="exam_start">
|
||||
<el-date-picker
|
||||
v-model="ruleForm.exam_start"
|
||||
type="datetime"
|
||||
placeholder="请选择考试开始时间"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="2" class="text-center">
|
||||
<span class="text-gray-500">-</span>
|
||||
</el-col>
|
||||
<el-col :span="11">
|
||||
<el-form-item prop="exam_end">
|
||||
<el-date-picker
|
||||
v-model="ruleForm.exam_end"
|
||||
type="datetime"
|
||||
placeholder="请选择考试结束时间"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
const ruleFormRef = ref(null);
|
||||
|
||||
const ruleForm = reactive({
|
||||
uid: "",
|
||||
exam_name: "",
|
||||
status: "",
|
||||
application_start: "",
|
||||
application_end: "",
|
||||
exam_start: "",
|
||||
exam_end: "",
|
||||
});
|
||||
|
||||
const formClone = ref({});
|
||||
|
||||
const rules = reactive({
|
||||
uid: [{ required: true, message: "请输入考试uid", trigger: "blur" }],
|
||||
exam_name: [{ required: true, message: "请输入考试名称", trigger: "blur" }],
|
||||
status: [{ required: true, message: "请选择考试状态", trigger: "change" }],
|
||||
application_start: [
|
||||
{ type: "date", required: true, message: "请选择报名开始时间", trigger: "change" },
|
||||
],
|
||||
application_end: [
|
||||
{ type: "date", required: true, message: "请选择报名结束时间", trigger: "change" },
|
||||
],
|
||||
exam_start: [
|
||||
{ type: "date", required: true, message: "请选择考试开始时间", trigger: "change" },
|
||||
],
|
||||
exam_end: [
|
||||
{ type: "date", required: true, message: "请选择考试结束时间", trigger: "change" },
|
||||
],
|
||||
});
|
||||
|
||||
const emit = defineEmits(["addExam"]);
|
||||
|
||||
const filter = (value, label) => {
|
||||
if (/[=\s"'+-]/.test(value)) {
|
||||
if (ruleForm[label]) {
|
||||
ruleForm[label] = value.replace(/[=\s"'+-]/g, "");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const props = defineProps({
|
||||
addData: Object,
|
||||
});
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!ruleFormRef) return;
|
||||
ruleFormRef.value.resetFields();
|
||||
};
|
||||
|
||||
const confirm = async () => {
|
||||
if (!ruleFormRef) return;
|
||||
await ruleFormRef.value.validate((valid) => {
|
||||
if (valid) {
|
||||
formClone.value = { ...ruleForm };
|
||||
emit("addExam", [formClone.value]);
|
||||
ruleFormRef.value.resetFields();
|
||||
ElMessage({
|
||||
message: `提交成功!`,
|
||||
type: "success",
|
||||
});
|
||||
} else {
|
||||
ElMessage.error("提交失败!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const validate = () => {
|
||||
if (!ruleFormRef) return Promise.resolve(false);
|
||||
return new Promise((resolve) => {
|
||||
ruleFormRef.value.validate((valid) => {
|
||||
resolve(valid);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ resetCheckForm, confirm, validate, ruleForm, formClone });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
132
src/components/addNewData/gradesForm/excleAdd.vue
Normal file
132
src/components/addNewData/gradesForm/excleAdd.vue
Normal file
@@ -0,0 +1,132 @@
|
||||
<template>
|
||||
<UploadFile
|
||||
ref="uploadFileRef"
|
||||
:options="options"
|
||||
:relatedRules="relatedRules"
|
||||
:relatedOptions="relatedOptions"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import UploadFile from "../../operate/uploadFile.vue";
|
||||
|
||||
const uploadFileRef = ref(null);
|
||||
const formClone = ref([]);
|
||||
|
||||
const options = {
|
||||
limit: 1,
|
||||
accept: ".xlsx",
|
||||
action: "",
|
||||
multiple: false,
|
||||
listType: "text",
|
||||
autoUpload: false,
|
||||
};
|
||||
|
||||
const relatedRules = {
|
||||
user_name: {
|
||||
value: "",
|
||||
label: "考生姓名",
|
||||
},
|
||||
identity_card: {
|
||||
value: "",
|
||||
label: "身份证号",
|
||||
},
|
||||
exam_uid: {
|
||||
value: "",
|
||||
label: "考试uid",
|
||||
},
|
||||
status: {
|
||||
value: "",
|
||||
label: "参与状态",
|
||||
},
|
||||
grades: {
|
||||
value: "",
|
||||
label: "考试成绩",
|
||||
},
|
||||
pass_type: {
|
||||
value: "",
|
||||
label: "考试结果",
|
||||
},
|
||||
};
|
||||
|
||||
const relatedOptions = [
|
||||
{
|
||||
value: "0",
|
||||
label: "考生姓名",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "1",
|
||||
label: "身份证号",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "2",
|
||||
label: "考试uid",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "3",
|
||||
label: "参与状态",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "4",
|
||||
label: "考试成绩",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "5",
|
||||
label: "考试结果",
|
||||
disabled: false,
|
||||
},
|
||||
];
|
||||
|
||||
const emit = defineEmits(["addGrades"]);
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!uploadFileRef) return;
|
||||
uploadFileRef.value.handleExceed();
|
||||
};
|
||||
|
||||
const confirm = async () => {
|
||||
if (!uploadFileRef) return;
|
||||
formClone.value = [];
|
||||
const length = uploadFileRef.value.loadData.length;
|
||||
if (length == 0) return ElMessage.error("请先上传文件!");
|
||||
const flag = await uploadFileRef.value.confirm();
|
||||
if (!flag) return ElMessage.error("请先选择表格关联项!");
|
||||
ElMessage({
|
||||
message: `正在上传数据中,请稍等...`,
|
||||
type: "success",
|
||||
});
|
||||
setTimeout(() => {
|
||||
uploadFileRef.value.loadData.forEach((ExcleForm) => {
|
||||
ExcleForm.forEach((worksheet) => {
|
||||
let context = [...worksheet];
|
||||
context.shift();
|
||||
context.forEach((item) => {
|
||||
if (item.length != 0) {
|
||||
formClone.value.push({
|
||||
identity_card: item[relatedRules.identity_card.value],
|
||||
user_name: item[relatedRules.user_name.value],
|
||||
exam_uid: item[relatedRules.exam_uid.value],
|
||||
status: item[relatedRules.status.value],
|
||||
grades: item[relatedRules.grades.value],
|
||||
pass_type: item[relatedRules.pass_type.value],
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
emit("addGrades", formClone.value);
|
||||
}, 3000);
|
||||
};
|
||||
|
||||
defineExpose({ resetCheckForm, confirm, formClone });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
174
src/components/addNewData/gradesForm/gradesForm.vue
Normal file
174
src/components/addNewData/gradesForm/gradesForm.vue
Normal file
@@ -0,0 +1,174 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:show-close="false"
|
||||
style="width: 80%"
|
||||
center
|
||||
align-center
|
||||
:before-close="resetCheckForm"
|
||||
>
|
||||
<template #header="{ titleId, titleClass }">
|
||||
<div
|
||||
style="font-size: 2rem"
|
||||
class="w-full font-bold"
|
||||
:id="titleId"
|
||||
:class="titleClass"
|
||||
>
|
||||
{{ title }}
|
||||
</div>
|
||||
<div
|
||||
@click="resetCheckForm"
|
||||
class="bg-gray-400 hover:bg-red-600 text-3xl absolute top-0 right-0 cursor-pointer flex justify-center items-center"
|
||||
>
|
||||
<el-icon>
|
||||
<CloseBold />
|
||||
</el-icon>
|
||||
</div>
|
||||
</template>
|
||||
<FormTools @showTools="showTools" :dialogObj="gradesMsgActive" />
|
||||
<SingleAdd
|
||||
ref="singleAddRef"
|
||||
v-if="dialogSingleVisible"
|
||||
:addData="addData"
|
||||
@addGrades="addGrades"
|
||||
/>
|
||||
<MultipleAdd
|
||||
ref="multipleAddRef"
|
||||
v-if="dialogMultipleVisible"
|
||||
:checkNeed="true"
|
||||
:addData="addData"
|
||||
@addGrades="addGrades"
|
||||
/>
|
||||
<ExcleAdd ref="excleAddRef" v-if="dialogExcleVisible" @addGrades="addGrades" />
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button style="font-weight: bold" @click="resetCheckForm"> 取消 </el-button>
|
||||
<el-button style="font-weight: bold" type="primary" @click="confirm">
|
||||
确定
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { CloseBold } from "@element-plus/icons-vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import FormTools from "../../operate/formTools.vue";
|
||||
import SingleAdd from "./singleAdd.vue";
|
||||
import MultipleAdd from "./multipleAdd.vue";
|
||||
import ExcleAdd from "./excleAdd.vue";
|
||||
|
||||
import gradesActiveStore from "../../../stores/gradesMsg";
|
||||
|
||||
import $http from "../../../api/index";
|
||||
import $url from "../../../api/url";
|
||||
|
||||
import { encrypt } from "../../../utils/aes";
|
||||
|
||||
const gradesMsgActive = gradesActiveStore();
|
||||
|
||||
const dialogVisible = ref(false);
|
||||
const singleAddRef = ref(null);
|
||||
const multipleAddRef = ref(null);
|
||||
const excleAddRef = ref(null);
|
||||
const dialogSingleVisible = ref(true);
|
||||
const dialogMultipleVisible = ref(false);
|
||||
const dialogExcleVisible = ref(false);
|
||||
|
||||
const props = defineProps({
|
||||
title: String,
|
||||
addData: Object,
|
||||
});
|
||||
|
||||
const emit = defineEmits(["reloadData"]);
|
||||
|
||||
const showTools = (operateType) => {
|
||||
switch (operateType) {
|
||||
case "single":
|
||||
dialogSingleVisible.value = true;
|
||||
dialogMultipleVisible.value = false;
|
||||
dialogExcleVisible.value = false;
|
||||
gradesMsgActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
gradesMsgActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
gradesMsgActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
case "multiple":
|
||||
dialogSingleVisible.value = false;
|
||||
dialogMultipleVisible.value = true;
|
||||
dialogExcleVisible.value = false;
|
||||
gradesMsgActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
gradesMsgActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
gradesMsgActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
case "excle":
|
||||
dialogSingleVisible.value = false;
|
||||
dialogMultipleVisible.value = false;
|
||||
dialogExcleVisible.value = true;
|
||||
gradesMsgActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
gradesMsgActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
gradesMsgActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (dialogSingleVisible.value) {
|
||||
singleAddRef.value.resetCheckForm();
|
||||
} else if (dialogMultipleVisible.value) {
|
||||
multipleAddRef.value.resetCheckForm();
|
||||
} else if (dialogExcleVisible.value) {
|
||||
excleAddRef.value.resetCheckForm();
|
||||
}
|
||||
dialogVisible.value = false;
|
||||
};
|
||||
|
||||
const confirm = () => {
|
||||
if (dialogSingleVisible.value) {
|
||||
singleAddRef.value.confirm();
|
||||
} else if (dialogMultipleVisible.value) {
|
||||
multipleAddRef.value.confirm();
|
||||
} else if (dialogExcleVisible.value) {
|
||||
excleAddRef.value.confirm();
|
||||
}
|
||||
};
|
||||
|
||||
const addGrades = (requestMsg) => {
|
||||
requestMsg.forEach((element) => {
|
||||
element.identity_card = encrypt(String(element.identity_card));
|
||||
element.user_name = encrypt(String(element.user_name));
|
||||
element.exam_uid = encrypt(String(element.exam_uid));
|
||||
element.status = encrypt(String(element.status));
|
||||
element.grades = encrypt(String(element.grades));
|
||||
element.pass_type = encrypt(String(element.pass_type));
|
||||
});
|
||||
const data = { requestMsg };
|
||||
$http.post($url.addGrades, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
resetCheckForm();
|
||||
ElMessage({
|
||||
message: "新增考生成绩成功!",
|
||||
type: "success",
|
||||
});
|
||||
emit("reloadData");
|
||||
} else if (res.data.code === 300) {
|
||||
resetCheckForm();
|
||||
ElMessage({
|
||||
message: "新增部分考生成绩成功,请查看新增失败的数据以查找原因!",
|
||||
type: "warning",
|
||||
});
|
||||
emit("reloadData");
|
||||
} else {
|
||||
ElMessage.error("新增考生成绩失败!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ dialogVisible });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
117
src/components/addNewData/gradesForm/multipleAdd.vue
Normal file
117
src/components/addNewData/gradesForm/multipleAdd.vue
Normal file
@@ -0,0 +1,117 @@
|
||||
<template>
|
||||
<div>
|
||||
<div
|
||||
style="font-size: 2rem"
|
||||
class="flex flex-warp justify-center items-center font-bold"
|
||||
>
|
||||
<div style="font-size: 1rem">请输入要导入的数据数量:</div>
|
||||
<el-input-number v-model="singleFormNum" :min="1" :max="10" @change="createForm" />
|
||||
<div v-if="checkNeed"> </div>
|
||||
<el-checkbox
|
||||
v-if="checkNeed"
|
||||
v-model="checked"
|
||||
label="为所有表单进行相同操作"
|
||||
size="large"
|
||||
/>
|
||||
</div>
|
||||
<el-scrollbar max-height="40rem">
|
||||
<div class="mt-2 border-2 border-gray-300" v-for="item in input">
|
||||
<div style="font-size: 1.2rem" class="w-full text-center font-bold">
|
||||
{{ item.label }}
|
||||
</div>
|
||||
<SingleAdd ref="singleAddRef" :addData="addData" />
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import SingleAdd from "./singleAdd.vue";
|
||||
|
||||
const singleFormNum = ref(1);
|
||||
const checked = ref(true);
|
||||
const input = ref([{ label: "成绩1" }]);
|
||||
const singleAddRef = ref(null);
|
||||
const formClone = ref([]);
|
||||
|
||||
const props = defineProps({
|
||||
checkNeed: Boolean,
|
||||
addData: Object,
|
||||
});
|
||||
|
||||
const emit = defineEmits(["addGrades"]);
|
||||
|
||||
const initData = () => {
|
||||
setTimeout(() => {
|
||||
singleAddRef.value.forEach((item) => {
|
||||
item.ruleForm.status = singleAddRef.value[0].ruleForm.status;
|
||||
item.ruleForm.pass_type = singleAddRef.value[0].ruleForm.pass_type;
|
||||
});
|
||||
}, 100);
|
||||
};
|
||||
|
||||
const createForm = () => {
|
||||
let difference = Math.abs(singleFormNum.value - input.value.length);
|
||||
for (let i = 0; i < difference; i++) {
|
||||
if (singleFormNum.value > input.value.length) {
|
||||
input.value.push({ label: `成绩${input.value.length + 1}` });
|
||||
} else if (singleFormNum.value < input.value.length) {
|
||||
input.value.pop();
|
||||
}
|
||||
}
|
||||
if (checked.value) {
|
||||
initData();
|
||||
}
|
||||
};
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!singleAddRef) return;
|
||||
singleAddRef.value.forEach((element) => {
|
||||
element.resetCheckForm();
|
||||
});
|
||||
singleFormNum.value = 1;
|
||||
createForm();
|
||||
};
|
||||
|
||||
const confirm = () => {
|
||||
if (!singleAddRef) return;
|
||||
let valid = true;
|
||||
formClone.value = [];
|
||||
singleAddRef.value.forEach((element) => {
|
||||
element.validate().then((result) => {
|
||||
if (result) {
|
||||
formClone.value.push({ ...element.ruleForm });
|
||||
} else {
|
||||
valid = result;
|
||||
}
|
||||
});
|
||||
});
|
||||
setTimeout(() => {
|
||||
if (valid) {
|
||||
emit("addGrades", formClone.value);
|
||||
singleAddRef.value.forEach((item) => {
|
||||
item.resetCheckForm();
|
||||
});
|
||||
ElMessage({
|
||||
message: `提交成功!`,
|
||||
type: "success",
|
||||
});
|
||||
} else {
|
||||
ElMessage.error("提交失败!");
|
||||
}
|
||||
}, 100);
|
||||
};
|
||||
|
||||
defineExpose({ resetCheckForm, confirm, formClone });
|
||||
|
||||
watch(checked, (value) => {
|
||||
if (value) {
|
||||
initData();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
272
src/components/addNewData/gradesForm/singleAdd.vue
Normal file
272
src/components/addNewData/gradesForm/singleAdd.vue
Normal file
@@ -0,0 +1,272 @@
|
||||
<template>
|
||||
<el-form
|
||||
ref="ruleFormRef"
|
||||
style="max-width: 600px"
|
||||
:model="ruleForm"
|
||||
:rules="rules"
|
||||
label-width="auto"
|
||||
size="default"
|
||||
status-icon
|
||||
class="mx-auto"
|
||||
>
|
||||
<el-form-item class="mx-1 font-bold" label="考生姓名" prop="user_name">
|
||||
<el-autocomplete
|
||||
:fetch-suggestions="searchUserName"
|
||||
clearable
|
||||
placeholder="请输入考生姓名"
|
||||
minlength="1"
|
||||
maxlength="6"
|
||||
v-model="ruleForm.user_name"
|
||||
@input="filter(ruleForm.user_name, 'user_name')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="身份证号" prop="identity_card">
|
||||
<el-autocomplete
|
||||
:fetch-suggestions="searchIdentityCard"
|
||||
clearable
|
||||
placeholder="请输入身份证号"
|
||||
minlength="18"
|
||||
maxlength="18"
|
||||
v-model="ruleForm.identity_card"
|
||||
@input="filter(ruleForm.identity_card, 'identity_card')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="考试uid" prop="exam_uid">
|
||||
<el-autocomplete
|
||||
:fetch-suggestions="searchExamUid"
|
||||
clearable
|
||||
placeholder="请输入考试uid"
|
||||
minlength="10"
|
||||
maxlength="10"
|
||||
v-model="ruleForm.exam_uid"
|
||||
@input="filter(ruleForm.exam_uid, 'exam_uid')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="参与状态" prop="status">
|
||||
<el-select
|
||||
clearable
|
||||
size="small"
|
||||
placeholder="请选择参与状态"
|
||||
autocomplete="off"
|
||||
v-model="ruleForm.status"
|
||||
style="width: 100%; font-size: 1rem"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in addData.statusOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
class="text-center"
|
||||
:style="item.style"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="考生成绩" prop="grades">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入考生成绩"
|
||||
minlength="1"
|
||||
maxlength="5"
|
||||
v-model="ruleForm.grades"
|
||||
@input="filter(ruleForm.grades, 'grades')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="考试结果" prop="pass_type">
|
||||
<el-select
|
||||
clearable
|
||||
size="small"
|
||||
placeholder="请选择考试结果"
|
||||
autocomplete="off"
|
||||
v-model="ruleForm.pass_type"
|
||||
style="width: 100%; font-size: 1rem"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in addData.passTypeOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
class="text-center"
|
||||
:style="item.style"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import $http from "../../../api/index";
|
||||
import $url from "../../../api/url";
|
||||
|
||||
const ruleFormRef = ref(null);
|
||||
|
||||
const ruleForm = reactive({
|
||||
identity_card: "",
|
||||
user_name: "",
|
||||
exam_uid: "",
|
||||
status: "",
|
||||
grades: "",
|
||||
pass_type: "",
|
||||
});
|
||||
|
||||
const formClone = ref({});
|
||||
|
||||
const identityCardRegex = /^[1-9](?:\d{5})(?:19|20)?\d{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12]\d|3[01])\d{3}(?:\d|X|x)$/;
|
||||
|
||||
const searchUserName = (value, cb) => {
|
||||
const data = {
|
||||
user_name: value,
|
||||
};
|
||||
$http.post($url.searchUserName, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
cb(res.data.data);
|
||||
} else {
|
||||
cb([]);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const validateUserName = (rule, value, callback) => {
|
||||
if (value === "") {
|
||||
callback(new Error("请输入考生姓名"));
|
||||
} else {
|
||||
const data = {
|
||||
user_name: value,
|
||||
};
|
||||
$http.post($url.findUserName, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
callback();
|
||||
} else {
|
||||
callback(new Error("该考生不存在!"));
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const searchIdentityCard = (value, cb) => {
|
||||
const data = {
|
||||
identity_card: value,
|
||||
};
|
||||
$http.post($url.searchIdentityCard, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
cb(res.data.data);
|
||||
} else {
|
||||
cb([]);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const validateIdentityCard = (rule, value, callback) => {
|
||||
if (value === "") {
|
||||
callback(new Error("请输入身份证号"));
|
||||
} else if (!identityCardRegex.test(value)) {
|
||||
callback(new Error("身份证格式不正确,请重新输入!"));
|
||||
} else if (ruleForm.user_name == "") {
|
||||
callback(new Error("请输入考生姓名"));
|
||||
} else {
|
||||
const data = {
|
||||
identity_card: value,
|
||||
user_name: ruleForm.user_name,
|
||||
};
|
||||
$http.post($url.findIdentityCard, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
callback();
|
||||
} else if (res.data.code === 303) {
|
||||
callback(new Error("考生身份证号码与考生姓名不匹配!"));
|
||||
} else {
|
||||
callback(new Error("该考生身份证号未注册!"));
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const searchExamUid = (value, cb) => {
|
||||
const data = {
|
||||
exam_uid: value,
|
||||
};
|
||||
$http.post($url.searchExamUid, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
cb(res.data.data);
|
||||
} else {
|
||||
cb([]);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const validateExamUid = (rule, value, callback) => {
|
||||
if (value === "") {
|
||||
callback(new Error("请输入考试uid"));
|
||||
} else {
|
||||
const data = {
|
||||
exam_uid: value,
|
||||
};
|
||||
$http.post($url.findExamUid, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
callback();
|
||||
} else {
|
||||
callback(new Error("该考试不存在!"));
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const rules = reactive({
|
||||
identity_card: [{ required: true, validator: validateIdentityCard, trigger: "blur" }],
|
||||
user_name: [{ required: true, validator: validateUserName, trigger: "blur" }],
|
||||
exam_uid: [{ required: true, validator: validateExamUid, trigger: "blur" }],
|
||||
status: [{ required: true, message: "请选择参与状态", trigger: "change" }],
|
||||
grades: [{ required: true, message: "请输入考生成绩", trigger: "blur" }],
|
||||
pass_type: [{ required: true, message: "请选择考试结果", trigger: "change" }],
|
||||
});
|
||||
|
||||
const emit = defineEmits(["addGrades"]);
|
||||
|
||||
const filter = (value, label) => {
|
||||
if (/[=\s"'+-]/.test(value)) {
|
||||
if (ruleForm[label]) {
|
||||
ruleForm[label] = value.replace(/[=\s"'+-]/g, "");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const props = defineProps({
|
||||
addData: Object,
|
||||
});
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!ruleFormRef) return;
|
||||
ruleFormRef.value.resetFields();
|
||||
};
|
||||
|
||||
const confirm = async () => {
|
||||
if (!ruleFormRef) return;
|
||||
await ruleFormRef.value.validate((valid) => {
|
||||
if (valid) {
|
||||
formClone.value = { ...ruleForm };
|
||||
emit("addGrades", [formClone.value]);
|
||||
ruleFormRef.value.resetFields();
|
||||
ElMessage({
|
||||
message: `提交成功!`,
|
||||
type: "success",
|
||||
});
|
||||
} else {
|
||||
ElMessage.error("提交失败!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const validate = () => {
|
||||
if (!ruleFormRef) return Promise.resolve(false);
|
||||
return new Promise((resolve) => {
|
||||
ruleFormRef.value.validate((valid) => {
|
||||
resolve(valid);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ resetCheckForm, confirm, validate, ruleForm, formClone });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
101
src/components/addNewData/topicWhitelistForm/excleAdd.vue
Normal file
101
src/components/addNewData/topicWhitelistForm/excleAdd.vue
Normal file
@@ -0,0 +1,101 @@
|
||||
<template>
|
||||
<UploadFile
|
||||
ref="uploadFileRef"
|
||||
:options="options"
|
||||
:relatedRules="relatedRules"
|
||||
:relatedOptions="relatedOptions"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import UploadFile from "../../operate/uploadFile.vue";
|
||||
|
||||
const uploadFileRef = ref(null);
|
||||
const formClone = ref([]);
|
||||
|
||||
const options = {
|
||||
limit: 1,
|
||||
accept: ".xlsx",
|
||||
action: "",
|
||||
multiple: false,
|
||||
listType: "text",
|
||||
autoUpload: false,
|
||||
};
|
||||
|
||||
const relatedRules = {
|
||||
phone: {
|
||||
value: "",
|
||||
label: "电话号码",
|
||||
},
|
||||
type: {
|
||||
value: "",
|
||||
label: "白名单类型",
|
||||
},
|
||||
expired_at: {
|
||||
value: "",
|
||||
label: "白名单过期时间",
|
||||
},
|
||||
};
|
||||
|
||||
const relatedOptions = [
|
||||
{
|
||||
value: "0",
|
||||
label: "电话号码",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "1",
|
||||
label: "白名单类型",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "2",
|
||||
label: "白名单过期时间",
|
||||
disabled: false,
|
||||
},
|
||||
];
|
||||
|
||||
const emit = defineEmits(["addTopicWhitelist"]);
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!uploadFileRef) return;
|
||||
uploadFileRef.value.handleExceed();
|
||||
};
|
||||
|
||||
const confirm = async () => {
|
||||
if (!uploadFileRef) return;
|
||||
formClone.value = [];
|
||||
const length = uploadFileRef.value.loadData.length;
|
||||
if (length == 0) return ElMessage.error("请先上传文件!");
|
||||
const flag = await uploadFileRef.value.confirm();
|
||||
if (!flag) return ElMessage.error("请先选择表格关联项!");
|
||||
ElMessage({
|
||||
message: `正在上传数据中,请稍等...`,
|
||||
type: "success",
|
||||
});
|
||||
setTimeout(() => {
|
||||
uploadFileRef.value.loadData.forEach((ExcleForm) => {
|
||||
ExcleForm.forEach((worksheet) => {
|
||||
let context = [...worksheet];
|
||||
context.shift();
|
||||
context.forEach((item) => {
|
||||
if (item.length != 0) {
|
||||
formClone.value.push({
|
||||
phone: item[relatedRules.phone.value],
|
||||
type: item[relatedRules.type.value],
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
emit("addTopicWhitelist", formClone.value);
|
||||
}, 3000);
|
||||
};
|
||||
|
||||
defineExpose({ resetCheckForm, confirm, formClone });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
116
src/components/addNewData/topicWhitelistForm/multipleAdd.vue
Normal file
116
src/components/addNewData/topicWhitelistForm/multipleAdd.vue
Normal file
@@ -0,0 +1,116 @@
|
||||
<template>
|
||||
<div>
|
||||
<div
|
||||
style="font-size: 2rem"
|
||||
class="flex flex-warp justify-center items-center font-bold"
|
||||
>
|
||||
<div style="font-size: 1rem">请输入要导入的数据数量:</div>
|
||||
<el-input-number v-model="singleFormNum" :min="1" :max="10" @change="createForm" />
|
||||
<div v-if="checkNeed"> </div>
|
||||
<el-checkbox
|
||||
v-if="checkNeed"
|
||||
v-model="checked"
|
||||
label="为所有表单进行相同操作"
|
||||
size="large"
|
||||
/>
|
||||
</div>
|
||||
<el-scrollbar max-height="40rem">
|
||||
<div class="mt-2 border-2 border-gray-300" v-for="item in input">
|
||||
<div style="font-size: 1.2rem" class="w-full text-center font-bold">
|
||||
{{ item.label }}
|
||||
</div>
|
||||
<SingleAdd ref="singleAddRef" :addData="addData" />
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import SingleAdd from "./singleAdd.vue";
|
||||
|
||||
const singleFormNum = ref(1);
|
||||
const checked = ref(true);
|
||||
const input = ref([{ label: "白名单1" }]);
|
||||
const singleAddRef = ref(null);
|
||||
const formClone = ref([]);
|
||||
|
||||
const props = defineProps({
|
||||
checkNeed: Boolean,
|
||||
addData: Object,
|
||||
});
|
||||
|
||||
const emit = defineEmits(["addTopicWhitelist"]);
|
||||
|
||||
const initData = () => {
|
||||
setTimeout(() => {
|
||||
singleAddRef.value.forEach((item) => {
|
||||
item.ruleForm.type = singleAddRef.value[0].ruleForm.typw;
|
||||
});
|
||||
}, 100);
|
||||
};
|
||||
|
||||
const createForm = () => {
|
||||
let difference = Math.abs(singleFormNum.value - input.value.length);
|
||||
for (let i = 0; i < difference; i++) {
|
||||
if (singleFormNum.value > input.value.length) {
|
||||
input.value.push({ label: `白名单${input.value.length + 1}` });
|
||||
} else if (singleFormNum.value < input.value.length) {
|
||||
input.value.pop();
|
||||
}
|
||||
}
|
||||
if (checked.value) {
|
||||
initData();
|
||||
}
|
||||
};
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!singleAddRef) return;
|
||||
singleAddRef.value.forEach((element) => {
|
||||
element.resetCheckForm();
|
||||
});
|
||||
singleFormNum.value = 1;
|
||||
createForm();
|
||||
};
|
||||
|
||||
const confirm = () => {
|
||||
if (!singleAddRef) return;
|
||||
let valid = true;
|
||||
formClone.value = [];
|
||||
singleAddRef.value.forEach((element) => {
|
||||
element.validate().then((result) => {
|
||||
if (result) {
|
||||
formClone.value.push({ ...element.ruleForm });
|
||||
} else {
|
||||
valid = result;
|
||||
}
|
||||
});
|
||||
});
|
||||
setTimeout(() => {
|
||||
if (valid) {
|
||||
emit("addTopicWhitelist", formClone.value);
|
||||
singleAddRef.value.forEach((item) => {
|
||||
item.resetCheckForm();
|
||||
});
|
||||
ElMessage({
|
||||
message: `提交成功!`,
|
||||
type: "success",
|
||||
});
|
||||
} else {
|
||||
ElMessage.error("提交失败!");
|
||||
}
|
||||
}, 100);
|
||||
};
|
||||
|
||||
defineExpose({ resetCheckForm, confirm, formClone });
|
||||
|
||||
watch(checked, (value) => {
|
||||
if (value) {
|
||||
initData();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
123
src/components/addNewData/topicWhitelistForm/singleAdd.vue
Normal file
123
src/components/addNewData/topicWhitelistForm/singleAdd.vue
Normal file
@@ -0,0 +1,123 @@
|
||||
<template>
|
||||
<el-form
|
||||
ref="ruleFormRef"
|
||||
style="max-width: 600px"
|
||||
:model="ruleForm"
|
||||
:rules="rules"
|
||||
label-width="auto"
|
||||
size="default"
|
||||
status-icon
|
||||
class="mx-auto"
|
||||
>
|
||||
<el-form-item class="mx-1 font-bold" label="电话号码" prop="phone">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入电话号码"
|
||||
minlength="11"
|
||||
maxlength="11"
|
||||
v-model="ruleForm.phone"
|
||||
@input="filter(ruleForm.phone, 'phone')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="白名单类型" prop="type">
|
||||
<el-select
|
||||
clearable
|
||||
size="small"
|
||||
placeholder="请选择白名单类型"
|
||||
autocomplete="off"
|
||||
v-model="ruleForm.type"
|
||||
style="width: 100%; font-size: 1rem"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in addData.typeOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
class="text-center"
|
||||
:style="item.style"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="白名单过期时间">
|
||||
<el-col :span="11">
|
||||
<el-form-item prop="expired_at">
|
||||
<el-date-picker
|
||||
v-model="ruleForm.expired_at"
|
||||
type="datetime"
|
||||
placeholder="请选择白名单过期时间"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
const ruleFormRef = ref(null);
|
||||
|
||||
const ruleForm = reactive({
|
||||
phone: "",
|
||||
type: "",
|
||||
expired_at: "",
|
||||
});
|
||||
|
||||
const formClone = ref({});
|
||||
|
||||
const rules = reactive({
|
||||
phone: [{ required: true, message: "请输入手机号码", trigger: "blur" }],
|
||||
type: [{ required: true, message: "请选择白名单类型", trigger: "change" }],
|
||||
});
|
||||
|
||||
const emit = defineEmits(["addTopicWhitelist"]);
|
||||
|
||||
const filter = (value, label) => {
|
||||
if (/[=\s"'+-]/.test(value)) {
|
||||
if (ruleForm[label]) {
|
||||
ruleForm[label] = value.replace(/[=\s"'+-]/g, "");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const props = defineProps({
|
||||
addData: Object,
|
||||
});
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!ruleFormRef) return;
|
||||
ruleFormRef.value.resetFields();
|
||||
};
|
||||
|
||||
const confirm = async () => {
|
||||
if (!ruleFormRef) return;
|
||||
await ruleFormRef.value.validate((valid) => {
|
||||
if (valid) {
|
||||
formClone.value = { ...ruleForm };
|
||||
emit("addTopicWhitelist", [formClone.value]);
|
||||
ruleFormRef.value.resetFields();
|
||||
ElMessage({
|
||||
message: `提交成功!`,
|
||||
type: "success",
|
||||
});
|
||||
} else {
|
||||
ElMessage.error("提交失败!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const validate = () => {
|
||||
if (!ruleFormRef) return Promise.resolve(false);
|
||||
return new Promise((resolve) => {
|
||||
ruleFormRef.value.validate((valid) => {
|
||||
resolve(valid);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ resetCheckForm, confirm, validate, ruleForm, formClone });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -0,0 +1,168 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:show-close="false"
|
||||
style="width: 80%"
|
||||
center
|
||||
align-center
|
||||
:before-close="resetCheckForm"
|
||||
>
|
||||
<template #header="{ titleId, titleClass }">
|
||||
<div
|
||||
style="font-size: 2rem"
|
||||
class="w-full font-bold"
|
||||
:id="titleId"
|
||||
:class="titleClass"
|
||||
>
|
||||
{{ title }}
|
||||
</div>
|
||||
<div
|
||||
@click="resetCheckForm"
|
||||
class="bg-gray-400 hover:bg-red-600 text-3xl absolute top-0 right-0 cursor-pointer flex justify-center items-center"
|
||||
>
|
||||
<el-icon>
|
||||
<CloseBold />
|
||||
</el-icon>
|
||||
</div>
|
||||
</template>
|
||||
<FormTools @showTools="showTools" :dialogObj="topicWhitelistActive" />
|
||||
<SingleAdd
|
||||
ref="singleAddRef"
|
||||
v-if="dialogSingleVisible"
|
||||
:addData="addData"
|
||||
@addTopicWhitelist="addTopicWhitelist"
|
||||
/>
|
||||
<MultipleAdd
|
||||
ref="multipleAddRef"
|
||||
v-if="dialogMultipleVisible"
|
||||
:checkNeed="true"
|
||||
:addData="addData"
|
||||
@addTopicWhitelist="addTopicWhitelist"
|
||||
/>
|
||||
<ExcleAdd
|
||||
ref="excleAddRef"
|
||||
v-if="dialogExcleVisible"
|
||||
@addTopicWhitelist="addTopicWhitelist"
|
||||
/>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button style="font-weight: bold" @click="resetCheckForm"> 取消 </el-button>
|
||||
<el-button style="font-weight: bold" type="primary" @click="confirm">
|
||||
确定
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { CloseBold } from "@element-plus/icons-vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import FormTools from "../../operate/formTools.vue";
|
||||
import SingleAdd from "./singleAdd.vue";
|
||||
import MultipleAdd from "./multipleAdd.vue";
|
||||
import ExcleAdd from "./excleAdd.vue";
|
||||
|
||||
import topicWhitelistActiveStore from "../../../stores/topicWhitelist";
|
||||
|
||||
import $http from "../../../api/index";
|
||||
import $url from "../../../api/url";
|
||||
|
||||
import { encrypt } from "../../../utils/aes";
|
||||
|
||||
const topicWhitelistActive = topicWhitelistActiveStore();
|
||||
|
||||
const dialogVisible = ref(false);
|
||||
const singleAddRef = ref(null);
|
||||
const multipleAddRef = ref(null);
|
||||
const excleAddRef = ref(null);
|
||||
const dialogSingleVisible = ref(true);
|
||||
const dialogMultipleVisible = ref(false);
|
||||
const dialogExcleVisible = ref(false);
|
||||
|
||||
const props = defineProps({
|
||||
title: String,
|
||||
addData: Object,
|
||||
});
|
||||
|
||||
const emit = defineEmits(["reloadData"]);
|
||||
|
||||
const showTools = (operateType) => {
|
||||
switch (operateType) {
|
||||
case "single":
|
||||
dialogSingleVisible.value = true;
|
||||
dialogMultipleVisible.value = false;
|
||||
dialogExcleVisible.value = false;
|
||||
topicWhitelistActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
topicWhitelistActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
topicWhitelistActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
case "multiple":
|
||||
dialogSingleVisible.value = false;
|
||||
dialogMultipleVisible.value = true;
|
||||
dialogExcleVisible.value = false;
|
||||
topicWhitelistActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
topicWhitelistActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
topicWhitelistActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
case "excle":
|
||||
dialogSingleVisible.value = false;
|
||||
dialogMultipleVisible.value = false;
|
||||
dialogExcleVisible.value = true;
|
||||
topicWhitelistActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
topicWhitelistActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
topicWhitelistActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (dialogSingleVisible.value) {
|
||||
singleAddRef.value.resetCheckForm();
|
||||
} else if (dialogMultipleVisible.value) {
|
||||
multipleAddRef.value.resetCheckForm();
|
||||
} else if (dialogExcleVisible.value) {
|
||||
excleAddRef.value.resetCheckForm();
|
||||
}
|
||||
dialogVisible.value = false;
|
||||
};
|
||||
|
||||
const confirm = () => {
|
||||
if (dialogSingleVisible.value) {
|
||||
singleAddRef.value.confirm();
|
||||
} else if (dialogMultipleVisible.value) {
|
||||
multipleAddRef.value.confirm();
|
||||
} else if (dialogExcleVisible.value) {
|
||||
excleAddRef.value.confirm();
|
||||
}
|
||||
};
|
||||
|
||||
const addTopicWhitelist = (requestMsg) => {
|
||||
requestMsg.forEach((element) => {
|
||||
element.phone = encrypt(String(element.phone));
|
||||
element.type = encrypt(String(element.type));
|
||||
element.expired_at = encrypt(String(element.expired_at));
|
||||
});
|
||||
const data = { requestMsg };
|
||||
$http.post($url.addTopicWhitelist, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
resetCheckForm();
|
||||
ElMessage({
|
||||
message: "新增题库白名单成功!",
|
||||
type: "success",
|
||||
});
|
||||
emit("reloadData");
|
||||
} else {
|
||||
ElMessage.error("新增题库白名单失败!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ dialogVisible });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -0,0 +1,102 @@
|
||||
<template>
|
||||
<UploadFile
|
||||
ref="uploadFileRef"
|
||||
:options="options"
|
||||
:relatedRules="relatedRules"
|
||||
:relatedOptions="relatedOptions"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import UploadFile from "../../../operate/uploadFile.vue";
|
||||
|
||||
const uploadFileRef = ref(null);
|
||||
const formClone = ref([]);
|
||||
|
||||
const options = {
|
||||
limit: 1,
|
||||
accept: ".xlsx",
|
||||
action: "",
|
||||
multiple: false,
|
||||
listType: "text",
|
||||
autoUpload: false,
|
||||
};
|
||||
|
||||
const relatedRules = {
|
||||
stem: {
|
||||
value: "",
|
||||
label: "题干",
|
||||
},
|
||||
answer: {
|
||||
value: "",
|
||||
label: "答案",
|
||||
},
|
||||
difficulty: {
|
||||
value: "",
|
||||
label: "难度",
|
||||
},
|
||||
};
|
||||
|
||||
const relatedOptions = [
|
||||
{
|
||||
value: "0",
|
||||
label: "题干",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "1",
|
||||
label: "答案",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "2",
|
||||
label: "难度",
|
||||
disabled: false,
|
||||
},
|
||||
];
|
||||
|
||||
const emit = defineEmits(["addInterlocution"]);
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!uploadFileRef) return;
|
||||
uploadFileRef.value.handleExceed();
|
||||
};
|
||||
|
||||
const confirm = async () => {
|
||||
if (!uploadFileRef) return;
|
||||
formClone.value = [];
|
||||
const length = uploadFileRef.value.loadData.length;
|
||||
if (length == 0) return ElMessage.error("请先上传文件!");
|
||||
const flag = await uploadFileRef.value.confirm();
|
||||
if (!flag) return ElMessage.error("请先选择表格关联项!");
|
||||
ElMessage({
|
||||
message: `正在上传数据中,请稍等...`,
|
||||
type: "success",
|
||||
});
|
||||
setTimeout(() => {
|
||||
uploadFileRef.value.loadData.forEach((ExcleForm) => {
|
||||
ExcleForm.forEach((worksheet) => {
|
||||
let context = [...worksheet];
|
||||
context.shift();
|
||||
context.forEach((item) => {
|
||||
if (item.length != 0) {
|
||||
formClone.value.push({
|
||||
stem: item[relatedRules.stem.value],
|
||||
answer: item[relatedRules.answer.value],
|
||||
difficulty: item[relatedRules.difficulty.value],
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
emit("addInterlocution", formClone.value);
|
||||
}, 3000);
|
||||
};
|
||||
|
||||
defineExpose({ resetCheckForm, confirm, formClone });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -0,0 +1,161 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:show-close="false"
|
||||
style="width: 80%"
|
||||
center
|
||||
align-center
|
||||
:before-close="resetCheckForm"
|
||||
>
|
||||
<template #header="{ titleId, titleClass }">
|
||||
<div
|
||||
style="font-size: 2rem"
|
||||
class="w-full font-bold"
|
||||
:id="titleId"
|
||||
:class="titleClass"
|
||||
>
|
||||
{{ title }}
|
||||
</div>
|
||||
<div
|
||||
@click="resetCheckForm"
|
||||
class="bg-gray-400 hover:bg-red-600 text-3xl absolute top-0 right-0 cursor-pointer flex justify-center items-center"
|
||||
>
|
||||
<el-icon>
|
||||
<CloseBold />
|
||||
</el-icon>
|
||||
</div>
|
||||
</template>
|
||||
<FormTools @showTools="showTools" :dialogObj="interlocutionMsgActive" />
|
||||
<SingleAdd
|
||||
ref="singleAddRef"
|
||||
v-if="dialogSingleVisible"
|
||||
:addData="addData"
|
||||
@addInterlocution="addInterlocution"
|
||||
/>
|
||||
<MultipleAdd
|
||||
ref="multipleAddRef"
|
||||
v-if="dialogMultipleVisible"
|
||||
:checkNeed="true"
|
||||
:addData="addData"
|
||||
@addInterlocution="addInterlocution"
|
||||
/>
|
||||
<ExcleAdd
|
||||
ref="excleAddRef"
|
||||
v-if="dialogExcleVisible"
|
||||
@addInterlocution="addInterlocution"
|
||||
/>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button style="font-weight: bold" @click="resetCheckForm"> 取消 </el-button>
|
||||
<el-button style="font-weight: bold" type="primary" @click="confirm">
|
||||
确定
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { CloseBold } from "@element-plus/icons-vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import FormTools from "../../../operate/formTools.vue";
|
||||
import SingleAdd from "./singleAdd.vue";
|
||||
import MultipleAdd from "./multipleAdd.vue";
|
||||
import ExcleAdd from "./excleAdd.vue";
|
||||
|
||||
import interlocutionActiveStore from "../../../../stores/trainindTopic/interlocution.js";
|
||||
|
||||
import $http from "../../../../api/index";
|
||||
import $url from "../../../../api/url";
|
||||
|
||||
const interlocutionMsgActive = interlocutionActiveStore();
|
||||
|
||||
const dialogVisible = ref(false);
|
||||
const singleAddRef = ref(null);
|
||||
const multipleAddRef = ref(null);
|
||||
const excleAddRef = ref(null);
|
||||
const dialogSingleVisible = ref(true);
|
||||
const dialogMultipleVisible = ref(false);
|
||||
const dialogExcleVisible = ref(false);
|
||||
|
||||
const props = defineProps({
|
||||
title: String,
|
||||
addData: Object,
|
||||
});
|
||||
|
||||
const emit = defineEmits(["reloadData"]);
|
||||
|
||||
const showTools = (operateType) => {
|
||||
switch (operateType) {
|
||||
case "single":
|
||||
dialogSingleVisible.value = true;
|
||||
dialogMultipleVisible.value = false;
|
||||
dialogExcleVisible.value = false;
|
||||
interlocutionMsgActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
interlocutionMsgActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
interlocutionMsgActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
case "multiple":
|
||||
dialogSingleVisible.value = false;
|
||||
dialogMultipleVisible.value = true;
|
||||
dialogExcleVisible.value = false;
|
||||
interlocutionMsgActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
interlocutionMsgActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
interlocutionMsgActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
case "excle":
|
||||
dialogSingleVisible.value = false;
|
||||
dialogMultipleVisible.value = false;
|
||||
dialogExcleVisible.value = true;
|
||||
interlocutionMsgActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
interlocutionMsgActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
interlocutionMsgActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (dialogSingleVisible.value) {
|
||||
singleAddRef.value.resetCheckForm();
|
||||
} else if (dialogMultipleVisible.value) {
|
||||
multipleAddRef.value.resetCheckForm();
|
||||
} else if (dialogExcleVisible.value) {
|
||||
excleAddRef.value.resetCheckForm();
|
||||
}
|
||||
dialogVisible.value = false;
|
||||
};
|
||||
|
||||
const confirm = () => {
|
||||
if (dialogSingleVisible.value) {
|
||||
singleAddRef.value.confirm();
|
||||
} else if (dialogMultipleVisible.value) {
|
||||
multipleAddRef.value.confirm();
|
||||
} else if (dialogExcleVisible.value) {
|
||||
excleAddRef.value.confirm();
|
||||
}
|
||||
};
|
||||
|
||||
const addInterlocution = (requestMsg) => {
|
||||
const data = { requestMsg };
|
||||
$http.post($url.addInterlocution, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
resetCheckForm();
|
||||
ElMessage({
|
||||
message: "新增问答题成功!",
|
||||
type: "success",
|
||||
});
|
||||
emit("reloadData");
|
||||
} else {
|
||||
ElMessage.error("新增问答题失败!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ dialogVisible });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -0,0 +1,116 @@
|
||||
<template>
|
||||
<div>
|
||||
<div
|
||||
style="font-size: 2rem"
|
||||
class="flex flex-warp justify-center items-center font-bold"
|
||||
>
|
||||
<div style="font-size: 1rem">请输入要导入的数据数量:</div>
|
||||
<el-input-number v-model="singleFormNum" :min="1" :max="10" @change="createForm" />
|
||||
<div v-if="checkNeed"> </div>
|
||||
<el-checkbox
|
||||
v-if="checkNeed"
|
||||
v-model="checked"
|
||||
label="为所有表单进行相同操作"
|
||||
size="large"
|
||||
/>
|
||||
</div>
|
||||
<el-scrollbar max-height="40rem">
|
||||
<div class="mt-2 border-2 border-gray-300" v-for="item in input">
|
||||
<div style="font-size: 1.2rem" class="w-full text-center font-bold">
|
||||
{{ item.label }}
|
||||
</div>
|
||||
<SingleAdd ref="singleAddRef" :addData="addData" />
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import SingleAdd from "./singleAdd.vue";
|
||||
|
||||
const singleFormNum = ref(1);
|
||||
const checked = ref(true);
|
||||
const input = ref([{ label: "问答题1" }]);
|
||||
const singleAddRef = ref(null);
|
||||
const formClone = ref([]);
|
||||
|
||||
const props = defineProps({
|
||||
checkNeed: Boolean,
|
||||
addData: Object,
|
||||
});
|
||||
|
||||
const emit = defineEmits(["addInterlocution"]);
|
||||
|
||||
const initData = () => {
|
||||
setTimeout(() => {
|
||||
singleAddRef.value.forEach((item) => {
|
||||
item.ruleForm.role = singleAddRef.value[0].ruleForm.role;
|
||||
});
|
||||
}, 100);
|
||||
};
|
||||
|
||||
const createForm = () => {
|
||||
let difference = Math.abs(singleFormNum.value - input.value.length);
|
||||
for (let i = 0; i < difference; i++) {
|
||||
if (singleFormNum.value > input.value.length) {
|
||||
input.value.push({ label: `问答题${input.value.length + 1}` });
|
||||
} else if (singleFormNum.value < input.value.length) {
|
||||
input.value.pop();
|
||||
}
|
||||
}
|
||||
if (checked.value) {
|
||||
initData();
|
||||
}
|
||||
};
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!singleAddRef) return;
|
||||
singleAddRef.value.forEach((element) => {
|
||||
element.resetCheckForm();
|
||||
});
|
||||
singleFormNum.value = 1;
|
||||
createForm();
|
||||
};
|
||||
|
||||
const confirm = () => {
|
||||
if (!singleAddRef) return;
|
||||
let valid = true;
|
||||
formClone.value = [];
|
||||
singleAddRef.value.forEach((element) => {
|
||||
element.validate().then((result) => {
|
||||
if (result) {
|
||||
formClone.value.push({ ...element.ruleForm });
|
||||
} else {
|
||||
valid = result;
|
||||
}
|
||||
});
|
||||
});
|
||||
setTimeout(() => {
|
||||
if (valid) {
|
||||
emit("addInterlocution", formClone.value);
|
||||
singleAddRef.value.forEach((item) => {
|
||||
item.resetCheckForm();
|
||||
});
|
||||
ElMessage({
|
||||
message: `提交成功!`,
|
||||
type: "success",
|
||||
});
|
||||
} else {
|
||||
ElMessage.error("提交失败!");
|
||||
}
|
||||
}, 100);
|
||||
};
|
||||
|
||||
defineExpose({ resetCheckForm, confirm, formClone });
|
||||
|
||||
watch(checked, (value) => {
|
||||
if (value) {
|
||||
initData();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -0,0 +1,118 @@
|
||||
<template>
|
||||
<el-form
|
||||
ref="ruleFormRef"
|
||||
style="max-width: 600px"
|
||||
:model="ruleForm"
|
||||
:rules="rules"
|
||||
label-width="auto"
|
||||
size="default"
|
||||
status-icon
|
||||
class="mx-auto"
|
||||
>
|
||||
<el-form-item class="mx-1 font-bold" label="题干" prop="stem">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入题干"
|
||||
v-model="ruleForm.stem"
|
||||
@input="filter(ruleForm.stem, 'stem')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="答案" prop="answer">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入答案"
|
||||
v-model="ruleForm.answer"
|
||||
@input="filter(ruleForm.answer, 'answer')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="难度" prop="difficulty">
|
||||
<el-select
|
||||
clearable
|
||||
size="small"
|
||||
placeholder="请选择难度"
|
||||
autocomplete="off"
|
||||
v-model="ruleForm.difficulty"
|
||||
style="width: 100%; font-size: 1rem"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in addData.difficultyOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
class="text-center"
|
||||
:style="item.style"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
const ruleFormRef = ref(null);
|
||||
|
||||
const ruleForm = reactive({
|
||||
stem: "",
|
||||
answer: "",
|
||||
difficulty: "",
|
||||
});
|
||||
|
||||
const formClone = ref({});
|
||||
|
||||
const rules = reactive({
|
||||
stem: [{ required: true, message: "请输入题干", trigger: "blur" }],
|
||||
answer: [{ required: true, message: "请输入答案", trigger: "blur" }],
|
||||
difficulty: [{ required: true, message: "请选择难度", trigger: "change" }],
|
||||
});
|
||||
|
||||
const emit = defineEmits(["addInterlocution"]);
|
||||
|
||||
const filter = (value, label) => {
|
||||
if (/[=\s"'+-]/.test(value)) {
|
||||
if (ruleForm[label]) {
|
||||
ruleForm[label] = value.replace(/[=\s"'+-]/g, "");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const props = defineProps({
|
||||
addData: Object,
|
||||
});
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!ruleFormRef) return;
|
||||
ruleFormRef.value.resetFields();
|
||||
};
|
||||
|
||||
const confirm = async () => {
|
||||
if (!ruleFormRef) return;
|
||||
await ruleFormRef.value.validate((valid) => {
|
||||
if (valid) {
|
||||
formClone.value = { ...ruleForm };
|
||||
emit("addInterlocution", [formClone.value]);
|
||||
ruleFormRef.value.resetFields();
|
||||
ElMessage({
|
||||
message: `提交成功!`,
|
||||
type: "success",
|
||||
});
|
||||
} else {
|
||||
ElMessage.error("提交失败!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const validate = () => {
|
||||
if (!ruleFormRef) return Promise.resolve(false);
|
||||
return new Promise((resolve) => {
|
||||
ruleFormRef.value.validate((valid) => {
|
||||
resolve(valid);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ resetCheckForm, confirm, validate, ruleForm, formClone });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
102
src/components/addNewData/trainindTopic/judgment/excleAdd.vue
Normal file
102
src/components/addNewData/trainindTopic/judgment/excleAdd.vue
Normal file
@@ -0,0 +1,102 @@
|
||||
<template>
|
||||
<UploadFile
|
||||
ref="uploadFileRef"
|
||||
:options="options"
|
||||
:relatedRules="relatedRules"
|
||||
:relatedOptions="relatedOptions"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import UploadFile from "../../../operate/uploadFile.vue";
|
||||
|
||||
const uploadFileRef = ref(null);
|
||||
const formClone = ref([]);
|
||||
|
||||
const options = {
|
||||
limit: 1,
|
||||
accept: ".xlsx",
|
||||
action: "",
|
||||
multiple: false,
|
||||
listType: "text",
|
||||
autoUpload: false,
|
||||
};
|
||||
|
||||
const relatedRules = {
|
||||
stem: {
|
||||
value: "",
|
||||
label: "题干",
|
||||
},
|
||||
answer: {
|
||||
value: "",
|
||||
label: "答案",
|
||||
},
|
||||
difficulty: {
|
||||
value: "",
|
||||
label: "难度",
|
||||
},
|
||||
};
|
||||
|
||||
const relatedOptions = [
|
||||
{
|
||||
value: "0",
|
||||
label: "题干",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "1",
|
||||
label: "答案",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "2",
|
||||
label: "难度",
|
||||
disabled: false,
|
||||
},
|
||||
];
|
||||
|
||||
const emit = defineEmits(["addJudgment"]);
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!uploadFileRef) return;
|
||||
uploadFileRef.value.handleExceed();
|
||||
};
|
||||
|
||||
const confirm = async () => {
|
||||
if (!uploadFileRef) return;
|
||||
formClone.value = [];
|
||||
const length = uploadFileRef.value.loadData.length;
|
||||
if (length == 0) return ElMessage.error("请先上传文件!");
|
||||
const flag = await uploadFileRef.value.confirm();
|
||||
if (!flag) return ElMessage.error("请先选择表格关联项!");
|
||||
ElMessage({
|
||||
message: `正在上传数据中,请稍等...`,
|
||||
type: "success",
|
||||
});
|
||||
setTimeout(() => {
|
||||
uploadFileRef.value.loadData.forEach((ExcleForm) => {
|
||||
ExcleForm.forEach((worksheet) => {
|
||||
let context = [...worksheet];
|
||||
context.shift();
|
||||
context.forEach((item) => {
|
||||
if (item.length != 0) {
|
||||
formClone.value.push({
|
||||
stem: item[relatedRules.stem.value],
|
||||
answer: item[relatedRules.answer.value],
|
||||
difficulty: item[relatedRules.difficulty.value],
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
emit("addJudgment", formClone.value);
|
||||
}, 3000);
|
||||
};
|
||||
|
||||
defineExpose({ resetCheckForm, confirm, formClone });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -0,0 +1,157 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:show-close="false"
|
||||
style="width: 80%"
|
||||
center
|
||||
align-center
|
||||
:before-close="resetCheckForm"
|
||||
>
|
||||
<template #header="{ titleId, titleClass }">
|
||||
<div
|
||||
style="font-size: 2rem"
|
||||
class="w-full font-bold"
|
||||
:id="titleId"
|
||||
:class="titleClass"
|
||||
>
|
||||
{{ title }}
|
||||
</div>
|
||||
<div
|
||||
@click="resetCheckForm"
|
||||
class="bg-gray-400 hover:bg-red-600 text-3xl absolute top-0 right-0 cursor-pointer flex justify-center items-center"
|
||||
>
|
||||
<el-icon>
|
||||
<CloseBold />
|
||||
</el-icon>
|
||||
</div>
|
||||
</template>
|
||||
<FormTools @showTools="showTools" :dialogObj="judgmentMsgActive" />
|
||||
<SingleAdd
|
||||
ref="singleAddRef"
|
||||
v-if="dialogSingleVisible"
|
||||
:addData="addData"
|
||||
@addJudgment="addJudgment"
|
||||
/>
|
||||
<MultipleAdd
|
||||
ref="multipleAddRef"
|
||||
v-if="dialogMultipleVisible"
|
||||
:checkNeed="true"
|
||||
:addData="addData"
|
||||
@addJudgment="addJudgment"
|
||||
/>
|
||||
<ExcleAdd ref="excleAddRef" v-if="dialogExcleVisible" @addJudgment="addJudgment" />
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button style="font-weight: bold" @click="resetCheckForm"> 取消 </el-button>
|
||||
<el-button style="font-weight: bold" type="primary" @click="confirm">
|
||||
确定
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { CloseBold } from "@element-plus/icons-vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import FormTools from "../../../operate/formTools.vue";
|
||||
import SingleAdd from "./singleAdd.vue";
|
||||
import MultipleAdd from "./multipleAdd.vue";
|
||||
import ExcleAdd from "./excleAdd.vue";
|
||||
|
||||
import judgmentActiveStore from "../../../../stores/trainindTopic/judgment.js";
|
||||
|
||||
import $http from "../../../../api/index";
|
||||
import $url from "../../../../api/url";
|
||||
|
||||
const judgmentMsgActive = judgmentActiveStore();
|
||||
|
||||
const dialogVisible = ref(false);
|
||||
const singleAddRef = ref(null);
|
||||
const multipleAddRef = ref(null);
|
||||
const excleAddRef = ref(null);
|
||||
const dialogSingleVisible = ref(true);
|
||||
const dialogMultipleVisible = ref(false);
|
||||
const dialogExcleVisible = ref(false);
|
||||
|
||||
const props = defineProps({
|
||||
title: String,
|
||||
addData: Object,
|
||||
});
|
||||
|
||||
const emit = defineEmits(["reloadData"]);
|
||||
|
||||
const showTools = (operateType) => {
|
||||
switch (operateType) {
|
||||
case "single":
|
||||
dialogSingleVisible.value = true;
|
||||
dialogMultipleVisible.value = false;
|
||||
dialogExcleVisible.value = false;
|
||||
judgmentMsgActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
judgmentMsgActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
judgmentMsgActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
case "multiple":
|
||||
dialogSingleVisible.value = false;
|
||||
dialogMultipleVisible.value = true;
|
||||
dialogExcleVisible.value = false;
|
||||
judgmentMsgActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
judgmentMsgActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
judgmentMsgActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
case "excle":
|
||||
dialogSingleVisible.value = false;
|
||||
dialogMultipleVisible.value = false;
|
||||
dialogExcleVisible.value = true;
|
||||
judgmentMsgActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
judgmentMsgActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
judgmentMsgActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (dialogSingleVisible.value) {
|
||||
singleAddRef.value.resetCheckForm();
|
||||
} else if (dialogMultipleVisible.value) {
|
||||
multipleAddRef.value.resetCheckForm();
|
||||
} else if (dialogExcleVisible.value) {
|
||||
excleAddRef.value.resetCheckForm();
|
||||
}
|
||||
dialogVisible.value = false;
|
||||
};
|
||||
|
||||
const confirm = () => {
|
||||
if (dialogSingleVisible.value) {
|
||||
singleAddRef.value.confirm();
|
||||
} else if (dialogMultipleVisible.value) {
|
||||
multipleAddRef.value.confirm();
|
||||
} else if (dialogExcleVisible.value) {
|
||||
excleAddRef.value.confirm();
|
||||
}
|
||||
};
|
||||
|
||||
const addJudgment = (requestMsg) => {
|
||||
const data = { requestMsg };
|
||||
$http.post($url.addJudgment, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
resetCheckForm();
|
||||
ElMessage({
|
||||
message: "新增判断题成功!",
|
||||
type: "success",
|
||||
});
|
||||
emit("reloadData");
|
||||
} else {
|
||||
ElMessage.error("新增判断题失败!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ dialogVisible });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
116
src/components/addNewData/trainindTopic/judgment/multipleAdd.vue
Normal file
116
src/components/addNewData/trainindTopic/judgment/multipleAdd.vue
Normal file
@@ -0,0 +1,116 @@
|
||||
<template>
|
||||
<div>
|
||||
<div
|
||||
style="font-size: 2rem"
|
||||
class="flex flex-warp justify-center items-center font-bold"
|
||||
>
|
||||
<div style="font-size: 1rem">请输入要导入的数据数量:</div>
|
||||
<el-input-number v-model="singleFormNum" :min="1" :max="10" @change="createForm" />
|
||||
<div v-if="checkNeed"> </div>
|
||||
<el-checkbox
|
||||
v-if="checkNeed"
|
||||
v-model="checked"
|
||||
label="为所有表单进行相同操作"
|
||||
size="large"
|
||||
/>
|
||||
</div>
|
||||
<el-scrollbar max-height="40rem">
|
||||
<div class="mt-2 border-2 border-gray-300" v-for="item in input">
|
||||
<div style="font-size: 1.2rem" class="w-full text-center font-bold">
|
||||
{{ item.label }}
|
||||
</div>
|
||||
<SingleAdd ref="singleAddRef" :addData="addData" />
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import SingleAdd from "./singleAdd.vue";
|
||||
|
||||
const singleFormNum = ref(1);
|
||||
const checked = ref(true);
|
||||
const input = ref([{ label: "判断题1" }]);
|
||||
const singleAddRef = ref(null);
|
||||
const formClone = ref([]);
|
||||
|
||||
const props = defineProps({
|
||||
checkNeed: Boolean,
|
||||
addData: Object,
|
||||
});
|
||||
|
||||
const emit = defineEmits(["addJudgment"]);
|
||||
|
||||
const initData = () => {
|
||||
setTimeout(() => {
|
||||
singleAddRef.value.forEach((item) => {
|
||||
item.ruleForm.role = singleAddRef.value[0].ruleForm.role;
|
||||
});
|
||||
}, 100);
|
||||
};
|
||||
|
||||
const createForm = () => {
|
||||
let difference = Math.abs(singleFormNum.value - input.value.length);
|
||||
for (let i = 0; i < difference; i++) {
|
||||
if (singleFormNum.value > input.value.length) {
|
||||
input.value.push({ label: `判断题${input.value.length + 1}` });
|
||||
} else if (singleFormNum.value < input.value.length) {
|
||||
input.value.pop();
|
||||
}
|
||||
}
|
||||
if (checked.value) {
|
||||
initData();
|
||||
}
|
||||
};
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!singleAddRef) return;
|
||||
singleAddRef.value.forEach((element) => {
|
||||
element.resetCheckForm();
|
||||
});
|
||||
singleFormNum.value = 1;
|
||||
createForm();
|
||||
};
|
||||
|
||||
const confirm = () => {
|
||||
if (!singleAddRef) return;
|
||||
let valid = true;
|
||||
formClone.value = [];
|
||||
singleAddRef.value.forEach((element) => {
|
||||
element.validate().then((result) => {
|
||||
if (result) {
|
||||
formClone.value.push({ ...element.ruleForm });
|
||||
} else {
|
||||
valid = result;
|
||||
}
|
||||
});
|
||||
});
|
||||
setTimeout(() => {
|
||||
if (valid) {
|
||||
emit("addJudgment", formClone.value);
|
||||
singleAddRef.value.forEach((item) => {
|
||||
item.resetCheckForm();
|
||||
});
|
||||
ElMessage({
|
||||
message: `提交成功!`,
|
||||
type: "success",
|
||||
});
|
||||
} else {
|
||||
ElMessage.error("提交失败!");
|
||||
}
|
||||
}, 100);
|
||||
};
|
||||
|
||||
defineExpose({ resetCheckForm, confirm, formClone });
|
||||
|
||||
watch(checked, (value) => {
|
||||
if (value) {
|
||||
initData();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
129
src/components/addNewData/trainindTopic/judgment/singleAdd.vue
Normal file
129
src/components/addNewData/trainindTopic/judgment/singleAdd.vue
Normal file
@@ -0,0 +1,129 @@
|
||||
<template>
|
||||
<el-form
|
||||
ref="ruleFormRef"
|
||||
style="max-width: 600px"
|
||||
:model="ruleForm"
|
||||
:rules="rules"
|
||||
label-width="auto"
|
||||
size="default"
|
||||
status-icon
|
||||
class="mx-auto"
|
||||
>
|
||||
<el-form-item class="mx-1 font-bold" label="题干" prop="stem">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入题干"
|
||||
v-model="ruleForm.stem"
|
||||
@input="filter(ruleForm.stem, 'stem')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="答案" prop="answer">
|
||||
<el-select
|
||||
clearable
|
||||
size="small"
|
||||
placeholder="请选择答案"
|
||||
autocomplete="off"
|
||||
v-model="ruleForm.answer"
|
||||
style="width: 100%; font-size: 1rem"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in addData.answerOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
class="text-center"
|
||||
:style="item.style"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="难度" prop="difficulty">
|
||||
<el-select
|
||||
clearable
|
||||
size="small"
|
||||
placeholder="请选择难度"
|
||||
autocomplete="off"
|
||||
v-model="ruleForm.difficulty"
|
||||
style="width: 100%; font-size: 1rem"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in addData.difficultyOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
class="text-center"
|
||||
:style="item.style"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
const ruleFormRef = ref(null);
|
||||
|
||||
const ruleForm = reactive({
|
||||
stem: "",
|
||||
answer: "",
|
||||
difficulty: "",
|
||||
});
|
||||
|
||||
const formClone = ref({});
|
||||
|
||||
const rules = reactive({
|
||||
stem: [{ required: true, message: "请输入题干", trigger: "blur" }],
|
||||
answer: [{ required: true, message: "请选择答案", trigger: "change" }],
|
||||
difficulty: [{ required: true, message: "请选择难度", trigger: "change" }],
|
||||
});
|
||||
|
||||
const emit = defineEmits(["addJudgment"]);
|
||||
|
||||
const filter = (value, label) => {
|
||||
if (/[=\s"'+-]/.test(value)) {
|
||||
if (ruleForm[label]) {
|
||||
ruleForm[label] = value.replace(/[=\s"'+-]/g, "");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const props = defineProps({
|
||||
addData: Object,
|
||||
});
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!ruleFormRef) return;
|
||||
ruleFormRef.value.resetFields();
|
||||
};
|
||||
|
||||
const confirm = async () => {
|
||||
if (!ruleFormRef) return;
|
||||
await ruleFormRef.value.validate((valid) => {
|
||||
if (valid) {
|
||||
formClone.value = { ...ruleForm };
|
||||
emit("addJudgment", [formClone.value]);
|
||||
ruleFormRef.value.resetFields();
|
||||
ElMessage({
|
||||
message: `提交成功!`,
|
||||
type: "success",
|
||||
});
|
||||
} else {
|
||||
ElMessage.error("提交失败!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const validate = () => {
|
||||
if (!ruleFormRef) return Promise.resolve(false);
|
||||
return new Promise((resolve) => {
|
||||
ruleFormRef.value.validate((valid) => {
|
||||
resolve(valid);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ resetCheckForm, confirm, validate, ruleForm, formClone });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
152
src/components/addNewData/trainindTopic/multiple/excleAdd.vue
Normal file
152
src/components/addNewData/trainindTopic/multiple/excleAdd.vue
Normal file
@@ -0,0 +1,152 @@
|
||||
<template>
|
||||
<UploadFile
|
||||
ref="uploadFileRef"
|
||||
:options="options"
|
||||
:relatedRules="relatedRules"
|
||||
:relatedOptions="relatedOptions"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import UploadFile from "../../../operate/uploadFile.vue";
|
||||
|
||||
const uploadFileRef = ref(null);
|
||||
const formClone = ref([]);
|
||||
|
||||
const options = {
|
||||
limit: 1,
|
||||
accept: ".xlsx",
|
||||
action: "",
|
||||
multiple: false,
|
||||
listType: "text",
|
||||
autoUpload: false,
|
||||
};
|
||||
|
||||
const relatedRules = {
|
||||
stem: {
|
||||
value: "",
|
||||
label: "题干",
|
||||
},
|
||||
options_a: {
|
||||
value: "",
|
||||
label: "选项A",
|
||||
},
|
||||
options_b: {
|
||||
value: "",
|
||||
label: "选项B",
|
||||
},
|
||||
options_c: {
|
||||
value: "",
|
||||
label: "选项C",
|
||||
},
|
||||
options_d: {
|
||||
value: "",
|
||||
label: "选项D",
|
||||
},
|
||||
options_e: {
|
||||
value: "",
|
||||
label: "选项E",
|
||||
},
|
||||
answer: {
|
||||
value: "",
|
||||
label: "答案",
|
||||
},
|
||||
difficulty: {
|
||||
value: "",
|
||||
label: "难度",
|
||||
},
|
||||
};
|
||||
|
||||
const relatedOptions = [
|
||||
{
|
||||
value: "0",
|
||||
label: "题干",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "1",
|
||||
label: "选项A",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "2",
|
||||
label: "选项B",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "3",
|
||||
label: "选项C",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "4",
|
||||
label: "选项D",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "5",
|
||||
label: "选项E",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "6",
|
||||
label: "答案",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "7",
|
||||
label: "难度",
|
||||
disabled: false,
|
||||
},
|
||||
];
|
||||
|
||||
const emit = defineEmits(["addMultiple"]);
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!uploadFileRef) return;
|
||||
uploadFileRef.value.handleExceed();
|
||||
};
|
||||
|
||||
const confirm = async () => {
|
||||
if (!uploadFileRef) return;
|
||||
formClone.value = [];
|
||||
const length = uploadFileRef.value.loadData.length;
|
||||
if (length == 0) return ElMessage.error("请先上传文件!");
|
||||
const flag = await uploadFileRef.value.confirm();
|
||||
if (!flag) return ElMessage.error("请先选择表格关联项!");
|
||||
ElMessage({
|
||||
message: `正在上传数据中,请稍等...`,
|
||||
type: "success",
|
||||
});
|
||||
setTimeout(() => {
|
||||
uploadFileRef.value.loadData.forEach((ExcleForm) => {
|
||||
ExcleForm.forEach((worksheet) => {
|
||||
let context = [...worksheet];
|
||||
context.shift();
|
||||
context.forEach((item) => {
|
||||
if (item.length != 0) {
|
||||
formClone.value.push({
|
||||
stem: item[relatedRules.stem.value],
|
||||
options_a: item[relatedRules.options_a.value],
|
||||
options_b: item[relatedRules.options_b.value],
|
||||
options_c: item[relatedRules.options_c.value],
|
||||
options_d: item[relatedRules.options_d.value],
|
||||
options_e: item[relatedRules.options_e.value],
|
||||
answer: item[relatedRules.answer.value],
|
||||
difficulty: item[relatedRules.difficulty.value],
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
emit("addMultiple", formClone.value);
|
||||
}, 3000);
|
||||
};
|
||||
|
||||
defineExpose({ resetCheckForm, confirm, formClone });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
116
src/components/addNewData/trainindTopic/multiple/multipleAdd.vue
Normal file
116
src/components/addNewData/trainindTopic/multiple/multipleAdd.vue
Normal file
@@ -0,0 +1,116 @@
|
||||
<template>
|
||||
<div>
|
||||
<div
|
||||
style="font-size: 2rem"
|
||||
class="flex flex-warp justify-center items-center font-bold"
|
||||
>
|
||||
<div style="font-size: 1rem">请输入要导入的数据数量:</div>
|
||||
<el-input-number v-model="singleFormNum" :min="1" :max="10" @change="createForm" />
|
||||
<div v-if="checkNeed"> </div>
|
||||
<el-checkbox
|
||||
v-if="checkNeed"
|
||||
v-model="checked"
|
||||
label="为所有表单进行相同操作"
|
||||
size="large"
|
||||
/>
|
||||
</div>
|
||||
<el-scrollbar max-height="40rem">
|
||||
<div class="mt-2 border-2 border-gray-300" v-for="item in input">
|
||||
<div style="font-size: 1.2rem" class="w-full text-center font-bold">
|
||||
{{ item.label }}
|
||||
</div>
|
||||
<SingleAdd ref="singleAddRef" :addData="addData" />
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import SingleAdd from "./singleAdd.vue";
|
||||
|
||||
const singleFormNum = ref(1);
|
||||
const checked = ref(true);
|
||||
const input = ref([{ label: "多选题1" }]);
|
||||
const singleAddRef = ref(null);
|
||||
const formClone = ref([]);
|
||||
|
||||
const props = defineProps({
|
||||
checkNeed: Boolean,
|
||||
addData: Object,
|
||||
});
|
||||
|
||||
const emit = defineEmits(["addMultiple"]);
|
||||
|
||||
const initData = () => {
|
||||
setTimeout(() => {
|
||||
singleAddRef.value.forEach((item) => {
|
||||
item.ruleForm.role = singleAddRef.value[0].ruleForm.role;
|
||||
});
|
||||
}, 100);
|
||||
};
|
||||
|
||||
const createForm = () => {
|
||||
let difference = Math.abs(singleFormNum.value - input.value.length);
|
||||
for (let i = 0; i < difference; i++) {
|
||||
if (singleFormNum.value > input.value.length) {
|
||||
input.value.push({ label: `多选题${input.value.length + 1}` });
|
||||
} else if (singleFormNum.value < input.value.length) {
|
||||
input.value.pop();
|
||||
}
|
||||
}
|
||||
if (checked.value) {
|
||||
initData();
|
||||
}
|
||||
};
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!singleAddRef) return;
|
||||
singleAddRef.value.forEach((element) => {
|
||||
element.resetCheckForm();
|
||||
});
|
||||
singleFormNum.value = 1;
|
||||
createForm();
|
||||
};
|
||||
|
||||
const confirm = () => {
|
||||
if (!singleAddRef) return;
|
||||
let valid = true;
|
||||
formClone.value = [];
|
||||
singleAddRef.value.forEach((element) => {
|
||||
element.validate().then((result) => {
|
||||
if (result) {
|
||||
formClone.value.push({ ...element.ruleForm });
|
||||
} else {
|
||||
valid = result;
|
||||
}
|
||||
});
|
||||
});
|
||||
setTimeout(() => {
|
||||
if (valid) {
|
||||
emit("addMultiple", formClone.value);
|
||||
singleAddRef.value.forEach((item) => {
|
||||
item.resetCheckForm();
|
||||
});
|
||||
ElMessage({
|
||||
message: `提交成功!`,
|
||||
type: "success",
|
||||
});
|
||||
} else {
|
||||
ElMessage.error("提交失败!");
|
||||
}
|
||||
}, 100);
|
||||
};
|
||||
|
||||
defineExpose({ resetCheckForm, confirm, formClone });
|
||||
|
||||
watch(checked, (value) => {
|
||||
if (value) {
|
||||
initData();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -0,0 +1,157 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:show-close="false"
|
||||
style="width: 80%"
|
||||
center
|
||||
align-center
|
||||
:before-close="resetCheckForm"
|
||||
>
|
||||
<template #header="{ titleId, titleClass }">
|
||||
<div
|
||||
style="font-size: 2rem"
|
||||
class="w-full font-bold"
|
||||
:id="titleId"
|
||||
:class="titleClass"
|
||||
>
|
||||
{{ title }}
|
||||
</div>
|
||||
<div
|
||||
@click="resetCheckForm"
|
||||
class="bg-gray-400 hover:bg-red-600 text-3xl absolute top-0 right-0 cursor-pointer flex justify-center items-center"
|
||||
>
|
||||
<el-icon>
|
||||
<CloseBold />
|
||||
</el-icon>
|
||||
</div>
|
||||
</template>
|
||||
<FormTools @showTools="showTools" :dialogObj="multipleMsgActive" />
|
||||
<SingleAdd
|
||||
ref="singleAddRef"
|
||||
v-if="dialogSingleVisible"
|
||||
:addData="addData"
|
||||
@addMultiple="addMultiple"
|
||||
/>
|
||||
<MultipleAdd
|
||||
ref="multipleAddRef"
|
||||
v-if="dialogMultipleVisible"
|
||||
:checkNeed="true"
|
||||
:addData="addData"
|
||||
@addMultiple="addMultiple"
|
||||
/>
|
||||
<ExcleAdd ref="excleAddRef" v-if="dialogExcleVisible" @addMultiple="addMultiple" />
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button style="font-weight: bold" @click="resetCheckForm"> 取消 </el-button>
|
||||
<el-button style="font-weight: bold" type="primary" @click="confirm">
|
||||
确定
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { CloseBold } from "@element-plus/icons-vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import FormTools from "../../../operate/formTools.vue";
|
||||
import SingleAdd from "./singleAdd.vue";
|
||||
import MultipleAdd from "./multipleAdd.vue";
|
||||
import ExcleAdd from "./excleAdd.vue";
|
||||
|
||||
import multipleActiveStore from "../../../../stores/trainindTopic/multiple.js";
|
||||
|
||||
import $http from "../../../../api/index";
|
||||
import $url from "../../../../api/url";
|
||||
|
||||
const multipleMsgActive = multipleActiveStore();
|
||||
|
||||
const dialogVisible = ref(false);
|
||||
const singleAddRef = ref(null);
|
||||
const multipleAddRef = ref(null);
|
||||
const excleAddRef = ref(null);
|
||||
const dialogSingleVisible = ref(true);
|
||||
const dialogMultipleVisible = ref(false);
|
||||
const dialogExcleVisible = ref(false);
|
||||
|
||||
const props = defineProps({
|
||||
title: String,
|
||||
addData: Object,
|
||||
});
|
||||
|
||||
const emit = defineEmits(["reloadData"]);
|
||||
|
||||
const showTools = (operateType) => {
|
||||
switch (operateType) {
|
||||
case "single":
|
||||
dialogSingleVisible.value = true;
|
||||
dialogMultipleVisible.value = false;
|
||||
dialogExcleVisible.value = false;
|
||||
multipleMsgActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
multipleMsgActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
multipleMsgActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
case "multiple":
|
||||
dialogSingleVisible.value = false;
|
||||
dialogMultipleVisible.value = true;
|
||||
dialogExcleVisible.value = false;
|
||||
multipleMsgActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
multipleMsgActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
multipleMsgActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
case "excle":
|
||||
dialogSingleVisible.value = false;
|
||||
dialogMultipleVisible.value = false;
|
||||
dialogExcleVisible.value = true;
|
||||
multipleMsgActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
multipleMsgActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
multipleMsgActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (dialogSingleVisible.value) {
|
||||
singleAddRef.value.resetCheckForm();
|
||||
} else if (dialogMultipleVisible.value) {
|
||||
multipleAddRef.value.resetCheckForm();
|
||||
} else if (dialogExcleVisible.value) {
|
||||
excleAddRef.value.resetCheckForm();
|
||||
}
|
||||
dialogVisible.value = false;
|
||||
};
|
||||
|
||||
const confirm = () => {
|
||||
if (dialogSingleVisible.value) {
|
||||
singleAddRef.value.confirm();
|
||||
} else if (dialogMultipleVisible.value) {
|
||||
multipleAddRef.value.confirm();
|
||||
} else if (dialogExcleVisible.value) {
|
||||
excleAddRef.value.confirm();
|
||||
}
|
||||
};
|
||||
|
||||
const addMultiple = (requestMsg) => {
|
||||
const data = { requestMsg };
|
||||
$http.post($url.addMultiple, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
resetCheckForm();
|
||||
ElMessage({
|
||||
message: "新增多选题成功!",
|
||||
type: "success",
|
||||
});
|
||||
emit("reloadData");
|
||||
} else {
|
||||
ElMessage.error("新增多选题失败!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ dialogVisible });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
168
src/components/addNewData/trainindTopic/multiple/singleAdd.vue
Normal file
168
src/components/addNewData/trainindTopic/multiple/singleAdd.vue
Normal file
@@ -0,0 +1,168 @@
|
||||
<template>
|
||||
<el-form
|
||||
ref="ruleFormRef"
|
||||
style="max-width: 600px"
|
||||
:model="ruleForm"
|
||||
:rules="rules"
|
||||
label-width="auto"
|
||||
size="default"
|
||||
status-icon
|
||||
class="mx-auto"
|
||||
>
|
||||
<el-form-item class="mx-1 font-bold" label="题干" prop="stem">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入题干"
|
||||
v-model="ruleForm.stem"
|
||||
@input="filter(ruleForm.stem, 'stem')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="选项A" prop="options_a">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入选项A"
|
||||
v-model="ruleForm.options_a"
|
||||
@input="filter(ruleForm.options_a, 'options_a')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="选项B" prop="options_b">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入选项B"
|
||||
v-model="ruleForm.options_b"
|
||||
@input="filter(ruleForm.options_b, 'options_b')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="选项C" prop="options_c">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入选项C"
|
||||
v-model="ruleForm.options_c"
|
||||
@input="filter(ruleForm.options_c, 'options_c')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="选项D" prop="options_d">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入选项D"
|
||||
v-model="ruleForm.options_d"
|
||||
@input="filter(ruleForm.options_d, 'options_d')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="选项E" prop="options_e">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入选项E"
|
||||
v-model="ruleForm.options_e"
|
||||
@input="filter(ruleForm.options_e, 'options_e')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="答案" prop="answer">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入答案"
|
||||
v-model="ruleForm.answer"
|
||||
@input="filter(ruleForm.answer, 'answer')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="难度" prop="difficulty">
|
||||
<el-select
|
||||
clearable
|
||||
size="small"
|
||||
placeholder="请选择难度"
|
||||
autocomplete="off"
|
||||
v-model="ruleForm.difficulty"
|
||||
style="width: 100%; font-size: 1rem"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in addData.difficultyOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
class="text-center"
|
||||
:style="item.style"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
const ruleFormRef = ref(null);
|
||||
|
||||
const ruleForm = reactive({
|
||||
stem: "",
|
||||
options_a: "",
|
||||
options_b: "",
|
||||
options_c: "",
|
||||
options_d: "",
|
||||
options_e: "",
|
||||
answer: "",
|
||||
difficulty: "",
|
||||
});
|
||||
|
||||
const formClone = ref({});
|
||||
|
||||
const rules = reactive({
|
||||
stem: [{ required: true, message: "请输入题干", trigger: "blur" }],
|
||||
options_a: [{ required: true, message: "请输入选项A", trigger: "blur" }],
|
||||
options_b: [{ required: true, message: "请输入选项B", trigger: "blur" }],
|
||||
options_c: [{ required: true, message: "请输入选项C", trigger: "blur" }],
|
||||
options_d: [{ required: true, message: "请输入选项D", trigger: "blur" }],
|
||||
options_e: [{ required: true, message: "请输入选项E", trigger: "blur" }],
|
||||
answer: [{ required: true, message: "请输入答案", trigger: "blur" }],
|
||||
difficulty: [{ required: true, message: "请选择难度", trigger: "change" }],
|
||||
});
|
||||
|
||||
const emit = defineEmits(["addMultiple"]);
|
||||
|
||||
const filter = (value, label) => {
|
||||
if (/[=\s"'+-]/.test(value)) {
|
||||
if (ruleForm[label]) {
|
||||
ruleForm[label] = value.replace(/[=\s"'+-]/g, "");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const props = defineProps({
|
||||
addData: Object,
|
||||
});
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!ruleFormRef) return;
|
||||
ruleFormRef.value.resetFields();
|
||||
};
|
||||
|
||||
const confirm = async () => {
|
||||
if (!ruleFormRef) return;
|
||||
await ruleFormRef.value.validate((valid) => {
|
||||
if (valid) {
|
||||
formClone.value = { ...ruleForm };
|
||||
emit("addMultiple", [formClone.value]);
|
||||
ruleFormRef.value.resetFields();
|
||||
ElMessage({
|
||||
message: `提交成功!`,
|
||||
type: "success",
|
||||
});
|
||||
} else {
|
||||
ElMessage.error("提交失败!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const validate = () => {
|
||||
if (!ruleFormRef) return Promise.resolve(false);
|
||||
return new Promise((resolve) => {
|
||||
ruleFormRef.value.validate((valid) => {
|
||||
resolve(valid);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ resetCheckForm, confirm, validate, ruleForm, formClone });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
142
src/components/addNewData/trainindTopic/radio/excleAdd.vue
Normal file
142
src/components/addNewData/trainindTopic/radio/excleAdd.vue
Normal file
@@ -0,0 +1,142 @@
|
||||
<template>
|
||||
<UploadFile
|
||||
ref="uploadFileRef"
|
||||
:options="options"
|
||||
:relatedRules="relatedRules"
|
||||
:relatedOptions="relatedOptions"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import UploadFile from "../../../operate/uploadFile.vue";
|
||||
|
||||
const uploadFileRef = ref(null);
|
||||
const formClone = ref([]);
|
||||
|
||||
const options = {
|
||||
limit: 1,
|
||||
accept: ".xlsx",
|
||||
action: "",
|
||||
multiple: false,
|
||||
listType: "text",
|
||||
autoUpload: false,
|
||||
};
|
||||
|
||||
const relatedRules = {
|
||||
stem: {
|
||||
value: "",
|
||||
label: "题干",
|
||||
},
|
||||
options_a: {
|
||||
value: "",
|
||||
label: "选项A",
|
||||
},
|
||||
options_b: {
|
||||
value: "",
|
||||
label: "选项B",
|
||||
},
|
||||
options_c: {
|
||||
value: "",
|
||||
label: "选项C",
|
||||
},
|
||||
options_d: {
|
||||
value: "",
|
||||
label: "选项D",
|
||||
},
|
||||
answer: {
|
||||
value: "",
|
||||
label: "答案",
|
||||
},
|
||||
difficulty: {
|
||||
value: "",
|
||||
label: "难度",
|
||||
},
|
||||
};
|
||||
|
||||
const relatedOptions = [
|
||||
{
|
||||
value: "0",
|
||||
label: "题干",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "1",
|
||||
label: "选项A",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "2",
|
||||
label: "选项B",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "3",
|
||||
label: "选项C",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "4",
|
||||
label: "选项D",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "5",
|
||||
label: "答案",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "6",
|
||||
label: "难度",
|
||||
disabled: false,
|
||||
},
|
||||
];
|
||||
|
||||
const emit = defineEmits(["addRadio"]);
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!uploadFileRef) return;
|
||||
uploadFileRef.value.handleExceed();
|
||||
};
|
||||
|
||||
const confirm = async () => {
|
||||
if (!uploadFileRef) return;
|
||||
formClone.value = [];
|
||||
const length = uploadFileRef.value.loadData.length;
|
||||
if (length == 0) return ElMessage.error("请先上传文件!");
|
||||
const flag = await uploadFileRef.value.confirm();
|
||||
if (!flag) return ElMessage.error("请先选择表格关联项!");
|
||||
ElMessage({
|
||||
message: `正在上传数据中,请稍等...`,
|
||||
type: "success",
|
||||
});
|
||||
setTimeout(() => {
|
||||
uploadFileRef.value.loadData.forEach((ExcleForm) => {
|
||||
ExcleForm.forEach((worksheet) => {
|
||||
let context = [...worksheet];
|
||||
context.shift();
|
||||
context.forEach((item) => {
|
||||
if (item.length != 0) {
|
||||
formClone.value.push({
|
||||
stem: item[relatedRules.stem.value],
|
||||
options_a: item[relatedRules.options_a.value],
|
||||
options_b: item[relatedRules.options_b.value],
|
||||
options_c: item[relatedRules.options_c.value],
|
||||
options_d: item[relatedRules.options_d.value],
|
||||
answer: item[relatedRules.answer.value],
|
||||
difficulty: item[relatedRules.difficulty.value],
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
emit("addRadio", formClone.value);
|
||||
}, 3000);
|
||||
};
|
||||
|
||||
defineExpose({ resetCheckForm, confirm, formClone });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
116
src/components/addNewData/trainindTopic/radio/multipleAdd.vue
Normal file
116
src/components/addNewData/trainindTopic/radio/multipleAdd.vue
Normal file
@@ -0,0 +1,116 @@
|
||||
<template>
|
||||
<div>
|
||||
<div
|
||||
style="font-size: 2rem"
|
||||
class="flex flex-warp justify-center items-center font-bold"
|
||||
>
|
||||
<div style="font-size: 1rem">请输入要导入的数据数量:</div>
|
||||
<el-input-number v-model="singleFormNum" :min="1" :max="10" @change="createForm" />
|
||||
<div v-if="checkNeed"> </div>
|
||||
<el-checkbox
|
||||
v-if="checkNeed"
|
||||
v-model="checked"
|
||||
label="为所有表单进行相同操作"
|
||||
size="large"
|
||||
/>
|
||||
</div>
|
||||
<el-scrollbar max-height="40rem">
|
||||
<div class="mt-2 border-2 border-gray-300" v-for="item in input">
|
||||
<div style="font-size: 1.2rem" class="w-full text-center font-bold">
|
||||
{{ item.label }}
|
||||
</div>
|
||||
<SingleAdd ref="singleAddRef" :addData="addData" />
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import SingleAdd from "./singleAdd.vue";
|
||||
|
||||
const singleFormNum = ref(1);
|
||||
const checked = ref(true);
|
||||
const input = ref([{ label: "单选题1" }]);
|
||||
const singleAddRef = ref(null);
|
||||
const formClone = ref([]);
|
||||
|
||||
const props = defineProps({
|
||||
checkNeed: Boolean,
|
||||
addData: Object,
|
||||
});
|
||||
|
||||
const emit = defineEmits(["addRadio"]);
|
||||
|
||||
const initData = () => {
|
||||
setTimeout(() => {
|
||||
singleAddRef.value.forEach((item) => {
|
||||
item.ruleForm.role = singleAddRef.value[0].ruleForm.role;
|
||||
});
|
||||
}, 100);
|
||||
};
|
||||
|
||||
const createForm = () => {
|
||||
let difference = Math.abs(singleFormNum.value - input.value.length);
|
||||
for (let i = 0; i < difference; i++) {
|
||||
if (singleFormNum.value > input.value.length) {
|
||||
input.value.push({ label: `单选题${input.value.length + 1}` });
|
||||
} else if (singleFormNum.value < input.value.length) {
|
||||
input.value.pop();
|
||||
}
|
||||
}
|
||||
if (checked.value) {
|
||||
initData();
|
||||
}
|
||||
};
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!singleAddRef) return;
|
||||
singleAddRef.value.forEach((element) => {
|
||||
element.resetCheckForm();
|
||||
});
|
||||
singleFormNum.value = 1;
|
||||
createForm();
|
||||
};
|
||||
|
||||
const confirm = () => {
|
||||
if (!singleAddRef) return;
|
||||
let valid = true;
|
||||
formClone.value = [];
|
||||
singleAddRef.value.forEach((element) => {
|
||||
element.validate().then((result) => {
|
||||
if (result) {
|
||||
formClone.value.push({ ...element.ruleForm });
|
||||
} else {
|
||||
valid = result;
|
||||
}
|
||||
});
|
||||
});
|
||||
setTimeout(() => {
|
||||
if (valid) {
|
||||
emit("addRadio", formClone.value);
|
||||
singleAddRef.value.forEach((item) => {
|
||||
item.resetCheckForm();
|
||||
});
|
||||
ElMessage({
|
||||
message: `提交成功!`,
|
||||
type: "success",
|
||||
});
|
||||
} else {
|
||||
ElMessage.error("提交失败!");
|
||||
}
|
||||
}, 100);
|
||||
};
|
||||
|
||||
defineExpose({ resetCheckForm, confirm, formClone });
|
||||
|
||||
watch(checked, (value) => {
|
||||
if (value) {
|
||||
initData();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
157
src/components/addNewData/trainindTopic/radio/radioForm.vue
Normal file
157
src/components/addNewData/trainindTopic/radio/radioForm.vue
Normal file
@@ -0,0 +1,157 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:show-close="false"
|
||||
style="width: 80%"
|
||||
center
|
||||
align-center
|
||||
:before-close="resetCheckForm"
|
||||
>
|
||||
<template #header="{ titleId, titleClass }">
|
||||
<div
|
||||
style="font-size: 2rem"
|
||||
class="w-full font-bold"
|
||||
:id="titleId"
|
||||
:class="titleClass"
|
||||
>
|
||||
{{ title }}
|
||||
</div>
|
||||
<div
|
||||
@click="resetCheckForm"
|
||||
class="bg-gray-400 hover:bg-red-600 text-3xl absolute top-0 right-0 cursor-pointer flex justify-center items-center"
|
||||
>
|
||||
<el-icon>
|
||||
<CloseBold />
|
||||
</el-icon>
|
||||
</div>
|
||||
</template>
|
||||
<FormTools @showTools="showTools" :dialogObj="radioMsgActive" />
|
||||
<SingleAdd
|
||||
ref="singleAddRef"
|
||||
v-if="dialogSingleVisible"
|
||||
:addData="addData"
|
||||
@addRadio="addRadio"
|
||||
/>
|
||||
<MultipleAdd
|
||||
ref="multipleAddRef"
|
||||
v-if="dialogMultipleVisible"
|
||||
:checkNeed="true"
|
||||
:addData="addData"
|
||||
@addRadio="addRadio"
|
||||
/>
|
||||
<ExcleAdd ref="excleAddRef" v-if="dialogExcleVisible" @addRadio="addRadio" />
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button style="font-weight: bold" @click="resetCheckForm"> 取消 </el-button>
|
||||
<el-button style="font-weight: bold" type="primary" @click="confirm">
|
||||
确定
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { CloseBold } from "@element-plus/icons-vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import FormTools from "../../../operate/formTools.vue";
|
||||
import SingleAdd from "./singleAdd.vue";
|
||||
import MultipleAdd from "./multipleAdd.vue";
|
||||
import ExcleAdd from "./excleAdd.vue";
|
||||
|
||||
import radioActiveStore from "../../../../stores/trainindTopic/radio.js";
|
||||
|
||||
import $http from "../../../../api/index";
|
||||
import $url from "../../../../api/url";
|
||||
|
||||
const radioMsgActive = radioActiveStore();
|
||||
|
||||
const dialogVisible = ref(false);
|
||||
const singleAddRef = ref(null);
|
||||
const multipleAddRef = ref(null);
|
||||
const excleAddRef = ref(null);
|
||||
const dialogSingleVisible = ref(true);
|
||||
const dialogMultipleVisible = ref(false);
|
||||
const dialogExcleVisible = ref(false);
|
||||
|
||||
const props = defineProps({
|
||||
title: String,
|
||||
addData: Object,
|
||||
});
|
||||
|
||||
const emit = defineEmits(["reloadData"]);
|
||||
|
||||
const showTools = (operateType) => {
|
||||
switch (operateType) {
|
||||
case "single":
|
||||
dialogSingleVisible.value = true;
|
||||
dialogMultipleVisible.value = false;
|
||||
dialogExcleVisible.value = false;
|
||||
radioMsgActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
radioMsgActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
radioMsgActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
case "multiple":
|
||||
dialogSingleVisible.value = false;
|
||||
dialogMultipleVisible.value = true;
|
||||
dialogExcleVisible.value = false;
|
||||
radioMsgActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
radioMsgActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
radioMsgActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
case "excle":
|
||||
dialogSingleVisible.value = false;
|
||||
dialogMultipleVisible.value = false;
|
||||
dialogExcleVisible.value = true;
|
||||
radioMsgActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
radioMsgActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
radioMsgActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (dialogSingleVisible.value) {
|
||||
singleAddRef.value.resetCheckForm();
|
||||
} else if (dialogMultipleVisible.value) {
|
||||
multipleAddRef.value.resetCheckForm();
|
||||
} else if (dialogExcleVisible.value) {
|
||||
excleAddRef.value.resetCheckForm();
|
||||
}
|
||||
dialogVisible.value = false;
|
||||
};
|
||||
|
||||
const confirm = () => {
|
||||
if (dialogSingleVisible.value) {
|
||||
singleAddRef.value.confirm();
|
||||
} else if (dialogMultipleVisible.value) {
|
||||
multipleAddRef.value.confirm();
|
||||
} else if (dialogExcleVisible.value) {
|
||||
excleAddRef.value.confirm();
|
||||
}
|
||||
};
|
||||
|
||||
const addRadio = (requestMsg) => {
|
||||
const data = { requestMsg };
|
||||
$http.post($url.addRadio, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
resetCheckForm();
|
||||
ElMessage({
|
||||
message: "新增单选题成功!",
|
||||
type: "success",
|
||||
});
|
||||
emit("reloadData");
|
||||
} else {
|
||||
ElMessage.error("新增单选题失败!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ dialogVisible });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
158
src/components/addNewData/trainindTopic/radio/singleAdd.vue
Normal file
158
src/components/addNewData/trainindTopic/radio/singleAdd.vue
Normal file
@@ -0,0 +1,158 @@
|
||||
<template>
|
||||
<el-form
|
||||
ref="ruleFormRef"
|
||||
style="max-width: 600px"
|
||||
:model="ruleForm"
|
||||
:rules="rules"
|
||||
label-width="auto"
|
||||
size="default"
|
||||
status-icon
|
||||
class="mx-auto"
|
||||
>
|
||||
<el-form-item class="mx-1 font-bold" label="题干" prop="stem">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入题干"
|
||||
v-model="ruleForm.stem"
|
||||
@input="filter(ruleForm.stem, 'stem')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="选项A" prop="options_a">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入选项A"
|
||||
v-model="ruleForm.options_a"
|
||||
@input="filter(ruleForm.options_a, 'options_a')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="选项B" prop="options_b">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入选项B"
|
||||
v-model="ruleForm.options_b"
|
||||
@input="filter(ruleForm.options_b, 'options_b')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="选项C" prop="options_c">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入选项C"
|
||||
v-model="ruleForm.options_c"
|
||||
@input="filter(ruleForm.options_c, 'options_c')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="选项D" prop="options_d">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入选项D"
|
||||
v-model="ruleForm.options_d"
|
||||
@input="filter(ruleForm.options_d, 'options_d')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="答案" prop="answer">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入答案"
|
||||
v-model="ruleForm.answer"
|
||||
@input="filter(ruleForm.answer, 'answer')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="难度" prop="difficulty">
|
||||
<el-select
|
||||
clearable
|
||||
size="small"
|
||||
placeholder="请选择难度"
|
||||
autocomplete="off"
|
||||
v-model="ruleForm.difficulty"
|
||||
style="width: 100%; font-size: 1rem"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in addData.difficultyOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
class="text-center"
|
||||
:style="item.style"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
const ruleFormRef = ref(null);
|
||||
|
||||
const ruleForm = reactive({
|
||||
stem: "",
|
||||
options_a: "",
|
||||
options_b: "",
|
||||
options_c: "",
|
||||
options_d: "",
|
||||
answer: "",
|
||||
difficulty: "",
|
||||
});
|
||||
|
||||
const formClone = ref({});
|
||||
|
||||
const rules = reactive({
|
||||
stem: [{ required: true, message: "请输入题干", trigger: "blur" }],
|
||||
options_a: [{ required: true, message: "请输入选项A", trigger: "blur" }],
|
||||
options_b: [{ required: true, message: "请输入选项B", trigger: "blur" }],
|
||||
options_c: [{ required: true, message: "请输入选项C", trigger: "blur" }],
|
||||
options_d: [{ required: true, message: "请输入选项D", trigger: "blur" }],
|
||||
answer: [{ required: true, message: "请输入答案", trigger: "blur" }],
|
||||
difficulty: [{ required: true, message: "请选择难度", trigger: "change" }],
|
||||
});
|
||||
|
||||
const emit = defineEmits(["addRadio"]);
|
||||
|
||||
const filter = (value, label) => {
|
||||
if (/[=\s"'+-]/.test(value)) {
|
||||
if (ruleForm[label]) {
|
||||
ruleForm[label] = value.replace(/[=\s"'+-]/g, "");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const props = defineProps({
|
||||
addData: Object,
|
||||
});
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!ruleFormRef) return;
|
||||
ruleFormRef.value.resetFields();
|
||||
};
|
||||
|
||||
const confirm = async () => {
|
||||
if (!ruleFormRef) return;
|
||||
await ruleFormRef.value.validate((valid) => {
|
||||
if (valid) {
|
||||
formClone.value = { ...ruleForm };
|
||||
emit("addRadio", [formClone.value]);
|
||||
ruleFormRef.value.resetFields();
|
||||
ElMessage({
|
||||
message: `提交成功!`,
|
||||
type: "success",
|
||||
});
|
||||
} else {
|
||||
ElMessage.error("提交失败!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const validate = () => {
|
||||
if (!ruleFormRef) return Promise.resolve(false);
|
||||
return new Promise((resolve) => {
|
||||
ruleFormRef.value.validate((valid) => {
|
||||
resolve(valid);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ resetCheckForm, confirm, validate, ruleForm, formClone });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
132
src/components/addNewData/userForm/excleAdd.vue
Normal file
132
src/components/addNewData/userForm/excleAdd.vue
Normal file
@@ -0,0 +1,132 @@
|
||||
<template>
|
||||
<UploadFile
|
||||
ref="uploadFileRef"
|
||||
:options="options"
|
||||
:relatedRules="relatedRules"
|
||||
:relatedOptions="relatedOptions"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import UploadFile from "../../operate/uploadFile.vue";
|
||||
|
||||
const uploadFileRef = ref(null);
|
||||
const formClone = ref([]);
|
||||
|
||||
const options = {
|
||||
limit: 1,
|
||||
accept: ".xlsx",
|
||||
action: "",
|
||||
multiple: false,
|
||||
listType: "text",
|
||||
autoUpload: false,
|
||||
};
|
||||
|
||||
const relatedRules = {
|
||||
phone: {
|
||||
value: "",
|
||||
label: "手机号码",
|
||||
},
|
||||
user_name: {
|
||||
value: "",
|
||||
label: "真实姓名",
|
||||
},
|
||||
identity_card: {
|
||||
value: "",
|
||||
label: "身份证号",
|
||||
},
|
||||
workplace: {
|
||||
value: "",
|
||||
label: "工作单位",
|
||||
},
|
||||
email: {
|
||||
value: "",
|
||||
label: "电子邮箱",
|
||||
},
|
||||
address: {
|
||||
value: "",
|
||||
label: "通讯地址",
|
||||
},
|
||||
};
|
||||
|
||||
const relatedOptions = [
|
||||
{
|
||||
value: "0",
|
||||
label: "手机号码",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "1",
|
||||
label: "真实姓名",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "2",
|
||||
label: "身份证号",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "3",
|
||||
label: "工作单位",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "4",
|
||||
label: "电子邮箱",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "5",
|
||||
label: "通讯地址",
|
||||
disabled: false,
|
||||
},
|
||||
];
|
||||
|
||||
const emit = defineEmits(["addUser"]);
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!uploadFileRef) return;
|
||||
uploadFileRef.value.handleExceed();
|
||||
};
|
||||
|
||||
const confirm = async () => {
|
||||
if (!uploadFileRef) return;
|
||||
formClone.value = [];
|
||||
const length = uploadFileRef.value.loadData.length;
|
||||
if (length == 0) return ElMessage.error("请先上传文件!");
|
||||
const flag = await uploadFileRef.value.confirm();
|
||||
if (!flag) return ElMessage.error("请先选择表格关联项!");
|
||||
ElMessage({
|
||||
message: `正在上传数据中,请稍等...`,
|
||||
type: "success",
|
||||
});
|
||||
setTimeout(() => {
|
||||
uploadFileRef.value.loadData.forEach((ExcleForm) => {
|
||||
ExcleForm.forEach((worksheet) => {
|
||||
let context = [...worksheet];
|
||||
context.shift();
|
||||
context.forEach((item) => {
|
||||
if (item.length != 0) {
|
||||
formClone.value.push({
|
||||
user_name: item[relatedRules.user_name.value],
|
||||
identity_card: item[relatedRules.identity_card.value],
|
||||
workplace: item[relatedRules.workplace.value],
|
||||
address: item[relatedRules.address.value],
|
||||
phone: item[relatedRules.phone.value],
|
||||
email: item[relatedRules.email.value],
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
emit("addUser", formClone.value);
|
||||
}, 3000);
|
||||
};
|
||||
|
||||
defineExpose({ resetCheckForm, confirm, formClone });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
114
src/components/addNewData/userForm/multipleAdd.vue
Normal file
114
src/components/addNewData/userForm/multipleAdd.vue
Normal file
@@ -0,0 +1,114 @@
|
||||
<template>
|
||||
<div>
|
||||
<div
|
||||
style="font-size: 2rem"
|
||||
class="flex flex-warp justify-center items-center font-bold"
|
||||
>
|
||||
<div style="font-size: 1rem">请输入要导入的数据数量:</div>
|
||||
<el-input-number v-model="singleFormNum" :min="1" :max="10" @change="createForm" />
|
||||
<div v-if="checkNeed"> </div>
|
||||
<el-checkbox
|
||||
v-if="checkNeed"
|
||||
v-model="checked"
|
||||
label="为所有表单进行相同操作"
|
||||
size="large"
|
||||
/>
|
||||
</div>
|
||||
<el-scrollbar max-height="40rem">
|
||||
<div class="mt-2 border-2 border-gray-300" v-for="item in input">
|
||||
<div style="font-size: 1.2rem" class="w-full text-center font-bold">
|
||||
{{ item.label }}
|
||||
</div>
|
||||
<SingleAdd ref="singleAddRef" :addData="addData" />
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import SingleAdd from "./singleAdd.vue";
|
||||
|
||||
const singleFormNum = ref(1);
|
||||
const checked = ref(true);
|
||||
const input = ref([{ label: "用户1" }]);
|
||||
const singleAddRef = ref(null);
|
||||
const formClone = ref([]);
|
||||
|
||||
const props = defineProps({
|
||||
checkNeed: Boolean,
|
||||
addData: Object,
|
||||
});
|
||||
|
||||
const emit = defineEmits(["addUser"]);
|
||||
|
||||
const initData = () => {
|
||||
setTimeout(() => {
|
||||
singleAddRef.value.forEach((item) => {});
|
||||
}, 100);
|
||||
};
|
||||
|
||||
const createForm = () => {
|
||||
let difference = Math.abs(singleFormNum.value - input.value.length);
|
||||
for (let i = 0; i < difference; i++) {
|
||||
if (singleFormNum.value > input.value.length) {
|
||||
input.value.push({ label: `用户${input.value.length + 1}` });
|
||||
} else if (singleFormNum.value < input.value.length) {
|
||||
input.value.pop();
|
||||
}
|
||||
}
|
||||
if (checked.value) {
|
||||
initData();
|
||||
}
|
||||
};
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!singleAddRef) return;
|
||||
singleAddRef.value.forEach((element) => {
|
||||
element.resetCheckForm();
|
||||
});
|
||||
singleFormNum.value = 1;
|
||||
createForm();
|
||||
};
|
||||
|
||||
const confirm = () => {
|
||||
if (!singleAddRef) return;
|
||||
let valid = true;
|
||||
formClone.value = [];
|
||||
singleAddRef.value.forEach((element) => {
|
||||
element.validate().then((result) => {
|
||||
if (result) {
|
||||
formClone.value.push({ ...element.ruleForm });
|
||||
} else {
|
||||
valid = result;
|
||||
}
|
||||
});
|
||||
});
|
||||
setTimeout(() => {
|
||||
if (valid) {
|
||||
emit("addUser", formClone.value);
|
||||
singleAddRef.value.forEach((item) => {
|
||||
item.resetCheckForm();
|
||||
});
|
||||
ElMessage({
|
||||
message: `提交成功!`,
|
||||
type: "success",
|
||||
});
|
||||
} else {
|
||||
ElMessage.error("提交失败!");
|
||||
}
|
||||
}, 100);
|
||||
};
|
||||
|
||||
defineExpose({ resetCheckForm, confirm, formClone });
|
||||
|
||||
watch(checked, (value) => {
|
||||
if (value) {
|
||||
initData();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
224
src/components/addNewData/userForm/singleAdd.vue
Normal file
224
src/components/addNewData/userForm/singleAdd.vue
Normal file
@@ -0,0 +1,224 @@
|
||||
<template>
|
||||
<el-form
|
||||
ref="ruleFormRef"
|
||||
style="max-width: 600px"
|
||||
:model="ruleForm"
|
||||
:rules="rules"
|
||||
label-width="auto"
|
||||
size="default"
|
||||
status-icon
|
||||
class="mx-auto"
|
||||
>
|
||||
<el-form-item class="mx-1 font-bold" label="姓名" prop="user_name">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入姓名"
|
||||
minlength="2"
|
||||
maxlength="10"
|
||||
v-model="ruleForm.user_name"
|
||||
@input="filter(ruleForm.user_name, 'user_name')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="身份证号" prop="identity_card">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入身份证号"
|
||||
minlength="18"
|
||||
maxlength="18"
|
||||
v-model="ruleForm.identity_card"
|
||||
@input="filter(ruleForm.identity_card, 'identity_card')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="工作单位" prop="workplace">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入工作单位"
|
||||
maxlength="60"
|
||||
v-model="ruleForm.workplace"
|
||||
@input="filter(ruleForm.workplace, 'workplace')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="通讯地址" prop="address">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入通讯地址"
|
||||
maxlength="120"
|
||||
v-model="ruleForm.address"
|
||||
@input="filter(ruleForm.address, 'address')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="手机号码" prop="phone">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入手机号码"
|
||||
minlength="11"
|
||||
maxlength="11"
|
||||
v-model="ruleForm.phone"
|
||||
@input="filter(ruleForm.phone, 'phone')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="电子邮箱号码" prop="email">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入电子邮箱号码"
|
||||
minlength="8"
|
||||
maxlength="60"
|
||||
v-model="ruleForm.email"
|
||||
@input="filter(ruleForm.email, 'email')"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import $http from "../../../api/index";
|
||||
import $url from "../../../api/url";
|
||||
|
||||
const ruleFormRef = ref(null);
|
||||
|
||||
const ruleForm = reactive({
|
||||
user_name: "",
|
||||
identity_card: "",
|
||||
workplace: "",
|
||||
address: "",
|
||||
phone: "",
|
||||
email: "",
|
||||
});
|
||||
|
||||
const formClone = ref({});
|
||||
|
||||
const identityCardRegex = /^[1-9](?:\d{5})(?:19|20)?\d{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12]\d|3[01])\d{3}(?:\d|X|x)$/;
|
||||
const phoneRegex = /^(?:(?:\+|00)86)?1(?:(?:3[\d])|(?:4[5-79])|(?:5[0-35-9])|(?:6[5-7])|(?:7[0-8])|(?:8[\d])|(?:9[0123456789]))\d{8}$/;
|
||||
const emailRegex = /^([a-zA-Z0-9]+[|-|.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[|-|.]?)*[a-zA-Z0-9]+(.[a-zA-Z]{2,3})+$/;
|
||||
|
||||
const validateIdentityCard = (rule, value, callback) => {
|
||||
if (value === "") {
|
||||
callback(new Error("请输入身份证号"));
|
||||
} else if (!identityCardRegex.test(value)) {
|
||||
callback(new Error("身份证格式不正确,请重新输入!"));
|
||||
} else {
|
||||
const data = {
|
||||
identity_card: value,
|
||||
type: "register",
|
||||
data: "null",
|
||||
};
|
||||
$http.post($url.diffIdentityCard, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
callback();
|
||||
} else {
|
||||
callback(new Error("该身份证号已被注册"));
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const validatePhone = (rule, value, callback) => {
|
||||
if (value === "") {
|
||||
callback(new Error("请输入手机号码"));
|
||||
} else if (!phoneRegex.test(value)) {
|
||||
callback(new Error("手机号码格式错误, 请重新输入!"));
|
||||
} else {
|
||||
const data = {
|
||||
phone: value,
|
||||
type: "register",
|
||||
data: "null",
|
||||
};
|
||||
$http.post($url.diffPhone, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
callback();
|
||||
} else {
|
||||
callback(new Error("该手机号码已被注册"));
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const validateEmail = (rule, value, callback) => {
|
||||
if (value === "") {
|
||||
callback(new Error("请输入电子邮箱号码"));
|
||||
} else if (!emailRegex.test(value)) {
|
||||
callback(new Error("电子邮箱号码格式不正确,请重新输入!"));
|
||||
} else {
|
||||
const data = {
|
||||
email: value,
|
||||
type: "register",
|
||||
data: "null",
|
||||
};
|
||||
$http.post($url.diffEmail, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
callback();
|
||||
} else {
|
||||
callback(new Error("该电子邮箱号码已被注册"));
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const rules = reactive({
|
||||
user_name: [{ required: true, message: "请输入姓名", trigger: "blur" }],
|
||||
identity_card: [{ required: true, validator: validateIdentityCard, trigger: "blur" }],
|
||||
workplace: {
|
||||
required: true,
|
||||
message: "请输入工作单位(若没有则填“无”)",
|
||||
trigger: "blur",
|
||||
},
|
||||
address: { required: true, message: "请输入通讯地址(若没有则填“无”)", trigger: "blur" },
|
||||
phone: [{ required: true, validator: validatePhone, trigger: "blur" }],
|
||||
email: [
|
||||
{ required: true, validator: validateEmail, trigger: "blur" },
|
||||
{ type: "email", message: "请输入正确的邮箱地址", trigger: ["blur", "change"] },
|
||||
],
|
||||
});
|
||||
|
||||
const emit = defineEmits(["addUser"]);
|
||||
|
||||
const filter = (value, label) => {
|
||||
if (label == "phone") {
|
||||
ruleForm.phone = value.replace(/\D/g, "");
|
||||
} else {
|
||||
ruleForm[label] = value.replace(/[=\s"'+-]/g, "");
|
||||
}
|
||||
};
|
||||
|
||||
const props = defineProps({
|
||||
addData: Object,
|
||||
});
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!ruleFormRef) return;
|
||||
ruleFormRef.value.resetFields();
|
||||
};
|
||||
|
||||
const confirm = async () => {
|
||||
if (!ruleFormRef) return;
|
||||
await ruleFormRef.value.validate((valid) => {
|
||||
if (valid) {
|
||||
formClone.value = { ...ruleForm };
|
||||
emit("addUser", [formClone.value]);
|
||||
ruleFormRef.value.resetFields();
|
||||
ElMessage({
|
||||
message: `提交成功!`,
|
||||
type: "success",
|
||||
});
|
||||
} else {
|
||||
ElMessage.error("提交失败!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const validate = () => {
|
||||
if (!ruleFormRef) return Promise.resolve(false);
|
||||
return new Promise((resolve) => {
|
||||
ruleFormRef.value.validate((valid) => {
|
||||
resolve(valid);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ resetCheckForm, confirm, validate, ruleForm, formClone });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
170
src/components/addNewData/userForm/userForm.vue
Normal file
170
src/components/addNewData/userForm/userForm.vue
Normal file
@@ -0,0 +1,170 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:show-close="false"
|
||||
style="width: 80%"
|
||||
center
|
||||
align-center
|
||||
:before-close="resetCheckForm"
|
||||
>
|
||||
<template #header="{ titleId, titleClass }">
|
||||
<div
|
||||
style="font-size: 2rem"
|
||||
class="w-full font-bold"
|
||||
:id="titleId"
|
||||
:class="titleClass"
|
||||
>
|
||||
{{ title }}
|
||||
</div>
|
||||
<div
|
||||
@click="resetCheckForm"
|
||||
class="bg-gray-400 hover:bg-red-600 text-3xl absolute top-0 right-0 cursor-pointer flex justify-center items-center"
|
||||
>
|
||||
<el-icon>
|
||||
<CloseBold />
|
||||
</el-icon>
|
||||
</div>
|
||||
</template>
|
||||
<FormTools @showTools="showTools" :dialogObj="userMsgActive" />
|
||||
<SingleAdd
|
||||
ref="singleAddRef"
|
||||
v-if="dialogSingleVisible"
|
||||
:addData="addData"
|
||||
@addUser="addUser"
|
||||
/>
|
||||
<MultipleAdd
|
||||
ref="multipleAddRef"
|
||||
v-if="dialogMultipleVisible"
|
||||
:checkNeed="false"
|
||||
:addData="addData"
|
||||
@addUser="addUser"
|
||||
/>
|
||||
<ExcleAdd ref="excleAddRef" v-if="dialogExcleVisible" @addUser="addUser" />
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button style="font-weight: bold" @click="resetCheckForm"> 取消 </el-button>
|
||||
<el-button style="font-weight: bold" type="primary" @click="confirm">
|
||||
确定
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { CloseBold } from "@element-plus/icons-vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import FormTools from "../../operate/formTools.vue";
|
||||
import SingleAdd from "./singleAdd.vue";
|
||||
import MultipleAdd from "./multipleAdd.vue";
|
||||
import ExcleAdd from "./excleAdd.vue";
|
||||
|
||||
import userActiveStore from "../../../stores/userMsg";
|
||||
|
||||
import $http from "../../../api/index";
|
||||
import $url from "../../../api/url";
|
||||
|
||||
import { encrypt } from "../../../utils/aes";
|
||||
|
||||
const userMsgActive = userActiveStore();
|
||||
|
||||
const dialogVisible = ref(false);
|
||||
const singleAddRef = ref(null);
|
||||
const multipleAddRef = ref(null);
|
||||
const excleAddRef = ref(null);
|
||||
const dialogSingleVisible = ref(true);
|
||||
const dialogMultipleVisible = ref(false);
|
||||
const dialogExcleVisible = ref(false);
|
||||
|
||||
const props = defineProps({
|
||||
title: String,
|
||||
addData: Object,
|
||||
});
|
||||
|
||||
const emit = defineEmits(["reloadData"]);
|
||||
|
||||
const showTools = (operateType) => {
|
||||
switch (operateType) {
|
||||
case "single":
|
||||
dialogSingleVisible.value = true;
|
||||
dialogMultipleVisible.value = false;
|
||||
dialogExcleVisible.value = false;
|
||||
userMsgActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
userMsgActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
userMsgActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
case "multiple":
|
||||
dialogSingleVisible.value = false;
|
||||
dialogMultipleVisible.value = true;
|
||||
dialogExcleVisible.value = false;
|
||||
userMsgActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
userMsgActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
userMsgActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
case "excle":
|
||||
dialogSingleVisible.value = false;
|
||||
dialogMultipleVisible.value = false;
|
||||
dialogExcleVisible.value = true;
|
||||
userMsgActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
userMsgActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
userMsgActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (dialogSingleVisible.value) {
|
||||
singleAddRef.value.resetCheckForm();
|
||||
} else if (dialogMultipleVisible.value) {
|
||||
multipleAddRef.value.resetCheckForm();
|
||||
} else if (dialogExcleVisible.value) {
|
||||
excleAddRef.value.resetCheckForm();
|
||||
}
|
||||
dialogVisible.value = false;
|
||||
};
|
||||
|
||||
const confirm = () => {
|
||||
if (dialogSingleVisible.value) {
|
||||
singleAddRef.value.confirm();
|
||||
} else if (dialogMultipleVisible.value) {
|
||||
multipleAddRef.value.confirm();
|
||||
} else if (dialogExcleVisible.value) {
|
||||
excleAddRef.value.confirm();
|
||||
}
|
||||
};
|
||||
|
||||
const addUser = (requestMsg) => {
|
||||
requestMsg.forEach((element) => {
|
||||
element.account_name = encrypt(String(element.account_name));
|
||||
element.identity_card = encrypt(String(element.identity_card));
|
||||
element.user_name = encrypt(String(element.user_name));
|
||||
element.gender = encrypt(String(element.gender));
|
||||
element.age = encrypt(String(element.age));
|
||||
element.email = encrypt(String(element.email));
|
||||
element.phone = encrypt(String(element.phone));
|
||||
element.address = encrypt(String(element.address));
|
||||
element.workplace = encrypt(String(element.workplace));
|
||||
});
|
||||
const data = { requestMsg };
|
||||
$http.post($url.addUser, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
resetCheckForm();
|
||||
ElMessage({
|
||||
message: "新增用户信息成功!",
|
||||
type: "success",
|
||||
});
|
||||
emit("reloadData");
|
||||
} else {
|
||||
ElMessage.error("新增用户信息失败!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ dialogVisible });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
Reference in New Issue
Block a user