index.vue 4.85 KB
<!--
 * @Date: 2026-01-08 13:01:56
 * @LastEditors: hookehuyr hookehuyr@gmail.com
 * @LastEditTime: 2026-01-14 20:49:12
 * @FilePath: /xyxBooking-weapp/src/pages/volunteerLogin/index.vue
 * @Description: 义工登录页面
-->
<template>
  <view class="login-page">
    <view class="logo-section">
      <image :src="logo" mode="aspectFit" />
      <text class="app-name">义工登录</text>
    </view>

    <view class="login-card">
      <view class="title">欢迎回来</view>

      <view class="input-group">
        <text class="label">账号</text>
        <input v-model="username" placeholder="请输入账号" placeholder-class="input-placeholder" cursorSpacing="40rpx" />
      </view>

      <view class="input-group">
        <text class="label">密码</text>
        <input v-model="password" password placeholder="请输入密码" placeholder-class="input-placeholder"
          cursorSpacing="40rpx" />
      </view>

      <button class="login-btn" @tap="handleLogin">立即登录</button>
    </view>
  </view>
</template>

<script setup>
import { ref } from 'vue'
import Taro, { useDidShow } from '@tarojs/taro'
import { mainStore } from '@/stores/main'
import { volunteerLoginAPI, checkRedeemPermissionAPI } from '@/api/index'
import { useReplace } from '@/hooks/useGo'
import logo from '@/assets/images/logo.png'

const store = mainStore()
const replace = useReplace()
const username = ref('')
const password = ref('')

/**
 * @description: 检查核销权限并重定向
 */

const check_permission_and_redirect = async () => {
  try {
    const permission_res = await checkRedeemPermissionAPI()
    if (permission_res?.code !== 1) return
    if (permission_res?.data) store.changeUserInfo(permission_res.data)
    if (permission_res?.data?.can_redeem === true) replace('verificationResult')
  } catch (e) { }
}

useDidShow(() => {
  check_permission_and_redirect()
})

const handleLogin = async () => {
  if (!username.value || !password.value) {
    Taro.showToast({ title: '请输入账号密码', icon: 'none' })
    return
  }

  Taro.showLoading({ title: '登录中...' })
  const login_res = await volunteerLoginAPI({ username: username.value, password: password.value })
  Taro.hideLoading()

  if (login_res?.code !== 1) {
    Taro.showToast({ title: login_res?.msg || '登录失败', icon: 'none' })
    return
  }

  Taro.showLoading({ title: '校验权限中...' })
  const permission_res = await checkRedeemPermissionAPI()
  Taro.hideLoading()

  if (permission_res?.code !== 1) {
    Taro.showToast({ title: permission_res?.msg || '权限校验失败', icon: 'none' })
    return
  }

  if (permission_res?.data) store.changeUserInfo(permission_res.data)

  if (permission_res?.data?.can_redeem === true) {
    Taro.showToast({ title: permission_res?.msg || login_res?.msg || '登录成功', icon: 'success' })
    setTimeout(() => replace('verificationResult'), 1200)
    return
  }

  Taro.showToast({ title: permission_res?.msg || '暂无核销权限', icon: 'none' })
}
</script>

<style lang="less">
.login-page {
  min-height: 100vh;
  background-color: #F6F6F6;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding-top: 120rpx;

  .logo-section {
    display: flex;
    flex-direction: column;
    align-items: center;
    margin-bottom: 60rpx;

    image {
      width: 120rpx;
      height: 120rpx;
      border-radius: 50%;
      margin-bottom: 24rpx;
      box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.1);
      background-color: #fff;
    }

    .app-name {
      font-size: 36rpx;
      font-weight: 600;
      color: #333;
      letter-spacing: 2rpx;
    }
  }

  .login-card {
    width: 690rpx;
    background: #fff;
    border-radius: 24rpx;
    padding: 60rpx 40rpx;
    box-shadow: 0 12rpx 40rpx rgba(0, 0, 0, 0.04);
    box-sizing: border-box;

    .title {
      font-size: 44rpx;
      font-weight: bold;
      color: #333;
      margin-bottom: 60rpx;
      padding-left: 10rpx;
    }

    .input-group {
      background-color: #F7F8FA;
      border-radius: 12rpx;
      padding: 28rpx 30rpx;
      margin-bottom: 32rpx;
      display: flex;
      align-items: center;
      transition: all 0.3s;

      .label {
        font-size: 30rpx;
        color: #333;
        font-weight: 500;
        width: 90rpx;
        margin-right: 20rpx;
      }

      input {
        flex: 1;
        font-size: 30rpx;
        color: #333;
        height: 44rpx;
        min-height: 44rpx;
      }

      .input-placeholder {
        color: #C0C4CC;
      }
    }

    .login-btn {
      margin-top: 80rpx;
      background: #A67939;
      color: #fff;
      height: 96rpx;
      line-height: 96rpx;
      border-radius: 48rpx;
      font-size: 34rpx;
      font-weight: 500;
      box-shadow: 0 12rpx 30rpx rgba(166, 121, 57, 0.3);
      border: none;

      &::after {
        border: none;
      }

      &:active {
        opacity: 0.9;
        transform: scale(0.99);
      }
    }
  }
}
</style>