chenxiaochao vor 3 Wochen
Ursprung
Commit
750bc11142

+ 0 - 0
ceshi.txt


+ 1 - 1
env/.env.development

6
 VITE_SHOW_SOURCEMAP = false
6
 VITE_SHOW_SOURCEMAP = false
7
 
7
 
8
 # 后台请求地址
8
 # 后台请求地址
9
-VITE_SERVER_BASEURL = 'http://192.168.1.15:8080'
9
+VITE_SERVER_BASEURL = 'http://39.164.159.226:8088'

+ 12 - 12
src/App.vue

1
 <script setup lang="ts">
1
 <script setup lang="ts">
2
 import { onHide, onLaunch, onShow } from '@dcloudio/uni-app'
2
 import { onHide, onLaunch, onShow } from '@dcloudio/uni-app'
3
 import { navigateToInterceptor } from '@/router/interceptor'
3
 import { navigateToInterceptor } from '@/router/interceptor'
4
-import { useTokenStore } from '@/store/token'
5
 import { useAuthStore } from '@/store/auth'
4
 import { useAuthStore } from '@/store/auth'
5
+import { useTokenStore } from '@/store/token'
6
 
6
 
7
 onLaunch((options) => {
7
 onLaunch((options) => {
8
   console.log('App.vue onLaunch', options)
8
   console.log('App.vue onLaunch', options)
9
   // 初始化 store
9
   // 初始化 store
10
   const tokenStore = useTokenStore()
10
   const tokenStore = useTokenStore()
11
   const authStore = useAuthStore()
11
   const authStore = useAuthStore()
12
-  
12
+
13
   // 钉钉免登录逻辑
13
   // 钉钉免登录逻辑
14
   async function handleDingTalkAutoLogin() {
14
   async function handleDingTalkAutoLogin() {
15
     try {
15
     try {
16
       // 检查是否已经有有效的token
16
       // 检查是否已经有有效的token
17
       if (!tokenStore.isTokenExpired.value) {
17
       if (!tokenStore.isTokenExpired.value) {
18
-        console.log('已有有效登录状态,无需重新登录');
19
-        return;
18
+        console.log('已有有效登录状态,无需重新登录')
19
+        return
20
       }
20
       }
21
-      
22
-      console.log('尝试钉钉免登录...');
21
+
22
+      console.log('尝试钉钉免登录...')
23
       // 尝试钉钉免登录
23
       // 尝试钉钉免登录
24
-      await authStore.authDingTalkLogin();
25
-      console.log('钉钉免登录成功');
24
+      await authStore.authDingTalkLogin()
25
+      console.log('钉钉免登录成功')
26
     }
26
     }
27
     catch (error) {
27
     catch (error) {
28
-      console.error('钉钉免登录失败,将跳转到登录页面:', error);
28
+      console.error('钉钉免登录失败,将跳转到登录页面:', error)
29
       // 免登录失败,跳转到登录页面
29
       // 免登录失败,跳转到登录页面
30
       // 注意:这里不立即跳转,避免影响应用启动性能
30
       // 注意:这里不立即跳转,避免影响应用启动性能
31
       // 路由拦截器会在页面跳转时处理未登录情况
31
       // 路由拦截器会在页面跳转时处理未登录情况
32
     }
32
     }
33
   }
33
   }
34
-  
34
+
35
   // 执行钉钉免登录
35
   // 执行钉钉免登录
36
-  handleDingTalkAutoLogin();
36
+  handleDingTalkAutoLogin()
37
 })
37
 })
