瀏覽代碼

完善APP样式和文件上传

LuChongMei 11 月之前
父節點
當前提交
382af6a522

+ 38 - 4
jp-mobile/pages.json

@@ -13,6 +13,36 @@
 				"navigationStyle": "custom" // 隐藏系统导航栏
 			}
 		},
+		{
+		    "path" : "pages/commonseal/addCommon",
+		    "style" : {
+				"navigationBarTitleText": "新增拟稿申请"
+			}
+		},
+		{
+		    "path" : "pages/commonseal/examineCommon",
+		    "style" : {
+				"navigationBarTitleText": "拟稿审批"
+			}
+		},
+		{
+		    "path" : "pages/commonseal/commonInfo",
+		    "style" : {
+				"navigationBarTitleText": "拟稿详情"
+			}
+		},
+		{
+		    "path" : "pages/commonseal/commonList",
+		    "style" : {
+				"navigationBarTitleText": "列表"
+			}
+		},
+		{
+		    "path" : "pages/commonseal/statistics",
+		    "style" : {
+				"navigationBarTitleText": "用章统计"
+			}
+		},
 		{
 		    "path" : "pages/fileTransmit/addFileTransmit",
 		    "style" : {
@@ -623,10 +653,14 @@
 	  "usingComponents": {
 				"ly-tree-node": "/components/ly-tree/ly-tree-node"
 			},
-		"navigationBarBackgroundColor": "#36a7f3",
-		"navigationBarTitleText": "公文流转",
-		"navigationStyle": "custom",
-		"navigationBarTextStyle": "white"
+		"h5":{
+			"navigationStyle": "custom"
+		},
+		"app-plus":{
+			"navigationBarBackgroundColor": "#36a7f3",
+			"navigationBarTitleText": "公文流转",
+			"navigationBarTextStyle": "white"
+		}
 	},
 	"usingComponts": true,
 		"condition": { //模式配置,仅开发期间生效

+ 3 - 0
jp-mobile/pages/addressbook/addressbook.vue

@@ -1,5 +1,8 @@
 <template>
 	<view class="main">
+		<cu-custom bgColor="bg-blue_default">
+			<block slot="content">通讯录</block>
+		</cu-custom>
 		<view class=" text-center flex tab-custom" style="height: 45px;line-height: 45px;">
 			<u-tabs :list="list" @click="changeParent" lineWidth="30" lineHeight="1" lineColor="#ffffff" :activeStyle="{
         color: '#ffffff',

+ 95 - 92
jp-mobile/pages/fileTransmit/addFileTransmit.vue

@@ -35,16 +35,17 @@
 					<u--textarea v-model="inputForm.contentSummary" placeholder="请输入内容摘要" border="none"></u--textarea>
 				</u-form-item>
 				<u-form-item label="来文附件" prop="attachedDocumentId" labelPosition="top">
-					<u-upload :fileList="fileLists" @afterRead="afterRead" multiple :maxCount="9" width="250"
-						height="150" accept="file" :previewImage="false">
-						<view class="addfile flex"> <u-icon size="20" bold name="plus"></u-icon></view>
-					</u-upload>
+					<lsj-upload ref="lsjUpload" childId="upload1" width="250rpx" height="200rpx" :option="option"
+						:debug="false" :instantly="false" @uploadEnd="onuploadEnd" @change="afterRead">
+						<view class="addfile flex">
+							<u-icon size="20" bold name="plus"></u-icon>
+						</view>
+					</lsj-upload>
+					<!-- #ifdef H5 -->
 					<view class="takephoto addfile flex" @click="takePhoto"> <u-icon size="20" bold
 							name="camera"></u-icon>
 					</view>
-					<!-- <u-upload :fileList="fileLists" @afterRead="afterRead"  width="80" height="80"
-						accept="image" capture="camera" :previewImage="false">
-					</u-upload> -->
+					<!-- #endif -->
 				</u-form-item>
 				<view class="text-danger" style="font-size: 12px!important;">请确保上传图片内容清晰可见,所有涉密敏感信息不得上传</view>
 				<view class="other_info">
@@ -102,6 +103,7 @@
 				isreceive: false,
 				iswrite: false,
 				fileLists: [],
+				files: [],
 				fileList: [],
 				imgList: [],
 				cardNum: "",
@@ -130,7 +132,15 @@
 						message: '请输入内容摘要',
 						trigger: ['blur', 'change']
 					}]
