完成Work组件的界面和一些小修改
> 1. 修改优化路由守卫
> 2. 去除拦截器中的调试信息
> 3. 修改头部导航条下拉菜单的样式增加图标。
> 4. work组件现在使用mock数据

Change-Id: Ic602a35bb02e645a0d5253c5cbd12a68d70bfb33
diff --git a/src/feature/work/utils.ts b/src/feature/work/utils.ts
new file mode 100644
index 0000000..a10d95f
--- /dev/null
+++ b/src/feature/work/utils.ts
@@ -0,0 +1,155 @@
+import type { RcFile } from 'antd/es/upload';
+
+// 将文件转换为Base64
+export const getBase64 = (file: RcFile): Promise<string> =>
+    new Promise((resolve, reject) => {
+        const reader = new FileReader();
+        reader.readAsDataURL(file);
+        reader.onload = () => resolve(reader.result as string);
+        reader.onerror = (error) => reject(error);
+    });
+
+// 验证图片文件
+interface ValidationResult {
+    valid: boolean;
+    message?: string;
+}
+
+export const validateImageFile = (file: RcFile): ValidationResult => {
+    const isImage = file.type.startsWith('image/');
+    if (!isImage) {
+        return { valid: false, message: '只能上传图片文件!' };
+    }
+
+    const isLt5M = file.size / 1024 / 1024 < 5;
+    if (!isLt5M) {
+        return { valid: false, message: '图片大小不能超过 5MB!' };
+    }
+
+    return { valid: true };
+};
+
+// 验证种子文件
+export const validateSeedFile = (file: RcFile): ValidationResult => {
+    const isLt100M = file.size / 1024 / 1024 < 100;
+    if (!isLt100M) {
+        return { valid: false, message: '种子文件大小不能超过 100MB!' };
+    }
+
+    return { valid: true };
+};
+
+// 格式化文件大小
+export const formatFileSize = (bytes: number): string => {
+    if (bytes === 0) return '0 Bytes';
+
+    const k = 1024;
+    const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
+    const i = Math.floor(Math.log(bytes) / Math.log(k));
+
+    return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
+};
+
+// 防抖函数 - 修复版本
+export const debounce = <T extends (...args: unknown[]) => unknown>(
+    func: T,
+    wait: number
+): ((...args: Parameters<T>) => void) => {
+    let timeout: ReturnType<typeof setTimeout>;
+    
+    return (...args: Parameters<T>) => {
+        clearTimeout(timeout);
+        timeout = setTimeout(() => func(...args), wait);
+    };
+};
+
+// 节流函数 - 修复版本
+export const throttle = <T extends (...args: unknown[]) => unknown>(
+    func: T,
+    limit: number
+): ((...args: Parameters<T>) => void) => {
+    let inThrottle: boolean;
+    
+    return (...args: Parameters<T>) => {
+        if (!inThrottle) {
+            func(...args);
+            inThrottle = true;
+            setTimeout(() => inThrottle = false, limit);
+        }
+    };
+};
+// 生成唯一ID
+export const generateId = (): string => {
+    return Date.now().toString(36) + Math.random().toString(36).substr(2);
+};
+
+// 安全的JSON解析
+export const safeJsonParse = <T>(str: string, defaultValue: T): T => {
+    try {
+        return JSON.parse(str) as T;
+    } catch {
+        return defaultValue;
+    }
+};
+
+// 检查是否为空值
+export const isEmpty = (value: unknown): boolean => {
+    if (value === null || value === undefined) return true;
+    if (typeof value === 'string') return value.trim() === '';
+    if (Array.isArray(value)) return value.length === 0;
+    if (typeof value === 'object') return Object.keys(value).length === 0;
+    return false;
+};
+
+// URL参数解析
+export const parseUrlParams = (url: string): Record<string, string> => {
+    const params: Record<string, string> = {};
+    const urlObj = new URL(url);
+    
+    urlObj.searchParams.forEach((value, key) => {
+        params[key] = value;
+    });
+    
+    return params;
+};
+
+// 时间格式化
+export const formatDate = (date: Date | string | number, format: string = 'YYYY-MM-DD HH:mm:ss'): string => {
+    const d = new Date(date);
+    
+    const year = d.getFullYear();
+    const month = String(d.getMonth() + 1).padStart(2, '0');
+    const day = String(d.getDate()).padStart(2, '0');
+    const hours = String(d.getHours()).padStart(2, '0');
+    const minutes = String(d.getMinutes()).padStart(2, '0');
+    const seconds = String(d.getSeconds()).padStart(2, '0');
+    
+    return format
+        .replace('YYYY', year.toString())
+        .replace('MM', month)
+        .replace('DD', day)
+        .replace('HH', hours)
+        .replace('mm', minutes)
+        .replace('ss', seconds);
+};
+
+// 相对时间格式化(例如:2小时前)
+export const formatRelativeTime = (date: Date | string | number): string => {
+    const now = new Date();
+    const target = new Date(date);
+    const diff = now.getTime() - target.getTime();
+    
+    const seconds = Math.floor(diff / 1000);
+    const minutes = Math.floor(seconds / 60);
+    const hours = Math.floor(minutes / 60);
+    const days = Math.floor(hours / 24);
+    const months = Math.floor(days / 30);
+    const years = Math.floor(months / 12);
+    
+    if (years > 0) return `${years}年前`;
+    if (months > 0) return `${months}个月前`;
+    if (days > 0) return `${days}天前`;
+    if (hours > 0) return `${hours}小时前`;
+    if (minutes > 0) return `${minutes}分钟前`;
+    return '刚刚';
+};
\ No newline at end of file