罗广辉
2026-05-08 be4e2d7c2b330c3b8991a0286ea16cc1285b9ec0
src/pages/login/index.vue
@@ -1,48 +1,95 @@
<!-- 登录页 -->
<template>
  <view>
    <view class="login-form-wrap">
      <view class="title"> 掌控智飞</view>
      <input
        v-model="loginForm.username"
        class="u-border-bottom"
        placeholder="请输入用户名"
      />
  <view class="login-form-wrap">
    <image class="logo" :src="logoSvg" />
    <div class="title">掌控智飞</div>
    <div class="user-name">
      <image :src="usernameSvg" />
      <input v-model="loginForm.username" placeholder="请输入用户名" />
    </div>
    <div class="pass-word">
      <image :src="passwordSvg" />
      <input
        v-model="loginForm.password"
        class="u-border-bottom"
        type="password"
        placeholder="请输入密码"
      />
      <button class="login-btn" :style="[inputStyle]" @tap="submit">
        登录
        <text class="i-mdi-login" />
      </button>
    </view>
    </div>
    <div class="remember-password">
      <label>
        <checkbox-group @change="toggleRemember">
          <checkbox
            :checked="rememberPassword"
            color="#1D6FE9"
            style="transform: scale(0.7)"
          />
        </checkbox-group>
        记住密码
      </label>
    </div>
    <button class="login-btn" :style="[inputStyle]" @tap="submit">登录</button>
    <image class="lowerRightCorner" :src="droneSvg" />
    <!-- #ifdef MP-WEIXIN -->
    <GetPrivacy ref="privacyComponent" position="center" @allowPrivacy="allowPrivacy"/>
    <!-- #endif -->
  </view>
