import { Component } from 'vue-property-decorator'; import { VueLifeCycleProcessing } from '../../../decorators'; import { contextMenu, ContextMenuItem } from '@ibiz/context-menu'; import { DesignContainerBase } from '../design-container-base/design-container-base'; import { Util } from '@ibizstudio-ex/runtime'; @Component({}) @VueLifeCycleProcessing() export class DesignGridContainer extends DesignContainerBase { /** * 子数据布局模式支持 * * @author chitanda * @date 2022-03-21 10:03:40 * @type {number[][]} */ layoutMode: number[][] = [[12], [3, 6, 3], [3, 9], [9, 3], [6, 6], [4, 4, 4], [3, 3, 3, 3]]; /** * @description 子项默认参数 * @memberof DesignContainerGrid */ defaultChildParam = { itemtype: 'CONTAINER', showcaption: 0, playoutmode: 'SIMPLEFLEX' }; /** * @description 自定义右键菜单项 * @type {ContextMenuItem[]} * @memberof DesignContainerGrid */ contextMenus: ContextMenuItem[] = [ { tag: 'addBefore', text: '在左侧添加', icon: 'assets/svg/double-left-arrow.svg', }, { tag: 'addAfter', text: '在右侧添加', icon: 'assets/svg/double-right-arrow.svg', }, { type: 'separator', }, { tag: 'remove', text: '删除', icon: 'assets/svg/trash.svg', }, ]; /** * 选择子项布局绘制模式 * * @author chitanda * @date 2022-03-21 15:03:46 * @return {*} {VNode} */ renderSelectModel(): any { return (
{this.layoutMode.map(arr => { return (
this.onCellClick(e, arr)} > {arr.map(item => { return (
{item}
); })}
); })}
取消
); } /** * @description 栅格子项 * @param {MouseEvent} e * @param {number[]} arr * @return {*} {Promise} * @memberof DesignGroup */ async onCellClick(e: MouseEvent, arr: number[]): Promise { e.stopPropagation(); this.service.disableAcc(); const items = arr.map((num, index) => { return { ...this.defaultChildParam, flexgrow: num, srfpkey: this.data.srfkey, srfkey: Util.createUUID(), ppssysviewpanelitemid: this.data.pssysviewpanelitemid, ppssysviewpanelitemname: this.data.pssysviewpanelitemname, ordervalue: (index + 1) * 100, }; }); for (let index = 0; index < items.length; index++) { const data = items[index]; const res = await this.service.GetDraftTemp(this.context, data); if (res.ok) { await this.service.CreateTemp(this.context, res.data); } } this.service.enableAcc(); (this.ctx.ctrl as any).evt.emit("refreshPanel"); } /** * 取消新建 * * @author chitanda * @date 2022-03-21 18:03:12 * @param {MouseEvent} e */ onCancel(e: MouseEvent): void { e.stopPropagation(); this.deleteHandle(e); } /** * 绘制栅格容器 * * @author chitanda * @date 2022-03-22 15:03:20 * @param {number} i * @param {PanelLayoutDataProvider} data * @return {*} {VNode} */ renderGridContainer(i: number, data: any): any { const style: Record = {}; if (data.flexgrow != null && data.flexgrow > 0) { style.width = `${(data.flexgrow / 12) * 100}%`; } else { style['flex-grow'] = 1; style['flex-basis']=0; style.width = "auto"; style.minWidth = `${(1 / 12) * 100}%`; } return ( this.onContextMenu(e, i, data), }} /> ); } /** * @description 点击打开自定义功能菜单 * @param {MouseEvent} event * @param {number} i * @param {*} data * @memberof DesignGroup */ onContextMenu(event: MouseEvent, i: number, data: any): void { if (event) { event.stopPropagation(); } contextMenu.open(event, this.contextMenus, { minWidth: 150 }).click((item: ContextMenuItem) => { this.onContextMenuClick(event, item, i, data); }); } /** * 上下文菜单点击 * * @author chitanda * @date 2022-03-22 15:03:38 * @param {MouseEvent} e * @param {ContextMenuItem} item * @param {number} i 数据位置 * @param {PanelLayoutDataProvider} data 当前数据 */ onContextMenuClick($event: MouseEvent, item: ContextMenuItem, i: number, data: any): void { switch (item.tag) { case 'addBefore': this.addAutoChild(i); break; case 'addAfter': this.addAutoChild(i + 1); break; case 'remove': this.deleteChild(data); break; } } /** * 添加一个自适应子 * * @author chitanda * @date 2022-03-22 17:03:10 * @param {number} i 需要插入的位置 * @return {*} {Promise} */ async addAutoChild(i: number): Promise { const param = { ...this.defaultChildParam, srfpkey: this.data.srfkey, srfkey: Util.createUUID(), ppssysviewpanelitemid: this.data.pssysviewpanelitemid, ppssysviewpanelitemname: this.data.pssysviewpanelitemname, }; const res = await this.service.GetDraftTemp(this.context, param); if (res.ok) { this.service.disableAcc(); const result = await this.service.CreateTemp(this.context, res.data); if (result.ok) { this.list.splice(i, 0, result.data); await this.sortChildren(i); } this.service.enableAcc(); } } /** * 从第几个开始重新排序 * * @author chitanda * @date 2022-02-21 19:02:03 * @param {number} num 开始排序下标 */ async sortChildren(num: number) { if (this.list.length === 0) { this.$forceUpdate(); return; } for (let i = num; i < this.list.length; i++) { const item = this.list[i]; item.ordervalue = (i + 1) * 100; } const items = this.list.slice(num); await this.service.updateBatchLocal(this.context, items); } /** * 删除子数据 * * @author chitanda * @date 2022-02-21 16:02:47 * @param {PanelDataProvider} data * @return {*} {Promise} */ deleteChild(data: any): void { this.service.disableAcc() this.service.RemoveTemp(this.context, data); const i = this.list.findIndex(item => item.pssysviewpanelid === data.pssysviewpanelid); this.list.splice(i, 1); this.setSelect(this.data); this.sortChildren(i); this.service.enableAcc(); this.$forceUpdate(); } /** * @description 绘制子项 * @param {*} item * @return {*} * @memberof DesignGroup */ renderChildItem(item: any) { if (item.isDefaultLayout || item.isCtrls) { return null; } return this.ctx.ctrl.renderChildItem(this.$createElement, this.ctx, item, this.data); } /** * @description 绘制拖拽区 * @param {any[]} list * @param {*} [content] * @return {*} {*} * @memberof DesignGroup */ renderDraggable(list: any[], content?: any): any { const h = this.$createElement; return h( 'draggable', { attrs: { handle: this.options.handle, group: this.options.group, ghostClass: 'ghostClass-draggle', forceFallback: true, animation: this.options.animation, list: list, }, class: 'draggable-container', on: { change: (e: any) => this.change(e, list), }, }, [ h( 'transition-group', { attrs: { type: 'transition', name: 'flip-list', }, class: this.getDraggableClass(), ...this.getDraggableOtherParams(), }, content, ), ], ); } /** * @description 外层容器-重绘 * @return {*} {*} * @memberof DesignContainerGrid */ renderContent(): any { const { text, showcaption, showtitlebar } = this.data; const contentStyle = this.getContentStyle(this.data); const hiddenHeader = showcaption == 0 || showtitlebar == 0; return (
{ hiddenHeader ? (
{text}
) : (
{text}
) } < div class='content' style={contentStyle}>
{Object.is(this.list?.length, 0) ? this.renderSelectModel() : null } {this.list?.map((item: any, i: number) => this.renderGridContainer(i, item))}
); } render() { const { srfkey } = this.data; this.calcStyle(); return (
this.onActiveClick(e, this.data)} on-dblclick={(e: any) => this.editorHandle(e)} > {this.renderContent()} {this.renderOther()}
); } }