gaoluyang
2026-06-02 7c2cdcbc7f5585b96fba76a07b0e4417a09c4d7e
src/views/collaborativeApproval/notificationManagement/meetSetting/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,318 @@
<template>
  <div>
    <!-- æœç´¢åŒºåŸŸ -->
    <el-form :model="searchForm" label-width="100px" class="search-form">
      <el-form-item label="会议室名称">
        <el-input v-model="searchForm.name" placeholder="请输入会议室名称" clearable />
      </el-form-item>
      <el-form-item label="位置">
        <el-input v-model="searchForm.location" placeholder="请输入位置" clearable />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="handleSearch">搜索</el-button>
        <el-button @click="resetSearch">重置</el-button>
      </el-form-item>
      <el-form-item class="search-actions">
        <el-button @click="handleExport">导出</el-button>
        <el-button type="primary" @click="handleAdd">
          <el-icon><Plus /></el-icon>
          æ–°å¢žä¼šè®®å®¤
        </el-button>
      </el-form-item>
    </el-form>
    <!-- ä¼šè®®å®¤åˆ—表 -->
    <el-card>
      <el-table v-loading="loading" :data="meetingRoomList" border :height="tableHeight">
        <el-table-column prop="name" label="会议室名称" align="center" />
        <el-table-column prop="location" label="位置" align="center" />
        <el-table-column prop="capacity" label="容纳人数" align="center" />
        <el-table-column prop="equipment" label="设备配置" align="center">
          <template #default="scope">
            <el-tag v-for="item in scope.row.equipment" :key="item" style="margin-right: 5px; margin-bottom: 5px;">
              {{ item }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="status" label="状态" align="center" width="100">
          <template #default="scope">
            <el-tag :type="scope.row.status === 1 ? 'success' : 'danger'">
              {{ scope.row.status === 1 ? '启用' : '禁用' }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="操作" align="center" width="200">
          <template #default="scope">
            <el-button type="primary" link @click="handleEdit(scope.row)">编辑</el-button>
            <el-button type="danger" link @click="handleDelete(scope.row)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
      <!-- åˆ†é¡µ -->
      <pagination
        v-show="total > 0"
        :total="total"
        v-model:page="queryParams.current"
        v-model:limit="queryParams.size"
        @pagination="getList"
      />
    </el-card>
    <!-- æ·»åŠ /编辑对话框 -->
    <el-dialog :title="dialogTitle" v-model="dialogVisible" width="600px" @close="cancel">
      <el-form ref="meetingRoomFormRef" :model="meetingRoomForm" :rules="rules" label-width="100px">
        <el-form-item label="会议室名称" prop="name">
          <el-input v-model="meetingRoomForm.name" placeholder="请输入会议室名称" />
        </el-form-item>
        <el-form-item label="位置" prop="location">
          <el-input v-model="meetingRoomForm.location" placeholder="请输入会议室位置" />
        </el-form-item>
        <el-form-item label="容纳人数" prop="capacity">
          <el-input-number v-model="meetingRoomForm.capacity" :min="1" placeholder="请输入容纳人数" />
        </el-form-item>
        <el-form-item label="设备配置" prop="equipment">
          <el-select v-model="meetingRoomForm.equipment" multiple placeholder="请选择设备配置" style="width: 100%">
            <el-option
              v-for="item in equipmentOptions"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="状态" prop="status">
          <el-radio-group v-model="meetingRoomForm.status">
            <el-radio :label="1">启用</el-radio>
            <el-radio :label="0">禁用</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="备注" prop="remark">
          <el-input v-model="meetingRoomForm.remark" type="textarea" placeholder="请输入备注" />
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitForm">ç¡® å®š</el-button>
          <el-button @click="cancel">取 æ¶ˆ</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>
<script setup>
import { ref, reactive, onMounted, getCurrentInstance } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Plus } from '@element-plus/icons-vue'
import Pagination from '@/components/Pagination/index.vue'
import {getMeetingRoomList,saveRoom,delRoom} from '@/api/collaborativeApproval/meeting.js'
// æ•°æ®åˆ—表加载状态
const loading = ref(false)
// æ€»æ¡æ•°
const total = ref(0)
// è¡¨æ ¼é«˜åº¦ï¼ˆæ ¹æ®çª—口高度自适应)
const tableHeight = ref(window.innerHeight - 380)
// ä¼šè®®å®¤åˆ—表数据
const meetingRoomList = ref([])
// æŸ¥è¯¢å‚æ•°
const queryParams = reactive({
  current: 1,
  size: 10
})
// æœç´¢è¡¨å•
const searchForm = reactive({
  name: '',
  location: ''
})
// å¯¹è¯æ¡†æ ‡é¢˜
const dialogTitle = ref('')
// æ˜¯å¦æ˜¾ç¤ºå¯¹è¯æ¡†
const dialogVisible = ref(false)
// è®¾å¤‡é…ç½®é€‰é¡¹
const equipmentOptions = ref([
  { value: '投影仪', label: '投影仪' },
  { value: '电视', label: '电视' },
  { value: '音响', label: '音响' },
  { value: '电话', label: '电话' },
  { value: '视频会议系统', label: '视频会议系统' },
  { value: '白板', label: '白板' },
  { value: '写字板', label: '写字板' },
  { value: '无线网络', label: '无线网络' }
])
// è¡¨å•数据
const meetingRoomForm = reactive({
  id: undefined,
  name: '',
  location: '',
  capacity: 10,
  equipment: [],
  status: 1,
  remark: ''
})
// è¡¨å•校验规则
const rules = {
  name: [{ required: true, message: '会议室名称不能为空', trigger: 'blur' }],
  location: [{ required: true, message: '位置不能为空', trigger: 'blur' }],
  capacity: [{ required: true, message: '容纳人数不能为空', trigger: 'blur' }]
}
// è¡¨å•引用
const meetingRoomFormRef = ref(null)
// æŸ¥è¯¢æ•°æ®
const getList = async () => {
  loading.value = true
  let resp = await getMeetingRoomList({...searchForm,...queryParams})
  meetingRoomList.value = resp.data.records.map(it=>{
    it.equipment = it.equipment.split(',')
    return it;
  })
  total.value = resp.data.total
  loading.value = false
}
// æœç´¢æŒ‰é’®æ“ä½œ
const handleSearch = () => {
  queryParams.current = 1
  getList()
}
// é‡ç½®æœç´¢è¡¨å•
const resetSearch = () => {
  Object.assign(searchForm, {
    name: '',
    location: ''
  })
  handleSearch()
}
// æ·»åŠ æŒ‰é’®æ“ä½œ
const handleAdd = () => {
  dialogTitle.value = '添加会议室'
  dialogVisible.value = true
}
// ä¿®æ”¹æŒ‰é’®æ“ä½œ
const handleEdit = (row) => {
  dialogTitle.value = '修改会议室'
  Object.assign(meetingRoomForm, row)
  dialogVisible.value = true
}
// åˆ é™¤æŒ‰é’®æ“ä½œ
const handleDelete = (row) => {
  ElMessageBox.confirm(
    `是否确认删除会议室 "${row.name}"?`,
    '警告',
    {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    }
  ).then(() => {
    // æ¨¡æ‹Ÿåˆ é™¤æ“ä½œ
    delRoom(row.id).then(resp=>{
      ElMessage.success('删除成功')
      getList()
    })
  }).catch(() => {})
}
// å–消按钮
const cancel = () => {
  dialogVisible.value = false
  reset()
}
// è¡¨å•重置
const reset = () => {
  Object.assign(meetingRoomForm, {
    id: undefined,
    name: '',
    location: '',
    capacity: 10,
    equipment: [],
    status: 1,
    remark: ''
  })
  meetingRoomFormRef.value?.resetFields()
}
// æäº¤è¡¨å•
const submitForm = () => {
  meetingRoomFormRef.value?.validate((valid) => {
    if (valid) {
      // æ¨¡æ‹Ÿæäº¤æ“ä½œ
      let formData = {...  meetingRoomForm}
      formData.equipment = formData.equipment.join(',')
      saveRoom(formData).then(resp=>{
        ElMessage.success('保存成功')
        dialogVisible.value = false
        getList()
      })
    }
  })
}
// å¯¼å‡º
const { proxy } = getCurrentInstance()
const handleExport = () => {
  proxy.download('/meeting/export', { ...searchForm }, '会议室设置.xlsx')
}
// é¡µé¢åŠ è½½æ—¶èŽ·å–æ•°æ®
onMounted(() => {
  getList()
})
</script>
<style scoped>
.app-container {
  padding: 20px;
}
.search-form {
  display: flex;
  /* align-items: center; */
}
.search-actions {
  margin-left: auto;
}
.page-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}
.page-header h2 {
  margin: 0;
  color: #303133;
}
.search-card {
  margin-bottom: 20px;
}
.dialog-footer {
   text-align: center;
}
</style>