宜搭-低代码开发师(高级)认证实操题1-待办列表

宜搭-低代码开发师(高级)认证实操题1-待办列表

终于通过了认证!!!耗时整理了一份自己实操的实现步骤,主要是复习使用自定义页面表格实现数据管理页功能✌✌✌希望大家都能顺利通过!!!

1. 考前须知

如下图:需要扫描二维码加入组织,我当时扫描失效,以下是另一种加入组织的方法

步骤1:打开手机钉钉右下角点击我的找到【客服与帮助】

步骤2:在【客服与帮助】页面下滑找到【快捷工具】选择【加入团队】即可根据名称搜索加入组织

 

2. 项目实操

2.1新增普通表单

2.1.1进行中待办

(1) 创建如下字段:

  • 待办事项:单行文本组件,必填
  • 分类:单选组件,必填,按照个人、工作、其他分类
  • 重要度:评分组件,默认值为1,必填
  • 设置提醒日期:日期组件,格式为年月日
  • 待办详情:多行文本组件

(2)设置重要度的默认值为1

步骤1:获取组件唯一标识,复制rateField_me2n0yf0(每个人创建的组件标识都不一样,按照自己创建的即可)

步骤2:在左侧动作面板中使用如下代码设置默认值

that.$('组件唯一标识').setValue()

2.1.2已完成待办

点击进行中待办表单旁边的⚙按钮,复制表单,并修改页面名称为【已完成待办】

2.2新增TodoList自定义界面

2.2.1TodoList自定义页面

点击+,新建自定义页面,在弹出的页面中【从模板中新建】,找到【工作台模板-01】,点击使用,如下图所示

删除无关组件,按照如下操作依次删除两个布局容器

选中"我的资产管理"修改内容为"待办列表"

创建进行中待办表格,进行一些字段/样式设置(拖拽两个组件分组、子表格,如下展示)

1. 将分组标题设置为“进行中待办”

2. 选中表格组件,删除无用字段,增加:待办事项、分类、重要度、设置提醒日期、待办事项

3. 设置字段名称,浏览器新开一个页面窗口,打开“进行中待办”的表单设计,选中组件→右侧点击“高级”→复制组件标识,粘贴到表格对应的数据字段,效果如下图所示

4. 修改“设置提醒日期”的数据类型,时间格式;修改“重要度”为枚举,并修改对应样式,操作步骤,代码如下

[ { "color": "grey", "text": "1", "value": 1, "__sid__": "serial_me9yvo5m" }, { "color": "blue", "text": "2", "value": 2, "__sid__": "serial_me9yvo5n" }, { "color": "yellow", "text": "3", "value": 3, "__sid__": "serial_me9yvo5o" }, { "color": "green", "text": "4", "value": 4, "__sid__": "serial_me9yvo5p" }, { "color": "red", "text": "5", "value": 5, "__sid__": "serial_me9yvo5q" } ]

5. 点击复制,用于已完成待办页面的展示,并选中分组组件,更改标题为“已完成待办”,效果如下图

