create-jnrs-template-vue 1.1.12 → 1.1.14
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/jnrs-template-vue/README.md +5 -1
- package/jnrs-template-vue/components.d.ts +3 -4
- package/jnrs-template-vue/package.json +5 -4
- package/jnrs-template-vue/src/App.vue +3 -1
- package/jnrs-template-vue/src/api/common/index.ts +20 -5
- package/jnrs-template-vue/src/api/demos/index.ts +86 -0
- package/jnrs-template-vue/src/api/system/index.ts +1 -1
- package/jnrs-template-vue/src/api/user/index.ts +1 -1
- package/jnrs-template-vue/src/components/base/ImageView.vue +58 -0
- package/jnrs-template-vue/src/components/common/JnPagination.vue +83 -0
- package/jnrs-template-vue/src/components/common/JnTable.vue +133 -0
- package/jnrs-template-vue/src/composables/{common → base}/useAvatar.ts +1 -1
- package/jnrs-template-vue/src/composables/{useForm.ts → common/useForm.ts} +1 -1
- package/jnrs-template-vue/src/composables/{useModal.ts → common/useModal.ts} +1 -1
- package/jnrs-template-vue/src/composables/{useTable.ts → common/usePagination.ts} +1 -1
- package/jnrs-template-vue/src/composables/common/useTable.ts +35 -0
- package/jnrs-template-vue/src/composables/{useUser.ts → common/useUser.ts} +1 -1
- package/jnrs-template-vue/src/composables/tools/useReactivityTableHeight.ts +63 -0
- package/jnrs-template-vue/src/layout/SideMenu.vue +1 -1
- package/jnrs-template-vue/src/layout/SideMenuItem.vue +1 -1
- package/jnrs-template-vue/src/layout/TopHeader.vue +3 -3
- package/jnrs-template-vue/src/layout/index.vue +1 -1
- package/jnrs-template-vue/src/router/index.ts +1 -1
- package/jnrs-template-vue/src/utils/file.ts +15 -1
- package/jnrs-template-vue/src/utils/{common.ts → packages.ts} +33 -1
- package/jnrs-template-vue/src/utils/permissions.ts +1 -1
- package/jnrs-template-vue/src/views/demos/crud/index.vue +104 -2
- package/jnrs-template-vue/src/views/demos/unitTest/RequestPage.vue +141 -0
- package/jnrs-template-vue/src/views/demos/unitTest/index.vue +5 -99
- package/jnrs-template-vue/src/views/login/index.vue +12 -12
- package/jnrs-template-vue/src/views/system/menu/index.vue +1 -1
- package/jnrs-template-vue/src/views/system/mine/baseInfo.vue +3 -3
- package/jnrs-template-vue/src/views/system/mine/securitySettings.vue +1 -1
- package/jnrs-template-vue/viteMockServe/index.ts +9 -0
- package/jnrs-template-vue/viteMockServe/tableRes.json +275 -0
- package/package.json +1 -1
- package/jnrs-template-vue/src/api/mock/index.ts +0 -34
- package/jnrs-template-vue/src/api/request.ts +0 -40
- package/jnrs-template-vue/src/composables/index.ts +0 -11
- package/jnrs-template-vue/src/stores/index.ts +0 -2
- package/jnrs-template-vue/src/stores/mock.ts +0 -21
|
@@ -3,7 +3,7 @@ import { ref, watch, toRefs } from 'vue'
|
|
|
3
3
|
import SideMenu from './SideMenu.vue'
|
|
4
4
|
import TopHeader from './TopHeader.vue'
|
|
5
5
|
import RouterTabs from './RouterTabs.vue'
|
|
6
|
-
import { useAuthStore, useSystemStore } from '
|
|
6
|
+
import { useAuthStore, useSystemStore } from '@jnrs/vue-core/pinia'
|
|
7
7
|
|
|
8
8
|
const watermarkFont = ref({
|
|
9
9
|
color: 'rgba(0, 0, 0, 0)',
|
|
@@ -2,7 +2,7 @@ import { LAYOUT_NAME, GLOBAL_COMPONENT, routes } from './routes'
|
|
|
2
2
|
import { createVueRouter } from '@jnrs/vue-core/router'
|
|
3
3
|
import type { FileModules, RouteLocationNormalizedGeneric } from '@jnrs/vue-core/router'
|
|
4
4
|
import type { MenuItem } from '@jnrs/vue-core'
|
|
5
|
-
import { useAuthStore, useMenuStore } from '
|
|
5
|
+
import { useAuthStore, useMenuStore } from '@jnrs/vue-core/pinia'
|
|
6
6
|
import { MenuApi } from '@/api/system'
|
|
7
7
|
import { hasMenuViewPermission } from '@/utils/permissions'
|
|
8
8
|
|
|
@@ -3,5 +3,19 @@
|
|
|
3
3
|
* @WeChat : Tan578853789
|
|
4
4
|
* @File : file.ts
|
|
5
5
|
* @Date : 2025/10/16
|
|
6
|
-
* @Desc. :
|
|
6
|
+
* @Desc. : 文件处理相关函数
|
|
7
7
|
*/
|
|
8
|
+
|
|
9
|
+
// import { blobToUrl } from '@jnrs/shared'
|
|
10
|
+
import { useObjectUrl } from '@vueuse/core'
|
|
11
|
+
import { FileApi } from '@/api/common'
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* 根据文件下载接口返回的二进制数据生成 URL(用于图片、PDF预览)
|
|
15
|
+
* @param uniqueFileName 文件唯一名称
|
|
16
|
+
* @returns 响应式文件 URL
|
|
17
|
+
*/
|
|
18
|
+
export const getFileUrl = async (uniqueFileName: string) => {
|
|
19
|
+
const blob = await FileApi(uniqueFileName)
|
|
20
|
+
return useObjectUrl(blob)
|
|
21
|
+
}
|
|
@@ -1,11 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @Author : TanRui
|
|
3
|
+
* @WeChat : Tan578853789
|
|
4
|
+
* @File : common.ts
|
|
5
|
+
* @Date : 2025/12/17
|
|
6
|
+
* @Desc. : 对 packages 的一些公用方法进行封装
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { ElMessage } from 'element-plus'
|
|
1
10
|
import {
|
|
2
11
|
getOneDictList as _getOneDictList,
|
|
3
12
|
getDictLabel as _getDictLabel,
|
|
4
13
|
getDictValue as _getDictValue,
|
|
5
|
-
getDictColor as _getDictColor
|
|
14
|
+
getDictColor as _getDictColor,
|
|
15
|
+
downloadFile as _downloadFile
|
|
6
16
|
} from '@jnrs/shared'
|
|
7
17
|
import { useAuthStore } from '@jnrs/vue-core/pinia'
|
|
8
18
|
import { objectToFormData as _objectToFormData } from '@jnrs/shared'
|
|
19
|
+
import { FileApi } from '@/api/common'
|
|
9
20
|
|
|
10
21
|
/**
|
|
11
22
|
* 根据字典名称获取字典数据
|
|
@@ -77,3 +88,24 @@ export const objectToFormData = (obj: Record<string, unknown>) => {
|
|
|
77
88
|
}
|
|
78
89
|
return _objectToFormData(obj, mapConfig)
|
|
79
90
|
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* 根据文件下载接口返回的二进制数据进行下载
|
|
94
|
+
* @param uniqueFileName 后端存储的唯一文件名
|
|
95
|
+
* @param filename 下载文件显示的文件名
|
|
96
|
+
* @returns loading 下载状态
|
|
97
|
+
*/
|
|
98
|
+
export const downloadFile = async (uniqueFileName: string, filename?: string) => {
|
|
99
|
+
let loading = true
|
|
100
|
+
ElMessage.info('文件下载中...')
|
|
101
|
+
try {
|
|
102
|
+
const blob = await FileApi(uniqueFileName)
|
|
103
|
+
_downloadFile(blob, filename || uniqueFileName)
|
|
104
|
+
} catch (error) {
|
|
105
|
+
console.error(error)
|
|
106
|
+
ElMessage.warning('文件下载失败')
|
|
107
|
+
} finally {
|
|
108
|
+
loading = false
|
|
109
|
+
}
|
|
110
|
+
return loading
|
|
111
|
+
}
|
|
@@ -1,6 +1,108 @@
|
|
|
1
|
-
<script setup lang="ts"
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { ref, onActivated } from 'vue'
|
|
3
|
+
import JnTable from '@/components/common/JnTable.vue'
|
|
4
|
+
import JnPagination from '@/components/common/JnPagination.vue'
|
|
5
|
+
import { DemosTableApi } from '@/api/demos/index'
|
|
6
|
+
import type { ProjectItem } from '@/api/demos/index'
|
|
7
|
+
|
|
8
|
+
const tableData = ref<ProjectItem[]>()
|
|
9
|
+
const total = ref(0)
|
|
10
|
+
const pagination = ref({ currentPage: 1, pageSize: 10 })
|
|
11
|
+
|
|
12
|
+
const fetchData = () => {
|
|
13
|
+
console.log(pagination.value)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const getDemosTable = async () => {
|
|
17
|
+
try {
|
|
18
|
+
const res = await DemosTableApi()
|
|
19
|
+
tableData.value = res
|
|
20
|
+
total.value = res.length
|
|
21
|
+
} catch (error) {
|
|
22
|
+
console.error(error)
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const edit = (row: ProjectItem) => {
|
|
27
|
+
console.log(row)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const handleSelectionChange = (row: ProjectItem[]) => {
|
|
31
|
+
console.log(row)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
onActivated(() => {
|
|
35
|
+
getDemosTable()
|
|
36
|
+
})
|
|
37
|
+
</script>
|
|
2
38
|
|
|
3
39
|
<template>
|
|
4
|
-
<
|
|
40
|
+
<el-card>
|
|
41
|
+
<template #header>
|
|
42
|
+
<span>Card name</span>
|
|
43
|
+
</template>
|
|
44
|
+
<JnTable
|
|
45
|
+
:data="tableData"
|
|
46
|
+
:pagination="pagination"
|
|
47
|
+
:showIndexColumn="true"
|
|
48
|
+
:showSelectionColumn="true"
|
|
49
|
+
@selection-change="handleSelectionChange"
|
|
50
|
+
>
|
|
51
|
+
<el-table-column prop="code" label="项目编号" min-width="200" sortable show-overflow-tooltip />
|
|
52
|
+
<el-table-column prop="name" label="项目名称" min-width="200" sortable show-overflow-tooltip>
|
|
53
|
+
<template #default="{ row }">
|
|
54
|
+
<span>{{ row.name }}</span>
|
|
55
|
+
</template>
|
|
56
|
+
</el-table-column>
|
|
57
|
+
<el-table-column prop="program" label="项目集名称" min-width="200" sortable show-overflow-tooltip />
|
|
58
|
+
<el-table-column prop="type" label="项目类型" width="100" align="center" sortable>
|
|
59
|
+
<template #default="{ row }">
|
|
60
|
+
<span>{{ row.type }}</span>
|
|
61
|
+
</template>
|
|
62
|
+
</el-table-column>
|
|
63
|
+
<el-table-column prop="manager" label="项目经理" width="100" align="center" sortable />
|
|
64
|
+
<el-table-column prop="budget" label="预算" width="100" align="center" sortable>
|
|
65
|
+
<template #default="{ row }">
|
|
66
|
+
<span>{{ row.budget }}</span>
|
|
67
|
+
</template>
|
|
68
|
+
</el-table-column>
|
|
69
|
+
<el-table-column prop="plannedStartDate" label="计划开始日期" width="130" align="center" sortable>
|
|
70
|
+
<template #default="{ row }">
|
|
71
|
+
<span>{{ row.plannedStartDate }}</span>
|
|
72
|
+
</template>
|
|
73
|
+
</el-table-column>
|
|
74
|
+
<el-table-column prop="plannedFinishDate" label="计划完成日期" width="130" align="center" sortable>
|
|
75
|
+
<template #default="{ row }">
|
|
76
|
+
<span>{{ row.plannedFinishDate }}</span>
|
|
77
|
+
</template>
|
|
78
|
+
</el-table-column>
|
|
79
|
+
<el-table-column prop="progress" label="进度" width="100" align="center" sortable>
|
|
80
|
+
<template #default="{ row }">
|
|
81
|
+
<span>{{ row.progress }}</span>
|
|
82
|
+
</template>
|
|
83
|
+
</el-table-column>
|
|
84
|
+
<el-table-column prop="status" label="状态" width="100" align="center" sortable>
|
|
85
|
+
<template #default="{ row }">
|
|
86
|
+
<span>{{ row.status }}</span>
|
|
87
|
+
</template>
|
|
88
|
+
</el-table-column>
|
|
89
|
+
<el-table-column prop="imageDocument" label="图片" width="100" align="center" sortable>
|
|
90
|
+
<template #default="{ row }">
|
|
91
|
+
<span>{{ row.imageDocument?.attachments.length || 0 }}</span>
|
|
92
|
+
</template>
|
|
93
|
+
</el-table-column>
|
|
94
|
+
<el-table-column prop="attachmentDocument" label="附件" width="100" align="center" sortable>
|
|
95
|
+
<template #default="{ row }">
|
|
96
|
+
<span>{{ row.attachmentDocument?.attachments.length || 0 }}</span>
|
|
97
|
+
</template>
|
|
98
|
+
</el-table-column>
|
|
99
|
+
<el-table-column label="操作" width="100" align="center" fixed="right">
|
|
100
|
+
<template #default="{ row }">
|
|
101
|
+
<el-button link type="primary" @click.stop="edit(row)">编辑</el-button>
|
|
102
|
+
</template>
|
|
103
|
+
</el-table-column>
|
|
104
|
+
</JnTable>
|
|
105
|
+
<jn-pagination :total="total" v-model="pagination" @change="fetchData" />
|
|
106
|
+
</el-card>
|
|
5
107
|
</template>
|
|
6
108
|
<style scoped></style>
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { ref } from 'vue'
|
|
3
|
+
import { storeToRefs } from 'pinia'
|
|
4
|
+
import { ElMessage } from 'element-plus'
|
|
5
|
+
import { objectToFormData } from '@/utils/packages'
|
|
6
|
+
import { useMockStore } from '@jnrs/vue-core/pinia'
|
|
7
|
+
import { LoginApi, UserInfoApi } from '@/api/system'
|
|
8
|
+
import { NotFoundApi, NoAuth, DetailsApi } from '@/api/demos'
|
|
9
|
+
import { getFileUrl } from '@/utils/file'
|
|
10
|
+
import { downloadFile } from '@/utils/packages'
|
|
11
|
+
|
|
12
|
+
const { isMock } = storeToRefs(useMockStore())
|
|
13
|
+
const squareUrl = ref()
|
|
14
|
+
|
|
15
|
+
const loginParams = ref({
|
|
16
|
+
account: 'user',
|
|
17
|
+
password: '123456'
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
const handleInfoApi = async () => {
|
|
21
|
+
try {
|
|
22
|
+
const res = await UserInfoApi()
|
|
23
|
+
console.log(res)
|
|
24
|
+
} catch (error) {
|
|
25
|
+
console.log(error)
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const handleNotFoundApi = async () => {
|
|
30
|
+
try {
|
|
31
|
+
const res = await NotFoundApi()
|
|
32
|
+
console.log(res)
|
|
33
|
+
} catch (error) {
|
|
34
|
+
console.log(error)
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const handleNoAuth = async (showErrorMsg = true) => {
|
|
39
|
+
try {
|
|
40
|
+
const res = await NoAuth(showErrorMsg)
|
|
41
|
+
console.log(res)
|
|
42
|
+
} catch (error) {
|
|
43
|
+
console.log(error)
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// 验证登录接口
|
|
48
|
+
const handleLogin = async () => {
|
|
49
|
+
try {
|
|
50
|
+
const res = await LoginApi(loginParams.value)
|
|
51
|
+
ElMessage.success('登录成功')
|
|
52
|
+
console.log(res)
|
|
53
|
+
} catch (error) {
|
|
54
|
+
console.log(error)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// 获取数据列表单个数据
|
|
59
|
+
const handleDetailsApi = async () => {
|
|
60
|
+
try {
|
|
61
|
+
const res = await DetailsApi()
|
|
62
|
+
let formatData: Record<string, unknown> = {}
|
|
63
|
+
formatData = {
|
|
64
|
+
...res
|
|
65
|
+
}
|
|
66
|
+
if (res.attachmentDocument?.attachments) {
|
|
67
|
+
formatData.newAttachmentFile = res.attachmentDocument.attachments
|
|
68
|
+
}
|
|
69
|
+
if (res.imageDocument?.attachments) {
|
|
70
|
+
formatData.newImageFiles = res.imageDocument.attachments
|
|
71
|
+
}
|
|
72
|
+
console.log(formatData)
|
|
73
|
+
const formData = objectToFormData(formatData)
|
|
74
|
+
console.log(formData)
|
|
75
|
+
for (const [key, value] of formData.entries()) {
|
|
76
|
+
console.log(key, value)
|
|
77
|
+
}
|
|
78
|
+
} catch (error) {
|
|
79
|
+
console.log(error)
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// 获取后端服务器文件进行下载
|
|
84
|
+
const handleFileView = async () => {
|
|
85
|
+
try {
|
|
86
|
+
const url = await getFileUrl('20251217171430919-34bcc1a9-a19d-4b91-9ab6-57cb31c3df28.jpg')
|
|
87
|
+
squareUrl.value = url.value
|
|
88
|
+
} catch (error) {
|
|
89
|
+
console.log(error)
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
</script>
|
|
93
|
+
|
|
94
|
+
<template>
|
|
95
|
+
<p>网络请求测试</p>
|
|
96
|
+
<div>
|
|
97
|
+
<span>服务器类型:</span>
|
|
98
|
+
<el-switch v-model="isMock" active-text="Mock 服务器" inactive-text="后端服务器" />
|
|
99
|
+
</div>
|
|
100
|
+
<el-button-group>
|
|
101
|
+
<el-button type="success" size="small" @click="handleInfoApi">获取用户数据</el-button>
|
|
102
|
+
<el-button type="primary" size="small" @click="handleNotFoundApi">404</el-button>
|
|
103
|
+
<el-button type="primary" size="small" @click="handleNoAuth()">暂无权限</el-button>
|
|
104
|
+
<el-button type="primary" size="small" @click="handleNoAuth(false)">暂无权限(不显示 Message)</el-button>
|
|
105
|
+
</el-button-group>
|
|
106
|
+
<el-input v-model="loginParams.account" size="small" style="width: 200px">
|
|
107
|
+
<template #append>
|
|
108
|
+
<el-button size="small" @click="handleLogin">验证登录接口</el-button>
|
|
109
|
+
</template>
|
|
110
|
+
</el-input>
|
|
111
|
+
<div>
|
|
112
|
+
<el-button-group>
|
|
113
|
+
<el-button type="primary" plain size="small" @click="handleDetailsApi">获取数据列表单个数据</el-button>
|
|
114
|
+
<el-button
|
|
115
|
+
type="primary"
|
|
116
|
+
plain
|
|
117
|
+
size="small"
|
|
118
|
+
@click="downloadFile('20251217171430919-34bcc1a9-a19d-4b91-9ab6-57cb31c3df28.jpg')"
|
|
119
|
+
>
|
|
120
|
+
获取后端服务器文件进行下载
|
|
121
|
+
</el-button>
|
|
122
|
+
</el-button-group>
|
|
123
|
+
<div>
|
|
124
|
+
<el-avatar shape="square" :src="squareUrl" />
|
|
125
|
+
</div>
|
|
126
|
+
<div>
|
|
127
|
+
<el-button type="primary" plain size="small" @click="handleFileView">获取后端服务器图片</el-button>
|
|
128
|
+
</div>
|
|
129
|
+
</div>
|
|
130
|
+
</template>
|
|
131
|
+
|
|
132
|
+
<style scoped lang="scss">
|
|
133
|
+
h3 {
|
|
134
|
+
color: var(--jnrs-color-primary);
|
|
135
|
+
}
|
|
136
|
+
p {
|
|
137
|
+
margin: 24px 0 8px;
|
|
138
|
+
color: var(--jnrs-background-primary);
|
|
139
|
+
background: var(--jnrs-font-primary);
|
|
140
|
+
}
|
|
141
|
+
</style>
|
|
@@ -1,38 +1,16 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
+
import RequestPage from './RequestPage.vue'
|
|
2
3
|
import { ref, onMounted } from 'vue'
|
|
3
|
-
import { storeToRefs } from 'pinia'
|
|
4
|
-
import { ElMessage } from 'element-plus'
|
|
5
|
-
import { MenuApi, LoginApi, UserInfoApi } from '@/api/system'
|
|
6
|
-
import { NotFoundApi, NoAuth, DetailsApi } from '@/api/mock'
|
|
7
4
|
import { handleRouter } from '@jnrs/vue-core/router'
|
|
8
5
|
import type { MenuItem } from '@jnrs/vue-core'
|
|
9
6
|
import { hasPermission } from '@/utils/permissions'
|
|
10
|
-
import {
|
|
11
|
-
import { objectToFormData } from '@/utils/common'
|
|
12
|
-
|
|
13
|
-
const { isMock } = storeToRefs(useMockStore())
|
|
14
|
-
|
|
15
|
-
const loginParams = ref({
|
|
16
|
-
account: 'user',
|
|
17
|
-
password: '123456'
|
|
18
|
-
})
|
|
7
|
+
import { MenuApi } from '@/api/system'
|
|
19
8
|
|
|
20
9
|
const routeOptions = ref<MenuItem[]>([])
|
|
21
10
|
const currentRoute = ref('')
|
|
22
11
|
const datePicker = ref(new Date())
|
|
23
12
|
|
|
24
|
-
onMounted(() => {
|
|
25
|
-
handleDetailsApi()
|
|
26
|
-
})
|
|
27
|
-
|
|
28
|
-
const handleInfoApi = async () => {
|
|
29
|
-
try {
|
|
30
|
-
const res = await UserInfoApi()
|
|
31
|
-
console.log(res)
|
|
32
|
-
} catch (error) {
|
|
33
|
-
console.log(error)
|
|
34
|
-
}
|
|
35
|
-
}
|
|
13
|
+
onMounted(() => {})
|
|
36
14
|
|
|
37
15
|
const handleMenuApi = async () => {
|
|
38
16
|
try {
|
|
@@ -43,58 +21,6 @@ const handleMenuApi = async () => {
|
|
|
43
21
|
}
|
|
44
22
|
}
|
|
45
23
|
|
|
46
|
-
const handleNotFoundApi = async () => {
|
|
47
|
-
try {
|
|
48
|
-
const res = await NotFoundApi()
|
|
49
|
-
console.log(res)
|
|
50
|
-
} catch (error) {
|
|
51
|
-
console.log(error)
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const handleNoAuth = async (showErrorMsg = true) => {
|
|
56
|
-
try {
|
|
57
|
-
const res = await NoAuth(showErrorMsg)
|
|
58
|
-
console.log(res)
|
|
59
|
-
} catch (error) {
|
|
60
|
-
console.log(error)
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const handleDetailsApi = async () => {
|
|
65
|
-
try {
|
|
66
|
-
const res = await DetailsApi()
|
|
67
|
-
let formatData: Record<string, unknown> = {}
|
|
68
|
-
formatData = {
|
|
69
|
-
...res
|
|
70
|
-
}
|
|
71
|
-
if (res.attachmentDocument?.attachments) {
|
|
72
|
-
formatData.newAttachmentFile = res.attachmentDocument.attachments
|
|
73
|
-
}
|
|
74
|
-
if (res.imageDocument?.attachments) {
|
|
75
|
-
formatData.newImageFiles = res.imageDocument.attachments
|
|
76
|
-
}
|
|
77
|
-
console.log(formatData)
|
|
78
|
-
const formData = objectToFormData(formatData)
|
|
79
|
-
console.log(formData)
|
|
80
|
-
for (const [key, value] of formData.entries()) {
|
|
81
|
-
console.log(key, value)
|
|
82
|
-
}
|
|
83
|
-
} catch (error) {
|
|
84
|
-
console.log(error)
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
const handleLogin = async () => {
|
|
89
|
-
try {
|
|
90
|
-
const res = await LoginApi(loginParams.value)
|
|
91
|
-
ElMessage.success('登录成功')
|
|
92
|
-
console.log(res)
|
|
93
|
-
} catch (error) {
|
|
94
|
-
console.log(error)
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
24
|
const handleRouteChange = () => {
|
|
99
25
|
handleRouter({
|
|
100
26
|
name: currentRoute.value
|
|
@@ -128,29 +54,9 @@ const handleRouteChange = () => {
|
|
|
128
54
|
<button size="small" v-permissions="['test:del']">删除</button>
|
|
129
55
|
</li>
|
|
130
56
|
</ul>
|
|
131
|
-
<
|
|
132
|
-
<div>
|
|
133
|
-
<span>服务器类型:</span>
|
|
134
|
-
<el-switch v-model="isMock" active-text="Mock 服务器" inactive-text="后端服务器" />
|
|
135
|
-
</div>
|
|
136
|
-
<el-button-group>
|
|
137
|
-
<el-button type="success" size="small" @click="handleMenuApi">获取完整菜单数据</el-button>
|
|
138
|
-
<el-button type="success" size="small" @click="handleInfoApi">获取用户数据</el-button>
|
|
139
|
-
<el-button type="primary" size="small" @click="handleNotFoundApi">404</el-button>
|
|
140
|
-
<el-button type="primary" size="small" @click="handleNoAuth()">暂无权限</el-button>
|
|
141
|
-
<el-button type="primary" size="small" @click="handleNoAuth(false)">暂无权限(不显示 Message)</el-button>
|
|
142
|
-
</el-button-group>
|
|
143
|
-
<el-input v-model="loginParams.account" size="small" style="width: 200px">
|
|
144
|
-
<template #append>
|
|
145
|
-
<el-button size="small" @click="handleLogin">验证登录接口</el-button>
|
|
146
|
-
</template>
|
|
147
|
-
</el-input>
|
|
148
|
-
<div>
|
|
149
|
-
<el-button-group>
|
|
150
|
-
<el-button type="primary" plain size="small" @click="handleDetailsApi">获取数据列表单个数据</el-button>
|
|
151
|
-
</el-button-group>
|
|
152
|
-
</div>
|
|
57
|
+
<RequestPage />
|
|
153
58
|
<p>完整路由测试(先点击按钮,获取完整菜单数据)</p>
|
|
59
|
+
<el-button type="success" plain @click="handleMenuApi">获取完整菜单数据</el-button>
|
|
154
60
|
<el-cascader
|
|
155
61
|
v-model="currentRoute"
|
|
156
62
|
:options="routeOptions"
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import type { FormInstance, FormRules } from 'element-plus'
|
|
3
3
|
import { ref } from 'vue'
|
|
4
4
|
import { RoleApi, LoginApi } from '@/api/system'
|
|
5
|
-
import { useAuthStore } from '
|
|
5
|
+
import { useAuthStore } from '@jnrs/vue-core/pinia'
|
|
6
6
|
import { handleRouter, useRoute } from '@jnrs/vue-core/router'
|
|
7
7
|
import { isWeakPwd } from '@jnrs/shared/validator'
|
|
8
8
|
import { formatDateTime, formatWeekday } from '@jnrs/shared'
|
|
@@ -51,21 +51,21 @@ const submitForm = async () => {
|
|
|
51
51
|
const loginDateTime = formatDateTime() + ' ' + formatWeekday()
|
|
52
52
|
|
|
53
53
|
// 获取角色列表,将登录人角色对应的权限叠加给当前登录人(一次性获取叠加)
|
|
54
|
-
const roleRes = await RoleApi()
|
|
55
|
-
let permissionsMerger = restParameter.permissions
|
|
56
|
-
if (Array.isArray(restParameter.permissions)) {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
}
|
|
54
|
+
// const roleRes = await RoleApi()
|
|
55
|
+
// let permissionsMerger = restParameter.permissions
|
|
56
|
+
// if (Array.isArray(restParameter.permissions)) {
|
|
57
|
+
// permissionsMerger = [
|
|
58
|
+
// ...new Set([
|
|
59
|
+
// ...restParameter.permissions,
|
|
60
|
+
// ...(roleRes.find((r) => r.value === restParameter.role)?.permissions ?? []).flat()
|
|
61
|
+
// ])
|
|
62
|
+
// ]
|
|
63
|
+
// }
|
|
64
64
|
// setRole(roleRes) // 由于是一次性获取叠加,此处不需要保存角色列表到全局状态
|
|
65
65
|
|
|
66
66
|
setUserInfo({
|
|
67
67
|
...restParameter,
|
|
68
|
-
permissions: permissionsMerger,
|
|
68
|
+
// permissions: permissionsMerger,
|
|
69
69
|
account: ruleForm.value.account,
|
|
70
70
|
loginDateTime
|
|
71
71
|
})
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { ref } from 'vue'
|
|
3
|
-
import { useMenuStore } from '
|
|
3
|
+
import { useMenuStore } from '@jnrs/vue-core/pinia'
|
|
4
4
|
import { useAsyncTableHeight } from '@jnrs/vue-core/composables'
|
|
5
5
|
|
|
6
6
|
const { maxHeight } = useAsyncTableHeight('el_table_menu', 0)
|
|
@@ -3,9 +3,9 @@ import { ref, onMounted } from 'vue'
|
|
|
3
3
|
import { storeToRefs } from 'pinia'
|
|
4
4
|
import { ElMessage } from 'element-plus'
|
|
5
5
|
import type { UploadProps } from 'element-plus'
|
|
6
|
-
import { useAuthStore } from '
|
|
7
|
-
import { useAvatar } from '@/composables/
|
|
8
|
-
import { getOneDictList } from '@/utils/
|
|
6
|
+
import { useAuthStore } from '@jnrs/vue-core/pinia'
|
|
7
|
+
import { useAvatar } from '@/composables/base/useAvatar'
|
|
8
|
+
import { getOneDictList } from '@/utils/packages'
|
|
9
9
|
import type { User } from '@jnrs/shared'
|
|
10
10
|
|
|
11
11
|
const { userInfo, token } = storeToRefs(useAuthStore())
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { reactive, ref } from 'vue'
|
|
3
3
|
import { PasswordChangeApi } from '@/api/system'
|
|
4
|
-
import { useAuthStore } from '
|
|
4
|
+
import { useAuthStore } from '@jnrs/vue-core/pinia'
|
|
5
5
|
import { handleRouter } from '@jnrs/vue-core/router'
|
|
6
6
|
import { isWeakPwd } from '@jnrs/shared/validator'
|
|
7
7
|
import type { FormInstance, FormItemRule } from 'element-plus'
|
|
@@ -7,6 +7,7 @@ import dictRes from './dictRes.json'
|
|
|
7
7
|
import dictItemRes from './dictItemRes.json'
|
|
8
8
|
import roleRes from './roleRes.json'
|
|
9
9
|
import detailsRes from './detailsRes.json'
|
|
10
|
+
import tableRes from './tableRes.json'
|
|
10
11
|
|
|
11
12
|
export default [
|
|
12
13
|
...successMock,
|
|
@@ -72,5 +73,13 @@ export default [
|
|
|
72
73
|
response: () => {
|
|
73
74
|
return detailsRes
|
|
74
75
|
}
|
|
76
|
+
},
|
|
77
|
+
// 获取表格数据
|
|
78
|
+
{
|
|
79
|
+
url: '/mock/demos/table',
|
|
80
|
+
method: 'get',
|
|
81
|
+
response: () => {
|
|
82
|
+
return tableRes
|
|
83
|
+
}
|
|
75
84
|
}
|
|
76
85
|
]
|