# SunAdmin 后台管理系统前端框架

> **一句命令即可安装完整的后台管理系统前端框架！**

## 介绍

SunAdmin Admin UI 是一个基于 Vue 3 和 Element Plus 开发的通用后台管理系统前端框架，旨在提供一套完整的后台管理界面解决方案，帮助开发者快速搭建专业的管理后台。

### 开发目的

-   **一句命令安装**：通过简单的 npm/pnpm 命令即可获得完整后台框架
-   **零侵入性**：作为独立的 npm 包，对宿主项目无任何侵入性
-   **便捷更新**：版本更新只需更改依赖版本号，无需修改现有代码
-   **避免依赖冲突**：使用 peerDependencies 设计，避免重复依赖安装
-   提供开箱即用的后台管理界面
-   减少重复开发常见后台功能的工作量
-   统一管理后台的界面风格与交互体验
-   与 SunAdmin 后端框架无缝集成，形成完整解决方案

### 为什么开发成独立的包？

-   **便于安装**：一句命令即可完成安装，无需复杂配置
-   **无侵入性**：作为独立包引入，不会污染宿主项目的代码结构
-   **便捷更新**：只需修改版本号即可获取最新功能和安全修复
-   **跨项目复用**：可在多个项目中使用相同的管理界面
-   **统一维护**：集中维护一套代码，确保各项目使用相同标准
-   **避免依赖冲突**：通过 peerDependencies 设计，让宿主项目管理依赖版本

### 技术栈

-   **Vue 3**: 渐进式 JavaScript 框架
-   **TypeScript**: 类型安全的 JavaScript 超集
-   **Element Plus**: 基于 Vue 3 的组件库
-   **Pinia**: Vue 的状态管理库
-   **Vue Router**: Vue.js 的官方路由
-   **Axios**: 基于 Promise 的 HTTP 客户端
-   **Vite**: 现代前端构建工具

## 起步

### 安装

> **只需一句命令，即可拥有完整的后台管理系统前端框架！**

#### 1. 安装依赖

由于采用了 peerDependencies 设计，您需要先安装必要的依赖：

```bash
# 使用 npm
npm install vue@^3.4.29 element-plus@^2.7.7 @element-plus/icons-vue@^2.3.1 pinia@^3.0.3 pinia-plugin-persistedstate@^4.2.0 vue-router@^4.3.3 axios@^1.7.2

# 使用 pnpm
pnpm add vue@^3.4.29 element-plus@^2.7.7 @element-plus/icons-vue@^2.3.1 pinia@^3.0.3 pinia-plugin-persistedstate@^4.2.0 vue-router@^4.3.3 axios@^1.7.2
```

#### 2. 安装 SunAdmin

```bash
# 使用 npm
npm install @sunjinglong/sunadmin-admin-ui

# 使用 pnpm
pnpm add @sunjinglong/sunadmin-admin-ui
```

### 基础配置

由于新的设计架构，您需要在宿主项目中自行配置第三方库：

#### main.js 配置示例

```js
import { createApp } from "vue";
import App from "./App.vue";

// 手动配置第三方库
import ElementPlus from "element-plus";
import "element-plus/dist/index.css";
import zhCn from "element-plus/dist/locale/zh-cn.mjs";
import * as ElementPlusIconsVue from "@element-plus/icons-vue";

import { createRouter, createWebHistory } from "vue-router";
import { createPinia } from "pinia";
import piniaPluginPersistedstate from "pinia-plugin-persistedstate";

// 导入 SunAdmin
import SunAdminUI from "@sunjinglong/sunadmin-admin-ui";
import "@sunjinglong/sunadmin-admin-ui/dist/style.css";

const app = createApp(App);

// 1. 配置 Element Plus
app.use(ElementPlus, { locale: zhCn });

// 2. 注册 Element Plus Icons
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
    app.component(key, component);
}

// 3. 配置 Pinia
const pinia = createPinia();
pinia.use(piniaPluginPersistedstate);
app.use(pinia);

// 4. 配置路由
const router = createRouter({
    history: createWebHistory(),
    routes: [
        // 您的自定义路由
    ],
});
app.use(router);

// 5. 配置 SunAdmin
app.use(SunAdminUI, {
    apiConfig: {
        baseURL: "http://your-api-domain.com/sunAdmin", // 后端API基础地址
        timeout: 60000, // 请求超时时间
        wsUrl: "ws://xxxx",
    },
});

app.mount("#app");
```

