yangg 1 viikko sitten
vanhempi
sitoutus
93f81c8176

+ 8 - 0
src/views/system/allusers/api.ts

@@ -63,4 +63,12 @@ export function BatchExportUsers(userIds: number[], userType?: number) {
         data: params,
         responseType: 'blob', // 重要:设置响应类型为blob以处理文件下载
     });
+}
+
+
+export function GetTree() {
+	return request({
+		url: `/api/system/organization/tree/`,
+		method: 'get',
+	});
 }

+ 91 - 0
src/views/system/allusers/crud.tsx

@@ -3,8 +3,63 @@ import * as api from './api';
 import { auth } from '/@/utils/authFunction';
 import { ElMessage } from 'element-plus';
 import { ref } from 'vue';
+// 全局变量存储组织树数据,供 valueBuilder 使用
+let organizationTreeData: any[] = [];
+
+// 初始化时获取组织树数据
+const initOrganizationTree = async () => {
+	try {
+		const res = await api.GetTree();
+		if (res && (res.code === 200 || res.code === 2000 || !res.code)) {
+			const data = res.data || res.results || res;
+			if (Array.isArray(data)) {
+				organizationTreeData = data;
+			}
+		}
+	} catch (error) {
+		console.error('获取组织架构数据失败:', error);
+		organizationTreeData = [];
+	}
+};
+
+// 通过名称在组织树中查找节点的辅助函数(在整个树中递归搜索)
+function findNodeByName(name: string, tree: any[], depth: number = 0, maxDepth: number = 10): any {
+	if (!name || !tree || depth > maxDepth) return undefined;
+	
+	for (const node of tree) {
+		if (node.name === name) {
+			return node;
+		}
+		if (Array.isArray(node.children)) {
+			const found = findNodeByName(name, node.children, depth + 1, maxDepth);
+			if (found) return found;
+		}
+	}
+	return undefined;
+}
+
+// 在学院层级中查找节点(跳过学校层)
+function findNodeInColleges(name: string, tree: any[]): any {
+	if (!name || !tree) return undefined;
+	
+	// 遍历所有学校
+	for (const school of tree) {
+		if (Array.isArray(school.children)) {
+			// 在每个学校的子节点(学院)中查找
+			for (const college of school.children) {
+				if (college.name === name) {
+					return college;
+				}
+			}
+		}
+	}
+	return undefined;
+}
 
 export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet {
+	// 初始化组织树数据(异步执行,不阻塞返回)
+	initOrganizationTree();
+
 	const pageRequest = async (query: UserPageQuery) => {
 		return await api.GetList(query);
 	};
@@ -383,6 +438,12 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 						form.organization_ref = value;
 						// 仅学生类型需要拆分层级进行回显
 						const od = (form as any).organization_detail;
+						
+						// 如果组织树数据未加载,尝试加载(异步,不阻塞)
+						if (organizationTreeData.length === 0) {
+							initOrganizationTree();
+						}
+						
 						if ((form as any).user_type === 0 && od && Array.isArray(od.parent_chain)) {
 							// 期望 parent_chain: [学校, 学院, 专业, 年级] 或至少包含 [学院, 专业, 年级]
 							const chain = od.parent_chain;
@@ -418,6 +479,36 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 							if (od && od.id) {
 								(form as any).organization_ref = od.id;
 							}
+						} else if ((form as any).user_type === 0 && !od && organizationTreeData.length > 0) {
+							// 学生类型且 organization_detail 为 null 时,通过文本名称查找并回显
+							const orgName = (form as any).organization; // 学院名称
+							const subOrgName = (form as any).sub_organization; // 专业名称
+							const gradeName = (form as any).grade_or_level || (form as any).class_or_group; // 班级/年级名称
+							
+							// 查找学院节点(在学院层级查找)
+							if (orgName) {
+								const collegeNode = findNodeInColleges(orgName, organizationTreeData);
+								if (collegeNode) {
+									(form as any)._college_id = collegeNode.id;
+									
+									// 查找专业节点(在学院的直接子节点中查找)
+									if (subOrgName && Array.isArray(collegeNode.children)) {
+										const majorNode = collegeNode.children.find((child: any) => child.name === subOrgName);
+										if (majorNode) {
+											(form as any)._major_id = majorNode.id;
+											
+											// 查找班级/年级节点(在专业的直接子节点中查找)
+											if (gradeName && Array.isArray(majorNode.children)) {
+												const gradeNode = majorNode.children.find((child: any) => child.name === gradeName);
+												if (gradeNode) {
+													(form as any)._grade_id = gradeNode.id;
+													(form as any).organization_ref = gradeNode.id;
+												}
+											}
+										}
+									}
+								}
+							}
 						}
 					},
 					valueResolve({ form, value }) {

+ 135 - 43
src/views/system/studentInfo/crud.tsx

@@ -2,14 +2,70 @@ import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, dict, UserPageQue
 import * as api from './api';
 import { auth } from '/@/utils/authFunction';
 
+// 全局变量存储组织树数据,供 valueBuilder 使用
+let organizationTreeData: any[] = [];
+
+// 初始化时获取组织树数据
+const initOrganizationTree = async () => {
+	try {
+		const res = await api.GetTree();
+		if (res && (res.code === 200 || res.code === 2000 || !res.code)) {
+			const data = res.data || res.results || res;
+			if (Array.isArray(data)) {
+				organizationTreeData = data;
+			}
+		}
+	} catch (error) {
+		console.error('获取组织架构数据失败:', error);
+		organizationTreeData = [];
+	}
+};
+
+// 通过名称在组织树中查找节点的辅助函数(在整个树中递归搜索)
+function findNodeByName(name: string, tree: any[], depth: number = 0, maxDepth: number = 10): any {
+	if (!name || !tree || depth > maxDepth) return undefined;
+	
+	for (const node of tree) {
+		if (node.name === name) {
+			return node;
+		}
+		if (Array.isArray(node.children)) {
+			const found = findNodeByName(name, node.children, depth + 1, maxDepth);
+			if (found) return found;
+		}
+	}
+	return undefined;
+}
+
+// 在学院层级中查找节点(跳过学校层)
+function findNodeInColleges(name: string, tree: any[]): any {
+	if (!name || !tree) return undefined;
+	
+	// 遍历所有学校
+	for (const school of tree) {
+		if (Array.isArray(school.children)) {
+			// 在每个学校的子节点(学院)中查找
+			for (const college of school.children) {
+				if (college.name === name) {
+					return college;
+				}
+			}
+		}
+	}
+	return undefined;
+}
+
 export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet {
+	// 初始化组织树数据(异步执行,不阻塞返回)
+	initOrganizationTree();
+
 	const pageRequest = async (query: UserPageQuery) => {
 		return await api.GetList(query);
 	};
 
-		const getDetail = async ({ row }: InfoReq) => {
-		return await api.GetObj(row.id);
-	};
+	const getDetail = async ({ row }: InfoReq) => {
+	return await api.GetObj(row.id);
+};
 
 	const editRequest = async ({ form, row }: EditReq) => {
 		form.id = row.id;
@@ -354,48 +410,84 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 					// 学生类型表单的级联选择依赖于 index.vue 中的 _college_id/_major_id/_grade_id
 					// 这里通过 valueBuilder 在打开编辑/查看表单时,将 organization_detail.parent_chain 回显到这三个临时字段
 					// 同时通过 valueResolve 在提交时将最终选择写回 organization_ref(学生为年级ID,其它类型为学院ID)
-					valueBuilder({ form, value }) {
-						// 保留后端原始值
-						form.organization_ref = value;
-						// 仅学生类型需要拆分层级进行回显
-						const od = (form as any).organization_detail;
-						if ((form as any).user_type === 0 && od && Array.isArray(od.parent_chain)) {
-							// 期望 parent_chain: [学校, 学院, 专业, 年级] 或至少包含 [学院, 专业, 年级]
-							const chain = od.parent_chain;
-							// 按长度精确映射,避免把学校ID当作学院ID
-							if (chain.length >= 4) {
-								// [学校, 学院, 专业, 年级]
-								(form as any)._college_id = chain[1]?.id;
-								(form as any)._major_id = chain[2]?.id;
-								(form as any)._grade_id = od?.id;
-							} else if (chain.length === 3) {
-								// 常见后端:含学校,无年级 -> [学校, 学院, 专业]
-								(form as any)._college_id = chain[1]?.id;
-								(form as any)._major_id = chain[2]?.id;
-								(form as any)._grade_id = od?.id;
-							} else if (chain.length === 2) {
-								// [学院, 专业]
-								(form as any)._college_id = chain[0]?.id;
-								(form as any)._major_id = chain[1]?.id;
-								(form as any)._grade_id = od?.id;
-							} else if (chain.length === 1) {
-								// [学院]
-								(form as any)._college_id = chain[0]?.id;
-								(form as any)._major_id = undefined;
-								(form as any)._grade_id = od?.id;
-							} else {
-								(form as any)._college_id = undefined;
-								(form as any)._major_id = undefined;
-								(form as any)._grade_id = od?.id;
-							}
-							// 学生模式下,不直接把 organization_ref 设为学院,保持由 index.vue 的联动逻辑在变更时再写入
-						} else if ((form as any).user_type === 1 || (form as any).user_type === 3) {
-							// 教师/学院领导:直接以当前组织ID为学院选择
-							if (od && od.id) {
-								(form as any).organization_ref = od.id;
+				valueBuilder({ form, value }) {
+					// 保留后端原始值
+					form.organization_ref = value;
+					// 仅学生类型需要拆分层级进行回显
+					const od = (form as any).organization_detail;
+					
+					// 如果组织树数据未加载,尝试加载(异步,不阻塞)
+					if (organizationTreeData.length === 0) {
+						initOrganizationTree();
+					}
+					
+					if ((form as any).user_type === 0 && od && Array.isArray(od.parent_chain)) {
+						// 期望 parent_chain: [学校, 学院, 专业, 年级] 或至少包含 [学院, 专业, 年级]
+						const chain = od.parent_chain;
+						// 按长度精确映射,避免把学校ID当作学院ID
+						if (chain.length >= 4) {
+							// [学校, 学院, 专业, 年级]
+							(form as any)._college_id = chain[1]?.id;
+							(form as any)._major_id = chain[2]?.id;
+							(form as any)._grade_id = od?.id;
+						} else if (chain.length === 3) {
+							// 常见后端:含学校,无年级 -> [学校, 学院, 专业]
+							(form as any)._college_id = chain[1]?.id;
+							(form as any)._major_id = chain[2]?.id;
+							(form as any)._grade_id = od?.id;
+						} else if (chain.length === 2) {
+							// [学院, 专业]
+							(form as any)._college_id = chain[0]?.id;
+							(form as any)._major_id = chain[1]?.id;
+							(form as any)._grade_id = od?.id;
+						} else if (chain.length === 1) {
+							// [学院]
+							(form as any)._college_id = chain[0]?.id;
+							(form as any)._major_id = undefined;
+							(form as any)._grade_id = od?.id;
+						} else {
+							(form as any)._college_id = undefined;
+							(form as any)._major_id = undefined;
+							(form as any)._grade_id = od?.id;
+						}
+						// 学生模式下,不直接把 organization_ref 设为学院,保持由 index.vue 的联动逻辑在变更时再写入
+					} else if ((form as any).user_type === 1 || (form as any).user_type === 3) {
+						// 教师/学院领导:直接以当前组织ID为学院选择
+						if (od && od.id) {
+							(form as any).organization_ref = od.id;
+						}
+					} else if ((form as any).user_type === 0 && !od && organizationTreeData.length > 0) {
+						// 学生类型且 organization_detail 为 null 时,通过文本名称查找并回显
+						const orgName = (form as any).organization; // 学院名称
+						const subOrgName = (form as any).sub_organization; // 专业名称
+						const gradeName = (form as any).grade_or_level || (form as any).class_or_group; // 班级/年级名称
+						
+						// 查找学院节点(在学院层级查找)
+						if (orgName) {
+							const collegeNode = findNodeInColleges(orgName, organizationTreeData);
+							if (collegeNode) {
+								(form as any)._college_id = collegeNode.id;
+								
+								// 查找专业节点(在学院的直接子节点中查找)
+								if (subOrgName && Array.isArray(collegeNode.children)) {
+									const majorNode = collegeNode.children.find((child: any) => child.name === subOrgName);
+									if (majorNode) {
+										(form as any)._major_id = majorNode.id;
+										
+										// 查找班级/年级节点(在专业的直接子节点中查找)
+										if (gradeName && Array.isArray(majorNode.children)) {
+											const gradeNode = majorNode.children.find((child: any) => child.name === gradeName);
+											if (gradeNode) {
+												(form as any)._grade_id = gradeNode.id;
+												(form as any).organization_ref = gradeNode.id;
+											}
+										}
+									}
+								}
 							}
 						}
-					},
+					}
+				},
 					valueResolve({ form, value }) {
 						// 非学生:提交学院ID
 						if ((form as any).user_type !== 0) {

+ 7 - 0
src/views/system/teacherInfor/api.ts

@@ -105,3 +105,10 @@ export function GetPermission() {
 // 	return results.flatMap(res => res.data.data)
 //   }
   
+
+export function GetTree() {
+	return request({
+		url: `/api/system/organization/tree/`,
+		method: 'get',
+	});
+}

+ 91 - 18
src/views/system/teacherInfor/crud.tsx

@@ -2,7 +2,62 @@ import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, dict, UserPageQue
 import * as api from './api';
 import { auth } from '/@/utils/authFunction';
 
+// 全局变量存储组织树数据,供 valueBuilder 使用
+let organizationTreeData: any[] = [];
+
+// 初始化时获取组织树数据
+const initOrganizationTree = async () => {
+	try {
+		const res = await api.GetTree();
+		if (res && (res.code === 200 || res.code === 2000 || !res.code)) {
+			const data = res.data || res.results || res;
+			if (Array.isArray(data)) {
+				organizationTreeData = data;
+			}
+		}
+	} catch (error) {
+		console.error('获取组织架构数据失败:', error);
+		organizationTreeData = [];
+	}
+};
+
+// 通过名称在组织树中查找节点的辅助函数(在整个树中递归搜索)
+function findNodeByName(name: string, tree: any[], depth: number = 0, maxDepth: number = 10): any {
+	if (!name || !tree || depth > maxDepth) return undefined;
+	
+	for (const node of tree) {
+		if (node.name === name) {
+			return node;
+		}
+		if (Array.isArray(node.children)) {
+			const found = findNodeByName(name, node.children, depth + 1, maxDepth);
+			if (found) return found;
+		}
+	}
+	return undefined;
+}
+
+// 在学院层级中查找节点(跳过学校层)
+function findNodeInColleges(name: string, tree: any[]): any {
+	if (!name || !tree) return undefined;
+	
+	// 遍历所有学校
+	for (const school of tree) {
+		if (Array.isArray(school.children)) {
+			// 在每个学校的子节点(学院)中查找
+			for (const college of school.children) {
+				if (college.name === name) {
+					return college;
+				}
+			}
+		}
+	}
+	return undefined;
+}
+
 export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet {
+	// 初始化组织树数据(异步执行,不阻塞返回)
+	initOrganizationTree();
 	const pageRequest = async (query: UserPageQuery) => {
 		return await api.GetList(query);
 	
@@ -295,27 +350,45 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 						rules: [{ required: false, message: '请选择用户类型' }],
 					},
 				},
-				organization_ref:{
-					title: '学院',
-					type: "dict-cascader",
-					column: {
-						show: false,
-					},
-					// 教师和学院领导的级联选择
-					valueBuilder({ form, value }) {
-						// 保留后端原始值
-						form.organization_ref = value;
-						// 教师/学院领导:直接以当前组织ID为学院选择
-						const od = (form as any).organization_detail;
-						if (od && od.id) {
-							(form as any).organization_ref = od.id;
+			organization_ref:{
+				title: '学院',
+				type: "dict-cascader",
+				column: {
+					show: false,
+				},
+				// 教师和学院领导的级联选择
+				valueBuilder({ form, value }) {
+					// 保留后端原始值
+					form.organization_ref = value;
+					// 教师/学院领导:直接以当前组织ID为学院选择
+					const od = (form as any).organization_detail;
+					
+					if (od && od.id) {
+						// 有 organization_detail,直接使用其 id
+						(form as any).organization_ref = od.id;
+					} else if (!od && organizationTreeData.length > 0) {
+						// organization_detail 为 null 时,根据 organization 文本名称查找并回显
+						const orgName = (form as any).organization; // 学院名称
+						
+						if (orgName) {
+							// 在学院层级中查找节点(跳过学校层)
+							const collegeNode = findNodeInColleges(orgName, organizationTreeData);
+							if (collegeNode && collegeNode.id) {
+								(form as any).organization_ref = collegeNode.id;
+							}
 						}
-					},
-					valueResolve({ form, value }) {
-						// 教师/学院领导:提交学院ID
-						(form as any).organization_ref = value ?? (form as any).organization_ref;
+					}
+					
+					// 如果组织树数据未加载,尝试加载(异步,不阻塞)
+					if (organizationTreeData.length === 0) {
+						initOrganizationTree();
 					}
 				},
+				valueResolve({ form, value }) {
+					// 教师/学院领导:提交学院ID
+					(form as any).organization_ref = value ?? (form as any).organization_ref;
+				}
+			},
 				organization:{
 					title: '学院',
 					type: 'input',