6. 选择整个页面,点击右上角“页面设置”,设置背景色为“白色”

    2.3 TotoList自定义页面功能实现

     参考文档:自定义表格实现增删改查 | 钉钉宜搭·帮助中心

    功能实现前的说明:

    比如在浏览器端想调用应用编码为 APP_X1X2X3X4 的「流程实例-流程发起」服务接口,则在数据面板里调用请求地址为(使用相对路径即可):

    /dingtalk/web/APP_X1X2X3X4/v1/process/startInstance.json

    获取应用编码的步骤,以我当前创建的项目为例,在浏览器上方复制如下,我此时的应用编码为:appType:APP_L0MRPK82DM5SNZ2UIHPM

    获取formUuid的步骤,以“进行中待办”表单为例,同样浏览器上方获取,我此时“进行中待办”的formUuid为:FORM-50859B5DAD37446FA143EDCB4CF3A44375VP,用于下面获取数据展示定义必填参数

    对于表格组件来说,我们主要在如下图所示,这两个地方进行配置

    2.2.1 进行中待办-数据展示

    步骤1:选中左侧数据源,删除三个未被使用的远程数据源,并添加【getTodoDAata】远程API,可选中下面这个参考文档,定位到3.5 根据条件搜索表单实例ID列表,获取接口,请求类型,请求参数

    • 请求地址:/v1/form/searchFormDatas.json
    • 请求类型:GET
    • 请求参数:formUuid 表单Id 必填

    步骤2:在数据处理部分,选中请求完成回调函数,修改如下代码,其中,字段名称都要跟表格字段对应一致,如下

    function didFetch(content) { // content.b = 1; 修改返回数据结构中的 b 字段为1 const value = []; const data = content.data.map((item) => { let arr = { textField_me2n0yey: item.formData.textField_me2n0yey, radioField_me2n0yez: item.formData.radioField_me2n0yez, rateField_me2n0yf0: item.formData.rateField_me2n0yf0, dateField_me2n0yf1: item.formData.dateField_me2n0yf1, textareaField_me2n0yf2: item.formData.textareaField_me2n0yf2, instid: item.formInstId } value.push(arr); }) let result = { "data": value, "currentPage": content.currentPage, "totalCount": content.totalCount } return result; // 重要,需返回 content }

    步骤3:点击进行中待办的表格,右侧数据源设置变量为state.getTodoData,并且修改数据字主键为:instid

    步骤4:测试结果,在“进行中待办”页面新增一条数据,然后我们回到“TodoList自定义页面”点击预览查看已新增一条待办事项为“测试1”的数据,也可点击页面右上角选择“新窗口打开”,此时数据展示功能完成。

    2.2.2 进行中待办-分页/搜索

    步骤1:在“进行中待办”页面新增6条数据,效果如下

    步骤2:在数据源新增两个变量page和searchKey

    远程getTodoData中设置请求参数变量,代码如下:

    { searchFieldJson: JSON.stringify({ radioField_me2n0yez: state.searchKey }), formUuid: "FORM-50859B5DAD37446FA143EDCB4CF3A44375VP", currentPage: state.page, pageSize: 5 }

    步骤3:选中“进行中待办”的表格,滑到页面最底下选择“分页、搜索、排序时触发”,定义函数名称为onFetchTodoData,如果显示名称已存在,直接选中右侧的onFetchTodoData即可,现在我们动作面板编写代码

    // 点击进行中待办分页、搜索时触发 export function onFetchTodoData(params) { if (params.from === 'search') { params.currentPage = 1; } this.setState({ "searchKey": params.searchKey, "page": params.currentPage }) }

    步骤4:选择表格点击右侧分页设置,设置pageSize值为5

    步骤5:功能实现,查看效果

    2.2.3 进行中待办-新增

    步骤1:选中表格,在右侧点击“顶部操作”,删除原有的操作一,操作二,点击“添加一项”按钮,新增一个“新增待办”

    步骤2:在右侧新增一个对话框组件,设置标题为“新增待办”,并在对话框页面创建如下字段,举例:我这里对话框的唯一标识为dialog_me9xwn20,后面点击按钮打开弹窗的时候要用到

    • 待办事项:单行文本组件,必填
    • 分类:单选组件,必填,按照个人、工作、其他分类
    • 重要度:评分组件,默认值为1,必填
    • 设置提醒日期:日期组件,格式为年月日
    • 待办详情:多行文本组件

    如下图,可点击这两个位置,对弹窗进行隐藏,以便我们后续写代码逻辑

    步骤3:选中表格,在右侧点击“顶部操作”,点击新增待办中编辑,添加回调函数为onActionBarItemClick,然后返回js面板书写代码

    步骤4:代码书写,打开弹窗,分别重置表单组件唯一标识的值

    export function onActionBarItemClick() { // 打开弹窗,重置表单字段 this.$('dialog_me9xwn20').show(() => { this.$('textField_me9xwn22').reset(); this.$('radioField_me9xwn23').reset(); this.$('rateField_me9xwn24').setValue(1); this.$('dateField_me9xwn25').reset(); this.$('textareaField_me9xwn26').reset() }) }

    步骤5:选中对话框组件,滑到最底下,选择onOk编写我们的代码逻辑

    export function onOk() { // 需要校验组件的唯一标识集合 const createFieldList = [ 'textField_me9xwn22', 'radioField_me9xwn23', 'rateField_me9xwn24', 'dateField_me9xwn25' ]; // 字段名:分别复制表格中设置的字段名称的唯一标识 // 字段值:分别复制对话框中设置的字段名称的唯一标识 const data1 = { "textField_me2n0yey": this.$('textField_me9xwn22').getValue(), "radioField_me2n0yez": this.$('radioField_me9xwn23').getValue(), "rateField_me2n0yf0": this.$('rateField_me9xwn24').getValue(), "dateField_me2n0yf1": this.$('dateField_me9xwn25').getValue(), "textareaField_me2n0yf2": this.$('textareaField_me9xwn26').getValue() } const param = { formUuid: "FORM-50859B5DAD37446FA143EDCB4CF3A44375VP", appType: "APP_L0MRPK82DM5SNZ2UIHPM", formDataJson: JSON.stringify(data1) } // 调用表单校验函数 this.fieldsValidate(createFieldList).then((errorList) => { setTimeout(() => { if (errorList.length > 0) { // 表单校验未通过 return; }; //新增表单数据 this.dataSourceMap["insert"].load(param).then(res => { this.utils.toast({ title: '新增成功', type: 'success', size: 'large', }); }) // 新增完毕,关闭弹窗 this.$('dialog_me9xwn20').hide(); setTimeout(() => { this.dataSourceMap['getTodoData'].load(); }, 1000); }); }, 0); } // fieldList:Array,需要校验组件的唯一标识集合 export async function fieldsValidate(fieldList = []) { const result = []; for (let i = 0; i < fieldList.length; i++) { await this.$(fieldList[i]).validate((errors, values) => { if (!errors) { return }; result.push({ fieldId: fieldList[i], // 组件标识 errors: this.utils.isMobile() ? errors.errors[fieldList[i]].errors : errors[fieldList[i]].errors // 校验错误信息 }); }); }; return result; }

    步骤6:添加insert远程数据源,关闭自动加载,请求方式为post

    • 请求地址:/v1/form/saveFormData.json
    • 请求类型:post

    步骤7:测试结果,新增成功,校验效果也生效

    2.2.4 进行中待办-删除

    步骤1:新增一个对话框组件,并且设置标题为”确认删除“,样式设置为一级标题;再嵌套一个文本组件,设置内容为”删除后无法撤销,数据会永久删除,是否确认删除?“,设置样式为二级标题,padding为12px。因为我们要删除数据,所以需要获取到当前选择数据的id,需要在对话框里增加一个输入框组件,设置为隐藏,用于存储当前数据的id

    步骤2:在页面右侧操作列中增加”删除“,绑定回调函数onDeleteClick,编写代码

     export function onDeleteClick(rowData) { this.$('dialog_mea9fcvy').show(() => { this.$('textField_mea9fcw0').setValue(rowData.instid) }) }

    步骤3:当点击确认,调用onDeleteTodoData,设置代码

    export function onDeleteTodoData() { const param = { // 这里需要修改为自己设置的输入框组件【实例Id】的唯一标识 formInstId: this.$('textField_mea9fcw0').getValue(), } // 去远程数据源新增一个deleteData远程API this.dataSourceMap['deleteData'].load(param).then(res => { this.utils.toast({ title: "删除成功", type: "success", size: "large" }); // 这里需要修改为自己删除【对话框】组件的唯一标识 this.$('dialog_mea9fcvy').hide() setTimeout(() => { this.dataSourceMap['getTodoData'].load(); }, 1000); }) }

    步骤4:新增deleteData远程数据源,关闭自动加载,设置请求方式为post

    • 请求地址:/v1/form/deleteFormData.json
    • 请求类型:post

    步骤5:测试结果,,删除成功

    2.2.5 进行中待办-编辑

    步骤1:在页面右侧操作列中增加”编辑“,绑定回调函数onEditClick,打开新增待办的弹窗,回填数据,代码如下

     export function onEditClick(rowData) { this.$('dialog_me9xwn20').show(() => { // 前面的this.$('字段名'):字段名分别取的是对话框里组件的唯一标识 // rowData.字段名:字段名分别取的是table表格里面组件的唯一标识 this.$('textField_me9xwn22').setValue(rowData.textField_me2n0yey); this.$('radioField_me9xwn23').setValue(rowData.radioField_me2n0yez); this.$('rateField_me9xwn24').setValue(rowData.rateField_me2n0yf0); this.$('dateField_me9xwn25').setValue(rowData.dateField_me2n0yf1); this.$('textareaField_me9xwn26').setValue(rowData.textareaField_me2n0yf2); }) }

    步骤2:操作列出现两个,导致页面效果换行,所以我们需要在右侧选择操作列→设置合适的宽度,如下图设置为130px,页面显示效果正常

    步骤3:编辑同样我们需要获取到当前数据id,用于更新数据,刷新列表。所以需要在新增待办弹框创建一个实例Id用于存放当条数据id,隐藏;在数据源增加一个flag变量,用于判断我们打开的是新增还是编辑操作;增加updateData远程数据源,关闭自动加载调

    • 请求地址:/v1/form/updateFormData.json
    • 请求类型:post

    步骤4:修改三处代码

    (1)找到”新增待办“按钮触发的函数onActionBarItemClick,设置flag值为insert,并且重置输入框组件实例ID的值

       export function onActionBarItemClick() { // 当点击新增的时候,设置flag为insert this.setState({ flag:'insert' }) this.$('dialog_me5mzrhu').show(() => { this.$('textField_me5mzrhw').reset(); this.$('radioField_me5mzrhx').reset(); this.$('rateField_me5mzrhy').setValue(1); this.$('dateField_me5mzrhz').reset(); this.$('textareaField_me5mzri0').reset(); //重置实例ID的值 this.$('textField_mea9fcw1').reset() }) } 

      (2)找到”编辑“按钮触发的函数onEditClick,设置flag值为edit,设置实例ID值为rowData.instid

      export function onEditClick(rowData) { // 设置flag值为edit this.setState({ flag: 'edit' }) this.$('dialog_me5mzrhu').show(() => { this.$('textField_me5mzrhw').setValue(rowData.textField_me2n0yey); this.$('radioField_me5mzrhx').setValue(rowData.radioField_me2n0yez); this.$('rateField_me5mzrhy').setValue(rowData.rateField_me2n0yf0); this.$('dateField_me5mzrhz').setValue(rowData.dateField_me2n0yf1); this.$('textareaField_me5mzri0').setValue(rowData.textareaField_me2n0yf2); // 设置实例ID唯一标识值为当前选择行的instid this.$('textField_mea9fcw1').setValue(rowData.instid) }) } 

      (3)点击确定按钮,找到onOk函数修改代码,增加一个if判断,如果flag值为insert,新增数据,反之修改数据

      export function onOk() { // 需要校验组件的唯一标识集合 const createFieldList = [ 'textField_me9xwn22', 'radioField_me9xwn23', 'rateField_me9xwn24', 'dateField_me9xwn25' ]; // 字段名:是表格中相对应的字段名称的唯一标识 // 字段值:是当前对话框中的字段名称的唯一标识 const data1 = { "textField_me2n0yey": this.$('textField_me9xwn22').getValue(), "radioField_me2n0yez": this.$('radioField_me9xwn23').getValue(), "rateField_me2n0yf0": this.$('rateField_me9xwn24').getValue(), "dateField_me2n0yf1": this.$('dateField_me9xwn25').getValue(), "textareaField_me2n0yf2": this.$('textareaField_me9xwn26').getValue() } const param = { formUuid: "FORM-50859B5DAD37446FA143EDCB4CF3A44375VP", appType: "APP_L0MRPK82DM5SNZ2UIHPM", formDataJson: JSON.stringify(data1) } // 调用表单校验函数 this.fieldsValidate(createFieldList).then((errorList) => { setTimeout(() => { if (errorList.length > 0) { // 表单校验未通过 return; }; if(this.state.flag === 'insert'){ //新增表单数据 this.dataSourceMap["insert"].load(param).then(res => { this.utils.toast({ title: '新增成功', type: 'success', size: 'large', }); }) this.$('dialog_me9xwn20').hide(); setTimeout(() => { this.dataSourceMap['getTodoData'].load(); }, 1000); } else { const param2 = { formInstId: this.$('textField_mea9fcw1').getValue(), updateFormDataJson: JSON.stringify(data1) } this.dataSourceMap['updateData'].load(param2).then(res => { this.utils.toast({ title: "修改成功", type: "success", size: "large" }); this.$('dialog_me9xwn20').hide(); setTimeout(() => { this.dataSourceMap['getTodoData'].load(); }, 1000); }) } }); }, 0); }

      步骤5:测试结果,编辑成功

      2.2.6 已完成待办-数据展示

      步骤1:选择表格组件,在右侧页面设置中,找到顶部操作,删除操作1,操作2;操作列,将详情删除,新增一项删除,效果如下

      步骤2:新建远程API,getDoneData,设置请求地址、参数值、请求方式,数据处理

      function didFetch(content) { // content.b = 1; 修改返回数据结构中的 b 字段为1 const value = []; const data = content.data.map((item) => { let arr = { // item.formData.字段名:要跟已完成待办字段名对应上 textField_me2n0yey: item.formData.textField_me2ndu46, radioField_me2n0yez: item.formData.radioField_me2ndu47, rateField_me2n0yf0: item.formData.rateField_me2ndu48, dateField_me2n0yf1: item.formData.dateField_me2ndu49, textareaField_me2n0yf2: item.formData.textareaField_me2ndu4a, instid: item.formInstId } value.push(arr); }) let result = { "data": value, "currentPage": content.currentPage, "totalCount": content.totalCount } return result; // 重要,需返回 content }

      步骤3:设置已完成待办数据源变量、数据主键

      步骤4:在已完成待办中新增6条数据,进行测试,已成功显示

      2.2.7 已完成待办-分页/搜索

      步骤1:将已完成待办这里分页设置为5,并且新增变量donePage和doneSearchKey

      步骤2:将远程数据源getDoneData绑定请求参数变量,如下

      { searchFieldJson: JSON.stringify({ radioField_me2ndu47: state.doneSearchKey }), formUuid: "FORM-17BD995E61214B80BCEE9BB6EADF8DC8JNTV", currentPage: state.donePage, pageSize: 5 }

      步骤3:选中已完成待办表格,右侧动作选择分页,排序,搜索触发绑定onFetchDoneData,编写代码

      // 点击已完成待办分页,搜索时触发 export function onFetchDoneData(params) { if (params.from === 'search') { params.currentPage = 1; } this.setState({ "doneSearchKey": params.searchKey, "donePage": params.currentPage }) }

      步骤4:测试结果

      2.2.8 已完成待办-删除

      步骤1:操作列中为删除绑定onDeleteClick,代码可以直接复用,不用再写

      步骤2:在大纲树中打开删除的对话框,在右侧动作设置中直接定位到代码,增加一行,每次点击删除的时候会同时更新进行中待办,已完成待办表格数据,调用两次接口,我这里为了简写代码就这样写了,后续应该可以优化的

      this.dataSourceMap['getDoneList'].load()

      2.2.9 进行中待办-选择单行,删除数据,在已完成待办插入数据

      在页面设置中找到行选择器,开启显示,选择单选,在单行选择回调onSelect写逻辑代码

      export function onSelect(selected, rowData, selectedRows) { const param1 = { formInstId: rowData.instid } this.dataSourceMap['deleteData'].load(param1).then(res => { setTimeout(() => { this.dataSourceMap['getTodoData'].load(); }, 1000); }) const data1 = { // key:分别从已完成待办页面获取组件的唯一标识作为key // value:分别使用rowData.字段名,获取当前选中“进行中待办”数据作为value "textField_me2ndu46": rowData.textField_me2n0yey, "radioField_me2ndu47": rowData.radioField_me2n0yez, "rateField_me2ndu48": rowData.rateField_me2n0yf0, "dateField_me2ndu49": rowData.dateField_me2n0yf1, "textareaField_me2ndu4a": rowData.textareaField_me2n0yf2 } const param2 = { // formUuid:取的是已完成待办页面中的formUuid formUuid: "FORM-1FA35C7CEE6548928D83CB89D8B9877D5GQR", appType: "APP_L0MRPK82DM5SNZ2UIHPM", formDataJson: JSON.stringify(data1) } this.dataSourceMap["insert"].load(param2).then(res => { }) setTimeout(() => { this.dataSourceMap['getDoneData'].load(); }, 1000); console.log(selected, rowData, selectedRows); }

      2.2.9 “设置提醒日期”的通知功能

      在“进行中待办”表单设置中国,点击页面设置,再点击左侧“消息通知”,新增完成此功能实现

      3. TodoList自定义页面整体代码

      /** * 尊敬的用户,你好:页面 JS 面板是高阶用法,一般不建议普通用户使用,如需使用,请确定你具备研发背景,能够自我排查问题。当然,你也可以咨询身边的技术顾问或者联系宜搭平台的技术支持获得服务(可能收费)。 * 我们可以用 JS 面板来开发一些定制度高功能,比如:调用阿里云接口用来做图像识别、上报用户使用数据(如加载完成打点)等等。 * 你可以点击面板上方的 「使用帮助」了解。 */ // 当页面渲染完毕后马上调用下面的函数,这个函数是在当前页面 - 设置 - 生命周期 - 页面加载完成时中被关联的。 export function didMount() { console.log(`「页面 JS」:当前页面地址 ${location.href}`); // console.log(`「页面 JS」:当前页面 id 参数为 ${this.state.urlParams.id}`); // 更多 this 相关 API 请参考:https://aliwork.com/developer/API // document.title = window.loginUser.userName + ' | 宜搭'; } // 点击进行中待办分页、搜索时触发 export function onFetchTodoData(params) { if (params.from === 'search') { params.currentPage = 1; } this.setState({ "searchKey": params.searchKey, "page": params.currentPage }) } export function onActionBarItemClick() { this.setState({ flag:'insert' }) // 打开弹窗,重置表单字段 this.$('dialog_me9xwn20').show(() => { this.$('textField_me9xwn22').reset(); this.$('radioField_me9xwn23').reset(); this.$('rateField_me9xwn24').setValue(1); this.$('dateField_me9xwn25').reset(); this.$('textareaField_me9xwn26').reset() this.$('textField_mea9fcw1').reset() }) } /** * dialog onOk */ export function onOk() { // 需要校验组件的唯一标识集合 const createFieldList = [ 'textField_me9xwn22', 'radioField_me9xwn23', 'rateField_me9xwn24', 'dateField_me9xwn25' ]; // 字段名:是表格中相对应的字段名称的唯一标识 // 字段值:是当前对话框中的字段名称的唯一标识 const data1 = { "textField_me2n0yey": this.$('textField_me9xwn22').getValue(), "radioField_me2n0yez": this.$('radioField_me9xwn23').getValue(), "rateField_me2n0yf0": this.$('rateField_me9xwn24').getValue(), "dateField_me2n0yf1": this.$('dateField_me9xwn25').getValue(), "textareaField_me2n0yf2": this.$('textareaField_me9xwn26').getValue() } const param = { formUuid: "FORM-50859B5DAD37446FA143EDCB4CF3A44375VP", appType: "APP_L0MRPK82DM5SNZ2UIHPM", formDataJson: JSON.stringify(data1) } // 调用表单校验函数 this.fieldsValidate(createFieldList).then((errorList) => { setTimeout(() => { if (errorList.length > 0) { // 表单校验未通过 return; }; if(this.state.flag === 'insert'){ //新增表单数据 this.dataSourceMap["insert"].load(param).then(res => { this.utils.toast({ title: '新增成功', type: 'success', size: 'large', }); }) this.$('dialog_me9xwn20').hide(); setTimeout(() => { this.dataSourceMap['getTodoData'].load(); }, 1000); } else { const param2 = { formInstId: this.$('textField_mea9fcw1').getValue(), updateFormDataJson: JSON.stringify(data1) } this.dataSourceMap['updateData'].load(param2).then(res => { this.utils.toast({ title: "修改成功", type: "success", size: "large" }); this.$('dialog_me9xwn20').hide(); setTimeout(() => { this.dataSourceMap['getTodoData'].load(); }, 1000); }) } }); }, 0); } // fieldList:Array,需要校验组件的唯一标识集合 export async function fieldsValidate(fieldList = []) { const result = []; for (let i = 0; i < fieldList.length; i++) { await this.$(fieldList[i]).validate((errors, values) => { if (!errors) { return }; result.push({ fieldId: fieldList[i], // 组件标识 errors: this.utils.isMobile() ? errors.errors[fieldList[i]].errors : errors[fieldList[i]].errors // 校验错误信息 }); }); }; return result; } export function onDeleteClick(rowData) { this.$('dialog_mea9fcvy').show(() => { this.$('textField_mea9fcw0').setValue(rowData.instid) }) } // 删除进行中待办 export function onDeleteTodoData() { const param = { // 这里需要修改为自己设置的实例Id 唯一标识 formInstId: this.$('textField_mea9fcw0').getValue(), } // 去远程数据源新增一个deleteData远程API this.dataSourceMap['deleteData'].load(param).then(res => { this.utils.toast({ title: "删除成功", type: "success", size: "large" }); // 这里需要修改为自己删除弹窗的唯一标识 this.$('dialog_mea9fcvy').hide() setTimeout(() => { this.dataSourceMap['getTodoData'].load(); this.dataSourceMap['getDoneData'].load() }, 1000); }) } export function onEditClick(rowData) { this.setState({ flag:'edit' }) this.$('dialog_me9xwn20').show(() => { this.$('textField_me9xwn22').setValue(rowData.textField_me2n0yey); this.$('radioField_me9xwn23').setValue(rowData.radioField_me2n0yez); this.$('rateField_me9xwn24').setValue(rowData.rateField_me2n0yf0); this.$('dateField_me9xwn25').setValue(rowData.dateField_me2n0yf1); this.$('textareaField_me9xwn26').setValue(rowData.textareaField_me2n0yf2); this.$('textField_mea9fcw1').setValue(rowData.instid) }) } /** * 选择(或取消选择)数据之后的回调 * @param selected Boolean 是否选中 * @param rowData Object 当前操作行 * @param selectedRows Array 选中的行数据 */ export function onSelect(selected, rowData, selectedRows) { const param1 = { formInstId: rowData.instid } this.dataSourceMap['deleteData'].load(param1).then(res => { setTimeout(() => { this.dataSourceMap['getTodoData'].load(); }, 1000); }) const data1 = { // key:分别从已完成待办页面获取组件的唯一标识作为key // value:分别使用rowData.字段名,获取当前选中“进行中待办”数据作为value "textField_me2ndu46": rowData.textField_me2n0yey, "radioField_me2ndu47": rowData.radioField_me2n0yez, "rateField_me2ndu48": rowData.rateField_me2n0yf0, "dateField_me2ndu49": rowData.dateField_me2n0yf1, "textareaField_me2ndu4a": rowData.textareaField_me2n0yf2 } const param2 = { // 取已完成待办页面当中的formUuid formUuid: "FORM-17BD995E61214B80BCEE9BB6EADF8DC8JNTV", appType: "APP_L0MRPK82DM5SNZ2UIHPM", formDataJson: JSON.stringify(data1) } this.dataSourceMap["insert"].load(param2).then(res => { }) setTimeout(() => { this.dataSourceMap['getDoneData'].load(); }, 1000); } // 点击已完成待办分页,搜索时触发 export function onFetchDoneData(params) { if (params.from === 'search') { params.currentPage = 1; } this.setState({ "doneSearchKey": params.searchKey, "donePage": params.currentPage }) } 

      Read more

      C++分布式语音识别服务实践

      C++分布式语音识别服务实践

      基于 brpc+etcd + 百度 AI SDK 的分布式语音识别服务实践:从代码架构到踩坑复盘 一、项目背景与核心功能 最近基于 C++ 实现了一个分布式语音识别子服务,核心目标是提供高可用的 RPC 接口,支持客户端上传 PCM 音频文件并返回识别结果。技术栈选型如下: * RPC 框架:brpc(百度开源高性能 RPC 框架,支持多种协议); * 数据序列化:Protobuf(定义 RPC 接口和数据结构); * 服务注册与发现:etcd(分布式键值存储,实现服务上下线感知); * 语音识别能力:百度 AI 语音 SDK(提供成熟的 PCM 音频转文字能力); * 日志与配置:spdlog(高性能日志库)、gflags(命令行参数解析)。 项目分为服务端和客户端两部分:

      By Ne0inhk
      C++ 抽象类与多态原理深度解析:从纯虚函数到虚表机制(附高频面试题)

      C++ 抽象类与多态原理深度解析:从纯虚函数到虚表机制(附高频面试题)

      🔥草莓熊Lotso:个人主页 ❄️个人专栏: 《C++知识分享》《Linux 入门到实践:零基础也能懂》 ✨生活是默默的坚持,毅力是永久的享受! 🎬 博主简介: 文章目录 * 前言: * 一. 纯虚函数与抽象类:强制接口规范的“契约” * 1.1 纯虚函数:没有实现的 “接口声明” * 1.2 抽象类:包含纯虚函数的 “不可实例化类” * 二. 多态的底层原理:虚表指针与虚函数表 * 2.1 虚表指针(vfptr):对象中的 “导航器” * 2.2 多态的实现原理 * 2.3 虚函数表(vtable):存储虚函数地址的 “数组” * 2.4 动态绑定与静态绑定 * 三. 关键问题辨析与总结

      By Ne0inhk
      《C++ 递归、搜索与回溯》第1题:汉诺塔问题

      《C++ 递归、搜索与回溯》第1题:汉诺塔问题

      🔥个人主页:Cx330🌸 ❄️个人专栏:《C语言》《LeetCode刷题集》《数据结构-初阶》《C++知识分享》 《优选算法指南-必刷经典100题》《Linux操作系统》:从入门到入魔 《Git深度解析》:版本管理实战全解 🌟心向往之行必能至 🎥Cx330🌸的简介: 前言: 聚焦算法题实战,系统讲解三大核心板块:“精准定位最优解”——优选算法,“简化逻辑表达,系统性探索与剪枝优化”——递归与回溯,“以局部最优换全局高效”——贪心算法,讲解思路与代码实现,帮助大家快速提升代码能力 目录 前言: 递归,搜索与回溯算法前置知识 1. 汉诺塔 算法原理(递归): 思路: 算法流程: 解法代码(C++): 博主手记(字体还请见谅哈): 结尾: 递归,搜索与回溯算法前置知识 1. 汉诺塔 题目链接: 面试题 08.

      By Ne0inhk
      【C++藏宝阁】C++入门:命名空间(namespace)详解

      【C++藏宝阁】C++入门:命名空间(namespace)详解

      🌈个人主页:聆风吟 🔥系列专栏:C++藏宝阁 🔖少年有梦不应止于心动,更要付诸行动。 文章目录 * 📚专栏订阅推荐 * 📋前言:为什么需要命名空间? * 一、命名空间的定义 * 二、命名空间的使用 * 三、命名空间的特性 * 3.1 命名空间的嵌套定义 * 3.2 命名空间的定义可以不连续 * 四、命名空间的本质:独立的作用域 * 4.1 命名空间是C++的一种作用域类型 * 4.2 命名空间作用域的特点 * 4.3 域作用限定符 `::` 的作用 * 4.4 编译器的查找规则 * 五、命名空间的价值 * 5.1 解决命名冲突 * 5.2 模块化组织代码 * 5.3

      By Ne0inhk