Pre Merge pull request !120 from Jason/dev

pull/120/MERGE
Jason 2025-05-29 01:00:33 +00:00 committed by Gitee
commit e5de909263
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
4 changed files with 361 additions and 29 deletions

View File

@ -0,0 +1,228 @@
<script setup lang="ts">
import type { HttpRequestParam } from '../../../consts';
import { Plus, Trash2 } from '@vben/icons';
import {
Button,
Col,
FormItem,
Input,
Row,
Select,
SelectOption,
} from 'ant-design-vue';
import {
BPM_HTTP_REQUEST_PARAM_TYPES,
BpmHttpRequestParamTypeEnum,
} from '../../../consts';
import { useFormFieldsAndStartUser } from '../../../helpers';
defineOptions({ name: 'HttpRequestParamSetting' });
const props = defineProps({
header: {
type: Array as () => HttpRequestParam[],
required: false,
default: () => [],
},
body: {
type: Array as () => HttpRequestParam[],
required: false,
default: () => [],
},
bind: {
type: String,
required: true,
},
});
//
const formFieldOptions = useFormFieldsAndStartUser();
/** 添加请求配置项 */
const addHttpRequestParam = (arr: HttpRequestParam[]) => {
arr.push({
key: '',
type: BpmHttpRequestParamTypeEnum.FIXED_VALUE,
value: '',
});
};
/** 删除请求配置项 */
const deleteHttpRequestParam = (arr: HttpRequestParam[], index: number) => {
arr.splice(index, 1);
};
</script>
<template>
<FormItem
label="请求头"
:label-col="{ span: 24 }"
:wrapper-col="{ span: 24 }"
>
<Row :gutter="8" v-for="(item, index) in props.header" :key="index">
<Col :span="7">
<FormItem
:name="[bind, 'header', index, 'key']"
:rules="{
required: true,
message: '参数名不能为空',
trigger: ['blur', 'change'],
}"
>
<Input placeholder="参数名不能为空" v-model:value="item.key" />
</FormItem>
</Col>
<Col :span="5">
<Select v-model:value="item.type">
<SelectOption
v-for="types in BPM_HTTP_REQUEST_PARAM_TYPES"
:key="types.value"
:label="types.label"
:value="types.value"
>
{{ types.label }}
</SelectOption>
</Select>
</Col>
<Col :span="10">
<FormItem
:name="[bind, 'header', index, 'value']"
:rules="{
required: true,
message: '参数值不能为空',
trigger: ['blur', 'change'],
}"
v-if="item.type === BpmHttpRequestParamTypeEnum.FIXED_VALUE"
>
<Input placeholder="请求头" v-model:value="item.value" />
</FormItem>
<FormItem
:name="[bind, 'header', index, 'value']"
:rules="{
required: true,
message: '参数值不能为空',
trigger: 'change',
}"
v-if="item.type === BpmHttpRequestParamTypeEnum.FROM_FORM"
>
<Select v-model:value="item.value" placeholder="请选择表单字段">
<SelectOption
v-for="(field, fIdx) in formFieldOptions"
:key="fIdx"
:label="field.title"
:value="field.field"
:disabled="!field.required"
>
{{ field.title }}
</SelectOption>
</Select>
</FormItem>
</Col>
<Col :span="2">
<div class="flex h-[32px] items-center">
<Trash2
class="size-4 cursor-pointer text-red-500"
@click="deleteHttpRequestParam(props.header, index)"
/>
</div>
</Col>
</Row>
<Button
type="link"
@click="addHttpRequestParam(props.header)"
class="flex items-center"
>
<template #icon>
<Plus class="size-[18px]" />
</template>
添加一行
</Button>
</FormItem>
<FormItem
label="请求体"
:label-col="{ span: 24 }"
:wrapper-col="{ span: 24 }"
>
<Row :gutter="8" v-for="(item, index) in props.body" :key="index">
<Col :span="7">
<FormItem
:name="[bind, 'body', index, 'key']"
:rules="{
required: true,
message: '参数名不能为空',
trigger: ['blur', 'change'],
}"
>
<Input placeholder="参数名" v-model:value="item.key" />
</FormItem>
</Col>
<Col :span="5">
<Select v-model:value="item.type">
<SelectOption
v-for="types in BPM_HTTP_REQUEST_PARAM_TYPES"
:key="types.value"
:label="types.label"
:value="types.value"
>
{{ types.label }}
</SelectOption>
</Select>
</Col>
<Col :span="10">
<FormItem
:name="[bind, 'body', index, 'value']"
:rules="{
required: true,
message: '参数值不能为空',
trigger: ['blur', 'change'],
}"
v-if="item.type === BpmHttpRequestParamTypeEnum.FIXED_VALUE"
>
<Input placeholder="参数值" v-model:value="item.value" />
</FormItem>
<FormItem
:name="[bind, 'body', index, 'value']"
:rules="{
required: true,
message: '参数值不能为空',
trigger: 'change',
}"
v-if="item.type === BpmHttpRequestParamTypeEnum.FROM_FORM"
>
<Select v-model:value="item.value" placeholder="请选择表单字段">
<SelectOption
v-for="(field, fIdx) in formFieldOptions"
:key="fIdx"
:label="field.title"
:value="field.field"
:disabled="!field.required"
>
{{ field.title }}
</SelectOption>
</Select>
</FormItem>
</Col>
<Col :span="2">
<div class="flex h-[32px] items-center">
<Trash2
class="size-4 cursor-pointer text-red-500"
@click="deleteHttpRequestParam(props.body, index)"
/>
</div>
</Col>
</Row>
<Button
type="link"
@click="addHttpRequestParam(props.body)"
class="flex items-center"
>
<template #icon>
<Plus class="size-[18px]" />
</template>
添加一行
</Button>
</FormItem>
</template>
<style lang="scss" scoped></style>

