Browse Source

电池管理

蒋科 10 months ago
parent
commit
fc38bd2c90
29 changed files with 2645 additions and 152 deletions
  1. 28 0
      common/check.js
  2. 52 0
      common/http.js
  3. 11 4
      components/BatteryInfo/BatteryInfo.vue
  4. 4 4
      components/Navbar/Navbar.vue
  5. 8 0
      components/PublicDrawer/PublicDrawer.vue
  6. 2 2
      pages/basic-data/BasicDrawer.vue
  7. 43 0
      pages/basic-data/BatteryDrawer.vue
  8. 52 0
      pages/basic-data/ChargeDrawer.vue
  9. 37 8
      pages/basic-data/baseData-table/baseDateTable.vue
  10. 810 52
      pages/basic-data/index.vue
  11. 1 1
      pages/equipment-monitoring/components/StorageInfo.vue
  12. 123 23
      pages/equipment-monitoring/components/batteryDrawe.vue
  13. 13 4
      pages/index/components/ChargerState.vue
  14. 86 33
      pages/index/index.vue
  15. 17 2
      pages/power-changer/index.scss
  16. 17 11
      pages/power-changer/index.vue
  17. BIN
      static/change/battery-anim4.gif
  18. BIN
      static/change/battery4.png
  19. 47 0
      uni_modules/uni-data-checkbox/changelog.md
  20. 821 0
      uni_modules/uni-data-checkbox/components/uni-data-checkbox/uni-data-checkbox.vue
  21. 84 0
      uni_modules/uni-data-checkbox/package.json
  22. 18 0
      uni_modules/uni-data-checkbox/readme.md
  23. 1 1
      uni_modules/uni-load-more/components/uni-load-more/i18n/zh-Hans.json
  24. 1 1
      uni_modules/uni-load-more/components/uni-load-more/i18n/zh-Hant.json
  25. 6 6
      uni_modules/uni-load-more/components/uni-load-more/uni-load-more.vue
  26. 35 0
      uni_modules/uni-number-box/changelog.md
  27. 233 0
      uni_modules/uni-number-box/components/uni-number-box/uni-number-box.vue
  28. 82 0
      uni_modules/uni-number-box/package.json
  29. 13 0
      uni_modules/uni-number-box/readme.md

+ 28 - 0
common/check.js

@@ -49,3 +49,31 @@ export function KeepDecimals(num,len =2 ){
     Decimals=Decimals.replace(/[^0-9]/g,'').slice(0,len) // 处理小数位中的无效字符,并截取指定长度
     return `${Number(integer)}.${Decimals || ''}` // 组装数据。并在处理小数位事,将无效字符处理成空串
 }
+export function powerFitler(value){
+  switch (value) {
+    case 0:
+      return '桩自主控制功率';
+    case 1:
+      return '功率值';
+    case 2:
+      return '功率百分比';
+    case 3:
+      return '输出电流';
+    default:
+      return '—';
+  }
+}
+export function cangFitler(value){
+  switch (value) {
+    case 0:
+      return '单四联切换';
+    case -1:
+      return '无';
+    case 1:
+      return '单连不可切换';
+    case 4:
+      return '四连不可切换';
+    default:
+      return '-';
+  }
+}

+ 52 - 0
common/http.js

@@ -161,4 +161,56 @@ export function getgunStartCharge(data) {
 //停止插枪充电
 export function getgunStopCharge(data) {
 	return request.post("/discharge/gunStopCharge",data)
+}
+//设备监控充电机获取设置功率
+export function getChargePower(data) {
+  return request.post("/discharge/getPower",data)
+}
+//仓位管理、基础数据
+export function encodeList(data) {
+	return request.post('/encode/list',data)
+}
+//删除仓位、基础数据
+export function delEncode(data) {
+	return request.post('/encode/del',data)
+}
+//添加仓位、基础数据
+export function addEncode(data) {
+	return request.post('/encode/add',data)
+}
+//编辑仓位、基础数据
+export function editEncode(data) {
+	return request.post('/encode/edit',data)
+}
+//基础数据-站控配置中转仓相关
+export function setStation(data) {
+	return request.post('/swap/setStation',data)
+}
+//基础数据-获取站控配置
+export function getOtherStation(data) {
+	return request.post('/swap/other',data)
+}
+//基础数据-设置温度
+export function setTemp(data){
+  return request.post(`/alarm/setTemp?temp=${data}`)
+}
+//基础-获取温度
+export function serchTemp(){
+	return request.post('/alarm/queryTemp')
+}
+//电池管理、基础数据
+export function batteryList(data) {
+	return request.post('/battery/list',data)
+}
+//删除电池、基础数据
+export function delBattery(data) {
+	return request.post('/battery/del',data)
+}
+//添加电池、基础数据
+export function addBattery(data) {
+	return request.post('/battery/add',data)
+}
+//编辑电池、基础数据
+export function editBattery(data) {
+	return request.post('/battery/edit',data)
 }

+ 11 - 4
components/BatteryInfo/BatteryInfo.vue

@@ -1,7 +1,7 @@
 <template>
 	<view class="battery-info" :class="[IsSelect?'SelectBorder':'defaultBorder']" @click="HandleBatterySelected(storeCode,storeState,getChgState)">
 		<view class="battery-header" :class="[storeState===1&&soc?'battery-have':'battery-null']">
-			<view class="battery-box" v-show="getChgState!=2 && storeState===1">
+			<view class="battery-box" :class="linktype===4?'battery4-box':''" v-show="getChgState!=2 && storeState===1">
 				<view class="batteryList">
 					<view class="battery-many" v-for="item in getBatteryNum" :key="item"
 						:style="{ 'bottom': item * 14 - 14 + 'px' }">
@@ -10,7 +10,7 @@
 				</view>
 				<span>SOC {{soc || '0'}}%</span>
 			</view>
-			<view class="battery-anmition" v-show="getChgState==2">
+			<view class="battery-anmition" :class="linktype===4?'battery-anmition4':''" v-show="getChgState==2">
 				<span>SOC {{soc || '0'}}%<br>{{chgEstimatedTime || '0'}}min 充满</span>
 			</view>
 		</view>
@@ -34,6 +34,7 @@
 			'BatterySelectAllArr',
 			'chgEstimatedTime',
 			'storeState',
+			'linktype',//单四连型号
 			'freezeState', //冻结状态
 			'comState', //电池通讯状态
 			'chargerComState', //充电机通讯状态
@@ -94,6 +95,7 @@
 		display: flex;
 		flex-direction: column;
 		cursor: pointer;
+		margin-left: 14px;
 		.battery-null{
 			background: #292D46;
 		}
@@ -113,7 +115,7 @@
 				margin: 0 10px;
 				position: relative;
 			}
-
+			
 			.battery-box {
 				width: 90px;
 				height: 136px;
@@ -161,7 +163,12 @@
 					}
 				}
 			}
