Commit ec6a46a5413447d1d8a8eb5edb78c27465ffd599

Authored by YunaiV
1 parent 8e29e427

bpm:增加流程模型的列表

yudao-ui-admin-vue3/src/api/bpm/model/index.ts
1 1 import request from '@/config/axios'
2   -import { ModelVO } from './types'
  2 +
  3 +export type ProcessDefinitionVO = {
  4 + id: string
  5 + version: number
  6 + deploymentTIme: string
  7 + suspensionState: number
  8 +}
  9 +
  10 +export type ModelVO = {
  11 + id: number
  12 + formName: string
  13 + key: string
  14 + name: string
  15 + description: string
  16 + category: string
  17 + formType: number
  18 + formId: number
  19 + formCustomCreatePath: string
  20 + formCustomViewPath: string
  21 + processDefinition: ProcessDefinitionVO
  22 + status: number
  23 + remark: string
  24 + createTime: string
  25 +}
3 26  
4 27 export const getModelPageApi = async (params) => {
5 28 return await request.get({ url: '/bpm/model/page', params })
... ...
yudao-ui-admin-vue3/src/api/bpm/model/types.ts deleted
1   -export type ProcessDefinitionVO = {
2   - id: string
3   - version: number
4   - deploymentTIme: string
5   - suspensionState: number
6   -}
7   -
8   -export type ModelVO = {
9   - id: number
10   - formName: string
11   - key: string
12   - name: string
13   - description: string
14   - category: string
15   - formType: number
16   - formId: number
17   - formCustomCreatePath: string
18   - formCustomViewPath: string
19   - processDefinition: ProcessDefinitionVO
20   - status: number
21   - remark: string
22   - createTime: string
23   -}
yudao-ui-admin-vue3/src/components/DictTag/src/DictTag.vue
... ... @@ -33,6 +33,9 @@ export default defineComponent({
33 33 if (!props.type) {
34 34 return null
35 35 }
  36 + if (!props.value) {
  37 + return null
  38 + }
36 39 getDictObj(props.type, props.value.toString())
37 40 return (
38 41 <ElTag
... ...
yudao-ui-admin-vue3/src/views/bpm/model/index.vue
1   -<script setup lang="ts" name="Model">
2   -import dayjs from 'dayjs'
3   -import { DICT_TYPE } from '@/utils/dict'
4   -import { useTable } from '@/hooks/web/useTable'
5   -import type { FormExpose } from '@/components/Form'
6   -import type { ModelVO } from '@/api/bpm/model/types'
7   -import { rules, allSchemas } from './model.data'
  1 +<template>
  2 + <ContentWrap>
  3 + <!-- 列表 -->
  4 + <XTable @register="registerTable">
  5 + <template #toolbar_buttons>
  6 + <!-- 操作:新增 -->
  7 + <XButton
  8 + type="primary"
  9 + preIcon="ep:zoom-in"
  10 + title="新建流程"
  11 + v-hasPermi="['bpm:model:create']"
  12 + @click="handleCreate"
  13 + />
  14 + <!-- 操作:导入 -->
  15 + <XButton
  16 + type="warning"
  17 + preIcon="ep:upload"
  18 + :title="'导入流程'"
  19 + @click="handleImport"
  20 + style="margin-left: 10px"
  21 + />
  22 + </template>
  23 + <!-- 流程名称 -->
  24 + <template #name_default="{ row }">
  25 + <XTextButton :title="row.name" @click="handleBpmnDetail(row.id)" />
  26 + </template>
  27 + <!-- 表单信息 -->
  28 + <template #formId_default="{ row }">
  29 + <XTextButton
  30 + :title="forms.find((form) => form.id === row.formId)?.name || row.formId"
  31 + @click="handleFormDetail(row.id)"
  32 + />
  33 + </template>
  34 + <!-- 流程版本 -->
  35 + <template #version_default="{ row }">
  36 + <el-tag v-if="row.processDefinition">v{{ row.processDefinition.version }}</el-tag>
  37 + <el-tag type="warning" v-else>未部署</el-tag>
  38 + </template>
  39 + <!-- 激活状态 -->
  40 + <template #status_default="{ row }">
  41 + <el-switch
  42 + v-if="row.processDefinition"
  43 + v-model="row.processDefinition.suspensionState"
  44 + :active-value="1"
  45 + :inactive-value="2"
  46 + @change="handleChangeState(row)"
  47 + />
  48 + </template>
  49 + <!-- 操作 -->
  50 + <template #actionbtns_default="{ row }">
  51 + <XTextButton
  52 + preIcon="ep:edit"
  53 + title="修改流程"
  54 + v-hasPermi="['bpm:model:update']"
  55 + @click="handleUpdate(row.id)"
  56 + />
  57 + <XTextButton
  58 + preIcon="ep:setting"
  59 + title="设计流程"
  60 + v-hasPermi="['bpm:model:update']"
  61 + @click="handleDesign(row)"
  62 + />
  63 + <XTextButton
  64 + preIcon="ep:user"
  65 + title="分配规则"
  66 + v-hasPermi="['bpm:task-assign-rule:query']"
  67 + @click="handleAssignRule(row)"
  68 + />
  69 + <XTextButton
  70 + preIcon="ep:position"
  71 + title="发布流程"
  72 + v-hasPermi="['bpm:model:deploy']"
  73 + @click="handleDeploy(row)"
  74 + />
  75 + <XTextButton
  76 + preIcon="ep:aim"
  77 + title="流程定义"
  78 + v-hasPermi="['bpm:process-definition:query']"
  79 + @click="handleDefinitionList(row.id)"
  80 + />
  81 + <!-- 操作:删除 -->
  82 + <XTextButton
  83 + preIcon="ep:delete"
  84 + :title="t('action.del')"
  85 + v-hasPermi="['bpm:model:delete']"
  86 + @click="handleDelete(row.id)"
  87 + />
  88 + </template>
  89 + </XTable>
  90 +
  91 + <!-- 对话框(添加 / 修改流程) -->
  92 + <XModal v-model="dialogVisible" :title="dialogTitle" width="600">
  93 + <el-form
  94 + :loading="dialogLoading"
  95 + el-form
  96 + ref="saveFormRef"
  97 + :model="saveForm"
  98 + :rules="rules"
  99 + label-width="110px"
  100 + >
  101 + <el-form-item label="流程标识" prop="key">
  102 + <el-input
  103 + v-model="saveForm.key"
  104 + placeholder="请输入流标标识"
  105 + style="width: 330px"
  106 + :disabled="!!saveForm.id"
  107 + />
  108 + <el-tooltip
  109 + v-if="!saveForm.id"
  110 + class="item"
  111 + effect="light"
  112 + content="新建后,流程标识不可修改!"
  113 + placement="top"
  114 + >
  115 + <i style="padding-left: 5px" class="el-icon-question"></i>
  116 + </el-tooltip>
  117 + <el-tooltip
  118 + v-else
  119 + class="item"
  120 + effect="light"
  121 + content="流程标识不可修改!"
  122 + placement="top"
  123 + >
  124 + <i style="padding-left: 5px" class="el-icon-question"></i>
  125 + </el-tooltip>
  126 + </el-form-item>
  127 + <el-form-item label="流程名称" prop="name">
  128 + <el-input
  129 + v-model="saveForm.name"
  130 + placeholder="请输入流程名称"
  131 + :disabled="!!saveForm.id"
  132 + clearable
  133 + />
  134 + </el-form-item>
  135 + <el-form-item v-if="saveForm.id" label="流程分类" prop="category">
  136 + <el-select
  137 + v-model="saveForm.category"
  138 + placeholder="请选择流程分类"
  139 + clearable
  140 + style="width: 100%"
  141 + >
  142 + <el-option
  143 + v-for="dict in getDictOptions(DICT_TYPE.BPM_MODEL_CATEGORY)"
  144 + :key="dict.value"
  145 + :label="dict.label"
  146 + :value="dict.value"
  147 + />
  148 + </el-select>
  149 + </el-form-item>
  150 + <el-form-item label="流程描述" prop="description">
  151 + <el-input type="textarea" v-model="saveForm.description" clearable />
  152 + </el-form-item>
  153 + <div v-if="saveForm.id">
  154 + <el-form-item label="表单类型" prop="formType">
  155 + <el-radio-group v-model="saveForm.formType">
  156 + <el-radio
  157 + v-for="dict in getDictOptions(DICT_TYPE.BPM_MODEL_FORM_TYPE)"
  158 + :key="parseInt(dict.value)"
  159 + :label="parseInt(dict.value)"
  160 + >
  161 + {{ dict.label }}
  162 + </el-radio>
  163 + </el-radio-group>
  164 + </el-form-item>
  165 + <el-form-item v-if="saveForm.formType === 10" label="流程表单" prop="formId">
  166 + <el-select v-model="saveForm.formId" clearable style="width: 100%">
  167 + <el-option v-for="form in forms" :key="form.id" :label="form.name" :value="form.id" />
  168 + </el-select>
  169 + </el-form-item>
  170 + <el-form-item
  171 + v-if="saveForm.formType === 20"
  172 + label="表单提交路由"
  173 + prop="formCustomCreatePath"
  174 + >
  175 + <el-input
  176 + v-model="saveForm.formCustomCreatePath"
  177 + placeholder="请输入表单提交路由"
  178 + style="width: 330px"
  179 + />
  180 + <el-tooltip
  181 + class="item"
  182 + effect="light"
  183 + content="自定义表单的提交路径,使用 Vue 的路由地址,例如说:bpm/oa/leave/create"
  184 + placement="top"
  185 + >
  186 + <i style="padding-left: 5px" class="el-icon-question"></i>
  187 + </el-tooltip>
  188 + </el-form-item>
  189 + <el-form-item
  190 + v-if="saveForm.formType === 20"
  191 + label="表单查看路由"
  192 + prop="formCustomViewPath"
  193 + >
  194 + <el-input
  195 + v-model="saveForm.formCustomViewPath"
  196 + placeholder="请输入表单查看路由"
  197 + style="width: 330px"
  198 + />
  199 + <el-tooltip
  200 + class="item"
  201 + effect="light"
  202 + content="自定义表单的查看路径,使用 Vue 的路由地址,例如说:bpm/oa/leave/view"
  203 + placement="top"
  204 + >
  205 + <i style="padding-left: 5px" class="el-icon-question"></i>
  206 + </el-tooltip>
  207 + </el-form-item>
  208 + </div>
  209 + </el-form>
  210 + <template #footer>
  211 + <!-- 按钮:保存 -->
  212 + <XButton
  213 + type="primary"
  214 + :loading="dialogLoading"
  215 + @click="submitForm()"
  216 + :title="t('action.save')"
  217 + />
  218 + <!-- 按钮:关闭 -->
  219 + <XButton
  220 + :loading="dialogLoading"
  221 + @click="dialogVisible = false"
  222 + :title="t('dialog.close')"
  223 + />
  224 + </template>
  225 + </XModal>
  226 +
  227 + <!-- 导入流程 -->
  228 + <XModal v-model="importDialogVisible" width="400" title="导入流程">
  229 + <div>
  230 + <el-upload
  231 + ref="uploadRef"
  232 + :action="importUrl"
  233 + :headers="uploadHeaders"
  234 + :drag="true"
  235 + :limit="1"
  236 + :multiple="true"
  237 + :show-file-list="true"
  238 + :disabled="uploadDisabled"
  239 + :on-exceed="handleExceed"
  240 + :on-success="handleFileSuccess"
  241 + :on-error="excelUploadError"
  242 + :auto-upload="false"
  243 + accept=".bpmn, .xml"
  244 + name="bpmnFile"
  245 + :data="importForm"
  246 + >
  247 + <el-icon class="el-icon--upload"><upload-filled /></el-icon>
  248 + <div class="el-upload__text"> 将文件拖到此处,或 <em>点击上传</em> </div>
  249 + <template #tip>
  250 + <div class="el-upload__tip" style="color: red">
  251 + 提示:仅允许导入“bpm”或“xml”格式文件!
  252 + </div>
  253 + <div>
  254 + <el-form
  255 + ref="importFormRef"
  256 + :model="importForm"
  257 + :rules="rules"
  258 + label-width="120px"
  259 + status-icon
  260 + >
  261 + <el-form-item label="流程标识" prop="key">
  262 + <el-input
  263 + v-model="importForm.key"
  264 + placeholder="请输入流标标识"
  265 + style="width: 250px"
  266 + />
  267 + </el-form-item>
  268 + <el-form-item label="流程名称" prop="name">
  269 + <el-input v-model="importForm.name" placeholder="请输入流程名称" clearable />
  270 + </el-form-item>
  271 + <el-form-item label="流程描述" prop="description">
  272 + <el-input type="textarea" v-model="importForm.description" clearable />
  273 + </el-form-item>
  274 + </el-form>
  275 + </div>
  276 + </template>
  277 + </el-upload>
  278 + </div>
  279 + <template #footer>
  280 + <!-- 按钮:保存 -->
  281 + <XButton
  282 + type="warning"
  283 + preIcon="ep:upload-filled"
  284 + :title="t('action.save')"
  285 + @click="submitFileForm"
  286 + />
  287 + <XButton title="取 消" @click="uploadClose" />
  288 + </template>
  289 + </XModal>
  290 + </ContentWrap>
  291 +</template>
  292 +
  293 +<script setup lang="ts">
  294 +// 全局相关的 import
  295 +import { onMounted, ref, unref } from 'vue'
  296 +import { DICT_TYPE, getDictOptions } from '@/utils/dict'
  297 +import { FormInstance, UploadInstance } from 'element-plus'
  298 +
  299 +// 业务相关的 import
  300 +import { getAccessToken, getTenantId } from '@/utils/auth'
  301 +import * as FormApi from '@/api/bpm/form'
8 302 import * as ModelApi from '@/api/bpm/model'
  303 +import { allSchemas, rules } from './model.data'
9 304  
10 305 const { t } = useI18n() // 国际化
11   -const message = useMessage()
  306 +const message = useMessage() // 消息弹窗
  307 +const router = useRouter() // 路由
12 308  
13 309 // ========== 列表相关 ==========
14   -const { register, tableObject, methods } = useTable<ModelVO>({
15   - getListApi: ModelApi.getModelPageApi,
16   - delListApi: ModelApi.deleteModelApi
  310 +const [registerTable, { reload }] = useXTable({
  311 + allSchemas: allSchemas,
  312 + getListApi: ModelApi.getModelPageApi
17 313 })
18   -const { getList, setSearchParams, delList } = methods
  314 +const forms = ref() // 流程表单的下拉框的数据
  315 +
  316 +// 设计流程
  317 +const handleDesign = (row) => {
  318 + console.log(row, '设计流程')
  319 + router.push({
  320 + name: 'modelEditor',
  321 + query: {
  322 + modelId: row.id
  323 + }
  324 + })
  325 +}
  326 +
  327 +// 跳转到指定流程定义列表
  328 +const handleDefinitionList = (row) => {
  329 + router.push({
  330 + name: 'BpmProcessDefinitionList',
  331 + query: {
  332 + modelId: row.id
  333 + }
  334 + })
  335 +}
  336 +
  337 +// 流程表单的详情按钮操作
  338 +const handleFormDetail = (row) => {
  339 + // TODO 芋艿:表单组件开发中
  340 + console.log(row)
  341 + message.success('动态表单开发中,预计 2 月底完成')
  342 +}
  343 +
  344 +// 流程图的详情按钮操作
  345 +const handleBpmnDetail = (row) => {
  346 + // TODO 芋艿:流程组件开发中
  347 + console.log(row)
  348 + message.success('流程组件开发中,预计 2 月底完成')
  349 +}
  350 +
  351 +// 点击任务分配按钮
  352 +const handleAssignRule = (row) => {
  353 + router.push({
  354 + name: 'BpmTaskAssignRuleList',
  355 + query: {
  356 + modelId: row.id
  357 + }
  358 + })
  359 +}
19 360  
20   -// ========== CRUD 相关 ==========
21   -const actionLoading = ref(false) // 遮罩层
22   -const actionType = ref('') // 操作按钮的类型
23   -const dialogVisible = ref(false) // 是否显示弹出层
24   -const dialogTitle = ref('edit') // 弹出层标题
25   -const formRef = ref<FormExpose>() // 表单 Ref
  361 +// ========== 新建/修改流程 ==========
  362 +const dialogVisible = ref(false)
  363 +const dialogTitle = ref('新建模型')
  364 +const dialogLoading = ref(false)
  365 +const saveForm = ref({})
  366 +const saveFormRef = ref<FormInstance>()
26 367  
27 368 // 设置标题
28   -const setDialogTile = (type: string) => {
  369 +const setDialogTile = async (type: string) => {
29 370 dialogTitle.value = t('action.' + type)
30   - actionType.value = type
31 371 dialogVisible.value = true
32 372 }
33 373  
34 374 // 新增操作
35   -const handleCreate = () => {
36   - setDialogTile('create')
  375 +const handleCreate = async () => {
  376 + resetForm()
  377 + await setDialogTile('create')
37 378 }
38 379  
39 380 // 修改操作
40   -const handleUpdate = async (row: ModelVO) => {
41   - setDialogTile('update')
  381 +const handleUpdate = async (rowId: number) => {
  382 + resetForm()
  383 + await setDialogTile('create')
42 384 // 设置数据
43   - const res = await ModelApi.getModelApi(row.id)
44   - unref(formRef)?.setValues(res)
  385 + saveForm.value = await ModelApi.getModelApi(rowId)
45 386 }
46 387  
47 388 // 提交按钮
48 389 const submitForm = async () => {
49   - const elForm = unref(formRef)?.getElFormRef()
  390 + // 参数校验
  391 + const elForm = unref(saveFormRef)
50 392 if (!elForm) return
51   - elForm.validate(async (valid) => {
52   - if (valid) {
53   - actionLoading.value = true
54   - // 提交请求
55   - try {
56   - const data = unref(formRef)?.formModel as ModelVO
57   - if (actionType.value === 'create') {
58   - await ModelApi.createModelApi(data)
59   - message.success(t('common.createSuccess'))
60   - } else {
61   - await ModelApi.updateModelApi(data)
62   - message.success(t('common.updateSuccess'))
63   - }
64   - // 操作成功,重新加载列表
65   - dialogVisible.value = false
66   - await getList()
67   - } finally {
68   - actionLoading.value = false
69   - }
  393 + const valid = await elForm.validate()
  394 + if (!valid) return
  395 +
  396 + // 提交请求
  397 + dialogLoading.value = true
  398 + try {
  399 + const data = saveForm.value as ModelApi.ModelVO
  400 + if (!data.id) {
  401 + await ModelApi.createModelApi(data)
  402 + message.success(t('common.createSuccess'))
  403 + } else {
  404 + await ModelApi.updateModelApi(data)
  405 + message.success(t('common.updateSuccess'))
70 406 }
  407 + dialogVisible.value = false
  408 + } finally {
  409 + // 刷新列表
  410 + await reload()
  411 + dialogLoading.value = false
  412 + }
  413 +}
  414 +
  415 +// 重置表单
  416 +const resetForm = () => {
  417 + saveForm.value = {
  418 + formType: 10,
  419 + name: '',
  420 + courseSort: '',
  421 + description: '',
  422 + formId: '',
  423 + formCustomCreatePath: '',
  424 + formCustomViewPath: ''
  425 + }
  426 + saveFormRef.value?.resetFields()
  427 +}
  428 +
  429 +// ========== 删除 / 更新状态 / 发布流程 ==========
  430 +// 删除流程
  431 +const handleDelete = (rowId) => {
  432 + message.delConfirm('是否删除该流程!!').then(async () => {
  433 + await ModelApi.deleteModelApi(rowId)
  434 + message.success(t('common.delSuccess'))
  435 + // 刷新列表
  436 + reload()
71 437 })
72 438 }
73 439  
74   -/** 流程表单的详情按钮操作 */
75   -const handleChangeState = async (row: ModelVO) => {
  440 +// 更新状态操作
  441 +const handleChangeState = (row) => {
  442 + const id = row.id
76 443 const state = row.processDefinition.suspensionState
77 444 const statusState = state === 1 ? '激活' : '挂起'
  445 + const content = '是否确认' + statusState + '流程名字为"' + row.name + '"的数据项?'
78 446 message
79   - .confirm(
80   - '是否确认' + statusState + '流程名字为"' + row.name + '"的数据项?',
81   - t('common.reminder')
82   - )
  447 + .confirm(content)
83 448 .then(async () => {
84   - ModelApi.updateModelStateApi(row.id, state).then(() => {
85   - message.success(t('common.updateSuccess'))
86   - getList()
87   - })
  449 + await ModelApi.updateModelStateApi(id, state)
  450 + message.success(t('部署成功'))
  451 + // 刷新列表
  452 + reload()
  453 + })
  454 + .catch(() => {
  455 + // 取消后,进行恢复按钮
  456 + row.processDefinition.suspensionState = state === 1 ? 2 : 1
88 457 })
89   - .catch(() => {})
90 458 }
91   -// ========== 详情相关 ==========
92   -const detailData = ref() // 详情 Ref
93 459  
94   -// 详情操作
95   -const handleDetail = async (row: ModelVO) => {
96   - // 设置数据
97   - detailData.value = row
98   - setDialogTile('detail')
  460 +// 发布流程
  461 +const handleDeploy = (row) => {
  462 + message.confirm('是否部署该流程!!').then(async () => {
  463 + await ModelApi.deployModelApi(row.id)
  464 + message.success(t('部署成功'))
  465 + // 刷新列表
  466 + reload()
  467 + })
99 468 }
100 469  
101   -// ========== 初始化 ==========
102   -getList()
103   -</script>
  470 +// ========== 导入流程 ==========
  471 +const uploadRef = ref<UploadInstance>()
  472 +let importUrl = import.meta.env.VITE_BASE_URL + import.meta.env.VITE_API_URL + '/bpm/model/import'
  473 +const uploadHeaders = ref()
  474 +const importDialogVisible = ref(false)
  475 +const uploadDisabled = ref(false)
  476 +const importFormRef = ref<FormInstance>()
  477 +const importForm = ref({
  478 + key: '',
  479 + name: '',
  480 + description: ''
  481 +})
104 482  
105   -<template>
106   - <!-- 搜索工作区 -->
107   - <ContentWrap>
108   - <Search :schema="allSchemas.searchSchema" @search="setSearchParams" @reset="setSearchParams" />
109   - </ContentWrap>
110   - <ContentWrap>
111   - <!-- 操作工具栏 -->
112   - <div class="mb-10px">
113   - <el-button type="primary" v-hasPermi="['bpm:model:create']" @click="handleCreate()">
114   - <Icon icon="ep:zoom-in" class="mr-5px" /> {{ t('action.add') }}
115   - </el-button>
116   - </div>
117   - <!-- 列表 -->
118   - <Table
119   - :columns="allSchemas.tableColumns"
120   - :selection="false"
121   - :data="tableObject.tableList"
122   - :loading="tableObject.loading"
123   - :pagination="{
124   - total: tableObject.total
125   - }"
126   - v-model:pageSize="tableObject.pageSize"
127   - v-model:currentPage="tableObject.currentPage"
128   - @register="register"
129   - >
130   - <template #category="{ row }">
131   - <DictTag :type="DICT_TYPE.BPM_MODEL_CATEGORY" :value="row.category" />
132   - </template>
133   - <template #formId="{ row }">
134   - <span>{{ row.formName }}</span>
135   - </template>
136   - <template #processDefinition>
137   - <el-table-column label="流程版本" prop="processDefinition.version">
138   - <template #default="{ row }">
139   - <el-tag v-if="row.processDefinition">
140   - {{ 'v' + row.processDefinition.version }}
141   - </el-tag>
142   - <el-tag type="warning" v-else>未部署</el-tag>
143   - </template>
144   - </el-table-column>
145   - <el-table-column label="激活状态" prop="processDefinition.suspensionState">
146   - <template #default="{ row }">
147   - <el-switch
148   - v-if="row.processDefinition"
149   - v-model="row.processDefinition.suspensionState"
150   - :active-value="1"
151   - :inactive-value="2"
152   - @change="handleChangeState(row)"
153   - />
154   - </template>
155   - </el-table-column>
156   - <el-table-column label="部署时间" prop="processDefinition.deploymentTime">
157   - <template #default="{ row }">
158   - <span>
159   - {{ dayjs(row.processDefinition.deploymentTime).format('YYYY-MM-DD HH:mm:ss') }}
160   - </span>
161   - </template>
162   - </el-table-column>
163   - </template>
164   - <template #createTime="{ row }">
165   - <span>{{ dayjs(row.createTime).format('YYYY-MM-DD HH:mm:ss') }}</span>
166   - </template>
167   - <template #action="{ row }">
168   - <el-button link type="primary" v-hasPermi="['bpm:model:update']" @click="handleUpdate(row)">
169   - <Icon icon="ep:edit" class="mr-1px" /> {{ t('action.edit') }}
170   - </el-button>
171   - <el-button link type="primary" v-hasPermi="['bpm:model:update']" @click="handleDetail(row)">
172   - <Icon icon="ep:view" class="mr-1px" /> {{ t('action.detail') }}
173   - </el-button>
174   - <el-button
175   - link
176   - type="primary"
177   - v-hasPermi="['bpm:model:delete']"
178   - @click="delList(row.id, false)"
179   - >
180   - <Icon icon="ep:delete" class="mr-1px" /> {{ t('action.del') }}
181   - </el-button>
182   - </template>
183   - </Table>
184   - </ContentWrap>
  483 +// 导入流程弹窗显示
  484 +const handleImport = () => {
  485 + importDialogVisible.value = true
  486 +}
  487 +// 文件数超出提示
  488 +const handleExceed = (): void => {
  489 + message.error('最多只能上传一个文件!')
  490 +}
  491 +// 上传错误提示
  492 +const excelUploadError = (): void => {
  493 + message.error('导入流程失败,请您重新上传!')
  494 +}
185 495  
186   - <XModal v-model="dialogVisible" :title="dialogTitle">
187   - <!-- 对话框(添加 / 修改) -->
188   - <Form
189   - v-if="['create', 'update'].includes(actionType)"
190   - :schema="allSchemas.formSchema"
191   - :rules="rules"
192   - ref="formRef"
193   - />
194   - <!-- 对话框(详情) -->
195   - <Descriptions
196   - v-if="actionType === 'detail'"
197   - :schema="allSchemas.detailSchema"
198   - :data="detailData"
199   - />
200   - <!-- 操作按钮 -->
201   - <template #footer>
202   - <!-- 按钮:保存 -->
203   - <XButton
204   - v-if="['create', 'update'].includes(actionType)"
205   - type="primary"
206   - :title="t('action.save')"
207   - :loading="actionLoading"
208   - @click="submitForm()"
209   - />
210   - <!-- 按钮:关闭 -->
211   - <XButton :loading="actionLoading" :title="t('dialog.close')" @click="dialogVisible = false" />
212   - </template>
213   - </XModal>
214   -</template>
  496 +// 提交文件上传
  497 +const submitFileForm = () => {
  498 + uploadHeaders.value = {
  499 + Authorization: 'Bearer ' + getAccessToken(),
  500 + 'tenant-id': getTenantId()
  501 + }
  502 + uploadDisabled.value = true
  503 + uploadRef.value!.submit()
  504 +}
  505 +// 文件上传成功
  506 +const handleFileSuccess = async (response: any): Promise<void> => {
  507 + if (response.code !== 0) {
  508 + message.error(response.msg)
  509 + return
  510 + }
  511 + // 重置表单
  512 + uploadClose()
  513 + // 提示,并刷新
  514 + message.success('导入流程成功!请点击【设计流程】按钮,进行编辑保存后,才可以进行【发布流程】')
  515 + await reload()
  516 +}
  517 +// 关闭文件上传
  518 +const uploadClose = () => {
  519 + // 关闭弹窗
  520 + importDialogVisible.value = false
  521 + // 重置上传状态和文件
  522 + uploadDisabled.value = false
  523 + uploadRef.value!.clearFiles()
  524 + // 重置表单
  525 + importForm.value = {
  526 + key: '',
  527 + name: '',
  528 + description: ''
  529 + }
  530 + importFormRef.value?.resetFields()
  531 +}
  532 +
  533 +// ========== 初始化 ==========
  534 +onMounted(() => {
  535 + // 获得流程表单的下拉框的数据
  536 + FormApi.getSimpleFormsApi().then((data) => {
  537 + forms.value = data
  538 + })
  539 +})
  540 +</script>
... ...
yudao-ui-admin-vue3/src/views/bpm/model/model.data.ts
1   -import { CrudSchema, useCrudSchemas } from '@/hooks/web/useCrudSchemas'
  1 +import { reactive } from 'vue'
  2 +import { useI18n } from '@/hooks/web/useI18n'
  3 +import { required } from '@/utils/formRules'
  4 +import { VxeCrudSchema, useVxeCrudSchemas } from '@/hooks/web/useVxeCrudSchemas'
  5 +
  6 +import { DICT_TYPE } from '@/utils/dict'
2 7 const { t } = useI18n() // 国际化
3 8  
4 9 // 表单校验
5 10 export const rules = reactive({
6   - name: [required]
  11 + key: [required],
  12 + name: [required],
  13 + category: [required],
  14 + formType: [required],
  15 + formId: [required],
  16 + formCustomCreatePath: [required],
  17 + formCustomViewPath: [required]
7 18 })
8 19  
9 20 // CrudSchema
10   -const crudSchemas = reactive<CrudSchema[]>([
11   - {
12   - label: t('common.index'),
13   - field: 'id',
14   - type: 'index',
15   - form: {
16   - show: false
  21 +const crudSchemas = reactive<VxeCrudSchema>({
  22 + primaryKey: 'key',
  23 + primaryType: null,
  24 + action: true,
  25 + actionWidth: '540px',
  26 + columns: [
  27 + {
  28 + title: '流程标识',
  29 + field: 'key',
  30 + isSearch: true,
  31 + table: {
  32 + width: 120
  33 + }
17 34 },
18   - detail: {
19   - show: false
20   - }
21   - },
22   - {
23   - label: '流程标识',
24   - field: 'key',
25   - search: {
26   - show: true
27   - }
28   - },
29   - {
30   - label: '流程名称',
31   - field: 'name',
32   - search: {
33   - show: true
34   - }
35   - },
36   - {
37   - label: '流程分类',
38   - field: 'category',
39   - dictType: DICT_TYPE.BPM_MODEL_CATEGORY,
40   - dictClass: 'number',
41   - search: {
42   - show: true
43   - }
44   - },
45   - {
46   - label: '表单信息',
47   - field: 'formId'
48   - },
49   - {
50   - label: '最新部署的流程定义',
51   - field: 'processDefinition',
52   - form: {
53   - show: false
  35 + {
  36 + title: '流程名称',
  37 + field: 'name',
  38 + isSearch: true,
  39 + table: {
  40 + width: 120,
  41 + slots: {
  42 + default: 'name_default'
  43 + }
  44 + }
54 45 },
55   - detail: {
56   - show: false
57   - }
58   - },
59   - {
60   - label: t('common.createTime'),
61   - field: 'createTime',
62   - form: {
63   - show: false
64   - }
65   - },
66   - {
67   - label: t('table.action'),
68   - field: 'action',
69   - width: '240px',
70   - form: {
71   - show: false
  46 + {
  47 + title: '流程分类',
  48 + field: 'category',
  49 + dictType: DICT_TYPE.BPM_MODEL_CATEGORY,
  50 + dictClass: 'number',
  51 + isSearch: true
  52 + },
  53 + {
  54 + title: '表单信息',
  55 + field: 'formId',
  56 + table: {
  57 + width: 120,
  58 + slots: {
  59 + default: 'formId_default'
  60 + }
  61 + }
72 62 },
73   - detail: {
74   - show: false
  63 + {
  64 + title: '最新部署的流程定义',
  65 + field: 'processDefinition',
  66 + isForm: false,
  67 + table: {
  68 + children: [
  69 + {
  70 + title: '流程版本',
  71 + field: 'version',
  72 + slots: {
  73 + default: 'version_default'
  74 + },
  75 + width: 80
  76 + },
  77 + {
  78 + title: '激活状态',
  79 + field: 'status',
  80 + slots: {
  81 + default: 'status_default'
  82 + },
  83 + width: 80
  84 + },
  85 + {
  86 + title: '部署时间',
  87 + field: 'processDefinition.deploymentTime',
  88 + formatter: 'formatDate',
  89 + width: 180
  90 + }
  91 + ]
  92 + }
  93 + },
  94 + {
  95 + title: t('common.createTime'),
  96 + field: 'createTime',
  97 + isForm: false,
  98 + formatter: 'formatDate',
  99 + table: {
  100 + width: 180
  101 + }
75 102 }
76   - }
77   -])
78   -export const { allSchemas } = useCrudSchemas(crudSchemas)
  103 + ]
  104 +})
  105 +export const { allSchemas } = useVxeCrudSchemas(crudSchemas)
... ...