38
 onShow((options) => {
38
 onShow((options) => {
39
-  console.log('App.vue onShow', options)
39
+  // console.log('App.vue onShow', options)
40
   // 处理直接进入页面路由的情况:如h5直接输入路由、微信小程序分享后进入等
40
   // 处理直接进入页面路由的情况:如h5直接输入路由、微信小程序分享后进入等
41
   // https://github.com/unibest-tech/unibest/issues/192
41
   // https://github.com/unibest-tech/unibest/issues/192
42
   if (options?.path) {
42
   if (options?.path) {

+ 1 - 1
src/api/auth.ts

25
  */
25
  */
26
 export function login(loginForm: ILoginForm) {
26
 export function login(loginForm: ILoginForm) {
27
   return http.post<IAuthLoginRes>('/login', loginForm)
27
   return http.post<IAuthLoginRes>('/login', loginForm)
28
-}
28
+}

+ 4 - 4
src/api/login.ts

94
   return new Promise<{ code: string }>((resolve, reject) => {
94
   return new Promise<{ code: string }>((resolve, reject) => {
95
     // #ifdef H5
95
     // #ifdef H5
96
     // H5环境下,模拟获取code,实际项目中可能需要通过URL参数或其他方式获取
96
     // H5环境下,模拟获取code,实际项目中可能需要通过URL参数或其他方式获取
97
-    console.warn('H5环境下,需要手动传入钉钉code');
98
-    resolve({ code: 'mock-dingtalk-code' });
97
+    console.warn('H5环境下,需要手动传入钉钉code')
98
+    resolve({ code: 'mock-dingtalk-code' })
99
     // #endif
99
     // #endif
100
     // #ifdef APP-PLUS
100
     // #ifdef APP-PLUS
101
     // 钉钉小程序环境下,调用钉钉SDK获取code
101
     // 钉钉小程序环境下,调用钉钉SDK获取code
102
     plus.dingtalk.getAuthCode({
102
     plus.dingtalk.getAuthCode({
103
       success: (res: { code: string }) => resolve(res),
103
       success: (res: { code: string }) => resolve(res),
104
-      fail: (err: any) => reject(new Error(JSON.stringify(err)))
105
-    });
104
+      fail: (err: any) => reject(new Error(JSON.stringify(err))),
105
+    })
106
     // #endif
106
     // #endif
107
   })
107
   })
108
 }
108
 }

+ 1 - 1
src/locale/index.ts

37
 
37
 
38
   try {
38
   try {
39
     const keyList = key.split('.')
39
     const keyList = key.split('.')
40
-    let result = keyList.reduce((pre, cur) => {
40
+    const result = keyList.reduce((pre, cur) => {
41
       return pre && typeof pre === 'object' ? pre[cur] : undefined
41
       return pre && typeof pre === 'object' ? pre[cur] : undefined
42
     }, message)
42
     }, message)
43
     // 确保返回的是字符串类型
43
     // 确保返回的是字符串类型

+ 1 - 1
src/pages-fg/login/login.vue

220
 
220
 
221
       <!-- 登录按钮 -->
221
       <!-- 登录按钮 -->
222
       <view class="login-actions">
222
       <view class="login-actions">
223
-        <wd-button type="primary" block round :loading="authStore.loginLoading" @click="validateForm">
223
+        <wd-button type="primary" round block :loading="authStore.loginLoading" @click="validateForm">
224
           {{ authStore.loginLoading ? '登录中...' : '登录' }}
224
           {{ authStore.loginLoading ? '登录中...' : '登录' }}
225
         </wd-button>
225
         </wd-button>
226
       </view>
226
       </view>

+ 37 - 25
src/pages/index/index.vue

30
   children?: MenuItem[]
30
   children?: MenuItem[]
31
   /** 图标颜色 */
31
   /** 图标颜色 */
32
   iconColor?: string
32
   iconColor?: string
33
+  /** 组件路径 */
34
+  component?: string
35
+  /** 元信息 */
36
+  meta?: {
37
+    /** 标题 */
38
+    title?: string
39
+    /** 图标 */
40
+    icon?: string
41
+  }
33
 }
42
 }
34
 
43
 
35
 // 菜单数据
44
 // 菜单数据
49
     const response = await http<MenuItem[]>({
58
     const response = await http<MenuItem[]>({
50
       url: '/getRouters',
59
       url: '/getRouters',
51
       method: 'GET',
60
       method: 'GET',
61
+      data: {
62
+        source: 1,
63
+      }
52
     })
64
     })
53
     menuData.value = response.data
65
     menuData.value = response.data
54
     console.log('菜单数据:', response)
66
     console.log('菜单数据:', response)
55
   } catch (err) {
67
   } catch (err) {
68
+
56
     console.error('获取菜单失败:', err)
69
     console.error('获取菜单失败:', err)
57
     // 接口调用失败时使用mock数据
70
     // 接口调用失败时使用mock数据
58
     // menuData.value = mockMenuData
71
     // menuData.value = mockMenuData
76
     url: '/pages/schedule/view/index',
89
     url: '/pages/schedule/view/index',
77
   })
90
   })
