yjwang 1 日 前
コミット
2aae9bee0b
1 ファイル変更399 行追加196 行削除
  1. 399 196
      src/views/course/userCoursePeriod/index.vue

+ 399 - 196
src/views/course/userCoursePeriod/index.vue

@@ -94,7 +94,7 @@
             />
           </el-form-item>
           <el-form-item label="公司" prop="companyIdList">
-            <el-select v-model="queryParams.companyIdList" placeholder="请选择公司" clearable filterable size="small" multiple>
+            <el-select v-model="queryParams.companyIdList"  filterable placeholder="请选择公司" clearable size="small" multiple>
               <el-option
                 v-for="item in companyOptions"
                 :key="item.companyId"
@@ -157,6 +157,16 @@
               :disabled="batchSetRedPacketDisabled"
             >批量设置红包</el-button>
           </el-col>
+          <el-col :span="1.5">
+            <el-button
+              type="primary"
+              plain
+              icon="el-icon-plus"
+              size="mini"
+              @click="handleAddExistCampPeriod"
+              v-hasPermi="['course:period:add']"
+            >复制现有营期</el-button>
+          </el-col>
           <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
         </el-row>
 
@@ -232,7 +242,7 @@
           <el-input v-model="form.periodName" placeholder="请输入营期名称" />
         </el-form-item>
         <el-form-item label="公司" prop="companyId">
-          <el-select v-model="form.companyId" placeholder="请选择公司" multiple filterable>
+          <el-select v-model="form.companyId" placeholder="请选择公司" filterable clearable multiple>
             <el-option
               v-for="item in companyOptions"
               :key="item.companyId"
@@ -367,32 +377,14 @@
           </el-select>
         </el-form-item>
         <el-form-item label="小节" prop="videoIds">
-          <div style="display: flex; align-items: center;">
-            <el-select
-              filterable
-              v-model="course.form.videoIds"
-              placeholder="请选择小节"
-              :multiple-limit="getDiff(course.row.periodStartingTime, course.row.periodEndTime) - course.total"
-              multiple
-              clearable
-              size="small"
-              style="flex: 1; margin-right: 10px;"
-              :value-key="'dictValue'">
-              <el-option
-                v-for="dict in videoList"
-                :key="dict.dictValue"
-                :label="dict.dictLabel"
-                :value="parseInt(dict.dictValue)"
-              />
-            </el-select>
-            <el-button
-              type="primary"
-              size="small"
-              @click="selectAllVideos"
-              :disabled="videoList.length === 0 || !course.form.courseId">
-              全选
-            </el-button>
-          </div>
+          <el-select filterable  v-model="course.form.videoIds" placeholder="请选择小节" :multiple-limit="getDiff(course.row.periodStartingTime, course.row.periodEndTime) - course.total" multiple clearable size="small" style="width: 100%" :value-key="'dictValue'">
+            <el-option
+              v-for="dict in videoList"
+              :key="dict.dictValue"
+              :label="dict.dictLabel"
+              :value="parseInt(dict.dictValue)"
+            />
+          </el-select>
         </el-form-item>
         <el-form-item label="看课时间" prop="timeRange">
           <el-time-picker
@@ -457,44 +449,22 @@
           </el-date-picker>
           <p style="color: red;margin: 0;font-size: 12px">超过领取红包时间,只允许看课,不允许领取红包</p>
         </el-form-item>
-        <!--  是否批量修改开关 0-关 1-开 默认关闭 -->
-      </el-form>
-      <el-form>
-        <el-form-item label="是否批量修改" prop="batchUpdateSwitch" label-width="110px">
-          <el-radio-group
-            v-model="updateCourse.form.batchUpdateSwitch"
-          >
-            <el-radio :label="0">关</el-radio>
-            <el-radio :label="1">开</el-radio>
-          </el-radio-group>
-          <br />
-          <span style="color: red;margin: 0;font-size: 12px">批量修改开关开启后,后续的课程会默认+1修改课程和红包时间</span>
-        </el-form-item>
       </el-form>
