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 () => { 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 { query } = currRoute() console.error(query.redirect) uni.switchTab({ url: query.redirect }) // è®°ä½å¯ç if (rember.value) { configStore.setConfigInfo({ ...model, ...{ remberPassword: true } }) } const res = await login(model) accessStore.setAccessInfo(res as any) 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() 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 {