import { IParam, deepCopy, srfFilePath2, ICtrlAbility, IEvent, IViewLogicInput, ICtrlStore, IFormStore, IFormAbility, IDashboardStore, IDashboardAbility, IMDCtrlAbility, IMDCtrlStore, IExpCtrlModel, IExpCtrlStore, IExpCtrlAbility, ISearchFormAbility, ISearchFormStore, IGridStore, IGridAbility, computedNavData, IPanelStore, IPanelAbility, IPortletStore, IPortletAbility, IDECtrlAbility, IViewAbility, } from '@/core'; import { ICtrlController, IDashboardController, IExpCtrlController, IFormController, IGridController, IMDCtrlController, IPanelController, IPortletController, ISearchFormController, } from '@/core/interface/widgets/controller'; import { ICtrlEvent } from '@/core/interface/widgets/event/i-ctrl-event'; import { ICtrlModel } from '@/core/interface/widgets/model/i-ctrl-model'; import { QXEvent } from 'qx-util'; /** * 部件事件绑定 * * @export * @template T * @template A * @param {Function} emit * @return {*} QXEvent> */ export function useEventBind( emit: Function ): QXEvent> { const evt = new QXEvent>(); // 绑定事件回调 evt.on('ctrlAction', (controlName: string, action: T, data: any) => { emit('ctrl-action', controlName, action, data); }); evt.on('ctrlInit', (controlName: string, data: A) => { emit('ctrl-init', controlName, data); }); evt.on('ctrlDestroy', (controlName: string, data: IParam) => { emit('ctrl-destroy', controlName, data); }); return evt; } /** * 处理部件初始化 * * @export * @template C * @param {C} controller 控制器 * @param {string} name 部件名称 * @param {ICtrlAbility} ability 部件能力 */ export function handleCtrlInit< C extends ICtrlController >(controller: C, name: string, ability: ICtrlAbility | IViewAbility) { controller.setSubAbility(name, ability); } /** * 处理子部件挂载 * * @export * @template C * @param {C} controller * @param {string} name * @param {IParam} data */ export function handleCtrlMounted< C extends ICtrlController >(controller: C, name: string, data: IParam) { controller.handleCtrlMounted(name, data); } /** * 处理部件行为 * * @export * @template C * @template A * @param {C} controller 控制器 * @param {string} name 部件名称 * @param {A} action 行为标识 * @param {IParam[]} data 数据 */ export function handleCtrlAction< C extends ICtrlController, A extends string >(controller: C, name: string, action: A, data: IParam[]) { controller.handleCtrlAction(name, action, data); } /** * 处理部件销毁 * * @export * @template C * @param {C} controller 控制器 * @param {string} name 部件名称 * @param {IParam} data 数据 */ export function handleCtrlDestroy< C extends ICtrlController >(controller: C, name: string, data: IParam) { controller.handleCtrlDestroy(name, data); } /** * 处理部件子组件行为 * * @export * @param {(IFormController | IPortletController)} controller * @param {IEvent} actionParam */ export function handleComponentAction( controller: | IFormController | IPortletController | IGridController | IPanelController, actionParam: IEvent, index?: number ) { if ((controller.getModel().controlType == 'GRID')) { ( controller as IGridController ).handleComponentAction(actionParam, index as number); } else { ( controller as | IFormController | IPortletController | IPanelController ).handleComponentAction(actionParam); } } /** * 多数据部件页码变化 * * @export * @param {IMDCtrlController} controller * @param {number} currentPage */ export function handlePageChange( controller: IMDCtrlController, currentPage: number ) { controller.handlePageChange(currentPage); } /** * 多数据部件分页大小变化 * * @export * @param {IMDCtrlController} controller * @param {number} size */ export function handlePageSizeChange( controller: IMDCtrlController, size: number ) { controller.handlePageSizeChange(size); } /** * 多数据部件排序变化 * * @export * @param {IMDCtrlController} controller * @param {string} sortField * @param {('asc' | 'desc' | '')} sortDir */ export function handleSortChange( controller: IMDCtrlController, sortField: string, sortDir: 'asc' | 'desc' | '' ) { controller.handleSortChange(sortField, sortDir); } /** * 多数据部件选中数据改变 * * @export * @param {IMDCtrlController} controller * @param {IParam[]} selections */ export function handleSelectionChange( controller: IMDCtrlController, selections: IParam[] ) { controller.handleSelectionChange(selections); } /** * 多数据部件行为点击 * * @export * @param {IMDCtrlController} controller * @param {IViewLogicInput} logic * @param {IParam} data * @param {MouseEvent} event */ export function handleActionClick( controller: IMDCtrlController, logic: IViewLogicInput, data: IParam, event: MouseEvent ) { const ability = controller.getAbility(); const { context, viewParams } = controller.getStore(); App.getViewLogicHelper().executeViewLogic( context, viewParams, [data], event, ability, logic ); } /** * 计算部件上下文 * * @export * @param {IParam} props * @return {*} */ export function useCtrlContext(props: IParam) { const { context: propContext } = props; const context = deepCopy(propContext); if (context.srfparentdename && context.srfparentkey) { Object.assign(context, { [context.srfparentdename.toLowerCase()]: context.srfparentkey, }); } return context; } /** * 计算部件导航参数 * * @export * @param {IParam} model * @param {IParam} props * @return {*} {{ context: IParam; viewParams: IParam }} */ export function useCtrlParams( model: IParam, props: IParam ): { context: IParam; viewParams: IParam } { const { context: propContext, viewParams: propViewParams, localContext, localViewParams, } = props; const context = deepCopy(propContext); const viewParams = deepCopy(propViewParams); if (context.srfparentdename && context.srfparentkey) { Object.assign(context, { [context.srfparentdename.toLowerCase()]: context.srfparentkey, }); } if (localContext && Object.keys(localContext).length > 0) { const _context = computedNavData({}, context, viewParams, localContext); Object.assign(context, _context); } if (localViewParams && Object.keys(localViewParams).length > 0) { const _viewParams = computedNavData( {}, context, viewParams, localViewParams ); Object.assign(viewParams, _viewParams); } return { context, viewParams }; } /** * 设置导航参数 * * @param {ICtrlController} controller * @param {IParam} props */ function computeNavParams( controller: ICtrlController, props: IParam ) { const model = controller.getModel(); const { context, viewParams } = useCtrlParams(model, props); controller.setNavParams(context, viewParams); } /** * 导航参数绑定 * * @export * @param {ICtrlController} controller * @param {IParam} props */ export function useNavParamsBind( controller: ICtrlController, props: IParam ) { watch( () => props.context, () => { computeNavParams(controller, props); }, { immediate: true } ); watch( () => props.viewParams, () => { computeNavParams(controller, props); }, { immediate: true } ); } /** * 获取部件类名 * * @export * @param {IParam} model * @param {IParam} [props={}] * @return {*} {IParam} */ export function getCtrlClassNames(model: IParam, props: IParam = {}): IParam { const classNames: IParam = { 'control-container': true, }; if (model.controlType) { Object.assign(classNames, { [`app-control-${model.controlType.toLowerCase()}`]: true, }); } if (model.codeName) { Object.assign(classNames, { [srfFilePath2(model.codeName)]: true }); } if (model.cssName) { Object.assign(classNames, { [model.cssName]: true }); } return classNames; } /** * 部件类名 * * @export * @param {*} [model={}] 部件模型 * @param {string} [customClassNames] 自定义样式名 * @return {*} {string} */ export function useCtrlClassNames(model: IParam, props: IParam = {}): IParam { const classNames: IParam = { 'control-container': true, }; if (model.controlType) { Object.assign(classNames, { [`app-control-${model.controlType.toLowerCase()}`]: true, }); } if (model.codeName) { Object.assign(classNames, { [srfFilePath2(model.codeName)]: true }); } if (model.cssName) { Object.assign(classNames, { [model.cssName]: true }); } return classNames; } /** * 获取数据看板部件类名 * * @export * @param {ICtrlModel} model 部件模型 * @param {IParam} props 部件输入参数 * @param {IParam} [customClassNames={}] 自定义类名 * @return {*} */ export function getDashboardClassNames( model: ICtrlModel, props: IParam, customClassNames: IParam = {} ) { const classNames = useCtrlClassNames(model, props); Object.assign(classNames, customClassNames); return classNames; } /** * 获取表单部件类名 * * @export * @param {ICtrlModel} model 部件模型 * @param {IParam} props 部件输入参数 * @param {IParam} [customClassNames={}] 自定义类名 * @return {*} */ export function getFormClassNames( model: ICtrlModel, props: IParam, customClassNames: IParam = {} ) { const classNames = useCtrlClassNames(model, props); Object.assign(classNames, { 'app-control-form--info': model.infoFormMode, }); Object.assign(classNames, customClassNames); return classNames; } /** * 获取搜索表单部件类名 * * @export * @param {ICtrlModel} model 部件模型 * @param {IParam} props 部件输入参数 * @param {IParam} [customClassNames={}] 自定义类名 * @return {*} */ export function getSearchFormClassNames( model: ICtrlModel, props: IParam, customClassNames: IParam = {} ) { const classNames = useCtrlClassNames(model, props); if (model.formStyle === 'SEARCHBAR' || model.searchButtonStyle === 'NONE') { Object.assign(classNames, { 'no-action': true }); } Object.assign(classNames, customClassNames); return classNames; } /** * 获取树部件类名 * * @export * @param {ICtrlModel} model 部件模型 * @param {IParam} props 部件输入参数 * @param {IParam} [customClassNames={}] 自定义类名 * @return {*} */ export function getTreeClassNames( model: ICtrlModel, props: IParam, customClassNames: IParam = {} ) { const classNames = useCtrlClassNames(model, props); Object.assign(classNames, customClassNames); return classNames; } /** * 获取树导航栏类名 * * @export * @param {ICtrlModel} model * @param {IParam} props * @param {IParam} [customClassNames={}] * @return {*} */ export function getTreeExpBarClassNames( model: ICtrlModel, props: IParam, customClassNames: IParam = {} ) { const classNames = useCtrlClassNames(model, props); Object.assign(classNames, customClassNames); return classNames; } /** * 多编辑表单面板类名 * * @export * @param {ICtrlModel} model * @param {IParam} props * @param {IParam} [customClassNames={}] * @return {*} */ export function getMultiEditViewPanelClassNames( model: ICtrlModel, props: IParam, customClassNames: IParam = {} ) { const classNames = useCtrlClassNames(model, props); Object.assign(classNames, customClassNames); return classNames; } /** * 获取导航栏类名 * * @export * @param {IExpCtrlModel} model * @param {IParam} props * @param {IParam} [customClassNames={}] * @return {*} */ export function getExpBarClassNames( model: IExpCtrlModel, props: IParam, customClassNames: IParam = {} ) { // TODO 计算父视图时候有快速分组 const classNames = useCtrlClassNames(model, props); Object.assign(classNames, { 'app-control-expbar': true, }); Object.assign(classNames, customClassNames); return classNames; } /** * 工具栏点击 * * @export * @param {IViewController} controller * @param {string} name * @param {MouseEvent} event * @param {IParam} [logic] * @return {*} */ export function handleToolbarItemClick( controller: ICtrlController, name: string, event: MouseEvent, logic?: IViewLogicInput ) { if (!logic) { console.warn('无事件逻辑'); return; } const model = controller.getModel(); if (!logic.xDataCtrlName) { console.warn('无数据目标部件'); } else { // 触发源为数据部件或当前部件(适配导航工具栏) if ( model?.xDataCtrlName?.toLowerCase() === logic.xDataCtrlName.toLowerCase() || model.name.toLowerCase() === logic.xDataCtrlName.toLowerCase() ) { // 获取参数 const { context, viewParams } = controller.getStore(); const tempContext = deepCopy(context); const tempViewParams = deepCopy(viewParams); // 获取能力 const ability = controller.getSubAbility( logic.xDataCtrlName.toLowerCase() ) as IDECtrlAbility; // 获取数据 let data: IParam[] = []; if (ability) { data = ability.getData(); } // 执行视图逻辑 App.getViewLogicHelper().executeViewLogic( tempContext, tempViewParams, data, event, ability, logic ); } } } /** * 处理导航部件快速搜索 * * @export * @param {IExpCtrlController} controller * @param {string} searchValue */ export function handleQuickSearch( controller: IExpCtrlController, searchValue: string ) { controller.search(searchValue); }