78
   // 根据菜单ID执行相应操作
91
   // 根据菜单ID执行相应操作
79
-  // if (menu.url) {
80
-  //   uni.navigateTo({
81
-  //     url: menu.url,
82
-  //   })
83
-  // } else {
84
-  //   uni.showToast({
85
-  //     title: `点击了${menu.meta?.title || menu.name}`,
86
-  //     icon: 'none',
87
-  //   })
88
-  // }
92
+
93
+  if (menu.component) {
94
+    console.log('component:', menu.component)
95
+    uni.navigateTo({
96
+      url: menu.component,
97
+    })
98
+  }
99
+  else {
100
+    uni.showToast({
101
+      title: `点击了${menu.meta?.title || menu.name}`,
102
+      icon: 'none',
103
+    })
104
+  }
89
 }
105
 }
90
 onMounted(async () => {
106
 onMounted(async () => {
91
   // fetchMenuData()
107
   // fetchMenuData()
100
     <!-- 菜单内容 -->
116
     <!-- 菜单内容 -->
101
     <view class="p-2">
117
     <view class="p-2">
102
       <block v-if="loading">
118
       <block v-if="loading">
103
-        <view class="text-center p-16">
104
-          <wd-loading size="large" type="ring"></wd-loading>
105
-          <text class="text-gray-500 text-sm mt-4 inline-block">加载中...</text>
119
+        <view class="p-16 text-center">
120
+          <wd-loading size="large" type="ring" />
121
+          <text class="mt-4 inline-block text-sm text-gray-500">加载中...</text>
106
         </view>
122
         </view>
107
       </block>
123
       </block>
108
       <block v-else-if="error">
124
       <block v-else-if="error">
109
-        <view class="text-center p-16">
110
-          <wd-icon name="info-circle" size="60" color="#909399"></wd-icon>
111
-          <text class="text-gray-500 text-sm mt-4 inline-block">{{
112
-            error
113
-          }}</text>
125
+
126
+        <view class="p-16 text-center">
127
+          <wd-icon name="info-circle" size="60" color="#909399" />
128
+          <text class="mt-4 inline-block text-sm text-gray-500">{{ error }}</text>
114
         </view>
129
         </view>
115
       </block>
130
       </block>
116
       <block v-else>
131
       <block v-else>
126
             <wd-grid-item
141
             <wd-grid-item
127
               v-for="item in group.children"
142
               v-for="item in group.children"
128
               :key="item.id"
143
               :key="item.id"
129
-              @click="handleMenuItemClick(item)"
130
               class="menu-item"
144
               class="menu-item"
145
+              @click="handleMenuItemClick(item)"
131
             >
146
             >
132
               <wd-card
147
               <wd-card
133
                 size="small"
148
                 size="small"
134
                 :border="false"
149
                 :border="false"
135
                 class="menu-card"
150
                 class="menu-card"
136
-                :style="{
137
-                  backgroundColor: (item.iconColor || '#4CAF50') + '20',
138
-                }"
151
+                :style="{ backgroundColor: `${item.iconColor || '#4CAF50'}20` }"
139
               >
152
               >
140
                 <wd-icon
153
                 <wd-icon
141
                   :name="item.meta?.icon || item.icon"
154
                   :name="item.meta?.icon || item.icon"
143
                   size="30"
156
                   size="30"
144
                 />
157
                 />
145
               </wd-card>
158
               </wd-card>
146
-              <text class="text-xs text-center mt-1">{{
147
-                item.meta?.title || item.name
148
-              }}</text>
159
+              <text class="mt-1 text-center text-xs">{{ item.meta?.title || item.name }}</text>
149
             </wd-grid-item>
160
             </wd-grid-item>
150
           </wd-grid>
161
           </wd-grid>
151
         </wd-card>
162
         </wd-card>
174
   padding: 0;
185
   padding: 0;
175
 }
186
 }
176
 </style>
187
 </style>
188
+

+ 8 - 8
src/pages/me/me.vue

1
 <script lang="ts" setup>
1
 <script lang="ts" setup>
2
 import { storeToRefs } from 'pinia'
2
 import { storeToRefs } from 'pinia'
3
-import { ref } from 'vue'
4
 import { LOGIN_PAGE } from '@/router/config'
3
 import { LOGIN_PAGE } from '@/router/config'
5
 import { useUserStore } from '@/store'
4
 import { useUserStore } from '@/store'
6
 import { useTokenStore } from '@/store/token'
5
 import { useTokenStore } from '@/store/token'
7
 
6
 
8
-
9
 definePage({
7
 definePage({
10
   style: {
8
   style: {
11
     navigationBarTitleText: '我的',
9
     navigationBarTitleText: '我的',
40
     'data-board': '动',
38
     'data-board': '动',
41
     'star': '收',
39
     'star': '收',
42
     'customer-service': '客',
40
     'customer-service': '客',
43
-    'setting': '设'
41
+    'setting': '设',
44
   }
42
   }
45
   return iconMap[iconName] || iconName.charAt(0)
43
   return iconMap[iconName] || iconName.charAt(0)
46
 }
44
 }
48
 function handleFeature(featureName: string) {
46
 function handleFeature(featureName: string) {
49
   uni.showToast({
47
   uni.showToast({
50
     title: `点击了${featureName}`,
48
     title: `点击了${featureName}`,
51
-    icon: 'none'
49
+    icon: 'none',
52
   })
50
   })
53
 }
51
 }
54
 
52
 
81
         })
79
         })
