import { useAjax } from '@/Hook/useAjax' import { delMenu, editMenu, getMenu, syncMenu, syncPlatform } from '@/services/operating/weMenu' import { useCallback, useReducer } from 'react' type State = { defaultMenu: any,//菜单配置 resMenu: any,//默认菜单配置 作比较使用 conditionalMenus: any[],//个性菜单 actionMenuId?: number,//当前选中的菜单ID actionItemId?: number,//当前选中的子菜单ID msgVisible: boolean,//图片,视频,音频类型弹窗 textVisible: boolean,//文字类型弹窗 graphicVisible: boolean,//图文类型弹窗 imgCardVisible: boolean,//小程序卡片弹窗 msgType: 'news' | 'text' | 'voice' | 'video' | 'image',//消息类型 actionWX: any,//选中微信 theEdit: any,//选中的数据 type: 'click' | 'view' | 'miniprogram',//菜单按钮类型 ref: any, // ruleClientPlatformType: null | '1' | '2'//公众号菜单类型1:IOS 2安卓 NULL默认 addMenuType: '0' | '1' | '2',//新增类型菜单 isSaver: boolean//是否保存 isUserId: any//是否在路径中插入userID 1|0 } export type Action = { type: 'addMenu' | 'moveAddMenu' | 'addMenuItem' | 'moveAddMenuItem' | 'actionMenuId' | 'actionItemId' | 'msgType' | 'msgVisible' | 'textVisible' | 'graphicVisible' | 'theEdit' | 'setMenuType' | 'initData' | 'delMenu' | 'setName' | 'defaultData' | 'setRef' | 'pushData' | 'isSaver' | 'init' | 'addConditionalMenus' | 'addMenuType' | 'ruleClientPlatformType' | 'imgCardVisible' | 'isUserId' params?: any } export function reducer(state: State, action: Action) { let { type, params } = action let { actionMenuId, actionItemId } = state let newMenu: any = {} switch (type) { case 'moveAddMenu': return { ...state, defaultMenu: params.defaultMenu } case 'actionMenuId'://选中的菜单当选中菜单ID把子菜单选中ID设为0,为了配合选中效果逻辑 return { ...state, actionMenuId: params.actionMenuId, actionItemId: 0, } case 'actionItemId'://选中的菜单子菜单 return { ...state, actionItemId: params.actionItemId, } case 'addMenu'://添加菜单 newMenu = JSON.parse(JSON.stringify(state.defaultMenu)) if (newMenu?.buttons?.length < 4) { //假如subMenus的长度大于0,那么已存至少一个菜单,那新增的菜单menuId就按第一个菜单的menuId+1 否则就是第一次添加 newMenu?.buttons?.push({ menuId: newMenu?.buttons?.length > 0 ? newMenu?.buttons[newMenu?.buttons?.length - 1].menuId + 1 : 1, subButtons: [], type: 'click' }) state.actionMenuId = newMenu?.buttons?.length > 0 ? newMenu?.buttons[newMenu?.buttons?.length - 1].menuId : 1 } return { ...state, defaultMenu: newMenu, isSaver: false } case 'addMenuItem'://添加子菜单 newMenu = JSON.parse(JSON.stringify(state.defaultMenu)) let itemArr: any = []; newMenu?.buttons?.map((item: any) => {//遍历菜单查找菜单ID是否等于选中的菜单ID,是就把当前菜单的子菜单数组赋值给变量itemArr if (item.menuId === state.actionMenuId) { itemArr = item.subButtons } }) if (itemArr.length < 6) {//假如itemArr的长度小于6证明不满5个可以添加子菜单,子菜单的ID等于菜单长度+1 //假如itemArr的长度大于0,那么已存至少一个子菜单,那新增的子菜单itemId就按第一个菜单的itemId+1 否则就是第一次添加 itemArr.push({ itemId: itemArr.length > 0 ? itemArr[itemArr.length - 1].itemId + 1 : 1, type: 'click' }) state.actionItemId = itemArr.length > 0 ? itemArr[itemArr.length - 1].itemId : 1 } newMenu?.buttons?.forEach((item: any) => {//最后将编辑后的itemArr数组放回当前选中的菜单中,返回整个state页面监听到参数有改动重新渲染 if (item.menuId === state.actionMenuId) { //添加子菜单清空父菜单多余内容 item.subButtons = itemArr item.url = '' item.appId = '' item.pagePath = '' item.menuType = '' item.msgContent = {} } }) return { ...state, defaultMenu: newMenu, isSaver: false } case 'delMenu': let { menuId, itemId } = params newMenu = JSON.parse(JSON.stringify(state.defaultMenu)) if (menuId && !itemId) {//menuId存在,itemId不存在删除主菜单 newMenu.buttons = newMenu?.buttons?.filter((item: any) => { if (item.menuId !== menuId) { return item } }) //处理menuId不然选中会错乱 newMenu.buttons = newMenu?.buttons?.map((item: any, index: number) => { item.menuId = index + 1 return item }) //删除主菜单清除选中的主菜单ID newMenu = { actionMenuId: menuId && !itemId ? 0 : actionMenuId, defaultMenu: newMenu } } if (menuId && itemId) { //menuId, itemId 都存在删除子菜单 newMenu.buttons = newMenu?.buttons?.map((item: any) => { if (item.menuId === menuId) {//遍历菜单数组查找当前选中的主菜单 item.subButtons = item.subButtons.filter((items: any) => {//筛选子菜单 if (items.itemId !== itemId) { return items } }) if (item.subButtons.length === 0) {//假如删完了子菜单给父菜单添加type item.type = 'click' } return item } return item }) //删除子菜单清除选中的子菜单ID归0选中调回主菜单 newMenu = { actionMenuId: actionMenuId, actionItemId: 0, defaultMenu: newMenu } } return { ...state, ...newMenu, isSaver: JSON.stringify(state.resMenu) === JSON.stringify(newMenu.defaultMenu) } case 'msgType': return { ...state, msgType: params.msgType } case 'setMenuType': return { ...state, menuType: params.menuType } case 'msgVisible': return { ...state, msgVisible: !state.msgVisible } case 'textVisible': return { ...state, textVisible: !state.textVisible } case 'graphicVisible': return { ...state, graphicVisible: !state.graphicVisible } case 'imgCardVisible': return { ...state, imgCardVisible: !state.imgCardVisible } case 'theEdit': return { ...state, theEdit: params.theEdit } case 'addConditionalMenus': let conditionalMenus if(params?.ruleClientPlatformType === 0){ conditionalMenus = [...state.conditionalMenus, { buttons: [] }] }else{ conditionalMenus = state.conditionalMenus.length < 3 ? [...state.conditionalMenus, { buttons: [], ruleClientPlatformType: params.ruleClientPlatformType }] : state.conditionalMenus } return { ...state, conditionalMenus } case 'addMenuType': return { ...state, addMenuType: params.addMenuType } case 'ruleClientPlatformType': return { ...state, defaultMenu: { ...state.defaultMenu, ruleClientPlatformType: params.ruleClientPlatformType }, isSaver: false } case 'isUserId': return { ...state, isUserId: params.isUserId } case 'pushData': newMenu = JSON.parse(JSON.stringify(state.defaultMenu)) Object.keys(params).forEach((key: string) => { newMenu?.buttons?.map((item: any) => { if (actionMenuId && !actionItemId) { if (item.menuId === actionMenuId) { if (key === 'msgType') { item.msgContent[key] = params[key] } else { item[key] = params[key] } } } if (actionMenuId && actionItemId && item?.subButtons?.length > 0) { if (item.menuId === actionMenuId) { item.subButtons.map((button: any) => { if (button.itemId === actionItemId) { if (key === 'msgType') { } else { button[key] = params[key] } } }) } } }) }) return { ...state, defaultMenu: newMenu, isSaver: false } case 'initData'://清空内容 return { ...initData, defaultMenu: state.defaultMenu, actionItemId, actionMenuId, conditionalMenus: state.conditionalMenus, resMenu: state.resMenu, addMenuType: state.addMenuType } case 'defaultData'://回填接口获取的菜单 return { ...initData, conditionalMenus: params.conditionalMenus, defaultMenu: params.defaultMenu, resMenu: params.resMenu } case 'init': return { ...initData } case 'setRef': return { ...state, ref: params.ref } case 'isSaver': return { ...state, isSaver: true } default: return state; } } let initData: State = { defaultMenu: { ruleClientPlatformType: null, buttons: [] }, resMenu: {}, conditionalMenus: [], msgType: 'news', msgVisible: false, textVisible: false, graphicVisible: false, theEdit: null, actionWX: null, type: 'click', ref: null, addMenuType: '0', isSaver: true, imgCardVisible: false, isUserId: 1 } export default function useWeMenu() { const [state, dispatch] = useReducer(reducer, initData) const getMenus = useAjax((params: { mpId: string }) => getMenu(params)) const delMenus = useAjax((params: { menuId: string }) => delMenu(params), { msgNmae: '删除' }) const editMenus = useAjax((params: any) => editMenu(params), { msgNmae: '编辑' }) const syncMenus = useAjax((params: { mpId: string }) => syncMenu(params), { msgNmae: '同步' }) const syncPlatforms = useAjax((params: { platform: string, menuId: string }) => syncPlatform(params), { msgNmae: '同步' }) const addMenu = useCallback(() => { console.log('11111') dispatch({ type: 'initData' })//清空数据初始化只保留已编辑的菜单 dispatch({ type: 'addMenu' }) }, []) const setMenuId = useCallback((actionMenuId: number) => { dispatch({ type: 'actionMenuId', params: { actionMenuId } }) }, []) const setItemId = useCallback((actionItemId: number) => { dispatch({ type: 'actionItemId', params: { actionItemId } }) }, []) const addMenuItem = useCallback(() => { dispatch({ type: 'initData' })//清空数据初始化只保留已编辑的数组 dispatch({ type: 'addMenuItem' }) //添加一级菜单 }, []) return { state, addMenu, setMenuId, setItemId, addMenuItem, getMenus, delMenus, editMenus, syncMenus, dispatch, syncPlatforms } }