Commit a3d9dfdf authored by 前端-许佳敏's avatar 前端-许佳敏

修改树形菜单

parent 7372cf58
...@@ -18,7 +18,7 @@ export interface TabTreeActions { ...@@ -18,7 +18,7 @@ export interface TabTreeActions {
setSelectKey: (key: ReactText) => void setSelectKey: (key: ReactText) => void
setSelectKeys: (keys: ReactText[]) => void setSelectKeys: (keys: ReactText[]) => void
getParentPath: (id: ReactText) => string getParentPath: (id: ReactText) => string
connected: boolean getParent: (id) => any
} }
export interface toolsRenderProps { export interface toolsRenderProps {
...@@ -52,13 +52,13 @@ export interface RenderIconsProps { ...@@ -52,13 +52,13 @@ export interface RenderIconsProps {
export const useTreeActions = (action?): TabTreeActions => { export const useTreeActions = (action?): TabTreeActions => {
const actionRef = useRef<any>(null) const actionRef = useRef<any>(null)
actionRef.current = actionRef.current || action || createTreeActions() actionRef.current = actionRef.current || action || createTreeActions()
return actionRef.current return actionRef.current
} }
export const createTreeActions = () => { export const createTreeActions = () => {
const actions: TabTreeActions = { const actions: TabTreeActions = {
selected: [], selected: [],
connected: false,
getExpandedKeys(){ return [] }, getExpandedKeys(){ return [] },
getSelectKey(){ return '' }, getSelectKey(){ return '' },
getSelectKeys(){ return [] }, getSelectKeys(){ return [] },
...@@ -66,6 +66,7 @@ export const createTreeActions = () => { ...@@ -66,6 +66,7 @@ export const createTreeActions = () => {
setSelectKeys(){}, setSelectKeys(){},
setExpandedKeys(){}, setExpandedKeys(){},
getParentPath(id){return ''}, getParentPath(id){return ''},
getParent(id){return null}
} }
return actions return actions
} }
...@@ -186,9 +187,7 @@ const TabTree:React.FC<TabTreeProps> = (props) => { ...@@ -186,9 +187,7 @@ const TabTree:React.FC<TabTreeProps> = (props) => {
if (selfActions) { if (selfActions) {
selfActions.getExpandedKeys = () => expandkeys selfActions.getExpandedKeys = () => expandkeys
selfActions.getSelectKey = () => selectKey selfActions.getSelectKey = () => selectKey
selfActions.getSelectKeys = () => { selfActions.getSelectKeys = () => selected
return selected
}
selfActions.selected = selected selfActions.selected = selected
selfActions.setSelectKeys = (keys: ReactText[]) => { selfActions.setSelectKeys = (keys: ReactText[]) => {
setSelected(keys) setSelected(keys)
...@@ -203,8 +202,13 @@ const TabTree:React.FC<TabTreeProps> = (props) => { ...@@ -203,8 +202,13 @@ const TabTree:React.FC<TabTreeProps> = (props) => {
selfActions.getParentPath = (id: ReactText) => { selfActions.getParentPath = (id: ReactText) => {
return getParentTreeTitles(treeData, id) return getParentTreeTitles(treeData, id)
} }
// 链接成功
selfActions.connected = true selfActions.getParent = (id) => {
const reductData = treeReduction(treeData)
const targetInfo = reductData[id]
const parentInfo = reductData[targetInfo.parentId]
return parentInfo || null
}
} }
const batchSelect = (items: any) => { const batchSelect = (items: any) => {
...@@ -215,6 +219,7 @@ const TabTree:React.FC<TabTreeProps> = (props) => { ...@@ -215,6 +219,7 @@ const TabTree:React.FC<TabTreeProps> = (props) => {
items.forEach(v => select(v)) items.forEach(v => select(v))
} }
} }
return ( return (
<div> <div>
{title && {title &&
...@@ -243,7 +248,7 @@ const TabTree:React.FC<TabTreeProps> = (props) => { ...@@ -243,7 +248,7 @@ const TabTree:React.FC<TabTreeProps> = (props) => {
if (props.handleSelect) { if (props.handleSelect) {
const result = props.handleSelect(node.key, node) const result = props.handleSelect(node.key, node)
// 存在返回值则不执行选中事件, 一般用于切换node时,不希望离开当前页面 // 存在返回值则不执行选中事件, 一般用于切换node时,不希望离开当前页面
if (result !== undefined) { if (result) {
result.then(() => { result.then(() => {
// 若promise 是resolve状态, 说明确认离开了当前页面 // 若promise 是resolve状态, 说明确认离开了当前页面
setSelectKey(selectKey === node.key ? '' : node.key) setSelectKey(selectKey === node.key ? '' : node.key)
......
import { useMap } from '@umijs/hooks' import { useMap } from '@umijs/hooks'
import { useState, useEffect } from 'react' import React, { useState, useEffect } from 'react'
import { Modal } from 'antd' import { Modal } from 'antd'
import { TabTreeActions } from '@/components/TabTree'
import { ISchemaFormActions } from '@formily/antd'
import { isObject } from '@/utils'
export enum FormState { export enum FormState {
FREE, // 空闲状态 FREE, // 空闲状态
...@@ -12,11 +15,20 @@ export interface useTreeTabOptions { ...@@ -12,11 +15,20 @@ export interface useTreeTabOptions {
selectCallback?(selectKey?, node?), selectCallback?(selectKey?, node?),
fetchMenuData?(), fetchMenuData?(),
fetchItemDetailData?(id), fetchItemDetailData?(id),
// 重置右侧详情
resetDetail?(), resetDetail?(),
// 对树形工具栏做render扩展
extendsToolsRender?: any,
// 树形的实例操作方法
treeActions?: TabTreeActions
// 右侧表单的实例操作方法
formActions?: ISchemaFormActions
// 删除菜单时调用的API
deleteMenu?: any
} }
export const useTreeTabs = (options: useTreeTabOptions = {}) => { export const useTreeTabs = (options: useTreeTabOptions = {}) => {
const { selectCallback, fetchMenuData, fetchItemDetailData, resetDetail } = options const { selectCallback, fetchMenuData, fetchItemDetailData, resetDetail, treeActions, formActions, extendsToolsRender, deleteMenu } = options
const [ treeExtraMaps, { set, get } ] = useMap<any, any>() const [ treeExtraMaps, { set, get } ] = useMap<any, any>()
const [ treeData, setTreeData ] = useState<any[]>([]) const [ treeData, setTreeData ] = useState<any[]>([])
const [ treeStatus, setTreeStatus ] = useState<FormState>(FormState.FREE) const [ treeStatus, setTreeStatus ] = useState<FormState>(FormState.FREE)
...@@ -86,6 +98,45 @@ export const useTreeTabs = (options: useTreeTabOptions = {}) => { ...@@ -86,6 +98,45 @@ export const useTreeTabs = (options: useTreeTabOptions = {}) => {
set(id, data) set(id, data)
}) })
} }
const handleDeleteMenu = (id) => {
deleteMenu({
id: isObject(id) ? nodeRecord.key : id
}).then(() => {
setTreeStatus(FormState.FREE)
setNodeRecord(undefined)
resetMenu()
})
}
// 新增整合树形操作菜单
// 树形工具栏
const toolsRender = {
addNode(node) {
const activeParentId = treeActions && treeActions.getParent(node.key || node.id)?.id
setNodeRecord({
...node,
parentId: activeParentId, // 添加同级的时候 使用上一级的id作为parentId
})
formActions && formActions.reset({ validate: false })
setTreeStatus(FormState.ADD)
},
addChildNode(node) {
setNodeRecord({
...node,
parentId: node.key || node.id
})
formActions && formActions.reset({ validate: false })
set(node.key || node.id, null)
setTreeStatus(FormState.ADD)
},
deleteNode(node) {
const id = node.key || node.id
handleDeleteMenu(id)
},
...extendsToolsRender
}
return { return {
handleSelect, handleSelect,
treeStatus, treeStatus,
...@@ -99,6 +150,8 @@ export const useTreeTabs = (options: useTreeTabOptions = {}) => { ...@@ -99,6 +150,8 @@ export const useTreeTabs = (options: useTreeTabOptions = {}) => {
treeExtraMaps, treeExtraMaps,
setTreeMaps: set, setTreeMaps: set,
getTreeMaps: get, getTreeMaps: get,
resetMenu resetMenu,
toolsRender,
handleDeleteMenu
} }
} }
\ No newline at end of file
...@@ -48,7 +48,7 @@ const MemberDetail: React.FC<{}> = () => { ...@@ -48,7 +48,7 @@ const MemberDetail: React.FC<{}> = () => {
nodeRecord, nodeRecord,
isEditForm, isEditForm,
setIsEditForm, setIsEditForm,
getTreeMaps getTreeMaps,
} = useTreeTabs({ } = useTreeTabs({
fetchMenuData, fetchMenuData,
fetchItemDetailData: ({id}) => PublicApi.getMemberRoleAuthButton({ fetchItemDetailData: ({id}) => PublicApi.getMemberRoleAuthButton({
......
...@@ -5,7 +5,7 @@ import { ...@@ -5,7 +5,7 @@ import {
FormOutlined, FormOutlined,
PlusOutlined PlusOutlined
} from '@ant-design/icons'; } from '@ant-design/icons';
import TabTree, { useTreeActions } from '@/components/TabTree'; import TabTree, { useTreeActions, createTreeActions } from '@/components/TabTree';
import SchemaForm, { createFormActions, LifeCycleTypes, FormEffectHooks } from '@formily/antd'; import SchemaForm, { createFormActions, LifeCycleTypes, FormEffectHooks } from '@formily/antd';
import { menuSchema } from './schema'; import { menuSchema } from './schema';
import { PublicApi } from '@/services/api'; import { PublicApi } from '@/services/api';
...@@ -25,6 +25,7 @@ enum FormState { ...@@ -25,6 +25,7 @@ enum FormState {
} }
const formActions = createFormActions() const formActions = createFormActions()
const treeActions = createTreeActions()
const fetchMenuData = async (params?) => { const fetchMenuData = async (params?) => {
const res = await PublicApi.getMemberOrgTree() const res = await PublicApi.getMemberOrgTree()
...@@ -43,27 +44,23 @@ const Organ: React.FC<{}> = () => { ...@@ -43,27 +44,23 @@ const Organ: React.FC<{}> = () => {
handleSelect, handleSelect,
getTreeMaps, getTreeMaps,
setTreeMaps, setTreeMaps,
resetMenu resetMenu,
toolsRender,
handleDeleteMenu
} = useTreeTabs({ } = useTreeTabs({
treeActions,
formActions,
deleteMenu: PublicApi.postMemberOrgDelete,
fetchMenuData: fetchMenuData, fetchMenuData: fetchMenuData,
fetchItemDetailData: PublicApi.getMemberOrgGet fetchItemDetailData: PublicApi.getMemberOrgGet
}) })
const formInitValue = nodeRecord ? getTreeMaps(nodeRecord.key) : {} // 当拥有节点数据并且当前状态是编辑状态时 需回显表单
const formInitValue = (nodeRecord && treeStatus === FormState.EDIT) ? getTreeMaps(nodeRecord.key) : {}
const handleSubmitAllSetting = () => { const handleSubmitAllSetting = () => {
formActions.submit() formActions.submit()
} }
const handleDeleteMenu = (id) => {
PublicApi.postMemberOrgDelete({
id: isObject(id) ? nodeRecord.key : id
}).then(() => {
setTreeStatus(FormState.FREE)
setNodeRecord(undefined)
resetMenu()
})
}
// 保存设置提交 // 保存设置提交
const handleSubmit = (value) => { const handleSubmit = (value) => {
...@@ -83,27 +80,6 @@ const Organ: React.FC<{}> = () => { ...@@ -83,27 +80,6 @@ const Organ: React.FC<{}> = () => {
}) })
} }
// 树形工具栏
const toolsRender = {
addNode(node) {
formActions.reset({ validate: false })
setNodeRecord(undefined)
setTreeStatus(FormState.ADD)
},
addChildNode(node) {
setNodeRecord({
...node,
parentId: node.key
})
formActions.reset({ validate: false })
setTreeMaps(node.key, null)
setTreeStatus(FormState.ADD)
},
deleteNode(node) {
handleDeleteMenu(node.key)
}
}
return <div className="common-wrapper"> return <div className="common-wrapper">
<Row gutter={[36, 36]}> <Row gutter={[36, 36]}>
<Col span={8}> <Col span={8}>
...@@ -114,6 +90,7 @@ const Organ: React.FC<{}> = () => { ...@@ -114,6 +90,7 @@ const Organ: React.FC<{}> = () => {
fetchData = {params => fetchMenuData(params)} fetchData = {params => fetchMenuData(params)}
treeData={treeData} treeData={treeData}
toolsRender={toolsRender} toolsRender={toolsRender}
actions={treeActions}
customKey='id' customKey='id'
handleSelect={(key, node) => handleSelect(key, node)} handleSelect={(key, node) => handleSelect(key, node)}
/> />
......
...@@ -17,6 +17,12 @@ export const UserDetailSchema:ISchema = { ...@@ -17,6 +17,12 @@ export const UserDetailSchema:ISchema = {
account: { account: {
type: 'string', type: 'string',
title: '登录账号', title: '登录账号',
"x-rules": [
{
pattern: /^\w{6,20}$/,
message: '请输入由数字字母或者下划线组成的6-20位账号'
}
],
required: true required: true
}, },
password: { password: {
...@@ -33,6 +39,7 @@ export const UserDetailSchema:ISchema = { ...@@ -33,6 +39,7 @@ export const UserDetailSchema:ISchema = {
name: { name: {
type: 'string', type: 'string',
title: '姓名', title: '姓名',
maxLength: 16,
required: true required: true
}, },
phoneLayout: { phoneLayout: {
...@@ -95,7 +102,8 @@ export const UserDetailSchema:ISchema = { ...@@ -95,7 +102,8 @@ export const UserDetailSchema:ISchema = {
}, },
jobTitle: { jobTitle: {
type: 'string', type: 'string',
title: '职位' title: '职位',
maxLength: 20,
}, },
orgName: { orgName: {
type: 'string', type: 'string',
......
...@@ -35,6 +35,8 @@ const fetchOriginTreeData = async (params?) => { // 平台后台树 ...@@ -35,6 +35,8 @@ const fetchOriginTreeData = async (params?) => { // 平台后台树
} }
const userActions = createFormActions() const userActions = createFormActions()
const originTreeActions = useTreeActions()
const AddUser: React.FC<{}> = () => { const AddUser: React.FC<{}> = () => {
const [originVisible, setOriginVisible] = useState(false) const [originVisible, setOriginVisible] = useState(false)
...@@ -45,7 +47,6 @@ const AddUser: React.FC<{}> = () => { ...@@ -45,7 +47,6 @@ const AddUser: React.FC<{}> = () => {
const [formData, setFormData] = useState<any>(null) const [formData, setFormData] = useState<any>(null)
const { id, pageStatus } = usePageStatus() const { id, pageStatus } = usePageStatus()
const [roleSelection, roleSelectCtl] = useRowSelectionTable() const [roleSelection, roleSelectCtl] = useRowSelectionTable()
const originTreeActions = useTreeActions()
const [originSelectNode, setOriginSelectNode] = useState<any>() const [originSelectNode, setOriginSelectNode] = useState<any>()
const { data, loading, err, run } = useHttpRequest(id ? PublicApi.postMemberUserUpdate : PublicApi.postMemberUserAdd) const { data, loading, err, run } = useHttpRequest(id ? PublicApi.postMemberUserUpdate : PublicApi.postMemberUserAdd)
const { const {
......
...@@ -6,13 +6,14 @@ import { ...@@ -6,13 +6,14 @@ import {
LinkOutlined, LinkOutlined,
} from '@ant-design/icons'; } from '@ant-design/icons';
import { PageHeaderWrapper } from '@ant-design/pro-layout'; import { PageHeaderWrapper } from '@ant-design/pro-layout';
import TabTree, { useTreeActions } from '@/components/TabTree'; import TabTree, { useTreeActions, createTreeActions } from '@/components/TabTree';
import { UploadFile, UploadChangeParam } from 'antd/lib/upload/interface'; import { UploadFile, UploadChangeParam } from 'antd/lib/upload/interface';
import SchemaForm, { createFormActions, LifeCycleTypes, FormEffectHooks, FormButtonGroup } from '@formily/antd'; import SchemaForm, { createFormActions, LifeCycleTypes, FormEffectHooks, FormButtonGroup } from '@formily/antd';
import { classSchema } from './schema' import { classSchema } from './schema'
import { PublicApi } from '@/services/api'; import { PublicApi } from '@/services/api';
import { useTreeTabs } from '@/hooks/useTreeTabs'; import { useTreeTabs } from '@/hooks/useTreeTabs';
import NiceForm from '@/components/NiceForm'; import NiceForm from '@/components/NiceForm';
import { isObject } from '@antv/util';
const { ON_FORM_INPUT_CHANGE } = LifeCycleTypes const { ON_FORM_INPUT_CHANGE } = LifeCycleTypes
...@@ -23,6 +24,7 @@ enum FormState { ...@@ -23,6 +24,7 @@ enum FormState {
} }
const formActions = createFormActions() const formActions = createFormActions()
const treeActions = createTreeActions()
const fetchClassTreeData = async (params?) => { const fetchClassTreeData = async (params?) => {
const res = await PublicApi.getProductPlatformGetCategoryTree() const res = await PublicApi.getProductPlatformGetCategoryTree()
...@@ -42,41 +44,22 @@ const ClassProperty: React.FC<{}> = () => { ...@@ -42,41 +44,22 @@ const ClassProperty: React.FC<{}> = () => {
handleSelect, handleSelect,
getTreeMaps, getTreeMaps,
setTreeMaps, setTreeMaps,
resetMenu resetMenu,
toolsRender,
handleDeleteMenu
} = useTreeTabs({ } = useTreeTabs({
treeActions,
formActions,
deleteMenu: PublicApi.postProductPlatformDeleteCategory,
fetchMenuData: fetchClassTreeData, fetchMenuData: fetchClassTreeData,
fetchItemDetailData: PublicApi.getProductPlatformGetCategory fetchItemDetailData: PublicApi.getProductPlatformGetCategory
}) })
const formInitValue = nodeRecord ? getTreeMaps(nodeRecord.key) : {} const formInitValue = (nodeRecord && treeStatus === FormState.EDIT) ? getTreeMaps(nodeRecord.key) : {}
useEffect(() => { useEffect(() => {
console.log(nodeRecord, 'getTreeMaps') console.log(nodeRecord, 'getTreeMaps')
}, [getTreeMaps]) }, [getTreeMaps])
// 树形工具栏
const toolsRender = {
addNode(node) {
formActions.reset({ validate: false })
setTreeStatus(FormState.ADD)
},
addChildNode(node) {
formActions.reset({ validate: false })
setNodeRecord({
...node,
parentId: node.id, // 添加子级的时候 使用上一级的id作为parentId
})
setTreeMaps(node.id, null)
setTreeStatus(FormState.ADD)
},
deleteNode(node) {
PublicApi.postProductPlatformDeleteCategory({
id: node.id
}).then(() => {
resetMenu()
})
}
}
const onFinish = (values) => { const onFinish = (values) => {
const editOrAdd = nodeRecord && treeStatus === FormState.EDIT const editOrAdd = nodeRecord && treeStatus === FormState.EDIT
const params = editOrAdd ? { ...values, parentId: nodeRecord.id } : { const params = editOrAdd ? { ...values, parentId: nodeRecord.id } : {
...@@ -94,17 +77,6 @@ const ClassProperty: React.FC<{}> = () => { ...@@ -94,17 +77,6 @@ const ClassProperty: React.FC<{}> = () => {
} }
const handleDeleteMenu = () => {
if (nodeRecord) {
PublicApi.postProductPlatformDeleteCategory({
id: nodeRecord.id
}).then(() => {
setNodeRecord(undefined)
resetMenu()
})
}
}
return <PageHeaderWrapper return <PageHeaderWrapper
title="品类" title="品类"
> >
......
...@@ -5,7 +5,7 @@ function isArray(arr: any) { ...@@ -5,7 +5,7 @@ function isArray(arr: any) {
return Array.isArray(arr) return Array.isArray(arr)
} }
function isObject(obj: any) { export function isObject(obj: any) {
return Object.prototype.toString.call(obj) === '[object Object]' return Object.prototype.toString.call(obj) === '[object Object]'
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment