feat(web): 申请页改用中文姓名,前端转拼音提交
- ApplyView 的'姓名'字段(2~10 个汉字)替代自定义用户名
- 前端经 pinyin-pro(toneType:none + surname:head 处理姓氏多音字)转拼音作为用户名
- 提交前兜底校验拼音用户名长度(后端规则 [a-z][a-z0-9]{1,31})
- alert 文案改为实时预览 '通过后自动创建账号 ext_<username>'
- 新增依赖 pinyin-pro@3.29.3
This commit is contained in:
Generated
+7
@@ -12,6 +12,7 @@
|
||||
"axios": "^1.7.9",
|
||||
"element-plus": "^2.9.3",
|
||||
"pinia": "^2.3.1",
|
||||
"pinyin-pro": "^3.29.3",
|
||||
"vue": "^3.5.13",
|
||||
"vue-router": "^4.5.0"
|
||||
},
|
||||
@@ -1830,6 +1831,12 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/pinyin-pro": {
|
||||
"version": "3.29.3",
|
||||
"resolved": "https://registry.npmjs.org/pinyin-pro/-/pinyin-pro-3.29.3.tgz",
|
||||
"integrity": "sha512-+UU9bx6vfDw8amOJGHm0TE0rdQl8VPylsDWviQ5OOQ3e+on1xRP4OqDbiDuMT5OISgvfl/Y6ez1BBRaIP80GLQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/postcss": {
|
||||
"version": "8.5.26",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.26.tgz",
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
"axios": "^1.7.9",
|
||||
"element-plus": "^2.9.3",
|
||||
"pinia": "^2.3.1",
|
||||
"pinyin-pro": "^3.29.3",
|
||||
"vue": "^3.5.13",
|
||||
"vue-router": "^4.5.0"
|
||||
},
|
||||
|
||||
+36
-15
@@ -1,26 +1,24 @@
|
||||
<script setup lang="ts">
|
||||
import { reactive, ref } from 'vue'
|
||||
import { computed, reactive, ref } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { pinyin } from 'pinyin-pro'
|
||||
import * as api from '@/api'
|
||||
|
||||
const router = useRouter()
|
||||
const submitting = ref(false)
|
||||
const form = reactive({
|
||||
username: '',
|
||||
realName: '', // 中文姓名,提交时转换为拼音作为用户名
|
||||
email: '',
|
||||
supervisor: '',
|
||||
purpose: '',
|
||||
})
|
||||
|
||||
// 前端校验:中文姓名、邮箱、挂靠老师、用途均在前端完成
|
||||
const rules = {
|
||||
username: [
|
||||
{ required: true, message: '请输入用户名', trigger: 'blur' },
|
||||
{
|
||||
pattern: /^[a-z][a-z0-9_]{1,30}$/,
|
||||
message: '小写字母开头,仅小写字母/数字/下划线,2~31 位',
|
||||
trigger: 'blur',
|
||||
},
|
||||
realName: [
|
||||
{ required: true, message: '请输入中文姓名', trigger: 'blur' },
|
||||
{ pattern: /^[\u4e00-\u9fa5]{2,10}$/, message: '请输入 2~10 个汉字', trigger: 'blur' },
|
||||
],
|
||||
email: [
|
||||
{ required: true, message: '请输入邮箱', trigger: 'blur' },
|
||||
@@ -32,21 +30,44 @@ const rules = {
|
||||
|
||||
const formRef = ref()
|
||||
|
||||
// 姓名 → 拼音(小写、无空格;首字按姓氏读音处理多音字)
|
||||
function nameToPinyin(name: string): string {
|
||||
const parts = pinyin(name, { toneType: 'none', type: 'array', surname: 'head' })
|
||||
return parts.join('')
|
||||
}
|
||||
|
||||
// 实时预览将创建的账号名;姓名非法或未输入时返回空
|
||||
const accountPreview = computed(() => {
|
||||
const n = form.realName.trim()
|
||||
if (!/^[\u4e00-\u9fa5]{2,10}$/.test(n)) return ''
|
||||
return `ext_${nameToPinyin(n)}`
|
||||
})
|
||||
|
||||
// 提交前的前端校验(姓名→拼音合法性兜底,防止姓名过长)
|
||||
function validUsername(uname: string): boolean {
|
||||
return /^[a-z][a-z0-9]{1,31}$/.test(uname)
|
||||
}
|
||||
|
||||
async function onSubmit() {
|
||||
const valid = await formRef.value?.validate().catch(() => false)
|
||||
if (!valid) return
|
||||
const uname = nameToPinyin(form.realName.trim())
|
||||
if (!validUsername(uname)) {
|
||||
ElMessage.warning('姓名拼音过长,无法生成可用账号,请联系管理员')
|
||||
return
|
||||
}
|
||||
submitting.value = true
|
||||
try {
|
||||
await api.submitApproval({
|
||||
username: form.username.trim(),
|
||||
username: uname,
|
||||
email: form.email.trim(),
|
||||
supervisor: form.supervisor.trim(),
|
||||
purpose: form.purpose.trim(),
|
||||
})
|
||||
ElMessage.success('申请已提交,等待管理员审批(结果将邮件通知)')
|
||||
Object.assign(form, { username: '', email: '', supervisor: '', purpose: '' })
|
||||
Object.assign(form, { realName: '', email: '', supervisor: '', purpose: '' })
|
||||
} catch {
|
||||
// 拦截器已提示(如用户名已被占用)
|
||||
// 拦截器已提示(如拼音与已有申请重名)
|
||||
} finally {
|
||||
submitting.value = false
|
||||
}
|
||||
@@ -65,14 +86,14 @@ async function onSubmit() {
|
||||
</div>
|
||||
|
||||
<el-alert type="info" :closable="false" show-icon class="apply-tip">
|
||||
通过后自动创建账号(用户名将带 <code>ext_</code> 前缀)。
|
||||
通过后自动创建账号 {{ accountPreview || 'ext_<username>' }}
|
||||
</el-alert>
|
||||
|
||||
<el-divider />
|
||||
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="90px" @submit.prevent="onSubmit">
|
||||
<el-form-item label="用户名" prop="username">
|
||||
<el-input v-model="form.username" placeholder="如 zhangsan(自动成为 ext_zhangsan)" maxlength="31" />
|
||||
<el-form-item label="姓名" prop="realName">
|
||||
<el-input v-model="form.realName" placeholder="输入中文姓名,如 张三" maxlength="10" />
|
||||
</el-form-item>
|
||||
<el-form-item label="邮箱" prop="email">
|
||||
<el-input v-model="form.email" placeholder="接收通知与 OTP 验证码" />
|
||||
|
||||
Reference in New Issue
Block a user