guoyujia 8 months ago
parent
commit
5ad84d2996

+ 13 - 0
api/business/storageRetrieval.js

@@ -0,0 +1,13 @@
+import req from '@/utils/request.js'
+
+/**
+ * 查询零存零取
+ * @param {Object} data
+ */
+export function getStorageRetrievalList(data) {
+	return req.request({
+		url: '/business/storageRetrieval/list',
+		method: 'post',
+		data: data
+	})
+}

+ 6 - 0
pages.json

@@ -110,6 +110,12 @@
 				"navigationBarTitleText": "检查项选择"
 			}
 		},
+		{
+			"path": "pages/sorting/storageRetrieval",
+			"style": {
+				"navigationBarTitleText": "分选报工"
+			}
+		},
 		{
 			"path": "pages/sorting/consultation",
 			"style": {

+ 1 - 0
pages/firstInspection/index.vue

@@ -128,6 +128,7 @@
 			title: '加载中'
 		});
 		//quer.value.creatorId = store.userInfo.userId;
+		quer.value.deptId = store.curDeptDetails.deptId
 		quer.value.startTime = startTime.value;
 		quer.value.type = "firstArticleInspection"
 		getProcessInspecionList(quer.value).then(res => {

+ 46 - 46
pages/queryLotInfo/index.vue

@@ -400,51 +400,51 @@
 	//扫码
 	function handleScanCode() {
 		//引入原生插件
-		// const mpaasScanModule = uni.requireNativePlugin("Mpaas-Scan-Module");
-		// if (mpaasScanModule) {
-		// 	// 调用插件的 mpaasScan 方法
-		// 	mpaasScanModule.mpaasScan({
-		// 			// 扫码识别类型,参数可多选,qrCode、barCode,
-		// 			// 如不设置,默认识别所有扫码类型,可能有些许影响识别效率
-		// 			scanType: ["qrCode", "barCode"],
-		// 			// 是否隐藏相册,默认false不隐藏
-		// 			hideAlbum: false,
-		// 		},
-		// 		(ret) => {
-		// 			console.log(ret);
-		// 			let vehicleObj = {
-		// 				carrierCode: ret.resp_result
-		// 			};
-		// 			if (!vehicleObj.carrierCode || vehicleObj.carrierCode == "") {
-		// 				uni.showToast({
-		// 					icon: "none",
-		// 					title: "请扫载具码",
-		// 					duration: 1000
-		// 				})
-		// 				return;
-		// 			}
-		// 			getDayworkCarrierByCarrierCode({
-		// 				carrierCode: vehicleObj.carrierCode,
-		// 			}).then(response => {
-		// 				if (response.code == 200) {
-		// 					if (response.data.length > 0) {
-		// 						if (response.data.length > 1) {
-		// 							selectLotDialog.value.open(response.data);
-		// 						} else {
-		// 							handleDoIt(response.data[0])
-		// 						}
-		// 					} else {
-		// 						uni.showToast({
-		// 							icon: 'none',
-		// 							title: "该箱未绑定批次,请重新扫码",
-		// 							duration: 2000
-		// 						})
-		// 					}
-		// 				}
-		// 			})
-		// 		}
-		// 	);
-		// } else {
+		const mpaasScanModule = uni.requireNativePlugin("Mpaas-Scan-Module");
+		if (mpaasScanModule) {
+			// 调用插件的 mpaasScan 方法
+			mpaasScanModule.mpaasScan({
+					// 扫码识别类型,参数可多选,qrCode、barCode,
+					// 如不设置,默认识别所有扫码类型,可能有些许影响识别效率
+					scanType: ["qrCode", "barCode"],
+					// 是否隐藏相册,默认false不隐藏
+					hideAlbum: false,
+				},
+				(ret) => {
+					console.log(ret);
+					let vehicleObj = {
+						carrierCode: ret.resp_result
+					};
+					if (!vehicleObj.carrierCode || vehicleObj.carrierCode == "") {
+						uni.showToast({
+							icon: "none",
+							title: "请扫载具码",
+							duration: 1000
+						})
+						return;
+					}
+					getDayworkCarrierByCarrierCode({
+						carrierCode: vehicleObj.carrierCode,
+					}).then(response => {
+						if (response.code == 200) {
+							if (response.data.length > 0) {
+								if (response.data.length > 1) {
+									selectLotDialog.value.open(response.data);
+								} else {
+									handleDoIt(response.data[0])
+								}
+							} else {
+								uni.showToast({
+									icon: 'none',
+									title: "该箱未绑定批次,请重新扫码",
+									duration: 2000
+								})
+							}
+						}
+					})
+				}
+			);
+		} else {
 			// 测试时用
 			getDayworkCarrierByCarrierCode({
 				carrierCode: '000605'
@@ -465,7 +465,7 @@
 					}
 				}
 			})
-		// }
+		}
 	}
 
 	function handleDoIt(data) {

+ 258 - 5
pages/sorting/form.vue

@@ -62,6 +62,57 @@
 				</view> -->
 			</view>
 		</view>
+		<!-- 零存库部分 -->
+		<view class="title">零存库</view>
+		<view class="consultation-container ">
+			<view class="title unfit-title uni-row">
+				<view class="title">零取</view>
+				<view class="add-btn" v-if="Number(dayworkItem.status) < 3" style="background-color: #409eff;"  @click="handleAddLot">添加</view>
+			</view>
+				<view >
+					<zb-table v-if="Number(dayworkItem.status) < 3"
+					    :columns="column1"
+					    :stripe="true"
+						:fit="true"
+						@dele="dele"
+					    :data="retrievalInfo"></zb-table>
+						<zb-table v-else
+						    :columns="column2"
+						    :stripe="true"
+							:fit="true"
+							@dele="dele"
+						    :data="retrievalInfo"></zb-table>
+				<!-- <uni-table   ref="table" :loading="loading" border stripe  emptyText="暂无更多数据" >
+							<uni-tr >
+								<uni-th style="font-size: 25rpx;" width="atuo"   align="center">批次号</uni-th>
+								<uni-th style="font-size: 25rpx;" width="120"  align="center">数量</uni-th>
+								<uni-th v-if="Number(dayworkItem.status) < 3" style="font-size: 25rpx;" width="80"  align="center">操作</uni-th>
+							</uni-tr>
+							<uni-tr v-for="(item, index) in retrievalInfo" :key="index">
+								<uni-th style="font-size: 24rpx;" width="auto" align="center">{{ item.lotCode }}</uni-th>
+								<uni-th style="font-size: 25rpx;" width="120" align="center">
+									{{ item.storageNum }}
+								</uni-th>
+								<uni-th v-if="Number(dayworkItem.status) < 3 && item.status == 0" align="center" width="80">
+									<uni-icons  type="closeempty" size="22" @click="handleDelete(item)"></uni-icons>
+
+								</uni-th>
+							</uni-tr>
+						</uni-table> -->
+						</view>
+						<view v-if="saveFlag"  class='middle'>
+							<view class='segment'></view>
+							<view class='segment'></view>
+						</view>
+						<view v-if="saveFlag" class="title unfit-title uni-row">
+							<view class="title">零存</view>
+						</view>
+						<view v-if="saveFlag" class="save uni-row">
+							<text class="label">存入数量</text>
+							<input  class="number" type="number" v-if="!(storageInfo.status == 1 || Number(dayworkItem.status) >= 3 || storageInfo.id)" placeholder="请输入" v-model="storageNum" />
+							<span style="margin-left: 56rpx;flex: 1;" v-else>{{ storageNum }}</span>
+						</view>
+		</view>
 
 		<!-- 报工部分 -->
 		<view class="daywork-container">
@@ -126,18 +177,44 @@
 	import {
 		store
 	} from '@/store/index.js'
+	import {
+		timestampToTime,
+		toHHmmss
+	} from '@/utils/common.js'
 
 	const isEventTriggered = ref(false); // 创建一个标志位
 	const unfitInfos = ref([])
 	const consultations = ref([])
 	const dayworkInfo = ref({})
+	const retrievalInfo = ref([])
 	// 创建一个引用来存储最后一次请求的时间戳
 	const lastRequestTimestamp = ref(0);
 	const dayworkItem = ref({})
+	const saveFlag = ref(false)
+	const storageNum = ref(null)
+	const storageInfo = ref(null)
+	const column1 = [
+	    { name: 'lotCode', label: '批次号',align:'center'},
+	    { name: 'storageNum', label: '数量',align:'center' },
+		{ name: 'operation', type:'operation',label: '操作',align:'center',renders:[
+              {
+                name:'删除',
+                type:'warn',
+                func:"dele",
+				class:"buttonOp"
+              },
+            ]},
+	]
+	const column2 = [
+	    { name: 'lotCode', label: '批次号',align:'center'},
+	    { name: 'storageNum', label: '数量',align:'center' },
+	]
 
 	/***************************** 页面生命周期函数 *****************************/
+	onLoad(()=>{
+	})
 	onShow(() => {
-
+		uni.$off('addInfoEvent');
 	})
 	onMounted(() => {
 		const instance = getCurrentInstance().proxy
@@ -166,20 +243,67 @@
 			console.log(res)
 			if (res.code === 200) {
 				dayworkItem.value = res.data
+				//判断是否显示零存
+				if(dayworkItem.value.processStepNumber == dayworkInfo.value.processSequence[dayworkInfo.value.processSequence.length - 1].processStepNumber) {
+					saveFlag.value = true
+				}else{
+					saveFlag.value = false
+				}
 				console.log(dayworkItem.value)
 				if (dayworkItem.value.qualifiedNum === 0 && dayworkItem.value.rejectNum === 0) {
 					dayworkItem.value.qualifiedNum = res.data.prodNum
 				}
+				retrievalInfo.value = res.data.retrievalInfo
+				storageInfo.value = res.data.storageInfo
+				console.log(Object.keys(storageInfo.value).length === 0)
+				if(Object.keys(storageInfo.value).length !== 0) {
+					storageNum.value = storageInfo.value.storageNum
+				}
 				consultations.value = res.data.consults
 				unfitInfos.value = res.data.rejectList
 			} else {
 				uni.showToast({
-					icon: none,
+					icon: 'none',
 					title: res.message
 				})
 			}
 		})
 	}
+
+	const addInfo = (data) => {
+		data.forEach(item=>{
+			console.log(retrievalInfo.value)
+			retrievalInfo.value.push(item)
+		})
+		console.log(data)
+		uni.$off('addInfoEvent');
+	}
+	//添加零取批次
+	function handleAddLot() {
+		console.log('調用 handleAddLot')
+		uni.$on('addInfoEvent', (data) => {
+			addInfo(data.data)
+		})
+		console.log(dayworkItem.value)
+		const info = {
+			deptId:dayworkItem.value.deptId,
+			productId:dayworkItem.value.daywork.productId,
+			drawingNumber:dayworkItem.value.drawingNumber,
+			technologyVersion:dayworkItem.value.technologicalProcessDetail.technologyVersion,
+			retrievalLotId:dayworkItem.value.lotId,
+			hasAddedList : retrievalInfo.value
+		}
+		// 将 info 对象转换为 JSON 字符串
+const serializedData = JSON.stringify(info);
+
+// 对 JSON 字符串进行 URL 编码
+const encodedData = encodeURIComponent(serializedData);
+
+// 构建 URL,确保使用正确编码的数据
+uni.navigateTo({
+  url: `/pages/sorting/storageRetrieval?data=${encodedData}`
+});
+	}
 	const addUnfitInfo = (data) => {
 		console.log(data)
 		if (data.index > unfitInfos.value.length) {
@@ -194,6 +318,16 @@
 			unfitInfos.value.push(info)
 		}
 	}
