From ee6317e9060a4276767926dfd959ffab819a38e8 Mon Sep 17 00:00:00 2001 From: xingyu <xingyu4j@vip.qq.com> Date: Thu, 28 Jul 2022 12:18:38 +0800 Subject: [PATCH] feat: bpm api --- yudao-ui-admin-vue3/src/api/bpm/form/index.ts | 48 ++++ yudao-ui-admin-vue3/src/api/bpm/form/types.ts | 9 + .../src/api/bpm/leave/index.ts | 18 ++ .../src/api/bpm/leave/types.ts | 10 + .../src/api/bpm/model/index.ts | 36 +++ .../src/api/bpm/model/types.ts | 15 ++ .../src/api/bpm/processInstance/index.ts | 23 ++ .../src/api/bpm/processInstance/types.ts | 18 ++ yudao-ui-admin-vue3/src/api/bpm/task/index.ts | 36 +++ yudao-ui-admin-vue3/src/api/bpm/task/types.ts | 9 + .../src/api/bpm/taskAssignRule/index.ts | 21 ++ .../src/api/bpm/taskAssignRule/types.ts | 9 + .../src/api/bpm/userGroup/index.ts | 39 +++ .../src/api/bpm/userGroup/types.ts | 9 + .../src/api/system/user/index.ts | 5 + .../src/views/bpm/definition/index.vue | 7 - .../src/views/bpm/form/form.data.ts | 61 +++++ .../src/views/bpm/form/index.vue | 170 ++++++++++++- .../src/views/bpm/group/group.data.ts | 69 ++++++ .../src/views/bpm/group/index.vue | 230 +++++++++++++++++- 20 files changed, 827 insertions(+), 15 deletions(-) create mode 100644 yudao-ui-admin-vue3/src/api/bpm/form/index.ts create mode 100644 yudao-ui-admin-vue3/src/api/bpm/form/types.ts create mode 100644 yudao-ui-admin-vue3/src/api/bpm/leave/index.ts create mode 100644 yudao-ui-admin-vue3/src/api/bpm/leave/types.ts create mode 100644 yudao-ui-admin-vue3/src/api/bpm/model/index.ts create mode 100644 yudao-ui-admin-vue3/src/api/bpm/model/types.ts create mode 100644 yudao-ui-admin-vue3/src/api/bpm/processInstance/index.ts create mode 100644 yudao-ui-admin-vue3/src/api/bpm/processInstance/types.ts create mode 100644 yudao-ui-admin-vue3/src/api/bpm/task/index.ts create mode 100644 yudao-ui-admin-vue3/src/api/bpm/task/types.ts create mode 100644 yudao-ui-admin-vue3/src/api/bpm/taskAssignRule/index.ts create mode 100644 yudao-ui-admin-vue3/src/api/bpm/taskAssignRule/types.ts create mode 100644 yudao-ui-admin-vue3/src/api/bpm/userGroup/index.ts create mode 100644 yudao-ui-admin-vue3/src/api/bpm/userGroup/types.ts delete mode 100644 yudao-ui-admin-vue3/src/views/bpm/definition/index.vue create mode 100644 yudao-ui-admin-vue3/src/views/bpm/form/form.data.ts create mode 100644 yudao-ui-admin-vue3/src/views/bpm/group/group.data.ts diff --git a/yudao-ui-admin-vue3/src/api/bpm/form/index.ts b/yudao-ui-admin-vue3/src/api/bpm/form/index.ts new file mode 100644 index 000000000..23f2fce0b --- /dev/null +++ b/yudao-ui-admin-vue3/src/api/bpm/form/index.ts @@ -0,0 +1,48 @@ +import { useAxios } from '@/hooks/web/useAxios' +import { FormVO } from './types' +const request = useAxios() + +// 创建工作流的表单定义 +export const createFormApi = async (data: FormVO) => { + return await request.post({ + url: '/bpm/form/create', + data: data + }) +} + +// 更新工作流的表单定义 +export const updateFormApi = async (data: FormVO) => { + return await request.put({ + url: '/bpm/form/update', + data: data + }) +} + +// 删除工作流的表单定义 +export const deleteFormApi = async (id: number) => { + return await request.delete({ + url: '/bpm/form/delete?id=' + id + }) +} + +// 获得工作流的表单定义 +export const getFormApi = async (id: number) => { + return await request.get({ + url: '/bpm/form/get?id=' + id + }) +} + +// 获得工作流的表单定义分页 +export const getFormPageApi = async (params) => { + return await request.get({ + url: '/bpm/form/page', + params + }) +} + +// 获得动态表单的精简列表 +export const getSimpleFormsApi = async () => { + return await request.get({ + url: '/bpm/form/list-all-simple' + }) +} diff --git a/yudao-ui-admin-vue3/src/api/bpm/form/types.ts b/yudao-ui-admin-vue3/src/api/bpm/form/types.ts new file mode 100644 index 000000000..2bc8b6912 --- /dev/null +++ b/yudao-ui-admin-vue3/src/api/bpm/form/types.ts @@ -0,0 +1,9 @@ +export type FormVO = { + id: number + name: string + conf: string + fields: string[] + status: number + remark: string + createTime: string +} diff --git a/yudao-ui-admin-vue3/src/api/bpm/leave/index.ts b/yudao-ui-admin-vue3/src/api/bpm/leave/index.ts new file mode 100644 index 000000000..7f266cdf4 --- /dev/null +++ b/yudao-ui-admin-vue3/src/api/bpm/leave/index.ts @@ -0,0 +1,18 @@ +import { useAxios } from '@/hooks/web/useAxios' +import { LeaveVO } from './types' +const request = useAxios() + +// 创建请假申请 +export const createLeaveApi = async (data: LeaveVO) => { + return await request.post({ url: '/bpm/oa/leave/create', data: data }) +} + +// 获得请假申请 +export const getLeaveApi = async (id: number) => { + return await request.get({ url: '/bpm/oa/leave/get?id=' + id }) +} + +// 获得请假申请分页 +export const getLeavePageApi = async (params) => { + return await request.get({ url: '/bpm/oa/leave/page', params }) +} diff --git a/yudao-ui-admin-vue3/src/api/bpm/leave/types.ts b/yudao-ui-admin-vue3/src/api/bpm/leave/types.ts new file mode 100644 index 000000000..60b4bf831 --- /dev/null +++ b/yudao-ui-admin-vue3/src/api/bpm/leave/types.ts @@ -0,0 +1,10 @@ +export type LeaveVO = { + id: number + result: number + type: number + reason: string + processInstanceId: string + startTime: string + endTime: string + createTime: string +} diff --git a/yudao-ui-admin-vue3/src/api/bpm/model/index.ts b/yudao-ui-admin-vue3/src/api/bpm/model/index.ts new file mode 100644 index 000000000..cc577a7fc --- /dev/null +++ b/yudao-ui-admin-vue3/src/api/bpm/model/index.ts @@ -0,0 +1,36 @@ +import { useAxios } from '@/hooks/web/useAxios' +import { ModelVO } from './types' +const request = useAxios() + +export const getModelPage = async (params) => { + return await request.get({ url: '/bpm/model/page', params }) +} + +export const getModel = async (id: number) => { + return await request.get({ url: '/bpm/model/get?id=' + id }) +} + +export const updateModel = async (data: ModelVO) => { + return await request.put({ url: '/bpm/model/update', data: data }) +} + +// 任务状态修改 +export const updateModelState = async (id: number, state: string) => { + const data = { + id: id, + state: state + } + return await request.put({ url: '/bpm/model/update-state', data: data }) +} + +export const createModel = async (data: ModelVO) => { + return await request.post({ url: '/bpm/model/create', data: data }) +} + +export const deleteModel = async (id: number) => { + return await request.delete({ url: '/bpm/model/delete?id=' + id }) +} + +export const deployModel = async (id: number) => { + return await request.post({ url: '/bpm/model/deploy?id=' + id }) +} diff --git a/yudao-ui-admin-vue3/src/api/bpm/model/types.ts b/yudao-ui-admin-vue3/src/api/bpm/model/types.ts new file mode 100644 index 000000000..96266fab3 --- /dev/null +++ b/yudao-ui-admin-vue3/src/api/bpm/model/types.ts @@ -0,0 +1,15 @@ +export type ModelVO = { + id: number + formName: string + key: string + name: string + description: string + category: string + formType: number + formId: number + formCustomCreatePath: string + formCustomViewPath: string + status: number + remark: string + createTime: string +} diff --git a/yudao-ui-admin-vue3/src/api/bpm/processInstance/index.ts b/yudao-ui-admin-vue3/src/api/bpm/processInstance/index.ts new file mode 100644 index 000000000..b49dfa615 --- /dev/null +++ b/yudao-ui-admin-vue3/src/api/bpm/processInstance/index.ts @@ -0,0 +1,23 @@ +import { useAxios } from '@/hooks/web/useAxios' +import { ProcessInstanceVO } from './types' +const request = useAxios() + +export const getMyProcessInstancePage = async (params) => { + return await request.get({ url: '/bpm/process-instance/my-page', params }) +} + +export const createProcessInstance = async (data: ProcessInstanceVO) => { + return await request.post({ url: '/bpm/process-instance/create', data: data }) +} + +export const cancelProcessInstance = async (id: number, reason: string) => { + const data = { + id: id, + reason: reason + } + return await request.delete({ url: '/bpm/process-instance/cancel', data: data }) +} + +export const getProcessInstance = async (id: number) => { + return await request.get({ url: '/bpm/process-instance/get?id=' + id }) +} diff --git a/yudao-ui-admin-vue3/src/api/bpm/processInstance/types.ts b/yudao-ui-admin-vue3/src/api/bpm/processInstance/types.ts new file mode 100644 index 000000000..3ab506389 --- /dev/null +++ b/yudao-ui-admin-vue3/src/api/bpm/processInstance/types.ts @@ -0,0 +1,18 @@ +export type task = { + id: string + name: string +} +export type ProcessInstanceVO = { + id: number + name: string + processDefinitionId: string + category: string + result: number + tasks: task[] + fields: string[] + status: number + remark: string + businessKey: string + createTime: string + endTime: string +} diff --git a/yudao-ui-admin-vue3/src/api/bpm/task/index.ts b/yudao-ui-admin-vue3/src/api/bpm/task/index.ts new file mode 100644 index 000000000..7967f5e37 --- /dev/null +++ b/yudao-ui-admin-vue3/src/api/bpm/task/index.ts @@ -0,0 +1,36 @@ +import { useAxios } from '@/hooks/web/useAxios' + +const request = useAxios() + +export const getTodoTaskPage = async (params) => { + return await request.get({ url: '/bpm/task/todo-page', params }) +} + +export const getDoneTaskPage = async (params) => { + return await request.get({ url: '/bpm/task/done-page', params }) +} + +export const completeTask = async (data) => { + return await request.put({ url: '/bpm/task/complete', data: data }) +} + +export const approveTask = async (data) => { + return await request.put({ url: '/bpm/task/approve', data: data }) +} + +export const rejectTask = async (data) => { + return await request.put({ url: '/bpm/task/reject', data: data }) +} +export const backTask = async (data) => { + return await request.put({ url: '/bpm/task/back', data: data }) +} + +export const updateTaskAssignee = async (data) => { + return await request.put({ url: '/bpm/task/update-assignee', data: data }) +} + +export const getTaskListByProcessInstanceId = async (processInstanceId) => { + return await request.get({ + url: '/bpm/task/list-by-process-instance-id?processInstanceId=' + processInstanceId + }) +} diff --git a/yudao-ui-admin-vue3/src/api/bpm/task/types.ts b/yudao-ui-admin-vue3/src/api/bpm/task/types.ts new file mode 100644 index 000000000..2bc8b6912 --- /dev/null +++ b/yudao-ui-admin-vue3/src/api/bpm/task/types.ts @@ -0,0 +1,9 @@ +export type FormVO = { + id: number + name: string + conf: string + fields: string[] + status: number + remark: string + createTime: string +} diff --git a/yudao-ui-admin-vue3/src/api/bpm/taskAssignRule/index.ts b/yudao-ui-admin-vue3/src/api/bpm/taskAssignRule/index.ts new file mode 100644 index 000000000..f6105293d --- /dev/null +++ b/yudao-ui-admin-vue3/src/api/bpm/taskAssignRule/index.ts @@ -0,0 +1,21 @@ +import { useAxios } from '@/hooks/web/useAxios' +import { TaskAssignVO } from './types' +const request = useAxios() + +export const getTaskAssignRuleList = async (params) => { + return await request.get({ url: '/bpm/task-assign-rule/list', params }) +} + +export const createTaskAssignRule = async (data: TaskAssignVO) => { + return await request.post({ + url: '/bpm/task-assign-rule/create', + data: data + }) +} + +export const updateTaskAssignRule = async (data: TaskAssignVO) => { + return await request.put({ + url: '/bpm/task-assign-rule/update', + data: data + }) +} diff --git a/yudao-ui-admin-vue3/src/api/bpm/taskAssignRule/types.ts b/yudao-ui-admin-vue3/src/api/bpm/taskAssignRule/types.ts new file mode 100644 index 000000000..e9340e7ea --- /dev/null +++ b/yudao-ui-admin-vue3/src/api/bpm/taskAssignRule/types.ts @@ -0,0 +1,9 @@ +export type TaskAssignVO = { + id: number + modelId: string + processDefinitionId: string + taskDefinitionKey: string + taskDefinitionName: string + options: string[] + type: number +} diff --git a/yudao-ui-admin-vue3/src/api/bpm/userGroup/index.ts b/yudao-ui-admin-vue3/src/api/bpm/userGroup/index.ts new file mode 100644 index 000000000..e7cd3f507 --- /dev/null +++ b/yudao-ui-admin-vue3/src/api/bpm/userGroup/index.ts @@ -0,0 +1,39 @@ +import { useAxios } from '@/hooks/web/useAxios' +import { UserGroupVO } from './types' +const request = useAxios() + +// 创建用户组 +export const createUserGroupApi = async (data: UserGroupVO) => { + return await request.post({ + url: '/bpm/user-group/create', + data: data + }) +} + +// 更新用户组 +export const updateUserGroupApi = async (data: UserGroupVO) => { + return await request.put({ + url: '/bpm/user-group/update', + data: data + }) +} + +// 删除用户组 +export const deleteUserGroupApi = async (id: number) => { + return await request.delete({ url: '/bpm/user-group/delete?id=' + id }) +} + +// 获得用户组 +export const getUserGroupApi = async (id: number) => { + return await request.get({ url: '/bpm/user-group/get?id=' + id }) +} + +// 获得用户组分页 +export const getUserGroupPageApi = async (params) => { + return await request.get({ url: '/bpm/user-group/page', params }) +} + +// 获取用户组精简信息列表 +export const listSimpleUserGroupsApi = async () => { + return await request.get({ url: '/bpm/user-group/list-all-simple' }) +} diff --git a/yudao-ui-admin-vue3/src/api/bpm/userGroup/types.ts b/yudao-ui-admin-vue3/src/api/bpm/userGroup/types.ts new file mode 100644 index 000000000..d0d67ad43 --- /dev/null +++ b/yudao-ui-admin-vue3/src/api/bpm/userGroup/types.ts @@ -0,0 +1,9 @@ +export type UserGroupVO = { + id: number + name: string + description: string + memberUserIds: number[] + status: number + remark: string + createTime: string +} diff --git a/yudao-ui-admin-vue3/src/api/system/user/index.ts b/yudao-ui-admin-vue3/src/api/system/user/index.ts index f4a484eaf..5085d5c11 100644 --- a/yudao-ui-admin-vue3/src/api/system/user/index.ts +++ b/yudao-ui-admin-vue3/src/api/system/user/index.ts @@ -55,3 +55,8 @@ export const updateUserStatusApi = (id: number, status: number) => { } return request.put({ url: '/system/user/update-status', data: data }) } + +// 获取用户精简信息列表 +export const getListSimpleUsersApi = () => { + return request.get({ url: '/system/user/list-all-simple' }) +} diff --git a/yudao-ui-admin-vue3/src/views/bpm/definition/index.vue b/yudao-ui-admin-vue3/src/views/bpm/definition/index.vue deleted file mode 100644 index b03cb75c8..000000000 --- a/yudao-ui-admin-vue3/src/views/bpm/definition/index.vue +++ /dev/null @@ -1,7 +0,0 @@ -<script setup lang="ts"></script> - -<template> - <div>index</div> -</template> - -<style scoped></style> diff --git a/yudao-ui-admin-vue3/src/views/bpm/form/form.data.ts b/yudao-ui-admin-vue3/src/views/bpm/form/form.data.ts new file mode 100644 index 000000000..32de7da57 --- /dev/null +++ b/yudao-ui-admin-vue3/src/views/bpm/form/form.data.ts @@ -0,0 +1,61 @@ +import { reactive } from 'vue' +import { useI18n } from '@/hooks/web/useI18n' +import { required } from '@/utils/formRules' +import { CrudSchema, useCrudSchemas } from '@/hooks/web/useCrudSchemas' +import { DICT_TYPE } from '@/utils/dict' +const { t } = useI18n() // 国际化 + +// 表单校验 +export const rules = reactive({ + name: [required] +}) + +// CrudSchema +const crudSchemas = reactive<CrudSchema[]>([ + { + label: t('common.index'), + field: 'id', + type: 'index', + form: { + show: false + }, + detail: { + show: false + } + }, + { + label: '表单名', + field: 'name', + search: { + show: true + } + }, + { + label: t('common.status'), + field: 'status', + dictType: DICT_TYPE.COMMON_STATUS + }, + { + label: '备注', + field: 'remark' + }, + { + label: t('common.createTime'), + field: 'createTime', + form: { + show: false + } + }, + { + label: t('table.action'), + field: 'action', + width: '240px', + form: { + show: false + }, + detail: { + show: false + } + } +]) +export const { allSchemas } = useCrudSchemas(crudSchemas) diff --git a/yudao-ui-admin-vue3/src/views/bpm/form/index.vue b/yudao-ui-admin-vue3/src/views/bpm/form/index.vue index b03cb75c8..edd99c84b 100644 --- a/yudao-ui-admin-vue3/src/views/bpm/form/index.vue +++ b/yudao-ui-admin-vue3/src/views/bpm/form/index.vue @@ -1,7 +1,169 @@ -<script setup lang="ts"></script> +<script setup lang="ts"> +import { ref, unref } from 'vue' +import dayjs from 'dayjs' +import { ElMessage } from 'element-plus' +import { DICT_TYPE } from '@/utils/dict' +import { useTable } from '@/hooks/web/useTable' +import { useI18n } from '@/hooks/web/useI18n' +import { FormExpose } from '@/components/Form' +import type { FormVO } from '@/api/bpm/form/types' +import { rules, allSchemas } from './form.data' +import * as FormApi from '@/api/bpm/form' +const { t } = useI18n() // 国际化 + +// ========== 列表相关 ========== +const { register, tableObject, methods } = useTable<FormVO>({ + getListApi: FormApi.getFormPageApi, + delListApi: FormApi.deleteFormApi +}) +const { getList, setSearchParams, delList } = methods + +// ========== CRUD 相关 ========== +const actionLoading = ref(false) // 遮罩层 +const actionType = ref('') // 操作按钮的类型 +const dialogVisible = ref(false) // 是否显示弹出层 +const dialogTitle = ref('edit') // 弹出层标题 +const formRef = ref<FormExpose>() // 表单 Ref + +// 设置标题 +const setDialogTile = (type: string) => { + dialogTitle.value = t('action.' + type) + actionType.value = type + dialogVisible.value = true +} + +// 新增操作 +const handleCreate = () => { + setDialogTile('create') + // 重置表单 + unref(formRef)?.getElFormRef()?.resetFields() +} + +// 修改操作 +const handleUpdate = async (row: FormVO) => { + setDialogTile('update') + // 设置数据 + const res = await FormApi.getFormApi(row.id) + unref(formRef)?.setValues(res) +} + +// 提交按钮 +const submitForm = async () => { + actionLoading.value = true + // 提交请求 + try { + const data = unref(formRef)?.formModel as FormVO + if (actionType.value === 'create') { + await FormApi.createFormApi(data) + ElMessage.success(t('common.createSuccess')) + } else { + await FormApi.updateFormApi(data) + ElMessage.success(t('common.updateSuccess')) + } + // 操作成功,重新加载列表 + dialogVisible.value = false + await getList() + } finally { + actionLoading.value = false + } +} + +// 删除操作 +const handleDelete = (row: FormVO) => { + delList(row.id, false) +} + +// ========== 详情相关 ========== +const detailRef = ref() // 详情 Ref + +// 详情操作 +const handleDetail = async (row: FormVO) => { + // 设置数据 + detailRef.value = row + setDialogTile('detail') +} + +// ========== 初始化 ========== +getList() +</script> <template> - <div>index</div> -</template> + <!-- 搜索工作区 --> + <ContentWrap> + <Search :schema="allSchemas.searchSchema" @search="setSearchParams" @reset="setSearchParams" /> + </ContentWrap> + <ContentWrap> + <!-- 操作工具栏 --> + <div class="mb-10px"> + <el-button type="primary" v-hasPermi="['bpm:form:create']" @click="handleCreate"> + <Icon icon="ep:zoom-in" class="mr-5px" /> {{ t('action.add') }} + </el-button> + </div> + <!-- 列表 --> + <Table + :columns="allSchemas.tableColumns" + :selection="false" + :data="tableObject.tableList" + :loading="tableObject.loading" + :pagination="{ + total: tableObject.total + }" + v-model:pageSize="tableObject.pageSize" + v-model:currentPage="tableObject.currentPage" + @register="register" + > + <template #status="{ row }"> + <DictTag :type="DICT_TYPE.COMMON_STATUS" :value="row.status" /> + </template> + <template #createTime="{ row }"> + <span>{{ dayjs(row.createTime).format('YYYY-MM-DD HH:mm:ss') }}</span> + </template> + <template #action="{ row }"> + <el-button link type="primary" v-hasPermi="['bpm:form:update']" @click="handleUpdate(row)"> + <Icon icon="ep:edit" class="mr-1px" /> {{ t('action.edit') }} + </el-button> + <el-button link type="primary" v-hasPermi="['bpm:form:update']" @click="handleDetail(row)"> + <Icon icon="ep:view" class="mr-1px" /> {{ t('action.detail') }} + </el-button> + <el-button link type="primary" v-hasPermi="['bpm:form:delete']" @click="handleDelete(row)"> + <Icon icon="ep:delete" class="mr-1px" /> {{ t('action.del') }} + </el-button> + </template> + </Table> + </ContentWrap> -<style scoped></style> + <Dialog v-model="dialogVisible" :title="dialogTitle"> + <!-- 对话框(添加 / 修改) --> + <Form + v-if="['create', 'update'].includes(actionType)" + :schema="allSchemas.formSchema" + :rules="rules" + ref="formRef" + /> + <!-- 对话框(详情) --> + <Descriptions + v-if="actionType === 'detail'" + :schema="allSchemas.detailSchema" + :data="detailRef" + > + <template #status="{ row }"> + <DictTag :type="DICT_TYPE.COMMON_STATUS" :value="row.status" /> + </template> + <template #createTime="{ row }"> + <span>{{ dayjs(row.createTime).format('YYYY-MM-DD HH:mm:ss') }}</span> + </template> + </Descriptions> + <!-- 操作按钮 --> + <template #footer> + <el-button + v-if="['create', 'update'].includes(actionType)" + type="primary" + :loading="actionLoading" + @click="submitForm" + > + {{ t('action.save') }} + </el-button> + <el-button @click="dialogVisible = false">{{ t('dialog.close') }}</el-button> + </template> + </Dialog> +</template> diff --git a/yudao-ui-admin-vue3/src/views/bpm/group/group.data.ts b/yudao-ui-admin-vue3/src/views/bpm/group/group.data.ts new file mode 100644 index 000000000..83562b156 --- /dev/null +++ b/yudao-ui-admin-vue3/src/views/bpm/group/group.data.ts @@ -0,0 +1,69 @@ +import { reactive } from 'vue' +import { useI18n } from '@/hooks/web/useI18n' +import { required } from '@/utils/formRules' +import { CrudSchema, useCrudSchemas } from '@/hooks/web/useCrudSchemas' +import { DICT_TYPE } from '@/utils/dict' +const { t } = useI18n() // 国际化 + +// 表单校验 +export const rules = reactive({ + name: [required] +}) + +// CrudSchema +const crudSchemas = reactive<CrudSchema[]>([ + { + label: t('common.index'), + field: 'id', + type: 'index', + form: { + show: false + }, + detail: { + show: false + } + }, + { + label: '组名', + field: 'name', + search: { + show: true + } + }, + { + label: '成员', + field: 'memberUserIds' + }, + { + label: '描述', + field: 'description' + }, + { + label: t('common.status'), + field: 'status', + dictType: DICT_TYPE.COMMON_STATUS + }, + { + label: '备注', + field: 'remark' + }, + { + label: t('common.createTime'), + field: 'createTime', + form: { + show: false + } + }, + { + label: t('table.action'), + field: 'action', + width: '240px', + form: { + show: false + }, + detail: { + show: false + } + } +]) +export const { allSchemas } = useCrudSchemas(crudSchemas) diff --git a/yudao-ui-admin-vue3/src/views/bpm/group/index.vue b/yudao-ui-admin-vue3/src/views/bpm/group/index.vue index b03cb75c8..20c9c7201 100644 --- a/yudao-ui-admin-vue3/src/views/bpm/group/index.vue +++ b/yudao-ui-admin-vue3/src/views/bpm/group/index.vue @@ -1,7 +1,229 @@ -<script setup lang="ts"></script> +<script setup lang="ts"> +import { ref, unref, onMounted } from 'vue' +import dayjs from 'dayjs' +import { ElMessage, ElSelect, ElOption } from 'element-plus' +import { DICT_TYPE } from '@/utils/dict' +import { useTable } from '@/hooks/web/useTable' +import { useI18n } from '@/hooks/web/useI18n' +import { FormExpose } from '@/components/Form' +import type { UserGroupVO } from '@/api/bpm/userGroup/types' +import { rules, allSchemas } from './group.data' +import * as UserGroupApi from '@/api/bpm/userGroup' +import { getListSimpleUsersApi } from '@/api/system/user' +import { UserVO } from '@/api/system/user/types' + +const { t } = useI18n() // 国际化 + +// ========== 列表相关 ========== +const { register, tableObject, methods } = useTable<UserGroupVO>({ + getListApi: UserGroupApi.getUserGroupPageApi, + delListApi: UserGroupApi.deleteUserGroupApi +}) +const { getList, setSearchParams, delList } = methods + +// ========== CRUD 相关 ========== +const actionLoading = ref(false) // 遮罩层 +const actionType = ref('') // 操作按钮的类型 +const dialogVisible = ref(false) // 是否显示弹出层 +const dialogTitle = ref('edit') // 弹出层标题 +const formRef = ref<FormExpose>() // 表单 Ref + +// ========== 用户选择 ========== +const userIds = ref<number[]>([]) +const userOptions = ref<UserVO[]>([]) +const getUserOptions = async () => { + const res = await getListSimpleUsersApi() + userOptions.value.push(...res) +} + +// 设置标题 +const setDialogTile = (type: string) => { + dialogTitle.value = t('action.' + type) + actionType.value = type + dialogVisible.value = true +} + +// 新增操作 +const handleCreate = () => { + setDialogTile('create') + userIds.value = [] + // 重置表单 + unref(formRef)?.getElFormRef()?.resetFields() +} + +// 修改操作 +const handleUpdate = async (row: UserGroupVO) => { + setDialogTile('update') + // 设置数据 + const res = await UserGroupApi.getUserGroupApi(row.id) + userIds.value = res.memberUserIds + unref(formRef)?.setValues(res) +} + +// 提交按钮 +const submitForm = async () => { + actionLoading.value = true + // 提交请求 + try { + const data = unref(formRef)?.formModel as UserGroupVO + data.memberUserIds = userIds.value + if (actionType.value === 'create') { + await UserGroupApi.createUserGroupApi(data) + ElMessage.success(t('common.createSuccess')) + } else { + await UserGroupApi.updateUserGroupApi(data) + ElMessage.success(t('common.updateSuccess')) + } + // 操作成功,重新加载列表 + dialogVisible.value = false + await getList() + } finally { + actionLoading.value = false + } +} + +// 删除操作 +const handleDelete = (row: UserGroupVO) => { + delList(row.id, false) +} + +// 根据用户名获取用户真实名 +const getUserNickName = (userId: number) => { + for (const user of userOptions.value) { + if (user.id === userId) return user.nickname + } + return '未知(' + userId + ')' +} +// ========== 详情相关 ========== +const detailRef = ref() // 详情 Ref + +// 详情操作 +const handleDetail = async (row: UserGroupVO) => { + // 设置数据 + detailRef.value = row + setDialogTile('detail') +} + +// ========== 初始化 ========== +onMounted(async () => { + await getList() + await getUserOptions() +}) +</script> <template> - <div>index</div> -</template> + <!-- 搜索工作区 --> + <ContentWrap> + <Search :schema="allSchemas.searchSchema" @search="setSearchParams" @reset="setSearchParams" /> + </ContentWrap> + <ContentWrap> + <!-- 操作工具栏 --> + <div class="mb-10px"> + <el-button type="primary" v-hasPermi="['bpm:user-group:create']" @click="handleCreate"> + <Icon icon="ep:zoom-in" class="mr-5px" /> {{ t('action.add') }} + </el-button> + </div> + <!-- 列表 --> + <Table + :columns="allSchemas.tableColumns" + :selection="false" + :data="tableObject.tableList" + :loading="tableObject.loading" + :pagination="{ + total: tableObject.total + }" + v-model:pageSize="tableObject.pageSize" + v-model:currentPage="tableObject.currentPage" + @register="register" + > + <template #status="{ row }"> + <DictTag :type="DICT_TYPE.COMMON_STATUS" :value="row.status" /> + </template> + <template #memberUserIds="{ row }"> + <span v-for="userId in row.memberUserIds" :key="userId"> + {{ getUserNickName(userId) + ' ' }} + </span> + </template> + <template #createTime="{ row }"> + <span>{{ dayjs(row.createTime).format('YYYY-MM-DD HH:mm:ss') }}</span> + </template> + <template #action="{ row }"> + <el-button + link + type="primary" + v-hasPermi="['bpm:user-group:update']" + @click="handleUpdate(row)" + > + <Icon icon="ep:edit" class="mr-1px" /> {{ t('action.edit') }} + </el-button> + <el-button + link + type="primary" + v-hasPermi="['bpm:user-group:update']" + @click="handleDetail(row)" + > + <Icon icon="ep:view" class="mr-1px" /> {{ t('action.detail') }} + </el-button> + <el-button + link + type="primary" + v-hasPermi="['bpm:user-group:delete']" + @click="handleDelete(row)" + > + <Icon icon="ep:delete" class="mr-1px" /> {{ t('action.del') }} + </el-button> + </template> + </Table> + </ContentWrap> -<style scoped></style> + <Dialog v-model="dialogVisible" :title="dialogTitle"> + <!-- 对话框(添加 / 修改) --> + <Form + v-if="['create', 'update'].includes(actionType)" + :schema="allSchemas.formSchema" + :rules="rules" + ref="formRef" + > + <template #memberUserIds> + <el-select v-model="userIds" multiple> + <el-option + v-for="item in userOptions" + :key="item.id" + :label="item.nickname" + :value="item.id" + /> + </el-select> + </template> + </Form> + <!-- 对话框(详情) --> + <Descriptions + v-if="actionType === 'detail'" + :schema="allSchemas.detailSchema" + :data="detailRef" + > + <template #memberUserIds="{ row }"> + <span v-for="userId in row.memberUserIds" :key="userId"> + {{ getUserNickName(userId) + ' ' }} + </span> + </template> + <template #status="{ row }"> + <DictTag :type="DICT_TYPE.COMMON_STATUS" :value="row.status" /> + </template> + <template #createTime="{ row }"> + <span>{{ dayjs(row.createTime).format('YYYY-MM-DD HH:mm:ss') }}</span> + </template> + </Descriptions> + <!-- 操作按钮 --> + <template #footer> + <el-button + v-if="['create', 'update'].includes(actionType)" + type="primary" + :loading="actionLoading" + @click="submitForm" + > + {{ t('action.save') }} + </el-button> + <el-button @click="dialogVisible = false">{{ t('dialog.close') }}</el-button> + </template> + </Dialog> +</template>