import { Vue, Component } from 'vue-property-decorator'; import { Subject } from 'rxjs'; import { Util, ViewTool, ModelTool, LogUtil, throttle, CalendarControlInterface } from '@ibizstudio/runtime'; import { MDControlBase } from './md-control-base'; import { GlobalService } from '@ibizstudio/runtime'; import { AppCalendarService } from '../ctrl-service'; import { ContextMenu } from '../components/common/context-menu/context-menu'; import { AppDefaultContextMenu } from '../components/control/app-default-contextmenu/app-default-contextmenu'; import { AppViewLogicService } from '../app-service'; import { IPSAppDataEntity, IPSAppDECalendarView, IPSAppView, IPSAppViewRef, IPSDECalendar, IPSDECMUIActionItem, IPSDEContextMenu, IPSDETBUIActionItem, IPSDEToolbar, IPSDEToolbarItem, IPSDEUIAction, IPSSysCalendar, IPSSysCalendarItem, } from '@ibizstudio/runtime'; import moment from 'moment'; import { VueLifeCycleProcessing, Watch } from '../decorators'; /** * 应用日历部件基类 * * @export * @class CalendarControlBase * @extends {MDControlBase} */ @Component({ components: { 'app-default-contextmenu': AppDefaultContextMenu, }, }) @VueLifeCycleProcessing() export class CalendarControlBase extends MDControlBase implements CalendarControlInterface { /** * 日历部件模型实例 * * @type {*} * @memberof CalendarControlBase */ declare controlInstance: IPSDECalendar; /** * 日历部件样式名 * * @public * @type {any[]} * @memberof CalendarControlBase */ calendarClass: string = 'calendar'; /** * 日历默认打开样式 * * @type {string} * @memberof CalendarControlBase */ defaultView: string = 'dayGridMonth'; /** * this引用 * * @type {any} * @memberof CalendarControlBase */ thisRef: any = this; /** * 组件key值(用于刷新日历) * * @type {any} * @memberof CalendarControlBase */ UUKey: string = Util.createUUID(); /** * 设置头部显示 * * @public * @type {} * @memberof CalendarControlBase */ header: any = { left: 'prev,next today gotoDate', center: 'title', right: 'dayGridMonth,timeGridWeek,timeGridDay,listWeek', }; /** * 按钮文本集合 * * @public * @type {} * @memberof CalendarControlBase */ buttonText: any = { today: this.$t('app.calendar.today'), month: this.$t('app.calendar.month'), week: this.$t('app.calendar.week'), day: this.$t('app.calendar.day'), list: this.$t('app.calendar.list'), }; /** * 自定义按钮集合 * * @public * @type {} * @memberof CalendarControlBase */ customButtons: any = { gotoDate: { text: this.$t('app.calendar.gotodate'), click: this.openDateSelect, }, }; /** * 模态显示控制变量 * * @public * @type boolean * @memberof CalendarControlBase */ modalVisible: boolean = false; /** * 跳转日期 * * @public * @type Date * @memberof CalendarControlBase */ selectedGotoDate: Date = new Date(); /** * 日历部件动态参数 * * @type {any} * @memberof CalendarControlBase */ ctrlParams: any; /** * 有效日期范围 * * @public * @type {} * @memberof CalendarControlBase */ validRange: any = { start: '0000-01-01', end: '9999-12-31', }; /** * 默认加载日期 * * @public * @type {} * @memberof CalendarControlBase */ defaultDate: any = Util.dateFormat(new Date()); /** * 快速工具栏项 * * @type {Array} * @memberof CalendarControlBase */ quickToolbarItems: Array = []; /** * 快速工具栏模型 * * @type {*} * @memberof CalendarControlBase */ quickToolbarModels: any = {}; /** * 日程事件集合 * * @public * @type {any[]} * @memberof CalendarControlBase */ events: any[] = []; /** * 日历项上下文菜单集合 * * @type {string[]} * @memberof CalendarControlBase */ actionModel: any = { //TODO待补充 }; /** * 备份日历项上下文菜单 * * @type {string[]} * @memberof CalendarControlBase */ copyActionModel: any; /** * 日历样式类型 * * @public * @type {string} * @memberof CalendarControlBase */ calendarType: string = ''; /** * 图例显示控制 * * @public * @type {any} * @memberof CalendarControlBase */ isShowlegend: any = {}; /** * 是否已经选中第一条数据 * * @type {boolean} * @memberof CalendarControlBase */ isSelectFirst: boolean = false; /** * 事件id * * @type {string} * @memberof CalendarControlBase */ eventid: string = ''; /** * 事件类型map * * @type {any} * @memberof CalendarControlBase */ eventKey: any = new Map(); /** * 查询参数缓存 * * @public * @type {any} * @memberof CalendarControlBase */ searchArgCache: any = {}; /** * 监听部件动态参数变化 * * @param {*} newVal * @param {*} oldVal * @memberof CalendarControlBase */ onDynamicPropsChange(newVal: any, oldVal: any) { super.onDynamicPropsChange(newVal, oldVal); } /** * 监听部件参数变化 * * @param {*} newVal * @param {*} oldVal * @memberof CalendarControlBase */ onStaticPropsChange(newVal: any, oldVal: any) { this.isSelectFirstDefault = newVal.isSelectFirstDefault ? true : false; super.onStaticPropsChange(newVal, oldVal); } /** * 部件模型数据初始化 * * @memberof CalendarControlBase */ async ctrlModelInit(args?: any) { await super.ctrlModelInit(); if (!(this.Environment && this.Environment.isPreviewMode)) { this.service = new AppCalendarService(this.controlInstance, this.context); this.appEntityService = await new GlobalService().getService(this.appDeCodeName, this.context); } this.initShowLegend(); this.initActionModel(); this.initQuickToolbar(); this.initEventKey(); this.calendarType = this.controlInstance?.calendarStyle; this.ctrlParams = this.controlInstance?.getPSControlParam()?.ctrlParams; if (Object.is(this.calendarType, 'WEEK')) { this.defaultView = 'timeGridWeek'; } else if (Object.is(this.calendarType, 'DAY')) { this.defaultView = 'timeGridDay'; } } /** * 部件模型数据加载 * * @memberof CalendarControlBase */ async ctrlModelLoad() { const calendarItems = (this.controlInstance as IPSSysCalendar).getPSSysCalendarItems() || []; if (calendarItems.length > 0) { for (const item of calendarItems) { await item.getPSAppDataEntity?.()?.fill?.(); await item.getNavPSAppView?.()?.fill?.(); } } } /** * 日历视图部件初始化 * * @memberof CalendarControlBase */ ctrlInit() { super.ctrlInit(); if (Object.is(this.calendarType, 'TIMELINE')) { this.searchEvents(); } else { this.setButtonText(); } } viewStateAction(tag: string, action: string, data: any) { if (!Object.is(tag, this.name)) { return; } super.viewStateAction(tag, action, data); } /** * 部件挂载 * * @memberof CalendarControlBase */ ctrlMounted() { super.ctrlMounted(); let appCalendar: any = this.$refs[this.controlInstance?.codeName]; if (appCalendar) { let api = appCalendar.getApi(); api.updateSize(); } } /** * 初始化日历项上下文菜单集合 * * @memberof CalendarControlBase */ initActionModel() { const calendarItems: Array = (this.controlInstance as IPSSysCalendar).getPSSysCalendarItems() || []; let tempModel: any = {}; if (calendarItems.length > 0) { calendarItems.forEach((item: IPSSysCalendarItem) => { const contextMenuItems: Array = (item.getPSDEContextMenu() as IPSDEContextMenu)?.getPSDEToolbarItems() || []; if (contextMenuItems.length > 0) { contextMenuItems.forEach((toolbarItem: IPSDEToolbarItem) => { this.initActionModelItem(toolbarItem, item, tempModel); }); } }); } this.actionModel = {}; Object.assign(this.actionModel, tempModel); } /** * 初始化上下菜单项 * * @param toolbarItem * @param item * @param tempModel * @memberof CalendarControlBase */ initActionModelItem(toolbarItem: IPSDEToolbarItem, item: IPSSysCalendarItem, tempModel: any) { let tempItem: any = { name: toolbarItem.name, nodeOwner: item.itemType, }; if (toolbarItem.itemType == 'DEUIACTION') { const uiAction: IPSDEUIAction = (toolbarItem as IPSDECMUIActionItem).getPSUIAction() as IPSDEUIAction; if (uiAction) { Object.assign(tempItem, { type: item.itemType, tag: uiAction.id, visabled: true, disabled: false, actiontarget: uiAction.actionTarget, noprivdisplaymode: uiAction.noPrivDisplayMode, dataaccaction: uiAction.dataAccessAction, }); } } tempModel[`${item.itemType}_${toolbarItem.name}`] = tempItem; //TODO YY 上下文菜单子项 // if(toolbarItem.getPSDEToolbarItems?.length > 0){ // for(let toolBarChild of toolbarItem.getPSDEToolbarItems){ // this.initActionModelItem(toolBarChild,item,tempModel) // } // } } /** * 初始化快速工具栏 * * @memberof CalendarControlBase */ initQuickToolbar() { const quickToolbaItems: Array = (ModelTool.findPSControlByType('QUICKTOOLBAR', this.controlInstance.getPSControls() || []) as IPSDEToolbar)?.getPSDEToolbarItems() || []; if (quickToolbaItems.length > 0) { let items: Array = quickToolbaItems.filter((item: IPSDEToolbarItem) => { return item.itemType == 'DEUIACTION'; }); this.quickToolbarItems = [...items]; } this.initQuickToolbarItemModel(); } /** * 初始化快速工具栏模型 * * @memberof CalendarControlBase */ initQuickToolbarItemModel() { const items: Array = this.quickToolbarItems; let models: any = {}; if (items.length > 0) { items.forEach((_item: IPSDEToolbarItem) => { const item: IPSDETBUIActionItem = _item as IPSDETBUIActionItem; const uiAction: IPSDEUIAction = item.getPSUIAction() as IPSDEUIAction; let model: any = {}; Object.assign(model, { name: item.name?.toLowerCase(), actiontarget: 'NONE', disabled: false, visabled: true, type: item.itemType, noprivdisplaymode: uiAction?.noPrivDisplayMode, dataaccaction: uiAction?.dataAccessAction, uiaction: { tag: uiAction?.uIActionTag ? uiAction.uIActionTag : uiAction.id ? uiAction.id : '', target: uiAction?.actionTarget, }, }); Object.assign(models, { [`${item.name?.toLowerCase()}`]: model }); }); } this.quickToolbarModels = {}; Object.assign(this.quickToolbarModels, models); } /** * 初始化事件map对象 * * @memberof CalendarControlBase */ initEventKey() { const calendarItems: Array = (this.controlInstance as IPSSysCalendar).getPSSysCalendarItems() || []; if (calendarItems.length > 0) { calendarItems.forEach(calendarItem => { let eventKey = ModelTool.getAppEntityKeyField(calendarItem?.getPSAppDataEntity())?.codeName?.toLowerCase() || ''; this.eventKey.set(calendarItem.itemType, eventKey); }); } } /** * 初始化图例显示控制 * * @memberof CalendarControlBase */ initShowLegend() { if (Object.keys(this.isShowlegend).length > 0) { return; } const calendarItems: Array = (this.controlInstance as IPSSysCalendar).getPSSysCalendarItems() || []; if (calendarItems.length > 0) { calendarItems.forEach((item: IPSSysCalendarItem) => { this.isShowlegend[item.itemType as string] = true; }); } } /** * 图例点击事件 * * @param {string} itemType 日历项类型 * @return {*} * @memberof CalendarControlBase */ legendTrigger(itemType: string) { const eventDisabled = this.$el.getElementsByClassName('event-disabled').length; if (Object.keys(this.isShowlegend).length != 1 && eventDisabled == Object.keys(this.isShowlegend).length - 1 && this.isShowlegend[itemType]) { return; } this.isShowlegend[itemType] = !this.isShowlegend[itemType]; this.refresh(); } /** * 面板数据变化处理事件 * @param {any} item 当前数据 * @param {any} $event 面板事件数据 * * @memberof CalendarControlBase */ onPanelDataChange(item: any, $event: any) { Object.assign(item, $event, { rowDataState: 'update' }); } /** * 搜索获取日程事件 * * @param {*} [fetchInfo] 日期信息 * @param {*} [successCallback] 成功回调 * @return {*} * @memberof CalendarControlBase */ searchEvents(fetchInfo?: any, successCallback?: any) { if (this.Environment && this.Environment.isPreviewMode) { this.events = []; return; } // 处理请求参数 let start = fetchInfo && fetchInfo.start ? Util.dateFormat(fetchInfo.start) : null; let end = fetchInfo && fetchInfo.end ? Util.dateFormat(fetchInfo.end) : null; let arg = { query_start: start, query_end: end }; if (fetchInfo && fetchInfo.query) { Object.assign(arg, { query: fetchInfo.query }); } const parentdata: any = {}; this.$emit('ctrl-event', { controlname: this.controlInstance?.name, action: 'beforeload', data: parentdata }); Object.assign(arg, parentdata); let tempViewParams: any = parentdata.viewparams ? parentdata.viewparams : {}; Object.assign(tempViewParams, Util.deepCopy(this.viewparams ? this.viewparams : '')); Object.assign(arg, { viewparams: tempViewParams }); // 处理events数据 let _this = this; let handleEvents = () => { if (_this.isSelectFirstDefault) { _this.calendarClass = 'calendar select-first-calendar'; _this.isSelectFirst = true; } let filterEvents = this.events.filter((event: any) => { return _this.isShowlegend[event.itemType]; }); if (successCallback) { successCallback(filterEvents); } }; if (JSON.stringify(arg) === JSON.stringify(this.searchArgCache)) { handleEvents(); return; } else { this.searchArgCache = arg; } let tempContext: any = Util.deepCopy(this.context); const post: Promise = this.service.search(this.loadAction, tempContext, arg, this.showBusyIndicator); post.then( (response: any) => { if (!response || response.status !== 200) { this.$throw(response, 'searchEvents'); return; } // 默认选中第一项 this.events = response.data; this.ctrlEvent({ controlname: this.name, action: 'load', data: this.events, }); handleEvents(); this.scheduleSort(); }, (response: any) => { this.$throw(response, 'searchEvents'); }, ); } /** * 日期点击事件 * * @param {*} $event 日期信息 * @memberof CalendarControlBase */ onDateClick($event: any) { let date = $event.date; let datestr = $event.dateStr; } /** * 时间轴点击事件 * * @param {*} item 项数据 * @memberof CalendarControlBase */ onTimeLineClick(item: any) { this.events.forEach((event: any) => { event.srfchecked = 0; }); item.srfchecked = Number(!item.srfchecked); this.onEventClick(item, true); this.$forceUpdate(); } /** * 处理日历日程选中样式 * * @param {*} item 项数据 * @memberof CalendarControlBase */ handleEventSelectStyle($event: any) { const calendarApi: any = (this.$refs[this.controlInstance?.codeName] as any)?.getApi(); if (!calendarApi) { return; } const findApis = (id: any) => { if (!id) { return []; } return calendarApi.getEvents().filter((event: any) => { return event.extendedProps.curdata[this.getEventKey(event.extendedProps)] === id; }); }; const eventId: any = $event.event.extendedProps.curdata[this.getEventKey($event.event.extendedProps)]; const eventApis: any[] = findApis(eventId); eventApis.forEach((api: any) => { const classNames: any[] = [...api.classNames]; if ( classNames.findIndex((className: any) => { return className == 'selected-event'; }) === -1 ) { classNames.push('selected-event'); } api.setProp('classNames', classNames); }); if ((this.isSelectFirstDefault && this.eventid != eventId) || !this.isSelectFirstDefault) { const _eventApis: any[] = findApis(this.eventid); _eventApis.forEach((api: any) => { const _temp: any[] = [...api.classNames]; const index = _temp.findIndex((className: any) => { return className == 'selected-event'; }); if (index !== -1) { _temp.splice(index, 1); api.setProp('classNames', _temp); } }); } this.eventid = this.eventid && this.eventid == eventId && !this.isSelectFirstDefault ? '' : eventId; } /** * 日程点击事件 * * @param {*} $event calendar事件对象或event数据 * @param {*} isOriginData true:$event是原始event数据,false:是组件 * @param {*} $event timeline事件对象 * @memberof CalendarControlBase */ async onEventClick($event: any, isOriginData: boolean = false, $event2?: any) { // 处理event数据 let event: any = {}; if (isOriginData) { event = Util.deepCopy($event); } else { event = Object.assign({ title: $event.event.title, start: $event.event.start, end: $event.event.end }, $event.event.extendedProps); } // 点击选中样式 let JSelement: any = null; if (!isOriginData && $event.el) { JSelement = $event.el; } else if (isOriginData && $event2 && $event2.currentTarget) { JSelement = $event2.currentTarget; } if (JSelement) { this.calendarClass = 'calendar'; } const eventId: any = event.curdata[this.getEventKey(event)]; let tempItem = this.events.find((_item: any) => { return _item.curdata[this.getEventKey(_item)] == eventId; }); if (this.eventid && this.eventid == eventId) { if (tempItem) tempItem.curdata.srfchecked = 0; } else { if (tempItem) tempItem.curdata.srfchecked = 1; } this.selections = this.eventid && this.eventid == eventId ? [] : [event]; this.handleEventSelectStyle($event); // 处理上下文数据 let _this: any = this; let view: IPSAppView | null | undefined; let _context: any = Object.assign({}, this.context); let _viewparams: any = Object.assign({ start: event.start, end: event.end }, this.viewparams); const item: IPSSysCalendarItem = (((this.controlInstance as IPSSysCalendar).getPSSysCalendarItems() || []) as Array).find((_item: IPSSysCalendarItem) => { return _item.itemType == event.itemType; }) as IPSSysCalendarItem; if (item) { const codeName = ((item.getPSAppDataEntity() as IPSAppDataEntity)?.codeName as string).toLowerCase(); if (codeName) { _context[codeName] = event[codeName]; } view = this.getEditView(item); } await view?.fill(); // 导航栏中不需要打开视图,只要抛出选中数据 this.$emit('ctrl-event', { controlname: this.controlInstance.name, action: 'selectionchange', data: this.selections }); if (this.isSelectFirstDefault) { return; } // 根据打开模式打开视图 if (!view) { return; } else if (Object.is(view.openMode, 'INDEXVIEWTAB') || Util.isEmpty(view.openMode)) { const deResParameters: any[] = []; const parameters: any[] = []; await this.processingParameter(this.context, view, deResParameters, parameters); const routePath = ViewTool.buildUpRoutePath(_this.$route, this.context, deResParameters, parameters, [Util.deepCopy(_context)], _viewparams); _this.$router.push(routePath); } else { let container: Subject = new Subject(); if (Object.is(view.openMode, 'POPOVER')) { container = _this.$apppopover.openPop(isOriginData ? $event2 : $event.jsEvent, view, Util.deepCopy(_context), _viewparams); } else if (Object.is(view.openMode, 'POPUPMODAL')) { container = _this.$appmodal.openModal(view, Util.deepCopy(_context), _viewparams); } else if (view.openMode.startsWith('DRAWER')) { container = _this.$appdrawer.openDrawer(view, Util.getViewProps(_context, _viewparams)); } container.subscribe((result: any) => { container.complete(); if (!result || !Object.is(result.ret, 'OK')) { return; } // 刷新日历 _this.refresh(); }); } } /** * 整合参数 * * @memberof AppFuncService */ async processingParameter(context: any, appView: any, deResParameters: any[], parameters: any[]) { let params = []; if (appView.getPSAppDataEntity()) { let result: IPSAppDataEntity = appView.getPSAppDataEntity(); await result.fill(); if (!result) { console.error('未找到应用实体'); return; } if ((appView.openMode && (appView.openMode == 'INDEXVIEWTAB' || appView.openMode == 'POPUPAPP' || appView.openMode == '')) || !appView.openMode) { params = [ { pathName: Util.srfpluralize(result.codeName).toLowerCase(), parameterName: result.codeName.toLowerCase(), }, { pathName: 'views', parameterName: appView.getPSDEViewCodeName().toLowerCase() }, ]; } else { params = [ { pathName: Util.srfpluralize(result.codeName).toLowerCase(), parameterName: result.codeName.toLowerCase(), }, ]; } } else { params = [{ pathName: 'views', parameterName: appView.name.toLowerCase() }]; } Object.assign(parameters, params); } /** * 日历刷新 * * @param {*} [args] 额外参数 * @memberof CalendarControlBase */ refresh(args?: any) { if (Object.is(this.calendarType, 'TIMELINE')) { this.searchArgCache = {}; this.searchEvents(); } else if (this.ctrlParams) { let calendarTimeLine: any = this.$refs['appCalendarTimeline']; if (calendarTimeLine) { calendarTimeLine.refetchEvents(); } } else { let calendarApi = (this.$refs[this.controlInstance?.codeName] as any).getApi(); calendarApi.refetchEvents().then(() => { this.UUKey = Util.createUUID(); }); } this.$forceUpdate(); } /** * 日程拖动事件 * * @param {*} $event 事件信息 * @memberof CalendarControlBase */ onEventDrop($event: any) { if (this.isSelectFirstDefault) { return; } let arg: any = {}; let _context: any = Object.assign({}, this.context); arg.start = Util.dateFormat($event.event.start); arg.end = Util.dateFormat($event.event.end); let itemType = $event.event._def.extendedProps.itemType; const item: IPSSysCalendarItem = (((this.controlInstance as IPSSysCalendar).getPSSysCalendarItems() || []) as Array).find((_item: IPSSysCalendarItem) => { return _item.itemType == itemType; }) as IPSSysCalendarItem; if (item) { const codeName = ((item.getPSAppDataEntity() as IPSAppDataEntity)?.codeName as string).toLowerCase(); if (codeName) { arg[codeName] = $event.event._def.extendedProps[codeName]; _context[codeName] = $event.event._def.extendedProps[codeName]; } } Object.assign(arg, { viewparams: this.viewparams }); let tempContext: any = Util.deepCopy(this.context); this.onControlRequset('onEventDrop', tempContext, arg); const post: Promise = this.service.update(itemType, tempContext, arg, this.showBusyIndicator); post.then( (response: any) => { this.onControlResponse('onEventDrop', response); if (!response || response.status !== 200) { this.$throw(response, 'onEventDrop'); return; } }, (response: any) => { this.onControlResponse('onEventDrop', response); this.$throw(response, 'onEventDrop'); }, ); } /** * 快速工具栏菜单项点击 * * @param {*} tag 菜单项标识 * @param {*} $event 事件源 * @memberof CalendarControlBase */ itemClick(tag: any, $event: any) { AppViewLogicService.getInstance().executeViewLogic(`calendar_quicktoolbar_${tag}_click`, $event, this, {}, this.controlInstance.getPSAppViewLogics() || []); } /** * 时间点击 * * @param {*} $event 当前时间 * @param {*} jsEvent 原生事件对象 * @returns * @memberof CalendarControlBase */ onDayClick($event: any, jsEvent: any) { let _this: any = this; let content: any = this.renderBarMenu; const container: any = _this.$apppopover.openPopover(jsEvent, content, 'left-end', true, 103, _this.quickToolbarItems.length * 34); } /** * 计算节点右键权限 * * @param {*} data 日历项数据 * @param {*} appEntityName 应用实体名称 * @returns * @memberof CalendarControlBase */ async computeNodeState(data: any, appEntityName: string) { let service = await new GlobalService().getService(appEntityName, this.context); if (this.copyActionModel && Object.keys(this.copyActionModel).length > 0) { if (service['Get'] && service['Get'] instanceof Function) { let tempContext: any = Util.deepCopy(this.context); tempContext[appEntityName.toLowerCase()] = data[appEntityName.toLowerCase()]; let targetData = await service.Get(tempContext, {}); ViewTool.calcTreeActionItemAuthState(targetData.data, this.copyActionModel, this.appUIService); return this.copyActionModel; } else { LogUtil.warn(this.$t('app.warn.geterror')); return this.copyActionModel; } } return this.copyActionModel; } /** * 计算日历日程样式 * * @param info */ handleEventStyle(info?: any) { if (!info) { return; } const calendarApi: any = (this.$refs[this.controlInstance?.codeName] as any)?.getApi(); if (!calendarApi) { return; } const data = info.event.extendedProps.curdata; let calendarItem: IPSSysCalendarItem = (((this.controlInstance as IPSSysCalendar).getPSSysCalendarItems() || []) as Array).find((_item: IPSSysCalendarItem) => { return _item.itemType == data.itemType; }) as IPSSysCalendarItem; const cssName = calendarItem?.getPSSysCss?.()?.cssName; const calendarEvents: any[] = calendarApi.getEvents().filter((event: any) => { return event.extendedProps.curdata[this.getEventKey(event.extendedProps)] === data[this.getEventKey(info.event.extendedProps)]; }); if (cssName && calendarEvents.length > 0) { calendarEvents.forEach((event: any) => { const classNames: any[] = [...event.classNames]; if ( classNames.findIndex((className: any) => { return className == cssName; }) === -1 ) { classNames.push(cssName); event.setProp('classNames', classNames); } }); } } /** * 事件绘制回调 * * @param {*} info 信息 * @memberof CalendarControlBase */ eventRender(info?: any) { if (this.isSelectFirstDefault && this.isSelectFirst) { this.isSelectFirst = false; this.onEventClick(info); } this.handleEventStyle(info); let data = Object.assign({ title: info.event.title, start: info.event.start, end: info.event.end }, info.event.extendedProps); info.el.addEventListener('contextmenu', (event: MouseEvent) => { this.copyActionModel = {}; Object.values(this.actionModel).forEach((item: any) => { if (Object.is(item.nodeOwner, data.itemType)) { this.copyActionModel[item.name] = item; } }); if (Object.keys(this.copyActionModel).length === 0) { return; } let dataMapping: IPSSysCalendarItem = (((this.controlInstance as IPSSysCalendar).getPSSysCalendarItems() || []) as Array).find((_item: IPSSysCalendarItem) => { return _item.itemType == data.itemType; }) as IPSSysCalendarItem; const appDECodeName = (dataMapping.getPSAppDataEntity() as IPSAppDataEntity)?.codeName as string; if (!appDECodeName) { return; } this.computeNodeState(data, appDECodeName).then((result: any) => { let flag: boolean = false; if (Object.values(result).length > 0) { flag = Object.values(result).some((item: any) => { return item.visabled === true; }); } if (flag) { let props = { data: data, renderContent: this.renderContextMenu }; let component = ContextMenu; const vm: any = new Vue({ render(h) { return h(component, { props }); }, }).$mount(); document.body.appendChild(vm.$el); const comp: any = vm.$children[0]; comp.showContextMenu(event.clientX, event.clientY); } }); }); } /** * 绘制右键菜单 * * @param {*} event * @returns * @memberof CalendarControlBase */ renderContextMenu(event: any) { if (!event || !event.itemType) { return null; } this.selections = [event]; const calendarItems: Array = (this.controlInstance as IPSSysCalendar).getPSSysCalendarItems() || []; if (calendarItems.length > 0) { let item: IPSSysCalendarItem = calendarItems.find((_item: IPSSysCalendarItem) => { return _item.itemType == event.itemType; }) as IPSSysCalendarItem; const contextMenu = item.getPSDEContextMenu() as IPSDEContextMenu; if (contextMenu && contextMenu.controlType == 'CONTEXTMENU') { let { targetCtrlName, targetCtrlParam, targetCtrlEvent }: { targetCtrlName: string; targetCtrlParam: any; targetCtrlEvent: any } = this.computeTargetCtrlData(contextMenu, event); targetCtrlParam.dynamicProps.contextMenuActionModel = this.copyActionModel; return this.$createElement(targetCtrlName, { props: targetCtrlParam, ref: contextMenu.name, on: targetCtrlEvent }); } } return null; } /** * 绘制快速工具栏项 * * @returns * @memberof CalendarControlBase */ renderBarMenu() { return (
throttle(this.itemClick, [$event, $event2], this)}> {this.quickToolbarItems.map((item: any) => { return ( {item.showIcon && item.getPSSysImage ? : null} {item.showCaption ? {item.caption} : null} ); })}
); } /** * 部件事件 * @param ctrl 部件 * @param action 行为 * @param data 数据 * * @memberof CalendarControlBase */ onCtrlEvent(controlname: string, action: string, data: any) { if (action == 'contextMenuItemClick') { AppViewLogicService.getInstance().executeViewLogic(`${controlname}_${data?.data}_click`, undefined, this, {}, this.controlInstance?.getPSAppViewLogics() || []); } else if (action == 'panelDataChange') { this.onPanelDataChange(data.item, data.data); } else { this.ctrlEvent({ controlname, action, data }); } } /** * 设置按钮文本 * * @public * @memberof CalendarControlBase */ setButtonText() { (this.buttonText.today = this.$t('app.calendar.today')), (this.buttonText.month = this.$t('app.calendar.month')), (this.buttonText.week = this.$t('app.calendar.week')), (this.buttonText.day = this.$t('app.calendar.day')), (this.buttonText.list = this.$t('app.calendar.list')); this.customButtons.gotoDate.text = this.$t('app.calendar.gotodate'); } /** * 监听语言变化 * * @public * @memberof CalendarControlBase */ @Watch('$i18n.locale') onLocaleChange(newval: any, val: any) { this.setButtonText(); } /** * 打开时间选择模态 * * @public * @memberof CalendarControlBase */ openDateSelect() { this.modalVisible = true; } /** * 跳转到指定时间 * * @public * @memberof CalendarControlBase */ gotoDate() { let appCalendar: any = this.$refs[this.controlInstance?.codeName]; let api = appCalendar?.getApi(); if (api) { api.gotoDate(this.selectedGotoDate); } } /** * 获取事件key * * @param {*} event 事件对象 * @return {*} * @memberof CalendarControlBase */ getEventKey(event: any) { if (event?.itemType && this.eventKey.has(event.itemType)) { return this.eventKey.get(event.itemType); } return ''; } /** * 获取编辑视图信息 * * @param {string} deName 视图名称 * @return {*} * @memberof CalendarControlBase */ getEditView(item: IPSSysCalendarItem) { let parentModel: IPSAppDECalendarView = (this.controlInstance as any).parentModel; if (parentModel && parentModel?.getPSAppViewRefs?.()?.length) { const viewRef: IPSAppViewRef = (parentModel as any).getPSAppViewRefs().find((element: any) => { return element.id.endsWith(`@${item.id}`); }); return viewRef.getRefPSAppView(); } } /** * 计算部件所需参数 * * @param {*} controlInstance 部件模型对象 * @param {*} item 日历项数据 * @returns * @memberof CalendarControlBase */ computeTargetCtrlData(controlInstance: any, item?: any) { const { targetCtrlName, targetCtrlParam, targetCtrlEvent } = super.computeTargetCtrlData(controlInstance); Object.assign(targetCtrlParam.dynamicProps, { navdatas: [item?.curdata], }); Object.assign(targetCtrlParam.staticProps, { transformData: this.transformData, opendata: this.opendata, newdata: this.newdata, refresh: this.refresh, }); targetCtrlEvent['ctrl-event'] = ({ controlname, action, data }: { controlname: string; action: string; data: any }) => { this.onCtrlEvent(controlname, action, { item: item.curdata, data: data }); }; return { targetCtrlName, targetCtrlParam, targetCtrlEvent }; } /** * 日程排序 * * @memberof CalendarControlBase */ scheduleSort() { if (Object.is(this.calendarType, 'TIMELINE') && this.events.length > 0) { this.events.sort((a: any, b: any) => { const x: any = a.start; const y: any = b.start; return moment(x).isAfter(y) ? -1 : moment(x).isBefore(y) ? 1 : 0; }); // 默认选中第一项 if (this.isSelectFirstDefault) { this.onTimeLineClick(this.events[0]); } } } }