82
         // 使用reLaunch清除所有页面栈并跳转到登录页
80
         // 使用reLaunch清除所有页面栈并跳转到登录页
83
         uni.reLaunch({
81
         uni.reLaunch({
84
-          url: LOGIN_PAGE
82
+          url: LOGIN_PAGE,
85
         })
83
         })
86
       }
84
       }
87
     },
85
     },
100
         </view>
98
         </view>
101
         <!-- 右侧人员信息 -->
99
         <!-- 右侧人员信息 -->
102
         <view class="user-details">
100
         <view class="user-details">
103
-          <view class="username">{{ userInfo.nickname || '游客' }}</view>
101
+          <view class="username">
102
+            {{ userInfo.nickname || '游客' }}
103
+          </view>
104
           <view class="user-meta">
104
           <view class="user-meta">
105
             <text class="user-role">{{ userInfo.username || '普通用户' }}</text>
105
             <text class="user-role">{{ userInfo.username || '普通用户' }}</text>
106
           </view>
106
           </view>
117
         </view>
117
         </view>
118
         <view class="feature-right">
118
         <view class="feature-right">
119
           <text v-if="item.badge" class="feature-badge">{{ item.badge }}</text>
119
           <text v-if="item.badge" class="feature-badge">{{ item.badge }}</text>
120
-          <text v-if="item.dot" class="notification-dot"></text>
120
+          <text v-if="item.dot" class="notification-dot" />
121
           <text class="arrow">></text>
121
           <text class="arrow">></text>
122
         </view>
122
         </view>
123
       </view>
123
       </view>
124
     </view>
124
     </view>
125
     <!-- 退出登录按钮 -->
125
     <!-- 退出登录按钮 -->
126
-    <view class="logout-section px-4 mb-8">
126
+    <view class="logout-section mb-8 px-4">
127
       <button v-if="tokenStore.hasLogin" type="primary" class="w-full" @click="handleLogout">
127
       <button v-if="tokenStore.hasLogin" type="primary" class="w-full" @click="handleLogout">
128
         退出登录
128
         退出登录
129
       </button>
129
       </button>

+ 8 - 8
src/store/auth.ts

67
      */
67
      */
