first commit
This commit is contained in:
@@ -0,0 +1,194 @@
|
||||
<template>
|
||||
<el-dialog v-model="visible" :title="formData.id ? '编辑租户' : '添加租户'" width="600px" @closed="handleClosed"
|
||||
destroy-on-close>
|
||||
<el-form ref="formRef" :model="formData" :rules="rules" label-width="100px" v-loading="loading"
|
||||
style="padding: 20px">
|
||||
<el-form-item label="租户编码" prop="tenant_code">
|
||||
<el-input v-model="formData.tenant_code" placeholder="系统自动生成" disabled />
|
||||
<div class="form-tip" v-if="!formData.id" style="font-size: 12px; color: #999;">
|
||||
* 编码由系统随机分配,提交时将自动校验唯一性
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="租户名称" prop="tenant_name">
|
||||
<el-input v-model="formData.tenant_name" placeholder="请输入租户名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="联系人" prop="contact_person">
|
||||
<el-input v-model="formData.contact_person" placeholder="请输入联系人" />
|
||||
</el-form-item>
|
||||
<el-form-item label="联系电话" prop="contact_phone">
|
||||
<el-input v-model="formData.contact_phone" placeholder="请输入联系电话" />
|
||||
</el-form-item>
|
||||
<el-form-item label="电子邮箱" prop="contact_email">
|
||||
<el-input v-model="formData.contact_email" placeholder="请输入电子邮箱" />
|
||||
</el-form-item>
|
||||
<el-form-item label="租户地址" prop="address">
|
||||
<el-input v-model="formData.address" type="textarea" placeholder="请输入地址" />
|
||||
</el-form-item>
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-radio-group v-model="formData.status">
|
||||
<el-radio :label="1">启用</el-radio>
|
||||
<el-radio :label="0">禁用</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<el-button @click="visible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="submitting" @click="submitForm">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from 'vue';
|
||||
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||
import { createTenant, editTenant, getTenantDetail, checkTenantCode } from '@/api/tenant';
|
||||
|
||||
const emit = defineEmits(['success']);
|
||||
const visible = ref(false);
|
||||
const loading = ref(false);
|
||||
const submitting = ref(false);
|
||||
const formRef = ref();
|
||||
|
||||
const initialData = {
|
||||
id: null,
|
||||
tenant_name: '',
|
||||
tenant_code: '',
|
||||
contact_person: '',
|
||||
contact_phone: '',
|
||||
contact_email: '',
|
||||
address: '',
|
||||
status: 1
|
||||
};
|
||||
|
||||
const formData = reactive({ ...initialData });
|
||||
|
||||
const rules = {
|
||||
tenant_name: [{ required: true, message: '请输入租户名称', trigger: 'blur' }],
|
||||
tenant_code: [{ required: true, message: '请输入租户编码', trigger: 'blur' }],
|
||||
contact_phone: [
|
||||
{ pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号', trigger: 'blur' }
|
||||
]
|
||||
};
|
||||
|
||||
// 暴露给父组件的方法
|
||||
const open = (id?: number) => {
|
||||
visible.value = true;
|
||||
Object.assign(formData, initialData);
|
||||
|
||||
if (id) {
|
||||
formData.id = id;
|
||||
fetchDetail(id);
|
||||
} else {
|
||||
formData.tenant_code = Math.floor(100000 + Math.random() * 900000).toString();
|
||||
}
|
||||
};
|
||||
|
||||
const fetchDetail = async (id: number) => {
|
||||
loading.value = true;
|
||||
try {
|
||||
const res = await getTenantDetail(id);
|
||||
if (res.code === 200) {
|
||||
Object.assign(formData, res.data);
|
||||
}
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const submitForm = async () => {
|
||||
if (!formRef.value) return;
|
||||
|
||||
// 1. 基础表单验证(必填项等)
|
||||
await formRef.value.validate();
|
||||
|
||||
submitting.value = true;
|
||||
|
||||
try {
|
||||
// 2. 如果是新增模式,进入“编码唯一性”校验环
|
||||
if (!formData.id) {
|
||||
let isCodeValid = false;
|
||||
|
||||
while (!isCodeValid) {
|
||||
const res = await checkTenantCode(formData.tenant_code);
|
||||
|
||||
if (res.code === 200) {
|
||||
// 编码可用,跳出循环
|
||||
isCodeValid = true;
|
||||
} else {
|
||||
// 编码重复,重新生成
|
||||
const newCode = Math.floor(100000 + Math.random() * 900000).toString();
|
||||
|
||||
// 弹出提示框告知用户
|
||||
await ElMessageBox.alert(
|
||||
`租户编码 [${formData.tenant_code}] 已重复,系统已自动为您重新生成为 [${newCode}],请重新点击提交。`,
|
||||
'编码重复提示',
|
||||
{ confirmButtonText: '我知道了', type: 'warning' }
|
||||
);
|
||||
|
||||
formData.tenant_code = newCode;
|
||||
submitting.value = false;
|
||||
return; // 中断本次提交,让用户看一眼新编码后再次点击
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 发起真正的保存请求
|
||||
const saveApi = formData.id ? editTenant(formData.id, formData) : createTenant(formData);
|
||||
const saveRes = await saveApi;
|
||||
|
||||
if (saveRes.code === 200) {
|
||||
ElMessage.success('保存成功');
|
||||
visible.value = false;
|
||||
emit('success');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('提交失败', error);
|
||||
} finally {
|
||||
submitting.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 生成 6 位随机数字并校验唯一性
|
||||
*/
|
||||
const generateUniqueCode = async () => {
|
||||
loading.value = true;
|
||||
let isUnique = false;
|
||||
let newCode = '';
|
||||
let retryCount = 0;
|
||||
const maxRetries = 10; // 保护措施:最多重试10次
|
||||
|
||||
while (!isUnique && retryCount < maxRetries) {
|
||||
// 1. 生成 6 位随机数字字符串
|
||||
newCode = Math.floor(100000 + Math.random() * 900000).toString();
|
||||
|
||||
try {
|
||||
// 2. 调用接口校验
|
||||
const res = await checkTenantCode(newCode);
|
||||
if (res.code === 200) {
|
||||
isUnique = true; // 接口返回 200 表示不存在,可用
|
||||
} else {
|
||||
console.warn(`编码 ${newCode} 重复,正在重试...`);
|
||||
retryCount++;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("校验编码失败", error);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isUnique) {
|
||||
formData.tenant_code = newCode;
|
||||
} else {
|
||||
ElMessage.error('无法生成唯一的租户编码,请重试');
|
||||
}
|
||||
loading.value = false;
|
||||
};
|
||||
|
||||
const handleClosed = () => {
|
||||
formRef.value?.resetFields();
|
||||
};
|
||||
|
||||
defineExpose({ open });
|
||||
</script>
|
||||
Reference in New Issue
Block a user