<template> 
 | 
  <div class="app-container scheduling-container"> 
 | 
    <!-- 筛选区域 --> 
 | 
    <div class="filter-section"> 
 | 
      <el-form :inline="true" :model="filterForm" class="filter-form"> 
 | 
        <el-form-item label="员工姓名:"> 
 | 
          <el-input 
 | 
              v-model="filterForm.staffName" 
 | 
              placeholder="请输入员工姓名" 
 | 
              clearable 
 | 
              style="width: 150px" 
 | 
          /> 
 | 
        </el-form-item> 
 | 
        <el-form-item label="班次类型:"> 
 | 
          <el-select v-model="filterForm.shiftType" placeholder="请选择班次" clearable style="width: 120px"> 
 | 
            <el-option v-for="item in shift_type" :label="item.label" :value="item.value" :key="item.value"/> 
 | 
          </el-select> 
 | 
        </el-form-item> 
 | 
        <el-form-item label="日期范围:"> 
 | 
          <el-date-picker 
 | 
              v-model="filterForm.dateRange" 
 | 
              type="daterange" 
 | 
              range-separator="至" 
 | 
              start-placeholder="开始日期" 
 | 
              end-placeholder="结束日期" 
 | 
              format="YYYY-MM-DD" 
 | 
              value-format="YYYY-MM-DD" 
 | 
              style="width: 250px" 
 | 
          /> 
 | 
        </el-form-item> 
 | 
        <el-form-item> 
 | 
          <el-button type="primary" @click="handleFilter"> 
 | 
            <el-icon><Search/></el-icon> 
 | 
            筛选 
 | 
          </el-button> 
 | 
          <el-button @click="resetFilter"> 
 | 
            <el-icon><Refresh/></el-icon> 
 | 
            重置 
 | 
          </el-button> 
 | 
          <el-button @click="handleExport"> 
 | 
            <el-icon><Download/></el-icon> 
 | 
            导出 
 | 
          </el-button> 
 | 
          <el-button type="primary" @click="openScheduleDialog('add')"> 
 | 
          <el-icon><Plus/></el-icon> 
 | 
          新增排班 
 | 
        </el-button> 
 | 
        </el-form-item> 
 | 
      </el-form> 
 | 
    </div> 
 | 
  
 | 
    <!-- 排班表格 --> 
 | 
    <div class="table-section"> 
 | 
      <el-table 
 | 
          :data="scheduleList" 
 | 
          border 
 | 
          :loading="tableLoading" 
 | 
          stripe 
 | 
          style="width: 100%" 
 | 
          height="calc(100vh - 18.5em)" 
 | 
          @selection-change="handleSelectionChange" 
 | 
      > 
 | 
        <el-table-column type="selection" width="55"/> 
 | 
        <el-table-column prop="staffName" label="员工姓名" width="120"/> 
 | 
        <el-table-column prop="staffNo" label="员工工号" width="100"/> 
 | 
        <el-table-column prop="department" label="部门" width="120"> 
 | 
          <template #default="scope"> 
 | 
              {{ (department_type.find(i => i.value === String(scope.row.department)) || {}).label }} 
 | 
          </template> 
 | 
        </el-table-column> 
 | 
        <el-table-column prop="shiftType" label="班次类型" width="100"> 
 | 
          <template #default="scope"> 
 | 
            <el-tag :type="getShiftTagType(scope.row.shiftType)"> 
 | 
              {{ (shift_type.find(i => i.value === String(scope.row.shiftType)) || {}).label }} 
 | 
            </el-tag> 
 | 
          </template> 
 | 
        </el-table-column> 
 | 
        <el-table-column prop="workDate" label="工作日期" width="120"/> 
 | 
        <el-table-column prop="startTime" label="开始时间" width="100"/> 
 | 
        <el-table-column prop="endTime" label="结束时间" width="100"/> 
 | 
        <el-table-column prop="workHours" label="工作时长" width="100"> 
 | 
          <template #default="scope"> 
 | 
            {{ scope.row.workHours }}小时 
 | 
          </template> 
 | 
        </el-table-column> 
 | 
        <el-table-column prop="status" label="状态" width="100"> 
 | 
          <template #default="scope"> 
 | 
            <el-tag :type="getStatusTagType(scope.row.status)"> 
 | 
              {{ (schedule_status.find(i => i.value === String(scope.row.status)) || {}).label }} 
 | 
            </el-tag> 
 | 
          </template> 
 | 
        </el-table-column> 
 | 
        <el-table-column prop="remark" label="备注" min-width="150"/> 
 | 
        <el-table-column label="操作" width="200" fixed="right"> 
 | 
          <template #default="scope"> 
 | 
            <el-button 
 | 
                type="primary" 
 | 
                size="small" 
 | 
                @click="openScheduleDialog('edit', scope.row)" 
 | 
            > 
 | 
              编辑 
 | 
            </el-button> 
 | 
            <el-button 
 | 
                type="danger" 
 | 
                size="small" 
 | 
                @click="handleDelete(scope.row)" 
 | 
            > 
 | 
              删除 
 | 
            </el-button> 
 | 
          </template> 
 | 
        </el-table-column> 
 | 
      </el-table> 
 | 
        <pagination 
 | 
            v-if="tableCount > 0" 
 | 
            :total="tableCount" 
 | 
            :page="filterForm.current" 
 | 
            :limit="filterForm.size" 
 | 
            @pagination="paginationChange" 
 | 
        /> 
 | 
    </div> 
 | 
  
 | 
    <!-- 批量操作 --> 
 | 
    <div class="batch-actions" v-if="selectedRows.length > 0"> 
 | 
      <el-button 
 | 
          type="danger" 
 | 
          @click="handleBatchDelete" 
 | 
          :disabled="selectedRows.length === 0" 
 | 
      > 
 | 
        批量删除 ({{ selectedRows.length }}) 
 | 
      </el-button> 
 | 
    </div> 
 | 
  
 | 
    <!-- 排班新增/编辑对话框 --> 
 | 
    <el-dialog 
 | 
        v-model="scheduleDialog" 
 | 
        :title="dialogType === 'add' ? '新增排班' : '编辑排班'" 
 | 
        width="700px" 
 | 
        @close="closeScheduleDialog" 
 | 
    > 
 | 
      <el-form 
 | 
          :model="scheduleForm" 
 | 
          :rules="scheduleRules" 
 | 
          ref="scheduleFormRef" 
 | 
          label-width="120px" 
 | 
      > 
 | 
        <el-row :gutter="20"> 
 | 
          <el-col :span="12"> 
 | 
            <el-form-item label="员工姓名:" prop="staffId"> 
 | 
              <el-select v-model="scheduleForm.staffId" placeholder="请输入员工姓名" style="width: 100%" 
 | 
                         @change="handleSelectStaff"> 
 | 
                <el-option v-for="item in personList" :label="item.staffName" :value="item.id" :key="item.id"/> 
 | 
              </el-select> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
          <el-col :span="12"> 
 | 
            <el-form-item label="员工工号:" prop="staffNo"> 
 | 
              <el-input :disabled="true" v-model="scheduleForm.staffNo" placeholder=""/> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
        </el-row> 
 | 
  
 | 
        <el-row :gutter="20"> 
 | 
          <el-col :span="12"> 
 | 
            <el-form-item label="部门:" prop="department"> 
 | 
              <el-select v-model="scheduleForm.department" placeholder="请选择部门" style="width: 100%"> 
 | 
                <el-option v-for="item in department_type" :label="item.label" :value="item.value" :key="item.value"/> 
 | 
              </el-select> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
          <el-col :span="12"> 
 | 
            <el-form-item label="班次类型:" prop="shiftType"> 
 | 
              <el-select v-model="scheduleForm.shiftType" placeholder="请选择班次" style="width: 100%"> 
 | 
                <el-option v-for="item in shift_type" :label="item.label" :value="item.value" :key="item.value"/> 
 | 
              </el-select> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
        </el-row> 
 | 
  
 | 
        <el-row :gutter="20"> 
 | 
          <el-col :span="12"> 
 | 
            <el-form-item label="工作日期:" prop="workDate"> 
 | 
              <el-date-picker 
 | 
                  v-model="scheduleForm.workDate" 
 | 
                  type="date" 
 | 
                  placeholder="选择工作日期" 
 | 
                  style="width: 100%" 
 | 
                  format="YYYY-MM-DD" 
 | 
                  value-format="YYYY-MM-DD" 
 | 
              /> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
          <el-col :span="12"> 
 | 
            <el-form-item label="状态:" prop="status"> 
 | 
              <el-select v-model="scheduleForm.status" placeholder="请选择状态" style="width: 100%"> 
 | 
                <el-option v-for="item in schedule_status" :label="item.label" :value="item.value" :key="item.value"/> 
 | 
              </el-select> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
        </el-row> 
 | 
  
 | 
        <el-row :gutter="20"> 
 | 
          <el-col :span="12"> 
 | 
            <el-form-item label="开始时间:" prop="startTime"> 
 | 
              <el-time-picker 
 | 
                  v-model="scheduleForm.startTime" 
 | 
                  placeholder="选择开始时间" 
 | 
                  style="width: 100%" 
 | 
                  format="HH:mm" 
 | 
                  value-format="HH:mm" 
 | 
              /> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
          <el-col :span="12"> 
 | 
            <el-form-item label="结束时间:" prop="endTime"> 
 | 
              <el-time-picker 
 | 
                  v-model="scheduleForm.endTime" 
 | 
                  placeholder="选择结束时间" 
 | 
                  style="width: 100%" 
 | 
                  format="HH:mm" 
 | 
                  value-format="HH:mm" 
 | 
              /> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
        </el-row> 
 | 
  
 | 
        <el-row :gutter="20"> 
 | 
          <el-col :span="24"> 
 | 
            <el-form-item label="备注:" prop="remark"> 
 | 
              <el-input 
 | 
                  v-model="scheduleForm.remark" 
 | 
                  type="textarea" 
 | 
                  :rows="3" 
 | 
                  placeholder="请输入备注信息" 
 | 
              /> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
        </el-row> 
 | 
      </el-form> 
 | 
  
 | 
      <template #footer> 
 | 
        <div class="dialog-footer"> 
 | 
          <el-button type="primary" @click="submitScheduleForm">确认</el-button> 
 | 
          <el-button @click="closeScheduleDialog">取消</el-button> 
 | 
        </div> 
 | 
      </template> 
 | 
    </el-dialog> 
 | 
  </div> 
 | 
