Browse Source

提交代码

zlwu 1 year ago
parent
commit
46775101e9
1 changed files with 451 additions and 138 deletions
  1. 451 138
      mobile/src/pages/xg/xsjcxx/xsjcxx/index.vue

+ 451 - 138
mobile/src/pages/xg/xsjcxx/xsjcxx/index.vue

@@ -10,6 +10,12 @@
         <!-- 加载中状态 -->
         <u-loading-page :loading="loading" loading-text="加载中..."></u-loading-page>
 
+        <!-- 后台数据加载提示 -->
+        <view v-if="!loading && !backgroundDataLoaded" class="background-loading-tip">
+            <u-icon name="clock" size="16" color="#909399"></u-icon>
+            <text class="tip-text">部分辅助数据正在后台加载中...</text>
+        </view>
+
         <!-- 内容区域 -->
         <view v-if="!loading" class="content-wrapper">
             <!-- 学生基本信息卡片 -->
@@ -95,7 +101,7 @@
                     </view>
                     <view class="info-item">
                         <text class="label">籍贯</text>
-                        <text class="value">{{ getRegionFullPath(form.nativePlace) || '-' }}</text>
+                        <text class="value">{{ nativePlaceDisplayName || '-' }}</text>
                     </view>
                     <view class="info-item">
                         <text class="label">政治面貌</text>
@@ -172,7 +178,7 @@
                     <view class="info-item long-content">
                         <text class="label">生源地区</text>
                         <text class="value long-text">
-                            {{ getRegionFullPath(form.sourceRegion) || '-' }}
+                            {{ sourceRegionDisplayName || '-' }}
                         </text>
                     </view>
                     <view class="info-item long-content">
@@ -782,38 +788,32 @@ export default {
             // 显示名称(异步加载)
             roomDisplayName: '',
             bedDisplayName: '',
+            nativePlaceDisplayName: '', // 籍贯显示名称
+            sourceRegionDisplayName: '', // 生源地区显示名称
+
+            // 加载状态
+            regionLoadingPromise: null,
+            backgroundDataLoaded: false, // 后台数据是否加载完成
         };
     },
 
     async created() {
         console.log('=== 学生信息页面初始化开始 ===');
-        try {
-            await this.loadDictData();
-            console.log('✓ 字典数据加载完成');
-        } catch (error) {
-            console.error('字典数据加载出错(不影响后续流程):', error);
-        }
 
+        // 第一阶段:立即加载核心个人信息,让页面内容快速显示
         try {
-            await this.loadRegionAndDormData();
-            console.log('✓ 区域和宿舍数据加载完成');
+            this.loading = true;
+            await this.getPersonalInfoData();
+            console.log('✓ 核心个人信息加载完成,页面可以显示');
         } catch (error) {
-            console.error('区域和宿舍数据加载出错:', error);
+            console.error('个人信息加载失败:', error);
+            // 即使个人信息加载失败,也要设置loading为false,避免页面一直loading
+            this.loading = false;
         }
 
-        try {
-            await this.loadDormRoomAndBedData();
-            console.log('✓ 房间和床位数据加载完成');
-        } catch (error) {
-            console.error('房间和床位数据加载出错:', error);
-        }
+        // 第二阶段:并行加载辅助数据(不阻塞页面显示)
+        this.loadSupportingDataInBackground();
 
-        try {
-            await this.getPersonalInfoData();
-            console.log('✓ 个人信息加载完成');
-        } catch (error) {
-            console.error('个人信息加载出错:', error);
-        }
         console.log('=== 学生信息页面初始化完成 ===');
     },
 
@@ -1054,6 +1054,256 @@ export default {
             return getDictTagType(this.studentStatusOptions, this.form.studentStatus, fallbackMap);
         },
 
