diff --git a/src/control/grid/grid/grid.tsx b/src/control/grid/grid/grid.tsx index c5c9b9130d26835fe1902bd7bc4660bfcafe0498..2a53be9cb0834fd23eb8fd31eb0a81dab5bac93e 100644 --- a/src/control/grid/grid/grid.tsx +++ b/src/control/grid/grid/grid.tsx @@ -20,6 +20,8 @@ export const GridControl = defineComponent({ * @type {(number | 0 | 1 | 2)} */ mdctrlActiveMode: { type: Number, default: 2 }, + + singleSelect: { type: Boolean, default: true } }, setup() { const c = useControlController((...args) => new GridController(...args)); diff --git a/src/control/index.ts b/src/control/index.ts index e790b9aee9b51941b811ebfb30073e157d00be0d..a1a3f9f14281ed734323431710af7ad065556bda 100644 --- a/src/control/index.ts +++ b/src/control/index.ts @@ -6,3 +6,4 @@ export * from './toolbar'; export * from './panel'; export * from './caption-bar'; export * from './data-view'; +export * from './pickup-view-panel'; diff --git a/src/control/list/list.controller.ts b/src/control/list/list.controller.ts index cde86e7777663f259d16d2868a2a401cc0324e9c..e4d895a33053f662cab4ac46f028e1f7313195de 100644 --- a/src/control/list/list.controller.ts +++ b/src/control/list/list.controller.ts @@ -55,4 +55,28 @@ export class ListController await super.afterLoad(allItems); return this.state.items; } + + /** + * 设置列表数据 + * + * @author zk + * @date 2023-05-26 02:05:46 + * @param {IData[]} items + * @memberof ListController + */ + setData(items: IData[]): void { + this.state.items = items; + } + + /** + * 获取列表数据 + * + * @author zk + * @date 2023-05-26 02:05:35 + * @return {*} {IData[]} + * @memberof ListController + */ + getAllData(): IData[] { + return this.state.items; + } } diff --git a/src/control/list/list.tsx b/src/control/list/list.tsx index 7bedcc627a57a373536761b52be1790840297070..bd88740607de4b293b7a1ef66b13941205a0248a 100644 --- a/src/control/list/list.tsx +++ b/src/control/list/list.tsx @@ -10,6 +10,24 @@ export const ListControl = defineComponent({ modelData: { type: Object as PropType, required: true }, context: { type: Object as PropType, required: true }, params: { type: Object as PropType, default: () => ({}) }, + /** + * 部件行数据默认激活模式 + * - 0 不激活 + * - 1 单击激活 + * - 2 双击激活(默认值) + * + * @type {(number | 0 | 1 | 2)} + */ + mdctrlActiveMode: { type: Number, default: 2 }, + + /** + * 是否为单选 + * - true 单选 + * - false 多选 + * + * @type {(Boolean)} + */ + singleSelect: { type: Boolean, default: true } }, setup() { const c = useControlController((...args) => new ListController(...args)); diff --git a/src/control/pickup-view-panel/index.ts b/src/control/pickup-view-panel/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..9cbda51b3e5f7d2fac27c9ae7ffe0cbbf425bb8d --- /dev/null +++ b/src/control/pickup-view-panel/index.ts @@ -0,0 +1,21 @@ +import { registerControlProvider, ControlType } from '@ibiz-template/runtime'; +import { withInstall } from '@ibiz-template/vue3-util'; +import { App } from 'vue'; +import { PickupViewPanelControl } from './pickup-view-panel'; +import { PickupViewPanelProvider } from './pickup-view-panel.provider'; + +export * from './pickup-view-panel.provider'; +export * from './pickup-view-panel.controller'; + +export const IBizPickupViewPanelControl = withInstall( + PickupViewPanelControl, + function (v: App) { + v.component(PickupViewPanelControl.name, PickupViewPanelControl); + registerControlProvider( + ControlType.PICKUP_VIEW_PANEL, + () => new PickupViewPanelProvider(), + ); + }, +); + +export default IBizPickupViewPanelControl; diff --git a/src/control/pickup-view-panel/pickup-view-panel.controller.ts b/src/control/pickup-view-panel/pickup-view-panel.controller.ts new file mode 100644 index 0000000000000000000000000000000000000000..94ce07825e67aa02b7596a9d80cf6daefcff11b6 --- /dev/null +++ b/src/control/pickup-view-panel/pickup-view-panel.controller.ts @@ -0,0 +1,138 @@ +import { + ControlController, + convertNavData, + IPickupGridViewEvent, + IPickupViewPanelController, + IPickupViewPanelEvent, + IPickupViewPanelState, + IViewController, + IPickupGridViewState, +} from '@ibiz-template/runtime'; +import { IAppDEGridView, IAppView, IDEPickupViewPanel } from '@ibiz/model-core'; + +/** + * 选择面板控制器 + * + * @export + * @class PickupViewPanelController + * @extends {ControlController} + * @implements {IPickupViewPanelController} + */ +export class PickupViewPanelController + extends ControlController< + IDEPickupViewPanel, + IPickupViewPanelState, + IPickupViewPanelEvent + > + implements IPickupViewPanelController +{ + /** + * 嵌入视图控制器 + * + * @type {IViewController} + * @memberof PickupViewPanelController + */ + embedView!: IViewController< + IAppDEGridView, + IPickupGridViewState, + IPickupGridViewEvent + >; + + /** + * 嵌入视图模型 + * + * @type {IAppView} + * @memberof PickupViewPanelController + */ + embedViewModel!: IAppView; + + /** + * 生命周期-创建完成 + * + * @protected + * @return {*} {Promise} + * @memberof PickupViewPanelController + */ + protected async doCreated(): Promise { + await super.doCreated(); + this.initNavParam(); + this.embedViewModel = await ibiz.hub.getAppView( + this.model.embeddedAppDEViewId!, + ); + } + + /** + * 初始化导航参数 + * + * @memberof PickupViewPanelController + */ + initNavParam() { + const { navigateContexts, navigateParams } = this.model; + const context = this.context.clone(); + const params = { ...this.params }; + if (navigateContexts) { + Object.assign( + context, + convertNavData(navigateContexts, this.context, this.params), + ); + } + if (navigateParams) { + Object.assign( + params, + convertNavData(navigateParams, this.context, this.params), + ); + } + this.state.context = context; + this.state.params = params; + } + + /** + * 设置嵌入视图 + * + * @param {IViewController} view + * @memberof PickupViewPanelController + */ + setEmbedView( + view: IViewController< + IAppDEGridView, + IPickupGridViewState, + IPickupGridViewEvent + >, + ) { + this.embedView = view; + this.embedView.evt.on('onSelectionChange', event => { + this.evt.emit('onSelectionChange', event); + }); + this.embedView.evt.on('onDataActive', event => { + this.evt.emit('onDataActive', { + data: event.data, + }); + }); + } + + /** + * 获取选中数据 + * + * @author zk + * @date 2023-05-26 03:05:53 + * @return {*} {Promise} + * @memberof PickupViewPanelController + */ + async getSelectedData(): Promise { + const items: IData[] = await this.embedView.call('GetData'); + return items; + } + + /** + * 获取全部数据 + * + * @author zk + * @date 2023-05-26 03:05:49 + * @return {*} {Promise} + * @memberof PickupViewPanelController + */ + async getAllData(): Promise { + const items: IData[] = await this.embedView.call('GetAllData'); + return items; + } +} diff --git a/src/control/pickup-view-panel/pickup-view-panel.provider.ts b/src/control/pickup-view-panel/pickup-view-panel.provider.ts new file mode 100644 index 0000000000000000000000000000000000000000..403363121615a834644bd072ede26ee854b02f16 --- /dev/null +++ b/src/control/pickup-view-panel/pickup-view-panel.provider.ts @@ -0,0 +1,12 @@ +import { IControlProvider } from '@ibiz-template/runtime'; + +/** + * 选择视图面板适配器 + * + * @export + * @class PickupViewPanelProvider + * @implements {IControlProvider} + */ +export class PickupViewPanelProvider implements IControlProvider { + component: string = 'IBizPickupViewPanelControl'; +} diff --git a/src/control/pickup-view-panel/pickup-view-panel.scss b/src/control/pickup-view-panel/pickup-view-panel.scss new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/control/pickup-view-panel/pickup-view-panel.tsx b/src/control/pickup-view-panel/pickup-view-panel.tsx new file mode 100644 index 0000000000000000000000000000000000000000..a6cfa36c35a9fa7c7b7c475b293a4e7ef50887eb --- /dev/null +++ b/src/control/pickup-view-panel/pickup-view-panel.tsx @@ -0,0 +1,60 @@ +import { useControlController, useNamespace } from '@ibiz-template/vue3-util'; +import { defineComponent, h, PropType, resolveComponent } from 'vue'; +import { IAppDEGridView, IDEPickupViewPanel } from '@ibiz/model-core'; +import { PickupViewPanelController } from './pickup-view-panel.controller'; +import { EventBase, IPickupGridViewEvent, IPickupGridViewState, IViewController } from '@ibiz-template/runtime'; +import './pickup-view-panel.scss'; + +export const PickupViewPanelControl = defineComponent({ + name: 'IBizPickupViewPanelControl', + props: { + modelData: { type: Object as PropType, required: true }, + context: { type: Object as PropType, required: true }, + params: { type: Object as PropType, default: () => ({}) }, + }, + setup() { + const c = useControlController((...args) => new PickupViewPanelController(...args)); + const ns = useNamespace(`control-${c.model.controlType!.toLowerCase()}`); + + const onCreated = (event: EventBase) => { + c.setEmbedView(event.view as IViewController< + IAppDEGridView, + IPickupGridViewState, + IPickupGridViewEvent + >); + }; + return { + c, + ns, + onCreated, + }; + }, + render() { + return ( + + { + this.c.state.isCreated && +
+ { + this.$slots.default ? + this.$slots.default({ + context: this.c.state.context, + params: this.c.state.params, + modelData: this.c.embedViewModel, + state: { singleSelect: this.c.state.singleSelect }, + onCreated: this.onCreated, + }) : + h(resolveComponent('IBizViewShell'), { + context: this.c.state.context, + params: this.c.state.params, + modelData: this.c.embedViewModel, + state: { singleSelect: this.c.state.singleSelect }, + onCreated: this.onCreated, + }) + } +
+ } +
+ ); + }, +}); diff --git a/src/index.ts b/src/index.ts index 85225a1cce4345984f7d8628bb601bb209b4b763..2d2e941d43ed02c11f8ccae71a7ee77d6999d183 100644 --- a/src/index.ts +++ b/src/index.ts @@ -12,6 +12,7 @@ import { IBizListControl, IBizCaptionBarControl, IBizDataViewControl, + IBizPickupViewPanelControl, } from './control'; import IBizEditor from './editor'; import { IBizView } from './view'; @@ -33,6 +34,7 @@ export default { v.use(IBizAppMenuControl); v.use(IBizGridControl); v.use(IBizListControl); + v.use(IBizPickupViewPanelControl); v.use(IBizToolbarControl); v.use(IBizViewLayoutPanelControl); v.use(IBizFormControl); diff --git a/src/view-engine/index.ts b/src/view-engine/index.ts index 4c5f0492c5597cccdf60b84dfb9df2ef5ed2c0b2..150c3ff499bfd31aa4cd3d060fd48dcd22098c0c 100644 --- a/src/view-engine/index.ts +++ b/src/view-engine/index.ts @@ -6,6 +6,9 @@ import { IndexViewEngine } from './index-view.engine'; import { ListViewEngine } from './list-view.engine'; import { DataViewEngine } from './data-view.engine'; import { OptViewEngine } from './opt-view.engine'; +import { PickupGridViewEngine } from './pickup-grid-view.engine'; +import { PickupViewEngine } from './pickup-view.engine'; +import { MPickupViewEngine } from './mpickup-view-engine'; export * from './grid-view.engine'; export * from './index-view.engine'; @@ -42,5 +45,17 @@ export const IBizViewEngine = { 'VIEW_OptionView', (c: IViewController) => new OptViewEngine(c), ); + ibiz.engine.register( + 'VIEW_PickupGridView', + (c: IViewController) => new PickupGridViewEngine(c), + ); + ibiz.engine.register( + 'VIEW_PickupView', + (c: IViewController) => new PickupViewEngine(c), + ); + ibiz.engine.register( + 'VIEW_MPickupView', + (c: IViewController) => new MPickupViewEngine(c), + ); }, }; diff --git a/src/view-engine/list-view.engine.ts b/src/view-engine/list-view.engine.ts index e4b669eabe13dbe00ae0fe53c788add811b612d4..302ae98485537ae58764b333e0d6d1607dc001b3 100644 --- a/src/view-engine/list-view.engine.ts +++ b/src/view-engine/list-view.engine.ts @@ -21,8 +21,6 @@ export class ListViewEngine extends MDViewEngine { async doMounted() { super.doMounted(); const { model } = this.view; - this.list.setState({ - mdctrlActiveMode: model.mdctrlActiveMode!, - }); + this.list.state.mdctrlActiveMode = model.mdctrlActiveMode!; } } diff --git a/src/view-engine/mpickup-view-engine.ts b/src/view-engine/mpickup-view-engine.ts new file mode 100644 index 0000000000000000000000000000000000000000..3b90f3ddeb75d0d64deef4ac432539003764cb45 --- /dev/null +++ b/src/view-engine/mpickup-view-engine.ts @@ -0,0 +1,243 @@ +import { + ViewController, + IMPickupViewState, + IMPickupViewEvent, + SysUIActionTag, + IListController, +} from '@ibiz-template/runtime'; +// todo 缺失 IAppDEMPickupView +import { IAppDEPickupView } from '@ibiz/model-core'; +import { PickupViewEngine } from './pickup-view.engine'; + +/** + * 多数据选择视图引擎 + * + * @author zk + * @date 2023-05-25 03:05:17 + * @export + * @class MPickupViewEngine + * @extends {ViewEngineBase} + */ +export class MPickupViewEngine extends PickupViewEngine { + protected declare view: ViewController< + IAppDEPickupView, + IMPickupViewState, + IMPickupViewEvent + >; + + /** + * 简单列表控制器 + * + * @author zk + * @date 2023-05-26 03:05:43 + * @readonly + * @memberof MPickupViewEngine + */ + get simpleList() { + return this.view.getController('simplelist') as IListController; + } + + /** + * 视图created生命周期执行逻辑 + * + * @author zk + * @date 2023-05-26 05:05:36 + * @return {*} {Promise} + * @memberof MPickupViewEngine + */ + async doCreated(): Promise { + await super.doCreated(); + // 设置回显selectedData + if (this.view.params.selectedData) { + this.selectData = JSON.parse(this.view.params.selectedData); + delete this.view.params.selectedData; + } + if (!this.view.slotProps.simpleList) { + this.view.slotProps.simpleList = {}; + } + if (!this.view.slotProps.pickupViewPanel) { + this.view.slotProps.pickupViewPanel = {}; + } + this.view.slotProps.simpleList.mdctrlActiveMode = 2; + this.view.slotProps.simpleList.singleSelect = false; + this.view.slotProps.pickupViewPanel.singleSelect = false; + } + + /** + * 视图mounted生命周期执行逻辑 + * + * @author zk + * @date 2023-05-26 05:05:27 + * @return {*} {Promise} + * @memberof MPickupViewEngine + */ + async doMounted(): Promise { + await super.doMounted(); + // 列表激活取消选中 + this.simpleList.evt.on('onActive', event => { + this.simpleListActive(event.data); + }); + // 默认回显选中数据 + this.simpleList.setData(this.selectData); + } + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + async call(key: string, args: any): Promise { + if (key === SysUIActionTag.CANCEL) { + this.cancel(); + return null; + } + if (key === SysUIActionTag.OK) { + this.confirm(); + return null; + } + if (key === SysUIActionTag.ADD_SELECTION) { + this.addSelection(); + return null; + } + if (key === SysUIActionTag.ADD_ALL) { + this.addAll(); + return null; + } + if (key === SysUIActionTag.REMOVE_ALL) { + this.removeAll(); + return null; + } + if (key === SysUIActionTag.REMOVE_SELECTION) { + this.removeSelection(); + return null; + } + return super.call(key, args); + } + + /** + * 选则面板激活数据 + * + * @author zk + * @date 2023-05-26 05:05:13 + * @param {*} data + * @memberof PickupViewEngine + */ + public pickupViewPanelDataActive(data: IData[]) { + this.handlePushSimpleListItems(data); + } + + /** + * 列表激活 + * + * @author zk + * @date 2023-05-26 05:05:47 + * @param {IData[]} data + * @memberof MPickupViewEngine + */ + simpleListActive(data: IData[]) { + const items = this.simpleList.getAllData(); + data.forEach(item => { + const index = items.findIndex(_item => _item.srfkey === item.srfkey); + if (index !== -1) { + items.splice(index, 1); + } + }); + this.simpleList.setData(items); + } + + /** + * 添加选中 + * + * @author zk + * @date 2023-05-25 05:05:10 + * @memberof MPickupViewEngine + */ + public async addSelection() { + const selectItem = await this.pickupViewPanel.getSelectedData(); + this.handlePushSimpleListItems(selectItem); + } + + /** + * 处理添加简单列表数据 + * + * @author zk + * @date 2023-05-26 02:05:41 + * @param {IData[]} data + * @memberof MPickupViewEngine + */ + public handlePushSimpleListItems(data: IData[]) { + const allData = this.simpleList.getAllData(); + const items = [...allData, ...data]; + // 去重items + const uniqueItems = this.handleUniqueItems(items); + this.simpleList.setData(uniqueItems); + } + + /** + * 去重数组 + * + * @author zk + * @date 2023-05-26 03:05:08 + * @param {IData[]} arr + * @return {*} + * @memberof MPickupViewEngine + */ + public handleUniqueItems(arr: IData[]) { + const res = new Map(); + return arr.filter( + (item: IData) => !res.has(item.srfkey) && res.set(item.srfkey, 1), + ); + } + + /** + * 添加所有 + * + * @author zk + * @date 2023-05-25 05:05:12 + * @memberof MPickupViewEngine + */ + public async addAll() { + const allItems = await this.pickupViewPanel.getAllData(); + this.handlePushSimpleListItems(allItems); + } + + /** + * 删除所有 + * + * @author zk + * @date 2023-05-25 05:05:14 + * @memberof MPickupViewEngine + */ + public removeAll() { + this.simpleList.setData([]); + } + + /** + * 删除选中 + * + * @author zk + * @date 2023-05-25 05:05:16 + * @memberof MPickupViewEngine + */ + public removeSelection() { + const selectData = this.simpleList.getData(); + const items = this.simpleList.getAllData(); + selectData.forEach((_item: IData) => { + const index = items.findIndex( + (item: IData) => _item.srfkey === item.srfkey, + ); + if (index !== -1) { + items.splice(index, 1); + } + }); + this.simpleList.setData(items); + } + + /** + * 提交 + * + * @author zk + * @date 2023-05-25 06:05:42 + * @memberof MPickupViewEngine + */ + confirm() { + const items = this.handleSelectData(this.simpleList.getAllData()); + this.view.closeView({ ok: true, data: items }); + } +} diff --git a/src/view-engine/pickup-grid-view.engine.ts b/src/view-engine/pickup-grid-view.engine.ts new file mode 100644 index 0000000000000000000000000000000000000000..461f6b7e12c5cf25d01ce2b517fbe9fb8bb26e93 --- /dev/null +++ b/src/view-engine/pickup-grid-view.engine.ts @@ -0,0 +1,75 @@ +import { + ViewController, + IPickupGridViewEvent, + IPickupGridViewState, + IGridController, +} from '@ibiz-template/runtime'; +// import { IAppDEPickupGridView } from '@ibiz/model-core'; +import { IAppDEGridView } from '@ibiz/model-core'; +import { GridViewEngine } from './grid-view.engine'; +// todo 缺失 IAppDEPickupGridView +export class PickupGridViewEngine extends GridViewEngine { + protected declare view: ViewController< + IAppDEGridView, + IPickupGridViewState, + IPickupGridViewEvent + >; + + /** + * 表格控制器 + * + * @author zk + * @date 2023-05-26 05:05:43 + * @readonly + * @memberof PickupGridViewEngine + */ + get grid() { + return this.view.getController('grid') as IGridController; + } + + /** + * 创建完成 + * + * @author zk + * @date 2023-05-26 05:05:35 + * @memberof PickupGridViewEngine + */ + async doCreated() { + super.doCreated(); + const { model } = this.view; + if (!this.view.slotProps.grid) { + this.view.slotProps.grid = {}; + } + this.view.slotProps.grid.singleSelect = this.view.state.singleSelect; + this.view.slotProps.grid.mdctrlActiveMode = model.gridRowActiveMode!; + } + + /** + * 挂载完成 + * + * @author zk + * @date 2023-05-26 10:05:13 + * @memberof PickupGridViewEngine + */ + async doMounted() { + const { model } = this.view; + this.xdataControl.evt.on('onSelectionChange', async event => { + this.view.evt.emit('onSelectionChange', { ...event }); + }); + this.xdataControl.evt.on('onActive', async event => { + this.view.evt.emit('onDataActive', { ...event }); + }); + // 默认加载 + if (model.loadDefault) { + this.load(); + } + } + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + async call(key: string, args: any): Promise { + if (key === 'GetAllData') { + return this.grid.state.items; + } + return super.call(key, args); + } +} diff --git a/src/view-engine/pickup-view.engine.ts b/src/view-engine/pickup-view.engine.ts new file mode 100644 index 0000000000000000000000000000000000000000..9d7a99e7be5c5c73800ca2e56cea1ad5230d42a4 --- /dev/null +++ b/src/view-engine/pickup-view.engine.ts @@ -0,0 +1,133 @@ +import { + ViewEngineBase, + ViewController, + IPickupViewPanelController, + SysUIActionTag, + IPickupViewState, + IPickupViewEvent, +} from '@ibiz-template/runtime'; +import { IAppDEPickupView } from '@ibiz/model-core'; + +export class PickupViewEngine extends ViewEngineBase { + /** + * 视图控制器 + * + * @protected + * @type {ViewController} + * @memberof PickupViewEngine + */ + protected declare view: ViewController< + IAppDEPickupView, + IPickupViewState, + IPickupViewEvent + >; + + /** + * 选中数据 + * + * @type {IData[]} + * @memberof PickupViewEngine + */ + selectData: IData[] = []; + + /** + * 选择视图面板 + * + * @readonly + * @memberof PickupViewEngine + */ + get pickupViewPanel() { + return this.view.getController( + 'pickupviewpanel', + ) as IPickupViewPanelController; + } + + /** + * 视图created生命周期执行逻辑 + * + * @return {*} {Promise} + * @memberof PickupViewEngine + */ + async doCreated(): Promise { + await super.doCreated(); + const { childNames } = this.view; + childNames.push('pickupviewpanel'); + } + + /** + * 视图mounted生命周期执行逻辑 + * + * @return {*} {Promise} + * @memberof PickupViewEngine + */ + async doMounted(): Promise { + this.pickupViewPanel.state.singleSelect = true; + this.pickupViewPanel.evt.on('onSelectionChange', event => { + this.selectData = this.handleSelectData(event.data); + }); + this.pickupViewPanel.evt.on('onDataActive', event => { + this.pickupViewPanelDataActive(event.data); + }); + } + + /** + * 选则面板激活数据 + * + * @author zk + * @date 2023-05-26 05:05:13 + * @param {*} data + * @memberof PickupViewEngine + */ + public pickupViewPanelDataActive(data: IData[]) { + this.selectData = this.handleSelectData(data); + this.view.closeView({ ok: true, data: this.selectData }); + } + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + async call(key: string, args: any): Promise { + if (key === SysUIActionTag.CANCEL) { + this.cancel(); + return null; + } + if (key === SysUIActionTag.OK) { + this.confirm(); + return null; + } + return super.call(key, args); + } + + /** + * 处理选中数据 + * + * @memberof PickupViewEngine + */ + handleSelectData(data: IData[]): IData[] { + const selectData: IData[] = []; + data.forEach((item: IData) => { + selectData.push({ + srfkey: item.srfkey, + srfmajortext: item.srfmajortext, + data: { ...item }, + }); + }); + return selectData; + } + + /** + * 确认 + * + * @memberof PickupViewEngine + */ + confirm() { + this.view.closeView({ ok: true, data: this.selectData }); + } + + /** + * 取消 + * + * @memberof PickupViewEngine + */ + cancel() { + this.view.closeView({ ok: false, data: [] }); + } +}