• [技术干货] 华为云低代码实践:快速搭建高效可控的算账系统
    在企业数字化转型进程中,算账系统作为财务核算与业务管控的核心载体,直接影响企业运营效率与决策质量。传统算账系统开发面临周期长、技术门槛高、供需对接难等问题,而低代码开发模式的兴起,为这类场景提供了高效解决方案。本文将以华为云Astro低代码平台为依托,详细拆解算账系统的实践路径,展现低代码在财务数字化场景中的落地价值。一、项目背景:算账场景的核心痛点与需求无论是中小企业的日常账务管理,还是大型企业的多维度成本核算,算账系统都需要满足“数据准确、流程规范、高效协同、可追溯”的核心诉求。结合实际业务场景,传统算账模式主要存在以下痛点:数据孤岛严重:业务数据(如采购、销售、报销)与财务数据分散存储,人工汇总耗时费力,易出现数据偏差,且项目经营数据汇总周期往往长达数十天,无法及时支撑决策。流程繁琐低效:传统凭证录入、审核、记账等环节需多岗位手动协作,以劳务产值申报为例,传统流程往往需要9个步骤,重复性工作多,效率低下。技术门槛高:定制化开发需专业开发团队支撑,中小企业难以承担高昂成本,且需求变更响应滞后,无法快速适配业务迭代。可追溯性差:财务数据与业务凭证的关联关系不清晰,审计核查时需逐一核对,耗时耗力,且难以实现全链路数据溯源。基于上述痛点,本次实践核心目标是搭建一套基于华为云低代码的算账系统,实现“数据集中化、核算标准化、流程自动化、追溯便捷化”,同时降低开发成本与周期,快速响应业务需求。二、技术选型:为何选择华为云Astro低代码平台在低代码平台选型过程中,我们对比了多款主流产品,最终选择华为云Astro低代码平台,核心原因在于其贴合算账系统场景的四大核心优势:1. 全场景开发能力,适配财务业务需求华为云Astro支持零码、低码、高低码协同的开发模式,既满足财务人员(非技术人员)通过拖拽式操作快速搭建基础功能,也支持技术人员通过代码扩展实现复杂业务逻辑(如自定义核算规则、复杂报表计算)。平台预置了丰富的UI组件与流程模板,可直接适配凭证管理、账簿生成、报表统计等算账核心场景。2. 数据安全与合规保障,守护财务核心数据财务数据的安全性与合规性是算账系统的重中之重。华为云Astro提供端到端安全可信保障,支持数据加密传输与存储,满足《数据安全法》《个人信息保护法》等法规要求;同时支持精细化权限管控,可按角色分配凭证录入、审核、记账等操作权限,实现职责分离,防止数据篡改与泄露。3. 高效流程自动化,大幅降低人工成本平台内置强大的流程引擎,可实现算账全流程自动化管控,包括凭证自动校验、审核待办分发、期末自动转账、报表自动生成等场景。通过流程配置,可将复杂业务步骤简化,例如将劳务产值申报步骤从9个减至2个,大幅提升工作效率。4. 开放集成与数据协同,打破信息孤岛华为云Astro支持与企业现有系统(如ERP、CRM、银行对账系统)快速集成,实现业务数据与财务数据的无缝同步;同时基于统一数据底座,可实现数据一处维护、多处复用,避免重复录入,确保数据一致性,将项目经营数据汇总周期从数十天缩短至1天,效率提升20倍以上。三、核心实践:华为云低代码算账系统搭建全流程本次算账系统实践基于华为云Astro低代码平台,采用“需求梳理→基础配置→功能开发→流程编排→集成测试→上线运维”的六步流程,全程无需大量编码,即可快速完成系统搭建。1. 需求梳理与架构设计结合财务核算核心场景,明确系统核心模块与业务流程。参考总账系统设计规范,本次搭建的算账系统核心模块包括:基础数据管理、凭证管理、账簿管理、报表管理、期末处理、权限管理,各模块形成“数据录入→审核→记账→结账→输出”的完整闭环。在架构设计上,基于华为云Astro的“云端一体”架构,采用“前端可视化搭建+后端云服务支撑”模式,前端通过拖拽组件快速构建页面,后端对接华为云数据库、云函数等服务,实现数据存储与业务逻辑处理,同时支持多端适配(Web端、移动端),满足随时随地办公需求。2. 基础数据配置:筑牢核算基础基础数据是算账系统正常运行的前提,主要包括会计科目、辅助核算项、记账规则等配置,通过华为云Astro的零码配置功能即可完成:会计科目管理:基于《企业会计准则》,通过平台预置的科目模板,快速创建资产、负债、所有者权益、成本、损益等类别科目,支持科目编码层级配置(如4-2-2级编码:1002银行存款→100201工行账户),同时可根据企业需求自定义科目、冻结停用历史科目。辅助核算项管理:配置部门、客户、供应商、项目等辅助核算维度,指定需关联辅助核算的科目(如“管理费用”关联部门、“应收账款”关联客户),并维护相关档案信息,实现精细化核算。记账规则配置:设置凭证录入必填字段(摘要、借贷方金额、辅助核算项等)、金额平衡校验规则、权限控制规则(如会计录入、主管审核),确保核算流程规范合规。3. 核心功能开发:拖拽式搭建+低码扩展借助华为云Astro的可视化开发工具,无需编码或少量编码即可完成核心功能开发,重点实现三大核心场景:(1)凭证管理:自动化录入与智能校验凭证作为算账系统的核心数据入口,支持手工录入与模板导入两种方式。通过平台预置的凭证录入组件,拖拽配置页面元素(如科目选择框、金额输入框、辅助核算下拉框),并配置智能校验规则:科目有效性校验:确保录入科目为末级科目且未冻结;金额平衡校验:自动校验借贷方金额是否相等,不平衡则提示报错;辅助核算匹配校验:若科目需关联辅助核算项,自动校验是否选择对应维度。同时,通过低码编写简单脚本,实现凭证自动编号、附件上传(如发票、合同照片)、OCR识别自动填充凭证信息等功能,进一步提升录入效率。(2)账簿与报表管理:自动生成与可视化展示基于记账凭证数据,系统自动生成总账、明细账、日记账等各类账簿,支持按科目、期间、辅助核算项组合查询(如查询“2026年1月销售部管理费用明细”)。在报表管理模块,通过平台预置的报表模板(资产负债表、利润表、现金流量表),配置取数规则,实现报表数据自动提取与计算,无需人工汇总。借助华为云Astro的大屏可视化能力,可快速搭建财务数据大屏,实时展示核心指标(如月度收支总额、预算执行率、应收账款余额),支持图表化展示(柱状图、折线图、饼图),让管理层一目了然掌握财务状况,助力智慧决策。(3)期末处理:自动化结账与数据闭环期末处理是财务核算的关键环节,通过平台流程引擎配置期末结账流程,实现自动化处理:月末检查:系统自动校验所有凭证是否已审核记账、试算是否平衡、关联业务(如折旧计提、税费计算)是否完成,不满足条件则禁止结账;自动转账:按预设规则自动生成费用分摊、损益结转、税费计提等转账凭证,无需人工录入;结账操作:检查通过后,一键完成结账,标记当前期间为“已结账”,自动生成下月期初余额,同时支持反结账功能(仅允许授权角色操作)。4. 流程编排:全链路自动化协同通过华为云Astro的流程设计器,可视化编排算账全流程,实现多岗位高效协同:凭证录入流程:会计岗录入凭证后,系统自动推送审核待办至主管岗;凭证审核流程:主管岗审核通过后,凭证自动进入记账队列,审核不通过则退回会计岗修改;期末结账流程:结账前自动推送待办事项至相关岗位(如资产岗完成折旧计提、税务岗完成税费计算);消息通知流程:流程节点变更后(如审核通过、结账完成),自动通过邮件、短信或系统消息通知相关人员,确保信息实时同步。通过流程自动化,不仅减少了人工沟通成本,还确保了流程执行的规范性与及时性,避免人为遗漏。5. 集成测试与上线运维在测试阶段,通过华为云Astro的模拟运行功能,模拟真实业务场景(如凭证录入、审核、结账、报表生成),校验系统功能准确性、流程顺畅性、数据一致性;同时对接企业现有系统(如银行对账系统),测试数据同步效果,确保系统集成正常。测试通过后,通过平台的一键发布功能,快速部署系统上线,支持私有化部署或云上部署模式。上线后,借助华为云的运维监控能力,实时监控系统运行状态(如响应速度、报错情况),及时排查问题;同时支持需求快速迭代,通过低代码修改功能配置或流程编排,无需重启系统即可完成升级。四、实践成果:降本增效,赋能财务数字化转型基于华为云低代码平台搭建的算账系统,上线后取得了显著的业务价值与技术价值,核心成果如下:开发效率大幅提升:相比传统定制化开发,开发周期缩短60%以上,无需专业开发团队,财务人员与IT人员协同即可完成系统搭建与迭代,大幅降低开发成本。业务流程显著优化:凭证处理、期末结账等核心流程效率提升80%,劳务产值申报、费用报销等场景的操作步骤大幅简化,人工工作量减少70%以上。数据质量与决策效率提升:实现业务与财务数据无缝对接,数据汇总周期从20天缩短至1天,数据准确率提升至99.9%,为管理层提供实时、准确的财务数据支撑,助力科学决策。合规性与可追溯性增强:全流程规范管控,权限分工明确,数据从凭证到账簿、报表全链路可追溯,满足审计与监管要求,降低合规风险。五、总结与展望本次基于华为云Astro低代码平台的算账系统实践,充分验证了低代码开发模式在财务数字化场景中的可行性与优势——通过可视化搭建、自动化流程、开放集成等能力,快速解决了传统算账模式的低效、易错、孤岛等痛点,实现了“降本、增效、合规、可控”的核心目标。未来,随着AI技术与低代码平台的深度融合,可进一步优化算账系统的智能化水平,例如通过华为云大模型实现发票OCR智能识别、凭证自动分类、异常账务智能预警等功能;同时拓展多场景应用,如预算管理、成本分析、财务预测等,构建全流程智能化的财务核算体系,为企业数字化转型注入更强动力。华为云低代码平台将持续作为企业数字化创新的重要载体,让更多非技术人员参与到系统搭建中,实现“人人都是开发者”,加速业务创新与转型落地。
  • [案例共创] 【案例共创】基于MaaS结合开发者空间Astro低代码平台完成基线核查结果分析系统
    一、概述1. 案例介绍本案例面向网安行业运维人员等,用于分析基线报告的风险等级,筛选需要紧急修复的配置项,降低认为分析的操作误差。通过实际操作,了解如何利用Astro低代码平台开发应用。在这个过程中,学习从模型集成、界面操作、页面布置到逻辑实现以及应用打包一系列关键步骤,从而掌握Astro低代码平台的基本使用方法及于大模型的结合,体验其在应用开发中的优势。开发者空间Astro低代码开发平台通过平台提供的界面、逻辑、对象等可视化编排工具,以“拖、拉、拽”的方式来快速构建应用,从而实现所见即所得的应用开发构建体验。华为开发者空间,是为全球开发者打造的专属开发者空间,致力于为每位开发者提供一台云主机、一套开发工具和云上存储空间,汇聚昇腾、鸿蒙、鲲鹏、GaussDB、欧拉等华为各项根技术的开发工具资源,并提供配套案例指导开发者 从开发编码到应用调测,基于华为根技术生态高效便捷的知识学习、技术体验、应用创新。ModelArts Studio(MaaS)平台:是华为云推出的一款大模型即服务平台,可以一站式的对业界主流开源大模型进行部署托管,同时开放大模型API服务,可以结合业界主流Agent开发框架,轻松构建AI Agent应用。2. 适用对象企业个人开发者高校学生3. 案例时间本案例总时长预计90分钟。4. 案例流程说明:领取华为开发者空间,登录华为开发者空间-低代码应用开发平台;新建低代码应用,进入Astro轻应用服务控制台主页,开发应用;5. 资源总览本案例预计花费0元。资源名称规格单价(元)时长(分钟)MaaS 平台商用模型DeepSeek-R1 轻量体验包(¥7.00)/ DeepSeek-V3 轻量体验包(¥3.50)领券免费90华为开发者空间 - 低代码应用开发平台系统标配免费90二、案例准备1、开通ModelArts Studio(MaaS)商用百万Token活动连接:每周畅领100万商用级Tokens!基于CloudMatrix384超节点,Token时延低、TPM/RPM速率高,助您开发商用级AI应用!商用百万Token代金券免费领取链接(可每周领取):DeepSeek-R1/V3-64K百万tokens代金券:cid:link_22.1、大模型领取:切换到开发者空间首页,或者点击上面连接,参与活动“百万商用服务tokens免费领!”活动,按照使用说明进行服务开通:活动页面:2.2、开通完成后,进行大模型的接入:ModelArts控制台:ModelArts - Console在线推理里面搜刚刚买的R1还是V3,然后点击搜索结果后面的调用说明,看一下model参数,后面会用上,一般都是DeepSeek-R1或DeepSeek-V3:2.3、创建apikey点击前往API Key管理创建apikey,点击新建创建apikey注意!!创建好API Key之后,点击后面的复制按钮,妥善保存,若未复制保存,后续只能新建。三、华为开发者空间-低代码应用开发平台开发应用登录华为开发者空间,在左侧菜单列表选择华为开发者空间 -> 开发平台 -> Astro 低代码开发,进入华为开发者空间-低代码应用开发平台。 创建应用新建Astro低代码应用,标准应用创建 填写应用必备的属性 创建连接器跳转后选择集成,创建一个大模型连接器: 正确填写模型名称和KEY,我这里购买了R1的资源包,所以填写的R1的模型名称: 保存后点击测试看是否成功调用:  创建OBS连接器:这里前提需要创建一个OBS对象桶并购买对应的资源包,已经生成ak/sk获取ak/sk的方法放上官方链接:cid:link_6创建桶和资源包这个不必说,大家都懂得!下面继续添加桶信息: 创建数据对象新建一个数据对象: 确认后编辑该对象: 新建字段:这里选择文本区,能容纳更多的字段: 继续添加其他字段,我这里只需要用到三个:  创建结构体新建结构体用于数据调用:创建后修改结构体:   创建UI页面随后点击页面->新建页面,输入一些必备信息: 页面这里拖入一个表单进去: 然后点击箭头所向的数据绑定,新建一个模型: 新建一个对象: 下一步配置对象,选择字段:  下一步,自动新增方法:  然后选择模型,确认保存: 这里我选择只绑定模型:   这里拖动一个多行文本框,并输入一些基本属性: 点击数据绑定设置,将当前元素与模型中自建的文本报告字段绑定: 拖动一个上传控件,相同的一些操作,再加个必填的属性:修改属性:    拖动一个提交按钮,不绑定数据:     为了输出直观一点,这里拖动一个md控件,并绑定属性为result报告输出字段:    创建服务编排创建服务编排: 添加赋值与maas连接器  全局上下文添加变量:  配置出入参:  模块赋值:  配置大模型连接器:   配置大模型参数:   然后按顺序点击按钮保存一下:  第三步会打开一个测试页面,可简单测试一下:    编写脚本Obs文件读取脚本至此,开始编写脚本, 首先前面的obs对象已绑定。点击逻辑->脚本,新建一个名称: 这里是为了读取obs的excel文件,然后解析内容。完整代码如下:import * as excel from 'excel';import * as objectstorage from 'objectstorage';@action.object({ type: "param" })export class Input { @action.param({ type: "String", required: true, description: "fileUrl" }) fileUrl: string;}@action.object({ type: "param" })export class Output { @action.param({ type: "Any", description: "result message" }) fileContent: Object;}@action.object({ type: "method" })export class PostProcess { @action.method({ input: "Input", output: "Output" }) public postProcess(input: Input): Output { let ObsCli = objectstorage.newClient(objectstorage.StoreType.OBS, "SecLineCheck__uploadobs", "up-files"); // 连接器名称+桶名 let data = ObsCli.getObject(input.fileUrl);//文件名 let x = excel.decodeAll(data); let out = new Output(); out.fileContent = x; return out; }}然后回到页面,点击按钮,数据绑定: 这一步是为了新建一个模型,用于存数据,但是无需绑定:点击新建模型,选择自定义,继续下一步即可:  然后选择事件,新增脚本:  选择执行脚本,添加输入的文件地址,以及内容输出到指定的数据模型:(这里传入的url地址是表单提交后的CheckData数据模型里面的SecLineCheck__filesUrl字段的originalUrl值,由于环境需要,所以采用的JSON解析传递,想要具体探究的可以选择自定义动作,然后将整个数据模型的表单用控制台打印一下就行。)  流程调用脚本保存完继续新建,自定义脚本,这里就是汇聚文本框和文件内容, 然后调用编排动作去执行分析并返回对应的数据: 完整代码:var model = context.$model.ref("CheckData").getData(); var modelCopy = JSON.parse(JSON.stringify(model)); var model2 = context.$model.ref("excel_result").getData(); var modelCopy2 = JSON.parse(JSON.stringify(model2)); var keys = Object.keys(modelCopy2); console.log(keys); var allSheetValues = []; keys.forEach(key => { if (Array.isArray(modelCopy2[key])) { const sheetArray = modelCopy2[key]; sheetArray.forEach(row => { if (Array.isArray(row)) { allSheetValues.push(...row); } }); } }); var newSheetValues = allSheetValues.join(",") console.log(allSheetValues); // 处理非字符串字段 Object.keys(modelCopy).forEach(item => { if (modelCopy[item] && typeof modelCopy[item] !== "string") { modelCopy[item] = JSON.stringify(modelCopy[item]); } }); // 提取问题字段值 var message = modelCopy["SecLineCheck__text__CST"] // 构建提示文本 var suggestionText = `你是一个精通网络安全的专家,现在已经为甲方单位的服务器做完基线核查,这里是具体的报告,请你根据报告内容分析危险等级,先输出需要紧急修复的配置,再输出风险等级分析,使用MAKEDOWN的格式。这里是我补充的其他文本信息,如果它存在的话:${message}。\n这里是需要处理的报告信息,如果它存在的话:${newSheetValues}`.replace(/"/g, "'"); // 初始化Flow var _flow = context.flow("SecLineCheck__process"); // 调用AI服务获取建议 try { // 提示信息 context.$message.info("正在分析,请稍后..."); const resp = await _flow.run({ input: suggestionText }); const reader = resp.body.getReader(); const decoder = new TextDecoder(); let buffer = ''; let msg = ''; while (true) { const { done, value } = await reader.read(); if (done) break; buffer += decoder.decode(value); const lines = buffer.split('\n'); // 保留最后一行(可能不完整) buffer = lines.pop() || ''; for (const line of lines) { if (!line.trim()) continue; try { const jsonStr = line.startsWith('data: ') ? line.substring(6) : line; if (jsonStr.trim() === '[DONE]') continue; const obj = JSON.parse(jsonStr); const newMsg = obj?.choices[0]?.delta?.content || ''; if (newMsg) msg += newMsg; } catch (err) { console.warn('解析JSON失败,保留到下一轮处理:', err.message); buffer = line + '\n' + buffer; } } } // 最终保存结果 modelCopy.SecLineCheck__result__CST = msg; context.$model.ref("CheckData").setData(modelCopy); // 提交数据 const saveResult = await context.$model.ref("CheckData").save(); if (saveResult.resCode == 0) { const recordId = saveResult.result[0]?.id; if (recordId) { // context.$page.loadStdPage('xiaocao__t_mass', "recordId=" + recordId); // // 成功消息 // context.$message.success('生成成功'); } } } catch (error) { console.error("AI服务调用失败:", error); // 可以添加错误处理逻辑,如显示错误信息 }至此这个版本的编辑结束,选择保存,预览:   结束预览输出结果:  四、案例分享至此案例结束,案例整体步骤看起来比较多,但实际基本上都是命令的参数相互调用,建议不要使用大小写来重复命令,容易混淆,我已经上过当了。另外通过案例发现该低代码应用场景的处理节点还是比较缺乏的。譬如我这个案例最不好处理的就是附件上传,一开始是直接创建数据对象来存储,但是无法上传,后续就采用OBS存储,但是只返回违反没链接,而大模型不处理链接,所以需要写脚本来解析上传附件到OBS返回的文件链接,然后再与其他的内容进行合并,输送到流程里面进行下一步。这里如果上传支持一些节点调用或者直接返回数据而无需上传的功能就更好使了。另外还有一个问题就是我的案例是基线结果分析,那么提供的检查报告里面肯定会存在一些代码,而这些内容在流程这一块是走不通的,会提示疑似攻击行为,但是直接调用大模型却可以。希望后续能够优化一下。感谢华为云提供的学习平台,让自己能够接触到更多的新鲜东西,仅仅需要付出一些时间成本,而收获良多。希望后续针对该平台优化得更好! 附件分享文章不支持zip上传,放一个百度网盘的地址:链接: https://pan.baidu.com/s/1zUtbbqMp43-2Ljj1PNex6g?pwd=ukfw 提取码: ukfw 复制这段内容后打开百度网盘手机App,操作更方便哦我正在参加【案例共创】第7期 基于MaaS商用服务 + 华为开发者空间 - Astro 低代码开发平台构建低代码应用 cid:link_3
  • [案例共创] 【案例共创】基于华为开发者空间-云开发环境(容器)+MaaS实现 <来刷题吧> - AI试卷生成和测试平台
    案例介绍本项目是基于华为开发者空间云上开发环境部署的<AI试卷生成与在线测试平台>技术实践案例。该应用深度集成华为云MaaS(ModelArts as a Service)平台提供的DeepSeek-V3大语言模型,充分利用平台提供的百万级商用token处理能力,构建了一个能够一键生成任意学科、任意难度的试卷,提供模拟考试环境、自动评分以及智能解析功能的智能试卷生成与在线测试平台。案例内容一、概述1. 案例介绍华为开发者空间,是为全球开发者打造的专属开发者空间,致力于为每位开发者提供一台云主机、一套开发工具和云上存储空间,汇聚昇腾、鸿蒙、鲲鹏、GaussDB、欧拉等华为各项根技术的开发工具资源,并提供配套案例指导开发者从开发编码到应用调测,基于华为根技术生态高效便捷的知识学习、技术体验、应用创新。本项目是华为开发者空间开发平台 - 云开发环境(容器)部署的<AI试卷生成与在线测试平台>技术实践案例。该应用深度集成华为云MaaS(ModelArts as a Service)平台提供的DeepSeek-V3大语言模型,充分利用平台提供的百万级商用token处理能力,构建了一个能够一键生成任意学科、任意难度的试卷,提供模拟考试环境、自动评分以及智能解析功能的智能试卷生成与在线测试平台。<AI试卷生成与在线测试平台>技术架构上,项目采用react+typescript技术栈,基于华为MaaS平台的强大算力支持,实现了智能解析功能的智能试卷生成与在线测试平台。华为MaaS平台不仅提供高质量的DeepSeek-V3模型,更具备百万token的超长上下文处理能力,使得本应用能够生成准确的试题。前端采用React框架构建响应式界面,后端通过封装MaaS平台API,为用户提供刷题、模拟考试、自动评分、智能解析等功能。2. 功能特性AI 智能出题: 输入任意主题(如“Python基础”、“中国近代史”、“驾考科目一”),即刻生成包含单选、多选、判断题的完整试卷。模拟考试: 沉浸式答题界面,配备倒计时功能。自动评分: 考试结束后立即出分,通过可视化图表展示得分详情。错题回顾: 提供复习模式,高亮显示错题,并附带 AI 生成的详细解析。题集功能: 建立错题难题题集,不断复习巩固知识。题集试卷: 根据题集生成试卷,检验你的学习成果。历史记录: 自动保存考试记录与成绩,随时回溯过往练习。云端同步: 支持配置 Huawei Cloud OBS 将考试记录同步至云端。3. 适用对象企业个人开发者高校学生4. 案例时间本案例总时长预计60分钟。5. 案例流程说明:登录华为开发者空间,VS Code安装Huawei Developer Space插件,远程连接操作云开发环境;远程创建、开机、连接云开发环境(虚拟机);领取百万token代金券福利,开通商用模型服务,获取模型API 地址、API Key等参数;GitCode拉取代码 https://gitcode.com/zhepama/ai-exam-platform.git,安装依赖,修改参数;启动程序,在浏览器端测试验证<AI试卷生成与在线测试平台>。5. 资源总览本案例预计花费0元。资源名称规格单价(元)时长(分钟)华为开发者空间开发平台 - 云开发环境(容器)鲲鹏通用计算增强型 kc1 | 2vCPUs | 4G | HCE免费60二、基础环境与资源准备1. VS Code远程连接云开发环境(容器)参考案例《华为开发者空间 - 云开发环境(容器)IDE插件远程连接操作指导》中的“二、云开发环境IDE插件远程连接操作指导”的内容,完成“1. 安装插件” ~ “4. 连接”章节步骤。完成连接之后的状态:2. 领取百万免费token福利参考案例《Versatile Agent中自定义接入大模型配置华为云Maas指导》中的“一、 领取”章节内容,领取华为开发者空间百万token代金券福利,购买ModelArts Studio DeepSeek-V3 轻量体验包(¥3.50)。开通商用模型服务,最后获取API地址、API Key的参数值。三、来刷题吧 - AI试卷生成与在线测试平台1.来刷题吧 - AI试卷生成与在线测试平台功能介绍AI试卷生成与在线测试平台是一个基于DeepSeek大模型的智能聊天应用,提供美观的Web界面和流畅的对话体验。项目采用React + Typescript,结合华为云MaaS平台百万免费商用token,配置DeepSeek-V3大模型。🛠️ 技术栈核心框架: React 19构建工具: ViteUI 样式: Tailwind CSS图标库: Lucide React环境管理: dotenv📂 目录结构server/index.js - 后端服务主入口与路由逻辑src/App.tsx - 前端应用主入口与路由逻辑src/services/geminiService.ts - AI 接口调用与试卷生成逻辑src/services/storageService.ts - 本地存储与云同步逻辑src/components/ - UI 组件库types.ts - TypeScript 类型定义2. 获取来刷题吧 - AI试卷生成与在线测试平台代码新建项目文件在/workspace/node目录下创建ai-exam-platform文件夹。cd /workspace/node mkdir ai-exam-platform cd ai-exam-platform下载代码点击Source Control图标,然后点Initialize Repository。点CHANGES右侧的 ··· 图标,在下拉菜单中选择Clone。输入代码仓地址,Clone from URL: https://gitcode.com/zhepama/ai-exam-platform.git选择代码仓目录:/workspace/ai-exam-platform/,点Select as Repository Destination。然后点Open,将此目录设置为本地代码仓。加载结束后的状态如下:3. 安装项目依赖安装项目依赖npm install2. 修改配置文件,配置API Key在项目根目录下创建一个 .env 文件,参考 .env.example 进行配置:cp .env.example .env打开配置文件.env,修改配置参数。将配置文件中的your_API_Key替换为“二、基础环境与资源准备”章中的“4. 领取百万免费福利”节最后获取到的API Key。配置项说明:变量名必填描述示例API_KEY✅AI 模型的 API 密钥 (Gemini 或 OpenAI)AIzaSy...AI_PROVIDER❌指定 AI 提供商 (gemini 或 openai)openaiAI_MODEL❌指定模型版本deepseek-v3.1AI_BASE_URL❌OpenAI 接口地址 (用于代理)https://api.modelarts-maas.com/v2OBS_SERVER❌连接OBS的服务地址``OBS_ACCESS_KEY_ID❌OBS访问密钥中的AK。``OBS_SECRET_ACCESS_KEY❌OBS访问密钥中的SK。``OBS_BUCKET❌OBS的bucker``JUDGE_COUNT❌判断题数量。5SINGLE_CHOICE_COUNT❌单选题数量。5MULTI_CHOICE_COUNT❌多选题数量5# API配置 # AI Provider Configuration # Options: 'gemini' | 'openai' # Default: 'gemini' AI_PROVIDER=openai # API Key for the selected provider # For Gemini: Get from Google AI Studio # For OpenAI: Get from OpenAI Platform API_KEY=your_API_Key # 替换为你的实际API密钥 # AI Model to use # Default for Gemini: 'gemini-2.5-flash' # Default for OpenAI: 'gpt-3.5-turbo' # You can override this with other models like 'gpt-4', 'gemini-1.5-pro', etc. AI_MODEL=deepseek-v3.1 # AI Base URL # Only used if AI_PROVIDER is 'openai' (or compatible services like DeepSeek, Moonshot, etc.) # Default: 'https://api.openai.com/v1' AI_BASE_URL=https://api.modelarts-maas.com/v2 5. 测试体验来刷题吧 - AI试卷生成与在线测试平台在VS Code终端窗口中运行如下命令,启动来刷题吧 - AI试卷生成与在线测试平台。npm run dev:server在VS Code弹出的对话框中点Open in Browser,或者直接在浏览器中打开:http://localhost:3000/输入测试问题:“驾考科目一”,来刷题吧 - AI试卷生成与在线测试平台正确回答。开始答题提交试卷查看错题每一题都会有答案解析数据同步题集功能 (新增)查看题集题集中会随机出题,供你测试点击题目卡片,卡片反转可以查看答案题集试卷根据题目生成试卷生成新的试卷进行测试吧至此,基于华为开发者空间-云开发环境(容器)+MaaS实现来刷题吧 - AI试卷生成与在线测试平台案例结束,各位开发者快来华为开发者空间体验吧。我正在参加【案例共创】【第8期】基于华为开发者空间云开发环境(容器),集成华为云AI服务(Agent或MaaS API),完成AI应用构建开发最佳实践cid:link_6
  • [问题求助] VPN启动失败
    strongswan up gw-gw 命令retransmit 5 of request with message ID 0sending packet: from 192.168.0.222[500] to 121.37.54.108[500] (464 bytes)giving up after 5 retransmitsestablishing IKE_SA failed, peer not respondingestablishing connection 'gw-gw' failed
  • [案例共创] 【案例共创】基于MaaS结合Astro平台快速创建景点推荐智能化系统
    案例介绍本案例应用基于MaaS结合Astro平台快速创建景点推荐智能化系统,针对用户选择的城市基于人工智能大模型DeepSeek智能输出景区推荐。 一、概述1. 案例介绍开发者空间Astro低代码开发平台通过平台提供的界面、逻辑、对象等可视化编排工具,以“拖、拉、拽”的方式来快速构建应用,从而实现所见即所得的应用开发构建体验。本案例应用基于MaaS结合Astro平台快速创建景点推荐智能化系统,针对用户选择的城市基于人工智能大模型DeepSeek智能输出景区推荐。通过项目实际流程操作,让大家更加清晰的了解如何利用Astro低代码平台来进行应用的开发。在这个操作流程中,大家将会学习到Astro集成模型、界面拖拽操作、页面布置到逻辑实现以及应用打包一系列关键步骤,从而掌握Astro低代码平台的基本使用方法及于大模型的结合,体验其在应用开发中的优势。华为开发者空间,是为全球开发者打造的专属开发者空间,致力于为每位开发者提供一台云主机、一套开发工具和云上存储空间,汇聚昇腾、鸿蒙、鲲鹏、GaussDB、欧拉等华为各项根技术的开发工具资源,并提供配套案例指导开发者 从开发编码到应用调测,基于华为根技术生态高效便捷的知识学习、技术体验、应用创新。2. 适用对象企业个人开发者高校学生3. 案例时间本案例总时长预计90分钟。4. 案例流程说明:领取华为开发者空间,登录华为开发者空间-低代码应用开发平台;新建低代码应用,进入Astro轻应用服务控制台主页,开发应用;5. 资源总览本案例预计花费0元。资源名称规格单价(元)时长(分钟)MaaS 平台商用模型DeepSeek-R1 轻量体验包(¥7.00)/ DeepSeek-V3 轻量体验包(¥3.50)领券免费90华为开发者空间 - 低代码应用开发平台系统标配免费90 二、华为开发者空间-低代码应用开发平台1. 登录华为开发者空间-低代码应用开发平台华为开发者空间-低代码应用开发平台( Astro 低代码开发平台)是华为云推出的一款可视化应用开发平台,旨在通过提供的界面、逻辑、对象等可视化编排工具,以“拖、拉、拽”的方式来快速构建应用,从而实现所见即所得的应用开发构建体验,以此来降低开发门槛,提升企业数字化应用构建效率。平台主要特点包括:可视化开发:通过图形化界面和预置组件,无需编写复杂代码即可快速搭建应用;全场景支持:覆盖Web、移动端、大屏等多终端应用开发;高效集成:内置连接器可快速对接华为云及其他主流企业系统;智能辅助:提供AI辅助开发能力,如智能表单生成、流程自动化等;企业级能力:具备权限管理、数据安全、高可用等企业所需特性。登录华为开发者空间,在左侧菜单列表选择华为开发者空间 -> 开发平台 -> Astro 低代码开发,进入华为开发者空间-低代码应用开发平台。2. 创建低代码应用华为开发者空间-低代码应用开发平台页面点击新建低代码应用,在弹出的新建低代码应用对话框中,选择标准应用/基于模板创建,点击确定按钮。点击确定后,弹出创建空白应用页面,上传图片、填写名称、标签后,点击确定,则可创建成功。创建成功后,浏览器会自动打开一个新的页面:Astro轻应用服务控制台。三、项目设计开发1、页面简单了解点击菜单界面-页面 后面的加好可以创建一个新页面,当然也可以点击后面的目录,创建一个新目录,对页面进行汇总,这里我们就不演示了,直接创建一个页面点击创建后,弹出《添加标准页面》,填写标签和名称,这里可以根据自己的需求进行 填写,填写完成后点击添加。这样就创建出了一个空白 的html页面,大家可以看到基本组件块,有很多基础组件,包括了表单 、表格、容器、分栏等等,一应俱全。将表单拖拽到中间页面上,右侧会自动弹出元数据表单配置向导,其中可以选择数据源,选择后可以下一步进行配置功能点。注意:这里的数据源可以先选择一个默认的测试一下。后面我们会详细配置数据源。数据源表单我们选择名称、文件名称后,点击下一步,选择按钮为保存 。 可以看到页面上创建了一个表单,有名称和文件名称2个字段,且事件按钮为保存。接下来我们需要注意的是,关于这个表单所有的操作,如属性、事件、库等,都可以在右侧进行配置。 2、Mass领取开发者空间首页-激励管理-非计划权益中选择DeepSeek-R1领取百万tokens,点击立即申请可申请代金券。购买DeepSeek Tokens套餐包,DeepSeek-R1 轻量体验包(¥7.00)或DeepSeek-V3 轻量体验包(¥3.50)。点击去支付后 ,在支付 页面选择代金券后,0元购买。 购买完成后, 进入ModelArts Studio服务页面—在线推理—商用服务—DeepSeek-V3/R1-64K—开通服务—API Key配置。这里我们选择DeepSeek-R1 模型。API Key的配置一定要注意,在调用模型时必须要用API Key进行验证,所以需要生成一个秘钥,秘钥生成时可以复制,后面是不能查看的,忘记了就只能删除重新生成。3、配置连接器生成完成API Key后,我们回到Astro页面,点击右侧菜单集成 - 连接器实例-大模型-MaaS云平台,来 新增一个与大模型进行连接的连接器。创建连接器时,标签可以自行填写。名称需要注意,后面在调用模型时,是以这个名称来进行调用的,我这个名称相当于是:xiaocao__mass 。模型名称填写真实的就行,这样可以更好的区分。API Key则是上面刚创建的秘钥。保存后,一个连接器就创建好了,接下来就是测试和配置连接器了。我们先测试下,点击Maas云平台详情,也就是上面这张图,有一个测试按钮,可以输入参数测试一下,如果正常返回数据了,说明大模型已经联通了。接下来,我们创建一个逻辑编排,使用一个逻辑,把输入与大模型进行连接起 来(也就是实现上面测试模块的功能点)点击逻辑-编排。添加一个编排。添加编排时,最需要注意的也是这个名称。我们在后面在页面上调用编排时,使用的就是编排名称值。添加完成后,页面上就有 一个启动按钮,点击启动按钮,可以弹出基本信息浮层,点击全局上下文,我们来创建一些变量。创建2个变量input和output ,其中input是文本输入,output是任意类型代表输出。注意修改类型可以点击右侧三个小点-设置里面进行设置。接下来我们要创建一个对象变量来接收大模型返回的数据,在此之前我们创建一个全局的数据结构体来接收这个对象。点击数据-结构体-新建结构体。开始创建全局结构体填写完成结构体基本 信息后,可以看到关于结构体的详细信息。点击结构按钮,进行结构体内容 模块,点击结构体后面的编辑按钮,增加相应的结构类型。role是角色的意思,content是内容,也就是我们要通过角色和内容去调用 maas.结构体创建完成后,我们需要回到编排页面中去,继续创建对象变量,这样 我们在创建时就可以选择全局结构体,直接选择我们刚才创建的结构体。 变量都创建完成后, 我们就可以在画布上进行变量的操作了。点击参数按钮,将入参和出参拖动到对应的位置 选择赋值图标,将赋值图标拖进画布,并连接起来选择赋值图标后,可以将变量赋值,新增一行message变量中的role,直接拖入就可以,值设置为"user"(要用英文双引号),再新增 一行message变量中的content,变量值直接将变量中的input拖入回到一级菜单,选择连接器,选择Mass云平台,拖进画布。将赋值与Mass云平台进行连接。将Mass连接器关联上我们创建的大模型对连接器进行参数设置,目标message将配置的message拖入到源。新增输出参数:选择result ,将 output拖入。在这里强调一下,其实我们很明确了,这里就是在配置给大模型的入参和出参。现在就已经配置完成整个连接器了, 接下来我们保存、启用、运行就可以进行测试了。点击启用后会打开一个新页面显示,输入参数:{"input":""},运行。 可以看到运行的结果,这是大模型的结果,这样就已经通了。 4、页面构造我们是基于一个城市的旅游推荐,所以我页面上只需要选择一个city,通过提示词由智能体推荐出来旅游推荐就可。所以我们先创建一个城市数据选择项,点击数据-选项列表-新建,开始创建选项列表和一个存用户输入信息的表就行。填写完成标签、名称后、增加标签名称。比如北京:标签和名称都填写北京就可以,后续如果有其他的城市我们也可以在这里添加。点击数据-对象,添加一 个对像,添加完成对象后,会默认有一些表字段,根据需求我们在创建一些自己的表字段就可以了。数据创建后,我们就可以开始构建页面了。在界面菜单,点击新增创建一个旅游推荐页面,将页面修改为手机端。在页面右侧选择公共区域,这是整个页面的公共区域,可以先上传一张背景图。选择容器,对容器进行布局的基础配置,选择标题。选择标题,对标题进行一些简单的布局和字体处理。这里需要有一个小细节可以加速我们的学习:组件导航这里可以更方便的选择一个模块。添加表单到页面配置好下拉列表,将其他3个标签删除选中表单,简单调整一下边距和透明度,效果就实现了。我们丢选择下拉选框,开始给下拉选框绑定数据输入名称,选择按对象创建选择对象,选择字段,点击下一步选中名称,点击确定,就绑定好数据了。选中开始推荐按钮,绑定事件,开始对接大模型点击创建后,编写js代码, 注意需要将我提供的内容关于xiaocao的命名空间进行修改。这js的用法与vue是一样的。// 表单校验var _form = context.$component.form;var validFlag = _form.formValidateUnPromise();if (!validFlag) return false;// 序列化表单数据var model = context.$model.ref("message").getData();var modelCopy = JSON.parse(JSON.stringify(model));// 处理非字符串字段Object.keys(modelCopy).forEach(item => { if (modelCopy[item] && typeof modelCopy[item] !== "string") { modelCopy[item] = JSON.stringify(modelCopy[item]); }});// 提取问题字段值var city = modelCopy["name"]var message = modelCopy["xiaocao__message__CST"]// 构建提示文本var suggestionText = `你是一个全能百科,用户想要在${city}旅游,给用户推荐一下当地的特色点及旅游景点`.replace(/"/g, "'");var model_value0 = {"from":"user","content":suggestionText}var model_value1 = {"from":"model","content":"正在生成中","thinkProcessContent":"您好","thinkProcessStatus":"thinking"}var model_value_list = [model_value0,model_value1];// modelCopy.xiaocao__message__CST = suggestionText;// 初始化Flowvar _flow = context.flow("xiaocao__ds");// 调用AI服务获取建议try { // 提示信息 // context.$message.info("信息分析中,正在生成建议。。。。。。"); // context.$model.ref("content").setData("获取推荐中..."); context.$model.ref("model_value").setData(model_value_list) const resp = await _flow.run({ input: suggestionText }); const reader = resp.body.getReader(); const decoder = new TextDecoder(); let buffer = ''; let msg = ''; while (true) { const { done, value } = await reader.read(); if (done) break; buffer += decoder.decode(value); const lines = buffer.split('\n'); // 保留最后一行(可能不完整) buffer = lines.pop() || ''; for (const line of lines) { if (!line.trim()) continue; try { const jsonStr = line.startsWith('data: ') ? line.substring(6) : line; if (jsonStr.trim() === '[DONE]') continue; const obj = JSON.parse(jsonStr); const newMsg = obj?.choices[0]?.delta?.content || ''; if (newMsg) msg += newMsg; // context.$model.ref("content").setData(msg); model_value1.content = msg; // model_value1.thinkProcessStatus = "complete"; context.$model.ref("model_value").setData([model_value0,model_value1]) } catch (err) { console.warn('解析JSON失败,保留到下一轮处理:', err.message); buffer = line + '\n' + buffer; } } } // 最终保存结果 modelCopy.xiaocao__content__CST = msg; context.$model.ref("message").setData(modelCopy); model_value1.thinkProcessStatus = "complete"; context.$model.ref("model_value").setData([model_value0,model_value1]) // 提交数据 const saveResult = await context.$model.ref("message").save(); if (saveResult.resCode == 0) { const recordId = saveResult.result[0]?.id; if (recordId) { // context.$page.loadStdPage('xiaocao__t_mass', "recordId=" + recordId); // // 成功消息 // context.$message.success('生成成功'); } }} catch (error) { console.error("AI服务调用失败:", error); // 可以添加错误处理逻辑,如显示错误信息}将对话列表拖入页面中,然后进行数据绑定。这里的绑定我写的model_value,这是一个自定义的数据类型,下面我截图了为什么定义这个类型和这个类型的结构,核心还是这个对话列表需要这样的数据结构所以才创建。 至些,我们整体 的就开发完了。看一下效果。dian我正在参加【案例共创】第7期 基于MaaS商用服务 + 华为开发者空间 - Astro 低代码开发平台构建低代码应用 cid:link_5  
  • [案例共创] 通过华为云Astro轻应用开发答题程序
    通过华为云Astro轻应用开发答题程序这是一个网络安全宣传的答题程序,可以更换试题,开发自己的固定试卷的答题程序,具有答题和排行榜的功能。下面将详细阐述如何从零开始,利用华为云Astro轻应用低代码平台开发一款功能完备的网络安全知识竞赛小程序。该程序旨在通过互动答题的形式,向用户普及网络安全知识。其核心功能包括:固定的题库答题、用户身份记录、成绩自动计算、以及动态实时更新的排行榜。通过本指南,开发者可以快速掌握关键页面的创建、数据结构的规划、前后端逻辑的连接,并最终打造出属于自己的定制化答题应用。排行榜参考了:https://support.huaweicloud.com/bestpractice-astrozero/astrozero_07_1009.html1、创建首页1.1同理创建相应的其他页面:1.2创建相应的数据结构:1.3在上面进行编辑,导入相应的模板内容:题目的数据库导入下载模板之后,将问题的字段写好后进行导入:点击确定进行相应的上传:2、首页设置:2.1 布局设置好了之后,将控件重命名。接着将按钮的点击事件先进行绑定,相应的输入框绑定输入的值。输入框绑定用户名:2.2生成模板对象username——通过数据库结构生成:2.2.1第一步:2.2.2第二步:2.2.3 第三步确认:生成后点击数据模型进行确定:2.3 开始答题按钮增加页面跳转:2.4同样在排行榜的按钮创建排行榜,注意相应的动作名称可以更改哦。注意点左上角保存哦,这个平台很差劲,很多时候不能修改;修改的暂存按左上角的保存有的时候会被其他锁住,导致状态不一致修改丢失,经常会出现丢失。3、答题页面答题页面的组件布局也是一样的,只能够单选题或者多选题,随机出题这种几乎实现不了,(考虑过根据题型进行单选多选判断,但是失败了,小程序的企业微信客服也不理人的,官方文档用处也没有,Gemini YYDS)3.1题目加载:因为题目固定,所以没有加载,就是相应的静态3.2提交按钮事件(标记未完成)提交按钮一样进行添加事件:这个需要添加相应的提交接口,先暂停,后面再绑定。3.3 设置相应的数据的绑定examData3.4 相应的题目和相应的数据结构绑定50个就不一一展示了4、提交页面这个抄一下官方的示例的,复制官方模板进行生成:4.1再次答题按钮设置跳转:4.2查看排行榜按钮:还可以设置每次答题的分数和用时,但是这个平台调试和bug太多了,舍弃~~、5、排行榜页面补充:这个参考如下:因为之前使用其他的列表不太好用都没有实现,最后的方案是自己相应的嵌套出来的,参考如下:组件导航->页面->容器->列表视图容器->表格容器->表格5.1首先设置相应的数据的绑定和跳转页面的内容:选中表格后进行相应的数据绑定:5.1.1模型设置为rankdata去绑定相应的排行信息。5.1.2第二步:设置相应的数据5.1.3第三步:下一步,然后确定就可以了。5.1.4距离美化还差一个排名,需要增加,后面给后端去计算:点击确定就成了这样了:这个rank有点突兀,改一下中文。就可以了。5.2返回首页增加点击事件:进入增加相应的跳转:现在基本的跳转已经实现了,现在开始相应的接口开发和业务的处理:6、进行接口的开发前置——脚本:6.1新建脚本submiexam:添加内容后保存后启用:TypeScript import * as context from 'context';import * as db from 'db';// [修正] 不再需要 'decimal' 模块,已将其移除// 声明此脚本将操作的对象@useObject(['secweek__questions__CST'])/** * 定义从前端页面接收的输入参数结构 (保持不变) */@action.object({ type: 'param' })export class Input {    @action.param({ type: 'String', required: true, label: 'question_1' }) question_1: string;    @action.param({ type: 'String', required: true, label: 'question_2' }) question_2: string;    @action.param({ type: 'String', required: true, label: 'question_3' }) question_3: string;    @action.param({ type: 'String', required: true, label: 'question_4' }) question_4: string;    @action.param({ type: 'String', required: true, label: 'question_5' }) question_5: string;    @action.param({ type: 'String', required: true, label: 'question_6' }) question_6: string;    @action.param({ type: 'String', required: true, label: 'question_7' }) question_7: string;    @action.param({ type: 'String', required: true, label: 'question_8' }) question_8: string;    @action.param({ type: 'String', required: true, label: 'question_9' }) question_9: string;    @action.param({ type: 'String', required: true, label: 'question_10' }) question_10: string;    @action.param({ type: 'String', required: true, label: 'question_11' }) question_11: string;    @action.param({ type: 'String', required: true, label: 'question_12' }) question_12: string;    @action.param({ type: 'String', required: true, label: 'question_13' }) question_13: string;    @action.param({ type: 'String', required: true, label: 'question_14' }) question_14: string;    @action.param({ type: 'String', required: true, label: 'question_15' }) question_15: string;    @action.param({ type: 'String', required: true, label: 'question_16' }) question_16: string;    @action.param({ type: 'String', required: true, label: 'question_17' }) question_17: string;    @action.param({ type: 'String', required: true, label: 'question_18' }) question_18: string;    @action.param({ type: 'String', required: true, label: 'question_19' }) question_19: string;    @action.param({ type: 'String', required: true, label: 'question_20' }) question_20: string;    @action.param({ type: 'String', required: true, label: 'question_21' }) question_21: string;    @action.param({ type: 'String', required: true, label: 'question_22' }) question_22: string;    @action.param({ type: 'String', required: true, label: 'question_23' }) question_23: string;    @action.param({ type: 'String', required: true, label: 'question_24' }) question_24: string;    @action.param({ type: 'String', required: true, label: 'question_25' }) question_25: string;    @action.param({ type: 'String', required: true, label: 'question_26' }) question_26: string;    @action.param({ type: 'String', required: true, label: 'question_27' }) question_27: string;    @action.param({ type: 'String', required: true, label: 'question_28' }) question_28: string;    @action.param({ type: 'String', required: true, label: 'question_29' }) question_29: string;    @action.param({ type: 'String', required: true, label: 'question_30' }) question_30: string;    @action.param({ type: 'String', required: true, label: 'question_31' }) question_31: string;    @action.param({ type: 'String', required: true, label: 'question_32' }) question_32: string;    @action.param({ type: 'String', required: true, label: 'question_33' }) question_33: string;    @action.param({ type: 'String', required: true, label: 'question_34' }) question_34: string;    @action.param({ type: 'String', required: true, label: 'question_35' }) question_35: string;    @action.param({ type: 'String', required: true, label: 'question_36' }) question_36: string;    @action.param({ type: 'String', required: true, label: 'question_37' }) question_37: string;    @action.param({ type: 'String', required: true, label: 'question_38' }) question_38: string;    @action.param({ type: 'String', required: true, label: 'question_39' }) question_39: string;    @action.param({ type: 'String', required: true, label: 'question_40' }) question_40: string;    @action.param({ type: 'String', required: true, label: 'question_41' }) question_41: string;    @action.param({ type: 'String', required: true, label: 'question_42' }) question_42: string;    @action.param({ type: 'String', required: true, label: 'question_43' }) question_43: string;    @action.param({ type: 'String', required: true, label: 'question_44' }) question_44: string;    @action.param({ type: 'String', required: true, label: 'question_45' }) question_45: string;    @action.param({ type: 'String', required: true, label: 'question_46' }) question_46: string;    @action.param({ type: 'String', required: true, label: 'question_47' }) question_47: string;    @action.param({ type: 'String', required: true, label: 'question_48' }) question_48: string;    @action.param({ type: 'String', required: true, label: 'question_49' }) question_49: string;    @action.param({ type: 'String', required: true, label: 'question_50' }) question_50: string;}/** * 定义成功时返回给前端的输出参数结构 */@action.object({ type: 'param' })export class Output {    @action.param({ type: 'String', required: true, label: 'id' })    id: string; // 成功创建的记录ID    @action.param({ type: 'String', required: true, label: 'message' })    message: string; // 成功的提示信息}/** * 主逻辑类 */@action.object({ type: 'method' })export class Main {    @action.method({ input: 'Input', output: 'Output', description: 'Submit Cyber Security Quiz Answers with Proactive Error Throwing' })    public run(input: Input): Output {        // --- 1. 前置校验 ---        console.log('开始执行提交答卷脚本...');        if (!input) {            throw new Error('[E1001] 请求参数无效:输入数据为空。');        }        const userId = context.getUserId();        const userName = context.getUserName();        if (!userId || !userName) {            throw new Error('[E1002] 用户身份验证失败:无法获取当前用户信息,请尝试重新登录。');        }        console.log(`校验通过,用户ID: ${userId}, 用户名: ${userName}`);        // --- 2. 业务逻辑:计算得分 ---        const correctAnswers = {            question_1: 'A', question_2: 'B', question_3: 'B', question_4: 'C', question_5: 'B',            question_6: 'B', question_7: 'C', question_8: 'B', question_9: 'B', question_10: 'C',            question_11: 'B', question_12: 'B', question_13: 'C', question_14: 'C', question_15: 'B',            question_16: 'B', question_17: 'C', question_18: 'C', question_19: 'C', question_20: 'C',            question_21: 'C', question_22: 'D', question_23: 'B', question_24: 'B', question_25: 'B',            question_26: 'D', question_27: 'B', question_28: 'B', question_29: 'C', question_30: 'C',            question_31: 'C', question_32: 'B', question_33: 'A', question_34: 'B', question_35: 'B',            question_36: 'B', question_37: 'C', question_38: 'B', question_39: 'B', question_40: 'C',            question_41: 'A', question_42: 'C', question_43: 'B', question_44: 'B', question_45: 'A',            question_46: 'B', question_47: 'B', question_48: 'C', question_49: 'B', question_50: 'B'        };        let score = 0;        for (let i = 1; i <= 50; i++) {            const questionKey = `question_${i}` as keyof Input;            const correctAnswerKey = `question_${i}` as keyof typeof correctAnswers;            if (input[questionKey] === correctAnswers[correctAnswerKey]) {                score += 2;            }        }        console.log(`分数计算完成,总得分: ${score}`);        // --- 3. 数据库交互 ---        const _object = db.object('secweek__questions__CST');        // // 3.1 清理历史记录        // try {        //     const _condition = { conjunction: 'AND', conditions: [{ field: 'secweek__userid__CST', operator: 'eq', value: userId }] };        //     const existingRecords = _object.queryByCondition(_condition);        //     if (existingRecords && existingRecords.length > 0) {        //         console.log(`找到 ${existingRecords.length} 条该用户的历史记录,准备删除...`);        //         existingRecords.forEach(record => {        //             _object.deleteById(record.id);        //         });        //         console.log('历史记录删除完毕。');        //     }        // } catch (e) {        //     console.error('数据库错误:查询或删除历史记录时失败。', e);        //     throw new Error(`[E2001] 系统繁忙:清理历史答卷时发生错误,请稍后重试。`);        // }        // 3.2 准备新记录        const quizRecord: { [key: string]: any } = {            name: userName,            secweek__userid__CST: userId,            // [修正] 直接传递 Number 类型的 score 变量            secweek__score__CST: score        };        for (let i = 1; i <= 50; i++) {            quizRecord[`secweek__question_${i}__CST`] = input[`question_${i}` as keyof Input];        }        // 3.3 插入新记录        let newRecordId: string;        try {            console.log('准备向数据库插入新记录...');            newRecordId = _object.insert(quizRecord);            console.log(`新记录插入成功,记录ID: ${newRecordId}`);        } catch (e) {            console.error('数据库错误:插入新记录时失败。', e);            throw new Error(`[E2002] 提交失败:保存您的答卷时系统发生错误,请稍后重试。`);        }        if (!newRecordId) {            console.error('逻辑错误:数据库insert操作未返回新记录ID。');            throw new Error('[E2003] 严重错误:数据保存后未能获取确认ID,请联系管理员核实。');        }        // --- 4. 成功返回 ---        console.log('脚本所有步骤执行成功,准备返回响应。');        const out = new Output();        out.id = newRecordId;        out.message = '答卷提交成功!';        return out;    }} 6.2脚本继续增加获取排行榜信息:一样增加代码保存后运行:TypeScriptimport * as context from 'context';import * as db from 'db';// 声明此脚本将操作的对象@useObject(['secweek__questions__CST'])// --- 平台可见的输入/输出定义 ---@action.object({ type: 'param' })export class Input {    @action.param({ type: 'Number', required: false, label: 'Top N' })    topN: number;}@action.object({ type: 'param' })export class Output {    @action.param({ type: 'String', required: true, label: '结果JSON字符串' })    result: string;}// --- 内部使用的数据结构 ---class RankEntry {    rank: number;    name: string;    score: number;    submissionTime: string;}class LeaderboardResult {    topRanks: RankEntry[];    currentUser?: RankEntry;}// --- 主逻辑类 ---@action.object({ type: 'method' })export class Main {    /**     * 安全地格式化日期字符串,处理无效或空值。     * (您的日期格式化函数保持不变)     */    private formatDate(dateInput: any): string {        if (!dateInput) {            return 'N/A';        }        try {            const originalDate = new Date(dateInput);            if (isNaN(originalDate.getTime())) {                return 'Invalid Date';            }            const CST_OFFSET = 8 * 60 * 60 * 1000;            const cstDate = new Date(originalDate.getTime() + CST_OFFSET);            const year = cstDate.getUTCFullYear();            const month = String(cstDate.getUTCMonth() + 1).padStart(2, '0');            const day = String(cstDate.getUTCDate()).padStart(2, '0');            const hours = String(cstDate.getUTCHours()).padStart(2, '0');            const minutes = String(cstDate.getUTCMinutes()).padStart(2, '0');            const seconds = String(cstDate.getUTCSeconds()).padStart(2, '0');            return `${year}/${month}/${day} ${hours}:${minutes}:${seconds}`;        } catch (e) {            return 'Date Format Error';        }    }    @action.method({ input: 'Input', output: 'Output', description: '获取排行榜,每个用户只显示最高分,并包含当前用户的排名信息' })    public run(input: Input): Output {        const out = new Output();        const finalResult: LeaderboardResult = { topRanks: [], currentUser: undefined };        try {            const topN = input.topN || 20;            const currentUserId = context.getUserId();            const _object = db.object('secweek__questions__CST');            // --- 步骤 1: 一次性获取所有有效记录,并按排名规则排序 ---            // 这是整个优化的基础:先将所有记录按最终排名规则排序。            const allRecords = _object.queryByCondition({                conjunction: 'AND',                conditions: [                    { field: 'secweek__score__CST', operator: 'isnotnull' }                ],                sort: [                    { field: 'secweek__score__CST', order: 'desc' }, // 分数从高到低                    { field: 'createdDate', order: 'asc' }       // 分数相同,时间从早到晚                ]            });            // --- 步骤 2: 遍历排序后的记录,筛选出每个用户的最高分记录 ---            // `uniqueUserRecords` 将是最终的、无重复用户的排名列表。            const uniqueUserRecords: any[] = [];            const processedUserIds = new Set<string>(); // 用于跟踪已处理过的用户            if (allRecords && allRecords.length > 0) {                for (const record of allRecords) {                    const userId = record.secweek__userid__CST;                    // 如果用户ID有效,并且我们还没有处理过这个用户                    if (userId && !processedUserIds.has(userId)) {                        // 因为 `allRecords` 已经排序,所以我们遇到的第一个该用户的记录就是他的最佳记录。                        uniqueUserRecords.push(record);                        processedUserIds.add(userId); // 标记该用户已处理                    }                }            }            // --- 步骤 3: 从 `uniqueUserRecords` 构建 Top N 排行榜 ---            // `uniqueUserRecords` 本身就是完整的排行榜,我们只需截取前 N 名。            finalResult.topRanks = uniqueUserRecords                .slice(0, topN) // 获取前 N 条记录                .map((record, index) => ({                    rank: index + 1, // 排名就是索引 + 1                    name: record.name || '匿名用户',                    score: record.secweek__score__CST,                    submissionTime: this.formatDate(record.createdDate)                }));            // --- 步骤 4: 从 `uniqueUserRecords` 中查找当前用户并确定其排名 ---            if (currentUserId) {                // 使用 findIndex 在已去重的排名列表中查找当前用户的位置。                // 这个索引 + 1 就是他的真实排名。                const currentUserRankIndex = uniqueUserRecords.findIndex(                    record => record.secweek__userid__CST === currentUserId                );                // 如果找到了(即 index 不是 -1)                if (currentUserRankIndex !== -1) {                    const myRecord = uniqueUserRecords[currentUserRankIndex];                    finalResult.currentUser = {                        rank: currentUserRankIndex + 1, // 排名                        name: myRecord.name || '匿名用户',                        score: myRecord.secweek__score__CST,                        submissionTime: this.formatDate(myRecord.createdDate)                    };                }            }            out.result = JSON.stringify(finalResult);            return out;        } catch (error) {            const errorMessage = `生成排行榜时出错: ${error.message || '未知错误'}`;            console.error(errorMessage, { stack: error.stack });            throw new Error(`生成排行榜失败: ${error.message || '未知错误'}`);        }    }}6.3 绑定前创建相应的接口的用户的业务凭证:新建用户:6.4设置提交结果接口6.4.1提交结果接口:6.4.2添加相应的业务凭证:6.5设置加载排行榜接口6.5.1加载排行榜接口6.5.2添加相应的业务凭证:7、数据模型绑定——回到答题页面7.1绑定相应的答题数据内容:模型名设置为submit,使用服务生成:选择提交的脚本继续下一步进行生成:增加映射的类型方法,并完成。7.2接着绑定相应的数据内容到表单:7.3提交按钮事件(标记完成)参考代码如下:JavaScript$model.ref('examData').run().then(() => {// 只有在平台的隐式校验通过,且后端脚本成功执行后,才会进入这里context.$message.success("提交成功", 3);setTimeout(function () {context.$page.loadStdPage("secweek__submit", "page=secweek__exam");}, 1000);}).catch((error) => {// 如果用户有未填项,或后端脚本返回错误,都会进入这里console.error("提交失败:", error);context.$message.error('提交失败: ' + error.resMsg, 5);});8、数据模型绑定——排行榜页面8.1排行榜页面的接口加载数据:增加相应的事件:参考代码如下:JavaScriptconsole.log('页面加载事件已触发,准备执行排行榜代码...');// --- 配置区 ---const SERVICE_API_NAME = 'secweek__getranklist';const DATA_MODEL_NAME = 'rankdata';console.log('服务API Name:', SERVICE_API_NAME, '绑定的数据模型名:', DATA_MODEL_NAME);// --- 逻辑执行区 ---try {context.script(SERVICE_API_NAME).run({topN: 50}).then(function (response) {console.log('后端脚本成功返回响应:', response);if (response && response.result && response.result.value && typeof response.result.value.result === 'string') {try {const leaderboardJsonString = response.result.value.result;const leaderboardData = JSON.parse(leaderboardJsonString);let finalRankData = leaderboardData.topRanks || [];const currentUser = leaderboardData.currentUser;if (currentUser && currentUser.name) {const isCurrentUserInTopRanks = finalRankData.some(user => user.name === currentUser.name);if (!isCurrentUserInTopRanks) {finalRankData.push(currentUser);}}finalRankData.sort((a, b) => a.rank - b.rank);// [核心修复] 在将数据设置到模型前,转换数据对象的键名以匹配表格的列配置。const tableFormattedData = finalRankData.map(function(item) {return {'rank': item.rank,'name': item.name,'secweek__score__CST': item.score,'createdDate': item.submissionTime};});const dataModel = $model.ref(DATA_MODEL_NAME);if (dataModel) {try {dataModel.setData(tableFormattedData);console.log(`成功转换数据键名并调用 setData 方法,提交了 ${tableFormattedData.length} 条数据。UI应该会更新。`);} catch (e) {console.error(`向数据模型 ${DATA_MODEL_NAME} 设置数据时出错:`, e);context.$message.error('更新表格数据时发生内部错误。');}} else {console.error(`错误:在页面上找不到名为 '${DATA_MODEL_NAME}' 的数据模型。`);context.$message.error(`页面上缺少关键数据模型: ${DATA_MODEL_NAME}`);}} catch (parseError) {console.error('解析后端返回的JSON字符串时失败:', parseError);context.$message.error('解析排行榜数据失败。');}} else {console.error('响应格式不正确,未能从 response.result.value.result 获取到JSON字符串。', response);context.$message.error('加载排行榜失败:响应格式不正确。');}}).catch(function (error) {console.error("调用后端脚本时发生错误:", error);context.$message.error('加载排行榜失败: ' + (error.resMsg || '未知错误'));});} catch (e) {console.error('在调用 context.script() 时发生同步错误:', e);context.$message.error('调用后端服务API时发生错误: ' + e.message);}最后生成安装包:Plain Text一个网络安全宣传的答题程序,可以更换试题,开发自己的固定试卷。到这里就结束了,我们来演示一下吧。
  • [案例共创] 【案例共创】基于MaaS结合开发者空间Astro低代码平台开发高考大学择校推荐系统
    案例介绍2025年高考报名人数突破1300万,大部分学生在院校档次与专业兴趣的取舍焦虑,全国3005所高校、792个本科专业构成的选择矩阵远超个体认知负荷本案例开发一个大学择校推荐系统,根据学生成绩,专业兴趣,地域爱好等,基于人工智能大模型DeepSeek生成推荐的大学院校,帮助万千学子提供择校参考 案例内容一、概述1. 案例介绍本案例开发一个大学择校推荐系统,根据学生成绩,专业兴趣,地域爱好等,基于人工智能大模型DeepSeek生成推荐的大学院校通过实际操作,了解如何利用Astro低代码平台开发应用。在这个过程中,学习从模型集成、界面操作、页面布置到逻辑实现以及应用打包一系列关键步骤,从而掌握Astro低代码平台的基本使用方法及于大模型的结合,体验其在应用开发中的优势。开发者空间Astro低代码开发平台通过平台提供的界面、逻辑、对象等可视化编排工具,以“拖、拉、拽”的方式来快速构建应用,从而实现所见即所得的应用开发构建体验。华为开发者空间,是为全球开发者打造的专属开发者空间,致力于为每位开发者提供一台云主机、一套开发工具和云上存储空间,汇聚昇腾、鸿蒙、鲲鹏、GaussDB、欧拉等华为各项根技术的开发工具资源,并提供配套案例指导开发者 从开发编码到应用调测,基于华为根技术生态高效便捷的知识学习、技术体验、应用创新。ModelArts Studio(MaaS)平台:是华为云推出的一款大模型即服务平台,可以一站式的对业界主流开源大模型进行部署托管,同时开放大模型API服务,可以结合业界主流Agent开发框架,轻松构建AI Agent应用。2. 适用对象企业个人开发者高校学生3. 案例时间本案例总时长预计90分钟。4. 案例流程说明:领取华为开发者空间,登录华为开发者空间-低代码应用开发平台;新建低代码应用,进入Astro轻应用服务控制台主页,开发应用;5. 资源总览本案例预计花费0元。资源名称规格单价(元)时长(分钟)MaaS 平台商用模型DeepSeek-R1 轻量体验包(¥7.00)/ DeepSeek-V3 轻量体验包(¥3.50)领券免费90华为开发者空间 - 低代码应用开发平台系统标配免费90二、案例准备1、设计对象字段低代码平台中的对象(也可以称为Object)相当于传统方式开发业务系统时,数据库中创建的一个表。每个对象对应一张数据库表,用于保存业务系统需要的配置数据和业务数据。本用例会使用到对象来存储数据,建议提前设计好对象字段,避免后续手忙脚乱字段名称唯一标识字段类型字段说明大学择校推荐tuijian文本区用于返回推荐结果高考省份shengfen文本高考省份和文理科高考分数fenshu数字高考的分数兴趣与能力xingqu文本自身的兴趣爱好或者有哪方面的能力学校性质 xingzhi文本想选择的学校性质如本科专科性别xingbie文本性别,更好的结合性别来推荐学校希望就读城市或者地域chengshi文本希望就读的城市或地域 2、开通ModelArts Studio(MaaS)商用百万Token活动连接:每周畅领100万商用级Tokens!基于CloudMatrix384超节点,Token时延低、TPM/RPM速率高,助您开发商用级AI应用!商用百万Token代金券免费领取链接(可每周领取):DeepSeek-R1/V3-64K百万tokens代金券:cid:link_22.1、大模型领取:切换到开发者空间首页,或者点击上面连接,参与活动“百万商用服务tokens免费领!”活动,按照使用说明进行服务开通:活动页面:2.2、开通完成后,进行大模型的接入:ModelArts控制台:ModelArts - Console模型部署页:部署页面,点击调用按钮,进入调用页面,这里我们提前保存好Api地址和模型名称,点击API调用说明:2.3、创建apikey点击前往API Key管理创建apikey,点击新建创建apikey注意!!创建好API Key之后,点击后面的复制按钮,妥善保存,若未复制保存,后续无法重新复制获取。 三、华为开发者空间-低代码应用开发平台开发应用1. 登录华为开发者空间-低代码应用开发平台华为开发者空间-低代码应用开发平台是华为云推出的一款可视化应用开发平台,旨在通过"拖拽式"组件和模板化设计,降低开发门槛,提升企业数字化应用构建效率。平台主要特点包括:可视化开发:通过图形化界面和预置组件,无需编写复杂代码即可快速搭建应用;全场景支持:覆盖Web、移动端、大屏等多终端应用开发;高效集成:内置连接器可快速对接华为云及其他主流企业系统;智能辅助:提供AI辅助开发能力,如智能表单生成、流程自动化等;企业级能力:具备权限管理、数据安全、高可用等企业所需特性。Astro平台特别适合业务人员与开发者协同创新,能大幅缩短应用交付周期,典型适用于OA审批、数据看板、轻量级业务系统等场景。登录华为开发者空间,在左侧菜单列表选择华为开发者空间 -> 开发平台 -> Astro 低代码开发,进入华为开发者空间-低代码应用开发平台。2. 创建低代码应用2.1、华为开发者空间-低代码应用开发平台页面点击新建低代码应用,在弹出的新建低代码应用对话框中,选择标准应用,点击确定按钮。 注:命名空间为租户数据唯一标识,为免重复,首次创建或使用工程时需定义命名空间。请务必慎重,一旦定义,不可修改,推荐使用公司前缀。本案例中使用xiaowuyun作为命名空间。2.2、在右侧弹出的新建空白应用配置页签中,配置应用名称和标签均为university。2.3、点击右下角确认按钮,平台会自动打开一个新的页面:Astro轻应用服务控制台。注:在点击确认后,在Astro轻应用管理页会同时新增一条刚才创建的名称为xxxx__university的应用,点击编辑同样可以进入Astro轻应用服务控制台。 3. 集成连接器大模型将外部接口集成zero并编写编排流程:在应用中,点击左侧集成 - 连接器实例 - 大模型 - MaaS云平台:点击右上角加号,创建自定义连接器,输入标“标签”(这里为ds,可自定义)、“名称”(这里填入MaaS,可自定义)、“模型名称”(前步保存的模型名称)和“APIKey”(前步保存的apiKey);点击保存:测试连通性,点击“测试”,在弹出框中输入测试内容后,点击测试等待返回结果,正常返回说明添加成功:4. 添加对象和全局结构体4.1、创建大学推荐记录对象进入大学推荐系统设计器界面,在左侧导航栏中,选择“数据”;单击对象后的“新建对象”图标,进入创建新对象页面;设置对象基本信息:填写对象名称为“大学择校推荐系统”,唯一标识为“university”,单击“确定”按钮。4.2、创建字段4.2.1、 单击对象中的编辑图标,进入对象详情页:4.2.2 点击“添加”,添加字段:显示名称“高考省份”,唯一标识:“shengfen”,点击字段类型,选择“文本”类型,点击“确定”:4.2.3 、相同的操作,添加显示名称“大学择校推荐 ”,唯一标识“tuijian”,类型“文本区”:参考如让步骤,把案例准备设计的字段全部创建,添加完如下图字段名称唯一标识字段类型字段说明大学择校推荐tuijian文本区用于返回推荐结果高考省份shengfen文本高考省份和文理科高考分数fenshu数字高考的分数兴趣与能力xingqu文本自身的兴趣爱好或者有哪方面的能力学校性质 xingzhi文本想选择的学校性质如本科专科性别xingbie文本性别,更好的结合性别来推荐学校希望就读城市或者地域chengshi文本希望就读的城市或地域4.3、创建全局结构体:4.3.1、 点击左侧菜单栏数据,选择结构体新增,输入名称和唯一标识(可自定义,这里选择message为例),创建结构体4.3.2、创建完成后点击结构,选择结构体编辑按钮,添加的字段新增role和content,保存:5. 开发推荐系统页面5.1、创建系统页面在新版应用设计器的“界面”中,单击页面后的添加图标,设置页面标签为“大学择校推荐”、名称为“university”,单击“添加”,即可创建一个标准页面:5.2、添加并设置表单从左侧“组件”区域,将“表单”组件拖拽到页面中间,元数据表单配置向导点击“取消”:设置表单属性:如设置布局为宽“800px”和高“1024px”、居中对齐,设置字体大小为“16px”、行高为“23”等。(可自定义)设置数据绑定,点击数据绑定后的“设置”图标,点击“新增模型”:设置模型名称为“formData”,来源选择“对象”,单击“下一步””选择对象”下拉框选择“大学择校推荐系统(xxx__university__CST)”,“选择字段”勾选全部字段,单击“下一步”:单击“确定”:勾选“formData”,单击“确定”:注:在弹出框中,选择“只绑定模型”5.3、添加大标题。从左侧“组件”区域,将“标题”组件拖拽到表单中间:设置标题属性:点击标题,在右侧菜单栏点击基本属性,设置标题内容为“大学择校推荐系统”:点击下方字体,如设置字体颜色为“#147AEC”、字体大小为“28px”、上下间距为“50”、位置为“center”。(可自定义)当前配置会生成对应的css样式,可以查看高级设置(无具体操作,供查看学习使用)。5.4、添加图片5.4.1、从左侧“组件”区域,将“图片”组件拖拽到标题下方:5.4.2、设置图片属性:单击“图片地址”后的“选择图片”图标,在选择图片界面,选中一张图片,单击“确定”,或者单击“上传图片”按钮,从本地电脑中选择一张图片上传即可:5.4.3 设置图片宽度为“100%”注:选择或上传图片,支持上传JPG、JPEG、PNG和GIF格式的图片,图片大小不超过1MB5.5、设置小标题参考步骤5.3,设置小标题,设置标题内容为“帮你解决高考志愿填报的难题,填写你的信息,我会尽力为你提供帮助,让我们一起为你的未来规划加油吧!”(可自定义),标题类型为“Hending2”;5.6、添加采集项15.6.1、在标准页面设计界面,从“基本组件 > 表单”中,拖拽“输入框”组件至表单工作区域:点击基本属性,设置标签内容输入“1、高考省份”,在表单校验中,打开必填开关,设置必填错误信息为“请输入你的高考省份”5.6.2、设置输入框属性:点击输入框,点击右侧菜单栏“数据绑定”中的“设置”图标,勾选“xxxx__shengfen__CST”,单击“确定”:注意:数据绑定时要跟自己设计的对象字段名称一一对应5.7、添加采集项2同上:从“基本组件 > 表单”中,拖拽“输入框”组件至表单工作区域:点击基本属性,设置标签内容输入“2、高考分数”,在表单校验中,打开必填开关,设置必填错误信息为“请输入你的高考分数”点击数据绑定中的设置图标,勾选“xxx__fenshu__CST”,单击“确定”。 5.8、添加采集项3同上:从“基本组件 > 表单”中,拖拽“输入框”组件至表单工作区域:点击基本属性,设置标签内容输入“3、兴趣能力”,点击数据绑定中的设置图标,勾选“xxx__xingqu_CST”,单击“确定5.9、添加采集项4同上:从“基本组件 > 表单”中,拖拽“复选按钮”组件至表单工作区域:点击基本属性,设置标签内容输入“4、学校性质(可选多个)”,设置选项如图,点击数据绑定中的设置图标,勾选“xxx__xingzhi_CST”,单击“确定5.10、添加采集项5在标准页面设计界面,从“基本组件 - 表单”中,拖拽“单选按钮”组件至表单工作区域。设置单选按钮属性。设置标签为“5,性别”,选项为“男 - 男”和“女 - 女”,点击数据绑定中的设置图标,勾选“xxx__xingbie_CST”,单击“确定5.11、添加采集项6同上:从“基本组件 > 表单”中,拖拽“输入框”组件至表单工作区域:点击基本属性,设置标签内容输入“6、希望就读城市或地域”,点击数据绑定中的设置图标,勾选“xxx__chengshi_CST”,单击“确定5.12、添加容器在标准页面设计界面,从“基本组件 > 布局”中,拖拽“容器”组件至表单工作区域。5.13、添加提交按钮:在标准页面设计界面,从“基本组件 > 基本”中,拖拽“按钮”组件至容器区域:5.13.1设置按钮属性:设置显示名称为“提交”,大小选择“默认”。5.13.2、设置按钮事件:首先切换到“事件”标签,单击加号,在“添加动作 > 自定义动作(名称可自定义) > 动作名称”代码区域中,输入代码,单击“创建”。粘贴代码后点击保存代码部分如下:其中代码中formData在步骤《5.2、添加并设置表单:》中创建的对象模型名称xiaowuyun_ds是步骤《3. 集成连接器大模型》绑定的MaaS大模型的实例连接器定义的标签,xiaowuyun__xxx_xxx的字段名前面的部分需要更改为用户自己的命名空间。其他对应修改,可参考如下完整代码####注释的部分// 表单校验var _form = context.$component.form;var validFlag = _form.formValidateUnPromise();if (!validFlag) return false;// 序列化表单数据var model = context.$model.ref("formData").getData();var modelCopy = JSON.parse(JSON.stringify(model));// 处理非字符串字段Object.keys(modelCopy).forEach(item => { if (modelCopy[item] && typeof modelCopy[item] !== "string") { modelCopy[item] = JSON.stringify(modelCopy[item]); }});// 提取问题字段值var questionCodes = [];const arr = ['shengfen', 'fenshu', 'xingqu','xingzhi', 'xingbie', 'chengshi']; ####修改为自己定义的字段名称for (let i = 0; i < arr.length; i++) { var fieldName = "xiaowuyun__" + arr[i] + "__CST"; #####修改为自己的命名空间 questionCodes.push(modelCopy[fieldName] || "");}// 构建提示文本var suggestionText = `你是一个专业的大学推荐助手,该学生高考省份为 ${questionCodes[0]},高考分数是 ${questionCodes[1]}分,兴趣与能力是 ${questionCodes[2]},希望上的大学学校性质为:${questionCodes[3]},性别是 ${questionCodes[4]} 生,希望就读城市或者地域为 :${questionCodes[5]}。请根据以上信息给出该学生进行大学推荐,推荐内容包含大学的介绍和特色。`.replace(/"/g, "'");// 初始化Flowvar _flow = context.flow("xiaowuyun__ds"); #####修改为自己创建大模型集成器的名称// 调用AI服务获取建议try { // 提示信息 context.$message.info("信息分析中,正在生成建议。。。。。。"); const resp = await _flow.run({ input: suggestionText }); const reader = resp.body.getReader(); const decoder = new TextDecoder(); let buffer = ''; let msg = ''; while (true) { const { done, value } = await reader.read(); if (done) break; buffer += decoder.decode(value); const lines = buffer.split('\n'); // 保留最后一行(可能不完整) buffer = lines.pop() || ''; for (const line of lines) { if (!line.trim()) continue; try { const jsonStr = line.startsWith('data: ') ? line.substring(6) : line; if (jsonStr.trim() === '[DONE]') continue; const obj = JSON.parse(jsonStr); const newMsg = obj?.choices[0]?.delta?.content || ''; if (newMsg) msg += newMsg; } catch (err) { console.warn('解析JSON失败,保留到下一轮处理:', err.message); buffer = line + '\n' + buffer; } } } // 最终保存结果 modelCopy.xiaowuyun__tuijian__CST = msg; #### ####修改为自己命名空间和定义的字段名称 context.$model.ref("formData").setData(modelCopy); // 提交数据 const saveResult = await context.$model.ref("formData").save(); if (saveResult.resCode == 0) { const recordId = saveResult.result[0]?.id; if (recordId) { context.$page.loadStdPage('xiaowuyun__suggestion', "recordId=" + recordId); // 成功消息 context.$message.success('生成成功'); } }} catch (error) { console.error("AI服务调用失败:", error); // 可以添加错误处理逻辑,如显示错误信息}6、添加逻辑编排6.1、添加服务编排点击左侧逻辑 - 编排 - 新建编排,名称填ds,模板类型默认,点击添加:6.2、新增变量点击右侧“全局上下文”,新增变量,创建变量 - input,类型为文本:创建变量 - output,类型为任意:6.3、新增对象变量创建对象变量 - messages,使用步骤3中创建的全局结构体,选择数组:6.4、添加配置开始图元点击画布上的开始图元,点击参数,将刚才创建的变量分别拖进入参和出参:6.5、添加配置赋值图元选择左侧赋值图元,拖入界面,并将开始图元与赋值图元连接:选择赋值图元,点击赋值按钮,将变量赋值,第一行为刚才的全局结构体变量名称“messages[0].role”,我们将值设置为"user"(要用英文双引号),第二行为全局结构体变量名称“messages[0].content”,变量值可直接将变量中的input拖入:6.6、添加配置连接器图元左侧选择连接器 - 自定义连接器,选择前面步骤我们创建的连接器。将其拖拽进页面,并将赋值图元与连接图元连接:点击连接器图元,点击基本信息,选中步骤《3. 集成连接器大模型》创建的大模型连接器:选择连接器按钮,将连接器的入参message为对象变量message拖拽入,输出参数result为变量output拖拽:注意:此处可以多试几次,动作有时候显示不出来6.7、保存测试编排点击保存,启用,运行测试:输入参数{"input":"我要上大学"},测试看是否成功,参数内容可以自定义,最好简单一些防止运行时间过久:7. 开发结果推荐页面7.1、添加页面点击导航栏界面,选择+号新建页面:输入标签"推荐"和名称"suggestion",点击添加:7.2、设置表单仿照步骤《5.2、添加并设置表单》界面格式,进行页面设置,从左侧组件栏将表单组件拖拽至页面,元数据表单配置向导点击取消,属性设置布局:宽800px,高1024px,居中。(设置可根据自己需要自定义):7.3、数据绑定点击属性 - 数据绑定 - 新增模型:按前述步骤设置模型名称为"form0",选择来源为对象:点击下一步,选择"大学择校推荐系统"并勾选所有字段:点击下一步,点击确定:选择刚创建好的模型,点击确定,选择只绑定模型:7.4、添加图片参考步骤《5.4、添加图片》,添加图片;7.5、添加多行输入框在标准页面设计界面,从“基本组件 - 表单”中,拖拽“多行输入框”组件至表单工作区域,点击数据绑定中的设置图标,勾选“XXX__suggestion__CS”,单击“确定标签 填入 根据您提供的信息,有如下推荐,预祝你选上心仪的大学;高度 - 自适应高度,其余参考下图;点击页面,创建自定义脚本,写入以下代码点击保存其中“xiaowuyun_xx_xx”类的字段需更换为自身的命名空间:修改为自己创建的命名空间和对象名称,对象名称为步骤《4.1、创建大学推荐记录对象》创建的对象名称 var _object = context.object('xiaowuyun__university__CST');  完整代码如下:// json化方法function parseJSON(str) { var flag = false; try { JSON.parse(str); flag = true } catch (err) { flag = false; } return flag;}var recordId = context.$page.params.recordId;if (!recordId) return;try { // 获取Object对象 var _object = context.object('xiaowuyun__university__CST'); ####修改为自己创建的命名空间和对象名称 // 查询满足条件数据 var _condition = { conjunction: 'AND', conditions: [{ field: 'id', operator: 'eq', value: recordId }] }; const res = await _object.query(_condition); if (res.resCode !== '0' || !res.result || res.result.length === 0) return; const data = res.result[0]; // 解析JSON字符串字段 Object.keys(data).forEach(item => { if (data[item] && parseJSON(data[item])) { try { const parsed = JSON.parse(data[item]); data[item] = parsed; } catch (e) { // 不是有效JSON,保持原值 } } }); $model.ref("form0").setData(data);} catch (err) { console.error("数据查询或处理失败:", err);}8. 页面效果测试预览填报界面,进行功能调试、测试验证:点击页面左上角的预览图标如遇异常可以在数据-对象-对应对象数据里看到采集到的数据点击预览图标后会跳转大学推荐系统应用,然后填写大学推荐应用参数;提交完成时后跳转大学推荐页面; 至此案例结束,案例整体步骤比较多,后续各种调用其实都是根据定义名称来的,一定要先梳理好对象的命名规划,还有大模型、对象名称等要制定好,避免后续名字乱不好调用我正在参加【案例共创】第7期 基于MaaS商用服务 + 华为开发者空间 - Astro 低代码开发平台构建低代码应用 cid:link_3
  • [热门活动] 【热门活动】 PaaS生态夏日嘉年华来啦,登录即送精美好礼,限时福利别错过!
    夏日炎炎,暑气正盛PaaS生态夏日嘉年华带着满满的清爽和诚意来啦登录任意两个以上开发平台,即可获得抽奖机会1次,完成四个额外获得抽奖机会1次!无论是被高温困住脚步的你,还是在空调房里想找点乐子的你,这场夏日限定狂欢都能让你甩掉燥热,收获一整个夏天的好心情! 一、活动时间2025年7月28日-7月31日二、活动流程登录2个及以上平台 → 首页截图 → 发给活动助手 → 参与抽奖三、活动方式​第1步:活动期间,登录PaaS生态大家族2个及以上产品的用户,凭登录截图联系活动助手,即可参与抽奖活动(注意:截图需包含华为云账号)。①产品一:CodeArts华为云软件开发生产线CodeArts是一站式、全流程、安全可信的云原生DevSecOps平台,覆盖需求、开发、测试、部署、运维等软件交付全生命周期环节,为开发者打造全云化研发体验。登录网址:cid:link_3,②产品二:CodeArts IDE华为云CodeArts IDE Online是轻量级WebIDE,通过浏览器即可实现环境快速获取和环境访问,完成编码、构建、调试、运行、访问代码仓库和命令执行等工作,支持第三方业务集成,内置插件市场支持插件扩展。登录网址:cid:link_2③产品三:Astro ZeroAstro 低代码平台是华为云自主创新的全场景低代码平台,其中的Astro轻应用,通过简单拖拽配置完成应用搭建,轻松构建专业级应用,创新随心所欲,敏捷超乎想象,为企业提供低门槛、高效率的数字化业务应用生产新模式。登录网址:cid:link_1,④产品四:FunctionGraphFunctionGraph是基于事件驱动的函数托管的计算服务,使用FunctionGraph函数,只需编写业务函数代码并设置运行的条件,无需配置和管理服务器等基础设施,函数以弹性、免运维、高可靠的方式运行,助力开发者快速上线各类应用。登录网址:cid:link_0 第2步:添加小助手微信号,将所有的首页截图发给其中一位工作人员即可。         第3步:经过小助手确认有效后,即发送链接进行抽奖。登录任意两大开发平台,即可获得抽奖机会1次;完成四大开发平台登录并截图,额外获得1次抽奖机会;当用户获得 2 次抽奖机会且两次抽奖均获奖时,可从两次抽中的礼品中选择其一,另一未选择的礼品自动失效;若两次抽奖中仅有一次获奖,则获得该次抽中的礼品;若两次均未获奖,则无礼品。四、奖品展示华为智能跳绳 8个云宝公仔 50个便携茶具 10个U型枕 6个数据线 30个马克杯 14个*奖品已实物为准,如遇缺货将替换同等价值礼品。五、活动须知请确保您的用户信息填写准确无误,以便我们及时为您送上精美奖品。请确保截图右上角华为云用户名与获奖信息保持一致,即截图、获奖信息与华为云账号保持一致视为一次有效抽奖,否则不予奖品发放。奖品将在活动结束后15个工作日内发放,如遇缺货将会替换同等价值奖品。如有任何疑问,欢迎随时联系我们的小助手。本活动最终解释权归PaaS生态夏日嘉年华活动所有。特别注意:用户参与活动产品截图中的华为云账号需与参与抽奖的华为云账号一致,否则获奖信息无效。
  • [技术干货] 基于华为开发者空间Astro低代码应用平台,构建Deepseek智能助手界面
    📰 案例概览🚀 背景与简介华为开发者空间是为全球开发者打造的专属云上成长空间,深度整合昇腾AI、鸿蒙、鲲鹏等华为根技术。开发者空间在HDC2025上迎来全面升级,新增AI原生应用引擎、AI Notebook、鸿蒙云手机、FunctionGraph云函数、Astro低代码等核心能力,并在算力、模型、平台、应用层实现全方位优化,助力开发者高效完成从编码到调测的全流程,打造智能AI应用开发新体验。智能助手模板是基于AI大模型定制化的智能助手解决方案,旨在为企业和开发者提供灵活、高效、智能的交互体验。通过对接先进的AI大模型,能够实现多场景、多领域的智能化应用,满足不同业务的需求,助力企业实现数字化转型和效率提升。随着AI技术的不断进步,智能助手模板将进一步扩展应用场景,为企业创造更大的价值。案例优势:智能助手模板支持无缝对接主流AI大模型,通过灵活的模型调用和优化机制,实现多场景、多领域的智能适配,满足不同业务需求。智能助手模板提供高度可定制化的前端配置能力,支持根据具体场景需求,灵活调整交互逻辑、功能模块及品牌视觉风格,打造贴合用户需求的智能化解决方案。🎯  本案例将通过华为开发者空间-低代码应用开发平台对接AI开发平台ModelArts,并以其中的DeepSeek-V3-32K服务模型为例,实现智能助手对话界面的搭建及后端功能开发。🥏 案例流程🕹️ 流程说明:领取华为开发者空间,登录华为开发者空间-低代码应用开发平台,新建低代码应用工程,进入Astro轻应用服务控制台主页,开发应用。登录ModelArts平台,领取免费服务tokens,配置DeepSeek-V3-32K服务模型。完成Deepseek智能助手低代码应用开发,发布应用。✍️ 案例实操🎉 AstroChat智能助手对话界面开发  👈👈👈  体验完整案例,点这里登录华为开发者空间-低代码应用开发平台,创建AstroChat标准应用;创建智能助手模板自定义组件:获取组件模板、上传自定义组件;登录ModelArts平台,领取免费服务tokens,获取DeepSeek模型关键参数API地址、模型名称、API Key;创建自定义连接器,设置连接器动作参数与认证信息,配置DeepSeek模型信息;创建服务编排,添加配置图元,启用服务编排;开发智能助手对话界面,设置agent-ui组件属性,测试发布智能助手应用。🌈  案例最终效果:
  • [问题求助] 地图切换为室内,触发不了点击事件
    切换为室内,单击无反应,双击报错,无法正常显示弹窗
  • [技术干货] 基于华为开发者空间Astro低代码应用平台,构建业务用户登录功能开发
    📋 案例概览📝 背景与简介华为开发者空间是为全球开发者打造的专属云上成长空间,深度整合昇腾AI、鸿蒙、鲲鹏等华为根技术。开发者空间在HDC2025上迎来全面升级,新增AI原生应用引擎、AI Notebook、鸿蒙云手机、FunctionGraph云函数、Astro低代码等核心能力,并在算力、模型、平台、应用层实现全方位优化,助力开发者高效完成从编码到调测的全流程,打造智能AI应用开发新体验。华为开发者空间-低代码应用开发平台是华为云推出的一款可视化应用开发平台,旨在通过"拖拽式"组件和模板化设计,降低开发门槛,提升企业数字化应用构建效率。Astro平台特别适合业务人员与开发者协同创新,能大幅缩短应用交付周期,典型适用于OA审批、数据看板、轻量级业务系统等场景。传统用户登录开发深陷 “高成本、低效率、弱安全” 困局,而华为Astro通过 “预制安全能力+可视化编排+云原生运维” 三位一体,实现:安全零信任:内建金融级防护,杜绝密码泄露风险;部署小时级:拖拽式开发释放IT资源;业务可持续:权限热配置支撑敏捷迭代。本案例将通过华为开发者空间-低代码应用开发平台,为业务应用自定义一个登录页。通过在登录页中输入用户名、密码等登录信息,与系统中存储的业务用户信息进行对比,来验证业务用户的身份,并根据设置的业务用户权限,为业务用户分配相应的资源和访问权限。🔖 案例流程🕹️ 流程说明:领取华为开发者空间,登录华为开发者空间-低代码应用开发平台;新建低代码应用,进入Astro轻应用服务控制台主页,开发应用。✍️ 案例实操📝 业务用户登录后台开发领取华为开发者空间,登录华为开发者空间-低代码应用开发平台;在华为开发者空间-低代码应用开发平台创建低代码应用,配置系统环境变量;创建用户登录、注册脚本,测试登录注册运行,返回参数;关联登录脚本,创建用户登录服务编排;创建公共接口,发布服务。在业务用户登录后台开发的最后,我们创建了一个公共接口。接下来我们将完成业务用户前台的开发,通过调取公共接口进行前后端数据互传,完成业务用户登录功能的开发。📝 业务用户登录前台开发获取自定义登录组件模板,修改配置文件,创建自定义组件;创建高级页面,开发登录页,配置后台公共接口;发布应用,登录成功!!!🌈 案例最终效果
  • [热门活动] 【华为云低代码校园实训营·青岛城市学院站】【低码提交】【7月1日~7月31日】
    【活动简介】数字人才需求不断放大,为顺应国家产业发展需求,青岛城市学院与华为云共同策划举办校园实训活动,本次实训活动以华为云Astro 低代码平台为基础,结合线上活动+线下沙龙+实践操作的形式,同学们可以通过实操案例体验零码和低码开发模式,快速搭建应用,还可以跟华为云专家面对面交流,了解行业最新动态和前沿技术,从而开拓视野,增强实践能力,提升就业竞争力。同时还有丰富的奖品等着大家~【活动准备】步骤一、点击>>链接<<注册华为云账号,并完成实名认证。(已注册用户不用重复注册)步骤二、点击>>链接<<开通Astro Zero免费试用。(已开通用户不用重复开通)步骤三、点击>>链接<<登录Astro 低代码平台学习中心,初步了解和认识零码、低码知识,为实践阶段做准备。【实验操作指导手册】>>低码操作指导<<【提交要求】低码提交时间:7月1日~7月31日提交方式:按照操作指导最后一步,在“发布 > 应用包管理”下,选择“下载”,在评论区提交下载的应用包(应用包不要做任何修改),并备注姓名、联系方式和华为云账号。【奖励】按照要求提交完作业后,即可获得抽奖机会一次,以及结业证书一张。奖品和证书将在活动结束后统一发放。
  • [热门活动] 【华为云低代码校园实训营·青岛城市学院站】【零码提交】【6月15日~6月30日】
    【活动简介】数字人才需求不断放大,为顺应国家产业发展需求,青岛城市学院与华为云共同策划举办校园实训活动,本次实训活动以华为云Astro 低代码平台为基础,结合线上活动+线下沙龙+实践操作的形式,同学们可以通过实操案例体验零码和低码开发模式,快速搭建应用,还可以跟华为云专家面对面交流,了解行业最新动态和前沿技术,从而开拓视野,增强实践能力,提升就业竞争力。同时还有丰富的奖品等着大家~【活动准备】步骤一、点击>>链接<<注册华为云账号,并完成实名认证。(已注册用户不用重复注册)步骤二、点击>>链接<<开通Astro Zero免费试用。(已开通用户不用重复开通)步骤三、点击>>链接<<登录Astro 低代码平台学习中心,初步了解和认识零码、低码知识,为实践阶段做准备。【实验操作指导手册】>>零码操作指导<<【提交要求】零码提交时间:6月15日~6月30日提交方式:按照操作指导完成应用后,在评论区提交任务六和七最后一步的截图(截图须含华为云账号),并备注姓名、联系方式和华为云账号。【奖励】按照要求提交完作业后,即可获得抽奖机会一次,以及结业证书一张。奖品和证书将在活动结束后统一发放。
  • [热门活动] 【获奖已公布】PaaS产品开年体验季·一起玩转DeepSeek!赢取华为耳机、云宝手办等好礼~
    各位小伙伴久等啦~感谢大家的参与,现公布获奖名单,请在5月14日前>点此反馈收货地址<,逾期视为放弃礼品,请耐心等待礼品发出哦~注:有奖问卷的礼品近期也会安排发出,请注意查收。期待小伙伴后续持续关注我们更多精彩活动!【活动原文】新年新气象,在这充满机遇与挑战的 2025 年开篇之际,我们为您筹备了一场PaaS 产品开年体验季,PaaS产品结合当下炙手可热的 DeepSeek,推出最新的体验案例,帮助您在开发道路上更上一层楼!>>活动报名入口<<【活动内容】一、资源准备,限时优惠套餐•         Astro Zero 5.99元套餐(仅面向新注册用户)•         免费领取200万Tokens,体验DeepSeek系列等模型•         创建CodeArts API示例项目•         CodeArts Repo15元套餐(仅面向新注册用户)•    免费开通CodeArts体验套餐•         免费领取开发者空间云主机二、免费课程学习,产品入门指导1、看视频,学CodeArts开发2、华为云Astro实操指导课程3、华为云Astro介绍与开发实战4、图解开发者空间三、DeepSeek实践体验案例1、 在华为开发者空间快速部署DeepSeek2、 基于Astro的校级就业指导应用接入DeepSeek智能分析实践体验有奖互动:分享实践体验案例成果+体验心得/建议到本活动贴评论区,筛选8名优质分享内容,随机送出华为半入耳式耳机、华为云云宝手办。四、有奖调研,反馈您的真实声音 有奖问卷:完成问卷填写,即可参与抽奖哦(奖品:华为云云宝手办、鼠标垫) 加入PaaS产品交流群,与大家共同进步。
  • [案例共创] 【案例共创】通过ModelArts自动学习能力和低代码平台Astro实现"比熊识别"的AI应用实践
    引言在当今快速发展的技术环境中,人工智能(AI)和机器学习(ML)已经成为推动创新的关键力量。随着这些技术的普及,越来越多的企业和个人开发者开始探索如何将AI集成到日常应用中,以解决实际问题并提升效率。作为一名对AI充满热情的技术爱好者,我一直渴望找到一个既有趣又能体现AI价值的项目。因此,我选择了构建一个“比熊识别”应用程序作为我的实践案例,不仅因为比熊犬是我最喜欢的宠物之一,而且这个项目也提供了一个完美的机会来体验华为云提供的ModelArts自动学习能力和低代码开发平台——Astro的强大功能。(实话实说,比熊是真的可爱,我家的比熊就像个小公主,哈哈~通过该案例的实践,大家可以训练更庞大的数据集,毕竟千篇一律嘛~)选择ModelArts与Astro的原因ModelArts是一个一站式AI开发平台,它集成了数据处理、模型训练、部署和服务管理等功能,使得即使是非专业开发者也能轻松上手。而Astro则是一款基于浏览器的可视化编程工具,允许用户无需编写大量代码就能创建复杂的AI应用程序。这两个平台结合在一起,为我这样的开发者提供了前所未有的便利性和灵活性。本文将介绍如何通过 ModelArts 和 Astro 轻应用实现 AI 应用落地,并以一个物体检测应用为例进行演示。本次实践基于华北-北京四环境。准备工作在开始之前,首先需要准备一些基础材料:硬件环境:一台可以连接互联网的计算机。软件环境:安装了最新版本Chrome或Firefox浏览器的操作系统;注册华为云账号,并开通ModelArts服务。数据集:收集足够数量且质量良好的比熊犬图片用于训练模型。可以通过公开的数据集或者自行拍摄获得。第一步:ModelArts 训练并部署模型使用 ModelArts 的数据处理功能,对原始数据进行预处理和标注,生成训练所需的数据集。通过自动学习对数据集进行训练并发布部署模型。数据是 AI 应用的基础,要构建一个高质量的 AI 模型,首先需要有一个高质量的数据集(在 GPT 时代数据集也许无需标注,但要求更高的质量和多样性)。ModelArts 提供了数据处理功能,可以帮助用户对原始数据进行预处理和标注,生成训练所需的数据集。ModelArts 也提供了自动学习,就算您是零基础的 AI 小白,根据教程点点鼠标就能训练出自己专属的模型。1.登录 ModelArts 控制台,在左侧导航栏中选择“自动学习”,进入自动学习页面并点击物体检测创建自动学习任务。(PS:由于下载的数据集默认在新版数据集管理中,无法一键创建自动学习任务,我们可以在自动学习页面用下载的数据集来创建新的数据集进行自动学习)这里我要补充说明下:在创建项目的时候有个前提就是你得先创建数据集,我们可以通过OBS来上传,如下图所示:01在OBS上创建和上传相关材料;02创建数据集,路径使用刚创建的obs路径:03创建数据集后我们需要等待一段时间将数据导入,看数据大小,我这边100份图OBS只需要1分钟左右:04接下来就可以创建物体检测项目了,这里我们选择了限时免费训练规格(其他参数自定义即可):05创建完成后,我们将进行训练学习,训练学习的步骤可分为6项,分别是:数据标注、数据集版本发布、数据校验、物体检测、模型注册、服务部署。如下图所示:05-001首先第一步:数据标注,点击【数据标注】下的【实例详情】按钮,跳转至实例详情页面:05-002单击开始标注进行图片标注(这里我们先创建标签并手动进行5张图片的标注,然后可以选择智能标注):05-003进入智能标注后,我们等待时间即可(这里我9张图花了5分钟时间,标注的效果其实还不错的):05-004复核标注信息,这里我们可以选择【快速复核】,快速复核会直接展示标注信息,如果你看到某张图标注有问题,可以点击进入进行修改调整重新标注;05-005完成确认后,点击发布即可(版本默认设置为v001);05-006然后下一步我们返回【自助学习页面】点击进行【继续运行】进入到下一步:【数据集版本发布】:05-007【数据集版本发布】成功够将会自动进入下一步【数据校验】,这里我们等待这即可,无须操作(华为云提供了[限时免费]的训练资源规格:GPU: 1*GP-Vnt1(32GB) | CPU: 8 核 64GB):05-008【数据校验】成功够将会自动进入下一步【物体检测】,这里我们同样只需等待即可:当然,如果等待过程如果你想查询进入,我们可以前往【实例详情】页面进行查看:在运行日志中,我们可以直观的看到相关进度:05-009在【物体检测】跑完后,我们可以在实例运行界面查看数据评估,这里他会给出综合评估(从多个角度评价模型,并给出一定的调优建议。)。这里我的模型跑出来人建议如下所示:目标框面积占比对bixong的召回率有重大影响,在不同特征区间上mAP的方差为0.400。建议使用Balanced Loss来进行目标框回归计算。目标框清晰度对bixong的召回率有重大影响,在不同特征区间上mAP的方差为0.400。建议在训练时,添加针对此特征的数据增强。目标框亮度对bixong的召回率有重大影响,在不同特征区间上mAP的方差为0.331。建议在训练时,添加针对此特征的数据增强。05-009接下来我进行【服务部署】,这里计算机规格可以选择(免费)的哟(选择免费规格的话需要开启自动停止配置,且时间只能选择1小时,否则会部署失败);05-010等待部署成功之后可以进行预测调试。在线服务将AI应用部署为一个Web Service,并且提供在线的测试UI与监控能力。(这里我再强调下:免费实例 1 小时之后就会自动停止,如需不间断运行只能使用付费运行或者使用脚本维持。)这里,请记住服务 ID,比如: 26078a82-1da1-443c-a98b-9516ae422815,请保存调用指南中的 API 地址,前面一串数字是 模型Apig-Code,服务ID也就是后面那串数字是 模型Id。ModelArts 的数据处理能力展现了其在灵活性、效率和易用性方面的显著优势,为用户提供了强大的支持:多样化的数据与标注类型:无论是图像、视频、音频还是文本,ModelArts 都能处理,并且支持分类、检测、分割等多样的标注需求。这种广泛的支持确保了无论您的项目涉及何种数据形式或任务类型,都能找到合适的解决方案。智能化与协作式的标注流程:通过集成智能标注特性,ModelArts 能够利用预设或定制化的模型自动完成数据标签化工作,大幅减少了人工投入的时间与成本。同时,平台还支持团队成员间的协同作业,允许多人共同参与数据标注过程,并内置了评分与反馈机制,确保了标注结果的一致性和精准度。灵活的数据存储选项:为了简化数据管理并提升使用便捷性,ModelArts 提供了两种主要的存储方案——OBS(华为云对象存储服务)和本地存储。前者适合需要安全、稳定地保存大量数据的场景;后者则针对快速上传下载的需求设计,提供了即时可用的临时存储空间。第二步:Astro 轻应用集成 ModelArts 在线服务使用 Astro 轻应用的轻应用功能,通过拖拉拽的方式搭建应用界面,将 ModelArts 的模型服务接入 Astro 轻应用的连接器,实现应用的前端展示和交互。应用是 AI 应用的载体,要构建一个高品质的 AI 应用,需要有一个高品质的应用界面,并能与 AI 模型服务进行有效的交互。Astro 轻应用提供了轻应用功能,可以帮助用户通过拖拉拽的方式搭建应用界面,并将 ModelArts 的模型服务接入 Astro 轻应用的数据源,实现应用的前端展示和交互。步骤开始咯01登录 Astro 轻应用控制台,在左侧导航栏中选择的“应用”,点击“新建低代码应用–新建空白应用”。02根据流程,我们先配置好应用名称,和图标:03Astro 通过集成 ModelArts 连接器,实现了调用 ModelArts 在线服务。以前在没有 ModelArts 连接器的时候,我们需要自行开发 AKCK 鉴权、ModelArts API 调用、OBS 文件上传等等。现在我们要将Astro 集成 ModelArts 连接器,我们的环境默认是没有配置好的 ModelArts 连接器,需要开发者自行配置,我们可以导入下面的实例安装包,再进行连接器配置。实例安装包:https://appcube-ai-temp.obs.cn-north-4.myhuaweicloud.com/CNAMEO__EI-0.0.1-beta.zip04配置好连接器,我们可以在这个页面对在线模型检测简单的测试。为了方便大家的学习和操作,我这边附上官方的教学视频:低代码 AI 实战营: https://bbs.huaweicloud.com/live/cloud_live/202212151900.html05接着进行拖拉拽开发页面,这里就不多说,重要的还是自己去动手实践。完成开发后,大致的实现效果如下所示:Astro 轻应用不仅是一套工具,更是一种全新的开发理念,它通过一系列创新特性,为开发者和业务人员提供了前所未有的便捷性和灵活性。多样化应用场景:无论是构建轻量级应用、行业定制化解决方案还是大型业务展示平台,Astro 都能完美适配。从日常办公到人力资源管理,再到运营协同与项目管控,Astro 涵盖了企业运作的方方面面,确保每个需求都能得到精准满足。直观易用的界面设计:借助拖拽式的页面编辑器,即使是没有编程背景的用户也能轻松创建出功能完备的应用界面。丰富的组件库、预设模板以及可视化工作流编辑器,让用户能够迅速将创意转化为现实,无需一行代码。强大的数据整合能力:Astro 支持多源数据接入及服务编排,可以无缝集成来自 ModelArts 的机器学习模型服务或华为云及其他第三方提供的各种服务。这一切都可以通过图形化的界面完成配置,让复杂的数据处理变得简单直观,实现从前端交互到后端逻辑的全面贯通。高效的应用部署与管理:一键发布功能支持多种终端形式——PC 端、移动端、微信小程序/H5 和 WeLink 集成等,同时提供详尽的应用性能监控、使用统计和分享选项,确保每一个上线的应用都具备高度的可用性和稳定性。总结与展望以上便是我个人关于通过ModelArts自动学习能力和低代码平台Astro实现“比熊识别”的AI应用实践经历。希望这篇文章能够为同样对AI感兴趣的朋友们提供一些有价值的参考。如果你也有兴趣尝试,请不要犹豫,勇敢迈出第一步吧!当然,通过这次实践案例,我深刻体会到了ModelArts和Astro所带来的巨大便利。它们不仅大大降低了AI开发的技术门槛,也让普通开发者有机会参与到这场科技变革之中。未来,我希望能够继续深入研究这两个平台的更多特性,并尝试将其应用于更广泛的领域。此外,随着AI技术的不断发展,相信会有越来越多类似ModelArts和Astro这样优秀的工具涌现出来,为人们的生活带来更多惊喜和改变。我正在参加【案例共创】第1期 书写云产品应用构建开发最佳实践/评测,共创官方文档https://bbs.huaweicloud.com/forum/thread-0217170307934787108-1-1.html