Commit b4e86430a3f1ffb63d9e4245c74d52d6d1776cd5
1 parent
1b60975e
bpm:增加 OA 请假的列表
Showing
9 changed files
with
359 additions
and
15 deletions
yudao-ui-admin-vue3/src/api/bpm/leave/index.ts
| 1 | import request from '@/config/axios' | 1 | import request from '@/config/axios' |
| 2 | -import { LeaveVO } from './types' | 2 | + |
| 3 | +export type LeaveVO = { | ||
| 4 | + id: number | ||
| 5 | + result: number | ||
| 6 | + type: number | ||
| 7 | + reason: string | ||
| 8 | + processInstanceId: string | ||
| 9 | + startTime: string | ||
| 10 | + endTime: string | ||
| 11 | + createTime: string | ||
| 12 | +} | ||
| 3 | 13 | ||
| 4 | // 创建请假申请 | 14 | // 创建请假申请 |
| 5 | export const createLeaveApi = async (data: LeaveVO) => { | 15 | export const createLeaveApi = async (data: LeaveVO) => { |
yudao-ui-admin-vue3/src/api/bpm/leave/types.ts deleted
yudao-ui-admin-vue3/src/router/modules/remaining.ts
| @@ -220,6 +220,54 @@ const remainingRouter: AppRouteRecordRaw[] = [ | @@ -220,6 +220,54 @@ const remainingRouter: AppRouteRecordRaw[] = [ | ||
| 220 | canTo: true, | 220 | canTo: true, |
| 221 | title: '任务分配规则' | 221 | title: '任务分配规则' |
| 222 | } | 222 | } |
| 223 | + }, | ||
| 224 | + { | ||
| 225 | + path: '/process-instance/create', | ||
| 226 | + component: () => import('@/views/bpm/processInstance/create.vue'), | ||
| 227 | + name: 'BpmProcessInstanceCreate', | ||
| 228 | + meta: { | ||
| 229 | + noCache: true, | ||
| 230 | + hidden: true, | ||
| 231 | + canTo: true, | ||
| 232 | + title: '发起流程', | ||
| 233 | + activeMenu: 'bpm/processInstance/create' | ||
| 234 | + } | ||
| 235 | + }, | ||
| 236 | + { | ||
| 237 | + path: '/process-instance/detail', | ||
| 238 | + component: () => import('@/views/bpm/processInstance/detail.vue'), | ||
| 239 | + name: 'BpmProcessInstanceDetail', | ||
| 240 | + meta: { | ||
| 241 | + noCache: true, | ||
| 242 | + hidden: true, | ||
| 243 | + canTo: true, | ||
| 244 | + title: '流程详情', | ||
| 245 | + activeMenu: 'bpm/processInstance/detail' | ||
| 246 | + } | ||
| 247 | + }, | ||
| 248 | + { | ||
| 249 | + path: '/oa/leave/create', | ||
| 250 | + component: () => import('@/views/bpm/oa/leave/create.vue'), | ||
| 251 | + name: 'OALeaveCreate', | ||
| 252 | + meta: { | ||
| 253 | + noCache: true, | ||
| 254 | + hidden: true, | ||
| 255 | + canTo: true, | ||
| 256 | + title: '发起 OA 请假', | ||
| 257 | + activeMenu: 'bpm/oa/leave/create' | ||
| 258 | + } | ||
| 259 | + }, | ||
| 260 | + { | ||
| 261 | + path: '/oa/leave/detail', | ||
| 262 | + component: () => import('@/views/bpm/oa/leave/detail.vue'), | ||
| 263 | + name: 'OALeaveDetail', | ||
| 264 | + meta: { | ||
| 265 | + noCache: true, | ||
| 266 | + hidden: true, | ||
| 267 | + canTo: true, | ||
| 268 | + title: '查看 OA 请假', | ||
| 269 | + activeMenu: 'bpm/oa/leave/detail' | ||
| 270 | + } | ||
| 223 | } | 271 | } |
| 224 | ] | 272 | ] |
| 225 | } | 273 | } |
yudao-ui-admin-vue3/src/types/auto-imports.d.ts
| @@ -3,6 +3,7 @@ export {} | @@ -3,6 +3,7 @@ export {} | ||
| 3 | declare global { | 3 | declare global { |
| 4 | const DICT_TYPE: typeof import('@/utils/dict')['DICT_TYPE'] | 4 | const DICT_TYPE: typeof import('@/utils/dict')['DICT_TYPE'] |
| 5 | const EffectScope: typeof import('vue')['EffectScope'] | 5 | const EffectScope: typeof import('vue')['EffectScope'] |
| 6 | + const ElMessage: typeof import('element-plus/es')['ElMessage'] | ||
| 6 | const computed: typeof import('vue')['computed'] | 7 | const computed: typeof import('vue')['computed'] |
| 7 | const createApp: typeof import('vue')['createApp'] | 8 | const createApp: typeof import('vue')['createApp'] |
| 8 | const customRef: typeof import('vue')['customRef'] | 9 | const customRef: typeof import('vue')['customRef'] |
yudao-ui-admin-vue3/src/views/bpm/oa/index.vue deleted
yudao-ui-admin-vue3/src/views/bpm/oa/leave/create.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div class="app-container"> | ||
| 3 | + <el-form ref="createForm" :model="form" :rules="rules" label-width="80px"> | ||
| 4 | + <el-form-item label="开始时间" prop="startTime"> | ||
| 5 | + <el-date-picker clearable v-model="form.startTime" type="date" placeholder="选择开始时间" /> | ||
| 6 | + </el-form-item> | ||
| 7 | + <el-form-item label="结束时间" prop="endTime"> | ||
| 8 | + <el-date-picker clearable v-model="form.endTime" type="date" placeholder="选择结束时间" /> | ||
| 9 | + </el-form-item> | ||
| 10 | + <el-form-item label="请假类型" prop="type"> | ||
| 11 | + <el-select v-model="form.type" placeholder="请选择"> | ||
| 12 | + <el-option | ||
| 13 | + v-for="dict in typeDictData" | ||
| 14 | + :key="parseInt(dict.value)" | ||
| 15 | + :label="dict.label" | ||
| 16 | + :value="parseInt(dict.value)" | ||
| 17 | + /> | ||
| 18 | + </el-select> | ||
| 19 | + </el-form-item> | ||
| 20 | + <el-form-item label="原因" prop="reason"> | ||
| 21 | + <el-input | ||
| 22 | + style="width: 650px" | ||
| 23 | + type="textarea" | ||
| 24 | + :rows="3" | ||
| 25 | + v-model="form.reason" | ||
| 26 | + placeholder="请输入原因" | ||
| 27 | + /> | ||
| 28 | + </el-form-item> | ||
| 29 | + <el-form-item> | ||
| 30 | + <el-button type="primary" @click="submitForm(createForm)">提 交</el-button> | ||
| 31 | + </el-form-item> | ||
| 32 | + </el-form> | ||
| 33 | + </div> | ||
| 34 | +</template> | ||
| 35 | +<script setup lang="ts"> | ||
| 36 | +import { ref, reactive } from 'vue' | ||
| 37 | +import { | ||
| 38 | + ElInput, | ||
| 39 | + ElSelect, | ||
| 40 | + ElOption, | ||
| 41 | + ElForm, | ||
| 42 | + ElFormItem, | ||
| 43 | + ElMessage, | ||
| 44 | + ElDatePicker | ||
| 45 | +} from 'element-plus' | ||
| 46 | +import type { FormInstance } from 'element-plus' | ||
| 47 | +import { createLeaveApi } from '@/api/bpm/leave' | ||
| 48 | +import { getDictOptions, DICT_TYPE } from '@/utils/dict' | ||
| 49 | +import { useRouter } from 'vue-router' | ||
| 50 | + | ||
| 51 | +const { push } = useRouter() | ||
| 52 | +const createForm = ref() | ||
| 53 | +// 表单参数 | ||
| 54 | +const form = ref({ | ||
| 55 | + startTime: undefined, | ||
| 56 | + endTime: undefined, | ||
| 57 | + type: undefined, | ||
| 58 | + reason: undefined | ||
| 59 | +}) | ||
| 60 | +// 表单校验 | ||
| 61 | +const rules = reactive({ | ||
| 62 | + startTime: [{ required: true, message: '开始时间不能为空', trigger: 'blur' }], | ||
| 63 | + endTime: [{ required: true, message: '结束时间不能为空', trigger: 'blur' }], | ||
| 64 | + type: [{ required: true, message: '请假类型不能为空', trigger: 'change' }], | ||
| 65 | + reason: [{ required: true, message: '请假原因不能为空', trigger: 'change' }] | ||
| 66 | +}) | ||
| 67 | +const typeDictData = getDictOptions(DICT_TYPE.BPM_OA_LEAVE_TYPE) | ||
| 68 | + | ||
| 69 | +const submitForm = async (formEl: FormInstance | undefined) => { | ||
| 70 | + if (!formEl) return | ||
| 71 | + await formEl.validate((valid, fields) => { | ||
| 72 | + if (valid) { | ||
| 73 | + console.log(form.value, 'submit!') | ||
| 74 | + form.value.startTime = Date.parse(form.value.startTime) | ||
| 75 | + form.value.endTime = Date.parse(form.value.endTime) | ||
| 76 | + // 添加的提交 | ||
| 77 | + createLeaveApi(form.value).then((response) => { | ||
| 78 | + console.log(response, 'response') | ||
| 79 | + ElMessage({ | ||
| 80 | + type: 'success', | ||
| 81 | + message: '发起成功' | ||
| 82 | + }) | ||
| 83 | + push('/bpm/oa/leave') | ||
| 84 | + }) | ||
| 85 | + } else { | ||
| 86 | + console.log('error submit!', fields) | ||
| 87 | + } | ||
| 88 | + }) | ||
| 89 | +} | ||
| 90 | +</script> |
yudao-ui-admin-vue3/src/views/bpm/oa/leave/detail.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div class="app-container"> | ||
| 3 | + <!-- 对话框(添加 / 修改) --> | ||
| 4 | + <el-form ref="form" :model="form" label-width="100px"> | ||
| 5 | + <el-form-item label="开始时间:" prop="startTime"> | ||
| 6 | + {{ formatDate(form.startTime, '{y}-{m}-{d}') }} | ||
| 7 | + </el-form-item> | ||
| 8 | + <el-form-item label="结束时间:" prop="endTime"> | ||
| 9 | + {{ formatDate(form.endTime, '{y}-{m}-{d}') }} | ||
| 10 | + </el-form-item> | ||
| 11 | + <el-form-item label="请假类型:" prop="type"> | ||
| 12 | + <dict-tag :type="DICT_TYPE.BPM_OA_LEAVE_TYPE" :value="form.type" /> | ||
| 13 | + </el-form-item> | ||
| 14 | + <el-form-item label="原因:" prop="reason"> {{ form.reason }}</el-form-item> | ||
| 15 | + </el-form> | ||
| 16 | + </div> | ||
| 17 | +</template> | ||
| 18 | + | ||
| 19 | +<script lang="ts" setup> | ||
| 20 | +import { onMounted, ref } from 'vue' | ||
| 21 | +import { ElMessage } from 'element-plus' | ||
| 22 | + | ||
| 23 | +import { getLeaveApi } from '@/api/bpm/leave' | ||
| 24 | +import { DICT_TYPE } from '@/utils/dict' | ||
| 25 | +import { formatDate } from '@/utils/formatTime' | ||
| 26 | +import { useRouter } from 'vue-router' | ||
| 27 | +const router = useRouter() | ||
| 28 | +// 请假编号 | ||
| 29 | +const id = ref() | ||
| 30 | +// 表单参数 | ||
| 31 | +const form = ref({ | ||
| 32 | + startTime: undefined, | ||
| 33 | + endTime: undefined, | ||
| 34 | + type: undefined, | ||
| 35 | + reason: undefined | ||
| 36 | +}) | ||
| 37 | +/** 获得请假信息 */ | ||
| 38 | +const getDetail = () => { | ||
| 39 | + getLeaveApi(id.value).then((response) => { | ||
| 40 | + form.value = response.data | ||
| 41 | + }) | ||
| 42 | +} | ||
| 43 | +onMounted(() => { | ||
| 44 | + id.value = router.currentRoute.value.query.id | ||
| 45 | + if (!id.value) { | ||
| 46 | + ElMessage({ | ||
| 47 | + type: 'error', | ||
| 48 | + message: '未传递 id 参数,无法查看 OA 请假信息' | ||
| 49 | + }) | ||
| 50 | + return | ||
| 51 | + } | ||
| 52 | + getDetail() | ||
| 53 | +}) | ||
| 54 | +</script> |
yudao-ui-admin-vue3/src/views/bpm/oa/leave/index.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <XTable @register="registerTable"> | ||
| 3 | + <template #toolbar_buttons> | ||
| 4 | + <!-- 操作:发起请假 --> | ||
| 5 | + <XButton type="primary" preIcon="ep:plus" title="发起请假" @click="handleCreate()" /> | ||
| 6 | + </template> | ||
| 7 | + <template #actionbtns_default="{ row }"> | ||
| 8 | + <!-- 操作: 取消请假 --> | ||
| 9 | + <XTextButton | ||
| 10 | + preIcon="ep:delete" | ||
| 11 | + title="取消请假" | ||
| 12 | + v-hasPermi="['bpm:oa-leave:create']" | ||
| 13 | + v-if="row.result === 1" | ||
| 14 | + @click="cancelLeave(row)" | ||
| 15 | + /> | ||
| 16 | + <!-- 操作: 详情 --> | ||
| 17 | + <XTextButton preIcon="ep:delete" :title="t('action.detail')" @click="handleDetail(row)" /> | ||
| 18 | + <!-- 操作: 审批进度 --> | ||
| 19 | + <XTextButton preIcon="ep:edit-pen" title="审批进度" @click="handleProcessDetail(row)" /> | ||
| 20 | + </template> | ||
| 21 | + </XTable> | ||
| 22 | +</template> | ||
| 23 | + | ||
| 24 | +<script setup lang="ts"> | ||
| 25 | +// 全局相关的 import | ||
| 26 | +import { ElMessageBox } from 'element-plus' | ||
| 27 | +// 业务相关的 import | ||
| 28 | +import { allSchemas } from './leave.data' | ||
| 29 | +import * as LeaveApi from '@/api/bpm/leave' | ||
| 30 | +import * as ProcessInstanceApi from '@/api/bpm/processInstance' | ||
| 31 | + | ||
| 32 | +const { t } = useI18n() // 国际化 | ||
| 33 | +const message = useMessage() // 消息弹窗 | ||
| 34 | +const router = useRouter() // 路由 | ||
| 35 | + | ||
| 36 | +const [registerTable, { reload }] = useXTable({ | ||
| 37 | + allSchemas: allSchemas, | ||
| 38 | + getListApi: LeaveApi.getLeavePageApi | ||
| 39 | +}) | ||
| 40 | + | ||
| 41 | +// 发起请假 | ||
| 42 | +const handleCreate = () => { | ||
| 43 | + router.push({ | ||
| 44 | + name: 'OALeaveCreate' | ||
| 45 | + }) | ||
| 46 | +} | ||
| 47 | + | ||
| 48 | +// 取消请假 | ||
| 49 | +const cancelLeave = (row) => { | ||
| 50 | + ElMessageBox.prompt('请输入取消原因', '取消流程', { | ||
| 51 | + confirmButtonText: t('common.ok'), | ||
| 52 | + cancelButtonText: t('common.cancel'), | ||
| 53 | + inputPattern: /^[\s\S]*.*\S[\s\S]*$/, // 判断非空,且非空格 | ||
| 54 | + inputErrorMessage: '取消原因不能为空' | ||
| 55 | + }).then(async ({ value }) => { | ||
| 56 | + await ProcessInstanceApi.cancelProcessInstanceApi(row.id, value) | ||
| 57 | + message.success('取消成功') | ||
| 58 | + reload() | ||
| 59 | + }) | ||
| 60 | +} | ||
| 61 | + | ||
| 62 | +// 详情 | ||
| 63 | +const handleDetail = (row) => { | ||
| 64 | + router.push({ | ||
| 65 | + name: 'OALeaveDetail', | ||
| 66 | + query: { | ||
| 67 | + id: row.id | ||
| 68 | + } | ||
| 69 | + }) | ||
| 70 | +} | ||
| 71 | + | ||
| 72 | +// 审批进度 | ||
| 73 | +const handleProcessDetail = (row) => { | ||
| 74 | + router.push({ | ||
| 75 | + name: 'BpmProcessInstanceDetail', | ||
| 76 | + query: { | ||
| 77 | + id: row.processInstanceId | ||
| 78 | + } | ||
| 79 | + }) | ||
| 80 | +} | ||
| 81 | +</script> |
yudao-ui-admin-vue3/src/views/bpm/oa/leave/leave.data.ts
0 → 100644
| 1 | +import { reactive } from 'vue' | ||
| 2 | +import { DICT_TYPE } from '@/utils/dict' | ||
| 3 | +import { VxeCrudSchema, useVxeCrudSchemas } from '@/hooks/web/useVxeCrudSchemas' | ||
| 4 | +// 国际化 | ||
| 5 | +const { t } = useI18n() | ||
| 6 | +// 表单校验 | ||
| 7 | +export const rules = reactive({ | ||
| 8 | + startTime: [{ required: true, message: '开始时间不能为空', trigger: 'blur' }], | ||
| 9 | + endTime: [{ required: true, message: '结束时间不能为空', trigger: 'blur' }], | ||
| 10 | + type: [{ required: true, message: '请假类型不能为空', trigger: 'change' }], | ||
| 11 | + reason: [{ required: true, message: '请假原因不能为空', trigger: 'change' }] | ||
| 12 | +}) | ||
| 13 | + | ||
| 14 | +// crudSchemas | ||
| 15 | +const crudSchemas = reactive<VxeCrudSchema>({ | ||
| 16 | + primaryKey: 'id', | ||
| 17 | + primaryType: 'id', | ||
| 18 | + primaryTitle: '申请编号', | ||
| 19 | + action: true, | ||
| 20 | + actionWidth: '260', | ||
| 21 | + columns: [ | ||
| 22 | + { | ||
| 23 | + title: t('common.status'), | ||
| 24 | + field: 'result', | ||
| 25 | + dictType: DICT_TYPE.BPM_PROCESS_INSTANCE_RESULT, | ||
| 26 | + dictClass: 'number', | ||
| 27 | + isSearch: true | ||
| 28 | + }, | ||
| 29 | + { | ||
| 30 | + title: t('common.startTimeText'), | ||
| 31 | + field: 'startTime', | ||
| 32 | + formatter: 'formatDate', | ||
| 33 | + table: { | ||
| 34 | + width: 180 | ||
| 35 | + } | ||
| 36 | + }, | ||
| 37 | + { | ||
| 38 | + title: t('common.endTimeText'), | ||
| 39 | + field: 'endTime', | ||
| 40 | + formatter: 'formatDate', | ||
| 41 | + table: { | ||
| 42 | + width: 180 | ||
| 43 | + } | ||
| 44 | + }, | ||
| 45 | + { | ||
| 46 | + title: '请假类型', | ||
| 47 | + field: 'result', | ||
| 48 | + dictType: DICT_TYPE.BPM_OA_LEAVE_TYPE, | ||
| 49 | + dictClass: 'number', | ||
| 50 | + isSearch: true | ||
| 51 | + }, | ||
| 52 | + { | ||
| 53 | + title: '原因', | ||
| 54 | + field: 'reason', | ||
| 55 | + isSearch: true | ||
| 56 | + }, | ||
| 57 | + { | ||
| 58 | + title: '申请时间', | ||
| 59 | + field: 'createTime', | ||
| 60 | + formatter: 'formatDate', | ||
| 61 | + table: { | ||
| 62 | + width: 180 | ||
| 63 | + }, | ||
| 64 | + isSearch: true, | ||
| 65 | + search: { | ||
| 66 | + show: true, | ||
| 67 | + itemRender: { | ||
| 68 | + name: 'XDataTimePicker' | ||
| 69 | + } | ||
| 70 | + } | ||
| 71 | + } | ||
| 72 | + ] | ||
| 73 | +}) | ||
| 74 | +export const { allSchemas } = useVxeCrudSchemas(crudSchemas) |