airconditioningCard.vue 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649
  1. <template>
  2. <div class="sceneCard">
  3. <div class="sceneCard-query">
  4. <Query :query-data.sync="queryData" :search="search" :reset="reset" >
  5. <template #extraItem>
  6. <a-form-model-item label="开关:" class="formItem">
  7. <a-select default-value="0" style="width: 120px" v-model="queryData.switch">
  8. <a-select-option value="0"> 全部 </a-select-option>
  9. <a-select-option value="1"> 开 </a-select-option>
  10. <a-select-option value="2"> 关 </a-select-option>
  11. </a-select>
  12. </a-form-model-item>
  13. <a-form-model-item label="模式:" class="formItem">
  14. <a-select default-value="0" style="width: 120px" v-model="queryData.mode">
  15. <a-select-option value="0"> 全部 </a-select-option>
  16. <a-select-option value="cold"> 制冷 </a-select-option>
  17. <a-select-option value="hot"> 制热 </a-select-option>
  18. </a-select>
  19. </a-form-model-item>
  20. <a-form-model-item label="温度:" class="formItem">
  21. <a-select default-value="0" style="width: 120px" v-model="queryData.tm">
  22. <a-select-option value="0"> 全部 </a-select-option>
  23. <a-select-option value="18"> 18°C </a-select-option>
  24. <a-select-option value="19"> 19°C </a-select-option>
  25. <a-select-option value="20"> 20°C </a-select-option>
  26. <a-select-option value="21"> 21°C </a-select-option>
  27. <a-select-option value="22"> 22°C </a-select-option>
  28. <a-select-option value="23"> 23°C </a-select-option>
  29. <a-select-option value="24"> 24°C </a-select-option>
  30. <a-select-option value="25"> 25°C </a-select-option>
  31. <a-select-option value="26"> 26°C </a-select-option>
  32. <a-select-option value="27"> 27°C </a-select-option>
  33. <a-select-option value="28"> 28°C </a-select-option>
  34. </a-select>
  35. </a-form-model-item>
  36. <!--<a-form-model-item label="设备编号:" class="formItem">-->
  37. <!-- <a-input v-model="queryData.deviceNo" placeholder="请输入设备编号" />-->
  38. <!--</a-form-model-item>-->
  39. </template>
  40. </Query>
  41. </div>
  42. <div class="sceneCard-control">
  43. <div style="display: inline-block;width: 50%;text-align: left">
  44. <a-space>
  45. <a-button style="font-size: 12px" size="small" @click="allPowerOff"><a-icon type="poweroff" />全开</a-button>
  46. <a-button style="font-size: 12px" size="small" @click="allPowerOn"><a-icon type="poweroff" />全关</a-button>
  47. <a-button type="primary" size="small" style="font-size: 12px" v-show="!showCard" @click="()=>{this.showBatchCL=true}">批量执行策略</a-button>
  48. </a-space>
  49. </div>
  50. <div style="display: inline-block;width: 50%;text-align: right">
  51. <a-select default-value="0">
  52. <a-select-option value="0">
  53. 按楼层显示
  54. </a-select-option>
  55. <!--<a-select-option value="1">-->
  56. <!-- 按公司-->
  57. <!--</a-select-option>-->
  58. <!--<a-select-option value="2">-->
  59. <!-- 按功能-->
  60. <!--</a-select-option>-->
  61. <!--<a-select-option value="3">-->
  62. <!-- 按分组-->
  63. <!--</a-select-option>-->
  64. </a-select>
  65. <a-button type="link" @click="toggleShowCard"><a-icon type="unordered-list" />
  66. <span v-if="showCard">列表模式</span>
  67. <span v-if="!showCard">卡片模式</span>
  68. </a-button>
  69. </div>
  70. <a-alert type="success" show-icon v-if="selectedRowKeys.length>0" closeText="取消选择" @close="clearSelectRow">
  71. <template #message>
  72. 已选择{{ selectedRowKeys.length }}台设备
  73. </template>
  74. </a-alert>
  75. </div>
  76. <div class="airContainer">
  77. <div class="airContainer-left">
  78. <div class="deviceFloorIndex">
  79. <a-input-search placeholder="请输入楼层"></a-input-search>
  80. <a-anchor :getContainer="getContainer" :target-offset="100" style="margin-top: 12px" @change="floorChange">
  81. <template v-for="item in floors" >
  82. <a-anchor-link :href="'#'+item.label" :key="item.value" >
  83. <template #title>
  84. <!--<span style="display: inline-block;padding-left: 5px; width: 20px;height: 40px;overflow: hidden">-->
  85. <!-- <div style="position: absolute;top: 15px;left: -2px;width: 4px;height: 4px;border-radius: 2px;background-color: #2EA8E6"></div>-->
  86. <!-- <div style="width: 18px;height: 18px;border-bottom: 1px dashed #2EA8E6;" ></div>-->
  87. <!-- <div style="width: 18px;height: 18px;border-left: 1px dashed #2EA8E6" ></div>-->
  88. <!--</span>-->
  89. {{ item.label }}
  90. </template>
  91. </a-anchor-link>
  92. </template>
  93. </a-anchor>
  94. </div>
  95. </div>
  96. <div class="airContainer-right" ref="airContainerRight">
  97. <template v-for="item in floors">
  98. <template v-if="showCard">
  99. <div :key="item.value" style="margin-bottom: 15px">
  100. <a-divider :id="item.label" style="margin: 0 0 15px;padding: 0" orientation="left" dashed >{{ item.label }}</a-divider>
  101. <div style="padding: 0 15px">
  102. <a-row :gutter="[30,12]">
  103. <a-col v-for="device in item.devices" :key="device.id" :span="6">
  104. <DeviceCardAir :item="device" :toggle="toggleOnline" />
  105. </a-col>
  106. </a-row>
  107. </div>
  108. </div>
  109. </template>
  110. <template v-if="!showCard">
  111. <div :key="item.value" :id="item.label" v-show="currFloor==item.label">
  112. <a-table :rowKey=" (record, index) => record.id"
  113. :row-selection="{ selectedRowKeys: selectedRowKeys, onChange: onSelectChange }"
  114. :columns="columns"
  115. :show-header="true"
  116. :data-source="item.devices"
  117. :pagination="false"
  118. :scroll="{ y: 400 }"
  119. >
  120. <template #name="text, record">
  121. <span>{{ record.id }}</span>
  122. </template>
  123. <template #mode="text, record">
  124. <span v-if="text=='hot'">制热</span>
  125. <span v-if="text=='cold'">制冷</span>
  126. </template>
  127. <template #tm="text, record">
  128. <span>{{text}}°C</span>
  129. </template>
  130. <template #isControl="text, record">
  131. <span>是</span>
  132. </template>
  133. <template #online="text, record">
  134. <span v-if="text">
  135. <span style="color: #19b955;background-color: #19b955;width: 15px;height: 15px;display: inline-block;border-radius: 8px;vertical-align: middle">•</span> 在线
  136. </span>
  137. <span v-if="!text">
  138. <span style="color: gray;background-color: gray;width: 15px;height: 15px;display: inline-block;border-radius: 8px;vertical-align: middle">•</span> 离线
  139. </span>
  140. </template>
  141. <template #strategy="text, record">
  142. <span>智慧场景策略配置</span>
  143. </template>
  144. </a-table>
  145. </div>
  146. </template>
  147. </template>
  148. </div>
  149. </div>
  150. <a-modal title="批量执行策略" v-if="showBatchCL" v-model="showBatchCL" width="500" height="300" centered style="max-height: 300px;overflow-y: auto" @ok="handleOk">
  151. <a-form-model :form="formData" :label-col="{span:6}" :wrapperCol="{span:16}" style="overflow-y: auto;height: 450px">
  152. <a-form-item label="选择策略:" class="formItem" >
  153. <a-radio-group v-model="formData.resource">
  154. <a-radio value="1">已有策略</a-radio>
  155. <a-radio value="2">自定义</a-radio>
  156. </a-radio-group>
  157. </a-form-item>
  158. <a-form-item label="策略名称:" class="formItem" >
  159. <template v-if="formData.resource=='1'">
  160. <a-select default-value="0" style="width: 200px" v-model="formData.clId">
  161. <a-select-option value="0"> 策略1 </a-select-option>
  162. <!--<a-select-option v-for="item in companyData" :key="item.value" :value="item.value"> {{ item.label }} </a-select-option>-->
  163. </a-select>
  164. </template>
  165. <template v-else>
  166. <a-input v-model="formData.clName" placeholder="请输入策略名称" />
  167. </template>
  168. </a-form-item>
  169. <a-form-item label="执行方式:" class="formItem" >
  170. <a-select default-value="0" style="width: 200px" v-model="formData.method" >
  171. <a-select-option value="1"> 每日执行 </a-select-option>
  172. <a-select-option value="2"> 工作日与非工作日区别执行 </a-select-option>
  173. </a-select>
  174. </a-form-item>
  175. <a-form-item label="执行时间:" class="formItem" >
  176. <timeRange time-format="yyyy/MM/DD" :time-range="formData.timeRange" />
  177. </a-form-item>
  178. <div style="margin-left: 8%;font-weight: bold;margin-bottom: 15px" v-if="formData.method=='2'" >工作日策略 -</div>
  179. <a-form-item label="开机策略:" class="formItem" >
  180. <a-select default-value="0" style="width: 200px" v-model="formData.openCl">
  181. <a-select-option value="0"> 定时开关机 </a-select-option>
  182. <a-select-option value="1"> 24小时开机 </a-select-option>
  183. </a-select>
  184. </a-form-item>
  185. <a-form-item label="开机时间:" class="formItem" >
  186. <a-time-picker use24-hours v-model="formData.openTime" :disabled="!(formData.openCl=='0')" />
  187. </a-form-item>
  188. <a-form-item label="关机时间:" class="formItem" >
  189. <a-time-picker use24-hours v-model="formData.closeTime" :disabled="!(formData.openCl=='0')" />
  190. </a-form-item>
  191. <a-form-item label="空调模式:" class="formItem" >
  192. <a-select style="width: 200px" v-model="formData.mode">
  193. <a-select-option value="1"> 制冷 </a-select-option>
  194. <a-select-option value="2"> 制热 </a-select-option>
  195. </a-select>
  196. </a-form-item>
  197. <a-form-item label="空调风速:" class="formItem" >
  198. <a-select style="width: 200px" v-model="formData.wind">
  199. <a-select-option value="1"> 一级 </a-select-option>
  200. <a-select-option value="2"> 二级 </a-select-option>
  201. <a-select-option value="3"> 三级 </a-select-option>
  202. <a-select-option value="0"> 自动 </a-select-option>
  203. </a-select>
  204. </a-form-item>
  205. <a-form-item label="设置温度:" class="formItem" >
  206. <a-select style="width: 200px" v-model="formData.tm">
  207. <a-select-option value="18"> 18°C </a-select-option>
  208. <a-select-option value="19"> 19°C </a-select-option>
  209. <a-select-option value="20"> 20°C </a-select-option>
  210. <a-select-option value="21"> 21°C </a-select-option>
  211. <a-select-option value="22"> 22°C </a-select-option>
  212. <a-select-option value="23"> 23°C </a-select-option>
  213. <a-select-option value="24"> 24°C </a-select-option>
  214. <a-select-option value="25"> 25°C </a-select-option>
  215. <a-select-option value="26"> 26°C </a-select-option>
  216. <a-select-option value="27"> 27°C </a-select-option>
  217. <a-select-option value="28"> 28°C </a-select-option>
  218. </a-select>
  219. </a-form-item>
  220. <a-form-item label="人体感应:" class="formItem" >
  221. <a-select default-value="0" style="width: 200px" v-model="formData.sensor">
  222. <a-select-option value="0"> 无 </a-select-option>
  223. </a-select>
  224. </a-form-item>
  225. <div v-if="formData.method=='2'">
  226. <div style="margin-left: 8%;font-weight: bold;margin-bottom: 15px" >非工作日策略 -</div>
  227. <a-form-item label="开机策略:" class="formItem" >
  228. <a-select default-value="0" style="width: 200px" v-model="formData.openCl">
  229. <a-select-option value="0"> 定时开关机 </a-select-option>
  230. <a-select-option value="1"> 24小时开机 </a-select-option>
  231. </a-select>
  232. </a-form-item>
  233. <a-form-item label="开机时间:" class="formItem" >
  234. <a-time-picker use24-hours v-model="formData.openTime" :disabled="!(formData.openCl=='0')"/>
  235. </a-form-item>
  236. <a-form-item label="关机时间:" class="formItem" >
  237. <a-time-picker use24-hours v-model="formData.closeTime" :disabled="!(formData.openCl=='0')" />
  238. </a-form-item>
  239. <a-form-item label="空调模式:" class="formItem" >
  240. <a-select style="width: 200px" v-model="formData.mode">
  241. <a-select-option value="1"> 制冷 </a-select-option>
  242. <a-select-option value="2"> 制热 </a-select-option>
  243. </a-select>
  244. </a-form-item>
  245. <a-form-item label="空调风速:" class="formItem" >
  246. <a-select style="width: 200px" v-model="formData.wind">
  247. <a-select-option value="1"> 一级 </a-select-option>
  248. <a-select-option value="2"> 二级 </a-select-option>
  249. <a-select-option value="3"> 三级 </a-select-option>
  250. <a-select-option value="0"> 自动 </a-select-option>
  251. </a-select>
  252. </a-form-item>
  253. <a-form-item label="设置温度:" class="formItem" >
  254. <a-select style="width: 200px" v-model="formData.tm">
  255. <a-select-option value="18"> 18°C </a-select-option>
  256. <a-select-option value="19"> 19°C </a-select-option>
  257. <a-select-option value="20"> 20°C </a-select-option>
  258. <a-select-option value="21"> 21°C </a-select-option>
  259. <a-select-option value="22"> 22°C </a-select-option>
  260. <a-select-option value="23"> 23°C </a-select-option>
  261. <a-select-option value="24"> 24°C </a-select-option>
  262. <a-select-option value="25"> 25°C </a-select-option>
  263. <a-select-option value="26"> 26°C </a-select-option>
  264. <a-select-option value="27"> 27°C </a-select-option>
  265. <a-select-option value="28"> 28°C </a-select-option>
  266. </a-select>
  267. </a-form-item>
  268. <a-form-item label="人体感应:" class="formItem" >
  269. <a-select default-value="0" style="width: 200px" v-model="formData.sensor">
  270. <a-select-option value="0"> 无 </a-select-option>
  271. </a-select>
  272. </a-form-item>
  273. </div>
  274. </a-form-model>
  275. </a-modal>
  276. </div>
  277. </template>
  278. <script>
  279. import Query from "@/components/common/query.vue";
  280. import DeviceCardAir from "@/components/scene/energy/common/deviceCardAir.vue";
  281. import timeRange from "@/components/common/timeRange.vue";
  282. export default {
  283. components: {
  284. Query,
  285. DeviceCardAir,
  286. timeRange,
  287. },
  288. data() {
  289. return {
  290. formData: {},
  291. currFloor: '1F',
  292. showCard: true,
  293. showBatchCL: false,
  294. queryData: {
  295. switch: '0',
  296. mode: '0',
  297. tm: '0'
  298. },
  299. selectedRowKeys: [],
  300. columns: [
  301. {
  302. title: '名称',
  303. dataIndex: 'name',
  304. key: 'name',
  305. scopedSlots: { customRender: 'name' },
  306. },
  307. {
  308. title: '模式',
  309. dataIndex: 'mode',
  310. key: 'mode',
  311. scopedSlots: { customRender: 'mode' },
  312. },
  313. {
  314. title: '温度',
  315. dataIndex: 'tm',
  316. key: 'tm',
  317. scopedSlots: { customRender: 'tm' },
  318. },
  319. {
  320. title: '风速',
  321. dataIndex: 'wind',
  322. key: 'wind',
  323. },
  324. {
  325. title: '是否支持调控',
  326. dataIndex: 'isControl',
  327. key: 'isControl',
  328. scopedSlots: { customRender: 'isControl' },
  329. },
  330. {
  331. title: '状态',
  332. dataIndex: 'online',
  333. key: 'online',
  334. scopedSlots: { customRender: 'online' },
  335. },
  336. {
  337. title: '执行策略',
  338. dataIndex: 'strategy',
  339. key: 'strategy',
  340. scopedSlots: { customRender: 'strategy' },
  341. },
  342. ],
  343. oriFloors: [],
  344. floors: [
  345. {
  346. label: '1F',
  347. value: '1',
  348. devices: [
  349. {
  350. id: '1101-1',
  351. mode: 'hot',
  352. tm: '26',
  353. wind: '一级',
  354. online: true
  355. },{
  356. id: '1101-2',
  357. mode: 'hot',
  358. tm: '26',
  359. wind: '一级',
  360. online: true
  361. },{
  362. id: '1102-1',
  363. mode: 'hot',
  364. tm: '26',
  365. wind: '一级',
  366. online: true
  367. },{
  368. id: '1102-2',
  369. mode: 'hot',
  370. tm: '26',
  371. wind: '一级',
  372. online: true
  373. },
  374. ]
  375. },
  376. {
  377. label: '2F',
  378. value: '2',
  379. devices: [
  380. {
  381. id: '2101-1',
  382. mode: 'cold',
  383. tm: '26',
  384. wind: '一级',
  385. online: true
  386. },{
  387. id: '2101-2',
  388. mode: 'hot',
  389. tm: '26',
  390. wind: '一级',
  391. online: true
  392. }
  393. ]
  394. },
  395. {
  396. label: '3F',
  397. value: '3',
  398. devices: [
  399. {
  400. id: '3101-1',
  401. mode: 'hot',
  402. tm: '26',
  403. wind: '一级',
  404. online: true
  405. },{
  406. id: '3101-2',
  407. mode: 'hot',
  408. tm: '26',
  409. wind: '一级',
  410. online: true
  411. }
  412. ]
  413. },
  414. {
  415. label: '4F',
  416. value: '4',
  417. devices: [
  418. {
  419. id: '4101-1',
  420. mode: 'hot',
  421. tm: '26',
  422. wind: '一级',
  423. online: true
  424. },{
  425. id: '4101-2',
  426. mode: 'hot',
  427. tm: '26',
  428. wind: '一级',
  429. online: true
  430. }
  431. ]
  432. },
  433. {
  434. label: '5F',
  435. value: '5',
  436. devices: [
  437. {
  438. id: '5101-1',
  439. mode: 'hot',
  440. tm: '26',
  441. wind: '一级',
  442. online: true,
  443. },{
  444. id: '5101-2',
  445. mode: 'hot',
  446. tm: '26',
  447. wind: '一级',
  448. online: true
  449. }
  450. ]
  451. },
  452. {
  453. label: '6F',
  454. value: '6',
  455. devices: [
  456. {
  457. id: '6101-1',
  458. mode: 'hot',
  459. tm: '26',
  460. wind: '一级',
  461. online: true
  462. },{
  463. id: '6101-2',
  464. mode: 'hot',
  465. tm: '26',
  466. wind: '一级',
  467. online: true
  468. }
  469. ]
  470. },
  471. {
  472. label: '7F',
  473. value: '7',
  474. devices: [
  475. {
  476. id: '7101-1',
  477. mode: 'hot',
  478. tm: '26',
  479. wind: '一级',
  480. online: true
  481. },{
  482. id: '7101-2',
  483. mode: 'hot',
  484. tm: '26',
  485. wind: '一级',
  486. online: true
  487. }
  488. ]
  489. },
  490. ]
  491. }
  492. },
  493. mounted() {
  494. this.oriFloors = JSON.parse(JSON.stringify(this.floors));
  495. },
  496. methods: {
  497. clearSelectRow() {
  498. this.selectedRowKeys = []
  499. },
  500. reset() {
  501. this.floors = JSON.parse(JSON.stringify(this.oriFloors));
  502. },
  503. handleOk() {
  504. this.showBatchCL = false;
  505. this.$message.success('设置成功')
  506. },
  507. search() {
  508. let objarr = JSON.parse(JSON.stringify(this.oriFloors));
  509. let app = this
  510. objarr.forEach(item=>{
  511. if (item.devices) {
  512. item.devices = item.devices.filter(item=>{
  513. if (!app.queryData.switch || app.queryData.switch=='0') {
  514. } else {
  515. return app.queryData.switch==item.online
  516. }
  517. if (!app.queryData.mode || app.queryData.mode=='0') {
  518. } else {
  519. return app.queryData.mode==item.mode
  520. }
  521. if (!app.queryData.tm || app.queryData.tm=='0') {
  522. } else {
  523. return app.queryData.tm==item.tm
  524. }
  525. return true;
  526. })
  527. }
  528. })
  529. this.floors = objarr
  530. },
  531. onSelectChange(val) {
  532. this.selectedRowKeys = val
  533. },
  534. toggleOnline(device) {
  535. device.online=!device.online;
  536. },
  537. floorChange(val) {
  538. let obj = val.replace('#','')
  539. this.currFloor = obj;
  540. //console.log(this.currFloor)
  541. },
  542. getContainer() {
  543. return this.$refs.airContainerRight
  544. },
  545. toggleShowCard() {
  546. this.showCard = !this.showCard;
  547. },
  548. allPowerOn() {
  549. this.floors.forEach(item=>{
  550. if (item.devices) {
  551. item.devices.forEach(i=>{
  552. i.online = false
  553. })
  554. }
  555. })
  556. },
  557. allPowerOff() {
  558. this.floors.forEach(item=>{
  559. if (item.devices) {
  560. item.devices.forEach(i=>{
  561. i.online = true
  562. })
  563. }
  564. })
  565. }
  566. }
  567. }
  568. </script>
  569. <style lang="less" scoped>
  570. .formItem {
  571. margin: 12px 0;
  572. }
  573. .sceneCard {
  574. width: 100%;
  575. height: 100%;
  576. .sceneCard-query {
  577. }
  578. .sceneCard-control {
  579. margin-top: 12px;
  580. }
  581. .airContainer {
  582. width: 100%;
  583. height: 600px;
  584. padding: 15px 8px;
  585. .airContainer-left {
  586. background-color: #fafafa;
  587. width: 20%;
  588. height: 100%;
  589. display: inline-block;
  590. vertical-align: top;
  591. padding: 12px;
  592. overflow-y: auto;
  593. }
  594. .airContainer-right {
  595. display: inline-block;
  596. width: 80%;
  597. height: 100%;
  598. vertical-align: top;
  599. padding: 12px 20px;
  600. overflow-y: auto;
  601. }
  602. .ant-anchor-link {
  603. line-height: 45px;
  604. font-size: 16px;
  605. }
  606. .ant-anchor-link-active {
  607. background-color: #e0effa;
  608. border-radius: 0px 4px 4px 0px;
  609. }
  610. }
  611. }
  612. </style>