Curtain.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451
  1. <template>
  2. <div class="curtain" v-if="curtainData && curtainData.length">
  3. <div class="curtain-top">
  4. <div class="curtain-desc">
  5. <p class="curtain-title">
  6. {{ curtainData.length && curtainData.length == 1 ? curtainData[0].name : '窗帘' }}
  7. </p>
  8. <p class="curtain-status">
  9. <!-- 窗帘已打开-->
  10. <span class="curtain-tip">{{ countText }}</span>
  11. </p>
  12. <div class="show-all" @click="showAll" v-if="isShowChildLight">
  13. <van-icon
  14. :name="lightIcon"
  15. class="light-icon"
  16. />
  17. <span>显示全部</span>
  18. </div>
  19. </div>
  20. <div class="curtain-right">
  21. <img
  22. :src="parseImgUrl('page-officehome','curtain-img.svg')"
  23. alt=""
  24. >
  25. <div class="curtain-control" v-if="!showFlag">
  26. <div class="control-item mr10"
  27. @click="handleTotal('EquipOffSet')"
  28. :class="{'box-active':curtainClose && count,'control-item-disabled':!userIsControl}"
  29. >
  30. <span class="timer-text" v-if="curtainClose && count">{{ count }}</span>
  31. <img
  32. v-else
  33. :src="parseImgUrl('page-officehome','curtain-close.png')"
  34. alt=""
  35. >
  36. </div>
  37. <div class="control-item"
  38. @click="handleTotal('EquipOnSet')"
  39. :class="{'box-active':curtainOpen && count,'control-item-disabled':!userIsControl}"
  40. >
  41. <span class="timer-text" v-if="curtainOpen && count">{{ count }}</span>
  42. <img
  43. v-else
  44. :src="parseImgUrl('page-officehome','curtain-open.png')"
  45. alt=""
  46. >
  47. </div>
  48. </div>
  49. </div>
  50. </div>
  51. <!--窗帘按钮-->
  52. <div class="child-curtain" v-if="showFlag"
  53. :key="item.id"
  54. v-for="(item,index) in curtainData"
  55. >
  56. <div class="child-title">{{ item.name }}</div>
  57. <div class="curtain-control">
  58. <div class="control-item mr10"
  59. @click="handleChild('EquipOffSet',item.id,index)"
  60. :class="{'box-active':item.curtainClose && count,'control-item-disabled':!userIsControl}"
  61. >
  62. <span class="timer-text" v-if="item.curtainClose && count">{{ count }}</span>
  63. <img
  64. v-else
  65. :src="parseImgUrl('page-officehome','curtain-close.png')"
  66. alt=""
  67. >
  68. </div>
  69. <div class="control-item"
  70. @click="handleChild('EquipOnSet',item.id,index)"
  71. :class="{'box-active':item.curtainOpen && count,'control-item-disabled':!userIsControl}"
  72. >
  73. <span class="timer-text" v-if="item.curtainOpen && count">{{ count }}</span>
  74. <img
  75. v-else
  76. :src="parseImgUrl('page-officehome','curtain-open.png')"
  77. alt=""
  78. >
  79. </div>
  80. </div>
  81. </div>
  82. </div>
  83. </template>
  84. <script lang="ts">
  85. import { computed, defineComponent, onMounted, reactive, toRefs, watch } from 'vue'
  86. import { getObjectDataEqpGroupHttp, setEquipeHttp } from '@/apis/envmonitor'
  87. import { parseImgUrl } from '@/utils'
  88. import { Toast } from 'vant'
  89. export default defineComponent({
  90. props: {
  91. projectId: {
  92. type: String,
  93. default: () => ''
  94. },
  95. spaceId: {
  96. type: String,
  97. default: () => ''
  98. },
  99. userIsControl: {
  100. type: Boolean,
  101. default: () => false
  102. }
  103. },
  104. setup(props) {
  105. let curtainData: any = []
  106. let timer: any = null
  107. let projectId: any = props.projectId
  108. const proxyData = reactive({
  109. curtainData: curtainData,
  110. userIsControl: props.userIsControl,
  111. lightIcon: 'arrow-down',
  112. showFlag: false,
  113. projectId: projectId,
  114. countText: '', // 到记时文案
  115. count: 0, // 到记时
  116. curtainOpen: false,
  117. curtainClose: false,
  118. parseImgUrl: parseImgUrl,
  119. timer: timer,
  120. // 获取窗帘列表
  121. getEqpGroup() {
  122. const params: any = {
  123. criteria: {
  124. projectId: props.projectId,
  125. spaceId: props.spaceId, // 空间ID
  126. type: 0 // 0.窗帘
  127. },
  128. orders: [
  129. {
  130. column: 'sortNum',
  131. asc: true
  132. }
  133. ]
  134. }
  135. getObjectDataEqpGroupHttp(params).then(res => {
  136. const resData: any = res
  137. proxyData.curtainData = resData.count ? resData.content : []
  138. for (let i = 0; i < proxyData.curtainData.length; i++) {
  139. let item = proxyData.curtainData[i]
  140. item.childDownFlag = false
  141. item.childUpFlag = false
  142. item.childCount = 2
  143. item.childCountText = ''
  144. }
  145. })
  146. },
  147. // 点击展示所有的登录
  148. showAll() {
  149. proxyData.showFlag = !proxyData.showFlag
  150. if (proxyData.showFlag) {
  151. proxyData.lightIcon = 'arrow-up'
  152. } else {
  153. proxyData.lightIcon = 'arrow-down'
  154. }
  155. },
  156. checkCount() {
  157. if (proxyData.count > 0) {
  158. return true
  159. } else {
  160. return false
  161. }
  162. },
  163. // 窗帘总开关
  164. handleTotal(setType: string) {
  165. if (proxyData.userIsControl) {
  166. let flag = proxyData.checkCount()
  167. /**
  168. * flag:true 代表指令正在发送中,false:代表当前没有指令在发送
  169. */
  170. if (!flag) { // 只要有一条指令在发送中,要求其它指令不能再发送
  171. proxyData.changeStatus(setType)
  172. let arr = JSON.parse(JSON.stringify(proxyData.curtainData)) // 窗帘数据
  173. let paramsArr = proxyData.setParams(arr, setType)
  174. // 更新窗帘的按钮可点击状态
  175. proxyData.setSwitchStatus(setType)
  176. // 发送窗帘指令
  177. setEquipeHttp(paramsArr).then(res => {
  178. })
  179. }
  180. } else {
  181. Toast('您没有当前空间的控制权限!')
  182. }
  183. },
  184. handleChild(setType: string, id: any, index: any) {
  185. if (proxyData.userIsControl) {
  186. let flag = proxyData.checkCount()
  187. /**
  188. * flag:true 代表指令正在发送中,false:代表当前没有指令在发送
  189. */
  190. if (!flag) { // 只要有一条指令在发送中,要求其它指令不能再发送
  191. let childItem: any = proxyData.curtainData[index]
  192. const params = {
  193. projectId: proxyData.projectId,
  194. objectId: id, // 设备ID/窗帘组ID
  195. equipmentCategory: 'CFSSES', // 设备编码 窗帘:CFSSES
  196. infoCode: setType, // 窗帘开设定:EquipOnSet 窗帘关设定:EquipOffSet
  197. value: 1 // 窗帘 1 移动/停止
  198. }
  199. let paramsArr = []
  200. paramsArr.push(params)
  201. // 更新窗帘的按钮可点击状态
  202. proxyData.changeStatus(setType, childItem)
  203. proxyData.setSwitchStatus(setType, childItem)
  204. // 发送窗帘指令
  205. setEquipeHttp(paramsArr).then(res => {
  206. })
  207. }
  208. } else {
  209. Toast('您没有当前空间的控制权限!')
  210. }
  211. },
  212. clearCurtain() {
  213. proxyData.curtainData.map((item: any) => {
  214. item.curtainClose = false
  215. item.curtainOpen = false
  216. proxyData.curtainClose = false
  217. proxyData.curtainOpen = false
  218. })
  219. },
  220. changeStatus(setType: any, item: any = null) {
  221. proxyData.clearCurtain()
  222. if (setType === 'EquipOffSet') {
  223. if (item) {
  224. item.curtainClose = true
  225. } else {
  226. proxyData.curtainClose = true
  227. }
  228. } else {
  229. if (item) {
  230. item.curtainOpen = true
  231. } else {
  232. proxyData.curtainOpen = true
  233. }
  234. }
  235. },
  236. // 窗帘状态数据
  237. setSwitchStatus(setType: any, item: any = null) {
  238. proxyData.count = 2 // 恢复count
  239. proxyData.countText = '指令下发中'
  240. proxyData.timer = setInterval(() => {
  241. if (proxyData.count === 0) {
  242. proxyData.countText = ''
  243. clearInterval(proxyData.timer)
  244. proxyData.clearCurtain()
  245. }
  246. if (proxyData.count === 1) {
  247. proxyData.countText = '再次点击停止窗帘'
  248. }
  249. if (proxyData.count > 0) {
  250. proxyData.count--
  251. } else {
  252. proxyData.count = 0
  253. }
  254. }, 1000)
  255. },
  256. // 设置发送给后台的窗帘数据
  257. setParams(arr: any, setType: any) {
  258. let paramsArr = []
  259. for (let i = 0; i < arr.length; i++) {
  260. let obj = {
  261. objectId: arr[i].id, // 设备ID/窗帘组ID
  262. equipmentCategory: 'CFSSES', // 设备编码 窗帘:CFSSES
  263. infoCode: setType, // 窗帘开设定:EquipOnSet 窗帘关设定:EquipOffSet
  264. value: 1
  265. }
  266. paramsArr.push(obj)
  267. }
  268. return paramsArr
  269. }
  270. })
  271. const isShowChildLight = computed(() => {
  272. return proxyData.curtainData.length && proxyData.curtainData.length > 1
  273. })
  274. watch(
  275. props,
  276. (newProps: any) => {
  277. if (newProps.spaceId) {
  278. // 当前空间的控制权限
  279. proxyData.getEqpGroup()
  280. proxyData.userIsControl = newProps.userIsControl
  281. }
  282. }
  283. )
  284. onMounted(() => {
  285. // 获取空调信息
  286. proxyData.getEqpGroup()
  287. })
  288. return {
  289. isShowChildLight,
  290. ...toRefs(proxyData)
  291. }
  292. }
  293. })
  294. </script>
  295. <style lang="scss" scoped>
  296. .curtain {
  297. width: 100%;
  298. padding-top: 10px;
  299. padding-right: 10px;
  300. background: #FFFFFF;
  301. box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.07), 0px 4px 10px rgba(0, 0, 0, 0.05);
  302. border-radius: 25px;
  303. margin: 15px 0px;
  304. }
  305. .curtain-top {
  306. padding-left: 20px;
  307. min-height: 130px;
  308. //padding-bottom: 30px;
  309. display: flex;
  310. justify-content: space-between;
  311. }
  312. .curtain-desc {
  313. flex: 1 98px;
  314. padding-top: 10px;
  315. font-family: PingFang SC;
  316. font-size: 16px;
  317. line-height: 19px;
  318. color: #4D5262;
  319. flex: none;
  320. order: 0;
  321. flex-grow: 0;
  322. margin: 5px 0px;
  323. }
  324. .curtain-right {
  325. position: relative;
  326. width: 110px;
  327. text-align: center;
  328. img {
  329. width: 92px;
  330. height: 69px;
  331. }
  332. .curtain-control {
  333. position: absolute;
  334. right: 10px;
  335. bottom: 0px;
  336. }
  337. }
  338. .curtain-title {
  339. font-family: PingFang SC;
  340. padding-left: 5px;
  341. font-size: 16px;
  342. line-height: 19px;
  343. color: #4D5262;
  344. flex: none;
  345. order: 0;
  346. flex-grow: 0;
  347. margin: 5px 0px;
  348. }
  349. .curtain-status {
  350. font-family: PingFang SC;
  351. padding-left: 5px;
  352. font-size: 14px;
  353. line-height: 16px;
  354. color: #C4C4C4;
  355. flex: none;
  356. order: 1;
  357. flex-grow: 0;
  358. margin: 10px 0px;
  359. .curtain-tip {
  360. display: block;
  361. padding-top: 20px;
  362. }
  363. }
  364. .show-all {
  365. font-family: PingFang SC;
  366. //display: none;
  367. .curtain-icon {
  368. font-size: 12px;
  369. padding-right: 10px;
  370. }
  371. padding-top: 10px;
  372. padding-bottom: 22px;
  373. font-size: 14px;
  374. line-height: 16px;
  375. color: #C4C4C4;
  376. margin: 0px 5px;
  377. }
  378. .curtain-control {
  379. text-align: right;
  380. padding-bottom: 15px;
  381. width: 100px;
  382. padding-top: 5px;
  383. //padding-right: 10px;
  384. .control-item {
  385. width: 40px;
  386. display: inline-block;
  387. height: 40px;
  388. text-align: center;
  389. border-radius: 50%;
  390. background: rgba(196, 196, 196, 0.2);
  391. img {
  392. margin-top: 10px;
  393. width: 19px;
  394. height: 19px;
  395. }
  396. }
  397. .control-item-disabled {
  398. opacity: 0.3;
  399. }
  400. .timer-text {
  401. width: 40px;
  402. display: inline-block;
  403. line-height: 40px;
  404. font-size: 18px;
  405. color: #fff;
  406. margin: 0;
  407. text-align: center;
  408. }
  409. }
  410. .child-curtain {
  411. display: flex;
  412. justify-content: space-between;
  413. padding: 10px 15px 0px 28px;
  414. border-top: 1px solid rgba(196, 196, 196, 0.4);
  415. .child-title {
  416. flex: 1 110px;
  417. font-weight: 500;
  418. font-family: PingFang SC;
  419. font-size: 16px;
  420. height: 40px;
  421. line-height: 40px;
  422. color: #4D5262;
  423. }
  424. .curtain-control {
  425. text-align: right;
  426. padding-right: 0;
  427. }
  428. }
  429. </style>