lilei 4 سال پیش
والد
کامیت
b01bba30df

+ 379 - 0
hybrid/html/ddvideo.html

@@ -0,0 +1,379 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"/>
+<title>点检巡店</title>
+<script src="js/vue@2.6.11"></script>
+<script src="js/uni.webview.1.5.2.js"></script>
+<!-- antd ui -->
+<script type="text/javascript" charset="utf-8" src="js/moment.min.js"></script>
+<script type="text/javascript" charset="utf-8" src="js/moment-with-locales.min.js"></script>
+<link rel="stylesheet" href="antd/antd.min.css" />
+<script type="text/javascript" charset="utf-8" src="antd/antd.min.js"></script>
+<!-- 编辑图片 -->
+<script type="text/javascript" charset="utf-8" src="imgEdit/ped.min.js"></script>
+<!-- 播放器 -->
+<link rel="stylesheet" href="aliplayer/aliplayer-min.css" />
+<script type="text/javascript" charset="utf-8" src="aliplayer/aliplayer-h5-min.js"></script>
+<!-- 页面样式 -->
+<link rel="stylesheet/less" type="text/css" href="css/styles.less" />
+<script src="js/less.min.js"></script>
+</head>
+<body>
+<div class="storeCheck" id="app">
+    <!-- 播放器 -->
+    <div class="videoPlay" v-if="xdType=='video'">
+      <!-- 云台控制 -->
+      <div class="control-yt" v-show="showYt&&!showYtbtns" @click="openYt"></div>
+      <div class="control-yt-close" v-show="showYtbtns" @click="openYt"></div>
+      <div v-show="showYtbtns" @click="kzYt(1)" class="ytBtns yt-left"></div>
+      <div v-show="showYtbtns" @click="kzYt(2)" class="ytBtns yt-right"></div>
+      <div v-show="showYtbtns" @click="kzYt(3)" class="ytBtns yt-top"></div>
+      <div v-show="showYtbtns" @click="kzYt(4)" class="ytBtns yt-bottom"></div>
+      <!-- 播放器 -->
+      <div class="prism-player" id="player-con"></div>
+    </div>
+    <!-- 工作区 -->
+    <div class="checkWork">
+      <!-- 统计及摄像头切换 -->
+      <div class="checkWork-head">
+        <div class="checkWork-head-row" v-if="xdType=='video'">
+          <!-- 机位 -->
+          <div>
+            <div>机位:</div>
+			<div></div>
+            <div>
+              <a-dropdown>
+                <a-menu selectable slot="overlay" @click="onVideoListClick">
+                  <a-menu-item v-for="item in videoList" :key="item.id"> {{item.name}} </a-menu-item>
+                </a-menu>
+				<a class="ant-dropdown-link" @click="e => e.preventDefault()">
+				  {{curVideo&&curVideo.name}} <a-icon type="down" />
+				</a>
+              </a-dropdown>
+            </div>
+          </div>
+          <!-- 预置位 -->
+          <!-- <div>
+            <div>预置位:</div>
+            <div>
+              <a-dropdown>
+                <a-menu slot="overlay">
+                  <a-menu-item key="1"> 预置位1 </a-menu-item>
+                  <a-menu-item key="2"> 预置位2 </a-menu-item>
+                  <a-menu-item key="3"> 预置位3 </a-menu-item>
+                </a-menu>
+                <a-button block> 请选择 <a-icon type="down" /> </a-button>
+              </a-dropdown>
+            </div>
+          </div> -->
+        </div>
+      </div>
+      <!-- 打分 -->
+      <div class="checkWork-body">
+        <div style="width: 100%;" class="checkWork-body-tabCons">
+          <div class="tabCons-items" v-for="(zb,zbIndex) in zbItem" :key="zb.id">
+            <div>
+              <div><b>{{zb.assessTargetName}}</b></div>
+			  <!-- 点击打开拍照 -->
+              <div @click="openCamera(zbIndex)"><a-icon type="camera" style="font-size: 30px;" /></div>
+            </div>
+			<!-- 拍照图片 -->
+			<div class="photos">
+				<div 
+				v-for="(photo,pindex) in zb.taskTargetPhotoVOList" 
+				:key="photo.id"
+				>
+				<a-avatar :size="40" shape="square" :src="photo.photoPath" />
+				</div>
+			</div>
+			<!-- 评论 -->
+			<div class="remarks">
+				评论:{{zb.comments}}
+			</div>
+			<!-- 评分 -->
+            <div>
+              <div><!-- 分值:{{zb.getScore}} <a-icon @click="openEditFs" type="edit" style="font-size: 20px;margin-left: 10px;"/> --></div>
+              <div>
+				  <!-- 不适用 -->
+                <a-icon @click="selZbResult(0,zb)" type="minus-circle" :class="zb.result=='bsy'?'choose-bsy':''"/>
+              </div>
+			  <div>
+				  <!-- 不合格 -->
+				  <a-icon @click="selZbResult(1,zb)" type="close-circle" :class="zb.result=='bhg'?'choose-bhg':''"/>
+			  </div>
+			  <div>
+				  <!-- 合格 -->
+				  <a-icon @click="selZbResult(2,zb)" type="check-circle" :class="zb.result=='hg'?'choose-hg':''"/>
+			  </div>
+            </div>
+          </div>
+		  </div>
+      </div>
+      <!-- 提交按钮 -->
+	  <div class="checkWork-button">
+		  <div v-if="xdType=='video'" @click="submitTask">提交</div>
+	  </div>
+	</div>
+	<!-- 拍照弹框 -->
+	<a-drawer
+	  title="快拍"
+	  placement="bottom"
+	  :closable="true"
+	  :visible="showPz"
+	  @close="onClosePz"
+	  :height="360"
+	>
+	  <div class="pzPopus">
+		  <!-- 评论 -->
+		  <div class="pz-pinglun">
+			  <div class="remarks">
+				  <a-textarea placeholder="请填写备注内容(选填)" v-model="curZbItem.comments" :rows="4" />
+			  </div>
+			  <div class="icons">
+				  <a-icon class="aicon" type="camera" />
+			  </div>
+		  </div>
+		  <!-- 图片列表 -->
+		  <div class="imglist">
+			  <div v-for="(photo,pindex) in curZbItem.taskTargetPhotoVOList" 
+				:key="photo.id"
+				>
+				  <img @click="editImgs(photo.photoPath,activeZbIndex,pindex)" :src="photo.photoPath">
+				  <a-icon @click.stop="delImgs(pindex)" class="aicon" type="close" />
+			  </div>
+		  </div>
+		  <!-- 提交 -->
+		  <div class="f-btns">
+			  <a-button size="large" @click="saveZbPlImgs" type="primary" block> 提交 </a-button>
+		  </div>
+	  </div>
+	</a-drawer>
+	
+	<!-- 加载条 -->
+	<div v-if="showLoading" class="loading">
+	    <a-spin />
+	</div>
+  </div>
+<script>
+	window.onload = function(){
+		vm.showLoading = false
+	}
+	// 初始化vm 实例
+	var vm = new Vue({
+	  el: '#app',
+	  data: {
+		  xdType:'video', // 巡店类型
+		  player: null, // 播放器对象
+		  videoList: [], // 播放通道
+		  curVideo: null, // 当前播放的视频
+		  showYt: false, // 显示云台控制
+		  showYtbtns: false,
+		  showPz: false,// 显示拍照弹框
+		  showLoading: true, // 页面加载条
+		  isEditImg: false, // 是否编辑图片
+		  PED: null, // 图片编辑对象
+		  activeZbIndex:0,//当前编辑的指标index
+		  activeZbPhoto:0, //当前编辑的指标图片index
+		  curZbItem: {comments:'',taskTargetPhotoVOList:[]},// 当前编辑的指标评论图片对象
+		  zbItem: [],// 考评项
+		},
+		mounted () {
+		  let _this = this
+		  moment.locale('zh-cn');
+		},
+		methods: {
+	      // 重置页面
+		  resetPage(){
+			  this.activeZbIndex = 0
+			  this.activeZbPhoto = 0
+			  this.curZbItem = {comments:'',taskTargetPhotoVOList:[]}
+			  this.showPz = false
+		  },
+		  // 设置巡店类型及标题
+		  setTyps(type,storeName){
+			  this.xdType = type
+			  // 设置标题
+			  document.title = storeName
+		  },
+		  // 设置视频列表
+		  setVideoList(data){
+			  this.videoList = JSON.parse(data)
+			  this.curVideo = this.videoList[0]
+			  this.videoInit()
+		  },
+		  // 设置任务项列表
+		  getTaskDetail(data){
+			  this.zbItem = JSON.parse(data)
+		  },
+		  // 选择机位
+		  onVideoListClick({ key }){
+			  let v = this.videoList.find(item=>item.id == key)
+			  if(v){
+				  this.curVideo = v
+				  // 重置播放器
+				  this.showYt = false
+				  this.showYtbtns = false
+				  this.player.dispose()
+				  this.videoInit()
+			  }
+		  },
+		  // 初始化播放器
+		  videoInit(){
+			  const _this = this
+			  const videoSrc = this.curVideo.videoSrc
+			  // 初始化播放器
+			  _this.player = new Aliplayer({
+			    'id': 'player-con',
+			    'source': videoSrc,
+			    'width': '100%',
+			    'height': '240px',
+			    'autoplay': false,
+			    'isLive': true,
+			    'rePlay': true,
+			    'playsinline': true,
+			    'preload': true,
+			    'language': 'zh-cn',
+			    'useH5Prism': true,
+			    'extraInfo': {
+			      'crossOrigin': 'anonymous'
+			    },
+			    'skinLayout': [
+			      {
+			        'name': 'bigPlayButton',
+			        'align': 'cc'
+			      },
+			      {
+			        'name': 'errorDisplay',
+			        'align': 'tlabs',
+			        'x': 0,
+			        'y': 0
+			      },
+			      {
+			        'name': 'infoDisplay'
+			      },
+			      {
+			        'name': 'controlBar',
+			        'align': 'blabs',
+			        'x': 0,
+			        'y': 0,
+			        'children': [
+			          {
+			            'name': 'fullScreenButton',
+			            'align': 'tr',
+			            'x': 15,
+			            'y': 10
+			          },
+			          {
+			            'name': 'volume',
+			            'align': 'tr',
+			            'x': 15,
+			            'y': 8
+			          },
+			          {
+			            'name': 'liveDisplay',
+			            'align': 'tl',
+			            'x': 15,
+			            'y': 2
+			          }
+			        ]
+			      }
+			    ]
+			  }, function (player) {
+			    _this.sendMsg('message','The player is created')
+			  }
+			  )
+			  // 控制栏
+			  _this.player.on('playing', function () {
+			    _this.showYt = true
+			  })
+			  _this.player.on('error',function(e){
+				  console.log(JSON.stringify(e),'error')
+			  })
+		  },
+		  // 发送消息给app 页面
+		  sendMsg (action,msg) {
+		    uni.postMessage({
+		      data: {
+		        action: action,
+		        msg: msg
+		      }
+		    })
+		  },
+		  // 显示云台控制按钮
+		  openYt () {
+		    this.showYtbtns = !this.showYtbtns
+		  },
+		  // 控制云台
+		  kzYt (index) {
+		    const cmd = ['left', 'right', 'up', 'down']
+		    this.sendMsg('kzyt','控制云台' + cmd[index - 1])
+		  },
+		  // 打开抓拍照片弹框
+		  openCamera(index){
+			 this.showPz = true
+			 this.activeZbIndex = index
+			 this.sendMsg('getWinStatus',JSON.stringify({key:'showPz',val: true}))
+			 // 当前查看的指标对象
+			 let obj = this.zbItem[this.activeZbIndex]
+			 this.curZbItem = JSON.parse(JSON.stringify(obj))
+		  },
+		  // 关闭抓拍弹框
+		  onClosePz(){
+			  this.showPz = false
+			  this.sendMsg('getWinStatus',JSON.stringify({key:'showPz',val: false}))
+		  },
+		  // 删除图片
+		  delImgs(index){
+			  this.sendMsg('delImgs',index)
+		  },
+		  delImgsSuccess(index){
+			  this.curZbItem.taskTargetPhotoVOList.splice(index,1)
+		  },
+		  // 预览编辑图片
+		  editImgs(url,index,pindex){
+			   let _this = this
+			   _this.activeZbIndex = index
+			   _this.activeZbPhoto = pindex
+			   _this.sendMsg('getWinStatus',JSON.stringify({key:'isEditImg',val: true}))
+			   this.PED = new window.PED.imageInfo(
+			   url,
+			   function(data){
+				   // 保存图片编辑
+				   _this.sendMsg('saveEditImg',data)
+			   },
+			   function(){
+				   _this.sendMsg('getWinStatus',JSON.stringify({key:'isEditImg',val: false}))
+			   })
+		  },
+		  // 关闭图片编辑
+		  closeImgsEdit(){
+			  this.PED.hidePED()
+			  this.sendMsg('getWinStatus',JSON.stringify({key:'isEditImg',val: false}))
+		  },
+		  // 更新编辑后的图片
+		  updateItemImg(path){
+			  let photoList = this.curZbItem.taskTargetPhotoVOList
+			  photoList[this.activeZbPhoto].photoPath = path
+		  },
+		  // 评分,0 不适用,1 不合格,2 合格
+		  selZbResult(type,zb){
+			  let ret = ['bsy','bhg','hg']
+			  zb.result = ret[type]
+		  },
+		  // 保存指标评论及图片
+		  saveZbPlImgs(){
+			  this.zbItem.splice(this.activeZbIndex,1,this.curZbItem)
+			  this.onClosePz()
+		  },
+		  // 提交此次任务
+		  submitTask(){
+			  this.sendMsg('submitTask',JSON.stringify(this.zbItem))
+		  },
+		}
+	})
+ 
+</script>
+</body>
+</html>