-
       <div slot="footer" class="dialog-footer">
         <el-button type="primary" @click="submitUpdateCourseForm">确 定</el-button>
         <el-button @click="closeUpdateCourse">取 消</el-button>
       </div>
     </el-dialog>
 
-    <el-dialog title="修改营期时间" :visible.sync="updatePeriodDate.open" width="550px" append-to-body>
-      <el-form ref="courseUpdateForm" :model="updatePeriodDate.form" label-width="120px">
-        <el-form-item v-if="updatePeriodDate.ids.length > 1" label="已选课程数">
-          <span>{{ updatePeriodDate.ids.length }} 个课程将统一修改</span>
-        </el-form-item>
-        <el-form-item label="营期时间" prop="timeRange">
+    <el-dialog title="修改营期时间" :visible.sync="updatePeriodDate.open" width="500px" append-to-body>
+      <el-form ref="courseUpdateForm" :model="updatePeriodDate.form" label-width="100px">
+        <el-form-item label="营期时间" prop="dayDate">
           <el-date-picker
-            v-model="updatePeriodDate.form.timeRange"
-            type="datetimerange"
-            range-separator="至"
-            start-placeholder="开始时间"
-            end-placeholder="结束时间"
-            value-format="yyyy-MM-dd HH:mm:ss"
-            format="yyyy-MM-dd HH:mm:ss"
-            :default-time="['00:00:00', '23:59:59']"
-            placeholder="选择时间范围"
-            style="width: 100%">
+            v-model="updatePeriodDate.form.dayDate"
+            :selectableRange="updatePeriodDate.form.dayDate"
+            value-format="yyyy-MM-dd"
+            type="date"
+            placeholder="选择日期">
           </el-date-picker>
         </el-form-item>
       </el-form>
@@ -535,14 +505,14 @@
                   v-hasPermi="['course:period:addCourse']"
                 >添加课程</el-button>
               </el-col>
-              <el-col :span="1.5">
-                <el-button
-                  type="primary"
-                  size="mini"
-                  :disabled="updateCourse.ids.length <= 0"
-                  @click="handleUpdatePeriodDate"
-                >修改营期时间</el-button>
-              </el-col>
+              <!--            <el-col :span="1.5">-->
+              <!--              <el-button-->
+              <!--                type="primary"-->
+              <!--                size="mini"-->
+              <!--                :disabled="updateCourse.ids.length <= 0"-->
+              <!--                @click="handleUpdatePeriodDate"-->
+              <!--              >修改营期时间</el-button>-->
+              <!--            </el-col>-->
               <el-col :span="1.5">
                 <el-button
                   type="primary"
@@ -640,13 +610,6 @@
               :active="activeTab === 'statistics'"
             />
           </el-tab-pane>
-
-          <el-tab-pane label="课程数据" name="courseStatistics">
-            <course-statistics-data
-              :periodId="periodSettingsData.periodId"
-              :active="activeTab === 'courseStatistics'"
-            />
-          </el-tab-pane>
         </el-tabs>
       </div>
     </el-drawer>
@@ -657,27 +620,125 @@
       @success="handleBatchRedPacketSuccess"
     />
 
