ソースを参照

Merge branch 'V0.0.7' of http://10.87.21.221:8000/jzyd_yyds/soc_app into V0.0.7

zhulu 1 年間 前
コミット
4531877792

+ 12 - 0
src/router/router.config.js

@@ -208,6 +208,18 @@ export let routers = [
         meta: { title: 'UPS诊断详情', keepAlive: false,  deep: 2 }
       },
       {
+        path: '/iot/airconditioner',
+        name: 'iot_airconditioner',
+        component: () => import('@/views/menu/iot/airConditioner/index'),
+        meta: { title: '空调管理', keepAlive: true , deep: 1}
+      },
+      {
+        path: '/iot/airconditioner/detail',
+        name: 'iot_airconditioner_detail',
+        component: () => import('@/views/menu/iot/airConditioner/detail'),
+        meta: { title: '空调详情', keepAlive: false,  deep: 2 }
+      },
+      {
         path: '/iot/board',
         name: 'iot_board',
         component: () => import('@/views/menu/iot/board'),

+ 45 - 0
src/views/menu/iot/airConditioner/components/dialog.adjust.vue

@@ -0,0 +1,45 @@
+<template>
+  <van-dialog @confirm="onConfirm" v-model="show" show-cancel-button>
+    <div style="margin: 10px">
+      <van-cell-group>
+        <van-cell :title="stateText + '调节'">
+          <template #default>
+            <van-stepper v-model="value" :min="min" :max="max"></van-stepper>
+          </template>
+        </van-cell>
+      </van-cell-group>
+    </div>
+  </van-dialog>
+</template>
+
+<script>
+import dayjs from 'dayjs'
+
+export default {
+  data() {
+    return {
+      show: false,
+      value: null,
+      min: null,
+      max: null,
+      info: {},
+      stateText: ''
+    }
+  },
+  props: {},
+  methods: {
+    dayjs,
+    onConfirm() {
+      this.$emit('success', this.state, this.stateText)
+    },
+    open(value, state, stateText, min, max) {
+      this.value = value
+      this.state = state
+      this.stateText = stateText
+      this.min = min
+      this.max = max
+      this.show = true
+    }
+  }
+}
+</script>

+ 34 - 0
src/views/menu/iot/airConditioner/components/dialog.mode.vue

@@ -0,0 +1,34 @@
+<template>
+  <van-dialog @confirm="onConfirm" v-model="show" show-cancel-button>
+    <div style="margin: 10px">
+      <div>确定将空调模式切换为{{ stateText }}?</div>
+    </div>
+  </van-dialog>
+</template>
+
+<script>
+import dayjs from 'dayjs'
+
+export default {
+  data() {
+    return {
+      show: false,
+      info: {},
+      stateText: '',
+      time: new Date()
+    }
+  },
+  props: {},
+  methods: {
+    dayjs,
+    onConfirm() {
+      this.$emit('success', this.state,this.stateText)
+    },
+    open(state, stateText) {
+      this.state = state
+      this.stateText = stateText
+      this.show = true
+    }
+  }
+}
+</script>

+ 34 - 0
src/views/menu/iot/airConditioner/components/dialog.offon.vue

@@ -0,0 +1,34 @@
+<template>
+  <van-dialog @confirm="onConfirm" v-model="show" show-cancel-button>
+    <div style="margin: 10px">
+      <div>确定对空调发送{{ stateText }}指令?</div>
+    </div>
+  </van-dialog>
+</template>
+
+<script>
+import dayjs from 'dayjs'
+
+export default {
+  data() {
+    return {
+      show: false,
+      info: {},
+      stateText: '',
+      time: new Date()
+    }
+  },
+  props: {},
+  methods: {
+    dayjs,
+    onConfirm() {
+      this.$emit('success', this.state,this.stateText)
+    },
+    open(state, stateText) {
+      this.state = state
+      this.stateText = stateText
+      this.show = true
+    }
+  }
+}
+</script>

+ 101 - 0
src/views/menu/iot/airConditioner/components/item.vue

@@ -0,0 +1,101 @@
+<template>
+  <div class="flex flex-col justify-center k-app-list__item van-clearfix">
+    <van-cell-group clickable @click="itemClick">
+      <van-cell :title="data.deviceName" value-class="cell-title-value" title-style="width:100% ;margin-left:10px;">
+        <template #icon>
+          <van-tag type="primary">{{ data.deviceType }}</van-tag>
+        </template>
+        <template #right-icon>
+          <!-- <van-tag type="danger" v-if="data.state === 1">{{ data.stateText }}</van-tag> -->
+          <!-- <van-tag color="gray" text-color="black" v-else-if="data.state == null">未知</van-tag> -->
+          <van-tag type="primary">{{ data.stateText }}</van-tag>
+        </template>
+      </van-cell>
+      <van-cell title="所属机构" :value="data.orgName"></van-cell>
+      <van-cell title="环境温湿度">
+        <template #default>
+          {{data.temperature}}°C、{{data.humidity}}%
+        </template>
+      </van-cell>
+    </van-cell-group>
+  </div>
+</template>
+<script>
+import { mapGetters } from 'vuex'
+import dayjs from 'dayjs'
+export default {
+  components: {},
+  data() {
+    return {}
+  },
+  computed: {
+    ...mapGetters(['orgName', 'orgId', 'dictionary']),
+    stateUpdateTimeText() {
+      if (this.data.stateUpdateTime == null) {
+        return '未上报'
+      }
+
+      return dayjs(this.data.stateUpdateTime).format('YYYY年M月D日H时m分');
+    },    
+  },
+  watch: {},
+  props: {
+    data: {},
+    statusOptions: {}
+  },
+  methods: {
+    itemClick() {
+      this.$router.push('/iot/airconditioner/detail?id=' + this.data.id)
+    }
+  },
+  async created() {},
+  async mounted() {}
+}
+</script>
+<style lang="scss" scoped>
+.cell-title-value {
+  display: none;
+}
+.k-app-list__item {
+  //   height: 11.85rem;
+  background: #ffffff;
+  margin: 0.3rem 0.325rem 0;
+  font-size: 3.733333vw;
+  .top {
+    // min-height: 3rem;
+    padding: 0.05rem 0.05rem;
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+    border-bottom: 1px solid #f3f4f5;
+    > label {
+      //   height: 1.38rem;
+      // font-size: 1rem;
+      //   line-height: 1.25rem;
+      color: #323233;
+      opacity: 1;
+    }
+  }
+  .bottom {
+    min-height: 7.75rem;
+    padding: 0 1rem;
+    span {
+      height: 1.25rem;
+      font-size: 0.88rem;
+      line-height: 1.25rem;
+      color: #000000;
+      opacity: 0.61;
+    }
+  }
+}
+.wrapper {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  height: 100%;
+}
+
+.time-cell-default {
+  min-width: 60vw;
+}
+</style>

+ 150 - 0
src/views/menu/iot/airConditioner/detail.vue

@@ -0,0 +1,150 @@
+<template>
+  <div class="detail">
+    <nav-bar></nav-bar>
+    <card title="基本信息">
+      <van-cell-group>
+        <van-cell title="名称" :value="info.deviceName" />
+        <van-cell title="连接状态">
+          <template #default><van-tag type="primary">已连接</van-tag></template>
+        </van-cell>
+        <van-cell title="所属机构" :value="info.orgName" />
+        <van-cell title="设备品牌" :value="info.brandName" />
+        <van-cell title="探头温度1">
+          <template #default>{{ info.temperature1 }}°C</template>
+        </van-cell>
+        <van-cell title="探头温度2">
+          <template #default>{{ info.temperature2 }}°C</template>
+        </van-cell>
+        <van-cell title="空调湿度">
+          <template #default>{{ info.humidity }}%</template>
+        </van-cell>
+        <van-cell title="更新时间" value-class="cell-updatetime-value">
+          <template #default>{{ stateUpdateTimeText }}</template>
+        </van-cell>
+      </van-cell-group>
+    </card>
+    <card title="空调控制">
+      <van-cell-group>
+        <van-cell title="空调控制">
+          <template #default>
+            <van-button type="info" size="small" @click="onOnOffClick(1, '开机')">开机</van-button>
+            <span style="display: inline-block; width: 3vw" />
+            <van-button type="info" size="small" @click="onOnOffClick(0, '关机')">关机</van-button>
+          </template>
+        </van-cell>
+        <van-cell title="模式选择">
+          <template #default>
+            <van-button type="info" size="small" @click="onModeSwitchClick(1, '制热')">制热</van-button>
+            <span style="display: inline-block; width: 3vw" />
+            <van-button type="info" size="small" @click="onModeSwitchClick(2, '制冷')">制冷</van-button>
+            <span style="display: inline-block; width: 3vw" />
+            <van-button type="info" size="small" @click="onModeSwitchClick(3, '除湿')">除湿</van-button>
+          </template>
+        </van-cell>
+        <van-cell title="温度调节">
+          <template #default>
+            <van-button type="info" size="small" @click="onAdjustClick(info.temperature1, 1, '温度', 16, 40)"
+              >温度{{ info.temperature1 }}°C</van-button
+            >
+            <span style="display: inline-block; width: 3vw" />
+            <van-button type="info" size="small" @click="onAdjustClick(info.temperature2, 2, '温度', 16, 40)"
+              >温度{{ info.temperature2 }}°C</van-button
+            >
+          </template>
+        </van-cell>
+        <van-cell title="湿度调节">
+          <template #default>
+            <van-button type="info" size="small" @click="onAdjustClick(info.humidity, 3, '湿度', 50, 100)"
+              >湿度{{ info.humidity }}%</van-button
+            >
+          </template>
+        </van-cell>
+      </van-cell-group>
+    </card>
+    <OnOff ref="onoffDialog" @success="onOnOff"></OnOff>
+    <ModeSwitch ref="modelSwitchDialog" @success="onModeSwitch"></ModeSwitch>
+    <Adjust ref="adjustDialog" @success="onAdjust"></Adjust>
+  </div>
+</template>
+<script>
+import NavBar from '@/components/NavBar'
+import dayjs from 'dayjs'
+import { durationText } from '@/utils/date.js'
+import Card from '@/components/card'
+import OnOff from './components/dialog.offon.vue'
+import ModeSwitch from './components/dialog.mode.vue'
+import Adjust from './components/dialog.adjust.vue'
+import { Toast } from 'vant'
+export default {
+  data() {
+    return {
+      info: {},
+      search: {
+        sensorId: this.$route.query.id
+      }
+    }
+  },
+  components: { NavBar, Card, OnOff, ModeSwitch, Adjust },
+  computed: {
+    stateUpdateTimeText() {
+      if (this.info.stateUpdateTime == null) {
+        return '未上报'
+      }
+
+      return dayjs(this.info.stateUpdateTime).format('YYYY年M月D日H时m分')
+    }
+  },
+  mounted() {
+    this.getInfo()
+  },
+  methods: {
+    getInfo() {
+      this.info = {
+        deviceName: '大厅空调',
+        orgName: '六一分理处',
+        brandName: '格力',
+        stateUpdateTime: dayjs().add(-1000, 'second').format('YYYY-MM-DD HH:mm:ss'),
+        temperature1: 30,
+        temperature2: 28,
+        humidity: 70
+      }
+    },
+    onOnOffClick(state, stateText) {
+      this.$refs['onoffDialog'].open(state, stateText)
+    },
+    onModeSwitchClick(state, stateText) {
+      this.$refs['modelSwitchDialog'].open(state, stateText)
+    },
+    onAdjustClick(current, state, stateText, min, max) {
+      this.$refs['adjustDialog'].open(current, state, stateText, min, max)
+    },
+    onOnOff(state, stateText) {
+      Toast(stateText + '指令发送成功')
+    },
+    onModeSwitch(state, stateText) {
+      Toast(stateText + '指令发送成功')
+    },
+    onAdjust(state, stateText) {
+      Toast(stateText + '调节指令发送成功')
+    }
+  }
+}
+</script>
+<style lang="scss" scoped>
+.cell-title-value {
+  display: none;
+}
+.detail {
+  margin: 15px;
+
+  ::v-deep .title {
+    font-weight: 700;
+  }
+}
+.cell-gather-alarm-value {
+  color: #ee0a24;
+}
+.cell-updatetime-value{
+  min-width: 60vw;
+}
+</style>

+ 196 - 0
src/views/menu/iot/airConditioner/index.vue

@@ -0,0 +1,196 @@
+<template>
+  <div class="page_list">
+    <nav-bar></nav-bar>
+    <van-row>
+      <van-col span="24">
+        <org-tree
+          v-model="search.orgId"
+          @changeItem="changeTree"
+          @checked="orgCheckChanged"
+          showChecked
+          defaultChecked
+        ></org-tree>
+      </van-col>
+    </van-row>
+    <!-- <van-row>
+      <van-col span="24">
+        <van-cell title="UPS状态" @click="showStatus = true" is-link arrow-direction="down" :value="defaultStatus" />
+        <van-popup v-model="showStatus" round position="bottom">
+          <van-picker
+            title="UPS状态"
+            show-toolbar
+            :columns="statusOptions"
+            @confirm="onStatusConfirm"
+            @cancel="onCancel"
+            default-index="0"
+            :close-on-click-overlay="false"
+          />
+        </van-popup>
+      </van-col>
+    </van-row> -->
+    <div class="container">
+      <k-list :list="list" :params="search" :auto="false" ref="list">
+        <template slot-scope="{ data }">
+          <item :data="data" :statusOptions="deviceTypeOptions"></item>
+        </template>
+      </k-list>
+    </div>
+  </div>
+</template>
+
+<script>
+import NavBar from '@/components/NavBar'
+// import Calendar from '@/components/Calendar';
+import { mapGetters } from 'vuex'
+import { deptTreeList } from '@/api/public'
+// import { list, stateStatistic } from '@/api/iot/donghuan.js'
+import KList from '@/components/list/index.vue'
+import Item from './components/item.vue'
+import OrgTree from '@/components/orgTree'
+import dayjs from 'dayjs'
+export default {
+  components: { NavBar, KList, Item, OrgTree },
+  name: 'iot_ups',
+  data() {
+    return {
+      search: {
+        orgId: this.orgId,
+        checkSub: true,
+        deviceType: null,
+        state: null,
+        pageNum: 1,
+        pageSize: 10
+      },
+      statusStatistic: null,
+      showDeviceType: false,
+      defaultDeviceType: '全部',
+      showStatus: false,
+      defaultStatus: '全部',
+      dicts: ['sensor_alarm_status']
+    }
+  },
+  watch: {},
+  created() {},
+  mounted() {
+    this.search.orgId = this.orgId
+  },
+  computed: {
+    ...mapGetters(['orgName', 'orgId', 'dictionary']),
+    statusOptions() {
+      let r = [{ value: null, text: '全部' }]
+
+      let dict = this.getDictItem('sensor_alarm_status')
+      if (dict) {
+        dict.forEach(element => {
+          let label = element.dictLabel
+
+          if (element.dictValue == 0 && this.statusStatistic) {
+            label += `(${this.statusStatistic.normal})`
+          } else if (element.dictValue == 1 && this.statusStatistic) {
+            label += `(${this.statusStatistic.alarm})`
+          }
+          r.push({ value: element.dictValue, text: label })
+        })
+      }
+
+      return r
+    }
+  },
+  methods: {
+    list() {
+      return {        
+        total: 3,
+        rows: [
+          {
+            orgName: '六一分理处',
+            deviceName: '大厅空调',
+            stateText:'已连接',
+            temperature: 30,
+            humidity: 70,
+            stateUpdateTime: dayjs().add(-1000, 'second').format('YYYY-MM-DD HH:mm:ss')
+          },
+          {
+            orgName: '六一分理处',
+            deviceName: '设备间空调',
+            stateText:'已连接',
+            temperature: 28,
+            humidity: 60,
+            stateUpdateTime: dayjs().add(-100, 'second').format('YYYY-MM-DD HH:mm:ss')
+          },
+          {
+            orgName: '六一分理处',
+            deviceName: '现金区空调',
+            stateText:'已连接',
+            temperature: 26,
+            humidity: 71,
+            stateUpdateTime: dayjs().add(-300, 'second').format('YYYY-MM-DD HH:mm:ss')
+          }
+        ]
+      }
+    },
+    onStatusConfirm(opt) {
+      this.defaultState = opt.text
+      this.search.state = opt.value
+      this.showStatus = false
+    },
+    onCancel() {
+      this.showAlarmType = false
+      this.showStatus = false
+    },
+    //改变机构后将重新发起请求
+    changeTree(node) {
+      this.search.orgId = node.id
+    },
+
+    orgCheckChanged(v) {
+      this.search.checkSub = v
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.page_list {
+  background-color: transparent;
+  display: block;
+
+  .container {
+    // overflow: auto;
+    // height: calc(100vh - 11rem);
+    .k-content-repair {
+      display: flex;
+      flex-direction: column;
+      justify-content: space-between;
+      flex: 1;
+    }
+  }
+}
+
+.search-devicetype {
+  width: 25%;
+  display: inline-block;
+  text-align: center;
+  margin-top: 10px;
+}
+.search-state {
+  width: 100%;
+  margin-top: 10px;
+  padding-left: 10px;
+  padding-right: 10px;
+  > span {
+    width: 50%;
+    border: solid 1px rgb(196, 196, 196);
+    display: inline-block;
+    text-align: center;
+    padding-top: 1.2vw;
+    padding-bottom: 1.2vw;
+  }
+}
+
+.alarm_state_selected {
+  background-color: #409eff;
+  border-color: #409eff;
+  color: white;
+  font-weight: 700;
+}
+</style>