This commit is contained in:
2025-12-02 09:38:59 +08:00
9 changed files with 156 additions and 260 deletions

View File

@@ -4,6 +4,13 @@
ref="baseTableRef"
hide-pagination
tableName="FLOW_NODE_PARAM"
:tree-config="{
transform: true,
expandAll: true,
rowField: 'formId',
parentField: 'parentId',
childrenField: 'children',
}"
>
<template #leftOptions>
@@ -12,9 +19,10 @@
<el-button type="">引用参数</el-button>
</template>
<template #value="{ row, column }">
<template #value="{ row, }">
<div class="pr10 tableCellContent">
<!-- 输入框 -->
<div
class="numInput flex-div"
v-if="(row.tagType === WIDGET_TYPE.INPUTS || row.tagType === WIDGET_TYPE.INPUT) && row.englishLabel"
@@ -26,18 +34,8 @@
gridTemplateColumns: 'repeat(' + row.column + ',1fr)',
}"
>
<div class="flex-align-center mr12" v-for="num in row?.total" :key="num">
<span
class="over-ellipsis span-fommat"
v-if="row.needLabel"
:title="row.labelList[num - 1]"
>{{ row.labelList[num - 1] }}</span>
<span v-if="row.needLabel"></span>
<el-input class="span-min80" v-model="row.list[num - 1]"></el-input>
</div>
<!-- 兼容老版input -->
<div class="flex-align-center mr12" v-if="!row?.total">
<el-input :placeholder="row.placeholder" :title="row.value" class="w70p" v-model="row.value"></el-input>
<div class="flex-align-center mr12" >
<el-input class="span-min80" v-model="row.defaultValue"></el-input>
</div>
</div>
</div>
@@ -45,8 +43,8 @@
<el-select
v-if="row.tagType === WIDGET_TYPE.SELECT"
:multiple="row.isMultiple === '1'"
:title="row.value"
v-model="row.value"
:title="row.defaultValue"
v-model="row.defaultValue"
class="w70p"
collapse-tags
:allow-create="row.importability === '1'"
@@ -54,120 +52,53 @@
default-first-option
>
<el-option
v-for="(item, index) in row.labelList?.split(';') || []"
:key="item"
:label="item"
:value="row.mapList ? row.mapList.split(';')[index] : item"
v-for="(item, index) in row?.options || []"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<!-- 4单选框 -->
<el-checkbox v-if="row.tagType === WIDGET_TYPE.CHECKBOX" v-model="row.value" true-value="1" false-value="0" />
<el-checkbox v-if="row.tagType === WIDGET_TYPE.CHECKBOX" v-model="row.defaultValue" true-value="1" false-value="0" />
<!-- 多选框 -->
<div v-if="row.tagType === WIDGET_TYPE.CHECKBOXS">
<div
class="input-grid"
:style="{
display: row.total === row.column ? 'flex' : 'grid',
gridTemplateColumns: 'repeat(' + row.column + ',1fr)',
}"
>
<div class="checkbox-group" v-for="(item, index) in row.list" :key="item">
<el-checkbox
:label="row?.labelList ? row?.labelList[index] : ''"
v-model="row.list[index]"
true-value="1"
false-value="0"
@change="changeCheckbox(row)"
/>
<span class="mr12"></span>
</div>
</div>
</div>
<el-checkbox-group v-model="row.defaultValue">
<el-checkbox v-for="item in row.options " :key="item.value" :label="item.label" :value="item.value" />
<div
class="numInput flex-div"
v-if="row.tagType === WIDGET_TYPE.NUMBER_INPUTS || row.tagType === WIDGET_TYPE.NUMBER_INPUT"
>
<!-- <el-input-number :precision="row.decimals" controls-position="right"
v-model="row.value"></el-input-number> -->
<div
class="input-grid"
:style="{
display: row.total === row.column ? 'flex' : 'grid',
gridTemplateColumns: 'repeat(' + row.column + ',1fr)',
}"
>
<div class="flex-align-center mr12" v-for="num in row.total" :key="num">
<span
class="over-ellipsis span-fommat"
v-if="row.needLabel"
:title="row.labelList[num - 1]"
>{{ row.labelList[num - 1] }}</span>
<span v-if="row.needLabel"></span>
<el-input-number
class="spanw100"
:precision="row.decimals"
controls-position="right"
v-model="row.list[num - 1]"
></el-input-number>
<span
class="over-ellipsis span-fommat"
:title="row?.units ? row?.units[num - 1] : ''"
>{{ row?.units ? row?.units[num - 1] : '' }}</span>
</div>
<!-- 兼容老版number-input -->
<el-input-number
v-if="!row?.total"
:precision="row.decimals"
controls-position="right"
v-model="row.value"
></el-input-number>
</div>
<div v-if="row.unitList">
<el-select :title="row.Value" v-model="row.Unit" class="w100 ml10">
<el-option v-for="item in row.UnitList.split(';')" :key="item" :label="item" :value="item" />
</el-select>
</div>
<span class="ml10" v-else>{{ row.unit }}</span>
</div>
<!-- 6单纯显示内容无法编辑 -->
<div v-if="row.tagType === WIDGET_TYPE.VIEW">
<el-icon class="colorIcon" v-if="isLoadingBaseInfo">
<Loading />
</el-icon>
{{ row.value }}
</div>
<!-- 滑块 -->
<div v-if="row.tagType === WIDGET_TYPE.SLIDER" class="slider">
<span class="value">{{ row.value }}</span>
<input
class="slider-input"
type="Range"
:min="row.minValue"
:max="row.maxValue"
:step="row.step"
v-model="row.value"
/>
<span class="min-value">{{ row.minValue }}</span>
<span class="max-value">{{ row.maxValue }}</span>
</div>
<!-- 批量选择框控件 -->
<div v-if="row.tagType === WIDGET_TYPE.BATCH_LOADCASE" class="INCLFileList loadcaseList">
<el-checkbox v-model="row.isAllChecked" @change="changeBatchLoadcase($event, row)">全选</el-checkbox>
<el-checkbox-group v-model="row.checkedList" @change="changeBatchLoadcaseNum(row)">
<el-checkbox
:label="item.id"
v-for="item in row.selectList"
:key="item.id"
class="span-3"
:title="item.loadcase"
>
{{ item.loadcase }}
</el-checkbox>
</el-checkbox-group>
</div>
<!-- 计数器 -->
<div
class="numInput "
v-if="row.tagType === WIDGET_TYPE.NUMBER_INPUTS || row.tagType === WIDGET_TYPE.NUMBER_INPUT"
>
<div
class="input-grid"
>
<el-input-number
class="mr10"
controls-position="right"
v-model="row.defaultValue"
></el-input-number>
<span
class="over-ellipsis span-fommat"
:title="row?.units "
>{{ row?.unit }}</span>
</div>
</div>
<!-- 6单纯显示内容无法编辑 -->
<div v-if="row.tagType === WIDGET_TYPE.VIEW && row.tagIcon === 'input'">
{{ row.defaultValue }}
</div>
<!-- 滑块 -->
<div v-if="row.tagType === WIDGET_TYPE.SLIDER" class="slider" >
<span class="value">{{ row.defaultValue }}</span>
<el-slider v-model="row.defaultValue" :min="row.min" :max="row.max" size="small" />
</div>
<!-- 9 模型文件选择 local + server-->
<div
class="localServer"
@@ -175,39 +106,34 @@
row.tagType === WIDGET_TYPE.FILE || row.tagType === NODE_TYPE.SCRIPT || row.tagType === NODE_TYPE.PPT
"
>
<!-- <server-local-file
@returnFile="changeFile($event, row)"
:row="{
Value: row.value,
Id: row.chineseLabel + row.id,
Multiple: row.isMultiple ? '1' : '0',
FileType: row.fileType,
SelectType: row.fromType,
Flag: 'automation',
ParentPath: '',
UiList: row.UiList,
Name: row.name,
Placeholder: row?.Placeholder,
SuffixName: row?.SuffixName,
uploadPath: props.currentNode?.path,
}"
:currentNode="currentNode"
/> -->
</div>
<!-- 行容器 -->
<div v-if="row.tagType === WIDGET_TYPE.VIEW && row.tagIcon === 'row'">
{{ '' }}
</div>
</div>
</template>
<template #label="{row}">
<span v-if="row.tagType === WIDGET_TYPE.VIEW && row.tagIcon === 'row'">
{{ row.componentName }}
</span>
<span v-else>{{ row.label }}</span>
</template>
</BaseTable>
</div>
</template>
<script setup lang="ts">
import { ref, watch, nextTick, reactive } from 'vue';
import { ref, watch, nextTick } from 'vue';
import BaseTable from '@/components/common/table/baseTable.vue';
import { NODE_TYPE, PAGE_TYPE, WIDGET_IDS, WIDGET_TYPE } from '@/utils/enum/flow';
import { ElMessage } from 'element-plus';
import { submitFileNameReg } from '@/utils/validate';
import { NODE_TYPE, WIDGET_TYPE } from '@/utils/enum/flow';
const props = defineProps({
nodeParams: {
@@ -222,64 +148,24 @@ const props = defineProps({
},
});
const emits = defineEmits(['syncJobName', 'syncPageInfo', 'changeBatchSubmit', 'verifyLight', 'paramPageHideControl']);
const pageInfo = reactive({
name: props.pageInfo?.name,
type: props.pageInfo?.type,
solver: props.pageInfo?.solver,
});
const baseTableRef = ref();
const tableData = ref<any>([]);
const isLoadingBaseInfo = ref(false);
const changeCheckbox = (record: any) => {
// 不生成include时隐藏参数设置界面
if (record.englishLabel === WIDGET_IDS.PRE_PROCESS) {
emits('paramPageHideControl', record.list[0] === '0');
}
};
const formatDataFun = (list:any, parentId:any) => {
// 更改头文件加载基本信息
const changeFile = async ({ fileType, data, fileList, isFile, isFromServer }: any, record: any) => {
console.log(fileType, 'fileType');
for (let index = 0; index < data.length; index++) {
if (!submitFileNameReg(data[index].fileName)) {
ElMessage.error('文件名仅可以包含字母 数字 . - _');
return;
for (let i = 0;i < list.length;i++) {
list[i].parentId = parentId;
if (list[i]?.children?.length) {
formatDataFun(list[i]?.children, list[i].renderKey);
}
}
record.value = data;
record.isFile = isFile;
record.isServer = isFromServer;
record.fileList = fileList;
if (pageInfo.type === PAGE_TYPE.MODEL && record.englishLabel === 'model' && data[0]?.fileName) {
emits('syncJobName', data[0].fileName);
}
};
// 批量提交的全选操作
const changeBatchLoadcase = (val: boolean, record: any) => {
record.isAllChecked = val;
if (val) {
record.checkedList = record.selectList.map((item: { id: string }) => {
return item.id;
});
} else {
record.checkedList = [];
}
emits('changeBatchSubmit', record.checkedList);
};
const changeBatchLoadcaseNum = (record: any) => {
record.isAllChecked = record.checkedList.length === record.selectList.length;
emits('changeBatchSubmit', record.checkedList);
};
watch(() => props.nodeParams, (newVal) => {
if (newVal) {
tableData.value = newVal;
formatDataFun(tableData.value, 0);
console.log(tableData.value, 'tableData.value');
nextTick(() => {
@@ -316,4 +202,19 @@ watch(() => props.nodeParams, (newVal) => {
width: 100px
}
}
.slider{
display: flex;
align-items: center;
height: 40px;
padding: 0 12px;
}
.value{
padding-right: 15px;
}
.mr10{
margin-right: 10px;
}
</style>

View File

@@ -20,6 +20,10 @@ const lang = {
'查看': 'View',
'审批类型': 'Approval Type',
'任务': 'Task',
'请输入': 'Please Enter ',
'请选择': 'Please Select ',
'操作成功': 'Operation Successful',
'操作失败': 'Operation Failed',
},
'菜单': {
'首页': 'Home',

View File

@@ -20,6 +20,10 @@ const lang = {
'查看': '查看',
'审批类型': '审批类型',
'任务': '任务',
'请输入': '请输入',
'请选择': '请选择',
'操作成功': '操作成功',
'操作失败': '操作失败',
},
'菜单': {
'首页': '首页',

View File

@@ -4,18 +4,14 @@
<div class="form">
<el-form>
<el-form-item :label="$t('数据预测.降阶模型')">
<el-select v-model="selectedModel" placeholder="请选择降阶模型" filterable @change="onModelChangeFun">
<el-select v-model="selectedModel" :placeholder="$t('通用.请选择')" filterable @change="onModelChangeFun">
<el-option v-for="item in modelOptions" :label="item.label" :value="item" :key="item.id" />
</el-select>
</el-form-item>
</el-form>
</div>
<div class="button">
<el-popover
class="box-item"
:title="selectedModel?.modelName"
:content="selectedModel?.description"
>
<el-popover class="box-item" :title="selectedModel?.modelName" :content="selectedModel?.description">
<template #reference>
<el-button>{{ $t('数据预测.功能说明') }}</el-button>
</template>
@@ -24,27 +20,41 @@
</div>
<div class="content" v-loading="forecastLoading">
<div class="left">
<BaseTable ref="inputTableRef" :tableName="TABLE_NAME.DATA_FORECAST_INPUT" showIndex :actionsWidth="200" hidePagination>
<BaseTable
ref="inputTableRef"
:tableName="TABLE_NAME.DATA_FORECAST_INPUT"
showIndex
hidePagination
>
<template #type>
{{ $t('数据预测.输入') }}
</template>
<template #value="{ row }">
<el-input-number
v-model="row.value"
placeholder="请输入内容"
/>
<el-input-number v-model="row.value" :placeholder="$t('通用.请输入')" class="full"/>
</template>
</BaseTable>
</div>
<div class="center">
<el-popconfirm :title="$t('数据预测.确定开始预测吗')" @confirm="beginForecastFun">
<el-popconfirm
:title="$t('数据预测.确定开始预测吗')"
@confirm="beginForecastFun"
:confirmButtonText="$t('通用.确定')"
:cancelButtonText="$t('通用.取消')"
>
<template #reference>
<el-button :disabled="selectedModel?.predStatus==='预测中'" type="primary" :loading="forecastLoading" >{{ $t('数据预测.开始预测') }}</el-button>
<el-button :disabled="selectedModel?.predStatus === '预测中'" type="primary" :loading="forecastLoading">
{{ $t('数据预测.开始预测') }}
</el-button>
</template>
</el-popconfirm>
</div>
<div class="right">
<BaseTable ref="outputTableRef" :tableName="TABLE_NAME.DATA_FORECAST_OUTPUT" showIndex :actionsWidth="200" hidePagination>
<BaseTable
ref="outputTableRef"
:tableName="TABLE_NAME.DATA_FORECAST_OUTPUT"
showIndex
hidePagination
>
<template #type>
{{ $t('数据预测.输出') }}
</template>
@@ -146,7 +156,7 @@ const getTitleMapFun = async () => {
if (Array.isArray(res.data?.source_title)) {
const titleMap: Record<string, string> = {};
res.data?.source_title.forEach((item: Record<string, string>) => {
Object.keys(item).forEach((key:string) => {
Object.keys(item).forEach((key: string) => {
titleMap[key] = item[key];
});
});
@@ -167,7 +177,7 @@ const clearResultFun = () => {
value: '',
};
});
const outputDataFormatted = outputData.map((item: any ) => {
const outputDataFormatted = outputData.map((item: any) => {
return {
...item,
value: '',
@@ -187,13 +197,13 @@ const getModelPredictResultFun = async () => {
const inputPredLabelValue = res.data?.inputPredLabelValue || [];
const forecastValue = res.data?.outputPredLabelValue;
const inputDataFormatted = inputData.map((item: any) => {
const inputValue = inputPredLabelValue.find((inputItem: any) => inputItem.name === item.name);
const inputValue = inputPredLabelValue.find((inputItem: any) => inputItem.name === item.name) || {};
return {
...item,
value: inputValue.value || '',
value: inputValue.value || null,
};
});
const outputDataFormatted = outputData.map((item: any ) => {
const outputDataFormatted = outputData.map((item: any) => {
return {
...item,
value: forecastValue ? forecastValue[item.name] : '',
@@ -251,4 +261,7 @@ onMounted(() => {
height: 100%;
}
}
.full {
width: 100%;
}
</style>

View File

@@ -130,15 +130,6 @@ const choseNodeFun = async (data: any) => {
parentPath.value = currentTreeNodeInfo.value.objectKey.replace(currentTreeNodeInfo.value.originalName + '/', '');
console.log(data, 'data');
// const res = await getUserFilePermissionFun({
// current: 1,
// size: 10,
// });
// tableData.value = res.data.data;
// if (baseTableRef.value) {
// baseTableRef.value.setDataFun(tableData.value);
// }
};
const updateNavFun = (data: any) => {
@@ -231,14 +222,7 @@ const ConversionStrToNum = (num: any) => {
const filterUserPermissionFun = async () => {
filterUserName.value = filterUserNameCopy.value;
// const res = await getUserFilePermissionFun({
// current: 1,
// size: 10,
// });
// tableData.value = res.data.data;
// if (baseTableRef.value) {
// baseTableRef.value.setDataFun(tableData.value);
// }
};
/**
@@ -246,26 +230,18 @@ const filterUserPermissionFun = async () => {
*/
const getUserFilePermissionFun = async (data: any) => {
if (!currentTreeNodeInfo.value.id) {
return;
}
const params: any = {
parentPath: parentPath.value,
fileName: currentTreeNodeInfo.value.originalName,
userId: '',
// type: 0,
userName: filterUserName.value,
fileId: currentTreeNodeInfo.value.id,
...data,
};
if (data) {
params.current = data.current;
params.size = data.size;
if (!params.fileId) {
return {
code: 500,
};
}
const res: any = await queryUserFilePermissionApi(params);
if (res && res.code === 200) {
console.log(res, 'resresres');
res.data.data = res.data.data.map((item: any) => {
const permissionStr = ConversionStrToNum(item.permission);
return {
@@ -282,8 +258,6 @@ const getUserFilePermissionFun = async (data: any) => {
// return res.data;
return res;
} else {
}
};

View File

@@ -1303,7 +1303,7 @@ onMounted(async () => {
await initPerformanceCompletionAtWorkstations();
await initPerformanceCompletionAtDiscipline();
await initReviewPassed();
await initAbnormalWorkstation();
// await initAbnormalWorkstation();
});
</script>
<style lang="scss" scoped>

View File

@@ -6,7 +6,7 @@ import { useNodeAttribute } from './nodeEvents';
* 校验流程合理性
* @param cells
*/
export const getRelationNodeAndVerifyFlowFun = (cells:any, templateName:string, uuid:string) => {
export const getRelationNodeAndVerifyFlowFun = (cells: any, templateName: string, uuid: string) => {
const { drawerVisible } = useNodeAttribute();
// 关闭配置弹窗
drawerVisible.value = false;
@@ -66,7 +66,7 @@ const sortNodeAndEdge = (nodeArr: any, edgeArr: any) => {
const relationNode = startNode;
console.log('relationNode', startNode);
const repeatNodeObj:any = {};
const repeatNodeObj: any = {};
for (let index = 0; index < edgeArr.length; index++) {
if (!repeatNodeObj[edgeArr[index].target]) {
repeatNodeObj[edgeArr[index].target] = [];
@@ -93,7 +93,7 @@ const sortNodeAndEdge = (nodeArr: any, edgeArr: any) => {
console.log('开始向node里插入preNode');
insertRepeatToNode([relationNode], repeatNodeArr, nodeArr);
const includeIds:string[] = [];
const includeIds: string[] = [];
console.log('校验流程尾部是否都为结束节点');
if (!verifyEndNode([relationNode], includeIds)) {
return false;
@@ -120,11 +120,11 @@ const sortNodeAndEdge = (nodeArr: any, edgeArr: any) => {
* @param nodeArr
* @param edgeArr
*/
const getNodeRelation = (preNode:any, includeId:any, nodeArr: any, edgeArr: any) => {
const getNodeRelation = (preNode: any, includeId: any, nodeArr: any, edgeArr: any) => {
preNode.children = [];
for (let index = 0; index < edgeArr.length; index++) {
if (edgeArr[index].source === preNode.id) {
const nextNode = nodeArr.find((item:any) => item.id === edgeArr[index].target);
const nextNode = nodeArr.find((item: any) => item.id === edgeArr[index].target);
includeId.push(nextNode.id);
getNodeRelation(nextNode, includeId, nodeArr, edgeArr);
preNode.children.push(nextNode);
@@ -132,14 +132,14 @@ const getNodeRelation = (preNode:any, includeId:any, nodeArr: any, edgeArr: any)
}
};
const insertRepeatToNode = (relationNode:any, repeatNodeArr:any, nodeArr:any) => {
const insertRepeatToNode = (relationNode: any, repeatNodeArr: any, nodeArr: any) => {
for (let index = 0; index < relationNode.length; index++) {
for (let j = 0; j < repeatNodeArr.length; j++) {
if (relationNode[index].id === repeatNodeArr[j].selfId) {
// console.log('relationNode[index]' + index, relationNode[index].label, relationNode[index].id);
// console.log('repeatNodeArr' + index, repeatNodeArr[j]);
relationNode[index].preNode = repeatNodeArr[j].repeatIds.map((item:any) => {
return { ...nodeArr.find((node:any) => node.id === item), children: [] };
relationNode[index].preNode = repeatNodeArr[j].repeatIds.map((item: any) => {
return { ...nodeArr.find((node: any) => node.id === item), children: [] };
});
}
}
@@ -149,13 +149,13 @@ const insertRepeatToNode = (relationNode:any, repeatNodeArr:any, nodeArr:any) =>
}
};
const verifyEndNode = (nodeArr:any, includeIds:string[]):boolean => {
const verifyEndNode = (nodeArr: any, includeIds: string[]): boolean => {
let isEnd = true;
for (let index = 0; index < nodeArr.length; index++) {
if (!includeIds.includes(nodeArr[index].id)) {
includeIds.push(nodeArr[index].id);
}
if (nodeArr[index].children.length > 0 ) {
if (nodeArr[index].children.length > 0) {
if (isEnd) {
isEnd = verifyEndNode(nodeArr[index].children, includeIds);
}
@@ -187,12 +187,12 @@ const checkStartEndNode = (nodeArr: any) => {
return true;
};
const formatNodeAndEdge = (edgeArr:any[], nodeArr:any[]) => {
const formatNodeAndEdge = (edgeArr: any[], nodeArr: any[]) => {
console.log('edgeArr', edgeArr);
console.log('nodeArr', nodeArr);
const edgeFormatArr:any = [];
const nodeFormatArr:any = [];
edgeArr.forEach((item:any) => {
const edgeFormatArr: any = [];
const nodeFormatArr: any = [];
edgeArr.forEach((item: any) => {
edgeFormatArr.push({
id: item.id,
type: 'sequenceFlow',
@@ -200,14 +200,14 @@ const formatNodeAndEdge = (edgeArr:any[], nodeArr:any[]) => {
targetRef: item.target,
});
});
nodeArr.forEach((node:any) => {
const formatItem:any = {
nodeArr.forEach((node: any) => {
const formatItem: any = {
id: node.id,
type: node.type,
nodeType: node.nodeType,
name: node.label,
};
edgeArr.forEach((edge:any) => {
edgeArr.forEach((edge: any) => {
if (node.id === edge.source) {
formatItem['incomingFlows'] = [edge.id];
}

View File

@@ -76,7 +76,7 @@ onMounted(() => {
appProperty.name = data.label;
appProperty.iconUrl = data.iconUrl;
appProperty.type = data.type;
appProperty.status = data.flowNodeInfo.nodeStatus || 'pending';
appProperty.status = data.flowNodeInfo?.nodeStatus || 'pending';
// console.log('data', data, appProperty);
}
}

View File

@@ -1,6 +1,6 @@
<template>
<div class="param-set-page">
<flowNodeParamTable :node-params="nodeParamData"></flowNodeParamTable>
<flowNodeParamTable :node-params="nodeParamData" :current-node="currentRunFlowNode"></flowNodeParamTable>
</div>
</template>