Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
N
nse-ui
概览
Overview
Details
Activity
Cycle Analytics
版本库
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
问题
0
Issues
0
列表
Board
标记
里程碑
合并请求
0
Merge Requests
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
Snippets
成员
Members
Collapse sidebar
Close sidebar
活动
图像
聊天
创建新问题
作业
提交
Issue Boards
Open sidebar
吴超
nse-ui
Commits
c81064a3
Commit
c81064a3
authored
Aug 21, 2025
by
wanglizhen
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
上传文件
parent
1165d598
显示空白字符变更
内嵌
并排
正在显示
5 个修改的文件
包含
465 行增加
和
13 行删除
+465
-13
src/components/CustomUpload/index.vue
+393
-0
src/components/EditPop/ExpressionEditor.vue
+2
-2
src/components/EditPop/ModalPop.vue
+3
-7
src/views/ruleConfig/Dictionary/index.vue
+13
-4
src/views/ruleConfig/Dictionary/modules/UploadModule.vue
+54
-0
没有找到文件。
src/components/CustomUpload/index.vue
0 → 100644
View file @
c81064a3
<
script
setup
lang=
"ts"
name=
"CustomUpload"
>
import
{
ref
,
getCurrentInstance
,
computed
,
onMounted
,
watch
}
from
'vue'
import
{
getToken
}
from
'@/utils/auth'
import
{
ElMessage
,
ElMessageBox
}
from
'element-plus'
import
{
parseTime
}
from
'@/utils/ruoyi'
import
axios
from
'axios'
// import { filePreview } from '@/api/preview'
const
{
proxy
}
=
getCurrentInstance
()
as
any
//
<
CustomUpload
v
-
model
:
file
-
list
=
"fileList"
/>
// const fileList = ref([
// {
// name: 'food.jpeg',
// fileSize: '23423',
// fileType: 'img',
// url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100',
// createTime: '2024-01-24 16:31'
// },
// {
// name: 'food.jpeg',
// fileSize: '23423',
// fileType: 'img',
// url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100',
// createTime: '2024-01-24 16:31'
// }
// ])
type
IFileList
=
Array
<
any
>
|
null
|
undefined
const
emit
=
defineEmits
<
{
'update:fileList'
:
[
fileList
:
IFileList
],
'onSuccess'
}
>
()
const
props
=
withDefaults
(
defineProps
<
{
fileList
:
IFileList
buttonPermission
?:
Array
<
string
>
needType
?:
boolean
needSize
?:
boolean
needTime
?:
boolean
needStatus
?:
boolean
,
acceptTypeList
?:
Array
<
string
>
limit
?:
number
,
prompt
?:
string
,
uploadType
?:
number
,
listShow
?:
boolean
}
>
(),
{
buttonPermission
:
()
=>
[
'upload'
,
'delete'
],
needType
:
true
,
needSize
:
true
,
needTime
:
true
,
needStatus
:
true
,
limit
:
100
,
prompt
:
'点击或将文件拖拽到此处上传'
,
uploadType
:
1
,
listShow
:
false
,
// acceptTypeList: () => ['png', 'jpg', 'doc', 'docx', 'pdf']
})
const
uploadFileUrl
=
(
props
.
uploadType
===
1
?
ref
(
import
.
meta
.
env
.
VITE_APP_BASE_API
+
'/core/dictionaryexcel/importfile'
)
:
ref
(
import
.
meta
.
env
.
VITE_APP_BASE_API
+
'/eo/TTenantContractlabelTemplateController/uploadTemporary'
))
// 上传文件服务器地址
const
headers
=
ref
({
Token
:
getToken
(),
'from-source'
:
'platformUi'
,
'Content-Type'
:
'mulipart/form-data'
})
// const FileList = ref
<
Array
<
any
>>
([])
const
FileList
=
computed
({
get
()
{
return
props
.
fileList
},
set
(
val
:
any
)
{
// console.log('fileList computed', val)
emit
(
'update:fileList'
,
val
)
}
})
const
uploadLoading
=
computed
(()
=>
{
if
(
FileList
.
value
!=
null
&&
FileList
.
value
.
some
(
item
=>
item
.
status
===
'uploading'
))
{
return
true
}
return
false
})
// const fileListlengthCompute = computed(() => {
// return props.fileList.length
// })
// watch(() => props.fileList, (val: IFileList) => {
// console.log('props.fileList', val)
// if (!val) {
// FileList.value = []
// return
// }
// FileList.value = JSON.parse(JSON.stringify(props.fileList))
// }, { deep: true, immediate: true })
// watch(fileListlengthCompute, (val) => {
// console.log(val)
// if (val === 0) {
// emit('update:fileList', [])
// FileList.value = []
// }
// }, { deep: true, immediate: true })
function
updateFileList
()
{
emit
(
'onSuccess'
)
// emit('update:fileList', FileList.value.filter(item => item.status === 'success'))
}
function
beforeUpload
(
file
)
{
console
.
log
(
'beforeUpload'
,
file
)
let
type
=
file
.
name
.
split
(
'.'
)
type
=
type
[
type
.
length
-
1
]
if
(
props
.
acceptTypeList
.
indexOf
(
type
)
>=
0
)
{
const
list
=
{}
for
(
const
key
in
file
)
{
list
[
key
]
=
file
[
key
]
}
// status:uploading、success、error 文件上传状态
// progress 文件上传进度
FileList
.
value
.
push
({
...
list
,
progress
:
0
,
status
:
'uploading'
})
// updateFileList()
httpRequest
(
file
,
parms
=>
{
showProgress
(
list
,
parms
)
})
// 阻止 el-upload的默认上传
return
false
}
proxy
.
$modal
.
msgError
(
`文件格式不正确, 请上传
${
props
.
acceptTypeList
.
join
(
'/'
)}
格式文件!`
)
return
false
}
async
function
httpRequest
(
file
,
callback
)
{
let
formData
=
new
FormData
()
formData
.
append
(
'fileUpload'
,
file
)
let
progress
=
0
axios
({
headers
:
headers
.
value
,
method
:
'post'
,
url
:
uploadFileUrl
.
value
,
data
:
formData
,
onUploadProgress
:
progressEvent
=>
{
// 获取文件上传进度 axios自带的
progress
=
(
progressEvent
.
loaded
/
progressEvent
.
total
*
100
)
|
0
callback
({
progress
,
status
:
'uploading'
})
}
}).
then
((
res
)
=>
{
// 成功状态
// console.log('res', res)
let
data
=
res
.
data
.
data
proxy
.
$emit
(
'uploadSuccessCallback'
,
data
)
if
(
props
.
uploadType
===
1
)
{
callback
({
progress
,
status
:
'success'
,
url
:
data
.
url
,
id
:
''
})
}
else
{
callback
({
progress
,
status
:
'success'
,
url
:
data
.
url
,
id
:
data
.
id
})
updateFileList
()
}
}).
catch
(()
=>
{
// 失败状态
callback
({
progress
,
status
:
'error'
})
})
}
function
showProgress
(
file
,
parms
)
{
const
{
progress
,
status
,
url
}
=
parms
const
arr
=
[...
FileList
.
value
].
map
(
items
=>
{
if
(
items
.
uid
===
file
.
uid
)
{
items
.
progress
=
progress
items
.
status
=
status
items
.
url
=
url
items
.
fileType
=
file
.
type
items
.
fileSize
=
file
.
size
items
.
createTime
=
parseTime
(
new
Date
(),
'{y}-{m}-{d} {h}:{i}:{s}'
)
items
.
id
=
parms
.
id
}
return
items
})
FileList
.
value
=
[...
arr
]
// updateFileList()
}
function
handleAvatarSuccess
(
response
,
uploadFile
)
{
console
.
log
(
response
)
console
.
log
(
uploadFile
)
}
function
handlePreviewFile
(
file
)
{
console
.
log
(
file
)
filePreview
(
file
.
url
)
}
function
handleDownFile
(
file
)
{
const
fileUrl
=
file
.
url
// 文件的URL地址
fetch
(
fileUrl
)
.
then
(
response
=>
response
.
blob
())
.
then
(
blob
=>
{
const
url
=
window
.
URL
.
createObjectURL
(
blob
)
const
link
=
document
.
createElement
(
'a'
)
link
.
href
=
url
link
.
setAttribute
(
'download'
,
file
.
name
)
document
.
body
.
appendChild
(
link
)
link
.
click
()
})
.
catch
(
error
=>
{
console
.
error
(
error
)
})
}
function
handleDeleteFile
(
index
)
{
FileList
.
value
.
splice
(
index
,
1
)
// updateFileList()
}
const
cancelEvent
=
()
=>
{
console
.
log
(
'cancel!'
)
}
</
script
>
<
template
>
<div
class=
"custom-upload-container"
v-loading=
"uploadLoading"
element-loading-text=
"文件上传中,请耐心等待,期间切勿进行任何操作,避免文件上传失败导致丢失。"
>
<el-upload
v-if=
"buttonPermission.indexOf('upload') >= 0"
:file-list=
"FileList"
:show-file-list=
"false"
class=
"upload-demo"
action=
"/"
drag
multiple
:before-upload=
"beforeUpload"
:on-success=
"handleAvatarSuccess"
:limit=
"limit"
:prompt=
"prompt"
>
<!--
<el-button
icon=
"Upload"
type=
"primary"
:loading=
"uploadLoading"
>
上传文件
</el-button>
-->
<div
class=
"upload-back"
>
<div
class=
"flex-container"
>
<!--
<img
class=
"logo-upload"
:src=
"logoUpload"
alt=
""
>
-->
<div>
<el-icon
:size=
"52"
color=
"rgb(51, 153, 255)"
>
<upload-filled
/>
</el-icon>
</div>
<div
class=
"text-container"
>
<div
class=
"accept-type-container"
>
{{
props
.
prompt
}}
</div>
</div>
</div>
</div>
</el-upload>
<el-row
style=
"padding-top: 8px;"
v-if=
"FileList&&FileList.length>0 && listShow"
>
<el-table
:data=
"FileList"
>
<el-table-column
type=
"index"
width=
"65"
align=
"center"
fixed=
"left"
label=
"序号"
/>
<el-table-column
prop=
"name"
align=
"left"
min-width=
"160"
:show-overflow-tooltip=
"true"
label=
"名称"
>
<template
v-slot=
"scope"
>
{{
scope
.
row
.
name
}}
</
template
>
</el-table-column>
<el-table-column
v-if=
"needType"
prop=
"fileType"
align=
"left"
:show-overflow-tooltip=
"true"
label=
"类型"
>
<
template
v-slot=
"scope"
>
{{
scope
.
row
.
fileType
}}
</
template
>
</el-table-column>
<el-table-column
v-if=
"needSize"
align=
"left"
width=
"140"
prop=
"fileSize"
label=
"大小(KB)"
>
<
template
v-slot=
"scope"
>
{{
Number
(
scope
.
row
.
fileSize
)
/
1000
}}
</
template
>
</el-table-column>
<el-table-column
v-if=
"needStatus"
align=
"center"
prop=
"name"
label=
"上传状态"
min-width=
"140"
>
<
template
v-slot=
"scope"
>
<template
v-if=
"scope.row.status === 'success' || scope.row.name || scope.row.url"
><el-tag
class=
"ml-2"
type=
"success"
>
上传成功
</el-tag></
template
>
<
template
v-else-if=
"scope.row.status === 'error'"
><el-tag
class=
"ml-2"
type=
"danger"
>
上传失败
</el-tag></
template
>
<el-progress
v-else
:percentage=
"scope.row.progress"
/>
</template>
</el-table-column>
<el-table-column
v-if=
"needTime"
align=
"left"
min-width=
"200"
prop=
"createTime"
label=
"上传时间"
/>
<el-table-column
align=
"center"
fixed=
"right"
label=
"操作"
width=
"200"
>
<
template
#
default=
"scope"
>
<el-button
link
icon=
"View"
type=
"primary"
size=
"small"
:disabled=
"scope.row.status === 'error' || scope.row.status === 'uploading'"
@
click=
"handlePreviewFile(scope.row)"
>
预览
</el-button>
<el-button
link
icon=
"Download"
type=
"primary"
size=
"small"
:disabled=
"scope.row.status === 'error' || scope.row.status === 'uploading'"
@
click=
"handleDownFile(scope.row)"
>
下载
</el-button>
<el-popconfirm
v-if=
"buttonPermission.indexOf('delete') >= 0"
confirm-button-text=
"确认"
cancel-button-text=
"取消"
icon-color=
"#626AEF"
title=
"确认删除?"
@
confirm=
"handleDeleteFile(scope.$index)"
@
cancel=
"cancelEvent"
>
<template
#
reference
>
<el-button
link
icon=
"Delete"
type=
"primary"
size=
"small"
:disabled=
"scope.row.status === 'uploading'"
>
删除
</el-button>
</
template
>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
</el-row>
</div>
</template>
<
style
lang=
"scss"
scoped
>
.custom-upload-container
{
width
:
100%
;
border-radius
:
8px
;
}
:deep
(
.el-upload
)
{
width
:
100%
;
.flex-container
{
display
:
flex
;
align-items
:
center
;
flex-direction
:
column
;
.text-container{
font-size
:
14px
;
color
:
rgb
(
188
,
195
,
203
);
}
}
}
.upload-demo
{
//
padding-top
:
24px
;
//
padding-bottom
:
16px
;
}
.upload-item
{
margin-left
:
5px
;
}
</
style
>
src/components/EditPop/ExpressionEditor.vue
View file @
c81064a3
...
...
@@ -73,11 +73,11 @@ const change = (val) => {
</div>
</div>
</div>
</
template
>
<
template
#
footer
>
<div
style=
"display: flex; justify-content: center; padding-top: 20px;"
>
<el-button
type=
"primary"
style=
"width: 150px;"
@
click=
"test"
>
测试
</el-button>
<el-button
type=
"info"
style=
"width: 150px;"
@
click=
"cancel"
>
取消
</el-button>
<el-button
type=
"primary"
style=
"width: 150px;"
@
click=
"confirm"
>
确认
</el-button>
</div>
</
template
>
</ModalPop>
</template>
...
...
src/components/EditPop/ModalPop.vue
View file @
c81064a3
...
...
@@ -22,18 +22,13 @@ const change = (visible: boolean) => {
</
script
>
<
template
>
<Modal
class=
"ModalPop"
v-model=
"props.modelValue"
:width=
"width"
draggable
scrollable
sticky
@
on-cancel=
"cancel"
@
on-visible-change=
"change"
>
<Modal
class=
"ModalPop"
footer-hide
:mask-closable=
"false"
v-model=
"props.modelValue"
:width=
"width"
draggable
scrollable
sticky
@
on-cancel=
"cancel"
@
on-visible-change=
"change"
>
<template
#
header
>
<span
style=
"font-size: 16px; font-weight: bold;color: #7A8495;"
>
{{
props
.
title
}}
</span>
</
template
>
<div
class=
"slot-warpper"
>
<slot
name=
"content"
></slot>
</div>
<
template
#
footer
>
<div
style=
"display: flex; justify-content: center; padding-top: 20px;"
>
<slot
name=
"footer"
></slot>
</div>
</
template
>
</Modal>
</template>
...
...
@@ -59,7 +54,7 @@ const change = (visible: boolean) => {
background
:
rgb
(
255
,
255
,
255
);
padding
:
30px
;
border-radius
:
4px
;
max-height
:
5
0
0px
;
max-height
:
5
5
0px
;
}
}
</
style
>
\ No newline at end of file
src/views/ruleConfig/Dictionary/index.vue
View file @
c81064a3
...
...
@@ -5,6 +5,7 @@ import { Split } from 'view-ui-plus';
import
ModalPop
from
"@/components/EditPop/ModalPop.vue"
import
AddClass
from
'./modules/AddClass.vue'
// 分类
import
AddValue
from
'./modules/AddValue.vue'
// 值
import
uploadModule
from
'./modules/uploadModule.vue'
// 上传模块
const
splitNum
=
ref
(
0.31
)
// 左右分割比例
...
...
@@ -28,7 +29,7 @@ const modalData = reactive({
show
:
false
,
text
:
''
,
icon
:
'error'
,
cancel
:
tru
e
,
cancel
:
fals
e
,
type
:
''
})
...
...
@@ -96,7 +97,6 @@ const addValueClick = (type, item) => {
const
valueDelete
=
(
item
)
=>
{
console
.
log
(
'删除值'
,
item
)
modalData
.
type
=
'value'
modalData
.
cancel
=
true
modalData
.
icon
=
'error'
modalData
.
text
=
'删除后无法恢复,是否确认删除['
+
item
.
name
+
']?'
modalData
.
show
=
true
...
...
@@ -106,7 +106,6 @@ const valueDelete = (item) => {
const
classDelete
=
(
item
)
=>
{
console
.
log
(
'删除分类事件'
,
item
)
modalData
.
type
=
'class'
modalData
.
cancel
=
false
modalData
.
icon
=
'error'
modalData
.
text
=
'删除后无法恢复,是否确认删除['
+
item
.
name
+
']?'
modalData
.
show
=
true
...
...
@@ -133,10 +132,19 @@ const AddDomainConfirm = (item) => {
console
.
log
(
'新增分类确认'
,
item
)
}
else
if
(
modalPopData
.
type
===
'value'
)
{
console
.
log
(
'新增值确认'
,
item
)
}
else
if
(
modalPopData
.
type
===
'upload'
)
{
console
.
log
(
'导入'
,
item
)
}
modalPopData
.
show
=
false
}
// 导入功能
const
importClick
=
()
=>
{
modalPopData
.
title
=
'上传文件'
modalPopData
.
type
=
'upload'
modalPopData
.
show
=
true
}
// 获取列表数据
const
getList
=
()
=>
{
...
...
@@ -189,7 +197,7 @@ onMounted(() => {
</el-input>
</el-form-item>
<div
style=
"display: flex;"
>
<el-button
icon=
"Upload"
type=
"primary"
>
导入
</el-button>
<el-button
icon=
"Upload"
type=
"primary"
@
click=
"importClick"
>
导入
</el-button>
<el-button
icon=
"Download"
type=
"success"
>
导出
</el-button>
<el-button
icon=
"Plus"
type=
"primary"
@
click=
"addValueClick('add')"
>
新增值
</el-button>
</div>
...
...
@@ -232,6 +240,7 @@ onMounted(() => {
v-if=
"modalPopData.type === 'class'"
/>
<AddValue
v-model=
"addValueForm"
:type=
"modalPopData.operation"
@
cancel=
"modalPopCancel"
@
confirm=
"AddDomainConfirm"
v-if=
"modalPopData.type === 'value'"
/>
<uploadModule
@
cancel=
"modalPopCancel"
@
confirm=
"AddDomainConfirm"
v-if=
"modalPopData.type === 'upload'"
/>
</
template
>
</ModalPop>
</div>
...
...
src/views/ruleConfig/Dictionary/modules/UploadModule.vue
0 → 100644
View file @
c81064a3
<
script
setup
lang=
"ts"
name=
"AddClass"
>
import
{
ref
}
from
"vue"
;
import
CustomUpload
from
"@/components/CustomUpload/index.vue"
const
emit
=
defineEmits
([
"update:modelValue"
,
"cancel"
,
"confirm"
]);
const
radioValue
=
ref
(
1
);
const
fileList
=
ref
<
File
[]
>
([]);
// 取消
const
cancel
=
()
=>
{
emit
(
"cancel"
);
};
// 确认
const
confirm
=
()
=>
{
console
.
log
(
fileList
.
value
);
// emit("confirm");
};
const
handleUpload
=
(
file
:
File
)
=>
{
console
.
log
(
file
);
// 上传文件
// 处理上传结果
// 更新modelValue
};
</
script
>
<
template
>
<div>
<div
class=
"mb20"
>
<CustomUpload
v-model:file-list=
"fileList"
:limit=
"1"
:needType=
"false"
:needSize=
"false"
:listShow=
"false"
prompt=
'点击或拖拽文件到此处上传'
/>
</div>
<el-form-item
label=
"上传方式"
label-width=
"200px"
>
<el-radio-group
v-model=
"radioValue"
>
<el-radio
:label=
"1"
>
覆盖原数据
</el-radio>
<el-radio
:label=
"2"
>
追加数据
</el-radio>
</el-radio-group>
</el-form-item>
<div
class=
"btn"
>
<el-button
type=
"info"
style=
"width: 150px;"
@
click=
"cancel"
>
取消
</el-button>
<el-button
type=
"primary"
style=
"width: 150px;"
@
click=
"confirm"
>
确认
</el-button>
</div>
</div>
</
template
>
<
style
lang=
"scss"
scoped
>
.btn
{
padding
:
20px
;
display
:
flex
;
justify-content
:
center
;
}
</
style
>
\ No newline at end of file
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论