xto-fronted 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +95 -0
- package/dist/403-MQkNUulz.js +31 -0
- package/dist/404-BOFYLq4X.js +31 -0
- package/dist/App.vue.d.ts +2 -0
- package/dist/api/auth.d.ts +8 -0
- package/dist/api/system.d.ts +16 -0
- package/dist/api/user.d.ts +13 -0
- package/dist/components/Layout/Footer.vue.d.ts +2 -0
- package/dist/components/Layout/Header.vue.d.ts +4 -0
- package/dist/components/Layout/Sidebar.vue.d.ts +2 -0
- package/dist/components/Layout/Tabs.vue.d.ts +2 -0
- package/dist/components/Layout/index.vue.d.ts +2 -0
- package/dist/composables/useAuth.d.ts +9 -0
- package/dist/composables/useForm.d.ts +20 -0
- package/dist/composables/useTable.d.ts +29 -0
- package/dist/directives/permission.d.ts +4 -0
- package/dist/enums/index.d.ts +32 -0
- package/dist/index-BJxYdNPy.js +475 -0
- package/dist/index-BvnIIBR1.js +142 -0
- package/dist/index-CEvAq6KE.js +372 -0
- package/dist/index-DPkqej__.js +345 -0
- package/dist/index-pq9Z5K62.js +184 -0
- package/dist/index-vVfjShJR.js +1183 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.es.js +73 -0
- package/dist/index.umd.js +1 -0
- package/dist/main.d.ts +0 -0
- package/dist/router/dynamicRoutes.d.ts +34 -0
- package/dist/router/index.d.ts +6 -0
- package/dist/router/staticRoutes.d.ts +3 -0
- package/dist/stores/app.d.ts +75 -0
- package/dist/stores/auth.d.ts +31 -0
- package/dist/stores/index.d.ts +9 -0
- package/dist/stores/menu.d.ts +108 -0
- package/dist/stores/user.d.ts +113 -0
- package/dist/style.css +1 -0
- package/dist/utils/auth.d.ts +18 -0
- package/dist/utils/permission.d.ts +17 -0
- package/dist/utils/request.d.ts +25 -0
- package/dist/utils/storage.d.ts +24 -0
- package/dist/views/dashboard/index.vue.d.ts +2 -0
- package/dist/views/error/403.vue.d.ts +2 -0
- package/dist/views/error/404.vue.d.ts +2 -0
- package/dist/views/login/index.vue.d.ts +4 -0
- package/dist/views/system/menu/index.vue.d.ts +4 -0
- package/dist/views/system/role/index.vue.d.ts +4 -0
- package/dist/views/system/user/index.vue.d.ts +4 -0
- package/dist/vite.svg +10 -0
- package/package.json +71 -0
package/README.md
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# Xto Demo
|
|
2
|
+
|
|
3
|
+
基于 xto 组件库的后台管理系统脚手架。
|
|
4
|
+
|
|
5
|
+
## 特性
|
|
6
|
+
|
|
7
|
+
- 🚀 Vue 3 + TypeScript + Vite 5
|
|
8
|
+
- 📦 Pinia 状态管理
|
|
9
|
+
- 🛣️ Vue Router 4 动态路由
|
|
10
|
+
- 🎨 xto 组件库
|
|
11
|
+
- 🔐 权限管理(角色、按钮级别)
|
|
12
|
+
- 🌓 亮色/暗色主题切换
|
|
13
|
+
- 📱 响应式布局
|
|
14
|
+
|
|
15
|
+
## 项目结构
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
src/
|
|
19
|
+
├── api/ # API 接口
|
|
20
|
+
├── assets/ # 静态资源
|
|
21
|
+
│ └── styles/ # 全局样式
|
|
22
|
+
├── components/ # 全局组件
|
|
23
|
+
│ └── Layout/ # 布局组件
|
|
24
|
+
├── composables/ # 组合式函数
|
|
25
|
+
├── directives/ # 自定义指令
|
|
26
|
+
├── enums/ # 枚举常量
|
|
27
|
+
├── router/ # 路由配置
|
|
28
|
+
├── stores/ # Pinia 状态
|
|
29
|
+
├── types/ # 类型定义
|
|
30
|
+
├── utils/ # 工具函数
|
|
31
|
+
└── views/ # 页面视图
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## 开发
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
# 安装依赖
|
|
38
|
+
pnpm install
|
|
39
|
+
|
|
40
|
+
# 启动开发服务器
|
|
41
|
+
pnpm dev
|
|
42
|
+
|
|
43
|
+
# 构建
|
|
44
|
+
pnpm build
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## 推送仓库
|
|
48
|
+
```bash
|
|
49
|
+
pnpm install
|
|
50
|
+
|
|
51
|
+
# 1. 构建(库模式)
|
|
52
|
+
pnpm run build:lib
|
|
53
|
+
|
|
54
|
+
# 2. 登录 npm(首次需要)
|
|
55
|
+
npm login
|
|
56
|
+
|
|
57
|
+
# 3. 发布
|
|
58
|
+
npm publish
|
|
59
|
+
```
|
|
60
|
+
## 功能模块
|
|
61
|
+
|
|
62
|
+
- [x] 登录/登出
|
|
63
|
+
- [x] 动态路由
|
|
64
|
+
- [x] 侧边栏菜单
|
|
65
|
+
- [x] 顶部导航/面包屑
|
|
66
|
+
- [x] 标签页缓存
|
|
67
|
+
- [x] 仪表盘
|
|
68
|
+
- [x] 用户管理 CRUD
|
|
69
|
+
- [x] 角色管理
|
|
70
|
+
- [x] 菜单管理
|
|
71
|
+
- [x] 主题切换
|
|
72
|
+
- [x] 权限控制
|
|
73
|
+
|
|
74
|
+
## Mock 数据
|
|
75
|
+
|
|
76
|
+
项目使用本地 Mock 数据,可直接登录测试:
|
|
77
|
+
|
|
78
|
+
- 用户名:任意
|
|
79
|
+
- 密码:任意
|
|
80
|
+
|
|
81
|
+
## 技术栈
|
|
82
|
+
|
|
83
|
+
| 技术 | 版本 |
|
|
84
|
+
|------|------|
|
|
85
|
+
| Vue | 3.4+ |
|
|
86
|
+
| TypeScript | 5.4+ |
|
|
87
|
+
| Vite | 5.x |
|
|
88
|
+
| Vue Router | 4.x |
|
|
89
|
+
| Pinia | 2.x |
|
|
90
|
+
| Axios | 1.x |
|
|
91
|
+
| xto | npm |
|
|
92
|
+
|
|
93
|
+
## License
|
|
94
|
+
|
|
95
|
+
MIT
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { defineComponent as s, openBlock as n, createElementBlock as p, createElementVNode as o, createVNode as d, unref as _, withCtx as a, createTextVNode as i } from "vue";
|
|
2
|
+
import { useRouter as m } from "vue-router";
|
|
3
|
+
import { Button as c } from "@xto/base";
|
|
4
|
+
import { c as l } from "./index-vVfjShJR.js";
|
|
5
|
+
const f = { class: "error-page" }, u = { class: "error-page__content" }, g = /* @__PURE__ */ s({
|
|
6
|
+
__name: "403",
|
|
7
|
+
setup(v) {
|
|
8
|
+
const r = m(), t = () => {
|
|
9
|
+
r.push("/");
|
|
10
|
+
};
|
|
11
|
+
return (x, e) => (n(), p("div", f, [
|
|
12
|
+
o("div", u, [
|
|
13
|
+
e[1] || (e[1] = o("div", { class: "error-page__code" }, "403", -1)),
|
|
14
|
+
e[2] || (e[2] = o("div", { class: "error-page__title" }, "无访问权限", -1)),
|
|
15
|
+
e[3] || (e[3] = o("div", { class: "error-page__desc" }, "抱歉,您没有权限访问此页面", -1)),
|
|
16
|
+
d(_(c), {
|
|
17
|
+
type: "primary",
|
|
18
|
+
onClick: t
|
|
19
|
+
}, {
|
|
20
|
+
default: a(() => [...e[0] || (e[0] = [
|
|
21
|
+
i("返回首页", -1)
|
|
22
|
+
])]),
|
|
23
|
+
_: 1
|
|
24
|
+
})
|
|
25
|
+
])
|
|
26
|
+
]));
|
|
27
|
+
}
|
|
28
|
+
}), V = /* @__PURE__ */ l(g, [["__scopeId", "data-v-f6105e3d"]]);
|
|
29
|
+
export {
|
|
30
|
+
V as default
|
|
31
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { defineComponent as s, openBlock as n, createElementBlock as p, createElementVNode as o, createVNode as a, unref as _, withCtx as d, createTextVNode as i } from "vue";
|
|
2
|
+
import { useRouter as c } from "vue-router";
|
|
3
|
+
import { Button as m } from "@xto/base";
|
|
4
|
+
import { c as l } from "./index-vVfjShJR.js";
|
|
5
|
+
const f = { class: "error-page" }, u = { class: "error-page__content" }, g = /* @__PURE__ */ s({
|
|
6
|
+
__name: "404",
|
|
7
|
+
setup(v) {
|
|
8
|
+
const r = c(), t = () => {
|
|
9
|
+
r.push("/");
|
|
10
|
+
};
|
|
11
|
+
return (x, e) => (n(), p("div", f, [
|
|
12
|
+
o("div", u, [
|
|
13
|
+
e[1] || (e[1] = o("div", { class: "error-page__code" }, "404", -1)),
|
|
14
|
+
e[2] || (e[2] = o("div", { class: "error-page__title" }, "页面不存在", -1)),
|
|
15
|
+
e[3] || (e[3] = o("div", { class: "error-page__desc" }, "抱歉,您访问的页面不存在或已被删除", -1)),
|
|
16
|
+
a(_(m), {
|
|
17
|
+
type: "primary",
|
|
18
|
+
onClick: t
|
|
19
|
+
}, {
|
|
20
|
+
default: d(() => [...e[0] || (e[0] = [
|
|
21
|
+
i("返回首页", -1)
|
|
22
|
+
])]),
|
|
23
|
+
_: 1
|
|
24
|
+
})
|
|
25
|
+
])
|
|
26
|
+
]));
|
|
27
|
+
}
|
|
28
|
+
}), V = /* @__PURE__ */ l(g, [["__scopeId", "data-v-f1a1acb0"]]);
|
|
29
|
+
export {
|
|
30
|
+
V as default
|
|
31
|
+
};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
declare const _default: import('vue').DefineComponent<{}, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, HTMLDivElement>;
|
|
2
|
+
export default _default;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { LoginParams, LoginResult, UserInfo } from '../types/api';
|
|
2
|
+
export declare function login(data: LoginParams): Promise<import('../utils/request').ApiResponse<LoginResult>>;
|
|
3
|
+
export declare function logout(): Promise<import('../utils/request').ApiResponse<unknown>>;
|
|
4
|
+
export declare function getUserInfo(): Promise<import('../utils/request').ApiResponse<UserInfo>>;
|
|
5
|
+
export declare function refreshToken(refreshToken: string): Promise<import('../utils/request').ApiResponse<{
|
|
6
|
+
token: string;
|
|
7
|
+
expireTime: number;
|
|
8
|
+
}>>;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { PageParams, PageResponse } from '../utils/request';
|
|
2
|
+
import { RoleInfo, MenuItem } from '../types/api';
|
|
3
|
+
export declare function getRoleList(params: PageParams & {
|
|
4
|
+
status?: number;
|
|
5
|
+
keyword?: string;
|
|
6
|
+
}): Promise<import('../utils/request').ApiResponse<PageResponse<RoleInfo>>>;
|
|
7
|
+
export declare function getRoleDetail(id: string | number): Promise<import('../utils/request').ApiResponse<RoleInfo>>;
|
|
8
|
+
export declare function createRole(data: Partial<RoleInfo>): Promise<import('../utils/request').ApiResponse<RoleInfo>>;
|
|
9
|
+
export declare function updateRole(id: string | number, data: Partial<RoleInfo>): Promise<import('../utils/request').ApiResponse<RoleInfo>>;
|
|
10
|
+
export declare function deleteRole(id: string | number): Promise<import('../utils/request').ApiResponse<unknown>>;
|
|
11
|
+
export declare function updateRoleStatus(id: string | number, status: number): Promise<import('../utils/request').ApiResponse<unknown>>;
|
|
12
|
+
export declare function getMenuList(): Promise<import('../utils/request').ApiResponse<MenuItem[]>>;
|
|
13
|
+
export declare function getMenuTree(): Promise<import('../utils/request').ApiResponse<MenuItem[]>>;
|
|
14
|
+
export declare function createMenu(data: Partial<MenuItem>): Promise<import('../utils/request').ApiResponse<MenuItem>>;
|
|
15
|
+
export declare function updateMenu(id: string | number, data: Partial<MenuItem>): Promise<import('../utils/request').ApiResponse<MenuItem>>;
|
|
16
|
+
export declare function deleteMenu(id: string | number): Promise<import('../utils/request').ApiResponse<unknown>>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { PageParams, PageResponse } from '../utils/request';
|
|
2
|
+
import { UserInfo } from '../types/api';
|
|
3
|
+
export declare function getUserList(params: PageParams & {
|
|
4
|
+
status?: number;
|
|
5
|
+
keyword?: string;
|
|
6
|
+
}): Promise<import('../utils/request').ApiResponse<PageResponse<UserInfo>>>;
|
|
7
|
+
export declare function getUserDetail(id: string | number): Promise<import('../utils/request').ApiResponse<UserInfo>>;
|
|
8
|
+
export declare function createUser(data: Partial<UserInfo>): Promise<import('../utils/request').ApiResponse<UserInfo>>;
|
|
9
|
+
export declare function updateUser(id: string | number, data: Partial<UserInfo>): Promise<import('../utils/request').ApiResponse<UserInfo>>;
|
|
10
|
+
export declare function deleteUser(id: string | number): Promise<import('../utils/request').ApiResponse<unknown>>;
|
|
11
|
+
export declare function batchDeleteUsers(ids: (string | number)[]): Promise<import('../utils/request').ApiResponse<unknown>>;
|
|
12
|
+
export declare function updateUserStatus(id: string | number, status: number): Promise<import('../utils/request').ApiResponse<unknown>>;
|
|
13
|
+
export declare function resetPassword(id: string | number): Promise<import('../utils/request').ApiResponse<unknown>>;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
declare const _default: import('vue').DefineComponent<{}, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, HTMLDivElement>;
|
|
2
|
+
export default _default;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
declare const _default: import('vue').DefineComponent<{}, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {
|
|
2
|
+
dropdownRef: HTMLDivElement;
|
|
3
|
+
}, HTMLDivElement>;
|
|
4
|
+
export default _default;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
declare const _default: import('vue').DefineComponent<{}, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, HTMLDivElement>;
|
|
2
|
+
export default _default;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
declare const _default: import('vue').DefineComponent<{}, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, HTMLDivElement>;
|
|
2
|
+
export default _default;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
declare const _default: import('vue').DefineComponent<{}, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, HTMLDivElement>;
|
|
2
|
+
export default _default;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 权限组合函数
|
|
3
|
+
*/
|
|
4
|
+
export declare function useAuth(): {
|
|
5
|
+
hasPermission: (permission: string | string[]) => boolean;
|
|
6
|
+
hasRole: (role: string | string[]) => boolean;
|
|
7
|
+
isAdmin: import('vue').ComputedRef<boolean>;
|
|
8
|
+
isLoggedIn: import('vue').ComputedRef<boolean>;
|
|
9
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 表单组合函数
|
|
3
|
+
*/
|
|
4
|
+
export interface FormOptions<T = any> {
|
|
5
|
+
rules?: Record<string, any[]>;
|
|
6
|
+
onSubmit?: (data: T) => Promise<void> | void;
|
|
7
|
+
}
|
|
8
|
+
export declare function useForm<T extends Record<string, any> = Record<string, any>>(initialValues: T, options?: FormOptions<T>): {
|
|
9
|
+
formRef: import('vue').Ref<any, any>;
|
|
10
|
+
formData: import('vue').Reactive<T>;
|
|
11
|
+
rules: Record<string, any[]> | undefined;
|
|
12
|
+
loading: import('vue').Ref<boolean, boolean>;
|
|
13
|
+
visible: import('vue').Ref<boolean, boolean>;
|
|
14
|
+
isEdit: import('vue').Ref<boolean, boolean>;
|
|
15
|
+
openAdd: () => void;
|
|
16
|
+
openEdit: (data: Partial<T>) => void;
|
|
17
|
+
close: () => void;
|
|
18
|
+
resetForm: () => void;
|
|
19
|
+
handleSubmit: () => Promise<void>;
|
|
20
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 表格组合函数
|
|
3
|
+
*/
|
|
4
|
+
export interface TableOptions<T = any> {
|
|
5
|
+
fetchData: (params: any) => Promise<{
|
|
6
|
+
list: T[];
|
|
7
|
+
total: number;
|
|
8
|
+
}>;
|
|
9
|
+
defaultPageSize?: number;
|
|
10
|
+
}
|
|
11
|
+
export declare function useTable<T = any>(options: TableOptions<T>): {
|
|
12
|
+
loading: import('vue').Ref<boolean, boolean>;
|
|
13
|
+
data: any;
|
|
14
|
+
total: import('vue').Ref<number, number>;
|
|
15
|
+
currentPage: import('vue').Ref<number, number>;
|
|
16
|
+
pageSize: import('vue').Ref<number, number>;
|
|
17
|
+
searchParams: Record<string, any>;
|
|
18
|
+
pagination: import('vue').ComputedRef<{
|
|
19
|
+
current: number;
|
|
20
|
+
pageSize: number;
|
|
21
|
+
total: number;
|
|
22
|
+
}>;
|
|
23
|
+
getData: () => Promise<void>;
|
|
24
|
+
handleSearch: () => void;
|
|
25
|
+
handleReset: () => void;
|
|
26
|
+
handlePageChange: (page: number) => void;
|
|
27
|
+
handleSizeChange: (size: number) => void;
|
|
28
|
+
refresh: () => void;
|
|
29
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 枚举常量
|
|
3
|
+
*/
|
|
4
|
+
export declare enum Status {
|
|
5
|
+
ENABLED = 1,
|
|
6
|
+
DISABLED = 0
|
|
7
|
+
}
|
|
8
|
+
export declare enum Gender {
|
|
9
|
+
UNKNOWN = 0,
|
|
10
|
+
MALE = 1,
|
|
11
|
+
FEMALE = 2
|
|
12
|
+
}
|
|
13
|
+
export declare enum MenuType {
|
|
14
|
+
DIRECTORY = 0,
|
|
15
|
+
MENU = 1,
|
|
16
|
+
BUTTON = 2
|
|
17
|
+
}
|
|
18
|
+
export declare const StatusText: Record<Status, string>;
|
|
19
|
+
export declare const GenderText: Record<Gender, string>;
|
|
20
|
+
export declare const MenuTypeText: Record<MenuType, string>;
|
|
21
|
+
export declare const StatusOptions: {
|
|
22
|
+
label: string;
|
|
23
|
+
value: Status;
|
|
24
|
+
}[];
|
|
25
|
+
export declare const GenderOptions: {
|
|
26
|
+
label: string;
|
|
27
|
+
value: Gender;
|
|
28
|
+
}[];
|
|
29
|
+
export declare const MenuTypeOptions: {
|
|
30
|
+
label: string;
|
|
31
|
+
value: MenuType;
|
|
32
|
+
}[];
|