</template> 
 | 
  
 | 
<script setup> 
 | 
import {ref, reactive, computed, onMounted, getCurrentInstance} from 'vue' 
 | 
import {ElMessage, ElMessageBox} from 'element-plus' 
 | 
import {useDict} from "@/utils/dict.js" 
 | 
import {Plus, Download, Search, Refresh} from '@element-plus/icons-vue' 
 | 
import {save, del, delByIds, listPage} from "@/api/personnelManagement/scheduling.js" 
 | 
import {getStaffOnJob} from "@/api/personnelManagement/onboarding.js"; 
 | 
import dayjs from "dayjs"; 
 | 
import pagination from "@/components/PIMTable/Pagination.vue"; 
 | 
  
 | 
const { proxy } = getCurrentInstance(); 
 | 
  
 | 
const tableCount = ref(0) 
 | 
// 响应式数据 
 | 
const scheduleDialog = ref(false) 
 | 
const dialogType = ref('add') 
 | 
const selectedRows = ref([]) 
 | 
const scheduleFormRef = ref() 
 | 
  
 | 
// 筛选表单 
 | 
const filterForm = reactive({ 
 | 
  staffName: '', 
 | 
  shiftType: '', 
 | 
  dateRange: [], 
 | 
  current:1, 
 | 
  size: 10 
 | 
}) 
 | 
  
 | 
