Files
erp_sb/electron-vue-template/src/renderer/components/auth/RegisterDialog.vue
悠山 02858146b3 style(components): format CSS styles in Vue components
- Remove extra spaces in CSS property declarations
- Consolidate multi-line CSS rules into single lines
- Maintain consistent formatting across component styles
- Improve readability by removing unnecessary line breaks
- Ensure uniform styling structure in scoped CSS blocks
2025-11-28 17:14:00 +08:00

194 lines
5.7 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script setup lang="ts">
import { ref, computed } from 'vue'
import { ElMessage } from 'element-plus'
import { User } from '@element-plus/icons-vue'
import { authApi } from '../../api/auth'
import { getOrCreateDeviceId } from '../../utils/deviceId'
interface Props {
modelValue: boolean
}
interface Emits {
(e: 'update:modelValue', value: boolean): void
(e: 'loginSuccess', data: { token: string; permissions?: string; expireTime?: string; accountType?: string; deviceTrialExpired?: boolean }): void
(e: 'backToLogin'): void
}
const props = defineProps<Props>()
const emit = defineEmits<Emits>()
const registerForm = ref({ username: '', password: '', confirmPassword: '' })
const registerLoading = ref(false)
const usernameCheckResult = ref<boolean | null>(null)
const visible = computed({
get: () => props.modelValue,
set: (value) => emit('update:modelValue', value)
})
const canRegister = computed(() => {
const { username, password, confirmPassword } = registerForm.value
return username &&
password.length >= 6 &&
password === confirmPassword &&
usernameCheckResult.value === true
})
function filterUsername(value: string) {
registerForm.value.username = value.replace(/[^a-zA-Z0-9_]/g, '')
}
async function checkUsernameAvailability() {
if (!registerForm.value.username) {
usernameCheckResult.value = null
return
}
try {
const res: any = await authApi.checkUsername(registerForm.value.username)
// 后端返回 {code: 200, data: true/false}data 直接是布尔值
usernameCheckResult.value = res.data
} catch {
usernameCheckResult.value = null
}
}
async function handleRegister() {
if (!canRegister.value) return
registerLoading.value = true
try {
// 获取设备ID
const deviceId = await getOrCreateDeviceId()
// 注册账号传递设备ID用于判断是否赠送VIP
const registerRes: any = await authApi.register({
username: registerForm.value.username,
password: registerForm.value.password,
deviceId: deviceId
})
// 显示注册成功提示
if (registerRes.data.deviceTrialExpired) {
ElMessage.warning('注册成功您获得了3天VIP体验但该设备试用期已过请更换设备或联系管理员续费')
} else {
ElMessage.success('注册成功您获得了3天VIP体验')
}
// 使用注册返回的token直接登录
emit('loginSuccess', {
token: registerRes.data.accessToken || registerRes.data.token,
permissions: registerRes.data.permissions,
expireTime: registerRes.data.expireTime,
accountType: registerRes.data.accountType,
deviceTrialExpired: registerRes.data.deviceTrialExpired || false
})
resetForm()
} catch (err) {
ElMessage.error((err as Error).message)
} finally {
registerLoading.value = false
}
}
function cancelRegister() {
visible.value = false
resetForm()
}
function resetForm() {
registerForm.value = { username: '', password: '', confirmPassword: '' }
usernameCheckResult.value = null
}
function backToLogin() {
emit('backToLogin')
resetForm()
}
</script>
<template>
<el-dialog
title=""
v-model="visible"
:close-on-click-modal="false"
width="380px"
center
class="auth-dialog">
<div style="padding: 20px 0;">
<div style="text-align: center; margin-bottom: 16px; color: #666;">
<img src="/icon/image.png" alt="logo" class="auth-logo" />
</div>
<div class="auth-title-wrap">
<h3 class="auth-title">创建账号</h3>
<p class="auth-subtitle">创建账号以获取完整服务体验</p>
</div>
<el-input
v-model="registerForm.username"
placeholder="请输入用户名(字母、数字、下划线)"
size="large"
style="margin-bottom: 15px;"
:disabled="registerLoading"
@input="filterUsername"
@blur="checkUsernameAvailability">
</el-input>
<div v-if="usernameCheckResult !== null" style="margin-bottom: 15px; text-align: left;">
<span v-if="usernameCheckResult" style="color: #67C23A; font-size: 12px;">
用户名可用
</span>
<span v-else style="color: #F56C6C; font-size: 12px;">
用户名已存在
</span>
</div>
<el-input
v-model="registerForm.password"
placeholder="请输入密码至少6位"
type="password"
size="large"
style="margin-bottom: 15px;"
:disabled="registerLoading"
show-password>
</el-input>
<el-input
v-model="registerForm.confirmPassword"
placeholder="请再次输入密码"
type="password"
size="large"
style="margin-bottom: 20px;"
:disabled="registerLoading"
show-password>
</el-input>
<div>
<el-button
type="primary"
size="large"
:loading="registerLoading"
:disabled="!canRegister || registerLoading"
@click="handleRegister"
style="width: 100%;">
注册
</el-button>
</div>
<div style="margin-top: 20px; text-align: center;">
<el-button type="text" @click="backToLogin" :disabled="registerLoading">
已有账号返回登录
</el-button>
</div>
</div>
</el-dialog>
</template>
<style scoped>
.auth-logo {width: 160px; height: auto;}
.auth-dialog {--el-color-primary: #1677FF;}
.auth-dialog :deep(.el-button--primary) {background-color: #1677FF; border-color: #1677FF;}
.auth-title-wrap {margin-bottom: 12px;}
.auth-title {margin: 0; font-size: 18px; font-weight: 700; color: #1f1f1f; text-align: left;}
.auth-subtitle {margin: 6px 0 0; font-size: 12px; color: #8c8c8c; text-align: left;}
</style>