# Ecode开发文档

# ecode使用说明

维护团队:云商店

原文地址 (opens new window) English (opens new window)

如何使用?

使用系统管理员账号登录系统,然后访问http[s]://${ip}:${prot}*/ecode

image-20231225152642089

如果提示没有权限,则需要为系统管理员添加权限,或者创建一个ecode开发用户的角色,指定某位用户进行ecode的开发,ecode开发权限如下:

image-20231225152753962

image-20231225152810009

image-20231225152826396

选择前端这三个权限填给指定角色即可进入开发页面

# 前言

描述ecode的作用和设计初衷

ecode核心是解决EC所有界面无侵入定制和扩展二次开发,采用动态注册,不直接修改源码的方案解决开发需求。除了新开发页面的之外,它还支持所有标准页面的修改。ecode包含了整套前端编辑器、编译器,可以让用户无需搭建开发环境直接通过浏览器开始single page前端开发,同时采用ecode开发的内容都是插件化,支持一键共享、复用、二次封装。

使用ecode需要提前学习的内容,基础决定了您可以用多深

PC端:js、css、es6、react16.x、react-router3、mobx

MOBILE端:js、css、es6、react16.x、react-router4、mobx

相关常用链接

ecology后端开发文档 (opens new window) - 维护团队:公共组件

相关技术快速入门方法:分享学习方法和学习资料 (opens new window) - 维护团队:公共组件

e9技术站:含所有e9技术文档,包括组件库及前后端sdk、api等等 (opens new window) - 维护团队:公共组件

weaJs:pc和移动都可用的一套轻量sdk,通常用于快速迁移e8以前老代码时最小改动 (opens new window) - 维护团队:公共组件

表单代码块sdk:包含pc和移动sdk (opens new window) - 维护团队:流程组

建模代码块sdk:只包含pc,移动建模当前版本使用的是独立框架,与e9总框架关系不大 (opens new window) - 维护团队:建模组

ecode前端开发规范 (opens new window) - 维护团队:公共组件

ecode常见问题及解决方法 (opens new window) - 维护团队:公共组件

全局数据读取 (opens new window) - 维护团队:公共组件

支持ecode复写的组件版本信息整理 (opens new window) - 维护团队:公共组件

# 注意事项(重要)

点击查看ecode注意事项 (opens new window)

点击查看ecode应用导致后台页面白屏通用解决方案 (opens new window)

点击查看系统登陆页/首页白屏相关问题及解决方案 (opens new window)

# 功能说明文档

点击查看ecode页面部分功能说明清单 (opens new window)

# 在线共享案例

点击查看ecode共享案例说明 (opens new window)

# 权限维护

登录sysadmin之后,在组织权限中心-权限管理-角色设置中,添加一个新的角色,例如ecode管理员,该角色添加权限项前端在线开发权限,在成员设置中添加用户即可.

ecode权限配置说明 (opens new window) - 维护团队:公共组件

# 如何安装

目前仅支持的浏览器内核谷歌chrome,国产环境请用360

下载并覆盖ecology的ecode通用升级包(注意标准kb1907+ 默认包含ecode,但版本不是最新版,最新版请以此链接为准)

点击这里下载安装包 (opens new window)

img

覆盖后到ecology访问地址进入ecode界面:ip:port/ecode

只要左侧菜单正常加载系统配置、默认分类,并且无报错就代表安装成功

img

导入最新官方参考案例,首先在左上角点击进入云商店案例库界面

img

找到需要的案例导入,导入案例将会放于本地分类【默认分类】

img

安装部署常见问题FAQ

点击这里查看 (opens new window)

# 一、ecode功能概述

# 1、新建

产生新数据

目前支持新建分类、文件夹、js、css、md

# 2、文件夹发布

发布成功文件夹变成橙色

作用是发布下面代码到EC,只有文件夹支持发布,文件夹选择了发布,其下面的文件会自动进行构建发布,开发者只需要编写代码,文件夹下的js和css就会分别被自动编译合并打包到一个js和css下,位置位于/cloudstore/release/${appId},此文件默认是不加载的,都是利用sdk去触发加载

# 3、前置加载

文件图标出现p标志

js、css支持前置加载,选择了前置加载将会在系统和组件未加载前执行,js在前置加载时可以用来进行一些底层全局事件注册,css在前置加载时可以用来做一些全局样式修改,当然也可以通过代码判断去区分作用范围,前置加载的所有脚本将会被合并到/cloudstore/dev/init.js/cloudstore/dev/init.css

# 4、在线编译语法与线下编译语法差异

react可以不用引入,全局默认存在

import React from "react"; //ecode中不用写
1

ecode模块引入与nodejs模块化中的import、export不同,需要修改成解构赋值

import {Button} from 'antd';
import {WeaInput} from 'ecCom';
1
2

改为

const {Button} = antd; //antd全局存在
const {WeaInput} = ecCom; //ecCom全局存在
1
2

ecode本地模块引入与nodejs本地模块化中的import、export不同,需要改成ecode imp、exp

export default NewCom; //模块化导出
import NewCom from './NewCom'; //模块化导入
1
2

改为

ecodeSDK.exp(NewCom); //ecode中导出
ecodeSDK.imp(NewCom); //ecode中导入,注意导入的模块必须在同一个橙色发布文件夹以内
1
2

ecode导出模块到全局的方式,这个在nodejs中是脚手架处理成umd导出,在ecode中我们封装了对应sdk,此方案可以有效管理全局组件

//NewBrowserForMeeting是对应组件名
ecodeSDK.setCom('${appId}','NewBrowserForMeeting',NewBrowserForMeeting);
1
2

ecode导入全局模块需要使用异步的方法一,通常用于表单和建模的代码块扩展

ecodeSDK.load({
  id:'${appId}', //如果在ecode外部(比如表单)使用,${appId}需要自行获取字符串
  noCss:true, //是否禁止单独加载css,通常为了减少css数量,css默认前置加载
  cb:function () {
      //回调的时候可以获取组件
    var Com = ecodeSDK.getCom('${appId}','NewBrowserForMeeting ');
    //将组件通过ReactDOM渲染到指定位置或者绑定到具体业务
  }
});
1
2
3
4
5
6
7
8
9

ecode前置加载文件中异步引入组件的方法,通常用于前置加载时扩展组件以及新页面开发

const acParams = {
    appId:'${appId}',
    name:'NewBrowserForMeeting', //模块名称
    isPage:false, //是否是路由页面
    noCss:true, //是否禁止单独加载css,通常为了减少css数量,css默认前置加载
    props:{} //组件参数
}
const Com = ecodeSDK.getAsyncCom(acParams);
1
2
3
4
5
6
7
8

# 5、ecode中使用组件库及工具库名称

