feat:【bpm】oa 请假:90% 发起等流程

This commit is contained in:
YunaiV
2025-12-24 20:42:14 +08:00
parent fd723685d9
commit 1eb03fe652
8 changed files with 458 additions and 310 deletions

View File

@@ -8,9 +8,9 @@ export interface Leave {
type: number
reason: string
processInstanceId: string
startTime: number
endTime: number
createTime: number
startTime: Date | any
endTime: Date | any
createTime: Date
startUserSelectAssignees?: Record<string, string[]>
}
@@ -19,11 +19,6 @@ export function createLeave(data: Partial<Leave>) {
return http.post<number>('/bpm/oa/leave/create', data)
}
/** 更新请假申请 */
export function updateLeave(data: Partial<Leave>) {
return http.put<boolean>('/bpm/oa/leave/update', data)
}
/** 获得请假申请 */
export function getLeave(id: number) {
return http.get<Leave>(`/bpm/oa/leave/get?id=${id}`)

View File

@@ -7,7 +7,6 @@
<!-- 搜索弹窗 -->
<wd-popup v-model="visible" position="top" @close="visible = false">
<view class="yd-search-form-container" :style="{ paddingTop: `${getNavbarHeight()}px` }">
<!-- 请假类型 -->
<view class="yd-search-form-item">
<view class="yd-search-form-label">
请假类型
@@ -21,7 +20,6 @@
</wd-radio>
</wd-radio-group>
</view>
<!-- 审批结果 -->
<view class="yd-search-form-item">
<view class="yd-search-form-label">
审批结果
@@ -35,7 +33,6 @@
</wd-radio>
</wd-radio-group>
</view>
<!-- 创建时间 -->
<view class="yd-search-form-item">
<view class="yd-search-form-label">
创建时间
@@ -72,7 +69,6 @@
</wd-button>
</view>
</view>
<!-- 请假原因 -->
<view class="yd-search-form-item">
<view class="yd-search-form-label">
请假原因
@@ -83,7 +79,6 @@
clearable
/>
</view>
<!-- 操作按钮 -->
<view class="yd-search-form-actions">
<wd-button class="flex-1" plain @click="handleReset">
重置

View File

@@ -2,95 +2,60 @@
<view class="yd-page-container">
<!-- 顶部导航栏 -->
<wd-navbar
:title="formData.id ? '编辑请假' : '发起请假'"
title="发起请假"
left-arrow placeholder safe-area-inset-top fixed
@click-left="handleBack"
/>
<!-- 表单内容 -->
<view class="p-24rpx">
<!-- 基本信息卡片 -->
<view class="overflow-hidden rounded-16rpx bg-white">
<view class="p-24rpx">
<view class="mb-24rpx text-32rpx text-[#333] font-bold">
请假信息
</view>
<!-- 请假类型 -->
<view class="mb-24rpx">
<view class="mb-12rpx text-28rpx text-[#333]">
<text class="text-[#ff4d4f]">*</text> 请假类型
</view>
<wd-picker
v-model="formData.type"
:columns="leaveTypeOptions"
label=""
placeholder="请选择请假类型"
/>
</view>
<!-- 开始时间 -->
<view class="mb-24rpx">
<view class="mb-12rpx text-28rpx text-[#333]">
<text class="text-[#ff4d4f]">*</text> 开始时间
</view>
<wd-datetime-picker
v-model="formData.startTime"
type="datetime"
label=""
placeholder="请选择开始时间"
/>
</view>
<!-- 结束时间 -->
<view class="mb-24rpx">
<view class="mb-12rpx text-28rpx text-[#333]">
<text class="text-[#ff4d4f]">*</text> 结束时间
</view>
<wd-datetime-picker
v-model="formData.endTime"
type="datetime"
label=""
placeholder="请选择结束时间"
/>
</view>
<!-- 请假原因 -->
<view>
<view class="mb-12rpx text-28rpx text-[#333]">
<text class="text-[#ff4d4f]">*</text> 请假原因
</view>
<wd-textarea
v-model="formData.reason"
placeholder="请输入请假原因"
:maxlength="200"
show-word-limit
/>
</view>
</view>
</view>
<wd-form ref="formRef" :model="formData" :rules="formRules">
<wd-cell-group border title="请假信息">
<wd-picker
v-model="formData.type"
:columns="getIntDictOptions(DICT_TYPE.BPM_OA_LEAVE_TYPE)"
label="请假类型"
label-width="200rpx"
prop="type"
:rules="[{ required: true, message: '请选择请假类型' }]"
placeholder="请选择请假类型"
/>
<wd-datetime-picker
v-model="formData.startTime"
label="开始时间"
label-width="200rpx"
prop="startTime"
:rules="[{ required: true, message: '请选择开始时间' }]"
placeholder="请选择开始时间"
/>
<wd-datetime-picker
v-model="formData.endTime"
label="结束时间"
label-width="200rpx"
prop="endTime"
:rules="[{ required: true, message: '请选择结束时间' }]"
placeholder="请选择结束时间"
/>
<wd-textarea
v-model="formData.reason"
label="请假原因"
label-width="200rpx"
prop="reason"
:rules="[{ required: true, message: '请输入请假原因' }]"
placeholder="请输入请假原因"
:maxlength="200"
show-word-limit
/>
</wd-cell-group>
</wd-form>
<!-- TODO流程预览卡片 -->
<!-- 原始 vben 版本有流程节点预览和发起人选择审批人功能 -->
<!-- 参考yudao-ui-admin-vben-v5/apps/web-antd/src/views/bpm/oa/leave/create.vue 40-50 -->
<!-- uniapp 端暂不实现流程节点预览因为需要复杂的 ProcessInstanceTimeline 组件 -->
<view class="mt-24rpx overflow-hidden rounded-16rpx bg-white">
<view class="p-24rpx">
<view class="mb-16rpx text-32rpx text-[#333] font-bold">
流程信息
</view>
<view class="text-28rpx text-[#999]">
提交后将进入审批流程
</view>
<!-- TODO实现流程节点预览 -->
<!-- 参考yudao-ui-admin-vben-v5/apps/web-antd/src/views/bpm/oa/leave/create.vue 40-50 -->
<!-- 需要实现 ProcessInstanceTimeline 组件和 getApprovalDetail API -->
</view>
</view>
</view>
<!-- TODO@jason流程预览卡片 -->
<!-- 原始 vben 版本有流程节点预览和发起人选择审批人功能 -->
<!-- 参考yudao-ui-admin-vben-v5/apps/web-antd/src/views/bpm/oa/leave/create.vue 40-50 -->
<!-- uniapp 端暂不实现流程节点预览因为需要复杂的 ProcessInstanceTimeline 组件 -->
<!-- 底部提交按钮 -->
<view class="yd-detail-footer">
<view class="yd-detail-footer-actions">
<wd-button type="default" class="flex-1" @click="handleBack">
取消
</wd-button>
<wd-button type="primary" class="flex-1" :loading="formLoading" @click="handleSubmit">
提交
</wd-button>
@@ -100,11 +65,11 @@
</template>
<script lang="ts" setup>
import type { FormInstance } from 'wot-design-uni/components/wd-form/types'
import type { Leave } from '@/api/bpm/oa/leave'
import { onLoad } from '@dcloudio/uni-app'
import { computed, ref } from 'vue'
import { ref } from 'vue'
import { useMessage, useToast } from 'wot-design-uni'
import { createLeave, updateLeave } from '@/api/bpm/oa/leave'
import { createLeave } from '@/api/bpm/oa/leave'
import { getIntDictOptions } from '@/hooks/useDict'
import { navigateBackPlus } from '@/utils'
import { DICT_TYPE } from '@/utils/constants'
@@ -119,21 +84,19 @@ definePage({
const toast = useToast()
const message = useMessage()
const formLoading = ref(false)
const formData = ref<Partial<Leave>>({
type: undefined,
startTime: undefined,
endTime: undefined,
reason: undefined,
})
/** 请假类型选项 */
const leaveTypeOptions = computed(() => {
return getIntDictOptions(DICT_TYPE.BPM_OA_LEAVE_TYPE).map(item => ({
label: item.label,
value: item.value,
}))
})
const formRules = {
type: [{ required: true, message: '请选择请假类型' }],
startTime: [{ required: true, message: '请选择开始时间' }],
endTime: [{ required: true, message: '请选择结束时间' }],
reason: [{ required: true, message: '请输入请假原因' }],
}
const formRef = ref<FormInstance>()
/** 返回上一页 */
function handleBack() {
@@ -147,74 +110,26 @@ function handleBack() {
})
}
/** 表单校验 */
function validateForm(): boolean {
if (formData.value.type === undefined) {
toast.show('请选择请假类型')
return false
}
if (!formData.value.startTime) {
toast.show('请选择开始时间')
return false
}
if (!formData.value.endTime) {
toast.show('请选择结束时间')
return false
}
if (formData.value.startTime >= formData.value.endTime) {
toast.show('结束时间必须大于开始时间')
return false
}
if (!formData.value.reason?.trim()) {
toast.show('请输入请假原因')
return false
}
return true
}
/** 提交表单 */
async function handleSubmit() {
if (!validateForm()) {
const { valid } = await formRef.value!.validate()
if (!valid) {
return
}
if (formData.value.startTime! >= formData.value.endTime!) {
toast.show('结束时间必须大于开始时间')
return
}
// TODO校验发起人选择审批人
// 参考yudao-ui-admin-vben-v5/apps/web-antd/src/views/bpm/oa/leave/create.vue 第 68-78 行
// uniapp 端暂不实现发起人选择审批人功能
formLoading.value = true
try {
formLoading.value = true
const submitData: Partial<Leave> = {
...formData.value,
startTime: Number(formData.value.startTime),
endTime: Number(formData.value.endTime),
}
if (formData.value.id) {
await updateLeave(submitData)
} else {
await createLeave(submitData)
}
await createLeave(formData.value)
uni.showToast({ title: '提交成功', icon: 'success' })
// 返回列表页
setTimeout(() => {
uni.navigateBack()
navigateBackPlus('/pages-bpm/oa/leave/index')
}, 1500)
} catch (error) {
console.error('[leave create] 提交失败:', error)
} finally {
formLoading.value = false
}
}
/** 初始化 */
onLoad((options) => {
// 如果有 id 参数,则为编辑模式
if (options?.id) {
// TODO加载请假详情进行编辑
// 参考yudao-ui-admin-vben-v5/apps/web-antd/src/views/bpm/oa/leave/create.vue
toast.show('编辑功能开发中')
}
})
</script>

View File

@@ -7,75 +7,37 @@
@click-left="handleBack"
/>
<!-- 加载中 -->
<view v-if="loading" class="flex items-center justify-center py-100rpx">
<wd-loading />
</view>
<!-- 详情内容 -->
<view v-else class="p-24rpx">
<!-- 基本信息卡片 -->
<view class="overflow-hidden rounded-16rpx bg-white">
<view class="p-24rpx">
<view class="mb-24rpx text-32rpx text-[#333] font-bold">
请假信息
</view>
<!-- 请假类型 -->
<view class="mb-16rpx flex items-center">
<text class="w-160rpx text-28rpx text-[#999]">请假类型</text>
<dict-tag :type="DICT_TYPE.BPM_OA_LEAVE_TYPE" :value="formData.type" />
</view>
<!-- 开始时间 -->
<view class="mb-16rpx flex items-center">
<text class="w-160rpx text-28rpx text-[#999]">开始时间</text>
<text class="text-28rpx text-[#333]">{{ formatDateTime(formData.startTime) }}</text>
</view>
<!-- 结束时间 -->
<view class="mb-16rpx flex items-center">
<text class="w-160rpx text-28rpx text-[#999]">结束时间</text>
<text class="text-28rpx text-[#333]">{{ formatDateTime(formData.endTime) }}</text>
</view>
<!-- 请假原因 -->
<view class="flex">
<text class="w-160rpx text-28rpx text-[#999]">请假原因</text>
<text class="flex-1 text-28rpx text-[#333]">{{ formData.reason }}</text>
</view>
</view>
</view>
<!-- 审批状态卡片 -->
<view class="mt-24rpx overflow-hidden rounded-16rpx bg-white">
<view class="p-24rpx">
<view class="mb-24rpx text-32rpx text-[#333] font-bold">
审批状态
</view>
<view class="flex items-center">
<text class="w-160rpx text-28rpx text-[#999]">当前状态</text>
<dict-tag :type="DICT_TYPE.BPM_PROCESS_INSTANCE_STATUS" :value="formData.status" />
</view>
</view>
</view>
<!-- 查看审批进度按钮 -->
<view v-if="formData.processInstanceId" class="mt-24rpx">
<wd-button type="primary" block @click="handleProgress">
查看审批进度
</wd-button>
</view>
<view>
<wd-cell-group border>
<wd-cell title="请假类型">
<dict-tag :type="DICT_TYPE.BPM_OA_LEAVE_TYPE" :value="formData.type" />
</wd-cell>
<wd-cell title="开始时间" :value="formatDateTime(formData.startTime) || '-'" />
<wd-cell title="结束时间" :value="formatDateTime(formData.endTime) || '-'" />
<wd-cell title="请假原因" :value="formData.reason || '-'" />
<wd-cell title="审批状态">
<dict-tag :type="DICT_TYPE.BPM_PROCESS_INSTANCE_STATUS" :value="formData.status" />
</wd-cell>
<wd-cell title="创建时间" :value="formatDateTime(formData.createTime) || '-'" />
</wd-cell-group>
</view>
</view>
</template>
<script lang="ts" setup>
import type { Leave } from '@/api/bpm/oa/leave'
import { onLoad } from '@dcloudio/uni-app'
import { ref } from 'vue'
import { onMounted, ref } from 'vue'
import { useToast } from 'wot-design-uni'
import { getLeave } from '@/api/bpm/oa/leave'
import { navigateBackPlus } from '@/utils'
import { DICT_TYPE } from '@/utils/constants'
import { formatDateTime } from '@/utils/date'
const props = defineProps<{
id?: number | string
}>()
definePage({
style: {
navigationBarTitleText: '',
@@ -84,39 +46,29 @@ definePage({
})
const toast = useToast()
const loading = ref(false)
const formData = ref<Partial<Leave>>({})
const formData = ref<Leave>({})
/** 返回上一页 */
function handleBack() {
navigateBackPlus('/pages-bpm/oa/leave/index')
}
/** 查看审批进度 */
function handleProgress() {
if (formData.value.processInstanceId) {
uni.navigateTo({ url: `/pages-bpm/processInstance/detail/index?id=${formData.value.processInstanceId}` })
}
}
/** 获取详情数据 */
async function getDetailData(id: number) {
async function getDetail() {
if (!props.id) {
toast.show('参数错误')
return
}
try {
loading.value = true
formData.value = await getLeave(id)
} catch (error) {
console.error('[leave detail] 获取详情失败:', error)
toast.loading('加载中...')
formData.value = await getLeave(Number(props.id))
} finally {
loading.value = false
toast.close()
}
}
/** 初始化 */
onLoad((options) => {
if (!options?.id) {
toast.show('参数错误')
return
}
getDetailData(Number(options.id))
onMounted(() => {
getDetail()
})
</script>

View File

@@ -49,14 +49,13 @@
<text class="bpm-time">{{ formatDateTime(item.createTime) }}</text>
</view>
</view>
<!-- 操作按钮 -->
<view class="bpm-actions">
<view class="bpm-action-btn" @click.stop="handleDetail(item)">
<wd-icon name="eye-on" size="32rpx" />
<wd-icon name="view" size="32rpx" />
<text class="ml-8rpx">详情</text>
</view>
<view class="bpm-action-btn" @click.stop="handleProgress(item)">
<wd-icon name="flow" size="32rpx" />
<wd-icon name="queue" size="32rpx" />
<text class="ml-8rpx">审批进度</text>
</view>
<view
@@ -81,12 +80,12 @@
/>
<!-- 新增按钮 -->
<view
class="fixed bottom-100rpx right-32rpx z-10 h-100rpx w-100rpx flex items-center justify-center rounded-full bg-[#1890ff] shadow-lg"
<wd-fab
position="right-bottom"
type="primary"
:expandable="false"
@click="handleCreate"
>
<wd-icon name="add" size="24px" color="#fff" />
</view>
/>
</view>
</view>
</template>
@@ -96,24 +95,15 @@ import type { Leave } from '@/api/bpm/oa/leave'
import type { LoadMoreState } from '@/http/types'
import { onReachBottom } from '@dcloudio/uni-app'
import { computed, onMounted, ref } from 'vue'
import { useMessage } from 'wot-design-uni'
import { getLeavePage } from '@/api/bpm/oa/leave'
import { cancelProcessInstanceByStartUser } from '@/api/bpm/processInstance'
import { useUserStore } from '@/store'
import { navigateBackPlus } from '@/utils'
import { DICT_TYPE } from '@/utils/constants'
import { BpmProcessInstanceStatus, DICT_TYPE } from '@/utils/constants'
import { formatDateTime } from '@/utils/date'
import LeaveSearchForm from './components/search-form.vue'
import '@/pages/bpm/styles/index.scss'
/** 流程实例状态枚举 */
const BpmProcessInstanceStatus = {
RUNNING: 1, // 审批中
APPROVE: 2, // 审批通过
REJECT: 3, // 审批不通过
CANCEL: 4, // 已取消
}
definePage({
style: {
navigationBarTitleText: '',
@@ -122,7 +112,6 @@ definePage({
})
const userStore = useUserStore()
const message = useMessage()
const userNickname = computed(() => userStore.userInfo?.nickname || '')
const total = ref(0)
@@ -136,7 +125,7 @@ const queryParams = ref({
/** 返回上一页 */
function handleBack() {
navigateBackPlus('/pages/bpm/index')
navigateBackPlus()
}
/** 查询列表 */
@@ -190,22 +179,25 @@ function handleProgress(item: Leave) {
/** 取消请假 */
function handleCancel(item: Leave) {
message.confirm({
uni.showModal({
title: '取消流程',
msg: '确定要取消该请假申请吗?',
}).then(async ({ action }) => {
if (action !== 'confirm') {
return
}
// TODO原始 vben 版本支持输入取消原因uniapp 的 message.confirm 不支持输入框
// 参考yudao-ui-admin-vben-v5/apps/web-antd/src/views/bpm/oa/leave/index.vue 第 35-60 行
try {
await cancelProcessInstanceByStartUser(String(item.id), '用户取消')
editable: true,
placeholderText: '请输入取消原因',
success: async (res) => {
if (!res.confirm) {
return
}
const reason = res.content?.trim()
if (!reason) {
uni.showToast({ title: '请输入取消原因', icon: 'none' })
return
}
await cancelProcessInstanceByStartUser(String(item.processInstanceId), reason)
// 更新状态
uni.showToast({ title: '取消成功', icon: 'success' })
handleSearch()
} catch (error) {
console.error('[leave] 取消失败:', error)
}
item.status = BpmProcessInstanceStatus.CANCEL
item.endTime = new Date()
},
})
}

View File

@@ -30,7 +30,6 @@ const menuGroupsData: MenuGroup[] = [
key: 'system',
name: '系统管理',
menus: [
// === 用户权限相关(蓝色系)===
{
key: 'user',
name: '用户管理',
@@ -42,7 +41,7 @@ const menuGroupsData: MenuGroup[] = [
{
key: 'role',
name: '角色管理',
icon: 'secured', // 安全/权限
icon: 'secured',
url: '/pages-system/role/index',
iconColor: '#2f54eb',
permission: 'system:role:query',
@@ -55,11 +54,10 @@ const menuGroupsData: MenuGroup[] = [
iconColor: '#597ef7',
permission: 'system:menu:query',
},
// === 组织架构相关(青色系)===
{
key: 'dept',
name: '部门管理',
icon: 'layers', // 层级结构
icon: 'layers',
url: '/pages-system/dept/index',
iconColor: '#13c2c2',
permission: 'system:dept:query',
@@ -72,11 +70,10 @@ const menuGroupsData: MenuGroup[] = [
iconColor: '#36cfc9',
permission: 'system:post:query',
},
// === 日志相关(紫色系)===
{
key: 'operateLog',
name: '操作日志',
icon: 'history', // 历史记录
icon: 'history',
url: '/pages-system/operate-log/index',
iconColor: '#722ed1',
permission: 'system:operate-log:query',
@@ -84,16 +81,15 @@ const menuGroupsData: MenuGroup[] = [
{
key: 'loginLog',
name: '登录日志',
icon: 'login', // 登录
icon: 'login',
url: '/pages-system/login-log/index',
iconColor: '#9254de',
permission: 'system:login-log:query',
},
// === 消息通知相关(橙色系)===
{
key: 'notice',
name: '通知公告',
icon: 'notification', // 通知
icon: 'notification',
url: '/pages-system/notice/index',
iconColor: '#fa8c16',
permission: 'system:notice:query',
@@ -101,7 +97,7 @@ const menuGroupsData: MenuGroup[] = [
{
key: 'sms',
name: '短信管理',
icon: 'chat1', // 消息
icon: 'chat1',
url: '/pages-system/sms/index',
iconColor: '#faad14',
permission: 'system:sms-channel:query',
@@ -117,12 +113,11 @@ const menuGroupsData: MenuGroup[] = [
{
key: 'notify',
name: '站内信管理',
icon: 'read', // 阅读/消息
icon: 'read',
url: '/pages-system/notify/index',
iconColor: '#ff7a45',
permission: 'system:notify-template:query',
},
// === 系统配置相关(粉色系)===
{
key: 'tenant',
name: '租户管理',
@@ -142,7 +137,7 @@ const menuGroupsData: MenuGroup[] = [
{
key: 'oauth2',
name: 'OAuth2.0',
icon: 'lock-on', // 授权/锁
icon: 'lock-on',
url: '/pages-system/oauth2/index',
iconColor: '#ff85c0',
permission: 'system:oauth2-client:query',
@@ -150,7 +145,7 @@ const menuGroupsData: MenuGroup[] = [
{
key: 'dict',
name: '字典管理',
icon: 'books', // 字典/书籍
icon: 'books',
url: '/pages-system/dict/index',
iconColor: '#c41d7f',
permission: 'system:dict:query',
@@ -168,11 +163,10 @@ const menuGroupsData: MenuGroup[] = [
key: 'infra',
name: '基础设施',
menus: [
// === 日志监控相关(红蓝色系)===
{
key: 'accessLog',
name: '访问日志',
icon: 'view-list', // 列表/日志
icon: 'view-list',
url: '/pages-infra/api-access-log/index',
iconColor: '#1890ff',
permission: 'infra:api-access-log:query',
@@ -185,7 +179,6 @@ const menuGroupsData: MenuGroup[] = [
iconColor: '#f5222d',
permission: 'infra:api-error-log:query',
},
// === 配置相关(青紫色系)===
{
key: 'config',
name: '参数配置',
@@ -197,12 +190,11 @@ const menuGroupsData: MenuGroup[] = [
{
key: 'dataSourceConfig',
name: '数据源配置',
icon: 'server', // 服务器/数据源
icon: 'server',
url: '/pages-infra/data-source-config/index',
iconColor: '#9254de',
permission: 'infra:data-source-config:query',
},
// === 文件存储相关(蓝色系)===
{
key: 'file',
name: '文件管理',
@@ -211,24 +203,21 @@ const menuGroupsData: MenuGroup[] = [
iconColor: '#2f54eb',
permission: 'infra:file:query',
},
// === 通信相关(青色系)===
{
key: 'websocket',
name: 'WebSocket',
icon: 'wifi', // 网络连接
icon: 'wifi',
url: '/pages-infra/web-socket/index',
iconColor: '#13c2c2',
},
// === 任务调度相关(橙色系)===
{
key: 'job',
name: '定时任务',
icon: 'time', // 时间/定时
icon: 'time',
url: '/pages-infra/job/index',
iconColor: '#fa8c16',
permission: 'infra:job:query',
},
// === 开发工具相关(绿色系)===
{
key: 'codegen',
name: '代码生成',
@@ -253,7 +242,7 @@ const menuGroupsData: MenuGroup[] = [
{
key: 'druid',
name: '监控中心',
icon: 'dashboard', // 仪表盘
icon: 'dashboard',
url: ONLY_PC_PAGE,
iconColor: '#389e0d',
},
@@ -263,11 +252,10 @@ const menuGroupsData: MenuGroup[] = [
key: 'bpm',
name: '工作流程',
menus: [
// === 个人工作台(蓝色系)===
{
key: 'bpmMy',
name: '我的流程',
icon: 'user-circle', // 个人
icon: 'user-circle',
url: '/pages/bpm/index?tab=my',
iconColor: '#1890ff',
permission: 'bpm:process-instance:query',
@@ -275,7 +263,7 @@ const menuGroupsData: MenuGroup[] = [
{
key: 'bpmTodo',
name: '待办任务',
icon: 'time', // 待处理/时间
icon: 'time',
url: '/pages/bpm/index?tab=todo',
iconColor: '#fa8c16',
permission: 'bpm:task:query',
@@ -296,11 +284,18 @@ const menuGroupsData: MenuGroup[] = [
iconColor: '#13c2c2',
permission: 'bpm:process-instance-cc:query',
},
// === 流程设计相关(紫色系)===
{
key: 'oaLeave',
name: '请假申请',
icon: 'calendar',
url: '/pages-bpm/oa/leave/index',
iconColor: '#52c41a',
permission: 'bpm:oa-leave:query',
},
{
key: 'bpmModel',
name: '流程模型',
icon: 'app', // 应用/模型
icon: 'app',
url: ONLY_PC_PAGE,
iconColor: '#722ed1',
permission: 'bpm:process-definition:query',
@@ -308,16 +303,15 @@ const menuGroupsData: MenuGroup[] = [
{
key: 'bpmForm',
name: '流程表单',
icon: 'edit-1', // 编辑/表单
icon: 'edit-1',
url: ONLY_PC_PAGE,
iconColor: '#9254de',
permission: 'bpm:form:query',
},
// === 流程配置相关(橙黄色系)===
{
key: 'bpmCategory',
name: '流程分类',
icon: 'folder-open', // 分类/文件夹
icon: 'folder-open',
url: '/pages-bpm/category/index',
iconColor: '#faad14',
permission: 'bpm:category:query',
@@ -330,11 +324,10 @@ const menuGroupsData: MenuGroup[] = [
iconColor: '#ffc53d',
permission: 'bpm:user-group:query',
},
// === 流程扩展相关(粉色系)===
{
key: 'bpmProcessListener',
name: '流程监听器',
icon: 'sound', // 监听/声音
icon: 'sound',
url: '/pages-bpm/process-listener/index',
iconColor: '#eb2f96',
permission: 'bpm:process-listener:query',
@@ -347,11 +340,10 @@ const menuGroupsData: MenuGroup[] = [
iconColor: '#f759ab',
permission: 'bpm:process-expression:query',
},
// === 流程管理相关(青色系)===
{
key: 'bpmProcessInstanceManager',
name: '流程实例',
icon: 'queue', // 队列/实例
icon: 'queue',
url: '/pages-bpm/processInstance/manager/index',
iconColor: '#36cfc9',
permission: 'bpm:process-instance:manager-query',
@@ -359,7 +351,7 @@ const menuGroupsData: MenuGroup[] = [
{
key: 'bpmTaskManager',
name: '流程任务',
icon: 'bulletpoint', // 任务列表
icon: 'bulletpoint',
url: '/pages-bpm/task/manager/index',
iconColor: '#5cdbd3',
permission: 'bpm:task:manager-query',

View File

@@ -1,3 +1,4 @@
export * from './constants/biz-bpm-enum'
export * from './constants/biz-infra-enum'
export * from './constants/biz-system-enum'
export * from './constants/dict-enum'

View File

@@ -0,0 +1,306 @@
// 候选人策略枚举 用于审批节点。抄送节点 )
export enum BpmCandidateStrategyEnum {
/**
* 审批人自选
*/
APPROVE_USER_SELECT = 34,
/**
* 部门的负责人
*/
DEPT_LEADER = 21,
/**
* 部门成员
*/
DEPT_MEMBER = 20,
/**
* 流程表达式
*/
EXPRESSION = 60,
/**
* 表单内部门负责人
*/
FORM_DEPT_LEADER = 51,
/**
* 表单内用户字段
*/
FORM_USER = 50,
/**
* 连续多级部门的负责人
*/
MULTI_LEVEL_DEPT_LEADER = 23,
/**
* 指定岗位
*/
POST = 22,
/**
* 指定角色
*/
ROLE = 10,
/**
* 发起人自己
*/
START_USER = 36,
/**
* 发起人部门负责人
*/
START_USER_DEPT_LEADER = 37,
/**
* 发起人连续多级部门的负责人
*/
START_USER_MULTI_LEVEL_DEPT_LEADER = 38,
/**
* 发起人自选
*/
START_USER_SELECT = 35,
/**
* 指定用户
*/
USER = 30,
/**
* 指定用户组
*/
USER_GROUP = 40,
}
/**
* 节点类型
*/
export enum BpmNodeTypeEnum {
/**
* 子流程节点
*/
CHILD_PROCESS_NODE = 20,
/**
* 条件分支节点 (对应排他网关)
*/
CONDITION_BRANCH_NODE = 51,
/**
* 条件节点
*/
CONDITION_NODE = 50,
/**
* 抄送人节点
*/
COPY_TASK_NODE = 12,
/**
* 延迟器节点
*/
DELAY_TIMER_NODE = 14,
/**
* 结束节点
*/
END_EVENT_NODE = 1,
/**
* 包容分支节点 (对应包容网关)
*/
INCLUSIVE_BRANCH_NODE = 53,
/**
* 并行分支节点 (对应并行网关)
*/
PARALLEL_BRANCH_NODE = 52,
/**
* 路由分支节点
*/
ROUTER_BRANCH_NODE = 54,
/**
* 发起人节点
*/
START_USER_NODE = 10,
/**
* 办理人节点
*/
TRANSACTOR_NODE = 13,
/**
* 触发器节点
*/
TRIGGER_NODE = 15,
/**
* 审批人节点
*/
USER_TASK_NODE = 11,
}
/**
* 流程任务操作按钮
*/
export enum BpmTaskOperationButtonTypeEnum {
/**
* 加签
*/
ADD_SIGN = 5,
/**
* 通过
*/
APPROVE = 1,
/**
* 抄送
*/
COPY = 7,
/**
* 委派
*/
DELEGATE = 4,
/**
* 拒绝
*/
REJECT = 2,
/**
* 退回
*/
RETURN = 6,
/**
* 转办
*/
TRANSFER = 3,
}
/**
* 任务状态枚举
*/
export enum BpmTaskStatusEnum {
/**
* 审批通过
*/
APPROVE = 2,
/**
* 审批通过中
*/
APPROVING = 7,
/**
* 已取消
*/
CANCEL = 4,
/**
* 未开始
*/
NOT_START = -1,
/**
* 审批不通过
*/
REJECT = 3,
/**
* 已退回
*/
RETURN = 5,
/**
* 审批中
*/
RUNNING = 1,
/**
* 跳过
*/
SKIP = -2,
/**
* 待审批
*/
WAIT = 0,
}
/**
* 节点 Id 枚举
*/
export enum BpmNodeIdEnum {
/**
* 发起人节点 Id
*/
END_EVENT_NODE_ID = 'EndEvent',
/**
* 发起人节点 Id
*/
START_USER_NODE_ID = 'StartUserNode',
}
/**
* 表单权限的枚举
*/
export enum BpmFieldPermissionType {
/**
* 隐藏
*/
NONE = '3',
/**
* 只读
*/
READ = '1',
/**
* 编辑
*/
WRITE = '2',
}
/**
* 流程模型类型
*/
export const BpmModelType = {
BPMN: 10, // BPMN 设计器
SIMPLE: 20, // 简易设计器
}
/**
* 流程模型表单类型
*/
export const BpmModelFormType = {
NORMAL: 10, // 流程表单
CUSTOM: 20, // 业务表单
}
/**
* 流程实例状态
*/
export const BpmProcessInstanceStatus = {
NOT_START: -1, // 未开始
RUNNING: 1, // 审批中
APPROVE: 2, // 审批通过
REJECT: 3, // 审批不通过
CANCEL: 4, // 已取消
}
/**
* 自动审批类型
*/
export const BpmAutoApproveType = {
NONE: 0, // 不自动通过
APPROVE_ALL: 1, // 仅审批一次,后续重复的审批节点均自动通过
APPROVE_SEQUENT: 2, // 仅针对连续审批的节点自动通过
}
/**
* 审批操作按钮名称
*/
export const OPERATION_BUTTON_NAME = new Map<number, string>()
OPERATION_BUTTON_NAME.set(BpmTaskOperationButtonTypeEnum.APPROVE, '通过')
OPERATION_BUTTON_NAME.set(BpmTaskOperationButtonTypeEnum.REJECT, '拒绝')
OPERATION_BUTTON_NAME.set(BpmTaskOperationButtonTypeEnum.TRANSFER, '转办')
OPERATION_BUTTON_NAME.set(BpmTaskOperationButtonTypeEnum.DELEGATE, '委派')
OPERATION_BUTTON_NAME.set(BpmTaskOperationButtonTypeEnum.ADD_SIGN, '加签')
OPERATION_BUTTON_NAME.set(BpmTaskOperationButtonTypeEnum.RETURN, '退回')
OPERATION_BUTTON_NAME.set(BpmTaskOperationButtonTypeEnum.COPY, '抄送')
/**
* 流程实例的变量枚举
*/
export enum ProcessVariableEnum {
/**
* 流程定义名称
*/
PROCESS_DEFINITION_NAME = 'PROCESS_DEFINITION_NAME',
/**
* 发起时间
*/
START_TIME = 'PROCESS_START_TIME',
/**
* 发起用户 ID
*/
START_USER_ID = 'PROCESS_START_USER_ID',
}