Compare commits

..

No commits in common. "ecfe1b6145c32c4396835d3720ff3992b14610b9" and "3e826776f466b5e932fca6c55f584f03aaf5c804" have entirely different histories.

37 changed files with 789 additions and 1721 deletions

View File

@ -32,6 +32,3 @@ VITE_MALL_H5_DOMAIN='http://mall.yudao.iocoder.cn'
# 验证码的开关
VITE_APP_CAPTCHA_ENABLE=true
# GoView域名
VITE_GOVIEW_URL='http://127.0.0.1:3000'

View File

@ -29,6 +29,3 @@ VITE_MALL_H5_DOMAIN='http://localhost:3000'
# 验证码的开关
VITE_APP_CAPTCHA_ENABLE=false
# GoView域名
VITE_GOVIEW_URL='http://127.0.0.1:3000'

View File

@ -29,6 +29,3 @@ 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'

View File

@ -29,6 +29,3 @@ 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'

View File

@ -29,6 +29,3 @@ 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'

View File

@ -71,7 +71,7 @@
"vue": "3.5.12",
"vue-dompurify-html": "^4.1.4",
"vue-i18n": "9.10.2",
"vue-router": "4.4.5",
"vue-router": "^4.3.0",
"vue-types": "^5.1.1",
"vuedraggable": "^4.1.0",
"web-storage-cache": "^1.1.1",

File diff suppressed because it is too large Load Diff

View File

@ -15,6 +15,7 @@ import {
AssignStartUserHandlerType,
AssignEmptyHandlerType,
FieldPermissionType,
ProcessVariableEnum
} from './consts'
import { parseFormFields } from '@/components/FormCreate/src/utils/index'
export function useWatchNode(props: { flowNode: SimpleFlowNode }): Ref<SimpleFlowNode> {
@ -36,6 +37,13 @@ const parseFormCreateFields = (formFields?: string[]) => {
parseFormFields(JSON.parse(fieldStr), result)
})
}
// 固定添加发起人 ID 字段
result.unshift({
field: ProcessVariableEnum.START_USER_ID,
title: '发起人',
type: 'UserSelect',
required: true
})
return result
}

View File

@ -26,13 +26,19 @@
</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"
@ -102,11 +108,10 @@
<div class="mr-2">
<el-select style="width: 160px" v-model="rule.leftSide">
<el-option
v-for="(item, index) in fieldOptions"
v-for="(item, index) in fieldsInfo"
:key="index"
:label="item.title"
:value="item.field"
:disabled="!item.required"
/>
</el-select>
</div>
@ -160,12 +165,10 @@ import {
COMPARISON_OPERATORS,
ConditionGroup,
Condition,
ConditionRule,
ProcessVariableEnum
ConditionRule
} from '../consts'
import { getDefaultConditionNodeName } from '../utils'
import { useFormFields } from '../node'
import { BpmModelFormType } from '@/utils/constants'
const message = useMessage() //
defineOptions({
name: 'ConditionNodeConfig'
@ -174,8 +177,8 @@ const formType = inject<Ref<number>>('formType') // 表单类型
const conditionConfigTypes = computed(() => {
return CONDITION_CONFIG_TYPES.filter((item) => {
//
if (formType?.value === BpmModelFormType.CUSTOM && item.value === ConditionType.RULE) {
return false
if (formType?.value !== 10) {
return item.value === ConditionType.RULE
} else {
return true
}
@ -365,29 +368,16 @@ 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: any) => item.value === opCode)
const opName = COMPARISON_OPERATORS.find((item) => item.value === opCode)
return opName?.label
}
</script>

View File

@ -469,8 +469,7 @@ import {
TimeoutHandlerType,
ASSIGN_EMPTY_HANDLER_TYPES,
AssignEmptyHandlerType,
FieldPermissionType,
ProcessVariableEnum
FieldPermissionType
} from '../consts'
import {
@ -520,13 +519,6 @@ 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')
})
// ,

View File

@ -406,31 +406,6 @@
"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"
}
]
},

View File

@ -165,12 +165,6 @@ 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',

View File

