<template>
	<view class="fill-form" v-if="step===STEP.FILL">
		<view class="tips">
			<text v-text="addGuestTips"></text>
		</view>
		<view class="input-area">
			<view class="info-item">
				<view class="item-label">
					<text>姓名</text>
				</view>
				<view class="item-content">
					<input v-model="name" type="text" placeholder="请输入姓名" />
				</view>
			</view>
			<view class="info-item">
				<view class="item-label">
					<text>身份证</text>
				</view>
				<view class="item-content">
					<input v-model="idNumber" type="text" placeholder="请输入身份证" />
				</view>
			</view>
			<view class="info-item">
				<view class="item-label">
					<text>手机号</text>
				</view>
				<view class="item-content">
					<input v-model="phone" type="text" placeholder="请输入手机号" />
				</view>
			</view>
		</view>
		<view class="confirm-button">
			<button @click="gotoVerification">立即认证</button>
		</view>
	</view>

	<view class="upload-card" v-else-if="step===STEP.UPLOAD">
		<view class="tips" v-if="!userInfo.name">
			<text v-text="uploadCardTips"></text>
		</view>
		<view class="upload-container" @click="uploadCard('portrait')">
			<image :src="picPath.portrait"></image>
		</view>
		<view class="upload-container" @click="uploadCard('emblem')">
			<image :src="picPath.emblem"></image>
		</view>
		<view class="confirm-button">
			<button @click="uploadComplete">完成上传</button>
		</view>
		<canvas id="convertCanvas" canvas-id="convertCanvas"
			style="width: 1px; height: 1px; position: absolute; left: -9999px;"></canvas>
	</view>

	<view class="verification" v-else-if="step===STEP.VERIFICATION">
		<view class="face-area">
			<view class="tips">
				<view class="tips-title">
					<text>身份核验</text>
				</view>
				<view class="tips-content">
					<text>请根据页面提示进行操作</text>
				</view>
			</view>
			<view class="separator"></view>
			<view class="camera-container">
				<camera v-if="showCamera" class="camera" device-position="front" flash="off" resolution="low"></camera>
			</view>
			<view class="start-info" v-if="showCamera">
				<text>{{verificationTips}}</text>
			</view>
		</view>
		<view class="precautions">
			<view class="tips">
				<view class="tips-title">
					<text>注意事项</text>
				</view>
				<view class="tips-content">
					<text>请遵守需注意事项</text>
				</view>
			</view>
			<view class="separator"></view>
			<view class="precautions-content">
				<text>确认{{name}}本人操作；保持正脸在取景框中根据屏幕指示完成</text>
			</view>
			<view class="precautions-img">
				<view class="precautions-img-item" v-for="img in imgList" :key="img.src">
					<view class="image-container">
						<image :src="img.src" mode="aspectFit"></image>
					</view>
					<view class="precautions-img-desc">
						<text>{{img.desc}}</text>
					</view>
				</view>
			</view>
		</view>
		<view class="confirm-button">
			<button @click="agreeAndStart">同意并开始验证</button>
		</view>
	</view>
</template>

