From a1d7e81859f554f3a53680cc35f0f49bf1f77098 Mon Sep 17 00:00:00 2001
From: wwf <1971391498@qq.com>
Date: 星期四, 14 五月 2026 14:37:02 +0800
Subject: [PATCH] 导入项目
---
src/views/bpm/model/form/BasicInfo.vue | 360 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 360 insertions(+), 0 deletions(-)
diff --git a/src/views/bpm/model/form/BasicInfo.vue b/src/views/bpm/model/form/BasicInfo.vue
new file mode 100644
index 0000000..b937b61
--- /dev/null
+++ b/src/views/bpm/model/form/BasicInfo.vue
@@ -0,0 +1,360 @@
+<template>
+ <el-form ref="formRef" :model="modelData" :rules="rules" label-width="120px" class="mt-20px">
+ <el-form-item label="娴佺▼鏍囪瘑" prop="key" class="mb-20px">
+ <div class="flex items-center">
+ <el-input
+ class="!w-440px"
+ v-model="modelData.key"
+ :disabled="!!modelData.id"
+ placeholder="璇疯緭鍏ユ祦绋嬫爣璇嗭紝浠ュ瓧姣嶆垨涓嬪垝绾垮紑澶�"
+ />
+ <el-tooltip
+ class="item"
+ :content="modelData.id ? '娴佺▼鏍囪瘑涓嶅彲淇敼锛�' : '鏂板缓鍚庯紝娴佺▼鏍囪瘑涓嶅彲淇敼锛�'"
+ effect="light"
+ placement="top"
+ >
+ <Icon icon="ep:question-filled" class="ml-5px" />
+ </el-tooltip>
+ </div>
+ </el-form-item>
+ <el-form-item label="娴佺▼鍚嶇О" prop="name" class="mb-20px">
+ <el-input
+ v-model="modelData.name"
+ :disabled="!!modelData.id"
+ clearable
+ placeholder="璇疯緭鍏ユ祦绋嬪悕绉�"
+ />
+ </el-form-item>
+ <el-form-item label="娴佺▼鍒嗙被" prop="category" class="mb-20px">
+ <el-select
+ class="!w-full"
+ v-model="modelData.category"
+ clearable
+ placeholder="璇烽�夋嫨娴佺▼鍒嗙被"
+ >
+ <el-option
+ v-for="category in categoryList"
+ :key="category.code"
+ :label="category.name"
+ :value="category.code"
+ />
+ </el-select>
+ </el-form-item>
+ <el-form-item label="娴佺▼鍥炬爣" class="mb-20px">
+ <UploadImg v-model="modelData.icon" :limit="1" height="64px" width="64px" />
+ </el-form-item>
+ <el-form-item label="娴佺▼鎻忚堪" prop="description" class="mb-20px">
+ <el-input v-model="modelData.description" clearable type="textarea" />
+ </el-form-item>
+ <el-form-item label="娴佺▼绫诲瀷" prop="type" class="mb-20px">
+ <el-radio-group v-model="modelData.type">
+ <el-radio
+ v-for="dict in getIntDictOptions(DICT_TYPE.BPM_MODEL_TYPE)"
+ :key="dict.value"
+ :value="dict.value"
+ >
+ {{ dict.label }}
+ </el-radio>
+ </el-radio-group>
+ </el-form-item>
+ <el-form-item label="鏄惁鍙" prop="visible" class="mb-20px">
+ <el-radio-group v-model="modelData.visible">
+ <el-radio
+ v-for="dict in getBoolDictOptions(DICT_TYPE.INFRA_BOOLEAN_STRING)"
+ :key="dict.value as string"
+ :value="dict.value"
+ >
+ {{ dict.label }}
+ </el-radio>
+ </el-radio-group>
+ </el-form-item>
+ <el-form-item label="璋佸彲浠ュ彂璧�" prop="startUserType" class="mb-20px">
+ <el-select
+ v-model="modelData.startUserType"
+ placeholder="璇烽�夋嫨璋佸彲浠ュ彂璧�"
+ @change="handleStartUserTypeChange"
+ >
+ <el-option label="鍏ㄥ憳" :value="0" />
+ <el-option label="鎸囧畾浜哄憳" :value="1" />
+ <el-option label="鎸囧畾閮ㄩ棬" :value="2" />
+ </el-select>
+ <div v-if="modelData.startUserType === 1" class="mt-2 flex flex-wrap gap-2">
+ <div
+ v-for="user in selectedStartUsers"
+ :key="user.id"
+ class="bg-gray-100 h-35px rounded-3xl flex items-center pr-8px dark:color-gray-600 position-relative"
+ >
+ <el-avatar class="!m-5px" :size="28" v-if="user.avatar" :src="user.avatar" />
+ <el-avatar class="!m-5px" :size="28" v-else>
+ {{ user.nickname.substring(0, 1) }}
+ </el-avatar>
+ {{ user.nickname }}
+ <Icon
+ icon="ep:close"
+ class="ml-2 cursor-pointer hover:text-red-500"
+ @click="handleRemoveStartUser(user)"
+ />
+ </div>
+ <el-button type="primary" link @click="openStartUserSelect">
+ <Icon icon="ep:plus" /> 閫夋嫨浜哄憳
+ </el-button>
+ </div>
+ <div v-if="modelData.startUserType === 2" class="mt-2 flex flex-wrap gap-2">
+ <div
+ v-for="dept in selectedStartDepts"
+ :key="dept.id"
+ class="bg-gray-100 h-35px rounded-3xl flex items-center pr-8px dark:color-gray-600 position-relative"
+ >
+ <Icon icon="ep:office-building" class="!m-5px text-20px" />
+ {{ dept.name }}
+ <Icon
+ icon="ep:close"
+ class="ml-2 cursor-pointer hover:text-red-500"
+ @click="handleRemoveStartDept(dept)"
+ />
+ </div>
+ <el-button type="primary" link @click="openStartDeptSelect">
+ <Icon icon="ep:plus" /> 閫夋嫨閮ㄩ棬
+ </el-button>
+ </div>
+ </el-form-item>
+ <el-form-item label="娴佺▼绠$悊鍛�" prop="managerUserIds" class="mb-20px">
+ <div class="flex flex-wrap gap-2">
+ <div
+ v-for="user in selectedManagerUsers"
+ :key="user.id"
+ class="bg-gray-100 h-35px rounded-3xl flex items-center pr-8px dark:color-gray-600 position-relative"
+ >
+ <el-avatar class="!m-5px" :size="28" v-if="user.avatar" :src="user.avatar" />
+ <el-avatar class="!m-5px" :size="28" v-else>
+ {{ user.nickname.substring(0, 1) }}
+ </el-avatar>
+ {{ user.nickname }}
+ <Icon
+ icon="ep:close"
+ class="ml-2 cursor-pointer hover:text-red-500"
+ @click="handleRemoveManagerUser(user)"
+ />
+ </div>
+ <el-button type="primary" link @click="openManagerUserSelect">
+ <Icon icon="ep:plus" />閫夋嫨浜哄憳
+ </el-button>
+ </div>
+ </el-form-item>
+ </el-form>
+
+ <!-- 鐢ㄦ埛閫夋嫨寮圭獥 -->
+ <UserSelectForm ref="userSelectFormRef" @confirm="handleUserSelectConfirm" />
+ <!-- 閮ㄩ棬閫夋嫨寮圭獥 -->
+ <DeptSelectForm
+ ref="deptSelectFormRef"
+ :multiple="true"
+ :check-strictly="true"
+ @confirm="handleDeptSelectConfirm"
+ />
+</template>
+
+<script lang="ts" setup>
+import { DICT_TYPE, getBoolDictOptions, getIntDictOptions } from '@/utils/dict'
+import { UserVO } from '@/api/system/user'
+import { DeptVO } from '@/api/system/dept'
+import { CategoryVO } from '@/api/bpm/category'
+
+const props = defineProps({
+ categoryList: {
+ type: Array as PropType<CategoryVO[]>,
+ required: true
+ },
+ userList: {
+ type: Array,
+ required: true
+ },
+ deptList: {
+ type: Array,
+ required: true
+ }
+})
+
+const formRef = ref()
+const selectedStartUsers = ref<UserVO[]>([])
+const selectedStartDepts = ref<DeptVO[]>([])
+const selectedManagerUsers = ref<UserVO[]>([])
+const userSelectFormRef = ref()
+const deptSelectFormRef = ref()
+const currentSelectType = ref<'start' | 'manager'>('start')
+
+const rules = {
+ name: [{ required: true, message: '娴佺▼鍚嶇О涓嶈兘涓虹┖', trigger: 'blur' }],
+ key: [
+ { required: true, message: '娴佺▼鏍囪瘑涓嶈兘涓虹┖', trigger: 'blur' },
+ {
+ validator: (_rule: any, value: string, callback: any) => {
+ if (!value) {
+ callback()
+ return
+ }
+ if (!/^[a-zA-Z_][\-_.0-9_a-zA-Z$]*$/.test(value)) {
+ callback(new Error('鍙兘鍖呭惈瀛楁瘝銆佹暟瀛椼�佷笅鍒掔嚎銆佽繛瀛楃鍜岀偣鍙凤紝涓斿繀椤讳互瀛楁瘝鎴栦笅鍒掔嚎寮�澶�'))
+ return
+ }
+ callback()
+ },
+ trigger: 'blur'
+ }
+ ],
+ category: [{ required: true, message: '娴佺▼鍒嗙被涓嶈兘涓虹┖', trigger: 'blur' }],
+ type: [{ required: true, message: '鏄惁鍙涓嶈兘涓虹┖', trigger: 'blur' }],
+ visible: [{ required: true, message: '鏄惁鍙涓嶈兘涓虹┖', trigger: 'blur' }],
+ managerUserIds: [{ required: true, message: '娴佺▼绠$悊鍛樹笉鑳戒负绌�', trigger: 'blur' }]
+}
+
+// 鍒涘缓鏈湴鏁版嵁鍓湰
+const modelData = defineModel<any>()
+
+// 鍒濆鍖栭�変腑鐨勭敤鎴�
+watch(
+ () => modelData.value,
+ (newVal) => {
+ if (newVal.startUserIds?.length) {
+ selectedStartUsers.value = props.userList.filter((user: UserVO) =>
+ newVal.startUserIds.includes(user.id)
+ ) as UserVO[]
+ } else {
+ selectedStartUsers.value = []
+ }
+ if (newVal.startDeptIds?.length) {
+ selectedStartDepts.value = props.deptList.filter((dept: DeptVO) =>
+ newVal.startDeptIds.includes(dept.id)
+ ) as DeptVO[]
+ } else {
+ selectedStartDepts.value = []
+ }
+ if (newVal.managerUserIds?.length) {
+ selectedManagerUsers.value = props.userList.filter((user: UserVO) =>
+ newVal.managerUserIds.includes(user.id)
+ ) as UserVO[]
+ } else {
+ selectedManagerUsers.value = []
+ }
+ },
+ {
+ immediate: true
+ }
+)
+
+/** 鎵撳紑鍙戣捣浜洪�夋嫨 */
+const openStartUserSelect = () => {
+ currentSelectType.value = 'start'
+ userSelectFormRef.value.open(0, selectedStartUsers.value)
+}
+
+/** 鎵撳紑閮ㄩ棬閫夋嫨 */
+const openStartDeptSelect = () => {
+ deptSelectFormRef.value.open(selectedStartDepts.value)
+}
+
+/** 鎵撳紑绠$悊鍛橀�夋嫨 */
+const openManagerUserSelect = () => {
+ currentSelectType.value = 'manager'
+ userSelectFormRef.value.open(0, selectedManagerUsers.value)
+}
+
+/** 澶勭悊鐢ㄦ埛閫夋嫨纭 */
+const handleUserSelectConfirm = (_, users: UserVO[]) => {
+ if (currentSelectType.value === 'start') {
+ modelData.value = {
+ ...modelData.value,
+ startUserIds: users.map((u) => u.id)
+ }
+ } else {
+ modelData.value = {
+ ...modelData.value,
+ managerUserIds: users.map((u) => u.id)
+ }
+ }
+}
+
+/** 澶勭悊閮ㄩ棬閫夋嫨纭 */
+const handleDeptSelectConfirm = (depts: DeptVO[]) => {
+ modelData.value = {
+ ...modelData.value,
+ startDeptIds: depts.map((d) => d.id)
+ }
+}
+
+/** 澶勭悊鍙戣捣浜虹被鍨嬪彉鍖� */
+const handleStartUserTypeChange = (value: number) => {
+ if (value === 0) {
+ modelData.value = {
+ ...modelData.value,
+ startUserIds: [],
+ startDeptIds: []
+ }
+ } else if (value === 1) {
+ modelData.value = {
+ ...modelData.value,
+ startDeptIds: []
+ }
+ } else if (value === 2) {
+ modelData.value = {
+ ...modelData.value,
+ startUserIds: []
+ }
+ }
+}
+
+/** 绉婚櫎鍙戣捣浜� */
+const handleRemoveStartUser = (user: UserVO) => {
+ modelData.value = {
+ ...modelData.value,
+ startUserIds: modelData.value.startUserIds.filter((id: number) => id !== user.id)
+ }
+}
+
+/** 绉婚櫎閮ㄩ棬 */
+const handleRemoveStartDept = (dept: DeptVO) => {
+ modelData.value = {
+ ...modelData.value,
+ startDeptIds: modelData.value.startDeptIds.filter((id: number) => id !== dept.id)
+ }
+}
+
+/** 绉婚櫎绠$悊鍛� */
+const handleRemoveManagerUser = (user: UserVO) => {
+ modelData.value = {
+ ...modelData.value,
+ managerUserIds: modelData.value.managerUserIds.filter((id: number) => id !== user.id)
+ }
+}
+
+/** 琛ㄥ崟鏍¢獙 */
+const validate = async () => {
+ await formRef.value?.validate()
+}
+
+defineExpose({
+ validate
+})
+</script>
+
+<style lang="scss" scoped>
+.bg-gray-100 {
+ background-color: #f5f7fa;
+ transition: all 0.3s;
+
+ &:hover {
+ background-color: #e6e8eb;
+ }
+
+ .ep-close {
+ font-size: 14px;
+ color: #909399;
+ transition: color 0.3s;
+
+ &:hover {
+ color: #f56c6c;
+ }
+ }
+}
+</style>
--
Gitblit v1.8.0