工作笔记--常用js

133 阅读9分钟

//uniapp 拍照添加水印

//第三方调用---
<photoCamera :ref="'photo'+index" :delIicon='whetherOperable' :contentObj="contentObj" @imglistQuery="imglistQuery" :disabledview="!whetherOperable" :imglist="data.imgList" :imglistBollean="imglistBollean"></photoCamera>
//imglistBollean 拍照返回的图片不传回去true:传回,false:不传回去
//imglist 预览照片时传给组件图片url的集合
//disabledview 是否禁用
//delIicon 是否是只读
//contentObj 水印要添加的内容
//   contentObj: {
            projName: '',
            projId: '',
            savejcTag: '',
            content: '',
    },

// 图片返回
imglistQuery(arr) {
    let imgarr = []
    arr.forEach(item => {
            imgarr.push(item.url)
    })
    this.imglistBollean=false  //
},



//photoCamera公用组件----以下都是组件内容
<template>
	<div style="width: 100%;">
		<uni-file-picker :disabled="disabled" :readonly="!delIicon" v-model="fileLists" :auto-upload="false" mode="grid" limit="9" title="最多上传9张图片" @select="selectImg" @delete="deleteImg"></uni-file-picker>
		<canvas v-if="waterMarkParams.display" canvas-id="waterMarkCanvas" :style="canvasStyle" />
	</div>
</template>

