Merge remote-tracking branch 'origin/master'

This commit is contained in:
XaoLi717 2024-11-25 15:44:54 +08:00
commit 76fea279a2
12 changed files with 470 additions and 19 deletions

View File

@ -8,6 +8,7 @@ export interface FormProcessMappingVO {
formCustomCreatePath: string // 表单的提交路径
formCustomViewPath: string // 表单的查看路径
status: number // 状态0正常 1停用
remark: string // 备注
}
// BPM 表单工作流对应 API
@ -49,4 +50,8 @@ export const FormProcessMappingApi = {
getFormCreatePath: async (key: string) => {
return await request.get({ url: `/bpm/form-process-mapping/get-form-create-path?processKey=` + key })
},
// 通过流程的formCustomCreatePath得到key
selectProcessKey: async (fullpath: string) => {
return await request.get({ url: `/bpm/form-process-mapping/get-process-key?fullpath=` + fullpath })
},
}

View File

@ -0,0 +1,48 @@
import request from '@/config/axios'
// BPM 流程实例信息 VO
export interface ProcessInstanceTodoVO {
id: number // 编号
title: string // 标题
processKey: string // 流程信息
processInstanceId: string // 流程实例id
formCustomCreatePath: string // 表单的提交路径
field1: string // 备用字段1
field2: string // 备用字段2
field3: string // 备用字段3
status: number // 状态0正常 1停用
remark: string // 备注
}
// BPM 流程实例信息 API
export const ProcessInstanceTodoApi = {
// 查询BPM 流程实例信息分页
getProcessInstanceTodoPage: async (params: any) => {
return await request.get({ url: `/bpm/process-instance-todo/page`, params })
},
// 查询BPM 流程实例信息详情
getProcessInstanceTodo: async (id: number) => {
return await request.get({ url: `/bpm/process-instance-todo/get?id=` + id })
},
// 新增BPM 流程实例信息
createProcessInstanceTodo: async (data: ProcessInstanceTodoVO) => {
return await request.post({ url: `/bpm/process-instance-todo/create`, data })
},
// 修改BPM 流程实例信息
updateProcessInstanceTodo: async (data: ProcessInstanceTodoVO) => {
return await request.put({ url: `/bpm/process-instance-todo/update`, data })
},
// 删除BPM 流程实例信息
deleteProcessInstanceTodo: async (id: number) => {
return await request.delete({ url: `/bpm/process-instance-todo/delete?id=` + id })
},
// 导出BPM 流程实例信息 Excel
exportProcessInstanceTodo: async (params) => {
return await request.download({ url: `/bpm/process-instance-todo/export-excel`, params })
}
}

View File

@ -106,7 +106,8 @@
<el-tabs type="border-card" class="demo-tabs" @tab-click="moreName">
<el-tab-pane label="待办">
<el-table v-loading="loading" :data="TodoList" height="250">
<el-table-column align="center" label="流程" prop="processInstance.name" style="width: 20%;" />
<el-table-column align="center" label="流程" prop="processInstance.name" style="width: 10%;" />
<el-table-column align="center" label="标题" prop="title" style="width: 20%;" />
<el-table-column
align="center"
label="发起人"
@ -133,7 +134,8 @@
</el-tab-pane>
<el-tab-pane label="已办" name="BpmDoneTask">
<el-table v-loading="loading" :data="DoneList" height="250">
<el-table-column align="center" label="流程" prop="processInstance.name" style="width: 20%;" />
<el-table-column align="center" label="流程" prop="processInstance.name" style="width: 10%;" />
<el-table-column align="center" label="标题" prop="title" style="width: 20%;" />
<el-table-column
align="center"
label="发起人"
@ -155,7 +157,8 @@
</el-tab-pane>
<el-tab-pane label="抄送" name="BpmProcessInstanceCopy">
<el-table v-loading="loading" :data="CopyList" height="250">
<el-table-column align="center" label="流程" prop="processInstanceName" style="width: 20%;" />
<el-table-column align="center" label="流程" prop="processInstanceName" style="width: 10%;" />
<el-table-column align="center" label="标题" prop="title" style="width: 20%;" />
<el-table-column align="center" label="发起人" prop="startUserName" style="width: 20%;" />
<el-table-column align="center" label="抄送任务" prop="taskName" style="width: 20%;" />
<el-table-column align="center" label="抄送人" prop="creatorName" style="width: 20%;" />