</template>
<script setup>
import { getAssetsImage } from "@/utils/index.js";
import md5 from "js-md5";
import { loginByUsername } from "@/api/user/index.js";
import { useUserStore } from "@/store/index.js";
// #ifdef MP-WEIXIN
import GetPrivacy from '@/components/GetPrivacy.vue'
// #endif
import { HOME_PATH, LOGIN_PATH, removeQueryString } from "@/router";
import { onMounted } from "vue";
const droneSvg = getAssetsImage("/images/login/droneSvg.png");
const usernameSvg = getAssetsImage("/images/login/username.png");
const passwordSvg = getAssetsImage("/images/login/password.png");
const logoSvg = getAssetsImage("/images/login/logo.png");
const userStore = useUserStore();
const loginForm = ref({
  username: "cpz3",
  password: "cpz3@2025",
  username: "",
  password: "",
});
const rememberPassword = ref(false);
const inputStyle = computed(() => {
  const style = {};
  if (loginForm.value.username && loginForm.value.password) {
    style.color = "#fff";
    style.backgroundColor = uni.$u.color.warning;
    style.backgroundColor = "#1D6FE9";
  }
  return style;
});
let redirect = HOME_PATH;
function toggleRemember(e) {
  rememberPassword.value = e.detail.value.length > 0;
}
async function submit() {
  if (!loginForm.value.username.trim()) {
    uni.showToast({
      title: "请输入用户名",
      icon: "none",
      duration: 2000,
    });
    return;
  }
  if (!loginForm.value.password.trim()) {
    uni.showToast({
      title: "请输入密码",
      icon: "none",
      duration: 2000,
    });
    return;
  }
  let userInfo = {
    tenantId: "000000",
    deptId: "",
@@ -53,36 +100,177 @@
    code: "",
    key: "",
  };
  loginByUsername(
    userInfo.tenantId,
    userInfo.deptId,
    userInfo.roleId,
    userInfo.username,
    md5(userInfo.password),
    userInfo.type,
    userInfo.key,
    userInfo.code
  ).then((res) => {
    userStore.setUserInfo(res.data);
    uni.switchTab({
      url: "/pages/user/index",
  if (rememberPassword.value) {
    uni.setStorageSync("rememberedUser", {
      username: loginForm.value.username,
      password: loginForm.value.password,
    });
  });
  } else {
    uni.removeStorageSync("rememberedUser");
  }
  try {
    const res = await loginByUsername(
      userInfo.tenantId,
      userInfo.deptId,
      userInfo.roleId,
      userInfo.username,
      md5(userInfo.password),
      userInfo.type,
      userInfo.key,
      userInfo.code
    );
    userStore.setUserInfo(res.data);
    uni.reLaunch({
      url: "/pages/map/index",
    });
  } catch (error) {
    const errorMsg =
      error.data?.error_description !== "Bad credentials"
        ? error.data?.error_description
        : "登录失败,请重试";
    uni.showToast({
      title: errorMsg,
      icon: "none",
      duration: 2000,
    });
  }
}
// 从本地存储加载记住的密码
onMounted(() => {
  const savedUserInfo = uni.getStorageSync("rememberedUser");
  console.log("记住密码", savedUserInfo);
  if (savedUserInfo) {
    loginForm.value.username = savedUserInfo.username;
    loginForm.value.password = savedUserInfo.password;
    rememberPassword.value = true;
  }
});
onLoad((options) => {
  if (options.redirect && removeQueryString(options.redirect) !== LOGIN_PATH) {
    redirect = decodeURIComponent(options.redirect);
  }
});
// #ifdef MP-WEIXIN
const allowPrivacy = () =>{
  // 同意隐私协议触发事件,有些接口需要同意授权后才能执行,比如获取手机号授权接口,可以在同意隐私协议后,再执行授权获取手机号接口,如果不需要可以不添加该方法
  console.log('同意隐私授权')
}
const privacyComponent =ref(null)
// onShow(() =>{
//   wx.getPrivacySetting({
//     success: res => {
//       console.log(res)
//       if (!res.needAuthorization) {
//         privacyComponent?.value?.closePrivacy()
//         // 查询授权,针对有tab切换的页面,可以在onshow中查询隐私授权状态,判断在tab切换后是否需要关闭授权弹框
//         console.log('已经同意隐私授权,不需要再次授权')
//       }
//     },
//     fail: () => {},
//     complete: () => {}
//   })
// })
// #endif
</script>
<style lang="scss" scoped>
.login-form-wrap {
  @apply mt-80rpx mx-auto mb-0 w-600rpx;
  position: relative;
  text-align: center;
  height: 100%;
  width: 100%;
  .logo {
    width: 127px;
    height: 51px;
    margin: 0 auto;
    margin-top: 104px;
    margin-bottom: 16px;
  }
  .lowerRightCorner {
    position: absolute;
    right: 0;
    bottom: 0;
    width: 425.61rpx;
    height: 316.46rpx;
  }
  .title {
    @apply mb-100rpx text-60rpx text-left font-500;
    font-family: YouSheBiaoTiHei, YouSheBiaoTiHei;
    font-weight: 400;
    font-size: 84rpx;
    line-height: 82rpx;
    letter-spacing: 1px;
    text-shadow: 0px 8px 8px rgba(0, 0, 0, 0.18);
    text-align: center;
    font-style: normal;
    text-transform: none;
    color: #1452d3;
    text-align: center;
    margin-bottom: 168rpx;
  }
  .user-name,
  .pass-word {
    display: flex;
    //justify-content: center;
    align-items: center;
    margin-left: 62rpx;
    margin-right: 58rpx;
    height: 118rpx;
    border-bottom: 2rpx solid #e3e3e3;
    image {
      width: 40rpx;
      height: 40rpx;
      margin-right: 12rpx;
    }
    :deep(uni-input) {
      height: 40rpx;
      line-height: 40rpx;
      width: 80%;
      margin-top: 20rpx;
      padding: 0 !important;
    }
    :deep(input) {
      height: 40rpx;
      line-height: 40rpx;
      width: 80%;
      margin-top: 20rpx;
      padding: 0 !important;
      margin: 0 !important;
    }
    :deep(.uni-input-placeholder) {
      font-size: 32rpx;
      color: #e3e3e3;
      font-weight: 500;
    }
  }
  .remember-password {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    margin-left: 62rpx;
    margin-right: 58rpx;
    margin-top: 20rpx;
    color: #666;
    font-size: 28rpx;
    label {
      display: flex;
      align-items: center;
    }
  }
  input {
@@ -91,14 +279,18 @@
  .tips {
    @apply mt-8rpx mb-60rpx;
    color: $u-info;
  }
  .login-btn {
    @apply flex items-center justify-center py-12rpx px-0 text-30rpx bg-#fdf3d0 border-none;
    color: $u-tips-color;
    z-index: 1;
    @apply flex items-center justify-center py-12rpx px-0 text-30rpx border-none;
    background: #1d6fe9;
    color: white;
    width: 590rpx;
    height: 76rpx;
    border-radius: 40rpx 40rpx 40rpx 40rpx;
    margin-top: 100rpx;
    &::after {
      @apply border-none;
@@ -107,7 +299,6 @@
  .alternative {
    @apply flex justify-between mt-30rpx;
    color: $u-tips-color;
  }
}
@@ -117,14 +308,12 @@
  .item {
    @apply flex items-center flex-col text-28rpx;
    color: $u-content-color;
  }
}
.hint {
  @apply px-40rpx py-20rpx text-24rpx;
  color: $u-tips-color;
  .link {