// 排班表单 
 | 
const scheduleForm = reactive({ 
 | 
  id: '', 
 | 
  staffId: '', 
 | 
  staffNo: '', 
 | 
  department: '', 
 | 
  shiftType: '', 
 | 
  workDate: '', 
 | 
  startTime: '', 
 | 
  endTime: '', 
 | 
  workStartTime: '', 
 | 
  workEndTime: '', 
 | 
  workHours: 0, 
 | 
  status: '', 
 | 
  remark: '' 
 | 
}) 
 | 
  
 | 
// 表单验证规则 
 | 
const scheduleRules = reactive({ 
 | 
  staffId: [{required: true, message: '请选择员工', trigger: 'change'}], 
 | 
  department: [{required: true, message: '请选择部门', trigger: 'change'}], 
 | 
  shiftType: [{required: true, message: '请选择班次类型', trigger: 'change'}], 
 | 
  workDate: [{required: true, message: '请选择工作日期', trigger: 'change'}], 
 | 
  startTime: [{required: true, message: '请选择开始时间', trigger: 'change'}], 
 | 
  endTime: [{required: true, message: '请选择结束时间', trigger: 'change'}], 
 | 
  status: [{required: true, message: '请选择状态', trigger: 'change'}] 
 | 
}) 
 | 
