From a1d7e81859f554f3a53680cc35f0f49bf1f77098 Mon Sep 17 00:00:00 2001
From: wwf <1971391498@qq.com>
Date: 星期四, 14 五月 2026 14:37:02 +0800
Subject: [PATCH] 导入项目

---
 src/components/DeptSelectForm/index.vue |  122 ++++++++++++++++++++++++++++++++++++++++
 1 files changed, 122 insertions(+), 0 deletions(-)

diff --git a/src/components/DeptSelectForm/index.vue b/src/components/DeptSelectForm/index.vue
new file mode 100644
index 0000000..140f495
--- /dev/null
+++ b/src/components/DeptSelectForm/index.vue
@@ -0,0 +1,122 @@
+<template>
+  <Dialog v-model="dialogVisible" title="閮ㄩ棬閫夋嫨" width="600">
+    <el-row v-loading="formLoading">
+      <el-col :span="24">
+        <ContentWrap class="h-1/1">
+          <el-tree
+            ref="treeRef"
+            :data="deptTree"
+            :props="defaultProps"
+            show-checkbox
+            :check-strictly="checkStrictly"
+            check-on-click-node
+            default-expand-all
+            highlight-current
+            node-key="id"
+            @check="handleCheck"
+          />
+        </ContentWrap>
+      </el-col>
+    </el-row>
+    <template #footer>
+      <el-button
+        :disabled="formLoading || !selectedDeptIds?.length"
+        type="primary"
+        @click="submitForm"
+      >
+        纭� 瀹�
+      </el-button>
+      <el-button @click="dialogVisible = false">鍙� 娑�</el-button>
+    </template>
+  </Dialog>
+</template>
+
+<script lang="ts" setup>
+import { defaultProps, handleTree } from '@/utils/tree'
+import * as DeptApi from '@/api/system/dept'
+
+defineOptions({ name: 'DeptSelectForm' })
+
+const emit = defineEmits<{
+  confirm: [deptList: any[]]
+}>()
+
+const { t } = useI18n() // 鍥介檯鍖�
+const message = useMessage() // 娑堟伅寮圭獥
+
+const props = defineProps({
+  // 鏄惁涓ユ牸鐨勯伒寰埗瀛愪笉浜掔浉鍏宠仈
+  checkStrictly: {
+    type: Boolean,
+    default: false
+  },
+  // 鏄惁鏀寔澶氶��
+  multiple: {
+    type: Boolean,
+    default: true
+  }
+})
+
+const treeRef = ref()
+const deptTree = ref<Tree[]>([]) // 閮ㄩ棬鏍戝舰缁撴瀯
+const selectedDeptIds = ref<number[]>([]) // 閫変腑鐨勯儴闂� ID 鍒楄〃
+const dialogVisible = ref(false) // 寮圭獥鐨勬槸鍚﹀睍绀�
+const formLoading = ref(false) // 琛ㄥ崟鐨勫姞杞戒腑
+
+/** 鎵撳紑寮圭獥 */
+const open = async (selectedList?: DeptApi.DeptVO[]) => {
+  resetForm()
+  formLoading.value = true
+  try {
+    // 鍔犺浇閮ㄩ棬鍒楄〃
+    const deptData = await DeptApi.getSimpleDeptList()
+    deptTree.value = handleTree(deptData)
+  } finally {
+    formLoading.value = false
+  }
+  dialogVisible.value = true
+  // 璁剧疆宸查�夋嫨鐨勯儴闂�
+  if (selectedList?.length) {
+    await nextTick()
+    const selectedIds = selectedList
+      .map((dept) => dept.id)
+      .filter((id): id is number => id !== undefined)
+    selectedDeptIds.value = selectedIds
+    treeRef.value?.setCheckedKeys(selectedIds)
+  }
+}
+
+/** 澶勭悊閫変腑鐘舵�佸彉鍖� */
+const handleCheck = (data: any, checked: any) => {
+  selectedDeptIds.value = treeRef.value.getCheckedKeys()
+  if (!props.multiple && selectedDeptIds.value.length > 1) {
+    // 鍗曢�夋ā寮忎笅锛屽彧淇濈暀鏈�鍚庨�夋嫨鐨勮妭鐐�
+    const lastSelectedId = selectedDeptIds.value[selectedDeptIds.value.length - 1]
+    selectedDeptIds.value = [lastSelectedId]
+    treeRef.value.setCheckedKeys([lastSelectedId])
+  }
+}
+
+/** 鎻愪氦閫夋嫨 */
+const submitForm = async () => {
+  try {
+    // 鑾峰彇閫変腑鐨勫畬鏁撮儴闂ㄦ暟鎹�
+    const checkedNodes = treeRef.value.getCheckedNodes()
+    message.success(t('common.updateSuccess'))
+    dialogVisible.value = false
+    emit('confirm', checkedNodes)
+  } finally {
+  }
+}
+
+/** 閲嶇疆琛ㄥ崟 */
+const resetForm = () => {
+  deptTree.value = []
+  selectedDeptIds.value = []
+  if (treeRef.value) {
+    treeRef.value.setCheckedKeys([])
+  }
+}
+
+defineExpose({ open }) // 鎻愪緵 open 鏂规硶锛岀敤浜庢墦寮�寮圭獥
+</script>

--
Gitblit v1.8.0