<template>
    <div v-loading="loading" element-loading-text="拼命加载中" class="edit-view">
        <div class="edit-view__content-wrapper">
            <div class="edit-view__content-section">
                <el-form
                    :model="formData"
                    :rules="rules"
                    ref="form"
                    label-width="50px"
                    label-position="right"
                    size="mini"
                >
                    <el-form-item prop="tableName" label="表名">
                        <el-select
                            placeholder="表名"
                            clearable
                            filterable
                            v-model="formData.tableName"
                            @change="changeTableName"
                            class="filter-item"
                        >
                            <el-option
                                v-for="item in tableList"
                                :label="item.name"
                                :value="item.name"
                                :key="item.name"
                            ></el-option>
                        </el-select>
                    </el-form-item>

                    <el-form-item prop="className" label="类名">
                        <el-input v-model="formData.className" style="width: 400px;"> </el-input>
                    </el-form-item>

                    <el-form-item prop="tablePackage" label="包名">
                        <el-input v-model="formData.tablePackage" style="width: 400px;"> </el-input>
                    </el-form-item>

                    <el-form-item prop="remark" label="描述">
                        <el-input v-model="formData.remark" style="width: 400px;"> </el-input>
                    </el-form-item>

                    <el-form-item label="目录">
                        {{ formData.javaPath }}<br />
                        {{ formData.viewPath }}<br />
                        {{ formData.routerPath }}<br />
                        {{ formData.resourcesPath }}
                    </el-form-item>

                    <el-form-item prop="genCode" label="生成">
                        <el-checkbox v-model="formData.genClass" label="类"> </el-checkbox>
                        <el-checkbox v-model="formData.genList" label="列表"> </el-checkbox>
                        <el-checkbox v-model="formData.genForm" label="表单"> </el-checkbox>
                        <el-checkbox v-model="formData.genRouter" label="路由"> </el-checkbox>
                    </el-form-item>
                    <el-form-item prop="fields" label="数据">
                        <el-tabs value="1" type="border-card">
                            <el-tab-pane label="字段" name="1">
                                <el-table :data="fields">
                                    <el-table-column prop="name" label="字段名" width="200" align="center">
                                        <template slot-scope="{ row }">
                                            <el-input v-model="row.name"></el-input>
                                        </template>
                                    </el-table-column>
                                    <el-table-column prop="remark" label="描述" align="center" width="200">
                                        <template slot-scope="{ row }">
                                            <el-input v-model="row.remark"></el-input>
                                        </template>
                                    </el-table-column>
                                    <el-table-column width="130" align="center">
                                        <template slot-scope="{ row, column, $index }">
                                            <el-button @click="moveUp($index)" type="text">上移</el-button>
                                            <el-button @click="moveDown($index)" type="text">下移</el-button>
                                            <el-button @click="removeField($index)" type="text">删除</el-button>
                                        </template>
                                    </el-table-column>
                                </el-table>
                                <el-button @click="addField" type="text" icon="el-icon-plus">添加</el-button>
                            </el-tab-pane>
                            <el-tab-pane label="页面属性" name="2">
                                <el-table :data="editableFields">
                                    <el-table-column prop="name" label="字段" width="200"> </el-table-column>
                                    <el-table-column prop="showInList" label="列表" width="50" align="center">
                                        <template slot-scope="{ row }">
                                            <el-checkbox v-model="row.showInList"> </el-checkbox>
                                        </template>
                                    </el-table-column>
                                    <el-table-column prop="showInForm" label="表单" width="50" align="center">
                                        <template slot-scope="{ row }">
                                            <el-checkbox
                                                v-model="row.showInForm"
                                                :disabled="row.primaryKey && !formData.readTable"
                                            >
                                            </el-checkbox>
                                        </template>
                                    </el-table-column>
                                    <!-- <el-table-column prop="sortable" label="排序" width="50" align="center">
                                <template slot-scope="{row}">
                                    <el-checkbox v-model="row.sortable"></el-checkbox>
                                </template>
                            </el-table-column> -->
                                    <el-table-column prop="formType" label="表单类型" width="150" align="center">
                                        <template slot-scope="{ row }">
                                            <el-select v-model="row.formType">
                                                <el-option
                                                    v-for="item in formTypes"
                                                    :label="item.label"
                                                    :value="item.value"
                                                    :key="item.value"
                                                ></el-option>
                                            </el-select>
                                        </template>
                                    </el-table-column>
                                    <el-table-column prop="apiFlag" label="接口" width="300" align="center">
                                        <template slot-scope="{ row }">
                                            <el-radio
                                                v-model="row.apiFlag"
                                                label="1"
                                                :disabled="row.formType !== 'select' && row.formType !== 'multiSelect'"
                                            >
                                                枚举
                                            </el-radio>
                                            <el-radio
                                                v-model="row.apiFlag"
                                                label="2"
                                                :disabled="row.formType !== 'select' && row.formType !== 'multiSelect'"
                                            >
                                                接口
                                            </el-radio>
                                        </template>
                                    </el-table-column>
                                    <el-table-column prop="optionsValue" label="选项" min-width="150" align="center">
                                        <template slot-scope="{ row }">
                                            <el-input
                                                class="code"
                                                v-model="row.optionsValue"
                                                autosize
                                                v-if="
                                                    row.apiFlag === '1' &&
                                                        (row.formType === 'select' || row.formType === 'multiSelect')
                                                "
                                            >
                                                <el-button slot="append" type="text" @click="editOptions(row)"
                                                    >编辑
                                                </el-button>
                                            </el-input>
                                            <el-input
                                                class="code"
                                                :value="optionsInfo(row)"
                                                disabled
                                                v-if="
                                                    (row.apiFlag === '2' || row.apiFlag === '3') &&
                                                        (row.formType === 'select' || row.formType === 'multiSelect')
                                                "
                                            >
                                                <el-button slot="append" type="text" @click="editSelectField(row)"
                                                    >编辑
                                                </el-button>
                                            </el-input>
                                        </template>
                                    </el-table-column>
                                    <!-- <el-table-column prop="searchMethod" label="搜索方式" width="150" align="center">
                                <template slot-scope="{row}">
                                    <el-select v-model="row.searchMethod">
                                        <el-option v-for="item in searchMethods" :label="item" :value="item" :key="item"></el-option>
                                    </el-select>
                                </template>
                            </el-table-column> -->
                                </el-table>
                            </el-tab-pane>
                            <el-tab-pane label="表单校验" name="3">
                                <el-table :data="fields">
                                    <el-table-column prop="name" label="字段" width="200"> </el-table-column>
                                    <!-- <el-table-column prop="logicalKey" label="逻辑关键字"
                                             width="100" align="center">
                                <template slot-scope="{row}">
                                    <el-checkbox v-model="row.logicalKey">
                                    </el-checkbox>
                                </template>
                            </el-table-column> -->
                                    <el-table-column prop="required" label="必填" width="50" align="center">
                                        <template slot-scope="{ row }">
                                            <el-checkbox v-model="row.required"> </el-checkbox>
                                        </template>
                                    </el-table-column>
                                    <el-table-column prop="validate" label="校验" width="50" align="center">
                                        <template slot-scope="{ row }">
                                            <el-checkbox v-model="row.validate"> </el-checkbox>
                                        </template>
                                    </el-table-column>
                                    <el-table-column prop="minLength" label="最短" min-width="80" align="center">
                                        <template slot-scope="{ row }">
                                            <el-input v-model.number="row.minLength"> </el-input>
                                        </template>
                                    </el-table-column>
                                    <el-table-column prop="maxLength" label="最长" min-width="80" align="center">
                                        <template slot-scope="{ row }">
                                            <el-input v-model.number="row.maxLength"> </el-input>
                                        </template>
                                    </el-table-column>
                                    <el-table-column prop="min" label="最小值" min-width="80" align="center">
                                        <template slot-scope="{ row }">
                                            <el-input v-model="row.min"></el-input>
                                        </template>
                                    </el-table-column>
                                    <el-table-column prop="max" label="最大值" min-width="80" align="center">
                                        <template slot-scope="{ row }">
                                            <el-input v-model="row.max"></el-input>
                                        </template>
                                    </el-table-column>
                                    <el-table-column
                                        prop="validatorType"
                                        label="校验类型"
                                        min-width="150"
                                        align="center"
                                    >
                                        <template slot-scope="{ row }">
                                            <el-select v-model="row.validatorType" clearable>
                                                <el-option
                                                    v-for="item in validatorTypes"
                                                    :label="item.label"
                                                    :value="item.value"
                                                    :key="item.value"
                                                ></el-option>
                                            </el-select>
                                        </template>
                                    </el-table-column>
                                </el-table>
                            </el-tab-pane>
                            <el-tab-pane label="子表" name="4">
                                <el-table :data="subtables">
                                    <el-table-column prop="name" label="控件名" width="150" align="center">
                                        <template slot-scope="{ row }">
                                            <el-input v-model="row.name"></el-input>
                                        </template>
                                    </el-table-column>

                                    <el-table-column prop="column" label="主表字段" width="150" align="center">
                                        <template slot-scope="{ row }">
                                            <el-input v-model="row.column"></el-input>
                                        </template>
                                    </el-table-column>

                                    <el-table-column prop="subColumn" label="子表字段" width="150" align="center">
                                        <template slot-scope="{ row }">
                                            <el-input v-model="row.subColumn"> </el-input>
                                        </template>
                                    </el-table-column>
                                    <el-table-column prop="subCode" label="子表类" width="150" align="center">
                                        <template slot-scope="{ row }">
                                            <el-select v-model="row.subCode" clearable>
                                                <el-option
                                                    v-for="item in subCodes"
                                                    :label="item.className"
                                                    :value="item.className"
                                                    :key="item.className"
                                                ></el-option>
                                            </el-select>
                                        </template>
                                    </el-table-column>
                                    <el-table-column width="60" align="center">
                                        <template slot-scope="{ row, column, $index }">
                                            <el-button @click="removeSubtable($index)" type="text">删除</el-button>
                                        </template>
                                    </el-table-column>
                                </el-table>
                                <el-button @click="addSubtable" type="text" icon="el-icon-plus">添加</el-button>
                            </el-tab-pane>
                        </el-tabs>
                    </el-form-item>
                    <el-form-item>
                        <el-button @click="onSave" :loading="$store.state.fetchingData" type="primary">保存</el-button>
                        <el-button @click="$router.go(-1)">取消</el-button>
                    </el-form-item>
                </el-form>

                <el-dialog title="接口选项" :visible.sync="showApiSelectDialog">
                    <el-form :model="selectField" label-position="right" label-width="80px">
                        <el-form-item label="接口">
                            <el-select
                                placeholder="接口"
                                filterable
                                clearable
                                v-model="selectField.optionsMethod"
                                class="filter-item"
                            >
                                <el-option
                                    v-for="item in selectMappings"
                                    :label="item.url"
                                    :value="item.url"
                                    :key="item.url"
                                >
                                </el-option>
                            </el-select>
                        </el-form-item>
                        <el-form-item label="显示">
                            <el-input v-model="selectField.optionsLabel"> </el-input>
                        </el-form-item>
                        <el-form-item label="选项">
                            <el-input v-model="selectField.optionsValue"> </el-input>
                        </el-form-item>
                    </el-form>
                    <span slot="footer" class="dialog-footer">
                        <el-button type="primary" @click="selectMappingSubmit">确定 </el-button>
                    </span>
                </el-dialog>

                <gen-option-dialog
                    :visible.sync="showGenOptionsDialog"
                    v-model="tempRow.optionsValue"
                ></gen-option-dialog>
            </div>
        </div>
    </div>