-				}
+				},
+				// 上传接口参数
+				option: {
+					url: BASE_URL + '/gwfile/upload?uploadPath=filetransmit',
+					name: 'file',
+					header: {
+						"token": $auth.getUserToken()
+					},
+				},
 			}
 		},
 		methods: {
@@ -149,27 +159,18 @@
 			// 删除文件
 			deleteFile(item) {
 				let that = this
-				uni.showModal({
-					title: '提示',
-					content: '确认删除该文件',
-					success: function(res) {
-						if (res.confirm) {
-							that.fileLists = that.fileLists.filter(i => !(i.url == item.url))
-							that.fileList = that.fileList.filter(i => !(i.url == item.url))
-						} else if (res.cancel) {
-							console.log('用户点击取消');
-						}
-					}
-				});
+				that.fileList = that.fileList.filter(i => !(i.url == item.url))
+				that.fileLists = that.fileLists.filter(i => !(i.url == item.url))
 
 			},
 			// 删除图片
 			deletePic(event) {
+				let that = this
 				this.imgList = this.imgList.filter(item => item.name != event.file.name)
-				this.fileLists = this.fileLists.filter(item => item.name != event.file.name)
+				that.fileLists = that.fileLists.filter(i => !(i.name == event.file.name))
 			},
 			// 图片压缩
-			async compressH5(urlData, targetSizeKB, initialQuality = 1.0) {
+			compressH5(urlData, targetSizeKB, initialQuality = 1.0) {
 				const maxQuality = 1.0;
 				const minQuality = 0.0;
 				const tolerance = 0.01; // 根据需要调整公差
@@ -207,9 +208,6 @@
 											tolerance) {
 											// 当前质量足够接近目标大小,使用当前质量解析
 											reader.readAsDataURL(blob);
-											uni.showToast({
-												title: blob.size
-											})
 											reader.onload = () => {
 												let result = that
 													.uploadFilePromise(reader
@@ -247,90 +245,95 @@
 						uni.showLoading({
 							title: "上传中"
 						})
-
 						const tempFilePaths = chooseImageRes.tempFiles[0];
 						// 成功选择图片后进行压缩处理
-							that.compressH5(tempFilePaths, 150).then(result =>{
-								const fileName = result.split(/[/\\=]/).pop();
-								let item1 = {
-									name: fileName,
-									url: BASE_URL + result
-								}
-								let item = {
-									name: fileName,
-									url: result
-								}
-								that.fileLists.push(item)
-								that.imgList.push(item1)
-								uni.hideLoading()
-							})
-						
+						that.compressH5(tempFilePaths, 150).then(result => {
+							const fileName = result.split(/[/\\=]/).pop();
+							let item1 = {
+								name: fileName,
+								url: BASE_URL + result
+							}
+							let item = {
+								name: fileName,
+								path: result,
+
+							}
+							that.fileLists.push(item)
+							that.imgList.push(item1)
+							uni.hideLoading()
+						})
+
 					},
 					fail: (error) => {
-						console.log('Error while choosing image:', error);
+
 						uni.hideLoading()
 					}
 				});
 			},
 			// 新增图片
-			async afterRead(event) {
+			afterRead(files) {
 				uni.showLoading({
 					title: "上传中"
 				})
-
-				// 当设置 multiple 为 true 时, file 为数组格式,否则为对象格式
-				let lists = [].concat(event.file)
-				let fileListLen = this.fileLists.length
-				lists.map((item) => {
-					this.fileLists.push({
-						...item,
-						status: 'uploading',
-						message: '上传中'
-					})
-				})
+				let lists = [...files.values()]
+				this.files = files
 				for (let i = 0; i < lists.length; i++) {
-					let result = ""
+					if (lists[i].type == 'success') continue;
+					this.upload(lists[i].name)
+				}
 
-					if (isImageFormat(lists[i].name)) {
-						if (lists[i].size > (200 * 1024)) {
-							result = await this.compressH5(lists[i], 150);
-						} else {
-							result = await this.uploadFilePromise(lists[i].url)
-						}
-						const fileName = result.split(/[/\\=]/).pop();
-						let item1 = {
-							name: fileName,
-							url: BASE_URL + result
-						}
-						this.imgList.push(item1)
-
-					} else {
-						result = await this.uploadFilePromise(lists[i].url)
-						const fileName = result.split(/[/\\=]/).pop();
-						let a = {
-							name: fileName,
-							url: BASE_URL + result
-						}
-						this.fileList.push(a)
+			},
+			// APP手动上传
+			upload(name) {
+				// name=指定文件名,不指定则上传所有type等于waiting和fail的文件
+				this.$refs['lsjUpload'].upload(name);
+			},
+			onuploadEnd(item) {
+				console.log(`${item.name}已上传结束,上传状态=${item.type}`);
+
+				// 更新当前窗口状态变化的文件
+				this.files.set(item.name, item);
+				this.fileLists.push(item)
+
+				const fileName = item.name.split(/[/\\=]/).pop();
+				if (isImageFormat(item.name)) {
+					let item1 = {
+						name: fileName,
+						url: BASE_URL + item.responseText
+					}
+					this.imgList.push(item1)
+
+				} else {
+					let a = {
+						name: fileName,
+						url: BASE_URL + item.responseText
 					}
-					let item = this.fileLists[fileListLen]
-					item.name = result.split(/[/\\=]/).pop();
-					this.fileLists.splice(fileListLen, 1, Object.assign(item, {
-						status: 'success',
-						message: '',
-						url: result
-					}))
-
-					fileListLen++
+					this.fileList.push(a)
+				}
+				// 微信小程序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) {
+					uni.hideLoading()
+				} else {
+					console.log(isAll.name + '待上传');
 				}
-				uni.hideLoading()
+
 			},
+			// 
 			async uploadFilePromise(param) {
-
 				return new Promise((resolve, reject) => {
 
 					let a = uni.uploadFile({
-						url: this.BASE_URL + '/gwfile/upload?uploadPath=filtransmit',
+						url: this.BASE_URL + '/gwfile/upload?uploadPath=filetransmit',
 						filePath: param,
 						name: 'file',
 						header: {
@@ -355,8 +358,9 @@
 				this.loading = true
 				let auditForm = Object.assign({}, this.inputForm);
 				let files = []
+				console.log('this.fileLists', this.fileLists);
 				this.fileLists.forEach(item => {
-					files.push(item.url)
+					files.push(item.path)
 				})
 				auditForm.attachedDocumentId = files.join(",");
 				auditForm.writtenTime = auditForm.writtenTime + " 00:00:00";
@@ -422,7 +426,7 @@
 	.submit_btn button {
 		height: 40px;
 		width: 80%;
-		border-radius: 30px;
+		border-radius: 50px;
 
 	}
 
@@ -430,8 +434,7 @@
 		width: 80px;
 		height: 80px;
 		background-color: #eee;
-		padding-left: 30%;
-		/* padding-left: 18%; */
+		padding-left: 24%;
 		margin: 10px;
 	}
 

+ 7 - 1
jp-mobile/pages/fileTransmit/examineFile.vue

@@ -335,7 +335,13 @@
 
 	.submit_btn button {
 		height: 40px;
+		/* #ifdef H5 */
 		width: 40%;
-		border-radius: 30px;
+		/* #endif */
+		/* #ifdef APP-PLUS */
+		width: 30vw!important;
+		/* #endif */
+		
+		border-radius: 50px;
 	}
 </style>

+ 1 - 1
jp-mobile/pages/fileTransmit/fileInfo.vue

@@ -39,7 +39,7 @@
 			// 先获取页面栈
 			let pages = getCurrentPages();
 			// 当前页面的前一个页面
-			let prevPage = pages[pages.length - 2];
+			let prevPage = pages[pages.length - 1];
 			if (prevPage.options.type == '1') {
 				uni.$emit('refresh', {
 					type: 4

+ 16 - 3
jp-mobile/pages/fileTransmit/fileTransmitList.vue

@@ -22,7 +22,7 @@
 						<view class="text-grey text-sm list_label margin-top">
 							{{item.createTime}}
 						</view>
-						<view>
+						<view class="value_tag">
 							<u-tag v-if="type==5" :text="item.state==1?'待办':item.state == 3?'归档':'已办'" plain
 								:type="item.state==1?'warning':item.state == 3?'primary':'success'">
 							</u-tag>
@@ -259,13 +259,26 @@
 	}
 
 	.list_search_select {
-		width: 200px;
+		/*  */
+		/* #ifdef H5 */
+		width: 300px !important;
+		/* #endif */
 		background-color: #fff;
 		height: 30px;
 		border-radius: 10px;
 		margin: 15px 5px 0;
 	}
-
+	.value_tag {
+		width: 50%;
+		position: relative;
+		/* #ifdef H5 */
+		right: -60px;
+		/* #endif */
+		/* #ifdef APP-PLUS */
+		right: -50px;
+		/* #endif */
+		
+	}
 	.list_search_date {
 		margin: 8px 5px 0;
 	}

+ 5 - 37
jp-mobile/pages/login/login.vue

@@ -1,7 +1,6 @@
 <template>
 	<view class="main">
 		<view id="box">
-
 			<view id="top" class="">
 				<view class="top_le"></view>
 				<view class="top_ri"></view>
@@ -12,32 +11,17 @@
 			<view class="login-form">
 				<u--form :model="inputForm" labelWidth="100px" labelPosition="left" :rules="rules" ref="uForm">
 					<u-form-item label="用户名" borderBottom prop="username">
-						<u-input @focus="isfocus = true" v-model="inputForm.username" />
+						<u-input v-model="inputForm.username" />
 					</u-form-item>
 					<u-form-item label="密码" borderBottom prop="password">
-						<u-input @focus="isfocus = true"  password v-model="inputForm.password" />
+						<u-input password v-model="inputForm.password" />
 					</u-form-item>
-					<!-- <u-checkbox-group v-model="isrember" placement="column" @change="checkboxChange">
-						<u-checkbox :customStyle="{marginBottom: '8px'}" label="记住密码" name="true">
-						</u-checkbox>
-					</u-checkbox-group> -->
 				</u--form>
 			</view>
-			<!-- <view v-if="isfocus" class="focus_info" >
-				<view class="flex" v-for="item in accounts">
-					<u--text decoration='underline' color='#36a7f3' :text="item.username"
-						@click="checked"></u--text>
-				</view>
-			</view> -->
 			<view class="but">
 				<u-button type="primary" shape="circle" color="linear-gradient(90deg, #1989FA, #19C2FA)"
 					@click="bindLogin" text="登录"></u-button>
 			</view>
-			<!-- <view class="fot">
-				<text @tap="reg_ok">免费注册</text>
-				<text style="display: inline-block;width: 10vw;"></text>
-				<text @tap="forget_ok">忘记密码</text>
-			</view> -->
 		</view>
 	</view>
 </template>
@@ -50,15 +34,9 @@
 	} from 'vuex'
 
 	export default {
-		mounted() {
-			// if(uni.getStorageSync("accounts")){
-			// 	this.accounts =[].concat(uni.getStorageSync("accounts")) 
-			// }
-			
-		},
 		data() {
 			return {
-				isfocus:false,
+				isfocus: false,
 				captchaImg: '',
 				accounts: [],
 				isrember: [],
@@ -92,10 +70,6 @@
 		},
 		methods: {
 			...mapActions(['refreshUserInfo']),
-			checkboxChange(n) {
-				console.log('change', n);
-				this.isrember[0] = n
-			},
 			// 登录
 			bindLogin() {
 				/**
@@ -105,11 +79,6 @@
 				this.$refs.uForm.validate().then(res => {
 					loginService.login(this.inputForm).then((data) => {
 						this.$store.commit('SET_TOKEN', data.token);
-						// if (this.isrember[0]) {
-						// 	this.accounts.push(this.inputForm)
-						// 	uni.setStorageSync("accounts", this.accounts)
-						// }
-
 						this.refreshUserInfo();
 						uni.reLaunch({
 							url: '../index/index',
@@ -137,9 +106,8 @@
 
 <style lang="scss" scoped>
 	// 记住账户展示
-	.focus_info{
-		
-	}
+	.focus_info {}
+
 	#box {
 		position: relative;
 		// color: $u-content-color;

+ 6 - 7
jp-mobile/pages/user/person/person.vue

@@ -1,5 +1,8 @@
 <template>
   <view class="main">
+	  <cu-custom bgColor="bg-blue">
+	  	<block slot="content">我的</block>
+	  </cu-custom>
     <view class="person-head">
 	  <view class="cu-avatar xl round margin-left-sm" @tap="ChooseImage" :style="`background-image:url('${avatar}')`" ></view>
       <view class="person-head-box">
@@ -96,7 +99,6 @@
 	 		sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
 	 		sourceType: ['album'], //从相册选择
 	 		success: (res) => {
-				console.log("photo",res);
 				this.upload(res.tempFilePaths[0])
 	 		}
 	 	});
@@ -115,15 +117,12 @@
 		    uni.showLoading()
 			loginService.logout().then((data)=>{
 	  		  		this.$store.commit('logout');
-					// uni.removeStorageSync("WMS-username");
-					// uni.removeStorageSync("WMS-userinfo");
-					// uni.removeStorageSync("dictList");
-					// uni.removeStorageSync("WMS-permission");
-					// uni.removeStorageSync("token");
 					uni.clearStorage();
+					uni.hideLoading()
 	  		  		uni.reLaunch({
 	  		  			url: '/pages/login/login'
 	  		  		})
+					
 	  		})
 	  }
     }
@@ -137,7 +136,7 @@
     align-items: center;
     height: 150px;
     padding-left: 20px;
-    background: linear-gradient(to right, #365fff, #36bbff);
+    background: #0081ff;
   }
 
   .person-head-box {

+ 15 - 11
jp-mobile/pages/user/setting/signature/signature.vue

@@ -41,6 +41,7 @@
 				loading: false,
 				inputForm: this.$auth.getUserInfo(),
 				fileList: [],
+				signPic: ''
 			}
 		},
 
@@ -50,7 +51,7 @@
 			 * 签名完成回调
 			 */
 			signToUrl(e) {
-				this.inputForm.signPic = e.data
+				this.signPic = e.data
 				if (e.error_code && e.error_code === '201') {
 					uni.showToast({
 						title: e.msg,
@@ -80,27 +81,28 @@
 								img.onload = function() {
 									const canvas = document.createElement('canvas');
 									const ctx = canvas.getContext('2d');
-			
+
 									canvas.width = img.width;
 									canvas.height = img.height;
-			
+
 									ctx.clearRect(0, 0, canvas.width, canvas.height);
 									ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
-			
+
 									// 使用异步的 toBlob 方法
 									canvas.toBlob(async (blob) => {
 										const fileSizeKB = blob.size / 1024;
 										if (Math.abs(fileSizeKB - targetSizeKB) <
 											tolerance || max - min < tolerance) {
 											// 当前质量足够接近目标大小,使用当前质量解析
-											const dataUrl = canvas.toDataURL(urlData.type, midQuality);
+											const dataUrl = canvas.toDataURL(urlData
+												.type, midQuality);
 											let result = that
 												.uploadFilePromise(dataUrl)
 											setTimeout(() => {
 												resolve(
 													result)
 											}, 1000)
-			
+
 										} else if (fileSizeKB > targetSizeKB) {
 											// 如果文件大小太大,降低质量,继续二分查找
 											binarySearch(min, midQuality);
@@ -126,10 +128,10 @@
 			},
 			// 新增图片
 			async afterRead(event) {
-				
+
 				// 当设置 multiple 为 true 时, file 为数组格式,否则为对象格式
 				let lists = [].concat(event.file)
-				
+
 				let fileListLen = this.fileList.length
 				lists.map((item) => {
 					this.fileList.push({
@@ -139,15 +141,15 @@
 					})
 				})
 				for (let i = 0; i < lists.length; i++) {
-					
+
 					let result = ""
 					if (lists[i].size > (200 * 1024)) {
 						result = await this.compressH5(lists[i], 150);
-						
+
 					} else {
 						result = await this.uploadFilePromise(lists[i].url)
 					}
-					
+
 					let item = this.fileList[fileListLen]
 
 					this.fileList.splice(fileListLen, 1, Object.assign(item, {
@@ -188,6 +190,8 @@
 					})
 					this.inputForm.signPic = files.join(",");
 
+				} else {
+					this.inputForm.signPic = this.signPic
 				}
 				userService.saveInfo(this.inputForm).then((data) => {
 					$auth.setUserInfo(this.inputForm)

+ 47 - 56
jp-mobile/pages/workbench/workbench.vue

@@ -1,8 +1,8 @@
 <template>
 	<view class="main">
-		<!-- <cu-custom bgColor="bg-blue">
-			<block slot="content">文件传阅</block>
-		</cu-custom> -->
+		<cu-custom bgColor="bg-blue">
+			<block slot="content">工作台</block>
+		</cu-custom>
 		<swiper class="screen-swiper square-dot bg-blue" :indicator-dots="true" :circular="true" :autoplay="true"
 			interval="2000" duration="500">
 			<swiper-item v-for="(item,index) in swiperList" :key="index">
@@ -35,8 +35,9 @@
 					<text class=" text-orange font-b">快捷入口</text>
 				</view>
 			</view>
+			<uni-section class="mb-10" title="文件传阅" type="line"></uni-section>
 			<view class="cu-list grid col-4 no-border">
-				<view @tap="add" class="circle-button-box">
+				<view @tap="add(1)" class="circle-button-box">
 					<view><u--image src="/static/index/icon4.png" width="40px" height="40px"></u--image></view>
 					<text>新增</text>
 				</view>
@@ -52,16 +53,33 @@
 					<view><u--image src="/static/index/icon2.png" width="40px" height="40px"></u--image></view>
 					<text>已归档</text>
 				</view>
-				<!-- <view @tap="toPerson" class="circle-button-box">
-					<view ><u--image src="/static/index/icon3.png" width="40px" height="40px"></u--image></view>
-					<text>通讯录</text>
-				</view> -->
+			</view>
+			<uni-section class="mb-10" title="用章审批" type="line"></uni-section>
+			<view class="cu-list grid col-4 no-border">
+				<view @tap="add(2)" class="circle-button-box">
+					<view><u--image src="/static/index/icon4.png" width="40px" height="40px"></u--image></view>
+					<text>新增</text>
+				</view>
+				<view @tap="toCommonList(1)" class="circle-button-box">
+					<view><u--image src="/static/index/icon1.png" width="40px" height="40px"></u--image></view>
+					<text>待办</text>
+				</view>
+				<view @tap="toCommonList(4)" class="circle-button-box">
+					<view><u--image src="/static/index/icon5.png" width="40px" height="40px"></u--image></view>
+					<text>已办</text>
+				</view>
+				<view @tap="toCommonList(3)" class="circle-button-box">
+					<view><u--image src="/static/index/icon2.png" width="40px" height="40px"></u--image></view>
+					<text>已归档</text>
+				</view>
+			</view>
+			<uni-section class="mb-10" title="公文统计" type="line"></uni-section>
+			<view class="cu-list grid col-4 no-border">
 				<view @tap="toApplyList" class="circle-button-box">
 					<view><u--image src="/static/index/icon6.png" width="40px" height="40px"></u--image></view>
 					<text>公文统计</text>
 				</view>
 			</view>
-
 			<u-gap height="80" bgColor="#fff"></u-gap>
 		</scroll-view>
 	</view>
@@ -120,7 +138,7 @@
 				statistics: {},
 			};
 		},
-		
+
 		computed: mapState({
 			username: (state) => state.user.username
 		}),
@@ -128,27 +146,6 @@
 			gwCirculationCard2Service.getStatistics().then(data => {
 				this.statistics = data
 			})
-			// let res = await actCategoryService.treeData()
-			// let data = await processService.list({current: 1, size: -1})
-			// this.processMap = new Map()
-			// res.forEach((item)=>{
-			// 	this.processMap.set(item.name, [])
-			// })
-			// let list = data.records
-			// list.forEach((item)=>{
-			// 	if(this.processMap.has(item.category)){
-			// 		let list = this.processMap.get(item.category)
-			// 		list.push(item)
-			// 	}else{
-			// 		this.processMap.set(item.category, [item])
-			// 	}
-			// })
-
-			// for(let [key,value] of this.processMap){
-			//     console.log(key,value);
-			// }
-
-
 		},
 		created() {
 			if (!this.username) {
@@ -163,9 +160,15 @@
 				})
 			},
 			add(mail) {
-				uni.navigateTo({
-					url: '/pages/fileTransmit/addFileTransmit'
-				})
+				if(mail == 1){
+					uni.navigateTo({
+						url: '/pages/fileTransmit/addFileTransmit'
+					})
+				}else {
+					uni.navigateTo({
+						url: '/pages/commonseal/addCommon'
+					})
+				}
 			},
 			toPerson(mail) {
 				uni.navigateTo({
@@ -177,33 +180,21 @@
 					url: '/pages/fileTransmit/fileTransmitList?type=' + type
 				})
 			},
-			start(row) {
-				// 读取流程表单
-				taskService.getTaskDef({
-					procDefId: row.id,
-					status: 'start'
-				}).then((data) => {
-					let processTitle =
-						`${this.username} 在 ${moment(new Date()).format('YYYY-MM-DD HH:mm')} 发起了 [${row.name}]`
-					let query = {
-						procDefId: row.id,
-						procDefKey: row.key,
-						status: 'start',
-						title: `发起流程【${row.name}】`,
-						formType: data.formType,
-						formUrl: data.formUrl,
-						formTitle: processTitle
-					}
-					uni.navigateTo({
-						url: '/pages/workbench/task/TaskForm?flow=' + JSON.stringify(query)
-					})
+			toCommonList(type) {
+				uni.navigateTo({
+					url: '/pages/commonseal/commonList?type=' + type
 				})
-			}
+			},
 		}
 	}
 </script>
 
 <style>
+	.page .uni-section {
+		border-bottom: 1px solid #ededed;
+		padding-left: 10px;
+	}
+
 	.cu-list.card-menu {
 		overflow: hidden;
 		margin-right: 5px;
@@ -242,7 +233,7 @@
 
 	.circle-button-box {
 		width: 25%;
-		margin-top: 30px;
+		margin-top: 10px;
 		display: -webkit-box;
 		display: -webkit-flex;
 		display: flex;

+ 4 - 0
jp-mobile/static/css/jeeplus.scss

@@ -46,6 +46,10 @@
 	background-color: #0081ff !important;
 	color: #ffffff;
 }
+.bg-blue_default {
+	background-color: #36a7f3 !important;
+	color: #ffffff;
+}
 
 .u-form{
 	padding-top: 25rpx;

+ 5 - 0
jp-mobile/static/css/main.css

@@ -15,6 +15,7 @@ body {
 	color: #333333;
 	background-color: #eee;
 	font-family: Helvetica Neue, Helvetica, sans-serif;
+	/* font-family:'楷体' */
 }
 .main *{
 	font-size: 20px!important;
@@ -3440,6 +3441,10 @@ scroll-view.cu-steps .cu-item {
 	background-color: #0081ff !important;
 	color: #ffffff;
 }
+.bg-blue_default {
+	background-color: #36a7f3 !important;
+	color: #ffffff;
+}
 
 .bg-purple {
 	background-color: #6739b6;

+ 114 - 0
jp-mobile/uni_modules/lsj-upload/changelog.md

@@ -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自定义按钮样式

+ 400 - 0
jp-mobile/uni_modules/lsj-upload/components/lsj-upload/LsjFile.js

@@ -0,0 +1,400 @@
+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: () => {
+				this.toast(`打开失败`);
+			}
+		})
+	}
+	
+	_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);
+				}
+			})
+		});
+	}
+}

+ 321 - 0
jp-mobile/uni_modules/lsj-upload/components/lsj-upload/lsj-upload.vue

@@ -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>

文件差異過大導致無法顯示
+ 5 - 0
jp-mobile/uni_modules/lsj-upload/hybrid/html/js/vue.min.js


+ 198 - 0
jp-mobile/uni_modules/lsj-upload/hybrid/html/uploadFile.html

@@ -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>

+ 78 - 0
jp-mobile/uni_modules/lsj-upload/package.json

@@ -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"
+                }
+            }
+        }
+    }
+}

+ 353 - 0
jp-mobile/uni_modules/lsj-upload/readme.md

@@ -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颗小星星以作鼓励哈~

部分文件因文件數量過多而無法顯示