index.tsx 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755
  1. import React, { useState, useEffect, useRef, useCallback } from 'react';
  2. import { FormattedMessage, useModel } from 'umi';
  3. import SearchInput from '@/sagacare_components/SearchInput';
  4. import PageHeader from '@/sagacare_components/PageHeader';
  5. import Map from '@/sagacare_components/map';
  6. import TopNavigator from '@/sagacare_components/topNavigator';
  7. import TopNavRight from './components/topNavRight';
  8. import DeviceModal from './components/deviceModal';
  9. import styles from './index.less';
  10. import mapstyles from '@/sagacare_components/map/index.less';
  11. import cx from 'classnames';
  12. import { Spin, Modal, message } from 'antd';
  13. import moment from 'moment';
  14. import { getMaxScale } from '@/hooks/useMap';
  15. import { ExclamationCircleOutlined } from '@ant-design/icons';
  16. import { equipImageMap } from '@/config/sagacare/sagacare_image.js';
  17. import Icon from '@/tenants-ui/SgIcon';
  18. import type { navigatorItem } from '@/pages/Environment/index';
  19. import { projectObj } from '@/config/api.js';
  20. import {
  21. getMapList,
  22. queryEquipStatistics,
  23. queryDeviceTimeManage,
  24. queryProjectEquipType,
  25. } from '@/services/sagacare_service/environment';
  26. import {
  27. changeCurtain,
  28. changeAir,
  29. changeLight,
  30. getLamp,
  31. getAirInfo,
  32. } from '@/pages/Equipment/equipmentControl';
  33. //设备状态
  34. type equipStatus = {
  35. equipType: string;
  36. status: number;
  37. };
  38. //设备开启数量
  39. type statistics = {
  40. equipType: string;
  41. runCount: number;
  42. };
  43. const Environment: React.FC = () => {
  44. const { hasPersonList, querySpaceAdjustList } = useModel('sagacare_spaceFunc');
  45. const { changeLastFloorId } = useModel('sagacare_buildFloor');
  46. const { searchSpace } = useModel('sagacare_searchInfo');
  47. const { getSpaceFunc } = useModel('sagacare_spaceFunc');
  48. const { envir_all, equip_air, equip_lamp, envir_curtain } = equipImageMap;
  49. const [showModal, setShowModal] = useState<boolean>(false);
  50. const [showSpace, setShowSpace] = useState<API.MapInfo>({}); //当前弹框选中的空间
  51. const initNavigatorList = [
  52. {
  53. name: '全部设备',
  54. id: 'all',
  55. src: envir_all,
  56. //color: '#E5574F',
  57. color: '#E89E32',
  58. colorStr: '',
  59. },
  60. {
  61. name: '空调',
  62. id: 'airConditioner',
  63. src: equip_air,
  64. num: '--',
  65. color: '#5E8BCF',
  66. colorStr: '94,139,207,',
  67. },
  68. {
  69. name: '照明',
  70. id: 'light',
  71. src: equip_lamp,
  72. num: '--',
  73. color: '#FFE823',
  74. colorStr: '255,232,35,',
  75. },
  76. {
  77. name: '窗帘',
  78. id: 'curtain',
  79. src: envir_curtain,
  80. num: '--',
  81. color: '#E89E32',
  82. colorStr: '232, 158, 50,',
  83. },
  84. ];
  85. const [navigatorList, setNavigatorList] = useState<any[]>([]);
  86. const [scale, setScale] = useState<number>(0.8);
  87. const [maxScale, setMaxScale] = useState<number>(1);
  88. const [transXInit, setTransXInit] = useState<number>(0);
  89. const [mapList, setMapList] = useState<API.MapInfo[]>([]);
  90. const mapListCopy = useRef<any[]>([]);
  91. const [mapSize, setMapSize] = useState<any>({});
  92. const [equipMapList, setEquipMapList] = useState<any[]>([]);
  93. const [timeMapList, setTimeMapList] = useState<any[]>([]);
  94. const [selNav, setSelNav] = useState<navigatorItem>(initNavigatorList[0]);
  95. const [selFloorId, setSelFloorId] = useState<string>();
  96. const [mapCombineList, setMapCombineList] = useState<any[]>([]);
  97. const [loading, setLoading] = useState<boolean>(false);
  98. const changeFloorId = (data: string) => {
  99. //debugger;
  100. setSelFloorId(data);
  101. };
  102. //导航条切换
  103. const navigatorChange = (item: navigatorItem) => {
  104. setSelNav(item);
  105. };
  106. const showModalClick = (item) => {
  107. // console.log('showChart', item);
  108. setShowModal(true);
  109. setShowSpace(item);
  110. };
  111. //当前设备的状态 all全部开启 part部分开启 close全都关闭 还有类型type 包括airConditioner light curtain
  112. //根据设备状态返回不同的 颜色
  113. const getColorOpacity = (value: any, type?: string): string => {
  114. let colorStr = '';
  115. // console.log('getColorOpacity-selNav', selNav, navigatorList);
  116. if (selNav.id == 'all') {
  117. //全部设备时 colorStr赋值
  118. var filterRes = navigatorList.filter(function (item) {
  119. return item.id == type;
  120. });
  121. colorStr = (filterRes[0] || {}).colorStr;
  122. } else {
  123. colorStr = selNav.colorStr;
  124. }
  125. if (selNav.id == 'curtain' || type == 'curtain') {
  126. //console.log('valuevaluevaluevalue', value);
  127. if (value == 'noHave') {
  128. //没有
  129. return 'rgba(196, 196, 196, 0)';
  130. } else {
  131. return 'rgba(' + colorStr + '1)';
  132. }
  133. } else {
  134. if (value === 2) {
  135. //2 是部分开启
  136. return 'rgba(' + colorStr + '0.4)';
  137. } else if (value === 1) {
  138. //1 是开启
  139. return 'rgba(' + colorStr + '1)';
  140. } else if (value === 0 || value == 'nostatus') {
  141. //0是关闭
  142. return 'rgba(196, 196, 196, 0.6)';
  143. }
  144. }
  145. };
  146. const { confirm } = Modal;
  147. //单个空间的点击事情
  148. const spaceControl = (item, index: number) => {
  149. //全部设备 或者没有房间类型 则不可以点击
  150. if (selNav.id == 'all' || !item.canClick) return;
  151. //没有设备时
  152. if (item[selNav.id] == 'noHave') return;
  153. if (item[selNav.id] == 'nostatus') {
  154. message.success('该空间设备离线');
  155. return;
  156. }
  157. if (item[selNav.id] === 2) {
  158. //半开时
  159. confirm({
  160. title: '请确认',
  161. icon: <ExclamationCircleOutlined />,
  162. content: `是否进入单空间进行调节?`,
  163. okText: '确认',
  164. cancelText: '取消',
  165. onOk() {
  166. showModalClick(item);
  167. },
  168. onCancel() {
  169. //console.log('Cancel');
  170. },
  171. });
  172. return;
  173. }
  174. var status = item[selNav.id] === 1 ? '关闭' : '打开';
  175. confirm({
  176. title: '请确认',
  177. icon: <ExclamationCircleOutlined />,
  178. content: `确认${status}该${selNav.name}吗?`,
  179. okText: '确认',
  180. cancelText: '取消',
  181. onOk() {
  182. //现在加上循环调用 所以把手动去了
  183. function callback() {
  184. //这是在手动改变状态
  185. // var mapCopy = JSON.parse(JSON.stringify(mapCombineList));
  186. // mapCopy[index][selNav.id] = item[selNav.id] === 1 ? 0 : 1;
  187. // setMapCombineList(mapCopy);
  188. }
  189. //如果是空调
  190. if (selNav.id == 'airConditioner') {
  191. changeAir(item, index, callback);
  192. }
  193. if (selNav.id == 'light') {
  194. changeLight('one', [item], callback, status);
  195. }
  196. if (selNav.id == 'curtain') {
  197. changeCurtain('one', [item], callback, status);
  198. }
  199. },
  200. onCancel() {
  201. //console.log('Cancel');
  202. },
  203. });
  204. };
  205. //获取地图 mapList
  206. useEffect(() => {
  207. if (selFloorId) {
  208. changeLastFloorId(selFloorId);
  209. setLoading(true);
  210. getMapList({
  211. //floorId: 'Fl11010802593241ec348ecb4148806b9034c8957454',
  212. floorId: selFloorId,
  213. })
  214. .then((res) => {
  215. setLoading(false);
  216. var data: API.MapInfo[] = (res.data || {}).spaceList || [];
  217. var bodyWidth = document.body.offsetWidth;
  218. var mapWidth = (res.data || {}).width || 800;
  219. if (mapWidth < bodyWidth) {
  220. var mscale = 1;
  221. setTransXInit((bodyWidth - mapWidth) / 2);
  222. } else {
  223. var mscale = Number((bodyWidth / mapWidth).toFixed(4));
  224. setTransXInit(0);
  225. }
  226. var mapSize: any = {
  227. width: mapWidth * mscale,
  228. height: (res.data || {}).height * mscale,
  229. };
  230. setMapSize(mapSize);
  231. //把地图变成 屏幕大小
  232. data.forEach((item, index) => {
  233. item.width = item.width * mscale;
  234. item.height = item.height * mscale;
  235. item.left = item.left * mscale;
  236. item.top = item.top * mscale;
  237. });
  238. var maxScaleTemp = getMaxScale(data);
  239. setMaxScale(maxScaleTemp);
  240. setMapList(data);
  241. mapListCopy.current = data;
  242. //setSelNav(navigatorList[0]); //每当重新请求地图时 让选中导航的默认是第一个
  243. })
  244. .catch(() => {
  245. setLoading(false);
  246. });
  247. } else {
  248. setMapList([]);
  249. }
  250. }, [selFloorId]);
  251. const changeMapList = useCallback(
  252. (mscale, moveWidth, moveHeight) => {
  253. setScale(mscale);
  254. console.log('mscale', mscale);
  255. var mapListTemp = JSON.parse(JSON.stringify(mapListCopy.current));
  256. var mapListTemp2 = mapListTemp.map((item, index) => {
  257. if (index == 0) {
  258. // console.log('mapListTemp', mscale, item.width, item.width * mscale);
  259. }
  260. item.width = item.width * mscale;
  261. item.height = item.height * mscale;
  262. item.left = item.left * mscale - moveWidth;
  263. item.top = item.top * mscale - moveHeight;
  264. return item;
  265. });
  266. setMapList(mapListTemp2);
  267. },
  268. [mapListCopy],
  269. );
  270. const queryDeviceManage = (equiptTypeArr: any) => {
  271. //setLoading(true);
  272. return queryEquipStatistics({
  273. floorId: selFloorId,
  274. projectId: projectObj.projectId,
  275. })
  276. .then((res) => {
  277. // setLoading(false);
  278. //if (!setTimer.current) return;
  279. var statistics = res.data.statistics || [];
  280. //赋值 运行中的设备数量
  281. equiptTypeArr.forEach(function (nItem) {
  282. var fres = statistics.filter((sItem: statistics) => {
  283. return sItem.equipType == nItem.id;
  284. });
  285. nItem.num = (fres[0] || {}).runCount;
  286. });
  287. //console.log('queryDeviceManage333-arr', equiptTypeArr);
  288. setNavigatorList(equiptTypeArr);
  289. //设备空间信息
  290. var spaceList = res.data.spaceList || [];
  291. spaceList.forEach((item: any) => {
  292. var allType = ['airConditioner', 'light', 'curtain'];
  293. allType.forEach((etype) => {
  294. var filterEquip = (item.equipList || []).filter((eItem: any) => {
  295. return eItem.equipType == etype;
  296. });
  297. //有当前设备
  298. if (filterEquip.length > 0) {
  299. item.equipStatusList = item.equipStatusList ? item.equipStatusList : [];
  300. var filterRes = (item.equipStatusList || []).filter((eItem: equipStatus) => {
  301. return eItem.equipType == etype;
  302. });
  303. //不存时 赋值not 如果没有设备状态 则说明没有设备 1 是开启 0是关闭
  304. if (filterRes.length > 0) {
  305. item[etype] = filterRes[0].status;
  306. } else {
  307. item[etype] = 'nostatus';
  308. item.equipStatusList.push({
  309. equipType: etype,
  310. status: 'nostatus',
  311. });
  312. }
  313. } else {
  314. item[etype] = 'noHave';
  315. }
  316. });
  317. });
  318. //console.log('spaceList', spaceList);
  319. //debugger;
  320. setEquipMapList(spaceList);
  321. return 'next';
  322. })
  323. .catch(() => {
  324. //setNavigatorList(equiptTypeArr);
  325. // setLoading(false);
  326. });
  327. };
  328. let setTimer1 = useRef();
  329. let setTimer2 = useRef();
  330. function getDeviceStatus(equiptTypeArr: any) {
  331. queryDeviceManage(equiptTypeArr).then((res) => {
  332. clearTimeout(setTimer1.current);
  333. setTimer1.current = setTimeout(() => {
  334. getDeviceStatus(equiptTypeArr);
  335. }, 8000);
  336. });
  337. }
  338. function getProjectEquipType() {
  339. // 项目拥有的设备
  340. return queryProjectEquipType().then((res) => {
  341. const resData = res.data || [];
  342. let arr: any = [];
  343. initNavigatorList.map((item: any, idx: any) => {
  344. if (idx === 0) {
  345. arr.push(item);
  346. return;
  347. } // 第一个为全部设备,不参与对比
  348. let hasEquip = false; // 没有此设备
  349. resData.map((resItem: any) => {
  350. if (item.id === resItem) {
  351. hasEquip = true;
  352. }
  353. });
  354. if (hasEquip) {
  355. arr.push(item);
  356. }
  357. });
  358. //console.log('setNavigatorList-arr1111', arr);
  359. setNavigatorList(arr);
  360. return arr;
  361. });
  362. }
  363. function getSpaceHasPerson(sfId: any) {
  364. //获取有人无人
  365. querySpaceAdjustList(sfId).then((res) => {
  366. //debugger;
  367. clearTimeout(setTimer2.current);
  368. setTimer2.current = setTimeout(() => {
  369. getSpaceHasPerson(sfId);
  370. }, 8000);
  371. });
  372. }
  373. //获取设备状态 设备种类
  374. useEffect(() => {
  375. (async function () {
  376. var equiptTypeArr = await getProjectEquipType();
  377. //console.log('getProjectEquipType222-equiptTypeArr', equiptTypeArr);
  378. if (selFloorId) {
  379. getDeviceStatus(equiptTypeArr);
  380. getSpaceHasPerson(selFloorId);
  381. }
  382. })();
  383. return () => {
  384. //clearInterval(setTimer.current);
  385. console.log('clearTimeout-clear');
  386. clearTimeout(setTimer1.current);
  387. clearTimeout(setTimer2.current);
  388. };
  389. }, [selFloorId]);
  390. //获取时间列表 spaceTimeList
  391. useEffect(() => {
  392. if (selFloorId) {
  393. //setLoading(true);
  394. queryDeviceTimeManage({
  395. floorId: selFloorId,
  396. //floorId: 'Fl11010802593241ec348ecb4148806b9034c8957454',
  397. date: moment().format('YYYYMMDD'),
  398. })
  399. .then(function (res) {
  400. // setLoading(false);
  401. var resList = res.content || [];
  402. setTimeMapList(resList);
  403. })
  404. .catch(() => {
  405. // setLoading(false);
  406. });
  407. }
  408. }, [selFloorId]);
  409. //合并空间设备数据 和 空间数据
  410. useEffect(() => {
  411. var combineList: any = [];
  412. mapList.map(function (mitem) {
  413. var spaceId = mitem.spaceId;
  414. var filterSpace1 = equipMapList.filter((ele) => {
  415. return ele.id == spaceId;
  416. });
  417. var filterSpace2 = timeMapList.filter((ele) => {
  418. return ele.id == spaceId;
  419. });
  420. var filterSpace3 = hasPersonList.filter((ele) => {
  421. return ele.spaceId == spaceId;
  422. });
  423. var combine = Object.assign({}, filterSpace3[0], filterSpace2[0], mitem, filterSpace1[0]);
  424. combineList.push(combine);
  425. });
  426. setMapCombineList(combineList);
  427. }, [equipMapList, mapList, timeMapList, hasPersonList]);
  428. let firtTime: number = 0;
  429. let lastTime: number = 0;
  430. return (
  431. <div className={styles.sagawrap}>
  432. <PageHeader title={<FormattedMessage id="menu.equipment" />} action={<SearchInput />} />
  433. <TopNavigator
  434. navigatorList={navigatorList}
  435. type={'equipment'}
  436. navigatorChange={navigatorChange}
  437. action={
  438. navigatorList.length > 0 && (
  439. <TopNavRight
  440. selNavObj={selNav}
  441. navigatorList={navigatorList}
  442. mapList={mapCombineList}
  443. ></TopNavRight>
  444. )
  445. }
  446. changeFloorId={changeFloorId}
  447. selParamObj={selNav}
  448. ></TopNavigator>
  449. <div className={styles.maptop}>
  450. {selNav.id !== 'all' && selNav.id !== 'curtain' && (
  451. <div className={styles.left}>
  452. <span>
  453. <Icon
  454. className=""
  455. type="youren"
  456. style={{ color: '#CE9F27', fontWeight: 'bold', fontSize: '9px' }}
  457. ></Icon>
  458. 有人
  459. </span>
  460. <span>
  461. <Icon
  462. className=""
  463. type="wuren"
  464. style={{ color: '#8B949E', fontWeight: 'bold', fontSize: '9px' }}
  465. ></Icon>
  466. 无人
  467. </span>
  468. </div>
  469. )}
  470. {selNav.id !== 'all' && selNav.id !== 'curtain' && (
  471. <div className={styles.right}>
  472. <div className={styles.rightOpen}>
  473. <div>
  474. <span
  475. className={styles.circle}
  476. style={{ backgroundColor: 'rgba(' + selNav.colorStr + '1)' }}
  477. ></span>
  478. <span>开启</span>
  479. </div>
  480. <div>
  481. <span
  482. className={styles.circle}
  483. style={{ backgroundColor: 'rgba(' + selNav.colorStr + '0.4)' }}
  484. ></span>
  485. <span>部分开启</span>
  486. </div>
  487. <div>
  488. <span
  489. className={styles.circle}
  490. style={{ backgroundColor: 'rgba(196, 196, 196, 0.6)' }}
  491. ></span>
  492. <span>关闭</span>
  493. </div>
  494. </div>
  495. </div>
  496. )}
  497. {selNav.id == 'curtain' && (
  498. <div className={styles.right}>
  499. <div>
  500. <span
  501. className={styles.circle}
  502. style={{ backgroundColor: 'rgba(' + selNav.colorStr + '1)' }}
  503. ></span>
  504. <span>有</span>
  505. </div>
  506. <div>
  507. <span className={cx(styles.circle, styles.noCurtain)}></span>
  508. <span>无</span>
  509. </div>
  510. </div>
  511. )}
  512. </div>
  513. <Spin spinning={loading} wrapperClassName={mapstyles.spinnclass}>
  514. {mapCombineList.length > 0 && (
  515. <Map
  516. changeMapList={changeMapList}
  517. mapList={mapCombineList}
  518. mapSize={mapSize}
  519. maxscale={maxScale}
  520. transXInit={transXInit}
  521. type={'equipment'}
  522. selFloorId={selFloorId}
  523. render={(item, index) => {
  524. return (
  525. <div
  526. className={mapstyles.houseWrap}
  527. key={index + item.id}
  528. style={{
  529. left: item.left,
  530. top: item.top,
  531. width: item.width,
  532. height: item.height,
  533. }}
  534. >
  535. <div
  536. style={{
  537. backgroundColor: item.canClick
  538. ? selNav.id == 'all'
  539. ? 'rgba(196, 196, 196, 0.4)'
  540. : getColorOpacity(item[selNav.id])
  541. : '',
  542. }}
  543. className={cx(mapstyles.house, {
  544. [mapstyles.notclick]: !item.canClick || item[selNav.id] == 'noHave',
  545. [mapstyles.searchSel]: item.spaceId && item.spaceId === searchSpace.spaceId,
  546. })}
  547. onClick={(event) => {
  548. event.stopPropagation();
  549. if (lastTime - firtTime < 200) {
  550. spaceControl(item, index);
  551. }
  552. }}
  553. onMouseDown={(event) => {
  554. //event.stopPropagation();
  555. firtTime = new Date().getTime();
  556. }}
  557. onMouseUp={(event) => {
  558. //event.stopPropagation();
  559. lastTime = new Date().getTime();
  560. }}
  561. >
  562. {/* {selNav.id !== 'all' && item[selNav.id] == 'noHave' && (
  563. <div className={mapstyles.noDevice}>
  564. <span className={mapstyles.noText}>无设备</span>
  565. </div>
  566. style={{ display: item.width > 80 && item.height > 50 ? 'flex' : 'none' }}
  567. )} */}
  568. {selNav.id == 'all' && (
  569. <div
  570. className={mapstyles.allDevice}
  571. style={{
  572. transform:
  573. scale == maxScale
  574. ? 'scale(1)'
  575. : item.width < 24 * (item.equipStatusList || []).length ||
  576. item.height < 24
  577. ? 'scale(0.3)'
  578. : 'scale(1)',
  579. }}
  580. >
  581. {/* 所有设备的图标列表 */}
  582. {(item.equipStatusList || []).map((ditem: equipStatus, dindex: number) => {
  583. return (
  584. <div
  585. key={dindex + 'device'}
  586. className={mapstyles.icon}
  587. style={{
  588. backgroundColor: getColorOpacity(ditem.status, ditem.equipType),
  589. }}
  590. >
  591. <Icon
  592. className=""
  593. type={ditem.equipType}
  594. style={{ color: '#fff', fontWeight: 'bold', fontSize: '8px' }}
  595. ></Icon>
  596. </div>
  597. );
  598. })}
  599. </div>
  600. )}
  601. {(selNav.id == 'airConditioner' || selNav.id == 'light') &&
  602. item.runStatus === 1 &&
  603. item.canClick && (
  604. <div
  605. className={mapstyles.hasPerson}
  606. style={{
  607. transform:
  608. scale == maxScale
  609. ? 'scale(1)'
  610. : item.width < 46 || item.height < 25
  611. ? 'scale(0.4)'
  612. : 'scale(1)',
  613. }}
  614. >
  615. <Icon
  616. className=""
  617. type="youren"
  618. style={{ color: '#CE9F27', fontWeight: 'bold', fontSize: '9px' }}
  619. ></Icon>
  620. </div>
  621. )}
  622. {(selNav.id == 'airConditioner' || selNav.id == 'light') &&
  623. item.runStatus === 0 &&
  624. item.canClick && (
  625. <div
  626. className={mapstyles.hasPerson}
  627. style={{
  628. transform:
  629. scale == maxScale
  630. ? 'scale(1)'
  631. : item.width < 46 || item.height < 25
  632. ? 'scale(0.4)'
  633. : 'scale(1)',
  634. }}
  635. >
  636. <Icon
  637. className=""
  638. type="wuren"
  639. style={{ color: '#8B949E', fontWeight: 'bold', fontSize: '9px' }}
  640. ></Icon>
  641. </div>
  642. )}
  643. {item.canClick && item[selNav.id] != 'noHave' && (
  644. <div
  645. className={mapstyles.showModal}
  646. onClick={(event) => {
  647. event.stopPropagation();
  648. if (lastTime - firtTime < 400) {
  649. showModalClick(item);
  650. }
  651. }}
  652. onMouseDown={(event) => {
  653. //event.stopPropagation();
  654. firtTime = new Date().getTime();
  655. }}
  656. onMouseUp={(event) => {
  657. //event.stopPropagation();
  658. lastTime = new Date().getTime();
  659. }}
  660. style={{
  661. transform: `scale(${scale - 0.1 < 1 ? scale - 0.1 : 1})`,
  662. }}
  663. >
  664. <Icon className="" type="hover" style={{ fontSize: '10px' }}></Icon>
  665. </div>
  666. )}
  667. <div className={mapstyles.content}>
  668. <Icon
  669. className=""
  670. type={getSpaceFunc(item.roomFuncType)}
  671. style={{
  672. fontSize: 18,
  673. display: item.width > 28 && item.height > 50 ? 'block' : 'none',
  674. }}
  675. ></Icon>
  676. <div
  677. className={mapstyles.name}
  678. style={{
  679. display:
  680. (item.width > 64 && item.height > 80) ||
  681. item.height > 140 ||
  682. item.width > 120 ||
  683. scale == maxScale
  684. ? 'block'
  685. : 'none',
  686. }}
  687. >
  688. {item.localName}
  689. </div>
  690. {(getSpaceFunc(item.roomFuncType) || item.localName) &&
  691. !(
  692. (getSpaceFunc(item.roomFuncType) &&
  693. item.width > 28 &&
  694. item.height > 50) ||
  695. (item.localName &&
  696. ((item.width > 64 && item.height > 80) ||
  697. item.height > 140 ||
  698. item.width > 120 ||
  699. scale == maxScale))
  700. ) && <div className={mapstyles.pointer}>.</div>}
  701. </div>
  702. </div>
  703. </div>
  704. );
  705. }}
  706. ></Map>
  707. )}
  708. </Spin>
  709. {showModal && (
  710. <DeviceModal
  711. showSpace={showSpace}
  712. onClose={() => {
  713. setShowModal(false);
  714. }}
  715. ></DeviceModal>
  716. )}
  717. </div>
  718. );
  719. };
  720. export default Environment;