@@ -23,7 +23,8 @@ | |||
"vuex": "^3.6.2", | |||
"dayjs": "^1.11.7", | |||
"echarts": "^5.4.1", | |||
"js-base64": "^2.5.2" | |||
"js-base64": "^2.5.2", | |||
"weixin-js-sdk": "^1.6.0" | |||
}, | |||
"devDependencies": { | |||
"@babel/core": "^7.18.10", | |||
@@ -0,0 +1,12 @@ | |||
import request from '@/config/request'; | |||
export const APIHealthUser = { | |||
addPerson //添加人员 | |||
}; | |||
export default APIHealthUser; | |||
function addPerson(params) { | |||
return request({ | |||
url: `/api/HealthyUser/AddPerson`, | |||
method: 'post', | |||
data: params | |||
}); | |||
} |
@@ -11,7 +11,8 @@ export const APIUser = { | |||
getAdminList, //管理员列表 | |||
wxAutoLogin, //微信自动登录 | |||
getVerificationCode, //获取手机验证码 | |||
wxLogin //微信登陆 | |||
wxLogin, //微信登陆 | |||
wxVerifyLogin //微信短信登陆 | |||
}; | |||
export default APIUser; | |||
// 获取用户信息 | |||
@@ -103,3 +104,12 @@ function wxLogin(params) { | |||
data: params | |||
}); | |||
} | |||
function wxVerifyLogin(params) { | |||
return request({ | |||
url: `/api/User/WxVerifyLogin`, | |||
method: 'post', | |||
headers: { AuthKey: 'key1' }, | |||
data: params | |||
}); | |||
} |
@@ -13,7 +13,14 @@ $com_light_green: #8dc21f; | |||
// 灰色线条 | |||
$lineGray: #F5F5F5; | |||
// 绑定时选择人物关系图片head.png | |||
$spriteWidthHead: 180; | |||
$spriteHeightHead: 330; | |||
$iconWidthHead: 80; | |||
$iconHeightHead: 80; | |||
// 雪碧图 | |||
$spriteWidth: 400; | |||
$spriteHeight: 400; | |||
// 清除浮动 | |||
@mixin clearfix { | |||
&:after { | |||
@@ -116,4 +123,19 @@ $lineGray: #F5F5F5; | |||
display: flex; | |||
justify-content: center; | |||
align-items: center; | |||
} | |||
} | |||
// 绑定时选择人物关系图片head.png | |||
@mixin head_position($iconX, $iconY) { | |||
@include bgPosition( | |||
$spriteWidthHead, | |||
$spriteHeightHead, | |||
$iconWidthHead, | |||
$iconHeightHead, | |||
$iconX, | |||
$iconY | |||
); | |||
} | |||
@mixin head { | |||
background: transparent url('~@/assets/myself/head.png') no-repeat; | |||
background-size: 180px 330px; | |||
} |
@@ -79,6 +79,19 @@ service.interceptors.request.use(request => { | |||
router.push({ name: 'login' }); | |||
return request; | |||
} | |||
// 全局请求统一增加一个 sourcetype: 1的参数跟区分新旧接口 | |||
if (request.method == 'get') { | |||
request.params = { | |||
...request.params, | |||
sourcetype: 1 | |||
}; | |||
} else if (request.method == 'post') { | |||
request.data = { | |||
...request.data, | |||
sourcetype: 1 | |||
}; | |||
} | |||
return request; | |||
}, errorHandler); | |||
@@ -248,6 +248,18 @@ export const constantRouterMap = [ | |||
component: () => import('@/views/myself/news/news'), | |||
meta: { title: '消息', keepAlive: false } | |||
}, | |||
{ | |||
path: '/relation', | |||
name: 'relation', | |||
component: () => import('@/views/myself/relation'), | |||
meta: { title: '绑定', keepAlive: false } | |||
}, | |||
{ | |||
path: '/bindingCheck', | |||
name: 'bindingCheck', | |||
component: () => import('@/views/myself/bindingCheck'), | |||
meta: { title: '绑定', keepAlive: false } | |||
}, | |||
{ | |||
path: '/login', | |||
name: 'login', | |||
@@ -255,8 +267,8 @@ export const constantRouterMap = [ | |||
meta: { title: '登录', keepAlive: false } | |||
}, | |||
{ | |||
path: '/bind', | |||
name: 'bind', | |||
path: '/deviceBinding', | |||
name: 'deviceBinding', | |||
component: () => import('@/views/login/bindDevices'), | |||
meta: { title: '绑定设备', keepAlive: false } | |||
}, | |||
@@ -1,21 +1,21 @@ | |||
<!-- --> | |||
<template> | |||
<div class="bind"> | |||
<NavBar title="绑定设备" @on-click-left="onNavBack"></NavBar> | |||
<NavBar title="绑定设备" @on-click-left="onNavBack" :leftArrow="false" leftText=""></NavBar> | |||
<div class="main"> | |||
<div class="top"> | |||
<van-button size="small" round type="default" class="btn-def">暂不绑定</van-button> | |||
<van-button size="small" round type="default" class="btn-def" @click="onNotBind">暂不绑定</van-button> | |||
</div> | |||
<div class="bind-con"> | |||
<div class="scan"> | |||
<p>申请获取并验证你的手机号</p> | |||
<img :src="scanImg" alt="" /> | |||
<img :src="scanImg" alt="" @click="onScanQRCodeSubmit" /> | |||
</div> | |||
<div class="cut-line"> | |||
<span>----------或手动填写绑定----------</span> | |||
</div> | |||
<div class="input"> | |||
<van-field v-model="imei" placeholder="请填写设备码" input-align="right"> | |||
<van-field v-model="inputVal" placeholder="请填写设备码" input-align="right"> | |||
<template #label> | |||
<p class="input-label">设备码</p> | |||
</template> | |||
@@ -33,21 +33,387 @@ | |||
<script> | |||
import NavBar from '@/components/NavBar.vue'; | |||
import DialogService from '@/services/dialog-service'; | |||
import AppId from '@/config/appId'; | |||
import ToastService from '@/services/toast-service'; | |||
import APIWx from '@/api/wx'; | |||
import APIDevice from '@/api/device'; | |||
import APICommand from '@/api/command'; | |||
import { isComma } from '@/services/utils-service'; | |||
let wx = require('weixin-js-sdk'); | |||
export default { | |||
components: { NavBar }, | |||
data() { | |||
return { | |||
scanImg: require('../../assets/com-imges/55_10.png'), | |||
imei: '' | |||
scanImg: require('@/assets/com-imges/55_10.png'), | |||
active: 0, | |||
inputVal: '', | |||
isAdmin: false, | |||
canScan: false, | |||
serialNo: '', //提取扫码url里面的serialNo | |||
code: '', //提取扫码url里面的密文 | |||
iccid: '', //提取扫码url里面的iccid | |||
issue: '', //分期数 | |||
params: {} | |||
}; | |||
}, | |||
created() {}, | |||
created() { | |||
this.loadParams(); | |||
this.getWxAutograph(); | |||
}, | |||
mounted() {}, | |||
methods: { | |||
loadParams() { | |||
let params = this.$route.query; | |||
if (params) { | |||
this.params = { ...params }; | |||
} | |||
}, | |||
onNavBack() { | |||
this.$router.back(); | |||
}, | |||
onNext() { | |||
// 验证输入框或者微信扫码得到的设备信息,再通过这些信息判断跳转到哪些页面 | |||
// 1.首先判断输入框 | |||
// 2. 再判断微信扫码 | |||
this.$router.push({ | |||
name: 'Index' | |||
}); | |||
/* if (this.inputVal != '') { | |||
this.CheckImei(); | |||
} else { | |||
DialogService.confirm({ message: '输入的值不能空,请不要输入空格' }); | |||
} */ | |||
}, | |||
onScanQRCodeSubmit() { | |||
if (!this.canScan) { | |||
DialogService.confirm({ message: '扫一扫功能加载中,请稍等或者重新进入' }); | |||
return; | |||
} | |||
let that = this; | |||
wx.scanQRCode({ | |||
needResult: 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果 | |||
scanType: ['qrCode', 'barCode'], // 可以指定扫二维码还是一维码,默认二者都有 | |||
success: function (res) { | |||
console.log('微信扫码返回的结果::', res.resultStr); | |||
var url = res.resultStr; // 当needResult 为 1 时,扫码返回的结果 | |||
that.compatibleDevice(url); | |||
}, | |||
fail: function (err) { | |||
alert(`扫码请求失败,请重新打开应用。\n${err.errMsg}`); | |||
console.log('wx.scanQRCode fail:::', err); | |||
} | |||
}); | |||
}, | |||
getWxAutograph() { | |||
let that = this; | |||
return new Promise((resolve, reject) => { | |||
APIWx.createJSSDK({ | |||
sUrl: window.location.href.split('#')[0], | |||
userId: this.$store.getters.userId, | |||
appId: AppId | |||
}) | |||
.then(res => { | |||
let item = res.data.data; | |||
wx.config({ | |||
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 | |||
appId: item.appId, // 必填,公众号的唯一标识 | |||
timestamp: item.timeStamp, // 必填,生成签名的时间戳 | |||
nonceStr: item.nonceStr, // 必填,生成签名的随机串 | |||
signature: item.signature, // 必填,签名 | |||
jsApiList: ['scanQRCode'] // 必填,需要使用的JS接口列表 | |||
}); | |||
wx.ready(() => { | |||
resolve(true); | |||
that.canScan = true; | |||
}); | |||
}) | |||
.catch(err => { | |||
reject(false); | |||
console.log(err); | |||
}); | |||
}); | |||
}, | |||
CheckImei() { | |||
let reqBody = { | |||
imei: this.serialNo || this.inputVal.trim(), | |||
iccid: this.iccid || '' | |||
}; | |||
APICommand.CheckImei(reqBody) | |||
.then(res => { | |||
let data = res.data; | |||
this.issue = data.title === '富康通' ? 60 : 0; | |||
// 2023.05.25,取消!---接口新增加一个 isActive 参数来判断是否需要调用激活接口, 0,不需要直接绑定,1 需要 | |||
if (data.stateCode === 1 && data.rule === 1 && data.isRecharge === false && data.iccid !== null) { | |||
// stateCode = 1 ,title = '直播' 并且isRecharge 是false才可以进入到充值界面 | |||
this.$router.push({ | |||
name: 'topup', | |||
query: { | |||
isCanTopup: true, | |||
iccid: this.iccid, | |||
isAdmin: this.isAdmin, | |||
serialNo: this.serialNo | |||
} | |||
}); | |||
} else if ( | |||
data.stateCode === 1 && | |||
data.message === 'ok' && | |||
data.isRecharge === false && | |||
data.iccid === null && | |||
this.inputVal !== '' | |||
) { | |||
// 手动输入是直播基地的设备 | |||
DialogService.confirm({ | |||
message: '请您通过扫码方式激活绑定!' | |||
}); | |||
} else if ( | |||
data.stateCode === 1 && | |||
data.message === 'ok' && | |||
data.isRecharge === true && | |||
data.iccid === null && | |||
this.inputVal !== '' | |||
) { | |||
DialogService.confirm({ | |||
message: '请您通过扫码方式激活绑定!' | |||
}); | |||
} else if ( | |||
data.stateCode === 0 && | |||
data.message === '请插入正确的电话卡进行设备激活' && | |||
data.iccid === null && | |||
this.inputVal !== '' | |||
) { | |||
DialogService.confirm({ | |||
message: '请您通过扫码方式激活绑定!' | |||
}); | |||
} else if ( | |||
data.stateCode === 0 && | |||
data.message === '请插入正确的电话卡进行设备激活' && | |||
data.iccid !== null && | |||
this.inputVal === '' | |||
) { | |||
DialogService.confirm({ | |||
message: '为了更好地为您服务,请务必使用我司提供的电话卡。有疑问请来电400 002 3393咨询。' | |||
}); | |||
} else if ( | |||
data.stateCode === 0 && | |||
data.message === '请插入正确的电话卡进行设备激活' && | |||
data.iccid === null && | |||
this.inputVal === '' | |||
) { | |||
DialogService.confirm({ | |||
message: '为了更好地为您服务,请务必使用我司提供的电话卡。有疑问请来电400 002 3393咨询。' | |||
}); | |||
} else if ( | |||
data.stateCode === 1 && | |||
data.rule === 1 && | |||
data.message === 'ok' && | |||
data.isRecharge === true && | |||
this.iccid !== null | |||
) { | |||
// 扫码时是直播基地的设备并且已经支付完成的 | |||
this.getAdminOfIdByScan(this.serialNo, this.iccid); | |||
} else if ( | |||
data.stateCode === 1 && | |||
data.rule === 2 && | |||
!this.isCanEffective(data.title) && | |||
this.inputVal === '' | |||
) { | |||
this.getAdminOfIdByScan(this.serialNo, this.iccid); | |||
} else if (data.stateCode === 1 && data.rule === 2 && this.isCanEffective(data.title)) { | |||
// 中亿/联通的卡不走激活接口,直接绑定 | |||
this.getAdminOfIdByScan(this.serialNo); | |||
} else if (data.stateCode === 0 && data.rule === 0 && this.inputVal === '') { | |||
this.getAdminOfIdByScan(this.serialNo); | |||
} else if (data.stateCode === 0 && data.rule === 0 && this.inputVal !== '') { | |||
this.getAdminOfIdByScan(this.inputVal); | |||
} else { | |||
if (this.inputVal != '') { | |||
//this.getAdminByInput(); | |||
this.getAdminOfIdByScan(this.inputVal); | |||
} else { | |||
this.getAdminOfIdByScan(this.serialNo); | |||
} | |||
} | |||
}) | |||
.catch(() => {}); | |||
}, | |||
/** | |||
* 扫码 | |||
* 参数为明文的cid/serialNo | |||
*/ | |||
getAdminOfIdByScan(serialNo, iccid) { | |||
/* let reqUrl = '/api/Device/BindingScan'; | |||
let reqBody = { url }; */ | |||
ToastService.loading(); | |||
/* this.$axios | |||
.post(reqUrl, reqBody) */ | |||
let url = `?id=${serialNo}`; | |||
APIDevice.bindingScan({ url }) | |||
.then(res => { | |||
let data = res.data.data; | |||
if (res.data.stateCode === 1) { | |||
this.isAdmin = data.isAdmin; | |||
this.$store.commit('isAdmin', data.isAdmin); | |||
this.$router.push({ | |||
// 2022 03. 19 需求变更 取消向设备发送安全码 | |||
/* name: data.isAdmin ? "safetyCode" : "relation", */ | |||
// 2022. 4. 6 需求变更 增加一个中间页 | |||
/* name: "relation", */ | |||
name: 'bindingCheck', | |||
query: { | |||
serialNo: data.serialNo, | |||
isAdmin: data.isAdmin, | |||
iccid: iccid || '', | |||
issue: this.issue | |||
} | |||
}); | |||
} else { | |||
DialogService.confirm({ message: res.data.message }); | |||
} | |||
}) | |||
.catch(e => console.log(e)) | |||
.finally(() => ToastService.clear()); | |||
}, | |||
/** | |||
* 扫码 | |||
* 使用新设备的接口,参数为加密的cid | |||
*/ | |||
getAdminOfCidByScan(code) { | |||
/* let reqUrl = '/api/Device/BindingScan'; | |||
let reqBody = { url }; */ | |||
ToastService.loading(); | |||
/* this.$axios | |||
.post(reqUrl, reqBody) */ | |||
let url = `?cid=${code}`; | |||
APIDevice.bindingScan({ url }) | |||
.then(res => { | |||
let data = res.data.data; | |||
if (res.data.stateCode === 1) { | |||
// TODO isAdmin true:该请求为管理员,false:该请求为家属(需要提示用户等待管理员的通过) | |||
// TODO 新旧设备标记:useSafeCode = 0 | 1 | |||
this.isAdmin = data.isAdmin; | |||
this.$store.commit('isAdmin', data.isAdmin); | |||
this.$router.push({ | |||
name: 'relation', | |||
query: { | |||
serialNo: data.serialNo, | |||
isAdmin: data.isAdmin | |||
} | |||
}); | |||
} else { | |||
DialogService.confirm({ message: res.data.message }); | |||
} | |||
}) | |||
.catch(e => console.log(e)) | |||
.finally(() => ToastService.clear()); | |||
}, | |||
/** | |||
* 扫码后,返回的数据是一个 url,参数为 id | cid,新设备为 cid,旧设备为 id | |||
* 新设备使用新的加密方式,获取的非明文 imei/serialNo,故省略了发送验证码步骤 | |||
*/ compatibleDevice(url) { | |||
console.log('url', url); | |||
let res = /\?cid=/.test(url); | |||
let isId = /\?id=/.test(url); | |||
let idCallBack = isComma(url); | |||
console.log('idCallBack', idCallBack); | |||
// 如果 二维码url存在 Unknown 增加 提示, 并且不允许进行下一步操作 | |||
// eslint-disable-next-line no-useless-escape | |||
if (/\Unknown/.test(url)) { | |||
return DialogService.confirm({ | |||
title: 'SIM卡识别失败', | |||
message: '请在设备操作[返回],再按[确定]显示绑定二维码。' | |||
}); | |||
} | |||
// 旧设备 | |||
if (isId) { | |||
// 根据返回类型获取想要的数据 | |||
if (typeof idCallBack === 'object') { | |||
let newSerialNo = idCallBack.imei.split('?id=')[1]; | |||
this.serialNo = newSerialNo; | |||
this.iccid = idCallBack.data; | |||
console.log('newSerialNo', newSerialNo, 'iccid', idCallBack.data); | |||
this.CheckImei(); | |||
/* this.getAdminOfIdByScan(this.serialNo); */ | |||
} else if (typeof idCallBack === 'string') { | |||
this.serialNo = url.split('?id=')[1]; | |||
this.CheckImei(); | |||
//this.getAdminOfIdByScan(this.serialNo); | |||
} | |||
} else if (idCallBack.type === 'rfIdAndiccId') { | |||
// 明文没有url 只有imei,rfid,iccid | |||
let newSerialNo = idCallBack.imei; | |||
this.serialNo = newSerialNo; | |||
this.iccid = idCallBack.data; | |||
console.log('newSerialNo', newSerialNo, 'iccid', idCallBack.data); | |||
this.CheckImei(); | |||
} else if (res) { | |||
// 新设备 | |||
if (typeof idCallBack === 'object') { | |||
let newCode = idCallBack.imei.split('?cid=')[1]; | |||
this.code = newCode; | |||
this.iccid = idCallBack.data; | |||
this.decodeSerialNo(newCode); | |||
this.getAdminOfCidByScan(newCode); | |||
} else if (typeof idCallBack === 'string') { | |||
let newCode = url.split('?cid=')[1]; | |||
this.code = newCode; | |||
this.decodeSerialNo(newCode); | |||
this.getAdminOfCidByScan(newCode); | |||
} | |||
// 无id或者cid时 | |||
} else { | |||
if (typeof idCallBack === 'object') { | |||
let newSerialNo = idCallBack.imei; | |||
this.serialNo = newSerialNo; | |||
this.getAdminOfIdByScan(this.serialNo); | |||
} else if (typeof idCallBack === 'string') { | |||
this.serialNo = url; | |||
this.getAdminOfIdByScan(this.serialNo); | |||
} | |||
} | |||
// 2022/3/17 为了兼容新的扫码方式特意注释 | |||
/* if (res) { // 新设备 | |||
this.getAdminOfCidByScan(url); | |||
} else { // 旧设备 | |||
this.getAdminOfIdByScan(url); | |||
} */ | |||
}, | |||
// 通过密文解析获取imei | |||
decodeSerialNo() { | |||
APIDevice.decodeSerialNo({ code: this.code }) | |||
.then(res => { | |||
let data = res.data; | |||
if (data.stateCode === 1) { | |||
let newData = isComma(data.data); | |||
console.log('newData', newData); | |||
this.serialNo = newData.imei || data.data; | |||
console.log('this.serialNo', this.serialNo); | |||
// 如果返回的数据有逗号, 根据类型放到store里面 | |||
// todo 一期这个需求暂时不用做 | |||
/* if (newData) { | |||
if(newData.type === "iccId") { | |||
this.$store.commit("iccId", newData.data); | |||
} else if (newData.type === "rfId") { | |||
this.$store.commit("rfId", newData.data); | |||
} | |||
} */ | |||
} | |||
}) | |||
.catch(error => { | |||
console.log('error', error); | |||
}); | |||
}, | |||
// 是否可以走激活接口 | |||
isCanEffective(title) { | |||
let manufacturerArray = ['中亿', '联通', '中亿/联通']; | |||
let isEffective = manufacturerArray.some(item => { | |||
return item.includes(title); | |||
}); | |||
return isEffective; | |||
}, | |||
// 暂不绑定 | |||
onNotBind() { | |||
this.$router.push({ | |||
name: 'Index' | |||
}); | |||
@@ -7,7 +7,7 @@ import Vue from 'vue/types/umd'; | |||
<van-image width="100%" height="400" :src="bgImgPath" fit="contain" /> | |||
</div> | |||
<div class="login-btn"> | |||
<van-button type="primary" size="large" round @click="onLogin" :color="$green" class="login-text" | |||
<van-button type="primary" size="large" round @click="onWxAutoLogin" :color="$green" class="login-text" | |||
>用户一键登录</van-button | |||
> | |||
</div> | |||
@@ -38,7 +38,7 @@ import Vue from 'vue/types/umd'; | |||
</template> | |||
</van-field> | |||
</van-cell-group> | |||
<van-button size="large" round @click="onLogin('new')" :color="$green" class="login-text">注册/登录</van-button> | |||
<van-button size="large" round @click="onLogin" :color="$green" class="login-text">注册/登录</van-button> | |||
</div> | |||
</van-popup> | |||
</div> | |||
@@ -48,6 +48,7 @@ import Vue from 'vue/types/umd'; | |||
import APIUser from '@/api/user'; | |||
import NotifyService from '@/services/notify-service'; | |||
import AppId from '@/config/appId'; | |||
import APIWx from '@/api/wx'; | |||
export default { | |||
data() { | |||
const time = 120; | |||
@@ -65,8 +66,39 @@ export default { | |||
}; | |||
}, | |||
created() {}, | |||
mounted() {}, | |||
mounted() { | |||
// TODO 获取code再拿code获取openId | |||
// this.getCode(); | |||
}, | |||
methods: { | |||
getCode() { | |||
let url = window.location.href; | |||
if (url.indexOf('code') > -1) { | |||
let codeUrl = window.location.href.split('?code='); | |||
if (codeUrl) { | |||
let timeStamp = new Date().getTime(); | |||
let code = codeUrl[1].split('&')[0]; | |||
if (this.$own.isNotNull(code)) { | |||
this.$store.commit('code', `${code}-${timeStamp}`); | |||
this.checkedRegister(code); | |||
} | |||
} | |||
} | |||
}, | |||
// 通过code拿去openId | |||
checkedRegister(code) { | |||
if (code) { | |||
let reqBody = { | |||
loginCode: code.split('-')[0], | |||
appId: AppId | |||
}; | |||
APIWx.checkIsNewCustomer(reqBody).then(res => { | |||
if (res.data.stateCode === 1 || res.data.stateCode === 2) { | |||
this.$store.commit('openId', res.data.wxOpenId); | |||
} | |||
}); | |||
} | |||
}, | |||
sendCode() { | |||
// 验证是否输正确的手机号码, | |||
let reg = /^1[3456789]\d{9}$/; | |||
@@ -115,27 +147,61 @@ export default { | |||
} | |||
}, 1000); | |||
}, | |||
onLogin(type) { | |||
onLogin() { | |||
// 一键登录之前调取登录接口查询是否是旧用户,如果是旧用户直接登录无需再输入手机号码和验证码登录,否则需要 | |||
// 现在模拟是新用户,待接口完成 | |||
this.show = true; | |||
let reg = /^1[3456789]\d{9}$/; | |||
if (type === 'new') { | |||
if (this.phone === '' || !reg.test(this.phone)) { | |||
this.errPhoneMsg = '请输入正确的手机号码'; | |||
} else if (this.verificacode === '') { | |||
this.errCodeMsg = '请输入正确的验证码'; | |||
} else { | |||
// 格式正确 | |||
this.errPhoneMsg = ''; | |||
this.loginRequest(); | |||
} | |||
if (this.phone === '' || !reg.test(this.phone)) { | |||
this.errPhoneMsg = '请输入正确的手机号码'; | |||
} else if (this.verificacode === '') { | |||
this.errCodeMsg = '请输入正确的验证码'; | |||
} else { | |||
// 格式正确 | |||
this.errPhoneMsg = ''; | |||
this.loginRequest(); | |||
} | |||
}, | |||
// 使用微信code得到的openId 自动登录 | |||
onWxAutoLogin() { | |||
let reqBody = { | |||
appId: AppId, | |||
openId: /* this.$store.getters.openId || */ 'odcaWxCyeDHFpa3xpnQukqIcWvg0' | |||
}; | |||
APIUser.wxAutoLogin(reqBody) | |||
.then(res => { | |||
if (res.data.stateCode === 1) { | |||
if (res.data) { | |||
let item = res.data; | |||
this.$store.commit('authToken', item.authToken); | |||
this.$store.commit('userId', item.userId); | |||
this.$store.commit('code', ''); | |||
/* this.$store.commit('openId', item.wxOpenId || ''); */ | |||
NotifyService.notify({ message: '登录成功!正在为您跳转...', type: 'success' }); | |||
this.$store.commit('isLogin', 'true'); | |||
setTimeout(() => { | |||
this.$router.push({ name: 'Index' }); | |||
}, 1000); | |||
} | |||
} else { | |||
this.show = true; | |||
} | |||
}) | |||
.catch(e => { | |||
console.log(e); | |||
NotifyService.notify({ message: `${e.message}` }); | |||
}); | |||
}, | |||
loginRequest() { | |||
/* let reqBody = { | |||
phoneNumber: this.phone, | |||
loginCode: this.$store.getters.openId, | |||
appId: AppId, | |||
loginType: 2, | |||
verificationCode: this.verificacode | |||
}; */ | |||
let reqBody = { | |||
loginName: /* this.phone */ '18664272743', | |||
password: '123456', | |||
password: /* this.password */ '123456', | |||
loginCode: /* this.$store.getters.openId */ 'odcaWxCyeDHFpa3xpnQukqIcWvg0', | |||
appId: AppId | |||
}; | |||
@@ -155,7 +221,7 @@ export default { | |||
name: 'personInfos', | |||
query: { | |||
from: 'login', | |||
fromRouter: 'Index' | |||
toRouter: 'Index' | |||
} | |||
}); | |||
}, 1000); | |||
@@ -0,0 +1,369 @@ | |||
<template> | |||
<div class="container" v-show="isPageShow"> | |||
<NavBar title="绑定设备" @on-click-left="onBack"></NavBar> | |||
<div class="content"> | |||
<p class="tips">设备号码:</p> | |||
<p class="text">{{ isNewDevice ? decodedSerialNo || '正在解码...' : serialNo }}</p> | |||
<p class="tips" v-show="isShow">ICCID:</p> | |||
<p class="text" v-show="isShow">{{ iccid }}</p> | |||
<p class="iccid-text" v-show="iccidShow"> | |||
<span class="span-red" | |||
>SIM卡激活成功,请确认在线图标标志<img | |||
src="@/assets/myself/online.png" | |||
/>,如没有看到,请重启设备或者等1分钟之后再进入绑定界面。</span | |||
><br /> | |||
<span class="span-red">确认设备在线,再点击【下一步】。</span> | |||
</p> | |||
<p class="iccid-text" v-show="!iccidShow"> | |||
<span class="span-red">{{ errorText }}</span> | |||
</p> | |||
<div class="submit-button"> | |||
<van-button | |||
round | |||
type="info" | |||
:disabled="!canSubmit || !canNext || !isFail" | |||
:loading="loading" | |||
@click="onSubmit" | |||
> | |||
{{ submitText }} | |||
</van-button> | |||
</div> | |||
<!-- <div class="cancel-button" v-show="false"> | |||
<van-button round plain @click="onCancel"> 取消 </van-button> | |||
</div> --> | |||
</div> | |||
</div> | |||
</template> | |||
<script> | |||
import DialogService from '@/services/dialog-service'; | |||
import ToastService from '@/services/toast-service'; | |||
import APICommand from '@/api/command'; | |||
import APIDevice from '@/api/device'; | |||
import { isComma } from '@/services/utils-service'; | |||
import NavBar from '@/components/NavBar.vue'; | |||
export default { | |||
components: { NavBar }, | |||
computed: { | |||
canSubmit() { | |||
if (this.isNewDevice) { | |||
return this.$own.isNotNull(this.decodedSerialNo); | |||
} else { | |||
return true; | |||
} | |||
}, | |||
submitText() { | |||
return '下一步'; | |||
} | |||
}, | |||
data() { | |||
return { | |||
serialNo: '', | |||
decodedSerialNo: '', | |||
isNewDevice: false, | |||
loading: false, | |||
iccid: '', | |||
iccidShow: false, | |||
errorText: '', //sim卡激活失败 | |||
isShow: false, | |||
timer: null, //倒计时 | |||
bindTime: 60, //60秒倒计时 | |||
canNext: true, | |||
isPageShow: false, | |||
isFail: true //sim卡激活失败 | |||
}; | |||
}, | |||
destroyed() { | |||
clearInterval(this.timer); | |||
}, | |||
mounted() { | |||
this.serialNo = this.$route.query.serialNo; | |||
this.iccid = this.$route.query.iccid; | |||
this.isNewDevice = JSON.parse(this.$route.query.isNewDevice || false); | |||
if (this.isNewDevice) { | |||
this.decodeSerialNo(); | |||
} | |||
this.checkEffective(); | |||
}, | |||
methods: { | |||
// 返回 | |||
onBack() { | |||
this.$router.push({ name: 'deviceBinding' }); | |||
}, | |||
onSubmit() { | |||
if (this.isNewDevice) { | |||
this.getAdminOfCidByScan(); | |||
} else this.getAdminOfIdByScan(); | |||
}, | |||
// 检查是否需要激活,根据iccid是否不为空判断 | |||
checkEffective() { | |||
if (this.iccid !== '') { | |||
this.effective(); | |||
} else { | |||
this.isPageShow = false; | |||
this.onSubmit(); | |||
} | |||
}, | |||
// sim卡自动激活 | |||
// 中亿物联联通卡 SIM自动激活 | |||
effective() { | |||
ToastService.loading({ message: '激活中,请稍候...' }); | |||
let reqBody = { | |||
imei: this.serialNo, | |||
iccid: this.iccid, | |||
issue: this.$route.query.issue || 0 | |||
}; | |||
APICommand.Effective(reqBody) | |||
.then(res => { | |||
console.log('res', res); | |||
let data = res.data; | |||
if (data.stateCode === 0 && data.message !== null) { | |||
this.iccidShow = false; | |||
this.isShow = true; | |||
this.isFail = false; | |||
this.isPageShow = true; | |||
this.errorText = '电话卡激活失败!请进行实名认证与绑定SIM卡。如您已实名认证,请5分钟后,再进行设备绑定。'; | |||
/* Dialog.confirm({ title: "SIM卡激活失败", message: data.message, className: "device_confirm", }); */ | |||
} else if (data.stateCode === 1 && data.message !== 'ok') { | |||
this.isShow = true; | |||
this.iccidShow = true; | |||
this.isPageShow = true; | |||
this.canNext = true; | |||
/* this.countDown(); */ | |||
/* Dialog.confirm({ title: "SIM卡激活成功", message: '卡激活成功,5分钟后则可正常使用。', className: "device_confirm", }); */ | |||
} else if (data.stateCode === 1 && data.message === 'ok') { | |||
this.isShow = false; | |||
this.iccidShow = false; | |||
this.isPageShow = false; | |||
this.onSubmit(); | |||
} else if (data.stateCode === 2) { | |||
// 2023/5/25 ,新增 一个条件可以直接绑定,不需要用户继续操作 | |||
this.isShow = false; | |||
this.iccidShow = false; | |||
this.isPageShow = false; | |||
this.onSubmit(); | |||
} else if (data.stateCode === 0 && data.message === null) { | |||
// 2022 .4 .22 还有一种情况 stateCode === 0 并且 返回的message === null 也直接跳过不调小台风激活接口 | |||
this.isShow = false; | |||
this.iccidShow = false; | |||
this.isPageShow = false; | |||
this.onSubmit(); | |||
} else if (data.stateCode === 3) { | |||
// 2023/7/5 ,新增 一个条件可以直接绑定,不需要用户继续操作 | |||
this.isShow = false; | |||
this.iccidShow = false; | |||
this.isPageShow = false; | |||
this.onSubmit(); | |||
} else if ( | |||
data.stateCode === 0 && | |||
data.title === '直播' && | |||
data.message === '请插入正确的电话卡进行设备激活' | |||
) { | |||
// 2022 .4 .22 还有一种情况 stateCode === 0 并且 返回的message === null 也直接跳过不调小台风激活接口 | |||
this.isShow = false; | |||
this.iccidShow = false; | |||
this.isPageShow = false; | |||
DialogService.confirm({ | |||
title: '温馨提示', | |||
message: '为了更好地为您服务,请务必使用我司提供的电话卡。有疑问请来电400 002 3393咨询。' | |||
}).then(() => { | |||
this.$router.push({ name: 'deviceBinding' }); | |||
}); | |||
} | |||
}) | |||
.catch(error => { | |||
console.log('出错了:;', error); | |||
}) | |||
.finally(() => { | |||
ToastService.clear(); | |||
}); | |||
}, | |||
// 60秒倒计时 | |||
countDown() { | |||
this.timer = setInterval(() => { | |||
if (this.bindTime) { | |||
this.bindTime--; | |||
if (this.bindTime === 0) { | |||
this.canNext = true; | |||
} | |||
} else { | |||
this.bindTime = 60; | |||
clearInterval(this.timer); | |||
} | |||
}, 1000); | |||
}, | |||
decodeSerialNo() { | |||
let url = `/api/Device/DecodeImei`; | |||
let headers = { headers: { AuthKey: 'key1' } }; | |||
let reqBody = { code: this.serialNo }; | |||
this.$axios | |||
.post(url, reqBody, headers) | |||
.then(res => { | |||
let data = res.data; | |||
if (data.stateCode === 1) { | |||
let newData = isComma(data.data); | |||
this.decodedSerialNo = newData.imei || data.data; | |||
// 如果返回的数据有逗号, 根据类型放到store里面 | |||
if (newData) { | |||
if (newData.type === 'iccId') { | |||
this.$store.commit('iccId', newData.data); | |||
} else if (newData.type === 'rfId') { | |||
this.$store.commit('rfId', newData.data); | |||
} | |||
} | |||
} | |||
}) | |||
.catch(e => { | |||
console.log(e); | |||
}); | |||
}, | |||
/** | |||
* 使用新设备的接口,参数为加密的 cid | |||
*/ | |||
getAdminOfCidByScan() { | |||
this.loading = true; | |||
let reqBody = { url: `?cid=${this.serialNo}` }; | |||
APIDevice.bindingScan(reqBody) | |||
.then(res => { | |||
let data = res.data.data; | |||
if (res.data.stateCode === 1) { | |||
// TODO isAdmin true:该请求为管理员,false:该请求为家属(需要提示用户等待管理员的通过) | |||
this.isAdmin = data.isAdmin; | |||
this.$store.commit('isAdmin', data.isAdmin); | |||
this.$router.push({ | |||
name: 'relation', | |||
query: { | |||
serialNo: data.serialNo, | |||
isAdmin: data.isAdmin, | |||
iccid: this.iccid | |||
} | |||
}); | |||
} else if ( | |||
res.data.stateCode === 0 && | |||
res.data.message.indexOf('已经有用户获取安全码,请一分钟后再试') > -1 | |||
) { | |||
this.$router.push({ | |||
name: 'relation', | |||
query: { | |||
serialNo: data.serialNo, | |||
isAdmin: data.isAdmin, | |||
iccid: this.iccid | |||
} | |||
}); | |||
} else { | |||
DialogService.confirm({ title: res.data.message }); | |||
} | |||
}) | |||
.catch(e => { | |||
console.log(e); | |||
}) | |||
.finally(() => { | |||
this.loading = false; | |||
}); | |||
}, | |||
/** | |||
* 扫码 | |||
* 参数为明文的 id/serialNo | |||
*/ | |||
getAdminOfIdByScan() { | |||
this.loading = true; | |||
let reqBody = { url: `?id=${this.serialNo}` }; | |||
APIDevice.bindingScan(reqBody) | |||
.then(res => { | |||
let data = res.data.data; | |||
if (res.data.stateCode === 1) { | |||
this.isAdmin = data.isAdmin; | |||
this.$store.commit('isAdmin', data.isAdmin); | |||
this.$router.push({ | |||
// 2022 03. 19 需求变更 取消向设备发送安全码 | |||
name: /* data.isAdmin ? 'index' : */ 'relation', | |||
query: { | |||
serialNo: data.serialNo, | |||
isAdmin: data.isAdmin, | |||
iccid: this.iccid | |||
} | |||
}); | |||
} else if ( | |||
res.data.stateCode === 0 && | |||
res.data.message.indexOf('已经有用户获取安全码,请一分钟后再试') > -1 | |||
) { | |||
this.$router.push({ | |||
name: 'relation', | |||
query: { | |||
serialNo: data.serialNo, | |||
isAdmin: data.isAdmin, | |||
iccid: this.iccid | |||
} | |||
}); | |||
} else { | |||
DialogService.confirm({ title: res.data.message }); | |||
} | |||
}) | |||
.catch(e => { | |||
console.log(e); | |||
}) | |||
.finally(() => { | |||
this.loading = false; | |||
}); | |||
} | |||
} | |||
}; | |||
</script> | |||
<style lang="scss" scoped> | |||
.container { | |||
height: 100vh; | |||
position: relative; | |||
.content { | |||
height: 100%; | |||
width: 100%; | |||
position: absolute; | |||
top: 0; | |||
display: flex; | |||
flex-direction: column; | |||
justify-content: center; | |||
align-items: center; | |||
.tips { | |||
font-size: 30px; | |||
color: #aaa; | |||
} | |||
.text { | |||
margin-bottom: 50px; | |||
} | |||
.iccid-text { | |||
font-size: 32px; | |||
padding: 10px 40px; | |||
margin: 40px; | |||
.span-red { | |||
color: red; | |||
} | |||
img { | |||
height: 40px; | |||
line-height: 80px; | |||
margin: 10px 10px 0 10px; | |||
width: 100px; | |||
background-repeat: no-repeat; | |||
background-size: cover; | |||
} | |||
} | |||
.van-button { | |||
} | |||
.submit-button, | |||
.cancel-button { | |||
.van-button--normal { | |||
width: 300px; | |||
height: 60px; | |||
line-height: 60px; | |||
font-size: 15px; | |||
.van-loading__spinner { | |||
width: 25px !important; | |||
height: 25px !important; | |||
} | |||
} | |||
} | |||
.cancel-button { | |||
margin-top: 20px; | |||
} | |||
} | |||
} | |||
</style> |
@@ -265,9 +265,9 @@ export default { | |||
}, | |||
methods: { | |||
onNavBack() { | |||
let fromRouter = this.$route.query.from; | |||
let toRouter = this.$route.query.from; | |||
this.$router.push({ | |||
name: fromRouter ? fromRouter : 'watchSetting' | |||
name: toRouter ? toRouter : 'watchSetting' | |||
}); | |||
}, | |||
onSubmit() { | |||
@@ -315,10 +315,10 @@ export default { | |||
.then(res => { | |||
if (res.data.stateCode === 1) { | |||
ToastService.success({ message: '设置成功' }); | |||
let fromRouter = this.$route.query.from; | |||
let toRouter = this.$route.query.from; | |||
setTimeout(() => { | |||
this.$router.push({ | |||
name: fromRouter ? fromRouter : 'watchSetting' | |||
name: toRouter ? toRouter : 'watchSetting' | |||
}); | |||
}, 1500); | |||
} else { | |||
@@ -1,18 +1,19 @@ | |||
<template> | |||
<div class="registe-user-infos-container"> | |||
<div class="nav-bar"> | |||
<van-nav-bar :title="navBarTitle" :left-arrow="true" @click-left="onNavBack"> | |||
<!-- <template #right> | |||
<div class="setupClock_save">保存</div> | |||
</template> --> | |||
</van-nav-bar> | |||
<NavBar | |||
:title="navBarTitle" | |||
@on-click-left="onNavBack" | |||
:leftText="leftText" | |||
:leftArrow="leftText !== ''" | |||
></NavBar> | |||
</div> | |||
<div class="main"> | |||
<div class="list"> | |||
<div class="avatar" v-show="$route.query.from === 'login'"> | |||
<div class="avatar-con"> | |||
<div class="avatar"> | |||
<div class="avatar-con" @click="chooseImage"> | |||
<div class="avatar-img"> | |||
<img :src="imgPath" alt="" /> | |||
<img :src="imagePath" alt="" /> | |||
</div> | |||
<div class="avatar-text"> | |||
<span>设置头像</span> | |||
@@ -21,7 +22,7 @@ | |||
</div> | |||
<div class="item"> | |||
<div class="left importance"> | |||
<span class="title gray">设备昵称:</span> | |||
<span class="title gray">用户昵称:</span> | |||
</div> | |||
<div class="right" @click="onClick"> | |||
<input type="text" maxlength="6" v-model.trim="personData.nickName" placeholder="请输入昵称" /> | |||
@@ -91,7 +92,7 @@ | |||
</div> | |||
</div> | |||
<div class="item isHasBlood" v-show="this.$route.query.from === 'watchSetting'"> | |||
<div class="item isHasBlood"> | |||
<div class="left importance"> | |||
<span class="title gray">是否有高血压史:</span> | |||
</div> | |||
@@ -192,11 +193,17 @@ | |||
<script> | |||
import APIDevice from '@/api/device'; | |||
import APIWx from '@/api/wx'; | |||
import APIHealthUser from '@/api/health-user'; | |||
import { isNotNull, isNull } from '@/services/utils-service'; | |||
import AppId from '@/config/appId'; | |||
import DialogService from '@/services/dialog-service'; | |||
import ToastService from '@/services/toast-service'; | |||
import NavBar from '@/components/NavBar.vue'; | |||
let wx = require('weixin-js-sdk'); | |||
export default { | |||
name: '', | |||
components: { NavBar }, | |||
data() { | |||
return { | |||
isHasBlood: '1', | |||
@@ -206,7 +213,7 @@ export default { | |||
height: '', | |||
weight: '', | |||
rightIcon: require('../../../assets/myself/health/right_more.png'), | |||
imgPath: require('../../../assets/com-imges/55_03.png'), | |||
imagePath: '' || require('../../../assets/com-imges/55_03.png'), | |||
isDateShow: false, | |||
currentDate: '', | |||
minDate: '', | |||
@@ -332,20 +339,53 @@ export default { | |||
dialogTitle: '', | |||
profession: '', | |||
uid: '', | |||
navBarTitle: '' | |||
navBarTitle: '', | |||
params: {} | |||
}; | |||
}, | |||
computed: {}, | |||
computed: { | |||
leftText() { | |||
return this.params.from == 'login' ? '' : '返回'; | |||
} | |||
}, | |||
created() { | |||
this.loadParams(); | |||
this.setMaxDate(); | |||
this.getPersonData(); | |||
this.getWxAutograph(); | |||
this.navBarTitle = this.$route.query.from === 'psychologicalSetting' ? '登记佩戴者信息' : '添加成员'; | |||
}, | |||
mounted() { | |||
/* this.getPersonData(); */ | |||
}, | |||
methods: { | |||
// 加载微信jssdk | |||
getWxAutograph() { | |||
APIWx.createJSSDK({ | |||
userId: this.$store.getters.userId, | |||
sUrl: window.location.href.split('#')[0], | |||
appId: AppId | |||
}) | |||
.then(res => { | |||
let item = res.data.data; | |||
wx.config({ | |||
debug: false, | |||
appId: item.appId, | |||
timestamp: item.timeStamp, | |||
nonceStr: item.nonceStr, | |||
signature: item.signature, | |||
jsApiList: ['chooseImage', 'uploadImage'] | |||
}); | |||
wx.ready(() => {}); | |||
}) | |||
.catch(err => { | |||
console.log(err); | |||
}); | |||
}, | |||
loadParams() { | |||
let params = this.$route.query; | |||
if (params) { | |||
this.params = { ...params }; | |||
if (params.from === 'watchSetting' || params.isShowSubmit) { | |||
this.btnText = '保存'; | |||
} | |||
@@ -359,9 +399,6 @@ export default { | |||
this.currentDate = new Date(maxDate); | |||
}, | |||
getPersonData() { | |||
/* ToastService.loading({ | |||
message: '数据加载中' | |||
}); */ | |||
APIDevice.getPersonInfo({ | |||
userId: this.$store.getters.userId, | |||
deviceId: this.$store.getters.deviceId || '398b4b34-221b-4fc9-a9fb-e7bec8876248' | |||
@@ -384,10 +421,9 @@ export default { | |||
}); | |||
}, | |||
onNavBack() { | |||
let fromRouter = this.$route.query.from; | |||
this.$store.commit('notJump', 1); | |||
let toRouter = this.$route.query.toRouter; | |||
this.$router.push({ | |||
name: fromRouter ? fromRouter : 'psychologicalSetting', | |||
name: toRouter ? toRouter : 'Index', | |||
notJump: true | |||
}); | |||
}, | |||
@@ -439,61 +475,67 @@ export default { | |||
this.savePersonInfo(); | |||
}, | |||
savePersonInfo() { | |||
let reqBody = { ...this.personData }; | |||
reqBody['userId'] = this.$store.getters.userId; | |||
reqBody.weight = Number(reqBody.weight); | |||
reqBody.height = Number(reqBody.height); | |||
reqBody.ishypertension = Number(reqBody.ishypertension); | |||
reqBody.chronicDisease = Number(reqBody.chronicDisease); | |||
reqBody.regularity = Number(reqBody.regularity); | |||
reqBody.profession = Number(reqBody.profession); | |||
// 2023.07/19 增加容错 deviceId和serialNo关键参数为空时使用缓存里面的数据 | |||
reqBody.deviceId = reqBody.deviceId || this.$store.getters.deviceId; | |||
reqBody.serialNo = reqBody.serialNo || this.$store.getters.serialNo; | |||
let personForm = { ...this.personData }; | |||
let reqBody = { | |||
sourceType: 1, | |||
nickName: personForm.nickName, | |||
avatar: this.imagePath, | |||
level: 0, | |||
gender: personForm.gender == 'false' ? 0 : 1, | |||
height: Number(personForm.height), | |||
weight: Number(personForm.weight), | |||
birth: personForm.bornDate, | |||
education: Number(personForm.profession), | |||
isHypertension: personForm.ishypertension == '1', | |||
isScheduleRegular: personForm.regularity == '1', | |||
isChronicDisease: personForm.chronicDisease == '1' | |||
}; | |||
console.log('请求的参数', reqBody); | |||
// eslint-disable-next-line no-unreachable | |||
ToastService.loading({ | |||
message: '保存中' | |||
}); | |||
APIDevice.updatePersonInfo(reqBody).then(res => { | |||
ToastService.clear(); | |||
console.log(res.data); | |||
if (res.data.stateCode == 1) { | |||
ToastService.success({ | |||
message: '保存成功' | |||
}); | |||
if (this.$route.query.from === 'watchSetting') { | |||
setTimeout(() => { | |||
this.$router.push({ | |||
name: 'watchSetting' | |||
}); | |||
}, 1500); | |||
} else if (this.$route.query.from === 'psychologicalSetting') { | |||
setTimeout(() => { | |||
this.$router.push({ | |||
name: 'psychologicalSetting', | |||
from: 'watchSetting' | |||
}); | |||
}, 1500); | |||
} else if (this.$route.query.from === 'login') { | |||
setTimeout(() => { | |||
this.$router.push({ | |||
name: 'bind' | |||
}); | |||
}, 1500); | |||
APIHealthUser.addPerson(reqBody) | |||
.then(res => { | |||
ToastService.clear(); | |||
console.log(res.data); | |||
if (res.data.stateCode == 1) { | |||
ToastService.success({ | |||
message: '保存成功' | |||
}); | |||
let from = this.params.from; | |||
if (from === 'watchSetting') { | |||
setTimeout(() => { | |||
this.$router.push({ | |||
name: 'watchSetting' | |||
}); | |||
}, 1500); | |||
} else if (from === 'psychologicalSetting') { | |||
setTimeout(() => { | |||
this.$router.push({ | |||
name: 'psychologicalSetting', | |||
from: 'watchSetting' | |||
}); | |||
}, 1500); | |||
} else if (from === 'login' || from === 'Index') { | |||
setTimeout(() => { | |||
this.$router.push({ | |||
name: 'deviceBinding' | |||
}); | |||
}, 1500); | |||
} | |||
} else { | |||
setTimeout(() => { | |||
this.$router.push({ | |||
name: 'psychologicalSetting', | |||
query: { from: 'psychologicalRegUserInfos', uid: this.uid } | |||
}); | |||
}, 1500); | |||
DialogService.confirm({ | |||
title: res.data.message | |||
}); | |||
} | |||
} else { | |||
}) | |||
.catch(e => { | |||
ToastService.clear(); | |||
DialogService.confirm({ | |||
title: res.data.message | |||
title: e.message || '服务器异常' | |||
}); | |||
} | |||
}); | |||
}); | |||
}, | |||
onCancelDate() { | |||
this.isDateShow = false; | |||
@@ -543,6 +585,29 @@ export default { | |||
}, | |||
formatBorndate(date) { | |||
return date == '' ? '' : new Date(this.$own.formatTime(date)).Format('yyyy-MM-dd'); | |||
}, | |||
chooseImage() { | |||
let that = this; | |||
wx.chooseImage({ | |||
count: 1, | |||
sizeType: ['compressed'], | |||
sourceType: ['album', 'camera'], | |||
success: function (res) { | |||
var localIds = res.localIds[0]; | |||
that.imagePath = localIds; //显示图片的 | |||
wx.getLocalImgData({ | |||
localId: localIds, | |||
success: function (res) { | |||
let localData = res.localData; | |||
if (localData.indexOf('data:image') < 0) { | |||
localData = 'data:image/jpeg;base64,' + localData; | |||
} | |||
localData = localData.replace(/\r|\n/g, '').replace('data:image/jgp', 'data:image/jpeg'); | |||
that.imagePath = localData; | |||
} | |||
}); | |||
} | |||
}); | |||
} | |||
} | |||
}; | |||
@@ -552,17 +617,15 @@ export default { | |||
height: 100vh; | |||
overflow: hidden; | |||
.main { | |||
position: relative; | |||
height: calc(100vh - 170px); | |||
height: calc(100vh - 100px); | |||
padding-top: 100px; | |||
background-color: #fff; | |||
.list { | |||
height: calc(100vh - 300px); | |||
position: relative; | |||
height: 75vh; | |||
background-color: #fff; | |||
border-radius: 8px; | |||
padding: 20px 0; | |||
overflow: scroll; | |||
z-index: 99; | |||
.avatar { | |||
position: relative; | |||
height: 240px; | |||
@@ -671,9 +734,9 @@ export default { | |||
} | |||
.bottom-btn { | |||
position: absolute; | |||
bottom: -40px; | |||
bottom: -60px; | |||
left: 0; | |||
height: 120px; | |||
height: 100px; | |||
width: 100%; | |||
@include center(); | |||
z-index: 999; | |||
@@ -19,7 +19,7 @@ | |||
<div class="submenu device-manage"> | |||
<SubmenuList :title="device.title" :list="device.list" rounded> | |||
<template #addDevice> | |||
<div class="add-device"><span>+</span></div> | |||
<div class="add-device" @click="onAddPerson"><span>+</span></div> | |||
</template> | |||
</SubmenuList> | |||
</div> | |||
@@ -293,6 +293,15 @@ export default { | |||
this.$router.push({ | |||
name: 'location' | |||
}); | |||
}, | |||
onAddPerson() { | |||
this.$router.push({ | |||
name: 'personInfos', | |||
query: { | |||
from: 'Myself', | |||
toRouter: 'Myself' | |||
} | |||
}); | |||
} | |||
} | |||
}; | |||
@@ -0,0 +1,801 @@ | |||
<template> | |||
<div class="relation"> | |||
<van-nav-bar title="设备使用者角色" left-arrow @click-left="onBack" /> | |||
<div class="title"> | |||
<div class="role-user-container"> | |||
<div class="radio-box" v-for="(item, index) in radios" :key="item.id"> | |||
<span class="radio" :class="{ on: item.isChecked }" @click="onChooseRole(item.value, index)"></span> | |||
<input | |||
v-model="roleRadio" | |||
:value="item.value" | |||
class="input-radio" | |||
:checked="item.isChecked" | |||
type="radio" | |||
/><label>{{ item.label }}</label> | |||
</div> | |||
</div> | |||
<p class="main">您是设备使用者的:</p> | |||
</div> | |||
<div class="content"> | |||
<div class="item" v-show="roleRadio === '1'"> | |||
<div | |||
class="list" | |||
v-for="(item, index) in listData" | |||
:key="`relation_${index}`" | |||
@click="listClick(index, item.name, item.className)" | |||
> | |||
<div :class="[item.className, 'img', { active: active == index }]"></div> | |||
<span>{{ item.name }}</span> | |||
</div> | |||
</div> | |||
<div class="item" v-show="roleRadio === '2'"> | |||
<div | |||
class="list" | |||
v-for="(item, index) in newListData" | |||
:key="`relation_${index}`" | |||
@click="newListClick(index, item.name, item.className)" | |||
> | |||
<div :class="[item.className, 'img', { active: active == index }]"></div> | |||
<span>{{ item.name }}</span> | |||
</div> | |||
</div> | |||
</div> | |||
<div class="submit" @click="submit">确定</div> | |||
<van-dialog | |||
v-model="selectConfirm" | |||
:show-cancel-button="true" | |||
:close-on-click-overlay="true" | |||
overlay-class="mask_device" | |||
@confirm="confirm" | |||
@cancel="cancel" | |||
@closed="onClosedDialog" | |||
> | |||
<div class="device_confirm"> | |||
<div class="title">请输入身份</div> | |||
<div class="dialog-container"> | |||
<label> | |||
<input type="text" v-model.trim="value" maxlength="8" /> | |||
</label> | |||
</div> | |||
</div> | |||
</van-dialog> | |||
</div> | |||
</template> | |||
<script> | |||
import ToastService from '@/services/toast-service'; | |||
import DialogService from '@/services/dialog-service'; | |||
import APIDevice from '@/api/device'; | |||
import APICommand from '@/api/command'; | |||
export default { | |||
data() { | |||
return { | |||
value: '', | |||
selectConfirm: false, | |||
listData: [ | |||
{ name: '爸爸', className: 'father' }, | |||
{ name: '妈妈', className: 'monther' }, | |||
{ name: '爷爷', className: 'grandpa' }, | |||
{ name: '奶奶', className: 'grandma' }, | |||
{ name: '姥爷', className: 'grandfather' }, | |||
{ name: '姥姥', className: 'grandmonther' }, | |||
{ name: '其他', className: 'other' } | |||
], | |||
newListData: [ | |||
{ name: '儿子', className: 'father' }, | |||
{ name: '女儿', className: 'monther' }, | |||
{ name: '侄子', className: 'grandpa' }, | |||
{ name: '侄女', className: 'grandma' }, | |||
{ name: '孙子', className: 'grandfather' }, | |||
{ name: '孙女', className: 'grandmonther' }, | |||
{ name: '其他', className: 'other' } | |||
], | |||
roleRadio: '1', | |||
radios: [ | |||
{ | |||
label: '学生', | |||
value: '1', | |||
isChecked: false | |||
}, | |||
{ | |||
label: '长辈', | |||
value: '2', | |||
isChecked: false | |||
} | |||
], | |||
active: -1, | |||
second: 5, | |||
navigate: { | |||
timer: null, | |||
second: 10 | |||
}, | |||
isFromInfos: null, //是否从用户信息页面跳转过来 | |||
infosData: null, //用户信息 | |||
isHasOtherName: null //是否有“其他" | |||
}; | |||
}, | |||
created() { | |||
this.checkRoute(); | |||
}, | |||
mounted() { | |||
/* this.checkEffective(); */ | |||
}, | |||
methods: { | |||
countDown(codeTime, isSubmit) { | |||
let codeInterval = window.setInterval(() => { | |||
if (--codeTime <= 0) { | |||
window.clearInterval(codeInterval); | |||
} | |||
ToastService.loading({ | |||
message: `设备初始化,请在${codeTime}秒后再操作绑定\n` | |||
}); | |||
if (codeTime <= 0) { | |||
ToastService.clear(); | |||
if (isSubmit) { | |||
setTimeout(() => { | |||
this.submit(); | |||
}, 800); | |||
} | |||
} | |||
}, 1000); | |||
}, | |||
checkRoute() { | |||
let params = this.$route.query; | |||
console.log('params', params); | |||
if (params) { | |||
if (params.fromRoute === 'infos') { | |||
this.isFromInfos = true; | |||
this.getInfos(); | |||
} else { | |||
this.radios[0].isChecked = true; | |||
} | |||
} | |||
}, | |||
// 获取用户信息 | |||
getInfos() { | |||
APIDevice.getPersonInfo({ userId: this.$store.getters.userId, deviceId: this.$store.getters.deviceId }).then( | |||
res => { | |||
if (res.data.stateCode === 1) { | |||
this.infosData = res.data; | |||
this.initRelation(); | |||
} else { | |||
DialogService.confirm({ | |||
title: res.data.message | |||
}).then(() => { | |||
this.$router.push({ name: 'infos' }); | |||
}); | |||
} | |||
} | |||
); | |||
}, | |||
// 初始化用户选择列表 | |||
initRelation() { | |||
const infosData = this.infosData; | |||
// 1. 初始化 学生 老人单选按钮 | |||
this.roleRadio = String(infosData.userRole); | |||
let radiosIndex = this.radios.findIndex(item => { | |||
return item.value === String(infosData.userRole); | |||
}); | |||
this.radios[radiosIndex].isChecked = true; | |||
// 2. 初始化 家长身份列表以及已经设置好的身份名字 | |||
let relationName = infosData.relationName; | |||
console.log('infosData', infosData); | |||
let currentList = String(infosData.userRole) === '1' ? this.listData : this.newListData; | |||
this.isHasOtherName = currentList.some(item => { | |||
return item.name === relationName; | |||
}); | |||
if (relationName === '其他' || !this.isHasOtherName) { | |||
// 存在其他或者不属于指定的家长身份 | |||
currentList = currentList.filter(item => { | |||
return item.name !== '其他'; | |||
}); | |||
this.active = 6; | |||
this.selectConfirm = true; | |||
this.value = relationName; | |||
console.log('1', currentList, relationName, currentList.includes(relationName)); | |||
} else { | |||
currentList = currentList.filter(item => { | |||
return item.name !== '其他'; | |||
}); | |||
this.active = currentList.findIndex(item => { | |||
return item.name === relationName; | |||
}); | |||
this.value = relationName; | |||
console.log('2', currentList, currentList.includes(relationName)); | |||
} | |||
}, | |||
// 返回 | |||
onBack() { | |||
if (this.isFromInfos) { | |||
this.$router.push({ name: 'infos' }); | |||
} else { | |||
this.$router.push({ name: 'deviceBinding' }); | |||
} | |||
}, | |||
// 判断是否需要显示中亿的自动激活功能 | |||
checkEffective() { | |||
if (this.$own.isNotNull(this.$route.query.iccid)) { | |||
this.effective(); | |||
} | |||
}, | |||
// 中亿物联联通卡 SIM自动激活 | |||
async effective() { | |||
let reqBody = { | |||
imei: this.$route.query.serialNo, | |||
iccid: this.$route.query.iccid, | |||
issue: 0 | |||
}; | |||
APICommand.Effective(reqBody) | |||
.then(res => { | |||
console.log('res', res); | |||
let data = res.data; | |||
if (data.stateCode === 0) { | |||
DialogService.confirm({ title: 'SIM卡激活失败', message: '请进行实名认证与绑定SIM卡' }); | |||
} else if (data.stateCode === 1 && data.message !== 'ok') { | |||
DialogService.confirm({ title: 'SIM卡激活成功', message: '卡激活成功,5分钟后则可正常使用。' }); | |||
} | |||
}) | |||
.catch(error => { | |||
console.log('出错了:;', error); | |||
}); | |||
}, | |||
listClick(index, name, className) { | |||
this.active = index; | |||
if (className == 'other') { | |||
if (this.isFromInfos) { | |||
// 如果是从用户信息页面过来的,点击列表的时候如果是其他,value 则为relationName,否则为空 | |||
this.value = this.isHasOtherName ? '' : this.infosData.relationName; | |||
} else { | |||
this.value = ''; | |||
} | |||
this.selectConfirm = !this.selectConfirm; | |||
} else { | |||
this.value = name; | |||
} | |||
}, | |||
newListClick(index, name, className) { | |||
this.active = index; | |||
if (className == 'other') { | |||
if (this.isFromInfos) { | |||
// 如果是从用户信息页面过来的,点击列表的时候如果是其他,value 则为relationName,否则为空 | |||
this.value = this.isHasOtherName ? '' : this.infosData.relationName; | |||
} else { | |||
this.value = ''; | |||
} | |||
this.selectConfirm = !this.selectConfirm; | |||
} else { | |||
this.value = name; | |||
} | |||
}, | |||
confirm() {}, | |||
cancel() { | |||
if (!this.isFromInfos) { | |||
this.value = ''; | |||
} | |||
}, | |||
onClosedDialog() { | |||
let iconRule = | |||
// eslint-disable-next-line no-misleading-character-class, no-useless-escape | |||
/[\uD83C|\uD83D|\uD83E][\uDC00-\uDFFF][\u200D|\uFE0F]|[\uD83C|\uD83D|\uD83E][\uDC00-\uDFFF]|[0-9|*|#]\uFE0F\u20E3|[0-9|#]\u20E3|[\u203C-\u3299]\uFE0F\u200D|[\u203C-\u3299]\uFE0F|[\u2122-\u2B55]|\u303D|[\A9|\AE]\u3030|\uA9|\uAE|\u3030/gi; | |||
if (iconRule.test(this.value)) { | |||
DialogService.confirm({ title: '不能输入表情字符哦' }).then(() => (this.selectConfirm = true)); | |||
} | |||
}, | |||
onChooseRole(value, index) { | |||
console.log('选中的是', value); | |||
// 先取消所有选中项 | |||
this.radios.forEach(item => { | |||
item.isChecked = false; | |||
}); | |||
//再设置当前点击项选中 | |||
this.roleRadio = this.radios[index].value; | |||
// 设置值,以供传递 | |||
this.radios[index].isChecked = true; | |||
this.value = ''; | |||
this.active = -1; | |||
}, | |||
submit() { | |||
if (this.value == '') { | |||
DialogService.confirm({ title: '请选择家长身份', message: '若选择【其他】身份请不要留空' }); | |||
} else { | |||
// this.bindDevice(); | |||
// this.bindDeviceNew(); | |||
if (this.isFromInfos) { | |||
// 调取保存用户信息接口 | |||
this.updateInfos(); | |||
} else { | |||
//正常绑定设备 | |||
this.bindDevice(); | |||
} | |||
/* if(process.env.NODE_ENV === 'production'){ | |||
this.bindDevice(); | |||
} else { | |||
this.bindDeviceNew(); | |||
// 修改 测试环境的接口调用 | |||
this.bindDevice(); | |||
} */ | |||
} | |||
}, | |||
updateInfos() { | |||
let jsonData = this.infosData; | |||
jsonData.userRole = Number(this.roleRadio); | |||
jsonData['userId'] = this.$store.getters.userId; | |||
jsonData['relationName'] = this.value; | |||
console.log('请求的参数', jsonData); | |||
APIDevice.updatePersonInfo(jsonData) | |||
.then(res => { | |||
ToastService.clear(); | |||
console.log(res.data); | |||
if (res.data.stateCode == 1) { | |||
ToastService.success({ | |||
message: '保存成功', | |||
onClose: () => this.onBack() | |||
}); | |||
} else { | |||
DialogService.confirm({ | |||
title: res.data.message | |||
}); | |||
} | |||
}) | |||
.catch(() => {}) | |||
.finally(() => { | |||
//ToastService.clear(); | |||
}); | |||
}, | |||
bindDevice() { | |||
/* const url = '/api/Device/BindDevice'; | |||
const headers = { headers: { AuthToken: this.$store.getters.authToken } }; | |||
const body = { | |||
userId: this.$store.getters.userId, | |||
serialNo: this.$route.query.serialNo, | |||
relationName: this.value, | |||
requestMessage: `` | |||
}; */ | |||
ToastService.loading({}); | |||
/* this.$axios.post(url, body, headers) */ | |||
APIDevice.bindDevice({ | |||
headers: { AuthToken: this.$store.getters.authToken }, | |||
body: { | |||
userId: this.$store.getters.userId, | |||
serialNo: this.$route.query.serialNo, | |||
relationName: this.value, | |||
roleUser: Number(this.roleRadio), | |||
requestMessage: `` | |||
} | |||
}) | |||
.then(res => { | |||
// ToastService.clear(); | |||
if (res.data.stateCode === 1) { | |||
if (this.$route.query.isAdmin) { | |||
// 该申请为管理员,直接提示绑定成功,缓存serialNo | |||
this.$store.commit('serialNo', this.$route.query.serialNo); | |||
this.$store.commit('bindSerialNo', this.$route.query.serialNo); | |||
DialogService.confirm({ | |||
title: '绑定成功' | |||
}).then(() => { | |||
this.$router.push({ | |||
name: 'Index', | |||
query: { isBinding: true, bindSerialNo: this.$route.query.serialNo } | |||
}); | |||
}); | |||
this.navigator(true); | |||
} else { | |||
// 该申请为家属,需要提示用户等待管理员的通过,不可缓存serialNo | |||
DialogService.confirm({ | |||
title: '申请成功', | |||
message: '设备管理员同意通过便可查看宝贝信息,请耐心等待' | |||
}).then(() => { | |||
this.$router.push({ name: 'Index' }); | |||
}); | |||
this.navigator(false); | |||
} | |||
} else if (res.data.stateCode === 2) { | |||
DialogService.confirm({ title: '绑定成功', message: res.data.message }).then(() => { | |||
this.$router.push({ name: 'Index' }); | |||
}); | |||
this.navigator(false); | |||
} else if (res.data.message.indexOf('设备不在线') > -1) { | |||
DialogService.confirm({ title: '绑定失败', message: '设备不在线!请重新关机再开机,设备联网后再重试。' }); | |||
return; | |||
} else if ( | |||
res.data.stateCode === 0 && | |||
res.data.message.indexOf('您已经绑定了宝贝信息,请勿重复绑定!') > -1 | |||
) { | |||
// 2022 04 25 修改重复绑定文案 | |||
DialogService.confirm({ | |||
title: '绑定失败', | |||
message: '您已绑定了随手精灵设备,请勿重复绑定!如设备显示未激活,请重启设备!', | |||
messageAlign: 'left' | |||
}); | |||
return; | |||
} else if (res.data.stateCode === 3) { | |||
// 2023.11.26 绑定需求变更,返回状态码为3时进行以下操作 | |||
let countdown = res.data.data; | |||
if (countdown > 5) { | |||
// 倒计时大于5秒,不需要倒计时完成后继续提交 | |||
this.countDown(countdown, false); | |||
} else { | |||
// 小于5秒,倒计时完成后立即提交 | |||
this.countDown(countdown, true); | |||
} | |||
} else { | |||
DialogService.confirm({ title: '绑定失败', message: res.data.message }); | |||
} | |||
}) | |||
.catch(e => { | |||
console.log(e); | |||
}) | |||
.finally(() => ToastService.clear()); | |||
}, | |||
bindDeviceNew() { | |||
this.clearNaviagtor(); | |||
// const url = `/api/Device/BindDevice`; | |||
/* const url = `/api/Device/BindDeviceSsjl`; | |||
const headers = { headers: { AuthToken: this.$store.getters.authToken } }; | |||
const body = { | |||
userId: this.$store.getters.userId, | |||
serialNo: this.$route.query.serialNo, | |||
relationName: this.value, | |||
requestMessage: `` | |||
}; */ | |||
const toast = ToastService.loading({ | |||
duration: 0, // 持续展示 toast | |||
forbidClick: true | |||
// message: `下发中请稍后`, | |||
}); | |||
/* this.$axios.post(url, body, headers) */ | |||
APIDevice.bindDeviceSsjl({ | |||
headers: { AuthToken: this.$store.getters.authToken }, | |||
body: { | |||
userId: this.$store.getters.userId, | |||
serialNo: this.$route.query.serialNo, | |||
relationName: this.value, | |||
requestMessage: `` | |||
} | |||
}) | |||
.then(res => { | |||
if (res.data.stateCode === 1) { | |||
// ok | |||
const timer = setInterval(() => { | |||
this.second--; | |||
if (this.second >= 0) { | |||
toast.message = this.second ? `设备搜索中(${this.second})` : `设备搜索中`; | |||
} else { | |||
clearInterval(timer); | |||
ToastService.clear(); | |||
// 5 秒后调取查询结果 | |||
this.bindDeviceResult(); | |||
this.second = 5; | |||
} | |||
}, 1000); | |||
} else if ( | |||
res.data.stateCode === 0 && | |||
res.data.message.indexOf('您已经绑定了宝贝信息,请勿重复绑定!') > -1 | |||
) { | |||
// 2022 04 25 修改重复绑定文案 | |||
DialogService.confirm({ | |||
title: '绑定失败', | |||
message: '您已绑定了随手精灵设备,请勿重复绑定!如设备显示未激活,请重启设备!', | |||
messageAlign: 'left' | |||
}); | |||
return; | |||
} else { | |||
ToastService.clear(); | |||
DialogService.confirm({ title: '绑定失败', message: res.data.message }); | |||
} | |||
}) | |||
.catch(e => { | |||
console.log(e); | |||
ToastService.clear(); | |||
}); | |||
}, | |||
bindDeviceResult() { | |||
/* const url = `/api/Device/BindDeviceResult`; | |||
const headers = { headers: { AuthToken: this.$store.getters.authToken } }; | |||
const body = { | |||
userId: this.$store.getters.userId, | |||
serialNo: this.$route.query.serialNo, | |||
relationName: this.value, | |||
requestMessage: `` | |||
}; */ | |||
ToastService.loading({ | |||
duration: 0, // 持续展示 toast | |||
message: `激活中,请稍侯` | |||
}); | |||
/* this.$axios | |||
.post(url, body, headers) */ | |||
APIDevice.bindDeviceResult({ | |||
headers: { AuthToken: this.$store.getters.authToken }, | |||
body: { | |||
userId: this.$store.getters.userId, | |||
serialNo: this.$route.query.serialNo, | |||
relationName: this.value, | |||
requestMessage: `` | |||
} | |||
}) | |||
.then(res => { | |||
if (res.data.stateCode === 1) { | |||
if (this.$route.query.isAdmin) { | |||
// 该申请为管理员,直接提示绑定成功,缓存serialNo | |||
this.$store.commit('serialNo', this.$route.query.serialNo); | |||
this.$store.commit('bindSerialNo', this.$route.query.serialNo); | |||
DialogService.confirm({ | |||
title: '绑定成功' | |||
}).then(() => { | |||
this.$router.push({ | |||
name: 'Index', | |||
query: { isBinding: true, bindSerialNo: this.$route.query.serialNo } | |||
}); | |||
this.clearNaviagtor(); | |||
}); | |||
this.navigator(true); | |||
} else { | |||
// 该申请为家属,需要提示用户等待管理员的通过,不可缓存serialNo | |||
DialogService.confirm({ | |||
title: '申请成功', | |||
message: '设备管理员同意通过便可查看宝贝信息,请耐心等待' | |||
}).then(() => { | |||
this.$router.push({ name: 'Index' }); | |||
this.clearNaviagtor(); | |||
}); | |||
this.navigator(false); | |||
} | |||
} else if (res.data.stateCode === 2) { | |||
DialogService.confirm({ title: '绑定成功', message: res.data.message }).then(() => { | |||
this.$router.push({ name: 'Index' }); | |||
this.clearNaviagtor(); | |||
}); | |||
this.navigator(false); | |||
} else if ( | |||
res.data.stateCode === 0 && | |||
res.data.message.indexOf('您已经绑定了宝贝信息,请勿重复绑定!') > -1 | |||
) { | |||
// 2022 04 25 修改重复绑定文案 | |||
DialogService.confirm({ | |||
title: '绑定失败', | |||
message: '您已绑定了随手精灵设备,请勿重复绑定!如设备显示未激活,请重启设备!', | |||
messageAlign: 'left' | |||
}); | |||
return; | |||
} else { | |||
DialogService.confirm({ title: '绑定失败', message: res.data.message }); | |||
} | |||
}) | |||
.finally(() => ToastService.clear()); | |||
}, | |||
navigator(isBinding) { | |||
this.navigate.timer = setTimeout(() => { | |||
console.log('timer work'); | |||
DialogService.close(); | |||
this.$router.push({ name: 'Index', query: { isBinding: isBinding || false } }); | |||
}, this.navigate.second * 1000); | |||
}, | |||
clearNaviagtor() { | |||
clearTimeout(this.navigate.timer); | |||
} | |||
} | |||
}; | |||
</script> | |||
<style scoped lang="scss"> | |||
.relation { | |||
background: #fff !important; | |||
.title { | |||
display: flex; | |||
justify-content: flex-start; | |||
align-items: flex-start; | |||
flex-direction: column; | |||
height: auto; | |||
margin: 40px 0 5px 0; | |||
padding: 0 40px; | |||
p { | |||
@include center(); | |||
@include colorAndFont(#999, 35); | |||
&.main { | |||
margin: 30px 0 0 60px; | |||
@include colorAndFont(#333, 32); | |||
} | |||
} | |||
.role-user-container { | |||
display: flex; | |||
justify-content: flex-start; | |||
margin-left: 40px; | |||
.radio-box { | |||
display: flex; | |||
justify-content: flex-start; | |||
align-items: center; | |||
height: 60px; | |||
margin-right: 10px; | |||
margin-left: 20px; | |||
.radio { | |||
display: inline-block; | |||
width: 20px; | |||
height: 20px; | |||
border-radius: 30px; | |||
border: gray solid 2px; | |||
&.on { | |||
border: #2599ff solid 15px; | |||
} | |||
} | |||
.input-radio { | |||
display: inline-block; | |||
position: absolute; | |||
/* opacity: 0; */ | |||
width: 30px; | |||
height: 30px; | |||
left: 0px; | |||
} | |||
label { | |||
@include colorAndFont(#333, 32); | |||
margin-left: 15px; | |||
} | |||
} | |||
} | |||
} | |||
.content { | |||
.item { | |||
padding: 0 80px; | |||
display: flex; | |||
justify-content: space-between; | |||
flex-wrap: wrap; | |||
.list { | |||
width: 140px; | |||
display: flex; | |||
align-items: center; | |||
flex-flow: column; | |||
margin: 0 85px 50px 0; | |||
&:nth-child(3n) { | |||
margin-right: 0; | |||
} | |||
.img { | |||
position: relative; | |||
width: 140px; | |||
height: 140px; | |||
background: #f1f5f9; | |||
border: 2px solid transparent; | |||
border-radius: 50%; | |||
box-sizing: border-box; | |||
@include center(); | |||
&.active { | |||
border-color: #2599ff; | |||
background: #e0f0ff; | |||
&:after { | |||
content: ' '; | |||
position: absolute; | |||
right: -6px; | |||
bottom: 14px; | |||
width: 38px; | |||
height: 38px; | |||
border-radius: 50%; | |||
@include icon; | |||
@include icon_position(38, 38, 306, 56); | |||
} | |||
} | |||
&:before { | |||
content: ''; | |||
width: 80px; | |||
height: 80px; | |||
@include head(); | |||
} | |||
&.father:before { | |||
@include head_position(0, 0); | |||
} | |||
&.monther:before { | |||
@include head_position(100, 0); | |||
} | |||
&.grandpa:before { | |||
@include head_position(0, 85); | |||
} | |||
&.grandma:before { | |||
@include head_position(100, 85); | |||
} | |||
&.grandfather:before { | |||
@include head_position(0, 170); | |||
} | |||
&.grandmonther:before { | |||
@include head_position(100, 170); | |||
} | |||
&.other:before { | |||
@include head_position(0, 250); | |||
} | |||
} | |||
span { | |||
line-height: 1; | |||
@include colorAndFont(#333, 32); | |||
margin-top: 20px; | |||
} | |||
} | |||
} | |||
} | |||
.submit { | |||
@include center(); | |||
margin: 20px auto; | |||
width: 578px; | |||
height: 88px; | |||
background: $blue; | |||
color: #fff; | |||
font-size: 34px; | |||
border-radius: 10px; | |||
} | |||
.device_confirm { | |||
.title { | |||
@include center(); | |||
@include colorAndFont(#333, 34); | |||
padding: 40px px2rem(60); | |||
} | |||
.dialog-container { | |||
padding: 10px 40px 50px; | |||
@include colorAndFont(#666, 30); | |||
label { | |||
@include center(); | |||
input { | |||
// width: 100%; | |||
display: flex; | |||
height: 72px; | |||
background: #e8ecef; | |||
border-radius: 10px; | |||
text-indent: 15px; | |||
} | |||
} | |||
&.phone { | |||
padding: 0 40px; | |||
text-align: center; | |||
box-sizing: border-box; | |||
.tit { | |||
padding: 30px 0 4px; | |||
@include colorAndFont(#333, 34); | |||
font-weight: 500; | |||
line-height: 100px; | |||
} | |||
p { | |||
padding: 0 50px; | |||
@include colorAndFont(#999, 28); | |||
margin-bottom: 40px; | |||
} | |||
input { | |||
display: flex; | |||
width: 100%; | |||
height: 70px; | |||
border-radius: 10px; | |||
background-color: #e8ecef; | |||
margin-bottom: 30px; | |||
text-align: center; | |||
} | |||
} | |||
} | |||
} | |||
} | |||
</style> |
@@ -20,11 +20,7 @@ module.exports = defineConfig({ | |||
open: false, // 启动后打开浏览器 | |||
hot: true, //热更新 | |||
client: { | |||
overlay: { | |||
// 当出现编译器错误或警告时,在浏览器中显示全屏覆盖层 | |||
warnings: false, | |||
errors: false | |||
} | |||
overlay: false //报错是否显示遮罩层,不显示 | |||
} | |||
// proxy: { | |||
// //配置跨域 | |||