index.vue 9.6 KB
<template>
  <view class="login-page">
    <!-- 顶部标题区 -->
    <view class="top-title">
      <text class="welcome-text">你好,欢迎光临</text>
      <text class="platform-name">全域智能运营管理平台</text>
    </view>

    <!-- 登录表单区域 -->
    <view class="login-form">
      <!-- uview-plus的Tabs组件 -->
      <up-tabs
          :list="tabList"
          active-color="#0A86F4"
          inactive-color="#666"
          font-size="16px"
          line-width="40"
          line-height="3"
          @change="handleTabChange"
      ></up-tabs>

      <!-- 表单校验容器 -->
      <up-form
          label-position="left"
          :model="form"
          ref="loginFormRef"
          labelWidth="0"
      >
        <!-- 手机号输入框 -->
        <up-form-item v-if="loginType === '手机号登录'" prop="mobile">
          <up-input
              v-model="form.mobile"
              border="surround"
              clearable
              maxlength="11"
              input-align="left"
              fontSize="16px"
              :disabled="isLoading"
              shape="circle"
              placeholder="请输入手机号"
              @blur="() => loginFormRef.validateField('mobile')"
          />
        </up-form-item>

        <!-- 账号输入框 -->
        <up-form-item v-else prop="account">
          <up-input
              v-model="form.account"
              border="surround"
              clearable
              maxlength="30"
              input-align="left"
              fontSize="16px"
              :disabled="isLoading"
              shape="circle"
              placeholder="请输入账户"
              @blur="() => loginFormRef.validateField('account')"
          />
        </up-form-item>

        <!-- 密码输入框 -->
        <up-form-item
            prop="password"
            class="password-item"
        >
          <up-input
              v-model="form.password"
              placeholder="请输入密码"
              maxlength="20"
              border="surround"
              clearable
              input-align="left"
              type="password"
              :disabled="isLoading"
              shape="circle"
              @blur="() => loginFormRef.validateField('password')"
          />
        </up-form-item>

        <!-- 记住密码单独一行,居右显示 -->
        <view class="remember-wrap">
          <up-checkbox
              :customStyle="{marginBottom: '8px'}"
              label="记住密码"
              name="agree"
              usedAlone
              v-model:checked="rememberPwd"
          >
          </up-checkbox>
        </view>
      </up-form>

      <!-- 登录按钮 -->
      <up-button
          class="login-btn"
          type="primary"
          size="large"
          :loading="isLoading"
          @click="handleLogin"
          shape="circle"
      >
        登录
      </up-button>
    </view>

    <!-- 版权信息 -->
    <view class="copyright">蓟城山水集团版权所有</view>
  </view>
</template>

<script setup>
import { ref, reactive, onMounted, nextTick } from 'vue';
import { useUserStore } from '@/pinia/user';
import globalConfig from '@/common/config/global';

// 全局实例 & 基础状态
const userStore = useUserStore();
const loginFormRef = ref(null);
const isLoading = ref(false);

// Tabs配置(name直接存储显示文本)
const tabList = ref([
  { name: '手机号登录' },
  { name: '账号登录' }
]);
const loginType = ref('手机号登录'); // 登录类型标识

// 记住密码(默认选中)
const rememberPwd = ref(true);

// 表单数据
const form = reactive({
  account: '',    // 账号
  mobile: '',     // 手机号
  password: ''    // 密码
});