@ -56,7 +56,6 @@ export default {
'Create EndEvent': '创建结束事件',
'Create Task': '创建任务',
'Create User Task': '创建用户任务',
'Create Call Activity': '创建调用活动',
'Create Service Task': '创建服务任务',
'Create Gateway': '创建网关',
'Create DataObjectReference': '创建数据对象',

View File

@ -27,9 +27,7 @@
<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
@ -37,12 +35,8 @@
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>
@ -62,11 +56,7 @@
</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>
@ -82,7 +72,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' })

View File

@ -2,7 +2,6 @@ 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: {
@ -20,10 +19,6 @@ export const installedComponent = {
ReceiveTask: {
name: '接收任务',
component: ReceiveTask
},
CallActivity: {
name: '调用活动',
component: CallActivity
}
}

View File

@ -1,280 +0,0 @@
<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>

View File

@ -178,17 +178,12 @@
type="textarea"
v-model="userTaskForm.candidateParam[0]"
clearable
style="width: 100%"
style="width: 72%"
@change="updateElementTask"
/>
<XButton
class="!w-1/1 mt-5px"
type="success"
preIcon="ep:select"
title="选择表达式"
size="small"
@click="openProcessExpressionDialog"
/>
<el-button class="ml-5px" size="small" type="success" @click="openProcessExpressionDialog"
>选择表达式</el-button
>
<!-- 选择弹窗 -->
<ProcessExpressionDialog ref="processExpressionDialogRef" @select="selectProcessExpression" />
</el-form-item>

View File

@ -44,7 +44,8 @@ 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)
}
})

View File

@ -51,10 +51,7 @@ import {
ElMenu,
ElMenuItem,
ElFooter,
ElMessage,
ElCollapse,
ElCollapseItem,
ElCard,
ElMessage
// ElFormItem,
// ElOption
} from 'element-plus'
@ -116,10 +113,7 @@ const components = [
UserSelect,
DeptSelect,
ApiSelect,
Editor,
ElCollapse,
ElCollapseItem,
ElCard,
Editor
]
// 参考 http://www.form-create.com/v3/element-ui/auto-import.html 文档

View File

