• [问题求助] APP Security Management中,添加报警界面,详细地址下拉选项数据,怎么在空间BO添加数据?
    【功能模块】 APP Security Management中,添加报警弹框,详细地址下拉选项数据为空,看代码,查询的是空间BO,请问在空间BO中,哪里能添加图1上第2处,即下拉选项的数据?【操作步骤&问题现象】1、2、【截图信息】【日志信息】(可选,上传日志内容或者附件)
  • [技术干货] 智慧园区通用APP资产说明以及如何查询通用APP版本
    APP资产清单园区通用APP资产由以下APP组成:表1 APP资产说明资产名称资产描述统一门户APP提供APP的统一入口,同时提供菜单编辑。针对展示内容,提供组件资产、菜单及信息等的增加、删除、更新及查询接口。系统管理APP提供用户管理,权限管理和大屏管理的能力。针对展示内容,提供操作员密码、操作员及相关权限等的增加、删除、更新及查询接口。APP版本查询订购园区解决方案后,登录智慧园区运营中心,单击右上角登录用户账号下的菜单项目“关于”,即可查看已安装应用的版本号,如图1所示。图1 APP版本查询页面
  • [技术干货] 5分钟了解画app的界面是多么简单【vant】
    #### 主流开发场景 前端开发主流场景,当然多少还是在web app,对于新手的上手和对一个app从0 到 1 了解一个开发到上线有一个很好的认识,当然我们主要的学习目的是实现逻辑业务 而不是画页面,所以库就是一个很好的工具【vant】 #### Vue2 中 vant2 的使用 Vant 是一个轻量、可靠的移动端组件库,于 2017 年开源。 目前 Vant 官方提供了 Vue 2 版本、Vue 3 版本和微信小程序版本,并由社区团队维护 React 版本和支付宝小程序版本。 嗯,有大厂团队维护,嘎嘎用就对了。 **安装** ``` # Vue 2 项目,安装 Vant 2: npm i vant@latest-v2 -S ``` **组件引入** + 全局组件导入 ``` //main.js import Vue from 'vue'; import Vant from 'vant'; import 'vant/lib/index.css'; Vue.use(Vant); ``` 当然这种暴力行为不可取啊..... + 按需引入 ``` npm i babel-plugin-import -D ``` ``` // 在.babelrc 中添加配置 // 注意:webpack 1 无需设置 libraryDirectory { "plugins": [ ["import", { "libraryName": "vant", "libraryDirectory": "es", "style": true }] ] } // 对于使用 babel7 的用户,可以在 babel.config.js 中配置 module.exports = { plugins: [ ['import', { libraryName: 'vant', libraryDirectory: 'es', style: true }, 'vant'] ] }; ``` 这里因为vue2bable配置文件统一放到了`babel.config.js`配置如下: ``` module.exports = { presets: [ '@vue/cli-plugin-babel/preset' ], plugins: [ ["import", { "libraryName": "vant", "libraryDirectory": "es", "style": true }] ] } ``` **使用** 使用其实也是和正常组件也是一致得,引入组件,注册组件,渲染组件,差别在于使用注册 ``` import { Tabbar, TabbarItem, Icon } from "vant"; export default { components: { [Tabbar.name]: Tabbar, [TabbarItem.name]: TabbarItem, [Icon.name]: Icon, }, ``` **渲染组件** ``` <van-tabbar v-model="active" @change="onChange(active)" active-color="#ff4b41" inactive-color="#6d3d3d" > ``` **开发常用组件** + Tab 标签页 + Swipe 轮播 + List 列表 + PullRefresh 下拉刷新 + Popup 弹出层
  • [技术干货] 因不愿开放第三方支付,苹果被罚3.1635亿人民币【转载】
    2022年3月23日,苹果在荷兰被处以500万欧元(550万美元)的罚款,据统计,这已经是苹果第九次收到相同数额的罚款通知了。此次的原因是苹果未能按照欧洲国家竞争监管机构的要求,允许荷兰约会App使用第三方支付服务进行交易。如果苹果公司继续驳回消费者与市场管理局(ACM)的要求,它将因无视荷兰的竞争监管机构而受到第十次罚款,此前该类罚款最高为5000万欧元(5500万美元),或根据苹果2021年财务业绩,罚款其约五小时的利润。所以这意味着,如果苹果依然未按照要求进行调整,这将是最后一次罚款。目前苹果暂未回应,但此事很可能会回到荷兰的法院审理。反垄断风口上的苹果荷兰反垄断机构一直持续调查苹果,这并非是一时兴起。苹果早就因涉嫌滥用市场引起了约会软件开发商的投诉。此次重点调查App Store中应用内购支付系统的垄断嫌疑。调查结果显示,在App Store中的所有约会App都不能使用应用内购支付渠道的第三方支付。2021年8月的ACM确定,苹果滥用其主导地位,对荷兰App Store中的约会应用程序制造商施加不合理的限制。并且希望苹果公司能进行以下调整:苹果必须调整其访问荷兰App Store的条件,以便约会App提供商使用。在App Store中,约会App提供商还必须能够使用苹果支付系统以外的支付系统。约会app提供商必须能够引用应用程序外部的支付系统。2022年1月15日,ACM在对苹果进行调查后,发现苹果未能满足其为约会App提供商指定的支付系统的要求。最重要的是,苹果未进行调整,因此该约会App提供商仍然无法使用其他支付系统。此外,苹果还为约会App提供商使用第三方支付系统设置了一些障碍。例如,苹果迫使应用程序提供商做出选择:要么引用应用程序外部的支付系统,要么引用替代支付系统。这也和ACM的要求不相符。ACM通知苹果公司,如果不能按照规定做出调整,就需要定期支付罚款,即每周支付500万欧元,最高可达5000万欧元。2022年3月21日,NOS(荷兰广播基金会)的记者Nando Kasteleijn报道说,这已经是第九次ACM对苹果进行罚款,以符合该机构每周对iPhone业务罚款500万欧元的承诺。500万欧元<苹果两小时收入苹果公司在2021年的收入是3783亿美元,所以这500万欧元,对于它来说还不到两个小时的收入。苹果公司在1月中旬表示,它将遵守ACM关于允许约会应用程序使用替代支付系统的裁决,但该公司的条款只包括将其对此类购买的佣金从标准的30%降至27%,要求开发者维护独立的应用程序二进制文件,并要求开发者每月向苹果提交通过替代方式的销售记录,以便跟踪佣金。ACM对苹果处理方式感到不满意,继续每周进行罚款。据报道,在二月下旬,苹果公司致函ACM,称该公司已遵守ACM规定,但ACM表示不接受。“我理解,目前我们存在意见分歧,最终可能必须由法院解决。”苹果首席合规官凯尔·安德(Kyle Andeer)在签署的信中说。在Kasteleijn发布的ACM公报中,竞争监管机构表示,苹果公司已经提出了一项新提案,以遵守其要求。该消息称,ACM打算评估苹果的提议,并与受影响的各方进行谈判。持续的反垄断斗争自2020年以来,当Epic Games在美国和其他国家挑战苹果要求应用内支付通过苹果支付系统进行时,各方都在努力削弱iPhone业务对iOS生态系统的控制。2020年11月,苹果做出了重大让步,将年收入高达100万美元的公司应用内购买佣金减半至15%。但大公司被迫遵循苹果的App Store规则,并放弃30%的应用内销售,希望获得更优惠的条件。迄今为止,苹果仍在与这些法律和监管挑战作斗争,但在日本、韩国和荷兰已经失利。2021年8月,韩国通过了一项法律,禁止苹果和谷歌要求应用程序开发人员使用各自的内部支付系统。同年9月,日本公平贸易委员会(Fair Trade Commission)迫使苹果允许阅读器应用程序(显示以前从iOS外部购买的内容的应用程序)包含指向外部账户设置功能的应用程序内链接。ACM在荷兰的决定仅适用于荷兰App Store中的约会应用程序,但据推测,苹果担心该裁决可能适用于更广泛的应用程序,并可能传播到其他国家。开放第三方支付关于为什么苹果不愿意开放第三方购买渠道,苹果公司的解释是,如果允许荷兰App Store上约会软件的开发人员使用其他支付处理选项,将危及用户体验,并对用户隐私和数据安全产生新的威胁。但这是否是真正的或者主要的原因呢?据21世纪经济报道,工信部信息通信经济专家委员会委员、中南财经政法大学数字经济研究院执行院长盘和林在解析这一问题时表示,“苹果忌讳第三方支付是从自身抽佣收入考虑。”苹果通过App Store来抽成,对应用内购和购买应用都会有抽成。而应用无法绕过App Store的抽成。如果存在第三方支付渠道,应用有可能绕过苹果抽佣。盘和林教授分析苹果目前存在的主要垄断争议时称:“一个是苹果垄断应用下载渠道,用户买了苹果手机却没有应用使用的选择权;另一个是苹果利用终端垄断来对苹果应用商城的开发者进行抽佣,开发者没有话语权,而在抽佣比重上,也缺乏竞争对手,实现了市场支配。”原文链接:https://blog.csdn.net/csdnnews/article/details/123689384
  • [技术干货] 智慧园区21.2线下FusionCube环境安装后检查步骤
    Cube形态下安装后调测前,需要先检查BO、IO、DO资产和APP应用的安装情况。安装结果检查对于Cube环境,需要在园区应用租户下检查APP、IO、BO、DO资产的安装。检查APP和BO。登录AppCube平台。登录用户名为安装阶段自定义的租户名或者注册时申请的租户名。请联系安装人员获取。选择“管理>应用管理>软件包管理>软件包安装”,可以看到已经订购/安装的园区BO和APP,则说明订购成功。表1 安装后的BOBO描述Alarm告警BOAIServiceAI服务BOAuditLog日志BOBarcode条码服务BOBatchFile批量处理BOCommonBO依赖的公共能力Device设备BOGISGIS BOIdentity身份BOOrganization组织BOPermission权限BOPerson人员BOSpace空间BOTemplate模板BOVideoAnalysis视频分析BOVideoProxy视频代理BOWorkorder工单BO表2 安装后的APP场景APP名称APP说明公共Facility Management设施管理Space Management空间及组织管理System Management系统管理Unified Portal统一门户智慧安防OperationAnalysis运营态势SecurityDashboard安防态势SecurityWorkbenchBase安防作业中心基础应用SecurityWorkbenchExtend安防作业中心扩展应用MobileSecurityWorkbench安防作业Welink应用PersonAccess人员通行MobileAccess通行二维码Welink应用Person Management人员管理设施管理Device Operations设备运维BAconfigApplication组态应用FacilityWorkbench工作台WorkorderManagement工单管理AlarmManagement告警管理Operation Client技术支持DatatoolApp数据加工RuleEngine规则引擎能效管理EnergyEfficiency智慧能效单击“项目”,再单击“业务大屏”,如果可以查看到大屏应用,则说明订购成功。表3 安装后的大屏应用大屏应用名称大屏应用说明SecurityDashboard_IOC安防态势PortalOperationAnalysis_IOC运营态势Portal检查IO。登录对应的ROMA环境。Cube中的ROMA平台访问URL一般为:https://roma-docker.huawei.com,用户名:sctest1001。实际地址和租户账号都是在Cube安装阶段自定义的,请从安装人员处获取。选择左上角的应用名,单击“应用中心”,进入应用中心管理界面,如图1所示。下图中sctest1001为IO前缀示例,会根据实际项目变化。图1 应用中心检查已安装IO的应用列表。相关IO清单列表请参考《集成资产说明》。如果可以查看到应用详情,则说明IO订购成功。图2 应用详情检查DO。不支持在“数据加工”中对作业和任务进行定制修改,包括新增、修改、删除作业。登录智慧园区运营中心。单击“数据加工”,选择“数据调测>作业调测”,进入作业调测页面。检查已安装DO。如果看到作业开发中显示相关的作业列表,则说明DO安装成功。图3 作业开发检查Flink作业。在数据加工页面,选择“实时调测 > Flink作业”,查看已安装的Flink作业,确认Flink作业的状态都是“运行中”。图4 Cube实时作业检查FDI任务。登录对应的ROMA环境,查看对应模块下的FDI资产。图5 检查FDI任务检查数据服务。在ROMA环境中,查看各模块下是否存在API。图6 检查数据服务API
  • [技术干货] 使用Cloud DB构建APP 快速入门-Server篇
    JavaCloud DB提供多种云数据库数据管理方式,您可以在AppGallery Connect控制台管理数据,也可以在服务器上直接管理云侧数据库中的数据。您只需要在服务器端的服务中集成云数据库服务的Server SDK,即可调用它提供的接口,完成相关服务功能开发。Server SDK将会为您的服务器与云数据库的通讯和通讯安全提供保障。使用Server SDK管理数据,需要完成以下准备工作:您已经在AppGallery Connect控制台上开通云数据库,并成功创建对象类型。您已经获取到示例代码,请从示例代码获取。配置开发环境添加认证凭据,详细请参见项目级凭据。添加Server SDK至应用级build.gradle文件。在<项目名>/app/build.gradle文件中dependencies部分添加Server SDK。dependencies { // 添加Cloud DB SDK implementation 'com.huawei.agconnect.server:agconnect-database-server-sdk:1.0.3.300' }在应用级build.gradle文件中设置Java源码兼容模式为JDK1.8版本。compileOptions { sourceCompatibility = 1.8 targetCompatibility = 1.8 }添加对象类型文件您在进行本地应用开发时,可直接将AppGallery Connect控制台上导出的java格式文件添加至本地开发环境,无需再次创建对象类型。导出用于Server端的服务开发的java格式对象类型文件,请参见导出对象类型。将导出的全部java格式文件添加至本地开发环境,如已存在,请覆盖原文件。文件位置:<database>/src/main/java/com/huawei/agc/clouddb/quickstart/model。初始化在添加对象类型文件后,您就可以开始开发Server端的服务。在开发Server端的服务前,您需要先初始化对应数据处理位置的AGCClient,并创建Cloud DB zone实例和CloudDBZoneConfig对象,设置需要进行数据操作的云侧存储区名称。将配置开发环境中获取的认证凭据放置到您自定义的目录,并通过ClientNameEnum指定对应数据处理位置,调用getClientName方法获取初始化后的AGCClient实例。String credentialPath = "agc-apiclient.json"; AGCClient.initialize(ClientNameEnum.CLOUDDB_CN.getClientName(), AGCParameter.builder() .setCredential(CredentialParser.t**dential(credentialPath)) .build(), Constants.Region.REGION_CN);AGCClient初始化参数ClientNameEnumConstants.RegionCLOUDDB_CNREGION_CNCLOUDDB_RUREGION_RUCLOUDDB_SGREGION_SGCLOUDDB_DEREGION_DE通过getInstance(AGCClient agcClient)方法获取对应数据处理位置的AGConnectCloudDB实例。AGCClient agcClient = AGCClient.getInstance(CLOUDDB_CN.getClientName()); agConnectCloudDB = AGConnectCloudDB.getInstance(agcClient);创建CloudDBZoneConfig配置对象,并设置云侧Cloud DB zone名称,打开Cloud DB zone实例,详细请参考CloudDBZoneConfig。CloudDBZoneConfig cloudDBZoneConfig = new CloudDBZoneConfig("QuickStartDemo"); mCloudDBZone = agConnectCloudDB.openCloudDBZone(cloudDBZoneConfig);写入数据在本节主要介绍如何在Server端的服务中进行数据写入操作,以便您了解如何使用Server SDK实现数据的写入。使用executeUpsert()方法实现数据的写入。BookInfo为已定义对象类型,可参见新增和导出对象类型。public void upsertBookInfo(BookInfo bookInfo) { if (mCloudDBZone == null) { LOGGER.warn("CloudDBClient is null, try re-initialize it"); return; } try { CompletableFuture<Integer> result = mCloudDBZone.executeUpsert(bookInfo); System.out.println(result.get()); } catch (AGConnectCloudDBException | ExecutionException | InterruptedException e) { LOGGER.warn("upsertBookInfo: " + e.getMessage()); } }查看数据通过executeQuery()和get()方法的组合实现异步方式查询数据。public void queryBooks(CloudDBZoneQuery<BookInfo> query) { if (mCloudDBZone == null) { LOGGER.warn("CloudDBClient is null, try re-initialize it"); return; } try { CompletableFuture<CloudDBZoneSnapshot<BookInfo>> result = mCloudDBZone.executeQuery(query); CloudDBZoneSnapshot<BookInfo> snapshot = result.get(); processQueryResult(snapshot); } catch (AGConnectCloudDBException | InterruptedException | ExecutionException e) { LOGGER.warn("queryBooks: " + e.getMessage()); } }通过查询与orderByDesc()方法和limit()方法组合来实现数据的降序排序,并限制查询数据显示条数。private void queryWithOrder() { CloudDBZoneQuery<BookInfo> query = CloudDBZoneQuery.where(BookInfo.class); try { query.orderByDesc("price"); query.limit(10); CompletableFuture<CloudDBZoneSnapshot<BookInfo>> result = mCloudDBZone.executeQuery(query); processQueryResult(result.get()); } catch (AGConnectCloudDBException | InterruptedException | ExecutionException e) { LOGGER.warn("queryWithOrder: " + e.getMessage()); } }JavaScriptCloud DB提供多种云数据库数据管理方式,您可以在AppGallery Connect控制台管理数据,也可以在服务器上直接管理云侧数据库中的数据。您只需要在服务器端的服务中集成云数据库服务的Server SDK,即可调用它提供的接口,完成相关服务功能开发。Server SDK将会为您的服务器与云数据库的通讯和通讯安全提供保障。使用Server SDK管理数据,需要完成以下准备工作:您已经在AppGallery Connect控制台上开通云数据库,并成功创建对象类型。您已经获取到示例代码,请从示例代码获取。配置开发环境添加认证凭据,详细请参见项目级凭据。执行以下命令,安装Server SDK到您的项目中,并将依赖添加到您项目中的package.json文件中。npm install --save @agconnect/database-server在您项目中导入AGC模块。const clouddb = require('@agconnect/database-server/dist/index.js'); const agconnect = require('@agconnect/common-server');添加对象类型文件您在进行本地应用开发时,可直接将AppGallery Connect控制台上导出的js格式文件添加至本地开发环境,无需再次创建对象类型。导出用于Server端的服务开发的js格式对象类型文件,请参见导出对象类型。将导出的全部js格式文件添加至本地开发环境,如已存在,请覆盖原文件。文件位置:<database>/src/model。初始化在添加对象类型文件后,您就可以开始开发Server端的服务。在开发Server端的服务前,您需要先初始化AGCClient,并设置需要进行数据操作的云侧存储区名称,获取存储区实例。将配置开发环境中获取的认证凭据放置到您自定义的目录,并初始化AGCClient实例。const credentialPath = "resource\\agc-apiclient-xxxx.json"; agconnect.AGCClient.initialize(agconnect.CredentialParser.t**dential(credentialPath)); const agcClient = agconnect.AGCClient.getInstance();通过getInstance()方法初始化AGConnectCloudDB实例。clouddb.AGConnectCloudDB.initialize(agcClient);创建CloudDBZoneConfig配置对象,并设置云侧Cloud DB zone名称,打开Cloud DB zone实例,详细请参考CloudDBZoneConfig。const zoneName = 'QuickStartDemo'; const cloudDBZoneConfig = new clouddb.CloudDBZoneConfig(zoneName); const mCloudDBZone = clouddb.AGConnectCloudDB.getInstance().openCloudDBZone(cloudDBZoneConfig);写入数据在本节主要介绍如何在Server端的服务中进行数据写入操作,以便您了解如何使用Server SDK实现数据的写入。使用executeUpsert()方法实现数据的写入。BookInfo为已定义对象类型,可参见新增和导出对象类型。async upsertBookInfos(bookInfo) { if (!this.mCloudDBZone) { console.log("CloudDBClient is null, try re-initialize it"); return; } try { const resp = await this.mCloudDBZone.executeUpsert(bookInfo); } catch (error) { console.warn('upsertBookInfo=>', error) } }查看数据通过executeQuery()查询数据。async queryBooks(cloudDBZoneQuery) { if (!this.mCloudDBZone) { console.log("CloudDBClient is null, try re-initialize it"); return; } try { const resp = await this.mCloudDBZone.executeQuery(cloudDBZoneQuery); this.processQueryResult(resp.getSnapshotObjects()); } catch (error) { console.warn('queryBooks=>', error) } }通过查询与orderByDesc()方法和limit()方法组合来实现数据的降序排序,并限制查询数据显示条数。async queryBooksWithOrder() { if (!this.mCloudDBZone) { console.log("CloudDBClient is null, try re-initialize it"); return; } try { const cloudDBZoneQuery = clouddb.CloudDBZoneQuery.where(BookInfo).orderByDesc("price").limit(3); const resp = await this.mCloudDBZone.executeQuery(cloudDBZoneQuery); this.processQueryResult(resp.getSnapshotObjects()); } catch (error) { console.warn('queryBooks=>', error) } }
  • [问题求助] 【ABC】【Facility Management设施管理APP】新建工单里的工单等级映射值怎么修改
    【功能模块】您好,现在基线上有三种工单,安防和能效的工单等级是高中低,这个设施工单里是一级二级三级,想修改成高中低统一一下,查看到了页面的转换代码,但不清楚要怎么修改,试过改配置里的选项列表,但没有生效,请问要怎么处理?【操作步骤&问题现象】1、2、【截图信息】【日志信息】(可选,上传日志内容或者附件)
  • [技术干货] 使用Cloud DB构建APP 快速入门-快游戏篇
    快游戏的数据将会储存在云侧,本地不会缓存数据。在进行数据管理操作时,您将会直接操作云侧数据。快游戏SDK将会为您的应用与云数据库的通讯和通讯安全提供保障。使用Cloud DB构建快游戏,需要完成以下准备工作:您已经在开发者联盟官网注册帐号并通过实名认证,详细请参见帐号注册认证。完成开发环境的搭建,包括在PC上安装cocos creator、在调试快游戏的安卓手机上安装快游戏加载器,详细参见安装开发工具。在AppGallery Connect控制台上完成快游戏的创建,详细参见创建快游戏。生成指纹证书,详细参见“生成指纹证书”。您已经获取到示例代码,请从示例代码获取。启用服务使用Cloud DB服务前,您需要先启用服务。登录AppGallery Connect网站,选择“我的项目”。在项目列表页面中选择项目,单击项目下需要启用云数据库服务的应用。在导航树上选择“构建 > 云数据库”。单击“立即开通”,开通云数据库服务。                   (可选)如您还未选择数据处理位置,需要您先设置数据处理位置,具体操作请参见设置数据处理位置。服务初始化成功后,即启用云数据库服务成功。新增和导出对象类型您需要基于AppGallery Connect控制台创建对象类型,请您遵循操作步骤创建示例中涉及的对象类型,并导出用于快游戏开发的json格式和js格式对象类型文件。不允许修改导出的json格式和js格式文件,否则会导致数据同步功能异常。登录AppGallery Connect网站,选择“我的项目”。在项目列表页面中选择项目,单击项目下需要创建对象类型的应用。在导航树上选择“构建 > 云数据库”。单击“新增”,进入创建对象类型页面。            输入对象类型名为“BookInfo”后,单击“下一步”。单击,新增如下字段后,单击“下一步”。表1 字段定义表字段名称类型主键非空加密默认值idInteger√√––bookNameString––––authorString––––priceDouble––––publisherString––––publishTimeDate––––shadowFlagBoolean–––true单击,设置索引名为“bookName”,索引字段为“bookName”后,单击“下一步”。按照如下要求设置各角色权限后,单击“下一步”。表2 权限配置表角色queryupsertdelete所有人√––认证用户√√√数据创建者√√√管理员√√√单击“确定”。创建完成后返回对象类型列表中,可以查看已创建的对象类型。单击“导出”。                                                  导出“json格式”和“js格式”文件,导出的文件在后续步骤用于添加至本地开发环境。导出json格式文件选择“json格式”。单击“导出”。导出js格式文件选择“js格式”。选择js文件类型,选择“quickGame”。单击“导出”。 新增存储区您可基于AppGallery Connect控制台在云侧创建数据存储区,请您遵循操作步骤创建一个存储区名称为“QuickStartDemo”的存储区。登录AppGallery Connect网站,选择“我的项目”。在项目列表页面中选择项目,单击项目下需要创建存储区的应用。在导航树上选择“构建 > 云数据库”。选择“存储区”页签。单击“新增”,进入创建存储区页面。               输入存储区名称为“QuickStartDemo”。单击“确定”。创建完成后返回存储区列表中,可以查看已创建的存储区。配置开发环境打开cocos creator,其目录示例如下。                                                                                配置应用信息。登录AppGallery Connect网站,选择“我的项目”。在项目列表页面中选择项目,单击项目下的应用。选择“常规”页签,下载配置文件“agconnect-services.json”,并拷贝到您的快游戏项目assets/Script目录下,建议单独创建目录存放。在function文件中添加agconnect-services.json文件引用。import * as context from './agconnect-services.json';集成快游戏SDK。下载快云数据库服务的快游戏SDK,并将SDK js脚本导入至项目中的assets/Script目录下,建议单独创建目录存放。并将所有SDK js脚本设置“导入为插件”,具体步骤为:资源管理器中单击选中js脚本。选中属性检查器中的"导入为插件"。单击属性检查器右上角的“应用”按钮。                                                                      添加对象类型文件在开发应用时,可直接将AppGallery Connect控制台上导出的json格式和js格式文件添加至本地开发环境,并通过AGConnectCloudDB类中的createObjectType()方法实现对象类型的定义和创建。您在进行本地应用开发时,无需再次创建对象类型。将已在AppGallery Connect控制台上导出的全部json格式和js格式文件添加至本地开发环境。初始化Cloud DB,通过AGConnectCloudDB类中的createObjectType()方法实现对象类型的定义和创建,详细请参见初始化。初始化在添加对象类型文件后,您就可以使用云数据库进行应用开发。您开发应用时,需要先执行初始化操作,初始化AGConnectCloudDB、创建Cloud DB zone和对象类型。通过initialize()方法初始化AGConnectCloudDB。agconnect.cloudDB.AGConnectCloudDB.initialize(context);通过getInstance()方法获取AGConnectCloudDB实例,并使用createObjectType()创建对象类型。const schema = require('./BookInfo.json'); const agcCloudDB = agconnect.cloudDB.AGConnectCloudDB.getInstance(); agcCloudDB.createObjectType(schema);打开Cloud DB zone。const config = new agconnect.cloudDB.CloudDBZoneConfig('QuickStartDemo'); const cloudDBZone = await agcCloudDB.openCloudDBZone(config);写入数据在本节主要介绍如何在应用程序中进行数据写入操作,如下所示,使用executeUpsert()实现数据的写入。async function executeUpsert (book) { try { const cloudDBZoneResult = await cloudDBZone.executeUpsert(book); console.log('upsert' + cloudDBZoneResult + 'record' ); } catch (e) { conso.log(e); } }查看数据数据查询和排序通过executeQuery()实现异步方式查询数据。async function executeQuery() { try { const query = agconnect.cloudDB.CloudDBZoneQuery.where(BookInfo); const snapshot = await cloudDBZone.executeQuery(query); const resultArray = snapshot.getSnapshotObjects(); console.log(resultArray); } catch(e) { console.log(e); } }通过查询与limit()方法组合,实现限制查询数据显示条数的功能;与orderByAsc()方法或者orderByAsc()方法组合来实现数据的排序功能。async function executeQueryWithOrder (object) { const query = agconnect.cloudDB.CloudDBZoneQuery.where(BookInfo); if (object.name.length > 0) { query.equalTo('bookName', object.name); } if (parseFloat(object.minPrice) > 0) { query.greaterThanOrEqualTo('price', parseFloat(object.minPrice)); } if (parseFloat(object.maxPrice) > 0 && parseFloat(object.maxPrice) > parseFloat(object.minPrice)) { query.lessThanOrEqualTo('price', parseFloat(object.maxPrice)); } if (parseInt(object.bookCount) > 0) { query.limit(parseInt(object.bookCount)); } query.orderByAsc('id'); try { const snapshot = await cloudDBZone.executeQuery(query); console.log(snapshot.getSnapshotObjects()); return snapshot.getSnapshotObjects(); } catch (e) { console.log(e); } }本篇内容就介绍到这里了,感谢阅读。
  • [技术干货] 智慧园区二次开发发布基线移动APP(下)
    发布到生产环境发布到客户的WeLink环境,并在客户的AppCube生产环境安装移动APP。在AppCube安装移动APP。获取移动APP的zip安装包。登录客户的AppCube生产环境,在“管理 > 应用管理 > 软件包管理 > 软件包安装”下安装移动APP。选择“管理>用户管理>公司配置>公司信息”查看并保存租户ID,例如:0000000000XWnAab0LzN创建WeLink访问AppCube的鉴权信息,获取客户端ID和客户端密钥。创建子账号。因为沃土数字平台的要求,必须先完成租户实名认证,才能新增子账号。访问沃土数字平台官网。使用客户AppCube租户账号登录。鼠标放在界面右上角的租户名称上,单击“个人中心”。选择“我的账号>子账号管理”,进入子账号管理界面。单击“新增”。填写账号名、密码、邮箱、手机号。单击“提交”。账号名建议配置为租户名_welink,例如“SmartCampus_welink”。修改子账号的Profile。使用客户AppCube租户账号登录AppCube生产环境。选择“管理>用户管理>用户”。在用户列表中可以看到上一步创建的子账号。该子账号的默认Profile是“Developer Profile”。单击用户名,打开用户编辑界面,将其Profile修改为“Anonymous_User_Profile”。选择“管理>系统管理>OAuth”,单击“新建”。设置“名称”和“用户”,单击“保存”。名称:根据需要设置。授权类型:选择“客户端模式”。用户:选择上一步的子账号,例如“SmartCampus_welink”。单击操作列的查看密钥按钮,将密钥文件下载到本地。密钥可以只创建一次,下次发布时可以使用已创建好的,不需要重复新建。密钥文件中包含如下参数:username:SmartCampus_welinkclient_id:b6b7a7784xxxxxxxx17fa1a9732b743dclient_secret:d4d72bc4ce171xxxxxxxxxx6753ce64119084083ff32bc80使用客户的WeLink管理员账号/普通账号,登录PC端的HUAWEI CLOUD WeLink开放平台,在“企业内部应用 > We码”下创建We码应用。APP的名称为商用后在手机端显示的应用名称,例如“移动安防中心”。移动安防中心的应用图标为安防中心Logo.zip。发布移动APP到客户的WeLink后台。登录开发者的AppCube开发环境,进入移动APP的开发态,单击左下角的发布图标,选择“WeLink(蓝标WeLink)”。在弹出的WeLink登录界面,输入客户的WeLink管理员账号/普通账号登录。必须确保是发布到客户的WeLink环境。如果之前登录过别的WeLink账号,这里会自动进入发布页面,需要退出之前登录的WeLink账号,或者清除缓存后再重新发布。进入发布页面,配置发布参数。表3 参数说明参数描述应用ID选择在WeLink上创建的应用,即3中创建的APP,例如“移动安防中心”。版本号根据需要设置。主页选择一个页面作为移动APP的在手机端显示的默认页面,例如:“移动安防中心”选择“SmartCampus_workorder”。说明:每个移动APP的默认首页,由开发者指定,例如:移动安防中心的主页是“workorder”。便捷通行的主页是“personpass”。环境类型选择“生产环境”。生产环境域名客户的AppCube生产环境域名,用于移动APP运行态时关联生产环境的后端服务。生产环境客户端ID在客户的AppCube生产环境下创建的OAuth认证密钥,即2中创建的WeLink环境的鉴权信息。例如:b6b7a7784xxxxxxxx17fa1a9732b743d、d4d72bc4ce171xxxxxxxxxx6753ce64119084083ff32bc80。生产环境客户端密钥开启调试根据需要设置。关闭:选择“关闭”时,发布后移动端的APP打开的时候没有“vConsole”按钮,vConsole用于开发者调试。开启:选择“开启”时,则能看到vConsole。单击“发布”后,单击提示框的“确定”跳转到WeLink的“版本管理”界面。单击开发版中的“发布版本”,在弹出的“发布版本”界面填写本次更新内容,单击“确定”。管理员审核通过后,We码小程序在开发后台即显示为线上版。配置WeLink隐私声明。使用客户的WeLink管理员账号登录HUAWEI CLOUD WeLink控制管理台。选择“安全策略>隐私设置”,单击“编辑”配置隐私参数:组织隐私声明:开启声明链接名称:配置为“华为智慧园区隐私声明”。声明链接地址:配置为“https://app.xxx.com/magno/render/SmartCampus__SystemManagement_0000000000Vocvxxxx/PrivacyStatementMobile”,红色部分内容需修改,其中:“app.xxx.com”为客户的AppCube生产环境域名,例如https://app.besclouds.com“0000000000Vocvxxxx”请修改为企客户的AppCube租户ID,获取方法请参见1。隐私责任人:配置为“华为智慧园区”。
  • [技术干货] 智慧园区二次开发发布基线移动APP(下)
    发布到生产环境发布到客户的WeLink环境,并在客户的AppCube生产环境安装移动APP。在AppCube安装移动APP。获取移动APP的zip安装包。登录客户的AppCube生产环境,在“管理 > 应用管理 > 软件包管理 > 软件包安装”下安装移动APP。选择“管理>用户管理>公司配置>公司信息”查看并保存租户ID,例如:0000000000XWnAab0LzN创建WeLink访问AppCube的鉴权信息,获取客户端ID和客户端密钥。创建子账号。因为沃土数字平台的要求,必须先完成租户实名认证,才能新增子账号。访问沃土数字平台官网。使用客户AppCube租户账号登录。鼠标放在界面右上角的租户名称上,单击“个人中心”。选择“我的账号>子账号管理”,进入子账号管理界面。单击“新增”。填写账号名、密码、邮箱、手机号。单击“提交”。账号名建议配置为租户名_welink,例如“SmartCampus_welink”。修改子账号的Profile。使用客户AppCube租户账号登录AppCube生产环境。选择“管理>用户管理>用户”。在用户列表中可以看到上一步创建的子账号。该子账号的默认Profile是“Developer Profile”。单击用户名,打开用户编辑界面,将其Profile修改为“Anonymous_User_Profile”。选择“管理>系统管理>OAuth”,单击“新建”。设置“名称”和“用户”,单击“保存”。名称:根据需要设置。授权类型:选择“客户端模式”。用户:选择上一步的子账号,例如“SmartCampus_welink”。单击操作列的查看密钥按钮,将密钥文件下载到本地。密钥可以只创建一次,下次发布时可以使用已创建好的,不需要重复新建。密钥文件中包含如下参数:username:SmartCampus_welinkclient_id:b6b7a7784xxxxxxxx17fa1a9732b743dclient_secret:d4d72bc4ce171xxxxxxxxxx6753ce64119084083ff32bc80使用客户的WeLink管理员账号/普通账号,登录PC端的HUAWEI CLOUD WeLink开放平台,在“企业内部应用 > We码”下创建We码应用。APP的名称为商用后在手机端显示的应用名称,例如“移动安防中心”。移动安防中心的应用图标为安防中心Logo.zip。发布移动APP到客户的WeLink后台。登录开发者的AppCube开发环境,进入移动APP的开发态,单击左下角的发布图标,选择“WeLink(蓝标WeLink)”。在弹出的WeLink登录界面,输入客户的WeLink管理员账号/普通账号登录。必须确保是发布到客户的WeLink环境。如果之前登录过别的WeLink账号,这里会自动进入发布页面,需要退出之前登录的WeLink账号,或者清除缓存后再重新发布。进入发布页面,配置发布参数。表3 参数说明参数描述应用ID选择在WeLink上创建的应用,即3中创建的APP,例如“移动安防中心”。版本号根据需要设置。主页选择一个页面作为移动APP的在手机端显示的默认页面,例如:“移动安防中心”选择“SmartCampus_workorder”。说明:每个移动APP的默认首页,由开发者指定,例如:移动安防中心的主页是“workorder”。便捷通行的主页是“personpass”。环境类型选择“生产环境”。生产环境域名客户的AppCube生产环境域名,用于移动APP运行态时关联生产环境的后端服务。生产环境客户端ID在客户的AppCube生产环境下创建的OAuth认证密钥,即2中创建的WeLink环境的鉴权信息。例如:b6b7a7784xxxxxxxx17fa1a9732b743d、d4d72bc4ce171xxxxxxxxxx6753ce64119084083ff32bc80。生产环境客户端密钥开启调试根据需要设置。关闭:选择“关闭”时,发布后移动端的APP打开的时候没有“vConsole”按钮,vConsole用于开发者调试。开启:选择“开启”时,则能看到vConsole。单击“发布”后,单击提示框的“确定”跳转到WeLink的“版本管理”界面。单击开发版中的“发布版本”,在弹出的“发布版本”界面填写本次更新内容,单击“确定”。管理员审核通过后,We码小程序在开发后台即显示为线上版。配置WeLink隐私声明。使用客户的WeLink管理员账号登录HUAWEI CLOUD WeLink控制管理台。选择“安全策略>隐私设置”,单击“编辑”配置隐私参数:组织隐私声明:开启声明链接名称:配置为“华为智慧园区隐私声明”。声明链接地址:配置为“https://app.xxx.com/magno/render/SmartCampus__SystemManagement_0000000000Vocvxxxx/PrivacyStatementMobile”,红色部分内容需修改,其中:“app.xxx.com”为客户的AppCube生产环境域名,例如https://app.besclouds.com“0000000000Vocvxxxx”请修改为企客户的AppCube租户ID,获取方法请参见1。隐私责任人:配置为“华为智慧园区”。
  • [技术干货] 智慧园区二次开发发布基线移动APP(上)
    园区基线包中已经包含了移动安防中心、便捷通行等WeLink APP,如果项目没有特殊需求,可以直接将它们发布到生产环境使用。这里以移动安防中心APP为例,介绍基线移动APP发布到手机端WeLink的流程。表1 移动APP发布流程发布阶段说明准备数据开发阶段发布到WeLink自测完成移动APP的开发后,发布到开发者的WeLink账号做自验证。WeLink普通账号,可以用作移动APP的发布。WeLink管理员账号,既可以用作移动APP的发布,还拥有登录WeLink后台审核移动APP权限。如果WeLink管理员开启了“免审核”,则只需要WeLink普通账号即可发布移动APP。开发者的WeLink管理员账号/普通账号移动APP在AppCube开发平台的项目名,例如:MobileSecurityWorkbenchMobileAccess发布到生产环境发布到客户的WeLink环境,并在客户的AppCube生产环境安装移动APP。客户的AppCube平台的生产环境账号移动APP的安装包客户的WeLink管理员账号/普通账号注意事项移动APP发布前,必须确保AppCube开发环境中已安装如下2个库中的任意一个:WeLinkRuntimeFramework(租户级)、MobileAppRuntimeFramework(全局级)。您可以在AppCube平台“管理>应用管理>页面资产管理>库”中检索是否包含,如果2个都未检索到,请向管理员获取WeLinkRuntimeFramework(租户级库)。目前仅支持发布到公有云的WeLink环境。iOS系统不支持iVAS的Welink版本,所以人员位置采集、导航功能只能在安卓系统使用。iOS11及以上版本才支持移动安防中心。iOS系统,上传视频时,对于iphone7及其以上型号的手机,需要在“设置 > 相机 > 格式”中选择“兼容性最佳”模式。在使用移动安防中心前需要为Welink开启手机信息获取权限。对于华为手机,选择“设置 > 应用 > 权限管理”,找到WeLink,设置电话权限为允许。对于小米手机,在桌面长按Welink应用图标,选择“应用信息”,在打开的页面中选择“权限管理”菜单。将“获取手机信息”设置为“始终允许”。iPhone手机无需设置。手机需要允许位置获取及wifi权限,并打开wifi及位置获取开关。可以不需要有效wifi源。开启手机的蓝牙功能,辅助人员定位。开发阶段发布到WeLink自测完成移动APP的开发后,发布到开发者的WeLink账号做自验证。在WeLink上创建应用。以开发者的WeLink管理员账号/普通账号,登录HUAWEI CLOUD WeLink开放平台。选择“企业内部应用 > We码”,单击“创建We码”,设置应用的中/英文名称、上传应用的图标后,单击“确定”。应用名称自定义,例如“移动安防中心开发”,该名称会作为客户手机端WeLink内看到的We码名称。移动安防中心的应用图标为安防中心Logo.zip。发布应用。登录AppCube开发环境,找到需要发布的移动应用,进入移动应用的开发态。园区基线版本预置了以下移动APP:MobileSecurityWorkbenchMobileAccess检查“编译设置”,确认选择“资产包”、“类型”选择“APP”,确认后选择“编译”。图1 确认编译设置单击左下角的发布图标,选择“WeLink-We码”,进入移动APP的发布页面。如果弹出WeLink登录界面,输入开发者的WeLink管理员账号或者WeLink普通账号。填写发布信息,单击“发布”。单击“发布”后如果提示“无法获取WeLink依赖库”,请向管理员获取WeLinkRuntimeFramework库,并上传到AppCube平台的库。表2 参数说明参数描述应用ID选择在WeLink上创建的应用,即1中创建的“移动安防中心开发”。版本号根据需要设置。主页选择一个页面作为移动APP的在手机端显示的默认页面,例如:“移动安防中心”选择“SmartCampus_workorder”。说明:每个移动APP的默认首页,由开发者指定,例如:移动安防中心的主页是“workorder”。便捷通行的主页是“personpass”。环境类型这里选择“开发环境”。开启调试根据需要设置。关闭:选择“关闭”时,发布后移动端的APP打开的时候没有“vConsole”按钮,vConsole用于开发者调试。开启:选择“开启”时,则能看到vConsole。发布成功后,单击提示框的“确定”跳转到WeLink的“版本与发布”界面。如果确定后,弹出WeLink登录界面,输入开发者的WeLink管理员账号或者WeLink普通账号。在WeLink的“版本与发布”界面,单击“发布版本”,填写本次更新内容,单击“确定”。如果WeLink开启了自动审核功能,可以在审核版中看到已审核通过的WeLink应用。如果没有开启自动审核功能,需要使用WeLink管理员账号登录管理控制台,审核应用。管理员审核通过后,We码小程序在开发后台即显示为线上版。
  • [技术干货] 智慧园区二次开发场景分析
    本节列举合作伙伴常见的开发场景和开发方法。针对具体的项目,合作伙伴需要在智慧园区基线版本的基础上,新增或者修改已有能力。常见的场景举例如表1所示。表1 场景开发场景分析开发场景涉及的平台开发方法章节接入一种新设备(基线预置规格以外的设备),如何实现对它的集成,包括消息集成和接口集成。ROMA集成平台通过开发IO适配包实现。按照IoT标准接口,以开发基线闸机设备IO适配包为例,描述IO的功能、IO开发的规划设计、IO开发步骤、IO安装步骤等。ROMA平台开发IO接入一种新设备(基线预置规格以外的设备),实现多厂家共享统一标准的物信模型。设备标准库ROMA集成平台通过基线的设备标准库实现。基线的设备标准库是一个云上的规格管理平台,可用于合作伙伴将云上的设备规格同步到租户环境,也支持将租户自定义的设备规格、对应的IO适配包上传到云端,实现多租户、多厂家共享物模型。管理设备规格新增一项统计数据,例如实时在园的车辆统计。数据平台ROMA集成平台基线提供专业的DO开发工具DataToolKit,用于DO开发、同步、归档、打包。新增/修改DWI、DW层模型,开发DO,生成新的统计数据。使用DataToolKit开发DO在大屏页面展示上某个统计数据。AppCube业务平台在DO已开发完成的基础上,使用基线预置的组件组装大屏页面,在页面中调用DO接口展示数据。开发大屏应用新增一个园区业务应用,例如新增智慧消防。或者基于园区基线参考应用做定制适配。AppCube业务平台可以全新开发一个APP,或者基于基线应用创建一个Addon应用做功能增强。如果基线应用是以源码包方式安装的,合作伙伴还可以直接修改基线应用。开发元数据应用开发一个Welink移动APP。AppCube业务平台移动APP的开发方法,与开发PC端应用的方法一样,可以参照开发元数据应用。定制移动APP的发布方法,可以参照基线移动APP的发布流程。发布基线移动APP开发移动应用使用第三方账号登录IOC,例如使用WeLink账号登录IOC。第三方系统AppCube业务平台基线支持对第三方账号授权登录智慧园区运营中心。配置完成后,可以在IOC登录页使用第三方登录方式登录。授权第三方账号登录IOC将合作伙伴已有业务应用封装为AppCube业务平台的Native Service。IAM SSOAppCube业务平台第三方系统以原生服务的方式部署到AppCube平台后,可以将页面内嵌到园区Portal,实现单点登录;也可以将接口集成到AppCube平台,供其它APP调用。原生服务集成基于IAM SSO集成第三方系统将合作伙伴自研AI算法集成到华为智慧园区AI框架中。华为云市场IEFAppCube业务平台伙伴按照华为园区集成开发规范完成AI算法的代码整改并制作镜像;然后发布到华为云市场;最后在实际项目交付实施中,通过IEF将边缘市场的算法镜像下发到边缘节点服务器。AI集成开发
  • [技术干货] Android——一个神奇的计算器APP[转载]
    中缀运算        中缀运算定义了两个栈,数字栈和符号栈;分别存储用户输入的数字(例如:1,2,3)和输入的符号(例如:+,-);        下列视频以1+2+3/2*3%3为例;首先输入1,然后输入+,通过对运算符点击事件监听,将其分别纳入数字栈和符号栈,然后在输入2和+,即对+进行监听,并取出符号栈栈顶元素,判断其是否为初始化元素,若为否,则将数字栈栈顶元素取出,并获取拼接字符作为另外一个运算数字;(数字栈栈顶元素 &(代表符号栈栈顶元素)拼接字符串)(1+2);得到结果3之后将其压入数字栈中,并将第二个+号压入符号栈,用于下次运算;以此类推…效果视频运算自定义圆形TextView效果图建立attr文件通过对控件手势动作进行监听,改变按钮的样式;即按下为白色,松开为橙色<resources>    <declare-styleable name="SetCircle">        <attr name="CircleColor" format="color"/>        <attr name="SelectCircle" format="color"/>    </declare-styleable></resources>绘制圆形    protected void onDraw(Canvas canvas) {    //判断手势动作,改变控件状态        if (isSelect){            CirclePaint.setColor( SelectCircle );        }else {            CirclePaint.setColor( CircleColor );        }        //设置填充方式        CirclePaint.setStyle( Paint.Style.FILL );        //设置抗锯齿        CirclePaint.setAntiAlias( true );        RectF rectF = new RectF();        //设置半径,比较长宽,取最大值        int radius = getMeasuredWidth() > getMeasuredHeight() ? getMeasuredWidth() : getMeasuredHeight();        rectF.set(getPaddingLeft(),getPaddingTop(),radius-getPaddingRight(),radius-getPaddingBottom());        //绘制圆弧        canvas.drawArc(rectF,0,360,false,CirclePaint);        super.onDraw(canvas);    }字符拼接通过StringBuilder将用户输入的数字进行拼接,段尾对复位按钮进行判断,将数字栈和符号栈以及拼接字符串的内容全部清空;private class NumOnClick implements View.OnClickListener{        @Override        public void onClick(View view) {            switch (view.getId()){                case R.id.Zero:                    numBuilder.append('0');                    break;                case R.id.One:                    numBuilder.append('1');                    break;                case R.id.Two:                    numBuilder.append('2');                    break;                case R.id.Three:                    numBuilder.append('3');                    break;                case R.id.Four:                    numBuilder.append('4');                    break;                case R.id.Five:                    numBuilder.append('5');                    break;                case R.id.Six:                    numBuilder.append('6');                    break;                case R.id.Seven:                    numBuilder.append('7');                    break;                case R.id.Eight:                    numBuilder.append('8');                    break;                case R.id.Nine:                    numBuilder.append('9');                    break;                case R.id.Point:                    numBuilder.append('.');                    break;                case R.id.Reset:                    isReset = true;            }            if (isReset){                PopStack();                numBuilder.delete(0,numBuilder.length());                ResultBox.setText("0");                operatorStack.push('#');                isReset = false;            }else {                ResultBox.setText(numBuilder.toString());            }        }    }清空栈内元素清空数字栈和符号栈内元素  private void PopStack(){        while (numStack.isEmpty()){            numStack.pop();        }        while (operatorStack.isEmpty()){            operatorStack.pop();        }    }运算执行手势监听此处以加运算符为例,对按下和松开两个事情进行监听,分别改变控件样式,并传入相应运算符进行运算   private class OperatorOnClick implements View.OnTouchListener{        @Override        public boolean onTouch(View view, MotionEvent motionEvent) {            boolean isPress = false;            if (motionEvent.getAction() == MotionEvent.ACTION_DOWN){                isPress = true;            }            switch (view.getId()){                case R.id.Add:                    if (isPress){                        mAdd.IsSelect(true);                        mAdd.setTextColor(getResources().getColor(R.color.normal));                        StartOperation(ADD);                    }else {                        mAdd.IsSelect(false);                        mAdd.setTextColor(getResources().getColor(R.color.select));                    }                    break;入栈&&出栈在初始化时,将符号栈压入‘#’符号,即代表第一次执行,不进行结果运算operatorStack.push('#');1    第一次运行时,即将符号栈栈顶元素取出,即‘#’,假如输入1和+,此时无法构成算式,因为确实另外一个运算数,即直接将其压入栈中,不进行结果运算;然后将拼接字符串清空,因为假如输入完了100和+,因为+号是不显示在用户界面的,如果不进行清空,之后输入的字符会追加在其之后,例如在输入50,即不清空为10050,会造成用户体验不良以及使用麻烦等缺点;  假如输入了100和+,然后输入50和-,构成100+50-算式,第一次不进行运算,如上释所示,第二次输入的-,即取出符号栈顶元素+,和运算数100和50,并将其传入EXEOperation()方法,开始运算结果   private void StartOperation(char symbol){        char operator = operatorStack.pop();        if (operator == EQUAL){            operatorStack.push(symbol);        } else if (operator == '#'){            numStack.push(numBuilder.toString().isEmpty()?0:Double.parseDouble(numBuilder.toString()));            operatorStack.push(symbol);            numBuilder.delete(0,numBuilder.length());        }else {            switch (operator){                case ADD:                    EXEOperation(numStack.pop(),numBuilder.toString().isEmpty()?0:Double.parseDouble(numBuilder.toString()),ADD);                    break;                case SUB:                    EXEOperation(numStack.pop(),numBuilder.toString().isEmpty()?0:Double.parseDouble(numBuilder.toString()),SUB);                    break;                case MULTIPLY:                    EXEOperation(numStack.pop(),numBuilder.toString().isEmpty()?0:Double.parseDouble(numBuilder.toString()),MULTIPLY);                    break;                case DIVISION:                    EXEOperation(numStack.pop(),numBuilder.toString().isEmpty()?0:Double.parseDouble(numBuilder.toString()),DIVISION);                    break;                case MOD:                    EXEOperation(numStack.pop(),numBuilder.toString().isEmpty()?0:Double.parseDouble(numBuilder.toString()),MOD);                    break;                case EQUAL:                    EXEOperation(numStack.pop(),numBuilder.toString().isEmpty()?0:Double.parseDouble(numBuilder.toString()));                    break;            }        }    }运算结果  三个参数分别为第一个运算数,和另外一个运算数,以及符号栈栈顶元素,对符号进行判断,并进行结果运算,然后将结果压入栈中以及第二个运算符压人符合栈;  重点在于对等于键进行判断:    1:例如输入算式1+1-,对第二个运算符进行监听即可得到前一结果,然后在输入数字,符号,得到前一结果…    2:例如输入算式1+1=,此时并没有对等于符号进行监听,无法完成运算,解决办法为不将等于压入符号栈,直接结果入栈,相当于需要执行第一步才能完成运算小数位判断对结果字符串进行子串截取,判断小数点之后是否存在小数位,因为为double类型,默认会存在小数位。例如:(1)1.0,则省略小数点后的0,直接输出0;(2)1.05,则不进行小数位省略,直接输出 //判断小数位之后是否有数字        if (str.substring(str.indexOf('.') + 1, str.length() - 1).isEmpty()) {            str = str.substring(0, str.indexOf('.'));        }运算代码    private void EXEOperation(double front,double rear,char operator) {        double result = 0;        String str;        /**         * 对连续点击运算符,而运算数字并未符合标准时进行判断         * 例如:12+         * 此时12和+分别进栈,此时若再点击运算符+,则无法进行运算,因为rear运算数为空*/        switch (operator) {            case ADD:                result = front + rear;                break;            case SUB:                result = front - rear;                break;            case MULTIPLY:                result = front * rear;                break;            case DIVISION:                result = front / rear;                break;            case MOD:                result = front < rear ? front :front % rear;                break;        }        numStack.push(result);        if (isReturn){            operatorStack.push(EQUAL);        }else {            operatorStack.push(operator);            isReturn = false;        }        str = String.valueOf(result);        //判断小数位之后是否有数字        if (str.substring(str.indexOf('.') + 1, str.length() - 1).isEmpty()) {            str = str.substring(0, str.indexOf('.'));        }        ResultBox.setText(str);        //前运算符清空,为后运算符输入做准备        numBuilder.delete(0,numBuilder.length());    }任意进制转换通过输入十进制数,分别转化为相应的二进制,八进制,十六进制数效果视频转换进制进制转换因为需要分别转化多个进制,无法对其数组长度进行判断,即将每个数字首元素作为存储数组长度的地址   private int[] Conversion(int num,int binary){     int[] remainder = new int[255];     int count = 1;     do {         remainder[count++] = num%binary;         num /= binary;     } while (num != 0);     remainder[0] = count;     return remainder;    }结果逆置通过对解析的进制数组进行逆置,因为十六进制的10——A,11——B…,所以需要对其进行判断,然后使用字符串拼接,最终返回一个结果字符串    private String Inversion(int[] array){            StringBuilder builder = new StringBuilder();        for (int i = array[0]-1; i >=1 ; i--) {            if (array[i] == 10){                builder.append("A");            }else if (array[i] == 11){                builder.append("B");            }else if (array[i] == 12){                builder.append("C");            }else if (array[i] == 13){                builder.append("D");            }else if (array[i] == 14){                builder.append("E");            }else if (array[i] == 15){                builder.append("F");            }else {                builder.append(array[i]);            }        }        return builder.toString();    }结果返回int num = Integer.parseInt(ResultBox.getText().toString());Binary_2.setText(Inversion(Conversion(num,2)));Binary_8.setText(Inversion(Conversion(num,8)));Binary_10.setText(Inversion(Conversion(num,10)));Binary_16.setText(Inversion(Conversion(num,16)));原文链接:https://blog.csdn.net/News53231323/article/details/123234328
  • [其他] 养老服务机构引入电子签章推动养老合同在线签
    养老服务中,养老机构要和老人及监护人签署相关入住协议和服务协议,数字化服务中如何实现远程签署成为康养服务数字化转型的关键。签署需求分析:老人及监护人常常处于异地,为了办理入住,合同常常要快递周转多地,签署效力低、办理入住周期长。养老服务公司全国各地分院印章管控难,每个季度的签署情况难管控,服务定价、合同规范性无法统一。(养老服务文件在线签署场景)契约锁解决方案:契约锁帮助集成康养服务机构现有的养老服务系统以及养老服务APP应用,打造一个面向养老院内部管理人员以及老人、监督人的全程数字化康养服务窗口。养老入住在线发起,养老院和老人及其监护人移动APP远程签署养老合同及告知书等文件,高效办理入住。(养老服务文件在线签署)老人办理入住,分院人员通过养老系统发起入住申请,系统自动调用契约锁电子模板生成服务合同、协议、告知书等必签电子文件。签署消息自动下发养老服务APP,监护人、老人以及分院责任人,手机端快速认证身份、电子签名、电子盖章,提升养老服务智能化水平。(在线签署养老合同)
  • [技术干货] AppCube平台APP打包与发布说明
    应用开发完成后,您可以在沙箱环境中进行测试,并最终发布到运行环境中。基于AppCube平台的开发包括3个阶段:开发->测试->上线。为保证各阶段数据隔离、正式上线环境版本稳定,平台为每个阶段提供了独立的环境。表1 环境说明环境名称作用开发环境是开发者专门用于开发的环境,即本书前面章节使用的环境。测试环境以沙箱(Sandbox)环境来作为测试环境。生产环境是正式发布上线的真实环境。说明:生产环境涉及商务合同的签订;因此,租户默认看不到该环境,需要线下联系平台运营团队开通后方可使用。
总条数:642 到第 页
上滑加载中