const tableLoading = ref(false) 
 | 
  
 | 
//字典 
 | 
const {department_type, schedule_status, shift_type} = useDict("department_type", "schedule_status", "shift_type") 
 | 
// 人员列表 
 | 
const personList = ref([]); 
 | 
  
 | 
// 模拟排班数据 
 | 
const scheduleList = ref([]) 
 | 
  
 | 
  
 | 
/** 
 | 
 * 获取当前在职人员列表 
 | 
 */ 
 | 
const getPersonList = () => { 
 | 
  getStaffOnJob().then(res => { 
 | 
    personList.value = res.data 
 | 
  }) 
 | 
}; 
 | 
const paginationChange = (obj) => { 
 | 
  filterForm.current = obj.page; 
 | 
  filterForm.size = obj.limit; 
 | 
  handleFilter(); 
 | 
}; 
 | 
  
 | 
const handleSelectStaff = (val) => { 
 | 
  let obj = personList.value.find(item => item.id === val) 
 | 
  scheduleForm.staffNo = obj.staffNo 
 | 
  
 | 
} 
 | 
  
 | 
// 获取班次标签类型 
 | 
const getShiftTagType = (shiftType) => { 
 | 
  const typeMap = Object.fromEntries(shift_type.value.map(i => [i.value, i.elTagType])) 
 | 
  return typeMap[shiftType] || 'info' 
 | 
} 
 | 
  
 | 
// 获取状态标签类型 
 | 
const getStatusTagType = (status) => { 
 | 
  const typeMap = Object.fromEntries(schedule_status.value.map(i => [i.value, i.elTagType])) 
 | 
  return typeMap[status] || 'info' 
 | 
} 
 | 
  
 | 
// 筛选 
 | 
const handleFilter = async () => { 
 | 
  tableLoading.value = true 
 | 
  let searchForm = { 
 | 
    ...filterForm, 
 | 
    ...(filterForm.dateRange.length > 0 && { 
 | 
      startDate: filterForm.dateRange[0], 
 | 
      endDate: filterForm.dateRange[1], 
 | 
    }) 
 | 
  } 
 | 
  let resp = await listPage(searchForm) 
 | 
  tableCount.value = resp.data.total 
 | 
  scheduleList.value = resp.data.records.map(it => { 
 | 
    return { 
 | 
      ...it, 
 | 
      'startTime': dayjs(it.workStartTime).format('HH:mm'), 
 | 
      'endTime': dayjs(it.workEndTime).format('HH:mm'), 
 | 
    } 
 | 
  }) 
 | 
  tableLoading.value = false 
 | 
  
 | 
} 
 | 
  
 | 
// 重置筛选 
 | 
const resetFilter = () => { 
 | 
  filterForm.staffName = '' 
 | 
  filterForm.shiftType = '' 
 | 
  filterForm.dateRange = [] 
 | 
} 
 | 
  
 | 
// 打开排班对话框 
 | 
const openScheduleDialog = (type, data) => { 
 | 
  dialogType.value = type 
 | 
  scheduleDialog.value = true 
 | 
  getPersonList() 
 | 
  if (type === 'edit' && data) { 
 | 
    // 编辑模式,复制数据 
 | 
    Object.assign(scheduleForm, {...data}) 
 | 
  } else { 
 | 
    // 新增模式,重置表单 
 | 
    Object.keys(scheduleForm).forEach(key => { 
 | 
      scheduleForm[key] = '' 
 | 
    }) 
 | 
    // scheduleForm.status = '已安排' 
 | 
    scheduleForm.workDate = new Date().toISOString().split('T')[0] 
 | 
  } 
 | 
} 
 | 
  
 | 
