| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220 |
- <template>
- <view class="auth-page">
- <view class="auth-hero">
- <view class="auth-hero__brand">
- <text class="auth-hero__app">巴青农资商城</text>
- <text class="auth-hero__welcome">欢迎登录农资商城</text>
- </view>
- </view>
- <view class="auth-body">
- <view class="auth-card">
- <text class="auth-card__title">会员登录</text>
- <text class="auth-card__sub">可使用手机号登录</text>
- <view class="auth-field">
- <view class="auth-field__box">
- <u-icon name="account" color="#6b7f72" size="22" />
- <input
- v-model="form.account"
- class="auth-field__input"
- type="text"
- placeholder="手机号"
- placeholder-class="auth-field__placeholder"
- confirm-type="next"
- />
- </view>
- </view>
- <view class="auth-field">
- <view class="auth-field__box">
- <u-icon name="lock" color="#6b7f72" size="22" />
- <input
- v-model="form.password"
- class="auth-field__input"
- type="password"
- placeholder="请输入密码"
- placeholder-class="auth-field__placeholder"
- confirm-type="done"
- @confirm="handleLogin"
- />
- </view>
- </view>
- <view class="auth-remember" @click="form.rememberMe = !form.rememberMe">
- <view :class="['auth-remember__check', { 'auth-remember__check--on': form.rememberMe }]">
- <u-icon v-if="form.rememberMe" name="checkmark" color="#ffffff" size="14" />
- </view>
- <text class="auth-remember__txt">记住账号</text>
- </view>
- <agreement-block
- v-model="form.agreementAccepted"
- :enabled="needAgreement"
- :checkbox-label="agreement.checkboxLabel"
- :agreement-title="agreement.agreementTitle"
- :version-label="agreement.versionLabel"
- :content="agreement.content"
- />
- <view
- :class="['auth-btn', { 'auth-btn--loading': loading }]"
- :disabled="loading"
- @click="handleLogin"
- >
- <text class="auth-btn__txt">{{ loading ? '登录中…' : '登 录' }}</text>
- </view>
- <view class="auth-switch">
- <text>还没有账号?</text>
- <text class="auth-switch__link" @click="goRegister">立即注册</text>
- </view>
- </view>
- <text class="auth-footer">农资商城</text>
- </view>
- </view>
- </template>
- <script setup>
- import { ref, reactive, computed } from 'vue'
- import { onLoad } from '@dcloudio/uni-app'
- import { getToken } from '@/utils/auth'
- import { REMEMBER_ACCOUNT_KEY } from '@/config'
- import { useUserStore } from '@/store/user'
- import { loadServiceAgreement } from '@/utils/memberAgreement'
- import { PAGE_HOME, PAGE_REGISTER } from '@/utils/pageRoute'
- import AgreementBlock from '@/components/account/AgreementBlock.vue'
- import { useActionGuard } from '@/utils/actionGuard'
- const loginGuard = useActionGuard()
- const loading = loginGuard.locked
- const agreement = reactive({
- enabled: false,
- requireAgreementOnLogin: false,
- agreementTitle: '',
- versionLabel: '',
- content: '',
- checkboxLabel: ''
- })
- const form = reactive({
- account: '',
- password: '',
- rememberMe: false,
- agreementAccepted: false
- })
- const needAgreement = computed(
- () => agreement.enabled && agreement.requireAgreementOnLogin
- )
- onLoad(async (options) => {
- if (getToken()) {
- goHome()
- return
- }
- const cfg = await loadServiceAgreement()
- Object.assign(agreement, cfg)
- if (options && options.account) {
- form.account = decodeURIComponent(options.account)
- }
- loadRememberedAccount()
- })
- function loadRememberedAccount() {
- const saved =
- uni.getStorageSync(REMEMBER_ACCOUNT_KEY) || uni.getStorageSync('shop_login_username')
- if (saved) {
- form.account = saved
- form.rememberMe = true
- }
- }
- function goHome() {
- uni.switchTab({ url: PAGE_HOME })
- }
- function goRegister() {
- const q = form.account ? `?mobile=${encodeURIComponent(form.account.trim())}` : ''
- uni.navigateTo({ url: `${PAGE_REGISTER}${q}` })
- }
- function validateForm() {
- if (!(form.account || '').trim()) {
- uni.showToast({ title: '请输入账号', icon: 'none' })
- return false
- }
- if (!form.password) {
- uni.showToast({ title: '请输入密码', icon: 'none' })
- return false
- }
- if (needAgreement.value && !form.agreementAccepted) {
- uni.showToast({ title: '请先阅读并同意服务协议', icon: 'none' })
- return false
- }
- return true
- }
- function handleLogin() {
- loginGuard.run(async () => {
- if (!validateForm()) return
- const account = form.account.trim()
- if (form.rememberMe) {
- uni.setStorageSync(REMEMBER_ACCOUNT_KEY, account)
- } else {
- uni.removeStorageSync(REMEMBER_ACCOUNT_KEY)
- }
- const userStore = useUserStore()
- userStore.fedLogOut()
- await userStore.login({
- account,
- password: form.password,
- agreementAccepted: needAgreement.value ? form.agreementAccepted : true
- })
- await userStore.fetchUserInfo()
- goHome()
- })
- }
- </script>
- <style lang="scss" scoped>
- @import '@/styles/auth.scss';
- .auth-remember {
- display: flex;
- align-items: center;
- margin-top: 8rpx;
- }
- .auth-remember__check {
- width: 32rpx;
- height: 32rpx;
- margin-right: 12rpx;
- border: 2rpx solid #c8e6c9;
- border-radius: 6rpx;
- display: flex;
- align-items: center;
- justify-content: center;
- background: #fff;
- }
- .auth-remember__check--on {
- background: #2e7d32;
- border-color: #2e7d32;
- }
- .auth-remember__txt {
- font-size: 26rpx;
- color: #666;
- }
- .auth-footer {
- display: block;
- margin-top: 48rpx;
- text-align: center;
- font-size: 24rpx;
- color: #aaa;
- }
- </style>
|