+        // 后台并行加载辅助数据
+        async loadSupportingDataInBackground() {
+            console.log('开始后台加载辅助数据...');
+
+            // 第一阶段:并行加载所有非核心数据,互不阻塞
+            const loadPromises = [
+                this.loadDictDataSafely(),
+                this.loadDormDataSafely(),
+                this.loadDormRoomAndBedDataSafely(),
+            ];
+
+            // 使用Promise.allSettled确保即使某些请求失败也不影响其他
+            const results = await Promise.allSettled(loadPromises);
+
+            results.forEach((result, index) => {
+                const taskNames = ['字典数据', '宿舍数据', '房间床位数据'];
+                if (result.status === 'fulfilled') {
+                    console.log(`✓ ${taskNames[index]}后台加载完成`);
+                } else {
+                    console.warn(`✗ ${taskNames[index]}后台加载失败:`, result.reason);
+                }
+            });
+
+            // 第二阶段:更新宿舍相关显示名称(不依赖区域数据)
+            try {
+                await this.updateDisplayNamesAfterBackgroundLoad();
+                console.log('✓ 后台数据加载后显示名称更新完成');
+            } catch (error) {
+                console.warn('后台数据加载后显示名称更新失败:', error);
+            }
+
+            // 第三阶段:尝试加载区域数据并更新区域显示名称(可选,不阻塞整体完成)
+            this.loadRegionDataAndUpdateDisplay();
+
+            console.log('=== 后台辅助数据加载完成 ===');
+            this.backgroundDataLoaded = true;
+        },
+
+        // 安全加载字典数据(出错不影响页面)
+        async loadDictDataSafely() {
+            try {
+                await this.loadDictData();
+            } catch (error) {
+                console.warn('字典数据加载失败,使用默认值:', error);
+                // 确保字典数组不为undefined
+                this.ensureDictArraysExist();
+            }
+        },
+
+        // 安全加载宿舍数据(出错不影响页面)
+        async loadDormDataSafely() {
+            try {
+                await this.loadDormBuildingData();
+            } catch (error) {
+                console.warn('宿舍数据加载失败,使用默认值:', error);
+                this.dormBuildingOptions = [];
+            }
+        },
+
+        // 安全加载房间床位数据(出错不影响页面)
+        async loadDormRoomAndBedDataSafely() {
+            try {
+                await this.loadDormRoomAndBedData();
+            } catch (error) {
+                console.warn('房间床位数据加载失败,使用默认值:', error);
+                this.dormRoomOptions = [];
+                this.dormBedOptions = [];
+            }
+        },
+
+        // 设置临时显示名称,避免页面空白
+        setTemporaryDisplayNames() {
+            // 设置临时的区域显示名称
+            if (this.form.nativePlace) {
+                this.nativePlaceDisplayName = `区域${this.form.nativePlace}`;
+            }
+            if (this.form.sourceRegion) {
+                this.sourceRegionDisplayName = `区域${this.form.sourceRegion}`;
+            }
+
+            // 房间和床位显示名称暂时留空,将在后台数据加载完成后更新
+            console.log('临时显示名称已设置');
+        },
+
+        // 异步加载区域数据并更新显示名称(不阻塞主流程)
+        async loadRegionDataAndUpdateDisplay() {
+            try {
+                console.log('开始异步加载区域数据...');
+                await this.loadRegionDataLazily();
+
+                // 区域数据加载完成后,更新区域显示名称
+                if (this.form.nativePlace) {
+                    const nativePlaceName = this.buildRegionPath(this.form.nativePlace);
+                    if (nativePlaceName !== `区域${this.form.nativePlace}`) {
+                        this.nativePlaceDisplayName = nativePlaceName;
+                        console.log('✓ 异步更新籍贯名称:', nativePlaceName);
+                    }
+                }
+
+                if (this.form.sourceRegion) {
+                    const sourceRegionName = this.buildRegionPath(this.form.sourceRegion);
+                    if (sourceRegionName !== `区域${this.form.sourceRegion}`) {
+                        this.sourceRegionDisplayName = sourceRegionName;
+                        console.log('✓ 异步更新生源地区名称:', sourceRegionName);
+                    }
+                }
+
+                console.log('✓ 区域数据加载和显示名称更新完成');
+            } catch (error) {
+                console.warn('区域数据加载失败,保持临时显示名称:', error);
+            }
+        },
+
+        // 后台数据加载完成后更新显示名称(仅处理宿舍相关)
+        async updateDisplayNamesAfterBackgroundLoad() {
+            const updatePromises = [];
+
+            // 更新房间和床位名称(需要宿舍数据)
+            if (this.form.dormitoryRoom) {
+                updatePromises.push(
+                    this.getRoomName(this.form.dormitoryRoom)
+                        .then((name) => {
+                            this.roomDisplayName = name;
+                            console.log('✓ 后台更新房间名称:', name);
+                        })
+                        .catch((error) => {
+                            console.warn('后台更新房间名称失败:', error);
+                        }),
+                );
+            }
+
+            if (this.form.extField1) {
+                updatePromises.push(
+                    this.getBedName(this.form.extField1)
+                        .then((name) => {
+                            this.bedDisplayName = name;
+                            console.log('✓ 后台更新床位名称:', name);
+                        })
+                        .catch((error) => {
+                            console.warn('后台更新床位名称失败:', error);
+                        }),
+                );
+            }
+
+            // 等待所有宿舍相关更新完成
+            await Promise.allSettled(updatePromises);
+            console.log('宿舍相关显示名称更新完成');
+        },
+
+        // 确保字典数组存在,避免页面报错
+        ensureDictArraysExist() {
+            const dictArrays = [
+                'genderOptions',
+                'nationalityOptions',
+                'politicalStatusOptions',
+                'educationLevelOptions',
+                'householdRegisterTypeOptions',
+                'maritalStatusOptions',
+                'yesNoOptions',
+                'familyEconomicOptions',
+                'bloodTypeOptions',
+                'disabilityTypeOptions',
+                'academicLevelOptions',
+                'trainingModeOptions',
+                'admissionCategoryOptions',
+                'studentStatusOptions',
+            ];
+
+            dictArrays.forEach((arrayName) => {
+                if (!this[arrayName] || !Array.isArray(this[arrayName])) {
+                    this[arrayName] = [];
+                }
+            });
+        },
+
+        // 单独加载宿舍楼栋数据
+        async loadDormBuildingData() {
+            console.log('开始加载宿舍楼栋数据...');
+            try {
+                const dormRes = await request({
+                    url: '/xgss/dormBuildingTree/listAll',
+                    method: 'GET',
+                });
+
+                if (dormRes && dormRes.data) {
+                    this.dormBuildingOptions = this.processDormTreeData(dormRes.data);
+                    console.log('宿舍楼栋数据处理完成,条目数:', this.dormBuildingOptions.length);
+                } else {
+                    console.warn('宿舍楼栋数据加载失败或为空');
+                    this.dormBuildingOptions = [];
+                }
+            } catch (error) {
+                console.error('加载宿舍楼栋数据失败:', error);
+                this.dormBuildingOptions = [];
+                throw error;
+            }
+        },
+
+        // 懒加载行政区划数据(仅在需要时加载)
+        async loadRegionDataLazily() {
+            // 如果已经加载过,直接返回
+            if (this.regionOptions && this.regionOptions.length > 0) {
+                return this.regionOptions;
+            }
+
+            // 如果正在加载中,等待加载完成
+            if (this.regionLoadingPromise) {
+                return await this.regionLoadingPromise;
+            }
+
+            // 开始加载
+            this.regionLoadingPromise = this.doLoadRegionData();
+
+            try {
+                await this.regionLoadingPromise;
+                return this.regionOptions;
+            } finally {
+                this.regionLoadingPromise = null;
+            }
+        },
+
+        // 实际执行行政区划数据加载
+        async doLoadRegionData() {
+            console.log('懒加载行政区划数据...');
+            try {
+                const regionRes = await request({
+                    url: '/system/SysRegion/tree',
+                    method: 'GET',
+                });
+
+                if (regionRes && regionRes.data) {
+                    this.regionOptions = regionRes.data;
+                    console.log('行政区划数据懒加载完成,条目数:', regionRes.data.length);
+                } else {
+                    console.warn('行政区划数据懒加载失败或为空');
+                    this.regionOptions = [];
+                }
+            } catch (error) {
+                console.error('懒加载行政区划数据失败:', error);
+                this.regionOptions = [];
+                // 显示用户友好的错误提示
+                uni.showToast({
+                    title: '区域数据加载失败',
+                    icon: 'none',
+                    duration: 2000,
+                });
+                throw error;
+            }
+        },
+
         // 加载字典数据
         async loadDictData() {
             console.log('开始加载字典数据...');
@@ -1163,105 +1413,6 @@ export default {
             }
         },
 
