# fmdeui 组件库

## 项目介绍

fmdeui 是一个基于 Vue 3 的前端组件库，提供了丰富的工具函数、状态管理、国际化等功能，帮助开发者快速构建现代化的前端应用。

## 安装

```bash
# 使用 npm
npm install @fmdeui/fmui

# 使用 pnpm
pnpm add @fmdeui/fmui

# 使用 yarn
yarn add @fmdeui/fmui
```

## 快速开始

### 1. 基本使用

```javascript
import { createApp } from 'vue';
import App from './App.vue';
import fmdeui from '@fmdeui/fmui';
import '@fmdeui/fmui/dist/style.css';

const app = createApp(App);
app.use(fmdeui);
app.mount('#app');
```

### 2. 按需导入

```javascript
import { createApp } from 'vue';
import App from './App.vue';
import { useTagsViewRoutes, signalR, setIntroduction } from '@fmdeui/fmui';

const app = createApp(App);
// 配置图标字体
setIntroduction({ scriptUrl: '//at.alicdn.com/t/font_1788044_0dwu4guekcwr.js' });
app.mount('#app');
```

## 核心功能

### 1. 状态管理

#### 标签页管理

```javascript
import { useTagsViewRoutes } from '@fmdeui/fmui';

const { tagsViewRoutes, addTagsViewRoute, closeTagsViewRoute, closeAllTagsViewRoutes } = useTagsViewRoutes();

// 添加标签页
addTagsViewRoute({ path: '/home', name: 'home', meta: { title: '首页' } });

// 关闭标签页
closeTagsViewRoute('/home');

// 关闭所有标签页
closeAllTagsViewRoutes();
```

#### 主题配置

```javascript
import { useThemeConfig } from '@fmdeui/fmui';

const { themeConfig, setThemeConfig } = useThemeConfig();

// 修改主题配置
setThemeConfig({
  theme: 'dark',
  layout: 'vertical',
  primary: '#409EFF'
});
```

#### 用户信息

```javascript
import { useUserInfo } from '@fmdeui/fmui';

const { userInfo, setUserInfo } = useUserInfo();

// 设置用户信息
setUserInfo({
  userId: '1',
  userName: 'admin',
  userAccount: 'admin'
});
```

### 2. 工具函数

#### 存储工具

```javascript
import { Local, Session } from '@fmdeui/fmui';

// 本地存储
Local.set('key', 'value');
const value = Local.get('key');
Local.remove('key');
Local.clear();

// 会话存储
Session.set('key', 'value');
const value = Session.get('key');
Session.remove('key');
Session.clear();
```

#### 网络请求

```javascript
import { service, request2, getToken, clearAccessTokens } from '@fmdeui/fmui';

// 发送请求
const response = await service.get('/api/user');

// 带参数的请求
const response = await request2('/api/user', {
  method: 'post',
  data: { name: 'admin' }
});

// 获取 token
const token = getToken();

// 清除 token
clearAccessTokens();
```

#### 时间格式化

```javascript
import { formatDate, formatPast } from '@fmdeui/fmui';

// 格式化日期
const dateStr = formatDate(new Date(), 'YYYY-MM-DD HH:mm:ss');

// 格式化相对时间
const pastStr = formatPast(new Date(Date.now() - 3600000)); // 1小时前
```

#### 验证工具

```javascript
import { verifyEmail, verifyPhone, verifyPassword } from '@fmdeui/fmui';

// 验证邮箱
const isEmail = verifyEmail('test@example.com');

// 验证手机号
const isPhone = verifyPhone('13800138000');

// 验证密码
const isPassword = verifyPassword('Password123');
```

#### 文件下载

```javascript
import { downloadByUrl, downloadByData } from '@fmdeui/fmui';

// 通过 URL 下载
await downloadByUrl('https://example.com/file.pdf', '文件.pdf');

// 通过数据下载
await downloadByData(data, 'data.json', 'application/json');
```

#### Base64 转换

```javascript
import { fileToBase64, base64ToFile } from '@fmdeui/fmui';

// 文件转 Base64
const base64 = await fileToBase64(file);

// Base64 转文件
const file = base64ToFile(base64, 'image.png');
```

### 3. 钩子函数

#### 权限管理

```javascript
import { auth, auths, hAuth } from '@fmdeui/fmui';

// 单个权限检查
const hasPermission = auth('user:add');

// 多个权限检查
const hasPermissions = auths(['user:add', 'user:edit']);

// 指令形式
// <button v-auth="'user:add'">添加用户</button>
```

#### 国际化

```javascript
import { useLocale, setupI18n } from '@fmdeui/fmui';

// 设置国际化
setupI18n({
  locale: 'zh-cn',
  messages: {
    'zh-cn': {
      hello: '你好'
    },
    'en': {
      hello: 'Hello'
    }
  }
});

// 使用国际化
const { t } = useLocale();
const hello = t('hello');
```

#### 系统信息

