floorList.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. /**
  2. *@author:Guoxiaohuan
  3. *@date:2020.06.02
  4. *@info:楼层列表
  5. */
  6. <template>
  7. <div class='floor-box'>
  8. <div class='floor-list'>
  9. <div class='icon-top' v-if='floorsArr.length>showNumber'>
  10. <!-- @click='changeFloor(1,currIndex)' -->
  11. <img v-show='parseInt(marginTop) !== 0' v-repeat-click='increase' src='@/assets/imgs/iconBlackTop.png' alt />
  12. <img class='disabled' v-show='parseInt(marginTop) === 0' src='@/assets/imgs/iconLightTop.png' alt />
  13. </div>
  14. <div class='floor-out' :style='{ maxHeight:conHeight + "px;" }'>
  15. <!-- 放开marginTop样式 -->
  16. <div class='floor-center' :style='{ marginTop : marginTop }'>
  17. <div
  18. class='floor-item'
  19. :class='item.seq == currentFloorId?"isActive":""'
  20. @click='tabFloor(item,index)'
  21. v-for='(item,index) in floorsArr'
  22. :key='index'
  23. >{{item.code}}</div>
  24. </div>
  25. </div>
  26. <div class='icon-bottom' v-if='floorsArr.length>showNumber'>
  27. <!-- v-repeat-click='decrease' -->
  28. <img v-show='parseInt(marginTop) !== marginTopMax' v-repeat-click='decrease' src='@/assets/imgs/iconBlackBottom.png' alt />
  29. <img class='disabled' v-show='parseInt(marginTop) === marginTopMax' src='@/assets/imgs/iconLightBottom.png' alt />
  30. </div>
  31. </div>
  32. </div>
  33. </template>
  34. <script>
  35. import store from '../store'
  36. import { mapGetters } from 'vuex'
  37. import RepeatClick from '@/directives/repeat-click'
  38. export default {
  39. directives: {
  40. repeatClick: RepeatClick
  41. },
  42. data() {
  43. return {
  44. floorId: 'F1',
  45. showT: true,
  46. showB: true,
  47. num: 0,
  48. floorMapIdName: '',
  49. floor: {
  50. code: 'F1',
  51. gcode: '1F',
  52. gname: 'f1',
  53. name: '第1层',
  54. seq: 100
  55. },
  56. currentFloorId: null,
  57. marginTop: 0,
  58. marginTopMax: 0,
  59. startTime: '',
  60. endTime: '',
  61. showNumber: 8, //需要展示的楼层数 //TODO:
  62. height: 39, //一个楼层的高度
  63. currIndex: 0, //当前楼层在 楼层数组中的下标,上下箭头使用
  64. conHeight: 0 // floor-out 的高度
  65. }
  66. },
  67. props: {
  68. floorsArr: {
  69. type: Array,
  70. default: () => {
  71. return []
  72. }
  73. },
  74. // 默认true,
  75. // 1. 切换楼层后,是否触发 cookie,vuex数据修改,
  76. // 2. 在fenbuPic组件中为false, 1)不触发cookie,vuex , 2) 选中的楼层ID,为楼层列表数组floorIdArr的第0个
  77. changeDataFlag: {
  78. type: Boolean,
  79. default: true
  80. }
  81. },
  82. computed: {
  83. ...mapGetters(['legendTable'])
  84. },
  85. mounted() {
  86. window.vm = this
  87. this.init()
  88. },
  89. methods: {
  90. /**
  91. * @description 点击上箭头,marginTop<0时执行楼层滚动
  92. */
  93. increase() {
  94. // console.log('increase')
  95. let marginTop = parseInt(this.marginTop)
  96. marginTop < 0 && this.changeFloor(1, this.currIndex)
  97. },
  98. /**
  99. * @description 点击下箭头,marginTop小于最大值marginTopMax时,执行楼层滚动
  100. */
  101. decrease() {
  102. // console.log('decrease')
  103. let marginTop = Math.abs(parseInt(this.marginTop)),
  104. marginTopMax = Math.abs(parseInt(this.marginTopMax))
  105. marginTop < marginTopMax && this.changeFloor(-1, this.currIndex)
  106. },
  107. init() {
  108. // console.log('init')
  109. if (!this.floorsArr.length) {
  110. return false
  111. }
  112. this.floorIdArr = []
  113. this.floorsArr.map(item => {
  114. this.floorIdArr.push(item.seq)
  115. })
  116. this.currentFloorId = Number(this.$cookie.get('currentFloorId') || 100)
  117. // bug fix 修复 fenbuPic 弹窗中,楼层不能选中的问题
  118. // 如果 floorIdArr 不在 floorIdArr数组中,或者changeDataFlag为false(弹窗组件中的楼层组件),使用 floorIdArr[0], 而不使用 cookie
  119. let index = this.floorIdArr.findIndex(item => item === this.currentFloorId)
  120. if (index === -1 || !this.changeDataFlag) {
  121. this.currentFloorId = this.floorIdArr[0]
  122. }
  123. // 修复在设备设施页面中,楼层组件不够 8个楼层时,出现的样式问题,
  124. this.conHeight = this.floorsArr.length * 37.5
  125. this.conHeight = this.conHeight >= 300 ? 300 : this.conHeight
  126. this.showNumber = this.floorsArr.length > 8 ? 8 : this.floorsArr.length
  127. this.marginTopMax = -(this.floorIdArr.length - this.showNumber) * this.height
  128. this.changeFloor(0, index)
  129. },
  130. /**
  131. * @name changeFloor
  132. * @param {Number} flag 1:向上滚动楼层, -1向下滚动 , 0:进入页面初始化时,执行位置处理
  133. * @description 点击图例下方的,上下切换按钮
  134. */
  135. changeFloor(flag, index) {
  136. // console.log('changeFloor')
  137. const len = this.floorIdArr.length
  138. // let index = this.floorIdArr.findIndex(item => item === this.currentFloorId)
  139. this.currIndex = index
  140. // 点击上箭头
  141. if (flag === 1) {
  142. index--
  143. this.currIndex = index
  144. } else if (flag === -1) {
  145. //点击下箭头
  146. index++
  147. this.currIndex = index
  148. }
  149. // FEAT: 点击上下箭头,不触发cookie更改 , 只有初始化时,才进行选中的楼层 状态更新
  150. if (flag === 0) {
  151. this.handleCookie()
  152. }
  153. this.handlePosition(flag, index, len)
  154. },
  155. handleCookie() {
  156. let currentFloor = this.floorsArr.filter(item => item.seq == this.currentFloorId)[0]
  157. if (currentFloor) {
  158. // 如果 changeDataFlag为true(不是在 分布图弹窗组件中的 楼层组件),设置cookie,vuex
  159. if (this.changeDataFlag) {
  160. this.$cookie.set('floorNow', currentFloor.code || '', 3)
  161. this.$cookie.set('floorMapId', currentFloor.gname, 3)
  162. this.$cookie.set('currentFloorId', currentFloor.seq, 3)
  163. this.floorId = this.$cookie.get('floorNow') || currentFloor.code
  164. this.floorMapIdName = this.$cookie.get('floorMapId') || currentFloor.gname
  165. store.commit('SETCURRENTFLOOR', currentFloor)
  166. }
  167. this.$emit('emitFloor', currentFloor)
  168. }
  169. },
  170. /**
  171. * @name tabFloor
  172. * @param {Object} item 选中的楼层信息
  173. * @param {Number} index 楼层信息在floorsArr数组中的位置
  174. */
  175. tabFloor(item, index) {
  176. this.currentFloorId = this.floorIdArr[index]
  177. this.handleCookie()
  178. this.handlePosition(2, index, this.floorIdArr.length)
  179. this.viewLengend()
  180. },
  181. viewLengend() {
  182. if (this.legendTable.length > 0) {
  183. this.$store.commit('SETSHOWVIEW', 1)
  184. } else {
  185. this.$store.commit('SETSHOWVIEW', 0)
  186. }
  187. },
  188. /**
  189. * @description 楼层位置动画处理
  190. * @param flag 1:向上滚动楼层, -1向下滚动 , 0:进入页面初始化时,执行位置处理 2:直接点击楼层
  191. * @param index 楼层 在floorIdArr中的下标
  192. * @param len floorIdArr长度
  193. */
  194. handlePosition(flag, index, len) {
  195. // 取出当前 marginTop
  196. let marginTop = parseInt(this.marginTop)
  197. switch (flag) {
  198. // 初始化进入页面,位置处理
  199. case 0:
  200. // 直接点击楼层,滚动楼层
  201. case 2:
  202. // 将 marginTop 设置为对应的index 应滚动的距离
  203. marginTop = -index * this.height
  204. // marginTop 过大时,取最大值marginTopMax
  205. if (Math.abs(marginTop) >= Math.abs(this.marginTopMax)) {
  206. marginTop = parseInt(this.marginTopMax)
  207. }
  208. // marginTop>0时,取0,防止楼层上边出现空白
  209. marginTop = marginTop >= 0 ? 0 : marginTop
  210. // index为0,marginTop设置为0
  211. index == 0 && (marginTop = 0)
  212. // index为最后一个,设置为最大marginTopMax
  213. index == len - 1 && (marginTop = parseInt(this.marginTopMax))
  214. this.marginTop = marginTop + 'px'
  215. break
  216. // 1:向上滚动楼层
  217. case 1:
  218. this.marginTop = marginTop + this.height + 'px'
  219. break
  220. // -1向下滚动楼层
  221. case -1:
  222. this.marginTop = marginTop + this.height * -1 + 'px'
  223. break
  224. default:
  225. break
  226. }
  227. }
  228. }
  229. }
  230. </script>
  231. <style lang="less" scoped>
  232. .floor-box {
  233. .floor-list {
  234. width: 44px;
  235. // height: 212px;
  236. background: rgba(255, 255, 255, 1);
  237. box-shadow: 0px 2px 15px 0px rgba(31, 36, 41, 0.08);
  238. border-radius: 2px;
  239. position: relative;
  240. padding: 6px 4px;
  241. text-align: center;
  242. .floor-out {
  243. // max-height: 300px; //TODO:
  244. min-height: 38px;
  245. overflow: hidden;
  246. position: relative;
  247. overflow-y: auto;
  248. &::-webkit-scrollbar {
  249. display: none;
  250. }
  251. .floor-center {
  252. transition: all linear 0.5s;
  253. .floor-item {
  254. line-height: 28px;
  255. height: 28px;
  256. cursor: pointer;
  257. position: relative;
  258. &::after {
  259. position: absolute;
  260. left: 50%;
  261. margin-left: -20%;
  262. bottom: -6px;
  263. content: '';
  264. width: 14px;
  265. height: 1px;
  266. background: rgba(195, 199, 203, 1);
  267. border: 0px solid rgba(228, 229, 231, 1);
  268. }
  269. & + .floor-item {
  270. margin-top: 10px;
  271. }
  272. }
  273. }
  274. }
  275. .icon-top {
  276. cursor: pointer;
  277. height: 18px;
  278. img {
  279. width: 18px;
  280. height: 100%;
  281. margin-top: -10px;
  282. }
  283. }
  284. .icon-bottom {
  285. cursor: pointer;
  286. height: 18px;
  287. img {
  288. width: 18px;
  289. height: 100%;
  290. margin-top: -10px;
  291. }
  292. }
  293. .isActive {
  294. border-radius: 4px;
  295. color: #025baa;
  296. background: #e1f2ff;
  297. }
  298. }
  299. .disabled {
  300. cursor: not-allowed !important;
  301. }
  302. }
  303. </style>