车间能级提升-智能设备管理系统
zhuguifei
2025-04-18 7db4e38c6d967d511f0c1248bf22ceaf6a6f55d3
配置http,完成登录信息缓存,添加部分pinia配置
已添加10个文件
已修改9个文件
284 ■■■■ 文件已修改
eims-ui-mobile/src/interceptors/request.ts 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui-mobile/src/pages/home/index.vue 19 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui-mobile/src/pages/login/index.vue 76 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui-mobile/src/service/login.d.ts 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui-mobile/src/service/login.ts 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui-mobile/src/service/menu.d.ts 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui-mobile/src/service/menu.ts 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui-mobile/src/static/images/menu1.png 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui-mobile/src/static/images/pic1.png 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui-mobile/src/static/images/pic2.jpg 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui-mobile/src/static/images/pic3.png 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui-mobile/src/static/images/pic4.jpeg 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui-mobile/src/static/menu/menu1.png 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui-mobile/src/static/menu/menu2.png 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui-mobile/src/store/access.ts 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui-mobile/src/store/index.ts 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui-mobile/src/store/system-config.ts 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui-mobile/src/store/user.ts 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui-mobile/src/utils/http.ts 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui-mobile/src/interceptors/request.ts
@@ -1,8 +1,9 @@
/* eslint-disable no-param-reassign */
import qs from 'qs'
import { useUserStore } from '@/store'
import { useAccessStore } from '@/store'
import { platform } from '@/utils/platform'
import { getEnvBaseUrl } from '@/utils'
const clientId = import.meta.env.VITE_APP_CLIENT_ID
export type CustomRequestOptions = UniApp.RequestOptions & {
  query?: Record<string, any>
@@ -50,10 +51,11 @@
      ...options.header,
    }
    // 3. æ·»åŠ  token è¯·æ±‚头标识
    const userStore = useUserStore()
    const { token } = userStore.userInfo as unknown as IUserInfo
    const accessStore = useAccessStore()
    const token = accessStore.accessInfo.access_token
    if (token) {
      options.header.Authorization = `Bearer ${token}`
      options.header.clientid = clientId
    }
  },
}
eims-ui-mobile/src/pages/home/index.vue
@@ -128,8 +128,7 @@
</template>
<script lang="ts" setup>
import { TestEnum } from '@/typings'
import PLATFORM from '@/utils/platform'
import { getAllMenusApi } from '@/service/menu'
defineOptions({
  name: 'Home',
@@ -137,14 +136,14 @@
// èŽ·å–å±å¹•è¾¹ç•Œåˆ°å®‰å…¨åŒºåŸŸè·ç¦»
const { safeAreaInsets } = uni.getSystemInfoSync()
const author = ref('菲鸽')
const description = ref(
  'unibest æ˜¯ä¸€ä¸ªé›†æˆäº†å¤šç§å·¥å…·å’ŒæŠ€æœ¯çš„ uniapp å¼€å‘模板,由 uniapp + Vue3 + Ts + Vite4 + UnoCss + UniUI + VSCode æž„建,模板具有代码提示、自动格式化、统一配置、代码片段等功能,并内置了许多常用的基本组件和基本功能,让你编写 uniapp æ‹¥æœ‰ best ä½“验。',
)
// æµ‹è¯• uni API è‡ªåЍ引入
const getAllMenus = async () => {
  const menuList = await getAllMenusApi()
  console.error(menuList)
}
onLoad(() => {
  console.log(author)
  console.log(TestEnum.A)
  // getAllMenus()
})
const menuList = reactive([
@@ -161,7 +160,7 @@
])
function handleUserInfo() {
  console.error('12121')
  getAllMenus()
}
eims-ui-mobile/src/pages/login/index.vue
@@ -13,7 +13,7 @@
    <wd-cell-group border>
      <wd-input
        label="用户名"
        label-width="100px"
        label-width="200rpx"
        prop="username"
        clearable
        v-model="model.username"
@@ -22,7 +22,7 @@
      />
      <wd-input
        label="密码"
        label-width="100px"
        label-width="200rpx"
        prop="password"
        show-password
        clearable
@@ -31,28 +31,43 @@
        :rules="[{ required: true, message: '请填写密码' }]"
      />
    </wd-cell-group>
    <view class="footer mt-6">
      <wd-button type="primary" size="large" @click="handleSubmit" block>提交</wd-button>
    <view class="footer">
      <view class="w-full text-end">
        <wd-checkbox v-model="rember" shape="square" @change="handleChange">
          è®°ä½å¯†ç 
        </wd-checkbox>
      </view>
      <wd-button class="mt-6" type="primary" size="large" @click="handleSubmit" block>
        æäº¤
      </wd-button>
    </view>
  </wd-form>
</template>
<script setup lang="ts">
import { currRoute } from '@/utils'
import { useUserStore, useAccessStore } from '@/store'
import { useUserStore, useAccessStore, useSystemConfigStore } from '@/store'
import { useToast } from 'wot-design-uni'
import { login } from '@/service/login'
import { login, getUserInfo } from '@/service/login'
import type { UserInfo } from '@/service/login.d'
import { TestEnum } from '@/typings'
const userStore = useUserStore()
const accessStore = useAccessStore()
const configStore = useSystemConfigStore()
const { success: showSuccess } = useToast()
const model = reactive<{
  username: string
  password: string
}>({
  username: 'admin',
  password: 'admin123',
  username: '',
  password: '',
})
const rember = ref<boolean>(false)
function handleChange({ value }) {
  console.log(value)
}
const form = ref()
function handleSubmit() {
@@ -67,21 +82,48 @@
      console.log(error, 'error')
    })
}
onLoad(() => {
  const { remberPassword, username, password } = configStore.systemConfigInfo
  if (remberPassword) {
    rember.value = true
    model.username = username
    model.password = password
  }
})
const toLogin = async () => {
  // è®°ä½å¯†ç 
  if (rember.value) {
    configStore.setConfigInfo({ ...model, ...{ remberPassword: true } })
  }
  const res = await login(model)
  console.error(res)
  accessStore.setAccessInfo(res as any)
  console.error(accessStore.accessInfo.access_token)
  // userStore.setUserInfo({ nickname: '菲鸽', avatar: '', token: 'abcdef' })
  const backUserInfo: any = await getUserInfo()
  /**
   * ç™»å½•超时的情况
   */
  if (!backUserInfo) {
    throw new Error('获取用户信息失败.')
  }
  const { permissions = [], roles = [], user } = backUserInfo
  /**
   * ä»ŽåŽå°user -> vben user转换
   */
  const userInfo: UserInfo = {
    avatar: user.avatar ?? '',
    permissions,
    realName: user.nickName,
    roles,
    userId: user.userId,
    deptId: user.deptId,
    username: user.userName,
  }
  userStore.setUserInfo(userInfo)
  const { query } = currRoute()
  console.error(query.redirect)
  uni.switchTab({ url: query.redirect })
}
</script>
<style scoped lang="scss">
eims-ui-mobile/src/service/login.d.ts
@@ -5,3 +5,74 @@
  tenantId?: string;
  grantType?: string;
}
export interface User {
  avatar: string;
  createTime: string;
  deptId: number;
  deptName: string;
  email: string;
  loginDate: string;
  loginIp: string;
  nickName: string;
  phonenumber: string;
  remark: string;
  roles: Role[];
  sex: string;
  status: string;
  tenantId: string;
  userId: number;
  userName: string;
  userType: string;
}
export interface UserInfoResp {
  permissions: string[];
  roles: string[];
  user: User;
}
interface BasicUserInfo {
  /**
   * å¤´åƒ
   */
  avatar: string;
  /**
   * éƒ¨é—¨id
   */
  deptId: number;
  /**
   * ç”¨æˆ·æƒé™
   */
  permissions: string[];
  /**
   * ç”¨æˆ·æ˜µç§°
   */
  realName: string;
  /**
   * ç”¨æˆ·è§’色
   */
  roles: string[];
  /**
   * ç”¨æˆ·id
   */
  userId: number | string;
  /**
   * ç”¨æˆ·å
   */
  username: string;
}
/** ç”¨æˆ·ä¿¡æ¯ */
interface UserInfo extends BasicUserInfo {
  /**
   * æ‹“展使用
   */
  [key: string]: any;
}
eims-ui-mobile/src/service/login.ts
@@ -1,16 +1,11 @@
import { http } from '@/utils/http'
import type { LoginParams } from './login.d'
import type { LoginParams, UserInfoResp } from './login.d'
const clientId = import.meta.env.VITE_APP_CLIENT_ID
const DEFAULT_TENANT_ID = '000000'
const GRANT_TYPE = 'password'
/** GET è¯·æ±‚ */
export const getFooAPI = (name: string) => {
  return http.get<LoginParams>('/foo', { name })
}
/** POST è¯·æ±‚ */
/** get è¯·æ±‚ */
export const login = (params: LoginParams) => {
  const { username, password } = params
  // æž„造新的请求参数,避免直接修改原始对象
@@ -23,3 +18,7 @@
  }
  return http.post<any>('/auth/login', requestData)
}
export const getUserInfo = () => {
  return http.get<null | UserInfoResp>('/system/user/getInfo')
}
eims-ui-mobile/src/service/menu.d.ts
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,36 @@
/**
 * @description: èœå•meta
 * @param title èœå•名
 * @param icon èœå•图标
 * @param noCache æ˜¯å¦ä¸ç¼“å­˜
 * @param link å¤–链链接
 */
