scenelightCard.vue 21 KB

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