<template> 
 | 
  <GlobalAlertWindow 
 | 
    :title="title" 
 | 
    :visible.sync="visible" 
 | 
    :confirm-working="isWorking" 
 | 
    @confirm="confirm" 
 | 
    width="840px" 
 | 
  > 
 | 
    <el-form :model="form" ref="form" :rules="rules" label-width="120px" label-suffix=":"> 
 | 
      <el-form-item label="关联会议室" prop="roomId"> 
 | 
        <el-select 
 | 
          v-model="form.roomId" 
 | 
          filterable 
 | 
          clearable 
 | 
          :disabled="isEdit" 
 | 
          placeholder="请选择关联会议室" 
 | 
          @change="selectRoom" 
 | 
        > 
 | 
          <el-option v-for="item in rooms()" :key="item.id" :value="item.id" :label="item.name" /> 
 | 
        </el-select> 
 | 
      </el-form-item> 
 | 
      <el-form-item label="预定日期" prop="date"> 
 | 
        <el-date-picker 
 | 
          :disabled="isEdit" 
 | 
          v-model="form.date" 
 | 
          value-format="yyyy-MM-dd" 
 | 
          placeholder="请选择预定日期" 
 | 
          @change="selectDate" 
 | 
        ></el-date-picker> 
 | 
      </el-form-item> 
 | 
      <el-form-item label="预定时间" prop="times"> 
 | 
        <div class="time-style"> 
 | 
          <div 
 | 
            class="time-item" 
 | 
            v-for="(item, index) in timelist" 
 | 
            :key="item.id" 
 | 
            :class="{ 
 | 
              'time-item-sel': form.times.indexOf(index)!=-1, 
 | 
              'time-item-disable': item.isUse, 
 | 
              'disable': item.bookingTimeId 
 | 
            }" 
 | 
            @click="selectTimes(index, item)" 
 | 
          >{{ `${item.startTime}-${item.endTime}` }}</div> 
 | 
        </div> 
 | 
      </el-form-item> 
 | 
      <el-form-item label="会议主题" prop="name"> 
 | 
        <el-input v-model="form.name" placeholder="请输入会议主题" :maxlength="30" v-trim/> 
 | 
      </el-form-item> 
 | 
  
 | 
      <el-form-item label="参会人员"> 
 | 
        <!-- <el-input style="width:40%" disabled v-model="sysList" placeholder="选择参会人员" v-trim/> --> 
 | 
        <el-select 
 | 
          v-model="form.sysList" 
 | 
          filterable 
 | 
          clearable 
 | 
          multiple 
 | 
          placeholder="选择部门成员" 
 | 
        > 
 | 
          <el-option 
 | 
            v-for="item in sysList" 
 | 
            :key="item.id" 
 | 
            :value="item.id" 
 | 
            :label="item.department?`${item.department.name}-${item.realname}`:item.realname" 
 | 
          ></el-option> 
 | 
          <!-- <el-option :key="1" :value="1" label="禁用" /> --> 
 | 
        </el-select> 
 | 
      </el-form-item> 
 | 
      <el-form-item label="会议内容" prop="content"> 
 | 
        <el-input 
 | 
          type="textarea" 
 | 
          v-model="form.content" 
 | 
          :maxlength="300" 
 | 
          show-word-limit 
 | 
          :autosize="{ minRows: 4, maxRows: 12}" 
 | 
          placeholder="请输入会议内容" 
 | 
          v-trim 
 | 
        /> 
 | 
      </el-form-item> 
 | 
      <el-form-item v-if="projectList.length" label="选择服务项目" prop="projectList"> 
 | 
        <el-checkbox-group v-model="form.projectList"> 
 | 
          <el-checkbox 
 | 
            v-for="project in projectList" 
 | 
            :label="project.id" 
 | 
            :key="project.id" 
 | 
          >{{project.name}}</el-checkbox> 
 | 
        </el-checkbox-group> 
 | 
      </el-form-item> 
 | 
      <el-form-item label="会议附件" prop="fileList"> 
 | 
        <div> 
 | 
          <el-button type="primary" icon="el-icon-upload" @click="$refs.upFile.click()">会议附件</el-button> 
 | 
        </div> 
 | 
        <div class="data-list"> 
 | 
          <FileLink 
 | 
            :links="form.fileList" 
 | 
            linkName="fileFullUrl" 
 | 
          /> 
 | 
        </div> 
 | 
      </el-form-item> 
 | 
      <el-form-item label="会议备注" prop="remark"> 
 | 
        <el-input type="textarea" v-model="form.remark" placeholder="请输入会议备注" v-trim/> 
 | 
      </el-form-item> 
 | 
      <input type="file" @change="upFiles" ref="upFile" style="display: none;" /> 
 | 
    </el-form> 
 | 
  
 | 
    <el-dialog 
 | 
      title="会议室预约情况" 
 | 
      :visible.sync="isShowDetail" 
 | 
      append-to-body 
 | 
      width="600px" 
 | 
    > 
 | 
      <div class="detail_modal"> 
 | 
        <div class="h1">{{ activeInfo.meetingName }}</div> 
 | 
        <div class="line"> 
 | 
          <div class="label">会议时间</div> 
 | 
          <div class="value" v-if="activeInfo.meetingDate"> 
 | 
            {{ activeInfo.meetingDate.slice(5) }} {{ activeInfo.meetingTime }} 
 | 
          </div> 
 | 
        </div> 
 | 
        <div class="line"> 
 | 
          <div class="label">会议室</div> 
 | 
          <div class="value">{{ activeInfo.roomName }}</div> 
 | 
        </div> 
 | 
        <div class="line"> 
 | 
          <div class="label">预约人</div> 
 | 
          <div class="value">{{ activeInfo.bookingUserName }}</div> 
 | 
        </div> 
 | 
        <el-button @click="isShowDetail = false">关闭</el-button> 
 | 
      </div> 
 | 
    </el-dialog> 
 | 
  </GlobalAlertWindow> 
 | 
</template> 
 | 
  
 | 
<script> 
 | 
import BaseOpera from '@/components/base/BaseOpera' 
 | 
import GlobalAlertWindow from '@/components/common/GlobalAlertWindow' 
 | 
import FileLink from '@/views/meeting/components/common/FileLink' 
 | 
import { upload } from '@/api/system/common' 
 | 
import { fetchList as userList } from '@/api/system/user' 
 | 
import { findListByObjId } from '@/api/meeting/projects' 
 | 
import { BookDetailById } from '@/api/meeting/bookings' 
 | 
import { findList } from '@/api/meeting/roomTime' 
 | 
import { numRule, arrayRule } from '@/utils/form' 
 | 
export default { 
 | 
  name: 'OperaBookingsWindow', 
 | 
  extends: BaseOpera, 
 | 
  components: { GlobalAlertWindow, FileLink }, 
 | 
  data () { 
 | 
    return { 
 | 
      // 表单数据 
 | 
      form: { 
 | 
        id: null, 
 | 
        date: '', 
 | 
        editDate: '', 
 | 
        projectList: [], 
 | 
        remark: '', 
 | 
        name: '', 
 | 
        roomId: '', 
 | 
        startTime: '', 
 | 
        endTime: '', 
 | 
        times: [], 
 | 
        content: '', 
 | 
        sysList: [], 
 | 
        fileList: [] 
 | 
      }, 
 | 
      activeInfo: {}, 
 | 
      isShowDetail: false, 
 | 
      isEdit: false, 
 | 
      // room: [], 
 | 
      sysList: [], 
 | 
      projectList: [], 
 | 
      timelist: [], 
 | 
      // 验证规则 
 | 
      rules: { 
 | 
        roomId: [ 
 | 
          { required: true, validator: numRule, message: '请选择关联会议室', tigger: 'change' } 
 | 
        ], 
 | 
        date: [ 
 | 
          { required: true, message: '请选择预定日期', tigger: 'change' } 
 | 
        ], 
 | 
        times: [ 
 | 
          { required: true, validator: arrayRule, message: '请选择预约时间', tigger: 'change' } 
 | 
        ], 
 | 
        sysList: [ 
 | 
          { required: true, validator: arrayRule, message: '请选择参会人员', tigger: 'change' } 
 | 
        ], 
 | 
        name: [ 
 | 
          { required: true, message: '请选择输入会议主题', tigger: 'blur' } 
 | 
        ] 
 | 
        // content: [ 
 | 
        //  { required: true, message: '请输入会议内容', tigger: 'blur' } 
 | 
        // ], 
 | 
      } 
 | 
    } 
 | 
  }, 
 | 
  inject: ['rooms'], 
 | 
  created () { 
 | 
    this.config({ 
 | 
      api: '/meeting/bookings', 
 | 
      'field.id': 'id' 
 | 
    }) 
 | 
    userList({ 
 | 
      page: 1, 
 | 
      capacity: 9999, 
 | 
      model: { realname: this.filterText, memberType: 2, companyType: 1 } 
 | 
    }) 
 | 
      .then(res => { 
 | 
        console.log('userList', res) 
 | 
        this.sysList = res.records 
 | 
      }) 
 | 
  }, 
 | 
  methods: { 
 | 
    /** 
 | 
     * 打开窗口 
 | 
     * @title 窗口标题 
 | 
     * @target 编辑的对象 
 | 
     */ 
 | 
    open (title, target) { 
 | 
      this.title = title 
 | 
      this.visible = true 
 | 
      this.timelist = [] 
 | 
      this.isEdit = false 
 | 
      // 新建 
 | 
      if (target == null) { 
 | 
        this.$nextTick(() => { 
 | 
          this.$refs.form.resetFields() 
 | 
          this.form[this.configData['field.id']] = null 
 | 
        }) 
 | 
        return 
 | 
      } 
 | 
      // 编辑 
 | 
      this.$nextTick(() => { 
 | 
        for (const key in this.form) { 
 | 
          this.form[key] = target[key] 
 | 
        } 
 | 
        this.isEdit = true 
 | 
        this.form.projectList = target.projectList ? target.projectList.map(item => item.projectId) : [] 
 | 
        this.form.sysList = this.form.sysList ? this.form.sysList.map(item => item.userId) : [] 
 | 
        // console.log(target.startTime.split(' ')); 
 | 
        // debugger 
 | 
        this.form.date = target.startTime.split(' ')[0] 
 | 
        this.getTimes(true) 
 | 
        this.selectRoom(this.form.roomId) 
 | 
      }) 
 | 
    }, 
 | 
    selectRoom (objId) { 
 | 
      this.getTimes() 
 | 
      findListByObjId({ 
 | 
        objId: objId, 
 | 
        objType: 0 
 | 
      }) 
 | 
        .then(res => { 
 | 
          this.projectList = res 
 | 
        }) 
 | 
    }, 
 | 
    selectDate (v) { 
 | 
      // console.log(v); 
 | 
      this.getTimes() 
 | 
    }, 
 | 
    getTimes (isInit = false) { 
 | 
      this.form.times = [] 
 | 
      this.timelist = [] 
 | 
  
 | 
      if (this.form.date && this.form.roomId) { 
 | 
        findList({ 
 | 
          yudingDate: this.form.date + ' 00:00:00', 
 | 
          roomId: this.form.roomId, 
 | 
          bookingId: this.form.id 
 | 
        }) 
 | 
          .then(res => { 
 | 
            this.timelist = res 
 | 
            if (isInit) { 
 | 
              this.timelist.forEach((itme, index) => { 
 | 
                if (itme.isChoose) { 
 | 
                  itme.isUse = false 
 | 
                  this.form.times.push(index) 
 | 
                } 
 | 
              }) 
 | 
              // let startTime = this.form.startTime.split(' ')[1] 
 | 
              // let endTime = this.form.endTime.split(' ')[1] 
 | 
              // let firstIndex = this.timelist.findIndex(item => item.startTime == startTime) 
 | 
              // let lastIndex = this.timelist.findIndex(item => item.endTime == endTime) 
 | 
              // let index = firstIndex 
 | 
              // while(index <= lastIndex) { 
 | 
              //   this.form.times.push(index) 
 | 
              //   index ++ 
 | 
              // } 
 | 
              // console.log('startTime', startTime); 
 | 
              // console.log('endTime', endTime); 
 | 
              // console.log('firstIndex', firstIndex); 
 | 
              // console.log('lastIndex', lastIndex); 
 | 
              // console.log('this.form.times', this.form.times); 
 | 
            } 
 | 
          }) 
 | 
      } 
 | 
    }, 
 | 
    getDetail (id) { 
 | 
      BookDetailById({ 
 | 
        id 
 | 
      }).then(res => { 
 | 
        this.activeInfo = res 
 | 
        this.isShowDetail = true 
 | 
      }) 
 | 
    }, 
 | 
    selectTimes (index, item) { 
 | 
      if (item.bookingTimeId) { 
 | 
        this.getDetail(item.bookingTimeId) 
 | 
        return 
 | 
      } 
 | 
      if (this.isEdit) { 
 | 
        return 
 | 
      } 
 | 
      const tempIndex = this.form.times.indexOf(index) 
 | 
      if (tempIndex != -1) { 
 | 
        if (tempIndex == 0) { 
 | 
          // console.log(this.form.times); 
 | 
          // debugger 
 | 
          this.form.times.splice(0, 1) 
 | 
        } else if (tempIndex == this.form.times.length - 1) { 
 | 
          this.form.times.splice(tempIndex, 1) 
 | 
        } 
 | 
      } else { 
 | 
        if (item.isUse) { 
 | 
          return 
 | 
        } 
 | 
        if (this.form.times.length && index + 1 !== this.form.times[0] && index - 1 !== this.form.times[this.form.times.length - 1]) { 
 | 
          this.$message.error('预约时间必须是相邻的!') 
 | 
          return 
 | 
        } 
 | 
        this.form.times.push(index) 
 | 
        this.form.times.sort((x, y) => x - y) 
 | 
      } 
 | 
      // console.log(this.form.times); 
 | 
    }, 
 | 
    upFiles (file) { 
 | 
      const formdate = new FormData() 
 | 
      this.isUploading = true 
 | 
      formdate.append('file', file.target.files[0]) 
 | 
      formdate.append('folder', 'projects') 
 | 
      upload(formdate) 
 | 
        .then(res => { 
 | 
          // console.log(this.form); 
 | 
          this.form.fileList.push({ 
 | 
            name: res.originname, 
 | 
            url: res.url, 
 | 
            fileurl: res.imgaddr 
 | 
          }) 
 | 
        }) 
 | 
        .catch(err => { 
 | 
          console.log(err) 
 | 
        }) 
 | 
        .finally(() => this.isUploading = false) 
 | 
      this.$refs.upFile.value = null 
 | 
    }, 
 | 
    // 确认新建 
 | 
    __confirmCreate () { 
 | 
      this.$refs.form.validate((valid) => { 
 | 
        // debugger 
 | 
        if (!valid) { 
 | 
          return 
 | 
        } 
 | 
        // console.log(this.form); 
 | 
        // debugger 
 | 
        // 调用新建接口 
 | 
        this.isWorking = true 
 | 
        let sysList = [...this.form.sysList] 
 | 
        sysList = sysList.map(item => { 
 | 
          return { userId: item } 
 | 
        }) 
 | 
        let projectList = [...this.form.projectList] 
 | 
        projectList = projectList.map(item => { 
 | 
          return { projectId: item } 
 | 
        }) 
 | 
        const bookingTimeList = [] 
 | 
        this.form.times.forEach(item => { 
 | 
          bookingTimeList.push({ 
 | 
            timeId: this.timelist[item].id, 
 | 
            id: this.timelist[item].bookingTimeId 
 | 
          }) 
 | 
        }) 
 | 
        const startTime = this.form.date + ' ' + this.timelist[this.form.times[0]].startTime + ':00' 
 | 
        const endTime = this.form.date + ' ' + this.timelist[this.form.times[this.form.times.length - 1]].endTime + ':00' 
 | 
        this.api.create({ 
 | 
          ...this.form, 
 | 
          sysList, 
 | 
          projectList, 
 | 
          startTime, 
 | 
          endTime, 
 | 
          bookingTimeList 
 | 
        }) 
 | 
          .then(() => { 
 | 
            this.visible = false 
 | 
            this.$tip.apiSuccess('新建成功') 
 | 
            this.$emit('success') 
 | 
          }) 
 | 
          .catch(e => { 
 | 
            // this.$tip.apiFailed(e) 
 | 
          }) 
 | 
          .finally(() => { 
 | 
            this.isWorking = false 
 | 
          }) 
 | 
      }) 
 | 
    }, 
 | 
    // 确认修改 
 | 
    __confirmEdit () { 
 | 
      this.$refs.form.validate((valid) => { 
 | 
        if (!valid) { 
 | 
          return 
 | 
        } 
 | 
        // 调用新建接口 
 | 
        this.isWorking = true 
 | 
        let sysList = [...this.form.sysList] 
 | 
        sysList = sysList.map(item => { 
 | 
          return { userId: item } 
 | 
        }) 
 | 
        let projectList = [...this.form.projectList] 
 | 
        projectList = projectList.map(item => { 
 | 
          return { projectId: item } 
 | 
        }) 
 | 
        const bookingTimeList = [] 
 | 
        this.form.times.forEach(item => { 
 | 
          bookingTimeList.push({ 
 | 
            timeId: this.timelist[item].id, 
 | 
            id: this.timelist[item].bookingTimeId 
 | 
          }) 
 | 
        }) 
 | 
        const startTime = this.form.date + ' ' + this.timelist[this.form.times[0]].startTime + ':00' 
 | 
        const endTime = this.form.date + ' ' + this.timelist[this.form.times[this.form.times.length - 1]].endTime + ':00' 
 | 
        this.api.updateById({ 
 | 
          ...this.form, 
 | 
          sysList, 
 | 
          projectList, 
 | 
          startTime, 
 | 
          endTime, 
 | 
          bookingTimeList 
 | 
        }) 
 | 
          .then(() => { 
 | 
            this.visible = false 
 | 
            this.$tip.apiSuccess('修改成功') 
 | 
            this.$emit('success') 
 | 
          }) 
 | 
          .catch(e => { 
 | 
            // this.$tip.apiFailed(e) 
 | 
          }) 
 | 
          .finally(() => { 
 | 
            this.isWorking = false 
 | 
          }) 
 | 
      }) 
 | 
    } 
 | 
  } 
 | 
} 
 | 
