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.
Files changed (93) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +61 -0
  3. package/bin/create.mjs +221 -0
  4. package/bin/upgrade.mjs +40 -0
  5. package/jnrs-template-vue/.env.development +13 -0
  6. package/jnrs-template-vue/.env.production +4 -0
  7. package/jnrs-template-vue/.prettierrc.json +12 -0
  8. package/jnrs-template-vue/README.md +48 -0
  9. package/jnrs-template-vue/auto-imports.d.ts +17 -0
  10. package/jnrs-template-vue/components.d.ts +51 -0
  11. package/jnrs-template-vue/eslint.config.ts +40 -0
  12. package/jnrs-template-vue/index.html +13 -0
  13. package/jnrs-template-vue/package.json +55 -0
  14. package/jnrs-template-vue/public/favicon.ico +0 -0
  15. package/jnrs-template-vue/public/system/menu.json +137 -0
  16. package/jnrs-template-vue/src/App.vue +45 -0
  17. package/jnrs-template-vue/src/api/common/index.ts +28 -0
  18. package/jnrs-template-vue/src/api/demos/index.ts +155 -0
  19. package/jnrs-template-vue/src/api/request.ts +53 -0
  20. package/jnrs-template-vue/src/api/system/index.ts +107 -0
  21. package/jnrs-template-vue/src/api/user/index.ts +12 -0
  22. package/jnrs-template-vue/src/assets/fonts/.keep +0 -0
  23. package/jnrs-template-vue/src/assets/fonts/AlibabaPuHuiTi-Regular.woff2 +0 -0
  24. package/jnrs-template-vue/src/assets/fonts/AlimamaShuHeiTi-Bold.woff2 +0 -0
  25. package/jnrs-template-vue/src/assets/images/common/403.png +0 -0
  26. package/jnrs-template-vue/src/assets/images/common/404.png +0 -0
  27. package/jnrs-template-vue/src/assets/images/common/avatar.png +0 -0
  28. package/jnrs-template-vue/src/assets/images/common/jnrs-white.svg +1 -0
  29. package/jnrs-template-vue/src/assets/styles/animation.scss +0 -0
  30. package/jnrs-template-vue/src/assets/styles/common.scss +39 -0
  31. package/jnrs-template-vue/src/assets/styles/fonts.scss +27 -0
  32. package/jnrs-template-vue/src/assets/styles/index.scss +5 -0
  33. package/jnrs-template-vue/src/assets/styles/init.scss +41 -0
  34. package/jnrs-template-vue/src/assets/styles/root.scss +13 -0
  35. package/jnrs-template-vue/src/components/common/CardTable.vue +90 -0
  36. package/jnrs-template-vue/src/components/common/DictTag.vue +74 -0
  37. package/jnrs-template-vue/src/components/common/ImageView.vue +144 -0
  38. package/jnrs-template-vue/src/components/common/PdfView.vue +115 -0
  39. package/jnrs-template-vue/src/components/select/SelectManager.vue +26 -0
  40. package/jnrs-template-vue/src/directives/permissions.ts +28 -0
  41. package/jnrs-template-vue/src/layout/BlankLayout.vue +15 -0
  42. 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
  43. package/jnrs-template-vue/src/layout/RouterTabs.vue +142 -0
  44. package/jnrs-template-vue/src/layout/SideMenu.vue +208 -0
  45. package/jnrs-template-vue/src/layout/SideMenuItem.vue +38 -0
  46. package/jnrs-template-vue/src/layout/TopHeader.vue +184 -0
  47. package/jnrs-template-vue/src/layout/index.vue +71 -0
  48. package/jnrs-template-vue/src/locales/en.ts +14 -0
  49. package/jnrs-template-vue/src/locales/index.ts +23 -0
  50. package/jnrs-template-vue/src/locales/zhCn.ts +14 -0
  51. package/jnrs-template-vue/src/main.ts +31 -0
  52. package/jnrs-template-vue/src/router/index.ts +77 -0
  53. package/jnrs-template-vue/src/router/routes.ts +48 -0
  54. package/jnrs-template-vue/src/types/env.d.ts +12 -0
  55. package/jnrs-template-vue/src/types/index.ts +81 -0
  56. package/jnrs-template-vue/src/types/webSocket.ts +19 -0
  57. package/jnrs-template-vue/src/utils/file.ts +56 -0
  58. package/jnrs-template-vue/src/utils/packages.ts +116 -0
  59. package/jnrs-template-vue/src/utils/permissions.ts +16 -0
  60. package/jnrs-template-vue/src/views/common/403.vue +52 -0
  61. package/jnrs-template-vue/src/views/common/404.vue +52 -0
  62. package/jnrs-template-vue/src/views/demos/crud/index.vue +355 -0
  63. package/jnrs-template-vue/src/views/demos/simpleTable/index.vue +41 -0
  64. package/jnrs-template-vue/src/views/demos/unitTest/RequestPage.vue +137 -0
  65. package/jnrs-template-vue/src/views/demos/unitTest/index.vue +131 -0
  66. package/jnrs-template-vue/src/views/home/index.vue +9 -0
  67. package/jnrs-template-vue/src/views/lingshuSmart/editorPage.vue +9 -0
  68. package/jnrs-template-vue/src/views/login/index.vue +314 -0
  69. package/jnrs-template-vue/src/views/system/dict/index.vue +161 -0
  70. package/jnrs-template-vue/src/views/system/menu/index.vue +43 -0
  71. package/jnrs-template-vue/src/views/system/mine/baseInfo.vue +108 -0
  72. package/jnrs-template-vue/src/views/system/mine/index.vue +83 -0
  73. package/jnrs-template-vue/src/views/system/mine/securitySettings.vue +105 -0
  74. package/jnrs-template-vue/src/views/system/role/editDialog.vue +94 -0
  75. package/jnrs-template-vue/src/views/system/role/index.vue +41 -0
  76. package/jnrs-template-vue/src/views/visual/index.vue +143 -0
  77. package/jnrs-template-vue/tsconfig.json +25 -0
  78. package/jnrs-template-vue/vite.config.ts +71 -0
  79. package/jnrs-template-vue/viteMockServe/fail.ts +38 -0
  80. package/jnrs-template-vue/viteMockServe/file/mock-pdf.pdf +0 -0
  81. package/jnrs-template-vue/viteMockServe/file/mock-png-0.png +0 -0
  82. package/jnrs-template-vue/viteMockServe/file/mock-png-1.png +0 -0
  83. package/jnrs-template-vue/viteMockServe/file.ts +67 -0
  84. package/jnrs-template-vue/viteMockServe/index.ts +87 -0
  85. package/jnrs-template-vue/viteMockServe/json/detailsRes.json +56 -0
  86. package/jnrs-template-vue/viteMockServe/json/dictItemRes.json +27 -0
  87. package/jnrs-template-vue/viteMockServe/json/dictRes.json +21 -0
  88. package/jnrs-template-vue/viteMockServe/json/loginRes_admin.json +157 -0
  89. package/jnrs-template-vue/viteMockServe/json/loginRes_user.json +713 -0
  90. package/jnrs-template-vue/viteMockServe/json/roleRes.json +37 -0
  91. package/jnrs-template-vue/viteMockServe/json/tableRes.json +390 -0
  92. package/jnrs-template-vue/viteMockServe/success.ts +39 -0
  93. package/package.json +41 -0