+ 4 - 4
hybrid/html/video.html

@@ -117,7 +117,7 @@
 			</div>
 			<!-- 评论 -->
 			<div class="remarks">
-				评论:{{zb.remarks}}
+				评论:{{zb.comments}}
 			</div>
 			<!-- 评分 -->
             <div>
@@ -157,7 +157,7 @@
 		  <!-- 评论 -->
 		  <div class="pz-pinglun">
 			  <div class="remarks">
-				  <a-textarea placeholder="请填写备注内容(选填)" v-model="curZbItem.remarks" :rows="4" />
+				  <a-textarea placeholder="请填写备注内容(选填)" v-model="curZbItem.comments" :rows="4" />
 			  </div>
 			  <div class="icons">
 				  <a-icon class="aicon" type="camera" />
@@ -208,7 +208,7 @@
 		  activeIndex:0, // 当前选择的考评项
 		  activeZbIndex:0,//当前编辑的指标index
 		  activeZbPhoto:0, //当前编辑的指标图片index
-		  curZbItem: {remarks:'',taskTargetPhotoVOList:[]},// 当前编辑的指标评论图片对象
+		  curZbItem: {comments:'',taskTargetPhotoVOList:[]},// 当前编辑的指标评论图片对象
 		  // 考评统计
 		  kptj:{
 			  haoshi: '0时0分'
@@ -234,7 +234,7 @@
 			  this.activeIndex = 0
 			  this.activeZbIndex = 0
 			  this.activeZbPhoto = 0
-			  this.curZbItem = {remarks:'',taskTargetPhotoVOList:[]}
+			  this.curZbItem = {comments:'',taskTargetPhotoVOList:[]}
 			  this.isDelItem = false
 			  this.showPz = false
 		  },

