<template>
    <el-card header="动态增减嵌套表单验证问题(inputNumber设置空的默认值问题)">
        <el-form
            v-if="form && form.groups"
            ref="formRef"
            :model="form"
            :label-width="150"
        >
            <template
                v-for="(item, index) in form.groups"
                :key="index"
            >
                <h3>
                    <span> 分组：</span>
                    <el-button
                        v-if="form.groups.length > 1"
                        type="primary"
                        @click="removeGroup(index)"
                        >删除分组</el-button
                    >
                    <el-button
                        v-if="index === form.groups.length - 1"
                        type="primary"
                        @click="addGroup"
                        >增加分组</el-button
                    >
                </h3>
                <el-divider></el-divider>
                <el-form-item
                    label="分组名称"
                    :prop="`groups[${index}].name`"
                    :rules="[
                        // 必填验证
                        {
                            required: true,
                            message: '请输入分组名称',
                            trigger: 'blur',
                        },
                        // 正则表达式验证
                        {
                            pattern: /^[\u4e00-\u9fa5a-zA-Z0-9_]+$/,
                            message: '只能输入中文、字母、数字、下划线',
                            trigger: 'blur',
                        },
                        // 函数验证，demo 验证分组名称是否唯一
                        {
                            validator: (rule, value, callback) => validName(index, value, callback),
                            trigger: 'blur',
                        },
                    ]"
                >
                    <el-input
                        v-model="item.name"
                        placeholder="请输入分组名称"
                    />
                </el-form-item>
                <template
                    v-for="(cItem, cIndex) in item.rules"
                    :key="cIndex"
                >
                    <el-divider></el-divider>
                    <h4 class="pl-10 pb-5">
                        <span>规则：</span>
                        <el-button
                            v-if="item.rules.length > 1"
                            type="primary"
                            @click="removeRule(index, cIndex)"
                            >删除规则</el-button
                        >
                        <el-button
                            v-if="cIndex === item.rules.length - 1"
                            type="primary"
                            @click="addRule(index)"
                            >增加规则</el-button
                        >
                    </h4>
                    <el-form-item
                        label="规则名称"
                        :prop="`groups[${index}].rules[${cIndex}].alert`"
                        :rules="[
                            // 必填验证
                            {
                                required: true,
                                message: '请输入规则名称',
                                trigger: 'blur',
                            },
                            // 正则表达式验证
                            {
                                pattern: /^[\u4e00-\u9fa5a-zA-Z0-9_]+$/,
                                message: '只能输入中文、字母、数字、下划线',
                                trigger: 'blur',
                            },
                        ]"
                    >
                        <el-input
                            v-model="cItem.alert"
                            placeholder="请输入规则名称"
                        />
                    </el-form-item>
                    <el-form-item
                        label="规则表达式"
                        :prop="`groups[${index}].rules[${cIndex}].expr`"
                    >
                        <el-input
                            v-model="cItem.expr"
                            placeholder="请输入规则表达式"
                        />
                    </el-form-item>
                    <el-form-item
                        label="待发时长"
                        :prop="`groups[${index}].rules[${cIndex}].for`"
                    >
                        <el-input-number
                            :min="0"
                            :max="999"
                            :maxlength="3"
                            v-model="cItem.for"
                            placeholder="请输入待发时长"
                        />
                    </el-form-item>
                    <el-form-item
                        label="告警标题"
                        :prop="`groups[${index}].rules[${cIndex}].annotations.summary`"
                    >
                        <el-input
                            v-model="cItem.annotations.summary"
                            placeholder="请输入告警标题"
                        />
                    </el-form-item>
                    <el-form-item
                        label="告警详情"
                        :prop="`groups[${index}].rules[${cIndex}].annotations.des`"
                    >
                        <el-input
                            v-model="cItem.annotations.des"
                            placeholder="请输入告警详情"
                        />
                    </el-form-item>
                </template>
            </template>
        </el-form>
    </el-card>
</template>

<script setup lang="jsx">
import { ref } from 'vue';
const formRef = ref(null);

/**
 * groups 可以有多个
 * rules  可以有多个
 * name 必填，名称唯一
 */
const form = ref({
    groups: [
        {
            name: 'yaml规则1',
            rules: [
                {
                    alert: '节点状态1',
                    annotations: {
                        des: '节点状态必须为正常',
                        summary: 'IP xxxx 状态异常',
                    },
                    expr: 'up == 1',
                    for: 1,
                    labels: {
                        severity: 'warning',
                        status: 'firing',
                    },
                },
            ],
        },
        {
            name: 'yaml规则2',
            rules: [
                {
                    alert: '节点状态1',
                    annotations: {
                        des: '节点状态必须为正常',
                        summary: 'IP xxxx 状态异常',
                    },
                    expr: 'up == 1',
                    for: 0,
                    labels: {
                        severity: 'warning',
                        status: 'firing',
                    },
                },
                {
                    alert: '节点状态2',
                    annotations: {
                        des: '节点状态必须为正常',
                        summary: 'IP xxxx 状态异常',
                    },
                    expr: 'up == 1',
                    for: 10,
                    labels: {
                        severity: 'warning',
                        status: 'firing',
                    },
                },
            ],
        },
    ],
});

const initRules = () => {
    return {
        alert: '',
        annotations: {
            des: '',
            summary: '',
        },
        expr: '',
        /**
         * 当inputNumber设置空的默认值问题(设置空字符串''会有警告，并且会默认转为0), 可以通过设置NaN来解决
         * 如果后续判断值是否为NaN,需要使用Number.isNaN()来判断，不能使用 === NaN,永远为false
         */
        for: NaN,
        labels: {
            severity: '',
            status: '',
        },
    };
};

const initGroup = () => {
    return {
        name: '',
        rules: [initRules()],
    };
};

const addGroup = () => {
    form.value.groups.push(initGroup());
};

const addRule = (index) => {
    form.value.groups[index].rules.push(initRules());
};

const removeGroup = (index) => {
    form.value.groups.splice(index, 1);
};

const removeRule = (index, cIndex) => {
    form.value.groups[index].rules.splice(cIndex, 1);
};

const validName = (index, value, callback) => {
    const groups = form.value.groups;
    if (groups.length <= 1) {
        callback();
    }
    for (let i = 0; i < groups.length; i++) {
        if (i === index) {
            continue;
        }
        if (groups[i].name === value) {
            callback(new Error('分组名称已存在'));
            return;
        }
    }
};
</script>

<style lang="scss" scoped></style>