View File

@ -33,6 +33,9 @@
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="formData.remark" autosize type="textarea" placeholder="请输入备注" />
</el-form-item>
</el-form>
<template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
@ -67,7 +70,8 @@ const formData = ref({
processKey: undefined,
formCustomCreatePath: undefined,
formCustomViewPath: undefined,
status: 0
status: 0,
remark: undefined
})
const formRules = reactive({
name: [{ required: true, message: '映射名不能为空', trigger: 'blur' }],
@ -143,7 +147,8 @@ const resetForm = () => {
processKey: undefined,
formCustomCreatePath: undefined,
formCustomViewPath: undefined,
status: 0
status: 0,
remark: undefined
}
formRef.value?.resetFields()
}

View File

@ -83,6 +83,7 @@ import {KnowtypeApi} from "@/api/bpm/knows/knowtype";
import * as DefinitionApi from '@/api/bpm/definition'
import * as UserApi from '@/api/system/user'
import {useTagsViewStore} from "@/store/modules/tagsView";
import { FormProcessMappingApi} from '@/api/bpm/formprocessmapping'
/** 知识发布 表单 */
defineOptions({ name: 'KnowledgeCreate' })
@ -133,7 +134,7 @@ const getUserInfo = async () => {
}
//flow begin++++++++++++++++++++
//
const processDefineKey = 'pch-test-001' // Key
// const processDefineKey = '' // Key
const startUserSelectTasks = ref([]) //
const startUserSelectAssignees = ref({}) //
const startUserSelectAssigneesFormRef = ref() // Ref
@ -166,8 +167,11 @@ const submitForm = async () => {
if (startUserSelectTasks.value?.length > 0) {
data.startUserSelectAssignees = startUserSelectAssignees.value
}
if ( processDefineKey) {
data.processDefinitionKey = processDefineKey
const curFullPath = currentRoute.value.fullPath
const processKey = await FormProcessMappingApi.selectProcessKey( curFullPath )
if ( processKey) {
data.processDefinitionKey = processKey
}
await KnowledgeApi.createKnowledge(data)
message.success(t('发起成功!'))
@ -200,13 +204,21 @@ const getKnowtypeTree = async () => {
root.children = handleTree(data, 'id', 'parentId')
knowtypeTree.value.push(root)
}
/** 初始化 */
onMounted(async () => {
await getUserInfo()
await getKnowtypeTree()
const curFullPath = currentRoute.value.fullPath
const processKey = await FormProcessMappingApi.selectProcessKey( curFullPath )
if ( !processKey ) {
message.error('流程对应表单模型未配置,请检查!')
return
}
const processDefinitionDetail = await DefinitionApi.getProcessDefinition(
undefined,
processDefineKey
processKey
)
if (!processDefinitionDetail) {
message.error('OA 请假的流程模型未配置,请检查!')
@ -214,8 +226,8 @@ onMounted(async () => {
}
startUserSelectTasks.value = processDefinitionDetail.startUserSelectTasks
console.log(startUserSelectTasks.value?.length ,"length")
console.log(startUserSelectTasks.value ,"startUserSelectTasks.value")
//console.log(startUserSelectTasks.value?.length ,"length")
//console.log(startUserSelectTasks.value ,"startUserSelectTasks.value")
//
if (startUserSelectTasks.value?.length > 0) {
//

View File

@ -175,6 +175,7 @@ const tasks = ref<any[]>([]) // 任务列表
// ========== ==========
const runningTasks = ref<any[]>([]) //
const auditForms = ref<any[]>([]) //
const handleClick = (tab: TabsPaneContext) => {
if (tab.props.name==="flowChart"){
getProcessInstance()
@ -232,6 +233,7 @@ const handleAudit = async (task, pass) => {
await formCreateApi.validate()
data.variables = approveForms.value[index].value
}
await TaskApi.approveTask(data)
message.success('审批通过成功')
} else {
@ -307,7 +309,6 @@ const getProcessInstance = async () => {
//console.log(data.processDefinition.formCustomViewPath,"formCustomViewPath")
if ( data.processDefinition.formCustomViewPath == "") {
const process_key = data.processDefinition.key
//console.log(process_key,"process_key")
const formCustomViewPath = await FormProcessMappingApi.getFormViewPath(process_key)
BusinessFormComponent.value = registerComponent(formCustomViewPath)
} else {

View File

@ -1,6 +1,4 @@
<template>
<doc-alert title="流程发起、取消、重新发起" url="https://doc.iocoder.cn/bpm/process-instance/" />
<ContentWrap>
<!-- 搜索工作栏 -->
<el-form
@ -88,6 +86,7 @@
<ContentWrap>
<el-table v-loading="loading" :data="list">
<el-table-column label="流程名称" align="center" prop="name" min-width="200px" fixed="left" />
<el-table-column label="标题" align="center" prop="title" min-width="200px" fixed="left" />
<el-table-column
label="流程分类"
align="center"
@ -114,11 +113,11 @@
width="180"
:formatter="dateFormatter"
/>
<el-table-column align="center" label="耗时" prop="durationInMillis" width="160">
<template #default="scope">
{{ scope.row.durationInMillis > 0 ? formatPast2(scope.row.durationInMillis) : '-' }}
</template>
</el-table-column>
<!-- <el-table-column align="center" label="耗时" prop="durationInMillis" width="160">-->
<!-- <template #default="scope">-->
<!-- {{ scope.row.durationInMillis > 0 ? formatPast2(scope.row.durationInMillis) : '-' }}-->
<!-- </template>-->
<!-- </el-table-column>-->
<el-table-column label="当前审批任务" align="center" prop="tasks" min-width="120px">
<template #default="scope">
<el-button type="primary" v-for="task in scope.row.tasks" :key="task.id" link>

View File

@ -0,0 +1,145 @@
<template>
<Dialog :title="dialogTitle" v-model="dialogVisible">
<el-form
ref="formRef"
:model="formData"
:rules="formRules"
label-width="100px"
v-loading="formLoading"
>
<el-form-item label="标题" prop="title">
<el-input v-model="formData.title" placeholder="请输入标题" />
</el-form-item>
<el-form-item label="流程KEY" prop="processKey">
<el-input v-model="formData.processKey" placeholder="请输入流程信息" />
</el-form-item>
<el-form-item label="流程实例id" prop="processInstanceId">
<el-input v-model="formData.processInstanceId" placeholder="请输入流程实例id" />
</el-form-item>
<el-form-item label="提交路径" prop="formCustomCreatePath">
<el-input v-model="formData.formCustomCreatePath" placeholder="请输入表单的提交路径" />
</el-form-item>
<!-- <el-form-item label="备用字段1" prop="field1">-->
<!-- <el-input v-model="formData.field1" placeholder="请输入备用字段1" />-->
<!-- </el-form-item>-->
<!-- <el-form-item label="备用字段2" prop="field2">-->
<!-- <el-input v-model="formData.field2" placeholder="请输入备用字段2" />-->
<!-- </el-form-item>-->
<!-- <el-form-item label="备用字段3" prop="field3">-->
<!-- <el-input v-model="formData.field3" placeholder="请输入备用字段3" />-->
<!-- </el-form-item>-->
<el-form-item label="状态" prop="status">
<el-radio-group v-model="formData.status">
<el-radio
v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
:key="dict.value"
:label="dict.value"
>
{{ dict.label }}
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="formData.remark" placeholder="请输入备注" />
</el-form-item>
</el-form>
<template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
import { ProcessInstanceTodoApi, ProcessInstanceTodoVO } from '@/api/bpm/processinstancetodo'
/** BPM 流程实例信息 表单 */
defineOptions({ name: 'ProcessInstanceTodoForm' })
const { t } = useI18n() //
const message = useMessage() //
const dialogVisible = ref(false) //
const dialogTitle = ref('') //
const formLoading = ref(false) // 12
const formType = ref('') // create - update -
const formData = ref({
id: undefined,
title: undefined,
processKey: undefined,
processInstanceId: undefined,
formCustomCreatePath: undefined,
field1: undefined,
field2: undefined,
field3: undefined,
status: 0,
remark: undefined
})
const formRules = reactive({
title: [{ required: true, message: '标题不能为空', trigger: 'blur' }],
processKey: [{ required: true, message: '流程信息不能为空', trigger: 'blur' }],
processInstanceId: [{ required: true, message: '流程实例id不能为空', trigger: 'blur' }],
formCustomCreatePath: [{ required: true, message: '表单的提交路径不能为空', trigger: 'blur' }],
status: [{ required: true, message: '状态0正常 1停用不能为空', trigger: 'blur' }]
})
const formRef = ref() // Ref
/** 打开弹窗 */
const open = async (type: string, id?: number) => {
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
resetForm()
//
if (id) {
formLoading.value = true
try {
formData.value = await ProcessInstanceTodoApi.getProcessInstanceTodo(id)
} finally {
formLoading.value = false
}
}
}
defineExpose({ open }) // open
/** 提交表单 */
const emit = defineEmits(['success']) // success
const submitForm = async () => {
//
await formRef.value.validate()
//
formLoading.value = true
try {
const data = formData.value as unknown as ProcessInstanceTodoVO
if (formType.value === 'create') {
await ProcessInstanceTodoApi.createProcessInstanceTodo(data)
message.success(t('common.createSuccess'))
} else {
await ProcessInstanceTodoApi.updateProcessInstanceTodo(data)
message.success(t('common.updateSuccess'))
}
dialogVisible.value = false
//
emit('success')
} finally {
formLoading.value = false
}
}
/** 重置表单 */
const resetForm = () => {
formData.value = {
id: undefined,
title: undefined,
processKey: undefined,
processInstanceId: undefined,
formCustomCreatePath: undefined,
field1: undefined,
field2: undefined,
field3: undefined,
status: 0,
remark: undefined
}
formRef.value?.resetFields()
}
</script>

View File

@ -0,0 +1,230 @@
<template>
<ContentWrap>
<!-- 搜索工作栏 -->
<el-form
class="-mb-15px"
:model="queryParams"
ref="queryFormRef"
:inline="true"
label-width="68px"
>
<el-form-item label="标题" prop="title">
<el-input
v-model="queryParams.title"
placeholder="请输入标题"
clearable
@keyup.enter="handleQuery"
class="!w-240px"
/>
</el-form-item>
<el-form-item label="流程KEY" prop="processKey">
<el-input
v-model="queryParams.processKey"
placeholder="请输入流程KEY"
clearable
@keyup.enter="handleQuery"
class="!w-240px"
/>
</el-form-item>
<el-form-item label="流程id" prop="processInstanceId">
<el-input
v-model="queryParams.processInstanceId"
placeholder="请输入流程实例id"
clearable
@keyup.enter="handleQuery"
class="!w-240px"
/>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select
v-model="queryParams.status"
placeholder="请选择状态"
clearable
class="!w-240px"
>
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
<el-button
type="primary"
plain
@click="openForm('create')"
v-hasPermi="['bpm:process-instance-todo:create']"
>
<Icon icon="ep:plus" class="mr-5px" /> 新增
</el-button>
<el-button
type="success"
plain
@click="handleExport"
:loading="exportLoading"
v-hasPermi="['bpm:process-instance-todo:export']"
>
<Icon icon="ep:download" class="mr-5px" /> 导出
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
<!-- 列表 -->
<ContentWrap>
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
<el-table-column label="编号" align="center" prop="id" />
<el-table-column label="标题" align="center" prop="title" />
<el-table-column label="流程KEY" align="center" prop="processKey" />
<el-table-column label="流程实例id" align="center" prop="processInstanceId" />
<el-table-column label="表单的提交路径" align="center" prop="formCustomCreatePath" />
<!-- <el-table-column label="备用字段1" align="center" prop="field1" />-->
<!-- <el-table-column label="备用字段2" align="center" prop="field2" />-->
<!-- <el-table-column label="备用字段3" align="center" prop="field3" />-->
<el-table-column label="状态" align="center" prop="status">
<template #default="scope">
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
</template>
</el-table-column>
<el-table-column label="备注" align="center" prop="remark" />
<el-table-column
label="创建时间"
align="center"
prop="createTime"
:formatter="dateFormatter"
width="180px"
/>
<el-table-column label="操作" align="center">
<template #default="scope">
<el-button
link
type="primary"
@click="openForm('update', scope.row.id)"
v-hasPermi="['bpm:process-instance-todo:update']"
>
编辑
</el-button>
<el-button
link
type="danger"
@click="handleDelete(scope.row.id)"
v-hasPermi="['bpm:process-instance-todo:delete']"
>
删除
</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<Pagination
:total="total"
v-model:page="queryParams.pageNo"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
</ContentWrap>
<!-- 表单弹窗添加/修改 -->
<ProcessInstanceTodoForm ref="formRef" @success="getList" />
</template>
<script setup lang="ts">
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
import { dateFormatter } from '@/utils/formatTime'
import download from '@/utils/download'
import { ProcessInstanceTodoApi, ProcessInstanceTodoVO } from '@/api/bpm/processinstancetodo'
import ProcessInstanceTodoForm from './ProcessInstanceTodoForm.vue'
/** BPM 流程实例信息 列表 */
defineOptions({ name: 'ProcessInstanceTodo' })
const message = useMessage() //
const { t } = useI18n() //
const loading = ref(true) //
const list = ref<ProcessInstanceTodoVO[]>([]) //
const total = ref(0) //
const queryParams = reactive({
pageNo: 1,
pageSize: 10,
title: undefined,
processKey: undefined,
processInstanceId: undefined,
formCustomCreatePath: undefined,
field1: undefined,
field2: undefined,
field3: undefined,
status: undefined,
remark: undefined,
createTime: []
})
const queryFormRef = ref() //
const exportLoading = ref(false) //
/** 查询列表 */
const getList = async () => {
loading.value = true
try {
const data = await ProcessInstanceTodoApi.getProcessInstanceTodoPage(queryParams)
list.value = data.list
total.value = data.total
} finally {
loading.value = false
}
}
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.pageNo = 1
getList()
}
/** 重置按钮操作 */
const resetQuery = () => {
queryFormRef.value.resetFields()
handleQuery()
}
/** 添加/修改操作 */
const formRef = ref()
const openForm = (type: string, id?: number) => {
formRef.value.open(type, id)
}
/** 删除按钮操作 */
const handleDelete = async (id: number) => {
try {
//
await message.delConfirm()
//
await ProcessInstanceTodoApi.deleteProcessInstanceTodo(id)
message.success(t('common.delSuccess'))
//
await getList()
} catch {}
}
/** 导出按钮操作 */
const handleExport = async () => {
try {
//
await message.exportConfirm()
//
exportLoading.value = true
const data = await ProcessInstanceTodoApi.exportProcessInstanceTodo(queryParams)
download.excel(data, 'BPM 流程实例信息.xls')
} catch {
} finally {
exportLoading.value = false
}
}
/** 初始化 **/
onMounted(() => {
getList()
})
</script>

View File

@ -44,6 +44,7 @@
<ContentWrap>
<el-table v-loading="loading" :data="list">
<el-table-column align="center" label="流程名" prop="processInstanceName" min-width="180" />
<el-table-column align="center" label="标题" prop="title" min-width="180" />
<el-table-column align="center" label="流程发起人" prop="startUserName" min-width="100" />
<el-table-column
:formatter="dateFormatter"

View File

@ -53,6 +53,7 @@
<ContentWrap>
<el-table v-loading="loading" :data="list">
<el-table-column align="center" label="流程" prop="processInstance.name" width="180" />
<el-table-column align="center" label="标题" prop="title" width="180" />
<el-table-column
align="center"
label="发起人"

View File

@ -53,6 +53,7 @@
<ContentWrap>
<el-table v-loading="loading" :data="list">
<el-table-column align="center" label="流程" prop="processInstance.name" width="180" />
<el-table-column align="center" label="标题" prop="title" width="180" />
<el-table-column
align="center"
label="发起人"