diff --git a/src/manifest.json b/src/manifest.json index e38f0ec..eed4e79 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -48,9 +48,7 @@ "ignoreDevUnusedFiles": false, "ignoreUploadUnusedFiles": false }, - "usingComponents": true, - "darkMode": true, - "themeLocation": "theme.json" + "usingComponents": true }, "mp-alipay": { "usingComponents": true @@ -65,8 +63,5 @@ "enable": false }, "vueVersion": "3", - "h5": { - "darkmode": true, - "themeLocation": "theme.json" - } + "h5": {} } diff --git a/src/pages.json b/src/pages.json index fe3a4fc..01690ee 100644 --- a/src/pages.json +++ b/src/pages.json @@ -7,13 +7,10 @@ "backgroundTextStyle": "@bgTxtStyle", "backgroundColorTop": "@bgColorTop", "backgroundColorBottom": "@bgColorBottom", - "enablePullDownRefresh": false, - "onReachBottomDistance": 50, - "animationType": "pop-in", - "animationDuration": 300 + "enablePullDownRefresh": false }, "pages": [ - // GENERATED BY UNI-PAGES, PLATFORM: H5 + // GENERATED BY UNI-PAGES, PLATFORM: H5 || MP-WEIXIN { "path": "pages/index/index", "type": "home", @@ -215,15 +212,13 @@ "subPackages": [], "tabBar": { "custom": true, - "customize": true, - "overlay": true, "height": "0", "color": "@tabColor", "selectedColor": "@tabSelectedColor", "backgroundColor": "@tabBgColor", "borderStyle": "@tabBorderStyle", "list": [ - // GENERATED BY UNI-PAGES, PLATFORM: H5 + // GENERATED BY UNI-PAGES, PLATFORM: H5 || MP-WEIXIN { "pagePath": "pages/index/index" }, diff --git a/src/pages/login/index.vue b/src/pages/login/index.vue index 5896059..1ecde95 100644 --- a/src/pages/login/index.vue +++ b/src/pages/login/index.vue @@ -34,69 +34,84 @@ - + - + + + - + + + - + + + - + @@ -250,6 +265,7 @@ definePage({ import { onLoad, onShow } from "@dcloudio/uni-app"; import { useToast, useDialog } from "@wot-ui/ui"; +import type { FormSchema } from "@wot-ui/ui/components/wd-form/types"; import { useUserStore } from "@/store/modules/user"; import { useCountdown } from "@/composables/useCountdown"; @@ -258,6 +274,7 @@ import AuthAPI from "@/api/auth"; const toast = useToast(); const dialog = useDialog("policy-box"); const userStore = useUserStore(); +const loginFormRef = ref(); // 导航栏尺寸 const statusBarHeight = ref(20); @@ -309,15 +326,33 @@ const loginModeDesc = computed(() => { const isValidMobile = (mobile: string) => /^1\d{10}$/.test((mobile || "").trim()); -const canSubmit = computed(() => { - if (loginMode.value === "PASSWORD") { - return (formData.value.username || "").trim() && (formData.value.password || "").trim(); - } - if (loginMode.value === "SMS") { - return isValidMobile(formData.value.username) && (formData.value.code || "").trim(); - } - return false; -}); +// 表单校验规则 +const formSchema = computed(() => ({ + validate(model) { + const issues: { path: string[]; message: string }[] = []; + if (loginMode.value === "PASSWORD") { + if (!(model.username || "").trim()) { + issues.push({ path: ["username"], message: "请输入用户名" }); + } + if (!(model.password || "").trim()) { + issues.push({ path: ["password"], message: "请输入密码" }); + } + if (!(model.captchaCode || "").trim()) { + issues.push({ path: ["captchaCode"], message: "请输入验证码" }); + } + } else if (loginMode.value === "SMS") { + if (!(model.username || "").trim()) { + issues.push({ path: ["username"], message: "请输入手机号" }); + } else if (!isValidMobile(model.username)) { + issues.push({ path: ["username"], message: "请输入正确的手机号" }); + } + if (!(model.code || "").trim()) { + issues.push({ path: ["code"], message: "请输入验证码" }); + } + } + return issues; + }, +})); // 图形验证码 const fetchCaptcha = async () => { @@ -378,7 +413,6 @@ const openPolicyDialog = (action: "FORM" | "WECHAT_PHONE", phoneCode = "") => { // 表单登录 async function doFormLogin() { - if (isLoading.value) return; if (isLoading.value) return; isLoading.value = true; try { @@ -407,13 +441,9 @@ async function doFormLogin() { } const handleLogin = async () => { - // 先校验表单必填项 - if (!canSubmit.value) { - toast.error( - loginMode.value === "PASSWORD" ? "请输入用户名和密码" : "请输入正确的手机号和验证码" - ); - return; - } + // 先校验表单必填项(内联提示,不再弹窗) + const { valid } = await loginFormRef.value?.validate(); + if (!valid) return; // 再校验隐私协议 if (!isAgreePolicy.value) { openPolicyDialog("FORM"); @@ -748,6 +778,40 @@ onShow(() => uni.setNavigationBarTitle({ title: "" })); } } +// 覆盖 wd-form-item 默认样式,仅用于校验和错误提示 +:deep(.wd-form-item) { + padding: 0 !important; + margin-top: 32rpx; + background: transparent; + + &:first-child { + margin-top: 0; + } +} + +// 垂直布局下隐藏左侧区域(无标题时) +:deep(.wd-form-item .wd-cell__left) { + display: none; +} + +:deep(.wd-form-item .wd-cell__wrapper) { + flex-direction: column; +} + +:deep(.wd-form-item .wd-cell__right) { + width: 100%; +} + +// 错误提示:独占一行,显示在输入框下方 +:deep(.wd-form-item__error-message) { + display: block !important; + width: 100% !important; + padding: 8rpx 0 0 !important; + font-size: 24rpx !important; + line-height: 1.5 !important; + color: var(--color-danger) !important; +} + // 输入框行 .login__field { display: flex;