app-form-mdctrl.vue 7.7 KB
<template>
    <div class="app-form-mdctrl">
        <Icon class="app-form-mdctrl__icon" type="md-add" @click="addItem()" />
        <div class="app-form-mdctrl__item" v-for="(item, index) in items" :key="item.data[deKeyField.toLowerCase()]">
            <slot :viewparams="viewparams" :context="item.context" :viewState="MDCtrlState" :formMDCtrlAction="formMDCtrlAction"></slot>
            <Icon class="app-form-mdctrl__icon" type="ios-trash-outline" @click="removeItem(item, index)" />
        </div>
    </div>
</template>

<script lang="ts">
import { Vue, Component, Prop } from 'vue-property-decorator';
import { Subject, Unsubscribable } from 'rxjs';

@Component({})
export default class AppFormMdCtrl extends Vue {

    /**
     * 视图上下文
     *
     * @type {*}
     * @memberof AppFormMdCtrl
     */
    @Prop() public context!: any;

    /**
     * 视图参数
     *
     * @type {*}
     * @memberof AppFormMdCtrl
     */
    @Prop() public viewparams!: any;

    /**
     * 表单状态
     *
     * @type {Subject<any>}
     * @memberof AppFormMdCtrl
     */
    @Prop() public formState!: Subject<any>;

    /**
     * 实体代码标识
     *
     * @type {string}
     * @memberof AppFormMdCtrl
     */
    @Prop() public entityCodeName!: string;

    /**
     * 应用实体主键属性名称
     *
     * @type {string}
     * @memberof AppFormMdCtrl
     */
    @Prop() public deKeyField!: string;

    /**
     * 部件名称
     *
     * @type {string}
     * @memberof AppFormMdCtrl
     */
    @Prop() public ctrlName!: string;

    /**
     * 多数据部件类型
     *
     * @type {[多数据部件类型] {LIST:列表、 FORM:表单、 REPEATER:重复器 }}
     * @memberof AppFormMdCtrl
     */
    @Prop({ default: 'FORM' }) public contentType!: string | 'LIST' | 'FORM' | 'REPEATER';

    /**
     * 表单状态事件
     *
     * @private
     * @type {(Unsubscribable | undefined)}
     * @memberof AppFormMdCtrl
     */
    private formStateEvent: Unsubscribable | undefined;

    /**
     * 视图状态
     *
     * @type {Subject<any>}
     * @memberof AppFormMdCtrl
     */
    private MDCtrlState: Subject<ViewState> = new Subject();

    /**
     * 项数据集
     *
     * @type {any[]}
     * @memberof AppFormMdCtrl
     */
    private items: any[] = [];

    /**
     * 数据服务
     *
     * @type {any[]}
     * @memberof AppFormMdCtrl
     */
    private dataService: any;

    /**
     * 子表单数量
     *
     * @type {number}
     * @memberof AppFormMdCtrl
     */
    private childFormCount: number = 0;

    /**
     * 错误提示数据
     *
     * @type {number}
     * @memberof AppFormMdCtrl
     */
    private errorInfoCount: number = 0;

    /**
     * vue  生命周期
     *
     * @memberof AppFormMdCtrl
     */
    public async created() {
        if (this.entityCodeName) {
            this.dataService = await window.entityServiceRegister.getService(this.entityCodeName.toLowerCase());
        }
        this.formStateEvent = this.formState.subscribe(($event: any) => {
            if (Object.is($event.type, 'load')) {
                this.loadData();
            }
            if (Object.is($event.type, 'beforesave')) {
                    if (this.items.length == 0) {
                        this.mdCtrlDataSaved();
                    } else {
                        this.childFormCount = 0;
                        this.errorInfoCount = 0;
                        this.MDCtrlState.next({
                            tag: this.ctrlName,
                            action: 'save',
                            data: { showResultInfo: false },
                        });
                    }
            }
            if (Object.is($event.type, 'save') && !Object.is($event.action, 'autoSave')) {
                this.loadData();
            }
        })
    }

    /**
     * 处理请求上下文
     * 
     * @param context 上下文
     * @memberof AppFormMdCtrl
     */
    private handleRequestContext(context: any): any {
        let tempContext = this.$util.deepCopy(this.context);
        if(tempContext && tempContext.srfsessionid){
            tempContext.srfsessionkey = tempContext.srfsessionid;
            delete tempContext.srfsessionid;
        }
        return tempContext
    }

    /**
     * 加载数据
     *
     * @memberof AppFormMdCtrl
     */
    public async loadData() {
        this.items = [];
        if (this.contentType == 'FORM' && this.dataService && this.dataService['FetchDefaultTemp'] && this.dataService['FetchDefaultTemp'] instanceof Function) {
            const context = this.handleRequestContext(this.context);
            const response = await this.dataService['FetchDefaultTemp'](context);
            if (response && response.status === 200) {
                this.handleData(response.data);
            }
        }
    }

    /**
     * 处理数据
     * 
     * @param data 数据集
     * @memberof AppFormMdCtrl
     */
    public handleData(data: any[]) {
        data.forEach((_item: any) => {
            const context = this.$util.deepCopy(this.context);
            Object.assign(context, { [this.entityCodeName.toLowerCase()]: _item[this.deKeyField.toLowerCase()] });
            this.items.push({ context, data: _item });
        });
    }

    /**
     * 添加项
     * 
     * @memberof AppFormMdCtrl
     */
    public async addItem() {
        if (this.dataService && this.deKeyField && this.dataService['CreateTemp'] && this.dataService['CreateTemp'] instanceof Function) {
            const data = { [this.deKeyField.toLowerCase()]: this.$util.createUUID() };
            const context = this.handleRequestContext(this.context);
            const response = await this.dataService['CreateTemp'](context, data);
            if (response && response.status === 200) {
                this.handleData([response.data]);
            }
        }
    }

    /**
     * 删除项
     * 
     * @param item 项数据
     * @param index 索引
     * @memberof AppFormMdCtrl
     */
    public async removeItem(item: any, index: number) {
        if (this.dataService && this.dataService['RemoveTemp'] && this.dataService['RemoveTemp'] instanceof Function) {
            const context = this.handleRequestContext(item.context);
            const response = await this.dataService['RemoveTemp'](context, item.data);
            if (response && response.status === 200) {
                this.items.splice(index, 1);
            }
        }
    }

    /**
     * 表单多数据部件行为
     * 
     * @param action 行为
     * @param data 数据
     * @memberof AppFormMdCtrl
     */
    public formMDCtrlAction(action: string, data: any) {
        if (this.contentType === 'FORM') {
                if (action === 'save') {
                    this.childFormCount++;
                    if (this.childFormCount === this.items.length) {
                        this.mdCtrlDataSaved(data);
                    }
                }
                if (action === 'checkFail') {
                    if(this.errorInfoCount !== 0){
                        return;
                    }
                    this.errorInfoCount ++;
                    this.$Notice.error({ title: (this.$t('app.commonWords.wrong') as string), desc: (this.$t('app.formpage.valuecheckex') as string) });
                }
            }
    }

    /**
     * 多数据部件数据保存完成
     * 
     * @param data 数据
     * @memberof AppFormMdCtrl
     */
    public mdCtrlDataSaved(data?: any) {
        this.$emit('drdatasaved', { type: 'MDCTRL' });
    }

    /**
     * 部件销毁
     *
     * @memberof AppFormMdCtrl
     */
    public destroyed(): void {
        if (this.formStateEvent) {
            this.formStateEvent.unsubscribe();
        }
    }
}
</script>
<style lang='less'>
@import './app-form-mdctrl.less';
</style>