From f5da3e442eb0b9208e7b37d25959a3d5362f3b54 Mon Sep 17 00:00:00 2001
From: Lou <luzhiping@qqyjz.com>
Date: Fri, 10 Nov 2023 17:20:54 +0800
Subject: [PATCH] 标签事件详情页面数据交互,网格员审核列表与审核功能数据交互

---
 uni_modules/z-paging/components/z-paging/js/modules/nvue.js                   |  249 +
 uni_modules/z-paging/components/z-paging/js/modules/loading.js                |   93 
 uni_modules/z-paging/components/z-paging/js/modules/refresher.js              |  689 +++++
 subPackage/label/hotelList.vue                                                |    7 
 subPackage/label/index.vue                                                    |    4 
 uni_modules/z-paging/components/z-paging/components/z-paging-refresh.vue      |  182 +
 uni_modules/z-paging/components/z-paging/js/modules/data-handle.js            |  746 +++++
 uni_modules/z-paging/components/z-paging/components/z-paging-load-more.vue    |  141 +
 subPackage/label/formList.vue                                                 |    7 
 subPackage/label/bailList.vue                                                 |    9 
 api/reporting/reporting.js                                                    |   74 
 pages/home/index.vue                                                          |   10 
 uni_modules/z-paging/components/z-paging/js/modules/i18n.js                   |  101 
 uni_modules/z-paging/components/z-paging/i18n/index.js                        |    8 
 uni_modules/z-paging/components/z-paging/js/z-paging-mixin.js                 |   22 
 uni_modules/z-paging/components/z-paging/js/hooks/useZPaging.js               |   25 
 uni_modules/z-paging/components/z-paging-empty-view/z-paging-empty-view.vue   |  162 +
 uni_modules/z-paging/components/z-paging/js/modules/load-more.js              |  315 ++
 pages.json                                                                    |   27 
 subPackage/workbench/views/labelReportDetail.vue                              |  220 +
 uni_modules/z-paging/components/z-paging-cell/z-paging-cell.vue               |   34 
 uni_modules/z-paging/components/z-paging-swiper-item/z-paging-swiper-item.vue |  143 +
 uni_modules/z-paging/components/z-paging/wxs/z-paging-wxs.wxs                 |  340 ++
 uni_modules/z-paging/components/z-paging/css/z-paging-main.css                |  225 +
 uni_modules/z-paging/components/z-paging/i18n/zh-Hant.json                    |   22 
 uni_modules/z-paging/components/z-paging/js/z-paging-config.js                |   21 
 uni_modules/z-paging/readme.md                                                |   53 
 uni_modules/z-paging/components/z-paging/i18n/en.json                         |   22 
 uni_modules/z-paging/components/z-paging/js/z-paging-constant.js              |   12 
 uni_modules/z-paging/components/z-paging/js/modules/empty.js                  |  147 +
 uni_modules/z-paging/components/z-paging/js/z-paging-enum.js                  |   44 
 uni_modules/z-paging/components/z-paging/i18n/zh-Hans.json                    |   22 
 uni_modules/z-paging/components/z-paging/js/modules/common-layout.js          |  116 
 uni_modules/z-paging/components/z-paging/js/z-paging-interceptor.js           |   48 
 uni_modules/z-paging/components/z-paging/js/modules/scroller.js               |  464 +++
 uni_modules/z-paging/components/z-paging/z-paging.vue                         |  310 ++
 uni_modules/z-paging/components/z-paging/css/z-paging-static.css              |   35 
 subPackage/workbench/views/bailReportDetail.vue                               |  469 +++
 uni_modules/z-paging/components/z-paging/js/z-paging-main.js                  |  447 +++
 uni_modules/z-paging/package.json                                             |   86 
 uni_modules/z-paging/components/z-paging/config/index.js                      |    3 
 uni_modules/z-paging/components/z-paging/js/modules/virtual-list.js           |  461 +++
 subPackage/workbench/views/audit.vue                                          |   50 
 uni_modules/z-paging/components/z-paging/js/z-paging-utils.js                 |  228 +
 uni_modules/z-paging/components/z-paging/js/hooks/useZPagingComp.js           |   25 
 manifest.json                                                                 |    2 
 subPackage/workbench/views/hotelReportDetail.vue                              |  299 ++
 uni_modules/z-paging/changelog.md                                             |   16 
 uni_modules/z-paging/components/z-paging/js/modules/back-to-top.js            |  111 
 uni_modules/z-paging/components/z-paging/wxs/z-paging-renderjs.js             |   58 
 common/setting.js                                                             |    2 
 uni_modules/z-paging/components/z-paging-swiper/z-paging-swiper.vue           |  170 +
 uni_modules/z-paging/components/z-paging/js/z-paging-static.js                |   13 
 53 files changed, 7,565 insertions(+), 24 deletions(-)

diff --git a/api/reporting/reporting.js b/api/reporting/reporting.js
index a49e2a2..9ae978b 100644
--- a/api/reporting/reporting.js
+++ b/api/reporting/reporting.js
@@ -30,7 +30,7 @@
 }
 
 //获取取保候审报事列表
-export const geteBailReportingList = (params) => {
+export const getBailReportingList = (params) => {
 	return http.request({
 		url: '/blade-taskBailReportingEvent/taskBailReportingEvent/page',
 		method: 'get',
@@ -69,3 +69,75 @@
 		data: data
 	})
 }
+
+//审核列表
+export const getAuditReportingList = (params) => {
+	return http.request({
+		url: '/blade-task/task/page',
+		method: 'get',
+		params: {
+			...params
+		}
+	})
+}
+
+//获取旅馆安全详情
+export const getHotelReportingDetail = (params) => {
+	return http.request({
+		url: '/blade-taskHotelReporting/taskHotelReporting/detail',
+		method: 'get',
+		params: {
+			...params
+		}
+	})
+}
+
+//获取取保候审详情
+export const getBailReportingDetail = (params) => {
+	return http.request({
+		url: '/blade-taskBailReportingEvent/taskBailReportingEvent/detail',
+		method: 'get',
+		params: {
+			...params
+		}
+	})
+}
+
+//获取打金店、二手车交易、二手手机维修详情
+export const getLabelReportingDetail = (params) => {
+	return http.request({
+		url: '/blade-taskLabelReportingEvent/taskLabelReportingEvent/detail',
+		method: 'get',
+		params: {
+			...params
+		}
+	})
+}
+
+//修改旅店安全
+export const setHotelReporting = (data) => {
+	return http.request({
+		url: '/blade-task/task/update',
+		method: 'POST',
+		data: data
+	})
+}
+
+//修改取保候审
+export const setBailReporting = (data) => {
+	return http.request({
+		url: '/blade-taskBailReportingEvent/taskBailReportingEvent/update',
+		method: 'POST',
+		data: data
+	})
+}
+
+//修改打金店、二手车交易、二手手机维修
+export const setLabelReporting = (data) => {
+	return http.request({
+		url: '/blade-taskLabelReportingEvent/taskLabelReportingEvent/update',
+		method: 'POST',
+		data: data
+	})
+}
+
diff --git a/common/setting.js b/common/setting.js
index 97efe8a..66b71d2 100644
--- a/common/setting.js
+++ b/common/setting.js
@@ -12,7 +12,7 @@
 	// devUrl: 'https://sk.hubeishuiyi.cn',
 	// devUrl: 'http://192.168.1.156:9528',
 	// devUrl:'http://192.168.1.50:9528',
-	devUrl: 'http://192.168.0.101:9528',
+	devUrl: 'http://192.168.0.102:9528',
 	minioBaseUrl: "http://60.220.177.113:9000/jczz/",
 	// 数据中台接口url
 	// dataCenterUrl: 'http://10.10.2.192/services',
diff --git a/manifest.json b/manifest.json
index 05e5a7d..03142ec 100644
--- a/manifest.json
+++ b/manifest.json
@@ -156,7 +156,7 @@
         "uniStatistics" : {
             "enable" : false
         },
-        "requiredPrivateInfos" : [ "getLocation" ],
+        "requiredPrivateInfos" : [ "getLocation","chooseLocation" ],
         "permission" : {
             "scope.userLocation" : {
                 "desc" : "定位"
diff --git a/pages.json b/pages.json
index 958224e..75ddcab 100644
--- a/pages.json
+++ b/pages.json
@@ -260,6 +260,33 @@
 						"navigationBarBackgroundColor": "#fff",
 						"navigationBarTextStyle": "black"
 					}
+				},
+				{
+					"path": "views/hotelReportDetail",
+					"style": {
+						"navigationBarTitleText": "审核",
+						"enablePullDownRefresh": false,
+						"navigationBarBackgroundColor": "#fff",
+						"navigationBarTextStyle": "black"
+					}
+				},
+				{
+					"path": "views/bailReportDetail",
+					"style": {
+						"navigationBarTitleText": "审核",
+						"enablePullDownRefresh": false,
+						"navigationBarBackgroundColor": "#fff",
+						"navigationBarTextStyle": "black"
+					}
+				},
+				{
+					"path": "views/labelReportDetail",
+					"style": {
+						"navigationBarTitleText": "审核",
+						"enablePullDownRefresh": false,
+						"navigationBarBackgroundColor": "#fff",
+						"navigationBarTextStyle": "black"
+					}
 				}
 			]
 		},
diff --git a/pages/home/index.vue b/pages/home/index.vue
index f214584..39e714e 100644
--- a/pages/home/index.vue
+++ b/pages/home/index.vue
@@ -14,12 +14,12 @@
 				<u-swiper :list="swiperList" height="320rpx"></u-swiper>
 			</view>
 			<view class="" v-if="roleType != 1">
-				<u-grid :border="false" :col="roleType == 2?3:4">
+				<u-grid :border="false" :col="4">
 					<u-grid-item v-for="(i,k) in cellList" :key="k" @click.native="toPage(i)">
 						<u-icon :name="i.icon" :size="45"></u-icon>
 						<text class="f-26 mt-20">{{i.text}}</text>
 					</u-grid-item>
-					<u-grid-item @click.native="navTo()" v-if="roleType == 3">
+					<u-grid-item @click.native="navTo()" v-if="roleType == 2">
 						<u-icon name="/static/icon/nav-04.png" width="90rpx" height="90rpx"></u-icon>
 						<text class="f-26 mt-20">租客上报</text>
 					</u-grid-item>
@@ -97,7 +97,7 @@
 				</u-grid>
 			</view>
 
-			<view class="mt-40" v-if="roleType != 3">
+			<view class="mt-40" v-if="roleType != 2">
 				<view class="caption">
 					<view class="flex a-i-c">
 						<view class="line"></view>
@@ -128,7 +128,7 @@
 				</u-cell-group>
 			</view>
 
-			<view class="notic" v-if="roleType == 3">
+			<view class="notic" v-if="roleType == 2">
 				<view class="caption flex a-i-c j-c-s-b" @click="navigatorPage('/subPackage/notice/list')">
 					<view class="flex a-i-c">
 						<view class="line"></view>
@@ -298,7 +298,7 @@
 						status: "待处理0"
 					}
 				],
-				roleType: 3, // 1网格员/系统管理员 、2场所负责人、  3居民
+				roleType: 2, // 1网格员/系统管理员 、  2居民
 				roleTypeName: "街道社区网格",
 				selectBoxShow: false,
 				siteColumns: [],
diff --git a/subPackage/label/bailList.vue b/subPackage/label/bailList.vue
index 60458ea..037980f 100644
--- a/subPackage/label/bailList.vue
+++ b/subPackage/label/bailList.vue
@@ -1,7 +1,7 @@
 <template>
 	<view class="">
          	<view class="list">
-         		<view class="list-item bgc-ff mb-20"  v-for="(i,k) in list"  :key="k">
+         		<view class="list-item bgc-ff mb-20"  v-for="(i,k) in list"  :key="k"  @click="navTo(i.taskId)">
          			<view class="item-title flex a-i-c j-c-s-b mb-20">
          				<text class="f-32 fw">{{i.checkUserName}}</text>
          				<u-tag v-if="i.confirmFlag == 1" text="待审批" type="warning" plain plainFill></u-tag>
@@ -40,7 +40,14 @@
 					console.log(res)
 					this.list = res.data.records;
 				})
+			},
+			
+			navTo(id){
+				uni.navigateTo({
+					url:`/subPackage/workbench/views/bailReportDetail?id=${id}`
+				})
 			}
+			
 		}
 	}
 </script>
diff --git a/subPackage/label/formList.vue b/subPackage/label/formList.vue
index 9a1e28a..2a6b838 100644
--- a/subPackage/label/formList.vue
+++ b/subPackage/label/formList.vue
@@ -1,7 +1,7 @@
 <template>
 	<view class="">
          	<view class="list">
-         		<view class="list-item bgc-ff mb-20"  v-for="(i,k) in list"  :key="k">
+         		<view class="list-item bgc-ff mb-20"  v-for="(i,k) in list"  :key="k"  @click="navTo(i.taskId)">
          			<view class="item-title flex a-i-c j-c-s-b mb-20">
          				<text class="f-32 fw">{{i.hotelName}}</text>
          				<u-tag v-if="i.confirmFlag == 1" text="待审批" type="warning" plain plainFill></u-tag>
@@ -41,6 +41,11 @@
 					console.log(res)
 					this.list = res.data.records;
 				})
+			},
+			navTo(id){
+				uni.navigateTo({
+					url:`/subPackage/workbench/views/bailReportDetail?id=${id}`
+				})
 			}
 		}
 	}
diff --git a/subPackage/label/hotelList.vue b/subPackage/label/hotelList.vue
index b3959d8..0a211d9 100644
--- a/subPackage/label/hotelList.vue
+++ b/subPackage/label/hotelList.vue
@@ -1,7 +1,7 @@
 <template>
 	<view class="">
          	<view class="list">
-         		<view class="list-item bgc-ff mb-20"  v-for="(i,k) in list"  :key="k">
+         		<view class="list-item bgc-ff mb-20"  v-for="(i,k) in list"  :key="k"  @click="navTo(i.taskId)">
          			<view class="item-title flex a-i-c j-c-s-b mb-20">
          				<text class="f-32 fw">{{i.hotelName}}</text>
          				<u-tag v-if="i.confirmFlag == 1" text="待审批" type="warning" plain plainFill></u-tag>
@@ -40,6 +40,11 @@
 					console.log(res)
 					this.list = res.data.records;
 				})
+			},
+			navTo(id){
+				uni.navigateTo({
+					url:`/subPackage/workbench/views/hotelReportDetail?id=${id}`
+				})
 			}
 		}
 	}
diff --git a/subPackage/label/index.vue b/subPackage/label/index.vue
index 542626a..7110dfd 100644
--- a/subPackage/label/index.vue
+++ b/subPackage/label/index.vue
@@ -99,8 +99,12 @@
 		
 		onLoad(){
 			this.siteInfo = uni.getStorageSync("siteInfo");
+		},
+		
+		onShow() {
 			this.getCount(uni.getStorageSync("siteInfo").id);
 		},
+		
 		methods:{
 			getCount(code){
 				  getReportingCount({houseCode:code}).then(res=>{
diff --git a/subPackage/workbench/views/audit.vue b/subPackage/workbench/views/audit.vue
index 07b5471..346251c 100644
--- a/subPackage/workbench/views/audit.vue
+++ b/subPackage/workbench/views/audit.vue
@@ -5,24 +5,20 @@
 			<u-tabs :list="tabList"  :current="tabIndex"  @click="changeTab"  :inactiveStyle="{color:'#999999'}"  :activeStyle="{color:'#017BFC'}"></u-tabs>
 		</view>
 		<view class="list">
-			<view class="list-item bgc-ff mb-20"  v-for="i in 3">
+			<view class="list-item bgc-ff mb-20"  v-for="(i,k) in list"  :key="k"    @click="navTo(i.name,i.id)">
 				<view class="item-title flex a-i-c j-c-s-b mb-20">
-					<text class="f-32 fw">名称</text>
-					<!-- <u-tag text="待审批" type="warning" plain plainFill></u-tag> -->
-					<u-tag text="审核通过" type="success" plain plainFill></u-tag>
-					<!-- <u-tag text="审核拒绝" type="error" plain plainFill></u-tag> -->
+					<text class="f-32 fw">{{i.name}}</text>
+					<u-tag v-if="i.status == 1"  text="待审批" type="warning" plain plainFill></u-tag>
+					<u-tag v-if="i.status == 2" text="审核通过" type="success" plain plainFill></u-tag>
+					<u-tag v-if="i.status == 3" text="审核拒绝" type="error" plain plainFill></u-tag>
 				</view>
 				<view class="item-row flex a-i-c j-c-s-b">
-					<text class="f-28">事件类型</text>
-					<text class="f-28 c-66">一次性任务</text>
-				</view>
-				<view class="item-row flex a-i-c j-c-s-b">
-					<text class="f-28">标签</text>
-					<text class="f-28 c-66">打金店</text>
+					<text class="f-28">时间</text>
+					<text class="f-28 c-66">{{i.createTime}}</text>
 				</view>
 				<view class="item-row flex a-i-c j-c-s-b">
 					<text class="f-28">地址</text>
-					<text class="address f-28 c-66">西市街道万达社区居民委员会滨江西路66号万达晶座11栋303室</text>
+					<text class="address f-28 c-66">{{i.addressName}}</text>
 				</view>
 			</view>
 		</view>
@@ -31,6 +27,7 @@
 </template>
 
 <script>
+	import { getAuditReportingList } from "@/api/reporting/reporting"
 	export default {
 		data(){
 			return {
@@ -48,12 +45,39 @@
 					status:3
 				},
 				],
-				tabIndex:0
+				tabIndex:0,
+				currentStatus:1,
+				list:[]
 			}
 		},
+		
+		onLoad(){
+			this.getList()
+		},
+		
 		methods:{
 			changeTab(e){
 				this.tabIndex = e.index;
+				this.currentStatus = e.status;
+				this.getList();
+			},
+			getList(){
+				getAuditReportingList({
+					page:1,
+					size:20,
+					status:this.currentStatus
+				}).then(res=>{
+					this.list = res.data.records;
+				})
+			},
+			navTo(name,id){
+				if(name == "旅馆安全"){
+					this.$u.func.globalNavigator(`hotelReportDetail?id=${id}`)
+				}else if (name == "取保候审"){
+					this.$u.func.globalNavigator(`bailReportDetail?id=${id}`)
+				}else{
+					this.$u.func.globalNavigator(`labelReportDetail?id=${id}`)
+				}
 			}
 		}
 	}
diff --git a/subPackage/workbench/views/bailReportDetail.vue b/subPackage/workbench/views/bailReportDetail.vue
new file mode 100644
index 0000000..1f85720
--- /dev/null
+++ b/subPackage/workbench/views/bailReportDetail.vue
@@ -0,0 +1,469 @@
+<template>
+	<view class="container">
+		<view class="basic">
+			<box-title title="基本信息" class="box-title"></box-title>
+			<view class="info">
+				<lineItem :dataInfo="basicData"></lineItem>
+			</view>
+		</view>
+		<view class="licence" v-if="locationImageUrls.length">
+			<box-title title="位置图片" class="box-title"></box-title>
+			<view class="flex-wrap">
+				<view v-for="(i,k) in locationImageUrls" :key="k" class="ml-20 mt-20">
+					<u-image :src="i" width="80" height="80"></u-image>
+				</view>
+			</view>
+		</view>
+
+
+		<view class="item mt-30">
+			<u-form labelPosition="left" :model="info"  ref="form" labelWidth="100"
+				:labelStyle="{fontSize:'28rpx'}">
+				<u-form-item label="审核结果" prop="confirmFlag" borderBottom  @click="showPicker()">
+					<u-input v-model="confirmFlag" disabled disabledColor="#ffffff" border="none" placeholder="请输入"
+						placeholderClass="f-28 c-99" inputAlign="right"></u-input>
+					<u-icon slot="right" name="arrow-right"></u-icon>
+				</u-form-item>
+				<u-form-item label="备注"  borderBottom>
+					<u--input type="textarea" v-model="info.confirmNotion" :disabled="isDisabled"
+						disabledColor="#ffffff" placeholderClass="f-28 c-99" border="none" inputAlign="right"></u--input>
+
+				</u-form-item>
+				<u-form-item label="审核人员" prop="checkUserName" borderBottom >
+					<u-input v-model="info.confirmUserName" :disabled="isDisabled" disabledColor="#ffffff" border="none"
+						placeholder="请输入审核人员姓名" placeholderClass="f-28 c-99" inputAlign="right"></u-input>
+				</u-form-item>
+				<u-form-item label="电话号码" prop="confirmUserTelephone" borderBottom >
+					<u-input v-model="info.confirmUserTelephone" :disabled="isDisabled" disabledColor="#ffffff"
+						border="none" placeholder="请输入审核人员电话号码" placeholderClass="f-28 c-99"
+						inputAlign="right"></u-input>
+				</u-form-item>
+			</u-form>
+		</view>
+
+		<view  v-if="status == 2 && roleType  == 2">
+			<u-subsection :list="tabList" :current="tabIndex"  button-color="#017BFC" @change="changeTab"></u-subsection>
+			<u-form labelPosition="left" :model="goOutInfo" ref="form" labelWidth="100"
+				:labelStyle="{fontSize:'28rpx'}">
+				<view class="" v-if="tabIndex == 0">
+					<u-form-item label="当前时间" prop="checkUserName" borderBottom   @click="showPickerDate">
+						<u-input v-model="goOutInfo.startTime" disabled disabledColor="#ffffff"
+							border="none" placeholder="请获取当前时间" placeholderClass="f-28 c-99"
+							inputAlign="right"></u-input>
+						<u-icon slot="right" name="arrow-right"></u-icon>
+					</u-form-item>
+					<u-form-item label="报备位置" prop="checkUserName" borderBottom  @click="getLocation('returnLocation')">
+						<u-input v-model="goOutInfo.startLocation" disabled disabledColor="#ffffff"
+							border="none" placeholder="请获取当前位置" placeholderClass="f-28 c-99"
+							inputAlign="right"></u-input>
+						<u-icon slot="right" name="arrow-right"></u-icon>
+					</u-form-item>
+				</view>
+				<view class="" v-if="tabIndex == 1">
+					<u-form-item label="到达时间" prop="reachTime" borderBottom  @click="showPickerDate">
+						<u-input v-model="goOutInfo.reachTime" disabled disabledColor="#ffffff"
+							border="none" placeholder="请获取当前时间" placeholderClass="f-28 c-99"
+							inputAlign="right"></u-input>
+						<u-icon slot="right" name="arrow-right"></u-icon>
+					</u-form-item>
+					<u-form-item label="到达位置" prop="reachLocation" borderBottom  @click="getLocation('returnLocation')">
+						<u-input v-model="goOutInfo.reachLocation" disabled disabledColor="#ffffff"
+							border="none" placeholder="请获取当前位置" placeholderClass="f-28 c-99"
+							inputAlign="right"></u-input>
+						<u-icon slot="right" name="arrow-right"></u-icon>
+					</u-form-item>
+				</view>
+				<view class="" v-if="tabIndex == 2">
+					<u-form-item label="返回时间" prop="returnTime" borderBottom  @click="showPickerDate">
+						<u-input v-model="goOutInfo.returnTime" disabled disabledColor="#ffffff"
+							border="none" placeholder="请获取返回时间" placeholderClass="f-28 c-99"
+							inputAlign="right"></u-input>
+						<u-icon slot="right" name="arrow-right"></u-icon>
+					</u-form-item>
+					<u-form-item label="返回位置" prop="returnLocation" borderBottom   @click="getLocation('returnLocation')">
+						<u-input v-model="goOutInfo.returnLocation" disabled disabledColor="#ffffff"
+							border="none" placeholder="请获取返回位置" placeholderClass="f-28 c-99"
+							inputAlign="right"></u-input>
+						<u-icon slot="right" name="arrow-right"></u-icon>
+					</u-form-item>
+				</view>
+			</u-form>
+			<view class="upload bgc-ff">
+				<view class="f-28 mb-20">位置图片</view>
+				<view class="mt-20"  v-if="tabIndex == 0">
+					<u-upload :fileList="startImageUrls" :previewFullImage="uploadConfig.previewFullImage"
+						:accept="uploadConfig.acceptImg" :multiple="uploadConfig.multiple"
+						:maxCount="uploadConfig.maxCount" :capture="uploadConfig.capture" @afterRead="afterReadImgs($event,'startImageUrls')"
+						@delete="deletePic">
+						<view class="upload-item upload-icon flex_base">
+							<u-icon name="/static/icon/upload.png" width="60rpx" height="60rpx"></u-icon>
+						</view>
+					</u-upload>
+				</view>
+				<view class="mt-20" v-if="tabIndex == 1">
+					<u-upload :fileList="reachImageUrls" :previewFullImage="uploadConfig.previewFullImage"
+						:accept="uploadConfig.acceptImg" :multiple="uploadConfig.multiple"
+						:maxCount="uploadConfig.maxCount" :capture="uploadConfig.capture" @afterRead="afterReadImgs($event,'reachImageUrls')"
+						@delete="deletePic">
+						<view class="upload-item upload-icon flex_base">
+							<u-icon name="/static/icon/upload.png" width="60rpx" height="60rpx"></u-icon>
+						</view>					
+					</u-upload>
+				</view>
+				<view class="mt-20" v-if="tabIndex == 2">
+					<u-upload :fileList="returnImageUrls" :previewFullImage="uploadConfig.previewFullImage"
+						:accept="uploadConfig.acceptImg" :multiple="uploadConfig.multiple"
+						:maxCount="uploadConfig.maxCount" :capture="uploadConfig.capture" @afterRead="afterReadImgs($event,'returnImageUrls')"
+						@delete="deletePic">
+						<view class="upload-item upload-icon flex_base">
+							<u-icon name="/static/icon/upload.png" width="60rpx" height="60rpx"></u-icon>
+						</view>
+					</u-upload>
+				</view>
+			</view>
+		</view>
+
+
+		<view class="bottom-btn">
+			<u-button type="primary" @click="submit">提交审核</u-button>
+		</view>
+		<u-datetime-picker ref="datetimePicker" :show="showSelectDate" v-model="goOutDate[tabIndex]" mode="datetime"
+			:formatter="formatter" @confirm="confirmDate" @cancel="cancelPickerDate"></u-datetime-picker>
+		<u-picker :closeOnClickOverlay="true" @close="isPickerShow = false" :show="isPickerShow" ref="uPicker"
+			:columns="columns" keyName="name" @cancel="isPickerShow = false" @confirm="handleConfirm"></u-picker>
+	</view>
+</template>
+
+<script>
+	import boxTitle from '@/components/boxTitle/index.vue'
+	import lineItem from '../components/lineItem.vue'
+	import uploadMixin from "@/mixin/uploadMixin";
+	import {
+		getBailReportingDetail,
+		setBailReporting
+	} from '@/api/reporting/reporting'
+	export default {
+		components: {
+			boxTitle,
+			lineItem
+		},
+		mixins: [uploadMixin],
+		data() {
+			return {
+				basicData: [{
+						label: '姓名',
+						name: "checkUserName",
+						value: '未完善'
+					},
+					{
+						label: '手机',
+						name: 'checkTelephone',
+						value: '未完善'
+					},
+					{
+						label: '申请名称',
+						name: 'applyName',
+						value: '未完善'
+					},
+					{
+						label: '申请时间',
+						name: 'applyTime',
+						value: '未完善'
+					},
+					{
+						label: '申请位置',
+						name: 'location',
+						value: '未完善'
+					}
+				],
+				confirmFlag: "待审核",
+				isPickerShow: false,
+				columns: [
+					[{
+							name: "待审核",
+							status: 1
+						},
+						{
+							name: "审核通过",
+							status: 2
+						},
+						{
+							name: "审核不通过",
+							status: 3
+						},
+					]
+				],
+				currentId: '',
+				currentData: {},
+				taskId: "",
+				locationImageUrls: [],
+				selectStatus: "",
+				remark: "",
+				isDisabled: false,
+				info: {
+					confirmFlag: 1,
+					confirmUserName: "",
+					confirmUserTelephone: ""
+				},
+				goOutInfo: {
+					startTime: "",
+					startLocation: "",
+					reachTime: "",
+					reachLocation: "",
+					returnTime: "",
+					returnLocation: ""
+				},
+				startImageUrls: [], //出发位置图片,
+				reachImageUrls: [], //到达位置图片
+				returnImageUrls: [], //返回位置图片
+				roleInfo: {},
+				roleType: "", //1系统管理员/网格员   2居民
+				tabList: [{
+						name: '出发时'
+					},
+					{
+						name: '到达时'
+					},
+					{
+						name: '返程时'
+					}
+				],
+				tabIndex:0,
+				goOutDate:["","",""],
+				showSelectDate:false,
+				status:1     ,//当前状态   1待审核  2审核通过   3审核不通过
+				id:""
+
+			}
+		},
+		onLoad(option) {
+			this.taskId = option.id;
+			this.getDetailInfo(option.id);
+			let roleInfo = uni.getStorageSync("activeRole");
+			this.roleInfo = roleInfo;
+			if (roleInfo.roleAlias == "inhabitant") {
+				this.isDisabled = true;
+				this.roleType = 2;
+			} else {
+				this.roleType = 1;
+			}
+		},
+
+		methods: {
+			
+			changeTab(index){
+				this.tabIndex = index;
+			},
+			
+			showPickerDate(){
+				if(this.roleType == 2) return;
+				this.showSelectDate = true;
+			},
+			cancelPickerDate(){
+				this.showSelectDate = false;
+			},
+			showPicker(){
+				if(this.roleType == 2) return;
+				this.isPickerShow = true
+			},
+			
+			showConfirmFlag(status){
+				if(status == 1){
+					this.confirmFlag = "待审核"
+				}else if(status == 2){
+					this.confirmFlag = "审核通过"
+				}else {
+					this.confirmFlag = "审核不通过"
+				}
+			},
+			
+			confirmDate(e) {
+				this.showSelectDate = false;
+				this.goOutDate[this.tabIndex] = e.value;
+				if(this.tabIndex == 0){
+					this.goOutInfo.startTime = uni.$u.timeFormat(e.value, 'yyyy-mm-dd hh:MM:ss')
+					
+				}else if(this.tabIndex == 1){
+					this.goOutInfo.reachTime = uni.$u.timeFormat(e.value, 'yyyy-mm-dd hh:MM:ss')
+				}else {
+					this.goOutInfo.returnTime = uni.$u.timeFormat(e.value, 'yyyy-mm-dd hh:MM:ss')
+				}
+			},
+			
+			getLocation(key){
+				if(this.roleType == 2) return;
+				uni.chooseLocation({
+					success:(res)=>{
+						console.log(res);
+						this.$set(this.goOutInfo, key, res.address)
+					},
+					complete:(err)=> {
+						console.log(err)
+					}
+				})
+			},
+			
+			async afterReadImgs(event, key) {
+				this.showLoading()
+				let lists = [].concat(event.file)
+				let fileListLen = this[key].length
+				lists.map((item) => {
+					this[key].push({
+						...item,
+						status: 'uploading',
+						message: '上传中'
+					})
+				})
+				for (let i = 0; i < lists.length; i++) {
+					const result = await this.uploadFilePromise(lists[i].url)
+					this[key].splice(fileListLen, 1, Object.assign({}, {
+						url: result.data.link,
+						name: result.data.name
+					}))
+					fileListLen++
+				}
+				this.loadingClose()
+			},
+
+			getDetailInfo(id) {
+				getBailReportingDetail({
+					taskId: id
+				}).then(res => {
+					console.log(res);
+					let data = res.data;
+					this.status = data.confirmFlag
+					this.id = data.id;
+					this.showConfirmFlag(data.confirmFlag)
+					if(data.confirmFlag != 1){
+						this.info.confirmFlag = data.confirmFlag;
+						this.info.confirmUserName = data.confirmUserName;
+						this.info.confirmUserTelephone = data.confirmUserTelephone;
+					}
+					this.basicData.forEach(item => {
+						item.value = data[item.name]
+					})
+					this.locationImageUrls = this.setImages(data.locationImageUrls);
+
+				})
+			},
+			setImages(str) {
+				if (str) {
+					return str.split(",")
+				} else {
+					return []
+				}
+			},
+
+			handleConfirm(e) {
+				this.confirmFlag = e.value[0].name;
+				this.info.confirmFlag = e.value[0].status;
+				this.isPickerShow = false
+			},
+			
+			checkImages() {
+				if (this.startImageUrls.length) {
+					this.$set(this.goOutInfo, "startImageUrls", this.setGoOutImages(this.fireImageUrls))
+				}
+				if (this.reachImageUrls.length) {
+					this.$set(this.goOutInfo, "reachImageUrls", this.setGoOutImages(this.reachImageUrls))
+				}
+				if (this.returnImageUrls.length) {
+					this.$set(this.goOutInfo, "returnImageUrls", this.setGoOutImages(this.returnImageUrls))
+				}
+			},
+			
+			setGoOutImages(key) {
+				let urls = [];
+				for (let i of key) {
+					urls.push(i.url);
+				}
+				return urls.join(",")
+			},
+			
+			submit() {
+				if(this.roleType == 1){
+					this.submitRequest(this.info);
+				}else{
+					this.checkImages()
+					setTimeout(()=>{
+						this.submitRequest(this.goOutInfo);
+					},1000)
+				}		
+			},
+			
+			submitRequest(data){
+				data.taskId = this.taskId;
+				data.id = this.id;
+				setBailReporting(data).then(res => {
+					if (res.code !== 200) {
+						uni.showToast({
+							title: '更新失败',
+							icon: 'error'
+						})
+					}else {
+						this.getDetailInfo(this.taskId)
+					}
+					// uni.navigateBack()
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.container {
+		padding: 0 20rpx 130rpx;
+
+		.box-title {
+			margin-bottom: 15rpx;
+		}
+
+		.info {
+			.title {
+				font-size: 30rpx;
+				padding-left: 10rpx;
+			}
+
+			.images-box {
+				padding: 20rpx;
+				min-height: 100rpx;
+				background-color: #fff;
+			}
+		}
+
+		.form {
+			background-color: #fff;
+
+			.form-item {
+				padding: 0 20rpx;
+
+				&:first-child {
+					border-bottom: 1rpx solid #f6f6ff;
+				}
+			}
+		}
+
+		.bottom-btn {
+			position: fixed;
+			left: 0;
+			bottom: 0;
+			padding: 20rpx;
+			width: calc(100% - 40rpx);
+			background-color: #fff;
+			z-index: 9999;
+		}
+	}
+
+	/deep/ .u-form-item__body__left__content__label,
+	/deep/ .uni-input-placeholder {
+		font-size: 30rpx;
+	}
+	
+	.upload {
+		margin: 0 30rpx;
+		padding: 30rpx;
+	
+	
+	}
+	
+</style>
\ No newline at end of file
diff --git a/subPackage/workbench/views/hotelReportDetail.vue b/subPackage/workbench/views/hotelReportDetail.vue
new file mode 100644
index 0000000..9385180
--- /dev/null
+++ b/subPackage/workbench/views/hotelReportDetail.vue
@@ -0,0 +1,299 @@
+<template>
+	<view class="container">
+		<view class="basic">
+			<box-title title="基本信息" class="box-title"></box-title>
+			<view class="info">
+				<lineItem :dataInfo="basicData"></lineItem>
+			</view>
+		</view>
+		<view class="licence" v-if="fireImages.length">
+			<box-title title="灭火器图片" class="box-title"></box-title>
+			<view class="flex-wrap">
+				<view v-for="(i,k) in fireImages" :key="k" class="ml-20 mt-20">
+					<u-image :src="i" width="80" height="80"></u-image>
+				</view>
+			</view>
+		</view>
+		<view class="planegraph" v-if="scImageUrls.length">
+			<box-title title="安全通道图片" class="box-title"></box-title>
+			<view class="flex-wrap">
+				<view v-for="(i,k) in scImageUrls" :key="k" class="ml-20 mt-20">
+					<u-image :src="i" width="80" height="80"></u-image>
+				</view>
+			</view>
+		</view>
+		<view class="planegraph" v-if="pfImageUrls.length">
+			<box-title title="技防设施图片" class="box-title"></box-title>
+			<view class="flex-wrap">
+				<view v-for="(i,k) in pfImageUrls" :key="k" class="ml-20 mt-20">
+					<u-image :src="i" width="80" height="80"></u-image>
+				</view>
+			</view>
+		</view>
+		<view class="planegraph" v-if="uanImageUrls.length">
+			<box-title title="未成年人入住及照片" class="box-title"></box-title>
+			<view class="flex-wrap">
+				<view v-for="(i,k) in uanImageUrls" :key="k" class="ml-20 mt-20">
+					<u-image :src="i" width="80" height="80"></u-image>
+				</view>
+			</view>
+		</view>
+
+		<view class="examine">
+			<box-title title="审核信息" class="box-title"></box-title>
+			<view class="info">
+				<u-form labelWidth="70" :model="form" ref="form" class="form">
+					<u-form-item label="审核状态" @click="isPickerShow = true" class="form-item" :border-bottom="true">
+						<u--input v-model="form.confirmFlag" disabled disabledColor="#ffffff"
+							placeholder="请选择审核状态"  :border="false"></u--input>
+						<u-icon slot="right" name="arrow-right"></u-icon>
+					</u-form-item>
+					<u-form-item label="备注" class="form-item" v-if="selectStatus == 3">
+						<u--input type="textarea" v-model="remark"></u--input>
+					</u-form-item>
+				</u-form>
+			</view>
+		</view>
+		<view class="bottom-btn">
+			<u-button type="primary" @click="submit">提交审核</u-button>
+		</view>
+		<u-picker :closeOnClickOverlay="true" @close="isPickerShow = false" :show="isPickerShow" ref="uPicker"
+			:columns="columns" keyName="name" @cancel="isPickerShow = false" @confirm="handleConfirm"></u-picker>
+	</view>
+</template>
+
+<script>
+	import boxTitle from '@/components/boxTitle/index.vue'
+	import lineItem from '../components/lineItem.vue'
+	import {
+		getHotelReportingDetail,
+		setHotelReporting
+	} from '@/api/reporting/reporting'
+	export default {
+		components: {
+			boxTitle,
+			lineItem
+		},
+		data() {
+			return {
+				basicData: [{
+						label: '社区名称',
+						name: "districtName",
+						value: '未完善'
+					},
+					{
+						label: '酒店名称',
+						name: 'hotelName',
+						value: '未完善'
+					},
+					{
+						label: '自查时间',
+						name: 'checkTime',
+						value: '未完善'
+					},
+					{
+						label: '自查人姓名',
+						name: 'checkUserName',
+						value: '未完善'
+					},
+					{
+						label: '自查人手机',
+						name: 'checkTelephone',
+						value: '未完善'
+					},
+					{
+						label: '自查位置',
+						name: 'location',
+						value: '未完善'
+					},
+					{
+						label: '自查数量',
+						name: 'fireNums',
+						value: '未完善'
+					},
+					{
+						label: '灭火器状态',
+						name: 'fireStatus',
+						value: '未完善'
+					},
+					{
+						label: '安全通道有无',
+						name: 'scFlag',
+						value: '未完善'
+					},
+					{
+						label: '安全通道状态',
+						name: 'scStatus',
+						value: '未完善'
+					},
+					{
+						label: '防设施有无',
+						name: 'pfFlag',
+						value: '未完善'
+					},
+					{
+						label: '技防设施名称',
+						name: 'pfName',
+						value: '未完善'
+					},
+					{
+						label: '是否完全实名制登记',
+						name: 'realName',
+						value: '未完善'
+					},
+				],
+				personnelData: [
+					[{
+							label: '姓名',
+							value: '未完善',
+						},
+						{
+							label: '电话号码',
+							value: '未完善',
+						},
+						{
+							label: '暂住地',
+							value: '未完善',
+						}
+					]
+				],
+				form: {
+					confirmFlag: '待审核',
+					confirmNotion: ''
+				},
+				isPickerShow: false,
+				columns: [
+					[{
+							name: "待审核",
+							status: 1
+						},
+						{
+							name: "审核通过",
+							status: 2
+						},
+						{
+							name: "审核不通过",
+							status: 3
+						},
+					]
+				],
+				currentId: '',
+				currentData: {},
+				id: "",
+				fireImages: [],
+				scImageUrls: [],
+				pfImageUrls: [],
+				uanImageUrls: [],
+				selectStatus: "",
+				remark: ""
+
+			}
+		},
+		onLoad(option) {
+			this.id = option.id;
+			this.getDetailInfo(option.id);
+		},
+		
+		methods: {
+
+			getDetailInfo(id) {
+				getHotelReportingDetail({
+					taskId: id
+				}).then(res => {
+					console.log(res);
+					let data = res.data;
+					this.basicData.forEach(item => {
+						item.value = data[item.name]
+					})
+					this.fireImages = this.setImages(data.fireImageUrls);
+					this.scImageUrls = this.setImages(data.scImageUrls);
+					this.pfImageUrls = this.setImages(data.pfImageUrls);
+					this.uanImageUrls = this.setImages(data.uanImageUrls);
+
+				})
+			},
+			setImages(str) {
+				if (str) {
+					return str.split(",")
+				} else {
+					return []
+				}
+			},
+
+			handleConfirm(e) {
+				this.form.confirmFlag = e.value[0].name;
+				this.selectStatus = e.value[0].status;
+				this.isPickerShow = false
+			},
+			submit() {
+				let data = {
+					id: this.id,
+					status: this.selectStatus,
+					remark: this.remark
+				}
+				if (this.selectStatus == 3 && !this.remark) {
+					uni.showToast({
+						title: "请输入拒绝原因",
+						icon: "none"
+					})
+					return;
+				}
+				setHotelReporting(data).then(res=>{
+					if (res.code !== 200) {
+						uni.showToast({
+							title: '更新失败',
+							icon: 'error'
+						})
+						return
+					}
+					uni.navigateBack()
+				})
+			},
+		}
+	}
+</script>
+
+<style lang="scss">
+	.container {
+		padding:0 20rpx 130rpx;
+		.box-title {
+			margin-bottom: 15rpx;
+		}
+		.info {
+			.title {
+				font-size: 30rpx;
+				padding-left: 10rpx;
+			}
+			.images-box {
+				padding: 20rpx;
+				min-height: 100rpx;
+				background-color: #fff;
+			}
+		}
+		.form {
+			background-color: #fff;
+			.form-item {
+				padding: 0 20rpx;
+
+				&:first-child {
+					border-bottom: 1rpx solid #f6f6ff;
+				}
+			}
+		}
+
+		.bottom-btn {
+			position: fixed;
+			left: 0;
+			bottom: 0;
+			padding: 20rpx;
+			width: calc(100% - 40rpx);
+			background-color: #fff;
+			z-index: 9999;
+		}
+	}
+
+	/deep/ .u-form-item__body__left__content__label,
+	/deep/ .uni-input-placeholder {
+		font-size: 30rpx;
+	}
+</style>
\ No newline at end of file
diff --git a/subPackage/workbench/views/labelReportDetail.vue b/subPackage/workbench/views/labelReportDetail.vue
new file mode 100644
index 0000000..0bb1ce9
--- /dev/null
+++ b/subPackage/workbench/views/labelReportDetail.vue
@@ -0,0 +1,220 @@
+<template>
+	<view class="container">
+		<view class="basic">
+			<box-title title="基本信息" class="box-title"></box-title>
+			<view class="info">
+				<lineItem :dataInfo="basicData"></lineItem>
+			</view>
+		</view>
+		<view class="licence" v-if="imageUrls.length">
+			<box-title title="手持身份证" class="box-title"></box-title>
+			<view class="flex-wrap">
+				<view v-for="(i,k) in imageUrls" :key="k" class="ml-20 mt-20">
+					<u-image :src="i" width="80" height="80"></u-image>
+				</view>
+			</view>
+		</view>
+		<view class="planegraph" v-if="goodsImageUrls.length">
+			<box-title title="物品照片" class="box-title"></box-title>
+			<view class="flex-wrap">
+				<view v-for="(i,k) in goodsImageUrls" :key="k" class="ml-20 mt-20">
+					<u-image :src="i" width="80" height="80"></u-image>
+				</view>
+			</view>
+		</view>
+		<view class="examine">
+			<box-title title="审核信息" class="box-title"></box-title>
+			<view class="info">
+				<u-form labelWidth="70" :model="form" ref="form" class="form">
+					<u-form-item label="审核状态" @click="isPickerShow = true" class="form-item" :border-bottom="true">
+						<u--input v-model="form.confirmFlag" disabled disabledColor="#ffffff"
+							placeholder="请选择审核状态"  :border="false"></u--input>
+						<u-icon slot="right" name="arrow-right"></u-icon>
+					</u-form-item>
+					<u-form-item label="备注" class="form-item" v-if="selectStatus == 3">
+						<u--input type="textarea" v-model="remark"></u--input>
+					</u-form-item>
+				</u-form>
+			</view>
+		</view>
+		<view class="bottom-btn">
+			<u-button type="primary" @click="submit">提交审核</u-button>
+		</view>
+		<u-picker :closeOnClickOverlay="true" @close="isPickerShow = false" :show="isPickerShow" ref="uPicker"
+			:columns="columns" keyName="name" @cancel="isPickerShow = false" @confirm="handleConfirm"></u-picker>
+	</view>
+</template>
+
+<script>
+	import boxTitle from '@/components/boxTitle/index.vue'
+	import lineItem from '../components/lineItem.vue'
+	import {
+		getLabelReportingDetail,
+		setLabelReporting
+	} from '@/api/reporting/reporting'
+	export default {
+		components: {
+			boxTitle,
+			lineItem
+		},
+		data() {
+			return {
+				basicData: [{
+						label: '对象电话',
+						name: "transactionObjectTel",
+						value: '未完善'
+					},
+					{
+						label: '交易金额',
+						name: 'transactionMoney',
+						value: '未完善'
+					},
+					{
+						label: '物品数量',
+						name: 'goodsNums',
+						value: '未完善'
+					},
+					{
+						label: '交易位置',
+						name: 'location',
+						value: '未完善'
+					},
+					{
+						label: '交易过程',
+						name: 'transactionProcess',
+						value: '未完善'
+					}
+				],
+				form: {
+					confirmFlag: '待审核',
+					confirmNotion: ''
+				},
+				isPickerShow: false,
+				columns: [
+					[{
+							name: "待审核",
+							status: 1
+						},
+						{
+							name: "审核通过",
+							status: 2
+						},
+						{
+							name: "审核不通过",
+							status: 3
+						},
+					]
+				],
+				currentId: '',
+				currentData: {},
+				id: "",
+				imageUrls:[],
+				goodsImageUrls:[],
+				selectStatus: "",
+				remark: ""
+			}
+		},
+		onLoad(option) {
+			this.id = option.id;
+			this.getDetailInfo(option.id);
+		},
+		
+		methods: {
+			getDetailInfo(id) {
+				getLabelReportingDetail({
+					taskId: id
+				}).then(res => {
+					console.log(res);
+					let data = res.data;
+					this.basicData.forEach(item => {
+						item.value = data[item.name]
+					})
+					this.imageUrls = this.setImages(data.imageUrls);
+					this.goodsImageUrls = this.setImages(data.goodsImageUrls);
+				})
+			},
+			setImages(str) {
+				if (str) {
+					return str.split(",")
+				} else {
+					return []
+				}
+			},
+
+			handleConfirm(e) {
+				this.form.confirmFlag = e.value[0].name;
+				this.selectStatus = e.value[0].status;
+				this.isPickerShow = false
+			},
+			submit() {
+				let data = {
+					id: this.id,
+					status: this.selectStatus,
+					remark: this.remark
+				}
+				if (this.selectStatus == 3 && !this.remark) {
+					uni.showToast({
+						title: "请输入拒绝原因",
+						icon: "none"
+					})
+					return;
+				}
+				setLabelReporting(data).then(res=>{
+					if (res.code !== 200) {
+						uni.showToast({
+							title: '更新失败',
+							icon: 'error'
+						})
+						return
+					}
+					uni.navigateBack()
+				})
+			},
+		}
+	}
+</script>
+
+<style lang="scss">
+	.container {
+		padding:0 20rpx 130rpx;
+		.box-title {
+			margin-bottom: 15rpx;
+		}
+		.info {
+			.title {
+				font-size: 30rpx;
+				padding-left: 10rpx;
+			}
+			.images-box {
+				padding: 20rpx;
+				min-height: 100rpx;
+				background-color: #fff;
+			}
+		}
+		.form {
+			background-color: #fff;
+			.form-item {
+				padding: 0 20rpx;
+
+				&:first-child {
+					border-bottom: 1rpx solid #f6f6ff;
+				}
+			}
+		}
+
+		.bottom-btn {
+			position: fixed;
+			left: 0;
+			bottom: 0;
+			padding: 20rpx;
+			width: calc(100% - 40rpx);
+			background-color: #fff;
+			z-index: 9999;
+		}
+	}
+
+	/deep/ .u-form-item__body__left__content__label,
+	/deep/ .uni-input-placeholder {
+		font-size: 30rpx;
+	}
+</style>
\ No newline at end of file
diff --git a/uni_modules/z-paging/changelog.md b/uni_modules/z-paging/changelog.md
new file mode 100644
index 0000000..197e9a7
--- /dev/null
+++ b/uni_modules/z-paging/changelog.md
@@ -0,0 +1,16 @@
+## 2.6.2(2023-10-31)
+1.`修复` 在源码中有异常字符导致的在vue3中编译报错的问题。  
+2.`修复` 在微信小程序中`z-paging-refresh`的height无效的问题(by xiaohe0601)。  
+近期更新:  
+=============================  
+1.`新增` 手动更新自定义下拉刷新view高度方法。  
+2.`新增` 点击返回顶部按钮添加事件监听&支持拦截。  
+3.`新增` 是否开启下拉刷新状态栏占位,适用于隐藏导航栏时,下拉刷新需要避开状态栏高度的情况。  
+4.`新增` 支持配置网络请求失败触发`reject`。  
+5.`修复` 显示空数据图时,滚动到底部依然可以加载更多的问题。  
+6.`修复` 在vue2中底部加载更多相关`slot`使用`template`插入无效的问题。  
+7.`修复` `complete`的`Promise`可能无效的问题。  
+8.`优化` `hooks`判断`z-paging`为空则不调用。 
+  
+
+
diff --git a/uni_modules/z-paging/components/z-paging-cell/z-paging-cell.vue b/uni_modules/z-paging/components/z-paging-cell/z-paging-cell.vue
new file mode 100644
index 0000000..e9aca70
--- /dev/null
+++ b/uni_modules/z-paging/components/z-paging-cell/z-paging-cell.vue
@@ -0,0 +1,34 @@
+<!-- z-paging -->
+<!-- github地址:https://github.com/SmileZXLee/uni-z-paging -->
+<!-- dcloud地址:https://ext.dcloud.net.cn/plugin?id=3935 -->
+<!-- 反馈QQ群:790460711 -->
+
+<!-- z-paging-cell,用于在nvue中使用cell包裹,vue中使用view包裹 -->
+<template>
+	<!-- #ifdef APP-NVUE -->
+	<cell :style="[cellStyle]">
+		<slot />
+	</cell>
+	<!-- #endif -->
+	<!-- #ifndef APP-NVUE -->
+	<view :style="[cellStyle]">
+		<slot />
+	</view>
+	<!-- #endif -->
+</template>
+
+<script>
+	export default {
+		name: "z-paging-cell",
+		props: {
+			//cellStyle
+			cellStyle: {
+				type: Object,
+				default: function() {
+                    return {}
+                }
+			}
+		}
+	}
+</script>
+
diff --git a/uni_modules/z-paging/components/z-paging-empty-view/z-paging-empty-view.vue b/uni_modules/z-paging/components/z-paging-empty-view/z-paging-empty-view.vue
new file mode 100644
index 0000000..18ee4ee
--- /dev/null
+++ b/uni_modules/z-paging/components/z-paging-empty-view/z-paging-empty-view.vue
@@ -0,0 +1,162 @@
+<!-- z-paging -->
+<!-- github地址:https://github.com/SmileZXLee/uni-z-paging -->
+<!-- dcloud地址:https://ext.dcloud.net.cn/plugin?id=3935 -->
+<!-- 反馈QQ群:790460711 -->
+
+<!-- 空数据占位view,此组件支持easycom规范,可以在项目中直接引用 -->
+<template>
+	<view :class="{'zp-container':true,'zp-container-fixed':emptyViewFixed}" :style="[finalEmptyViewStyle]" @click="emptyViewClick">
+		<view class="zp-main">
+			<image v-if="!emptyViewImg.length" class="zp-main-image" :style="[emptyViewImgStyle]" :src="emptyImg" />
+			<image v-else class="zp-main-image" mode="aspectFit" :style="[emptyViewImgStyle]" :src="emptyViewImg" />
+			<text class="zp-main-title" :style="[emptyViewTitleStyle]">{{emptyViewText}}</text>
+			<text v-if="showEmptyViewReload" class="zp-main-error-btn" :style="[emptyViewReloadStyle]" @click.stop="reloadClick">{{emptyViewReloadText}}</text>
+		</view>
+	</view>
+</template>
+
+<script>
+	import zStatic from '../z-paging/js/z-paging-static'
+	export default {
+		name: "z-paging-empty-view",
+		data() {
+			return {
+				
+			};
+		},
+		props: {
+			//空数据描述文字
+			emptyViewText: {
+				type: String,
+				default: '没有数据哦~'
+			},
+			//空数据图片
+			emptyViewImg: {
+				type: String,
+				default: ''
+			},
+			//是否显示空数据图重新加载按钮
+			showEmptyViewReload: {
+				type: Boolean,
+				default: false
+			},
+			//空数据点击重新加载文字
+			emptyViewReloadText: {
+				type: String,
+				default: '重新加载'
+			},
+			//是否是加载失败
+			isLoadFailed: {
+				type: Boolean,
+				default: false
+			},
+			//空数据图样式
+			emptyViewStyle: {
+				type: Object,
+				default: function() {
+                    return {}
+                }
+			},
+			//空数据图img样式
+			emptyViewImgStyle: {
+				type: Object,
+				default: function() {
+				    return {}
+				}
+			},
+			//空数据图描述文字样式
+			emptyViewTitleStyle: {
+				type: Object,
+				default: function() {
+				    return {}
+				}
+			},
+			//空数据图重新加载按钮样式
+			emptyViewReloadStyle: {
+				type: Object,
+				default: function() {
+				    return {}
+				}
+			},
+			//空数据图z-index
+			emptyViewZIndex: {
+				type: Number,
+				default: 9
+			},
+			//空数据图片是否使用fixed布局并铺满z-paging
+			emptyViewFixed: {
+				type: Boolean,
+				default: true
+			}
+		},
+		computed: {
+			emptyImg() {
+                return this.isLoadFailed ? zStatic.base64Error : zStatic.base64Empty;
+			},
+			finalEmptyViewStyle(){
+				this.emptyViewStyle['z-index'] = this.emptyViewZIndex;
+				return this.emptyViewStyle;
+			}
+		},
+		methods: {
+			reloadClick() {
+				this.$emit('reload');
+			},
+			emptyViewClick() {
+				this.$emit('viewClick');
+			}
+		}
+	}
+</script>
+
+<style scoped>
+	.zp-container{
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		align-items: center;
+		justify-content: center;
+	}
+	.zp-container-fixed {
+		/* #ifndef APP-NVUE */
+		position: absolute;
+		top: 0;
+		left: 0;
+		width: 100%;
+		height: 100%;
+		/* #endif */
+		/* #ifdef APP-NVUE */
+		flex: 1;
+		/* #endif */
+	}
+
+	.zp-main{
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: column;
+		align-items: center;
+        padding: 50rpx 0rpx;
+	}
+
+	.zp-main-image {
+		width: 200rpx;
+		height: 200rpx;
+	}
+
+	.zp-main-title {
+		font-size: 26rpx;
+		color: #aaaaaa;
+		text-align: center;
+		margin-top: 10rpx;
+	}
+
+	.zp-main-error-btn {
+		font-size: 26rpx;
+		padding: 8rpx 24rpx;
+		border: solid 1px #dddddd;
+		border-radius: 6rpx;
+		color: #aaaaaa;
+		margin-top: 50rpx;
+	}
+</style>
diff --git a/uni_modules/z-paging/components/z-paging-swiper-item/z-paging-swiper-item.vue b/uni_modules/z-paging/components/z-paging-swiper-item/z-paging-swiper-item.vue
new file mode 100644
index 0000000..0501457
--- /dev/null
+++ b/uni_modules/z-paging/components/z-paging-swiper-item/z-paging-swiper-item.vue
@@ -0,0 +1,143 @@
+<!-- z-paging -->
+<!-- github地址:https://github.com/SmileZXLee/uni-z-paging -->
+<!-- dcloud地址:https://ext.dcloud.net.cn/plugin?id=3935 -->
+<!-- 反馈QQ群:790460711 -->
+
+<!-- 滑动切换选项卡swiper-item,此组件支持easycom规范,可以在项目中直接引用 -->
+<template>
+	<view class="zp-swiper-item-container">
+		<z-paging ref="paging" :fixed="false" 
+			:auto="false" :useVirtualList="useVirtualList" :useInnerList="useInnerList" :cellKeyName="cellKeyName" :innerListStyle="innerListStyle" 
+			:preloadPage="preloadPage" :cellHeightMode="cellHeightMode" :virtualScrollFps="virtualScrollFps" :virtualListCol="virtualListCol"
+			@query="_queryList" @listChange="_updateList" style="height: 100%;">
+			<slot />
+			<template #header>
+				<slot name="header"/>
+			</template>
+			<template #cell="{item,index}">
+				<slot name="cell" :item="item" :index="index"/>
+			</template>
+			<template #footer>
+				<slot name="footer"/>
+			</template>
+		</z-paging>
+	</view>
+</template>
+
+<script>
+	import zPaging from '../z-paging/z-paging'
+	export default {
+		name: "z-paging-swiper-item",
+		components: { zPaging },
+		data() {
+			return {
+				firstLoaded: false
+			}
+		},
+		props: {
+			//当前组件的index,也就是当前组件是swiper中的第几个
+			tabIndex: {
+				type: Number,
+				default: function() {
+					return 0
+				}
+			},
+			//当前swiper切换到第几个index
+			currentIndex: {
+				type: Number,
+				default: function() {
+					return 0
+				}
+			},
+			//是否使用虚拟列表,默认为否
+			useVirtualList: {
+				type: Boolean,
+				default: false
+			},
+			//是否在z-paging内部循环渲染列表(内置列表),默认为否。若use-virtual-list为true,则此项恒为true
+			useInnerList: {
+				type: Boolean,
+				default: false
+			},
+			//内置列表cell的key名称,仅nvue有效,在nvue中开启use-inner-list时必须填此项
+			cellKeyName: {
+				type: String,
+				default: ''
+			},
+			//innerList样式
+			innerListStyle: {
+				type: Object,
+				default: function() {
+					return {};
+				}
+			},
+			//预加载的列表可视范围(列表高度)页数,默认为12,即预加载当前页及上下各12页的cell。此数值越大,则虚拟列表中加载的dom越多,内存消耗越大(会维持在一个稳定值),但增加预加载页面数量可缓解快速滚动短暂白屏问题
+			preloadPage: {
+				type: [Number, String],
+				default: 12
+			},
+			//虚拟列表cell高度模式,默认为fixed,也就是每个cell高度完全相同,将以第一个cell高度为准进行计算。可选值【dynamic】,即代表高度是动态非固定的,【dynamic】性能低于【fixed】。
+			cellHeightMode: {
+				type: String,
+				default: 'fixed'
+			},
+			//虚拟列表列数,默认为1。常用于每行有多列的情况,例如每行有2列数据,需要将此值设置为2
+			virtualListCol: {
+				type: [Number, String],
+				default: 1
+			},
+			//虚拟列表scroll取样帧率,默认为60,过高可能出现卡顿等问题
+			virtualScrollFps: {
+				type: [Number, String],
+				default: 60
+			},
+		},
+		watch: {
+			currentIndex: {
+				handler(newVal, oldVal) {
+					if (newVal === this.tabIndex) {
+						//懒加载,当滑动到当前的item时,才去加载
+						if (!this.firstLoaded) {
+							this.$nextTick(()=>{
+								let delay = 5;
+								// #ifdef MP-TOUTIAO
+								delay = 100;
+								// #endif
+								setTimeout(() => {
+									this.$refs.paging.reload().catch(() => {});
+								}, delay);
+							})
+						}
+					}
+				},
+				immediate: true
+			}
+		},
+		methods: {
+			reload(data) {
+				return this.$refs.paging.reload(data);
+			},
+			complete(data) {
+				this.firstLoaded = true;
+				return this.$refs.paging.complete(data);
+			},
+			_queryList(pageNo, pageSize, from) {
+				this.$emit('query', pageNo, pageSize, from);
+			},
+			_updateList(list) {
+				this.$emit('updateList', list);
+			}
+		}
+	}
+</script>
+
+<style scoped>
+	.zp-swiper-item-container {
+		/* #ifndef APP-NVUE */
+		height: 100%;
+		/* #endif */
+		/* #ifdef APP-NVUE */
+		flex: 1;
+		/* #endif */
+	}
+</style>
diff --git a/uni_modules/z-paging/components/z-paging-swiper/z-paging-swiper.vue b/uni_modules/z-paging/components/z-paging-swiper/z-paging-swiper.vue
new file mode 100644
index 0000000..27cdb8e
--- /dev/null
+++ b/uni_modules/z-paging/components/z-paging-swiper/z-paging-swiper.vue
@@ -0,0 +1,170 @@
+<!-- z-paging -->
+<!-- github地址:https://github.com/SmileZXLee/uni-z-paging -->
+<!-- dcloud地址:https://ext.dcloud.net.cn/plugin?id=3935 -->
+<!-- 反馈QQ群:790460711 -->
+
+<!-- 滑动切换选项卡swiper容器,此组件支持easycom规范,可以在项目中直接引用 -->
+<template>
+	<view :class="fixed?'zp-swiper-container zp-swiper-container-fixed':'zp-swiper-container'" :style="[finalSwiperStyle]">
+		<!-- #ifndef APP-PLUS -->
+		<view v-if="cssSafeAreaInsetBottom===-1" class="zp-safe-area-inset-bottom"></view>
+		<!-- #endif -->
+		<slot v-if="zSlots.top" name="top" />
+		<view class="zp-swiper-super">
+			<view v-if="zSlots.left" :class="{'zp-swiper-left':true,'zp-absoulte':isOldWebView}">
+				<slot name="left" />
+			</view>
+			<view :class="{'zp-swiper':true,'zp-absoulte':isOldWebView}" :style="[swiperContentStyle]">
+				<slot />
+			</view>
+			<view v-if="zSlots.right" :class="{'zp-swiper-right':true,'zp-absoulte zp-right':isOldWebView}">
+				<slot name="right" />
+			</view>
+		</view>
+		<slot v-if="zSlots.bottom" name="bottom" />
+	</view>
+</template>
+
+<script>
+	import commonLayoutModule from '../z-paging/js/modules/common-layout'
+	
+	export default {
+		name: "z-paging-swiper",
+		mixins: [commonLayoutModule],
+		data() {
+			return {
+				swiperContentStyle: {}
+			};
+		},
+		props: {
+			//是否使用fixed布局,默认为是
+			fixed: {
+				type: Boolean,
+				default: true
+			},
+			//是否开启底部安全区域适配
+			safeAreaInsetBottom: {
+				type: Boolean,
+				default: false
+			},
+			//z-paging-swiper样式
+			swiperStyle: {
+				type: Object,
+				default: function() {
+					return {};
+				},
+			}
+		},
+		mounted() {
+			this.$nextTick(() => {
+				this.systemInfo = uni.getSystemInfoSync();
+			})
+			// #ifndef APP-PLUS
+			this._getCssSafeAreaInsetBottom();
+			// #endif
+			this.updateLeftAndRightWidth();
+
+			this.swiperContentStyle = { 'flex': '1' };
+			// #ifndef APP-NVUE
+			this.swiperContentStyle = { width: '100%',height: '100%' };
+			// #endif
+		},
+		computed: {
+			finalSwiperStyle() {
+				const swiperStyle = this.swiperStyle;
+				if (!this.systemInfo) return swiperStyle;
+				const windowTop = this.windowTop;
+				const windowBottom = this.systemInfo.windowBottom;
+				if (this.fixed) {
+					if (windowTop && !swiperStyle.top) {
+						swiperStyle.top = windowTop + 'px';
+					}
+					if (!swiperStyle.bottom) {
+						let bottom = windowBottom || 0;
+						bottom += this.safeAreaInsetBottom ? this.safeAreaBottom : 0;
+						if (bottom > 0) {
+							swiperStyle.bottom = bottom + 'px';
+						}
+					}
+				}
+				return swiperStyle;
+			}
+		},
+		methods: {
+			//更新slot="left"和slot="right"宽度,当slot="left"或slot="right"宽度动态改变时调用
+			updateLeftAndRightWidth() {
+				if (!this.isOldWebView) return;
+				this.$nextTick(() => this._updateLeftAndRightWidth(this.swiperContentStyle, 'zp-swiper'));
+			}
+		}
+	}
+</script>
+
+<style scoped>
+	.zp-swiper-container {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: column;
+		flex: 1;
+	}
+
+	.zp-swiper-container-fixed {
+		position: fixed;
+		/* #ifndef APP-NVUE */
+		height: auto;
+		width: auto;
+		/* #endif */
+		top: 0;
+		left: 0;
+		bottom: 0;
+		right: 0;
+	}
+	
+	.zp-safe-area-inset-bottom {
+		position: absolute;
+		/* #ifndef APP-PLUS */
+		height: env(safe-area-inset-bottom);
+		/* #endif */
+	}
+
+	.zp-swiper-super {
+		flex: 1;
+		overflow: hidden;
+		position: relative;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+	}
+	
+	.zp-swiper-left,.zp-swiper-right{
+		/* #ifndef APP-NVUE */
+		height: 100%;
+		/* #endif */
+	}
+
+	.zp-swiper {
+		flex: 1;
+		/* #ifndef APP-NVUE */
+		height: 100%;
+		width: 100%;
+		/* #endif */
+	}
+	
+	.zp-absoulte {
+		/* #ifndef APP-NVUE */
+		position: absolute;
+		top: 0;
+		width: auto;
+		/* #endif */
+	}
+	
+	.zp-right{
+		right: 0;
+	}
+	
+	.zp-swiper-item {
+		height: 100%;
+	}
+</style>
diff --git a/uni_modules/z-paging/components/z-paging/components/z-paging-load-more.vue b/uni_modules/z-paging/components/z-paging/components/z-paging-load-more.vue
new file mode 100644
index 0000000..f3ef931
--- /dev/null
+++ b/uni_modules/z-paging/components/z-paging/components/z-paging-load-more.vue
@@ -0,0 +1,141 @@
+<!-- [z-paging]上拉加载更多view -->
+<template>
+	<view class="zp-l-container" :style="[c.customStyle]" @click="doClick">
+		<template v-if="!c.hideContent">
+			<text v-if="c.showNoMoreLine&&finalStatus===M.NoMore" class="zp-l-line" :style="[{backgroundColor:zTheme.line[ts]},c.noMoreLineCustomStyle]" />
+			<!-- #ifndef APP-NVUE -->
+			<image v-if="finalStatus===M.Loading&&!!c.loadingIconCustomImage"
+				:src="c.loadingIconCustomImage" :style="[c.iconCustomStyle]" :class="{'zp-l-line-loading-custom-image':true,'zp-l-line-loading-custom-image-animated':c.loadingAnimated}" />
+			<image v-if="finalStatus===M.Loading&&finalLoadingIconType==='flower'&&!c.loadingIconCustomImage.length"
+				class="zp-line-loading-image" :style="[c.iconCustomStyle]" :src="zTheme.flower[ts]" />
+			<!-- #endif -->
+			<!-- #ifdef APP-NVUE -->
+			<view>
+				<loading-indicator v-if="finalStatus===M.Loading&&finalLoadingIconType!=='circle'" class="zp-line-loading-image" :style="[{color:zTheme.indicator[ts]}]" :animating="true" />
+			</view>
+			<!-- #endif -->
+			<text v-if="finalStatus===M.Loading&&finalLoadingIconType==='circle'&&!c.loadingIconCustomImage.length"
+				class="zp-l-circle-loading-view" :style="[{borderColor:zTheme.circleBorder[ts],borderTopColor:zTheme.circleBorderTop[ts]},c.iconCustomStyle]" />
+			<text class="zp-l-text" :style="[{color:zTheme.title[ts]},c.titleCustomStyle]">{{ownLoadingMoreText}}</text>
+			<text v-if="c.showNoMoreLine&&finalStatus===M.NoMore" class="zp-l-line" :style="[{backgroundColor:zTheme.line[ts]},c.noMoreLineCustomStyle]" />
+		</template>
+	</view>
+</template>
+<script>
+	import zStatic from '../js/z-paging-static'
+	import Enum from '../js/z-paging-enum'
+	export default {
+		name: 'z-paging-load-more',
+		data() {
+			return {
+				M: Enum.More,
+				zTheme: {
+					title: { white: '#efefef', black: '#a4a4a4' },
+					line: { white: '#efefef', black: '#eeeeee' },
+					circleBorder: { white: '#aaaaaa', black: '#c8c8c8' },
+					circleBorderTop: { white: '#ffffff', black: '#444444' },
+					flower: { white: zStatic.base64FlowerWhite, black: zStatic.base64Flower },
+					indicator: { white: '#eeeeee', black: '#777777' }
+				}
+			};
+		},
+		props: ['zConfig'],
+		computed: {
+			ts() {
+				return this.c.defaultThemeStyle;
+			},
+			c() {
+				return this.zConfig || {};
+			},
+			ownLoadingMoreText() {
+				const statusTextArr = [this.c.defaultText,this.c.loadingText,this.c.noMoreText,this.c.failText];
+				return statusTextArr[this.finalStatus];
+			},
+			finalStatus() {
+				if (this.c.defaultAsLoading && this.c.status === this.M.Default) return this.M.Loading;
+				return this.c.status;
+			},
+			finalLoadingIconType() {
+				// #ifdef APP-NVUE
+				return 'flower';
+				// #endif
+				return this.c.loadingIconType;
+			}
+		},
+		methods: {
+			doClick() {
+				this.$emit('doClick');
+			}
+		}
+	}
+</script>
+
+<style scoped>
+	@import "../css/z-paging-static.css";
+
+	.zp-l-container {
+		height: 80rpx;
+		font-size: 27rpx;
+		/* #ifndef APP-NVUE */
+		clear: both;
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		align-items: center;
+		justify-content: center;
+	}
+
+	.zp-l-line-loading-custom-image {
+		color: #a4a4a4;
+		margin-right: 8rpx;
+		width: 28rpx;
+		height: 28rpx;
+	}
+	
+	.zp-l-line-loading-custom-image-animated{
+		/* #ifndef APP-NVUE */
+		animation: loading-circle 1s linear infinite;
+		/* #endif */
+	}
+
+	.zp-l-circle-loading-view {
+		margin-right: 8rpx;
+		width: 23rpx;
+		height: 23rpx;
+		border: 3rpx solid #dddddd;
+		border-radius: 50%;
+		/* #ifndef APP-NVUE */
+		animation: loading-circle 1s linear infinite;
+		/* #endif */
+		/* #ifdef APP-NVUE */
+		width: 30rpx;
+		height: 30rpx;
+		/* #endif */
+	}
+
+	.zp-l-text {
+		/* #ifdef APP-NVUE */
+		font-size: 30rpx;
+		margin: 0rpx 10rpx;
+		/* #endif */
+	}
+
+	.zp-l-line {
+		height: 1px;
+		width: 100rpx;
+		margin: 0rpx 10rpx;
+	}
+
+	/* #ifndef APP-NVUE */
+	@keyframes loading-circle {
+		0% {
+			-webkit-transform: rotate(0deg);
+			transform: rotate(0deg);
+		}
+		100% {
+			-webkit-transform: rotate(360deg);
+			transform: rotate(360deg);
+		}
+	}
+	/* #endif */
+</style>
diff --git a/uni_modules/z-paging/components/z-paging/components/z-paging-refresh.vue b/uni_modules/z-paging/components/z-paging/components/z-paging-refresh.vue
new file mode 100644
index 0000000..12ac9db
--- /dev/null
+++ b/uni_modules/z-paging/components/z-paging/components/z-paging-refresh.vue
@@ -0,0 +1,182 @@
+<!-- [z-paging]下拉刷新view -->
+<template>
+	<view style="height: 100%;">
+		<view :class="showUpdateTime?'zp-r-container zp-r-container-padding':'zp-r-container'">
+			<view class="zp-r-left">
+				<image v-if="status!==R.Loading" :class="leftImageClass" :style="[leftImageStyle,imgStyle]" :src="leftImageSrc" />
+				<!-- #ifndef APP-NVUE -->
+				<image v-else :class="{'zp-line-loading-image':refreshingAnimated,'zp-r-left-image':true}" :style="[leftImageStyle,imgStyle]" :src="leftImageSrc" />
+				<!-- #endif -->
+				<!-- #ifdef APP-NVUE -->
+				<view v-else :style="[{'margin-right':showUpdateTime?'18rpx':'12rpx'}]">
+					<loading-indicator :class="isIos?'zp-loading-image-ios':'zp-loading-image-android'" 
+					:style="[{color:zTheme.indicator[ts]},imgStyle]" :animating="true" />
+				</view>
+				<!-- #endif -->
+			</view>
+			<view class="zp-r-right">
+				<text class="zp-r-right-text" :style="[rightTextStyle,titleStyle]">{{currentTitle}}</text>
+				<text v-if="showUpdateTime&&refresherTimeText.length" class="zp-r-right-text zp-r-right-time-text" :style="[rightTextStyle,updateTimeStyle]">
+					{{refresherTimeText}}
+				</text>
+			</view>
+		</view>
+	</view>
+</template>
+<script>
+	import zStatic from '../js/z-paging-static'
+	import u from '../js/z-paging-utils'
+	import Enum from '../js/z-paging-enum'
+	
+	export default {
+		name: 'z-paging-refresh',
+		data() {
+			return {
+				R: Enum.Refresher,
+				isIos: uni.getSystemInfoSync().platform === 'ios',
+				refresherTimeText: '',
+				zTheme: {
+					title: { white: '#efefef', black: '#555555' },
+					arrow: { white: zStatic.base64ArrowWhite, black: zStatic.base64Arrow },
+					flower: { white: zStatic.base64FlowerWhite, black: zStatic.base64Flower },
+					success: { white: zStatic.base64SuccessWhite, black: zStatic.base64Success },
+					indicator: { white: '#eeeeee', black: '#777777' }
+				}
+			};
+		},
+		props: ['status', 'defaultThemeStyle', 'defaultText', 'pullingText', 'refreshingText', 'completeText', 'defaultImg', 'pullingImg', 
+			'refreshingImg', 'completeImg', 'refreshingAnimated', 'showUpdateTime', 'updateTimeKey', 'imgStyle', 'titleStyle', 'updateTimeStyle', 'updateTimeTextMap'
+		],
+		computed: {
+			ts() {
+				return this.defaultThemeStyle;
+			},
+			statusTextArr() {
+				this.updateTime();
+				return [this.defaultText,this.pullingText,this.refreshingText,this.completeText];
+			},
+			currentTitle() {
+				return this.statusTextArr[this.status] || this.defaultText;
+			},
+			leftImageClass() {
+				if (this.status === this.R.Complete) return 'zp-r-left-image-pre-size';
+				return `zp-r-left-image zp-r-left-image-pre-size ${this.status === this.R.Default ? 'zp-r-arrow-down' : 'zp-r-arrow-top'}`;
+			},
+			leftImageStyle() {
+				const showUpdateTime = this.showUpdateTime;
+				const size = showUpdateTime ? '36rpx' : '30rpx';
+				return {width: size,height: size,'margin-right': showUpdateTime ? '20rpx' : '9rpx'};
+			},
+			leftImageSrc() {
+				const R = this.R;
+				const status = this.status;
+				if (status === R.Default) {
+					if (!!this.defaultImg) return this.defaultImg;
+					return this.zTheme.arrow[this.ts];
+				} else if (status  === R.ReleaseToRefresh) {
+					if (!!this.pullingImg) return this.pullingImg;
+					if (!!this.defaultImg) return this.defaultImg;
+					return this.zTheme.arrow[this.ts];
+				} else if (status  === R.Loading) {
+					if (!!this.refreshingImg) return this.refreshingImg;
+					return this.zTheme.flower[this.ts];;
+				} else if (status  === R.Complete) {
+					if (!!this.completeImg) return this.completeImg;
+					return this.zTheme.success[this.ts];;
+				}
+				return '';
+			},
+			rightTextStyle() {
+				let stl = {};
+				// #ifdef APP-NVUE
+				const textHeight = this.showUpdateTime ? '40rpx' : '80rpx';
+				stl = {'height': textHeight, 'line-height': textHeight}
+				// #endif
+				stl['color'] = this.zTheme.title[this.ts];
+				return stl;
+			}
+		},
+		methods: {
+			updateTime() {
+				if (this.showUpdateTime) {
+					this.refresherTimeText = u.getRefesrherFormatTimeByKey(this.updateTimeKey, this.updateTimeTextMap);
+				}
+			}
+		}
+	}
+</script>
+
+<style scoped>
+	@import "../css/z-paging-static.css";
+
+	.zp-r-container {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		height: 100%;
+		/* #endif */
+		flex-direction: row;
+		justify-content: center;
+		align-items: center;
+	}
+
+	.zp-r-container-padding {
+		/* #ifdef APP-NVUE */
+		padding: 15rpx 0rpx;
+		/* #endif */
+	}
+
+	.zp-r-left {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		align-items: center;
+		overflow: hidden;
+		/* #ifdef MP-ALIPAY */
+		margin-top: -4rpx;
+		/* #endif */
+	}
+
+	.zp-r-left-image {
+		transition-duration: .2s;
+		transition-property: transform;
+		color: #666666;
+	}
+	
+	.zp-r-left-image-pre-size{
+		/* #ifndef APP-NVUE */
+		width: 30rpx;
+		height: 30rpx;
+		overflow: hidden;
+		/* #endif */
+	}
+
+	.zp-r-arrow-top {
+		transform: rotate(0deg);
+	}
+
+	.zp-r-arrow-down {
+		transform: rotate(180deg);
+	}
+
+	.zp-r-right {
+		font-size: 27rpx;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: column;
+		align-items: center;
+		justify-content: center;
+	}
+
+	.zp-r-right-text {
+		/* #ifdef APP-NVUE */
+		font-size: 28rpx;
+		/* #endif */
+	}
+
+	.zp-r-right-time-text {
+		margin-top: 10rpx;
+		font-size: 24rpx;
+	}
+</style>
diff --git a/uni_modules/z-paging/components/z-paging/config/index.js b/uni_modules/z-paging/components/z-paging/config/index.js
new file mode 100644
index 0000000..15a37e2
--- /dev/null
+++ b/uni_modules/z-paging/components/z-paging/config/index.js
@@ -0,0 +1,3 @@
+// z-paging全局配置文件,注意避免更新时此文件被覆盖,若被覆盖,可在此文件中右键->点击本地历史记录,找回覆盖前的配置
+
+export default {}
\ No newline at end of file
diff --git a/uni_modules/z-paging/components/z-paging/css/z-paging-main.css b/uni_modules/z-paging/components/z-paging/css/z-paging-main.css
new file mode 100644
index 0000000..5d48e57
--- /dev/null
+++ b/uni_modules/z-paging/components/z-paging/css/z-paging-main.css
@@ -0,0 +1,225 @@
+/* [z-paging]公共css*/
+
+.z-paging-content {
+	position: relative;
+	/* #ifndef APP-NVUE */
+	display: flex;
+	width: 100%;
+	height: 100%;
+	overflow: hidden;
+	/* #endif */
+	flex-direction: column;
+}
+
+.z-paging-content-fixed, .zp-loading-fixed {
+	position: fixed;
+	/* #ifndef APP-NVUE */
+	height: auto;
+	width: auto;
+	/* #endif */
+	top: 0;
+	left: 0;
+	bottom: 0;
+	right: 0;
+}
+
+.zp-page-top,.zp-page-bottom {
+	/* #ifndef APP-NVUE */
+	width: auto;
+	/* #endif */
+	position: fixed;
+	left: 0;
+	right: 0;
+	z-index: 999;
+}
+
+.zp-page-left,.zp-page-right{
+	/* #ifndef APP-NVUE */
+	height: 100%;
+	/* #endif */
+}
+
+.zp-scroll-view-super {
+	flex: 1;
+	overflow: hidden;
+	position: relative;
+}
+
+.zp-view-super{
+	/* #ifndef APP-NVUE */
+	display: flex;
+	/* #endif */
+	flex-direction: row;
+}
+
+.zp-scroll-view-container,.zp-scroll-view {
+	position: relative;
+	/* #ifndef APP-NVUE */
+	height: 100%;
+	width: 100%;
+	/* #endif */
+}
+
+.zp-absoulte{
+	/* #ifndef APP-NVUE */
+	position: absolute;
+	top: 0;
+	width: auto;
+	/* #endif */
+}
+
+.zp-right{
+	right: 0;
+}
+
+.zp-scroll-view-absolute {
+	position: absolute;
+	top: 0;
+	left: 0;
+}
+
+/* #ifndef APP-NVUE */
+.zp-scroll-view-hide-scrollbar ::-webkit-scrollbar {
+	display: none;
+	-webkit-appearance: none;
+	width: 0 !important;
+	height: 0 !important;
+	background: transparent;
+}
+/* #endif */
+
+.zp-paging-touch-view {
+	width: 100%;
+	height: 100%;
+	position: relative;
+}
+
+.zp-fixed-bac-view {
+	position: absolute;
+	width: 100%;
+	top: 0;
+	left: 0;
+	height: 200px;
+}
+
+.zp-paging-main {
+	height: 100%;
+	/* #ifndef APP-NVUE */
+	display: flex;
+	/* #endif */
+	flex-direction: column;
+}
+
+.zp-paging-container {
+	flex: 1;
+	position: relative;
+	/* #ifndef APP-NVUE */
+	display: flex;
+	/* #endif */
+	flex-direction: column;
+}
+
+.zp-chat-record-loading-container {
+	/* #ifndef APP-NVUE */
+	display: flex;
+	width: 100%;
+	/* #endif */
+	/* #ifdef APP-NVUE */
+	width: 750rpx;
+	/* #endif */
+	align-items: center;
+	justify-content: center;
+	height: 60rpx;
+	font-size: 26rpx;
+}
+
+.zp-chat-record-loading-custom-image {
+	width: 35rpx;
+	height: 35rpx;
+	/* #ifndef APP-NVUE */
+	animation: loading-flower 1s linear infinite;
+	/* #endif */
+}
+
+.zp-custom-refresher-container {
+	overflow: hidden;
+}
+
+.zp-custom-refresher-refresh {
+	/* #ifndef APP-NVUE */
+	display: block;
+	/* #endif */
+}
+
+.zp-back-to-top {
+	width: 76rpx;
+	height: 76rpx;
+	z-index: 999;
+	position: absolute;
+	bottom: 0rpx;
+	right: 25rpx;
+	transition-duration: .3s;
+	transition-property: opacity;
+}
+
+.zp-back-to-top-show {
+	opacity: 1;
+}
+
+.zp-back-to-top-hide {
+	opacity: 0;
+}
+
+.zp-back-to-top-img {
+	/* #ifndef APP-NVUE */
+	width: 100%;
+	height: 100%;
+	/* #endif */
+	/* #ifdef APP-NVUE */
+	flex: 1;
+	/* #endif */
+	z-index: 999;
+}
+
+.zp-empty-view {
+	/* #ifdef APP-NVUE */
+	height: 100%;
+	/* #endif */
+	flex: 1;
+}
+
+.zp-empty-view-center {
+	/* #ifndef APP-NVUE */
+	display: flex;
+	/* #endif */
+	flex-direction: column;
+	align-items: center;
+	justify-content: center;
+}
+
+.zp-loading-fixed {
+	z-index: 9999;
+}
+
+.zp-safe-area-inset-bottom {
+	position: absolute;
+	/* #ifndef APP-PLUS */
+	height: env(safe-area-inset-bottom);
+	/* #endif */
+}
+
+.zp-n-refresh-container {
+	/* #ifndef APP-NVUE */
+	display: flex;
+	/* #endif */
+	justify-content: center;
+	width: 750rpx;
+}
+
+.zp-n-list-container{
+	/* #ifndef APP-NVUE */
+	display: flex;
+	/* #endif */
+	flex-direction: row;
+	flex: 1;
+}
diff --git a/uni_modules/z-paging/components/z-paging/css/z-paging-static.css b/uni_modules/z-paging/components/z-paging/css/z-paging-static.css
new file mode 100644
index 0000000..eaad977
--- /dev/null
+++ b/uni_modules/z-paging/components/z-paging/css/z-paging-static.css
@@ -0,0 +1,35 @@
+/* [z-paging]公用的静态css资源 */
+
+.zp-line-loading-image {
+	margin-right: 8rpx;
+	width: 28rpx;
+	height: 28rpx;
+	/* #ifndef APP-NVUE */
+	animation: loading-flower 1s steps(12) infinite;
+	/* #endif */
+	color: #666666;
+}
+
+.zp-loading-image-ios{
+	width: 20px;
+	height: 20px;
+}
+
+.zp-loading-image-android{
+	width: 32rpx;
+	height: 32rpx;
+}
+
+/* #ifndef APP-NVUE */
+@keyframes loading-flower {
+	0% {
+		-webkit-transform: rotate(0deg);
+		transform: rotate(0deg);
+	}
+	to {
+		-webkit-transform: rotate(1turn);
+		transform: rotate(1turn);
+	}
+}
+/* #endif */
+
diff --git a/uni_modules/z-paging/components/z-paging/i18n/en.json b/uni_modules/z-paging/components/z-paging/i18n/en.json
new file mode 100644
index 0000000..d93430f
--- /dev/null
+++ b/uni_modules/z-paging/components/z-paging/i18n/en.json
@@ -0,0 +1,22 @@
+{	
+	"zp.refresher.default": "Pull down to refresh",
+	"zp.refresher.pulling": "Release to refresh",
+	"zp.refresher.refreshing": "Refreshing...",
+	"zp.refresher.complete": "Refresh succeeded",
+	
+	"zp.loadingMore.default": "Click to load more",
+	"zp.loadingMore.loading": "Loading...",
+	"zp.loadingMore.noMore": "No more data",
+	"zp.loadingMore.fail": "Load failed,click to reload",
+	
+	"zp.emptyView.title": "No data",
+	"zp.emptyView.reload": "Reload",
+	"zp.emptyView.error": "Sorry,load failed",
+	
+	"zp.refresherUpdateTime.title": "Last update: ",
+	"zp.refresherUpdateTime.none": "None",
+	"zp.refresherUpdateTime.today": "Today",
+	"zp.refresherUpdateTime.yesterday": "Yesterday",
+	
+	"zp.systemLoading.title": "Loading..."
+}
diff --git a/uni_modules/z-paging/components/z-paging/i18n/index.js b/uni_modules/z-paging/components/z-paging/i18n/index.js
new file mode 100644
index 0000000..de7509c
--- /dev/null
+++ b/uni_modules/z-paging/components/z-paging/i18n/index.js
@@ -0,0 +1,8 @@
+import en from './en.json'
+import zhHans from './zh-Hans.json'
+import zhHant from './zh-Hant.json'
+export default {
+	en,
+	'zh-Hans': zhHans,
+	'zh-Hant': zhHant
+}
diff --git a/uni_modules/z-paging/components/z-paging/i18n/zh-Hans.json b/uni_modules/z-paging/components/z-paging/i18n/zh-Hans.json
new file mode 100644
index 0000000..f2cc3c8
--- /dev/null
+++ b/uni_modules/z-paging/components/z-paging/i18n/zh-Hans.json
@@ -0,0 +1,22 @@
+{	
+	"zp.refresher.default": "继续下拉刷新",
+	"zp.refresher.pulling": "松开立即刷新",
+	"zp.refresher.refreshing": "正在刷新...",
+	"zp.refresher.complete": "刷新成功",
+	
+	"zp.loadingMore.default": "点击加载更多",
+	"zp.loadingMore.loading": "正在加载...",
+	"zp.loadingMore.noMore": "没有更多了",
+	"zp.loadingMore.fail": "加载失败,点击重新加载",
+	
+	"zp.emptyView.title": "没有数据哦~",
+	"zp.emptyView.reload": "重新加载",
+	"zp.emptyView.error": "很抱歉,加载失败",
+	
+	"zp.refresherUpdateTime.title": "最后更新:",
+	"zp.refresherUpdateTime.none": "无",
+	"zp.refresherUpdateTime.today": "今天",
+	"zp.refresherUpdateTime.yesterday": "昨天",
+	
+	"zp.systemLoading.title": "加载中..."
+}
diff --git a/uni_modules/z-paging/components/z-paging/i18n/zh-Hant.json b/uni_modules/z-paging/components/z-paging/i18n/zh-Hant.json
new file mode 100644
index 0000000..e9c80cf
--- /dev/null
+++ b/uni_modules/z-paging/components/z-paging/i18n/zh-Hant.json
@@ -0,0 +1,22 @@
+{	
+	"zp.refresher.default": "繼續下拉重繪",
+	"zp.refresher.pulling": "鬆開立即重繪",
+	"zp.refresher.refreshing": "正在重繪...",
+	"zp.refresher.complete": "重繪成功",
+	
+	"zp.loadingMore.default": "點擊加載更多",
+	"zp.loadingMore.loading": "正在加載...",
+	"zp.loadingMore.noMore": "沒有更多了",
+	"zp.loadingMore.fail": "加載失敗,點擊重新加載",
+	
+	"zp.emptyView.title": "沒有數據哦~",
+	"zp.emptyView.reload": "重新加載",
+	"zp.emptyView.error": "很抱歉,加載失敗",
+	
+	"zp.refresherUpdateTime.title": "最後更新:",
+	"zp.refresherUpdateTime.none": "無",
+	"zp.refresherUpdateTime.today": "今天",
+	"zp.refresherUpdateTime.yesterday": "昨天",
+	
+	"zp.systemLoading.title": "加載中..."
+}
diff --git a/uni_modules/z-paging/components/z-paging/js/hooks/useZPaging.js b/uni_modules/z-paging/components/z-paging/js/hooks/useZPaging.js
new file mode 100644
index 0000000..adb6e1b
--- /dev/null
+++ b/uni_modules/z-paging/components/z-paging/js/hooks/useZPaging.js
@@ -0,0 +1,25 @@
+// [z-paging]useZPaging hooks
+
+import { onPageScroll, onReachBottom, onPullDownRefresh } from '@dcloudio/uni-app';
+
+function useZPaging(paging) {
+	const cPaging = !!paging ? paging.value || paging : null;
+	
+	onPullDownRefresh(() => {
+		if (!cPaging || !cPaging.value) return;
+		cPaging.value.reload().catch(() => {});
+	})
+	
+	onPageScroll(e => {
+		if (!cPaging || !cPaging.value) return;
+		cPaging.value.updatePageScrollTop(e.scrollTop);
+		e.scrollTop < 10 && cPaging.value.doChatRecordLoadMore();
+	})
+	
+	onReachBottom(() => {
+		if (!cPaging || !cPaging.value) return;
+		cPaging.value.pageReachBottom();
+	})
+}
+
+export default useZPaging
\ No newline at end of file
diff --git a/uni_modules/z-paging/components/z-paging/js/hooks/useZPagingComp.js b/uni_modules/z-paging/components/z-paging/js/hooks/useZPagingComp.js
new file mode 100644
index 0000000..f9bc5ab
--- /dev/null
+++ b/uni_modules/z-paging/components/z-paging/js/hooks/useZPagingComp.js
@@ -0,0 +1,25 @@
+// [z-paging]useZPagingComp hooks
+
+function useZPagingComp(paging) {
+	const cPaging = !!paging ? paging.value || paging : null;
+	
+	const reload = () => {
+		if (!cPaging || !cPaging.value) return;
+		cPaging.value.reload().catch(() => {});
+	}
+	const updatePageScrollTop = scrollTop => {
+		if (!cPaging || !cPaging.value) return;
+		cPaging.value.updatePageScrollTop(scrollTop);
+	}
+	const doChatRecordLoadMore = () => {
+		if (!cPaging || !cPaging.value) return;
+		cPaging.value.doChatRecordLoadMore();
+	}
+	const pageReachBottom = () => {
+		if (!cPaging || !cPaging.value) return;
+		cPaging.value.pageReachBottom();
+	}
+	return { reload, updatePageScrollTop, doChatRecordLoadMore, pageReachBottom };
+}
+
+export default useZPagingComp
\ No newline at end of file
diff --git a/uni_modules/z-paging/components/z-paging/js/modules/back-to-top.js b/uni_modules/z-paging/components/z-paging/js/modules/back-to-top.js
new file mode 100644
index 0000000..7cfd298
--- /dev/null
+++ b/uni_modules/z-paging/components/z-paging/js/modules/back-to-top.js
@@ -0,0 +1,111 @@
+// [z-paging]点击返回顶部view模块
+import u from '.././z-paging-utils'
+
+export default {
+	props: {
+		//自动显示点击返回顶部按钮,默认为否
+		autoShowBackToTop: {
+			type: Boolean,
+			default: u.gc('autoShowBackToTop', false)
+		},
+		//点击返回顶部按钮显示/隐藏的阈值(滚动距离),单位为px,默认为400rpx
+		backToTopThreshold: {
+			type: [Number, String],
+			default: u.gc('backToTopThreshold', '400rpx')
+		},
+		//点击返回顶部按钮的自定义图片地址,默认使用z-paging内置的图片
+		backToTopImg: {
+			type: String,
+			default: u.gc('backToTopImg', '')
+		},
+		//点击返回顶部按钮返回到顶部时是否展示过渡动画,默认为是
+		backToTopWithAnimate: {
+			type: Boolean,
+			default: u.gc('backToTopWithAnimate', true)
+		},
+		//点击返回顶部按钮与底部的距离,注意添加单位px或rpx,默认为160rpx
+		backToTopBottom: {
+			type: [Number, String],
+			default: u.gc('backToTopBottom', '160rpx')
+		},
+		//点击返回顶部按钮的自定义样式
+		backToTopStyle: {
+			type: Object,
+			default: function() {
+				return u.gc('backToTopStyle', {});
+			},
+		},
+		//iOS点击顶部状态栏、安卓双击标题栏时,滚动条返回顶部,只支持竖向,默认为是
+		enableBackToTop: {
+			type: Boolean,
+			default: u.gc('enableBackToTop', true)
+		},
+	},
+	data() {
+		return {
+			backToTopClass: 'zp-back-to-top zp-back-to-top-hide',
+			lastBackToTopShowTime: 0,
+			showBackToTopClass: false,
+		}
+	},
+	computed: {
+		finalEnableBackToTop() {
+			return this.usePageScroll ? false : this.enableBackToTop;
+		},
+		finalBackToTopThreshold() {
+			return u.convertToPx(this.backToTopThreshold);
+		},
+		finalBackToTopStyle() {
+			const backToTopStyle = this.backToTopStyle;
+			if (!backToTopStyle.bottom) {
+				backToTopStyle.bottom = this.windowBottom + u.convertToPx(this.backToTopBottom) + 'px';
+			}
+			if(!backToTopStyle.position){
+				backToTopStyle.position = this.usePageScroll ? 'fixed': 'absolute';
+			}
+			return backToTopStyle;
+		},
+	},
+	methods: {
+		//点击返回顶部
+		_backToTopClick() {
+			let callbacked = false;
+			this.$emit('backToTopClick', toTop => {
+				(toTop === undefined || toTop === true) && this._handleToTop();
+				callbacked = true;
+			});
+			this.$nextTick(() => {
+				!callbacked && this._handleToTop();
+			})
+		},
+		//处理滚动到顶部
+		_handleToTop() {
+			!this.backToTopWithAnimate && this._checkShouldShowBackToTop(0);
+			this.scrollToTop(this.backToTopWithAnimate);
+		},
+		//判断是否要显示返回顶部按钮
+		_checkShouldShowBackToTop(scrollTop) {
+			if (!this.autoShowBackToTop) {
+				this.showBackToTopClass = false;
+				return;
+			}
+			if (scrollTop > this.finalBackToTopThreshold) {
+				if (!this.showBackToTopClass) {
+					this.showBackToTopClass = true;
+					this.lastBackToTopShowTime = new Date().getTime();
+					u.delay(() => {
+						this.backToTopClass = 'zp-back-to-top zp-back-to-top-show';
+					}, 300)
+				}
+			} else {
+				if (this.showBackToTopClass) {
+					this.backToTopClass = 'zp-back-to-top zp-back-to-top-hide';
+					u.delay(() => {
+						this.showBackToTopClass = false;
+					}, new Date().getTime() - this.lastBackToTopShowTime < 500 ? 0 : 300)
+				}
+			}
+		},
+	}
+}
+
diff --git a/uni_modules/z-paging/components/z-paging/js/modules/common-layout.js b/uni_modules/z-paging/components/z-paging/js/modules/common-layout.js
new file mode 100644
index 0000000..249d7aa
--- /dev/null
+++ b/uni_modules/z-paging/components/z-paging/js/modules/common-layout.js
@@ -0,0 +1,116 @@
+// [z-paging]通用布局相关模块
+
+// #ifdef APP-NVUE
+const weexDom = weex.requireModule('dom');
+// #endif
+
+export default {
+	data() {
+		return {
+			systemInfo: null,
+			cssSafeAreaInsetBottom: -1,
+		}
+	},
+	computed: {
+		windowTop() {
+			if (!this.systemInfo) return 0;
+			//暂时修复vue3中隐藏系统导航栏后windowTop获取不正确的问题,具体bug详见https://ask.dcloud.net.cn/question/141634
+			//感谢litangyu!!https://github.com/SmileZXLee/uni-z-paging/issues/25
+			// #ifdef VUE3 && H5
+			const pageHeadNode = document.getElementsByTagName("uni-page-head");
+			if (!pageHeadNode.length) return 0;
+			// #endif
+			return this.systemInfo.windowTop || 0;
+		},
+		safeAreaBottom() {
+			if (!this.systemInfo) return 0;
+			let safeAreaBottom = 0;
+			// #ifdef APP-PLUS
+			safeAreaBottom = this.systemInfo.safeAreaInsets.bottom || 0 ;
+			// #endif
+			// #ifndef APP-PLUS
+			safeAreaBottom = Math.max(this.cssSafeAreaInsetBottom, 0);
+			// #endif
+			return safeAreaBottom;
+		},
+		isOldWebView() {
+			// #ifndef APP-NVUE || MP-KUAISHOU
+			try {
+				const systemInfos = uni.getSystemInfoSync().system.split(' ');
+				const deviceType = systemInfos[0];
+				const version = parseInt(systemInfos[1]);
+				if ((deviceType === 'iOS' && version <= 10) || (deviceType === 'Android' && version <= 6)) {
+					return true;
+				}
+			} catch(e) {
+				return false;
+			}
+			// #endif
+			return false;
+		},
+		zSlots() {
+			// #ifdef VUE2
+			
+			// #ifdef MP-ALIPAY
+			return this.$slots;
+			// #endif
+			
+			return this.$scopedSlots || this.$slots;
+			// #endif
+			
+			return this.$slots;
+		}
+	},
+	methods: {
+		//获取节点尺寸
+		_getNodeClientRect(select, inDom = true, scrollOffset = false) {
+			// #ifdef APP-NVUE
+			select = select.replace(/[.|#]/g, '');
+			const ref = this.$refs[select];
+			return new Promise((resolve, reject) => {
+				if (ref) {
+					weexDom.getComponentRect(ref, option => {
+						resolve(option && option.result ? [option.size] : false);
+					})
+				} else {
+					resolve(false);
+				}
+			});
+			return;
+			// #endif
+			//#ifdef MP-ALIPAY
+			inDom = false;
+			//#endif
+			let res = !!inDom ? uni.createSelectorQuery().in(inDom === true ? this : inDom) : uni.createSelectorQuery();
+			scrollOffset ? res.select(select).scrollOffset() : res.select(select).boundingClientRect();
+			return new Promise((resolve, reject) => {
+				res.exec(data => {
+					resolve((data && data != '' && data != undefined && data.length) ? data : false);
+				});
+			});
+		},
+		//获取slot="left"和slot="right"宽度并且更新布局
+		_updateLeftAndRightWidth(targetStyle, parentNodePrefix) {
+			this.$nextTick(() => {
+				let delayTime = 0;
+				// #ifdef MP-BAIDU
+				delayTime = 10;
+				// #endif
+				setTimeout(() => {
+					['left','right'].map(position => {
+						this._getNodeClientRect(`.${parentNodePrefix}-${position}`).then(res => {
+							this.$set(targetStyle, position, res ? res[0].width + 'px' : '0px');
+						});
+					})
+				}, delayTime)
+			})
+		},
+		//通过获取css设置的底部安全区域占位view高度设置bottom距离
+		_getCssSafeAreaInsetBottom(success) {
+			this._getNodeClientRect('.zp-safe-area-inset-bottom').then(res => {
+				this.cssSafeAreaInsetBottom = res ? res[0].height : -1;
+				res && success && success();
+			});
+		}
+	}
+}
diff --git a/uni_modules/z-paging/components/z-paging/js/modules/data-handle.js b/uni_modules/z-paging/components/z-paging/js/modules/data-handle.js
new file mode 100644
index 0000000..0e64605
--- /dev/null
+++ b/uni_modules/z-paging/components/z-paging/js/modules/data-handle.js
@@ -0,0 +1,746 @@
+// [z-paging]数据处理模块
+import u from '.././z-paging-utils'
+import c from '.././z-paging-constant'
+import Enum from '.././z-paging-enum'
+import interceptor from '../z-paging-interceptor'
+
+export default {
+	props: {
+		//自定义初始的pageNo,默认为1
+		defaultPageNo: {
+			type: [Number, String],
+			default: u.gc('defaultPageNo', 1),
+			observer: function(newVal) {
+				this.pageNo = newVal;
+			},
+		},
+		//自定义pageSize,默认为10
+		defaultPageSize: {
+			type: [Number, String],
+			default: u.gc('defaultPageSize', 10),
+			validator: (value) => {
+				if (value <= 0) u.consoleErr('default-page-size必须大于0!');
+				return value > 0;
+			}
+		},
+		//为保证数据一致,设置当前tab切换时的标识key,并在complete中传递相同key,若二者不一致,则complete将不会生效
+		dataKey: {
+			type: [Number, String, Object],
+			default: function() {
+				return u.gc('dataKey', null);
+			},
+		},
+		//使用缓存,若开启将自动缓存第一页的数据,默认为否。请注意,因考虑到切换tab时不同tab数据不同的情况,默认仅会缓存组件首次加载时第一次请求到的数据,后续的下拉刷新操作不会更新缓存。
+		useCache: {
+			type: Boolean,
+			default: u.gc('useCache', false)
+		},
+		//使用缓存时缓存的key,用于区分不同列表的缓存数据,useCache为true时必须设置,否则缓存无效
+		cacheKey: {
+			type: String,
+			default: u.gc('cacheKey', null)
+		},
+		//缓存模式,默认仅会缓存组件首次加载时第一次请求到的数据,可设置为always,即代表总是缓存,每次列表刷新(下拉刷新、调用reload等)都会更新缓存
+		cacheMode: {
+			type: String,
+			default: u.gc('cacheMode', Enum.CacheMode.Default)
+		},
+		//自动注入的list名,可自动修改父view(包含ref="paging")中对应name的list值
+		autowireListName: {
+			type: String,
+			default: u.gc('autowireListName', '')
+		},
+		//自动注入的query名,可自动调用父view(包含ref="paging")中的query方法
+		autowireQueryName: {
+			type: String,
+			default: u.gc('autowireQueryName', '')
+		},
+		//z-paging mounted后自动调用reload方法(mounted后自动调用接口),默认为是
+		auto: {
+			type: Boolean,
+			default: u.gc('auto', true)
+		},
+		//用户下拉刷新时是否触发reload方法,默认为是
+		reloadWhenRefresh: {
+			type: Boolean,
+			default: u.gc('reloadWhenRefresh', true)
+		},
+		//reload时自动滚动到顶部,默认为是
+		autoScrollToTopWhenReload: {
+			type: Boolean,
+			default: u.gc('autoScrollToTopWhenReload', true)
+		},
+		//reload时立即自动清空原list,默认为是,若立即自动清空,则在reload之后、请求回调之前页面是空白的
+		autoCleanListWhenReload: {
+			type: Boolean,
+			default: u.gc('autoCleanListWhenReload', true)
+		},
+		//列表刷新时自动显示下拉刷新view,默认为否
+		showRefresherWhenReload: {
+			type: Boolean,
+			default: u.gc('showRefresherWhenReload', false)
+		},
+		//列表刷新时自动显示加载更多view,且为加载中状态,默认为否
+		showLoadingMoreWhenReload: {
+			type: Boolean,
+			default: u.gc('showLoadingMoreWhenReload', false)
+		},
+		//组件created时立即触发reload(可解决一些情况下先看到页面再看到loading的问题),auto为true时有效。为否时将在mounted+nextTick后触发reload,默认为否
+		createdReload: {
+			type: Boolean,
+			default: u.gc('createdReload', false)
+		},
+		//本地分页时上拉加载更多延迟时间,单位为毫秒,默认200毫秒
+		localPagingLoadingTime: {
+			type: [Number, String],
+			default: u.gc('localPagingLoadingTime', 200)
+		},
+		//使用聊天记录模式,默认为否
+		useChatRecordMode: {
+			type: Boolean,
+			default: u.gc('useChatRecordMode', false)
+		},
+		//使用聊天记录模式时是否自动隐藏键盘:在用户触摸列表时候自动隐藏键盘,默认为是
+		autoHideKeyboardWhenChat: {
+			type: Boolean,
+			default: u.gc('autoHideKeyboardWhenChat', true)
+		},
+		//自动拼接complete中传过来的数组(使用聊天记录模式时无效)
+		concat: {
+			type: Boolean,
+			default: u.gc('concat', true)
+		},
+		//请求失败是否触发reject,默认为是
+		callNetworkReject: {
+			type: Boolean,
+			default: u.gc('callNetworkReject', true)
+		},
+		//父组件v-model所绑定的list的值
+		value: {
+			type: Array,
+			default: function() {
+				return [];
+			}
+		},
+		// #ifdef VUE3
+		modelValue: {
+			type: Array,
+			default: function() {
+				return [];
+			}
+		}
+		// #endif
+	},
+	data (){
+		return {
+			currentData: [],
+			totalData: [],
+			realTotalData: [],
+			totalLocalPagingList: [],
+			dataPromiseResultMap: {
+				reload: null,
+				complete: null,
+				localPaging: null
+			},
+			isSettingCacheList: false,
+			pageNo: 1,
+			currentRefreshPageSize: 0,
+			isLocalPaging: false,
+			isAddedData: false,
+			isTotalChangeFromAddData: false,
+			privateConcat: true,
+			myParentQuery: -1,
+			firstPageLoaded: false,
+			pagingLoaded: false,
+			loaded: false,
+			isUserReload: true,
+			fromEmptyViewReload: false,
+			queryFrom: '',
+			listRendering: false,
+			isHandlingRefreshToPage: false
+		}
+	},
+	computed: {
+		pageSize() {
+			return this.defaultPageSize;
+		},
+		finalConcat() {
+			return this.concat && this.privateConcat;
+		},
+		finalUseCache() {
+			if (this.useCache && !this.cacheKey) {
+				u.consoleErr('use-cache为true时,必须设置cache-key,否则缓存无效!');
+			}
+			return this.useCache && !!this.cacheKey;
+		},
+		finalCacheKey() {
+			return this.cacheKey ? `${c.cachePrefixKey}-${this.cacheKey}` : null; 
+		},
+		isFirstPage() {
+			return this.pageNo === this.defaultPageNo;
+		}
+	},
+	watch: {
+		totalData(newVal, oldVal) {
+			this._totalDataChange(newVal, oldVal);
+		},
+		currentData(newVal, oldVal) {
+			this._currentDataChange(newVal, oldVal);
+		},
+		useChatRecordMode(newVal, oldVal) {
+			if (newVal) {
+				this.nLoadingMoreFixedHeight = false;
+			}
+		},
+		value: {
+			handler(newVal) {
+				this.realTotalData = newVal;
+			},
+			immediate: true
+		},
+		// #ifdef VUE3
+		modelValue: {
+			handler(newVal) {
+				this.realTotalData = newVal;
+			},
+			immediate: true
+		}
+		// #endif
+	},
+	methods: {
+		//请求结束(成功或者失败)调用此方法,将请求的结果传递给z-paging处理,第一个参数为请求结果数组,第二个参数为是否成功(默认是是)
+		complete(data, success = true) {
+			this.customNoMore = -1;
+			return this.addData(data, success);
+		},
+		//【保证数据一致】请求结束(成功或者失败)调用此方法,将请求的结果传递给z-paging处理,第一个参数为请求结果数组,第二个参数为dataKey,需与:data-key绑定的一致,第三个参数为是否成功(默认为是)
+		completeByKey(data, dataKey = null, success = true) {
+			if (dataKey !== null && this.dataKey !== null && dataKey !== this.dataKey) {
+				this.isFirstPage && this.endRefresh();
+				return new Promise(resolve => resolve());
+			}
+			this.customNoMore = -1;
+			return this.addData(data, success);
+		},
+		//【通过total判断是否有更多数据】请求结束(成功或者失败)调用此方法,将请求的结果传递给z-paging处理,第一个参数为请求结果数组,第二个参数为total(列表总数),第三个参数为是否成功(默认为是)
+		completeByTotal(data, total, success = true) {
+			if (total == 'undefined') {
+				this.customNoMore = -1;
+			} else {
+				const dataTypeRes = this._checkDataType(data, success, false);
+				data = dataTypeRes.data;
+				success = dataTypeRes.success;
+				if (total >= 0 && success) {
+					return new Promise((resolve, reject) => {
+						this.$nextTick(() => {
+							let nomore = false;
+							const realTotalDataCount = this.pageNo == this.defaultPageNo ? 0 : this.realTotalData.length;
+							const dataLength = this.privateConcat ? data.length : 0;
+							let exceedCount = realTotalDataCount + dataLength - total;
+							if (exceedCount >= 0) {
+								nomore = true;
+								exceedCount = this.defaultPageSize - exceedCount;
+								if (this.privateConcat && exceedCount > 0 && exceedCount < data.length) {
+									data = data.splice(0, exceedCount);
+								}
+							}
+							this.completeByNoMore(data, nomore, success).then(res => resolve(res)).catch(() => reject());
+						})
+					});
+				}
+			}
+			return this.addData(data, success);
+		},
+		//【自行判断是否有更多数据】请求结束(成功或者失败)调用此方法,将请求的结果传递给z-paging处理,第一个参数为请求结果数组,第二个参数为是否有更多数据,第三个参数为是否成功(默认是是)
+		completeByNoMore(data, nomore, success = true) {
+			if (nomore != 'undefined') {
+				this.customNoMore = nomore == true ? 1 : 0;
+			}
+			return this.addData(data, success);
+		},
+		//与上方complete方法功能一致,新版本中设置服务端回调数组请使用complete方法
+		addData(data, success = true) {
+			if (!this.fromCompleteEmit) {
+				this.disabledCompleteEmit = true;
+				this.fromCompleteEmit = false;
+			}
+			const currentTimeStamp = u.getTime();
+			const disTime = currentTimeStamp - this.requestTimeStamp;
+			let minDelay = this.minDelay;
+			if (this.isFirstPage && this.finalShowRefresherWhenReload) {
+				minDelay = Math.max(400, minDelay);
+			}
+			const addDataDalay = (this.requestTimeStamp > 0 && disTime < minDelay) ? minDelay - disTime : 0;
+			this.$nextTick(() => {
+				u.delay(() => {
+					this._addData(data, success, false);
+				}, this.delay > 0 ? this.delay : addDataDalay)
+			})
+			
+			return new Promise((resolve, reject) => {
+				this.dataPromiseResultMap.complete = { resolve, reject };
+			});
+		},
+		//从顶部添加数据,不会影响分页的pageNo和pageSize
+		addDataFromTop(data, toTop = true, toTopWithAnimate = true) {
+			data = Object.prototype.toString.call(data) !== '[object Array]' ? [data] : data.reverse();
+			// #ifndef APP-NVUE
+			this.finalUseVirtualList && this._setCellIndex(data, 'top')
+			// #endif
+			this.totalData = [...data, ...this.totalData];
+			if (toTop) {
+				u.delay(() => this._scrollToTop(toTopWithAnimate));
+			}
+		},
+		//重新设置列表数据,调用此方法不会影响pageNo和pageSize,也不会触发请求。适用场景:当需要删除列表中某一项时,将删除对应项后的数组通过此方法传递给z-paging。(当出现类似的需要修改列表数组的场景时,请使用此方法,请勿直接修改page中:list.sync绑定的数组)
+		resetTotalData(data) {
+			this.isTotalChangeFromAddData = true;
+			data = Object.prototype.toString.call(data) !== '[object Array]' ? [data] : data;
+			this.totalData = data;
+		},
+		//添加聊天记录
+		addChatRecordData(data, toBottom = true, toBottomWithAnimate = true) {
+			data = Object.prototype.toString.call(data) !== '[object Array]' ? [data] : data;
+			if (!this.useChatRecordMode) return;
+			this.isTotalChangeFromAddData = true;
+			//#ifndef APP-NVUE
+			this.totalData = [...this.totalData, ...data];
+			//#endif
+			//#ifdef APP-NVUE
+			this.totalData = this.nIsFirstPageAndNoMore ? [...this.totalData, ...data] : [...data, ...this.totalData];
+			//#endif
+			if (toBottom) {
+				u.delay(() => {
+					//#ifndef APP-NVUE
+					this._scrollToBottom(toBottomWithAnimate);
+					//#endif
+					//#ifdef APP-NVUE
+					this.nIsFirstPageAndNoMore ? this._scrollToBottom(toBottomWithAnimate) : this._scrollToTop(toBottomWithAnimate);
+					//#endif
+				})
+			}
+		},
+		//设置本地分页数据,请求结束(成功或者失败)调用此方法,将请求的结果传递给z-paging作分页处理(若调用了此方法,则上拉加载更多时内部会自动分页,不会触发@query所绑定的事件)
+		setLocalPaging(data, success = true) {
+			this.isLocalPaging = true;
+			this.$nextTick(() => {
+				this._addData(data, success, true);
+			})
+			return new Promise((resolve, reject) => {
+				this.dataPromiseResultMap.localPaging = { resolve, reject };
+			});
+		},
+		//重新加载分页数据,pageNo会恢复为默认值,相当于下拉刷新的效果(animate为true时会展示下拉刷新动画,默认为false)
+		reload(animate = this.showRefresherWhenReload) {
+			if (animate) {
+				this.privateShowRefresherWhenReload = animate;
+				this.isUserPullDown = true;
+			}
+			if (!this.showLoadingMoreWhenReload) {
+				this.listRendering = true;
+			}
+			this.$nextTick(() => {
+				this._preReload(animate, false);
+			})
+			return new Promise((resolve, reject) => {
+				this.dataPromiseResultMap.reload = { resolve, reject };
+			});
+		},
+		//刷新列表数据,pageNo和pageSize不会重置,列表数据会重新从服务端获取。必须保证@query绑定的方法中的pageNo和pageSize和传给服务端的一致
+		refresh() {
+			return this._handleRefreshWithDisPageNo(this.pageNo - this.defaultPageNo + 1);
+		},
+		//刷新列表数据至指定页,例如pageNo=5时则代表刷新列表至第5页,此时pageNo会变为5,列表会展示前5页的数据。必须保证@query绑定的方法中的pageNo和pageSize和传给服务端的一致
+		refreshToPage(pageNo) {
+			this.isHandlingRefreshToPage = true;
+			return this._handleRefreshWithDisPageNo(pageNo + this.defaultPageNo - 1);
+		},
+		//手动更新列表缓存数据,将自动截取v-model绑定的list中的前pageSize条覆盖缓存,请确保在list数据更新到预期结果后再调用此方法
+		updateCache() {
+			if (this.finalUseCache && this.totalData.length) {
+				this._saveLocalCache(this.totalData.slice(0, Math.min(this.totalData.length, this.pageSize)));
+			}
+		},
+		//清空分页数据
+		clean() {
+			this._reload(true);
+			this._addData([], true, false);
+		},
+		//清空分页数据
+		clear() {
+			this.clean();
+		},
+		//手动触发滚动到顶部加载更多,聊天记录模式时有效
+		doChatRecordLoadMore() {
+			this.useChatRecordMode && this._onLoadingMore('click');
+		},
+		//reload之前的一些处理
+		_preReload(animate = this.showRefresherWhenReload, isFromMounted = true) {
+			const showRefresher = this.finalRefresherEnabled && this.useCustomRefresher;
+			// #ifndef APP-NVUE
+			if (this.customRefresherHeight === -1 && showRefresher) {
+				u.delay(() => this._preReload(animate, isFromMounted), c.delayTime / 2);
+				return;
+			}
+			// #endif
+			this.isUserReload = true;
+			this.loadingType = Enum.LoadingType.Refresher;
+			if (animate) {
+				this.privateShowRefresherWhenReload = animate;
+				// #ifndef APP-NVUE
+				if (this.useCustomRefresher) {
+					this._doRefresherRefreshAnimate();
+				} else {
+					this.refresherTriggered = true;
+				}
+				// #endif
+				// #ifdef APP-NVUE
+				this.refresherStatus = Enum.Refresher.Loading;
+				this.refresherRevealStackCount ++;
+				u.delay(() => {
+					this._getNodeClientRect('zp-n-refresh-container', false).then((node) => {
+						if (node) {
+							let nodeHeight = node[0].height;
+							this.nShowRefresherReveal = true;
+							this.nShowRefresherRevealHeight = nodeHeight;
+							u.delay(() => {
+								this._nDoRefresherEndAnimation(0, -nodeHeight, false, false);
+								u.delay(() => {
+									this._nDoRefresherEndAnimation(nodeHeight, 0);
+								}, 10)
+							}, 10)
+						}
+						this._reload(false, isFromMounted);
+						this._doRefresherLoad(false);
+					});
+				}, this.pagingLoaded ? 10 : 100)
+				return;
+				// #endif
+			} else {
+				this._refresherEnd(false, false, false, false);
+			}
+			this._reload(false, isFromMounted);
+		},
+		//重新加载分页数据
+		_reload(isClean = false, isFromMounted = false, isUserPullDown = false) {
+			this.isAddedData = false;
+			this.insideOfPaging = -1;
+			this.cacheScrollNodeHeight = -1;
+			this.pageNo = this.defaultPageNo;
+			this._cleanRefresherEndTimeout();
+			!this.privateShowRefresherWhenReload && !isClean && this._startLoading(true);
+			this.firstPageLoaded = true;
+			this.isTotalChangeFromAddData = false;
+			if (!this.isSettingCacheList) {
+				this.totalData = [];
+			}
+			if (!isClean) {
+				this._emitQuery(this.pageNo, this.defaultPageSize, isUserPullDown ? Enum.QueryFrom.UserPullDown : Enum.QueryFrom.Reload);
+				let delay = 0;
+				// #ifdef MP-TOUTIAO
+				delay = 5;
+				// #endif
+				u.delay(this._callMyParentQuery, delay);
+				if (!isFromMounted && this.autoScrollToTopWhenReload) {
+					let checkedNRefresherLoading = true;
+					// #ifdef APP-NVUE
+					checkedNRefresherLoading = !this.nRefresherLoading;
+					// #endif
+					checkedNRefresherLoading && this._scrollToTop(false);
+				}
+			}
+			// #ifdef APP-NVUE
+			this.$nextTick(() => {
+				this.nShowBottom = this.realTotalData.length > 0;
+			})
+			// #endif
+		},
+		//处理服务端返回的数组
+		_addData(data, success, isLocal) {
+			this.isAddedData = true;
+			this.fromEmptyViewReload = false;
+			this.isTotalChangeFromAddData = true;
+			this.refresherTriggered = false;
+			this._endSystemLoadingAndRefresh();
+			const tempIsUserPullDown = this.isUserPullDown;
+			if (this.showRefresherUpdateTime && this.isFirstPage) {
+				u.setRefesrherTime(u.getTime(), this.refresherUpdateTimeKey);
+				this.$refs.refresh && this.$refs.refresh.updateTime();
+			}
+			if (!isLocal && tempIsUserPullDown && this.isFirstPage) {
+				this.isUserPullDown = false;
+			}
+			if (!this.isFirstPage) {
+				this.listRendering = true;
+				this.$nextTick(() => {
+					u.delay(() => this.listRendering = false);
+				})
+			} else {
+				this.listRendering = false;
+			}
+			let dataTypeRes = this._checkDataType(data, success, isLocal);
+			data = dataTypeRes.data;
+			success = dataTypeRes.success;
+			let delayTime = c.delayTime;
+			// #ifdef APP-NVUE
+			if (this.useChatRecordMode) delayTime = 0;
+			// #endif
+			this.loadingForNow = false;
+			u.delay(() => {
+				this.pagingLoaded = true;
+				this.$nextTick(()=>{
+					!isLocal && this._refresherEnd(delayTime > 0, true, tempIsUserPullDown);
+				})
+			})
+			if (this.isFirstPage) {
+				this.isLoadFailed = !success;
+				this.$emit('isLoadFailedChange', this.isLoadFailed);
+				if (this.finalUseCache && success && (this.cacheMode === Enum.CacheMode.Always ? true : this.isSettingCacheList)) {
+					this._saveLocalCache(data);
+				}
+			}
+			this.isSettingCacheList = false;
+			if (success) {
+				if (!(this.privateConcat === false && this.loadingStatus === Enum.More.NoMore)) {
+					this.loadingStatus = Enum.More.Default;
+				}
+				if (isLocal) {
+					this.totalLocalPagingList = data;
+					const localPageNo = this.defaultPageNo;
+					const localPageSize = this.queryFrom !== Enum.QueryFrom.Refresh ? this.defaultPageSize : this.currentRefreshPageSize;
+					this._localPagingQueryList(localPageNo, localPageSize, 0, res => {
+						this.completeByTotal(res, this.totalLocalPagingList.length);
+					})
+				} else {
+					let dataChangeDelayTime = 0;
+					// #ifdef APP-NVUE
+					if (this.privateShowRefresherWhenReload && this.finalNvueListIs === 'waterfall') {
+						dataChangeDelayTime = 150;
+					}
+					// #endif
+					u.delay(() => {
+						this._currentDataChange(data, this.currentData);
+						this._callDataPromise(true, this.totalData);
+					}, dataChangeDelayTime)
+				}
+				if (this.isHandlingRefreshToPage) {
+					this.isHandlingRefreshToPage = false;
+					this.pageNo = this.defaultPageNo + Math.ceil(data.length / this.pageSize) - 1;
+					if (data.length % this.pageSize !== 0) {
+						this.customNoMore = 1;
+					}
+				}
+			} else {
+				this._currentDataChange(data, this.currentData);
+				this._callDataPromise(false);
+				this.loadingStatus = Enum.More.Fail;
+				this.isHandlingRefreshToPage = false;
+				if (this.loadingType === Enum.LoadingType.LoadingMore) {
+					this.pageNo --;
+				}
+			}
+		},
+		//所有数据改变时调用
+		_totalDataChange(newVal, oldVal, eventThrow=true) {
+			if ((!this.isUserReload || !this.autoCleanListWhenReload) && this.firstPageLoaded && !newVal.length && oldVal.length) {
+				return;
+			}
+			this._doCheckScrollViewShouldFullHeight(newVal);
+			if(!this.realTotalData.length && !newVal.length){
+				eventThrow = false;
+			}
+			this.realTotalData = newVal;
+			if (eventThrow) {
+				this.$emit('input', newVal);
+				// #ifdef VUE3
+				this.$emit('update:modelValue', newVal);
+				// #endif
+				this.$emit('update:list', newVal);
+				this.$emit('listChange', newVal);
+				this._callMyParentList(newVal);
+			}
+			this.firstPageLoaded = false;
+			this.isTotalChangeFromAddData = false;
+			this.$nextTick(() => {
+				u.delay(()=>{
+					this._getNodeClientRect('.zp-paging-container-content').then(res => {
+						res && this.$emit('contentHeightChanged', res[0].height);
+					});
+				}, c.delayTime * (this.isIos ? 1 : 3))
+				// #ifdef APP-NVUE
+				if (this.useChatRecordMode && this.nIsFirstPageAndNoMore && this.isFirstPage && !this.nFirstPageAndNoMoreChecked) {
+					this.nFirstPageAndNoMoreChecked = true;
+					this._scrollToBottom(false);
+				}
+				u.delay(() => {
+					this.nShowBottom = true;
+				}, c.delayTime * 6, 'nShowBottomDelay');
+				// #endif
+			})
+		},
+		//当前数据改变时调用
+		_currentDataChange(newVal, oldVal) {
+			newVal = [...newVal];
+			// #ifndef APP-NVUE
+			this.finalUseVirtualList && this._setCellIndex(newVal, 'bottom');
+			this.useChatRecordMode && newVal.reverse();
+			// #endif
+			if (this.isFirstPage && this.finalConcat) {
+				this.totalData = [];
+			}
+			if (this.customNoMore !== -1) {
+				if (this.customNoMore === 1 || !newVal.length) {
+					this.loadingStatus = Enum.More.NoMore;
+				}
+			} else {
+				if (!newVal.length || (newVal.length && newVal.length < this.defaultPageSize)) {
+					this.loadingStatus = Enum.More.NoMore;
+				}
+			}
+			if (!this.totalData.length) {
+				if (this.finalConcat) {
+					// #ifdef APP-NVUE
+					if (this.useChatRecordMode && this.isFirstPage && this.loadingStatus === Enum.More.NoMore) {
+						newVal.reverse();
+					}
+					// #endif
+					this.totalData = newVal;
+				}
+				if (this.useChatRecordMode) {
+					// #ifndef APP-NVUE
+					this.$nextTick(() => {
+						this._scrollToBottom(false);
+					})
+					// #endif
+				}
+			} else {
+				if (this.useChatRecordMode) {
+					// #ifdef APP-NVUE
+					this.totalData = [...this.totalData, ...newVal];
+					// #endif
+					//#ifndef APP-NVUE
+					const idIndex = newVal.length;
+					let idIndexStr = `z-paging-${idIndex}`;
+					this.totalData = [...newVal, ...this.totalData];
+					if (this.pageNo !== this.defaultPageNo) {
+						this.privateScrollWithAnimation = 0;
+						this.$emit('update:chatIndex', idIndex);
+						this.$nextTick(() => {
+							this._scrollIntoView(idIndexStr, 30 + Math.max(0, this.cacheTopHeight), false, () => {
+								this.$emit('update:chatIndex', 0);
+							});
+						})
+					} else {
+						this.$nextTick(() => {
+							this._scrollToBottom(false);
+						})
+					}
+					//#endif
+		
+				} else {
+					if (this.finalConcat) {
+						const currentScrollTop = this.oldScrollTop;
+						this.totalData = [...this.totalData, ...newVal];
+						// #ifdef MP-WEIXIN
+						if (!this.isIos && !this.refresherOnly && !this.usePageScroll && newVal.length) {
+							this.loadingMoreTimeStamp = u.getTime();
+							this.$nextTick(() => {
+								this.scrollToY(currentScrollTop);
+							})
+						}
+						// #endif
+					} else {
+						this.totalData = newVal;
+					}
+				}
+			}
+			this.privateConcat = true;
+		},
+		//根据pageNo处理refresh操作
+		_handleRefreshWithDisPageNo(pageNo) {
+			if (!this.realTotalData.length) return this.reload();
+			if (pageNo >= 1) {
+				this.loading = true;
+				this.privateConcat = false;
+				const totalPageSize = pageNo * this.pageSize;
+				this.currentRefreshPageSize = totalPageSize;
+				this._emitQuery(this.defaultPageNo, totalPageSize, Enum.QueryFrom.Refresh);
+				this._callMyParentQuery(this.defaultPageNo, totalPageSize);
+			}
+			return new Promise((resolve, reject) => {
+				this.dataPromiseResultMap.reload = { resolve, reject };
+			});
+		},
+		//本地分页请求
+		_localPagingQueryList(pageNo, pageSize, localPagingLoadingTime, callback) {
+			pageNo = Math.max(1, pageNo);
+			pageSize = Math.max(1, pageSize);
+			const totalPagingList = [...this.totalLocalPagingList];
+			const pageNoIndex = (pageNo - 1) * pageSize;
+			const finalPageNoIndex = Math.min(totalPagingList.length, pageNoIndex + pageSize);
+			const resultPagingList = totalPagingList.splice(pageNoIndex, finalPageNoIndex - pageNoIndex);
+			u.delay(() => callback(resultPagingList), localPagingLoadingTime)
+		},
+		//存储列表缓存数据
+		_saveLocalCache(data) {
+			uni.setStorageSync(this.finalCacheKey, data);
+		},
+		//通过缓存数据填充列表数据
+		_setListByLocalCache() {
+			this.totalData = uni.getStorageSync(this.finalCacheKey) || [];
+			this.isSettingCacheList = true;
+		},
+		//修改父view的list
+		_callMyParentList(newVal) {
+			if (this.autowireListName.length) {
+				const myParent = u.getParent(this.$parent);
+				if (myParent && myParent[this.autowireListName]) {
+					myParent[this.autowireListName] = newVal;
+				}
+			}
+		},
+		//调用父view的query
+		_callMyParentQuery(customPageNo = 0, customPageSize = 0) {
+			if (this.autowireQueryName) {
+				if (this.myParentQuery === -1) {
+					const myParent = u.getParent(this.$parent);
+					if (myParent && myParent[this.autowireQueryName]) {
+						this.myParentQuery = myParent[this.autowireQueryName];
+					}
+				} 
+				if (this.myParentQuery !== -1) {
+					customPageSize > 0 ? this.myParentQuery(customPageNo, customPageSize) : this.myParentQuery(this.pageNo, this.defaultPageSize);
+				}
+			}
+		},
+		//emit query事件
+		_emitQuery(pageNo, pageSize, from){
+			this.queryFrom = from;
+			this.requestTimeStamp = u.getTime();
+			const [lastItem] = this.realTotalData.slice(-1);
+			this.$emit('query', ...interceptor._handleQuery(pageNo, pageSize, from, lastItem || null));
+		},
+		//触发数据改变promise
+		_callDataPromise(success, totalList) {
+			for (const key in this.dataPromiseResultMap) {
+				const obj = this.dataPromiseResultMap[key];
+				if (!obj) continue;
+				success ? obj.resolve({ totalList, noMore: this.loadingStatus === Enum.More.NoMore }) : this.callNetworkReject && obj.reject(`z-paging-${key}-error`);
+			}
+		},
+		//检查complete data的类型
+		_checkDataType(data, success, isLocal) {
+			const dataType = Object.prototype.toString.call(data);
+			if (dataType === '[object Boolean]') {
+				success = data;
+				data = [];
+			} else if (dataType !== '[object Array]') {
+				data = [];
+				if (dataType !== '[object Undefined]' && dataType !== '[object Null]') {
+					u.consoleErr(`${isLocal ? 'setLocalPaging' : 'complete'}参数类型不正确,第一个参数类型必须为Array!`);
+				}
+			}
+			return { data, success };
+		},
+	}
+}
diff --git a/uni_modules/z-paging/components/z-paging/js/modules/empty.js b/uni_modules/z-paging/components/z-paging/js/modules/empty.js
new file mode 100644
index 0000000..fdf7be0
--- /dev/null
+++ b/uni_modules/z-paging/components/z-paging/js/modules/empty.js
@@ -0,0 +1,147 @@
+// [z-paging]空数据图view模块
+import u from '.././z-paging-utils'
+
+export default {
+	props: {
+		//是否强制隐藏空数据图,默认为否
+		hideEmptyView: {
+			type: Boolean,
+			default: u.gc('hideEmptyView', false)
+		},
+		//空数据图描述文字,默认为“没有数据哦~”
+		emptyViewText: {
+			type: [String, Object],
+			default: u.gc('emptyViewText', null)
+		},
+		//是否显示空数据图重新加载按钮(无数据时),默认为否
+		showEmptyViewReload: {
+			type: Boolean,
+			default: u.gc('showEmptyViewReload', false)
+		},
+		//加载失败时是否显示空数据图重新加载按钮,默认为是
+		showEmptyViewReloadWhenError: {
+			type: Boolean,
+			default: u.gc('showEmptyViewReloadWhenError', true)
+		},
+		//空数据图点击重新加载文字,默认为“重新加载”
+		emptyViewReloadText: {
+			type: [String, Object],
+			default: u.gc('emptyViewReloadText', null)
+		},
+		//空数据图图片,默认使用z-paging内置的图片
+		emptyViewImg: {
+			type: String,
+			default: u.gc('emptyViewImg', '')
+		},
+		//空数据图“加载失败”描述文字,默认为“很抱歉,加载失败”
+		emptyViewErrorText: {
+			type: [String, Object],
+			default: u.gc('emptyViewErrorText', null)
+		},
+		//空数据图“加载失败”图片,默认使用z-paging内置的图片
+		emptyViewErrorImg: {
+			type: String,
+			default: u.gc('emptyViewErrorImg', '')
+		},
+		//空数据图样式
+		emptyViewStyle: {
+			type: Object,
+			default: function() {
+				return u.gc('emptyViewStyle', {});
+			}
+		},
+		//空数据图容器样式
+		emptyViewSuperStyle: {
+			type: Object,
+			default: function() {
+				return u.gc('emptyViewSuperStyle', {});
+			}
+		},
+		//空数据图img样式
+		emptyViewImgStyle: {
+			type: Object,
+			default: function() {
+				return u.gc('emptyViewImgStyle', {});
+			}
+		},
+		//空数据图描述文字样式
+		emptyViewTitleStyle: {
+			type: Object,
+			default: function() {
+				return u.gc('emptyViewTitleStyle', {});
+			}
+		},
+		//空数据图重新加载按钮样式
+		emptyViewReloadStyle: {
+			type: Object,
+			default: function() {
+				return u.gc('emptyViewReloadStyle', {});
+			}
+		},
+		//空数据图片是否铺满z-paging,默认为否,即填充满z-paging内列表(滚动区域)部分。若设置为否,则为填铺满整个z-paging
+		emptyViewFixed: {
+			type: Boolean,
+			default: u.gc('emptyViewFixed', false)
+		},
+		//空数据图片是否垂直居中,默认为是,若设置为否即为从空数据容器顶部开始显示。emptyViewFixed为false时有效
+		emptyViewCenter: {
+			type: Boolean,
+			default: u.gc('emptyViewCenter', true)
+		},
+		//加载中时是否自动隐藏空数据图,默认为是
+		autoHideEmptyViewWhenLoading: {
+			type: Boolean,
+			default: u.gc('autoHideEmptyViewWhenLoading', true)
+		},
+		//用户下拉列表触发下拉刷新加载中时是否自动隐藏空数据图,默认为是
+		autoHideEmptyViewWhenPull: {
+			type: Boolean,
+			default: u.gc('autoHideEmptyViewWhenPull', true)
+		},
+		//空数据view的z-index,默认为9
+		emptyViewZIndex: {
+			type: Number,
+			default: u.gc('emptyViewZIndex', 9)
+		},
+	},
+	computed: {
+		finalEmptyViewImg() {
+			return this.isLoadFailed ? this.emptyViewErrorImg : this.emptyViewImg;
+		},
+		finalShowEmptyViewReload() {
+			return this.isLoadFailed ? this.showEmptyViewReloadWhenError : this.showEmptyViewReload;
+		},
+		showEmpty() {
+			if (this.refresherOnly || this.hideEmptyView || this.realTotalData.length) return false;
+			if (this.autoHideEmptyViewWhenLoading) {
+				if (this.isAddedData && !this.firstPageLoaded && !this.loading) return true;
+			} else {
+				return true;
+			}
+			return !this.autoHideEmptyViewWhenPull && !this.isUserReload;
+		},
+	},
+	methods: {
+		//点击了空数据view重新加载按钮
+		_emptyViewReload() {
+			let callbacked = false;
+			this.$emit('emptyViewReload', reload => {
+				if (reload === undefined || reload === true) {
+					this.fromEmptyViewReload = true;
+					this.reload().catch(() => {});
+				}
+				callbacked = true;
+			});
+			this.$nextTick(() => {
+				if (!callbacked) {
+					this.fromEmptyViewReload = true;
+					this.reload().catch(() => {});
+				}
+			})
+		},
+		//点击了空数据view
+		_emptyViewClick() {
+			this.$emit('emptyViewClick');
+		},
+	}
+}
\ No newline at end of file
diff --git a/uni_modules/z-paging/components/z-paging/js/modules/i18n.js b/uni_modules/z-paging/components/z-paging/js/modules/i18n.js
new file mode 100644
index 0000000..6502df9
--- /dev/null
+++ b/uni_modules/z-paging/components/z-paging/js/modules/i18n.js
@@ -0,0 +1,101 @@
+// [z-paging]i18n模块
+import { initVueI18n } from '@dcloudio/uni-i18n'
+import messages from '../../i18n/index.js'
+const { t } = initVueI18n(messages)
+
+import u from '.././z-paging-utils'
+import c from '.././z-paging-constant'
+import interceptor from '../z-paging-interceptor'
+
+const language = uni.getSystemInfoSync().language;
+export default {
+	data() {
+		return {
+			language
+		}
+	},
+	computed: {
+		finalLanguage() {
+			try {
+				const local = uni.getLocale();
+				const language = this.language;
+				return local === 'auto' ? interceptor._handleLanguage2Local(language, this._language2Local(language)) : local;
+			} catch (e) {
+				return 'zh-Hans';
+			}
+		},
+		finalRefresherDefaultText() {
+			return this._getI18nText('zp.refresher.default', this.refresherDefaultText);
+		},
+		finalRefresherPullingText() {
+			return this._getI18nText('zp.refresher.pulling', this.refresherPullingText);
+		},
+		finalRefresherRefreshingText() {
+			return this._getI18nText('zp.refresher.refreshing', this.refresherRefreshingText);
+		},
+		finalRefresherCompleteText() {
+			return this._getI18nText('zp.refresher.complete', this.refresherCompleteText);
+		},
+		finalRefresherUpdateTimeTextMap() {
+			return {
+				title: t('zp.refresherUpdateTime.title'),
+				none: t('zp.refresherUpdateTime.none'),
+				today: t('zp.refresherUpdateTime.today'),
+				yesterday: t('zp.refresherUpdateTime.yesterday')
+			};
+		},
+		finalLoadingMoreDefaultText() {
+			return this._getI18nText('zp.loadingMore.default', this.loadingMoreDefaultText);
+		},
+		finalLoadingMoreLoadingText() {
+			return this._getI18nText('zp.loadingMore.loading', this.loadingMoreLoadingText);
+		},
+		finalLoadingMoreNoMoreText() {
+			return this._getI18nText('zp.loadingMore.noMore', this.loadingMoreNoMoreText);
+		},
+		finalLoadingMoreFailText() {
+			return this._getI18nText('zp.loadingMore.fail', this.loadingMoreFailText);
+		},
+		finalEmptyViewText() {
+			return this.isLoadFailed ? this.finalEmptyViewErrorText : this._getI18nText('zp.emptyView.title', this.emptyViewText);
+		},
+		finalEmptyViewReloadText() {
+			return this._getI18nText('zp.emptyView.reload', this.emptyViewReloadText);
+		},
+		finalEmptyViewErrorText() {
+			return this._getI18nText('zp.emptyView.error', this.emptyViewErrorText);
+		},
+		finalSystemLoadingText() {
+			return this._getI18nText('zp.systemLoading.title', this.systemLoadingText);
+		},
+	},
+	methods: {
+		//获取当前z-paging的语言
+		getLanguage() {
+			return this.finalLanguage;
+		},
+		//获取国际化转换后的文本
+		_getI18nText(key, value) {
+			const dataType = Object.prototype.toString.call(value);
+			if (dataType === '[object Object]') {
+				const nextValue = value[this.finalLanguage];
+				if (nextValue) return nextValue;
+			} else if (dataType === '[object String]') {
+				return value;
+			}
+			return t(key);
+		},
+		//系统language转i18n local
+		_language2Local(language) {
+			const formatedLanguage = language.toLowerCase().replace(new RegExp('_', ''), '-');
+			if (formatedLanguage.indexOf('zh') !== -1) {
+				if (formatedLanguage === 'zh' || formatedLanguage === 'zh-cn' || formatedLanguage.indexOf('zh-hans') !== -1) {
+					return 'zh-Hans';
+				}
+				return 'zh-Hant';
+			}
+			if (formatedLanguage.indexOf('en') !== -1) return 'en';
+			return language;
+		}
+	}
+}
diff --git a/uni_modules/z-paging/components/z-paging/js/modules/load-more.js b/uni_modules/z-paging/components/z-paging/js/modules/load-more.js
new file mode 100644
index 0000000..c47be08
--- /dev/null
+++ b/uni_modules/z-paging/components/z-paging/js/modules/load-more.js
@@ -0,0 +1,315 @@
+// [z-paging]滚动到底部加载更多模块
+import u from '.././z-paging-utils'
+import Enum from '.././z-paging-enum'
+
+export default {
+	props: {
+		//自定义底部加载更多样式
+		loadingMoreCustomStyle: {
+			type: Object,
+			default: function() {
+				return u.gc('loadingMoreCustomStyle', {});
+			}
+		},
+		//自定义底部加载更多文字样式
+		loadingMoreTitleCustomStyle: {
+			type: Object,
+			default: function() {
+				return u.gc('loadingMoreTitleCustomStyle', {});
+			}
+		},
+		//自定义底部加载更多加载中动画样式
+		loadingMoreLoadingIconCustomStyle: {
+			type: Object,
+			default: function() {
+				return u.gc('loadingMoreLoadingIconCustomStyle', {});
+			}
+		},
+		//自定义底部加载更多加载中动画图标类型,可选flower或circle,默认为flower
+		loadingMoreLoadingIconType: {
+			type: String,
+			default: u.gc('loadingMoreLoadingIconType', 'flower')
+		},
+		//自定义底部加载更多加载中动画图标图片
+		loadingMoreLoadingIconCustomImage: {
+			type: String,
+			default: u.gc('loadingMoreLoadingIconCustomImage', '')
+		},
+		//底部加载更多加载中view是否展示旋转动画,默认为是
+		loadingMoreLoadingAnimated: {
+			type: Boolean,
+			default: u.gc('loadingMoreLoadingAnimated', true)
+		},
+		//是否启用加载更多数据(含滑动到底部加载更多数据和点击加载更多数据),默认为是
+		loadingMoreEnabled: {
+			type: Boolean,
+			default: u.gc('loadingMoreEnabled', true)
+		},
+		//是否启用滑动到底部加载更多数据,默认为是
+		toBottomLoadingMoreEnabled: {
+			type: Boolean,
+			default: u.gc('toBottomLoadingMoreEnabled', true)
+		},
+		//滑动到底部状态为默认状态时,以加载中的状态展示,默认为否。若设置为是,可避免滚动到底部看到默认状态然后立刻变为加载中状态的问题,但分页数量未超过一屏时,不会显示【点击加载更多】
+		loadingMoreDefaultAsLoading: {
+			type: [Boolean],
+			default: u.gc('loadingMoreDefaultAsLoading', false)
+		},
+		//滑动到底部"默认"文字,默认为【点击加载更多】
+		loadingMoreDefaultText: {
+			type: [String, Object],
+			default: u.gc('loadingMoreDefaultText', null)
+		},
+		//滑动到底部"加载中"文字,默认为【正在加载...】
+		loadingMoreLoadingText: {
+			type: [String, Object],
+			default: u.gc('loadingMoreLoadingText', null)
+		},
+		//滑动到底部"没有更多"文字,默认为【没有更多了】
+		loadingMoreNoMoreText: {
+			type: [String, Object],
+			default: u.gc('loadingMoreNoMoreText', null)
+		},
+		//滑动到底部"加载失败"文字,默认为【加载失败,点击重新加载】
+		loadingMoreFailText: {
+			type: [String, Object],
+			default: u.gc('loadingMoreFailText', null)
+		},
+		//当没有更多数据且分页内容未超出z-paging时是否隐藏没有更多数据的view,默认为否
+		hideNoMoreInside: {
+			type: Boolean,
+			default: u.gc('hideNoMoreInside', false)
+		},
+		//当没有更多数据且分页数组长度少于这个值时,隐藏没有更多数据的view,默认为0,代表不限制。
+		hideNoMoreByLimit: {
+			type: Number,
+			default: u.gc('hideNoMoreByLimit', 0)
+		},
+		//是否显示默认的加载更多text,默认为是
+		showDefaultLoadingMoreText: {
+			type: Boolean,
+			default: u.gc('showDefaultLoadingMoreText', true)
+		},
+		//是否显示没有更多数据的view
+		showLoadingMoreNoMoreView: {
+			type: Boolean,
+			default: u.gc('showLoadingMoreNoMoreView', true)
+		},
+		//是否显示没有更多数据的分割线,默认为是
+		showLoadingMoreNoMoreLine: {
+			type: Boolean,
+			default: u.gc('showLoadingMoreNoMoreLine', true)
+		},
+		//自定义底部没有更多数据的分割线样式
+		loadingMoreNoMoreLineCustomStyle: {
+			type: Object,
+			default: function() {
+				return u.gc('loadingMoreNoMoreLineCustomStyle', {});
+			},
+		},
+		//当分页未满一屏时,是否自动加载更多,默认为否(nvue无效)
+		insideMore: {
+			type: Boolean,
+			default: u.gc('insideMore', false)
+		},
+		//距底部/右边多远时(单位px),触发 scrolltolower 事件,默认为100rpx
+		lowerThreshold: {
+			type: [Number, String],
+			default: u.gc('lowerThreshold', '100rpx')
+		},
+	},
+	data() {
+		return {
+			M: Enum.More,
+			//底部加载更多状态
+			loadingStatus: Enum.More.Default,
+			loadingStatusAfterRender: Enum.More.Default,
+			loadingMoreTimeStamp: 0,
+			loadingMoreDefaultSlot: null,
+			showLoadingMore: false,
+			customNoMore: -1,
+		}
+	},
+	computed: {
+		zLoadMoreConfig() {
+			return {
+				status: this.loadingStatusAfterRender,
+				defaultAsLoading: this.loadingMoreDefaultAsLoading,
+				defaultThemeStyle: this.finalLoadingMoreThemeStyle,
+				customStyle: this.loadingMoreCustomStyle,
+				titleCustomStyle: this.loadingMoreTitleCustomStyle,
+				iconCustomStyle: this.loadingMoreLoadingIconCustomStyle,
+				loadingIconType: this.loadingMoreLoadingIconType,
+				loadingIconCustomImage: this.loadingMoreLoadingIconCustomImage,
+				loadingAnimated: this.loadingMoreLoadingAnimated,
+				showNoMoreLine: this.showLoadingMoreNoMoreLine,
+				noMoreLineCustomStyle: this.loadingMoreNoMoreLineCustomStyle,
+				defaultText: this.finalLoadingMoreDefaultText,
+				loadingText: this.finalLoadingMoreLoadingText,
+				noMoreText: this.finalLoadingMoreNoMoreText,
+				failText: this.finalLoadingMoreFailText,
+				hideContent: !this.loadingMoreDefaultAsLoading && this.listRendering,
+			};
+		},
+		finalLoadingMoreThemeStyle() {
+			return this.loadingMoreThemeStyle.length ? this.loadingMoreThemeStyle : this.defaultThemeStyle;
+		},
+		showLoadingMoreDefault() {
+			return this._showLoadingMore('Default');
+		},
+		showLoadingMoreLoading() {
+			return this._showLoadingMore('Loading');
+		},
+		showLoadingMoreNoMore() {
+			return this._showLoadingMore('NoMore');
+		},
+		showLoadingMoreFail() {
+			return this._showLoadingMore('Fail');
+		},
+		showLoadingMoreCustom() {
+			return this._showLoadingMore('Custom');
+		}
+	},
+	methods: {
+		//页面滚动到底部时通知z-paging进行进一步处理
+		pageReachBottom() {
+			!this.useChatRecordMode && this._onLoadingMore('toBottom');
+		},
+		//手动触发上拉加载更多(非必须,可依据具体需求使用)
+		doLoadMore(type) {
+			this._onLoadingMore(type);
+		},
+		//通过@scroll事件检测是否滚动到了底部
+		_checkScrolledToBottom(scrollDiff, checked = false) {
+			if (this.cacheScrollNodeHeight === -1) {
+				this._getNodeClientRect('.zp-scroll-view').then((res) => {
+					if (res) {
+						const pageScrollNodeHeight = res[0].height;
+						this.cacheScrollNodeHeight = pageScrollNodeHeight;
+						if (scrollDiff - pageScrollNodeHeight <= this.finalLowerThreshold) {
+							this._onLoadingMore('toBottom');
+						}
+					}
+				});
+			} else {
+				if (scrollDiff - this.cacheScrollNodeHeight <= this.finalLowerThreshold) {
+					this._onLoadingMore('toBottom');
+				} else if (scrollDiff - this.cacheScrollNodeHeight <= 500 && !checked) {
+					u.delay(() => {
+						this._getNodeClientRect('.zp-scroll-view', true, true).then((res) => {
+							this.oldScrollTop = res[0].scrollTop;
+							const newScrollDiff = res[0].scrollHeight - this.oldScrollTop;
+							this._checkScrolledToBottom(newScrollDiff, true);
+						})
+					}, 150, 'checkScrolledToBottomDelay')
+				}
+			}
+		},
+		//触发加载更多时调用,from:toBottom-滑动到底部触发;1、click-点击加载更多触发
+		_onLoadingMore(from = 'click') {
+			if (this.isIos && from === 'toBottom' && !this.scrollToBottomBounceEnabled && this.scrollEnable) {
+				this.scrollEnable = false;
+				this.$nextTick(() => {
+					this.scrollEnable = true;
+				})
+			}
+			this.$emit('scrolltolower', from);
+			if (from === 'toBottom' && (!this.toBottomLoadingMoreEnabled || this.useChatRecordMode)) return;
+			if (this.refresherOnly || !this.loadingMoreEnabled || !(this.loadingStatus === Enum.More.Default || this.loadingStatus === Enum.More.Fail) || this.loading || this.showEmpty) return;
+			// #ifdef MP-WEIXIN
+			if (!this.isIos && !this.refresherOnly && !this.usePageScroll) {
+				const currentTimestamp = u.getTime();
+				if (this.loadingMoreTimeStamp > 0 && currentTimestamp - this.loadingMoreTimeStamp < 100) {
+					this.loadingMoreTimeStamp = 0;
+					return;
+				}
+			}
+			// #endif
+			this._doLoadingMore();
+		},
+		//处理开始加载更多
+		_doLoadingMore() {
+			if (this.pageNo >= this.defaultPageNo && this.loadingStatus !== Enum.More.NoMore) {
+				this.pageNo ++;
+				this._startLoading(false);
+				if (this.isLocalPaging) {
+					this._localPagingQueryList(this.pageNo, this.defaultPageSize, this.localPagingLoadingTime, res => {
+						this.completeByTotal(res, this.totalLocalPagingList.length);
+					})
+				} else {
+					this._emitQuery(this.pageNo, this.defaultPageSize, Enum.QueryFrom.LoadingMore);
+					this._callMyParentQuery();
+				}
+				this.loadingType = Enum.LoadingType.LoadingMore;
+			}
+		},
+		//(预处理)判断当没有更多数据且分页内容未超出z-paging时是否显示没有更多数据的view
+		_preCheckShowNoMoreInside(newVal, scrollViewNode, pagingContainerNode) {
+			if (this.loadingStatus === Enum.More.NoMore && this.hideNoMoreByLimit > 0 && newVal.length) {
+				this.showLoadingMore = newVal.length > this.hideNoMoreByLimit;
+			} else if ((this.loadingStatus === Enum.More.NoMore && this.hideNoMoreInside && newVal.length) || (this.insideMore && this.insideOfPaging !== false && newVal.length)) {
+				this.$nextTick(() => {
+					this._checkShowNoMoreInside(newVal, scrollViewNode, pagingContainerNode);
+				})
+				if (this.insideMore && this.insideOfPaging !== false && newVal.length) {
+					this.showLoadingMore = newVal.length;
+				}
+			} else {
+				this.showLoadingMore = newVal.length;
+			}
+		},
+		//判断当没有更多数据且分页内容未超出z-paging时是否显示没有更多数据的view
+		async _checkShowNoMoreInside(totalData, oldScrollViewNode, oldPagingContainerNode) {
+			try {
+				const scrollViewNode = oldScrollViewNode || await this._getNodeClientRect('.zp-scroll-view');
+				if (this.usePageScroll) {
+					if (scrollViewNode) {
+						const scrollViewTotalH = scrollViewNode[0].top + scrollViewNode[0].height;
+						this.insideOfPaging = scrollViewTotalH < this.windowHeight;
+						if (this.hideNoMoreInside) {
+							this.showLoadingMore = !this.insideOfPaging;
+						}
+						this._updateInsideOfPaging();
+					}
+				} else {
+					const pagingContainerNode = oldPagingContainerNode || await this._getNodeClientRect('.zp-paging-container-content');
+					const pagingContainerH = pagingContainerNode ? pagingContainerNode[0].height : 0;
+					const scrollViewH = scrollViewNode ? scrollViewNode[0].height : 0;
+					this.insideOfPaging = pagingContainerH < scrollViewH;
+					if (this.hideNoMoreInside) {
+						this.showLoadingMore = !this.insideOfPaging;
+					}
+					this._updateInsideOfPaging();
+				}
+			} catch (e) {
+				this.insideOfPaging = !totalData.length;
+				if (this.hideNoMoreInside) {
+					this.showLoadingMore = !this.insideOfPaging;
+				}
+				this._updateInsideOfPaging();
+			}
+		},
+		//是否要展示上拉加载更多view
+		_showLoadingMore(type) {
+			if (!this.showLoadingMoreWhenReload && (!(this.loadingStatus === Enum.More.Default ? this.nShowBottom : true) || !this.realTotalData.length)) return false;
+			if (((!this.showLoadingMoreWhenReload || this.isUserPullDown || this.loadingStatus !== Enum.More.Loading) && !this.showLoadingMore) || 
+			(!this.loadingMoreEnabled && (!this.showLoadingMoreWhenReload || this.isUserPullDown || this.loadingStatus !== Enum.More.Loading)) || this.refresherOnly) {
+				return false;
+			}
+			if (this.useChatRecordMode && type !== 'Loading') return false;
+			if (!this.zSlots) return false;
+			if (type === 'Custom') {
+				return this.showDefaultLoadingMoreText && !(this.loadingStatus === Enum.More.NoMore && !this.showLoadingMoreNoMoreView);
+			}
+			const res = this.loadingStatus === Enum.More[type] && this.zSlots[`loadingMore${type}`] && (type === 'NoMore' ? this.showLoadingMoreNoMoreView : true);
+			if (res) {
+				// #ifdef APP-NVUE
+				if (!this.isIos) {
+					this.nLoadingMoreFixedHeight = false;
+				}
+				//  #endif
+			}
+			return res;
+		},
+	}
+}
diff --git a/uni_modules/z-paging/components/z-paging/js/modules/loading.js b/uni_modules/z-paging/components/z-paging/js/modules/loading.js
new file mode 100644
index 0000000..52960a5
--- /dev/null
+++ b/uni_modules/z-paging/components/z-paging/js/modules/loading.js
@@ -0,0 +1,93 @@
+// [z-paging]loading相关模块
+import u from '.././z-paging-utils'
+import Enum from '.././z-paging-enum'
+
+export default {
+	props: {
+		//第一次加载后自动隐藏loading slot,默认为是
+		autoHideLoadingAfterFirstLoaded: {
+			type: Boolean,
+			default: u.gc('autoHideLoadingAfterFirstLoaded', true)
+		},
+		//loading slot是否铺满屏幕并固定,默认为否
+		loadingFullFixed: {
+			type: Boolean,
+			default: u.gc('loadingFullFixed', false)
+		},
+		//是否自动显示系统Loading:即uni.showLoading,若开启则将在刷新列表时(调用reload、refresh时)显示,下拉刷新和滚动到底部加载更多不会显示,默认为false。
+		autoShowSystemLoading: {
+			type: Boolean,
+			default: u.gc('autoShowSystemLoading', false)
+		},
+		//显示系统Loading时是否显示透明蒙层,防止触摸穿透,默认为是(H5、App、微信小程序、百度小程序有效)
+		systemLoadingMask: {
+			type: Boolean,
+			default: u.gc('systemLoadingMask', true)
+		},
+		//显示系统Loading时显示的文字,默认为"加载中"
+		systemLoadingText: {
+			type: [String, Object],
+			default: u.gc('systemLoadingText', null)
+		},
+	},
+	data() {
+		return {
+			loading: false,
+			loadingForNow: false,
+		}
+	},
+	watch: {
+		loadingStatus(newVal) {
+			this.$emit('loadingStatusChange', newVal);
+			this.$nextTick(() => {
+				this.loadingStatusAfterRender = newVal;
+			})
+			// #ifdef APP-NVUE
+			if (this.useChatRecordMode) {
+				if (this.pageNo === this.defaultPageNo && newVal === Enum.More.NoMore) {
+					this.nIsFirstPageAndNoMore = true;
+					return;
+				}
+			}
+			this.nIsFirstPageAndNoMore = false;
+			//  #endif
+		},
+		loading(newVal){
+			if (newVal) {
+				this.loadingForNow = newVal;
+			}
+		},
+	},
+	computed: {
+		showLoading() {
+			if (this.firstPageLoaded || !this.loading || !this.loadingForNow) return false;
+			if (this.finalShowSystemLoading){
+				uni.showLoading({
+					title: this.finalSystemLoadingText,
+					mask: this.systemLoadingMask
+				})
+			}
+			return this.autoHideLoadingAfterFirstLoaded ? (this.fromEmptyViewReload ? true : !this.pagingLoaded) : this.loadingType === Enum.LoadingType.Refresher;
+		},
+		finalShowSystemLoading() {
+			return this.autoShowSystemLoading && this.loadingType === Enum.LoadingType.Refresher;
+		}
+	},
+	methods: {
+		//处理开始加载更多状态
+		_startLoading(isReload = false) {
+			if ((this.showLoadingMoreWhenReload && !this.isUserPullDown) || !isReload) {
+				this.loadingStatus = Enum.More.Loading;
+			}
+			this.loading = true;
+		},
+		//停止系统loading和refresh
+		_endSystemLoadingAndRefresh(){
+			this.finalShowSystemLoading && uni.hideLoading();
+			!this.useCustomRefresher && uni.stopPullDownRefresh();
+			// #ifdef APP-NVUE
+			this.usePageScroll && uni.stopPullDownRefresh();
+			// #endif
+		}
+	}
+}
diff --git a/uni_modules/z-paging/components/z-paging/js/modules/nvue.js b/uni_modules/z-paging/components/z-paging/js/modules/nvue.js
new file mode 100644
index 0000000..2228841
--- /dev/null
+++ b/uni_modules/z-paging/components/z-paging/js/modules/nvue.js
@@ -0,0 +1,249 @@
+// [z-paging]nvue独有部分模块
+import u from '.././z-paging-utils'
+import c from '.././z-paging-constant'
+import Enum from '.././z-paging-enum'
+
+// #ifdef APP-NVUE
+const weexAnimation = weex.requireModule('animation');
+// #endif
+export default {
+	props: {
+		// #ifdef APP-NVUE
+		//nvue中修改列表类型,可选值有list、waterfall和scroller,默认为list
+		nvueListIs: {
+			type: String,
+			default: u.gc('nvueListIs', 'list')
+		},
+		//nvue waterfall配置,仅在nvue中且nvueListIs=waterfall时有效,配置参数详情参见:https://uniapp.dcloud.io/component/waterfall
+		nvueWaterfallConfig: {
+			type: Object,
+			default: function() {
+				return u.gc('nvueWaterfallConfig', {});
+			}
+		},
+		//nvue 控制是否回弹效果,iOS不支持动态修改
+		nvueBounce: {
+			type: Boolean,
+			default: u.gc('nvueBounce', true)
+		},
+		//nvue中通过代码滚动到顶部/底部时,是否加快动画效果(无滚动动画时无效),默认为否
+		nvueFastScroll: {
+			type: Boolean,
+			default: u.gc('nvueFastScroll', false)
+		},
+		//nvue中list的id
+		nvueListId: {
+			type: String,
+			default: u.gc('nvueListId', '')
+		},
+		//nvue中refresh组件的样式
+		nvueRefresherStyle: {
+			type: Object,
+			default: function() {
+				return u.gc('nvueRefresherStyle', {});
+			}
+		},
+		//nvue中是否按分页模式(类似竖向swiper)显示List,默认为false
+		nvuePagingEnabled: {
+			type: Boolean,
+			default: u.gc('nvuePagingEnabled', false)
+		},
+		//是否隐藏nvue列表底部的tagView,此view用于标识滚动到底部位置,若隐藏则滚动到底部功能将失效,在nvue中实现吸顶+swiper功能时需将最外层z-paging的此属性设置为true。默认为否
+		hideNvueBottomTag: {
+			type: Boolean,
+			default: u.gc('hideNvueBottomTag', false)
+		},
+		//nvue中控制onscroll事件触发的频率:表示两次onscroll事件之间列表至少滚动了10px。注意,将该值设置为较小的数值会提高滚动事件采样的精度,但同时也会降低页面的性能
+		offsetAccuracy: {
+			type: Number,
+			default: u.gc('offsetAccuracy', 10)
+		},
+		// #endif
+	},
+	data() {
+		return {
+			nRefresherLoading: false,
+			nListIsDragging: false,
+			nShowBottom: true,
+			nFixFreezing: false,
+			nShowRefresherReveal: false,
+			nIsFirstPageAndNoMore: false,
+			nFirstPageAndNoMoreChecked: false,
+			nLoadingMoreFixedHeight: false,
+			nShowRefresherRevealHeight: 0,
+			nOldShowRefresherRevealHeight: -1,
+			nRefresherWidth: uni.upx2px(750),
+		}
+	},
+	watch: {
+		// #ifdef APP-NVUE
+		nIsFirstPageAndNoMore: {
+			handler(newVal) {
+				const cellStyle = !this.useChatRecordMode || newVal ? {} : { transform: 'rotate(180deg)' };
+				this.$emit('update:cellStyle', cellStyle);
+				this.$emit('cellStyleChange', cellStyle);
+			},
+			immediate: true
+		},
+		// #endif
+	},
+	computed: {
+		// #ifdef APP-NVUE
+		nScopedSlots() {
+			// #ifdef VUE2
+			return this.$scopedSlots;
+			// #endif
+			// #ifdef VUE3
+			return null;
+			// #endif
+		},
+		nWaterfallColumnCount() {
+			if (this.finalNvueListIs !== 'waterfall') return 0;
+			return this._nGetWaterfallConfig('column-count', 2);
+		},
+		nWaterfallColumnWidth() {
+			return this._nGetWaterfallConfig('column-width', 'auto');
+		},
+		nWaterfallColumnGap() {
+			return this._nGetWaterfallConfig('column-gap', 'normal');
+		},
+		nWaterfallLeftGap() {
+			return this._nGetWaterfallConfig('left-gap', 0);
+		},
+		nWaterfallRightGap() {
+			return this._nGetWaterfallConfig('right-gap', 0);
+		},
+		nViewIs() {
+			const is = this.finalNvueListIs;
+			return is === 'scroller' || is === 'view' ? 'view' : is === 'waterfall' ? 'header' : 'cell';
+		},
+		nSafeAreaBottomHeight() {
+			return this.safeAreaInsetBottom ? this.safeAreaBottom : 0;
+		},
+		nChatRecordRotateStyle() {
+			return this.useChatRecordMode ? { transform: this.nIsFirstPageAndNoMore ? 'rotate(0deg)' : 'rotate(180deg)' } : {};
+		},
+		finalNvueListIs() {
+			if (this.usePageScroll) return 'view';
+			const nvueListIsLowerCase = this.nvueListIs.toLowerCase();
+			if (['list','waterfall','scroller'].indexOf(nvueListIsLowerCase) !== -1) return nvueListIsLowerCase;
+			return 'list';
+		},
+		finalNvueSuperListIs() {
+			return this.usePageScroll ? 'view' : 'scroller';
+		},
+		finalNvueRefresherEnabled() {
+			return this.finalNvueListIs !== 'view' && this.finalRefresherEnabled && !this.nShowRefresherReveal && !this.useChatRecordMode;
+		},
+		// #endif
+	},
+	mounted(){
+		// #ifdef APP-NVUE
+		//旋转屏幕时更新宽度
+		uni.onWindowResize((res) => {
+			// this._nUpdateRefresherWidth();
+		})
+		// #endif
+	},
+	methods: {
+		// #ifdef APP-NVUE
+		//列表滚动时触发
+		_nOnScroll(e) {
+			this.$emit('scroll', e);
+			const contentOffsetY = -e.contentOffset.y;
+			this.oldScrollTop = contentOffsetY;
+			this.nListIsDragging = e.isDragging;
+			this._checkShouldShowBackToTop(contentOffsetY, contentOffsetY - 1);
+		},
+		//下拉刷新刷新中
+		_nOnRrefresh() {
+			if (this.nShowRefresherReveal) return;
+			this.nRefresherLoading = true;
+			this.refresherStatus = Enum.Refresher.Loading;
+			this._doRefresherLoad();
+		},
+		//下拉刷新下拉中
+		_nOnPullingdown(e) {
+			if (this.refresherStatus === Enum.Refresher.Loading || (this.isIos && !this.nListIsDragging)) return;
+			this._emitTouchmove(e);
+			const { viewHeight, pullingDistance } = e;
+			this.refresherStatus = pullingDistance >= viewHeight ? Enum.Refresher.ReleaseToRefresh : Enum.Refresher.Default;
+		},
+		//下拉刷新结束
+		_nRefresherEnd(doEnd = true) {
+			if (doEnd) {
+			   this._nDoRefresherEndAnimation(0, -this.nShowRefresherRevealHeight); 
+			   !this.usePageScroll && this.$refs['zp-n-list'].resetLoadmore();
+			   this.nRefresherLoading = false;
+			}
+		},
+		//执行主动触发下拉刷新动画
+		_nDoRefresherEndAnimation(height, translateY, animate = true, checkStack = true) {
+			this._cleanRefresherCompleteTimeout();
+			this._cleanRefresherEndTimeout();
+			
+			if (!this.finalShowRefresherWhenReload) {
+				this.refresherEndTimeout = u.delay(() => {
+					this.refresherStatus = Enum.Refresher.Default;
+				}, this.refresherCompleteDuration);
+				return;
+			}
+			const stackCount = this.refresherRevealStackCount;
+			if (height === 0 && checkStack) {
+				this.refresherRevealStackCount --;
+				if (stackCount > 1) return;
+				this.refresherEndTimeout = u.delay(() => {
+					this.refresherStatus = Enum.Refresher.Default;
+				}, this.refresherCompleteDuration);
+			}
+			if (stackCount > 1) {
+				this.refresherStatus = Enum.Refresher.Loading;
+			}
+			
+			const duration = animate ? 200 : 0;
+			if (this.nOldShowRefresherRevealHeight !== height) {
+				if (height > 0) {
+					this.nShowRefresherReveal = true;
+				}
+				weexAnimation.transition(this.$refs['zp-n-list-refresher-reveal'], {
+					styles: {
+						height: `${height}px`,
+						transform: `translateY(${translateY}px)`,
+					},
+					duration,
+					timingFunction: 'linear',
+					needLayout: true,
+					delay: 0
+				})
+			}
+			u.delay(() => {
+				if (animate) {
+					this.nShowRefresherReveal = height > 0;
+				}
+			}, duration > 0 ? duration - 60 : 0);
+			this.nOldShowRefresherRevealHeight = height;
+		},
+		//滚动到底部加载更多
+		_nOnLoadmore() {
+			if (this.nShowRefresherReveal || !this.totalData.length) return;
+			this.useChatRecordMode ? this.doChatRecordLoadMore() : this._onLoadingMore('toBottom');
+		},
+		//获取nvue waterfall单项配置
+		_nGetWaterfallConfig(key, defaultValue) {
+			return this.nvueWaterfallConfig[key] || defaultValue;
+		},
+		//更新nvue 下拉刷新view容器的宽度
+		_nUpdateRefresherWidth() {
+			u.delay(() => {
+				this.$nextTick(()=>{
+					this._getNodeClientRect('.zp-n-list').then(node => {
+						if (node) {
+							this.nRefresherWidth = node[0].width || this.nRefresherWidth;
+						}
+					})
+				})
+			})	
+		}
+		// #endif
+	}
+}
diff --git a/uni_modules/z-paging/components/z-paging/js/modules/refresher.js b/uni_modules/z-paging/components/z-paging/js/modules/refresher.js
new file mode 100644
index 0000000..a349ca9
--- /dev/null
+++ b/uni_modules/z-paging/components/z-paging/js/modules/refresher.js
@@ -0,0 +1,689 @@
+// [z-paging]下拉刷新view模块
+import u from '.././z-paging-utils'
+import c from '.././z-paging-constant'
+import Enum from '.././z-paging-enum'
+
+export default {
+	props: {
+		//下拉刷新的主题样式,支持black,white,默认black
+		refresherThemeStyle: {
+			type: String,
+			default: u.gc('refresherThemeStyle', '')
+		},
+		//自定义下拉刷新中左侧图标的样式
+		refresherImgStyle: {
+			type: Object,
+			default: function() {
+				return u.gc('refresherImgStyle', {});
+			}
+		},
+		//自定义下拉刷新中右侧状态描述文字的样式
+		refresherTitleStyle: {
+			type: Object,
+			default: function() {
+				return u.gc('refresherTitleStyle', {});
+			}
+		},
+		//自定义下拉刷新中右侧最后更新时间文字的样式(show-refresher-update-time为true时有效)
+		refresherUpdateTimeStyle: {
+			type: Object,
+			default: function() {
+				return u.gc('refresherUpdateTimeStyle', {});
+			}
+		},
+		//在微信小程序和QQ小程序中,是否实时监听下拉刷新中进度,默认为否
+		watchRefresherTouchmove: {
+			type: Boolean,
+			default: u.gc('watchRefresherTouchmove', false)
+		},
+		//底部加载更多的主题样式,支持black,white,默认black
+		loadingMoreThemeStyle: {
+			type: String,
+			default: u.gc('loadingMoreThemeStyle', '')
+		},
+		//是否只使用下拉刷新,设置为true后将关闭mounted自动请求数据、关闭滚动到底部加载更多,强制隐藏空数据图。默认为否
+		refresherOnly: {
+			type: Boolean,
+			default: u.gc('refresherOnly', false)
+		},
+		//自定义下拉刷新默认状态下回弹动画时间,单位为毫秒,默认为100毫秒,nvue无效
+		refresherDefaultDuration: {
+			type: [Number, String],
+			default: u.gc('refresherDefaultDuration', 100)
+		},
+		//自定义下拉刷新结束以后延迟回弹的时间,单位为毫秒,默认为0
+		refresherCompleteDelay: {
+			type: [Number, String],
+			default: u.gc('refresherCompleteDelay', 0)
+		},
+		//自定义下拉刷新结束回弹动画时间,单位为毫秒,默认为300毫秒(refresherEndBounceEnabled为false时,refresherCompleteDuration为设定值的1/3),nvue无效
+		refresherCompleteDuration: {
+			type: [Number, String],
+			default: u.gc('refresherCompleteDuration', 300)
+		},
+		//自定义下拉刷新结束状态下是否允许列表滚动,默认为否
+		refresherCompleteScrollable: {
+			type: Boolean,
+			default: u.gc('refresherCompleteScrollable', false)
+		},
+		//是否使用自定义的下拉刷新,默认为是,即使用z-paging的下拉刷新。设置为false即代表使用uni scroll-view自带的下拉刷新,h5、App、微信小程序以外的平台不支持uni scroll-view自带的下拉刷新
+		useCustomRefresher: {
+			type: Boolean,
+			default: u.gc('useCustomRefresher', true)
+		},
+		//自定义下拉刷新下拉帧率,默认为40,过高可能会出现抖动问题
+		refresherFps: {
+			type: [Number, String],
+			default: u.gc('refresherFps', 40)
+		},
+		//自定义下拉刷新允许触发的最大下拉角度,默认为40度,当下拉角度小于设定值时,自定义下拉刷新动画不会被触发
+		refresherMaxAngle: {
+			type: [Number, String],
+			default: u.gc('refresherMaxAngle', 40)
+		},
+		//自定义下拉刷新的角度由未达到最大角度变到达到最大角度时,是否继续下拉刷新手势,默认为否
+		refresherAngleEnableChangeContinued: {
+			type: Boolean,
+			default: u.gc('refresherAngleEnableChangeContinued', false)
+		},
+		//自定义下拉刷新默认状态下的文字
+		refresherDefaultText: {
+			type: [String, Object],
+			default: u.gc('refresherDefaultText', null)
+		},
+		//自定义下拉刷新松手立即刷新状态下的文字
+		refresherPullingText: {
+			type: [String, Object],
+			default: u.gc('refresherPullingText', null)
+		},
+		//自定义下拉刷新刷新中状态下的文字
+		refresherRefreshingText: {
+			type: [String, Object],
+			default: u.gc('refresherRefreshingText', null)
+		},
+		//自定义下拉刷新刷新结束状态下的文字
+		refresherCompleteText: {
+			type: [String, Object],
+			default: u.gc('refresherCompleteText', null)
+		},
+		//自定义下拉刷新默认状态下的图片
+		refresherDefaultImg: {
+			type: String,
+			default: u.gc('refresherDefaultImg', null)
+		},
+		//自定义下拉刷新松手立即刷新状态下的图片,默认与refresherDefaultImg一致
+		refresherPullingImg: {
+			type: String,
+			default: u.gc('refresherPullingImg', null)
+		},
+		//自定义下拉刷新刷新中状态下的图片
+		refresherRefreshingImg: {
+			type: String,
+			default: u.gc('refresherRefreshingImg', null)
+		},
+		//自定义下拉刷新刷新结束状态下的图片
+		refresherCompleteImg: {
+			type: String,
+			default: u.gc('refresherCompleteImg', null)
+		},
+		//自定义下拉刷新刷新中状态下是否展示旋转动画
+		refresherRefreshingAnimated: {
+			type: Boolean,
+			default: u.gc('refresherRefreshingAnimated', true)
+		},
+		//是否开启自定义下拉刷新刷新结束回弹效果,默认为是
+		refresherEndBounceEnabled: {
+			type: Boolean,
+			default: u.gc('refresherEndBounceEnabled', true)
+		},
+		//是否开启自定义下拉刷新,默认为是
+		refresherEnabled: {
+			type: Boolean,
+			default: u.gc('refresherEnabled', true)
+		},
+		//设置自定义下拉刷新阈值,默认为80rpx
+		refresherThreshold: {
+			type: [Number, String],
+			default: u.gc('refresherThreshold', '80rpx')
+		},
+		//设置系统下拉刷新默认样式,支持设置 black,white,none,none 表示不使用默认样式,默认为black
+		refresherDefaultStyle: {
+			type: String,
+			default: u.gc('refresherDefaultStyle', 'black')
+		},
+		//设置自定义下拉刷新区域背景
+		refresherBackground: {
+			type: String,
+			default: u.gc('refresherBackground', 'transparent')
+		},
+		//设置固定的自定义下拉刷新区域背景
+		refresherFixedBackground: {
+			type: String,
+			default: u.gc('refresherFixedBackground', 'transparent')
+		},
+		//设置固定的自定义下拉刷新区域高度,默认为0
+		refresherFixedBacHeight: {
+			type: [Number, String],
+			default: u.gc('refresherFixedBacHeight', 0)
+		},
+		//设置自定义下拉刷新下拉超出阈值后继续下拉位移衰减的比例,范围0-1,值越大代表衰减越多。默认为0.65(nvue无效)
+		refresherOutRate: {
+			type: Number,
+			default: u.gc('refresherOutRate', 0.65)
+		},
+		//设置自定义下拉刷新下拉时实际下拉位移与用户下拉距离的比值,默认为0.75,即代表若用户下拉10px,则实际位移为7.5px(nvue无效)
+		refresherPullRate: {
+			type: Number,
+			default: u.gc('refresherPullRate', 0.75)
+		},
+		//是否显示最后更新时间,默认为否
+		showRefresherUpdateTime: {
+			type: Boolean,
+			default: u.gc('showRefresherUpdateTime', false)
+		},
+		//如果需要区别不同页面的最后更新时间,请为不同页面的z-paging的`refresher-update-time-key`设置不同的字符串
+		refresherUpdateTimeKey: {
+			type: String,
+			default: u.gc('refresherUpdateTimeKey', 'default')
+		},
+		//下拉刷新时下拉到“松手立即刷新”状态时是否使手机短振动,默认为否(h5无效)
+		refresherVibrate: {
+			type: Boolean,
+			default: u.gc('refresherVibrate', false)
+		},
+		//下拉刷新时是否禁止下拉刷新view跟随用户触摸竖直移动,默认为否。注意此属性只是禁止下拉刷新view移动,其他下拉刷新逻辑依然会正常触发
+		refresherNoTransform: {
+			type: Boolean,
+			default: u.gc('refresherNoTransform', false)
+		},
+		//是否开启下拉刷新状态栏占位,适用于隐藏导航栏时,下拉刷新需要避开状态栏高度的情况,默认为否
+		useRefresherStatusBarPlaceholder: {
+			type: Boolean,
+			default: u.gc('useRefresherStatusBarPlaceholder', false)
+		},
+	},
+	data() {
+		return {
+			R: Enum.Refresher,
+			//下拉刷新状态
+			refresherStatus: Enum.Refresher.Default,
+			refresherTouchstartY: 0,
+			lastRefresherTouchmove: null,
+			refresherReachMaxAngle: true,
+			refresherTransform: 'translateY(0px)',
+			refresherTransition: '',
+			finalRefresherDefaultStyle: 'black',
+			refresherRevealStackCount: 0,
+			refresherCompleteTimeout: null,
+			refresherCompleteSubTimeout: null,
+			refresherEndTimeout: null,
+			isTouchmovingTimeout: null,
+			refresherTriggered: false,
+			isTouchmoving: false,
+			isTouchEnded: false,
+			isUserPullDown: false,
+			privateRefresherEnabled: -1,
+			privateShowRefresherWhenReload: false,
+			customRefresherHeight: -1,
+			showCustomRefresher: false,
+			doRefreshAnimateAfter: false,
+			isRefresherInComplete: false,
+			pullDownTimeStamp: 0,
+			moveDis: 0,
+			oldMoveDis: 0,
+			currentDis: 0,
+			oldCurrentMoveDis: 0,
+			oldRefresherTouchmoveY: 0,
+			oldTouchDirection: '',
+			oldEmitedTouchDirection: '',
+			oldPullingDistance: -1,
+			refresherThresholdUpdateTag: 0
+		}
+	},
+	watch: {
+		refresherDefaultStyle: {
+			handler(newVal) {
+				if (newVal.length) {
+					this.finalRefresherDefaultStyle = newVal;
+				}
+			},
+			immediate: true
+		},
+		refresherStatus(newVal) {
+			newVal === Enum.Refresher.Loading && this._cleanRefresherEndTimeout();
+			this.refresherVibrate && newVal === Enum.Refresher.ReleaseToRefresh && this._doVibrateShort();
+			this.$emit('refresherStatusChange', newVal);
+			this.$emit('update:refresherStatus', newVal);
+		},
+		refresherEnabled(newVal) {
+			!newVal && this.endRefresh();
+		}
+	},
+	computed: {
+		pullDownDisTimeStamp() {
+			return 1000 / this.refresherFps;
+		},
+		finalRefresherEnabled() {
+			if (this.useChatRecordMode) return false;
+			if (this.privateRefresherEnabled === -1) return this.refresherEnabled;
+			return this.privateRefresherEnabled === 1;
+		},
+		finalRefresherThreshold() {
+			let refresherThreshold = this.refresherThreshold;
+			let idDefault = false;
+			if (refresherThreshold === '80rpx') {
+				idDefault = true;
+				if (this.showRefresherUpdateTime) {
+					refresherThreshold = '120rpx';
+				}
+			}
+			if (idDefault && this.customRefresherHeight > 0) return this.customRefresherHeight + this.finalRefresherThresholdPlaceholder;
+			return u.convertToPx(refresherThreshold) + this.finalRefresherThresholdPlaceholder;
+		},
+		finalRefresherThresholdPlaceholder() {
+			return this.useRefresherStatusBarPlaceholder ? this.statusBarHeight : 0;
+		},
+		finalRefresherFixedBacHeight() {
+			return u.convertToPx(this.refresherFixedBacHeight);
+		},
+		finalRefresherThemeStyle() {
+			return this.refresherThemeStyle.length ? this.refresherThemeStyle : this.defaultThemeStyle;
+		},
+		finalRefresherOutRate() {
+			let rate = this.refresherOutRate;
+			rate = Math.max(0,rate);
+			rate = Math.min(1,rate);
+			return rate;
+		},
+		finalRefresherPullRate() {
+			let rate = this.refresherPullRate;
+			rate = Math.max(0,rate);
+			return rate;
+		},
+		finalRefresherTransform() {
+			if (this.refresherNoTransform || this.refresherTransform === 'translateY(0px)') return 'none';
+			return this.refresherTransform;
+		},
+		finalShowRefresherWhenReload() {
+			return this.showRefresherWhenReload || this.privateShowRefresherWhenReload;
+		},
+		finalRefresherTriggered() {
+			if (!(this.finalRefresherEnabled && !this.useCustomRefresher)) return false;
+			return this.refresherTriggered;
+		},
+		showRefresher() {
+			const showRefresher = this.finalRefresherEnabled && this.useCustomRefresher;
+			// #ifndef APP-NVUE
+			this.customRefresherHeight === -1 && showRefresher && this.updateCustomRefresherHeight();
+			// #endif
+			return showRefresher;
+		},
+		hasTouchmove(){
+			// #ifdef VUE2
+			// #ifdef APP-VUE || H5
+			if (this.$listeners && !this.$listeners.refresherTouchmove) return false;
+			// #endif
+			// #ifdef MP-WEIXIN || MP-QQ
+			return this.watchRefresherTouchmove;
+			// #endif
+			return true;
+			// #endif
+			return this.watchRefresherTouchmove;
+		},
+	},
+	methods: {
+		//终止下拉刷新状态
+		endRefresh() {
+			this.totalData = this.realTotalData;
+			this._refresherEnd();
+			this._endSystemLoadingAndRefresh();
+			this._handleScrollViewDisableBounce({ bounce: true });
+			this.$nextTick(() => {
+				this.refresherTriggered = false;
+			})
+		},
+		handleRefresherStatusChanged(func) {
+			this.refresherStatusChangedFunc = func;
+		},
+		//手动更新自定义下拉刷新view高度
+		updateCustomRefresherHeight() {
+			u.delay(() => this.$nextTick(this._updateCustomRefresherHeight));
+		},
+		//自定义下拉刷新被触发
+		_onRefresh(fromScrollView = false,isUserPullDown = true) {
+			if (fromScrollView && !(this.finalRefresherEnabled && !this.useCustomRefresher)) return;
+			this.$emit('onRefresh');
+			this.$emit('Refresh');
+			// #ifdef APP-NVUE
+			if (this.loading) {
+				u.delay(this._nRefresherEnd, 500)
+				return;
+			}
+			// #endif
+			if (this.loading || this.isRefresherInComplete) return;
+			this.loadingType = Enum.LoadingType.Refresher;
+			if (this.nShowRefresherReveal) return;
+			this.isUserPullDown = isUserPullDown;
+			this.isUserReload = !isUserPullDown;
+			this._startLoading(true);
+			this.refresherTriggered = true;
+			if(this.reloadWhenRefresh && isUserPullDown){
+				this.useChatRecordMode ? this._onLoadingMore('click') : this._reload(false, false, isUserPullDown);
+			}
+		},
+		//自定义下拉刷新被复位
+		_onRestore() {
+			this.refresherTriggered = 'restore';
+			this.$emit('onRestore');
+			this.$emit('Restore');
+		},
+		// #ifndef APP-VUE || MP-WEIXIN || MP-QQ || H5
+		//拖拽开始
+		_refresherTouchstart(e) {
+			this._handleListTouchstart();
+			if (this._touchDisabled()) return;
+			this._handleRefresherTouchstart(u.getTouch(e));
+		},
+		// #endif
+		//进一步处理拖拽开始结果
+		_handleRefresherTouchstart(touch) {
+			if (!this.loading && this.isTouchEnded) {
+				this.isTouchmoving = false;
+			}
+			this.loadingType = Enum.LoadingType.Refresher;
+			this.isTouchmovingTimeout && clearTimeout(this.isTouchmovingTimeout);
+			this.isTouchEnded = false;
+			this.refresherTransition = '';
+			this.refresherTouchstartY = touch.touchY;
+			this.$emit('refresherTouchstart', this.refresherTouchstartY);
+			this.lastRefresherTouchmove = touch;
+			this._cleanRefresherCompleteTimeout();
+			this._cleanRefresherEndTimeout();
+		},
+		// #ifndef APP-VUE || MP-WEIXIN || MP-QQ || H5
+		//拖拽中
+		_refresherTouchmove(e) {
+			const currentTimeStamp = u.getTime();
+			let touch = null;
+			let refresherTouchmoveY = 0;
+			if (this.watchTouchDirectionChange) {
+				touch = u.getTouch(e);
+				refresherTouchmoveY = touch.touchY;
+				const direction  = refresherTouchmoveY > this.oldRefresherTouchmoveY ? 'top' : 'bottom';
+				if (direction === this.oldTouchDirection && direction !== this.oldEmitedTouchDirection) {
+					this._handleTouchDirectionChange({ direction });
+					this.oldEmitedTouchDirection = direction;
+				}
+				this.oldTouchDirection = direction;
+				this.oldRefresherTouchmoveY = refresherTouchmoveY;
+			}
+			if (this.pullDownTimeStamp && currentTimeStamp - this.pullDownTimeStamp <= this.pullDownDisTimeStamp) return;
+			if (this._touchDisabled()) return;
+			this.pullDownTimeStamp = Number(currentTimeStamp);
+			touch = u.getTouch(e);
+			refresherTouchmoveY = touch.touchY;
+			let moveDis = refresherTouchmoveY - this.refresherTouchstartY;
+			if (moveDis < 0) return;
+			if (this.refresherMaxAngle >= 0 && this.refresherMaxAngle <= 90 && this.lastRefresherTouchmove && this.lastRefresherTouchmove.touchY <= refresherTouchmoveY) {
+				if (!moveDis && !this.refresherAngleEnableChangeContinued && this.moveDis < 1 && !this.refresherReachMaxAngle) return;
+				const x = Math.abs(touch.touchX - this.lastRefresherTouchmove.touchX);
+				const y = Math.abs(refresherTouchmoveY - this.lastRefresherTouchmove.touchY);
+				const z = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
+				if ((x || y) && x > 1) {
+					const angle = Math.asin(y / z) / Math.PI * 180;
+					if (angle < this.refresherMaxAngle) {
+						this.lastRefresherTouchmove = touch;
+						this.refresherReachMaxAngle = false;
+						return;
+					}
+				}
+			}
+			moveDis = this._getFinalRefresherMoveDis(moveDis);
+			this._handleRefresherTouchmove(moveDis, touch);
+			if (!this.disabledBounce) {
+				if(this.isIos){
+					// #ifndef MP-LARK
+					this._handleScrollViewDisableBounce({ bounce: false });
+					// #endif
+				}
+				this.disabledBounce = true;
+			}
+			this._emitTouchmove({ pullingDistance: moveDis, dy: this.moveDis - this.oldMoveDis });
+		},
+		// #endif
+		//进一步处理拖拽中结果
+		_handleRefresherTouchmove(moveDis, touch) {
+			this.refresherReachMaxAngle = true;
+			this.isTouchmovingTimeout && clearTimeout(this.isTouchmovingTimeout);
+			this.isTouchmoving = true;
+			this.isTouchEnded = false;
+			this.refresherStatus = moveDis >= this.finalRefresherThreshold ? Enum.Refresher.ReleaseToRefresh : this.refresherStatus = Enum.Refresher.Default;
+			// #ifndef APP-VUE || MP-WEIXIN || MP-QQ  || H5
+			// this.scrollEnable = false;
+			this.refresherTransform = `translateY(${moveDis}px)`;
+			this.lastRefresherTouchmove = touch;
+			// #endif
+			this.moveDis = moveDis;
+		},
+		// #ifndef APP-VUE || MP-WEIXIN || MP-QQ || H5
+		//拖拽结束
+		_refresherTouchend(e) {
+			if (this._touchDisabled() || !this.isTouchmoving) return;
+			const touch = u.getTouch(e);
+			let refresherTouchendY = touch.touchY;
+			let moveDis = refresherTouchendY - this.refresherTouchstartY;
+			moveDis = this._getFinalRefresherMoveDis(moveDis);
+			this._handleRefresherTouchend(moveDis);
+			this._handleScrollViewDisableBounce({bounce: true});
+			this.disabledBounce = false;
+		},
+		// #endif
+		//进一步处理拖拽结束结果
+		_handleRefresherTouchend(moveDis) {
+			// #ifndef APP-PLUS || H5 || MP-WEIXIN
+			if (!this.isTouchmoving) return;
+			// #endif
+			this.isTouchmovingTimeout && clearTimeout(this.isTouchmovingTimeout);
+			this.refresherReachMaxAngle = true;
+			this.isTouchEnded = true;
+			const refresherThreshold = this.finalRefresherThreshold;
+			if (moveDis >= refresherThreshold && this.refresherStatus === Enum.Refresher.ReleaseToRefresh) {
+				// #ifndef APP-VUE || MP-WEIXIN || MP-QQ || H5
+				this.refresherTransform = `translateY(${refresherThreshold}px)`;
+				this.refresherTransition = 'transform .1s linear';
+				// #endif
+				u.delay(() => {
+					this._emitTouchmove({ pullingDistance: refresherThreshold, dy: this.moveDis - refresherThreshold });
+				}, 0.1);
+				this.moveDis = refresherThreshold;
+				this.refresherStatus = Enum.Refresher.Loading;
+				this._doRefresherLoad();
+			} else {
+				this._refresherEnd();
+				this.isTouchmovingTimeout = u.delay(() => {
+					this.isTouchmoving = false;
+				}, this.refresherDefaultDuration);
+			}
+			this.scrollEnable = true;
+			this.$emit('refresherTouchend', moveDis);
+		},
+		//处理列表触摸开始事件
+		_handleListTouchstart() {
+			if (this.useChatRecordMode && this.autoHideKeyboardWhenChat) {
+				uni.hideKeyboard();
+				this.$emit('hidedKeyboard');
+			}
+		},
+		//处理scroll-view bounce是否生效
+		_handleScrollViewDisableBounce({ bounce }) {
+			if (!this.usePageScroll && !this.scrollToTopBounceEnabled && this.wxsScrollTop <= 5) {
+				// #ifdef APP-VUE || MP-WEIXIN || MP-QQ || H5
+				this.refresherTransition = '';
+				// #endif
+				this.scrollEnable = bounce;
+			}
+		},
+		//wxs正在下拉状态改变处理
+		_handleWxsPullingDownStatusChange(onPullingDown) {
+			this.wxsOnPullingDown = onPullingDown;
+			if (onPullingDown && !this.useChatRecordMode) {
+				this.renderPropScrollTop = 0;
+			}
+		},
+		//wxs正在下拉处理
+		_handleWxsPullingDown({ moveDis, diffDis }){
+			this._emitTouchmove({ pullingDistance: moveDis,dy: diffDis });
+		},
+		//wxs触摸方向改变
+		_handleTouchDirectionChange({ direction }) {
+			this.$emit('touchDirectionChange',direction);
+		},
+		//wxs通知更新其props
+		_handlePropUpdate(){
+			this.wxsPropType = u.getTime().toString();
+		},
+		//下拉刷新结束
+		_refresherEnd(shouldEndLoadingDelay = true, fromAddData = false, isUserPullDown = false, setLoading = true) {
+			if (this.loadingType === Enum.LoadingType.Refresher) {
+				const refresherCompleteDelay = (fromAddData && (isUserPullDown || this.showRefresherWhenReload)) ? this.refresherCompleteDelay : 0;
+				const refresherStatus = refresherCompleteDelay > 0 ? Enum.Refresher.Complete : Enum.Refresher.Default;
+				if (this.finalShowRefresherWhenReload) {
+					const stackCount = this.refresherRevealStackCount;
+					this.refresherRevealStackCount --;
+					if (stackCount > 1) return;
+				}
+				this._cleanRefresherEndTimeout();
+				this.refresherEndTimeout = u.delay(() => {
+					this.refresherStatus = refresherStatus;
+				}, this.refresherStatus !== Enum.Refresher.Default && refresherStatus === Enum.Refresher.Default ? this.refresherCompleteDuration : 0);
+				
+				// #ifndef APP-NVUE
+				if (refresherCompleteDelay > 0) {
+					this.isRefresherInComplete = true;
+				}
+				// #endif
+				this._cleanRefresherCompleteTimeout();
+				this.refresherCompleteTimeout = u.delay(() => {
+					let animateDuration = 1;
+					const animateType = this.refresherEndBounceEnabled && fromAddData ? 'cubic-bezier(0.19,1.64,0.42,0.72)' : 'linear';
+					if (fromAddData) {
+						animateDuration = this.refresherEndBounceEnabled ? this.refresherCompleteDuration / 1000 : this.refresherCompleteDuration / 3000;
+					}
+					this.refresherTransition = `transform ${fromAddData ? animateDuration : this.refresherDefaultDuration / 1000}s ${animateType}`;
+					// #ifndef APP-VUE || MP-WEIXIN || MP-QQ  || H5
+					this.refresherTransform = 'translateY(0px)';
+					this.currentDis = 0;
+					// #endif
+					// #ifdef APP-VUE || MP-WEIXIN || MP-QQ || H5
+					this.wxsPropType = this.refresherTransition + 'end' + u.getTime();
+					// #endif
+					// #ifdef APP-NVUE
+					this._nRefresherEnd();
+					// #endif
+					this.moveDis = 0;
+					// #ifndef APP-NVUE
+					if (refresherStatus === Enum.Refresher.Complete) {
+						if (this.refresherCompleteSubTimeout) {
+							clearTimeout(this.refresherCompleteSubTimeout);
+							this.refresherCompleteSubTimeout = null;
+						}
+						this.refresherCompleteSubTimeout = u.delay(() => {
+							this.$nextTick(() => {
+								this.refresherStatus = Enum.Refresher.Default;
+								this.isRefresherInComplete = false;
+							})
+						}, animateDuration * 800);
+					}
+					// #endif
+					this._emitTouchmove({ pullingDistance: 0, dy: this.moveDis });
+				}, refresherCompleteDelay);
+			}
+			if (setLoading) {
+				u.delay(() => this.loading = false, shouldEndLoadingDelay ? c.delayTime : 0);
+				isUserPullDown && this._onRestore();
+			}
+		},
+		//模拟用户手动触发下拉刷新
+		_doRefresherRefreshAnimate() {
+			this._cleanRefresherCompleteTimeout();
+			// #ifndef APP-NVUE
+			const doRefreshAnimateAfter = !this.doRefreshAnimateAfter && (this.finalShowRefresherWhenReload) && this
+				.customRefresherHeight === -1 && this.refresherThreshold === '80rpx';
+			if (doRefreshAnimateAfter) {
+				this.doRefreshAnimateAfter = true;
+				return;
+			}
+			// #endif
+			this.refresherRevealStackCount ++;
+			// #ifndef APP-VUE || MP-WEIXIN || MP-QQ  || H5
+			this.refresherTransform = `translateY(${this.finalRefresherThreshold}px)`;
+			// #endif
+			// #ifdef APP-VUE || MP-WEIXIN || MP-QQ || H5
+			this.wxsPropType = 'begin' + u.getTime();
+			// #endif
+			this.moveDis = this.finalRefresherThreshold;
+			this.refresherStatus = Enum.Refresher.Loading;
+			this.isTouchmoving = true;
+			this.isTouchmovingTimeout && clearTimeout(this.isTouchmovingTimeout);
+			this._doRefresherLoad(false);
+		},
+		//触发下拉刷新
+		_doRefresherLoad(isUserPullDown = true) {
+			this._onRefresh(false,isUserPullDown);
+			this.loading = true;
+		},
+		// #ifndef APP-VUE || MP-WEIXIN || MP-QQ || H5
+		//获取处理后的moveDis
+		_getFinalRefresherMoveDis(moveDis) {
+			let diffDis = moveDis - this.oldCurrentMoveDis;
+			this.oldCurrentMoveDis = moveDis;
+			if (diffDis > 0) {
+				diffDis = diffDis * this.finalRefresherPullRate;
+				if (this.currentDis > this.finalRefresherThreshold) {
+					diffDis = diffDis * (1 - this.finalRefresherOutRate);
+				}
+			}
+			diffDis = diffDis > 100 ? diffDis / 100 : diffDis;
+			this.currentDis += diffDis;
+			this.currentDis = Math.max(0, this.currentDis);
+			return this.currentDis;
+		},
+		//判断touch手势是否要触发
+		_touchDisabled() {
+			const checkOldScrollTop = this.oldScrollTop > 5;
+			return this.loading || this.isRefresherInComplete || this.useChatRecordMode || !this.refresherEnabled || !this.useCustomRefresher ||(this.usePageScroll && this.useCustomRefresher && this.pageScrollTop > 10) || (!(this.usePageScroll && this.useCustomRefresher) && checkOldScrollTop);
+		},
+		// #endif
+		//更新自定义下拉刷新view高度
+		_updateCustomRefresherHeight() {
+			this._getNodeClientRect('.zp-custom-refresher-slot-view').then((res) => {
+				this.customRefresherHeight = res ? res[0].height : 0;
+				this.showCustomRefresher = this.customRefresherHeight > 0;
+				if (this.doRefreshAnimateAfter) {
+					this.doRefreshAnimateAfter = false;
+					this._doRefresherRefreshAnimate();
+				}
+			});
+		},
+		//发射pullingDown事件
+		_emitTouchmove(e) {
+			// #ifndef APP-NVUE
+			e.viewHeight = this.finalRefresherThreshold;
+			// #endif
+			e.rate = e.viewHeight > 0 ? e.pullingDistance / e.viewHeight : 0;
+			this.hasTouchmove && this.oldPullingDistance !== e.pullingDistance && this.$emit('refresherTouchmove', e);
+			this.oldPullingDistance = e.pullingDistance;
+		},
+		//清除refresherCompleteTimeout
+		_cleanRefresherCompleteTimeout() {
+			this.refresherCompleteTimeout = this._cleanTimeout(this.refresherCompleteTimeout);
+			// #ifdef APP-NVUE
+			this._nRefresherEnd(false);
+			// #endif
+		},
+		//清除refresherEndTimeout
+		_cleanRefresherEndTimeout() {
+			this.refresherEndTimeout = this._cleanTimeout(this.refresherEndTimeout);
+		},
+	}
+}
diff --git a/uni_modules/z-paging/components/z-paging/js/modules/scroller.js b/uni_modules/z-paging/components/z-paging/js/modules/scroller.js
new file mode 100644
index 0000000..39a2fbc
--- /dev/null
+++ b/uni_modules/z-paging/components/z-paging/js/modules/scroller.js
@@ -0,0 +1,464 @@
+// [z-paging]scroll相关模块
+import u from '.././z-paging-utils'
+import Enum from '.././z-paging-enum'
+
+// #ifdef APP-NVUE
+const weexDom = weex.requireModule('dom');
+// #endif
+
+export default {
+	props: {
+		//使用页面滚动,默认为否,当设置为是时则使用页面的滚动而非此组件内部的scroll-view的滚动,使用页面滚动时z-paging无需设置确定的高度且对于长列表展示性能更高,但配置会略微繁琐
+		usePageScroll: {
+			type: Boolean,
+			default: u.gc('usePageScroll', false)
+		},
+		//是否可以滚动,使用内置scroll-view和nvue时有效,默认为是
+		scrollable: {
+			type: Boolean,
+			default: u.gc('scrollable', true)
+		},
+		//控制是否出现滚动条,默认为是
+		showScrollbar: {
+			type: Boolean,
+			default: u.gc('showScrollbar', true)
+		},
+		//是否允许横向滚动,默认为否
+		scrollX: {
+			type: Boolean,
+			default: u.gc('scrollX', false)
+		},
+		//iOS设备上滚动到顶部时是否允许回弹效果,默认为否。关闭回弹效果后可使滚动到顶部与下拉刷新更连贯,但是有吸顶view时滚动到顶部时可能出现抖动。
+		scrollToTopBounceEnabled: {
+			type: Boolean,
+			default: u.gc('scrollToTopBounceEnabled', false)
+		},
+		//iOS设备上滚动到底部时是否允许回弹效果,默认为是。
+		scrollToBottomBounceEnabled: {
+			type: Boolean,
+			default: u.gc('scrollToBottomBounceEnabled', true)
+		},
+		//在设置滚动条位置时使用动画过渡,默认为否
+		scrollWithAnimation: {
+			type: Boolean,
+			default: u.gc('scrollWithAnimation', false)
+		},
+		//值应为某子元素id(id不能以数字开头)。设置哪个方向可滚动,则在哪个方向滚动到该元素
+		scrollIntoView: {
+			type: String,
+			default: u.gc('scrollIntoView', '')
+		},
+	},
+	data() {
+		return {
+			scrollTop: 0,
+			oldScrollTop: 0,
+			scrollViewStyle: {},
+			scrollViewContainerStyle: {},
+			scrollViewInStyle: {},
+			pageScrollTop: -1,
+			scrollEnable: true,
+			privateScrollWithAnimation: -1,
+			cacheScrollNodeHeight: -1
+		}
+	},
+	watch: {
+		oldScrollTop(newVal) {
+			!this.usePageScroll && this._scrollTopChange(newVal,false);
+		},
+		pageScrollTop(newVal) {
+			this.usePageScroll && this._scrollTopChange(newVal,true);
+		},
+		usePageScroll: {
+			handler(newVal) {
+				this.loaded && this.autoHeight && this._setAutoHeight(!newVal);
+				// #ifdef H5
+				if (newVal) {
+					this.$nextTick(() => {
+						const mainScrollRef = this.$refs['zp-scroll-view'].$refs.main;
+						if (mainScrollRef) {
+							mainScrollRef.style = {};
+						}
+					})
+				}
+				// #endif
+			},
+			immediate: true
+		},
+		finalScrollTop(newVal) {
+			if (!this.useChatRecordMode) {
+				this.renderPropScrollTop = newVal < 6 ? 0 : 10;
+			}
+		},
+	},
+	computed: {
+		finalScrollWithAnimation() {
+			if (this.privateScrollWithAnimation !== -1) {
+				const scrollWithAnimation = this.privateScrollWithAnimation === 1;
+				this.privateScrollWithAnimation = -1;
+				return scrollWithAnimation;
+			}
+			return this.scrollWithAnimation;
+		},
+		finalScrollViewStyle() {
+			if (this.superContentZIndex != 1) {
+				this.scrollViewStyle['z-index'] = this.superContentZIndex;
+				this.scrollViewStyle['position'] = 'relative';
+			}
+			return this.scrollViewStyle;
+		},
+		finalScrollTop() {
+			return this.usePageScroll ? this.pageScrollTop : this.oldScrollTop;
+		},
+		finalIsOldWebView() {
+			return this.isOldWebView && !this.usePageScroll;
+		}
+	},
+	methods: {
+		//滚动到顶部,animate为是否展示滚动动画,默认为是
+		scrollToTop(animate, checkReverse = true) {
+			// #ifdef APP-NVUE
+			if (checkReverse && this.useChatRecordMode) {
+				if (!this.nIsFirstPageAndNoMore) {
+					this.scrollToBottom(animate, false);
+					return;
+				}
+			}
+			// #endif
+			this.$nextTick(() => {
+				this._scrollToTop(animate, false);
+				// #ifdef APP-NVUE
+				if (this.nvueFastScroll && animate) {
+					u.delay(() => {
+						this._scrollToTop(false, false);
+					});
+				}
+				// #endif
+			})
+		},
+		//滚动到底部,animate为是否展示滚动动画,默认为是
+		scrollToBottom(animate, checkReverse = true) {
+			// #ifdef APP-NVUE
+			if (checkReverse && this.useChatRecordMode) {
+				if (!this.nIsFirstPageAndNoMore) {
+					this.scrollToTop(animate, false);
+					return;
+				}
+			}
+			// #endif
+			this.$nextTick(() => {
+				this._scrollToBottom(animate);
+				// #ifdef APP-NVUE
+				if (this.nvueFastScroll && animate) {
+					u.delay(() => {
+						this._scrollToBottom(false);
+					});
+				}
+				// #endif
+			})
+		},
+		//滚动到指定view(vue中有效)。sel为需要滚动的view的id值,不包含"#";offset为偏移量,单位为px;animate为是否展示滚动动画,默认为否
+		scrollIntoViewById(sel, offset, animate) {
+			this._scrollIntoView(sel, offset, animate);
+		},
+		//滚动到指定view(vue中有效)。nodeTop为需要滚动的view的top值(通过uni.createSelectorQuery()获取);offset为偏移量,单位为px;animate为是否展示滚动动画,默认为否
+		scrollIntoViewByNodeTop(nodeTop, offset, animate) {
+			this.scrollTop = this.oldScrollTop;
+			this.$nextTick(() => {
+				this._scrollIntoViewByNodeTop(nodeTop, offset, animate);
+			})
+		},
+		//滚动到指定位置(vue中有效)。y为与顶部的距离,单位为px;offset为偏移量,单位为px;animate为是否展示滚动动画,默认为否
+		scrollToY(y, offset, animate) {
+			this.scrollTop = this.oldScrollTop;
+			this.$nextTick(() => {
+				this._scrollToY(y, offset, animate);
+			})
+		},
+		//滚动到指定view(nvue中有效)。index为需要滚动的view的index(第几个);offset为偏移量,单位为px;animate为是否展示滚动动画,默认为否
+		scrollIntoViewByIndex(index, offset, animate) {
+			this._scrollIntoView(index, offset, animate);
+		},
+		//滚动到指定view(nvue中有效)。view为需要滚动的view(通过`this.$refs.xxx`获取),不包含"#";offset为偏移量,单位为px;animate为是否展示滚动动画,默认为否
+		scrollIntoViewByView(view, offset, animate) {
+			this._scrollIntoView(view, offset, animate);
+		},
+		//当使用页面滚动并且自定义下拉刷新时,请在页面的onPageScroll中调用此方法,告知z-paging当前的pageScrollTop,否则会导致在任意位置都可以下拉刷新
+		updatePageScrollTop(value) {
+			this.pageScrollTop = value;
+		},
+		//当使用页面滚动并且设置了slot="top"时,默认初次加载会自动获取其高度,并使内部容器下移,当slot="top"的view高度动态改变时,在其高度需要更新时调用此方法
+		updatePageScrollTopHeight() {
+			this._updatePageScrollTopOrBottomHeight('top');
+		},
+		//当使用页面滚动并且设置了slot="bottom"时,默认初次加载会自动获取其高度,并使内部容器下移,当slot="bottom"的view高度动态改变时,在其高度需要更新时调用此方法
+		updatePageScrollBottomHeight() {
+			this._updatePageScrollTopOrBottomHeight('bottom');
+		},
+		//更新slot="left"和slot="right"宽度,当slot="left"或slot="right"宽度动态改变时调用
+		updateLeftAndRightWidth() {
+			if (!this.finalIsOldWebView) return;
+			this.$nextTick(() => this._updateLeftAndRightWidth(this.scrollViewContainerStyle, 'zp-page'));
+		},
+		//更新z-paging内置scroll-view的scrollTop
+		updateScrollViewScrollTop(scrollTop, animate = true) {
+			this.privateScrollWithAnimation = animate ? 1 : 0;
+			this.scrollTop = this.oldScrollTop;
+			this.$nextTick(() => {
+				this.scrollTop = scrollTop;
+				this.oldScrollTop = this.scrollTop;
+			});
+		},
+		
+		//当滚动到顶部时
+		_onScrollToUpper() {
+			this.$emit('scrolltoupper');
+			this.$emit('scrollTopChange', 0);
+			this.$nextTick(() => {
+				this.oldScrollTop = 0;
+			})
+			this.useChatRecordMode && this.loadingStatus !== Enum.More.NoMore && this._onLoadingMore('click');
+		},
+		//当滚动到底部时
+		_onScrollToLower(e) {
+			(!e.detail || !e.detail.direction || e.detail.direction === 'bottom') && this._onLoadingMore('toBottom')
+		},
+		//滚动到顶部
+		_scrollToTop(animate = true, isPrivate = true) {
+			// #ifdef APP-NVUE
+			const el = this.$refs['zp-n-list-top-tag'];
+			if (this.usePageScroll) {
+				this._getNodeClientRect('zp-page-scroll-top', false).then(node => {
+					const nodeHeight = node ? node[0].height : 0;
+					weexDom.scrollToElement(el, {
+						offset: -nodeHeight,
+						animated: animate
+					});
+				});
+			} else {
+				if (!this.isIos && this.nvueListIs === 'scroller') {
+					this._getNodeClientRect('zp-n-refresh-container', false).then(node => {
+						const nodeHeight = node ? node[0].height : 0;
+						weexDom.scrollToElement(el, {
+							offset: -nodeHeight,
+							animated: animate
+						});
+					});
+				} else {
+					weexDom.scrollToElement(el, {
+						offset: 0,
+						animated: animate
+					});
+				}
+			}
+			return;
+			// #endif
+			if (this.usePageScroll) {
+				this.$nextTick(() => {
+					uni.pageScrollTo({
+						scrollTop: 0,
+						duration: animate ? 100 : 0,
+					});
+				});
+				return;
+			}
+			this.privateScrollWithAnimation = animate ? 1 : 0;
+			this.scrollTop = this.oldScrollTop;
+			this.$nextTick(() => {
+				this.scrollTop = 0;
+				this.oldScrollTop = this.scrollTop;
+			});
+		},
+		//滚动到底部
+		async _scrollToBottom(animate = true) {
+			// #ifdef APP-NVUE
+			const el = this.$refs['zp-n-list-bottom-tag'];
+			if (el) {
+				weexDom.scrollToElement(el, {
+					offset: 0,
+					animated: animate
+				});
+			} else {
+				u.consoleErr('滚动到底部失败,因为您设置了hideNvueBottomTag为true');
+			}
+			return;
+			// #endif
+			if (this.usePageScroll) {
+				this.$nextTick(() => {
+					uni.pageScrollTo({
+						scrollTop: Number.MAX_VALUE,
+						duration: animate ? 100 : 0,
+					});
+				});
+				return;
+			}
+			try {
+				this.privateScrollWithAnimation = animate ? 1 : 0;
+				const pagingContainerNode = await this._getNodeClientRect('.zp-paging-container');
+				const scrollViewNode = await this._getNodeClientRect('.zp-scroll-view');
+				const pagingContainerH = pagingContainerNode ? pagingContainerNode[0].height : 0;
+				const scrollViewH = scrollViewNode ? scrollViewNode[0].height : 0;
+				if (pagingContainerH > scrollViewH) {
+					this.scrollTop = this.oldScrollTop;
+					this.$nextTick(() => {
+						this.scrollTop = pagingContainerH - scrollViewH + this.virtualPlaceholderTopHeight;
+						this.oldScrollTop = this.scrollTop;
+					});
+				}
+			} catch (e) {}
+		},
+		//滚动到指定view
+		_scrollIntoView(sel, offset = 0, animate = false, finishCallback) {
+			try {
+				this.scrollTop = this.oldScrollTop;
+				this.$nextTick(() => {
+					// #ifdef APP-NVUE
+					const refs = this.$parent.$refs;
+					if (!refs) return;
+					const dataType = Object.prototype.toString.call(sel);
+					let el = null;
+					if (dataType === '[object Number]') {
+						const els = refs[`z-paging-${sel}`];
+						el = els ? els[0] : null;
+					} else if (dataType === '[object Array]') {
+						el = sel[0];
+					} else {
+						el = sel;
+					}
+					if (el) {
+						weexDom.scrollToElement(el, {
+							offset: -offset,
+							animated: animate
+						});
+					} else {
+						u.consoleErr('在nvue中滚动到指定位置,cell必须设置 :ref="`z-paging-${index}`"');
+					}
+					return;
+					// #endif
+					this._getNodeClientRect('#' + sel.replace('#', ''), this.$parent).then((node) => {
+						if (node) {
+							let nodeTop = node[0].top;
+							this._scrollIntoViewByNodeTop(nodeTop, offset, animate);
+							finishCallback && finishCallback();
+						}
+					});
+				});
+			} catch (e) {}
+		},
+		//通过nodeTop滚动到指定view
+		_scrollIntoViewByNodeTop(nodeTop, offset = 0, animate = false) {
+			this._scrollToY(nodeTop, offset, animate, true);
+		},
+		//滚动到指定位置
+		_scrollToY(y, offset = 0, animate = false, addScrollTop = false) {
+			this.privateScrollWithAnimation = animate ? 1 : 0;
+			if (this.usePageScroll) {
+				uni.pageScrollTo({
+					scrollTop: y - offset,
+					duration: animate ? 100 : 0
+				});
+			} else {
+				if(addScrollTop){
+				   y += this.oldScrollTop; 
+				}
+				this.scrollTop = y - offset;
+				this.oldScrollTop = this.scrollTop;
+			}
+		},
+		//scroll-view滚动中
+		_scroll(e) {
+			this.$emit('scroll', e);
+			const scrollTop = e.detail.scrollTop;
+			// #ifndef APP-NVUE
+			this.finalUseVirtualList && this._updateVirtualScroll(scrollTop, this.oldScrollTop - scrollTop);
+			// #endif
+			this.oldScrollTop = scrollTop;
+			const scrollDiff = e.detail.scrollHeight - this.oldScrollTop;
+			!this.isIos && this._checkScrolledToBottom(scrollDiff);
+		},
+		//检测scrollView是否要铺满屏幕
+		_doCheckScrollViewShouldFullHeight(totalData) {
+			if (this.autoFullHeight && this.usePageScroll && this.isTotalChangeFromAddData) {
+				// #ifndef APP-NVUE
+				this.$nextTick(() => {
+					this._checkScrollViewShouldFullHeight((scrollViewNode, pagingContainerNode) => {
+						this._preCheckShowNoMoreInside(totalData, scrollViewNode, pagingContainerNode)
+					});
+				})
+				// #endif
+				// #ifdef APP-NVUE
+				this._preCheckShowNoMoreInside(totalData)
+				// #endif
+			} else {
+				this._preCheckShowNoMoreInside(totalData)
+			} 
+		},
+		//检测z-paging是否要全屏覆盖(当使用页面滚动并且不满全屏时,默认z-paging需要铺满全屏,避免数据过少时内部的empty-view无法正确展示)
+		async _checkScrollViewShouldFullHeight(callback) {
+			try {
+				const scrollViewNode = await this._getNodeClientRect('.zp-scroll-view');
+				const pagingContainerNode = await this._getNodeClientRect('.zp-paging-container-content');
+				if (!scrollViewNode || !pagingContainerNode) return;
+				const scrollViewHeight = pagingContainerNode[0].height;
+				const scrollViewTop = scrollViewNode[0].top;
+				if (this.isAddedData && scrollViewHeight + scrollViewTop <= this.windowHeight) {
+					this._setAutoHeight(true, scrollViewNode);
+					callback(scrollViewNode, pagingContainerNode);
+				} else {
+					this._setAutoHeight(false);
+					callback(null, null);
+				}
+			} catch (e) {
+				callback(null, null);
+			}
+		},
+		//scrollTop改变时触发
+		_scrollTopChange(newVal, isPageScrollTop){
+			this.$emit('scrollTopChange', newVal);
+			this.$emit('update:scrollTop', newVal);
+			this._checkShouldShowBackToTop(newVal);
+			const scrollTop = this.isIos ? (newVal > 5 ? 6 : 0) : (newVal > 105 ? 106 : (newVal > 5 ? 6 : 0));
+			if (isPageScrollTop && this.wxsPageScrollTop !== scrollTop) {
+				this.wxsPageScrollTop = scrollTop;
+			} else if (!isPageScrollTop && this.wxsScrollTop !== scrollTop) {
+				this.wxsScrollTop = scrollTop;
+				if (scrollTop > 6) {
+					this.scrollEnable = true;
+				}
+			}
+		},
+		//更新使用页面滚动时slot="top"或"bottom"插入view的高度
+		_updatePageScrollTopOrBottomHeight(type) {
+			// #ifndef APP-NVUE
+			if (!this.usePageScroll) return;
+			// #endif
+			this._doCheckScrollViewShouldFullHeight(this.realTotalData);
+			const node = `.zp-page-${type}`;
+			const marginText = `margin${type.slice(0,1).toUpperCase() + type.slice(1)}`;
+			let safeAreaInsetBottomAdd = this.safeAreaInsetBottom;
+			this.$nextTick(() => {
+				let delayTime = 0;
+				// #ifdef MP-BAIDU || APP-NVUE
+				delayTime = 50;
+				// #endif
+				u.delay(() => {
+					this._getNodeClientRect(node).then((res) => {
+						if (res) {
+							let pageScrollNodeHeight = res[0].height;
+							if (type === 'bottom') {
+								if (safeAreaInsetBottomAdd) {
+									pageScrollNodeHeight += this.safeAreaBottom;
+								}
+							} else {
+								this.cacheTopHeight = pageScrollNodeHeight;
+							}
+							this.$set(this.scrollViewStyle, marginText, `${pageScrollNodeHeight}px`);
+						} else if (safeAreaInsetBottomAdd) {
+							this.$set(this.scrollViewStyle, marginText, `${this.safeAreaBottom}px`);
+						}
+					});
+				}, delayTime)
+			})
+		},
+	}
+}
diff --git a/uni_modules/z-paging/components/z-paging/js/modules/virtual-list.js b/uni_modules/z-paging/components/z-paging/js/modules/virtual-list.js
new file mode 100644
index 0000000..dd55127
--- /dev/null
+++ b/uni_modules/z-paging/components/z-paging/js/modules/virtual-list.js
@@ -0,0 +1,461 @@
+// [z-paging]虚拟列表模块
+import u from '.././z-paging-utils'
+import c from '.././z-paging-constant'
+import Enum from '.././z-paging-enum'
+
+export default {
+	props: {
+		//是否使用虚拟列表,默认为否
+		useVirtualList: {
+			type: Boolean,
+			default: u.gc('useVirtualList', false)
+		},
+		//在使用虚拟列表时,是否使用兼容模式,默认为否
+		useCompatibilityMode: {
+			type: Boolean,
+			default: u.gc('useCompatibilityMode', false)
+		},
+		//使用兼容模式时传递的附加数据
+		extraData: {
+			type: Object,
+			default: function() {
+				return u.gc('extraData', {});
+			}
+		},
+		//是否在z-paging内部循环渲染列表(内置列表),默认为否。若use-virtual-list为true,则此项恒为true
+		useInnerList: {
+			type: Boolean,
+			default: u.gc('useInnerList', false)
+		},
+		//强制关闭inner-list,默认为false,如果为true将强制关闭innerList,适用于开启了虚拟列表后需要强制关闭inner-list的情况
+		forceCloseInnerList: {
+			type: Boolean,
+			default: u.gc('forceCloseInnerList', false)
+		},
+		//内置列表cell的key名称,仅nvue有效,在nvue中开启use-inner-list时必须填此项
+		cellKeyName: {
+			type: String,
+			default: u.gc('cellKeyName', '')
+		},
+		//innerList样式
+		innerListStyle: {
+			type: Object,
+			default: function() {
+				return u.gc('innerListStyle', {});
+			}
+		},
+		//innerCell样式
+		innerCellStyle: {
+			type: Object,
+			default: function() {
+				return u.gc('innerCellStyle', {});
+			}
+		},
+		//预加载的列表可视范围(列表高度)页数,默认为12,即预加载当前页及上下各12页的cell。此数值越大,则虚拟列表中加载的dom越多,内存消耗越大(会维持在一个稳定值),但增加预加载页面数量可缓解快速滚动短暂白屏问题
+		preloadPage: {
+			type: [Number, String],
+			default: u.gc('preloadPage', 12),
+			validator: (value) => {
+				if (value <= 0) u.consoleErr('preload-page必须大于0!');
+				return value > 0;
+			}
+		},
+		//虚拟列表cell高度模式,默认为fixed,也就是每个cell高度完全相同,将以第一个cell高度为准进行计算。可选值【dynamic】,即代表高度是动态非固定的,【dynamic】性能低于【fixed】。
+		cellHeightMode: {
+			type: String,
+			default: u.gc('cellHeightMode', Enum.CellHeightMode.Fixed)
+		},
+		//虚拟列表列数,默认为1。常用于每行有多列的情况,例如每行有2列数据,需要将此值设置为2
+		virtualListCol: {
+			type: [Number, String],
+			default: u.gc('virtualListCol', 1)
+		},
+		//虚拟列表scroll取样帧率,默认为80,过低容易出现白屏问题,过高容易出现卡顿问题
+		virtualScrollFps: {
+			type: [Number, String],
+			default: u.gc('virtualScrollFps', 80)
+		},
+	},
+	data() {
+		return {
+			virtualListKey: u.getInstanceId(),
+			virtualPageHeight: 0,
+			virtualCellHeight: 0,
+			virtualScrollTimeStamp: 0,
+			
+			virtualList: [],
+			virtualPlaceholderTopHeight: 0,
+			virtualPlaceholderBottomHeight: 0,
+			virtualTopRangeIndex: 0,
+			virtualBottomRangeIndex: 0,
+			lastVirtualTopRangeIndex: 0,
+			lastVirtualBottomRangeIndex: 0,
+			virtualItemInsertedCount: 0,
+			
+			virtualHeightCacheList: [],
+			
+			getCellHeightRetryCount: {
+				fixed: 0,
+				dynamic: 0
+			},
+			pagingOrgTop: -1,
+			updateVirtualListFromDataChange: false
+		}
+	},
+	watch: {
+		realTotalData(newVal) {
+			// #ifndef APP-NVUE
+			if (this.finalUseVirtualList) {
+				this.updateVirtualListFromDataChange = true;
+				this.$nextTick(() => {
+					this.getCellHeightRetryCount.fixed = 0;
+					!newVal.length && this._resetDynamicListState(!this.isUserPullDown);
+					newVal.length && this.cellHeightMode === Enum.CellHeightMode.Fixed && this.isFirstPage && this._updateFixedCellHeight();
+					this._updateVirtualScroll(this.oldScrollTop);
+				})
+			}
+			// #endif
+		},
+		virtualList(newVal){
+			this.$emit('update:virtualList', newVal);
+			this.$emit('virtualListChange', newVal);
+		}
+	},
+	computed: {
+		virtualCellIndexKey() {
+			return c.listCellIndexKey;
+		},
+		finalUseVirtualList() {
+			if (this.useVirtualList && this.usePageScroll){
+				u.consoleErr('使用页面滚动时,开启虚拟列表无效!');
+			}
+			return this.useVirtualList && !this.usePageScroll;
+		},
+		finalUseInnerList() {
+			return this.useInnerList || (this.finalUseVirtualList && !this.forceCloseInnerList);
+		},
+		finalCellKeyName() {
+			// #ifdef APP-NVUE
+			if (this.finalUseVirtualList && !this.cellKeyName.length){
+				u.consoleErr('在nvue中开启use-virtual-list必须设置cell-key-name,否则将可能导致列表渲染错误!');
+			}
+			// #endif
+			return this.cellKeyName;
+		},
+		finalVirtualPageHeight(){
+			return this.virtualPageHeight > 0 ? this.virtualPageHeight : this.windowHeight;
+		},
+		virtualRangePageHeight(){
+			return this.finalVirtualPageHeight * this.preloadPage;
+		},
+		virtualScrollDisTimeStamp() {
+			return 1000 / this.virtualScrollFps;
+		},
+	},
+	methods: {
+		//在使用动态高度虚拟列表时,若在列表数组中需要插入某个item,需要调用此方法;item:需要插入的item,index:插入的cell位置,若index为2,则插入的item在原list的index=1之后,index从0开始
+		doInsertVirtualListItem(item, index) {
+			if (this.cellHeightMode !== Enum.CellHeightMode.Dynamic) return;
+			this.virtualItemInsertedCount ++;
+			if (!item || Object.prototype.toString.call(item) !== '[object Object]') {
+				item = { item };
+			}
+			const cellIndexKey = this.virtualCellIndexKey;
+			item[cellIndexKey] = `custom-${this.virtualItemInsertedCount}`;
+			item[c.listCellIndexUniqueKey] = `${this.virtualListKey}-${item[cellIndexKey]}`;
+			this.totalData.splice(index, 0, item);
+			this.$nextTick(async () => {
+				let retryCount = 0;
+				while (retryCount <= 10) {
+					await u.wait(c.delayTime);
+					
+					const cellNode = await this._getNodeClientRect(`#zp-id-${item[cellIndexKey]}`, this.finalUseInnerList);
+					if (!cellNode) {
+						retryCount ++;
+						continue;
+					} 
+					
+					const currentHeight = cellNode ? cellNode[0].height : 0;
+					const lastHeightCache = this.virtualHeightCacheList[index - 1];
+					const lastTotalHeight = lastHeightCache ? lastHeightCache.totalHeight : 0;
+					this.virtualHeightCacheList.splice(index, 0, {
+						height: currentHeight,
+						lastTotalHeight,
+						totalHeight: lastTotalHeight + currentHeight
+					});
+					
+					for (let i = index + 1; i < this.virtualHeightCacheList.length; i++) {
+						const thisNode = this.virtualHeightCacheList[i];
+						thisNode.lastTotalHeight += currentHeight;
+						thisNode.totalHeight += currentHeight;
+					}
+					
+					this._updateVirtualScroll(this.oldScrollTop);
+					break;
+				}
+			})
+		},
+		//在使用动态高度虚拟列表时,手动更新指定cell的缓存高度(当cell高度在初始化之后再次改变时调用);index:需要更新的cell在列表中的位置,从0开始
+		didUpdateVirtualListCell(index) {
+			if (this.cellHeightMode !== Enum.CellHeightMode.Dynamic) return;
+			const currentNode = this.virtualHeightCacheList[index];
+			this.$nextTick(() => {
+				this._getNodeClientRect(`#zp-id-${index}`, this.finalUseInnerList).then(cellNode => {
+					const cellNodeHeight = cellNode ? cellNode[0].height : 0;
+					const heightDis = cellNodeHeight - currentNode.height;
+					currentNode.height = cellNodeHeight;
+					currentNode.totalHeight = currentNode.lastTotalHeight + cellNodeHeight;
+					
+					for (let i = index + 1; i < this.virtualHeightCacheList.length; i++) {
+						const thisNode = this.virtualHeightCacheList[i];
+						thisNode.totalHeight += heightDis;
+						thisNode.lastTotalHeight += heightDis;
+					}
+				});
+			})
+		},
+		//在使用动态高度虚拟列表时,若删除了列表数组中的某个item,需要调用此方法以更新高度缓存数组;index:删除的cell在列表中的位置,从0开始
+		didDeleteVirtualListCell(index) {
+			if (this.cellHeightMode !== Enum.CellHeightMode.Dynamic) return;
+			const currentNode = this.virtualHeightCacheList[index];
+			for (let i = index + 1; i < this.virtualHeightCacheList.length; i++) {
+				const thisNode = this.virtualHeightCacheList[i];
+				thisNode.totalHeight -= currentNode.height;
+				thisNode.lastTotalHeight -= currentNode.height;
+			}
+			this.virtualHeightCacheList.splice(index, 1);
+		},
+		//初始化虚拟列表
+		_virtualListInit() {
+			this.$nextTick(() => {
+				u.delay(() => {
+					this._getNodeClientRect('.zp-scroll-view').then(node => {
+						if (node) {
+							this.pagingOrgTop = node[0].top;
+							this.virtualPageHeight = node[0].height;
+						}
+					});
+				});
+			})
+		},
+		//cellHeightMode为fixed时获取第一个cell高度
+		_updateFixedCellHeight() {
+			this.$nextTick(() => {
+				u.delay(() => {
+					this._getNodeClientRect(`#zp-id-${0}`,this.finalUseInnerList).then(cellNode => {
+						if (!cellNode) {
+							if (this.getCellHeightRetryCount.fixed > 10) return;
+							this.getCellHeightRetryCount.fixed ++;
+							this._updateFixedCellHeight();
+						} else {
+							this.virtualCellHeight = cellNode[0].height;
+							this._updateVirtualScroll(this.oldScrollTop);
+						}
+					});
+				}, c.delayTime, 'updateFixedCellHeightDelay');
+			})
+		},
+		//cellHeightMode为dynamic时获取每个cell高度
+		_updateDynamicCellHeight(list, dataFrom = 'bottom') {
+			const dataFromTop = dataFrom === 'top';
+			const heightCacheList = this.virtualHeightCacheList;
+			const currentCacheList = dataFromTop ?  [] : heightCacheList;
+			let listTotalHeight = 0;
+			this.$nextTick(() => {
+				u.delay(async () => {
+					for (let i = 0; i < list.length; i++) {
+						const cellNode = await this._getNodeClientRect(`#zp-id-${list[i][this.virtualCellIndexKey]}`, this.finalUseInnerList);
+						const currentHeight = cellNode ? cellNode[0].height : 0;
+						if (!cellNode) {
+							if (this.getCellHeightRetryCount.dynamic <= 10) {
+								heightCacheList.splice(heightCacheList.length - i, i);
+								this.getCellHeightRetryCount.dynamic ++;
+								this._updateDynamicCellHeight(list, dataFrom);
+							}
+							return;
+						} 
+						const lastHeightCache = currentCacheList.length ? currentCacheList.slice(-1)[0] : null;
+						const lastTotalHeight = lastHeightCache ? lastHeightCache.totalHeight : 0;
+						currentCacheList.push({
+							height: currentHeight,
+							lastTotalHeight,
+							totalHeight: lastTotalHeight + currentHeight
+						});
+						if (dataFromTop) {
+							listTotalHeight += currentHeight;
+						}
+					}
+					if (dataFromTop && list.length) {
+						for (let i = 0; i < heightCacheList.length; i++) {
+							const heightCacheItem = heightCacheList[i];
+							heightCacheItem.lastTotalHeight += listTotalHeight;
+							heightCacheItem.totalHeight += listTotalHeight;
+						}
+						this.virtualHeightCacheList = currentCacheList.concat(heightCacheList);
+					}
+					this._updateVirtualScroll(this.oldScrollTop);
+				}, c.delayTime, 'updateDynamicCellHeightDelay')
+			})
+		},
+		//设置cellItem的index
+		_setCellIndex(list, dataFrom = 'bottom') {
+			let currentItemIndex = 0;
+			const cellIndexKey = this.virtualCellIndexKey;
+			if (this.totalData.length) {
+				if (dataFrom === 'bottom') {
+					currentItemIndex = this.realTotalData.length;
+					const lastItem = this.realTotalData.length ? this.realTotalData.slice(-1)[0] : null;
+					if (lastItem && lastItem[cellIndexKey] !== undefined) {
+						currentItemIndex = lastItem[cellIndexKey] + 1;
+					}
+				} else if (dataFrom === 'top') {
+					const firstItem = this.realTotalData.length ? this.realTotalData[0] : null;
+					if (firstItem && firstItem[cellIndexKey] !== undefined) {
+						currentItemIndex = firstItem[cellIndexKey] - list.length;
+					}
+				}
+			} else {			
+				this._resetDynamicListState();
+			}
+			for (let i = 0; i < list.length; i++) {
+				let item = list[i];
+				if (!item || Object.prototype.toString.call(item) !== '[object Object]') {
+					item = { item };
+				}
+				item[cellIndexKey] = currentItemIndex + i;
+				item[c.listCellIndexUniqueKey] = `${this.virtualListKey}-${item[cellIndexKey]}`;
+				list[i] = item;
+			}
+			this.getCellHeightRetryCount.dynamic = 0;
+			this.cellHeightMode === Enum.CellHeightMode.Dynamic && this._updateDynamicCellHeight(list, dataFrom);
+		},
+		//更新scroll滚动
+		_updateVirtualScroll(scrollTop, scrollDiff = 0) {
+			const currentTimeStamp = u.getTime();
+			scrollTop === 0 && this._resetTopRange();
+			if (scrollTop !== 0 && this.virtualScrollTimeStamp && currentTimeStamp - this.virtualScrollTimeStamp <= this.virtualScrollDisTimeStamp) {
+				return;
+			}
+			this.virtualScrollTimeStamp = currentTimeStamp;
+			
+			let scrollIndex = 0;
+			const cellHeightMode = this.cellHeightMode;
+			if (cellHeightMode === Enum.CellHeightMode.Fixed) {
+				scrollIndex = parseInt(scrollTop / this.virtualCellHeight) || 0;
+				this._updateFixedTopRangeIndex(scrollIndex);
+				this._updateFixedBottomRangeIndex(scrollIndex);
+			} else if(cellHeightMode === Enum.CellHeightMode.Dynamic) {
+				const scrollDirection = scrollDiff > 0 ? 'top' : 'bottom';
+				const rangePageHeight = this.virtualRangePageHeight;
+				const topRangePageOffset = scrollTop - rangePageHeight;
+				const bottomRangePageOffset = scrollTop + this.finalVirtualPageHeight + rangePageHeight;
+				
+				let virtualBottomRangeIndex = 0;
+				let virtualPlaceholderBottomHeight = 0;
+				let reachedLimitBottom = false;
+				const heightCacheList = this.virtualHeightCacheList;
+				const lastHeightCache = !!heightCacheList ? heightCacheList.slice(-1)[0] : null;
+				
+				let startTopRangeIndex = this.virtualTopRangeIndex;
+				if (scrollDirection === 'bottom') {
+					for (let i = startTopRangeIndex; i < heightCacheList.length; i++){
+						const heightCacheItem = heightCacheList[i];
+						if (heightCacheItem && heightCacheItem.totalHeight > topRangePageOffset) {
+							this.virtualTopRangeIndex = i;
+							this.virtualPlaceholderTopHeight = heightCacheItem.lastTotalHeight;
+							break;
+						}
+					}
+				} else {
+					let topRangeMatched = false;
+					for (let i = startTopRangeIndex; i >= 0; i--){
+						const heightCacheItem = heightCacheList[i];
+						if (heightCacheItem && heightCacheItem.totalHeight < topRangePageOffset) {
+							this.virtualTopRangeIndex = i;
+							this.virtualPlaceholderTopHeight = heightCacheItem.lastTotalHeight;
+							topRangeMatched = true;
+							break;
+						}
+					}
+					!topRangeMatched && this._resetTopRange();
+				}
+				for (let i = this.virtualTopRangeIndex; i < heightCacheList.length; i++){
+					const heightCacheItem = heightCacheList[i];
+					if (heightCacheItem && heightCacheItem.totalHeight > bottomRangePageOffset) {
+						virtualBottomRangeIndex = i;
+						virtualPlaceholderBottomHeight = lastHeightCache.totalHeight - heightCacheItem.totalHeight;
+						reachedLimitBottom = true;
+						break;
+					}
+				}
+				if (!reachedLimitBottom || this.virtualBottomRangeIndex === 0) {
+					this.virtualBottomRangeIndex = this.realTotalData.length ? this.realTotalData.length - 1 : this.pageSize;
+					this.virtualPlaceholderBottomHeight = 0;
+				} else {
+					this.virtualBottomRangeIndex = virtualBottomRangeIndex;
+					this.virtualPlaceholderBottomHeight = virtualPlaceholderBottomHeight;
+				}
+				this._updateVirtualList();
+			}
+		},
+		//更新fixedCell模式下topRangeIndex&placeholderTopHeight
+		_updateFixedTopRangeIndex(scrollIndex) {
+			let virtualTopRangeIndex = this.virtualCellHeight === 0 ? 0 : scrollIndex - (parseInt(this.finalVirtualPageHeight / this.virtualCellHeight) || 1) * this.preloadPage;
+			virtualTopRangeIndex *= this.virtualListCol;
+			virtualTopRangeIndex = Math.max(0, virtualTopRangeIndex);
+			this.virtualTopRangeIndex = virtualTopRangeIndex;
+			this.virtualPlaceholderTopHeight = (virtualTopRangeIndex / this.virtualListCol) * this.virtualCellHeight;
+		},
+		//更新fixedCell模式下bottomRangeIndex&placeholderBottomHeight
+		_updateFixedBottomRangeIndex(scrollIndex) {
+			let virtualBottomRangeIndex = this.virtualCellHeight === 0 ? this.pageSize : scrollIndex + (parseInt(this.finalVirtualPageHeight / this.virtualCellHeight) || 1) * (this.preloadPage + 1);
+			virtualBottomRangeIndex *= this.virtualListCol;
+			virtualBottomRangeIndex = Math.min(this.realTotalData.length, virtualBottomRangeIndex);
+			this.virtualBottomRangeIndex = virtualBottomRangeIndex;
+			this.virtualPlaceholderBottomHeight = (this.realTotalData.length - virtualBottomRangeIndex) * this.virtualCellHeight / this.virtualListCol;
+			this._updateVirtualList();
+		},
+		//更新virtualList
+		_updateVirtualList() {
+			const shouldUpdateList = this.updateVirtualListFromDataChange || (this.lastVirtualTopRangeIndex !== this.virtualTopRangeIndex || this.lastVirtualBottomRangeIndex !== this.virtualBottomRangeIndex);
+			if (shouldUpdateList) {
+				this.updateVirtualListFromDataChange = false;
+				this.lastVirtualTopRangeIndex =  this.virtualTopRangeIndex;
+				this.lastVirtualBottomRangeIndex = this.virtualBottomRangeIndex;
+				this.virtualList = this.realTotalData.slice(this.virtualTopRangeIndex, this.virtualBottomRangeIndex + 1);
+			}
+		},
+		//重置动态cell模式下的高度缓存数据、虚拟列表和滚动状态
+		_resetDynamicListState(resetVirtualList = false) {
+			this.virtualHeightCacheList = [];
+			if (resetVirtualList) {
+				this.virtualList = [];
+			}
+			this.virtualTopRangeIndex = 0;
+			this.virtualPlaceholderTopHeight = 0;
+		},
+		//重置topRangeIndex和placeholderTopHeight
+		_resetTopRange() {
+			this.virtualTopRangeIndex = 0;
+			this.virtualPlaceholderTopHeight = 0;
+			this._updateVirtualList();
+		},
+		//检测虚拟列表当前滚动位置,如发现滚动位置不正确则重新计算虚拟列表相关参数(为解决在App中可能出现的长时间进入后台后打开App白屏的问题)
+		_checkVirtualListScroll() {
+			if (this.finalUseVirtualList) {
+				this.$nextTick(() => {
+					this._getNodeClientRect('.zp-paging-touch-view').then(node => {
+						const currentTop = node ? node[0].top : 0;
+						if (!node || (currentTop === this.pagingOrgTop && this.virtualPlaceholderTopHeight !== 0)) {
+							this._updateVirtualScroll(0);
+						}
+					});
+				})
+			}
+		},
+		//处理使用内置列表时点击了cell事件
+		_innerCellClick(item, index) {
+			this.$emit('innerCellClick', item, index);
+		}
+	}
+}
diff --git a/uni_modules/z-paging/components/z-paging/js/z-paging-config.js b/uni_modules/z-paging/components/z-paging/js/z-paging-config.js
new file mode 100644
index 0000000..c7b714e
--- /dev/null
+++ b/uni_modules/z-paging/components/z-paging/js/z-paging-config.js
@@ -0,0 +1,21 @@
+// [z-paging]处理main.js中的配置信息工具
+
+let config = null;
+let getedStorage = false;
+const storageKey = 'Z-PAGING-CONFIG-STORAGE-KEY'
+
+function setConfig(value) {
+	uni.setStorageSync(storageKey, value);
+}
+
+function getConfig() {
+	if (getedStorage) return config;
+	config = uni.getStorageSync(storageKey);
+	getedStorage = true;
+	return config;
+}
+
+export default {
+	setConfig,
+	getConfig
+};
diff --git a/uni_modules/z-paging/components/z-paging/js/z-paging-constant.js b/uni_modules/z-paging/components/z-paging/js/z-paging-constant.js
new file mode 100644
index 0000000..93e8518
--- /dev/null
+++ b/uni_modules/z-paging/components/z-paging/js/z-paging-constant.js
@@ -0,0 +1,12 @@
+// [z-paging]常量
+
+export default {
+	version: '2.6.2',
+	delayTime: 100,
+	errorUpdateKey: 'z-paging-error-emit',
+	completeUpdateKey: 'z-paging-complete-emit',
+	cachePrefixKey: 'z-paging-cache',
+	
+	listCellIndexKey: 'zp_index',
+	listCellIndexUniqueKey: 'zp_unique_index'
+}
diff --git a/uni_modules/z-paging/components/z-paging/js/z-paging-enum.js b/uni_modules/z-paging/components/z-paging/js/z-paging-enum.js
new file mode 100644
index 0000000..17ad63a
--- /dev/null
+++ b/uni_modules/z-paging/components/z-paging/js/z-paging-enum.js
@@ -0,0 +1,44 @@
+// [z-paging]枚举
+
+export default {
+	//当前加载类型 0.下拉刷新 1.上拉加载更多
+	LoadingType: {
+		Refresher: 0,
+		LoadingMore: 1
+	},
+	//下拉刷新状态 0.默认状态 1.松手立即刷新 2.刷新中 3.刷新结束
+	Refresher: {
+		Default: 0,
+		ReleaseToRefresh: 1,
+		Loading: 2,
+		Complete: 3
+	},
+	//底部加载更多状态 0.默认状态 1.加载中 2.没有更多数据 3.加载失败
+	More: {
+		Default: 0,
+		Loading: 1,
+		NoMore: 2,
+		Fail: 3
+	},
+	//@query触发来源 0.用户主动下拉刷新 1.通过reload触发 2.通过refresh触发 3.通过滚动到底部加载更多或点击底部加载更多触发
+	QueryFrom: {
+		UserPullDown: 0,
+		Reload: 1,
+		Refresh: 2,
+		LoadingMore: 3
+	},
+	//虚拟列表cell高度模式
+	CellHeightMode: {
+		//固定高度
+		Fixed: 'fixed',
+		//动态高度
+		Dynamic: 'dynamic'
+	},
+	//列表缓存模式
+	CacheMode: {
+		//默认模式,只会缓存一次
+		Default: 'default',
+		//总是缓存,每次列表刷新(下拉刷新、调用reload等)都会更新缓存
+		Always: 'always'
+	}
+}
\ No newline at end of file
diff --git a/uni_modules/z-paging/components/z-paging/js/z-paging-interceptor.js b/uni_modules/z-paging/components/z-paging/js/z-paging-interceptor.js
new file mode 100644
index 0000000..d0e9b2b
--- /dev/null
+++ b/uni_modules/z-paging/components/z-paging/js/z-paging-interceptor.js
@@ -0,0 +1,48 @@
+// [z-paging]拦截器
+
+//拦截&处理@query事件
+function handleQuery(callback) {
+	try {
+		setTimeout(function() {
+			_getApp().globalData.zp_handleQueryCallback = callback;
+		}, 1);
+	} catch (e) {}
+}
+
+//拦截&处理@query事件(私有,请勿调用)
+function _handleQuery(pageNo, pageSize, from, lastItem){
+	const callback = _getApp().globalData.zp_handleQueryCallback;
+	return callback ? callback(pageNo, pageSize, from, lastItem) : [pageNo, pageSize, from];
+}
+
+//拦截&处理系统language转i18n local
+function handleLanguage2Local(callback) {
+	try {
+		setTimeout(function() {
+			_getApp().globalData.zp_handleLanguage2LocalCallback = callback;
+		}, 1);
+	} catch (e) {}
+}
+
+//拦截&处理系统language转i18n local(私有,请勿调用)
+function _handleLanguage2Local(language, local){
+	const callback = _getApp().globalData.zp_handleLanguage2LocalCallback;
+	return callback ? callback(language, local) : local;
+}
+
+//获取当前app对象
+function _getApp(){
+	// #ifndef APP-NVUE
+	return getApp();
+	// #endif
+	// #ifdef APP-NVUE
+	return getApp({ allowDefault: true });
+	// #endif
+}
+
+export default {
+	handleQuery,
+	_handleQuery,
+	handleLanguage2Local,
+	_handleLanguage2Local
+};
diff --git a/uni_modules/z-paging/components/z-paging/js/z-paging-main.js b/uni_modules/z-paging/components/z-paging/js/z-paging-main.js
new file mode 100644
index 0000000..6812252
--- /dev/null
+++ b/uni_modules/z-paging/components/z-paging/js/z-paging-main.js
@@ -0,0 +1,447 @@
+// [z-paging]核心js
+
+import zStatic from './z-paging-static'
+import c from './z-paging-constant'
+import u from './z-paging-utils'
+
+import zPagingRefresh from '../components/z-paging-refresh'
+import zPagingLoadMore from '../components/z-paging-load-more'
+import zPagingEmptyView from '../../z-paging-empty-view/z-paging-empty-view'
+
+// modules
+import commonLayoutModule from './modules/common-layout'
+import dataHandleModule from './modules/data-handle'
+import i18nModule from './modules/i18n'
+import nvueModule from './modules/nvue'
+import emptyModule from './modules/empty'
+import refresherModule from './modules/refresher'
+import loadMoreModule from './modules/load-more'
+import loadingModule from './modules/loading'
+import scrollerModule from './modules/scroller'
+import backToTopModule from './modules/back-to-top'
+import virtualListModule from './modules/virtual-list'
+
+import Enum from './z-paging-enum'
+
+const systemInfo = uni.getSystemInfoSync();
+
+export default {
+	name: "z-paging",
+	components: {
+		zPagingRefresh,
+		zPagingLoadMore,
+		zPagingEmptyView
+	},
+	mixins: [
+		commonLayoutModule,
+		dataHandleModule,
+		i18nModule,
+		nvueModule,
+		emptyModule,
+		refresherModule,
+		loadMoreModule,
+		loadingModule,
+		scrollerModule,
+		backToTopModule,
+		virtualListModule
+	],
+	data() {
+		return {
+			//--------------静态资源---------------
+			base64Arrow: zStatic.base64Arrow,
+			base64Flower: zStatic.base64Flower,
+			base64BackToTop: zStatic.base64BackToTop,
+
+			//-------------全局数据相关--------------
+			//当前加载类型
+			loadingType: Enum.LoadingType.Refresher,
+			requestTimeStamp: 0,
+			chatRecordLoadingMoreText: '',
+			wxsPropType: '',
+			renderPropScrollTop: -1,
+			checkScrolledToBottomTimeOut: null,
+			cacheTopHeight: -1,
+			statusBarHeight: systemInfo.statusBarHeight,
+
+			//--------------状态&判断---------------
+			insideOfPaging: -1,
+			isLoadFailed: false,
+			isIos: systemInfo.platform === 'ios',
+			disabledBounce: false,
+			fromCompleteEmit: false,
+			disabledCompleteEmit: false,
+			pageLaunched: false,
+			
+			//---------------wxs相关---------------
+			wxsIsScrollTopInTopRange: true,
+			wxsScrollTop: 0,
+			wxsPageScrollTop: 0,
+			wxsOnPullingDown: false,
+		};
+	},
+	props: {
+		//调用complete后延迟处理的时间,单位为毫秒,默认0毫秒,优先级高于minDelay
+		delay: {
+			type: [Number, String],
+			default: u.gc('delay', 0),
+		},
+		//触发@query后最小延迟处理的时间,单位为毫秒,默认0毫秒,优先级低于delay(假设设置为300毫秒,若分页请求时间小于300毫秒,则在调用complete后延迟[300毫秒-请求时长];若请求时长大于300毫秒,则不延迟),当show-refresher-when-reload为true或reload(true)时,其最小值为400
+		minDelay: {
+			type: [Number, String],
+			default: u.gc('minDelay', 0),
+		},
+		//设置z-paging的style,部分平台(如微信小程序)无法直接修改组件的style,可使用此属性代替
+		pagingStyle: {
+			type: Object,
+			default: function() {
+				return u.gc('pagingStyle', {});
+			},
+		},
+		//z-paging的高度,优先级低于pagingStyle中设置的height;传字符串,如100px、100rpx、100%
+		height: {
+			type: String,
+			default: u.gc('height', '')
+		},
+		//z-paging的宽度,优先级低于pagingStyle中设置的width;传字符串,如100px、100rpx、100%
+		width: {
+			type: String,
+			default: u.gc('width', '')
+		},
+		//z-paging的背景色,优先级低于pagingStyle中设置的background。传字符串,如"#ffffff"
+		bgColor: {
+			type: String,
+			default: u.gc('bgColor', '')
+		},
+		//设置z-paging的容器(插槽的父view)的style
+		pagingContentStyle: {
+			type: Object,
+			default: function() {
+				return u.gc('pagingContentStyle', {});
+			},
+		},
+		//z-paging是否自动高度,若自动高度则会自动铺满屏幕
+		autoHeight: {
+			type: Boolean,
+			default: u.gc('autoHeight', false)
+		},
+		//z-paging是否自动高度时,附加的高度,注意添加单位px或rpx,若需要减少高度,则传负数
+		autoHeightAddition: {
+			type: [Number, String],
+			default: u.gc('autoHeightAddition', '0px')
+		},
+		//loading(下拉刷新、上拉加载更多)的主题样式,支持black,white,默认black
+		defaultThemeStyle: {
+			type: String,
+			default: u.gc('defaultThemeStyle', 'black')
+		},
+		//z-paging是否使用fixed布局,若使用fixed布局,则z-paging的父view无需固定高度,z-paging高度默认为100%,默认为是(当使用内置scroll-view滚动时有效)
+		fixed: {
+			type: Boolean,
+			default: u.gc('fixed', true)
+		},
+		//是否开启底部安全区域适配
+		safeAreaInsetBottom: {
+			type: Boolean,
+			default: u.gc('safeAreaInsetBottom', false)
+		},
+		//开启底部安全区域适配后,是否使用placeholder形式实现,默认为否。为否时滚动区域会自动避开底部安全区域,也就是所有滚动内容都不会挡住底部安全区域,若设置为是,则滚动时滚动内容会挡住底部安全区域,但是当滚动到底部时才会避开底部安全区域
+		useSafeAreaPlaceholder: {
+			type: Boolean,
+			default: u.gc('useSafeAreaPlaceholder', false)
+		},
+		//slot="top"的view的z-index,默认为99,仅使用页面滚动时有效
+		topZIndex: {
+			type: Number,
+			default: u.gc('topZIndex', 99)
+		},
+		//z-paging内容容器父view的z-index,默认为1
+		superContentZIndex: {
+			type: Number,
+			default: u.gc('superContentZIndex', 1)
+		},
+		//z-paging内容容器部分的z-index,默认为10
+		contentZIndex: {
+			type: Number,
+			default: u.gc('contentZIndex', 10)
+		},
+		//使用页面滚动时,是否在不满屏时自动填充满屏幕,默认为是
+		autoFullHeight: {
+			type: Boolean,
+			default: u.gc('autoFullHeight', true)
+		},
+		//是否监听列表触摸方向改变,默认为否
+		watchTouchDirectionChange: {
+			type: Boolean,
+			default: u.gc('watchTouchDirectionChange', false)
+		},
+	},
+	created(){
+		if (this.createdReload && !this.refresherOnly && this.auto) {
+			this._startLoading();
+			this.$nextTick(this._preReload);
+		}
+	},
+	mounted() {
+		this.wxsPropType = u.getTime().toString();
+		this.renderJsIgnore;
+		if (!this.createdReload && !this.refresherOnly && this.auto) {
+			this.$nextTick(this._preReload);
+		}
+		this.finalUseCache && this._setListByLocalCache();
+		let delay = 0;
+		// #ifdef H5 || MP
+		delay = c.delayTime;
+		// #endif
+		this.$nextTick(() => {
+			this.systemInfo = uni.getSystemInfoSync();
+			!this.usePageScroll && this.autoHeight && this._setAutoHeight();
+			this.loaded = true;
+		})
+		this.updatePageScrollTopHeight();
+		this.updatePageScrollBottomHeight();
+		this.updateLeftAndRightWidth();
+		if (this.finalRefresherEnabled && this.useCustomRefresher) {
+			this.$nextTick(() => {
+				this.isTouchmoving = true;
+			})
+		}
+		this._onEmit();
+		// #ifdef APP-NVUE
+		if (!this.isIos && !this.useChatRecordMode) {
+			this.nLoadingMoreFixedHeight = true;
+		}
+		this._nUpdateRefresherWidth();
+		// #endif
+		// #ifndef APP-NVUE
+		this.finalUseVirtualList && this._virtualListInit();
+		// #endif
+		// #ifndef APP-PLUS
+		this.$nextTick(() => {
+			setTimeout(() => {
+				this._getCssSafeAreaInsetBottom(() => this.safeAreaInsetBottom && this.updatePageScrollBottomHeight());
+			}, delay)
+		})
+		// #endif
+	},
+	destroyed() {
+		this._offEmit();
+	},
+	// #ifdef VUE3
+	unmounted() {
+		this._offEmit();
+	},
+	// #endif
+	watch: {
+		defaultThemeStyle: {
+			handler(newVal) {
+				if (newVal.length) {
+					this.finalRefresherDefaultStyle = newVal;
+				}
+			},
+			immediate: true
+		},
+		autoHeight(newVal) {
+			this.loaded && !this.usePageScroll && this._setAutoHeight(newVal);
+		},
+		autoHeightAddition(newVal) {
+			this.loaded && !this.usePageScroll && this.autoHeight && this._setAutoHeight(newVal);
+		},
+	},
+	computed: {
+		finalPagingStyle() {
+			const pagingStyle = this.pagingStyle;
+			if (!this.systemInfo) return pagingStyle;
+			const { windowTop, windowBottom } = this;
+			if (!this.usePageScroll && this.fixed) {
+				if (windowTop && !pagingStyle.top) {
+					pagingStyle.top = windowTop + 'px';
+				}
+				if (windowBottom && !pagingStyle.bottom) {
+					pagingStyle.bottom = windowBottom + 'px';
+				}
+			}
+			if (this.bgColor.length && !pagingStyle['background']) {
+				pagingStyle['background'] = this.bgColor;
+			}
+			if (this.height.length && !pagingStyle['height']) {
+				pagingStyle['height'] = this.height;
+			}
+			if (this.width.length && !pagingStyle['width']) {
+				pagingStyle['width'] = this.width;
+			}
+			return pagingStyle;
+		},
+		finalLowerThreshold() {
+			return u.convertToPx(this.lowerThreshold);
+		},
+		finalPagingContentStyle() {
+			if (this.contentZIndex != 1) {
+				this.pagingContentStyle['z-index'] = this.contentZIndex;
+				this.pagingContentStyle['position'] = 'relative';
+			}
+			return this.pagingContentStyle;
+		},
+		renderJsIgnore() {
+			if ((this.usePageScroll && this.useChatRecordMode) || !this.refresherEnabled || !this.useCustomRefresher) {
+				this.$nextTick(() => {
+					this.renderPropScrollTop = 10;
+				})
+			}
+			return 0;
+		},
+		windowHeight() {
+			if (!this.systemInfo) return 0;
+			return this.systemInfo.windowHeight || 0;
+		},
+		windowBottom() {
+			if (!this.systemInfo) return 0;
+			let windowBottom = this.systemInfo.windowBottom || 0;
+			if (this.safeAreaInsetBottom && !this.useSafeAreaPlaceholder) {
+				windowBottom += this.safeAreaBottom;
+			}
+			return windowBottom;
+		},
+		isIosAndH5() {
+			// #ifndef H5
+			return false;
+			// #endif
+			return this.isIos;
+		}
+	},
+	methods: {
+		//当前版本号
+		getVersion() {
+			return `z-paging v${c.version}`;
+		},
+		//设置nvue List的specialEffects
+		setSpecialEffects(args) {
+			this.setListSpecialEffects(args);
+		},
+		//与setSpecialEffects等效,兼容旧版本
+		setListSpecialEffects(args) {
+			this.nFixFreezing = args && Object.keys(args).length;
+			if (this.isIos) {
+				this.privateRefresherEnabled = 0;
+			}
+			!this.usePageScroll && this.$refs['zp-n-list'].setSpecialEffects(args);
+		},
+		// #ifdef APP-VUE
+		//当app长时间进入后台后进入前台,因系统内存管理导致app重新加载时,进行一些适配处理
+		_handlePageLaunch() {
+			// 首次触发不进行处理,只有进入后台后打开app重新加载时才处理
+			if (this.pageLaunched) {
+				// 解决在vue3+ios中,app ReLaunch时顶部下拉刷新展示位置向下偏移的问题
+				// #ifdef VUE3
+				this.refresherThresholdUpdateTag = 1;
+				this.$nextTick(() => {
+					this.refresherThresholdUpdateTag = 0;
+				})
+				// #endif
+				// 解决使用虚拟列表时,app ReLaunch时白屏问题
+				this._checkVirtualListScroll();
+			}
+			this.pageLaunched = true;
+		},
+		// #endif
+		//使手机发生较短时间的振动(15ms)
+		_doVibrateShort() {
+			// #ifndef H5
+			
+			// #ifdef APP-PLUS
+			if (this.isIos) {
+				const UISelectionFeedbackGenerator = plus.ios.importClass('UISelectionFeedbackGenerator');
+				const feedbackGenerator = new UISelectionFeedbackGenerator();
+				feedbackGenerator.init();
+				setTimeout(() => {
+					feedbackGenerator.selectionChanged();
+				}, 0)
+			} else {
+				plus.device.vibrate(15);
+			}
+			// #endif
+			// #ifndef APP-PLUS
+			uni.vibrateShort();
+			// #endif
+			
+			// #endif
+		},
+		//设置z-paging高度
+		async _setAutoHeight(shouldFullHeight = true, scrollViewNode = null) {
+			let heightKey = 'min-height';
+			// #ifndef APP-NVUE
+			heightKey = 'min-height';
+			// #endif
+			try {
+				if (shouldFullHeight) {
+					let finalScrollViewNode = scrollViewNode || await this._getNodeClientRect('.zp-scroll-view');
+					let finalScrollBottomNode = await this._getNodeClientRect('.zp-page-bottom');
+					if (finalScrollViewNode) {
+						const scrollViewTop = finalScrollViewNode[0].top;
+						let scrollViewHeight = this.windowHeight - scrollViewTop;
+						scrollViewHeight -= finalScrollBottomNode ? finalScrollBottomNode[0].height : 0;
+						const additionHeight = u.convertToPx(this.autoHeightAddition);
+						const finalHeight = scrollViewHeight + additionHeight - (this.insideMore ? 1 : 0) + 'px !important';
+						this.$set(this.scrollViewStyle, heightKey, finalHeight);
+						this.$set(this.scrollViewInStyle, heightKey, finalHeight);
+					}
+				} else {
+					this.$delete(this.scrollViewStyle, heightKey);
+					this.$delete(this.scrollViewInStyle, heightKey);
+				}
+			} catch (e) {}
+		},
+		//触发更新是否超出页面状态
+		_updateInsideOfPaging() {
+			this.insideMore && this.insideOfPaging === true && setTimeout(this.doLoadMore, 200)
+		},
+		//清除timeout
+		_cleanTimeout(timeout) {
+			if (timeout) {
+				clearTimeout(timeout);
+				timeout = null;
+			}
+			return timeout;
+		},
+		//添加全局emit监听
+		_onEmit() {
+			uni.$on(c.errorUpdateKey, () => {
+				this.loading && this.complete(false).catch(() => {});
+			})
+			uni.$on(c.completeUpdateKey, (data) => {
+				setTimeout(() => {
+					if (this.loading) {
+						if (!this.disabledCompleteEmit) {
+							const type = data.type || 'normal';
+							const list = data.list || data;
+							const rule = data.rule;
+							this.fromCompleteEmit = true;
+							switch (type){
+								case 'normal':
+									this.complete(list);
+									break;
+								case 'total':
+									this.completeByTotal(list, rule);
+									break;
+								case 'nomore':
+									this.completeByNoMore(list, rule);
+									break;
+								case 'key':
+									this.completeByKey(list, rule);
+									break;
+								default:
+									break;
+							}
+						} else {
+							this.disabledCompleteEmit = false;
+						}
+					}
+				}, 1);
+			})
+		},
+		//销毁全局emit和listener监听
+		_offEmit(){
+			uni.$off(c.errorUpdateKey);
+			uni.$off(c.completeUpdateKey);
+		}
+	},
+};
diff --git a/uni_modules/z-paging/components/z-paging/js/z-paging-mixin.js b/uni_modules/z-paging/components/z-paging/js/z-paging-mixin.js
new file mode 100644
index 0000000..9d09caf
--- /dev/null
+++ b/uni_modules/z-paging/components/z-paging/js/z-paging-mixin.js
@@ -0,0 +1,22 @@
+// [z-paging]使用页面滚动时引入此mixin,用于监听和处理onPullDownRefresh等页面生命周期方法
+
+export default {
+	onPullDownRefresh() {
+		if (this.isPagingRefNotFound()) return;
+		this.$refs.paging.reload().catch(() => {});
+	},
+	onPageScroll(e) {
+		if (this.isPagingRefNotFound()) return;
+		this.$refs.paging.updatePageScrollTop(e.scrollTop);
+		e.scrollTop < 10 && this.$refs.paging.doChatRecordLoadMore();
+	},
+	onReachBottom() {
+		if (this.isPagingRefNotFound()) return;
+		this.$refs.paging.pageReachBottom();
+	},
+	methods: {
+		isPagingRefNotFound() {
+			return !this.$refs.paging;
+		}
+	}
+}
diff --git a/uni_modules/z-paging/components/z-paging/js/z-paging-static.js b/uni_modules/z-paging/components/z-paging/js/z-paging-static.js
new file mode 100644
index 0000000..05f80d5
--- /dev/null
+++ b/uni_modules/z-paging/components/z-paging/js/z-paging-static.js
@@ -0,0 +1,13 @@
+// [z-paging]公用的静态图片资源
+
+export default {
+	base64Arrow: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkBAMAAACCzIhnAAAAD1BMVEVHcExRUVFMTExRUVFRUVE9CdWsAAAABHRSTlMAjjrY9ZnUjwAAAQFJREFUWMPt2MsNgzAMgGEEE1B1gKJmAIRYoCH7z9RCXrabh33iYktcIv35EEg5ZBh07pvxJU6MFSPOSRnjnBUjUsaciRUjMsb4xIoRCWNiYsUInzE5sWKEyxiYWDbyefqHx1zIeiYTk7mQYziTYecxHvEJjwmIT3hMQELCYSISEg4TkZj0mYTEpM8kJCU9JiMp6TEZyUmbAUhO2gxAQNJiIAKSFgMRmNQZhMCkziAEJTUGIyipMRjBSZkhCE7KDEFIUmTeGCHJxWz0zXaE0GTCG8ZFtEaS347r/1fe11YyHYVfubxayfjoHmc0YYwmmmiiiSaaaKLJ7ckyz5ve+dw3Xw2emdwm9xSbAAAAAElFTkSuQmCC',
+	base64ArrowWhite: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkBAMAAACCzIhnAAAAElBMVEVHcEz///////////////////+IGTx/AAAABnRSTlMA/dAkXZOhASU/AAABYElEQVRYw+2YwXLCIBCGsdAHWGbyAKZ4zxi9O017rxLf/1UaWFAgA1m8dcpedNSPf/l/Vh0Ya/Wn6hN0JcGvoCqRM4C8VBFiDwBqqNuJKV0rAnCgy3AUqZE57x0iqTL8Br4U3WBf/YWaIlTKfAcELU/h9w72CSVPa3C3OCDvhpHbRp/s2vq4fHhCeiCl2A3m4Qd71DQR257mFBlMcTlbFnFWzNtHxewYEfSiaLS4el8d8nyhmKJd1CF4eOS0keLMAuSxubLBIeIGQW8YHCFFo7EH9+YDcQt9FMZEswTheaNxTHwHT8SZorJjMrEVwo4Zo0U8HSEyZvJMOg4RjnmmRr8nDYeIz3OMkbfE/QhBo+U9RnZJxjGCRh/WKmHEMWLNkfPKsGh/CWJk1JjG0kcuJggTt34VDP8aWAFhp4nybVb5+9qQhjSkIQ1pSEMa8k+Q5U9rV3dF8MpFBK+/7miVq1/HZ2qmo9D+pAAAAABJRU5ErkJggg==',
+	base64Flower: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkBAMAAACCzIhnAAAAKlBMVEVHcEzDw8Ovr6+pqamUlJTCwsKenp61tbWxsbGysrLNzc2bm5u5ubmjo6MpovhuAAAACnRSTlMA/P79/sHDhiZS0DxZowAABBBJREFUWMPtl89rE0EUx7ctTXatB3MI1SWnDbUKPUgXqh4ED8Uf7KUVSm3ooVSpSii0Fn/gD4j4o+APiEoVmos9FO2celiqZVgwgaKHPQiCCkv+F99kM7Ozm5kxq1dfD91k9pPve9/3ZjbRNHHok/mKli4eIPNgSuRObuN9SqSEzM20iGnm0yIbqCuV7NSSSIV7uyPM6JMBYdeTOanh/QihJYZsUCSby+VkMj2AvOt0rAeQAwqE3lfKMZVlQCZk1QOCKkkVPadITCfIRNKxfoJI5+0OIFtJx14CMSg1mRSDko7VAfksRQzEbGYqxOJcVTWMCH2I1/IACNW0PWU2M8cmAVHtnH5mM1VRWtwKZjOd5JbF6s1IbaYqaotjNlPHgDAnlAizubTR6ovMYn052g/U5qcmOpi0WL8xTS/3IfSet5m8MEr5ajjF5le6dq/OJpobrdY0t3i9QgefWrxW9/1BLhk0E9m8FeUMhhXal499iD0eQRfDF+ts/tttORRerfp+oV7f4xJj82iUYm1Yzod+ZQEAlS/8mMBwKebVmCVp1f0JLS6zKd17+iwRKTARVg2SHtz3iEbBH+Q+U28zW2Jiza8Tjb1YFoYZMsJyjDqp3M9XBQdSdPLFdxEpvOB37JrHcmR/y9+LgoTlCFGZEa2sc6d4PGlweEa2JSVPoVm+IfGG3ZL037iV9oH+P+Jxc4HGVflNq1M0pivao/EopO4b/ojVCP9GjmiXOeS0DOn1o/iiccT4ORnyvBGF3yUywkQajW4Ti0SGuiy/wVSg/L8w+X/8Q+hvUx8Xd90z4oV5a1i88MbFWHz0WZZ1UrTwBGPX3Rat9AFiXRMRjoMdIdJLEOt2h7jrYOzgOamKZSWSNspOS0X8SAqRYmxRL7sg4eLzYmNehcxh3uoyud/BH2Udux4ywxFTc1xC7Mgf4vMhc5S+kSH3Y7yj+qpwIWSoPTVCOOPVthGx9FbGqrwFw6wSFxJr+17zeKcztt3u+2roAEVgUjDd+AHGuxHy2rZHaa8JMkTHEeyi85ANPO9j9BVuBRD2FY5LDMo/Sz/2hReqGIs/KiFin+CsPsYO/yvM3jL2vE8EbX7/Bf8ejtr2GLN65bioAdgLd8Bis/mD5GmP2qeqyo2ZwQEOtAjRIDH7mBKpUcMoApbZJ5UIxkEwxyMZyMxW/uKFvHCFR3SSmerHyDNQ2dF4JG6zIMpBgLfjSF9x1D6smFcYnGApjmSLICO3ecCDWrQ48geba9DI3STy2i7ax6WIB62fSyIZIiO3GFQqSURp8wCo7GhJBGwuSovJBNjb7kT6FPVnIa9qJ2Ko+l9mefGIdinaMp0yC1URYiwsdfNE45EuA5Cx9EhalfvN5s+UyItm81vaB3p4joniN+SCP7Qc1hblAAAAAElFTkSuQmCC',
+	base64FlowerWhite: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkBAMAAACCzIhnAAAAElBMVEX///9HcEz///////////////84chYNAAAABnRSTlP/AGzCOYZj5g1nAAACfklEQVRYw+2YTVPDIBCGtza9Jw25a0bvcax30o73OOr//yvma2F3YWlpPTijXNpAHrK8LLALVPFium2vNIFSbwGKTGQA2GUiHcD29yDNy3sMIdUBQl7r2H8mOEVqAHgPkYZUS6Qc2zYhQqtjyDZEximCZwWZLIBeIgYShs2NzxKpSUehYpMJhURGb+O+w5BpMCAREKPnCDHbIY20SzhM5yxziAXpOiBXydrekT9i5XDEq4NIIHHgyU5mRGqviII4mREJJA4QJzMiILwlRJzpKxJKvCBm8OsBBbLux0tsPl4RKYm5aPu6jw1U4mGxEUR9g8M1PcqBEp/WJliNgYOXueBzS4jZSIcgY5lCtevgDSgyzE+rAfuOTQMq0yzvoGH18qju27Mayzs4fPyMziCx81NJa5RNfW7vPYK9KOfDiVkBxFHG8hAj9txuoBuSWORsFfkpBf7xKFLSeaOefEojh5jz22DJEqMP8fUyaKdQx+RnG+yXMpe8Aars8ueR1pVH/bW3FyyvPRw90upLDHwpgBDtg4aUBNkxRLXMAi03IhcZtr1m+FeI/O/JNyDmmL1djLOauSlNflBpW18RQ2bPqXI22MXXEk75KRHTnkPkYbESbdKP2ZFk0r5sIwffAjy1lx+vx7NLjB6/E7Jfv5ERKhzpN0w8IDE8IGFDv5dhz10s7GFiXRZcUeLCEG5P5nDq9k4PFDcoMpE3GY4OuxuCXhmuyNB6k0RsLIAvqp9NE5r8ZCSS8gxnUp7ODdYhZTqxuiJ9uyJJtPmpqJ7wVj+XVieS903iViHziqAhchLEJAyb7jWU647EpUofQ0ziUuXXXhDddtlllSwjgSQu7r4BRWhQqfDPMVwAAAAASUVORK5CYII=',
+	base64Success: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkBAMAAACCzIhnAAAAElBMVEVRUVFHcExTU1NRUVFRUVFRUVFOSlSUAAAABnRSTlP/AI6+VySB3ZENAAACcElEQVRYw+2YyYKCMAyGI8hdpdxdZu7gcpdZ7jL6/s8yYheSNi0aPdqbwOffpGmaFOYPD3gj4bisN7vddv17N/JVgxn5x12IWgIaWTuO/IE3PseQbwjGPo2cgRmHFLJwdm/X643zwiqOKPPJ1nj3sjEP2iiifZWj5bhopSyGaEO2HX5fbQJzwJ+W7x/jw5ZFjsEU0PMph9xE8i5EqprKALW95eJQURkgzw98uJ/JvwGecR7bIjWWsUgVrrIfFZ2HlLy3sKETD1mmRLRMRhGVssRa0xJkdn3SpJBymBkM8+pSSDXMDNyDaToVHd2fgpNt0sjwiUZO19+jGQ+gQEg9Oq+bufmAVGihomNmjQG7UG3020vrlm7lkFnKFGU3kZ0KGAdmKe821pipQ+qEKcrZeTL2g5FsUks4cStjEZWwXg0b0n4GxmEpkWwIs5VBynjgK7xZaz1/0D7OxkVuLpsY5BQNFyLS84VBjjbg0iL2r2EQHBOxBhikuUOkdxODVF1cxHoWtPPsiyXO455Iv34hssCO8EV4ZIYTjS8SR4qYSHRiTiYQ4ZFbHi0iIhhBTi6dTCgSWRcnw4h4yGTuyTAiOGBIWGoZTgSHJQl+LcOJ4OCnW6yX2bMnJ9pidCOXtkTkTrIGpYuOynAiOF14SamMiOCk5Ke+mq8BcOrrvym8d0zKIQnWT+M1WwOQNO4fFiWb18hhERxJPx2fblbPHHyC41VyiAtKBUFBIih7JMWVoIQTFIr3lKPN80WvoLSWFPC653ioTZA0I0FrQ7qU6asaK0H7JmkSJa2ooOGVtNUsc3j9FYHkIkJy3SG6VHnfXKXGP9t4N9Q4Ye98AAAAAElFTkSuQmCC',
+	base64SuccessWhite: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkBAMAAACCzIhnAAAAGFBMVEVHcEz///////////////////////////8dS1W+AAAAB3RSTlMAiVYk6KvDHLfaegAAAo1JREFUWMPtWEtzmzAQNhCTq910ytXpiyvxTNOr60zrayepx9d02gnX4sTm7xcEiJX2gdnkGJ1A4tOnfWqXyeR1vMRYzrcPD9v5h5MBl3/Ldvx4cxIg/FWC8X0xjLjalM54uhhCfCrRuJURX0pi3EmIqZV7O59vrRZmguStHL9b7S7ftfLwOtiZDw7AHMtmquAQ12b5Wwbnordm8g9zLLO49qc/m2n6aKnhwPOGZ08hAiNHhheiHae1lOUPGZpQkPKa3q0mOUjaRzSRaGUjpy/mmWSwySSpllcEteBKAT52KEnSbblA51pJEPxBQoiH1FP4E3s5+FJv07h6/ylD6ui7B+9fq/ehrFB98ghec9EoVtyjK8pqCHLmCBOwMWSCeWFNN4MbPAk55NhsvoFHSSVR0k5TCTTEzlUGcqV/nVp7n9oIVkmtaqbAEqEgfdgHJPwsEAyZ9r4VAZXFjpEwyaw3+H2v42KYxKhs1XvY/gSSGv+IHyUSuHXCeZhLAgVI3EjgSGo1Fb3xO0tGGU9S2/KAIbtjxpJASG73qox6w5LUq0cEOa+iIONIWIilQSQ0pPa2jgaRQAgQP7c0mITRWGxpMAmEQFN2NAQJNCV0mI6GIIEO47hlQ0ORQLd0nL+hoUjg1m6I1TRr8uYEAriBHLcVFQ5UEMiBe3XkTBEG04WXlGKGxPnMS305XQPA1Ocn2JiuAZwE66fxnKwBnDTuXxZTMq85lwW6kt5ndLqZPefiU1yvmktcUSooChJF2aMprhQlnKJQ5FxRKkcVRa+itNYU8Io2oVkY14w0NMWYlqft91Bj9VHq+ca3b43BxjWJmla0sfKohlfTVpPN+93L/yLQ/IjQ/O5Q/VR5HdL4D7mlxmjwVdELAAAAAElFTkSuQmCC',
+	base64Empty: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADIBAMAAABfdrOtAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAbUExURdvc3EdwTMLBwcjIyLSzs/Hx8ff39////19dXXz7IJEAAAAFdFJOU/4A6J9QDyyutAAAB5VJREFUeNrtnM1z4jYYxhUHkR4hdu9eU7Z75Ct7jgPbs9ZZmSuTrUWPmXTA186e+LMrf0uWLMtf2WkHXQgzln88et5XeiVMwPQdGrhCrpAr5Aq5Qv4TkJ07OGQFMLp1B4VYCz+kDblDQhJGeH4eEDLBYdLOHwaDWNBPIeHLYJAJ3meQ83IoCMTHDBKOBoKYGOeM8G0gyD0LObnDQB5ZSCtTNCBfsM9AboaBPLCQcDAIM1zht/dQEkMsd1DjI4hpw2YzMtBJeBbydWpCTJs3YDKGX62YgfGoVwi9KwtZJAzcYHHRm7sYCKD390nQSIoO5JGZIEOYxNoZ4+deISYLyeL5hLHbJ2QK98W0kudMgJe9Qh73odhO+KZHyNYGvgQS9gmJKhUigwSj3iBPUhXxePWmxBqHw0Mej9WQ3qILVjLC177yxNxXQ/7uK+Mn1aNVLsGsBTaWrSAPobYl0aUHt2fIs2Rgz7c9QYL0pSTkSzILLFtAJMH1cidN998T9E0/Sg73/pEEwrgkYRh86wlC949gJsR6EobBcz8hHOVgKYi2m6kZtodIkjEQvF3QjbGpmplB4/lRgJhxgRS2N15iijAvPmByDtCxfQhPJ8J4CR82rgCCBILarScw6X0OcMUyYrFVmbxErl0ZacFIoloOLdJAO42qY+NMDss2kKS8xmiZxcCpFKXWvpRGbQqJp5ixyRfJMmR6x0Fk+z29kmgWDYI5ziFbdug/84HxvduhWhLOJ2StPDQrMJPSjNANklh8QhB7dBO0yTGRwn1fkOk8rbQjiB8Ymww+JuiuN0icmSccK4naLMWYa/euL0+m23GyM8kgAc6sYeL4z04Qa4WjGepcKIliO8EUGSk7d9OGWOsoK31OSdy8TQZ59Y/hWbaV1IVs5/Ed6UzGK4nANAJiyGhRsZPUg2yzLe9hLyiJIyCaDU7udC2uy9pnkKvidlBUEltzFAqxRhBrBZm7HfZnjEQI3boqTsJq15PUDEaKZLgiJYc8OZtCtnM/4G93OFYooXpvdy0guwWWNQkEHl/j7Jw1XRmtlS9HYJkSPjk1IUnyyRqUKQn45NSDlP1mcg9i6En1ZU2IADnEtHF1Q+JwIcS/d5YakPuDUamEShGUHHikAz9oQCaE0CsrpYjDBVkEHQYdyK+EkKPhVErxqh1xbJ/oQf4gEeVsOIEc41WJNAwcd9GBfCZJezXsJhAvH+ImEEIOzlwXgpw5wQ0gH3MIOcsiQAahZuSD69/UQyxcQEggiQARQseVFO/ASAMCgM9gjkHZmhLENzi1AOhA7ullkMWUrfHKfpMiDBHtDIx6yCS6jseEnDUe7zcT6DGCtnrIY3olZw1hrPHkfucIAJa1EDu/lsVEyVmGGA67coKijeogFnMxlEaAV5ghRdDm1kDuuatZTJBGgJdOthIzsvZbDWRRuh6ScgR4EQLgagQvRQIxxQ4sxqcR4GE+c4CkjZQQW9YF89Y4OFAjOCki5KmiDxsBL3PlSJWlAFVogaoIePlYi2ClCJAHRa/cmre5eqTii4uvisqQJxqnip6pNd68DhEvyEs5xIyHBNdh4thCKhU++10kD7Gy1Up1A/o56FKuRJQWSFCuf8dpbisxhqHSKlSSgvG7VTaFKO5TzYD5VMPUxEB2YJNiqq3xYJ0KrroH8mq7xpoXqEZgfgNRUQsDtTVvUOk3sLUKbqrBr7YGvkCkQNC/9SA+vTYtvERrxiKEmcogk4ZqCLUd59MIEiFYHlIoxelCaJWDMmtOPIa80XVLbkb6hzaEwwTcPEmV4AIRlBGNIEmuJBFwLAZoHClJ36J8h+wxihpCqJosAnJrSKwEcQOFAFeWN4RQMYc0Ao4Jhg5gpASzyWcDvjpuDIlTkrGGJEro1rHIjHKR3wJCAj+z5oyi11gJBkXy9QFJIiAu78d+pgSjuWhGN0gUAZAcEncSJf4LRrZ8I94WEmcNCJJqBWYjVbE9bg2JxiyrViBWty6QvO56D8jPVWLA4ZX8dfkxvJJPl8t8aCX+pU/Iz1SCf7lc4OBK0OWfQaKLP0TKjj96VvIp+/BDZjwNKF2ItV2vN7sWStAl87oWkm3dZ+k3lEMoYXe8cT1eq2TOePJDD8KfQdxu6iEPxanUZa4HmZRq3dunGsj3BzFq6yD3wnZNX4n2emI2hXyXQpi6RRZdfSgxHNuxVZBFdyVeBPDmCsiksxKUiDAUEKuzkvRUEs0V08pjVyU2/yqFmF2VZGYop3peitdUiQd1pnrL7qTE01tPzE6eaEKm23dQwh2jNlbiay+/245zl94abw45CzNPyqYQ2++kxHGV1crWzg4A2yvR+BY7wziwnRLN7+O36aA54+ZKGjxZYK3txJpxQyUNn5GwtquII4+ACiWtnvawduu1A3SVtH5uhTvAVSpBG7fDYz6RQ+M6JWjmKm6g+RvTla9UMtspu+s+37VbVCupNqPx43CsNawSb1PbtcmDfQWmUILW7rRXSPHtSq5k5ur0a/hb7DQCUiW3G71ejX/wvV1kSoyNbp8Wvyqn1lCIKvl6gNDkNBYzt0GHdr+Pt9xGl1//ncAVcoVcIVfIFXKFXCFXyP8I8i8SyTW4yTz2lwAAAABJRU5ErkJggg==',
+	base64Error: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADIBAMAAABfdrOtAAAAJFBMVEVHcEzo6Oibm5ukpKSbm5uampqbm5ubm5u5ubnn5+fm5ub6+vpGpDPdAAAAC3RSTlMA/v4hb+u20dq8aQhnHL4AAATwSURBVHja7ZvNb+JGGMbdjjdVe3NPodzeMhj1ZMUGujkh28B9wKR7iwwBqafWSbPqsbm0uTWtVlrTS9v0Et9yqLQS/1zHNiTZMMB4bO92d+dRUITt8c/PvPPx2h4URUpKSkpKSkpK6m3K6lFN73Q+S/+es3W3fzabTh2Dl0FAXEM+BgrgeXxRsdILTDU9n7J0vz/+EsCYC9KEiSFc06pf5zouqAkjkGWo0OG5Fq6j2IwZ6I4/4DhyTxc20oUjAj5PRTTrwvGAZ9p+ADzlD4RDctCoLhb7JUP87xeLxS3BZUIQ+YNCFi8wRwc4GIqGRK/GkM+5ILV8kFflOmkkkH/LddJ4c05eSSfSyTvrZPEmnCw+UCeuk84QvTSnUF0uCL68fBle/swF+RL1QZ/EpU6gHtOsAM64pnjPwxgTLsjoBM58ODNaAXYBT5QeGdr0KwcEA8He0TkPBLCjUDNHpG4qlg8eTCzXht1FVd1MxTPHj5LTtUiSrKK+7iDf8wBGxk4If3arLv/HF4Tox0A2nlFIGp+CIA+LzSamgbp4TNvZjECtDAjyMcB5HybLO6NxsRA1vmFCNjguNXDGWygbRPXh/B+zn9zPWK5RCkT18QxA57YgAqE+HGS6/tAoD4JO0ts+M2tbyQJpc95a5oI0xXNhCZGQ/x8E0VSCkUZY6Z6CIE/qdO5eL+yPlW6tMMgefPs3o7Bdt8iguJj4DThlZSY/rJ0yB+RraLDK2jAQCHyr4zIhT9mQ7vowygMZjpgQG+CYUV2E1EWqixyzICr8eFFnBB5ba1Y4IIfeKQvysW7ssZrwQLEFmvCBM2U6oRkdI5Wgm1QnO8RUTDlASoiESIiESMh7BDHKhlhu/LbSNUuEqL3lu1p945vO3BArADiaum7vBGDUKQfSIjBykooyrRPQnTIglHFfSagHeqd4iErwa9duEebpckGQjx/VT4v5fC0XhJHAd1mPRvJAVMZiAeQzTpgHYrPKqkGnUEiX+dCoNS4UgniHMTnUS4iESIiE7IS0x+mnVAidglDwVcmQJpy2WQ8VC4UgogfbA1RE4Nuw3UghEBV2rKl7V5ygAJPSY9KGQbP01mVjA5Fa2f1kQN2U3k+M9POWB8gnJUNMZJioWTMzKwOklyxgDrCXVcMMEF90tXM9C2TiCqmfCdIRi/jeewNpyerKok9WkGuzfCdYC+fXRsmBxxpVGG2zY0ZBbieJKvPrDQce3lxppBhIjGFWGkVoxUEoZt0Mukn2XBQH0bTHZpaMIp2sU/6qasU70W6/eHjM09VmYSc6C6Jpvz+orKvVxot8kL3HkMr9IZ9qeZ2o6RrO9mOI9ufdIR9peZ2gNIW31yC/MpyI9ngUDNIsezPks3vIsWDGdYA7cZa9pbqUVeCr/neiaR3U3R4BfXPg75vwb8I/b7HjxChobDZCO+Ny4wuxxaVxPPowcoNnrzPmzGFlX3RJHz2FafbhJ41n8PLx2DCM7KkwQgpqka1DVzKdJNHfJwBe9l/n0eSZFsIPjVSY8xZKZpSXnogwled98wAx3xRcdBNq1f1fhFVdIcL5tvaDolC7XaqaWStEtLOJHkbhlSauMLrma4yHEa03AVUoIUs/M2NQFkchBZiGUPeKonAnqhLOo4hrKf0WTyZ1FcU0Ki0hVrSr+Mucnvya7jYUKSkpKSkpKSmpD0f/AXq+Umj5XnXDAAAAAElFTkSuQmCC',
+	base64BackToTop: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADIBAMAAABfdrOtAAAAElBMVEVRUVH+/v5HcEyZmZlRUVFRUVGm1ByOAAAABnRSTlPMzADMTZAJBBGsAAAEnElEQVR42t2cS27jMAyGf7/2U+QCQeDsbeQCgZDujaC5/1UmkzaJn+JDFGcw3LdfflKibJkkDnxrL7dbg7sNt6+L4O8OYBM+B0ys+QrGkHZG+OEEQ8g6go8Bx1GIGMdpNOQyIG6XdMgnSPtKhLQDGEZFBgYMkhKFtGBb0EIEjDgFRowoBVaMGAWpMedEfxMiZtwpUsgZCqtlkCNUdpVAWigtCCCDFtLwIWeoreZCWiRYYEKGFEjDg+yRZCUH0iLRAgNyToXUNCRZyMqWhGnUN2IPm3wSlwJ7IUspyCBkIQUZhCykIIeQuRTkEDKXAuM9srrtYbrZN7Y98giZSoFd+t1OxmMITG0dcrSFXFchZ1tIvQZpYWxhBbK3hpQrkMEa0iwh5t4a+QvZvDXyF7J5a+Qv5PPW21/I5623v5DPW29/IaO3Xv5Clrw1y1/Ikrdm+Qs5svw83yNnSJ5BQb4F/F7EIEJSnThGBAXxkFQfLOviQUE8JAUPsosHBfGQfDAtHhREQ1JxIV00KIgmrnRI84S0yAd5BAXxxJUck0f6Qnwr9qmr6xF5xLMjcwn/iudIEAdWnyjkEXlQKZiRVzoqRyLbgeUKKR8Q4alY7cSnoxzSf2ggsqehKr6YVpcXpOd7H93f60cKhOd7Re2LteUF4eLqiVS1mr0ge4io6C2+soaFkJ7MuuuQs1yITEp9hwwKISIpzR2iESKSIoT0rLNwuVHQqoSIpAQJpGce60vIUSdEIuUqgPTsJ5QFZK8UIpBS8iG94GFrDjlrhfCl8CG96Llxmle4kEr6vKWBPIVo9kqDQSRk9/3cWoikcCFPAd33v4dIChPyEvLzBA6RlEYWke4JEUnhKXkLeUEKxRHJFfKCQHGucIW8IdZSRkLeEGMpYyEjiK2UsZARxFTKRMgYYillImQMMZQyFTKB2EmZCplAuFLIHT8TMoWwpQwiIVMIUwqpZP5bp5CCvCTiQKr5f5lCQN+tPCBn2ZvVDFJwIDUP0m1BYAfZYRNSsCB7BqTbhoARePIxtZ9tgwWkoJcwCalmv3MBAemtO4R6dah2HaKQqj8Zvp9sQDjvJ21+SPCBHPJDDk6QITekEV7gqCC19CpKAym9IMfckKv4olMBCeIrWwVEfvkshzQekO9r9P1/ALk+IG1eSPCDiCJfyG+FyU+A6ZCa/piZDinpz7LpkCv5gdkAEshP5emQhv7onw6pGeULyZCSUYiRDAmMkpJkCKs4JhFSq8p8hJBSVbAkhARV6ZUQoisik0FqXTmcDHLVFfbJIEFXoiiCNMpiSxGkVJaNiiBBWQArgTTaUl4JpNQWJUsgQVteXQg+AKkLxQWFGKW+5J2+eVp4S168X3CF1CltCKdTJ8lb84YK2bUBO+wZW0Pqv9nk4tKu49N45NJC5dMM5tLW5tOg59Jq6NM06dL+abFXwr/RkuvTXJwae1abtE/Dt0/ruksTvs84AZ/BCC4jHnyGVfiM3VBQFANEXEah+Ax18RlP4zNox2dkkM/wI58xTn8yDCXGYCDV3W5RGSajtXyGhG1jbpbjzpwGt/0MJft8jqC7iUbQ/QZaxdnKqcIftwAAAABJRU5ErkJggg==',
+}
diff --git a/uni_modules/z-paging/components/z-paging/js/z-paging-utils.js b/uni_modules/z-paging/components/z-paging/js/z-paging-utils.js
new file mode 100644
index 0000000..59e9bf6
--- /dev/null
+++ b/uni_modules/z-paging/components/z-paging/js/z-paging-utils.js
@@ -0,0 +1,228 @@
+// [z-paging]工具类
+
+import zConfig from './z-paging-config'
+import zLocalConfig from '../config/index'
+import c from './z-paging-constant'
+
+const storageKey = 'Z-PAGING-REFRESHER-TIME-STORAGE-KEY';
+let config = null;
+const timeoutMap = {};
+
+/*
+当z-paging未使用uni_modules管理时,控制台会有警告:WARNING: Module not found: Error: Can't resolve '@/uni_modules/z-paging'...
+此时注释下方try中的代码即可
+*/
+// #ifdef VUE2
+try {
+	const contextKeys = require.context('@/uni_modules/z-paging', false, /\z-paging-config$/).keys();
+	if (contextKeys.length) {
+		const suffix = '.js';
+		config = require('@/uni_modules/z-paging/z-paging-config' + suffix);
+	}
+} catch (e) {}
+// #endif
+
+//获取默认配置信息
+function gc(key, defaultValue) {
+	if (!config) {
+		if (zLocalConfig && Object.keys(zLocalConfig).length) {
+			config = zLocalConfig;
+		} else {
+			const tempConfig = zConfig.getConfig();
+			if (zConfig && tempConfig) {
+				config = tempConfig;
+			}
+		}
+	}
+	if (!config) return defaultValue;
+	const value = config[_toKebab(key)];
+	return value === undefined ? defaultValue : value;
+}
+
+
+//获取最终的touch位置
+function getTouch(e) {
+	let touch = null;
+	if (e.touches && e.touches.length) {
+		touch = e.touches[0];
+	} else if (e.changedTouches && e.changedTouches.length) {
+		touch = e.changedTouches[0];
+	} else if (e.datail && e.datail != {}) {
+		touch = e.datail;
+	} else {
+		return {
+			touchX: 0,
+			touchY: 0
+		}
+	}
+	return {
+		touchX: touch.clientX,
+		touchY: touch.clientY
+	};
+}
+
+//判断当前手势是否在z-paging内触发
+function getTouchFromZPaging(target) {
+	if (target && target.tagName && target.tagName !== 'BODY' && target.tagName !== 'UNI-PAGE-BODY') {
+		const classList = target.classList;
+		if (classList && classList.contains('z-paging-content')) {
+			return {
+				isFromZp: true, 
+				isPageScroll: classList.contains('z-paging-content-page'), 
+				isReachedTop: classList.contains('z-paging-reached-top')
+			};
+		} else {
+			return getTouchFromZPaging(target.parentNode);
+		}
+	} else {
+		return { isFromZp: false };
+	}
+}
+
+//获取z-paging所在的parent
+function getParent(parent) {
+	if (!parent) return null;
+	if (parent.$refs.paging) return parent;
+	return getParent(parent.$parent);
+}
+
+//打印错误信息
+function consoleErr(err) {
+	console.error(`[z-paging]${err}`);
+}
+
+//延时操作,如果key存在,调用时根据key停止之前的延时操作
+function delay(callback, ms = c.delayTime, key) {
+	const timeout = setTimeout(callback, ms);;
+	if (!!key) {
+		timeoutMap[key] && clearTimeout(timeoutMap[key]);
+		timeoutMap[key] = timeout;
+	}
+	return timeout;
+}
+
+//设置下拉刷新时间
+function setRefesrherTime(time, key) {
+	const datas = getRefesrherTime() || {};
+	datas[key] = time;
+	uni.setStorageSync(storageKey, datas);
+}
+
+//获取下拉刷新时间
+function getRefesrherTime() {
+	return uni.getStorageSync(storageKey);
+}
+
+//通过下拉刷新标识key获取下拉刷新时间
+function getRefesrherTimeByKey(key) {
+	const datas = getRefesrherTime();
+	return datas && datas[key] ? datas[key] : null;
+}
+
+//通过下拉刷新标识key获取下拉刷新时间(格式化之后)
+function getRefesrherFormatTimeByKey(key, textMap) {
+	const time = getRefesrherTimeByKey(key);
+	const timeText = time ? _timeFormat(time, textMap) : textMap.none;
+	return `${textMap.title}${timeText}`;
+}
+
+//将文本的px或者rpx转为px的值
+function convertToPx(text) {
+	const dataType = Object.prototype.toString.call(text);
+	if (dataType === '[object Number]') return text;
+	let isRpx = false;
+	if (text.indexOf('rpx') !== -1 || text.indexOf('upx') !== -1) {
+		text = text.replace('rpx', '').replace('upx', '');
+		isRpx = true;
+	} else if (text.indexOf('px') !== -1) {
+		text = text.replace('px', '');
+	}
+	if (!isNaN(text)) {
+		if (isRpx) return Number(uni.upx2px(text));
+		return Number(text);
+	}
+	return 0;
+}
+
+//获取当前时间
+function getTime() {
+	return (new Date()).getTime();
+}
+
+//获取z-paging实例id
+function getInstanceId() {
+    const s = [];
+    const hexDigits = "0123456789abcdef";
+    for (let i = 0; i < 10; i++) {
+        s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
+    }
+    return s.join('') + getTime();
+}
+
+// 等待一段时间
+function wait(ms) {
+	return new Promise(resolve => {
+		setTimeout(resolve, ms);
+	});
+}
+
+//------------------ 私有方法 ------------------------
+//时间格式化
+function _timeFormat(time, textMap) {
+	const date = new Date(time);
+	const currentDate = new Date();
+	const dateDay = new Date(time).setHours(0, 0, 0, 0);
+	const currentDateDay = new Date().setHours(0, 0, 0, 0);
+	const disTime = dateDay - currentDateDay;
+	let dayStr = '';
+	const timeStr = _dateTimeFormat(date);
+	if (disTime === 0) {
+		dayStr = textMap.today;
+	} else if (disTime === -86400000) {
+		dayStr = textMap.yesterday;
+	} else {
+		dayStr = _dateDayFormat(date, date.getFullYear() !== currentDate.getFullYear());
+	}
+	return `${dayStr} ${timeStr}`;
+}
+
+//date格式化为年月日
+function _dateDayFormat(date, showYear = true) {
+	const year = date.getFullYear();
+	const month = date.getMonth() + 1;
+	const day = date.getDate();
+	return showYear ? `${year}-${_fullZeroToTwo(month)}-${_fullZeroToTwo(day)}` : `${_fullZeroToTwo(month)}-${_fullZeroToTwo(day)}`;
+}
+
+//data格式化为时分
+function _dateTimeFormat(date) {
+	const hour = date.getHours();
+	const minute = date.getMinutes();
+	return `${_fullZeroToTwo(hour)}:${_fullZeroToTwo(minute)}`;
+}
+
+//不满2位在前面填充0
+function _fullZeroToTwo(str) {
+	str = str.toString();
+	return str.length === 1 ? '0' + str : str;
+}
+
+//驼峰转短横线
+function _toKebab(value) {
+	return value.replace(/([A-Z])/g, "-$1").toLowerCase();
+}
+
+export default {
+	gc,
+	setRefesrherTime,
+	getRefesrherFormatTimeByKey,
+	getTouch,
+	getTouchFromZPaging,
+	getParent,
+	convertToPx,
+	getTime,
+	getInstanceId,
+	consoleErr,
+	delay,
+	wait
+};
diff --git a/uni_modules/z-paging/components/z-paging/wxs/z-paging-renderjs.js b/uni_modules/z-paging/components/z-paging/wxs/z-paging-renderjs.js
new file mode 100644
index 0000000..9ecf76b
--- /dev/null
+++ b/uni_modules/z-paging/components/z-paging/wxs/z-paging-renderjs.js
@@ -0,0 +1,58 @@
+// [z-paging]使用renderjs在app-vue和h5中对touchmove事件冒泡进行处理
+
+import u from '../js/z-paging-utils'
+const data = {
+	startY: 0,
+	isTouchFromZPaging: false,
+	isUsePageScroll: false,
+	isReachedTop: true,
+	isIosAndH5: false,
+	appLaunched: false
+}
+
+export default {
+	mounted() {
+		if (window) {
+			this._handleTouch();
+			// #ifdef APP-VUE
+			this.$ownerInstance.callMethod('_handlePageLaunch');
+			// #endif
+		}
+	},
+	methods: {
+		//接收逻辑层发送的数据
+		renderPropIsIosAndH5Change(newVal) {
+			if (newVal === -1) return;
+			data.isIosAndH5 = newVal;
+		},
+		//拦截处理touch事件
+		_handleTouch() {
+			if (!window.$zPagingRenderJsInited) {
+				window.$zPagingRenderJsInited = true;
+				window.addEventListener('touchstart', this._handleTouchstart, { passive: true })
+				window.addEventListener('touchmove', this._handleTouchmove, { passive: false })
+			}
+		},
+		_handleTouchstart(e) {
+			const touch = u.getTouch(e);
+			data.startY = touch.touchY;
+			const touchResult = u.getTouchFromZPaging(e.target);
+			data.isTouchFromZPaging = touchResult.isFromZp;
+			data.isUsePageScroll = touchResult.isPageScroll;
+			data.isReachedTop = touchResult.isReachedTop;
+		},
+		_handleTouchmove(e) {
+			const touch = u.getTouch(e);
+			const moveY = touch.touchY - data.startY;
+			if (data.isTouchFromZPaging && ((data.isReachedTop && moveY > 0)  || (data.isIosAndH5 && !data.isUsePageScroll && moveY < 0))) {
+				if (e.cancelable && !e.defaultPrevented) {
+					e.preventDefault();
+				}
+			}
+		},
+		_removeAllEventListener(){
+			window.removeEventListener('touchstart');
+			window.removeEventListener('touchmove');
+		}
+	}
+};
diff --git a/uni_modules/z-paging/components/z-paging/wxs/z-paging-wxs.wxs b/uni_modules/z-paging/components/z-paging/wxs/z-paging-wxs.wxs
new file mode 100644
index 0000000..4dbc64f
--- /dev/null
+++ b/uni_modules/z-paging/components/z-paging/wxs/z-paging-wxs.wxs
@@ -0,0 +1,340 @@
+// [z-paging]微信小程序、QQ小程序、app-vue、h5上使用wxs实现自定义下拉刷新,降低逻辑层与视图层的通信折损,提升性能
+
+var currentDis = 0;
+var isPCFlag = -1;
+var startY = -1;
+
+function propObserver(newValue, oldValue, ownerIns, ins) {
+	var state = ownerIns.getState() || {};
+	state.currentIns = ins;
+	var dataset = ins.getDataset();
+	var loading = dataset.loading == true;
+	if (newValue && newValue.indexOf('end') != -1) {
+		var transition = newValue.split('end')[0];
+		_setTransform('translateY(0px)', ins, false, transition);
+		state.moveDis = 0;
+		state.oldMoveDis = 0;
+		currentDis = 0;
+	} else if (newValue && newValue.indexOf('begin') != -1) {
+		var refresherThreshold = ins.getDataset().refresherthreshold;
+		_setTransformValue(refresherThreshold, ins, state, false);
+	}
+}
+
+function touchstart(e, ownerIns) {
+	var ins = _getIns(ownerIns);
+	var state = {};
+	var dataset = {};
+	ownerIns.callMethod('_handleListTouchstart');
+	if (ins) {
+		state = ins.getState();
+		dataset = ins.getDataset();
+		if (_touchDisabled(e, ins, 0)) return;
+	}
+	var isTouchEnded = state.isTouchEnded;
+	state.oldMoveDis = 0;
+	var touch = _getTouch(e);
+	var loading = _isTrue(dataset.loading);
+	state.startY = touch.touchY;
+	startY = state.startY;
+	state.lastTouch = touch;
+	if (!loading && isTouchEnded) {
+		state.isTouchmoving = false;
+	}
+	state.isTouchEnded = false;
+	ownerIns.callMethod('_handleRefresherTouchstart', touch);
+}
+
+function touchmove(e, ownerIns) {
+	var touch = _getTouch(e);
+	var ins = _getIns(ownerIns);
+	var dataset = ins.getDataset();
+	var refresherThreshold = dataset.refresherthreshold;
+	var isIos = _isTrue(dataset.isios);
+	var state = ins.getState();
+	var watchTouchDirectionChange = _isTrue(dataset.watchtouchdirectionchange);
+	var moveDisObj = {};
+	var moveDis = 0;
+	var prevent = false;
+	if (watchTouchDirectionChange) {
+		moveDisObj = _getMoveDis(e, ins);
+		moveDis = moveDisObj.currentDis;
+		prevent = moveDisObj.isDown;
+		var direction = prevent ? 'top' : 'bottom';
+		if (prevent == state.oldTouchDirection && prevent != state.oldEmitedTouchDirection) {
+			ownerIns.callMethod('_handleTouchDirectionChange', { direction: direction }); 
+			state.oldEmitedTouchDirection = prevent;
+		}
+		state.oldTouchDirection = prevent;
+	}
+	if (_touchDisabled(e, ins, 1)) {
+		_handlePullingDown(state, ownerIns, false);
+		return true;
+	}
+	if (!_getAngleIsInRange(e, touch, state, dataset)) {
+		_handlePullingDown(state, ownerIns, false);
+		return true;
+	}
+	moveDisObj = _getMoveDis(e, ins);
+	moveDis = moveDisObj.currentDis;
+	prevent = moveDisObj.isDown;
+	if (moveDis < 0) {
+		_setTransformValue(0, ins, state, false);
+		_handlePullingDown(state, ownerIns, false);
+		return true;
+	}
+	if (prevent && !state.disabledBounce) {
+		ownerIns.callMethod('_handleScrollViewDisableBounce', {bounce: false});
+		state.disabledBounce = true;
+		_handlePullingDown(state, ownerIns, prevent);
+		return !prevent;
+	}
+	_setTransformValue(moveDis, ins, state, false);
+	var oldRefresherStatus = state.refresherStatus;
+	var oldIsTouchmoving = _isTrue(dataset.oldistouchmoving);
+	var hasTouchmove = _isTrue(dataset.hastouchmove);
+	var isTouchmoving = state.isTouchmoving;
+	state.refresherStatus = moveDis >= refresherThreshold ? 1 : 0;
+	if (!isTouchmoving) {
+		state.isTouchmoving = true;
+		isTouchmoving = true;
+	}
+	if (state.isTouchEnded) {
+		state.isTouchEnded = false;
+	}
+	if (hasTouchmove) {
+		ownerIns.callMethod('_handleWxsPullingDown', { moveDis:moveDis, diffDis:moveDisObj.diffDis });
+	}
+	if (oldRefresherStatus == undefined || oldRefresherStatus != state.refresherStatus || oldIsTouchmoving != isTouchmoving) {
+		ownerIns.callMethod('_handleRefresherTouchmove', moveDis, touch);
+	}
+	_handlePullingDown(state, ownerIns, prevent);
+	return !prevent;
+}
+
+function touchend(e, ownerIns) {
+	var touch = _getTouch(e);
+	var ins = _getIns(ownerIns);
+	var dataset = ins.getDataset();
+	var state = ins.getState();
+	if (_touchDisabled(e, ins, 2)) return;
+	state.reachMaxAngle = true;
+	state.hitReachMaxAngleCount = 0;
+	state.disabledBounce = false;
+	state.fixedIsTopHitCount = 0;
+	if (!state.isTouchmoving) return;
+	var oldRefresherStatus = state.refresherStatus;
+	var oldMoveDis = state.moveDis;
+	var refresherThreshold = ins.getDataset().refresherthreshold
+	var moveDis = _getMoveDis(e, ins).currentDis;
+	if (!(moveDis >= refresherThreshold && oldRefresherStatus === 1)) {
+		state.isTouchmoving = false;
+	}
+	ownerIns.callMethod('_handleRefresherTouchend', moveDis);
+	state.isTouchEnded = true;
+	if (oldMoveDis < refresherThreshold) return;
+	var animate = false;
+	if (moveDis >= refresherThreshold) {
+		moveDis = refresherThreshold;
+		animate = true;
+	}
+	_setTransformValue(moveDis, ins, state, animate);
+}
+
+// #ifdef H5
+function isPC() {
+	if (!navigator) return false;
+	if (isPCFlag != -1) return isPCFlag;
+	var agents = ["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"];
+	isPCFlag = agents.every(function(item) { return navigator.userAgent.indexOf(item) < 0 });
+	return isPCFlag;
+}
+
+var movable = false;
+
+function mousedown(e, ins) {
+	if (!isPC()) return;
+	touchstart(e, ins);
+	movable = true;
+}
+
+function mousemove(e, ins) {
+	if (!isPC() || !movable) return;
+	touchmove(e, ins);
+}
+
+function mouseup(e, ins) {
+	if (!isPC()) return;
+	touchend(e, ins);
+	movable = false;
+}
+
+function mouseleave(e, ins) {
+	if (!isPC()) return;
+	movable = false;
+}
+// #endif
+
+
+function _setTransformValue(value, ins, state, animate) {
+	value = value || 0;
+	if (state.moveDis == value) return;
+	state.moveDis = value;
+	_setTransform('translateY(' + value + 'px)', ins, animate, '');
+}
+
+function _setTransform(transform, ins, animate, transition) {
+	var dataset = ins.getDataset();
+	if (_isTrue(dataset.refreshernotransform)) return;
+	transform = transform == 'translateY(0px)' ? 'none' : transform;
+	ins.requestAnimationFrame(function() {
+		var stl = { 'transform': transform };
+		if (animate) {
+			stl['transition'] = 'transform .1s linear';
+		}
+		if (transition.length) {
+			stl['transition'] = transition;
+		}
+		ins.setStyle(stl);
+	})
+}
+
+function _getMoveDis(e, ins) {
+	var state = ins.getState();
+	var refresherThreshold = parseFloat(ins.getDataset().refresherthreshold);
+	var refresherOutRate = parseFloat(ins.getDataset().refresheroutrate);
+	var refresherPullRate = parseFloat(ins.getDataset().refresherpullrate);
+	var touch = _getTouch(e);
+	var currentStartY = !state.startY || state.startY == 'NaN' ? startY : state.startY;
+	var moveDis = touch.touchY - currentStartY;
+	var oldMoveDis = state.oldMoveDis || 0;
+	state.oldMoveDis = moveDis;
+	var diffDis = moveDis - oldMoveDis;
+	if (diffDis > 0) {
+		diffDis = diffDis * refresherPullRate;
+		if (currentDis > refresherThreshold) {
+			diffDis = diffDis * (1 - refresherOutRate);
+		}
+	}
+	diffDis = diffDis > 100 ? diffDis / 100 : (diffDis > 20 ? diffDis / 1.2 : diffDis);
+	currentDis += diffDis;
+	currentDis = Math.max(0, currentDis);
+	return {
+		currentDis: currentDis,
+		diffDis: diffDis,
+		isDown: diffDis > 0
+	};
+}
+
+function _getTouch(e) {
+	var touch = e;
+	if (e.touches && e.touches.length) {
+		touch = e.touches[0];
+	} else if (e.changedTouches && e.changedTouches.length) {
+		touch = e.changedTouches[0];
+	} else if (e.datail && e.datail != {}) {
+		touch = e.datail;
+	}
+	return {
+		touchX: touch.clientX,
+		touchY: touch.clientY
+	};
+}
+
+function _getIns(ownerIns) {
+	var ins = ownerIns.getState().currentIns;
+	if (!ins) {
+		ownerIns.callMethod('_handlePropUpdate');
+	}
+	return ins;
+}
+
+function _touchDisabled(e, ins, processTag) {
+	var dataset = ins.getDataset();
+	var state = ins.getState();
+	var loading = _isTrue(dataset.loading);
+	var useChatRecordMode = _isTrue(dataset.usechatrecordmode);
+	var refresherEnabled = _isTrue(dataset.refresherenabled);
+	var useCustomRefresher = _isTrue(dataset.usecustomrefresher);
+	var usePageScroll = _isTrue(dataset.usepagescroll);
+	var pageScrollTop = parseFloat(dataset.pagescrolltop);
+	var scrollTop = parseFloat(dataset.scrolltop);
+	var finalScrollTop = usePageScroll ? pageScrollTop : scrollTop;
+	var fixedIsTop = false;
+	var isIos = _isTrue(dataset.isios);
+	if (!isIos && finalScrollTop == (state.startScrollTop || 0) && finalScrollTop <= 105) {
+		fixedIsTop = true;
+	}
+	var fixedIsTopHitCount = state.fixedIsTopHitCount || 0;
+	if (fixedIsTop) {
+		fixedIsTopHitCount ++;
+		if (fixedIsTopHitCount <= 2) {
+			fixedIsTop = false;
+		}
+		state.fixedIsTopHitCount = fixedIsTopHitCount;
+	} else {
+		state.fixedIsTopHitCount = 0;
+	}
+	if (!isIos && processTag === 0) {
+		state.startScrollTop = finalScrollTop || 0;
+	}
+	if (!isIos && processTag === 2) {
+		fixedIsTop = true;
+	}
+	return loading || useChatRecordMode || !refresherEnabled || !useCustomRefresher || 
+	((usePageScroll && useCustomRefresher && pageScrollTop > 5) && !fixedIsTop) || 
+	((!usePageScroll && useCustomRefresher && scrollTop > 5) && !fixedIsTop);
+}
+
+function _getAngleIsInRange(e, touch, state, dataset) {
+	var maxAngle = dataset.refreshermaxangle;
+	var refresherAecc = _isTrue(dataset.refresheraecc);
+	var lastTouch = state.lastTouch;
+	var reachMaxAngle = state.reachMaxAngle;
+	var moveDis = state.oldMoveDis;
+	if (!lastTouch) return true;
+	if (maxAngle >= 0 && maxAngle <= 90 && lastTouch) {
+		if ((!moveDis || moveDis < 1) && !refresherAecc && reachMaxAngle != null && !reachMaxAngle) return false;
+		var x = Math.abs(touch.touchX - lastTouch.touchX);
+		var y = Math.abs(touch.touchY - lastTouch.touchY);
+		var z = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
+		if ((x || y) && x > 1) {
+			var angle = Math.asin(y / z) / Math.PI * 180;
+			if (angle < maxAngle) {
+				var hitReachMaxAngleCount = state.hitReachMaxAngleCount || 0;
+				state.hitReachMaxAngleCount = ++hitReachMaxAngleCount;
+				if (state.hitReachMaxAngleCount > 2) {
+					state.lastTouch = touch;
+					state.reachMaxAngle = false;
+				}
+				return false;
+			}
+		}
+	}
+	state.lastTouch = touch;
+	return true;
+}
+
+function _handlePullingDown(state, ins, onPullingDown) {
+	var oldOnPullingDown = state.onPullingDown || false;
+	if (oldOnPullingDown != onPullingDown) {
+		ins.callMethod('_handleWxsPullingDownStatusChange', onPullingDown);
+	}
+	state.onPullingDown = onPullingDown;
+}
+
+function _isTrue(value) {
+	value = (typeof(value) === 'string' ? JSON.parse(value) : value) || false;
+	return value == true || value == 'true';
+}
+
+module.exports = {
+	touchstart: touchstart,
+	touchmove: touchmove,
+	touchend: touchend,
+	mousedown: mousedown,
+	mousemove: mousemove,
+	mouseup: mouseup,
+	mouseleave: mouseleave,
+	propObserver: propObserver
+}
diff --git a/uni_modules/z-paging/components/z-paging/z-paging.vue b/uni_modules/z-paging/components/z-paging/z-paging.vue
new file mode 100644
index 0000000..30c675a
--- /dev/null
+++ b/uni_modules/z-paging/components/z-paging/z-paging.vue
@@ -0,0 +1,310 @@
+ <!--                        _             
+  ____     _ __   __ _  __ _(_)_ __   __ _ 
+ |_  /____| '_ \ / _` |/ _` | | '_ \ / _` |
+  / /_____| |_) | (_| | (_| | | | | | (_| |
+ /___|    | .__/ \__,_|\__, |_|_| |_|\__, |
+          |_|          |___/         |___/ 
+v2.6.2 (2023-10-31)
+by ZXLee
+-->
+<!-- 文档地址:https://z-paging.zxlee.cn -->
+<!-- github地址:https://github.com/SmileZXLee/uni-z-paging -->
+<!-- dcloud地址:https://ext.dcloud.net.cn/plugin?id=3935 -->
+<!-- 反馈QQ群:790460711(已满)、371624008 -->
+
+<template name="z-paging">
+	<!-- #ifndef APP-NVUE -->
+	<view :class="{'z-paging-content':true,'z-paging-content-fixed':!usePageScroll&&fixed,'z-paging-content-page':usePageScroll,'z-paging-reached-top':renderPropScrollTop<1}" :style="[finalPagingStyle]">
+		<!-- #ifndef APP-PLUS -->
+		<view v-if="cssSafeAreaInsetBottom===-1" class="zp-safe-area-inset-bottom"></view>
+		<!-- #endif -->
+		<!-- 顶部固定的slot -->
+		<slot v-if="!usePageScroll&&zSlots.top" name="top" />
+		<view class="zp-page-top" @touchmove.stop.prevent v-else-if="usePageScroll&&zSlots.top" :style="[{'top':`${windowTop}px`,'z-index':topZIndex}]">
+			<slot name="top" />
+		</view>
+		<view :class="{'zp-view-super':true,'zp-scroll-view-super':!usePageScroll}" :style="[finalScrollViewStyle]">
+			<view v-if="zSlots.left" :class="{'zp-page-left':true,'zp-absoulte':finalIsOldWebView}">
+				<slot name="left" />
+			</view>
+			<view :class="{'zp-scroll-view-container':true,'zp-absoulte':finalIsOldWebView}" :style="[scrollViewContainerStyle]">
+				<scroll-view
+					ref="zp-scroll-view" :class="{'zp-scroll-view':true,'zp-scroll-view-absolute':!usePageScroll,'zp-scroll-view-hide-scrollbar':!showScrollbar}"
+					:scroll-top="scrollTop" :scroll-x="scrollX"
+					:scroll-y="scrollable&&!usePageScroll&&scrollEnable&&(refresherCompleteScrollable?true:refresherStatus!==R.Complete)" :enable-back-to-top="finalEnableBackToTop"
+					:show-scrollbar="showScrollbar" :scroll-with-animation="finalScrollWithAnimation"
+					:scroll-into-view="scrollIntoView" :lower-threshold="finalLowerThreshold" :upper-threshold="5"
+					:refresher-enabled="finalRefresherEnabled&&!useCustomRefresher" :refresher-threshold="finalRefresherThreshold"
+					:refresher-default-style="finalRefresherDefaultStyle" :refresher-background="refresherBackground"
+					:refresher-triggered="finalRefresherTriggered" @scroll="_scroll" @scrolltolower="_onScrollToLower"
+					@scrolltoupper="_onScrollToUpper" @refresherrestore="_onRestore" @refresherrefresh="_onRefresh(true)"
+					>	
+					<view class="zp-paging-touch-view"
+					<!-- #ifndef APP-VUE || MP-WEIXIN || MP-QQ  || H5 -->
+					@touchstart="_refresherTouchstart" @touchmove="_refresherTouchmove" @touchend="_refresherTouchend" @touchcancel="_refresherTouchend"
+					<!-- #endif -->
+					<!-- #ifdef APP-VUE || MP-WEIXIN || MP-QQ || H5 -->
+					@touchstart="pagingWxs.touchstart" @touchmove="pagingWxs.touchmove" @touchend="pagingWxs.touchend" @touchcancel="pagingWxs.touchend"
+					@mousedown="pagingWxs.mousedown" @mousemove="pagingWxs.mousemove" @mouseup="pagingWxs.mouseup" @mouseleave="pagingWxs.mouseleave"
+					<!-- #endif -->
+					>	
+						<view v-if="finalRefresherFixedBacHeight>0" class="zp-fixed-bac-view" :style="[{'background': refresherFixedBackground,'height': `${finalRefresherFixedBacHeight}px`}]"></view>
+						<view class="zp-paging-main" :style="[scrollViewInStyle,{'transform': finalRefresherTransform,'transition': refresherTransition}]"
+						<!-- #ifdef APP-VUE || MP-WEIXIN || MP-QQ || H5 -->
+						:change:prop="pagingWxs.propObserver" :prop="wxsPropType"
+						:data-refresherThreshold="finalRefresherThreshold" :data-isIos="isIos"
+						:data-loading="loading||isRefresherInComplete" :data-useChatRecordMode="useChatRecordMode" 
+						:data-refresherEnabled="refresherEnabled" :data-useCustomRefresher="useCustomRefresher" :data-pageScrollTop="wxsPageScrollTop"
+						:data-scrollTop="wxsScrollTop" :data-refresherMaxAngle="refresherMaxAngle" :data-refresherNoTransform="refresherNoTransform"
+						:data-refresherAecc="refresherAngleEnableChangeContinued" :data-usePageScroll="usePageScroll" :data-watchTouchDirectionChange="watchTouchDirectionChange"
+						:data-oldIsTouchmoving="isTouchmoving" :data-refresherOutRate="finalRefresherOutRate" :data-refresherPullRate="finalRefresherPullRate" :data-hasTouchmove="hasTouchmove"
+						<!-- #endif -->
+						<!-- #ifdef APP-VUE || H5 -->
+						:change:renderPropIsIosAndH5="pagingRenderjs.renderPropIsIosAndH5Change" :renderPropIsIosAndH5="isIosAndH5"
+						<!-- #endif -->
+						>	
+							<view v-if="showRefresher" class="zp-custom-refresher-view" :style="[{'margin-top': `-${finalRefresherThreshold+refresherThresholdUpdateTag}px`,'background': refresherBackground,'opacity': isTouchmoving ? 1 : 0}]">
+								<view class="zp-custom-refresher-container" :style="[{'height': `${finalRefresherThreshold}px`,'background': refresherBackground}]">
+									<view v-if="useRefresherStatusBarPlaceholder" class="zp-custom-refresher-status-bar-placeholder" :style="[{'height': `${statusBarHeight}px`}]" />
+									<!-- 下拉刷新view -->
+									<view class="zp-custom-refresher-slot-view">
+										<slot v-if="!(zSlots.refresherComplete&&refresherStatus===R.Complete)" :refresherStatus="refresherStatus" name="refresher" />
+									</view>
+									<slot v-if="zSlots.refresherComplete&&refresherStatus===R.Complete" name="refresherComplete" />
+									<z-paging-refresh ref="refresh" v-else-if="!showCustomRefresher" class="zp-custom-refresher-refresh" :style="[{'height': `${finalRefresherThreshold - finalRefresherThresholdPlaceholder}px`}]" :status="refresherStatus"
+										:defaultThemeStyle="finalRefresherThemeStyle" :defaultText="finalRefresherDefaultText"
+										:pullingText="finalRefresherPullingText" :refreshingText="finalRefresherRefreshingText" :completeText="finalRefresherCompleteText"
+										:defaultImg="refresherDefaultImg" :pullingImg="refresherPullingImg" :refreshingImg="refresherRefreshingImg" :completeImg="refresherCompleteImg" :refreshingAnimated="refresherRefreshingAnimated"
+										:showUpdateTime="showRefresherUpdateTime" :updateTimeKey="refresherUpdateTimeKey" :updateTimeTextMap="finalRefresherUpdateTimeTextMap"
+										:imgStyle="refresherImgStyle" :titleStyle="refresherTitleStyle" :updateTimeStyle="refresherUpdateTimeStyle" />
+								</view>
+							</view>
+							<view class="zp-paging-container">
+								<slot v-if="useChatRecordMode&&zSlots.chatLoading&&loadingStatus!==M.NoMore&&realTotalData.length" name="chatLoading" />
+								<view v-else-if="useChatRecordMode&&loadingStatus!==M.NoMore&&realTotalData.length" class="zp-chat-record-loading-container">
+									<text v-if="loadingStatus!==M.Loading" @click="_onScrollToUpper"
+										:class="defaultThemeStyle==='white'?'zp-loading-more-text zp-loading-more-text-white':'zp-loading-more-text zp-loading-more-text-black'">{{chatRecordLoadingMoreText}}</text>
+									<image v-else :src="base64Flower" class="zp-chat-record-loading-custom-image" />
+								</view>
+								<!-- 全屏Loading -->
+								<slot v-if="showLoading&&zSlots.loading&&!loadingFullFixed" name="loading" />
+								<!-- 主体内容 -->
+								<view class="zp-paging-container-content" :style="[{transform:virtualPlaceholderTopHeight>0?`translateY(${virtualPlaceholderTopHeight}px)`:'none'},finalPagingContentStyle]">
+									<slot />
+									<!-- 内置列表&虚拟列表 -->
+									<template v-if="finalUseInnerList">
+										<slot name="header"/>
+										<view class="zp-list-container" :style="[innerListStyle]">
+											<template v-if="finalUseVirtualList">
+												<view class="zp-list-cell" :style="[innerCellStyle]" :id="`zp-id-${item[virtualCellIndexKey]}`" v-for="(item,index) in virtualList" :key="item['zp_unique_index']" @click="_innerCellClick(item,virtualTopRangeIndex+index)">
+													<view v-if="useCompatibilityMode">使用兼容模式请在组件源码z-paging.vue第100行中注释这一行,并打开下面一行注释</view>
+													<!-- <zp-public-virtual-cell v-if="useCompatibilityMode" :extraData="extraData" :item="item" :index="virtualTopRangeIndex+index" /> -->
+													<slot v-else name="cell" :item="item" :index="virtualTopRangeIndex+index"/>
+												</view>
+											</template>
+											<template v-else>
+												<view class="zp-list-cell" v-for="(item,index) in realTotalData" :key="index" @click="_innerCellClick(item,index)">
+													<slot name="cell" :item="item" :index="index"/>
+												</view>
+											</template>
+										</view>
+										<slot name="footer"/>
+									</template>
+									<view v-if="useVirtualList" class="zp-virtual-placeholder" :style="[{height:virtualPlaceholderBottomHeight+'px'}]"/>
+									<!-- 上拉加载更多view -->
+									<!-- #ifndef MP-ALIPAY -->
+									<slot v-if="showLoadingMoreDefault" name="loadingMoreDefault" />
+									<slot v-else-if="showLoadingMoreLoading" name="loadingMoreLoading" />
+									<slot v-else-if="showLoadingMoreNoMore" name="loadingMoreNoMore" />
+									<slot v-else-if="showLoadingMoreFail" name="loadingMoreFail" />
+									<z-paging-load-more @doClick="_onLoadingMore('click')" v-else-if="showLoadingMoreCustom" :zConfig="zLoadMoreConfig" />
+									<!-- #endif -->
+									<!-- #ifdef MP-ALIPAY -->
+									<slot v-if="loadingStatus===M.Default&&zSlots.loadingMoreDefault&&showLoadingMore&&loadingMoreEnabled&&!useChatRecordMode" name="loadingMoreDefault" />
+									<slot v-else-if="loadingStatus===M.Loading&&zSlots.loadingMoreLoading&&showLoadingMore&&loadingMoreEnabled" name="loadingMoreLoading" />
+									<slot v-else-if="loadingStatus===M.NoMore&&zSlots.loadingMoreNoMore&&showLoadingMore&&showLoadingMoreNoMoreView&&loadingMoreEnabled&&!useChatRecordMode" name="loadingMoreNoMore" />
+									<slot v-else-if="loadingStatus===M.Fail&&zSlots.loadingMoreFail&&showLoadingMore&&loadingMoreEnabled&&!useChatRecordMode" name="loadingMoreFail" />
+									<z-paging-load-more @doClick="_onLoadingMore('click')" v-else-if="showLoadingMore&&showDefaultLoadingMoreText&&!(loadingStatus===M.NoMore&&!showLoadingMoreNoMoreView)&&loadingMoreEnabled&&!useChatRecordMode" :zConfig="zLoadMoreConfig" />
+									<!-- #endif -->
+									<view v-if="safeAreaInsetBottom&&useSafeAreaPlaceholder" class="zp-safe-area-placeholder" :style="[{height:safeAreaBottom+'px'}]" />
+								</view>
+								<!-- 空数据图 -->
+								<view v-if="showEmpty" :class="{'zp-empty-view':true,'zp-empty-view-center':emptyViewCenter}" :style="[emptyViewSuperStyle]">
+									<slot v-if="zSlots.empty" name="empty" :isLoadFailed="isLoadFailed"/>
+									<z-paging-empty-view v-else :emptyViewImg="finalEmptyViewImg" :emptyViewText="finalEmptyViewText" :showEmptyViewReload="finalShowEmptyViewReload" 
+									:emptyViewReloadText="finalEmptyViewReloadText" :isLoadFailed="isLoadFailed" :emptyViewStyle="emptyViewStyle" :emptyViewTitleStyle="emptyViewTitleStyle" 
+									:emptyViewImgStyle="emptyViewImgStyle" :emptyViewReloadStyle="emptyViewReloadStyle" :emptyViewZIndex="emptyViewZIndex" :emptyViewFixed="emptyViewFixed" 
+									@reload="_emptyViewReload" @viewClick="_emptyViewClick" />
+								</view>
+							</view>
+						</view>
+					</view>
+				</scroll-view>
+			</view>
+			<view v-if="zSlots.right" :class="{'zp-page-right':true,'zp-absoulte zp-right':finalIsOldWebView}">
+				<slot name="right" />
+			</view>
+		</view>
+		<!-- 底部固定的slot -->
+		<slot v-if="!usePageScroll&&zSlots.bottom" name="bottom" />
+		<view class="zp-page-bottom" @touchmove.stop.prevent v-else-if="usePageScroll&&zSlots.bottom" :style="[{'bottom': `${windowBottom}px`}]">
+			<slot name="bottom" />
+		</view>
+		<!-- 点击返回顶部view -->
+		<view v-if="showBackToTopClass" :class="backToTopClass" :style="[finalBackToTopStyle]" @click.stop="_backToTopClick">
+			<slot v-if="zSlots.backToTop" name="backToTop" />
+			<image v-else class="zp-back-to-top-img" :src="backToTopImg.length?backToTopImg:base64BackToTop" />
+		</view>
+		<!-- 全屏Loading(铺满z-paging并固定) -->
+		<view v-if="showLoading&&zSlots.loading&&loadingFullFixed" class="zp-loading-fixed">
+			<slot name="loading" />
+		</view>
+	</view>
+	<!-- #endif -->
+	<!-- #ifdef APP-NVUE -->
+	<component :is="finalNvueSuperListIs" :style="[finalPagingStyle]" :class="{'z-paging-content-fixed':fixed&&!usePageScroll}" :scrollable="false">
+		<!-- 顶部固定的slot -->
+		<view ref="zp-page-top" v-if="zSlots.top" :class="{'zp-page-top':usePageScroll}" :style="[usePageScroll?{'top':`${windowTop}px`,'z-index':topZIndex}:{}]">
+			<slot name="top" />
+		</view>
+		<component :is="finalNvueSuperListIs" class="zp-n-list-container" :scrollable="false">
+			<view v-if="zSlots.left" class="zp-page-left">
+				<slot name="left" />
+			</view>
+			<component :is="finalNvueListIs" ref="zp-n-list" :id="nvueListId" :style="[{'flex': 1,'top':isIos?'0px':'-1px'},usePageScroll?scrollViewStyle:{},nChatRecordRotateStyle]" :alwaysScrollableVertical="true"
+				:fixFreezing="nFixFreezing" :show-scrollbar="showScrollbar&&!useChatRecordMode" :loadmoreoffset="finalLowerThreshold" :enable-back-to-top="enableBackToTop"
+				:scrollable="scrollable&&scrollEnable&&(refresherCompleteScrollable?true:refresherStatus!==R.Complete)" :bounce="nvueBounce" :column-count="nWaterfallColumnCount" :column-width="nWaterfallColumnWidth"
+				:column-gap="nWaterfallColumnGap" :left-gap="nWaterfallLeftGap" :right-gap="nWaterfallRightGap" :pagingEnabled="nvuePagingEnabled" :offset-accuracy="offsetAccuracy"
+				@loadmore="_nOnLoadmore" @scroll="_nOnScroll">
+				<refresh v-if="(zSlots.top?cacheTopHeight!==-1:true)&&finalNvueRefresherEnabled" class="zp-n-refresh" :style="[nvueRefresherStyle]" :display="nRefresherLoading?'show':'hide'" @refresh="_nOnRrefresh" @pullingdown="_nOnPullingdown">
+					<view ref="zp-n-refresh-container" class="zp-n-refresh-container" :style="[{background:refresherBackground,width:nRefresherWidth}]" id="zp-n-refresh-container">
+						<view v-if="useRefresherStatusBarPlaceholder" class="zp-custom-refresher-status-bar-placeholder" :style="[{'height': `${statusBarHeight}px`}]" />
+						<!-- 下拉刷新view -->
+						<slot v-if="zSlots.refresherComplete&&refresherStatus===R.Complete" name="refresherComplete" />
+						<slot v-else-if="(nScopedSlots?nScopedSlots:zSlots).refresher" :refresherStatus="refresherStatus" name="refresher" />
+						<z-paging-refresh ref="refresh" v-else :status="refresherStatus" :defaultThemeStyle="finalRefresherThemeStyle"
+							:defaultText="finalRefresherDefaultText" :pullingText="finalRefresherPullingText" :refreshingText="finalRefresherRefreshingText" :completeText="finalRefresherCompleteText"
+							:defaultImg="refresherDefaultImg" :pullingImg="refresherPullingImg" :refreshingImg="refresherRefreshingImg" :completeImg="refresherCompleteImg" :refreshingAnimated="refresherRefreshingAnimated"
+							:showUpdateTime="showRefresherUpdateTime" :updateTimeKey="refresherUpdateTimeKey" :updateTimeTextMap="finalRefresherUpdateTimeTextMap"
+							:imgStyle="refresherImgStyle" :titleStyle="refresherTitleStyle" :updateTimeStyle="refresherUpdateTimeStyle" />
+					</view>
+				</refresh>
+				<component :is="nViewIs" v-if="isIos&&!useChatRecordMode?oldScrollTop>10:true" ref="zp-n-list-top-tag" class="zp-n-list-top-tag" style="margin-top: -1rpx;" :style="[{height:finalNvueRefresherEnabled?'0px':'1px'}]"></component>
+				<component :is="nViewIs" v-if="nShowRefresherReveal" ref="zp-n-list-refresher-reveal" :style="[{transform:`translateY(-${nShowRefresherRevealHeight}px)`},{background:refresherBackground}]">
+					<view v-if="useRefresherStatusBarPlaceholder" class="zp-custom-refresher-status-bar-placeholder" :style="[{'height': `${statusBarHeight}px`}]" />
+					<!-- 下拉刷新view -->
+					<slot v-if="zSlots.refresherComplete&&refresherStatus===R.Complete" name="refresherComplete" />
+					<slot v-else-if="(nScopedSlots?nScopedSlots:$slots).refresher" :refresherStatus="R.Loading" name="refresher" />
+					<z-paging-refresh ref="refresh" v-else :status="R.Loading" :defaultThemeStyle="finalRefresherThemeStyle"
+						:defaultText="finalRefresherDefaultText" :pullingText="finalRefresherPullingText" :refreshingText="finalRefresherRefreshingText" :completeText="finalRefresherCompleteText" 
+						:defaultImg="refresherDefaultImg" :pullingImg="refresherPullingImg" :refreshingImg="refresherRefreshingImg" :completeImg="refresherCompleteImg" :refreshingAnimated="refresherRefreshingAnimated"
+						:showUpdateTime="showRefresherUpdateTime" :updateTimeKey="refresherUpdateTimeKey" :updateTimeTextMap="finalRefresherUpdateTimeTextMap"
+						:imgStyle="refresherImgStyle" :titleStyle="refresherTitleStyle" :updateTimeStyle="refresherUpdateTimeStyle" />
+				</component>
+				<template v-if="finalUseInnerList">
+					<component :is="nViewIs">
+						<slot name="header"/>
+					</component>	
+					<component :is="nViewIs" class="zp-list-cell" v-for="(item,index) in realTotalData" :key="finalCellKeyName.length?item[finalCellKeyName]:index">
+						<slot name="cell" :item="item" :index="index"/>
+					</component>
+					<component :is="nViewIs">
+						<slot name="footer"/>
+					</component>	
+				</template>
+				<template v-else>
+					<slot />
+				</template>
+				<!-- 全屏Loading -->
+				<component :is="nViewIs" v-if="showLoading&&zSlots.loading&&!loadingFullFixed" :class="{'z-paging-content-fixed':usePageScroll}" style="flex:1" :style="[nChatRecordRotateStyle]">
+					<slot name="loading" />
+				</component>
+				<!-- 上拉加载更多view -->
+				<component :is="nViewIs" v-if="!refresherOnly&&loadingMoreEnabled&&!showEmpty">
+					<view v-if="useChatRecordMode">
+						<view v-if="loadingStatus!==M.NoMore&&realTotalData.length">
+							<slot v-if="zSlots.chatLoading" name="chatLoading" />
+							<view v-else class="zp-chat-record-loading-container">
+								<text v-if="loadingStatus!==M.Loading" @click="_onScrollToUpper"
+									:class="defaultThemeStyle==='white'?'zp-loading-more-text zp-loading-more-text-white':'zp-loading-more-text zp-loading-more-text-black'">{{chatRecordLoadingMoreText}}</text>
+								<view>
+									<loading-indicator v-if="loadingStatus===M.Loading" class="zp-line-loading-image" animating />
+								</view>
+							</view>
+						</view>
+					</view>
+					<view :style="nLoadingMoreFixedHeight?{height:loadingMoreCustomStyle&&loadingMoreCustomStyle.height?loadingMoreCustomStyle.height:'80rpx'}:{}">
+						<slot v-if="showLoadingMoreDefault" name="loadingMoreDefault" />
+						<slot v-else-if="showLoadingMoreLoading" name="loadingMoreLoading" />
+						<slot v-else-if="showLoadingMoreNoMore" name="loadingMoreNoMore" />
+						<slot v-else-if="showLoadingMoreFail" name="loadingMoreFail" />
+						<z-paging-load-more @doClick="_onLoadingMore('click')" v-else-if="showLoadingMoreCustom" :zConfig="zLoadMoreConfig" />
+						<view v-if="safeAreaInsetBottom&&useSafeAreaPlaceholder" class="zp-safe-area-placeholder" :style="[{height:safeAreaBottom+'px'}]" />
+					</view>
+				</component>
+				<!-- 空数据图 -->
+				<component :is="nViewIs" v-if="showEmpty" :class="{'z-paging-content-fixed':usePageScroll}" :style="[{flex:emptyViewCenter?1:0},emptyViewSuperStyle,nChatRecordRotateStyle]">
+					<view :class="{'zp-empty-view':true,'zp-empty-view-center':emptyViewCenter}">
+						<slot v-if="zSlots.empty" name="empty" :isLoadFailed="isLoadFailed" />
+						<z-paging-empty-view v-else :emptyViewImg="finalEmptyViewImg" :emptyViewText="finalEmptyViewText" :showEmptyViewReload="finalShowEmptyViewReload" 
+						:emptyViewReloadText="finalEmptyViewReloadText" :isLoadFailed="isLoadFailed" :emptyViewStyle="emptyViewStyle" :emptyViewTitleStyle="emptyViewTitleStyle" 
+						:emptyViewImgStyle="emptyViewImgStyle" :emptyViewReloadStyle="emptyViewReloadStyle" :emptyViewZIndex="emptyViewZIndex" :emptyViewFixed="emptyViewFixed" 
+						@reload="_emptyViewReload" @viewClick="_emptyViewClick" />
+					</view>
+				</component>
+				<component is="header" v-if="!hideNvueBottomTag" ref="zp-n-list-bottom-tag" class="zp-n-list-bottom-tag"></component>
+			</component>
+			<view v-if="zSlots.right" class="zp-page-right">
+				<slot name="right" />
+			</view>
+		</component>
+		<!-- 底部固定的slot -->
+		<slot name="bottom" />
+		<!-- 点击返回顶部view -->
+		<view v-if="showBackToTopClass" :class="backToTopClass" :style="[finalBackToTopStyle]" @click.stop="_backToTopClick">
+			<slot v-if="zSlots.backToTop" name="backToTop" />
+			<image v-else class="zp-back-to-top-img" :src="backToTopImg.length?backToTopImg:base64BackToTop" />
+		</view>
+		<!-- 全屏Loading(铺满z-paging并固定) -->
+		<view v-if="showLoading&&zSlots.loading&&loadingFullFixed" class="zp-loading-fixed">
+			<slot name="loading" />
+		</view>
+	</component>
+	<!-- #endif -->
+</template>
+<!-- #ifdef APP-VUE || MP-WEIXIN || MP-QQ || H5 -->
+<script src="./wxs/z-paging-wxs.wxs" module="pagingWxs" lang="wxs"></script>
+<!-- #endif -->
+<script module="pagingRenderjs" lang="renderjs">
+	import pagingRenderjs from './wxs/z-paging-renderjs.js';
+	/**
+	 * z-paging 分页组件
+	 * @description 高性能,全平台兼容。支持虚拟列表,支持nvue、vue3
+	 * @tutorial https://z-paging.zxlee.cn
+	 * @notice 以下仅为部分常用属性、方法和事件,完整文档请查阅z-paging官网
+	 * @property {Number|String} default-page-no 自定义初始的pageNo,默认为1
+	 * @property {Number|String} default-page-size 自定义pageSize,默认为10
+	 * @property {Object} paging-style 设置z-paging的style,部分平台(如微信小程序)无法直接修改组件的style,可使用此属性代替
+	 * @property {String} height z-paging的高度,优先级低于pagingStyle中设置的height,传字符串,如100px、100rpx、100%
+	 * @property {String} width z-paging的宽度,优先级低于pagingStyle中设置的width,传字符串,如100px、100rpx、100%
+	 * @property {Boolean} use-page-scroll 使用页面滚动,默认为否
+	 * @property {Boolean} use-virtual-list 是否使用虚拟列表,默认为否
+	 * @property {Boolean} fixed z-paging是否使用fixed布局,若使用fixed布局,则z-paging的父view无需固定高度,z-paging高度默认为100%,默认为是(当使用内置scroll-view滚动时有效)
+	 * @property {Boolean} auto [z-paging]mounted后是否自动调用reload方法(mounted后自动调用接口),默认为是
+	 * @property {Boolean} use-chat-record-mode 使用聊天记录模式,默认为否
+	 * @event {Function} query 下拉刷新或滚动到底部时会自动触发此方法。z-paging加载时也会触发(若要禁止,请设置:auto="false")。pageNo和pageSize会自动计算好,直接传给服务器即可。
+	 * @example <z-paging ref="paging" v-model="dataList" @query="queryList"></z-paging>
+	 */
+	export default {
+		name:"z-paging",
+		// #ifdef APP-VUE || H5
+		mixins: [pagingRenderjs],
+		// #endif
+	}
+</script>
+<script src="./js/z-paging-main.js" />
+	
+<style scoped>
+	@import "./css/z-paging-main.css";
+	@import "./css/z-paging-static.css";
+</style>
diff --git a/uni_modules/z-paging/package.json b/uni_modules/z-paging/package.json
new file mode 100644
index 0000000..2afbbbc
--- /dev/null
+++ b/uni_modules/z-paging/package.json
@@ -0,0 +1,86 @@
+{
+  "id": "z-paging",
+  "name": "z-paging",
+  "displayName": "【z-paging下拉刷新、上拉加载】高性能,全平台兼容。支持虚拟列表,支持nvue、vue3",
+  "version": "2.6.2",
+  "description": "超简单、低耦合!使用wxs+renderjs实现。支持长列表优化,支持自定义下拉刷新、上拉加载更多,支持自动管理空数据图、点击返回顶部,支持聊天分页、本地分页,支持国际化等100+项配置",
+  "keywords": [
+    "下拉刷新",
+    "上拉加载",
+    "分页器",
+    "nvue",
+    "虚拟列表"
+],
+  "repository": "https://github.com/SmileZXLee/uni-z-paging",
+  "engines": {
+    "HBuilderX": "^3.0.7"
+  },
+"dcloudext": {
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": "393727164"
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/z-paging",
+    "type": "component-vue"
+  },
+  "uni_modules": {
+    "dependencies": [],
+    "encrypt": [],
+    "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",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y",
+		  "钉钉": "y",
+		  "快手": "y",
+		  "飞书": "y",
+		  "京东": "y"
+        },
+        "快应用": {
+          "华为": "y",
+          "联盟": "y"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/uni_modules/z-paging/readme.md b/uni_modules/z-paging/readme.md
new file mode 100644
index 0000000..bf21cd6
--- /dev/null
+++ b/uni_modules/z-paging/readme.md
@@ -0,0 +1,53 @@
+# z-paging
+
+<p align="center">
+    <img alt="logo" src="https://z-paging.zxlee.cn/img/title-logo.png" height="100" style="margin-bottom: 50px;">
+</p>
+
+[![version](https://img.shields.io/badge/version-2.6.2-blue)](https://github.com/SmileZXLee/uni-z-paging)
+[![license](https://img.shields.io/github/license/SmileZXLee/uni-z-paging)](https://en.wikipedia.org/wiki/MIT_License)
+
+### 文档地址:[https://z-paging.zxlee.cn](https://z-paging.zxlee.cn)
+
+### 更新组件前,请注意[版本差异](https://z-paging.zxlee.cn/start/upgrade-guide.html)
+
+***  
+### 功能&特点
+* 【配置简单】仅需两步(绑定网络请求方法、绑定分页结果数组)轻松完成完整下拉刷新,上拉加载更多功能。
+* 【低耦合,低侵入】分页自动管理。在page中无需处理任何分页相关逻辑,无需在data中定义任何分页相关变量,全由z-paging内部处理。
+* 【超灵活,支持各种类型自定义】支持自定义下拉刷新,自定义上拉加载更多等各种自定义效果;支持使用内置自动分页,同时也支持通过监听下拉刷新和滚动到底部事件自行处理;支持使用自带全屏布局规范,同时也支持将z-paging自由放在任意容器中。
+* 【功能丰富】支持国际化,支持自定义且自动管理空数据图,支持主题模式切换,支持本地分页,支持聊天分页模式,支持展示最后更新时间,支持吸顶效果,支持内部scroll-view滚动与页面滚动,支持一键滚动到顶部等诸多功能。
+* 【全平台兼容】支持vue、nvue,vue2、vue3,支持h5、app及各家小程序。
+* 【高性能】在app-vue、h5、微信小程序、QQ小程序上使用wxs+renderjs从视图层实现下拉刷新;支持虚拟列表,轻松渲染万级数据!
+
+*** 
+### 反馈qq群
+* 官方1群`已满`:[790460711](https://jq.qq.com/?_wv=1027&k=vU2fKZZH)
+
+* 官方2群:[371624008](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=avPmibADf2TNi4LxkIwjCE5vbfXpa-r1&authKey=dQ%2FVDAR87ONxI4b32Py%2BvmXbhnopjHN7%2FJPtdsqJdsCPFZB6zDQ17L06Uh0kITUZ&noverify=0&group_code=371624008)
+ 
+*** 
+
+### 预览
+
+***
+
+|                 自定义下拉刷新效果演示                  |                      滑动切换选项卡+吸顶演示                       |
+| :----------------------------------------------------------: | :----------------------------------------------------------: |
+| ![](https://z-paging.zxlee.cn/public/img/z-paging-demo5.gif) | ![](https://z-paging.zxlee.cn/public/img/z-paging-demo6.gif) |
+
+|                   聊天记录模式演示                    |                    虚拟列表(流畅渲染1万+条)演示                     |
+| :----------------------------------------------------------: | :----------------------------------------------------------: |
+| ![](https://z-paging.zxlee.cn/public/img/z-paging-demo7.gif) | ![](https://z-paging.zxlee.cn/public/img/z-paging-demo8.gif) |
+
+### 在线demo体验地址:
+
+* [https://demo.z-paging.zxlee.cn](https://demo.z-paging.zxlee.cn)
+
+| 扫码体验                                                     |
+| ------------------------------------------------------------ |
+| ![](https://z-paging.zxlee.cn/public/img/code.png) |
+
+### demo下载
+* 支持vue2&vue3的`选项式api`写法demo下载,请点击页面右上角的【使用HBuilderX导入示例项目】或【下载示例项目ZIP】。
+* 支持vue3的`组合式api`写法demo下载,请访问[github](https://github.com/SmileZXLee/uni-z-paging)。
\ No newline at end of file

--
Gitblit v1.9.3