Commit 8f7acb3f authored by kang.nie@inzymeits.com's avatar kang.nie@inzymeits.com
Browse files

初始化代码

parent 2d7d3f82
Pipeline #3104 failed with stages
in 0 seconds
<template>
<Page class="page-rnr-person-card">
<template #slot-title>
<span>1/{{ totalFlow }}</span>
<span>车卡信息</span>
</template>
<VinScan ref="vinScanRef" @change="handleChangeVin" />
<div class="page-rnr-main-card page-rnr-main-card-iccid">
<div class="page-rnr-main-card-title">
<div class="page-rnr-main-card-title-tl">ICCID</div>
<div class="page-rnr-main-card-title-tr">{{ iccidList.length }}/5</div>
</div>
<List v-model="iccidList" @click="handleOpenEditIccid" />
<van-button class="rnr-main-card-add-btn" plain hairline round block color="#0761F3" @click="handleOpenAddIccid"><i class="imageicon imageicon-add" />添加</van-button>
</div>
<template #slot-operation>
<van-button :disabled="iccidList.length === 0" :loading="submitLoading" type="primary" class="page-rnr-main-btn-next" round color="linear-gradient(120deg, #4F4CFB 0%, #376FF4 97%)" block @click="handleToNext">下一步</van-button>
</template>
<InputActionSheet
:title="addType === 'add' ? '添加卡号' : '修改卡号'"
:rules="{ iccid: 'iccid' }"
:data="newIccid"
:visible.sync="showAddVin"
label="ICCID"
@submit="handleAddIccid"
/>
</Page>
</template>
<script>
import Page from '@/components/Page'
import List from '@/components/List'
import InputActionSheet from '@/components/InputActionSheet'
import VinScan from '@/components/VinScan'
import ErrorWrap from '@/components/ErrorWrap.vue'
import { getIccidListByVin, getBindIccidListByVin, verifyVinCards } from '@/api/rnr'
import { Toast } from 'vant'
import flowMixin from '@/minxin/flow'
import { SET_PERSON_CARD } from '@/store/modules/rnr'
export default {
name: 'RnrPersonCard',
components: { Page, ErrorWrap, VinScan, List, InputActionSheet },
mixins: [flowMixin],
data() {
const { customerType } = this.$route.query
return {
addType: 'add',
customerType: +customerType,
isConsigner: +this.$route.query.isConsigner === 1,
isLoading: false,
vin: '',
newIccid: '',
showSearchBtn: true,
showAddVin: false,
submitLoading: false,
iccidList: []
}
},
methods: {
/**
* 改变vin码
* @param vin 当前输入的vin码
*/
handleChangeVin(vin) {
// 如果当前输入的内容和之前输入的vin不一致,则需要展示搜索按钮
if (vin !== this.vin) {
this.showSearchBtn = true
}
// 记下当前输入的vin码
this.vin = vin
// 如果校验失败,则不请求接口
if (`${vin}`.length !== 17) {
return
}
// 查询一遍vin码
this.handleFetchIccidByVin()
},
/**
* 通过vin号搜索iccid的集合
* @param value
*/
async handleFetchIccidByVin() {
// 获取输入的vin号
const vin = this.vin
// 展示loading
this.isLoading = true
try {
// 当前iccid的集合
const { iccidList } = await (this.customerType === 1 ? getBindIccidListByVin : getIccidListByVin)({ vin })
// 不展示搜索
this.showSearchBtn = false
// 页面开始渲染
this.iccidList = iccidList
} catch (error) {
console.error(error)
}
// 展示loading
this.isLoading = false
},
/**
* 编辑指定的iccid
* @param index 当前需要编辑的iccid
*/
handleOpenEditIccid(iccid, index) {
// 标记当前是编辑
this.addType = 'edit'
// 展示弹框
this.showAddVin = true
// 当前的iccid
this.newIccid = iccid
// 记住当前编辑的索引
this.editIndex = index
},
/**
* 新增一条iccid
*/
handleOpenAddIccid() {
// 标记当前是编辑
this.addType = 'add'
// 展示弹框
this.showAddVin = true
// 清空iccid
this.newIccid = ''
},
/**
* 新增一条iccid数据
*/
handleAddIccid(iccid) {
// 关闭弹框
this.showAddVin = false
// 如果当年是新增
if (this.addType === 'add') {
// 开始添加一条iccid
this.iccidList.push(iccid)
} else {
this.$set(this.iccidList, this.editIndex, iccid)
}
// 清空数据
this.newIccid = ''
},
/**
* 跳转到下一页
*/
async handleToNext() {
// 如果vin号输入不正确
if (!this.vin) {
return
}
// 如果校验失败,则不请求接口
if (`${this.vin}`.length !== 17) {
return
}
// 如果vin-scan中输入的vin长度不等于17位
if (this.$refs.vinScanRef.vin.length !== 17) {
return
}
// 如果当前没有输入或选择iccid
if (this.iccidList.length === 0) {
Toast('请至少添加1个ICCID号')
return
}
// 如果当前iccid超过5个
if (this.iccidList.length > 5) {
Toast('ICCID号最多不能超过5个')
return
}
// 展示loading框
this.submitLoading = true
try {
// 校验vin号和iccid是否合法
await verifyVinCards({
businessType: this.customerType === 0 ? 1 : 2,
vin: this.vin,
iccidList: this.iccidList
})
} catch (error) {
// 关闭loading框
this.submitLoading = false
return
}
// 关闭loading框
this.submitLoading = false
// 开始保存数据
this.$store.commit(`rnr/${SET_PERSON_CARD}`, {
customerType: +this.$route.query.customerType || 0,
isConsigner: this.isConsigner,
vin: this.vin,
iccidList: this.iccidList
})
// 开始跳转页面
this.$router.push({ name: 'RnrPersonIdcard', query: { step: 2 }})
}
}
}
</script>
<style lang="scss">
.page-rnr-person-card {
.van-field__button {
margin-left: 0px;
padding-left: 24px;
.page-rnr-icon-scan {
background-image: url(../../../assets/rnr/ico_scan.svg);
background-size: 100% 100%;
width: 30px;
height: 30px;
}
}
.page-rnr-main-fixed-btn-group {
.page-rnr-main-btn-next {
height: 96px;
}
}
.page-rnr-main-iccid-icon-del {
background-image: url(../../../assets/rnr/ico_del.png);
background-size: 100% 100%;
width: 30px;
height: 30px;
}
.page-rnr-main-iccid-icon-close {
background-image: url(../../../assets/rnr/ico_close.png);
background-size: 100% 100%;
width: 30px;
height: 30px;
}
.page-rnr-main-card-btn-iccid-add {
padding: 0 24px;
.page-rnr-main-card-btn-iccid {
margin-top: 24px;
.van-icon {
margin-right: 14px;
}
}
}
.page-rnr-main-iccid-container {
padding: 0px 24px;
.page-rnr-main-iccid-item {
background-image: linear-gradient(121deg, #617DFF 0%, #AEC6FF 98%);
border-radius: 16px;
display: flex;
height: 125px;
margin-top: 12px;
position: relative;
.page-rnr-main-iccid-item-icon {
background-image: url(../../../assets/rnr/ico_iccid.png);
background-size: 100% 100%;
width: 110px;
height: 101px;
margin: 24px 36px 0 42px;
}
.page-rnr-main-iccid-item-split {
background: #FFFFFF;
display: block;
width: 1px;
height: 80px;
opacity: 0.29;
margin-top: 20px;
}
.van-cell {
background-color: transparent;
padding: 0 16px 0 40px !important;
height: 45px;
margin-top: 40px;
.van-field__control {
color: #FFFFFF !important;
font-size: 32px !important;
font-weight: 400 !important;
}
.van-field__button {
padding-left: 60px;
}
}
&:first-child {
margin-top: 0;
}
&:before {
background-image: url(../../../assets/rnr/gradient.png);
background-size: 100% 100%;
content: "";
display: block;
position: absolute;
top: -12px;
left: 0px;
right: 0px;
height: 24px;
z-index: -1;
}
}
::-webkit-input-placeholder {
color: rgba(255, 255, 255, 0.4) !important;
font-weight: 400;
}
:-moz-placeholder {
color: rgba(255, 255, 255, 0.4) !important;
font-weight: 400;
}
::-moz-placeholder {
color: rgba(255, 255, 255, 0.4) !important;
font-weight: 400;
}
:-ms-input-placeholder {
color: rgba(255, 255, 255, 0.4) !important;
font-weight: 400;
}
}
.page-rnr-action-sheet {
padding: 30px;
.page-rnr-action-sheet-title {
color: #242424;
font-size: 32px;
font-weight: 500;
line-height: 45px;
padding: 0 0 0 24px;
}
.van-cell {
background-color: transparent;
padding: 0;
&.van-field {
background-color: transparent;
padding: 44px 26px;
position: relative;
.van-field__label {
color: #242424;
font-size: 32px;
font-weight: 400;
height: 45px;
}
.van-cell__value {
height: 45px;
.van-field__control {
color: #242424;
font-size: 32px;
}
&.van-field__value {
position: relative;
.van-field__error-message {
position: absolute;
left: -220px;
bottom: -90px;
}
}
}
}
&.van-cell--required {
.van-cell__title {
span {
padding-left: 20px;
}
}
&:before {
left: 0px;
font-size: 16px;
}
}
.van-cell__title {
span {
color: #242424;
font-size: 32px;
font-weight: 400;
}
}
.van-cell__label {
margin-top: 36px;
}
&:after {
position: absolute;
box-sizing: border-box;
content: ' ';
pointer-events: none;
right: 0px;
bottom: 0;
left: 0px;
border-bottom: 1PX solid #ebedf0 !important;
transform: scaleY(.5);
}
}
.page-rnr-action-sheet-btn {
margin: 112px 0px 88px;
}
}
.page-rnr-main-card-iccid {
padding-bottom: 36px !important;
.page-rnr-main-card-title {
align-items: center;
display: flex;
height: 46px;
padding: 30px 0 48px;
justify-content: space-between;
.page-rnr-main-card-title-tl {
color: #242424;
font-size: 32px;
font-weight: 500;
flex-shrink: 0;
}
.page-rnr-main-card-title-tr {
color: #CACACA;
font-size: 32px;
flex-shrink: 0;
}
}
.rnr-main-card-add-btn {
margin-top: 24px;
.imageicon {
margin-bottom: -4px;
margin-right: 12px;
}
}
}
}
</style>
<template>
<Page class="page-rnr-person-base">
<template #slot-title>
<span>{{ currentFlow }}/{{ totalFlow }}</span>
<span>代办人身份信息</span>
</template>
<UserInfo :value="formData" :cert-type="personRnr.consignerInfo.certType" ref="userRef" type="bluetooth" />
<template slot="slot-operation">
<van-button type="primary" class="page-rnr-main-btn-before" round color="linear-gradient(120deg, #EDF3FF 0%, #E9F0FF 97%)" @click="handleToBefore">上一步</van-button>
<van-button type="primary" class="page-rnr-main-btn-next" round color="linear-gradient(120deg, #4F4CFB 0%, #376FF4 97%)" @click="handleToNext">下一步</van-button>
</template>
</Page>
</template>
<script>
import { mapGetters } from 'vuex'
import Page from '@/components/Page'
import UserInfo from '@/components/UserInfo'
import flowMixin from '@/minxin/flow'
import { SET_PERSON_CONSIGNER_CARD } from '@/store/modules/rnr'
export default {
name: 'RnrPersonConsignerBase',
components: { Page, UserInfo },
mixins: [flowMixin],
data() {
return {
isConnect: false,
formData: {
certAddress: '',
certExpirationDate: '',
certNumber: '',
contactAddress: '',
fullName: '',
gender: ''
}
}
},
computed: {
...mapGetters(['personRnr'])
},
methods: {
/**
* 调到到下一页:腾讯的实名认证平台
*/
handleToNext() {
// 校验不通过的字段
try {
const formData = this.$refs.userRef.validate()
// 将当前数据保存到store中
this.$store.commit(`rnr/${SET_PERSON_CONSIGNER_CARD}`, formData)
// 跳转到文件上传页
this.routerToNextPage('RnrPersonFile')
} catch (error) {
console.error('校验失败:', error)
}
},
/**
* 跳转到上一页
*/
handleToBefore() {
// 回退到上个页面
this.$router.back()
}
}
}
</script>
<style lang="scss">
.page-rnr-person-base {
.page-rnr-main-card {
.page-rnr-person-base-icon-idcard-reader {
background-image: url(../../../assets/rnr/ico_idcard_reader.png);
background-size: 100% 100%;
width: 654px;
height: 272px;
margin: 0 auto;
}
.page-rnr-person-base-step {
color: #242424;
font-size: 24px;
text-align: center;
font-weight: 400;
line-height: 34px;
margin-top: 10px;
&:first-child {
margin-top: 20px;
}
}
.page-rnr-person-base-btn-wrap {
margin-top: 56px;
.van-button {
font-size: 30px;
.page-rnr-person-base-icon-bluetooth {
background-image: url(../../../assets/rnr/ico_bluetooth.png);
background-size: 100% 100%;
display: inline-block;
width: 30px;
height: 30px;
margin-right: 12px;
margin-bottom: -4px;
}
}
.page-rnr-person-base-btn-block {
align-items: center;
border-radius: 50%;
color: #0761F3;
display: flex;
font-size: 30px;
height: 88px;
justify-content: center;
margin-top: 24px;
.page-rnr-person-base-icon-switch {
background-image: url(../../../assets/rnr/ico_switch.png);
background-size: 100% 100%;
display: inline-block;
width: 30px;
height: 30px;
margin-right: 12px;
margin-bottom: -4px;
}
}
}
&.base-intro {
padding: 26px 24px 40px !important;
}
}
.page-rnr-main-fixed-btn-group {
display: flex;
justify-content: space-between;
.page-rnr-main-btn-before {
color: #242424 !important;
flex: 1;
height: 96px;
}
.page-rnr-main-btn-next {
flex: 2;
margin-left: 40px;
height: 96px;
}
}
.van-cell__label {
.page-rnr-flex {
display: flex;
justify-content: space-between;
}
}
}
</style>
<template>
<Page class="page-rnr-person-idcard">
<template #slot-title>
<span>{{ currentFlow }}/{{ totalFlow }}</span>
<span>代办人证件信息</span>
</template>
<template #slot-before-main>
<div class="page-rnr-person-idcard-tip">文件类型为图片文件,允许支持的照片格式包括bmp、jpg/jpeg、png,小于500K。</div>
</template>
<div class="page-rnr-main-card">
<!-- 身份证选择上传 -->
<FormRender
ref="formRenderRef"
v-if="formData.certType === 'IDCARD'"
v-model="formData"
:schema="SCHEMA1"
@change="handleFormDataChange"
/>
<!-- 其他证件照片的选择上传 -->
<FormRender
ref="formRenderRef"
v-else
v-model="formData"
:schema="SCHEMA2"
@change="handleFormDataChange"
/>
</div>
<MustKnow />
<template slot="slot-operation">
<van-button type="primary" class="page-rnr-main-btn-before" round color="linear-gradient(120deg, #EDF3FF 0%, #E9F0FF 97%)" @click="handleToBefore">上一步</van-button>
<van-button :disabled="!formData.certPic[0] || !formData.certPic[1]" type="primary" class="page-rnr-main-btn-next" round color="linear-gradient(120deg, #4F4CFB 0%, #376FF4 97%)" @click="handleToNext">下一步</van-button>
</template>
</Page>
</template>
<script>
import cache from '@/utils/cache'
import { cuscImageUpload } from '@/api/rnr'
import Page from '@/components/Page'
import MustKnow from '@/components/MustKnow'
import FormRender from '@/components/FormRender'
import { SET_PERSON_CONSIGNER_CARD } from '@/store/modules/rnr'
import flowMixin from '@/minxin/flow'
export default {
name: 'RnrPersonCard',
components: { Page, FormRender, MustKnow },
mixins: [flowMixin],
data() {
const { CARD_TYPE } = this.$store.getters.dict
return {
formData: {
certType: 'IDCARD',
certPic: []
},
SCHEMA1: {
certType: {
label: '证件类型',
type: 'rnr-select',
rules: [
{ required: true }
],
options: CARD_TYPE
},
certPic: {
type: 'rnr-idcard',
compress: {},
api: file => cuscImageUpload({ file }).then(resp => resp.uuid),
rules: [
{ required: true },
{
validator(value) {
// 如果人像面没有上传
if (!value[0] || value[0].length === 0) {
return { result: false, message: '请上传身份证人像面' }
}
if (!value[1] || value[1].length === 0) {
return { result: false, message: '请上传身份证国徽面' }
}
return true
}
}
]
}
},
SCHEMA2: {
certType: {
label: '证件类型',
type: 'rnr-select',
rules: [
{ required: true }
],
options: CARD_TYPE
},
certPic: {
type: 'rnr-file',
size: 'large',
compress: {},
maxCount: 2,
api: file => cuscImageUpload({ file }).then(resp => resp.uuid),
rules: [
{ required: true },
{
validator(value) {
// 如果人像面没有上传
if (!value[0] || value[0].length === 0) {
return { result: false, message: '请上传证件信息正面' }
}
if (!value[1] || value[1].length === 0) {
return { result: false, message: '请上传证件信息反面' }
}
return true
}
}
]
}
}
}
},
methods: {
/**
* 表单项改变方法
* @param value 当前双向绑定的值
* @param key 当前改变的字段key
*/
handleFormDataChange(value, key) {
if (key === 'certType') {
this.formData.certPic = []
}
},
/**
* 跳转到上一页
*/
handleToBefore() {
// 回退到上个页面
this.$router.back()
},
/**
* 调到到下一页:腾讯的实名认证平台
*/
async handleToNext() {
// 开始校验数据
this.$refs.formRenderRef.validate()
// 取出双向绑定的身份证照片id
const { certType, certPic } = this.formData
// 将当前数据保存到store中
this.$store.commit(`rnr/${SET_PERSON_CONSIGNER_CARD}`, { certType, certPic: certPic.map(pic => pic.uuid) })
// 当前证件照片的识别key
const CERT_PIC_STORAGE_KEY = `cert-pic-${Date.now()}`
// 将证件信息保存到缓存中
cache.set(CERT_PIC_STORAGE_KEY, certPic, { noStorage: true })
// 跳转到文件上传页
this.routerToNextPage('RnrPersonConsignerBase', { certPicKey: CERT_PIC_STORAGE_KEY })
}
}
}
</script>
<style lang="scss">
.page-rnr-person-idcard {
padding-bottom: 72px;
.page-rnr-main {
margin-top: 0px !important;
.rnr-idcard, .rnr-file {
padding: 48px 0;
}
}
.page-rnr-person-idcard-tip {
font-size: 24px;
color: rgba(255, 255, 255, 0.6);
font-weight: 400;
padding: 14px 48px 18px;
}
}
</style>
<template>
<Page class="page-rnr-person-file">
<template #slot-title>
<span>{{ currentFlow }}/{{ totalFlow }}</span>
<span>代办人证件信息</span>
</template>
<template #slot-before-main>
<div class="page-rnr-person-file-tip">文件类型为图片文件,允许支持的照片格式包括bmp、jpg/jpeg、png,小于500K。</div>
</template>
<div class="page-rnr-main-card">
<ErrorWrap :error-message="inputError.certPic" :error="!!inputError.certPic">
<van-cell id="contractPic" :required="true" title="证件信息" class="van-field">
<template #label>
<BridgeUpload
:max-count="3"
:compress="{}"
:security="true"
v-model="formData.certPic"
>
<div class="page-rnr-main-card-upload-normal">
<div class="icon-upload-camera" />
</div>
</BridgeUpload>
</template>
</van-cell>
</ErrorWrap>
</div>
<template #slot-operation>
<van-button type="primary" class="page-rnr-main-btn-before" round color="linear-gradient(120deg, #EDF3FF 0%, #E9F0FF 97%)" @click="handleToBefore">上一步</van-button>
<van-button type="primary" class="page-rnr-main-btn-next" round color="linear-gradient(120deg, #4F4CFB 0%, #376FF4 97%)" @click="handleToNext">下一步</van-button>
</template>
</Page>
</template>
<script>
import Page from '@/components/Page'
import ErrorWrap from '@/components/ErrorWrap'
import BridgeUpload from '@/components/BridgeUpload'
import { validate } from '@/utils/validate'
import flowMixin from '@/minxin/flow'
import { SET_PERSON_CONSIGNER_CARD } from '@/store/modules/rnr'
export default {
name: 'RnrPersonConsignerCard',
components: { Page, BridgeUpload, ErrorWrap },
mixins: [flowMixin],
data() {
const { customerType } = this.$store.getters.personRnr
return {
inputError: {},
countTime: 59,
isSend: false,
showSms: false,
customerType,
formData: {
certPic: []
}
}
},
methods: {
/**
* 调到到下一页:腾讯的实名认证平台
*/
handleToNext() {
// 校验不通过的字段
const failFiled = this.validate()
// 如果当前有字段没校验通过
if (failFiled) {
return
}
// 保存到store中
this.$store.commit(`rnr/${SET_PERSON_CONSIGNER_CARD}`, this.formData)
// 跳转到支付结果页
this.routerToNextPage('RnrPersonFile')
},
/**
* 校验用户输入
*/
validate(ruleKeys = ['certPic']) {
// 错误的字段,错误的信息
const [failField, failMessage] = validate(this.formData, ruleKeys)
// 如果当前有错误信息
ruleKeys.forEach(key => {
this.$set(this.inputError, key, failField === key ? failMessage : '')
})
return failField
},
/**
* 跳转到上一页
*/
handleToBefore() {
// 回退到上个页面
this.$router.back()
}
}
}
</script>
<style lang="scss">
.page-rnr-person-file {
.page-rnr-main {
margin-top: 0px;
}
.page-rnr-main-fixed-btn-group {
display: flex;
justify-content: space-between;
.page-rnr-main-btn-before {
color: #242424 !important;
flex: 1;
height: 96px;
}
.page-rnr-main-btn-next {
flex: 2;
margin-left: 40px;
height: 96px;
}
}
.icon-upload-camera {
background-image: url(../../../assets/rnr/ico_camera.png);
background-size: 100% 100%;
position: absolute;
width: 80px;
height: 80px;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.page-rnr-main-card-upload-normal {
background-image: url(../../../assets/rnr/ico_pic.png);
background-color: #F7F8FA;
background-size: 196px 196px;
background-repeat: no-repeat;
background-position: center;
border-radius: 8px;
width: 196px;
height: 196px;
}
.page-rnr-main-btn {
font-size: 32px !important;
&.disabled {
color: #CACACA !important;
}
}
.van-cell__label {
.page-rnr-flex {
display: flex;
justify-content: space-between;
}
}
.page-rnr-person-file-tip {
font-size: 24px;
color: rgba(255, 255, 255, 0.6);
font-weight: 400;
padding: 14px 48px 18px;
}
.van-dialog {
box-sizing: border-box;
width: 685px;
padding: 0 40px 50px;
.van-dialog__header {
padding: 60px 0 12px;
}
.van-field__button {
padding-left: 30px;
.page-rnr-main-btn {
color: #0761F3;
font-size: 32px;
font-weight: 400;
}
}
.page-rnr-main-btn-confirm {
margin-top: 44px;
}
}
}
</style>
<template>
<Page class="page-rnr-person-file" title="文件信息">
<template #slot-title>
<span>{{ currentFlow }}/{{ totalFlow }}</span>
<span>文件信息</span>
</template>
<template #slot-before-main>
<div class="page-rnr-person-file-tip">文件类型为图片文件,允许支持的照片格式包括bmp、jpg/jpeg、png,小于500K。</div>
</template>
<div v-if="personRnr.isConsigner" class="page-rnr-main-card" >
<ErrorWrap :error-message="inputError.attorneyLetterPic" :error="!!inputError.attorneyLetterPic">
<van-cell id="attorneyLetterPic" :required="true" title="个人授权书" class="van-field">
<template #label>
<BridgeUpload v-model="attorneyLetterPic">
<div class="page-rnr-main-card-upload-normal">
<div class="icon-upload-camera" />
</div>
</BridgeUpload>
</template>
</van-cell>
</ErrorWrap>
</div>
<div v-if="personRnr.customerType == 1" class="page-rnr-main-card">
<ErrorWrap :error-message="inputError.purchaseContractPic" :error="!!inputError.purchaseContractPic">
<van-cell id="purchaseContractPic" :required="true" title="购车合同" class="van-field">
<template #label>
<BridgeUpload v-model="formData.purchaseContractPic">
<div class="page-rnr-main-card-upload-normal">
<div class="icon-upload-camera" />
</div>
</BridgeUpload>
</template>
</van-cell>
</ErrorWrap>
</div>
<div v-if="personRnr.customerType == 1" class="page-rnr-main-card">
<ErrorWrap :error-message="inputError.purchaseInvoicePic" :error="!!inputError.purchaseInvoicePic">
<van-cell id="purchaseInvoicePic" :required="true" title="购车发票或行驶本之一" class="van-field">
<template #label>
<BridgeUpload v-model="formData.purchaseInvoicePic">
<div class="page-rnr-main-card-upload-normal">
<div class="icon-upload-camera" />
</div>
</BridgeUpload>
</template>
</van-cell>
</ErrorWrap>
</div>
<div v-if="personRnr.customerType == 1" class="page-rnr-main-card">
<ErrorWrap :error-message="inputError.transferCertificatePic" :error="!!inputError.transferCertificatePic">
<van-cell id="contractPic" :required="true" title="过户证明" class="van-field">
<template #label>
<BridgeUpload v-model="formData.transferCertificatePic">
<div class="page-rnr-main-card-upload-normal">
<div class="icon-upload-camera" />
</div>
</BridgeUpload>
</template>
</van-cell>
</ErrorWrap>
</div>
<template #slot-operation>
<van-button type="primary" class="page-rnr-main-btn-before" round color="linear-gradient(120deg, #EDF3FF 0%, #E9F0FF 97%)" @click="handleToBefore">上一步</van-button>
<van-button :disabled="btnDisable" type="primary" class="page-rnr-main-btn-next" round color="linear-gradient(120deg, #4F4CFB 0%, #376FF4 97%)" @click="handleToNext">下一步</van-button>
</template>
</Page>
</template>
<script>
import Page from '@/components/Page'
import ErrorWrap from '@/components/ErrorWrap'
import BridgeUpload from '@/components/BridgeUpload'
import { fileUpload } from '@/api/rnr'
import { Toast } from 'vant'
import { validate } from '@/utils/validate'
import { SET_PERSON_FILE, SET_PERSON_CONSIGNER_CARD } from '@/store/modules/rnr'
import { mapGetters } from 'vuex'
import flowMixin from '@/minxin/flow'
export default {
name: 'RnrPersonCard',
components: { Page, BridgeUpload, ErrorWrap },
mixins: [flowMixin],
data() {
return {
inputError: {},
countTime: 59,
isSend: false,
showSms: false,
attorneyLetterPic: [],
formData: {
purchaseContractPic: [],
purchaseInvoicePic: [],
transferCertificatePic: []
}
}
},
computed: {
...mapGetters(['personRnr']),
/**
* 按钮是否禁用
*/
btnDisable() {
// 如果当前是二手车
if (+this.personRnr.customerType === 1) {
const { transferCertificatePic, purchaseContractPic, purchaseInvoicePic } = this.formData
return transferCertificatePic.length === 0 || purchaseContractPic.length === 0 || purchaseInvoicePic.length === 0
}
// 如果当前是代办,且没有上传个人委托人信息
return this.personRnr.isConsigner && this.attorneyLetterPic.length === 0
}
},
methods: {
/**
* 删除文件
*/
handleDeleteFile(files, { index }, key) {
this.formData[key].splice(index, 1)
},
/**
* 上传文件
* @param origin 源文件
* @param key 字段key
*/
handleUploadFile(origin, key) {
// 获取当前文件
let files = origin
// 如果当前不是数组,则将其变成数组
if (!(files instanceof Array)) {
files = [files]
}
// 将文件的uuid都展示在界面上
files.forEach(async file => {
// 文件可访问路径和文件的uuid
const { uuid } = await fileUpload({ file: file.content })
// 将文件id保存在照片中
this.formData[key].push(uuid)
// 开始校验上传字段
this.validate([key])
})
},
/**
* 调到到下一页:签名页
*/
async handleToNext() {
// 校验字段
let validKey = []
// 如果当前是代办
if (this.personRnr.isConsigner) {
validKey.push('attorneyLetterPic')
}
// 客户类型是二手车
if (+this.personRnr.customerType === 1) {
validKey = validKey.concat(['purchaseContractPic', 'purchaseInvoicePic', 'transferCertificatePic'])
}
// 校验不通过的字段
const failField = this.validate(validKey)
// 如果当前校验失败
if (failField) {
return
}
// 如果当前是委托人,则上传委托人
if (this.personRnr.isConsigner) {
this.$store.commit(`rnr/${SET_PERSON_CONSIGNER_CARD}`, {
attorneyLetterPic: this.attorneyLetterPic
})
}
// 将当前数据保存到store中
this.$store.commit(`rnr/${SET_PERSON_FILE}`, this.formData)
// 跳转页面
this.routerToNextPage('RnrPersonNotification')
},
/**
* 校验用户输入
*/
validate(ruleKeys) {
// 错误的字段,错误的信息
const [failField, failMessage] = validate(this.formData, ruleKeys)
// 如果当前有错误信息
ruleKeys.forEach(key => {
this.$set(this.inputError, key, failField === key ? failMessage : '')
})
return failField
},
/**
* 跳转到上一页
*/
handleToBefore() {
// 回退到上个页面
this.$router.back()
},
/**
* 图片超过最大限制
*/
handleOverSize() {
Toast('选择的图片超过最大限制,请重新选择')
}
}
}
</script>
<style lang="scss">
.page-rnr-person-file {
.page-rnr-main {
margin-top: 0px;
}
.page-rnr-main-fixed-btn-group {
display: flex;
justify-content: space-between;
.page-rnr-main-btn-before {
color: #242424 !important;
flex: 1;
height: 96px;
}
.page-rnr-main-btn-next {
flex: 2;
margin-left: 40px;
height: 96px;
}
}
.icon-upload-camera {
background-image: url(../../../assets/rnr/ico_camera.png);
background-size: 100% 100%;
position: absolute;
width: 80px;
height: 80px;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.page-rnr-main-card-upload-normal {
background-image: url(../../../assets/rnr/ico_pic.png);
background-color: #F7F8FA;
background-size: 196px 196px;
background-repeat: no-repeat;
background-position: center;
border-radius: 8px;
width: 196px;
height: 196px;
}
.page-rnr-main-btn {
font-size: 32px !important;
&.disabled {
color: #CACACA !important;
}
}
.van-cell__label {
.page-rnr-flex {
display: flex;
justify-content: space-between;
}
}
.page-rnr-person-file-tip {
font-size: 24px;
color: rgba(255, 255, 255, 0.6);
font-weight: 400;
padding: 14px 48px 18px;
}
}
</style>
<template>
<Page class="page-rnr-person-idcard">
<template #slot-title>
<span>{{ currentFlow }}/{{ totalFlow }}</span>
<span>证件信息</span>
</template>
<template #slot-before-main>
<div class="page-rnr-person-idcard-tip">文件类型为图片文件,允许支持的照片格式包括bmp、jpg/jpeg、png,小于500K。</div>
</template>
<div class="page-rnr-main-card">
<!-- 身份证选择上传 -->
<FormRender
ref="formRenderRef"
v-if="formData.certType === 'IDCARD'"
v-model="formData"
:schema="SCHEMA1"
@change="handleFormDataChange"
/>
<!-- 其他证件照片的选择上传 -->
<FormRender
ref="formRenderRef"
v-else
v-model="formData"
:schema="SCHEMA2"
@change="handleFormDataChange"
/>
</div>
<MustKnow v-if="formData.certType === 'IDCARD'" />
<template slot="slot-operation">
<van-button type="primary" class="page-rnr-main-btn-before" round color="linear-gradient(120deg, #EDF3FF 0%, #E9F0FF 97%)" @click="handleToBefore">上一步</van-button>
<van-button :disabled="!formData.certPic[0] || !formData.certPic[1]" type="primary" class="page-rnr-main-btn-next" round color="linear-gradient(120deg, #4F4CFB 0%, #376FF4 97%)" @click="handleToNext">下一步</van-button>
</template>
</Page>
</template>
<script>
import cache from '@/utils/cache'
import { cuscImageUpload } from '@/api/rnr'
import Page from '@/components/Page'
import MustKnow from '@/components/MustKnow'
import FormRender from '@/components/FormRender'
import { SET_PERSON_IDCARD } from '@/store/modules/rnr'
import flowMixin from '@/minxin/flow'
export default {
name: 'RnrPersonCard',
components: { Page, FormRender, MustKnow },
mixins: [flowMixin],
data() {
const { CARD_TYPE } = this.$store.getters.dict
return {
formData: {
certType: 'IDCARD',
certPic: []
},
SCHEMA1: {
certType: {
label: '证件类型',
type: 'rnr-select',
rules: [
{ required: true }
],
options: CARD_TYPE
},
certPic: {
type: 'rnr-idcard',
compress: {},
api: file => cuscImageUpload({ file }).then(resp => resp.uuid),
rules: [
{ required: true },
{
validator(value) {
// 如果人像面没有上传
if (!value[0] || value[0].length === 0) {
return { result: false, message: '请上传身份证人像面' }
}
if (!value[1] || value[1].length === 0) {
return { result: false, message: '请上传身份证国徽面' }
}
return true
}
}
]
}
},
SCHEMA2: {
certType: {
label: '证件类型',
type: 'rnr-select',
rules: [
{ required: true }
],
options: CARD_TYPE
},
certPic: {
type: 'rnr-file',
size: 'large',
compress: {},
maxCount: 2,
api: file => cuscImageUpload({ file }).then(resp => resp.uuid),
rules: [
{ required: true },
{
validator(value) {
// 如果人像面没有上传
if (!value[0] || value[0].length === 0) {
return { result: false, message: '请上传证件信息正面' }
}
if (!value[1] || value[1].length === 0) {
return { result: false, message: '请上传证件信息反面' }
}
return true
}
}
]
}
}
}
},
methods: {
/**
* 表单项改变方法
* @param value 当前双向绑定的值
* @param key 当前改变的字段key
*/
handleFormDataChange(value, key) {
if (key === 'certType') {
this.formData.certPic = []
}
},
/**
* 调到到下一页:腾讯的实名认证平台
*/
async handleToNext() {
// 开始校验数据
this.$refs.formRenderRef.validate()
// 取出双向绑定的身份证照片id
const { certType, certPic } = this.formData
// 将当前数据保存到store中
this.$store.commit(`rnr/${SET_PERSON_IDCARD}`, { certType, certPic: certPic.map(pic => pic.uuid) })
// 当前证件照片的识别key
const CERT_PIC_STORAGE_KEY = `cert-pic-${Date.now()}`
// 将证件信息保存到缓存中
cache.set(CERT_PIC_STORAGE_KEY, certPic, { noStorage: true })
// 跳转到基本信息页
this.routerToNextPage('RnrPersonBase', { certPicKey: CERT_PIC_STORAGE_KEY })
},
/**
* 跳转到上一页
*/
handleToBefore() {
// 回退到上个页面
this.$router.back()
}
}
}
</script>
<style lang="scss">
.page-rnr-person-idcard {
padding-bottom: 72px;
.page-rnr-main {
margin-top: 0px !important;
.rnr-idcard, .rnr-file {
padding: 48px 0;
}
}
.page-rnr-person-idcard-tip {
font-size: 24px;
color: rgba(255, 255, 255, 0.6);
font-weight: 400;
padding: 14px 48px 18px;
}
.page-rnr-main-fixed-btn-group {
display: flex;
justify-content: space-between;
.page-rnr-main-btn-before {
color: #242424 !important;
flex: 1;
height: 96px;
margin-right: 12px;
}
.page-rnr-main-btn-next {
flex: 2;
height: 96px;
}
}
}
</style>
<template>
<Page class="page-rnr-person-agreement">
<template #slot-title>
<span>{{ currentFlow }}/{{ totalFlow }}</span>
<span>责任告知书</span>
</template>
<div class="page-rnr-main-card">
<van-loading v-if="!notificationUrl" class="global-loading" color="#0094ff" />
<Painter ref="painterRef" v-else>
<img crossOrigin :src="notificationUrl">
<img :src="signUrl" class="fixed-right">
</Painter>
</div>
<div class="page-rnr-sign-wrapper">
<div v-if="signUrl" class="page-rnr-sign-fill" @click="openSign">
<img :src="signUrl" class="page-rnr-sign-img">
<div class="page-rnr-sign-btn">重签</div>
</div>
<div v-else class="page-rnr-sign" @click="openSign">点击在此处签名</div>
</div>
<template #slot-operation>
<van-button type="primary" class="page-rnr-main-btn-before" round color="linear-gradient(120deg, #EDF3FF 0%, #E9F0FF 97%)" @click="handleToBefore">上一步</van-button>
<van-button :disabled="btnDisable" :loading="loading" type="primary" class="page-rnr-main-btn-next" round color="linear-gradient(120deg, #4F4CFB 0%, #376FF4 97%)" @click="handleToNext">下一步</van-button>
</template>
<Sign :visible.sync="showSign" @submit="handleSignChange" />
</Page>
</template>
<script>
import Painter from '@/components/Painter'
import { fileUpload } from '@/api/rnr'
import { SET_PERSON_DUTY_PIC, DISPATCH_INIT_PROTOCAL } from '@/store/modules/rnr'
import Page from '@/components/Page'
import signMixin from '@/minxin/sign'
import flowMixin from '@/minxin/flow'
export default {
name: 'RnrPersonNotification',
components: { Page, Painter },
mixins: [flowMixin, signMixin],
data() {
return {
loading: false,
showSms: false,
notificationUrl: ''
}
},
async mounted() {
// 查询协议数据
await this.$store.dispatch(`rnr/${DISPATCH_INIT_PROTOCAL}`)
// 当前请求到的协议数据
const { protocal } = this.$store.getters
// 协议链接
this.notificationUrl = protocal[window.os.isTablet ? 'realnameNoticeVertical' : 'realnameNoticeHorizontal'].fileUrl
},
methods: {
/**
* 调到到下一页:腾讯的实名认证平台
*/
async handleToNext(formData) {
// 展示loading框
this.loading = true
try {
// 开始绘制canvas
const file = await this.$refs.painterRef.draw()
// 开始导出图片
const { uuid } = await fileUpload({ file })
// 开始保存数据
this.$store.commit(`rnr/${SET_PERSON_DUTY_PIC}`, {
dutyPic: [uuid]
})
// 跳转到
this.routerToNextPage('RnrPersonAgreement')
} catch (error) {
console.error(error)
}
this.loading = false
},
/**
* 跳转到上一页
*/
handleToBefore() {
// 回退到上个页面
this.$router.back()
}
}
}
</script>
<style lang="scss">
@import "../rnr.scss";
.page-rnr-person-agreement {
.page-rnr-main {
margin-top: 30px;
.page-rnr-main-card {
padding: 24px 24px 168px;
height: calc(100vh - 450px);
overflow: auto;
.page-rnr-main-canvas {
width: 100%;
}
.paint-sign-image {
width: auto;
height: 120px;
margin: -120px 0 0 52%;
}
}
.page-rnr-sign-wrapper {
background: #ffffff;
bottom: 196px;
padding: 24px 32px;
position: fixed;
left: 24px;
right: 24px;
.page-rnr-sign {
align-items: center;
background: #F7F8FA;
border: 1px dashed rgba(7, 97, 243, 1);
border-radius: 12px;
color: #0761F3;
display: flex;
font-size: 24px;
font-weight: 400;
height: 120px;
justify-content: center;
}
.page-rnr-sign-fill {
align-items: center;
background: #F7F8FA;
border-radius: 12px;
bottom: 148px;
display: flex;
height: 120px;
justify-content: space-between;
padding: 0px 48px 0px 132px;
.page-rnr-sign-img {
width: auto;
height: 100px;
}
.page-rnr-sign-btn {
color: #0761F3;
font-size: 24px;
font-weight: 400;
}
}
}
.page-rnr-main-fixed-btn-group {
display: flex;
justify-content: space-between;
.page-rnr-main-btn-before {
color: #242424 !important;
flex: 1;
height: 96px;
}
.page-rnr-main-btn-next {
flex: 2;
margin-left: 40px;
height: 96px;
}
}
}
}
</style>
<template>
<Page class="page-rnr-person-file">
<template #slot-title>
<span>{{ currentFlow }}/{{ totalFlow }}</span>
<span>证件信息</span>
</template>
<template #slot-before-main>
<div class="page-rnr-person-file-tip">文件类型为图片文件,允许支持的照片格式包括bmp、jpg/jpeg、png,小于500K。</div>
</template>
<div class="page-rnr-main-card">
<ErrorWrap :error-message="inputError.certPic" :error="!!inputError.certPic">
<van-cell id="contractPic" :required="true" title="证件信息" class="van-field">
<template #label>
<BridgeUpload
:max-count="3"
:compress="{}"
:security="true"
v-model="formData.certPic"
>
<div class="page-rnr-main-card-upload-normal">
<div class="icon-upload-camera" />
</div>
</BridgeUpload>
</template>
</van-cell>
</ErrorWrap>
</div>
<template #slot-operation>
<van-button type="primary" class="page-rnr-main-btn-before" round color="linear-gradient(120deg, #EDF3FF 0%, #E9F0FF 97%)" @click="handleToBefore">上一步</van-button>
<van-button type="primary" class="page-rnr-main-btn-next" round color="linear-gradient(120deg, #4F4CFB 0%, #376FF4 97%)" @click="handleToNext">下一步</van-button>
</template>
</Page>
</template>
<script>
import Page from '@/components/Page'
import ErrorWrap from '@/components/ErrorWrap'
import BridgeUpload from '@/components/BridgeUpload'
import { validate } from '@/utils/validate'
import flowMixin from '@/minxin/flow'
import { SET_PERSON_PAPER } from '@/store/modules/rnr'
export default {
name: 'RnrPersonCard',
components: { Page, BridgeUpload, ErrorWrap },
mixins: [flowMixin],
data() {
const { customerType } = this.$store.getters.personRnr
return {
inputError: {},
countTime: 59,
isSend: false,
showSms: false,
customerType,
formData: {
certPic: []
}
}
},
methods: {
/**
* 调到到下一页:腾讯的实名认证平台
*/
handleToNext() {
// 校验不通过的字段
const failFiled = this.validate()
// 如果当前有字段没校验通过
if (failFiled) {
return
}
// 保存到store中
this.$store.commit(`rnr/${SET_PERSON_PAPER}`, this.formData)
// 取出当前是否是委托人字段
const { isConsigner, customerType } = this.$store.getters.personRnr
// 如果当前是委托人,则跳转到委托人
if (isConsigner) {
// 跳转到支付结果页
this.routerToNextPage('RnrPersonConsignerBase')
return
}
// 跳转到支付结果页
this.routerToNextPage(customerType === 0 ? 'RnrPersonNotification' : 'RnrPersonFile')
},
/**
* 校验用户输入
*/
validate(ruleKeys = ['certPic']) {
// 错误的字段,错误的信息
const [failField, failMessage] = validate(this.formData, ruleKeys)
// 如果当前有错误信息
ruleKeys.forEach(key => {
this.$set(this.inputError, key, failField === key ? failMessage : '')
})
return failField
},
/**
* 跳转到上一页
*/
handleToBefore() {
// 回退到上个页面
this.$router.back()
}
}
}
</script>
<style lang="scss">
.page-rnr-person-file {
.page-rnr-main {
margin-top: 0px;
}
.page-rnr-main-fixed-btn-group {
display: flex;
justify-content: space-between;
.page-rnr-main-btn-before {
color: #242424 !important;
flex: 1;
height: 96px;
}
.page-rnr-main-btn-next {
flex: 2;
margin-left: 40px;
height: 96px;
}
}
.icon-upload-camera {
background-image: url(../../../assets/rnr/ico_camera.png);
background-size: 100% 100%;
position: absolute;
width: 80px;
height: 80px;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.page-rnr-main-card-upload-normal {
background-image: url(../../../assets/rnr/ico_pic.png);
background-color: #F7F8FA;
background-size: 196px 196px;
background-repeat: no-repeat;
background-position: center;
border-radius: 8px;
width: 196px;
height: 196px;
}
.page-rnr-main-btn {
font-size: 32px !important;
&.disabled {
color: #CACACA !important;
}
}
.van-cell__label {
.page-rnr-flex {
display: flex;
justify-content: space-between;
}
}
.page-rnr-person-file-tip {
font-size: 24px;
color: rgba(255, 255, 255, 0.6);
font-weight: 400;
padding: 14px 48px 18px;
}
.van-dialog {
box-sizing: border-box;
width: 685px;
padding: 0 40px 50px;
.van-dialog__header {
padding: 60px 0 12px;
}
.van-field__button {
padding-left: 30px;
.page-rnr-main-btn {
color: #0761F3;
font-size: 32px;
font-weight: 400;
}
}
.page-rnr-main-btn-confirm {
margin-top: 44px;
}
}
}
</style>
<template>
<van-loading v-if="status === STATUS.PENDING" vertical color="#0094ff" class="loading-container">加载中...</van-loading>
<section v-else class="page-rnr-result">
<main class="page-rnr-result-content">
<div :class="[STATUS.FAIL, STATUS.TX_VALID_FAIL].includes(status) ? 'icon-result-fail' : 'icon-result-success'" class="page-rnr-result-icon" />
<div v-if="status === STATUS.FAIL" class="page-rnr-result-title">认证失败</div>
<div v-else-if="status === STATUS.MAN_WORK" class="page-rnr-result-title">已转入人工审核,请注意查询认证进度</div>
<div v-else-if="status === STATUS.TX_VALID_FAIL" class="page-rnr-result-title">腾讯活体认证失败</div>
<div v-else class="page-rnr-result-title">恭喜您认证成功</div>
</main>
<div class="page-rnr-main-fixed-btn-group">
<van-button v-if="status === STATUS.TX_VALID_FAIL" type="primary" class="page-rnr-main-btn-next" round block color="linear-gradient(120deg, #4F4CFB 0%, #376FF4 97%)" @click="handleToTxVerify">重新认证</van-button>
<van-button v-else type="primary" class="page-rnr-main-btn-next" round block color="linear-gradient(120deg, #4F4CFB 0%, #376FF4 97%)" @click="handleToNextPage(status === STATUS.FAIL ? 'RnrPersonCard' : 'Home')">{{ status === STATUS.FAIL ? '重新认证' : '返回首页' }}</van-button>
</div>
</section>
</template>
<script>
import cache from '@/utils/cache'
import { livenessCallback } from '@/api/rnr'
// 状态
const STATUS = {
// 加载中
PENDING: -1,
// 腾讯活体认证失败
TX_VALID_FAIL: 2,
// 成功
SUCCESS: 0,
// 人工审核中
MAN_WORK: 1,
// 失败
FAIL: 3
}
export default {
name: 'RnrPersonResult',
data() {
return {
STATUS,
status: STATUS.PENDING,
h5LivenessUrl: ''
}
},
activated() {
// 开始提交实名信息
this.fetchSubmitRnr(this.$route.query)
},
methods: {
/**
* 提交实名认证的接口
*/
async fetchSubmitRnr(query) {
try {
// 开始提交数据
const { status, h5LivenessUrl } = await livenessCallback(this.$route.query)
// 标记当前提交成功
this.status = status
// h5活体验证的链接
this.h5LivenessUrl = h5LivenessUrl
return
} catch (error) {
console.error(error)
}
// 标记当前提交失败
this.status = STATUS.FAIL
},
/**
* 跳转到活体认证
*/
handleToTxVerify() {
// 跳转到活体认证页面
window.location.href = this.h5LivenessUrl
},
/**
* 跳转到下一个页面
* @param pageName 页面名称
*/
handleToNextPage(pageName) {
// 跳转到响应的页面
this.$router.push({ name: pageName, query: cache.get('rnr-result-condition') })
// 移除缓存中保存的数据
cache.remove('rnr-result-condition')
}
}
}
</script>
<style lang="scss">
.page-rnr-result {
.page-rnr-result-content {
padding-top: 72px;
.page-rnr-result-icon {
background-size: 100% 100%;
background-repeat: no-repeat;
width: 648px;
height: 490px;
margin: 0 auto;
&.icon-result-success {
background-image: url(../../../assets/rnr/ico_success.png);
}
&.icon-result-fail {
background-image: url(../../../assets/rnr/ico_fail.png);
}
}
.page-rnr-result-title {
color: #212026;
font-size: 36px;
font-weight: 500;
text-align: center;
margin-top: 24px;
}
}
.page-rnr-main-fixed-btn-group {
background-color: #ffffff;
bottom: 0px;
height: 148px;
padding: 20px 32px;
position: fixed;
left: 0px;
right: 0px;
.page-rnr-main-btn-next {
font-size: 30px;
height: 96px;
}
}
}
.loading-container {
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
position: fixed;
}
</style>
<template>
<div class="agreement">
<div class="content">
(一)共享<br>
我们不会与联通智网和您所购买车辆的道路机动车辆生产企业以外的任何公司、组织和个人分享您的个人信息,但以下情况除外:<br>
1.在获取单独同意的情况下共享:获得您的单独同意后,我们会与其他方共享您的个人信息。<br>
2.我们可能会根据法律法规及监管政策要求,或按政府主管部门的强制性要求,对外共享您的个人信息。<br>
3.您授权银行、征信机构等第三方向我们查询、采集您在联通智网的信息,或者我们会在法律法规及监管政策允许范围内及您对第三方的授权范围内向第三方共享您的信息,我们会依据与第三方的约定、对个人信息来源的合法性进行确认后,在符合法律法规及监管政策的前提下,使用您的这些个人信息。<br>
4.与我们的关联公司共享:您的个人信息可能会与我们的关联公司共享。关联公司如要改变个人信息的处理目的,将再次征求您的授权同意。<br>
我们的关联公司包括联通智网和您所购买车辆的道路机动车辆生产企业现在或将来控制、受控制或与其处于共同控制下的任何公司、机构以及上述公司或机构的合法继承人。其中“控制”是指直接或间接地拥有影响所提及公司管理的能力,无论是通过所有权、有投票权的股份、合同或其他被人民法院认定的方式。<br>
5.与授权合作伙伴共享:仅为实现本政策中声明的目的,我们的某些服务将由授权合作伙伴提供,我们可能会与合作伙伴共享您的某些个人信息,以提供更好的客户服务和用户体验。我们仅会出于合法、正当、必要、特定、明确的目的共享您的个人信息,并且只会共享提供服务所必要的个人信息。我们的合作伙伴无权将共享的个人信息用于任何其他用途。<br>
(二)转移<br>
我们不会将您的个人信息转移给任何公司、组织和个人,但以下情况除外:<br>
1.在获取单独同意的情况下转移:获得您的单独同意后,我们会向其他方转移您的个人信息;<br>
2.在涉及合并、收购或破产清算时,如涉及到个人信息转移,我们会要求新的持有您个人信息的公司、组织继续受此隐私政策的约束,否则我们将要求该公司、组织重新向您征求授权同意。<br>
(三)公开披露<br>
我们仅会在以下情况下,公开披露您的个人信息:<br>
1.获得您单独同意后;<br>
2.基于法律的披露:在法律、法律程序或政府主管部门强制性要求的情况下,我们可能会公开披露您的个人信息。<br>
(四)例外<br>
以下情形中,共享、转让、公开披露个人信息无需征得您的授权和同意:<br>
(1) 为履行法定职责或者法定义务所必需;<br>
(2) 与国家安全、国防安全直接相关的;<br>
(3) 为订立、履行您作为一方当事人的合同所必需;<br>
(4) 与公共安全、公共卫生、重大公共利益直接相关的。例如:为应对突发公共卫生事件,或者紧急情况下为保护自然人的生命健康和财产安全所必需;<br>
(5) 与刑事侦查、起诉、审判和判决执行等直接相关的;<br>
(6) 出于维护您或其他个人的生命、财产等重大合法权益但又很难得到您的授权同意的;<br>
(7) 依照法律法规的规定在合理的范围内处理您自行公开或者其他已经合法公开的个人信息,例如:合法的新闻报道、政府信息公开等渠道等。<br>
</div>
<div class="btn-group">
<van-button type="info" round class="btn" @click="toUserHome">同意</van-button>
<!-- <div class="btn-disagree" @click="logOut">不同意</div> -->
</div>
</div>
</template>
<script>
// import { saveAgreement, logout } from '@/api/loginToC'
// import { removeToken } from '@/utils/auth'
export default {
name: 'RnrPersonUserInfoAgreement',
methods: {
toUserHome() {
this.$router.go(-1)
// saveAgreement({
// consent: 1
// }).then(() => {
// this.$router.push({ name: 'UserHome' })
// }).catch(() => {
// })
}
// logOut() {
// logout().then(res => {
// removeToken()
// this.$router.push({ name: 'Login', params: { name: 'user' }, query: { tenantNo: this.tenantNo }})
// })
// }
}
}
</script>
<style lang="scss" scoped>
.agreement {
text-align: left;
.content {
padding: 24px 24px 240px;
line-height: 1.4;
}
.btn-group {
position: fixed;
padding: 20px 0;
bottom: 0;
left: 50%;
margin-left: -375px;
width: 750px;
background: #f9f9f9;
}
.btn {
margin: 0 auto;
display: block;
width: 686px;
height: 96px;
background-image: linear-gradient(120deg, #4F4CFB 0%, #376FF4 97%);
}
.btn-disagree {
margin: 0 auto;
height: 96px;
line-height: 96px;
text-align: center;
border: 0 none;
}
}
</style>
.page-rnr {
background-image: url(../../../assets/rnr/bg-header.png);
background-repeat: no-repeat;
background-size: 100% auto;
background-position: left top;
.page-rnr-header {
overflow: hidden;
padding: 58px 0 0 48px;
.page-rnr-title {
color: #FFFFFF;
font-size: 46px;
font-weight: 600;
float: left;
text-shadow: 0 2px 10px rgba(41,38,169,0.65);
line-height: 65px;
}
.page-rnr-back {
align-items: center;
background-image: linear-gradient(90deg, rgba(255, 255, 255, 0.2) 0%, rgba(255, 255, 255, 0.2) 100%);
border-radius: 100px 0px 0px 100px;
color: #FFFFFF;
display: flex;
font-size: 20px;
font-weight: 400;
float: right;
width: 140px;
height: 48px;
padding-left: 20px;
.van-icon {
font-weight: 700;
margin-left: 8px;
}
}
}
.page-rnr-main {
padding-bottom: 184px;
margin-top: 46px;
.page-rnr-main-progress {
color: #FFFFFF;
font-weight: 500;
padding: 0 0 20px 48px;
.page-rnr-main-progress-curr {
font-size: 46px;
}
.page-rnr-main-progress-total {
color: rgba(255, 255, 255, 0.4);
font-size: 26px;
}
.page-rnr-main-progress-remain {
font-size: 30px;
font-weight: 400;
margin-left: 16px;
}
}
.page-rnr-main-card {
background: rgba(255, 255, 255, 1);
border-radius: 16px;
box-sizing: border-box;
margin: 0 24px 24px;
padding: 0px 32px 0;
.page-rnr-main-card-title {
color: #242424;
font-size: 32px;
font-weight: 500;
padding: 30px 0 0;
.page-rnr-icon {
background-size: 100% 100%;
background-repeat: no-repeat;
display: inline-block;
width: 40px;
height: 40px;
margin-right: 12px;
}
}
.page-rnr-main-btn {
color: #0761F3;
font-size: 24px;
font-weight: 400;
}
.van-list {
margin-top: 36px;
.page-rnr-main-btn {
font-size: 24px;
margin-left: 30px;
}
}
.van-uploader {
width: 100%;
.van-uploader__wrapper {
display: flex;
.van-uploader__preview {
margin: 0 24px 16px 0;
.van-uploader__preview-image {
width: 196px;
height: 196px;
}
.van-uploader__preview-delete {
background-color: rgba(0, 0, 0, .4);
border-radius: 20px;
display: flex;
width: 40px;
height: 40px;
.van-uploader__preview-delete-icon {
font-size: 60px;
top: -10px;
right: -10px;
}
}
&:nth-child(3) {
margin-right: 0px;
}
}
}
}
}
.page-rnr-main-fixed-btn-group {
background-color: #ffffff;
bottom: 0px;
height: 148px;
padding: 20px 32px;
position: fixed;
left: 0px;
right: 0px;
}
.van-cell {
background-color: transparent;
padding: 0;
&.van-field {
background-color: transparent;
padding: 44px 0;
position: relative;
.van-field__label {
color: #242424;
font-size: 32px;
font-weight: 400;
height: 45px;
}
.van-cell__value {
height: 45px;
.van-field__control {
color: #242424;
font-size: 32px;
}
&.van-field__value {
position: relative;
.van-field__error-message {
position: absolute;
left: -220px;
bottom: -90px;
}
}
}
}
&.van-cell--required {
.van-cell__title {
span {
padding-left: 20px;
}
}
&:before {
left: 0px;
font-size: 16px;
}
}
.van-cell__title {
span {
color: #242424;
font-size: 32px;
font-weight: 400;
}
}
.van-cell__label {
margin-top: 36px;
}
&:after {
position: absolute;
box-sizing: border-box;
content: ' ';
pointer-events: none;
right: 0px;
bottom: 0;
left: 0px;
border-bottom: 1PX solid #ebedf0 !important;
transform: scaleY(.5);
}
}
}
.van-button {
font-size: 30px;
}
}
::-webkit-input-placeholder {
color: #CACACA !important;
font-weight: 400;
}
:-moz-placeholder {
color: #CACACA !important;
font-weight: 400;
}
::-moz-placeholder {
color: #CACACA !important;
font-weight: 400;
}
:-ms-input-placeholder {
color: #CACACA !important;
font-weight: 400;
}
\ No newline at end of file
<template>
<Page class="page-search-car" :show-operation="false" title="认证查询">
<div class="page-rnr-main-card placeholder-wrapper">
<div :class="isSearch ? 'scale' : ''" class="page-search-car-image-placeholder animation" />
<div :class="isSearch ? 'scale' : ''" class="page-search-car-title animation">请输入VIN码,查询车辆认证信息</div>
<SearchInput ref="searchInputRef" :class="isSearch ? 'page-search-car-input-indent' : 'page-search-car-input'" @search="handleSearch" />
<!-- <van-button plain hairline block round color="#0761F3" @click="handleScanCode"><i class="imageicon imageicon-scan" />扫码输入</van-button> -->
</div>
<TimeLine class="time-line-wrapper" v-if="!isEmpty">
<TimeLineItem v-for="(children, time) in list" :key="time" :time="time">
<div v-for="item in children" :key="item.iotId" class="page-search-car-block">
<div class="page-search-car-row">
<div class="title">
{{ item.orderType | businessName }}
</div>
<div :class="item.orderStatus == 3 ? 'success' : ''" class="status">{{ ['已提交', '待分派/认领', '待审核', '审核通过', '未通过', '', '', '', '', '作废'][item.orderStatus] }}</div>
</div>
<van-cell-group>
<van-cell title="ICCID" :value="item.iccid" />
<van-cell title="车主/责任人" :value="item.fullName" />
<van-cell title="手机号" :value="item.phone" />
<van-cell title="所属企业" :value="item.companyName" />
<van-cell title="申请时间" :value="item.startCheckDate" />
</van-cell-group>
</div>
</TimeLineItem>
</TimeLine>
<van-empty v-else-if="isSearch" :image="require('@/assets/search/empty.png')" description="未查询到认证信息" />
</Page>
</template>
<script>
import JsBridge from '@/utils/bridge'
import Page from '@/components/Page'
import TimeLine from '@/components/TimeLine/Index'
import TimeLineItem from '@/components/TimeLine/Item'
import SearchInput from '@/components/SearchInput'
import { querySearchProgress } from '@/api/search'
// 业务类型
const BUSINESS_TYPE = [
{ name: '自然人新车实名认证', value: '1' }, // 自然人
{ name: '自然人二手车实名认证', value: '2' }, // 自然人
{ name: '企业新车实名认证', value: '3' }, // 企业实名
{ name: '车企新车实名认证', value: '4' }, // 企业实名
{ name: '企业责任人变更', value: '5' }, // 企业负责人变更
{ name: '车主解绑', value: '6' }, // 自然人
{ name: '二手车主解绑', value: '7' }, // 自然人
{ name: '车企实名解绑', value: '8' },
{ name: '设备更换', value: '9' },
{ name: '一车多卡绑定', value: '10' },
{ name: '重新绑定', value: '11' },
{ name: '企业解绑', value: '12' }
]
export default {
name: 'CarSearch',
components: { Page, SearchInput, TimeLine, TimeLineItem },
filters: {
/**
* 业务名称
*/
businessName(val) {
// 取出当前字典项
const businessDict = BUSINESS_TYPE.find(type => +type.value === +val)
return businessDict ? businessDict.name : ''
}
},
data() {
return {
isSearch: false,
vin: '',
isEmpty: true,
list: {}
}
},
methods: {
/**
* 处理搜索方法
*/
async handleSearch(vin) {
// 接口返回值
try {
// 给输入框设置vin号
this.$refs.searchInputRef.setValue(vin)
// 开始请求接口
const list = await querySearchProgress({ vin })
// 先清空数据
this.list = {}
// 循环数据
list.forEach(item => {
// 当前年的key
const key = item.startCheckDate.slice(0, 4)
// 如果当前年没有在数据
if (!this.list[key]) {
this.list[key] = []
}
// 将数据塞进去
this.list[key].push(item)
})
// 重新赋值数据
this.isEmpty = list.length === 0
} catch (error) {
this.list = []
// 重新赋值数据
this.isEmpty = true
}
// 标记当前搜索过了
this.isSearch = true
},
/**
* 开始扫码
*/
handleScanCode() {
JsBridge.scanCode(true, vin => {
this.handleSearch(vin)
})
}
}
}
</script>
<style lang="scss">
.page-search-car {
font-family: PingFangSC-Regular;
.placeholder-wrapper {
padding: 40px 32px 36px !important;
.page-search-car-image-placeholder {
background-image: url(../../assets/search/search.png);
background-size: 100% 100%;
width: 290px;
height: 184px;
margin: 0 auto;
}
.page-search-car-title {
color: #242424;
font-size: 32px;
text-align: center;
font-weight: 400;
margin-top: 24px;
}
.page-search-car-input {
margin-top: 40px;
}
.page-search-car-input-indent {
margin-top: -25px;
}
.van-button {
width: 100%;
margin-top: 24px;
.imageicon-scan {
margin-bottom: -4px;
margin-right: 12px;
}
}
}
.time-line-wrapper {
margin: 36px 24px 0;
.page-search-car-block {
background: #ffffff;
border-radius: 16px;
padding: 36px 32px;
margin-top: 24px;
.page-search-car-row {
align-items: center;
display: flex;
justify-content: space-between;
line-height: 46px;
.title {
color: #242424;
font-size: 34px;
font-weight: 500;
}
.status {
align-items: center;
color: #352FD1;
display: flex;
font-size: 24px;
font-weight: 400;
&.success {
color: #7DD164;
&:before {
background-image: url('../../assets/home/ico_point_green.png');
}
}
&.fail {
color: #F16E6F;
&::before {
background-image: url('../../assets/home/ico_point_red.png');
}
}
&:before {
background-size: 100% 100%;
background-image: url('../../assets/home/ico_point_purple.png');
content: "";
display: block;
width: 36px;
height: 36px;
}
}
}
.van-cell-group {
margin-top: 26px;
.van-cell {
color: #000000;
font-size: 32px;
height: 64px;
line-height: 64px;
.van-cell__value {
color: rgba(39, 39, 39, 0.5);
flex: 2;
}
&:after {
display: none;
}
}
&:after {
display: none;
}
}
&:first-child {
margin-top: 0;
}
}
}
.van-empty {
.van-empty__image {
width: 354px;
height: 264px;
}
.van-empty__description {
color: #242424;
font-size: 32px;
font-weight: 400;
text-align: center;
opacity: 0.4;
margin-top: 28px;
}
}
.animation {
transition: all 300ms linear;
&.scale {
height: 0;
opacity: 0;
margin-top: 0px;
}
}
}
</style>
export const identifyStatus = {
'0': {
textColor: '#352FD1', // 左边文字颜色
leftIcon: 'ing', // 左边ico class
leftText: '审核中', // 左边文字
leftDesc: '', // 左边描述
rightBtn: false, // 是否有按钮
rightIcon: '', // 右边按钮ico
rightText: '', // 右边按钮文字
rightUrl: '' // 右边按钮跳转url
},
'3': {
textColor: '#39D3EA',
leftIcon: 'no',
leftText: '已解绑',
leftDesc: '',
rightBtn: false, // true,
rightIcon: '', // require('@/assets/icon/icon_rebind.png'),
rightText: '', // '重新绑定',
rightUrl: '' // 'Rebind'
},
'2': {
textColor: '#F16E6F',
leftIcon: 'failed',
leftText: '认证失败',
leftDesc: '',
rightBtn: false,
rightIcon: '',
rightText: '',
rightUrl: ''
},
'1': {
textColor: '#7DD164',
leftIcon: 'success',
leftText: '认证成功',
leftDesc: '',
rightBtn: true,
rightIcon: require('@/assets/icon/icon_unbound.png'),
rightText: '去解绑',
rightUrl: 'Unbound'
}
}
<template>
<div class="download">
<p v-if="isWx">请点击右上方 . . . </p>
<p v-if="isWx">使用默认浏览器打开</p>
</div>
</template>
<script>
export default {
name: 'Download',
data() {
return {
isWx: window.os.isWx
}
},
mounted() {
// 如果在微信中,则不处理
if (this.isWx) {
return
}
// 开始获取当前url
const { url } = this.$route.query
// 直接下载
window.location.href = decodeURIComponent(url)
}
}
</script>
<style lang="scss" scoped>
.download {
align-items: center;
display: flex;
font-size: 42px;
flex-direction: column;
justify-content: center;
height: 100vh;
p {
margin: 20px 0;
}
}
</style>
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment