jiangping
2024-11-25 4e86fd38a29427a8bb50d73d8eb22f21dfb943d4
Merge remote-tracking branch 'origin/master'
已添加4个文件
已修改16个文件
5991 ■■■■ 文件已修改
admin/package-lock.json 4943 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/package.json 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/api/Inspection/ywPatrolPoint.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/api/client/staff.js 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/api/project/yeFloor.js 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/api/system/user.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/api/workorder/ywWorkorder.js 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/assets/icons/position.png 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/components/common/CommonHeader.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/components/common/map/mapDrag.vue 320 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/eventBus/eventBus.js 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/Inspection/components/OperaYwPatrolPointWindow.vue 81 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/Inspection/dot.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/operation/components/deviceEdit.vue 36 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/project/components/OperaYwRoomWindow.vue 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/project/components/floorLevel.vue 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/project/housingList.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/workorder/components/OperaYwWorkorderWindow.vue 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/workorder/components/detail.vue 371 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/workorder/workorderList.vue 144 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/package-lock.json
ÎļþÌ«´ó
admin/package.json
@@ -13,6 +13,7 @@
    "fix": "eslint --ext .js,.vue src --fix"
  },
  "dependencies": {
    "@amap/amap-jsapi-loader": "^1.0.1",
    "@riophae/vue-treeselect": "^0.4.0",
    "@wangeditor/editor": "^5.1.23",
    "@wangeditor/editor-for-vue": "^1.0.2",
admin/src/api/Inspection/ywPatrolPoint.js
@@ -34,6 +34,10 @@
export function deleteById (id) {
  return request.get(`/visitsAdmin/cloudService/business/ywPatrolPoint/delete/${id}`)
}
// è¯¦æƒ…
export function detail (id) {
  return request.get(`/visitsAdmin/cloudService/business/ywPatrolPoint/${id}`)
}
// æ‰¹é‡åˆ é™¤
export function deleteByIdInBatch (ids) {
admin/src/api/client/staff.js
@@ -6,7 +6,12 @@
    trim: true
  })
}
// æŸ¥è¯¢
export function getStaffList (data) {
  return request.post('/visitsAdmin/cloudService/business/member/ywList', data, {
    trim: true
  })
}
// å¯¼å‡ºExcel
export function exportExcel (data) {
  return request.post('/visitsAdmin/cloudService/business/member/exportExcel', data, {
admin/src/api/project/yeFloor.js
@@ -6,6 +6,11 @@
    trim: true
  })
}
export function getFloorList (data) {
  return request.post('/visitsAdmin/cloudService/business/ywFloor/list', data, {
    trim: true
  })
}
// å¯¼å‡ºExcel
export function exportExcel (data) {
  return request.post('/visitsAdmin/cloudService/business/ywFloor/exportExcel', data, {
admin/src/api/system/user.js
@@ -4,6 +4,10 @@
export function fetchList (data) {
  return request.post('/visitsAdmin/cloudService/system/user/page', data)
}
// æŸ¥è¯¢æ‰€æœ‰å†…部人员
export function getUserList (data) {
  return request.post('/visitsAdmin/cloudService/system/user/findInternalList', data)
}
// æ–°å»º
export function create (data) {
admin/src/api/workorder/ywWorkorder.js
@@ -19,7 +19,14 @@
export function create (data) {
  return request.post('/visitsAdmin/cloudService/business/ywWorkorder/create', data)
}
// æŒ‡æ´¾
export function dispatchOrder (data) {
  return request.post('/visitsAdmin/cloudService/business/ywWorkorder/dispatchOrder', data)
}
// å¤„理
export function dealOrder (data) {
  return request.post('/visitsAdmin/cloudService/business/ywWorkorder/dealOrder', data)
}
// ä¿®æ”¹
export function updateById (data) {
  return request.post('/visitsAdmin/cloudService/business/ywWorkorder/updateById', data)
@@ -29,6 +36,10 @@
export function deleteById (id) {
  return request.get(`/visitsAdmin/cloudService/business/ywWorkorder/delete/${id}`)
}
// æŸ¥è¯¢è¯¦æƒ…
export function detailById (id) {
  return request.get(`/visitsAdmin/cloudService/business/ywWorkorder/${id}`)
}
// æ‰¹é‡åˆ é™¤
export function deleteByIdInBatch (ids) {
admin/src/assets/icons/position.png
admin/src/components/common/CommonHeader.vue
@@ -114,9 +114,9 @@
  },
  mounted() {
    // needChangePwd 0 : é»˜è®¤å¯†ç éœ€è¦ä¿®æ”¹ï¼Œ1 ä¸éœ€è¦
    if (this.userInfo &&(!this.userInfo.needChangePwd || this.userInfo.needChangePwd == '0')) {
      this.visible.changePwd = true
    }
    // if (this.userInfo &&(!this.userInfo.needChangePwd || this.userInfo.needChangePwd == '0')) {
    //   this.visible.changePwd = true
    // }
  },
  filters: {
    // å±•示名称
admin/src/components/common/map/mapDrag.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,320 @@
<!--
  æè¿°ï¼šæ‹–放地图组件,默认尺寸是 500 * 300
  æŽ¥æ”¶å±žæ€§å‚数:
    lat: çº¬åº¦
    lng: ç»åº¦
  è‡ªå®šä¹‰äº‹ä»¶ï¼š
    drag: æ‹–放完成事件
  ç¤ºä¾‹ï¼š
    <mapDrag @drag="dragMap" lat="22.574405" lng="114.095388"></mapDrag>
-->
<template>
  <div class="m-map">
    <div class="search">
      <el-form @submit.native.prevent>
        <input
          :id="search_id"
          v-model="input"
          type="text"
          placeholder="请输入关键字"
          autocomplete="off"
        >
        <input type="text" style="display: none">
        <button type="primary" @click="searchMap">搜索</button>
      </el-form>
      <div v-show="searchKey" id="js-result" class="result" />
    </div>
    <!-- <div id="panel" /> -->
    <!-- æœç´¢ç»“果栏 -->
    <div v-if="showsearchResult" class="tool_search_result">
      <ul>
        <li
          v-for="(item, index) in poiList"
          :key="index"
          @click="markerResult(item)"
        >
          {{ item.name }}
        </li>
      </ul>
    </div>
    <div id="js-container" class="map">正在加载数据 ...</div>
  </div>
</template>
<script>
// import remoteLoad from '@/utils/remoteLoad.js'
import bus from '@/eventBus/eventBus.js'
// import { MapKey, securityJsCode } from '@/api/config'
import AMapLoader from '@amap/amap-jsapi-loader'
const MapKey = 'c477e250c63cde947d7e9072bdcf9e65'
const securityJsCode = '746ae93f3f20c7fc30134109bd55fd19'
export default {
  props: {
    lat: {
      type: String,
      default: ''
    },
    lng: {
      type: String,
      default: ''
    }
  },
  data() {
    return {
      autoOptions: {
        input: ''
      },
      showsearchResult: false,
      search_id: 'searchId',
      input: '',
      searchPlaceInput: '',
      searchKey: '',
      placeSearch: null,
      dragStatus: false,
      AMapUI: null,
      AMap: null,
      positionImage: require('@/assets/icons/position.png'),
      marker: {},
      map: null,
      poiList: []
    }
  },
  watch: {
    searchPlaceInput(newValue) {
      if (newValue != null) {
        // this.placeSearch.search(newValue)
      }
    }
  },
  created() {
    bus.$on('share_id', val => {
      this.autoOptions.input = val
    })
    bus.$on('share', val => {
      this.searchPlaceInput = val
    })
  },
  mounted() {
    this.initMap()
    this.sendId()
  },
  methods: {
    sendMsg() {
      bus.$emit('share', this.input)
    },
    sendId() {
      bus.$emit('share_id', this.search_id)
    },
    // å®žä¾‹åŒ–地图
    initMap() {
      window._AMapSecurityConfig = { securityJsCode }
      AMapLoader.load({
        key: MapKey, // ç”³è¯·å¥½çš„Web端开发者Key,首次调用 load æ—¶å¿…å¡«
        version: '2.0', // æŒ‡å®šè¦åŠ è½½çš„ JSAPI çš„版本,缺省时默认为 1.4.15
        plugins: ['AMap.ToolBar', 'AMap.Geocoder', 'AMap.PlaceSearch', 'AMap.Geolocation', 'AMap.MapType', 'AMap.HawkEye', 'AMap.Scale', 'AMap.AutoComplete'] // éœ€è¦ä½¿ç”¨çš„的插件列表,如比例尺'AMap.Scale'等
      }).then((AMap) => {
        this.map = new AMap.Map('js-container', { // è®¾ç½®åœ°å›¾å®¹å™¨id
          viewMode: '3D', // æ˜¯å¦ä¸º3D地图模式
          zoom: 11, // åˆå§‹åŒ–地图级别
          center: [117.279952, 31.850109] // åˆå§‹åŒ–地图中心点位置
        })
        this.map.addControl(new AMap.ToolBar())
        this.mapOn(AMap)
      }).catch(e => {
        console.log(e)
      })
    },
    searchMap() {
      var placeSearch = new AMap.PlaceSearch({
        // æž„造地点查询类
        pageSize: 30, // å•页显示结果条数
        pageIndex: 1, // é¡µç 
        citylimit: false, // æ˜¯å¦å¼ºåˆ¶é™åˆ¶åœ¨è®¾ç½®çš„城市内搜索
        map: this.map, // å±•现结果的地图实例
        // panel: 'panel', // ç»“果列表将在此容器中进行展示。
        autoFitView: true // æ˜¯å¦è‡ªåŠ¨è°ƒæ•´åœ°å›¾è§†é‡Žä½¿ç»˜åˆ¶çš„ Marker点都处于视口的可见范围
      })
      // å…³é”®å­—查询
      const cur = this
      placeSearch.search(this.input, (status, result) => {
        // æŸ¥è¯¢æˆåŠŸæ—¶ï¼Œresult即对应匹配的POI信息
        console.log(status)
        console.log(result)
        if (status === 'complete' && result.info === 'OK') {
          cur.showsearchResult = true
          cur.poiList = result.poiList.pois
        } else {
          cur.showsearchResult = false
          cur.poiList = []
          cur.$message({
            message: '没有查到结果',
            type: 'warning'
          })
        }
      })
    },
    markerResult(data) {
      // this.input = data.name
      // this.searchMap()
      const that = this
      const { lat, lng } = data.location
      window._AMapSecurityConfig = { securityJsCode }
      AMapLoader.load({
        key: MapKey, // ç”³è¯·å¥½çš„Web端开发者Key,首次调用 load æ—¶å¿…å¡«
        version: '2.0', // æŒ‡å®šè¦åŠ è½½çš„ JSAPI çš„版本,缺省时默认为 1.4.15
        plugins: ['AMap.ToolBar', 'AMap.Geocoder', 'AMap.PlaceSearch', 'AMap.Geolocation', 'AMap.MapType', 'AMap.HawkEye', 'AMap.Scale', 'AMap.AutoComplete'] // éœ€è¦ä½¿ç”¨çš„的插件列表,如比例尺'AMap.Scale'等
      }).then((AMap) => {
        this.map = new AMap.Map('js-container', { // è®¾ç½®åœ°å›¾å®¹å™¨id
          viewMode: '3D', // æ˜¯å¦ä¸º3D地图模式
          zoom: 18, // åˆå§‹åŒ–地图级别
          center: [lng, lat] // åˆå§‹åŒ–地图中心点位置
        })
        this.map.addControl(new AMap.ToolBar())
        const address = data.name
        const marker = new AMap.Marker({
          position: new AMap.LngLat(lng, lat),
          icon: that.positionImage,
          anchor: 'bottom-center'
        })
        // map.remove(that.marker)
        this.map.add(marker)
        that.marker = marker
        that.showsearchResult = false
        that.$emit('center', { lnglat: lng + ',' + lat, address })
        this.mapOn(AMap)
      }).catch(e => {
        console.log(e)
      })
      // var marker = new AMap.Marker({
      //   position: [Number(data.location.lng), Number(data.location.lat)],
      //   cursor: 'pointer',
      //   // icon: carIcon,
      //   autoRotation: true,
      //   angle: 0,
      //   offset: new AMap.Pixel(-36, -30),
      // })
      // marker.setMap(this.mapall)
      // this.mapall.setFitView();
    },
    // åœ°å›¾äº‹ä»¶ç›‘听
    mapOn(AMap) {
      const { map } = this
      const that = this
      const geocoder = new AMap.Geocoder()
      let address = ''
      // ç›‘听地图点击事件
      map.on('click', function(e) {
        // èŽ·å–ç‚¹å‡»ä½ç½®åæ ‡
        const { lat, lng } = e.lnglat
        // è®¾ç½®æ ‡è®°ç‚¹
        const marker = new AMap.Marker({
          position: new AMap.LngLat(lng, lat),
          icon: that.positionImage,
          anchor: 'bottom-center'
        })
        map.remove(that.marker)
        map.add(marker)
        that.marker = marker
        geocoder.getAddress([lng, lat], function(status, result) {
          address = result.regeocode.formattedAddress
          that.showsearchResult = false
          that.$emit('center', { lng, lat, address })
        })
      })
    }
  }
}
</script>
<style lang="css">
.m-map {
  min-width: 500px;
  min-height: 300px;
  position: relative;
}
.m-map .map {
  width: 100%;
  height: 100%;
}
.m-map .search {
  position: absolute;
  top: 10px;
  left: 10px;
  width: 285px;
  z-index: 1;
}
.m-map .search input {
  width: 220px;
  border: 1px solid #ccc;
  height: 30px;
  box-sizing: border-box;
  line-height: 20px;
  padding: 5px;
  outline: none;
}
.m-map .search button {
  line-height: 26px;
  background: #fff;
  border: 1px solid #ccc;
  width: 50px;
  text-align: center;
}
.m-map .result {
  max-height: 300px;
  overflow: auto;
  margin-top: 10px;
}
#panel {
  position: absolute;
  top: 50px;
  left: 10px;
  width: 270px;
  z-index: 1;
}
.tool_search_result {
  position: absolute;
  top: 40px;
  left: 10px;
  width: 270px;
  height: 300px;
  overflow: auto;
  z-index: 1;
  border: 1px solid rgb(175, 175, 173);
  border-top: none;
  background: #fff;
  opacity: 0.8;
  bottom: auto;
  z-index: 12;
  position: absolute;
  text-align: left;
  font-size: 14px;
}
.tool_search_result ul {
  width: 100%;
  list-style: none;
  margin: 0;
  padding: 0;
}
.tool_search_result ul li {
  font-size: 12px;
  cursor: pointer;
  color: rgb(23, 40, 75);
  text-align: center;
  width: 100%;
  line-height: 2;
  padding: 5px 10px;
  box-sizing: border-box;
  border-bottom: 1px dashed rgb(170, 170, 172);
  display: block;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.tool_search_result ul li:last-child {
  border: none;
}
</style>
admin/src/eventBus/eventBus.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,3 @@
import Vue from 'vue'
// å…„弟组件之间进行通行
export default new Vue()
admin/src/views/Inspection/components/OperaYwPatrolPointWindow.vue
@@ -18,18 +18,20 @@
            label: 'name',
            value: 'id',
            children: 'childCategoryList',
            checkStrictly: true
          }"></el-cascader>
      </el-form-item>
      <el-form-item label="经纬度">
        <el-input v-model="form.lnglat" disabled v-trim />
      </el-form-item>
      <el-form-item>
        <mapDrag class="mapbox" @center="getCenter" />
      </el-form-item>
      <el-form-item label="巡检内容" prop="content">
        <el-input type="textarea" :rows="4" v-model="form.content" placeholder="请输入" />
      </el-form-item>
      <el-form-item label="上传图片" prop="imgurl">
        <UploadAvatarImage :file="{ 'imgurlfull': form.imgurlfull, 'imgurl': form.imgurl }"
          :uploadData="{ folder: 'projects' }" @uploadSuccess="uploadAvatarSuccess" @uploadEnd="isUploading = false"
          :uploadData="{ folder: 'ywPatrol/' }" @uploadSuccess="uploadAvatarSuccess" @uploadEnd="isUploading = false"
          @uploadBegin="isUploading = true" />
      </el-form-item>
    </el-form>
@@ -40,11 +42,13 @@
import BaseOpera from '@/components/base/BaseOpera'
import GlobalWindow from '@/components/common/GlobalWindow'
import UploadAvatarImage from '@/components/common/UploadAvatarImage'
import mapDrag from '@/components/common/map/mapDrag.vue'
import { fetchList } from '@/api/business/category'
import { detail } from '@/api/Inspection/ywPatrolPoint'
export default {
  name: 'OperaYwPatrolPointWindow',
  extends: BaseOpera,
  components: { GlobalWindow, UploadAvatarImage },
  components: { GlobalWindow, UploadAvatarImage, mapDrag },
  data() {
    return {
      // è¡¨å•数据
@@ -53,7 +57,8 @@
        code: '',
        content: '',
        imgurl: '',
        areaId: '',
        areaId: 0,
        areaIds: [],
        addr: ''
      },
      deviceList: [],
@@ -73,28 +78,64 @@
    })
  },
  methods: {
    initData() {
    open(title, row) {
      this.title = title
      this.visible = true
      if (row && row.id) {
        this.getDetail(row)
      }
    },
    getDetail(row) {
      detail(row.id).then(res => {
        this.form = { ...res }
        // this.$set(this.form, 'areaId', res.areaId)
        // console.log('res', res)
        // console.log('res', this.form)
        this.initData(res.areaId)
      })
    },
    initData(areaId) {
      fetchList({
        model: { type: 4 },
        capacity: 1000,
        page: 1,
      }).then(res => {
        this.cateList = res.records || []
        console.log('this.form.areaId', this.form)
        if (areaId) {
          this.cateList.forEach(item => {
            if (item.childCategoryList) {
              item.childCategoryList.forEach(item2 => {
                if (item2.id == areaId) {
                  this.$set(this.form, 'areaIds', [item.id, item2.id])
                  console.log('areaIds', this.form)
                }
              })
            }
          })
        }
      })
    },
    changeSel(e) {
      if (e && e.length == 1) {
        this.$set(this.form, 'catePId', e[0])
        this.$set(this.form, 'cateId', '')
      } else if (e && e.length == 2) {
        this.$set(this.form, 'catePId', e[0])
        this.$set(this.form, 'cateId', e[1])
    getCenter(data) {
      // console.log(data)
      // this.$set(this.form, 'postion', data.address)
      if(data.lng){
        this.$set(this.form, 'lnglat', data.lng + ',' + data.lat)
      } else {
        this.$set(this.form, 'catePId', '')
        this.$set(this.form, 'cateId', '')
        this.$set(this.form, 'lnglat', '')
      }
      this.search()
      this.$set(this.form, 'longitude', data.lng)
      this.$set(this.form, 'latitude', data.lat)
    },
    changeSel(e) {
      if (e && e.length == 2) {
        this.$set(this.form, 'areaId', e[1])
      } else {
        this.$set(this.form, 'areaId', '')
      }
    },
    uploadAvatarSuccess(file) {
      this.form.imgurl = file.imgurl
@@ -103,3 +144,11 @@
  }
}
</script>
<style lang="scss" scoped>
.mapbox {
  width: 100%;
  height: 400px;
  margin-bottom: 20px;
  float: left;
}
</style>
admin/src/views/Inspection/dot.vue
@@ -106,11 +106,11 @@
    },
    editClick(row) {
      if (row && row.id) {
        this.$refs.operaYwPatrolPointWindow.open('编辑巡检点')
        this.$refs.operaYwPatrolPointWindow.open('编辑巡检点', row)
      } else {
        this.$refs.operaYwPatrolPointWindow.open('新建巡检点')
      }
      this.$refs.operaYwPatrolPointWindow.initData()
      // this.$refs.operaYwPatrolPointWindow.initData()
    },
    changeSel(e) {
      if (e && e.length == 1) {
admin/src/views/operation/components/deviceEdit.vue
@@ -1,6 +1,6 @@
<template>
  <GlobalWindow :title="param.id ? '编辑设备' : '新建设备'" :confirmWorking="subLoading" :visible.sync="isShowModal" width="600px" @close="close"
    @confirm="handleSub">
  <GlobalWindow :title="param.id ? '编辑设备' : '新建设备'" :confirmWorking="subLoading" :visible.sync="isShowModal"
    width="600px" @close="close" @confirm="handleSub">
    <el-form :model="param" ref="paramRef" :rules="rules">
      <el-form-item label="设备编码" prop="code">
        <el-input v-model="param.code" placeholder="请输入" v-trim />
@@ -12,17 +12,16 @@
        <el-input v-model="param.modelNo" placeholder="请输入" v-trim />
      </el-form-item>
      <el-form-item label="设备分类" prop="">
        <el-cascader v-model="param.areaIds" @change="changeSel" placeholder="请选择巡检区域" clearable :options="cateList"
        <el-cascader v-model="param.areaIds" @change="changeSel" placeholder="请选择设备分类" clearable :options="cateList"
          :props="{
            label: 'name',
            value: 'id',
            children: 'childCategoryList',
            checkStrictly: true
            children: 'childCategoryList'
          }"></el-cascader>
      </el-form-item>
      <el-form-item label="设备管理员" prop="">
        <el-select v-model="param.realName" filterable clearable>
          <el-option value="0" label="xxx"></el-option>
        <el-select v-model="param.userId" clearable filterable class="w400">
          <el-option v-for="item in staffList" :label="item.realname" :value="item.id"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="所在位置" prop="">
@@ -60,6 +59,7 @@
import UploadAvatarImage from '@/components/common/UploadAvatarImage'
import { fetchList } from '@/api/business/category'
import { create, updateById } from '@/api/Inspection/device'
import { getUserList } from '@/api/system/user'
import { Message } from 'element-ui'
export default {
  components: { GlobalWindow, UploadAvatarImage },
@@ -73,6 +73,7 @@
        name: [{ required: true, message: '请输入' }],
        code: [{ required: true, message: '请输入' }]
      },
      staffList: []
    }
  },
@@ -99,6 +100,11 @@
        }
      })
    },
    getStaff() {
      getUserList({}).then(res => {
        this.staffList = res
      })
    },
    initData() {
      fetchList({
        model: { type: 5 },
@@ -107,20 +113,14 @@
      }).then(res => {
        this.cateList = res.records || []
      })
      this.getStaff()
    },
    changeSel(e) {
      if (e && e.length == 1) {
        this.$set(this.param, 'catePId', e[0])
        this.$set(this.param, 'cateId', '')
      } else if (e && e.length == 2) {
        this.$set(this.param, 'catePId', e[0])
        this.$set(this.param, 'cateId', e[1])
      if (e && e.length == 2) {
        this.$set(this.param, 'areaId', e[1])
      } else {
        this.$set(this.param, 'catePId', '')
        this.$set(this.param, 'cateId', '')
        this.$set(this.param, 'areaId', '')
      }
      this.search()
    },
    uploadAvatarSuccess(file) {
      this.$set(this.param, 'imgurl', file.imgurl)
@@ -133,5 +133,3 @@
  }
}
</script>
<style lang="scss" scoped></style>
admin/src/views/project/components/OperaYwRoomWindow.vue
@@ -7,12 +7,14 @@
        </el-select>
      </el-form-item>
      <el-form-item label="所属楼宇" prop="buildingId">
        <el-select v-model="form.buildingId" placeholder="请选择楼宇" clearable>
        <el-select v-model="form.buildingId" @change="changeBuild" placeholder="请选择楼宇" clearable>
          <el-option v-for="item in buildList" :key="item.id" :label="item.name" :value="item.id"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="楼层" prop="floor">
        <el-input v-model="form.floor" placeholder="请输入楼层" v-trim />
        <el-select v-model="form.floor" placeholder="请选择楼层" clearable>
          <el-option v-for="item in floorList" :key="item.id" :label="item.name" :value="item.id"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="房号" prop="roomNum">
        <el-input v-model="form.roomNum" placeholder="请输入房号" v-trim />
@@ -42,6 +44,7 @@
import GlobalWindow from '@/components/common/GlobalWindow'
import { getProjectList } from '@/api/project/ywProject'
import { getBuildList } from '@/api/project/ywBuilding'
import { getFloorList } from '@/api/project/yeFloor'
export default {
  name: 'OperaYwRoomWindow',
  extends: BaseOpera,
@@ -83,6 +86,7 @@
      },
      projectList: [],
      buildList: [],
      floorList: [],
    }
  },
  created() {
@@ -100,10 +104,16 @@
    },
    changeProject(e) {
      this.form.buildingId = ''
      getBuildList({id: e}).then(res => {
      getBuildList({projectId: e}).then(res => {
        this.buildList = res || []
      })
    },
    changeBuild(e) {
      this.form.floor = ''
      getFloorList({buildingId: e}).then(res => {
        this.floorList = res || []
      })
    },
  }
}
</script>
admin/src/views/project/components/floorLevel.vue
@@ -97,6 +97,7 @@
      let page = pagination.page
      fetchList({ capacity, page, model: { buildingId: id } }).then(res => {
        this.list = res.records
        this.pagination.total = res.total
      })
    },
    editClick(row) {
admin/src/views/project/housingList.vue
@@ -34,7 +34,7 @@
        <el-table-column type="selection" width="55"></el-table-column>
        <el-table-column prop="projectName" label="项目" min-width="100px"></el-table-column>
        <el-table-column prop="buildingName" label="楼宇" min-width="70px"></el-table-column>
        <el-table-column prop="floor" label="楼层" min-width="60px"></el-table-column>
        <el-table-column prop="floorName" label="楼层" min-width="60px"></el-table-column>
        <el-table-column prop="roomNum" label="房号" min-width="60px"></el-table-column>
        <el-table-column prop="rentArea" label="计租面积(m²)" min-width="80px"></el-table-column>
        <el-table-column prop="feeArea" label="计费面积(m²)" min-width="80px"></el-table-column>
admin/src/views/workorder/components/OperaYwWorkorderWindow.vue
@@ -1,5 +1,5 @@
<template>
  <GlobalWindow width="800px" :title="title" :visible.sync="visible" :confirm-working="isWorking" @confirm="confirm">
  <GlobalWindow width="800px" :title="title" :visible.sync="visible" @close="close" :confirm-working="isWorking" @confirm="confirm">
    <el-form :model="form" ref="form" :rules="rules">
      <el-form-item label="位置类型" prop="areaType">
        <el-select v-model="form.areaType">
@@ -18,14 +18,14 @@
        </el-select>
      </el-form-item>
      <el-form-item label="选择楼层" prop="floorId">
      <el-form-item v-if="form.areaType == 1" label="选择楼层" prop="floorId">
        <el-select v-model="form.floorId">
          <el-option v-for="item in levelList" clearable filterable :label="item.name" :value="item.id" />
        </el-select>
      </el-form-item>
      <el-form-item v-if="form.areaType == 0" label="选择房间" prop="roomId">
        <el-select v-model="form.roomId" clearable filterable>
          <el-option v-for="item in roomList" :label="item.name" :value="item.id" />
          <el-option v-for="item in roomList" :label="item.roomNum" :value="item.id" />
        </el-select>
      </el-form-item>
      <el-form-item label="分类" prop="cateId">
@@ -74,7 +74,7 @@
import { getProjectList } from '@/api/project/ywProject'
import { getBuildList } from '@/api/project/ywBuilding'
import { getRoomList } from '@/api/project/ywRoom'
import { fetchList } from '@/api/project/yeFloor'
import { getFloorList } from '@/api/project/yeFloor'
import { fetchList as getCateList } from '@/api/business/category.js'
import { rules } from './config'
export default {
@@ -128,7 +128,7 @@
      uploadImgUrl: process.env.VUE_APP_API_PREFIX + '/visitsAdmin/cloudService/public/uploadBatch',
      fileList: [],
      uploadData: {
        folder: 'HIDDEN_DANGER_FILE'
        folder: 'YW_WORKORDER_FILE'
      },
    }
  },
@@ -159,6 +159,10 @@
        }
      })
    },
    close() {
      this.visible = false
      this.$emit('close')
    },
    getProject() {
      getProjectList({}).then(res => {
        this.projectList = res
@@ -175,12 +179,17 @@
    changeBuild(e) {
      this.$set(this.form, 'floorId', '')
      this.$set(this.form, 'roomId', '')
      if(this.form.areaType == 1){
      this.getLevel(e)
      }else{
      this.getRoom(e)
      }
    },
    getLevel(buildingId) {
      fetchList({ model: { buildingId }, capacity: 9999, page: 1 }).then(res => {
        this.levelList = res.records
      getFloorList({ buildingId}).then(res => {
        this.levelList = res
      })
    },
    getRoom(buildingId) {
@@ -195,7 +204,6 @@
      }else{
        this.$set(this.form, 'cateId', '')
      }
    },
    getCate() {
      getCateList({
@@ -247,12 +255,14 @@
          fileurlFull: item.url
        })
      }
      console.log('file', this.fileList)
      // this.$set(this.param, 'faceImg', file.imgurl)
      // console.log('file', this.fileList)
      this.$set(this.form, 'fileList', this.fileList)
      // this.$set(this.param, 'faceImgUrl', file.imgurlfull)
    },
    handleDelImg(i) {
      this.fileList.splice(i, 1)
      this.$set(this.form, 'fileList', this.fileList)
    },
    close() {
      this.isShowModal = false
admin/src/views/workorder/components/detail.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,371 @@
<template>
  <GlobalWindow width="820px" title="工单详情" :visible.sync="visible" :confirm-working="isWorking" @close="close"
    @confirm="confirm">
    <div class="main">
      <div class="title">
        <span>工单详情</span>
        <div>
          <div class="status primaryColor" v-if="info.dealStatus == 0 || info.dealStatus == null">待指派</div>
          <div class="status" v-if="info.dealStatus == 1">已指派</div>
          <div class="status gray" v-if="info.dealStatus == 2">已处理</div>
        </div>
      </div>
      <div class="list">
        <div class="item">
          <div class="la">位置类型</div>
          <div class="val">{{ info.areaType == 0 ? '室内维修' : '公共维修' }}</div>
        </div>
        <div class="item">
          <div class="la">对应位置</div>
          <div class="val">{{ info.buildingName }} / {{ info.roomNum || info.floorName }}</div>
        </div>
        <div class="item">
          <div class="la">工单类别</div>
          <div class="val">{{ info.categoryName }}</div>
        </div>
        <div class="item">
          <div class="la">上报人</div>
          <div class="val">{{ info.creatorName }}</div>
        </div>
        <div class="item">
          <div class="la">上报人电话</div>
          <div class="val">{{ info.creatorPhone }}</div>
        </div>
        <div class="item">
          <div class="la">上报时间</div>
          <div class="val">{{ info.createDate }}</div>
        </div>
        <div class="item max">
          <div class="la">上门时间</div>
          <div class="val">{{ info.getDate }}</div>
        </div>
        <div class="item max">
          <div class="la">问题描述</div>
          <div class="val">{{ info.content }}</div>
        </div>
        <div class="item max">
          <div class="la">问题图片</div>
          <div class="value" v-if="info.fileList == null || !info.fileList.length">无</div>
          <div class="value" v-if="info.fileList != null && info.fileList.length">
            <div v-for="item in info.fileList" :key="item.id" style="display: inline;margin-right: 20px">
              <video v-if="item.fileurlFull && item.fileurlFull.endsWith('.mp4')" ref="videoRef" controls preload="auto"
                style="width: 80px;height: 80px;object-fit: contain;" :src="item.fileurlFull" />
              <el-image v-else-if="item.fileurlFull" style="width:80px; height: 80px" :src="item.fileurlFull"
                :preview-src-list="[item.fileurlFull]">
              </el-image>
            </div>
          </div>
        </div>
      </div>
      <div class="title">工单处理</div>
      <el-form :model="param" ref="form" :rules="rules">
        <template v-if="info.dealStatus == 0 || info.dealStatus == null">
          <el-form-item label="处理方式" prop="dealType">
            <div>
              <el-radio v-model="param.dealType" :label="0">指派</el-radio>
              <el-radio v-model="param.dealType" :label="1">直接回复</el-radio>
            </div>
          </el-form-item>
          <el-form-item v-if="param.dealType == 0" label="指派给" prop="dealUserId">
            <el-select v-model="param.dealUserId" clearable filterable class="w400">
              <el-option v-for="item in staffList" :label="item.realname" :value="item.id"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item v-if="param.dealType == 1" label="回复内容" prop="dealInfo">
            <el-input type="textarea" class="w400" :rows="4" v-model="param.dealInfo" placeholder="请填写说明"></el-input>
          </el-form-item>
        </template>
        <template v-if="info.dealStatus == 1 && info.dealUserId === userInfo.id">
          <el-form-item label="处理时间" prop="getDate">
            <el-date-picker type="datetime" class="w400" v-model="param.getDate" format="yyyy-MM-dd HH:mm"
              value-format="yyyy-MM-dd HH:mm:ss" placeholder="请选择"></el-date-picker>
          </el-form-item>
          <el-form-item label="回复内容" prop="dealInfo">
            <el-input type="textarea" class="w400" :rows="4" v-model="param.dealInfo" placeholder="请填写说明"></el-input>
          </el-form-item>
          <el-form-item label="现场图片">
            <div class="file_list">
              <el-upload class="avatar-uploader" :data="uploadData" multiple :limit="6" :auto-upload="true" :action="uploadImgUrl"
                :show-file-list="false" :on-success="uploadAvatarSuccess" :on-error="uploadError"
                :before-upload="beforeUpload">
                <div class="upload_wrap">
                  <i class="el-icon-plus avatar-uploader-icon"></i>
                  <div>图片/视频</div>
                </div>
              </el-upload>
              <div v-for="(item, i) in dealFileList" :key="i" class="item">
                <i @click="handleDelImg(i)" class="el-icon-error close"></i>
                <el-image :src="item.fileurlFull" :preview-src-list="[item.fileurlFull]" v-if="item.type == 0"
                  class="img"></el-image>
                <video :src="item.fileurlFull" controls v-if="item.type == 1" class="img"></video>
              </div>
            </div>
          </el-form-item>
        </template>
        <template v-if="info.dealStatus == 2">
          <div class="list">
            <div class="item item2">
              <div class="la">处理时间:</div>
              <div class="val">{{ info.getDate }}</div>
            </div>
            <div class="item item2">
              <div class="la">处理备注:</div>
              <div class="val">{{ info.dealInfo }}</div>
            </div>
            <div class="item item2">
              <div class="la">现场照片:</div>
              <div class="value" v-if="info.dealFileList == null || !info.dealFileList.length">无</div>
              <div class="value" v-if="info.dealFileList != null && info.dealFileList.length">
                <div v-for="item in info.dealFileList" :key="item.id" style="display: inline;margin-right: 20px">
                  <video v-if="item.fileurlFull && item.fileurlFull.endsWith('.mp4')" ref="videoRef" controls
                    preload="auto" style="width: 80px;height: 80px;object-fit: contain;" :src="item.fileurlFull" />
                  <el-image v-else-if="item.fileurlFull" style="width:80px; height: 80px" :src="item.fileurlFull"
                    :preview-src-list="[item.fileurlFull]">
                  </el-image>
                </div>
              </div>
            </div>
          </div>
        </template>
      </el-form>
    </div>
  </GlobalWindow>
</template>
<script>
import GlobalWindow from '@/components/common/GlobalWindow'
import BaseOpera from '@/components/base/BaseOpera'
import { detailById, dispatchOrder, dealOrder } from '@/api/workorder/ywWorkorder'
import { getUserList } from '@/api/system/user'
import { Message, Loading } from 'element-ui'
export default {
  components: {
    GlobalWindow
  },
  extends: BaseOpera,
  data() {
    return {
      id: '',
      visible: false,
      param: {
        dealType: 0
      },
      info: {},
      rules: {
        dealType: [{ required: true, message: '请选择' }],
        dealUserId: [{ required: true, message: '请选择' }],
      },
      staffList: [],
      uploadImgUrl: process.env.VUE_APP_API_PREFIX + '/visitsAdmin/cloudService/public/uploadBatch',
      dealFileList: [],
      uploadData: {
        folder: 'HIDDEN_DANGER_FILE'
      },
    }
  },
  computed: {
    userInfo() {
      return this.$store.state.userInfo
    }
  },
  created() {
    this.getStaff()
  },
  methods: {
    confirm() {
      this.$refs['form'].validate((valid) => {
        if (valid) {
          const { param, id, dealFileList, info } = this
          let fn = null
          if(info.dealStatus == 0 || info.dealStatus == null){
            fn = param.dealType == 0 ? dispatchOrder : dealOrder
          }else{
            fn = dealOrder
          }
          fn({
            id,
            ...param,
            dealFileList
          }).then(res => {
            Message.success('提交成功')
            this.visible = false
            this.$emit('success')
          })
        }
      })
    },
    getDetail() {
      const { id } = this
      detailById(id).then(res => {
        this.info = res
      })
    },
    getStaff() {
      getUserList({}).then(res => {
        this.staffList = res
      })
    },
    beforeUpload(file) {
      if (['video/mp4', 'video/ogg', 'video/flv', 'video/avi', 'video/wmv', 'video/rmvb', 'image/jpeg', 'image/jpg', 'image/png', 'image/gif'].indexOf(file.type) == -1) {
        this.$message.error('请上传正确的视频/图片格式')
        return false
      }
      if (this.dealFileList.length > 8) return Message.warning('现场图片不能超过9å¼ ')
      this.loadingInstance = Loading.service({
        lock: true,
        text: 'Loading',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)'
      })
    },
    uploadError() {
      this.$nextTick(() => { // ä»¥æœåŠ¡çš„æ–¹å¼è°ƒç”¨çš„ Loading éœ€è¦å¼‚步关闭
        if (this.loadingInstance) {
          this.loadingInstance.close()
        }
      })
    },
    uploadAvatarSuccess(file) {
      this.$nextTick(() => { // ä»¥æœåŠ¡çš„æ–¹å¼è°ƒç”¨çš„ Loading éœ€è¦å¼‚步关闭
        if (this.loadingInstance) {
          this.loadingInstance.close()
        }
      })
      console.log('file', file)
      const item = file.data[0]
      if (['.mp4', '.avi', '.flv', '.wmv'].some(char => item.imgaddr.includes(char))) {
        this.dealFileList.push({
          type: 1,
          fileurl: item.imgaddr,
          fileurlFull: item.url
        })
      } else {
        this.dealFileList.push({
          type: 0,
          fileurl: item.imgaddr,
          fileurlFull: item.url
        })
      }
      console.log('file', this.dealFileList)
      // this.$set(this.param, 'faceImg', file.imgurl)
      // this.$set(this.param, 'faceImgUrl', file.imgurlfull)
    },
    handleDelImg(i) {
      this.dealFileList.splice(i, 1)
    },
    close() {
      this.visible = false
      this.$emit('close')
    }
  }
}
</script>
<style lang="scss" scoped>
@import '@/assets/style/variables.scss';
.main {
  padding-top: 20px;
  .title {
    font-weight: 500;
    font-size: 18px;
    color: $primary-color;
    margin-bottom: 10px;
    display: flex;
    align-items: center;
    .status {
      padding: 0 6px;
      height: 22px;
      line-height: 22px;
      border-radius: 2px;
      border: 1px solid #00BA92;
      color: #00BA92;
      font-weight: 400;
      font-size: 12px;
      margin-left: 10px;
    }
    .primaryColor {
      border: 1px solid $primary-color;
    }
    .gray {
      color: gray;
      border: 1px solid gray;
    }
  }
  .list {
    display: flex;
    flex-wrap: wrap;
    /* background: #F7F7F7; */
    border-radius: 2px;
    padding: 15px 20px;
    margin-bottom: 16px;
    .item {
      width: 33.3%;
      margin-bottom: 12px;
      .la {
        color: #7f7f7f;
        margin-top: 2px;
      }
    }
    .item2 {
      width: 100%;
      display: flex;
      align-items: center;
    }
    .max {
      width: 100%;
    }
  }
}
.file_list {
  display: flex;
  flex-wrap: wrap;
  .avatar-uploader {
    width: 92px;
    height: 92px;
    display: flex;
    justify-content: center;
    align-items: center;
    border: 1px dashed #d9d9d9;
  }
  .item {
    width: 92px;
    max-height: 92px;
    margin-left: 10px;
    position: relative;
    border: 1px dashed #d9d9d9;
    border-radius: 4px;
    display: flex;
    align-items: center;
    justify-content: center;
    .close {
      font-size: 20px;
      position: absolute;
      right: -10px;
      top: -10px;
      z-index: 111;
      color: red;
      cursor: pointer;
    }
    .img {
      width: 92px;
      max-height: 92px;
    }
  }
}
</style>
admin/src/views/workorder/workorderList.vue
@@ -2,19 +2,35 @@
  <TableLayout :permissions="['business:ywworkorder:query']">
    <!-- æœç´¢è¡¨å• -->
    <el-form ref="searchForm" slot="search-form" :model="searchForm" label-width="100px" inline>
      <el-form-item prop="areaType">
      <el-form-item prop="areaType" label="位置类别">
        <el-select v-model="searchForm.areaType">
          <el-option label="室内维修" value="0"></el-option>
          <el-option label="公共维修" value="1"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="请选择报修区域" prop="buildingId">
        <el-input v-model="searchForm.buildingId" placeholder="请输入所属项目编码(关联yw_building)"
          @keypress.enter.native="search"></el-input>
      <el-form-item label="选择项目" prop="projectId">
        <el-select v-model="searchForm.projectId" @change="getBuild" clearable filterable>
          <el-option v-for="item in projectList" :label="item.name" :value="item.id" />
        </el-select>
      </el-form-item>
      <el-form-item prop="cateId">
        <el-input v-model="searchForm.cateId" placeholder="报修物品类别" @keypress.enter.native="search"></el-input>
      <el-form-item label="选择楼宇" prop="buildingId">
        <el-select v-model="searchForm.buildingId" clearable filterable>
          <el-option v-for="item in buildList" :label="item.name" :value="item.id" />
        </el-select>
      </el-form-item>
      <el-form-item prop="cateId" label="物品类别">
        <el-cascader v-model="searchForm.areaIds" @change="changeSel" placeholder="请选择巡检区域" clearable
          :options="cateList" :props="{
            label: 'name',
            value: 'id',
            children: 'childCategoryList'
          }"></el-cascader>
      </el-form-item>
      <el-form-item label="提交日期">
        <el-date-picker v-model="searchForm.selDate" @change="changeSelDate" format="yyyy-MM-dd"
          value-format="yyyy-MM-dd" type="daterange"></el-date-picker>
      </el-form-item>
      <section>
        <el-button type="primary" @click="search">搜索</el-button>
        <el-button type="primary" :loading="isWorking.export" v-permissions="['business:ywworkorder:exportExcel']"
@@ -37,10 +53,15 @@
            <span v-if="scope.row.areaType == 1">公共区域</span>
          </template>
        </el-table-column>
        <el-table-column prop="" label="报修区域" min-width="100px"></el-table-column>
        <el-table-column prop="cateName" label="报修物品类型" min-width="100px"></el-table-column>
        <el-table-column prop="userName" label="上报人" min-width="100px"></el-table-column>
        <el-table-column prop="submitDate" label="上报时间" min-width="100px"></el-table-column>
        <el-table-column prop="" label="报修区域" min-width="100px">
          <template v-slot="scope">
            <span>{{ scope.row.buildingName }} / {{ scope.row.areaType == 0 ? scope.row.roomNum : scope.row.floorName
              }}</span>
          </template>
        </el-table-column>
        <el-table-column prop="categoryName" label="物品类型" min-width="100px"></el-table-column>
        <el-table-column prop="creatorName" label="上报人" min-width="100px"></el-table-column>
        <el-table-column prop="createDate" label="上报时间" min-width="100px"></el-table-column>
        <el-table-column prop="dealUserName" label="处理人" min-width="100px"></el-table-column>
        <el-table-column label="处理结果" min-width="100px">
          <template slot-scope="{row}">
@@ -49,16 +70,17 @@
            <span v-if="row.dealStatus == 2">已处理</span>
          </template>
        </el-table-column>
        <el-table-column v-if="containPermissions(['business:ywworkorder:update'])"
          label="操作" min-width="80" fixed="right">
        <el-table-column v-if="containPermissions(['business:ywworkorder:update'])" label="操作" min-width="80"
          fixed="right">
          <template slot-scope="{row}">
            <span class="primaryColor cu">查看详情</span>
            <span @click="handleDetail(row)" class="primaryColor cu">查看详情</span>
          </template>
        </el-table-column>
      </el-table>
      <pagination @size-change="handleSizeChange" @current-change="handlePageChange" :pagination="tableData.pagination">
      </pagination>
    </template>
    <Detail v-if="showDetail" ref="DetailRef" @close="showDetail = false" @success="search" />
    <!-- æ–°å»º/修改 -->
    <OperaYwWorkorderWindow ref="operaYwWorkorderWindow" @success="handlePageChange" />
  </TableLayout>
@@ -69,43 +91,29 @@
import TableLayout from '@/layouts/TableLayout'
import Pagination from '@/components/common/Pagination'
import OperaYwWorkorderWindow from './components/OperaYwWorkorderWindow'
import Detail from './components/detail'
import { getBuildList } from '@/api/project/ywBuilding'
import { getProjectList } from '@/api/project/ywProject'
import { fetchList as getCateList } from '@/api/business/category.js'
export default {
  name: 'YwWorkorder',
  extends: BaseTable,
  components: { TableLayout, Pagination, OperaYwWorkorderWindow },
  components: { TableLayout, Pagination,Detail, OperaYwWorkorderWindow },
  data() {
    return {
      // æœç´¢
      showDetail: false,
      searchForm: {
        selDate: [],
        areaType: '',
        creator: '',
        createDate: '',
        editor: '',
        editDate: '',
        isdeleted: '',
        title: '',
        remark: '',
        status: '',
        sortnum: '',
        content: '',
        getDate: '',
        areaIds: '',
        projectId: '',
        buildingId: '',
        roomId: '',
        userId: '',
        phone: '',
        submitDate: '',
        cateId: '',
        code: '',
        dealStatus: '',
        dispatchUserId: '',
        dispatchDate: '',
        dispatchInfo: '',
        dealUserId: '',
        dealDate: '',
        dealInfo: '',
        dealType: ''
      }
      },
      projectList: [],
      buildList: [],
      cateList: [],
    }
  },
  created() {
@@ -116,6 +124,64 @@
      'field.main': 'id'
    })
    this.search()
    this.initData()
  },
  methods: {
    handleDetail(row) {
      this.showDetail = true
      this.$nextTick(() => {
        this.$refs.DetailRef.visible = true
        this.$refs.DetailRef.id = row.id
        this.$refs.DetailRef.getDetail()
      })
    },
    initData() {
      getProjectList({}).then(res => {
        this.projectList = res
      })
      getCateList({
        model: { type: 3 },
        capacity: 1000,
        page: 1,
      }).then(res => {
        this.cateList = res.records || []
      })
    },
    getBuild(projectId) {
      this.$set(this.searchForm, 'buildingId', '')
      getBuildList({ projectId }).then(res => {
        this.buildList = res
      })
    },
    changeSel(e) {
      if (e && e.length == 2) {
        this.$set(this.searchForm, 'cateId', e[1])
      } else {
        this.$set(this.searchForm, 'cateId', '')
      }
    },
    reset() {
      this.searchForm = {
        selDate: [],
        areaType: '',
        areaIds: '',
        projectId: '',
        buildingId: '',
        cateId: '',
      }
      this.search()
    },
    changeSelDate(e) {
      if (e && e.length > 0) {
        this.$set(this.searchForm, 'queryStartTime', e[0] + ' 00:00:00')
        this.$set(this.searchForm, 'queryEndTime', e[1] + ' 23:59:59')
      } else {
        this.$set(this.searchForm, 'queryStartTime', '')
        this.$set(this.searchForm, 'queryEndTime', '')
      }
    },
  }
}
</script>