<template>
    <div class="p-5 space-y-5 !bg-gray-100">
        <el-card header="表单一个formItem中校验多个字段">
            <el-form
                :model="form"
                label-width="120px"
                :rules="rules"
                ref="formRef"
            >
                <el-form-item
                    label="新贷款利率区间"
                    prop="newLoanRateRange"
                >
                    <el-input
                        style="width: 45%"
                        v-model="form.newLoanRateMin"
                        placeholder="最小值"
                        :maxlength="10"
                        @input="handleRateInput('newLoanRateRange')"
                    />
                    <span style="width: 10%; text-align: center">至</span>
                    <el-input
                        style="width: 45%"
                        v-model="form.newLoanRateMax"
                        placeholder="最大值"
                        :maxlength="10"
                        @input="handleRateInput('newLoanRateRange')"
                    />
                </el-form-item>
                <el-form-item
                    label="降息利率区间"
                    prop="newRateRange"
                >
                    <el-input
                        style="width: 45%"
                        v-model="form.newRateMin"
                        placeholder="最小值"
                        :maxlength="10"
                        @input="handleRateInput('newRateRange')"
                    />
                    <span style="width: 10%; text-align: center">至</span>
                    <el-input
                        style="width: 45%"
                        v-model="form.newRateMax"
                        placeholder="最大值"
                        :maxlength="10"
                        @input="handleRateInput('newRateRange')"
                    />
                </el-form-item>
                <el-form-item
                    label="放款金额区间"
                    prop="getAmtRange"
                >
                    <el-input
                        style="width: 45%"
                        v-model="form.getAmtMin"
                        placeholder="最小值"
                        :maxlength="10"
                        @input="handleRateInput('getAmtRange')"
                    /><span style="width: 10%; text-align: center">至</span>
                    <el-input
                        style="width: 45%"
                        v-model="form.getAmtMax"
                        placeholder="最大值"
                        :maxlength="10"
                        @input="handleRateInput('getAmtRange')"
                    />
                </el-form-item>
                <el-form-item
                    label="放款时间区间"
                    prop="getTimeRange"
                >
                    <el-date-picker
                        style="width: 45%"
                        v-model="form.getTimeMin"
                        value-format="YYYY-MM-DD"
                        type="date"
                        placeholder="开始时间"
                        @change="handleRateInput('getTimeRange')"
                    />
                    <span style="width: 10%; text-align: center">至</span>
                    <el-date-picker
                        style="width: 45%"
                        v-model="form.getTimeMax"
                        value-format="YYYY-MM-DD"
                        type="date"
                        placeholder="结束时间"
                        @change="handleRateInput('getTimeRange')"
                    />
                </el-form-item>
            </el-form>
            <el-button
                type="primary"
                @click="submitForm"
                >点击校验表单</el-button
            >
        </el-card>
    </div>
</template>

<script setup>
import { ref } from 'vue';
import { message } from '@/utils/message';
import dayjs from 'dayjs';
const formRef = ref(null);
const form = ref({
    newLoanRateMin: '',
    newLoanRateMax: '',
    newRateMin: '',
    newRateMax: '',
    getAmtMin: '',
    getAmtMax: '',
    getTimeMin: '',
    getTimeMax: '',
});

const validatorRange = (rule, value, callback) => {
    const { minKey, maxKey, required } = rule.params || {};
    const min = form.value[minKey];
    const max = form.value[maxKey];
    // 添加必填校验
    if (required) {
        // 如果两个字段都为空，则报错
        if (!min && !max) {
            return callback(new Error(rule.message || '请输入区间值'));
        }
    }

    // 1. 最小值有值，最大值为空
    if (min && !max) {
        return callback(new Error('请输入最大值'));
    }

    // 2. 最大值有值，最小值为空
    if (max && !min) {
        return callback(new Error('请输入最小值'));
    }

    // 3. 两者都有值，检查最大值是否小于最小值
    if (min && max) {
        const validNumberRegex = /^(0|[1-9]\d*)(\.\d+)?$/;

        // 校验最小值格式
        if (!validNumberRegex.test(min)) {
            return callback(new Error('最小值格式不正确'));
        }

        // 校验最大值格式
        if (!validNumberRegex.test(max)) {
            return callback(new Error('最大值格式不正确'));
        }

        const minNum = parseFloat(min);
        const maxNum = parseFloat(max);

        if (isNaN(minNum) || isNaN(maxNum)) {
            return callback(new Error('请输入有效的数字'));
        }

        if (maxNum < minNum) {
            return callback(new Error('最大值不能小于最小值'));
        }
    }

    return callback();
};
const validatorDateRange = (rule, value, callback) => {
    const { minKey, maxKey, required } = rule.params || {};
    const min = form.value[minKey];
    const max = form.value[maxKey];

    // 添加必填校验
    if (required) {
        if (!min && !max) {
            return callback(new Error(rule.message || '请选择时间区间'));
        }
    }

    if (min && !max) {
        return callback(new Error('请选择结束时间'));
    }

    if (max && !min) {
        return callback(new Error('请选择开始时间'));
    }

    if (min && max && dayjs(min).isAfter(dayjs(max))) {
        return callback(new Error('开始时间不能晚于结束时间'));
    }

    return callback();
};

const rules = ref({
    // 重点1，这里newLoanRateMin，newLoanRateMax合并范围值newLoanRateRange，对应formItem的prop
    newLoanRateRange: [
        {
            // 重点2，这里validatorRange是自定义的校验函数
            validator: validatorRange,
            trigger: 'blur',
            // 重点3，这里params是传递给validatorRange的参数
            params: {
                minKey: 'newLoanRateMin',
                maxKey: 'newLoanRateMax',
                required: true,
            },
        },
    ],
    newRateRange: [
        {
            validator: validatorRange,
            trigger: 'blur',
            params: {
                minKey: 'newRateMin',
                maxKey: 'newRateMax',
                required: true,
            },
        },
    ],
    getAmtRange: [
        {
            validator: validatorRange,
            trigger: 'blur',
            params: {
                minKey: 'getAmtMin',
                maxKey: 'getAmtMax',
                required: true,
            },
        },
    ],
    getTimeRange: [
        {
            validator: validatorDateRange,
            trigger: 'blur',
            params: {
                minKey: 'getTimeMin',
                maxKey: 'getTimeMax',
                required: true,
            },
        },
    ],
});

const handleRateInput = (field) => {
    formRef.value.validateField(field, (valid) => {
        console.log(`${field}校验结果:${valid}`);
    });
};

const submitForm = () => {
    formRef.value.validate((valid) => {
        if (valid) {
            message('校验成功', { type: 'success' });
        } else {
            message('校验失败', { type: 'warning' });
            return false;
        }
    });
};
</script>

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