diff --git a/src/api/appIns.ts b/src/api/appIns.ts new file mode 100644 index 0000000..4db89d7 --- /dev/null +++ b/src/api/appIns.ts @@ -0,0 +1,25 @@ +import axios from 'axios'; +import { apiResData } from '@/api/interface/index'; + +// 公共路径 +const urlPrefix = '/api/v1/bpms-workbench'; + +// 获取应用实例列表 +export function getInstances(data: any) { + return axios.post(`${urlPrefix}/appIns/page`, data); +} + +// 获取应用实例节点数据 +export function getNodeData(appId: string) { + return axios.get(`${urlPrefix}/appIns/${appId}/nodeData`); +} + +// 获取应用实例数据 +export function getInstanceDefinition(id: any) { + return axios.get(`${urlPrefix}/appIns/${id}/render`); +} + +// 获取应用实例资源 +export function getInstanceResData(id: any) { + return axios.get(`${urlPrefix}/appIns/${id}/res`); +} diff --git a/src/api/apps.ts b/src/api/apps.ts new file mode 100644 index 0000000..1dc9256 --- /dev/null +++ b/src/api/apps.ts @@ -0,0 +1,106 @@ +import axios from 'axios'; +import { apiResData, queryParams, applicationModel, publishApi, paramsT } from '@/api/interface/index'; + +// 公共路径 +const urlPrefix = '/api/v1/bpms-workbench'; +const runPrefix = '/api/v1/bpms-runtime'; + +// 个人分页 +export function getMyAppList(data: queryParams) { + return axios.post(`${urlPrefix}/apps/minePage`, data); +} + +// 公共分页 +export function getPubAppList(data: queryParams) { + return axios.post(`${urlPrefix}/apps/publicPage`, data); +} + +// 协调分页 +export function getTeamAppList(data: queryParams) { + return axios.post(`${urlPrefix}/apps/teamPage`, data); +} + +// 根据场景id分页 +export function getAppListBySceneId(data: queryParams) { + return axios.post(`${urlPrefix}/apps/page`, data); +} + +// 新增应用 +export function addApp(data: applicationModel) { + return axios.post(`${urlPrefix}/apps`, data); +} + +// 编辑应用 +export function editApp(data: applicationModel) { + return axios.put(`${urlPrefix}/apps`, data); +} + +// 删除应用 +export function deleteApp(id: string) { + return axios.delete(`${urlPrefix}/apps/${id}`); +} + +// 复制应用 +export function copyApp(data: any) { + return axios.post(`${urlPrefix}/apps/copy`, data); +} + +// 导入应用 +export function importApp(data: any) { + return axios.post(`${urlPrefix}/apps/import`, data); +} + +// 导出应用 +export function exportApp(data: any) { + return axios({ + method: 'post', + url: `${urlPrefix}/apps/export`, + responseType: 'blob', + data: data + }); +} + +// 运行主流程 +export function runMainFlow(data: any) { + return axios.post(`${runPrefix}/apps/run`, data); +} + +// 运行子流程 +export function runSubFlow(data: any) { + return axios.post(`${runPrefix}/apps/runSubflow`, data); +} + +// 重运行 +export function reRunApp(data: any) { + return axios.post(`${runPrefix}/apps/rerun`, data); +} + +// 暂停 +export function pauseApp(data: any) { + return axios.post(`${runPrefix}/apps/${data.id}/pause`); +} + +// 恢复 +export function resumeApp(data: any) { + return axios.post(`${runPrefix}/apps/${data.id}/resume`); +} + +// 停止 +export function stopApp(data: any) { + return axios.post(`${runPrefix}/apps/${data.id}/stop`); +} + +// APi发布 +export function apiPublish(data: publishApi) { + return axios.post(`${urlPrefix}/apps/apiPublish`, data); +} + +// 获取api信息 +export function getPublishApi(appId: string) { + return axios.get(`${urlPrefix}/apps/getPublishApi/${appId}`); +} + +// 刷新Api +export function refreshToken(data: publishApi) { + return axios.post(`${urlPrefix}/apps/apiTokenRefresh`, data); +} diff --git a/src/pages/instance/index.tsx b/src/pages/instance/index.tsx index a5e1628..7ee9b99 100644 --- a/src/pages/instance/index.tsx +++ b/src/pages/instance/index.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useState, useEffect } from 'react'; import styles from './style/index.module.less'; import CustomCard from '@/components/CustomCard'; import Overview from './overview'; @@ -13,6 +13,9 @@ import { IconEye } from '@arco-design/web-react/icon'; import { formatInstanceStatus, formatInstanceType, formatTimestamp } from '@/utils/common'; +import { getInstances } from '@/api/appIns'; +import { getOverviewApp } from '@/api/overview'; +import { getMyAppList } from '@/api/apps'; const Option = Select.Option; @@ -78,66 +81,6 @@ const columns: TableColumnProps[] = [ } ]; -const data = [ - { - 'appId': '1951085958320037889', - 'appResHistoryId': '1951157955455545345', - 'createBy': '1123598821738675201', - 'createTime': 1754028849000, - 'description': '', - 'duration': 0, - 'endTime': 0, - 'id': '1951164528214003713', - 'name': '复制:复制:轮胎装配流程', - 'nodeNum': 35, - 'progress': 14, - 'runningNum': 5, - 'startTime': 1754028849067, - 'state': 'RUNNING', - 'type': 'MANUAL', - 'updateBy': '1123598821738675201', - 'updateTime': 1754028849000 - }, - { - 'appId': '1951085958320037889', - 'appResHistoryId': '1951157955455545345', - 'createBy': '1123598821738675201', - 'createTime': 1754028826000, - 'description': '', - 'duration': 0, - 'endTime': 0, - 'id': '1951164430486720513', - 'name': '复制:复制:轮胎装配流程', - 'nodeNum': 35, - 'progress': 14, - 'runningNum': 5, - 'startTime': 1754028825767, - 'state': 'RUNNING', - 'type': 'MANUAL', - 'updateBy': '1123598821738675201', - 'updateTime': 1754028826000 - }, - { - 'appId': '1951085958320037889', - 'appResHistoryId': '1951157955455545345', - 'createBy': '1123598821738675201', - 'createTime': 1754028784000, - 'description': '', - 'duration': 0, - 'endTime': 0, - 'id': '1951164255143841793', - 'name': '复制:复制:轮胎装配流程', - 'nodeNum': 35, - 'progress': 14, - 'runningNum': 5, - 'startTime': 1754028783957, - 'state': 'RUNNING', - 'type': 'MANUAL', - 'updateBy': '1123598821738675201', - 'updateTime': 1754028784000 - } -]; - function checkInstance(instance) { console.log('instance:', instance); } @@ -161,65 +104,158 @@ function getIcon(type) { } } -function Selector() { - const cities = ['Beijing', 'Shanghai', 'Guangzhou', 'Shenzhen', 'Chengdu', 'Wuhan']; - return ( - - ); -} +const Instance = () => { + const [instanceData, setInstanceData] = useState({ + list: [], + totalCount: 0, + totalPage: 0, + currentPage: 1, + pageSize: 10 + }); + const [searchOptions, setSearchOptions] = useState([]); + const [overviewData, setOverviewData] = useState({}); + const [searchParams, setSearchParams] = useState({ + appId: '', + state: '', + type: '', + durationDesc: false + }); -function RunStatus() { - const cities = ['Beijing', 'Shanghai', 'Guangzhou', 'Shenzhen', 'Chengdu', 'Wuhan']; - return ( - - ); -} -function Type() { - const cities = ['Beijing', 'Shanghai', 'Guangzhou', 'Shenzhen', 'Chengdu', 'Wuhan']; - return ( - - ); -} + const Selector = () => { + return ( + + ); + }; + + const RunStatus = () => { + const stateList = [ + { + label: '暂停', + value: 'PAUSED' + }, + { + label: '中止', + value: 'KILL' + }, + { + label: '运行中', + value: 'RUNNING' + }, + { + label: '停止', + value: 'STOPPED' + }, + { + label: '失败', + value: 'FAILURE' + }, + { + label: '成功', + value: 'SUCCESS' + } + ]; + return ( + + ); + }; + + const Type = () => { + const typeDict = [ + // { + // label: 'HOOK', + // value: 'HOOK', + // }, + { + label: '定时任务', + value: 'TIMER' + }, + { + label: '运行应用', + value: 'MANUAL' + }, + { + label: '运行子流程', + value: 'MANUAL_SUB' + } + ]; + return ( + + ); + }; + + // 获取实例列表和概览数据 + const fetchData = async (params: any = {}) => { + const requestParams: any = { + appId: searchParams.appId, + state: searchParams.state, + type: searchParams.type, + currPage: params.currPage || instanceData.currentPage, + pageSize: params.pageSize || instanceData.pageSize, + total: 0, + durationDesc: searchParams.durationDesc + }; + + if (!requestParams.state) delete requestParams.state; + if (!requestParams.type) delete requestParams.type; + if (!requestParams.appId) delete requestParams.appId; -function generateData() { - const newData = []; - for (let i = 0; i < 11; i++) { - data.forEach((item, index) => { - newData.push({ - ...item, - key: `${item.appId}-${i}` // 确保key唯一 + const res: any = await getInstances(requestParams); + if (res.code === 200) { + setInstanceData({ + ...res.data, + currentPage: params.currPage || instanceData.currentPage, + pageSize: params.pageSize || instanceData.pageSize }); + } + const overviewData: any = await getOverviewApp(requestParams.appId); + if (overviewData.code === 200) setOverviewData(overviewData.data); + }; + + const getSearchOptions = async () => { + const res: any = await getMyAppList({ + currPage: 1, + pageSize: 999 }); - } - return newData; -} + if (res.code === 200) setSearchOptions(res.data.list); + }; + + useEffect(() => { + fetchData(); + getSearchOptions(); + }, []); + + const handlePageChange = (page: number) => { + fetchData({ currPage: page }); + }; + + const handlePageSizeChange = (pageSize: number) => { + fetchData({ pageSize, currPage: 1 }); + }; -function Instance() { - const newData = generateData(); return ( <>
- +
- +
); -} +}; export default Instance; \ No newline at end of file diff --git a/src/pages/instance/overview.tsx b/src/pages/instance/overview.tsx index c024e7a..07ebcd3 100644 --- a/src/pages/instance/overview.tsx +++ b/src/pages/instance/overview.tsx @@ -10,6 +10,7 @@ import IconCalendar from './assets/calendar.svg'; import IconComments from './assets/comments.svg'; import IconContent from './assets/content.svg'; import IconIncrease from './assets/increase.svg'; +import { formatSeconds } from '@/utils/common'; const { Row, Col } = Grid; @@ -40,31 +41,19 @@ function StatisticItem(props: StatisticItemType) { } type DataType = { - allContents?: string; - liveContents?: string; - increaseComments?: string; - growthRate?: string; - down?: boolean; + avgTime?: number; + runningNum?: number; + successNum?: number; + failureNum?: number; }; -function Overview() { +const Overview = ({ overviewData }) => { const [data, setData] = useState({}); - const [loading, setLoading] = useState(true); - - const fetchData = () => { - setLoading(true); - setData({ - allContents: '1', - liveContents: '1,397', - increaseComments: '1,837', - growthRate: '650' - }); - setLoading(false); - }; + const [loading, setLoading] = useState(false); useEffect(() => { - fetchData(); - }, []); + setData(overviewData); + }, [overviewData]); return ( @@ -73,9 +62,9 @@ function Overview() { } title="实例平均处理时间" - count={data.allContents} + count={data.avgTime < 1000 ? data.avgTime : Math.floor(data.avgTime / 1000 / 60)} loading={loading} - unit="分" + unit={data.avgTime >= 1000 ? '分' + formatSeconds(`${data.avgTime / 1000}`).split('分')[1] || formatSeconds(`${data.avgTime / 1000}`) : '毫秒'} /> @@ -83,7 +72,7 @@ function Overview() { } title="运行中" - count={data.liveContents} + count={data.runningNum} loading={loading} unit="个" /> @@ -93,7 +82,7 @@ function Overview() { } title="成功数" - count={data.increaseComments} + count={data.successNum} loading={loading} unit="个" /> @@ -103,7 +92,7 @@ function Overview() { } title="失败数" - count={data.growthRate} + count={data.failureNum} loading={loading} unit="个" /> @@ -111,6 +100,6 @@ function Overview() { ); -} +}; export default Overview; diff --git a/src/utils/common.ts b/src/utils/common.ts index c27f924..ef029b2 100644 --- a/src/utils/common.ts +++ b/src/utils/common.ts @@ -96,6 +96,10 @@ export function formatInstanceType(value: string): string { switch (value) { case 'MANUAL': return '运行应用'; + case 'MANUAL_SUB': + return '运行子流程'; + case 'TIMER': + return '定时任务'; default: return value; } @@ -117,6 +121,8 @@ export function formatInstanceStatus(value: string): string { return '已删除'; case 'FAILED': return '失败'; + case 'SUCCESS': + return '成功'; default: return value; } @@ -158,4 +164,36 @@ export function isJSON(str: any): boolean { } catch (e) { return false; } +} + +// 秒数转化为时分秒,返回中文字符串 +export function formatSeconds(value: string) { + let secondTime = parseInt(value, 10); // 秒 + let minuteTime = 0; // 分 + let hourTime = 0; // 小时 + if (secondTime > 59) { + // 如果秒数大于60,将秒数转换成整数 + // 获取分钟,除以60取整数,得到整数分钟 + minuteTime = parseInt(`${secondTime / 60}`, 10); + // 获取秒数,秒数取余,得到整数秒数 + secondTime = parseInt(`${secondTime % 60}`, 10); + // 如果分钟大于60,将分钟转换成小时 + if (minuteTime > 59) { + // 获取小时,获取分钟除以60,得到整数小时 + hourTime = parseInt(`${minuteTime / 60}`, 10); + // 获取小时后取余的分,获取分钟除以60取余的分 + minuteTime = parseInt(`${minuteTime % 60}`, 10); + } + } + let result = ''; + if (secondTime > 0) { + result = `${parseInt(`${secondTime}`, 10)}秒`; + } + if (minuteTime > 0) { + result = `${parseInt(`${minuteTime}`, 10)}分${result}`; + } + if (hourTime > 0) { + result = `${parseInt(`${hourTime}`, 10)}小时${result}`; + } + return result; } \ No newline at end of file