You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
501 lines
15 KiB
501 lines
15 KiB
var express = require('express');
|
|
var router = express.Router();
|
|
var doSQL = require('../mysql/index').doSQL;
|
|
const axios = require('axios');
|
|
const { createProxyMiddleware, responseInterceptor } = require('http-proxy-middleware');
|
|
const fs = require("fs");
|
|
var path = require("path");
|
|
var config = require('../config');
|
|
|
|
const baseURL = config.camunda.base;
|
|
|
|
//1.获取最新流程定义列表
|
|
router.get('/engine-rest/process-definition', function(request, response) {
|
|
//查询流程总数量
|
|
axios.get(baseURL + '/engine-rest/process-definition/count?latestVersion=true').then(res=>{
|
|
let count = res.data.count;
|
|
doRequest(request).then(data=>{
|
|
response.send({
|
|
code: 200,
|
|
data: {
|
|
list: data,
|
|
total: count
|
|
}
|
|
});
|
|
}).catch(err=>{
|
|
response.send(JSON.stringify({
|
|
code: 600,
|
|
message: err
|
|
}));
|
|
})
|
|
})
|
|
|
|
});
|
|
|
|
//2.获取流程实例列表
|
|
router.get('/engine-rest/history/process-instance', function(request, response) {
|
|
let processDefinitionKey = request.query.processDefinitionKey;
|
|
let finished = request.query.finished;
|
|
//查询实例总数量
|
|
axios.get(baseURL + `/engine-rest/history/process-instance/count`,{
|
|
params: {
|
|
processDefinitionKey,
|
|
finished
|
|
}
|
|
}).then(res=>{
|
|
let count = res.data.count;
|
|
doRequest(request).then(data=>{
|
|
response.send({
|
|
code: 200,
|
|
data: {
|
|
list: data,
|
|
total: count
|
|
}
|
|
});
|
|
}).catch(err=>{
|
|
response.send(JSON.stringify({
|
|
code: 600,
|
|
message: err
|
|
}));
|
|
})
|
|
})
|
|
|
|
});
|
|
|
|
//3.获取流程实例任务列表
|
|
router.get('/engine-rest/history/task', function(request, response) {
|
|
let processInstanceId = request.query.processInstanceId;
|
|
//查询实例任务总数量
|
|
axios.get(baseURL + `/engine-rest/history/task/count?processInstanceId=${processInstanceId}`).then(res=>{
|
|
let count = res.data.count;
|
|
doRequest(request).then(data=>{
|
|
//如果任务已完成,获取任务评论
|
|
let promiseArr = [];
|
|
data.forEach(item=> {
|
|
promiseArr.push(axios.get(baseURL + `/engine-rest/task/${item.id}/comment`))
|
|
})
|
|
Promise.all(promiseArr).then(res=>{
|
|
res.forEach((item,index)=> {
|
|
data[index].comment = item.data;
|
|
})
|
|
response.send({
|
|
code: 200,
|
|
data: {
|
|
list: data,
|
|
total: count
|
|
}
|
|
});
|
|
})
|
|
}).catch(err=>{
|
|
response.send(JSON.stringify({
|
|
code: 600,
|
|
message: err
|
|
}));
|
|
})
|
|
})
|
|
|
|
});
|
|
|
|
//4.添加候选人
|
|
router.post('/engine-rest/task/:taskId/identity-links', function(request, response) {
|
|
doRequest(request).then(data=>{
|
|
response.send({
|
|
code: 200
|
|
});
|
|
}).catch(err=>{
|
|
response.send(JSON.stringify({
|
|
code: 600,
|
|
message: err
|
|
}));
|
|
})
|
|
});
|
|
|
|
//5.移除候选人
|
|
router.post('/engine-rest/task/:taskId/identity-links/delete', function(request, response) {
|
|
doRequest(request).then(data=>{
|
|
response.send({
|
|
code: 200
|
|
});
|
|
}).catch(err=>{
|
|
response.send(JSON.stringify({
|
|
code: 600,
|
|
message: err
|
|
}));
|
|
})
|
|
});
|
|
|
|
function getProcessInstanceDetail(taskInfo,id) {
|
|
return new Promise((resolve, reject) => {
|
|
const query = `
|
|
SELECT wi.form_id, wi.process_key, wi.form_values, wi.process_instance_id, wi.status, wf.form_name, wf.form_desc, wf.form_path
|
|
FROM workflow_instance wi
|
|
LEFT JOIN workflow_form wf ON wf.id = wi.form_id
|
|
WHERE process_instance_id = ?
|
|
`;
|
|
const params = [id];
|
|
doSQL(query, params).then(res=>{
|
|
let data = res.data[0];
|
|
axios.get(baseURL + `/engine-rest/process-definition/${taskInfo.processDefinitionId}`)
|
|
.then(res=>{
|
|
let processInfo = res.data;
|
|
if(data){
|
|
try {
|
|
let form = require(path.join(__dirname, '../' + data.form_path));
|
|
resolve({
|
|
processName: processInfo.name,
|
|
...taskInfo,
|
|
...data,
|
|
form: form.formFields
|
|
})
|
|
} catch (error) {
|
|
resolve({
|
|
processName: processInfo.name,
|
|
...taskInfo,
|
|
...data
|
|
})
|
|
}
|
|
|
|
// fs.readFile(path.join(__dirname, '../' + data.form_path), 'utf-8', function(err, form) {
|
|
// if (err) {
|
|
// resolve({
|
|
// processName: processInfo.name,
|
|
// ...taskInfo,
|
|
// ...data
|
|
// })
|
|
// } else {
|
|
// resolve({
|
|
// processName: processInfo.name,
|
|
// ...taskInfo,
|
|
// ...data,
|
|
// form: JSON.parse(form)
|
|
// })
|
|
// }
|
|
// });
|
|
} else {
|
|
resolve({
|
|
processName: processInfo.name,
|
|
...taskInfo
|
|
})
|
|
}
|
|
})
|
|
.catch(error => {
|
|
// 处理 axios 错误
|
|
resolve({
|
|
...taskInfo
|
|
})
|
|
});
|
|
}).catch(error => {
|
|
// 处理 doSQL 错误
|
|
reject(error);
|
|
});
|
|
});
|
|
}
|
|
//6.查询候选任务
|
|
router.get('/engine-rest/task', async function(request, response) {
|
|
let candidateUser = request.query.candidateUser;
|
|
let assignee = request.query.assignee;
|
|
let candidateGroup = request.query.candidateGroup;
|
|
try {
|
|
let count = 0;
|
|
let primiseArr = [];
|
|
if(!candidateUser && !assignee && !candidateGroup){
|
|
res = await axios.get(baseURL + '/engine-rest/task/count');
|
|
count = res.data.count;
|
|
const data = await doRequest(request);
|
|
// 按照 created 字段倒序排序
|
|
data.sort((a, b) => new Date(b.created) - new Date(a.created));
|
|
data.forEach(item => {
|
|
primiseArr.push(getProcessInstanceDetail(item, item.processInstanceId));
|
|
});
|
|
}else{
|
|
// 如果传入了参数,分别查询
|
|
let requests = [];
|
|
if (candidateUser) {
|
|
requests.push(axios.get(baseURL + '/engine-rest/task', {
|
|
params: { candidateUser: candidateUser }
|
|
}));
|
|
}
|
|
if (assignee) {
|
|
requests.push(axios.get(baseURL + '/engine-rest/task', {
|
|
params: { assignee: assignee }
|
|
}));
|
|
}
|
|
if (candidateGroup) {
|
|
requests.push(axios.get(baseURL + '/engine-rest/task', {
|
|
params: { candidateGroup: candidateGroup }
|
|
}));
|
|
}
|
|
|
|
// 等待所有请求完成
|
|
const responses = await Promise.all(requests);
|
|
|
|
// 合并所有请求的结果
|
|
let tasks = [];
|
|
responses.forEach(response => {
|
|
tasks = tasks.concat(response.data);
|
|
});
|
|
|
|
// 去重
|
|
const uniqueTasks = tasks.filter((task, index, self) =>
|
|
index === self.findIndex((t) => (
|
|
t.id === task.id
|
|
))
|
|
);
|
|
// 按照 created 字段倒序排序
|
|
uniqueTasks.sort((a, b) => new Date(b.created) - new Date(a.created));
|
|
|
|
// 分页处理
|
|
let firstResult = request.query.firstResult || 0;
|
|
let maxResults = request.query.maxResults || 10;
|
|
const paginatedTasks = uniqueTasks.slice(firstResult, firstResult + maxResults);
|
|
|
|
// 获取任务总数
|
|
count = uniqueTasks.length;
|
|
|
|
// 获取任务详情
|
|
paginatedTasks.forEach(item => {
|
|
primiseArr.push(getProcessInstanceDetail(item, item.processInstanceId));
|
|
});
|
|
}
|
|
|
|
const results = await Promise.all(primiseArr);
|
|
response.send({
|
|
code: 200,
|
|
data: {
|
|
list: results,
|
|
total: count
|
|
}
|
|
});
|
|
} catch (err) {
|
|
console.error('Error:', err);
|
|
response.send({
|
|
code: 600,
|
|
message: err.message || '处理请求时发生错误'
|
|
});
|
|
}
|
|
});
|
|
|
|
//7.领取任务
|
|
router.post('/engine-rest/task/:taskId/claim', function(request, response) {
|
|
doRequest(request).then(data=>{
|
|
response.send({
|
|
code: 200
|
|
});
|
|
}).catch(err=>{
|
|
response.send(JSON.stringify({
|
|
code: 600,
|
|
message: err
|
|
}));
|
|
})
|
|
});
|
|
//8.取消执行人
|
|
router.post('/engine-rest/task/:taskId/unclaim', function(request, response) {
|
|
doRequest(request).then(data=>{
|
|
response.send({
|
|
code: 200
|
|
});
|
|
}).catch(err=>{
|
|
response.send(JSON.stringify({
|
|
code: 600,
|
|
message: err
|
|
}));
|
|
})
|
|
});
|
|
//9.执行任务
|
|
router.post('/engine-rest/task/:taskId/complete', function(request, response) {
|
|
doRequest(request).then(data=>{
|
|
response.send({
|
|
code: 200
|
|
});
|
|
}).catch(err=>{
|
|
response.send(JSON.stringify({
|
|
code: 600,
|
|
message: err
|
|
}));
|
|
})
|
|
});
|
|
//10.设置任务评论
|
|
router.post('/engine-rest/task/:taskId/comment/create', function(request, response) {
|
|
doRequest(request).then(data=>{
|
|
response.send({
|
|
code: 200
|
|
});
|
|
}).catch(err=>{
|
|
response.send(JSON.stringify({
|
|
code: 600,
|
|
message: err
|
|
}));
|
|
})
|
|
});
|
|
|
|
/**
|
|
* 创建自定义流程实例
|
|
* @description 本系统内生成流程实例,并启动camunda流程--------标准需要开事务
|
|
* @
|
|
*/
|
|
router.post('/start', function(request, response) {
|
|
//1. 启动camunda流程
|
|
let processKey = request.body.processKey;
|
|
let createUser = request.body.createUser;
|
|
//1.本系统内生成流程实例
|
|
let formId = request.body.formId;
|
|
let formValues = request.body.formValues;
|
|
const query = `
|
|
INSERT INTO workflow_instance (form_id, process_key, process_instance_id, form_values, status, create_user)
|
|
VALUES (?, ?, NULL, ?, 1, ?)
|
|
`;
|
|
const params = [formId, processKey, formValues, createUser];
|
|
|
|
doSQL(query,params).then(res=>{
|
|
if(!res.error){
|
|
//获取刚刚插入的id
|
|
const insertId = res.data.insertId;
|
|
axios.post(baseURL + `/engine-rest/process-definition/key/${processKey}/start`, {
|
|
businessKey: insertId
|
|
}).then(res=>{
|
|
let processInstanceId = res.data.id;
|
|
if( processInstanceId ){
|
|
//2. 创建本系统内的流程实例包含form_id,process_instance_id,status
|
|
const query = `UPDATE workflow_instance SET process_instance_id = ? WHERE id = ?`;
|
|
const params = [processInstanceId, insertId];
|
|
|
|
doSQL(query, params).then(res=>{
|
|
if(!res.error){
|
|
response.send({
|
|
code: 200,
|
|
message: '启动流程成功'
|
|
});
|
|
}else{
|
|
const query = `delete from workflow_instance where id = ?`;
|
|
const params = [insertId];
|
|
doSQL(query, params).then(res=>{
|
|
response.send({
|
|
code: 600,
|
|
message: '启动流程失败'
|
|
});
|
|
})
|
|
}
|
|
})
|
|
}else {
|
|
response.send({
|
|
code: 600,
|
|
message: '启动流程失败'
|
|
});
|
|
}
|
|
})
|
|
}else{
|
|
response.send({
|
|
code: 600,
|
|
message: '启动流程失败'
|
|
});
|
|
}
|
|
})
|
|
});
|
|
|
|
|
|
router.use('/', createProxyMiddleware({
|
|
target: baseURL,
|
|
changeOrigin: true, // 确保请求头正确
|
|
pathRewrite: {
|
|
'^/process': '', // 去掉路径前缀
|
|
},
|
|
timeout: 60000, // 设置超时为60秒
|
|
selfHandleResponse: true,
|
|
on: {
|
|
// proxyReq: (proxyReq, req, res) => {
|
|
// console.log('代理请求发送到目标服务器:', proxyReq.path);
|
|
// console.log('请求头:', proxyReq.getHeaders());
|
|
// },
|
|
proxyRes: responseInterceptor(async (responseBuffer, proxyRes, req, res) => {
|
|
const response = responseBuffer.toString('utf8'); // convert buffer to string
|
|
let originalData;
|
|
try {
|
|
originalData = response ? JSON.parse(response) : {}; // parse JSON
|
|
} catch (error) {
|
|
originalData = {
|
|
code: 500,
|
|
message: 'Error parsing response',
|
|
data: response
|
|
};
|
|
}
|
|
|
|
//异常特殊处理
|
|
if(originalData?.message?.includes('ENGINE-03076')){
|
|
return JSON.stringify({
|
|
code: 503,
|
|
msg: '流程存在启用的实例,无法删除!'
|
|
});
|
|
}else{
|
|
let statusCode = proxyRes.statusCode == 204 ? 200 : proxyRes.statusCode;
|
|
const wrappedData = {
|
|
code: originalData.code || statusCode, // 包含 HTTP 状态码
|
|
data: originalData.data || originalData, // 返回的实际数据
|
|
timestamp: new Date().toISOString(), // 添加时间戳
|
|
};
|
|
return JSON.stringify(wrappedData);
|
|
}
|
|
}),
|
|
error: (err, req, res) => {
|
|
console.error('Proxy error:', err);
|
|
res.status(500).json({
|
|
code: 500,
|
|
message: 'Proxy request failed',
|
|
error: err.message
|
|
});
|
|
}
|
|
},
|
|
}));
|
|
|
|
|
|
// function proxyDataResolver(fn) {
|
|
// return proxy(baseURL + '', {
|
|
// proxyReqPathResolver: function (req) {
|
|
// // 移除请求路径中的开头 /process
|
|
// return req.url.replace(/^\/process/, '');
|
|
// },
|
|
// proxyReqOptDecorator: function(proxyReqOpts, req) {
|
|
// // 确保请求头中包含正确的 Content-Type
|
|
// if (req.headers['content-type']) {
|
|
// proxyReqOpts.headers['Content-Type'] = req.headers['content-type'];
|
|
// }
|
|
// return proxyReqOpts;
|
|
// },
|
|
// userResDecorator: function (proxyRes, proxyResData, req, res) {
|
|
// try {
|
|
// // 处理返回的结果
|
|
// const originalData = JSON.parse(proxyResData.toString('utf8')); // 解析 JSON
|
|
// const wrappedData = {
|
|
// code: originalData.code || proxyRes.statusCode, // 包含 HTTP 状态码
|
|
// data: fn ? fn(originalData) : (originalData.data || originalData), // 返回的实际数据
|
|
// timestamp: new Date().toISOString(), // 添加时间戳
|
|
// };
|
|
// return JSON.stringify(wrappedData); // 转换为字符串返回
|
|
// } catch (error) {
|
|
// console.error('Error processing response:', error);
|
|
// return proxyResData; // 如果解析失败,直接返回原始数据
|
|
// }
|
|
// },
|
|
// })
|
|
// }
|
|
|
|
function doRequest(req) {
|
|
return new Promise((resolve, reject) => {
|
|
// 构建请求选项
|
|
const url = baseURL + `${req.url.replace(/^\/process/, '')}`;
|
|
axios({
|
|
url: url,
|
|
method: req.method,
|
|
data: req.body,
|
|
})
|
|
.then(response => {
|
|
resolve(response.data,response)
|
|
})
|
|
.catch(error => {
|
|
reject(error)
|
|
});
|
|
|
|
});
|
|
}
|
|
|
|
|
|
module.exports = router;
|
|
|