<div id="app" v-cloak>
    <el-card class="box-card control">

        <el-row>
            <el-col :span="3">
                <a>Nginx 控制中心</a>
            </el-col>
            <el-col :span="5">
                <a @click="nginxStart">
                    <el-image v-if="run" :src="'${Uri.getUrl('/static/img/start_.png')}'"
                              style="width: 50px; height: 50px"
                              fit="fill"></el-image>
                    <el-image v-if="!run" :src="'${Uri.getUrl('/static/img/start.png')}'"
                              style="width: 50px; height: 50px"
                              fit="fill"></el-image>
                </a>
                <a @click="nginxStop">
                    <el-image v-if="run" :src="'${Uri.getUrl('/static/img/stop.png')}'"
                              style="width: 50px; height: 50px"
                              fit="fill"></el-image>
                    <el-image v-if="!run" :src="'${Uri.getUrl('/static/img/stop_.png')}'"
                              style="width: 50px; height: 50px"
                              fit="fill"></el-image>
                </a>
                <a @click="nginxReload">
                    <el-image v-if="run" :src="'${Uri.getUrl('/static/img/reload.png')}'"
                              style="width: 50px; height: 50px"
                              fit="fill"></el-image>
                    <el-image v-if="!run" :src="'${Uri.getUrl('/static/img/reload_.png')}'"
                              style="width: 50px; height: 50px"
                              fit="fill"></el-image>
                </a>
            </el-col>
        </el-row>
    </el-card>
    <el-row>
        <el-col :span="24">
            <span style="float: right;">
            <el-button type="success" size="small" icon="el-icon-plus" @click="onAction(['create',{}])">新增
            </el-button>
            <el-button size="small" icon="el-icon-refresh" @click="onRefresh"></el-button>
            </span>
        </el-col>
    </el-row>

    <el-table
            :data="result.filter(data => !vm.search || data.name.toLowerCase().includes(vm.search.toLowerCase())|| data.value.toLowerCase().includes(vm.search.toLowerCase()))"
            style="width: 100%">
        <el-table-column
                width="150px"
                label="名称"
                prop="name">
            <template slot-scope="scope">
                <span style="margin-left: 10px">{{ scope.row.name }}</span>
                <el-popover
                        placement="top-start"
                        width="200"
                        trigger="hover"
                        :content="scope.row.bz">
                    <i slot="reference" class="el-icon-warning-outline"></i>
                </el-popover>
            </template>
        </el-table-column>
        <el-table-column
                width="130px"
                label="端口"
                prop="servicePort">
        </el-table-column>
        <el-table-column
                width="130px"
                label="路径"
                prop="context">
        </el-table-column>
        <el-table-column
                width="220px"
                label="地址"
                prop="location">
        </el-table-column>
        <el-table-column
                width="150px"
                label="创建日期"
                prop="createTime">
        </el-table-column>
        <el-table-column
                label="备注"
                prop="bz">
        </el-table-column>
        <el-table-column
                width="150px"
                align="right">
            <template slot="header" slot-scope="scope">
                <el-input
                        v-model="vm.search"
                        size="small"
                        placeholder="输入关键字搜索"/>
            </template>
            <template slot-scope="scope">
                <el-button
                        size="mini"
                        @click="onAction(['edit',scope.row,item])">编辑
                </el-button>
                <el-button
                        size="mini"
                        type="danger"
                        @click="onAction(['delete', scope.row])">删除
                </el-button>
            </template>
        </el-table-column>
    </el-table>

    <el-dialog :title="form.title" :visible.sync="form.dialog" width="550px">
        <el-form :model="form" :rules="formRules" ref="form" label-width="80px"
                 style="width: 400px;margin: 0 auto">
            <el-form-item label="映射名称" required prop="name">
                <el-row>
                    <el-col :span="22">
                        <el-input v-model="form.name" clearable size="small" placeholder="映射名称"></el-input>
                    </el-col>
                </el-row>
            </el-form-item>
            <el-form-item label="映射端口" required prop="servicePort">
                <el-row>
                    <el-col :span="22">
                        <el-input v-model="form.servicePort" type="number" clearable size="small" placeholder="映射端口"></el-input>
                    </el-col>
                </el-row>
            </el-form-item>
            <el-form-item label="映射路径" required prop="context">
                <el-row>
                    <el-col :span="22">
                        <el-input v-model="form.context" clearable size="small" placeholder="字母数字组合">
                            <template slot="prepend">http://host:{{form.servicePort}}</template>
                        </el-input>
                    </el-col>
                </el-row>
            </el-form-item>
            <el-form-item label="映射类型" required prop="type">
                <el-radio v-model="form.type" label="HTTP">HTTP</el-radio>
                <el-radio v-model="form.type" label="FILE">FILE</el-radio>
            </el-form-item>
            <el-form-item label="映射地址" required prop="location">
                <el-row>
                    <el-col :span="22">
                        <el-input v-model="form.location" clearable size="small"
                                  :placeholder="form.type=='HTTP'?'代理地址http://':'文件地址D:\ or /root'"></el-input>
                    </el-col>
                    <el-col :span="2" style="text-align: right">
                        <el-popover
                                placement="top-start"
                                width="200"
                                trigger="hover"
                                content="映射类型为文件时，映射路径名需和即将映射的文件夹一样，且不以“\”结尾，映射地址为该文件夹的上一层，则可正常访问。">
                            <i slot="reference" class="el-icon-warning-outline"></i>
                        </el-popover>
                    </el-col>
                </el-row>
            </el-form-item>
            <el-form-item label="映射备注" prop="bz">
                <el-row>
                    <el-col :span="22">
                        <el-input type="textarea" :autosize="{ minRows: 3, maxRows: 5}" v-model="form.bz" clearable
                                  size="small"
                                  placeholder="备注信息"></el-input>
                    </el-col>
                </el-row>
            </el-form-item>
        </el-form>
        <span slot="footer" class="dialog-footer">
                        <el-button size="small" @click="form.dialog = false">取 消</el-button>
                        <el-button size="small" type="primary" @click="onAction(['save',''])">保存</el-button>
                    </span>
    </el-dialog>
