<template>
    <div>
        <Modal v-model="opened"
            scrollable
            width="800">
            <div slot="header">
                <span class="title">字段设置</span>
                <span class="description">Column Setting</span>
            </div>
            <div class="ivu-ml-8 ivu-mr-8">
                <Form ref="form"
                    :model="data"
                    label-position="top"
                    label-colon="："
                    class="ivu-mt"
                    :rules="rules"
                    @submit.native.prevent>
                    <Row :gutter="24"
                        type="flex">
                        <Col v-bind="grid8">
                        <FormItem label="字段"
                            key="code"
                            prop="code">
                            <span v-if="!data.isVirtual">{{ data.code }}</span>
                            <Input type="text"
                                v-if="data.isVirtual"
                                v-model="data.code"
                                maxlength="200" />
                        </FormItem>
                        </Col>
                        <Col v-bind="grid8">
                        <FormItem label="名称"
                            key="name"
                            prop="name">
                            <Input type="text"
                                v-model="data.name"
                                maxlength="200" />
                        </FormItem>
                        </Col>
                        <Col v-bind="grid8">
                        <FormItem label="控件类型"
                            key="controlType"
                            prop="controlType">
                            <Select v-model="data.controlType"
                                :transfer="true"
                                @on-change="controlTypeChange">
                                <Option v-for="item in getEnumList('ControlType')"
                                    :key="item.id"
                                    :value="item.id">{{ item.name }}</Option>
                            </Select>
                        </FormItem>
                        </Col>
                        <Col v-bind="grid8"
                            v-show="data.controlType == 'Select' || data.controlType == 'ComboSelect'">
                        <FormItem label="数据源"
                            key="source"
                            prop="source">
                            <dialog-select ref="select"
                                v-model="data.source"
                                source="EntitySelect"
                                source-data-code="name"
                                source-display-code="name"
                                @on-change="sourceChange">
                            </dialog-select>
                        </FormItem>
                        </Col>
                        <Col v-bind="grid8"
                            v-show="data.controlType == 'DialogSelect'">
                        <FormItem label="视图"
                            key="dataViewSource"
                            prop="dataViewSource">
                            <dialog-select ref="dataViewSource"
                                v-model="data.source"
                                source="DataViewSelect"
                                source-data-code="code"
                                source-display-code="code"
                                :param="{'viewType': 'TableView'}"
                                @on-change="sourceChange">
                            </dialog-select>
                        </FormItem>
                        </Col>
                        <Col v-bind="grid8"
                            v-if="needDataSource">
                        <FormItem label="数据字段"
                            prop="sourceDataCode"
                            v-if="data.source">
                            <Input type="text"
                                :readonly="true"
                                v-model="data.sourceDataCode"
                                @on-focus="openColumnSelect(data, 'sourceDataCode')">
                            <Button slot="prepend"
                                custom-icon="fa fa-search"
                                @click="openColumnSelect(data, 'sourceDataCode')"></Button>
                            </Input>
                        </FormItem>
                        </Col>
                        <Col v-bind="grid8"
                            v-if="needDataSource">
                        <FormItem label="显示字段"
                            key="sourceDisplayCode"
                            prop="sourceDisplayCode"
                            v-if="data.source">
                            <Input type="text"
                                :readonly="true"
                                v-model="data.sourceDisplayCode"
                                @on-focus="openColumnSelect(data, 'sourceDisplayCode')">
                            <Button slot="prepend"
                                custom-icon="fa fa-search"
                                @click="openColumnSelect(data, 'sourceDisplayCode')"></Button>
                            </Input>
                        </FormItem>
                        </Col>
                        <Col v-bind="grid16"
                            v-if="needDataSource">
                        <FormItem label="参数"
                            key="param"
                            prop="param"
                            v-if="data.source">
                            <Input type="text"
                                @click.native="paramOpen"
                                :readonly='true'
                                v-model="data.param"
                                maxlength="200" />
                        </FormItem>
                        </Col>
                        <Col v-bind="grid8"
                            v-if="needDataSource">
                        <FormItem label="默认第一项"
                            key="isDefaultFirst"
                            prop="isDefaultFirst">
                            <Switch :value="!!data.isDefaultFirst"
                                @input="($event)=>{ data.isDefaultFirst = $event }" />
                        </FormItem>
                        </Col>
                        <Col v-bind="grid8">
                        <FormItem label="是否显示"
                            key="isShow"
                            prop="isShow">
                            <Switch :value="!!data.isShow"
                                @input="($event)=>{ data.isShow = $event }" />
                        </FormItem>
                        </Col>
                        <Col v-bind="grid8">
                        <FormItem label="是否只读"
                            key="isReadonly"
                            prop="isReadonly">
                            <Switch :value="!!data.isReadonly"
                                @input="($event)=>{ data.isReadonly = $event }" />
                        </FormItem>
                        </Col>
                        <Col v-bind="grid8"
                            v-if="viewType==20">
                        <FormItem label="栏目宽度"
                            key="columnWidth"
                            prop="columnWidth">
                            <Select v-model="data.columnWidth"
                                :transfer="true">
                                <Option v-for="item in getEnumList('ColumnWidth')"
                                    :key="item.id"
                                    :value="item.id">{{ item.name }}</Option>
                            </Select>
                        </FormItem>
                        </Col>
                        <Col v-bind="grid8">
                        <FormItem label="控件宽度"
                            key="controlWidth"
                            prop="controlWidth">
                            <Input type="number"
                                style="width: 100px"
                                number
                                v-model="data.controlWidth" />
                        </FormItem>
                        </Col>
                        <Col v-bind="grid8">
                        <FormItem label="控件高度"
                            key="controlHeight"
                            prop="controlHeight">
                            <Input type="number"
                                style="width: 100px"
                                number
                                v-model="data.controlHeight" />
                        </FormItem>
                        </Col>
                        <Col v-bind="grid8">
                        <FormItem label="显示格式"
                            key="displayFormat"
                            prop="displayFormat">
                            <Select v-model="data.displayFormat"
                                :transfer="true">
                                <Option v-for="item in getDisplayFormats()"
                                    :key="item.id"
                                    :value="item.code">{{ item.name }}</Option>
                            </Select>
                        </FormItem>
                        </Col>
                        <Col v-bind="grid8">
                        <FormItem label="是否必填"
                            key="isRequired"
                            prop="isRequired">
                            <Switch :value="!!data.isRequired"
                                @input="($event)=>{ data.isRequired = $event }" />
                        </FormItem>
                        </Col>
                        <Col v-bind="grid8">
                        <FormItem label="默认值"
                            key="defaultValue"
                            prop="defaultValue">
                            <Input type="text"
                                v-model="data.defaultValue"
                                maxlength="200" />
                        </FormItem>
                        </Col>
                        <Col v-bind="grid8">
                        <FormItem label="描述"
                            key="description"
                            prop="description">
                            <Input type="text"
                                v-model="data.description"
                                maxlength="200" />
                        </FormItem>
                        </Col>
                        <Col v-bind="grid8">
                        <FormItem label="最大字符数量"
                            key="maxLength"
                            prop="maxLength">
                            <Input type="number"
                                style="width: 100px"
                                number
                                v-model="data.maxLength" />
                        </FormItem>
                        </Col>
                        <Col v-bind="grid8">
                        <FormItem label="输入范围">
                            <Input type="number"
                                style="width: 60px"
                                number
                                v-model="data.minValue" />
                            -
                            <Input type="number"
                                style="width: 60px"
                                number
                                v-model="data.maxValue" />
                        </FormItem>
                        </Col>
                        <Col v-bind="grid8">
                        <FormItem label="验证表达式"
                            key="pattern"
                            prop="pattern">
                            <Input type="text"
                                v-model="data.pattern"
                                maxlength="100" />
                        </FormItem>
                        </Col>
                        <Col v-bind="grid8"
                            v-if="viewType==20">
                        <FormItem label="选项卡序号"
                            key="tabIndex"
                            prop="tabIndex">
                            <Input type="number"
                                style="width: 100px"
                                number
                                v-model="data.tabIndex" />
                        </FormItem>
                        </Col>
                    </Row>
                </Form>
            </div>
            <div slot="footer">
                <Button type="primary"
                    custom-icon="fa fa-check"
                    @click="finish">
                    确定
                </Button>
                <Button type="default"
                    custom-icon="fa fa-times"
                    @click="close">
                    关闭
                </Button>
            </div>
        </Modal>
        <Modal v-model="paramOpened"
            scrollable
            width="600">
            <div slot="header">
                <slot name="header">
                    <span class="title">参数</span>
                    <span class="description">Param</span>
                </slot>
            </div>
            <div class="i-table-no-border">
                <Table :columns="parpamColumns"
                    :data="params"
                    stripe
                    size="small"
                    no-data-text="暂无数据...">
                    <template slot-scope="{ row, index }"
                        slot="command">
                        <Button size="small"
                            title="编辑"
                            type="primary"
                            ghost
                            custom-icon="fa fa-edit"
                            @click="paramEdit(row, index)"></Button>
                        <Button size="small"
                            title="上移"
                            type="primary"
                            ghost
                            custom-icon="fa fa-chevron-up"
                            @click="upParam(row, index)"></Button>
                        <Button size="small"
                            title="下移"
                            type="primary"
                            ghost
                            custom-icon="fa fa-chevron-down"
                            @click="downParam(row, index)"></Button>
                        <Button size="small"
                            title="移除"
                            type="primary"
                            ghost
                            custom-icon="fa fa-times"
                            @click="paramRemove(row, index)"></Button>
                    </template>
                </Table>
            </div>
            <div slot="footer">
                <Button type="primary"
                    ghost
                    custom-icon="fa fa-plus"
                    @click="paramEdit()">
                    新增
                </Button>
                <Button type="primary"
                    custom-icon="fa fa-check"
                    @click="paramSave">
                    确定
                </Button>
            </div>
        </Modal>
        <Modal v-model="paramItemOpened"
            scrollable
            width="800">
            <div slot="header">
                <span class="title">参数设置</span>
                <span class="description">Param Setting</span>
            </div>
            <div class="ivu-ml-8 ivu-mr-8">
                <Form ref="paramItemForm"
                    :rules="paramItemFormRules"
                    :model="paramData"
                    label-position="top"
                    label-colon="："
                    class="ivu-mt"
                    @submit.native.prevent>
                    <Row :gutter="24"
                        type="flex">
                        <Col v-bind="grid8">
                        <FormItem label="字段"
                            key="code"
                            prop="code">
                            <Input type="text"
                                v-model="paramData.code">
                            <Button slot="prepend"
                                custom-icon="fa fa-search"
                                @click="openColumnSelect(paramData,'code')"></Button>
                            </Input>
                        </FormItem>
                        </Col>
                        <Col v-bind="grid8">
                        <FormItem label="字段类型"
                            key="keyType"
                            prop="keyType">
                            <RadioGroup v-model="paramData.keyType"
                                @on-change="keyTypeChange">
                                <Radio label="常量"></Radio>
                                <Radio label="变量"></Radio>
                            </RadioGroup>
                        </FormItem>
                        </Col>
                        <Col v-bind="grid8"
                            v-if="paramData.keyType=='常量'">
                        <FormItem label="值"
                            key="val"
                            prop="val">
                            <Input type="text"
                                v-model="paramData.val"
                                size="small" />
                        </FormItem>
                        </Col>
                        <Col v-bind="grid8"
                            v-if="paramData.keyType=='变量'">
                        <FormItem label="值"
                            key="val2"
                            prop="val">
                            <Input type="text"
                                :readonly="true"
                                v-model="paramData.val"
                                @on-focus="openValueSelect">
                            <Button slot="prepend"
                                custom-icon="fa fa-search"
                                @click="openValueSelect"></Button>
                            </Input>
                        </FormItem>
                        </Col>
                    </Row>
                </Form>
            </div>
            <div slot="footer">
                <Button type="primary"
                    custom-icon="fa fa-check"
                    @click="paramItemSave">
                    确定
                </Button>
                <Button type="default"
                    custom-icon="fa fa-times"
                    @click="paramItemClose">
                    关闭
                </Button>
            </div>
        </Modal>
        <column-check ref="columnCheck" />
    </div>