</template>

<script>
import GenOptionDialog from '../components/GenOptionsDialog';

export default {
    created() {
        if (this.$route.query.className) {
            this.loading = true;
            this.$http
                .get('/genCode/getOne', {
                    className: this.$route.query.className
                })
                .then(res => {
                    console.log(res);
                    this.loading = false;

                    this.$http
                        .get('/genCode/tableFields', {
                            className: res.tablePackage
                        })
                        .then(fields => {
                            this.formData = {
                                ...this.formData,
                                ...res,
                                className: res.className,
                                tableName: res.tableName,
                                genRouter: false
                            };
                            let finalFields = [];

                            fields.forEach(field => {
                                let f = this.formData.fields.find(i => {
                                    return (i.modelName = field.modalName);
                                });
                                if (f) {
                                    finalFields.push(f);
                                } else {
                                    finalFields.push(field);
                                }
                            });
                            this.fields = finalFields;
                            this.subtables = this.formData.subtables;
                        })
                        .catch(e => {
                            console.log(e);
                        });
                })
                .catch(e => {
                    console.log(e);
                    this.loading = false;
                });
        }
        Promise.resolve()
            .then(() => {
                if (this.$route.query.className) {
                    this.loading = true;
                    return this.$http.get('/genCode/getOne', {
                        className: this.$route.query.className
                    });
                } else {
                    return Promise.resolve();
                }
            })
            .then(res => {
                this.loading = false;
                if (res) {
                    this.$http
                        .get('/genCode/tableFields', {
                            className: res.tablePackage
                        })
                        .then(fields => {
                            this.formData = {
                                ...this.formData,
                                ...res,
                                className: res.className,
                                tableName: res.tableName,
                                genRouter: false
                            };
                            let finalFields = [];

                            fields.forEach(field => {
                                let f = res.fields.find(item => {
                                    return item.modelName === field.modelName;
                                });
                                if (f) {
                                    finalFields.push(f);
                                } else {
                                    finalFields.push(field);
                                }
                            });
                            this.fields = finalFields;
                            this.subtables = this.formData.subtables;
                        })
                        .catch(e => {
                            console.log(e);
                        });
                }
                return this.$http.get('/genCode/getSrcPath');
            })
            .then(res => {
                this.formData.javaPath = res.javaPath;
                this.formData.viewPath = res.viewPath;
                this.formData.routerPath = res.routerPath;
                this.formData.resourcesPath = res.resourcesPath;
            })
            .catch(e => {
                console.log(e);
                this.$message.error(e.error);
                this.loading = false;
            });

        this.$http
            .get('/genCode/all')
            .then(res => {
                this.subCodes = res;
            })
            .catch(e => {
                console.log(e);
            });

        this.$http
            .get('/dev/selectMappings')
            .then(res => {
                let temp = {};
                if (res.length > 0) {
                    res.forEach(item => {
                        temp[item.url] = item;
                    });
                }
                this.selectMappingsJson = temp;
                this.selectMappings = res;
            })
            .catch(e => {
                console.log(e);
            });

        this.getDatabaseTables();
    },
    data() {
        return {
            loading: false,
            fieldTypes: ['char', 'varchar', 'int', 'bit', 'text', 'timestamp', 'datetime', 'decimal', 'float', 'vue'],
            searchMethods: ['=', '!=', '>', '>=', '<', '<=', 'between', 'like', 'left like', 'right like'],
            formTypes: [
                { label: '单行文本', value: 'singleLineText' },
                { label: '数字', value: 'number' },
                { label: '日期选择', value: 'date' },
                { label: '日期时间选择', value: 'datetime' },
                { label: '登录名', value: 'loginName' },
                { label: '当前时间', value: 'currentTime' },
                { label: '当前日期', value: 'currentDate' },
                { label: '单选下拉框', value: 'select' },
                { label: '多选下拉框', value: 'multiSelect' },
                { label: '单图上传', value: 'singleImage' },
                { label: '多图上传', value: 'multiImage' },
                { label: '文件上传', value: 'fileUpload' },
                { label: '树形选择', value: 'tree' },
                { label: '开关', value: 'switch' },
                { label: '多行文本', value: 'textarea' },
                { label: '富文本', value: 'richText' }
            ],
            validatorTypes: [
                { label: '英文', value: 'english' },
                { label: '数字', value: 'number' },
                { label: '手机', value: 'phone' },
                { label: '网址', value: 'url' },
                { label: '电子邮件', value: 'email' },
                { label: '身份证', value: 'id' }
            ],
            rules: {
                className: [
                    { required: true, message: '请填写类名', trigger: 'blur' },
                    {
                        validator: (rule, value, callback) => {
                            if (value) {
                                if (/^[\u4e00-\u9fa5a-zA-Z0-9_]*$/.test(value)) {
                                    callback();
                                } else {
                                    callback(new Error('类名不正确'));
                                }
                            }
                        },
                        trigger: 'blur'
                    }
                ],
                tableName: [
                    { required: true, message: '请填写表名', trigger: 'blur' },
                    {
                        validator: (rule, value, callback) => {
                            if (value) {
                                if (/^[\u4e00-\u9fa5a-zA-Z0-9_]*$/.test(value)) {
                                    callback();
                                } else {
                                    callback(new Error('表名不正确'));
                                }
                            }
                        },
                        trigger: 'blur'
                    }
                ],
                remark: [{ required: true, message: '请填写描述', trigger: 'blur' }],
                dataBaseType: [
                    {
                        required: true,
                        message: '请选择数据库类型',
                        trigger: 'blur'
                    }
                ],
                dataSourceCode: [
                    {
                        required: true,
                        message: '请填选择数据库',
                        trigger: 'blur'
                    }
                ],
                typeFlag: [
                    {
                        required: true,
                        message: '请填填写分类',
                        trigger: 'blur'
                    }
                ]
            },
            formData: {
                tableName: '',
                remark: '',
                genTable: true,
                genClass: true,
                genList: true,
                genForm: true,
                genRouter: true,
                javaPathRelative: '',
                viewPathRelative: '',
                dataBaseType: 'Mysql',
                readTable: false,
                dataSourceCode: 'dataSource',
                className: '',
                subtables: [],
                fields: []
            },
            fields: [],
            tableList: [],
            subtables: [],
            subCodes: [],
            selectMappings: [],
            selectMappingsJson: {},
            showApiSelectDialog: false,
            selectField: {},
            showTableSelectDialog: false,
            optionsTableList: [],
            optionsFields: [],
            showGenOptionsDialog: false,
            tempRow: {}
        };
    },
    computed: {
        editableFields() {
            return this.fields.filter(i => {
                return i.name;
            });
        }
    },
    methods: {
        onSave() {
            this.$refs.form.validate(valid => {
                if (valid) {
                    this.submit();
                } else {
                    return false;
                }
            });
        },
        submit() {
            this.formData.fields = this.fields;
            this.formData.subtables = this.subtables;
            this.formData.genJson = '';

            this.$alert('生成代码可能会删除已有同名表、数据或文件，确认要生成么？', '警告', { type: 'error' })
                .then(() => {
                    this.loading = true;
                    return this.$http.post('/genCode/save', this.formData, {
                        body: 'json'
                    });
                })
                .then(() => {
                    this.loading = false;
                    this.$message.success('代码生成成功');
                    this.$router.go(-1);
                })
                .catch(e => {
                    this.loading = false;
                    if ('cancel' !== e) {
                        this.$message.error(eval);
                    }
                });
        },
        addField() {
            this.fields.push({
                name: '',
                jdbcType: 'varchar',
                notNull: false,
                primaryKey: false,
                autoIncrease: false,
                remark: '',
                showInList: true,
                showInForm: true,
                formType: 'singleLineText',
                sortable: true
            });
        },
        removeField(i) {
            if (this.fields.length > 0) {
                this.fields.splice(i, 1);
            }
        },
        getDatabaseTables() {
            this.tableList = [];
            this.$http
                .get('/dev/entities')
                .then(res => {
                    this.tableList = res;
                })
                .catch(e => {
                    console.log(e);
                });
        },
        getPackageByTableName(tableName) {
            var packageName = '';
            this.tableList.forEach(item => {
                if (item.name == tableName) {
                    packageName = item.package;
                }
            });
            return packageName;
        },
        changeTableName() {
            this.fields = [];
            this.formData.className = this.formData.tableName;
            this.formData.tablePackage = this.getPackageByTableName(this.formData.tableName);
            this.getTableFields(this.formData.tableName);
        },
        changeOptionsTableName() {
            this.optionsFields = [];

            this.getOptionsTableFields(this.selectField.optionsMethod);
        },
        getTableFields(tableName) {
            var data = {
                className: this.getPackageByTableName(tableName)
            };
            this.$http
                .get('/genCode/tableFields', data)
                .then(res => {
                    this.fields = res;
                })
                .catch(e => {
                    console.log(e);
                });
        },
        getOptionsTableFields(tableName) {
            var data = {
                className: this.getPackageByTableName(tableName)
            };
            this.$http
                .get('/genCode/tableFields', data)
                .then(res => {
                    this.optionsFields = res;
                })
                .catch(e => {
                    console.log(e);
                });
        },
        addSubtable() {
            this.subtables.push({
                name: '',
                column: '',
                subColumn: '',
                subCode: ''
            });
        },
        removeSubtable(i) {
            if (this.subtables.length > 0) {
                this.subtables.splice(i, 1);
            }
        },
        moveUp(i) {
            if (i > 0) {
                let tempFields = [...this.fields];
                let tempField = tempFields[i - 1];

                tempFields[i - 1] = tempFields[i];
                tempFields[i] = tempField;

                this.fields = tempFields;
            }
        },
        moveDown(i) {
            if (this.fields.length - 1 > i) {
                let tempFields = [...this.fields];

                let tempField = tempFields[i + 1];

                tempFields[i + 1] = tempFields[i];
                tempFields[i] = tempField;

                this.fields = tempFields;
            }
        },
        editSelectField(row) {
            this.selectField = row;

            if (row.apiFlag === '2') {
                this.showApiSelectDialog = true;
            }
        },
        optionsInfo(row) {
            let value = '';
            if (row.apiFlag === '1') {
                value = row.optionsValue;
            } else if (row.apiFlag === '2') {
                value = row.optionsMethod + ',' + row.optionsLabel + ',' + row.optionsValue;
            }
            return value;
        },
        selectMappingSubmit() {
            if (this.selectField.apiFlag === '2') {
                this.showApiSelectDialog = false;
            }
        },
        editOptions(row) {
            this.tempRow = row;
            this.showGenOptionsDialog = true;
        }
    },
    components: {
        GenOptionDialog
    }
};
</script>

<style lang="less" scoped>
.code {
    font-family: 'dejavu sans mono', 'droid sans mono', consolas, monaco, 'lucida console', 'courier new', courier,
        monospace, sans-serif;
}
</style>