</div>
<style>
    #app {
        padding: 10px;
        margin: 0 auto;
        width: 1080px;
    }

    .box-card {
        margin: 10px;
    }

    .control a:first-child {
        padding-right: 10px;
    }

    .control a {
        display: inline-block;
        line-height: 50px;
        height: 50px;
        vertical-align: top;
    }

    .control a:hover {
        background: #e7e7e7;
    }

    .control a:first-child:hover {
        background: #ffffff;
    }
</style>
<script>
    var app = new Vue({
        el: "#app",
        data: {
            vm: {
                search: ""
            },
            form: {
                title: "",
                dialog: false,
                id: '',
                type: 'HTTP',
                context: '',
                location: '',
                name: '',
                bz: ''
            },
            formRules: {
                name: [
                    {required: true, message: '映射名称不能为空', trigger: 'blur'},
                    {min: 1, max: 50, message: '长度在 1 到 50 字符', trigger: 'blur'}
                ],
                servicePort: [
                    {required: true, message: '映射端口不能为空', trigger: 'blur'},
                    {pattern: "^[0-9]*$", message: '映射端口只能为数字', trigger: 'blur'},
                ],
                context: [
                    {required: true, message: '映射路径不能为空', trigger: 'blur'},
                    {pattern: "^/[a-zA-Z][a-zA-Z0-9_-]*$|^/$", message: '上下文须是(/)或(/+字母+字母数字及_', trigger: 'blur'},
                ],
                location: [
                    {required: true, message: '映射地址不能为空', trigger: 'change'},
                    {
                        validator: function (rule, value, callback) {
                            if (app.form.type == "HTTP") {
                                if (value.match("http:\/\/.*")) {
                                    callback();
                                } else {
                                    callback(new Error("需以http://协议开始"))
                                }
                            }
                            if (app.form.type == "FILE") {
                                if (value.match("^[A-Z]:\\\\.*$|^[A-Z]:/.*$|^/.*$")) {
                                    callback();
                                } else {
                                    callback(new Error("windows目录(C:\\)或linux目录(\\)"))
                                }
                            }
                        }, trigger: 'blur'
                    }
                ],
            },
            result: [],
            run: ${run?default('false')}
        },
        methods: {
            onFind: function () {
                ajax.mappingFind(this.vm).then(function (response) {
                    if (response.errors.length > 0) {
                        nav.e(response.errors[0].message);
                    } else {
                        this.result = response.result;
                    }
                }.bind(this))
            },
            onAction: function (arg) {
                const action = arg[0];
                switch (action) {
                    case "create":
                        this.form.title = '新增';
                        this.form.servicePoert = "8080";
                        this.form.port = arg[1].value;
                        this.form.id = '';
                        this.form.name = '';
                        this.form.context = '';
                        this.form.type = 'HTTP';
                        this.form.location = '';
                        this.form.bz = '';
                        this.form.dialog = true;
                        break;
                    case "edit":
                        this.form.title = '编辑';
                        this.form.id = arg[1].id;
                        this.form.serviceId = arg[1].serviceId;
                        this.form.port = arg[2].value;
                        this.form.name = arg[1].name;
                        this.form.context = arg[1].context;
                        this.form.type = arg[1].type;
                        this.form.location = arg[1].location;
                        this.form.bz = arg[1].bz;
                        this.form.dialog = true;
                        break;
                    case "save":
                        this.$refs['form'].validate(function (valid) {
                            if (valid) {
                                if (this.form.id) {
                                    ajax.mappingUpdate(this.form).then(function (response) {
                                        if (response.errors.length > 0) {
                                            nav.e(response.errors[0].message);
                                        } else {
                                            this.onFind();
                                            this.form.dialog = false;
                                            this.configFlush();
                                            if (this.run) {
                                                this.nginxReload();
                                            }
                                        }
                                    }.bind(this))
                                } else {
                                    ajax.mappingCreate(this.form).then(function (response) {
                                        if (response.errors.length > 0) {
                                            nav.e(response.errors[0].message);
                                        } else {
                                            this.onFind();
                                            this.form.dialog = false;
                                            this.configFlush();
                                            if (this.run) {
                                                this.nginxReload();
                                            }
                                        }
                                    }.bind(this))
                                }
                            } else {
                                return false;
                            }
                        }.bind(this));
                        break;
                    case "delete":
                        this.$confirm('将删除该项, 是否继续?', '提示', {
                            confirmButtonText: '确定',
                            cancelButtonText: '取消',
                            type: 'warning'
                        }).then(function () {
                            ajax.mappingDelete({id: arg[1].id}).then(function (response) {
                                if (response.errors.length > 0) {
                                    nav.e(response.errors[0].message);
                                } else {
                                    nav.s("删除成功");
                                    this.onFind();
                                    this.configFlush();
                                    if (this.run) {
                                        this.nginxReload();
                                    }
                                }
                            }.bind(this))
                        }.bind(this)).catch(function (action) {

                        });
                        break;
                }
            },
            startMonitor: function () {
                if (window.EventSource) {
                    window.evtSource = new EventSource('${Uri.getUrl("/sse/1")}');
                    window.evtSource.addEventListener('message', function (e) {

                        var msg = JSON.parse(e.data);
                        if (msg.type == 'NGINX_STATE') {//状态推送
                            if (this.run != msg.object.run) {

                                this.$notify.info({
                                    title: '提示',
                                    message: "Nginx 运行状态发生变化。",
                                    duration: 5000
                                });
                                this.run = msg.object.run;
                            }
                        }
                    }.bind(this))
                }
            },
            nginxStart: function () {
                ajax.nginxStart().then(function (response) {
                    if (response.errors.length > 0) {
                        nav.e(response.errors[0].message);
                    } else {
                        this.onFind();
                        this.form.dialog = false;
                    }
                }.bind(this))
            },
            nginxStop: function () {
                ajax.nginxStop().then(function (response) {
                    if (response.errors.length > 0) {
                        nav.e(response.errors[0].message);
                    } else {
                        this.onFind();
                        this.form.dialog = false;
                    }
                }.bind(this))
            },
            configFlush: function () {
                ajax.configFlush();
            },
            onRefresh: function () {
                this.configFlush();
                this.onFind();
            },
            nginxReload: function () {
                ajax.nginxReload().then(function (response) {
                    if (response.errors.length > 0) {
                        nav.e(response.errors[0].message);
                    } else {

                    }
                }.bind(this))
            }
        },
        created: function () {
        },
        mounted: function () {
            this.onFind();
            this.startMonitor();
        },
        watch: {}
    })
</script>
