fix: 组织架构部门下拉显示层级路径
- 部门编辑弹窗上级部门下拉显示完整路径如 总公司 / 技术部 / 前端组 - 岗位编辑弹窗所属部门下拉同样显示层级路径 - 下拉选项按路径名排序
This commit is contained in:
@@ -51,6 +51,28 @@ export default function OrgChart() {
|
|||||||
onError: (err: any) => toast.error(err?.response?.data?.error?.message || '删除失败'),
|
onError: (err: any) => toast.error(err?.response?.data?.error?.message || '删除失败'),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 构建部门层级路径映射,如 "总公司 / 技术部 / 前端组"
|
||||||
|
const buildDeptPath = (departments: any[]): Record<string, string> => {
|
||||||
|
const map: Record<string, string> = {}
|
||||||
|
const byId: Record<string, any> = {}
|
||||||
|
departments.forEach(d => { byId[d.id] = d })
|
||||||
|
const getPath = (d: any): string => {
|
||||||
|
if (map[d.id]) return map[d.id]
|
||||||
|
const parts: string[] = [d.name]
|
||||||
|
let cur = d
|
||||||
|
while (cur.parentId && byId[cur.parentId]) {
|
||||||
|
cur = byId[cur.parentId]
|
||||||
|
parts.unshift(cur.name)
|
||||||
|
}
|
||||||
|
const path = parts.join(' / ')
|
||||||
|
map[d.id] = path
|
||||||
|
return path
|
||||||
|
}
|
||||||
|
departments.forEach(d => getPath(d))
|
||||||
|
return map
|
||||||
|
}
|
||||||
|
const deptPathMap = buildDeptPath(departments)
|
||||||
|
|
||||||
const toggleExpand = (id: string) => {
|
const toggleExpand = (id: string) => {
|
||||||
setExpanded(prev => {
|
setExpanded(prev => {
|
||||||
const next = new Set(prev)
|
const next = new Set(prev)
|
||||||
@@ -180,9 +202,9 @@ export default function OrgChart() {
|
|||||||
<div>
|
<div>
|
||||||
<Label>上级部门</Label>
|
<Label>上级部门</Label>
|
||||||
<Select value={form.parentId} onChange={(e) => setForm({ ...form, parentId: e.target.value })}>
|
<Select value={form.parentId} onChange={(e) => setForm({ ...form, parentId: e.target.value })}>
|
||||||
{departments.filter((d: any) => d.id !== editing?.id).map((d: any) => (
|
{departments.filter((d: any) => d.id !== editing?.id).sort((a: any, b: any) => (deptPathMap[a.id] || a.name).localeCompare(deptPathMap[b.id] || b.name)).map((d: any) => (
|
||||||
<option key={d.id} value={d.id}>
|
<option key={d.id} value={d.id}>
|
||||||
{d.level === 0 && !d.parentId ? `${d.name}(公司)` : d.name}
|
{d.level === 0 && !d.parentId ? `${d.name}(公司)` : deptPathMap[d.id] || d.name}
|
||||||
</option>
|
</option>
|
||||||
))}
|
))}
|
||||||
</Select>
|
</Select>
|
||||||
@@ -215,6 +237,28 @@ function PositionTab({ positions, departments }: { positions: any[]; departments
|
|||||||
const [editing, setEditing] = useState<any>(null)
|
const [editing, setEditing] = useState<any>(null)
|
||||||
const [form, setForm] = useState<any>({ name: '', departmentId: '', headcount: 0, level: '', description: '' })
|
const [form, setForm] = useState<any>({ name: '', departmentId: '', headcount: 0, level: '', description: '' })
|
||||||
|
|
||||||
|
// 构建部门层级路径
|
||||||
|
const buildDeptPath = (depts: any[]): Record<string, string> => {
|
||||||
|
const map: Record<string, string> = {}
|
||||||
|
const byId: Record<string, any> = {}
|
||||||
|
depts.forEach(d => { byId[d.id] = d })
|
||||||
|
const getPath = (d: any): string => {
|
||||||
|
if (map[d.id]) return map[d.id]
|
||||||
|
const parts: string[] = [d.name]
|
||||||
|
let cur = d
|
||||||
|
while (cur.parentId && byId[cur.parentId]) {
|
||||||
|
cur = byId[cur.parentId]
|
||||||
|
parts.unshift(cur.name)
|
||||||
|
}
|
||||||
|
const path = parts.join(' / ')
|
||||||
|
map[d.id] = path
|
||||||
|
return path
|
||||||
|
}
|
||||||
|
depts.forEach(d => getPath(d))
|
||||||
|
return map
|
||||||
|
}
|
||||||
|
const deptPathMap = buildDeptPath(departments)
|
||||||
|
|
||||||
const createMutation = useMutation({
|
const createMutation = useMutation({
|
||||||
mutationFn: (data: any) => editing ? api.put(`/positions/${editing.id}`, data) : api.post('/positions', data),
|
mutationFn: (data: any) => editing ? api.put(`/positions/${editing.id}`, data) : api.post('/positions', data),
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
@@ -288,7 +332,7 @@ function PositionTab({ positions, departments }: { positions: any[]; departments
|
|||||||
<Label>所属部门</Label>
|
<Label>所属部门</Label>
|
||||||
<Select value={form.departmentId} onChange={(e) => setForm({ ...form, departmentId: e.target.value })}>
|
<Select value={form.departmentId} onChange={(e) => setForm({ ...form, departmentId: e.target.value })}>
|
||||||
<option value="">无</option>
|
<option value="">无</option>
|
||||||
{departments.map(d => <option key={d.id} value={d.id}>{d.name}</option>)}
|
{departments.sort((a: any, b: any) => (deptPathMap[a.id] || a.name).localeCompare(deptPathMap[b.id] || b.name)).map(d => <option key={d.id} value={d.id}>{deptPathMap[d.id] || d.name}</option>)}
|
||||||
</Select>
|
</Select>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid grid-cols-2 gap-3">
|
<div className="grid grid-cols-2 gap-3">
|
||||||
|
|||||||
Reference in New Issue
Block a user