-
+			.battery-anmition4{
+				background-image: url('~@/static/change/battery-anim4.gif');
+			}
+			.battery4-box{
+				background-image: url('~@/static/change/battery4.png');
+			}
 			span {
 				position: absolute;
 				width: 100%;

+ 4 - 4
components/Navbar/Navbar.vue

@@ -85,10 +85,10 @@
 			// this.getRoute()
 			this.getuserinfo()
 			this.getState()
-			this.curAlarmNum=setInterval(()=>{
-				this.cloudConnState()
-				this.getnum()
-			},1000)
+			// this.curAlarmNum=setInterval(()=>{
+			// 	this.cloudConnState()
+			// 	this.getnum()
+			// },1000)
 		},
 		destroyed() {
 			clearInterval(this.curAlarmNum)

+ 8 - 0
components/PublicDrawer/PublicDrawer.vue

@@ -38,6 +38,14 @@
 					this.$emit('HandleEditPlate')
 				}else if(this.title == '充电设置'){
 					
+				}else if(this.title=='新增仓位'){
+					this.$emit('AddCanginfo')
+				}else if(this.title=='编辑仓位'){
+					this.$emit('EditCangInfo')
+				}else if(this.title=='编辑电池'){
+					this.$emit('EditBatteryInfo')
+				}else if(this.title=='新增电池'){
+					this.$emit('AddBatteryinfo')
 				}
 			},
 			close(){

+ 2 - 2
pages/basic-data/BasicDrawer.vue

@@ -38,8 +38,8 @@
 <style lang="scss" scoped>
 	::v-deep .uni-forms-item__content {
 		background: rgba(255, 255, 255, 0);
-		border-radius: 2px 2px 2px 2px;
-		border: 1px solid #263042;
+		// border-radius: 2px 2px 2px 2px;
+		// border: 1px solid #263042;
 
 		.uni-easyinput__content {
 			background: none !important;

+ 43 - 0
pages/basic-data/BatteryDrawer.vue

@@ -0,0 +1,43 @@
+<template>
+	<view>
+		<uni-forms :modelValue="BatteryForm" ref="valueForm" :rules="rules">
+			<uni-forms-item label="电池编号SN:" required name="sn" label-align="right" label-width="138px">
+				<uni-easyinput type="text" :maxlength="30" v-model="BatteryForm.sn" placeholder="请输入电池编号" :clear="false"/>
+			</uni-forms-item>
+			<uni-forms-item label="长(cm):" required name="length" label-align="right" label-width="138px">
+				<uni-easyinput type="text" v-model.trim="BatteryForm.length" :maxlength="5" placeholder="请输入电池长度" :clear="false"/>
+			</uni-forms-item>
+			<uni-forms-item label="宽(cm):" required name="width" label-align="right" label-width="138px">
+				<uni-easyinput type="text" v-model.trim="BatteryForm.width" :maxlength="5" placeholder="请输入电池宽度" :clear="false"/>
+			</uni-forms-item>
+			<uni-forms-item label="高(cm):" required name="height" label-align="right" label-width="138px">
+				<uni-easyinput type="text" v-model.trim="BatteryForm.height" :maxlength="5" placeholder="请输入电池高度" :clear="false"/>
+			</uni-forms-item>
+			<uni-forms-item label="重量(kg):" required name="weight" label-align="right" label-width="138px">
+				<uni-easyinput type="text" v-model.trim="BatteryForm.weight" :maxlength="5" placeholder="请输入电池重量" :clear="false"/>
+			</uni-forms-item>
+		</uni-forms>
+	</view>
+</template>
+
+<script>
+	export default {
+		name: 'BatteryDrawer',
+		props: ['BatteryForm','rules'],
+		data() {
+			return {
+				// getbasicFrom:{}
+			}
+		},
+		methods:{
+		}
+	}
+</script>
+<style lang="scss" scoped>
+	
+	::v-deep .uni-forms-item {
+		width: 100% !important;
+		
+	}
+	
+</style>

+ 52 - 0
pages/basic-data/ChargeDrawer.vue

@@ -0,0 +1,52 @@
+<template>
+	<view>
+		<uni-forms :modelValue="setForm" ref="setvalueForm" :rules="rules">
+			<uni-forms-item label="仓位号:" required name="chargerId" label-align="right" label-width="138px">
+				<uni-easyinput type="text" :maxlength="2" @blur="getChargerId" v-model="setForm.chargerId" placeholder="请输入仓位号" :clear="false"/>
+			</uni-forms-item>
+			<uni-forms-item label="桩编号:" required name="chargerCode" label-align="right" label-width="138px">
+				<uni-easyinput type="text" v-model.trim="setForm.chargerCode" :maxlength="50" placeholder="请输入桩编号" :clear="false"/>
+			</uni-forms-item>
+			<uni-forms-item label="是否可换电:" required name="isSwap" label-align="right" label-width="138px">
+				<uni-data-select v-model.trim="setForm.isSwap" placeholder="请选择是否可换电" :localdata="rangePower"
+					 :clear="false"></uni-data-select>
+			</uni-forms-item>
+			<uni-forms-item label="充电连接控制方式:" required name="isCheck" label-align="right" label-width="138px">
+				<uni-data-select v-model.trim="setForm.isCheck" placeholder="请选择充电连接控制方式" :localdata="rangeCharge"
+					 :clear="false"></uni-data-select>
+			</uni-forms-item>
+			<!-- <uni-forms-item label="状态:" name="state" label-align="right" label-width="120px">
+				<uni-data-select v-model.trim="basicFrom.state" :localdata="range"
+					 :clear="false"></uni-data-select>
+			</uni-forms-item> -->
+		</uni-forms>
+	</view>
+	<!-- 剩个已充时长和落座信号没有对字段 -->
+</template>
+
+<script>
+	export default {
+		name: 'ChargeDrawer',
+		props: ['setForm','rangePower','rangeCharge','rules','changeChargerId'],
+		data() {
+			return {
+				// getbasicFrom:{}
+			}
+		},
+		methods:{
+			getChargerId() {
+				if(this.setForm.chargerId==0){
+					this.$emit('changeChargerId')
+				}
+			},
+		}
+	}
+</script>
+<style lang="scss" scoped>
+	
+	::v-deep .uni-forms-item {
+		width: 100% !important;
+		
+	}
+	
+</style>

+ 37 - 8
pages/basic-data/baseData-table/baseDateTable.vue

@@ -35,20 +35,26 @@
 						style="display:flex;table-layout: fixed;min-width: 100%;" @click.native="rowClick(content)">
 						<uni-td v-for="(header,hindex) in headers" :key="hindex" :width="header.widtd" align="center"
 							:style="{display:header.hidden?'none':'table-cell',textAlign:'center',
-					  left:fixedLeft(hindex),
-					  position:hindex<=columnFixed-1?'sticky':'unset',
-					  zIndex:hindex<=columnFixed-1?9:'unset',
-					  backgroundColor:'inherit'}">
+						  left:fixedLeft(hindex),
+						  position:hindex<=columnFixed-1?'sticky':'unset',
+						  zIndex:hindex<=columnFixed-1?9:'unset',
+						  backgroundColor:'inherit'}">
 							<template v-if="header.key == 'source'">
 								<text>{{content[header.key] === 0 ? '站控':'云端'}}</text>
 							</template>
-							<!-- <template v-else-if="header.key == 'state'">
-								<text>{{content[header.key] === 0 ? '停用':'启用'}}</text>
-							</template> -->
+							<template v-else-if="header.key == 'isSwap'">
+								<text>{{content[header.key] === 1 ? '是':content[header.key] === 0?'否':emptyString}}</text>
+							</template>
+							<template v-else-if="header.key == 'isCheck'">
+								<text>{{$checks.cangFitler(content[header.key])}}</text>
+							</template>
 							<template v-else>
 								<view v-if="header.label == '操作'" class="editColor">
-									<!-- <view @click="EditBacisData(content)">编辑</view> -->
+									<view @click="EditCangData(content)" v-if="isEdit===1">编辑</view>
 									<view @click="DelBacisData(content)" v-if="content['source']==0">删除</view>
+									<view @click="DelCangData(content)" v-if="isEdit===1">删除</view>
+									<view @click="EditBatteryData(content)" v-if="isEdit===2">编辑</view>
+									<view @click="DelBatteryData(content)" v-if="isEdit===2">删除</view>
 								</view>
 								<text v-else>{{content[header.key]||emptyString}}</text>
 							</template>
@@ -151,6 +157,11 @@
 			totalRow: {
 				type: Array,
 				default: () => []
+			},
+			//是否编辑
+			isEdit:{
+				type:Number,
+				default:0
 			}
 		},
 		mounted() {
@@ -257,11 +268,27 @@
 			EditBacisData(row) {
 				this.$emit('EditCarData', row)
 			},
+			//触发充电机仓位编辑
+			EditCangData(row){
+				this.$emit('EditCangData', row)
+			},
+			//触发电池仓位编辑
+			EditBatteryData(row){
+				this.$emit('EditBatteryData', row)
+			},
 			//删除车辆信息
 			DelBacisData(row) {
 				// console.log(row)
 				this.$emit('DelCarData', row.id)
 			},
+			//删除仓位信息
+			DelCangData(row) {
+				this.$emit('DelCangData', row.id)
+			},
+			//删除电池信息
+			DelBatteryData(row) {
+				this.$emit('DelBatteryData', row.id)
+			},
 			//点击排序表头时存储上次排序列名,并循环切换排序方式
 			doSort(item) {
 
@@ -430,6 +457,8 @@
 
 	.editColor {
 		color: #55B693;
+		display: flex;
+		justify-content:space-between;
 	}
 
 	.container {

File diff suppressed because it is too large
+ 810 - 52
pages/basic-data/index.vue


+ 1 - 1
pages/equipment-monitoring/components/StorageInfo.vue

@@ -213,7 +213,7 @@
 			},
 			//打开弹窗
 			set() {
-				this.$emit('drawer')
+			  this.$emit('drawer')
 			},
 			//切换仓内仓外
 			ChargingMode(chgType) {

+ 123 - 23
pages/equipment-monitoring/components/batteryDrawe.vue

@@ -11,20 +11,43 @@
 		</view>
 		<view class="main_drawe">
 			<uni-forms :modelValue="fromData">
-				<uni-forms-item label="当前充电:" name="name" label-align="right" label-width="120px">
-					<uni-easyinput type="text" v-model="fromData.comState== 0 ?'线束充电':'插枪充电'" placeholder="请输入"
-						disabled />
-				</uni-forms-item>
-				<uni-forms-item label="枪号:" name="arr" label-width="120px" label-align="right">
-					<uni-data-select v-model="fromData.Guncall" :localdata="fromData.arr" @change="changegun">
+				<view class="chargeAway">充电方式【{{fromData.chargerAway}}】</view>
+				<view class="chargeCont">
+					<view class="gunleft">
+						<view class="gun">A</view>
+						<view class="power">
+							<view>{{$checks.powerFitler(fromData.powerObj.powerType)}}</view>
+							<view>{{fromData.powerObj.power?fromData.powerObj.power+'kW':'—'}}</view>
+						</view>
+					</view>
+					<view class="gunleft" v-if="fromData.powerObj.type===4 || fromData.powerObj.type===2">
+						<view class="gun">B</view>
+						<view class="power">
+							<view>{{$checks.powerFitler(fromData.powerObj.powerType)}}</view>
+							<view>{{fromData.powerObj.power?fromData.powerObj.power+'kW':'—'}}</view>
+						</view>
+					</view>
+				</view>
+				<view class="chargeAway">设置</view>
+				<!-- <uni-forms-item label="当前充电:" name="name" label-align="right" label-width="120px">
+					<uni-easyinput type="text" v-model="fromData.comState== 0 ?'线束充电':'插枪充电'"
+						placeholder="请输入" disabled />
+				</uni-forms-item> -->
+
+				<uni-forms-item label="枪号:" name="arr" label-width="66px" label-align="right">
+					<uni-data-select v-model="fromData.Guncall" :localdata="fromData.arr"
+						@change="changegun">
 					</uni-data-select>
 				</uni-forms-item>
-				<uni-forms-item label="按类型设置:" name="arrType" label-width="120px" label-align="right">
-					<uni-data-select v-model="fromData.setType" :localdata="fromData.arrType" @change="changeId">
+				<uni-forms-item label="类型:" name="arrType" label-width="66px" label-align="right">
+					<uni-data-select v-model="fromData.setType" :localdata="fromData.arrType"
+						@change="changeId">
 					</uni-data-select>
 				</uni-forms-item>
-				<uni-forms-item label="充电功率:" name="name" label-align="right" label-width="120px" v-if="fromData.setType !=0">
-					<uni-easyinput type="number" v-model="fromData.powerNum" placeholder="请输入" maxlength="4"/>
+				<uni-forms-item label="功率:" name="name" label-align="right" label-width="66px"
+					v-if="fromData.setType !=0">
+					<uni-easyinput type="number" v-model="fromData.powerNum" placeholder="请输入"
+						maxlength="4" />
 					<view class="kwh">
 						{{fromData.setType == 2 ?'%': fromData.setType == 3 ?'A':'kW'}}
 					</view>
@@ -40,7 +63,7 @@
 		props: ['infodata'],
 		data() {
 			return {
-				
+
 				fromData: {
 					arr: [{
 						text: 'A枪',
@@ -69,16 +92,40 @@
 					comState: 1, //充电类型
 					Guncall: '',
 					setType: '',
-					cangnum:0,//仓号
-					powerNum:'',
+					cangnum: 0, //仓号
+					powerNum: '',
+					powerObj: {
+						type: null,
+						power: null,
+						powerType: null
+					}, //充电设置功率
+					chargerAway:null,
 				},
 
 
 			}
 		},
 		methods: {
+			//获取充个设置数据
+			getChargePower(){
+				let type=null
+				  if(this.infodata.chargerInfoVo.chgState===2){
+					type=1
+				  }else if(this.infodata.chargerInfoOneVo.chgState===2 && this.infodata.chargerInfoTwoVo.chgState===2){
+					type=2
+				  }else if(this.infodata.chargerInfoOneVo.chgState===2 && this.infodata.chargerInfoTwoVo.chgState!==2){
+					type=3
+				  }else if(this.infodata.chargerInfoOneVo.chgState!==2 && this.infodata.chargerInfoTwoVo.chgState===2){
+					type=4
+				  }
+				this.$http.getChargePower({chargerId:this.infodata.chargerInfoVo.chargerCode,type}).then(res=>{
+					if(res.code===0){
+					  this.fromData.powerObj=res.data
+					}
+				  })
+			},
 			//下拉事件
-			changeId() { 
+			changeId() {
 				console.log(123)
 			},
 			//下拉事件
@@ -91,15 +138,27 @@
 			},
 			// 保存
 			SubmitPublic() {
-				this.$emit('save',this.fromData)
+				this.$emit('save', this.fromData)
 			}
 		},
 		mounted() {
+			this.getChargePower()
 			this.fromData.comState = this.infodata.chgType
-			if(this.fromData.comState == 1){ //1是插枪充电 0是线束充电
-				this.fromData.arr = [ {text: "A枪",value: "0",},{text: "B枪",value: "1",}]
-			}else{
-				this.fromData.arr = [ {text: "A枪",value: "0",}]
+			if (this.fromData.comState == 1) { //1是插枪充电 0是线束充电
+				this.fromData.chargerAway='插枪充电'
+				this.fromData.arr = [{
+					text: "A枪",
+					value: "0",
+				}, {
+					text: "B枪",
+					value: "1",
+				}]
+			} else {
+				this.fromData.chargerAway='线束充电'
+				this.fromData.arr = [{
+					text: "A枪",
+					value: "0",
+				}]
 			}
 			this.fromData.cangnum = this.infodata.chargerInfoVo.chargerCode
 		}
@@ -117,7 +176,45 @@
 			color: #fff;
 		}
 	}
-
+	.chargeAway{
+	    background-color: #1c263a;
+	    width: 100%;
+	    height: 34px;
+	    line-height: 34px;
+	    color: white;
+	    font-weight: 600;
+	    font-size: 15px;
+	    text-indent: 15px;
+	    margin-bottom: 26px;
+	  }
+	  .chargeCont{
+	    display: flex;
+	    margin-left: 15px;
+		margin-bottom: 26px;
+	    .gunleft{
+	      display: flex;
+	      width: 50%;
+	      .gun{
+	        width: 56px;
+	        height: 56px;
+	        line-height: 56px;
+	        text-align: center;
+	        border: #1c263a solid 1px;
+	        color: white;
+	        font-size: 24px;
+	        font-weight: 600;
+	      }
+	      .power{
+	        display: flex;
+	        flex-direction: column;
+	        color: white;
+	        font-size: 16px;
+	        padding-left: 18px;
+	        justify-content: space-around;
+	      }
+	    }
+	
+	  }
 	.kwh {
 		width: 50px;
 		height: 35px;
@@ -135,7 +232,7 @@
 	::v-deep .uni-select__selector {
 		background: #111827;
 		border: 1px solid #263042;
-		color: #606266;
+		color: white;
 		z-index: 9999999;
 	}
 
@@ -154,7 +251,10 @@
 	::v-deep .uni-select__input-text {
 		color: #fff;
 	}
-
+	::v-deep .uni-forms-item__label{
+		color: white;
+		font-weight: bold;
+	}
 	.main_drawe {
 		padding: 20px;
 		margin-top: 80px;
@@ -240,4 +340,4 @@
 			}
 		}
 	}
-</style>
+</style>

+ 13 - 4
pages/index/components/ChargerState.vue

@@ -1,5 +1,5 @@
 <template>
-	<view>
+	<view class="chargeState">
 		<image :src="getchargeState"></image>
 	</view>
 </template>
@@ -39,8 +39,17 @@
 </script>
 
 <style lang="scss" scoped>
-	image {
-		width: 70px;
-		height: 70px;
+	.chargeState{
+		image {
+			width: 70px;
+			height: 70px;
+			padding-right: 41px;
+		}
+	}
+	.chargeState:last-child{
+		image{
+			padding: 0;
+		}
 	}
+	
 </style>

+ 86 - 33
pages/index/index.vue

@@ -59,35 +59,47 @@
 			<SubTitle title="设备状态" titleEng="DEVICE STATUS"></SubTitle>
 			<view class="statusShow">
 				<template v-if="stateList.length>0">
-				<view class="positon p-left"></view>
-				<view class="positon p-right"></view>
-				<view class="positon p-b-left"></view>
-				<view class="positon p-b-right"></view>
-				<view class="title">
-					<view class="first">
-						<image src="/static/index/title-left.png"></image>
-					</view>
-					<view class="second">智能换电站</view>
-					<view class="last">
-						<image src="/static/index/title-right.png">
-					</view>
-				</view>
-				<view class="line">
-					<image src="/static/index/line.png"></image>
-				</view>
-				<view class="changeList">
-					<view>
-						<image :src="robotResult"></image>
+					<view class="status-top">
+						<view class="positon p-left"></view>
+						<view class="positon p-right"></view>
+						<view class="positon p-b-left"></view>
+						<view class="positon p-b-right"></view>
+						<view class="title">
+							<view class="first">
+								<image src="/static/index/title-left.png"></image>
+							</view>
+							<view class="second">智能换电站</view>
+							<view class="last">
+								<image src="/static/index/title-right.png">
+							</view>
+						</view>
+						<view class="line">
+							<!-- <image src="/static/index/line.png"></image> -->
+							<view class="sx"></view>
+						</view>
 					</view>
-					<ChargerState v-for="item in stateList" :key="item.code" :chargerState="item.chargerState"></ChargerState>
-				</view>
-				<view class="borderList">
-					<view></view>
-					<view v-for="item in 8"></view>
-				</view>
-				<view class="batteryList">
-					<view></view>
-					<BatteryState v-for="item in stateList" :key="item.code" :batteryState="item.batteryState"></BatteryState>
+					<view class="stateList">
+					<scroll-view scroll-x="true" class="scroll_x">
+						<view>
+							<view class="lineBox">
+								<view class="line-child"  v-for="(item, index) in stateList.length"></view>
+							</view>
+							<view class="changeList">
+								<view>
+									<image :src="robotResult"></image>
+								</view>
+								<ChargerState v-for="(item,index) in stateList" :key="item.code" :chargerState="item.chargerState"></ChargerState>
+							</view>
+							<view class="borderList">
+								<view></view>
+								<view v-for="(item, index) in stateList.length"></view>
+							</view>
+							<view class="batteryList">
+								<view></view>
+								<BatteryState v-for="(item, index) in stateList" :key="item.code" :batteryState="item.batteryState"></BatteryState>
+							</view>
+						</view>
+					</scroll-view>
 				</view>
 				</template>
 			</view>
@@ -391,7 +403,7 @@
 				height: 386px;
 				border: 1px solid #334568;
 				box-sizing: border-box;
-				padding: 20px;
+				padding: 20px 0px;
 				position: relative;
 
 				.title {
@@ -429,22 +441,63 @@
 				}
 
 				.line {
-					text-align: center;
+					display: flex;
+					justify-content: center;
 					width: 100%;
-
+					.sx{
+						width: 1px;
+						height: 28px;
+						background-color: #334568;
+					}
 					image {
 						width: 889px;
 						height: 56px;
 					}
 				}
-
+				.status-top{
+					padding: 0px 20px;
+				}
+				.stateList{
+					width: 980px;
+					display: flex;
+					flex-direction: column;
+					overflow: hidden;
+					padding-left:20px;
+					.scroll_x {
+						width: 980px;
+						height: 100%;
+						// border: 1px solid red;
+					
+						::v-deep .uni-scroll-view-content {
+							display: flex;
+							view:first-child {
+								.battery-info {
+									margin-left: 0px;
+								}
+							}
+						}
+					}
+					.lineBox{
+						height: 28px;
+						border-left: #334568 solid 1px;
+						display: flex;
+						margin-left: 36px;
+						box-sizing: border-box;
+						.line-child{
+							width: 110px;
+							height: 28px;
+							border-top:#334568 solid 1px;
+							border-right:#334568 solid 1px;
+						}
+					}
+				}
 				.changeList {
 					display: flex;
-					justify-content: space-between;
 					margin-top: 8px;
 					image {
 						width: 70px;
 						height: 70px;
+						padding-right: 41px;
 					}
 				}
 

+ 17 - 2
pages/power-changer/index.scss

@@ -106,9 +106,24 @@ $titColor:#192233;
 		background-color: #111827;
 		margin-top: 18px;
 		.storeList{
-			display: flex;
-			justify-content: space-between;
+			width: 1000px;
+			display: flex;			
 			padding: 16px 20px;
+			overflow: hidden;
+			.scroll_x {
+				width: 100%;
+				height: 100%;
+				// border: 1px solid red;
+			
+				::v-deep .uni-scroll-view-content {
+					display: flex;
+					view:first-child {
+						.battery-info {
+							margin-left: 0px;
+						}
+					}
+				}
+			}
 		}
 	}
 	//选电模式结束

+ 17 - 11
pages/power-changer/index.vue

@@ -96,17 +96,23 @@
 							@click="ChangeModel(1)">手动选电</view>
 					</view>
 				</view>
-			</view>
-			<view class="storeList">
-				<!-- 电池列表信息 -->
-				<BatteryInfo v-for="(item, index) in storeInfoList" :soc="item.soc"
-					:chgState="item.chargerInfoVo.chgState" :chgEstimatedTime="item.chargerInfoVo.chgEstimatedTime"
-					:key="index" :storeState="item.storeState" :storeCode="item.storeCode"
-					:freezeState="item.freezeState" :comState="item.comState"
-					:chargerComState="item.chargerInfoVo.comState" :BatterySelectAllArr="BatterySelectAllArr"
-					:BatterySelected="BatterySelected" :IsSelect="BatteryIsSelectArr[index]" />
-				<!-- 电池信息结束 -->
-			</view>
+			</view>
+			
+			<view class="storeList">
+				<scroll-view scroll-x="true" class="scroll_x">
+					<view v-for="(item, index) in storeInfoList">
+						<!-- 电池列表信息 -->
+						<BatteryInfo :soc="item.soc"
+							:chgState="item.chargerInfoVo.chgState" :chgEstimatedTime="item.chargerInfoVo.chgEstimatedTime"
+							:key="index" :storeState="item.storeState" :storeCode="item.storeCode"
+							:freezeState="item.freezeState" :comState="item.comState" :linktype="item.chargerInfoVo.linktype"
+							:chargerComState="item.chargerInfoVo.comState" :BatterySelectAllArr="BatterySelectAllArr"
+							:BatterySelected="BatterySelected" :IsSelect="BatteryIsSelectArr[index]" />
+						<!-- 电池信息结束 -->
+					</view>
+				</scroll-view>
+			</view>
+			
 		</view>
 		<!-- 选电模式结束-->
 		<!-- 底部开始 -->

BIN
static/change/battery-anim4.gif


BIN
static/change/battery4.png


+ 47 - 0
uni_modules/uni-data-checkbox/changelog.md

@@ -0,0 +1,47 @@
+## 1.0.4(2024-01-27)
+- 修复 修复错别字chagne为change
+## 1.0.3(2022-09-16)
+- 可以使用 uni-scss 控制主题色
+## 1.0.2(2022-06-30)
+- 优化 在 uni-forms 中的依赖注入方式
+## 1.0.1(2022-02-07)
+- 修复 multiple 为 true 时,v-model 的值为 null 报错的 bug
+## 1.0.0(2021-11-19)
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-data-checkbox](https://uniapp.dcloud.io/component/uniui/uni-data-checkbox)
+## 0.2.5(2021-08-23)
+- 修复 在uni-forms中 modelValue 中不存在当前字段,当前字段必填写也不参与校验的问题
+## 0.2.4(2021-08-17)
+- 修复 单选 list 模式下 ,icon 为 left 时,选中图标不显示的问题
+## 0.2.3(2021-08-11)
+- 修复 在 uni-forms 中重置表单,错误信息无法清除的问题
+## 0.2.2(2021-07-30)
+- 优化 在uni-forms组件,与label不对齐的问题
+## 0.2.1(2021-07-27)
+- 修复 单选默认值为0不能选中的Bug
+## 0.2.0(2021-07-13)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 0.1.11(2021-07-06)
+- 优化 删除无用日志
+## 0.1.10(2021-07-05)
+- 修复 由 0.1.9 引起的非 nvue 端图标不显示的问题
+## 0.1.9(2021-07-05)
+- 修复 nvue 黑框样式问题
+## 0.1.8(2021-06-28)
+- 修复 selectedTextColor 属性不生效的Bug
+## 0.1.7(2021-06-02)
+- 新增 map 属性,可以方便映射text/value属性
+## 0.1.6(2021-05-26)
+- 修复 不关联服务空间的情况下组件报错的Bug
+## 0.1.5(2021-05-12)
+- 新增 组件示例地址
+## 0.1.4(2021-04-09)
+- 修复 nvue 下无法选中的问题
+## 0.1.3(2021-03-22)
+- 新增 disabled属性
+## 0.1.2(2021-02-24)
+- 优化 默认颜色显示
+## 0.1.1(2021-02-24)
+- 新增 支持nvue
+## 0.1.0(2021-02-18)
+- “暂无数据”显示居中

+ 821 - 0
uni_modules/uni-data-checkbox/components/uni-data-checkbox/uni-data-checkbox.vue

@@ -0,0 +1,821 @@
+<template>
+	<view class="uni-data-checklist" :style="{'margin-top':isTop+'px'}">
+		<template v-if="!isLocal">
+			<view class="uni-data-loading">
+				<uni-load-more v-if="!mixinDatacomErrorMessage" status="loading" iconType="snow" :iconSize="18" :content-text="contentText"></uni-load-more>
+				<text v-else>{{mixinDatacomErrorMessage}}</text>
+			</view>
+		</template>
+		<template v-else>
+			<checkbox-group v-if="multiple" class="checklist-group" :class="{'is-list':mode==='list' || wrap}" @change="change">
+				<label class="checklist-box" :class="['is--'+mode,item.selected?'is-checked':'',(disabled || !!item.disabled)?'is-disable':'',index!==0&&mode==='list'?'is-list-border':'']"
+				 :style="item.styleBackgroud" v-for="(item,index) in dataList" :key="index">
+					<checkbox class="hidden" hidden :disabled="disabled || !!item.disabled" :value="item[map.value]+''" :checked="item.selected" />
+					<view v-if="(mode !=='tag' && mode !== 'list') || ( mode === 'list' && icon === 'left')" class="checkbox__inner"  :style="item.styleIcon">
+						<view class="checkbox__inner-icon"></view>
+					</view>
+					<view class="checklist-content" :class="{'list-content':mode === 'list' && icon ==='left'}">
+						<text class="checklist-text" :style="item.styleIconText">{{item[map.text]}}</text>
+						<view v-if="mode === 'list' && icon === 'right'" class="checkobx__list" :style="item.styleBackgroud"></view>
+					</view>
+				</label>
+			</checkbox-group>
+			<radio-group v-else class="checklist-group" :class="{'is-list':mode==='list','is-wrap':wrap}" @change="change">
+				<!-- -->
+				<label class="checklist-box" :class="['is--'+mode,item.selected?'is-checked':'',(disabled || !!item.disabled)?'is-disable':'',index!==0&&mode==='list'?'is-list-border':'']"
+				 :style="item.styleBackgroud" v-for="(item,index) in dataList" :key="index">
+					<radio class="hidden" hidden :disabled="disabled || item.disabled" :value="item[map.value]+''" :checked="item.selected" />
+					<view v-if="(mode !=='tag' && mode !== 'list') || ( mode === 'list' && icon === 'left')" class="radio__inner"
+					 :style="item.styleBackgroud">
+						<view class="radio__inner-icon" :style="item.styleIcon"></view>
+					</view>
+					<view class="checklist-content" :class="{'list-content':mode === 'list' && icon ==='left'}">
+						<text class="checklist-text" :style="item.styleIconText">{{item[map.text]}}</text>
+						<view v-if="mode === 'list' && icon === 'right'" :style="item.styleRightIcon" class="checkobx__list"></view>
+					</view>
+				</label>
+			</radio-group>
+		</template>
+	</view>
+</template>
+
+<script>
+	/**
+	 * DataChecklist 数据选择器
+	 * @description 通过数据渲染 checkbox 和 radio
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=xxx
+	 * @property {String} mode = [default| list | button | tag] 显示模式
+	 * @value default  	默认横排模式
+	 * @value list		列表模式
+	 * @value button	按钮模式
+	 * @value tag 		标签模式
+	 * @property {Boolean} multiple = [true|false] 是否多选
+	 * @property {Array|String|Number} value 默认值
+	 * @property {Array} localdata 本地数据 ,格式 [{text:'',value:''}]
+	 * @property {Number|String} min 最小选择个数 ,multiple为true时生效
+	 * @property {Number|String} max 最大选择个数 ,multiple为true时生效
+	 * @property {Boolean} wrap 是否换行显示
+	 * @property {String} icon = [left|right]  list 列表模式下icon显示位置
+	 * @property {Boolean} selectedColor 选中颜色
+	 * @property {Boolean} emptyText 没有数据时显示的文字 ,本地数据无效
+	 * @property {Boolean} selectedTextColor 选中文本颜色,如不填写则自动显示
+	 * @property {Object} map 字段映射, 默认 map={text:'text',value:'value'}
+	 * @value left 左侧显示
+	 * @value right 右侧显示
+	 * @event {Function} change  选中发生变化触发
+	 */
+
+	export default {
+		name: 'uniDataChecklist',
+		mixins: [uniCloud.mixinDatacom || {}],
+		emits:['input','update:modelValue','change'],
+		props: {
+			mode: {
+				type: String,
+				default: 'default'
+			},
+
+			multiple: {
+				type: Boolean,
+				default: false
+			},
+			value: {
+				type: [Array, String, Number],
+				default () {
+					return ''
+				}
+			},
+			// TODO vue3
+			modelValue: {
+				type: [Array, String, Number],
+				default() {
+					return '';
+				}
+			},
+			localdata: {
+				type: Array,
+				default () {
+					return []
+				}
+			},
+			min: {
+				type: [Number, String],
+				default: ''
+			},
+			max: {
+				type: [Number, String],
+				default: ''
+			},
+			wrap: {
+				type: Boolean,
+				default: false
+			},
+			icon: {
+				type: String,
+				default: 'left'
+			},
+			selectedColor: {
+				type: String,
+				default: ''
+			},
+			selectedTextColor: {
+				type: String,
+				default: ''
+			},
+			emptyText:{
+				type: String,
+				default: '暂无数据'
+			},
+			disabled:{
+				type: Boolean,
+				default: false
+			},
+			map:{
+				type: Object,
+				default(){
+					return {
+						text:'text',
+						value:'value'
+					}
+				}
+			}
+		},
+		watch: {
+			localdata: {
+				handler(newVal) {
+					this.range = newVal
+					this.dataList = this.getDataList(this.getSelectedValue(newVal))
+				},
+				deep: true
+			},
+			mixinDatacomResData(newVal) {
+				this.range = newVal
+				this.dataList = this.getDataList(this.getSelectedValue(newVal))
+			},
+			value(newVal) {
+				this.dataList = this.getDataList(newVal)
+				// fix by mehaotian is_reset 在 uni-forms 中定义
+				// if(!this.is_reset){
+				// 	this.is_reset = false
+				// 	this.formItem && this.formItem.setValue(newVal)
+				// }
+			},
+			modelValue(newVal) {
+				this.dataList = this.getDataList(newVal);
+				// if(!this.is_reset){
+				// 	this.is_reset = false
+				// 	this.formItem && this.formItem.setValue(newVal)
+				// }
+			}
+		},
+		data() {
+			return {
+				dataList: [],
+				range: [],
+				contentText: {
+					contentdown: '查看更多',
+					contentrefresh: '加载中',
+					contentnomore: '没有更多'
+				},
+				isLocal:true,
+				styles: {
+					selectedColor: '#2979ff',
+					selectedTextColor: '#666',
+				},
+				isTop:0
+			};
+		},
+		computed:{
+			dataValue(){
+				if(this.value === '')return this.modelValue
+				if(this.modelValue === '') return this.value
+				return this.value
+			}
+		},
+		created() {
+			// this.form = this.getForm('uniForms')
+			// this.formItem = this.getForm('uniFormsItem')
+			// this.formItem && this.formItem.setValue(this.value)
+
+			// if (this.formItem) {
+			// 	this.isTop = 6
+			// 	if (this.formItem.name) {
+			// 		// 如果存在name添加默认值,否则formData 中不存在这个字段不校验
+			// 		if(!this.is_reset){
+			// 			this.is_reset = false
+			// 			this.formItem.setValue(this.dataValue)
+			// 		}
+			// 		this.rename = this.formItem.name
+			// 		this.form.inputChildrens.push(this)
+			// 	}
+			// }
+
+			if (this.localdata && this.localdata.length !== 0) {
+				this.isLocal = true
+				this.range = this.localdata
+				this.dataList = this.getDataList(this.getSelectedValue(this.range))
+			} else {
+				if (this.collection) {
+					this.isLocal = false
+					this.loadData()
+				}
+			}
+		},
+		methods: {
+			loadData() {
+				this.mixinDatacomGet().then(res=>{
+					this.mixinDatacomResData = res.result.data
+					if(this.mixinDatacomResData.length === 0){
+						this.isLocal = false
+						this.mixinDatacomErrorMessage = this.emptyText
+					}else{
+						this.isLocal = true
+					}
+				}).catch(err=>{
+					this.mixinDatacomErrorMessage = err.message
+				})
+			},
+			/**
+			 * 获取父元素实例
+			 */
+			getForm(name = 'uniForms') {
+				let parent = this.$parent;
+				let parentName = parent.$options.name;
+				while (parentName !== name) {
+					parent = parent.$parent;
+					if (!parent) return false
+					parentName = parent.$options.name;
+				}
+				return parent;
+			},
+			change(e) {
+				const values = e.detail.value
+
+				let detail = {
+					value: [],
+					data: []
+				}
+
+				if (this.multiple) {
+					this.range.forEach(item => {
+
+						if (values.includes(item[this.map.value] + '')) {
+							detail.value.push(item[this.map.value])
+							detail.data.push(item)
+						}
+					})
+				} else {
+					const range = this.range.find(item => (item[this.map.value] + '') === values)
+					if (range) {
+						detail = {
+							value: range[this.map.value],
+							data: range
+						}
+					}
+				}
+				// this.formItem && this.formItem.setValue(detail.value)
+				// TODO 兼容 vue2
+				this.$emit('input', detail.value);
+				// // TOTO 兼容 vue3
+				this.$emit('update:modelValue', detail.value);
+				this.$emit('change', {
+					detail
+				})
+				if (this.multiple) {
+					// 如果 v-model 没有绑定 ,则走内部逻辑
+					// if (this.value.length === 0) {
+					this.dataList = this.getDataList(detail.value, true)
+					// }
+				} else {
+					this.dataList = this.getDataList(detail.value)
+				}
+			},
+
+			/**
+			 * 获取渲染的新数组
+			 * @param {Object} value 选中内容
+			 */
+			getDataList(value) {
+				// 解除引用关系,破坏原引用关系,避免污染源数据
+				let dataList = JSON.parse(JSON.stringify(this.range))
+				let list = []
+				if (this.multiple) {
+					if (!Array.isArray(value)) {
+						value = []
+					}
+				}
+				dataList.forEach((item, index) => {
+					item.disabled = item.disable || item.disabled || false
+					if (this.multiple) {
+						if (value.length > 0) {
+							let have = value.find(val => val === item[this.map.value])
+							item.selected = have !== undefined
+						} else {
+							item.selected = false
+						}
+					} else {
+						item.selected = value === item[this.map.value]
+					}
+
+					list.push(item)
+				})
+				return this.setRange(list)
+			},
+			/**
+			 * 处理最大最小值
+			 * @param {Object} list
+			 */
+			setRange(list) {
+				let selectList = list.filter(item => item.selected)
+				let min = Number(this.min) || 0
+				let max = Number(this.max) || ''
+				list.forEach((item, index) => {
+					if (this.multiple) {
+						if (selectList.length <= min) {
+							let have = selectList.find(val => val[this.map.value] === item[this.map.value])
+							if (have !== undefined) {
+								item.disabled = true
+							}
+						}
+
+						if (selectList.length >= max && max !== '') {
+							let have = selectList.find(val => val[this.map.value] === item[this.map.value])
+							if (have === undefined) {
+								item.disabled = true
+							}
+						}
+					}
+					this.setStyles(item, index)
+					list[index] = item
+				})
+				return list
+			},
+			/**
+			 * 设置 class
+			 * @param {Object} item
+			 * @param {Object} index
+			 */
+			setStyles(item, index) {
+				//  设置自定义样式
+				item.styleBackgroud = this.setStyleBackgroud(item)
+				item.styleIcon = this.setStyleIcon(item)
+				item.styleIconText = this.setStyleIconText(item)
+				item.styleRightIcon = this.setStyleRightIcon(item)
+			},
+
+			/**
+			 * 获取选中值
+			 * @param {Object} range
+			 */
+			getSelectedValue(range) {
+				if (!this.multiple) return this.dataValue
+				let selectedArr = []
+				range.forEach((item) => {
+					if (item.selected) {
+						selectedArr.push(item[this.map.value])
+					}
+				})
+				return this.dataValue.length > 0 ? this.dataValue : selectedArr
+			},
+
+			/**
+			 * 设置背景样式
+			 */
+			setStyleBackgroud(item) {
+				let styles = {}
+				let selectedColor = this.selectedColor?this.selectedColor:'#2979ff'
+				if (this.selectedColor) {
+					if (this.mode !== 'list') {
+						styles['border-color'] = item.selected?selectedColor:'#DCDFE6'
+					}
+					if (this.mode === 'tag') {
+						styles['background-color'] = item.selected? selectedColor:'#f5f5f5'
+					}
+				}
+				let classles = ''
+				for (let i in styles) {
+					classles += `${i}:${styles[i]};`
+				}
+				return classles
+			},
+			setStyleIcon(item) {
+				let styles = {}
+				let classles = ''
+				if (this.selectedColor) {
+					let selectedColor = this.selectedColor?this.selectedColor:'#2979ff'
+					styles['background-color'] = item.selected?selectedColor:'#fff'
+					styles['border-color'] = item.selected?selectedColor:'#DCDFE6'
+					
+					if(!item.selected && item.disabled){
+						styles['background-color'] = '#F2F6FC'
+						styles['border-color'] = item.selected?selectedColor:'#DCDFE6'
+					}
+				}
+				for (let i in styles) {
+					classles += `${i}:${styles[i]};`
+				}
+				return classles
+			},
+			setStyleIconText(item) {
+				let styles = {}
+				let classles = ''
+				if (this.selectedColor) {
+					let selectedColor = this.selectedColor?this.selectedColor:'#2979ff'
+					if (this.mode === 'tag') {
+						styles.color = item.selected?(this.selectedTextColor?this.selectedTextColor:'#fff'):'#666'
+					} else {
+						styles.color = item.selected?(this.selectedTextColor?this.selectedTextColor:selectedColor):'#666'
+					}
+					if(!item.selected && item.disabled){
+						styles.color = '#999'
+					}
+				}
+				for (let i in styles) {
+					classles += `${i}:${styles[i]};`
+				}
+				return classles
+			},
+			setStyleRightIcon(item) {
+				let styles = {}
+				let classles = ''
+				if (this.mode === 'list') {
+					styles['border-color'] = item.selected?this.styles.selectedColor:'#DCDFE6'
+				}
+				for (let i in styles) {
+					classles += `${i}:${styles[i]};`
+				}
+
+				return classles
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	$uni-primary: #2979ff !default;
+	$border-color: #DCDFE6;
+	$disable:0.4;
+
+	@mixin flex {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+	}
+
+	.uni-data-loading {
+		@include flex;
+		flex-direction: row;
+		justify-content: center;
+		align-items: center;
+		height: 36px;
+		padding-left: 10px;
+		color: #999;
+	}
+
+	.uni-data-checklist {
+		position: relative;
+		z-index: 0;
+		flex: 1;
+		// 多选样式
+		.checklist-group {
+			@include flex;
+			flex-direction: row;
+			flex-wrap: wrap;
+
+			&.is-list {
+				flex-direction: column;
+			}
+
+			.checklist-box {
+				@include flex;
+				flex-direction: row;
+				align-items: center;
+				position: relative;
+				margin: 5px 0;
+				margin-right: 25px;
+
+				.hidden {
+					position: absolute;
+					opacity: 0;
+				}
+
+				// 文字样式
+				.checklist-content {
+					@include flex;
+					flex: 1;
+					flex-direction: row;
+					align-items: center;
+					justify-content: space-between;
+					.checklist-text {
+						font-size: 14px;
+						color: #666;
+						margin-left: 5px;
+						line-height: 14px;
+					}
+
+					.checkobx__list {
+						border-right-width: 1px;
+						border-right-color: #007aff;
+						border-right-style: solid;
+						border-bottom-width:1px;
+						border-bottom-color: #007aff;
+						border-bottom-style: solid;
+						height: 12px;
+						width: 6px;
+						left: -5px;
+						transform-origin: center;
+						transform: rotate(45deg);
+						opacity: 0;
+					}
+				}
+
+				// 多选样式
+				.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: 4px;
+					background-color: #fff;
+					z-index: 1;
+					.checkbox__inner-icon {
+						position: absolute;
+						/* #ifdef APP-NVUE */
+						top: 2px;
+						/* #endif */
+						/* #ifndef APP-NVUE */
+						top: 1px;
+						/* #endif */
+						left: 5px;
+						height: 8px;
+						width: 4px;
+						border-right-width: 1px;
+						border-right-color: #fff;
+						border-right-style: solid;
+						border-bottom-width:1px ;
+						border-bottom-color: #fff;
+						border-bottom-style: solid;
+						opacity: 0;
+						transform-origin: center;
+						transform: rotate(40deg);
+					}
+				}
+
+				// 单选样式
+				.radio__inner {
+					@include flex;
+					/* #ifndef APP-NVUE */
+					flex-shrink: 0;
+					box-sizing: border-box;
+					/* #endif */
+					justify-content: center;
+					align-items: center;
+					position: relative;
+					width: 16px;
+					height: 16px;
+					border: 1px solid $border-color;
+					border-radius: 16px;
+					background-color: #fff;
+					z-index: 1;
+
+					.radio__inner-icon {
+						width: 8px;
+						height: 8px;
+						border-radius: 10px;
+						opacity: 0;
+					}
+				}
+
+				// 默认样式
+				&.is--default {
+
+					// 禁用
+					&.is-disable {
+						/* #ifdef H5 */
+						cursor: not-allowed;
+						/* #endif */
+						.checkbox__inner {
+							background-color: #F2F6FC;
+							border-color: $border-color;
+							/* #ifdef H5 */
+							cursor: not-allowed;
+							/* #endif */
+						}
+
+						.radio__inner {
+							background-color: #F2F6FC;
+							border-color: $border-color;
+						}
+						.checklist-text {
+							color: #999;
+						}
+					}
+
+					// 选中
+					&.is-checked {
+						.checkbox__inner {
+							border-color: $uni-primary;
+							background-color: $uni-primary;
+
+							.checkbox__inner-icon {
+								opacity: 1;
+								transform: rotate(45deg);
+							}
+						}
+						.radio__inner {
+							border-color: $uni-primary;
+							.radio__inner-icon {
+								opacity: 1;
+								background-color: $uni-primary;
+							}
+						}
+						.checklist-text {
+							color: $uni-primary;
+						}
+						// 选中禁用
+						&.is-disable {
+							.checkbox__inner {
+								opacity: $disable;
+							}
+
+							.checklist-text {
+								opacity: $disable;
+							}
+							.radio__inner {
+								opacity: $disable;
+							}
+						}
+					}
+				}
+
+				// 按钮样式
+				&.is--button {
+					margin-right: 10px;
+					padding: 5px 10px;
+					border: 1px $border-color solid;
+					border-radius: 3px;
+					transition: border-color 0.2s;
+
+					// 禁用
+					&.is-disable {
+						/* #ifdef H5 */
+						cursor: not-allowed;
+						/* #endif */
+						border: 1px #eee solid;
+						opacity: $disable;
+						.checkbox__inner {
+							background-color: #F2F6FC;
+							border-color: $border-color;
+							/* #ifdef H5 */
+							cursor: not-allowed;
+							/* #endif */
+						}
+						.radio__inner {
+							background-color: #F2F6FC;
+							border-color: $border-color;
+							/* #ifdef H5 */
+							cursor: not-allowed;
+							/* #endif */
+						}
+						.checklist-text {
+							color: #999;
+						}
+					}
+
+					&.is-checked {
+						border-color: $uni-primary;
+						.checkbox__inner {
+							border-color: $uni-primary;
+							background-color: $uni-primary;
+							.checkbox__inner-icon {
+								opacity: 1;
+								transform: rotate(45deg);
+							}
+						}
+
+						.radio__inner {
+							border-color: $uni-primary;
+
+							.radio__inner-icon {
+								opacity: 1;
+								background-color: $uni-primary;
+							}
+						}
+
+						.checklist-text {
+							color: $uni-primary;
+						}
+
+						// 选中禁用
+						&.is-disable {
+							opacity: $disable;
+						}
+					}
+				}
+
+				// 标签样式
+				&.is--tag {
+					margin-right: 10px;
+					padding: 5px 10px;
+					border: 1px $border-color solid;
+					border-radius: 3px;
+					background-color: #f5f5f5;
+
+					.checklist-text {
+						margin: 0;
+						color: #666;
+					}
+
+					// 禁用
+					&.is-disable {
+						/* #ifdef H5 */
+						cursor: not-allowed;
+						/* #endif */
+						opacity: $disable;
+					}
+
+					&.is-checked {
+						background-color: $uni-primary;
+						border-color: $uni-primary;
+
+						.checklist-text {
+							color: #fff;
+						}
+					}
+				}
+				// 列表样式
+				&.is--list {
+					/* #ifndef APP-NVUE */
+					display: flex;
+					/* #endif */
+					padding: 10px 15px;
+					padding-left: 0;
+					margin: 0;
+
+					&.is-list-border {
+						border-top: 1px #eee solid;
+					}
+
+					// 禁用
+					&.is-disable {
+						/* #ifdef H5 */
+						cursor: not-allowed;
+						/* #endif */
+						.checkbox__inner {
+							background-color: #F2F6FC;
+							border-color: $border-color;
+							/* #ifdef H5 */
+							cursor: not-allowed;
+							/* #endif */
+						}
+						.checklist-text {
+							color: #999;
+						}
+					}
+
+					&.is-checked {
+						.checkbox__inner {
+							border-color: $uni-primary;
+							background-color: $uni-primary;
+
+							.checkbox__inner-icon {
+								opacity: 1;
+								transform: rotate(45deg);
+							}
+						}
+						.radio__inner {
+							.radio__inner-icon {
+								opacity: 1;
+							}
+						}
+						.checklist-text {
+							color: $uni-primary;
+						}
+
+						.checklist-content {
+							.checkobx__list {
+								opacity: 1;
+								border-color: $uni-primary;
+							}
+						}
+
+						// 选中禁用
+						&.is-disable {
+							.checkbox__inner {
+								opacity: $disable;
+							}
+
+							.checklist-text {
+								opacity: $disable;
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+</style>

+ 84 - 0
uni_modules/uni-data-checkbox/package.json

@@ -0,0 +1,84 @@
+{
+  "id": "uni-data-checkbox",
+  "displayName": "uni-data-checkbox 数据选择器",
+  "version": "1.0.4",
+  "description": "通过数据驱动的单选框和复选框",
+  "keywords": [
+    "uni-ui",
+    "checkbox",
+    "单选",
+    "多选",
+    "单选多选"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": "^3.1.1"
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+"dcloudext": {
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
+    "type": "component-vue"
+  },
+  "uni_modules": {
+    "dependencies": ["uni-load-more","uni-scss"],
+    "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"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}

+ 18 - 0
uni_modules/uni-data-checkbox/readme.md

@@ -0,0 +1,18 @@
+
+
+## DataCheckbox 数据驱动的单选复选框
+> **组件名:uni-data-checkbox**
+> 代码块: `uDataCheckbox`
+
+
+本组件是基于uni-app基础组件checkbox的封装。本组件要解决问题包括:
+
+1. 数据绑定型组件:给本组件绑定一个data,会自动渲染一组候选内容。再以往,开发者需要编写不少代码实现类似功能
+2. 自动的表单校验:组件绑定了data,且符合[uni-forms](https://ext.dcloud.net.cn/plugin?id=2773)组件的表单校验规范,搭配使用会自动实现表单校验
+3. 本组件合并了单选多选
+4. 本组件有若干风格选择,如普通的单选多选框、并列button风格、tag风格。开发者可以快速选择需要的风格。但作为一个封装组件,样式代码虽然不用自己写了,却会牺牲一定的样式自定义性
+
+在uniCloud开发中,`DB Schema`中配置了enum枚举等类型后,在web控制台的[自动生成表单](https://uniapp.dcloud.io/uniCloud/schema?id=autocode)功能中,会自动生成``uni-data-checkbox``组件并绑定好data
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-data-checkbox)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 

+ 1 - 1
uni_modules/uni-load-more/components/uni-load-more/i18n/zh-Hans.json

@@ -1,5 +1,5 @@
 {
 	"uni-load-more.contentdown": "上拉显示更多",
 	"uni-load-more.contentrefresh": "正在加载...",
-	"uni-load-more.contentnomore": "没有更多了"
+	"uni-load-more.contentnomore": "没有更多数据了"
 }

+ 1 - 1
uni_modules/uni-load-more/components/uni-load-more/i18n/zh-Hant.json

@@ -1,5 +1,5 @@
 {
 	"uni-load-more.contentdown": "上拉顯示更多",
 	"uni-load-more.contentrefresh": "正在加載...",
-	"uni-load-more.contentnomore": "沒有更多了"
+	"uni-load-more.contentnomore": "沒有更多數據了"
 }

+ 6 - 6
uni_modules/uni-load-more/components/uni-load-more/uni-load-more.vue

@@ -6,28 +6,28 @@
 			class="uni-load-more__img uni-load-more__img--nvue"></loading-indicator>
 		<!-- #endif -->
 		<!-- #ifdef H5 -->
-		<!-- <svg width="24" height="24" viewBox="25 25 50 50"
+		<svg width="24" height="24" viewBox="25 25 50 50"
 			v-if="!webviewHide && (iconType==='circle' || iconType==='auto' && platform === 'android') && status === 'loading' && showIcon"
 			:style="{width:iconSize+'px',height:iconSize+'px'}"
 			class="uni-load-more__img uni-load-more__img--android-H5">
 			<circle cx="50" cy="50" r="20" fill="none" :style="{color:color}" :stroke-width="3"></circle>
-		</svg> -->
+		</svg>
 		<!-- #endif -->
 		<!-- #ifndef APP-NVUE || H5 -->
-		<!-- <view
+		<view
 			v-if="!webviewHide && (iconType==='circle' || iconType==='auto' && platform === 'android') && status === 'loading' && showIcon"
 			:style="{width:iconSize+'px',height:iconSize+'px'}"
 			class="uni-load-more__img uni-load-more__img--android-MP">
 			<view class="uni-load-more__img-icon" :style="{borderTopColor:color,borderTopWidth:iconSize/12}"></view>
 			<view class="uni-load-more__img-icon" :style="{borderTopColor:color,borderTopWidth:iconSize/12}"></view>
 			<view class="uni-load-more__img-icon" :style="{borderTopColor:color,borderTopWidth:iconSize/12}"></view>
-		</view> -->
+		</view>
 		<!-- #endif -->
 		<!-- #ifndef APP-NVUE -->
-		<!-- <view v-else-if="!webviewHide && status === 'loading' && showIcon"
+		<view v-else-if="!webviewHide && status === 'loading' && showIcon"
 			:style="{width:iconSize+'px',height:iconSize+'px'}" class="uni-load-more__img uni-load-more__img--ios-H5">
 			<image :src="imgBase64" mode="widthFix"></image>
-		</view> -->
+		</view>
 		<!-- #endif -->
 		<text v-if="showText" class="uni-load-more__text"
 			:style="{color: color}">{{ status === 'more' ? contentdownText : status === 'loading' ? contentrefreshText : contentnomoreText }}</text>

+ 35 - 0
uni_modules/uni-number-box/changelog.md

@@ -0,0 +1,35 @@
+## 1.2.6(2024-02-22)
+- 新增 设置宽度属性width(单位:px)
+## 1.2.5(2024-02-21)
+- 修复 step步长小于1时,键盘类型为number的bug
+## 1.2.4(2024-02-02)
+- 修复 加减号垂直位置偏移样式问题
+## 1.2.3(2023-05-23)
+- 更新示例工程
+## 1.2.2(2023-05-08)
+- 修复 change 事件执行顺序错误的问题
+## 1.2.1(2021-11-22)
+- 修复 vue3中某些scss变量无法找到的问题
+## 1.2.0(2021-11-19)
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-number-box](https://uniapp.dcloud.io/component/uniui/uni-number-box)
+## 1.1.2(2021-11-09) 
+- 新增 提供组件设计资源,组件样式调整
+## 1.1.1(2021-07-30)
+- 优化 vue3下事件警告的问题
+## 1.1.0(2021-07-13)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 1.0.7(2021-05-12)
+- 新增 组件示例地址
+## 1.0.6(2021-04-20)
+- 修复 uni-number-box 浮点数运算不精确的 bug
+- 修复 uni-number-box change 事件触发不正确的 bug
+- 新增 uni-number-box v-model 双向绑定
+## 1.0.5(2021-02-05)
+- 调整为uni_modules目录规范
+
+## 1.0.7(2021-02-05)
+- 调整为uni_modules目录规范
+- 新增 支持 v-model
+- 新增 支持 focus、blur 事件
+- 新增 支持 PC 端

+ 233 - 0
uni_modules/uni-number-box/components/uni-number-box/uni-number-box.vue

@@ -0,0 +1,233 @@
+<template>
+	<view class="uni-numbox">
+		<view @click="_calcValue('minus')" class="uni-numbox__minus uni-numbox-btns" :style="{background}">
+			<text class="uni-numbox--text" :class="{ 'uni-numbox--disabled': inputValue <= min || disabled }"
+				:style="{color}">-</text>
+		</view>
+		<input :disabled="disabled" @focus="_onFocus" @blur="_onBlur" class="uni-numbox__value"
+			:type="step<1?'digit':'number'" v-model="inputValue" :style="{background, color, width:widthWithPx}" />
+		<view @click="_calcValue('plus')" class="uni-numbox__plus uni-numbox-btns" :style="{background}">
+			<text class="uni-numbox--text" :class="{ 'uni-numbox--disabled': inputValue >= max || disabled }"
+				:style="{color}">+</text>
+		</view>
+	</view>
+</template>
+<script>
+	/**
+	 * NumberBox 数字输入框
+	 * @description 带加减按钮的数字输入框
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=31
+	 * @property {Number} value 输入框当前值
+	 * @property {Number} min 最小值
+	 * @property {Number} max 最大值
+	 * @property {Number} step 每次点击改变的间隔大小
+	 * @property {String} background 背景色
+	 * @property {String} color 字体颜色(前景色)
+	 * @property {Number} width 输入框宽度(单位:px)
+	 * @property {Boolean} disabled = [true|false] 是否为禁用状态
+	 * @event {Function} change 输入框值改变时触发的事件,参数为输入框当前的 value
+	 * @event {Function} focus 输入框聚焦时触发的事件,参数为 event 对象
+	 * @event {Function} blur 输入框失焦时触发的事件,参数为 event 对象
+	 */
+
+	export default {
+		name: "UniNumberBox",
+		emits: ['change', 'input', 'update:modelValue', 'blur', 'focus'],
+		props: {
+			value: {
+				type: [Number, String],
+				default: 1
+			},
+			modelValue: {
+				type: [Number, String],
+				default: 1
+			},
+			min: {
+				type: Number,
+				default: 0
+			},
+			max: {
+				type: Number,
+				default: 100
+			},
+			step: {
+				type: Number,
+				default: 1
+			},
+			background: {
+				type: String,
+				default: '#f5f5f5'
+			},
+			color: {
+				type: String,
+				default: '#333'
+			},
+			disabled: {
+				type: Boolean,
+				default: false
+			},
+			width: {
+				type: Number,
+				default: 40,
+			}
+		},
+		data() {
+			return {
+				inputValue: 0
+			};
+		},
+		watch: {
+			value(val) {
+				this.inputValue = +val;
+			},
+			modelValue(val) {
+				this.inputValue = +val;
+			}
+		},
+		computed: {
+			widthWithPx() {
+				return this.width + 'px';
+			}
+		},
+		created() {
+			if (this.value === 1) {
+				this.inputValue = +this.modelValue;
+			}
+			if (this.modelValue === 1) {
+				this.inputValue = +this.value;
+			}
+		},
+		methods: {
+			_calcValue(type) {
+				if (this.disabled) {
+					return;
+				}
+				const scale = this._getDecimalScale();
+				let value = this.inputValue * scale;
+				let step = this.step * scale;
+				if (type === "minus") {
+					value -= step;
+					if (value < (this.min * scale)) {
+						return;
+					}
+					if (value > (this.max * scale)) {
+						value = this.max * scale
+					}
+				}
+
+				if (type === "plus") {
+					value += step;
+					if (value > (this.max * scale)) {
+						return;
+					}
+					if (value < (this.min * scale)) {
+						value = this.min * scale
+					}
+				}
+
+				this.inputValue = (value / scale).toFixed(String(scale).length - 1);
+				// TODO vue2 兼容
+				this.$emit("input", +this.inputValue);
+				// TODO vue3 兼容
+				this.$emit("update:modelValue", +this.inputValue);
+				this.$emit("change", +this.inputValue);
+			},
+			_getDecimalScale() {
+
+				let scale = 1;
+				// 浮点型
+				if (~~this.step !== this.step) {
+					scale = Math.pow(10, String(this.step).split(".")[1].length);
+				}
+				return scale;
+			},
+			_onBlur(event) {
+				this.$emit('blur', event)
+				let value = event.detail.value;
+				if (isNaN(value)) {
+					this.inputValue = this.min;
+					return;
+				}
+				value = +value;
+				if (value > this.max) {
+					value = this.max;
+				} else if (value < this.min) {
+					value = this.min;
+				}
+				const scale = this._getDecimalScale();
+				this.inputValue = value.toFixed(String(scale).length - 1);
+				this.$emit("input", +this.inputValue);
+				this.$emit("update:modelValue", +this.inputValue);
+				this.$emit("change", +this.inputValue);
+			},
+			_onFocus(event) {
+				this.$emit('focus', event)
+			}
+		}
+	};
+</script>
+<style lang="scss">
+	$box-height: 26px;
+	$bg: #f5f5f5;
+	$br: 2px;
+	$color: #333;
+
+	.uni-numbox {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+	}
+
+	.uni-numbox-btns {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		align-items: center;
+		justify-content: center;
+		padding: 0 8px;
+		background-color: $bg;
+		/* #ifdef H5 */
+		cursor: pointer;
+		/* #endif */
+	}
+
+	.uni-numbox__value {
+		margin: 0 2px;
+		background-color: $bg;
+		width: 40px;
+		height: $box-height;
+		text-align: center;
+		font-size: 14px;
+		border-left-width: 0;
+		border-right-width: 0;
+		color: $color;
+	}
+
+	.uni-numbox__minus {
+		border-top-left-radius: $br;
+		border-bottom-left-radius: $br;
+	}
+
+	.uni-numbox__plus {
+		border-top-right-radius: $br;
+		border-bottom-right-radius: $br;
+	}
+
+	.uni-numbox--text {
+		// fix nvue
+		line-height: 20px;
+		margin-bottom: 2px;
+		font-size: 20px;
+		font-weight: 300;
+		color: $color;
+	}
+
+	.uni-numbox .uni-numbox--disabled {
+		color: #c0c0c0 !important;
+		/* #ifdef H5 */
+		cursor: not-allowed;
+		/* #endif */
+	}
+</style>

+ 82 - 0
uni_modules/uni-number-box/package.json

@@ -0,0 +1,82 @@
+{
+  "id": "uni-number-box",
+  "displayName": "uni-number-box 数字输入框",
+  "version": "1.2.6",
+  "description": "NumberBox 带加减按钮的数字输入框组件,用户可以控制每次点击增加的数值,支持小数。",
+  "keywords": [
+    "uni-ui",
+    "uniui",
+    "数字输入框"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": ""
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+"dcloudext": {
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
+    "type": "component-vue"
+  },
+  "uni_modules": {
+    "dependencies": ["uni-scss"],
+    "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"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}

+ 13 - 0
uni_modules/uni-number-box/readme.md

@@ -0,0 +1,13 @@
+
+
+## NumberBox 数字输入框
+> **组件名:uni-number-box**
+> 代码块: `uNumberBox`
+
+
+带加减按钮的数字输入框。
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-number-box)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 
+
+

Some files were not shown because too many files changed in this diff