// 表单校验规则
const loginFormRules = reactive({
  account: [
    { type: 'string', required: true, message: '请输入登录账号', trigger: ['change', 'blur'] },
    { type: 'string', min: 2, max: 30, message: '账号长度为2-30个字符', trigger: ['change', 'blur'] }
  ],
  mobile: [
    { type: 'string', required: true, message: '请输入手机号', trigger: ['change', 'blur'] },
    { type: 'string', pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号格式', trigger: ['change', 'blur'] }
  ],
  password: [
    { type: 'string', required: true, message: '请输入登录密码', trigger: ['change', 'blur'] },
    { type: 'string', min: 3, max: 20, message: '密码长度为3-20个字符', trigger: ['change', 'blur'] }
  ]
});

// Tabs切换事件
const handleTabChange = ({name}) => {
  console.log(name)
  if (isLoading.value) return;
  loginType.value = name;

  // 切换时清空另一类输入框
  if (name === '手机号登录') {
    form.account = '';
  } else {
    form.mobile = '';
  }

  // 清空校验状态
  nextTick(() => {
    loginFormRef.value?.clearValidate();
  });
};

// 生命周期
onMounted(() => {
  // 检查登录态
  checkLoginStatus();

  // 初始化表单校验规则
  nextTick(() => {
    loginFormRef.value?.setRules(loginFormRules);
  });

  // 读取缓存的账号/密码
  if (rememberPwd.value) {
    try {
      const savedAccount = uni.getStorageSync('login_account') || '';
      const savedMobile = uni.getStorageSync('login_mobile') || '';
      const savedPwd = uni.getStorageSync('login_password') || '';

      if (savedAccount) {
        form.account = savedAccount;
        loginType.value = '账号登录';

      } else if (savedMobile) {
        form.mobile = savedMobile;
        loginType.value = '手机号登录';
      }
      form.password = savedPwd;
    } catch (err) {
      console.warn('读取缓存密码失败:', err);
    }
  }
});

// 检查登录状态
const checkLoginStatus = () => {
  try {
    if (userStore.isLogin) {
      uni.switchTab({
        url: '/pages/workbench/index',
        fail: () => uni.reLaunch({ url: '/pages/workbench/index' })
      });
    }
  } catch (err) {
    console.warn('检查登录状态失败:', err);
  }
};

// 登录方法
const handleLogin = async () => {
  try {
    // 表单校验
    await loginFormRef.value.validate();
    isLoading.value = true;

    // 组装登录参数
    const loginParams = { password: form.password };
    if (loginType.value === '手机号登录') {
      // loginParams.mobile = form.mobile;
      loginParams.username = form.mobile;
    } else {
      loginParams.username = form.account;
    }

    // 执行登录
    await userStore.login(loginParams);

    // 保存记住密码
    if (rememberPwd.value) {
      try {
        if (loginType.value === '手机号登录') {
          uni.setStorageSync('login_mobile', form.mobile);
          uni.removeStorageSync('login_account');
        } else {
          uni.setStorageSync('login_account', form.account);
          uni.removeStorageSync('login_mobile');
        }
        uni.setStorageSync('login_password', form.password);
      } catch (err) {
        console.warn('保存密码失败:', err);
      }
    } else {
      // 清除缓存
      uni.removeStorageSync('login_account');
      uni.removeStorageSync('login_mobile');
      uni.removeStorageSync('login_password');
    }

    // 登录成功提示+跳转
    uni.showToast({ title: '登录成功', icon: 'success', duration: 1000 });
    setTimeout(() => {
      uni.switchTab({
        url: globalConfig.router.tabBarList[1].path,
        fail: () => uni.reLaunch({ url: '/pages/workbench/index' })
      });
    }, 1000);
  } catch (err) {
    // 错误处理
    if (!Array.isArray(err)) {
      console.error('登录失败:', err);
      uni.showToast({
        title: err.msg || '账号或密码错误,请重试',
        icon: 'none',
        duration: 1000
      });
    }
  } finally {
    isLoading.value = false;
  }
};
</script>

<style scoped lang="scss">
// 核心布局
.login-page {
  min-height: 100vh;
  padding: 0;
  box-sizing: border-box;
  overflow: hidden;
  position: relative;
  background: #f5f7fa;
}

// 顶部样式
.top-title {
  background: url("https://img.jichengshanshui.com.cn:28207/appimg/bg.jpg") no-repeat;
  background-size: 100% 100%;
  color: #fff;
  padding: 200rpx 0 200rpx 40rpx;
  text-align: left;
  position: relative;
  z-index: 1;

  .welcome-text {
    font-size: 23px;
    display: block;
    margin-bottom: 10px;
    font-weight: 500;
  }

  .platform-name {
    margin-bottom: 10px;
    font-size: 23px;
    display: block;
    opacity: 0.95;
  }
}

.login-form {
  background-color: #fff;
  padding: 20px 15px;
  border-radius: 8px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.06);
  margin: -90px 20px 0;
  position: relative;
  z-index: 10;
  box-sizing: border-box;
}

// Tabs样式适配
:deep(.u-tabs) {
  margin-bottom: 15px;
  .u-tabs__content {
    height: auto !important;
  }
  .u-tab-item {
    padding: 0 10px;
  }
}

// 表单间距
:deep(.u-form-item) {
  margin-bottom: 10px;
  position: relative;
}

// 密码项样式
.password-item {
  position: relative;
  margin-bottom: 5px !important;
}

// ✅ 核心优化:记住密码完全居右对齐
.remember-wrap {
  //text-align: right;
  padding: 0; // 移除多余内边距
  margin: 10px 0 20px;

  :deep(.u-checkbox) {
    font-size: 12px;
    color: #666;
    justify-content: flex-end;
    // 移除复选框的默认左边距,确保居右紧凑
    margin-left: 0 !important;

    .u-checkbox__label {
      margin-left: 5px;
    }
  }
}

// 登录按钮
.login-btn {
  margin-top: 10px;
  width: 100%;
  height: 44px;
  line-height: 44px;
  border-radius: 4px;
  font-size: 16px;
  background: #0A86F4;
  box-shadow: 0px 4px 6px 1px rgba(25,94,215,0.5);
  border-radius: 23px;
}

// 版权信息
.copyright {
  width: 100%;
  text-align: center;
  font-size: 12px;
  color: #999;
  position: fixed;
  bottom: 100px;
}
</style>