+    <el-dialog
+      :title="addExistCampPeriodName"
+      :visible.sync="addExistCampPeriod"
+      width="1000px"
+      append-to-body
+      @close="handleDialogClose"
+    >
+      <el-form ref="createCampPeriodForm" :model="createCampPeriodForm" :rules="campRules" label-width="500px">
+        <el-form-item label="营期创建方式" prop="campPeriodType">
+          <el-radio-group v-model="createCampPeriodForm.campPeriodType" @change="handlePeriodTypeChange">
+            <el-radio :label="1">从当前训练营复制</el-radio>
+            <el-radio :label="2">从其他训练营复制</el-radio>
+            <el-radio :label="3">我要新建一个训练营</el-radio>
+          </el-radio-group>
+        </el-form-item>
+
+        <!-- 从当前训练营复制 -->
+        <el-form-item
+          v-if="createCampPeriodForm.campPeriodType === 1"
+          label="选择当前营期"
+          prop="periodId"
+        >
+          <el-select
+            v-model="createCampPeriodForm.periodId"
+            placeholder="请选择当前营期"
+            clearable
+          >
+            <el-option
+              v-for="item in currentCampPeriods"
+              :key="item.periodId"
+              :label="item.periodName"
+              :value="item.periodId"
+            />
+          </el-select>
+        </el-form-item>
+
+        <!-- 从其他训练营复制 -->
+        <el-form-item
+          v-if="createCampPeriodForm.campPeriodType === 2"
+          label="选择其他营期"
+          prop="periodId"
+        >
+          <el-select
+            v-model="createCampPeriodForm.trainingCampId"
+            placeholder="请选择训练营"
+            :loading="loadingNew"
+            clearable
+            filterable
+            @change="handleTrainingCampChange"
+          >
+            <el-option
+              v-for="item in trainingCampList"
+              :key="item.trainingCampId"
+              :label="item.trainingCampName"
+              :value="item.trainingCampId"
+            />
+          </el-select>
+
+          <el-select
+            v-model="createCampPeriodForm.periodId"
+            placeholder="请选择营期"
+            :loading="loadingNew"
+            clearable
+            filterable
+          >
+            <el-option
+              v-for="item in otherCampPeriods"
+              :key="item.periodId"
+              :label="item.periodName"
+              :value="item.periodId"
+            />
+          </el-select>
+
+          <div v-if="loadingNew" class="loading-text">
+            <i class="el-icon-loading"></i> 加载中...
+          </div>
+        </el-form-item>
+
+        <!-- 新建营期 -->
+        <el-form-item
+          v-if="createCampPeriodForm.campPeriodType === 3"
+          label="新建营期名称"
+          prop="trainingCampName"
+        >
+          <el-input
+            v-model="createCampPeriodForm.trainingCampName"
+            placeholder="请输入新训练营名称"
+            style="width: 300px"
+            maxlength="50"
+            show-word-limit
+          />
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="copySubmitCampForm" :loading="submitLoading">确 定</el-button>
+        <el-button @click="cancelExistCampPeriod" :disabled="submitLoading">取 消</el-button>
+      </div>
+    </el-dialog>
+
   </div>
 </template>
 
 <script>
-import {addPeriod, delPeriod, exportPeriod, getPeriod, pagePeriod, updatePeriod, getDays, addCourse,delPeriodDay,  updateCourseTime, updateCourseDate, updateListCourseData, periodCourseMove, closePeriod} from "@/api/course/userCoursePeriod";
+import {addPeriod, delPeriod, exportPeriod, getPeriod, pagePeriod, updatePeriod, getDays, addCourse,delPeriodDay,  updateCourseTime, updateCourseDate, updateListCourseData, periodCourseMove, closePeriod, batchAddCourseSections,copyExistCampPeriod, updateOrderNumber} from "@/api/course/userCoursePeriod";
 import {getCompanyList} from "@/api/company/company";
-import { listCamp, addCamp, editCamp, delCamp, copyCamp } from "@/api/course/userCourseCamp";
+import { listCamp, addCamp, editCamp, delCamp, copyCamp, getScreeningCampPeriod, updateCampOrderNumber} from "@/api/course/userCourseCamp";
 import { courseList,videoList } from '@/api/course/courseRedPacketLog'
 import RedPacket from './redPacket.vue'
 import BatchRedPacket from './batchRedPacket.vue'
 import CourseStatistics from './statistics.vue'
-import CourseStatisticsData from './statistics.vue'
 import Da from "element-ui/src/locale/lang/da";
 import { getConfigByKey } from '@/api/system/config'
