create-young-proj 0.6.1 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +5 -3
- package/dist/index.mjs +9 -9
- package/package.json +1 -1
- package/template-nuxt-admin/Dockerfile +41 -0
- package/template-nuxt-admin/README.md +35 -0
- package/template-nuxt-admin/app.vue +41 -0
- package/template-nuxt-admin/boot.mjs +16 -0
- package/template-nuxt-admin/components/ScreenFull.vue +18 -0
- package/template-nuxt-admin/components/TopSearch.vue +73 -0
- package/template-nuxt-admin/components/TopUser.vue +69 -0
- package/template-nuxt-admin/components/YoungChangePassword.vue +87 -0
- package/template-nuxt-admin/components/YoungCodeInput.vue +60 -0
- package/template-nuxt-admin/components/YoungLink.vue +23 -0
- package/template-nuxt-admin/components/YoungLoading.vue +39 -0
- package/template-nuxt-admin/components/layout/Footer.vue +29 -0
- package/template-nuxt-admin/components/layout/Logo.vue +52 -0
- package/template-nuxt-admin/components/layout/Main.vue +41 -0
- package/template-nuxt-admin/components/layout/NavBar.vue +77 -0
- package/template-nuxt-admin/components/layout/SideBar.vue +90 -0
- package/template-nuxt-admin/components/layout/SubMenu.vue +46 -0
- package/template-nuxt-admin/components/layout/TabsBar.vue +183 -0
- package/template-nuxt-admin/composables/api.ts +104 -0
- package/template-nuxt-admin/composables/apis/delete.ts +37 -0
- package/template-nuxt-admin/composables/apis/get.ts +83 -0
- package/template-nuxt-admin/composables/apis/index.ts +10 -0
- package/template-nuxt-admin/composables/apis/patch.ts +74 -0
- package/template-nuxt-admin/composables/apis/post.ts +85 -0
- package/template-nuxt-admin/composables/config.ts +13 -0
- package/template-nuxt-admin/composables/icon.ts +27 -0
- package/template-nuxt-admin/composables/nav.ts +60 -0
- package/template-nuxt-admin/composables/tags.ts +108 -0
- package/template-nuxt-admin/composables/user.ts +29 -0
- package/template-nuxt-admin/config/.devrc +1 -0
- package/template-nuxt-admin/config/.onlinerc +1 -0
- package/template-nuxt-admin/config/.testrc +1 -0
- package/template-nuxt-admin/env.d.ts +47 -0
- package/template-nuxt-admin/error.vue +53 -0
- package/template-nuxt-admin/layouts/blank.vue +9 -0
- package/template-nuxt-admin/layouts/default.vue +124 -0
- package/template-nuxt-admin/middleware/auth.global.ts +39 -0
- package/template-nuxt-admin/nuxt.config.ts +101 -0
- package/template-nuxt-admin/package.json +44 -0
- package/template-nuxt-admin/pages/home/[id].vue +28 -0
- package/template-nuxt-admin/pages/index.vue +20 -0
- package/template-nuxt-admin/pages/login.vue +179 -0
- package/template-nuxt-admin/pages/system/api.vue +166 -0
- package/template-nuxt-admin/pages/system/hooks/useRole.ts +336 -0
- package/template-nuxt-admin/pages/system/menuList.vue +329 -0
- package/template-nuxt-admin/pages/system/role.vue +117 -0
- package/template-nuxt-admin/pages/system/user.vue +214 -0
- package/template-nuxt-admin/plugins/directive.ts +26 -0
- package/template-nuxt-admin/public/default_avatar.svg +1 -0
- package/template-nuxt-admin/public/favicon.ico +0 -0
- package/template-nuxt-admin/public/image_placeholder.svg +15 -0
- package/template-nuxt-admin/public/tabbar_bg.png +0 -0
- package/template-nuxt-admin/rome.json +26 -0
- package/template-nuxt-admin/server/api/[...all].ts +10 -0
- package/template-nuxt-admin/server/plugins/env.ts +89 -0
- package/template-nuxt-admin/server/routes/get/env.ts +13 -0
- package/template-nuxt-admin/server/tsconfig.json +3 -0
- package/template-nuxt-admin/server/utils/index.ts +35 -0
- package/template-nuxt-admin/styles/element.scss +30 -0
- package/template-nuxt-admin/styles/index.scss +59 -0
- package/template-nuxt-admin/styles/variable.scss +103 -0
- package/template-nuxt-admin/tsconfig.json +7 -0
- package/template-nuxt-admin/typings/global.d.ts +16 -0
- package/template-nuxt-admin/typings/system.d.ts +66 -0
- package/template-nuxt-admin/typings/user.d.ts +19 -0
- package/template-nuxt-admin/uno.config.ts +40 -0
- package/template-nuxt-admin/utils/tool.ts +207 -0
- package/template-nuxt-admin/yarn.lock +6849 -0
- package/template-uni-app/_npmrc +2 -0
- package/template-uni-app/src/layouts/tabbar.vue +6 -6
- package/template-uni-app/src/pages/index.vue +16 -12
- package/template-uni-app/src/pages/my.vue +7 -11
@@ -0,0 +1,183 @@
|
|
1
|
+
<!--
|
2
|
+
* @Author: zhangyang
|
3
|
+
* @Date: 2023-07-21 17:05:40
|
4
|
+
* @LastEditTime: 2023-07-23 17:00:42
|
5
|
+
* @Description:
|
6
|
+
-->
|
7
|
+
<script lang="ts" setup>
|
8
|
+
import type { RouteLocationNormalized, RouteRecordRaw } from '.nuxt/vue-router';
|
9
|
+
|
10
|
+
const route = useRoute();
|
11
|
+
const tagsState = useTagsStore();
|
12
|
+
|
13
|
+
const { visitedViews } = storeToRefs(tagsState);
|
14
|
+
|
15
|
+
const tabClick = (e: any) => {
|
16
|
+
const currentName = e.paneName;
|
17
|
+
if (isActive(currentName)) {
|
18
|
+
return;
|
19
|
+
}
|
20
|
+
navigateTo(currentName);
|
21
|
+
};
|
22
|
+
|
23
|
+
const isActive = (view: RouteLocationNormalized) => view.path === route.path;
|
24
|
+
const isAffix = (route: RouteLocationNormalized | RouteRecordRaw) => route?.meta?.affix ?? false;
|
25
|
+
|
26
|
+
const toLastView = (visitedViews: RouteLocationNormalized[]) => {
|
27
|
+
const lastView = visitedViews.slice(-1)[0];
|
28
|
+
if (lastView) {
|
29
|
+
navigateTo(lastView.fullPath);
|
30
|
+
}
|
31
|
+
};
|
32
|
+
|
33
|
+
const removeTab = (currentName: any) => {
|
34
|
+
const to = visitedViews.value.find((r) => r.path === currentName as string);
|
35
|
+
if (to) {
|
36
|
+
tagsState.delView(to);
|
37
|
+
isActive(to) && toLastView(visitedViews.value);
|
38
|
+
}
|
39
|
+
|
40
|
+
if (visitedViews.value.length === 0) {
|
41
|
+
navigateTo('/');
|
42
|
+
}
|
43
|
+
};
|
44
|
+
|
45
|
+
const closeCurrentTab = () => {
|
46
|
+
removeTab(route.path);
|
47
|
+
};
|
48
|
+
|
49
|
+
const closeOtherTab = () => {
|
50
|
+
const currentName = route.path;
|
51
|
+
const to = visitedViews.value.find((r) => r.path === currentName as string);
|
52
|
+
to && tagsState.delOtherViews(to);
|
53
|
+
}
|
54
|
+
|
55
|
+
const closeAllTab = () => {
|
56
|
+
tagsState.delAllViews();
|
57
|
+
navigateTo('/');
|
58
|
+
};
|
59
|
+
</script>
|
60
|
+
|
61
|
+
<template>
|
62
|
+
<div class="tabs-bar-container">
|
63
|
+
<div class="tabs-content">
|
64
|
+
<ElTabs v-if="visitedViews.length > 0" type="card" v-model="$route.path" @tab-click="tabClick"
|
65
|
+
@tab-remove="removeTab">
|
66
|
+
<ElTabPane v-for="item in visitedViews" type="card" :key="item.path" :path="item.path"
|
67
|
+
:label="(item.meta.title as string)" :name="item.path" :closable="!isAffix(item)">
|
68
|
+
<template #label>
|
69
|
+
{{ item.meta.title }}
|
70
|
+
</template>
|
71
|
+
</ElTabPane>
|
72
|
+
</ElTabs>
|
73
|
+
</div>
|
74
|
+
<div class="tabs-action">
|
75
|
+
<ElDropdown trigger="click">
|
76
|
+
<ElIcon color="rgba(0, 0, 0, 0.65)" :size="20">
|
77
|
+
<div class="i-ep-menu" />
|
78
|
+
</ElIcon>
|
79
|
+
<template #dropdown>
|
80
|
+
<ElDropdownMenu>
|
81
|
+
<ElDropdownItem @click="closeCurrentTab">
|
82
|
+
<ElIcon :size="14">
|
83
|
+
<div class="i-ep-folder-remove" />
|
84
|
+
</ElIcon>
|
85
|
+
关闭当前
|
86
|
+
</ElDropdownItem>
|
87
|
+
<ElDropdownItem @click="closeOtherTab">
|
88
|
+
<ElIcon :size="14">
|
89
|
+
<div class="i-ep-close" />
|
90
|
+
</ElIcon>
|
91
|
+
关闭其他
|
92
|
+
</ElDropdownItem>
|
93
|
+
<ElDropdownItem @click="closeAllTab">
|
94
|
+
<ElIcon :size="14">
|
95
|
+
<div class="i-ep-folder-delete" />
|
96
|
+
</ElIcon>
|
97
|
+
关闭所有
|
98
|
+
</ElDropdownItem>
|
99
|
+
</ElDropdownMenu>
|
100
|
+
</template>
|
101
|
+
</ElDropdown>
|
102
|
+
</div>
|
103
|
+
</div>
|
104
|
+
</template>
|
105
|
+
|
106
|
+
<style lang="scss" scoped>
|
107
|
+
.tabs-action {
|
108
|
+
padding-bottom: 5px;
|
109
|
+
cursor: pointer;
|
110
|
+
|
111
|
+
:deep(.el-icon) {
|
112
|
+
transition: all 0.3s;
|
113
|
+
}
|
114
|
+
}
|
115
|
+
|
116
|
+
.tabs-bar-container {
|
117
|
+
position: relative;
|
118
|
+
box-sizing: border-box;
|
119
|
+
display: flex;
|
120
|
+
align-content: center;
|
121
|
+
align-items: flex-end;
|
122
|
+
justify-content: space-between;
|
123
|
+
height: $base-tabs-bar-height;
|
124
|
+
padding-right: $base-padding;
|
125
|
+
padding-left: $base-padding;
|
126
|
+
user-select: none;
|
127
|
+
background: $base-color-white;
|
128
|
+
border-top: 1px solid #f6f6f6;
|
129
|
+
|
130
|
+
.tabs-content {
|
131
|
+
width: calc(100% - 0px);
|
132
|
+
}
|
133
|
+
|
134
|
+
:deep(.el-tabs--card) {
|
135
|
+
height: $base-tag-item-height;
|
136
|
+
|
137
|
+
.el-tabs__nav-next,
|
138
|
+
.el-tabs__nav-prev {
|
139
|
+
height: $base-tag-item-height;
|
140
|
+
line-height: $base-tag-item-height;
|
141
|
+
}
|
142
|
+
|
143
|
+
.el-tabs__header {
|
144
|
+
margin: 0;
|
145
|
+
border-bottom: 0;
|
146
|
+
}
|
147
|
+
|
148
|
+
.el-tabs__nav {
|
149
|
+
border: 0;
|
150
|
+
}
|
151
|
+
|
152
|
+
.tabs-icon {
|
153
|
+
top: 3px;
|
154
|
+
font-size: 15px;
|
155
|
+
}
|
156
|
+
|
157
|
+
.el-tabs__item {
|
158
|
+
box-sizing: border-box;
|
159
|
+
height: $base-tag-item-height;
|
160
|
+
line-height: $base-tag-item-height;
|
161
|
+
border: none;
|
162
|
+
border-radius: $base-border-radius;
|
163
|
+
transition: padding 0.3s cubic-bezier(0.645, 0.045, 0.355, 1) !important;
|
164
|
+
}
|
165
|
+
|
166
|
+
.el-tabs__item.is-active {
|
167
|
+
background-color: #e8f4ff;
|
168
|
+
-webkit-mask-image: url('/tabbar_bg.png');
|
169
|
+
mask-image: url('/tabbar_bg.png');
|
170
|
+
-webkit-mask-size: 100% 100%;
|
171
|
+
mask-size: 100% 100%;
|
172
|
+
}
|
173
|
+
|
174
|
+
.el-tabs__item:not(.is_active):hover {
|
175
|
+
background-color: #f6f8f9;
|
176
|
+
-webkit-mask-image: url('/tabbar_bg.png');
|
177
|
+
mask-image: url('/tabbar_bg.png');
|
178
|
+
-webkit-mask-size: 100% 100%;
|
179
|
+
mask-size: 100% 100%;
|
180
|
+
}
|
181
|
+
}
|
182
|
+
}
|
183
|
+
</style>
|
@@ -0,0 +1,104 @@
|
|
1
|
+
/*
|
2
|
+
* @Author: zhangyang
|
3
|
+
* @Date: 2023-06-20 17:14:58
|
4
|
+
* @LastEditTime: 2023-07-26 11:56:53
|
5
|
+
* @Description:
|
6
|
+
*/
|
7
|
+
import { useHttp } from '@bluesyoung/http';
|
8
|
+
import { useGet, usePost, usePatch, useDelete } from './apis';
|
9
|
+
|
10
|
+
export const startLoading = () => {
|
11
|
+
const { isLoading } = storeToRefs(useNavStore());
|
12
|
+
isLoading.value = true;
|
13
|
+
};
|
14
|
+
|
15
|
+
export const endLoading = () => {
|
16
|
+
const { isLoading } = storeToRefs(useNavStore());
|
17
|
+
isLoading.value = false;
|
18
|
+
};
|
19
|
+
|
20
|
+
const http = useHttp<{
|
21
|
+
code: number;
|
22
|
+
data: any;
|
23
|
+
msg: string;
|
24
|
+
}>({
|
25
|
+
timeout: -1,
|
26
|
+
loading: {
|
27
|
+
start: startLoading,
|
28
|
+
end: endLoading,
|
29
|
+
},
|
30
|
+
fail: (err: any) => {
|
31
|
+
console.log('🚀 ~ file: api.ts:28 ~ err:', err);
|
32
|
+
const { cookie } = storeToRefs(useUserStore());
|
33
|
+
if (err?.response?.status === 401) {
|
34
|
+
showDialog({
|
35
|
+
title: '温馨提示',
|
36
|
+
message: '未登录或登录过期,请登录后再继续!',
|
37
|
+
showCancelButton: true,
|
38
|
+
})
|
39
|
+
.then(() => {
|
40
|
+
cookie.value && (cookie.value.uuid = '');
|
41
|
+
navigateTo(
|
42
|
+
`/login?redirect=${encodeURIComponent(location.href.replace(location.origin, ''))}`,
|
43
|
+
);
|
44
|
+
})
|
45
|
+
.catch(() => {
|
46
|
+
navigateTo({
|
47
|
+
path: '/',
|
48
|
+
replace: true,
|
49
|
+
});
|
50
|
+
});
|
51
|
+
|
52
|
+
throw err;
|
53
|
+
}
|
54
|
+
|
55
|
+
if (typeof err === 'string') {
|
56
|
+
// 通用失败,弹出提示信息
|
57
|
+
showNotify({
|
58
|
+
type: 'danger',
|
59
|
+
message: err,
|
60
|
+
});
|
61
|
+
}
|
62
|
+
if ((err as any) instanceof Error) {
|
63
|
+
showNotify({
|
64
|
+
type: 'danger',
|
65
|
+
// 接口出错
|
66
|
+
message:
|
67
|
+
err?.response?.data?.message ||
|
68
|
+
err?.response?.data?.msg ||
|
69
|
+
err?.response?.data ||
|
70
|
+
err.message ||
|
71
|
+
'网络错误!',
|
72
|
+
});
|
73
|
+
}
|
74
|
+
|
75
|
+
throw err;
|
76
|
+
},
|
77
|
+
headers: {
|
78
|
+
getAuthHeaders: () => {
|
79
|
+
const { token } = storeToRefs(useUserStore());
|
80
|
+
return {
|
81
|
+
Authorization: `Bearer ${token.value}`,
|
82
|
+
};
|
83
|
+
},
|
84
|
+
},
|
85
|
+
checkFn: ({ code, msg, data }) => {
|
86
|
+
if (code === 0) {
|
87
|
+
// 通用成功
|
88
|
+
return data;
|
89
|
+
} else if (code === -1) {
|
90
|
+
// 通用失败
|
91
|
+
throw msg;
|
92
|
+
} else {
|
93
|
+
// 特殊状态码
|
94
|
+
throw code;
|
95
|
+
}
|
96
|
+
},
|
97
|
+
});
|
98
|
+
|
99
|
+
export const apis = http.__mixin__({
|
100
|
+
get: useGet(http),
|
101
|
+
post: usePost(http),
|
102
|
+
patch: usePatch(http),
|
103
|
+
delete: useDelete(http),
|
104
|
+
});
|
@@ -0,0 +1,37 @@
|
|
1
|
+
/*
|
2
|
+
* @Author: zhangyang
|
3
|
+
* @Date: 2023-07-26 11:54:08
|
4
|
+
* @LastEditTime: 2023-07-26 11:56:39
|
5
|
+
* @Description:
|
6
|
+
*/
|
7
|
+
import type { YoungHttp, YoungHttpAuthReq } from '@bluesyoung/http';
|
8
|
+
|
9
|
+
export const useDelete = (http: YoungHttp) => {
|
10
|
+
const AuthReq: YoungHttpAuthReq = (args) => http.authReq({ method: 'DELETE', ...args });
|
11
|
+
|
12
|
+
const del = async (url: string, ids: string) => {
|
13
|
+
await AuthReq({
|
14
|
+
url,
|
15
|
+
data: { ids },
|
16
|
+
});
|
17
|
+
};
|
18
|
+
|
19
|
+
return {
|
20
|
+
/**
|
21
|
+
* 删除用户
|
22
|
+
*/
|
23
|
+
deleteUser: async (ids: string) => del('/user/delete/batch', ids),
|
24
|
+
/**
|
25
|
+
* 删除菜单
|
26
|
+
*/
|
27
|
+
deleteMenu: async (ids: string) => del('/menu/delete/batch', ids),
|
28
|
+
/**
|
29
|
+
* 删除接口
|
30
|
+
*/
|
31
|
+
deleteApi: async (ids: string) => del('/api/delete/batch', ids),
|
32
|
+
/**
|
33
|
+
* 删除角色
|
34
|
+
*/
|
35
|
+
deleteRole: async (ids: string) => del('/role/delete/batch', ids),
|
36
|
+
};
|
37
|
+
};
|
@@ -0,0 +1,83 @@
|
|
1
|
+
/*
|
2
|
+
* @Author: zhangyang
|
3
|
+
* @Date: 2023-07-21 09:09:37
|
4
|
+
* @LastEditTime: 2023-07-26 11:58:32
|
5
|
+
* @Description:
|
6
|
+
*/
|
7
|
+
import type { YoungHttp, YoungHttpFreeReq, YoungHttpAuthReq } from '@bluesyoung/http';
|
8
|
+
|
9
|
+
export const useGet = (http: YoungHttp) => {
|
10
|
+
const FreeReq: YoungHttpFreeReq = (args) => http.freeReq({ method: 'GET', ...args });
|
11
|
+
const AuthReq: YoungHttpAuthReq = (args) => http.authReq({ method: 'GET', ...args });
|
12
|
+
|
13
|
+
return {
|
14
|
+
/**
|
15
|
+
* 发送短信验证码
|
16
|
+
*/
|
17
|
+
sendCode: async (phone: string) => {
|
18
|
+
showToast(`todo: ${phone}发送短信验证码`);
|
19
|
+
// await FreeReq({ url: '/v1/user/sendCode', params: { phone } });
|
20
|
+
},
|
21
|
+
/**
|
22
|
+
* 获取用户的菜单树
|
23
|
+
*/
|
24
|
+
getUserMenuTree: async () => {
|
25
|
+
return AuthReq<Record<number, NavArrItem>>({
|
26
|
+
url: '/menu/tree',
|
27
|
+
});
|
28
|
+
},
|
29
|
+
/**
|
30
|
+
* 获取角色列表
|
31
|
+
*/
|
32
|
+
getRoleList: async (params: Partial<BaseQuery> = {}) =>
|
33
|
+
AuthReq<PagesData>({
|
34
|
+
url: `/role/list`,
|
35
|
+
params,
|
36
|
+
}),
|
37
|
+
/**
|
38
|
+
* 获取用户列表
|
39
|
+
*/
|
40
|
+
getUserList: async (params: Partial<BaseQuery> = {}) =>
|
41
|
+
AuthReq<PagesData>({
|
42
|
+
url: '/user/list',
|
43
|
+
|
44
|
+
params,
|
45
|
+
}),
|
46
|
+
/**
|
47
|
+
* 获取菜单列表
|
48
|
+
*/
|
49
|
+
getMenuList: async () =>
|
50
|
+
AuthReq<Record<string, NavArrItem>>({
|
51
|
+
url: '/menu/list',
|
52
|
+
}),
|
53
|
+
/**
|
54
|
+
* 获取接口列表
|
55
|
+
*/
|
56
|
+
getApiList: async (params: Partial<BaseQuery> = {}) =>
|
57
|
+
AuthReq<PagesData>({
|
58
|
+
url: '/api/list',
|
59
|
+
|
60
|
+
params,
|
61
|
+
}),
|
62
|
+
/**
|
63
|
+
* 获取角色拥有权限的菜单
|
64
|
+
*/
|
65
|
+
getRoleMenuTree: async (id: number) =>
|
66
|
+
AuthReq<{
|
67
|
+
list: NavArrItem[];
|
68
|
+
accessIds: number[];
|
69
|
+
}>({
|
70
|
+
url: `/menu/all/${id}`,
|
71
|
+
}),
|
72
|
+
/**
|
73
|
+
* 获取角色拥有的接口权限
|
74
|
+
*/
|
75
|
+
getRoleApis: async (id: number) =>
|
76
|
+
AuthReq<{
|
77
|
+
list: ApiItem[];
|
78
|
+
accessIds: number[];
|
79
|
+
}>({
|
80
|
+
url: `/api/all/category/${id}`,
|
81
|
+
}),
|
82
|
+
};
|
83
|
+
};
|
@@ -0,0 +1,74 @@
|
|
1
|
+
/*
|
2
|
+
* @Author: zhangyang
|
3
|
+
* @Date: 2023-07-26 11:51:44
|
4
|
+
* @LastEditTime: 2023-07-26 16:37:45
|
5
|
+
* @Description:
|
6
|
+
*/
|
7
|
+
import type { YoungHttp, YoungHttpAuthReq } from '@bluesyoung/http';
|
8
|
+
|
9
|
+
export const usePatch = (http: YoungHttp) => {
|
10
|
+
const AuthReq: YoungHttpAuthReq = (args) => http.authReq({ method: 'PATCH', ...args });
|
11
|
+
|
12
|
+
return {
|
13
|
+
/**
|
14
|
+
* 更新接口
|
15
|
+
*/
|
16
|
+
changeApiItem: async ({ id, ...data }: Partial<ApiItem>) => {
|
17
|
+
await AuthReq({
|
18
|
+
url: `/api/update/${id}`,
|
19
|
+
data,
|
20
|
+
});
|
21
|
+
},
|
22
|
+
/**
|
23
|
+
* 更新菜单信息
|
24
|
+
*/
|
25
|
+
changeMenuItem: async ({ id, ...data }: Partial<NavArrItem>) => {
|
26
|
+
await AuthReq({
|
27
|
+
url: `/menu/update/${id}`,
|
28
|
+
data,
|
29
|
+
});
|
30
|
+
},
|
31
|
+
/**
|
32
|
+
* 更新角色
|
33
|
+
*/
|
34
|
+
changeRoleItem: async ({ id, ...data }: Partial<RoleItem>) => {
|
35
|
+
await AuthReq({
|
36
|
+
url: `/role/update/${id}`,
|
37
|
+
data,
|
38
|
+
});
|
39
|
+
},
|
40
|
+
/**
|
41
|
+
* 更新角色菜单权限
|
42
|
+
*/
|
43
|
+
changeRoleMenu: async (roleId: number, add: number[], del: number[]) => {
|
44
|
+
await AuthReq({
|
45
|
+
url: `role/menus/update/${roleId}`,
|
46
|
+
data: {
|
47
|
+
create: add,
|
48
|
+
delete: del,
|
49
|
+
},
|
50
|
+
});
|
51
|
+
},
|
52
|
+
/**
|
53
|
+
* 更新角色接口权限
|
54
|
+
*/
|
55
|
+
changeRoleApi: async (roleId: number, add: number[], del: number[]) => {
|
56
|
+
await AuthReq({
|
57
|
+
url: `role/apis/update/${roleId}`,
|
58
|
+
data: {
|
59
|
+
create: add,
|
60
|
+
delete: del,
|
61
|
+
},
|
62
|
+
});
|
63
|
+
},
|
64
|
+
/**
|
65
|
+
* 更新用户信息
|
66
|
+
*/
|
67
|
+
changeUserItem: async ({ id, ...data }: Partial<UserItem>) => {
|
68
|
+
await AuthReq({
|
69
|
+
url: `/user/update/${id}`,
|
70
|
+
data,
|
71
|
+
});
|
72
|
+
},
|
73
|
+
};
|
74
|
+
};
|
@@ -0,0 +1,85 @@
|
|
1
|
+
/*
|
2
|
+
* @Author: zhangyang
|
3
|
+
* @Date: 2023-07-21 09:21:02
|
4
|
+
* @LastEditTime: 2023-07-26 16:39:22
|
5
|
+
* @Description:
|
6
|
+
*/
|
7
|
+
import type { YoungHttp, YoungHttpFreeReq, YoungHttpAuthReq } from '@bluesyoung/http';
|
8
|
+
import { telMasaike } from '@bluesyoung/utils';
|
9
|
+
|
10
|
+
export const usePost = (http: YoungHttp) => {
|
11
|
+
const FreeReq: YoungHttpFreeReq = (args) => http.freeReq({ method: 'POST', ...args });
|
12
|
+
const AuthReq: YoungHttpAuthReq = (args) => http.authReq({ method: 'POST', ...args });
|
13
|
+
|
14
|
+
return {
|
15
|
+
login: async (args: LoginForm) => {
|
16
|
+
console.log('🚀 ~ file: post.ts:15 ~ login: ~ args:', args);
|
17
|
+
|
18
|
+
const { token } = await FreeReq({
|
19
|
+
url: '/base/login',
|
20
|
+
data: {
|
21
|
+
username: 'super',
|
22
|
+
password: '123456',
|
23
|
+
},
|
24
|
+
});
|
25
|
+
|
26
|
+
return {
|
27
|
+
uuid: '9527',
|
28
|
+
nickname: '用户xxx',
|
29
|
+
headimgurl: 'https://avatars.githubusercontent.com/u/55608642?v=4',
|
30
|
+
token,
|
31
|
+
phone: telMasaike(args.mobile),
|
32
|
+
} as UserLoginRes;
|
33
|
+
},
|
34
|
+
changePassword: async (args: LoginForm) => {
|
35
|
+
console.log('🚀 ~ file: post.ts:15 ~ login: ~ args:', args);
|
36
|
+
showToast('todo: user change password');
|
37
|
+
|
38
|
+
return {
|
39
|
+
uuid: '9527',
|
40
|
+
nickname: '用户xxx',
|
41
|
+
headimgurl: 'https://avatars.githubusercontent.com/u/55608642?v=4',
|
42
|
+
token: 'xxx',
|
43
|
+
phone: telMasaike(args.mobile),
|
44
|
+
} as UserLoginRes;
|
45
|
+
},
|
46
|
+
|
47
|
+
/**
|
48
|
+
* 创建接口
|
49
|
+
*/
|
50
|
+
addApiItem: async (data: ApiItem) => {
|
51
|
+
await AuthReq({
|
52
|
+
url: '/api/create',
|
53
|
+
data,
|
54
|
+
});
|
55
|
+
},
|
56
|
+
/**
|
57
|
+
* 创建菜单
|
58
|
+
*/
|
59
|
+
addMenuItem: async (data: NavArrItem) => {
|
60
|
+
await AuthReq({
|
61
|
+
url: '/menu/create',
|
62
|
+
data,
|
63
|
+
});
|
64
|
+
},
|
65
|
+
/**
|
66
|
+
* 创建角色
|
67
|
+
*/
|
68
|
+
addRoleItem: async (data: RoleItem) => {
|
69
|
+
await AuthReq({
|
70
|
+
url: '/role/create',
|
71
|
+
data,
|
72
|
+
});
|
73
|
+
},
|
74
|
+
|
75
|
+
/**
|
76
|
+
* 创建用户
|
77
|
+
*/
|
78
|
+
addUserItem: async (data: UserItem) => {
|
79
|
+
await AuthReq({
|
80
|
+
url: '/user/create',
|
81
|
+
data,
|
82
|
+
});
|
83
|
+
},
|
84
|
+
};
|
85
|
+
};
|
@@ -0,0 +1,27 @@
|
|
1
|
+
/*
|
2
|
+
* @Author: zhangyang
|
3
|
+
* @Date: 2023-07-21 15:20:01
|
4
|
+
* @LastEditTime: 2023-07-21 15:49:22
|
5
|
+
* @Description:
|
6
|
+
* @unocss-include
|
7
|
+
*/
|
8
|
+
import type { SelectOptionItem } from '@bluesyoung/ui-vue3-element-plus';
|
9
|
+
|
10
|
+
export const MenuIcons = [
|
11
|
+
'i-icon-park-solid-analysis',
|
12
|
+
'i-ant-design-account-book-outlined',
|
13
|
+
'i-ant-design-bulb-outlined',
|
14
|
+
'i-icon-park-solid-application',
|
15
|
+
'i-icon-park-solid-apple-one',
|
16
|
+
'i-icon-park-solid-align-text-right-one',
|
17
|
+
'i-icon-park-solid-auto-focus',
|
18
|
+
'i-humbleicons-crown',
|
19
|
+
'i-icon-park-solid-add-user',
|
20
|
+
'i-typcn-device-desktop',
|
21
|
+
'i-icon-park-solid-application-two',
|
22
|
+
] as const;
|
23
|
+
|
24
|
+
export const MenuIconList: SelectOptionItem[] = MenuIcons.map((label) => ({
|
25
|
+
label,
|
26
|
+
value: label,
|
27
|
+
}));
|
@@ -0,0 +1,60 @@
|
|
1
|
+
/*
|
2
|
+
* @Author: zhangyang
|
3
|
+
* @Date: 2023-06-01 12:03:44
|
4
|
+
* @LastEditTime: 2023-07-28 17:43:00
|
5
|
+
* @Description:
|
6
|
+
*/
|
7
|
+
export const useNavStore = defineStore('useNavStore', () => {
|
8
|
+
const title = ref('');
|
9
|
+
const sub_title = ref('');
|
10
|
+
/**
|
11
|
+
* 树形导航数组(仅可见)
|
12
|
+
*/
|
13
|
+
const nav_arr = ref<NavArrItem[]>([]);
|
14
|
+
/**
|
15
|
+
* 拍平之后的导航数组(仅可见,用于快速搜索)
|
16
|
+
*/
|
17
|
+
const flat_nav_arr = ref<NavArrItem[]>([]);
|
18
|
+
/**
|
19
|
+
* 拥有权限的路由
|
20
|
+
*/
|
21
|
+
const auth_routes = ref<string[]>([]);
|
22
|
+
|
23
|
+
const active_nav = ref('');
|
24
|
+
|
25
|
+
const isLoading = ref(false);
|
26
|
+
const isCollapse = ref(false);
|
27
|
+
|
28
|
+
watch(
|
29
|
+
() => WindowSize['lt-lg'],
|
30
|
+
(v) => {
|
31
|
+
isCollapse.value = v;
|
32
|
+
},
|
33
|
+
{
|
34
|
+
immediate: true,
|
35
|
+
},
|
36
|
+
);
|
37
|
+
|
38
|
+
watchEffect(() => {
|
39
|
+
if (isLoading.value) {
|
40
|
+
document.body.style.overflow = 'hidden';
|
41
|
+
} else {
|
42
|
+
document.body.style.overflow = 'auto';
|
43
|
+
}
|
44
|
+
});
|
45
|
+
|
46
|
+
return {
|
47
|
+
title,
|
48
|
+
sub_title,
|
49
|
+
nav_arr,
|
50
|
+
active_nav,
|
51
|
+
flat_nav_arr,
|
52
|
+
auth_routes,
|
53
|
+
isLoading,
|
54
|
+
isCollapse,
|
55
|
+
};
|
56
|
+
});
|
57
|
+
|
58
|
+
if (import.meta.hot) {
|
59
|
+
import.meta.hot.accept(acceptHMRUpdate(useNavStore, import.meta.hot));
|
60
|
+
}
|