泛微ECODE实现流程界面增加组件WeaSlideModal同时通过API获取建模预设流程节点数据
·
运行环境:泛微E9,ecode版本为1.9.14
实现效果:在流程界面,依流程名称/流程节点,获取各个节点的配置说明内容,如下:

第一步:建模建表如下,生成API接口(略),供调用,

第二步:创建ECODE项目(在流程界面组件用滑块)
2.1 ecode建好项目(按标准ecode提供的案例)
2.2 这些文件上做好设置

2.3各代码的具体代码:
样式:index.css
.wea-new-top-req-content{font-size:14px;color:rgb(61,126,247);font-weight: 400;}
配置:config.js
const configs={
wfids:[535, 1645, ], //多个流程id逗号隔开
};
ecodeSDK.setCom("${appId}","configs",configs);
配置要加载的页面:register.js
const configs = ecodeSDK.getCom('${appId}', 'configs')//获取对应的appid
let isRun = true;
ecodeSDK.overwritePropsFnQueueMapSet('WeaReqTop', {
fn: (newProps) => {
const { hash } = window.location//获取当前页面的URL
if (!~hash.indexOf('/main/workflow/req')) return newProps;
if (!window.wfform) return newProps;
let baseInfo = wfform.getBaseInfo() // 获取流程基础信息(包含workflowid、jdid等)
if (!configs.wfids.includes(Number(baseInfo.workflowid))) return newProps;
if (isRun) {
let timer1 = setTimeout(() => {
if ($('.wea-new-top-req-content').length > 0) {
$('.wea-new-top-req-content').prepend('<div id="wfRightInfo"></div>');
const acParams = {
appId: 'ac6865876e5e4ea9ab2e2880894f18de',
name: 'WfCustomInfoCopy',
// 传递流程基础信息作为组件参数(供接口调用使用)
params: {
workflowid: baseInfo.workflowid,
// jdid: baseInfo.nodeid, // 假设baseInfo包含jdid(流程实例ID)
// lc: baseInfo.workflowid, // 假设baseInfo包含(流程节点相关)
operator: baseInfo.creatorid // 假设使用创建者ID作为操作人
},
isPage: false,
noCss: true,
}
ReactDOM.render(ecodeSDK.getAsyncCom(acParams), document.getElementById('wfRightInfo'))
clearTimeout(timer1)
}
}, 10);
isRun = false;
}
return newProps;
}
})
加载的页面内容:index.js
const { WeaTools, WeaSlideModal } = ecCom;
const { callApi } = WeaTools;
class WfCustomInfoCopy extends React.Component {
constructor(props) {
super(props);
this.state = {
visible: true,
data: null, // 接口返回数据
loading: true, // 加载状态
error: null // 错误信息
};
}
componentDidMount() {
// 组件挂载后调用接口
this.executeRequest();
}
// MD5加密工具函数(保持不变)
md5(string) {
function rotateLeft(lValue, iShiftBits) {
return (lValue << iShiftBits) | (lValue >>> (32 - iShiftBits));
}
function addUnsigned(lX, lY) {
let lX4, lY4, lX8, lY8, lResult;
lX8 = (lX & 0x80000000);
lY8 = (lY & 0x80000000);
lX4 = (lX & 0x40000000);
lY4 = (lY & 0x40000000);
lResult = (lX & 0x3FFFFFFF) + (lY & 0x3FFFFFFF);
if (lX4 & lY4) return (lResult ^ 0x80000000 ^ lX8 ^ lY8);
if (lX4 | lY4) {
if (lResult & 0x40000000) return (lResult ^ 0xC0000000 ^ lX8 ^ lY8);
else return (lResult ^ 0x40000000 ^ lX8 ^ lY8);
} else return (lResult ^ lX8 ^ lY8);
}
function F(x, y, z) { return (x & y) | ((~x) & z); }
function G(x, y, z) { return (x & z) | (y & (~z)); }
function H(x, y, z) { return (x ^ y ^ z); }
function I(x, y, z) { return (y ^ (x | (~z))); }
function FF(a, b, c, d, x, s, ac) {
a = addUnsigned(a, addUnsigned(addUnsigned(F(b, c, d), x), ac));
return addUnsigned(rotateLeft(a, s), b);
}
function GG(a, b, c, d, x, s, ac) {
a = addUnsigned(a, addUnsigned(addUnsigned(G(b, c, d), x), ac));
return addUnsigned(rotateLeft(a, s), b);
}
function HH(a, b, c, d, x, s, ac) {
a = addUnsigned(a, addUnsigned(addUnsigned(H(b, c, d), x), ac));
return addUnsigned(rotateLeft(a, s), b);
}
function II(a, b, c, d, x, s, ac) {
a = addUnsigned(a, addUnsigned(addUnsigned(I(b, c, d), x), ac));
return addUnsigned(rotateLeft(a, s), b);
}
function convertToWordArray(string) {
let lWordCount;
const lMessageLength = string.length;
const lNumberOfWordsTemp1 = lMessageLength + 8;
const lNumberOfWordsTemp2 = (lNumberOfWordsTemp1 - (lNumberOfWordsTemp1 % 64)) / 64;
const lNumberOfWords = (lNumberOfWordsTemp2 + 1) * 16;
const lWordArray = Array(lNumberOfWords - 1);
let lBytePosition = 0;
let lByteCount = 0;
while (lByteCount < lMessageLength) {
lWordCount = (lByteCount - (lByteCount % 4)) / 4;
lBytePosition = (lByteCount % 4) * 8;
lWordArray[lWordCount] = (lWordArray[lWordCount] | (string.charCodeAt(lByteCount) << lBytePosition));
lByteCount++;
}
lWordCount = (lByteCount - (lByteCount % 4)) / 4;
lBytePosition = (lByteCount % 4) * 8;
lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80 << lBytePosition);
lWordArray[lNumberOfWords - 2] = lMessageLength << 3;
lWordArray[lNumberOfWords - 1] = lMessageLength >>> 29;
return lWordArray;
}
function wordToHex(lValue) {
let WordToHexValue = "", WordToHexValueTemp = "", lByte, lCount;
for (lCount = 0; lCount <= 3; lCount++) {
lByte = (lValue >>> (lCount * 8)) & 255;
WordToHexValueTemp = "0" + lByte.toString(16);
WordToHexValue = WordToHexValue + WordToHexValueTemp.substr(WordToHexValueTemp.length - 2, 2);
}
return WordToHexValue;
}
let x = [], k, AA, BB, CC, DD, a, b, c, d;
const S11 = 7, S12 = 12, S13 = 17, S14 = 22;
const S21 = 5, S22 = 9, S23 = 14, S24 = 20;
const S31 = 4, S32 = 11, S33 = 16, S34 = 23;
const S41 = 6, S42 = 10, S43 = 15, S44 = 21;
string = unescape(encodeURIComponent(string));
x = convertToWordArray(string);
a = 0x67452301; b = 0xEFCDAB89; c = 0x98BADCFE; d = 0x10325476;
for (k = 0; k < x.length; k += 16) {
AA = a; BB = b; CC = c; DD = d;
a = FF(a, b, c, d, x[k + 0], S11, 0xD76AA478);
d = FF(d, a, b, c, x[k + 1], S12, 0xE8C7B756);
c = FF(c, d, a, b, x[k + 2], S13, 0x242070DB);
b = FF(b, c, d, a, x[k + 3], S14, 0xC1BDCEEE);
a = FF(a, b, c, d, x[k + 4], S11, 0xF57C0FAF);
d = FF(d, a, b, c, x[k + 5], S12, 0x4787C62A);
c = FF(c, d, a, b, x[k + 6], S13, 0xA8304613);
b = FF(b, c, d, a, x[k + 7], S14, 0xFD469501);
a = FF(a, b, c, d, x[k + 8], S11, 0x698098D8);
d = FF(d, a, b, c, x[k + 9], S12, 0x8B44F7AF);
c = FF(c, d, a, b, x[k + 10], S13, 0xFFFF5BB1);
b = FF(b, c, d, a, x[k + 11], S14, 0x895CD7BE);
a = FF(a, b, c, d, x[k + 12], S11, 0x6B901122);
d = FF(d, a, b, c, x[k + 13], S12, 0xFD987193);
c = FF(c, d, a, b, x[k + 14], S13, 0xA679438E);
b = FF(b, c, d, a, x[k + 15], S14, 0x49B40821);
a = GG(a, b, c, d, x[k + 1], S21, 0xF61E2562);
d = GG(d, a, b, c, x[k + 6], S22, 0xC040B340);
c = GG(c, d, a, b, x[k + 11], S23, 0x265E5A51);
b = GG(b, c, d, a, x[k + 0], S24, 0xE9B6C7AA);
a = GG(a, b, c, d, x[k + 5], S21, 0xD62F105D);
d = GG(d, a, b, c, x[k + 10], S22, 0x2441453);
c = GG(c, d, a, b, x[k + 15], S23, 0xD8A1E681);
b = GG(b, c, d, a, x[k + 4], S24, 0xE7D3FBC8);
a = GG(a, b, c, d, x[k + 9], S21, 0x21E1CDE6);
d = GG(d, a, b, c, x[k + 14], S22, 0xC33707D6);
c = GG(c, d, a, b, x[k + 3], S23, 0xF4D50D87);
b = GG(b, c, d, a, x[k + 8], S24, 0x455A14ED);
a = GG(a, b, c, d, x[k + 13], S21, 0xA9E3E905);
d = GG(d, a, b, c, x[k + 2], S22, 0xFCEFA3F8);
c = GG(c, d, a, b, x[k + 7], S23, 0x676F02D9);
b = GG(b, c, d, a, x[k + 12], S24, 0x8D2A4C8A);
a = HH(a, b, c, d, x[k + 5], S31, 0xFFFA3942);
d = HH(d, a, b, c, x[k + 8], S32, 0x8771F681);
c = HH(c, d, a, b, x[k + 11], S33, 0x6D9D6122);
b = HH(b, c, d, a, x[k + 14], S34, 0xFDE5380C);
a = HH(a, b, c, d, x[k + 1], S31, 0xA4BEEA44);
d = HH(d, a, b, c, x[k + 4], S32, 0x4BDECFA9);
c = HH(c, d, a, b, x[k + 7], S33, 0xF6BB4B60);
b = HH(b, c, d, a, x[k + 10], S34, 0xBEBFBC70);
a = HH(a, b, c, d, x[k + 13], S31, 0x289B7EC6);
d = HH(d, a, b, c, x[k + 0], S32, 0xEAA127FA);
c = HH(c, d, a, b, x[k + 3], S33, 0xD4EF3085);
b = HH(b, c, d, a, x[k + 6], S34, 0x4881D05);
a = HH(a, b, c, d, x[k + 9], S31, 0xD9D4D039);
d = HH(d, a, b, c, x[k + 12], S32, 0xE6DB99E5);
c = HH(c, d, a, b, x[k + 15], S33, 0x1FA27CF8);
b = HH(b, c, d, a, x[k + 2], S34, 0xC4AC5665);
a = II(a, b, c, d, x[k + 0], S41, 0xF4292244);
d = II(d, a, b, c, x[k + 7], S42, 0x432AFF97);
c = II(c, d, a, b, x[k + 14], S43, 0xAB9423A7);
b = II(b, c, d, a, x[k + 5], S44, 0xFC93A039);
a = II(a, b, c, d, x[k + 12], S41, 0x655B59C3);
d = II(d, a, b, c, x[k + 3], S42, 0x8F0CCC92);
c = II(c, d, a, b, x[k + 10], S43, 0xFFEFF47D);
b = II(b, c, d, a, x[k + 1], S44, 0x85845DD1);
a = II(a, b, c, d, x[k + 8], S41, 0x6FA87E4F);
d = II(d, a, b, c, x[k + 15], S42, 0xFE2CE6E0);
c = II(c, d, a, b, x[k + 6], S43, 0xA3014314);
b = II(b, c, d, a, x[k + 13], S44, 0x4E0811A1);
a = II(a, b, c, d, x[k + 4], S41, 0xF7537E82);
d = II(d, a, b, c, x[k + 11], S42, 0xBD3AF235);
c = II(c, d, a, b, x[k + 2], S43, 0x2AD7D2BB);
b = II(b, c, d, a, x[k + 9], S44, 0xEB86D391);
a = addUnsigned(a, AA);
b = addUnsigned(b, BB);
c = addUnsigned(c, CC);
d = addUnsigned(d, DD);
}
const temp = wordToHex(a) + wordToHex(b) + wordToHex(c) + wordToHex(d);
return temp.toLowerCase();
}
// 接口调用方法(保持不变)
async executeRequest() {
let baseInfo = wfform.getBaseInfo() // 获取流程基础信息(包含workflowid、jdid等)
const { jdid, lc, operator = '329' } = this.props; // 从props获取动态参数
const url = "http://ip:port/api/cube/restful/interface/getDataByPK/getWorkflowNodeMsg";
const now = new Date();
const currentDate = now.toISOString().split('T')[0];
const currentTime = now.toTimeString().substr(0, 8);
const year = now.getFullYear();
const month = String(now.getMonth() + 1).padStart(2, '0');
const day = String(now.getDate()).padStart(2, '0');
const hours = String(now.getHours()).padStart(2, '0');
const minutes = String(now.getMinutes()).padStart(2, '0');
const seconds = String(now.getSeconds()).padStart(2, '0');
const currentTimestamp = `${year}${month}${day}${hours}${minutes}${seconds}`;
// 系统标识和密码
const systemid = "xxx";//建模的
const d_password = "xxx";//建模的
// 准备header参数
const md5Source = systemid + d_password + currentTimestamp;
const md5Str = this.md5(md5Source); // 使用组件内的md5方法
const header = {
"systemid": systemid,
"currentDateTime": currentTimestamp,
"Md5": md5Str.toLowerCase()
};
// 准备请求数据(使用props传递的动态参数)
const paramDatajson = {
"header": header,
"pageInfo": {
"pageNo": 1,
"pageSize": 10
},
"mainTable": {
"jdid": baseInfo.nodeid, // 动态获取
"lc": baseInfo.workflowid, // 动态获取
},
"operationinfo": {
"operator": operator // 动态获取
}
};
console.log(lc);
console.log("===请求参数datajson===", paramDatajson);
try {
// 准备表单数据
const formData = new URLSearchParams();
formData.append('datajson', JSON.stringify(paramDatajson));
// 发送POST请求
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8'
},
body: formData
});
if (response.ok) {
// 处理返回信息
const res = await response.text();
console.log("请求成功", res);
// 假设返回的是JSON字符串,解析后存入state
const resData = JSON.parse(res);
this.setState({
data: resData,
loading: false,
error: null
});
} else {
const errorMsg = `获取数据失败,HTTP状态码: ${response.status}`;
console.error(errorMsg, currentDate, currentTime);
this.setState({
error: errorMsg,
loading: false
});
}
} catch (error) {
const errorMsg = "请求失败: " + error.message;
console.error(errorMsg, currentDate, currentTime);
this.setState({
error: errorMsg,
loading: false
});
}
}
render() {
const { visible, loading, error, data } = this.state;
// 动态渲染内容
let contentNode;
if (loading) {
contentNode = <div style={{ padding: '20px' }}>加载中...</div>;
} else if (error) {
contentNode = <div style={{ padding: '20px', color: 'red' }}>错误:{error}</div>;
} else if (data) {
// 解析嵌套的JSON结构以获取spnr值(兼容写法)
let spnrValue = null;
let parseError = null;
try {
// 第一层:解析result字段(它是一个JSON字符串)
const resultObj = JSON.parse(data.result || '{}');
// 第二层:从解析后的对象中获取spnr(使用传统判断方式,不依赖可选链)
if (resultObj && resultObj.mainTable && resultObj.mainTable.spnr) {
spnrValue = resultObj.mainTable.spnr;
}
} catch (e) {
parseError = `数据解析错误: ${e.message}`;
console.error(parseError);
}
// 根据解析结果展示内容
contentNode = (
<div style={{ padding: '15px', lineHeight: '1.6' }}>
{parseError ? (
<div style={{ color: 'red' }}>{parseError}</div>
) : spnrValue ? (
// 展示spnr值并保留换行格式
<div dangerouslySetInnerHTML={{ __html: spnrValue.replace(/\n/g, '<br>') }} />
) : (
<div style={{ color: '#666' }}>未配置节点审批要求</div>
)}
</div>
);
} else {
contentNode = <div style={{ padding: '20px' }}>暂无数据</div>;
}
return (
<div>
<WeaSlideModal
visible={visible}
top={12}
width={20}
height={20}
direction={'right'}
measure={'%'}
title={'当前节点审阅要求'}
content={contentNode}
onClose={() => this.setState({ visible: false })}
onAnimationEnd={() => console.log('onAnimationEnd')}
/>
</div>
);
}
}
ecodeSDK.setCom('${appId}', 'WfCustomInfoCopy', WfCustomInfoCopy);
发布看看效果:

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐


所有评论(0)