<script>
	import {
		config
	} from '@/config.js'
	export default {
		data() {
			return {
				fileLists: [], //附件图片.
				address: '',
				map: null, // 地图实例
				waterMarkParams: {
					display: false, // 控制 canvas 创建与销毁
					canvasWidth: 300, // 默认宽度
					canvasHeight: 225, // 默认高度
					contentHeight: 100, // 将要被绘制到图像中的矩形的高度(px)
				},
				screenWidth: 0,
				disabled:true,
				systemInfo:'',
				userInfo:'',
			}
		},
		props: {
			contentObj: {//水印显示内容
				type: [Object],
				default: () => {
					return {};
				},
			},
			delIicon:{//隐藏删除按钮和添加按钮
				type:[Boolean],
				default:true,
			},
			disabledview:{//是否禁用
				type:[Boolean],
				default:false,
			},
			imglist:{
				type:[Array],
				default:()=>[],
			},
			imglistBollean:{//是否回显图片
				type:[Boolean],
				default:true,
			},
			showIndex:{
				type:[Number],
				debugger:0
			}
		},
		watch: {
			contentObj:{
				deep:true,
				immediate:true,
				handler(newName, oldName) {
					if(newName.projName!=''){
						this.disabled=false
					}
				},
			},
			disabledview:{
				deep:true,
				immediate:true,
				handler(newName, oldName) {
					if(newName==true){
						this.disabled=true
					}
				},
			},
			imglist:{
				deep:true,
				immediate:true,
				handler(newName, oldName) {
					console.log(newName,'imglistimglist')
					if(newName.length!=0&&this.imglistBollean){
						this.fileLists=[]
						newName.map(item=>{
							this.fileLists.push({
								url:item
							})
						})
					}else if(newName.length==0&&this.imglistBollean){
						this.fileLists=[]
					}
				},
			},
		},
		computed: {
		  canvasStyle() {
		    return {
				position: 'fixed',
				left:'99999px',
				width: this.waterMarkParams.canvasWidth + 'px',
				height: this.waterMarkParams.canvasHeight + 'px',
		    }
		  }
		},
		async mounted() {
			this.userInfo = uni.getStorageSync('userInfo') ? JSON.parse(uni.getStorageSync('userInfo')) : ''
			if(!this.systemInfo){
				this.systemInfo = await uni.getSystemInfoSync();
				this.screenWidth = this.systemInfo.windowWidth;
			}
			
			await this.startLocation() //拍照前先定位
			this.address=this.address||uni.getStorageSync('address')?this.address||uni.getStorageSync('address'):''
			if(!this.address){
				await this.getLocation()//拍照前检查权限
			}
		},
		async created() {
			if(!this.systemInfo){
				this.systemInfo = await uni.getSystemInfoSync();
				this.screenWidth = this.systemInfo.windowWidth;
			}
			
			await this.startLocation() //拍照前先定位
			this.address=this.address||uni.getStorageSync('address')?this.address||uni.getStorageSync('address'):''
			if(!this.address){
				await this.getLocation()//拍照前检查权限
			}
		},
		methods: {
			async selectImg(e){
				console.log(e,'------',this.fileLists)
				// this.fileLists=this.fileLists
				this.address=this.address||uni.getStorageSync('address')?this.address||uni.getStorageSync('address'):''
				if(!this.address){
					await this.getLocation()//拍照前检查权限
				}
				await this.unichooseImage(e)
			},
			successImg(e){
				console.log(e,'返回成功')
			},
			async deleteImg(rel){
				let that=this
				console.log(rel,111)
				let id=rel.tempFile.id
				if(!id){
					that.fileLists.splice(rel.index,1)
					that.$emit('imglistQuery',that.fileLists)
					console.log(that.fileLists,2222)
					return
				}
				let URL=`/doc/docAttachment/del`;
				await this.$postFn({
					url: URL,
					params:[id],
				}).then(_result=>{
					// console.log(that.fileLists)
					// this.fileLists=[...obj,...this.fileLists]
					that.$emit('imglistQuery',that.fileLists)
				})	
			},
			// 拍照
			
			async unichooseImage(res) {
				let params=this.contentObj
				// console.log(params,'paramsparamsparamsparams')
				let systemInfo = await uni.getSystemInfoSync();
				this.screenWidth = systemInfo.windowWidth;
				// console.log('屏幕' + systemInfo.platform);
				const platform = systemInfo.platform;
				let that=this
				let obj = {}
				let tempFilePaths = res.tempFilePaths
				const imgFileArr = await this.callIosAddWaterMark(tempFilePaths, params)
				// console.log(imgFileArr,'imgFileArrimgFileArr')
				imgFileArr.forEach((item, index) => {
					uni.uploadFile({
						url: config.dev.baseUrl + 'doc/docAttachment/upload',
						header: {
							'Admin-Token': uni.getStorageSync('access_token') || 'admin'
						},
						filePath: imgFileArr[index],
						name: 'file',
						formData: {
							businessId: params.projId, //项目id
							// dirId: 1,
							tag: params.savejcTag, //拼接id为数据id
						},
						success: (res) => {
							obj = JSON.parse(res.data).data
							obj.showIndex=this.showIndex
							obj.extname=obj.filetype
							obj.url=obj.fileurl
							that.fileLists.push(obj)
							that.$emit('imglistQuery',that.fileLists)
							console.log(that.fileLists,'返回值')
						},
						fail: (err) => {
							uni.showToast({
								title: '图片上传失败!',
								icon: 'none'
							})
						}
					})
				})
				
			},
				//水印
				async callIosAddWaterMark(imgPathArr, params) {
					// console.log('处理', imgPathArr)
					let results = []
					if (imgPathArr.length > 0) {
						let addIndex = 0
						while (addIndex < imgPathArr.length) {
							// console.log('imgPathArr[addIndex]', imgPathArr[addIndex])
							const tempFilePath = await this.iosAddWaterMark(imgPathArr[addIndex], params)
							results.push(tempFilePath)
							addIndex = addIndex + 1
						}
					}
					// console.log('results', results)
					return results
				},

				// 添加水印
				iosAddWaterMark(src, params) {
					// 水印名称
					let roleObj = uni.getStorageSync('role') ? JSON.parse(uni.getStorageSync('role')) : ''
					let name = this.userInfo.realname
					let role = roleObj ? roleObj.roleName : this.userInfo.roleList[0].roleName
					//水印日期
					const now = new Date();
					const year = now.getFullYear();
					const month = (now.getMonth() + 1) < 9 ? '0' + (now.getMonth() + 1) : (now.getMonth() + 1); // 月份从0开始,所以要加1
					// const day = now.getDate();
					const day = (now.getDate()) < 9 ? '0' + (now.getDate()) : (now.getDate());
					// const hour = now.getHours();
					const hour = (now.getHours()) < 9 ? '0' + (now.getHours()) : (now.getHours());
					// const minute = now.getMinutes();
					const minute = (now.getMinutes()) < 9 ? '0' + (now.getMinutes()) : (now.getMinutes());
					// const second = now.getSeconds();
					const second = (now.getSeconds()) < 9 ? '0' + (now.getSeconds()) : (now.getSeconds());
					let time = year + '-' + month + '-' + day + ' ' + hour + ':' + minute + ':' + second
					return new Promise((resolve, reject) => {
						// 获取图片信息,配置 canvas 尺寸
						uni.getImageInfo({
							src,
							success: res => {
								// const { canvasWidth, canvasHeight} = res;
								console.log('---识别手机1', JSON.stringify(res),this.screenWidth)
								// 修复部分手机(如红米9)手机屏幕比较窄拍摄出来的图片水印压缩着覆盖的问题
								// this.waterMarkParams.canvasWidth = Math.max(res.width, 886);
								// this.waterMarkParams.canvasHeight = res.height;
								let textArray=[]
								if(params.content.length>40){
									this.waterMarkParams.contentHeight=100+20
									params['content1']=params.content.slice(40)
									params.content=params.content.slice(0,40)
									textArray=[params.projName,`拍摄人员: ${role}-${name}`,`拍摄时间: ${time}`,`拍摄地点: ${this.address}`,`${params.content}`,`${params.content1}`]
								}else{
									this.waterMarkParams.contentHeight=100
									textArray=[params.projName,`拍摄人员: ${role}-${name}`,`拍摄时间: ${time}`,`拍摄地点: ${this.address}`,`${params.content}`]
								}
									// textArray.reverse()
								let fontSize = 12;
								
								const ratio = this.screenWidth / res.width;
								this.waterMarkParams.canvasWidth = this.screenWidth * 1.2
								this.waterMarkParams.canvasHeight = res.height * ratio * 1.2;
								this.waterMarkParams.display = true
								// 等待 canvas 元素创建
								this.$nextTick(() => {
									// console.log('0000000000', JSON.stringify(this.waterMarkParams))
									let context = uni.createCanvasContext("waterMarkCanvas", this);
									/* 绘制 */
									const {
										canvasWidth,
										canvasHeight,
										contentHeight
									} = this.waterMarkParams
									// console.log(canvasWidth, canvasHeight,contentHeight,'画布大小')
									// 绘制前清空画布
									context.clearRect(0, 0, canvasWidth, canvasHeight);
									// 将图片src放到cancas内,宽高必须为图片大小
									context.drawImage(src, 0, 0, canvasWidth, canvasHeight , canvasWidth, canvasHeight);
									
									// 绘制白色画布--开始
									context.save();
									context.setGlobalAlpha(0.3);// 设置边框的透明度
									context.beginPath();// 绘制底部的白色背景
									context.setFillStyle("white");
									context.fillRect(0, canvasHeight - contentHeight,canvasWidth, contentHeight);//绘制画布(x,y,width,height)
									// 绘制白色画布--结束
								
									// 绘制文字画布--开始
									context.save();
									context.setGlobalAlpha(0.8);// 设置文字的透明度
									context.setTextAlign("left");
									context.setFillStyle("black");
									textArray.forEach((el, index) => {
										let offsetY = index ==0 ? fontSize * index + 25  : fontSize * index + (index+10) + 25;
										if(index ==0){
											context.setFontSize(16);// 绘制底部的文字
										}else{
											context.setFontSize(12);// 绘制底部的文字
										}
										// console.log( offsetY)
										context.fillText(el, 10, (canvasHeight - contentHeight) + offsetY + index);
										context.save();
									});
									
									// 一定要加上一个定时器否则进入到页面第一次可能会无法正常拍照,后几次才正常
									setTimeout(() => {
									  // 本次绘画完重开开始绘画,并且在绘画完毕之后再保存图片,不然页面可能会出现白屏等情况							
										// 绘制文字画布--结束
										context.draw(false,() => {
											uni.canvasToTempFilePath({
												canvasId: "waterMarkCanvas",
												fileType: "jpg",
												width: canvasWidth,
												height: canvasHeight,
												destWidth: canvasWidth,
												destHeight: canvasHeight,
												success: (res) => {
													this.waterMarkParams.display = false
													// console.log(res.tempFilePath,'保存画布成功')
													resolve(res.tempFilePath)
												},
												fail: (err) => {
													// console.error('保存画布失败:', err);
												}
											});
										}, this)
									}, 1000);
								})
							}
						})
					})
				},
				
				// 定位授权
				getLocation() {
					// console.log('开始获取位置')
					var that=this
					// #ifdef APP-PLUS
					// console.log('APP环境')
					if (this.systemInfo.platform === 'android') {
						// console.log('Android平台')
						// Android 权限请求
						const permissionList = ['android.permission.ACCESS_FINE_LOCATION']
						plus.android.requestPermissions(
							permissionList,
							(resultObj) => {
								// console.log('Android权限检查结果:', resultObj)
								if (resultObj.granted.length === permissionList.length) {
									// 检查 GPS 是否开启
									try {
										const Context = plus.android.importClass("android.content.Context")
										const LocationManager = plus.android.importClass("android.location.LocationManager")
										const main = plus.android.runtimeMainActivity()
										const locationManager = main.getSystemService(Context.LOCATION_SERVICE)
										const isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)
										const isNetworkEnabled = locationManager.isProviderEnabled(LocationManager
											.NETWORK_PROVIDER)
			
										// console.log('GPS状态:', isGPSEnabled, '网络定位状态:', isNetworkEnabled)
			
										if (!isGPSEnabled && !isNetworkEnabled) {
											uni.showModal({
												title: '提示',
												content: '请开启GPS定位服务',
												showCancel: false,
												confirmText: '去设置',
												success: () => {
													const Intent = plus.android.importClass(
														'android.content.Intent')
													const Settings = plus.android.importClass(
														'android.provider.Settings')
													const intent = new Intent(Settings
														.ACTION_LOCATION_SOURCE_SETTINGS)
													main.startActivity(intent)
												}
											})
											return
										}
			
										// GPS已开启,开始定位
										that.doLocation()
									} catch (error) {
										// console.error('GPS检查失败:', error)
										that.doLocation() // 即使检查失败也尝试定位
									}
								} else {
									uni.showModal({
										title: '提示',
										content: '请在系统设置中开启定位权限',
										showCancel: false,
										confirmText: '去设置',
										success: () => {
											const main = plus.android.runtimeMainActivity()
											const Intent = plus.android.importClass('android.content.Intent')
											const Settings = plus.android.importClass(
												'android.provider.Settings')
											const intent = new Intent(Settings
												.ACTION_APPLICATION_DETAILS_SETTINGS)
											const Uri = plus.android.importClass('android.net.Uri')
											const uri = Uri.fromParts('package', main.getPackageName(), null)
											intent.setData(uri)
											main.startActivity(intent)
										}
									})
								}
							},
							(error) => {
								// console.error('Android权限请求失败:', error)
								that.doLocation() // 即使权限请求失败也尝试定位
							}
						)
					} else {
						// console.log('iOS平台')
						// iOS 权限请求
						const CLLocationManager = plus.ios.import("CLLocationManager");
						const locationMgr = new CLLocationManager();
						const status = CLLocationManager.authorizationStatus();
						// console.log('iOS定位权限状态:', status)
						if (status === 3 || status === 4) {
							this.doLocation()
						} else if (status === 0) { // kCLAuthorizationStatusNotDetermined
							// console.log('请求定位权限')
							this.doLocation()
						} else {
							uni.showModal({
								title: '提示',
								content: '请在系统设置中开启定位权限',
								showCancel: false,
								confirmText: '去设置',
								success: (res) => {
									if (res.confirm) {
										plus.runtime.openURL('app-settings:')
									}
								}
							})
						}
						plus.ios.deleteObject(locationMgr);
					}
					// #endif
			
					// #ifdef H5
					// console.log('H5环境')
					if ("geolocation" in navigator) {
						// console.log('浏览器支持地理定位')
						navigator.geolocation.getCurrentPosition(
							(position) => {
								// console.log('H5获取位置成功:', position)
								const coords = position.coords
								// console.log('当前位置的经度:' + coords.longitude)
								// console.log('当前位置的纬度:' + coords.latitude)
								this.getAddress(coords.latitude,coords.longitude)
								// that.doLocation() 
								uni.hideLoading()
							},
							(error) => {
								// console.error('H5获取位置失败:', error)
								let message = '获取位置失败'
								switch (error.code) {
									case error.PERMISSION_DENIED:
										message = '请允许浏览器获取位置信息'
										break
									case error.POSITION_UNAVAILABLE:
										message = '位置信息不可用'
										break
									case error.TIMEOUT:
										message = '获取位置超时'
										break
								}
								uni.showModal({
									title: '提示',
									content: message,
									showCancel: false
								})
							}, {
								enableHighAccuracy: true,
								timeout: 5000,
								maximumAge: 0
							}
						)
					} else {
						// console.log('浏览器不支持地理定位')
						uni.showModal({
							title: '提示',
							content: '您的浏览器不支持地理定位',
							showCancel: false
						})
					}
					// #endif
				},
			
				// 实际执行定位的方法
				async doLocation() {
					// console.log('开始执行定位')
					uni.showLoading({
						title: '获取位置中...'
					})
					var that=this
			
					await uni.getLocation({
						type: 'wgs84',//'gcj02',//
						altitude:true,
						geocode: true,
						isHighAccuracy: true,
						timeout: 10000,
						success: (res) => {
							console.log(JSON.stringify(res),'地址')
							console.log('当前位置的经度:' + res.longitude)
							console.log('当前位置的纬度:' + res.latitude)
							uni.hideLoading()
							that.getAddress(res.latitude,res.longitude) //调用工匠会获取地址
						},
						fail: (err) => {
							uni.hideLoading()
							console.error('定位失败,详细错误:', err)
							let errorMsg = '获取位置失败,请检查定位权限并重试'
							if (err.errMsg) {
								if (err.errMsg.includes('permission')) {
									errorMsg = '请在系统设置中开启定位权限'
								} else if (err.errMsg.includes('timeout')) {
									errorMsg = '获取位置超时,请重试'
								} else if (err.errMsg.includes('GPS')) {
									errorMsg = '请开启GPS定位服务'
								}
							}
			
							// iOS 特殊处理
							// #ifdef APP-PLUS
							if (this.systemInfo.platform === 'ios') {
								uni.showModal({
									title: '提示',
									content: errorMsg,
									confirmText: '去设置',
									success: (res) => {
										if (res.confirm) {
											plus.runtime.openURL('app-settings:')
										}
									}
								})
							} else {
								uni.showModal({
									title: '提示',
									content: errorMsg,
									confirmText: '确定',
									success: () => {
										if (errorMsg.includes('权限')) {
											// 打开应用设置页面
											const Intent = plus.android.importClass('android.content.Intent')
											const Settings = plus.android.importClass('android.provider.Settings')
											const Uri = plus.android.importClass('android.net.Uri')
											const main = plus.android.runtimeMainActivity()
											const intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
											const uri = Uri.fromParts('package', main.getPackageName(), null)
											intent.setData(uri)
											main.startActivity(intent)
										} else if (errorMsg.includes('GPS')) {
											// 打开GPS设置页面
											const Intent = plus.android.importClass('android.content.Intent')
											const Settings = plus.android.importClass('android.provider.Settings')
											const main = plus.android.runtimeMainActivity()
											const intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)
											main.startActivity(intent)
										}
									}
								})
							}
							// #endif

						},
						complete: () => {
							uni.hideLoading()
						}
					})
				},
				async getAddress(latitude, longitude) {
					let lat=latitude+0.002024//尽量不调整
					let lon=longitude+0.005876//尽量不调整
					// console.log(lon,lat)          
					let that=this
						try {
							// 高德逆地理变码 https://lbs.amap.com/api/webservice/guide/api/georegeo/
							let _key = 'e0ae9ad9fd21287cefc4fffcb98fb649';//高德API key类型:web服务
							uni.request({
								method: 'GET',
								url: 'https://restapi.amap.com/v3/geocode/regeo?parameters',
								data: {
									key: _key,
									location: `${lon},${lat}`,
									extensions:'base',
									output: 'JSON'
								},
								success: async (res) => {
									that.address=res.data.regeocode.formatted_address
									uni.setStorageSync('address',this.address)
									console.log(res.data.regeocode.formatted_address);
									//用户所在的地理位置信息
								},
								fail: r => {
									console.log(r);
								}
							});
								  
							
						} catch (error) {
							console.error('getAddress执行出错:', error)
							uni.hideLoading()
						}
				},
				startLocation() {
					const self = this
					// console.log('===== 开始定位流程 =====')
					// #ifdef APP-PLUS
					const platform = this.systemInfo.platform
					// console.log('当前平台:', platform)
				
					if (platform === 'android') {
						// 1. 先检查是否有权限
						const checkAndroidPermission = () => {
							try {
								const main = plus.android.runtimeMainActivity()
								const PackageManager = plus.android.importClass('android.content.pm.PackageManager')
				
								// 检查精确定位权限
								const fineLocationGranted = main.checkSelfPermission('android.permission.ACCESS_FINE_LOCATION') === PackageManager.PERMISSION_GRANTED
								// 检查粗略定位权限
								const coarseLocationGranted = main.checkSelfPermission('android.permission.ACCESS_COARSE_LOCATION') === PackageManager.PERMISSION_GRANTED
				
								// console.log('精确定位权限状态:', fineLocationGranted)
								// console.log('粗略定位权限状态:', coarseLocationGranted)
				
								return fineLocationGranted && coarseLocationGranted
							} catch (error) {
								// console.error('检查权限时出错:', error)
								return false
							}
						}
				
						// 2. 检查GPS状态
						const checkGPSStatus = () => {
							try {
								const Context = plus.android.importClass('android.content.Context')
								const LocationManager = plus.android.importClass('android.location.LocationManager')
								const main = plus.android.runtimeMainActivity()
								const lm = main.getSystemService(Context.LOCATION_SERVICE)
				
								const gpsEnabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER)
								const networkEnabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER)
				
								// console.log('GPS状态:', gpsEnabled)
								// console.log('网络定位状态:', networkEnabled)
				
								return gpsEnabled || networkEnabled
							} catch (error) {
								// console.error('检查GPS状态时出错:', error)
								return false
							}
						}
				
						// 3. 请求权限
						const requestPermissions = () => {
							return new Promise((resolve, reject) => {
								plus.android.requestPermissions(
									[
										'android.permission.ACCESS_FINE_LOCATION',
										'android.permission.ACCESS_COARSE_LOCATION'
									],
									function(resultObj) {
										// console.log('权限请求结果:', resultObj)
										if (resultObj.granted.length === 2) {
											resolve(true)
										} else {
											resolve(false)
										}
									},
									function(error) {
										console.error('请求权限失败:', error)
										reject(error)
									}
								)
							})
						}
				
						// 4. 执行定位
						const doLocationRequest = () => {
							// console.log('开始执行uni.getLocation')
							uni.showLoading({ title: '获取位置中...' })
							uni.getLocation({
								type: 'wgs84',//'gcj02',//
								altitude:true,
								geocode: true,
								isHighAccuracy: true,
								timeout: 10000,
								success: (res) => {
									// console.log('定位成功:', res)
									self.getAddress(res.latitude, res.longitude)
								},
								fail: (err) => {
									// console.error('定位失败:', err)
									// uni.$emit('location', { status: 0 })
				
									let errorMsg = '获取位置失败,请检查定位权限并重试'
									if (err.errMsg) {
										// console.log('错误信息:', err.errMsg)
										if (err.errMsg.includes('permission')) {
											errorMsg = '请在系统设置中开启定位权限'
										} else if (err.errMsg.includes('timeout')) {
											errorMsg = '获取位置超时,请重试'
										} else if (err.errMsg.includes('GPS')) {
											errorMsg = '请开启GPS定位服务'
										}
									}
				
									uni.showModal({
										title: '提示',
										content: errorMsg,
										showCancel: false,
										confirmText: '确定',
										success: () => {
											if (errorMsg.includes('权限')) {
												// 打开应用设置页面
												const Intent = plus.android.importClass('android.content.Intent')
												const Settings = plus.android.importClass('android.provider.Settings')
												const Uri = plus.android.importClass('android.net.Uri')
												const main = plus.android.runtimeMainActivity()
												const intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
												const uri = Uri.fromParts('package', main.getPackageName(), null)
												intent.setData(uri)
												main.startActivity(intent)
											} else if (errorMsg.includes('GPS')) {
												// 打开GPS设置页面
												const Intent = plus.android.importClass('android.content.Intent')
												const Settings = plus.android.importClass('android.provider.Settings')
												const main = plus.android.runtimeMainActivity()
												const intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)
												main.startActivity(intent)
											}
										}
									})
								},
								complete: () => {
									uni.hideLoading()
								}
							})
						}
				
						// 执行定位流程
						const startLocationProcess = async () => {
							try {
								// console.log('检查现有权限')
								const hasPermissions = checkAndroidPermission()
				
								if (!hasPermissions) {
									// console.log('没有权限,请求权限')
									const granted = await requestPermissions()
									if (!granted) {
										console.log('权限请求被拒绝')
										throw new Error('permission denied')
									}
								}
				
								// console.log('检查GPS状态')
								const gpsEnabled = checkGPSStatus()
								if (!gpsEnabled) {
									// console.log('GPS未开启')
									uni.showModal({
										title: '提示',
										content: '请开启GPS定位服务',
										showCancel: false,
										confirmText: '去设置',
										success: () => {
											const Intent = plus.android.importClass('android.content.Intent')
											const Settings = plus.android.importClass('android.provider.Settings')
											const main = plus.android.runtimeMainActivity()
											const intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)
											main.startActivity(intent)
										}
									})
									return
								}
				
								// console.log('开始定位请求')
								doLocationRequest()
							} catch (error) {
								// console.error('定位流程出错:', error)
								uni.showModal({
									title: '提示',
									content: '定位失败,请检查权限设置',
									showCancel: false,
									confirmText: '确定'
								})
							}
						}
				
						// 启动定位流程
						startLocationProcess()
					}else{
						this.checkLocationPermission()
					}
					// #endif
				},
				// 获取定位前先检查权限
				async checkLocationPermission() {
					// #ifdef APP-PLUS
						return new Promise((resolve, reject) => {
							try {
								// console.log('开始检查 iOS 定位权限')
								const CLLocationManager = plus.ios.import("CLLocationManager")
								const status = CLLocationManager.authorizationStatus()
								// console.log('iOS定位权限状态:', status)
				
								// 创建定位管理器实例
								const locationMgr = new CLLocationManager()
				
								if (status === 0) { // 未确定
									// console.log('请求定位权限')
									try {
										// 使用uni的方式请求定位
										// uni.getLocation({
										// 	type: 'wgs84',//'gcj02',//
										// altitude:true,
										// geocode: true,
										// isHighAccuracy: true,
										// timeout: 10000,
										// 	success: (res) => {
										// 		console.log(res,'定位权限请求成功')
										// 		this.getAddress(res.latitude, res.longitude)
										// 		resolve(true)
										// 	},
										// 	fail: (err) => {
										// 		console.error('定位权限请求失败:', err)
										// 		uni.hideLoading()
										// 		resolve(false)
										// 	}
										// })
										this.doLocation()
									} catch (error) {
										// console.error('请求权限失败:', error)
										resolve(false)
									}
								} else if (status === 2) { // 拒绝
									uni.showModal({
										title: '提示',
										content: '需要开启定位权限才能拍照,是否去设置?',
										success: (res) => {
											if (res.confirm) {
												plus.runtime.openURL('app-settings:')
											}
											plus.ios.deleteObject(locationMgr)
											plus.ios.deleteObject(CLLocationManager)
											resolve(false)
										}
									})
								} else if (status === 3 || status === 4) { // 已授权
									plus.ios.deleteObject(locationMgr)
									plus.ios.deleteObject(CLLocationManager)
									resolve(true)
								} else {
									plus.ios.deleteObject(locationMgr)
									plus.ios.deleteObject(CLLocationManager)
									resolve(false)
								}
							} catch (error) {
								// console.error('iOS权限检查失败:', error)
								resolve(false)
							}
						})
					// #endif
					return Promise.resolve(true)
				},
			},
	};