<script setup>
	import {
		onLoad
	} from '@dcloudio/uni-app'
	import {
		computed,
		getCurrentInstance,
		reactive,
		ref,
		watch
	} from 'vue'
	import {
		useUserStore
	} from '../../store/userStore'
	import {
		useCheckinInfoStore
	} from '../../store/checkinInfoStore'
	import {
		useHotelStore
	} from '../../store/hotelStore'
	import {
		useIdCardInfoStore
	} from '../../store/idCardInfoStore'
	import {
		useOrderStore
	} from '../../store/orderStore'
	const STEP = {
		FILL: 'FILL',
		UPLOAD: 'UPLOAD',
		VERIFICATION: 'VERIFICATION'
	}
	let step = ref(STEP.FILL)
	let userStore = useUserStore()
	let userInfo = userStore.userInfo
	let hotelStore = useHotelStore()
	let hotel = hotelStore.hotel
	let checkinInfoStore = useCheckinInfoStore()
	let checkinInfo = checkinInfoStore.checkinInfo
	let idCardInfoStore = useIdCardInfoStore()
	let idCardInfo = idCardInfoStore.idCardInfo

	let currentIdCardInfo = {}

	let VKSession
	/**
	 * addGuest代码区域
	 */
	const addGuestTips = '根据《治安管理处罚法》要求所有入住宾客和访客必须一人一证实名登记'
	let name = ref('')
	let phone = ref('')
	let idNumber = ref('')
	let isMainCustomer = false

	async function gotoVerification() {
		//检查格式是否正确
		let nameReg = /\d/
		if (!name.value || nameReg.test(name.value)) {
			uni.showToast({
				icon: 'none',
				title: '姓名格式错误！'
			})
			return
		}
		let idNumberReg = /^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/;
		if (!idNumberReg.test(idNumber.value)) {
			uni.showToast({
				icon: 'none',
				title: '身份证号格式错误！'
			})
			return
		}
		let phoneReg = /^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/;
		if (!phoneReg.test(phone.value)) {
			uni.showToast({
				icon: 'none',
				title: '手机号格式错误！'
			})
			return
		}
		//判断此顾客信息是否已添加
		for (const info of checkinInfo) {
			if (info.idNumber === idNumber.value) {
				uni.showToast({
					icon: 'none',
					title: '已添加此顾客，请检查填写信息！'
				})
				return
			}
		}
		//检查该顾客是否在当前酒店入住
		let checkinQueryRes = await uni.request({
			url: '/user/isCheckin',
			method: 'POST',
			data: {
				idNumber: idNumber.value,
				hotelId: hotel.hotelId
			}
		})
		if (checkinQueryRes.data.data) {
			uni.showToast({
				icon: 'none',
				title: '该顾客已入住！'
			})
			return
		}

		//判断本地缓存是否有顾客身份证信息
		for (const info of idCardInfo) {
			if (info.name === name.value && info.idNumber === idNumber.value) {
				//本地有，更新当前使用的身份证信息，跳转至人证比对
				currentIdCardInfo = info
				step.value = STEP.VERIFICATION
				return
			}
		}
		//本地没有顾客身份证信息，先到后台查询
		let idCardInfoQueryRes = await uni.request({
			url: '/user/idCardInfo',
			method: 'POST',
			data: {
				idNumber: idNumber.value,
				name: name.value
			}
		})
		//查询到，写入pinia，跳转至人证比对
		if (idCardInfoQueryRes.data.code === 200 && idCardInfoQueryRes.data.data) {
			let info = idCardInfoQueryRes.data.data
			info.birth = info.birthday
			idCardInfoStore.addIdCardInfo(info)
			currentIdCardInfo = info
			step.value = STEP.VERIFICATION
			return
		}
		//没有查询到，初始化用于识别card的VKSession，跳转至上传页面
		step.value = STEP.UPLOAD
	}

	/**
	 * uploadCard代码区域
	 */
	const that = getCurrentInstance()
	const uploadCardTips = '根据《治安管理处罚法》要求所有入住宾客和访客必须一人一证实名登记'
	//照片最大1.5M
	const maxPicSize = 1024 * 1024 * 1.5

	let picPath = reactive({
		portrait: '../../static/idcard_upload_front.png',
		emblem: '../../static/idcard_upload_back.png'
	})
	let detectInfo
	let infoList = ['address', 'nation', 'sex', 'birth', 'issuingAuthority', 'issuingDate', 'expiryDate']

	function infoComplete() {
		for (let info of infoList) {
			if (!currentIdCardInfo[info]) {
				return false
			}
		}
		return true
	}

	function initIdCardVKSession() {
		VKSession = wx.createVKSession({
			track: {
				IDCard: {
					mode: 2 // 照片模式
				}
			},
			version: 'v1',
			gl: that.gl
		})
		VKSession.start(err => {
			VKSession.on('updateAnchors', anchors => {
				// 处理返回的身份证信息
				if (anchors && anchors[0]) {
					// 存在数组，证明存在身份证信息
					const anchor = anchors[0]
					detectInfo = {
						detected: true,
						detectSuccess: true,
						isComplete: anchor.isComplete,
						label: anchor.label,
						orientation: anchor.orientation,
						box: anchor.box,
					}

					// 裁剪信息
					const affineImgWidth = anchor.affineImgWidth
					const affineImgHeight = anchor.affineImgHeight
					const affineMat = anchor.affineMat

					// 存在裁剪信息，进行身份证裁剪处理
					if (affineImgWidth && affineImgHeight && affineMat) {
						getCropIDcard(affineImgWidth, affineImgHeight, affineMat)
					}
				}
			})
			VKSession.on('removeAnchors', anchors => {
				// 图片没有识别到身份证
				detectInfo.detected = true
				detectInfo.detectSuccess = false
			})
		})
	}

	async function uploadCard(direction) {
		let chooseImageRes = await uni.chooseImage({
			count: 1
		})
		//检查图片大小
		let fileSize = chooseImageRes.tempFiles[0].size
		if (fileSize > maxPicSize) {
			uni.showModal({
				title: '图片超出允许大小（1.5M）',
				showCancel: false
			})
			return
		}
		let path = chooseImageRes.tempFilePaths[0]
		//检查图片格式，仅支持jpg或者png格式
		let imageType = path.split('.')[1]
		if (imageType !== 'jpg') {
			if (imageType !== 'png') {
				uni.showModal({
					showCancel: false,
					title: '仅支持jpg或者png格式的图片'
				})
				return
			}
			//png转jpg
			console.log('png to jpg')
			const canvasId = 'convertCanvas'
			const ctx = uni.createCanvasContext(canvasId, that)
			let imageInfo = await uni.getImageInfo({
				src: path
			})
			console.log('getImageInfo', imageInfo)

			// 绘制图片到canvas
			await new Promise((resolve, reject) => {
				ctx.drawImage(path, 0, 0, imageInfo.width, imageInfo.height)
				ctx.draw(false,
					async () => {
							// 将canvas内容转换为jpg格式的临时文件路径
							let res = await uni.canvasToTempFilePath({
								canvasId: canvasId,
								fileType: 'jpg',
								quality: 1, // 图片质量，可根据需要调整
							}, that)
							path = res.tempFilePath
							console.log('图片转换成功，临时路径为：', res.tempFilePath)
							resolve()
						},
						err => {
							reject(err)
						})
			})
			console.log('jpg path', path)
		}

		await setImageUploadInfo(path)
		await detectIdCard()
		//图片中不包含身份证
		if (!detectInfo.detectSuccess) {
			uni.showModal({
				title: '图片中不包含身份证，请重新上传',
				showCancel: false
			})
			return
		}
		if (!detectInfo.isComplete) {
			uni.showModal({
				title: '身份证照片不完整，请重新上传',
				showCancel: false
			})
			return
		}
		if ((direction === 'portrait' && detectInfo.label !== 0) ||
			(direction === 'emblem' && detectInfo.label !== 1)) {
			uni.showModal({
				title: '身份证面错误，请重新上传',
				showCancel: false
			})
			return
		}
		uni.showLoading({
			title: '上传中',
			mask: true
		})
		try {
			let res = await uni.request({
				url: '/user/idCardOcr',
				method: 'POST',
				data: {
					image: imageUploadInfo.imgUrl.split(',')[1],
					ocrType: detectInfo.label,
					imageType: 'BASE64'
				}
			})
			if (!res.data.success || res.data.data.imageStatus !== 'normal') {
				uni.showModal({
					content: '获取信息失败，请检查图片并重新上传',
					showCancel: false,
				})
				return
			}

			if (direction === 'portrait') {
				//第一次使用时没有在addGuest页面输入信息，用身份证识别到的信息
				if (isMainCustomer && !name.value && !idNumber.value) {
					//检查该顾客是否在当前酒店入住
					let checkinQueryRes = await uni.request({
						url: '/user/isCheckin',
						method: 'POST',
						data: {
							idNumber: res.data.data.cardNum,
							hotelId: hotel.hotelId
						}
					})
					if (checkinQueryRes.data.data) {
						uni.showToast({
							icon: 'none',
							title: '该顾客已入住！'
						})
						return
					}
				} else {
					if (res.data.data.cardNum !== idNumber.value ||
						res.data.data.name !== name.value) {
						uni.showModal({
							content: '填写信息与身份证不一致',
							showCancel: false,
							complete: () => {
								step.value = STEP.FILL
							},
						})
						return
					}
					currentIdCardInfo = {
						...currentIdCardInfo,
						name: res.data.data.name,
						sex: res.data.data.sex,
						nation: res.data.data.nation,
						birth: res.data.data.birth,
						address: res.data.data.address,
						idNumber: res.data.data.cardNum
					}
				}
				picPath.portrait = imageUploadInfo.imgUrl
			} else {
				currentIdCardInfo = {
					...currentIdCardInfo,
					issuingAuthority: res.data.data.issuingAuthority,
					issuingDate: res.data.data.issuingDate,
					expiryDate: res.data.data.expiryDate
				}
				picPath.emblem = imageUploadInfo.imgUrl
			}
		} catch (err) {
			console.log("身份验证出错", err);
			uni.showModal({
				content: '获取信息失败，请检查图片并重新上传',
				showCancel: false,
			})
		} finally {
			uni.hideLoading()
		}
	}

	let imageUploadInfo

	async function setImageUploadInfo(url) {
		const fixWidth = 300
		let imageInfo = await uni.getImageInfo({
			src: url
		})
		console.log('imageInfo', imageInfo)
		let height = imageInfo.height
		let width = imageInfo.width
		imageUploadInfo = {
			imgUrl: url,
			imgWidth: fixWidth,
			imgHeight: (fixWidth / width) * height,
			imgOriginWidth: width,
			imgOriginHeight: height
		}
	}

	async function detectIdCard() {
		const canvas = wx.createOffscreenCanvas({
			type: '2d',
			width: imageUploadInfo.imgOriginWidth,
			height: imageUploadInfo.imgOriginHeight
		})
		const context = canvas.getContext('2d')
		const img = canvas.createImage()
		that.img = img
		await new Promise(resolve => {
			img.onload = resolve
			img.src = imageUploadInfo.imgUrl
		})
		context.clearRect(0, 0, imageUploadInfo.imgOriginWidth, imageUploadInfo.imgOriginHeight)
		context.drawImage(img, 0, 0, imageUploadInfo.imgOriginWidth, imageUploadInfo.imgOriginHeight)

		// 使用中的 image ArrayBuffer
		that.imgData = context.getImageData(0, 0, imageUploadInfo.imgOriginWidth, imageUploadInfo
			.imgOriginHeight)

		VKSession.detectIDCard({
			// 识别身份证图片的信息
			frameBuffer: that.imgData.data.buffer,
			width: imageUploadInfo.imgOriginWidth,
			height: imageUploadInfo.imgOriginHeight,
			// 是否获取裁剪图片信息
			getAffineImg: true,
		})
	}

	function getCropIDcard(affineImgWidth, affineImgHeight, affineMat) {
		const canvas = wx.createOffscreenCanvas({
			type: '2d',
			width: affineImgWidth,
			height: affineImgHeight,
		})
		const context = canvas.getContext('2d')

		context.clearRect(0, 0, affineImgWidth, affineImgHeight);
		/*
		 * affineMat 3x3仿射变换矩阵，行主序
		 *  [0 1 2
		 *   3 4 5
		 *   6 7 8]
		 */
		/*
		 * canvas 2d setTransform
		 * setTransform(a, b, c, d, e, f)
		 *  [a c e
		 *   b d f
		 *   0 0 1]
		 */
		context.setTransform(
			Number(affineMat[0]), Number(affineMat[3]), Number(affineMat[1]),
			Number(affineMat[4]), Number(affineMat[2]), Number(affineMat[5])
		);
		context.drawImage(that.img, 0, 0, imageUploadInfo.imgOriginWidth, imageUploadInfo.imgOriginHeight)
		const imgUrl = canvas.toDataURL()
		imageUploadInfo.imgUrl = imgUrl
	}

	function uploadComplete() {
		if (!infoComplete()) {
			uni.showToast({
				icon: 'none',
				title: '信息不完整，请检查身份证'
			})
			return
		}
		//保存到本地缓存
		idCardInfoStore.addIdCardInfo({
			...currentIdCardInfo
		})
		//上传至服务器
		uni.request({
			url: '/user/idCardInfo/add',
			method: 'POST',
			data: {
				...currentIdCardInfo,
				birthday: currentIdCardInfo.birth,
				idCardFrontBase64: picPath.portrait.split(',')[1],
				idCardBackBase64: picPath.emblem.split(',')[1]
			}
		})
		step.value = STEP.VERIFICATION
	}

	/**
	 * verification
	 */
	let cameraAuth = ref(false)
	let startVerification = ref(false)
	let verificationTips = ref('开始身份核验')
	let showCamera = computed(() => {
		return cameraAuth.value && startVerification.value
	})
	const imgList = [{
			src: '/static/check-face-phone.png',
			desc: '正对手机'
		},
		{
			src: '/static/check-face-light.png',
			desc: '光线充足'
		},
		{
			src: '/static/check-face-face.png',
			desc: '脸部无遮挡'
		}
	]

	function agreeAndStart() {
		if (!cameraAuth.value) {
			getCameraAuth()
			return
		} else {
			VKSession.start(err => {
				if (err) {
					uni.showModal({
						title: '网络错误,请退出后重试',
						showCancel: false,
					})
				}
			})
		}

		startVerification.value = true
	}

	function getCameraAuth() {
		uni.getSetting({
			success: (res) => {
				if (res.authSetting['scope.camera']) {
					cameraAuth.value = true
				} else {
					uni.authorize({
						scope: 'scope.camera',
						success: (res) => {
							cameraAuth.value = true
						},
						fail: (res) => {
							uni.showModal({
								title: '尚未进行授权，功能将无法使用',
								showCancel: false
							})
						}
					})
				}
			}
		})
	}

	let cameraEngine
	let listener

	function initCameraEngine() {
		cameraEngine = wx.createCameraContext()
		let count = 0
		listener = cameraEngine.onCameraFrame(frame => {
			count++
			//每十帧分析一次
			if (count === 10) {
				detectFace(frame)
				count = 0
			}
		})
		listener.start()
	}

	function initFaceVKSession() {
		//销毁上传身份证时创建的session
		if (VKSession) {
			VKSession.destroy()
		}
		VKSession = wx.createVKSession({
			version: 'v1',
			track: {
				plane: {
					mode: 1
				},
				face: {
					mode: 2
				}
			}
		})
		VKSession.on('updateAnchors', (anchors) => {
			// console.log('anchors', anchors)
			// console.log('anchors.length', anchors.length)
			anchors.forEach((anchor) => {
				// console.log('anchor.points', anchor.points)
				// console.log('anchor.origin', anchor.origin)
				// console.log('anchor.size', anchor.size)
				// console.log('anchor.angle', anchor.angle)
				// console.log('anchor', anchor.confidence)
				if (anchors.length > 1) {
					verificationTips.value = '请保证只有一个人'
				} else {
					const {
						pitch,
						roll,
						yaw
					} = anchor.angle
					const standard = 0.3

					if (
						Math.abs(pitch) >= standard ||
						Math.abs(roll) >= standard ||
						Math.abs(yaw) >= standard
					) {
						verificationTips.value = '请平视摄像头'
					} else if (
						anchor.origin.x < 0.15 ||
						anchor.origin.x > 0.3 ||
						anchor.origin.y < 0.2 ||
						anchor.origin.y > 0.45
					) {
						verificationTips.value = '请将人脸对准中心位置'
					} else if (
						anchor.confidence[0] <= 0.8 ||
						anchor.confidence[1] <= 0.8 ||
						anchor.confidence[2] <= 0.8 ||
						anchor.confidence[3] <= 0.8 ||
						anchor.confidence[4] <= 0.8
					) {
						verificationTips.value = '请勿遮挡五官'
					} else {
						listener.stop()
						verificationTips.value = '即将拍照，请保持！'
						setTimeout(function() {
							takePhoto()
						}, 1000)
					}
				}
			})
		})
	}

	function takePhoto() {
		verificationTips.value = ''
		uni.showLoading({
			title: '正在身份核验，请稍后',
		})
		cameraEngine.takePhoto({
			quality: 'normal',
			success: async ({
				tempImagePath
			}) => {
				let base64 = wx
					.getFileSystemManager()
					.readFileSync(tempImagePath, 'base64')
				startVerification.value = false
				await checkFace(base64)
			},
		})
	}

	async function detectFace(frame) {
		VKSession.detectFace({
			frameBuffer: frame.data,
			width: frame.width,
			height: frame.height,
			scoreThreshold: 0.8,
			sourceType: 0,
			modelMode: 1,
		})
	}

	async function checkFace(base64) {
		uni.showLoading({
			title: '正在身份核验，请稍后',
			mask: true
		})
		try {
			let res = await uni.request({
				url: '/user/faceCheckAll',
				method: 'POST',
				data: {
					hotelId: hotel.hotelId,
					name: name.value,
					idNumber: idNumber.value,
					imageBase64: base64
				}
			})
			if (res.data.success) {
				//如果是主入住人，且当前账号姓名和身份证号为空，则更新账号信息为主入住人信息
				if (isMainCustomer) {
					if (!userInfo.name || !userInfo.idNumber) {
						//修改本地缓存中的信息
						userInfo.name = name.value
						userInfo.idNumber = idNumber.value
						userStore.updateUserInfo(userInfo)
						//修改服务器中的信息
						uni.request({
							url: `/user`,
							method: 'PUT',
							data: {
								name: name.value,
								idNumber: idNumber.value
							}
						})
					}
					//更新订单中预定人信息为主入住人信息
					let orderStore = useOrderStore()
					let orderInfo = orderStore.orderInfo
					orderStore.updateOrderInfo({
						...orderInfo,
						name: name.value,
						phone: phone.value
					})
				}
				//更新缓存中的入住信息
				checkinInfoStore.addCheckinInfo({
					phone: phone.value,
					faceData: base64,
					...currentIdCardInfo
				})
				uni.showToast({
					icon: 'none',
					title: '身份核验通过！',
					success: () => {
						setTimeout(() => {
							uni.reLaunch({
								url: '/subpkg_checkin/confirmOrder/confirmOrder'
							})
						}, 1500)
					}
				})
			} else {
				uni.showModal({
					title: '身份核验失败,请重试',
					showCancel: false
				})
			}
		} catch (err) {
			console.log('err', err)
			uni.showModal({
				title: '身份核验失败,请重试',
				showCancel: false
			})
			uni.hideLoading()
		} finally {
			//finally中调用uni.hideLoading()会关闭上面的uni.showToast导致toast一闪而过
			//调用uni.showToast时会覆盖掉uni.hideLoading，因此只在catch中调用uni.hideLoading即可
			// uni.hideLoading()
		}
	}


	watch(step, (newValue, oldValue) => {
		if (newValue === STEP.UPLOAD) {
			console.log('initIdCardVKSession')
			initIdCardVKSession()
		} else if (newValue === STEP.VERIFICATION) {
			console.log('initCameraEngine')
			initCameraEngine()
			console.log('initFaceVKSession')
			initFaceVKSession()
		}
	})

	onLoad(() => {
		/**
		 * addGuest
		 */
		let pages = getCurrentPages()
		let beforePage = pages[pages.length - 2]
		if (beforePage.route === 'subpkg_checkin/selectRoom/selectRoom') {
			name.value = userInfo.name
			phone.value = userInfo.phone
			idNumber.value = userInfo.idNumber
			isMainCustomer = true
		}

		//是主入住人且姓名和身份证号为空，判断为新用户，直接跳转至上传身份证照片页面
		if (isMainCustomer && (!name.value || !idNumber.value)) {
			step.value = STEP.UPLOAD
		}

		/**
		 * uploadCard
		 */
		let isVKSupport = wx.isVKSupport('v1')
		if (!isVKSupport) {
			uni.showModal({
				title: '微信版本过低，请升级至最新版本',
				showCancel: false,
				success() {
					uni.navigateBack()
				}
			})
			return
		}
		/**
		 * verification
		 */
		//获取相机权限
		getCameraAuth()
	})
