瀏覽代碼

Merge branch 'master' of http://git.zthymaoyi.com/gdc/yiliangyiyun-app

gjy 2 年之前
父節點
當前提交
4f8a3faebd

+ 19 - 2
App.vue

@@ -6,10 +6,20 @@
 		mapMutations
 	} from 'vuex';
 	import * as config from '@/config'
-	import appUpdate from 'common/appUpdate.js'
+	// import appUpdate from 'common/appUpdate.js'
+	// #ifdef APP-PLUS
+	import APPUpdate, {
+		getCurrentNo
+	} from '@/uni_modules/zhouWei-APPUpdate/js_sdk/appUpdate';
+	// #endif
 	import app_push from './components/APPPush/app_push.js'
 	const pushLive = uni.requireNativePlugin('service-keep-live');
 	export default {
+		data(){
+			return{
+				version:"",
+			}
+		},
 		methods: {
 			...mapMutations(['login']),
 			nvueRequst: function(method, url, data, header) {
@@ -276,10 +286,17 @@
 
 		},
 		onShow: function() {
+			// #ifdef APP-PLUS
+			getCurrentNo(res => {
+				// 进页面获取当前APP版本号(用于页面显示)
+				this.version = res.versionName;
+			});
+			// #endif
 			let type = uni.getSystemInfoSync().platform
 			console.log(type)
 			if (type == "android") {
-				// appUpdate()
+				// AppUpdate()
+				APPUpdate()
 			}
 			console.log('App Show')
 		},

+ 1 - 1
common/appUpdate.js

@@ -5,7 +5,7 @@ import * as config from '../config'
 export default function appUpdate() {
 		
 	uni.request({
-	    url: 'http://api1.eliangeyun.com/appVersion/selectInfo',
+	    url: 'https://api2.eliangeyun.com/appVersion/selectInfo',
 	    data: {
 	    	appid: plus.runtime.appid,
 	    	version: plus.runtime.version,

+ 103 - 0
config/componentConfig.js

@@ -0,0 +1,103 @@
+/**** 此文件说明请看注释 *****/
+// 可以用自己项目的请求方法
+// 请求配置说明:https://ext.dcloud.net.cn/plugin?id=822
+// import $http from '@/config/requestConfig';
+/**** 结束 *****/
+const platform = uni.getSystemInfoSync().platform;
+import * as config from '../config'
+
+export default {
+	// 发起ajax请求获取服务端版本号
+	getServerNo: (version, isPrompt = false, callback) => {
+		let httpData = {
+			version: version.versionCode,
+			// 版本名称
+			versionName: version.versionName,
+			// setupPage参数说明(判断用户是不是从设置页面点击的更新,如果是设置页面点击的更新,有不要用静默更新了,不然用户点击没反应很奇怪的)
+			setupPage: isPrompt
+		};
+		if (platform == "android") {
+			httpData.type = 1101;
+		} else {
+			httpData.type = 1102;
+		}
+		/* 接口入参说明
+		 * version: 应用当前版本号(已自动获取)
+		 * versionName: 应用当前版本名称(已自动获取)
+		 * type:平台(1101是安卓,1102是IOS)
+		 */
+		/****************以下是示例*******************/
+		// 可以用自己项目的请求方法(接口自己找后台要,插件不提供
+		const baseUrlNew = config.def().baseUrlNew
+		uni.request({
+			url: baseUrlNew + '/appVersion/selectInfo',
+			data: {
+				appid: plus.runtime.appid,
+				version: plus.runtime.version,
+				imei: "1",
+			},
+			method: 'GET',
+			success: (res) => {
+				console.log(res.data)
+				if (res.data.data && res.data.data.wgtUrl) {
+					res.data.data.versionName = res.data.data.version
+					res.data.data.versionInfo = res.data.data.note
+					res.data.data.downloadUrl = res.data.data.wgtUrl
+					// 兼容之前的版本(updateType是新版才有的参数)
+					if (res.data.data.updateType) {
+						callback && callback(res.data.data);
+					} else {
+						if (res.forceUpdate) {
+							res.updateType = "forcibly";
+						} else {
+							res.updateType = "solicit";
+						}
+						callback && callback(res.data.data);
+					}
+				} else if (isPrompt) {
+					uni.showToast({
+						title: "暂无新版本",
+						icon: "none"
+					});
+				}
+			}
+		})
+		//      $http.get("api/common/v1/app_version", httpData,{
+		//          isPrompt: isPrompt
+		//      }).then(res => {
+		// console.log("新更新res",res)
+		//          /* res的数据说明
+		//           * | 参数名称        | 一定返回     | 类型        | 描述
+		//           * | -------------|--------- | --------- | ------------- |
+		//           * | versionCode     | y        | int       | 版本号        |
+		//           * | versionName     | y        | String    | 版本名称      |
+		//           * | versionInfo     | y        | String    | 版本信息      |
+		//           * | updateType      | y        | String    | forcibly = 强制更新, solicit = 弹窗确认更新, silent = 静默更新 |
+		//           * | downloadUrl     | y        | String    | 版本下载链接(IOS安装包更新请放跳转store应用商店链接,安卓apk和wgt文件放文件下载链接)  |
+		//           */
+		//          if (res && res.downloadUrl) {
+		//              // 兼容之前的版本(updateType是新版才有的参数)
+		//              if(res.updateType){
+		//                  callback && callback(res);
+		//              } else {
+		//                  if(res.forceUpdate){
+		//                      res.updateType = "forcibly";
+		//                  } else {
+		//                      res.updateType = "solicit";
+		//                  }
+		//                  callback && callback(res);
+		//              }
+		//          } else if (isPrompt) {
+		//              uni.showToast({
+		//                  title: "暂无新版本",
+		//                  icon: "none"
+		//              });
+		//          }
+		//      });
+		/****************以上是示例*******************/
+	},
+	// 弹窗主颜色(不填默认粉色)
+	appUpdateColor: "f00",
+	// 弹窗图标(不填显示默认图标,链接配置示例如: '/static/demo/ic_attention.png')
+	appUpdateIcon: ''
+}

+ 2 - 4
config/index.js

@@ -7,11 +7,9 @@ const dev = {
 	// baseUrlNew: 'http://192.168.1.122:8090/',
 	// baseUrlNew: 'http://192.168.110.82:8099/',
 	// baseUrlNew: 'http://192.168.110.202:8090/',
-	baseUrlNew: 'http://192.168.110.138:8090/',
+	// baseUrlNew: 'http://192.168.110.138:8090/',
 	// 上传图片的
-	// baseUrlNew1: 'http://192.168.110.82:9527/',
-	baseUrlNew1: 'https://api2.eliangeyun.com/',
-	// baseUrlNew: 'http://api1.eliangeyun.com/',
+	baseUrlNew: 'https://api2.eliangeyun.com/',
 	h5Appid: 'wxb66b599f7f61b46f',
 	debug: false
 }

+ 19 - 3
manifest.json

@@ -2,8 +2,8 @@
     "name" : "易粮易运",
     "appid" : "__UNI__7297DA2",
     "description" : "易粮易运——为天下粮食人服务的App",
-    "versionName" : "2.1.106",
-    "versionCode" : 21106,
+    "versionName" : "2.1.107",
+    "versionCode" : 21107,
     "transformPx" : false,
     /* SDK配置 */
     "quickapp" : {},
@@ -124,7 +124,9 @@
                     "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
                     "<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>",
                     "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
-                    "<uses-permission android:name=\"android.permission.RECORD_AUDIO\"/>"
+                    "<uses-permission android:name=\"android.permission.RECORD_AUDIO\"/>",
+					"<uses-permission android:name=\"android.permission.INSTALL_PACKAGES\"/>  ",
+					"<uses-permission android:name=\"android.permission.REQUEST_INSTALL_PACKAGES\"/>"
                 ]
             },
             "icons" : {
@@ -216,6 +218,20 @@
                     "pid" : "2018",
                     "parameters" : {}
                 }
+            },
+            "service-keep-live" : {
+                "__plugin_info__" : {
+                    "name" : "【推荐】安卓保活插件 防杀  增强保活,黑屏防睡眠(测试黑屏传数据一天多没问题)",
+                    "description" : "如果你的应用希望能够一直在后台运行而不被系统自动杀死的话,可以尝试一下。群485147231(已满) 598812409",
+                    "platforms" : "Android",
+                    "url" : "https://ext.dcloud.net.cn/plugin?id=3422",
+                    "android_package_name" : "uni.UNI7297DA2",
+                    "ios_bundle_id" : "uni.UNI7297DA2",
+                    "isCloud" : true,
+                    "bought" : 1,
+                    "pid" : "3422",
+                    "parameters" : {}
+                }
             }
         }
     }

+ 7 - 2
pages/clock/supp_clock.vue

@@ -5,7 +5,7 @@
 				<view class="c-row">
 					<view class="title">补卡原因</view>
 					<view class="con-list">
-						<u-radio-group  activeColor="#22C572" v-model="typevalue">
+						<u-radio-group activeColor="#22C572" v-model="typevalue">
 							<u-radio key="1" label="上班" name="1">上班</u-radio>
 							<u-radio key="3" label="下班" name="3">下班</u-radio>
 						</u-radio-group>
@@ -149,6 +149,10 @@
 					confirmText: '提交',
 					success: function(res) {
 						if (res.confirm) {
+							uni.showLoading({
+								mask: true,
+								title: '加载中'
+							})
 							that.detailData.id = that.id
 							that.detailData.compId = uni.getStorageSync('pcUserInfo').compId
 							that.detailData.commonId = uni.getStorageSync('pcUserInfo').userId
@@ -157,8 +161,9 @@
 								.then(res => {
 									if (res.data.code == 200) {
 										that.$api.msg('提交成功')
+										uni.hideLoading()
 										uni.navigateTo({
-											url: '/pages/clock/the_clock_record'
+											url: '/pages/clock/the_clock?value=1'
 										})
 									} else {
 										that.$api.msg('提交失败')

+ 35 - 9
pages/clock/the_clock.vue

@@ -52,11 +52,12 @@
 							<view class="toClockDate" v-if="item.toClockDate">{{ item.toClockDate.split(" ")[1] }}
 							</view>
 							<view class="toClockDate" v-else-if="!item.toClockDate">
-								<button v-if='item.approveStatus ==null && item.status == null' @click='supp(item)'
-									class="uni-button" size="mini" type="primary" align="center"
-									style="height: 30px;">补卡</button>
-								<button v-if='item.approveStatus=="待人事审核"' class='listitemStatus audit Regular'
-									size="mini" type="primary" align="center" style="height: 30px;">审核中</button>
+								<view v-if='item.approveStatus ==null && item.status == null' @click='supp(item)'
+									class="bk-button">补卡</view>
+								<view v-if='item.approveStatus=="待人事审核"' class='listitemStatus audit Regular'>待人事审核
+								</view>
+								<view v-if='item.approveStatus=="待主管审核"' class='listitemStatus audit Regular'>待主管审核
+								</view>
 								<button v-if='item.status=="补卡失败"' class='listitemStatus notPass Regular' size="mini"
 									type="primary" align="center" style="height: 30px;">补卡失败</button>
 								<button v-if='item.status=="补卡成功"' class='listitemStatus pass Regular' size="mini"
@@ -67,9 +68,8 @@
 							<view class="offClockDate" v-if="item.offClockDate">{{ item.offClockDate.split(" ")[1] }}
 							</view>
 							<view class="offClockDate" v-else-if="!item.offClockDate">
-								<button v-if='item.approveStatus ==null && item.status == null' @click='supp(item)'
-									class="uni-button" size="mini" type="primary" align="center"
-									style="height: 30px;">补卡</button>
+								<view v-if='item.approveStatus ==null && item.status == null' @click='supp(item)'
+									class="bk-button">补卡</view>
 								<button v-if='item.approveStatus=="待人事审核"' class='listitemStatus audit Regular'
 									size="mini" type="primary" align="center" style="height: 30px;">审核中</button>
 								<button v-if='item.status=="补卡失败"' class='listitemStatus notPass Regular' size="mini"
@@ -132,7 +132,10 @@
 		onShow() {
 			this.getList()
 		},
-		onLoad() {
+		onLoad(options) {
+			if (options.value) {
+				this.value = 1
+			}
 			console.log(uni.getStorageSync("clockwerehouse"))
 			if (!uni.getStorageSync("clockwerehouse")) {
 				uni.showLoading({
@@ -150,6 +153,11 @@
 			this.createDate = _day.getFullYear() + "-" + (_day.getMonth() + 1);
 		},
 		methods: {
+			supp(item) {
+				uni.navigateTo({
+					url: '/pages/clock/supp_clock' + `?id=${item.id}`,
+				})
+			},
 			dateChange(e) {
 				console.log(e)
 				this.createDate = e.year + "-" + e.month
@@ -427,4 +435,22 @@
 		}
 
 	}
+
+	.listitemStatus {
+		color: red;
+	}
+
+	.bk-button {
+		background: #22C572;
+		color: white;
+		width: 100rpx;
+		padding: 10rpx;
+		box-sizing: border-box;
+		border-radius: 50rpx;
+	}
+
+	.offClockDate {
+		display: flex;
+		justify-content: center;
+	}
 </style>

+ 2 - 2
pages/erp/exWarehousing/exWarehousing.vue

@@ -562,7 +562,7 @@
 				this.weightbills.goodsName = this.inOutNoList[e[0]].goodsName
 				if (this.detailData.inOutType == '销售出库') {
 					this.weightbills.buyer = this.inOutNoList[e[0]].buyer
-					this.weightbills.seller = uni.getStorageSync('compName')
+					this.weightbills.seller = uni.getStorageSync('compName1')
 					if (this.detailData.tips = '买方' + this.contractNoList[e[0]].buyer) {
 						this.detailData.tips = '买方' + this.contractNoList[e[0]].buyer +
 							'( ' +
@@ -573,7 +573,7 @@
 					}
 				} else if (this.detailData.inOutType == '移库出库') {
 					this.weightbills.buyer = this.inOutNoList[e[0]].receiveWarehouse
-					this.weightbills.seller = uni.getStorageSync('compName')
+					this.weightbills.seller = uni.getStorageSync('compName1')
 					this.detailData.tips = '入货库' + this.inOutNoList[e[0]].receiveWarehouse
 				}
 			},

+ 1 - 1
pages/erpbusiness/add_quality_testing.vue

@@ -583,7 +583,7 @@
 			this.gridList.warehouseName = options.warehouseName
 			// this.gridList.qualityNo = 'SGRK' + this.getdate() + this.commonWarehouseNo + number
 			this.cangid = options.cangid
-			this.gridList.compName = uni.getStorageSync('compName')
+			this.gridList.compName = uni.getStorageSync('compName1')
 			this.gridList.person= options.personCharge
 			this.gridList.personPhone= options.personPhone
 			this.gridList.qualityInspector= uni.getStorageSync("userInfo").userName

+ 6 - 1
pages/leave/the_leave.vue

@@ -51,7 +51,11 @@
 		<view class="" v-else>
 
 			<view class='wrap' v-for="(item, index) in tableData" :key="index">
-				<view class="wenzi audit1" v-if="item.approveStatus == '待人事审核' || item.approveStatus == '待主管审核' ">审核中
+				<view class="wenzi audit1" v-if="item.approveStatus == '待人事审核'">待人事审核
+				</view>
+				<view class="wenzi audit1" v-if="item.approveStatus == '待主管审核'">待主管审核
+				</view>
+				<view class="wenzi audit1" v-if="item.approveStatus == '待决策人审核'">待决策人审核
 				</view>
 				<view class="wenzi audit2" v-if="item.status == '已通过'">已通过</view>
 				<view class="wenzi audit3" v-if="item.status == '未通过'">未通过</view>
@@ -299,6 +303,7 @@
 										that.$api.msg('提交成功')
 										uni.hideLoading()
 										that.value = 1
+										that.getList()
 										// uni.navigateTo({
 										// 	url: '/pages/leave/the_leave_record'
 										// })

+ 1 - 1
pages/reimbursement/request_funds.vue

@@ -168,7 +168,7 @@
 				console.log(e)
 			},
 			uploadClick() {
-				let baseUrlNew = config.def().baseUrlNew1
+				let baseUrlNew = config.def().baseUrlNew
 				uni.chooseImage({
 					success: (chooseImageRes) => {
 						let a = chooseImageRes.tempFiles

+ 59 - 3
pages/user/setUp.vue

@@ -41,18 +41,27 @@
 				</view>
 				<image src="../../static/img/myimg/gengduo1@3x.png" class="arrow"></image>
 			</view>
-			<view class='cu-item' style='margin-bottom:10px;' @click='updataEdition'>
+			<!-- <view class='cu-item' style='margin-bottom:10px;' @click='updataEdition'>
 				<view>
 					<text>检查新版本</text>
 				</view>
 				<image src="../../static/img/myimg/gengduo1@3x.png" class="arrow"></image>
-			</view>
+			</view> -->
 			<view class='cu-item' style='margin-bottom:10px;' @click='unsubscribe'>
 				<view>
 					<text>注销账户</text>
 				</view>
 				<image src="../../static/img/myimg/gengduo1@3x.png" class="arrow"></image>
 			</view>
+			<view class='cu-item' style='margin-bottom:10px;'>
+				<view>
+					<text>检查更新</text>
+				</view>
+				<view class="version_css" @click="onAPPUpdate">
+					{{version}}
+					<image src="../../static/img/myimg/gengduo1@3x.png" class="arrow"></image>
+				</view>
+			</view>
 		</view>
 		<view class='exitloginwrap'>
 			<button @click='logout()' class='exitlogin'>退出登录</button>
@@ -68,6 +77,12 @@
 	import {
 		mapState
 	} from 'vuex';
+	// #ifdef APP-PLUS
+	import APPUpdate, {
+		getCurrentNo
+	} from '@/uni_modules/zhouWei-APPUpdate/js_sdk/appUpdate';
+	import * as config from '@/config/index.js'
+	// #endif
 	export default {
 		data() {
 			return {
@@ -84,6 +99,7 @@
 					url: '',
 					show: true
 				}, ],
+				version:"1.1.0"
 			}
 		},
 		computed: {
@@ -91,15 +107,49 @@
 		},
 		onShow() {
 			this.getList()
+			// #ifdef APP-PLUS
+			this.version = plus.runtime.version
+			console.log("当前版本为:",plus.runtime.version)
+			this.checkVersion()
+			// #endif
 		},
 		onLoad() {},
 		methods: {
+			// 检查APP是否有新版本
+			onAPPUpdate() {
+				// true 没有新版本的时候有提示,默认:false
+				if (this.version == "发现新版本,立即更新") {
+					// #ifdef APP-PLUS
+					APPUpdate(true);
+					// #endif
+				}
+			},
+			checkVersion() {
+				const baseUrlNew = config.def().baseUrlNew
+				uni.request({
+					url: baseUrlNew + '/appVersion/selectInfo',
+					data: {
+						appid: plus.runtime.appid,
+						version: plus.runtime.version,
+						imei: "1",
+					},
+					method: 'GET',
+					success: (res) => {
+						var versionNo = plus.runtime.version
+						if (versionNo == res.data.data.version) {
+							this.version = "当前为最新版" + res.data.data.version
+						} else {
+							this.version = "发现新版本,立即更新"
+						}
+					}
+				})
+			},
 			updataEdition() {
 				// #ifdef APP-PLUS
 				let type = uni.getSystemInfoSync().platform
 				if (type == "android") {
 					uni.request({
-						url: 'http://api1.eliangeyun.com/appVersion/selectInfo',
+						url: 'https://api2.eliangeyun.com/appVersion/selectInfo',
 						data: {
 							appid: plus.runtime.appid,
 							version: plus.runtime.version,
@@ -418,4 +468,10 @@
 	.exitlogin:after {
 		border: none;
 	}
+	.version_css {
+		// margin-right: 10rpx;
+		color: #9D9D9D;
+		font-size: 32rpx;
+		text-align: center;
+	}
 </style>

+ 44 - 24
pages/user/user.vue

@@ -397,11 +397,14 @@
 			this.scrollTop = e.scrollTop;
 		},
 		onShow() {
-			if (uni.getStorageSync('compName')) {
-				this.haveCompany = true
-			} else {
-				this.haveCompany = false
-			}
+			console.log("uni.getStorageSync('compName1')")
+			// console.log(uni.getStorageSync("compName1"))
+			
+			// if (uni.getStorageSync("compName1")) {
+			// 	this.haveCompany = true
+			// } else {
+			// 	this.haveCompany = false
+			// }
 			this.isShow();
 			uni.hideKeyboard()
 			uni.showTabBar()
@@ -409,7 +412,8 @@
 				index: 4
 			})
 			this.loadData()
-			console.log("hasLogin", this.hasLogin)
+			console.log("hasLogin", this.hasLogin)				
+			var that = this
 			if (this.userInfo) {
 				if (!this.userInfo.avatarUrl) {
 					this.headUrl = "../../static/img/myimg/YongHu@3x.png"
@@ -419,7 +423,6 @@
 				this.username = this.userInfo.userName ? this.userInfo.userName : uni.getStorageSync("userInfo").data
 					.userName
 				this.userphone = this.userInfo.phone ? this.userInfo.phone : uni.getStorageSync("userInfo").data.phone
-				var that = this
 				this.$api.doRequest('get', '/newNoticeTask/query/noticeTasks').then(res => {
 					console.log("noticeNumber", res)
 					if (res.data.data) {
@@ -449,22 +452,39 @@
 						// });
 					}
 				})
-				if (!uni.getStorageSync('compName')) {
-					this.$api.doRequest('get', '/commonUser/getCompOwn', {
-						phone: this.userInfo.phone
-					}).then(res => {
-						if (res.data.data) {
-							this.companyList = res.data.data
-							if (this.companyList.length > 0) {
-								this.compName = this.companyList[0].compName
-								uni.setStorageSync('compName', this.companyList[0].compName)
-								this.haveCompany = true
-							}
+									console.log("this.1111")
+				uni.getStorage({
+					key: 'compName1',
+					success: function (res) {
+									console.log("this.2222")
+						console.log(res.data);
+						if(res.data){
+							that.compName = res.data
+							that.haveCompany = true
 						}
-					})
-				} else {
-					this.compName = uni.getStorageSync('compName')
-				}
+					},
+					fail() {
+						that.$api.doRequest('get', '/commonUser/getCompOwn', {
+							phone: that.userInfo.phone
+						}).then(res => {
+							if (res.data.data) {
+								that.companyList = res.data.data
+									console.log("that.3333")
+									console.log(that.companyList)
+								if (that.companyList.length > 0) {
+									that.compName = that.companyList[0].compName
+									console.log("this.compName")
+									console.log(that.compName)
+									uni.setStorageSync('compName1', that.companyList[0].compName)
+									that.haveCompany = true
+								}
+								else{
+									that.haveCompany = false
+								}
+							}
+						})
+					}
+				});
 
 			} else {
 				this.headUrl = "../../static/img/myimg/YongHu@3x.png"
@@ -491,7 +511,7 @@
 				}).then(res1 => {
 					if (res1.data.code == 200) {
 						uni.setStorageSync('pcUserInfo', res1.data.data)
-						uni.setStorageSync('compName', that.companyList[e[0]].compName)
+						uni.setStorageSync('compName1', that.companyList[e[0]].compName)
 						that.compName = that.companyList[e[0]].compName
 						helper.getListByUserId()
 						that.$api.msg('切换成功')
@@ -502,7 +522,7 @@
 							veriCode: "123456",
 						}).then(res2 => {
 							uni.setStorageSync('pcUserInfo', res2.data.data)
-							uni.setStorageSync('compName', that.companyList[e[0]].compName)
+							uni.setStorageSync('compName1', that.companyList[e[0]].compName)
 							that.compName = that.companyList[e[0]].compName
 							helper.getListByUserId()
 							that.$api.msg('切换成功')

二進制
static/img/oa_office/clock.png


二進制
static/img/oa_office/fulling.png


二進制
static/img/oa_office/leave.png


二進制
static/img/oa_office/reimbursement.png


二進制
static/img/oa_office/shortfull.png


+ 1 - 1
static/map_0110.html

@@ -78,7 +78,7 @@
 			$.ajax({
 				type: "GET",
 				contentType: "application/json;charset=UTF-8",
-				url: "http://api1.eliangeyun.com/biInfoController/selectBiInfo?compId=" + compId+ '&seachMoth=' + seachMoth,
+				url: "https://api2.eliangeyun.com/biInfoController/selectBiInfo?compId=" + compId+ '&seachMoth=' + seachMoth,
 				success: function(result) {
 					console.log("result", result);
 					$("#progressBar").hide();

+ 5 - 0
uni_modules/zhouWei-APPUpdate/changelog.md

@@ -0,0 +1,5 @@
+## 3.0.1(2021-05-13)
+1. 跳转颜色和图标配置
+2. 新增静默更新
+## 3.0.0(2021-05-12)
+1. 支持uni_modules

+ 830 - 0
uni_modules/zhouWei-APPUpdate/js_sdk/appUpdate.js

@@ -0,0 +1,830 @@
+// #ifdef APP-PLUS 
+import componentConfig from "@/config/componentConfig"
+const platform = uni.getSystemInfoSync().platform;
+// 主颜色
+const $mainColor = componentConfig.appUpdateColor ? componentConfig.appUpdateColor : "FF5B78";
+// 弹窗图标url
+const $iconUrl = componentConfig.appUpdateIcon ? componentConfig.appUpdateIcon : "/uni_modules/zhouWei-APPUpdate/static/ic_ar.png";
+
+// 获取当前应用的版本号
+export const getCurrentNo = function(callback) {
+	// 获取本地应用资源版本号
+	plus.runtime.getProperty(plus.runtime.appid, function(inf) {
+		callback && callback({
+			versionCode: inf.versionCode,
+			versionName: inf.version
+		});
+	});
+}
+// 从服务器下载应用资源包(wgt文件)
+const getDownload = function(data) {
+	let dtask;
+	if(data.updateType == 'forcibly' || data.updateType == 'solicit'){
+		let popupData = {
+			progress: true,
+			buttonNum: 2
+		};
+		if(data.updateType == 'forcibly'){
+			popupData.buttonNum = 0;
+		}
+		let lastProgressValue = 0;
+		let popupObj = downloadPopup(popupData);
+		dtask = plus.downloader.createDownload(data.downloadUrl, {
+			filename: "_doc/update/"
+		}, function(download, status) {
+			if (status == 200) {
+				popupObj.change({
+					progressValue: 100,
+					progressTip:"正在安装文件...",
+					progress: true,
+					buttonNum: 0
+				});
+				plus.runtime.install(download.filename, {}, function() {
+					popupObj.change({
+						contentText: "应用资源更新完成!",
+						buttonNum: 1,
+						progress: false
+					});
+				}, function(e) {
+					popupObj.cancel();
+					plus.nativeUI.alert("安装文件失败[" + e.code + "]:" + e.message);
+				});
+			} else {
+				popupObj.change({
+					contentText: "文件下载失败...",
+					buttonNum: 1,
+					progress: false
+				});
+			}
+		});
+		dtask.start();
+		dtask.addEventListener("statechanged", function(task, status) {
+			switch (task.state) {
+				case 1: // 开始
+					popupObj.change({
+						progressValue:0,
+						progressTip:"准备下载...",
+						progress: true
+					});
+					break;
+				case 2: // 已连接到服务器  
+					popupObj.change({
+						progressValue:0,
+						progressTip:"开始下载...",
+						progress: true
+					});
+					break;
+				case 3:
+					const progress = parseInt(task.downloadedSize / task.totalSize * 100);
+					if(progress - lastProgressValue >= 2){
+						lastProgressValue = progress;
+						popupObj.change({
+							progressValue:progress,
+							progressTip: "已下载" + progress + "%",
+							progress: true
+						});
+					}
+					break;
+			}
+		});
+		// 取消下载
+		popupObj.cancelDownload = function(){
+			dtask && dtask.abort();
+			uni.showToast({
+				title: "已取消下载",
+				icon:"none"
+			});
+		}
+		// 重启APP
+		popupObj.reboot = function(){
+			plus.runtime.restart();
+		}
+	} else if(data.updateType == "silent"){
+		dtask = plus.downloader.createDownload(data.downloadUrl, {
+			filename: "_doc/update/"
+		}, function(download, status) {
+			if (status == 200) {
+				plus.runtime.install(download.filename, {}, function() {
+					console.log("应用资源更新完成");
+				}, function(e) {
+					plus.nativeUI.alert("安装文件失败[" + e.code + "]:" + e.message);
+				});
+			} else {
+				plus.nativeUI.alert("文件下载失败...");
+			}
+		});
+		dtask.start();
+	}
+}
+// 文字换行
+function drawtext(text, maxWidth) {
+	let textArr = text.split("");
+	let len = textArr.length;
+	// 上个节点
+	let previousNode = 0;
+	// 记录节点宽度
+	let nodeWidth = 0;
+	// 文本换行数组
+	let rowText = [];
+	// 如果是字母,侧保存长度
+	let letterWidth = 0;
+	// 汉字宽度
+	let chineseWidth = 14;
+	// otherFont宽度
+	let otherWidth = 7;
+	for (let i = 0; i < len; i++) {
+		if (/[\u4e00-\u9fa5]|[\uFE30-\uFFA0]/g.test(textArr[i])) {
+			if(letterWidth > 0){
+				if(nodeWidth + chineseWidth + letterWidth * otherWidth > maxWidth){
+					rowText.push({
+						type: "text",
+						content: text.substring(previousNode, i)
+					});
+					previousNode = i;
+					nodeWidth = chineseWidth;
+					letterWidth = 0;
+				} else {
+					nodeWidth += chineseWidth + letterWidth * otherWidth;
+					letterWidth = 0;
+				}
+			} else {
+				if(nodeWidth + chineseWidth > maxWidth){
+					rowText.push({
+						type: "text",
+						content: text.substring(previousNode, i)
+					});
+					previousNode = i;
+					nodeWidth = chineseWidth;
+				}else{
+					nodeWidth += chineseWidth;
+				}
+			}
+		} else {
+			if(/\n/g.test(textArr[i])){
+				rowText.push({
+					type: "break",
+					content: text.substring(previousNode, i)
+				});
+				previousNode = i + 1;
+				nodeWidth = 0;
+				letterWidth = 0;
+			}else if(textArr[i] == "\\" && textArr[i + 1] == "n"){
+				rowText.push({
+					type: "break",
+					content: text.substring(previousNode, i)
+				});
+				previousNode = i + 2;
+				nodeWidth = 0;
+				letterWidth = 0;
+			}else if(/[a-zA-Z0-9]/g.test(textArr[i])){
+				letterWidth += 1;
+				if(nodeWidth + letterWidth * otherWidth > maxWidth){
+					rowText.push({
+						type: "text",
+						content: text.substring(previousNode, i + 1 - letterWidth)
+					});
+					previousNode = i + 1 - letterWidth;
+					nodeWidth = letterWidth * otherWidth;
+					letterWidth = 0;
+				}
+			} else{
+				if(nodeWidth + otherWidth > maxWidth){
+					rowText.push({
+						type: "text",
+						content: text.substring(previousNode, i)
+					});
+					previousNode = i;
+					nodeWidth = otherWidth;
+				}else{
+					nodeWidth += otherWidth;
+				}
+			}
+		}
+	}
+	if (previousNode < len) {
+		rowText.push({
+			type: "text",
+			content: text.substring(previousNode, len)
+		});
+	}
+	return rowText;
+}
+// 是否更新弹窗
+function updatePopup(data, callback) {
+	// 弹窗遮罩层
+	let maskLayer = new plus.nativeObj.View("maskLayer", { //先创建遮罩层
+		top: '0px',
+		left: '0px',
+		height: '100%',
+		width: '100%',
+		backgroundColor: 'rgba(0,0,0,0.5)'
+	});
+
+	// 以下为计算菜单的nview绘制布局,为固定算法,使用者无关关心
+	const screenWidth = plus.screen.resolutionWidth;
+	const screenHeight = plus.screen.resolutionHeight;
+	//弹窗容器宽度
+	const popupViewWidth = screenWidth * 0.7;
+	// 弹窗容器的Padding
+	const viewContentPadding = 20;
+	// 弹窗容器的宽度
+	const viewContentWidth = parseInt(popupViewWidth - (viewContentPadding * 2));
+	// 描述的列表
+	const descriptionList = drawtext(data.versionInfo, viewContentWidth);
+	// 弹窗容器高度
+	let popupViewHeight = 80 + 20 + 20 + 90 + 10;
+	
+	let popupViewContentList = [{
+			src: $iconUrl,
+			id: "logo", 
+			tag: "img",
+			position: {
+				top: "0px",
+				left: (popupViewWidth - 124) / 2 + "px",
+				width: "124px",
+				height: "80px",
+			}
+		},
+		{
+			tag: 'font',
+			id: 'title',
+			text: "发现新版本" + data.versionName,
+			textStyles: {
+				size: '18px',
+				color: "#333",
+				weight: "bold",
+				whiteSpace: "normal"
+			},
+			position: {
+				top: '90px',
+				left: viewContentPadding + "px",
+				width: viewContentWidth + "px",
+				height: "30px",
+			}
+		}];
+	const textHeight = 18;
+	let contentTop = 130;
+	descriptionList.forEach((item,index) => {
+		if(index > 0){
+			popupViewHeight += textHeight;
+			contentTop += textHeight;
+		}
+		popupViewContentList.push({
+			tag: 'font',
+			id: 'content' + index + 1,
+			text: item.content,
+			textStyles: {
+				size: '14px',
+				color: "#666",
+				lineSpacing: "50%",
+				align: "left"
+			},
+			position: {
+				top: contentTop + "px",
+				left: viewContentPadding + "px",
+				width: viewContentWidth + "px",
+				height: textHeight + "px",
+			}
+		});
+		if(item.type == "break"){
+			contentTop += 10;
+			popupViewHeight += 10;
+		}
+	});
+	
+	if(data.updateType == "forcibly"){
+		popupViewContentList.push({
+			tag: 'rect', //绘制底边按钮
+			rectStyles:{
+				radius: "6px",
+				color: $mainColor
+			},
+			position:{
+				bottom: viewContentPadding + 'px',
+				left: viewContentPadding + "px",
+				width: viewContentWidth + "px",
+				height: "30px"
+			}
+		});
+		popupViewContentList.push({
+			tag: 'font',
+			id: 'confirmText',
+			text: "立即升级",
+			textStyles: {
+				size: '14px',
+				color: "#FFF",
+				lineSpacing: "0%",
+			},
+			position: {
+				bottom: viewContentPadding + 'px',
+				left: viewContentPadding + "px",
+				width: viewContentWidth + "px",
+				height: "30px"
+			}
+		});
+	} else {
+		// 绘制底边按钮
+		popupViewContentList.push({
+			tag: 'rect',
+			id: 'cancelBox',
+			rectStyles: {
+				radius: "3px",
+				borderColor: "#f1f1f1",
+				borderWidth: "1px",
+			},
+			position: {
+				bottom: viewContentPadding + 'px',
+				left: viewContentPadding + "px",
+				width: (viewContentWidth - viewContentPadding) / 2 + "px",
+				height: "30px",
+			}
+		});
+		popupViewContentList.push({
+			tag: 'rect',
+			id: 'confirmBox',
+			rectStyles: {
+				radius: "3px",
+				color: $mainColor,
+			},
+			position: {
+				bottom: viewContentPadding + 'px',
+				left: ((viewContentWidth - viewContentPadding) / 2 + viewContentPadding * 2) + "px",
+				width: (viewContentWidth - viewContentPadding) / 2 + "px",
+				height: "30px",
+			}
+		});
+		popupViewContentList.push({
+			tag: 'font',
+			id: 'cancelText',
+			text: "暂不升级",
+			textStyles: {
+				size: '14px',
+				color: "#666",
+				lineSpacing: "0%",
+				whiteSpace: "normal"
+			},
+			position: {
+				bottom: viewContentPadding + 'px',
+				left: viewContentPadding + "px",
+				width: (viewContentWidth - viewContentPadding) / 2 + "px",
+				height: "30px",
+			}
+		});
+		popupViewContentList.push({
+			tag: 'font',
+			id: 'confirmText',
+			text: "立即升级",
+			textStyles: {
+				size: '14px',
+				color: "#FFF",
+				lineSpacing: "0%",
+				whiteSpace: "normal"
+			},
+			position: {
+				bottom: viewContentPadding + 'px',
+				left: ((viewContentWidth - viewContentPadding) / 2 + viewContentPadding * 2) + "px",
+				width: (viewContentWidth - viewContentPadding) / 2 + "px",
+				height: "30px",
+			}
+		});
+	}
+	// 弹窗内容
+	let popupView = new plus.nativeObj.View("popupView", { //创建底部图标菜单
+		tag: "rect",
+		top: (screenHeight - popupViewHeight) / 2 + "px",
+		left: '15%',
+		height: popupViewHeight + "px",
+		width: "70%"
+	});
+	// 绘制白色背景
+	popupView.drawRect({
+		color: "#FFFFFF",
+		radius: "8px"
+	}, {
+		top: "40px",
+		height: popupViewHeight - 40 + "px",
+	});
+	
+	popupView.draw(popupViewContentList);
+	popupView.addEventListener("click", function(e) {
+		let maxTop = popupViewHeight - viewContentPadding;
+		let maxLeft = popupViewWidth - viewContentPadding;
+		let buttonWidth = (viewContentWidth - viewContentPadding) / 2;
+		if (e.clientY > maxTop - 30 && e.clientY < maxTop) {
+			if(data.updateType == "forcibly"){
+				if(e.clientX > viewContentPadding && e.clientX < maxLeft){
+					// 立即升级
+					maskLayer.hide();
+					popupView.hide();
+					callback && callback();
+				}
+			} else {
+				// 暂不升级
+				if (e.clientX > viewContentPadding && e.clientX < maxLeft - buttonWidth - viewContentPadding) {
+					maskLayer.hide();
+					popupView.hide();
+				} else if (e.clientX > maxLeft - buttonWidth && e.clientX < maxLeft) {
+					// 立即升级
+					maskLayer.hide();
+					popupView.hide();
+					callback && callback();
+				}
+			}
+			
+		}
+	});
+	if(data.updateType == "solicit"){
+		// 点击遮罩层
+		maskLayer.addEventListener("click", function() { //处理遮罩层点击
+			maskLayer.hide();
+			popupView.hide();
+		});
+	}
+	// 显示弹窗
+	maskLayer.show();
+	popupView.show();
+}
+// 文件下载的弹窗绘图
+function downloadPopupDrawing(data){
+	// 以下为计算菜单的nview绘制布局,为固定算法,使用者无关关心
+	const screenWidth = plus.screen.resolutionWidth;
+	const screenHeight = plus.screen.resolutionHeight;
+	//弹窗容器宽度
+	const popupViewWidth = screenWidth * 0.7;
+	// 弹窗容器的Padding
+	const viewContentPadding = 20;
+	// 弹窗容器的宽度
+	const viewContentWidth = popupViewWidth - (viewContentPadding * 2);
+	// 弹窗容器高度
+	let popupViewHeight = viewContentPadding * 3 + 60;
+	let progressTip = data.progressTip || "准备下载...";
+	let contentText = data.contentText || "正在为您更新,请耐心等待";
+	let elementList = [
+		{
+			tag: 'rect', //背景色
+			color: '#FFFFFF',
+			rectStyles:{
+				radius: "8px"
+			}
+		},
+		{
+			tag: 'font',
+			id: 'title',
+			text: "升级APP",
+			textStyles: {
+				size: '16px',
+				color: "#333",
+				weight: "bold",
+				verticalAlign: "middle",
+				whiteSpace: "normal"
+			},
+			position: {
+				top: viewContentPadding + 'px',
+				height: "30px",
+			}
+		},
+		{
+			tag: 'font',
+			id: 'content',
+			text: contentText,
+			textStyles: {
+				size: '14px',
+				color: "#333",
+				verticalAlign: "middle",
+				whiteSpace: "normal"
+			},
+			position: {
+				top: viewContentPadding * 2 + 30 + 'px',
+				height: "20px",
+			}
+		}
+	];
+	// 是否有进度条
+	if(data.progress){
+		popupViewHeight += viewContentPadding + 40;
+		elementList = elementList.concat([
+			{
+				tag: 'font',
+				id: 'progressValue',
+				text: progressTip,
+				textStyles: {
+					size: '14px',
+					color: $mainColor,
+					whiteSpace: "normal"
+				},
+				position: {
+					top: viewContentPadding * 4 + 20 + 'px',
+					height: "30px"
+				}
+			},
+			{
+				tag: 'rect', //绘制进度条背景
+				id: 'progressBg',
+				rectStyles:{
+					radius: "4px",
+					borderColor: "#f1f1f1",
+					borderWidth: "1px",
+				},
+				position:{
+					top: viewContentPadding * 4 + 60 + 'px',
+					left: viewContentPadding + "px",
+					width: viewContentWidth + "px",
+					height: "8px"
+				}
+			},
+		]);
+	}
+	if (data.buttonNum == 2) {
+		popupViewHeight += viewContentPadding + 30;
+		elementList = elementList.concat([
+			{
+				tag: 'rect', //绘制底边按钮
+				rectStyles:{
+					radius: "3px",
+					borderColor: "#f1f1f1",
+					borderWidth: "1px",
+				},
+				position:{
+					bottom: viewContentPadding + 'px',
+					left: viewContentPadding + "px",
+					width: (viewContentWidth - viewContentPadding) / 2 + "px",
+					height: "30px"
+				}
+			},
+			{
+				tag: 'rect', //绘制底边按钮
+				rectStyles:{
+					radius: "3px",
+					color: $mainColor
+				},
+				position:{
+					bottom: viewContentPadding + 'px',
+					left: ((viewContentWidth - viewContentPadding) / 2 + viewContentPadding * 2) + "px",
+					width: (viewContentWidth - viewContentPadding) / 2 + "px",
+					height: "30px"
+				}
+			},
+			{
+				tag: 'font',
+				id: 'cancelText',
+				text: "取消下载",
+				textStyles: {
+					size: '14px',
+					color: "#666",
+					lineSpacing: "0%",
+					whiteSpace: "normal"
+				},
+				position: {
+					bottom: viewContentPadding + 'px',
+					left: viewContentPadding + "px",
+					width: (viewContentWidth - viewContentPadding) / 2 + "px",
+					height: "30px",
+				}
+			},
+			{
+				tag: 'font',
+				id: 'confirmText',
+				text: "后台下载",
+				textStyles: {
+					size: '14px',
+					color: "#FFF",
+					lineSpacing: "0%",
+					whiteSpace: "normal"
+				},
+				position: {
+					bottom: viewContentPadding + 'px',
+					left: ((viewContentWidth - viewContentPadding) / 2 + viewContentPadding * 2) + "px",
+					width: (viewContentWidth - viewContentPadding) / 2 + "px",
+					height: "30px",
+				}
+			}
+		]);
+	}
+	if (data.buttonNum == 1) {
+		popupViewHeight += viewContentPadding + 40;
+		elementList = elementList.concat([
+			{
+				tag: 'rect', //绘制底边按钮
+				rectStyles:{
+					radius: "6px",
+					color: $mainColor
+				},
+				position:{
+					bottom: viewContentPadding + 'px',
+					left: viewContentPadding + "px",
+					width: viewContentWidth + "px",
+					height: "40px"
+				}
+			},
+			{
+				tag: 'font',
+				id: 'confirmText',
+				text: "关闭",
+				textStyles: {
+					size: '14px',
+					color: "#FFF",
+					lineSpacing: "0%",
+				},
+				position: {
+					bottom: viewContentPadding + 'px',
+					left: viewContentPadding + "px",
+					width: viewContentWidth + "px",
+					height: "40px"
+				}
+			}
+		]);
+	}
+	return {
+		popupViewHeight:popupViewHeight,
+		popupViewWidth:popupViewWidth,
+		screenHeight:screenHeight,
+		viewContentWidth:viewContentWidth,
+		viewContentPadding:viewContentPadding,
+		elementList: elementList
+	};
+}
+// 文件下载的弹窗
+function downloadPopup(data) {
+	// 弹窗遮罩层
+	let maskLayer = new plus.nativeObj.View("maskLayer", { //先创建遮罩层
+		top: '0px',
+		left: '0px',
+		height: '100%',
+		width: '100%',
+		backgroundColor: 'rgba(0,0,0,0.5)'
+	});
+	let popupViewData = downloadPopupDrawing(data);
+	// 弹窗内容
+	let popupView = new plus.nativeObj.View("popupView", { //创建底部图标菜单
+		tag: "rect",
+		top: (popupViewData.screenHeight - popupViewData.popupViewHeight) / 2 + "px",
+		left: '15%',
+		height: popupViewData.popupViewHeight + "px",
+		width: "70%",
+	});
+	let progressValue = 0;
+	let progressTip = 0;
+	let contentText = 0;
+	let buttonNum = 2;
+	if(data.buttonNum >= 0){
+		buttonNum = data.buttonNum;
+	}
+	popupView.draw(popupViewData.elementList);
+    let callbackData = {
+		change: function(res) {
+			let progressElement = [];
+			if(res.progressValue){
+				progressValue = res.progressValue;
+				// 绘制进度条
+				progressElement.push({
+					tag: 'rect', //绘制进度条背景
+					id: 'progressValueBg',
+					rectStyles:{
+						radius: "4px",
+						color: $mainColor
+					},
+					position:{
+						top: popupViewData.viewContentPadding * 4 + 60 + 'px',
+						left: popupViewData.viewContentPadding + "px",
+						width: popupViewData.viewContentWidth * (res.progressValue / 100) + "px",
+						height: "8px"
+					}
+				});
+			}
+			if(res.progressTip){
+				progressTip = res.progressTip;
+				progressElement.push({
+					tag: 'font',
+					id: 'progressValue',
+					text: res.progressTip,
+					textStyles: {
+						size: '14px',
+						color: $mainColor,
+						whiteSpace: "normal"
+					},
+					position: {
+						top: popupViewData.viewContentPadding * 4 + 20 + 'px',
+						height: "30px"
+					}
+				});
+			}
+			if(res.contentText){
+				contentText = res.contentText;
+				progressElement.push({
+					tag: 'font',
+					id: 'content',
+					text: res.contentText,
+					textStyles: {
+						size: '16px',
+						color: "#333",
+						whiteSpace: "normal"
+					},
+					position: {
+						top: popupViewData.viewContentPadding * 2 + 30 + 'px',
+						height: "30px",
+					}
+				});
+			}
+			if(res.buttonNum >= 0 && buttonNum != res.buttonNum){
+				buttonNum = res.buttonNum;
+				popupView.reset();
+				popupViewData = downloadPopupDrawing(Object.assign({
+					progressValue:progressValue,
+					progressTip:progressTip,
+					contentText:contentText,
+				},res));
+				let newElement = [];
+				popupViewData.elementList.map((item,index) => {
+					let have = false;
+					progressElement.forEach((childItem,childIndex) => {
+						if(item.id == childItem.id){
+							have = true;
+						}
+					});
+					if(!have){
+						newElement.push(item);
+					}
+				});
+				progressElement = newElement.concat(progressElement);
+				popupView.setStyle({
+					tag: "rect",
+					top: (popupViewData.screenHeight - popupViewData.popupViewHeight) / 2 + "px",
+					left: '15%',
+					height: popupViewData.popupViewHeight + "px",
+					width: "70%",
+				});
+				popupView.draw(progressElement); 
+			}else{
+				popupView.draw(progressElement);
+			}
+		},
+		cancel: function() { 
+			maskLayer.hide();
+			popupView.hide();
+		}
+	}
+	popupView.addEventListener("click", function(e) {
+		let maxTop = popupViewData.popupViewHeight - popupViewData.viewContentPadding;
+		let maxLeft = popupViewData.popupViewWidth - popupViewData.viewContentPadding;
+		if (e.clientY > maxTop - 40 && e.clientY < maxTop) {
+			if(buttonNum == 1){
+				// 单按钮
+				if (e.clientX > popupViewData.viewContentPadding && e.clientX < maxLeft) {
+					maskLayer.hide();
+					popupView.hide();
+                    callbackData.reboot();
+				}
+			}else if(buttonNum == 2){
+				// 双按钮
+				let buttonWidth = (popupViewData.viewContentWidth - popupViewData.viewContentPadding) / 2;
+				if (e.clientX > popupViewData.viewContentPadding && e.clientX < maxLeft - buttonWidth - popupViewData.viewContentPadding) {
+					maskLayer.hide();
+					popupView.hide();
+                    callbackData.cancelDownload();
+				} else if (e.clientX > maxLeft - buttonWidth && e.clientX < maxLeft) {
+					maskLayer.hide();
+					popupView.hide();
+				}
+			}
+		}
+	});
+	// 显示弹窗
+	maskLayer.show();
+	popupView.show();
+	// 改变进度条
+	return callbackData;
+}
+export default function(isPrompt = false) {
+	getCurrentNo(versionInfo => {
+		componentConfig.getServerNo(versionInfo, isPrompt, res => {
+			if (res.updateType == "forcibly" || res.updateType == "silent") {
+				if (/\.wgt$/i.test(res.downloadUrl)) {
+					getDownload(res);
+				} else if(/\.html$/i.test(res.downloadUrl)){
+					plus.runtime.openURL(res.downloadUrl);
+				} else {
+					if (platform == "android") {
+						getDownload(res);
+					} else {
+						plus.runtime.openURL(res.downloadUrl);
+					}
+				}
+			} else if(res.updateType == "solicit"){
+				updatePopup(res, function() {
+					if (/\.wgt$/i.test(res.downloadUrl)) {
+						getDownload(res);
+					} else if(/\.html$/i.test(res.downloadUrl)){
+						plus.runtime.openURL(res.downloadUrl);
+					} else {
+						if (platform == "android") {
+							getDownload(res);
+						} else {
+							plus.runtime.openURL(res.downloadUrl);
+						}
+					}
+				});
+			}
+		});
+	});
+}
+// #endif

+ 79 - 0
uni_modules/zhouWei-APPUpdate/package.json

@@ -0,0 +1,79 @@
+{
+  "id": "zhouWei-APPUpdate",
+  "displayName": "APP版本更新、强制更新、静默更新、下载进度(wgt更新)",
+  "version": "3.0.1",
+  "description": "APP版本更新、强制更新、静默更新、漂亮弹窗、下载进度(wgt更新)",
+  "keywords": [
+    "APP版本更新",
+    "强制更新",
+    "版本更新",
+    "静默更新"
+],
+  "repository": "https://github.com/zhouwei1994/uni-app-demo",
+  "engines": {
+    "HBuilderX": "^3.1.0"
+  },
+  "dcloudext": {
+    "category": [
+        "JS SDK",
+        "通用 SDK"
+    ],
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": "465081029"
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "<uses-permission android:name=\\\"android.permission.INSTALL_PACKAGES\\\"/>  \n<uses-permission android:name=\\\"android.permission.REQUEST_INSTALL_PACKAGES\\\"/>"
+    },
+    "npmurl": ""
+  },
+  "uni_modules": {
+    "dependencies": [],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "n",
+          "Android Browser": "n",
+          "微信浏览器(Android)": "n",
+          "QQ浏览器(Android)": "n"
+        },
+        "H5-pc": {
+          "Chrome": "n",
+          "IE": "n",
+          "Edge": "n",
+          "Firefox": "n",
+          "Safari": "n"
+        },
+        "小程序": {
+          "微信": "n",
+          "阿里": "n",
+          "百度": "n",
+          "字节跳动": "n",
+          "QQ": "n"
+        },
+        "快应用": {
+          "华为": "n",
+          "联盟": "n"
+        }
+      }
+    }
+  }
+}

+ 162 - 0
uni_modules/zhouWei-APPUpdate/readme.md

@@ -0,0 +1,162 @@
+# APP版本更新、强制更新、漂亮的更新界面、IOS更新(跳转IOS store)、wgt更新
+
+| `QQ交流群(607391225)`         | `微信交流群(加我好友备注"进群")`                  |
+| ----------------------------|--------------------------- |
+|![QQ交流群](http://qn.kemean.cn//upload/202004/14/15868301778472k7oubi6.png)|![微信交流群](https://qn.kemean.cn/upload/202010/13/weiXin_group_code.jpg)|
+| QQ群号:607391225 |微信号:zhou0612wei|
+
+### [点击跳转-插件示例](https://ext.dcloud.net.cn/plugin?id=2009)
+### [点击跳转-5年的web前端开源的uni-app快速开发模板-下载看文档](https://ext.dcloud.net.cn/plugin?id=2009)
+ 
+### 常见问题
+1.安卓apk下载完成后没有更新APP?
+
+答:问题是因为没有添加APP安装应用的权限,解决方法在`manifest.json`文件里面`APP模块权限配置`的`Android打包权限配置`勾选以下权限
+```
+<uses-permission android:name=\"android.permission.INSTALL_PACKAGES\"/>  
+<uses-permission android:name=\"android.permission.REQUEST_INSTALL_PACKAGES\"/>
+```
+若还有问题请看[安装apk无法执行的解决方案](https://ask.dcloud.net.cn/article/35703 "安装apk无法执行的解决方案")
+
+2.APP更新后版本号没变,还是之前的版本号?
+
+答:可能是更新的安装包没有升级版本号,`manifest.json`文件里面基本设置`应用版本号`和`应用版本名称`需要升高(保持一直减少问题)
+
+3.APP更新后没有覆盖之前的APP?
+
+答:可能是更新的安装包`包名`和APP的`包名`不一样
+
+4.弹窗的图标不显示?
+
+答:检查图片是不是放项目资源文件`static`,然后重新运行项目
+
+5.版本号是在前端对比还是在后端接口对比?
+
+答:当前案例是本地的版本号通过接口传递给后台,是后台对比的,若需要前端对比,请在接口返回数据的地方修改,不更新就不要调用`callback`方法
+
+6.本地的版本号比接口的版本号高还弹窗升级窗口?
+
+答:当前案例是本地的版本号通过接口传递给后台,后台对比是否需要升级,不需要升级就不要返回数据(特别是需要wgt更新的,建议这种方式)
+
+### 第一步`关键`配置APP更新接口(可以参考上面的示例)
+在项目目录下`config/componentConfig.js`里面如下配置
+```
+// 此方法是接口请求方法
+import $http from '@/config/requestConfig'
+export default {
+	// 发起ajax请求获取服务端版本号
+	getServerNo: (version, isPrompt = false, callback) => {
+		let httpData = {
+			version: version.versionCode,
+			// 版本名称
+		    versionName: version.versionName,
+			// setupPage参数说明(判断用户是不是从设置页面点击的更新,如果是设置页面点击的更新,有不要用静默更新了,不然用户点击没反应很奇怪的)
+			setupPage: isPrompt   
+		};
+		if (platform == "android") {
+			httpData.type = 1101;
+		} else {
+			httpData.type = 1102;
+		}
+		/* 接口入参说明
+		 * version: 应用当前版本号(已自动获取)
+		 * versionName: 应用当前版本名称(已自动获取)
+		 * type:平台(1101是安卓,1102是IOS)
+		 */
+		/****************以下是示例*******************/
+		// 可以用自己项目的请求方法(接口自己找后台要,插件不提供)
+		$http.get("api/common/v1/app_version", httpData,{
+			isPrompt: isPrompt
+		}).then(res => {
+			/* res的数据说明
+			 * | 参数名称	     | 一定返回 	| 类型	    | 描述
+			 * | -------------|--------- | --------- | ------------- |
+			 * | versionCode	 | y	    | int	    | 版本号        |
+			 * | versionName	 | y	    | String	| 版本名称      |
+			 * | versionInfo	 | y	    | String	| 版本信息      |
+			 * | updateType	     | y	    | String	| forcibly = 强制更新, solicit = 弹窗确认更新, silent = 静默更新 |
+			 * | downloadUrl	 | y	    | String	| 版本下载链接(IOS安装包更新请放跳转store应用商店链接,安卓apk和wgt文件放文件下载链接)  |
+			 */
+			if (res && res.downloadUrl) {
+				// 兼容之前的版本(updateType是新版才有的参数)
+				if(res.updateType){
+					callback && callback(res);
+				} else {
+					if(res.forceUpdate){
+						res.updateType = "forcibly";
+					} else {
+						res.updateType = "solicit";
+					}
+					callback && callback(res);
+				}
+			} else if (isPrompt) {
+				uni.showToast({
+					title: "暂无新版本",
+					icon: "none"
+				});
+			}
+		});
+		/****************以上是示例*******************/
+	},
+	// 弹窗主颜色(不填默认粉色)
+	appUpdateColor: "f00",
+	// 弹窗图标(不填显示默认图标,链接配置示例如: '/static/demo/ic_attention.png')
+	appUpdateIcon: ''
+}
+```
+
+### 第二步 使用方法
+``` 
+// App.vue页面
+
+// #ifdef APP-PLUS
+import APPUpdate from '@/uni_modules/zhouWei-APPUpdate/js_sdk/appUpdate';
+// #endif
+
+onLaunch: function(e) {
+	// #ifdef APP-PLUS
+	APPUpdate();
+	// #endif
+}
+```
+
+### 第三步 添加APP安装应用的权限
+在`manifest.json`文件里面`APP模块权限配置`的`Android打包权限配置`勾选以下权限
+```
+<uses-permission android:name=\"android.permission.INSTALL_PACKAGES\"/>  
+<uses-permission android:name=\"android.permission.REQUEST_INSTALL_PACKAGES\"/>
+```
+
+### 修改弹窗的主题色或弹窗图标
+在`APPUpdate/index.js`里面上面`$mainColor`常量中定义主题颜色,`$iconUrl`常量中定义图标地址
+
+### 检查APP是否有新版本(一般在设置页面使用)
+```
+// #ifdef APP-PLUS
+import APPUpdate, { getCurrentNo } from '@/uni_modules/zhouWei-APPUpdate/js_sdk/appUpdate';
+// #endif
+export default {
+	data() {
+		return {
+			version: "" // 版本号
+		};
+	},
+	//第一次加载
+	onLoad(e) {
+		// #ifdef APP-PLUS
+		getCurrentNo(res => {
+			// 进页面获取当前APP版本号(用于页面显示)
+			this.version = res.version;
+		});
+		// #endif
+	},
+	//方法
+	methods: {
+		// 检查APP是否有新版本
+		onAPPUpdate() {
+			// true 没有新版本的时候有提示,默认:false
+			APPUpdate(true);
+		}
+	}
+}
+```

二進制
uni_modules/zhouWei-APPUpdate/static/ic_ar.png