</script>

<style lang="less" scoped>
.buttonphoto{
	.van-button__icon{
		font-size: 2.2em;
		color: #666;
	}
}
.vantimg{
	width: 100px;
	height: 100px;
	border-radius: 6px;
	::v-deep.van-image__img{
		width: 100px;
		height: 100px;
		border-radius: 6px;
	}
}
.badge-icon {
  display: block;
  font-size: 10px;
  line-height: 16px;
}
.imgclose{
	::v-deep.van-badge{
		background-color:rgba(0, 0, 0, 0.8);
	}
	
}
</style>

//element-ui添加水印

<el-upload
          ref="upload"
          class="upload-demo"
          multiple
          :file-list="fileList"
          :show-file-list="false"
          :auto-upload="false"
          :on-change="handleChange"
        >
          <el-button
            type="primary"
            size="small"
            @click="fileUploadClick"
            :disabled="isLv"
            >上传文件</el-button
          >
        </el-upload>


// 文件改变时候
    handleChange(file, fileList) {
      this.upChange(file.raw).then((watermarkedImage) => {
        // 这里可以设置一个变量,以便在上传时使用处理后的图片
        const watermarkedFile = watermarkedImage;
        console.log(watermarkedFile);
        if (watermarkedFile) {
          this.uploadFile(watermarkedFile);
        } else {
          this.$message.error("请先选择并处理图片!");
        }
      });
    },
    
    //添加水印
    upChange(file) {
      let _this = this;

      console.log(file);
      let params = this.contentObj;//水印内容
      // 水印名称
      let roleObj = window.sessionStorage.getItem("role")
        ? JSON.parse(window.sessionStorage.getItem("role"))
        : "";
      let name = this.userInfo.realname;//水印内容-拍摄人
      let role = roleObj
        ? roleObj.roleName
        : this.userInfo.roleList[0].roleName;
      //水印日期
      const now = new Date();
      const year = now.getFullYear();
      const month =
        now.getMonth() + 1 < 9
          ? "0" + (now.getMonth() + 1)
          : now.getMonth() + 1; // 月份从0开始,所以要加1
      // const day = now.getDate();
      const day = now.getDate() < 9 ? "0" + now.getDate() : now.getDate();
      // const hour = now.getHours();
      const hour = now.getHours() < 9 ? "0" + now.getHours() : now.getHours();
      // const minute = now.getMinutes();
      const minute =
        now.getMinutes() < 9 ? "0" + now.getMinutes() : now.getMinutes();
      // const second = now.getSeconds();
      const second =
        now.getSeconds() < 9 ? "0" + now.getSeconds() : now.getSeconds();
      let time =
        year +
        "-" +
        month +
        "-" +
        day +
        " " +
        hour +
        ":" +
        minute +
        ":" +
        second;

      return new Promise((resolve, reject) => {
        let textArray = [];
        // if (params.content.length > 40) {//水印内容太长的话做折行处理
        //   contentHeight = 100 + 20;
        //   params["content1"] = params.content.slice(40);
        //   params.content = params.content.slice(0, 40);
        //   textArray = [
        //     params.projName,
        //     `拍摄人员: ${role}-${name}`,
        //     `拍摄时间: ${time}`,
        //     `拍摄地点: ${this.address}`,
        //     `${params.content}`,
        //     `${params.content1}`,
        //   ];
        // } else {
        //   contentHeight = 100;
        if (params.content) {
          textArray = [
            params.projName,
            `拍摄人员: ${role}-${name}`,
            `拍摄时间: ${time}`,
            `拍摄地点: ${this.address}`,
            `${params.content}`,
          ];
        } else {
          textArray = [
            params.projName,
            `拍摄人员: ${role}-${name}`,
            `拍摄时间: ${time}`,
            `拍摄地点: ${this.address}`,
          ];
        }

        // }

        const canvas = document.createElement("canvas");
        let ctx = canvas.getContext("2d");
        const img = new Image();
        img.onload = () => {
          canvas.width = img.width;
          canvas.height = img.height;
          let fontSize = img.height / 50;//根据图片高度设置水印文字大小
          let contentHeight = img.height / 6;//根据图片高度设置水印底色高度
          fontSize = fontSize < 12 ? 12 : fontSize;
          contentHeight = contentHeight < 100 ? 100 : contentHeight;
          console.log(img, img.width, img.height, "图片宽高");

          const width = img.width;
          const height = img.height;
          ctx.drawImage(img, 0, 0, width, height);
          // 绘制白色画布--开始
          // ctx.save();
          ctx.globalAlpha = 0.3; // 设置边框的透明度
          ctx.beginPath(); // 绘制底部的白色背景
          ctx.fillStyle = "white";
          ctx.fillRect(0, height - contentHeight, width, contentHeight); //绘制画布(x,y,width,height)
          console.log(height - contentHeight, contentHeight, "白底宽高");
          // 绘制白色画布--结束
          // 绘制文字画布--开始
          // ctx.save();
          ctx.globalAlpha = 0.8; // 设置文字的透明度
          ctx.textAlign = "left";
          ctx.fillStyle = "black";
          textArray.forEach((el, index) => {
            let offsetY =
              index == 0
                ? fontSize * index + fontSize * 2
                : fontSize * index + (index + fontSize) + fontSize * 2;
            let zi = `${fontSize}px  Arial`;
            if (index == 0) {
              zi = `${fontSize + 4}px  Arial`;
              ctx.font = zi; // 绘制底部的文字
            } else {
              ctx.font = zi; // 绘制底部的文字
            }
            console.log(zi, ctx.font, "画布字体大小");
            // console.log( offsetY)
            ctx.fillText(el, 10, height - contentHeight + offsetY + index);
            // ctx.save();
          });

          canvas.toBlob((blob) => {
            // 将带水印的图片转换为Blob对象,然后重新创建一个File对象,以便后续上传
            const newFile = new File([blob], file.name, { type: file.type });
            // _this.uploadFile(newFile); // 上传带水印的图片文件
            resolve(newFile);
          }, file.type);
        };
        img.src = URL.createObjectURL(file); // 设置图片源
      });
      // reader.readAsDataURL(file); // file转base64
      // 阻止默认上传行为,因为我们手动处理了文件上传逻辑
      // return false;
    },
    
    //水印添加成功后上传照片
    async uploadFile(file) {
      const formData = new FormData();
      formData.append("file", file); // 将带水印的图片文件添加到FormData对象中
      // formData.append("businessId", this.businessId);
      let dirId = this.dirId ? this.dirId : "";
      formData.append("dirId", dirId);
      formData.append("tag", this.tag);
      console.log(formData, "555555");
      axios
        .post("/doc/docAttachment/upload", formData, {
          headers: {
            "Content-Type": "multipart/form-data",
            "Admin-Token": window.sessionStorage.getItem("access_token"),
          },
        })
        .then((res) => {
          //上传成功返回文件处理
          let file = res.data.data;
          this.fileList.push({
            url: file.fileurl,
            uid: file.uid,
            id: file.id,
            name: file.name,
          });
        });
    },