// 关闭排班对话框 
 | 
const closeScheduleDialog = () => { 
 | 
  scheduleFormRef.value?.resetFields() 
 | 
  scheduleDialog.value = false 
 | 
} 
 | 
  
 | 
// 计算工作时长 
 | 
const calculateWorkHours = () => { 
 | 
  if (scheduleForm.workDate && scheduleForm.startTime && scheduleForm.endTime) { 
 | 
    // 使用 workDate 与 startTime 和 endTime 组合 
 | 
    const startDateTime = new Date(`${scheduleForm.workDate} ${scheduleForm.startTime}`) 
 | 
    const endDateTime = new Date(`${scheduleForm.workDate} ${scheduleForm.endTime}`) 
 | 
  
 | 
    // 处理跨天情况(结束时间早于开始时间) 
 | 
    if (endDateTime < startDateTime) { 
 | 
      // 跨天,将结束日期加一天 
 | 
      endDateTime.setDate(endDateTime.getDate() + 1) 
 | 
    } 
 | 
    // 计算工作时长(小时) 
 | 
    const diffMs = endDateTime - startDateTime 
 | 
    const diffHours = diffMs / (1000 * 60 * 60) 
 | 
    scheduleForm.workHours = Math.round(diffHours * 100) / 100 
 | 
    scheduleForm.workStartTime = dayjs(startDateTime).format("YYYY-MM-DD HH:mm:ss") 
 | 
    scheduleForm.workEndTime = dayjs(endDateTime).format("YYYY-MM-DD HH:mm:ss") 
 | 
  
 | 
  } 
 | 
} 
 | 
  
 | 
// 提交排班表单 
 | 
const submitScheduleForm = async () => { 
 | 
  const valid = await scheduleFormRef.value.validate() 
 | 
  if (!valid) return 
 | 
  
 | 
  calculateWorkHours() 
 | 
  const newSchedule = {...scheduleForm} 
 | 
  
 | 
  try { 
 | 
    await save(newSchedule) 
 | 
    ElMessage.success('保存排班成功') 
 | 
  
 | 
    handleFilter() 
 | 
    closeScheduleDialog() 
 | 
  } catch (err) { 
 | 
    ElMessage.error('保存失败') 
 | 
  } 
 | 
} 
 | 
  
 | 
// 删除排班 
 | 
const handleDelete = (row) => { 
 | 
  ElMessageBox.confirm( 
 | 
      `确定要删除 ${row.staffName} 的排班记录吗?`, 
 | 
      '删除提示', 
 | 
      { 
 | 
        confirmButtonText: '确认', 
 | 
        cancelButtonText: '取消', 
 | 
        type: 'warning' 
 | 
      } 
 | 
  ).then(() => { 
 | 
    del(row.id) 
 | 
    ElMessage.success('删除成功') 
 | 
    handleFilter() 
 | 
  }).catch(() => { 
 | 
    ElMessage.info('已取消删除') 
 | 
  }) 
 | 
} 
 | 
  
 | 
// 批量删除 
 | 
const handleBatchDelete = () => { 
 | 
  if (selectedRows.value.length === 0) { 
 | 
    ElMessage.warning('请选择要删除的记录') 
 | 
    return 
 | 
  } 
 | 
  
 | 
  ElMessageBox.confirm( 
 | 
      `确定要删除选中的 ${selectedRows.value.length} 条排班记录吗?`, 
 | 
      '批量删除提示', 
 | 
      { 
 | 
        confirmButtonText: '确认', 
 | 
        cancelButtonText: '取消', 
 | 
        type: 'warning' 
 | 
      } 
 | 
  ).then(() => { 
 | 
    delByIds(selectedRows.value.map(item => item.id)) 
 | 
    handleFilter() 
 | 
    ElMessage.success('批量删除成功') 
 | 
  }).catch(() => { 
 | 
    ElMessage.info('已取消删除') 
 | 
  }) 
 | 
} 
 | 
  
 | 
// 选择变化事件 
 | 
