merge
This commit is contained in:
@@ -53,6 +53,7 @@
|
||||
:belongProject="belongProject"
|
||||
:parentCategoryPath="parentNodeCategoryPath"
|
||||
:existingNodeCodes="existingNodeCodes"
|
||||
:showNodeExtraInfo="showNodeExtraInfo"
|
||||
@confirm="onNodeDetailConfirmFun"
|
||||
v-bind="$attrs"
|
||||
/>
|
||||
@@ -124,6 +125,7 @@ interface Props {
|
||||
checkMethod?: any; // 处理勾选逻辑
|
||||
showAddCategoryButton?: boolean; // 是否显示添加分类按钮
|
||||
allowRootAddTask?: boolean; // 是否允许在根节点添加任务
|
||||
showNodeExtraInfo?: boolean; // 显示扩展信息tab(日志/附件/闭环/异常)
|
||||
hideEditFn?: (row: any) => boolean; // 外部控制编辑按钮隐藏逻辑
|
||||
}
|
||||
|
||||
@@ -157,6 +159,7 @@ const props = withDefaults(defineProps<Props>(), {
|
||||
checkMethod: null,
|
||||
showAddCategoryButton: true,
|
||||
allowRootAddTask: false,
|
||||
showNodeExtraInfo: false,
|
||||
hideEditFn: undefined,
|
||||
});
|
||||
|
||||
@@ -428,7 +431,10 @@ const actionList = computed(() => {
|
||||
deleteTableRowFun(row);
|
||||
},
|
||||
hide: (row: any) => {
|
||||
return props.readonly || (props.belongProject && row.uuid && enableConfigByTenant([TENANT_ENUM.LYRIC]));
|
||||
return (
|
||||
props.readonly ||
|
||||
(props.belongProject && row.uuid && enableConfigByTenant([TENANT_ENUM.LYRIC]))
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
@@ -11,7 +11,11 @@
|
||||
>
|
||||
<template #default>
|
||||
<el-tabs
|
||||
v-if="enableConfigByTenant([TENANT_ENUM.LYRIC])"
|
||||
v-if="
|
||||
enableConfigByTenant([TENANT_ENUM.LYRIC]) &&
|
||||
showNodeExtraInfo &&
|
||||
formData?.nodeType === NODE_TYPE.TASK
|
||||
"
|
||||
v-model="tabName"
|
||||
type="card"
|
||||
class="node-detail-tab-content"
|
||||
@@ -139,6 +143,7 @@ interface Props {
|
||||
parentCategoryPath?: string[];
|
||||
existingNodeCodes?: string[];
|
||||
enableSelectCode?: boolean;
|
||||
showNodeExtraInfo?: boolean;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
@@ -157,6 +162,7 @@ const props = withDefaults(defineProps<Props>(), {
|
||||
parentCategoryPath: () => [],
|
||||
existingNodeCodes: () => [],
|
||||
enableSelectCode: false,
|
||||
showNodeExtraInfo: false,
|
||||
});
|
||||
|
||||
const emits = defineEmits(['update:modelValue', 'confirm']);
|
||||
|
||||
@@ -151,16 +151,16 @@ export default [
|
||||
path: '/job/submit',
|
||||
name: 'JobSubmit',
|
||||
},
|
||||
// {
|
||||
// title: '作业列表',
|
||||
// path: '/job/list',
|
||||
// name: 'JobList',
|
||||
// },
|
||||
// {
|
||||
// title: '计算资源',
|
||||
// path: '/job/resources',
|
||||
// name: 'JobResources',
|
||||
// },
|
||||
{
|
||||
title: '作业列表',
|
||||
path: '/job/list',
|
||||
name: 'JobList',
|
||||
},
|
||||
{
|
||||
title: '计算资源',
|
||||
path: '/job/resources',
|
||||
name: 'JobResources',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
@@ -98,18 +98,18 @@ export default [
|
||||
name: 'JobSubmit',
|
||||
component: () => import('@/views/job/jobSubmit/index.vue'),
|
||||
},
|
||||
// {
|
||||
// title: '作业列表',
|
||||
// path: '/job/list',
|
||||
// name: 'JobList',
|
||||
// component: () => import('@/views/job/JobList/index.vue'),
|
||||
// },
|
||||
// {
|
||||
// title: '计算资源',
|
||||
// path: '/job/resources',
|
||||
// name: 'JobResources',
|
||||
// component: () => import('@/views/job/JobResources/index.vue'),
|
||||
// },
|
||||
{
|
||||
title: '作业列表',
|
||||
path: '/job/list',
|
||||
name: 'JobList',
|
||||
component: () => import('@/views/job/JobList/index.vue'),
|
||||
},
|
||||
{
|
||||
title: '计算资源',
|
||||
path: '/job/resources',
|
||||
name: 'JobResources',
|
||||
component: () => import('@/views/job/JobResources/index.vue'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
@@ -156,16 +156,16 @@ export default [
|
||||
path: '/job/submit',
|
||||
name: 'JobSubmit',
|
||||
},
|
||||
// {
|
||||
// title: '作业列表',
|
||||
// path: '/job/list',
|
||||
// name: 'JobList',
|
||||
// },
|
||||
// {
|
||||
// title: '计算资源',
|
||||
// path: '/job/resources',
|
||||
// name: 'JobResources',
|
||||
// },
|
||||
{
|
||||
title: '作业列表',
|
||||
path: '/job/list',
|
||||
name: 'JobList',
|
||||
},
|
||||
{
|
||||
title: '计算资源',
|
||||
path: '/job/resources',
|
||||
name: 'JobResources',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
@@ -98,18 +98,18 @@ export default [
|
||||
name: 'JobSubmit',
|
||||
component: () => import('@/views/job/jobSubmit/index.vue'),
|
||||
},
|
||||
// {
|
||||
// title: '作业列表',
|
||||
// path: '/job/list',
|
||||
// name: 'JobList',
|
||||
// component: () => import('@/views/job/JobList/index.vue'),
|
||||
// },
|
||||
// {
|
||||
// title: '计算资源',
|
||||
// path: '/job/resources',
|
||||
// name: 'JobResources',
|
||||
// component: () => import('@/views/job/JobResources/index.vue'),
|
||||
// },
|
||||
{
|
||||
title: '作业列表',
|
||||
path: '/job/list',
|
||||
name: 'JobList',
|
||||
component: () => import('@/views/job/JobList/index.vue'),
|
||||
},
|
||||
{
|
||||
title: '计算资源',
|
||||
path: '/job/resources',
|
||||
name: 'JobResources',
|
||||
component: () => import('@/views/job/JobResources/index.vue'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
@@ -109,6 +109,7 @@
|
||||
:showAddCategoryButton="false"
|
||||
:allowRootAddTask="true"
|
||||
:defaultExpandAll="false"
|
||||
:showNodeExtraInfo="true"
|
||||
>
|
||||
<template #otherOptions>
|
||||
<el-tooltip
|
||||
@@ -770,7 +771,7 @@ const createTaskPoolFun = async (formData: any) => {
|
||||
const wrappedNodes = wrapWithVirtualNodeFun(nodes);
|
||||
const pickedNodes = transformTreeToPoolNodes(wrappedNodes);
|
||||
|
||||
const poolBrief:any = {
|
||||
const poolBrief: any = {
|
||||
poolName: currentPoolBrief.value.poolName,
|
||||
tenantId: currentPoolBrief.value.tenantId,
|
||||
};
|
||||
|
||||
@@ -6,12 +6,16 @@
|
||||
alt=""
|
||||
/>
|
||||
<div class="overlay-text">
|
||||
<div class="pool-title" :title="scene.nodeCode">{{ scene.nodeName }}</div>
|
||||
<div class="pool-title" :title="scene.nodeName">{{ scene.nodeName }}</div>
|
||||
</div>
|
||||
<div class="bottom-box">
|
||||
<span class="gl-text-ellipsis gl-pointer-class" :title="scene.nodeCode">
|
||||
{{ scene.nodeCode }}
|
||||
</span>
|
||||
<div class="confidence-bar" :title="scene.confidence + '%'">
|
||||
<el-progress :percentage="scene.confidence" :stroke-width="6" :show-text="false" />
|
||||
<span class="confidence-label">{{ scene.confidence }}%</span>
|
||||
</div>
|
||||
<span class="pool-meta">
|
||||
{{ scene.discipline || '--' }}
|
||||
</span>
|
||||
@@ -149,6 +153,28 @@ const visibleChangeFun = (visible: boolean) => {
|
||||
}
|
||||
}
|
||||
|
||||
.confidence-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
margin: 0 12px;
|
||||
|
||||
:deep(.el-progress) {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.confidence-label {
|
||||
font-size: 11px;
|
||||
color: #666;
|
||||
font-weight: 500;
|
||||
min-width: 32px;
|
||||
text-align: right;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.bottom-box {
|
||||
.gl-text-ellipsis {
|
||||
font-size: 14px;
|
||||
|
||||
@@ -588,8 +588,8 @@ export const isJSONFun = (str: any) => {
|
||||
|
||||
// 删除无用附件文件
|
||||
export const removeAttachmentFileIds = (oldIds: string, newIds: any) => {
|
||||
const oldList = oldIds.split(',');
|
||||
const newList = newIds.split(',');
|
||||
const oldList = oldIds?.split(',') || [];
|
||||
const newList = newIds?.split(',') || [];
|
||||
const newSet = new Set(newList);
|
||||
const delIds: any[] = oldList.filter((id) => !newSet.has(id));
|
||||
delIds.forEach((id: any) => {
|
||||
|
||||
@@ -1,9 +1,191 @@
|
||||
<template>
|
||||
<div>作业列表</div>
|
||||
<div class="job-list-page">
|
||||
<BaseTable
|
||||
ref="baseTableRef"
|
||||
tableName="HPC_LIST_TABLE"
|
||||
:api="queryJobsApi"
|
||||
:actionList="actionList"
|
||||
fullHeight
|
||||
:show-checkbox="true"
|
||||
:show-index="true"
|
||||
>
|
||||
<template #leftOptions>
|
||||
<el-button type="primary" @click="batchCancalFun">批量取消</el-button>
|
||||
<el-button type="primary" @click="batchDeleteFun">批量删除</el-button>
|
||||
</template>
|
||||
<template #totalElapsedTime="{ row }">
|
||||
<span>{{ row.totalElapsedTime ? row.totalElapsedTime + 'h' : '--' }}</span>
|
||||
</template>
|
||||
<template #jobStatus="{ row }">
|
||||
<el-tag v-if="row.jobStatus === 'Finished'" type="success">{{
|
||||
WORK_STATUS.O[row.jobStatus]
|
||||
}}</el-tag>
|
||||
<el-tag type="info" v-else-if="row.jobStatus === 'Canceled'">{{
|
||||
WORK_STATUS.O[row.jobStatus]
|
||||
}}</el-tag>
|
||||
<el-tag v-else-if="row.jobStatus === 'Failed'" type="danger">{{
|
||||
WORK_STATUS.O[row.jobStatus]
|
||||
}}</el-tag>
|
||||
<el-tag v-else type="primary">{{ WORK_STATUS.O[row.jobStatus] }}</el-tag>
|
||||
</template>
|
||||
<template #software="{ row }">
|
||||
<div class="img-box">
|
||||
<img width="14" :src="getAppImg(row)" alt="" />
|
||||
<span>{{ row.software }}</span>
|
||||
</div>
|
||||
</template>
|
||||
<template #jobName="{ row }">
|
||||
<el-button link type="primary" @click="getJobFileListFun(row)">{{ row.jobName }}</el-button>
|
||||
</template>
|
||||
</BaseTable>
|
||||
|
||||
<jobFile
|
||||
:jobInfo="currentJobRow"
|
||||
v-if="jobFileVisible"
|
||||
@close="jobFileVisible = false"
|
||||
></jobFile>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { onMounted, ref } from 'vue';
|
||||
import BaseTable from '@/components/common/table/baseTable.vue';
|
||||
import jobFile from '@/views/task/execution/components/runDetailPage/runPagecomponent/jobFile.vue';
|
||||
import { useDict } from '@/utils/useDict';
|
||||
import { delHpcJobsApi, queryJobsApi, stopHpcJobApi } from '@/api/pbs/pbs';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { FileUtil } from '@/utils/file';
|
||||
import { queryAllApplicationApi } from '@/api/system/application';
|
||||
|
||||
const { WORK_STATUS } = useDict('WORK_STATUS');
|
||||
const baseTableRef = ref();
|
||||
const jobFileVisible = ref(false);
|
||||
|
||||
const stopFun = async (data: any) => {
|
||||
const params = {
|
||||
jobId: data.jobId,
|
||||
};
|
||||
await stopHpcJobApi(params).then((res: any) => {
|
||||
if (res.code === 200) {
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const deleteFun = async (ids: any) => {
|
||||
const params = {
|
||||
hpcJobIds: ids,
|
||||
};
|
||||
|
||||
await delHpcJobsApi(params).then((res: any) => {
|
||||
if (res.code === 200) {
|
||||
ElMessage.success('操作成功');
|
||||
baseTableRef.value.resetFun();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const currentJobRow = ref<any>({});
|
||||
const getJobFileListFun = async (row: any) => {
|
||||
currentJobRow.value = row;
|
||||
jobFileVisible.value = true;
|
||||
return;
|
||||
};
|
||||
|
||||
// 批量取消任务
|
||||
const batchCancalFun = async () => {
|
||||
const checks: any = baseTableRef.value.tableRef.getCheckboxRecords();
|
||||
|
||||
if (checks.length) {
|
||||
for (let i = 0; i < checks.length; i++) {
|
||||
await stopFun(checks[i]);
|
||||
}
|
||||
baseTableRef.value.resetFun();
|
||||
}
|
||||
};
|
||||
|
||||
// 批量删除任务
|
||||
const batchDeleteFun = async () => {
|
||||
const checks: any = baseTableRef.value.tableRef.getCheckboxRecords();
|
||||
if (checks.length) {
|
||||
const ids = checks.map((item: any) => {
|
||||
return item.jobId;
|
||||
});
|
||||
|
||||
await deleteFun(ids);
|
||||
}
|
||||
};
|
||||
|
||||
const actionList = ref([
|
||||
{
|
||||
title: '取消',
|
||||
type: 'warning',
|
||||
needConfirm: true,
|
||||
confirmTip: '确定取消选中计算任务吗?',
|
||||
click: (row: any) => {
|
||||
stopFun(row);
|
||||
ElMessage.success('操作成功');
|
||||
baseTableRef.value.resetFun();
|
||||
},
|
||||
hide: (row: any) => {
|
||||
return ['Canceled', 'Finished', 'Failed'].includes(row.jobStatus);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '删除',
|
||||
type: 'danger',
|
||||
needConfirm: true,
|
||||
confirmTip: '确定删除选中计算任务吗?',
|
||||
click: (row: any) => {
|
||||
const jobIds = [row.jobId];
|
||||
deleteFun(jobIds);
|
||||
},
|
||||
hide: (row: any) => {
|
||||
return !['Canceled', 'Finished', 'Failed'].includes(row.jobStatus);
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
const appList = ref<any>([]);
|
||||
|
||||
const getAppInfo = async () => {
|
||||
const param = {
|
||||
appName: '',
|
||||
current: 1,
|
||||
size: 999,
|
||||
};
|
||||
|
||||
try {
|
||||
const res: any = await queryAllApplicationApi(param);
|
||||
if (res && res.code === 200) {
|
||||
appList.value = res.data.data.map((item: any) => {
|
||||
return {
|
||||
label: item.appName,
|
||||
img: FileUtil.getFilePreviewImgPathUrl(item.appImage),
|
||||
uuid: item.uuid,
|
||||
};
|
||||
});
|
||||
}
|
||||
} catch {}
|
||||
};
|
||||
|
||||
const getAppImg = (row: any) => {
|
||||
const appImg: any =
|
||||
appList.value.find((item: any) => {
|
||||
return item.uuid === row.softwareId;
|
||||
})?.img || '';
|
||||
return appImg;
|
||||
};
|
||||
|
||||
onMounted(async () => {
|
||||
await getAppInfo();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
<style lang="scss" scoped>
|
||||
.job-list-page {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #fff;
|
||||
padding: 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,9 +1,244 @@
|
||||
<template>
|
||||
<div>资源管理</div>
|
||||
<div class="source-chart-page">
|
||||
<div class="table">
|
||||
<div class="chart-box">
|
||||
<div class="chart-box-left">
|
||||
<commonFilterChart
|
||||
title="资源运行状态"
|
||||
:charts-id="'chart-1'"
|
||||
:bar-type="'pieChart'"
|
||||
:option="chartOptionOne"
|
||||
></commonFilterChart>
|
||||
</div>
|
||||
<div class="chart-box-right">
|
||||
<commonFilterChart
|
||||
title="节点分配状态"
|
||||
:charts-id="'chart-2'"
|
||||
:bar-type="'pieChart'"
|
||||
:option="chartOptionTwo"
|
||||
></commonFilterChart>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pege-table">
|
||||
<BaseTable
|
||||
ref="baseTableRef2"
|
||||
:showSetting="false"
|
||||
tableName="HPC_RESOURCE_LIST"
|
||||
fullHeight
|
||||
hidePagination
|
||||
:data="hpcSourceList"
|
||||
:show-index="true"
|
||||
:show-checkbox="true"
|
||||
>
|
||||
<template #nodeStatus="{ row }">
|
||||
<el-tag type="success" v-if="row.nodeStatus === 'Online'">在线</el-tag>
|
||||
<el-tag type="info" v-else-if="row.nodeStatus === 'Offline'">离线</el-tag>
|
||||
<el-tag type="warning" v-else>异常</el-tag>
|
||||
</template>
|
||||
|
||||
<template #efficiency="{ row }">
|
||||
<span>{{ row.freeCores }}</span
|
||||
>/<span>{{ row.totalCores }}</span
|
||||
>|<span>{{ getefficiencyFun(row) }}</span>
|
||||
</template>
|
||||
<template #nodeName="{ row }">
|
||||
<el-button link type="primary">{{ row.nodeName }}</el-button>
|
||||
</template>
|
||||
</BaseTable>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { queryHpcResourceApi } from '@/api/pbs/pbs';
|
||||
import { onMounted, ref } from 'vue';
|
||||
import commonFilterChart from '@/components/common/echartCard/commonFilterChart.vue';
|
||||
import BaseTable from '@/components/common/table/baseTable.vue';
|
||||
|
||||
const hpcSourceList = ref<any>([]);
|
||||
|
||||
const queryHpcResourceFun = async () => {
|
||||
try {
|
||||
const res: any = await queryHpcResourceApi();
|
||||
if (res && res.code === 200) {
|
||||
hpcSourceList.value = res.data.nodeList;
|
||||
|
||||
initChartOneFun(res.data);
|
||||
initChartTwoFun(res.data);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
};
|
||||
const colorList = ref<any>(['#409eff', '#67c23a', '#909399']);
|
||||
|
||||
const chartOptionOne = ref();
|
||||
|
||||
const initChartOneFun = (data: any) => {
|
||||
chartOptionOne.value = {
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
},
|
||||
title: {
|
||||
show: true,
|
||||
text: `全部 ${data.totalNodes}`, // 中间文字
|
||||
left: '24%',
|
||||
top: 'center',
|
||||
textStyle: {
|
||||
fontSize: 24,
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
},
|
||||
legend: {
|
||||
orient: 'vertical',
|
||||
left: '70%',
|
||||
top: 'center',
|
||||
icon: 'circle',
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'pie',
|
||||
radius: ['60%', '70%'],
|
||||
center: ['30%', '50%'],
|
||||
avoidLabelOverlap: false,
|
||||
label: {
|
||||
show: false,
|
||||
position: 'center',
|
||||
},
|
||||
emphasis: {
|
||||
label: {
|
||||
show: false,
|
||||
fontSize: 40,
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
},
|
||||
data: [
|
||||
// { value: data.totalNodes || '', name: '全部' },
|
||||
{ value: data.totalNodes - data.freeNodes || '', name: '已使用' },
|
||||
{ value: data.freeNodes || '', name: '未使用' },
|
||||
],
|
||||
itemStyle: {
|
||||
color: function (params: any) {
|
||||
return colorList.value[params.dataIndex];
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
};
|
||||
|
||||
const chartOptionTwo = ref();
|
||||
|
||||
const initChartTwoFun = (data: any) => {
|
||||
chartOptionTwo.value = {
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
},
|
||||
title: {
|
||||
text: `全部 ${data.totalCores}`, // 中间文字
|
||||
left: '24%',
|
||||
top: 'center',
|
||||
textStyle: {
|
||||
fontSize: 24,
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
},
|
||||
legend: {
|
||||
orient: 'vertical',
|
||||
left: '70%',
|
||||
top: 'center',
|
||||
icon: 'circle',
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'pie',
|
||||
radius: ['60%', '70%'],
|
||||
center: ['30%', '50%'],
|
||||
label: {
|
||||
show: false,
|
||||
position: 'center',
|
||||
},
|
||||
emphasis: {
|
||||
label: {
|
||||
show: false,
|
||||
fontSize: 40,
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
},
|
||||
data: [
|
||||
// { value: data.totalCores || '', name: '全部' },
|
||||
{ value: data.usedCores || '', name: '已使用' },
|
||||
{ value: data.freeCores || '', name: '未使用' },
|
||||
],
|
||||
itemStyle: {
|
||||
color: function (params: any) {
|
||||
return colorList.value[params.dataIndex];
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
};
|
||||
|
||||
// 获取CPU使用效率
|
||||
const getefficiencyFun = (row: any) => {
|
||||
let num: any = '0';
|
||||
|
||||
if (row.totalCores) {
|
||||
if (row.freeCores === row.totalCores || !row.usedCores) {
|
||||
num = '0';
|
||||
} else if (row.usedCores === row.totalCores || !row.freeCores) {
|
||||
num = '100%';
|
||||
} else {
|
||||
num = (row.usedCores / row.totalCores) * 100 + '%';
|
||||
}
|
||||
}
|
||||
|
||||
return num;
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
queryHpcResourceFun();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
<style lang="scss" scoped>
|
||||
.source-chart-page {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.table {
|
||||
height: 100%;
|
||||
padding: 10px;
|
||||
background-color: #f2f3f5;
|
||||
|
||||
.chart-box {
|
||||
width: 100%;
|
||||
height: 350px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
.chart-box-left,
|
||||
.chart-box-right {
|
||||
width: calc(50% - 5px);
|
||||
height: 100%;
|
||||
background-color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.pege-table {
|
||||
width: 100%;
|
||||
height: calc(100% - 360px);
|
||||
margin-top: 10px;
|
||||
padding: 10px;
|
||||
background-color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.white {
|
||||
background-color: #fff;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<Dialog
|
||||
v-model="visible"
|
||||
:diaTitle="`${currentRow?.id ? '编辑' : '新增'}应用`"
|
||||
:width="'25%'"
|
||||
:width="'50%'"
|
||||
:height="'70%'"
|
||||
@close="closeFun"
|
||||
show-footer
|
||||
@@ -24,6 +24,7 @@
|
||||
limit: 1,
|
||||
},
|
||||
}"
|
||||
@change="formChangeFun"
|
||||
>
|
||||
</TableForm>
|
||||
<!-- <el-form :model="appformData" labelWidth="80">
|
||||
@@ -31,7 +32,41 @@
|
||||
<UploadImg v-model="appformData.appImage" :limit-upload="true" :multiple="false" />
|
||||
</el-form-item>
|
||||
</el-form> -->
|
||||
|
||||
<el-form :model="appformData" labelWidth="80">
|
||||
<el-form-item label="命令参数">
|
||||
<BaseTable
|
||||
tableName="COMMAND_PARAM_TABLE"
|
||||
ref="baseTableRef"
|
||||
fullHeight
|
||||
:hide-pagination="true"
|
||||
>
|
||||
<template #keyCnName="{ row }">
|
||||
<el-input v-model="row.keyCnName"></el-input>
|
||||
</template>
|
||||
<template #defaultValue="{ row }">
|
||||
<el-input v-model="row.defaultValue"></el-input>
|
||||
</template>
|
||||
<template #isDisplay="{ row }">
|
||||
<el-switch
|
||||
v-model="row.isDisplay"
|
||||
inline-prompt
|
||||
active-value="Y"
|
||||
inactive-value="N"
|
||||
/>
|
||||
</template>
|
||||
<template #valueType="{ row }">
|
||||
<el-select v-model="row.valueType">
|
||||
<el-option
|
||||
v-for="item in valueTypeList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</template>
|
||||
</BaseTable>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="pic-content" ref="appNameRef" v-show="appName">
|
||||
<appNameBg :app-name="appName"></appNameBg>
|
||||
</div>
|
||||
@@ -57,6 +92,7 @@ import { delayTime } from '@/utils/common';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import Dialog from '@/components/common/dialog/index.vue';
|
||||
// import UploadImg from '@/components/common/uploadImg/index.vue';
|
||||
import BaseTable from '@/components/common/table/baseTable.vue';
|
||||
|
||||
const props = defineProps(['currentAppInfo', 'tableName']);
|
||||
const emit = defineEmits(['cancel', 'submit']);
|
||||
@@ -69,9 +105,10 @@ const loading = ref(false);
|
||||
const closeFun = () => {
|
||||
emit('cancel');
|
||||
};
|
||||
|
||||
const baseTableRef = ref();
|
||||
const appformData = reactive<any>({
|
||||
appImage: '',
|
||||
commandConfigs: [],
|
||||
});
|
||||
|
||||
const submitFun = async () => {
|
||||
@@ -81,6 +118,7 @@ const submitFun = async () => {
|
||||
if (valid) {
|
||||
const fromData = tableFormRef.value.getFormDataFun();
|
||||
const appImage: any = fromData.appImage;
|
||||
fromData.commandConfigs = appformData.commandConfigs;
|
||||
// 判断是否上传了图片
|
||||
if (!appImage) {
|
||||
appName.value = fromData.appName;
|
||||
@@ -128,19 +166,75 @@ const updatePngFun = async (name: any) => {
|
||||
}
|
||||
};
|
||||
|
||||
const getUseformDataFun = () => {
|
||||
nextTick(() => {
|
||||
const fromData = tableFormRef.value.getFormDataFun();
|
||||
const appImage = fromData.extras.find((item: any) => {
|
||||
return item.propertyName === 'appImage';
|
||||
})?.propertyValue;
|
||||
// const getUseformDataFun = () => {
|
||||
// nextTick(() => {
|
||||
// const fromData = tableFormRef.value.getFormDataFun();
|
||||
// const appImage = fromData.extras.find((item: any) => {
|
||||
// return item.propertyName === 'appImage';
|
||||
// })?.propertyValue;
|
||||
|
||||
if (appImage?.length) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
// if (appImage?.length) {
|
||||
// return true;
|
||||
// } else {
|
||||
// return false;
|
||||
// }
|
||||
// });
|
||||
// };
|
||||
|
||||
const valueTypeList = ref<any>([
|
||||
{
|
||||
label: '共享云盘文件',
|
||||
value: 'file',
|
||||
},
|
||||
{
|
||||
label: '用户自定义输入',
|
||||
value: 'input',
|
||||
},
|
||||
]);
|
||||
|
||||
const formChangeFun = (data: any) => {
|
||||
console.log(data, 'data');
|
||||
|
||||
if (data?.key === 'hpcCommand') {
|
||||
getCommandConfigsFun(data.val);
|
||||
}
|
||||
};
|
||||
|
||||
const getCommandConfigsFun = (str: any) => {
|
||||
const params = str
|
||||
? str.split(' ').filter((item: any) => {
|
||||
return item.startsWith('%');
|
||||
})
|
||||
: [];
|
||||
|
||||
const list = params.map((item: any) => {
|
||||
return item.replace('%', '');
|
||||
});
|
||||
appformData.commandConfigs = appformData.commandConfigs.filter((item: any) => {
|
||||
return list.includes(item.keyEnName);
|
||||
});
|
||||
|
||||
const appParams = appformData.commandConfigs.map((item: any) => {
|
||||
return item.keyEnName;
|
||||
});
|
||||
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
if (!appParams.includes(list[i])) {
|
||||
appformData.commandConfigs.push({
|
||||
defaultValue: 'default',
|
||||
featchType: 'param',
|
||||
fileRegular: '',
|
||||
keyCnName: '',
|
||||
keyEnName: list[i],
|
||||
valueType: 'input',
|
||||
isDisplay: 'Y',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
console.log(list);
|
||||
console.log(appformData.commandConfigs);
|
||||
baseTableRef.value.setDataFun(appformData.commandConfigs);
|
||||
};
|
||||
|
||||
watch(
|
||||
@@ -149,12 +243,14 @@ watch(
|
||||
if (newVal) {
|
||||
currentRow.value = cloneDeep(newVal);
|
||||
appformData.appImage = currentRow.value?.appImage;
|
||||
appformData.commandConfigs = currentRow.value?.commandConfigs || [];
|
||||
setTimeout(() => {
|
||||
if (currentRow.value?.id) {
|
||||
tableFormRef.value.setFormDataFun(currentRow.value);
|
||||
} else {
|
||||
tableFormRef.value.resetFun();
|
||||
}
|
||||
baseTableRef.value.setDataFun(appformData.commandConfigs);
|
||||
}, 100);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
>
|
||||
<template #leftOptions>
|
||||
<div>
|
||||
<el-button type="primary" @click="editAppInfoFun">新增应用 </el-button>
|
||||
<el-button type="primary" @click="editAppInfoFun">新增应用</el-button>
|
||||
<el-button type="" @click="showAppUseFun">应用统计 </el-button>
|
||||
</div>
|
||||
</template>
|
||||
@@ -283,6 +283,9 @@ const updateAppInfoFun = async (data: any) => {
|
||||
machineCode: data.machineCode,
|
||||
comment: data.comment,
|
||||
uuid: data.uuid,
|
||||
commandConfigs: data.commandConfigs,
|
||||
hpcCommand: data.hpcCommand,
|
||||
hpcGroup: 'HPC_PACK',
|
||||
// creator: 'vu0151d',
|
||||
});
|
||||
if (res && res.code === 200) {
|
||||
@@ -304,6 +307,9 @@ const updateAppInfoFun = async (data: any) => {
|
||||
comment: data.comment || '',
|
||||
creator: getUserId() || '',
|
||||
creatorName: getUserData()?.nickname || '',
|
||||
commandConfigs: data.commandConfigs,
|
||||
hpcCommand: data.hpcCommand,
|
||||
hpcGroup: 'HPC_PACK',
|
||||
};
|
||||
|
||||
const res: any = await addApplicationApi(param);
|
||||
@@ -357,7 +363,7 @@ const timer: any = ref(null);
|
||||
const startAppFun = async (data: any) => {
|
||||
await getdeviceuuidFun();
|
||||
|
||||
const uuid = localStorage.getItem('USER_UUID') ;
|
||||
const uuid = localStorage.getItem('USER_UUID');
|
||||
if (uuid) {
|
||||
const res: any = await execApi({
|
||||
path: data.appPath,
|
||||
|
||||
@@ -512,7 +512,7 @@ const submitFun = async () => {
|
||||
});
|
||||
}
|
||||
|
||||
if (props.taskInfo.exeStatus != 8) {
|
||||
if (props.taskInfo.exeStatus != TASK_PROCESS_STATUS.CLOSED_LOOP) {
|
||||
if (enableConfigByTenant([TENANT_ENUM.LYRIC])) {
|
||||
await updateTaskExeStatusFun();
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
<DemandDetail v-model="formVisible" :demandId="demandId" />
|
||||
</div>
|
||||
<attachments :demandId="demandInfo.uuid" v-model:visible="attachmentsVisible"></attachments>
|
||||
<RejectDia v-model="rejectVisible" title="撤销代办" @submit="rejectFun" />
|
||||
<RejectDia v-model="rejectVisible" title="撤回代办" @submit="rejectFun" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@@ -123,7 +123,7 @@ const actionList = ref([
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '撤销',
|
||||
title: '撤回',
|
||||
type: 'danger',
|
||||
click: (row: any) => {
|
||||
rejectData.value = row;
|
||||
@@ -169,7 +169,7 @@ const rejectFun = (data: any) => {
|
||||
withdrawDemandApi(params).then((res: any) => {
|
||||
if (res.code === 200) {
|
||||
rejectVisible.value = false;
|
||||
ElMessage.success('撤销成功');
|
||||
ElMessage.success('撤回成功');
|
||||
tableRef.value.tableRef.resetFun();
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user