//通过高德地图经纬度转换为具体位置

//获取当前位置
 geolocation() {
      navigator.geolocation.getCurrentPosition(
        (position) => {
          // console.log('H5获取位置成功:', position)
          const coords = position.coords;
          // console.log('当前位置的经度:' + coords.longitude)
          // console.log('当前位置的纬度:' + coords.latitude)
          this.getAddress(coords.latitude, coords.longitude);
          // that.doLocation()
        },
        (error) => {
          // console.error('H5获取位置失败:', error)
          let message = "获取位置失败";
          switch (error.code) {
            case error.PERMISSION_DENIED:
              message = "请允许浏览器获取位置信息";
              break;
            case error.POSITION_UNAVAILABLE:
              message = "位置信息不可用";
              break;
            case error.TIMEOUT:
              message = "获取位置超时";
              break;
          }
          this.$message.error(message);
        },
        {
          enableHighAccuracy: true,
          timeout: 5000,
          maximumAge: 0,
        }
      );
    },

//坐标转换位置
async getAddress(latitude, longitude) {
      let lat = latitude + 0.002024; //尽量不调整
      let lon = longitude + 0.005876; //尽量不调整
      let that = this;
      try {
        // 高德逆地理变码 https://lbs.amap.com/api/webservice/guide/api/georegeo/
        let _key = "e0ae9ad9fd21287cefc4fffcb98fb649"; //高德API key类型:web服务
        let response = await axios.get(
          `https://restapi.amap.com/v3/geocode/regeo?parameters`,
          {
            params: {
              key: _key,
              location: `${lon},${lat}`,
              extensions: "base",
              output: "JSON",
            },
          }
        );
        this.address = response.data.regeocode.formatted_address;
        window.sessionStorage.setItem("address", this.address);
        console.log(response.data.regeocode.formatted_address);
      } catch (error) {
        console.error("getAddress执行出错:", error);
      }
    },

