create-jnrs-vue 1.2.11
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/LICENSE +21 -0
- package/README.md +61 -0
- package/bin/create.mjs +221 -0
- package/bin/upgrade.mjs +40 -0
- package/jnrs-template-vue/.env.development +13 -0
- package/jnrs-template-vue/.env.production +4 -0
- package/jnrs-template-vue/.prettierrc.json +12 -0
- package/jnrs-template-vue/README.md +48 -0
- package/jnrs-template-vue/auto-imports.d.ts +17 -0
- package/jnrs-template-vue/components.d.ts +51 -0
- package/jnrs-template-vue/eslint.config.ts +40 -0
- package/jnrs-template-vue/index.html +13 -0
- package/jnrs-template-vue/package.json +55 -0
- package/jnrs-template-vue/public/favicon.ico +0 -0
- package/jnrs-template-vue/public/system/menu.json +137 -0
- package/jnrs-template-vue/src/App.vue +45 -0
- package/jnrs-template-vue/src/api/common/index.ts +28 -0
- package/jnrs-template-vue/src/api/demos/index.ts +155 -0
- package/jnrs-template-vue/src/api/request.ts +53 -0
- package/jnrs-template-vue/src/api/system/index.ts +107 -0
- package/jnrs-template-vue/src/api/user/index.ts +12 -0
- package/jnrs-template-vue/src/assets/fonts/.keep +0 -0
- package/jnrs-template-vue/src/assets/fonts/AlibabaPuHuiTi-Regular.woff2 +0 -0
- package/jnrs-template-vue/src/assets/fonts/AlimamaShuHeiTi-Bold.woff2 +0 -0
- package/jnrs-template-vue/src/assets/images/common/403.png +0 -0
- package/jnrs-template-vue/src/assets/images/common/404.png +0 -0
- package/jnrs-template-vue/src/assets/images/common/avatar.png +0 -0
- package/jnrs-template-vue/src/assets/images/common/jnrs-white.svg +1 -0
- package/jnrs-template-vue/src/assets/styles/animation.scss +0 -0
- package/jnrs-template-vue/src/assets/styles/common.scss +39 -0
- package/jnrs-template-vue/src/assets/styles/fonts.scss +27 -0
- package/jnrs-template-vue/src/assets/styles/index.scss +5 -0
- package/jnrs-template-vue/src/assets/styles/init.scss +41 -0
- package/jnrs-template-vue/src/assets/styles/root.scss +13 -0
- package/jnrs-template-vue/src/components/common/CardTable.vue +90 -0
- package/jnrs-template-vue/src/components/common/DictTag.vue +74 -0
- package/jnrs-template-vue/src/components/common/ImageView.vue +144 -0
- package/jnrs-template-vue/src/components/common/PdfView.vue +115 -0
- package/jnrs-template-vue/src/components/select/SelectManager.vue +26 -0
- package/jnrs-template-vue/src/directives/permissions.ts +28 -0
- package/jnrs-template-vue/src/layout/BlankLayout.vue +15 -0
- package/jnrs-template-vue/src/layout/RouterTabs /344/277/256/345/244/215/350/267/257/347/224/261/350/267/263/350/275/254/346/220/272/345/270/246/345/217/202/346/225/260/351/227/256/351/242/230.vue" +150 -0
- package/jnrs-template-vue/src/layout/RouterTabs.vue +142 -0
- package/jnrs-template-vue/src/layout/SideMenu.vue +208 -0
- package/jnrs-template-vue/src/layout/SideMenuItem.vue +38 -0
- package/jnrs-template-vue/src/layout/TopHeader.vue +184 -0
- package/jnrs-template-vue/src/layout/index.vue +71 -0
- package/jnrs-template-vue/src/locales/en.ts +14 -0
- package/jnrs-template-vue/src/locales/index.ts +23 -0
- package/jnrs-template-vue/src/locales/zhCn.ts +14 -0
- package/jnrs-template-vue/src/main.ts +31 -0
- package/jnrs-template-vue/src/router/index.ts +77 -0
- package/jnrs-template-vue/src/router/routes.ts +48 -0
- package/jnrs-template-vue/src/types/env.d.ts +12 -0
- package/jnrs-template-vue/src/types/index.ts +81 -0
- package/jnrs-template-vue/src/types/webSocket.ts +19 -0
- package/jnrs-template-vue/src/utils/file.ts +56 -0
- package/jnrs-template-vue/src/utils/packages.ts +116 -0
- package/jnrs-template-vue/src/utils/permissions.ts +16 -0
- package/jnrs-template-vue/src/views/common/403.vue +52 -0
- package/jnrs-template-vue/src/views/common/404.vue +52 -0
- package/jnrs-template-vue/src/views/demos/crud/index.vue +355 -0
- package/jnrs-template-vue/src/views/demos/simpleTable/index.vue +41 -0
- package/jnrs-template-vue/src/views/demos/unitTest/RequestPage.vue +137 -0
- package/jnrs-template-vue/src/views/demos/unitTest/index.vue +131 -0
- package/jnrs-template-vue/src/views/home/index.vue +9 -0
- package/jnrs-template-vue/src/views/lingshuSmart/editorPage.vue +9 -0
- package/jnrs-template-vue/src/views/login/index.vue +314 -0
- package/jnrs-template-vue/src/views/system/dict/index.vue +161 -0
- package/jnrs-template-vue/src/views/system/menu/index.vue +43 -0
- package/jnrs-template-vue/src/views/system/mine/baseInfo.vue +108 -0
- package/jnrs-template-vue/src/views/system/mine/index.vue +83 -0
- package/jnrs-template-vue/src/views/system/mine/securitySettings.vue +105 -0
- package/jnrs-template-vue/src/views/system/role/editDialog.vue +94 -0
- package/jnrs-template-vue/src/views/system/role/index.vue +41 -0
- package/jnrs-template-vue/src/views/visual/index.vue +143 -0
- package/jnrs-template-vue/tsconfig.json +25 -0
- package/jnrs-template-vue/vite.config.ts +71 -0
- package/jnrs-template-vue/viteMockServe/fail.ts +38 -0
- package/jnrs-template-vue/viteMockServe/file/mock-pdf.pdf +0 -0
- package/jnrs-template-vue/viteMockServe/file/mock-png-0.png +0 -0
- package/jnrs-template-vue/viteMockServe/file/mock-png-1.png +0 -0
- package/jnrs-template-vue/viteMockServe/file.ts +67 -0
- package/jnrs-template-vue/viteMockServe/index.ts +87 -0
- package/jnrs-template-vue/viteMockServe/json/detailsRes.json +56 -0
- package/jnrs-template-vue/viteMockServe/json/dictItemRes.json +27 -0
- package/jnrs-template-vue/viteMockServe/json/dictRes.json +21 -0
- package/jnrs-template-vue/viteMockServe/json/loginRes_admin.json +157 -0
- package/jnrs-template-vue/viteMockServe/json/loginRes_user.json +713 -0
- package/jnrs-template-vue/viteMockServe/json/roleRes.json +37 -0
- package/jnrs-template-vue/viteMockServe/json/tableRes.json +390 -0
- package/jnrs-template-vue/viteMockServe/success.ts +39 -0
- package/package.json +41 -0
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
{
|
|
2
|
+
"code": 0,
|
|
3
|
+
"msg": "操作成功",
|
|
4
|
+
"data": [
|
|
5
|
+
{
|
|
6
|
+
"meta": {
|
|
7
|
+
"title": "功能演示",
|
|
8
|
+
"icon": "StarFilled",
|
|
9
|
+
"todoCount": 4
|
|
10
|
+
},
|
|
11
|
+
"children": [
|
|
12
|
+
{
|
|
13
|
+
"path": "/unitTest",
|
|
14
|
+
"name": "UnitTest",
|
|
15
|
+
"meta": {
|
|
16
|
+
"title": "基础功能测试",
|
|
17
|
+
"todoCount": 8
|
|
18
|
+
},
|
|
19
|
+
"component": "/demos/unitTest/index"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"path": "/simpleTable",
|
|
23
|
+
"name": "SimpleTable",
|
|
24
|
+
"meta": {
|
|
25
|
+
"title": "简单数据表格模板",
|
|
26
|
+
"todoCount": 0
|
|
27
|
+
},
|
|
28
|
+
"component": "/demos/simpleTable/index"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"path": "/crud",
|
|
32
|
+
"name": "Crud",
|
|
33
|
+
"meta": {
|
|
34
|
+
"title": "完整增删改查模板",
|
|
35
|
+
"todoCount": 0
|
|
36
|
+
},
|
|
37
|
+
"component": "/demos/crud/index"
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"path": "/testRedirect",
|
|
41
|
+
"name": "TestRedirect",
|
|
42
|
+
"meta": {
|
|
43
|
+
"title": "重定向测试"
|
|
44
|
+
},
|
|
45
|
+
"redirect": "/crud"
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"path": "/testAlias",
|
|
49
|
+
"name": "TestAlias",
|
|
50
|
+
"meta": {
|
|
51
|
+
"title": "相同component不同path",
|
|
52
|
+
"testId": 1
|
|
53
|
+
},
|
|
54
|
+
"component": "/demos/crud/index"
|
|
55
|
+
}
|
|
56
|
+
]
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"path": "/visual",
|
|
60
|
+
"name": "Visual",
|
|
61
|
+
"meta": {
|
|
62
|
+
"title": "可视化看板",
|
|
63
|
+
"icon": "Platform",
|
|
64
|
+
"noAuth": true,
|
|
65
|
+
"global": true
|
|
66
|
+
},
|
|
67
|
+
"component": "/visual/index"
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"path": "/lingshuSmart/editorPage",
|
|
71
|
+
"name": "LingshuSmartEditorPage",
|
|
72
|
+
"meta": {
|
|
73
|
+
"title": "Lingshu Smart",
|
|
74
|
+
"icon": "Promotion",
|
|
75
|
+
"noAuth": true,
|
|
76
|
+
"global": true
|
|
77
|
+
},
|
|
78
|
+
"component": "/lingshuSmart/editorPage"
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"meta": {
|
|
82
|
+
"title": "系统管理",
|
|
83
|
+
"icon": "Tools",
|
|
84
|
+
"todoCount": 99
|
|
85
|
+
},
|
|
86
|
+
"children": [
|
|
87
|
+
{
|
|
88
|
+
"path": "/system/mine/index",
|
|
89
|
+
"name": "SystemMine",
|
|
90
|
+
"meta": {
|
|
91
|
+
"title": "个人中心",
|
|
92
|
+
"todoCount": 999,
|
|
93
|
+
"permissions": ["mine:view", "mine:edit"]
|
|
94
|
+
},
|
|
95
|
+
"component": "/system/mine/index"
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
"path": "/system/user",
|
|
99
|
+
"name": "SystemUser",
|
|
100
|
+
"meta": {
|
|
101
|
+
"title": "用户管理",
|
|
102
|
+
"todoCount": 0,
|
|
103
|
+
"permissions": ["user:view", "user:edit"]
|
|
104
|
+
},
|
|
105
|
+
"component": "/system/user/index"
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
"path": "/system/role",
|
|
109
|
+
"name": "SystemRole",
|
|
110
|
+
"meta": {
|
|
111
|
+
"title": "角色管理",
|
|
112
|
+
"permissions": ["role:view", "role:edit"]
|
|
113
|
+
},
|
|
114
|
+
"component": "/system/role/index"
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"path": "/system/dict",
|
|
118
|
+
"name": "SystemDict",
|
|
119
|
+
"meta": {
|
|
120
|
+
"title": "字典管理",
|
|
121
|
+
"permissions": ["dict:view", "dict:edit"]
|
|
122
|
+
},
|
|
123
|
+
"component": "/system/dict/index"
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
"path": "/system/menu",
|
|
127
|
+
"name": "SystemMenu",
|
|
128
|
+
"meta": {
|
|
129
|
+
"title": "菜单管理",
|
|
130
|
+
"permissions": ["menu:view", "menu:edit"]
|
|
131
|
+
},
|
|
132
|
+
"component": "/system/menu/index"
|
|
133
|
+
}
|
|
134
|
+
]
|
|
135
|
+
}
|
|
136
|
+
]
|
|
137
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { onMounted, watch } from 'vue'
|
|
3
|
+
import { useSystemStore } from '@jnrs/vue-core/pinia'
|
|
4
|
+
import { ElConfigProvider } from 'element-plus'
|
|
5
|
+
import zhCn from 'element-plus/es/locale/lang/zh-CN'
|
|
6
|
+
import en from 'element-plus/es/locale/lang/en'
|
|
7
|
+
import { useI18n } from 'vue-i18n'
|
|
8
|
+
import { changeLocales as changeLocalesForShared } from '@jnrs/shared/locales'
|
|
9
|
+
|
|
10
|
+
const { locale } = useI18n()
|
|
11
|
+
|
|
12
|
+
const { theme } = useSystemStore()
|
|
13
|
+
watch(
|
|
14
|
+
() => theme.locale,
|
|
15
|
+
(newValue) => {
|
|
16
|
+
locale.value = newValue
|
|
17
|
+
changeLocalesForShared(newValue)
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
immediate: true
|
|
21
|
+
}
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
const localeMap = {
|
|
25
|
+
zhCn: zhCn,
|
|
26
|
+
en: en
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
onMounted(() => {
|
|
30
|
+
console.log(
|
|
31
|
+
'%cPOWERED BY 🅹🅽🆁🆂 TECH',
|
|
32
|
+
`background: #f2f2c1;
|
|
33
|
+
color: #d15f2c;
|
|
34
|
+
font-weight: bold;
|
|
35
|
+
padding: 0 8px;
|
|
36
|
+
font-family: 'Helvetica Neue', sans-serif;`
|
|
37
|
+
)
|
|
38
|
+
})
|
|
39
|
+
</script>
|
|
40
|
+
|
|
41
|
+
<template>
|
|
42
|
+
<el-config-provider :locale="localeMap[theme.locale]">
|
|
43
|
+
<router-view></router-view>
|
|
44
|
+
</el-config-provider>
|
|
45
|
+
</template>
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { axiosRequest } from '../request'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* axios 方式下载文件
|
|
5
|
+
* @param uniqueFileName 文件唯一名称(列表中一般是在 item.attachmentDocument/imageDocument.attachments[].uniqueFileName)
|
|
6
|
+
* @returns Blob
|
|
7
|
+
*/
|
|
8
|
+
export const FileApi = (uniqueFileName: string): Promise<Blob> => {
|
|
9
|
+
return axiosRequest({
|
|
10
|
+
url: '/api/files/' + uniqueFileName,
|
|
11
|
+
method: 'get',
|
|
12
|
+
responseType: 'blob',
|
|
13
|
+
showErrorMsg: false
|
|
14
|
+
})
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Fetch 方式下载文件
|
|
19
|
+
*/
|
|
20
|
+
// import { useFetch } from '@vueuse/core'
|
|
21
|
+
// export const FileApi = (uniqueFileName: string) => {
|
|
22
|
+
// return useFetch(`/api/files/${uniqueFileName}`, {
|
|
23
|
+
// method: 'get',
|
|
24
|
+
// headers: {
|
|
25
|
+
// responseType: 'blob'
|
|
26
|
+
// }
|
|
27
|
+
// }).blob()
|
|
28
|
+
// }
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import type { Pagination, PageTableData, FileContainer } from '@/types'
|
|
2
|
+
import { axiosRequest } from '../request'
|
|
3
|
+
import { extractFieldId } from '@/utils/file'
|
|
4
|
+
import { objectToFormData } from '@/utils/packages'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* 项目
|
|
8
|
+
*/
|
|
9
|
+
export interface ProjectItem extends FileContainer {
|
|
10
|
+
id: string
|
|
11
|
+
programCode: string
|
|
12
|
+
program: string
|
|
13
|
+
code: string
|
|
14
|
+
name: string
|
|
15
|
+
description: string
|
|
16
|
+
projectType?: '敏捷型' | '瀑布型' | '混合型'
|
|
17
|
+
manager: string
|
|
18
|
+
budget: number
|
|
19
|
+
plannedStartDate: string
|
|
20
|
+
plannedFinishDate: string
|
|
21
|
+
progress: string
|
|
22
|
+
status: '进行中' | '已完成' | '未开始' | '已暂停'
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* 新增
|
|
27
|
+
*/
|
|
28
|
+
type AddProjectOmitKeys =
|
|
29
|
+
| 'id'
|
|
30
|
+
| 'programCode'
|
|
31
|
+
| 'program'
|
|
32
|
+
| 'code'
|
|
33
|
+
| 'manager'
|
|
34
|
+
| 'plannedFinishDate'
|
|
35
|
+
| 'progress'
|
|
36
|
+
| 'status'
|
|
37
|
+
| 'imageDocument'
|
|
38
|
+
| 'attachmentDocument'
|
|
39
|
+
|
|
40
|
+
export type AddProjectItem = Omit<ProjectItem, AddProjectOmitKeys> & {
|
|
41
|
+
id?: string
|
|
42
|
+
managerId?: Record<string, unknown> | unknown
|
|
43
|
+
newAttachmentFile: []
|
|
44
|
+
newImageFiles: []
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* 查询
|
|
49
|
+
*/
|
|
50
|
+
export interface ProjectQuery extends Pagination {
|
|
51
|
+
code?: string
|
|
52
|
+
projectType?: '敏捷型' | '瀑布型' | '混合型'
|
|
53
|
+
manager?: string
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* 测试 404 错误
|
|
58
|
+
*/
|
|
59
|
+
export const NotFoundApi = () => {
|
|
60
|
+
return axiosRequest({
|
|
61
|
+
url: '/mock/notFound',
|
|
62
|
+
method: 'get'
|
|
63
|
+
})
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* 测试 不需要权限
|
|
68
|
+
*/
|
|
69
|
+
export const NoNeedAuthApi = () => {
|
|
70
|
+
return axiosRequest({
|
|
71
|
+
url: '/mock/auth/no',
|
|
72
|
+
method: 'post',
|
|
73
|
+
noAuth: true
|
|
74
|
+
})
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* 测试 无权限
|
|
79
|
+
* @param showErrorMsg 是否显示错误信息
|
|
80
|
+
*/
|
|
81
|
+
export const NoAuthApi = (showErrorMsg: boolean) => {
|
|
82
|
+
return axiosRequest({
|
|
83
|
+
url: '/mock/auth/no',
|
|
84
|
+
method: 'post',
|
|
85
|
+
showErrorMsg
|
|
86
|
+
})
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* 数据详情
|
|
91
|
+
*/
|
|
92
|
+
export const DetailsApi = (): Promise<FileContainer> => {
|
|
93
|
+
return axiosRequest({
|
|
94
|
+
url: '/mock/details',
|
|
95
|
+
method: 'get'
|
|
96
|
+
})
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* 表单新增(包含文件上传类需使用 formData 类型)
|
|
101
|
+
*/
|
|
102
|
+
export const EditApi = (data: AddProjectItem) => {
|
|
103
|
+
const formData = objectToFormData({
|
|
104
|
+
...data,
|
|
105
|
+
managerId: extractFieldId(data.managerId, 'managerId')
|
|
106
|
+
})
|
|
107
|
+
return axiosRequest({
|
|
108
|
+
url: '/mock/demos/save',
|
|
109
|
+
method: 'post',
|
|
110
|
+
data: formData
|
|
111
|
+
})
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* 数据详情
|
|
116
|
+
*/
|
|
117
|
+
export const TableApi = (data?: ProjectQuery): Promise<PageTableData<ProjectItem>> => {
|
|
118
|
+
return axiosRequest({
|
|
119
|
+
url: '/mock/demos/table',
|
|
120
|
+
method: 'get',
|
|
121
|
+
data
|
|
122
|
+
})
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* 下载数据导入模板
|
|
127
|
+
*/
|
|
128
|
+
export const ImportTemplateApi = (): Promise<Blob> => {
|
|
129
|
+
return axiosRequest({
|
|
130
|
+
url: '/mock/project/template',
|
|
131
|
+
method: 'post'
|
|
132
|
+
})
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* 项目数据导入
|
|
137
|
+
*/
|
|
138
|
+
export const ImportDataApi = (data: FormData) => {
|
|
139
|
+
return axiosRequest({
|
|
140
|
+
url: '/mock/project/import',
|
|
141
|
+
method: 'post',
|
|
142
|
+
data
|
|
143
|
+
})
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* 项目数据导出
|
|
148
|
+
*/
|
|
149
|
+
export const ExportApi = (data: Record<string, unknown>): Promise<Blob> => {
|
|
150
|
+
return axiosRequest({
|
|
151
|
+
url: '/mock/project/export',
|
|
152
|
+
method: 'post',
|
|
153
|
+
data
|
|
154
|
+
})
|
|
155
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @Author : TanRui
|
|
3
|
+
* @WeChat : Tan578853789
|
|
4
|
+
* @File : request.ts
|
|
5
|
+
* @Date : 2025/11/10
|
|
6
|
+
* @Desc. : axios 网络请求实例
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { BusinessRequest, BusinessResponse } from '@jnrs/shared/request'
|
|
10
|
+
import { createAxiosInstance } from '@jnrs/shared/request'
|
|
11
|
+
import { useMockStore, useAuthStore } from '@jnrs/vue-core/pinia'
|
|
12
|
+
import { handleRouter } from '@jnrs/vue-core/router'
|
|
13
|
+
import { ElMessage } from 'element-plus'
|
|
14
|
+
|
|
15
|
+
const axiosInstance = createAxiosInstance({
|
|
16
|
+
// options: {
|
|
17
|
+
// noAuth: true // 全局设置为不需要权限
|
|
18
|
+
// },
|
|
19
|
+
handleMessageFn: ElMessage,
|
|
20
|
+
handleGetTokenFn: () => {
|
|
21
|
+
const { token } = useAuthStore()
|
|
22
|
+
return token
|
|
23
|
+
},
|
|
24
|
+
handleNoAuthFn: () => {
|
|
25
|
+
handleRouter({ name: 'Login' })
|
|
26
|
+
}
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* axios 请求方法(泛型拓展)
|
|
31
|
+
* @param options 请求配置项
|
|
32
|
+
* @returns Promise<T> 响应数据
|
|
33
|
+
*/
|
|
34
|
+
const axiosRequest = <T = BusinessResponse>(options: BusinessRequest): Promise<T> => {
|
|
35
|
+
if (!axiosInstance) {
|
|
36
|
+
throw new Error('请先调用 createRequest 初始化 axios 实例')
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// 如果是模拟请求,则将请求地址改为模拟地址
|
|
40
|
+
const { isMock } = useMockStore()
|
|
41
|
+
|
|
42
|
+
if (isMock) {
|
|
43
|
+
options.url = options.mockUrl
|
|
44
|
+
? options.mockUrl
|
|
45
|
+
: options.url.startsWith('/mock')
|
|
46
|
+
? options.url
|
|
47
|
+
: '/mock' + options.url
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return axiosInstance(options)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export { axiosRequest }
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import type { Dict, DictItem, User, Role } from '@jnrs/shared'
|
|
2
|
+
import type { MenuItem } from '@jnrs/vue-core'
|
|
3
|
+
import { axiosRequest } from '../request'
|
|
4
|
+
import { objectToFormData } from '@/utils/packages'
|
|
5
|
+
|
|
6
|
+
// 菜单
|
|
7
|
+
export const MenuApi = (): Promise<MenuItem[]> => {
|
|
8
|
+
return axiosRequest({
|
|
9
|
+
url: '/system/menu.json', // /public 文件夹下
|
|
10
|
+
mockUrl: '/mock/menu',
|
|
11
|
+
method: 'get',
|
|
12
|
+
noAuth: true // 本地数据忽略 token 验证
|
|
13
|
+
})
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// 登录
|
|
17
|
+
interface LoginParams {
|
|
18
|
+
account: string
|
|
19
|
+
password: string
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface LoginResult extends User {
|
|
23
|
+
token: string
|
|
24
|
+
dict: Dict
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export const LoginApi = (data: LoginParams): Promise<LoginResult> => {
|
|
28
|
+
return axiosRequest({
|
|
29
|
+
url: '/api/auth/login',
|
|
30
|
+
method: 'post',
|
|
31
|
+
data,
|
|
32
|
+
noAuth: true
|
|
33
|
+
})
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// 退出登录
|
|
37
|
+
export const LogoutApi = () => {
|
|
38
|
+
return axiosRequest({
|
|
39
|
+
url: '/api/auth/logout',
|
|
40
|
+
method: 'get'
|
|
41
|
+
})
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// 获取用户信息
|
|
45
|
+
export const UserInfoApi = (): Promise<User> => {
|
|
46
|
+
return axiosRequest({
|
|
47
|
+
url: '/api/auth/user-info',
|
|
48
|
+
method: 'get'
|
|
49
|
+
})
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// 修改头像
|
|
53
|
+
export const AvatarChangeApi = (data: File) => {
|
|
54
|
+
return axiosRequest({
|
|
55
|
+
url: '/api/user/avatar',
|
|
56
|
+
method: 'post',
|
|
57
|
+
data: objectToFormData({ file: data })
|
|
58
|
+
})
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// 修改密码
|
|
62
|
+
interface PasswordChange {
|
|
63
|
+
userId: number
|
|
64
|
+
password: string
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export const PasswordChangeApi = (data: PasswordChange) => {
|
|
68
|
+
return axiosRequest({
|
|
69
|
+
url: '/api/auth/change-password',
|
|
70
|
+
method: 'post',
|
|
71
|
+
data
|
|
72
|
+
})
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// 获取字典列表
|
|
76
|
+
export const DictApi = (): Promise<DictItem[]> => {
|
|
77
|
+
return axiosRequest({
|
|
78
|
+
url: '/api/dict-manager',
|
|
79
|
+
method: 'get'
|
|
80
|
+
})
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// 获取单个字典
|
|
84
|
+
export const DictDetailApi = (id: string) => {
|
|
85
|
+
return axiosRequest({
|
|
86
|
+
url: `/api/dict-manager/detail/${id}`,
|
|
87
|
+
method: 'get'
|
|
88
|
+
})
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// 修改单个字典
|
|
92
|
+
export const DictChangeApi = (data: DictItem) => {
|
|
93
|
+
return axiosRequest({
|
|
94
|
+
url: '/api/dict-manager/detail',
|
|
95
|
+
method: 'post',
|
|
96
|
+
data
|
|
97
|
+
})
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// 获取角色列表
|
|
101
|
+
export const RoleApi = (): Promise<Role[]> => {
|
|
102
|
+
return axiosRequest({
|
|
103
|
+
url: '/api/role-manager',
|
|
104
|
+
method: 'get',
|
|
105
|
+
noAuth: true
|
|
106
|
+
})
|
|
107
|
+
}
|
|
File without changes
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 276.55 50.85"><defs><style>.a{fill:#fff;}</style></defs><path class="a" d="M-336.3,445.05c6.8,0,13.6-.05,20.41,0,.05,14.45-.12,28.89-.14,43.33.3,3.93-3.34,7.48-7.21,7.43-4.35,0-8.71,0-13.06,0Q-336.33,470.45-336.3,445.05Z" transform="translate(381.53 -445.04)"/><path class="a" d="M-306.42,447.84a6.54,6.54,0,0,1,5.5-2.79h12.49a1.57,1.57,0,0,1,1.11.31c5.76,3.57,11.54,7.1,17.3,10.67q0,11.28,0,22.58c-5.92-3.59-11.83-7.22-17.76-10.8v28.08c-6.79,0-13.59,0-20.38,0q0-20.82,0-41.63A10.53,10.53,0,0,1-306.42,447.84Z" transform="translate(381.53 -445.04)"/><path class="a" d="M-267.56,452.43a7.3,7.3,0,0,1,7.09-7.38h13.39c.06,16.92,0,33.85,0,50.78-6.83,0-13.66,0-20.49,0C-267.61,481.37-267.54,466.9-267.56,452.43Z" transform="translate(381.53 -445.04)"/><path class="a" d="M-236.93,445.06q26.9,0,53.78,0a7.23,7.23,0,0,1,7,5.58c.11,1.55,0,3.1,0,4.64-20.28,0-40.56,0-60.84-.06Q-236.91,450.14-236.93,445.06Z" transform="translate(381.53 -445.04)"/><path class="a" d="M-165.71,450a7.14,7.14,0,0,1,6.63-4.95h42.25a11.66,11.66,0,0,1,8.19,3.34,13.71,13.71,0,0,1,3.65,6.86h-40.62c0,3.36,0,6.72,0,10.09q16.77,0,33.54,0a7.29,7.29,0,0,1,7,6.09c.09,1.33,0,2.67,0,4-18.42.05-36.84,0-55.26,0A7,7,0,0,1-166,469.7c0-5.16,0-10.33,0-15.49A13.83,13.83,0,0,1-165.71,450Z" transform="translate(381.53 -445.04)"/><path class="a" d="M-196.48,457.73c6.79-.05,13.59,0,20.39,0,0,3.89,0,7.78,0,11.66a7.07,7.07,0,0,1-7.05,6.1c-11.19,0-22.37,0-33.55,0q0,10.2,0,20.38c-6.79,0-13.58,0-20.38,0,0-10.05,0-20.11,0-30.16q20.26,0,40.52,0C-196.36,463.05-196.48,460.38-196.48,457.73Z" transform="translate(381.53 -445.04)"/><path class="a" d="M-381.49,472.19c6.78,0,13.56,0,20.34,0,0,4.48,0,9,0,13.42,7.43.14,14.88.06,22.31,0,.11,3.39,0,6.78,0,10.17q-17.79,0-35.58,0a7.23,7.23,0,0,1-7.16-7.13C-381.48,483.2-381.55,477.7-381.49,472.19Z" transform="translate(381.53 -445.04)"/><path class="a" d="M-202.37,477.73h19.88c.72,2.63,1.29,5.31,2.06,7.93,18.36-.07,36.72,0,55.08-.06,0-2.56,0-5.13,0-7.69,6.78,0,13.56,0,20.34,0,0,3.6,0,7.2,0,10.8a7.08,7.08,0,0,1-6.79,7.14h-52.05c-11.43,0-22.86-.07-34.28,0Q-200.28,486.8-202.37,477.73Z" transform="translate(381.53 -445.04)"/></svg>
|
|
File without changes
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* 业务功能通用样式表
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/*
|
|
6
|
+
* 禁止用户选中页面元素
|
|
7
|
+
*/
|
|
8
|
+
.no_select {
|
|
9
|
+
-khtml-user-drag: none;
|
|
10
|
+
-webkit-user-drag: none;
|
|
11
|
+
-webkit-user-select: none;
|
|
12
|
+
-moz-user-select: none;
|
|
13
|
+
-ms-user-select: none;
|
|
14
|
+
user-select: none;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.topBarBtn {
|
|
18
|
+
position: relative;
|
|
19
|
+
margin: 0 8px;
|
|
20
|
+
font-size: 22px;
|
|
21
|
+
transition: all 0.25s ease 0s;
|
|
22
|
+
cursor: pointer;
|
|
23
|
+
&:hover {
|
|
24
|
+
color: var(--jnrs-color-primary);
|
|
25
|
+
&::after {
|
|
26
|
+
content: '';
|
|
27
|
+
position: absolute;
|
|
28
|
+
top: 50%;
|
|
29
|
+
left: 50%;
|
|
30
|
+
transform: translate(-50%, -50%);
|
|
31
|
+
width: 32px;
|
|
32
|
+
height: 32px;
|
|
33
|
+
background: var(--jnrs-color-primary);
|
|
34
|
+
opacity: 0.1;
|
|
35
|
+
border-radius: 50%;
|
|
36
|
+
transition: all 0.25s ease 0s;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* 字体样式表
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
@font-face {
|
|
6
|
+
font-family: 'Alibaba-PuHuiTi-Regular';
|
|
7
|
+
src: url('@/assets/fonts/AlibabaPuHuiTi-Regular.woff2');
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
@font-face {
|
|
11
|
+
font-family: 'AlimamaShuHeiTi-Bold';
|
|
12
|
+
src: url('@/assets/fonts/AlimamaShuHeiTi-Bold.woff2');
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/*
|
|
16
|
+
* 阿里巴巴普惠体 - 正黑体
|
|
17
|
+
*/
|
|
18
|
+
.Alibaba-PuHuiTi-Regular {
|
|
19
|
+
font-family: 'Alibaba-PuHuiTi-Regular';
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/*
|
|
23
|
+
* 阿里妈妈字体 - 数黑体
|
|
24
|
+
*/
|
|
25
|
+
.AlimamaShuHeiTi-Bold {
|
|
26
|
+
font-family: 'AlimamaShuHeiTi-Bold';
|
|
27
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* 初始化重置样式表
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
*,
|
|
6
|
+
*::before,
|
|
7
|
+
*::after {
|
|
8
|
+
margin: 0;
|
|
9
|
+
box-sizing: border-box;
|
|
10
|
+
font-family: Alibaba-PuHuiTi-Regular;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
a {
|
|
14
|
+
text-decoration: none;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/*
|
|
18
|
+
* 禁止拖拽图片
|
|
19
|
+
* 禁止长按弹出菜单
|
|
20
|
+
*/
|
|
21
|
+
img {
|
|
22
|
+
-ms-user-drag: none;
|
|
23
|
+
-moz-user-drag: none;
|
|
24
|
+
-webkit-user-drag: none;
|
|
25
|
+
-webkit-touch-callout: none;
|
|
26
|
+
overflow: hidden;
|
|
27
|
+
object-fit: cover;
|
|
28
|
+
object-position: center center;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
body {
|
|
32
|
+
width: 100vw;
|
|
33
|
+
height: 100vh;
|
|
34
|
+
color: var(--jnrs-font-primary);
|
|
35
|
+
background: var(--jnrs-background-primary);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
#app {
|
|
39
|
+
min-width: 1280px;
|
|
40
|
+
height: 100%;
|
|
41
|
+
}
|