PC端相关库

const {Button} = antd;
const {WeaTop} = ecCom;
const {toJS} = mobx;
const {Provider} = mobxReact;
1
2
3
4

MOBILE端相关库

const { observer, inject } = mobxReact;
const { withRouter } = ReactRouterDom;
const { AtSomeone } = WeaverMobilePage;
const { Button,Tools,WingBlank } = WeaverMobile;
1
2
3
4

# 6、文件夹和文件剪切、复制、黏贴

用来方便的对已有方案进行二次修改

文件夹剪切黏贴之后,appId将不会变化,而文件夹复制黏贴之后,将会产生新的appId

# 7、灰度发布功能

查看 (opens new window)

# 二、如何创建ecode项目

# 1、新建ecode分类以及文件夹

新建分类,分类的作用是清晰的管理ecode代码

img

新建文件夹,文件夹的作用是用来放实际项目js、css、md代码,另外根文件夹可以用来发布,其它的文件夹无法发布

img

# 2、新建js文件并发布文件夹

右键新建选择类型为js,并填入名称点击保存

img

选择根文件夹,点击右键并点击发布,操作成功之后文件夹会变成橙色,关于发布的机制,请看(第一章,第2点)的介绍

img

选择js文件,点击右键并点击前置加载,操作成功后文件图标上会有一个”p”的标志,关于前置加载机制,请看(第一章,第3点)的介绍

img

# 三、EC如何查看前端源代码

ecode的深入应用需要搭配EC源代码,所以本章重点介绍如何快速查找源代码

# 1、PC端源码如何查找

找到各模块的源码入口

前台:/pc4mobx/[模块名]/index.js 后台:/pc4backstage/[模块名]/index.js

比如

流程表单 /pc4mobx/workflowForm/index.js 流程 /pc4mobx/workflow/index.js 流程后台 /pc4backstage/workflow/index.js

以前台流程为例,可以在路由定义中找到流程模块各个页面的地址,使用chrome search或ctrl+p抓取

img

接着可以看待办页面具体源码,继续使用chrome search抓取,通过这样的方式就可以以此类推,找出所有业务源码

img

# 2、MOBILE端源码如何查找

找到各模块的源码入口

/mobile4mobx/[模块名]/index.js

比如

流程表单/mobile4mobx/workflowForm/index.js 流程 /mobile4mobx/workflow/index.js

以前台流程为例,可以在路由定义中找到流程模块各个页面的地址,使用chrome search或ctrl+p抓取,这里要注意的是移动端h5每个模块是分离的,需要到对应模块页面去抓取

img

接着可以看流程中心页面具体源码,继续使用chrome search抓取,通过这样的方式就可以以此类推,找出所有业务源码

img

# 四、组件参数复写

可以对EC全系统组件参数进行配置,支持组件站 (opens new window)中大部分组件参数,相当于全系统视图参数配置,部分复写方案项目人员也可上手,比如常见的修改表单富文本、隐藏页面部分元素、在界面中添加按钮等等场景,我们会不断提供各种案例让大家参考

# 1、PC端组件参数复写

ecodeSDK.overwritePropsFnQueueMapSet(name,option)
1

ecology版本要求:1906及1906+

# (1)参数说明
参数 说明 类型 可选 默认 备注
name 组件名 string 必填 ‘’ 包含 组件站 (opens new window) PC组件库ecCom、antd大部分组件 ,其中Radio、Radio.Button、Tree.TreeNode、Menu.ItemGruop、Select.Option、Select.OptGroup、SelectNew.Option、SelectNew.OptGroup暂不支持复写
option 复写配置 object 必填 {}
option.fn 复写钩子函数 function 必填 (newProps)=>{}
option.order 复写排序 integer 选填 0
option.desc 复写说明 string 选填 ‘’
# (2)基本例子

首先需要创建ecode项目,请参考(二、如何开始ecode项目)进行操作,创建成功如图

img

其中register.js的代码如下

ecodeSDK.overwritePropsFnQueueMapSet('WeaTop',{ //组件名
    fn:(newProps)=>{ //newProps代表组件参数
        //进行位置判断
    },
    order:1, //排序字段,如果存在同一个页面复写了同一个组件,控制顺序时使用
    desc:'在这里写此复写的作用,在调试的时候方便查找'
});
1
2
3
4
5
6
7
# (3)如何定位组件及其参数

组件站 (opens new window)PC组件库中的组件与所需要修改的组件进行对比,比如下图中我们发现了WeaTop这个组件

img

img

当然有些组件不一定能通过查看完全确认,我们需要进一步通过日志确认是否正确

ecodeSDK.overwritePropsFnQueueMapSet('WeaTop',{ //组件名
    fn:(newProps)=>{ //newProps代表组件参数
        console.log('WeaTop:',newProps); //在这里输出日志,如果成功输出代表组件成功定位
    },
    order:1, //排序字段,如果存在同一个页面复写了同一个组件,控制顺序时使用
    desc:'在这里写此复写的作用,在调试的时候方便查找'
});
1
2
3
4
5
6
7

日志不输出,通常要先检查代码是否正常生成,chrome浏览器F12 Newwork 中,查找init.js,在js中搜索复写代码,如果存在,但数据还是没有打印,那就要进一步到源码确认,如何查看源码,请查看(三、如何查看前端源代码)

img

找到组件之后我们需要找到能解决我们需求的组件参数,比如当我需要修改顶部菜单按钮的情况,同样的在组件站 (opens new window)PC组件库中我们可以找到每一个参数的详细说明

img

img

# (4)如何开发调试

复写组件参数第一件事情,判断组件渲染位置

