zlwu 1 год назад
Родитель
Сommit
27c2a307e6
3 измененных файлов с 3698 добавлено и 0 удалено
  1. 8 0
      mobile/src/pages.json
  2. 17 0
      mobile/src/pages/xgss/wsjc/wsjc.vue
  3. 3673 0
      mobile/src/pages/xgss/wsjc/wsjcDetail.vue

+ 8 - 0
mobile/src/pages.json

@@ -191,6 +191,14 @@
 				"navigationBarBackgroundColor": "#0051d9",
 				"navigationBarTextStyle": "white"
 			}
+		},
+		{
+			"path": "pages/xgss/wsjc/wsjcDetail",
+			"style": {
+				"navigationBarTitleText": "宿舍卫生检查详情",
+				"navigationBarBackgroundColor": "#0051d9",
+				"navigationBarTextStyle": "white"
+			}
 		}
 	],
 	"globalStyle": {

+ 17 - 0
mobile/src/pages/xgss/wsjc/wsjc.vue

@@ -150,6 +150,12 @@
 
                     <!-- 操作按钮 -->
                     <view class="card-actions">
+                        <!-- 查看按钮 -->
+                        <view class="action-btn primary-btn" @click="handleView(item)">
+                            <u-icon name="eye" size="16" color="#19be6b"></u-icon>
+                            <text class="btn-text">查看</text>
+                        </view>
+
                         <!-- 修改按钮 -->
                         <view class="action-btn info-btn" @click="handleUpdate(item)">
                             <u-icon name="edit-pen" size="16" color="#3c9cff"></u-icon>
@@ -430,6 +436,13 @@ export default {
             });
         },
 
