1. 代码块-流程&建模
1.1 流程代码块
流程节点模板插入代码
场景1:请假流程,请假结束日期不能小于请假开始日期,否则给出提示信息,提示用户重新选择,并阻止流程提交
结束日期不能小于开始日期 |
---|
 |
function bindSave() { WfForm.registerCheckEvent(WfForm.OPER_SUBMIT, function(callback) { var jjrksrqId = WfForm.convertFieldNameToId("jjrksrq"); var jjrjsrqId = WfForm.convertFieldNameToId("jjrjsrq"); var jjrksrqv = WfForm.getFieldValue(jjrksrqId); var jjrjsrqv = WfForm.getFieldValue(jjrjsrqId); if (jjrjsrqv < jjrksrqv) { alert("结束日期不能小于开始日期!"); } else { callback(); } }); }
|
场景2:值班信息填报流程:根据选择的节假日带出的节假日开始日期和节假日结束日期,,并自动生成对应明细行,让用户填报值班信息。
根据选择的日期自动生成明细行 |
---|
 |
function bindTBJQ() { var tbjqid = WfForm.convertFieldNameToId("tbjq"); var jjrksrqId = WfForm.convertFieldNameToId("jjrksrq"); var jjrjsrqId = WfForm.convertFieldNameToId("jjrjsrq"); var zbrqid_1 = WfForm.convertFieldNameToId("zbrq", "detail_1"); WfForm.bindFieldChangeEvent(jjrjsrqId, function(obj, id, value) { var jjrksrqv = WfForm.getFieldValue(jjrksrqId); var jjrjsrqv = WfForm.getFieldValue(jjrjsrqId); var ksrqDate = new Date(jjrksrqv.replace(/-/g, "/")); var ksDate = new Date(jjrksrqv.replcace(/-/g, "/")).getTime()/1000; var jsDate = new Date(jjrjsrqv.eplcace(/-/g, "/")).getTime()/1000; var endTime = parseInt(jsDate) - parseInt(ksDate); var timeDay = parseInt(endTime/86400); for(var i=0; i<=timeDay; i++) { var dtrow = {}; if(i > 0) { ksrqDate.setDate(ksrqDate.getDate() + 1); } var rq = ksrqDate.getFullYear() + "-" + (ksrqDate.getMonth() + 1) + "-" + ksrqDate.getDate(); dtrow[zbrqid_1] = {value:rq, specialobj:[{id:rq, name:rq}]}; WfForm.addDetailRow("detail_1", dtrow); } }); }
|
上面两个函数需要放在页面初始化后绑定
JQuery().ready(function(){ pageInitFun(); });
function pageInitFun() { bindTBJQ(); bindSave(); };
|
1.2 建模代码块
场景1:查询列表,启用停用台账数据
启用/停用台账数据 |
---|
 |
