Jelajahi Sumber

流程设计表单描述加高行

pm 4 bulan lalu
induk
melakukan
2f5bd38f89
5 mengubah file dengan 175 tambahan dan 118 penghapusan
  1. 31 2
      src/App.tsx
  2. 1 1
      src/components/IsolationWork.tsx
  3. 42 0
      src/components/MyTask.tsx
  4. 95 115
      src/utils/auth.ts
  5. 6 0
      src/views/Login.tsx

+ 31 - 2
src/App.tsx

@@ -4,18 +4,47 @@ import { startTokenCheck, stopTokenCheck, getRefreshToken } from './utils/auth';
 
 export default function App() {
   useEffect(() => {
+    console.log('[App] 组件挂载,检查是否需要启动token检测');
+    
     // 如果用户已登录(有refreshToken),启动token定期检测
     const refreshToken = getRefreshToken();
+    console.log('[App] refreshToken存在:', !!refreshToken);
+    
     if (refreshToken) {
-      // 每10秒检测一次token是否失效
-      startTokenCheck(10);
+      // 每隔1秒检测一次token是否失效
+      console.log('[App] 启动token检测');
+      startTokenCheck(1);
+    } else {
+      console.log('[App] 没有refreshToken,不启动token检测');
     }
 
     // 组件卸载时清除定时器
     return () => {
+      console.log('[App] 组件卸载,清除token检测定时器');
       stopTokenCheck();
     };
   }, []);
+  
+  // 监听refreshToken的变化,如果登录后refreshToken被设置,启动检测
+  useEffect(() => {
+    const checkAndStart = () => {
+      const refreshToken = getRefreshToken();
+      if (refreshToken) {
+        console.log('[App] 检测到refreshToken,启动token检测');
+        startTokenCheck(1);
+      }
+    };
+    
+    // 立即检查一次
+    checkAndStart();
+    
+    // 每2秒检查一次refreshToken是否存在(用于登录后启动检测)
+    const checkInterval = setInterval(checkAndStart, 2000);
+    
+    return () => {
+      clearInterval(checkInterval);
+    };
+  }, []);
 
   return (
     <div>

+ 1 - 1
src/components/IsolationWork.tsx

@@ -2987,7 +2987,7 @@ export default function IsolationWork({ subMenu }: IsolationWorkProps) {
                 label="描述"
                 name="description"
               >
-                <Input.TextArea rows={4} placeholder="请输入描述" />
+                <Input.TextArea rows={10} placeholder="请输入描述" />
               </Form.Item>
             </Form>
           </Modal>

+ 42 - 0
src/components/MyTask.tsx

@@ -1275,6 +1275,27 @@ export default function MyTask() {
                               return;
                             }
                             
+                            // 如果有自定义表单,先校验表单
+                            if (formData.rule && formData.rule.length > 0) {
+                              try {
+                                // 校验表单所有字段
+                                await detailForm.validateFields();
+                                console.log('MyTask: 表单校验通过');
+                              } catch (error: any) {
+                                // 校验失败,显示错误信息
+                                console.error('MyTask: 表单校验失败', error);
+                                if (error.errorFields && error.errorFields.length > 0) {
+                                  // 获取第一个错误字段的提示信息
+                                  const firstError = error.errorFields[0];
+                                  const errorMessage = firstError.errors?.[0] || '请完善表单内容';
+                                  message.error(errorMessage);
+                                } else {
+                                  message.error('请完善表单内容');
+                                }
+                                return; // 阻止提交
+                              }
+                            }
+                            
                             setApprovalLoading(true);
                             try {
                               const params: UpdateNodeApprovalParam = {
@@ -1320,6 +1341,27 @@ export default function MyTask() {
                               return;
                             }
                             
+                            // 如果有自定义表单,先校验表单
+                            if (formData.rule && formData.rule.length > 0) {
+                              try {
+                                // 校验表单所有字段
+                                await detailForm.validateFields();
+                                console.log('MyTask: 表单校验通过');
+                              } catch (error: any) {
+                                // 校验失败,显示错误信息
+                                console.error('MyTask: 表单校验失败', error);
+                                if (error.errorFields && error.errorFields.length > 0) {
+                                  // 获取第一个错误字段的提示信息
+                                  const firstError = error.errorFields[0];
+                                  const errorMessage = firstError.errors?.[0] || '请完善表单内容';
+                                  message.error(errorMessage);
+                                } else {
+                                  message.error('请完善表单内容');
+                                }
+                                return; // 阻止提交
+                              }
+                            }
+                            
                             setApprovalLoading(true);
                             try {
                               const params: UpdateNodeApprovalParam = {

+ 95 - 115
src/utils/auth.ts

@@ -221,18 +221,25 @@ let tokenCheckInterval: NodeJS.Timeout | null = null;
 let isChecking = false; // 防止并发检测
 
 export const startTokenCheck = (intervalSeconds: number = 30) => {
+  console.log(`[TokenCheck] 启动token检测,间隔: ${intervalSeconds}秒`);
+  
   // 如果已经有定时器在运行,先清除
   if (tokenCheckInterval) {
+    console.log('[TokenCheck] 清除旧的定时器');
     stopTokenCheck();
   }
 
   // 立即执行一次检测
+  console.log('[TokenCheck] 立即执行一次检测');
   checkTokenAndRefresh();
 
   // 设置定时器
   tokenCheckInterval = setInterval(() => {
+    console.log(`[TokenCheck] 定时器触发,执行检测 (间隔: ${intervalSeconds}秒)`);
     checkTokenAndRefresh();
   }, intervalSeconds * 1000);
+  
+  console.log(`[TokenCheck] 定时器已设置,ID: ${tokenCheckInterval}`);
 };
 
 export const stopTokenCheck = () => {
@@ -244,17 +251,22 @@ export const stopTokenCheck = () => {
 
 // 检测token并刷新
 const checkTokenAndRefresh = async () => {
+  console.log('[TokenCheck] checkTokenAndRefresh 被调用');
+  
   // 如果正在检测中,跳过
   if (isChecking) {
+    console.log('[TokenCheck] 正在检测中,跳过本次调用');
     return;
   }
 
   // 如果没有refreshToken,不需要检测
   const refreshToken = getRefreshToken();
   if (!refreshToken) {
+    console.log('[TokenCheck] 没有refreshToken,跳过检测');
     return;
   }
 
+  console.log('[TokenCheck] 开始检测token...');
   isChecking = true;
 
   try {
@@ -267,135 +279,103 @@ const checkTokenAndRefresh = async () => {
     const baseURL = env.baseUrl ? `${env.baseUrl}/admin-api` : '/admin-api';
     const token = getAccessToken() || getToken();
     
-    const response = await axios.get(`${baseURL}/system/notify-message/get-unread-count`, {
+    if (!token) {
+      // 如果没有token,直接尝试刷新
+      console.log('[TokenCheck] 未找到accessToken,尝试刷新token...');
+      await refreshTokenIfNeeded(refreshToken);
+      return;
+    }
+    
+    const url = `${baseURL}/system/notify-message/get-unread-count`;
+    console.log(`[TokenCheck] 调用检测接口: ${url}`);
+    
+    const response = await axios.get(url, {
       headers: {
-        'Authorization': token ? `Bearer ${token}` : undefined,
+        'Authorization': `Bearer ${token}`,
         'Content-Type': 'application/json',
       },
+      validateStatus: (status) => {
+        // 接受所有状态码,包括401,以便我们能够检测到登录状态失效
+        return status >= 200 && status < 500;
+      },
     });
     
-    // 检查响应数据,如果code是401,说明token失效
+    console.log(`[TokenCheck] 接口响应: status=${response.status}, code=${response.data?.code}`);
+    
+    // 检查响应数据,如果code是401或HTTP状态码是401,说明token失效
     const responseData = response.data;
-    if (responseData && responseData.code === 401 && responseData.msg === '账号未登录') {
-      console.log('检测到token失效,开始刷新token...');
-      
-      // 调用刷新token接口
-      const refreshResponse = await loginApi.refreshToken(refreshToken);
-      
-      // 处理返回数据格式:{code: 0, data: {accessToken, refreshToken, ...}, msg: ""}
-      let tokenData;
-      if (refreshResponse?.code === 0 && refreshResponse?.data) {
-        // 标准格式:{code: 0, data: {...}}
-        tokenData = refreshResponse.data;
-      } else if (refreshResponse?.data) {
-        // 兼容格式:{data: {...}}
-        tokenData = refreshResponse.data;
-      } else {
-        // 直接是数据对象
-        tokenData = refreshResponse;
-      }
-      
-      const newAccessToken = tokenData?.accessToken || tokenData?.token;
-      const newRefreshToken = tokenData?.refreshToken;
-
-      if (newAccessToken) {
-        // 更新token
-        setToken({ accessToken: newAccessToken, token: newAccessToken });
-        setAccessToken(newAccessToken);
-        if (newRefreshToken) {
-          setRefreshToken(newRefreshToken);
-        }
-        console.log('Token刷新成功');
-      } else {
-        console.error('刷新token失败:未返回新token');
-      }
+    const isTokenExpired = 
+      response.status === 401 || 
+      (responseData && (responseData.code === 401 || responseData.msg === '账号未登录'));
+    
+    if (isTokenExpired) {
+      console.log('[TokenCheck] 检测到token失效,开始刷新token...');
+      await refreshTokenIfNeeded(refreshToken);
+    } else {
+      console.log('[TokenCheck] Token有效,无需刷新');
     }
-    // 如果返回正常(code !== 401),说明token有效,不需要处理
+    // 如果返回正常,说明token有效,不需要处理
   } catch (error: any) {
+    console.log(`[TokenCheck] 接口调用异常:`, error?.message || error);
+    
     // 检查错误响应,如果是401,说明token失效
-    if (error?.response?.data) {
-      const errorData = error.response.data;
-      if (errorData.code === 401 || errorData.msg === '账号未登录') {
-        console.log('检测到token失效(通过错误响应),开始刷新token...');
-        
-        try {
-          const { loginApi } = await import('../api/Login');
-          const refreshResponse = await loginApi.refreshToken(refreshToken);
-          
-          // 处理返回数据格式
-          let tokenData;
-          if (refreshResponse?.code === 0 && refreshResponse?.data) {
-            tokenData = refreshResponse.data;
-          } else if (refreshResponse?.data) {
-            tokenData = refreshResponse.data;
-          } else {
-            tokenData = refreshResponse;
-          }
-          
-          const newAccessToken = tokenData?.accessToken || tokenData?.token;
-          const newRefreshToken = tokenData?.refreshToken;
-
-          if (newAccessToken) {
-            setToken({ accessToken: newAccessToken, token: newAccessToken });
-            setAccessToken(newAccessToken);
-            if (newRefreshToken) {
-              setRefreshToken(newRefreshToken);
-            }
-            console.log('Token刷新成功');
-          } else {
-            console.warn('刷新token失败:未返回新token,但不退出登录');
-            // 即使刷新失败,也不退出登录,继续保留当前页面
-          }
-        } catch (refreshError) {
-          console.warn('刷新token失败:', refreshError, '但不退出登录,继续保留当前页面');
-          // 即使刷新失败,也不退出登录,继续保留当前页面
-        }
-      } else {
-        // 其他业务错误,不处理
-        console.log('Token检测接口返回其他错误:', errorData);
-      }
-    } else if (error?.response?.status === 401) {
-      // HTTP状态码401,尝试刷新token
-      console.log('检测到HTTP 401错误,开始刷新token...');
-      
-      try {
-        const { loginApi } = await import('../api/Login');
-        const refreshResponse = await loginApi.refreshToken(refreshToken);
-        
-        // 处理返回数据格式
-        let tokenData;
-        if (refreshResponse?.code === 0 && refreshResponse?.data) {
-          tokenData = refreshResponse.data;
-        } else if (refreshResponse?.data) {
-          tokenData = refreshResponse.data;
-        } else {
-          tokenData = refreshResponse;
-        }
-        
-        const newAccessToken = tokenData?.accessToken || tokenData?.token;
-        const newRefreshToken = tokenData?.refreshToken;
-
-        if (newAccessToken) {
-          setToken({ accessToken: newAccessToken, token: newAccessToken });
-          setAccessToken(newAccessToken);
-          if (newRefreshToken) {
-            setRefreshToken(newRefreshToken);
-          }
-          console.log('Token刷新成功');
-        } else {
-          console.warn('刷新token失败:未返回新token,但不退出登录');
-          // 即使刷新失败,也不退出登录,继续保留当前页面
-        }
-      } catch (refreshError) {
-        console.warn('刷新token失败:', refreshError, '但不退出登录,继续保留当前页面');
-        // 即使刷新失败,也不退出登录,继续保留当前页面
-      }
+    const isTokenExpired = 
+      error?.response?.status === 401 ||
+      (error?.response?.data && (
+        error.response.data.code === 401 || 
+        error.response.data.msg === '账号未登录'
+      ));
+    
+    if (isTokenExpired) {
+      console.log('[TokenCheck] 检测到token失效(通过错误响应),开始刷新token...');
+      await refreshTokenIfNeeded(refreshToken);
     } else {
       // 其他错误(网络问题等),不处理,不退出登录
-      console.log('Token检测接口调用失败:', error?.message || error, '但不退出登录');
+      console.log('[TokenCheck] Token检测接口调用失败:', error?.message || error, '但不退出登录');
     }
   } finally {
     isChecking = false;
+    console.log('[TokenCheck] 检测完成');
+  }
+};
+
+// 刷新token的辅助函数
+const refreshTokenIfNeeded = async (refreshToken: string) => {
+  try {
+    const { loginApi } = await import('../api/Login');
+    const refreshResponse = await loginApi.refreshToken(refreshToken);
+    
+    // 处理返回数据格式:{code: 0, data: {accessToken, refreshToken, ...}, msg: ""}
+    let tokenData;
+    if (refreshResponse?.code === 0 && refreshResponse?.data) {
+      // 标准格式:{code: 0, data: {...}}
+      tokenData = refreshResponse.data;
+    } else if (refreshResponse?.data) {
+      // 兼容格式:{data: {...}}
+      tokenData = refreshResponse.data;
+    } else {
+      // 直接是数据对象
+      tokenData = refreshResponse;
+    }
+    
+    const newAccessToken = tokenData?.accessToken || tokenData?.token;
+    const newRefreshToken = tokenData?.refreshToken;
+
+    if (newAccessToken) {
+      // 更新token
+      setToken({ accessToken: newAccessToken, token: newAccessToken });
+      setAccessToken(newAccessToken);
+      if (newRefreshToken) {
+        setRefreshToken(newRefreshToken);
+      }
+      console.log('Token刷新成功');
+    } else {
+      console.warn('刷新token失败:未返回新token,但不退出登录');
+      // 即使刷新失败,也不退出登录,继续保留当前页面
+    }
+  } catch (refreshError) {
+    console.warn('刷新token失败:', refreshError, '但不退出登录,继续保留当前页面');
+    // 即使刷新失败,也不退出登录,继续保留当前页面
   }
 };
 

+ 6 - 0
src/views/Login.tsx

@@ -8,6 +8,7 @@ import { toast } from 'sonner';
 import { Toaster } from 'sonner';
 import { env } from '../utils/env';
 import * as authUtil from '../utils/auth';
+import { startTokenCheck } from '../utils/auth';
 import { setPermissionInfo } from '../utils/permission';
 import { setDictOptions, DictDataType } from '../utils/dict';
 
@@ -339,6 +340,11 @@ export default function Login() {
       setTimeout(() => {
         toast.dismiss('loading');
         toast.success(t('common.success') || '登录成功');
+        
+        // 登录成功后启动token检测
+        console.log('[Login] 登录成功,启动token检测');
+        startTokenCheck(1);
+        
         navigate(redirectPath);
       }, 500);
     } catch (error: any) {