+        // 查看检查
+        handleView(item) {
+            uni.navigateTo({
+                url: `/pages/xgss/wsjc/wsjcDetail?id=${item.id}&type=view`,
+            });
+        },
+
         // 修改检查
         handleUpdate(item) {
             uni.navigateTo({
@@ -741,6 +754,10 @@ export default {
     font-weight: 500;
 }
 
+.primary-btn .btn-text {
+    color: #19be6b;
+}
+
 .info-btn .btn-text {
     color: #3c9cff;
 }

+ 3673 - 0
mobile/src/pages/xgss/wsjc/wsjcDetail.vue

@@ -0,0 +1,3673 @@
+<template>
+    <view class="page-container">
+        <!-- 顶部导航 -->
+        <u-navbar :title="navTitle" :border-bottom="false" bg-color="#3c9cff" title-color="#fff">
+            <view slot="left" @click="goBack">
+                <u-icon name="arrow-left" color="#fff" size="22"></u-icon>
+            </view>
+        </u-navbar>
+
+        <!-- 加载状态 -->
+        <u-loading-page :loading="pageLoading" loading-text="加载中..."></u-loading-page>
+
+        <!-- 表单内容 -->
+        <view v-if="!pageLoading" class="form-container">
+            <u-form ref="formRef" :model="formData" :rules="rules" label-width="100">
+                <!-- 基本信息 -->
+                <view class="form-section">
+                    <text class="section-title">基本信息</text>
+
+                    <u-form-item label="检查标题" prop="checkTitle" required>
+                        <u-input
+                            v-model="formData.checkTitle"
+                            placeholder="请输入检查标题"
+                            :readonly="pageType === 'view'"
+                        />
+                    </u-form-item>
+
+                    <u-form-item label="检查日期" prop="checkDate" required>
+                        <view
+                            @click="pageType !== 'view' && (showDatePicker = true)"
+                            style="width: 100%"
+                        >
+                            <u-input
+                                v-model="checkDateDisplay"
+                                placeholder="请选择检查日期"
+                                readonly
+                                border="none"
+                                :suffix-icon="pageType === 'view' ? '' : 'arrow-down'"
+                                suffix-icon-style="color: #c8c9cc;"
+                                :style="
+                                    pageType === 'view'
+                                        ? 'pointer-events: none'
+                                        : 'pointer-events: none'
+                                "
+                            />
+                        </view>
+                        <u-datetime-picker
+                            :show="showDatePicker"
+                            v-model="checkDateValue"
+                            mode="datetime"
+                            @confirm="handleDateConfirm"
+                            @cancel="showDatePicker = false"
+                        ></u-datetime-picker>
+                    </u-form-item>
+
+                    <u-form-item label="检查类型" prop="checkType" required>
+                        <view
+                            @click="pageType !== 'view' && (showCheckTypePicker = true)"
+                            style="width: 100%"
+                        >
+                            <u-input
+                                v-model="checkTypeDisplay"
+                                placeholder="请选择检查类型"
+                                readonly
+                                border="none"
+                                :suffix-icon="pageType === 'view' ? '' : 'arrow-down'"
+                                suffix-icon-style="color: #c8c9cc;"
+                                :style="
+                                    pageType === 'view'
+                                        ? 'pointer-events: none'
+                                        : 'pointer-events: none'
+                                "
+                            />
+                        </view>
+                        <u-picker
+                            :show="showCheckTypePicker && xg_dorm_hygiene_check_type.length > 0"
+                            :columns="checkTypeColumns"
+                            :defaultIndex="checkTypeDefaultIndex"
+                            keyName="text"
+                            @confirm="handleCheckTypeConfirm"
+                            @cancel="showCheckTypePicker = false"
+                        ></u-picker>
+                    </u-form-item>
+
+                    <u-form-item label="检查级别" prop="checkLevel" required>
+                        <view
+                            @click="pageType !== 'view' && (showCheckLevelPicker = true)"
+                            style="width: 100%"
+                        >
+                            <u-input
+                                v-model="checkLevelDisplay"
+                                placeholder="请选择检查级别"
+                                readonly
+                                border="none"
+                                :suffix-icon="pageType === 'view' ? '' : 'arrow-down'"
+                                suffix-icon-style="color: #c8c9cc;"
+                                :style="
+                                    pageType === 'view'
+                                        ? 'pointer-events: none'
+                                        : 'pointer-events: none'
+                                "
+                            />
+                        </view>
+                        <u-picker
+                            :show="showCheckLevelPicker && xg_dorm_hygiene_check_level.length > 0"
+                            :columns="checkLevelColumns"
+                            :defaultIndex="checkLevelDefaultIndex"
+                            keyName="text"
+                            @confirm="handleCheckLevelConfirm"
+                            @cancel="showCheckLevelPicker = false"
+                        ></u-picker>
+                    </u-form-item>
+                </view>
+
+                <!-- 位置信息 -->
+                <view class="form-section">
+                    <text class="section-title">位置信息</text>
+
+                    <u-form-item label="校区" prop="campusId" required>
+                        <view
+                            @click="pageType !== 'view' && (showCampusPicker = true)"
+                            style="width: 100%"
+                        >
+                            <u-input
+                                v-model="formData.campusName"
+                                placeholder="请选择校区"
+                                readonly
+                                border="none"
+                                :suffix-icon="pageType === 'view' ? '' : 'arrow-down'"
+                                suffix-icon-style="color: #c8c9cc;"
+                                :style="
+                                    pageType === 'view'
+                                        ? 'pointer-events: none'
+                                        : 'pointer-events: none'
+                                "
+                            />
+                        </view>
+                        <u-picker
+                            :show="showCampusPicker"
+                            :columns="campusColumns"
+                            keyName="text"
+                            @confirm="handleCampusConfirm"
+                            @cancel="showCampusPicker = false"
+                        ></u-picker>
+                    </u-form-item>
+
+                    <u-form-item label="宿舍区" prop="areaId" required>
+                        <view
+                            @click="pageType !== 'view' && (showAreaPicker = true)"
+                            style="width: 100%"
+                        >
+                            <u-input
+                                v-model="formData.areaName"
+                                placeholder="请选择宿舍区"
+                                readonly
+                                border="none"
+                                :suffix-icon="pageType === 'view' ? '' : 'arrow-down'"
+                                suffix-icon-style="color: #c8c9cc;"
+                                :disabled="!formData.campusId"
+                                :style="
+                                    pageType === 'view'
+                                        ? 'pointer-events: none'
+                                        : 'pointer-events: none'
+                                "
+                            />
+                        </view>
+                        <u-picker
+                            :show="showAreaPicker"
+                            :columns="areaColumns"
+                            keyName="text"
+                            @confirm="handleAreaConfirm"
+                            @cancel="showAreaPicker = false"
+                        ></u-picker>
+                    </u-form-item>
+
+                    <u-form-item label="宿舍楼" prop="buildingId" required>
+                        <view
+                            @click="pageType !== 'view' && (showBuildingPicker = true)"
+                            style="width: 100%"
+                        >
+                            <u-input
+                                v-model="formData.buildingName"
+                                placeholder="请选择宿舍楼"
+                                readonly
+                                border="none"
+                                :suffix-icon="pageType === 'view' ? '' : 'arrow-down'"
+                                suffix-icon-style="color: #c8c9cc;"
+                                :disabled="!formData.areaId"
+                                :style="
+                                    pageType === 'view'
+                                        ? 'pointer-events: none'
+                                        : 'pointer-events: none'
+                                "
+                            />
+                        </view>
+                        <u-picker
+                            :show="showBuildingPicker"
+                            :columns="buildingColumns"
+                            keyName="text"
+                            @confirm="handleBuildingConfirm"
+                            @cancel="showBuildingPicker = false"
+                        ></u-picker>
+                    </u-form-item>
+
+                    <u-form-item label="房间" prop="roomId" required>
+                        <view
+                            @click="pageType !== 'view' && (showRoomPicker = true)"
+                            style="width: 100%"
+                        >
+                            <u-input
+                                v-model="formData.roomName"
+                                placeholder="请选择房间"
+                                readonly
+                                border="none"
+                                :suffix-icon="pageType === 'view' ? '' : 'arrow-down'"
+                                suffix-icon-style="color: #c8c9cc;"
+                                :disabled="!formData.buildingId"
+                                :style="
+                                    pageType === 'view'
+                                        ? 'pointer-events: none'
+                                        : 'pointer-events: none'
+                                "
+                            />
+                        </view>
+                        <u-picker
+                            :show="showRoomPicker"
+                            :columns="roomColumns"
+                            keyName="text"
+                            @confirm="handleRoomConfirm"
+                            @cancel="showRoomPicker = false"
+                        ></u-picker>
+                    </u-form-item>
+                </view>
+
+                <!-- 检查结果 -->
+                <view class="form-section">
+                    <text class="section-title">检查结果</text>
+
+                    <u-form-item label="宿舍总分" prop="totalScore" required>
+                        <u-input
+                            v-model="formData.totalScore"
+                            type="digit"
+                            placeholder="请输入宿舍总分(0-100分)"
+                            :readonly="pageType === 'view'"
+                            @input="pageType !== 'view' && handleTotalScoreChange"
+                        />
+                    </u-form-item>
+
+                    <u-form-item label="卫生等级" prop="hygieneGrade" required>
+                        <view
+                            @click="pageType !== 'view' && (showHygieneGradePicker = true)"
+                            style="width: 100%"
+                        >
+                            <u-input
+                                v-model="hygieneGradeDisplay"
+                                placeholder="请选择卫生等级"
+                                readonly
+                                border="none"
+                                :suffix-icon="pageType === 'view' ? '' : 'arrow-down'"
+                                suffix-icon-style="color: #c8c9cc;"
+                                :style="
+                                    pageType === 'view'
+                                        ? 'pointer-events: none'
+                                        : 'pointer-events: none'
+                                "
+                            />
+                        </view>
+                        <u-picker
+                            :show="showHygieneGradePicker && xg_dorm_hygiene_grade.length > 0"
+                            :columns="hygieneGradeColumns"
+                            :defaultIndex="hygieneGradeDefaultIndex"
+                            keyName="text"
+                            @confirm="handleHygieneGradeConfirm"
+                            @cancel="showHygieneGradePicker = false"
+                        ></u-picker>
+                    </u-form-item>
+                </view>
+
+                <!-- 房间学生信息 -->
+                <view v-if="formData.roomId && roomStudents.length > 0" class="form-section">
+                    <text class="section-title">房间学生信息</text>
+
+                    <view class="student-list">
+                        <view
+                            v-for="(student, index) in roomStudents"
+                            :key="index"
+                            class="student-item"
+                        >
+                            <view class="student-header">
+                                <text class="student-name">{{ student.studentName }}</text>
+                                <text class="student-no">{{ student.studentNo }}</text>
+                                <text class="student-bed">{{ student.bedName }}</text>
+                            </view>
+                            <view class="student-form">
+                                <view class="form-row-flex">
+                                    <view class="form-col-flex">
+                                        <text class="form-label">个人得分</text>
+                                        <u-input
+                                            v-model="student.student_score"
+                                            type="digit"
+                                            placeholder="0-100分"
+                                            size="small"
+                                            :readonly="pageType === 'view'"
+                                            style="
+                                                height: 60rpx;
+                                                line-height: 60rpx;
+                                                padding: 0px 10px !important;
+                                            "
+                                            @input="
+                                                pageType !== 'view' &&
+                                                    handleStudentScoreChange(student)
+                                            "
+                                        />
+                                    </view>
+                                    <view class="form-col-flex">
+                                        <text class="form-label">出勤状态</text>
+                                        <view
+                                            @click="
+                                                pageType !== 'view' &&
+                                                    (student.showAttendancePicker = true)
+                                            "
+                                            style="width: 100%"
+                                        >
+                                            <u-input
+                                                :value="
+                                                    getAttendanceDisplay(student.attendance_status)
+                                                "
+                                                placeholder="请选择"
+                                                readonly
+                                                border="none"
+                                                :suffix-icon="
+                                                    pageType === 'view' ? '' : 'arrow-down'
+                                                "
+                                                suffix-icon-style="color: #c8c9cc;"
+                                                size="small"
+                                                :style="
+                                                    pageType === 'view'
+                                                        ? 'pointer-events: none'
+                                                        : 'pointer-events: none'
+                                                "
+                                            />
+                                        </view>
+                                        <u-picker
+                                            :show="
+                                                student.showAttendancePicker &&
+                                                xg_student_attendance_status.length > 0
+                                            "
+                                            :columns="attendanceStatusColumns"
+                                            keyName="text"
+                                            @confirm="(e) => handleAttendanceConfirm(e, student)"
+                                            @cancel="student.showAttendancePicker = false"
+                                        ></u-picker>
+                                    </view>
+                                    <view class="form-col-flex">
+                                        <text class="form-label">学生评级</text>
+                                        <view
+                                            @click="
+                                                pageType !== 'view' &&
+                                                    (student.showGradePicker = true)
+                                            "
+                                            style="width: 100%"
+                                        >
+                                            <u-input
+                                                :value="getGradeDisplay(student.student_grade)"
+                                                placeholder="请选择"
+                                                readonly
+                                                border="none"
+                                                :suffix-icon="
+                                                    pageType === 'view' ? '' : 'arrow-down'
+                                                "
+                                                suffix-icon-style="color: #c8c9cc;"
+                                                size="small"
+                                                :style="
+                                                    pageType === 'view'
+                                                        ? 'pointer-events: none'
+                                                        : 'pointer-events: none'
+                                                "
+                                            />
+                                        </view>
+                                        <u-picker
+                                            :show="
+                                                student.showGradePicker &&
+                                                xg_dorm_hygiene_grade.length > 0
+                                            "
+                                            :columns="hygieneGradeColumns"
+                                            keyName="text"
+                                            @confirm="(e) => handleStudentGradeConfirm(e, student)"
+                                            @cancel="student.showGradePicker = false"
+                                        ></u-picker>
+                                    </view>
+                                </view>
+                            </view>
+                        </view>
+                    </view>
+                </view>
+
+                <!-- 附件上传 -->
+                <view class="form-section">
+                    <text class="section-title">附件上传</text>
+
+                    <view class="upload-area">
+                        <!-- 图片展示区域 -->
+                        <view v-if="imageFiles.length > 0" class="image-section">
+                            <view class="image-title">图片附件</view>
+                            <view class="image-grid">
+                                <view
+                                    v-for="(image, index) in imageFiles"
+                                    :key="image.uid || index"
+                                    class="image-item"
+                                    @click="handleImageClick(image, index, $event)"
+                                >
+                                    <!-- 图片容器 -->
+                                    <view class="image-container">
+                                        <image
+                                            :src="image.blobUrl || image.url"
+                                            class="attachment-image"
+                                            mode="aspectFill"
+                                        ></image>
+
+                                        <!-- 上传状态遮罩 -->
+                                        <view
+                                            v-if="image.status === 'uploading'"
+                                            class="upload-overlay"
+                                        >
+                                            <u-loading-icon
+                                                mode="circle"
+                                                size="24"
+                                                color="#fff"
+                                            ></u-loading-icon>
+                                            <text class="upload-text">
+                                                {{ image.progress || 0 }}%
+                                            </text>
+                                        </view>
+
+                                        <!-- 错误状态遮罩 -->
+                                        <view v-if="image.status === 'error'" class="error-overlay">
+                                            <u-icon
+                                                name="close-circle"
+                                                size="24"
+                                                color="#fff"
+                                            ></u-icon>
+                                            <text class="error-text">上传失败</text>
+                                        </view>
+
+                                        <!-- 成功状态角标 -->
+                                        <view
+                                            v-if="image.status === 'success'"
+                                            class="success-badge"
+                                        >
+                                            <u-icon
+                                                name="checkmark-circle-fill"
+                                                size="18"
+                                                color="#52c41a"
+                                            ></u-icon>
+                                        </view>
+                                    </view>
+
+                                    <!-- 图片操作按钮 -->
+                                    <view class="image-actions" @click.stop>
+                                        <u-button
+                                            v-if="image.status === 'success'"
+                                            size="mini"
+                                            type="primary"
+                                            plain
+                                            @tap="handleImageDownload(image)"
+                                            @click.stop.prevent="
+                                                handleImageDownloadClick(image, $event)
+                                            "
+                                        >
+                                            下载
+                                        </u-button>
+                                        <u-button
+                                            v-if="image.status === 'error'"
+                                            size="mini"
+                                            type="warning"
+                                            plain
+                                            @click.stop.prevent="retryUploadFile(image, $event)"
+                                        >
+                                            重试
+                                        </u-button>
+                                        <!-- <u-button
+                                            size="mini"
+                                            type="error"
+                                            plain
+                                            @tap="handleImageDelete(image, index)"
+                                            @click.stop.prevent="
+                                                handleImageDeleteClick(image, index, $event)
+                                            "
+                                        >
+                                            删除
+                                        </u-button> -->
+                                    </view>
+
+                                    <!-- 文件名显示 -->
+                                    <view class="image-name">
+                                        <text>{{ getShortFileName(image.name) }}</text>
+                                    </view>
+                                </view>
+                            </view>
+                        </view>
+
+                        <!-- 微信图片上传进度条 -->
+                        <view
+                            v-if="uploadProgress > 0 && uploadProgress < 100"
+                            class="upload-progress"
+                        >
+                            <u-line-progress
+                                :percent="uploadProgress"
+                                :show-percent="true"
+                                active-color="#2979ff"
+                                inactive-color="#f0f0f0"
+                                height="8"
+                                :striped="true"
+                                :striped-active="true"
+                            ></u-line-progress>
+                            <text class="progress-text">
+                                微信图片上传进度: {{ uploadProgress }}%
+                            </text>
+                        </view>
+
+                        <!-- 自定义文件列表(用于显示非图片文件和上传状态) -->
+                        <view class="custom-file-list" v-if="nonImageFiles.length > 0">
+                            <view class="file-title">文档附件</view>
+                            <view class="file-grid">
+                                <view
+                                    class="file-card"
+                                    v-for="file in nonImageFiles"
+                                    :key="file.uid"
+                                >
+                                    <!-- 文件图标容器 -->
+                                    <view class="file-icon-container">
+                                        <u-icon
+                                            :name="
+                                                file.status === 'uploading' ? 'loading' : 'folder'
+                                            "
+                                            size="50"
+                                            :color="
+                                                file.status === 'error'
+                                                    ? '#fa3534'
+                                                    : file.status === 'success'
+                                                    ? '#19be6b'
+                                                    : '#909399'
+                                            "
+                                        />
+
+                                        <!-- 上传状态遮罩 -->
+                                        <view
+                                            v-if="file.status === 'uploading'"
+                                            class="upload-overlay"
+                                        >
+                                            <u-loading-icon
+                                                mode="circle"
+                                                size="24"
+                                                color="#fff"
+                                            ></u-loading-icon>
+                                            <text class="upload-text">
+                                                {{ file.progress || 0 }}%
+                                            </text>
+                                        </view>
+
+                                        <!-- 错误状态遮罩 -->
+                                        <view v-if="file.status === 'error'" class="error-overlay">
+                                            <u-icon
+                                                name="close-circle"
+                                                size="24"
+                                                color="#fff"
+                                            ></u-icon>
+                                            <text class="error-text">上传失败</text>
+                                        </view>
+
+                                        <!-- 成功状态角标 -->
+                                        <view
+                                            v-if="file.status === 'success'"
+                                            class="success-badge"
+                                        >
+                                            <u-icon
+                                                name="checkmark-circle-fill"
+                                                size="18"
+                                                color="#52c41a"
+                                            ></u-icon>
+                                        </view>
+                                    </view>
+
+                                    <!-- 文件操作按钮 -->
+                                    <view class="image-actions" @click.stop>
+                                        <u-button
+                                            v-if="file.status === 'success'"
+                                            size="mini"
+                                            type="primary"
+                                            plain
+                                            @tap="handleDownloadFile(file)"
+                                            @click.stop.prevent="
+                                                handleDownloadFileClick(file, $event)
+                                            "
+                                        >
+                                            下载
+                                        </u-button>
+                                        <u-button
+                                            v-if="file.status === 'error'"
+                                            size="mini"
+                                            type="warning"
+                                            plain
+                                            @click.stop.prevent="retryUploadFile(file, $event)"
+                                        >
+                                            重试
+                                        </u-button>
+                                        <!-- <u-button
+                                            size="mini"
+                                            type="error"
+                                            plain
+                                            @click.stop.prevent="
+                                                handleRemoveFile(
+                                                    file,
+                                                    index +
+                                                        attachmentList.filter((f) => isImageFile(f))
+                                                            .length,
+                                                    $event,
+                                                )
+                                            "
+                                        >
+                                            删除
+                                        </u-button> -->
+                                    </view>
+
+                                    <!-- 文件名显示 -->
+                                    <view class="file-name-display">
+                                        <text>{{ getShortFileName(file.name) }}</text>
+                                    </view>
+                                </view>
+                            </view>
+                        </view>
+
+                        <!-- 统一附件上传按钮 -->
+                        <view v-if="pageType !== 'view'" class="doc-upload-section">
+                            <u-button
+                                type="primary"
+                                icon="plus"
+                                plain
+                                @click="handleDocUpload"
+                                style="margin-top: 20rpx; width: 100%"
+                            >
+                                添加附件(图片)
+                            </u-button>
+                        </view>
+
+                        <!-- 上传提示信息 -->
+                        <view class="upload-tips">
+                            <text class="tip-item">
+                                • 支持格式:JPG、PNG等 • 单个文件不超过10MB • 最多上传15个文件
+                            </text>
+                            <text class="tip-item">• 图片文件将以图片形式展示,支持预览和下载</text>
+                            <text v-if="isWechatBrowser" class="tip-item wechat-tip">
+                                • 在微信中使用可获得更好的图片选择体验
+                            </text>
+                        </view>
+                    </view>
+                </view>
+
+                <!-- 备注信息 -->
+                <view class="form-section">
+                    <text class="section-title">备注信息</text>
+
+                    <u-form-item label="检查总结" prop="checkSummary">
+                        <u-textarea
+                            v-model="formData.checkSummary"
+                            placeholder="请输入检查总结"
+                            :maxlength="500"
+                            count
+                            :height="120"
+                            :readonly="pageType === 'view'"
+                        />
+                    </u-form-item>
+
+                    <u-form-item label="整改建议" prop="improvementSuggestions">
+                        <u-textarea
+                            v-model="formData.improvementSuggestions"
+                            placeholder="请输入整改建议"
+                            :maxlength="500"
+                            count
+                            :height="120"
+                            :readonly="pageType === 'view'"
+                        />
+                    </u-form-item>
+
+                    <u-form-item label="检查备注" prop="checkRemarks">
+                        <u-textarea
+                            v-model="formData.checkRemarks"
+                            placeholder="请输入检查备注"
+                            :maxlength="500"
+                            count
+                            :height="120"
+                            :readonly="pageType === 'view'"
+                        />
+                    </u-form-item>
+
+                    <u-form-item label="检查员" prop="checkerName" required>
+                        <u-input v-model="formData.checkerName" placeholder="检查员姓名" readonly />
+                    </u-form-item>
+                </view>
+            </u-form>
+        </view>
+
+        <!-- 底部操作按钮 -->
+        <view class="bottom-actions">
+            <u-button type="info" @click="goBack" style="margin-right: 20rpx">返回</u-button>
+            <!-- <u-button type="primary" @click="handleSubmit" :loading="submitLoading">保存</u-button> -->
+        </view>
+    </view>
+</template>
+
+<script>
+import { request, smartUploadFile, isWeChat } from '@/common/request.js';
+import { getDict, getDictLabel } from '@/common/dict.js';
+import weChatSDK from '@/utils/wechat.js';
+import { downloadFile } from '@/common/request.js';
+
+export default {
+    name: 'DormHygieneCheckAdd',
+    data() {
+        return {
+            pageLoading: false,
+            submitLoading: false,
+
+            // 页面参数
+            pageType: 'add', // add | update
+            checkId: null,
+
+            // 表单数据
+            formData: {
+                id: undefined,
+                checkTitle: '',
+                checkDate: '',
+                checkerId: undefined,
+                checkerName: '',
+                checkType: '1',
+                checkLevel: '1',
+                roomId: undefined,
+                roomCode: undefined,
+                roomName: undefined,
+                buildingId: undefined,
+                buildingName: undefined,
+                areaId: undefined,
+                areaName: undefined,
+                campusId: undefined,
+                campusName: undefined,
+                totalScore: '',
+                hygieneGrade: 'A',
+                attachmentIds: undefined,
+                checkSummary: undefined,
+                improvementSuggestions: undefined,
+                checkRemarks: undefined,
+            },
+
+            // 表单验证规则
+            rules: {
+                checkTitle: [{ required: true, message: '请输入检查标题', trigger: 'blur' }],
+                checkDate: [{ required: true, message: '请选择检查日期', trigger: 'change' }],
+                checkerName: [{ required: true, message: '请输入检查员姓名', trigger: 'blur' }],
+                campusId: [{ required: true, message: '请选择校区', trigger: 'change' }],
+                areaId: [{ required: true, message: '请选择宿舍区', trigger: 'change' }],
+                buildingId: [{ required: true, message: '请选择宿舍楼', trigger: 'change' }],
+                roomId: [{ required: true, message: '请选择房间', trigger: 'change' }],
+                checkType: [{ required: true, message: '请选择检查类型', trigger: 'change' }],
+                checkLevel: [{ required: true, message: '请选择检查级别', trigger: 'change' }],
+                hygieneGrade: [{ required: true, message: '请选择卫生等级', trigger: 'change' }],
+                totalScore: [
+                    {
+                        required: true,
+                        message: '请输入宿舍总分',
+                        trigger: 'blur',
+                        validator: (rule, value, callback) => {
+                            if (value === null || value === undefined || value === '') {
+                                callback(new Error('请输入宿舍总分'));
+                            } else {
+                                const numValue = Number(value);
+                                if (isNaN(numValue)) {
+                                    callback(new Error('宿舍总分必须是数字'));
+                                } else if (numValue < 0 || numValue > 100) {
+                                    callback(new Error('宿舍总分必须在0-100之间'));
+                                } else {
+                                    callback();
+                                }
+                            }
+                        },
+                    },
+                ],
+            },
+
+            // 时间选择器
+            showDatePicker: false,
+            checkDateValue: '',
+            checkDateDisplay: '',
+
+            // 级联选择器数据
+            campusOptions: [],
+            areaOptions: [],
+            buildingOptions: [],
+            roomOptions: [],
+
+            // 级联选择器显示状态
+            showCampusPicker: false,
+            showAreaPicker: false,
+            showBuildingPicker: false,
+            showRoomPicker: false,
+
+            // 字典选择器显示状态
+            showCheckTypePicker: false,
+            showCheckLevelPicker: false,
+            showHygieneGradePicker: false,
+
+            // 字典数据
+            xg_dorm_hygiene_check_type: [],
+            xg_dorm_hygiene_check_level: [],
+            xg_dorm_hygiene_grade: [],
+            xg_student_attendance_status: [],
+
+            // 房间学生信息
+            roomStudents: [],
+
+            // 附件数据
+            attachmentList: [], // 用于存储所有附件的原始数据
+
+            // 微信SDK相关
+            wechatSDK: weChatSDK,
+            isWechatBrowser: false,
+            wechatInitializing: false,
+            wechatImageLoading: false,
+
+            // 微信图片相关
+            selectedWechatImages: [],
+            uploadProgress: 0, // 上传进度
+        };
+    },
+
+    computed: {
+        navTitle() {
+            if (this.pageType === 'view') {
+                return '查看检查';
+            }
+            return this.pageType === 'add' ? '新增检查' : '修改检查';
+        },
+
+        // 级联选择器数据转换
+        campusColumns() {
+            return [this.campusOptions.map((item) => ({ text: item.campusName, value: item.id }))];
+        },
+
+        areaColumns() {
+            return [this.areaOptions.map((item) => ({ text: item.areaName, value: item.id }))];
+        },
+
+        buildingColumns() {
+            return [
+                this.buildingOptions.map((item) => ({ text: item.buildingName, value: item.id })),
+            ];
+        },
+
+        roomColumns() {
+            return [this.roomOptions.map((item) => ({ text: item.roomName, value: item.id }))];
+        },
+
+        // 字典选择器数据转换
+        checkTypeColumns() {
+            return [
+                this.xg_dorm_hygiene_check_type.map((item) => ({
+                    text: item.label,
+                    value: item.value,
+                })),
+            ];
+        },
+
+        // 检查类型默认索引
+        checkTypeDefaultIndex() {
+            if (!this.formData.checkType || this.xg_dorm_hygiene_check_type.length === 0) {
+                return [0];
+            }
+            const index = this.xg_dorm_hygiene_check_type.findIndex(
+                (item) => item.value === this.formData.checkType,
+            );
+            return [index >= 0 ? index : 0];
+        },
+
+        checkLevelColumns() {
+            return [
+                this.xg_dorm_hygiene_check_level.map((item) => ({
+                    text: item.label,
+                    value: item.value,
+                })),
+            ];
+        },
+
+        // 检查级别默认索引
+        checkLevelDefaultIndex() {
+            if (!this.formData.checkLevel || this.xg_dorm_hygiene_check_level.length === 0) {
+                return [0];
+            }
+            const index = this.xg_dorm_hygiene_check_level.findIndex(
+                (item) => item.value === this.formData.checkLevel,
+            );
+            return [index >= 0 ? index : 0];
+        },
+
+        hygieneGradeColumns() {
+            return [
+                this.xg_dorm_hygiene_grade.map((item) => ({ text: item.label, value: item.value })),
+            ];
+        },
+
+        // 卫生等级默认索引
+        hygieneGradeDefaultIndex() {
+            if (!this.formData.hygieneGrade || this.xg_dorm_hygiene_grade.length === 0) {
+                return [0];
+            }
+            const index = this.xg_dorm_hygiene_grade.findIndex(
+                (item) => item.value === this.formData.hygieneGrade,
+            );
+            return [index >= 0 ? index : 0];
+        },
+
+        attendanceStatusColumns() {
+            return [
+                this.xg_student_attendance_status.map((item) => ({
+                    text: item.label,
+                    value: item.value,
+                })),
+            ];
+        },
+
+        // 显示字段
+        checkTypeDisplay() {
+            const item = this.xg_dorm_hygiene_check_type.find(
+                (d) => d.value === this.formData.checkType,
+            );
+            return item ? item.label : '';
+        },
+
+        checkLevelDisplay() {
+            const item = this.xg_dorm_hygiene_check_level.find(
+                (d) => d.value === this.formData.checkLevel,
+            );
+            return item ? item.label : '';
+        },
+
+        hygieneGradeDisplay() {
+            const item = this.xg_dorm_hygiene_grade.find(
+                (d) => d.value === this.formData.hygieneGrade,
+            );
+            return item ? item.label : '';
+        },
+
+        // 图片文件(用于展示)
+        imageFiles() {
+            return this.attachmentList.filter((file) => this.isImageFile(file));
+        },
+
+        // 非图片文件(用于展示)
+        nonImageFiles() {
+            return this.attachmentList.filter((file) => !this.isImageFile(file));
+        },
+    },
+
+    async onLoad(options) {
+        console.log('页面参数:', options);
+
+        this.pageType = options.type || 'add';
+        this.checkId = options.id;
+
+        // 初始化微信环境检查并自动初始化SDK
+        await this.checkWechatEnvironment();
+
+        await this.initPage();
+    },
+    onUnload() {
+        // 清理blob URL,防止内存泄漏
+        this.cleanupBlobUrls();
+    },
+
+    methods: {
+        // === 微信SDK相关方法 ===
+
+        // 检查微信环境并自动初始化SDK
+        async checkWechatEnvironment() {
+            try {
+                // 检查是否在微信浏览器中
+                this.isWechatBrowser = this.wechatSDK.isWeChatBrowser();
+
+                if (this.isWechatBrowser) {
+                    // 在微信环境中,自动初始化SDK
+                    await this.initWechatSDK();
+                }
+            } catch (error) {
+                console.error('微信环境检查失败:', error);
+            }
+        },
+
+        // 初始化微信SDK
+        async initWechatSDK() {
+            if (this.wechatInitializing) {
+                return;
+            }
+
+            this.wechatInitializing = true;
+
+            try {
+                // 使用微信SDK工具类进行初始化
+                await this.wechatSDK.init({
+                    debug: process.env.NODE_ENV === 'development',
+                    jsApiList: ['chooseImage', 'previewImage', 'getLocation', 'openLocation'],
+                });
+
+                // 检查关键API支持情况
+                try {
+                    const apiCheckResult = await this.wechatSDK.checkJsApi([
+                        'chooseImage',
+                        'getLocation',
+                    ]);
+                } catch (apiError) {
+                    console.warn('API支持检查失败:', apiError.message);
+                }
+            } catch (error) {
+                console.error('微信SDK初始化失败:', error);
+            } finally {
+                this.wechatInitializing = false;
+            }
+        },
+
+        // 重新初始化微信SDK
+        async reinitWechatSDK() {
+            this.wechatSDK.isInitialized = false;
+            await this.initWechatSDK();
+        },
+
+        // 上传微信图片到OSS(参考stuMsgDialog.vue的实现)
+        async uploadWechatImageToOSS(localId) {
+            try {
+                this.uploadProgress = 10;
+
+                // 步骤1:上传到微信服务器(20%进度)
+                const wxUploadRes = await this.wechatSDK.uploadImage(localId);
+
+                if (!wxUploadRes.serverId) {
+                    throw new Error('微信服务器上传失败,未获取到serverId');
+                }
+
+                const mediaId = wxUploadRes.serverId;
+                this.uploadProgress = 30;
+
+                // 步骤2:保存到OSS(80%进度)
+                this.uploadProgress = 50;
+
+                const ossResponse = await request({
+                    url: '/system/wechat/downloadToOss',
+                    method: 'GET',
+                    params: {
+                        mediaId: mediaId,
+                    },
+                    timeout: 30000, // 30秒超时
+                });
+
+                if (ossResponse.code === 200) {
+                    const ossResult = ossResponse.data;
+                    this.uploadProgress = 90;
+
+                    this.uploadProgress = 100;
+                    return {
+                        ossId: ossResult.ossId,
+                        url: ossResult.url,
+                        fileName: ossResult.fileName,
+                        fileSize: ossResult.fileSize || 0,
+                    };
+                } else {
+                    throw new Error(ossResponse.msg || '保存图片到云端存储失败');
+                }
+            } catch (error) {
+                console.error('上传微信图片失败:', error);
+
+                // 上传失败时重置进度
+                this.uploadProgress = 0;
+
+                // 显示详细错误信息
+                let errorMsg = '图片上传失败,请重试';
+                if (error.message.includes('timeout')) {
+                    errorMsg = '上传超时,请检查网络连接后重试';
+                } else if (
+                    error.message.includes('mediaId') ||
+                    error.message.includes('serverId')
+                ) {
+                    errorMsg = '微信服务器上传失败,请重试';
+                } else if (error.message.includes('OSS')) {
+                    errorMsg = '保存到云端存储失败,请重试';
+                }
+
+                uni.showToast({
+                    title: errorMsg,
+                    icon: 'none',
+                    duration: 2000,
+                });
+
+                throw error;
+            }
+        },
+
+        // 初始化页面
+        async initPage() {
+            this.pageLoading = true;
+
+            try {
+                // 加载字典数据
+                await this.loadDictionaries();
+                // 加载级联选择器数据
+                await this.loadCampusOptions();
+                // 设置默认值
+                this.setDefaultValues();
+
+                // 编辑模式或查看模式加载数据
+                if ((this.pageType === 'update' || this.pageType === 'view') && this.checkId) {
+                    await this.loadCheckData();
+                }
+            } catch (error) {
+                console.error('初始化页面失败:', error);
+                uni.showToast({
+                    title: '页面初始化失败',
+                    icon: 'none',
+                });
+            } finally {
+                this.pageLoading = false;
+            }
+        },
+
+        // 加载字典数据
+        async loadDictionaries() {
+            try {
+                const dictTypes = [
+                    'xg_dorm_hygiene_check_type',
+                    'xg_dorm_hygiene_check_level',
+                    'xg_dorm_hygiene_grade',
+                    'xg_student_attendance_status',
+                ];
+
+                const results = await Promise.all(dictTypes.map((type) => getDict(type)));
+
+                this.xg_dorm_hygiene_check_type = results[0] || [];
+                this.xg_dorm_hygiene_check_level = results[1] || [];
+                this.xg_dorm_hygiene_grade = results[2] || [];
+                this.xg_student_attendance_status = results[3] || [];
+
+                console.log('字典数据加载完成');
+            } catch (error) {
+                console.error('加载字典数据失败:', error);
+            }
+        },
+
+        // 设置默认值
+        setDefaultValues() {
+            const now = new Date();
+            this.checkDateValue = now.getTime();
+            this.checkDateDisplay = this.formatDateTime(now);
+            this.formData.checkDate = this.formatDateTime(now);
+
+            // 设置默认检查标题
+            const dateStr = now.toISOString().slice(0, 10).replace(/-/g, '');
+            this.formData.checkTitle = `${dateStr}宿舍卫生检查`;
+
+            // 获取当前用户信息
+            this.getCurrentUserInfo();
+        },
+
+        // 获取当前用户信息
+        async getCurrentUserInfo() {
+            try {
+                const res = await request({
+                    url: '/system/user/getInfo',
+                    method: 'GET',
+                });
+
+                if (res && res.code === 200 && res.data && res.data.user) {
+                    const user = res.data.user;
+                    this.formData.checkerId = user.userId;
+                    this.formData.checkerName = user.nickName || user.userName;
+                }
+            } catch (error) {
+                console.warn('获取用户信息失败:', error);
+            }
+        },
+
+        // 加载检查数据(编辑模式)
+        async loadCheckData() {
+            try {
+                const res = await request({
+                    url: `/dormHygieneCheck/dormHygieneCheck/${this.checkId}`,
+                    method: 'GET',
+                });
+
+                if (res && res.code === 200 && res.data) {
+                    Object.assign(this.formData, res.data);
+
+                    // 确保totalScore为字符串类型,避免验证问题
+                    if (
+                        this.formData.totalScore !== null &&
+                        this.formData.totalScore !== undefined
+                    ) {
+                        this.formData.totalScore = String(this.formData.totalScore);
+                    }
+
+                    // 设置时间显示
+                    if (this.formData.checkDate) {
+                        const date = new Date(this.formData.checkDate);
+                        this.checkDateValue = date.getTime();
+                        this.checkDateDisplay = this.formatDateTime(date);
+                    }
+
+                    // 加载级联数据
+                    await this.loadCascadeData();
+                    // 加载房间学生数据
+                    await this.loadRoomStudents();
+                    // 加载附件数据
+                    await this.loadAttachmentData();
+                    // 为图片文件获取blob数据以确保正确显示
+                    await this.processImageFiles();
+
+                    // 强制刷新组件显示
+                    this.$nextTick(() => {
+                        // 预加载图片以确保能正确显示
+                        this.preloadImages();
+                    });
+                }
+            } catch (error) {
+                console.error('加载检查数据失败:', error);
+                uni.showToast({
+                    title: '加载数据失败',
+                    icon: 'none',
+                });
+            }
+        },
+
+        // 加载级联数据
+        async loadCascadeData() {
+            try {
+                const tasks = [];
+
+                if (this.formData.campusId) {
+                    tasks.push(this.loadAreaOptions(this.formData.campusId));
+                }
+                if (this.formData.areaId) {
+                    tasks.push(this.loadBuildingOptions(this.formData.areaId));
+                }
+                if (this.formData.buildingId) {
+                    tasks.push(this.loadRoomOptions(this.formData.buildingId));
+                }
+
+                await Promise.all(tasks);
+            } catch (error) {
+                console.error('加载级联数据失败:', error);
+            }
+        },
+
+        // 加载校区选项
+        async loadCampusOptions() {
+            try {
+                const res = await request({
+                    url: '/xqxx/dormCampus/list',
+                    method: 'GET',
+                });
+                this.campusOptions = res.rows || [];
+            } catch (error) {
+                console.error('加载校区选项失败:', error);
+            }
+        },
+
+        // 加载宿舍区选项
+        async loadAreaOptions(campusId) {
+            try {
+                const res = await request({
+                    url: '/ssqxx/dormArea/list',
+                    method: 'GET',
+                    params: { campusId },
+                });
+                this.areaOptions = res.rows || [];
+            } catch (error) {
+                console.error('加载宿舍区选项失败:', error);
+            }
+        },
+
+        // 加载宿舍楼选项
+        async loadBuildingOptions(areaId) {
+            try {
+                const res = await request({
+                    url: '/sslxx/dormBuilding/list',
+                    method: 'GET',
+                    params: { areaId },
+                });
+                this.buildingOptions = res.rows || [];
+            } catch (error) {
+                console.error('加载宿舍楼选项失败:', error);
+            }
+        },
+
+        // 加载房间选项
+        async loadRoomOptions(buildingId) {
+            try {
+                const res = await request({
+                    url: '/xgss/dormRoom/list',
+                    method: 'GET',
+                    params: { buildingId },
+                });
+                this.roomOptions = res.rows || [];
+            } catch (error) {
+                console.error('加载房间选项失败:', error);
+            }
+        },
+
+        // 加载房间学生信息
+        async loadRoomStudents() {
+            if (!this.formData.roomId) {
+                this.roomStudents = [];
+                return;
+            }
+
+            try {
+                // 如果是编辑模式或查看模式,先尝试获取历史评分数据
+                if ((this.pageType === 'update' || this.pageType === 'view') && this.formData.id) {
+                    const studentScoresRes = await request({
+                        url: `/dormHygieneStudentScore/dormHygieneStudentScore/getByCheckId/${this.formData.id}`,
+                        method: 'GET',
+                    });
+
+                    if (
+                        studentScoresRes.code === 200 &&
+                        studentScoresRes.data &&
+                        studentScoresRes.data.length > 0
+                    ) {
+                        this.roomStudents = studentScoresRes.data.map((item) => ({
+                            ...item,
+                            student_score: item.studentScore || null,
+                            attendance_status: item.attendanceStatus || '1',
+                            student_grade: item.studentGrade || 'A',
+                            showAttendancePicker: false,
+                            showGradePicker: false,
+                            bedCode: item.bedCode,
+                            bedName: item.bedCode,
+                        }));
+                        return;
+                    }
+                }
+
+                // 获取房间学生基础数据
+                const res = await request({
+                    url: '/dormBedStudent/dormBedStudent/getRoomStudents',
+                    method: 'GET',
+                    params: { roomId: this.formData.roomId },
+                });
+
+                if (res.code === 200 && res.data) {
+                    this.roomStudents = res.data.map((item) => ({
+                        ...item,
+                        student_score: null,
+                        attendance_status: '1',
+                        student_grade: 'A',
+                        showAttendancePicker: false,
+                        showGradePicker: false,
+                    }));
+                }
+            } catch (error) {
+                console.error('加载房间学生信息失败:', error);
+            }
+        },
+
+        // 加载附件数据
+        async loadAttachmentData() {
+            if (!this.formData.attachmentIds) {
+                this.attachmentList = [];
+                return;
+            }
+
+            try {
+                const ossIds = this.formData.attachmentIds.split(',').filter((id) => id.trim());
+                if (ossIds.length === 0) return;
+
+                const res = await request({
+                    url: `/resource/oss/listByIds/${ossIds.join(',')}`,
+                    method: 'GET',
+                });
+
+                if (res.code === 200 && res.data) {
+                    const attachmentFiles = res.data.map((item, index) => {
+                        // 使用fileSuffix字段判断文件类型
+                        const fileType = this.getFileTypeBySuffix(item.fileSuffix);
+                        const isImage = this.isImageFile({
+                            name: item.originalName,
+                            type: fileType,
+                        });
+
+                        // 处理图片URL - 确保有正确的API前缀
+                        let processedUrl = item.url;
+                        if (isImage && item.url && item.url.startsWith('/resource/')) {
+                            // 图片文件需要添加/api前缀
+                            processedUrl = `/api${item.url}`;
+                        }
+
+                        // 构造完整的文件名(包含扩展名)
+                        let fullFileName = item.originalName || `附件${index + 1}`;
+                        if (
+                            item.fileSuffix &&
+                            !fullFileName
+                                .toLowerCase()
+                                .endsWith(`.${item.fileSuffix.toLowerCase()}`)
+                        ) {
+                            fullFileName = `${fullFileName}.${item.fileSuffix}`;
+                        }
+
+                        const fileObj = {
+                            uid: `existing_${index}_${Date.now()}`,
+                            name: fullFileName,
+                            url: processedUrl,
+                            ossId: item.ossId,
+                            status: 'success',
+                            type: fileType,
+                            // 确保图片文件有正确的显示属性
+                            size: item.fileSize || 0,
+                            // 为uview2 upload组件添加必要的属性
+                            file: {
+                                name: fullFileName,
+                                type: fileType,
+                                size: item.fileSize || 0,
+                                path: processedUrl,
+                                url: processedUrl,
+                            },
+                        };
+
+                        return fileObj;
+                    });
+
+                    this.attachmentList = attachmentFiles;
+                }
+            } catch (error) {
+                console.error('加载附件数据失败:', error);
+            }
+        },
+
+        // 根据文件后缀获取文件类型(新增方法)
+        getFileTypeBySuffix(fileSuffix) {
+            if (!fileSuffix) return '';
+
+            // 移除点号,转换为小写
+            const ext = fileSuffix.replace('.', '').toLowerCase();
+
+            // 图片类型判断
+            const imageTypes = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'];
+            if (imageTypes.includes(ext)) {
+                // 修正MIME类型映射
+                const mimeTypeMap = {
+                    jpg: 'image/jpeg',
+                    jpeg: 'image/jpeg',
+                    png: 'image/png',
+                    gif: 'image/gif',
+                    bmp: 'image/bmp',
+                    webp: 'image/webp',
+                };
+                return mimeTypeMap[ext] || `image/${ext}`;
+            }
+
+            // 文档类型判断
+            const documentTypes = ['pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt'];
+            if (documentTypes.includes(ext)) {
+                return `file/${ext}`;
+            }
+
+            // 其他类型
+            return `file/${ext}`;
+        },
+
+        // 时间选择确认
+        handleDateConfirm(e) {
+            this.checkDateValue = e.value;
+            const date = new Date(e.value);
+            this.checkDateDisplay = this.formatDateTime(date);
+            this.formData.checkDate = this.formatDateTime(date);
+            this.showDatePicker = false;
+        },
+
+        // 校区选择确认
+        async handleCampusConfirm(e) {
+            console.log('校区选择确认:', e);
+            if (e && e.value && e.value.length > 0) {
+                const campus = this.campusOptions.find((item) => item.id === e.value[0].value);
+                if (campus) {
+                    this.formData.campusId = campus.id;
+                    this.formData.campusName = campus.campusName;
+
+                    // 清空下级选项
+                    this.clearSubOptions('campus');
+                    await this.loadAreaOptions(campus.id);
+                }
+            }
+            this.showCampusPicker = false;
+        },
+
+        // 宿舍区选择确认
+        async handleAreaConfirm(e) {
+            console.log('宿舍区选择确认:', e);
+            if (e && e.value && e.value.length > 0) {
+                const area = this.areaOptions.find((item) => item.id === e.value[0].value);
+                if (area) {
+                    this.formData.areaId = area.id;
+                    this.formData.areaName = area.areaName;
+
+                    // 清空下级选项
+                    this.clearSubOptions('area');
+                    await this.loadBuildingOptions(area.id);
+                }
+            }
+            this.showAreaPicker = false;
+        },
+
+        // 宿舍楼选择确认
+        async handleBuildingConfirm(e) {
+            console.log('宿舍楼选择确认:', e);
+            if (e && e.value && e.value.length > 0) {
+                const building = this.buildingOptions.find((item) => item.id === e.value[0].value);
+                if (building) {
+                    this.formData.buildingId = building.id;
+                    this.formData.buildingName = building.buildingName;
+
+                    // 清空下级选项
+                    this.clearSubOptions('building');
+                    await this.loadRoomOptions(building.id);
+                }
+            }
+            this.showBuildingPicker = false;
+        },
+
+        // 房间选择确认
+        async handleRoomConfirm(e) {
+            console.log('房间选择确认:', e);
+            if (e && e.value && e.value.length > 0) {
+                const room = this.roomOptions.find((item) => item.id === e.value[0].value);
+                if (room) {
+                    this.formData.roomId = room.id;
+                    this.formData.roomName = room.roomName;
+                    this.formData.roomCode = room.roomCode || room.roomName;
+
+                    // 加载房间学生信息
+                    await this.loadRoomStudents();
+                }
+            }
+            this.showRoomPicker = false;
+        },
+
+        // 清空下级选项
+        clearSubOptions(level) {
+            switch (level) {
+                case 'campus':
+                    this.formData.areaId = undefined;
+                    this.formData.areaName = undefined;
+                    this.areaOptions = [];
+                case 'area':
+                    this.formData.buildingId = undefined;
+                    this.formData.buildingName = undefined;
+                    this.buildingOptions = [];
+                case 'building':
+                    this.formData.roomId = undefined;
+                    this.formData.roomName = undefined;
+                    this.formData.roomCode = undefined;
+                    this.roomOptions = [];
+                    this.roomStudents = [];
+                    break;
+            }
+        },
+
+        // 检查类型选择确认
+        handleCheckTypeConfirm(e) {
+            console.log('检查类型选择确认:', e);
+            if (e && e.value && e.value.length > 0) {
+                this.formData.checkType = e.value[0].value;
+            }
+            this.showCheckTypePicker = false;
+        },
+
+        // 检查级别选择确认
+        handleCheckLevelConfirm(e) {
+            console.log('检查级别选择确认:', e);
+            if (e && e.value && e.value.length > 0) {
+                this.formData.checkLevel = e.value[0].value;
+            }
+            this.showCheckLevelPicker = false;
+        },
+
+        // 卫生等级选择确认
+        handleHygieneGradeConfirm(e) {
+            console.log('卫生等级选择确认:', e);
+            if (e && e.value && e.value.length > 0) {
+                this.formData.hygieneGrade = e.value[0].value;
+
+                // 自动为所有学生设置相同评级
+                if (this.roomStudents.length > 0) {
+                    this.roomStudents.forEach((student) => {
+                        student.student_grade = e.value[0].value;
+                    });
+
+                    const gradeItem = this.xg_dorm_hygiene_grade.find(
+                        (d) => d.value === e.value[0].value,
+                    );
+                    if (gradeItem) {
+                        uni.showToast({
+                            title: `已为${this.roomStudents.length}名学生设置评级:${gradeItem.label}`,
+                            icon: 'none',
+                        });
+                    }
+                }
+            }
+            this.showHygieneGradePicker = false;
+        },
+
+        // 总分变化处理
+        handleTotalScoreChange() {
+            // 确保totalScore为字符串类型,避免验证问题
+            if (this.formData.totalScore !== null && this.formData.totalScore !== undefined) {
+                this.formData.totalScore = String(this.formData.totalScore);
+            }
+
+            const score = parseFloat(this.formData.totalScore);
+
+            // 验证分数范围
+            if (!isNaN(score) && (score < 0 || score > 100)) {
+                uni.showToast({
+                    title: '宿舍总分必须在0-100分之间',
+                    icon: 'none',
+                });
+                this.formData.totalScore = '';
+                return;
+            }
+
+            if (!isNaN(score) && score >= 0 && score <= 100 && this.roomStudents.length > 0) {
+                this.roomStudents.forEach((student) => {
+                    student.student_score = score;
+                });
+
+                uni.showToast({
+                    title: `已为${this.roomStudents.length}名学生设置个人得分:${score}分`,
+                    icon: 'none',
+                });
+            }
+        },
+
+        // 学生分数变化处理
+        handleStudentScoreChange(student) {
+            const score = parseFloat(student.student_score);
+            if (!isNaN(score) && (score < 0 || score > 100)) {
+                uni.showToast({
+                    title: '个人得分必须在0-100分之间',
+                    icon: 'none',
+                });
+                student.student_score = '';
+            }
+        },
+
+        // 出勤状态选择确认
+        handleAttendanceConfirm(e, student) {
+            console.log('出勤状态选择确认:', e, student);
+            if (e && e.value && e.value.length > 0) {
+                student.attendance_status = e.value[0].value;
+            }
+            student.showAttendancePicker = false;
+        },
+
+        // 学生评级选择确认
+        handleStudentGradeConfirm(e, student) {
+            console.log('学生评级选择确认:', e, student);
+            if (e && e.value && e.value.length > 0) {
+                student.student_grade = e.value[0].value;
+            }
+            student.showGradePicker = false;
+        },
+
+        // 获取出勤状态显示文本
+        getAttendanceDisplay(value) {
+            const item = this.xg_student_attendance_status.find((d) => d.value === value);
+            return item ? item.label : '';
+        },
+
+        // 获取评级显示文本
+        getGradeDisplay(value) {
+            const item = this.xg_dorm_hygiene_grade.find((d) => d.value === value);
+            return item ? item.label : '';
+        },
+
+        // 选择图片
+        handleImageClick(image, index, event) {
+            // 检查点击目标是否是操作按钮区域
+            const target = event.target;
+            const isActionButton =
+                target.closest('.image-actions') ||
+                target.closest('u-button') ||
+                target.tagName === 'BUTTON';
+        },
+
+        // 统一附件上传方法(支持图片和文档)
+        handleDocUpload() {
+            console.log('=== 统一附件上传方法 ===');
+
+            // 检查文件数量限制
+            if (this.attachmentList.length >= 15) {
+                uni.showToast({
+                    title: '最多只能上传15个文件',
+                    icon: 'none',
+                });
+                return;
+            }
+
+            // 显示选择文件类型的操作菜单
+            uni.showActionSheet({
+                itemList: ['选择图片'],
+                success: (res) => {
+                    switch (res.tapIndex) {
+                        case 0:
+                            this.chooseDocuments();
+                            break;
+                    }
+                },
+                fail: () => {
+                    console.log('用户取消选择');
+                },
+            });
+        },
+
+        // 选择文档文件
+        chooseDocuments() {
+            // 使用uni.chooseFile选择文档
+            if (typeof uni.chooseFile === 'function') {
+                uni.chooseFile({
+                    count: Math.min(5, 15 - this.attachmentList.length),
+                    success: (res) => {
+                        console.log('选择文档成功:', res);
+                        if (res.tempFiles && res.tempFiles.length > 0) {
+                            this.handleFileUpload({
+                                tempFiles: res.tempFiles,
+                            });
+                        }
+                    },
+                    fail: (err) => {
+                        console.error('选择文档失败:', err);
+                        uni.showToast({
+                            title: '选择文档失败',
+                            icon: 'none',
+                        });
+                    },
+                });
+            } else {
+                // 降级方案:跳转到备用上传方式
+                this.handleBackupUpload();
+            }
+        },
+
+        // 备用上传方法(用户可见)
+        handleBackupUpload() {
+            console.log('=== 备用上传方法 ===');
+
+            // 先检查平台支持情况
+            uni.showActionSheet({
+                itemList: ['选择图片', '选择视频', '选择文档'],
+                success: (res) => {
+                    if (res.tapIndex === 0) {
+                        // 选择图片
+                        uni.chooseImage({
+                            count: 5,
+                            sizeType: ['original', 'compressed'],
+                            sourceType: ['album', 'camera'],
+                            success: (imageRes) => {
+                                console.log('选择图片成功 - 完整响应:', imageRes);
+                                console.log('tempFilePaths:', imageRes.tempFilePaths);
+                                console.log('tempFiles:', imageRes.tempFiles);
+
+                                const files = imageRes.tempFilePaths.map((path, index) => {
+                                    const fileName =
+                                        path.split('/').pop() || `image_${Date.now()}_${index}.jpg`;
+                                    const tempFile = imageRes.tempFiles?.[index];
+                                    const fileObj = {
+                                        name: fileName,
+                                        path: path,
+                                        url: path,
+                                        tempFilePath: path,
+                                        size: tempFile?.size || 0,
+                                        type: tempFile?.type || 'image/jpeg',
+                                    };
+                                    console.log(`创建图片文件对象 ${index}:`, fileObj);
+                                    console.log(`对应的tempFile:`, tempFile);
+                                    return fileObj;
+                                });
+
+                                // 检查文件大小
+                                const validFiles = files.filter((file) => {
+                                    if (!this.checkFileSize(file)) {
+                                        return false;
+                                    }
+                                    return true;
+                                });
+
+                                if (validFiles.length > 0) {
+                                    this.handleFileUpload({ tempFiles: validFiles });
+                                } else {
+                                    console.log('所有文件都超过大小限制,取消上传');
+                                }
+                            },
+                            fail: (err) => {
+                                console.error('选择图片失败:', err);
+                                uni.showToast({
+                                    title: '选择图片失败',
+                                    icon: 'none',
+                                });
+                            },
+                        });
+                    } else if (res.tapIndex === 1) {
+                        // 选择视频
+                        uni.chooseVideo({
+                            sourceType: ['album', 'camera'],
+                            maxDuration: 60,
+                            success: (videoRes) => {
+                                console.log('选择视频成功:', videoRes);
+                                const file = {
+                                    name: `video_${Date.now()}.mp4`,
+                                    path: videoRes.tempFilePath,
+                                    url: videoRes.tempFilePath,
+                                    tempFilePath: videoRes.tempFilePath,
+                                    size: videoRes.size || 0,
+                                    type: 'video/mp4',
+                                };
+
+                                // 检查文件大小
+                                if (this.checkFileSize(file)) {
+                                    this.handleFileUpload({ tempFiles: [file] });
+                                }
+                            },
+                            fail: (err) => {
+                                console.error('选择视频失败:', err);
+                                uni.showToast({
+                                    title: '选择视频失败',
+                                    icon: 'none',
+                                });
+                            },
+                        });
+                    } else if (res.tapIndex === 2) {
+                        // 选择文档
+                        this.handleDocUpload();
+                    }
+                },
+            });
+        },
+
+        // 文件上传
+        handleFileUpload(event) {
+            console.log('文件上传事件触发:', event);
+
+            // 显示用户提示
+            uni.showToast({
+                title: '文件选择成功,开始上传...',
+                icon: 'loading',
+                duration: 2000,
+            });
+
+            // 兼容不同的事件格式
+            let files = [];
+
+            // uview2 upload组件的after-read事件格式
+            if (event.file) {
+                files = Array.isArray(event.file) ? event.file : [event.file];
+                console.log('✅ uview2 upload格式解析结果:', files);
+            }
+            // 直接传递的tempFiles格式(文档上传等)
+            else if (event.tempFiles) {
+                files = event.tempFiles;
+                console.log('✅ tempFiles格式解析结果:', files);
+            }
+            // tempFilePaths格式(兼容旧版本)
+            else if (event.tempFilePaths) {
+                files = event.tempFilePaths.map((path, index) => ({
+                    url: path,
+                    path: path,
+                    tempFilePath: path,
+                    name: `文件${index + 1}`,
+                    type: '',
+                }));
+                console.log('✅ tempFilePaths格式解析结果:', files);
+            }
+            // 单文件格式处理
+            else if (event.url || event.path || event.tempFilePath) {
+                files = [event];
+                console.log('✅ 单文件格式解析结果:', files);
+            }
+
+            console.log('📋 最终解析得到的文件列表:', files);
+
+            if (files.length === 0) {
+                console.error('❌ 没有获取到文件数据');
+                console.error('可能的原因:');
+                console.error('1. u-upload组件事件参数结构发生变化');
+                console.error('2. 选择文件时发生错误');
+                console.error('3. 事件触发异常');
+
+                uni.showToast({
+                    title: '未获取到文件,请重试',
+                    icon: 'none',
+                });
+                return;
+            }
+
+            // 检查文件数量限制
+            if (this.attachmentList.length + files.length > 15) {
+                console.warn('⚠️ 文件数量超过限制');
+                uni.showToast({
+                    title: '最多只能上传15个文件',
+                    icon: 'none',
+                });
+                return;
+            }
+
+            // 检查文件大小限制
+            const validFiles = files.filter((file) => {
+                const isValid = this.checkFileSize(file);
+                console.log(
+                    `文件大小检查 - ${file.name || '未知文件'}:`,
+                    isValid ? '✅ 通过' : '❌ 超限',
+                );
+                return isValid;
+            });
+
+            if (validFiles.length === 0) {
+                console.log('❌ 所有文件都超过大小限制,取消上传');
+                return;
+            }
+
+            if (validFiles.length < files.length) {
+                const filteredCount = files.length - validFiles.length;
+                console.log(`⚠️ 已过滤 ${filteredCount} 个超限文件`);
+                uni.showToast({
+                    title: `已过滤 ${filteredCount} 个超限文件`,
+                    icon: 'none',
+                    duration: 2000,
+                });
+            }
+
+            // 处理有效文件
+            const newFiles = validFiles.map((file, index) => {
+                console.log(`🔍 处理文件 ${index + 1}:`, file);
+                console.log(`🔍 文件对象属性:`, Object.keys(file));
+
+                // uview2 upload组件返回的文件通常有url属性作为临时路径
+                const filePath = file.url || file.tempFilePath || file.path;
+                console.log(`📂 文件路径:`, filePath);
+
+                if (!filePath) {
+                    console.error(`❌ 文件 ${index + 1} 缺少有效路径`);
+                }
+
+                const fileName =
+                    file.name || filePath?.split('/').pop() || `图片${Date.now()}_${index}.jpg`;
+                console.log(`🏷️ 文件名:`, fileName);
+
+                const processedFile = {
+                    ...file,
+                    uid: `upload_${Date.now()}_${index}`,
+                    name: fileName,
+                    url: filePath,
+                    path: filePath, // 确保path属性存在
+                    tempFilePath: filePath, // 确保tempFilePath属性存在
+                    status: 'uploading',
+                    ossId: null,
+                    type: file.type || this.getFileTypeByName(fileName),
+                };
+
+                console.log(`✅ 文件 ${index + 1} 处理完成:`, processedFile);
+                return processedFile;
+            });
+
+            console.log('📊 处理后的新文件数量:', newFiles.length);
+            console.log('📊 处理后的新文件列表:', newFiles);
+
+            // 添加到附件列表
+            console.log('📋 当前attachmentList长度:', this.attachmentList.length);
+            this.attachmentList.push(...newFiles);
+            console.log('📋 添加后attachmentList长度:', this.attachmentList.length);
+
+            // 显示上传提示
+            uni.showToast({
+                title: `开始上传 ${newFiles.length} 个文件`,
+                icon: 'loading',
+                duration: 1500,
+            });
+
+            // 🚀 关键步骤:上传文件到服务器
+            console.log('🚀 开始逐个上传文件到服务器...');
+            newFiles.forEach((file, index) => {
+                console.log(`🚀 准备上传第 ${index + 1} 个文件: ${file.name}`);
+                console.log(`🚀 文件路径: ${file.path || file.url}`);
+
+                // 立即调用上传方法
+                this.uploadFileToServer(file)
+                    .then(() => {
+                        console.log(`✅ 文件 ${file.name} 上传完成`);
+                    })
+                    .catch((error) => {
+                        console.error(`❌ 文件 ${file.name} 上传失败:`, error);
+                    });
+            });
+        },
+
+        // 检查文件大小是否超过限制
+        checkFileSize(file) {
+            const maxSize = 10 * 1024 * 1024; // 10MB
+            const fileSize = file.size || 0;
+
+            console.log('=== 检查文件大小 ===');
+            console.log('文件大小:', fileSize, '字节');
+            console.log('最大限制:', maxSize, '字节');
+            console.log('是否超过限制:', fileSize > maxSize);
+
+            if (fileSize > maxSize) {
+                const fileSizeMB = (fileSize / (1024 * 1024)).toFixed(2);
+                uni.showToast({
+                    title: `文件大小 ${fileSizeMB}MB,超过10MB限制`,
+                    icon: 'none',
+                    duration: 3000,
+                });
+                return false;
+            }
+            return true;
+        },
+
+        // 上传文件到服务器
+        async uploadFileToServer(file) {
+            try {
+                console.log('🚀 === 开始上传文件到服务器 ===');
+                console.log('📁 待上传文件对象:', file);
+                console.log('📁 文件对象属性:', Object.keys(file));
+
+                // 更新文件状态
+                file.status = 'uploading';
+
+                // 确定正确的文件路径 - uview2通常使用url属性
+                const filePath = file.url || file.tempFilePath || file.path;
+                console.log('🎯 文件路径优先级选择:', {
+                    url: file.url,
+                    tempFilePath: file.tempFilePath,
+                    path: file.path,
+                    selected: filePath,
+                });
+
+                if (!filePath) {
+                    const error = new Error('文件路径不存在');
+                    console.error('❌ 上传失败 - 文件路径为空:', file);
+                    file.status = 'error';
+                    throw error;
+                }
+
+                // 验证文件路径格式
+                console.log('🔍 验证文件路径格式:', filePath);
+                if (
+                    !filePath.startsWith('http') &&
+                    !filePath.startsWith('/') &&
+                    !filePath.startsWith('wxfile://') &&
+                    !filePath.startsWith('file://') &&
+                    !filePath.startsWith('blob:')
+                ) {
+                    console.warn('⚠️ 文件路径格式可能不正确:', filePath);
+                } else {
+                    console.log('✅ 文件路径格式验证通过');
+                }
+
+                // 显示上传进度
+                uni.showLoading({
+                    title: `上传${file.name}...`,
+                    mask: true,
+                });
+                console.log(`💫 开始上传文件: ${file.name}`);
+
+                // 调用智能上传API(自动适配微信环境)
+                console.log('📡 调用智能上传API...');
+                console.log('📡 API参数:', {
+                    url: '/resource/oss/upload',
+                    file: file,
+                    formData: { bizType: 'dorm_hygiene_check_attachment' },
+                    环境检测: {
+                        isWeChat: isWeChat(),
+                        hasBlob: !!file._blob,
+                        isBlobUrl: filePath.startsWith('blob:'),
+                    },
+                });
+
+                // 🚀 使用智能上传方法,自动处理微信环境兼容性问题
+                const response = await smartUploadFile('/resource/oss/upload', file, {
+                    bizType: 'dorm_hygiene_check_attachment',
+                });
+
+                console.log('📡 上传API响应:', response);
+                uni.hideLoading();
+
+                if (response && response.code === 200) {
+                    // 上传成功
+                    file.url = response.data.url;
+                    file.ossId = response.data.ossId;
+                    file.status = 'success';
+
+                    console.log('✅ 文件上传成功:', {
+                        fileName: file.name,
+                        ossId: file.ossId,
+                        url: file.url,
+                    });
+
+                    uni.showToast({
+                        title: '上传成功',
+                        icon: 'success',
+                        duration: 1500,
+                    });
+
+                    return response;
+                } else {
+                    // 上传失败
+                    file.status = 'error';
+                    const errorMsg = response?.msg || '上传失败';
+                    console.error('❌ 上传失败 - API返回错误:', {
+                        response: response,
+                        fileName: file.name,
+                        errorMsg: errorMsg,
+                    });
+
+                    uni.showToast({
+                        title: errorMsg,
+                        icon: 'none',
+                        duration: 3000,
+                    });
+
+                    throw new Error(errorMsg);
+                }
+            } catch (error) {
+                console.error('❌ uploadFileToServer执行失败:', error);
+                console.error('❌ 错误详情:', {
+                    fileName: file.name,
+                    filePath: file.url || file.tempFilePath || file.path,
+                    errorMessage: error.message,
+                    errorStack: error.stack,
+                });
+
+                uni.hideLoading();
+                file.status = 'error';
+
+                // 更详细的错误提示
+                let errorMessage = '上传失败';
+                if (error.message) {
+                    if (error.message.includes('file is not present')) {
+                        errorMessage = '文件格式不支持或文件损坏';
+                    } else if (error.message.includes('timeout')) {
+                        errorMessage = '上传超时,请检查网络连接';
+                    } else if (error.message.includes('网络')) {
+                        errorMessage = '网络连接失败,请检查网络';
+                    } else if (error.message.includes('文件路径')) {
+                        errorMessage = '文件选择异常,请重新选择';
+                    } else {
+                        errorMessage = error.message;
+                    }
+                }
+
+                console.error('❌ 最终错误消息:', errorMessage);
+
+                uni.showModal({
+                    title: '上传失败',
+                    content: `文件"${file.name}"上传失败:${errorMessage}`,
+                    showCancel: true,
+                    cancelText: '取消',
+                    confirmText: '重试',
+                    success: (res) => {
+                        if (res.confirm) {
+                            console.log('🔄 用户选择重试上传');
+                            // 重置状态并重试
+                            file.status = 'pending';
+                            this.uploadFileToServer(file);
+                        } else {
+                            console.log('🚫 用户取消重试');
+                            // 从列表中移除失败的文件
+                            const index = this.attachmentList.findIndex((f) => f.uid === file.uid);
+                            if (index > -1) {
+                                this.attachmentList.splice(index, 1);
+                                console.log('🗑️ 已从附件列表中移除失败文件');
+                            }
+                        }
+                    },
+                });
+
+                throw error;
+            }
+        },
+
+        // 图片预览
+        handleImagePreview(image, index) {
+            if (image.status !== 'success') {
+                uni.showToast({
+                    title: '图片尚未上传完成',
+                    icon: 'none',
+                });
+                return;
+            }
+
+            // 获取所有成功上传的图片URL
+            const imageUrls = this.imageFiles
+                .filter((file) => file.status === 'success')
+                .map((file) => file.blobUrl || file.url);
+
+            if (imageUrls.length === 0) {
+                uni.showToast({
+                    title: '暂无可预览的图片',
+                    icon: 'none',
+                });
+                return;
+            }
+
+            // 找到当前图片在成功列表中的索引
+            const currentUrl = image.blobUrl || image.url;
+            const currentIndex = imageUrls.findIndex((url) => url === currentUrl);
+
+            uni.previewImage({
+                urls: imageUrls,
+                current: currentIndex >= 0 ? currentIndex : 0,
+                success: () => {
+                    // 预览成功
+                },
+                fail: (error) => {
+                    console.error('图片预览失败:', error);
+                    uni.showToast({
+                        title: '预览失败',
+                        icon: 'none',
+                    });
+                },
+            });
+        },
+
+        // 图片下载(带重试机制)
+        async handleImageDownload(image, event, retryCount = 0) {
+            // 事件阻止已由handleImageDownloadClick方法处理
+
+            if (image.status !== 'success') {
+                uni.showToast({
+                    title: '图片尚未上传完成',
+                    icon: 'none',
+                });
+                return;
+            }
+
+            // 显示下载进度提示
+            uni.showLoading({
+                title: '正在下载图片...',
+                mask: true,
+            });
+
+            try {
+                // 如果有ossId,通过API下载
+                if (image.ossId) {
+                    const downloadUrl = `/resource/oss/download/${image.ossId}`;
+
+                    // 调用下载接口并等待完成
+                    const response = await downloadFile(downloadUrl, image.name);
+
+                    if (response.statusCode === 200) {
+                        uni.hideLoading();
+                        uni.saveFile({
+                            tempFilePath: response.tempFilePath,
+                            success: function (res) {
+                                uni.showToast({
+                                    title: '下载成功',
+                                    icon: 'success',
+                                });
+                            },
+                            fail: function () {
+                                uni.showToast({
+                                    title: '保存失败',
+                                    icon: 'none',
+                                });
+                            },
+                        });
+                    }
+                }
+            } catch (error) {
+                console.error('图片下载过程出错:', error);
+
+                // 确保隐藏loading状态
+                uni.hideLoading();
+
+                // 重试机制(最多重试2次)
+                if (retryCount < 2) {
+                    // 显示重试提示
+                    uni.showToast({
+                        title: `下载失败,正在重试(${retryCount + 1}/2)...`,
+                        icon: 'none',
+                        duration: 1500,
+                    });
+
+                    setTimeout(() => {
+                        this.handleImageDownload(image, event, retryCount + 1);
+                    }, 1500); // 延迟1.5秒后重试
+
+                    return;
+                }
+
+                // 超过重试次数,显示最终错误信息
+                const errorMsg = error.message?.includes('网络')
+                    ? '网络连接失败,请检查网络后重试'
+                    : error.message?.includes('timeout')
+                    ? '下载超时,请重试'
+                    : '下载失败,已重试2次,请检查网络或稍后重试';
+
+                uni.showToast({
+                    title: errorMsg,
+                    icon: 'none',
+                    duration: 3000,
+                });
+            }
+        },
+
+        // 图片点击处理(智能判断是预览还是操作按钮)
+        handleImageClick(image, index, event) {
+            // 检查点击目标是否是操作按钮区域
+            const target = event.target;
+            const isActionButton =
+                target.closest('.image-actions') ||
+                target.closest('u-button') ||
+                target.tagName === 'BUTTON';
+        },
+
+        // 删除按钮点击处理(更强的事件处理)
+        handleImageDeleteClick(image, index, event) {
+            console.log('删除按钮被点击:', image, index);
+
+            // 强制阻止事件冒泡和默认行为
+            if (event) {
+                event.stopPropagation();
+                event.preventDefault();
+                event.stopImmediatePropagation();
+            }
+
+            // 调用实际的删除方法
+            this.handleImageDelete(image, index);
+        },
+
+        // 图片下载按钮点击处理(更强的事件处理)
+        handleImageDownloadClick(image, event) {
+            // 强制阻止事件冒泡和默认行为
+            if (event) {
+                event.stopPropagation();
+                event.preventDefault();
+                event.stopImmediatePropagation();
+            }
+
+            // 调用实际的下载方法
+            this.handleImageDownload(image, event);
+        },
+
+        // 图片删除
+        handleImageDelete(image, index, event) {
+            // 强制阻止事件冒泡和默认行为
+            if (event) {
+                event.stopPropagation();
+                event.preventDefault();
+            }
+
+            uni.showModal({
+                title: '确认删除',
+                content: '确定要删除这张图片吗?删除后无法恢复。',
+                confirmColor: '#ff5722',
+                success: (res) => {
+                    if (res.confirm) {
+                        // 从附件列表中删除
+                        const attachmentIndex = this.attachmentList.findIndex(
+                            (file) =>
+                                file.uid === image.uid ||
+                                (file.ossId && file.ossId === image.ossId) ||
+                                (file.url && file.url === image.url),
+                        );
+
+                        if (attachmentIndex >= 0) {
+                            this.attachmentList.splice(attachmentIndex, 1);
+                        }
+
+                        // 清理blob URL,防止内存泄漏
+                        if (image.blobUrl && image.blobUrl.startsWith('blob:')) {
+                            URL.revokeObjectURL(image.blobUrl);
+                        }
+
+                        uni.showToast({
+                            title: '删除成功',
+                            icon: 'success',
+                        });
+                    }
+                },
+                fail: (err) => {
+                    console.error('删除确认对话框显示失败:', err);
+                },
+            });
+        },
+
+        // 文件下载(微信小程序专用版本)
+        async handleDownloadFile(file, event) {
+            // 事件阻止已由handleDownloadFileClick方法处理
+
+            if (!file.ossId) {
+                uni.showToast({
+                    title: '文件未上传完成',
+                    icon: 'none',
+                });
+                return;
+            }
+
+            try {
+                uni.showLoading({
+                    title: `正在下载${file.name}...`,
+                    mask: true,
+                });
+
+                // 构建下载URL
+                const downloadUrl = `/resource/oss/download/${file.ossId}`;
+
+                if (this.isImageFile(file)) {
+                    // 图片文件:下载并保存到相册
+                    await this.downloadAndSaveImage(downloadUrl, file.name);
+                } else {
+                    // 非图片文件:下载并直接打开预览
+                    await this.downloadAndOpenDocument(downloadUrl, file.name);
+                }
+            } catch (error) {
+                console.error('下载过程发生异常:', error);
+                uni.hideLoading();
+
+                let errorMsg = '下载失败,请重试';
+                if (error.message.includes('timeout')) {
+                    errorMsg = '下载超时,请检查网络后重试';
+                } else if (error.message.includes('network')) {
+                    errorMsg = '网络错误,请检查网络连接';
+                } else if (error.message.includes('404')) {
+                    errorMsg = '文件不存在,请联系管理员';
+                } else if (error.message.includes('500')) {
+                    errorMsg = '服务器错误,请稍后重试';
+                }
+
+                uni.showModal({
+                    title: '下载失败',
+                    content: errorMsg,
+                    showCancel: true,
+                    cancelText: '取消',
+                    confirmText: '重试',
+                    success: (res) => {
+                        if (res.confirm) {
+                            this.handleDownloadFile(file);
+                        }
+                    },
+                });
+            }
+        },
+
+        // 下载图片并保存到相册
+        async downloadAndSaveImage(downloadUrl, fileName) {
+            return new Promise(async (resolve, reject) => {
+                // 调用下载接口并等待完成
+                const response = await downloadFile(downloadUrl, fileName);
+
+                if (response.statusCode === 200) {
+                    uni.hideLoading();
+                    uni.saveFile({
+                        tempFilePath: response.tempFilePath,
+                        success: function (res) {
+                            uni.showToast({
+                                title: '下载成功',
+                                icon: 'success',
+                            });
+                        },
+                        fail: function () {
+                            uni.showToast({
+                                title: '保存失败',
+                                icon: 'none',
+                            });
+                        },
+                    });
+                }
+                uni.hideLoading();
+                resolve();
+                // #endif
+            });
+        },
+
+        // 下载文档并打开预览
+        async downloadAndOpenDocument(downloadUrl, fileName) {
+            return new Promise(async (resolve, reject) => {
+                // 调用下载接口并等待完成
+                const response = await downloadFile(downloadUrl, fileName);
+
+                if (response.statusCode === 200) {
+                    uni.hideLoading();
+                    uni.saveFile({
+                        tempFilePath: response.tempFilePath,
+                        success: function (res) {
+                            uni.showToast({
+                                title: '下载成功',
+                                icon: 'success',
+                            });
+                        },
+                        fail: function () {
+                            uni.showToast({
+                                title: '保存失败',
+                                icon: 'none',
+                            });
+                        },
+                    });
+                }
+                uni.hideLoading();
+                resolve();
+                // #endif
+            });
+        },
+
+        // 文件下载按钮点击处理(更强的事件处理)
+        handleDownloadFileClick(file, event) {
+            // 强制阻止事件冒泡和默认行为
+            if (event) {
+                event.stopPropagation();
+                event.preventDefault();
+                event.stopImmediatePropagation();
+            }
+
+            // 调用实际的下载方法
+            this.handleDownloadFile(file, event);
+        },
+
+        // 删除文档
+        handleRemoveFile(file, index, event) {
+            event.stopPropagation();
+            uni.showModal({
+                title: '确认删除',
+                content: '确定要删除这个文件吗?',
+                success: (res) => {
+                    if (res.confirm) {
+                        const fileIndex = this.attachmentList.findIndex((f) => f.uid === file.uid);
+                        if (fileIndex > -1) {
+                            this.attachmentList.splice(fileIndex, 1);
+                            uni.showToast({
+                                title: '文件删除成功',
+                                icon: 'success',
+                            });
+                        }
+                    }
+                },
+            });
+        },
+
+        // 重试上传
+        async retryUploadFile(file, event) {
+            console.log('=== 重试上传文件 ===', file);
+
+            // 强制阻止事件冒泡和默认行为
+            if (event) {
+                event.stopPropagation();
+                event.preventDefault();
+            }
+
+            // 重置文件状态
+            file.status = 'uploading';
+            file.progress = 0;
+
+            try {
+                // 根据文件来源选择不同的上传方式
+                if (file.source === 'wechat' && file.localId) {
+                    // 微信图片重新上传
+                    const uploadResult = await this.uploadWechatImageToOSS(file.localId);
+
+                    // 更新文件信息
+                    file.status = 'success';
+                    file.ossId = uploadResult.ossId;
+                    file.url = uploadResult.url;
+                    file.name = uploadResult.fileName || file.name;
+                    file.size = uploadResult.fileSize || 0;
+                    file.progress = 100;
+                } else {
+                    // 普通文件重新上传
+                    await this.uploadFileToServer(file);
+                }
+
+                uni.showToast({
+                    title: '重新上传成功',
+                    icon: 'success',
+                    duration: 1500,
+                });
+            } catch (error) {
+                console.error('重试上传失败:', error);
+                file.status = 'error';
+                file.progress = 0;
+
+                uni.showToast({
+                    title: '重试失败,请稍后再试',
+                    icon: 'none',
+                    duration: 2000,
+                });
+            }
+        },
+
+        // 格式化日期时间
+        formatDateTime(date) {
+            const year = date.getFullYear();
+            const month = String(date.getMonth() + 1).padStart(2, '0');
+            const day = String(date.getDate()).padStart(2, '0');
+            const hours = String(date.getHours()).padStart(2, '0');
+            const minutes = String(date.getMinutes()).padStart(2, '0');
+            const seconds = String(date.getSeconds()).padStart(2, '0');
+            return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
+        },
+
+        // 表单提交
+        async handleSubmit() {
+            try {
+                // 表单验证
+                const valid = await this.$refs.formRef.validate();
+                if (!valid) return;
+
+                this.submitLoading = true;
+
+                // 处理附件ID
+                const allAttachments = this.attachmentList.filter(
+                    (item) => item.status === 'success' && item.ossId,
+                );
+                this.formData.attachmentIds = allAttachments.map((item) => item.ossId).join(',');
+
+                // 处理学生评分数据
+                const studentScores = this.roomStudents.map((student) => ({
+                    id: student.id, // 编辑时包含ID
+                    studentId: student.studentId,
+                    studentName: student.studentName,
+                    studentNo: student.studentNo,
+                    className: student.className,
+                    majorName: student.majorName,
+                    collegeName: student.collegeName,
+                    bedId: student.bedId,
+                    bedCode: student.bedCode,
+                    bedName: student.bedName,
+                    studentScore: student.student_score ? Number(student.student_score) : undefined,
+                    attendanceStatus: student.attendance_status,
+                    studentGrade: student.student_grade,
+                    isResponsiblePerson: student.isResponsiblePerson
+                        ? Number(student.isResponsiblePerson)
+                        : 0,
+                    scoreRemarks: student.scoreRemarks || '',
+                    improvementNotes: student.improvementNotes || '',
+                }));
+
+                // 构建提交数据
+                const submitData = {
+                    ...this.formData,
+                    // 确保totalScore为数字类型
+                    totalScore: this.formData.totalScore
+                        ? Number(this.formData.totalScore)
+                        : undefined,
+                    studentScores: studentScores,
+                };
+
+                console.log('提交数据:', submitData);
+
+                // 调用API
+                const url =
+                    this.pageType === 'add'
+                        ? '/dormHygieneCheck/dormHygieneCheck/addWithStudentScores'
+                        : `/dormHygieneCheck/dormHygieneCheck/updateWithStudentScores`;
+
+                const res = await request({
+                    url: url,
+                    method: this.pageType === 'add' ? 'POST' : 'PUT',
+                    data: submitData,
+                });
+
+                if (res && res.code === 200) {
+                    uni.showToast({
+                        title: '保存成功',
+                        icon: 'success',
+                    });
+
+                    // 发送刷新事件
+                    uni.$emit('refreshCheckList');
+
+                    // 返回上一页
+                    setTimeout(() => {
+                        uni.navigateBack();
+                    }, 1500);
+                } else {
+                    throw new Error(res?.msg || '保存失败');
+                }
+            } catch (error) {
+                console.error('提交失败:', error);
+                uni.showToast({
+                    title: error.message || '保存失败',
+                    icon: 'none',
+                });
+            } finally {
+                this.submitLoading = false;
+            }
+        },
+
+        // 返回上一页
+        goBack() {
+            uni.navigateBack();
+        },
+
+        // 获取文件名短格式
+        getShortFileName(fileName) {
+            if (!fileName) return '';
+
+            const lastDotIndex = fileName.lastIndexOf('.');
+            if (lastDotIndex === -1) {
+                // 没有后缀的文件名
+                return fileName.length > 12 ? fileName.substring(0, 12) + '...' : fileName;
+            }
+
+            const name = fileName.substring(0, lastDotIndex);
+            const ext = fileName.substring(lastDotIndex); // 包含点号的后缀
+
+            if (name.length <= 8) {
+                return fileName; // 文件名较短,直接返回
+            }
+
+            // 文件名较长,缩写中间部分,保留后缀
+            return name.substring(0, 8) + '...' + ext;
+        },
+
+        // 判断是否为图片文件
+        isImageFile(file) {
+            const imageTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/bmp', 'image/webp'];
+
+            // 优先使用文件MIME类型判断
+            if (file.type) {
+                return imageTypes.includes(file.type);
+            }
+
+            // 通过文件名判断
+            const fileName = file.name || file.url || '';
+            return /\.(jpg|jpeg|png|gif|bmp|webp)$/i.test(fileName);
+        },
+
+        // 根据文件名获取文件类型
+        getFileTypeByName(fileName) {
+            if (!fileName) return '';
+            const ext = fileName.split('.').pop()?.toLowerCase();
+            const imageTypes = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'];
+            if (imageTypes.includes(ext)) {
+                // 修正MIME类型映射
+                const mimeTypeMap = {
+                    jpg: 'image/jpeg',
+                    jpeg: 'image/jpeg',
+                    png: 'image/png',
+                    gif: 'image/gif',
+                    bmp: 'image/bmp',
+                    webp: 'image/webp',
+                };
+                return mimeTypeMap[ext] || `image/${ext}`;
+            }
+            return `file/${ext}`;
+        },
+
+        // 预加载图片以确保能正确显示
+        async preloadImages() {
+            console.log('=== 预加载图片 ===');
+            const imageFiles = this.attachmentList.filter((file) => this.isImageFile(file));
+
+            for (const file of imageFiles) {
+                if (file.url) {
+                    try {
+                        console.log(`预加载图片: ${file.name} - ${file.url}`);
+                        // 创建一个Image对象来预加载图片
+                        const img = new Image();
+                        img.onload = () => {
+                            console.log(`图片预加载成功: ${file.name}`);
+                        };
+                        img.onerror = () => {
+                            console.error(`图片预加载失败: ${file.name} - ${file.url}`);
+                        };
+                        img.src = file.url;
+                    } catch (error) {
+                        console.error(`预加载图片出错: ${file.name}`, error);
+                    }
+                }
+            }
+        },
+
+        // 获取图片的blob数据(用于uview2 upload组件显示)
+        async getImageBlobUrl(imageUrl) {
+            try {
+                console.log(`获取图片blob数据: ${imageUrl}`);
+
+                // 处理图片URL路径
+                let apiUrl = imageUrl;
+                if (imageUrl.startsWith('/api/')) {
+                    // 移除/api前缀,因为request会自动添加baseURL
+                    apiUrl = imageUrl.replace('/api', '');
+                } else if (imageUrl.startsWith('/resource/')) {
+                    // 直接使用相对路径
+                    apiUrl = imageUrl;
+                } else if (imageUrl.startsWith('http')) {
+                    // 完整URL,需要特殊处理
+                    console.log('检测到完整URL,直接返回原URL');
+                    return imageUrl;
+                }
+
+                console.log(`API请求URL: ${apiUrl}`);
+
+                // 使用request方法获取图片数据
+                const response = await request({
+                    url: apiUrl,
+                    method: 'GET',
+                    responseType: 'arraybuffer', // 设置响应类型为arraybuffer
+                    header: {
+                        isToken: true, // 图片请求可能不需要token验证
+                    },
+                });
+
+                // 将arraybuffer转换为blob
+                const blob = new Blob([response], { type: 'image/*' });
+                const blobUrl = URL.createObjectURL(blob);
+
+                console.log(`成功创建blob URL: ${blobUrl}`);
+                return blobUrl;
+            } catch (error) {
+                console.error(`获取图片blob数据失败: ${imageUrl}`, error);
+                // 如果请求失败,返回原始URL作为备用方案
+                return imageUrl;
+            }
+        },
+
+        // 处理图片文件,获取blob数据以确保正确显示
+        async processImageFiles() {
+            console.log('=== 处理图片文件 ===');
+            const imageFiles = this.attachmentList.filter((file) => this.isImageFile(file));
+
+            for (const file of imageFiles) {
+                if (file.url && !file.blobUrl) {
+                    try {
+                        console.log(`处理图片文件: ${file.name}`);
+                        const blobUrl = await this.getImageBlobUrl(file.url);
+                        if (blobUrl) {
+                            // 更新文件对象,添加blob URL,并标记为图片
+                            file.blobUrl = blobUrl;
+                            file.url = blobUrl; // 使用blob URL作为显示URL
+                            file.fileType = 'image';
+                            file.type =
+                                file.type && file.type.startsWith('image') ? file.type : 'image';
+                            file.isImage = true;
+                            console.log(`图片文件处理成功: ${file.name} - ${blobUrl}`);
+                        }
+                    } catch (error) {
+                        console.error(`处理图片文件失败: ${file.name}`, error);
+                    }
+                }
+            }
+        },
+
+        // 清理blob URL,防止内存泄漏
+        cleanupBlobUrls() {
+            console.log('=== 清理blob URL ===');
+            this.attachmentList.forEach((file) => {
+                if (file.blobUrl && file.blobUrl.startsWith('blob:')) {
+                    try {
+                        URL.revokeObjectURL(file.blobUrl);
+                        console.log(`已清理blob URL: ${file.name}`);
+                    } catch (error) {
+                        console.error(`清理blob URL失败: ${file.name}`, error);
+                    }
+                }
+            });
+        },
+    },
+};
+</script>
+
+<style lang="scss" scoped>
+.page-container {
+    min-height: 100vh;
+    background-color: #f5f6fa;
+    padding-bottom: 120rpx;
+}
+
+.form-container {
+    padding: 20rpx;
+}
+
+.form-section {
+    background-color: #ffffff;
+    border-radius: 16rpx;
+    padding: 32rpx;
+    margin-bottom: 20rpx;
+    box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.06);
+}
+
+.section-title {
+    font-size: 32rpx;
+    font-weight: 600;
+    color: #303133;
+    margin-bottom: 32rpx;
+    padding-bottom: 16rpx;
+    border-bottom: 2rpx solid #e4e7ed;
+    display: block;
+}
+
+// 学生信息样式
+.student-list {
+    display: flex;
+    flex-direction: column;
+    gap: 24rpx;
+}
+
+.student-item {
+    background-color: #f8f9fa;
+    border-radius: 12rpx;
+    padding: 24rpx;
+    border: 1px solid #e9ecef;
+}
+
+.student-header {
+    display: flex;
+    align-items: center;
+    gap: 16rpx;
+    margin-bottom: 20rpx;
+    padding-bottom: 16rpx;
+    border-bottom: 1px solid #e9ecef;
+}
+
+.student-name {
+    font-size: 28rpx;
+    font-weight: 600;
+    color: #303133;
+}
+
+.student-no {
+    font-size: 24rpx;
+    color: #606266;
+    background-color: #e9ecef;
+    padding: 4rpx 8rpx;
+    border-radius: 4rpx;
+}
+
+.student-bed {
+    font-size: 24rpx;
+    color: #909399;
+    background-color: #f0f0f0;
+    padding: 4rpx 8rpx;
+    border-radius: 4rpx;
+}
+
+.student-form {
+    display: flex;
+    flex-direction: column;
+    gap: 16rpx;
+}
+
+.form-row {
+    display: flex;
+    gap: 20rpx;
+}
+
+.form-col {
+    flex: 1;
+    display: flex;
+    flex-direction: column;
+    gap: 8rpx;
+}
+
+// 新增:支持三个字段自适应布局
+.form-row-flex {
+    display: flex;
+    flex-wrap: wrap;
+    gap: 16rpx;
+}
+
+.form-col-flex {
+    flex: 1;
+    min-width: 0;
+    min-width: calc(33.33% - 12rpx); // 每行最多3个,考虑gap
+    display: flex;
+    flex-direction: column;
+    gap: 8rpx;
+}
+
+// 当屏幕宽度不够时,自适应为两列布局
+@media screen and (max-width: 600rpx) {
+    .form-col-flex {
+        min-width: calc(50% - 8rpx); // 变为2列布局
+    }
+}
+
+// 当屏幕宽度很小时,自适应为单列布局
+@media screen and (max-width: 400rpx) {
+    .form-col-flex {
+        min-width: 100%; // 变为1列布局
+    }
+}
+
+.form-label {
+    font-size: 24rpx;
+    color: #606266;
+    margin-bottom: 8rpx;
+}
+
+// 附件样式
+.upload-area {
+    padding: 20rpx 0;
+}
+
+.doc-upload-section {
+    margin-top: 20rpx;
+    padding: 20rpx 0;
+    border-top: 2rpx dashed #e0e0e0;
+}
+
+// 微信上传区域样式
+.wechat-upload-section {
+    margin-bottom: 20rpx;
+    padding: 20rpx;
+    background: #f0f9ff;
+    border: 2rpx dashed #2979ff;
+    border-radius: 10rpx;
+}
+
+.upload-progress {
+    margin-top: 15rpx;
+}
+
+.progress-text {
+    font-size: 24rpx;
+    color: #666;
+    margin-top: 8rpx;
+    text-align: center;
+    display: block;
+}
+
+// 完善的上传进度条样式
+.upload-progress {
+    margin-top: 20rpx;
+    padding: 20rpx;
+    background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
+    border-radius: 12rpx;
+    border: 1px solid #e1e8ed;
+    box-shadow: 0 2px 8px rgba(41, 121, 255, 0.1);
+}
+
+.progress-text {
+    display: block;
+    text-align: center;
+    font-size: 26rpx !important;
+    color: #2979ff !important;
+    font-weight: 500;
+    margin-top: 12rpx;
+    animation: pulse 2s infinite;
+}
+
+@keyframes pulse {
+    0%,
+    100% {
+        opacity: 0.8;
+    }
+    50% {
+        opacity: 1;
+    }
+}
+
+// 图片展示区域样式
+.image-section {
+    margin-bottom: 30rpx;
+}
+
+.image-title {
+    font-size: 28rpx;
+    font-weight: 600;
+    color: #333;
+    margin-bottom: 20rpx;
+    padding-left: 10rpx;
+    border-left: 4rpx solid #2979ff;
+}
+
+.image-grid {
+    display: grid;
+    grid-template-columns: repeat(auto-fill, minmax(280rpx, 1fr));
+    gap: 20rpx;
+}
+
+.image-item {
+    position: relative;
+    background: #fff;
+    border-radius: 12rpx;
+    overflow: hidden;
+    border: 2rpx solid #f0f0f0;
+    transition: all 0.3s ease;
+    /* 确保图片容器的点击事件不影响按钮 */
+    cursor: pointer;
+}
+
+.image-item:active {
+    transform: scale(0.98);
+    border-color: #2979ff;
+}
+
+.image-container {
+    position: relative;
+    width: 100%;
+    height: 200rpx;
+    border-radius: 8rpx;
+    overflow: hidden;
+    cursor: pointer;
+}
+
+.attachment-image {
+    width: 100%;
+    height: 100%;
+    object-fit: cover;
+    background-color: #f5f5f5;
+}
+
+.upload-overlay {
+    position: absolute;
+    top: 0;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    background-color: rgba(0, 0, 0, 0.6);
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+    color: #fff;
+}
+
+.upload-text {
+    font-size: 24rpx;
+    margin-top: 8rpx;
+    font-weight: 500;
+}
+
+.error-overlay {
+    position: absolute;
+    top: 0;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    background-color: rgba(250, 53, 52, 0.8);
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+    color: #fff;
+}
+
+.error-text {
+    font-size: 24rpx;
+    margin-top: 8rpx;
+    font-weight: 500;
+}
+
+.success-badge {
+    position: absolute;
+    top: 8rpx;
+    right: 8rpx;
+    background-color: rgba(255, 255, 255, 0.9);
+    border-radius: 50%;
+    padding: 4rpx;
+    box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
+}
+
+.image-actions {
+    display: flex;
+    gap: 6rpx;
+    padding: 8rpx 12rpx;
+    background: #fafafa;
+    border-top: 1rpx solid #f0f0f0;
+    flex-wrap: nowrap;
+    justify-content: space-between;
+    /* 确保按钮区域能正确处理点击事件 */
+    position: relative;
+    z-index: 10;
+    pointer-events: auto;
+}
+
+.image-actions .u-button {
+    flex: 1;
+    min-width: 60rpx;
+    font-size: 24rpx !important;
+    /* 确保按钮可点击 */
+    pointer-events: auto;
+    position: relative;
+    z-index: 11;
+}
+
+.image-name {
+    padding: 8rpx 12rpx;
+    background: #fff;
+    font-size: 22rpx;
+    color: #666;
+    text-align: center;
+    overflow: hidden;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+}
+
+// 自定义文件列表样式
+.custom-file-list {
+    margin-top: 20rpx;
+}
+
+.file-title {
+    font-size: 28rpx;
+    font-weight: 600;
+    color: #333;
+    margin-bottom: 20rpx;
+    padding-left: 10rpx;
+    border-left: 4rpx solid #2979ff;
+}
+
+.file-grid {
+    display: grid;
+    grid-template-columns: repeat(auto-fill, minmax(280rpx, 1fr));
+    gap: 20rpx;
+}
+
+.file-card {
+    position: relative;
+    background: #fff;
+    border-radius: 12rpx;
+    overflow: hidden;
+    border: 2rpx solid #f0f0f0;
+    transition: all 0.3s ease;
+}
+
+.file-card:active {
+    transform: scale(0.98);
+    border-color: #2979ff;
+}
+
+.file-icon-container {
+    position: relative;
+    width: 100%;
+    height: 200rpx;
+    border-radius: 8rpx;
+    overflow: hidden;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    background: #f8f9fa;
+}
+
+.file-info-card {
+    position: absolute;
+    bottom: 8rpx;
+    left: 8rpx;
+    right: 8rpx;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+}
+
+.file-ext-badge {
+    background: rgba(255, 255, 255, 0.9);
+    color: #333;
+    font-size: 22rpx;
+    font-weight: 600;
+    padding: 4rpx 8rpx;
+    border-radius: 4rpx;
+    backdrop-filter: blur(4rpx);
+}
+
+.file-size {
+    background: rgba(0, 0, 0, 0.6);
+    color: #fff;
+    font-size: 20rpx;
+    padding: 2rpx 6rpx;
+    border-radius: 4rpx;
+}
+
+.file-actions {
+    display: flex;
+    gap: 6rpx;
+    padding: 8rpx 12rpx;
+    background: #fafafa;
+    border-top: 1rpx solid #f0f0f0;
+    flex-wrap: nowrap;
+    justify-content: space-between;
+}
+
+.file-actions .u-button {
+    flex: 1;
+    min-width: 60rpx;
+    font-size: 24rpx !important;
+}
+
+.file-name-display {
+    padding: 8rpx 12rpx;
+    background: #fff;
+    font-size: 22rpx;
+    color: #666;
+    text-align: center;
+    overflow: hidden;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+}
+
+.upload-tips {
+    margin-top: 20rpx;
+    padding: 15rpx;
+    background: #f8f9fa;
+    border-radius: 8rpx;
+    border-left: 4rpx solid #17a2b8;
+}
+
+.tip-item {
+    display: block;
+    font-size: 24rpx;
+    color: #666;
+    line-height: 1.5;
+    margin-bottom: 8rpx;
+}
+
+.wechat-tip {
+    color: #2979ff;
+    font-weight: 500;
+}
+
+/* 上传状态样式 */
+.upload-status {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    margin-top: 15rpx;
+    padding: 10rpx;
+    border-radius: 8rpx;
+    font-size: 24rpx;
+    font-weight: 500;
+}
+
+.upload-status.success {
+    color: #19be6b;
+    background-color: rgba(25, 190, 107, 0.1);
+}
+
+.upload-status.error {
+    color: #fa3534;
+    background-color: rgba(250, 53, 52, 0.1);
+}
+
+.upload-progress-small {
+    width: 100%;
+    margin-bottom: 8rpx;
+}
+
+.upload-text {
+    font-size: 22rpx;
+    color: #2979ff;
+    text-align: center;
+}
+
+// 底部操作按钮
+.bottom-actions {
+    position: fixed;
+    bottom: 0;
+    left: 0;
+    right: 0;
+    padding: 20rpx;
+    background-color: #ffffff;
+    border-top: 1px solid #e4e7ed;
+    display: flex;
+    gap: 20rpx;
+    z-index: 999;
+}
+
+.bottom-actions .u-button {
+    flex: 1;
+}
+
+// 响应式设计
+@media (max-width: 375px) {
+    .form-container {
+        padding: 16rpx;
+    }
+
+    .form-section {
+        padding: 24rpx;
+        margin-bottom: 16rpx;
+    }
+
+    .student-item {
+        padding: 20rpx;
+    }
+
+    .form-row {
+        flex-direction: column;
+        gap: 16rpx;
+    }
+
+    .form-row-flex {
+        flex-direction: column;
+        gap: 16rpx;
+    }
+
+    .form-col-flex {
+        min-width: 100%;
+    }
+
+    .image-grid {
+        grid-template-columns: repeat(2, 1fr);
+    }
+
+    .file-grid {
+        grid-template-columns: repeat(2, 1fr);
+    }
+}
+
+// uview组件样式调整
+::v-deep .u-form-item {
+    margin-bottom: 32rpx;
+}
+
+::v-deep .u-input {
+    font-size: 28rpx;
+}
+
+::v-deep .u-textarea {
+    font-size: 28rpx;
+}
+
+::v-deep .u-button {
+    border-radius: 12rpx;
+}
+
+// 确保表单项有足够的高度和宽度
+::v-deep .u-form-item__body {
+    // min-height: 60rpx;
+    padding: 0px !important;
+}
+
+// 统一学生信息卡片中输入框的高度
+::v-deep .student-form .u-input {
+    height: 60rpx !important;
+    line-height: 60rpx !important;
+    min-height: 60rpx !important;
+    padding: 0px 10px !important;
+}
+
+::v-deep .student-form .u-input__content {
+    height: 60rpx !important;
+    min-height: 60rpx !important;
+}
+
+::v-deep .student-form .u-input__content__field-wrapper {
+    height: 60rpx !important;
+    min-height: 60rpx !important;
+}
+
+::v-deep .student-form .u-input__content__field-wrapper__field {
+    height: 60rpx !important;
+    line-height: 60rpx !important;
+    min-height: 60rpx !important;
+}
+
+// 强制统一所有输入框高度
+::v-deep .form-col-flex .u-input {
+    height: 60rpx !important;
+    line-height: 60rpx !important;
+    min-height: 60rpx !important;
+}
+
+::v-deep .form-col-flex .u-input__content {
+    height: 60rpx !important;
+    min-height: 60rpx !important;
+}
+
+::v-deep .u-form-item__body__right {
+    flex: 1;
+}
+
+::v-deep .u-form-item__body__right__content {
+    width: 100%;
+}
+
+::v-deep .u-form-item__body__right__content .u-input {
+    width: 100%;
+}
+
+// 修复选择器样式
+::v-deep .u-picker {
+    z-index: 999999;
+}
+
+::v-deep .u-picker__view {
+    z-index: 999999;
+}
+
+// 响应式适配
+@media screen and (max-width: 750rpx) {
+    .file-grid {
+        grid-template-columns: repeat(auto-fill, minmax(240rpx, 1fr));
+        gap: 15rpx;
+    }
+
+    .file-icon-container {
+        height: 160rpx;
+    }
+
+    .image-grid {
+        grid-template-columns: repeat(auto-fill, minmax(240rpx, 1fr));
+        gap: 15rpx;
+    }
+
+    .image-container {
+        height: 160rpx;
+    }
+
+    .file-actions .u-button,
+    .image-actions .u-button {
+        font-size: 22rpx !important;
+        padding: 6rpx 12rpx;
+    }
+}
+
+/* 微信SDK调试样式 */
+.wechat-debug-section {
+    background: #fff;
+    border-radius: 12rpx;
+    padding: 30rpx;
+    margin-bottom: 20rpx;
+    border: 2rpx solid #2979ff;
+}
+
+.debug-controls {
+    display: flex;
+    gap: 10rpx;
+    align-items: center;
+    margin-top: 10rpx;
+    flex-wrap: wrap;
+}
+
+.sdk-status {
+    margin: 20rpx 0;
+    padding: 15rpx;
+    background: #f8f9fa;
+    border-radius: 8rpx;
+}
+
+.status-item {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 10rpx;
+}
+
+.status-label {
+    font-size: 26rpx;
+    color: #666;
+}
+
+.status-value {
+    font-size: 26rpx;
+    font-weight: 500;
+}
+
+.status-value.success {
+    color: #52c41a;
+}
+
+.status-value.error {
+    color: #f5222d;
+}
+
+.debug-logs {
+    margin-top: 20rpx;
+    border: 2rpx solid #e8e8e8;
+    border-radius: 8rpx;
+    background: #fafafa;
+}
+
+.log-content {
+    max-height: 400rpx;
+    padding: 15rpx;
+}
+
+.log-item {
+    margin-bottom: 10rpx;
+    padding: 8rpx 12rpx;
+    border-radius: 6rpx;
+    font-size: 24rpx;
+    line-height: 1.4;
+}
+
+.log-item.info {
+    background: #e6f7ff;
+    border-left: 4rpx solid #1890ff;
+}
+
+.log-item.success {
+    background: #f6ffed;
+    border-left: 4rpx solid #52c41a;
+}
+
+.log-item.warning {
+    background: #fffbe6;
+    border-left: 4rpx solid #faad14;
+}
+
+.log-item.error {
+    background: #fff2f0;
+    border-left: 4rpx solid #f5222d;
+}
+
+.log-time {
+    color: #999;
+    font-size: 22rpx;
+    margin-right: 10rpx;
+}
+
+.log-text {
+    color: #333;
+}
+
+.log-text.info {
+    color: #1890ff;
+}
+
+.log-text.success {
+    color: #52c41a;
+}
+
+.log-text.warning {
+    color: #faad14;
+}
+
+.log-text.error {
+    color: #f5222d;
+}
+
+.log-detail {
+    margin-top: 5rpx;
+    padding: 8rpx;
+    background: rgba(0, 0, 0, 0.03);
+    border-radius: 4rpx;
+}
+
+.detail-text {
+    font-size: 20rpx;
+    color: #666;
+    font-family: monospace;
+    word-break: break-all;
+}
+
+.empty-logs {
+    text-align: center;
+    color: #999;
+    padding: 40rpx 0;
+    font-size: 26rpx;
+}
+
+/* 浮动调试按钮 */
+.debug-fab {
+    position: fixed;
+    right: 30rpx;
+    bottom: 200rpx;
+    width: 80rpx;
+    height: 80rpx;
+    background: #2979ff;
+    border-radius: 50%;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    box-shadow: 0 4rpx 12rpx rgba(41, 121, 255, 0.3);
+    z-index: 999;
+}
+
+.debug-fab:active {
+    background: #1976d2;
+    transform: scale(0.95);
+}
+</style>