create-jnrs-template-vue 1.2.2 → 1.2.4

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.
Files changed (37) hide show
  1. package/jnrs-template-vue/.env.development +1 -1
  2. package/jnrs-template-vue/index.html +1 -1
  3. package/jnrs-template-vue/package.json +3 -4
  4. package/jnrs-template-vue/public/system/menu.json +11 -2
  5. package/jnrs-template-vue/src/App.vue +1 -3
  6. package/jnrs-template-vue/src/api/common/index.ts +2 -2
  7. package/jnrs-template-vue/src/api/demos/index.ts +85 -43
  8. package/jnrs-template-vue/src/api/system/index.ts +20 -10
  9. package/jnrs-template-vue/src/api/user/index.ts +2 -2
  10. package/jnrs-template-vue/src/assets/styles/index.scss +0 -24
  11. package/jnrs-template-vue/src/assets/styles/init.scss +24 -0
  12. package/jnrs-template-vue/src/assets/styles/root.scss +4 -0
  13. package/jnrs-template-vue/src/components/common/CardTable.vue +89 -0
  14. package/jnrs-template-vue/src/components/common/DictTag.vue +8 -4
  15. package/jnrs-template-vue/src/components/common/ImageView.vue +16 -7
  16. package/jnrs-template-vue/src/components/common/PdfView.vue +14 -5
  17. package/jnrs-template-vue/src/components/select/SelectManager.vue +2 -2
  18. package/jnrs-template-vue/src/layout/SideMenu.vue +0 -1
  19. package/jnrs-template-vue/src/layout/TopHeader.vue +7 -14
  20. package/jnrs-template-vue/src/locales/index.ts +1 -1
  21. package/jnrs-template-vue/src/types/webSocket.ts +19 -0
  22. package/jnrs-template-vue/src/utils/file.ts +36 -1
  23. package/jnrs-template-vue/src/views/demos/crud/index.vue +57 -32
  24. package/jnrs-template-vue/src/views/demos/simpleTable/index.vue +41 -0
  25. package/jnrs-template-vue/src/views/demos/unitTest/RequestPage.vue +2 -2
  26. package/jnrs-template-vue/src/views/demos/unitTest/index.vue +26 -2
  27. package/jnrs-template-vue/src/views/login/index.vue +18 -15
  28. package/jnrs-template-vue/src/views/system/dict/index.vue +63 -76
  29. package/jnrs-template-vue/src/views/system/menu/index.vue +42 -54
  30. package/jnrs-template-vue/src/views/system/mine/baseInfo.vue +26 -59
  31. package/jnrs-template-vue/src/views/system/role/index.vue +20 -29
  32. package/jnrs-template-vue/src/views/visual/index.vue +130 -15
  33. package/jnrs-template-vue/vite.config.ts +0 -1
  34. package/jnrs-template-vue/viteMockServe/fail.ts +12 -0
  35. package/package.json +1 -1
  36. package/jnrs-template-vue/src/composables/base/useAvatar.ts +0 -36
  37. package/jnrs-template-vue/src/composables/tools/useMouseSelection.ts +0 -150
@@ -1,21 +1,17 @@
1
1
  <script setup lang="ts">
2
- import { ref, computed } from 'vue'
2
+ import { ref } from 'vue'
3
3
  import { storeToRefs } from 'pinia'
4
4
  import { ElMessageBox } from 'element-plus'
5
5
  import { handleRouter } from '@jnrs/vue-core/router'
6
6
  import { GlobalSetting } from '@jnrs/vue-core/components'
7
7
  import { useSystemStore, useAuthStore, useMenuStore } from '@jnrs/vue-core/pinia'
8
8
  import { LogoutApi } from '@/api/system'
9
- import { getDictLabel, getDictColor } from '@/utils/packages'
10
-
11
9
  import ImageView from '@/components/common/ImageView.vue'
10
+ import DictTag from '@/components/common/DictTag.vue'
12
11
 
13
12
  const { userInfo, clearAuth } = useAuthStore()
