ci-plus 1.1.0 → 1.1.2
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/index.ts +1 -0
- package/package.json +4 -2
- package/src/components.d.ts +3 -0
- package/src/fileRelated/README.md +7 -0
- package/src/fileRelated/ciupload.vue +149 -0
- package/src/fileRelated/index/ciupload.ts +4 -0
- package/src/fileRelated/seeFile.vue +160 -0
- package/src/fileRelated/uploadV2.vue +212 -0
- package/src/identificationCard/barCode.vue +63 -0
- package/src/identificationCard/identificationCard.vue +1469 -0
- package/src/identificationCard/index.ts +4 -0
- package/src/identificationCard/read.md +64 -0
- package/src/index.ts +4 -1
- package/src/selectSuffix/selectSuffix.vue +31 -1
- package/src/selectSuffix/types.ts +32 -31
- package/src/sortableTable/headerInput.vue +603 -94
- package/src/sortableTable/index/headerInput.ts +4 -0
- package/src/sortableTable/utils/headerPopover.vue +88 -31
- package/src/sortableTable/utils/interface.ts +2 -2
- package/src/utils/Dayjs.ts +27 -0
- package/src/utils/baseApi.ts +38 -0
- package/src/utils/cardPrint.ts +689 -0
- package/src/utils/index.ts +1 -0
package/index.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ci-plus",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.2",
|
|
4
4
|
"description": "ci组件库",
|
|
5
5
|
"main": "./index.ts",
|
|
6
6
|
"scripts": {
|
|
@@ -20,7 +20,9 @@
|
|
|
20
20
|
"less": "^4.2.0",
|
|
21
21
|
"sortablejs": "^1.15.1",
|
|
22
22
|
"vite-plugin-svg-icons": "^2.0.1",
|
|
23
|
-
"vuedraggable": "^2.24.3"
|
|
23
|
+
"vuedraggable": "^2.24.3",
|
|
24
|
+
"jsbarcode": "^3.11.6",
|
|
25
|
+
"dayjs": "^1.11.9"
|
|
24
26
|
},
|
|
25
27
|
"devDependencies": {},
|
|
26
28
|
"peerDependencies": {},
|
package/src/components.d.ts
CHANGED
|
@@ -16,8 +16,11 @@ declare module '@vue/runtime-core' {
|
|
|
16
16
|
CiSuffix: typeof components.Suffix;
|
|
17
17
|
CiTable: typeof components.SorTables;
|
|
18
18
|
CiHeadbtns: typeof components.Headbtns
|
|
19
|
+
CiHeaderInput: typeof components.HeaderInput
|
|
19
20
|
CiSdialog: typeof components.Sdialog
|
|
20
21
|
CiColumncell: typeof components.Columncell
|
|
22
|
+
CiUpload: typeof components.Upload
|
|
23
|
+
CiIdentificationCard: typeof components.IdentificationCard
|
|
21
24
|
}
|
|
22
25
|
}
|
|
23
26
|
export { };
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<el-popover placement="bottom" :width="300" trigger="click">
|
|
3
|
+
<el-upload
|
|
4
|
+
ref="upload"
|
|
5
|
+
class="upload-demo"
|
|
6
|
+
:action="url + '_post/'"
|
|
7
|
+
:limit="1"
|
|
8
|
+
:on-exceed="handleExceed"
|
|
9
|
+
:auto-upload="false"
|
|
10
|
+
:on-success="onSuccess"
|
|
11
|
+
:on-error="onError"
|
|
12
|
+
:on-change="handleChange"
|
|
13
|
+
:data="datas"
|
|
14
|
+
>
|
|
15
|
+
<template #trigger>
|
|
16
|
+
<el-button size="small" type="primary" style="width: 166px" plain> 选择文件 </el-button>
|
|
17
|
+
</template>
|
|
18
|
+
<el-button
|
|
19
|
+
size="small"
|
|
20
|
+
@click="formwork"
|
|
21
|
+
style="float: left; margin: 0 12px 0 0; width: 95px"
|
|
22
|
+
>
|
|
23
|
+
下载模板
|
|
24
|
+
</el-button>
|
|
25
|
+
</el-upload>
|
|
26
|
+
|
|
27
|
+
<div style="width: 100%; display: flex">
|
|
28
|
+
<el-button size="small" @click="visible = false" style="flex: 1"> 取消 </el-button>
|
|
29
|
+
<el-button size="small" type="primary" @click="submitUpload" style="flex: 2">
|
|
30
|
+
上传
|
|
31
|
+
</el-button>
|
|
32
|
+
</div>
|
|
33
|
+
<template #reference>
|
|
34
|
+
<el-button type="success" plain @click="visible = true"> 导入 </el-button>
|
|
35
|
+
</template>
|
|
36
|
+
</el-popover>
|
|
37
|
+
</template>
|
|
38
|
+
|
|
39
|
+
<script setup lang="ts">
|
|
40
|
+
import { ref } from 'vue'
|
|
41
|
+
import { ElMessage, ElLoading, genFileId } from 'element-plus'
|
|
42
|
+
import axios from 'axios'
|
|
43
|
+
import type { UploadInstance, UploadProps, UploadRawFile } from 'element-plus'
|
|
44
|
+
const upload = ref<UploadInstance>()
|
|
45
|
+
const exporLoading = ref()
|
|
46
|
+
const visible = ref(false)
|
|
47
|
+
const filelist = ref([])
|
|
48
|
+
const props = defineProps<{
|
|
49
|
+
url: string
|
|
50
|
+
parameter?: object // 附件模板下载时的请求参数
|
|
51
|
+
data?: object // 附件上传时的请求参数
|
|
52
|
+
templateName?: string // 模板名称
|
|
53
|
+
templateDownloadFn?: (val: any) => Promise<any> //附件上传函数?: Function
|
|
54
|
+
}>()
|
|
55
|
+
const emits = defineEmits<{
|
|
56
|
+
(e: 'reloadTable'): void
|
|
57
|
+
}>()
|
|
58
|
+
|
|
59
|
+
const datas = ref(props.data)
|
|
60
|
+
|
|
61
|
+
//选择文件
|
|
62
|
+
const handleExceed: UploadProps['onExceed'] = (files) => {
|
|
63
|
+
upload.value!.clearFiles()
|
|
64
|
+
const file = files[0] as UploadRawFile
|
|
65
|
+
file.uid = genFileId()
|
|
66
|
+
upload.value!.handleStart(file)
|
|
67
|
+
}
|
|
68
|
+
const handleChange = (file: any, fileList: any) => {
|
|
69
|
+
filelist.value = fileList //更新文件列表数据
|
|
70
|
+
}
|
|
71
|
+
//上传文件
|
|
72
|
+
const submitUpload = () => {
|
|
73
|
+
console.log(filelist.value.length)
|
|
74
|
+
if (!filelist.value.length) return ElMessage.warning('请选择文件后在上传!')
|
|
75
|
+
exporLoading.value = ElLoading.service({ text: '导入中...' })
|
|
76
|
+
console.log('upload.value', upload.value)
|
|
77
|
+
upload.value!.submit()
|
|
78
|
+
visible.value = false
|
|
79
|
+
}
|
|
80
|
+
//文件上传成功回调
|
|
81
|
+
const onSuccess = (res: any, file: any, fileList: any) => {
|
|
82
|
+
// console.log('res: ', res)
|
|
83
|
+
// console.log('file: ', file)
|
|
84
|
+
// console.log('fileList: ', fileList)
|
|
85
|
+
exporLoading.value.close()
|
|
86
|
+
filelist.value.length = 0
|
|
87
|
+
upload.value!.clearFiles()
|
|
88
|
+
|
|
89
|
+
if (res.code !== 200) {
|
|
90
|
+
return ElMessage.warning(res.msg)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
ElMessage.success(res.msg)
|
|
94
|
+
emits('reloadTable')
|
|
95
|
+
}
|
|
96
|
+
//文件上传失败回调
|
|
97
|
+
const onError = (response: any, file: any, fileList: any) => {
|
|
98
|
+
// console.log('fileList: ', fileList)
|
|
99
|
+
// console.log('response: ', response)
|
|
100
|
+
ElMessage.error(file.name + '上传失败')
|
|
101
|
+
filelist.value.length = 0
|
|
102
|
+
upload.value!.clearFiles() // 清空文件列表
|
|
103
|
+
exporLoading.value.close()
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
//下载模板
|
|
107
|
+
const formwork = () => {
|
|
108
|
+
if (props.templateDownloadFn) {
|
|
109
|
+
props
|
|
110
|
+
.templateDownloadFn({
|
|
111
|
+
responseType: 'blob',
|
|
112
|
+
params: props.parameter
|
|
113
|
+
})
|
|
114
|
+
.then((res) => {
|
|
115
|
+
const url = URL.createObjectURL(new Blob([res.data]))
|
|
116
|
+
let link: HTMLAnchorElement | null = document.createElement('a')
|
|
117
|
+
link.href = url
|
|
118
|
+
link.setAttribute('download', props.templateName || '模板.xlsx')
|
|
119
|
+
document.body.appendChild(link)
|
|
120
|
+
link.click()
|
|
121
|
+
link = null
|
|
122
|
+
})
|
|
123
|
+
.catch((error) => {
|
|
124
|
+
console.log(error)
|
|
125
|
+
})
|
|
126
|
+
} else {
|
|
127
|
+
axios({
|
|
128
|
+
method: 'get',
|
|
129
|
+
url: props.url + '_get/',
|
|
130
|
+
responseType: 'blob',
|
|
131
|
+
params: props.parameter
|
|
132
|
+
})
|
|
133
|
+
.then((res) => {
|
|
134
|
+
const url = URL.createObjectURL(new Blob([res.data]))
|
|
135
|
+
let link: HTMLAnchorElement | null = document.createElement('a')
|
|
136
|
+
link.href = url
|
|
137
|
+
link.setAttribute('download', props.templateName || '模板.xlsx')
|
|
138
|
+
document.body.appendChild(link)
|
|
139
|
+
link.click()
|
|
140
|
+
link = null
|
|
141
|
+
})
|
|
142
|
+
.catch((error) => {
|
|
143
|
+
console.log(error)
|
|
144
|
+
})
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
</script>
|
|
148
|
+
|
|
149
|
+
<style scoped></style>
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
<!-- /**
|
|
2
|
+
* @module seeFile
|
|
3
|
+
* @author : 卖女孩的小火柴
|
|
4
|
+
* !description : 附件预览
|
|
5
|
+
* @version : 1.0.0
|
|
6
|
+
* @since : 创建时间 2024-02-19 10:13:32
|
|
7
|
+
*/ -->
|
|
8
|
+
|
|
9
|
+
<template>
|
|
10
|
+
<el-popover
|
|
11
|
+
placement="bottom"
|
|
12
|
+
:width="200"
|
|
13
|
+
style="height: 200px; max-height: 400px; max-width: 250px"
|
|
14
|
+
trigger="click"
|
|
15
|
+
>
|
|
16
|
+
<template #reference>
|
|
17
|
+
<el-button type="success" plain size="small"> 附件 </el-button>
|
|
18
|
+
</template>
|
|
19
|
+
<template v-for="(item, i) in pathArr" :key="i">
|
|
20
|
+
<div class="list" v-if="item.name">
|
|
21
|
+
<div class="list-a" @click="downloadFile(item.oldName, item.name)">
|
|
22
|
+
{{ item.name || '下载' }}
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
25
|
+
</template>
|
|
26
|
+
</el-popover>
|
|
27
|
+
</template>
|
|
28
|
+
|
|
29
|
+
<script setup lang="ts">
|
|
30
|
+
import { ref, watch } from 'vue'
|
|
31
|
+
import axios from 'axios'
|
|
32
|
+
import { ElMessage } from 'element-plus'
|
|
33
|
+
const props = defineProps<{
|
|
34
|
+
url?: string[] // 传入要显示的附件地址数组
|
|
35
|
+
baseUrl?: string // 图片展示的基础路径
|
|
36
|
+
}>()
|
|
37
|
+
/*
|
|
38
|
+
数据结构说明:
|
|
39
|
+
props.url:[
|
|
40
|
+
"media/material/3.1708222741.7763922.webp",
|
|
41
|
+
"media/material/3号(number-3)_爱给网_aigei_com.1708222741.7783866.png"
|
|
42
|
+
]
|
|
43
|
+
|
|
44
|
+
基础路径
|
|
45
|
+
props.baseUrl : http://10.20.72.231:9999/
|
|
46
|
+
*/
|
|
47
|
+
|
|
48
|
+
// 定义一个函数,用于处理字符串
|
|
49
|
+
export const setFilePath = (arr: string[], url?: string) => {
|
|
50
|
+
// console.log('重新渲染数据', arr);
|
|
51
|
+
if (arr && arr.length > 0) {
|
|
52
|
+
let newArr: { name: string; oldName: string }[] = []
|
|
53
|
+
arr.forEach((item, i) => {
|
|
54
|
+
let segments = item.split('.')
|
|
55
|
+
let parts = segments[0].split('/') // 获取每名称
|
|
56
|
+
let name = parts[parts.length - 1] + '.' + segments[segments.length - 1]
|
|
57
|
+
let oldName = url ? url + item : item //原来的名称
|
|
58
|
+
// let url = segments[0] + '.' + segments[segments.length - 1]
|
|
59
|
+
newArr.push({ name, oldName })
|
|
60
|
+
})
|
|
61
|
+
return newArr
|
|
62
|
+
} else {
|
|
63
|
+
return [] // 如果数组为空,则返回空数组
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// 将路径处理成附件的参数
|
|
68
|
+
export const fileArr = (url: string, pathArr: string[]) => {
|
|
69
|
+
if (pathArr && pathArr.length > 0) {
|
|
70
|
+
let objArr: any = []
|
|
71
|
+
if (pathArr.length > 0) {
|
|
72
|
+
pathArr.map((item: any) => {
|
|
73
|
+
objArr.push({
|
|
74
|
+
name: item.name,
|
|
75
|
+
oldName: item.oldName,
|
|
76
|
+
url: url + item.oldName
|
|
77
|
+
})
|
|
78
|
+
})
|
|
79
|
+
return objArr
|
|
80
|
+
} else {
|
|
81
|
+
return []
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const emits = defineEmits(['onClick'])
|
|
87
|
+
|
|
88
|
+
// console.log('props', props.url)
|
|
89
|
+
|
|
90
|
+
const pathArr = ref<any[]>([])
|
|
91
|
+
// 对数组中的每个字符串应用处理函数
|
|
92
|
+
// @ts-ignore
|
|
93
|
+
pathArr.value = setFilePath(props.url, props.baseUrl || 'http://10.20.72.231:9999/')
|
|
94
|
+
|
|
95
|
+
// 监听props.url的变化
|
|
96
|
+
watch(
|
|
97
|
+
() => props.url,
|
|
98
|
+
(newVal) => {
|
|
99
|
+
// console.log('newVal: ', newVal)
|
|
100
|
+
// 对新值进行处理
|
|
101
|
+
// @ts-ignore
|
|
102
|
+
pathArr.value = setFilePath(newVal, props.baseUrl || 'http://10.20.72.231:9999/')
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
immediate: true, // 是否立即执行
|
|
106
|
+
deep: true // 是否深度监听
|
|
107
|
+
}
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
// 下载文件
|
|
111
|
+
const downloadFile = (url: string, name: string) => {
|
|
112
|
+
axios({
|
|
113
|
+
method: 'GET',
|
|
114
|
+
url: url,
|
|
115
|
+
responseType: 'blob'
|
|
116
|
+
}).then((res) => {
|
|
117
|
+
console.log('res: ', res)
|
|
118
|
+
if (res.status === 200) {
|
|
119
|
+
if (res.headers['Content-Type'] === 'application/json') {
|
|
120
|
+
let data
|
|
121
|
+
if (res.request) data = JSON.parse(res.request.responseText)
|
|
122
|
+
else data = { code: 500, msg: '文件获取失败' }
|
|
123
|
+
return ElMessage.warning(`${data.code}:${data.msg}`) // 文件获取失败
|
|
124
|
+
}
|
|
125
|
+
ElMessage.success('开始下载!')
|
|
126
|
+
const link = document.createElement('a') // 创建a标签
|
|
127
|
+
link.href = window.URL.createObjectURL(new Blob([res.data])) // 创建下载链接
|
|
128
|
+
link.setAttribute('download', name) // 设置下载文件名称(名称+后缀)
|
|
129
|
+
link.click() // 下载文件
|
|
130
|
+
window.URL.revokeObjectURL(link.href) // 释放内存
|
|
131
|
+
} else ElMessage.error(`${res.status}:${res.statusText}`) // 文件获取失败
|
|
132
|
+
})
|
|
133
|
+
}
|
|
134
|
+
</script>
|
|
135
|
+
|
|
136
|
+
<style lang="scss" scoped>
|
|
137
|
+
.list {
|
|
138
|
+
display: flex;
|
|
139
|
+
justify-content: space-between;
|
|
140
|
+
width: 100%;
|
|
141
|
+
height: 30px;
|
|
142
|
+
line-height: 30px;
|
|
143
|
+
border: 1px solid #ebeef5;
|
|
144
|
+
padding: 0 10px;
|
|
145
|
+
box-sizing: border-box;
|
|
146
|
+
font-size: 14px;
|
|
147
|
+
overflow: hidden;
|
|
148
|
+
text-overflow: ellipsis;
|
|
149
|
+
white-space: nowrap;
|
|
150
|
+
.list-a {
|
|
151
|
+
width: 100%;
|
|
152
|
+
overflow: hidden;
|
|
153
|
+
text-overflow: ellipsis;
|
|
154
|
+
&:hover {
|
|
155
|
+
background-color: #f5f7fa;
|
|
156
|
+
cursor: pointer;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
</style>
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<el-popover placement="bottom" :width="300">
|
|
3
|
+
<el-upload
|
|
4
|
+
ref="upload"
|
|
5
|
+
class="upload-demo"
|
|
6
|
+
:action="url + '_post/'"
|
|
7
|
+
:limit="mylimit || 1"
|
|
8
|
+
:on-exceed="handleExceed"
|
|
9
|
+
:auto-upload="false"
|
|
10
|
+
:on-success="onSuccess"
|
|
11
|
+
:on-error="onError"
|
|
12
|
+
:on-change="handleChange"
|
|
13
|
+
:on-remove="handleRemove"
|
|
14
|
+
:data="datas"
|
|
15
|
+
:multiple="mymultiple || false"
|
|
16
|
+
v-model:file-list="fileList"
|
|
17
|
+
>
|
|
18
|
+
<template #trigger>
|
|
19
|
+
<el-button size="small" type="primary" style="width: 100px" plain> 选择文件 </el-button>
|
|
20
|
+
</template>
|
|
21
|
+
<el-button
|
|
22
|
+
size="small"
|
|
23
|
+
@click="formwork"
|
|
24
|
+
style="float: left; margin: 0 12px 0 0; width: 95px"
|
|
25
|
+
v-if="url"
|
|
26
|
+
>
|
|
27
|
+
下载模板
|
|
28
|
+
</el-button>
|
|
29
|
+
</el-upload>
|
|
30
|
+
|
|
31
|
+
<div style="width: 100%; display: flex" v-if="url">
|
|
32
|
+
<el-button size="small" @click="visible = false" style="flex: 1"> 取消 </el-button>
|
|
33
|
+
<el-button size="small" type="primary" @click="submitUpload" style="flex: 2">
|
|
34
|
+
上传
|
|
35
|
+
</el-button>
|
|
36
|
+
</div>
|
|
37
|
+
<template #reference>
|
|
38
|
+
<el-button type="success" plain @click="visible = true" size="small">
|
|
39
|
+
{{ props.title || '附件上传' }}
|
|
40
|
+
</el-button>
|
|
41
|
+
</template>
|
|
42
|
+
</el-popover>
|
|
43
|
+
</template>
|
|
44
|
+
|
|
45
|
+
<script setup lang="ts">
|
|
46
|
+
// 定义一个函数,用于处理字符串
|
|
47
|
+
export const setFilePath = (arr: string[], url?: string) => {
|
|
48
|
+
// console.log('重新渲染数据', arr);
|
|
49
|
+
if (arr && arr.length > 0) {
|
|
50
|
+
let newArr: { name: string; oldName: string }[] = []
|
|
51
|
+
arr.forEach((item, i) => {
|
|
52
|
+
let segments = item.split('.')
|
|
53
|
+
let parts = segments[0].split('/') // 获取每名称
|
|
54
|
+
let name = parts[parts.length - 1] + '.' + segments[segments.length - 1]
|
|
55
|
+
let oldName = url ? url + item : item //原来的名称
|
|
56
|
+
// let url = segments[0] + '.' + segments[segments.length - 1]
|
|
57
|
+
newArr.push({ name, oldName })
|
|
58
|
+
})
|
|
59
|
+
return newArr
|
|
60
|
+
} else {
|
|
61
|
+
return [] // 如果数组为空,则返回空数组
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// 将路径处理成附件的参数
|
|
66
|
+
export const fileArr = (url: string, pathArr: string[]) => {
|
|
67
|
+
if (pathArr && pathArr.length > 0) {
|
|
68
|
+
let objArr: any = []
|
|
69
|
+
if (pathArr.length > 0) {
|
|
70
|
+
pathArr.map((item: any) => {
|
|
71
|
+
objArr.push({
|
|
72
|
+
name: item.name,
|
|
73
|
+
oldName: item.oldName,
|
|
74
|
+
url: url + item.oldName
|
|
75
|
+
})
|
|
76
|
+
})
|
|
77
|
+
return objArr
|
|
78
|
+
} else {
|
|
79
|
+
return []
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
import { ref } from 'vue'
|
|
85
|
+
import { ElMessage, ElLoading, genFileId } from 'element-plus'
|
|
86
|
+
import axios from 'axios'
|
|
87
|
+
import type {
|
|
88
|
+
UploadFile,
|
|
89
|
+
UploadFiles,
|
|
90
|
+
UploadInstance,
|
|
91
|
+
UploadProps,
|
|
92
|
+
UploadUserFile
|
|
93
|
+
} from 'element-plus'
|
|
94
|
+
const upload = ref<UploadInstance>()
|
|
95
|
+
const exporLoading = ref()
|
|
96
|
+
const visible = ref(false)
|
|
97
|
+
// const filelist = ref([])
|
|
98
|
+
|
|
99
|
+
const props = defineProps<{
|
|
100
|
+
url?: string // 上传和下载模板的接口(当需要将附件传递回父组件时不需要传递此属性)
|
|
101
|
+
parameter?: () => {} // 模板下载的时候请求需要携带的参数:{state: 1}
|
|
102
|
+
data?: () => {} //上传携带的其他数据对象:{userId: 1, userName: '张三'}
|
|
103
|
+
title?: string // 上传按钮的名称
|
|
104
|
+
multiple?: boolean // 是否支持多文件
|
|
105
|
+
limit?: number // 最大文件数量
|
|
106
|
+
filePath?: UploadFile[] //UploadRawFile[] // 父组件传递的附件数据,用于显示附件列表和上传附件后传递给父组件附件数据
|
|
107
|
+
RowIndex?: number // 父组件传递的行索引,用于父组件中删除了附件找到对应的行
|
|
108
|
+
}>()
|
|
109
|
+
const emits = defineEmits<{
|
|
110
|
+
(e: 'reloadTable'): void // 组件中上传附件后刷新父组件表格数据方法
|
|
111
|
+
(e: 'getFile', files: UploadFiles, file?: UploadFile, rowindex?: number): void
|
|
112
|
+
(e: 'update:file', files: UploadFiles): void
|
|
113
|
+
}>()
|
|
114
|
+
console.log('附件props: ', props)
|
|
115
|
+
const datas = ref(props.data)
|
|
116
|
+
const mymultiple = ref<boolean>(props.multiple)
|
|
117
|
+
const mylimit = ref<number>(props.limit as number)
|
|
118
|
+
const myfilePath = ref<any>(props.filePath || [])
|
|
119
|
+
console.log('myfilePath: ', props.filePath)
|
|
120
|
+
|
|
121
|
+
// 对数组中的每个字符串应用处理函数
|
|
122
|
+
let pathArr = setFilePath(myfilePath.value)
|
|
123
|
+
|
|
124
|
+
// 打印处理后的数组
|
|
125
|
+
// 将父组件中传递过来的名称,处理成el-upload需要的格式
|
|
126
|
+
let pathUrlArr = fileArr(import.meta.env.VITE_BASE_URL9999, pathArr)
|
|
127
|
+
console.log('fileObj(): ', pathUrlArr)
|
|
128
|
+
const fileList = ref<UploadUserFile[]>(pathUrlArr)
|
|
129
|
+
console.log('fileList: ', fileList.value)
|
|
130
|
+
|
|
131
|
+
//当超出限制时,执行的钩子函数
|
|
132
|
+
const handleExceed: UploadProps['onExceed'] = (files) => {
|
|
133
|
+
console.log('超出限制: ', files)
|
|
134
|
+
ElMessage.warning(`超出最大文件数:${mylimit?.value}个文件,请重新选择`)
|
|
135
|
+
// upload.value!.clearFiles()
|
|
136
|
+
// const file = files[0] as UploadRawFile
|
|
137
|
+
// file.uid = genFileId()
|
|
138
|
+
// upload.value!.handleStart(file)
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// 文件状态改变时的钩子,添加文件、上传成功和上传失败时都会被调用
|
|
142
|
+
const handleChange = (file: any, fileLists: any) => {
|
|
143
|
+
// console.log('file: ', file)
|
|
144
|
+
// console.log('fileList: ', fileLists)
|
|
145
|
+
// filelist.value = fileLists //更新文件列表数据
|
|
146
|
+
// 如果没有url就将选中的附件文件流传递回父组件
|
|
147
|
+
if (!props.url) {
|
|
148
|
+
// const files: UploadRawFile[] = fileLists.map(
|
|
149
|
+
// (item) => item.raw,
|
|
150
|
+
// ) as UploadRawFile[]
|
|
151
|
+
emits('getFile', fileLists) //将选中的文件传递回父组件
|
|
152
|
+
emits('update:file', fileLists) //同步父组件绑定的附件字段,以便父组件提交表单的时候一起将附件提交
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
// 文件列表删除时
|
|
156
|
+
const handleRemove: UploadProps['onRemove'] = (file, fileList) => {
|
|
157
|
+
console.log('file: ', file)
|
|
158
|
+
console.log('fileList: ', fileList)
|
|
159
|
+
// 如果没有url时 在删除的时候将文件流同步回父组件
|
|
160
|
+
if (!props.url) {
|
|
161
|
+
// const files: UploadRawFile[] = fileList.map(
|
|
162
|
+
// (item) => item.raw,
|
|
163
|
+
// ) as UploadRawFile[]
|
|
164
|
+
emits('getFile', fileList, file, props.RowIndex)
|
|
165
|
+
emits('update:file', fileList)
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
//上传文件
|
|
169
|
+
const submitUpload = () => {
|
|
170
|
+
console.log(fileList.value.length)
|
|
171
|
+
if (!fileList.value.length) return ElMessage.warning('请选择文件后在上传12!')
|
|
172
|
+
exporLoading.value = ElLoading.service({ text: '导入中...' })
|
|
173
|
+
console.log('upload.value', upload.value)
|
|
174
|
+
upload.value!.submit()
|
|
175
|
+
visible.value = false
|
|
176
|
+
}
|
|
177
|
+
//文件上传成功回调
|
|
178
|
+
const onSuccess = (res: any, file: any, fileList: any) => {
|
|
179
|
+
exporLoading.value.close()
|
|
180
|
+
if (res.code !== 200) return ElMessage.warning(res.msg)
|
|
181
|
+
ElMessage.success(res.msg)
|
|
182
|
+
emits('reloadTable')
|
|
183
|
+
}
|
|
184
|
+
//文件上传失败回调
|
|
185
|
+
const onError = (response: any, file: any, fileList: any) => {
|
|
186
|
+
ElMessage.error('服务器异常!')
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
//下载模板
|
|
190
|
+
const formwork = () => {
|
|
191
|
+
axios({
|
|
192
|
+
method: 'get',
|
|
193
|
+
url: props.url + '_get/',
|
|
194
|
+
responseType: 'blob',
|
|
195
|
+
params: props.parameter
|
|
196
|
+
})
|
|
197
|
+
.then((res) => {
|
|
198
|
+
const url = URL.createObjectURL(new Blob([res.data]))
|
|
199
|
+
let link: HTMLAnchorElement | null = document.createElement('a')
|
|
200
|
+
link.href = url
|
|
201
|
+
link.setAttribute('download', '模板.xlsx')
|
|
202
|
+
document.body.appendChild(link)
|
|
203
|
+
link.click()
|
|
204
|
+
link = null
|
|
205
|
+
})
|
|
206
|
+
.catch((error) => {
|
|
207
|
+
console.log(error)
|
|
208
|
+
})
|
|
209
|
+
}
|
|
210
|
+
</script>
|
|
211
|
+
|
|
212
|
+
<style scoped></style>
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
* @module SelfBarcode
|
|
3
|
+
* @author : 卖女孩的小火柴
|
|
4
|
+
* !description : 条形码组件:根据传入的文本生成条形码
|
|
5
|
+
* @version : 1.0.0
|
|
6
|
+
* @since : 创建时间 2024-01-19 16:37:51
|
|
7
|
+
-->
|
|
8
|
+
|
|
9
|
+
<template>
|
|
10
|
+
<div>
|
|
11
|
+
<svg :class="'barcode' + props.value" class="mycards" :style="`max-width: ${maxWidth}`"></svg>
|
|
12
|
+
</div>
|
|
13
|
+
</template>
|
|
14
|
+
|
|
15
|
+
<script setup lang="ts">
|
|
16
|
+
import { ref, onMounted, nextTick, watch } from 'vue'
|
|
17
|
+
import JsBarcode from 'jsbarcode'
|
|
18
|
+
interface Props {
|
|
19
|
+
value: String // 条码文本
|
|
20
|
+
type: String // 类型
|
|
21
|
+
maxWidth: String // 最大宽度
|
|
22
|
+
newClass: String | Number // 自定义class
|
|
23
|
+
}
|
|
24
|
+
const props = defineProps<Props>()
|
|
25
|
+
// console.log('条码props', props)
|
|
26
|
+
watch(props, () => {
|
|
27
|
+
draw()
|
|
28
|
+
})
|
|
29
|
+
function draw() {
|
|
30
|
+
// 第一个参数,要渲染的dom的id或者class名称,第二个参数,条形码的实际文本,第三个参数,条形码的配置
|
|
31
|
+
JsBarcode('.barcode' + props.value, String(props.value), {
|
|
32
|
+
// format: 'CODE39', //选择要使用的条形码类型,默认值'auto' (CODE128)
|
|
33
|
+
width: 2, //设置条之间的宽度
|
|
34
|
+
height: 40, //高度
|
|
35
|
+
displayValue: true, //是否在条形码下方显示文字
|
|
36
|
+
// text: props.value,//覆盖显示的文本
|
|
37
|
+
// text:"456",//覆盖显示的文本
|
|
38
|
+
// fontOptions:"bold italic",//使文字加粗体或变斜体
|
|
39
|
+
// font:"fantasy",//设置文本的字体
|
|
40
|
+
// textAlign:"left",//设置文本的水平对齐方式
|
|
41
|
+
// textPosition:"top",//设置文本的垂直位置
|
|
42
|
+
// textMargin:5,//设置条形码和文本之间的间距
|
|
43
|
+
fontSize: 16, //设置文本的大小
|
|
44
|
+
// background: '#fff', //设置条形码的背景
|
|
45
|
+
// lineColor: '#2196f3', //设置条和文本的颜色。
|
|
46
|
+
// margin: 25, //设置条形码周围的空白边距
|
|
47
|
+
marginTop: 5, //相当于MarginTop
|
|
48
|
+
marginBottom: 0
|
|
49
|
+
})
|
|
50
|
+
}
|
|
51
|
+
onMounted(() => {
|
|
52
|
+
nextTick(() => {
|
|
53
|
+
draw()
|
|
54
|
+
})
|
|
55
|
+
})
|
|
56
|
+
</script>
|
|
57
|
+
<style lang="scss" scoped>
|
|
58
|
+
.mycards {
|
|
59
|
+
color: red;
|
|
60
|
+
max-width: 600px;
|
|
61
|
+
min-width: 400px;
|
|
62
|
+
}
|
|
63
|
+
</style>
|