</script> 
 | 
  
 | 
<style lang="scss" scoped> 
 | 
@import "@/assets/style/alertstyle.scss"; 
 | 
@import "@/assets/style/variables.scss"; 
 | 
  
 | 
::v-deep .el-input.is-disabled .el-input__inner { 
 | 
  background-color: #fff !important; 
 | 
  cursor: pointer; 
 | 
} 
 | 
  
 | 
.time-style { 
 | 
  display: flex; 
 | 
  flex-wrap: wrap; 
 | 
  cursor: pointer; 
 | 
  .time-item { 
 | 
    margin-right: 8px; 
 | 
    margin-bottom: 8px; 
 | 
    font-size: 14px; 
 | 
    font-weight: 400; 
 | 
    line-height: 14px; 
 | 
    width: 124px; 
 | 
    height: 36px; 
 | 
    display: flex; 
 | 
    justify-content: center; 
 | 
    align-items: center; 
 | 
    border-radius: 5px; 
 | 
    color: #111; 
 | 
    border: #cccccc solid 1px; 
 | 
    cursor: pointer; 
 | 
  } 
 | 
  .time-item-sel { 
 | 
    border-color: $primary-color; 
 | 
    background-color: #f6f9fe; 
 | 
    color: $primary-color; 
 | 
  } 
 | 
  .time-item-disable { 
 | 
    color: #fff; 
 | 
    border-color: #cccccc; 
 | 
    background-color: #cccccc; 
 | 
  } 
 | 
  .disable{ 
 | 
    border-color: #bed6f9; 
 | 
    background-color: #bed6f9; 
 | 
    color: #fff; 
 | 
  } 
 | 
} 
 | 
.detail_modal { 
 | 
  padding: 20px 16px; 
 | 
  .title { 
 | 
    text-align: center; 
 | 
    font-weight: 600; 
 | 
    font-size: 16px; 
 | 
    margin-bottom: 20px; 
 | 
  } 
 | 
  .h1 { 
 | 
    font-weight: 600; 
 | 
    font-size: 16px; 
 | 
    margin-bottom: 15px; 
 | 
  } 
 | 
  .line { 
 | 
    display: flex; 
 | 
    margin-bottom: 10px; 
 | 
    .label { 
 | 
      width: 70px; 
 | 
      color: #888888; 
 | 
    } 
 | 
    .value { 
 | 
      color: #333333; 
 | 
    } 
 | 
  } 
 | 
} 
 | 
  
 | 
</style> 
 |