+	function dele(ite,index) {
+		if(ite.status == 1){
+			uni.showToast({
+				icon: 'none',
+				title: '已被领取,不能删除'
+			})
+		}else{
+	  retrievalInfo.value.splice(index, 1);
+	  }
+	}
 	const addConsultation = (data) => {
 		const info = {
 			dayworkItemId: dayworkItem.value.id,
@@ -358,6 +492,14 @@
 	}
 
 	const validHandle = () => {
+		if(storageNum.value != null && storageNum.value<0) {
+			uni.showToast({
+				icon: 'none',
+				title: "存入数量应大于0",
+				duration: 2000
+			})
+			return false;
+		}
 		for (let i = 0; i < unfitInfos.value.length; i++) {
 			const e = unfitInfos.value[i]
 			if (e.rejectNum == null || e.rejectNum == 0) {
@@ -423,7 +565,37 @@ async function handleCheckStock() {
 		if(!checkStockResult ) { 
 			return;
 		}
-		console.log("777")
+		//零存数据
+	if(storageNum.value != null&& storageNum.value != "" ) {
+			if(Object.keys(storageInfo.value).length === 0){
+			storageInfo.value = {
+				productionPlanDetailId:dayworkItem.value.productionPlanDetailId,
+				productDescription:dayworkItem.value.productDescription,
+				drawingNumber:dayworkItem.value.drawingNumber,
+				lotId:dayworkItem.value.lotId,
+				lotCode:dayworkItem.value.lotCode,
+				deptId:dayworkItem.value.deptId,
+				productId:dayworkItem.value.daywork.productId,
+				technologyVersion:dayworkItem.value.technologicalProcessDetail.technologyVersion,
+				storageNum:storageNum.value,
+				storagerId:store.userInfo.userId,	
+			}
+			}
+			else{
+				storageInfo.value.storageNum = storageNum.value
+			}
+		}else{
+			storageInfo.value = null
+		}
+		//零取数据
+		if(retrievalInfo.value.length >0) {
+			retrievalInfo.value.forEach(item =>{
+				item.retrievalLotId = dayworkItem.value.lotId,
+				item.retrievalLotCode = dayworkItem.value.lotCode,
+				item.retrievalerId = store.userInfo.userId,
+				item.retrievalTime = timestampToTime(new Date())
+			})
+		}
 		const saveData = {
 			rejectList: unfitInfos.value,
 			consult: consultations.value,
@@ -431,7 +603,9 @@ async function handleCheckStock() {
 			prodNum: dayworkItem.value.prodNum,
 			rejectNum: dayworkItem.value.rejectNum,
 			qualifiedNum: dayworkItem.value.qualifiedNum,
-			remark: dayworkItem.value.remark
+			remark: dayworkItem.value.remark,
+			storageInfo:storageInfo.value,
+			retrievalInfo:retrievalInfo.value
 		}
 		const currentTime = Date.now();
 
@@ -445,6 +619,7 @@ async function handleCheckStock() {
 			})
 			return;
 		}
+		console.log(saveData)
 		finish(saveData).then(res => {
 			if (res.code === 200) {
 				uni.navigateBack()
@@ -460,6 +635,37 @@ async function handleCheckStock() {
 		if (!validHandle()) {
 			return
 		}
+		//零存数据
+	if(storageNum.value != null&& storageNum.value != "" ) {
+			if(Object.keys(storageInfo.value).length === 0){
+			storageInfo.value = {
+				productionPlanDetailId:dayworkItem.value.productionPlanDetailId,
+				productDescription:dayworkItem.value.productDescription,
+				drawingNumber:dayworkItem.value.drawingNumber,
+				lotId:dayworkItem.value.lotId,
+				lotCode:dayworkItem.value.lotCode,
+				deptId:dayworkItem.value.deptId,
+				productId:dayworkItem.value.daywork.productId,
+				technologyVersion:dayworkItem.value.technologicalProcessDetail.technologyVersion,
+				storageNum:storageNum.value,
+				storagerId:store.userInfo.userId,	
+			}
+			}
+			else{
+				storageInfo.value.storageNum = storageNum.value
+			}
+		}else{
+			storageInfo.value = null
+		}
+		//零取数据
+		if(retrievalInfo.value.length >0) {
+			retrievalInfo.value.forEach(item =>{
+				item.retrievalLotId = dayworkItem.value.lotId,
+				item.retrievalLotCode = dayworkItem.value.lotCode,
+				item.retrievalerId = store.userInfo.userId,
+				item.retrievalTime = timestampToTime(new Date())
+			})
+		}
 		const saveData = {
 			rejectList: unfitInfos.value,
 			consult: consultations.value,
@@ -467,8 +673,11 @@ async function handleCheckStock() {
 			prodNum: dayworkItem.value.prodNum,
 			rejectNum: dayworkItem.value.rejectNum,
 			qualifiedNum: dayworkItem.value.qualifiedNum,
-			remark: dayworkItem.value.remark
+			remark: dayworkItem.value.remark,
+			storageInfo:storageInfo.value,
+			retrievalInfo:retrievalInfo.value
 		}
+		console.log(saveData)
 		update(saveData).then(res => {
 			if (res.code === 200) {
 				uni.$emit("formBack")
@@ -485,6 +694,9 @@ async function handleCheckStock() {
 </script>
 
 <style lang="scss">
+	.buttonOp {
+		margin-top: 5px;
+	}
 	.page-container {
 		height: 100%;
 		background-color: #ececec;
@@ -495,6 +707,13 @@ async function handleCheckStock() {
 			margin: 24rpx 16rpx;
 		}
 	}
+	.add-btn {
+		padding: 12rpx 32rpx;
+		background-color: #a4adb3;
+		color: #ffffff;
+		border-radius: 12rpx;
+		font-size: 24rpx;
+	}
 
 	.lot-info {
 		margin: 32rpx 16rpx 0 16rpx;
@@ -513,6 +732,19 @@ async function handleCheckStock() {
 			color: #9f9f9f;
 		}
 	}
+	.middle {
+		display: flex;
+		flex-direction: row;
+		align-items: center;
+		justify-content: center
+	}
+	
+	.segment {
+		width: 80%;
+		background-color: rgba(213, 213, 213, 1);
+		border: 1rpx solid rgba(213, 213, 213, 1);
+		margin: 16px 0;
+	}
 
 	.unfit-title {
 		margin-bottom: 24rpx;
@@ -532,6 +764,24 @@ async function handleCheckStock() {
 			font-size: 24rpx;
 		}
 	}
+	
+	.save {
+		align-items: center;
+		padding-bottom: 32rpx;
+		justify-content: space-between;
+		input {
+			
+			height: 56rpx;
+			border: 1px solid #9f9f9f;
+			font-size: 28rpx;
+	
+			&.number {
+				width: 60%;
+				text-align: center;
+			}
+		}
+	}
+	
 
 	.unfit-container {
 		padding: 24rpx;
@@ -726,4 +976,7 @@ async function handleCheckStock() {
 			}
 		}
 	}
+	.zb-table .item-tr {
+		flex-direction: row;
+	}
 </style>

+ 169 - 0
pages/sorting/storageRetrieval.vue

@@ -0,0 +1,169 @@
+<template>
+	<view class="page-container uni-column">
+		<!-- 零存库部分 -->
+		<view class="title unfit-title uni-row">
+			<view class="title">零取</view>
+		</view>
+		<view class="consultation-container uni-column" style="margin-bottom: 120rpx;height: 90%;">
+			
+			<view style="width: 100%;height: 80%;">
+				<zb-table 
+				    :columns="column1"
+				    :stripe="true"
+					:fit="true"
+					@toggleRowSelection="selectionChange"
+				    :data="listData"></zb-table>
+<!-- 				<uni-table ref="table" :loading="loading" border stripe type="selection" emptyText="暂无更多数据"
+					@selection-change="selectionChange">
+					<uni-tr>
+						<uni-th style="font-size: 25rpx;" width="100" align="center">批次号</uni-th>
+						<uni-th style="font-size: 25rpx;" width="100" align="center">操作者</uni-th>
+						<uni-th style="font-size: 25rpx;" width="80" align="center">数量</uni-th>
+					</uni-tr>
+					<uni-tr v-for="(item, index) in listData" :key="index">
+						<uni-th style="font-size: 24rpx;" width="100" align="center">{{ item.lotCode }}</uni-th>
+						<uni-th style="font-size: 24rpx;" width="100" align="center">{{ item.storagerName }}</uni-th>
+						<uni-th style="font-size: 24rpx;" width="80" align="center">{{ item.storageNum }}</uni-th>
+
+					</uni-tr>
+				</uni-table> -->
+				</view>
+				</view>
+			</view>
+			<view class="bottom uni-row">
+				<button class="start-batch-btn" style="margin-right: 10rpx;" type="primary"
+				  :disabled="selections.length == 0"	@click="handleAdd">确认取出</button>
+			</view>
+</template>
+
+<script setup>
+	import {
+		ref
+	} from 'vue'
+	import {
+		onMounted,
+		getCurrentInstance
+	} from 'vue';
+
+	import {
+		getStorageRetrievalList
+	} from '@/api/business/storageRetrieval.js'
+	import {
+		onLoad,
+		onReady,
+		onUnload,
+		onShow
+	} from '@dcloudio/uni-app'
+	import {
+		store
+	} from '@/store/index.js'
+
+	const selections = ref([])
+	const listData = ref([])
+	const column1 = [
+		{ type:'selection', width:50 },
+	    { name: 'lotCode', label: '批次号',align:'center'},
+	    { name: 'storagerName', label: '操作者',align:'center' },
+{ name: 'storageNum', label: '数量',align:'center' },
+	]
+
+	/***************************** 页面生命周期函数 *****************************/
+
+	onLoad((options) => {
+		 const data = decodeURIComponent(options.data);
+		
+		  // 将解码后的字符串转换回对象
+		  const lotInfo = JSON.parse(data);
+		console.log(lotInfo)
+		init(lotInfo)
+		})
+
+	/***************************** 定义了一些方法 *****************************/
+	const init = (data) => {
+		console.log(data)
+		getStorageRetrievalList(data).then(res =>{
+			listData.value = res.rows
+		})
+	}
+	function selectionChange(checked,arr) {
+		console.log(checked,arr)
+		 getSelectionList(arr)
+	}
+	function getSelectionList(data) {
+		selections.value = data
+		console.log(selections.value)
+	}
+	//选择带回
+	function handleAdd() {
+		uni.$emit('addInfoEvent', {
+			data:selections.value
+		})
+		uni.navigateBack()
+	}
+</script>
+
+<style lang="scss">
+	.unfit-title{
+		height: 30rpx;
+		position: fixed;
+		top: 30rpx;
+	}
+	.page-container {
+		height: 90%;
+		background-color: #ffffff;
+		font-size: 28rpx;
+
+		>.title {
+			position: relative;
+			top: 0;
+			font-weight: 700;
+			margin: 24rpx 16rpx;
+		}
+	}
+
+	.unfit-title {
+		margin-bottom: 24rpx;
+		justify-content: space-between;
+		align-items: center;
+
+		text {
+			font-size: 28rpx;
+			font-weight: 700;
+		}
+
+	}
+
+	.bottom {
+		height: 10%;
+		position: fixed;
+		right: 0;
+		bottom: 0;
+		left: 0;
+		height: 100rpx;
+		border-top: 1px solid #999999;
+		padding: 16rpx 32rpx;
+		align-items: center;
+		background-color: #fff;
+		justify-content: space-evenly;
+		z-index: 99;
+
+		.start-batch-btn {
+			flex: 1;
+			height: 80rpx;
+			line-height: 80rpx;
+			border-radius: 8rpx;
+			color: #FFFFFF;
+			font-size: 28rpx;
+		}
+	}
+	.consultation-container {
+		margin: 0 16rpx;
+		padding: 24rpx;
+		background-color: #ffffff;
+		border-radius: 8rpx;
+	
+	}
+	.zb-table .item-tr {
+		flex-direction: row;
+	}
+</style>

+ 106 - 0
uni_modules/zb-table/changelog.md

@@ -0,0 +1,106 @@
+## 1.2.18(2023-06-01)
+更新
+## 1.2.16(2023-05-10)
+增加单元格点击事件
+完善文档
+增加示例
+## 1.2.15(2022-08-25)
+优化部分细节
+## 1.2.14(2022-04-25)
+修改vue 3 报错小程序Generated an empty chunk: "uni_modules/zb-table/components/zb-table/js/util"
+## 1.2.13(2022-04-22)
+增加图片宽度设置
+## 1.2.12(2022-04-22)
+修复pc端 滚动条占位问题
+## 1.2.11(2022-04-22)
+增加多图片展示
+## 1.2.10(2022-04-19)
+版本解决冲突
+## 1.2.9(2022-04-19)
+暂时去掉多级表头...有着某些问题,正在修复中
+## 1.1.9(2022-04-19)
+暂时去掉多级表头...有着某些问题,正在修复中
+## 1.1.23(2022-04-19)
+暂时去掉多级表头,有着某些问题,修复中。。。
+## 1.1.22(2022-04-19)
+暂时去掉多级表头,存在某些问题 ,正在修复中
+## 1.1.21(2022-03-29)
+优化数字问题
+## 1.1.20(2022-03-29)
+优化按钮,可以自定义按钮,自定义添加class
+## 1.1.19(2022-03-28)
+进行优化加载
+## 1.1.18(2022-03-28)
+修复pc端滚动条问题
+## 1.1.17(2022-03-25)
+修改 数据回显的时候,全选框没有选中效果
+## 1.1.16(2022-03-25)
+新增:table属性 cell-style 修改单元格样式
+## 1.1.15(2022-03-23)
+fix:支付宝小程序上拉加载e.detail 没有值导致上拉加载失效 ,已修复
+## 1.1.14(2022-03-23)
+fix: 支付宝小程序左右无法滑动的问题
+## 1.1.13(2022-03-21)
+fix:英文宽度自适应问题
+## 1.1.12(2022-03-20)
+修改自适应宽度问题
+## 1.1.11(2022-03-19)
+增加上拉加载功能
+## 1.1.10(2022-03-18)
+修改合计不更新问题
+## 1.1.9(2022-03-16)
+优化css 样式
+## 1.1.8(2022-03-16)
+增加表尾合计行
+## 1.1.7(2022-03-15)
+修改css样式
+## 1.1.6(2022-03-14)
+进行代码优化
+## 1.1.5(2022-03-12)
+更新一个操作按钮的时候 报错问题,进行代码优化
+## 1.1.4(2022-03-12)
+增加图片统一高度
+## 1.1.3(2022-03-12)
+增加图片地址 ,并且图片支持预览功能
+## 1.1.2(2022-03-11)
+新增默认 是否选中功能,进行优化
+## 1.1.1(2022-03-10)
+新增单击事件
+## 1.1.0(2022-03-10)
+- 增加单击事件
+
+## 1.1.0(2022-03-10)
+- 增加checkbox功能 ,进行优化
+
+## 1.0.11(2022-03-09)
+- 修改小程序中排序问题
+
+## 1.0.10(2022-03-09)
+- 做了兼容性处理
+
+## 1.0.8(2022-03-09)
+- 进行优化滚动防止 多次计算
+
+## 1.0.7(2022-03-09)
+- 修改一些问题 新增过滤器
+
+## 1.0.6(2022-03-08)
+- 修改样式 按钮自适应宽度
+
+## 1.0.5(2022-03-08)
+- 新增按钮 修改问题
+
+## 1.0.4(2022-03-04)
+- 增加空占位符"--"
+
+## 1.0.3(2022-03-02)
+- 新增表格斑马纹配置、列宽配置、表头显示配置
+
+## 1.0.2(2022-03-02)
+- 新增排序功能,优化样式
+
+## 1.0.1(2022-03-01)
+- 可以传入动态数据,可以对左边列表进行是否固定首列
+
+## 1.0.0(2022-03-01)
+- 初始化

+ 180 - 0
uni_modules/zb-table/components/zb-table/components/table-checkbox.vue

@@ -0,0 +1,180 @@
+<template>
+	<view class="uni-table-checkbox" @click.stop="selected">
+		<view v-if="!indeterminate" class="checkbox__inner" :class="{'is-checked':isChecked,'is-disable':isDisabled}">
+			<view class="checkbox__inner-icon"></view>
+		</view>
+		<view v-else class="checkbox__inner checkbox--indeterminate">
+			<view class="checkbox__inner-icon"></view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		name: 'TableCheckbox',
+		emits:['checkboxSelected'],
+		props: {
+			indeterminate: {
+				type: Boolean,
+				default: false
+			},
+			checked: {
+				type: [Boolean,String],
+				default: false
+			},
+			disabled: {
+				type: Boolean,
+				default: false
+			},
+			index: {
+				type: Number,
+				default: -1
+			},
+			cellData: {
+				type: Object,
+				default () {
+					return {}
+				}
+			}
+		},
+		watch:{
+			checked(newVal){
+				if(typeof this.checked === 'boolean'){
+					this.isChecked = newVal
+				}else{
+					this.isChecked = true
+				}
+			},
+			indeterminate(newVal){
+				this.isIndeterminate = newVal
+			}
+		},
+		data() {
+			return {
+				isChecked: false,
+				isDisabled: false,
+				isIndeterminate:false
+			}
+		},
+		created() {
+			if(typeof this.checked === 'boolean'){
+				this.isChecked = this.checked
+			}
+			this.isDisabled = this.disabled
+		},
+		methods: {
+			selected() {
+				if (this.isDisabled) return
+				this.isIndeterminate = false
+				this.isChecked = !this.isChecked
+        console.log('===',this.indeterminate,this.isChecked)
+				this.$emit('checkboxSelected', {
+					checked: this.isChecked,
+					data: this.cellData
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	$checked-color: #007aff;
+	$border-color: #DCDFE6;
+	$disable:0.4;
+
+	.uni-table-checkbox {
+		display: flex;
+		flex-direction: row;
+		align-items: center;
+		justify-content: center;
+		position: relative;
+		margin: 5px 0;
+		cursor: pointer;
+
+		// 多选样式
+		.checkbox__inner {
+			/* #ifndef APP-NVUE */
+			flex-shrink: 0;
+			box-sizing: border-box;
+			/* #endif */
+			position: relative;
+			width: 16px;
+			height: 16px;
+			border: 1px solid $border-color;
+			border-radius: 2px;
+			background-color: #fff;
+			z-index: 1;
+
+			.checkbox__inner-icon {
+				position: absolute;
+				/* #ifdef APP-NVUE */
+				top: 2px;
+				/* #endif */
+				/* #ifndef APP-NVUE */
+				top: 2px;
+				/* #endif */
+				left: 5px;
+				height: 7px;
+				width: 3px;
+				border: 1px solid #fff;
+				border-left: 0;
+				border-top: 0;
+				opacity: 0;
+				transform-origin: center;
+				transform: rotate(45deg);
+				box-sizing: content-box;
+			}
+
+			&.checkbox--indeterminate {
+				border-color: $checked-color;
+				background-color: $checked-color;
+
+				.checkbox__inner-icon {
+					position: absolute;
+					opacity: 1;
+					transform: rotate(0deg);
+					height: 2px;
+					top: 0;
+					bottom: 0;
+					margin: auto;
+					left: 0px;
+					right: 0px;
+					bottom: 0;
+					width: auto;
+					border: none;
+					border-radius: 2px;
+					transform: scale(0.5);
+					background-color: #fff;
+				}
+			}
+			&:hover{
+				border-color: $checked-color;
+			}
+			// 禁用
+			&.is-disable {
+				/* #ifdef H5 */
+				cursor: not-allowed;
+				/* #endif */
+				background-color: #F2F6FC;
+				border-color: $border-color;
+			}
+
+			// 选中
+			&.is-checked {
+				border-color: $checked-color;
+				background-color: $checked-color;
+
+				.checkbox__inner-icon {
+					opacity: 1;
+					transform: rotate(45deg);
+				}
+
+				// 选中禁用
+				&.is-disable {
+					opacity: $disable;
+				}
+			}
+
+		}
+	}
+</style>

+ 78 - 0
uni_modules/zb-table/components/zb-table/components/table-h5-summary.vue

@@ -0,0 +1,78 @@
+<template>
+  <view class="table-h5-footer top-header-uni" :style="{paddingRight:`${scrollbarSize}px`}">
+    <scroll-view class="zb-table-headers"
+                 @scroll="handleFooterTableScrollLeft"
+                 scroll-x="true"
+                 scroll-y="false"
+                 id="tableFooterHeaders"
+                 scroll-anchoring="true"
+                 :scroll-left="headerFooterTableLeft"
+                 style="padding-bottom: 0px;
+						background: #fafafa;height: 100%">
+      <view class="zb-table-fixed" >
+        <view class="zb-table-thead" style="position: relative;" >
+          <view class="item-tr">
+            <view
+                class="item-th"
+                :style="{
+	                              width:`${item.width?item.width:'100'}px`,
+															  flex:index===transColumns.length-1?1:'none',
+															  minWidth:`${item.width?item.width:'100'}px`,
+															  borderRight:`${border?'1px solid #e8e8e8':''}`,
+															  borderTop:`${border?'1px solid #e8e8e8':''}`,
+															  textAlign:item.align||'left'
+														  }"
+                v-for="(item,index) in transColumns" :key="index">
+              {{ sums[index] }}
+            </view>
+          </view>
+        </view>
+      </view>
+    </scroll-view>
+  </view>
+</template>
+<script>
+import summary from '../js/summary.js'
+export default {
+  name:'table-footer',
+  mixins:[summary],
+}
+</script>
+<style lang="scss" scoped>
+.table-h5-footer {
+  background: #fafafa;
+  /*每个页面公共css */
+  scroll-view ::-webkit-scrollbar {
+    display: none !important;
+    width: 0 !important;
+    height: 0 !important;
+    -webkit-appearance: none;
+    background: transparent;
+  }
+  //第二种
+  ::-webkit-scrollbar{
+    display: none;
+  }
+  .item-tr{
+    display: flex;
+  }
+  .item-th{
+    padding-left: 8px;
+    line-height: 39px;
+    height: 40px;
+    //display: flex;
+    //align-items: center;
+    box-sizing: border-box;
+    flex-shrink: 0;
+    width: 100px;
+    padding-right: 20px;
+    word-break: keep-all;
+    white-space: nowrap;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    overflow-wrap: break-word;
+    border-bottom: 1px solid #e8e8e8;
+  }
+
+}
+</style>

+ 59 - 0
uni_modules/zb-table/components/zb-table/components/table-side-summary.vue

@@ -0,0 +1,59 @@
+<template>
+  <view class="zb-table-header" style="display: flex;" >
+    <view class="item-tr" >
+      <view class='item-td'
+            :style="{
+	                       width:`${item.width?item.width:'100'}px`,
+	                       borderRight:`${border?'1px solid #e8e8e8':''}`,
+	                       textAlign:item.align||'left'
+	                      }"
+            :key="`15255966555${index}`"
+            v-for="(item,index) in fixedLeftColumns">
+        <template >
+          {{sums[index]}}
+        </template>
+      </view>
+    </view>
+  </view>
+
+</template>
+<script>
+import summary from '../js/summary.js'
+export default {
+  mixins:[summary]
+}
+</script>
+<style lang="scss" scoped>
+.zb-table-header {
+  overflow: hidden;
+  background: #fafafa;
+  .item-th{
+    padding-left: 8px;
+    line-height: 39px;
+    height: 40px;
+    //display: flex;
+    //align-items: center;
+    box-sizing: border-box;
+  }
+}
+.item-tr{
+  display: flex;
+  box-sizing: border-box;
+}
+.item-td{
+  flex-shrink: 0;
+  width: 100px;
+  padding-left: 8px;
+  height: 40px;
+  line-height: 40px;
+  padding-right: 20px;
+  box-sizing: border-box;
+  word-break: keep-all;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  overflow-wrap: break-word;
+  border-bottom: 1px solid #e8e8e8;
+  background: rgb(250, 250, 250);
+}
+</style>

+ 77 - 0
uni_modules/zb-table/components/zb-table/components/table-summary.vue

@@ -0,0 +1,77 @@
+<template>
+  <view class="zb-table-footer" style="height: 40px;">
+    <view class="zb-table-fixed" >
+      <view class="zb-table-thead" style="position: relative;" >
+        <view class="item-tr">
+          <view
+              :class="['item-th',index <fixedLeftColumns.length&&'zb-stick-side']"
+              :style="{
+	                              left:`${item.left}px`,
+	                              width:`${item.width?item.width:'100'}px`,
+															  flex:index===transColumns.length-1?1:'none',
+															  minWidth:`${item.width?item.width:'100'}px`,
+															   borderRight:`${border?'1px solid #e8e8e8':''}`,
+															  borderTop:`${border?'1px solid #e8e8e8':''}`,
+															   textAlign:item.align||'left'
+														  }"
+              v-for="(item,index) in transColumns" :key="index">
+            <template>
+              {{ sums[index]||item.emptyString }}
+            </template>
+          </view>
+        </view>
+      </view>
+    </view>
+  </view>
+</template>
+<script>
+  import summary from '../js/summary.js'
+  export default {
+    mixins:[summary]
+  }
+</script>
+<style lang="scss" scoped>
+  .zb-table-footer {
+    background: #fafafa;
+    width: fit-content;
+    min-width: 100%;
+    position: sticky;
+    bottom: 0;
+    z-index: 2;
+    .item-tr{
+      display: flex;
+      min-width: 100%;
+    }
+    .item-th{
+      padding-left: 8px;
+      line-height: 39px;
+      height: 40px;
+      //display: flex;
+      //align-items: center;
+      box-sizing: border-box;
+      flex-shrink: 0;
+      width: 100px;
+      padding-right: 20px;
+      word-break: keep-all;
+      white-space: nowrap;
+      overflow: hidden;
+      text-overflow: ellipsis;
+      overflow-wrap: break-word;
+      border-bottom: 1px solid #e8e8e8;
+    }
+    .zb-table-fixed{
+      min-width: 100%;
+
+    }
+    .zb-stick-side{
+      position: sticky;
+      bottom:0 ;
+      left: 0;
+      z-index: 2;
+      //border-right: solid 1rpx #dbdbdb;
+      box-sizing: border-box;
+      background: #fafafa;
+      //box-shadow: 6px 0 6px -4px #ccc;
+    }
+  }
+</style>

+ 50 - 0
uni_modules/zb-table/components/zb-table/components/zb-load-more.vue

@@ -0,0 +1,50 @@
+<template >
+  <view class="zb-load-more">
+    <image :src="base64Flower" style="" class="loading-custom-image"></image>
+    <text>正在加载中...</text>
+  </view>
+</template>
+<script>
+const 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';
+export default {
+  data(){
+    return{
+      base64Flower
+    }
+  }
+}
+</script>
+<style lang="scss" scoped>
+.zb-load-more {
+  width: 100%;
+  position: absolute;
+  bottom: 0;
+  left: 0;
+  z-index: 999;
+  background: white;
+  display: flex;
+  height: 40px;
+  flex-shrink: 0;
+  align-items: center;
+  justify-content: center;
+  .loading-custom-image{
+    color: #a4a4a4;
+    margin-right: 8rpx;
+    width: 24px;
+    height: 24px;
+    /* #ifndef APP-NVUE */
+    animation: loading-circle 1s linear infinite;
+    /* #endif */
+  }
+  @keyframes loading-circle {
+    0% {
+      -webkit-transform: rotate(0deg);
+      transform: rotate(0deg);
+    }
+    100% {
+      -webkit-transform: rotate(360deg);
+      transform: rotate(360deg);
+    }
+  }
+}
+</style>

+ 88 - 0
uni_modules/zb-table/components/zb-table/js/summary.js

@@ -0,0 +1,88 @@
+export default {
+    props:{
+        scrollbarSize:{
+            type:Number,
+            default:0
+        },
+        fixedLeftColumns:{
+            type:Array,
+            default:()=>[]
+        },
+        data:{
+            type:Array,
+            default:()=>[]
+        },
+        transColumns:{
+            type:Array,
+            default:()=>[]
+        },
+        border:{
+            type:Boolean,
+            default:false
+        },
+        showSummary:{
+            type:Boolean,
+            default:false
+        },
+        summaryMethod:{
+            type:Function
+        },
+        sumText:{
+            type:String,
+            default:'合计'
+        },
+        headerFooterTableLeft:{
+            type:Number,
+            default:0
+        },
+        handleFooterTableScrollLeft:Function,
+    },
+    data(){
+        return{
+            sums:[]
+        }
+    },
+    watch:{
+        'data':{
+            deep:true,
+            immediate:true,
+            handler(newValue,oldValue){
+                let sums = [];
+                if (this.summaryMethod) {
+                    sums = this.summaryMethod({ columns: this.transColumns, data: this.data });
+                } else {
+                    this.transColumns.forEach((column, index) => {
+                        if (index === 0) {
+                            sums[index] = this.sumText;
+                            return;
+                        }
+                        const values = this.data.map(item => Number(item[column.name]));
+                        const precisions = [];
+                        let notNumber = true;
+                        values.forEach(value => {
+                            if (!isNaN(value)) {
+                                notNumber = false;
+                                let decimal = ('' + value).split('.')[1];
+                                precisions.push(decimal ? decimal.length : 0);
+                            }
+                        });
+                        const precision = Math.max.apply(null, precisions);
+                        if (!notNumber) {
+                            sums[index] = values.reduce((prev, curr) => {
+                                const value = Number(curr);
+                                if (!isNaN(value)) {
+                                    return parseFloat((prev + curr).toFixed(Math.min(precision, 20)));
+                                } else {
+                                    return prev;
+                                }
+                            }, 0);
+                        } else {
+                            sums[index] = '';
+                        }
+                    });
+                }
+                this.sums = sums
+            },
+        }
+    }
+}

+ 51 - 0
uni_modules/zb-table/components/zb-table/js/util.js

@@ -0,0 +1,51 @@
+/**
+ * 获取滚动条宽度
+ */
+let cached = undefined;
+
+export const getScrollbarSize = fresh => {
+	// #ifdef H5
+	
+    if (fresh || cached === undefined) {
+        let inner = document.createElement("div");
+        let innerStyle = inner.style;
+
+        innerStyle.width = "100%";
+        innerStyle.height = "200px";
+
+        let outer = document.createElement("div");
+        let outerStyle = outer.style;
+
+        outerStyle.position = "absolute";
+        outerStyle.top = 0;
+        outerStyle.left = 0;
+        outerStyle.pointerEvents = "none";
+        outerStyle.width = "200px";
+        outerStyle.height = "150px";
+        outerStyle.visibility = "hidden";
+
+        outer.appendChild(inner);
+        document.body.appendChild(outer);
+
+        // 设置子元素超出部分隐藏
+        outerStyle.overflow = "hidden";
+
+        let width1 = inner.offsetWidth;
+
+        // 设置子元素超出部分滚动
+        outer.style.overflow = "scroll";
+
+        let width2 = inner.offsetWidth;
+
+        if (width1 === width2) {
+            width2 = outer.clientWidth;
+        }
+
+        document.body.removeChild(outer);
+
+        cached = width1 - width2;
+    }
+	//#endif
+
+    return cached;
+};

+ 1342 - 0
uni_modules/zb-table/components/zb-table/zb-table.vue

@@ -0,0 +1,1342 @@
+<template>
+	<!-- #ifdef H5 || APP-PLUS -->
+	<view :class="['zb-table','zb-table-fixed-header',!border&&(bodyTableLeft>50||headerTableLeft>50)&&'scroll-left-fixed']">
+	  <view class="zb-table-content" style="flex: 1">
+	    <view class="zb-table-scroll" style="height: 100%;">
+	      <template v-if="showHeader">
+	        <view class="zb-table-header top-header-uni"
+          >
+	          <scroll-view class="zb-table-headers"
+	                       @scroll="handleTableScrollLeft"
+	                       scroll-x="true"
+	                       scroll-y="false"
+	                       id="tableHeaders"
+	                       scroll-anchoring="true"
+	                       :scroll-left="headerTableLeft"
+	                       style="
+						height: 100%">
+
+	            <view class="zb-table-fixed" >
+	              <view class="zb-table-thead" style="position: relative;" >
+	                <view class="item-tr">
+	                  <view
+	                      @click.stop="sortAction(item,index)"
+	                      class="item-th"
+	                      :style="[{
+	                              width:`${item.width?item.width:'100'}px`,
+								  flex:index===transColumns.length-1?1:'none',
+								  minWidth:`${item.width?item.width:'100'}px`,
+								  borderRight:`${border?'1px solid #e8e8e8':''}`,
+
+								  borderTop:`${border?'1px solid #e8e8e8':''}`,
+								  textAlign:item.align||'left'
+							  },getHeaderCellStyle(item,index)]"
+	                      v-for="(item,index) in transColumns" :key="index">
+                      <template v-if="item.type==='selection'">
+                        <view class="checkbox-item">
+                          <tableCheckbox
+                              :indeterminate="indeterminate" :checked="checkedAll" @checkboxSelected="checkboxSelectedAll"></tableCheckbox>
+                        </view>
+                      </template>
+                      <template v-else>
+                        {{ item.label }}
+                        <view class="sorter-table" v-if="item.sorter">
+                          <view :class="['sorter-table-icon',item.sorterMode==='_asc'&&`sorting${item.sorterMode||''}`]"></view>
+                          <view :class="['sorter-table-icon',item.sorterMode==='_desc'&&`sorting${item.sorterMode||''}`]"></view>
+                        </view>
+                      </template>
+
+                    </view>
+                    <view
+                        v-if="scrollbarSize"
+                        class="item-th "
+                        :style="{
+
+                           borderTop:`${border?'1px solid #e8e8e8':''}`,
+                                padding:0,
+                                width:`${scrollbarSize}px`,
+                              }">
+                    </view>
+	                </view>
+	              </view>
+	            </view>
+	          </scroll-view>
+	        </view>
+	      </template>
+	      <template v-if="!data.length">
+	        <view class="no-data">暂无数据~~</view>
+	      </template>
+	      <scroll-view
+            class="zb-table-body" ref="tableBody"	scroll-x="true"	scroll-y="true"	id="tableBody"
+	                   :lower-threshold="40"
+	                   :upper-threshold="10"
+                     @scrolltolower="scrolltolower"
+	                   @scrolltoupper="(e)=>debounce(scrollToLeft)(e)"
+                     @scroll="handleBodyScroll"	:scroll-left="bodyTableLeft"	:scroll-top="bodyScrollTop"
+                     :style=" `height: calc(100% - ${showSummary?80:40}px)`" >
+	          <view class="zb-table-fixed">
+	            <view class="zb-table-tbody">
+	              <view  :class="['item-tr',highlight&&isHighlight(item,index)?'current-row':'']"
+                       @click.stop="rowClick(item,index)"
+	                     v-for="(item,index) in transData" :key="item.key" >
+	                <view
+	                    :style="[{
+							        width:`${ite.width?ite.width:'100'}px`,
+										  flex:i===transColumns.length-1?1:'none',
+										  minWidth:`${ite.width?ite.width:'100'}px`,
+										  borderRight:`${border?'1px solid #e8e8e8':''}`,
+											textAlign:ite.align||'left',
+									  },cellStyle&&getCellStyle(item,ite,index,i)]"
+                      @click="cellClick(item,index,ite)"
+	                    :class="['item-td',stripe?(index % 2) != 0?'odd':'even':'']"
+	                    v-for="(ite,i) in transColumns" :key="i">
+	                  <template  v-if="ite.type==='operation'">
+	                    <view style="display: flex;align-items: center;height: 100%">
+	                      <view
+                            v-for="ren,ind in permission(item,ite.renders,index)"
+	                          :key="ind"
+	                          @click.stop="$emit(ren.func,item,index)"
+	                          :style="{
+	                          display:'flex',
+	                          alignItems: 'center',
+	                          marginRight:ite.renders.length>1?'8px':'0'
+	                        }">
+                          <template v-if="ren.type==='custom'">
+                            <view :class="ren.class||''" style="cursor: pointer">
+                              {{ren.name}}
+                            </view>
+                          </template>
+                          <template v-else>
+                            <button
+                                :class="ren.class||''"
+                                :type="ren.type||'primary'" :size="ren.size||'mini'">{{ren.name}}</button>
+                          </template>
+	                      </view>
+	                    </view>
+	                  </template>
+                    <template v-else-if="ite.type==='selection'">
+                      <view class="checkbox-item">
+                        <tableCheckbox @checkboxSelected="(e)=>checkboxSelected(e,item)" :cellData="item" :checked="item.checked"/>
+                      </view>
+                    </template>
+                    <template v-else-if="ite.type==='index'">
+                      {{index+1}}
+                    </template>
+                  <template v-else-if="ite.type==='img'">
+                    <view class="checkbox-item">
+                      <template  v-if="item[ite.name]">
+                        <image
+                            @click.stop="previewImage(item,item[ite.name],iImage)"
+                            v-for="iImageTem,iImage in imgs(item[ite.name])"
+                            :show-menu-by-longpress="false"
+                            :key="iImage"
+                            :src="iImageTem" style="width: 40px;height:30px; " mode="aspectFit"></image>
+                      </template>
+                    <text v-else>{{ite.emptyString}}</text>
+                    </view>
+                  </template>
+	                  <template  v-else>
+<!--                      {{ ite.filters?itemFilter(item,ite):(item[ite.name]==null||item[ite.name]==='')?ite.emptyString:item[ite.name] }}-->
+                      {{ ite.filters?itemFilter(item,ite):formatterAction(item,ite,index,i) }}
+	                  </template>
+	                </view>
+	              </view>
+	            </view>
+	          </view>
+	        </scroll-view>
+       <table-h5-summary
+           :scrollbarSize="scrollbarSize"
+           :data="data"
+           :handleFooterTableScrollLeft="handleFooterTableScrollLeft"
+           :headerFooterTableLeft="headerFooterTableLeft"
+           v-if="showSummary"
+           :showSummary="showSummary"
+           :transColumns="transColumns"
+           :border="border"
+           :summary-method="summaryMethod"
+           :sumText="sumText"
+           :fixedLeftColumns="fixedLeftColumns"/>
+	    </view>
+	    <view class="zb-table-fixed-left"
+            v-if="isFixedLeft"
+            :style=" {height:  `calc(100% - ${scrollbarSize}px)`}"
+      >
+	      <template v-if="showHeader">
+	        <view class="zb-table-header" style="display: flex">
+	          <view class="item-tr"
+                  style=""
+                  @click.stop="rowClick(item,index)"
+                  v-for="(item,index) in fixedLeftColumns" :key="index">
+	            <view
+
+	                :style="{
+	               width:`${item.width?item.width:'100'}px`,
+	               borderRight:`${border?'1px solid #e8e8e8':''}`,
+	               borderTop:`${border?'1px solid #e8e8e8':''}`,
+                textAlign:item.align||'left'
+	            }"
+	                @click.stop="sortAction(item,index)"
+	                class="item-th"
+	            >
+                <template v-if="item.type==='selection'">
+                  <view class="checkbox-item">
+                    <tableCheckbox
+                        :indeterminate="indeterminate" :checked="checkedAll" @checkboxSelected="checkboxSelectedAll"></tableCheckbox>
+                  </view>
+                </template>
+                <template v-else>
+                  {{ item.label }}
+                  <view class="sorter-table" v-if="item.sorter">
+                    <view :class="['sorter-table-icon',item.sorterMode==='_asc'&&`sorting${item.sorterMode||''}`]"></view>
+                    <view :class="['sorter-table-icon',item.sorterMode==='_desc'&&`sorting${item.sorterMode||''}`]"></view>
+                  </view>
+                </template>
+              </view>
+	          </view>
+
+	        </view>
+	      </template>
+        <scroll-view
+            scroll-y="true"
+            id="leftTableFixed"
+            :upper-threshold="15"
+            @scrolltoupper="(e)=>scrollToFixedLeft(e)"
+            @scroll="leftFixedScrollAction"
+            :scroll-top="leftFiexScrollTop"
+            class="zb-table-body-inner"
+            :style=" `height: calc(100% - ${showSummary?80:40}px)`">
+          <view class="zb-table-fixed">
+            <view class="zb-table-tbody">
+              <view
+                  :class="['item-tr',stripe?(i % 2) != 0?'odd':'even':'',highlight&&isHighlight(ite,i)?'current-row':'']"
+                    v-for="(ite,i) in transData"
+                    @click.stop="rowClick(ite,i)"
+                    :key="ite.key"
+                    style="">
+                <view class='item-td'
+                      @click="cellClick(ite,index,item)"
+                      :style="[{
+	                       width:`${item.width?item.width:'100'}px`,
+	                       borderRight:`${border?'1px solid #e8e8e8':''}`,
+	                       textAlign:item.align||'left'
+	                      },cellStyle&&getCellStyle(ite,item,i,index)]"
+                      :key="index"
+                      v-for="(item,index) in fixedLeftColumns">
+                  <template v-if="item.type==='selection'">
+                    <view class="checkbox-item">
+                      <tableCheckbox @checkboxSelected="(e)=>checkboxSelected(e,ite)" :cellData="ite" :checked="ite.checked"/>
+                    </view>
+                  </template>
+                  <template v-else-if="item.type==='index'">
+                    {{i+1}}
+                  </template>
+                  <template v-else>
+                    {{ite[item.name]||item.emptyString}}
+                  </template>
+                </view>
+              </view>
+            </view>
+          </view>
+        </scroll-view>
+        <table-side-summary
+            :scrollbarSize="scrollbarSize"
+            v-if="showSummary&&!(scrollbarSize>0)"
+            :data="data"
+            :showSummary="showSummary"
+            :transColumns="transColumns"
+            :border="border"
+            :summary-method="summaryMethod"
+            :sumText="sumText"
+            :fixedLeftColumns="fixedLeftColumns"/>
+	    </view>
+	  </view>
+    <zb-load-more v-if="isLoadMore&&!completeLoading"/>
+	</view>
+	<!-- #endif -->
+	<!-- #ifndef H5 || APP-PLUS -->
+	<view class="zb-table-applet">
+	  <view class="zb-table-content" style="white-space: nowrap">
+      <scroll-view
+
+		<!-- #ifdef MP-ALIPAY -->
+		@scroll="scrollAlipay"
+		<!-- #endif  -->
+
+          @scrolltolower="scrolltolower"
+					<!-- #ifdef MP-ALIPAY -->
+                   style=" height: 100%;overflow-x:scroll"
+				   <!-- #endif  -->
+				   <!-- #ifndef MP-ALIPAY -->
+				   style=" height: 100%"
+				   <!-- #endif  -->
+                   scroll-y="true"
+				   scroll-x="true">
+	    <view class="zb-table-scroll" >
+	      <template v-if="showHeader">
+	        <view class="zb-table-header top-header-uni" style="">
+	            <view class="zb-table-fixed" >
+	              <view class="zb-table-thead" style="position: relative;" >
+	                <view class="item-tr">
+	                  <view
+	                      @click.stop="sortAction(item,index)"
+	                      :class="['item-th',index <fixedLeftColumns.length&&'zb-stick-side']"
+	                      :style="{
+	                              left:`${item.left}px`,
+	                              width:`${item.width?item.width:'100'}px`,
+															  flex:index===transColumns.length-1?1:'none',
+															  minWidth:`${item.width?item.width:'100'}px`,
+															   borderRight:`${border?'1px solid #e8e8e8':''}`,
+															  borderTop:`${border?'1px solid #e8e8e8':''}`,
+															   textAlign:item.align||'left'
+														  }"
+	                      v-for="(item,index) in transColumns" :key="index">
+                      <template v-if="item.type==='selection'">
+                        <view class="checkbox-item">
+                          <tableCheckbox
+                              :indeterminate="indeterminate" :checked="checkedAll" @checkboxSelected="checkboxSelectedAll"></tableCheckbox>
+                        </view>
+                      </template>
+                      <template v-else>
+                        {{ item.label||'' }}
+                        <view class="sorter-table" v-if="item.sorter">
+                          <view :class="['sorter-table-icon',item.sorterMode==='_asc'&&`sorting${item.sorterMode||''}`]"></view>
+                          <view :class="['sorter-table-icon',item.sorterMode==='_desc'&&`sorting${item.sorterMode||''}`]"></view>
+                        </view>
+                      </template>
+                    </view>
+	                </view>
+	              </view>
+	            </view>
+	        </view>
+	      </template>
+	      <template v-if="!data.length">
+	        <view class="no-data">暂无数据~~</view>
+	      </template>
+          <view class="zb-table-fixed">
+            <view class="zb-table-tbody">
+              <view  :class="['item-tr',highlight&&isHighlight(item,index)?'current-row':'']"
+                     @click.stop="rowClick(item,index)"
+                     v-for="(item,index) in transData" :key="item.key" >
+                <view
+                    :style="[{
+                      left:`${ite.left}px`,
+                      width:`${ite.width?ite.width:'100'}px`,
+                      flex:i===transColumns.length-1?1:'none',
+                      minWidth:`${ite.width?ite.width:'100'}px`,
+                      borderRight:`${border?'1px solid #e8e8e8':''}`,
+                      textAlign:ite.align||'left',
+                    },getCellStyle(item,ite,index,i)]"
+                    @click="cellClick(item,index,ite)"
+                    :class="['item-td', i <fixedLeftColumns.length&&'zb-stick-side',stripe?(index % 2) != 0?'odd':'even':'']"
+                    v-for="(ite,i) in transColumns" :key="i">
+                  <template  v-if="ite.type==='operation'">
+                    <view style="display: flex;align-items: center;height: 100%">
+                      <view
+                          v-for="ren,ind in permission(item,ite.renders,index)"
+                          :key="ind"
+                          @click.stop="$emit(ren.func,item,index)"
+                          :style="{
+	                          display:'flex',
+	                          alignItems: 'center',
+	                          marginRight:ite.renders.length>1?'8px':'0'
+	                        }">
+                        <template v-if="ren.type==='custom'">
+                          <view :class="ren.class||''" style="cursor: pointer">
+                            {{ren.name}}
+                          </view>
+                        </template>
+                        <template v-else>
+                          <button
+                              :class="ren.class||''"
+                              :type="ren.type||'primary'" :size="ren.size||'mini'">{{ren.name}}</button>
+                        </template>
+                      </view>
+                    </view>
+                  </template>
+                  <template v-else-if="ite.type==='selection'">
+                    <view class="checkbox-item">
+                      <tableCheckbox @checkboxSelected="(e)=>checkboxSelected(e,item)" :cellData="item" :checked="item.checked"/>
+                    </view>
+                  </template>
+                  <template v-else-if="ite.type==='img'">
+                    <template  v-if="item[ite.name]">
+                      <view class="checkbox-item" @click.stop>
+                        <image
+                            @click.stop="previewImage(iImageTem,item[ite.name],iImage)"
+                            v-for="iImageTem,iImage in imgs(item[ite.name])"
+                            :show-menu-by-longpress="false"
+                            :key="iImage"
+                            :src="iImageTem" style="width: 40px;height:30px; " mode="aspectFit"></image>
+                      </view>
+                    </template>
+
+                    <text v-else>{{ite.emptyString}}</text>
+                  </template>
+                  <template v-else-if="ite.type==='index'">
+                    {{index+1}}
+                  </template>
+                  <template  v-else>
+<!--                    {{ ite.filters?itemFilter(item,ite):(item[ite.name]==null||item[ite.name]==='')?ite.emptyString:item[ite.name] }}-->
+                    {{ ite.filters?itemFilter(item,ite):formatterAction(item,ite,index,i) }}
+                  </template>
+                </view>
+              </view>
+            </view>
+          </view>
+        <table-summary
+            v-if="showSummary"
+            :data="data"
+            :showSummary="showSummary"
+            :fixedLeftColumns="fixedLeftColumns"
+            :transColumns="transColumns"
+            :border="border"
+            :summary-method="summaryMethod"
+            :sumText="sumText"
+        />
+	    </view>
+      </scroll-view>
+	  </view>
+    <zb-load-more v-if="isLoadMore&&!completeLoading"/>
+	</view>
+	<!-- #endif -->
+</template>
+<script>
+import TableCheckbox from './components/table-checkbox.vue'
+import TableSummary from "./components/table-summary.vue";
+import TableSideSummary from "./components/table-side-summary.vue";
+import TableH5Summary from './components/table-h5-summary'
+import ZbLoadMore from './components/zb-load-more'
+
+// #ifdef H5
+import {getScrollbarSize} from "./js/util";
+// #endif
+
+export default {
+  components:{
+    TableCheckbox,
+    TableSummary,
+    TableSideSummary,
+    TableH5Summary,
+    ZbLoadMore
+  },
+  props:{
+    highlight:{
+      type:Boolean,
+      default:false
+    },
+    itemDate:{
+      type:Object,
+      default:()=>{}
+    },
+    columns:{
+      type:Array,
+      default:()=>[]
+    },
+    showSummary:{
+      type:Boolean,
+      default:false
+    },
+    isShowLoadMore:{
+      type:Boolean,
+      default:false
+    },
+    data:{
+      type:Array,
+      default:()=>[]
+    },
+    sumText:{
+      type:String,
+      default:'合计'
+    },
+    showHeader:{
+      type:Boolean,
+      default:true
+    },
+    border:{
+      type:Boolean,
+      default:false
+    },
+    stripe:{
+      type:Boolean,
+      default:true
+    },
+    fit:{
+      type:Boolean,
+      default:false
+    },
+    rowKey:[String, Function],
+    summaryMethod:Function,
+    pullUpLoading:Function,
+    formatter:Function,
+    cellStyle:Function,
+    cellHeaderStyle:Function,
+    permissionBtn:Function,
+  },
+  computed:{
+    loadMoreHeight(){
+      return this.isLoadMore?40:0
+    },
+    fixedLeftColumns(){
+      let arr = []
+      for(let i=0;i<this.columns.length;i++){
+        let item = this.columns[i]
+        if(item.fixed){
+          arr.push(item)
+        }else {
+          break
+        }
+      }
+      return arr
+    },
+    imgs(){
+      return (item)=>{
+        return typeof item==='string'?[item]:item
+      }
+    },
+    itemfilters(){
+      return(item,ite)=>{
+        if(item[ite.name]==null){
+          return ite.emptyString
+        }
+        return item[ite.name]
+      }
+    },
+    scrollbarSize(){
+		// #ifdef H5
+      return getScrollbarSize()
+	  // #endif
+
+	  // #ifndef H5
+	  return 0
+	  // #endif
+    },
+    isFixedLeft(){
+      if(!this.columns.length){
+        return false
+      }
+      if(!this.data.length){
+        return false
+      }
+      let [firstArr] = this.columns
+      return !!firstArr.fixed;
+    },
+    transColumns(){
+      if(this.fit){
+        this.columns.forEach(column=>{
+          if(column.type==="operation"&&column.renders){
+			      let str = ''
+            column.renders.map((item)=>{
+              str+=item.name
+            })
+            column.width = this.getTextWidth(str)+column.renders.length*40
+          }else if(column.type==="img"){
+
+			   }else if(column.type==="selection"){
+			}else{
+			let arr = [this.getTextWidth(column.label)]
+            this.data.forEach(data=>{
+              let str = (data[column.name]+'')
+			  if(str==='undefined'){
+				   arr.push(30)
+			  }else{
+				   let width = this.getTextWidth(str)
+				   arr.push(width)
+			  }
+            })
+			      column.width = Math.max(...arr)+20
+          }
+        })
+      }
+      let number = 0
+      this.columns.forEach((item,index)=>{
+        if(item.type==="operation"&&item.renders&&!item.width){
+          let str = ''
+          item.renders.map((item)=>{
+            str+=item.name
+          })
+          item.width = this.getTextWidth(str)+item.renders.length*40
+        }
+        if(item.type==="img"){
+          if(!item.width){
+            let arr = []
+            let widImg = this.getTextWidth(item.label)
+            this.data.forEach(data=>{
+              if(data[item.name]){
+                let urls = typeof data[item.name]==='string'?[data[item.name]]:data[item.name]
+                arr.push(urls.length)
+              }
+              item.width = Math.max(...arr)*40+widImg
+            })
+          }
+
+        }
+        if(item.fixed){
+          if(index===0){
+            item.left = 0
+            number+=item.width
+          }else {
+            item.left = number
+            number+=item.width
+          }
+        }
+        item.emptyString = item.emptyString||'--'
+      })
+      return this.columns
+    },
+    transData(){
+      let flag = this.columns.some(item=>item.type==='selection')
+      this.data.forEach((item,index)=>{
+        if(flag){
+          if(item.checked){
+            if(!this.selectArr.length){
+              this.selectArr.push(item)
+            }
+          }
+        }
+        if(this.rowKey){
+          if(typeof this.rowKey==='function'){
+            item.key = Object.freeze(this.rowKey(item))||Date.now()
+          }else {
+            item.key = Object.freeze(item[this.rowKey])||Date.now()
+          }
+        }else {
+          item.key = index
+        }
+      })
+      if(flag){
+              if(this.data.length){
+                let le = this.data.filter(item=>item.checked).length
+                if(le){
+                  if(le===this.data.length){
+                    this.checkedAll = true
+                  }else {
+                    this.indeterminate = true
+                  }
+                }else {
+                  this.checkedAll = false
+                  this.indeterminate = false
+                  this.selectArr = []
+                }
+              }else {
+                this.checkedAll = false
+                this.indeterminate = false
+                this.selectArr = []
+              }
+            }
+      return this.data
+    },
+    isHighlight(){
+      return (item,index)=>{
+        if(this.rowKey){
+          return item.key === this.currentRow['key']
+        }else{
+          return index === this.currentRowIndex
+        }
+      }
+    },
+    getHeaderCellStyle() {
+      return (column,  columnIndex,childIndex)=>{
+        const cellStyle = this.cellHeaderStyle;
+        if(typeof cellStyle==='function'){
+          return cellStyle({ column, columnIndex})
+        }
+        return {}
+      }
+    },
+    getCellStyle() {
+     return (row, column, rowIndex, columnIndex)=>{
+       const cellStyle = this.cellStyle;
+       if(typeof cellStyle==='function'){
+         return cellStyle({row, column, rowIndex, columnIndex})
+       }
+       return {}
+     }
+    },
+  },
+  data() {
+    return {
+      button:[],
+	    alipayScrollTop:0,
+      alipayScrollOldTop:0,
+      alipayFlag:false,
+      bodyTableLeft:0,
+      headerTableLeft:0,
+      lastScrollLeft:0,
+      isLoadMore:false,
+      headerFooterTableLeft:0,
+      leftFiexScrollTop:0,
+      bodyScrollTop:0,
+      currentDriver:null,
+      currentDriver1:null,
+      bodyTime:null,
+      currentRowIndex:null,
+      currentRow: {},
+      bodyTime1:null,
+      headerTime:null,
+      debounceTime:null,
+      operation:{},
+      completedFlag:false,
+      selectArr:[],
+      indeterminate:false,
+      checkedAll:false,
+      completeLoading:false,
+      aliTime:null,
+    }
+  },
+  created(){
+  },
+  mounted(){
+
+    // setTimeout(()=>{
+    //   uni.createSelectorQuery().in(this).select(".top-header-uni").boundingClientRect( data => {
+    //     console.log('data=======',data)
+    //     //data  可以打印data输出看详细数据,有很多数据信息
+    //     var left = data.width;//表示元素宽度
+    //   }).exec();
+    // },1000)
+  },
+  beforeDestroy(){
+      this.aliTime&&clearTimeout(this.aliTime)
+      this.debounceTime&&clearTimeout(this.debounceTime)
+      this.bodyTime1&&clearTimeout(this.bodyTime1)
+      this.bodyTime&&clearTimeout(this.bodyTime)
+      this.selectArr = []
+      this.indeterminate = false
+      this.checkedAll = false
+  
+    },
+  methods: {
+	clearSelection(){
+		this.transData.forEach(item=>{
+			item.checked = false
+		})
+		this.selectArr = []
+		this.indeterminate = false
+		this.checkedAll = false
+	},
+    formatterAction(row,column,rowIndex,columnIndex){
+      if(column.formatter&&typeof this.formatter==='function'){
+        return this.formatter(row,column,rowIndex,columnIndex)
+      }
+      return (row[column.name]==null||row[column.name]==='')?column.emptyString:row[column.name]
+    },
+    permission(item,renders,index){
+      if(this.permissionBtn&&typeof this.permissionBtn==='function'){
+        return this.permissionBtn(item,renders,index)
+      }
+      return renders
+    },
+    pullUpCompleteLoading(type){
+      this.isLoadMore = false
+      if(type==='ok'){
+        this.completeLoading = true
+      }
+    },
+    scrollAlipay(e){
+
+      if(!this.alipayScrollOldTop){
+        this.alipayScrollOldTop = e.detail.scrollTop
+      }
+      this.aliTime&&clearTimeout(this.aliTime)
+      this.aliTime = setTimeout(()=>{
+
+        if(this.alipayFlag&&e.detail.scrollTop>this.alipayScrollOldTop){
+          this.pullLoad()
+        }
+        this.alipayFlag = false
+        this.alipayScrollOldTop = null
+      },500)
+    },
+    pullLoad(){
+      if(this.isShowLoadMore){
+        this.isLoadMore = true
+        this.$emit('pullUpLoading')
+        let that = this
+        this.pullUpLoading&&this.pullUpLoading.call(this.$parent.$parent, (type)=>{
+          that.isLoadMore = false
+          if(type==='ok'){
+            that.completeLoading=true
+          }
+        })
+      }
+
+    },
+    scrolltolower(e){
+      this.alipayFlag = true
+      if(e.detail.direction==='bottom'){
+        this.pullLoad()
+      }
+
+      // this.pullUpLoading.call(this.$parent)
+    },
+	  previewImage(item,url,current){
+      let urls = typeof url==='string'?[url]:url
+		  uni.previewImage({
+			  current,
+			  urls:urls
+		  })
+	  },
+    resetHighlight(){
+      this.currentRowIndex = null
+      this.currentRow = {}
+    },
+    cellClick(row,index,column){
+        this.$emit('cellClick',row,index,column)
+    },
+    rowClick(row,index){
+      if(this.highlight){
+        this.currentRowIndex = index
+        this.currentRow = row
+        this.$emit('currentChange',row,index)
+      }
+      this.$emit('rowClick',row,index)
+    },
+    checkboxSelectedAll(e){
+      this.indeterminate = false
+      if(e.checked){
+        this.selectArr = []
+        this.checkedAll = true
+        this.data.forEach(item=>{
+          // this.$set(item,'checked',true)
+          item.checked = true
+          this.selectArr.push(item)
+        })
+      }else{
+        this.checkedAll = false
+        this.data.forEach(item=>{
+          this.$set(item,'checked',false)
+        })
+        this.selectArr = []
+      }
+      // #ifndef H5 || APP-PLUS
+      this.$forceUpdate()
+      // #endif
+      this.$emit('toggleAllSelection',e.checked,this.selectArr)
+    },
+    checkboxSelected(e,item){
+      // #ifdef H5 || APP-PLUS
+      this.$set(item,'checked',e.checked)
+      // #endif
+      // #ifndef H5 || APP-PLUS
+      this.data.forEach(item=>{
+        if(item.key===e.data.key){
+          item.checked = e.checked
+        }
+      })
+      // #endif
+      item.checked = e.checked
+      e.data.checked = e.checked
+      if(e.checked){
+        this.selectArr.push(e.data)
+      }else{
+        this.selectArr = this.selectArr.filter(item=>item.key!==e.data.key)
+      }
+      if(this.selectArr.length===this.transData.length){
+        this.indeterminate = false
+        this.checkedAll = true
+      }else{
+        this.indeterminate = true
+        this.checkedAll = false
+      }
+      if(!this.selectArr.length){
+        this.checkedAll = false
+        this.indeterminate = false
+      }
+      // #ifndef H5 || APP-PLUS
+      this.$forceUpdate()
+      // #endif
+      this.$emit('toggleRowSelection',e.checked,this.selectArr)
+    },
+    itemFilter(item,ite){
+      if(ite.filters&&ite.name){
+        let key = item[ite.name]
+        return ite.filters[key]||''
+      }
+      return item[ite.name]||ite.emptyString
+    },
+    // 默认字体为微软雅黑 Microsoft YaHei,字体大小为 14px
+    getTextWidth(str) {
+      if(str.length<3){
+        return 40
+      }
+      let regx = /^[0-9]+.?[0-9]*$/
+      let flexWidth = 0
+      for (const char of str) {
+        if ((char >= 'A' && char <= 'Z') || (char >= 'a' && char <= 'z')) {
+          // 如果是英文字符,为字符分配8个单位宽度
+          flexWidth += 10
+        } else if (char >= '\u4e00' && char <= '\u9fa5') {
+          // 如果是中文字符,为字符分配15个单位宽度
+          flexWidth += 15
+        } else if(regx.test(char)){
+          flexWidth += 9
+        }else {
+          // 其他种类字符,为字符分配8个单位宽度
+          flexWidth += 7
+        }
+      }
+      return flexWidth
+    },
+    width(item){
+      return `${item.width?item.width:'100'}px`
+    },
+    showStripe(index){
+      if(this.currentDriver)return
+      if(this.stripe){
+        return (index % 2) != 0?'odd':'even'
+      }else{
+        return ''
+      }
+    },
+    //验证字符串是否是数字
+    checkNumber(theObj) {
+      var reg = /^[0-9]+.?[0-9]*$/;
+      if (reg.test(theObj)) {
+        return true;
+      }
+      return false;
+    },
+    isDate(data){
+      if(isNaN(data)&&!isNaN(Date.parse(data))){
+        return true
+      }
+      return false
+    },
+    sortAction(item,index){
+      if(!item.sorter){return false}
+      this.$set(item,'sorterMode',item.sorterMode==='_asc'?'_desc':'_asc')
+      if(item.sorter==='custom'){
+        this.$emit('sort-change',item,item.sorterMode.replace('_',''),index)
+      }else {
+        this.sortData(item)
+      }
+      // #ifndef H5 || APP-PLUS
+      this.$forceUpdate()
+      // #endif
+    },
+    sortData(item){
+      let key = item.name
+
+      if(item.sorterMode==='_asc'){
+        this.data.sort((a,b)=>{
+          if(this.checkNumber(a[key])){
+            return a[key]-b[key]
+          }
+          if(this.isDate(a[key])){
+            let a1 = new Date(a[key]).getTime()
+            let b1 = new Date(b[key]).getTime()
+            return a1-b1
+          }
+        })
+      }else {
+        this.data.sort((a,b)=>{
+          if(this.checkNumber(a[key])){
+            return b[key]-a[key]
+          }
+          if(this.isDate(a[key])){
+            let a1 = new Date(a[key]).getTime()
+            let b1 = new Date(b[key]).getTime()
+            return b1-a1
+          }
+        })
+      }
+    },
+    throttle(method,delay=60){
+      let time = null
+      return (...args)=>{
+        if(!time){
+          time = setTimeout(()=>{
+            method(...args)
+            time = null;
+          },delay)
+        }
+      }
+    },
+    debounce(method,delay=1000){
+      return (...args)=>{
+        this.debounceTime&&clearTimeout(this.debounceTime)
+        this.debounceTime = setTimeout(()=>{
+          method(...args)
+        },delay)
+      }
+    },
+    handleBodyScroll(e){
+      if(this.currentDriver&&this.currentDriver!==e.currentTarget.id)return
+      this.currentDriver = e.currentTarget.id
+      this.headerTableLeft = e.detail.scrollLeft
+      this.headerFooterTableLeft = e.detail.scrollLeft
+      this.leftFiexScrollTop = e.detail.scrollTop
+      this.bodyTime&&clearTimeout(this.bodyTime)
+      this.bodyTime = setTimeout(()=>{
+        this.currentDriver=null
+      },200)
+
+    },
+    leftFixedScrollAction(e){
+      if(this.currentDriver&&this.currentDriver!==e.currentTarget.id)return
+      this.currentDriver = e.currentTarget.id
+      this.bodyScrollTop = e.detail.scrollTop
+      this.bodyTime&&clearTimeout(this.bodyTime)
+      this.bodyTime = setTimeout(()=>{
+        this.currentDriver=null
+      },200)
+    },
+    scrollToLeft(e){
+      if(this.currentDriver1&&this.currentDriver1!==e.currentTarget.id)return
+      this.currentDriver1 = e.currentTarget.id
+      if(e.detail.direction==='left'&&this.headerTableLeft<10){
+        this.headerTableLeft = 0
+      }else if(e.detail.direction==='top'&&this.leftFiexScrollTop<10){
+        this.leftFiexScrollTop = 0
+      }
+      this.bodyTime&&clearTimeout(this.bodyTime)
+      this.bodyTime = setTimeout(()=>{
+        this.currentDriver1=null
+      },200)
+    },
+    scrollToFixedLeft(e){
+      if(this.currentDriver1&&this.currentDriver1!==e.currentTarget.id)return
+      this.currentDriver1 = e.currentTarget.id
+      if(e.detail.direction==='top'&&this.bodyScrollTop<10){
+        this.bodyScrollTop = 0
+      }
+      this.bodyTime&&clearTimeout(this.bodyTime)
+      this.bodyTime = setTimeout(()=>{
+        this.currentDriver1=null
+      },200)
+    },
+    handleTableScrollLeft(e,type){
+      if(this.currentDriver&&this.currentDriver!==e.currentTarget.id)return
+      this.currentDriver = e.currentTarget.id
+      this.bodyTableLeft = e.detail.scrollLeft
+      this.headerFooterTableLeft = e.detail.scrollLeft
+      this.bodyTime&&clearTimeout(this.bodyTime)
+      this.bodyTime = setTimeout(()=>{
+        this.currentDriver=null
+      },200)
+    },
+    handleFooterTableScrollLeft(e){
+      if(this.currentDriver&&this.currentDriver!==e.currentTarget.id)return
+      this.currentDriver = e.currentTarget.id
+      this.bodyTableLeft = e.detail.scrollLeft
+      this.headerTableLeft = e.detail.scrollLeft
+      this.bodyTime&&clearTimeout(this.bodyTime)
+      this.bodyTime = setTimeout(()=>{
+        this.currentDriver=null
+      },200)
+    }
+  }
+}
+</script>
+<style lang="scss">
+.zb-table-fixed-left{
+  /*去除左边滚动条 */
+  scroll-view ::-webkit-scrollbar {
+    display: none !important;
+    width: 0 !important;
+    height: 0 !important;
+    -webkit-appearance: none;
+    background: transparent;
+  }
+}
+.zb-table-header{
+  ///*去除头部滚动条 */
+  scroll-view ::-webkit-scrollbar {
+    display: none !important;
+    width: 0 !important;
+    height: 0 !important;
+    -webkit-appearance: none;
+    background: transparent;
+  }
+}
+
+</style>
+<style lang="scss" scoped>
+.sorter-table{
+  position: absolute;
+  right: 6px;
+  top:50%;
+  transform:translateY(-50%);
+  .sorter-table-icon{
+    width: 0;
+    height: 0;
+    color: #dcdcdc;
+    border-right: 4px solid transparent;
+    border-left: 4px solid transparent;
+  }
+  .sorter-table-icon:first-child{
+    border-bottom: 5px solid currentColor;
+  }
+  .sorter-table-icon:last-child{
+    margin-top: 1.5px;
+    border-top: 5px solid currentColor;
+  }
+  .sorting_desc{
+    color: #2979ff;
+  }
+  .sorting_asc{
+    color: #2979ff;
+  }
+}
+.checkbox-item{
+  display: flex;align-items: center;justify-content: center;width: 100%;height: 100%
+}
+.no-data{
+  width: 100%;
+  height: 80rpx;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  border-bottom: 1px solid #e8e8e8;
+}
+.item-th{
+  position: relative;
+  flex-shrink: 0;
+  width: 100px;
+  overflow-wrap: break-word;
+  border-bottom: 1px solid #e8e8e8;
+  transition: background 0.3s;
+  padding-right: 20px;
+  word-break:keep-all;           /* 不换行 */
+  white-space:nowrap;          /* 不换行 */
+  overflow:hidden;               /* 内容超出宽度时隐藏超出部分的内容 */
+  text-overflow:ellipsis;         /* 当对象内文本溢出时显示省略标记(...) ;需与overflow:hidden;一起使用。*/
+  overflow-wrap: break-word;
+}
+.zb-table{
+  height: 100%;
+  overflow: hidden;
+  width: 100%;
+  display: flex;
+  flex-direction: column;
+  font-size: 12px;
+  position: relative;
+  .zb-table-content{
+    //height: 100%;
+    //flex: 1;
+    position: relative;
+    overflow: hidden;
+  }
+  .zb-table-fixed{
+    min-width: 100%;
+  }
+  .zb-table-body{
+    position: relative;
+    background: #fff;
+    transition: opacity 0.3s;
+  }
+  .item-tr{
+    display: flex;
+    //height: 41px;
+  }
+  .item-td{
+    flex-shrink: 0;
+    width: 100px;
+    padding-left: 8px;
+    height: 40px;
+    line-height: 40px;
+	padding-right: 20px;
+    box-sizing: border-box;
+    word-break:keep-all;           /* 不换行 */
+    white-space:nowrap;          /* 不换行 */
+    overflow:hidden;               /* 内容超出宽度时隐藏超出部分的内容 */
+    text-overflow:ellipsis;         /* 当对象内文本溢出时显示省略标记(...) ;需与overflow:hidden;一起使用。*/
+    overflow-wrap: break-word;
+    border-bottom: 1px solid #e8e8e8;
+    //transition: background 0.3s;
+  }
+
+  .zb-table-fixed-left .zb-table-header{
+    overflow-y: hidden;
+  }
+  .zb-table-header {
+    overflow: hidden;
+    background: #fafafa;
+    .item-th{
+      padding-left: 8px;
+      line-height: 39px;
+      height: 40px;
+      //display: flex;
+      //align-items: center;
+      box-sizing: border-box;
+    }
+  }
+  .zb-table-fixed-left .zb-table-fixed{
+    background: #fff;
+  }
+  .zb-table-fixed-right .zb-table-fixed{
+    background: #fff;
+  }
+  .zb-table-body-inner{
+    height: 100%;
+    // overflow: scroll;
+  }
+  .zb-table-fixed-left{
+    position: absolute;
+    top: 0;
+    z-index: 1;
+    overflow: hidden;
+    border-radius: 0;
+    height: 100%;
+    //transition: box-shadow 0.3s ease;
+  }
+  .odd{
+    background-color:rgba(249,249,249,0.6);
+    //height: 100%;
+    width: 100%;
+  }
+  .even{
+    background-color:white ;
+    //height: 100%;
+    width: 100%;
+  }
+}
+.scroll-left-fixed{
+  .zb-table-fixed-left {
+    left: 0;
+    box-shadow: 6px 0 6px -4px #ccc;
+  }
+}
+.zb-table-applet{
+  height: 100%;
+  //overflow: hidden;
+  width: 100%;
+  position: relative;
+  display: flex;
+  flex-direction: column;
+  font-size: 12px;
+  .zb-table-content{
+    //height: 100%;
+    flex: 1;
+    overflow: hidden;
+    position: relative;
+
+  }
+  .zb-table-fixed{
+    min-width: 100%;
+    width: fit-content;
+  }
+
+  .zb-table-body{
+    position: relative;
+    background: #fff;
+    transition: opacity 0.3s;
+  }
+  .item-tr{
+    display: flex;
+    //height: 41px;
+  }
+  .item-td{
+    flex-shrink: 0;
+    width: 100px;
+    padding-left: 8px;
+    height: 40px;
+    line-height: 40px;
+	padding-right:20px;
+    box-sizing: border-box;
+    word-break:keep-all;           /* 不换行 */
+    white-space:nowrap;          /* 不换行 */
+    overflow:hidden;               /* 内容超出宽度时隐藏超出部分的内容 */
+    text-overflow:ellipsis;         /* 当对象内文本溢出时显示省略标记(...) ;需与overflow:hidden;一起使用。*/
+    overflow-wrap: break-word;
+    border-bottom: 1px solid #e8e8e8;
+    //transition: background 0.3s;
+  }
+  .zb-table-header {
+    //overflow: hidden;
+    position: sticky;
+    top: 0;
+    z-index: 2;
+    //width: fit-content;
+    .item-th{
+      padding-left: 8px;
+      line-height: 39px;
+      height: 40px;
+      box-sizing: border-box;
+      background: #fafafa;
+    }
+    .zb-stick-side{
+      position: sticky;
+      top: 0;
+      left: 0;
+      z-index: 2;
+      //border-right: solid 1rpx #dbdbdb;
+      box-sizing: border-box;
+      background: #fafafa;
+      //box-shadow: 6px 0 6px -4px #ccc;
+    }
+  }
+  .zb-table-fixed-left .zb-table-fixed{
+    background: #fff;
+  }
+  .zb-table-fixed-right .zb-table-fixed{
+    background: #fff;
+  }
+  .zb-table-fixed-header .zb-table-body-inner{
+    height: 100%;
+    // overflow: scroll;
+  }
+  .zb-table-fixed-left{
+    position: absolute;
+    top: 0;
+    z-index: 1;
+    overflow: hidden;
+    border-radius: 0;
+    height: 100%;
+    //transition: box-shadow 0.3s ease;
+  }
+  .scroll-left-fixed{
+    .zb-table-fixed-left {
+      left: 0;
+      box-shadow: 6px 0 6px -4px #ccc;
+    }
+  }
+  .odd{
+    background-color:rgba(249,249,249,0.6);
+    //height: 100%;
+    width: 100%;
+  }
+  .even{
+    background-color:white ;
+    //height: 100%;
+    width: 100%;
+  }
+  .zb-table-tbody {
+    .zb-stick-side{
+      position: sticky;
+      left: 0;
+      z-index: 1;
+      box-sizing: border-box;
+      background:white;
+      //box-shadow: 6px 0 6px -2px #ccc;
+    }
+    .odd{
+      background:#f9f9f9;
+      //height: 100%;
+      width: 100%;
+    }
+    .even{
+      background:white ;
+      //height: 100%;
+      width: 100%;
+    }
+  }
+  .current-row{
+    .item-td{
+      background-color: #ecf5ff;
+    }
+  }
+}
+.current-row{
+  .item-td{
+    background-color: #ecf5ff;
+  }
+}
+.zb-table-header{
+  height: 40px;
+}
+.scrollPosition{
+  position: absolute;right: 0;top: 0;height: 100%;background: red;
+  z-index: 999;
+}
+</style>

