Compare commits
41 Commits
3e826776f4
...
ecfe1b6145
Author | SHA1 | Date | |
---|---|---|---|
![]() |
ecfe1b6145 | ||
![]() |
1df1850ef9 | ||
![]() |
169e3600d9 | ||
![]() |
b5aa9d24ac | ||
![]() |
e891a4bfd2 | ||
![]() |
f87b37eaac | ||
![]() |
9f0f5b0e6c | ||
![]() |
0ab7f2342c | ||
![]() |
a389392c8e | ||
![]() |
5d31881f48 | ||
![]() |
4c5c6ff5c3 | ||
![]() |
d76df547ae | ||
![]() |
bfb9e2e77f | ||
![]() |
8c52c6867f | ||
![]() |
46985c6e1b | ||
![]() |
7697054918 | ||
![]() |
acb00ba866 | ||
![]() |
cff65aa901 | ||
![]() |
a6de16a02d | ||
![]() |
0b6af855ac | ||
![]() |
ee46a31a81 | ||
![]() |
4835316fca | ||
![]() |
9bdafb0f6f | ||
![]() |
8e4d91f43e | ||
![]() |
1a95687f61 | ||
![]() |
f2f9391328 | ||
![]() |
2de62667dc | ||
![]() |
c79f027d62 | ||
![]() |
c665fad8bc | ||
![]() |
019bd9533e | ||
![]() |
8ff9443f28 | ||
![]() |
e591aa8867 | ||
![]() |
9da5beb879 | ||
![]() |
e3a39b7732 | ||
![]() |
d0ae37da4e | ||
![]() |
e0bc260fc1 | ||
![]() |
f93919b750 | ||
![]() |
6dc5f5dcb5 | ||
![]() |
455c192a9a | ||
![]() |
154dd6c40b | ||
![]() |
41b8407841 |
3
.env.dev
3
.env.dev
@ -32,3 +32,6 @@ VITE_MALL_H5_DOMAIN='http://mall.yudao.iocoder.cn'
|
||||
|
||||
# 验证码的开关
|
||||
VITE_APP_CAPTCHA_ENABLE=true
|
||||
|
||||
# GoView域名
|
||||
VITE_GOVIEW_URL='http://127.0.0.1:3000'
|
@ -29,3 +29,6 @@ VITE_MALL_H5_DOMAIN='http://localhost:3000'
|
||||
|
||||
# 验证码的开关
|
||||
VITE_APP_CAPTCHA_ENABLE=false
|
||||
|
||||
# GoView域名
|
||||
VITE_GOVIEW_URL='http://127.0.0.1:3000'
|
@ -29,3 +29,6 @@ VITE_OUT_DIR=dist-prod
|
||||
|
||||
# 商城H5会员端域名
|
||||
VITE_MALL_H5_DOMAIN='http://mall.yudao.iocoder.cn'
|
||||
|
||||
# GoView域名
|
||||
VITE_GOVIEW_URL='http://127.0.0.1:3000'
|
@ -29,3 +29,6 @@ VITE_OUT_DIR=dist-stage
|
||||
|
||||
# 商城H5会员端域名
|
||||
VITE_MALL_H5_DOMAIN='http://mall.yudao.iocoder.cn'
|
||||
|
||||
# GoView域名
|
||||
VITE_GOVIEW_URL='http://127.0.0.1:3000'
|
@ -29,3 +29,6 @@ VITE_OUT_DIR=dist-test
|
||||
|
||||
# 商城H5会员端域名
|
||||
VITE_MALL_H5_DOMAIN='http://mall.yudao.iocoder.cn'
|
||||
|
||||
# GoView域名
|
||||
VITE_GOVIEW_URL='http://127.0.0.1:3000'
|
@ -71,7 +71,7 @@
|
||||
"vue": "3.5.12",
|
||||
"vue-dompurify-html": "^4.1.4",
|
||||
"vue-i18n": "9.10.2",
|
||||
"vue-router": "^4.3.0",
|
||||
"vue-router": "4.4.5",
|
||||
"vue-types": "^5.1.1",
|
||||
"vuedraggable": "^4.1.0",
|
||||
"web-storage-cache": "^1.1.1",
|
||||
|
1326
pnpm-lock.yaml
1326
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
@ -15,7 +15,6 @@ import {
|
||||
AssignStartUserHandlerType,
|
||||
AssignEmptyHandlerType,
|
||||
FieldPermissionType,
|
||||
ProcessVariableEnum
|
||||
} from './consts'
|
||||
import { parseFormFields } from '@/components/FormCreate/src/utils/index'
|
||||
export function useWatchNode(props: { flowNode: SimpleFlowNode }): Ref<SimpleFlowNode> {
|
||||
@ -37,13 +36,6 @@ const parseFormCreateFields = (formFields?: string[]) => {
|
||||
parseFormFields(JSON.parse(fieldStr), result)
|
||||
})
|
||||
}
|
||||
// 固定添加发起人 ID 字段
|
||||
result.unshift({
|
||||
field: ProcessVariableEnum.START_USER_ID,
|
||||
title: '发起人',
|
||||
type: 'UserSelect',
|
||||
required: true
|
||||
})
|
||||
return result
|
||||
}
|
||||
|
||||
|
@ -26,19 +26,13 @@
|
||||
</div>
|
||||
</template>
|
||||
<div>
|
||||
<div class="mb-3 font-size-16px" v-if="currentNode.defaultFlow">未满足其它条件时,将进入此分支(该分支不可编辑和删除)</div>
|
||||
<div class="mb-3 font-size-16px" v-if="currentNode.defaultFlow"
|
||||
>未满足其它条件时,将进入此分支(该分支不可编辑和删除)</div
|
||||
>
|
||||
<div v-else>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="currentNode"
|
||||
:rules="formRules"
|
||||
label-position="top"
|
||||
>
|
||||
<el-form ref="formRef" :model="currentNode" :rules="formRules" label-position="top">
|
||||
<el-form-item label="配置方式" prop="conditionType">
|
||||
<el-radio-group
|
||||
v-model="currentNode.conditionType"
|
||||
@change="changeConditionType"
|
||||
>
|
||||
<el-radio-group v-model="currentNode.conditionType" @change="changeConditionType">
|
||||
<el-radio
|
||||
v-for="(dict, index) in conditionConfigTypes"
|
||||
:key="index"
|
||||
@ -108,10 +102,11 @@
|
||||
<div class="mr-2">
|
||||
<el-select style="width: 160px" v-model="rule.leftSide">
|
||||
<el-option
|
||||
v-for="(item, index) in fieldsInfo"
|
||||
v-for="(item, index) in fieldOptions"
|
||||
:key="index"
|
||||
:label="item.title"
|
||||
:value="item.field"
|
||||
:disabled="!item.required"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
@ -165,10 +160,12 @@ import {
|
||||
COMPARISON_OPERATORS,
|
||||
ConditionGroup,
|
||||
Condition,
|
||||
ConditionRule
|
||||
ConditionRule,
|
||||
ProcessVariableEnum
|
||||
} from '../consts'
|
||||
import { getDefaultConditionNodeName } from '../utils'
|
||||
import { useFormFields } from '../node'
|
||||
import { BpmModelFormType } from '@/utils/constants'
|
||||
const message = useMessage() // 消息弹窗
|
||||
defineOptions({
|
||||
name: 'ConditionNodeConfig'
|
||||
@ -177,8 +174,8 @@ const formType = inject<Ref<number>>('formType') // 表单类型
|
||||
const conditionConfigTypes = computed(() => {
|
||||
return CONDITION_CONFIG_TYPES.filter((item) => {
|
||||
// 业务表单暂时去掉条件规则选项
|
||||
if (formType?.value !== 10) {
|
||||
return item.value === ConditionType.RULE
|
||||
if (formType?.value === BpmModelFormType.CUSTOM && item.value === ConditionType.RULE) {
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
@ -368,16 +365,29 @@ const addConditionRule = (condition: Condition, idx: number) => {
|
||||
const deleteConditionRule = (condition: Condition, idx: number) => {
|
||||
condition.rules.splice(idx, 1)
|
||||
}
|
||||
|
||||
const fieldsInfo = useFormFields()
|
||||
|
||||
/** 条件规则可选择的表单字段 */
|
||||
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 item = fieldsInfo.find((item) => item.field === field)
|
||||
return item?.title
|
||||
}
|
||||
|
||||
/** 获取操作符名称 */
|
||||
const getOpName = (opCode: string): string => {
|
||||
const opName = COMPARISON_OPERATORS.find((item) => item.value === opCode)
|
||||
const opName = COMPARISON_OPERATORS.find((item: any) => item.value === opCode)
|
||||
return opName?.label
|
||||
}
|
||||
</script>
|
||||
|
@ -469,7 +469,8 @@ import {
|
||||
TimeoutHandlerType,
|
||||
ASSIGN_EMPTY_HANDLER_TYPES,
|
||||
AssignEmptyHandlerType,
|
||||
FieldPermissionType
|
||||
FieldPermissionType,
|
||||
ProcessVariableEnum
|
||||
} from '../consts'
|
||||
|
||||
import {
|
||||
@ -519,6 +520,13 @@ const { formType, fieldsPermissionConfig, formFieldOptions, getNodeConfigFormFie
|
||||
useFormFieldsPermission(FieldPermissionType.READ)
|
||||
// 表单内用户字段选项, 必须是必填和用户选择器
|
||||
const userFieldOnFormOptions = computed(() => {
|
||||
// 固定添加发起人 ID 字段
|
||||
formFieldOptions.unshift({
|
||||
field: ProcessVariableEnum.START_USER_ID,
|
||||
title: '发起人',
|
||||
type: 'UserSelect',
|
||||
required: true
|
||||
})
|
||||
return formFieldOptions.filter((item) => item.type === 'UserSelect')
|
||||
})
|
||||
// 表单内部门字段选项, 必须是必填和部门选择器
|
||||
|
@ -406,6 +406,31 @@
|
||||
"name": "variableMappingDelegateExpression",
|
||||
"isAttr": true,
|
||||
"type": "String"
|
||||
},
|
||||
{
|
||||
"name": "calledElementType",
|
||||
"isAttr": true,
|
||||
"type": "String"
|
||||
},
|
||||
{
|
||||
"name": "processInstanceName",
|
||||
"isAttr": true,
|
||||
"type": "String"
|
||||
},
|
||||
{
|
||||
"name": "inheritBusinessKey",
|
||||
"isAttr": true,
|
||||
"type": "Boolean"
|
||||
},
|
||||
{
|
||||
"name": "businessKey",
|
||||
"isAttr": true,
|
||||
"type": "String"
|
||||
},
|
||||
{
|
||||
"name": "inheritVariables",
|
||||
"isAttr": true,
|
||||
"type": "Boolean"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -165,6 +165,12 @@ F.prototype.getPaletteEntries = function () {
|
||||
'bpmn-icon-user-task',
|
||||
translate('Create User Task')
|
||||
),
|
||||
'create.call-activity': createAction(
|
||||
'bpmn:CallActivity',
|
||||
'activity',
|
||||
'bpmn-icon-call-activity',
|
||||
translate('Create Call Activity')
|
||||
),
|
||||
'create.service-task': createAction(
|
||||
'bpmn:ServiceTask',
|
||||
'activity',
|
||||
|
@ -56,6 +56,7 @@ export default {
|
||||
'Create EndEvent': '创建结束事件',
|
||||
'Create Task': '创建任务',
|
||||
'Create User Task': '创建用户任务',
|
||||
'Create Call Activity': '创建调用活动',
|
||||
'Create Service Task': '创建服务任务',
|
||||
'Create Gateway': '创建网关',
|
||||
'Create DataObjectReference': '创建数据对象',
|
||||
|
@ -27,7 +27,9 @@
|
||||
<element-form :id="elementId" :type="elementType" />
|
||||
</el-collapse-item>
|
||||
<el-collapse-item name="task" v-if="isTaskCollapseItemShow(elementType)" key="task">
|
||||
<template #title><Icon icon="ep:checked" />{{ getTaskCollapseItemName(elementType) }}</template>
|
||||
<template #title
|
||||
><Icon icon="ep:checked" />{{ getTaskCollapseItemName(elementType) }}</template
|
||||
>
|
||||
<element-task :id="elementId" :type="elementType" />
|
||||
</el-collapse-item>
|
||||
<el-collapse-item
|
||||
@ -35,8 +37,12 @@
|
||||
v-if="elementType.indexOf('Task') !== -1"
|
||||
key="multiInstance"
|
||||
>
|
||||
<template #title><Icon icon="ep:help-filled" />多实例(会签配置)</template>
|
||||
<element-multi-instance :id="elementId" :business-object="elementBusinessObject" :type="elementType" />
|
||||
<template #title><Icon icon="ep:help-filled" />多人审批方式</template>
|
||||
<element-multi-instance
|
||||
:id="elementId"
|
||||
:business-object="elementBusinessObject"
|
||||
:type="elementType"
|
||||
/>
|
||||
</el-collapse-item>
|
||||
<el-collapse-item name="listeners" key="listeners">
|
||||
<template #title><Icon icon="ep:bell-filled" />执行监听器</template>
|
||||
@ -56,7 +62,11 @@
|
||||
</el-collapse-item>
|
||||
<el-collapse-item name="customConfig" key="customConfig">
|
||||
<template #title><Icon icon="ep:tools" />自定义配置</template>
|
||||
<element-custom-config :id="elementId" :type="elementType" :business-object="elementBusinessObject" />
|
||||
<element-custom-config
|
||||
:id="elementId"
|
||||
:type="elementType"
|
||||
:business-object="elementBusinessObject"
|
||||
/>
|
||||
</el-collapse-item>
|
||||
</el-collapse>
|
||||
</div>
|
||||
@ -72,7 +82,7 @@ import ElementListeners from './listeners/ElementListeners.vue'
|
||||
import ElementProperties from './properties/ElementProperties.vue'
|
||||
// import ElementForm from './form/ElementForm.vue'
|
||||
import UserTaskListeners from './listeners/UserTaskListeners.vue'
|
||||
import { getTaskCollapseItemName,isTaskCollapseItemShow } from './task/data'
|
||||
import { getTaskCollapseItemName, isTaskCollapseItemShow } from './task/data'
|
||||
|
||||
defineOptions({ name: 'MyPropertiesPanel' })
|
||||
|
||||
|
@ -2,6 +2,7 @@ import UserTask from './task-components/UserTask.vue'
|
||||
import ServiceTask from './task-components/ServiceTask.vue'
|
||||
import ScriptTask from './task-components/ScriptTask.vue'
|
||||
import ReceiveTask from './task-components/ReceiveTask.vue'
|
||||
import CallActivity from './task-components/CallActivity.vue'
|
||||
|
||||
export const installedComponent = {
|
||||
UserTask: {
|
||||
@ -19,6 +20,10 @@ export const installedComponent = {
|
||||
ReceiveTask: {
|
||||
name: '接收任务',
|
||||
component: ReceiveTask
|
||||
},
|
||||
CallActivity: {
|
||||
name: '调用活动',
|
||||
component: CallActivity
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,280 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-form label-width="100px">
|
||||
<el-form-item label="实例名称" prop="processInstanceName">
|
||||
<el-input
|
||||
v-model="formData.processInstanceName"
|
||||
clearable
|
||||
placeholder="请输入实例名称"
|
||||
@change="updateCallActivityAttr('processInstanceName')"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<!-- TODO 需要可选择已存在的流程 -->
|
||||
<el-form-item label="被调用流程" prop="calledElement">
|
||||
<el-input
|
||||
v-model="formData.calledElement"
|
||||
clearable
|
||||
placeholder="请输入被调用流程"
|
||||
@change="updateCallActivityAttr('calledElement')"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="继承变量" prop="inheritVariables">
|
||||
<el-switch
|
||||
v-model="formData.inheritVariables"
|
||||
@change="updateCallActivityAttr('inheritVariables')"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="继承业务键" prop="inheritBusinessKey">
|
||||
<el-switch
|
||||
v-model="formData.inheritBusinessKey"
|
||||
@change="updateCallActivityAttr('inheritBusinessKey')"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item v-if="!formData.inheritBusinessKey" label="业务键表达式" prop="businessKey">
|
||||
<el-input
|
||||
v-model="formData.businessKey"
|
||||
clearable
|
||||
placeholder="请输入业务键表达式"
|
||||
@change="updateCallActivityAttr('businessKey')"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-divider />
|
||||
<div>
|
||||
<div class="flex mb-10px">
|
||||
<el-text>输入参数</el-text>
|
||||
<XButton
|
||||
class="ml-auto"
|
||||
type="primary"
|
||||
preIcon="ep:plus"
|
||||
title="添加参数"
|
||||
size="small"
|
||||
@click="openVariableForm('in', null, -1)"
|
||||
/>
|
||||
</div>
|
||||
<el-table :data="inVariableList" max-height="240" fit border>
|
||||
<el-table-column label="源" prop="source" min-width="100px" show-overflow-tooltip />
|
||||
<el-table-column label="目标" prop="target" min-width="100px" show-overflow-tooltip />
|
||||
<el-table-column label="操作" width="110px">
|
||||
<template #default="scope">
|
||||
<el-button link @click="openVariableForm('in', scope.row, scope.$index)" size="small">
|
||||
编辑
|
||||
</el-button>
|
||||
<el-divider direction="vertical" />
|
||||
<el-button
|
||||
link
|
||||
size="small"
|
||||
style="color: #ff4d4f"
|
||||
@click="removeVariable('in', scope.$index)"
|
||||
>
|
||||
移除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
|
||||
<el-divider />
|
||||
<div>
|
||||
<div class="flex mb-10px">
|
||||
<el-text>输出参数</el-text>
|
||||
<XButton
|
||||
class="ml-auto"
|
||||
type="primary"
|
||||
preIcon="ep:plus"
|
||||
title="添加参数"
|
||||
size="small"
|
||||
@click="openVariableForm('out', null, -1)"
|
||||
/>
|
||||
</div>
|
||||
<el-table :data="outVariableList" max-height="240" fit border>
|
||||
<el-table-column label="源" prop="source" min-width="100px" show-overflow-tooltip />
|
||||
<el-table-column label="目标" prop="target" min-width="100px" show-overflow-tooltip />
|
||||
<el-table-column label="操作" width="110px">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
link
|
||||
@click="openVariableForm('out', scope.row, scope.$index)"
|
||||
size="small"
|
||||
>
|
||||
编辑
|
||||
</el-button>
|
||||
<el-divider direction="vertical" />
|
||||
<el-button
|
||||
link
|
||||
size="small"
|
||||
style="color: #ff4d4f"
|
||||
@click="removeVariable('out', scope.$index)"
|
||||
>
|
||||
移除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</el-form>
|
||||
|
||||
<!-- 添加或修改参数 -->
|
||||
<el-dialog
|
||||
v-model="variableDialogVisible"
|
||||
title="参数配置"
|
||||
width="600px"
|
||||
append-to-body
|
||||
destroy-on-close
|
||||
>
|
||||
<el-form :model="varialbeFormData" label-width="80px" ref="varialbeFormRef">
|
||||
<el-form-item label="源:" prop="source">
|
||||
<el-input v-model="varialbeFormData.source" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="目标:" prop="target">
|
||||
<el-input v-model="varialbeFormData.target" clearable />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="variableDialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="saveVariable">确 定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
defineOptions({ name: 'CallActivity' })
|
||||
const props = defineProps({
|
||||
id: String,
|
||||
type: String
|
||||
})
|
||||
const prefix = inject('prefix')
|
||||
const message = useMessage()
|
||||
|
||||
const formData = ref({
|
||||
processInstanceName: '',
|
||||
calledElement: '',
|
||||
inheritVariables: false,
|
||||
businessKey: '',
|
||||
inheritBusinessKey: false,
|
||||
calledElementType: 'key'
|
||||
})
|
||||
const inVariableList = ref()
|
||||
const outVariableList = ref()
|
||||
const variableType = ref() // 参数类型
|
||||
const editingVariableIndex = ref(-1) // 编辑参数下标
|
||||
const variableDialogVisible = ref(false)
|
||||
const varialbeFormRef = ref()
|
||||
const varialbeFormData = ref({
|
||||
source: '',
|
||||
target: ''
|
||||
})
|
||||
|
||||
const bpmnInstances = () => (window as any)?.bpmnInstances
|
||||
const bpmnElement = ref()
|
||||
const otherExtensionList = ref()
|
||||
|
||||
const initCallActivity = () => {
|
||||
bpmnElement.value = bpmnInstances().bpmnElement
|
||||
console.log(bpmnElement.value.businessObject, 'callActivity')
|
||||
|
||||
// 初始化所有配置项
|
||||
Object.keys(formData.value).forEach((key) => {
|
||||
formData.value[key] = bpmnElement.value.businessObject[key] ?? formData.value[key]
|
||||
})
|
||||
|
||||
otherExtensionList.value = [] // 其他扩展配置
|
||||
inVariableList.value = []
|
||||
outVariableList.value = []
|
||||
// 初始化输入参数
|
||||
bpmnElement.value.businessObject?.extensionElements?.values?.forEach((ex) => {
|
||||
if (ex.$type === `${prefix}:In`) {
|
||||
inVariableList.value.push(ex)
|
||||
} else if (ex.$type === `${prefix}:Out`) {
|
||||
outVariableList.value.push(ex)
|
||||
} else {
|
||||
otherExtensionList.value.push(ex)
|
||||
}
|
||||
})
|
||||
|
||||
// 默认添加
|
||||
// bpmnInstances().modeling.updateProperties(toRaw(bpmnElement.value), {
|
||||
// calledElementType: 'key'
|
||||
// })
|
||||
}
|
||||
|
||||
const updateCallActivityAttr = (attr) => {
|
||||
bpmnInstances().modeling.updateProperties(toRaw(bpmnElement.value), {
|
||||
[attr]: formData.value[attr]
|
||||
})
|
||||
}
|
||||
|
||||
const openVariableForm = (type, data, index) => {
|
||||
editingVariableIndex.value = index
|
||||
variableType.value = type
|
||||
varialbeFormData.value = index === -1 ? {} : { ...data }
|
||||
variableDialogVisible.value = true
|
||||
}
|
||||
|
||||
const removeVariable = async (type, index) => {
|
||||
try {
|
||||
await message.delConfirm()
|
||||
if (type === 'in') {
|
||||
inVariableList.value.splice(index, 1)
|
||||
}
|
||||
if (type === 'out') {
|
||||
outVariableList.value.splice(index, 1)
|
||||
}
|
||||
updateElementExtensions()
|
||||
} catch {}
|
||||
}
|
||||
|
||||
const saveVariable = () => {
|
||||
if (editingVariableIndex.value === -1) {
|
||||
if (variableType.value === 'in') {
|
||||
inVariableList.value.push(
|
||||
bpmnInstances().moddle.create(`${prefix}:In`, { ...varialbeFormData.value })
|
||||
)
|
||||
}
|
||||
if (variableType.value === 'out') {
|
||||
outVariableList.value.push(
|
||||
bpmnInstances().moddle.create(`${prefix}:Out`, { ...varialbeFormData.value })
|
||||
)
|
||||
}
|
||||
updateElementExtensions()
|
||||
} else {
|
||||
if (variableType.value === 'in') {
|
||||
inVariableList.value[editingVariableIndex.value].source = varialbeFormData.value.source
|
||||
inVariableList.value[editingVariableIndex.value].target = varialbeFormData.value.target
|
||||
}
|
||||
if (variableType.value === 'out') {
|
||||
outVariableList.value[editingVariableIndex.value].source = varialbeFormData.value.source
|
||||
outVariableList.value[editingVariableIndex.value].target = varialbeFormData.value.target
|
||||
}
|
||||
}
|
||||
variableDialogVisible.value = false
|
||||
}
|
||||
|
||||
const updateElementExtensions = () => {
|
||||
const extensions = bpmnInstances().moddle.create('bpmn:ExtensionElements', {
|
||||
values: [...inVariableList.value, ...outVariableList.value, ...otherExtensionList.value]
|
||||
})
|
||||
bpmnInstances().modeling.updateProperties(toRaw(bpmnElement.value), {
|
||||
extensionElements: extensions
|
||||
})
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.id,
|
||||
(val) => {
|
||||
val &&
|
||||
val.length &&
|
||||
nextTick(() => {
|
||||
initCallActivity()
|
||||
})
|
||||
},
|
||||
{ immediate: true }
|
||||
)
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
@ -178,12 +178,17 @@
|
||||
type="textarea"
|
||||
v-model="userTaskForm.candidateParam[0]"
|
||||
clearable
|
||||
style="width: 72%"
|
||||
style="width: 100%"
|
||||
@change="updateElementTask"
|
||||
/>
|
||||
<el-button class="ml-5px" size="small" type="success" @click="openProcessExpressionDialog"
|
||||
>选择表达式</el-button
|
||||
>
|
||||
<XButton
|
||||
class="!w-1/1 mt-5px"
|
||||
type="success"
|
||||
preIcon="ep:select"
|
||||
title="选择表达式"
|
||||
size="small"
|
||||
@click="openProcessExpressionDialog"
|
||||
/>
|
||||
<!-- 选择弹窗 -->
|
||||
<ProcessExpressionDialog ref="processExpressionDialogRef" @select="selectProcessExpression" />
|
||||
</el-form-item>
|
||||
|
@ -44,8 +44,7 @@ service.interceptors.request.use(
|
||||
// 是否需要设置 token
|
||||
let isToken = (config!.headers || {}).isToken === false
|
||||
whiteList.some((v) => {
|
||||
if (config.url) {
|
||||
config.url.indexOf(v) > -1
|
||||
if (config.url && config.url.indexOf(v) > -1) {
|
||||
return (isToken = false)
|
||||
}
|
||||
})
|
||||
|
@ -51,7 +51,10 @@ import {
|
||||
ElMenu,
|
||||
ElMenuItem,
|
||||
ElFooter,
|
||||
ElMessage
|
||||
ElMessage,
|
||||
ElCollapse,
|
||||
ElCollapseItem,
|
||||
ElCard,
|
||||
// ElFormItem,
|
||||
// ElOption
|
||||
} from 'element-plus'
|
||||
@ -113,7 +116,10 @@ const components = [
|
||||
UserSelect,
|
||||
DeptSelect,
|
||||
ApiSelect,
|
||||
Editor
|
||||
Editor,
|
||||
ElCollapse,
|
||||
ElCollapseItem,
|
||||
ElCard,
|
||||
]
|
||||
|
||||
// 参考 http://www.form-create.com/v3/element-ui/auto-import.html 文档
|
||||
|
@ -120,7 +120,7 @@ export const generateRoute = (routes: AppCustomRouteRecordRaw[]): AppRouteRecord
|
||||
data.children = [childrenData]
|
||||
} else {
|
||||
// 目录
|
||||
if (route.children) {
|
||||
if (route.children?.length) {
|
||||
data.component = Layout
|
||||
data.redirect = getRedirect(route.path, route.children)
|
||||
// 外链
|
||||
|
@ -376,6 +376,9 @@ export const treeToString = (tree: any[], nodeId) => {
|
||||
let str = ''
|
||||
|
||||
function performAThoroughValidation(arr) {
|
||||
if (typeof arr === 'undefined' || !Array.isArray(arr) || arr.length === 0) {
|
||||
return false
|
||||
}
|
||||
for (const item of arr) {
|
||||
if (item.id === nodeId) {
|
||||
str += ` / ${item.name}`
|
||||
|
@ -8,8 +8,8 @@
|
||||
<!-- 中间主要内容 tab 栏 -->
|
||||
<el-tabs v-model="activeTab">
|
||||
<!-- 表单信息 -->
|
||||
<el-tab-pane label="表单填写" name="form">
|
||||
<div class="form-scroll-area">
|
||||
<el-tab-pane label="表单填写" name="form" >
|
||||
<div class="form-scroll-area" v-loading="processInstanceStartLoading">
|
||||
<el-scrollbar>
|
||||
<el-row>
|
||||
<el-col :span="17">
|
||||
@ -90,7 +90,7 @@ const props = defineProps<{
|
||||
selectProcessDefinition: any
|
||||
}>()
|
||||
const emit = defineEmits(['cancel'])
|
||||
|
||||
const processInstanceStartLoading = ref(false) // 流程实例发起中
|
||||
const { push, currentRoute } = useRouter() // 路由
|
||||
const message = useMessage() // 消息弹窗
|
||||
const { delView } = useTagsViewStore() // 视图操作
|
||||
@ -179,6 +179,8 @@ const submitForm = async () => {
|
||||
if (!fApi.value || !props.selectProcessDefinition) {
|
||||
return
|
||||
}
|
||||
// 流程表单校验
|
||||
await fApi.value.validate()
|
||||
// 如果有指定审批人,需要校验
|
||||
if (startUserSelectTasks.value?.length > 0) {
|
||||
for (const userTask of startUserSelectTasks.value) {
|
||||
@ -191,7 +193,7 @@ const submitForm = async () => {
|
||||
}
|
||||
|
||||
// 提交请求
|
||||
fApi.value.btn.loading(true)
|
||||
processInstanceStartLoading.value = true
|
||||
try {
|
||||
await ProcessInstanceApi.createProcessInstance({
|
||||
processDefinitionId: props.selectProcessDefinition.id,
|
||||
@ -206,7 +208,7 @@ const submitForm = async () => {
|
||||
name: 'BpmProcessInstanceMy'
|
||||
})
|
||||
} finally {
|
||||
fApi.value.btn.loading(false)
|
||||
processInstanceStartLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,9 +20,9 @@
|
||||
<el-form
|
||||
label-position="top"
|
||||
class="mb-auto"
|
||||
ref="formRef"
|
||||
:model="genericForm"
|
||||
:rules="genericRule"
|
||||
ref="approveFormRef"
|
||||
:model="approveReasonForm"
|
||||
:rules="approveReasonRule"
|
||||
label-width="100px"
|
||||
>
|
||||
<el-card v-if="runningTask?.formId > 0" class="mb-15px !-mt-10px">
|
||||
@ -38,17 +38,17 @@
|
||||
</el-card>
|
||||
<el-form-item label="审批意见" prop="reason">
|
||||
<el-input
|
||||
v-model="genericForm.reason"
|
||||
v-model="approveReasonForm.reason"
|
||||
placeholder="请输入审批意见"
|
||||
type="textarea"
|
||||
:rows="4"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button :disabled="formLoading" type="success" @click="handleAudit(true)">
|
||||
<el-button :disabled="formLoading" type="success" @click="handleAudit(true, approveFormRef)">
|
||||
{{ getButtonDisplayName(OperationButtonType.APPROVE) }}
|
||||
</el-button>
|
||||
<el-button @click="popOverVisible.approve = false"> 取消 </el-button>
|
||||
<el-button @click="closePropover('approve', approveFormRef)"> 取消 </el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
@ -72,24 +72,24 @@
|
||||
<el-form
|
||||
label-position="top"
|
||||
class="mb-auto"
|
||||
ref="formRef"
|
||||
:model="genericForm"
|
||||
:rules="genericRule"
|
||||
ref="rejectFormRef"
|
||||
:model="rejectReasonForm"
|
||||
:rules="rejectReasonRule"
|
||||
label-width="100px"
|
||||
>
|
||||
<el-form-item label="审批意见" prop="reason">
|
||||
<el-input
|
||||
v-model="genericForm.reason"
|
||||
v-model="rejectReasonForm.reason"
|
||||
placeholder="请输入审批意见"
|
||||
type="textarea"
|
||||
:rows="4"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button :disabled="formLoading" type="danger" @click="handleAudit(false)">
|
||||
<el-button :disabled="formLoading" type="danger" @click="handleAudit(false,rejectFormRef)">
|
||||
{{ getButtonDisplayName(OperationButtonType.REJECT) }}
|
||||
</el-button>
|
||||
<el-button @click="popOverVisible.reject = false"> 取消 </el-button>
|
||||
<el-button @click="closePropover('reject', rejectFormRef)"> 取消 </el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
@ -113,14 +113,14 @@
|
||||
<el-form
|
||||
label-position="top"
|
||||
class="mb-auto"
|
||||
ref="formRef"
|
||||
:model="genericForm"
|
||||
:rules="genericRule"
|
||||
ref="copyFormRef"
|
||||
:model="copyForm"
|
||||
:rules="copyFormRule"
|
||||
label-width="100px"
|
||||
>
|
||||
<el-form-item label="抄送人" prop="copyUserIds">
|
||||
<el-select
|
||||
v-model="genericForm.copyUserIds"
|
||||
v-model="copyForm.copyUserIds"
|
||||
clearable
|
||||
style="width: 100%"
|
||||
multiple
|
||||
@ -136,7 +136,7 @@
|
||||
</el-form-item>
|
||||
<el-form-item label="抄送意见" prop="copyReason">
|
||||
<el-input
|
||||
v-model="genericForm.copyReason"
|
||||
v-model="copyForm.copyReason"
|
||||
clearable
|
||||
placeholder="请输入抄送意见"
|
||||
type="textarea"
|
||||
@ -147,13 +147,13 @@
|
||||
<el-button :disabled="formLoading" type="primary" @click="handleCopy">
|
||||
{{ getButtonDisplayName(OperationButtonType.COPY) }}
|
||||
</el-button>
|
||||
<el-button @click="popOverVisible.copy = false"> 取消 </el-button>
|
||||
<el-button @click="closePropover('copy', copyFormRef)"> 取消 </el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</el-popover>
|
||||
|
||||
<!-- 【转交】按钮 -->
|
||||
<!-- 【转办】按钮 -->
|
||||
<el-popover
|
||||
:visible="popOverVisible.transfer"
|
||||
placement="top-start"
|
||||
@ -171,13 +171,13 @@
|
||||
<el-form
|
||||
label-position="top"
|
||||
class="mb-auto"
|
||||
ref="formRef"
|
||||
:model="genericForm"
|
||||
:rules="genericRule"
|
||||
ref="transferFormRef"
|
||||
:model="transferForm"
|
||||
:rules="transferFormRule"
|
||||
label-width="100px"
|
||||
>
|
||||
<el-form-item label="新审批人" prop="assigneeUserId">
|
||||
<el-select v-model="genericForm.assigneeUserId" clearable style="width: 100%">
|
||||
<el-select v-model="transferForm.assigneeUserId" clearable style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in userOptions"
|
||||
:key="item.id"
|
||||
@ -188,7 +188,7 @@
|
||||
</el-form-item>
|
||||
<el-form-item label="审批意见" prop="reason">
|
||||
<el-input
|
||||
v-model="genericForm.reason"
|
||||
v-model="transferForm.reason"
|
||||
clearable
|
||||
placeholder="请输入审批意见"
|
||||
type="textarea"
|
||||
@ -199,7 +199,7 @@
|
||||
<el-button :disabled="formLoading" type="primary" @click="handleTransfer()">
|
||||
{{ getButtonDisplayName(OperationButtonType.TRANSFER) }}
|
||||
</el-button>
|
||||
<el-button @click="popOverVisible.transfer = false"> 取消 </el-button>
|
||||
<el-button @click="closePropover('transfer', transferFormRef)"> 取消 </el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
@ -223,13 +223,13 @@
|
||||
<el-form
|
||||
label-position="top"
|
||||
class="mb-auto"
|
||||
ref="formRef"
|
||||
:model="genericForm"
|
||||
:rules="genericRule"
|
||||
ref="delegateFormRef"
|
||||
:model="delegateForm"
|
||||
:rules="delegateFormRule"
|
||||
label-width="100px"
|
||||
>
|
||||
<el-form-item label="接收人" prop="delegateUserId">
|
||||
<el-select v-model="genericForm.delegateUserId" clearable style="width: 100%">
|
||||
<el-select v-model="delegateForm.delegateUserId" clearable style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in userOptions"
|
||||
:key="item.id"
|
||||
@ -240,7 +240,7 @@
|
||||
</el-form-item>
|
||||
<el-form-item label="审批意见" prop="reason">
|
||||
<el-input
|
||||
v-model="genericForm.reason"
|
||||
v-model="delegateForm.reason"
|
||||
clearable
|
||||
placeholder="请输入审批意见"
|
||||
type="textarea"
|
||||
@ -251,7 +251,7 @@
|
||||
<el-button :disabled="formLoading" type="primary" @click="handleDelegate()">
|
||||
{{ getButtonDisplayName(OperationButtonType.DELEGATE) }}
|
||||
</el-button>
|
||||
<el-button @click="popOverVisible.delegate = false"> 取消 </el-button>
|
||||
<el-button @click="closePropover('delegate', delegateFormRef)"> 取消 </el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
@ -275,13 +275,13 @@
|
||||
<el-form
|
||||
label-position="top"
|
||||
class="mb-auto"
|
||||
ref="formRef"
|
||||
:model="genericForm"
|
||||
:rules="genericRule"
|
||||
ref="addSignFormRef"
|
||||
:model="addSignForm"
|
||||
:rules="addSignFormRule"
|
||||
label-width="100px"
|
||||
>
|
||||
<el-form-item label="加签处理人" prop="addSignUserIds">
|
||||
<el-select v-model="genericForm.addSignUserIds" multiple clearable style="width: 100%">
|
||||
<el-select v-model="addSignForm.addSignUserIds" multiple clearable style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in userOptions"
|
||||
:key="item.id"
|
||||
@ -292,7 +292,7 @@
|
||||
</el-form-item>
|
||||
<el-form-item label="审批意见" prop="reason">
|
||||
<el-input
|
||||
v-model="genericForm.reason"
|
||||
v-model="addSignForm.reason"
|
||||
clearable
|
||||
placeholder="请输入审批意见"
|
||||
type="textarea"
|
||||
@ -306,7 +306,7 @@
|
||||
<el-button :disabled="formLoading" type="primary" @click="handlerAddSign('after')">
|
||||
向后{{ getButtonDisplayName(OperationButtonType.ADD_SIGN) }}
|
||||
</el-button>
|
||||
<el-button @click="popOverVisible.addSign = false"> 取消 </el-button>
|
||||
<el-button @click="closePropover('addSign', addSignFormRef)"> 取消 </el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
@ -329,13 +329,13 @@
|
||||
<el-form
|
||||
label-position="top"
|
||||
class="mb-auto"
|
||||
ref="formRef"
|
||||
:model="genericForm"
|
||||
:rules="genericRule"
|
||||
ref="deleteSignFormRef"
|
||||
:model="deleteSignForm"
|
||||
:rules="deleteSignFormRule"
|
||||
label-width="100px"
|
||||
>
|
||||
<el-form-item label="减签人员" prop="deleteSignTaskId">
|
||||
<el-select v-model="genericForm.deleteSignTaskId" clearable style="width: 100%">
|
||||
<el-select v-model="deleteSignForm.deleteSignTaskId" clearable style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in runningTask.children"
|
||||
:key="item.id"
|
||||
@ -346,7 +346,7 @@
|
||||
</el-form-item>
|
||||
<el-form-item label="审批意见" prop="reason">
|
||||
<el-input
|
||||
v-model="genericForm.reason"
|
||||
v-model="deleteSignForm.reason"
|
||||
clearable
|
||||
placeholder="请输入审批意见"
|
||||
type="textarea"
|
||||
@ -357,7 +357,7 @@
|
||||
<el-button :disabled="formLoading" type="primary" @click="handlerDeleteSign()">
|
||||
减签
|
||||
</el-button>
|
||||
<el-button @click="popOverVisible.deleteSign = false"> 取消 </el-button>
|
||||
<el-button @click="closePropover('deleteSign', deleteSignFormRef)"> 取消 </el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
@ -372,7 +372,7 @@
|
||||
v-if="runningTask && isHandleTaskStatus() && isShowButton(OperationButtonType.RETURN)"
|
||||
>
|
||||
<template #reference>
|
||||
<div @click="openReturnPopover" class="hover-bg-gray-100 rounded-xl p-6px">
|
||||
<div @click="openPopover('return')" class="hover-bg-gray-100 rounded-xl p-6px">
|
||||
<Icon :size="14" icon="ep:back" />
|
||||
{{ getButtonDisplayName(OperationButtonType.RETURN) }}
|
||||
</div>
|
||||
@ -381,13 +381,13 @@
|
||||
<el-form
|
||||
label-position="top"
|
||||
class="mb-auto"
|
||||
ref="formRef"
|
||||
:model="genericForm"
|
||||
:rules="genericRule"
|
||||
ref="returnFormRef"
|
||||
:model="returnForm"
|
||||
:rules="returnFormRule"
|
||||
label-width="100px"
|
||||
>
|
||||
<el-form-item label="退回节点" prop="targetTaskDefinitionKey">
|
||||
<el-select v-model="genericForm.targetTaskDefinitionKey" clearable style="width: 100%">
|
||||
<el-select v-model="returnForm.targetTaskDefinitionKey" clearable style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in returnList"
|
||||
:key="item.taskDefinitionKey"
|
||||
@ -398,7 +398,7 @@
|
||||
</el-form-item>
|
||||
<el-form-item label="退回理由" prop="returnReason">
|
||||
<el-input
|
||||
v-model="genericForm.returnReason"
|
||||
v-model="returnForm.returnReason"
|
||||
clearable
|
||||
placeholder="请输入退回理由"
|
||||
type="textarea"
|
||||
@ -409,7 +409,7 @@
|
||||
<el-button :disabled="formLoading" type="primary" @click="handleReturn()">
|
||||
{{ getButtonDisplayName(OperationButtonType.RETURN) }}
|
||||
</el-button>
|
||||
<el-button @click="popOverVisible.return = false"> 取消 </el-button>
|
||||
<el-button @click="closePropover('return', returnFormRef)"> 取消 </el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
@ -434,15 +434,15 @@
|
||||
<el-form
|
||||
label-position="top"
|
||||
class="mb-auto"
|
||||
ref="formRef"
|
||||
:model="genericForm"
|
||||
:rules="genericRule"
|
||||
ref="cancelFormRef"
|
||||
:model="cancelForm"
|
||||
:rules="cancelFormRule"
|
||||
label-width="100px"
|
||||
>
|
||||
<el-form-item label="取消理由" prop="cancelReason">
|
||||
<span class="text-#878c93 text-12px"> 取消后,该审批流程将自动结束</span>
|
||||
<el-input
|
||||
v-model="genericForm.cancelReason"
|
||||
v-model="cancelForm.cancelReason"
|
||||
clearable
|
||||
placeholder="请输入取消理由"
|
||||
type="textarea"
|
||||
@ -451,9 +451,9 @@
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button :disabled="formLoading" type="primary" @click="handleCancel()">
|
||||
取消
|
||||
确认
|
||||
</el-button>
|
||||
<el-button @click="popOverVisible.cancel = false"> 取消 </el-button>
|
||||
<el-button @click="closePropover('cancel', cancelFormRef)"> 取消 </el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
@ -477,26 +477,29 @@ import { useUserStoreWithOut } from '@/store/modules/user'
|
||||
import { setConfAndFields2 } from '@/utils/formCreate'
|
||||
import * as TaskApi from '@/api/bpm/task'
|
||||
import * as ProcessInstanceApi from '@/api/bpm/processInstance'
|
||||
import { propTypes } from '@/utils/propTypes'
|
||||
import * as UserApi from '@/api/system/user'
|
||||
import {
|
||||
OperationButtonType,
|
||||
OPERATION_BUTTON_NAME
|
||||
} from '@/components/SimpleProcessDesignerV2/src/consts'
|
||||
import { BpmProcessInstanceStatus } from '@/utils/constants'
|
||||
|
||||
import { BpmProcessInstanceStatus, BpmModelFormType } from '@/utils/constants'
|
||||
import type { FormInstance, FormRules } from 'element-plus'
|
||||
defineOptions({ name: 'ProcessInstanceBtnContainer' })
|
||||
|
||||
const router = useRouter() // 路由
|
||||
const message = useMessage() // 消息弹窗
|
||||
const { proxy } = getCurrentInstance() as any
|
||||
|
||||
const userId = useUserStoreWithOut().getUser.id // 当前登录的编号
|
||||
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
|
||||
const props = defineProps({
|
||||
processInstance: propTypes.object, // 流程实例信息
|
||||
processDefinition: propTypes.object, // 流程定义信息
|
||||
userOptions: propTypes.any
|
||||
})
|
||||
|
||||
const props = defineProps< {
|
||||
processInstance: any, // 流程实例信息
|
||||
processDefinition: any, // 流程定义信息
|
||||
userOptions: UserApi.UserVO[],
|
||||
normalForm: any, // 流程表单 formCreate
|
||||
normalFormApi: any, // 流程表单 formCreate Api
|
||||
writableFields: string[] // 流程表单可以编辑的字段
|
||||
}>()
|
||||
|
||||
const formLoading = ref(false) // 表单加载中
|
||||
const popOverVisible = ref({
|
||||
@ -514,21 +517,99 @@ const returnList = ref([] as any) // 退回节点
|
||||
|
||||
// ========== 审批信息 ==========
|
||||
const runningTask = ref<any>() // 运行中的任务
|
||||
const genericForm = ref<any>({}) // 通用表单
|
||||
const approveForm = ref<any>({}) // 审批通过时,额外的补充信息
|
||||
const approveFormFApi = ref<any>({}) // approveForms 的 fAPi
|
||||
const formRef = ref()
|
||||
const genericRule = reactive({
|
||||
|
||||
// 审批通过意见表单
|
||||
const approveFormRef = ref<FormInstance>()
|
||||
const approveReasonForm = reactive({
|
||||
reason: ''
|
||||
})
|
||||
const approveReasonRule = reactive<FormRules<typeof approveReasonForm>>({
|
||||
reason: [{ required: true, message: '审批意见不能为空', trigger: 'blur' }],
|
||||
returnReason: [{ required: true, message: '退回理由不能为空', trigger: 'blur' }],
|
||||
cancelReason: [{ required: true, message: '取消理由不能为空', trigger: 'blur' }],
|
||||
copyUserIds: [{ required: true, message: '抄送人不能为空', trigger: 'change' }],
|
||||
})
|
||||
// 拒绝表单
|
||||
const rejectFormRef = ref<FormInstance>()
|
||||
const rejectReasonForm = reactive({
|
||||
reason: ''
|
||||
})
|
||||
const rejectReasonRule = reactive<FormRules<typeof rejectReasonForm>>({
|
||||
reason: [{ required: true, message: '审批意见不能为空', trigger: 'blur' }],
|
||||
})
|
||||
|
||||
// 抄送表单
|
||||
const copyFormRef = ref<FormInstance>()
|
||||
const copyForm = reactive({
|
||||
copyUserIds: [],
|
||||
copyReason: ''
|
||||
})
|
||||
const copyFormRule = reactive<FormRules<typeof copyForm>>({
|
||||
copyUserIds: [{ required: true, message: '抄送人不能为空', trigger: 'change' }]
|
||||
})
|
||||
|
||||
// 转办表单
|
||||
const transferFormRef = ref<FormInstance>()
|
||||
const transferForm = reactive({
|
||||
assigneeUserId: undefined,
|
||||
reason: ''
|
||||
})
|
||||
const transferFormRule = reactive<FormRules<typeof transferForm>>({
|
||||
assigneeUserId: [{ required: true, message: '新审批人不能为空', trigger: 'change' }],
|
||||
reason: [{ required: true, message: '审批意见不能为空', trigger: 'blur' }],
|
||||
})
|
||||
|
||||
// 委派表单
|
||||
const delegateFormRef = ref<FormInstance>()
|
||||
const delegateForm = reactive({
|
||||
delegateUserId: undefined,
|
||||
reason: ''
|
||||
})
|
||||
const delegateFormRule = reactive<FormRules<typeof delegateForm>>({
|
||||
delegateUserId: [{ required: true, message: '接收人不能为空', trigger: 'change' }],
|
||||
reason: [{ required: true, message: '审批意见不能为空', trigger: 'blur' }],
|
||||
})
|
||||
|
||||
// 加签表单
|
||||
const addSignFormRef = ref<FormInstance>()
|
||||
const addSignForm = reactive({
|
||||
addSignUserIds: undefined,
|
||||
reason: ''
|
||||
})
|
||||
const addSignFormRule = reactive<FormRules<typeof addSignForm>>({
|
||||
addSignUserIds: [{ required: true, message: '加签处理人不能为空', trigger: 'change' }],
|
||||
reason: [{ required: true, message: '审批意见不能为空', trigger: 'blur' }],
|
||||
})
|
||||
|
||||
// 减签表单
|
||||
const deleteSignFormRef = ref<FormInstance>()
|
||||
const deleteSignForm = reactive({
|
||||
deleteSignTaskId: undefined,
|
||||
reason: ''
|
||||
})
|
||||
const deleteSignFormRule = reactive<FormRules<typeof deleteSignForm>>({
|
||||
deleteSignTaskId: [{ required: true, message: '减签人员不能为空', trigger: 'change' }],
|
||||
targetTaskDefinitionKey: [{ required: true, message: '退回节点不能为空', trigger: 'change' }]
|
||||
}) // 表单校验规则
|
||||
reason: [{ required: true, message: '审批意见不能为空', trigger: 'blur' }],
|
||||
})
|
||||
|
||||
// 退回表单
|
||||
const returnFormRef = ref<FormInstance>()
|
||||
const returnForm = reactive({
|
||||
targetTaskDefinitionKey: undefined,
|
||||
returnReason: ''
|
||||
})
|
||||
const returnFormRule = reactive<FormRules<typeof returnForm>>({
|
||||
targetTaskDefinitionKey: [{ required: true, message: '退回节点不能为空', trigger: 'change' }],
|
||||
returnReason: [{ required: true, message: '退回理由不能为空', trigger: 'blur' }]
|
||||
})
|
||||
|
||||
// 取消表单
|
||||
const cancelFormRef = ref<FormInstance>()
|
||||
const cancelForm = reactive({
|
||||
cancelReason: ''
|
||||
})
|
||||
const cancelFormRule = reactive<FormRules<typeof cancelForm>>({
|
||||
cancelReason: [{ required: true, message: '取消理由不能为空', trigger: 'blur' }],
|
||||
})
|
||||
|
||||
/** 监听 approveFormFApis,实现它对应的 form-create 初始化后,隐藏掉对应的表单提交按钮 */
|
||||
watch(
|
||||
@ -542,43 +623,57 @@ watch(
|
||||
}
|
||||
)
|
||||
|
||||
/** 弹出退回气泡卡 */
|
||||
const openReturnPopover = async () => {
|
||||
returnList.value = await TaskApi.getTaskListByReturn(runningTask.value.id)
|
||||
if (returnList.value.length === 0) {
|
||||
message.warning('当前没有可退回的节点')
|
||||
return
|
||||
}
|
||||
await openPopover('return')
|
||||
}
|
||||
|
||||
/** 弹出气泡卡 */
|
||||
const openPopover = async (type: string) => {
|
||||
if (type === 'approve') {
|
||||
// 校验流程表单
|
||||
const valid = await validateNormalForm();
|
||||
if (!valid) {
|
||||
message.warning('表单校验不通过,请先完善表单!!')
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (type === 'return') {
|
||||
// 获取退回节点
|
||||
returnList.value = await TaskApi.getTaskListByReturn(runningTask.value.id)
|
||||
if (returnList.value.length === 0) {
|
||||
message.warning('当前没有可退回的节点')
|
||||
return
|
||||
}
|
||||
}
|
||||
Object.keys(popOverVisible.value).forEach((item) => {
|
||||
popOverVisible.value[item] = item === type
|
||||
})
|
||||
await nextTick()
|
||||
formRef.value.resetFields()
|
||||
// await nextTick()
|
||||
// formRef.value.resetFields()
|
||||
}
|
||||
|
||||
/** 关闭气泡卡 */
|
||||
const closePropover = (type: string, formRef: FormInstance | undefined) => {
|
||||
if (formRef) {
|
||||
formRef.resetFields()
|
||||
}
|
||||
popOverVisible.value[type] = false
|
||||
}
|
||||
|
||||
/** 处理审批通过和不通过的操作 */
|
||||
const handleAudit = async (pass: boolean) => {
|
||||
const handleAudit = async (pass: boolean, formRef: FormInstance | undefined) => {
|
||||
formLoading.value = true
|
||||
try {
|
||||
const genericFormRef = proxy.$refs['formRef']
|
||||
// 1.2 校验表单
|
||||
const elForm = unref(genericFormRef)
|
||||
if (!elForm) return
|
||||
const valid = await elForm.validate()
|
||||
if (!valid) return
|
||||
|
||||
// 2.1 提交审批
|
||||
const data = {
|
||||
id: runningTask.value.id,
|
||||
reason: genericForm.value.reason
|
||||
}
|
||||
// 校验表单
|
||||
if (!formRef) return
|
||||
await formRef.validate()
|
||||
if (pass) {
|
||||
// 审批通过,并且有额外的 approveForm 表单,需要校验 + 拼接到 data 表单里提交
|
||||
// 获取修改的流程变量, 暂时只支持流程表单
|
||||
const variables = getUpdatedProcessInstanceVaiables();
|
||||
// 审批通过数据
|
||||
const data = {
|
||||
id: runningTask.value.id,
|
||||
reason: approveReasonForm.reason,
|
||||
variables // 审批通过, 把修改的字段值赋于流程实例变量
|
||||
}
|
||||
// 多表单处理,并且有额外的 approveForm 表单,需要校验 + 拼接到 data 表单里提交
|
||||
// TODO 芋艿 任务有多表单这里要如何处理,会和可编辑的字段冲突
|
||||
const formCreateApi = approveFormFApi.value
|
||||
if (Object.keys(formCreateApi)?.length > 0) {
|
||||
await formCreateApi.validate()
|
||||
@ -589,11 +684,18 @@ const handleAudit = async (pass: boolean) => {
|
||||
popOverVisible.value.approve = false
|
||||
message.success('审批通过成功')
|
||||
} else {
|
||||
// 审批不通过数据
|
||||
const data = {
|
||||
id: runningTask.value.id,
|
||||
reason: rejectReasonForm.reason,
|
||||
}
|
||||
await TaskApi.rejectTask(data)
|
||||
popOverVisible.value.reject = false
|
||||
message.success('审批不通过成功')
|
||||
}
|
||||
// 2.2 加载最新数据
|
||||
// 重置表单
|
||||
formRef.resetFields()
|
||||
// 加载最新数据
|
||||
reload()
|
||||
} finally {
|
||||
formLoading.value = false
|
||||
@ -604,19 +706,17 @@ const handleAudit = async (pass: boolean) => {
|
||||
const handleCopy = async () => {
|
||||
formLoading.value = true
|
||||
try {
|
||||
const copyFormRef = proxy.$refs['formRef']
|
||||
// 1. 校验表单
|
||||
const elForm = unref(copyFormRef)
|
||||
if (!elForm) return
|
||||
const valid = await elForm.validate()
|
||||
if (!valid) return
|
||||
if (!copyFormRef.value) return
|
||||
await copyFormRef.value.validate()
|
||||
// 2. 提交抄送
|
||||
const data = {
|
||||
id: runningTask.value.id,
|
||||
reason: genericForm.value.copyReason,
|
||||
copyUserIds: genericForm.value.copyUserIds
|
||||
reason: copyForm.copyReason,
|
||||
copyUserIds:copyForm.copyUserIds
|
||||
}
|
||||
await TaskApi.copyTask(data)
|
||||
copyFormRef.value.resetFields()
|
||||
popOverVisible.value.copy = false
|
||||
message.success('操作成功')
|
||||
} finally {
|
||||
@ -628,20 +728,17 @@ const handleCopy = async () => {
|
||||
const handleTransfer = async () => {
|
||||
formLoading.value = true
|
||||
try {
|
||||
const transferFormRef = proxy.$refs['formRef']
|
||||
// 1.1 校验表单
|
||||
const elForm = unref(transferFormRef)
|
||||
if (!elForm) return
|
||||
const valid = await elForm.validate()
|
||||
if (!valid) return
|
||||
if (!transferFormRef.value) return
|
||||
await transferFormRef.value.validate()
|
||||
// 1.2 提交转交
|
||||
const data = {
|
||||
id: runningTask.value.id,
|
||||
reason: genericForm.value.reason,
|
||||
assigneeUserId: genericForm.value.assigneeUserId
|
||||
reason: transferForm.reason,
|
||||
assigneeUserId: transferForm.assigneeUserId
|
||||
}
|
||||
|
||||
await TaskApi.transferTask(data)
|
||||
transferFormRef.value.resetFields()
|
||||
popOverVisible.value.transfer = false
|
||||
message.success('操作成功')
|
||||
// 2. 加载最新数据
|
||||
@ -655,21 +752,20 @@ const handleTransfer = async () => {
|
||||
const handleDelegate = async () => {
|
||||
formLoading.value = true
|
||||
try {
|
||||
const deletegateFormRef = proxy.$refs['formRef']
|
||||
|
||||
// 1.1 校验表单
|
||||
const elForm = unref(deletegateFormRef)
|
||||
if (!elForm) return
|
||||
const valid = await elForm.validate()
|
||||
if (!valid) return
|
||||
if (!delegateFormRef.value) return
|
||||
await delegateFormRef.value.validate()
|
||||
// 1.2 处理委派
|
||||
const data = {
|
||||
id: runningTask.value.id,
|
||||
reason: genericForm.value.reason,
|
||||
delegateUserId: genericForm.value.delegateUserId
|
||||
reason: delegateForm.reason,
|
||||
delegateUserId: delegateForm.delegateUserId
|
||||
}
|
||||
|
||||
await TaskApi.delegateTask(data)
|
||||
popOverVisible.value.delegate = false
|
||||
delegateFormRef.value.resetFields()
|
||||
message.success('操作成功')
|
||||
// 2. 加载最新数据
|
||||
reload()
|
||||
@ -682,21 +778,19 @@ const handleDelegate = async () => {
|
||||
const handlerAddSign = async (type: string) => {
|
||||
formLoading.value = true
|
||||
try {
|
||||
const transferFormRef = proxy.$refs['formRef']
|
||||
// 1.1 校验表单
|
||||
const elForm = unref(transferFormRef)
|
||||
if (!elForm) return
|
||||
const valid = await elForm.validate()
|
||||
if (!valid) return
|
||||
if (!addSignFormRef.value) return
|
||||
await addSignFormRef.value.validate()
|
||||
// 1.2 提交加签
|
||||
const data = {
|
||||
id: runningTask.value.id,
|
||||
type,
|
||||
reason: genericForm.value.reason,
|
||||
userIds: genericForm.value.addSignUserIds
|
||||
reason: addSignForm.reason,
|
||||
userIds: addSignForm.addSignUserIds
|
||||
}
|
||||
await TaskApi.signCreateTask(data)
|
||||
message.success('操作成功')
|
||||
addSignFormRef.value.resetFields()
|
||||
popOverVisible.value.addSign = false
|
||||
// 2 加载最新数据
|
||||
reload()
|
||||
@ -709,21 +803,19 @@ const handlerAddSign = async (type: string) => {
|
||||
const handleReturn = async () => {
|
||||
formLoading.value = true
|
||||
try {
|
||||
const returnFormRef = proxy.$refs['formRef']
|
||||
// 1.1 校验表单
|
||||
const elForm = unref(returnFormRef)
|
||||
if (!elForm) return
|
||||
const valid = await elForm.validate()
|
||||
if (!valid) return
|
||||
if (!returnFormRef.value) return
|
||||
await returnFormRef.value.validate()
|
||||
// 1.2 提交退回
|
||||
const data = {
|
||||
id: runningTask.value.id,
|
||||
reason: genericForm.value.returnReason,
|
||||
targetTaskDefinitionKey: genericForm.value.targetTaskDefinitionKey
|
||||
reason: returnForm.returnReason,
|
||||
targetTaskDefinitionKey: returnForm.targetTaskDefinitionKey
|
||||
}
|
||||
|
||||
await TaskApi.returnTask(data)
|
||||
popOverVisible.value.return = false
|
||||
returnFormRef.value.resetFields()
|
||||
message.success('操作成功')
|
||||
// 2 重新加载数据
|
||||
reload()
|
||||
@ -736,19 +828,17 @@ const handleReturn = async () => {
|
||||
const handleCancel = async () => {
|
||||
formLoading.value = true
|
||||
try {
|
||||
const cancelFormRef = proxy.$refs['formRef']
|
||||
// 1.1 校验表单
|
||||
const elForm = unref(cancelFormRef)
|
||||
if (!elForm) return
|
||||
const valid = await elForm.validate()
|
||||
if (!valid) return
|
||||
if (!cancelFormRef.value) return
|
||||
await cancelFormRef.value.validate()
|
||||
// 1.2 提交取消
|
||||
await ProcessInstanceApi.cancelProcessInstanceByStartUser(
|
||||
props.processInstance.id,
|
||||
genericForm.value.cancelReason
|
||||
cancelForm.cancelReason
|
||||
)
|
||||
popOverVisible.value.return = false
|
||||
message.success('操作成功')
|
||||
cancelFormRef.value.resetFields()
|
||||
// 2 重新加载数据
|
||||
reload()
|
||||
} finally {
|
||||
@ -775,19 +865,17 @@ const getDeleteSignUserLabel = (task: any): string => {
|
||||
const handlerDeleteSign = async () => {
|
||||
formLoading.value = true
|
||||
try {
|
||||
const deleteFormRef = proxy.$refs['formRef']
|
||||
// 1.1 校验表单
|
||||
const elForm = unref(deleteFormRef)
|
||||
if (!elForm) return
|
||||
const valid = await elForm.validate()
|
||||
if (!valid) return
|
||||
if (!deleteSignFormRef.value) return
|
||||
await deleteSignFormRef.value.validate()
|
||||
// 1.2 提交减签
|
||||
const data = {
|
||||
id: genericForm.value.deleteSignTaskId,
|
||||
reason: genericForm.value.reason
|
||||
id: deleteSignForm.deleteSignTaskId,
|
||||
reason: deleteSignForm.reason
|
||||
}
|
||||
await TaskApi.signDeleteTask(data)
|
||||
message.success('减签成功')
|
||||
deleteSignFormRef.value.resetFields()
|
||||
popOverVisible.value.deleteSign = false
|
||||
// 2 加载最新数据
|
||||
reload()
|
||||
@ -841,7 +929,6 @@ const getButtonDisplayName = (btnType: OperationButtonType) => {
|
||||
}
|
||||
|
||||
const loadTodoTask = (task: any) => {
|
||||
genericForm.value = {}
|
||||
approveForm.value = {}
|
||||
approveFormFApi.value = {}
|
||||
runningTask.value = task
|
||||
@ -855,6 +942,30 @@ const loadTodoTask = (task: any) => {
|
||||
}
|
||||
}
|
||||
|
||||
/** 校验流程表单 */
|
||||
const validateNormalForm = async () => {
|
||||
if (props.processDefinition?.formType === BpmModelFormType.NORMAL) {
|
||||
let valid = true
|
||||
try {
|
||||
await props.normalFormApi?.validate()
|
||||
} catch {
|
||||
valid = false;
|
||||
}
|
||||
return valid;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
/** 从可以编辑的流程表单字段,获取需要修改的流程实例的变量 */
|
||||
const getUpdatedProcessInstanceVaiables = ()=> {
|
||||
const variables = {}
|
||||
props.writableFields.forEach( (field) => {
|
||||
const fieldValue = props.normalFormApi.getValue(field)
|
||||
variables[field] = fieldValue;
|
||||
})
|
||||
return variables
|
||||
}
|
||||
|
||||
defineExpose({ loadTodoTask })
|
||||
</script>
|
||||
|
||||
|
@ -49,7 +49,7 @@
|
||||
class="form-box flex flex-col mb-30px flex-1"
|
||||
>
|
||||
<!-- 情况一:流程表单 -->
|
||||
<el-col v-if="processDefinition?.formType === 10">
|
||||
<el-col v-if="processDefinition?.formType === BpmModelFormType.NORMAL">
|
||||
<form-create
|
||||
v-model="detailForm.value"
|
||||
v-model:api="fApi"
|
||||
@ -58,7 +58,7 @@
|
||||
/>
|
||||
</el-col>
|
||||
<!-- 情况二:业务表单 -->
|
||||
<div v-if="processDefinition?.formType === 20">
|
||||
<div v-if="processDefinition?.formType === BpmModelFormType.CUSTOM">
|
||||
<BusinessFormComponent :id="processInstance.businessKey" />
|
||||
</div>
|
||||
</div>
|
||||
@ -116,6 +116,9 @@
|
||||
:process-instance="processInstance"
|
||||
:process-definition="processDefinition"
|
||||
:userOptions="userOptions"
|
||||
:normal-form="detailForm"
|
||||
:normal-form-api="fApi"
|
||||
:writable-fields="writableFields"
|
||||
@success="refresh"
|
||||
/>
|
||||
</div>
|
||||
@ -126,7 +129,7 @@
|
||||
<script lang="ts" setup>
|
||||
import { formatDate } from '@/utils/formatTime'
|
||||
import { DICT_TYPE } from '@/utils/dict'
|
||||
import { BpmModelType } from '@/utils/constants'
|
||||
import { BpmModelType, BpmModelFormType } from '@/utils/constants'
|
||||
import { setConfAndFields2 } from '@/utils/formCreate'
|
||||
import { registerComponent } from '@/utils/routerHelper'
|
||||
import type { ApiAttrs } from '@form-create/element-ui/types/config'
|
||||
@ -171,6 +174,8 @@ const detailForm = ref({
|
||||
value: {}
|
||||
}) // 流程实例的表单详情
|
||||
|
||||
const writableFields: Array<string> = [] // 表单可以编辑的字段
|
||||
|
||||
/** 获得详情 */
|
||||
const getDetail = () => {
|
||||
getApprovalDetail()
|
||||
@ -202,11 +207,12 @@ const getApprovalDetail = async () => {
|
||||
processDefinition.value = data.processDefinition
|
||||
|
||||
// 设置表单信息
|
||||
if (processDefinition.value.formType === 10) {
|
||||
if (processDefinition.value.formType === BpmModelFormType.NORMAL) {
|
||||
// 获取表单字段权限
|
||||
const formFieldsPermission = data.formFieldsPermission
|
||||
|
||||
if (detailForm.value.rule.length > 0) {
|
||||
// 清空可编辑字段为空
|
||||
writableFields.splice(0)
|
||||
if (detailForm.value.rule?.length > 0) {
|
||||
// 避免刷新 form-create 显示不了
|
||||
detailForm.value.value = processInstance.value.formVariables
|
||||
} else {
|
||||
@ -271,6 +277,8 @@ const setFieldPermission = (field: string, permission: string) => {
|
||||
if (permission === FieldPermissionType.WRITE) {
|
||||
//@ts-ignore
|
||||
fApi.value?.disabled(false, field)
|
||||
// 加入可以编辑的字段
|
||||
writableFields.push(field)
|
||||
}
|
||||
if (permission === FieldPermissionType.NONE) {
|
||||
//@ts-ignore
|
||||
@ -314,6 +322,7 @@ $process-header-height: 194px;
|
||||
overflow: auto;
|
||||
|
||||
.form-scroll-area {
|
||||
display: flex;
|
||||
height: calc(
|
||||
100vh - var(--top-tool-height) - var(--tags-view-height) - var(--app-footer-height) - 35px -
|
||||
$process-header-height - 40px
|
||||
@ -323,7 +332,6 @@ $process-header-height: 194px;
|
||||
$process-header-height - 40px
|
||||
);
|
||||
overflow: auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
:deep(.box-card) {
|
||||
|
@ -25,7 +25,8 @@
|
||||
</el-form-item>
|
||||
|
||||
<!-- TODO @ tuituji:style 可以使用 unocss -->
|
||||
<el-form-item label="" prop="category" :style="{ position: 'absolute', right: '130px' }">
|
||||
<el-form-item label="" prop="category" :style="{ position: 'absolute', right: '300px' }">
|
||||
<!-- TODO @tuituji:应该选择好分类,就触发搜索啦。 RE:done & to check-->
|
||||
<el-select
|
||||
v-model="queryParams.category"
|
||||
placeholder="请选择流程分类"
|
||||
@ -42,6 +43,25 @@
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="" prop="status" :style="{ position: 'absolute', right: '130px' }">
|
||||
<el-select
|
||||
v-model="queryParams.status"
|
||||
placeholder="请选择流程状态"
|
||||
clearable
|
||||
class="!w-155px"
|
||||
@change="handleQuery"
|
||||
>
|
||||
<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>
|
||||
|
||||
<!-- 高级筛选 -->
|
||||
<!-- TODO @ tuituji:style 可以使用 unocss -->
|
||||
<el-form-item :style="{ position: 'absolute', right: '0px' }">
|
||||
<el-popover
|
||||
:visible="showPopover"
|
||||
@ -84,21 +104,6 @@
|
||||
class="!w-390px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="流程状态" class="bold-label" label-position="top" prop="status">
|
||||
<el-select
|
||||
v-model="queryParams.status"
|
||||
placeholder="请选择流程状态"
|
||||
clearable
|
||||
class="!w-390px"
|
||||
>
|
||||
<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="发起时间" class="bold-label" label-position="top" prop="createTime">
|
||||
<el-date-picker
|
||||
v-model="queryParams.createTime"
|
||||
@ -110,10 +115,11 @@
|
||||
class="!w-240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<!-- TODO tuituiji:参考钉钉,1)按照清空、取消、确认排序。2)右对齐。3)确认增加 primary -->
|
||||
<el-form-item class="bold-label" label-position="top">
|
||||
<el-button @click="resetQuery"> 清空</el-button>
|
||||
<el-button @click="handleQuery"> 确认</el-button>
|
||||
<el-button @click="showPopover = false"> 取消</el-button>
|
||||
<el-button @click="handleQuery" type="primary"> 确认</el-button>
|
||||
<el-button @click="resetQuery"> 清空</el-button>
|
||||
</el-form-item>
|
||||
</el-popover>
|
||||
</el-form-item>
|
||||
@ -132,7 +138,7 @@
|
||||
fixed="left"
|
||||
/>
|
||||
<!-- TODO @芋艿:摘要 -->
|
||||
<!-- TODO @tuituji:流程状态。可见需求文档里 Re:没看懂;回复:1)就是审批中的时候,展示审批人;2)审批结束的时候,就展示状态 -->
|
||||
<!-- TODO tuituiji:参考钉钉;1)审批中时,展示审批任务;2)非审批中,展示状态 -->
|
||||
<el-table-column label="流程状态" prop="status" width="120">
|
||||
<template #default="scope">
|
||||
<dict-tag :type="DICT_TYPE.BPM_PROCESS_INSTANCE_STATUS" :value="scope.row.status" />
|
||||
@ -200,6 +206,7 @@
|
||||
</ContentWrap>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
// TODO @tuituji:List 改成 <Icon icon="ep:plus" class="mr-5px" /> 类似这种组件哈。 RE:done & to check
|
||||
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||
import { dateFormatter } from '@/utils/formatTime'
|
||||
import { ElMessageBox } from 'element-plus'
|
||||
@ -275,7 +282,7 @@ const handleCreate = async (row?: ProcessInstanceVO) => {
|
||||
}
|
||||
|
||||
/** 查看详情 */
|
||||
const handleDetail = (row: any) => {
|
||||
const handleDetail = (row: ProcessInstanceVO) => {
|
||||
router.push({
|
||||
name: 'BpmProcessInstanceDetail',
|
||||
query: {
|
||||
@ -285,7 +292,7 @@ const handleDetail = (row: any) => {
|
||||
}
|
||||
|
||||
/** 取消按钮操作 */
|
||||
const handleCancel = async (row: any) => {
|
||||
const handleCancel = async (row: ProcessInstanceVO) => {
|
||||
// 二次确认
|
||||
const { value } = await ElMessageBox.prompt('请输入取消原因', '取消流程', {
|
||||
confirmButtonText: t('common.ok'),
|
||||
|
@ -16,7 +16,7 @@
|
||||
class="-mb-15px"
|
||||
label-width="68px"
|
||||
>
|
||||
<el-form-item label="任务名称" prop="name">
|
||||
<el-form-item label="" prop="name">
|
||||
<el-input
|
||||
v-model="queryParams.name"
|
||||
class="!w-240px"
|
||||
@ -25,27 +25,96 @@
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="创建时间" prop="createTime">
|
||||
<el-date-picker
|
||||
v-model="queryParams.createTime"
|
||||
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
|
||||
class="!w-240px"
|
||||
end-placeholder="结束日期"
|
||||
start-placeholder="开始日期"
|
||||
type="daterange"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button @click="handleQuery">
|
||||
<Icon class="mr-5px" icon="ep:search" />
|
||||
搜索
|
||||
</el-button>
|
||||
<el-button @click="resetQuery">
|
||||
<Icon class="mr-5px" icon="ep:refresh" />
|
||||
重置
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="" prop="category" :style="{ position: 'absolute', right: '300px' }">
|
||||
<el-select
|
||||
v-model="queryParams.category"
|
||||
placeholder="请选择流程分类"
|
||||
clearable
|
||||
class="!w-155px"
|
||||
@change="handleQuery"
|
||||
>
|
||||
<el-option
|
||||
v-for="category in categoryList"
|
||||
:key="category.code"
|
||||
:label="category.name"
|
||||
:value="category.code"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="" prop="status" :style="{ position: 'absolute', right: '130px' }">
|
||||
<el-select
|
||||
v-model="queryParams.status"
|
||||
placeholder="请选择流程状态"
|
||||
clearable
|
||||
class="!w-155px"
|
||||
@change="handleQuery"
|
||||
>
|
||||
<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 :style="{ position: 'absolute', right: '0px' }">
|
||||
<el-popover
|
||||
:visible="showPopover"
|
||||
persistent
|
||||
:width="400"
|
||||
:show-arrow="false"
|
||||
placement="bottom-end"
|
||||
>
|
||||
<template #reference>
|
||||
<el-button @click="showPopover = !showPopover" >
|
||||
<Icon icon="ep:plus" class="mr-5px" />高级筛选
|
||||
</el-button>
|
||||
|
||||
</template>
|
||||
<el-form-item label="流程发起人" class="bold-label" label-position="top" prop="category">
|
||||
<el-select
|
||||
v-model="queryParams.category"
|
||||
placeholder="请选择流程发起人"
|
||||
clearable
|
||||
class="!w-390px"
|
||||
>
|
||||
<el-option
|
||||
v-for="category in categoryList"
|
||||
:key="category.code"
|
||||
:label="category.name"
|
||||
:value="category.code"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="发起时间" class="bold-label" label-position="top" 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 class="bold-label" label-position="top">
|
||||
<el-button @click="handleQuery"> 确认</el-button>
|
||||
<el-button @click="showPopover = false"> 取消</el-button>
|
||||
<el-button @click="resetQuery"> 清空</el-button>
|
||||
</el-form-item>
|
||||
</el-popover>
|
||||
</el-form-item>
|
||||
|
||||
</el-form>
|
||||
</ContentWrap>
|
||||
|
||||
@ -110,9 +179,10 @@
|
||||
</ContentWrap>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { DICT_TYPE } from '@/utils/dict'
|
||||
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||
import { dateFormatter, formatPast2 } from '@/utils/formatTime'
|
||||
import * as TaskApi from '@/api/bpm/task'
|
||||
import { CategoryApi, CategoryVO } from '@/api/bpm/category'
|
||||
|
||||
defineOptions({ name: 'BpmTodoTask' })
|
||||
|
||||
@ -125,9 +195,13 @@ const queryParams = reactive({
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
name: '',
|
||||
category: undefined,
|
||||
status: undefined,
|
||||
createTime: []
|
||||
})
|
||||
const queryFormRef = ref() // 搜索的表单
|
||||
const categoryList = ref<CategoryVO[]>([]) // 流程分类列表
|
||||
const showPopover = ref(false)
|
||||
|
||||
/** 查询任务列表 */
|
||||
const getList = async () => {
|
||||
@ -165,7 +239,8 @@ const handleAudit = (row: any) => {
|
||||
}
|
||||
|
||||
/** 初始化 **/
|
||||
onMounted(() => {
|
||||
getList()
|
||||
onMounted(async () => {
|
||||
await getList()
|
||||
categoryList.value = await CategoryApi.getCategorySimpleList()
|
||||
})
|
||||
</script>
|
||||
|
@ -16,7 +16,7 @@
|
||||
class="-mb-15px"
|
||||
label-width="68px"
|
||||
>
|
||||
<el-form-item label="任务名称" prop="name">
|
||||
<el-form-item label="" prop="name">
|
||||
<el-input
|
||||
v-model="queryParams.name"
|
||||
class="!w-240px"
|
||||
@ -25,27 +25,79 @@
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="创建时间" prop="createTime">
|
||||
<el-date-picker
|
||||
v-model="queryParams.createTime"
|
||||
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
|
||||
class="!w-240px"
|
||||
end-placeholder="结束日期"
|
||||
start-placeholder="开始日期"
|
||||
type="daterange"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button @click="handleQuery">
|
||||
<Icon class="mr-5px" icon="ep:search" />
|
||||
搜索
|
||||
</el-button>
|
||||
<el-button @click="resetQuery">
|
||||
<Icon class="mr-5px" icon="ep:refresh" />
|
||||
重置
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="" prop="category" :style="{ position: 'absolute', right: '130px' }">
|
||||
<el-select
|
||||
v-model="queryParams.category"
|
||||
placeholder="请选择流程分类"
|
||||
clearable
|
||||
class="!w-155px"
|
||||
@change="handleQuery"
|
||||
>
|
||||
<el-option
|
||||
v-for="category in categoryList"
|
||||
:key="category.code"
|
||||
:label="category.name"
|
||||
:value="category.code"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 高级筛选 -->
|
||||
<el-form-item :style="{ position: 'absolute', right: '0px' }">
|
||||
<el-popover
|
||||
:visible="showPopover"
|
||||
persistent
|
||||
:width="400"
|
||||
:show-arrow="false"
|
||||
placement="bottom-end"
|
||||
>
|
||||
<template #reference>
|
||||
<el-button @click="showPopover = !showPopover" >
|
||||
<Icon icon="ep:plus" class="mr-5px" />高级筛选
|
||||
</el-button>
|
||||
|
||||
</template>
|
||||
<el-form-item label="流程发起人" class="bold-label" label-position="top" prop="category">
|
||||
<el-select
|
||||
v-model="queryParams.category"
|
||||
placeholder="请选择流程发起人"
|
||||
clearable
|
||||
class="!w-390px"
|
||||
>
|
||||
<el-option
|
||||
v-for="category in categoryList"
|
||||
:key="category.code"
|
||||
:label="category.name"
|
||||
:value="category.code"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="发起时间" class="bold-label" label-position="top" 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 class="bold-label" label-position="top">
|
||||
<el-button @click="handleQuery"> 确认</el-button>
|
||||
<el-button @click="showPopover = false"> 取消</el-button>
|
||||
<el-button @click="resetQuery"> 清空</el-button>
|
||||
</el-form-item>
|
||||
</el-popover>
|
||||
</el-form-item>
|
||||
|
||||
</el-form>
|
||||
</ContentWrap>
|
||||
|
||||
@ -95,6 +147,7 @@
|
||||
<script lang="ts" setup>
|
||||
import { dateFormatter } from '@/utils/formatTime'
|
||||
import * as TaskApi from '@/api/bpm/task'
|
||||
import { CategoryApi, CategoryVO } from '@/api/bpm/category'
|
||||
|
||||
defineOptions({ name: 'BpmTodoTask' })
|
||||
|
||||
@ -107,9 +160,11 @@ const queryParams = reactive({
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
name: '',
|
||||
category: undefined,
|
||||
createTime: []
|
||||
})
|
||||
const queryFormRef = ref() // 搜索的表单
|
||||
const categoryList = ref<CategoryVO[]>([]) // 流程分类列表
|
||||
|
||||
/** 查询任务列表 */
|
||||
const getList = async () => {
|
||||
@ -123,6 +178,8 @@ const getList = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
const showPopover = ref(false)
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.pageNo = 1
|
||||
@ -147,7 +204,8 @@ const handleAudit = (row: any) => {
|
||||
}
|
||||
|
||||
/** 初始化 **/
|
||||
onMounted(() => {
|
||||
getList()
|
||||
onMounted(async () => {
|
||||
await getList()
|
||||
categoryList.value = await CategoryApi.getCategorySimpleList()
|
||||
})
|
||||
</script>
|
||||
|
@ -101,7 +101,7 @@
|
||||
<el-input
|
||||
disabled
|
||||
v-model="formData.totalProductPrice"
|
||||
:formatter="erpPriceTableColumnFormatter"
|
||||
:formatter="erpPriceInputFormatter"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@ -123,7 +123,7 @@
|
||||
disabled
|
||||
v-model="formData.totalPrice"
|
||||
placeholder="请输入商机金额"
|
||||
:formatter="erpPriceTableColumnFormatter"
|
||||
:formatter="erpPriceInputFormatter"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@ -142,7 +142,7 @@ import * as CustomerApi from '@/api/crm/customer'
|
||||
import * as UserApi from '@/api/system/user'
|
||||
import { useUserStore } from '@/store/modules/user'
|
||||
import BusinessProductForm from './components/BusinessProductForm.vue'
|
||||
import { erpPriceMultiply, erpPriceTableColumnFormatter } from '@/utils'
|
||||
import { erpPriceMultiply, erpPriceInputFormatter } from '@/utils'
|
||||
|
||||
const { t } = useI18n() // 国际化
|
||||
const message = useMessage() // 消息弹窗
|
||||
|
@ -159,7 +159,7 @@
|
||||
<el-input
|
||||
disabled
|
||||
v-model="formData.totalProductPrice"
|
||||
:formatter="erpPriceTableColumnFormatter"
|
||||
:formatter="erpPriceInputFormatter"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@ -181,7 +181,7 @@
|
||||
disabled
|
||||
v-model="formData.totalPrice"
|
||||
placeholder="请输入商机金额"
|
||||
:formatter="erpPriceTableColumnFormattere"
|
||||
:formatter="erpPriceInputFormatter"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@ -199,7 +199,7 @@ import * as ContractApi from '@/api/crm/contract'
|
||||
import * as UserApi from '@/api/system/user'
|
||||
import * as ContactApi from '@/api/crm/contact'
|
||||
import * as BusinessApi from '@/api/crm/business'
|
||||
import { erpPriceMultiply, erpPriceTableColumnFormatter } from '@/utils'
|
||||
import { erpPriceMultiply, erpPriceInputFormatter } from '@/utils'
|
||||
import { useUserStore } from '@/store/modules/user'
|
||||
import ContractProductForm from '@/views/crm/contract/components/ContractProductForm.vue'
|
||||
|
||||
|
@ -24,7 +24,7 @@ defineOptions({ name: 'CrmProductDetail' })
|
||||
|
||||
const route = useRoute()
|
||||
const message = useMessage()
|
||||
const id = Number(route.params.id) // 编号
|
||||
const id = route.params.id // 编号
|
||||
const loading = ref(true) // 加载中
|
||||
const product = ref<ProductApi.ProductVO>({} as ProductApi.ProductVO) // 详情
|
||||
|
||||
|
@ -27,7 +27,7 @@ defineOptions({ name: 'IoTDeviceDetail' })
|
||||
|
||||
const route = useRoute()
|
||||
const message = useMessage()
|
||||
const id = Number(route.params.id) // 编号
|
||||
const id = route.params.id // 编号
|
||||
const loading = ref(true) // 加载中
|
||||
const product = ref<ProductVO>({} as ProductVO) // 产品详情
|
||||
const device = ref<DeviceVO>({} as DeviceVO) // 设备详情
|
||||
|
@ -33,7 +33,7 @@ const { currentRoute } = useRouter()
|
||||
|
||||
const route = useRoute()
|
||||
const message = useMessage()
|
||||
const id = Number(route.params.id) // 编号
|
||||
const id = route.params.id // 编号
|
||||
const loading = ref(true) // 加载中
|
||||
const product = ref<ProductVO>({} as ProductVO) // 详情
|
||||
const activeTab = ref('info') // 默认激活的标签页
|
||||
|
@ -113,7 +113,7 @@ const getUserData = async (id: number) => {
|
||||
const { currentRoute } = useRouter() // 路由
|
||||
const { delView } = useTagsViewStore() // 视图操作
|
||||
const route = useRoute()
|
||||
const id = Number(route.params.id)
|
||||
const id = route.params.id
|
||||
/* 用户钱包相关信息 */
|
||||
const WALLET_INIT_DATA = {
|
||||
balance: 0,
|
||||
|
@ -97,7 +97,7 @@
|
||||
plain
|
||||
@click="handleExport"
|
||||
:loading="exportLoading"
|
||||
v-hasPermi="['system:tenant:export']"
|
||||
v-hasPermi="['pay:order:export']"
|
||||
>
|
||||
<Icon icon="ep:download" class="mr-5px" /> 导出
|
||||
</el-button>
|
||||
@ -192,6 +192,7 @@ import { dateFormatter } from '@/utils/formatTime'
|
||||
import * as OrderApi from '@/api/pay/order'
|
||||
import OrderDetail from './OrderDetail.vue'
|
||||
import download from '@/utils/download'
|
||||
import { getAppList } from '@/api/pay/app'
|
||||
|
||||
defineOptions({ name: 'PayOrder' })
|
||||
|
||||
@ -263,6 +264,7 @@ const openDetail = (id: number) => {
|
||||
/** 初始化 **/
|
||||
onMounted(async () => {
|
||||
await getList()
|
||||
appList.value = await getAppList()
|
||||
})
|
||||
</script>
|
||||
<style>
|
||||
|
@ -8,5 +8,5 @@
|
||||
<script lang="ts" setup>
|
||||
defineOptions({ name: 'GoView' })
|
||||
|
||||
const src = 'http://127.0.0.1:3000'
|
||||
const src = ref(import.meta.env.VITE_GOVIEW_URL)
|
||||
</script>
|
||||
|
1
types/env.d.ts
vendored
1
types/env.d.ts
vendored
@ -25,6 +25,7 @@ interface ImportMetaEnv {
|
||||
readonly VITE_DROP_CONSOLE: string
|
||||
readonly VITE_SOURCEMAP: string
|
||||
readonly VITE_OUT_DIR: string
|
||||
readonly VITE_GOVIEW_URL: string
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
@ -44,7 +44,8 @@ export default ({command, mode}: ConfigEnv): UserConfig => {
|
||||
preprocessorOptions: {
|
||||
scss: {
|
||||
additionalData: '@use "@/styles/variables.scss" as *;',
|
||||
javascriptEnabled: true
|
||||
javascriptEnabled: true,
|
||||
silenceDeprecations: ["legacy-js-api"], // 参考自 https://stackoverflow.com/questions/78997907/the-legacy-js-api-is-deprecated-and-will-be-removed-in-dart-sass-2-0-0
|
||||
}
|
||||
}
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user