Files
jnpf_app/pages/workFlow/comment/comment-file/lsj-upload/lsj-upload.vue

401 lines
8.2 KiB
Vue
Raw Normal View History

2026-01-04 11:09:06 +08:00
<template>
<view class="lsj-file" :style="[getStyles]">
<view ref="lsj" class="hFile" :style="[getStyles]" @click="onClick">
<slot>
<view class="defview" :style="[getStyles]">附件上传</view>
</slot>
</view>
</view>
</template>
<script>
// 查看文档https://ext.dcloud.net.cn/plugin?id=5459
import {
LsjFile
} from './LsjFile.js'
export default {
name: 'comment-Lsj-upload',
props: {
currentCount: {
type: Number,
default: 0
},
// 打印日志
debug: {
type: Boolean,
default: false
},
// 自动上传
instantly: {
type: Boolean,
default: false
},
// 上传接口参数设置
option: {
type: Object,
default: () => {}
},
// 文件大小上限
size: {
type: Number,
default: 10
},
// 文件选择个数上限,超出后不触发点击
count: {
type: Number,
default: 2000
},
// 是否允许多选文件
multiple: {
type: Boolean,
default: true
},
// 允许上传的文件格式(多个以逗号隔开)
formats: {
type: String,
default: ''
},
// input file选择限制
accept: {
type: String,
default: ''
},
// 微信选择文件类型
//all=从所有文件选择,
//video=只能选择视频文件,
//image=只能选择图片文件,
//file=可以选择除了图片和视频之外的其它的文件
wxFileType: {
type: String,
default: 'all'
},
// webviewID需唯一不同窗口也不要同Id
childId: {
type: String,
default: 'lsjUpload'
},
// 文件选择触发面宽度
width: {
type: String,
default: '100%'
},
// 文件选择触发面高度
height: {
type: String,
default: '80rpx'
},
// top,left,bottom,right仅position=absolute时才需要传入
top: {
type: [String, Number],
default: ''
},
left: {
type: [String, Number],
default: ''
},
bottom: {
type: [String, Number],
default: ''
},
right: {
type: [String, Number],
default: ''
},
// nvue不支持跟随窗口滚动
position: {
type: String,
// #ifdef APP-NVUE
default: 'absolute',
// #endif
// #ifndef APP-NVUE
default: 'static',
// #endif
},
},
data() {
return {
}
},
watch: {
option(v) {
// #ifdef APP-PLUS
2026-01-19 17:34:15 +08:00
console.log(v,'v--------')
2026-01-04 11:09:06 +08:00
this.lsjFile && this.show();
// #endif
}
},
updated() {
// #ifdef APP-PLUS
if (this.isShow) {
this.lsjFile && this.show();
}
// #endif
},
computed: {
getStyles() {
let styles = {
width: this.width,
height: this.height
}
if (this.position == 'absolute') {
styles['top'] = this.top
styles['bottom'] = this.bottom
styles['left'] = this.left
styles['right'] = this.right
styles['position'] = 'fixed'
}
return styles
}
},
mounted() {
this._size = 0;
let WEBID = this.childId + new Date().getTime();
this.lsjFile = new LsjFile({
id: WEBID,
debug: this.debug,
width: this.width,
height: this.height,
option: this.option,
instantly: this.instantly,
// 限制条件
prohibited: {
// 大小
size: this.size,
// 允许上传的格式
formats: this.formats,
// 限制选择的格式
accept: this.accept,
count: this.count,
// 是否多选
multiple: this.multiple,
},
onchange: this.onchange,
onprogress: this.onprogress,
});
this.create();
// 需判断是否当前页显示
uni.$on('lsjShow', this.show);
},
beforeDestroy() {
uni.$off('lsjShow', this.show);
// #ifdef APP-PLUS
this.lsjFile.dom.close();
// #endif
},
methods: {
setFiles(array) {
if (array instanceof Map) {
for (let [key, item] of array) {
item['progress'] = 100;
item['type'] = 'success';
this.lsjFile.files.set(key, item);
}
} else if (Array.isArray(array)) {
array.forEach(item => {
if (item.name) {
item['progress'] = 100;
item['type'] = 'success';
this.lsjFile.files.set(item.name, item);
}
});
}
this.onchange(this.lsjFile.files);
},
setData() {
this.lsjFile && this.lsjFile.setData(...arguments);
},
getDomStyles(callback) {
// #ifndef APP-NVUE
let view = uni
.createSelectorQuery()
.in(this)
.select('.lsj-file')
view.fields({
size: true,
rect: true
},
({
height,
width,
top,
left,
right,
bottom
}) => {
uni.createSelectorQuery()
.selectViewport()
.scrollOffset(({
scrollTop
}) => {
return callback({
top: parseInt(top) + parseInt(scrollTop) + 'px',
left: parseInt(left) + 'px',
width: parseInt(width) + 'px',
height: parseInt(height) + 'px'
})
})
.exec()
}
).exec()
// #endif
// #ifdef APP-NVUE
const dom = weex.requireModule('dom')
dom.getComponentRect(this.$refs.lsj, ({
size: {
height,
width,
top,
left,
right,
bottom
}
}) => {
return callback({
top: parseInt(top) + 'px',
left: parseInt(left) + 'px',
width: parseInt(width) + 'px',
height: parseInt(height) + 'px',
right: parseInt(right) + 'px',
bottom: parseInt(bottom) + 'px'
})
})
// #endif
},
show() {
if (this._size && (this._size >= this.count)) {
return;
}
this.isShow = true;
// #ifdef APP-PLUS
this.lsjFile && this.getDomStyles(styles => {
this.lsjFile.dom.setStyle(styles)
});
// #endif
// #ifdef H5
this.lsjFile.dom.style.display = 'inline'
// #endif
},
hide() {
this.isShow = false;
// #ifdef APP-PLUS
this.lsjFile && this.lsjFile.dom.setStyle({
top: '-100px',
left: '0px',
width: '1px',
height: '100px',
});
// #endif
// #ifdef H5
this.lsjFile.dom.style.display = 'none'
// #endif
},
/**
* 手动提交上传
* @param {string}name 文件名称不传则上传所有type等于waiting和fail的文件
*/
upload(name) {
this.lsjFile && this.lsjFile.upload(name);
},
/**
* @returns {Map} 已选择的文件Map集
*/
onchange(files) {
// this.$emit('change',files);
this._size = files.size;
return files.size >= this.count ? this.hide() : this.show();
},
/**
* @returns {object} 当前上传中的对象
*/
onprogress(item, end = false) {
this.$emit('progress', item);
if (end) {
setTimeout(() => {
this.$emit('uploadEnd', item);
}, 0);
}
},
/**
* 移除组件内缓存的某条数据
* @param {string}name 文件名称,不指定默认清除所有文件
*/
clear(name) {
this.lsjFile.clear(name);
},
// 创建选择器
create() {
// 若iOS端服务端处理不了跨域就将hybrid目录内的html放到服务端去并将此处path改成服务器上的地址
let path = '/uni_modules/lsj-upload/hybrid/html/uploadFile.html?sourceflag=comment';
let dom = this.lsjFile.create(path);
// #ifdef H5
this.$refs.lsj.$el.appendChild(dom);
// #endif
// #ifndef APP-PLUS
this.show();
// #endif
// #ifdef APP-PLUS
dom.setStyle({
position: this.position
});
dom.loadURL(path);
setTimeout(() => {
// #ifdef APP-NVUE
plus.webview.currentWebview().append(dom);
// #endif
// #ifndef APP-NVUE
this.$root.$scope.$getAppWebview().append(dom);
// #endif
this.show();
}, 300)
// #endif
},
// 点击选择附件
onClick() {
/*if (this.currentCount >= 9) {
this.toast(`最多可以上传9个文件`);
return;
}*/
// #ifdef MP-WEIXIN
if (!this.isShow) {
return;
}
let count = this.count - this._size;
this.lsjFile.chooseMessageFile(this.wxFileType, count);
// #endif
},
toast(msg) {
uni.showToast({
title: msg,
icon: 'none'
});
}
}
}
</script>
<style scoped>
.lsj-file {
display: inline-block;
}
.defview {
background-color: #007aff;
color: #fff;
border-radius: 10rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 28rpx;
}
.hFile {
position: relative;
overflow: hidden;
}
</style>