微信端添加版本号;

修补信息泄露漏洞;
This commit is contained in:
2025-12-16 12:54:05 +08:00
parent ae10b928ba
commit 783364b695
9 changed files with 121 additions and 2629 deletions
-310
View File
@@ -1,310 +0,0 @@
<template>
<div class='invitation-model-fixed' id="canvas">
<div class="invitation-model">
<img class="english-title" src="../assets/yinwen.png" alt="">
<div class="ewm-box">
<!-- <img :src=" 'data:image/png;base64,'+imgEncode" alt=""> -->
<img src="https://www.baidu.com/s?wd=%E7%99%BE%E5%BA%A6%E7%83%AD%E6%90%9C&sa=ire_dl_gh_logo_texing&rsv_dl=igh_logo_pcs" alt="">
<b class="ewm-box-one"></b>
<b class="ewm-box-two"></b>
<b class="ewm-box-three"></b>
<b class="ewm-box-four"></b>
</div>
<div class="tips">快来保存您的专属邀约二维码吧</div>
<button @click="onClickDown" class="save-button">保存图片</button>
<span @click="onClickA" :href="canvasUrl" download="下载">下载</span>
</div>
<!-- {{ raw }} -->
</div>
<Savesuccessmodel v-if="false" />
</template>
<script setup>
import { ref } from 'vue'
import { useRouter } from 'vue-router'
import { useStore } from 'vuex'
import { rulesForm, resetForm, rulesPhone } from '@/com/index'
import dd from 'dingtalk-jsapi'
import html2canvas from 'html2canvas'
import Savesuccessmodel from '@/components/save-success.vue'
import { getToken, getVisitorRecord, getWhiteCode } from '@/api/admin.js'
/* @data */
const router = useRouter()
const store = useStore()
const imgEncode = ref('')
const raw = ref('')
const canvasUrl = ref('')
/* @setup */
getWhiteCode().then(res =>{
console.log(res)
imgEncode.value = res.imgEncode
// raw.value = window.atob(res.imgEncode);
})
/* @method */
const onClickDown1 = () =>{
// const byteCharacters = atob(imgEncode.value);
// const byteNumbers = new Array(byteCharacters.length);
// for (let i = 0; i < byteCharacters.length; i++) {
// byteNumbers[i] = byteCharacters.charCodeAt(i);
// }
// const byteArray = new Uint8Array(byteNumbers);
// const blob = new Blob([byteArray], { type: 'image/jpeg' });
// raw.value = byteArray
// // 创建可下载链接
// const url = URL.createObjectURL(blob);
// // 创建隐藏的<a>标签
// const link = document.createElement('a');
// link.href = url;
// link.download = 'fileName';
// // 模拟点击隐藏的<a>标签来触发下载
// link.click();
// // 清理URL对象
// URL.revokeObjectURL(url);
}
const onClickA =() =>{
const canvas = document.getElementById('canvas')
console.log(canvas.offsetHeight)
console.log(canvas.scrollHeight)
// alert('asjfjafj1')
// // window.location.href = canvasUrl.value
// dd.previewImage({
// urls: [
// canvasUrl.value,
// ],
// current: 1,
// success: () => {},
// fail: () => {},
// complete: () => {},
// });
// dd.openLink({
// url: 'https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png',
// success: () => {},
// fail: () => {},
// complete: () => {},
// });
// dd.saveImage({
// url: 'https://img.alicdn.com/tps/TB1sXGYIFXXXXc5XpXXXXXXXXXX.jpg',
// success: () => {},
// fail: () => {},
// complete: () => {},
// });
}
const onClickDown = () =>{
let options = { scale: 1, allowTaint: false, useCORS: true, width: '375', height: '649', backgroundColor: null }
autoPicture('canvas')
}
const autoPicture = async (el, options) => {
// let { scale = 1, allowTaint = false, useCORS = true, width = '375', height = '649', backgroundColor = null } = options
const id = document.getElementById(el)
const canvas = await html2canvas(id, {
scale: 1, //缩放比例,默认为1
allowTaint: false, //是否允许跨域图像污染画布
useCORS: true, //是否尝试使用CORS从服务器加载图像
width: id.offsetWidth, //画布的宽度
height: id.offsetHeight, //画布的高度
backgroundColor: null //画布的背景色,默认为透明
})
// canvas.toDataURL('image/png')
console.log(canvas.toDataURL('image/png'))
canvasUrl.value = canvas.toDataURL('image/png')
}
</script>
<style lang='scss' scoped>
.invitation-model-fixed{
position: fixed;
width: 100%;
height: 100%;
background: rgba(60,60,67,0.6);
.invitation-model{
position: absolute;
top: 20%;
left: 50%;
transform: translateX(-50%);
width: 7.2267rem /* 542/75 */;
height: 9.3067rem /* 698/75 */;
background: #FFFFFF;
border-radius: .5333rem /* 40/75 */.5333rem /* 40/75 */ .5333rem /* 40/75 */ .5333rem /* 40/75 */;
// overflow: hidden;
opacity: 1;
background: url('../assets/yaoqingbeijing.png') left top/100% 100% no-repeat;
.english-title{
margin: 1.1733rem /* 88/75 */ auto 0;
width: 4.9867rem /* 374/75 */;
height: .6133rem /* 46/75 */;
}
.ewm-box{
position: relative;
border-radius: .1333rem /* 10/75 */;
// border: .1333rem /* 10/75 */ solid #30BF78;
width: 4.64rem /* 348/75 */;
height: 4.64rem /* 348/75 */;
margin: .5067rem /* 38/75 */ auto 0;
display: flex;
justify-content: center;
align-items: center;
img{
width: 4rem /* 300/75 */;
height: 4rem;
}
}
@mixin border-basics {
position: absolute;
width: 1.1733rem /* 88/75 */;
height: 1.1733rem /* 88/75 */;
// border-radius: .1333rem /* 10/75 */;
opacity: 1;
border: .1333rem /* 10/75 */ solid #30BF78;
}
.ewm-box-one::after{
content: '';
position: absolute;
left: 0;
top: 0;
// border: .1333rem /* 10/75 */ solid #30BF78;
width: .1333rem /* 10/75 */;
height: 1.3067rem /* 98/75 */;
background-color: #30BF78;
border-radius: .2667rem /* 20/75 */ 0 .1333rem /* 10/75 */ .1333rem /* 10/75 */;
}
.ewm-box-one::before{
content: '';
position: absolute;
left: 0;
top: 0;
// border: .1333rem /* 10/75 */ solid #30BF78;
width: 1.3067rem /* 98/75 */;
height: .1333rem /* 10/75 */;
background-color: #30BF78;
border-radius: .2667rem /* 20/75 */ .1333rem /* 10/75 */ .1333rem /* 10/75 */ 0 ;
}
.ewm-box-two::after{
content: '';
position: absolute;
right: 0;
top: 0;
// border: .1333rem /* 10/75 */ solid #30BF78;
width: .1333rem /* 10/75 */;
height: 1.3067rem /* 98/75 */;
background-color: #30BF78;
border-radius: 0 .2667rem /* 20/75 */ .1333rem /* 10/75 */ .1333rem /* 10/75 */;
}
.ewm-box-two::before{
content: '';
position: absolute;
right: 0;
top: 0;
// border: .1333rem /* 10/75 */ solid #30BF78;
width: 1.3067rem /* 98/75 */;
height: .1333rem /* 10/75 */;
background-color: #30BF78;
border-radius: .1333rem /* 10/75 */ .2667rem /* 20/75 */ 0 .1333rem /* 10/75 */ ;
}
// .ewm-box-three{
// @include border-basics;
// left: 0;
// bottom: 0;
// border-top: none;
// border-right: none;
// border-radius: 0 0 0 .1333rem /* 10/75 */ ;
// }
.ewm-box-three::after{
content: '';
position: absolute;
left: 0;
bottom: 0;
// border: .1333rem /* 10/75 */ solid #30BF78;
width: .1333rem /* 10/75 */;
height: 1.3067rem /* 98/75 */;
background-color: #30BF78;
border-radius: .1333rem /* 10/75 */ .1333rem /* 10/75 */ 0 .2667rem /* 20/75 */ ;
}
.ewm-box-three::before{
content: '';
position: absolute;
left: 0;
bottom: 0;
// border: .1333rem /* 10/75 */ solid #30BF78;
width: 1.3067rem /* 98/75 */;
height: .1333rem /* 10/75 */;
background-color: #30BF78;
border-radius: 0 .1333rem /* 10/75 */ .1333rem /* 10/75 */ .2667rem /* 20/75 */ ;
}
// .ewm-box-four{
// @include border-basics;
// bottom: 0;
// right: 0;
// border-top: none;
// border-left: none;
// border-radius: 0 0 .1333rem /* 10/75 */ 0;
// }
.ewm-box-four::after{
content: '';
position: absolute;
right: 0;
bottom: 0;
// border: .1333rem /* 10/75 */ solid #30BF78;
width: .1333rem /* 10/75 */;
height: 1.3067rem /* 98/75 */;
background-color: #30BF78;
border-radius: .1333rem /* 10/75 */ .1333rem /* 10/75 */ .2667rem /* 20/75 */ 0 ;
}
.ewm-box-four::before{
content: '';
position: absolute;
right: 0;
bottom: 0;
// border: .1333rem /* 10/75 */ solid #30BF78;
width: 1.3067rem /* 98/75 */;
height: .1333rem /* 10/75 */;
background-color: #30BF78;
border-radius: .1333rem /* 10/75 */ 0 .2667rem /* 20/75 */ .1333rem /* 10/75 */ ;
}
.tips{
font-size: $size30;
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 400;
color: #999999;
margin-top: .72rem /* 54/75 */;
text-align: center;
line-height: .6133rem /* 46/75 */;
}
.save-button{
position: absolute;
bottom: 0;
left: 50%;
z-index: 10;
transform: translateY(50% ) translateX(-50% );
width: 3.76rem /* 282/75 */;
height: 1.1467rem /* 86/75 */;
line-height: 1.1467rem /* 86/75 */;
background: #30BF78;
border-radius: 1.3333rem /* 100/75 */;
opacity: 1;
font-size: $lg-size;
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 400;
color: #FFFFFF;
text-align: center;
border: none;
outline: none;
}
}
}
</style>
-720
View File
@@ -1,720 +0,0 @@
<template>
<div v-if="true" class='box'>
<div class="apply-box">
<img class="text" src="../assets/zhinengfangke.png" alt="">
<p>来访提前约 拜访开门无需按铃</p>
<div class="apply-content">
<h3>
<img src="../assets/icon-shenfenzheng.png" alt="">
<span>拜访信息<span>(我找谁)</span></span>
</h3>
<div class="apply-content-form">
<!-- <Selectli label="被拜访对象" v-model="form.visitingTel" :columns="visitDict" :isMust="true" :isline="true" name="name" nameId="userId"/> -->
<!-- <div class="search-select-box">
<label class="label"><span>*&nbsp;</span>被拜访人</label>
<div class="search-select-input">
<input @click.stop="onClickVisitor" @input="onInputVisior" :value="visitorName" type="text" placeholder="可填写选择">
<div v-if="isSelect && visitDict.length" class="select-box">
<b></b>
<div class="select-sroll-box">
<div @click.self="onClickSelect(item)" v-for="item in visitDict" :class="item.userId == form.visitingTel ? 'select-active' : ''" class="select-li" :key="item.userId">{{ item.name }}</div>
</div>
</div>
<div v-if="isSelect && !visitDict.length" class="select-box">
<b></b>
<div class="select-li" >查无此人</div>
</div>
</div>
</div> -->
<Inputli v-if="telName" v-model="telName" @input="onInputName" label="被访人" :isMust="true" :isline="true" isMustPosition="left"/>
<Inputli v-else v-model="form.visitingTel" @blur="onBlurTel" @input="onInputTel" label="被访人电话" :isMust="true" :isline="true" isMustPosition="left"/>
<Selectdate v-model="form.hours" label="来访时间" :isMust="true" :isline="false" :minDate="minDate"/>
</div>
</div>
<img class="absolute-img" src="../assets/woyaoyuyue.png" alt="">
</div>
<p class="tips">
说明拜访时间前后一小时都可刷脸通过门禁
</p>
<div class="visitor-content">
<h3>
<img src="../assets/icon-shenfenzheng.png" alt="">
<span>访客信息<span>(我是谁)</span></span>
</h3>
<div class="visitor-content-form">
<Inputli v-model="form.name" label="访客姓名" :isMust="true" :isline="true" isMustPosition="left"/>
<Inputli v-model="form.phone" label="联系方式" :isMust="true" :isline="true" isMustPosition="left"/>
<Inputli v-model="form.visitingNum" label="随行人数" :isMust="true" :isline="true" isMustPosition="left"/>
<Inputli v-model="form.reason" label="来访事由" :isMust="true" :isline="true" isMustPosition="left"/>
<div class="upload-box">
<label for=""><span>*&nbsp;</span>人脸照片</label>
<div v-if="!form.img" class="upload-button">
<img @click="onClickUpload" src="../assets/xiangji.png" alt="">
<input v-if="isDisabled" @change="onChangeFile" type="file" accept="image/*">
</div>
<div v-else class="face-img">
<img :src="form.img" alt="">
<input v-if="true" @change="onChangeFile" type="file" accept="image/*">
</div>
</div>
</div>
</div>
<p class="tips">
说明人脸照片用于通过门禁系统请上传正脸无遮挡照片
</p>
<p class="tel-tips">
如果您在使用中遇到问题请联系<span @click="onClickCall">400040-1573</span>
</p>
<!-- <div class="disclaimer-box">
<input type="checkbox">
<p>勾选表示同意<span>用户协议</span></p>
</div> -->
<button @click="onClcikSubmit" class="submit-button " :class="isSubmit ? 'active-button' : ''">提交</button>
<Successmodel v-if="isSuccess" @click="onClickAffirm" />
<div v-if="false" class="disclaimer-model-fixed">
<h3>用户协议</h3>
<div class="disclaimer-model">
阿哈撒发哈师范哈撒发哈很舒服哈哈
阿哈撒发哈师范哈撒发哈很舒服哈哈
阿哈撒发哈师范哈撒发哈很舒服哈哈
阿哈撒发哈师范哈撒发哈很舒服哈哈
阿哈撒发哈师范哈撒发哈很舒服哈哈
阿哈撒发哈师范哈撒发哈很舒服哈哈
阿哈撒发哈师范哈撒发哈很舒服哈哈
阿哈撒发哈师范哈撒发哈很舒服哈哈
阿哈撒发哈师范哈撒发哈很舒服哈哈
阿哈撒发哈师范哈撒发哈很舒服哈哈
阿哈撒发哈师范哈撒发哈很舒服哈哈
</div>
</div>
</div>
</template>
<script setup>
import { reactive, ref, watch } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { useStore } from 'vuex'
import { Toast, ImagePreview , Uploader, Dialog } from 'vant';
import { rulesForm, resetForm, rulesPhone, rulesFormFBoolean, formatDate } from '@/com/index'
import Inputli from '@/components/input-li.vue'
import Selectli from '@/components/select-li.vue'
import Selectdate from '@/components/select-li-date.vue'
import Successmodel from '../components/success.vue'
import { postApply, getVisitor, getUserNameByTel } from '@/api/user.js'
import { uploadApi } from '@/api/upload'
/* @data */
const router = useRouter()
const route = useRoute()
const store = useStore()
const phoneReg = /(^1\d{10}$)|(^[0-9]\d{7}$)/;
let form = reactive({
name: "",
phone: "",
hours: "",
reason: "",
img: "",
visitingTel: "",
visitingNum: '',
})
const isSubmit = ref(false)
const visitDict = ref([]) // 被访客数据
const visitAllDict = ref([]) // 被访客数据
const isDisabled = ref(false) // 是否能提交
const isSuccess = ref(false) // 是否提交成功
const isSelect = ref( false) // 是否显示下拉选择
const visitorName = ref( '') // 是否显示下拉选择的名字
const telName = ref( '') // 电话查询姓名
/* watch */
watch(() => form, (v1, v2) => {
isSubmit.value = rulesFormFBoolean(v2)
if(v2.name && v2.phone){
if(!phoneReg.test(v2.phone)){
isDisabled.value = false
}else{
isDisabled.value = true
}
}else{
isDisabled.value = false
}
},{ deep: true }
) // 深度监听 ) // 监听单个
/* @method */
const onInputTel = (e) =>{
}
const onInputName = (e) =>{
form.visitingTel = ''
telName.value = ''
}
const onBlurTel = (phone) =>{
console.log(phone)
if(rulesPhone(phone)){
getUserNameByTel(phone).then(res =>{
console.log(res)
if(res.data){
telName.value = res.data
}
}).catch(err =>{
console.log(err)
Dialog.alert({
message: err.msg,
}).then(() => {
// on close
});
})
}
}
// const onBlurVisitor = () =>{
// isSelect.value = false
// let item = visitAllDict.value.find(item =>{ return item.userId == form.visitingTel })
// if(item){
// visitorName.value = item.name
// visitDict.value = visitAllDict.value
// }else{
// visitorName.value = '' // 是否显示下拉选择的名字
// visitDict.value = visitAllDict.value
// }
// }
// 输入框
// const onInputVisior = (e) =>{
// visitorName.value = e.target.value
// let arr = []
// visitAllDict.value.map( item =>{
// if(item.name.search(e.target.value) != -1){
// arr.push(item)
// }
// })
// visitDict.value = [ ...arr ]
// }
// 点击选择了拜访对象
// const onClickSelect = (item) =>{
// form.visitingTel = item.userId
// visitorName.value = item.name
// isSelect.value = false
// }
// const onClickVisitor = () =>{
// isSelect.value = true
// }
// 点击确认模态框
const onClickAffirm = () =>{
router.go(-1)
}
const onClickUpload = () =>{
if(isDisabled.value){
}else{
Toast.fail('请填写访客姓名和正确的联系方式!')
}
}
const onClcikSubmit = () =>{
if(isSubmit.value){
if(rulesPhone(form.phone) && rulesPhone(form.visitingTel)){
Toast.loading({ duration: 0, forbidClick: true, message: '提交中', });
postApply(form).then(res =>{
Toast.clear();
isSuccess.value = true
})
}
}else{
Toast.fail('请先填写完整信息后提交!')
}
}
// 上传照片
const onChangeFile = (e) =>{
console.log(e.target.files[0].size)
if(e.target.files[0]){
newcompressImg(e.target.files[0], 0.5).then(res =>{
let formData = new FormData()
// formData.append('file', e.target.files[0])
formData.append('file', res.file)
formData.append('userId', form.phone)
formData.append('name', form.name)
Toast.loading({ duration: 0, forbidClick: true, message: '上传中', });
uploadApi(formData).then(res =>{
Toast.success(res.msg);
form.img = res.data
})
}).catch(err =>{
Toast.fail('图片上传失败,请重新上传')
})
}
}
const onClickCall = () =>{
window.location.href = 'tel:400-040-1573'
}
const newcompressImg = (file, quality) =>{
var qualitys = 0.52
if (parseInt((file.size / 1024).toFixed(2)) < 1024) {
qualitys = 0.85
}
if (5 * 1024 < parseInt((file.size / 1024).toFixed(2))) {
qualitys = 0.92
}
if (quality) {
qualitys = quality
}
if (file[0]) {
return Promise.all(Array.from(file).map(e => this.compressImg(e,
qualitys))) // 如果是 file 数组返回 Promise 数组
} else {
return new Promise((resolve) => {
if ((file.size / 1024).toFixed(2) < 300) {
resolve({
file: file
})
} else {
const reader = new FileReader() // 创建 FileReader
reader.onload = ({
target: {
result: src
}
}) => {
const image = new Image() // 创建 img 元素
image.onload = async() => {
const canvas = document.createElement('canvas') // 创建 canvas 元素
const context = canvas.getContext('2d')
var targetWidth = image.width
var targetHeight = image.height
var originWidth = image.width
var originHeight = image.height
if (1 * 1024 <= parseInt((file.size / 1024).toFixed(2)) && parseInt((file.size / 1024).toFixed(2)) <= 10 * 1024) {
var maxWidth = 1600
var maxHeight = 1600
targetWidth = originWidth
targetHeight = originHeight
// 图片尺寸超过的限制
if (originWidth > maxWidth || originHeight > maxHeight) {
if (originWidth / originHeight > maxWidth / maxHeight) {
// 更宽,按照宽度限定尺寸
targetWidth = maxWidth
targetHeight = Math.round(maxWidth * (originHeight / originWidth))
} else {
targetHeight = maxHeight
targetWidth = Math.round(maxHeight * (originWidth / originHeight))
}
}
}
if (10 * 1024 <= parseInt((file.size / 1024).toFixed(2)) && parseInt((file.size / 1024).toFixed(2)) <= 20 * 1024) {
maxWidth = 1400
maxHeight = 1400
targetWidth = originWidth
targetHeight = originHeight
// 图片尺寸超过的限制
if (originWidth > maxWidth || originHeight > maxHeight) {
if (originWidth / originHeight > maxWidth / maxHeight) {
// 更宽,按照宽度限定尺寸
targetWidth = maxWidth
targetHeight = Math.round(maxWidth * (originHeight / originWidth))
} else {
targetHeight = maxHeight
targetWidth = Math.round(maxHeight * (originWidth / originHeight))
}
}
}
canvas.width = targetWidth
canvas.height = targetHeight
context.clearRect(0, 0, targetWidth, targetHeight)
context.drawImage(image, 0, 0, targetWidth, targetHeight) // 绘制 canvas
const canvasURL = canvas.toDataURL('image/jpeg', qualitys)
const buffer = atob(canvasURL.split(',')[1])
let length = buffer.length
const bufferArray = new Uint8Array(new ArrayBuffer(length))
while (length--) {
bufferArray[length] = buffer.charCodeAt(length)
}
const miniFile = new File([bufferArray], file.name, {
type: 'image/jpeg'
})
resolve({
file: miniFile,
origin: file,
beforeSrc: src,
afterSrc: canvasURL,
beforeKB: Number((file.size / 1024).toFixed(2)),
afterKB: Number((miniFile.size / 1024).toFixed(2))
})
}
image.src = src
}
reader.readAsDataURL(file)
}
})
}
}
/* @setup */
const minDate = ref( formatDate(new Date()))
console.log(route.query.tel)
if(route.query.tel){
form.visitingTel = route.query.tel
onBlurTel(route.query.tel)
}
getVisitor().then( res=>{
visitDict.value = res.data
visitAllDict.value = res.data
})
</script>
<style lang='scss' scoped>
.box{
width: 100%;
height: 100%;
background: #F5F5F5;
padding: 0 0 1.08rem /* 81/75 */;
box-sizing: border-box;
overflow: auto;
.apply-box{
position: relative;
width: 100%;
height: 8.0267rem /* 602/75 */;
background: url('../assets/yuyuebeijing.png') left top/ 100% 100% no-repeat;
padding: 1.04rem /* 78/75 */ 0 0;
box-sizing: border-box;
.text{
width: 3.5467rem /* 266/75 */;
height: 1.1467rem /* 86/75 */;
margin-left: .6133rem /* 46/75 */;
}
p{
line-height: .48rem /* 36/75 */;
font-size: $sm-size;
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 400;
color: #999999;
padding: .1067rem /* 8/75 */ 0 0 .7467rem /* 56/75 */;
}
.apply-content{
width: 9.2rem /* 690/75 */;
height: 4.32rem /* 324/75 */;
background: #FFFFFF;
border-radius: .2667rem /* 20/75 */;
margin: 1.0133rem /* 76/75 */ auto 0;
h3{
padding: .5067rem /* 38/75 */ .3467rem /* 26/75 */ 0 .4533rem /* 34/75 */;
box-sizing: border-box;
display: flex;
align-items: center;
color: #222222;
font-size: $size30;
img{
width: .5867rem /* 44/75 */;
height: .5333rem /* 40/75 */;
margin-right: .16rem /* 12/75 */;
}
span{
span{
font-size: .32rem /* 24/75 */;
color: #666;
}
}
}
.apply-content-form{
width: 100%;
padding: 0 .3467rem /* 26/75 */ 0 .4533rem /* 34/75 */;
box-sizing: border-box;
.search-select-box{
position: relative;
width: 100%;
height: 1.5733rem /* 118/75 */;
// background: #F9F9F9;
// border-radius: .2667rem /* 20/75 */;
padding: 0 .0267rem /* 2/75 */ 0;
box-sizing: border-box;
display: flex;
// margin-bottom: .2667rem /* 20/75 */;
border-bottom: 0.0267rem dashed #D9D9D9;
.label{
flex: 1;
font-size: $size26;
color: #333333;
line-height: 1.5733rem /* 118/75 */;
span{
color: #FF0000;
margin-right: .0267rem /* 2/75 */;
}
}
.search-select-input{
position: relative;
height: 100%;
box-sizing: border-box;
input{
flex: 1;
border: none;
outline: none;
text-align: right;
font-size: $size26;
color: #333333;
// background: #F9F9F9;
padding-right: 0.3733rem;
// line-height: 1.5733rem /* 118/75 */;
box-sizing: border-box;
height: 100%;
}
input::-webkit-input-placeholder {
font-size: $size26;
color: #999999;
}
.select-box{
position: absolute;
right: 0;
top: 1.8667rem /* 140/75 */;
z-index: 5;
width: 3.7333rem /* 280/75 */;
// max-height: 5.0667rem /* 380/75 */;
background: #FFFFFF;
box-shadow: 0px 0px .2667rem /* 20/75 */ .1067rem /* 8/75 */ rgba(0,0,0,0.1);
border-radius: .0533rem /* 4/75 */ ;
// overflow: auto;
.select-sroll-box{
// position: absolute;
// right: 0;
// top: 1.8667rem /* 140/75 */;
// z-index: 5;
width: 100%;
max-height: 5.0667rem /* 380/75 */;
background: #FFFFFF;
// box-shadow: 0px 0px .2667rem /* 20/75 */ .1067rem /* 8/75 */ rgba(0,0,0,0.1);
// border-radius: .0533rem /* 4/75 */ ;
overflow: auto;
}
.select-li{
height: 1.0133rem /* 76/75 */;
background: #fff;
border-radius: .0533rem /* 4/75 */ .0533rem /* 4/75 */ 0px 0px;
font-size: $size26;
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 400;
color: #999999;
line-height: 1.0133rem /* 76/75 */;
text-align: center;
}
.select-active{
color: #30BF78;
background: #F3FEFB;
}
}
b{
position: absolute;
left: 50%;
// top: -100%;
// width: .2rem /* 15/75 */;
// height: 20px;
// background: red;
// display: block;
width: 0;
height: 0;
border: .16rem /* 12/75 */ solid transparent;
border-bottom: .16rem /* 12/75 */ solid #fff;
transform: translateY(-100%) translateX(-50%);
// margin-top: -.6667rem /* 50/75 */;
}
}
}
}
}
.absolute-img{
position: absolute;
top: .5333rem /* 40/75 */;
right: .4rem /* 30/75 */;
width: 4.5067rem /* 338/75 */;
height: 3.7867rem /* 284/75 */;
}
}
.tips{
line-height: .4533rem /* 34/75 */;
font-size: .2933rem /* 22/75 */;
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 400;
color: #999999;
padding: .2133rem /* 16/75 */ 0 .4267rem /* 32/75 */ .8rem /* 60/75 */;
box-sizing: border-box;
}
.visitor-content{
width: 9.2rem /* 690/75 */;
// height: 4.32rem /* 324/75 */;
background: #FFFFFF;
border-radius: .2667rem /* 20/75 */;
margin: 0 auto 0;
h3{
padding: .5067rem /* 38/75 */ .3467rem /* 26/75 */ 0 .4533rem /* 34/75 */;
box-sizing: border-box;
display: flex;
align-items: center;
color: #222222;
font-size: $size30;
img{
width: .5867rem /* 44/75 */;
height: .5333rem /* 40/75 */;
margin-right: .16rem /* 12/75 */;
}
span{
span{
font-size: .32rem /* 24/75 */;
color: #666;
}
}
}
.visitor-content-form{
width: 100%;
padding: 0 .3467rem /* 26/75 */ .16rem /* 12/75 */ .4533rem /* 34/75 */;
box-sizing: border-box;
.upload-box{
width: 100%;
height: 1.9733rem /* 148/75 */;
// padding: 0 .6933rem /* 52/75 */ 0 0;
padding-right: .3733rem /* 28/75 */;
box-sizing: border-box;
display: flex;
justify-content: space-between;
align-items: center;
color: #333333;
font-size: $size26;
label{
line-height: 1.9733rem /* 148/75 */;
span{
color: #FF0000;
}
}
.upload-button{
position: relative;
width: 1.3333rem /* 100/75 */;
height: 1.3333rem /* 100/75 */;
background: #FFFFFF;
border-radius: .1333rem /* 10/75 */;
border: .0267rem /* 2/75 */ dashed #D9D9D9;
display: flex;
align-items: center;
justify-content: center;
// overflow: hidden;
input{
position: absolute;
left: 0;
top: 0;
width: 1.3333rem /* 100/75 */;
height: 1.3333rem /* 100/75 */;
opacity: 0;
}
}
.face-img{
position: relative;
width: 1.3333rem /* 100/75 */;
height: 1.3333rem /* 100/75 */;
background: #FFFFFF;
border-radius: .1333rem /* 10/75 */;
img{
width: 100%;
height: 100%;
border-radius: .1333rem /* 10/75 */;
}
input{
position: absolute;
left: 0;
top: 0;
width: 1.3333rem /* 100/75 */;
height: 1.3333rem /* 100/75 */;
opacity: 0;
}
}
}
}
}
.disclaimer-box{
display: flex;
justify-content: center;
input{
margin-right: .1333rem /* 10/75 */;
}
span{
color: #30BF78;
}
}
.tel-tips{
line-height: .4533rem /* 34/75 */;
font-size: .2933rem /* 22/75 */;
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 400;
color: #999999;
padding: 0 0 .4267rem /* 32/75 */ .8rem /* 60/75 */;
box-sizing: border-box;
margin-top: -.24rem /* 18/75 */;
span{
color: #409eff;
}
}
.submit-button{
display: block;
width: 6.72rem /* 504/75 */;
height: 1.12rem /* 84/75 */;
background: #D9D9D9;
border-radius: 1.3333rem /* 100/75 */ ;
opacity: 1;
font-size: $size30;
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 500;
color: #222222;
border: none;
outline: none;
margin: 1.0133rem /* 76/75 */ auto 0;
}
.active-button{
background-color: #30BF78;
color: #fff;
}
}
.disclaimer-model-fixed{
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: #fff;
display: flex;
flex-direction: column;
padding: .4rem /* 30/75 */;
box-sizing: border-box;
h3{
font-size: .4267rem /* 32/75 */;
line-height: .8rem /* 60/75 */;
text-align: center;
}
.disclaimer-model{
flex: 1;
line-height: .5333rem /* 40/75 */;
text-align: justify;
}
}
</style>
-720
View File
@@ -1,720 +0,0 @@
<template>
<div v-if="true" class='box'>
<div class="apply-box">
<img class="text" src="../assets/zhinengfangke.png" alt="">
<p>来访提前约 拜访开门无需按铃</p>
<div class="apply-content">
<h3>
<img src="../assets/icon-shenfenzheng.png" alt="">
<span>拜访信息<span>(我找谁)</span></span>
</h3>
<div class="apply-content-form">
<!-- <Selectli label="被拜访对象" v-model="form.visitingTel" :columns="visitDict" :isMust="true" :isline="true" name="name" nameId="userId"/> -->
<!-- <div class="search-select-box">
<label class="label"><span>*&nbsp;</span>被拜访人</label>
<div class="search-select-input">
<input @click.stop="onClickVisitor" @input="onInputVisior" :value="visitorName" type="text" placeholder="可填写选择">
<div v-if="isSelect && visitDict.length" class="select-box">
<b></b>
<div class="select-sroll-box">
<div @click.self="onClickSelect(item)" v-for="item in visitDict" :class="item.userId == form.visitingTel ? 'select-active' : ''" class="select-li" :key="item.userId">{{ item.name }}</div>
</div>
</div>
<div v-if="isSelect && !visitDict.length" class="select-box">
<b></b>
<div class="select-li" >查无此人</div>
</div>
</div>
</div> -->
<Inputli v-if="telName" v-model="telName" @input="onInputName" label="被访人" :isMust="true" :isline="true" isMustPosition="left"/>
<Inputli v-else v-model="form.visitingTel" @blur="onBlurTel" @input="onInputTel" label="被访人电话" :isMust="true" :isline="true" isMustPosition="left"/>
<Selectdate v-model="form.hours" label="来访时间" :isMust="true" :isline="false" :minDate="minDate"/>
</div>
</div>
<img class="absolute-img" src="../assets/woyaoyuyue.png" alt="">
</div>
<p class="tips">
说明拜访时间前后一小时都可刷脸通过门禁
</p>
<div class="visitor-content">
<h3>
<img src="../assets/icon-shenfenzheng.png" alt="">
<span>访客信息<span>(我是谁)</span></span>
</h3>
<div class="visitor-content-form">
<Inputli v-model="form.name" label="访客姓名" :isMust="true" :isline="true" isMustPosition="left"/>
<Inputli v-model="form.phone" label="联系方式" :isMust="true" :isline="true" isMustPosition="left"/>
<Inputli v-model="form.visitingNum" label="随行人数" :isMust="true" :isline="true" isMustPosition="left"/>
<Inputli v-model="form.reason" label="来访事由" :isMust="true" :isline="true" isMustPosition="left"/>
<div class="upload-box">
<label for=""><span>*&nbsp;</span>人脸照片</label>
<div v-if="!form.img" class="upload-button">
<img @click="onClickUpload" src="../assets/xiangji.png" alt="">
<input v-if="isDisabled" @change="onChangeFile" type="file" accept="image/*">
</div>
<div v-else class="face-img">
<img :src="form.img" alt="">
<input v-if="true" @change="onChangeFile" type="file" accept="image/*">
</div>
</div>
</div>
</div>
<p class="tips">
说明人脸照片用于通过门禁系统请上传正脸无遮挡照片
</p>
<p class="tel-tips">
如果您在使用中遇到问题请联系<span @click="onClickCall">400040-1573</span>
</p>
<!-- <div class="disclaimer-box">
<input type="checkbox">
<p>勾选表示同意<span>用户协议</span></p>
</div> -->
<button @click="onClcikSubmit" class="submit-button " :class="isSubmit ? 'active-button' : ''">提交</button>
<Successmodel v-if="isSuccess" @click="onClickAffirm" />
<div v-if="false" class="disclaimer-model-fixed">
<h3>用户协议</h3>
<div class="disclaimer-model">
阿哈撒发哈师范哈撒发哈很舒服哈哈
阿哈撒发哈师范哈撒发哈很舒服哈哈
阿哈撒发哈师范哈撒发哈很舒服哈哈
阿哈撒发哈师范哈撒发哈很舒服哈哈
阿哈撒发哈师范哈撒发哈很舒服哈哈
阿哈撒发哈师范哈撒发哈很舒服哈哈
阿哈撒发哈师范哈撒发哈很舒服哈哈
阿哈撒发哈师范哈撒发哈很舒服哈哈
阿哈撒发哈师范哈撒发哈很舒服哈哈
阿哈撒发哈师范哈撒发哈很舒服哈哈
阿哈撒发哈师范哈撒发哈很舒服哈哈
</div>
</div>
</div>
</template>
<script setup>
import { reactive, ref, watch } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { useStore } from 'vuex'
import { Toast, ImagePreview , Uploader, Dialog } from 'vant';
import { rulesForm, resetForm, rulesPhone, rulesFormFBoolean, formatDate } from '@/com/index'
import Inputli from '@/components/input-li.vue'
import Selectli from '@/components/select-li.vue'
import Selectdate from '@/components/select-li-date.vue'
import Successmodel from '../components/success.vue'
import { postApply, getVisitor, getUserNameByTel } from '@/api/user.js'
import { uploadApi } from '@/api/upload'
/* @data */
const router = useRouter()
const route = useRoute()
const store = useStore()
const phoneReg = /(^1\d{10}$)|(^[0-9]\d{7}$)/;
let form = reactive({
name: "",
phone: "",
hours: "",
reason: "",
img: "",
visitingTel: "",
visitingNum: '',
})
const isSubmit = ref(false)
const visitDict = ref([]) // 被访客数据
const visitAllDict = ref([]) // 被访客数据
const isDisabled = ref(false) // 是否能提交
const isSuccess = ref(false) // 是否提交成功
const isSelect = ref( false) // 是否显示下拉选择
const visitorName = ref( '') // 是否显示下拉选择的名字
const telName = ref( '') // 电话查询姓名
/* watch */
watch(() => form, (v1, v2) => {
isSubmit.value = rulesFormFBoolean(v2)
if(v2.name && v2.phone){
if(!phoneReg.test(v2.phone)){
isDisabled.value = false
}else{
isDisabled.value = true
}
}else{
isDisabled.value = false
}
},{ deep: true }
) // 深度监听 ) // 监听单个
/* @method */
const onInputTel = (e) =>{
}
const onInputName = (e) =>{
form.visitingTel = ''
telName.value = ''
}
const onBlurTel = (phone) =>{
console.log(phone)
if(rulesPhone(phone)){
getUserNameByTel(phone).then(res =>{
console.log(res)
if(res.data){
telName.value = res.data
}
}).catch(err =>{
console.log(err)
Dialog.alert({
message: err.msg,
}).then(() => {
// on close
});
})
}
}
// const onBlurVisitor = () =>{
// isSelect.value = false
// let item = visitAllDict.value.find(item =>{ return item.userId == form.visitingTel })
// if(item){
// visitorName.value = item.name
// visitDict.value = visitAllDict.value
// }else{
// visitorName.value = '' // 是否显示下拉选择的名字
// visitDict.value = visitAllDict.value
// }
// }
// 输入框
// const onInputVisior = (e) =>{
// visitorName.value = e.target.value
// let arr = []
// visitAllDict.value.map( item =>{
// if(item.name.search(e.target.value) != -1){
// arr.push(item)
// }
// })
// visitDict.value = [ ...arr ]
// }
// 点击选择了拜访对象
// const onClickSelect = (item) =>{
// form.visitingTel = item.userId
// visitorName.value = item.name
// isSelect.value = false
// }
// const onClickVisitor = () =>{
// isSelect.value = true
// }
// 点击确认模态框
const onClickAffirm = () =>{
router.go(-1)
}
const onClickUpload = () =>{
if(isDisabled.value){
}else{
Toast.fail('请填写访客姓名和正确的联系方式!')
}
}
const onClcikSubmit = () =>{
if(isSubmit.value){
if(rulesPhone(form.phone) && rulesPhone(form.visitingTel)){
Toast.loading({ duration: 0, forbidClick: true, message: '提交中', });
postApply(form).then(res =>{
Toast.clear();
isSuccess.value = true
})
}
}else{
Toast.fail('请先填写完整信息后提交!')
}
}
// 上传照片
const onChangeFile = (e) =>{
console.log(e.target.files[0].size)
if(e.target.files[0]){
newcompressImg(e.target.files[0], 0.5).then(res =>{
let formData = new FormData()
// formData.append('file', e.target.files[0])
formData.append('file', res.file)
formData.append('userId', form.phone)
formData.append('name', form.name)
Toast.loading({ duration: 0, forbidClick: true, message: '上传中', });
uploadApi(formData).then(res =>{
Toast.success(res.msg);
form.img = res.data
})
}).catch(err =>{
Toast.fail('图片上传失败,请重新上传')
})
}
}
const onClickCall = () =>{
window.location.href = 'tel:400-040-1573'
}
const newcompressImg = (file, quality) =>{
var qualitys = 0.52
if (parseInt((file.size / 1024).toFixed(2)) < 1024) {
qualitys = 0.85
}
if (5 * 1024 < parseInt((file.size / 1024).toFixed(2))) {
qualitys = 0.92
}
if (quality) {
qualitys = quality
}
if (file[0]) {
return Promise.all(Array.from(file).map(e => this.compressImg(e,
qualitys))) // 如果是 file 数组返回 Promise 数组
} else {
return new Promise((resolve) => {
if ((file.size / 1024).toFixed(2) < 300) {
resolve({
file: file
})
} else {
const reader = new FileReader() // 创建 FileReader
reader.onload = ({
target: {
result: src
}
}) => {
const image = new Image() // 创建 img 元素
image.onload = async() => {
const canvas = document.createElement('canvas') // 创建 canvas 元素
const context = canvas.getContext('2d')
var targetWidth = image.width
var targetHeight = image.height
var originWidth = image.width
var originHeight = image.height
if (1 * 1024 <= parseInt((file.size / 1024).toFixed(2)) && parseInt((file.size / 1024).toFixed(2)) <= 10 * 1024) {
var maxWidth = 1600
var maxHeight = 1600
targetWidth = originWidth
targetHeight = originHeight
// 图片尺寸超过的限制
if (originWidth > maxWidth || originHeight > maxHeight) {
if (originWidth / originHeight > maxWidth / maxHeight) {
// 更宽,按照宽度限定尺寸
targetWidth = maxWidth
targetHeight = Math.round(maxWidth * (originHeight / originWidth))
} else {
targetHeight = maxHeight
targetWidth = Math.round(maxHeight * (originWidth / originHeight))
}
}
}
if (10 * 1024 <= parseInt((file.size / 1024).toFixed(2)) && parseInt((file.size / 1024).toFixed(2)) <= 20 * 1024) {
maxWidth = 1400
maxHeight = 1400
targetWidth = originWidth
targetHeight = originHeight
// 图片尺寸超过的限制
if (originWidth > maxWidth || originHeight > maxHeight) {
if (originWidth / originHeight > maxWidth / maxHeight) {
// 更宽,按照宽度限定尺寸
targetWidth = maxWidth
targetHeight = Math.round(maxWidth * (originHeight / originWidth))
} else {
targetHeight = maxHeight
targetWidth = Math.round(maxHeight * (originWidth / originHeight))
}
}
}
canvas.width = targetWidth
canvas.height = targetHeight
context.clearRect(0, 0, targetWidth, targetHeight)
context.drawImage(image, 0, 0, targetWidth, targetHeight) // 绘制 canvas
const canvasURL = canvas.toDataURL('image/jpeg', qualitys)
const buffer = atob(canvasURL.split(',')[1])
let length = buffer.length
const bufferArray = new Uint8Array(new ArrayBuffer(length))
while (length--) {
bufferArray[length] = buffer.charCodeAt(length)
}
const miniFile = new File([bufferArray], file.name, {
type: 'image/jpeg'
})
resolve({
file: miniFile,
origin: file,
beforeSrc: src,
afterSrc: canvasURL,
beforeKB: Number((file.size / 1024).toFixed(2)),
afterKB: Number((miniFile.size / 1024).toFixed(2))
})
}
image.src = src
}
reader.readAsDataURL(file)
}
})
}
}
/* @setup */
const minDate = ref( formatDate(new Date()))
console.log(route.query.tel)
if(route.query.tel){
form.visitingTel = route.query.tel
onBlurTel(route.query.tel)
}
getVisitor().then( res=>{
visitDict.value = res.data
visitAllDict.value = res.data
})
</script>
<style lang='scss' scoped>
.box{
width: 100%;
height: 100%;
background: #F5F5F5;
padding: 0 0 1.08rem /* 81/75 */;
box-sizing: border-box;
overflow: auto;
.apply-box{
position: relative;
width: 100%;
height: 8.0267rem /* 602/75 */;
background: url('../assets/yuyuebeijing.png') left top/ 100% 100% no-repeat;
padding: 1.04rem /* 78/75 */ 0 0;
box-sizing: border-box;
.text{
width: 3.5467rem /* 266/75 */;
height: 1.1467rem /* 86/75 */;
margin-left: .6133rem /* 46/75 */;
}
p{
line-height: .48rem /* 36/75 */;
font-size: $sm-size;
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 400;
color: #999999;
padding: .1067rem /* 8/75 */ 0 0 .7467rem /* 56/75 */;
}
.apply-content{
width: 9.2rem /* 690/75 */;
height: 4.32rem /* 324/75 */;
background: #FFFFFF;
border-radius: .2667rem /* 20/75 */;
margin: 1.0133rem /* 76/75 */ auto 0;
h3{
padding: .5067rem /* 38/75 */ .3467rem /* 26/75 */ 0 .4533rem /* 34/75 */;
box-sizing: border-box;
display: flex;
align-items: center;
color: #222222;
font-size: $size30;
img{
width: .5867rem /* 44/75 */;
height: .5333rem /* 40/75 */;
margin-right: .16rem /* 12/75 */;
}
span{
span{
font-size: .32rem /* 24/75 */;
color: #666;
}
}
}
.apply-content-form{
width: 100%;
padding: 0 .3467rem /* 26/75 */ 0 .4533rem /* 34/75 */;
box-sizing: border-box;
.search-select-box{
position: relative;
width: 100%;
height: 1.5733rem /* 118/75 */;
// background: #F9F9F9;
// border-radius: .2667rem /* 20/75 */;
padding: 0 .0267rem /* 2/75 */ 0;
box-sizing: border-box;
display: flex;
// margin-bottom: .2667rem /* 20/75 */;
border-bottom: 0.0267rem dashed #D9D9D9;
.label{
flex: 1;
font-size: $size26;
color: #333333;
line-height: 1.5733rem /* 118/75 */;
span{
color: #FF0000;
margin-right: .0267rem /* 2/75 */;
}
}
.search-select-input{
position: relative;
height: 100%;
box-sizing: border-box;
input{
flex: 1;
border: none;
outline: none;
text-align: right;
font-size: $size26;
color: #333333;
// background: #F9F9F9;
padding-right: 0.3733rem;
// line-height: 1.5733rem /* 118/75 */;
box-sizing: border-box;
height: 100%;
}
input::-webkit-input-placeholder {
font-size: $size26;
color: #999999;
}
.select-box{
position: absolute;
right: 0;
top: 1.8667rem /* 140/75 */;
z-index: 5;
width: 3.7333rem /* 280/75 */;
// max-height: 5.0667rem /* 380/75 */;
background: #FFFFFF;
box-shadow: 0px 0px .2667rem /* 20/75 */ .1067rem /* 8/75 */ rgba(0,0,0,0.1);
border-radius: .0533rem /* 4/75 */ ;
// overflow: auto;
.select-sroll-box{
// position: absolute;
// right: 0;
// top: 1.8667rem /* 140/75 */;
// z-index: 5;
width: 100%;
max-height: 5.0667rem /* 380/75 */;
background: #FFFFFF;
// box-shadow: 0px 0px .2667rem /* 20/75 */ .1067rem /* 8/75 */ rgba(0,0,0,0.1);
// border-radius: .0533rem /* 4/75 */ ;
overflow: auto;
}
.select-li{
height: 1.0133rem /* 76/75 */;
background: #fff;
border-radius: .0533rem /* 4/75 */ .0533rem /* 4/75 */ 0px 0px;
font-size: $size26;
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 400;
color: #999999;
line-height: 1.0133rem /* 76/75 */;
text-align: center;
}
.select-active{
color: #30BF78;
background: #F3FEFB;
}
}
b{
position: absolute;
left: 50%;
// top: -100%;
// width: .2rem /* 15/75 */;
// height: 20px;
// background: red;
// display: block;
width: 0;
height: 0;
border: .16rem /* 12/75 */ solid transparent;
border-bottom: .16rem /* 12/75 */ solid #fff;
transform: translateY(-100%) translateX(-50%);
// margin-top: -.6667rem /* 50/75 */;
}
}
}
}
}
.absolute-img{
position: absolute;
top: .5333rem /* 40/75 */;
right: .4rem /* 30/75 */;
width: 4.5067rem /* 338/75 */;
height: 3.7867rem /* 284/75 */;
}
}
.tips{
line-height: .4533rem /* 34/75 */;
font-size: .2933rem /* 22/75 */;
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 400;
color: #999999;
padding: .2133rem /* 16/75 */ 0 .4267rem /* 32/75 */ .8rem /* 60/75 */;
box-sizing: border-box;
}
.visitor-content{
width: 9.2rem /* 690/75 */;
// height: 4.32rem /* 324/75 */;
background: #FFFFFF;
border-radius: .2667rem /* 20/75 */;
margin: 0 auto 0;
h3{
padding: .5067rem /* 38/75 */ .3467rem /* 26/75 */ 0 .4533rem /* 34/75 */;
box-sizing: border-box;
display: flex;
align-items: center;
color: #222222;
font-size: $size30;
img{
width: .5867rem /* 44/75 */;
height: .5333rem /* 40/75 */;
margin-right: .16rem /* 12/75 */;
}
span{
span{
font-size: .32rem /* 24/75 */;
color: #666;
}
}
}
.visitor-content-form{
width: 100%;
padding: 0 .3467rem /* 26/75 */ .16rem /* 12/75 */ .4533rem /* 34/75 */;
box-sizing: border-box;
.upload-box{
width: 100%;
height: 1.9733rem /* 148/75 */;
// padding: 0 .6933rem /* 52/75 */ 0 0;
padding-right: .3733rem /* 28/75 */;
box-sizing: border-box;
display: flex;
justify-content: space-between;
align-items: center;
color: #333333;
font-size: $size26;
label{
line-height: 1.9733rem /* 148/75 */;
span{
color: #FF0000;
}
}
.upload-button{
position: relative;
width: 1.3333rem /* 100/75 */;
height: 1.3333rem /* 100/75 */;
background: #FFFFFF;
border-radius: .1333rem /* 10/75 */;
border: .0267rem /* 2/75 */ dashed #D9D9D9;
display: flex;
align-items: center;
justify-content: center;
// overflow: hidden;
input{
position: absolute;
left: 0;
top: 0;
width: 1.3333rem /* 100/75 */;
height: 1.3333rem /* 100/75 */;
opacity: 0;
}
}
.face-img{
position: relative;
width: 1.3333rem /* 100/75 */;
height: 1.3333rem /* 100/75 */;
background: #FFFFFF;
border-radius: .1333rem /* 10/75 */;
img{
width: 100%;
height: 100%;
border-radius: .1333rem /* 10/75 */;
}
input{
position: absolute;
left: 0;
top: 0;
width: 1.3333rem /* 100/75 */;
height: 1.3333rem /* 100/75 */;
opacity: 0;
}
}
}
}
}
.disclaimer-box{
display: flex;
justify-content: center;
input{
margin-right: .1333rem /* 10/75 */;
}
span{
color: #30BF78;
}
}
.tel-tips{
line-height: .4533rem /* 34/75 */;
font-size: .2933rem /* 22/75 */;
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 400;
color: #999999;
padding: 0 0 .4267rem /* 32/75 */ .8rem /* 60/75 */;
box-sizing: border-box;
margin-top: -.24rem /* 18/75 */;
span{
color: #409eff;
}
}
.submit-button{
display: block;
width: 6.72rem /* 504/75 */;
height: 1.12rem /* 84/75 */;
background: #D9D9D9;
border-radius: 1.3333rem /* 100/75 */ ;
opacity: 1;
font-size: $size30;
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 500;
color: #222222;
border: none;
outline: none;
margin: 1.0133rem /* 76/75 */ auto 0;
}
.active-button{
background-color: #30BF78;
color: #fff;
}
}
.disclaimer-model-fixed{
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: #fff;
display: flex;
flex-direction: column;
padding: .4rem /* 30/75 */;
box-sizing: border-box;
h3{
font-size: .4267rem /* 32/75 */;
line-height: .8rem /* 60/75 */;
text-align: center;
}
.disclaimer-model{
flex: 1;
line-height: .5333rem /* 40/75 */;
text-align: justify;
}
}
</style>
+15 -71
View File
@@ -9,26 +9,6 @@
<span>拜访信息<span>(我找谁)</span></span>
</h3>
<div class="apply-content-form">
<!-- <Selectli label="被拜访对象" v-model="form.visitingTel" :columns="visitDict" :isMust="true" :isline="true" name="name" nameId="userId"/> -->
<!-- <div class="search-select-box">
<label class="label"><span>*&nbsp;</span>被拜访人</label>
<div class="search-select-input">
<input @click.stop="onClickVisitor" @input="onInputVisior" :value="visitorName" type="text" placeholder="可填写选择">
<div v-if="isSelect && visitDict.length" class="select-box">
<b></b>
<div class="select-sroll-box">
<div @click.self="onClickSelect(item)" v-for="item in visitDict" :class="item.userId == form.visitingTel ? 'select-active' : ''" class="select-li" :key="item.userId">{{ item.name }}</div>
</div>
</div>
<div v-if="isSelect && !visitDict.length" class="select-box">
<b></b>
<div class="select-li" >查无此人</div>
</div>
</div>
</div> -->
<Inputli v-if="telName" v-model="telName" @input="onInputName" label="被访人" :isMust="true" :isline="true" isMustPosition="left"/>
<Inputli v-else v-model="form.visitingTel" @blur="onBlurTel" @input="onInputTel" label="被访人电话" :isMust="true" :isline="true" isMustPosition="left"/>
<Selectdate v-model="form.hours" label="来访时间" :isMust="true" :isline="false" :minDate="minDate"/>
@@ -123,8 +103,6 @@ import { uploadGuestFaceApi } from '@/api/upload'
visitingNum: '',
})
const isSubmit = ref(false)
const visitDict = ref([]) // 被访客数据
const visitAllDict = ref([]) // 被访客数据
const isDisabled = ref(false) // 是否能提交
const isSuccess = ref(false) // 是否提交成功
const isSelect = ref( false) // 是否显示下拉选择
@@ -156,58 +134,28 @@ import { uploadGuestFaceApi } from '@/api/upload'
}
const onBlurTel = (phone) =>{
console.log(phone)
if(rulesPhone(phone)){
getUserNameByTel(phone).then(res =>{
console.log(res)
if(res.data){
telName.value = res.data
if (rulesPhone(phone)) {
getUserNameByTel(phone).then(res => {
if (res.data) {
telName.value = res.data;
} else {
Toast.fail('未找到该手机号对应的被访人');
telName.value = '';
}
}).catch(err =>{
}).catch(err => {
Toast.clear();
console.log(err)
console.log(err);
Dialog.alert({
message: err.msg,
}).then(() => {
// on close
message: err.msg || '查询失败',
});
})
telName.value = '';
});
} else {
Toast.fail('请输入正确的手机号');
telName.value = '';
}
}
// const onBlurVisitor = () =>{
// isSelect.value = false
// let item = visitAllDict.value.find(item =>{ return item.userId == form.visitingTel })
// if(item){
// visitorName.value = item.name
// visitDict.value = visitAllDict.value
// }else{
// visitorName.value = '' // 是否显示下拉选择的名字
// visitDict.value = visitAllDict.value
// }
// }
// 输入框
// const onInputVisior = (e) =>{
// visitorName.value = e.target.value
// let arr = []
// visitAllDict.value.map( item =>{
// if(item.name.search(e.target.value) != -1){
// arr.push(item)
// }
// })
// visitDict.value = [ ...arr ]
// }
// 点击选择了拜访对象
// const onClickSelect = (item) =>{
// form.visitingTel = item.userId
// visitorName.value = item.name
// isSelect.value = false
// }
// const onClickVisitor = () =>{
// isSelect.value = true
// }
// 点击确认模态框
const onClickAffirm = () =>{
router.go(-1)
@@ -365,10 +313,6 @@ import { uploadGuestFaceApi } from '@/api/upload'
form.visitingTel = route.query.tel
onBlurTel(route.query.tel)
}
getVisitor().then( res=>{
visitDict.value = res.data
visitAllDict.value = res.data
})
</script>
-786
View File
@@ -1,786 +0,0 @@
<template>
<div v-if="true" class='box'>
<div class="apply-box">
<img class="text" src="../assets/zhinengfangke.png" alt="">
<p>来访提前约 拜访开门无需按铃</p>
<img class="absolute-img" src="../assets/woyaoyuyue.png" alt="">
<div class="apply-content">
<h3>
<img src="../assets/icon-shenfenzheng.png" alt="">
<span>拜访信息<span>(我找谁)</span></span>
</h3>
<div class="apply-content-form">
<Inputli v-model="form.name" label="访客姓名" :isMust="true" :isline="true" isMustPosition="left"/>
<Inputli v-model="form.phone" label="联系方式" :isMust="true" :isline="true" isMustPosition="left"/>
<Inputli v-model="form.visitingNum" label="随行人数" :isMust="true" :isline="true" isMustPosition="left"/>
<Inputli v-model="form.reason" label="来访事由" :isMust="true" :isline="true" isMustPosition="left"/>
<div class="upload-box">
<label for=""><span>*&nbsp;</span>人脸照片</label>
<div v-if="!form.img" class="upload-button">
<img @click="onClickUpload" src="../assets/xiangji.png" alt="">
<input v-if="isDisabled" @change="onChangeFile" type="file" accept="image/*">
</div>
<div v-else class="face-img">
<img :src="form.img" alt="">
<input v-if="true" @change="onChangeFile" type="file" accept="image/*">
</div>
</div>
</div>
</div>
</div>
<p class="tips">
说明人脸照片用于通过门禁系统请上传正脸无遮挡照片
</p>
<p class="tel-tips">
如果您在使用中遇到问题请联系<span @click="onClickCall">400040-1573</span>
</p>
<div class="visitor-content">
<h3>
<img src="../assets/icon-shenfenzheng.png" alt="">
<span>访客信息<span>(我是谁)</span></span>
</h3>
<div class="visitor-content-form">
<Inputli v-if="telName" v-model="telName" @input="onInputName" label="被访人" :isMust="true" :isline="true" isMustPosition="left"/>
<Inputli v-else v-model="form.visitingTel" @blur="onBlurTel" @input="onInputTel" label="被访人电话" :isMust="true" :isline="true" isMustPosition="left"/>
<Selectdate v-model="form.hours" label="来访时间" :isMust="true" :isline="false" :minDate="minDate"/>
</div>
</div>
<p class="tips" style="margin-top: .2rem /* 15/75 */">
说明拜访时间前后一小时都可刷脸通过门禁
</p>
<!-- <p class="tips">
说明拜访时间前后一小时都可刷脸通过门禁
</p>
<div v-if="false" class="visitor-content">
<h3>
<img src="../assets/icon-shenfenzheng.png" alt="">
<span>访客信息<span>(我是谁)</span></span>
</h3>
<div class="visitor-content-form">
<Inputli v-if="telName" v-model="telName" @input="onInputName" label="被访人" :isMust="true" :isline="true" isMustPosition="left"/>
<Inputli v-else v-model="form.visitingTel" @blur="onBlurTel" @input="onInputTel" label="被访人电话" :isMust="true" :isline="true" isMustPosition="left"/>
<Selectdate v-model="form.hours" label="来访时间" :isMust="true" :isline="false" :minDate="minDate"/>
</div>
</div>
<p class="tips">
说明人脸照片用于通过门禁系统请上传正脸无遮挡照片
</p>
<p class="tel-tips">
如果您在使用中遇到问题请联系<span @click="onClickCall">400040-1573</span>
</p> -->
<!-- <div class="disclaimer-box">
<input type="checkbox">
<p>勾选表示同意<span>用户协议</span></p>
</div> -->
<button @click="onClcikSubmit" class="submit-button " :class="isSubmit ? 'active-button' : ''">提交</button>
<Successmodel v-if="isSuccess" @click="onClickAffirm" />
<div v-if="false" class="disclaimer-model-fixed">
<h3>用户协议</h3>
<div class="disclaimer-model">
阿哈撒发哈师范哈撒发哈很舒服哈哈
阿哈撒发哈师范哈撒发哈很舒服哈哈
阿哈撒发哈师范哈撒发哈很舒服哈哈
阿哈撒发哈师范哈撒发哈很舒服哈哈
阿哈撒发哈师范哈撒发哈很舒服哈哈
阿哈撒发哈师范哈撒发哈很舒服哈哈
阿哈撒发哈师范哈撒发哈很舒服哈哈
阿哈撒发哈师范哈撒发哈很舒服哈哈
阿哈撒发哈师范哈撒发哈很舒服哈哈
阿哈撒发哈师范哈撒发哈很舒服哈哈
阿哈撒发哈师范哈撒发哈很舒服哈哈
</div>
</div>
</div>
</template>
<script setup>
import { reactive, ref, watch } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { useStore } from 'vuex'
import { Toast, ImagePreview , Uploader, Dialog } from 'vant';
import { rulesForm, resetForm, rulesPhone, rulesFormFBoolean, formatDate } from '@/com/index'
import Inputli from '@/components/input-li.vue'
import Selectli from '@/components/select-li.vue'
import Selectdate from '@/components/select-li-date.vue'
import Successmodel from '../components/success.vue'
import { postApply, getVisitor, getUserNameByTel } from '@/api/user.js'
import { uploadApi } from '@/api/upload'
/* @data */
const router = useRouter()
const route = useRoute()
const store = useStore()
const phoneReg = /(^1\d{10}$)|(^[0-9]\d{7}$)/;
let form = reactive({
name: "",
phone: "",
hours: "",
reason: "",
img: "",
visitingTel: "",
visitingNum: '',
})
const isSubmit = ref(false)
const visitDict = ref([]) // 被访客数据
const visitAllDict = ref([]) // 被访客数据
const isDisabled = ref(false) // 是否能提交
const isSuccess = ref(false) // 是否提交成功
const isSelect = ref( false) // 是否显示下拉选择
const visitorName = ref( '') // 是否显示下拉选择的名字
const telName = ref( '') // 电话查询姓名
/* watch */
watch(() => form, (v1, v2) => {
isSubmit.value = rulesFormFBoolean(v2)
if(v2.name && v2.phone){
if(!phoneReg.test(v2.phone)){
isDisabled.value = false
}else{
isDisabled.value = true
}
}else{
isDisabled.value = false
}
},{ deep: true }
) // 深度监听 ) // 监听单个
/* @method */
const onInputTel = (e) =>{
}
const onInputName = (e) =>{
form.visitingTel = ''
telName.value = ''
}
const onBlurTel = (phone) =>{
console.log(phone)
if(rulesPhone(phone)){
getUserNameByTel(phone).then(res =>{
console.log(res)
if(res.data){
telName.value = res.data
}
}).catch(err =>{
console.log(err)
Dialog.alert({
message: err.msg,
}).then(() => {
// on close
});
})
}
}
// const onBlurVisitor = () =>{
// isSelect.value = false
// let item = visitAllDict.value.find(item =>{ return item.userId == form.visitingTel })
// if(item){
// visitorName.value = item.name
// visitDict.value = visitAllDict.value
// }else{
// visitorName.value = '' // 是否显示下拉选择的名字
// visitDict.value = visitAllDict.value
// }
// }
// 输入框
// const onInputVisior = (e) =>{
// visitorName.value = e.target.value
// let arr = []
// visitAllDict.value.map( item =>{
// if(item.name.search(e.target.value) != -1){
// arr.push(item)
// }
// })
// visitDict.value = [ ...arr ]
// }
// 点击选择了拜访对象
// const onClickSelect = (item) =>{
// form.visitingTel = item.userId
// visitorName.value = item.name
// isSelect.value = false
// }
// const onClickVisitor = () =>{
// isSelect.value = true
// }
// 点击确认模态框
const onClickAffirm = () =>{
router.go(-1)
}
const onClickUpload = () =>{
if(isDisabled.value){
}else{
Toast.fail('请填写访客姓名和正确的联系方式!')
}
}
const onClcikSubmit = () =>{
if(isSubmit.value){
if(rulesPhone(form.phone) && rulesPhone(form.visitingTel)){
Toast.loading({ duration: 0, forbidClick: true, message: '提交中', });
postApply(form).then(res =>{
Toast.clear();
isSuccess.value = true
})
}
}else{
Toast.fail('请先填写完整信息后提交!')
}
}
// 上传照片
const onChangeFile = (e) =>{
console.log(e.target.files[0].size)
if(e.target.files[0]){
newcompressImg(e.target.files[0], 0.5).then(res =>{
let formData = new FormData()
// formData.append('file', e.target.files[0])
formData.append('file', res.file)
formData.append('userId', form.phone)
formData.append('name', form.name)
Toast.loading({ duration: 0, forbidClick: true, message: '上传中', });
uploadApi(formData).then(res =>{
Toast.success(res.msg);
form.img = res.data
})
}).catch(err =>{
Toast.fail('图片上传失败,请重新上传')
})
}
}
const onClickCall = () =>{
window.location.href = 'tel:400-040-1573'
}
const newcompressImg = (file, quality) =>{
var qualitys = 0.52
if (parseInt((file.size / 1024).toFixed(2)) < 1024) {
qualitys = 0.85
}
if (5 * 1024 < parseInt((file.size / 1024).toFixed(2))) {
qualitys = 0.92
}
if (quality) {
qualitys = quality
}
if (file[0]) {
return Promise.all(Array.from(file).map(e => this.compressImg(e,
qualitys))) // 如果是 file 数组返回 Promise 数组
} else {
return new Promise((resolve) => {
if ((file.size / 1024).toFixed(2) < 300) {
resolve({
file: file
})
} else {
const reader = new FileReader() // 创建 FileReader
reader.onload = ({
target: {
result: src
}
}) => {
const image = new Image() // 创建 img 元素
image.onload = async() => {
const canvas = document.createElement('canvas') // 创建 canvas 元素
const context = canvas.getContext('2d')
var targetWidth = image.width
var targetHeight = image.height
var originWidth = image.width
var originHeight = image.height
if (1 * 1024 <= parseInt((file.size / 1024).toFixed(2)) && parseInt((file.size / 1024).toFixed(2)) <= 10 * 1024) {
var maxWidth = 1600
var maxHeight = 1600
targetWidth = originWidth
targetHeight = originHeight
// 图片尺寸超过的限制
if (originWidth > maxWidth || originHeight > maxHeight) {
if (originWidth / originHeight > maxWidth / maxHeight) {
// 更宽,按照宽度限定尺寸
targetWidth = maxWidth
targetHeight = Math.round(maxWidth * (originHeight / originWidth))
} else {
targetHeight = maxHeight
targetWidth = Math.round(maxHeight * (originWidth / originHeight))
}
}
}
if (10 * 1024 <= parseInt((file.size / 1024).toFixed(2)) && parseInt((file.size / 1024).toFixed(2)) <= 20 * 1024) {
maxWidth = 1400
maxHeight = 1400
targetWidth = originWidth
targetHeight = originHeight
// 图片尺寸超过的限制
if (originWidth > maxWidth || originHeight > maxHeight) {
if (originWidth / originHeight > maxWidth / maxHeight) {
// 更宽,按照宽度限定尺寸
targetWidth = maxWidth
targetHeight = Math.round(maxWidth * (originHeight / originWidth))
} else {
targetHeight = maxHeight
targetWidth = Math.round(maxHeight * (originWidth / originHeight))
}
}
}
canvas.width = targetWidth
canvas.height = targetHeight
context.clearRect(0, 0, targetWidth, targetHeight)
context.drawImage(image, 0, 0, targetWidth, targetHeight) // 绘制 canvas
const canvasURL = canvas.toDataURL('image/jpeg', qualitys)
const buffer = atob(canvasURL.split(',')[1])
let length = buffer.length
const bufferArray = new Uint8Array(new ArrayBuffer(length))
while (length--) {
bufferArray[length] = buffer.charCodeAt(length)
}
const miniFile = new File([bufferArray], file.name, {
type: 'image/jpeg'
})
resolve({
file: miniFile,
origin: file,
beforeSrc: src,
afterSrc: canvasURL,
beforeKB: Number((file.size / 1024).toFixed(2)),
afterKB: Number((miniFile.size / 1024).toFixed(2))
})
}
image.src = src
}
reader.readAsDataURL(file)
}
})
}
}
/* @setup */
const minDate = ref( formatDate(new Date()))
console.log(route.query.tel)
if(route.query.tel){
form.visitingTel = route.query.tel
onBlurTel(route.query.tel)
}
getVisitor().then( res=>{
visitDict.value = res.data
visitAllDict.value = res.data
})
</script>
<style lang='scss' scoped>
.box{
width: 100%;
height: 100%;
background: #F5F5F5;
padding: 0 0 1.08rem /* 81/75 */;
box-sizing: border-box;
overflow: auto;
.apply-box{
position: relative;
width: 100%;
height: 8.0267rem /* 602/75 */;
background: url('../assets/yuyuebeijing.png') left top/ 100% 100% no-repeat;
padding: 1.04rem /* 78/75 */ 0 0;
box-sizing: border-box;
.text{
width: 3.5467rem /* 266/75 */;
height: 1.1467rem /* 86/75 */;
margin-left: .6133rem /* 46/75 */;
}
p{
line-height: .48rem /* 36/75 */;
font-size: $sm-size;
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 400;
color: #999999;
padding: .1067rem /* 8/75 */ 0 0 .7467rem /* 56/75 */;
}
.apply-content{
width: 9.2rem /* 690/75 */;
// height: 4.32rem /* 324/75 */;
background: #FFFFFF;
border-radius: .2667rem /* 20/75 */;
margin: 1.0133rem /* 76/75 */ auto 0;
h3{
padding: .5067rem /* 38/75 */ .3467rem /* 26/75 */ 0 .4533rem /* 34/75 */;
box-sizing: border-box;
display: flex;
align-items: center;
color: #222222;
font-size: $size30;
img{
width: .5867rem /* 44/75 */;
height: .5333rem /* 40/75 */;
margin-right: .16rem /* 12/75 */;
}
span{
span{
font-size: .32rem /* 24/75 */;
color: #666;
}
}
}
.apply-content-form{
width: 100%;
padding: 0 .3467rem /* 26/75 */ 0 .4533rem /* 34/75 */;
box-sizing: border-box;
.search-select-box{
position: relative;
width: 100%;
height: 1.5733rem /* 118/75 */;
// background: #F9F9F9;
// border-radius: .2667rem /* 20/75 */;
padding: 0 .0267rem /* 2/75 */ 0;
box-sizing: border-box;
display: flex;
// margin-bottom: .2667rem /* 20/75 */;
border-bottom: 0.0267rem dashed #D9D9D9;
.label{
flex: 1;
font-size: $size26;
color: #333333;
line-height: 1.5733rem /* 118/75 */;
span{
color: #FF0000;
margin-right: .0267rem /* 2/75 */;
}
}
.search-select-input{
position: relative;
height: 100%;
box-sizing: border-box;
input{
flex: 1;
border: none;
outline: none;
text-align: right;
font-size: $size26;
color: #333333;
// background: #F9F9F9;
padding-right: 0.3733rem;
// line-height: 1.5733rem /* 118/75 */;
box-sizing: border-box;
height: 100%;
}
input::-webkit-input-placeholder {
font-size: $size26;
color: #999999;
}
.select-box{
position: absolute;
right: 0;
top: 1.8667rem /* 140/75 */;
z-index: 5;
width: 3.7333rem /* 280/75 */;
// max-height: 5.0667rem /* 380/75 */;
background: #FFFFFF;
box-shadow: 0px 0px .2667rem /* 20/75 */ .1067rem /* 8/75 */ rgba(0,0,0,0.1);
border-radius: .0533rem /* 4/75 */ ;
// overflow: auto;
.select-sroll-box{
// position: absolute;
// right: 0;
// top: 1.8667rem /* 140/75 */;
// z-index: 5;
width: 100%;
max-height: 5.0667rem /* 380/75 */;
background: #FFFFFF;
// box-shadow: 0px 0px .2667rem /* 20/75 */ .1067rem /* 8/75 */ rgba(0,0,0,0.1);
// border-radius: .0533rem /* 4/75 */ ;
overflow: auto;
}
.select-li{
height: 1.0133rem /* 76/75 */;
background: #fff;
border-radius: .0533rem /* 4/75 */ .0533rem /* 4/75 */ 0px 0px;
font-size: $size26;
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 400;
color: #999999;
line-height: 1.0133rem /* 76/75 */;
text-align: center;
}
.select-active{
color: #30BF78;
background: #F3FEFB;
}
}
b{
position: absolute;
left: 50%;
// top: -100%;
// width: .2rem /* 15/75 */;
// height: 20px;
// background: red;
// display: block;
width: 0;
height: 0;
border: .16rem /* 12/75 */ solid transparent;
border-bottom: .16rem /* 12/75 */ solid #fff;
transform: translateY(-100%) translateX(-50%);
// margin-top: -.6667rem /* 50/75 */;
}
}
}
.upload-box{
width: 100%;
height: 1.9733rem /* 148/75 */;
// padding: 0 .6933rem /* 52/75 */ 0 0;
padding-right: .3733rem /* 28/75 */;
box-sizing: border-box;
display: flex;
justify-content: space-between;
align-items: center;
color: #333333;
font-size: $size26;
label{
line-height: 1.9733rem /* 148/75 */;
span{
color: #FF0000;
}
}
.upload-button{
position: relative;
width: 1.3333rem /* 100/75 */;
height: 1.3333rem /* 100/75 */;
background: #FFFFFF;
border-radius: .1333rem /* 10/75 */;
border: .0267rem /* 2/75 */ dashed #D9D9D9;
display: flex;
align-items: center;
justify-content: center;
// overflow: hidden;
input{
position: absolute;
left: 0;
top: 0;
width: 1.3333rem /* 100/75 */;
height: 1.3333rem /* 100/75 */;
opacity: 0;
}
}
.face-img{
position: relative;
width: 1.3333rem /* 100/75 */;
height: 1.3333rem /* 100/75 */;
background: #FFFFFF;
border-radius: .1333rem /* 10/75 */;
img{
width: 100%;
height: 100%;
border-radius: .1333rem /* 10/75 */;
}
input{
position: absolute;
left: 0;
top: 0;
width: 1.3333rem /* 100/75 */;
height: 1.3333rem /* 100/75 */;
opacity: 0;
}
}
}
}
}
.absolute-img{
position: absolute;
top: .5333rem /* 40/75 */;
right: .4rem /* 30/75 */;
width: 4.5067rem /* 338/75 */;
height: 3.7867rem /* 284/75 */;
}
}
.tips{
line-height: .4533rem /* 34/75 */;
font-size: .2933rem /* 22/75 */;
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 400;
color: #999999;
padding: .2133rem /* 16/75 */ 0 .4267rem /* 32/75 */ .8rem /* 60/75 */;
box-sizing: border-box;
margin-top: 5.3333rem /* 400/75 */;
}
.visitor-content{
width: 9.2rem /* 690/75 */;
// height: 4.32rem /* 324/75 */;
background: #FFFFFF;
border-radius: .2667rem /* 20/75 */;
margin: 0 auto 0;
// margin-top: 5.3333rem /* 400/75 */;
h3{
padding: .5067rem /* 38/75 */ .3467rem /* 26/75 */ 0 .4533rem /* 34/75 */;
box-sizing: border-box;
display: flex;
align-items: center;
color: #222222;
font-size: $size30;
img{
width: .5867rem /* 44/75 */;
height: .5333rem /* 40/75 */;
margin-right: .16rem /* 12/75 */;
}
span{
span{
font-size: .32rem /* 24/75 */;
color: #666;
}
}
}
.visitor-content-form{
width: 100%;
padding: 0 .3467rem /* 26/75 */ .16rem /* 12/75 */ .4533rem /* 34/75 */;
box-sizing: border-box;
.upload-box{
width: 100%;
height: 1.9733rem /* 148/75 */;
// padding: 0 .6933rem /* 52/75 */ 0 0;
padding-right: .3733rem /* 28/75 */;
box-sizing: border-box;
display: flex;
justify-content: space-between;
align-items: center;
color: #333333;
font-size: $size26;
label{
line-height: 1.9733rem /* 148/75 */;
span{
color: #FF0000;
}
}
.upload-button{
position: relative;
width: 1.3333rem /* 100/75 */;
height: 1.3333rem /* 100/75 */;
background: #FFFFFF;
border-radius: .1333rem /* 10/75 */;
border: .0267rem /* 2/75 */ dashed #D9D9D9;
display: flex;
align-items: center;
justify-content: center;
// overflow: hidden;
input{
position: absolute;
left: 0;
top: 0;
width: 1.3333rem /* 100/75 */;
height: 1.3333rem /* 100/75 */;
opacity: 0;
}
}
.face-img{
position: relative;
width: 1.3333rem /* 100/75 */;
height: 1.3333rem /* 100/75 */;
background: #FFFFFF;
border-radius: .1333rem /* 10/75 */;
img{
width: 100%;
height: 100%;
border-radius: .1333rem /* 10/75 */;
}
input{
position: absolute;
left: 0;
top: 0;
width: 1.3333rem /* 100/75 */;
height: 1.3333rem /* 100/75 */;
opacity: 0;
}
}
}
}
}
.disclaimer-box{
display: flex;
justify-content: center;
input{
margin-right: .1333rem /* 10/75 */;
}
span{
color: #30BF78;
}
}
.tel-tips{
line-height: .4533rem /* 34/75 */;
font-size: .2933rem /* 22/75 */;
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 400;
color: #999999;
padding: 0 0 .4267rem /* 32/75 */ .8rem /* 60/75 */;
box-sizing: border-box;
margin-top: -.24rem /* 18/75 */;
span{
color: #409eff;
}
}
.submit-button{
display: block;
width: 6.72rem /* 504/75 */;
height: 1.12rem /* 84/75 */;
background: #D9D9D9;
border-radius: 1.3333rem /* 100/75 */ ;
opacity: 1;
font-size: $size30;
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 500;
color: #222222;
border: none;
outline: none;
margin: 1.0133rem /* 76/75 */ auto 0;
}
.active-button{
background-color: #30BF78;
color: #fff;
}
}
.disclaimer-model-fixed{
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: #fff;
display: flex;
flex-direction: column;
padding: .4rem /* 30/75 */;
box-sizing: border-box;
h3{
font-size: .4267rem /* 32/75 */;
line-height: .8rem /* 60/75 */;
text-align: center;
}
.disclaimer-model{
flex: 1;
line-height: .5333rem /* 40/75 */;
text-align: justify;
}
}
</style>
+14
View File
@@ -5,6 +5,7 @@
<h1><img src="../assets/userhome/dingsheng.png" alt="" /></h1>
<img class="h3" src="../assets/userhome/zhiengfangke.png" alt="" />
<p>欢迎进入鼎盛无际智能访客系统</p>
<p class="version">v {{ appVersion }}</p>
</div>
<div class="plate-box">
<div @click="onClickGo('/apply')" class="list">
@@ -59,6 +60,7 @@ import { getWeChatCode, login } from "../api/user";
import { Toast, ImagePreview } from "vant";
/* @data */
const appVersion = ref(import.meta.env.VITE_APP_VERSION || '1.0.0')
const router = useRouter();
const store = useStore();
const url = "https://visitor.scdswj.cn/?code=071ucW200YtsQR1AUj3007Tabj2ucW26&state=STATE";
@@ -177,6 +179,18 @@ if (isWXBrowser) {
padding: 0 0 0 0.7467rem /* 56/75 */;
box-sizing: border-box;
}
.version {
line-height: 0.4rem;
font-size: 0.2667rem /* 20/75 */;
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 400;
color: #514e4b;
padding: 0 0 0 0.7467rem /* 56/75 */;
box-sizing: border-box;
margin-top: -0.1333rem /* 10/75 */;
}
}
.plate-box {
width: 100%;