智慧工地前端
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

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;