fix(im/registrationInvite): add input verification for bound user search
1. add computed state to check if bind user input is unverified 2. disable confirm button and show warning tip when input is unverified 3. track last searched keyword to validate user input 4. add submission guard to prevent unvalidated submissions
This commit is contained in:
@@ -20,6 +20,7 @@
|
|||||||
<span class="bound-user-name">{{ boundUser.nickname || boundUser.username || boundUser.phone || '--' }}({{ boundUser.userId }})</span>
|
<span class="bound-user-name">{{ boundUser.nickname || boundUser.username || boundUser.phone || '--' }}({{ boundUser.userId }})</span>
|
||||||
<n-button text type="error" @click="clearBoundUser">清除</n-button>
|
<n-button text type="error" @click="clearBoundUser">清除</n-button>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-if="bindInputUnverified" class="bind-user-tip">输入的用户ID未验证,请先点击搜索</div>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item label="到期时间" path="expiresAt">
|
<n-form-item label="到期时间" path="expiresAt">
|
||||||
<n-date-picker v-model:value="formValue.expiresAt" type="datetime" clearable />
|
<n-date-picker v-model:value="formValue.expiresAt" type="datetime" clearable />
|
||||||
@@ -31,14 +32,14 @@
|
|||||||
<template #action>
|
<template #action>
|
||||||
<n-space justify="end">
|
<n-space justify="end">
|
||||||
<n-button @click="closeModal">取消</n-button>
|
<n-button @click="closeModal">取消</n-button>
|
||||||
<n-button type="primary" :loading="loading" @click="submit">确认</n-button>
|
<n-button type="primary" :loading="loading" :disabled="bindInputUnverified" @click="submit">确认</n-button>
|
||||||
</n-space>
|
</n-space>
|
||||||
</template>
|
</template>
|
||||||
</n-modal>
|
</n-modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { reactive, ref } from 'vue';
|
import { computed, reactive, ref } from 'vue';
|
||||||
import { useMessage } from 'naive-ui';
|
import { useMessage } from 'naive-ui';
|
||||||
import { BatchCreate, Create } from '@/api/im/registrationInvite';
|
import { BatchCreate, Create } from '@/api/im/registrationInvite';
|
||||||
import { List as UserList } from '@/api/imUser';
|
import { List as UserList } from '@/api/imUser';
|
||||||
@@ -55,6 +56,12 @@
|
|||||||
const bindUserInput = ref('');
|
const bindUserInput = ref('');
|
||||||
const searching = ref(false);
|
const searching = ref(false);
|
||||||
const boundUser = ref<any>(null);
|
const boundUser = ref<any>(null);
|
||||||
|
// 最近一次已通过搜索验证的输入值;输入框有值但不等于它时视为未验证
|
||||||
|
const lastSearchedKeyword = ref('');
|
||||||
|
const bindInputUnverified = computed(() => {
|
||||||
|
const input = bindUserInput.value.trim();
|
||||||
|
return !!input && input !== lastSearchedKeyword.value;
|
||||||
|
});
|
||||||
const formValue = reactive({
|
const formValue = reactive({
|
||||||
quantity: 100,
|
quantity: 100,
|
||||||
expiresAt: Date.now() + 7 * 24 * 3600 * 1000,
|
expiresAt: Date.now() + 7 * 24 * 3600 * 1000,
|
||||||
@@ -78,6 +85,7 @@
|
|||||||
formValue.boundUserId = '';
|
formValue.boundUserId = '';
|
||||||
bindUserInput.value = '';
|
bindUserInput.value = '';
|
||||||
boundUser.value = null;
|
boundUser.value = null;
|
||||||
|
lastSearchedKeyword.value = '';
|
||||||
showModal.value = true;
|
showModal.value = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,6 +108,8 @@
|
|||||||
page: 1,
|
page: 1,
|
||||||
perPage: 1,
|
perPage: 1,
|
||||||
});
|
});
|
||||||
|
// 搜索成功返回即视为已验证(无论是否找到用户)
|
||||||
|
lastSearchedKeyword.value = keyword;
|
||||||
const user = res?.list?.[0];
|
const user = res?.list?.[0];
|
||||||
if (!user) {
|
if (!user) {
|
||||||
message.warning('未找到该用户,将不绑定用户');
|
message.warning('未找到该用户,将不绑定用户');
|
||||||
@@ -124,10 +134,16 @@
|
|||||||
boundUser.value = null;
|
boundUser.value = null;
|
||||||
formValue.boundUserId = '';
|
formValue.boundUserId = '';
|
||||||
bindUserInput.value = '';
|
bindUserInput.value = '';
|
||||||
|
lastSearchedKeyword.value = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
async function submit() {
|
async function submit() {
|
||||||
await formRef.value?.validate();
|
await formRef.value?.validate();
|
||||||
|
// 输入了用户ID但未点击搜索验证时,禁止提交,兜底拦截
|
||||||
|
if (bindInputUnverified.value) {
|
||||||
|
message.warning('请先点击搜索验证输入的用户ID');
|
||||||
|
return;
|
||||||
|
}
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
try {
|
try {
|
||||||
const params: any = {
|
const params: any = {
|
||||||
@@ -174,5 +190,12 @@
|
|||||||
.bound-user-name {
|
.bound-user-name {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.bind-user-tip {
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 4px;
|
||||||
|
color: #f0a020;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user