gaoluyang
2025-08-06 6abe22fc75b115d2a68103a4d8b24d0815a016f8
登录页联调开发,首页开发
已修改11个文件
已添加2个文件
15173 ■■■■ 文件已修改
package-lock.json 7994 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package.json 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/App.vue 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/login.js 30 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/Splash.vue 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/config.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages.json 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/index.vue 212 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/login.vue 200 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/splash.vue 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/store/modules/user.ts 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-scss/styles/setting/_variables.scss 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
yarn.lock 6524 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package-lock.json
ÎļþÌ«´ó
package.json
@@ -77,7 +77,7 @@
    "mqtt": "4.1.0",
    "pinia": "2.2.2",
    "tslib": "^2.7.0",
    "uview-plus": "^3.3.32",
    "uview-plus": "^3.4.62",
    "vue": "3.4.21",
    "vue-i18n": "^9.14.2"
  },
src/App.vue
@@ -1,16 +1,20 @@
<script>
<template>
  <Splash v-if="showSplash" />
  <div v-else>
    <router-view />
  </div>
</template>
export default {
    onLaunch: function () {
        console.log('App Launch')
    },
    onShow: function () {
        console.log('App Show')
    },
    onHide: function () {
        console.log('App Hide')
    }
}
<script setup>
import { ref, onMounted } from 'vue'
import Splash from './components/Splash.vue'
const showSplash = ref(true)
onMounted(() => {
  setTimeout(() => {
    showSplash.value = false
  }, 5000)
})
</script>
<style lang="scss">
src/api/login.js
@@ -1,27 +1,14 @@
import request from '@/utils/request'
// ç™»å½•方法
export function login(username, password, code, uuid) {
export function loginCheckFactory(username, password, factoryId) {
  const data = {
    username,
    password,
    code,
    uuid
    factoryId
  }
  return request({
    url: '/login',
    headers: {
      isToken: false
    },
    method: 'post',
    data: data
  })
}
// æ³¨å†Œæ–¹æ³•
export function register(data) {
  return request({
    url: '/register',
    url: '/loginCheckFactory',
    headers: {
      isToken: false
    },
@@ -46,14 +33,11 @@
  })
}
// èŽ·å–éªŒè¯ç 
export function getCodeImg() {
// èŽ·å–å…¬å¸åˆ—è¡¨
export function userLoginFacotryList(params) {
  return request({
    url: '/captchaImage',
    headers: {
      isToken: false
    },
    url: '/userLoginFacotryList',
    method: 'get',
    timeout: 20000
    params: params
  })
}
src/components/Splash.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,36 @@
<template>
  <div class="splash-container">
        <span class="title">科技</span>
        <span class="title1">便携生活</span>
  </div>
</template>
<script setup>
// æ— éœ€é€»è¾‘
</script>
<style scoped>
.splash-container {
  width: 100vw;
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  background: #fff;
}
.splash-logo {
  width: 180px;
  height: 180px;
  object-fit: contain;
}
.title {
    font-weight: 400;
    font-size: 60px;
    color: #000000;
}
.title1 {
    font-weight: 400;
    font-size: 40px;
    color: #000000;
}
</style>
src/config.js
@@ -2,7 +2,7 @@
const config = {
  //  baseUrl: 'https://vue.ruoyi.vip/prod-api',
  // baseUrl: 'http://localhost/prod-api',
  baseUrl: 'http://localhost:8080',
  baseUrl: 'http://114.132.189.42:8089',
   //cloud后台网关地址
  //  baseUrl: 'http://192.168.10.3:8080',
   // åº”用信息
src/pages.json
@@ -12,9 +12,16 @@
  },
  "pages": [
    {
      "path": "pages/splash",
      "style": {
        "navigationBarTitleText": "启动页",
        "navigationStyle": "custom"
      }
    },
    {
      "path": "pages/index",
      "style": {
        "navigationBarTitleText": "若依移动端框架",
        "navigationBarTitleText": "首页",
        "navigationStyle": "custom"
      }
    },
@@ -251,18 +258,6 @@
        "iconPath": "static/images/tabbar/home.png",
        "selectedIconPath": "static/images/tabbar/home_.png",
        "text": "首页"
      },
      {
        "pagePath": "pages/work",
        "iconPath": "static/images/tabbar/work.png",
        "selectedIconPath": "static/images/tabbar/work_.png",
        "text": "工作台"
      },
      {
        "pagePath": "pages/template",
        "iconPath": "static/images/tabbar/work.png",
        "selectedIconPath": "static/images/tabbar/work_.png",
        "text": "模板"
      },
      {
        "pagePath": "pages/mine",
src/pages/index.vue
@@ -1,75 +1,179 @@
<template>
  <view class="content">
    <image class="logo" src="@/static/logo.png"></image>
    <view class="text-area">
      <text class="title"> RuoYi-Geek-App</text>
        <view>
            <view class="currentFactory">
                <up-text type="primary" :text="userStore.currentFactoryName" @click="show = true"
                                 class="factoryName" suffixIcon="arrow-right" :iconStyle="iconStyle"></up-text>
    </view>
    <view class="text-area">
      <up-text type="primary" text="uview-plus"></up-text>
            <up-picker :show="show" :columns="factoryList" @confirm="changeFactory"></up-picker>
            <view>
                <view class="bg-img"></view>
    </view>
    <view class="charts-box">
      <qiun-data-charts type="column" :chartData="chartData" />
            <view class="bg-img">
                <up-grid
                    :border="false"
                    col="4"
                >
                    <up-grid-item
                        v-for="(listItem,listIndex) in list"
                        :key="listIndex"
                    >
                        <up-icon
                            :customStyle="{paddingTop:20+'rpx'}"
                            :name="listItem.name"
                            :size="22"
                        ></up-icon>
                        <text class="grid-text">{{listItem.title}}</text>
                    </up-grid-item>
                </up-grid>
    </view>
        </view>
<!--        <view class="select-container">-->
<!--            <up-picker-data-->
<!--                class="picker"-->
<!--                v-model="currentFatoryId"-->
<!--                title="请选择公司"-->
<!--                :options="factoryList"-->
<!--                valueKey="id"-->
<!--                labelKey="name">-->
<!--            </up-picker-data>-->
<!--        </view>-->
  </view>
</template>
<script setup>
import { ref, onMounted } from 'vue';
import {ref, onMounted, nextTick, reactive} from 'vue';
import {userLoginFacotryList} from "@/api/login";
import modal from "@/plugins/modal";
import useUserStore from "@/store/modules/user";
const chartData = ref({});
onMounted(() => { getServerData() });
function getServerData() {
  // æ¨¡æ‹Ÿä»ŽæœåŠ¡å™¨èŽ·å–æ•°æ®æ—¶çš„å»¶æ—¶
  setTimeout(() => {
    let res = {
      categories: ['2016', '2017', '2018', '2019', '2020', '2021'],
      series: [
        {
          name: '目标值',
          data: [35, 36, 31, 33, 13, 34],
        },
        {
          name: '完成量',
          data: [18, 27, 21, 24, 6, 28],
        },
      ],
    };
    chartData.value = JSON.parse(JSON.stringify(res));
  }, 500);
const userStore = useUserStore()
const factoryId = ref('');
const show = ref(false);
const factoryList = ref([]);
const factoryListTem = ref([]);
const iconStyle = {
    fontSize: '14px',
    color: '#165DFF'
}
// åˆ›å»ºå“åº”式数据
const list = reactive([
    {
        name: 'photo',
        title: '图片'
    },
    {
        name: 'lock',
        title: '锁头'
    },
    {
        name: 'star',
        title: '星星'
    },
    {
        name: 'hourglass',
        title: '沙漏'
    },
    {
        name: 'home',
        title: '首页'
    },
    {
        name: 'volume', // æ³¨æ„ï¼šè¿™é‡Œä¿®æ”¹äº† name ä»Ž 'star' æ”¹ä¸º 'volume',以避免列表中两个元素具有相同的 name
        title: '音量'
    },
]);
// åˆ›å»ºå¯¹å­ç»„件的引用
const uToastRef = ref(null);
function getUserLoginFacotryList() {
    userLoginFacotryList({userName: userStore.nickName}).then(res => {
        // æ£€æŸ¥res.data是否为数组
        factoryList.value[0] = []
        if (res.data && Array.isArray(res.data)) {
            factoryListTem.value = res.data
            res.data.forEach(item => {
                factoryList.value[0].push(item.deptName)
            })
            factoryId.value = userStore.currentDeptId
        } else {
            // å¦‚æžœres.data不是数组,设置为空数组
            factoryList.value = []
        }
    }).catch(error => {
        modal.msgError('获取公司列表失败:', error)
        factoryList.value = []
    })
}
const changeFactory = async (arr) => {
    show.value = false;
    const factoryId = factoryListTem.value[arr.indexs[0]].deptId
    const loginForm = {
        username: userStore.name,
        password: uni.getStorageSync('remembered_password'),
        factoryId: factoryId,
    }
    modal.loading("刷新中,请耐心等待...")
    userStore.loginCheckFactory(loginForm).then(() => {
        modal.closeLoading()
        nextTick(() => {
            loginSuccess()
        });
    }).catch(() => {
        modal.closeLoading()
    })
}
function loginSuccess(result) {
    uni.reLaunch({
        url: '/pages/index'
    });
}
// å®šä¹‰æ–¹æ³•
const click = (name) => {
    if (uToastRef.value) {
        uToastRef.value.success(`点击了第${name + 1}个`); // æ³¨æ„ï¼šè¿™é‡ŒåŠ 1是因为通常我们是从第1个开始计数的
    }
};
onMounted(() => {
    // è®¾ç½®ç”¨æˆ·ä¿¡æ¯
    userStore.getInfo()
    getUserLoginFacotryList()
});
</script>
<style scoped>
<style scoped lang="scss">
.content {
    background-color: transparent !important;
    padding: 14px;
}
.currentFactory {
    margin-top: 12px;
    margin-left: 6px;
    font-weight: 400;
    font-size: 14px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
.logo {
  height: 200rpx;
  width: 200rpx;
  margin-top: 200rpx;
  margin-left: auto;
  margin-right: auto;
  margin-bottom: 50rpx;
.factoryName {
    width: auto;
}
.text-area {
  display: flex;
  justify-content: center;
:deep(.u-text) {
    align-items: flex-end;
}
.title {
  font-size: 36rpx;
  color: #8f8f94;
}
.charts-box {
.bg-img {
    margin-top: 12px;
  width: 100%;
  height: 300px;
    height: 145px;
    background-color: #ffffff;
    border-radius: 10px 10px 10px 10px;
}
.grid-text {
    font-size: 14px;
    color: #909399;
    padding: 10rpx 0 20rpx 0rpx;
    /* #ifndef APP-PLUS */
    box-sizing: border-box;
    /* #endif */
}
</style>
src/pages/login.vue
@@ -1,59 +1,94 @@
<template>
  <view class="normal-login-container">
    <view class="logo-content align-center justify-center flex">
      <image style="width: 100rpx;height: 100rpx;" :src="globalConfig.appInfo.logo" mode="widthFix">
      </image>
      <text class="title">若依移动端登录</text>
    <view class="logo-content">
<!--      <image style="width: 100rpx;height: 100rpx;" :src="globalConfig.appInfo.logo" mode="widthFix">-->
<!--      </image>-->
      <text>账号密码登录</text>
    </view>
    <view class="login-form-content">
      <view class="input-item flex align-center">
        <view class="iconfont icon-user icon"></view>
        <input v-model="loginForm.username" class="input" type="text" placeholder="请输入账号" maxlength="30" />
                <up-input prefixIcon="account" placeholder="请输入账号" border="bottom"
                                    @blur="getUserLoginFacotryList"
                                    maxlength="30" v-model="loginForm.username" clearable></up-input>
      </view>
      <view class="input-item flex align-center">
        <view class="iconfont icon-password icon"></view>
        <input v-model="loginForm.password" type="password" class="input" placeholder="请输入密码" maxlength="20" />
                <up-input prefixIcon="lock" placeholder="请输入密码" border="bottom" maxlength="20" v-model="loginForm.password" clearable type="password"></up-input>
      </view>
      <view class="input-item flex align-center" style="width: 60%;margin: 0px;" v-if="captchaEnabled">
        <view class="iconfont icon-code icon"></view>
        <input v-model="loginForm.code" type="number" class="input" placeholder="请输入验证码" maxlength="4" />
        <view class="login-code">
          <image :src="codeUrl" @click="getCode" class="login-code-img"></image>
            <view class="input-item flex align-center select-container">
                <up-icon name="tags" size="18"></up-icon>
                <up-picker-data
                    v-model="loginForm.factoryId"
                    title="请选择公司"
                    :options="factoryList"
                    valueKey="id"
                    labelKey="name">
                </up-picker-data>
        </view>
      </view>
      <view class="action-btn">
      <view>
        <button @click="handleLogin" class="login-btn cu-btn block bg-blue lg round">登录</button>
      </view>
    </view>
    <view class="xieyi text-center">
      <text class="text-grey1">登录即代表同意</text>
      <text @click="handleUserAgrement" class="text-blue">《用户协议》</text>
      <text @click="handlePrivacy" class="text-blue">《隐私协议》</text>
        <!-- è®°ä½å¯†ç é€‰é¡¹ -->
        <view class="remember-password">
            <up-checkbox
                :customStyle="{marginBottom: '8px'}"
                label="记住密码"
                name="agree"
                usedAlone
                v-model:checked="rememberPassword"
            >
            </up-checkbox>
    </view>
  </view>
</template>
<script setup>
import modal from '@/plugins/modal'
import { getCodeImg } from '@/api/login'
import { ref } from "vue";
import config from '@/config.js'
import { userLoginFacotryList} from '@/api/login'
import { ref, onMounted } from "vue";
import useUserStore from '@/store/modules/user'
import { getWxCode } from '@/utils/geek';
import { wxLogin } from '@/api/oauth';
import { setToken } from '@/utils/auth';
const userStore = useUserStore()
const codeUrl = ref("");
const captchaEnabled = ref(true); // æ˜¯å¦å¼€å¯éªŒè¯ç 
const useWxLogin = ref(false); // æ˜¯å¦ä½¿ç”¨å¾®ä¿¡ç™»å½•
const globalConfig = ref(config);
const rememberPassword = ref(false); // è®°ä½å¯†ç 
const loginForm = ref({
  username: "admin",
  password: "admin123",
  code: "",
  uuid: ''
  username: "",
  password: "",
    factoryId: "",
    currentFatoryName: "",
});
const factoryList = ref([]) // å…¬å¸åˆ—表
// ä¿å­˜å¯†ç åˆ°æœ¬åœ°å­˜å‚¨
function savePassword() {
  if (rememberPassword.value) {
    uni.setStorageSync('remembered_username', loginForm.value.username);
    uni.setStorageSync('remembered_password', loginForm.value.password);
    uni.setStorageSync('remember_password', true);
  } else {
    uni.removeStorageSync('remembered_username');
    uni.removeStorageSync('remembered_password');
    uni.setStorageSync('remember_password', false);
  }
}
// ä»Žæœ¬åœ°å­˜å‚¨åŠ è½½å¯†ç 
function loadPassword() {
  const remembered = uni.getStorageSync('remember_password');
  if (remembered) {
    rememberPassword.value = true;
    const savedUsername = uni.getStorageSync('remembered_username');
    const savedPassword = uni.getStorageSync('remembered_password');
    if (savedUsername) {
      loginForm.value.username = savedUsername;
    }
    if (savedPassword) {
      loginForm.value.password = savedPassword;
    }
  }
}
if (useWxLogin.value) {
  getWxCode().then(res => {
@@ -67,25 +102,36 @@
  })
}
// èŽ·å–å›¾å½¢éªŒè¯ç 
function getCode() {
  getCodeImg().then(res => {
    captchaEnabled.value = res.captchaEnabled === undefined ? true : res.captchaEnabled
    if (captchaEnabled.value) {
      codeUrl.value = 'data:image/gif;base64,' + res.img
      loginForm.value.uuid = res.uuid
function getUserLoginFacotryList() {
    if(loginForm.value.username){
        userLoginFacotryList({userName:loginForm.value.username}).then(res => {
            // æ£€æŸ¥res.data是否为数组
            if (res.data && Array.isArray(res.data)) {
                // é‡æ–°ç»„装数据格式:deptId变成id,deptName变成name
                factoryList.value = res.data.map(item => ({
                    id: item.deptId,
                    name: item.deptName
                }))
            } else {
                // å¦‚æžœres.data不是数组,设置为空数组
                factoryList.value = []
    }
        }).catch(error => {
            modal.msgError('获取公司列表失败:', error)
            factoryList.value = []
  })
};
    }else {
        factoryList.value = []
    }
}
async function handleLogin() {
  if (loginForm.value.username === "") {
    modal.msgError("请输入您的账号")
  } else if (loginForm.value.password === "") {
    modal.msgError("请输入您的密码")
  } else if (loginForm.value.code === "" && captchaEnabled.value) {
    modal.msgError("请输入验证码")
  } else if (loginForm.value.factoryId === "") {
    modal.msgError("请选择公司")
  } else {
    modal.loading("登录中,请耐心等待...")
    pwdLogin()
@@ -93,14 +139,13 @@
};
// å¯†ç ç™»å½•
async function pwdLogin() {
  userStore.login(loginForm.value).then(() => {
  userStore.loginCheckFactory(loginForm.value).then(() => {
    modal.closeLoading()
    // ç™»å½•成功后保存密码
    savePassword();
    loginSuccess()
  }).catch(() => {
    if (captchaEnabled.value) {
      modal.closeLoading()
      getCode()
    }
  })
};
@@ -112,23 +157,11 @@
    });
  })
}
// éšç§åè®®
function handlePrivacy() {
  let site = globalConfig.value.appInfo.agreements[0];
  uni.navigateTo({
    url: `/pages/common/webview/index?title=${site.title}&url=${site.url}`
// é¡µé¢åŠ è½½æ—¶æ£€æŸ¥æ˜¯å¦æœ‰ä¿å­˜çš„å¯†ç 
onMounted(() => {
    loadPassword();
    getUserLoginFacotryList()
  });
};
// ç”¨æˆ·åè®®
function handleUserAgrement() {
  let site = globalConfig.value.appInfo.agreements[1]
  uni.navigateTo({
    url: `/pages/common/webview/index?title=${site.title}&url=${site.url}`
  });
};
getCode();
</script>
<style lang="scss">
@@ -141,9 +174,10 @@
  .logo-content {
    width: 100%;
    font-size: 21px;
    text-align: center;
    padding-top: 15%;
        font-weight: 400;
        font-size: 30px;
        color: #333333;
        margin: 80px 0 0 30px;
    image {
      border-radius: 4px;
@@ -153,18 +187,18 @@
      margin-left: 10px;
    }
  }
    .u-checkbox {
        margin-left: 34px;
    }
  .login-form-content {
    text-align: center;
    margin: 20px auto;
    margin-top: 15%;
    width: 80%;
    margin: 58px auto;
        padding: 0 30px;
    .input-item {
      margin: 20px auto;
      background-color: #f5f6f7;
       margin: 30px auto;
      height: 45px;
      border-radius: 20px;
      .icon {
        font-size: 38rpx;
@@ -179,12 +213,34 @@
        text-align: left;
        padding-left: 15px;
      }
     }
        .select-container {
            flex: 1;
            border-bottom: 1px solid #e5e5e5;
            padding: 6px 9px;
            :deep(.up-select) {
                border: none;
                background: transparent;
                .up-select__label {
                    font-size: 14px;
                    color: #333;
                }
                .up-select__value {
                    font-size: 14px;
                    color: #333;
                }
            }
    }
    .login-btn {
      margin-top: 40px;
      height: 45px;
      margin-top: 60px;
      height: 50px;
            background: linear-gradient( 140deg, #00BAFF 0%, #006CFB 100%);
            box-shadow: 0px 4px 10px 0px rgba(3,88,185,0.2);
            border-radius: 40px 40px 40px 40px;
    }
    .xieyi {
src/pages/splash.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,46 @@
<template>
  <div class="splash-container">
    <span class="title">科技</span>
    <span class="title1">便携生活</span>
  </div>
</template>
<script setup>
import { onMounted } from 'vue'
// #ifdef H5
import { useRouter } from 'vue-router'
const router = useRouter()
// #endif
onMounted(() => {
  setTimeout(() => {
    // #ifdef H5
    router.replace({ path: '/pages/login' })
    // #endif
    // #ifndef H5
    uni.reLaunch({ url: '/pages/login' })
    // #endif
  }, 2000)
})
</script>
<style scoped>
.splash-container {
  width: 100vw;
  height: 100vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  background: #fff;
}
.title {
  font-weight: 400;
  font-size: 60px;
  color: #000000;
}
.title1 {
  font-weight: 400;
  font-size: 40px;
  color: #000000;
}
</style>
src/store/modules/user.ts
@@ -1,4 +1,4 @@
import { login, logout, getInfo } from "@/api/login";
import {logout, getInfo, loginCheckFactory} from "@/api/login";
import { getToken, setToken, removeToken } from "@/utils/auth";
import defAva from "@/static/images/profile.jpg";
import { defineStore } from "pinia";
@@ -6,57 +6,61 @@
export interface LoginForm {
  username: string;
  password: string;
  code: string;
  uuid: string;
  factoryId: string;
}
const useUserStore = defineStore("user", {
  state: () => ({
    token: getToken(),
      id: "",
    name: "",
    avatar: "",
      currentFactoryName: "",
      nickName: "",
      roleName: "",
      currentDeptId: "",
      currentLoginTime: "",
    roles: Array(),
    permissions: [],
  }),
  actions: {
    // ç™»å½•
    login(userInfo: LoginForm) {
      const username = userInfo.username.trim();
      const password = userInfo.password;
      const code = userInfo.code;
      const uuid = userInfo.uuid;
      // éƒ¨é—¨ç™»å½•
      loginCheckFactory(userInfo: any) {
          const username = userInfo.username.trim()
          const password = userInfo.password
          const factoryId = userInfo.factoryId
      return new Promise((resolve, reject) => {
        login(username, password, code, uuid)
          .then((res: any) => {
            setToken(res.token);
            this.token = res.token;
            resolve(null);
              loginCheckFactory(username, password, factoryId).then((res: any) => {
                  setToken(res.token)
                  this.token = res.token
                  resolve(null)
              }).catch((error: any) => {
                  reject(error)
          })
          .catch((error) => {
            reject(error);
          });
      });
          })
    },
    // èŽ·å–ç”¨æˆ·ä¿¡æ¯
    getInfo() {
      return new Promise((resolve, reject) => {
        getInfo()
          .then((res: any) => {
            const user = res.user;
            const avatar =
              user.avatar == "" || user.avatar == null
                ? defAva
                : import.meta.env.VITE_APP_BASE_API + user.avatar;
            if (res.roles && res.roles.length > 0) {
              // éªŒè¯è¿”回的roles是否是一个非空数组
              this.roles = res.roles;
              this.permissions = res.permissions;
              const user = res.user
              let avatar = user.avatar || ""
              avatar = import.meta.env.VITE_APP_BASE_API + '/profile/' + avatar
              if (res.roles && res.roles.length > 0) { // éªŒè¯è¿”回的roles是否是一个非空数组
                  this.roles = res.roles
                  this.permissions = res.permissions
            } else {
              this.roles = ["ROLE_DEFAULT"];
                  this.roles = ['ROLE_DEFAULT']
            }
            this.name = user.userName;
            this.avatar = avatar;
              this.id = user.userId
              this.name = user.userName
              this.avatar = avatar
              this.currentFactoryName = user.currentFactoryName
              this.nickName = user.nickName
              this.roleName = user.roles[0].roleName
              this.currentDeptId = user.tenantId
              this.currentLoginTime = this.getCurrentTime()
            resolve(res);
          })
          .catch((error) => {
@@ -82,6 +86,16 @@
          });
      });
    },
      getCurrentTime() {
          const now = new Date();
          const year = now.getFullYear();       // èŽ·å–å¹´ä»½
          const month = String(now.getMonth() + 1).padStart(2, '0');  // æœˆä»½ä»Ž0开始,要+1,并补零
          const day = String(now.getDate()).padStart(2, '0');         // æ—¥æœŸè¡¥é›¶
          const hours = String(now.getHours()).padStart(2, '0');      // å°æ—¶è¡¥é›¶
          const minutes = String(now.getMinutes()).padStart(2, '0');  // åˆ†é’Ÿè¡¥é›¶
          const seconds = String(now.getSeconds()).padStart(2, '0');  // ç§’数补零
          return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
      },
  },
});
src/uni_modules/uni-scss/styles/setting/_variables.scss
@@ -1,4 +1,4 @@
// @use "sass:math";
// @import "sass:math";
@import  '../tools/functions.scss';
// é—´è·åŸºç¡€å€æ•°
$uni-space-root: 2 !default;
yarn.lock
ÎļþÌ«´ó