mirror of
https://github.com/fastapiadmin/FastapiAdmin.git
synced 2026-10-16 22:51:14 +00:00
refactor(frontend): 统一使用wd-text组件替换原生text标签,优化页面配置
1. 全局替换普通text标签为wd-text组件,统一文本样式与功能 2. 调整页面全局配置与tabBar配置,按平台动态裁剪无效配置 3. 修复微信小程序端表单item样式兼容问题,添加自定义样式隐藏空left区域 4. 移除登录页冗余的微信一键登录相关代码
This commit is contained in:
@@ -330,6 +330,7 @@ function getGreeting() {
|
||||
:interval="4500"
|
||||
:autoplay="true"
|
||||
:loop="true"
|
||||
:adjust-height="false"
|
||||
>
|
||||
<template #default="{ index }">
|
||||
<view class="banner-slide" :class="banners[index].cls" @click="banners[index].onClick">
|
||||
@@ -398,9 +399,7 @@ function getGreeting() {
|
||||
<!-- 运营概览 -->
|
||||
<view class="mb-2 mt-4 flex items-center gap-2 px-3">
|
||||
<view class="h-3.5 w-1 rounded-full" style="background-color: var(--primary-color, #4F8CFF);" />
|
||||
<text class="text-3.5 font-bold wot-text-text-main">
|
||||
{{ t('index.opsOverview') }}
|
||||
</text>
|
||||
<wd-text class="text-3.5 wot-text-text-main" :text="t('index.opsOverview')" bold />
|
||||
</view>
|
||||
<SkeletonPage v-if="loading && !dashboardStats" :rows="3" />
|
||||
<view v-else class="mx-3">
|
||||
@@ -454,17 +453,13 @@ function getGreeting() {
|
||||
<view id="monitor-section" class="mt-4">
|
||||
<view class="mb-2 flex items-center gap-2 px-3">
|
||||
<view class="h-3.5 w-1 rounded-full" style="background-color: var(--danger-color, #EF4444);" />
|
||||
<text class="text-3.5 font-bold wot-text-text-main">
|
||||
{{ t('index.sysMonitor') }}
|
||||
</text>
|
||||
<wd-text class="text-3.5 wot-text-text-main" :text="t('index.sysMonitor')" bold />
|
||||
</view>
|
||||
|
||||
<!-- 登录趋势折线图 -->
|
||||
<view class="mx-3 mb-3 rounded-2 p-4 wot-bg-filled-oppo">
|
||||
<view class="mb-4 flex items-center gap-2">
|
||||
<text class="text-3.5 font-bold wot-text-text-main">
|
||||
{{ t('index.loginTrend') }}
|
||||
</text>
|
||||
<wd-text class="text-3.5 wot-text-text-main" :text="t('index.loginTrend')" bold />
|
||||
</view>
|
||||
<uni-echarts custom-class="h-52 w-full" :option="loginTrendOption" />
|
||||
</view>
|
||||
@@ -474,13 +469,9 @@ function getGreeting() {
|
||||
<view v-if="recentNotices.length > 0" class="mb-2 mt-4 flex items-center justify-between px-3">
|
||||
<view class="flex items-center gap-2">
|
||||
<view class="h-3.5 w-1 rounded-full" style="background-color: var(--success-color, #10B981);" />
|
||||
<text class="text-3.5 font-bold wot-text-text-main">
|
||||
{{ t('index.latestNotice') }}
|
||||
</text>
|
||||
<wd-text class="text-3.5 wot-text-text-main" :text="t('index.latestNotice')" bold />
|
||||
</view>
|
||||
<text class="text-3 wot-text-primary" @click="navigateTo('work-notices')">
|
||||
{{ t('common.all') }}
|
||||
</text>
|
||||
<wd-text class="text-3" :text="t('common.all')" type="primary" @click="navigateTo('work-notices')" />
|
||||
</view>
|
||||
<view v-if="recentNotices.length > 0" class="mx-3">
|
||||
<wd-cell-group border custom-class="rounded-2! overflow-hidden">
|
||||
@@ -492,9 +483,7 @@ function getGreeting() {
|
||||
@click="navigateTo('work-notices')"
|
||||
>
|
||||
<template #label>
|
||||
<text class="text-2.5 wot-text-text-auxiliary">
|
||||
{{ item.created_time || '' }}
|
||||
</text>
|
||||
<wd-text class="text-2.5 wot-text-text-auxiliary" :text="item.created_time || ''" />
|
||||
</template>
|
||||
</wd-cell>
|
||||
</wd-cell-group>
|
||||
|
||||
@@ -85,7 +85,7 @@ function goLogin() {
|
||||
|
||||
<view class="forget-form">
|
||||
<wd-form ref="forgetFormRef" :model="forgetForm" :schema="forgetSchema">
|
||||
<wd-form-item prop="username">
|
||||
<wd-form-item prop="username" custom-style="margin-bottom: 14rpx; padding-left: 0; padding-right: 0;">
|
||||
<wd-input
|
||||
v-model="forgetForm.username"
|
||||
:placeholder="t('common.form.usernamePlaceholder')"
|
||||
@@ -94,7 +94,7 @@ function goLogin() {
|
||||
prefix-icon="user"
|
||||
/>
|
||||
</wd-form-item>
|
||||
<wd-form-item prop="new_password">
|
||||
<wd-form-item prop="new_password" custom-style="margin-bottom: 14rpx; padding-left: 0; padding-right: 0;">
|
||||
<wd-input
|
||||
v-model="forgetForm.new_password"
|
||||
:placeholder="t('common.form.newPasswordPlaceholder')"
|
||||
@@ -104,7 +104,7 @@ function goLogin() {
|
||||
prefix-icon="lock"
|
||||
/>
|
||||
</wd-form-item>
|
||||
<wd-form-item prop="confirmPassword">
|
||||
<wd-form-item prop="confirmPassword" custom-style="margin-bottom: 14rpx; padding-left: 0; padding-right: 0;">
|
||||
<wd-input
|
||||
v-model="forgetForm.confirmPassword"
|
||||
:placeholder="t('common.form.confirmNewPlaceholder')"
|
||||
@@ -121,9 +121,7 @@ function goLogin() {
|
||||
</view>
|
||||
|
||||
<view class="forget-footer">
|
||||
<text class="forget-footer__link wot-text-primary" @click="goLogin">
|
||||
{{ t('forget.toLogin') }}
|
||||
</text>
|
||||
<wd-text class="forget-footer__link" :text="t('forget.toLogin')" type="primary" @click="goLogin" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -215,3 +213,12 @@ function goLogin() {
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss">
|
||||
/* MP 端兼容:wd-form-item 内部 wd-cell 因 uni-app 插槽静态声明(u-s)误判 label/title 插槽被使用,
|
||||
showLeft=true 渲染空 left 区域(flex:1 占半宽),H5 端运行时插槽判定无此问题。
|
||||
本页 form-item 无 title/label/prefix 内容,隐藏 left 安全,保证输入框与登录按钮同宽 */
|
||||
.forget-card .wd-form-item .wd-cell__left {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -7,7 +7,6 @@ import { computed, nextTick, reactive, ref, watch } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import AuthAPI from '@/api/module_system/auth'
|
||||
import { useI18nNavTitle } from '@/composables/useI18nNavTitle'
|
||||
import { useWxLogin } from '@/composables/useWxLogin'
|
||||
import { REMEMBER_ME_KEY } from '@/constants'
|
||||
import { useConfigStore } from '@/store/configStore'
|
||||
import { useUserStore } from '@/store/userStore'
|
||||
@@ -22,7 +21,6 @@ const sliderCaptchaRef = ref<SlideVerifyInstance>()
|
||||
const loading = ref(false)
|
||||
const userStore = useUserStore()
|
||||
const configStore = useConfigStore()
|
||||
const { wxLogin, wxPhoneLogin } = useWxLogin()
|
||||
const redirect = ref('/pages/index/index')
|
||||
|
||||
/** 规范化 BASE_URL(保证以 / 结尾),用于拼接静态资源路径:H5 下避免 base '/app' 拼出 /appstatic/xxx */
|
||||
@@ -241,43 +239,6 @@ async function handleOAuth(provider: OAuthProvider) {
|
||||
uni.showToast({ title: t('login.oauthFailed'), icon: 'none' })
|
||||
}
|
||||
}
|
||||
|
||||
/** 微信一键登录(仅小程序端显示按钮) */
|
||||
const wxLoading = ref(false)
|
||||
async function handleWxLogin() {
|
||||
if (wxLoading.value)
|
||||
return
|
||||
wxLoading.value = true
|
||||
try {
|
||||
await wxLogin()
|
||||
uni.reLaunch({ url: redirect.value })
|
||||
}
|
||||
catch {
|
||||
uni.showToast({ title: t('login.wxLoginFailed'), icon: 'none' })
|
||||
}
|
||||
finally {
|
||||
wxLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 微信手机号登录(配合 open-type="getPhoneNumber") */
|
||||
async function handleWxPhoneLogin(e: any) {
|
||||
if (e.detail.errMsg !== 'getPhoneNumber:ok') {
|
||||
uni.showToast({ title: t('login.phoneAuthCancel'), icon: 'none' })
|
||||
return
|
||||
}
|
||||
wxLoading.value = true
|
||||
try {
|
||||
await wxPhoneLogin(e.detail.code)
|
||||
uni.reLaunch({ url: redirect.value })
|
||||
}
|
||||
catch {
|
||||
uni.showToast({ title: t('login.phoneLoginFailed'), icon: 'none' })
|
||||
}
|
||||
finally {
|
||||
wxLoading.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -288,9 +249,7 @@ async function handleWxPhoneLogin(e: any) {
|
||||
<text class="brand-title">
|
||||
{{ brandTitle }}
|
||||
</text>
|
||||
<text class="brand-subtitle">
|
||||
{{ brandSubtitle }}
|
||||
</text>
|
||||
<wd-text class="brand-subtitle" :text="brandSubtitle" />
|
||||
</view>
|
||||
|
||||
<!-- Form card -->
|
||||
@@ -299,39 +258,9 @@ async function handleWxPhoneLogin(e: any) {
|
||||
{{ t('login.cardTitle') }}
|
||||
</text>
|
||||
|
||||
<!-- 微信一键登录(仅小程序端显示) -->
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<view class="wx-login-section">
|
||||
<wd-button
|
||||
type="primary"
|
||||
:loading="wxLoading"
|
||||
round
|
||||
block
|
||||
@click="handleWxLogin"
|
||||
>
|
||||
<wd-icon name="wechat" size="18px" color="#FFFFFF" />
|
||||
<text class="ml-1">
|
||||
{{ t('login.wxLogin') }}
|
||||
</text>
|
||||
</wd-button>
|
||||
<wd-button
|
||||
plain
|
||||
round
|
||||
block
|
||||
custom-class="mt-3"
|
||||
:loading="wxLoading"
|
||||
open-type="getPhoneNumber"
|
||||
@getphonenumber="handleWxPhoneLogin"
|
||||
>
|
||||
{{ t('login.phoneLogin') }}
|
||||
</wd-button>
|
||||
</view>
|
||||
<wd-divider>{{ t('login.orAccount') }}</wd-divider>
|
||||
<!-- #endif -->
|
||||
|
||||
<wd-form ref="loginFormRef" :model="loginFormData" :schema="loginSchema">
|
||||
<!-- Username — wot 原生 wd-input,前缀图标走 prefix-icon 属性 -->
|
||||
<wd-form-item prop="username">
|
||||
<wd-form-item prop="username" custom-style="margin-bottom: 14rpx; padding-left: 0; padding-right: 0;">
|
||||
<wd-input
|
||||
v-model="loginFormData.username"
|
||||
:placeholder="t('common.form.usernamePlaceholder')"
|
||||
@@ -344,7 +273,7 @@ async function handleWxPhoneLogin(e: any) {
|
||||
</wd-form-item>
|
||||
|
||||
<!-- Password — show-password 自动启用密码可见性切换 -->
|
||||
<wd-form-item prop="password">
|
||||
<wd-form-item prop="password" custom-style="margin-bottom: 14rpx; padding-left: 0; padding-right: 0;">
|
||||
<wd-input
|
||||
v-model="loginFormData.password"
|
||||
:placeholder="t('common.form.passwordPlaceholder')"
|
||||
@@ -358,7 +287,7 @@ async function handleWxPhoneLogin(e: any) {
|
||||
</wd-form-item>
|
||||
|
||||
<!-- Slider Captcha — wd-slide-verify 滑块拖动验证(条件显示) -->
|
||||
<wd-form-item v-if="captchaState.enable">
|
||||
<wd-form-item v-if="captchaState.enable" custom-style="margin-bottom: 14rpx; padding-left: 0; padding-right: 0;">
|
||||
<wd-slide-verify
|
||||
ref="sliderCaptchaRef"
|
||||
:text="t('login.sliderText')"
|
||||
@@ -373,9 +302,7 @@ async function handleWxPhoneLogin(e: any) {
|
||||
<wd-checkbox v-model="loginFormData.remember" size="18px">
|
||||
{{ t('login.remember') }}
|
||||
</wd-checkbox>
|
||||
<text class="forgot-link wot-text-primary" @click="goForget">
|
||||
{{ t('login.forgot') }}
|
||||
</text>
|
||||
<wd-text class="forgot-link" :text="t('login.forgot')" type="primary" @click="goForget" />
|
||||
</view>
|
||||
|
||||
<!-- Submit -->
|
||||
@@ -400,9 +327,7 @@ async function handleWxPhoneLogin(e: any) {
|
||||
<view class="oauth-btn__icon" style="background: #07C160">
|
||||
<image class="oauth-btn__iconify" src="/static/icons/wechat.svg" />
|
||||
</view>
|
||||
<text class="oauth-btn__label">
|
||||
{{ t('login.wechat') }}
|
||||
</text>
|
||||
<wd-text class="oauth-btn__label" :text="t('login.wechat')" />
|
||||
</wd-grid-item>
|
||||
|
||||
<!-- GitHub -->
|
||||
@@ -410,9 +335,7 @@ async function handleWxPhoneLogin(e: any) {
|
||||
<view class="oauth-btn__icon" style="background: #24292F">
|
||||
<image class="oauth-btn__iconify" src="/static/icons/github.svg" />
|
||||
</view>
|
||||
<text class="oauth-btn__label">
|
||||
{{ t('login.github') }}
|
||||
</text>
|
||||
<wd-text class="oauth-btn__label" :text="t('login.github')" />
|
||||
</wd-grid-item>
|
||||
|
||||
<!-- Gitee -->
|
||||
@@ -420,9 +343,7 @@ async function handleWxPhoneLogin(e: any) {
|
||||
<view class="oauth-btn__icon" style="background: #C71D23">
|
||||
<image class="oauth-btn__iconify" src="/static/icons/gitee.svg" />
|
||||
</view>
|
||||
<text class="oauth-btn__label">
|
||||
{{ t('login.gitee') }}
|
||||
</text>
|
||||
<wd-text class="oauth-btn__label" :text="t('login.gitee')" />
|
||||
</wd-grid-item>
|
||||
|
||||
<!-- QQ -->
|
||||
@@ -430,21 +351,15 @@ async function handleWxPhoneLogin(e: any) {
|
||||
<view class="oauth-btn__icon" style="background: #12B7F5">
|
||||
<image class="oauth-btn__iconify" src="/static/icons/qq.svg" />
|
||||
</view>
|
||||
<text class="oauth-btn__label">
|
||||
{{ t('login.qq') }}
|
||||
</text>
|
||||
<wd-text class="oauth-btn__label" :text="t('login.qq')" />
|
||||
</wd-grid-item>
|
||||
</wd-grid>
|
||||
</view>
|
||||
|
||||
<!-- Footer -->
|
||||
<view class="login-footer">
|
||||
<text class="login-footer__text">
|
||||
{{ t('login.noAccount') }}
|
||||
</text>
|
||||
<text class="login-footer__link wot-text-primary" @click="goRegister">
|
||||
{{ t('login.toRegister') }}
|
||||
</text>
|
||||
<wd-text class="login-footer__text" :text="t('login.noAccount')" />
|
||||
<wd-text class="login-footer__link" :text="t('login.toRegister')" type="primary" @click="goRegister" />
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
@@ -637,3 +552,12 @@ async function handleWxPhoneLogin(e: any) {
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss">
|
||||
/* MP 端兼容:wd-form-item 内部 wd-cell 因 uni-app 插槽静态声明(u-s)误判 label/title 插槽被使用,
|
||||
showLeft=true 渲染空 left 区域(flex:1 占半宽),H5 端运行时插槽判定无此问题。
|
||||
本页 form-item 无 title/label/prefix 内容,隐藏 left 安全,保证输入框与登录按钮同宽 */
|
||||
.login-card .wd-form-item .wd-cell__left {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -148,7 +148,7 @@ function goLogin() {
|
||||
|
||||
<view class="register-form">
|
||||
<wd-form ref="registerFormRef" :model="registerForm" :schema="registerSchema">
|
||||
<wd-form-item prop="username">
|
||||
<wd-form-item prop="username" custom-style="margin-bottom: 14rpx; padding-left: 0; padding-right: 0;">
|
||||
<wd-input
|
||||
v-model="registerForm.username"
|
||||
:placeholder="t('common.form.usernamePlaceholder')"
|
||||
@@ -157,7 +157,7 @@ function goLogin() {
|
||||
prefix-icon="user"
|
||||
/>
|
||||
</wd-form-item>
|
||||
<wd-form-item prop="name">
|
||||
<wd-form-item prop="name" custom-style="margin-bottom: 14rpx; padding-left: 0; padding-right: 0;">
|
||||
<wd-input
|
||||
v-model="registerForm.name"
|
||||
:placeholder="t('common.form.nicknamePlaceholder')"
|
||||
@@ -166,7 +166,7 @@ function goLogin() {
|
||||
prefix-icon="user"
|
||||
/>
|
||||
</wd-form-item>
|
||||
<wd-form-item prop="password">
|
||||
<wd-form-item prop="password" custom-style="margin-bottom: 14rpx; padding-left: 0; padding-right: 0;">
|
||||
<wd-input
|
||||
v-model="registerForm.password"
|
||||
:placeholder="t('common.form.passwordPlaceholder')"
|
||||
@@ -176,7 +176,7 @@ function goLogin() {
|
||||
prefix-icon="lock"
|
||||
/>
|
||||
</wd-form-item>
|
||||
<wd-form-item prop="confirmPassword">
|
||||
<wd-form-item prop="confirmPassword" custom-style="margin-bottom: 14rpx; padding-left: 0; padding-right: 0;">
|
||||
<wd-input
|
||||
v-model="registerForm.confirmPassword"
|
||||
:placeholder="t('common.form.confirmPlaceholder')"
|
||||
@@ -193,9 +193,7 @@ function goLogin() {
|
||||
<wd-checkbox v-model="agreeRead" size="18px">
|
||||
{{ t('register.agree') }}
|
||||
</wd-checkbox>
|
||||
<text class="register-agreement__link wot-text-primary" @click="handleAgreementOpen">
|
||||
{{ t('register.userAgreement') }}
|
||||
</text>
|
||||
<wd-text class="register-agreement__link" :text="t('register.userAgreement')" type="primary" @click="handleAgreementOpen" />
|
||||
</view>
|
||||
|
||||
<wd-button type="primary" round block :loading="submitting" @click="handleSubmit">
|
||||
@@ -204,12 +202,8 @@ function goLogin() {
|
||||
</view>
|
||||
|
||||
<view class="register-footer">
|
||||
<text class="register-footer__text">
|
||||
{{ t('register.hasAccount') }}
|
||||
</text>
|
||||
<text class="register-footer__link wot-text-primary" @click="goLogin">
|
||||
{{ t('register.toLogin') }}
|
||||
</text>
|
||||
<wd-text class="register-footer__text" :text="t('register.hasAccount')" />
|
||||
<wd-text class="register-footer__link" :text="t('register.toLogin')" type="primary" @click="goLogin" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -323,3 +317,12 @@ function goLogin() {
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss">
|
||||
/* MP 端兼容:wd-form-item 内部 wd-cell 因 uni-app 插槽静态声明(u-s)误判 label/title 插槽被使用,
|
||||
showLeft=true 渲染空 left 区域(flex:1 占半宽),H5 端运行时插槽判定无此问题。
|
||||
本页 form-item 无 title/label/prefix 内容,隐藏 left 安全,保证输入框与登录按钮同宽 */
|
||||
.register-card .wd-form-item .wd-cell__left {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -231,9 +231,7 @@ async function handleSubmitPassword() {
|
||||
<view class="mx-3 mb-3">
|
||||
<view class="mb-2 mt-1 flex items-center gap-2 px-3">
|
||||
<view class="h-3.5 w-1 rounded-full" style="background-color: var(--primary-color, #4F8CFF);" />
|
||||
<text class="text-3.5 font-bold wot-text-text-main">
|
||||
{{ t('common.settings') }}
|
||||
</text>
|
||||
<wd-text class="text-3.5 wot-text-text-main" :text="t('common.settings')" bold />
|
||||
</view>
|
||||
<wd-cell-group border custom-class="rounded-2! overflow-hidden">
|
||||
<wd-cell
|
||||
|
||||
@@ -112,12 +112,8 @@ const filteredGroups = computed(() => {
|
||||
<view v-for="(group, gi) in filteredGroups" :key="gi" class="mb-4">
|
||||
<view class="mb-2 mt-1 flex items-center gap-2 px-3">
|
||||
<view class="h-3.5 w-1 rounded-full" :style="{ backgroundColor: group.color }" />
|
||||
<text class="text-3.5 font-bold wot-text-text-main">
|
||||
{{ t(group.titleKey) }}
|
||||
</text>
|
||||
<text class="text-2.5 wot-text-text-auxiliary">
|
||||
{{ group.items.length }}
|
||||
</text>
|
||||
<wd-text class="text-3.5 wot-text-text-main" :text="t(group.titleKey)" bold />
|
||||
<wd-text class="text-2.5 wot-text-text-auxiliary" :text="group.items.length" />
|
||||
</view>
|
||||
<wd-cell-group border custom-class="mx-3 rounded-2! overflow-hidden">
|
||||
<wd-cell
|
||||
@@ -135,7 +131,9 @@ const filteredGroups = computed(() => {
|
||||
>
|
||||
<wd-icon :name="item.icon" size="16px" :color="group.color" />
|
||||
</view>
|
||||
<text>{{ t(item.titleKey) }}</text>
|
||||
<text>
|
||||
{{ t(item.titleKey) }}
|
||||
</text>
|
||||
</view>
|
||||
</template>
|
||||
</wd-cell>
|
||||
|
||||
Reference in New Issue
Block a user