|
|
@@ -0,0 +1,258 @@
|
|
|
+<template>
|
|
|
+ <view class="form-page">
|
|
|
+ <!-- 可滚动内容区域 -->
|
|
|
+ <scroll-view class="form-scroll" scroll-y="true">
|
|
|
+ <view class="form-container">
|
|
|
+
|
|
|
+ <form-item label="密码" :required="formConfig.password.required" :error="formConfig.password.error">
|
|
|
+ <l-input
|
|
|
+ :type="showPassword ? 'text' : 'password'"
|
|
|
+ class="form-input"
|
|
|
+ v-model="formData.password"
|
|
|
+ placeholder="请输入密码"
|
|
|
+ :maxlength="100"
|
|
|
+ :bordered="false"
|
|
|
+ placeholderStyle="font-size: 14px;"
|
|
|
+ />
|
|
|
+ <image class="eye-icon" :src="showPassword ? '/static/images/login/4.png' : '/static/images/login/3.png'" mode="aspectFit" @click="handleTogglePassword"></image>
|
|
|
+ </form-item>
|
|
|
+ <form-item label="新密码" :required="formConfig.newPassword.required" :error="formConfig.newPassword.error">
|
|
|
+ <l-input
|
|
|
+ :type="showNewPassword ? 'text' : 'password'"
|
|
|
+ class="form-input"
|
|
|
+ v-model="formData.newPassword"
|
|
|
+ placeholder="请输入新密码"
|
|
|
+ :maxlength="100"
|
|
|
+ :bordered="false"
|
|
|
+ placeholderStyle="font-size: 14px;"
|
|
|
+ />
|
|
|
+ <image class="eye-icon" :src="showNewPassword ? '/static/images/login/4.png' : '/static/images/login/3.png'" mode="aspectFit" @click="handleToggleNewPassword"></image>
|
|
|
+ </form-item>
|
|
|
+ <form-item label="确认密码" :required="formConfig.confirmPassword.required" :error="formConfig.confirmPassword.error">
|
|
|
+ <l-input
|
|
|
+ :type="showConfirmPassword ? 'text' : 'password'"
|
|
|
+ class="form-input"
|
|
|
+ v-model="formData.confirmPassword"
|
|
|
+ placeholder="请输入密码"
|
|
|
+ :maxlength="100"
|
|
|
+ :bordered="false"
|
|
|
+ placeholderStyle="font-size: 14px;"
|
|
|
+ />
|
|
|
+ <image class="eye-icon" :src="showConfirmPassword ? '/static/images/login/4.png' : '/static/images/login/3.png'" mode="aspectFit" @click="handleToggleConfirmPassword"></image>
|
|
|
+ </form-item>
|
|
|
+
|
|
|
+ </view>
|
|
|
+ </scroll-view>
|
|
|
+
|
|
|
+ <!-- 固定底部按钮 -->
|
|
|
+ <view class="footer">
|
|
|
+ <button class="submit-btn" :disabled="submitting" @click="handleSubmit">
|
|
|
+ <text class="submit-btn-text">{{ submitting ? "提交中..." : "提交" }}</text>
|
|
|
+ </button>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup lang="uts">
|
|
|
+ import { ref } from 'vue'
|
|
|
+ import { updatePassword } from '../../../api/user/info'
|
|
|
+
|
|
|
+ const showPassword = ref<boolean>(false)
|
|
|
+ const showNewPassword = ref<boolean>(false)
|
|
|
+ const showConfirmPassword = ref<boolean>(false)
|
|
|
+
|
|
|
+ // 表单 label 宽度统一配置
|
|
|
+ const labelWidth = '140rpx'
|
|
|
+
|
|
|
+ // 切换密码显示/隐藏
|
|
|
+ const handleTogglePassword = (): void => {
|
|
|
+ showPassword.value = !showPassword.value
|
|
|
+ }
|
|
|
+
|
|
|
+ // 切换密码显示/隐藏
|
|
|
+ const handleToggleNewPassword = (): void => {
|
|
|
+ showNewPassword.value = !showNewPassword.value
|
|
|
+ }
|
|
|
+
|
|
|
+ // 切换密码显示/隐藏
|
|
|
+ const handleToggleConfirmPassword = (): void => {
|
|
|
+ showConfirmPassword.value = !showConfirmPassword.value
|
|
|
+ }
|
|
|
+
|
|
|
+ // 表单数据类型
|
|
|
+ type FormDataType = {
|
|
|
+ password: string
|
|
|
+ newPassword: string
|
|
|
+ confirmPassword: string
|
|
|
+ }
|
|
|
+
|
|
|
+ // 表单数据
|
|
|
+ const formData = ref<FormDataType>({
|
|
|
+ password: '',
|
|
|
+ newPassword: '',
|
|
|
+ confirmPassword: ''
|
|
|
+ })
|
|
|
+
|
|
|
+ const submitting = ref<boolean>(false)
|
|
|
+
|
|
|
+ // 表单字段配置类型
|
|
|
+ type FormFieldConfig = {
|
|
|
+ required: boolean
|
|
|
+ error: string
|
|
|
+ errorMsg: string
|
|
|
+ errorValid: string
|
|
|
+ }
|
|
|
+
|
|
|
+ // 表单字段配置
|
|
|
+ type FormFieldsConfig = {
|
|
|
+ password: FormFieldConfig
|
|
|
+ newPassword: FormFieldConfig
|
|
|
+ confirmPassword: FormFieldConfig
|
|
|
+ }
|
|
|
+
|
|
|
+ // 表单配置
|
|
|
+ const formConfig = ref<FormFieldsConfig>({
|
|
|
+ password: {
|
|
|
+ required: true,
|
|
|
+ error: '',
|
|
|
+ errorMsg: '请输入密码',
|
|
|
+ errorValid: ''
|
|
|
+ },
|
|
|
+ newPassword: {
|
|
|
+ required: true,
|
|
|
+ error: '',
|
|
|
+ errorMsg: '请输入新密码',
|
|
|
+ errorValid: "2次密码不一样"
|
|
|
+ },
|
|
|
+ confirmPassword: {
|
|
|
+ required: true,
|
|
|
+ error: '',
|
|
|
+ errorMsg: '请输入确认密码',
|
|
|
+ errorValid: ''
|
|
|
+
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ // 清空所有错误信息
|
|
|
+ const clearErrors = (): void => {
|
|
|
+ formConfig.value.password.error = ''
|
|
|
+ formConfig.value.newPassword.error = ''
|
|
|
+ formConfig.value.confirmPassword.error = ''
|
|
|
+ }
|
|
|
+
|
|
|
+ // 表单验证
|
|
|
+ const validateForm = (): boolean => {
|
|
|
+ // 清空之前的错误信息
|
|
|
+ clearErrors()
|
|
|
+
|
|
|
+ let isValid = true
|
|
|
+
|
|
|
+ if (formConfig.value.password.required && formData.value.password.length == 0) {
|
|
|
+ formConfig.value.password.error = formConfig.value.password.errorMsg
|
|
|
+ isValid = false
|
|
|
+ }
|
|
|
+
|
|
|
+ if (formConfig.value.newPassword.required && formData.value.newPassword.length == 0) {
|
|
|
+ formConfig.value.newPassword.error = formConfig.value.newPassword.errorMsg
|
|
|
+ isValid = false
|
|
|
+ }
|
|
|
+
|
|
|
+ if (formConfig.value.confirmPassword.required && formData.value.confirmPassword.length == 0) {
|
|
|
+ formConfig.value.confirmPassword.error = formConfig.value.confirmPassword.errorMsg
|
|
|
+ isValid = false
|
|
|
+ }
|
|
|
+
|
|
|
+ if (formData.value.confirmPassword != formData.value.newPassword) {
|
|
|
+ formConfig.value.newPassword.error = formConfig.value.newPassword.errorValid
|
|
|
+ isValid = false
|
|
|
+ }
|
|
|
+ return isValid
|
|
|
+ }
|
|
|
+
|
|
|
+ // 提交表单
|
|
|
+ const handleSubmit = async (): Promise<void> => {
|
|
|
+ if (!validateForm()) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ submitting.value = true
|
|
|
+
|
|
|
+ // 打印表单数据
|
|
|
+ console.log('表单数据:', formData.value)
|
|
|
+
|
|
|
+ // 模拟提交
|
|
|
+ await updatePassword(formData.value.password, formData.value.newPassword);
|
|
|
+
|
|
|
+ uni.showToast({
|
|
|
+ title: '提交成功',
|
|
|
+ icon: 'success'
|
|
|
+ })
|
|
|
+ setTimeout(() => {
|
|
|
+ uni.navigateBack()
|
|
|
+ }, 800)
|
|
|
+ } catch (e: any) {
|
|
|
+ uni.showToast({
|
|
|
+ title: e.message ?? '提交失败',
|
|
|
+ icon: 'none'
|
|
|
+ })
|
|
|
+ } finally {
|
|
|
+ submitting.value = false
|
|
|
+ }
|
|
|
+ }
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss">
|
|
|
+ @import "@/static/css/form.scss";
|
|
|
+
|
|
|
+ .form-page {
|
|
|
+ flex: 1;
|
|
|
+ background-color: #e8f0f9;
|
|
|
+ flex-direction: column;
|
|
|
+
|
|
|
+ .form-scroll {
|
|
|
+ flex: 1;
|
|
|
+ padding: 30rpx;
|
|
|
+ padding-bottom: 20rpx;
|
|
|
+
|
|
|
+ .form-container {
|
|
|
+ background-color: #ffffff;
|
|
|
+ border-radius: 16rpx;
|
|
|
+ padding: 30rpx;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .footer {
|
|
|
+ padding: 20rpx 30rpx;
|
|
|
+ padding-bottom: 40rpx;
|
|
|
+
|
|
|
+ .submit-btn {
|
|
|
+ width: 100%;
|
|
|
+ height: 88rpx;
|
|
|
+ background-color: #007aff;
|
|
|
+ border-radius: 12rpx;
|
|
|
+ color: #ffffff !important;
|
|
|
+
|
|
|
+ &:disabled {
|
|
|
+ background-color: #cccccc;
|
|
|
+ }
|
|
|
+
|
|
|
+ .submit-btn-text {
|
|
|
+ font-size: 32rpx;
|
|
|
+ color: #ffffff !important;
|
|
|
+ font-weight: bold;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .eye-icon {
|
|
|
+ position: absolute;
|
|
|
+ right: 30rpx;
|
|
|
+ top: 50%;
|
|
|
+ transform: translateY(-50%);
|
|
|
+ width: 40rpx;
|
|
|
+ height: 40rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+</style>
|