mirror of
https://gitee.com/myxzgzs/boyue-ui-admin-vue3
synced 2025-08-08 16:32:43 +08:00
Merge branch 'feature/bpm' of https://gitee.com/yudaocode/yudao-ui-admin-vue3
# Conflicts: # src/views/system/menu/index.vue
This commit is contained in:
commit
c6f70cce00
@ -246,15 +246,15 @@ export type AssignEmptyHandler = {
|
|||||||
export type ListenerHandler = {
|
export type ListenerHandler = {
|
||||||
enable: boolean
|
enable: boolean
|
||||||
path?: string
|
path?: string
|
||||||
header?: ListenerParam[]
|
header?: HttpRequestParam[]
|
||||||
body?: ListenerParam[]
|
body?: HttpRequestParam[]
|
||||||
}
|
}
|
||||||
export type ListenerParam = {
|
export type HttpRequestParam = {
|
||||||
key: string
|
key: string
|
||||||
type: number
|
type: number
|
||||||
value: string
|
value: string
|
||||||
}
|
}
|
||||||
export enum ListenerParamTypeEnum {
|
export enum BpmHttpRequestParamTypeEnum {
|
||||||
/**
|
/**
|
||||||
* 固定值
|
* 固定值
|
||||||
*/
|
*/
|
||||||
@ -264,7 +264,7 @@ export enum ListenerParamTypeEnum {
|
|||||||
*/
|
*/
|
||||||
FROM_FORM = 2
|
FROM_FORM = 2
|
||||||
}
|
}
|
||||||
export const LISTENER_MAP_TYPES = [
|
export const BPM_HTTP_REQUEST_PARAM_TYPES = [
|
||||||
{
|
{
|
||||||
value: 1,
|
value: 1,
|
||||||
label: '固定值'
|
label: '固定值'
|
||||||
@ -371,13 +371,13 @@ export enum TimeUnitType {
|
|||||||
/**
|
/**
|
||||||
* 条件节点设置结构定义,用于条件节点
|
* 条件节点设置结构定义,用于条件节点
|
||||||
*/
|
*/
|
||||||
export type ConditionSetting = {
|
export type ConditionSetting = {
|
||||||
// 条件类型
|
// 条件类型
|
||||||
conditionType?: ConditionType,
|
conditionType?: ConditionType
|
||||||
// 条件表达式
|
// 条件表达式
|
||||||
conditionExpression?: string,
|
conditionExpression?: string
|
||||||
// 条件组
|
// 条件组
|
||||||
conditionGroups?: ConditionGroup,
|
conditionGroups?: ConditionGroup
|
||||||
// 是否默认的条件
|
// 是否默认的条件
|
||||||
defaultFlow?: boolean
|
defaultFlow?: boolean
|
||||||
}
|
}
|
||||||
@ -710,13 +710,14 @@ export type RouterSetting = {
|
|||||||
conditionGroups: ConditionGroup
|
conditionGroups: ConditionGroup
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==================== 触发器相关定义 ====================
|
// ==================== 触发器相关定义 ====================
|
||||||
/**
|
/**
|
||||||
* 触发器节点结构定义
|
* 触发器节点结构定义
|
||||||
*/
|
*/
|
||||||
export type TriggerSetting = {
|
export type TriggerSetting = {
|
||||||
type: TriggerTypeEnum
|
type: TriggerTypeEnum
|
||||||
httpRequestSetting: HttpRequestTriggerSetting
|
httpRequestSetting?: HttpRequestTriggerSetting
|
||||||
|
normalFormSetting?: NormalFormTriggerSetting
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -727,6 +728,10 @@ export enum TriggerTypeEnum {
|
|||||||
* 发送 HTTP 请求触发器
|
* 发送 HTTP 请求触发器
|
||||||
*/
|
*/
|
||||||
HTTP_REQUEST = 1,
|
HTTP_REQUEST = 1,
|
||||||
|
/**
|
||||||
|
* 更新流程表单触发器
|
||||||
|
*/
|
||||||
|
UPDATE_NORMAL_FORM = 2 // TODO @jason:FORM_UPDATE?
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -736,11 +741,22 @@ export type HttpRequestTriggerSetting = {
|
|||||||
// 请求 URL
|
// 请求 URL
|
||||||
url: string
|
url: string
|
||||||
// 请求头参数设置
|
// 请求头参数设置
|
||||||
header?: ListenerParam[] // TODO 需要重命名一下
|
header?: HttpRequestParam[]
|
||||||
// 请求体参数设置
|
// 请求体参数设置
|
||||||
body?: ListenerParam[]
|
body?: HttpRequestParam[]
|
||||||
|
// 请求响应设置
|
||||||
|
response?: Record<string, string>[]
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 流程表单触发器配置结构定义
|
||||||
|
*/
|
||||||
|
export type NormalFormTriggerSetting = {
|
||||||
|
// 更新表单字段
|
||||||
|
updateFormFields?: Record<string, any>
|
||||||
}
|
}
|
||||||
|
|
||||||
export const TRIGGER_TYPES: DictDataVO[] = [
|
export const TRIGGER_TYPES: DictDataVO[] = [
|
||||||
{ label: 'HTTP 请求', value: TriggerTypeEnum.HTTP_REQUEST }
|
{ label: 'HTTP 请求', value: TriggerTypeEnum.HTTP_REQUEST },
|
||||||
|
{ label: '修改表单数据', value: TriggerTypeEnum.UPDATE_NORMAL_FORM }
|
||||||
]
|
]
|
||||||
|
@ -14,7 +14,8 @@ import {
|
|||||||
AssignStartUserHandlerType,
|
AssignStartUserHandlerType,
|
||||||
AssignEmptyHandlerType,
|
AssignEmptyHandlerType,
|
||||||
FieldPermissionType,
|
FieldPermissionType,
|
||||||
ListenerParam
|
HttpRequestParam,
|
||||||
|
ProcessVariableEnum
|
||||||
} from './consts'
|
} from './consts'
|
||||||
import { parseFormFields } from '@/components/FormCreate/src/utils'
|
import { parseFormFields } from '@/components/FormCreate/src/utils'
|
||||||
|
|
||||||
@ -105,14 +106,31 @@ export function useFormFieldsPermission(defaultPermission: FieldPermissionType)
|
|||||||
getNodeConfigFormFields
|
getNodeConfigFormFields
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description 获取表单的字段
|
* @description 获取流程表单的字段
|
||||||
*/
|
*/
|
||||||
export function useFormFields() {
|
export function useFormFields() {
|
||||||
const formFields = inject<Ref<string[]>>('formFields', ref([])) // 流程表单字段
|
const formFields = inject<Ref<string[]>>('formFields', ref([])) // 流程表单字段
|
||||||
return parseFormCreateFields(unref(formFields))
|
return parseFormCreateFields(unref(formFields))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO @芋艿:后续需要把各种类似 useFormFieldsPermission 的逻辑,抽成一个通用方法。
|
||||||
|
/**
|
||||||
|
* @description 获取流程表单的字段和发起人字段
|
||||||
|
*/
|
||||||
|
export function useFormFieldsAndStartUser() {
|
||||||
|
const injectFormFields = inject<Ref<string[]>>('formFields', ref([])) // 流程表单字段
|
||||||
|
const formFields = parseFormCreateFields(unref(injectFormFields))
|
||||||
|
// 添加发起人
|
||||||
|
formFields.unshift({
|
||||||
|
field: ProcessVariableEnum.START_USER_ID,
|
||||||
|
title: '发起人',
|
||||||
|
required: true
|
||||||
|
})
|
||||||
|
return formFields
|
||||||
|
}
|
||||||
|
|
||||||
export type UserTaskFormType = {
|
export type UserTaskFormType = {
|
||||||
candidateStrategy: CandidateStrategy
|
candidateStrategy: CandidateStrategy
|
||||||
approveMethod: ApproveMethodType
|
approveMethod: ApproveMethodType
|
||||||
@ -139,20 +157,20 @@ export type UserTaskFormType = {
|
|||||||
taskCreateListenerEnable?: boolean
|
taskCreateListenerEnable?: boolean
|
||||||
taskCreateListenerPath?: string
|
taskCreateListenerPath?: string
|
||||||
taskCreateListener?: {
|
taskCreateListener?: {
|
||||||
header: ListenerParam[],
|
header: HttpRequestParam[]
|
||||||
body: ListenerParam[]
|
body: HttpRequestParam[]
|
||||||
}
|
}
|
||||||
taskAssignListenerEnable?: boolean
|
taskAssignListenerEnable?: boolean
|
||||||
taskAssignListenerPath?: string
|
taskAssignListenerPath?: string
|
||||||
taskAssignListener?: {
|
taskAssignListener?: {
|
||||||
header: ListenerParam[],
|
header: HttpRequestParam[]
|
||||||
body: ListenerParam[]
|
body: HttpRequestParam[]
|
||||||
}
|
}
|
||||||
taskCompleteListenerEnable?: boolean
|
taskCompleteListenerEnable?: boolean
|
||||||
taskCompleteListenerPath?: string
|
taskCompleteListenerPath?: string
|
||||||
taskCompleteListener?:{
|
taskCompleteListener?: {
|
||||||
header: ListenerParam[],
|
header: HttpRequestParam[]
|
||||||
body: ListenerParam[]
|
body: HttpRequestParam[]
|
||||||
}
|
}
|
||||||
signEnable: boolean
|
signEnable: boolean
|
||||||
reasonRequire: boolean
|
reasonRequire: boolean
|
||||||
|
@ -47,10 +47,9 @@ import {
|
|||||||
SimpleFlowNode,
|
SimpleFlowNode,
|
||||||
ConditionType,
|
ConditionType,
|
||||||
COMPARISON_OPERATORS,
|
COMPARISON_OPERATORS,
|
||||||
ProcessVariableEnum
|
|
||||||
} from '../consts'
|
} from '../consts'
|
||||||
import { getDefaultConditionNodeName } from '../utils'
|
import { getDefaultConditionNodeName } from '../utils'
|
||||||
import { useFormFields } from '../node'
|
import { useFormFieldsAndStartUser } from '../node'
|
||||||
import Condition from './components/Condition.vue'
|
import Condition from './components/Condition.vue'
|
||||||
const message = useMessage() // 消息弹窗
|
const message = useMessage() // 消息弹窗
|
||||||
defineOptions({
|
defineOptions({
|
||||||
@ -176,23 +175,12 @@ const getShowText = (): string => {
|
|||||||
}
|
}
|
||||||
return showText
|
return showText
|
||||||
}
|
}
|
||||||
|
// 流程表单字段和发起人字段
|
||||||
const fieldsInfo = useFormFields()
|
const fieldOptions = useFormFieldsAndStartUser()
|
||||||
/** 条件规则可选择的表单字段 */
|
|
||||||
const fieldOptions = computed(() => {
|
|
||||||
const fieldsCopy = fieldsInfo.slice()
|
|
||||||
// 固定添加发起人 ID 字段
|
|
||||||
fieldsCopy.unshift({
|
|
||||||
field: ProcessVariableEnum.START_USER_ID,
|
|
||||||
title: '发起人',
|
|
||||||
required: true
|
|
||||||
})
|
|
||||||
return fieldsCopy
|
|
||||||
})
|
|
||||||
|
|
||||||
/** 获取字段名称 */
|
/** 获取字段名称 */
|
||||||
const getFieldTitle = (field: string) => {
|
const getFieldTitle = (field: string) => {
|
||||||
const item = fieldOptions.value.find((item) => item.field === field)
|
const item = fieldOptions.find((item) => item.field === field)
|
||||||
return item?.title
|
return item?.title
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,6 +124,7 @@ const saveConfig = async () => {
|
|||||||
if (!valid) return false
|
if (!valid) return false
|
||||||
const showText = getShowText()
|
const showText = getShowText()
|
||||||
if (!showText) return false
|
if (!showText) return false
|
||||||
|
currentNode.value.name = nodeName.value!
|
||||||
currentNode.value.showText = showText
|
currentNode.value.showText = showText
|
||||||
if (configForm.value.delayType === DelayTypeEnum.FIXED_TIME_DURATION) {
|
if (configForm.value.delayType === DelayTypeEnum.FIXED_TIME_DURATION) {
|
||||||
currentNode.value.delaySetting = {
|
currentNode.value.delaySetting = {
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<!-- HTTP 请求触发器 -->
|
||||||
<div
|
<div
|
||||||
v-if="configForm.type === TriggerTypeEnum.HTTP_REQUEST && configForm.httpRequestSetting"
|
v-if="configForm.type === TriggerTypeEnum.HTTP_REQUEST && configForm.httpRequestSetting"
|
||||||
>
|
>
|
||||||
@ -46,14 +47,137 @@
|
|||||||
:closable="false"
|
:closable="false"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<!-- 请求地址-->
|
||||||
<el-form-item label="请求地址" prop="httpRequestSetting.url">
|
<el-form-item label="请求地址" prop="httpRequestSetting.url">
|
||||||
<el-input v-model="configForm.httpRequestSetting.url" />
|
<el-input v-model="configForm.httpRequestSetting.url" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<!-- 请求头,请求体设置-->
|
||||||
<HttpRequestParamSetting
|
<HttpRequestParamSetting
|
||||||
:header="configForm.httpRequestSetting.header"
|
:header="configForm.httpRequestSetting.header"
|
||||||
:body="configForm.httpRequestSetting.body"
|
:body="configForm.httpRequestSetting.body"
|
||||||
:bind="'httpRequestSetting'"
|
:bind="'httpRequestSetting'"
|
||||||
/>
|
/>
|
||||||
|
<!-- 返回值设置-->
|
||||||
|
<el-form-item label="返回值">
|
||||||
|
<el-alert
|
||||||
|
title="通过请求返回值, 可以修改流程表单的值"
|
||||||
|
type="warning"
|
||||||
|
show-icon
|
||||||
|
:closable="false"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<div
|
||||||
|
class="flex pt-2"
|
||||||
|
v-for="(item, index) in configForm.httpRequestSetting.response"
|
||||||
|
:key="index"
|
||||||
|
>
|
||||||
|
<div class="mr-2">
|
||||||
|
<el-form-item
|
||||||
|
:prop="`httpRequestSetting.response.${index}.key`"
|
||||||
|
:rules="{
|
||||||
|
required: true,
|
||||||
|
message: '表单字段不能为空',
|
||||||
|
trigger: 'blur'
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<el-select class="w-160px!" v-model="item.key" placeholder="请选择表单字段">
|
||||||
|
<el-option
|
||||||
|
v-for="(field, fIdx) in formFields"
|
||||||
|
:key="fIdx"
|
||||||
|
:label="field.title"
|
||||||
|
:value="field.field"
|
||||||
|
:disabled="!field.required"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
<div class="mr-2">
|
||||||
|
<el-form-item
|
||||||
|
:prop="`httpRequestSetting.response.${index}.value`"
|
||||||
|
:rules="{
|
||||||
|
required: true,
|
||||||
|
message: '请求返回字段不能为空',
|
||||||
|
trigger: 'blur'
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<el-input class="w-160px" v-model="item.value" placeholder="请求返回字段" />
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
<div class="mr-1 pt-1 cursor-pointer">
|
||||||
|
<Icon
|
||||||
|
icon="ep:delete"
|
||||||
|
:size="18"
|
||||||
|
@click="deleteHttpResponseSetting(configForm.httpRequestSetting.response!, index)"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
text
|
||||||
|
@click="addHttpResponseSetting(configForm.httpRequestSetting.response!)"
|
||||||
|
>
|
||||||
|
<Icon icon="ep:plus" class="mr-5px" />添加一行
|
||||||
|
</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="
|
||||||
|
configForm.type === TriggerTypeEnum.UPDATE_NORMAL_FORM && configForm.normalFormSetting
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<el-divider content-position="left">修改表单设置</el-divider>
|
||||||
|
<div
|
||||||
|
class="flex items-center"
|
||||||
|
v-for="key in Object.keys(configForm.normalFormSetting.updateFormFields!)"
|
||||||
|
:key="key"
|
||||||
|
>
|
||||||
|
<div class="mr-2 flex items-center">
|
||||||
|
<el-form-item>
|
||||||
|
<el-select
|
||||||
|
class="w-160px!"
|
||||||
|
:model-value="key"
|
||||||
|
@update:model-value="(newKey) => updateFormFieldKey(key, newKey)"
|
||||||
|
placeholder="请选择表单字段"
|
||||||
|
:disabled="key !== ''"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="(field, fIdx) in optionalUpdateFormFields"
|
||||||
|
:key="fIdx"
|
||||||
|
:label="field.title"
|
||||||
|
:value="field.field"
|
||||||
|
:disabled="field.disabled"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
<div class="mx-2"><el-form-item>的值设置为</el-form-item></div>
|
||||||
|
<div class="mr-2">
|
||||||
|
<el-form-item
|
||||||
|
:prop="`normalFormSetting.updateFormFields.${key}`"
|
||||||
|
:rules="{
|
||||||
|
required: true,
|
||||||
|
message: '值不能为空',
|
||||||
|
trigger: 'blur'
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<el-input
|
||||||
|
class="w-160px"
|
||||||
|
v-model="configForm.normalFormSetting.updateFormFields![key]"
|
||||||
|
placeholder="请输入"
|
||||||
|
:disabled="!key"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
<div class="mr-1 pt-1 cursor-pointer">
|
||||||
|
<el-form-item>
|
||||||
|
<Icon icon="ep:delete" :size="18" @click="deleteFormFieldSetting(key)" />
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<el-button type="primary" text @click="addFormFieldSetting()">
|
||||||
|
<Icon icon="ep:plus" class="mr-5px" />添加修改字段
|
||||||
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
</el-form>
|
</el-form>
|
||||||
</div>
|
</div>
|
||||||
@ -68,7 +192,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { SimpleFlowNode, NodeType, TriggerSetting, TRIGGER_TYPES, TriggerTypeEnum } from '../consts'
|
import { SimpleFlowNode, NodeType, TriggerSetting, TRIGGER_TYPES, TriggerTypeEnum } from '../consts'
|
||||||
import { useWatchNode, useDrawer, useNodeName } from '../node'
|
import { useWatchNode, useDrawer, useNodeName, useFormFields } from '../node'
|
||||||
import HttpRequestParamSetting from './components/HttpRequestParamSetting.vue'
|
import HttpRequestParamSetting from './components/HttpRequestParamSetting.vue'
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
@ -80,6 +204,7 @@ const props = defineProps({
|
|||||||
required: true
|
required: true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
// 抽屉配置
|
// 抽屉配置
|
||||||
const { settingVisible, closeDrawer, openDrawer } = useDrawer()
|
const { settingVisible, closeDrawer, openDrawer } = useDrawer()
|
||||||
// 当前节点
|
// 当前节点
|
||||||
@ -91,9 +216,7 @@ const formRef = ref() // 表单 Ref
|
|||||||
// 表单校验规则
|
// 表单校验规则
|
||||||
const formRules = reactive({
|
const formRules = reactive({
|
||||||
type: [{ required: true, message: '触发器类型不能为空', trigger: 'change' }],
|
type: [{ required: true, message: '触发器类型不能为空', trigger: 'change' }],
|
||||||
httpRequestSetting: {
|
'httpRequestSetting.url': [{ required: true, message: '请求地址不能为空', trigger: 'blur' }]
|
||||||
url: [{ required: true, message: '请求地址不能为空', trigger: 'blur' }]
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
// 触发器配置表单数据
|
// 触发器配置表单数据
|
||||||
const configForm = ref<TriggerSetting>({
|
const configForm = ref<TriggerSetting>({
|
||||||
@ -101,9 +224,56 @@ const configForm = ref<TriggerSetting>({
|
|||||||
httpRequestSetting: {
|
httpRequestSetting: {
|
||||||
url: '',
|
url: '',
|
||||||
header: [],
|
header: [],
|
||||||
body: []
|
body: [],
|
||||||
}
|
response: []
|
||||||
|
},
|
||||||
|
normalFormSetting: { updateFormFields: {} }
|
||||||
})
|
})
|
||||||
|
// 流程表单字段
|
||||||
|
const formFields = useFormFields()
|
||||||
|
|
||||||
|
// 可选的修改的表单字段
|
||||||
|
const optionalUpdateFormFields = computed(() => {
|
||||||
|
const usedFields = Object.keys(configForm.value.normalFormSetting?.updateFormFields || {})
|
||||||
|
return formFields.map((field) => ({
|
||||||
|
title: field.title,
|
||||||
|
field: field.field,
|
||||||
|
disabled: usedFields.includes(field.field)
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
|
||||||
|
const updateFormFieldKey = (oldKey: string, newKey: string) => {
|
||||||
|
if (!configForm.value.normalFormSetting?.updateFormFields) return
|
||||||
|
const value = configForm.value.normalFormSetting.updateFormFields[oldKey]
|
||||||
|
delete configForm.value.normalFormSetting.updateFormFields[oldKey]
|
||||||
|
configForm.value.normalFormSetting.updateFormFields[newKey] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 添加 HTTP 请求返回值设置项*/
|
||||||
|
const addHttpResponseSetting = (responseSetting: Record<string, string>[]) => {
|
||||||
|
responseSetting.push({
|
||||||
|
key: '',
|
||||||
|
value: ''
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除 HTTP 请求返回值设置项 */
|
||||||
|
const deleteHttpResponseSetting = (responseSetting: Record<string, string>[], index: number) => {
|
||||||
|
responseSetting.splice(index, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 添加修改表单设置项 */
|
||||||
|
const addFormFieldSetting = () => {
|
||||||
|
if (configForm.value.normalFormSetting!.updateFormFields === undefined) {
|
||||||
|
configForm.value.normalFormSetting!.updateFormFields = {}
|
||||||
|
}
|
||||||
|
configForm.value.normalFormSetting!.updateFormFields[''] = undefined
|
||||||
|
}
|
||||||
|
/** 删除修改表单设置项 */
|
||||||
|
const deleteFormFieldSetting = (key: string) => {
|
||||||
|
if (!configForm.value.normalFormSetting?.updateFormFields) return
|
||||||
|
delete configForm.value.normalFormSetting.updateFormFields[key]
|
||||||
|
}
|
||||||
|
|
||||||
/** 保存配置 */
|
/** 保存配置 */
|
||||||
const saveConfig = async () => {
|
const saveConfig = async () => {
|
||||||
@ -112,16 +282,31 @@ const saveConfig = async () => {
|
|||||||
if (!valid) return false
|
if (!valid) return false
|
||||||
const showText = getShowText()
|
const showText = getShowText()
|
||||||
if (!showText) return false
|
if (!showText) return false
|
||||||
|
currentNode.value.name = nodeName.value!
|
||||||
currentNode.value.showText = showText
|
currentNode.value.showText = showText
|
||||||
|
if (configForm.value.type === TriggerTypeEnum.HTTP_REQUEST) {
|
||||||
|
configForm.value.normalFormSetting = undefined
|
||||||
|
}
|
||||||
|
if (configForm.value.type === TriggerTypeEnum.UPDATE_NORMAL_FORM) {
|
||||||
|
configForm.value.httpRequestSetting = undefined
|
||||||
|
}
|
||||||
currentNode.value.triggerSetting = configForm.value
|
currentNode.value.triggerSetting = configForm.value
|
||||||
settingVisible.value = false
|
settingVisible.value = false
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 获取节点展示内容 */
|
/** 获取节点展示内容 */
|
||||||
const getShowText = (): string => {
|
const getShowText = (): string => {
|
||||||
let showText = ''
|
let showText = ''
|
||||||
if (configForm.value.type === TriggerTypeEnum.HTTP_REQUEST) {
|
if (configForm.value.type === TriggerTypeEnum.HTTP_REQUEST) {
|
||||||
showText = `${configForm.value.httpRequestSetting.url}`
|
showText = `${configForm.value.httpRequestSetting?.url}`
|
||||||
|
} else if (configForm.value.type === TriggerTypeEnum.UPDATE_NORMAL_FORM) {
|
||||||
|
const updatefields = Object.keys(configForm.value.normalFormSetting?.updateFormFields || {})
|
||||||
|
if (updatefields.length === 0) {
|
||||||
|
message.warning('请设置修改表单字段')
|
||||||
|
} else {
|
||||||
|
showText = '修改表单数据'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return showText
|
return showText
|
||||||
}
|
}
|
||||||
@ -130,8 +315,16 @@ const getShowText = (): string => {
|
|||||||
const showTriggerNodeConfig = (node: SimpleFlowNode) => {
|
const showTriggerNodeConfig = (node: SimpleFlowNode) => {
|
||||||
nodeName.value = node.name
|
nodeName.value = node.name
|
||||||
if (node.triggerSetting) {
|
if (node.triggerSetting) {
|
||||||
configForm.value.type = node.triggerSetting.type
|
configForm.value = {
|
||||||
configForm.value.httpRequestSetting = node.triggerSetting.httpRequestSetting
|
type: node.triggerSetting.type,
|
||||||
|
httpRequestSetting: node.triggerSetting.httpRequestSetting || {
|
||||||
|
url: '',
|
||||||
|
header: [],
|
||||||
|
body: [],
|
||||||
|
response: []
|
||||||
|
},
|
||||||
|
normalFormSetting: node.triggerSetting.normalFormSetting || { updateFormFields: {} }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@
|
|||||||
label="指定角色"
|
label="指定角色"
|
||||||
prop="roleIds"
|
prop="roleIds"
|
||||||
>
|
>
|
||||||
<el-select v-model="configForm.roleIds" clearable multiple style="width: 100%">
|
<el-select filterable v-model="configForm.roleIds" clearable multiple style="width: 100%">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in roleOptions"
|
v-for="item in roleOptions"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
@ -99,7 +99,7 @@
|
|||||||
prop="postIds"
|
prop="postIds"
|
||||||
span="24"
|
span="24"
|
||||||
>
|
>
|
||||||
<el-select v-model="configForm.postIds" clearable multiple style="width: 100%">
|
<el-select filterable v-model="configForm.postIds" clearable multiple style="width: 100%">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in postOptions"
|
v-for="item in postOptions"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
@ -114,7 +114,7 @@
|
|||||||
prop="userIds"
|
prop="userIds"
|
||||||
span="24"
|
span="24"
|
||||||
>
|
>
|
||||||
<el-select v-model="configForm.userIds" clearable multiple style="width: 100%">
|
<el-select filterable v-model="configForm.userIds" clearable multiple style="width: 100%">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in userOptions"
|
v-for="item in userOptions"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
@ -128,7 +128,7 @@
|
|||||||
label="指定用户组"
|
label="指定用户组"
|
||||||
prop="userGroups"
|
prop="userGroups"
|
||||||
>
|
>
|
||||||
<el-select v-model="configForm.userGroups" clearable multiple style="width: 100%">
|
<el-select filterable v-model="configForm.userGroups" clearable multiple style="width: 100%">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in userGroupOptions"
|
v-for="item in userGroupOptions"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
@ -142,7 +142,7 @@
|
|||||||
label="表单内用户字段"
|
label="表单内用户字段"
|
||||||
prop="formUser"
|
prop="formUser"
|
||||||
>
|
>
|
||||||
<el-select v-model="configForm.formUser" clearable style="width: 100%">
|
<el-select filterable v-model="configForm.formUser" clearable style="width: 100%">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="(item, idx) in userFieldOnFormOptions"
|
v-for="(item, idx) in userFieldOnFormOptions"
|
||||||
:key="idx"
|
:key="idx"
|
||||||
@ -157,7 +157,7 @@
|
|||||||
label="表单内部门字段"
|
label="表单内部门字段"
|
||||||
prop="formDept"
|
prop="formDept"
|
||||||
>
|
>
|
||||||
<el-select v-model="configForm.formDept" clearable style="width: 100%">
|
<el-select filterable v-model="configForm.formDept" clearable style="width: 100%">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="(item, idx) in deptFieldOnFormOptions"
|
v-for="(item, idx) in deptFieldOnFormOptions"
|
||||||
:key="idx"
|
:key="idx"
|
||||||
@ -179,7 +179,7 @@
|
|||||||
prop="deptLevel"
|
prop="deptLevel"
|
||||||
span="24"
|
span="24"
|
||||||
>
|
>
|
||||||
<el-select v-model="configForm.deptLevel" clearable>
|
<el-select filterable v-model="configForm.deptLevel" clearable>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="(item, index) in MULTI_LEVEL_DEPT"
|
v-for="(item, index) in MULTI_LEVEL_DEPT"
|
||||||
:key="index"
|
:key="index"
|
||||||
@ -245,7 +245,7 @@
|
|||||||
label="驳回节点"
|
label="驳回节点"
|
||||||
prop="returnNodeId"
|
prop="returnNodeId"
|
||||||
>
|
>
|
||||||
<el-select v-model="configForm.returnNodeId" clearable style="width: 100%">
|
<el-select filterable v-model="configForm.returnNodeId" clearable style="width: 100%">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in returnTaskList"
|
v-for="item in returnTaskList"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
@ -293,6 +293,7 @@
|
|||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-select
|
<el-select
|
||||||
|
filterable
|
||||||
v-model="timeUnit"
|
v-model="timeUnit"
|
||||||
class="mr-2"
|
class="mr-2"
|
||||||
:style="{ width: '100px' }"
|
:style="{ width: '100px' }"
|
||||||
@ -332,6 +333,7 @@
|
|||||||
span="24"
|
span="24"
|
||||||
>
|
>
|
||||||
<el-select
|
<el-select
|
||||||
|
filterable
|
||||||
v-model="configForm.assignEmptyHandlerUserIds"
|
v-model="configForm.assignEmptyHandlerUserIds"
|
||||||
clearable
|
clearable
|
||||||
multiple
|
multiple
|
||||||
@ -758,22 +760,22 @@ const showUserTaskNodeConfig = (node: SimpleFlowNode) => {
|
|||||||
getNodeConfigFormFields(node.fieldsPermission)
|
getNodeConfigFormFields(node.fieldsPermission)
|
||||||
// 5. 监听器
|
// 5. 监听器
|
||||||
// 5.1 创建任务
|
// 5.1 创建任务
|
||||||
configForm.value.taskCreateListenerEnable = node.taskCreateListener!.enable
|
configForm.value.taskCreateListenerEnable = node.taskCreateListener?.enable
|
||||||
configForm.value.taskCreateListenerPath = node.taskCreateListener!.path
|
configForm.value.taskCreateListenerPath = node.taskCreateListener?.path
|
||||||
configForm.value.taskCreateListener = {
|
configForm.value.taskCreateListener = {
|
||||||
header: node.taskCreateListener?.header ?? [],
|
header: node.taskCreateListener?.header ?? [],
|
||||||
body: node.taskCreateListener?.body ?? []
|
body: node.taskCreateListener?.body ?? []
|
||||||
}
|
}
|
||||||
// 5.2 指派任务
|
// 5.2 指派任务
|
||||||
configForm.value.taskAssignListenerEnable = node.taskAssignListener!.enable
|
configForm.value.taskAssignListenerEnable = node.taskAssignListener?.enable
|
||||||
configForm.value.taskAssignListenerPath = node.taskAssignListener!.path
|
configForm.value.taskAssignListenerPath = node.taskAssignListener?.path
|
||||||
configForm.value.taskAssignListener = {
|
configForm.value.taskAssignListener = {
|
||||||
header: node.taskAssignListener?.header ?? [],
|
header: node.taskAssignListener?.header ?? [],
|
||||||
body: node.taskAssignListener?.body ?? []
|
body: node.taskAssignListener?.body ?? []
|
||||||
}
|
}
|
||||||
// 5.3 完成任务
|
// 5.3 完成任务
|
||||||
configForm.value.taskCompleteListenerEnable = node.taskCompleteListener!.enable
|
configForm.value.taskCompleteListenerEnable = node.taskCompleteListener?.enable
|
||||||
configForm.value.taskCompleteListenerPath = node.taskCompleteListener!.path
|
configForm.value.taskCompleteListenerPath = node.taskCompleteListener?.path
|
||||||
configForm.value.taskCompleteListener = {
|
configForm.value.taskCompleteListener = {
|
||||||
header: node.taskCompleteListener?.header ?? [],
|
header: node.taskCompleteListener?.header ?? [],
|
||||||
body: node.taskCompleteListener?.body ?? []
|
body: node.taskCompleteListener?.body ?? []
|
||||||
|
@ -138,11 +138,10 @@ import {
|
|||||||
COMPARISON_OPERATORS,
|
COMPARISON_OPERATORS,
|
||||||
CONDITION_CONFIG_TYPES,
|
CONDITION_CONFIG_TYPES,
|
||||||
ConditionType,
|
ConditionType,
|
||||||
DEFAULT_CONDITION_GROUP_VALUE,
|
DEFAULT_CONDITION_GROUP_VALUE
|
||||||
ProcessVariableEnum
|
|
||||||
} from '../../consts'
|
} from '../../consts'
|
||||||
import { BpmModelFormType } from '@/utils/constants'
|
import { BpmModelFormType } from '@/utils/constants'
|
||||||
import { useFormFields } from '../../node'
|
import { useFormFieldsAndStartUser } from '../../node'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: {
|
modelValue: {
|
||||||
@ -170,17 +169,10 @@ const conditionConfigTypes = computed(() => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
/** 条件规则可选择的表单字段 */
|
/** 条件规则可选择的表单字段 */
|
||||||
const fieldOptions = computed(() => {
|
const fieldOptions = useFormFieldsAndStartUser()
|
||||||
const fieldsCopy = useFormFields().slice()
|
|
||||||
// 固定添加发起人 ID 字段
|
|
||||||
fieldsCopy.unshift({
|
|
||||||
field: ProcessVariableEnum.START_USER_ID,
|
|
||||||
title: '发起人',
|
|
||||||
required: true
|
|
||||||
})
|
|
||||||
return fieldsCopy
|
|
||||||
})
|
|
||||||
// 表单校验规则
|
// 表单校验规则
|
||||||
const formRules = reactive({
|
const formRules = reactive({
|
||||||
conditionType: [{ required: true, message: '配置方式不能为空', trigger: 'blur' }],
|
conditionType: [{ required: true, message: '配置方式不能为空', trigger: 'blur' }],
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
<div class="mr-2">
|
<div class="mr-2">
|
||||||
<el-select class="w-100px!" v-model="item.type">
|
<el-select class="w-100px!" v-model="item.type">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="types in LISTENER_MAP_TYPES"
|
v-for="types in BPM_HTTP_REQUEST_PARAM_TYPES"
|
||||||
:key="types.value"
|
:key="types.value"
|
||||||
:label="types.label"
|
:label="types.label"
|
||||||
:value="types.value"
|
:value="types.value"
|
||||||
@ -33,7 +33,7 @@
|
|||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<el-input
|
<el-input
|
||||||
v-if="item.type === ListenerParamTypeEnum.FIXED_VALUE"
|
v-if="item.type === BpmHttpRequestParamTypeEnum.FIXED_VALUE"
|
||||||
class="w-160px"
|
class="w-160px"
|
||||||
v-model="item.value"
|
v-model="item.value"
|
||||||
/>
|
/>
|
||||||
@ -47,7 +47,7 @@
|
|||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<el-select
|
<el-select
|
||||||
v-if="item.type === ListenerParamTypeEnum.FROM_FORM"
|
v-if="item.type === BpmHttpRequestParamTypeEnum.FROM_FORM"
|
||||||
class="w-160px!"
|
class="w-160px!"
|
||||||
v-model="item.value"
|
v-model="item.value"
|
||||||
>
|
>
|
||||||
@ -86,7 +86,7 @@
|
|||||||
<div class="mr-2">
|
<div class="mr-2">
|
||||||
<el-select class="w-100px!" v-model="item.type">
|
<el-select class="w-100px!" v-model="item.type">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="types in LISTENER_MAP_TYPES"
|
v-for="types in BPM_HTTP_REQUEST_PARAM_TYPES"
|
||||||
:key="types.value"
|
:key="types.value"
|
||||||
:label="types.label"
|
:label="types.label"
|
||||||
:value="types.value"
|
:value="types.value"
|
||||||
@ -103,7 +103,7 @@
|
|||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<el-input
|
<el-input
|
||||||
v-if="item.type === ListenerParamTypeEnum.FIXED_VALUE"
|
v-if="item.type === BpmHttpRequestParamTypeEnum.FIXED_VALUE"
|
||||||
class="w-160px"
|
class="w-160px"
|
||||||
v-model="item.value"
|
v-model="item.value"
|
||||||
/>
|
/>
|
||||||
@ -117,7 +117,7 @@
|
|||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<el-select
|
<el-select
|
||||||
v-if="item.type === ListenerParamTypeEnum.FROM_FORM"
|
v-if="item.type === BpmHttpRequestParamTypeEnum.FROM_FORM"
|
||||||
class="w-160px!"
|
class="w-160px!"
|
||||||
v-model="item.value"
|
v-model="item.value"
|
||||||
>
|
>
|
||||||
@ -141,20 +141,20 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ListenerParam, LISTENER_MAP_TYPES, ListenerParamTypeEnum } from '../../consts'
|
import { HttpRequestParam, BPM_HTTP_REQUEST_PARAM_TYPES, BpmHttpRequestParamTypeEnum } from '../../consts'
|
||||||
import { useFormFields } from '../../node'
|
import { useFormFieldsAndStartUser } from '../../node'
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'HttpRequestParamSetting'
|
name: 'HttpRequestParamSetting'
|
||||||
})
|
})
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
header: {
|
header: {
|
||||||
type: Array as () => ListenerParam[],
|
type: Array as () => HttpRequestParam[],
|
||||||
required: false,
|
required: false,
|
||||||
default: () => []
|
default: () => []
|
||||||
},
|
},
|
||||||
body: {
|
body: {
|
||||||
type: Array as () => ListenerParam[],
|
type: Array as () => HttpRequestParam[],
|
||||||
required: false,
|
required: false,
|
||||||
default: () => []
|
default: () => []
|
||||||
},
|
},
|
||||||
@ -164,16 +164,19 @@ const props = defineProps({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const formFieldOptions = useFormFields()
|
// 流程表单字段,发起人字段
|
||||||
|
const formFieldOptions = useFormFieldsAndStartUser()
|
||||||
const addHttpRequestParam = (arr: ListenerParam[]) => {
|
/** 添加请求配置项 */
|
||||||
|
const addHttpRequestParam = (arr: HttpRequestParam[]) => {
|
||||||
arr.push({
|
arr.push({
|
||||||
key: '',
|
key: '',
|
||||||
type: ListenerParamTypeEnum.FIXED_VALUE,
|
type: BpmHttpRequestParamTypeEnum.FIXED_VALUE,
|
||||||
value: ''
|
value: ''
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
const deleteHttpRequestParam = (arr: ListenerParam[], index: number) => {
|
|
||||||
|
/** 删除请求配置项 */
|
||||||
|
const deleteHttpRequestParam = (arr: HttpRequestParam[], index: number) => {
|
||||||
arr.splice(index, 1)
|
arr.splice(index, 1)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -307,6 +307,18 @@ const remainingRouter: AppRouteRecordRaw[] = [
|
|||||||
activityId: route.query.activityId
|
activityId: route.query.activityId
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'process-instance/report',
|
||||||
|
component: () => import('@/views/bpm/processInstance/report/index.vue'),
|
||||||
|
name: 'BpmProcessInstanceReport',
|
||||||
|
meta: {
|
||||||
|
noCache: true,
|
||||||
|
hidden: true,
|
||||||
|
canTo: true,
|
||||||
|
title: '数据报表',
|
||||||
|
activeMenu: '/bpm/manager/model'
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: 'oa/leave/create',
|
path: 'oa/leave/create',
|
||||||
component: () => import('@/views/bpm/oa/leave/create.vue'),
|
component: () => import('@/views/bpm/oa/leave/create.vue'),
|
||||||
|
@ -13,6 +13,9 @@
|
|||||||
<el-form-item label="分类标志" prop="code">
|
<el-form-item label="分类标志" prop="code">
|
||||||
<el-input v-model="formData.code" placeholder="请输入分类标志" />
|
<el-input v-model="formData.code" placeholder="请输入分类标志" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item label="分类描述" prop="description">
|
||||||
|
<el-input v-model="formData.description" type="textarea" placeholder="请输入分类描述" />
|
||||||
|
</el-form-item>
|
||||||
<el-form-item label="分类状态" prop="status">
|
<el-form-item label="分类状态" prop="status">
|
||||||
<el-radio-group v-model="formData.status">
|
<el-radio-group v-model="formData.status">
|
||||||
<el-radio
|
<el-radio
|
||||||
@ -58,6 +61,7 @@ const formData = ref({
|
|||||||
id: undefined,
|
id: undefined,
|
||||||
name: undefined,
|
name: undefined,
|
||||||
code: undefined,
|
code: undefined,
|
||||||
|
description: undefined,
|
||||||
status: CommonStatusEnum.ENABLE,
|
status: CommonStatusEnum.ENABLE,
|
||||||
sort: undefined
|
sort: undefined
|
||||||
})
|
})
|
||||||
@ -117,6 +121,7 @@ const resetForm = () => {
|
|||||||
id: undefined,
|
id: undefined,
|
||||||
name: undefined,
|
name: undefined,
|
||||||
code: undefined,
|
code: undefined,
|
||||||
|
description: undefined,
|
||||||
status: CommonStatusEnum.ENABLE,
|
status: CommonStatusEnum.ENABLE,
|
||||||
sort: undefined
|
sort: undefined
|
||||||
}
|
}
|
||||||
|
@ -192,6 +192,16 @@
|
|||||||
<el-dropdown-item command="handleDefinitionList" v-if="hasPermiPdQuery">
|
<el-dropdown-item command="handleDefinitionList" v-if="hasPermiPdQuery">
|
||||||
历史
|
历史
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
|
<el-dropdown-item
|
||||||
|
command="handleReport"
|
||||||
|
v-if="
|
||||||
|
checkPermi(['bpm:process-instance:manager-query']) &&
|
||||||
|
scope.row.processDefinition
|
||||||
|
"
|
||||||
|
:disabled="!isManagerUser(scope.row)"
|
||||||
|
>
|
||||||
|
报表
|
||||||
|
</el-dropdown-item>
|
||||||
<el-dropdown-item
|
<el-dropdown-item
|
||||||
command="handleChangeState"
|
command="handleChangeState"
|
||||||
v-if="hasPermiUpdate && scope.row.processDefinition"
|
v-if="hasPermiUpdate && scope.row.processDefinition"
|
||||||
@ -301,6 +311,7 @@ const { t } = useI18n() // 国际化
|
|||||||
const { push } = useRouter() // 路由
|
const { push } = useRouter() // 路由
|
||||||
const userStore = useUserStoreWithOut() // 用户信息缓存
|
const userStore = useUserStoreWithOut() // 用户信息缓存
|
||||||
const isDark = computed(() => useAppStore().getIsDark) // 是否黑暗模式
|
const isDark = computed(() => useAppStore().getIsDark) // 是否黑暗模式
|
||||||
|
const router = useRouter() // 路由
|
||||||
|
|
||||||
const isModelSorting = ref(false) // 是否正处于排序状态
|
const isModelSorting = ref(false) // 是否正处于排序状态
|
||||||
const originalData = ref<ModelInfo[]>([]) // 原始数据
|
const originalData = ref<ModelInfo[]>([]) // 原始数据
|
||||||
@ -349,6 +360,15 @@ const handleModelCommand = (command: string, row: any) => {
|
|||||||
case 'handleClean':
|
case 'handleClean':
|
||||||
handleClean(row)
|
handleClean(row)
|
||||||
break
|
break
|
||||||
|
case 'handleReport':
|
||||||
|
router.push({
|
||||||
|
name: 'BpmProcessInstanceReport',
|
||||||
|
query: {
|
||||||
|
processDefinitionId: row.processDefinition.id,
|
||||||
|
processDefinitionKey: row.key
|
||||||
|
}
|
||||||
|
})
|
||||||
|
break
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -216,16 +216,16 @@ const formFieldOptions4Title = computed(() => {
|
|||||||
})
|
})
|
||||||
// 固定添加发起人 ID 字段
|
// 固定添加发起人 ID 字段
|
||||||
cloneFormField.unshift({
|
cloneFormField.unshift({
|
||||||
label: ProcessVariableEnum.PROCESS_DEFINITION_NAME,
|
label: '流程名称',
|
||||||
value: '流程名称'
|
value: ProcessVariableEnum.PROCESS_DEFINITION_NAME
|
||||||
})
|
})
|
||||||
cloneFormField.unshift({
|
cloneFormField.unshift({
|
||||||
label: ProcessVariableEnum.START_TIME,
|
label: '发起时间',
|
||||||
value: '发起时间'
|
value: ProcessVariableEnum.START_TIME
|
||||||
})
|
})
|
||||||
cloneFormField.unshift({
|
cloneFormField.unshift({
|
||||||
label: ProcessVariableEnum.START_USER_ID,
|
label: '发起人',
|
||||||
value: '发起人'
|
value: ProcessVariableEnum.START_USER_ID
|
||||||
})
|
})
|
||||||
return cloneFormField
|
return cloneFormField
|
||||||
})
|
})
|
||||||
|
@ -114,6 +114,16 @@ const setSimpleModelNodeTaskStatus = (
|
|||||||
simpleModel.activityStatus = TaskStatusEnum.NOT_START
|
simpleModel.activityStatus = TaskStatusEnum.NOT_START
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 触发器节点
|
||||||
|
if (simpleModel.type === NodeType.TRIGGER_NODE) {
|
||||||
|
// 触发器节点,只有通过和未执行状态
|
||||||
|
if (finishedActivityIds.includes(simpleModel.id)) {
|
||||||
|
simpleModel.activityStatus = TaskStatusEnum.APPROVE
|
||||||
|
} else {
|
||||||
|
simpleModel.activityStatus = TaskStatusEnum.NOT_START
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 条件节点对应 SequenceFlow
|
// 条件节点对应 SequenceFlow
|
||||||
if (simpleModel.type === NodeType.CONDITION_NODE) {
|
if (simpleModel.type === NodeType.CONDITION_NODE) {
|
||||||
// 条件节点,只有通过和未执行状态
|
// 条件节点,只有通过和未执行状态
|
||||||
|
274
src/views/bpm/processInstance/report/index.vue
Normal file
274
src/views/bpm/processInstance/report/index.vue
Normal file
@ -0,0 +1,274 @@
|
|||||||
|
<template>
|
||||||
|
<doc-alert title="工作流手册" url="https://doc.iocoder.cn/bpm/" />
|
||||||
|
|
||||||
|
<ContentWrap>
|
||||||
|
<!-- 搜索工作栏 -->
|
||||||
|
<el-form
|
||||||
|
class="-mb-15px"
|
||||||
|
:model="queryParams"
|
||||||
|
ref="queryFormRef"
|
||||||
|
:inline="true"
|
||||||
|
label-width="68px"
|
||||||
|
>
|
||||||
|
<el-form-item label="发起人" prop="startUserId">
|
||||||
|
<el-select v-model="queryParams.startUserId" placeholder="请选择发起人" class="!w-240px">
|
||||||
|
<el-option
|
||||||
|
v-for="user in userList"
|
||||||
|
:key="user.id"
|
||||||
|
:label="user.nickname"
|
||||||
|
:value="user.id"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="流程名称" prop="name">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.name"
|
||||||
|
placeholder="请输入流程名称"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
class="!w-240px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="流程状态" prop="status">
|
||||||
|
<el-select
|
||||||
|
v-model="queryParams.status"
|
||||||
|
placeholder="请选择流程状态"
|
||||||
|
clearable
|
||||||
|
class="!w-240px"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="dict in getIntDictOptions(DICT_TYPE.BPM_PROCESS_INSTANCE_STATUS)"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.label"
|
||||||
|
:value="dict.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="发起时间" prop="createTime">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="queryParams.createTime"
|
||||||
|
value-format="YYYY-MM-DD HH:mm:ss"
|
||||||
|
type="daterange"
|
||||||
|
start-placeholder="开始日期"
|
||||||
|
end-placeholder="结束日期"
|
||||||
|
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
|
||||||
|
class="!w-240px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="结束时间" prop="endTime">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="queryParams.endTime"
|
||||||
|
value-format="YYYY-MM-DD HH:mm:ss"
|
||||||
|
type="daterange"
|
||||||
|
start-placeholder="开始日期"
|
||||||
|
end-placeholder="结束日期"
|
||||||
|
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
|
||||||
|
class="!w-240px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item
|
||||||
|
v-for="(item, index) in formFields"
|
||||||
|
:key="index"
|
||||||
|
:label="item.title"
|
||||||
|
:prop="item.field"
|
||||||
|
>
|
||||||
|
<!-- TODO @lesan:目前只支持input类型的字符串搜索 -->
|
||||||
|
<el-input
|
||||||
|
:disabled="item.type !== 'input'"
|
||||||
|
v-model="queryParams.formFieldsParams[item.field]"
|
||||||
|
:placeholder="`请输入${item.title}`"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
class="!w-240px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
|
||||||
|
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</ContentWrap>
|
||||||
|
|
||||||
|
<!-- 列表 -->
|
||||||
|
<ContentWrap>
|
||||||
|
<el-table v-loading="loading" border :data="list">
|
||||||
|
<el-table-column label="流程名称" align="center" prop="name" fixed="left" width="200" />
|
||||||
|
<el-table-column label="流程发起人" align="center" prop="startUser.nickname" width="120" />
|
||||||
|
<el-table-column label="流程状态" prop="status" width="120">
|
||||||
|
<template #default="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.BPM_PROCESS_INSTANCE_STATUS" :value="scope.row.status" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
label="发起时间"
|
||||||
|
align="center"
|
||||||
|
prop="startTime"
|
||||||
|
width="180"
|
||||||
|
:formatter="dateFormatter"
|
||||||
|
/>
|
||||||
|
<el-table-column
|
||||||
|
label="结束时间"
|
||||||
|
align="center"
|
||||||
|
prop="endTime"
|
||||||
|
width="180"
|
||||||
|
:formatter="dateFormatter"
|
||||||
|
/>
|
||||||
|
<el-table-column
|
||||||
|
v-for="(item, index) in formFields"
|
||||||
|
:key="index"
|
||||||
|
:label="item.title"
|
||||||
|
:prop="item.field"
|
||||||
|
width="120"
|
||||||
|
>
|
||||||
|
<!-- TODO @lesan:可以根据formField的type进行展示方式的控制,现在全部以字符串 -->
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.formVariables[item.field] ?? '' }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" align="center" fixed="right" width="180">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button
|
||||||
|
link
|
||||||
|
type="primary"
|
||||||
|
v-hasPermi="['bpm:process-instance:cancel']"
|
||||||
|
@click="handleDetail(scope.row)"
|
||||||
|
>
|
||||||
|
详情
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
link
|
||||||
|
type="primary"
|
||||||
|
v-if="scope.row.status === 1"
|
||||||
|
v-hasPermi="['bpm:process-instance:query']"
|
||||||
|
@click="handleCancel(scope.row)"
|
||||||
|
>
|
||||||
|
取消
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<!-- 分页 -->
|
||||||
|
<Pagination
|
||||||
|
:total="total"
|
||||||
|
v-model:page="queryParams.pageNo"
|
||||||
|
v-model:limit="queryParams.pageSize"
|
||||||
|
@pagination="getList"
|
||||||
|
/>
|
||||||
|
</ContentWrap>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||||
|
import { dateFormatter } from '@/utils/formatTime'
|
||||||
|
import * as ProcessInstanceApi from '@/api/bpm/processInstance'
|
||||||
|
import * as UserApi from '@/api/system/user'
|
||||||
|
import * as DefinitionApi from '@/api/bpm/definition'
|
||||||
|
import { parseFormFields } from '@/components/FormCreate/src/utils'
|
||||||
|
import { ElMessageBox } from 'element-plus'
|
||||||
|
|
||||||
|
defineOptions({ name: 'BpmProcessInstanceReport' })
|
||||||
|
|
||||||
|
const router = useRouter() // 路由
|
||||||
|
const { query } = useRoute()
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
const { t } = useI18n() // 国际化
|
||||||
|
|
||||||
|
const loading = ref(true) // 列表的加载中
|
||||||
|
const total = ref(0) // 列表的总页数
|
||||||
|
const list = ref([]) // 列表的数据
|
||||||
|
const formFields = ref()
|
||||||
|
const processDefinitionId = query.processDefinitionId as string
|
||||||
|
const queryParams = reactive({
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
startUserId: undefined,
|
||||||
|
name: '',
|
||||||
|
processDefinitionKey: query.processDefinitionKey,
|
||||||
|
status: undefined,
|
||||||
|
createTime: [],
|
||||||
|
endTime: [],
|
||||||
|
formFieldsParams: {}
|
||||||
|
})
|
||||||
|
const queryFormRef = ref() // 搜索的表单
|
||||||
|
const userList = ref<any[]>([]) // 用户列表
|
||||||
|
|
||||||
|
/** 查询列表 */
|
||||||
|
const getList = async () => {
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
const data = await ProcessInstanceApi.getProcessInstanceManagerPage({
|
||||||
|
...queryParams,
|
||||||
|
formFieldsParams: JSON.stringify(queryParams.formFieldsParams)
|
||||||
|
})
|
||||||
|
list.value = data.list
|
||||||
|
total.value = data.total
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 获取流程定义 */
|
||||||
|
const getProcessDefinition = async () => {
|
||||||
|
const processDefinition = await DefinitionApi.getProcessDefinition(processDefinitionId)
|
||||||
|
formFields.value = parseFormCreateFields(processDefinition.formFields)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 解析表单字段 */
|
||||||
|
const parseFormCreateFields = (formFields?: string[]) => {
|
||||||
|
const result: Array<Record<string, any>> = []
|
||||||
|
if (formFields) {
|
||||||
|
formFields.forEach((fieldStr: string) => {
|
||||||
|
parseFormFields(JSON.parse(fieldStr), result)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
const handleQuery = () => {
|
||||||
|
queryParams.pageNo = 1
|
||||||
|
getList()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
const resetQuery = () => {
|
||||||
|
queryFormRef.value.resetFields()
|
||||||
|
queryParams.formFieldsParams = {}
|
||||||
|
handleQuery()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 查看详情 */
|
||||||
|
const handleDetail = (row) => {
|
||||||
|
router.push({
|
||||||
|
name: 'BpmProcessInstanceDetail',
|
||||||
|
query: {
|
||||||
|
id: row.id
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 取消按钮操作 */
|
||||||
|
const handleCancel = async (row) => {
|
||||||
|
// 二次确认
|
||||||
|
const { value } = await ElMessageBox.prompt('请输入取消原因', '取消流程', {
|
||||||
|
confirmButtonText: t('common.ok'),
|
||||||
|
cancelButtonText: t('common.cancel'),
|
||||||
|
inputPattern: /^[\s\S]*.*\S[\s\S]*$/, // 判断非空,且非空格
|
||||||
|
inputErrorMessage: '取消原因不能为空'
|
||||||
|
})
|
||||||
|
// 发起取消
|
||||||
|
await ProcessInstanceApi.cancelProcessInstanceByAdmin(row.id, value)
|
||||||
|
message.success('取消成功')
|
||||||
|
// 刷新列表
|
||||||
|
await getList()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 初始化 **/
|
||||||
|
onMounted(async () => {
|
||||||
|
// 获取流程定义,用于 table column 的展示
|
||||||
|
await getProcessDefinition()
|
||||||
|
// 获取流程列表
|
||||||
|
await getList()
|
||||||
|
// 获取用户列表
|
||||||
|
userList.value = await UserApi.getSimpleUserList()
|
||||||
|
})
|
||||||
|
</script>
|
@ -46,6 +46,15 @@
|
|||||||
<el-table v-loading="loading" :data="list">
|
<el-table v-loading="loading" :data="list">
|
||||||
<!-- TODO 芋艿:增加摘要 -->
|
<!-- TODO 芋艿:增加摘要 -->
|
||||||
<el-table-column align="center" label="流程名" prop="processInstanceName" min-width="180" />
|
<el-table-column align="center" label="流程名" prop="processInstanceName" min-width="180" />
|
||||||
|
<el-table-column label="摘要" prop="summary" min-width="180">
|
||||||
|
<template #default="scope">
|
||||||
|
<div class="flex flex-col" v-if="scope.row.summary && scope.row.summary.length > 0">
|
||||||
|
<div v-for="(item, index) in scope.row.summary" :key="index">
|
||||||
|
<el-text type="info"> {{ item.key }} : {{ item.value }} </el-text>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
align="center"
|
align="center"
|
||||||
label="流程发起人"
|
label="流程发起人"
|
||||||
|
@ -122,10 +122,10 @@
|
|||||||
<ContentWrap>
|
<ContentWrap>
|
||||||
<el-table v-loading="loading" :data="list">
|
<el-table v-loading="loading" :data="list">
|
||||||
<el-table-column align="center" label="流程" prop="processInstance.name" width="180" />
|
<el-table-column align="center" label="流程" prop="processInstance.name" width="180" />
|
||||||
<el-table-column label="摘要" prop="summary" min-width="180">
|
<el-table-column label="摘要" prop="processInstance.summary" min-width="180">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<div class="flex flex-col" v-if="scope.row.summary && scope.row.summary.length > 0">
|
<div class="flex flex-col" v-if="scope.row.processInstance.summary && scope.row.processInstance.summary.length > 0">
|
||||||
<div v-for="(item, index) in scope.row.summary" :key="index">
|
<div v-for="(item, index) in scope.row.processInstance.summary" :key="index">
|
||||||
<el-text type="info"> {{ item.key }} : {{ item.value }} </el-text>
|
<el-text type="info"> {{ item.key }} : {{ item.value }} </el-text>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -105,10 +105,10 @@
|
|||||||
<ContentWrap>
|
<ContentWrap>
|
||||||
<el-table v-loading="loading" :data="list">
|
<el-table v-loading="loading" :data="list">
|
||||||
<el-table-column align="center" label="流程" prop="processInstance.name" width="180" />
|
<el-table-column align="center" label="流程" prop="processInstance.name" width="180" />
|
||||||
<el-table-column label="摘要" prop="summary" min-width="180">
|
<el-table-column label="摘要" prop="processInstance.summary" min-width="180">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<div class="flex flex-col" v-if="scope.row.summary && scope.row.summary.length > 0">
|
<div class="flex flex-col" v-if="scope.row.processInstance.summary && scope.row.processInstance.summary.length > 0">
|
||||||
<div v-for="(item, index) in scope.row.summary" :key="index">
|
<div v-for="(item, index) in scope.row.processInstance.summary" :key="index">
|
||||||
<el-text type="info"> {{ item.key }} : {{ item.value }} </el-text>
|
<el-text type="info"> {{ item.key }} : {{ item.value }} </el-text>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user