zlwu il y a 1 an
Parent
commit
562180de0e

+ 2 - 1
.gitignore

@@ -323,4 +323,5 @@ docs/变更管理/
 移动端附件组件规范.md
 移动端违纪记录模块开发规范.md
 .playwright-mcp/
-
+查找界面中涉及到的权限字符.md
+docs/部署文档/nginx配置/hzdyjsweb.camasort.com.conf

+ 33 - 1
backend/ruoyi-modules/ruoyi-hq/src/main/java/org/dromara/hq/service/impl/HqSatQuestionServiceImpl.java

@@ -73,7 +73,39 @@ public class HqSatQuestionServiceImpl implements IHqSatQuestionService {
     private LambdaQueryWrapper<HqSatQuestion> buildQueryWrapper(HqSatQuestionBo bo) {
         Map<String, Object> params = bo.getParams();
         LambdaQueryWrapper<HqSatQuestion> lqw = Wrappers.lambdaQuery();
-        lqw.orderByAsc(HqSatQuestion::getId);
+
+        // 处理排序参数
+        if (params != null && params.containsKey("orderByColumn") && params.containsKey("isAsc")) {
+            String orderByColumn = (String) params.get("orderByColumn");
+            String isAsc = (String) params.get("isAsc");
+
+            if ("createTime".equals(orderByColumn)) {
+                if ("desc".equals(isAsc)) {
+                    lqw.orderByDesc(HqSatQuestion::getCreateTime);
+                } else {
+                    lqw.orderByAsc(HqSatQuestion::getCreateTime);
+                }
+            } else if ("updateTime".equals(orderByColumn)) {
+                if ("desc".equals(isAsc)) {
+                    lqw.orderByDesc(HqSatQuestion::getUpdateTime);
+                } else {
+                    lqw.orderByAsc(HqSatQuestion::getUpdateTime);
+                }
+            } else if ("sortOrder".equals(orderByColumn)) {
+                if ("desc".equals(isAsc)) {
+                    lqw.orderByDesc(HqSatQuestion::getSortOrder);
+                } else {
+                    lqw.orderByAsc(HqSatQuestion::getSortOrder);
+                }
+            } else {
+                // 默认按创建时间倒序
+                lqw.orderByDesc(HqSatQuestion::getCreateTime);
+            }
+        } else {
+            // 默认按创建时间倒序
+            lqw.orderByDesc(HqSatQuestion::getCreateTime);
+        }
+
         // 添加ID查询条件
         lqw.eq(bo.getId() != null, HqSatQuestion::getId, bo.getId());
         lqw.eq(bo.getDeleted() != null, HqSatQuestion::getDeleted, bo.getDeleted());

+ 1 - 5
backend/ruoyi-modules/ruoyi-hq/src/main/resources/mapper/HqPmRepairOrderMapper.xml

@@ -15,11 +15,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         LEFT JOIN sys_dept d ON u.dept_id = d.dept_id
         INNER JOIN sys_user_role ur ON u.user_id = ur.user_id
         INNER JOIN sys_role r ON ur.role_id = r.role_id
-        WHERE (r.role_key = 'maintenance_worker'
-           OR r.role_name = '维修人员'
-           OR r.role_id = 5
-           OR r.role_name LIKE '%维修%'
-           OR r.role_key LIKE '%worker%')
+        WHERE r.role_key = 'maintenance_worker'
         AND u.status = '0'
         AND u.del_flag = '0'
         ORDER BY u.user_id

+ 59 - 11
docs/部署文档/nginx配置/hzdyjsweb.camasort.com.conf

@@ -41,17 +41,65 @@ server {
         add_header Pragma "no-cache";
     }
     
-    # API代理配置(如果需要避免CORS问题)
-    # location /api/ {
-    #     proxy_pass http://47.121.125.41:8080/;
-    #     proxy_set_header Host $host;
-    #     proxy_set_header X-Real-IP $remote_addr;
-    #     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
-    #     proxy_set_header X-Forwarded-Proto $scheme;
-    #     proxy_connect_timeout 60s;
-    #     proxy_send_timeout 60s;
-    #     proxy_read_timeout 60s;
-    # }
+    # Warm-Flow工作流UI代理配置(重要:必须放在Vue路由配置之前,使用^~确保优先级)
+    location ^~ /prod-api/warm-flow-ui/ {
+        proxy_pass http://47.121.125.41:8080/warm-flow-ui/;
+        proxy_set_header Host $host;
+        proxy_set_header X-Real-IP $remote_addr;
+        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+        proxy_set_header X-Forwarded-Proto $scheme;
+        
+        # 支持WebSocket和SSE
+        proxy_http_version 1.1;
+        proxy_set_header Upgrade $http_upgrade;
+        proxy_set_header Connection "upgrade";
+        proxy_buffering off;
+        proxy_cache off;
+        
+        # 超时设置
+        proxy_connect_timeout 60s;
+        proxy_send_timeout 60s;
+        proxy_read_timeout 86400s;
+        
+        # CORS处理
+        add_header Access-Control-Allow-Origin *;
+        add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS';
+        add_header Access-Control-Allow-Headers 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization,clientid';
+        
+        if ($request_method = 'OPTIONS') {
+            return 204;
+        }
+    }
+    
+    # API代理配置(使用^~确保优先级,避免被Vue路由配置干扰)
+    location ^~ /prod-api/ {
+        proxy_pass http://47.121.125.41:8080/;
+        proxy_set_header Host $host;
+        proxy_set_header X-Real-IP $remote_addr;
+        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+        proxy_set_header X-Forwarded-Proto $scheme;
+        
+        # 支持WebSocket和SSE
+        proxy_http_version 1.1;
+        proxy_set_header Upgrade $http_upgrade;
+        proxy_set_header Connection "upgrade";
+        proxy_buffering off;
+        proxy_cache off;
+        
+        # 超时设置
+        proxy_connect_timeout 60s;
+        proxy_send_timeout 60s;
+        proxy_read_timeout 86400s;
+        
+        # CORS处理
+        add_header Access-Control-Allow-Origin *;
+        add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS';
+        add_header Access-Control-Allow-Headers 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization,clientid';
+        
+        if ($request_method = 'OPTIONS') {
+            return 204;
+        }
+    }
     
     # Gzip压缩配置
     gzip on;

+ 36 - 36
mobile/src/pages/index/index.vue

@@ -74,7 +74,7 @@
                 <GridLayout :columns="3" gap="16px">
                     <!-- 卡片开始 -->
                     <ServiceItem
-                        v-if="hasPermi(['student:info:list'])"
+                        v-if="hasPermi(['student:info:listapp'])"
                         title="学生信息"
                         @click="handleServiceClick"
                     >
@@ -87,7 +87,7 @@
                         </template>
                     </ServiceItem>
                     <!-- 卡片结束 -->
-                    <ServiceItem
+                    <!-- <ServiceItem
                         v-if="hasPermi(['student:dorm:list'])"
                         title="宿舍管理"
                         @click="handleServiceClick"
@@ -95,10 +95,10 @@
                         <template #icon>
                             <u-icon name="home" size="24" />
                         </template>
-                    </ServiceItem>
+                    </ServiceItem> -->
 
                     <ServiceItem
-                        v-if="hasPermi(['student:leave:list'])"
+                        v-if="hasPermi(['student:leave:listapp'])"
                         title="学生请假"
                         @click="gotoStudentLeave"
                     >
@@ -111,7 +111,7 @@
                         </template>
                     </ServiceItem>
 
-                    <ServiceItem
+                    <!-- <ServiceItem
                         v-if="hasPermi(['student:psychology:list'])"
                         title="心理健康"
                         @click="handleServiceClick"
@@ -119,9 +119,9 @@
                         <template #icon>
                             <u-icon name="heart" size="24" />
                         </template>
-                    </ServiceItem>
+                    </ServiceItem> -->
 
-                    <ServiceItem
+                    <!-- <ServiceItem
                         v-if="hasPermi(['student:club:list'])"
                         title="社团管理"
                         @click="handleServiceClick"
@@ -129,9 +129,9 @@
                         <template #icon>
                             <u-icon name="star" size="24" />
                         </template>
-                    </ServiceItem>
+                    </ServiceItem> -->
 
-                    <ServiceItem
+                    <!-- <ServiceItem
                         v-if="hasPermi(['student:counsel:list'])"
                         title="心理咨询"
                         @click="handleServiceClick"
@@ -139,10 +139,10 @@
                         <template #icon>
                             <u-icon name="chat" size="24" />
                         </template>
-                    </ServiceItem>
+                    </ServiceItem> -->
 
                     <ServiceItem
-                        v-if="hasPermi(['student:info:edit'])"
+                        v-if="hasPermi(['student:info:editapp'])"
                         title="学生信息完善"
                         @click="gotoStudentInfoComplete"
                     >
@@ -182,7 +182,7 @@
                         </template>
                     </ServiceItem>
                     <ServiceItem
-                        v-if="hasPermi(['student:dormviolation:list'])"
+                        v-if="hasPermi(['student:dormviolation:listapp'])"
                         title="宿舍违纪"
                         @click="gotoDormViolation"
                     >
@@ -195,7 +195,7 @@
                         </template>
                     </ServiceItem>
                     <ServiceItem
-                        v-if="hasPermi(['student:dormhygiene:list'])"
+                        v-if="hasPermi(['student:dormhygiene:listapp'])"
                         title="宿舍卫生检查"
                         @click="gotoDormHygiene"
                     >
@@ -208,7 +208,7 @@
                         </template>
                     </ServiceItem>
                     <ServiceItem
-                        v-if="hasPermi(['student:dormhygiene:studentlist'])"
+                        v-if="hasPermi(['student:dormhygiene:studentlistapp'])"
                         title="宿舍卫生检查(学生)"
                         @click="gotoStudentDormHygiene"
                     >
@@ -236,7 +236,7 @@
                     </ServiceItem>
 
                     <ServiceItem
-                        v-if="hasPermi(['student:violation:list'])"
+                        v-if="hasPermi(['student:violation:listapp'])"
                         title="违纪记录(学生)"
                         @click="gotoStudentViolation"
                     >
@@ -250,7 +250,7 @@
                     </ServiceItem>
 
                     <ServiceItem
-                        v-if="hasPermi(['student:assessment:apply'])"
+                        v-if="hasPermi(['student:assessment:applyapp'])"
                         title="考核申请"
                         @click="gotoAssessmentApply"
                     >
@@ -266,7 +266,7 @@
             </Card>
 
             <!-- 后勤管理 -->
-            <Card v-if="hasLogisticsServices">
+            <!-- <Card v-if="hasLogisticsServices">
                 <template #header>
                     <view class="section-header">
                         <u-icon name="setting" size="18" color="#52c41a" />
@@ -334,10 +334,10 @@
                         </template>
                     </ServiceItem>
                 </GridLayout>
-            </Card>
+            </Card> -->
 
             <!-- 招生就业 -->
-            <Card v-if="hasRecruitmentServices">
+            <!-- <Card v-if="hasRecruitmentServices">
                 <template #header>
                     <view class="section-header">
                         <u-icon name="trophy" size="18" color="#fa8c16" />
@@ -375,10 +375,10 @@
                         </template>
                     </ServiceItem>
                 </GridLayout>
-            </Card>
+            </Card> -->
 
             <!-- 人事管理 -->
-            <Card v-if="hasHRServices">
+            <!-- <Card v-if="hasHRServices">
                 <template #header>
                     <view class="section-header">
                         <u-icon name="friends" size="18" color="#722ed1" />
@@ -416,10 +416,10 @@
                         </template>
                     </ServiceItem>
                 </GridLayout>
-            </Card>
+            </Card> -->
 
             <!-- 财务管理 -->
-            <Card v-if="hasFinanceServices">
+            <!-- <Card v-if="hasFinanceServices">
                 <template #header>
                     <view class="section-header">
                         <u-icon name="rmb-circle" size="18" color="#13c2c2" />
@@ -457,10 +457,10 @@
                         </template>
                     </ServiceItem>
                 </GridLayout>
-            </Card>
+            </Card> -->
 
             <!-- 系统管理 -->
-            <Card v-if="hasSystemServices">
+            <!-- <Card v-if="hasSystemServices">
                 <template #header>
                     <view class="section-header">
                         <u-icon name="setting" size="18" color="#f5222d" />
@@ -532,14 +532,14 @@
                         </template>
                     </ServiceItem>
                 </GridLayout>
-            </Card>
+            </Card> -->
 
             <!-- 工作流 -->
             <Card v-if="hasWorkflowServices">
                 <template #header>
                     <view class="section-header">
                         <u-icon name="share" size="18" color="#eb2f96" />
-                        <text class="card-title">工作流</text>
+                        <text class="card-title">请销假待办</text>
                     </view>
                 </template>
                 <GridLayout :columns="2" gap="16px">
@@ -586,7 +586,7 @@
             </Card>
 
             <!-- 微信SDK测试 -->
-            <Card v-if="hasWechatTestAccess">
+            <!-- <Card v-if="hasWechatTestAccess">
                 <template #header>
                     <view class="section-header">
                         <u-icon name="chat" size="18" color="#07c160" />
@@ -606,7 +606,7 @@
                         </template>
                     </ServiceItem>
                 </GridLayout>
-            </Card>
+            </Card> -->
 
             <!-- 底部间距 -->
             <view class="bottom-spacer"></view>
@@ -677,20 +677,20 @@ export default {
         // 检查各模块是否有权限
         hasStudentServices() {
             return (
-                this.hasPermi(['student:info:list']) ||
+                this.hasPermi(['student:info:listapp']) ||
                 this.hasPermi(['student:dorm:list']) ||
-                this.hasPermi(['student:leave:list']) ||
+                this.hasPermi(['student:leave:listapp']) ||
                 this.hasPermi(['student:psychology:list']) ||
                 this.hasPermi(['student:club:list']) ||
                 this.hasPermi(['student:counsel:list']) ||
-                this.hasPermi(['student:info:edit']) ||
+                this.hasPermi(['student:info:editapp']) ||
                 this.hasPermi(['student:internship:list']) ||
-                this.hasPermi(['student:dorm:violation:list']) ||
+                this.hasPermi(['student:dormviolation:listapp']) ||
                 this.hasPermi(['student:visit:list']) ||
-                this.hasPermi(['student:dorm:hygiene:list']) ||
+                this.hasPermi(['student:dormhygiene:listapp']) ||
                 this.hasPermi(['student:workstudy:list']) ||
-                this.hasPermi(['student:violation:list']) ||
-                this.hasPermi(['student:assessment:apply'])
+                this.hasPermi(['student:violation:listapp']) ||
+                this.hasPermi(['student:assessment:applyapp'])
             );
         },
 

BIN
web/public/assets/images/01.jpg


BIN
web/public/assets/images/02.jpg


BIN
web/public/assets/images/03.jpg


BIN
web/public/assets/images/login-background-2-bak.jpg


BIN
web/public/assets/images/login-background-2.jpg


BIN
web/public/assets/images/login-background-bak.jpg


BIN
web/public/assets/images/login-background-old.jpg


BIN
web/public/assets/images/login-background.jpg


BIN
web/src/assets/images/01.jpg


BIN
web/src/assets/images/02.jpg


BIN
web/src/assets/images/03.jpg


+ 1 - 1
web/src/views/hq/bgtgl/hallReservation/index.vue

@@ -429,7 +429,7 @@ const auditorList = ref<any[]>([]);
 /** 获取具有审核权限的人员列表 */
 const getAuditorList = async () => {
   try {
-    const res = await listUsersByPermission('hq:hallAudit:list');
+    const res = await listUsersByPermission('hq:hallAudit:hallAudit');
     auditorList.value = res.data || [];
     console.log('审核人员列表:', auditorList.value);
   } catch (error) {

+ 5 - 0
web/src/views/hq/myddc/satCategory/index.vue

@@ -174,6 +174,8 @@ const data = reactive<PageData<SatCategoryForm, SatCategoryQuery>>({
     categoryDesc: undefined,
     sortOrder: undefined,
     status: undefined,
+    orderByColumn: 'createTime',
+    isAsc: 'desc',
     params: {}
   },
   rules: {
@@ -215,6 +217,9 @@ const handleQuery = () => {
 /** 重置按钮操作 */
 const resetQuery = () => {
   queryFormRef.value?.resetFields();
+  // 保持排序设置
+  queryParams.value.orderByColumn = 'createTime';
+  queryParams.value.isAsc = 'desc';
   handleQuery();
 };
 

+ 4 - 1
web/src/views/hq/myddc/satQuestion/index.vue

@@ -319,7 +319,10 @@ const data = reactive<PageData<SatQuestionForm, SatQuestionQuery>>({
     isRequired: undefined,
     sortOrder: undefined,
     status: undefined,
-    params: {}
+    params: {
+      orderByColumn: 'createTime',
+      isAsc: 'desc'
+    }
   },
   rules: {
     id: [{ required: true, message: '主键ID不能为空', trigger: 'blur' }],

+ 126 - 3
web/src/views/index.vue

@@ -1,5 +1,21 @@
 <template>
   <div class="app-container home">
+    <!-- 上半部分:校园风景图片轮播 -->
+    <div class="carousel-section">
+      <el-carousel :interval="4000" type="card" height="400px" indicator-position="outside" arrow="always" class="campus-carousel">
+        <el-carousel-item v-for="(image, index) in campusImages" :key="index">
+          <div class="carousel-item">
+            <img :src="image.url" :alt="image.title" class="carousel-image" />
+            <div class="carousel-overlay">
+              <h3 class="carousel-title">{{ image.title }}</h3>
+              <p class="carousel-description">{{ image.description }}</p>
+            </div>
+          </div>
+        </el-carousel-item>
+      </el-carousel>
+    </div>
+
+    <!-- 下半部分:原有内容 -->
     <div class="construction-container">
       <div class="construction-content">
         <!-- 系统标题 -->
@@ -58,8 +74,28 @@
 </template>
 
 <script setup name="Index" lang="ts">
+import { computed } from 'vue';
 import { Tools, Calendar, Service, Phone, Message } from '@element-plus/icons-vue';
 
+// 校园风景图片数据
+const campusImages = [
+  {
+    url: '/assets/images/01.jpg',
+    title: '校园正门',
+    description: '绿意盎然的校园入口,展现学院的自然之美'
+  },
+  {
+    url: '/assets/images/02.jpg',
+    title: '校园风光',
+    description: '现代化的校园建筑与自然景观的完美融合'
+  },
+  {
+    url: '/assets/images/03.jpg',
+    title: '校园全景',
+    description: '鸟瞰校园全景,展现学院的整体风貌'
+  }
+];
+
 // 计算预计完成时间(当前时间后30天)
 const expectedDate = computed(() => {
   const date = new Date();
@@ -75,16 +111,79 @@ const expectedDate = computed(() => {
 <style lang="scss" scoped>
 .home {
   min-height: calc(100vh - 200px);
-  display: flex;
-  align-items: center;
-  justify-content: center;
   background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
 }
 
+// 上半部分:轮播图样式
+.carousel-section {
+  padding: 40px 20px;
+  background: rgba(255, 255, 255, 0.1);
+  backdrop-filter: blur(5px);
+}
+
+.campus-carousel {
+  max-width: 1200px;
+  margin: 0 auto;
+  border-radius: 16px;
+  overflow: hidden;
+  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
+
+  :deep(.el-carousel__item) {
+    border-radius: 16px;
+  }
+}
+
+.carousel-item {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  overflow: hidden;
+  border-radius: 16px;
+}
+
+.carousel-image {
+  width: 100%;
+  height: 100%;
+  object-fit: cover;
+  transition: transform 0.3s ease;
+}
+
+.carousel-item:hover .carousel-image {
+  transform: scale(1.05);
+}
+
+.carousel-overlay {
+  position: absolute;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  background: linear-gradient(transparent, rgba(0, 0, 0, 0.7));
+  color: white;
+  padding: 40px 30px 30px;
+  text-align: left;
+}
+
+.carousel-title {
+  font-size: 24px;
+  font-weight: 600;
+  margin: 0 0 10px 0;
+  text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
+}
+
+.carousel-description {
+  font-size: 16px;
+  margin: 0;
+  opacity: 0.9;
+  text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5);
+  line-height: 1.5;
+}
+
+// 下半部分:原有样式
 .construction-container {
   width: 100%;
   max-width: 800px;
   padding: 40px;
+  margin: 0 auto;
 }
 
 .construction-content {
@@ -212,6 +311,26 @@ const expectedDate = computed(() => {
 
 // 响应式设计
 @media (max-width: 768px) {
+  .carousel-section {
+    padding: 20px 10px;
+  }
+
+  .campus-carousel {
+    height: 300px !important;
+  }
+
+  .carousel-overlay {
+    padding: 30px 20px 20px;
+  }
+
+  .carousel-title {
+    font-size: 20px;
+  }
+
+  .carousel-description {
+    font-size: 14px;
+  }
+
   .construction-container {
     padding: 20px;
   }
@@ -237,6 +356,10 @@ const expectedDate = computed(() => {
 
 // 深色主题适配
 html.dark {
+  .carousel-section {
+    background: rgba(0, 0, 0, 0.1);
+  }
+
   .construction-content {
     background: rgba(30, 30, 30, 0.95);
     border: 1px solid rgba(255, 255, 255, 0.1);

+ 2 - 2
web/src/views/login.vue

@@ -10,12 +10,12 @@
         <h3 class="title">{{ title }}</h3>
         <!-- <lang-select /> -->
       </div>
-      <el-form-item v-if="tenantEnabled" prop="tenantId" class="el_select_coopr">
+      <!-- <el-form-item v-if="tenantEnabled" prop="tenantId" class="el_select_coopr">
         <el-select v-model="loginForm.tenantId" filterable :placeholder="proxy.$t('login.selectPlaceholder')" style="width: 100%">
           <el-option v-for="item in tenantList" :key="item.tenantId" :label="item.companyName" :value="item.tenantId"></el-option>
           <template #prefix><svg-icon icon-class="company" class="el-input__icon input-icon" /></template>
         </el-select>
-      </el-form-item>
+      </el-form-item> -->
       <el-form-item prop="username">
         <el-input v-model="loginForm.username" type="text" auto-complete="off" :placeholder="proxy.$t('login.username')">
           <template #prefix><svg-icon icon-class="user" class="el-input__icon input-icon" /></template>

+ 1 - 8
web/src/views/xg/xsjcxx/stuMsgAudit/index.vue

@@ -123,7 +123,7 @@
         </el-table-column>
       </el-table>
 
-      <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
+      <!-- 分页组件已移除,因为列表接口不支持分页 -->
     </el-card>
     <!-- 添加或修改学生信息收集批次对话框 -->
     <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
@@ -313,7 +313,6 @@ const showSearch = ref(true);
 const ids = ref<Array<string | number>>([]);
 const single = ref(true);
 const multiple = ref(true);
-const total = ref(0);
 
 const queryFormRef = ref<ElFormInstance>();
 const stuColBatchFormRef = ref<ElFormInstance>();
@@ -384,8 +383,6 @@ const initFormData: StuColBatchForm = {
 const data = reactive<PageData<StuColBatchForm, StuColBatchQuery>>({
   form: { ...initFormData },
   queryParams: {
-    pageNum: 1,
-    pageSize: 10,
     batchName: undefined,
     status: undefined,
     collectionType: undefined,
@@ -419,16 +416,13 @@ const getList = async () => {
     if (res && res.code === 200) {
       // 将返回的数据转换为表格需要的格式
       stuColBatchList.value = res.data || [];
-      total.value = res.data ? res.data.length : 0;
     } else {
       stuColBatchList.value = [];
-      total.value = 0;
       proxy?.$modal.msgError(res?.msg || '获取数据失败');
     }
   } catch (error) {
     console.error('获取学生可参与批次信息失败:', error);
     stuColBatchList.value = [];
-    total.value = 0;
     proxy?.$modal.msgError('获取数据失败');
   } finally {
     loading.value = false;
@@ -449,7 +443,6 @@ const reset = () => {
 
 /** 搜索按钮操作 */
 const handleQuery = () => {
-  queryParams.value.pageNum = 1;
   getList();
 };
 

+ 185 - 14
web/src/views/xg/xsjcxx/studentMsg/studentMsg/index.vue

@@ -145,6 +145,12 @@
               </template>
             </el-table-column>
 
+            <!-- <el-table-column v-if="columns[9].visible" label="宿舍房间" align="center" prop="dormitoryRoom" width="120">
+              <template #default="scope">
+                <span>{{ getRoomDisplayName(scope.row.dormitoryRoom) }}</span>
+              </template>
+            </el-table-column> -->
+
             <el-table-column label="操作" fixed="right" width="240" class-name="small-padding fixed-width">
               <template #default="scope">
                 <el-tooltip content="修改" placement="top">
@@ -826,8 +832,13 @@
             </el-row>
             <el-row :gutter="20">
               <el-col :span="8">
-                <el-form-item label="宿舍房间号" prop="dormitoryRoom">
-                  <el-input disabled v-model="form.dormitoryRoom" placeholder="请输入宿舍房间号" maxlength="20" />
+                <el-form-item label="宿舍房间" prop="dormitoryRoom">
+                  <el-input disabled :value="getRoomDisplayName(form.dormitoryRoom)" placeholder="宿舍房间" maxlength="20" />
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="床位" prop="extField1">
+                  <el-input disabled :value="getBedDisplayName(form.extField1)" placeholder="床位" maxlength="20" />
                 </el-form-item>
               </el-col>
             </el-row>
@@ -1389,8 +1400,13 @@
             </el-row>
             <el-row :gutter="20">
               <el-col :span="8">
-                <el-form-item label="宿舍房间号">
-                  <span class="form-value">{{ detailForm.dormitoryRoom }}</span>
+                <el-form-item label="宿舍房间">
+                  <span class="form-value">{{ getRoomDisplayName(detailForm.dormitoryRoom) }}</span>
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="床位">
+                  <span class="form-value">{{ getBedDisplayName(detailForm.extField1) }}</span>
                 </el-form-item>
               </el-col>
             </el-row>
@@ -1603,6 +1619,8 @@ const classOptions = ref([]);
 const regionOptions = ref([]); // 行政区划选项
 const dormBuildingOptions = ref([]); // 宿舍楼栋选项
 const currentSelectedNode = ref<any>(null); // 当前选中的部门节点
+const roomCache = ref<Map<string | number, string>>(new Map()); // 房间名称缓存
+const bedCache = ref<Map<string | number, string>>(new Map()); // 床位名称缓存
 
 // 计算属性:判断是否显示新增按钮(只有班级节点才显示)
 const showAddButton = computed(() => {
@@ -1623,7 +1641,8 @@ const columns = ref([
   { key: 5, label: `班级`, visible: true },
   { key: 6, label: `手机号码`, visible: true },
   { key: 7, label: `状态`, visible: true },
-  { key: 8, label: `创建时间`, visible: true }
+  { key: 8, label: `创建时间`, visible: true },
+  { key: 9, label: `宿舍房间`, visible: true }
 ]);
 
 const deptTreeRef = ref<any>();
@@ -1686,7 +1705,7 @@ const initFormData: StudentMsgForm = {
   photoUrl: '',
   photoPath: '',
   phone: '',
-  isBoarder: 0,
+  isBoarder: '0',
 
   // // 扩展信息字段
   educationLevel: '2',
@@ -1700,14 +1719,14 @@ const initFormData: StudentMsgForm = {
   emergencyContactName: '',
   emergencyContactPhone: '',
   emergencyContactRelation: '',
-  isPoorStudent: 0,
-  isMinority: 0,
-  isDisabled: 0,
-  isOrphan: 0,
-  isLeftBehindChild: 0,
-  isSingleChild: 0,
-  isLowIncome: 0,
-  hasLoan: 0,
+  isPoorStudent: '0',
+  isMinority: '0',
+  isDisabled: '0',
+  isOrphan: '0',
+  isLeftBehindChild: '0',
+  isSingleChild: '0',
+  isLowIncome: '0',
+  hasLoan: '0',
   loanAmount: undefined,
   specialties: '',
   awards: '',
@@ -1762,6 +1781,7 @@ const initFormData: StudentMsgForm = {
   classTeacherName: '',
   dormitoryBuilding: '',
   dormitoryRoom: '',
+  extField1: '', // 床位ID
 
   // // 银行卡信息字段
   bankCardNo: '',
@@ -1873,6 +1893,152 @@ const getDormBuildingName = (id: string | number) => {
   return findBuildingName(dormBuildingOptions.value, id) || String(id);
 };
 
+/** 根据房间ID获取房间名称 */
+const getRoomName = async (roomId: string | number): Promise<string> => {
+  if (!roomId) return '';
+
+  // 检查缓存
+  if (roomCache.value.has(roomId)) {
+    return roomCache.value.get(roomId) || '';
+  }
+
+  try {
+    // 调用房间信息接口
+    const res = await service.get(`/xgss/dormRoom/${roomId}`);
+    if (res && res.code === 200 && res.data) {
+      const roomName = res.data.roomName || res.data.roomCode || String(roomId);
+      // 缓存结果
+      roomCache.value.set(roomId, roomName);
+      return roomName;
+    }
+  } catch (error) {
+    console.error('获取房间信息失败:', error);
+  }
+
+  // 如果获取失败,返回ID并缓存
+  roomCache.value.set(roomId, String(roomId));
+  return String(roomId);
+};
+
+/** 根据床位ID获取床位名称 */
+const getBedName = async (bedId: string | number): Promise<string> => {
+  if (!bedId) return '';
+
+  // 检查缓存
+  if (bedCache.value.has(bedId)) {
+    return bedCache.value.get(bedId) || '';
+  }
+
+  try {
+    // 调用床位信息接口
+    const res = await service.get(`/dormbed/dormBed/${bedId}`);
+    if (res && res.code === 200 && res.data) {
+      const bedName = res.data.bedName || res.data.bedCode || String(bedId);
+      // 缓存结果
+      bedCache.value.set(bedId, bedName);
+      return bedName;
+    }
+  } catch (error) {
+    console.error('获取床位信息失败:', error);
+  }
+
+  // 如果获取失败,返回ID并缓存
+  bedCache.value.set(bedId, String(bedId));
+  return String(bedId);
+};
+
+/** 获取房间显示名称(同步方法,用于弹窗显示) */
+const getRoomDisplayName = (roomId: string | number): string => {
+  if (!roomId) return '-';
+
+  // 优先从缓存中获取
+  if (roomCache.value.has(roomId)) {
+    return roomCache.value.get(roomId) || String(roomId);
+  }
+
+  // 如果缓存中没有,返回ID,并异步加载
+  setTimeout(() => {
+    getRoomName(roomId);
+  }, 0);
+
+  return String(roomId);
+};
+
+/** 获取床位显示名称(同步方法,用于弹窗显示) */
+const getBedDisplayName = (bedId: string | number): string => {
+  if (!bedId) return '-';
+
+  // 优先从缓存中获取
+  if (bedCache.value.has(bedId)) {
+    return bedCache.value.get(bedId) || String(bedId);
+  }
+
+  // 如果缓存中没有,返回ID,并异步加载
+  setTimeout(() => {
+    getBedName(bedId);
+  }, 0);
+
+  return String(bedId);
+};
+
+/** 预加载房间信息 */
+const preloadRoomInfo = async () => {
+  if (!studentList.value || studentList.value.length === 0) return;
+
+  // 收集所有需要查询的房间ID(兼容不同的字段名)
+  const roomIds = studentList.value
+    .map((student) => (student as any).dormitoryRoom || (student as any).dormitory_room)
+    .filter((roomId) => roomId && !roomCache.value.has(roomId));
+
+  if (roomIds.length === 0) return;
+
+  // 批量查询房间信息
+  const uniqueRoomIds = [...new Set(roomIds)];
+
+  for (const roomId of uniqueRoomIds) {
+    try {
+      const res = await service.get(`/xgss/dormRoom/${roomId}`);
+      if (res && res.code === 200 && res.data) {
+        const roomName = res.data.roomName || res.data.roomCode || String(roomId);
+        roomCache.value.set(roomId, roomName);
+      } else {
+        roomCache.value.set(roomId, String(roomId));
+      }
+    } catch (error) {
+      console.error(`获取房间信息失败,房间ID: ${roomId}`, error);
+      roomCache.value.set(roomId, String(roomId));
+    }
+  }
+};
+
+/** 预加载床位信息 */
+const preloadBedInfo = async () => {
+  if (!studentList.value || studentList.value.length === 0) return;
+
+  // 收集所有需要查询的床位ID(从extField1字段获取)
+  const bedIds = studentList.value.map((student) => (student as any).extField1).filter((bedId) => bedId && !bedCache.value.has(bedId));
+
+  if (bedIds.length === 0) return;
+
+  // 批量查询床位信息
+  const uniqueBedIds = [...new Set(bedIds)];
+
+  for (const bedId of uniqueBedIds) {
+    try {
+      const res = await service.get(`/dormbed/dormBed/${bedId}`);
+      if (res && res.code === 200 && res.data) {
+        const bedName = res.data.bedName || res.data.bedCode || String(bedId);
+        bedCache.value.set(bedId, bedName);
+      } else {
+        bedCache.value.set(bedId, String(bedId));
+      }
+    } catch (error) {
+      console.error(`获取床位信息失败,床位ID: ${bedId}`, error);
+      bedCache.value.set(bedId, String(bedId));
+    }
+  }
+};
+
 /** 根据行政区划代码获取完整路径(省/市/区) */
 const getRegionFullPath = (code: string): string => {
   if (!code || !regionOptions.value) return code || '';
@@ -1940,6 +2106,11 @@ const getList = async () => {
     if (res && res.code === 200) {
       studentList.value = res.rows || [];
       total.value = res.total || 0;
+
+      // 预加载房间信息
+      await preloadRoomInfo();
+      // 预加载床位信息
+      await preloadBedInfo();
     } else {
       ElMessage.error(res?.msg || '查询学生列表失败');
       studentList.value = [];