View File

@ -0,0 +1,107 @@
<script setup lang="ts">
import { computed, ref } from 'vue';
import {
Alert,
Divider,
Form,
FormItem,
Input,
Switch,
TypographyText,
} from 'ant-design-vue';
import HttpRequestParamSetting from './http-request-param-setting.vue';
const props = defineProps({
modelValue: {
type: Object,
required: true,
},
formFieldOptions: {
type: Object,
required: true,
},
});
const emit = defineEmits(['update:modelValue']);
const listenerFormRef = ref();
const configForm = computed({
get() {
return props.modelValue;
},
set(newValue) {
emit('update:modelValue', newValue);
},
});
const taskListener = ref([
{
name: '创建任务',
type: 'Create',
},
{
name: '指派任务执行人员',
type: 'Assign',
},
{
name: '完成任务',
type: 'Complete',
},
]);
const validate = async () => {
if (!listenerFormRef.value) return false;
return await listenerFormRef.value.validate();
};
defineExpose({ validate });
</script>
<template>
<Form ref="listenerFormRef" :model="configForm" :label-col="{ span: 24 }">
<div
v-for="(listener, listenerIdx) in taskListener"
:key="listenerIdx"
class="pl-2"
>
<Divider orientation="left">
<TypographyText tag="b" size="large">
{{ listener.name }}
</TypographyText>
</Divider>
<FormItem>
<Switch
v-model:checked="configForm[`task${listener.type}ListenerEnable`]"
checked-children="开启"
un-checked-children="关闭"
/>
</FormItem>
<div v-if="configForm[`task${listener.type}ListenerEnable`]">
<FormItem>
<Alert
message="仅支持 POST 请求,以请求体方式接收参数"
type="warning"
show-icon
:closable="false"
/>
</FormItem>
<FormItem
label="请求地址"
:name="`task${listener.type}ListenerPath`"
:rules="{
required: true,
message: '请求地址不能为空',
trigger: ['blur', 'change'],
}"
>
<Input
v-model:value="configForm[`task${listener.type}ListenerPath`]"
/>
</FormItem>
<HttpRequestParamSetting
:header="configForm[`task${listener.type}Listener`].header"
:body="configForm[`task${listener.type}Listener`].body"
:bind="`task${listener.type}Listener`"
/>
</div>
</div>
</Form>
</template>

View File

@ -34,7 +34,6 @@ import {
TypographyText,
} from 'ant-design-vue';
// TODO import { defaultProps4AntTree } from '#/utils/tree';
import {
APPROVE_METHODS,
APPROVE_TYPE,
@ -65,10 +64,9 @@ import {
useNodeName,
useWatchNode,
} from '../../helpers';
import UserTaskListener from './modules/user-task-listener.vue';
import { convertTimeUnit, getApproveTypeText } from './utils';
// TODO import UserTaskListener from './components/UserTaskListener.vue';
defineOptions({ name: 'UserTaskNodeConfig' });
const props = defineProps({
flowNode: {
@ -233,8 +231,7 @@ const {
cTimeoutMaxRemindCount,
} = useTimeoutHandler();
// TODO
// const userTaskListenerRef = ref();
const userTaskListenerRef = ref();
/** 节点类型名称 */
const nodeTypeName = computed(() => {
@ -253,25 +250,24 @@ const saveConfig = async () => {
drawerApi.close();
return true;
}
// TODO
// activeTabName.value = 'listener';
// await nextTick();
activeTabName.value = 'user';
if (!formRef.value) return false;
// TODO
// if (!userTaskListenerRef.value) return false;
// const valid =
// (await formRef.value.validate()) &&
// (await userTaskListenerRef.value.validate());
if (!userTaskListenerRef.value) return false;
if (!(await formRef.value.validate())) {
activeTabName.value = 'user';
//
const userFormValid = await formRef.value.validate().catch(() => false);
const listenerValid = await userTaskListenerRef.value.validate().catch(() => {
return false;
});
// Tab
if (!listenerValid) {
activeTabName.value = 'listener';
return false;
}
// Tab
if (!userFormValid) {
activeTabName.value = 'user';
return false;
}
// TODO
// if (!(await userTaskListenerRef.value.validate())) {
// activeTabName.value = 'listener';
// }
const showText = getShowText();
if (!showText) return false;
@ -658,10 +654,14 @@ onMounted(() => {
label="指定部门"
name="deptIds"
>
<!-- TODO :replace-fields="defaultProps4AntTree" -->
<TreeSelect
v-model:value="configForm.deptIds"
:tree-data="deptTreeOptions"
:field-names="{
label: 'name',
value: 'id',
children: 'children',
}"
empty-text="加载中,请稍后"
multiple
node-key="id"
@ -1225,14 +1225,12 @@ onMounted(() => {
</div>
</div>
</TabPane>
<TabPane tab="监听器" key="listener">
<!-- TODO 待实现 -->
<span>待实现</span>
<!-- <UserTaskListener
<TabPane tab="监听器" key="listener" :force-render="true">
<UserTaskListener
ref="userTaskListenerRef"
v-model:value="configForm"
v-model="configForm"
:form-field-options="formFieldOptions"
/> -->
/>
</TabPane>
</Tabs>
<template #footer>

View File

@ -338,7 +338,6 @@ const handleDeploy = async () => {
/** 步骤切换处理 */
const handleStepClick = async (index: number) => {
try {
console.warn('handleStepClick', index);
if (index !== 0) {
await validateBasic();
}