-        // 加载行政区划和宿舍楼栋数据
-        async loadRegionAndDormData() {
-            console.log('开始加载区域和宿舍数据...');
-            try {
-                console.log('发起并行请求: 行政区划 & 宿舍楼栋');
-                const [regionRes, dormRes] = await Promise.all([
-                    request({
-                        url: '/system/SysRegion/tree',
-                        method: 'GET',
-                    })
-                        .then((res) => {
-                            console.log('✓ 行政区划请求完成');
-                            return res;
-                        })
-                        .catch((err) => {
-                            console.error('✗ 行政区划请求失败:', err);
-                            throw err;
-                        }),
-                    request({
-                        url: '/xgss/dormBuildingTree/listAll',
-                        method: 'GET',
-                    })
-                        .then((res) => {
-                            console.log('✓ 宿舍楼栋请求完成');
-                            return res;
-                        })
-                        .catch((err) => {
-                            console.error('✗ 宿舍楼栋请求失败:', err);
-                            throw err;
-                        }),
-                ]);
-
-                // 处理行政区划数据
-                if (regionRes && regionRes.data) {
-                    this.regionOptions = regionRes.data;
-                    console.log('行政区划数据处理完成,条目数:', regionRes.data.length);
-                } else {
-                    console.warn('行政区划数据加载失败或为空');
-                }
-
-                // 处理宿舍楼栋数据,添加性别标识
-                if (dormRes && dormRes.data) {
-                    console.log('dormRes', dormRes);
-                    this.dormBuildingOptions = this.processDormTreeData(dormRes.data);
-                    console.log('宿舍楼栋数据处理完成,条目数:', this.dormBuildingOptions.length);
-                } else {
-                    console.warn('宿舍楼栋数据加载失败或为空');
-                    this.dormBuildingOptions = [];
-                }
-            } catch (error) {
-                console.error('加载区域和宿舍数据失败:', error);
-                uni.showToast({
-                    title: '加载基础数据失败,部分功能可能受影响',
-                    icon: 'none',
-                    duration: 3000,
-                });
-            }
-        },
-
-        // 处理宿舍楼栋树形数据,为楼栋添加性别标识
-        processDormTreeData(nodes) {
-            console.log('processDormTreeData - nodes', nodes);
-            if (!nodes || !Array.isArray(nodes)) {
-                console.warn('宿舍楼栋数据格式不正确');
-                return [];
-            }
-
-            return nodes.map((node) => {
-                const processedNode = { ...node };
-
-                // 如果是楼栋类型,添加性别标识
-                if (node.type === 'building' && node.buildingType) {
-                    console.log('node.buildingType', node.buildingType);
-                    const genderSuffix =
-                        node.buildingType === '1'
-                            ? '(男)'
-                            : node.buildingType === '2'
-                            ? '(女)'
-                            : '';
-
-                    // 确保 label 和 name 存在后再添加后缀
-                    if (node.label) {
-                        processedNode.label = node.label + genderSuffix;
-                    }
-                    if (node.name) {
-                        processedNode.name = node.name + genderSuffix;
-                    }
-                }
-
-                // 递归处理子节点
-                if (node.children && node.children.length > 0) {
-                    processedNode.children = this.processDormTreeData(node.children);
-                }
-                console.log('processedNode', processedNode);
-
-                return processedNode;
-            });
-        },
-
         // 加载房间和床位数据(改为按需加载)
         async loadDormRoomAndBedData() {
             console.log('房间和床位数据改为按需加载模式,不再预加载所有数据');
@@ -1270,29 +1421,70 @@ export default {
             this.dormBedOptions = [];
         },
 
-        // 异步加载房间和床位显示名称
-        async loadRoomAndBedDisplayNames() {
+        // 异步加载各种显示名称(房间、床位、区域)
+        async loadDisplayNames() {
             try {
-                // 加载房间名称
+                // 并行加载房间和床位名称
+                const loadPromises = [];
+
                 if (this.form.dormitoryRoom) {
-                    this.roomDisplayName = await this.getRoomName(this.form.dormitoryRoom);
-                    console.log('房间名称加载完成:', this.roomDisplayName);
+                    loadPromises.push(
+                        this.getRoomName(this.form.dormitoryRoom).then((name) => {
+                            this.roomDisplayName = name;
+                            console.log('房间名称加载完成:', name);
+                        }),
+                    );
                 }
 
-                // 加载床位名称
                 if (this.form.extField1) {
-                    this.bedDisplayName = await this.getBedName(this.form.extField1);
-                    console.log('床位名称加载完成:', this.bedDisplayName);
+                    loadPromises.push(
+                        this.getBedName(this.form.extField1).then((name) => {
+                            this.bedDisplayName = name;
+                            console.log('床位名称加载完成:', name);
+                        }),
+                    );
+                }
+
+                // 并行加载区域显示名称(不阻塞房间床位显示)
+                if (this.form.nativePlace) {
+                    loadPromises.push(
+                        this.getRegionFullPathAsync(this.form.nativePlace)
+                            .then((name) => {
+                                this.nativePlaceDisplayName = name;
+                                console.log('籍贯显示名称加载完成:', name);
+                            })
+                            .catch((error) => {
+                                console.warn('籍贯显示名称加载失败:', error);
+                                this.nativePlaceDisplayName = `区域${this.form.nativePlace}`;
+                            }),
+                    );
+                }
+
+                if (this.form.sourceRegion) {
+                    loadPromises.push(
+                        this.getRegionFullPathAsync(this.form.sourceRegion)
+                            .then((name) => {
+                                this.sourceRegionDisplayName = name;
+                                console.log('生源地区显示名称加载完成:', name);
+                            })
+                            .catch((error) => {
+                                console.warn('生源地区显示名称加载失败:', error);
+                                this.sourceRegionDisplayName = `区域${this.form.sourceRegion}`;
+                            }),
+                    );
                 }
+
+                // 等待所有显示名称加载完成(使用 allSettled 确保部分失败不影响其他)
+                await Promise.allSettled(loadPromises);
+                console.log('所有显示名称加载完成');
             } catch (error) {
-                console.error('加载房间和床位显示名称失败:', error);
+                console.error('加载显示名称失败:', error);
             }
         },
 
         // 获取学生个人信息
         async getPersonalInfoData() {
             try {
-                this.loading = true;
                 const response = await request({
                     url: '/studentMsg/studentMsg/personalInfo',
                     method: 'GET',
@@ -1331,8 +1523,10 @@ export default {
                         extField1Type: typeof this.form.extField1,
                     });
 
-                    // 异步加载房间和床位信息
-                    await this.loadRoomAndBedDisplayNames();
+                    // 立即设置临时显示名称,避免空白
+                    this.setTemporaryDisplayNames();
+
+                    console.log('✓ 个人信息加载完成,页面可以显示');
                 } else {
                     uni.showToast({
                         title: response.msg || '获取个人信息失败',
@@ -1437,9 +1631,108 @@ export default {
             }
         },
 
-        // 根据行政区划代码获取完整路径(省/市/区)
+        // 处理宿舍楼栋树形数据,为楼栋添加性别标识
+        processDormTreeData(nodes) {
+            console.log('processDormTreeData - nodes', nodes);
+            if (!nodes || !Array.isArray(nodes)) {
+                console.warn('宿舍楼栋数据格式不正确');
+                return [];
+            }
+
+            return nodes.map((node) => {
+                const processedNode = { ...node };
+
+                // 如果是楼栋类型,添加性别标识
+                if (node.type === 'building' && node.buildingType) {
+                    console.log('node.buildingType', node.buildingType);
+                    const genderSuffix =
+                        node.buildingType === '1'
+                            ? '(男)'
+                            : node.buildingType === '2'
+                            ? '(女)'
+                            : '';
+
+                    // 确保 label 和 name 存在后再添加后缀
+                    if (node.label) {
+                        processedNode.label = node.label + genderSuffix;
+                    }
+                    if (node.name) {
+                        processedNode.name = node.name + genderSuffix;
+                    }
+                }
+
+                // 递归处理子节点
+                if (node.children && node.children.length > 0) {
+                    processedNode.children = this.processDormTreeData(node.children);
+                }
+                console.log('processedNode', processedNode);
+
+                return processedNode;
+            });
+        },
+
+        // 异步获取区域完整路径(用于后台加载)
+        async getRegionFullPathAsync(code) {
+            if (!code) return '';
+
+            // 懒加载区域数据
+            await this.loadRegionDataLazily();
+
+            // 获取完整路径
+            return this.buildRegionPath(code);
+        },
+
+        // 构建区域路径(纯计算,不触发加载)
+        buildRegionPath(code) {
+            if (!code || !this.regionOptions || this.regionOptions.length === 0) {
+                return `区域${code}`;
+            }
+
+            const path = [];
+            const findPath = (nodes, targetCode) => {
+                for (const node of nodes) {
+                    path.push(node.name);
+                    if (node.code === targetCode) {
+                        return true;
+                    }
+                    if (node.children && node.children.length > 0) {
+                        if (findPath(node.children, targetCode)) {
+                            return true;
+                        }
+                    }
+                    path.pop();
+                }
+                return false;
+            };
+
+            if (findPath(this.regionOptions, code)) {
+                return path.join(' / ');
+            }
+
+            return `区域${code}`;
+        },
+
+        // 根据行政区划代码获取完整路径(省/市/区)- 同步版本,用于模板(已弃用)
         getRegionFullPath(code) {
-            if (!code || !this.regionOptions) return '';
+            if (!code) return '';
+
+            // 如果行政区划数据未加载,触发懒加载并返回临时显示
+            if (!this.regionOptions || this.regionOptions.length === 0) {
+                // 异步加载区域数据,不阻塞当前显示
+                this.loadRegionDataLazily()
+                    .then(() => {
+                        // 加载完成后触发页面更新
+                        this.$forceUpdate();
+                    })
+                    .catch(() => {
+                        // 加载失败时显示代码
+                        console.warn('行政区划数据懒加载失败,显示原始代码');
+                    });
+
+                // 返回代码作为临时显示
+                return `区域${code}`;
+            }
+
             const path = [];
             const findPath = (nodes, targetCode) => {
                 for (const node of nodes) {
@@ -1456,8 +1749,13 @@ export default {
                 }
                 return false;
             };
-            findPath(this.regionOptions, code);
-            return path.join(' / ');
+
+            if (findPath(this.regionOptions, code)) {
+                return path.join(' / ');
+            }
+
+            // 如果找不到,返回代码
+            return `区域${code}`;
         },
 
         // 根据楼栋ID获取楼栋名称(含性别标识)
@@ -1726,6 +2024,21 @@ export default {
     min-height: 100vh;
 }
 
+.background-loading-tip {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    padding: 16rpx 30rpx;
+    background-color: #f0f9ff;
+    border-bottom: 1px solid #e1ecf4;
+    gap: 8rpx;
+}
+
+.tip-text {
+    font-size: 24rpx;
+    color: #606266;
+}
+
 .content-wrapper {
     padding: 20rpx;
     padding-bottom: 40rpx;