</script>

<style lang="scss">
	.fill-form {
		.tips {
			margin: 30rpx;
			color: #333333;
			font-size: 28rpx;
		}

		.input-area {
			background-color: #ffffff;

			.info-item {
				height: 100rpx;
				display: flex;
				align-items: center;
				margin: 0 40rpx;
				border-bottom: #E5E5E5 2rpx solid;

				.item-label {
					width: 20vw;
				}

				.item-content {
					input {
						padding: 10rpx;
						width: 50vw;
					}
				}
			}
		}

		.confirm-button {
			position: fixed;
			bottom: 90rpx;
			left: 30rpx;
			right: 30rpx;

			button {
				background-color: #a09cc4;
				color: #ffffff;
			}
		}
	}

	.upload-card {
		.tips {
			margin: 30rpx;
			color: #333333;
			font-size: 28rpx;
		}

		.upload-container {
			width: 500rpx;
			margin: 30rpx auto;

			image {
				width: 500rpx;
				height: 350rpx;
				margin: 0 auto;
			}
		}

		.confirm-button {
			position: fixed;
			bottom: 90rpx;
			left: 30rpx;
			right: 30rpx;

			button {
				background-color: #a09cc4;
				color: #ffffff;
			}
		}
	}

	.verification {
		.tips {
			display: flex;
			margin: 20rpx;
			align-items: flex-end;

			.tips-title {
				color: #333333;
				font-weight: bold;
				font-size: 34rpx;
				margin-right: 20rpx;
			}

			.tips-content {
				color: #CBCBCB;
				font-size: 28rpx;
			}
		}

		.separator {
			margin-left: 40rpx;
			margin-bottom: 20rpx;
			width: 30rpx;
			border-bottom: solid 6rpx #9e97c3;
		}

		.face-area {
			display: flex;
			flex-direction: column;
			background-color: #FFFFFF;
			border-radius: 50rpx;
			overflow: hidden;

			.camera-container {
				width: 80%;
				height: 80vw;
				margin: 0 auto;
				margin-bottom: 30rpx;

				camera {
					width: 100%;
					height: 80vw;
					margin: 0 auto;
					margin-bottom: 30rpx;
					border: 2rpx solid black;
					border-radius: 50%;
					// box-sizing: border-box;
				}
			}

			.start-info {
				margin: 0 auto
			}
		}

		.precautions {
			.precautions-content {
				color: #666666;
				font-size: 24rpx;
				margin: 20rpx;
			}

			.precautions-img {
				display: flex;
				justify-content: space-around;

				.precautions-img-item {
					display: flex;
					flex-direction: column;
					align-items: center;
					width: 20%;

					.image-container {
						width: 120rpx;
						height: 120rpx;
						border-radius: 20rpx;
						background-color: #dcdce9;
						display: flex;
						justify-content: center;
						align-items: center;

						image {
							width: 80rpx;
							height: 80rpx;
						}
					}

					image {
						width: 80rpx;
						height: 80rpx;
					}
				}
			}
		}

		.confirm-button {
			position: fixed;
			bottom: 90rpx;
			left: 30rpx;
			right: 30rpx;

			button {
				background-color: #a09cc4;
				color: #ffffff;
			}
		}
	}
</style>