@ -120,7 +120,7 @@ export const generateRoute = (routes: AppCustomRouteRecordRaw[]): AppRouteRecord
data.children = [childrenData]
} else {
// 目录
if (route.children?.length) {
if (route.children) {
data.component = Layout
data.redirect = getRedirect(route.path, route.children)
// 外链

View File

@ -376,9 +376,6 @@ 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}`

View File

@ -8,8 +8,8 @@
<!-- 中间主要内容 tab -->
<el-tabs v-model="activeTab">
<!-- 表单信息 -->
<el-tab-pane label="表单填写" name="form" >
<div class="form-scroll-area" v-loading="processInstanceStartLoading">
<el-tab-pane label="表单填写" name="form">
<div class="form-scroll-area">
<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,8 +179,6 @@ const submitForm = async () => {
if (!fApi.value || !props.selectProcessDefinition) {
return
}
//
await fApi.value.validate()
//
if (startUserSelectTasks.value?.length > 0) {
for (const userTask of startUserSelectTasks.value) {
@ -193,7 +191,7 @@ const submitForm = async () => {
}
//
processInstanceStartLoading.value = true
fApi.value.btn.loading(true)
try {
await ProcessInstanceApi.createProcessInstance({
processDefinitionId: props.selectProcessDefinition.id,
@ -208,7 +206,7 @@ const submitForm = async () => {
name: 'BpmProcessInstanceMy'
})
} finally {
processInstanceStartLoading.value = false
fApi.value.btn.loading(false)
}
}

View File

@ -20,9 +20,9 @@
<el-form
label-position="top"
class="mb-auto"
ref="approveFormRef"
:model="approveReasonForm"
:rules="approveReasonRule"
ref="formRef"
:model="genericForm"
:rules="genericRule"
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="approveReasonForm.reason"
v-model="genericForm.reason"
placeholder="请输入审批意见"
type="textarea"
:rows="4"
/>
</el-form-item>
<el-form-item>
<el-button :disabled="formLoading" type="success" @click="handleAudit(true, approveFormRef)">
<el-button :disabled="formLoading" type="success" @click="handleAudit(true)">
{{ getButtonDisplayName(OperationButtonType.APPROVE) }}
</el-button>
<el-button @click="closePropover('approve', approveFormRef)"> 取消 </el-button>
<el-button @click="popOverVisible.approve = false"> 取消 </el-button>
</el-form-item>
</el-form>
</div>
@ -72,24 +72,24 @@
<el-form
label-position="top"
class="mb-auto"
ref="rejectFormRef"
:model="rejectReasonForm"
:rules="rejectReasonRule"
ref="formRef"
:model="genericForm"
:rules="genericRule"
label-width="100px"
>
<el-form-item label="审批意见" prop="reason">
<el-input
v-model="rejectReasonForm.reason"
v-model="genericForm.reason"
placeholder="请输入审批意见"
type="textarea"
:rows="4"
/>
</el-form-item>
<el-form-item>
<el-button :disabled="formLoading" type="danger" @click="handleAudit(false,rejectFormRef)">
<el-button :disabled="formLoading" type="danger" @click="handleAudit(false)">
{{ getButtonDisplayName(OperationButtonType.REJECT) }}
</el-button>
<el-button @click="closePropover('reject', rejectFormRef)"> 取消 </el-button>
<el-button @click="popOverVisible.reject = false"> 取消 </el-button>
</el-form-item>
</el-form>
</div>
@ -113,14 +113,14 @@
<el-form
label-position="top"
class="mb-auto"
ref="copyFormRef"
:model="copyForm"
:rules="copyFormRule"
ref="formRef"
:model="genericForm"
:rules="genericRule"
label-width="100px"
>
<el-form-item label="抄送人" prop="copyUserIds">
<el-select
v-model="copyForm.copyUserIds"
v-model="genericForm.copyUserIds"
clearable
style="width: 100%"
multiple
@ -136,7 +136,7 @@
</el-form-item>
<el-form-item label="抄送意见" prop="copyReason">
<el-input
v-model="copyForm.copyReason"
v-model="genericForm.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="closePropover('copy', copyFormRef)"> 取消 </el-button>
<el-button @click="popOverVisible.copy = false"> 取消 </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="transferFormRef"
:model="transferForm"
:rules="transferFormRule"
ref="formRef"
:model="genericForm"
:rules="genericRule"
label-width="100px"
>
<el-form-item label="新审批人" prop="assigneeUserId">
<el-select v-model="transferForm.assigneeUserId" clearable style="width: 100%">
<el-select v-model="genericForm.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="transferForm.reason"
v-model="genericForm.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="closePropover('transfer', transferFormRef)"> 取消 </el-button>
<el-button @click="popOverVisible.transfer = false"> 取消 </el-button>
</el-form-item>
</el-form>
</div>
@ -223,13 +223,13 @@
<el-form
label-position="top"
class="mb-auto"
ref="delegateFormRef"
:model="delegateForm"
:rules="delegateFormRule"
ref="formRef"
:model="genericForm"
:rules="genericRule"
label-width="100px"
>
<el-form-item label="接收人" prop="delegateUserId">
<el-select v-model="delegateForm.delegateUserId" clearable style="width: 100%">
<el-select v-model="genericForm.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="delegateForm.reason"
v-model="genericForm.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="closePropover('delegate', delegateFormRef)"> 取消 </el-button>
<el-button @click="popOverVisible.delegate = false"> 取消 </el-button>
</el-form-item>
</el-form>
</div>
@ -275,13 +275,13 @@
<el-form
label-position="top"
class="mb-auto"
ref="addSignFormRef"
:model="addSignForm"
:rules="addSignFormRule"
ref="formRef"
:model="genericForm"
:rules="genericRule"
label-width="100px"
>
<el-form-item label="加签处理人" prop="addSignUserIds">
<el-select v-model="addSignForm.addSignUserIds" multiple clearable style="width: 100%">
<el-select v-model="genericForm.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="addSignForm.reason"
v-model="genericForm.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="closePropover('addSign', addSignFormRef)"> 取消 </el-button>
<el-button @click="popOverVisible.addSign = false"> 取消 </el-button>
</el-form-item>
</el-form>
</div>
@ -329,13 +329,13 @@
<el-form
label-position="top"
class="mb-auto"
ref="deleteSignFormRef"
:model="deleteSignForm"
:rules="deleteSignFormRule"
ref="formRef"
:model="genericForm"
:rules="genericRule"
label-width="100px"
>
<el-form-item label="减签人员" prop="deleteSignTaskId">
<el-select v-model="deleteSignForm.deleteSignTaskId" clearable style="width: 100%">
<el-select v-model="genericForm.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="deleteSignForm.reason"
v-model="genericForm.reason"
clearable
placeholder="请输入审批意见"
type="textarea"
@ -357,7 +357,7 @@
<el-button :disabled="formLoading" type="primary" @click="handlerDeleteSign()">
减签
</el-button>
<el-button @click="closePropover('deleteSign', deleteSignFormRef)"> 取消 </el-button>
<el-button @click="popOverVisible.deleteSign = false"> 取消 </el-button>
</el-form-item>
</el-form>
</div>
@ -372,7 +372,7 @@
v-if="runningTask && isHandleTaskStatus() && isShowButton(OperationButtonType.RETURN)"
>
<template #reference>
<div @click="openPopover('return')" class="hover-bg-gray-100 rounded-xl p-6px">
<div @click="openReturnPopover" class="hover-bg-gray-100 rounded-xl p-6px">
<Icon :size="14" icon="ep:back" />&nbsp;
{{ getButtonDisplayName(OperationButtonType.RETURN) }}
</div>
@ -381,13 +381,13 @@
<el-form
label-position="top"
class="mb-auto"
ref="returnFormRef"
:model="returnForm"
:rules="returnFormRule"
ref="formRef"
:model="genericForm"
:rules="genericRule"
label-width="100px"
>
<el-form-item label="退回节点" prop="targetTaskDefinitionKey">
<el-select v-model="returnForm.targetTaskDefinitionKey" clearable style="width: 100%">
<el-select v-model="genericForm.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="returnForm.returnReason"
v-model="genericForm.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="closePropover('return', returnFormRef)"> 取消 </el-button>
<el-button @click="popOverVisible.return = false"> 取消 </el-button>
</el-form-item>
</el-form>
</div>
@ -434,15 +434,15 @@
<el-form
label-position="top"
class="mb-auto"
ref="cancelFormRef"
:model="cancelForm"
:rules="cancelFormRule"
ref="formRef"
:model="genericForm"
:rules="genericRule"
label-width="100px"
>
<el-form-item label="取消理由" prop="cancelReason">
<span class="text-#878c93 text-12px">&nbsp; 取消后该审批流程将自动结束</span>
<el-input
v-model="cancelForm.cancelReason"
v-model="genericForm.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="closePropover('cancel', cancelFormRef)"> 取消 </el-button>
<el-button @click="popOverVisible.cancel = false"> 取消 </el-button>
</el-form-item>
</el-form>
</div>
@ -477,29 +477,26 @@ 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 * as UserApi from '@/api/system/user'
import { propTypes } from '@/utils/propTypes'
import {
OperationButtonType,
OPERATION_BUTTON_NAME
} from '@/components/SimpleProcessDesignerV2/src/consts'
import { BpmProcessInstanceStatus, BpmModelFormType } from '@/utils/constants'
import type { FormInstance, FormRules } from 'element-plus'
import { BpmProcessInstanceStatus } from '@/utils/constants'
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: any, //
processDefinition: any, //
userOptions: UserApi.UserVO[],
normalForm: any, // formCreate
normalFormApi: any, // formCreate Api
writableFields: string[] //
}>()
const props = defineProps({
processInstance: propTypes.object, //
processDefinition: propTypes.object, //
userOptions: propTypes.any
})
const formLoading = ref(false) //
const popOverVisible = ref({
@ -517,99 +514,21 @@ const returnList = ref([] as any) // 退回节点
// ========== ==========
const runningTask = ref<any>() //
const genericForm = ref<any>({}) //
const approveForm = ref<any>({}) //
const approveFormFApi = ref<any>({}) // approveForms fAPi
//
const approveFormRef = ref<FormInstance>()
const approveReasonForm = reactive({
reason: ''
})
const approveReasonRule = reactive<FormRules<typeof approveReasonForm>>({
const formRef = ref()
const genericRule = reactive({
reason: [{ required: true, message: '审批意见不能为空', trigger: 'blur' }],
})
//
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' }],
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>>({
returnReason: [{ required: true, message: '退回理由不能为空', trigger: 'blur' }],
cancelReason: [{ required: true, message: '取消理由不能为空', trigger: 'blur' }],
})
copyUserIds: [{ required: true, message: '抄送人不能为空', trigger: 'change' }],
assigneeUserId: [{ required: true, message: '新审批人不能为空', trigger: 'change' }],
delegateUserId: [{ required: true, message: '接收人不能为空', trigger: 'change' }],
addSignUserIds: [{ required: true, message: '加签处理人不能为空', trigger: 'change' }],
deleteSignTaskId: [{ required: true, message: '减签人员不能为空', trigger: 'change' }],
targetTaskDefinitionKey: [{ required: true, message: '退回节点不能为空', trigger: 'change' }]
}) //
/** 监听 approveFormFApis实现它对应的 form-create 初始化后,隐藏掉对应的表单提交按钮 */
watch(
@ -623,57 +542,43 @@ 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()
}
/** 关闭气泡卡 */
const closePropover = (type: string, formRef: FormInstance | undefined) => {
if (formRef) {
formRef.resetFields()
}
popOverVisible.value[type] = false
await nextTick()
formRef.value.resetFields()
}
/** 处理审批通过和不通过的操作 */
const handleAudit = async (pass: boolean, formRef: FormInstance | undefined) => {
const handleAudit = async (pass: boolean) => {
formLoading.value = true
try {
//
if (!formRef) return
await formRef.validate()
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 (pass) {
// ,
const variables = getUpdatedProcessInstanceVaiables();
//
const data = {
id: runningTask.value.id,
reason: approveReasonForm.reason,
variables // ,
}
// approveForm + data
// TODO
// approveForm + data
const formCreateApi = approveFormFApi.value
if (Object.keys(formCreateApi)?.length > 0) {
await formCreateApi.validate()
@ -684,18 +589,11 @@ const handleAudit = async (pass: boolean, formRef: FormInstance | undefined) =>
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('审批不通过成功')
}
//
formRef.resetFields()
//
// 2.2
reload()
} finally {
formLoading.value = false
@ -706,17 +604,19 @@ const handleAudit = async (pass: boolean, formRef: FormInstance | undefined) =>
const handleCopy = async () => {
formLoading.value = true
try {
const copyFormRef = proxy.$refs['formRef']
// 1.
if (!copyFormRef.value) return
await copyFormRef.value.validate()
const elForm = unref(copyFormRef)
if (!elForm) return
const valid = await elForm.validate()
if (!valid) return
// 2.
const data = {
id: runningTask.value.id,
reason: copyForm.copyReason,
copyUserIds:copyForm.copyUserIds
reason: genericForm.value.copyReason,
copyUserIds: genericForm.value.copyUserIds
}
await TaskApi.copyTask(data)
copyFormRef.value.resetFields()
popOverVisible.value.copy = false
message.success('操作成功')
} finally {
@ -728,17 +628,20 @@ const handleCopy = async () => {
const handleTransfer = async () => {
formLoading.value = true
try {
const transferFormRef = proxy.$refs['formRef']
// 1.1
if (!transferFormRef.value) return
await transferFormRef.value.validate()
const elForm = unref(transferFormRef)
if (!elForm) return
const valid = await elForm.validate()
if (!valid) return
// 1.2
const data = {
id: runningTask.value.id,
reason: transferForm.reason,
assigneeUserId: transferForm.assigneeUserId
reason: genericForm.value.reason,
assigneeUserId: genericForm.value.assigneeUserId
}
await TaskApi.transferTask(data)
transferFormRef.value.resetFields()
popOverVisible.value.transfer = false
message.success('操作成功')
// 2.
@ -752,20 +655,21 @@ const handleTransfer = async () => {
const handleDelegate = async () => {
formLoading.value = true
try {
const deletegateFormRef = proxy.$refs['formRef']
// 1.1
if (!delegateFormRef.value) return
await delegateFormRef.value.validate()
const elForm = unref(deletegateFormRef)
if (!elForm) return
const valid = await elForm.validate()
if (!valid) return
// 1.2
const data = {
id: runningTask.value.id,
reason: delegateForm.reason,
delegateUserId: delegateForm.delegateUserId
reason: genericForm.value.reason,
delegateUserId: genericForm.value.delegateUserId
}
await TaskApi.delegateTask(data)
popOverVisible.value.delegate = false
delegateFormRef.value.resetFields()
message.success('操作成功')
// 2.
reload()
@ -778,19 +682,21 @@ const handleDelegate = async () => {
const handlerAddSign = async (type: string) => {
formLoading.value = true
try {
const transferFormRef = proxy.$refs['formRef']
// 1.1
if (!addSignFormRef.value) return
await addSignFormRef.value.validate()
const elForm = unref(transferFormRef)
if (!elForm) return
const valid = await elForm.validate()
if (!valid) return
// 1.2
const data = {
id: runningTask.value.id,
type,
reason: addSignForm.reason,
userIds: addSignForm.addSignUserIds
reason: genericForm.value.reason,
userIds: genericForm.value.addSignUserIds
}
await TaskApi.signCreateTask(data)
message.success('操作成功')
addSignFormRef.value.resetFields()
popOverVisible.value.addSign = false
// 2
reload()
@ -803,19 +709,21 @@ const handlerAddSign = async (type: string) => {
const handleReturn = async () => {
formLoading.value = true
try {
const returnFormRef = proxy.$refs['formRef']
// 1.1
if (!returnFormRef.value) return
await returnFormRef.value.validate()
const elForm = unref(returnFormRef)
if (!elForm) return
const valid = await elForm.validate()
if (!valid) return
// 1.2 退
const data = {
id: runningTask.value.id,
reason: returnForm.returnReason,
targetTaskDefinitionKey: returnForm.targetTaskDefinitionKey
reason: genericForm.value.returnReason,
targetTaskDefinitionKey: genericForm.value.targetTaskDefinitionKey
}
await TaskApi.returnTask(data)
popOverVisible.value.return = false
returnFormRef.value.resetFields()
message.success('操作成功')
// 2
reload()
@ -828,17 +736,19 @@ const handleReturn = async () => {
const handleCancel = async () => {
formLoading.value = true
try {
const cancelFormRef = proxy.$refs['formRef']
// 1.1
if (!cancelFormRef.value) return
await cancelFormRef.value.validate()
const elForm = unref(cancelFormRef)
if (!elForm) return
const valid = await elForm.validate()
if (!valid) return
// 1.2
await ProcessInstanceApi.cancelProcessInstanceByStartUser(
props.processInstance.id,
cancelForm.cancelReason
genericForm.value.cancelReason
)
popOverVisible.value.return = false
message.success('操作成功')
cancelFormRef.value.resetFields()
// 2
reload()
} finally {
@ -865,17 +775,19 @@ const getDeleteSignUserLabel = (task: any): string => {
const handlerDeleteSign = async () => {
formLoading.value = true
try {
const deleteFormRef = proxy.$refs['formRef']
// 1.1
if (!deleteSignFormRef.value) return
await deleteSignFormRef.value.validate()
const elForm = unref(deleteFormRef)
if (!elForm) return
const valid = await elForm.validate()
if (!valid) return
// 1.2
const data = {
id: deleteSignForm.deleteSignTaskId,
reason: deleteSignForm.reason
id: genericForm.value.deleteSignTaskId,
reason: genericForm.value.reason
}
await TaskApi.signDeleteTask(data)
message.success('减签成功')
deleteSignFormRef.value.resetFields()
popOverVisible.value.deleteSign = false
// 2
reload()
@ -929,6 +841,7 @@ const getButtonDisplayName = (btnType: OperationButtonType) => {
}
const loadTodoTask = (task: any) => {
genericForm.value = {}
approveForm.value = {}
approveFormFApi.value = {}
runningTask.value = task
@ -942,30 +855,6 @@ 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>

View File

@ -49,7 +49,7 @@
class="form-box flex flex-col mb-30px flex-1"
>
<!-- 情况一流程表单 -->
<el-col v-if="processDefinition?.formType === BpmModelFormType.NORMAL">
<el-col v-if="processDefinition?.formType === 10">
<form-create
v-model="detailForm.value"
v-model:api="fApi"
@ -58,7 +58,7 @@
/>
</el-col>
<!-- 情况二业务表单 -->
<div v-if="processDefinition?.formType === BpmModelFormType.CUSTOM">
<div v-if="processDefinition?.formType === 20">
<BusinessFormComponent :id="processInstance.businessKey" />
</div>
</div>
@ -116,9 +116,6 @@
:process-instance="processInstance"
:process-definition="processDefinition"
:userOptions="userOptions"
:normal-form="detailForm"
:normal-form-api="fApi"
:writable-fields="writableFields"
@success="refresh"
/>
</div>
@ -129,7 +126,7 @@
<script lang="ts" setup>
import { formatDate } from '@/utils/formatTime'
import { DICT_TYPE } from '@/utils/dict'
import { BpmModelType, BpmModelFormType } from '@/utils/constants'
import { BpmModelType } from '@/utils/constants'
import { setConfAndFields2 } from '@/utils/formCreate'
import { registerComponent } from '@/utils/routerHelper'
import type { ApiAttrs } from '@form-create/element-ui/types/config'
@ -174,8 +171,6 @@ const detailForm = ref({
value: {}
}) //
const writableFields: Array<string> = [] //
/** 获得详情 */
const getDetail = () => {
getApprovalDetail()
@ -207,12 +202,11 @@ const getApprovalDetail = async () => {
processDefinition.value = data.processDefinition
//
if (processDefinition.value.formType === BpmModelFormType.NORMAL) {
if (processDefinition.value.formType === 10) {
//
const formFieldsPermission = data.formFieldsPermission
//
writableFields.splice(0)
if (detailForm.value.rule?.length > 0) {
if (detailForm.value.rule.length > 0) {
// form-create
detailForm.value.value = processInstance.value.formVariables
} else {
@ -277,8 +271,6 @@ 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
@ -322,7 +314,6 @@ $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
@ -332,6 +323,7 @@ $process-header-height: 194px;
$process-header-height - 40px
);
overflow: auto;
display: flex;
flex-direction: column;
:deep(.box-card) {

View File

@ -25,8 +25,7 @@
</el-form-item>
<!-- TODO @ tuitujistyle 可以使用 unocss -->
<el-form-item label="" prop="category" :style="{ position: 'absolute', right: '300px' }">
<!-- TODO @tuituji应该选择好分类就触发搜索啦 RE:done & to check-->
<el-form-item label="" prop="category" :style="{ position: 'absolute', right: '130px' }">
<el-select
v-model="queryParams.category"
placeholder="请选择流程分类"
@ -43,25 +42,6 @@
</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 @ tuitujistyle 可以使用 unocss -->
<el-form-item :style="{ position: 'absolute', right: '0px' }">
<el-popover
:visible="showPopover"
@ -104,6 +84,21 @@
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"
@ -115,11 +110,10 @@
class="!w-240px"
/>
</el-form-item>
<!-- TODO tuituiji参考钉钉1按照清空取消确认排序2右对齐3确认增加 primary -->
<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-button @click="showPopover = false"> 取消</el-button>
<el-button @click="handleQuery" type="primary"> 确认</el-button>
</el-form-item>
</el-popover>
</el-form-item>
@ -138,7 +132,7 @@
fixed="left"
/>
<!-- TODO @芋艿摘要 -->
<!-- TODO tuituiji参考钉钉1审批中时展示审批任务2非审批中展示状态 -->
<!-- TODO @tuituji流程状态可见需求文档里 Re:没看懂回复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" />
@ -206,7 +200,6 @@
</ContentWrap>
</template>
<script lang="ts" setup>
// TODO @tuitujiList <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'
@ -282,7 +275,7 @@ const handleCreate = async (row?: ProcessInstanceVO) => {
}
/** 查看详情 */
const handleDetail = (row: ProcessInstanceVO) => {
const handleDetail = (row: any) => {
router.push({
name: 'BpmProcessInstanceDetail',
query: {
@ -292,7 +285,7 @@ const handleDetail = (row: ProcessInstanceVO) => {
}
/** 取消按钮操作 */
const handleCancel = async (row: ProcessInstanceVO) => {
const handleCancel = async (row: any) => {
//
const { value } = await ElMessageBox.prompt('请输入取消原因', '取消流程', {
confirmButtonText: t('common.ok'),

View File

@ -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,96 +25,27 @@
@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>
@ -179,10 +110,9 @@
</ContentWrap>
</template>
<script lang="ts" setup>
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { DICT_TYPE } 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' })
@ -195,13 +125,9 @@ 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 () => {
@ -239,8 +165,7 @@ const handleAudit = (row: any) => {
}
/** 初始化 **/
onMounted(async () => {
await getList()
categoryList.value = await CategoryApi.getCategorySimpleList()
onMounted(() => {
getList()
})
</script>

View File

@ -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,79 +25,27 @@
@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>
@ -147,7 +95,6 @@
<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' })
@ -160,11 +107,9 @@ const queryParams = reactive({
pageNo: 1,
pageSize: 10,
name: '',
category: undefined,
createTime: []
})
const queryFormRef = ref() //
const categoryList = ref<CategoryVO[]>([]) //
/** 查询任务列表 */
const getList = async () => {
@ -178,8 +123,6 @@ const getList = async () => {
}
}
const showPopover = ref(false)
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.pageNo = 1
@ -204,8 +147,7 @@ const handleAudit = (row: any) => {
}
/** 初始化 **/
onMounted(async () => {
await getList()
categoryList.value = await CategoryApi.getCategorySimpleList()
onMounted(() => {
getList()
})
</script>

View File

@ -101,7 +101,7 @@
<el-input
disabled
v-model="formData.totalProductPrice"
:formatter="erpPriceInputFormatter"
:formatter="erpPriceTableColumnFormatter"
/>
</el-form-item>
</el-col>
@ -123,7 +123,7 @@
disabled
v-model="formData.totalPrice"
placeholder="请输入商机金额"
:formatter="erpPriceInputFormatter"
:formatter="erpPriceTableColumnFormatter"
/>
</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, erpPriceInputFormatter } from '@/utils'
import { erpPriceMultiply, erpPriceTableColumnFormatter } from '@/utils'
const { t } = useI18n() //
const message = useMessage() //

View File

@ -159,7 +159,7 @@
<el-input
disabled
v-model="formData.totalProductPrice"
:formatter="erpPriceInputFormatter"
:formatter="erpPriceTableColumnFormatter"
/>
</el-form-item>
</el-col>
@ -181,7 +181,7 @@
disabled
v-model="formData.totalPrice"
placeholder="请输入商机金额"
:formatter="erpPriceInputFormatter"
:formatter="erpPriceTableColumnFormattere"
/>
</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, erpPriceInputFormatter } from '@/utils'
import { erpPriceMultiply, erpPriceTableColumnFormatter } from '@/utils'
import { useUserStore } from '@/store/modules/user'
import ContractProductForm from '@/views/crm/contract/components/ContractProductForm.vue'

View File

@ -24,7 +24,7 @@ defineOptions({ name: 'CrmProductDetail' })
const route = useRoute()
const message = useMessage()
const id = route.params.id //
const id = Number(route.params.id) //
const loading = ref(true) //
const product = ref<ProductApi.ProductVO>({} as ProductApi.ProductVO) //

View File

@ -27,7 +27,7 @@ defineOptions({ name: 'IoTDeviceDetail' })
const route = useRoute()
const message = useMessage()
const id = route.params.id //
const id = Number(route.params.id) //
const loading = ref(true) //
const product = ref<ProductVO>({} as ProductVO) //
const device = ref<DeviceVO>({} as DeviceVO) //

View File

@ -33,7 +33,7 @@ const { currentRoute } = useRouter()
const route = useRoute()
const message = useMessage()
const id = route.params.id //
const id = Number(route.params.id) //
const loading = ref(true) //
const product = ref<ProductVO>({} as ProductVO) //
const activeTab = ref('info') //

View File

@ -113,7 +113,7 @@ const getUserData = async (id: number) => {
const { currentRoute } = useRouter() //
const { delView } = useTagsViewStore() //
const route = useRoute()
const id = route.params.id
const id = Number(route.params.id)
/* 用户钱包相关信息 */
const WALLET_INIT_DATA = {
balance: 0,

View File

@ -97,7 +97,7 @@
plain
@click="handleExport"
:loading="exportLoading"
v-hasPermi="['pay:order:export']"
v-hasPermi="['system:tenant:export']"
>
<Icon icon="ep:download" class="mr-5px" /> 导出
</el-button>
@ -192,7 +192,6 @@ 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' })
@ -264,7 +263,6 @@ const openDetail = (id: number) => {
/** 初始化 **/
onMounted(async () => {
await getList()
appList.value = await getAppList()
})
</script>
<style>

View File

@ -8,5 +8,5 @@
<script lang="ts" setup>
defineOptions({ name: 'GoView' })
const src = ref(import.meta.env.VITE_GOVIEW_URL)
const src = 'http://127.0.0.1:3000'
</script>

1
types/env.d.ts vendored
View File

@ -25,7 +25,6 @@ interface ImportMetaEnv {
readonly VITE_DROP_CONSOLE: string
readonly VITE_SOURCEMAP: string
readonly VITE_OUT_DIR: string
readonly VITE_GOVIEW_URL: string
}
declare global {

View File

@ -44,8 +44,7 @@ export default ({command, mode}: ConfigEnv): UserConfig => {
preprocessorOptions: {
scss: {
additionalData: '@use "@/styles/variables.scss" as *;',
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
javascriptEnabled: true
}
}
},