import { IParam, IHttpResponse, ICalendarControllerParams, ICtrlActionResult, } from '@/core/interface'; import { ICalendarAbility } from '@/core/interface/widgets/ability'; import { ICalendarController } from '@/core/interface/widgets/controller'; import { CalendarActionType } from '@/core/interface/widgets/event'; import { ICalendarStore } from '@/core/interface/widgets/store'; import { ControlVOBase } from '@/core/modules'; import CalendarService from '@/core/modules/ctrl-service/calendar-service'; import { dateFormat, deepCopy } from '@/core/utils'; import { compareAsc, parseISO } from 'date-fns'; import { MDCtrlController } from './md-ctrl-controller'; /** * 日历控制器 (todo:ctrlMounted存在问题) * * @export * @class CalendarController * @extends {(MDCtrlController)} * @implements {ICalendarController} * @template A */ export class CalendarController extends MDCtrlController implements ICalendarController { /** * Creates an instance of CalendarController. * @param {ICalendarControllerParams} params * @memberof CalendarController */ public constructor( params: ICalendarControllerParams ) { super(params); this.ctrlInit(params); } /** * 日历部件服务 * * @type {CalendarService} * @memberof CalendarController */ declare ctrlService: CalendarService; /** * 备份日历项上下文菜单 * * @memberof CalendarController */ public copyActionModel: IParam = {}; /** * 查询参数缓存 * * @memberof CalendarController */ public searchArgCache: IParam = {}; /** * 事件类型map * * @memberof CalendarController */ public eventKey: Map = new Map(); /** * 是否已经选中第一条数据 * * @type {boolean} * @memberof CalendarController */ public isSelectFirst = false; /** * 处理部件初始化 * * @protected * @param { ICalendarControllerParams} params * @memberof CalendarController */ protected processCtrlInit( params: ICalendarControllerParams ) { super.processCtrlInit(params); Object.assign(this.store, { isNoData: false, quickToolbarItems: [], events: [], calendarType: '', defaultView: 'dayGridMonth', isShowLegend: {}, }); // 初始化图例显示控制 this.initShowLegend(); // TODO 初始化上下文菜单 // this.initActionModel(); // TODO 初始化快速工具栏 // this.initQuickToolbar(); // 初始化事件map对象 this.initEventKey(); this.store.calendarType = this.model.calendarStyle; if (Object.is(this.store.calendarType, 'WEEK')) { this.store.defaultView = 'timeGridWeek'; } else if (Object.is(this.store.calendarType, 'DAY')) { this.store.defaultView = 'timeGridDay'; } } /** * 初始化图例显示控制 * * @memberof CalendarController */ public initShowLegend() { if (Object.keys(this.store.isShowLegend).length > 0) { return; } const calendarItems = this.model.calendarItems; if (calendarItems.length > 0) { calendarItems.forEach((item: IParam) => { this.store.isShowLegend[item.itemType] = true; }); } } /** * 初始化事件map对象 * * @memberof CalendarController */ public initEventKey() { const calendarItems = this.model.calendarItems; if (calendarItems.length > 0) { calendarItems.forEach((calendarItem: IParam) => { this.eventKey.set( calendarItem.itemType, calendarItem?.entityKeyName?.toLowerCase() ); }); } } /** * 日历数据加载 * * @param {IParam} [opts={}] * @param {boolean} [pageReset=false] * @return {*} {Promise} * @memberof ChartController */ public async load(opts: IParam = {}): Promise { if (!Object.is(this.store.calendarType, 'TIMELINE') && !opts.callback) { this.emit('refetchEvents', []); return { ok: false, data: this.getData(), rowData: { status: 500 } }; } const _this = this; const { context, viewParams } = this.store; const { fetchAction } = this.actions; if (!fetchAction) { console.warn(App.ts('widget.md.notconfig.fetchaction', '未配置加载行为')); return { ok: false, data: this.getData(), rowData: [] }; } const { limit, noSort, sortDir, sortField } = this.model; // 处理请求参数 const calendarArgs = opts.arg; const start = calendarArgs && calendarArgs.start ? dateFormat(calendarArgs.start) : null; const end = calendarArgs && calendarArgs.end ? dateFormat(calendarArgs.end) : null; const arg = { start: start, end: end }; if (opts && opts.query) { Object.assign(arg, { query: opts.query }); } const page: any = {}; // 开启分页 Object.assign(page, { page: 0, size: limit || 1000 }); // 排序 if (!noSort && sortField) { Object.assign(page, { sort: `${sortField},${sortDir ? sortDir : 'asc'}`, }); } Object.assign(arg, page); const parentData: IParam = {}; this.emit('beforeLoad', [parentData]); Object.assign(arg, parentData); const tempViewParams: IParam = parentData.viewParams ? parentData.viewParams : {}; Object.assign(arg, { viewParams: tempViewParams }); const tempContext = deepCopy(context); this.beforeAsyncAction('load', tempContext, arg); try { const response: IHttpResponse = await this.ctrlService.search( fetchAction, tempContext, arg ); if (!response.success) { this.afterAsyncAction('load', response); return { ok: false, data: this.getData(), rowData: response, }; } const { total } = response as IParam; if (total) { this.store.totalRecord = total as number; } this.store.data = response.data; this.store.events = this.store.data; if (this.selectFirstDefault) { this.isSelectFirst = true; } const filterEvents = this.store.events.filter((event: any) => { return _this.store.isShowLegend[event.itemType]; }); if (opts.callback) { opts.callback(filterEvents); } this.scheduleSort(); this.afterAsyncAction('load', response); return { ok: true, data: this.getData(), rowData: response, }; } catch (error: any) { this.afterAsyncAction('load', error); if (error) { return error; } else { return { ok: false, data: this.getData(), rowData: error, }; } } } /** * 日程排序 * * @memberof CalendarController */ public scheduleSort() { if ( Object.is(this.store.calendarType, 'TIMELINE') && this.store.events.length > 0 ) { this.store.events.sort((a: any, b: any) => { const x: any = a.start; const y: any = b.start; const xDate = parseISO(x); const yDate = parseISO(y); const currentTime = compareAsc(xDate, yDate); return currentTime; }); // 默认选中第一项 if (this.selectFirstDefault) { this.onTimeLineClick(this.store.events[0]); } } } /** * 时间轴点击事件 * * @param {*} item 项数据 * @memberof CalendarController */ public onTimeLineClick(item: any) { this.store.events.forEach((event: any) => { event.srfchecked = 0; }); item.srfchecked = Number(!item.srfchecked); this.onEventClick(item, true); } /** * 日程点击事件 * * @param {*} arg calendar事件对象或event数据 * @param {*} isOriginData true:$event是原始event数据,false:是组件 * @memberof CalendarController */ public onEventClick(arg: IParam, isOriginData = false) { let event: any = {}; if (isOriginData) { event = arg; } else { const data = arg.event.extendedProps.$DO; const calendarItem = this.model.calendarItems.find((_item: IParam) => { return _item.itemType == data.itemType; }); event = Object.assign( { title: arg.event.title, start: arg.event.start, end: arg.event.end, srfkey: data[calendarItem.entityKeyName?.toLowerCase()], }, data ); } this.store.selections = [event]; this.emit('selectionChange', this.store.selections); } /** * 获取事件key * * @param {*} event 事件对象 * @return {*} * @memberof CalendarController */ public getEventKey(event: any) { if (event?.itemType && this.eventKey.has(event.itemType)) { return this.eventKey.get(event.itemType); } return ''; } /** * 部件挂载 * * @memberof CalendarController */ public ctrlMounted(): void { super.ctrlMounted(); if (this.model.calendarStyle == 'TIMELINE') { this.load({}); } } /** * 设置是否已经选中第一项 * * @param {*} info 信息 * @memberof CalendarController */ public setIsSelectFirst(info: boolean) { this.isSelectFirst = info; } /** * 处理上下文菜单选中 * * @memberof CalendarController */ public handleContextMenuItemClick(arg: IParam, args: IParam) { this.onEventClick(arg); const { context, viewParams } = this.store; const tempContext = deepCopy(context); const tempViewParams = deepCopy(viewParams); const data = this.getData(); const event = args.event; const ability = this.getAbility(); const logic = args.item.uiAction; // 执行视图逻辑 App.getViewLogicHelper().executeViewLogic( tempContext, tempViewParams, data, event, ability, logic ); } /** * 获取部件能力 * * @return {*} {A} * @memberof CalendarController */ public getAbility(): ICalendarAbility { return { ...super.getAbility(), }; } }