export interface MenuMeta {
  icon: string;
  link?: string;
  noCache: boolean;
  title: string;
}
/**
 * @description: èœå•
 * @param name èœå•名
 * @param path èœå•路径
 * @param hidden æ˜¯å¦éšè—
 * @param component ç»„件名称 Laout
 * @param alwaysShow æ€»æ˜¯æ˜¾ç¤º
 * @param query è·¯ç”±å‚æ•°(json形式)
 * @param meta è·¯ç”±ä¿¡æ¯
 * @param children å­è·¯ç”±ä¿¡æ¯
 */
export interface Menu {
  alwaysShow?: boolean;
  children: Menu[];
  component: string;
  hidden: boolean;
  meta: MenuMeta;
  name: string;
  path: string;
  query?: string;
  redirect?: string;
}
eims-ui-mobile/src/service/menu.ts
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,6 @@
import { http } from '@/utils/http'
import type { Menu } from './menu.d'
export const getAllMenusApi = () => {
  return http.get<Menu>('/system/menu/getRouters')
}
eims-ui-mobile/src/static/images/menu1.png
eims-ui-mobile/src/static/images/pic1.png
eims-ui-mobile/src/static/images/pic2.jpg
eims-ui-mobile/src/static/images/pic3.png
eims-ui-mobile/src/static/images/pic4.jpeg
eims-ui-mobile/src/static/menu/menu1.png
eims-ui-mobile/src/static/menu/menu2.png
eims-ui-mobile/src/store/access.ts
@@ -44,7 +44,7 @@
}
export const useAccessStore = defineStore(
  'access',
  'accessInfo',
  () => {
    const accessInfo = ref<AccessInfo>({ ...initState })
eims-ui-mobile/src/store/index.ts
@@ -16,3 +16,4 @@
// æ¨¡å—统一导出
export * from './user'
export * from './access'
export * from './system-config'
eims-ui-mobile/src/store/system-config.ts
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,37 @@
import { defineStore } from 'pinia'
import { ref } from 'vue'
const initState = {
  remberPassword: false,
  username: '',
  password: '',
}
export const useSystemConfigStore = defineStore(
  'systemConfig',
  () => {
    const systemConfigInfo = ref<any>({ ...initState })
    const setConfigInfo = (val: any) => {
      systemConfigInfo.value = val
    }
    const clearConfigInfo = () => {
      systemConfigInfo.value = { ...initState }
    }
    // ä¸€èˆ¬æ²¡æœ‰reset需求,不需要的可以删除
    const reset = () => {
      systemConfigInfo.value = { ...initState }
    }
    return {
      systemConfigInfo,
      setConfigInfo,
      clearConfigInfo,
      reset,
    }
  },
  {
    persist: true,
  },
)
eims-ui-mobile/src/store/user.ts
@@ -1,14 +1,15 @@
import { defineStore } from 'pinia'
import { ref } from 'vue'
import type { UserInfoResp, UserInfo } from '@/service/login.d'
const initState = { nickname: '', avatar: '' }
const initState = null
export const useUserStore = defineStore(
  'user',
  'userInfo',
  () => {
    const userInfo = ref<IUserInfo>({ ...initState })
    const userInfo = ref<UserInfo>({ ...initState })
    const setUserInfo = (val: IUserInfo) => {
    const setUserInfo = (val: UserInfo) => {
      userInfo.value = val
    }
@@ -19,13 +20,11 @@
    const reset = () => {
      userInfo.value = { ...initState }
    }
    const isLogined = computed(() => !!userInfo.value.token)
    return {
      userInfo,
      setUserInfo,
      clearUserInfo,
      isLogined,
      reset,
    }
  },
eims-ui-mobile/src/utils/http.ts
@@ -1,4 +1,5 @@
import { CustomRequestOptions } from '@/interceptors/request'
import { useUserStore, useAccessStore } from '@/store'
export const http = <T>(options: CustomRequestOptions) => {
  // 1. è¿”回 Promise å¯¹è±¡
@@ -24,7 +25,8 @@
          }
        } else if (res.statusCode === 401) {
          // 401错误  -> æ¸…理用户信息,跳转到登录页
          // userStore.clearUserInfo()
          useAccessStore().clearAccessInfo()
          useUserStore().clearUserInfo()
          uni.navigateTo({ url: '/pages/login/index' })
          reject(res)
        } else {