staging #23

Merged
hy merged 38 commits from staging into master 2025-10-14 11:13:16 +08:00
7 changed files with 554 additions and 231 deletions
Showing only changes of commit f29c76ba84 - Show all commits

View File

@ -1,6 +1,7 @@
import { ComboModel } from "@/components/hTable/hTable"; import { ComboModel } from "@/components/hTable/hTable";
import { http } from "@/utils/http"; import { http } from "@/utils/http";
import type { Res, ResPage } from "@/utils/http/types"; import type { Res, ResPage } from "@/utils/http/types";
import { Ref } from "vue";
/** /**
* @description * @description
* @param {string} type type=StatusEnum * @param {string} type type=StatusEnum
@ -151,12 +152,14 @@ export interface Position {
graduationYear: number; graduationYear: number;
grade: string; grade: string;
classId: number; classId: number;
gradeLevel: string;
className: string; className: string;
subjectId: number; subjectId: number;
subjectName: string; subjectName: string;
positionType: number; positionType: number;
positionLevel: number; positionLevel: number;
status: boolean; status: boolean;
classList?: ComboModel[];
} }
/** /**

View File

@ -401,3 +401,33 @@ export function intTableData(tValue: TableConfig): TableConfig {
} }
return tValue; return tValue;
} }
/**
*
*/
export function gradeComboModel(): ComboModel[] {
const now = new Date();
const currentYear = now.getFullYear();
const currentMonth = now.getMonth() + 1;
const isAfterAugust = currentMonth >= 9;
const baseYear = isAfterAugust ? currentYear : currentYear - 1;
const gradeOffsets = [
{ baseGradeName: "初", yearOffset: 0, grade: "初一" }, // 初一
{ baseGradeName: "初", yearOffset: 1, grade: "初二" }, // 初二
{ baseGradeName: "初", yearOffset: 2, grade: "初三" }, // 初三
{ baseGradeName: "高", yearOffset: 0, grade: "高一" }, // 高一
{ baseGradeName: "高", yearOffset: 1, grade: "高二" }, // 高二
{ baseGradeName: "高", yearOffset: 2, grade: "高三" }, // 高三
];
return gradeOffsets.map(
(item): ComboModel => {
const entranceYear = baseYear - item.yearOffset;
const graduationYear = entranceYear + 3;
let v = `${item.baseGradeName}${graduationYear}`;
return { text: v + ` [${item.grade}]`, value: v };
}
);
}

View File

