diff --git a/src/api/vi/project.js b/src/api/vi/project.js index 0eddc50..be5dba4 100644 --- a/src/api/vi/project.js +++ b/src/api/vi/project.js @@ -42,3 +42,30 @@ export function delProject(projectId) { method: 'delete' }) } + +export function getExecuteRunParams(projectId) { + return request({ + url: '/vi/project/queryExecuteRunParams', + method: 'get', + params: { + projectId + } + }) +} + +export function projectExecute(data) { + return request({ + url: '/vi/project/execute', + method: 'post', + data + }) +} + +export function queryExecuteInstId(projectId) { + return request({ + url: `/vi/project/queryExecuteInstId/${projectId}`, + method: 'get', + + }) +} + diff --git a/src/utils/flow.js b/src/utils/flow.js index f76f4b1..94f7557 100644 --- a/src/utils/flow.js +++ b/src/utils/flow.js @@ -81,11 +81,11 @@ export const getStartNodeFormData = () => { return data } -export const addValueProperty = (data) => { +export const addValueProperty = (data, schemeId = '') => { // 处理单个对象或对象数组 const processItem = (item, index, path) => { // 根据类型设置默认值 - item.value = ''; + item.value = item.name === 'schemeId' ? schemeId : ''; item.propPath = `${path}.${index}.` if (item.type.includes('array') && !item.type.includes('object')) { const type = item.type.match(/<([^>]+)>/)[1] diff --git a/src/utils/request.js b/src/utils/request.js index 2b10149..218e236 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -1,152 +1,153 @@ -import axios from 'axios' -import { ElNotification , ElMessageBox, ElMessage, ElLoading } from 'element-plus' -import { getToken } from '@/utils/auth' -import errorCode from '@/utils/errorCode' -import { tansParams, blobValidate } from '@/utils/ruoyi' -import cache from '@/plugins/cache' -import { saveAs } from 'file-saver' -import useUserStore from '@/store/modules/user' - -let downloadLoadingInstance; -// 是否显示重新登录 -export let isRelogin = { show: false }; - -axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8' -// 创建axios实例 -const service = axios.create({ - // axios中请求配置有baseURL选项,表示请求URL公共部分 - baseURL: import.meta.env.VITE_APP_BASE_API, - // 超时 - timeout: 100000 -}) - -// request拦截器 -service.interceptors.request.use(config => { - // 是否需要设置 token - const isToken = (config.headers || {}).isToken === false - // 是否需要防止数据重复提交 - const isRepeatSubmit = (config.headers || {}).repeatSubmit === false - if (getToken() && !isToken) { - config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改 - } - // get请求映射params参数 - if (config.method === 'get' && config.params) { - let url = config.url + '?' + tansParams(config.params); - url = url.slice(0, -1); - config.params = {}; - config.url = url; - } - if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) { - const requestObj = { - url: config.url, - data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data, - time: new Date().getTime() - } - const requestSize = Object.keys(JSON.stringify(requestObj)).length; // 请求数据大小 - const limitSize = 5 * 1024 * 1024; // 限制存放数据5M - if (requestSize >= limitSize) { - console.warn(`[${config.url}]: ` + '请求数据大小超出允许的5M限制,无法进行防重复提交验证。') - return config; - } - const sessionObj = cache.session.getJSON('sessionObj') - if (sessionObj === undefined || sessionObj === null || sessionObj === '') { - cache.session.setJSON('sessionObj', requestObj) - } else { - const s_url = sessionObj.url; // 请求地址 - const s_data = sessionObj.data; // 请求数据 - const s_time = sessionObj.time; // 请求时间 - const interval = 500; // 间隔时间(ms),小于此时间视为重复提交 - if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) { - const message = '数据正在处理,请勿重复提交'; - console.warn(`[${s_url}]: ` + message) - return Promise.reject(new Error(message)) - } else { - cache.session.setJSON('sessionObj', requestObj) - } - } - } - return config -}, error => { - console.log(error) - Promise.reject(error) -}) - -// 响应拦截器 -service.interceptors.response.use(res => { - // 未设置状态码则默认成功状态 - const code = res.data.code || 200; - // 获取错误信息 - const msg = errorCode[code] || res.data.msg || errorCode['default'] - // 二进制数据则直接返回 - if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') { - return res.data - } - if (code === 401) { - if (!isRelogin.show) { - isRelogin.show = true; - ElMessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning' }).then(() => { - isRelogin.show = false; - useUserStore().logOut().then(() => { - location.href = '/index'; - }) - }).catch(() => { - isRelogin.show = false; - }); - } - return Promise.reject('无效的会话,或者会话已过期,请重新登录。') - } else if (code === 500) { - ElMessage({ message: msg, type: 'error' }) - return Promise.reject(new Error(msg)) - } else if (code === 601) { - ElMessage({ message: msg, type: 'warning' }) - return Promise.reject(new Error(msg)) - } else if (code !== 200) { - ElNotification.error({ title: msg }) - return Promise.reject('error') - } else { - return Promise.resolve(res.data) - } - }, - error => { - console.log('err' + error) - let { message } = error; - if (message == "Network Error") { - message = "后端接口连接异常"; - } else if (message.includes("timeout")) { - message = "系统接口请求超时"; - } else if (message.includes("Request failed with status code")) { - message = "系统接口" + message.substr(message.length - 3) + "异常"; - } - ElMessage({ message: message, type: 'error', duration: 5 * 1000 }) - return Promise.reject(error) - } -) - -// 通用下载方法 -export function download(url, params, filename, config) { - downloadLoadingInstance = ElLoading.service({ text: "正在下载数据,请稍候", background: "rgba(0, 0, 0, 0.7)", }) - return service.post(url, params, { - transformRequest: [(params) => { return tansParams(params) }], - headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, - responseType: 'blob', - ...config - }).then(async (data) => { - const isBlob = blobValidate(data); - if (isBlob) { - const blob = new Blob([data]) - saveAs(blob, filename) - } else { - const resText = await data.text(); - const rspObj = JSON.parse(resText); - const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default'] - ElMessage.error(errMsg); - } - downloadLoadingInstance.close(); - }).catch((r) => { - console.error(r) - ElMessage.error('下载文件出现错误,请联系管理员!') - downloadLoadingInstance.close(); - }) -} - -export default service +import axios from 'axios' +import { ElNotification , ElMessageBox, ElMessage, ElLoading } from 'element-plus' +import { getToken } from '@/utils/auth' +import errorCode from '@/utils/errorCode' +import { tansParams, blobValidate } from '@/utils/ruoyi' +import cache from '@/plugins/cache' +import { saveAs } from 'file-saver' +import useUserStore from '@/store/modules/user' + +let downloadLoadingInstance; +// 是否显示重新登录 +export let isRelogin = { show: false }; + +axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8' +// 创建axios实例 +const service = axios.create({ + // axios中请求配置有baseURL选项,表示请求URL公共部分 + baseURL: import.meta.env.VITE_APP_BASE_API, + // 超时 + timeout: 100000 +}) + +// request拦截器 +service.interceptors.request.use(config => { + // 是否需要设置 token + const isToken = (config.headers || {}).isToken === false + // 是否需要防止数据重复提交 + const isRepeatSubmit = (config.headers || {}).repeatSubmit === false + if (getToken() && !isToken) { + config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改 + } + // get请求映射params参数 + if (config.method === 'get' && config.params) { + let url = config.url + '?' + tansParams(config.params); + url = url.slice(0, -1); + config.params = {}; + config.url = url; + } + if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) { + const requestObj = { + url: config.url, + data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data, + time: new Date().getTime() + } + const requestSize = Object.keys(JSON.stringify(requestObj)).length; // 请求数据大小 + const limitSize = 5 * 1024 * 1024; // 限制存放数据5M + if (requestSize >= limitSize) { + console.warn(`[${config.url}]: ` + '请求数据大小超出允许的5M限制,无法进行防重复提交验证。') + return config; + } + const sessionObj = cache.session.getJSON('sessionObj') + if (sessionObj === undefined || sessionObj === null || sessionObj === '') { + cache.session.setJSON('sessionObj', requestObj) + } else { + const s_url = sessionObj.url; // 请求地址 + const s_data = sessionObj.data; // 请求数据 + const s_time = sessionObj.time; // 请求时间 + const interval = 500; // 间隔时间(ms),小于此时间视为重复提交 + if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) { + const message = '数据正在处理,请勿重复提交'; + console.warn(`[${s_url}]: ` + message) + return Promise.reject(new Error(message)) + } else { + cache.session.setJSON('sessionObj', requestObj) + } + } + } + return config +}, error => { + console.log(error) + Promise.reject(error) +}) + +// 响应拦截器 +service.interceptors.response.use(res => { + console.log('res', res) + // 未设置状态码则默认成功状态 + const code = res.data.code || 200; + // 获取错误信息 + const msg = errorCode[code] || res.data.msg || errorCode['default'] + // 二进制数据则直接返回 + if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') { + return res.data + } + if (code === 401) { + if (!isRelogin.show) { + isRelogin.show = true; + ElMessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning' }).then(() => { + isRelogin.show = false; + useUserStore().logOut().then(() => { + location.href = '/index'; + }) + }).catch(() => { + isRelogin.show = false; + }); + } + return Promise.reject('无效的会话,或者会话已过期,请重新登录。') + } else if (code === 500) { + ElMessage({ message: msg, type: 'error' }) + return Promise.reject(new Error(msg)) + } else if (code === 601) { + ElMessage({ message: msg, type: 'warning' }) + return Promise.reject(new Error(msg)) + } else if (code !== 200) { + ElNotification.error({ title: msg }) + return Promise.reject('error') + } else { + return Promise.resolve(res.data) + } + }, + error => { + console.log('err' + error) + let { message } = error; + if (message == "Network Error") { + message = "后端接口连接异常"; + } else if (message.includes("timeout")) { + message = "系统接口请求超时"; + } else if (message.includes("Request failed with status code")) { + message = "系统接口" + message.substr(message.length - 3) + "异常"; + } + ElMessage({ message: message, type: 'error', duration: 5 * 1000 }) + return Promise.reject(error) + } +) + +// 通用下载方法 +export function download(url, params, filename, config) { + downloadLoadingInstance = ElLoading.service({ text: "正在下载数据,请稍候", background: "rgba(0, 0, 0, 0.7)", }) + return service.post(url, params, { + transformRequest: [(params) => { return tansParams(params) }], + headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, + responseType: 'blob', + ...config + }).then(async (data) => { + const isBlob = blobValidate(data); + if (isBlob) { + const blob = new Blob([data]) + saveAs(blob, filename) + } else { + const resText = await data.text(); + const rspObj = JSON.parse(resText); + const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default'] + ElMessage.error(errMsg); + } + downloadLoadingInstance.close(); + }).catch((r) => { + console.error(r) + ElMessage.error('下载文件出现错误,请联系管理员!') + downloadLoadingInstance.close(); + }) +} + +export default service diff --git a/src/views/test/configs/Run.vue b/src/views/test/configs/Run.vue index f93f72a..95d1b4b 100644 --- a/src/views/test/configs/Run.vue +++ b/src/views/test/configs/Run.vue @@ -1,172 +1,172 @@ - - + + diff --git a/src/views/vi/testProject/Run.vue b/src/views/vi/testProject/Run.vue new file mode 100644 index 0000000..eede135 --- /dev/null +++ b/src/views/vi/testProject/Run.vue @@ -0,0 +1,164 @@ + + \ No newline at end of file diff --git a/src/views/vi/testProject/index.vue b/src/views/vi/testProject/index.vue index 148c06b..1af93cc 100644 --- a/src/views/vi/testProject/index.vue +++ b/src/views/vi/testProject/index.vue @@ -171,7 +171,7 @@ - + @@ -345,6 +352,41 @@ + + + + + +
+
{{ item.name }}
+
+ + + +
+
+
+
@@ -358,6 +400,9 @@ import { } from "@/api/vi/project"; import TableSearch from "@/components/TableSearch/index.vue"; import { useContainerHeight } from "@/hooks/tableHeight"; +import Run from "./Run.vue"; +import { getExecuteRunParams, queryExecuteInstId } from "@/api/vi/project.js" +import { appendParamsToPath } from "@/utils/fn.js"; const topContainerRef = ref(); const containerHeight = useContainerHeight(topContainerRef); @@ -538,10 +583,64 @@ const handleSetting = (row) => { router.push('/vi/plan/index/' + row.projectId) } +const executeOpen = ref(false); +const currentRow = ref(undefined); + const handleExecute = (row) => { - console.log('暂未开发') + currentRow.value = row; + executeOpen.value = true; } +const currentLog = ref({}); +const openDashboard = ref(false); +const taskRightList = ref([]); +const lastInstId = ref('') + +const handleOpenDashboard = (row) => { + openDashboard.value = true; + currentLog.value = row; + getRightTaskList(row.projectId); + getExecuteInstId(row.projectId) +} + +//获取右侧编排数据 +const getRightTaskList = (projectId) => { + getExecuteRunParams(projectId).then((response) => { + taskRightList.value = + response.data?.map((item) => { + return { + name: item.schemeName, + id: item.itemId, + }; + }) || []; + }); +}; + +const getExecuteInstId = (projectId) => { + queryExecuteInstId(projectId).then((res) => { + console.log('res', res) + lastInstId.value = res.data + }) +} + +// 取消按钮 +function handleClose() { + openDashboard.value = false; +} + +const handleLogicFlow = (item) => { + const params = { + instId: lastInstId.value, + taskId: currentLog.value.projectId, + itemId: item.id, + name: item.name, + state: "0", + isLog: true, + }; + + const fullPath = appendParamsToPath("/flow", params); + window.open(fullPath, "_blank"); +}; onMounted(() => { getList(); });