### 与后端集成

SunAdmin 前端框架设计为与 `sunjinglong/sunadmin-server` 后端框架无缝集成，一句命令即可拥有高性能后端。

[请阅读后端仓库中的使用文档](https://gitee.com/sunjinglong/sunadmin-server)

#### 后端 API 格式要求

响应格式：

```json
{
    "code": 200,
    "message": "操作成功",
    "data": {}
}
```

认证方式：

-   使用 Bearer Token 认证
-   Token 通过请求头 `Authorization: Bearer {token}` 传递

## 封装列表

### 用户认证与权限管理

-   登录页面与认证流程
-   基于角色的权限控制
-   动态菜单权限
-   Token 自动刷新
-   用户信息管理

### 布局与导航

-   响应式侧边栏
-   面包屑导航
-   标签页导航
-   自适应布局
-   主题定制

### 数据管理页面

-   管理员账号管理
-   角色权限管理
-   菜单管理
-   数据字典管理
-   附件管理
-   定时任务管理

### WebSocket 实时通信

-   自动连接与重连
-   消息订阅与发布
-   实时通知
-   用户在线状态

### 通用组件

-   页面容器组件
-   搜索卡片组件
-   表单构建器
-   图标选择器
-   图片选择器
-   附件选择器

## 二开文档

### 创建页面

-   在你的项目 pages 目录中创建页面 vue 文件,例: src/test.vue
-   在 main.js 中加载 sunadmin 的时候传入路由配置

```js
app.use(SunAdminCore,{
    apiConfig: {....api配置信息},
    //layoutRoutes中的路由页面将在系统框架内显示
    layoutRoutes: [
      //该数组中加入你的路由地址
        {
            path: '/test',
            component: () => import('./pages/test.vue')
        }
    ],
    outsideRoutes:[
      {
        path:'/其他不需要再框架内显示的页面'
      }
    ]
})
```

-   最后需要在后台 - 运维 - 菜单权限 - 新增 - 菜单类型(页面路由) - 路由地址(/test), 将菜单路由信息提交到服务区,该步骤请保证你已经安装了后端服务,具体请参阅[sunadmin 配套后端服务安装方式,一条命令即可安装](https://gitee.com/sunjinglong/sunadmin-server)
-   刷新页面后会即可在后台看到菜单

### 使用 ElementPlus 相关 api

> sunadmin 包内已经安装了 ElementPlus 组件库,用户宿主项目中无需重复安装

```js
import { ElMessage,ElMessageBox, ...其他api } from "@sunjinglong/sunadmin-admin-ui";
ElMessage.info("信息提示");
ElMessage.error("错误提示");
```

### 使用 pinia

> sunadmin 中已经导入并加载了 pinia, 用户在宿主项目中无需安装和导入 pinia

```js
import { defineStore } from "@sunjinglong/sunadmin-admin-ui";
export const useAccountStore = defineStore("account", {
    state: () => {
        return {
            test: "",
        };
    },
});
```

### 路由实例 router 的使用

> npm 包内已经创建了路由实例，并且导出了该实例，宿主项目中无需引入并创建路由实例

-   如果是 vue 组合式 api 风格，那么请直接使用 vue 原生的 useRouter()钩子来获取当前的路由实例（推荐）；

```js
// 组合式api风格，在宿主项目中
import { useRouter } from "vue-router";
// 在setup函数或组件中
const router = useRouter();
// 使用路由
router.push("/dashboard");
```

-   如果使用的不是组合式 api 风格，那么请使用 vue 原生的 this.$router 来访问路由实例 （推荐）

```js
// 选项式API组件
export default {
    methods: {
        navigateTo(path) {
            this.$router.push(path);
        },
        goBack() {
            this.$router.go(-1);
        },
    },
    mounted() {
        // 在生命周期钩子中使用
        console.log(this.$router.currentRoute.value);
    },
};
```

-   如果需要在组件外或者特殊需求下获取 sunadmin 包内创建的路由实例，那么请使用 sunadmin 导出的 router（一般很少遇到这种场景）

```js
import { router } from "@sunjinglong/sunadmin-admin-ui";
router.push("/some-path");
```

### HTTP 请求

> sunadmin 包内已经自行使用 axios 封装了网络请求方法,导出了 get,post,del,service（axios 实例）

> 请求返回拦截处理原则是：当接口 http 状态码为 200，且业务数据中 response.code 为 200，那么认为该接口成功。否则一律按照接口异常处理，返回 Promise.reject，走 catch。

```js
import { get, post } from "@sunjinglong/sunadmin-admin-ui";

// GET 请求
http.get("请求地址（会自动拼接host）", {'请求数据对象'})
    .then((response) => {
        console.log(response.data);
    })
    .catch((err) => {
        console.error(err.message);
    });

// POST 请求
http.post("/api/users", { name: "John", email: "john@example.com" }).then((response) => {
    console.log(response.data);
});

// DELETE 请求
http.del("/api/users/1").then((response) => {
    console.log(response.data);
});
```

### WebSocket 管理

#### 主动订阅 ws 消息

```js
import { wsManager } from "@sunjinglong/sunadmin-admin-ui";
//消息订阅 (一般在页面组件create的时候订阅),返回销毁方法
this.wsHandle = wsManager.addMessageHandler((data) => {
    console.log("收到ws消息");
});
//记得在合适时机取消订阅(一般在页面组件销毁beforeUnmount)
this.wsHandle();
```

### sunadmin 包内可用的 pinia 状态实例

#### 后台管理员登录信息

```js
import { useAccountStore } from "@sunjinglong/sunadmin-admin-ui";
// 账户状态
const accountStore = useAccountStore();
```

##### 属性:

-   自行打印 accountStore 查看
-   isLogin 可判断当前登录状态,是一个 getters 属性

##### 方法:

-   loginOut() 退出登录
-   accountOffLine() 强制踢出某管理员下线

### 日期工具

```js
import { formatFriendlyTime } from "@sunjinglong/sunadmin-admin-ui";
```

#### 友好时间显示

-   formatFriendlyTime(dateTime: string | number | Date | null | undefined)

#### 判断两个日志是否为同一天

-   isSameDay(date1: Date, date2: Date)

### 业务初始化

```js
import { initBusiness, cleanupBusiness, reinitBusiness } from "@sunjinglong/sunadmin-admin-ui";

// 初始化业务逻辑
initBusiness();

// 清理业务资源
cleanupBusiness();

// 重新初始化业务逻辑
reinitBusiness();
```

## 自定义开发

### 扩展组件

您可以通过导入并扩展 SunAdmin 的组件来创建自定义组件：

```vue
<template>
    <PageViewContainer title="自定义页面">
        <!-- 自定义内容 -->
    </PageViewContainer>
</template>

<script setup>
import { PageViewContainer } from "@sunjinglong/sunadmin-admin-ui";
</script>
```

## 相关链接

-   [SunAdmin 前端仓库](https://gitee.com/sunjinglong/sunadmin-admin-ui)
-   [SunAdmin 后端仓库](https://gitee.com/sunjinglong/sunadmin-server)
-   [Vue 3 文档](https://cn.vuejs.org/)
-   [Element Plus 文档](https://element-plus.org/zh-CN/)

## 许可证

SunAdmin Admin UI 使用 MIT 许可证，详见 LICENSE 文件。
