Merge branch 'gyj' of SH-Arbitrate/miniapp into dev
This commit was merged in pull request #35.
This commit is contained in:
@@ -153,6 +153,12 @@
|
|||||||
batchNumber:"",
|
batchNumber:"",
|
||||||
caseFlowId:this.defalutVal.caseFlowId
|
caseFlowId:this.defalutVal.caseFlowId
|
||||||
}
|
}
|
||||||
|
uni.showModal({
|
||||||
|
title: '提示',
|
||||||
|
content: '您确定要提交案件',
|
||||||
|
success: function (res) {
|
||||||
|
if (res.confirm) {
|
||||||
|
// console.log('用户点击确定');
|
||||||
caseAppSubmit(onsubmitVal).then(res => {
|
caseAppSubmit(onsubmitVal).then(res => {
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: '提交成功',
|
title: '提交成功',
|
||||||
@@ -162,8 +168,12 @@
|
|||||||
uni.navigateTo({
|
uni.navigateTo({
|
||||||
url:'/pages/handlecase/index'
|
url:'/pages/handlecase/index'
|
||||||
})
|
})
|
||||||
//this.$emit("getList");
|
|
||||||
})
|
})
|
||||||
|
} else if (res.cancel) {
|
||||||
|
// console.log('用户点击取消');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
},
|
},
|
||||||
// 修改
|
// 修改
|
||||||
modify() {
|
modify() {
|
||||||
@@ -178,6 +188,12 @@
|
|||||||
batchNumber:"",
|
batchNumber:"",
|
||||||
caseFlowId:this.defalutVal.caseFlowId
|
caseFlowId:this.defalutVal.caseFlowId
|
||||||
}
|
}
|
||||||
|
uni.showModal({
|
||||||
|
title: '提示',
|
||||||
|
content: '您确定要删除案件',
|
||||||
|
success: function (res) {
|
||||||
|
if (res.confirm) {
|
||||||
|
// console.log('用户点击确定');
|
||||||
caseDelete(objValue).then(res =>{
|
caseDelete(objValue).then(res =>{
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: '删除成功',
|
title: '删除成功',
|
||||||
@@ -188,6 +204,12 @@
|
|||||||
url:'/pages/handlecase/index'
|
url:'/pages/handlecase/index'
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
} else if (res.cancel) {
|
||||||
|
// console.log('用户点击取消');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
|||||||
@@ -385,7 +385,7 @@
|
|||||||
uni.navigateBack({
|
uni.navigateBack({
|
||||||
delta: 1
|
delta: 1
|
||||||
})
|
})
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
onLoad(data) {
|
onLoad(data) {
|
||||||
this.ids = data.id
|
this.ids = data.id
|
||||||
|
|||||||
@@ -0,0 +1,114 @@
|
|||||||
|
## 2.2.9(2023-06-01)
|
||||||
|
优化:将是否多选与count字段解绑(原逻辑是count>1为允许多选),改为新增multiple属性控制是否多选。
|
||||||
|
## 2.2.8(2023-06-01)
|
||||||
|
修复上版本提交时accept测试值未删除导致h5端只能选择图片的问题。
|
||||||
|
## 2.2.7(2023-05-06)
|
||||||
|
应群友建议,当instantly为true时,触发change事件后延迟1000毫秒再自动上传,方便动态修改参数,其实个人还是建议想在change事件动态设置参数的伙伴将instantly设置为false,修改参数后手动调用upload()
|
||||||
|
## 2.2.6(2023-02-09)
|
||||||
|
修复多个文件同时选择时返回多次change回调的问题
|
||||||
|
## 2.2.5(2022-12-27)
|
||||||
|
1.修复多选文件时未能正常校验数量的问题;
|
||||||
|
2.app端与H5端支持单选或多选文件,通过count数量控制,超过1开启多选。
|
||||||
|
## 2.2.4(2022-12-27)
|
||||||
|
1.修复多选文件时未能正常校验数量的问题;
|
||||||
|
2.app端修复多选只取到第一个文件的问题。
|
||||||
|
## 2.2.3(2022-12-06)
|
||||||
|
修复手动调用show()导致count失效的问题
|
||||||
|
## 2.2.2(2022-12-01)
|
||||||
|
Vue3自行修改兼容
|
||||||
|
## 2.2.1(2022-10-19)
|
||||||
|
修复childId警告提示
|
||||||
|
## 2.2.0(2022-10-10)
|
||||||
|
更新app端webview窗口参数clidId,默认值添加时间戳保证唯一性
|
||||||
|
## 2.1.9(2022-07-13)
|
||||||
|
[修复] app端选择文件后初始化设置的文件列表被清空问题
|
||||||
|
## 2.1.8(2022-07-13)
|
||||||
|
[新增] ref方法初始化文件列表,用于已提交后再次编辑时需带入已上传文件:setFiles(files),可传入数组或Map对象,传入格式请与组件选择返回格式保持一致,且name为必须属性。
|
||||||
|
## 2.1.7(2022-07-12)
|
||||||
|
修复ios端偶现创建webview初始化参数未生效的问题
|
||||||
|
## 2.1.6(2022-07-11)
|
||||||
|
[修复]:修复上个版本更新导致nvue窗口组件不能选择文件的问题;
|
||||||
|
[新增]:
|
||||||
|
1.应群友建议(填写禁止格式太多)格式限制formats由原来填写禁止选择的格式改为填写允许被选择的格式;
|
||||||
|
2.应群友建议(增加上传结束回调事件),上传结束回调事件@uploadEnd
|
||||||
|
3.如能帮到你请留下你的免费好评,组件使用过程中有问题可以加QQ群交流,至于Map对象怎么使用这类前端基础问题请自行百度
|
||||||
|
## 2.1.5(2022-07-01)
|
||||||
|
app端组件销毁时添加自动销毁webview功能,避免v-if销毁组件的情况控件还能被点击的问题
|
||||||
|
## 2.1.4(2022-07-01)
|
||||||
|
修复小程序端回显问题
|
||||||
|
## 2.1.3(2022-06-30)
|
||||||
|
回调事件返回参数新增path字段(文件临时地址),用于回显
|
||||||
|
## 2.1.2(2022-06-16)
|
||||||
|
修复APP端Tabbar窗口无法选择文件的问题
|
||||||
|
## 2.1.1(2022-06-16)
|
||||||
|
优化:
|
||||||
|
1.组件优化为允许在v-if中使用;
|
||||||
|
2.允许option直接在data赋值,不再强制在onRead中初始化;
|
||||||
|
## 2.1.0(2022-06-13)
|
||||||
|
h5 pc端更改为单次可多选
|
||||||
|
## 2.0.9(2022-06-10)
|
||||||
|
更新演示内容,部分同学不知道怎么获取服务端返回的数据
|
||||||
|
## 2.0.8(2022-06-09)
|
||||||
|
优化动态更新上传参数函数,具体查看下方说明:动态更新参数演示
|
||||||
|
## 2.0.7(2022-06-07)
|
||||||
|
新增wxFileType属性,用于小程序端选择附件时可选文件类型
|
||||||
|
## 2.0.6(2022-06-07)
|
||||||
|
修复小程序端真机选择文件提示失败的问题
|
||||||
|
## 2.0.5(2022-06-02)
|
||||||
|
优化小程序端调用hide()后未阻止触发文件选择问题
|
||||||
|
## 2.0.4(2022-06-01)
|
||||||
|
优化APP端选择器初始定位
|
||||||
|
## 2.0.3(2022-05-31)
|
||||||
|
修复nvue窗口选择文件报错问题
|
||||||
|
## 2.0.2(2022-05-20)
|
||||||
|
修复ios端opiton设置过早未传入webview导致不自动上传问题
|
||||||
|
## 2.0.1(2022-05-19)
|
||||||
|
修复APP端子窗口点击选择文件不响应问题
|
||||||
|
## 2.0.0(2022-05-18)
|
||||||
|
此次组件更新至2.0版本,与1.0版本使用上略有差异,已使用1.0的同学请自行斟酌是否需要升级!
|
||||||
|
部分差异:
|
||||||
|
一、 2.0新增异步触发上传功能;
|
||||||
|
二、2.0新增文件批量上传功能;
|
||||||
|
三、2.0优化option,剔除属性,只保留上传接口所需字段,且允许异步更改option的值;
|
||||||
|
四、组件增加size(文件大小限制)、count(文件个数限制)、formats(文件后缀限制)、accept(文件类型限制)、instantly(是否立即自动上传)、debug(日志打印)等属性;
|
||||||
|
五、回调事件取消input事件、callback事件,新增change事件和progress事件;
|
||||||
|
六、ref事件新增upload事件、clear事件;
|
||||||
|
七、优化组件代码,show和hide函数改为显示隐藏,不再重复开关webview;
|
||||||
|
|
||||||
|
## 1.2.3(2022-03-22)
|
||||||
|
修复Demo里传入待完善功能[手动上传属性manual=true]导致不自动上传的问题,手动提交上传待下个版本更新
|
||||||
|
## 1.2.2(2022-02-21)
|
||||||
|
修复上版本APP优化导致H5和小程序端不自动初始化的问题,此次更新仅修复此问题。异步提交功能下个版本更新~
|
||||||
|
## 1.2.1(2022-01-25)
|
||||||
|
QQ1群已满,已开放2群:469580165
|
||||||
|
## 1.2.0(2021-12-09)
|
||||||
|
优化APP端页面中DOM重排后每次需要重新定位的问题
|
||||||
|
## 1.1.1(2021-12-09)
|
||||||
|
优化,与上版本使用方式有改变,请检查后确认是否需要更新,create更名为show, close更名为hide,取消初始化时手动create, 传参方式改为props=>option
|
||||||
|
## 1.1.0(2021-12-09)
|
||||||
|
新增refresh方法,用于DOM发生重排时重新定位控件(APP端)
|
||||||
|
## 1.0.9(2021-07-15)
|
||||||
|
修复上传进度未同步渲染,直接返回100%的BUG
|
||||||
|
## 1.0.8(2021-07-12)
|
||||||
|
修复H5端传入height和width未生效的bug
|
||||||
|
## 1.0.7(2021-07-07)
|
||||||
|
修复h5和小程序端上传完成callback未返回fileName字段问题
|
||||||
|
## 1.0.6(2021-07-07)
|
||||||
|
修复h5端提示信息debug
|
||||||
|
## 1.0.5(2021-06-29)
|
||||||
|
感谢小伙伴找出bug,上传成功回调success未置为true,已修复
|
||||||
|
## 1.0.4(2021-06-28)
|
||||||
|
新增兼容APP,H5,小程序手动关闭控件,关闭后不再弹出文件选择框,需要重新create再次开启
|
||||||
|
## 1.0.3(2021-06-28)
|
||||||
|
close增加条件编译,除app端外不需要close
|
||||||
|
## 1.0.2(2021-06-28)
|
||||||
|
1.修复页面滚动位置后再create控件导致控件位置不正确的问题;
|
||||||
|
2.修复nvue无法create控件;
|
||||||
|
3.示例项目新增nvue使用案例;
|
||||||
|
## 1.0.1(2021-06-28)
|
||||||
|
因为有的朋友不清楚app端切换tab时应该怎么处理webview,现重新上传一版示例项目,需要做tab切换的朋友可以导入示例项目查看
|
||||||
|
## 1.0.0(2021-06-25)
|
||||||
|
此插件为l-file插件中上传功能改版,更新内容为:
|
||||||
|
1. 按钮内嵌入页面,不再强制固定底部,可跟随页面滚动
|
||||||
|
2.无需再单独弹框点击上传,减去中间层
|
||||||
|
3.通过slot自定义按钮样式
|
||||||
@@ -0,0 +1,401 @@
|
|||||||
|
export class LsjFile {
|
||||||
|
constructor(data) {
|
||||||
|
this.dom = null;
|
||||||
|
// files.type = waiting(等待上传)|| loading(上传中)|| success(成功) || fail(失败)
|
||||||
|
this.files = new Map();
|
||||||
|
this.debug = data.debug || false;
|
||||||
|
this.id = data.id;
|
||||||
|
this.width = data.width;
|
||||||
|
this.height = data.height;
|
||||||
|
this.option = data.option;
|
||||||
|
this.instantly = data.instantly;
|
||||||
|
this.prohibited = data.prohibited;
|
||||||
|
this.onchange = data.onchange;
|
||||||
|
this.onprogress = data.onprogress;
|
||||||
|
this.uploadHandle = this._uploadHandle;
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
this.uploadHandle = this._uploadHandleWX;
|
||||||
|
// #endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建File节点
|
||||||
|
* @param {string}path webview地址
|
||||||
|
*/
|
||||||
|
create(path) {
|
||||||
|
if (!this.dom) {
|
||||||
|
// #ifdef H5
|
||||||
|
let dom = document.createElement('input');
|
||||||
|
dom.type = 'file'
|
||||||
|
dom.value = ''
|
||||||
|
dom.style.height = this.height
|
||||||
|
dom.style.width = this.width
|
||||||
|
dom.style.position = 'absolute'
|
||||||
|
dom.style.top = 0
|
||||||
|
dom.style.left = 0
|
||||||
|
dom.style.right = 0
|
||||||
|
dom.style.bottom = 0
|
||||||
|
dom.style.opacity = 0
|
||||||
|
dom.style.zIndex = 999
|
||||||
|
dom.accept = this.prohibited.accept;
|
||||||
|
if (this.prohibited.multiple) {
|
||||||
|
dom.multiple = 'multiple';
|
||||||
|
}
|
||||||
|
dom.onchange = event => {
|
||||||
|
for (let file of event.target.files) {
|
||||||
|
if (this.files.size >= this.prohibited.count) {
|
||||||
|
this.toast(`只允许上传${this.prohibited.count}个文件`);
|
||||||
|
this.dom.value = '';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.addFile(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._uploadAfter();
|
||||||
|
|
||||||
|
this.dom.value = '';
|
||||||
|
};
|
||||||
|
this.dom = dom;
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #ifdef APP-PLUS
|
||||||
|
let styles = {
|
||||||
|
top: '-200px',
|
||||||
|
left: 0,
|
||||||
|
width: '1px',
|
||||||
|
height: '200px',
|
||||||
|
background: 'transparent'
|
||||||
|
};
|
||||||
|
let extras = {
|
||||||
|
debug: this.debug,
|
||||||
|
instantly: this.instantly,
|
||||||
|
prohibited: this.prohibited,
|
||||||
|
}
|
||||||
|
this.dom = plus.webview.create(path, this.id, styles,extras);
|
||||||
|
this.setData(this.option);
|
||||||
|
this._overrideUrlLoading();
|
||||||
|
// #endif
|
||||||
|
return this.dom;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置上传参数
|
||||||
|
* @param {object|string}name 上传参数,支持a.b 和 a[b]
|
||||||
|
*/
|
||||||
|
setData() {
|
||||||
|
let [name,value = ''] = arguments;
|
||||||
|
if (typeof name === 'object') {
|
||||||
|
Object.assign(this.option,name);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this._setValue(this.option,name,value);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.debug&&console.log(JSON.stringify(this.option));
|
||||||
|
|
||||||
|
// #ifdef APP-PLUS
|
||||||
|
this.dom.evalJS(`vm.setData('${JSON.stringify(this.option)}')`);
|
||||||
|
// #endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传
|
||||||
|
* @param {string}name 文件名称
|
||||||
|
*/
|
||||||
|
async upload(name='') {
|
||||||
|
if (!this.option.url) {
|
||||||
|
throw Error('未设置上传地址');
|
||||||
|
}
|
||||||
|
|
||||||
|
// #ifndef APP-PLUS
|
||||||
|
if (name && this.files.has(name)) {
|
||||||
|
await this.uploadHandle(this.files.get(name));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (let item of this.files.values()) {
|
||||||
|
if (item.type === 'waiting' || item.type === 'fail') {
|
||||||
|
await this.uploadHandle(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #ifdef APP-PLUS
|
||||||
|
this.dom&&this.dom.evalJS(`vm.upload('${name}')`);
|
||||||
|
// #endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// 选择文件change
|
||||||
|
addFile(file,isCallChange) {
|
||||||
|
|
||||||
|
let name = file.name;
|
||||||
|
this.debug&&console.log('文件名称',name,'大小',file.size);
|
||||||
|
|
||||||
|
if (file) {
|
||||||
|
// 限制文件格式
|
||||||
|
let path = '';
|
||||||
|
let suffix = name.substring(name.lastIndexOf(".")+1).toLowerCase();
|
||||||
|
let formats = this.prohibited.formats.toLowerCase();
|
||||||
|
|
||||||
|
|
||||||
|
// #ifndef MP-WEIXIN
|
||||||
|
path = URL.createObjectURL(file);
|
||||||
|
// #endif
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
path = file.path;
|
||||||
|
// #endif
|
||||||
|
if (formats&&!formats.includes(suffix)) {
|
||||||
|
this.toast(`不支持上传${suffix.toUpperCase()}格式文件`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// 限制文件大小
|
||||||
|
if (file.size > 1024 * 1024 * Math.abs(this.prohibited.size)) {
|
||||||
|
this.toast(`附件大小请勿超过${this.prohibited.size}M`)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
this.files.set(file.name,{file,path,name: file.name,size: file.size,progress: 0,type: 'waiting'});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 移除文件
|
||||||
|
* @param {string}name 不传name默认移除所有文件,传入name移除指定name的文件
|
||||||
|
*/
|
||||||
|
clear(name='') {
|
||||||
|
// #ifdef APP-PLUS
|
||||||
|
this.dom&&this.dom.evalJS(`vm.clear('${name}')`);
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
if (!name) {
|
||||||
|
this.files.clear();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.files.delete(name);
|
||||||
|
}
|
||||||
|
return this.onchange(this.files);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 提示框
|
||||||
|
* @param {string}msg 轻提示内容
|
||||||
|
*/
|
||||||
|
toast(msg) {
|
||||||
|
uni.showToast({
|
||||||
|
title: msg,
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信小程序选择文件
|
||||||
|
* @param {number}count 可选择文件数量
|
||||||
|
*/
|
||||||
|
chooseMessageFile(type,count) {
|
||||||
|
wx.chooseMessageFile({
|
||||||
|
count: count,
|
||||||
|
type: type,
|
||||||
|
success: ({ tempFiles }) => {
|
||||||
|
for (let file of tempFiles) {
|
||||||
|
this.addFile(file);
|
||||||
|
}
|
||||||
|
this._uploadAfter();
|
||||||
|
},
|
||||||
|
fail: (e) => {
|
||||||
|
this.toast(`打开失败`);
|
||||||
|
console.log(e)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
_copyObject(obj) {
|
||||||
|
if (typeof obj !== "undefined") {
|
||||||
|
return JSON.parse(JSON.stringify(obj));
|
||||||
|
} else {
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自动根据字符串路径设置对象中的值 支持.和[]
|
||||||
|
* @param {Object} dataObj 数据源
|
||||||
|
* @param {String} name 支持a.b 和 a[b]
|
||||||
|
* @param {String} value 值
|
||||||
|
* setValue(dataObj, name, value);
|
||||||
|
*/
|
||||||
|
_setValue(dataObj, name, value) {
|
||||||
|
// 通过正则表达式 查找路径数据
|
||||||
|
let dataValue;
|
||||||
|
if (typeof value === "object") {
|
||||||
|
dataValue = this._copyObject(value);
|
||||||
|
} else {
|
||||||
|
dataValue = value;
|
||||||
|
}
|
||||||
|
let regExp = new RegExp("([\\w$]+)|\\[(:\\d)\\]", "g");
|
||||||
|
const patten = name.match(regExp);
|
||||||
|
// 遍历路径 逐级查找 最后一级用于直接赋值
|
||||||
|
for (let i = 0; i < patten.length - 1; i++) {
|
||||||
|
let keyName = patten[i];
|
||||||
|
if (typeof dataObj[keyName] !== "object") dataObj[keyName] = {};
|
||||||
|
dataObj = dataObj[keyName];
|
||||||
|
}
|
||||||
|
// 最后一级
|
||||||
|
dataObj[patten[patten.length - 1]] = dataValue;
|
||||||
|
this.debug&&console.log('参数更新后',JSON.stringify(this.option));
|
||||||
|
}
|
||||||
|
|
||||||
|
_uploadAfter() {
|
||||||
|
this.onchange(this.files);
|
||||||
|
setTimeout(()=>{
|
||||||
|
this.instantly&&this.upload();
|
||||||
|
},1000)
|
||||||
|
}
|
||||||
|
|
||||||
|
_overrideUrlLoading() {
|
||||||
|
this.dom.overrideUrlLoading({ mode: 'reject' }, e => {
|
||||||
|
let {retype,item,files,end} = this._getRequest(
|
||||||
|
e.url
|
||||||
|
);
|
||||||
|
let _this = this;
|
||||||
|
switch (retype) {
|
||||||
|
case 'updateOption':
|
||||||
|
this.dom.evalJS(`vm.setData('${JSON.stringify(_this.option)}')`);
|
||||||
|
break
|
||||||
|
case 'change':
|
||||||
|
try {
|
||||||
|
_this.files = new Map([..._this.files,...JSON.parse(unescape(files))]);
|
||||||
|
} catch (e) {
|
||||||
|
return console.error('出错了,请检查代码')
|
||||||
|
}
|
||||||
|
_this.onchange(_this.files);
|
||||||
|
break
|
||||||
|
case 'progress':
|
||||||
|
try {
|
||||||
|
item = JSON.parse(unescape(item));
|
||||||
|
} catch (e) {
|
||||||
|
return console.error('出错了,请检查代码')
|
||||||
|
}
|
||||||
|
_this._changeFilesItem(item,end);
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
_getRequest(url) {
|
||||||
|
let theRequest = new Object()
|
||||||
|
let index = url.indexOf('?')
|
||||||
|
if (index != -1) {
|
||||||
|
let str = url.substring(index + 1)
|
||||||
|
let strs = str.split('&')
|
||||||
|
for (let i = 0; i < strs.length; i++) {
|
||||||
|
theRequest[strs[i].split('=')[0]] = unescape(strs[i].split('=')[1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return theRequest
|
||||||
|
}
|
||||||
|
|
||||||
|
_changeFilesItem(item,end=false) {
|
||||||
|
this.debug&&console.log('onprogress',JSON.stringify(item));
|
||||||
|
this.onprogress(item,end);
|
||||||
|
this.files.set(item.name,item);
|
||||||
|
}
|
||||||
|
|
||||||
|
_uploadHandle(item) {
|
||||||
|
item.type = 'loading';
|
||||||
|
delete item.responseText;
|
||||||
|
return new Promise((resolve,reject)=>{
|
||||||
|
this.debug&&console.log('option',JSON.stringify(this.option));
|
||||||
|
let {url,name,method='POST',header,formData} = this.option;
|
||||||
|
let form = new FormData();
|
||||||
|
for (let keys in formData) {
|
||||||
|
form.append(keys, formData[keys])
|
||||||
|
}
|
||||||
|
form.append(name, item.file);
|
||||||
|
let xmlRequest = new XMLHttpRequest();
|
||||||
|
xmlRequest.open(method, url, true);
|
||||||
|
for (let keys in header) {
|
||||||
|
xmlRequest.setRequestHeader(keys, header[keys])
|
||||||
|
}
|
||||||
|
|
||||||
|
xmlRequest.upload.addEventListener(
|
||||||
|
'progress',
|
||||||
|
event => {
|
||||||
|
if (event.lengthComputable) {
|
||||||
|
let progress = Math.ceil((event.loaded * 100) / event.total)
|
||||||
|
if (progress <= 100) {
|
||||||
|
item.progress = progress;
|
||||||
|
this._changeFilesItem(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
|
xmlRequest.ontimeout = () => {
|
||||||
|
console.error('请求超时')
|
||||||
|
item.type = 'fail';
|
||||||
|
this._changeFilesItem(item,true);
|
||||||
|
return resolve(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
xmlRequest.onreadystatechange = ev => {
|
||||||
|
if (xmlRequest.readyState == 4) {
|
||||||
|
if (xmlRequest.status == 200) {
|
||||||
|
this.debug&&console.log('上传完成:' + xmlRequest.responseText)
|
||||||
|
item['responseText'] = xmlRequest.responseText;
|
||||||
|
item.type = 'success';
|
||||||
|
this._changeFilesItem(item,true);
|
||||||
|
return resolve(true);
|
||||||
|
} else if (xmlRequest.status == 0) {
|
||||||
|
console.error('status = 0 :请检查请求头Content-Type与服务端是否匹配,服务端已正确开启跨域,并且nginx未拦截阻止请求')
|
||||||
|
}
|
||||||
|
console.error('--ERROR--:status = ' + xmlRequest.status)
|
||||||
|
item.type = 'fail';
|
||||||
|
this._changeFilesItem(item,true);
|
||||||
|
return resolve(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xmlRequest.send(form)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_uploadHandleWX(item) {
|
||||||
|
item.type = 'loading';
|
||||||
|
delete item.responseText;
|
||||||
|
return new Promise((resolve,reject)=>{
|
||||||
|
this.debug&&console.log('option',JSON.stringify(this.option));
|
||||||
|
let form = {filePath: item.file.path,...this.option };
|
||||||
|
form['fail'] = ({ errMsg = '' }) => {
|
||||||
|
console.error('--ERROR--:' + errMsg)
|
||||||
|
item.type = 'fail';
|
||||||
|
this._changeFilesItem(item,true);
|
||||||
|
return resolve(false);
|
||||||
|
}
|
||||||
|
form['success'] = res => {
|
||||||
|
if (res.statusCode == 200) {
|
||||||
|
this.debug&&console.log('上传完成,微信端返回不一定是字符串,根据接口返回格式判断是否需要JSON.parse:' + res.data)
|
||||||
|
item['responseText'] = res.data;
|
||||||
|
item.type = 'success';
|
||||||
|
this._changeFilesItem(item,true);
|
||||||
|
return resolve(true);
|
||||||
|
}
|
||||||
|
item.type = 'fail';
|
||||||
|
this._changeFilesItem(item,true);
|
||||||
|
return resolve(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
let xmlRequest = uni.uploadFile(form);
|
||||||
|
xmlRequest.onProgressUpdate(({ progress = 0 }) => {
|
||||||
|
if (progress <= 100) {
|
||||||
|
item.progress = progress;
|
||||||
|
this._changeFilesItem(item);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,321 @@
|
|||||||
|
<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: 'Lsj-upload',
|
||||||
|
props: {
|
||||||
|
// 打印日志
|
||||||
|
debug: {type: Boolean,default: false},
|
||||||
|
// 自动上传
|
||||||
|
instantly: {type: Boolean,default: false},
|
||||||
|
// 上传接口参数设置
|
||||||
|
option: {type: Object,default: ()=>{}},
|
||||||
|
// 文件大小上限
|
||||||
|
size: { type: Number, default: 10 },
|
||||||
|
// 文件选择个数上限,超出后不触发点击
|
||||||
|
count: { type: Number, default: 9 },
|
||||||
|
// 是否允许多选文件
|
||||||
|
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
|
||||||
|
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';
|
||||||
|
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._size >= this.count) {
|
||||||
|
this.toast(`只允许上传${this.count}个文件`);
|
||||||
|
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>
|
||||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,198 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-cn">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title class="title">[文件管理器]</title>
|
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
|
||||||
|
<style type="text/css">
|
||||||
|
.content {background: transparent;}
|
||||||
|
.btn {position: relative;top: 0;left: 0;bottom: 0;right: 0;}
|
||||||
|
.btn .file {position: fixed;z-index: 93;left: 0;right: 0;top: 0;bottom: 0;width: 100%;opacity: 0;}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div id="content" class="content">
|
||||||
|
<div class="btn">
|
||||||
|
<input :multiple="multiple" @change="onChange" :accept="accept" ref="file" class="file" type="file" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script type="text/javascript" src="js/vue.min.js"></script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
let _this;
|
||||||
|
var vm = new Vue({
|
||||||
|
el: '#content',
|
||||||
|
data: {
|
||||||
|
accept: '',
|
||||||
|
multiple: true,
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
console.log('加载webview');
|
||||||
|
_this = this;
|
||||||
|
this.files = new Map();
|
||||||
|
document.addEventListener('plusready', (e)=>{
|
||||||
|
let {debug,instantly,prohibited} = plus.webview.currentWebview();
|
||||||
|
this.debug = debug;
|
||||||
|
this.instantly = instantly;
|
||||||
|
this.prohibited = prohibited;
|
||||||
|
this.accept = prohibited.accept;
|
||||||
|
if (prohibited.multiple === 'false') {
|
||||||
|
prohibited.multiple = false;
|
||||||
|
}
|
||||||
|
this.multiple = prohibited.multiple;
|
||||||
|
location.href = 'callback?retype=updateOption';
|
||||||
|
}, false);
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
toast(msg) {
|
||||||
|
plus.nativeUI.toast(msg);
|
||||||
|
},
|
||||||
|
clear(name) {
|
||||||
|
if (!name) {
|
||||||
|
this.files.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.files.delete(name);
|
||||||
|
},
|
||||||
|
setData(option='{}') {
|
||||||
|
this.debug&&console.log('更新参数:'+option);
|
||||||
|
try{
|
||||||
|
_this.option = JSON.parse(option);
|
||||||
|
}catch(e){
|
||||||
|
console.error('参数设置错误')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async upload(name=''){
|
||||||
|
if (name && this.files.has(name)) {
|
||||||
|
await this.createUpload(this.files.get(name));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (let item of this.files.values()) {
|
||||||
|
if (item.type === 'waiting' || item.type === 'fail') {
|
||||||
|
await this.createUpload(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onChange(e) {
|
||||||
|
let fileDom = this.$refs.file;
|
||||||
|
for (let file of fileDom.files) {
|
||||||
|
if (this.files.size >= this.prohibited.count) {
|
||||||
|
this.toast(`只允许上传${this.prohibited.count}个文件`);
|
||||||
|
fileDom.value = '';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.addFile(file);
|
||||||
|
}
|
||||||
|
this.uploadAfter();
|
||||||
|
fileDom.value = '';
|
||||||
|
},
|
||||||
|
addFile(file) {
|
||||||
|
if (file) {
|
||||||
|
let name = file.name;
|
||||||
|
this.debug&&console.log('文件名称',name,'大小',file.size);
|
||||||
|
// 限制文件格式
|
||||||
|
let suffix = name.substring(name.lastIndexOf(".")+1).toLowerCase();
|
||||||
|
let formats = this.prohibited.formats.toLowerCase();
|
||||||
|
if (formats&&!formats.includes(suffix)) {
|
||||||
|
this.toast(`不支持上传${suffix.toUpperCase()}格式文件`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 限制文件大小
|
||||||
|
if (file.size > 1024 * 1024 * Math.abs(this.prohibited.size)) {
|
||||||
|
this.toast(`附件大小请勿超过${this.prohibited.size}M`)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// let itemBlob = new Blob([file]);
|
||||||
|
let path = URL.createObjectURL(file);
|
||||||
|
this.files.set(file.name,{file,path,name: file.name,size: file.size,progress: 0,type: 'waiting'});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* @returns {Map} 已选择的文件Map集
|
||||||
|
*/
|
||||||
|
callChange() {
|
||||||
|
location.href = 'callback?retype=change&files=' + escape(JSON.stringify([...this.files]));
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* @returns {object} 正在处理的当前对象
|
||||||
|
*/
|
||||||
|
changeFilesItem(item,end='') {
|
||||||
|
this.files.set(item.name,item);
|
||||||
|
location.href = 'callback?retype=progress&end='+ end +'&item=' + escape(JSON.stringify(item));
|
||||||
|
},
|
||||||
|
uploadAfter() {
|
||||||
|
this.callChange();
|
||||||
|
setTimeout(()=>{
|
||||||
|
this.instantly&&this.upload();
|
||||||
|
},1000)
|
||||||
|
},
|
||||||
|
createUpload(item) {
|
||||||
|
this.debug&&console.log('准备上传,option=:'+JSON.stringify(this.option));
|
||||||
|
item.type = 'loading';
|
||||||
|
delete item.responseText;
|
||||||
|
return new Promise((resolve,reject)=>{
|
||||||
|
let {url,name,method='POST',header={},formData={}} = this.option;
|
||||||
|
let form = new FormData();
|
||||||
|
for (let keys in formData) {
|
||||||
|
form.append(keys, formData[keys])
|
||||||
|
}
|
||||||
|
form.append(name, item.file);
|
||||||
|
let xmlRequest = new XMLHttpRequest();
|
||||||
|
xmlRequest.open(method, url, true);
|
||||||
|
for (let keys in header) {
|
||||||
|
xmlRequest.setRequestHeader(keys, header[keys])
|
||||||
|
}
|
||||||
|
xmlRequest.upload.addEventListener(
|
||||||
|
'progress',
|
||||||
|
event => {
|
||||||
|
if (event.lengthComputable) {
|
||||||
|
let progress = Math.ceil((event.loaded * 100) / event.total)
|
||||||
|
if (progress <= 100) {
|
||||||
|
item.progress = progress;
|
||||||
|
this.changeFilesItem(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
|
xmlRequest.ontimeout = () => {
|
||||||
|
console.error('请求超时')
|
||||||
|
item.type = 'fail';
|
||||||
|
this.changeFilesItem(item,true);
|
||||||
|
return resolve(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
xmlRequest.onreadystatechange = ev => {
|
||||||
|
if (xmlRequest.readyState == 4) {
|
||||||
|
this.debug && console.log('接口是否支持跨域',xmlRequest.withCredentials);
|
||||||
|
if (xmlRequest.status == 200) {
|
||||||
|
this.debug && console.log('上传完成:' + xmlRequest.responseText)
|
||||||
|
item['responseText'] = xmlRequest.responseText;
|
||||||
|
item.type = 'success';
|
||||||
|
this.changeFilesItem(item,true);
|
||||||
|
return resolve(true);
|
||||||
|
} else if (xmlRequest.status == 0) {
|
||||||
|
console.error('status = 0 :请检查请求头Content-Type与服务端是否匹配,服务端已正确开启跨域,并且nginx未拦截阻止请求')
|
||||||
|
}
|
||||||
|
console.error('--ERROR--:status = ' + xmlRequest.status)
|
||||||
|
item.type = 'fail';
|
||||||
|
this.changeFilesItem(item,true);
|
||||||
|
return resolve(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xmlRequest.send(form)
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
{
|
||||||
|
"id": "lsj-upload",
|
||||||
|
"displayName": "全文件上传选择非原生2.0版",
|
||||||
|
"version": "2.2.9",
|
||||||
|
"description": "文件选择上传-支持APP-H5网页-微信小程序",
|
||||||
|
"keywords": [
|
||||||
|
"附件",
|
||||||
|
"file",
|
||||||
|
"upload",
|
||||||
|
"上传",
|
||||||
|
"文件管理器"
|
||||||
|
],
|
||||||
|
"repository": "",
|
||||||
|
"engines": {
|
||||||
|
},
|
||||||
|
"dcloudext": {
|
||||||
|
"sale": {
|
||||||
|
"regular": {
|
||||||
|
"price": "0.00"
|
||||||
|
},
|
||||||
|
"sourcecode": {
|
||||||
|
"price": "0.00"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"contact": {
|
||||||
|
"qq": ""
|
||||||
|
},
|
||||||
|
"declaration": {
|
||||||
|
"ads": "无",
|
||||||
|
"data": "无",
|
||||||
|
"permissions": "无"
|
||||||
|
},
|
||||||
|
"npmurl": "",
|
||||||
|
"type": "component-vue"
|
||||||
|
},
|
||||||
|
"uni_modules": {
|
||||||
|
"platforms": {
|
||||||
|
"cloud": {
|
||||||
|
"tcb": "y",
|
||||||
|
"aliyun": "y"
|
||||||
|
},
|
||||||
|
"client": {
|
||||||
|
"App": {
|
||||||
|
"app-vue": "y",
|
||||||
|
"app-nvue": "y"
|
||||||
|
},
|
||||||
|
"H5-mobile": {
|
||||||
|
"Safari": "y",
|
||||||
|
"Android Browser": "y",
|
||||||
|
"微信浏览器(Android)": "y",
|
||||||
|
"QQ浏览器(Android)": "y"
|
||||||
|
},
|
||||||
|
"H5-pc": {
|
||||||
|
"Chrome": "y",
|
||||||
|
"IE": "y",
|
||||||
|
"Edge": "y",
|
||||||
|
"Firefox": "y",
|
||||||
|
"Safari": "y"
|
||||||
|
},
|
||||||
|
"小程序": {
|
||||||
|
"微信": "y",
|
||||||
|
"阿里": "u",
|
||||||
|
"百度": "u",
|
||||||
|
"字节跳动": "u",
|
||||||
|
"QQ": "u"
|
||||||
|
},
|
||||||
|
"快应用": {
|
||||||
|
"华为": "y",
|
||||||
|
"联盟": "y"
|
||||||
|
},
|
||||||
|
"Vue": {
|
||||||
|
"vue2": "y",
|
||||||
|
"vue3": "y"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,353 @@
|
|||||||
|
# lsj-upload
|
||||||
|
|
||||||
|
### 插件地址:https://ext.dcloud.net.cn/plugin?id=5459
|
||||||
|
|
||||||
|
### 不清楚使用方式可点击右侧导入示例项目运行完整示例
|
||||||
|
### 此次更新2.0与1.0使用方式略有差异,已使用1.0的同学自行斟酌是否更新到2.0版本!!!
|
||||||
|
|
||||||
|
使用插件有任何问题欢迎加入QQ讨论群:
|
||||||
|
- 群1:701468256(已满)
|
||||||
|
- 群2:469580165(已满)
|
||||||
|
- 群3:667530868
|
||||||
|
|
||||||
|
若能帮到你请高抬贵手点亮5颗星~
|
||||||
|
------
|
||||||
|
## 重要提示
|
||||||
|
### 组件是窗口级滚动,不要在scroll-view内使用!!
|
||||||
|
### 组件是窗口级滚动,不要在scroll-view内使用!!
|
||||||
|
### 组件是窗口级滚动,不要在scroll-view内使用!!
|
||||||
|
|
||||||
|
### 控件的height高度应与slot自定义内容高度保持一致
|
||||||
|
### nvue窗口只能使用固定模式position=absolute
|
||||||
|
### show() 当DOM重排后在this.$nextTick内调用show(),控件定位会更加准确
|
||||||
|
### hide() APP端webview层级比view高,如不希望触发点击时,应调用hide隐藏控件,反之调用show
|
||||||
|
### 若iOS端跨域服务端同学实在配置不好,可把hybrid下html目录放到服务器去,同源则不存在跨域问题。
|
||||||
|
### 小程序端因hybrid不能使用本地HTML,所以插件提供的是从微信消息列表拉取文件并选择,请知悉。
|
||||||
|
### file对象不是object对象,也不能转json字符串,如果你打印file那就是{},可以打印file.name和file.size。
|
||||||
|
### 返回的path是个blob类型,仅供用于文件回显,插件已内置好上传函数,调用上传会自动提交待上传文件,若非要自己拿path去搞上传那你自己处理。
|
||||||
|
------
|
||||||
|
|
||||||
|
## 使用说明
|
||||||
|
| 属性 | 是否必填 | 值类型 | 默认值 | 说明 |
|
||||||
|
| --------- | -------- | -----: | --: | :------------:|
|
||||||
|
| width | 否 | String |100% | 容器宽度 |
|
||||||
|
| height | 是 | String |80rpx | 容器高度 |
|
||||||
|
| debug | 否 | Boolean |false | 打印调试日志 |
|
||||||
|
| option | 是 | Object |- | [文件上传接口相关参数](#p1)|
|
||||||
|
| instantly | 否 | Boolean |false | true=自动上传 |
|
||||||
|
| count | 否 | Number |10 | 附件选择上限(个)|
|
||||||
|
| size | 否 | Number |10 | 附件大小上限(M)|
|
||||||
|
| wxFileType | 否 | String |all | 微信小程序文件选择器格式限制(all=从所有文件选择,video=只能选择视频文件,image=只能选择图片文件,file=可以选择除了图片和视频之外的其它的文件)|
|
||||||
|
| accept | 否 | String |- | 文件选择器input file格式限制(部分机型不兼容,建议使用formats)|
|
||||||
|
| formats | 否 | String |- | 限制允许上传的格式,空串=不限制,默认为空,多个格式以逗号隔开,例如png,jpg,pdf|
|
||||||
|
| childId | 否 | String |lsjUpload| 控件的id(仅APP有效,应用内每个控件命名一个唯一Id,不同窗口也不要同名Id)|
|
||||||
|
| position | 否 | String |static | 控件的定位模式(static=控件随页面滚动;absolute=控件在页面中绝对定位,不随窗口内容滚动)|
|
||||||
|
| top,left,right,bottom | 否 | [Number,String] |0 | 设置控件绝对位置,position=absolute时有效|
|
||||||
|
| @change | 否 | Function |Map | 选择文件触发,返回所有已选择文件Map集合|
|
||||||
|
| @progress | 否 | Function |Object | 上传过程中发生状态变化的文件对象,需通过set更新至Map集合|
|
||||||
|
| @uploadEnd| 否 | Function |Object | 上传结束回调,返回参数与progress一致|
|
||||||
|
|
||||||
|
## <a id="p1">option说明</a>
|
||||||
|
|参数 | 是否必填 | 说明|
|
||||||
|
|---- | ---- | :--: |
|
||||||
|
|url | 是 | 上传接口地址|
|
||||||
|
|name| 否 |上传接口文件key,默认为file|
|
||||||
|
|header| 否 |上传接口请求头|
|
||||||
|
|formData| 否 |上传接口额外参数|
|
||||||
|
|
||||||
|
## ref调用
|
||||||
|
|作用 | 方法名| 传入参数| 说明|
|
||||||
|
|---- | --------- | -------- | :--: |
|
||||||
|
|显示控件| show|-| 控件显示状态下可触发点击|
|
||||||
|
|隐藏控件| hide|-| 控件隐藏状态下不触发点击|
|
||||||
|
|动态设置文件列表| setFiles|[Array,Map] files| 传入格式请与组件选择返回格式保持一致,且name为必须属性,可查看下方演示|
|
||||||
|
|动态更新参数| setData|[String] name,[any] value| name支持a.b 和 a[b],可查看下方演示|
|
||||||
|
|移除选择的文件| clear|[String] name| 不传参数清空所有文件,传入文件name时删除该name的文件|
|
||||||
|
|手动上传| upload|[String] name| 不传参数默认依次上传所有type=waiting的文件,传入文件name时不关心type是否为waiting,单独上传指定name的文件|
|
||||||
|
|
||||||
|
## progress返回对象字段说明
|
||||||
|
|字段 | 说明|
|
||||||
|
|---- | :--: |
|
||||||
|
|file | 文件对象|
|
||||||
|
|name |文件名称|
|
||||||
|
|size |文件大小|
|
||||||
|
|type |文件上传状态:waiting(等待上传)、loading(上传中)、success(成功) 、fail(失败)|
|
||||||
|
|responseText|上传成功后服务端返回数据(仅type为success时存在)|
|
||||||
|
|
||||||
|
## 以下演示为vue窗口使用方式,nvue使用区别是必须传入控件绝对位置如top,bottom,left,right,且position只能为absolute,如不清楚可点击右侧导入示例项目有详细演示代码。
|
||||||
|
|
||||||
|
### vue:
|
||||||
|
``` javascript
|
||||||
|
<lsj-upload
|
||||||
|
ref="lsjUpload"
|
||||||
|
childId="upload1"
|
||||||
|
:width="width"
|
||||||
|
:height="height"
|
||||||
|
:option="option"
|
||||||
|
:size="size"
|
||||||
|
:formats="formats"
|
||||||
|
:debug="debug"
|
||||||
|
:instantly="instantly"
|
||||||
|
@uploadEnd="onuploadEnd"
|
||||||
|
@progress="onprogre"
|
||||||
|
@change="onChange">
|
||||||
|
<view class="btn" :style="{width: width,height: height}">选择附件</view>
|
||||||
|
</lsj-upload>
|
||||||
|
|
||||||
|
|
||||||
|
<view class="padding">
|
||||||
|
|
||||||
|
<view>已选择文件列表:</view>
|
||||||
|
|
||||||
|
<!-- #ifndef MP-WEIXIN -->
|
||||||
|
<view v-for="(item,index) in files.values()" :key="index">
|
||||||
|
<image style="width: 100rpx;height: 100rpx;" :src="item.path" mode="widthFix"></image>
|
||||||
|
<text>提示:【path主要用于图片视频类文件回显,他用自行处理】:{{item.path}}</text>
|
||||||
|
<text>{{item.name}}</text>
|
||||||
|
<text style="margin-left: 10rpx;">大小:{{item.size}}</text>
|
||||||
|
<text style="margin-left: 10rpx;">状态:{{item.type}}</text>
|
||||||
|
<text style="margin-left: 10rpx;">进度:{{item.progress}}</text>
|
||||||
|
<text style="margin-left: 10rpx;" v-if="item.responseText">服务端返回演示:{{item.responseText}}</text>
|
||||||
|
<text @click="resetUpload(item.name)" v-if="item.type=='fail'" style="margin-left: 10rpx;padding: 0 10rpx;border: 1rpx solid #007AFF;">重新上传</text>
|
||||||
|
<text @click="clear(item.name)" style="margin-left: 10rpx;padding: 0 10rpx;border: 1rpx solid #007AFF;">删除</text>
|
||||||
|
</view>
|
||||||
|
<!-- #endif -->
|
||||||
|
|
||||||
|
<!-- #ifdef MP-WEIXIN -->
|
||||||
|
<view v-for="(item,index) in wxFiles" :key="index">
|
||||||
|
<text>{{item.name}}</text>
|
||||||
|
<text style="margin-left: 10rpx;">大小:{{item.size}}</text>
|
||||||
|
<text style="margin-left: 10rpx;">状态:{{item.type}}</text>
|
||||||
|
<text style="margin-left: 10rpx;">进度:{{item.progress}}</text>
|
||||||
|
<view>
|
||||||
|
<button @click="resetUpload(item.name)">重新上传</button>
|
||||||
|
<button @click="clear(item.name)">删除</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- #endif -->
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
* 函数说明
|
||||||
|
|
||||||
|
|
||||||
|
``` javascript
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 上传接口参数
|
||||||
|
option: {
|
||||||
|
// 上传服务器地址,需要替换为你的接口地址
|
||||||
|
url: 'http://hl.j56.com/dropbox/document/upload', // 该地址非真实路径,需替换为你项目自己的接口地址
|
||||||
|
// 上传附件的key
|
||||||
|
name: 'file',
|
||||||
|
// 根据你接口需求自定义请求头,默认不要写content-type,让浏览器自适配
|
||||||
|
header: {
|
||||||
|
// 示例参数可删除
|
||||||
|
'Authorization': 'bearer eyJhbGciOiJSUzI1NiIsI',
|
||||||
|
'uid': '99',
|
||||||
|
'client': 'app',
|
||||||
|
'accountid': 'DP',
|
||||||
|
},
|
||||||
|
// 根据你接口需求自定义body参数
|
||||||
|
formData: {
|
||||||
|
// 'orderId': 1000
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 选择文件后是否立即自动上传,true=选择后立即上传
|
||||||
|
instantly: true,
|
||||||
|
// 必传宽高且宽高应与slot宽高保持一致
|
||||||
|
width: '180rpx',
|
||||||
|
height: '180rpx',
|
||||||
|
// 限制允许上传的格式,空串=不限制,默认为空
|
||||||
|
formats: '',
|
||||||
|
// 文件上传大小限制
|
||||||
|
size: 30,
|
||||||
|
// 文件数量限制
|
||||||
|
count: 2,
|
||||||
|
// 文件回显列表
|
||||||
|
files: new Map(),
|
||||||
|
// 微信小程序Map对象for循环不显示,所以转成普通数组,不要问为什么,我也不知道
|
||||||
|
wxFiles: [],
|
||||||
|
// 是否打印日志
|
||||||
|
debug: true,
|
||||||
|
|
||||||
|
|
||||||
|
// 演示用
|
||||||
|
tabIndex: 0,
|
||||||
|
list:[],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onReady() {
|
||||||
|
setTimeout(()=>{
|
||||||
|
console.log('----演示动态更新参数-----');
|
||||||
|
this.$refs['lsjUpload'+this.tabIndex].setData('formData.orderId','动态设置的参数');
|
||||||
|
|
||||||
|
console.log('以下注释内容为-动态更新参数更多演示,放开后可查看演示效果');
|
||||||
|
// 修改option对象的name属性
|
||||||
|
// this.$refs.lsjUpload.setData('name','myFile');
|
||||||
|
|
||||||
|
// 修改option对象的formData内的属性
|
||||||
|
// this.$refs.lsjUpload.setData('formData.appid','1111');
|
||||||
|
|
||||||
|
// 替换option对象的formData
|
||||||
|
// this.$refs.lsjUpload.setData('formData',{appid:'222'});
|
||||||
|
|
||||||
|
// option对象的formData新增属性
|
||||||
|
// this.$refs.lsjUpload.setData('formData.newkey','新插入到formData的属性');
|
||||||
|
|
||||||
|
|
||||||
|
// ---------演示初始化值,用于已提交后再次编辑时需带入已上传文件-------
|
||||||
|
// 方式1=传入数组
|
||||||
|
// let files1 = [{name: '1.png'},{name: '2.png',}];
|
||||||
|
|
||||||
|
// 方式2=传入Map对象
|
||||||
|
// let files2 = new Map();
|
||||||
|
// files2.set('1.png',{name: '1.png'})
|
||||||
|
|
||||||
|
// 此处调用setFiles设置初始files
|
||||||
|
// this.$refs.lsjUpload.setFiles(files1);
|
||||||
|
|
||||||
|
// 初始化tab
|
||||||
|
this.onTab(0);
|
||||||
|
},2000)
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// 某文件上传结束回调(成功失败都回调)
|
||||||
|
onuploadEnd(item) {
|
||||||
|
console.log(`${item.name}已上传结束,上传状态=${item.type}`);
|
||||||
|
|
||||||
|
// 更新当前窗口状态变化的文件
|
||||||
|
this.files.set(item.name,item);
|
||||||
|
|
||||||
|
// ---可删除--演示上传完成后取服务端数据
|
||||||
|
if (item['responseText']) {
|
||||||
|
console.log('演示服务器返回的字符串JSON转Object对象');
|
||||||
|
this.files.get(item.name).responseText = JSON.parse(item.responseText);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 微信小程序Map对象for循环不显示,所以转成普通数组,
|
||||||
|
// 如果你用不惯Map对象,也可以像这样转普通数组,组件使用Map主要是避免反复文件去重操作
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
this.wxFiles = [...this.files.values()];
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// 强制更新视图
|
||||||
|
this.$forceUpdate();
|
||||||
|
|
||||||
|
|
||||||
|
// ---可删除--演示判断是否所有文件均已上传成功
|
||||||
|
let isAll = [...this.files.values()].find(item=>item.type!=='success');
|
||||||
|
if (!isAll) {
|
||||||
|
console.log('已全部上传完毕');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.log(isAll.name+'待上传');
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
// 上传进度回调,如果网页上md文档没有渲染出事件名称onprogre,请复制代码的小伙伴自行添加上哈,没有哪个事件是只(item)的
|
||||||
|
onprogre(item) {
|
||||||
|
// 更新当前状态变化的文件
|
||||||
|
this.files.set(item.name,item);
|
||||||
|
|
||||||
|
console.log('打印对象',JSON.stringify(this.files.get(item.name)));
|
||||||
|
// 微信小程序Map对象for循环不显示,所以转成普通数组,不要问为什么,我也不知道
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
this.wxFiles = [...this.files.values()];
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// 强制更新视图
|
||||||
|
this.$forceUpdate();
|
||||||
|
|
||||||
|
},
|
||||||
|
// 文件选择回调
|
||||||
|
onChange(files) {
|
||||||
|
console.log('当前选择的文件列表:',JSON.stringify([...files.values()]));
|
||||||
|
// 更新选择的文件
|
||||||
|
this.files = files;
|
||||||
|
// 强制更新视图
|
||||||
|
this.$forceUpdate();
|
||||||
|
|
||||||
|
// 微信小程序Map对象for循环不显示,所以转成普通数组,不要问为什么,我也不知道
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
this.wxFiles = [...this.files.values()];
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// ---可删除--演示重新定位覆盖层控件
|
||||||
|
this.$nextTick(()=>{
|
||||||
|
console.log('演示重新定位');
|
||||||
|
this.$refs.lsjUpload0.show();
|
||||||
|
this.$refs.lsjUpload1.show();
|
||||||
|
this.$refs.lsjUpload2.show();
|
||||||
|
});
|
||||||
|
|
||||||
|
},
|
||||||
|
// 手动上传
|
||||||
|
upload() {
|
||||||
|
// name=指定文件名,不指定则上传所有type等于waiting和fail的文件
|
||||||
|
this.$refs['lsjUpload'+this.tabIndex].upload();
|
||||||
|
},
|
||||||
|
// 指定上传某个文件
|
||||||
|
resetUpload(name) {
|
||||||
|
this.$refs['lsjUpload'+this.tabIndex].upload(name);
|
||||||
|
},
|
||||||
|
// 移除某个文件
|
||||||
|
clear(name) {
|
||||||
|
// name=指定文件名,不传name默认移除所有文件
|
||||||
|
this.$refs['lsjUpload'+this.tabIndex].clear(name);
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* ---可删除--演示在组件上方添加新内容DOM变化
|
||||||
|
* DOM重排演示,重排后组件内部updated默认会触发show方法,若特殊情况未能触发updated也可以手动调用一次show()
|
||||||
|
* 什么是DOM重排?自行百度去
|
||||||
|
*/
|
||||||
|
add() {
|
||||||
|
this.list.push('DOM重排测试');
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* ---可删除--演示Tab切换时覆盖层是否能被点击
|
||||||
|
* APP端因为是webview,层级比view高,此时若不希望点击触发选择文件,需要手动调用hide()
|
||||||
|
* 手动调用hide后,需要调用show()才能恢复覆盖层的点击
|
||||||
|
*/
|
||||||
|
onTab(tabIndex) {
|
||||||
|
this.$refs.lsjUpload0.hide();
|
||||||
|
this.$refs.lsjUpload1.hide();
|
||||||
|
|
||||||
|
this.tabIndex = tabIndex;
|
||||||
|
|
||||||
|
this.$nextTick(()=>{
|
||||||
|
this.$refs['lsjUpload'+this.tabIndex].show();
|
||||||
|
})
|
||||||
|
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 打开nvue窗口查看非跟随窗口滚动效果
|
||||||
|
*/
|
||||||
|
open() {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages/nvue-demo/nvue-demo'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 温馨提示
|
||||||
|
|
||||||
|
* 文件上传
|
||||||
|
0. 如说明表达还不够清楚,不清楚怎么使用可导入完整示例项目运行体验和查看
|
||||||
|
1. APP端请优先联调Android,上传成功后再运行iOS端,如iOS返回status=0则需要后端开启允许跨域;
|
||||||
|
2. header的Content-Type类型需要与服务端要求一致,否则收不到附件(服务端若没有明文规定则可不写,使用默认匹配)
|
||||||
|
3. 服务端不清楚怎么配置跨域可加群咨询,具体百度~
|
||||||
|
4. 欢迎加入QQ讨论群:701468256(已满)
|
||||||
|
5. 欢迎加入QQ讨论群:469580165(已满)
|
||||||
|
6. 欢迎加入QQ讨论群:667530868
|
||||||
|
7. 若能帮到你还请点亮5颗小星星以作鼓励哈~
|
||||||
|
8. 若能帮到你还请点亮5颗小星星以作鼓励哈~
|
||||||
|
9. 若能帮到你还请点亮5颗小星星以作鼓励哈~
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
+13
-20
@@ -1,7 +1,8 @@
|
|||||||
{
|
{
|
||||||
"description": "项目配置文件。",
|
"description": "项目配置文件。",
|
||||||
"packOptions": {
|
"packOptions": {
|
||||||
"ignore": []
|
"ignore": [],
|
||||||
|
"include": []
|
||||||
},
|
},
|
||||||
"setting": {
|
"setting": {
|
||||||
"urlCheck": false,
|
"urlCheck": false,
|
||||||
@@ -9,28 +10,20 @@
|
|||||||
"postcss": true,
|
"postcss": true,
|
||||||
"minified": true,
|
"minified": true,
|
||||||
"newFeature": true,
|
"newFeature": true,
|
||||||
"bigPackageSizeSupport": true
|
"bigPackageSizeSupport": true,
|
||||||
|
"babelSetting": {
|
||||||
|
"ignore": [],
|
||||||
|
"disablePlugins": [],
|
||||||
|
"outputPath": ""
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"compileType": "miniprogram",
|
"compileType": "miniprogram",
|
||||||
"libVersion": "",
|
"libVersion": "3.3.2",
|
||||||
"appid": "wx91cb8459dca561b4",
|
"appid": "wx91cb8459dca561b4",
|
||||||
"projectname": "智慧仲裁",
|
"projectname": "智慧仲裁",
|
||||||
"condition": {
|
"condition": {},
|
||||||
"search": {
|
"editorSetting": {
|
||||||
"current": -1,
|
"tabIndent": "insertSpaces",
|
||||||
"list": []
|
"tabSize": 2
|
||||||
},
|
|
||||||
"conversation": {
|
|
||||||
"current": -1,
|
|
||||||
"list": []
|
|
||||||
},
|
|
||||||
"game": {
|
|
||||||
"current": -1,
|
|
||||||
"list": []
|
|
||||||
},
|
|
||||||
"miniprogram": {
|
|
||||||
"current": -1,
|
|
||||||
"list": []
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user