@@ -0,0 +1,314 @@
1
+ <script setup lang="ts">
2
+ import type { FormInstance, FormRules } from 'element-plus'
3
+ import { ref } from 'vue'
4
+ import { RoleApi, LoginApi } from '@/api/system'
5
+ import { useAuthStore } from '@jnrs/vue-core/pinia'
6
+ import { handleRouter, useRoute } from '@jnrs/vue-core/router'
7
+ import { isWeakPwd } from '@jnrs/shared/validator'
8
+ import { formatDateTime, formatWeekday } from '@jnrs/shared'
9
+ import { GlobalSetting } from '@jnrs/vue-core/components'
10
+
11
+ const route = useRoute()
12
+
13
+ const globalSettingRef = ref()
14
+ const showGlobalSetting = () => {
15
+ globalSettingRef.value.handleShow()
16
+ }
17
+
18
+ const loading = ref(false)
19
+ const { setUserInfo, setToken, setDict, setRole } = useAuthStore()
20
+
21
+ // 表单 ref
22
+ const ruleFormRef = ref<FormInstance>()
23
+ // 表单数据
24
+ const ruleForm = ref({
25
+ account: '',
26
+ password: ''
27
+ })
28
+ // 校验规则
29
+ const rules = ref<FormRules>({
30
+ account: [{ required: true, message: '请输入用户名', trigger: 'change' }],
31
+ password: [
32
+ { required: true, message: '请输入密码', trigger: 'change' },
33
+ { validator: isWeakPwd, trigger: 'change' }
34
+ ]
35
+ })
36
+
37
+ // 提交函数
38
+ const submitForm = async () => {
39
+ if (!ruleFormRef.value) return
40
+ ruleFormRef.value.validate(async (valid) => {
41
+ if (!valid) return
42
+ loading.value = true
43
+
44
+ try {
45
+ const loginRes = await LoginApi(ruleForm.value)
46
+ const { token, dict, ...restParameter } = loginRes
47
+ const loginDateTime = formatDateTime() + ' ' + formatWeekday()
48
+
49
+ // 登录成功后,获取角色列表,将登录人角色对应的权限叠加给当前登录人(一次性获取叠加)
50
+ let permissionsMerger = restParameter.permissions
51
+ try {
52
+ const roleRes = await RoleApi()
53
+ if (Array.isArray(restParameter.permissions)) {
54
+ permissionsMerger = [
55
+ ...new Set([
56
+ ...restParameter.permissions,
57
+ ...(roleRes.find((r) => r.value === restParameter.role)?.permissions ?? []).flat()
58
+ ])
59
+ ]
60
+ }
61
+ setRole(roleRes) // 由于是一次性获取叠加,此处不需要保存角色列表到全局状态
62
+ } catch (e) {
63
+ console.log(e)
64
+ }
65
+
66
+ // 保存用户信息到全局状态
67
+ setUserInfo({
68
+ ...restParameter,
69
+ permissions: permissionsMerger,
70
+ account: ruleForm.value.account,
71
+ loginDateTime
72
+ })
73
+ setToken(token)
74
+ setDict(dict)
75
+ handleRouter({ path: route.query.redirect?.toString() || '/' }, 'replace')
76
+ } catch (e) {
77
+ console.log(e)
78
+ } finally {
79
+ loading.value = false
80
+ }
81
+ })
82
+ }
83
+ </script>
84
+
85
+ <template>
86
+ <div class="login no_select">
87
+ <div class="topFixed_right">
88
+ <el-icon class="topBarBtn" title="全局偏好设置" @click="showGlobalSetting()">
89
+ <el-icon><Setting /></el-icon>
90
+ </el-icon>
91
+ </div>
92
+ <div class="card">
93
+ <div class="card_left">
94
+ <div class="card_left_mid">
95
+ <img class="logo" src="@/assets/images/common/jnrs-white.svg" alt="JNRS" />
96
+ <h5 class="title">{{ $t('login.title') }}</h5>
97
+ </div>
98
+ </div>
99
+ <div class="card_right">
100
+ <div class="card_right_mid">
101
+ <h1 class="title">{{ $t('login.formTitle') }}</h1>
102
+ <el-form
103
+ class="form"
104
+ ref="ruleFormRef"
105
+ :model="ruleForm"
106
+ :rules="rules"
107
+ size="large"
108
+ @keyup.enter="submitForm()"
109
+ >
110
+ <el-form-item prop="account">
111
+ <el-input
112
+ v-model="ruleForm.account"
113
+ :placeholder="$t('login.formAccount')"
114
+ prefix-icon="User"
115
+ clearable
116
+ />
117
+ </el-form-item>
118
+ <el-form-item prop="password">
119
+ <el-input
120
+ v-model="ruleForm.password"
121
+ type="password"
122
+ autocomplete="off"
123
+ :placeholder="$t('login.formPassword')"
124
+ prefix-icon="Lock"
125
+ show-password
126
+ ></el-input>
127
+ </el-form-item>
128
+ <el-form-item>
129
+ <el-button class="btn" type="primary" :loading="loading" @click="submitForm()">
130
+ {{ $t('login.formBtn') }}
131
+ </el-button>
132
+ </el-form-item>
133
+ </el-form>
134
+ <div class="greeting">{{ $t('login.greeting') }}</div>
135
+ </div>
136
+ <div class="copyright">Powered by JNRS TECH 2026</div>
137
+ </div>
138
+ </div>
139
+ </div>
140
+ <GlobalSetting ref="globalSettingRef" />
141
+ </template>
142
+
143
+ <style scoped lang="scss">
144
+ .login {
145
+ position: relative;
146
+ width: 100%;
147
+ height: 100%;
148
+ background: radial-gradient(circle at center, #232a4c, #000);
149
+
150
+ &::before {
151
+ content: '';
152
+ position: absolute;
153
+ width: 100%;
154
+ height: 100%;
155
+ background-image: radial-gradient(transparent 50%, rgba(255, 255, 255, 0.05) 50%);
156
+ background-size: 10px 10px;
157
+ }
158
+ }
159
+
160
+ .topBarBtn {
161
+ font-size: 22px;
162
+ color: #c2c2c2;
163
+ }
164
+
165
+ .topFixed_right {
166
+ position: absolute;
167
+ top: 4px;
168
+ right: 4px;
169
+ z-index: 1;
170
+ display: flex;
171
+ align-items: center;
172
+ justify-content: space-around;
173
+ padding: 8px 16px;
174
+ }
175
+
176
+ .card {
177
+ display: flex;
178
+ align-items: center;
179
+ position: absolute;
180
+ left: 50%;
181
+ top: 50%;
182
+ transform: translate(-50%, -50%);
183
+ width: 1000px;
184
+ height: 500px;
185
+ border-radius: 15px;
186
+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
187
+ overflow: hidden;
188
+
189
+ .card_left {
190
+ display: flex;
191
+ justify-content: center;
192
+ align-items: center;
193
+ width: 50%;
194
+ height: 100%;
195
+ background: radial-gradient(circle at center, #232a4c, #000);
196
+ box-shadow: 3px 0 6px rgba(0, 0, 0, 0.3);
197
+
198
+ .card_left_mid {
199
+ width: 50%;
200
+
201
+ .logo {
202
+ width: 100%;
203
+ margin-bottom: 20px;
204
+ filter: opacity(0.5);
205
+ }
206
+
207
+ .title {
208
+ text-align: center;
209
+ font-size: 24px;
210
+ white-space: nowrap;
211
+ font-weight: normal;
212
+ font-family: AlimamaShuHeiTi-Bold;
213
+ color: rgba(255, 255, 255, 0.5);
214
+ }
215
+ }
216
+ }
217
+
218
+ .card_right {
219
+ width: 50%;
220
+ height: 100%;
221
+ display: flex;
222
+ align-items: center;
223
+ justify-content: center;
224
+ position: relative;
225
+
226
+ &::after {
227
+ content: '';
228
+ position: absolute;
229
+ z-index: -1;
230
+ left: 0;
231
+ top: 0;
232
+ width: 100%;
233
+ height: 100%;
234
+ backdrop-filter: blur(2px);
235
+ -webkit-backdrop-filter: blur(2px);
236
+ }
237
+
238
+ .card_right_mid {
239
+ width: 50%;
240
+
241
+ .title {
242
+ text-align: center;
243
+ text-transform: uppercase;
244
+ color: var(--jnrs-color-primary);
245
+ }
246
+
247
+ .form {
248
+ margin-top: 50px;
249
+ }
250
+
251
+ .btn {
252
+ width: 100%;
253
+ background: var(--jnrs-color-primary);
254
+ border: none;
255
+ transition: all 0.25s ease;
256
+
257
+ &:hover {
258
+ background: var(--jnrs-color-primary-light);
259
+ }
260
+ }
261
+
262
+ .greeting {
263
+ position: relative;
264
+ color: var(--jnrs-color-primary-06);
265
+ font-size: 14px;
266
+ text-align: center;
267
+ text-transform: uppercase;
268
+
269
+ &::before,
270
+ &::after {
271
+ content: '';
272
+ position: absolute;
273
+ right: 0;
274
+ top: 50%;
275
+ width: 35%;
276
+ height: 1px;
277
+ background: var(--jnrs-color-primary-06);
278
+ transform: translateY(-50%);
279
+ filter: opacity(0.25);
280
+ }
281
+
282
+ &::after {
283
+ left: 0;
284
+ top: 50%;
285
+ }
286
+ }
287
+ }
288
+
289
+ .copyright {
290
+ position: absolute;
291
+ bottom: 5px;
292
+ font-size: 12px;
293
+ text-transform: uppercase;
294
+ color: var(--jnrs-font-primary-01);
295
+ }
296
+ }
297
+ }
298
+
299
+ .light {
300
+ .card_right {
301
+ &::after {
302
+ background: var(--jnrs-card-primary-06);
303
+ }
304
+ }
305
+ }
306
+
307
+ .dark {
308
+ .card_right {
309
+ &::after {
310
+ background: var(--jnrs-card-primary-03);
311
+ }
312
+ }
313
+ }
314
+ </style>
@@ -0,0 +1,161 @@
1
+ <script setup lang="ts">
2
+ import type { DictItem } from '@jnrs/shared'
3
+ import { ElMessage } from 'element-plus'
4
+ import { ref, onActivated } from 'vue'
5
+ import { DictApi, DictDetailApi, DictChangeApi } from '@/api/system'
6
+ import { hasPermission } from '@/utils/permissions'
7
+ import { JnTable } from '@jnrs/vue-core/components'
8
+
9
+ const PERMISSION_EDIT = ['dict:edit']
10
+ const loading = ref(false)
11
+ const tableData = ref<DictItem[]>()
12
+ const predefineColors = ref([
13
+ '#000000',
14
+ '#999999',
15
+ '#f2f2f2',
16
+ '#ffffff',
17
+ '#65DC79',
18
+ '#5887F7',
19
+ '#E43634',
20
+ '#FEA822',
21
+ '#C9512C'
22
+ ])
23
+
24
+ onActivated(() => {
25
+ getList()
26
+ })
27
+
28
+ const getList = () => {
29
+ loading.value = true
30
+ DictApi()
31
+ .then((res) => {
32
+ tableData.value = res
33
+ })
34
+ .finally(() => {
35
+ loading.value = false
36
+ })
37
+ }
38
+
39
+ const handleExpandChange = (row: DictItem) => {
40
+ loading.value = true
41
+ DictDetailApi(String(row.id))
42
+ .then((res) => {
43
+ row.options = res
44
+ })
45
+ .finally(() => {
46
+ loading.value = false
47
+ })
48
+ }
49
+
50
+ // 保存键值对
51
+ const editKeyValue = (row: DictItem) => {
52
+ if (!row.label) {
53
+ ElMessage({
54
+ type: 'warning',
55
+ message: 'label 不能为空'
56
+ })
57
+ return false
58
+ }
59
+ loading.value = true
60
+ DictChangeApi(row)
61
+ .then(() => {
62
+ ElMessage({
63
+ type: 'success',
64
+ message: '修改成功',
65
+ grouping: true
66
+ })
67
+ })
68
+ .finally(() => {
69
+ loading.value = false
70
+ })
71
+ }
72
+ </script>
73
+
74
+ <template>
75
+ <el-card v-loading="loading">
76
+ <template #header>
77
+ <span>字典管理</span>
78
+ </template>
79
+
80
+ <JnTable :data="tableData" @expand-change="handleExpandChange">
81
+ <el-table-column prop="dictName" label="字典名" />
82
+ <el-table-column prop="describe" label="说明" />
83
+ <el-table-column type="expand" fixed="right" label="字典值" width="100">
84
+ <template #default="scope">
85
+ <div class="table_expand">
86
+ <div class="table_expand_top">
87
+ <h5>字典值列表</h5>
88
+ </div>
89
+ <el-table :data="scope.row.options" :border="true" size="small" row-key="value">
90
+ <el-table-column label="value" prop="value" width="100" align="center"></el-table-column>
91
+ <el-table-column label="label" prop="label">
92
+ <template #default="optionScope">
93
+ <el-input
94
+ v-model="optionScope.row.label"
95
+ maxlength="20"
96
+ :disabled="!hasPermission(PERMISSION_EDIT)"
97
+ />
98
+ </template>
99
+ </el-table-column>
100
+ <el-table-column label="颜色" prop="displayColor">
101
+ <template #default="optionScope">
102
+ <el-color-picker
103
+ v-model="optionScope.row.displayColor"
104
+ :predefine="predefineColors"
105
+ :disabled="!hasPermission(PERMISSION_EDIT)"
106
+ />
107
+ <span style="margin-left: 10px">
108
+ {{ optionScope.row.displayColor || '无' }}
109
+ </span>
110
+ </template>
111
+ </el-table-column>
112
+ <el-table-column prop="sequence" label="排序" width="180" align="center">
113
+ <template #default="optionScope">
114
+ <el-input-number
115
+ v-model="optionScope.row.sequence"
116
+ :min="1"
117
+ :max="999"
118
+ :step="1"
119
+ controls-position="right"
120
+ step-strictly
121
+ :disabled="!hasPermission(PERMISSION_EDIT)"
122
+ style="width: 140px"
123
+ />
124
+ </template>
125
+ </el-table-column>
126
+ <el-table-column label="操作" width="100" align="center" fixed="right" v-permissions="PERMISSION_EDIT">
127
+ <template #default="optionScope">
128
+ <el-button type="success" size="small" @click="editKeyValue(optionScope.row)">确认修改</el-button>
129
+ </template>
130
+ </el-table-column>
131
+ </el-table>
132
+ </div>
133
+ </template>
134
+ </el-table-column>
135
+ </JnTable>
136
+ </el-card>
137
+ </template>
138
+
139
+ <style scoped lang="scss">
140
+ .table_expand {
141
+ padding: 10px;
142
+ color: var(--jnrs-font-primary);
143
+ background: var(--jnrs-background-primary);
144
+
145
+ .table_expand_top {
146
+ position: relative;
147
+
148
+ h5 {
149
+ font-size: 14px;
150
+ margin-bottom: 10px;
151
+ }
152
+
153
+ .table_expand_top_btn {
154
+ position: absolute;
155
+ right: 0;
156
+ top: 0;
157
+ z-index: 1;
158
+ }
159
+ }
160
+ }
161
+ </style>
@@ -0,0 +1,43 @@
1
+ <script setup lang="ts">
2
+ import { ref } from 'vue'
3
+ import { useMenuStore } from '@jnrs/vue-core/pinia'
4
+ import { JnTable } from '@jnrs/vue-core/components'
5
+
6
+ const loading = ref(false)
7
+
8
+ const { menus } = useMenuStore()
9
+ </script>
10
+
11
+ <template>
12
+ <el-card v-loading="loading">
13
+ <template #header>
14
+ <span>菜单管理</span>
15
+ </template>
16
+
17
+ <JnTable :data="menus" row-key="meta.uuid" :showScrollbar="true">
18
+ <el-table-column prop="meta.title" label="标题" min-width="120" header-align="center" />
19
+ <el-table-column prop="icon" label="图标" width="60" align="center">
20
+ <template #default="{ row }">
21
+ <el-icon v-if="row.meta.icon"><component :is="row.meta.icon" /></el-icon>
22
+ </template>
23
+ </el-table-column>
24
+ <el-table-column prop="path" label="path" min-width="120" header-align="center" />
25
+ <el-table-column prop="name" label="name" min-width="120" header-align="center" />
26
+ <el-table-column prop="component" label="component" min-width="120" header-align="center" />
27
+ <el-table-column prop="redirect" label="redirect" min-width="120" header-align="center" />
28
+ <el-table-column prop="meta.permissions" label="permissions" min-width="120" header-align="center">
29
+ <template #default="{ row }">
30
+ <span>{{ row.meta.permissions }}</span>
31
+ </template>
32
+ </el-table-column>
33
+ <el-table-column prop="type" label="类型" width="80" align="center">
34
+ <template #default="{ row }">
35
+ <el-tag type="primary" v-if="row.path">菜单</el-tag>
36
+ <el-tag type="success" v-else>目录</el-tag>
37
+ </template>
38
+ </el-table-column>
39
+ <el-table-column prop="meta.noAuth" label="meta.noAuth" width="80" align="center" />
40
+ <el-table-column prop="meta.global" label="meta.global" width="80" align="center" />
41
+ </JnTable>
42
+ </el-card>
43
+ </template>
@@ -0,0 +1,108 @@
1
+ <script setup lang="ts">
2
+ import type { FormInstance } from 'element-plus'
3
+ import { ref, onMounted } from 'vue'
4
+ import { useAuthStore } from '@jnrs/vue-core/pinia'
5
+ import { getDictList } from '@/utils/packages'
6
+ import { JnFileUpload } from '@jnrs/vue-core/components'
7
+ import { AvatarChangeApi } from '@/api/system'
8
+ import { objectMatchAssign } from '@jnrs/shared'
9
+
10
+ const { userInfo } = useAuthStore()
11
+ // const loading = ref(false)
12
+ const ruleFormRef = ref<FormInstance>()
13
+ const ruleForm = ref({
14
+ id: 0,
15
+ account: '',
16
+ name: '',
17
+ workNo: '',
18
+ jobTitle: 0,
19
+ workgroup: '',
20
+ role: 0,
21
+ avatarFileName: '',
22
+ file: []
23
+ })
24
+ const rules = ref({
25
+ // account: { required: true, message: '请输入', trigger: 'change' },
26
+ // role: { required: true, message: '请输入', trigger: 'change' },
27
+ // name: { required: true, message: '请输入', trigger: 'change' },
28
+ // workNo: { required: true, message: '请输入', trigger: 'change' },
29
+ })
30
+
31
+ onMounted(() => {
32
+ const matched = objectMatchAssign(ruleForm.value, userInfo)
33
+ ruleForm.value = matched
34
+ })
35
+ </script>
36
+
37
+ <template>
38
+ <el-form ref="ruleFormRef" :model="ruleForm" :rules="rules" label-width="auto" :disabled="true">
39
+ <el-form-item label="登录账号" prop="account">
40
+ <el-input v-model.trim="ruleForm.account" style="width: 200px" />
41
+ </el-form-item>
42
+ <el-form-item label="名称" prop="name">
43
+ <el-input v-model.trim="ruleForm.name" style="width: 200px" />
44
+ </el-form-item>
45
+ <el-form-item label="工号" prop="workNo">
46
+ <el-input v-model.trim="ruleForm.workNo" style="width: 200px" />
47
+ </el-form-item>
48
+ <el-form-item label="职称" prop="jobTitle">
49
+ <el-select v-model="ruleForm.jobTitle" placeholder="" style="width: 200px">
50
+ <el-option
51
+ :label="item.label"
52
+ :value="item.value"
53
+ v-for="(item, index) in getDictList('jobTitle')"
54
+ :key="index"
55
+ />
56
+ </el-select>
57
+ </el-form-item>
58
+ <el-form-item label="部门/班组" prop="workgroup">
59
+ <el-input v-model.trim="ruleForm.workgroup" style="width: 200px" />
60
+ </el-form-item>
61
+ <el-form-item label="职位/账号权限" prop="role">
62
+ <el-select v-model="ruleForm.role" placeholder="" style="width: 200px">
63
+ <el-option :label="item.label" :value="item.value" v-for="(item, index) in getDictList('role')" :key="index" />
64
+ </el-select>
65
+ </el-form-item>
66
+ <el-form-item label="头像" prop="file" class="uploader_item">
67
+ <JnFileUpload
68
+ v-model="ruleForm.file"
69
+ :formRef="ruleFormRef"
70
+ validateFieldName="newImageFiles"
71
+ accept=".png,.jpg,.bmp,.gif"
72
+ :fileSizeMb="50"
73
+ :limit="1"
74
+ :showFileList="false"
75
+ :autoUploadApi="AvatarChangeApi"
76
+ style="width: 500px"
77
+ :disabled="true"
78
+ />
79
+ </el-form-item>
80
+ <!-- <el-form-item>
81
+ <el-button class="form_submit" :loading="loading" type="primary" @click="submitForm">
82
+ 保存修改
83
+ </el-button>
84
+ </el-form-item> -->
85
+ </el-form>
86
+ </template>
87
+
88
+ <style lang="scss" scoped>
89
+ .uploader_item {
90
+ .uploader_avatar {
91
+ width: 100px;
92
+ height: 100px;
93
+ border: 1px solid #ccc;
94
+ border-radius: 50%;
95
+ }
96
+ .uploader_icon {
97
+ width: 100px;
98
+ height: 100px;
99
+ border: 1px solid #ccc;
100
+ border-radius: 50%;
101
+ font-size: 20px;
102
+ color: #bbb;
103
+ }
104
+ }
105
+ .form_submit {
106
+ margin-top: 30px;
107
+ }
108
+ </style>