-
组件设计开发前针对组件进行设计,比如组件是否可以多场景复用,是否可拆分组件从而达到可复用效果,组件可提供哪些配置能力无需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规范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里面给了不必要的接口附上了权限,存在隐藏接口(未公开接口)最下的权限集怎么确认呢? wx1097451
-
箭头函数中的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”图元也要首先考虑异常场景。避免使用循环套循环。不允许在子流程中结束,所有结束出口应在最外层服务编排中体现。子流程中应始终返回出参。
-
服务编排命名服务编排本身的名称,参照Java定义方法的命名规则:驼峰命名,首字母小写。不要携带下划线。动宾结构。例如:notifyOrderCompletion。(错误样例:OrderCompletionNotification)尽量不用缩写,除非是专有名词。例如:invokeCRM。(错误样例:paymentCbk)应简单明了,表示业务意义,而不是内部实现。例如:createPayment(错误样例:InsertAndUpdatePayData)变量命名在服务编排流程中,除了系统的输入变量和输出变量,在服务编排流程使用的内部变量:输入变量和输出变量:命名遵循接口设计文档的要求。内部变量:元素命名遵循驼峰命名原则。变量为单数时,命名包含对象名称(如Level1Catalog、Level2Catalog);变量为复数时命名包含集合名称(如:Level1CatalogList,或者Level2CatalogArray)。数组型变量的下标命名要符合规范,当使用I、J、K等字母来命名时,需要明确变量含义,勿重复使用。图元命名服务编排的图元的名称,采用动名短语形式,每个单词首字母大写,单词之间有空格。名称一般不要超过五个单词。短语尽可能简明,描述该图元的主要作用。例如:Valid Input、Call Device Service。连接线命名在服务编排的图元中,除了Decision连接线外,其他图元的连接线采用系统的固定命名。Decision连接线名称使用英文,采用单词首字母大写,一般不要超过三个单词,采用动名短语,尽可能简明、准确地描述该条件的判断逻辑。
-
选项列表如果对象的字段允许在多个已定义的值中选择一个,使用选项列表Picklist。选项列表的定义示例如图1所示。在基线包中导入的Picklist,默认为基线资产,不允许在界面上修改和删除。支持在界面上新增、编辑和删除非基线的PickList。图1 选项列表定义示例显示名称:BO的选项列表需要定义显示名称,用于显示在BO配置菜单中,应避免与其他可选配置项以及菜单名重复,建议以“工程名+选项列表”的固定方式拼接而成。使用中文字符,最长不超过32个字符,选项列表定义:名称:最多输入64个字符;必须以字母开头且只能包含字母、数字和下划线;采用大驼峰式命名,例如DeviceStatus。标签:最多输入255个字符;应该输入有意义的英文,采用大驼峰式命名,单词间以单个空格分割,不要含有制表符或者特殊字符。描述:最多输入255个字符;介绍当前PickList的使用场景。选项列表的值定义:PickList取值选项不允许重复;每个取值最多输入64个字符;如果取值是字符类型,采用大驼峰形式命名,不要含有空格或者制表符等占位符,例如Active。系统参数对于业务逻辑中存在可变性的参数(例如对接第三方接口的IP地址),无论是在页面中还是服务编排、Script中,都建议使用系统参数,而不能声明为内部变量。系统参数的定义示例如图2所示。在基线包中导入的Picklist,默认为基线资产,不允许在界面上修改和删除。支持在界面上新增、编辑和删除非基线的PickList。图2 系统参数定义示例显示名称:BO的系统参数需要定义显示名称,用于显示在BO配置菜单中,应避免与其他可选配置项以及菜单名重复,建议以“工程名+系统参数”的固定方式拼接而成。使用中文字符,最长不超过32个字符。系统参数:名称:最多输入64个字符;必须以字母开头且只能包含字母、数字和下划线;采用大驼峰式命名,例如ThirdPartyAddress。值:文本类型的参数,取值最多输入255个字符;对于敏感信息(例如第三方系统用户名、密码),需要加密保存;数字类型参数,取值允许输入数字、负号、小数点。描述:最多输入255个字符,介绍当前参数的用途。App导航菜单App菜单需要按照功能聚集,并按照功能关系形成菜单层级。App的菜单定义示例如图3所示,运行显示效果如图4所示。图3 App导航菜单定义示例图4 App导航菜单运行显示的示例每个App均需要设置默认主页;菜单层级最大支持三级,层次过深会导致菜单栏占用过多页面空间,且不利于菜单名称展示(英文菜单尤其明显)。菜单配置约束:标签:标签应直观体现菜单功能,起到功能导航作用;最多输入60个字符,采用中文菜单时,不超过10个汉字;不能包含空格、制表符以及特殊字符。图标:菜单图标不能重复。描述:最多输入255个字符,介绍当前菜单的具体功能。BO配置导航BO的配置导航菜单需要按照功能聚集,并按照功能关系形成菜单层级。BO的菜单定义示例如图5所示。图5 BO配置导航的定义示例BO配置导航的要求与App菜单一致。运营配置运营配置用于租户配置BO的可变项:显示名称:BO的运营配置定义显示名称,用于在“应用管理 > BO配置”菜单下显示的BO名称。应避免与其他可选配置项以及菜单名重复,建议此名称和工程名保持一致以提高区分度。使用中文字符,不要含有制表符或者特殊字符,最长不超过32个字符。布局:只有把配置项从“可选配置”中拖动到“已选配置”后,才可以在BO配置菜单中展现。选项列表如果对象的字段允许在多个已定义的值中选择一个,使用选项列表Picklist。选项列表的定义示例如图1所示。在基线包中导入的Picklist,默认为基线资产,不允许在界面上修改和删除。支持在界面上新增、编辑和删除非基线的PickList。图1 选项列表定义示例显示名称:BO的选项列表需要定义显示名称,用于显示在BO配置菜单中,应避免与其他可选配置项以及菜单名重复,建议以“工程名+选项列表”的固定方式拼接而成。使用中文字符,最长不超过32个字符,选项列表定义:名称:最多输入64个字符;必须以字母开头且只能包含字母、数字和下划线;采用大驼峰式命名,例如DeviceStatus。标签:最多输入255个字符;应该输入有意义的英文,采用大驼峰式命名,单词间以单个空格分割,不要含有制表符或者特殊字符。描述:最多输入255个字符;介绍当前PickList的使用场景。选项列表的值定义:PickList取值选项不允许重复;每个取值最多输入64个字符;如果取值是字符类型,采用大驼峰形式命名,不要含有空格或者制表符等占位符,例如Active。系统参数对于业务逻辑中存在可变性的参数(例如对接第三方接口的IP地址),无论是在页面中还是服务编排、Script中,都建议使用系统参数,而不能声明为内部变量。系统参数的定义示例如图2所示。在基线包中导入的Picklist,默认为基线资产,不允许在界面上修改和删除。支持在界面上新增、编辑和删除非基线的PickList。图2 系统参数定义示例显示名称:BO的系统参数需要定义显示名称,用于显示在BO配置菜单中,应避免与其他可选配置项以及菜单名重复,建议以“工程名+系统参数”的固定方式拼接而成。使用中文字符,最长不超过32个字符。系统参数:名称:最多输入64个字符;必须以字母开头且只能包含字母、数字和下划线;采用大驼峰式命名,例如ThirdPartyAddress。值:文本类型的参数,取值最多输入255个字符;对于敏感信息(例如第三方系统用户名、密码),需要加密保存;数字类型参数,取值允许输入数字、负号、小数点。描述:最多输入255个字符,介绍当前参数的用途。App导航菜单App菜单需要按照功能聚集,并按照功能关系形成菜单层级。App的菜单定义示例如图3所示,运行显示效果如图4所示。图3 App导航菜单定义示例图4 App导航菜单运行显示的示例每个App均需要设置默认主页;菜单层级最大支持三级,层次过深会导致菜单栏占用过多页面空间,且不利于菜单名称展示(英文菜单尤其明显)。菜单配置约束:标签:标签应直观体现菜单功能,起到功能导航作用;最多输入60个字符,采用中文菜单时,不超过10个汉字;不能包含空格、制表符以及特殊字符。图标:菜单图标不能重复。描述:最多输入255个字符,介绍当前菜单的具体功能。BO配置导航BO的配置导航菜单需要按照功能聚集,并按照功能关系形成菜单层级。BO的菜单定义示例如图5所示。图5 BO配置导航的定义示例BO配置导航的要求与App菜单一致。运营配置运营配置用于租户配置BO的可变项:显示名称:BO的运营配置定义显示名称,用于在“应用管理 > BO配置”菜单下显示的BO名称。应避免与其他可选配置项以及菜单名重复,建议此名称和工程名保持一致以提高区分度。使用中文字符,不要含有制表符或者特殊字符,最长不超过32个字符。布局:只有把配置项从“可选配置”中拖动到“已选配置”后,才可以在BO配置菜单中展现。
-
不允许在应用项目的Script中调用BO的script例如, 设备管理应用的Script不可调用设备BO内的任何Script。不允许跨BO调用script例如,人员BO的Script不允许调用设备BO内的任何Script。
-
输入校验不能依赖客户端校验,必须使用服务端代码对输入数据进行最终校验。对于在客户端已经做了输入校验,在服务器端再次以相同的规则进行校验时,一旦数据不合法,必须使会话失效,并记录告警日志。必须假定所有用户产生的输入都是不可信的,并对它们进行合法性校验和值域校验,一旦数据不合法,应该告知用户输入非法并建议用户纠正输入。如果输入为数字参数则必须进行数字型判断。如果输入只允许包含某些特定的字符或字符的组合,则使用白名单(推荐使用正则表达式)进行输入校验。如果输入为字符串参数则必须进行字符型合法性判断。如果明确输入数据的长度限制,必须校验输入数据的长度。如果输入数据为数值且明确范围,则必须检验数据的范围。禁止通过字符串串联直接使用用户输入构造可执行SQL语句,降低SQL注入攻击的风险。用于重定向的输入参数不能包含回车和换行字符,以防止HTTP响应拆分攻击。说明:注意,“回车”字符有多种表示方式(CR = %0d = \r ),“换行”字符有多种表示方式(LF = %0a= \n)。上传下载必须在服务器端采用白名单方式对上传或下载的文件类型、大小进行严格的限制。禁止以用户提交的数据作为读/写/上传/下载文件的路径或文件名,以防止目录跨越和不安全直接对象引用攻击。禁止将敏感文件(如日志文件、配置文件、数据库文件等)存放在Web内容目录下。Web内容目录指的是:通过Web可以直接浏览、访问的目录,存放在Web内容目录下的文件容易被攻击者直接下载。会话及权限管理对于每一个授权访问的接口内都必须核实用户的会话标识是否合法、用户是否被授权执行这个操作。授权和用户角色数据必须存放在服务器端,不能存放在客户端,鉴权处理也必须在服务器端完成。敏感数据保护敏感数据包括但不限于:口令、密钥、证书、会话标识、License、隐私数据(如短消息的内容)、授权凭据、个人数据(如姓名、住址、电话等)等,在程序文件、配置文件、日志文件、备份文件及数据库中都有可能包含敏感数据。禁止在代码和日志中存储敏感数据。禁止密钥或账号的口令以明文形式存储在数据库或文件中。禁止使用自己开发的加密算法,必须使用公开、安全的标准加密算法。
-
每句话后面加分号,脚本写完右键选择“Format Document”统一格式。string类型赋值统一使用双引号“”,获取字段统一使用单引号’’。相关代码写在一起,不相关逻辑最好以空行隔开。总是使用`{}`把循环体和条件语句括起来。开始的`{`总是在同一行。小括号里开始不要有空白逗号;冒号、分号后要有一个空格。例如:for (var i = 0, n = str.length; i < 10; i++) { } if (x < 10) { }function f(x: number, y: string): void { }每个变量声明语句只声明一个变量例如,使用var x = 1; var y = 2; 而不是var x = 1, y = 2;else要在结束的`}`后另起一行。一个函数仅完成一件功能,即使是简单功能也应该编写单独的方法实现。单个方法的方法体不要太长,建议控制在150行以内,保证代码可读性,也方便维护、测试。
-
本节包含字段、对象、结构体等的定义规则。每个字段的定义,均需要定义type、label、description、required、isCollection。有默认值的非必填。当字段为集合类型时候,需要定义成[]。【示例】:@action.object时,需要在脚本中详细定义清楚Object。不要引用其他脚本的Object。如果是嵌套结构体则从下到上粒度依次变小。【示例】不需要多定义Output对象,可以直接在方法使用定义的对象出参。【不推荐】:但是如果出参对象包含从外部引入的对象,则还是要按该方式定义。【推荐】除非业务有特殊要求,增修改脚本不返回结果码和结果信息。
-
总体原则无用的代码不能以注释形式存在。能用代码说明的尽量不要添加注释,脚本注释尽可能简洁。建议注释统一用英文。出入参不必写注释说明。注释方式在函数方法和结构体的元数据描述上面添加注释。方法内关键业务语句前必须添加注释。方法内的单行注释以“//”开头,应放在相关代码的上方或右方,不可放于下方;若放于上方,注释需与前面的代码间用空行隔开。注释与代码的比例没有量化标准;在删掉所有的代码内容、仅保留代码层级结构和注释,如果通过注释,可以很容易理解方法内都做了哪些事情(类似于伪代码),则认为注释比例合理。
-
本节包含脚本中函数、结构体、参数等的命名要求。所有的名称定义要能体现其作用,避免使用缩写(专有名词除外)。Script采用小驼峰命名,例如createDeviceInstance。结构体(struct)采用大驼峰命名,例如QueryPaymentResult。结构体内的字段采用小驼峰命名,例如customerName 。类、枚举值和接口采用大驼峰命名。函数采用小驼峰命名。属性或变量采用小驼峰命名。变量为单数时,命名包含对象名称,如:level1Catalog、level2Catalog。变量为复数时,命名包含集合名称,如:attributeRelationRuleList。
上滑加载中
推荐直播
-
华为云码道Agent集成与鸿蒙实战2026/08/11 周二 19:00-21:00
王一男-华为云码道产品规划专家;李炎-华为云码道产品专家;彭江敏-华为云鸿蒙端云一体化开发专家
本次直播带你解读华为云码道7月份产品新特性、新功能。更有专家演示码道Agent Space × 钉钉机器集成实战,从0到1打通消息通道;码道鸿蒙端云一体化实战,快速搭建员工签到系统。
回顾中 -
华为云开发者AI素养直播课·第五期2026/09/04 周五 16:00-18:00
林华鼎-华为云AI开发者运营负责人;蒋春阳-华为云AI开发者案例开发专家
本期直播内容: AI工具体验营 · 第5-8课连讲。Agent-Team 多智能体协作完成毕业设计实践
回顾中 -
华为云开发者AI素养ClassRoom·第六期2026/09/08 周二 19:00-20:00
樊渊-2026华为软件挑战赛冠军
高手来了:看软挑高手解析二维排样问题—从工业难题到算法突破
回顾中
热门标签