+ 7 - 1
pages.json

@@ -250,7 +250,13 @@
 				"navigationBarTitleText": "选择抄送人"
 			}
 		}
-	],
+	    ,{
+            "path" : "pages/spotCheck/spotCheck",
+            "style" : {
+				"navigationBarTitleText": "开始点检"
+			}
+        }
+    ],
 	"globalStyle": {
 		"navigationBarTitleText": "智能巡店",
 		"navigationBarBackgroundColor": "#0b6ce0",

+ 186 - 0
pages/spotCheck/spotCheck.vue

@@ -0,0 +1,186 @@
+<template>
+	<view>
+		<web-view @message="onmessage" src="/hybrid/html/ddvideo.html"></web-view>
+	</view>
+</template>
+
+<script>
+	import { clzConfirm,saveBase64ToAliOss } from '@/libs/tools'
+	import {getTaskDetail,savePointTask} from '@/api/task'
+	import {getTaskTargetById} from '@/api/taskTarget'
+	import {findVsDeviceChannels} from '@/api/store'
+	export default {
+		data() {
+			return {
+				wv: null,
+				isClose: false, // 是否关闭当前窗口
+				isEditImg: false, // 是否正在编辑图片
+				showPz: false, // 是否正在拍照
+				types: 'video', // 巡店类型,video,scene
+				taskId: '', // 任务id
+				storeId: '', // 门店id
+				storeName: '',// 门店名称
+			};
+		},
+		methods: {
+			// 监听html页面事件
+			onmessage(event) {
+				let data = event.detail.data[0]
+				// console.log(data)
+				// webview 窗口传过来的页面状态
+				if(data.action == 'getWinStatus'){
+					let d = JSON.parse(data.msg)
+					this[d.key] = d.val
+				}
+				// 保存编辑后的图片
+				if(data.action == 'saveEditImg'){
+					this.uploadImg(data.msg)
+				}
+				// 删除图片
+				if(data.action == 'delImgs'){
+					this.delImgs(data.msg)
+				}
+				// 提交巡店
+				if(data.action == 'submitTask'){
+					this.submitTask(JSON.parse(data.msg))
+				}
+			},
+			// 删除图片
+			delImgs(index){
+				const _this = this;
+				clzConfirm({
+					title: '提示',
+					content: '确定删除此图片,删除后无法恢复?',
+					success: function(res) {
+						if (res.confirm || res.index == 0) {
+							_this.wv.evalJS("vm.delImgsSuccess("+index+")") 
+						}
+					}
+				});
+			},
+			// 上传编辑后的图片到阿里云
+			uploadImg(formData) {
+				const _this = this;
+				saveBase64ToAliOss(formData,function(res){
+					// console.log(res);
+					// 关闭编辑图片
+					_this.wv.evalJS("vm.closeImgsEdit()")
+					// 更新编辑后的图片
+					_this.wv.evalJS("vm.updateItemImg('"+res.data+"')")
+				})
+			},
+			// 查询任务明细
+			getTaskDetail(){
+				getTaskTargetById({taskId:this.taskId}).then(res => {
+					console.log(res.data)
+					this.wv.evalJS("vm.getTaskDetail('"+JSON.stringify(res.data)+"')")
+				})
+			},
+			// 获取视频列表
+			getVideoList(){
+				findVsDeviceChannels({storeId:this.storeId}).then(res=>{
+					if(res.status==200){
+						this.wv.evalJS("vm.setVideoList('"+JSON.stringify(res.data)+"')")
+					}
+				})
+			},
+			// 提交本次任务
+			submitTask(data){
+				const _this = this;
+				console.log(data,'savePointTask')
+				clzConfirm({
+					title: '提示',
+					content: '确定提交本次点检任务?',
+					success: function(res) {
+						if (res.confirm || res.index == 0) {
+							savePointTask(data).then(ret=>{
+								console.log(ret)
+								if(ret.status == 200){
+									_this.isClose = true
+									// 打开完成页面
+									uni.redirectTo({
+										url: '/pages/spotCheckCenter/spotCheckResult?id=' + _this.taskId
+									});
+									// 刷新列表
+									uni.$emit('updatePointTaskList')
+								}else{
+									_this.isClose = false
+								}
+								uni.showToast({
+									icon:'none',
+									title: ret.message
+								})
+							})
+						}
+					}
+				});
+			},
+		},
+		onLoad(options) {
+			// 巡店类型,视频还时现场
+			this.types = options.types
+			this.taskId = options.taskId
+			this.storeId = options.storeId
+			this.storeName = options.storeName
+		},
+		onReady() {
+			let _this = this
+			// #ifdef APP-PLUS
+			 //获取当前页面的webview对象
+			 var currentWebview = this.$mp.page.$getAppWebview()
+			 //如果是页面初始化调用时,需要延时一下
+			 setTimeout(function() {
+				_this.wv = currentWebview.children()[0]
+				_this.wv.evalJS("vm.setTyps('"+_this.types+"','"+_this.storeName+"')")
+				// 获取视频列表
+				if(_this.types == 'video'){
+					_this.getVideoList() 
+				}
+				//查询任务项明细
+				_this.getTaskDetail()
+			 }, 500);
+			// #endif
+			// 关闭当前页面
+			uni.$on("closeTour",(flag)=>{
+				if(flag==1){
+					this.isClose = true
+					uni.navigateBack()
+				}
+			})
+		},
+		// 监听返回键
+		onBackPress() {
+			let _this = this
+			if(!_this.isClose){
+				// 正在编辑图片
+				if(this.isEditImg){
+					// 关闭编辑图片
+					_this.wv.evalJS("vm.closeImgsEdit()")
+				}
+				// 正在拍照
+				else if(this.showPz){
+					// 关闭拍照弹框
+					_this.wv.evalJS("vm.onClosePz()")
+				}else{
+					clzConfirm({
+						title: '提示',
+						content: '点检还未完成,确定退出吗?',
+						success: function(res) {
+							if (res.confirm || res.index == 0) {
+								_this.isClose = true
+								uni.navigateBack({
+									delta: 1
+								});
+							}
+						}
+					});
+				}
+				return true
+			}
+		},
+	}
+</script>
+
+<style>
+
+</style>

+ 6 - 5
pages/spotCheckCenter/spotChecking.vue

@@ -49,10 +49,6 @@ export default {
 					dispName: '待处理',
 					code: 5
 				},
-				{
-					dispName: '进行中',
-					code: 4
-				},
 				{
 					dispName: '已完成',
 					code: 3
@@ -73,6 +69,9 @@ export default {
 	},
 	onLoad() {
 		this.getRow();
+		uni.$on("updatePointTaskList",()=>{
+			this.getRow(1);
+		})
 	},
 	methods: {
 		message(title) {
@@ -156,7 +155,9 @@ export default {
 			}
 			// 待处理,开始点检
 			if(item.status == '待处理'){
-				
+				uni.navigateTo({
+					url: '/pages/spotCheck/spotCheck?taskId=' + item.id + '&types=video&storeId='+item.storeId+'&storeName='+item.storeName
+				});
 			}
 		},
 		clsStatus(status){

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 0
unpackage/dist/dev/app-plus/app-config-service.js


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 0
unpackage/dist/dev/app-plus/app-service.js


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 87 - 38
unpackage/dist/dev/app-plus/app-view.js


+ 4 - 4
unpackage/dist/dev/app-plus/hybrid/html/video.html

@@ -117,7 +117,7 @@
 			</div>
 			<!-- 评论 -->
 			<div class="remarks">
-				评论:{{zb.remarks}}
+				评论:{{zb.comments}}
 			</div>
 			<!-- 评分 -->
             <div>
@@ -157,7 +157,7 @@
 		  <!-- 评论 -->
 		  <div class="pz-pinglun">
 			  <div class="remarks">
-				  <a-textarea placeholder="请填写备注内容(选填)" v-model="curZbItem.remarks" :rows="4" />
+				  <a-textarea placeholder="请填写备注内容(选填)" v-model="curZbItem.comments" :rows="4" />
 			  </div>
 			  <div class="icons">
 				  <a-icon class="aicon" type="camera" />
@@ -208,7 +208,7 @@
 		  activeIndex:0, // 当前选择的考评项
 		  activeZbIndex:0,//当前编辑的指标index
 		  activeZbPhoto:0, //当前编辑的指标图片index
-		  curZbItem: {remarks:'',taskTargetPhotoVOList:[]},// 当前编辑的指标评论图片对象
+		  curZbItem: {comments:'',taskTargetPhotoVOList:[]},// 当前编辑的指标评论图片对象
 		  // 考评统计
 		  kptj:{
 			  haoshi: '0时0分'
@@ -234,7 +234,7 @@
 			  this.activeIndex = 0
 			  this.activeZbIndex = 0
 			  this.activeZbPhoto = 0
-			  this.curZbItem = {remarks:'',taskTargetPhotoVOList:[]}
+			  this.curZbItem = {comments:'',taskTargetPhotoVOList:[]}
 			  this.isDelItem = false
 			  this.showPz = false
 		  },

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است