// RSA加密

import { getEncryptValue } from '@/utils/util'

let news=getEncryptValue(Pasword//输入的密码)

const PUBLISH_KEY = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCidgwAP4UvGfZG2TAfS7ookIj/zltg0t3zwgq8qIws7veg8aN4kU8E4Xc+KKefeJ7zcFp5G9Y4s0V7uhgKaZCzotPbqwnNj24qoNQfLkUXfwZSIGEsRFEP1to5b8eFo5IQu8OEt8w4Tz4TgZaXyoLPoMLQYLoud07VlxewrfZdvQIDAQAB'

export function getEncryptValue(value) {
  const encrypt = new JSEncrypt()
  encrypt.setPublicKey(PUBLISH_KEY)
  return encrypt.encrypt(value)
}

转换时间格式2020-11-23


    if (time) {
        var date = new Date(time)
        var year = date.getFullYear()
        /* 在日期格式中,月份是从0开始的,因此要加0
         * 使用三元表达式在小于10的前面加0,以达到格式统一  如 09:11:05
         * */

        var month=date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1
        var day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate()
        var hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours()
        var minutes = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()
        var seconds = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()
        // 拼接
        return year + '-' + month + '-' + day
    } else {
        return ''
    }
}

echarts字体自适应

export const echartsFont = (size) => {
  let htmlFont
  if (screen.width > 750) {
    htmlFont = 75
  } else {
    htmlFont = screen.width / 10
  }
  return size * htmlFont
}

