提交 | 用户 | 时间
820397 1 <template>
H 2   <Dialog v-model="dialogVisible" :title="dialogTitle" width="600">
3     <el-form
4       ref="formRef"
5       v-loading="formLoading"
6       :model="formData"
7       :rules="formRules"
8       label-width="110px"
9     >
10       <el-form-item label="流程标识" prop="key">
3e359e 11         <el-input v-model="formData.key" :disabled="!!formData.id" placeholder="请输入流标标识" />
820397 12         <el-tooltip
H 13           v-if="!formData.id"
14           class="item"
15           content="新建后,流程标识不可修改!"
16           effect="light"
17           placement="top"
18         >
19           <i class="el-icon-question" style="padding-left: 5px"></i>
20         </el-tooltip>
21         <el-tooltip v-else class="item" content="流程标识不可修改!" effect="light" placement="top">
22           <i class="el-icon-question" style="padding-left: 5px"></i>
23         </el-tooltip>
24       </el-form-item>
25       <el-form-item label="流程名称" prop="name">
26         <el-input
27           v-model="formData.name"
28           :disabled="!!formData.id"
29           clearable
30           placeholder="请输入流程名称"
31         />
32       </el-form-item>
3e359e 33       <el-form-item label="流程分类" prop="category">
820397 34         <el-select
H 35           v-model="formData.category"
36           clearable
37           placeholder="请选择流程分类"
38           style="width: 100%"
39         >
40           <el-option
41             v-for="category in categoryList"
42             :key="category.code"
43             :label="category.name"
44             :value="category.code"
45           />
46         </el-select>
47       </el-form-item>
3e359e 48       <el-form-item label="流程图标" prop="icon">
H 49         <UploadImg v-model="formData.icon" :limit="1" height="64px" width="64px" />
820397 50       </el-form-item>
H 51       <el-form-item label="流程描述" prop="description">
52         <el-input v-model="formData.description" clearable type="textarea" />
53       </el-form-item>
3e359e 54       <el-form-item label="流程类型" prop="type">
H 55         <el-radio-group v-model="formData.type">
56           <el-radio
57             v-for="dict in getIntDictOptions(DICT_TYPE.BPM_MODEL_TYPE)"
58             :key="dict.value"
59             :label="dict.value"
820397 60           >
3e359e 61             {{ dict.label }}
H 62           </el-radio>
63         </el-radio-group>
64       </el-form-item>
65       <el-form-item label="表单类型" prop="formType">
66         <el-radio-group v-model="formData.formType">
67           <el-radio
68             v-for="dict in getIntDictOptions(DICT_TYPE.BPM_MODEL_FORM_TYPE)"
69             :key="dict.value"
70             :label="dict.value"
820397 71           >
3e359e 72             {{ dict.label }}
H 73           </el-radio>
74         </el-radio-group>
75       </el-form-item>
76       <el-form-item v-if="formData.formType === 10" label="流程表单" prop="formId">
77         <el-select v-model="formData.formId" clearable style="width: 100%">
78           <el-option v-for="form in formList" :key="form.id" :label="form.name" :value="form.id" />
79         </el-select>
80       </el-form-item>
81       <el-form-item
82         v-if="formData.formType === 20"
83         label="表单提交路由"
84         prop="formCustomCreatePath"
85       >
86         <el-input
87           v-model="formData.formCustomCreatePath"
88           placeholder="请输入表单提交路由"
89           style="width: 330px"
90         />
91         <el-tooltip
92           class="item"
93           content="自定义表单的提交路径,使用 Vue 的路由地址,例如说:bpm/oa/leave/create.vue"
94           effect="light"
95           placement="top"
96         >
97           <i class="el-icon-question" style="padding-left: 5px"></i>
98         </el-tooltip>
99       </el-form-item>
100       <el-form-item v-if="formData.formType === 20" label="表单查看地址" prop="formCustomViewPath">
101         <el-input
102           v-model="formData.formCustomViewPath"
103           placeholder="请输入表单查看的组件地址"
104           style="width: 330px"
105         />
106         <el-tooltip
107           class="item"
108           content="自定义表单的查看组件地址,使用 Vue 的组件地址,例如说:bpm/oa/leave/detail.vue"
109           effect="light"
110           placement="top"
111         >
112           <i class="el-icon-question" style="padding-left: 5px"></i>
113         </el-tooltip>
114       </el-form-item>
115       <el-form-item label="是否可见" prop="visible">
116         <el-radio-group v-model="formData.visible">
117           <el-radio
118             v-for="dict in getBoolDictOptions(DICT_TYPE.INFRA_BOOLEAN_STRING)"
119             :key="dict.value as string"
120             :label="dict.value"
121           >
122             {{ dict.label }}
123           </el-radio>
124         </el-radio-group>
125       </el-form-item>
126       <el-form-item label="谁可以发起" prop="startUserIds">
127         <el-select
128           v-model="formData.startUserIds"
129           multiple
130           placeholder="请选择可发起人,默认(不选择)则所有人都可以发起"
131         >
132           <el-option
133             v-for="user in userList"
134             :key="user.id"
135             :label="user.nickname"
136             :value="user.id"
137           />
138         </el-select>
139       </el-form-item>
140       <el-form-item label="流程管理员" prop="managerUserIds">
141         <el-select v-model="formData.managerUserIds" multiple placeholder="请选择流程管理员">
142           <el-option
143             v-for="user in userList"
144             :key="user.id"
145             :label="user.nickname"
146             :value="user.id"
147           />
148         </el-select>
149       </el-form-item>
820397 150     </el-form>
H 151     <template #footer>
152       <el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
153       <el-button @click="dialogVisible = false">取 消</el-button>
154     </template>
155   </Dialog>
156 </template>
157 <script lang="ts" setup>
3e359e 158 import { propTypes } from '@/utils/propTypes'
H 159 import { DICT_TYPE, getBoolDictOptions, getIntDictOptions } from '@/utils/dict'
820397 160 import { ElMessageBox } from 'element-plus'
H 161 import * as ModelApi from '@/api/bpm/model'
162 import * as FormApi from '@/api/bpm/form'
163 import { CategoryApi } from '@/api/bpm/category'
3e359e 164 import { BpmModelFormType, BpmModelType } from '@/utils/constants'
H 165 import { UserVO } from '@/api/system/user'
166 import * as UserApi from '@/api/system/user'
167 import { useUserStoreWithOut } from '@/store/modules/user'
820397 168
H 169 defineOptions({ name: 'ModelForm' })
170
171 const { t } = useI18n() // 国际化
172 const message = useMessage() // 消息弹窗
3e359e 173 const userStore = useUserStoreWithOut() // 用户信息缓存
H 174 const props = defineProps({
175   categoryId: propTypes.number
176 })
820397 177 const dialogVisible = ref(false) // 弹窗的是否展示
H 178 const dialogTitle = ref('') // 弹窗的标题
179 const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
180 const formType = ref('') // 表单的类型:create - 新增;update - 修改
181 const formData = ref({
3e359e 182   id: undefined,
820397 183   name: '',
3e359e 184   key: '',
820397 185   category: undefined,
H 186   icon: undefined,
187   description: '',
3e359e 188   type: BpmModelType.BPMN,
H 189   formType: BpmModelFormType.NORMAL,
820397 190   formId: '',
H 191   formCustomCreatePath: '',
3e359e 192   formCustomViewPath: '',
H 193   visible: true,
194   startUserIds: [],
195   managerUserIds: []
820397 196 })
H 197 const formRules = reactive({
3e359e 198   name: [{ required: true, message: '流程名称不能为空', trigger: 'blur' }],
H 199   key: [{ required: true, message: '流程标识不能为空', trigger: 'blur' }],
200   category: [{ required: true, message: '流程分类不能为空', trigger: 'blur' }],
201   icon: [{ required: true, message: '流程图标不能为空', trigger: 'blur' }],
202   type: [{ required: true, message: '是否可见不能为空', trigger: 'blur' }],
203   formType: [{ required: true, message: '是否可见不能为空', trigger: 'blur' }],
204   formId: [{ required: true, message: '流程表单不能为空', trigger: 'blur' }],
205   formCustomCreatePath: [{ required: true, message: '表单提交路由不能为空', trigger: 'blur' }],
206   formCustomViewPath: [{ required: true, message: '表单查看地址不能为空', trigger: 'blur' }],
207   visible: [{ required: true, message: '是否可见不能为空', trigger: 'blur' }],
208   managerUserIds: [{ required: true, message: '流程管理员不能为空', trigger: 'blur' }]
820397 209 })
H 210 const formRef = ref() // 表单 Ref
211 const formList = ref([]) // 流程表单的下拉框的数据
212 const categoryList = ref([]) // 流程分类列表
3e359e 213 const userList = ref<UserVO[]>([]) // 用户列表
820397 214
H 215 /** 打开弹窗 */
3e359e 216 const open = async (type: string, id?: string) => {
820397 217   dialogVisible.value = true
H 218   dialogTitle.value = t('action.' + type)
219   formType.value = type
220   resetForm()
221   // 修改时,设置数据
222   if (id) {
223     formLoading.value = true
224     try {
225       formData.value = await ModelApi.getModel(id)
226     } finally {
227       formLoading.value = false
228     }
3e359e 229   } else {
H 230     formData.value.managerUserIds.push(userStore.getUser.id)
820397 231   }
H 232   // 获得流程表单的下拉框的数据
233   formList.value = await FormApi.getFormSimpleList()
234   // 查询流程分类列表
235   categoryList.value = await CategoryApi.getCategorySimpleList()
3e359e 236   // 查询用户列表
H 237   userList.value = await UserApi.getSimpleUserList()
238   if (props.categoryId) {
239     formData.value.category = props.categoryId
240   }
820397 241 }
H 242 defineExpose({ open }) // 提供 open 方法,用于打开弹窗
243
244 /** 提交表单 */
245 const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
246 const submitForm = async () => {
247   // 校验表单
248   if (!formRef) return
249   const valid = await formRef.value.validate()
250   if (!valid) return
251   // 提交请求
252   formLoading.value = true
253   try {
254     const data = formData.value as unknown as ModelApi.ModelVO
255     if (formType.value === 'create') {
256       await ModelApi.createModel(data)
257       // 提示,引导用户做后续的操作
258       await ElMessageBox.alert(
3e359e 259         '<strong>新建模型成功!</strong>后续需要执行如下 2 个步骤:' +
H 260           '<div>1. 点击【设计流程】按钮,绘制流程图</div>' +
261           '<div>2. 点击【发布流程】按钮,完成流程的最终发布</div>' +
820397 262           '另外,每次流程修改后,都需要点击【发布流程】按钮,才能正式生效!!!',
H 263         '重要提示',
264         {
265           dangerouslyUseHTMLString: true,
266           type: 'success'
267         }
268       )
269     } else {
270       await ModelApi.updateModel(data)
271       message.success(t('common.updateSuccess'))
272     }
273     dialogVisible.value = false
274     // 发送操作成功的事件
275     emit('success')
276   } finally {
277     formLoading.value = false
278   }
279 }
280
281 /** 重置表单 */
282 const resetForm = () => {
283   formData.value = {
3e359e 284     id: undefined,
820397 285     name: '',
3e359e 286     key: '',
820397 287     category: undefined,
3e359e 288     icon: undefined,
820397 289     description: '',
3e359e 290     type: BpmModelType.BPMN,
H 291     formType: BpmModelFormType.NORMAL,
820397 292     formId: '',
H 293     formCustomCreatePath: '',
3e359e 294     formCustomViewPath: '',
H 295     visible: true,
296     startUserIds: [],
297     managerUserIds: []
820397 298   }
H 299   formRef.value?.resetFields()
300 }
301 </script>