• [技术干货] 智慧园区设备通过IoT网关和平台接入园区预集成设备
    园区基线预集成的设备IO包含:基线设备IO、连接实验室认证扩展IO。当对应设备接入园区时无需开发任何代码,可直接接入使用。基线设备IO:随基线版本一起安装,订购园区基线后默认安装好,如表1所示。连接实验室认证扩展IO:IO扩展包随基线版本发布,但默认不安装,项目可根据需要选装,如表2所示。扩展IO详情见连接实验室认证扩展IO。基线设备IO这部分设备IO随基线版本一起安装,订购园区基线后默认安装好。表1 基线设备IO条数分类设备IO“统一设备服务”端对应的设备规格1保安系统设备门禁设备IOAccessControl2泄露电缆设备IOLeakyCable3人行闸机设备IOTurnstile4消防系统设备消防烟感设备IOSmokeDetector5消防温感设备IOTemperatureSensor6消防手报设备IOManualFireAlarmActivation7声光报警设备IOAcoustoOpticAlarm8消防栓按钮设备IOFireHydrantButton9可燃气体探测器设备IOCombustibleGasDetector10能耗系统设备水表设备IOWaterMeter11电表设备IOElectricMeter12燃气表设备IOGasMeter13资产管理设备新基点IoT射频识别标签设备IORFID14新基点IoT射频识别读卡器设备IORFIDReader15环境监测设备户外环境监测设备IOOutdoorEnvSensor16室内环境监测设备IOIndoorEnvSensor17建筑BA设备空调机组设备IOAirHandleUnit18新风机组设备IOPreCoolingAirHandlingUnit19送风机设备IOSupplyAirFan20排风机设备IOExhaustAirFan21冷机设备IOChiller22冷冻水泵设备IOChillerWaterPump23冷却水泵设备IOCoolDownWaterPump24冷却塔设备IOCoolingTower25冷源补水箱设备IOColdSourceSupplyTank26冷源补水泵设备IOColdSourceSupplyPump27冷冻水总管设备IOChilledWaterMainPipe28冷却水总管设备IOCoolDownWaterMainPipe29管道设备IOMainPipe30膨胀水箱设备IOExpansionTank31蓄冷罐设备IOColdStorageTank32电热锅炉设备IOElectricBoiler33锅炉热水泵设备IOBoilerHotWaterPump34供热水泵设备IOHeatingWaterPump35排水泵设备IODrainagePump36生活水泵设备IODomesticWaterPump37集水井设备IOSumpPit38生活水箱设备IODomesticWaterTank39减压阀设备IOPressureReliefValve40室内照明控制器设备室内照明控制器设备IOIndoorLightingController41厕位检测设备厕位检测设备IOToiletPositionDetector42工位检测设备工位检测设备IOWorkStationDetector43升降电梯设备升降电梯设备IOElevator44电梯群控器设备电梯群控器设备IOElevatorClusterController连接实验室认证扩展IO这部分设备IO扩展包随基线版本发布,但默认不安装,项目可根据需要选装。表2 连接实验室认证扩展IO条数分类设备IO“统一设备服务”端对应的设备规格1电气火灾监测系统设备故障电弧探测器设备ArcFaultDetectionDevice2电气火灾检测系统探测器设备ElectrFireMonitorSysDetector3消防电源监控系统设备FirePowerMonitorSys4照明系统路灯设备StreetLight5室外景观照明设备OutdoorLandscapeLighting6室内多回路照明控制器设备IndoorMultLoopLightingController7环境空间监测系统震动传感器设备Vibrating8GPS定位器设备GPSLocator9智能手环设备SmartBand10垃圾桶设备Trashcans11擦手纸余量检测设备TissuePaper12厕纸余量检测设备ToiletPaper13客流统计设备PassengerFlow14多媒体点评器设备Evaluator15洗手液余量检测设备SoapDispenser16井盖检测器设备ManholeCoverDetector17路灯显示屏设备StreetLightDisplayScreen18激光探测器设备LaserDetector19应急指示灯设备EmergencyLamp20水文监测系统水位水质监测设备WaterQualityMonitoring21水文监测设备HydrologicalTelemetery22能耗管理系统能耗管理系统设备EnergyConsumption23智能水表设备SmartWaterMeter24热量表设备HeatMeter25冷量表设备CoolCapacityMeter26火灾自动报警系统报警主机设备AlarmHost27入侵报警系统电子围栏设备ElectronicFence28门磁探测器设备ElecLockDetector29报警主机防区设备AlarmHostDefenceArea30环境空间告警系统管线甲烷气体探测器设备PipelineCH4Detector31管线硫化氢气体探测器设备PipelineH2SDetector32管线温湿度探测器设备PipelineTempAndHumidityDetector33管线压力探测器设备PipelinePressureDetector34管线氧气气体探测器设备PipelineO2Detector35紧急按钮设备EmergencyButton36温湿度监测设备TemperatureHumidity37管道流量监测设备PipelineTrafficMonitoring38液压检测设备HydraulicPressureDetector39水浸检测设备WaterImmersion40液位检测设备LiquidLevelDetector41CH探测器设备CH4Detector42红外探测器设备InfraredDetector43一氧化碳探测器设备CODetector44氨气探测器设备AmmoniaDetector45空气质量探测器设备AirAualityDetector46地埋侧循环泵设备BuriedSideCirculatingPump47定压水泵设备ConstantPressurePump48水处理仪设备WaterTreatmentInstrument49地源热泵机组设备GroundSourceHeatPumpUnit50锅炉补水箱设备BoilerSupplyTank51二次水循环泵设备SecondaryCirculationPump52消防监测系统消防栓监测设备HydrantDetector53消防管道监测设备FireControlPipeDetector54BA400V进线设备InLine400V5510kV进线设备InLine10kV56400V出线设备OutLine400V57电力变压器温控器设备TransformerTempController58交流电通断检测器设备ACDetector59空气断路器设备AirCircuitBreaker60电箱温度传感器设备TempDetector61母联设备BusTieSwitch62电容器设备Capacitance6335kV出线设备Capacitance64主变压器设备MainTransformer6510kV出线设备OutLine10kV66站变设备StationTransformer67110kV分段设备Subsection110kV68直流屏设备DirectCurrentPanel69110kV进线间隔设备IncomingLineInterval110kV70双电源转换开关DualPowerSwitch71TV监控设备TVMonitoringDevice72母线保护设备BusbarProtection73光伏发电设备PhotovoltaicGenerator74柴油发电设备DieselGenerator75电动天窗电动天窗设备PowerSunroof76电梯及扶梯扶梯设备Escalator
  • [技术干货] 智慧园区设备通过IoT网关和平台接入园区集成架构
    图1 设备通过IoT接入南向设备接入的整个业务流程可以分为2部分:数据上报和指令下发,各模块的处理流程如下。数据上报IoT平台能力:南向设备通过IoT网关和IoT平台,将原始数据上报到ROMA MQS的原始topic中。基线预置能力:IoT Adapter IO依据消息类型将消息拆分,并根据设备类型和消息类型转发给对应设备IO的中间层topic。例如人行闸机上报的消息,会转发给“人行闸机设备IO”;门禁上报的消息会转发给“门禁设备IO”。设备IO能力:设备IO将消息转换成标准格式,并发送到“设备标准消息MQS Topic”。基线预置能力:统一设备服务消费标准topic中的消息,转换成事件供业务应用做逻辑判断。指令下发基线预置能力:统一设备服务提供标准化的设备模型和控制命令,无论是对哪种设备下发指令,业务应用都只需调用标准化的指令接口即可。基线预置能力:统一设备服务根据业务侧下发的指令,在设备的标准模型中查询到该设备的指令服务后回调ROMA侧的“设备标准IoT接口”。基线预置能力:ROMA侧的“设备标准IoT接口”依据指令中的“channel”和“deviceType”参数,将指令路由到设备IO。“channel”参数用于多IoT平台的场景,确定指令要下发给哪个IoT平台,例如新基点IoT平台的channel值为“basepoint.connectionmax.iot”。“deviceType”参数确定指令路由到哪个设备IO,deviceType的值来自统一设备服务中定义的标准模型。例如人行闸机的指令会路由到“人行闸机设备IO”,门禁的指令会路由到“门禁设备IO”。设备IO能力:设备IO将业务侧下发的指令转换为实际物理设备可以执行的指令,并回调南向IoT平台的指令下发接口。IoT平台能力:南向IoT平台向实际物理设备下发指令,控制设备的运行。在整个业务流程中,每种类型的设备,都需要有一个对应的设备IO,用于标准化实际设备上报的消息,以及转换业务下发给设备的指令,消息上报和指令下发通过IoT平台来实现。针对园区常见的一部分设备,基线已经预集成了对应的设备IO,无需开发任何代码,可直接接入使用,详细清单参见基线已集成设备。对于不在基线预置内的设备,只需开发对应的设备IO即可,其它部分不需要开发,整个上行/下行流程和业务侧都无需变动,开发流程详见基线未集成设备接入指导。
  • [技术干货] 智慧园区业务侧批量操作接口出入参规范(上)
    批量导出接口业务对象的数据很多场景下需要导出到外部,例如在界面导出成文件,导出到数据平台做分析,或导出到第三方系统使用。因此需要提供REST形式的数据导出接口。导出接口的命名举例:deviceDataExportForBatchURL格式举例:/service/Device/0.1.0/deviceDataExportForBatch导出接口的入参字段:导出接口的本质是按条件查询接口,但和数据视图的查询接口不同,导出接口通常入参与时间段相关,其查询结果应为平铺的字段列表而非嵌套的对象结构。导出接口的入参字段建议包含以下:表1 导出接口的入参字段序号名称类型必选(M)/可选(O)描述1countFlagIntegerM1:返回总数totalNumber。其它:返回title,data。2startIntegerO导出开始数,0开始。countFlag为1时,可不传。countFlag不为1时,必传。3limitIntegerO导出数。countFlag为1时,可不传。countFlag不为1时,必传。4xxxAnyO回调服务自定义参数。入参样例:{ "channel": "string", "countFlag": "string", "defId": "string", "deviceIds": [ "string" ], "deviceName": "string", "exportAllFlag": "string", "externalCode": "string", "gatewayId": "string", "limit": 0, "spaceInPath": "string", "start": 0, "status": "string" }导出接口的出参字段建议为:表2 导出接口的出参字段序号名称类型必选(M)/可选(O)描述1totalNumberIntegerO导出的总数,countFlag为1时返回。2titleString[]O导出文件标题列表,例如:["title1", "title2", "title3"]countFlag不为1时返回。3resultRecord[]O导出的数据列表。一条数据对应一行导出数据,字段名为对应标题,字段值为导出值,例如:[{"title1": "val1"}, {"title2": "val2"}, {"title3": "val3"}]countFlag不为1时返回。出参示例:{ "result": [ {} ], "title": [ "string" ], "totalNumber": 0 }一个应用通常会包含多个业务对象,例如人员BO包含了人员实例、人员群组、通行授权等业务对象。不同的业务对象应提供不同的批量导出接口,不同的业务对象关系也应提供不同的批量导出接口,因为批量导出的结果集为平铺的多字段数据记录集,不适合同时承载有关联关系的多个业务对象。
  • [技术干货] 智慧园区业务权限凭证配置规范
    在创建FUNCTION类型的权限资源时,只能选择已有的业务权限凭证。AppCube平台的业务权限凭证,由开发者在应用开发的“配置> 业务权限凭证”页面创建,删除同样如此,权限BO仅关联已有业务权限凭证。在应用开发的“配置> 业务权限凭证”页面创建凭证,APP/BO编译打包时,可以将凭证以及API关联的凭证数据一起打包出来。配置规范业务权限凭证配置的粒度应符合实际业务使用场景,使实际业务中既能灵活配置权限,又不产生越权的问题。如果一个权限中需要调用多个接口,其权限资源应配置上多个接口对应的业务权限凭证(即创建多个FUNCTION类型的权限资源),然后分别给这些接口配置业务权限凭证。通常一个接口对应一个业务权限凭证。命名规范凭证名称的命名规范如下:模块名称(APP/BO名称)[必选]_特性[必选]_操作[非必选],大驼峰格式。例如:SystemManagement_CommonSystemManagement_Operator_Create凭证分类(目录)原则:以APP/BO为模块进行分类,命名与APP/BO一致。目录必选。定义业务权限凭证时目录名称可直接输入。区分使用者权限如:SystemManagement_Common配给匿名用户;SystemManagement_Operator_Update配给系统管理员区分读写权限如:SystemManagement_Operator_QueryAll只读;SystemManagement_Operator_Create可写区分单个/批量权限如:SystemManagement_Operator_Delete单个删除;SystemManagement_Operator_BatchDelete批量删除区分同一操作结果不同权限如:SystemManagement_Operator_QueryAll查询全部信息;SystemManagement_Operator_QueryBasic查询基本信息区分可操作对象不同权限如:SystemManagement_Operator_QueryBasic查询返回多个结果;SystemManagement_Operator_QueryCurrent查询仅返回当前对象结果
  • [技术干货] 智慧园区系统参数命名规范
    BO系统参数BO中的系统参数,统一命名规则为 :BO名称 + 下划线 + 系统参数名称<BOName>_<SystemParameterName>系统参数名采用首字母大写的驼峰样式。例如:SampleBO_DefaultValue 、AlarmBO_SecurityLevel 、GISBO_MapServerHost创建系统参数的时候,勾选“使用命名空间”这个选项,确保跨租户全局唯一。另外,系统参数名需要能尽可能地表明参数的业务含义,避免与其它参数混淆或者完全看不出业务含义。图1 创建BO系统参数APP系统参数APP中的系统参数,统一命名规则为 :APP名称 + 下划线 + 系统参数名称<APPName>_<SystemParameterName>系统参数名采用首字母大写的驼峰样式。例如:SampleMgmt_MaxValue 、SecurityMgmt_DefaultSecurityLevel 、IOCMgmt_DataSourceType创建系统参数的时候,勾选“使用命名空间”这个选项,确保跨租户全局唯一。另外,系统参数名需要能尽可能地表明参数的业务含义,避免与其它参数混淆或者完全看不出业务含义。管理界面中的系统参数原则上,所有的系统参数都应该放到各BO及APP中。但是如果确实有些系统参数是共性的,也可以在管理界面中创建。管理界面中创建的系统参数,统一命名规则为 :Common + 下划线 + 系统参数名称Common_<SystemParameterName>系统参数名采用首字母大写的驼峰样式。例如:Common_CurrentEnvDomain 、Common_ClientTimezone创建系统参数的时候,勾选“使用命名空间”这个选项,确保跨租户全局唯一。另外,系统参数名需要能尽可能地表明参数的业务含义,避免与其它参数混淆或者完全看不出业务含义。
  • [技术干货] 智慧园区错误码定义规范
    错误码使用原则原则上,系统里面所有的报错或者提示信息,都禁止直接在代码里面硬编码,必须使用错误码的形式。错误码的命名,必须遵循错误码命名规范。错误码要配置在APP或者BO内。错误码命名规范BO名称/APP名称+“.”+错误码名称。错误码名称采用大驼峰的方式,通常采用简练的英文单词,不要使用汉语拼音。状态码不能返回4xx,否则页面会跳转到登录页。错误码的中英文错误信息都要写。错误参数信息不能使用 \ ,应该使用{0}。错误码定义范例全部错误码需要在业务平台上查看。APP错误码名称英文错误信息状态码中文错误信息AlarmBOAlarm.ServiceUnAvailableThe request has failed due to a temporary failure of the server.500服务不可用。Alarm.InvalidOperatorThe input operator is invalid.500非法操作符类型。Alarm.illegalParameterThe input parameter is illegal.500非法参数类型。
  • [问题求助] 【智慧园区】【部署】部署方式
    当前园区的版本可以支持私有云部署吗?客户这边已经搭建了第三方的私有云平台,并且不想使用公有云。平台可以部署到客户的私有云上面吗?
  • [技术干货] 智慧园区AppCube高级页面Widget设计原则、命名和注释规则
    设计原则开发者平台高级页面开发模式下页面是由N个widget构成(N>=1)。widget可以理解为页面中的小组件,组件的拆分根据具体的业务和组件的服用情况进行拆分。如果某个页面不可拆分或者无服用场景,则可以只有一个widget构成。组件存在的最主要的意义是可在不同页面中被复用。理论上拆分越细,可被复用的概率会越大。但是这带来的副作用是页面开发的复杂度上升。所以拆分的力度需要进行综合的考虑。Widget命名Widget命名采用三段式命名:命名空间_业务名称_widget(固定字段),业务名称采用大驼峰命名。函数/方法注释函数/方法注释采用典型的JSDoc的注释方式。函数注释入参说明:@param + 1个空格+ {参数类型} + 1个空格 + 参数名+ 1个空格 + 参数说明。函数注释出参说明:@return + 1个空格 + {参数类型} + 1个空格 + 出参说明(若没有出参,则出参说明可不写)。有关键逻辑或者重大变更时,增加改动者及改动描述。【示例】: /** * 在地图上创建标志 * * @param {String} latLng 经纬度信息 * @param {Object} mapInfo 地图描点信息 * @return {Boolean} 在地图上创建点选标志的结果 * @version 20180310 modify by xxx shangsan 修改地图上描点的样式 * @version 20180314 modify by xxx wangwu 在地图上描点增加事件发送,供外部订阅 */ var placeMarkerAndPanTo=function(latLng, mapInfo) { //返回创建点选标志的结果 return true; }方法内注释方法内使用单行注释,以“//”开头。对代码的注释应放在其上方或右方(对单条语句的注释)相邻位置。【示例】:var placeMarkerAndPanTo=function(latLng, mapInfo) { //返回创建点选标志的结果 return true; }FTL注释在一些主要节点标签结束的后边加上注释。【示例】:<div class="success-operate"> <a href="javascript:;" class="btn-md-red" @click="trackOrder">Track Order</a> <!-- btn-md-red end 跳转到订单详情页查看订单--> <a href="javascript:;" class="btn-md-primary" @click="continueShopping">Continue Shopping</a> <!-- btn-md- primary end 跳转到商城首页继续购物--> </div>在一些循环结束的后边加上注释。【示例】:<li class="li-tab" v-for="(item,index) in g_viewOrderData.tabsParam"> <div class="item-wrap"> <div class="img-wrap"> <img :src="item.url"></img> </div> <div class="wid-tab-text">{{item.value}}</div> </div> </li><!--loop end 遍历订单上的状态页签,获取名称和链接-->样式文件样式文件中图片及字体文件的引用,需使用相对路径。字体文件需要放置在与样式文件同级的目录中,目录名称为font、fonts(两个任选其一即可),可设置子层目录,子层目录命名无要求。目录及图片、文件的命名仅支持如下字符:数字、字母(大小写均可)、下划线、中划线。支持的图片格式包含如下:png、jpg、jpeg、gif、bmp、webp。支持的字体文件格式包含如下:tiff、woff、ttf、otf、eot、svg。多个Widget样式可以抽取为单独库文件,独立库文件可以方便进行整体样式主题的切换。缺点是widget的运行需要对这个库文件产生依赖。如果widget比较独立,也可以将样式文件定义到widget作用域的css中。响应式设计Widget需要支持响应式设计,页面需要在多屏下进行充分测试验证。浏览器兼容性组件开发需要考虑浏览器兼容性,对多浏览进行适配验证。需要支持IE10+,Chrome,Safari,Firefox,移动端需要考虑支持UC、QQ浏览器,Android Chrome,iOS Safari等。桥接器BridgeWidget数据访问需要封装到Bridge中,不允许在widget中直接通过ajax访问业务数据服务。通过Bridge的封装,可以保持widget的稳定性。未来数据源的切换不需要升级widget,只需要切换Bridge即可。对于数据消费类的Bridge,mock目录不允许为空。Mock数据会在编辑状态加载,如果直接调用API可能会因为API的不稳定而引起UI渲染异常。一个查询API一个Bridge,更新API当前可以共用同一个Bridge。前端对象需要在Bridge中进行明确定义,字段清晰。开放性Widget自身是开放的,直接引用业界的优秀的开源组件可以提高开发效率。在开发过程中可以按需引入。例如使用MVVM框架Vue(Vue相比AngularJS更轻量,性能更优)以及使用基于Vue的前端控件库Quasar,Element-UI。不允许引入JQuery。框架已经默认提供,引入后会引起运行冲突异常。非特殊场景组件的尺寸大小不建议固定值,可以指定最大/最小值。非特殊场景不允许直接对DOM元素添加CSS,DOM元素的样式通过显式的class引用,保证样式只作用在当前组件。
  • [技术干货] 智慧园区AppCube高级页面Widget开发编码规范
    组件设计开发前针对组件进行设计,比如组件是否可以多场景复用,是否可拆分组件从而达到可复用效果,组件可提供哪些配置能力无需Addon就可以直接使用。以下是平台针对Widgte设计的一套设计理念,供大家参考:开发者平台高级页面开发模式下页面是由N个widget构成(N>=1)。widget可以理解为页面中的小组件,组件的拆分根据具体的业务和组件的复用情况进行拆分。如果某个页面不可拆分或者无复用场景,则可以只有一个widget构成。组件存在的最主要的意义是可在不同页面中被复用。理论上拆分越细,可被复用的概率会越大。但是这带来的副作用是页面开发的复杂度上升。所以拆分的力度需要进行综合的考虑。响应式设计Widget需要支持响应式设计,页面需要在多屏下进行充分测试验证。合理的接口调用方式:APIConnector使用fetch/ajax方式调用固然可以,但是框架本身无法对这种方式的接口调用状态码401/403进行拦截,从而指引跳转登录页。因此请务必使用:APIConnector。有以下两点好处:统一接入:APIConnector统一调用Custom API,即路径中/service/调用。这就要求在平台中开发的脚本和服务编排,最终都要使用服务去封装对接,同时可以给服务配置相关的业务权限。统一拦截:应用中引入资源库:customConnector,便可对所有APIConnector方式发起的接口调用进行拦截,如上所述,接口401/403作统一跳转。开发性Widget自身是开放的,直接引用业界的优秀的开源组件可以提高开发效率。在开发过程中可以按需引入。例如使用MVVM框架Vue(Vue相比AngularJS更轻量,性能更优)以及使用基于Vue的前端控件库Quasar,Element-UI。不允许引入JQuery。框架已经默认提供,引入后会引起运行冲突异常。非特殊场景组件的尺寸大小不建议固定值,可以指定最大/最小值。非特殊场景不允许直接对DOM元素添加CSS,DOM元素的样式通过显式的class引用,保证样式只作用在当前组件。APIConnector调用方式在组件.editor.js中定义开发态APIConnector配置,代码片段如下:propertiesConfig:[ { headerTitle: "Connector", accordion: true, accordionState: "close", config: [{ "type": "connectorV2", "name": "APIConnector_POST", "label": "APIConnector_POST", "model": "ViewModel", "value": "global_connector_APIConnector" }, { "type": "connectorV2", "name": "APIConnector_GET", "label": "APIConnector_GET", "model": "ViewModel", "value": "global_connector_APIConnector" }, { "type": "connectorV2", "name": "APIConnector_PUT", "label": "APIConnector_PUT", "model": "ViewModel", "value": "global_connector_APIConnector" }, { "type": "connectorV2", "name": "APIConnector_DELETE", "label": "APIConnector_DELETE", "model": "ViewModel", "value": "global_connector_APIConnector" }] }]在组件.js中定义统一调用APIConnector配置,代码片段如下:(可根据各自业务场景自行补充相关代码)。callConn: function (service, param, type, callbackFunc) { var connector = null; switch (type.toUpperCase()) { case 'POST': connector = thisObj.getConnectorInstanceByName('APIConnector_POST'); break; case 'GET': connector = thisObj.getConnectorInstanceByName('APIConnector_GET'); break; case 'PUT': connector = thisObj.getConnectorInstanceByName('APIConnector_PUT'); break; case 'DELETE': connector = thisObj.getConnectorInstanceByName('APIConnector_DELETE'); break; default: connector = thisObj.getConnectorInstanceByName('APIConnector_POST'); break; } if (connector) { connector.setInputParams({ service: service, needSchema: 'data' }); //异步(默认) if (param.async === false) { connector.setInputParams({ service: service, needSchema: 'data', async: false }); //同步 delete param.async; } connector .query(param) .done((response)=> { if (response.resp && response.resp.code) { callbackFunc.call(this, response); } }) .fail(function (response) {}) } }在组件.js中具体调用某一个API,代码片段举例如下:async verifyLogin() { let identityId = ""; let callVerify = async () => { return new Promise(resolve => { this.callConn("/SmartCampus__UnifiedPortal/1.0.0/verifyLogin", {}, "POST", (res) => { if (res.resp.code == '0' && res.data[0].identityId) { identityId = res.data[0].identityId || ''; } resolve(identityId); }); }); }; identityId = await callVerify(); return identityId; }开发态配置APIConnector,四种方式:POST GET PUT DELETE
  • [技术干货] 智慧园区开发CSS和注释规范
    CSS规范BEM命名规范BEM 来自块(block)、元素(element)、修饰符(modifier)的缩写命名,约定模式:block:模块,名字单词间用 - 连接element:元素,模块的子元素,以 __ 与 block 连接modifier:修饰,模块的变体,定义特殊模块,以 -- 与 block 连接.block {} .block__element {} .block--modifier {}注释必要的地方务必要写注释。单行注释单独一行作为注释,//后面加空格代码及注释同行,//前后要加空格// 调用并获取用户基本信息 getUserInfo(); const MAX_COUNT = 3; // 最大统计数量多行注释不影响代码可读性,可考虑添加。主要涉及场景:业务逻辑性强关联代码难以理解/** * 代码注释1 * 代码注释2 */函数注释函数注释有业界统一的规范,复杂函数和类都有必要进行注释。/** * 以星号开头,紧跟一个空格,第一行为函数说明 * @param {类型} 参数 单独类型的参数 * @author 作者 创建时间 修改时间(短日期)改别人代码要留名(注意:不要写工号) * @example 举例(如果需要) */
  • [技术干货] 智慧园区开发前端性能优化
    阻塞式调用改为异步编程非特殊场景(判断登录与否),减少同步执行代码。不要仅仅为了获取接口返回及代码的简单,做成阻塞式的同步调用,弊端显而易见。改成异步调用又会出现代码层层嵌套的回调函数了。解决该问题,可以使用ES6的异步编程对象:Promise。更简洁的做法,使用Promise的语法糖:Async/Await,提升代码的可读性。非当前场景使用,勿提前处理典型场景:人员管理,业务开发追求效率,往往在页面初始化,就用一个接口,将之后所有操作用到的数据全查出来。可优化点:1:分页查询2:初始化前端只需展示名称/头像几个字段,点击查看才会展示详细信息。那么,请划分接口,查询人员列表可能只需查人员基本信息表;查询人员详情,才涉及到具体属性表关联。UI的增删改操作完成,不要盲目的全量查询全量查询能保证数据的一致性,但是站在使用者的角度,如果查询很慢,体验会很差。对象增删改操作完成,即可更新视图层Model。如果删除操作成功但还能查出来,那本身逻辑就有问题了。所以,尽量不要盲目的全量查询。内存泄漏:全局变量及函数声明未声明变量或者使用 this 创建的变量(this 的指向是 window)都会引起内存泄漏。而擅长定义全局变量、全局函数,这类问题较多出现在标准页面开发中。标准页面间的跳转,最终其实只是同一个路径下的Hash发生了变化,例如:/besBaas/baas/abc/foundation/index.html#/SmartCampus__TimeSchemaManagement /besBaas/baas/abc/foundation/index.html#/SmartCampus__AccessDeviceManageV4因此,全局变量、全局函数是被所有页面中所有JS代码所共享的,变量名冲突,函数名冲突,就会造成意想不到的结果。同时,系统进程不再用到的内存,没有及时释放,当内存占用越来越高,轻则影响系统性能,重则导致进程崩溃。防抖(debounce)与节流(throttle)函数防抖和函数节流都是防止某一时间频繁触发,但是两者原理不同。函数防抖是某一段时间内只执行一次,而函数节流是间隔时间执行。应用场景:debouncesearch搜索联想,实时远程搜索的场景,通过接口动态获取数据,用户在不断输入值时,用防抖来节约请求资源,避免带宽和性能浪费。window触发resize的时候,不断的调整浏览器窗口大小会不断的触发这个事件,用防抖来让其只触发一次。/** * 防抖 * @param {Function} fn * @param {Number} delay */ function debounce(fn, delay) { var timer; return function() { console.log('事件触发'); var self = this, argumentsBySelf = arguments; clearTimeout(timer); timer = setTimeout(function() { fn.apply(self, argumentsBySelf); }, delay); } }throttle鼠标不断点击触发,mousedown(单位时间内只触发一次)。获取滚动事件,比如是否滑到底部自动加载更多,用throttle来判断。/** * 节流 * @param {Function} fn * @param {Number} delay */ function throttle(fn, delay) { var last = 0; return function () { var now = Date.now(); if (now - last >= delay) { fn.apply(this, arguments); last = now; } } }
  • [问题求助] 【智慧园区】【权限】在园区创建角色时,在appcube对应的profile里面给了不必要的接口附上了权限,存在隐藏接口(未公开接
    在园区创建角色时,在appcube对应的profile里面给了不必要的接口附上了权限,存在隐藏接口(未公开接口)最下的权限集怎么确认呢? wx1097451 
  • [技术干货] 智慧园区JS编码规范
    箭头函数中的this箭头函数在使用闭包的时候不用纠结 this,不需要通过像 _this 这样的局部变量来临时引用 this 给闭包函数使用。箭头函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。例如:let obj = { func: function () { console.log(this); }, say: function () { setTimeout(() => { console.log(this); }); } }; obj.func(); //obj obj.say(); //obj代码边界判断变量使用前做空判断,增加边界场景验证:不赋值、赋值为null、赋值为空串“”、赋值为空对象{}、空数组[]。例如://错误示范 Uncaught TypeError: Cannot read property 'indexOf' of undefined if(this.value.indexOf('mary') < 0){ //xxx } //正确示范1 if(this.value && this.value.indexOf('mary') < 0){ //xxx } //正确示范2 if(this?.value?.indexOf('mary') < 0){ //xxx }数组/对象深拷贝深浅拷贝根本区别在于是否真正获取了一个对象的复制实体,还是仅仅是一个引用,具体可自行搜索。深拷贝简单粗暴型:序列化反序列化法let obj = {name: 'mary', age:17}; let copyObj = JSON.parse(JSON.stringify(obj))浅拷贝扩展运算符实现数组浅拷贝(只对第一层深拷贝,后面的拷贝引用值)// bad let arr = [1, 2, 3]; const len = arr.length; const copyArr = []; for (let i = 0; i < len; i += 1) { copyArr[i] = arr[i]; } // good const copyArr = [...arr];扩展运算符实现对象浅拷贝const original = { a: 1, b: 2 } const copy = { ...original, c: 3 }赋值运算符 = 实现的是浅拷贝,只拷贝对象的引用值。JavaScript 中数组和对象自带的拷贝方法都是“首层浅拷贝”(concat,slice,扩展运算符)。JSON.stringify 实现的是深拷贝,但是对目标对象有要求(非 undefined,function)。若想真正意义上的深拷贝,请递归。异常表达的分支,少用if-else,使用勿超过3层,增加可读性if (condition) { ... return obj; } // 继续写else业务逻辑代码for循环使用 for 循环过程中,数组的长度,使用一个变量来接收,这样有利于代码执行效率得到提高,而不是每走一次循环,都得重新计算数组长度。// bad for(var i = 0; i < arr.length; i++){ } // good for(var i = 0; len = arr.length; i < len; i++){ }eval()函数禁用此方法接受任意的字符串,并当作js代码来处理,从而带来安全隐患。
  • [技术干货] 智慧园区服务编排中入参、出参的定义,对异常判断、错误码定义要求
    服务编排的入参和出参需要根据设计文档做必填参数校验。出入参数不满足设计文档要求时,需要返回错误提示。出入参数需要定义清楚每个字段(接口文档将根据出入参数定义自动生成)。如果存在结构体,结构体中也应定义清楚每个字段。除了本身是预留的定制扩展的结构体之外,不允许有空结构的结构体。服务编排中暴露给用户由用户输入的参数必须放到服务编排的“入参”当中。服务编排中不能存在用户能够使用但不在“入参”及“出参”的参数。对可能引入错误的每个图元都需要做异常处理判断,并返回具体、清晰的错误码提示。错误码应遵循错误码定义规范。错误码赋值图元可以作为流程结束节点。在服务编排中暴露给最终用户的信息通常是错误码对应的错误信息。在目前的平台错误信息国际化的方案中,服务编排的错误码要保证全局唯一。在平台可以通过界面以错误码为KEY进行不同语言的国际化提示信息的维护。不允许在应用项目的服务编排中编排调用BO的内部服务编排。例如,设备管理应用的服务编排不可编排调用设备BO的服务编排,错误示例如图1所示 。图1 不可编排调用设备BO的服务编排不允许在应用项目的服务编排中编排调用BO的script。例如,设备管理应用的服务编排不可编排调用人员BO的所有script,即不可编排图2中的Peson_queryPerson。图2 不可编排调用人员BO的所有script不允许跨BO调用script和内部服务编排例如,人员BO的服务编排不允许调用空间BO的内部服务编排和Script。
  • [技术干货] 智慧园区服务编排中图元布局、摆放的要求
    为了服务编排画布排版美观以及方便后续的服务编排检视,服务编排的图元编排遵循以下原则:在配置服务编排之前,须明确具体步骤和子流程的分解,合理编排图元。业务逻辑采用自上而下、从左往右的页面布局方式,业务逻辑展示清晰;同一任务多个步骤,横向排列,不同任务之间竖向排列。利用横向和竖向,做到层次缩进。Decision图元里的Default改为表示主流程,类似于If Error Else MainProcess这种结构。把异常处理优先标出。在同一个版面中,图元之间的间隔大小相同。尽量避免连接线相互交叉。创建或查询较复杂的父子对象结构场景(如:创建订单和相关对象),应将父对象和典型子对象的创建和查询编排到子流程中,供多个流程共享。对于服务编排中常用到的业务功能(如获取Offer实例),可以考虑编排到子流程或用Script实现,供多个流程共享。编排每个服务编排时,首先都应该设置入参校验步骤,图元类型为“Decision”,分支优先考虑异常场景。服务编排流程中其他的“Decision”图元也要首先考虑异常场景。避免使用循环套循环。不允许在子流程中结束,所有结束出口应在最外层服务编排中体现。子流程中应始终返回出参。
总条数:953 到第
上滑加载中