// 防抖

export function debounce(fn, delay = 300) {
  let timer
  return function () {
    if (timer) {
      clearTimeout(timer)
    }
    timer = setTimeout(() => {
      timer = null
      fn.apply(this, arguments)
    }, delay)
  }
}

//随机字符串

export function randomString(e) {
  e = e || 32
  let t = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678',
    a = t.length,
    n = ''
  for (let i = 0; i < e; i++) n += t.charAt(Math.floor(Math.random() * a))
  return n
}

// 手机打码

export const maskmobile = (mobile) => {
  if (!mobile) return
  return mobile.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2')
}

// 身份证打码

export const maskIdNumber = (id) => {
  return id.replace(/^(.{6})(.*)(.{4})$/, '$1********$3')
}

// 姓名打码

export const maskName = (name) => {
  if (name.length < 2) {
    return
  }
  let arr = name.split('')
  if (arr.length === 2) {
    return arr[0] + '*'
  } else {
    return arr[0] + '*' + arr[arr.length - 1]
  }
}

//回显字典label

export function selectDictLabel(datas, value) {
  let actions = []
  Object.keys(datas).some((key) => {
    if (datas[key].value == '' + value) {
      actions.push(datas[key].label)
      return true
    }
  })
  return actions.join('')
}

// 验证中文

