create-jnrs-template-vue 1.2.1 → 1.2.3
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/bin/create.mjs +3 -3
- package/jnrs-template-vue/auto-imports.d.ts +4 -0
- package/jnrs-template-vue/components.d.ts +0 -1
- package/jnrs-template-vue/package.json +3 -4
- package/jnrs-template-vue/public/system/menu.json +1 -1
- package/jnrs-template-vue/src/App.vue +1 -3
- package/jnrs-template-vue/src/api/common/index.ts +2 -2
- package/jnrs-template-vue/src/api/demos/index.ts +84 -48
- package/jnrs-template-vue/src/api/system/index.ts +10 -10
- package/jnrs-template-vue/src/api/user/index.ts +2 -2
- package/jnrs-template-vue/src/assets/styles/animation.scss +0 -0
- package/jnrs-template-vue/src/assets/styles/common.scss +4 -0
- package/jnrs-template-vue/src/assets/styles/fonts.scss +4 -1
- package/jnrs-template-vue/src/assets/styles/{main.scss → index.scss} +1 -0
- package/jnrs-template-vue/src/assets/styles/init.scss +4 -13
- package/jnrs-template-vue/src/assets/styles/root.scss +0 -3
- package/jnrs-template-vue/src/components/common/{JnDictTag.vue → DictTag.vue} +1 -1
- package/jnrs-template-vue/src/components/{base → common}/PdfView.vue +2 -2
- package/jnrs-template-vue/src/components/select/SelectManager.vue +20 -0
- package/jnrs-template-vue/src/composables/common/usePagination.ts +4 -4
- package/jnrs-template-vue/src/composables/common/useTable.ts +4 -4
- package/jnrs-template-vue/src/composables/tools/useMouseSelection.ts +150 -0
- package/jnrs-template-vue/src/layout/SideMenu.vue +1 -0
- package/jnrs-template-vue/src/layout/TopHeader.vue +1 -1
- package/jnrs-template-vue/src/locales/en.ts +1 -1
- package/jnrs-template-vue/src/locales/index.ts +1 -1
- package/jnrs-template-vue/src/main.ts +1 -1
- package/jnrs-template-vue/src/types/index.ts +45 -3
- package/jnrs-template-vue/src/views/demos/crud/index.vue +140 -40
- package/jnrs-template-vue/src/views/demos/unitTest/RequestPage.vue +1 -1
- package/jnrs-template-vue/src/views/demos/unitTest/index.vue +26 -2
- package/jnrs-template-vue/src/views/login/index.vue +7 -2
- package/jnrs-template-vue/src/views/system/dict/index.vue +2 -2
- package/jnrs-template-vue/src/views/system/menu/index.vue +2 -2
- package/jnrs-template-vue/src/views/system/mine/baseInfo.vue +1 -1
- package/jnrs-template-vue/tsconfig.json +1 -9
- package/jnrs-template-vue/vite.config.ts +1 -3
- package/jnrs-template-vue/viteMockServe/fail.ts +12 -0
- package/jnrs-template-vue/viteMockServe/file.ts +2 -3
- package/jnrs-template-vue/viteMockServe/json/tableRes.json +384 -342
- package/package.json +1 -1
- package/jnrs-template-vue/src/assets/images/fileIcon/iconArchive.png +0 -0
- package/jnrs-template-vue/src/assets/images/fileIcon/iconAudio.png +0 -0
- package/jnrs-template-vue/src/assets/images/fileIcon/iconCode.png +0 -0
- package/jnrs-template-vue/src/assets/images/fileIcon/iconExcel.png +0 -0
- package/jnrs-template-vue/src/assets/images/fileIcon/iconFile.png +0 -0
- package/jnrs-template-vue/src/assets/images/fileIcon/iconFlash.png +0 -0
- package/jnrs-template-vue/src/assets/images/fileIcon/iconGif.png +0 -0
- package/jnrs-template-vue/src/assets/images/fileIcon/iconImage.png +0 -0
- package/jnrs-template-vue/src/assets/images/fileIcon/iconMac.png +0 -0
- package/jnrs-template-vue/src/assets/images/fileIcon/iconOfd.png +0 -0
- package/jnrs-template-vue/src/assets/images/fileIcon/iconPdf.png +0 -0
- package/jnrs-template-vue/src/assets/images/fileIcon/iconPpt.png +0 -0
- package/jnrs-template-vue/src/assets/images/fileIcon/iconText.png +0 -0
- package/jnrs-template-vue/src/assets/images/fileIcon/iconUnknown.png +0 -0
- package/jnrs-template-vue/src/assets/images/fileIcon/iconVideo.png +0 -0
- package/jnrs-template-vue/src/assets/images/fileIcon/iconWindows.png +0 -0
- package/jnrs-template-vue/src/assets/images/fileIcon/iconWord.png +0 -0
- package/jnrs-template-vue/src/assets/images/fileIcon/iconWps.png +0 -0
- package/jnrs-template-vue/src/components/base/JnFileUpload.vue +0 -433
- package/jnrs-template-vue/src/components/common/JnDatetime.vue +0 -37
- package/jnrs-template-vue/src/components/common/JnEdit.vue +0 -68
- package/jnrs-template-vue/src/components/common/JnPagination.vue +0 -83
- package/jnrs-template-vue/src/components/common/JnTable.vue +0 -133
- package/jnrs-template-vue/src/composables/tools/useReactivityTableHeight.ts +0 -63
- /package/jnrs-template-vue/src/components/{base → common}/ImageView.vue +0 -0
- /package/jnrs-template-vue/viteMockServe/{fileSrc → file}/mock-pdf.pdf +0 -0
- /package/jnrs-template-vue/viteMockServe/{fileSrc → file}/mock-png-0.png +0 -0
- /package/jnrs-template-vue/viteMockServe/{fileSrc → file}/mock-png-1.png +0 -0
package/package.json
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,433 +0,0 @@
|
|
|
1
|
-
<!--
|
|
2
|
-
@Author : TanRui
|
|
3
|
-
@WeChat : Tan578853789
|
|
4
|
-
@File : JnFileUpload.vue
|
|
5
|
-
@Date : 2025/12/25
|
|
6
|
-
@Desc. : 通用上传 & 回显组件 上传类型为File类型 二进制
|
|
7
|
-
-->
|
|
8
|
-
|
|
9
|
-
<script setup lang="ts">
|
|
10
|
-
import type { UploadRawFile, UploadFile, FormInstance } from 'element-plus'
|
|
11
|
-
import type { Attachment } from '@/types'
|
|
12
|
-
import { ElMessage } from 'element-plus'
|
|
13
|
-
import { ref, computed, nextTick } from 'vue'
|
|
14
|
-
import { downloadFile } from '@/utils/packages'
|
|
15
|
-
import iconUnknown from '@/assets/images/fileIcon/iconUnknown.png'
|
|
16
|
-
import iconCode from '@/assets/images/fileIcon/iconCode.png'
|
|
17
|
-
import iconWord from '@/assets/images/fileIcon/iconWord.png'
|
|
18
|
-
import iconWps from '@/assets/images/fileIcon/iconWps.png'
|
|
19
|
-
import iconText from '@/assets/images/fileIcon/iconText.png'
|
|
20
|
-
import iconPpt from '@/assets/images/fileIcon/iconPpt.png'
|
|
21
|
-
import iconPdf from '@/assets/images/fileIcon/iconPdf.png'
|
|
22
|
-
import iconArchive from '@/assets/images/fileIcon/iconArchive.png'
|
|
23
|
-
import iconWindows from '@/assets/images/fileIcon/iconWindows.png'
|
|
24
|
-
import iconMac from '@/assets/images/fileIcon/iconMac.png'
|
|
25
|
-
import iconVideo from '@/assets/images/fileIcon/iconVideo.png'
|
|
26
|
-
import iconAudio from '@/assets/images/fileIcon/iconAudio.png'
|
|
27
|
-
import iconFlash from '@/assets/images/fileIcon/iconFlash.png'
|
|
28
|
-
import iconGif from '@/assets/images/fileIcon/iconGif.png'
|
|
29
|
-
import iconImage from '@/assets/images/fileIcon/iconImage.png'
|
|
30
|
-
import iconFile from '@/assets/images/fileIcon/iconFile.png'
|
|
31
|
-
import iconExcel from '@/assets/images/fileIcon/iconExcel.png'
|
|
32
|
-
import iconOfd from '@/assets/images/fileIcon/iconOfd.png'
|
|
33
|
-
|
|
34
|
-
type MixedUploadFile = Attachment | UploadRawFile
|
|
35
|
-
|
|
36
|
-
interface Props {
|
|
37
|
-
/**
|
|
38
|
-
* 绑定的模型值(文件列表),默认为空数组
|
|
39
|
-
*/
|
|
40
|
-
modelValue: MixedUploadFile[]
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* 接受的文件类型(如 'image/*'),默认为空字符串
|
|
44
|
-
*/
|
|
45
|
-
accept?: string
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* 是否启用拖拽上传,默认为 false
|
|
49
|
-
*/
|
|
50
|
-
drag?: boolean
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* 单个文件大小限制(单位:MB),默认为 0(不限制)
|
|
54
|
-
*/
|
|
55
|
-
fileSizeMb?: number
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* 最大上传文件数量,0 表示不限制,默认为 0
|
|
59
|
-
*/
|
|
60
|
-
limit?: number
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Element Plus 组件的尺寸,默认为 'small'
|
|
64
|
-
*/
|
|
65
|
-
size?: '' | 'small' | 'default' | 'large'
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* 父级组件的表单引用(用于触发校验),默认为 null
|
|
69
|
-
*/
|
|
70
|
-
formRef?: FormInstance
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* 父级表单中用于校验的字段名(需配合 formRef 使用),默认为空字符串
|
|
74
|
-
*/
|
|
75
|
-
validateFieldName?: string
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
const {
|
|
79
|
-
modelValue,
|
|
80
|
-
accept = '',
|
|
81
|
-
drag = false,
|
|
82
|
-
fileSizeMb = 100,
|
|
83
|
-
limit = 0,
|
|
84
|
-
size = 'small',
|
|
85
|
-
formRef = null,
|
|
86
|
-
validateFieldName = ''
|
|
87
|
-
} = defineProps<Props>()
|
|
88
|
-
|
|
89
|
-
const emit = defineEmits(['update:modelValue'])
|
|
90
|
-
|
|
91
|
-
const loading = ref(false)
|
|
92
|
-
const uploadRef = ref()
|
|
93
|
-
const isDisable = computed(() => {
|
|
94
|
-
return limit && modelValue && modelValue.length >= limit
|
|
95
|
-
})
|
|
96
|
-
|
|
97
|
-
const fileSizeFmt = (value: number) => {
|
|
98
|
-
const units = ['B', 'KB', 'MB', 'GB']
|
|
99
|
-
let size = value
|
|
100
|
-
let unitIndex = 0
|
|
101
|
-
|
|
102
|
-
while (size >= 1024 && unitIndex < units.length - 1) {
|
|
103
|
-
size /= 1024
|
|
104
|
-
unitIndex++
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
const fixedDigits = unitIndex === 0 ? 0 : unitIndex === 1 ? 0 : 1
|
|
108
|
-
return size.toFixed(fixedDigits) + ' ' + units[unitIndex]
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
const getAccessoryIcon = (type: string) => {
|
|
112
|
-
let icon = iconUnknown
|
|
113
|
-
if (type.includes('code')) {
|
|
114
|
-
icon = iconCode
|
|
115
|
-
} else if (type.includes('text')) {
|
|
116
|
-
icon = iconText
|
|
117
|
-
} else if (type.includes('wps')) {
|
|
118
|
-
icon = iconWps
|
|
119
|
-
} else if (type.includes('word')) {
|
|
120
|
-
icon = iconWord
|
|
121
|
-
} else if (type.includes('ppt')) {
|
|
122
|
-
icon = iconPpt
|
|
123
|
-
} else if (type.includes('pdf')) {
|
|
124
|
-
icon = iconPdf
|
|
125
|
-
} else if (type.includes('archive')) {
|
|
126
|
-
icon = iconArchive
|
|
127
|
-
} else if (type.includes('x-msdownload')) {
|
|
128
|
-
icon = iconWindows
|
|
129
|
-
} else if (type.includes('x-apple-aspen-config')) {
|
|
130
|
-
icon = iconMac
|
|
131
|
-
} else if (type.includes('video')) {
|
|
132
|
-
icon = iconVideo
|
|
133
|
-
} else if (type.includes('audio')) {
|
|
134
|
-
icon = iconAudio
|
|
135
|
-
} else if (type.includes('flash')) {
|
|
136
|
-
icon = iconFlash
|
|
137
|
-
} else if (type.includes('gif')) {
|
|
138
|
-
icon = iconGif
|
|
139
|
-
} else if (type.includes('image')) {
|
|
140
|
-
icon = iconImage
|
|
141
|
-
} else if (type.includes('file')) {
|
|
142
|
-
icon = iconFile
|
|
143
|
-
} else if (type.includes('excel')) {
|
|
144
|
-
icon = iconExcel
|
|
145
|
-
} else if (type.includes('ofd')) {
|
|
146
|
-
icon = iconOfd
|
|
147
|
-
}
|
|
148
|
-
return icon
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
const loadingProgress = () => {
|
|
152
|
-
loading.value = true
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
const handleChange = (uploadFile: UploadFile) => {
|
|
156
|
-
const { status, raw } = uploadFile
|
|
157
|
-
|
|
158
|
-
if (status === 'ready' && raw) {
|
|
159
|
-
// 数量校验
|
|
160
|
-
if (limit && modelValue && modelValue.length >= limit) {
|
|
161
|
-
ElMessage({
|
|
162
|
-
message: `最多只能上传 ${limit} 个文件!`,
|
|
163
|
-
type: 'warning',
|
|
164
|
-
grouping: true,
|
|
165
|
-
duration: 3000
|
|
166
|
-
})
|
|
167
|
-
return false
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
// 文件类型校验
|
|
171
|
-
if (accept && accept.split(',').length > 0) {
|
|
172
|
-
let flag = false
|
|
173
|
-
accept.split(',').forEach((element) => {
|
|
174
|
-
if (raw.name.indexOf(element) > -1) {
|
|
175
|
-
flag = true
|
|
176
|
-
}
|
|
177
|
-
})
|
|
178
|
-
if (!flag) {
|
|
179
|
-
ElMessage({
|
|
180
|
-
message: `上传文件只能是 ${accept} 格式!`,
|
|
181
|
-
type: 'warning',
|
|
182
|
-
grouping: true,
|
|
183
|
-
duration: 3000
|
|
184
|
-
})
|
|
185
|
-
return false
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
// 文件大小校验
|
|
190
|
-
if (fileSizeMb && raw.size / 1024 / 1024 > fileSizeMb) {
|
|
191
|
-
ElMessage({
|
|
192
|
-
message: `上传的文件大小不能超过 ${fileSizeMb} MB!`,
|
|
193
|
-
type: 'warning',
|
|
194
|
-
grouping: true,
|
|
195
|
-
duration: 3000
|
|
196
|
-
})
|
|
197
|
-
return false
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
const temp = modelValue
|
|
201
|
-
temp.push(uploadFile.raw as UploadRawFile)
|
|
202
|
-
emit('update:modelValue', temp)
|
|
203
|
-
|
|
204
|
-
nextTick(() => {
|
|
205
|
-
if (formRef && validateFieldName) {
|
|
206
|
-
formRef.validateField(validateFieldName)
|
|
207
|
-
}
|
|
208
|
-
uploadRef.value?.clearFiles()
|
|
209
|
-
loading.value = false
|
|
210
|
-
})
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
const deleteFile = (file: MixedUploadFile) => {
|
|
215
|
-
const temp = modelValue
|
|
216
|
-
const index = modelValue.findIndex((item) => {
|
|
217
|
-
// Attachment 类型
|
|
218
|
-
if ('id' in file && 'id' in item) {
|
|
219
|
-
return item.id === file.id
|
|
220
|
-
}
|
|
221
|
-
// UploadRawFile 类型
|
|
222
|
-
if ('uid' in file && 'uid' in item) {
|
|
223
|
-
return item.uid === file.uid
|
|
224
|
-
}
|
|
225
|
-
})
|
|
226
|
-
|
|
227
|
-
if (index !== -1) {
|
|
228
|
-
temp.splice(index, 1)
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
emit('update:modelValue', temp)
|
|
232
|
-
|
|
233
|
-
nextTick(() => {
|
|
234
|
-
if (formRef && validateFieldName) {
|
|
235
|
-
formRef.validateField(validateFieldName)
|
|
236
|
-
}
|
|
237
|
-
})
|
|
238
|
-
}
|
|
239
|
-
</script>
|
|
240
|
-
|
|
241
|
-
<template>
|
|
242
|
-
<div class="jnFileUpload">
|
|
243
|
-
<el-upload
|
|
244
|
-
ref="uploadRef"
|
|
245
|
-
:http-request="() => {}"
|
|
246
|
-
:show-file-list="false"
|
|
247
|
-
:multiple="true"
|
|
248
|
-
:drag="drag"
|
|
249
|
-
:accept="accept"
|
|
250
|
-
:disabled="isDisable"
|
|
251
|
-
:on-progress="loadingProgress"
|
|
252
|
-
:on-change="handleChange"
|
|
253
|
-
>
|
|
254
|
-
<el-button type="primary" :size="size" :loading="loading" :disabled="isDisable">
|
|
255
|
-
上传
|
|
256
|
-
<span v-if="limit" style="display: inline-block; margin-left: 5px">
|
|
257
|
-
({{ modelValue ? modelValue.length : 0 }}/{{ limit }})
|
|
258
|
-
</span>
|
|
259
|
-
</el-button>
|
|
260
|
-
</el-upload>
|
|
261
|
-
|
|
262
|
-
<div class="uploadTips" :class="{ uploadTips_isDrag: drag }">
|
|
263
|
-
<span v-if="accept">
|
|
264
|
-
文件类型为
|
|
265
|
-
<b>{{ accept }}</b>
|
|
266
|
-
</span>
|
|
267
|
-
<span v-if="accept">
|
|
268
|
-
文件大小为
|
|
269
|
-
<b>{{ fileSizeMb }}MB</b>
|
|
270
|
-
以内
|
|
271
|
-
</span>
|
|
272
|
-
</div>
|
|
273
|
-
|
|
274
|
-
<div class="fileList" v-show="modelValue && modelValue.length > 0" v-loading="loading">
|
|
275
|
-
<div class="fileLis_item" v-for="(item, index) in modelValue" :key="index">
|
|
276
|
-
<!-- Attachment 类型 -->
|
|
277
|
-
<template v-if="'id' in item">
|
|
278
|
-
<div class="fileLis_item_left">
|
|
279
|
-
<span class="fileLis_item_index">{{ index + 1 }}</span>
|
|
280
|
-
<img class="fileLis_item_icon" v-if="item.fileType" :src="getAccessoryIcon(item.fileType)" />
|
|
281
|
-
<span class="fileLis_item_name">{{ item.fileName }}</span>
|
|
282
|
-
<span class="fileLis_item_size">
|
|
283
|
-
{{ fileSizeFmt(item.fileSize) }}
|
|
284
|
-
</span>
|
|
285
|
-
</div>
|
|
286
|
-
<div class="fileLis_item_right">
|
|
287
|
-
<span class="fileLis_item_btn" @click="downloadFile(item.uniqueFileName, item.fileName)">
|
|
288
|
-
<el-icon><Download /></el-icon>
|
|
289
|
-
</span>
|
|
290
|
-
<span class="fileLis_item_btn fileLis_item_btn_danger" @click="deleteFile(item)">
|
|
291
|
-
<el-icon><Delete /></el-icon>
|
|
292
|
-
</span>
|
|
293
|
-
</div>
|
|
294
|
-
</template>
|
|
295
|
-
|
|
296
|
-
<!-- UploadRawFile 类型 -->
|
|
297
|
-
<template v-if="'uid' in item">
|
|
298
|
-
<div class="fileLis_item_left">
|
|
299
|
-
<span class="fileLis_item_index">{{ index + 1 }}</span>
|
|
300
|
-
<img class="fileLis_item_icon" v-if="item.type" :src="getAccessoryIcon(item.type)" />
|
|
301
|
-
<span class="fileLis_item_name">{{ item.name }}</span>
|
|
302
|
-
<span class="fileLis_item_size">
|
|
303
|
-
{{ fileSizeFmt(item.size) }}
|
|
304
|
-
</span>
|
|
305
|
-
</div>
|
|
306
|
-
<div class="fileLis_item_right">
|
|
307
|
-
<span class="fileLis_item_btn fileLis_item_btn_danger" @click="deleteFile(item)">
|
|
308
|
-
<el-icon><Delete /></el-icon>
|
|
309
|
-
</span>
|
|
310
|
-
</div>
|
|
311
|
-
</template>
|
|
312
|
-
</div>
|
|
313
|
-
</div>
|
|
314
|
-
</div>
|
|
315
|
-
</template>
|
|
316
|
-
|
|
317
|
-
<style lang="scss" scoped>
|
|
318
|
-
.jnFileUpload {
|
|
319
|
-
position: relative;
|
|
320
|
-
width: 100%;
|
|
321
|
-
color: var(--jnrs-font-primary-06);
|
|
322
|
-
|
|
323
|
-
:deep(.el-upload-dragger) {
|
|
324
|
-
padding: 30px 0 10px;
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
.uploadTips {
|
|
328
|
-
display: block;
|
|
329
|
-
width: 100%;
|
|
330
|
-
margin-top: 5px;
|
|
331
|
-
line-height: 1.2em;
|
|
332
|
-
span {
|
|
333
|
-
display: inline-block;
|
|
334
|
-
margin-right: 10px;
|
|
335
|
-
}
|
|
336
|
-
b {
|
|
337
|
-
color: var(--el-color-danger, #ff3300);
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
.uploadTips_isDrag {
|
|
342
|
-
position: absolute;
|
|
343
|
-
top: 4px;
|
|
344
|
-
left: 0;
|
|
345
|
-
text-align: center;
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
.fileList {
|
|
349
|
-
width: 100%;
|
|
350
|
-
|
|
351
|
-
.fileLis_item {
|
|
352
|
-
display: flex;
|
|
353
|
-
align-items: center;
|
|
354
|
-
justify-content: space-between;
|
|
355
|
-
width: 100%;
|
|
356
|
-
margin-top: 8px;
|
|
357
|
-
padding: 5px 0;
|
|
358
|
-
border: 1px solid var(--jnrs-font-primary-03);
|
|
359
|
-
background: var(--jnrs-background-primary);
|
|
360
|
-
|
|
361
|
-
.fileLis_item_left {
|
|
362
|
-
flex: 1;
|
|
363
|
-
position: relative;
|
|
364
|
-
display: flex;
|
|
365
|
-
align-items: center;
|
|
366
|
-
justify-content: flex-start;
|
|
367
|
-
padding-right: 50px;
|
|
368
|
-
line-height: 1.1em;
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
.fileLis_item_right {
|
|
372
|
-
flex-shrink: 0;
|
|
373
|
-
width: 60px;
|
|
374
|
-
display: flex;
|
|
375
|
-
align-items: center;
|
|
376
|
-
justify-content: flex-end;
|
|
377
|
-
padding-right: 4px;
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
.fileLis_item_index {
|
|
381
|
-
flex-shrink: 0;
|
|
382
|
-
width: 20px;
|
|
383
|
-
height: 20px;
|
|
384
|
-
line-height: 20px;
|
|
385
|
-
text-align: center;
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
.fileLis_item_icon {
|
|
389
|
-
flex-shrink: 0;
|
|
390
|
-
width: 20px;
|
|
391
|
-
height: 20px;
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
.fileLis_item_name {
|
|
395
|
-
padding: 0 4px;
|
|
396
|
-
word-break: break-all;
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
.fileLis_item_size {
|
|
400
|
-
position: absolute;
|
|
401
|
-
right: 0;
|
|
402
|
-
width: 50px;
|
|
403
|
-
color: #999;
|
|
404
|
-
white-space: nowrap;
|
|
405
|
-
text-align: right;
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
.fileLis_item_btn {
|
|
409
|
-
flex-shrink: 0;
|
|
410
|
-
display: flex;
|
|
411
|
-
align-items: center;
|
|
412
|
-
justify-content: center;
|
|
413
|
-
width: 20px;
|
|
414
|
-
height: 20px;
|
|
415
|
-
margin: 0 2px;
|
|
416
|
-
border-radius: 3px;
|
|
417
|
-
font-size: 16px;
|
|
418
|
-
color: var(--el-color-primary, #5887f7);
|
|
419
|
-
transition: all 0.3s ease;
|
|
420
|
-
cursor: pointer;
|
|
421
|
-
|
|
422
|
-
&:hover {
|
|
423
|
-
background-color: var(--jnrs-card-primary);
|
|
424
|
-
}
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
.fileLis_item_btn_danger {
|
|
428
|
-
color: var(--el-color-danger, #ff3300);
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
</style>
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
<!--
|
|
2
|
-
@Author : TanRui
|
|
3
|
-
@WeChat : Tan578853789
|
|
4
|
-
@File : JnDatetime.vue
|
|
5
|
-
@Date : 2025/12/25
|
|
6
|
-
@desc. : 显示时间格式化,第一行是日期,第二行是时间
|
|
7
|
-
-->
|
|
8
|
-
|
|
9
|
-
<script setup lang="ts">
|
|
10
|
-
import { computed } from 'vue'
|
|
11
|
-
|
|
12
|
-
interface Props {
|
|
13
|
-
value: string
|
|
14
|
-
color?: string
|
|
15
|
-
}
|
|
16
|
-
const { value = '', color = '' } = defineProps<Props>()
|
|
17
|
-
|
|
18
|
-
const datetime = computed(() => {
|
|
19
|
-
if (value && value.split('T').length === 2) {
|
|
20
|
-
return value.split('T')
|
|
21
|
-
}
|
|
22
|
-
if (value && value.split(' ').length === 2) {
|
|
23
|
-
return value.split(' ')
|
|
24
|
-
}
|
|
25
|
-
return false
|
|
26
|
-
})
|
|
27
|
-
</script>
|
|
28
|
-
|
|
29
|
-
<template>
|
|
30
|
-
<template v-if="datetime">
|
|
31
|
-
<div style="line-height: 1.2em" :style="{ color: color }">
|
|
32
|
-
<div>{{ datetime[0] }}</div>
|
|
33
|
-
<span style="opacity: 0.7; font-size: 0.9em">{{ datetime[1] }}</span>
|
|
34
|
-
</div>
|
|
35
|
-
</template>
|
|
36
|
-
<span v-else>{{ value }}</span>
|
|
37
|
-
</template>
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
<!--
|
|
2
|
-
@Author : TanRui
|
|
3
|
-
@WeChat : Tan578853789
|
|
4
|
-
@File : JnEdit.vue
|
|
5
|
-
@Date : 2025/12/25
|
|
6
|
-
@Desc. : 表格编辑组件
|
|
7
|
-
-->
|
|
8
|
-
|
|
9
|
-
<script setup lang="ts">
|
|
10
|
-
import { ref } from 'vue'
|
|
11
|
-
|
|
12
|
-
interface Props {
|
|
13
|
-
/**
|
|
14
|
-
* 对话框的宽度,默认值为 50%
|
|
15
|
-
*/
|
|
16
|
-
title?: string
|
|
17
|
-
/**
|
|
18
|
-
* 对话框的宽度,默认值为 50%
|
|
19
|
-
*/
|
|
20
|
-
width?: string | number
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const { width = '50%', title = '' } = defineProps<Props>()
|
|
24
|
-
|
|
25
|
-
const emit = defineEmits<{
|
|
26
|
-
closed: []
|
|
27
|
-
}>()
|
|
28
|
-
|
|
29
|
-
const dialogVisible = ref(false)
|
|
30
|
-
|
|
31
|
-
const open = () => {
|
|
32
|
-
dialogVisible.value = true
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const close = () => {
|
|
36
|
-
dialogVisible.value = false
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
const handleClosed = () => {
|
|
40
|
-
emit('closed')
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
defineExpose({
|
|
44
|
-
open,
|
|
45
|
-
close,
|
|
46
|
-
handleClosed
|
|
47
|
-
})
|
|
48
|
-
</script>
|
|
49
|
-
|
|
50
|
-
<template>
|
|
51
|
-
<el-dialog
|
|
52
|
-
v-model="dialogVisible"
|
|
53
|
-
:title="title"
|
|
54
|
-
:width="width"
|
|
55
|
-
:close-on-click-modal="true"
|
|
56
|
-
:close-on-press-escape="true"
|
|
57
|
-
draggable
|
|
58
|
-
overflow
|
|
59
|
-
@closed="handleClosed"
|
|
60
|
-
>
|
|
61
|
-
<slot></slot>
|
|
62
|
-
<template #footer>
|
|
63
|
-
<slot name="footer"></slot>
|
|
64
|
-
</template>
|
|
65
|
-
</el-dialog>
|
|
66
|
-
</template>
|
|
67
|
-
|
|
68
|
-
<style lang="scss" scoped></style>
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
<!--
|
|
2
|
-
@Author : TanRui
|
|
3
|
-
@WeChat : Tan578853789
|
|
4
|
-
@File : JnPagination.vue
|
|
5
|
-
@Date : 2025/12/18
|
|
6
|
-
@Desc. : 分页组件
|
|
7
|
-
-->
|
|
8
|
-
|
|
9
|
-
<script setup lang="ts">
|
|
10
|
-
import { ref, watch } from 'vue'
|
|
11
|
-
import type { ComponentSize } from 'element-plus'
|
|
12
|
-
|
|
13
|
-
type PaginationModelValue = {
|
|
14
|
-
currentPage: number
|
|
15
|
-
pageSize: number
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
interface PaginationProps {
|
|
19
|
-
total: number
|
|
20
|
-
modelValue?: PaginationModelValue
|
|
21
|
-
size?: ComponentSize
|
|
22
|
-
background?: boolean
|
|
23
|
-
marginTop?: string
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
const props = withDefaults(defineProps<PaginationProps>(), {
|
|
27
|
-
modelValue: () => ({ currentPage: 1, pageSize: 10 }),
|
|
28
|
-
size: 'small',
|
|
29
|
-
background: true,
|
|
30
|
-
marginTop: '10px'
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
const emit = defineEmits<{
|
|
34
|
-
(e: 'update:modelValue', value: { currentPage: number; pageSize: number }): void
|
|
35
|
-
(e: 'change'): void
|
|
36
|
-
}>()
|
|
37
|
-
|
|
38
|
-
const localPage = ref(props.modelValue.currentPage)
|
|
39
|
-
const localSize = ref(props.modelValue.pageSize)
|
|
40
|
-
|
|
41
|
-
watch(
|
|
42
|
-
() => props.modelValue,
|
|
43
|
-
(newVal) => {
|
|
44
|
-
localPage.value = newVal.currentPage
|
|
45
|
-
localSize.value = newVal.pageSize
|
|
46
|
-
},
|
|
47
|
-
{ deep: true }
|
|
48
|
-
)
|
|
49
|
-
|
|
50
|
-
// 页码变化
|
|
51
|
-
const handleCurrentChange = (page: number) => {
|
|
52
|
-
localPage.value = page
|
|
53
|
-
const newValue = { currentPage: page, pageSize: localSize.value }
|
|
54
|
-
emit('update:modelValue', newValue)
|
|
55
|
-
emit('change')
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// 每页条数变化时重置到第一页
|
|
59
|
-
const handleSizeChange = (size: number) => {
|
|
60
|
-
localSize.value = size
|
|
61
|
-
localPage.value = 1
|
|
62
|
-
const newValue = { currentPage: 1, pageSize: size }
|
|
63
|
-
emit('update:modelValue', newValue)
|
|
64
|
-
emit('change')
|
|
65
|
-
}
|
|
66
|
-
</script>
|
|
67
|
-
|
|
68
|
-
<template>
|
|
69
|
-
<el-pagination
|
|
70
|
-
v-model:current-page="localPage"
|
|
71
|
-
v-model:page-size="localSize"
|
|
72
|
-
:total="total"
|
|
73
|
-
:page-sizes="[10, 20, 50, 100]"
|
|
74
|
-
:size="size"
|
|
75
|
-
:background="background"
|
|
76
|
-
layout="->, total, sizes, prev, pager, next, jumper"
|
|
77
|
-
:style="{
|
|
78
|
-
marginTop: marginTop
|
|
79
|
-
}"
|
|
80
|
-
@current-change="handleCurrentChange"
|
|
81
|
-
@size-change="handleSizeChange"
|
|
82
|
-
/>
|
|
83
|
-
</template>
|