feat 搭建架构骨架

This commit is contained in:
Ironsp
2026-09-24 09:09:47 +08:00
parent dd9f6b77a4
commit 7a2efa3fea
180 changed files with 18967 additions and 9 deletions

View File

@@ -0,0 +1,197 @@
<script setup lang="ts">
import { ref, watch } from 'vue'
import { ElMessage } from 'element-plus'
import { AppButton, PasswordStrength, SmsCodeInput } from '@/components'
interface Props {
/** 绑定手机号(脱敏展示) */
phone: string
}
const props = defineProps<Props>()
const visible = defineModel<boolean>('visible', { default: false })
const emit = defineEmits<{
submit: [payload: { code: string; password: string; confirm: string }]
}>()
const code = ref('')
const password = ref('')
const confirm = ref('')
const agree = ref(false)
watch(visible, (open) => {
if (!open) return
code.value = ''
password.value = ''
confirm.value = ''
agree.value = false
})
function onGetCode(): void {
ElMessage.success('验证码已发送')
}
function onSubmit(): void {
if (!code.value) {
ElMessage.warning('请输入验证码')
return
}
if (!password.value) {
ElMessage.warning('请输入新密码')
return
}
if (!agree.value) {
ElMessage.warning('请先阅读并同意《用户协议》和《隐私政策》')
return
}
emit('submit', {
code: code.value,
password: password.value,
confirm: confirm.value,
})
}
</script>
<template>
<Teleport to="body">
<div v-if="visible" class="change-pwd-dialog" @click.self="visible = false">
<div class="change-pwd-dialog__panel">
<h3 class="change-pwd-dialog__title">
修改密码
</h3>
<div class="change-pwd-dialog__field">
<label class="change-pwd-dialog__label">手机号</label>
<input
class="change-pwd-dialog__input"
type="text"
:value="props.phone"
readonly
>
</div>
<div class="change-pwd-dialog__field">
<label class="change-pwd-dialog__label">验证码</label>
<SmsCodeInput v-model:code="code" @get-code="onGetCode" />
</div>
<div class="change-pwd-dialog__field">
<label class="change-pwd-dialog__label">设置密码</label>
<input
v-model="password"
class="change-pwd-dialog__input"
type="password"
placeholder="请输入密码(6-20位)"
maxlength="20"
>
<PasswordStrength :password="password" />
</div>
<div class="change-pwd-dialog__field">
<label class="change-pwd-dialog__label">确认密码</label>
<input
v-model="confirm"
class="change-pwd-dialog__input"
type="password"
placeholder="请再次输入密码"
maxlength="20"
@keyup.enter="onSubmit"
>
</div>
<label class="change-pwd-dialog__agree">
<input v-model="agree" type="checkbox">
<span>我已阅读并同意《用户协议》和《隐私政策》</span>
</label>
<div class="change-pwd-dialog__footer">
<AppButton type="default" @click="visible = false">
取消
</AppButton>
<AppButton type="primary" @click="onSubmit">
确认修改
</AppButton>
</div>
</div>
</div>
</Teleport>
</template>
<style lang="less" scoped>
.change-pwd-dialog {
position: fixed;
inset: 0;
z-index: 1000;
.flex(row, center);
background: rgba(0, 0, 0, 0.45);
&__panel {
width: 440px;
max-width: calc(100vw - 32px);
padding: @spacing-lg;
border-radius: @radius-lg;
background: @white;
box-shadow: @shadow-lg;
.flex(column, flex-start);
gap: @spacing-base;
}
&__title {
font-size: @font-size-lg;
font-weight: 600;
color: @heading-color;
}
&__field {
.flex(column, flex-start);
gap: @spacing-xs;
width: 100%;
}
&__label {
font-size: @font-size-base;
color: @heading-color;
}
&__input {
width: 100%;
height: 40px;
padding: 0 @spacing-base;
border: 1px solid @border-color;
border-radius: @radius-base;
background: @bg-color-light;
font-size: @font-size-base;
outline: none;
transition: border-color 0.2s;
&:focus {
border-color: @primary-color;
}
&:read-only {
color: @text-color-secondary;
cursor: not-allowed;
}
}
&__agree {
.flex(row, flex-start, center);
gap: @spacing-sm;
font-size: @font-size-sm;
color: @text-color;
cursor: pointer;
input {
accent-color: @primary-color;
}
}
&__footer {
.flex(row, flex-end);
gap: @spacing-sm;
width: 100%;
}
}
</style>