feat(oa): tree multi-select for dept condition values
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
f874447ae2
commit
6beb243604
1 file changed
+66
-2
@@ -82,6 +82,23 @@
|
||||
:value="p.id"
|
||||
/>
|
||||
</el-select>
|
||||
<el-tree-select
|
||||
v-else-if="isDeptLikeField(rule.field)"
|
||||
:model-value="personValueIds(rule.value)"
|
||||
multiple
|
||||
filterable
|
||||
clearable
|
||||
check-strictly
|
||||
collapse-tags
|
||||
collapse-tags-tooltip
|
||||
default-expand-all
|
||||
:data="deptTreeData"
|
||||
:props="{ value: 'value', label: 'label', children: 'children' }"
|
||||
placeholder="选择部门(任一命中)"
|
||||
:disabled="disabled"
|
||||
class="cond-rule-editor__dept-select"
|
||||
@update:model-value="(v) => onValueChange(idx, Array.isArray(v) ? v.map(String) : [])"
|
||||
/>
|
||||
<el-select
|
||||
v-else-if="optionsFor(rule.field)?.length"
|
||||
:model-value="rule.value"
|
||||
@@ -132,7 +149,7 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted, ref, watch } from 'vue'
|
||||
import { Delete, Plus } from '@element-plus/icons-vue'
|
||||
import { fetchPostList, fetchUserList } from '@/api/admin'
|
||||
import { fetchDeptTree, fetchPostList, fetchUserList } from '@/api/admin'
|
||||
import { MAX_ADMIN_LIST_PAGE_SIZE } from '@/utils/fetch-paged-list'
|
||||
import {
|
||||
opsForFieldType,
|
||||
@@ -166,6 +183,10 @@
|
||||
const userOptions = ref<Array<{ id: string; label: string }>>([])
|
||||
const postOptions = ref<Array<{ id: string; label: string }>>([])
|
||||
|
||||
type DeptTreeNode = { value: string; label: string; children?: DeptTreeNode[] }
|
||||
|
||||
const deptTreeData = ref<DeptTreeNode[]>([])
|
||||
|
||||
function meta(field: string) {
|
||||
return props.candidates.find((c) => c.field === field)
|
||||
}
|
||||
@@ -179,6 +200,19 @@
|
||||
return meta(field)?.type === 'post'
|
||||
}
|
||||
|
||||
function isDeptLikeField(field: string) {
|
||||
const t = meta(field)?.type
|
||||
return t === 'dept' || t === 'ownerDept'
|
||||
}
|
||||
|
||||
function mapDeptTree(nodes: Api.Dept.DeptItem[]): DeptTreeNode[] {
|
||||
return (nodes || []).map((n) => ({
|
||||
value: String(n.id),
|
||||
label: String(n.deptName || n.id),
|
||||
children: n.children?.length ? mapDeptTree(n.children) : undefined
|
||||
}))
|
||||
}
|
||||
|
||||
function personValueIds(v: unknown): string[] {
|
||||
if (Array.isArray(v)) return v.map(String)
|
||||
if (v == null || v === '') return []
|
||||
@@ -186,7 +220,14 @@
|
||||
}
|
||||
|
||||
function defaultValueForType(type: string, opts?: ConditionCandidate['options']) {
|
||||
if (type === 'person' || type === 'ownerPerson' || type === 'post' || type === 'initiator') {
|
||||
if (
|
||||
type === 'person' ||
|
||||
type === 'ownerPerson' ||
|
||||
type === 'dept' ||
|
||||
type === 'ownerDept' ||
|
||||
type === 'post' ||
|
||||
type === 'initiator'
|
||||
) {
|
||||
return [] as string[]
|
||||
}
|
||||
return opts?.[0]?.value ?? ''
|
||||
@@ -336,6 +377,15 @@
|
||||
}
|
||||
}
|
||||
|
||||
async function loadDepts() {
|
||||
try {
|
||||
const tree = (await fetchDeptTree()) || []
|
||||
deptTreeData.value = mapDeptTree(tree as Api.Dept.DeptItem[])
|
||||
} catch {
|
||||
deptTreeData.value = []
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
if (props.candidates.some((c) => c.type === 'person' || c.type === 'ownerPerson' || c.type === 'initiator')) {
|
||||
loadUsers()
|
||||
@@ -343,6 +393,9 @@
|
||||
if (props.candidates.some((c) => c.type === 'post')) {
|
||||
loadPosts()
|
||||
}
|
||||
if (props.candidates.some((c) => c.type === 'dept' || c.type === 'ownerDept')) {
|
||||
loadDepts()
|
||||
}
|
||||
})
|
||||
|
||||
watch(
|
||||
@@ -361,6 +414,13 @@
|
||||
if (need && !postOptions.value.length) loadPosts()
|
||||
}
|
||||
)
|
||||
|
||||
watch(
|
||||
() => props.candidates.some((c) => c.type === 'dept' || c.type === 'ownerDept'),
|
||||
(need) => {
|
||||
if (need && !deptTreeData.value.length) loadDepts()
|
||||
}
|
||||
)
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@@ -404,4 +464,8 @@
|
||||
.cond-rule-editor__post-select :deep(.el-select__selection) {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.cond-rule-editor__dept-select :deep(.el-select__selection) {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
</style>
|
||||
Reference in new issue
Block a user