```javascript
import { loadSysInfo, updateFavicon } from '@fmdeui/fmui';

// 加载系统信息
await loadSysInfo();

// 更新 favicon
updateFavicon('https://example.com/favicon.ico');
```

#### 空闲超时管理

```javascript
import { initIdleTimeout, updateIdleTimeout, destroyIdleTimeout } from '@fmdeui/fmui';

// 初始化空闲超时（10秒）
initIdleTimeout({ timeout: 10 });

// 更新空闲超时时间（30分钟）
updateIdleTimeout(30 * 60);

// 销毁空闲超时
// destroyIdleTimeout();
```

### 4. SignalR 实时通信

```javascript
import { signalR, restartSignalR } from '@fmdeui/fmui';

// 监听在线用户列表
signalR.on('OnlineUserList', (data) => {
  console.log('在线用户列表:', data.userList);
  
  // 上下线通知
  ElNotification({
    title: '提示',
    message: `${data.online ? `【${data.realName}】上线了` : `【${data.realName}】离开了`}`,
    type: `${data.online ? 'primary' : 'error'}`,
    position: 'bottom-right',
  });
});

// 监听强制下线
signalR.on('ForceOffline', async (data) => {
  await signalR.stop();
  // 执行登出操作
  // ...
});

// 发送消息
signalR.send('SendMessage', { message: 'Hello' });

// 重新初始化 SignalR（登录后调用）
await restartSignalR();
```

### 5. 国际化

```javascript
import { i18n, languageList, setupI18n } from '@fmdeui/fmui';

// 可用语言列表
console.log(languageList);

// 设置国际化
setupI18n({
  locale: 'zh-cn',
  messages: {
    'zh-cn': {
      welcome: '欢迎'
    },
    'en': {
      welcome: 'Welcome'
    }
  }
});

// 使用 i18n 实例
const welcome = i18n.t('welcome');
```

### 6. API 服务

```javascript
import { useApi, useBaseApi } from '@fmdeui/fmui';

// 使用基础 API 服务
const baseApi = useBaseApi('sysAuth');
const response = await baseApi.post(null, 'login', { username: 'admin', password: '123456' });

// 使用自定义 API 服务
const api = useApi({
  getUsers: { method: 'get', url: '/api/users' },
  createUser: { method: 'post', url: '/api/users' }
});

const users = await api.getUsers();
const newUser = await api.createUser({ name: 'admin' });
```

## 高级配置

### 1. 图标字体配置

```javascript
import { setIntroduction, setCssCdn, setJsCdn } from '@fmdeui/fmui';

// 设置图标字体
setIntroduction({
  scriptUrl: '//at.alicdn.com/t/font_1788044_0dwu4guekcwr.js'
});

// 单独设置 CSS CDN
setCssCdn('//at.alicdn.com/t/font_1788044_0dwu4guekcwr.css');

// 单独设置 JS CDN
setJsCdn('//at.alicdn.com/t/font_1788044_0dwu4guekcwr.js');
```

### 2. 事件总线

```javascript
import { mittBus } from '@fmdeui/fmui';

// 监听事件
mittBus.on('event', (data) => {
  console.log('事件触发:', data);
});

// 触发事件
mittBus.emit('event', { message: 'Hello' });

// 移除事件监听
mittBus.off('event');
```

### 3. 水印

```javascript
import { Watermark } from '@fmdeui/fmui';

// 创建水印
const watermark = new Watermark({
  text: 'fmdeui',
  fontSize: 14,
  color: '#999',
  opacity: 0.1,
  angle: -45,
  density: 20
});

// 销毁水印
// watermark.destroy();
```

### 4. 通用函数

```javascript
import { commonFunction, commonFun } from '@fmdeui/fmui';

// 使用 commonFunction
const common = commonFunction();

// 使用 commonFun（已初始化的实例）
const result = commonFun.someMethod();
```

### 5. 其他工具函数

```javascript
import { other } from '@fmdeui/fmui';

// 设置浏览器标题国际化
other.useTitle();

// 设置 tagsView 名称国际化
const tagsViewName = other.setTagsViewNameI18n(router.currentRoute.value);

// 图片懒加载
other.lazyImg('.lazy-img', imageList);

// 获取全局组件大小
const size = other.globalComponentSize();

// 对象深克隆
const clonedObj = other.deepClone(originalObj);

// 判断是否是移动端
const isMobile = other.isMobile();

// 处理空数组
const filteredList = other.handleEmpty(list);

// 打开外部链接
other.handleOpenLink(menuItem);
```

## 版本信息

当前版本：`1.0.46`

## 注意事项

1. 使用 SignalR 功能时，确保后端已配置相应的 Hub 服务
2. 空闲超时功能会在用户长时间无操作时自动登出
3. 部分功能依赖 Element Plus 组件库
4. SignalR 实例会存储在 window.__SIGNALR_INSTANCE__ 中，确保全局唯一

## 浏览器兼容性

- Chrome ≥ 60
- Firefox ≥ 55
- Safari ≥ 12
- Edge ≥ 79

## 许可证

MIT License