const getLb = (id,name)=>{
    const {WeaLocaleProvider} = ecCom;
    const getLabel = WeaLocaleProvider.getLabel;
    return getLabel(id, name);
}
ecodeSDK.overwritePropsFnQueueMapSet('WeaTop',{ //组件名
    fn:(newProps)=>{ //newProps代表组件参数
        //可以通过地址栏判断,此函数会自动匹配实际html为/wui/index.html 且hash为#/main/workflow/listDoing的页面,如果html含参数/wui/index.html?xxx=ssss也支持判断
        if(!ecodeSDK.checkLPath('/wui/index.html#/main/workflow/listDoing')) return ;
        //也可以通过newProps.className、newProps.id 等等业务参数来判断,也可以调用业务api判断 ,如果组件页面内只存在一个,地址判断即可
    },
    order:1, //排序字段,如果存在同一个页面复写了同一个组件,控制顺序时使用
    desc:'在这里写此复写的作用,在调试的时候方便查找'
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14

找到参数后,我们可以直接对参数进行修改,以下是常见类型的改法

ecodeSDK.overwritePropsFnQueueMapSet('WeaTop',{ //组件名
    fn:(newProps)=>{ //newProps代表组件参数
        if(!ecodeSDK.checkLPath('/wui/index.html#/main/workflow/listDoing')) return ;
        console.log('WeaTop:',newProps); //在这里输出日志,如果成功输出代表组件成功定位
        //数组操作,引入组件,可以放入任意位置,数组元素的类型必须匹配,修改对应数据必须判断下标
        const {Button} = antd;
        if(newProps.buttons.length>=1) newProps.buttons[0] = (<Button>测试</Button>);
        //组件操作,可追加或者更换或者注入组件
        newProps.children = [newProps.children,(<div>我的自定义内容,也可以放dialog</div>)];
        //className、style修改,并给到特殊样式
        newProps.className = 'my-new-class';
        newProps.style = {
            color:'red'
        };
        //icon修改
        newProps.icon = (<i className="icon-coms-download2" />);
        return newProps; //修改之后返回数据
    },
    order:1, //排序字段,如果存在同一个页面复写了同一个组件,控制顺序时使用
    desc:'在这里写此复写的作用,在调试的时候方便查找'
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# 2、MOBILE端组件参数复写:

ecodeSDK.overwriteMobilePropsFnQueueMapSet(name,option)
1

ecology版本要求:1906及1906+

# (1)参数说明
参数 说明 类型 可选 默认 备注
name 组件名 string 必填 ‘’ 包含 组件站 (opens new window) 移动组件库WeaverMobile、WeaMobilePage大部分组件
option 复写配置 object 必填 {}
option.fn 复写钩子函数 function 必填 (newProps)=>{}
option.order 复写排序 integer 选填 0
option.desc 复写说明 string 选填 ‘’
# (2)基本例子

首先需要创建ecode项目,请参考(二、如何开始ecode项目)进行操作,创建成功如图

img

其中register.js的代码如下

ecodeSDK.overwriteMobilePropsFnQueueMapSet('TabPage',{ //组件名
    fn:(newProps)=>{ //newProps代表组件参数
        //进行位置判断
    },
    order:1, //排序字段,如果存在同一个页面复写了同一个组件,控制顺序时使用
    desc:'在这里写此复写的作用,在调试的时候方便查找'
});
1
2
3
4
5
6
7
# (3)如何定位组件及其参数

参考第四章组件参数复写sdk 第1节第(3)点

# (4)如何开发调试

参考第四章组件参数复写sdk 第1节第(4)点

# 五、组件重写

可以对EC全系统组件进行重写,支持组件站 (opens new window)中大部分组件,重新定义的组件只要遵循原组件的交互要求,即可进行自由定义,我们会不断提供各种案例让大家参考

# 1、PC端组件重写

ecodeSDK.overwriteClassFnQueueMapSet(name,option) ecology版本要求:1906及1906+

# (1)参数说明
参数 说明 类型 可选 默认 备注
name 组件名 string 必填 ‘’
option 复写配置 object 必填 {}
option.fn 复写钩子函数 function 必填 (Com,newProps)=>{}
option.order 复写排序 integer 选填 0
option.desc 复写说明 string 选填 ‘’

option.fn钩子函数用法

ecodeSDK.overwriteClassFnQueueMapSet('WeaBrowser',{
    fn:(Com,newProps)=>{
        //Com是当前复写的原组件
        //newProps是当前复写的原组件参数
        return {
              com:Com,
              props:newProps
            };
        }
    },
    order:1,
    desc:'浏览按钮复写'
})
1
2
3
4
5
6
7
8
9
10
11
12
13
# (2)基本例子

register.js:需要前置加载

let enable = true;
const NewWeaBrowser = (props)=>{ //此函数不允许写在复写方法内,会导致实例重复创建,也就是dimout不断执行
  const acParams = {
      appId:'${appId}', //appId会自动识别
      name:'NewWeaBrowserCom', //模块名称
      isPage:false, //是否是路由页面
      noCss:true, //是否禁止单独加载css,通常为了减少css数量,css默认前置加载
  }
  const NewCom = props.Com;
  return window.comsMobx?ecodeSDK.getAsyncCom(acParams):(<NewCom {...props} />);
}
ecodeSDK.overwriteClassFnQueueMapSet('WeaBrowser',{
  fn:(Com,newProps)=>{
    if(!enable) return ; //总开关
    const {hash} = window.location;
    if(!hash.startsWith('#/main/workflow/req')) return ;
    const baseInfo = WfForm.getBaseInfo();
    //判断流程id
    if(baseInfo.workflowid!==44) return ;
    //判断字段id,并且判断组件是否允许不能复写,如果不能复写,直接返回空
    if(newProps.fieldid!=="6318"||newProps._noOverwrite) return ;
    newProps.Com = Com;  //如果需要原组件,可带上
    return {
      com:NewWeaBrowser,
      props:newProps
    };
  }
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

index.js:不需要前置加载,所有非前置加载js,会被发布成模块 /cloudstore/release/${appId}/index.js

const {WeaBrowser} = ecCom;
class NewWeaBrowserCom extends React.Component {
  constructor(props) { //初始化,固定语法
    super(props);
    this.state = {}
  }
  render() {
    let newProps = {...this.props};
    //复写组件的时候,必须带上_noOverwrite参数,避免被复写的组件又被复写导致死循环
    return (
      <WeaBrowser {...newProps}  _noOverwrite />
    )
  }
}
//发布模块
ecodeSDK.setCom('${appId}','NewWeaBrowserCom',NewWeaBrowserCom);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# (3)如何定位组件及其参数

参考第四章组件参数复写sdk 第1节第(3)点

# (4)如何开发调试

参考第四章组件参数复写sdk 第1节第(4)点

# 2、MOBILE端组件重写

ecodeSDK.overwriteMobileClassFnQueueMapSet(name,option) ecology版本要求:1906及1906+

# (1)参数说明
参数 说明 类型 可选 默认 备注
name 组件名 string 必填 ‘’
option 复写配置 object 必填 {}
option.fn 复写钩子函数 function 必填 (Com,newProps)=>{}
option.order 复写排序 integer 选填 0
option.desc 复写说明 string 选填 ‘’

option.fn钩子函数用法

ecodeSDK.overwriteMobileClassFnQueueMapSet('WeaBrowser',{
    fn:(Com,newProps)=>{
    //Com是当前复写的原组件
    //newProps是当前复写的原组件参数
    return {
          com:Com,
          props:newProps
        };
    }
},
    order:1,
    desc:'浏览按钮复写'
})
1
2
3
4
5
6
7
8
9
10
11
12
13
# (2)基本例子

register.js:需要前置加载

let enable = true;
const NewWeaBrowser = (props)=>{ //此函数不允许写在复写方法内,会导致实例重复创建,也就是dimout不断执行
  const acParams = {
      appId:'${appId}', //appId会自动识别
      name:'NewWeaBrowserCom', //模块名称
      isPage:false, //是否是路由页面
      noCss:true, //是否禁止单独加载css,通常为了减少css数量,css默认前置加载
  }
  //const NewCom = props.Com;
  return ecodeSDK.getAsyncCom(acParams);
}
ecodeSDK.overwriteMobileClassFnQueueMapSet('Browser',{
  fn:(Com,newProps)=>{
    if(!enable) return ; //总开关
    const {hash} = window.location;
    if(!hash.startWith('#/req')) return ;
    const baseInfo = WfForm.getBaseInfo();
    //判断流程id
    if(baseInfo.workflowid!==44) return ;
    //判断字段id,并且判断组件是否允许不能复写,如果不能复写,直接返回空
    if(newProps.fieldid!=="6318"||newProps._noOverwrite) return ;
    //newProps.Com = Com;  //如果需要原组件,可带上
    return {
      com:NewWeaBrowser,
      props:newProps
    };
  }
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

index.js:不需要前置加载,所有非前置加载js,会被发布成模块 /cloudstore/release/${appId}/index.js

const {Browser} = WeaverMobile;
class NewWeaBrowserCom extends React.Component {
  constructor(props) { //初始化,固定语法
    super(props);
    this.state = {}
  }
  render() {
    let newProps = {...this.props};
    //复写组件的时候,必须带上_noOverwrite参数,避免被复写的组件又被复写导致死循环
    return (
      <Browser {...newProps}  _noOverwrite />
    )
  }
}
//发布模块
ecodeSDK.setCom('${appId}','NewWeaBrowserCom',NewWeaBrowserCom);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# (3)如何定位组件及其参数

参考第四章组件参数复写sdk 第1节第(3)点

# (4)如何开发调试

参考第四章组件参数复写sdk 第1节第(4)点

# 六、新页面开发

# 1、PC端新页面开发:

ecodeSDK.rewriteRouteQueue.push(option) ecology版本要求:1906及1906+

# (1)参数说明
参数 说明 类型 可选 默认 备注
option 复写配置 object 必填 {}
option.fn 复写钩子函数 function 必填 (params)=>{} params 参数请看下一个表格
option.order 复写排序 integer 选填 0
option.desc 复写说明 string 选填 ‘’

params 数据

参数 说明 类型 备注
Com 路由组件 react component 路由定义时传入的compoent
Route 路由参数 object
nextState 路由参数 object
# (2)基本例子

register.js:需要前置加载,注册了路由就会动态注入到react路由中

ecodeSDK.rewriteRouteQueue.push({
  fn:(params)=>{
    const {Com,Route,nextState} = params;
    const cpParams = {
      path:'main/cs/app', //路由地址
      appId:'${appId}',
      name:'pageSimple', //具体页面应用id
      node:'app', //渲染的路由节点,这里渲染的是app这个节点
      Route,
      nextState
    }
    if(ecodeSDK.checkPath(cpParams)) { //判断地址是否是要注入的地址
      const acParams = {
        appId:cpParams.appId,
        name:cpParams.name, //模块名称
        props:params, //参数
        isPage:true, //是否是路由页面
        noCss:true //是否禁止单独加载css,通常为了减少css数量,css默认前置加载
      }
      //异步加载模块${appId}下的子模块pageSimple
      return ecodeSDK.getAsyncCom(acParams);
    }
    return null; //这里一定要返回空,不然会干扰到其它新页面
  },
  order:10,
  desc:'Demo简单页面'
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

index.js:不需要前置加载,所有非前置加载js,会被发布成模块 /cloudstore/release/${appId}/index.js

const { Provider } = mobxReact;
const SimpleStore = ecodeSDK.imp(SimpleStore);
const Simple = ecodeSDK.imp(Simple);
//实例化store,并通过provider注入所有组件中
const allSimpleStore = {
  simpleStore:new SimpleStore()
}
class simpleRoot extends React.Component {
  render() {
    return (
      <Provider {...allSimpleStore}>
        <Simple {...this.props} />
      </Provider>
    )
  }
}
//发布模块
ecodeSDK.setCom('${appId}','pageSimple',simpleRoot);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# (3)如何配置和访问页面

获取appId,左上角点击已发布清单图标进入

img

img

假如appId是d7dce9fcf9d7430e9bdd7eddcb3bfc29,在门户菜单中配置路由地址:/main/cs/app/d7dce9fcf9d7430e9bdd7eddcb3bfc29_pageSimple

img

门户主入口访问地址:/wui/index.html#/main/cs/app/d7dce9fcf9d7430e9bdd7eddcb3bfc29_pageSimple

img

单独访问地址:/spa/custom/static/index.html#/main/cs/app/d7dce9fcf9d7430e9bdd7eddcb3bfc29_pageSimple

img

# 2、MOBILE端新页面开发

ecodeSDK.rewriteMobileRouteQueue.push(option) ecology版本要求:1906及1906+

# (1)参数说明
参数 说明 类型 可选 默认 备注
option 复写配置 object 必填 {}
option.fn 复写钩子函数 function 必填 (params)=>{} params 参数请看下一个表格
option.order 复写排序 integer 选填 0
option.desc 复写说明 string 选填 ‘’

params 数据

参数 说明 类型 备注
Com 路由组件 react component 路由定义时传入的compoent
props 路由参数 object 在移动端中,有些路由节点不会传入Com,而是传入 props.render
state 路由参数 object
context 路由参数 object
# (2)基本例子

register.js:需要前置加载,注册了路由就会动态注入到react路由中

let _this = null;
const waitWmLoad = (props,params) => {
    const acParams = {
        appId:'${appId}',
        name:'MobileSimplePage', //模块名称
        params, //参数
        isPage:true, //是否是路由页面
        noCss:true //是否禁止单独加载css,通常为了减少css数量,css默认前置加载
      }
      //异步加载${appId}下的子模块MobilePage1
      class WaitWeaverMobileLoad extends React.Component {
        constructor(props) {
          super(props);
          this.state = {
            isLoad:false
          }
          _this = this;
        }
        setIsLoad(b) {
          this.setState({
            isLoad:b
          });
        }
        render() {
          if(!this.state.isLoad) return (<div />);
          const NewCom = ecodeSDK.getAsyncCom(acParams);
          return (<NewCom />);
        }
      }
      return WaitWeaverMobileLoad;
}
ecodeSDK.onWeaverMobileLoadQueue.push(()=>{
  _this&&_this.setIsLoad(true);
});
//注册和绑定新页面前端实现接口
ecodeSDK.rewriteMobileRouteQueue.push({
  fn:(params)=>{
    const {Com,props,state,context} = params;
    const mpParams = {
      path:'/cs/app/:uuid', //路由地址
      appId:'${appId}',
      name:'MobileSimplePage', //路由名称
      props,
      state
    }
    if(ecodeSDK.checkMobilePath(mpParams)) {
      return waitWmLoad(props,params);
    }
    return null;
  },
  order:10,
  desc:'Demo简单页面'
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

index.js:不需要前置加载,所有非前置加载js,会被发布成模块 /cloudstore/release/${appId}/index.js

const { Provider } = mobxReact;
const SimpleStore = ecodeSDK.imp(SimpleStore);
const Simple = ecodeSDK.imp(Simple);
//实例化store,并通过provider注入所有组件中
const allSimpleStore = {
  simpleStore:new SimpleStore()
}
class simpleRoot extends React.Component {
  render() {
    return (
      <Provider {...allSimpleStore}>
        <Simple {...this.props} />
      </Provider>
    )
  }
}
//发布模块
ecodeSDK.setCom('${appId}','MobileSimplePage',simpleRoot);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# (3)如何配置和访问页面

获取appId,左上角点击已发布清单图标进入

img

img

假如appId是2d7187049bbe4adfbc4bfe4a41e188f6,生成的访问地址为:/spa/custom/static4mobile/index.html#/cs/app/2d7187049bbe4adfbc4bfe4a41e188f6_MobileSimplePage

img

img

配置完成后进入移动门户设置新应用

img

进入移动端入口访问 /spa/em/mobile.html

img

# 七、业务绑定

ecode除了可以在针对所有界面动态复写和动态注入组件之外,我们还提供了针对特殊业务绑定的sdk

# 1、PC门户主题注册

ecodeSDK.rewritePortalThemeQueue.push(option) ecology版本要求:1906及1906+

ecode的主题开发方案,解决传统主题开发的几大问题:主题通常都需要二次修改,用了ecode只需复制一下即可开始二次修改,不用安装配置脚手架,甚至一些小修改项目人员即可处理;主题的复用问题,使用ecode开发的主题完全无侵入,可拔插方便的在不同环境之间共享;解决以往难以让客户维护主题源码的问题,主题交付客户之后,可让客户自行维护;此方案开发进行标准页面跳转,直接支持single page模式,可以用react-router进行路由快速切换

# (1)参数说明
参数 说明 类型 可选 默认 备注
option 复写配置 object 必填 {}
option.fn 复写钩子函数 function 必填 (params)=>{} params 参数请看下一个表格
option.order 复写排序 integer 选填 0
option.desc 复写说明 string 选填 ‘’

params 数据

参数 说明 类型 备注
props 主题父组件参数 object
options 业务信息 object
options.id 主题ID string 主题定义完成后生成的ID
# (2)基本例子

register.js:需要前置加载,注册了主题即可关联到标准

 //注册和绑定门户主题前端实现接口
ecodeSDK.rewritePortalThemeQueue.push({
fn:(params)=>{
 const {props,options} = params;
 //异步加载模块${appId}下的子模块NewTheme
 if(options&&options.id==='d89d986c812a4f038740e3f824999de1') {
   const acParams = {
     appId:'${appId}',
     name:'NewTheme', //模块名称
     props:props,
     isPage:false, //是否是路由页面
     noCss:true //是否禁止单独加载css,通常为了减少css数量,css默认前置加载
   }
   return ecodeSDK.getAsyncCom(acParams);
 }
 return null;
},
order:1,
desc:'这是一个主题界面的参考案例'
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

index.js:不需要前置加载,用来实现主题代码,也可以使用mobx开发

const Top = ecodeSDK.imp(Top);
const {WeaPopoverHrm} = ecCom;
class NewTheme extends React.Component {
  render() {
    return (
      <div className="newtheme">
        {!window.pointerXY && (<WeaPopoverHrm />)}
        <Top {...this.props} />
        <div className='newtheme-container'>{this.props.children}</div>
      </div>
    )
  }
}
//发布模块NewTheme,作为模块${appId}的子模块
ecodeSDK.setCom('${appId}','NewTheme',NewTheme);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# (3)如何配置主题

到后台门户引擎,特色门户中新建主题

img

新建成功后,配置好主题共享权限,然后选择自定义模式,可以获取到主题id

img

在主题注册代码中关联这个id

img

配置完后即可自由开发主题

img

# 2、PC门户元素注册

ecodeSDK.rewritePortalCusEleQueue.push(option) ecology版本要求:1906及1906+

此方案开发的元素,客户端性能可达到最优,避免门户内存泄漏,另外复用性也比较强,可方便进行二次修改

# (1)参数说明
参数 说明 类型 可选 默认 备注
option 复写配置 object 必填 {}
option.fn 复写钩子函数 function 必填 (params)=>{} params 参数请看下一个表格
option.order 复写排序 integer 选填 0
option.desc 复写说明 string 选填 ‘’

params 数据

参数 说明 类型 备注
props 主题父组件参数 object
options 业务信息 object
options.ebaseid 元素ID string 元素定义完成后生成的ID
# (2)基本例子

register.js:需要前置加载,注册了元素即可关联到标准

//注册和绑定门户元素前端实现接口
ecodeSDK.rewritePortalCusEleQueue.push({
  fn:(params)=>{
    // console.log('params:',params);
    const {props,options} = params;
    if(options.ebaseid==='Custom_1562992730957') {
      const acParams = {
        appId:'${appId}',
        name:'CusEle', //模块名称
        params, //参数
        isPage:false, //是否是路由页面
        noCss:true //是否禁止单独加载css,通常为了减少css数量,css默认前置加载
      }
      //异步加载模块${appId}下的子模块CusEle
      return ecodeSDK.getAsyncCom(acParams);
    }
    return null;
  },
  order:1,
  desc:'这是一个元素界面的参考案例'
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

index.js:不需要前置加载,元素也可以用mobx实现

const {Button} = antd;
class CusEle extends React.Component {
  render() {
    // console.log(this.props);
    return (
      <div style={{padding:10}}>
        <Button>我是一个动态加载的元素界面</Button>
      </div>
    )
  }
}
//发布模块CusEle,作为模块${appId}的子模块
ecodeSDK.setCom('${appId}','CusEle',CusEle);
1
2
3
4
5
6
7
8
9
10
11
12
13
# (3)如何配置元素

在门户引擎中建立元素,获取主键ID

img

img

在代码中关联这个ID

img

# (4)如何配置自定义内容来源

ecology版本要求:2110及2110+

自定义元素设置默认有个内容来源设置,可以配置当前元素内容来源参数,参数格式可以根据自定义元素实际需求设置,比如获取某个门户下文档列表元素的数据时,可以配置为:

{"hpid": 1, "subCompanyId": 1, "eid": 1, "ebaseid": "7", "styleid": "synergys1"}
1

注意:JSON格式的key和value一定要用英文双引号。

img

内容来源参数可以在自定义元素组件中通过属性获取:

  componentDidMount() {
    const { datasourceconfig = '{}' } = this.props.params.options.config.item;
    const datasourceconfigobj = JSON.parse(datasourceconfig);
    const { hpid, subCompanyId, eid, ebaseid, styleid } = datasourceconfigobj;
    WeaTools.callApi('/api/portal/element/news', 'POST', { hpid, subCompanyId, eid, ebaseid, styleid }).then(result => {
      const data = result.data || {};
      this.setState({ data });
    })
  }
1
2
3
4
5
6
7
8
9
# (5)自定义设置

register.js:需要前置加载,注册了元素即可关联到标准

ecodeSDK.rewritePortalCusEleSettingQueue.push({
  fn: (params) => {
    const { props = {}, options = {} } = params;
    if (options.ebaseid === 'Custom_1562992730957') {
      const acParams = {
        appId: '${appId}',
        name: 'Setting',
        params,
        isPage: false,
        noCss: true
      };
      return ecodeSDK.getAsyncCom(acParams);
    }
    return null;
  }
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

Setting.js:自定义设置组件

const { WeaTools, WeaFormItem, WeaBrowser } = window.ecCom;
class Setting extends React.Component {
  constructor(props) {
    super(props);
    const { params = {} } = this.props;
    const { options = {} } = params;
    // 获取自定义设置组件实例,固定写法
    options.getInstance && options.getInstance(this);
    // 自定义设置组件中的相关数据
    this.state = { ids: '', datas: [] };
  }
  componentWillMount() {
    const { params = {} } = this.props;
    const { options = {} } = params;
    const { eid } = options;
    // 自定义实现元素自定义设置数据的获取
    WeaTools.callApi('/api/portal/dev/element/docsearch/getsecid', 'GET', { eid }).then((result) => {
      const { data = {} } = result;
      const { secobj = [] } = data;
      this.setState({ datas: secobj });
    });
  }
  render() {
    // 实现自定义配置项
    return (
      <WeaFormItem label="文档目录" labelCol={{ span: 6 }} wrapperCol={{ span: 16 }}>
        <WeaBrowser 
          title="请选择文档目录"
          type="doccategory"
          isSingle={false}
          replaceDatas={this.state.datas}
          onChange = {(ids, names, datas) => this.setState({ ids, datas })}
        />
      </WeaFormItem>
    );
  }
  // 设置保存方法名固定为onSave
  onSave = () => {
    const { params = {} } = this.props;
    const { options = {} } = params;
    const { eid } = options;
    const { ids: secid } = this.state;
    // 自定义实现元素自定义设置数据的保存接口
    WeaTools.callApi('/api/portal/dev/element/docsearch/setsecid', 'POST', { eid, secid });
  };
}
ecodeSDK.setCom('${appId}', 'Setting', Setting);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

# 3、移动门户元素注册

ecodeSDK.rewritePortalCusEleQueue.push(option) ecology版本要求:1912及1912+ 移动门户元素注册的钩子函数与pc端一致

此方案开发的元素,客户端性能可达到最优,避免门户内存泄漏,另外复用性也比较强,可方便进行二次修改

# (1)参数说明
参数 说明 类型 可选 默认 备注
option 复写配置 object 必填 {}
option.fn 复写钩子函数 function 必填 (params)=>{} params 参数请看下一个表格
option.order 复写排序 integer 选填 0
option.desc 复写说明 string 选填 ‘’

params 数据

参数 说明 类型 备注
props 主题父组件参数 object
options 业务信息 object
options.ebaseid 元素ID string 元素定义完成后生成的ID
# (2)基本例子

register.js:需要前置加载,注册了元素即可关联到标准

ecodeSDK.rewritePortalCusEleQueue.push({
  fn: (params) => {
    const { props } = params;
    // client = mobile:移动端门户标记
    // ebaseid = Custom_QuickEntry: 移动端门户自定义元素标记,区分元素类型
    if (props.client === 'mobile' && props.ebaseid === 'Custom_QuickEntry') {
      const acParams = {
        appId: '${appId}',
        name: 'View',
        params,
        isPage: false,
        noCss: true
      };
      return ecodeSDK.getAsyncCom(acParams);
    }
    return null;
  }
});

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

组件

class View extends React.Component {
  render() {
    const data = [
      {
        id: 1, 
        name: '我要请假', 
        icon: '/cloudstore/release/b59e05ced89f43d69ed7d6bdb6c57140/resources/01.png', 
        url: '/spa/workflow/static4mobileform/index.html#/req?iscreate=1&workflowid=1'
      },
      {
        id: 2, 
        name: '我要留言', 
        icon: '/cloudstore/release/b59e05ced89f43d69ed7d6bdb6c57140/resources/02.png', 
        url: '/spa/workflow/static4mobileform/index.html#/req?iscreate=1&workflowid=2'
      },
      {
        id: 3, 
        name: '我要出差', 
        icon: '/cloudstore/release/b59e05ced89f43d69ed7d6bdb6c57140/resources/03.png', 
        url: '/spa/workflow/static4mobileform/index.html#/req?iscreate=1&workflowid=3'
      },
      {
        id: 4, 
        name: '产品建议', 
        icon: '/cloudstore/release/b59e05ced89f43d69ed7d6bdb6c57140/resources/04.png', 
        url: '/spa/workflow/static4mobileform/index.html#/req?iscreate=1&workflowid=4'
      },
    ];
    return (
      <div className="portal-m-e-quick-entry">
        {
          data.map((item, index) => {
            return (
              <div key={index} onClick={() => this.onOpen(item.url)}>
                <img src={item.icon} />
                <div><span>{item.name}</span></div>
              </div>
            );
          })
        }
      </div>
    );
  }
  onOpen = (url) => {
    if (window.em && window.em.checkJsApi('openLink')) {
      window.em.openLink({
        sysId: window.localStorage.emobile_ec_id,
        url: url,
        openType: 2
      });
    } else {
      window.open(url);
    }
  };
}
ecodeSDK.setCom('${appId}', 'View', View);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# (3)如何配置元素

通过脚本建立元素,获取主键ID

insert into hp_mobile_BaseElement(id,elementtype,title,elementdesc,isuse,titleEN,titleTHK,loginview,isbase) 
values('Custom_QuickEntry',2,'快捷入口元素','快捷入口元素',1,'Quick Entry Element','快捷入口元素',0,1)
1
2

在移动门户配置对应元素(如:快捷入口元素)

img

在代码中关联元素类型:如案例中的‘Custom_QuickEntry’

img

# 4、特色门户元素注册

ecodeSDK.rewritePortalCusEleQueue.push(option)

ecology版本要求:2003及2003+

ecode元素开发易常简洁,无需创建表结构、接口和执行sql,就可以实现多tab元素,只需依照案例重写业务设置项与视图,即可实现整个元素开发。

# (1)参数说明
参数 说明 类型 可选 默认 备注
option 复写配置 object 必填 {}
option.fn 复写钩子函数 function 必填 (params)=>{} params 参数请看下一个表格
option.order 复写排序 integer 选填 0
option.desc 复写说明 string 选填 ‘’

params 数据

参数 说明 类型 备注
props 元素父组件参数 object
options 业务信息 object
options.id 元素ID string 主题定义完成后生成的ID
# (2)基本例子

register.js:注册元素文件,需要前置加载。该文件可以修改,元素选择名称,如下图

img

img

SettingExtend.js :内容设置扩展文件。该文件可以扩展内容设置页面 设置项,如下图

img

img

SettingStyleExtend.js :样式设置扩展文件。该文件可以扩展样式设置页面 设置项,如下图

img

img

ContainerModleProxy.js :元素模型代理文件。该文件可以设置 设置扩展页面属性默认值,如下图

img

img

ContainerViewProxy.js :显示页面代理文件。 该文件可以设置

  • 是否隐藏 设置页面的 内容来源表格 (即是否有多tab)
  • more 页面地址,如下图

1)、是否隐藏 设置页面的 内容来源表格

img

img

2)、more 页面地址

img

img

AddExtend.js :添加页面扩展文件。该 文件可以

  • 扩展添加页面 设置项

  • 设置扩展添加页面 属性默认 ,如下图 1)、扩展添加页面 设置项

img

img

2)、设置扩展添加页面 属性默认值

img

img

AddExtendGroup.js :添加页面扩展文件。该文件可以扩展添加页面 设置项组,如下图

img

img

ContainerViewExtend.js :显示页面文件。该文件是元素的显示页面,可以拿到所有设置数据,具体内容显示根据业务渲染,如下图

img

img

ContainerViewExtend.js: 元素设置页面代理文件,作为功能扩展文件,目前开发不需要修改

# 5.元素头注册

ecodeSDK.rewritePortalCusEleHeaderQueue.push(option) ecology版本要求:2011及2011+

此方案开发的元素,可以直接使用标准登录插件,另外跳转到主题可以用路由跳转,性能可达到最优

# (1)参数说明
参数 说明 类型 可选 默认 备注
option 复写配置 object 必填 {}
option.fn 复写钩子函数 function 必填 (params)=>{} params 参数请看下一个表格
option.order 复写排序 integer 选填 0
option.desc 复写说明 string 选填 ‘’

params 数据

参数 说明 类型 备注
props 主题父组件参数 object
options 业务信息 object
options.ebaseid 元素ID string 元素定义完成后生成的ID
# (2)基本例子

register.js:需要前置加载,注册了登录页即可关联到标准

ecodeSDK.rewritePortalCusEleHeaderQueue.push({
  fn: (params) => {
    const { props = {}, options = {} } = params;
    if (options.ebaseid === '1') {
      const acParams = {
        appId: '${appId}',
        name: 'Header',
        params,
        isPage: false,
        noCss: true
      };
      return ecodeSDK.getAsyncCom(acParams);
    }
    return null;
  }
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

Header.js:不需要前置加载,元素也可以用mobx实现

class Header extends React.Component {
  render() {
    // console.log(this.props);
    const { params = {} } = this.props;
    const { props = {}, options = {} } = params;
    const { config = {} } = props;
    const { header = {} } = config.item || {};
    return (
      <div className="portal-cus-rss-header">
        <span className="portal-cus-rss-header-title">{header.title}</span>
        {options.ToolbarCom}
      </div>
    );
  }
}
ecodeSDK.setCom('${appId}', 'Header', Header);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

Header.css:需要前置加载,自定义元素样式

.portal-cus-rss-header {
  position: relative;
  height: 36px;
  line-height: 36px;
  color: #fff;
  background-color: #4d7ad8;
}
.portal-cus-rss-header-title {
  padding-left: 10px;
  font-size: 14px;
}
1
2
3
4
5
6
7
8
9
10
11
# (3)案例效果

img

# 6.元素标签页注册

ecodeSDK.rewritePortalCusEleTabQueue.push(option) ecology版本要求:2011及2011+

此方案开发的元素,可以直接使用标准登录插件,另外跳转到主题可以用路由跳转,性能可达到最优

# (1)参数说明
参数 说明 类型 可选 默认 备注
option 复写配置 object 必填 {}
option.fn 复写钩子函数 function 必填 (params)=>{} params 参数请看下一个表格
option.order 复写排序 integer 选填 0
option.desc 复写说明 string 选填 ‘’

params 数据

参数 说明 类型 备注
props 主题父组件参数 object
options 业务信息 object
options.ebaseid 元素ID string 元素定义完成后生成的ID
# (2)基本例子

register.js:需要前置加载,注册了登录页即可关联到标准

ecodeSDK.rewritePortalCusEleTabQueue.push({
  fn: (params) => {
    const { props = {}, options = {} } = params;
    if (options.ebaseid === '1') {
      const acParams = {
        appId: '${appId}',
        name: 'Tab',
        params,
        isPage: false,
        noCss: true
      };
      return ecodeSDK.getAsyncCom(acParams);
    }
    return null;
  }
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

Tab.js:不需要前置加载,元素也可以用mobx实现

const { Popconfirm } = antd;
class Tab extends React.Component {
  render() {
    const { params = {} } = this.props;
    const { props = {}, options = {} } = params;
    const { datas = {} } = props;
    const { tabids = [], titles = [], counts = {} } = datas;
    return (
      <div className="portal-cus-rss-tab">
        <ul>
          {
            titles.map((item, index) => {
              return (
                <li 
                  key={tabids[index]} 
                  className={tabids[index] == options.tabid ? 'portal-cus-rss-tab-active' : ''} 
                  onClick={() => options.handleTabData(tabids[index])}
                >
                  <span>{item}</span>
                </li>
              );
            })
          }
        </ul>
      </div>
    );
  }
}
ecodeSDK.setCom('${appId}', 'Tab', Tab);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

Tab.css:需要前置加载,自定义元素样式

.portal-cus-rss-tab {
  position: relative;
  height: 36px;
  line-height: 36px;
  color: #333;
  border-bottom: 1px solid #ccc;
  box-sizing: content-box;
}
.portal-cus-rss-tab ul::after {
  content: '';
  display: block;
  clear: both;
}
.portal-cus-rss-tab ul li {
  float: left;
  width: auto;
  padding: 0px 10px;
  cursor: pointer;
}
.portal-cus-rss-tab-active {
  color: #4d7ad8;
  border-bottom: 1px solid #4d7ad8;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# (3)案例效果

img

# 7.元素工具栏注册

ecodeSDK.rewritePortalCusEleToolbarQueue.push(option) ecology版本要求:2011及2011+

此方案开发的元素,可以直接使用标准登录插件,另外跳转到主题可以用路由跳转,性能可达到最优

# (1)参数说明
参数 说明 类型 可选 默认 备注
option 复写配置 object 必填 {}
option.fn 复写钩子函数 function 必填 (params)=>{} params 参数请看下一个表格
option.order 复写排序 integer 选填 0
option.desc 复写说明 string 选填 ‘’

params 数据

参数 说明 类型 备注
props 主题父组件参数 object
options 业务信息 object
options.ebaseid 元素ID string 元素定义完成后生成的ID
# (2)基本例子

register.js:需要前置加载,注册了登录页即可关联到标准

ecodeSDK.rewritePortalCusEleToolbarQueue.push({
  fn: (params) => {
    const { props = {}, options = {} } = params;
    if (options.ebaseid === '1') {
      const acParams = {
        appId: '${appId}',
        name: 'Toolbar',
        params,
        isPage: false,
        noCss: true
      };
      return ecodeSDK.getAsyncCom(acParams);
    }
    return null;
  }
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

Toolbar.js:不需要前置加载,元素也可以用mobx实现

const { Popconfirm } = antd;
class Toolbar extends React.Component {
  render() {
    const { params = {} } = this.props;
    const { props = {}, options = {} } = params;
    return (
      <div className="portal-cus-rss-toolbar">
        <ul>
          <li><span onClick={options.handleRefresh}>刷新</span></li>
          <li><span onClick={options.handleSetting}>设置</span></li>
          <li>
            <Popconfirm 
              placement="leftTop" 
              title="此元素被删除后将不能被恢复,是否继续?"
              onConfirm={options.handleDelete} 
              okText="确定"
              cancelText="取消"
            >
              <span>删除</span>
            </Popconfirm>
          </li>
          <li><span onClick={options.handleMore}>更多</span></li>
        </ul>
      </div>
    );
  }
}
ecodeSDK.setCom('${appId}', 'Toolbar', Toolbar);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

Toolbar.css:需要前置加载,自定义元素样式

.portal-cus-rss-toolbar {
  position: absolute;
  top: 0;
  right: 5px;
}
.portal-cus-rss-toolbar ul::after {
  content: '';
  display: block;
  clear: both;
}
.portal-cus-rss-toolbar ul li {
  float: left;
  width: auto;
  padding: 0px 10px;
  cursor: pointer;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# (3)案例效果

img

# 8、PC门户登录页注册

ecodeSDK.rewritePortalLoginQueue.push(option) ecology版本要求:1906及1906+

此方案开发的元素,可以直接使用标准登录插件,另外跳转到主题可以用路由跳转,性能可达到最优

# (1)参数说明
参数 说明 类型 可选 默认 备注
option 复写配置 object 必填 {}
option.fn 复写钩子函数 function 必填 (params)=>{} params 参数请看下一个表格
option.order 复写排序 integer 选填 0
option.desc 复写说明 string 选填 ‘’

params 数据

参数 说明 类型 备注
props 主题父组件参数 object
options 业务信息 object
options.id 登录页ID string 登录页定义完成后生成的ID
# (2)基本例子

register.js:需要前置加载,注册了登录页即可关联到标准

ecodeSDK.rewritePortalLoginQueue.push({
  fn:(params)=>{
    const {props,options} = params;
    if(options.id==='a92ef529fd16469988feebe0e38cd83e') {
      const acParams = {
        appId:'${appId}',
        name:'E9NewLogin', //模块名称
        isPage:false, //是否是路由页面
        noCss:true, //是否禁止单独加载css,通常为了减少css数量,css默认前置加载
        props:props
      }
      //异步加载模块${appId}下的子模块CusEle
      return ecodeSDK.getAsyncCom(acParams);
    }
    return null;
  },
  order:1,
  desc:'新登录页'
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# (3)如何配置登录页

建立特色登录前门户,并获取ID

img

在登录页中关联登录前门户,从页面模板可以选择到这个特色门户,并选中这个登录页启用,注意一旦启用并且登录页还未调试好,就必须通过特殊地址才能登陆,调试期间可通过此地址/wui/index.html#/?templateId=-1强制切到标准登录页

img

在代码中关联此登录页,即可开始调试

img

# 9、全局流程代码块整合

此方案用于对全局流程做批量控制采用,另外也可作为单个流程或节点的代码块快速绑定,省去了绑定流程还到多个地方操作的麻烦,创建ecode项目的register.js并标记前置加载

let enable = true;
let isRun = false; //控制执行次数
const runScript = ()=>{ //代码块钩子,类似放在代码块中或者jquery.ready
  //可操作WfForm,以及部分表单dom hiden、ReactDOM.render
  //console.log('runScript!');
  isRun = true; //确保只执行一次
}
//PC端代码块
//利用组件复写作为代码块执行钩子,这种方案可以支持覆盖到所有流程,也可以判断到指定流程指定节点
ecodeSDK.overwritePropsFnQueueMapSet('WeaReqTop',{
  fn:(newProps)=>{
    if(!enable) return ; //开关打开
    const {hash} = window.location;
    if(!hash.startsWith('#/main/workflow/req')) return ; //判断页面地址
    if(!ecCom.WeaTools.Base64) return ; //完整组件库加载完成
    if(!WfForm) return ; //表单sdk加载完成
    const baseInfo = WfForm.getBaseInfo();
    const {workflowid} = baseInfo;
    if(workflowid!==44) return ; //判断流程id
    if(isRun) return ; //执行过一次就不执行
    runScript(); //执行代码块
  }
});
//移动端触发代码块,由于移动端代码块使用的组件和PC端代码块不同,所以此方法可以建一个独立项目(橙色)
ecodeSDK.overwriteMobilePropsFnQueueMapSet('TabPage',{
  fn:(newProps)=>{
    if(!enable) return ; //开关打开
    const {hash} = window.location;
    if(!hash.startsWith('#/req')) return ; //判断页面地址
    if(!WfForm) return ; //表单sdk加载完成
    const baseInfo = WfForm.getBaseInfo();
    const {workflowid} = baseInfo;
    if(workflowid!==44) return ; //判断流程id
    if(isRun) return ; //执行过一次就不执行
    runScript(); //执行代码块
  }
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

# 八、标准页面无侵入注册组件

整理中

Ecode开发文档

二开文档   |