+ 81 - 0
uni_modules/zb-table/package.json

@@ -0,0 +1,81 @@
+{
+  "id": "zb-table",
+  "displayName": "zb-table(多功能表格)",
+  "version": "1.2.18",
+  "description": "表格组件 支持固定表头和首列、上拉加载更多、及固定多列,表格自适应内容,排序,多选checkbox、可点击删除,编辑、合计功能,兼容多端",
+  "keywords": [
+    "table",
+    "表格",
+    "固定表头、固定首列、多列",
+    "上拉加载更多、",
+    "排序、自适应列宽、多选checkbox、编辑、删除、按钮、合计"
+],
+  "repository": "https://github.com/zouzhibin/zb-table.git",
+  "engines": {
+    "HBuilderX": "^3.1.0"
+  },
+"dcloudext": {
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "",
+    "type": "component-vue"
+  },
+  "uni_modules": {
+    "dependencies": [],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y"
+      },
+      "client": {
+        "Vue": {
+          "vue2": "y",
+          "vue3": "y"
+        },
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "u"
+        },
+        "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"
+        }
+      }
+    }
+  }
+}

+ 189 - 0
uni_modules/zb-table/readme.md

@@ -0,0 +1,189 @@
+
+## 介绍
+基于uni-app开发的一个普通的表格组件,功能有固定首列和表头、排序、操作按钮、
+table 表格 固定表头、固定首列、多列 上拉加载更多、 排序、自适应列宽、多选checkbox、编辑、删除、按钮、合计
+已用于生产环境
+
+微信=》 19550102670 拉进群
+## -- github 第一时间会更新到github,永远保持最新,有啥想法的可以提PR,共同开发 [地址](https://github.com/zouzhibin/zb-ui)
+
+## 友情链接
+### 在线预览点击 —— [企业级、通用型中后台前端解决方案 ](https://yuanzbz.gitee.io/vue-admin-perfect/#/login?redirect=/home)
+### vue-admin-perfect —— [企业级、通用型中后台前端解决方案(基于vue3.0+TS+Element-Plus  最新版,同时支持电脑,手机,平板)](https://github.com/zouzhibin/vue-admin-perfect)
+
+
+## table 属性
+| 参数 | 说明 | 类型 | 可选值 | 默认值 |是否必须|
+| ------ | ------ | ------ | ------ | ------ |------ |
+| data | 显示的数据 | array |-- | -- |必须 |
+| column | 显示的列数据 | array |-- | -- |必须 |
+| stripe | 是否为斑马纹 table| boolean | - |false | 否 |
+| fit | 列的宽度是否自撑开 | boolean |true,false | false |否 |
+| show-header | 是否显示表头 | boolean |true,false | true |否 |
+| cell-style | 单元格的 style 的回调方法,也可以使用一个固定的 Object 为所有单元格设置一样的 Style。 | Function({row, column, rowIndex, columnIndex})/Object |-- | -- |否 |
+| cell-header-style | 头部单元格的 style 的回调方法,也可以使用一个固定的 Object 为所有单元格设置一样的 Style。 | Function({ column, columnIndex})/Object |-- | -- |否 |
+| formatter | colomn =》formatter 必须设置为true,才有作用,进行格式化数据,进行数据的转换 | Function({row, column, rowIndex, columnIndex})/Object |-- | -- |否 |
+| border | 是否带有纵向边框 | boolean |true,false | true |否 |
+| highlight | 是否要高亮当前行 | boolean |true,false | false |否 |
+| show-summary | 是否在表尾显示合计行 | boolean |true,false | false |否 |
+| sum-text | 合计行第一列的文本 | String |- | 合计 |否 |
+| summary-method | 自定义的合计计算方法 | Function({ columns, data }) |- | - |否 |
+| permissionBtn | 是否动态控制按钮的显示隐藏 | Function({ row, renders,index }) |- | - |否 |
+| isShowLoadMore | 是否开启上拉加载 | boolean |true,false | false |否 |
+| pullUpLoading | 开启上拉加载后的返回函数,接收参数done是函数,done(type),type为空代表还有数据,继续开启上拉加载,type='ok',代表结束上拉加载 | Function(done) |-- | -- |否 |
+
+```
+关闭上拉加载的方式1:pullUpLoading((done)=>{
+	done(type)
+})
+done 接收参数为 type ,type为空代表还有数据,可以继续加载,无数据的时候传入 'ok'代表结束
+```
+
+## table 事件
+| 参数 | 说明 | 类型 | 可选值                      | 默认值 |是否必须|
+| ------ | ------ | ------ |--------------------------| ------ |------ |
+| 事件名自定义 | 取决于type类型为operation的 renders参数里面 func 的参数名 | Function | (row,index)=>{}          | -- |否 |
+| sort-change | 取决于type类型为operation的 renders参数里面 func 的参数名 | Function | (column,model,index)=>{} | -- |否 |
+| currentChange | 当表格的当前行发生变化的时候会触发该事件,如果要高亮当前行,请打开表格的 highlight属性,this.$refs.table.resetHighlight()清除选中 | Function | (row,index)=>{}          | -- |否 |
+| toggleRowSelection | 用于多选表格,切换某一行的选中状态,第一个参数代表选中状态,参数二代表选中的对象 | Function | (selected ,array)=>{}    | -- |否 |
+| toggleAllSelection | 用于多选表格,切换所有行的选中状态 ,第一个参数代表选中状态,参数二代表选中的对象| Function | (selected ,array)=>{}    | -- |否 |
+| rowClick | 单击某行 ,第一个参数代表选中对象,参数二代表选中的index| Function | (row ,index)=>{}         | -- |否 |
+| cellClick | 单击单元格 ,当某个单元格被点击时会触发该事件| Function | (row ,index,column)=>{}        | -- |否 |
+| pullUpLoading | 开启上拉加载后的返回函数,无参数| Function  | --                       |-- |否 |
+
+```
+关闭上拉加载的方式2:this.$refs.zbTable.pullUpCompleteLoading('ok')
+接收参数为 type ,type为空代表还有数据,可以继续加载,无数据的时候传入 'ok'代表结束
+```
+
+## data 属性
+| 参数 | 说明 | 类型 | 可选值 | 默认值 |
+| ------ | ------ | ------ | ------ | ------ |
+| checked | 是否被勾选 | boolean |true,false | 无 |
+
+
+## column 属性
+| 参数 | 说明 | 类型 | 可选值 | 默认值 |
+| ------ | ------ | ------ | ------ | ------ |
+| name | 属性值 | string |-- | 无 |
+| label | 显示的标题 | string |-- | 无 |
+| width | 列的宽度 | number |-- | 100 |
+| fixed | 列是否固定在左侧,true 表示固定在左侧 | boolean |true,false | true |
+| sorter | 排序,当设置为custom的时候代表自定义排序,不会再触发默认排序,会触发table事件@sort-change,可以通过接口来进行排序 | boolean |true,false,'custom' | false |
+| emptyString | 当值为空的时候默认显示的值 | string |  | -- |
+| filters | 对象过滤的选项,对象格式,对象中的元素需要有 key 和 value 属性。 | Object | {key:value} | -- |
+| align | 对齐方式 | String | left/center/right | left |
+| type | 为 operation 的时候代表为操作按钮,img的时候代表图片地址,index代表序列号 | string | operation,img,index | -- |
+| renders | type 为operation的时候 必传 | Array | {name:'名字',func:"父元素接收事件名",type:"按钮的类型",size:"大小"} | -- |
+```
+type 为 operation 的时候代表为操作按钮
+renders 代表传入的按钮  Array  =>[
+    {
+        name:'编辑',
+        class:"", // 添加class
+        type:'primary',代表按钮的类型  type 为custom的时候自定义按钮 其他类型取决于uniapp buttom组件按钮
+        size:'mini',代表按钮的大小
+        func:'edit' // func 代表操作按钮点击的事件名字 父元素接收的事件 父元素 @edit
+        例如:// <zb-table @edit=""/> 
+        
+    }
+]
+```
+## 示例
+```
+<zb-table
+            :show-header="true"
+            :columns="column"
+            :stripe="true"
+            :fit="false"
+            show-summary
+            sum-text="合计"
+            @rowClick="rowClick"
+            :summary-method="getSummaries"
+            @toggleRowSelection="toggleRowSelection"
+            @toggleAllSelection="toggleAllSelection"
+            :border="true"
+            @edit="buttonEdit"
+            @dele="dele"
+            :data="data"></zb-table>
+```
+
+## 数据格式
+```
+column:[
+          { type:'selection', fixed:true,width:50 },
+          { name: 'name', label: '姓名',fixed:false,width:80,emptyString:'--' },
+          { name: 'age', label: '年纪',sorter:false,align:'right', },
+          { name: 'sex', label: '性别',filters:{0:'男',1:'女'}},
+		  { name: 'img', label: '图片',type:"img" },
+          { name: 'address', label: '地址' },
+          { name: 'date', label: '日期',sorter:true },
+          { name: 'province', label: '省份' },
+          { name: 'city', label: '城市' },
+          { name: 'zip', label: '邮编' },
+          { name: 'operation', type:'operation',label: '操作',renders:[
+              {
+                name:'编辑',
+                func:'edit' // func 代表子元素点击的事件 父元素接收的事件 父元素 @edit
+              },
+              {
+                name:'删除',
+                type:'warn',
+                func:"dele"
+              },
+            ]},
+        ],
+ data:[
+          {
+            date: '2016-05-02',
+            name: '王小虎1',
+            province: '上海',
+            sex:'男',
+            age:'18',
+			img:"https://img1.baidu.com/it/u=300787145,1214060415&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500",
+            city: '普陀区',
+            address: '上海市普',
+            zip: 200333
+          },
+          {
+            date: '2016-05-02',
+            name: '王小虎2',
+            province: '上海',
+            sex:'男',
+            age:'18',
+            city: '普陀区',
+            address: '上海市普',
+            zip: 200333
+          },
+          {
+            date: '2016-05-02',
+            name: '王小虎3',
+            province: '上海',
+            sex:'男',
+            age:'18',
+            city: '普陀区',
+            address: '上海市普',
+            zip: 200333
+          },
+          {
+            date: '2016-05-02',
+            name: '王小虎4',
+            province: '上海',
+            sex:'男',
+            age:'18',
+            city: '普陀区',
+            address: '上海市普',
+            zip: 200333
+          },
+          {
+            date: '2016-05-02',
+            name: '王小虎5',
+            province: '上海',
+            sex:'男',
+            age:'18',
+            city: '普陀区',
+            address: '上海市普',
+            zip: 200333
+          }
+        ]       
+```