@ -1,7 +1,9 @@
<script setup lang="ts"> <script setup lang="ts">
import ahTable from "@/components/hTable/index.vue"; import ahTable from "@/components/hTable/index.vue";
import { import {
ComboModel,
ConditionalType, ConditionalType,
gradeComboModel,
intTableData, intTableData,
TableColumn, TableColumn,
TableColumnEdit, TableColumnEdit,
@ -13,6 +15,7 @@ import { fa } from "element-plus/es/locales.mjs";
import { hTableAPI } from "@/api/hTable"; import { hTableAPI } from "@/api/hTable";
import { getenum } from "@/api/enum"; import { getenum } from "@/api/enum";
import { ruleClassName, ruleRequired } from "@/utils/rules"; import { ruleClassName, ruleRequired } from "@/utils/rules";
import { text } from "node:stream/consumers";
const ControllerName = "classes"; const ControllerName = "classes";
defineOptions({ defineOptions({
@ -88,7 +91,7 @@ const tableData: TableConfig = intTableData({
label: "年级", label: "年级",
width: "220px", width: "220px",
type: "dropdown", type: "dropdown",
custom: (row) => `${row.grade ?? ""} [${row.gradeLevel + row.graduationYear}]`, custom: (row) => `${row.gradeLevel + row.graduationYear}届 [${row.grade ?? ""}]`,
search: new TableColumnSearch(true), search: new TableColumnSearch(true),
edit: { add: true, edit: false, rules: ruleRequired }, edit: { add: true, edit: false, rules: ruleRequired },
}, },
@ -129,20 +132,7 @@ const showTable = ref(false);
onMounted(async () => { onMounted(async () => {
// //
tableData.column.Grade.setting.datasource = [ tableData.column.Grade.setting.datasource = gradeComboModel();
{ text: "初一", value: "初一" },
{ text: "初二", value: "初二" },
{ text: "初三", value: "初三" },
{ text: "高一", value: "高一" },
{ text: "高二", value: "高二" },
{ text: "高三", value: "高三" },
{ text: "一年级", value: "一年级" },
{ text: "二年级", value: "二年级" },
{ text: "三年级", value: "三年级" },
{ text: "四年级", value: "四年级" },
{ text: "五年级", value: "五年级" },
{ text: "六年级", value: "六年级" },
];
tableData.column.type.setting.datasource = (await getenum("ClassTypeEnum")).data; tableData.column.type.setting.datasource = (await getenum("ClassTypeEnum")).data;
tableData.column.schoolId.setting.datasource = ( tableData.column.schoolId.setting.datasource = (
await SchoolApi.querycombo({ TextName: "Name", ValueName: "Id" }) await SchoolApi.querycombo({ TextName: "Name", ValueName: "Id" })

View File

@ -20,6 +20,19 @@
</el-col> </el-col>
</el-row> </el-row>
<el-row>
<el-col :span="12">
<el-form-item label="职务:" prop="studentId">
<el-input
type="text"
v-model="form.studentId"
autocomplete="off"
maxlength="16"
:show-word-limit="true"
/>
</el-form-item>
</el-col>
</el-row>
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="入班时间:" prop="joinTime"> <el-form-item label="入班时间:" prop="joinTime">
@ -186,40 +199,93 @@
<el-row class="pt-4"> <el-row class="pt-4">
<el-col :span="24"> <el-col :span="24">
<el-form-item label="就读班级:" prop="positionIds" :rules="ruleRequired"> <el-form-item label="就读班级:" prop="positionIds" :rules="ruleRequired">
<el-button type="success" @click="CheckPosition()">选择就读班级</el-button> <el-button type="success" @click="AddPosition()">添加就读班级</el-button>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </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 <div
v-for="(position, index) in positionList" v-for="(position, index) in positionList"
:key="index" :key="index"
style="padding-left: 120px; padding-bottom: 20px" class="subjectTagEnableDiv"
style=""
> >
<div class="subjectTagEnableDiv" v-if="position.enable === false"> <el-form-item>
<el-tag type="info">{{ "禁用" }}</el-tag> <el-button
<el-tag type="info">{{ position.schoolName || "-" }}</el-tag> title="删除就读班级"
<el-tag type="info">{{ class="mr-[5px]!"
position.graduationYear ? position.graduationYear + "届" : "-" type="danger"
}}</el-tag> :icon="Delete"
<el-tag type="info">{{ position.grade || "-" }}</el-tag> @click="positionClose(position)"
<el-tag type="info">{{ position.className || "-" }}</el-tag> circle
<el-tag type="info">{{ position.subjectName || "-" }}</el-tag> />
<el-tag type="info">{{ position.name || "-" }}</el-tag> </el-form-item>
<el-tag type="info">{{ position.endTime }}</el-tag>
</div> <el-form-item :prop="`${index}.schoolId`" :rules="ruleRequired">
<div class="subjectTagEnableDiv" v-else> <el-select
<el-tag>{{ position.schoolName || "-" }}</el-tag> :disabled="position.id != undefined"
<el-tag type="warning">{{ class="w-[250px]!"
position.graduationYear ? position.graduationYear + "届" : "-" v-model="position.schoolId"
}}</el-tag> placeholder="学校"
<el-tag type="success">{{ position.grade || "-" }}</el-tag> clearable
<el-tag type="primary" class="classTag">{{ position.className || "-" }}</el-tag> filterable
<el-tag type="info" class="subjectTag">{{ @change="() => schoolChange(position)"
position.subjectName || "-" >
}}</el-tag> <el-option
<el-tag type="danger">{{ position.name || "-" }}</el-tag> 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> </div>
</el-form>
</div> </div>
<el-form-item> <el-form-item>
<el-button type="primary" :loading="loading" @click="handleSubmitForm()" <el-button type="primary" :loading="loading" @click="handleSubmitForm()"
@ -228,35 +294,25 @@
<el-button @click="handleResetForm()">重置</el-button> <el-button @click="handleResetForm()">重置</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
<div class="dialog-container">
<el-dialog
v-if="dialog.visible"
ref="PositionCheckFromDialog"
:title="dialog.title"
v-model="dialog.visible"
:width="dialog.width"
:close-on-click-modal="dialog.close"
:close-on-press-escape="dialog.close"
append-to-body
>
<PositionForm
:userType="form.userType"
:positions="PositionFormIds"
@handleCheckCallback="handleCheckCallback"
/>
</el-dialog>
</div>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, reactive, onMounted } from "vue"; import { ref, reactive, onMounted } from "vue";
import { EditStudent, StudentInfo } from "@/api/student"; import { EditStudent, StudentInfo } from "@/api/student";
import { cloudSchoolCombo, getUserInfo, editUser, Position } from "@/api/userCenter"; import {
cloudSchoolCombo,
getUserInfo,
editUser,
Position,
getClassCombo,
getSchoolData,
} from "@/api/userCenter";
import PositionForm from "../teacher/positionForm.vue"; import PositionForm from "../teacher/positionForm.vue";
import { getenum, getenumDic } from "@/api/enum"; import { getenum, getenumDic } from "@/api/enum";
import { ruleRequired, rulePhone } from "@/utils/rules"; import { ruleRequired, rulePhone } from "@/utils/rules";
import { ElMessage, FormInstance } from "element-plus"; import { ElMessage, FormInstance } from "element-plus";
import { ComboModel } from "@/components/hTable/hTable"; import { ComboModel, gradeComboModel } from "@/components/hTable/hTable";
import { Check, Delete, Edit, Message, Search, Star } from "@element-plus/icons-vue";
interface FormData { interface FormData {
id: number; id: number;
@ -273,6 +329,7 @@ interface FormData {
subjectLevels: any[]; subjectLevels: any[];
subjectLevel: Record<string, any>; subjectLevel: Record<string, any>;
positionIds: number[]; positionIds: number[];
positionList: Position[];
positionFormIds?: number[]; positionFormIds?: number[];
gLSubject?: number; gLSubject?: number;
gSubject1?: number; gSubject1?: number;
@ -330,6 +387,37 @@ const positionList = ref<Position[]>([]);
const CloudSchoolArr = ref<ComboModel[]>([]); const CloudSchoolArr = ref<ComboModel[]>([]);
const Template = ref<any[]>([]); const Template = ref<any[]>([]);
const PositionFormIds = ref<number[]>([]); 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({ const defaultSubjectLevel = reactive({
UserId: 0, UserId: 0,
@ -349,7 +437,7 @@ const defaultSubjectLevel = reactive({
const form = ref<FormData>({ const form = ref<FormData>({
id: props.id, id: props.id,
account: "", account: "",
userType: 1, userType: 2,
level: 0, level: 0,
passWord: "", passWord: "",
realName: "", realName: "",
@ -357,6 +445,7 @@ const form = ref<FormData>({
templateId: 0, templateId: 0,
phone: "", phone: "",
cloudSchoolId: 0, cloudSchoolId: 0,
positionList: [],
subjectLevels: [], subjectLevels: [],
subjectLevel: { ...defaultSubjectLevel }, subjectLevel: { ...defaultSubjectLevel },
positionIds: [], positionIds: [],
@ -381,29 +470,44 @@ const customeRules = reactive({
], ],
}); });
const getUserSubjectLevel = (obj: Record<string, any>) => { function positionClose(p: Position) {
if (!obj.id) { positionList.value = positionList.value.filter((s) => s != p);
form.value.subjectLevel = { ...defaultSubjectLevel }; }
obj = form.value.subjectLevel;
}
return Object.entries(obj).filter((s) => s[0].includes("Subject"));
};
const userLevel2subject = (str: string) => { const AddPositionArr: Position[] = [];
const name = str.match(/[0-9]+/)?.[0] || ""; function AddPosition() {
return subjectLEnum.value[name]; let p = {
}; userId: form.value.id,
schoolId: null,
enable: false,
graduationYear: null,
gradeLevel: "",
classId: null,
subjectId: null,
positionType: 2,
positionLevel: null,
status: true,
};
AddPositionArr.push((p as unknown) as Position);
positionList.value.push((p as unknown) as Position);
}
const emit = defineEmits(["handlePagedCallback"]); const emit = defineEmits(["handlePagedCallback"]);
const handlePagedCallback = () => { const handlePagedCallback = () => {
// Emit event to parent if needed // Emit event to parent if needed
emit("handlePagedCallback"); emit("handlePagedCallback");
}; };
const handleSubmitForm = () => { const handleSubmitForm = async () => {
userEditForm.value.validate(async (valid) => { try {
if (valid) { 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; loading.value = true;
let ac = form.value.account || new Date().getTime() + "";
const formData = { const formData = {
id: form.value.uId || 0, id: form.value.uId || 0,
userType: form.value.userType || 1, userType: form.value.userType || 1,
@ -444,13 +548,13 @@ const handleSubmitForm = () => {
ElMessage.success("操作成功"); ElMessage.success("操作成功");
handlePagedCallback(); handlePagedCallback();
//edit info //edit info
} } catch (error) {}
});
// Form validation and submission logic // Form validation and submission logic
}; };
const handleResetForm = () => { const handleResetForm = () => {
Object.assign(form, { form.value = {
id: props.id, id: props.id,
account: "", account: "",
userType: 1, userType: 1,
@ -458,14 +562,24 @@ const handleResetForm = () => {
passWord: "", passWord: "",
realName: "", realName: "",
studentId: "", studentId: "",
templateId: 0,
phone: "",
cloudSchoolId: 0,
positionList: [],
subjectLevels: [], subjectLevels: [],
subjectLevel: { ...defaultSubjectLevel }, subjectLevel: { ...defaultSubjectLevel },
positionIds: [], positionIds: [],
idCard: "", idCard: "",
phone: "", exitTime: null,
cloudSchoolId: "", joinTime: null,
pointPenSN: "", remark: null,
}); studentType: null,
status: null,
amountRelief: null,
reliefSubTime: null,
reliefType: null,
reliefApplication: null,
};
positionList.value = []; positionList.value = [];
}; };
@ -500,6 +614,12 @@ const fetchInitData = async () => {
const [value, text] = s.trim().split("."); const [value, text] = s.trim().split(".");
return { value: parseInt(value.trim()), text: text.trim() }; 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 () => { const fetchFormData = async () => {
@ -510,6 +630,13 @@ const fetchFormData = async () => {
delete res.data.SubjectLevel.CreatePositionId; delete res.data.SubjectLevel.CreatePositionId;
} }
let sInfo = await StudentInfo(props.id); 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, { Object.assign(form.value, {
id: res.data.id, id: res.data.id,
uId: res.data.id, uId: res.data.id,
@ -532,13 +659,21 @@ const fetchFormData = async () => {
phone: res.data.phone, phone: res.data.phone,
cloudSchoolId: res.data.cloudSchoolId, cloudSchoolId: res.data.cloudSchoolId,
pointPenSN: res.data.pointPenSN, pointPenSN: res.data.pointPenSN,
positionList: positionList.value,
...sInfo.data, ...sInfo.data,
}); });
positionList.value = res.data.positions
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 PositionFormIds.value = res.data.positions
.filter((s: any) => s.Enable !== false) .filter((s: Position) => s.enable)
.map((s: any) => s.id); .map((s: any) => s.id);
for (const element of positionList.value) {
getClass(element);
}
} }
}; };
@ -582,9 +717,14 @@ onMounted(async () => {
.subjectTagEnableDiv { .subjectTagEnableDiv {
margin-top: 5px; margin-top: 5px;
padding-left: 120px !important;
} }
.subjectTagEnableDiv .el-tag { .subjectTagEnableDiv .el-form-item {
margin-right: 0px !important;
margin-bottom: 10px !important;
}
.subjectTagEnableDiv .el-select {
margin-right: 5px; margin-right: 5px;
} }

View File

@ -25,7 +25,7 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item v-show="search.schoolId != 0" style="width: 100px"> <el-form-item v-show="search.schoolId != 0" style="width: 145px">
<el-select <el-select
v-model="search.grade" v-model="search.grade"
placeholder="年级" placeholder="年级"
@ -110,7 +110,9 @@
<el-tag v-if="position.enable === false" type="info">已禁用</el-tag> <el-tag v-if="position.enable === false" type="info">已禁用</el-tag>
<el-tag>{{ position.schoolName || "-" }}</el-tag> <el-tag>{{ position.schoolName || "-" }}</el-tag>
<el-tag type="success">{{ <el-tag type="success">{{
position.graduationYear ? position.graduationYear + "届" : "-" position.graduationYear
? position.gradeLevel + position.graduationYear + "届"
: "-"
}}</el-tag> }}</el-tag>
<el-tag type="primary" class="classTag">{{ <el-tag type="primary" class="classTag">{{
position.className || "-" position.className || "-"
@ -201,7 +203,7 @@ import {
Search, Search,
Star, Star,
} from "@element-plus/icons-vue"; } from "@element-plus/icons-vue";
import { ComboModel } from "@/components/hTable/hTable"; import { ComboModel, gradeComboModel } from "@/components/hTable/hTable";
import { ImportStudent, PageList } from "@/api/student"; import { ImportStudent, PageList } from "@/api/student";
const classAPI = new hTableAPI("usercenter/back/classes"); const classAPI = new hTableAPI("usercenter/back/classes");
@ -314,14 +316,7 @@ const userTypeList = ref<ComboModel[]>([
const userLevelList = ref<ComboModel[]>([]); const userLevelList = ref<ComboModel[]>([]);
const schoolList = ref<ComboModel[]>([]); const schoolList = ref<ComboModel[]>([]);
const gradeList = ref<ComboModel[]>([ const gradeList = ref<ComboModel[]>(gradeComboModel());
{ value: "初一", text: "初一" },
{ value: "初二", text: "初二" },
{ value: "初三", text: "初三" },
{ value: "高一", text: "高一" },
{ value: "高二", text: "高二" },
{ value: "高三", text: "高三" },
]);
const classList = ref<ComboModel[]>([]); const classList = ref<ComboModel[]>([]);
const subjectList = ref<ComboModel[]>([]); const subjectList = ref<ComboModel[]>([]);
const positionList = ref<any[]>([]); const positionList = ref<any[]>([]);
@ -344,7 +339,7 @@ const dialog = reactive<DialogData>({
update: { update: {
title: "", title: "",
visible: false, visible: false,
width: "800px", width: "1000px",
}, },
editLevel: { editLevel: {
userIds: [], userIds: [],

View File

@ -35,33 +35,139 @@
</el-row> </el-row>
<el-row> <el-row>
<el-col :span="24"> <el-col :span="24">
<el-form-item label="任教信息:" prop="positionIds" :rules="ruleRequired"> <el-form-item label="任教信息:" prop="positionList" :rules="ruleRequired">
<el-button type="success" @click="CheckPosition()">分配职位</el-button> <el-button type="success" @click="AddPosition()">添加职位</el-button>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<div class="max-h-[400px] overflow-auto pb-1"> <div class="max-h-[400px] overflow-auto pb-1">
<span class="pl-[120px]"
>提示:任职信息所有项值<span class="text-red-500">必填</span>,
非常规任教信息录入到职位里即可.
</span>
<el-form :model="positionList" inline ref="positionEditForm">
<div <div
v-for="(position, index) in positionList" v-for="(position, index) in positionList"
:key="index" :key="index"
style="padding-left: 120px; padding-bottom: 20px" class="subjectTagEnableDiv"
style=""
> >
<div class="subjectTagEnableDiv"> <el-form-item>
<el-tag v-if="!position.enable" type="info">已禁用</el-tag> <el-button
<el-tag>{{ position.schoolName || "-" }}</el-tag> title="删除职位"
<el-tag type="warning">{{ class="mr-[5px]!"
position.graduationYear ? position.graduationYear + "届" : "-" type="danger"
}}</el-tag> :icon="Delete"
<el-tag type="success" v-show="position.grade">{{ position.grade }}</el-tag> @click="positionClose(position)"
<el-tag type="primary" v-show="position.className" class="classTag">{{ circle
position.className />
}}</el-tag> </el-form-item>
<el-tag type="info" v-show="position.subjectName" class="subjectTag">{{ <el-form-item :prop="`${index}.positionLevel`" :rules="ruleRequired">
position.subjectName <el-select
}}</el-tag> :disabled="position.id != undefined"
<el-tag type="danger">{{ position.name || "-" }}</el-tag> class="w-[100px]!"
</div> v-model="position.positionLevel"
placeholder="类型"
clearable
filterable
>
<el-option
v-for="item in positionEnumList"
:key="item.value"
:label="item.text"
:value="item.value"
>
</el-option>
</el-select>
</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="position.positionLevel > 3 ? ruleRequired : []"
>
<el-select
:disabled="position.id != undefined"
v-show="position.positionLevel > 3"
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>
<el-form-item
:prop="`${index}.subjectId`"
:rules="position.positionLevel == 5 ? ruleRequired : []"
>
<el-select
:disabled="position.id != undefined"
v-show="position.positionLevel == 5"
class="w-[100px]!"
v-model="position.subjectId"
placeholder="学科"
clearable
filterable
>
<el-option
v-for="item in subjectList"
:key="item.value"
:label="item.text"
:value="item.value"
>
</el-option>
</el-select>
</el-form-item>
</div> </div>
</el-form>
</div> </div>
<el-form-item> <el-form-item>
<el-button type="primary" :loading="loading" @click="handleSubmitForm()" <el-button type="primary" :loading="loading" @click="handleSubmitForm()"
@ -70,36 +176,25 @@
<el-button @click="handleResetForm()">重置</el-button> <el-button @click="handleResetForm()">重置</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
<div class="dialog-container">
<el-dialog
v-if="dialog.visible"
ref="PositionCheckFromDialog"
:title="dialog.title"
v-model="dialog.visible"
:width="dialog.width"
:close-on-click-modal="dialog.close"
:close-on-press-escape="dialog.close"
append-to-body
>
<PositionForm
:userType="form.userType"
:positions="PositionFormIds"
@handleCheckCallback="handleCheckCallback"
/>
</el-dialog>
</div>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, reactive, onMounted } from "vue"; import { ref, reactive, onMounted } from "vue";
import {} from "@/api/user"; import {} from "@/api/user";
import { cloudSchoolCombo, getUserInfo, editUser, Position } from "@/api/userCenter"; import {
cloudSchoolCombo,
getUserInfo,
editUser,
Position,
getSchoolData,
getClassCombo,
} from "@/api/userCenter";
import PositionForm from "./positionForm.vue"; import PositionForm from "./positionForm.vue";
import { getenum, getenumDic } from "@/api/enum"; import { getenum, getenumDic } from "@/api/enum";
import { ruleRequired, rulePhone } from "@/utils/rules"; import { ruleRequired, rulePhone } from "@/utils/rules";
import { ElMessage, FormInstance } from "element-plus"; import { ElMessage, FormInstance } from "element-plus";
import { ComboModel } from "@/components/hTable/hTable"; import { ComboModel, gradeComboModel } from "@/components/hTable/hTable";
import { InformationEvent } from "http"; import { Check, Delete, Edit, Message, Search, Star } from "@element-plus/icons-vue";
interface FormData { interface FormData {
id: number; id: number;
@ -115,6 +210,7 @@ interface FormData {
subjectLevels: any[]; subjectLevels: any[];
subjectLevel: Record<string, any>; subjectLevel: Record<string, any>;
positionIds: number[]; positionIds: number[];
positionList: Position[];
positionFormIds?: number[]; positionFormIds?: number[];
gLSubject?: number; gLSubject?: number;
gSubject1?: number; gSubject1?: number;
@ -161,6 +257,42 @@ const positionList = ref<Position[]>([]);
const CloudSchoolArr = ref<ComboModel[]>([]); const CloudSchoolArr = ref<ComboModel[]>([]);
const Template = ref<any[]>([]); const Template = ref<any[]>([]);
const PositionFormIds = ref<number[]>([]); 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[]>([]);
const positionEnumList = ref<ComboModel[]>([
{ text: "年级主任", value: 3 },
{ text: "班主任", value: 4 },
{ text: "科任老师", value: 5 },
]);
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({ const defaultSubjectLevel = reactive({
UserId: 0, UserId: 0,
@ -188,6 +320,7 @@ const form = ref<FormData>({
templateId: 0, templateId: 0,
phone: "", phone: "",
cloudSchoolId: 0, cloudSchoolId: 0,
positionList: [],
subjectLevels: [], subjectLevels: [],
subjectLevel: { ...defaultSubjectLevel }, subjectLevel: { ...defaultSubjectLevel },
positionIds: [], positionIds: [],
@ -212,34 +345,50 @@ const customeRules = reactive({
], ],
}); });
const getUserSubjectLevel = (obj: Record<string, any>) => { function positionClose(p: Position) {
if (!obj.id) { positionList.value = positionList.value.filter((s) => s != p);
form.value.subjectLevel = { ...defaultSubjectLevel }; }
obj = form.value.subjectLevel;
}
return Object.entries(obj).filter((s) => s[0].includes("Subject"));
};
const userLevel2subject = (str: string) => { const AddPositionArr: Position[] = [];
const name = str.match(/[0-9]+/)?.[0] || ""; function AddPosition() {
return subjectLEnum.value[name]; let p = {
}; userId: form.value.id,
schoolId: null,
enable: false,
graduationYear: null,
gradeLevel: "",
classId: null,
subjectId: null,
positionType: 2,
positionLevel: null,
status: true,
};
AddPositionArr.push((p as unknown) as Position);
positionList.value.push((p as unknown) as Position);
}
const handlePagedCallback = () => { const handlePagedCallback = () => {
emit("handlePagedCallback"); emit("handlePagedCallback");
}; };
const userEditForm = ref<FormInstance>(); const userEditForm = ref<FormInstance>();
const handleSubmitForm = () => { const handleSubmitForm = async () => {
userEditForm.value.validate((valid) => { try {
if (valid) { 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; loading.value = true;
const formData = { const formData = {
...form.value, ...form.value,
account: form.value.phone || "", account: form.value.phone || "",
positionIds: form.value.positionIds || [], positionIds: positionList.value.map((s) => s.id),
}; };
editUser(formData).then((res) => { const res = await editUser(formData);
loading.value = false; loading.value = false;
if (res.code === 200) { if (res.code === 200) {
ElMessage.success("操作成功"); ElMessage.success("操作成功");
@ -247,11 +396,10 @@ const handleSubmitForm = () => {
} else { } else {
ElMessage.error(res.message); ElMessage.error(res.message);
} }
}); } catch (error) {
ElMessage.error("请求失败!" + JSON.stringify(error));
loading.value = false;
} }
});
// Form validation and submission logic
}; };
const handleResetForm = () => { const handleResetForm = () => {
@ -273,7 +421,6 @@ const handleResetForm = () => {
}); });
positionList.value = []; positionList.value = [];
}; };
const fetchInitData = async () => { const fetchInitData = async () => {
// //
const levelRes = await getenum("StudentLevelEnum"); const levelRes = await getenum("StudentLevelEnum");
@ -282,6 +429,9 @@ const fetchInitData = async () => {
const typeRes = await getenum("UserTypeEnum"); const typeRes = await getenum("UserTypeEnum");
userTypeList.value = typeRes.data; userTypeList.value = typeRes.data;
schoolList.value = (await getSchoolData()).data;
subjectList.value = (await getenum("SubjectEnum")).data;
// // // //
// const schoolRes = await cloudSchoolCombo(); // const schoolRes = await cloudSchoolCombo();
// if (schoolRes.code === 200) { // if (schoolRes.code === 200) {
@ -301,6 +451,13 @@ const fetchFormData = () => {
delete res.data.SubjectLevel.CreatePositionId; delete res.data.SubjectLevel.CreatePositionId;
} }
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, { Object.assign(form.value, {
id: res.data.id, id: res.data.id,
userType: res.data.userType, userType: res.data.userType,
@ -322,12 +479,21 @@ const fetchFormData = () => {
phone: res.data.phone, phone: res.data.phone,
cloudSchoolId: res.data.cloudSchoolId, cloudSchoolId: res.data.cloudSchoolId,
pointPenSN: res.data.pointPenSN, pointPenSN: res.data.pointPenSN,
positionList: positionList.value,
});
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;
}); });
positionList.value = res.data.positions;
PositionFormIds.value = res.data.positions PositionFormIds.value = res.data.positions
.filter((s: any) => s.Enable !== false) .filter((s: Position) => s.enable)
.map((s: any) => s.id); .map((s: any) => s.id);
for (const element of positionList.value) {
if (element.positionLevel > 3) getClass(element);
}
} }
}); });
} }
@ -376,9 +542,14 @@ onMounted(async () => {
.subjectTagEnableDiv { .subjectTagEnableDiv {
margin-top: 5px; margin-top: 5px;
padding-left: 120px !important;
} }
.subjectTagEnableDiv .el-tag { .subjectTagEnableDiv .el-form-item {
margin-right: 0px !important;
margin-bottom: 10px !important;
}
.subjectTagEnableDiv .el-select {
margin-right: 5px; margin-right: 5px;
} }

View File

@ -54,7 +54,7 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item v-show="search.schoolId != 0" style="width: 100px"> <el-form-item v-show="search.schoolId != 0" style="width: 145px">
<el-select <el-select
v-model="search.grade" v-model="search.grade"
placeholder="年级" placeholder="年级"
@ -259,7 +259,7 @@ import {
Search, Search,
Star, Star,
} from "@element-plus/icons-vue"; } from "@element-plus/icons-vue";
import { ComboModel } from "@/components/hTable/hTable"; import { ComboModel, gradeComboModel } from "@/components/hTable/hTable";
import { ImportTeacher } from "@/api/student"; import { ImportTeacher } from "@/api/student";
const classAPI = new hTableAPI("usercenter/back/classes"); const classAPI = new hTableAPI("usercenter/back/classes");
@ -373,14 +373,8 @@ const userTypeList = ref<ComboModel[]>([
const userLevelList = ref<ComboModel[]>([]); const userLevelList = ref<ComboModel[]>([]);
const schoolList = ref<ComboModel[]>([]); const schoolList = ref<ComboModel[]>([]);
const gradeList = ref<ComboModel[]>([
{ value: "初一", text: "初一" }, const gradeList = ref<ComboModel[]>(gradeComboModel());
{ value: "初二", text: "初二" },
{ value: "初三", text: "初三" },
{ value: "高一", text: "高一" },
{ value: "高二", text: "高二" },
{ value: "高三", text: "高三" },
]);
const classList = ref<ComboModel[]>([]); const classList = ref<ComboModel[]>([]);
const subjectList = ref<ComboModel[]>([]); const subjectList = ref<ComboModel[]>([]);
const positionList = ref<any[]>([]); const positionList = ref<any[]>([]);