const handleSelectionChange = (selection) => { 
 | 
  selectedRows.value = selection 
 | 
} 
 | 
  
 | 
// 导出 
 | 
const handleExport = () => { 
 | 
  let searchForm = { 
 | 
    ...filterForm, 
 | 
    ...(filterForm.dateRange.length > 0 && { 
 | 
      startDate: filterForm.dateRange[0], 
 | 
      endDate: filterForm.dateRange[1], 
 | 
    }) 
 | 
  } 
 | 
  proxy.download('/staff/staffScheduling/export', {}, '人员排班.xlsx') 
 | 
} 
 | 
  
 | 
// 生命周期 
 | 
onMounted(() => { 
 | 
  // 页面初始化 
 | 
  handleFilter() 
 | 
}) 
 | 
</script> 
 | 
  
 | 
<style scoped> 
 | 
.scheduling-container { 
 | 
  padding: 20px; 
 | 
  background-color: #f5f7fa; 
 | 
  min-height: 100vh; 
 | 
} 
 | 
  
 | 
.page-header { 
 | 
  text-align: center; 
 | 
  margin-bottom: 30px; 
 | 
  padding: 20px; 
 | 
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); 
 | 
  border-radius: 12px; 
 | 
  color: white; 
 | 
} 
 | 
  
 | 
.page-header h2 { 
 | 
  color: white; 
 | 
  margin-bottom: 10px; 
 | 
  font-size: 28px; 
 | 
  font-weight: 600; 
 | 
} 
 | 
  
 | 
.page-header p { 
 | 
  color: rgba(255, 255, 255, 0.9); 
 | 
  font-size: 14px; 
 | 
  margin: 0 0 15px 0; 
 | 
} 
 | 
  
 | 
.header-controls { 
 | 
  display: flex; 
 | 
  justify-content: center; 
 | 
  gap: 15px; 
 | 
} 
 | 
  
 | 
.filter-section { 
 | 
  background: white; 
 | 
  padding: 20px; 
 | 
  border-radius: 8px; 
 | 
  margin-bottom: 20px; 
 | 
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); 
 | 
} 
 | 
  
 | 
.filter-form { 
 | 
  margin: 0; 
 | 
} 
 | 
  
 | 
.table-section { 
 | 
  background: white; 
 | 
  border-radius: 8px; 
 | 
  overflow: hidden; 
 | 
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); 
 | 
  margin-bottom: 20px; 
 | 
} 
 | 
  
 | 
.batch-actions { 
 | 
  background: white; 
 | 
  padding: 15px 20px; 
 | 
  border-radius: 8px; 
 | 
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); 
 | 
} 
 | 
  
 | 
.dialog-footer { 
 | 
  text-align: right; 
 | 
} 
 | 
  
 | 
:deep(.el-form-item__label) { 
 | 
  font-weight: 500; 
 | 
  color: #303133; 
 | 
} 
 | 
  
 | 
:deep(.el-input__wrapper) { 
 | 
  box-shadow: 0 0 0 1px #dcdfe6 inset; 
 | 
} 
 | 
  
 | 
:deep(.el-input__wrapper:hover) { 
 | 
  box-shadow: 0 0 0 1px #c0c4cc inset; 
 | 
} 
 | 
  
 | 
:deep(.el-input__wrapper.is-focus) { 
 | 
  box-shadow: 0 0 0 1px #409eff inset; 
 | 
} 
 | 
  
 | 
/* 响应式设计 */ 
 | 
@media (max-width: 768px) { 
 | 
  .scheduling-container { 
 | 
    padding: 10px; 
 | 
  } 
 | 
  
 | 
  .page-header { 
 | 
    padding: 15px; 
 | 
  } 
 | 
  
 | 
  .page-header h2 { 
 | 
    font-size: 24px; 
 | 
  } 
 | 
  
 | 
  .header-controls { 
 | 
    flex-direction: column; 
 | 
    gap: 10px; 
 | 
  } 
 | 
} 
 | 
  
 | 
@media (max-width: 768px) { 
 | 
  .filter-form .el-form-item { 
 | 
    margin-bottom: 10px; 
 | 
  } 
 | 
} 
 | 
</style> 
 |