14
13
  const { clearMenu } = useMenuStore()
15
14
 
16
- const roleLabel = computed(() => getDictLabel('role', userInfo?.role || ''))
17
- const roleColor = computed(() => getDictColor('role', userInfo?.role || ''))
18
-
19
15
  const systemStore = useSystemStore()
20
16
  const { documentFullscreen } = storeToRefs(systemStore)
21
17
  const { toggleFullScreen } = systemStore
@@ -29,8 +25,8 @@ const handleLogout = async () => {
29
25
  type: 'warning'
30
26
  })
31
27
  await LogoutApi()
32
- await clearAuth()
33
- await clearMenu()
28
+ clearAuth()
29
+ clearMenu()
34
30
  handleRouter({ name: 'Login' }, 'replace')
35
31
  } catch {}
36
32
  }
@@ -68,16 +64,12 @@ const showGlobalSetting = () => {
68
64
  <span class="userMenu_reference">
69
65
  <ImageView class="userMenu_avatar" :loadKeys="userInfo?.avatarFileName" />
70
66
  <span>{{ userInfo?.name }}</span>
71
- <span class="userMenu_roleName" :style="{ color: roleColor }" v-if="userInfo?.role">[{{ roleLabel }}]</span>
67
+ <DictTag dictName="role" :value="userInfo.role" v-if="userInfo?.role" />
72
68
  <el-icon class="userMenu_icon"><arrow-down /></el-icon>
73
69
  </span>
74
70
  </template>
75
71
  <div class="userMenu_dropdown">
76
72
  <ImageView class="userMenu_dropdown_avatar" :loadKeys="userInfo?.avatarFileName" />
77
- <b>
78
- <span>{{ userInfo?.name }}</span>
79
- <span class="userMenu_roleName" :style="{ color: roleColor }" v-if="userInfo?.role">[{{ roleLabel }}]</span>
80
- </b>
81
73
  <div class="loginDateTime" v-if="userInfo?.loginDateTime">
82
74
  <span>登录时间</span>
83
75
  <p>{{ userInfo?.loginDateTime }}</p>
@@ -132,13 +124,14 @@ $topHoverSize: 35px;
132
124
  display: flex;
133
125
  align-items: center;
134
126
  margin-left: 16px;
135
- transition: all 0.25s ease;
136
127
  cursor: pointer;
137
128
  &:hover {
138
129
  span {
130
+ transition: all 0.25s ease;
139
131
  color: var(--jnrs-color-primary) !important;
140
132
  }
141
133
  .userMenu_icon {
134
+ transition: all 0.25s ease;
142
135
  color: var(--jnrs-color-primary);
143
136
  }
144
137
  }
@@ -4,7 +4,7 @@ import en from './en'
4
4
  import { zhCn as vueCore_zhCn, en as vueCore_en } from '@jnrs/vue-core/locales'
5
5
 
6
6
  const i18n = createI18n({
7
- legacy: false, // 启用 Composition API 模式
7
+ legacy: false, // legacy 为 false 则启用 Composition API 模式
8
8
  globalInjection: true, // 允许在模板中使用 $t
9
9
  locale: 'zhCn',
10
10
  fallbackLocale: 'en',
@@ -0,0 +1,19 @@
1
+ export interface MsgIdMessage {
2
+ msgId: string
3
+ d: unknown
4
+ }
5
+
6
+ export interface TypeDataMessage {
7
+ type: string | number
8
+ data: unknown
9
+ }
10
+
11
+ // 类型守卫函数 MsgId 结构
12
+ export function isMsgIdMessage(msg: unknown): msg is MsgIdMessage {
13
+ return typeof msg === 'object' && msg !== null && 'msgId' in msg && 'd' in msg
14
+ }
15
+
16
+ // 类型守卫函数 Type 结构
17
+ export function isTypeDataMessage(msg: unknown): msg is TypeDataMessage {
18
+ return typeof msg === 'object' && msg !== null && 'type' in msg && 'data' in msg
19
+ }
@@ -6,7 +6,6 @@
6
6
  * @Desc. : 文件处理相关函数
7
7
  */
8
8
 
9
- // import { blobToUrl } from '@jnrs/shared'
10
9
  import { useObjectUrl } from '@vueuse/core'
11
10
  import { FileApi } from '@/api/common'
12
11
 
@@ -19,3 +18,39 @@ export const getFileUrl = async (uniqueFileName: string) => {
19
18
  const blob = await FileApi(uniqueFileName)
20
19
  return useObjectUrl(blob)
21
20
  }
21
+
22
+ /**
23
+ * 从可能为原始值或对象的输入中提取指定字段的值
24
+ * @param value - 输入值(可能是 string/number/对象)
25
+ * @param fieldName - 要提取的对象字段名(默认 'id')
26
+ * @returns 提取出的 string | number 值,或 undefined
27
+ */
28
+ export function extractFieldId(value: unknown, fieldName: string = 'id'): string | number | undefined {
29
+ // 1. 排除 null 和 undefined
30
+ if (value == null) return undefined
31
+
32
+ // 2. 如果是原始 ID 类型,直接返回
33
+ if (typeof value === 'string' || typeof value === 'number') {
34
+ return value
35
+ }
36
+
37
+ // 3. 必须是普通对象(非数组、非 Date 等)
38
+ if (typeof value !== 'object' || Array.isArray(value)) {
39
+ return undefined
40
+ }
41
+
42
+ // 4. 检查对象是否包含目标字段
43
+ if (!(fieldName in value)) {
44
+ return undefined
45
+ }
46
+
47
+ // 5. 安全获取字段值(使用 keyof 断言确保类型安全)
48
+ const fieldValue = (value as Record<string, unknown>)[fieldName]
49
+
50
+ // 6. 只接受 string 或 number 类型
51
+ if (typeof fieldValue === 'string' || typeof fieldValue === 'number') {
52
+ return fieldValue
53
+ }
54
+
55
+ return undefined
56
+ }
@@ -5,13 +5,13 @@ import type { ProjectItem, AddProjectItem } from '@/api/demos/index'
5
5
  import { ref, onActivated } from 'vue'
6
6
  import { ElMessage } from 'element-plus'
7
7
  import { Plus } from '@element-plus/icons-vue'
8
- import { objectMatchAssign } from '@jnrs/shared'
8
+ import { objectMatchAssign, dateFormatsToObject } from '@jnrs/shared'
9
9
  import { debounce } from '@jnrs/shared/lodash'
10
10
  import { isNumberGtZero } from '@jnrs/shared/validator'
11
- import { getDictList, objectToFormData, downloadFile } from '@/utils/packages'
12
- import { DemosTableApi, DemosFormApi } from '@/api/demos/index'
11
+ import { getDictList, downloadFile } from '@/utils/packages'
12
+ import { TableApi, EditApi, ImportTemplateApi, ImportDataApi, ExportApi } from '@/api/demos/index'
13
13
 
14
- import { JnDialog, JnDatetime, JnPagination, JnFileUpload, JnTable } from '@jnrs/vue-core/components'
14
+ import { JnDialog, JnDatetime, JnPagination, JnFileUpload, JnTable, JnImportAndExport } from '@jnrs/vue-core/components'
15
15
  import ImageView from '@/components/common/ImageView.vue'
16
16
  import PdfView from '@/components/common/PdfView.vue'
17
17
  import DictTag from '@/components/common/DictTag.vue'
@@ -28,12 +28,11 @@ const total = ref(0)
28
28
  const pagination = ref<Pagination>({ pageNo: 1, pageSize: 10 })
29
29
 
30
30
  // 编辑
31
- const jnEditRef = ref()
31
+ const editDialogRef = ref()
32
32
  const ruleFormRef = ref<FormInstance>()
33
33
  const ruleForm = ref<AddProjectItem>({
34
34
  id: '',
35
35
  name: '',
36
- program: '',
37
36
  projectType: undefined,
38
37
  managerId: undefined,
39
38
  budget: 0,
@@ -44,7 +43,6 @@ const ruleForm = ref<AddProjectItem>({
44
43
  })
45
44
  const rules = ref<FormRules>({
46
45
  name: [{ required: true, message: '请输入', trigger: 'change' }],
47
- program: [{ required: true, message: '请选择', trigger: 'change' }],
48
46
  projectType: [{ required: true, message: '请选择', trigger: 'change' }],
49
47
  plannedStartDate: [{ required: true, message: '请选择', trigger: 'change' }],
50
48
  newImageFiles: [{ required: true, message: '请上传', trigger: 'change' }],
@@ -62,16 +60,18 @@ const rules = ref<FormRules>({
62
60
  const queryForm = ref({
63
61
  code: '',
64
62
  projectType: undefined,
65
- manager: ''
63
+ manager: '',
64
+ plannedStartDate: ''
66
65
  })
67
66
 
68
67
  const handleSelectionChange = (row: ProjectItem[]) => {
69
68
  console.log(row)
70
69
  }
71
70
 
72
- const getDemosTable = debounce(async () => {
71
+ const getTable = debounce(async () => {
72
+ loading.value = true
73
73
  try {
74
- const res = await DemosTableApi({
74
+ const res = await TableApi({
75
75
  ...pagination.value,
76
76
  ...queryForm.value
77
77
  })
@@ -83,12 +83,14 @@ const getDemosTable = debounce(async () => {
83
83
  total.value = res.count
84
84
  } catch (error) {
85
85
  console.error(error)
86
+ } finally {
87
+ loading.value = false
86
88
  }
87
89
  }, 300)
88
90
 
89
91
  // 新增和修改
90
92
  const handleEdit = (row?: ProjectItem) => {
91
- jnEditRef.value.open()
93
+ editDialogRef.value.open()
92
94
  queueMicrotask(() => {
93
95
  ruleFormRef.value?.resetFields()
94
96
  const matched = objectMatchAssign(ruleForm.value, row)
@@ -108,15 +110,12 @@ const submitForm = () => {
108
110
  ruleFormRef.value?.validate(async (valid) => {
109
111
  if (valid) {
110
112
  loading.value = true
111
- const formData = objectToFormData({
112
- ...ruleForm.value,
113
- managerId: ruleForm.value.managerId?.managerId
114
- })
115
113
  try {
116
- await DemosFormApi(formData)
114
+ await EditApi(ruleForm.value)
117
115
  ElMessage({
118
116
  message: '数据已保存',
119
117
  grouping: true,
118
+ showClose: true,
120
119
  type: 'success'
121
120
  })
122
121
  } catch (err) {
@@ -129,13 +128,13 @@ const submitForm = () => {
129
128
  }
130
129
 
131
130
  onActivated(() => {
132
- getDemosTable()
131
+ getTable()
133
132
  })
134
133
  </script>
135
134
 
136
135
  <template>
137
136
  <!-- 编辑弹窗 -->
138
- <JnDialog ref="jnEditRef" title="项目管理" width="600px">
137
+ <JnDialog ref="editDialogRef" title="项目管理" width="600px">
139
138
  <el-form ref="ruleFormRef" :model="ruleForm" :rules="rules" label-width="auto" v-loading="loading">
140
139
  <el-form-item prop="id"></el-form-item>
141
140
  <el-form-item label="项目名称" prop="name">
@@ -209,20 +208,41 @@ onActivated(() => {
209
208
  </template>
210
209
  </JnDialog>
211
210
 
212
- <el-card>
211
+ <el-card v-loading="loading">
213
212
  <template #header>
214
- <div style="display: flex; justify-content: space-between">
213
+ <div style="display: flex; justify-content: space-between; align-items: center">
215
214
  <span>项目管理</span>
216
- <el-button type="primary" size="small" :icon="Plus" @click="handleEdit()">新增</el-button>
215
+ <div style="display: flex; justify-content: space-between; align-items: center">
216
+ <JnImportAndExport
217
+ :importTemplateApi="ImportTemplateApi"
218
+ importBtnName="导入项目"
219
+ :importApi="ImportDataApi"
220
+ exportBtnName="导出项目"
221
+ :exportApi="ExportApi"
222
+ :exportParams="{
223
+ ...dateFormatsToObject(queryForm.plannedStartDate)
224
+ }"
225
+ :exportDynamicParamsConfig="{
226
+ label: '项目编号',
227
+ prop: 'code'
228
+ }"
229
+ :exportDisabled="tableData.length === 0"
230
+ size="small"
231
+ @change="getTable()"
232
+ />
233
+ <el-button type="primary" size="small" :icon="Plus" @click="handleEdit()" style="margin-left: 12px">
234
+ 新增
235
+ </el-button>
236
+ </div>
217
237
  </div>
218
238
  </template>
219
239
 
220
240
  <!-- 查询条件 -->
221
241
  <el-form :model="queryForm" size="small" inline v-loading="loading">
222
242
  <el-form-item label="项目编号" prop="code">
223
- <el-input v-model="queryForm.code" clearable style="width: 150px">
243
+ <el-input v-model="queryForm.code" clearable style="width: 200px">
224
244
  <template #append>
225
- <el-button icon="Search" @click="getDemosTable()" />
245
+ <el-button icon="Search" @click="getTable()" />
226
246
  </template>
227
247
  </el-input>
228
248
  </el-form-item>
@@ -232,8 +252,8 @@ onActivated(() => {
232
252
  filterable
233
253
  placeholder=""
234
254
  clearable
235
- style="width: 150px"
236
- @change="getDemosTable()"
255
+ style="width: 200px"
256
+ @change="getTable()"
237
257
  >
238
258
  <el-option
239
259
  :label="item.label"
@@ -249,9 +269,18 @@ onActivated(() => {
249
269
  :initialParams="{ role: 1 }"
250
270
  size="small"
251
271
  width="200px"
252
- @change="getDemosTable()"
272
+ @change="getTable()"
253
273
  ></SelectManager>
254
274
  </el-form-item>
275
+ <el-form-item label="计划开始时间" prop="plannedStartDate">
276
+ <el-date-picker
277
+ v-model="queryForm.plannedStartDate"
278
+ value-format="YYYY-MM-DD"
279
+ size="small"
280
+ style="width: 200px"
281
+ @change="getTable()"
282
+ />
283
+ </el-form-item>
255
284
  </el-form>
256
285
 
257
286
  <!-- 数据列表 -->
@@ -266,11 +295,7 @@ onActivated(() => {
266
295
  @selection-change="handleSelectionChange"
267
296
  >
268
297
  <el-table-column prop="code" label="项目编号" min-width="200" sortable show-overflow-tooltip />
269
- <el-table-column prop="name" label="项目名称" min-width="200" sortable show-overflow-tooltip>
270
- <template #default="{ row }">
271
- {{ row.name }}
272
- </template>
273
- </el-table-column>
298
+ <el-table-column prop="name" label="项目名称" min-width="200" sortable show-overflow-tooltip />
274
299
  <el-table-column prop="program" label="项目集名称" min-width="200" sortable show-overflow-tooltip />
275
300
  <el-table-column prop="projectType" label="项目类型" width="100" align="center" sortable>
276
301
  <template #default="{ row }">
@@ -322,6 +347,6 @@ onActivated(() => {
322
347
  </JnTable>
323
348
 
324
349
  <!-- 表格分页 -->
325
- <JnPagination :total="total" v-model="pagination" @change="getDemosTable" />
350
+ <JnPagination :total="total" v-model="pagination" @change="getTable" />
326
351
  </el-card>
327
352
  </template>
@@ -0,0 +1,41 @@
1
+ <script setup lang="ts">
2
+ import { TableApi } from '@/api/demos/index'
3
+ import { JnDatetime } from '@jnrs/vue-core/components'
4
+ import CardTable from '@/components/common/CardTable.vue'
5
+ import ImageView from '@/components/common/ImageView.vue'
6
+ import PdfView from '@/components/common/PdfView.vue'
7
+ import DictTag from '@/components/common/DictTag.vue'
8
+ </script>
9
+
10
+ <template>
11
+ <CardTable :getTableDataApi="TableApi">
12
+ <template #header>项目列表</template>
13
+ <template #table>
14
+ <el-table-column prop="name" label="项目名称" min-width="200" sortable show-overflow-tooltip />
15
+ <el-table-column prop="projectType" label="项目类型" width="100" align="center" sortable>
16
+ <template #default="{ row }">
17
+ <DictTag dictName="projectType" :value="row.projectType" />
18
+ </template>
19
+ </el-table-column>
20
+ <el-table-column prop="manager" label="项目经理" width="100" align="center" sortable />
21
+ <el-table-column prop="plannedStartDate" label="计划开始时间" width="130" align="center" sortable>
22
+ <template #default="{ row }">
23
+ <JnDatetime :value="row.plannedStartDate" />
24
+ </template>
25
+ </el-table-column>
26
+ <el-table-column prop="description" label="描述" min-width="200" show-overflow-tooltip />
27
+ <el-table-column prop="imageDocument" label="图片" width="100" align="center" sortable>
28
+ <template #default="{ row }">
29
+ <ImageView :loadKeys="row.newImageFiles" preview height="50px" />
30
+ </template>
31
+ </el-table-column>
32
+ <el-table-column prop="attachmentDocument" label="附件" width="100" align="center" sortable>
33
+ <template #default="{ row }">
34
+ <PdfView :loadKeys="row.newAttachmentFile" isPdf />
35
+ </template>
36
+ </el-table-column>
37
+ </template>
38
+ </CardTable>
39
+ </template>
40
+
41
+ <style lang="scss" scoped></style>
@@ -3,7 +3,7 @@ import { ref } from 'vue'
3
3
  import { ElMessage } from 'element-plus'
4
4
  import { objectToFormData } from '@/utils/packages'
5
5
  import { LoginApi, UserInfoApi } from '@/api/system'
6
- import { NotFoundApi, NoAuth, DetailsApi } from '@/api/demos'
6
+ import { NotFoundApi, NoAuthApi, DetailsApi } from '@/api/demos'
7
7
  import { getFileUrl } from '@/utils/file'
8
8
  import { downloadFile } from '@/utils/packages'
9
9
 
@@ -36,7 +36,7 @@ const handleNotFoundApi = async () => {
36
36
 
37
37
  const handleNoAuth = async (showErrorMsg = true) => {
38
38
  try {
39
- const res = await NoAuth(showErrorMsg)
39
+ const res = await NoAuthApi(showErrorMsg)
40
40
  console.log(res)
41
41
  } catch (error) {
42
42
  console.log(error)
@@ -5,12 +5,16 @@ import { handleRouter } from '@jnrs/vue-core/router'
5
5
  import type { MenuItem } from '@jnrs/vue-core'
6
6
  import { hasPermission } from '@/utils/permissions'
7
7
  import { MenuApi } from '@/api/system'
8
+ import { formatDateTime, formatWeekday } from '@jnrs/shared'
9
+ import { isFloatGtZero } from '@jnrs/shared/validator'
10
+ import { testI18n } from '@jnrs/shared/request'
8
11
 
9
12
  const routeOptions = ref<MenuItem[]>([])
10
13
  const currentRoute = ref('')
11
14
  const datePicker = ref(new Date())
12
-
13
- onMounted(() => {})
15
+ const datetime = ref(formatDateTime() + ' ' + formatWeekday())
16
+ const validator = ref()
17
+ const testI18nInCore = ref('')
14
18
 
15
19
  const handleMenuApi = async () => {
16
20
  try {
@@ -26,11 +30,31 @@ const handleRouteChange = () => {
26
30
  name: currentRoute.value
27
31
  })
28
32
  }
33
+
34
+ const changeI18n = () => {
35
+ datetime.value = formatDateTime() + ' ' + formatWeekday()
36
+ isFloatGtZero({}, '0', (msg) => {
37
+ validator.value = msg
38
+ })
39
+ testI18nInCore.value = testI18n()
40
+ }
41
+
42
+ onMounted(() => {
43
+ isFloatGtZero({}, '0', (msg) => {
44
+ validator.value = msg
45
+ })
46
+ testI18nInCore.value = testI18n()
47
+ })
29
48
  </script>
30
49
 
31
50
  <template>
32
51
  <div>
33
52
  <h3>Playground - 功能测试</h3>
53
+ <p>国际化测试</p>
54
+ <div>@jnrs/shared: {{ datetime }}</div>
55
+ <div>@jnrs/shared/validator: {{ validator }}</div>
56
+ <div>@jnrs/shared/request: {{ testI18nInCore }}</div>
57
+ <el-button type="primary" size="small" @click="changeI18n">切换语言后点击按钮更新国际化显示</el-button>
34
58
  <p>权限测试(admin 账号拥有全部权限,请用非 admin 账号测试该功能)</p>
35
59
  <ul>
36
60
  <li>
@@ -45,18 +45,22 @@ const submitForm = async () => {
45
45
  const { token, dict, ...restParameter } = loginRes
46
46
  const loginDateTime = formatDateTime() + ' ' + formatWeekday()
47
47
 
48
- // 获取角色列表,将登录人角色对应的权限叠加给当前登录人(一次性获取叠加)
49
- const roleRes = await RoleApi()
50
48
  let permissionsMerger = restParameter.permissions
51
- if (Array.isArray(restParameter.permissions)) {
52
- permissionsMerger = [
53
- ...new Set([
54
- ...restParameter.permissions,
55
- ...(roleRes.find((r) => r.value === restParameter.role)?.permissions ?? []).flat()
56
- ])
57
- ]
49
+ try {
50
+ // 获取角色列表,将登录人角色对应的权限叠加给当前登录人(一次性获取叠加)
51
+ const roleRes = await RoleApi()
52
+ if (Array.isArray(restParameter.permissions)) {
53
+ permissionsMerger = [
54
+ ...new Set([
55
+ ...restParameter.permissions,
56
+ ...(roleRes.find((r) => r.value === restParameter.role)?.permissions ?? []).flat()
57
+ ])
58
+ ]
59
+ }
60
+ setRole(roleRes) // 由于是一次性获取叠加,此处不需要保存角色列表到全局状态
61
+ } catch (e) {
62
+ console.log(e)
58
63
  }
59
- setRole(roleRes) // 由于是一次性获取叠加,此处不需要保存角色列表到全局状态
60
64
 
61
65
  setUserInfo({
62
66
  ...restParameter,
@@ -153,6 +157,7 @@ const submitForm = async () => {
153
157
 
154
158
  .topBarBtn {
155
159
  font-size: 22px;
160
+ color: #c2c2c2;
156
161
  }
157
162
 
158
163
  .topFixed_right {
@@ -163,9 +168,9 @@ const submitForm = async () => {
163
168
  display: flex;
164
169
  align-items: center;
165
170
  justify-content: space-around;
166
- background: var(--jnrs-card-primary);
167
- padding: 4px 16px;
168
- border-radius: 10px;
171
+ padding: 8px 16px;
172
+ // background: var(--jnrs-card-primary);
173
+ // border-radius: 10px;
169
174
  }
170
175
 
171
176
  .card {
@@ -204,7 +209,6 @@ const submitForm = async () => {
204
209
  .title {
205
210
  text-align: center;
206
211
  font-size: 24px;
207
- letter-spacing: 4px;
208
212
  white-space: nowrap;
209
213
  font-weight: normal;
210
214
  font-family: AlimamaShuHeiTi-Bold;
@@ -289,7 +293,6 @@ const submitForm = async () => {
289
293
  position: absolute;
290
294
  bottom: 5px;
291
295
  font-size: 12px;
292
- letter-spacing: 2px;
293
296
  text-transform: uppercase;
294
297
  color: rgba(0, 0, 0, 0.1);
295
298
  }