Learn.Archives.Web/src/views/student/edit.vue

776 lines
21 KiB
Vue

<template>
<div>
<el-form ref="userEditForm" :model="form" :label-width="formLabelWidth" clearable>
<el-row>
<el-col :span="12">
<el-form-item label="姓名:" prop="realName" :rules="ruleRequired">
<el-input
type="text"
v-model="form.realName"
autocomplete="off"
maxlength="20"
:show-word-limit="true"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="家长电话" prop="phone">
<el-input type="text" v-model="form.phone" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="入班时间:" prop="joinTime">
<el-date-picker v-model="form.joinTime" type="date" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="退出时间:" prop="exitTime">
<el-date-picker v-model="form.exitTime" type="date" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="当前状态:" prop="status">
<el-select
v-model="form.status"
filterable
placeholder="就读/退出"
style="width: 180px"
>
<el-option key="1" label="未录入" :value="0" />
<el-option key="2" label="就读" :value="1" />
<el-option key="3" label="退出" :value="10" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="学生类型" prop="studentType">
<el-select
v-model="form.studentType"
filterable
placeholder="学生类型"
style="width: 180px"
>
<el-option
v-for="(item, i) in studentTypeEnum"
:key="i"
autocomplete="off"
:label="item.text"
:value="item.value"
>
</el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="申请减免" prop="amountRelief">
<el-switch v-model="form.reliefApplication" />
</el-form-item>
</el-col>
</el-row>
<el-row v-show="form.reliefApplication" class="pb-4.5">
<el-col :span="24">
<div style="display: flex; gap: 10px">
<label for="Level" class="el-form-item__label" style="width: 120px"
>减免详情:
</label>
<el-input-number
v-model="form.amountRelief"
:precision="2"
:step="0.1"
style="width: 180px"
placeholder="减免金额(元)"
:max="99999999"
/>
<el-select
v-model="form.reliefType"
filterable
placeholder="减免类型"
style="width: 180px"
>
<el-option
v-for="(item, i) in reliefTypeEnum"
:key="i"
autocomplete="off"
:label="item.text"
:value="item.value"
>
</el-option>
</el-select>
<el-date-picker
placeholder="减免时间"
style="width: 180px"
v-model="form.reliefSubTime"
type="date"
/>
</div>
</el-col>
</el-row>
<!-- 选修方向 -->
<el-row class="pb-4.5">
<el-col :span="24">
<div style="display: flex; gap: 10px">
<label for="Level" class="el-form-item__label" style="width: 120px"
>选修方向:</label
>
<el-select
v-model="form.gLSubject"
filterable
clearable
placeholder="历史/地理"
style="width: 180px"
>
<el-option
v-for="(item, i) in subject1"
:key="i"
clearable
autocomplete="off"
:label="item.text"
:value="item.value"
>
</el-option>
</el-select>
<el-select
v-model="form.gSubject1"
filterable
clearable
placeholder="小学科"
style="width: 180px"
>
<el-option
v-for="(item, i) in subject2"
:key="i"
autocomplete="off"
:label="item.text"
:value="item.value"
>
</el-option>
</el-select>
<el-select
v-model="form.gSubject2"
filterable
placeholder="小学科"
style="width: 180px"
>
<el-option
v-for="(item, i) in subject2"
:key="i"
autocomplete="off"
:label="item.text"
:value="item.value"
>
</el-option>
</el-select>
</div>
</el-col>
</el-row>
<el-form-item label="备注:" prop="remark">
<el-input v-model="form.remark" maxlength="500" type="textarea" />
</el-form-item>
<el-row>
<el-col :span="12"> </el-col>
</el-row>
<el-row class="pt-4">
<el-col :span="24">
<el-form-item label="就读班级:" prop="positionList" :rules="ruleRequired">
<el-button type="success" @click="AddPosition()">添加就读班级</el-button>
</el-form-item>
</el-col>
</el-row>
<div class="max-h-[300px] overflow-auto pb-1">
<span class="pl-[120px]"
>提示:就读信息所有项值<span class="text-red-500">必填</span>,
如若查询不到对应班级,请先添加
</span>
<el-form :model="positionList" inline ref="positionEditForm">
<div
v-for="(position, index) in positionList"
:key="index"
class="subjectTagEnableDiv"
style=""
>
<el-form-item>
<el-button
title="删除就读班级"
class="mr-[5px]!"
type="danger"
:icon="Delete"
@click="positionClose(position)"
circle
/>
</el-form-item>
<el-form-item :prop="`${index}.schoolId`" :rules="ruleRequired">
<el-select
:disabled="position.id != undefined"
class="w-[250px]!"
v-model="position.schoolId"
placeholder="学校"
clearable
filterable
@change="() => schoolChange(position)"
>
<el-option
v-for="item in schoolList"
:key="item.value"
:label="item.text"
:value="item.value"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item :prop="`${index}.grade`" :rules="ruleRequired">
<el-select
:disabled="position.id != undefined"
class="w-[150px]!"
v-model="position.grade"
placeholder="年级"
clearable
filterable
@change="() => gradeChange(position)"
>
<el-option
v-for="item in gradeList"
:key="item.value"
:label="item.text"
:value="item.value"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item :prop="`${index}.classId`" :rules="ruleRequired">
<el-select
:disabled="position.id != undefined"
class="w-[120px]!"
v-model="position.classId"
placeholder="班级"
clearable
filterable
>
<el-option
v-for="item in position.classList"
:key="item.value"
:label="item.text"
:value="item.value"
>
</el-option>
</el-select>
</el-form-item>
</div>
</el-form>
</div>
<el-form-item>
<el-button type="primary" :loading="loading" @click="handleSubmitForm()"
>立即提交</el-button
>
<el-button @click="handleResetForm()">重置</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script setup lang="ts">
import { ref, reactive, onMounted } from "vue";
import { EditStudent, StudentInfo } from "@/api/student";
import {
cloudSchoolCombo,
getUserInfo,
editUser,
Position,
getClassCombo,
getSchoolData,
} from "@/api/userCenter";
import PositionForm from "../teacher/positionForm.vue";
import { getenum, getenumDic } from "@/api/enum";
import { ruleRequired, rulePhone } from "@/utils/rules";
import { ElMessage, FormInstance } from "element-plus";
import { ComboModel, gradeComboModel } from "@/components/hTable/hTable";
import { Check, Delete, Edit, Message, Search, Star } from "@element-plus/icons-vue";
import { PosititonIds } from "@/api/student";
interface FormData {
id: number;
uId?: number;
account: string;
userType: number;
level: number;
passWord: string;
realName: string;
studentId: string;
templateId: number;
phone: string | number;
cloudSchoolId: number;
subjectLevels: any[];
subjectLevel: Record<string, any>;
positionIds: number[];
positionList: Position[];
positionFormIds?: number[];
gLSubject?: number;
gSubject1?: number;
gSubject2?: number;
idCard?: string;
exitTime?: string;
joinTime?: string;
remark?: string;
studentType?: number;
status?: string;
amountRelief?: number;
reliefSubTime?: number;
reliefType?: number;
reliefApplication?: boolean;
}
interface DialogConfig {
close: boolean;
title: string;
visible: boolean;
width: string;
}
defineOptions({
name: "UserEditForm",
});
const userEditForm = ref<FormInstance>();
const props = defineProps<{
id: number;
}>();
const formLabelWidth = "120px";
const size = "small";
const loading = ref(false);
const reliefTypeEnum = ref<ComboModel[]>();
const studentTypeEnum = ref<ComboModel[]>();
const subject1 = ref<ComboModel[]>([
{ value: 4, text: "物理" },
{ value: 8, text: "历史" },
]);
const subject2 = ref<ComboModel[]>([
{ value: 5, text: "化学" },
{ value: 6, text: "生物" },
{ value: 9, text: "地理" },
{ value: 7, text: "政治" },
]);
const userTypeList = ref<ComboModel[]>([]);
const userLevelList = ref<ComboModel[]>([]);
const subjectLEnum = ref<Record<string, string>>({});
const positionList = ref<Position[]>([]);
const CloudSchoolArr = ref<ComboModel[]>([]);
const Template = ref<any[]>([]);
const PositionFormIds = ref<number[]>([]);
const positionEditForm = ref<FormInstance>();
const schoolList = ref<ComboModel[]>([]);
const classList = ref<ComboModel[]>([]);
const gradeList = ref<ComboModel[]>(gradeComboModel());
const subjectList = ref<ComboModel[]>([]);
function schoolChange(p: Position) {
p.graduationYear = null;
p.grade = "";
p.classId = null;
p.subjectId = null;
getClass(p);
}
function gradeChange(p: Position) {
p.classId = null;
p.subjectId = null;
getClass(p);
}
function getClass(p: Position) {
const data = {
schoolId: p.schoolId || 0,
graduationYear: p.graduationYear || 0,
grade: p.grade,
};
getClassCombo(data).then((res) => {
if (res.code === 200) {
p.classList = res.data;
}
});
}
const defaultSubjectLevel = reactive({
UserId: 0,
Level: 0,
Subject1: 0,
Subject2: 0,
Subject3: 0,
Subject4: 0,
Subject5: 0,
Subject6: 0,
Subject7: 0,
Subject8: 0,
Subject9: 0,
CreatePositionId: 1,
});
const form = ref<FormData>({
id: props.id,
account: "",
userType: 2,
level: 0,
passWord: "",
realName: "",
studentId: "",
templateId: 0,
phone: "",
cloudSchoolId: 0,
positionList: [],
subjectLevels: [],
subjectLevel: { ...defaultSubjectLevel },
positionIds: [],
positionFormIds: [],
});
const dialog = reactive<DialogConfig>({
close: false,
title: "",
visible: false,
width: "1200px",
});
const customeRules = reactive({
mobile: [
{ required: false, message: "手机号必填", trigger: "blur" },
{
pattern: /^1[3456789]\d{9}$/,
message: "手机号码格式不正确",
trigger: "blur",
},
],
});
function positionClose(p: Position) {
positionList.value = positionList.value.filter((s) => s != p);
}
const AddPositionArr: Position[] = [];
function AddPosition() {
let p = {
userId: form.value.id,
schoolId: null,
enable: false,
graduationYear: null,
gradeLevel: "",
classId: null,
subjectId: null,
positionType: 1,
positionLevel: 4,
status: true,
};
let p1 = (p as unknown) as Position;
form.value.positionList.push(p1);
AddPositionArr.push(p1);
positionList.value.push(p1);
}
const emit = defineEmits(["handlePagedCallback"]);
const handlePagedCallback = () => {
// Emit event to parent if needed
emit("handlePagedCallback");
};
const handleSubmitForm = async () => {
try {
const valid1 = await userEditForm.value.validate();
const valid = await positionEditForm.value.validate();
if (!valid || !valid1) return;
} catch (error) {
ElMessage.warning("表单验证未通过,请检查!");
return;
}
try {
loading.value = true;
const postIdArr = positionList.value.map((s) => s.id).filter((s) => s != null);
const addPArr = positionList.value
.filter((s) => s.id == null)
.map((s) => {
return {
positionType: 1,
positionLevel: 4,
subjectId: s.subjectId,
schoolId: s.schoolId,
classId: s.classId,
gradeLevel: s.grade[0],
graduationYear: parseInt(s.grade.slice(1, 5)),
};
});
if (addPArr.length > 0) {
const resPId = await PosititonIds(addPArr);
if (
resPId.code != 200 ||
resPId.data.length == 0 ||
resPId.data.length != addPArr.length
) {
ElMessage.warning("校验添加的职位数据异常,请删除后重新选择!");
return;
}
postIdArr.push(...resPId.data);
}
const formData = {
id: form.value.uId || 0,
userType: form.value.userType || 1,
level: form.value.level || 0,
account: form.value.account || new Date().getTime() + "",
PassWord: form.value.id === 0 ? "无效密码" : "",
realName: form.value.realName || "",
studentId: form.value.studentId || "",
templateId: form.value.templateId || 0,
subjectLevels: form.value.subjectLevels || [],
subjectLevel: form.value.subjectLevel || { ...defaultSubjectLevel },
gLSubject: form.value.gLSubject,
gSubject1: form.value.gSubject1,
gSubject2: form.value.gSubject2,
idCard: form.value.idCard,
cloudSchoolId: form.value.cloudSchoolId,
phone: form.value.phone,
positionIds: postIdArr,
};
let res = await editUser(formData);
if (res.code !== 200) {
loading.value = false;
ElMessage.error(res.message);
return;
}
res = await EditStudent({
...form.value,
userCenterId: res.data,
});
if (res.code !== 200) {
loading.value = false;
ElMessage.error(res.message);
return;
}
loading.value = false;
ElMessage.success("操作成功");
handlePagedCallback();
//edit info
} catch (error) {}
// Form validation and submission logic
};
const handleResetForm = () => {
form.value = {
id: props.id,
account: "",
userType: 1,
level: 0,
passWord: "",
realName: "",
studentId: "",
templateId: 0,
phone: "",
cloudSchoolId: 0,
positionList: [],
subjectLevels: [],
subjectLevel: { ...defaultSubjectLevel },
positionIds: [],
idCard: "",
exitTime: null,
joinTime: null,
remark: null,
studentType: null,
status: null,
amountRelief: null,
reliefSubTime: null,
reliefType: null,
reliefApplication: false,
};
positionList.value = [];
};
const fetchInitData = async () => {
reliefTypeEnum.value = `
1.建卡贫困户
2.低保户
3.教师子女
4.孤儿
5.艺体生
6.残疾学生
7.领导特殊承诺减免`
.split("\n")
.filter((s) => s.trim())
.map((s) => {
const [value, text] = s.trim().split(".");
return { value: text.trim(), text: text.trim() };
});
studentTypeEnum.value = `
1.复读生
10.艺术生
20.春招生
30.领导承诺批准全免
40.资源班
50.国际班
60.合同制收费学校
70.渠道商家属
80.新开班但领导承诺第一学期不收费`
.split("\n")
.filter((s) => s.trim())
.map((s) => {
const [value, text] = s.trim().split(".");
return { value: parseInt(value.trim()), text: text.trim() };
});
const typeRes = await getenum("UserTypeEnum");
userTypeList.value = typeRes.data;
schoolList.value = (await getSchoolData()).data;
subjectList.value = (await getenum("SubjectEnum")).data;
};
const fetchFormData = async () => {
handleResetForm();
if (props.id !== 0) {
let res = await getUserInfo(props.id);
if (res.data.SubjectLevel && res.data.SubjectLevel.CreatePositionId) {
delete res.data.SubjectLevel.CreatePositionId;
}
let sInfo = await StudentInfo(props.id);
positionList.value = res.data.positions
.filter((s: Position) => s.enable)
.map((s: Position) => {
if (s.positionLevel > 2)
s.grade = (s.gradeLevel ?? s.grade[0]) + s.graduationYear + "届";
return s;
});
Object.assign(form.value, {
id: res.data.id,
uId: res.data.id,
userType: res.data.userType,
level: res.data.level,
account: res.data.account,
passWord: res.data.passWord,
realName: res.data.realName,
studentId: res.data.studentId,
templateId: res.data.templateId,
subjectLevels: res.data.subjectLevels,
subjectLevel: res.data.subjectLevel,
positionIds: res.data.positions
.filter((s: any) => s.enable !== false)
.map((w: any) => w.id),
gLSubject: res.data.gLSubject,
gSubject1: res.data.gSubject1,
gSubject2: res.data.gSubject2,
idCard: res.data.idCard,
phone: res.data.phone,
cloudSchoolId: res.data.cloudSchoolId,
pointPenSN: res.data.pointPenSN,
positionList: positionList.value,
...sInfo.data,
});
positionList.value = res.data.positions
.filter((s: Position) => s.enable)
.map((s: Position) => {
s.grade = (s.gradeLevel ?? s.grade[0]) + s.graduationYear + "届";
return s;
});
PositionFormIds.value = res.data.positions
.filter((s: Position) => s.enable)
.map((s: any) => s.id);
for (const element of positionList.value) {
getClass(element);
}
}
};
const userTypeChange = () => {
if (form.value.userType === 2) {
form.value.studentId = "";
}
customeRules.mobile[0].required = form.value.userType !== 1;
};
const CheckPosition = () => {
dialog.title = "选择就读班级";
dialog.visible = true;
PositionFormIds.value = positionList.value
.filter((s) => s.enable !== false)
.map((s) => s.id);
};
const handleCheckCallback = (checkPosition: Position[]) => {
dialog.visible = false;
positionList.value = checkPosition;
form.value.positionIds = positionList.value.map((w) => w.id);
};
onMounted(async () => {
await fetchInitData();
fetchFormData();
});
</script>
<style scoped>
.userform_ul {
list-style: none;
padding: 0;
margin: 0;
}
.userform_ul li {
margin-bottom: 10px;
}
.subjectTagEnableDiv {
margin-top: 5px;
padding-left: 120px !important;
}
.subjectTagEnableDiv .el-form-item {
margin-right: 0px !important;
margin-bottom: 10px !important;
}
.subjectTagEnableDiv .el-select {
margin-right: 5px;
}
.classTag {
background-color: #409eff;
color: white;
}
.subjectTag {
background-color: #909399;
color: white;
}
.classTag {
color: #a3bf08 !important;
background-color: #f4fbd1 !important;
border-color: #f4fbd1 !important;
}
.subjectTagEnableDiv {
padding: 1px;
}
.subjectTag {
color: #eb0de4 !important;
background-color: #fbd9ff !important;
border-color: #fbd9ff !important;
}
.userform_ul {
list-style: none;
}
</style>