</template>
<script>
    import mixinPage from '../../mixins/page';
    import modelApi from '../../api/model';
    import columnCheck from './column-check';

    export default {
        mixins: [mixinPage],
        components: { columnCheck },
        data() {
            return {
                data: {},
                opened: false,
                callback: null,
                displayFormats: [],
                parpamColumns: [
                    { title: '参数', resizable: true, align: 'center', key: 'code' },
                    { title: '值', align: 'center', resizable: true, key: 'val' },
                    { slot: 'command', title: ' ', align: 'center', resizable: true, fixed: 'right' }
                ],
                params: [],
                paramData: {},
                rules: {
                    name: {
                        type: 'string',
                        required: true,
                        message: '请输入名称',
                        trigger: 'blur,change'
                    },
                    controlType: {
                        type: 'string',
                        required: true,
                        message: '请输入控件类型',
                        trigger: 'blur,change'
                    },
                    columnWidth: {
                        type: 'string',
                        required: true,
                        message: '请输入栏目宽度',
                        trigger: 'blur,change'
                    }
                },
                paramItemFormRules: {
                    code: {
                        type: 'string',
                        required: true,
                        message: '请输入字段名称',
                        trigger: 'blur,change'
                    },
                    keyType: {
                        type: 'string',
                        required: true,
                        message: '请选择字段类型',
                        trigger: 'blur,change'
                    },
                    val: {
                        type: 'string',
                        required: true,
                        message: '请输入值',
                        trigger: 'blur,change'
                    }
                },
                paramOpened: false,
                paramItemOpened: false,
                sourceBefore: null,
                controlTypeBefore: null
            };
        },
        async created() {
            // 获取所有显示格式
            let res = await modelApi.query('DisplayFormat', {});
            this.displayFormats = res.data;
        },
        props: {
            // 视图类型
            viewType: {
                type: Number
            }
        },
        computed: {
            // 选择框，或复选框组，且非枚举类型，需要输入数据源
            needDataSource() {
                if (this.data) {
                    return (
                        ((this.data.controlType === 'Select' ||
                            this.data.controlType === 'ComboSelect' ||
                            this.data.controlType === 'AutoComplete' ||
                            this.data.controlType === 'Radio' ||
                            this.data.controlType === 'CheckGroup') &&
                            this.data.dataType.indexOf('Enum:') !== 0) ||
                        this.data.controlType === 'DialogSelect'
                    );
                }
            }
        },
        methods: {
            // 打开
            open(row, callback) {
                this.data = this.copy(row);
                this.callback = callback;
                this.opened = true;
                this.$refs.form.resetFields();
                this.controlTypeBefore = this.data.controlType;
            },
            // 关闭
            close() {
                this.opened = false;
            },
            // 确认
            async finish() {
                let isOK = await this.$refs.form.validate();

                if (!isOK) {
                    this.error('有内容不符合要求，请正确填写！');
                } else {
                    this.callback(this.copy(this.data));
                    this.opened = false;
                }
            },
            // 过滤显示格式
            getDisplayFormats() {
                return this.displayFormats.filter(item => {
                    return item.dataType === this.data.dataType;
                });
            },
            // 控件类型变更
            controlTypeChange() {
                if (
                    (this.data.controlType == 'DialogSelect' && (this.controlTypeBefore == 'Select' || this.controlTypeBefore == 'ComboSelect')) ||
                    (this.controlTypeBefore == 'DialogSelect' && (this.data.controlType == 'Select' || this.data.controlType == 'ComboSelect'))
                ) {
                    this.data.source = null;
                    this.data.sourceDisplayCode = null;
                    this.data.sourceDataCode = null;
                    this.data.param = null;
                }

                this.controlTypeBefore = this.data.controlType;
            },
            // 数据源变更
            sourceChange() {
                if (this.sourceBefore != this.data.source) {
                    this.data.sourceDisplayCode = null;
                    this.data.sourceDataCode = null;
                    this.data.param = null;
                }

                this.sourceBefore = this.data.source;
            },
            // 打开字段选择界面
            openColumnSelect(data, code) {
                if (this.data.source == null) {
                    return;
                }

                let model;
                if (this.data.controlType == 'DialogSelect') {
                    model = this.$refs.dataViewSource.selectedData.model;
                } else {
                    model = this.data.source;
                }

                this.$refs.columnCheck.open(
                    {
                        model: model
                    },
                    checked => {
                        data[code] = checked.code;
                        this.$forceUpdate();
                    }
                );
            },
            // 打开变量字段选择界面
            openValueSelect() {
                this.$refs.columnCheck.open(
                    {
                        model: this.data.dataView.model
                    },
                    checked => {
                        this.paramData.val = checked.code;
                        this.$forceUpdate();
                    }
                );
            },
            // 打开参数弹框
            paramOpen() {
                this.params = [];
                this.paramOpened = true;
                if (this.data.param != null && this.data.param != '') {
                    let obj = JSON.parse(this.data.param);
                    for (let key in obj) {
                        let type = '变量';
                        if (obj[key].indexOf('[') == 0 && obj[key].indexOf(']') + 1 == obj[key].length) {
                            type = '常量';
                        }
                        this.params.push({
                            code: key,
                            val: obj[key],
                            type: type
                        });
                    }
                }
            },
            // 参数框确认
            async paramItemSave() {
                let isOK = await this.$refs.paramItemForm.validate();

                if (!isOK) {
                    this.error('有内容不符合要求，请正确填写！');
                    return;
                }
                let val = this.paramData.val;

                if (this.paramData.keyType == '常量') {
                    let len = this.paramData.val.length;
                    val = this.paramData.val.padStart(len + 1, '[').padEnd(len + 2, ']');
                }

                if (this.paramData.source) {
                    this.paramData.source.code = this.paramData.code;
                    this.paramData.source.val = val;
                    this.paramData.source.type = this.paramData.keyType;
                } else {
                    this.params.push({
                        code: this.paramData.code,
                        val: val,
                        type: this.paramData.keyType
                    });
                }
                this.paramItemOpened = false;
                this.$refs.paramItemForm.resetFields();
            },
            paramItemClose() {
                this.paramItemOpened = false;
                this.$refs.paramItemForm.resetFields();
            },
            keyTypeChange() {
                setTimeout(() => {
                    this.paramData.val = null;
                    this.$forceUpdate();
                });
            },
            // 保存参数
            paramSave() {
                let obj = {};
                this.params.forEach(item => {
                    obj[item.code] = item.val;
                });

                this.data.param = this.params.length > 0 ? JSON.stringify(obj) : '';
                this.paramOpened = false;
            },
            // 编辑参数项
            paramEdit(row) {
                if (row) {
                    this.paramData = {
                        code: row.code,
                        val: row.val.replace('[', '').replace(']', ''),
                        keyType: row.type,
                        source: row
                    };
                } else {
                    this.paramData = {
                        code: '',
                        val: '',
                        keyType: '常量'
                    };
                }
                this.paramItemOpened = true;
            },
            // 上移参数项
            upParam(row, index) {
                if (index > 0) {
                    this.params.splice(index, 1);
                    this.params.splice(index - 1, 0, row);
                }
            },
            // 下移参数项
            downParam(row, index) {
                if (index < this.params.length - 1) {
                    this.params.splice(index, 1);
                    this.params.splice(index + 1, 0, row);
                }
            },
            // 删除参数项
            paramRemove(row, index) {
                this.params.splice(index, 1);
            }
        }
    };
</script>