export const isCN = (str) => {
  if (!str) return
  return str.match(/^([\u4E00-\u9FA5]+,?)+$/) !== null
}

// 验证手机号

export const isMobile = (val) => {
  return /^1[3-9]\d{9}$/.test(val)
}

// 验证手机号和座机 7-20位

export const isAllMobile = (mobile) => {
  if (!mobile) return
  if (!('' + mobile).match(/^([0-9]|[-]){7,20}$/)) {
    return false
  } 
  return true
}

// 验证身份证

export const isIdNumber = (str) => {
  if (!str) return
  return /(^\d{15}$)|(^\d{17}([0-9]|X)$)/.test(str)
}

// 验证邮件

export const isEmail = (email) => {
  return /^(\w-*\.*)+@(\w-?)+(\.\w{2,})+$/.test(email)
}

// 数字 (number)

// @force {Boolean} 是否强制验证类型
export const isNumber = (val, force = true) => {
  return force ? _isNumber(val) : !isNaN(val)
}

// 整数 (int)

export const isInt = (val, force = true) => {
  return force ? isInteger(val) : /^-?\d+$/.test(val)
}

// 是否是0

export const isZero = (val, force = true) => {
  return force ? val === 0 : /^[0]+$/.test(val)
}

// 正整数(含0)

export const isPositiveInt = (val, force = true) => {
  return (
    isZero(val, force) || (isInt(val, force) && /^\+?[1-9][0-9]*$/.test(val))
  )
}

// 网址

// (protocol)xxx.xxx.xxx(pathname)(query)(hash)
export const isUrl = (url) => {
  //let reg = '(https?|ftp|file)://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]'
  //let re = new RegExp(reg)
  let re = /[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+\.?/
  return re.test(url)
}

//短信验证码

export const smsCode=(val)=>{
  return /^\d{6}$/.test(val)
}

//密码:置为8~20位,且包含数字和字母、字母区分大小写;不支持特殊字符

export const passwordRules = (val)=>{
  return /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,20}$/.test(val)
}

//用户名:2到12个中英文字符

export const userNameRules = (val)=>{
  return /^[\u4e00-\u9fa5a-zA-Z]{2,12}$/.test(val)
}

// 验证邮件和手机号

export const isMobileEmail = (value) =>{
  return isEmail(value) || isMobile(value)
}