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,355 @@
1
+ <script setup lang="ts">
2
+ import type { FormInstance, FormRules } from 'element-plus'
3
+ import type { Attachment, Pagination } from '@/types'
4
+ import type { ProjectItem, AddProjectItem } from '@/api/demos/index'
5
+ import { ref, onActivated } from 'vue'
6
+ import { ElMessage } from 'element-plus'
7
+ import { Plus } from '@element-plus/icons-vue'
8
+ import { useRoute } from '@jnrs/vue-core/router'
9
+ import { objectMatchAssign, dateFormatsToObject } from '@jnrs/shared'
10
+ import { debounce } from '@jnrs/shared/lodash'
11
+ import { isNumberGtZero } from '@jnrs/shared/validator'
12
+ import { getDictList, downloadFile } from '@/utils/packages'
13
+ import { TableApi, EditApi, ImportTemplateApi, ImportDataApi, ExportApi } from '@/api/demos/index'
14
+
15
+ import { JnDialog, JnDatetime, JnPagination, JnFileUpload, JnTable, JnImportAndExport } from '@jnrs/vue-core/components'
16
+ import ImageView from '@/components/common/ImageView.vue'
17
+ import PdfView from '@/components/common/PdfView.vue'
18
+ import DictTag from '@/components/common/DictTag.vue'
19
+ import SelectManager from '@/components/select/SelectManager.vue'
20
+
21
+ interface ProcessedProjectItem extends ProjectItem {
22
+ newImageFiles?: Attachment[]
23
+ newAttachmentFile?: Attachment[]
24
+ }
25
+
26
+ const loading = ref(false)
27
+ const tableData = ref<ProcessedProjectItem[]>([])
28
+ const total = ref(0)
29
+ const pagination = ref<Pagination>({ pageNo: 1, pageSize: 20 })
30
+ const route = useRoute()
31
+
32
+ // 编辑
33
+ const editDialogRef = ref()
34
+ const ruleFormRef = ref<FormInstance>()
35
+ const ruleForm = ref<AddProjectItem>({
36
+ id: '',
37
+ name: '',
38
+ projectType: undefined,
39
+ managerId: undefined,
40
+ budget: 0,
41
+ plannedStartDate: '',
42
+ description: '',
43
+ newImageFiles: [],
44
+ newAttachmentFile: []
45
+ })
46
+ const rules = ref<FormRules>({
47
+ name: [{ required: true, message: '请输入', trigger: 'change' }],
48
+ projectType: [{ required: true, message: '请选择', trigger: 'change' }],
49
+ plannedStartDate: [{ required: true, message: '请选择', trigger: 'change' }],
50
+ newImageFiles: [{ required: true, message: '请上传', trigger: 'change' }],
51
+ managerId: [{ required: true, message: '请选择', trigger: 'change' }],
52
+ budget: [
53
+ { required: true, message: '请输入', trigger: 'change' },
54
+ {
55
+ validator: isNumberGtZero,
56
+ trigger: 'change'
57
+ }
58
+ ]
59
+ })
60
+
61
+ // 查询
62
+ const queryForm = ref({
63
+ code: '',
64
+ projectType: undefined,
65
+ manager: '',
66
+ plannedStartDate: ''
67
+ })
68
+
69
+ const handleSelectionChange = (row: ProjectItem[]) => {
70
+ console.log(row)
71
+ }
72
+
73
+ const getTable = debounce(async () => {
74
+ loading.value = true
75
+ try {
76
+ const res = await TableApi({
77
+ ...pagination.value,
78
+ ...queryForm.value
79
+ })
80
+ tableData.value = res.list.map((item) => ({
81
+ ...item,
82
+ newImageFiles: item.imageDocument?.attachments,
83
+ newAttachmentFile: item.attachmentDocument?.attachments
84
+ }))
85
+ total.value = res.count
86
+ } catch (error) {
87
+ console.error(error)
88
+ } finally {
89
+ loading.value = false
90
+ }
91
+ }, 300)
92
+
93
+ // 新增和修改
94
+ const handleEdit = (row?: ProjectItem) => {
95
+ editDialogRef.value.open()
96
+ queueMicrotask(() => {
97
+ ruleFormRef.value?.resetFields()
98
+ const matched = objectMatchAssign(ruleForm.value, row)
99
+ ruleForm.value = matched
100
+ // Select 组件数据回填
101
+ if (row && 'managerId' in row && 'manager' in row) {
102
+ ruleForm.value.managerId = {
103
+ managerId: row.managerId,
104
+ manager: row.manager
105
+ }
106
+ }
107
+ })
108
+ }
109
+
110
+ // 提交表单
111
+ const submitForm = () => {
112
+ ruleFormRef.value?.validate(async (valid) => {
113
+ if (valid) {
114
+ loading.value = true
115
+ try {
116
+ await EditApi(ruleForm.value)
117
+ ElMessage({
118
+ message: '数据已保存',
119
+ grouping: true,
120
+ showClose: true,
121
+ type: 'success'
122
+ })
123
+ } catch (err) {
124
+ console.error(err)
125
+ } finally {
126
+ loading.value = false
127
+ }
128
+ }
129
+ })
130
+ }
131
+
132
+ onActivated(() => {
133
+ console.log(route.meta)
134
+ getTable()
135
+ })
136
+ </script>
137
+
138
+ <template>
139
+ <!-- 编辑弹窗 -->
140
+ <JnDialog ref="editDialogRef" title="项目管理" width="600px">
141
+ <el-form ref="ruleFormRef" :model="ruleForm" :rules="rules" label-width="auto" v-loading="loading">
142
+ <el-form-item prop="id"></el-form-item>
143
+ <el-form-item label="项目名称" prop="name">
144
+ <el-input v-model.trim="ruleForm.name" maxlength="20" show-word-limit />
145
+ </el-form-item>
146
+ <el-form-item label="类型" prop="projectType">
147
+ <el-select v-model="ruleForm.projectType" filterable placeholder="">
148
+ <el-option
149
+ :label="item.label"
150
+ :value="item.value"
151
+ v-for="item in getDictList('projectType')"
152
+ :key="item.value"
153
+ />
154
+ </el-select>
155
+ </el-form-item>
156
+ <el-form-item label="项目经理" prop="managerId">
157
+ <SelectManager
158
+ v-model="ruleForm.managerId"
159
+ :formRef="ruleFormRef"
160
+ validateFieldName="managerId"
161
+ :simpleValue="false"
162
+ ></SelectManager>
163
+ </el-form-item>
164
+ <el-form-item label="预算" prop="budget">
165
+ <el-input-number v-model="ruleForm.budget" :min="0" :precision="2" :step="10000" controls-position="right">
166
+ <template #prefix>
167
+ <span>¥</span>
168
+ </template>
169
+ </el-input-number>
170
+ </el-form-item>
171
+ <el-form-item label="计划开始时间" prop="plannedStartDate">
172
+ <el-date-picker
173
+ v-model="ruleForm.plannedStartDate"
174
+ type="datetime"
175
+ format="YYYY-MM-DD HH:mm:ss"
176
+ value-format="YYYY-MM-DD HH:mm:ss"
177
+ :disabled-date="
178
+ (time: number) => {
179
+ return time < Date.now() - 86400000
180
+ }
181
+ "
182
+ />
183
+ </el-form-item>
184
+ <el-form-item label="描述" prop="description">
185
+ <el-input
186
+ v-model="ruleForm.description"
187
+ :autosize="{ minRows: 2, maxRows: 4 }"
188
+ type="textarea"
189
+ maxlength="200"
190
+ show-word-limit
191
+ />
192
+ </el-form-item>
193
+ <el-form-item label="上传图片" prop="newImageFiles">
194
+ <JnFileUpload
195
+ v-model="ruleForm.newImageFiles"
196
+ :formRef="ruleFormRef"
197
+ validateFieldName="newImageFiles"
198
+ accept=".png,.jpg,.bmp,.gif"
199
+ :fileSizeMb="50"
200
+ :limit="3"
201
+ drag
202
+ :downloadFileFn="(file) => downloadFile(file.uniqueFileName, file.fileName)"
203
+ />
204
+ </el-form-item>
205
+ <el-form-item label="上传文件" prop="newAttachmentFile">
206
+ <JnFileUpload v-model="ruleForm.newAttachmentFile" accept=".pdf" :limit="1" />
207
+ </el-form-item>
208
+ </el-form>
209
+ <template #footer>
210
+ <el-button type="success" icon="Select" :loading="loading" @click="submitForm()">提交</el-button>
211
+ </template>
212
+ </JnDialog>
213
+
214
+ <el-card v-loading="loading">
215
+ <template #header>
216
+ <div style="display: flex; justify-content: space-between; align-items: center">
217
+ <span>项目管理</span>
218
+ <div style="display: flex; justify-content: space-between; align-items: center">
219
+ <JnImportAndExport
220
+ :importTemplateApi="ImportTemplateApi"
221
+ importBtnName="导入项目"
222
+ :importApi="ImportDataApi"
223
+ exportBtnName="导出项目"
224
+ :exportApi="ExportApi"
225
+ :exportParams="{
226
+ ...dateFormatsToObject(queryForm.plannedStartDate)
227
+ }"
228
+ :exportDynamicParamsConfig="{
229
+ label: '项目编号',
230
+ prop: 'code'
231
+ }"
232
+ :exportDisabled="tableData.length === 0"
233
+ size="small"
234
+ @change="getTable()"
235
+ />
236
+ <el-button type="primary" size="small" :icon="Plus" @click="handleEdit()" style="margin-left: 12px">
237
+ 新增
238
+ </el-button>
239
+ </div>
240
+ </div>
241
+ </template>
242
+
243
+ <!-- 查询条件 -->
244
+ <el-form :model="queryForm" size="small" inline v-loading="loading">
245
+ <el-form-item label="项目编号" prop="code">
246
+ <el-input v-model="queryForm.code" clearable style="width: 200px">
247
+ <template #append>
248
+ <el-button icon="Search" @click="getTable()" />
249
+ </template>
250
+ </el-input>
251
+ </el-form-item>
252
+ <el-form-item label="项目名称" prop="projectType">
253
+ <el-select
254
+ v-model="queryForm.projectType"
255
+ filterable
256
+ placeholder=""
257
+ clearable
258
+ style="width: 200px"
259
+ @change="getTable()"
260
+ >
261
+ <el-option
262
+ :label="item.label"
263
+ :value="item.value"
264
+ v-for="item in getDictList('projectType')"
265
+ :key="item.value"
266
+ />
267
+ </el-select>
268
+ </el-form-item>
269
+ <el-form-item label="项目经理" prop="manager">
270
+ <SelectManager
271
+ v-model="queryForm.manager"
272
+ :initialParams="{ role: 1 }"
273
+ size="small"
274
+ width="200px"
275
+ @change="getTable()"
276
+ ></SelectManager>
277
+ </el-form-item>
278
+ <el-form-item label="计划开始时间" prop="plannedStartDate">
279
+ <el-date-picker
280
+ v-model="queryForm.plannedStartDate"
281
+ value-format="YYYY-MM-DD"
282
+ size="small"
283
+ style="width: 200px"
284
+ @change="getTable()"
285
+ />
286
+ </el-form-item>
287
+ </el-form>
288
+
289
+ <!-- 数据列表 -->
290
+ <JnTable
291
+ :data="tableData"
292
+ :pagination="pagination"
293
+ :autoHeight="true"
294
+ :showScrollbar="true"
295
+ :showIndexColumn="true"
296
+ :showSelectionColumn="true"
297
+ :showMouseSelection="true"
298
+ @selection-change="handleSelectionChange"
299
+ >
300
+ <el-table-column prop="code" label="项目编号" min-width="200" sortable show-overflow-tooltip />
301
+ <el-table-column prop="name" label="项目名称" min-width="200" sortable show-overflow-tooltip />
302
+ <el-table-column prop="program" label="项目集名称" min-width="200" sortable show-overflow-tooltip />
303
+ <el-table-column prop="projectType" label="项目类型" width="100" align="center" sortable>
304
+ <template #default="{ row }">
305
+ <DictTag dictName="projectType" :value="row.projectType" />
306
+ </template>
307
+ </el-table-column>
308
+ <el-table-column prop="manager" label="项目经理" width="100" align="center" sortable />
309
+ <el-table-column prop="budget" label="预算(¥)" width="100" align="center" sortable>
310
+ <template #default="{ row }">
311
+ {{ row.budget }}
312
+ </template>
313
+ </el-table-column>
314
+ <el-table-column prop="plannedStartDate" label="计划开始时间" width="130" align="center" sortable>
315
+ <template #default="{ row }">
316
+ <JnDatetime :value="row.plannedStartDate" />
317
+ </template>
318
+ </el-table-column>
319
+ <el-table-column prop="plannedFinishDate" label="计划完成日期" width="130" align="center" sortable>
320
+ <template #default="{ row }">
321
+ {{ row.plannedFinishDate }}
322
+ </template>
323
+ </el-table-column>
324
+ <el-table-column prop="progress" label="进度" width="100" align="center" sortable>
325
+ <template #default="{ row }">
326
+ <span>{{ row.progress }}</span>
327
+ </template>
328
+ </el-table-column>
329
+ <el-table-column prop="status" label="状态" width="100" align="center" sortable>
330
+ <template #default="{ row }">
331
+ <DictTag dictName="status" :value="row.status" :showColor="false" />
332
+ </template>
333
+ </el-table-column>
334
+ <el-table-column prop="description" label="描述" min-width="200" show-overflow-tooltip />
335
+ <el-table-column prop="imageDocument" label="图片" width="100" align="center" sortable>
336
+ <template #default="{ row }">
337
+ <ImageView :loadKeys="row.newImageFiles" preview maxHeight="50px" />
338
+ </template>
339
+ </el-table-column>
340
+ <el-table-column prop="attachmentDocument" label="附件" width="100" align="center" sortable>
341
+ <template #default="{ row }">
342
+ <PdfView :loadKeys="row.newAttachmentFile" isPdf />
343
+ </template>
344
+ </el-table-column>
345
+ <el-table-column label="操作" width="100" align="center" fixed="right">
346
+ <template #default="{ row }">
347
+ <el-button link type="primary" @click.stop="handleEdit(row)">编辑</el-button>
348
+ </template>
349
+ </el-table-column>
350
+ </JnTable>
351
+
352
+ <!-- 表格分页 -->
353
+ <JnPagination :total="total" v-model="pagination" @change="getTable" />
354
+ </el-card>
355
+ </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>
@@ -0,0 +1,137 @@
1
+ <script setup lang="ts">
2
+ import { ref } from 'vue'
3
+ import { ElMessage } from 'element-plus'
4
+ import { objectToFormData } from '@/utils/packages'
5
+ import { LoginApi, UserInfoApi } from '@/api/system'
6
+ import { NotFoundApi, NoAuthApi, DetailsApi } from '@/api/demos'
7
+ import { getFileUrl } from '@/utils/file'
8
+ import { downloadFile } from '@/utils/packages'
9
+
10
+ import ImageView from '@/components/common/ImageView.vue'
11
+
12
+ const squareUrl = ref()
13
+
14
+ const loginParams = ref({
15
+ account: 'user',
16
+ password: '123456'
17
+ })
18
+
19
+ const handleInfoApi = async () => {
20
+ try {
21
+ const res = await UserInfoApi()
22
+ console.log(res)
23
+ } catch (error) {
24
+ console.log(error)
25
+ }
26
+ }
27
+
28
+ const handleNotFoundApi = async () => {
29
+ try {
30
+ const res = await NotFoundApi()
31
+ console.log(res)
32
+ } catch (error) {
33
+ console.log(error)
34
+ }
35
+ }
36
+
37
+ const handleNoAuth = async (showErrorMsg = true) => {
38
+ try {
39
+ const res = await NoAuthApi(showErrorMsg)
40
+ console.log(res)
41
+ } catch (error) {
42
+ console.log(error)
43
+ }
44
+ }
45
+
46
+ // 验证登录接口
47
+ const handleLogin = async () => {
48
+ try {
49
+ const res = await LoginApi(loginParams.value)
50
+ ElMessage.success('登录成功')
51
+ console.log(res)
52
+ } catch (error) {
53
+ console.log(error)
54
+ }
55
+ }
56
+
57
+ // 获取数据列表单个数据
58
+ const handleDetailsApi = async () => {
59
+ try {
60
+ const res = await DetailsApi()
61
+ let formatData: Record<string, unknown> = {}
62
+ formatData = {
63
+ ...res
64
+ }
65
+ if (res.attachmentDocument?.attachments) {
66
+ formatData.newAttachmentFile = res.attachmentDocument.attachments
67
+ }
68
+ if (res.imageDocument?.attachments) {
69
+ formatData.newImageFiles = res.imageDocument.attachments
70
+ }
71
+ console.log(formatData)
72
+ const formData = objectToFormData(formatData)
73
+ console.log(formData)
74
+ for (const [key, value] of formData.entries()) {
75
+ console.log(key, value)
76
+ }
77
+ } catch (error) {
78
+ console.log(error)
79
+ }
80
+ }
81
+
82
+ // 获取后端服务器文件进行预览
83
+ const handleFileView = async () => {
84
+ try {
85
+ const url = await getFileUrl('mock-png-1.png')
86
+ squareUrl.value = url.value
87
+ } catch (error) {
88
+ console.log(error)
89
+ }
90
+ }
91
+ </script>
92
+
93
+ <template>
94
+ <p>网络请求测试</p>
95
+ <el-button-group>
96
+ <el-button type="success" size="small" @click="handleInfoApi">获取用户数据</el-button>
97
+ <el-button type="primary" size="small" @click="handleNotFoundApi">接口返回404</el-button>
98
+ <el-button type="primary" size="small" @click="handleNoAuth()">接口返回暂无权限</el-button>
99
+ <el-button type="primary" size="small" @click="handleNoAuth(false)">接口返回暂无权限(不显示 Message)</el-button>
100
+ </el-button-group>
101
+ <el-input v-model="loginParams.account" size="small" style="width: 200px">
102
+ <template #append>
103
+ <el-button size="small" @click="handleLogin">验证登录接口</el-button>
104
+ </template>
105
+ </el-input>
106
+ <div>
107
+ <el-button-group>
108
+ <el-button type="primary" plain size="small" @click="handleDetailsApi">获取数据列表单个数据</el-button>
109
+ <el-button type="primary" plain size="small" @click="downloadFile('mock-pdf.pdf')">
110
+ 获取后端服务器文件进行下载
111
+ </el-button>
112
+ </el-button-group>
113
+ <div>
114
+ <span>通过 ImageView 组件显示的图片(可支持预览)</span>
115
+ <ImageView
116
+ loadKeys="mock-png-1.png"
117
+ preview
118
+ style="width: 300px; height: 50px; border: 1px solid var(--jnrs-color-primary)"
119
+ />
120
+ </div>
121
+ <div>
122
+ <el-button type="primary" plain size="small" @click="handleFileView">获取后端服务器图片</el-button>
123
+ <el-avatar shape="circle" :src="squareUrl" />
124
+ </div>
125
+ </div>
126
+ </template>
127
+
128
+ <style scoped lang="scss">
129
+ h3 {
130
+ color: var(--jnrs-color-primary);
131
+ }
132
+ p {
133
+ margin: 24px 0 8px;
134
+ color: var(--jnrs-background-primary);
135
+ background: var(--jnrs-font-primary);
136
+ }
137
+ </style>
@@ -0,0 +1,131 @@
1
+ <script setup lang="ts">
2
+ import RequestPage from './RequestPage.vue'
3
+ import { ref, onMounted } from 'vue'
4
+ import { handleRouter } from '@jnrs/vue-core/router'
5
+ import type { MenuItem } from '@jnrs/vue-core'
6
+ import { hasPermission } from '@/utils/permissions'
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'
11
+
12
+ const routeOptions = ref<MenuItem[]>([])
13
+ const currentRoute = ref('')
14
+ const datePicker = ref(new Date())
15
+ const datetime = ref(formatDateTime() + ' ' + formatWeekday())
16
+ const validator = ref()
17
+ const testI18nInCore = ref('')
18
+
19
+ const handleMenuApi = async () => {
20
+ try {
21
+ const res = await MenuApi()
22
+ routeOptions.value = res
23
+ } catch (error) {
24
+ console.log(error)
25
+ }
26
+ }
27
+
28
+ const handleRouteChange = () => {
29
+ handleRouter({
30
+ name: currentRoute.value
31
+ })
32
+ }
33
+
34
+ const handleRouterSystemMine = () => {
35
+ handleRouter({
36
+ name: 'SystemMine',
37
+ query: {
38
+ id: 1
39
+ }
40
+ })
41
+ // handleRouter({
42
+ // path: '/system/mine/index',
43
+ // query: {
44
+ // id: 1
45
+ // }
46
+ // })
47
+ }
48
+
49
+ const changeI18n = () => {
50
+ datetime.value = formatDateTime() + ' ' + formatWeekday()
51
+ isFloatGtZero({}, '0', (msg) => {
52
+ validator.value = msg
53
+ })
54
+ testI18nInCore.value = testI18n()
55
+ }
56
+
57
+ onMounted(() => {
58
+ isFloatGtZero({}, '0', (msg) => {
59
+ validator.value = msg
60
+ })
61
+ testI18nInCore.value = testI18n()
62
+ })
63
+ </script>
64
+
65
+ <template>
66
+ <div>
67
+ <h3>Playground - 功能测试</h3>
68
+ <p>国际化测试</p>
69
+ <div>@jnrs/shared: {{ datetime }}</div>
70
+ <div>@jnrs/shared/validator: {{ validator }}</div>
71
+ <div>@jnrs/shared/request: {{ testI18nInCore }}</div>
72
+ <el-button type="primary" size="small" @click="changeI18n">切换语言后点击按钮更新国际化显示</el-button>
73
+ <p>权限测试(admin 账号拥有全部权限,请用非 admin 账号测试该功能)</p>
74
+ <ul>
75
+ <li>
76
+ <span>有权限:(期望:正常显示按钮)</span>
77
+ <el-button type="primary" size="small" v-permissions="['mine:view']">添加</el-button>
78
+ </li>
79
+ <li>
80
+ <span>无权限:(期望:按钮禁用 -> UI 组件:使用 UI 框架提供的禁用属性)</span>
81
+ <el-button type="primary" size="small" :disabled="!hasPermission(['test:del'])">删除</el-button>
82
+ </li>
83
+ <li>
84
+ <span>无权限:(期望:按钮禁用 -> 原生元素:添加 disabled 属性和类名)</span>
85
+ <button size="small" v-permissions.disabled="['test:del']">删除</button>
86
+ </li>
87
+ <li>
88
+ <span>无权限:(期望:按钮不可见 -> 添加样式 display:none)</span>
89
+ <button size="small" v-permissions.display="['test:del']">删除</button>
90
+ </li>
91
+ <li>
92
+ <span>无权限:(期望:按钮不可见 -> remove HTMLElement)</span>
93
+ <button size="small" v-permissions="['test:del']">删除</button>
94
+ </li>
95
+ </ul>
96
+ <RequestPage />
97
+ <p>完整路由测试(先点击按钮,获取完整菜单数据)</p>
98
+ <el-button type="success" plain size="small" @click="handleRouterSystemMine">跳转到个人中心</el-button>
99
+ <el-button type="success" plain size="small" @click="handleMenuApi">获取完整菜单数据</el-button>
100
+ <el-cascader
101
+ v-model="currentRoute"
102
+ :options="routeOptions"
103
+ :props="{
104
+ emitPath: false,
105
+ value: 'name',
106
+ label: 'name'
107
+ }"
108
+ size="small"
109
+ :show-all-levels="false"
110
+ @change="handleRouteChange"
111
+ >
112
+ <template #default="{ data }">
113
+ <span>{{ data.meta.title }}</span>
114
+ </template>
115
+ </el-cascader>
116
+ <p>Element 组件测试</p>
117
+ <el-date-picker-panel v-model="datePicker" />
118
+ </div>
119
+ <router-view></router-view>
120
+ </template>
121
+
122
+ <style scoped lang="scss">
123
+ h3 {
124
+ color: var(--jnrs-color-primary);
125
+ }
126
+ p {
127
+ margin: 24px 0 8px;
128
+ color: var(--jnrs-background-primary);
129
+ background: var(--jnrs-font-primary);
130
+ }
131
+ </style>
@@ -0,0 +1,9 @@
1
+ <script setup lang="ts">
2
+ import { ref } from 'vue'
3
+ </script>
4
+
5
+ <template>
6
+ <div>欢迎使用</div>
7
+ </template>
8
+
9
+ <style lang="scss" scoped></style>
@@ -0,0 +1,9 @@
1
+ <script setup lang="ts">
2
+ import { LingshuSmartEditor } from '@jnrs/lingshu-smart/components'
3
+ </script>
4
+
5
+ <template>
6
+ <LingshuSmartEditor />
7
+ </template>
8
+
9
+ <style lang="scss" scoped></style>