建模引擎->应用建模->模块->页面扩展
javascrpt:aa(); function aa() { var ids = _xtable_CheckedCheckboxId(); alert(ids + "启用成功"); }
|
场景2:建模保存后调用第三方接口回传数据,判断是否存在重复数据(比如供应商录入,不允许相同名称重复录入),存在则提示用户存在重复数据,不允许保存。
建模引擎->应用建模->模块->页面扩展->接口动作(涉及后端,后面再讲)
或者
建模引擎->应用建模->模块->基础->新建布局->插入->E9代码块
<script type="text/javascript"> $(function() { var appid_id = ModeForm.convertFiledNameToId("appid"); ModeForm.bindFieldChangeEvent(appid_id, function(obj, id, value) { console.log("值改变--", obj, id, value); }) });
windows.checkCustomize = () => { var flag = false; alert("重复创建不允许保存,请检查数据"); return flag; } </script>
|
2. Ecode无侵入组件复写&重写
http://ip:port/ecode
进入Ecode页面定制开发,具体如何书写可以参考示例
书写完成后鼠标右键文件夹菜单点击发布
2.1 组件复写
参考资料:https://e-cloudstore.com/doc.html
组件库:https://e-cloudstore.com/e9/index2.html
场景1:待办流程页面,隐藏部分Tab内容
const enable = true
const getLb = (id, name) => { const {WeaLocaleProvider} = ecCom; const getLabel = WeaLocaleProvider.getLabel; return getLabel(id, name); }
ecodeSDK.overwritePropsFnQueueMapSet('Tabs', { fn:(newProps) => { if (!enable) return; const {hash} = window.location; if(!hash.startsWith('#/main/workflow/listDoing')) return; console.log(newProps); let datas = newProps.datas; let children = newProps.children; let newDatas = []; let newChildren = []; for(let i=0;i<datas.length;i++) { if(datas[i].groupid!="flowSup") { newDatas.push(datas[i]); newChildren.push(children[i]); } } newProps.datas=newDatas; newProps.children=newChildren; return newProps; } });
|
场景2:新建流程页面复写顶部按钮
const enable = true
ecodeSDK.overwritePropsFnQueueMapSet('Button', { fn:(newProps) => { if (!enable) return; const {hash} = window.location; if(!hash.startsWith('#/main/workflow/req')) return; console.log(newProps); if(newProps.title=="提交") { newProps.title="发送"; newProps.children.props.children="发送"; newProps.onClick=function() { alert("发送!"); }; } if(newProps.title==”保存") { newProps.disabled=true; } return newProps; } });
|
2.2 组件重写
注:如何找到组件的源码?
前台:/pc4mobx/[模块名]/index.js
后台:/pc4backstage/[模块名]/index.js
比如
流程表单 /pc4mobx/workflowForm/index.js
流程 /pc4mobx/workflow/index.js
流程后台 /pc4backstage/workflow/index.js
场景1:新建流程页面增加新页签newTabs
index.js
const { weaTab } = ecCom;
class NewTab extends React.Component { getDatas = () => { const { data = [] } => this.props; if (!datas.find((data) => data.key === 'newTab')) { let newTab = { key: 'newTab', title: '', }; $.ajax({ url: "/api/newworkflow/getParentSubcompData", data: {}, async: false, dataType: "json", success: function(res) { if(res.api_status) { let tabs = res.data; for(let i=0;i<tabs.length;i++) { let row=tabs[i]; if (i==0&&row.companyname="CCTV") { newTab.title=row.companyname; datas.push(newTab); } } } else { message.error(res.msg || '接口调用失败!'); } } }); } return datas; } getStore = () => { if (window.weaWorkfolw && window.weaWorkflow.store.wfAddStore) { return window.weaWorkflow.store.wfAddStore; } return {}; } onChange = (tabKey) => { const { onChange } = this.props; const wfAddStore = this.getStore(); const { lastWftypes } = wfAddStore; if (!wfAddStore['lastWftypes'] || (wfAddStore['lastWftypes'] && wfAddStore['lastWftypes'].length === 0)){ wfAddStore['lastWftypes'] = [...wfAddStore.wftypes]; wfAddStore['compWftypes'] = [...wfAddStore.wftypes]; let compWftypes=wfAddStore['compWftypes']; $.ajax({ url: "/api/newworkflow/getNewWorkflowTabTypeIds", data: {}, async: false, dataType: "json", success: function(res) { if(res.api_status) { let wftype = "," + res.wftype + ","; let nowWftypes = []; for(let i=0;i<compWftypes.length;i++) { let compWftypesid = ',' + compWftypes[i].id + ','; if (wftype.indexOf(compWftypesid) >= 0) { nowWftypes.push(nowWftypes[i]); } } wfAddStore['nowWftypes'] = nowWftypes; } else { message.error(res.msg || '接口调用失败!'); } } }); } if (tabKey === 'newTab') { wfAddStore.wftypes = wfAddStore['nowWftypes']; } else { $.ajax({ url: "/api/workflow/createreq/wfinfo?needall=1&menuIds=1%2C12&tabkey=newTab&__radom__=16092080808589", data: {}, async: false, dataType: "json", success: function(res) { wfAddStore.wftypes=res.datas; } }); } if (typeof onChange === 'function') onChange(tabKey); } render() { let {selectedKey, isfirstselect} = this.props; if (isfirstselect == "1") { selectedKey = "newTab"; isfirstselect = "2"; const wfAddStore = this.getStore(); const { lastWftypes } = wfAddStore; if (!wfAddStore['lastWftypes'] || (wfAddStore['lastWftypes'] && wfAddStore['lastWftypes'].length === 0)){ wfAddStore['lastWftypes'] = [...wfAddStore.wftypes]; wfAddStore['compWftypes'] = [...wfAddStore.wftypes]; let compWftypes=wfAddStore['compWftypes']; $.ajax({ url: "/api/newworkflow/getNewWorkflowTabTypeIds", data: {}, async: false, dataType: "json", success: function(res) { if(res.api_status) { let wftype = "," + res.wftype + ","; let nowWftypes = []; for(let i=0;i<compWftypes.length;i++) { let compWftypesid = ',' + compWftypes[i].id + ','; if (wftype.indexOf(compWftypesid) >= 0) { nowWftypes.push(nowWftypes[i]); } } wfAddStore['nowWftypes'] = nowWftypes; } else { message.error(res.msg || '接口调用失败!'); } } }); } wfAddStore.wftypes = wfAddStore['nowWftypes']; wfAddStore.tabKey = "newTab"; wfAddStore.initParams.tabkey = "newTab"; wfAddStore.changeTab("newTab"); } return { <div> <WeaTab _noOverWrite {...this.props} datas={this.getDatas()} onChange={this.onChange} /> </div> } } }
ecodeSDK.setCom('${appId}', 'NewTab', NewTab);
|
init.js
const NewTab = (props) => { const acParams = { appId: '${appId}', name: 'newTab', isPage: false, noCss: true, props, } return ecodeSDK.getAsyncCom(acParams); }
window.addEventListener('hashchange', () => { localStorage.setItem("isfristselect", "1"); })
localStorage.setItem("isfristselect", "1");
ecodeSDK.overwriteClassFnQueueMapSet('WeaTab', { fn:(Com, newProps) => { console.log(newProps); if(newProps._noOverwrite) return; if(windows.location.hash.indexOf('/main/workflow/add') >= 0) { let tabs = newProps.datas; if (tabs.length >= 3 && localStorage.getItem("isfirstselect") == "1") { if (newProps.isfirstselect && newProps.isfirstselect == "2") { } else { newProps.isfirstselect = "1"; newProps.selectedKey = "newTab"; localStorage.setItem("isfristselect", "2"); window.weaWorkflow.store.wfAddStore.tabkey="newTab"; window.weaWorkflow.store.wfAddStore.initParams.tabkey="newTab"; window.weaWorkflow.store.wfAddStore.changeTab("newTab"); } } return { com: newTab, props: newProps; } } else { localStorage.setItem("isfristselect", "1"); } } })
|
3. Ecode前端接口拦截
场景:新建流程页面增加按钮获取第三方数据
ecodeSDK.overwriteApiDataQueueMapSet({ fn: (url, params, datas) => { if (url.indexOf('/api/workflow/createreq/wfinfo') >= 0) { $.ajax({ url: "/api/newworkflow/getParentSubcompData", data: {}, async: false, dataType: "json", success: function(res) { if(res.api_status) { let tabs = res.data; for(let i=0;i<tabs.length;i++) { let row=tabs[i]; if (i==0&&row.companyname="CCTV") { datas.tabs.push({title: row.companyname, key: "newTab"}); datas.userOperationHabit.defaultSelectedTab="newTab"; let tabdata = datas.datas; let newtabdata = []; for(let j=0; j<tabdata.length; j++) { if((","+row.lcljlx+",").indexOf(","+tabdata[j].id+",")>=0) { newtabdata.push(tabdata[j]); } } datas.lastdatas=tabdata; datas.data=newtabdata; } } } else { message.error(res.msg || '接口调用失败!'); } } }); } } }
|
4. Ecode自定义页面
场景:值班信息页面
值班信息页面 |
---|
 |
apis文件夹下index.js
const { WeaTools } = ecCom;
const getCondition = params => { return WeaTools.callApi('/api/skj/abxxCondition', 'GET', params); };
const getDatas = params => { return WeaTools.callApi('/api/skj/zbxxReport', 'GET', params); };
const publishDoc = params => { return WeaTools.callApi('/api/skj/publishDoc', 'POST', params); };
const outExcel = params => { return WeaTools.callApi('/api/skj/zbxxOutExcel', 'GET', params); };
const API = { getCondition, getDatas, publishDoc, outExcel }
ecodeSDK.exp(API);
|
utils文件夹index.js
const { Spin } = antd; const { WeaLocaleProvider, WeaAlertPage } = ecCom; const getLabel = WeaLocaleProvider.getLabel;
const renderLoading = (loading) => { <div className="wea-demo-loading"> <Spin spinning={loading} /> </div> }
const renderNoright = () => { <WeaAlertPage> <div> {getLabel(2012, "对不起,您暂时没有权限!")} </div> </WeaAlertPage> }
const renderNoData = () => { <WeaAlertPage> <div> 暂无数据 </div> </WeaAlertPage> }
const utils = { renderLoading, renderNoright, renderNoData, }
ecodeSDK.exp(utils);
|
style文件夹(右键该文件夹启用前置加载)下的report.css
.zbxx { width: 100%; height: 100%; }
.zbxx .wea-tab{ padding: 0 20px; }
.zbxx-datas { padding: 30px 20px 0 20px; }
.zbxx td{ border: 1px; solid; }
.zbxx th{ border: 1px solid; }
.zbxx table { border-collapse: collapse; width: 100%; }
.zbxx td { text-align: center }
|
stores文件夹下index.js
const ReportStore = ecodeSDK.imp(ReportStore);
const allStore = { reportStore: new ReportStore(); };
ecodeSDK.exp(allStore);
|
stores文件夹下report.js
const { observable, action, toJS } = mobx; const { message } = antd; const { WeaForm } = comsMobx;
const API = ecodeSDK.imp(API);
class ReportStore { @observable form = new WeaForm(); @observable loading = true; @observable hasRight = true; @observable condition = []; @observable datas = []; @observable colnameArr = []; @observable excel=''; @action doInit = () => { this.getCondition(); this.getDatas(); } @action getCondition = () => { API.getCondition().then(action(res => { if (res.api_status) { this.condition = res.condition; this.form.initFormFields(res.condition); } else { message.error(res.msg || '接口调用失败!'); } })) } @action getDatas = (params) => { this.loading = true; API.getDatas().then(action(res => { if (res.api_status) { this.datas = res.data; this.colnameArr=res.colname; this.hasRight=res.hasRight; } else { message.error(res.msg || '接口调用失败!'); } })) this.loading = false; } }
|
coms文件夹下的index.js
const { inject, observer } = mobxReact; const { toJS } = mobx; const { Button, message } = antd; const { WeaSwitch } = comsMobx; const { WeaTop, WeaTab, WeaRightMeanu, WeaReport, WeaFormItem, WeaMewScroll} = ecCom;
const { renderNoright, renderLoading } = ecodeSDK.imp(utils);
@inject('reportStore') @observer class Report extends React.Component { static defaultProps = { prefixCls: "zbxx" }; componentWillMount() { const { reportStore: { doInit }} = this.props; doInit(); } componentWillReceiveProps(nextProps) { const { reportStore } = this.props; if (this.props.location.key !== nextProps.location,key) { reportStore.doInit(); } } exportExcel = () => { const { reportStore: { outExcel, form }} = this.props; const params = form.getFormParams(); console.log("paramsexcel", params); outExcel(params); } expExcel = () => { const { reportStore: { outExcel1, form }} = this.props; const params = form.getFormParams(); console.log("paramsexcel", params); outExcel(params); } publishDoc = () => { const { reportStore: { publishDoc, form }} = this.props; const params = form.getFormParams(); console.log("publishDoc", params); publishDoc(params); } doSearch = () => { const { reportStore: { getDatas, form }} = this.props; const params = form.getFormParams(); console.log("params=", params); if(params.jjr==""){ message.info("请先选择节假日!") } else { getDatas(params); } } getSearchsAdQuick = () => { const { reportStore: { form, condition }} = this.props; const { isFormInit } = form; const arr = []; if(isFormInit) { const c = toJS(condition)||[]; c.length>0&&c[0].items.map(field=>{ arr.push( <WeaFormItem label={`${field.label}`} labelCol={{span: `${field.labelcol}`}} wrapperCol={{span: `${field.fieldcol}`}} > <WeaSwitch fieldConfig={field} form={form} /> </WeaFormItem> ); }); } return arr; } render() { const { reportStore, prefixCls } = this.props; const { loading, hasRight, form, datas, colnameArr } = reportStore; if (!hasRight && !loading) { return renderNoRight(); } const rightMenu = [ { key: 'BTN_EXP', icon: <i className='icon-coms-Restore' /> content: '导出', onClick: this.expExcel, }, ]; const rightMenu = [ { key: 'BTN_EXP', icon: <i className='icon-coms-Restore' /> content: '导出', onClick: this.expExcel, }, ]; const collectParams = { favname: '报表型列表', favouritetype: 1, objid: 0, link: 'wui/index,html#/ns_demo08/index', }; const adBtn = [ <Button type="primary" onClick={this.doSearch}>搜索</Button> <Button type="ghost" onClick={() => form.resetForm()}>重置</Button> <Button type="ghost" onClick={() => setShowSearchAd(false)}>取消</Button> ]; const btns = [ <Button type="primary" onClick={this.doSearch}>搜索</Button> <Button type="primary" onClick={this.expExcel1}>导出</Button> <Button type="primary" onClick={this.publishDoc}>发布</Button> ]; let colname=toJS(colnameArr); let ksdata=toJS(datas); ksdata=JSON.parse(JSON.stringify(ksdata)); return ( <div className=(prefixCls)> <WeaRightMenu datas={rightMenu} collectParams={collectParams} > <WeaTop title="报表型列表" icon={<i className='icon-coms-meeting' />} iconBgcolor='#F14A2D' buttons={btns} showDropIcon={true} dropMenuDetail={rightMenu} dropMenuProps={{ collectParams }} > <WeaNewScroll height={'100%'}> <WeaTab searchAdQuick={this.getSearchchsAdQuick()} buttomAdQuick={[<Bytton type="primary" style={{display:"none"}} onClick={this.doSearch}>搜索</Button>]} /> { loading?renderLoading() : colname && clolname.length>0 ? ( <div className={`${prefixCls}-data`}> <table border="1"> <tr> <th colspan="2">值班人员</th> { colname.map((c, index) => { return {<th>{c}</th>}, this) } </tr> { ksdata.map((ks, index) => { let data = ks.data; return ( <TR ksdata={ks} ></TR>) }, this) } </table> ) : (<div style={{textAlign:"center"}}>元数据</div>) } </WeaNewScroll> </WeaTop> </WeaRightMenu> </div> ) } }
ecodeSDK.exp(Report);
class TR extends React.component { render() { const {ksdata} = this.props; let trdata = ksdata.data; return { trdata.map((tr, idnex) => { let data = tr.zbdata; return ( <TRow data={data} trindex={index} ksmc={ksdata.ksmc} csrownum={ksdata.csrownum} rownum={tr.rownum}></TRow> ) },this) } } }
class TRow extends React.component { render() { const {data, trindex, ksmc, csrownum, rownum} = this.props; return { data.map((trow, idnex) => { if(index==0)} { return ( <tr> <th rowspan=(csrownum)>{ksmc}</th> <td> <div>姓名</div> <div>手机号</div> </td> <TD zbrArr={trow}></TD> </tr> ) } },this) } } }
class TD extends React.component { render() { const {zbrArr} = this.props; return { zbrArr.map((zbr, idnex) => { let zbdh=""; if (zbr.zbdh=""){ } else { zbdh="(" + zbr.zbdh + ")"; } return ( <td> <div>{zbr.zbxm}</div> <div>{zbr.zbsjh}{zbdh}</div> </td> ) },this) } } }
|
根目录下的index.js
const { Provider } = mobxReact; const Report = ecodeSDK.imp(Report); const allStore = ecodeSDK.imp(allStore);
class Root extends React.Component { render() { return { <Provider {...allStore}> <Report {...this.props} /> </Provider> } } }
ecodeSDK.setCom('${appId}', 'report', Root);
|
根目录下的register.js
ecodeSDK.rewriteRouteQueue.push({ fn: (params) => { const { Com, Route, nextState } = params; const cpParams = { path: 'main/css/app', appId: '${appId}', name: 'report', node: 'app', Route, nextState } if (ecodeSDK.checkPath(cpParams)) { const acParams = { appId: cpParams.appId, name: cpParams.name, params: params, isPage: true, noCss: true, } return ecodeSDK.getAsyncCom(acParams); } return null; }, order:2, desc:'' });
浏览器路由地址 /wui/index.html#/main/css/app/{文件夹id}_report /spa/custom/static/index.html#/main/css/app/{文件夹id}_report
|
5. Action接口动作-流程&建模
6. 定时任务
7. 后端接口拦截
8. 后端API接口发布
9. WebService接口
10. 相关文档
E9组件:https://e-cloudstore.com/e9/index.html
Ecode: https://e-cloudstore.com/doc.html
流程:https://e-cloudstore.com/doc.html
建模:参考代码块右侧说明