68
     const authDingTalkLogin = async (code?: string) => {
68
     const authDingTalkLogin = async (code?: string) => {
69
       try {
69
       try {
70
-        loginLoading.value = true;
71
-        const res = await tokenStore.dingTalkLogin(code);
70
+        loginLoading.value = true
71
+        const res = await tokenStore.dingTalkLogin(code)
72
         uni.showToast({
72
         uni.showToast({
73
           title: '登录成功',
73
           title: '登录成功',
74
           icon: 'success',
74
           icon: 'success',
75
-        });
76
-        return res;
75
+        })
76
+        return res
77
       }
77
       }
78
       catch (error) {
78
       catch (error) {
79
-        console.error('钉钉登录失败:', error);
79
+        console.error('钉钉登录失败:', error)
80
         uni.showToast({
80
         uni.showToast({
81
           title: '钉钉登录失败,请重试',
81
           title: '钉钉登录失败,请重试',
82
           icon: 'error',
82
           icon: 'error',
83
-        });
84
-        throw error;
83
+        })
84
+        throw error
85
       }
85
       }
86
       finally {
86
       finally {
87
-        loginLoading.value = false;
87
+        loginLoading.value = false
88
       }
88
       }
89
     }
89
     }
90
 
90
 

+ 12 - 12
src/store/token.ts

5
 import { defineStore } from 'pinia'
5
 import { defineStore } from 'pinia'
6
 import { computed, ref } from 'vue' // 修复:导入 computed
6
 import { computed, ref } from 'vue' // 修复:导入 computed
7
 import {
7
 import {
8
+  dingTalkLogin as _dingTalkLogin,
8
   login as _login,
9
   login as _login,
9
   logout as _logout,
10
   logout as _logout,
10
   refreshToken as _refreshToken,
11
   refreshToken as _refreshToken,
11
   wxLogin as _wxLogin,
12
   wxLogin as _wxLogin,
12
-  getWxCode,
13
-  dingTalkLogin as _dingTalkLogin,
14
   getDingTalkCode,
13
   getDingTalkCode,
14
+  getWxCode,
15
 } from '@/api/login'
15
 } from '@/api/login'
16
 import { isDoubleTokenRes, isSingleTokenRes } from '@/api/types/login'
16
 import { isDoubleTokenRes, isSingleTokenRes } from '@/api/types/login'
17
 import { useUserStore } from './user'
17
 import { useUserStore } from './user'
192
     const dingTalkLogin = async (code?: string) => {
192
     const dingTalkLogin = async (code?: string) => {
193
       try {
193
       try {
194
         // 如果没有传入code,则自动获取
194
         // 如果没有传入code,则自动获取
195
-        const authCode = code || (await getDingTalkCode()).code;
196
-        console.log('钉钉登录-code: ', authCode);
197
-        const res = await _dingTalkLogin(authCode);
198
-        console.log('钉钉登录-res: ', res);
199
-        await _postLogin(res);
195
+        const authCode = code || (await getDingTalkCode()).code
196
+        console.log('钉钉登录-code: ', authCode)
197
+        const res = await _dingTalkLogin(authCode)
198
+        console.log('钉钉登录-res: ', res)
199
+        await _postLogin(res)
200
         uni.showToast({
200
         uni.showToast({
201
           title: '登录成功',
201
           title: '登录成功',
202
           icon: 'success',
202
           icon: 'success',
203
-        });
204
-        return res;
203
+        })
204
+        return res
205
       }
205
       }
206
       catch (error) {
206
       catch (error) {
207
-        console.error('钉钉登录失败:', error);
207
+        console.error('钉钉登录失败:', error)
208
         uni.showToast({
208
         uni.showToast({
209
           title: '钉钉登录失败,请重试',
209
           title: '钉钉登录失败,请重试',
210
           icon: 'error',
210
           icon: 'error',
211
-        });
212
-        throw error;
211
+        })
212
+        throw error
213
       }
213
       }
214
     }
214
     }
215
 
215
 

+ 0 - 3
src/utils/i18n.ts

1
-import { t } from '@/locale/index'
2
-
3
 /** 非vue 文件使用 i18n */
1
 /** 非vue 文件使用 i18n */
4
 export function testI18n() {
2
 export function testI18n() {
5
   // 下面同样生效
3
   // 下面同样生效
6
   uni.showModal({
4
   uni.showModal({
7
     title: 'i18n 测试',
5
     title: 'i18n 测试',
8
-    content: t('i18n.title'),
9
   })
6
   })
10
 }
7
 }