+import {listUserCourse} from "@/api/course/userCourse";
 export default {
   name: "Period",
   components: {
     RedPacket,
     BatchRedPacket,
-    CourseStatistics,
-    CourseStatisticsData
+    CourseStatistics
   },
   data() {
     return {
@@ -744,11 +805,9 @@ export default {
       //修改营期时间参数
       updatePeriodDate: {
         open: false,
-        loading: false,
+        loading: true,
         ids: [],
-        form: {
-          timeRange: null
-        },
+        form: {},
       },
       joinTimeSwitch:true,
       updateCourse: {
@@ -757,8 +816,7 @@ export default {
         ids: [],
         form: {
           timeRange: null,
-          joinTime: null,
-          batchUpdateSwitch: 0
+          joinTime: null
         },
       },
       // 表单校验
@@ -894,6 +952,26 @@ export default {
       batchSetRedPacketDisabled: true,
       // 批量设置红包弹出框
       batchRedPacketVisible: false,
+      //课程选择
+      courseSelection: [],
+      courseSelectionIsAdd: true, // 默认新增状态,编辑时会设为false
+      // 训练营对话框是否显示
+      addExistCampPeriod: false,
+      addExistCampPeriodName: "新增已存在营期",
+      loadingNew: false,
+      submitLoading: false,
+      // 表单数据
+      createCampPeriodForm: {
+        campPeriodType: 1,
+        periodId: null,
+        trainingCampName: null,
+      },
+      // 数据列表
+      currentCampPeriods: [],    // 当前训练营的期数列表
+      otherCampPeriods: [],      // 其他训练营的期数列表
+      // 缓存数据避免重复请求
+      periodDataCache: new Map(),
+      trainingCampList:[],
     };
   },
   created() {
@@ -904,12 +982,13 @@ export default {
     // this.getList();
     this.getLeftList();
     this.getCompanyList();
+    /** 获取课程下拉框*/
+    listUserCourse().then(response => {
+      this.courseSelection = response.rows;
+    });
 
   },
   methods: {
-    selectAllVideos() {
-      this.course.form.videoIds = this.videoList.map(video => parseInt(video.dictValue));
-    },
     /** 删除按钮操作 */
     async handleDeleteCourse(row) {
       const periodDayIds = row.id || this.updateCourse.ids;
@@ -1341,6 +1420,7 @@ export default {
       // 加载对应的训练营营期数据
       const selectedCamp = this.campList[index];
       this.queryParams.trainingCampId = selectedCamp.trainingCampId;
+      this.trainingCampIdValue=selectedCamp.trainingCampId;
       this.getList();
     },
     /** 处理滚动事件,实现滚动到底部加载更多 */
@@ -1628,36 +1708,11 @@ export default {
       });
     },
     updatePeriodDateSubmit(){
-      const form = this.updatePeriodDate.form;
-      if (!form.timeRange || !Array.isArray(form.timeRange) || form.timeRange.length !== 2) {
-        this.$message.warning('请选择完整的营期开始时间和结束时间');
-        return;
-      }
-      const [startDateTime, endDateTime] = form.timeRange;
-      if (startDateTime >= endDateTime) {
-        this.$message.warning('开始时间必须早于结束时间');
-        return;
-      }
-      const ids = this.updatePeriodDate.ids;
-      if (!ids || ids.length === 0) {
-        this.$message.warning('请选择要修改的课程');
-        return;
-      }
-      updateCourseDate({
-        ids: ids,
-        startDateTime: startDateTime,
-        endDateTime: endDateTime
-      }).then(response => {
-        if (response.code === 200) {
-          this.$message.success('修改成功');
-          this.updatePeriodDate.open = false;
-          this.updatePeriodDate.form.timeRange = null;
-          this.getCourseList();
-        } else {
-          this.$message.error(response.msg || '修改失败');
-        }
-      }).catch(() => {
-        this.$message.error('修改失败');
+      updateCourseDate(this.updatePeriodDate.form).then(response => {
+        this.$message.success('修改成功');
+        this.updatePeriodDate.open = false;
+        // 重新加载课程列表
+        this.getCourseList();
       });
     },
     // saveCourseData(){
@@ -1787,29 +1842,9 @@ export default {
       };
       return statusMap[row.status] || '未知状态';
     },
-    /** 单行修改营期时间 */
+    /** 营期状态格式化 */
     handleUpdateDate(row) {
-      this.updatePeriodDate.ids = [row.id];
-      this.updatePeriodDate.form = {
-        timeRange: row.startDateTime && row.endDateTime ? [row.startDateTime, row.endDateTime] : null
-      };
-      this.updatePeriodDate.open = true;
-    },
-    /** 批量修改营期时间 */
-    handleUpdatePeriodDate() {
-      const ids = this.updateCourse.ids;
-      if (!ids || ids.length === 0) {
-        this.$message.warning('请先选择要修改的课程');
-        return;
-      }
-      this.updatePeriodDate.ids = [...ids];
-      // 取第一个选中行的开始和结束时间作为默认值
-      const firstRow = this.course.list.find(item => item.id === ids[0]);
-      this.updatePeriodDate.form = {
-        timeRange: firstRow && firstRow.startDateTime && firstRow.endDateTime
-          ? [firstRow.startDateTime, firstRow.endDateTime]
-          : null
-      };
+      this.updatePeriodDate.form = {id: row.id, dayDate: row.dayDate};
       this.updatePeriodDate.open = true;
     },
     // disabledDate(time) {
@@ -1835,37 +1870,245 @@ export default {
       // 强制更新组件以刷新领取红包时间的可选范围
       this.$forceUpdate();
     },
+    /** 新建存在训练营按钮操作 */
+    handleAddExistCampPeriod() {
+      this.resetForm();
+      this.addExistCampPeriod = true;
+      // 初始化当前训练营的期数列表
+      this.initCurrentCampPeriods();
+    },
+    /** 初始化当前训练营期数列表 */
+    initCurrentCampPeriods() {
+      // 对当前营期列表按照创建时间倒序排序(最新的在前面)
+      this.currentCampPeriods = [...(this.periodList || [])].sort((a, b) => {
+        // 如果没有创建时间,按原始顺序
+        if (!a.createTime || !b.createTime) return 0;
+
+        // 将时间字符串转换为时间戳进行比较
+        const timeA = new Date(a.createTime).getTime();
+        const timeB = new Date(b.createTime).getTime();
+
+        // 按创建时间倒序排列(最新的在前面)
+        return timeB - timeA;
+      });
+    },
+    /** 处理创建方式变更 */
+    async handlePeriodTypeChange(value) {
+      this.createCampPeriodForm.periodId = null;
+      this.createCampPeriodForm.trainingCampName = null;
+      if (value === 1) {
+        // 从当前训练营复制 - 使用本地数据
+        this.initCurrentCampPeriods();
+      } else if (value === 2) {
+        // 从其他训练营复制 - 需要请求接口
+        await this.loadOtherCampPeriods();
+      }
+    },
+    /** 加载其他训练营期数列表 */
+    async loadOtherCampPeriods() {
+      // 清空营期数据和选中项,避免显示旧数据
+      this.otherCampPeriods = [];
+      this.createCampPeriodForm.periodId = ''; // 清空已选营期
+      this.createCampPeriodForm.trainingCampId = ''; // 清空已选训练营
+
+      // 检查缓存 - 使用固定键名,因为训练营列表不依赖当前训练营ID
+      // const cacheKey = 'trainingCampList';
+      // if (this.periodDataCache.has(cacheKey)) {
+      //   this.trainingCampList = this.periodDataCache.get(cacheKey);
+      //   return;
+      // }
+
+      this.loadingNew = true;
+      try {
+        const requestParams = {
+          periodId: this.trainingCampIdValue,
+          campPeriodType: this.createCampPeriodForm.campPeriodType
+        };
+        const response = await getScreeningCampPeriod(requestParams);
+        if (response && Array.isArray(response.resultList)) {
+          this.trainingCampList = response.resultList;
+          // 缓存数据 - 使用固定键名
+          //this.periodDataCache.set(cacheKey, response.resultList);
+        } else {
+          console.warn('接口返回格式异常:', response);
+          this.trainingCampList = [];
+        }
+      } catch (error) {
+        console.error('接口请求失败:', error);
+        this.$message.error('查询失败,请重试');
+        this.trainingCampList = [];
+      } finally {
+        this.loadingNew = false;
+      }
+    },
+    /** 对话框关闭事件 */
+    handleDialogClose() {
+      this.resetForm();
+    },
+    /** 重置表单 */
+    resetForm() {
+      this.createCampPeriodForm = {
+        campPeriodType: 1,
+        periodId: null,
+        trainingCampName: null,
+      };
+
+      this.currentCampPeriods = [];
+      this.otherCampPeriods = [];
+      this.trainingCampList=[]
+      this.loading = false;
+      this.submitLoading = false;
+
+      // 清除表单验证
+      if (this.$refs.createCampPeriodForm) {
+        this.$refs.createCampPeriodForm.clearValidate();
+      }
+    },
+    handleTrainingCampChange(trainingCampId){
+      this.otherCampPeriods = [];
+      this.createCampPeriodForm.periodId = '';
+      const params = {
+        ...this.queryParams,
+        trainingCampId: trainingCampId  // 更新训练营ID
+      };
+      pagePeriod(params).then(response => {
+        if (response.code === 200) {
+          this.otherCampPeriods = response.rows;
+        } else {
+          this.$message.error(response.msg || '查询营期失败');
+        }
+      }).catch(error => {
+        this.$message.error('查询营期失败: ' + (error.message || '查询营期失败'));
+      });
+    },
+    /** 提交表单 */
+    copySubmitCampForm() {
+      try {
+        // 表单验证
+        const valid =  this.$refs.createCampPeriodForm.validate();
+        if (!valid) return ;
+        this.submitLoading = true;
+        const submitData = this.buildSubmitData();
+        if (submitData.campPeriodType===3){
+          // 新增训练营
+          addCamp(submitData).then(response => {
+            if (response.code === 200) {
+              this.$message.success('新建训练营成功');
+              this.addExistCampPeriod = false;
+              // 重新加载训练营列表
+              this.getLeftList();
+            } else {
+              this.$message.error(response.msg || '新建训练营失败');
+            }
+          }).catch(error => {
+            this.$message.error('新建训练营失败: ' + (error.message || '未知错误'));
+          });
+        }else {
+          // 显示全屏加载圈和遮蔽层
+          const loadingInstance = this.$loading({
+            lock: true,
+            text: '复制营期中,请耐心等待...',
+            spinner: 'el-icon-loading',
+            background: 'rgba(0, 0, 0, 0.7)'
+          });
+          // 调用批量添加小节接口
+          copyExistCampPeriod(submitData).then(response => {
+            if (response.code === 200) {
+              this.$message.success('复制营期成功');
+              this.course.addOpen = false;
+              this.addExistCampPeriod = false;
+              // 重新加载训练营列表
+              this.getList();
+            } else {
+              this.$message.error(response.msg || '复制营期失败');
+            }
+          }).catch(error => {
+            this.$message.error('复制营期失败:' + (error.message || '未知错误'));
+          }).finally(() => {
+            loadingInstance.close();   // 关闭加载圈
+          });
+        }
+      } catch (error) {
+        this.$message.error('提交失败:' + (error.message || '未知错误'));
+      } finally {
+        this.submitLoading = false;
+      }
+    },
+    /** 组装提交数据 */
+    buildSubmitData() {
+      const { campPeriodType, periodId, trainingCampName } = this.createCampPeriodForm;
+      const baseData = {
+        campPeriodType,
+        trainingCampId: this.trainingCampIdValue  // 这里已经正确添加了 trainingCampId
+      };
+      switch (campPeriodType) {
+        case 1: // 从当前训练营复制
+        case 2: // 从其他训练营复制
+          if (!periodId) {
+            throw new Error('请选择要复制的营期');
+          }
+          return { ...baseData, periodId };
+        case 3: // 新建营期
+          if (!trainingCampName?.trim()) {
+            throw new Error('请输入营期名称');
+          }
+          return { ...baseData, trainingCampName: trainingCampName.trim() };
+        default:
+          throw new Error('未知的创建方式');
+      }
+    },
+    /** 取消新建存在训练营 */
+    cancelExistCampPeriod() {
+      this.addExistCampPeriod = false;
+      this.resetForm();
+    },
+    /** 更新训练营序号 */
+    updateCampOrderNumber(item) {
+      // 校验序号值
+      if (!item.orderNumber || item.orderNumber < 1 || item.orderNumber > 9999) {
+        this.$message.warning('请输入有效的序号(1-9999)');
+        return;
+      }
+
+      // 调用接口更新序号,使用params传参
+      const params = {
+        trainingCampId: item.trainingCampId,
+        orderNumber: item.orderNumber
+      };
+
+      updateCampOrderNumber(params).then(response => {
+        if (response.code === 200) {
+          this.$message.success('训练营序号更新成功');
+          // 刷新训练营列表以保持排序一致(序号越大排在越前面)
+          this.getLeftList();
+        } else {
+          this.$message.error(response.msg || '训练营序号更新失败');
+          // 更新失败时刷新列表,恢复原值
+          this.getLeftList();
+        }
+      }).catch(error => {
+        this.$message.error('训练营序号更新失败:' + (error.message || '未知错误'));
+        // 更新失败时刷新列表,恢复原值
+        this.getLeftList();
+      });
+    },
   },
 };
 </script>
 
 <style scoped>
-/* 全局高度重置(确保父容器有明确高度) */
-html, body, #app {
-  height: 100%;
-  margin: 0;
-  padding: 0;
-}
-
-.app-container {
-  height: 100%;
-  overflow: hidden;
-}
-
 .left-aside {
   background-color: #fff;
   border-right: 1px solid #EBEEF5;
   padding: 0;
   display: flex;
   flex-direction: column;
-  height: 100%;          /* 改为相对父容器高度,而不是固定 calc */
-  overflow: hidden;
+  height: 800px;
 }
 
 .left-header {
   padding: 10px;
   border-bottom: 1px solid #EBEEF5;
-  flex-shrink: 0;        /* 防止头部被压缩 */
 }
 
 .left-header-top {
@@ -1936,31 +2179,10 @@ html, body, #app {
 
 .camp-list {
   flex: 1;
-  overflow-y: auto !important;
-  min-height: 0;
+  overflow-y: auto;
   padding: 3px;
-  scrollbar-gutter: stable;
-  height: 500px;  /* 添加固定高度,可根据需要调整 */
-  max-height: 500px;  /* 限制最大高度 */
-}
-
-.camp-list::-webkit-scrollbar {
-  width: 8px;
-}
-
-.camp-list::-webkit-scrollbar-track {
-  background: #f1f1f1;
-  border-radius: 4px;
 }
 
-.camp-list::-webkit-scrollbar-thumb {
-  background: #c1c1c1;
-  border-radius: 4px;
-}
-
-.camp-list::-webkit-scrollbar-thumb:hover {
-  background: #909399;
-}
 .camp-item {
   margin-bottom: 5px;
   padding: 15px;
@@ -2082,30 +2304,11 @@ html, body, #app {
 
 .el-main {
   padding: 10px;
-  overflow: hidden;
-  display: flex;
-  flex-direction: column;
-  height: 100%;          /* 确保右侧也占满 */
-}
-
-/* 确保容器高度稳定 - 左右两侧固定高度,不被内容撑开 */
-.app-container >>> .el-container {
-  height: 100%;
-  overflow: hidden;
-}
-
-.app-container >>> .el-aside {
-  height: 100%;
-  overflow: hidden;
-}
-
-.app-container >>> .el-main {
-  height: 100%;
-  overflow-y: auto;
 }
 
 /* 添加训练营表单样式 */
 .drawer-footer {
+  /* position: absolute; */
   bottom: 0;
   left: 0;
   right: 0;