Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
聂康
cusc-realname-private-pc-master
Commits
d2c4018b
Commit
d2c4018b
authored
Jun 17, 2025
by
kang.nie@inzymeits.com
Browse files
初始化代码
parent
de8a8ae5
Pipeline
#3105
failed with stages
in 0 seconds
Changes
393
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
src/views/realname-enterprise/step3.vue
0 → 100644
View file @
d2c4018b
<
template
>
<div
class=
"page"
>
<pageTitle
title=
"企业实名认证"
/>
<steps
:data=
"dict.enterpriseRealnameSteps"
:index=
"2"
/>
<page-module
name=
"责任人基本信息"
icon=
"info"
>
<CompBasicInfo
ref=
"baseInfo"
:data=
"baseData"
type=
"enterprise"
/>
</page-module>
<page-module
name=
"证件信息"
icon=
"idcard"
>
<CompCertificateInfo
ref=
"certInfo"
:data=
"certData"
@
read-cert=
"onReadCert"
/>
</page-module>
<page-module
name=
"文件信息"
icon=
"folder"
>
<el-row>
<el-col
:span=
"12"
>
<FileInfo
ref=
"contractInfo"
:sign=
"true"
:data=
"contractData"
:upload-type=
"['camera', 'sign']"
:attachment-url=
"attachmentUrl"
sign-key=
"companyAgreement"
label=
"入网协议"
/>
</el-col>
<el-col
:span=
"12"
>
<FileInfo
ref=
"fileInfo"
:data=
"fileData"
label=
"企业实名认证授权书"
/>
</el-col>
</el-row>
<el-row>
<el-col
:span=
"12"
>
<FileInfo
ref=
"dutyInfo"
:sign=
"true"
:data=
"dutyData"
:upload-type=
"['camera', 'sign']"
sign-key=
"realnameNotice"
label=
"责任告知书"
/>
</el-col>
</el-row>
</page-module>
<page-module
name=
"联系信息"
icon=
"tel"
>
<CompConcatInfo
ref=
"concatInfo"
:data=
"concatData"
/>
</page-module>
<div
class=
"next-step"
>
<el-button
size=
"small"
plain
@
click=
"onPrevStep"
>
上一步
</el-button>
<el-button
size=
"small"
type=
"primary"
@
click=
"onNextStep"
>
下一步
</el-button>
</div>
<CompAttachment
:vin=
"attachment.vin"
:file-id=
"attachment.fileId"
@
change=
"handleAttachmentChange"
/>
</div>
</
template
>
<
script
>
import
{
checkSmsCaptcha
}
from
'
@/api/realname-person
'
import
{
submitEnterpriseRnrWithFile
,
submitEnterpriseRnr
}
from
'
@/api/realname-enterprise
'
import
{
mapGetters
}
from
'
vuex
'
import
CompAttachment
from
'
@/components/CompAttachment
'
import
CompBasicInfo
from
'
@/components/CompBasicInfo
'
import
CompCertificateInfo
from
'
@/components/CompCertificateInfo
'
import
CompConcatInfo
from
'
@/components/CompConcatInfo
'
import
FileInfo
from
'
@/components/FileInfo
'
import
Common
from
'
@/components/Common
'
export
default
{
name
:
'
EnterpriseRealnameStep3
'
,
components
:
{
CompAttachment
,
CompBasicInfo
,
CompCertificateInfo
,
FileInfo
,
CompConcatInfo
},
mixins
:
[
Common
],
data
()
{
return
{
pageData
:
{
baseData
:
{},
certData
:
{},
fileData
:
{},
contractData
:
{},
dutyData
:
{},
concatData
:
{}
},
attachment
:
{
vin
:
[],
fileId
:
''
},
attachmentUrl
:
''
}
},
computed
:
{
...
mapGetters
([
'
dict
'
,
'
deviceType
'
]),
baseData
()
{
return
this
.
pageData
.
baseData
||
{}
},
certData
()
{
return
this
.
pageData
.
certData
||
{}
},
fileData
()
{
return
this
.
pageData
.
fileData
||
{}
},
dutyData
()
{
return
this
.
pageData
.
dutyData
||
{}
},
concatData
()
{
return
this
.
pageData
.
concatData
||
{}
},
contractData
()
{
return
this
.
pageData
.
contractData
||
{}
}
},
created
()
{
this
.
init
()
},
activated
()
{
this
.
$refs
.
baseInfo
.
clearValidate
()
this
.
$refs
.
certInfo
.
clearValidate
()
this
.
$refs
.
contractInfo
.
clearValidate
()
this
.
$refs
.
fileInfo
.
clearValidate
()
this
.
$refs
.
dutyInfo
.
clearValidate
()
this
.
$refs
.
concatInfo
.
clearValidate
()
},
methods
:
{
/**
* 附件改变方法
*/
handleAttachmentChange
(
val
)
{
this
.
attachmentUrl
=
val
},
init
()
{
this
.
getCacheData
()
if
(
this
.
$route
.
params
.
from
===
'
prev
'
)
{
this
.
restoreCacheData
()
}
else
{
this
.
resetStepData
()
}
// 从缓存中取出数据
const
stepPad
=
this
.
cacheGetStepData
(
'
EnterpriseRealnameStepPad1
'
)
||
{}
const
stepPc
=
this
.
cacheGetStepData
(
'
EnterpriseRealnameStep1
'
)
||
{}
this
.
attachment
=
{
vin
:
stepPad
.
iccidList
||
[],
fileId
:
stepPc
.
checkData
?
stepPc
.
checkData
.
fileId
:
''
}
},
getCacheData
()
{
this
.
cacheData
=
this
.
cacheGetStepData
(
this
.
cacheKey
)
},
restoreCacheData
()
{
if
(
this
.
isValidObject
(
this
.
cacheData
))
{
this
.
pageData
=
this
.
cloneObject
(
this
.
cacheData
)
}
else
{
this
.
resetStepData
()
}
},
resetStepData
()
{
this
.
pageData
=
{
baseData
:
{},
certData
:
{},
fileData
:
{},
dutyData
:
{},
concatData
:
{},
contractData
:
{}
}
},
onReadCert
(
data
)
{
this
.
$set
(
this
.
pageData
.
baseData
,
'
name
'
,
data
.
name
)
this
.
$set
(
this
.
pageData
.
baseData
,
'
sex
'
,
data
.
gender
)
this
.
$refs
.
baseInfo
.
validate
()
},
/**
* 上一步
* @time 2022-04-23 16:33:24
*/
onPrevStep
()
{
this
.
$router
.
push
({
name
:
'
EnterpriseRealnameStep2
'
,
params
:
{
from
:
'
prev
'
}})
},
getSubmitData
()
{
const
stepPad1Data
=
this
.
cacheGetStepData
(
'
EnterpriseRealnameStepPad1
'
)
||
{}
const
step1Data
=
this
.
cacheGetStepData
(
'
EnterpriseRealnameStep1
'
)
||
{}
const
step2Data
=
this
.
cacheGetStepData
(
'
EnterpriseRealnameStep2
'
)
||
{}
const
step3Data
=
this
.
cacheGetStepData
(
'
EnterpriseRealnameStep3
'
)
||
{}
const
ret
=
{
companyName
:
step2Data
.
baseData
.
companyName
,
companyType
:
step2Data
.
baseData
.
companyType
,
industryType
:
step2Data
.
baseData
.
industryType
,
companyCertType
:
step2Data
.
certData
.
companyCertType
,
licenseImages
:
step2Data
.
certData
.
licenseImages
.
map
(
item
=>
item
.
uuid
),
companyCertNumber
:
step2Data
.
certData
.
companyCertNumber
,
companyCertAddress
:
step2Data
.
certData
.
companyCertAddress
,
companyContactAddress
:
step2Data
.
certData
.
companyContactAddress
,
corporationName
:
step3Data
.
baseData
.
name
,
corporationGender
:
step3Data
.
baseData
.
sex
,
corporationCertType
:
step3Data
.
certData
.
type
,
corporationPhotoPic
:
step3Data
.
certData
.
photoUrls
.
filter
(
item
=>
item
.
url
.
id
!==
null
).
map
(
item
=>
item
.
url
.
id
),
corporationCertNumber
:
step3Data
.
certData
.
no
,
corporationCertAddress
:
step3Data
.
certData
.
address
,
corporationCertExpirationDate
:
step3Data
.
certData
.
validDate
,
corporationCertEffectiveDate
:
step3Data
.
certData
.
certEffectiveDate
,
corporationContactAddress
:
step3Data
.
certData
.
connectAddress
,
corporationPhone
:
step3Data
.
concatData
.
phone
,
verificationCode
:
step3Data
.
concatData
.
veCode
,
authorizationLetterPic
:
step3Data
.
fileData
.
fileList
.
map
(
item
=>
item
.
uuid
),
dutyPic
:
step3Data
.
dutyData
.
fileList
.
map
(
item
=>
item
.
uuid
),
contractPic
:
step3Data
.
contractData
.
fileList
.
map
(
item
=>
item
.
uuid
),
vinList
:
stepPad1Data
.
vinList
?
stepPad1Data
.
vinList
.
map
(
vin
=>
vin
.
vin
)
:
''
,
fileId
:
step1Data
.
checkData
?
step1Data
.
checkData
.
fileId
:
''
,
isVehicleCompany
:
0
}
return
ret
},
/**
* 下一步
* @time 2022-04-23 15:50:05
*/
async
onNextStep
()
{
try
{
const
valid
=
[
this
.
$refs
.
baseInfo
.
validate
(),
this
.
$refs
.
certInfo
.
validate
(),
this
.
$refs
.
contractInfo
.
validate
(),
this
.
$refs
.
fileInfo
.
validate
(),
this
.
$refs
.
dutyInfo
.
validate
(),
this
.
$refs
.
concatInfo
.
validate
()
]
await
Promise
.
all
(
valid
)
const
baseData
=
this
.
$refs
.
baseInfo
.
getPendingCacheData
()
const
certData
=
this
.
$refs
.
certInfo
.
getPendingCacheData
()
const
contractData
=
this
.
$refs
.
contractInfo
.
getPendingCacheData
()
const
fileData
=
this
.
$refs
.
fileInfo
.
getPendingCacheData
()
const
dutyData
=
this
.
$refs
.
dutyInfo
.
getPendingCacheData
()
const
concatData
=
this
.
$refs
.
concatInfo
.
getPendingCacheData
()
this
.
cacheSetStepData
(
this
.
cacheKey
,
{
baseData
,
certData
,
fileData
,
contractData
,
dutyData
,
concatData
})
// 如果当前是平板
if
(
window
.
OS
.
isTablet
)
{
// 当前提交的数据
const
reqData
=
this
.
getSubmitData
()
// 提交接口
const
{
h5LivenessUrl
}
=
await
(
this
.
$store
.
getters
.
deviceType
===
'
aio
'
?
submitEnterpriseRnrWithFile
:
submitEnterpriseRnr
)({
...(
reqData
||
{}),
source
:
'
PAD
'
})
// 跳转到活体认证页面
window
.
location
.
href
=
h5LivenessUrl
return
}
// 校验手机号输入是否正确
await
checkSmsCaptcha
({
phone
:
concatData
.
phone
,
captcha
:
concatData
.
veCode
})
this
.
$router
.
push
({
name
:
'
EnterpriseRealnameStep4
'
})
}
catch
(
e
)
{
console
.
log
(
e
)
e
.
anchor
()
}
}
}
}
</
script
>
src/views/realname-enterprise/step4.vue
0 → 100644
View file @
d2c4018b
<
template
>
<div
v-loading.fullscreen.lock=
"fullscreenLoading"
class=
"page"
>
<pageTitle
v-loading.fullscreen.lock=
"fullscreenLoading"
title=
"企业实名认证"
/>
<steps
:data=
"dict.enterpriseRealnameSteps"
:index=
"3"
/>
<PageModuleTabs
:tabs=
"TABS"
v-if=
"device.showTakePhoto"
v-model=
"tabName"
>
<CompFaceRecognition
ref=
"faceInfo"
:type=
"livenessType"
:take=
"tabName == 'carmer'"
:data=
"faceData"
/>
</PageModuleTabs>
<page-module
v-else
name=
"活体视频上传"
icon=
"video"
>
<CompFaceRecognition
ref=
"faceInfo"
:type=
"livenessType"
:data=
"faceData"
/>
</page-module>
<div
class=
"next-step"
>
<el-button
size=
"small"
plain
@
click=
"onPrevStep"
>
上一步
</el-button>
<el-button
size=
"small"
type=
"primary"
@
click=
"onSubmit"
>
提交
</el-button>
</div>
<comp-confirm
:show.sync=
"showSuccessConfirm"
:desc=
"successConfirmDesc"
:show-cancel-btn=
"false"
type=
"success"
@
on-sure=
"onSure"
/>
<comp-confirm
:show.sync=
"showErrorConfirm"
:desc=
"errorConfirmDesc"
/>
</div>
</
template
>
<
script
>
import
{
mapGetters
}
from
'
vuex
'
import
{
getLivenessCode
,
enterpriseSubmitRnr
}
from
'
@/api/realname-enterprise
'
import
CompFaceRecognition
from
'
@/components/CompFaceRecognition
'
import
CompConfirm
from
'
@/components/CompConfirm
'
import
PageModuleTabs
from
'
@/components/PageModule/tabs
'
import
Common
from
'
@/components/Common
'
const
TABS
=
[
{
label
:
'
活体视频上传
'
,
value
:
'
video
'
,
icon
:
require
(
'
@/assets/image/video@2x.png
'
)
},
{
label
:
'
在线拍摄视频
'
,
value
:
'
carmer
'
,
icon
:
require
(
'
@/assets/image/icon_user@2x.png
'
)
}
]
export
default
{
name
:
'
EnterpriseRealnameStep4
'
,
components
:
{
CompFaceRecognition
,
CompConfirm
,
PageModuleTabs
},
mixins
:
[
Common
],
data
()
{
return
{
TABS
,
showSuccessConfirm
:
false
,
successConfirmDesc
:
''
,
pageData
:
{},
showErrorConfirm
:
false
,
errorConfirmDesc
:
''
,
livenessType
:
''
,
fullscreenLoading
:
false
,
tabName
:
'
video
'
}
},
computed
:
{
...
mapGetters
([
'
dict
'
,
'
device
'
]),
faceData
()
{
return
this
.
pageData
.
faceData
||
{}
}
},
created
()
{
this
.
_initMount
=
true
this
.
init
()
},
methods
:
{
errorTips
(
errMsg
)
{
this
.
showErrorConfirm
=
true
this
.
errorConfirmDesc
=
errMsg
},
successTips
(
msg
)
{
this
.
showSuccessConfirm
=
true
this
.
successConfirmDesc
=
msg
},
/**
* 上一步
* @time 2022-04-23 16:33:24
*/
onPrevStep
()
{
this
.
$router
.
push
({
name
:
'
EnterpriseRealnameStep3
'
,
params
:
{
from
:
'
prev
'
}})
},
getSubmitData
()
{
const
step1Data
=
this
.
cacheGetStepData
(
'
EnterpriseRealnameStep1
'
)
const
step2Data
=
this
.
cacheGetStepData
(
'
EnterpriseRealnameStep2
'
)
const
step3Data
=
this
.
cacheGetStepData
(
'
EnterpriseRealnameStep3
'
)
const
ret
=
{
companyName
:
step2Data
.
baseData
.
companyName
,
companyType
:
step2Data
.
baseData
.
companyType
,
industryType
:
step2Data
.
baseData
.
industryType
,
companyCertType
:
step2Data
.
certData
.
companyCertType
,
licenseImages
:
step2Data
.
certData
.
licenseImages
.
map
(
item
=>
item
.
uuid
),
companyCertNumber
:
step2Data
.
certData
.
companyCertNumber
,
companyCertAddress
:
step2Data
.
certData
.
companyCertAddress
,
companyContactAddress
:
step2Data
.
certData
.
companyContactAddress
,
corporationName
:
step3Data
.
baseData
.
name
,
corporationGender
:
step3Data
.
baseData
.
sex
,
corporationCertType
:
step3Data
.
certData
.
type
,
corporationPhotoPic
:
step3Data
.
certData
.
photoUrls
.
filter
(
item
=>
item
.
url
.
id
!==
null
).
map
(
item
=>
item
.
url
.
id
),
corporationCertNumber
:
step3Data
.
certData
.
no
,
corporationCertAddress
:
step3Data
.
certData
.
address
,
corporationCertExpirationDate
:
step3Data
.
certData
.
validDate
,
corporationCertEffectiveDate
:
step3Data
.
certData
.
certEffectiveDate
,
corporationContactAddress
:
step3Data
.
certData
.
connectAddress
,
corporationPhone
:
step3Data
.
concatData
.
phone
,
verificationCode
:
step3Data
.
concatData
.
veCode
,
authorizationLetterPic
:
step3Data
.
fileData
.
fileList
.
map
(
item
=>
item
.
uuid
),
dutyPic
:
step3Data
.
dutyData
.
fileList
.
map
(
item
=>
item
.
uuid
),
contractPic
:
step3Data
.
contractData
.
fileList
.
map
(
item
=>
item
.
uuid
),
liveVerificationVideo
:
this
.
$refs
.
faceInfo
.
getFormData
().
fileList
[
0
].
uuid
,
fileId
:
step1Data
.
checkData
.
fileId
,
requestId
:
this
.
_remoteLiveData
.
requestId
,
isVehicleCompany
:
0
}
return
ret
},
async
init
()
{
this
.
fullscreenLoading
=
true
this
.
_remoteLiveData
=
await
this
.
getLivenessCode
()
this
.
fullscreenLoading
=
false
this
.
livenessType
=
this
.
_remoteLiveData
?
this
.
_remoteLiveData
.
livenessType
:
''
this
.
pageData
=
{
faceData
:
{
number
:
this
.
_remoteLiveData
?
this
.
_remoteLiveData
.
livenessCode
:
''
}
}
},
async
onSubmit
()
{
if
(
this
.
faceData
.
number
===
''
)
{
this
.
errorTips
(
'
获取活体数字验证码失败,请刷新页面重试
'
)
return
}
try
{
await
this
.
$refs
.
faceInfo
.
validate
()
this
.
fullscreenLoading
=
true
const
respData
=
await
this
.
enterpriseSubmitRnr
(
this
.
getSubmitData
())
this
.
fullscreenLoading
=
false
if
(
!
respData
.
isOk
)
{
this
.
errorTips
(
respData
.
data
.
message
||
'
实名认证失败
'
)
return
}
if
(
respData
.
data
.
verifyStatus
===
0
)
{
this
.
successTips
(
'
实名认证成功
'
)
}
else
if
(
respData
.
data
.
verifyStatus
===
1
)
{
this
.
successTips
(
'
已转入人工审核,请注意查询认证进度
'
)
}
else
{
this
.
errorTips
(
'
实名认证失败
'
)
}
}
catch
(
e
)
{
console
.
log
(
e
)
e
.
anchor
()
}
},
async
getLivenessCode
()
{
try
{
const
ret
=
await
getLivenessCode
()
return
ret
}
catch
(
e
)
{
return
null
}
},
async
enterpriseSubmitRnr
(
params
)
{
try
{
const
respData
=
await
enterpriseSubmitRnr
({
data
:
{
...
params
},
hideToast
:
true
})
return
{
isOk
:
true
,
data
:
respData
}
}
catch
(
e
)
{
return
{
isOk
:
false
,
data
:
e
}
}
},
onSure
()
{
sessionStorage
.
clear
()
this
.
$router
.
push
({
name
:
'
HomePage
'
})
}
}
}
</
script
>
src/views/realname-person/components/common.js
0 → 100644
View file @
d2c4018b
const
range
=
[
'
PersonRealnameStep1
'
,
'
PersonRealnameStep2
'
,
'
PersonRealnameStep3
'
]
export
default
{
beforeRouteLeave
(
to
,
from
,
next
)
{
if
(
range
.
indexOf
(
to
.
name
)
===
-
1
)
{
range
.
forEach
(
name
=>
{
this
.
cacheDelStepData
(
name
)
})
}
next
()
},
created
()
{
this
.
_isInitMount
=
true
this
.
init
()
},
activated
()
{
if
(
this
.
_isInitMount
)
{
this
.
_isInitMount
=
false
return
}
this
.
show
()
},
methods
:
{
// 从前一个页面进入当前页时,先从缓存恢复数据,否则重建
// 其他情况进入当前页,重建
initRenderPage
()
{
if
(
this
.
$route
.
params
.
from
===
'
prev
'
)
{
this
.
restorePageDataFromCache
()
}
else
{
this
.
initEmptyPageData
()
}
},
// 获取车卡关系验证请求参数
getVerifyVinCardsInfoParams
(
data
,
addition
)
{
const
iccidList
=
data
.
iccidList
.
filter
(
item
=>
item
.
iccid
!==
''
).
map
(
item
=>
item
.
iccid
)
const
vin
=
data
.
vin
const
rnrId
=
data
.
rnrId
return
{
iccidList
,
vin
,
rnrId
,
...
addition
}
},
// 获取提交自然人实名认证请求参数
getSubmitPersonRealNameAuthParams
(
data
)
{
const
{
step1Data
,
step2Data
,
step3Data
}
=
data
const
busTypeData
=
step1Data
.
busTypeData
const
carCardData
=
step1Data
.
carCardData
const
masterData
=
step2Data
.
masterData
const
delegateData
=
step2Data
.
delegateData
const
ret
=
{
// 业务类型
customerType
:
busTypeData
.
userType
===
'
new
'
?
0
:
1
,
isConsigner
:
busTypeData
.
isDelegate
,
// 车卡信息
vin
:
carCardData
.
vin
,
iccidList
:
carCardData
.
iccidList
.
filter
(
item
=>
item
.
iccid
!==
''
).
map
(
item
=>
item
.
iccid
),
// 基本信息
fullName
:
masterData
.
basicInfoData
.
name
,
gender
:
masterData
.
basicInfoData
.
sex
,
// 证件信息
certAddress
:
masterData
.
certInfoData
.
address
,
certExpirationDate
:
masterData
.
certInfoData
.
validDate
,
certEffectiveDate
:
masterData
.
certInfoData
.
certEffectiveDate
,
certPic
:
masterData
.
certInfoData
.
photoUrls
.
filter
(
item
=>
item
.
url
.
id
!==
null
).
map
(
item
=>
item
.
url
.
id
),
certNumber
:
masterData
.
certInfoData
.
no
,
certType
:
masterData
.
certInfoData
.
type
,
contactAddress
:
masterData
.
certInfoData
.
connectAddress
,
// 文件信息
contractPic
:
masterData
.
fileInfoData
.
protocolUrl
.
map
(
item
=>
item
.
uuid
),
purchaseContractPic
:
busTypeData
.
userType
===
'
new
'
?
[]
:
masterData
.
fileInfoData
.
contractUrl
.
map
(
item
=>
item
.
uuid
),
purchaseInvoicePic
:
busTypeData
.
userType
===
'
new
'
?
[]
:
masterData
.
fileInfoData
.
billUrl
.
map
(
item
=>
item
.
uuid
),
transferCertificatePic
:
busTypeData
.
userType
===
'
new
'
?
[]
:
masterData
.
fileInfoData
.
transferUrl
.
map
(
item
=>
item
.
uuid
),
dutyPic
:
masterData
.
fileInfoData
.
notifyUrl
.
map
(
item
=>
item
.
uuid
),
// 联系信息
phone
:
masterData
.
concatInfoData
.
phone
,
verificationCode
:
masterData
.
concatInfoData
.
veCode
,
// 委托人
consignerInfo
:
{
// 基本信息
fullName
:
''
,
gender
:
''
,
// 证件信息
certType
:
''
,
certPic
:
[],
certNumber
:
''
,
certAddress
:
''
,
certExpirationDate
:
''
,
contactAddress
:
''
,
// 委托书
attorneyLetterPic
:
''
,
// 联系信息
phone
:
''
,
verificationCode
:
''
},
liveVerificationVideo
:
step3Data
?
step3Data
.
fileData
.
fileList
[
0
].
uuid
:
''
,
requestId
:
step3Data
?
step3Data
.
requestId
:
''
}
if
(
busTypeData
.
isDelegate
)
{
ret
.
consignerInfo
.
fullName
=
delegateData
.
basicInfoData
.
name
ret
.
consignerInfo
.
gender
=
delegateData
.
basicInfoData
.
sex
ret
.
consignerInfo
.
certType
=
delegateData
.
certInfoData
.
type
ret
.
consignerInfo
.
certPic
=
delegateData
.
certInfoData
.
photoUrls
.
filter
(
item
=>
item
.
url
.
id
!==
null
).
map
(
item
=>
item
.
url
.
id
)
ret
.
consignerInfo
.
certNumber
=
delegateData
.
certInfoData
.
no
ret
.
consignerInfo
.
certAddress
=
delegateData
.
certInfoData
.
address
ret
.
consignerInfo
.
certExpirationDate
=
delegateData
.
certInfoData
.
validDate
ret
.
consignerInfo
.
certEffectiveDate
=
delegateData
.
certInfoData
.
certEffectiveDate
ret
.
consignerInfo
.
contactAddress
=
delegateData
.
certInfoData
.
connectAddress
ret
.
consignerInfo
.
attorneyLetterPic
=
delegateData
.
fileInfoData
.
fileList
.
map
(
item
=>
item
.
uuid
)
ret
.
consignerInfo
.
phone
=
delegateData
.
concatInfoData
.
phone
ret
.
consignerInfo
.
verificationCode
=
delegateData
.
concatInfoData
.
veCode
}
return
ret
}
}
}
src/views/realname-person/components/validate-step.js
0 → 100644
View file @
d2c4018b
import
Schema
from
'
async-validator
'
const
step1Descriptor
=
{
busTypeData
:
{
type
:
'
object
'
,
required
:
true
,
fields
:
{
userType
:
{
type
:
'
string
'
,
required
:
true
},
isDelegate
:
{
type
:
'
boolean
'
,
required
:
true
}
}
},
carCardData
:
{
type
:
'
object
'
,
required
:
true
,
fields
:
{
vin
:
{
type
:
'
string
'
,
required
:
true
},
iccidList
:
{
type
:
'
array
'
,
required
:
true
,
defaultField
:
{
type
:
'
object
'
,
required
:
true
,
fields
:
{
iccid
:
{
type
:
'
string
'
},
state
:
{
type
:
'
string
'
,
required
:
true
},
_formId
:
{
type
:
'
number
'
,
required
:
true
},
_inputId
:
{
type
:
'
number
'
,
required
:
true
}
}
}
}
}
}
}
const
step1Validator
=
new
Schema
(
step1Descriptor
)
// 第2步车主数据校验
const
step2MasterDataDescriptor
=
{
isDelegate
:
{
type
:
'
boolean
'
,
required
:
true
},
vin
:
{
type
:
'
string
'
,
required
:
true
},
userType
:
{
type
:
'
string
'
,
required
:
true
},
masterData
:
{
type
:
'
object
'
,
required
:
true
,
fields
:
{
basicInfoData
:
{
type
:
'
object
'
,
required
:
true
,
fields
:
{
name
:
{
type
:
'
string
'
,
required
:
true
},
sex
:
{
type
:
'
string
'
,
required
:
true
},
vin
:
{
type
:
'
string
'
,
required
:
true
}
}
},
certInfoData
:
{
type
:
'
object
'
,
required
:
true
,
fields
:
{
address
:
{
type
:
'
string
'
,
required
:
true
},
connectAddress
:
{
type
:
'
string
'
,
required
:
false
},
no
:
{
type
:
'
string
'
,
required
:
true
},
type
:
{
type
:
'
string
'
,
required
:
true
},
validDate
:
{
type
:
'
string
'
,
required
:
true
},
photoUrls
:
{
type
:
'
array
'
,
required
:
true
,
defaultField
:
{
type
:
'
object
'
,
required
:
true
,
fields
:
{
id
:
{
type
:
'
number
'
,
required
:
true
},
url
:
{
type
:
'
object
'
}
}
}
}
}
},
fileInfoData
:
{
type
:
'
object
'
,
required
:
true
,
fields
:
{
protocolUrl
:
{
type
:
'
array
'
,
required
:
true
,
defaultField
:
{
type
:
'
object
'
,
required
:
true
,
fields
:
{
accessUrl
:
{
type
:
'
string
'
}
}
}
},
contractUrl
:
{
type
:
'
array
'
,
defaultField
:
{
type
:
'
object
'
,
required
:
true
,
fields
:
{
accessUrl
:
{
type
:
'
string
'
}
}
}
},
billUrl
:
{
type
:
'
array
'
,
defaultField
:
{
type
:
'
object
'
,
required
:
true
,
fields
:
{
accessUrl
:
{
type
:
'
string
'
}
}
}
},
transferUrl
:
{
type
:
'
array
'
,
defaultField
:
{
type
:
'
object
'
,
required
:
true
,
fields
:
{
accessUrl
:
{
type
:
'
string
'
}
}
}
}
}
},
concatInfoData
:
{
type
:
'
object
'
,
required
:
true
,
fields
:
{
phone
:
{
type
:
'
string
'
,
required
:
true
},
veCode
:
{
type
:
'
string
'
}
}
}
}
}
}
const
step2MasterDataValidator
=
new
Schema
(
step2MasterDataDescriptor
)
// 第2步代办人数据校验
const
step2DelegateDataDescriptor
=
{
delegateData
:
{
type
:
'
object
'
,
required
:
true
,
fields
:
{
basicInfoData
:
{
type
:
'
object
'
,
required
:
true
,
fields
:
{
name
:
{
type
:
'
string
'
,
required
:
true
},
sex
:
{
type
:
'
string
'
,
required
:
true
}
}
},
certInfoData
:
{
type
:
'
object
'
,
required
:
true
,
fields
:
{
address
:
{
type
:
'
string
'
,
required
:
true
},
connectAddress
:
{
type
:
'
string
'
,
required
:
false
},
no
:
{
type
:
'
string
'
,
required
:
true
},
type
:
{
type
:
'
string
'
,
required
:
true
},
validDate
:
{
type
:
'
string
'
,
required
:
true
},
photoUrls
:
{
type
:
'
array
'
,
required
:
true
,
defaultField
:
{
type
:
'
object
'
,
required
:
true
,
fields
:
{
id
:
{
type
:
'
number
'
,
required
:
true
},
url
:
{
type
:
'
object
'
}
}
}
}
}
},
fileInfoData
:
{
type
:
'
object
'
,
required
:
true
,
fields
:
{
fileList
:
{
type
:
'
array
'
,
required
:
true
,
defaultField
:
{
type
:
'
object
'
,
required
:
true
,
fields
:
{
accessUrl
:
{
type
:
'
string
'
,
required
:
true
}
}
}
}
}
},
concatInfoData
:
{
type
:
'
object
'
,
required
:
true
,
fields
:
{
phone
:
{
type
:
'
string
'
,
required
:
true
},
veCode
:
{
type
:
'
string
'
}
}
}
}
}
}
const
step2DelegateDataValidator
=
new
Schema
(
step2DelegateDataDescriptor
)
export
default
{
methods
:
{
step1Validate
(
data
=
{})
{
return
new
Promise
((
resolve
,
reject
)
=>
{
step1Validator
.
validate
(
data
||
{},
(
errors
,
fields
)
=>
{
if
(
errors
)
{
resolve
(
false
)
return
}
resolve
(
true
)
})
})
},
step2Validate
(
data
=
{})
{
data
=
data
||
{}
const
masterData
=
{
isDelegate
:
data
.
isDelegate
,
vin
:
data
.
vin
,
userType
:
data
.
userType
,
masterData
:
data
.
masterData
}
return
new
Promise
((
resolve
,
reject
)
=>
{
if
(
data
.
isDelegate
)
{
step2MasterDataValidator
.
validate
(
masterData
,
(
errors
,
fields
)
=>
{
if
(
errors
)
{
resolve
(
false
)
return
}
step2DelegateDataValidator
.
validate
({
delegateData
:
data
.
delegateData
},
(
errors
,
fields
)
=>
{
if
(
errors
)
{
resolve
(
false
)
return
}
resolve
(
true
)
})
})
return
}
step2MasterDataValidator
.
validate
(
masterData
,
(
errors
,
fields
)
=>
{
if
(
errors
)
{
resolve
(
false
)
return
}
resolve
(
true
)
})
})
}
}
}
src/views/realname-person/result.vue
0 → 100644
View file @
d2c4018b
<
template
>
<div
v-loading.fullscreen.lock=
"loading"
class=
"page-person-real-result"
>
<page-title
title=
"完成人脸识别"
/>
<section
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=
"next-step"
>
<el-button
v-if=
"status === STATUS.TX_VALID_FAIL"
size=
"small"
plain
@
click.stop=
"handleToTxVerify"
>
重新认证
</el-button>
<el-button
v-else
size=
"small"
type=
"primary"
@
click.stop=
"handleToNextPage(status === STATUS.FAIL ? 'PersonRealnameStep1' : 'HomePage')"
>
{{
status
===
STATUS
.
FAIL
?
'
重新认证
'
:
'
返回首页
'
}}
</el-button>
</div>
</section>
</div>
</
template
>
<
script
>
import
{
livenessCallback
}
from
'
@/api/realname-person
'
// 状态
const
STATUS
=
{
// 加载中
PENDING
:
-
1
,
// 腾讯活体认证失败
TX_VALID_FAIL
:
2
,
// 成功
SUCCESS
:
0
,
// 人工审核中
MAN_WORK
:
1
,
// 失败
FAIL
:
3
}
export
default
{
name
:
'
MarkupPersonResult
'
,
data
()
{
return
{
STATUS
,
status
:
STATUS
.
PENDING
,
h5LivenessUrl
:
''
,
loading
:
true
}
},
mounted
()
{
// 开始提交实名信息
this
.
fetchRnrCallback
(
this
.
$route
.
query
)
},
methods
:
{
/**
* 提交实名认证的接口
*/
async
fetchRnrCallback
(
query
)
{
// 标记当前在loading中
this
.
loading
=
true
try
{
// 开始提交数据
const
{
status
,
h5LivenessUrl
}
=
await
livenessCallback
({
...(
query
||
{}),
source
:
'
PAD
'
})
// 标记当前提交成功
this
.
status
=
status
// h5活体验证的链接
this
.
h5LivenessUrl
=
h5LivenessUrl
// 标记当前loading结束
this
.
loading
=
false
return
}
catch
(
error
)
{
console
.
error
(
error
)
}
// 标记当前loading结束
this
.
loading
=
false
// 标记当前提交失败
this
.
status
=
STATUS
.
FAIL
},
/**
* 跳转到活体认证
*/
handleToTxVerify
()
{
// 跳转到活体认证页面
window
.
location
.
href
=
this
.
h5LivenessUrl
},
/**
* 跳转到下一个页面
* @param pageName 页面名称
*/
handleToNextPage
(
pageName
)
{
this
.
$router
.
push
({
name
:
pageName
})
}
}
}
</
script
>
<
style
lang=
"scss"
>
.page-person-real-result
{
padding-bottom
:
64px
;
.next-step
{
z-index
:
5
;
}
.page-rnr-result
{
.page-rnr-result-content
{
padding-top
:
72px
;
.page-rnr-result-icon
{
background-size
:
100%
100%
;
background-repeat
:
no-repeat
;
width
:
324px
;
height
:
245px
;
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
;
}
}
}
}
</
style
>
src/views/realname-person/step1.vue
0 → 100644
View file @
d2c4018b
<
template
>
<div
v-loading.fullscreen.lock=
"fullscreenLoading"
class=
"page-person-real-step1"
>
<page-title
title=
"自然人实名认证"
/>
<steps
:data=
"stepData"
/>
<page-module
name=
"业务类型"
icon=
"star"
>
<CompBusType
ref=
"busType"
:data=
"busTypeData"
@
change=
"userType => (isBind = userType === 'old')"
/>
</page-module>
<page-module
name=
"车卡信息"
icon=
"car"
>
<CompCarCard
ref=
"carCard"
:data=
"carCardData"
@
on-canenable=
"carCardLoading = !$event"
:is-bind=
"isBind"
/>
</page-module>
<div
class=
"next-step"
>
<el-button
:disabled=
"carCardLoading"
size=
"small"
type=
"primary"
@
click.stop=
"clickNextStep"
>
下一步
</el-button>
</div>
</div>
</
template
>
<
script
>
import
{
checkVinCard
}
from
'
@/api/iccid
'
import
PageTitle
from
'
@/components/PageTitle
'
import
Steps
from
'
@/components/Steps
'
import
CompBusType
from
'
@/components/CompBusType
'
import
CompCarCard
from
'
@/components/CompCarCard
'
import
Common
from
'
@/components/Common
'
import
SelfCommon
from
'
./components/common
'
export
default
{
name
:
'
PersonRealnameStep1
'
,
components
:
{
PageTitle
,
Steps
,
CompBusType
,
CompCarCard
},
mixins
:
[
Common
,
SelfCommon
],
data
()
{
return
{
stepData
:
[
'
车卡信息录入
'
,
'
填写客户信息
'
,
'
完成人脸识别
'
],
pageData
:
{},
isBind
:
false
,
carCardLoading
:
false
,
fullscreenLoading
:
false
}
},
computed
:
{
busTypeData
()
{
return
this
.
pageData
.
busTypeData
||
{}
},
carCardData
()
{
return
this
.
pageData
.
carCardData
||
{}
}
},
methods
:
{
init
()
{
this
.
initStepCachePageData
()
this
.
initRenderPage
()
},
show
()
{
// todo
},
// 初始化空页面数据
initEmptyPageData
()
{
this
.
pageData
=
this
.
makeEmptyPageDataTemplate
()
},
// 从缓存恢复数据
restorePageDataFromCache
()
{
const
_step1CachePageData
=
this
.
_step1CachePageData
if
(
this
.
isValidObject
(
_step1CachePageData
))
{
this
.
pageData
=
this
.
cloneObject
(
_step1CachePageData
)
}
else
{
this
.
initEmptyPageData
()
}
},
// 获取缓存的 step page data
initStepCachePageData
()
{
this
.
_step1CachePageData
=
this
.
cacheGetStepData
(
this
.
cacheKey
)
},
// 下一步
async
clickNextStep
()
{
try
{
await
Promise
.
all
([
this
.
$refs
.
busType
.
validate
(),
this
.
$refs
.
carCard
.
validate
()
])
this
.
nextStepHandler
()
}
catch
(
e
)
{
e
.
anchor
()
}
},
async
nextStepHandler
()
{
// 校验车卡关系
this
.
fullscreenLoading
=
true
const
retData
=
await
this
.
verifyVinCardsInfo
()
this
.
fullscreenLoading
=
false
if
(
retData
===
null
)
{
return
}
const
step1CachePageData
=
this
.
makeEmptyPageDataTemplate
()
step1CachePageData
.
busTypeData
=
this
.
$refs
.
busType
.
getPendingCacheData
()
step1CachePageData
.
carCardData
=
this
.
$refs
.
carCard
.
getPendingCacheData
()
this
.
cacheSetStepData
(
this
.
cacheKey
,
step1CachePageData
)
this
.
$router
.
push
({
name
:
'
PersonRealnameStep2
'
})
},
async
verifyVinCardsInfo
()
{
try
{
return
await
checkVinCard
(
this
.
getVerifyVinCardsInfoParams
(
this
.
$refs
.
carCard
.
getPendingCacheData
(),
{
businessType
:
this
.
isBind
?
2
:
1
}))
}
catch
(
e
)
{
return
null
}
},
makeEmptyPageDataTemplate
()
{
return
{
busTypeData
:
null
,
carCardData
:
null
}
}
}
}
</
script
>
<
style
lang=
"scss"
>
.page-person-real-step1
{
padding-bottom
:
64px
;
.next-step
{
z-index
:
5
;
}
}
</
style
>
src/views/realname-person/step2.vue
0 → 100644
View file @
d2c4018b
<
template
>
<div
class=
"page-person-real-step2"
>
<page-title
title=
"填写客户信息"
/>
<steps
:data=
"stepData"
:index=
"1"
/>
<div
v-if=
"pageData.userType === 'new'"
key=
"newUser"
>
<div
v-if=
"!pageData.isDelegate"
key=
"self"
>
<page-module
name=
"基本信息"
icon=
"info"
>
<comp-basic-info
ref=
"masterBasicInfo"
:data=
"masterBasicInfoData"
/>
</page-module>
<page-module
name=
"证件信息"
icon=
"idcard"
>
<comp-certificate-info
ref=
"masterCertInfo"
:data=
"masterCertInfoData"
@
read-cert=
"(data)=> onReadCert(data, 'master')"
/>
</page-module>
<page-module
name=
"文件信息"
icon=
"folder"
>
<CompMasterFileInfo
ref=
"masterFileInfo"
:data=
"masterFileInfoData"
:type=
"pageData.userType"
:attachment-url=
"attachmentUrl"
/>
</page-module>
<page-module
name=
"联系信息"
icon=
"tel"
>
<comp-concat-info
ref=
"masterConcatInfo"
:data=
"masterConcatInfoData"
/>
</page-module>
</div>
<div
v-else
key=
"delegate"
>
<page-module
name=
"车主基本信息"
icon=
"info"
>
<comp-basic-info
ref=
"masterBasicInfo"
:data=
"masterBasicInfoData"
/>
</page-module>
<page-module
name=
"车主证件信息"
icon=
"idcard"
>
<comp-certificate-info
ref=
"masterCertInfo"
:data=
"masterCertInfoData"
@
read-cert=
"(data)=> onReadCert(data, 'master')"
/>
</page-module>
<page-module
name=
"车主文件信息"
icon=
"folder"
>
<CompMasterFileInfo
ref=
"masterFileInfo"
:data=
"masterFileInfoData"
:type=
"pageData.userType"
:attachment-url=
"attachmentUrl"
/>
</page-module>
<page-module
name=
"车主联系信息"
icon=
"tel"
>
<comp-concat-info
ref=
"masterConcatInfo"
:data=
"masterConcatInfoData"
:need-vcode=
"false"
/>
</page-module>
<page-module
name=
"代办人基本信息"
icon=
"info"
>
<comp-basic-info
ref=
"delegateBasicInfo"
:data=
"delegateBasicInfoData"
:show-vin=
"false"
/>
</page-module>
<page-module
name=
"代办人证件信息"
icon=
"idcard"
>
<comp-certificate-info
ref=
"delegateCertInfo"
:data=
"delegateCertInfoData"
@
read-cert=
"(data)=> onReadCert(data, 'delegate')"
/>
</page-module>
<page-module
name=
"代办人文件信息"
icon=
"folder"
>
<file-info
ref=
"delegateFileInfo"
:limit=
"1"
:file-size=
"10"
:data=
"delegateFileInfoData"
label=
"委托书"
placeholder=
"上传文件"
/>
</page-module>
<page-module
name=
"代办人联系信息"
icon=
"tel"
>
<comp-concat-info
ref=
"delegateConcatInfo"
:data=
"delegateConcatInfoData"
/>
</page-module>
</div>
</div>
<div
v-else
key=
"oldUser"
>
<div
v-if=
"!pageData.isDelegate"
key=
"self"
>
<page-module
name=
"基本信息"
icon=
"info"
>
<comp-basic-info
ref=
"masterBasicInfo"
:data=
"masterBasicInfoData"
/>
</page-module>
<page-module
name=
"证件信息"
icon=
"idcard"
>
<comp-certificate-info
ref=
"masterCertInfo"
:data=
"masterCertInfoData"
@
read-cert=
"(data)=> onReadCert(data, 'master')"
/>
</page-module>
<page-module
name=
"文件信息"
icon=
"folder"
>
<CompMasterFileInfo
ref=
"masterFileInfo"
:data=
"masterFileInfoData"
:type=
"pageData.userType"
:attachment-url=
"attachmentUrl"
/>
</page-module>
<page-module
name=
"联系信息"
icon=
"tel"
>
<comp-concat-info
ref=
"masterConcatInfo"
:data=
"masterConcatInfoData"
/>
</page-module>
</div>
<div
v-else
key=
"delegate"
>
<page-module
name=
"车主基本信息"
icon=
"info"
>
<comp-basic-info
ref=
"masterBasicInfo"
:data=
"masterBasicInfoData"
/>
</page-module>
<page-module
name=
"车主证件信息"
icon=
"idcard"
>
<comp-certificate-info
ref=
"masterCertInfo"
:data=
"masterCertInfoData"
@
read-cert=
"(data)=> onReadCert(data, 'master')"
/>
</page-module>
<page-module
name=
"车主文件信息"
icon=
"folder"
>
<CompMasterFileInfo
ref=
"masterFileInfo"
:data=
"masterFileInfoData"
:type=
"pageData.userType"
:attachment-url=
"attachmentUrl"
/>
</page-module>
<page-module
name=
"车主联系信息"
icon=
"tel"
>
<comp-concat-info
ref=
"masterConcatInfo"
:data=
"masterConcatInfoData"
:need-vcode=
"false"
/>
</page-module>
<page-module
name=
"代办人基本信息"
icon=
"info"
>
<comp-basic-info
ref=
"delegateBasicInfo"
:data=
"delegateBasicInfoData"
:show-vin=
"false"
/>
</page-module>
<page-module
name=
"代办人证件信息"
icon=
"idcard"
>
<comp-certificate-info
ref=
"delegateCertInfo"
:data=
"delegateCertInfoData"
@
read-cert=
"(data)=> onReadCert(data, 'delegate')"
/>
</page-module>
<page-module
name=
"代办人文件信息"
icon=
"folder"
>
<file-info
ref=
"delegateFileInfo"
:limit=
"1"
:file-size=
"10"
:data=
"delegateFileInfoData"
label=
"委托书"
placeholder=
"上传文件"
/>
</page-module>
<page-module
name=
"代办人联系信息"
icon=
"tel"
>
<comp-concat-info
ref=
"delegateConcatInfo"
:data=
"delegateConcatInfoData"
/>
</page-module>
</div>
</div>
<div
class=
"next-step"
>
<el-button
size=
"small"
plain
@
click.stop=
"clickPrevStep"
>
上一步
</el-button>
<el-button
size=
"small"
type=
"primary"
@
click.stop=
"clickNextStep"
>
下一步
</el-button>
</div>
<comp-confirm
:show.sync=
"showErrorConfirm"
:desc=
"errorConfirmDesc"
/>
<CompAttachment
:vin=
"attachment.vin"
:iccid=
"attachment.iccid"
@
change=
"handleAttachmentChange"
/>
</div>
</
template
>
<
script
>
import
{
submitPersonRealNameAuthH5
,
checkSmsCaptcha
}
from
'
@/api/realname-person
'
import
CompAttachment
from
'
@/components/CompAttachment
'
import
PageTitle
from
'
@/components/PageTitle
'
import
Steps
from
'
@/components/Steps
'
import
Common
from
'
@/components/Common
'
import
CompBasicInfo
from
'
@/components/CompBasicInfo
'
import
CompCertificateInfo
from
'
@/components/CompCertificateInfo
'
import
CompConcatInfo
from
'
@/components/CompConcatInfo
'
import
CompMasterFileInfo
from
'
@/components/CompMasterFileInfo
'
import
FileInfo
from
'
@/components/FileInfo
'
import
ValidateStep
from
'
./components/validate-step
'
import
SelfCommon
from
'
./components/common
'
import
CompConfirm
from
'
@/components/CompConfirm
'
export
default
{
name
:
'
PersonRealnameStep2
'
,
components
:
{
PageTitle
,
Steps
,
CompBasicInfo
,
CompCertificateInfo
,
CompMasterFileInfo
,
FileInfo
,
CompConcatInfo
,
CompConfirm
,
CompAttachment
},
mixins
:
[
Common
,
SelfCommon
,
ValidateStep
],
data
()
{
return
{
stepData
:
[
'
车卡信息录入
'
,
'
填写客户信息
'
,
'
完成人脸识别
'
],
pageData
:
{
userType
:
''
,
isDelegate
:
false
,
vin
:
''
,
masterData
:
{
basicInfoData
:
{
vin
:
''
}
},
delegateData
:
{
basicInfoData
:
{}
}
},
attachment
:
{
vin
:
''
,
iccid
:
[]
},
attachmentUrl
:
''
,
showErrorConfirm
:
false
,
errorConfirmDesc
:
''
}
},
computed
:
{
masterData
()
{
return
this
.
pageData
.
masterData
||
{}
},
masterBasicInfoData
()
{
return
this
.
masterData
.
basicInfoData
||
{}
},
masterCertInfoData
()
{
return
this
.
masterData
.
certInfoData
||
{}
},
masterFileInfoData
()
{
return
this
.
masterData
.
fileInfoData
||
{}
},
masterConcatInfoData
()
{
return
this
.
masterData
.
concatInfoData
||
{}
},
delegateData
()
{
return
this
.
pageData
.
delegateData
||
{}
},
delegateBasicInfoData
()
{
return
this
.
delegateData
.
basicInfoData
||
{}
},
delegateCertInfoData
()
{
return
this
.
delegateData
.
certInfoData
||
{}
},
delegateFileInfoData
()
{
return
this
.
delegateData
.
fileInfoData
||
{}
},
delegateConcatInfoData
()
{
return
this
.
delegateData
.
concatInfoData
||
{}
}
},
methods
:
{
/**
* 附件变化方法
*/
handleAttachmentChange
(
val
)
{
this
.
attachmentUrl
=
val
},
errorTips
(
errMsg
)
{
this
.
showErrorConfirm
=
true
this
.
errorConfirmDesc
=
errMsg
},
async
init
()
{
this
.
initStepCachePageData
()
const
canEnter
=
await
this
.
canEnter
()
if
(
!
canEnter
)
{
this
.
$router
.
replace
({
name
:
'
PersonRealnameStep1
'
})
}
else
{
this
.
initRenderPage
()
}
},
async
show
()
{
this
.
initStepCachePageData
()
const
canEnter
=
await
this
.
canEnter
()
if
(
!
canEnter
)
{
this
.
$router
.
replace
({
name
:
'
PersonRealnameStep1
'
})
}
else
{
// 更新依赖数据
this
.
updateDepData
()
}
},
// 初始化空页面数据
initEmptyPageData
()
{
const
step1CachePageData
=
this
.
_step1CachePageData
this
.
pageData
=
this
.
makeEmptyPageDataTemplate
()
this
.
pageData
.
userType
=
(
step1CachePageData
.
busTypeData
||
{}).
userType
this
.
pageData
.
isDelegate
=
!!
((
step1CachePageData
.
busTypeData
||
{}).
isDelegate
)
this
.
pageData
.
vin
=
(
step1CachePageData
.
carCardData
||
{}).
vin
||
''
this
.
pageData
.
masterData
.
basicInfoData
.
vin
=
this
.
pageData
.
vin
},
// 从缓存恢复数据
restorePageDataFromCache
()
{
const
step2CachePageData
=
this
.
_step2CachePageData
if
(
this
.
isValidObject
(
step2CachePageData
))
{
this
.
pageData
=
this
.
cloneObject
(
step2CachePageData
)
}
else
{
this
.
initEmptyPageData
()
}
},
// 更新依赖前一步的数据
updateDepData
()
{
const
step1CachePageData
=
this
.
_step1CachePageData
this
.
pageData
.
userType
=
(
step1CachePageData
.
busTypeData
||
{}).
userType
this
.
pageData
.
isDelegate
=
!!
((
step1CachePageData
.
busTypeData
||
{}).
isDelegate
)
this
.
pageData
.
vin
=
(
step1CachePageData
.
carCardData
||
{}).
vin
||
''
if
(
this
.
isValidObject
(
this
.
pageData
.
masterData
)
&&
this
.
isValidObject
(
this
.
pageData
.
masterData
.
basicInfoData
))
{
this
.
pageData
.
masterData
.
basicInfoData
.
vin
=
this
.
pageData
.
vin
}
},
// 获取缓存的 step page data
initStepCachePageData
()
{
this
.
_step1CachePageData
=
this
.
cacheGetStepData
(
'
PersonRealnameStep1
'
)
this
.
_step2CachePageData
=
this
.
cacheGetStepData
(
this
.
cacheKey
)
if
(
this
.
_step1CachePageData
)
{
const
carCardData
=
this
.
_step1CachePageData
.
carCardData
||
{}
this
.
attachment
=
{
vin
:
carCardData
.
vin
,
iccid
:
carCardData
.
iccidList
.
filter
(
item
=>
item
.
iccid
!==
''
).
map
(
item
=>
item
.
iccid
)
}
}
},
// 是否可以进入当前页检查
async
canEnter
()
{
const
step1CachePageData
=
this
.
_step1CachePageData
const
result
=
await
this
.
step1Validate
(
step1CachePageData
)
return
result
},
// 上一步
clickPrevStep
()
{
this
.
$router
.
push
({
name
:
'
PersonRealnameStep1
'
,
params
:
{
from
:
'
prev
'
}
})
},
// 下一步
async
clickNextStep
()
{
try
{
const
validateList
=
[
this
.
$refs
.
masterBasicInfo
.
validate
(),
this
.
$refs
.
masterCertInfo
.
validate
(),
this
.
$refs
.
masterFileInfo
.
validate
(),
this
.
$refs
.
masterConcatInfo
.
validate
()
]
if
(
this
.
pageData
.
isDelegate
)
{
validateList
.
push
(...[
this
.
$refs
.
delegateBasicInfo
.
validate
(),
this
.
$refs
.
delegateCertInfo
.
validate
(),
this
.
$refs
.
delegateFileInfo
.
validate
(),
this
.
$refs
.
delegateConcatInfo
.
validate
()
])
}
await
Promise
.
all
(
validateList
)
// 校验车主和委托人证件信息
if
(
this
.
pageData
.
isDelegate
)
{
const
masterCertInfo
=
this
.
$refs
.
masterCertInfo
.
getPendingCacheData
()
const
delegateCertInfo
=
this
.
$refs
.
delegateCertInfo
.
getPendingCacheData
()
if
(
masterCertInfo
.
type
===
delegateCertInfo
.
type
&&
masterCertInfo
.
no
===
delegateCertInfo
.
no
)
{
this
.
errorTips
(
'
车主证件信息与委托代办人证件信息一致,请更换
'
)
return
}
}
// 手机号校验成功,则跳转下一步
this
.
clickNextStepHandler
()
}
catch
(
e
)
{
console
.
error
(
'
校验错误:
'
,
e
)
e
.
anchor
()
}
},
async
clickNextStepHandler
()
{
const
step2CachePageData
=
this
.
makeEmptyPageDataTemplate
()
step2CachePageData
.
userType
=
this
.
pageData
.
userType
step2CachePageData
.
isDelegate
=
this
.
pageData
.
isDelegate
step2CachePageData
.
vin
=
this
.
pageData
.
vin
const
masterBasicInfoData
=
this
.
$refs
.
masterBasicInfo
.
getPendingCacheData
()
const
masterCertInfoData
=
this
.
$refs
.
masterCertInfo
.
getPendingCacheData
()
const
masterFileInfoData
=
this
.
$refs
.
masterFileInfo
.
getPendingCacheData
()
const
masterConcatInfoData
=
this
.
$refs
.
masterConcatInfo
.
getPendingCacheData
()
step2CachePageData
.
masterData
=
{
basicInfoData
:
masterBasicInfoData
,
certInfoData
:
masterCertInfoData
,
fileInfoData
:
masterFileInfoData
,
concatInfoData
:
masterConcatInfoData
}
// 校验参数
let
phoneValidParams
=
{
phone
:
masterConcatInfoData
.
phone
,
captcha
:
masterConcatInfoData
.
veCode
}
if
(
this
.
pageData
.
isDelegate
)
{
const
delegateBasicInfoData
=
this
.
$refs
.
delegateBasicInfo
.
getPendingCacheData
()
const
delegateCertInfoData
=
this
.
$refs
.
delegateCertInfo
.
getPendingCacheData
()
const
delegateFileInfoData
=
this
.
$refs
.
delegateFileInfo
.
getPendingCacheData
()
const
delegateConcatInfoData
=
this
.
$refs
.
delegateConcatInfo
.
getPendingCacheData
()
step2CachePageData
.
delegateData
=
{
basicInfoData
:
delegateBasicInfoData
,
certInfoData
:
delegateCertInfoData
,
fileInfoData
:
delegateFileInfoData
,
concatInfoData
:
delegateConcatInfoData
}
phoneValidParams
=
{
phone
:
delegateConcatInfoData
.
phone
,
captcha
:
delegateConcatInfoData
.
veCode
}
}
this
.
cacheSetStepData
(
this
.
cacheKey
,
step2CachePageData
)
// 如果当前是平板下,调用h5的接口,跳转腾讯活体
if
(
window
.
OS
.
isTablet
)
{
// 请求入参
const
reqData
=
this
.
getSubmitPersonRealNameAuthParams
({
step1Data
:
this
.
cacheGetStepData
(
'
PersonRealnameStep1
'
),
step2Data
:
this
.
cacheGetStepData
(
'
PersonRealnameStep2
'
)
})
// 开始提交接口
const
{
h5LivenessUrl
}
=
await
submitPersonRealNameAuthH5
({
...(
reqData
||
{}),
source
:
'
PAD
'
})
// 跳转去活体
window
.
location
.
href
=
h5LivenessUrl
return
}
// 校验手机号输入是否正确
await
checkSmsCaptcha
(
phoneValidParams
)
this
.
$router
.
push
({
name
:
'
PersonRealnameStep3
'
})
},
makeEmptyPageDataTemplate
()
{
return
{
userType
:
''
,
isDelegate
:
false
,
vin
:
''
,
masterData
:
{
basicInfoData
:
{
vin
:
''
}
},
delegateData
:
{
basicInfoData
:
{}
}
}
},
onReadCert
(
data
,
type
)
{
if
(
type
===
'
master
'
)
{
this
.
$set
(
this
.
pageData
.
masterData
.
basicInfoData
,
'
name
'
,
data
.
name
)
this
.
$set
(
this
.
pageData
.
masterData
.
basicInfoData
,
'
sex
'
,
data
.
gender
)
this
.
$refs
.
masterCertInfo
.
validate
()
}
else
{
this
.
$set
(
this
.
pageData
.
delegateData
.
basicInfoData
,
'
name
'
,
data
.
name
)
this
.
$set
(
this
.
pageData
.
delegateData
.
basicInfoData
,
'
sex
'
,
data
.
gender
)
this
.
$refs
.
delegateCertInfo
.
validate
()
}
this
.
$refs
.
masterBasicInfo
.
validate
()
}
}
}
</
script
>
<
style
lang=
"scss"
>
.page-person-real-step2
{
padding-bottom
:
64px
;
.next-step
{
z-index
:
5
;
}
}
</
style
>
src/views/realname-person/step3.vue
0 → 100644
View file @
d2c4018b
<
template
>
<div
v-loading.fullscreen.lock=
"fullscreenLoading"
class=
"page-person-real-step3"
>
<page-title
title=
"完成人脸识别"
/>
<steps
:data=
"stepData"
:index=
"2"
/>
<PageModuleTabs
:tabs=
"TABS"
v-if=
"device.showTakePhoto"
v-model=
"tabName"
>
<CompFaceRecognition
ref=
"face"
:type=
"livenessType"
:take=
"tabName == 'carmer'"
:data=
"faceData"
/>
</PageModuleTabs>
<page-module
v-else
name=
"活体视频上传"
icon=
"video"
>
<CompFaceRecognition
ref=
"face"
:type=
"livenessType"
:data=
"faceData"
/>
</page-module>
<div
class=
"next-step"
>
<el-button
size=
"small"
plain
@
click.stop=
"clickPrevStep"
>
上一步
</el-button>
<el-button
size=
"small"
type=
"primary"
@
click.stop=
"clickNextStep"
>
提交
</el-button>
</div>
<comp-confirm
:show.sync=
"showErrorConfirm"
:desc=
"errorConfirmDesc"
/>
<comp-confirm
:show.sync=
"showSuccessConfirm"
:desc=
"successConfirmDesc"
type=
"success"
@
on-sure=
"successSureHandler"
/>
</div>
</
template
>
<
script
>
import
{
mapGetters
}
from
'
vuex
'
import
PageModuleTabs
from
'
@/components/PageModule/tabs
'
import
{
submitPersonRealNameAuth
,
getLivenessCode
}
from
'
@/api/realname-person
'
import
PageTitle
from
'
@/components/PageTitle
'
import
Steps
from
'
@/components/Steps
'
import
Common
from
'
@/components/Common
'
import
CompConfirm
from
'
@/components/CompConfirm
'
import
CompFaceRecognition
from
'
@/components/CompFaceRecognition
'
import
ValidateStep
from
'
./components/validate-step
'
import
SelfCommon
from
'
./components/common
'
const
TABS
=
[
{
label
:
'
活体视频上传
'
,
value
:
'
video
'
,
icon
:
require
(
'
@/assets/image/video@2x.png
'
)
},
{
label
:
'
在线拍摄视频
'
,
value
:
'
carmer
'
,
icon
:
require
(
'
@/assets/image/icon_user@2x.png
'
)
}
]
export
default
{
name
:
'
PersonRealnameStep3
'
,
components
:
{
PageTitle
,
Steps
,
CompConfirm
,
CompFaceRecognition
,
PageModuleTabs
},
mixins
:
[
Common
,
SelfCommon
,
ValidateStep
],
data
()
{
return
{
fullscreenLoading
:
false
,
showErrorConfirm
:
false
,
errorConfirmDesc
:
''
,
showSuccessConfirm
:
false
,
successConfirmDesc
:
''
,
stepData
:
[
'
车卡信息录入
'
,
'
填写客户信息
'
,
'
完成人脸识别
'
],
livenessType
:
''
,
pageData
:
{},
tabName
:
'
video
'
,
TABS
}
},
computed
:
{
...
mapGetters
([
'
device
'
]),
faceData
()
{
return
this
.
pageData
.
faceData
||
{}
}
},
methods
:
{
errorTips
(
errMsg
)
{
this
.
showErrorConfirm
=
true
this
.
errorConfirmDesc
=
errMsg
},
successTips
(
msg
)
{
this
.
showSuccessConfirm
=
true
this
.
successConfirmDesc
=
msg
},
async
init
()
{
this
.
fullscreenLoading
=
true
this
.
_remoteLiveData
=
await
this
.
getLivenessCode
()
this
.
fullscreenLoading
=
false
this
.
initStepCachePageData
()
const
canEnter
=
await
this
.
canEnter
()
if
(
!
canEnter
)
{
this
.
$router
.
replace
({
name
:
'
PersonRealnameStep1
'
})
}
else
{
this
.
initRenderPage
()
}
},
async
show
()
{
this
.
initStepCachePageData
()
const
canEnter
=
await
this
.
canEnter
()
if
(
!
canEnter
)
{
this
.
$router
.
replace
({
name
:
'
PersonRealnameStep1
'
})
}
else
{
this
.
updateDepData
()
}
},
// 初始化空页面数据
initEmptyPageData
()
{
this
.
pageData
=
this
.
makeEmptyPageDataTemplate
()
this
.
livenessType
=
this
.
_remoteLiveData
?
this
.
_remoteLiveData
.
livenessType
:
''
this
.
pageData
.
faceData
=
{
number
:
this
.
_remoteLiveData
?
this
.
_remoteLiveData
.
livenessCode
:
''
}
},
// 从缓存恢复数据
restorePageDataFromCache
()
{
const
step3CachePageData
=
this
.
_step3CachePageData
if
(
this
.
isValidObject
(
step3CachePageData
))
{
this
.
pageData
=
this
.
cloneObject
(
step3CachePageData
)
}
else
{
this
.
initEmptyPageData
()
}
},
updateDepData
()
{
// todo
},
// 获取缓存的 step page data
initStepCachePageData
()
{
this
.
_step1CachePageData
=
this
.
cacheGetStepData
(
'
PersonRealnameStep1
'
)
this
.
_step2CachePageData
=
this
.
cacheGetStepData
(
'
PersonRealnameStep2
'
)
this
.
_step3CachePageData
=
this
.
cacheGetStepData
(
this
.
cacheKey
)
},
// 是否可以进入当前页检查
async
canEnter
()
{
const
step1IsOk
=
await
this
.
step1Validate
(
this
.
_step1CachePageData
)
const
step2IsOk
=
await
this
.
step2Validate
(
this
.
_step2CachePageData
)
return
step1IsOk
&&
step2IsOk
},
// 上一步
clickPrevStep
()
{
this
.
$router
.
push
({
name
:
'
PersonRealnameStep2
'
,
params
:
{
from
:
'
prev
'
}
})
},
// 下一步
async
clickNextStep
()
{
if
(
this
.
faceData
.
number
===
''
)
{
this
.
errorTips
(
'
获取活体数字验证码失败,请刷新页面重试
'
)
return
}
try
{
await
this
.
$refs
.
face
.
validate
()
this
.
clickNextStepHandler
()
}
catch
(
e
)
{
e
.
anchor
()
}
},
async
clickNextStepHandler
()
{
const
submitData
=
{
step1Data
:
this
.
_step1CachePageData
,
step2Data
:
this
.
_step2CachePageData
,
step3Data
:
{
fileData
:
this
.
$refs
.
face
.
getFormData
(),
number
:
this
.
faceData
.
number
,
requestId
:
this
.
_remoteLiveData
.
requestId
}
}
this
.
fullscreenLoading
=
true
const
respData
=
await
this
.
submitPersonRealNameAuth
(
this
.
getSubmitPersonRealNameAuthParams
(
submitData
))
this
.
fullscreenLoading
=
false
if
(
!
respData
.
isOk
)
{
this
.
errorTips
(
respData
.
data
.
message
||
'
实名认证失败
'
)
return
}
if
(
respData
.
data
.
verifyStatus
===
0
)
{
this
.
successTips
(
'
实名认证成功
'
)
}
else
if
(
respData
.
data
.
verifyStatus
===
1
)
{
this
.
successTips
(
'
已转入人工审核,请注意查询认证进度
'
)
}
else
{
this
.
errorTips
(
'
实名认证失败
'
)
}
},
successSureHandler
()
{
this
.
$router
.
push
({
name
:
'
Home
'
})
},
makeEmptyPageDataTemplate
()
{
return
{
faceData
:
null
}
},
async
submitPersonRealNameAuth
(
params
)
{
try
{
const
respData
=
await
submitPersonRealNameAuth
({
data
:
{
...
params
},
hideToast
:
true
})
return
{
isOk
:
true
,
data
:
respData
}
}
catch
(
e
)
{
return
{
isOk
:
false
,
data
:
e
}
}
},
async
getLivenessCode
()
{
try
{
const
ret
=
await
getLivenessCode
()
return
ret
}
catch
(
e
)
{
return
null
}
}
}
}
</
script
>
<
style
lang=
"scss"
>
.page-person-real-step3
{
padding-bottom
:
64px
;
.next-step
{
z-index
:
5
;
}
}
</
style
>
src/views/search/car-auth1.vue
0 → 100644
View file @
d2c4018b
<
template
>
<div
v-loading.fullscreen.lock=
"fullscreenLoading"
class=
"page page-search page-car-auth"
>
<div
class=
"manage-title"
>
单车认证查询
</div>
<div
class=
"search-form"
>
<el-form
ref=
"searchForm"
:rules=
"rules"
:model=
"searchForm"
label-width=
"90px"
size=
"small"
@
submit.native.prevent
>
<el-row
:gutter=
"20"
>
<el-col
:span=
"12"
>
<el-form-item
label=
"车辆VIN码"
prop=
"vin"
>
<el-input
v-model=
"searchForm.vin"
maxlength=
"17"
placeholder=
"请输入车辆VIN码"
clearable
/>
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-button
size=
"small"
type=
"primary"
icon=
"iconfont icon-search"
@
click=
"onSearch"
>
搜索
</el-button>
<el-button
size=
"small"
type=
"gray"
icon=
"iconfont icon-clear"
@
click=
"onClear"
>
清除
</el-button>
</el-col>
</el-row>
</el-form>
</div>
<div
class=
"search-body"
>
<div
class=
"search-title"
>
认证进度查询结果
</div>
<div
v-if=
"list.length > 0"
>
<div
v-for=
"(item, index) in list"
:key=
"index"
class=
"auth-content"
>
<div
class=
"auth-date"
>
<div
v-if=
"item.year"
>
{{
item
.
year
}}
年
</div>
</div>
<div
class=
"auth-step"
>
<div
class=
"step-item"
>
<div
class=
"step-time"
>
申请时间:
{{
item
.
startCheckDate
}}
</div>
<div
class=
"step-cont"
>
<div
class=
"step-head"
>
<div
class=
"step-name"
>
{{
item
.
title
}}
</div>
<el-tag
v-if=
"[0, 1, 2].includes(+item.orderStatus)"
size=
"mini"
type=
"warning"
>
{{
AUDIT_STATUS
[
item
.
orderStatus
]
}}
</el-tag>
<el-tag
v-else-if=
"+item.orderStatus === 3"
size=
"mini"
type=
"success"
>
{{
AUDIT_STATUS
[
item
.
orderStatus
]
}}
</el-tag>
<el-tag
v-else-if=
"[4, 9].includes(+item.orderStatus)"
size=
"mini"
type=
"danger"
>
{{
AUDIT_STATUS
[
item
.
orderStatus
]
}}
</el-tag>
</div>
<ul
class=
"step-body"
>
<li>
ICCID:
{{
item
.
iccid
}}
</li>
<li>
组织名称:
{{
item
.
orgName
||
'
-
'
}}
</li>
<li>
车主/责任人:
{{
item
.
fullName
}}
</li>
<li>
手机号:
{{
item
.
phone
}}
</li>
<li>
所属企业:
{{
item
.
companyName
||
'
-
'
}}
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<div
v-else
class=
"empty-data"
>
暂无数据
</div>
</div>
</div>
</
template
>
<
script
>
import
{
carAuthList1
}
from
'
@/api/search
'
const
AUDIT_STATUS
=
[
'
已提交
'
,
'
待分派/认领
'
,
'
待审核
'
,
'
审核通过
'
,
'
未通过
'
,
''
,
''
,
''
,
''
,
'
作废
'
]
export
default
{
name
:
'
CarAuth1
'
,
data
()
{
const
checkVin
=
(
rule
,
value
,
callback
)
=>
{
if
(
!
value
)
{
callback
(
new
Error
(
'
车辆VIN码不能为空
'
))
}
else
if
(
value
.
length
!==
17
)
{
callback
(
new
Error
(
'
车辆VIN码格式不正确
'
))
}
else
{
callback
()
}
}
return
{
fullscreenLoading
:
false
,
searchForm
:
{
vin
:
''
},
AUDIT_STATUS
,
searchData
:
{},
list
:
[],
rules
:
{
vin
:
[
{
required
:
true
,
trigger
:
'
blur
'
,
message
:
'
车辆VIN码不能为空
'
},
{
validator
:
checkVin
,
trigger
:
'
blur
'
}
]
}
}
},
methods
:
{
/**
* 获取数据
* @time 2021-11-06 13:23:29
*/
async
getData
()
{
const
param
=
{
...
this
.
searchData
}
this
.
fullscreenLoading
=
true
try
{
const
data
=
await
carAuthList1
(
param
)
this
.
list
=
data
||
[]
const
dataInfo
=
{}
const
{
businessType
}
=
this
.
$store
.
getters
.
dict
this
.
list
.
forEach
(
item
=>
{
const
time
=
item
.
startCheckDate
.
substring
(
0
,
4
)
if
(
!
dataInfo
[
time
])
{
dataInfo
[
time
]
=
[]
item
.
year
=
time
}
dataInfo
[
time
].
push
(
item
)
item
.
title
=
businessType
.
find
(
type
=>
+
type
.
value
===
+
item
.
orderType
).
label
})
}
catch
(
error
)
{
console
.
error
(
error
)
}
this
.
fullscreenLoading
=
false
},
/**
* 搜索事件
* @time 2021-11-06 14:45:23
*/
onSearch
()
{
this
.
$refs
.
searchForm
.
validate
(
valid
=>
{
if
(
valid
)
{
this
.
searchData
=
{
...
this
.
searchForm
}
this
.
getData
()
}
})
},
/**
* 清除事件
* @time 2021-11-06 14:45:23
*/
onClear
()
{
this
.
$refs
.
searchForm
.
resetFields
()
this
.
searchData
=
{
...
this
.
searchForm
}
this
.
list
=
[]
// this.getData()
}
}
}
</
script
>
<
style
lang=
"scss"
>
.page-car-auth
{
padding
:
24px
;
.search-body
{
.auth-date
{
margin-top
:
-6px
;
}
}
}
</
style
>
src/views/search/car-auth2.vue
0 → 100644
View file @
d2c4018b
<
template
>
<div
class=
"page-search page-auth-search"
>
<div
class=
"page-car-auth"
>
<div
class=
"manage-title"
>
态势感知看板(截止昨日)
</div>
<div
class=
"search-count"
>
<dl
class=
"count-item count1"
>
<dt>
自然人实名数
</dt>
<dd>
{{
statistics
.
peopleRnrNum
||
0
}}
</dd>
</dl>
<dl
class=
"count-item count2"
>
<dt>
企业实名数
</dt>
<dd>
{{
statistics
.
companyRnrNum
||
0
}}
</dd>
</dl>
<dl
class=
"count-item count3"
>
<dt>
车企实名成功率
</dt>
<dd>
{{
statistics
.
vehicleCompanyRnrSuccessRate
}}
</dd>
</dl>
<dl
class=
"count-item count4"
>
<dt>
车企人工审核平均时长
</dt>
<dd>
{{
statistics
.
vehicleHandleTimeAvg
}}
</dd>
</dl>
</div>
</div>
<SearchTable
title=
"认证进度查询"
ref=
"searchTableRef"
v-model=
"searchForm"
@
reset=
"handleReset"
@
submit=
"handleSubmit"
>
<template
#slot-form
>
<el-col
:span=
"isTablet ? 12 : 6"
>
<el-form-item
label=
"车辆VIN码"
prop=
"vin"
label-width=
"120px"
>
<el-input
v-model=
"searchForm.vin"
placeholder=
"请输入车辆VIN码"
clearable
/>
</el-form-item>
</el-col>
<el-col
:span=
"isTablet ? 12 : 6"
>
<el-form-item
label=
"关联ICCID"
prop=
"iccid"
label-width=
"120px"
>
<el-input
v-model=
"searchForm.iccid"
placeholder=
"请输入关联ICCID"
clearable
/>
</el-form-item>
</el-col>
<el-col
:span=
"isTablet ? 12 : 6"
:class=
"isTablet ? 'mt-16' : ''"
>
<el-form-item
label=
"车主/企业责任人"
prop=
"user"
label-width=
"120px"
>
<el-input
v-model=
"searchForm.user"
placeholder=
"请输入车主/企业责任人"
clearable
/>
</el-form-item>
</el-col>
<el-col
:span=
"isTablet ? 12 : 6"
:class=
"isTablet ? 'mt-16' : ''"
>
<el-form-item
label=
"车主/责任人手机"
prop=
"userPhone"
label-width=
"120px"
>
<el-input
v-model=
"searchForm.userPhone"
placeholder=
"请输入车主/责任人手机号码"
clearable
/>
</el-form-item>
</el-col>
<el-col
:span=
"isTablet ? 24 : 12"
class=
"mt-16"
>
<el-form-item
label=
"提审日期"
prop=
"sendCheck"
label-width=
"120px"
>
<el-date-picker
v-model=
"searchForm.sendCheck"
:editable=
"false"
type=
"datetimerange"
start-placeholder=
"请选择开始时间"
end-placeholder=
"请选择结束时间"
align=
"right"
/>
</el-form-item>
</el-col>
<el-col
:span=
"isTablet ? 12 : 6"
class=
"mt-16"
>
<el-form-item
label=
"业务类型"
prop=
"orderType"
label-width=
"120px"
>
<el-select
v-model=
"searchForm.orderType"
placeholder=
"请选择业务类型"
clearable
>
<el-option
v-for=
"item in dict.businessType"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col
:span=
"isTablet ? 12 : 6"
class=
"mt-16"
>
<el-form-item
label=
"审核进度"
prop=
"status"
label-width=
"120px"
>
<el-select
v-model=
"searchForm.checkStatus"
placeholder=
"请选择审核进度"
clearable
>
<el-option
v-for=
"status in auditStatus"
v-bind=
"status"
:key=
"status.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col
:span=
"isTablet ? 12 : 6"
class=
"mt-16"
>
<el-form-item
label=
"企业名称"
prop=
"companyName"
label-width=
"120px"
>
<el-input
v-model=
"searchForm.companyName"
placeholder=
"请输入企业名称"
clearable
/>
</el-form-item>
</el-col>
<!--
<el-col
:span=
"isTablet ? 12 : 6"
class=
"mt-16"
>
<el-form-item
label=
"组织名称"
prop=
"carCompanyName"
label-width=
"120px"
>
<el-input
v-model=
"searchForm.carCompanyName"
placeholder=
"请输入车企名称"
clearable
/>
</el-form-item>
</el-col>
-->
<!--
<el-col
:span=
"6"
class=
"mt-16"
>
<el-form-item
label=
"经销商名称"
prop=
"dealer"
label-width=
"120px"
>
<el-input
v-model=
"searchForm.dealer"
placeholder=
"请输入经销商名称"
clearable
/>
</el-form-item>
</el-col>
-->
<!--
<el-col
:span=
"8"
>
<el-form-item
label=
"审核人"
prop=
"operator"
>
<el-input
v-model=
"searchForm.operator"
placeholder=
"请输入审核人"
clearable
/>
</el-form-item>
</el-col>
-->
<!--
<el-col
:span=
"12"
class=
"mt-16"
>
<el-form-item
label=
"审核日期"
prop=
"auditTime"
label-width=
"120px"
>
<el-date-picker
v-model=
"searchForm.auditTime"
:editable=
"false"
type=
"datetimerange"
start-placeholder=
"提交开始时间"
end-placeholder=
"提交结束时间"
align=
"right"
/>
</el-form-item>
</el-col>
-->
</
template
>
<
template
#slot-table
>
<el-table-column
label=
"认证进度"
fixed=
"left"
prop=
"orderStatus"
min-width=
"150"
>
<template
slot-scope=
"scope"
>
<span
v-if=
"[0, 1, 2].includes(+scope.row.orderStatus)"
class=
"status warning"
>
{{
AUDIT_STATUS
[
scope
.
row
.
orderStatus
]
}}
</span>
<span
v-else-if=
"+scope.row.orderStatus === 3"
class=
"status success"
>
{{
AUDIT_STATUS
[
scope
.
row
.
orderStatus
]
}}
</span>
<span
v-else-if=
"[4, 9].includes(+scope.row.orderStatus)"
class=
"status fail"
>
{{
AUDIT_STATUS
[
scope
.
row
.
orderStatus
]
}}
</span>
</
template
>
</el-table-column>
<el-table-column
label=
"车辆VIN码"
prop=
"iotId"
min-width=
"200"
/>
<el-table-column
label=
"关联ICCID"
prop=
"iccid"
min-width=
"200"
/>
<el-table-column
label=
"企业名称"
prop=
"companyName"
min-width=
"230"
show-overflow-tooltip
/>
<el-table-column
label=
"车主/责任人"
prop=
"fullName"
min-width=
"150"
/>
<el-table-column
label=
"车主/责任人手机"
prop=
"phone"
min-width=
"200"
/>
<el-table-column
label=
"认证日期"
prop=
"startCheckDate"
min-width=
"200"
/>
<el-table-column
label=
"组织名称"
prop=
"orgName"
min-width=
"230"
show-overflow-tooltip
/>
<el-table-column
label=
"业务类型"
min-width=
"180"
>
<
template
slot-scope=
"scope"
>
<span>
{{
getOrderType
(
scope
.
row
)
}}
</span>
</
template
>
</el-table-column>
<el-table-column
label=
"审核人"
prop=
"checkUser"
min-width=
"140"
/>
<el-table-column
label=
"审核日期"
prop=
"endCheckDate"
min-width=
"180"
/>
</template>
</SearchTable>
</div>
</template>
<
script
>
import
SearchTable
from
'
@/components/SearchTable
'
import
{
mapGetters
}
from
'
vuex
'
import
{
carAuthList2
,
queryCheckStatistics
}
from
'
@/api/search
'
const
AUDIT_STATUS
=
[
'
已提交
'
,
'
待分派/认领
'
,
'
待审核
'
,
'
审核通过
'
,
'
未通过
'
,
''
,
''
,
''
,
''
,
'
作废
'
]
const
ORDER_TYPE
=
[
''
,
'
自然人实名认证
'
,
'
自然人代办人实名认证
'
,
'
自然人二手车实名认证
'
,
'
自然人二手车代办人实名认证
'
,
'
自然人二手车解绑
'
,
'
企业实名认证
'
,
'
企业责任人变更
'
]
export
default
{
name
:
'
CarAuth2
'
,
components
:
{
SearchTable
},
data
()
{
return
{
totalCount
:
0
,
searchForm
:
{
vin
:
''
,
iccid
:
''
,
user
:
''
,
sendCheck
:
[],
userPhone
:
''
,
orderType
:
''
,
checkStatus
:
''
,
companyName
:
''
,
carCompanyName
:
''
,
dealer
:
''
,
operator
:
''
,
auditTime
:
[]
},
// 统计看板数据
statistics
:
{},
AUDIT_STATUS
,
ORDER_TYPE
,
list
:
[],
isTablet
:
window
.
OS
.
isTablet
}
},
computed
:
{
...
mapGetters
([
'
dict
'
]),
// 审核状态
auditStatus
()
{
return
AUDIT_STATUS
.
map
((
item
,
index
)
=>
{
return
{
label
:
item
,
value
:
index
}
}).
filter
(
item
=>
!!
item
.
label
)
}
},
async
mounted
()
{
this
.
statistics
=
await
queryCheckStatistics
()
||
{}
},
methods
:
{
/**
* 获取订单类型
*/
getOrderType
(
row
)
{
try
{
return
this
.
dict
.
businessType
.
find
(
type
=>
+
type
.
value
===
+
row
.
orderType
).
label
}
catch
(
error
)
{
return
''
}
},
/**
* 获取数据
* @param formData 表格数据
* @param callback 回调函数
*/
async
handleSubmit
(
formData
,
callback
)
{
try
{
const
formDataCopy
=
{
...
formData
}
// 如果当前选择了提审时间
if
(
formDataCopy
.
sendCheck
&&
formDataCopy
.
sendCheck
.
length
>
0
)
{
formDataCopy
.
startSendCheck
=
formDataCopy
.
sendCheck
[
0
]
formDataCopy
.
endSendCheck
=
formDataCopy
.
sendCheck
[
1
]
}
// 如果当前选择了审核时间
if
(
formDataCopy
.
auditTime
&&
formDataCopy
.
auditTime
.
length
>
0
)
{
formDataCopy
.
startCheck
=
formDataCopy
.
auditTime
[
0
]
formDataCopy
.
endCheck
=
formDataCopy
.
auditTime
[
1
]
}
// 是否车企实名
formDataCopy
.
isVehicleCompany
=
!
formDataCopy
.
carCompanyName
?
0
:
1
// 删除原来的数据
delete
formDataCopy
.
sendCheck
delete
formDataCopy
.
auditTime
// 列表数据
const
respData
=
await
carAuthList2
(
formDataCopy
)
// 开始渲染页面
callback
(
respData
)
}
catch
(
error
)
{
console
.
error
(
error
)
}
},
/**
* 重置方法
*/
handleReset
()
{
Object
.
keys
(
this
.
searchForm
).
forEach
(
key
=>
{
this
.
searchForm
[
key
]
=
[
'
string
'
,
'
number
'
].
includes
(
typeof
key
)
?
''
:
[]
})
},
/**
* 清除事件
* @time 2021-11-06 14:45:23
*/
onClear
()
{
this
.
searchForm
.
currPage
=
1
this
.
$refs
.
searchForm
.
resetFields
()
this
.
searchData
=
{
...
this
.
searchForm
}
this
.
list
=
[]
// this.getData()
}
}
}
</
script
>
<
style
lang=
"scss"
>
.page-auth-search
{
.page-car-auth
{
padding
:
24px
24px
0
;
}
.search-count
{
margin
:
0
auto
;
background
:
#fff
;
box-sizing
:
border-box
;
display
:
flex
;
justify-content
:
space-between
;
align-items
:
center
;
.count-item
{
margin-right
:
24px
;
padding
:
24px
;
box-sizing
:
border-box
;
width
:
25%
;
height
:
112px
;
color
:
#fff
;
border-radius
:
4px
;
background-size
:
100%
112px
;
background-position
:
0
0
;
background-repeat
:
no-repeat
;
display
:
flex
;
align-items
:
flex-start
;
flex-direction
:
column
;
justify-content
:
center
;
position
:
relative
;
overflow
:
hidden
;
&
:before
{
content
:
''
;
width
:
118px
;
height
:
112px
;
background
:
url(../../assets/image/count_light.png)
no-repeat
0
0
/
118px
112px
;
position
:
absolute
;
left
:
0
;
top
:
0
;
}
&
:after
{
content
:
''
;
width
:
100px
;
height
:
100px
;
position
:
absolute
;
right
:
0
;
bottom
:
0
;
}
&
:last-child
{
margin-right
:
0
;
}
&
.count1
{
background
:
linear-gradient
(
90deg
,
#77B4FF
0%
,
#2A68FF
100%
);
&
:after
{
background
:
url(../../assets/image/count1.png)
no-repeat
0
0
/
100px
100px
;
}
}
&
.count2
{
background
:
linear-gradient
(
90deg
,
#6A8EFF
0%
,
#2A4EFF
100%
);
&
:after
{
background
:
url(../../assets/image/count2.png)
no-repeat
0
0
/
100px
100px
;
}
}
&
.count3
{
background
:
linear-gradient
(
90deg
,
#70E592
0%
,
#1EB980
100%
);
&
:after
{
background
:
url(../../assets/image/count3.png)
no-repeat
0
0
/
100px
100px
;
}
}
&
.count4
{
background
:
linear-gradient
(
90deg
,
#59BEF8
0%
,
#0D7FE1
100%
);
&
:after
{
background
:
url(../../assets/image/count4.png)
no-repeat
0
0
/
100px
100px
;
}
}
dt
{
font-size
:
14px
;
font-family
:
PingFangSC-Regular
,
PingFang
SC
;
font-weight
:
400
;
}
dd
{
margin-top
:
5px
;
font-size
:
28px
;
font-family
:
PingFangSC-Medium
,
PingFang
SC
;
font-weight
:
500
;
position
:
relative
;
white-space
:
nowrap
;
z-index
:
1
;
i
{
font-size
:
18px
;
font-family
:
PingFangSC-Medium
,
PingFang
SC
;
font-weight
:
500
;
font-style
:
normal
;
}
}
}
}
.status
{
position
:
relative
;
padding-left
:
10px
;
&
.success
:before
{
background
:
#25C343
;
}
&
.warning
:before
{
background
:
#FF9C00
;
}
&
.fail
:before
{
background
:
#FF4D4F
;
}
&
:before
{
content
:
''
;
width
:
6px
;
height
:
6px
;
border-radius
:
3px
;
left
:
-5px
;
top
:
50%
;
margin-top
:
-3px
;
position
:
absolute
;
}
}
.mt-16
{
margin-top
:
16px
;
}
.el-col
{
&
:last-child
{
margin-top
:
16px
;
}
}
}
</
style
>
src/views/search/check-account.vue
0 → 100644
View file @
d2c4018b
<
template
>
<SearchTable
title=
"服务对账"
ref=
"searchTableRef"
v-model=
"formData"
@
submit=
"handleSubmit"
>
<template
#slot-form
>
<el-col
:span=
"isTablet ? 12 : 6"
>
<el-form-item
label=
"月份"
prop=
"vin"
label-width=
"120px"
>
<el-date-picker
v-model=
"formData.month"
type=
"monthrange"
range-separator=
"至"
start-placeholder=
"开始月份"
end-placeholder=
"结束月份"
/>
</el-form-item>
</el-col>
</
template
>
<
template
#slot-table
>
<el-table-column
label=
"月份"
prop=
"month"
min-width=
"200"
/>
<el-table-column
label=
"服务类型"
prop=
"serviceType"
min-width=
"200"
/>
<el-table-column
label=
"调用次数"
prop=
"time"
min-width=
"200"
/>
</
template
>
</SearchTable>
</template>
<
script
>
import
SearchTable
from
'
@/components/SearchTable
'
export
default
{
name
:
'
CheckAccount
'
,
components
:
{
SearchTable
},
data
()
{
return
{
isTablet
:
window
.
OS
.
isTablet
,
formData
:
{}
}
},
methods
:
{
/**
* 触发提交方法
* @param formData 当前表单填写的内容
* @param callback 回调函数
*/
handleSubmit
(
formData
,
callback
)
{
console
.
log
(
'
formData:
'
,
formData
)
callback
({
list
:
[],
total
:
0
})
}
}
}
</
script
>
<
style
lang=
"scss"
>
</
style
>
src/views/search/system-log.vue
0 → 100644
View file @
d2c4018b
<
template
>
<SearchTable
class=
"page-search-system-log"
title=
"日志查询"
ref=
"searchTableRef"
v-model=
"formData"
@
submit=
"handleSubmit"
@
reset=
"handleReset"
>
<template
#slot-form
>
<el-col
:span=
"isTablet ? 12 : 6"
>
<el-form-item
label=
"组织"
label-width=
"80px"
prop=
"orgId"
>
<Organ
v-model=
"formData.orgId"
:type=
"0"
/>
</el-form-item>
</el-col>
<el-col
:span=
"isTablet ? 12 : 6"
>
<el-form-item
label=
"用户名"
prop=
"account"
label-width=
"80px"
>
<el-input
v-model=
"formData.account"
placeholder=
"请输入用户名"
clearable
/>
</el-form-item>
</el-col>
<el-col
:span=
"isTablet ? 12 : 6"
:style=
"
{ marginTop: isTablet ? '16px' : '0px' }">
<el-form-item
label=
"手机号"
prop=
"phone"
label-width=
"80px"
>
<el-input
v-model=
"formData.phone"
maxlength=
"11"
placeholder=
"请输入手机号"
clearable
/>
</el-form-item>
</el-col>
<el-col
:span=
"isTablet ? 12 : 6"
:style=
"
{ marginTop: isTablet ? '16px' : '0px' }">
<el-form-item
label=
"日志类型"
prop=
"logCategory"
label-width=
"80px"
>
<el-select
v-model=
"formData.logCategory"
placeholder=
"请选择日志类型"
clearable
@
change=
"formData.logOpt = ''"
>
<el-option
v-for=
"(logType, index) in logCategorys"
:label=
"logType.logCategory"
:value=
"logType.logCategory"
:key=
"index"
/>
</el-select>
</el-form-item>
</el-col>
<el-col
:span=
"isTablet ? 12 : 6"
style=
"margin-top: 16px;"
>
<el-form-item
label=
"操作类型"
prop=
"vin"
label-width=
"80px"
>
<el-select
v-model=
"formData.logOpt"
placeholder=
"请选择操作类型"
clearable
>
<el-option
v-for=
"(type, index) in logOpts"
:label=
"type"
:value=
"type"
:key=
"index"
/>
</el-select>
</el-form-item>
</el-col>
<el-col
:span=
"isTablet ? 24 : 6"
style=
"margin-top: 16px;"
>
<el-form-item
label=
"时间"
prop=
"createTime"
label-width=
"80px"
>
<el-date-picker
v-model=
"formData.createTime"
type=
"daterange"
range-separator=
"至"
start-placeholder=
"开始日期"
end-placeholder=
"结束日期"
clearable
/>
</el-form-item>
</el-col>
</
template
>
<
template
#slot-table
>
<el-table-column
label=
"用户名"
prop=
"account"
min-width=
"200"
/>
<el-table-column
label=
"手机号码"
prop=
"phone"
min-width=
"200"
/>
<el-table-column
label=
"日志类型"
prop=
"logCategory"
min-width=
"200"
/>
<el-table-column
label=
"操作类型"
prop=
"logOpt"
min-width=
"200"
/>
<el-table-column
label=
"操作内容"
prop=
"logContent"
min-width=
"200"
/>
<el-table-column
label=
"IP地址"
prop=
"ip"
min-width=
"200"
/>
<el-table-column
label=
"操作时间"
prop=
"createTime"
min-width=
"200"
/>
</
template
>
</SearchTable>
</template>
<
script
>
import
dayjs
from
'
dayjs
'
import
Organ
from
'
@/components/Organ
'
import
SearchTable
from
'
@/components/SearchTable
'
import
{
mapGetters
}
from
'
vuex
'
import
{
fetchLogCategory
,
fetchLogList
}
from
'
@/api/search
'
export
default
{
name
:
'
SystemLog
'
,
components
:
{
Organ
,
SearchTable
},
data
()
{
// 组织id
const
{
organId
}
=
this
.
$store
.
getters
return
{
isTablet
:
window
.
OS
.
isTablet
,
formData
:
{
orgId
:
organId
,
account
:
''
,
phone
:
''
,
logCategory
:
''
,
logOpt
:
''
,
createTime
:
[]
},
logCategorys
:
[],
dict
:
{}
}
},
computed
:
{
...
mapGetters
([
'
dict
'
]),
/**
* 操作类型
*/
logOpts
()
{
// 日志类型
const
{
logCategory
}
=
this
.
formData
// 如果选择了日志类型
if
(
logCategory
)
{
return
this
.
logCategorys
.
find
(
category
=>
category
.
logCategory
===
logCategory
).
logOptList
}
return
[]
}
},
async
mounted
()
{
// 查询日志类型
const
{
logDetailList
}
=
await
fetchLogCategory
()
||
{}
// 记录当前日志类型
this
.
logCategorys
=
logDetailList
},
methods
:
{
/**
* 点击重置方法
*/
handleReset
()
{
// 组织id
const
{
organId
}
=
this
.
$store
.
getters
// 设置组织id
this
.
formData
.
orgId
=
organId
// 开始触发提交方法
this
.
$refs
.
searchTableRef
.
handleSubmit
()
},
/**
* 触发提交方法
* @param formData 当前表单填写的内容
* @param callback 回调函数
*/
async
handleSubmit
(
formData
,
callback
)
{
// 如果当前选择了时间
if
(
formData
.
createTime
&&
formData
.
createTime
.
length
===
2
)
{
formData
.
createTimeStart
=
dayjs
(
formData
.
createTime
[
0
]).
startOf
(
'
day
'
).
valueOf
()
formData
.
createTimeEnd
=
dayjs
(
formData
.
createTime
[
1
]).
endOf
(
'
day
'
).
valueOf
()
delete
formData
.
createTime
}
// 开始请求接口
const
{
list
,
totalCount
}
=
await
fetchLogList
(
formData
)
// 开始渲染页面
callback
({
list
,
totalCount
})
}
}
}
</
script
>
<
style
lang=
"scss"
>
.page-search-system-log
{
.component-search-table-btn-wrap
{
margin-top
:
16px
;
}
}
</
style
>
src/views/special-business/car-unbinding/components/car-unbind-file.vue
0 → 100644
View file @
d2c4018b
<
template
>
<div
v-loading.fullscreen.lock=
"fullscreenLoading"
class=
"page"
>
<el-form
ref=
"form"
:model=
"form"
label-width=
"80px"
label-position=
"top"
size=
"small"
>
<page-module
name=
"车卡文件上传"
icon=
"folder"
>
<div
class=
"download-template-file"
>
<span
class=
"name"
>
文件上传
</span>
<el-link
type=
"primary"
icon=
"el-icon-download"
@
click=
"downloadTemplateFile"
>
下载模板
</el-link>
</div>
<div
class=
"file-upload-wrap"
>
<div
class=
"file-upload-l"
>
<el-upload
ref=
"upload"
:limit=
"1"
:data=
"upload.data"
:headers=
"upload.headers"
:file-list=
"form.fileList"
:action=
"upload.action"
:before-upload=
"onBefore"
:on-remove=
"onRemove"
:on-success =
"onSuccess"
:on-error =
"onError"
:on-exceed=
"onExceed"
class=
"file-uploader"
accept=
".xls,.xlsx"
name=
"file"
multiple
>
<el-button
slot=
"trigger"
size=
"small"
type=
"primary"
>
选择文件
</el-button>
<el-button
:disabled=
"checkBtnStatus"
style=
"margin-left: 8px;"
size=
"small"
type=
"primary"
@
click=
"checkVinData"
>
校验数据
</el-button>
<div
slot=
"tip"
class=
"el-upload__tip"
>
只能上传excel文件,文件大小不超过10MB,记录数不超过5000条
</div>
</el-upload>
</div>
<div
class=
"file-upload-r"
/>
</div>
</page-module>
<page-module
v-if=
"showCheckData"
name=
"校验结果"
icon=
"check"
>
<div
class=
"file-upload-check"
>
<div
v-if=
"form.checkData.failCount > 0"
class=
"check-l fail"
/>
<div
v-else
class=
"check-l success"
/>
<div
class=
"check-r"
>
<div
v-if=
"form.checkData.totalCount === form.checkData.failCount"
class=
"info"
>
全部数据验证失败,请更新后重试
</div>
<template
v-else-if=
"form.checkData.failCount > 0"
>
<div
class=
"info"
>
{{
form
.
checkData
.
failCount
}}
条车卡数据验证失败
</div>
<div
class=
"tips"
>
异常数据不进入后续的实名认证环节
</div>
<div
class=
"btns"
>
<el-button
type=
"primary"
plain
size=
"small"
icon=
"el-icon-download"
@
click=
"downloadCheckFailFile"
>
下载文件
</el-button>
</div>
</
template
>
<div
v-else
class=
"info"
>
全部数据验证成功
</div>
</div>
</div>
</page-module>
</el-form>
</div>
</template>
<
script
>
import
{
mapGetters
}
from
'
vuex
'
import
{
getToken
}
from
'
@/utils/auth
'
import
{
postUploadFile
,
vehicleUnboundVerifyVinCards
}
from
'
@/api/special-business
'
import
{
downloadFailFile
}
from
'
@/api/realname-car-enterprise
'
export
default
{
name
:
'
CarUnbindFile
'
,
components
:
{},
props
:
{
data
:
{
type
:
Object
,
default
()
{
return
{}
}
}
},
data
()
{
return
{
fullscreenLoading
:
false
,
upload
:
{
data
:
{
rootPath
:
''
,
path
:
''
},
headers
:
{
'
Authorization
'
:
`bearer
${
getToken
()}
`
},
action
:
postUploadFile
},
form
:
{
fileId
:
''
,
checkData
:
{},
fileList
:
[]
}
}
},
computed
:
{
...
mapGetters
([
'
dict
'
]),
checkBtnStatus
()
{
return
!
this
.
form
.
fileId
},
showCheckData
()
{
const
keys
=
Object
.
keys
(
this
.
form
.
checkData
)
return
keys
.
length
>
0
}
},
watch
:
{
data
()
{
this
.
updateInternalData
()
}
},
created
()
{
this
.
init
()
},
methods
:
{
init
()
{
this
.
updateInternalData
()
},
updateInternalData
()
{
if
(
typeof
this
.
data
===
'
object
'
&&
this
.
data
!==
null
)
{
this
.
form
=
{
fileId
:
this
.
data
.
fileId
||
''
,
checkData
:
this
.
data
.
checkData
||
{},
fileList
:
this
.
data
.
fileList
||
[]
}
}
else
{
this
.
form
=
{
fileId
:
''
,
checkData
:
{},
fileList
:
[]
}
}
},
/**
* 上传前校验
* @time 2021-12-06 10:02:49
*/
onBefore
(
file
)
{
const
type1
=
'
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
'
const
type2
=
'
application/vnd.ms-excel
'
let
isExcel
=
false
if
(
file
.
type
===
type1
||
file
.
type
===
type2
)
{
isExcel
=
true
}
const
isLt10M
=
file
.
size
/
1024
/
1024
<=
10
if
(
!
isExcel
)
{
this
.
$message
.
error
(
'
车卡信息文件只支持excel文件
'
)
return
false
}
if
(
!
isLt10M
)
{
this
.
$message
.
error
(
'
车卡信息文件大小不能超过10MB
'
)
return
false
}
},
/**
* 文件上传
* @time 2021-12-06 10:02:33
*/
onSuccess
(
json
)
{
if
(
json
.
success
)
{
this
.
$message
.
success
(
'
文件上传成功
'
)
const
data
=
json
.
data
||
{}
this
.
form
.
fileList
=
[{
name
:
data
.
fileName
,
url
:
data
.
accessUrl
,
uuid
:
data
.
uuid
}]
this
.
form
.
fileId
=
data
.
uuid
}
},
/**
* 上传错误
* @param {Object} err 错误对象
* @time 2021-12-15 14:14:49
*/
onError
()
{
this
.
$message
.
error
(
'
文件上传失败
'
)
this
.
$refs
.
upload
.
clearFiles
()
this
.
onRemove
()
},
/**
* 响应删除文件操作
* @time 2021-12-09 09:52:56
*/
onRemove
(
file
,
fileList
)
{
this
.
form
=
{
fileId
:
''
,
checkData
:
{},
fileList
:
[]
}
this
.
$emit
(
'
check
'
,
this
.
form
)
},
/**
* 上传数量限制
* @time 2021-12-06 10:03:10
*/
onExceed
()
{
this
.
$message
.
error
(
'
最多上传1个excel文件
'
)
},
/**
* 校验车卡信息
* @time 2022-04-23 14:27:21
*/
checkVinData
()
{
this
.
fullscreenLoading
=
true
return
vehicleUnboundVerifyVinCards
({
fileId
:
this
.
form
.
fileId
}).
then
(
data
=>
{
this
.
fullscreenLoading
=
false
this
.
form
.
checkData
=
data
this
.
$emit
(
'
check
'
,
this
.
form
)
}).
catch
(()
=>
{
this
.
fullscreenLoading
=
false
this
.
$emit
(
'
check
'
,
{})
})
},
getFormData
()
{
return
this
.
form
},
// 获取待缓存数据
getPendingCacheData
()
{
return
this
.
getFormData
()
},
/**
* 下载校验失败的文件
* @time 2022-04-23 15:02:50
*/
downloadCheckFailFile
()
{
// location.href = `${process.env.VUE_APP_ROUTER}static/template.xlsx`
this
.
fullscreenLoading
=
true
return
downloadFailFile
({
uuid
:
this
.
form
.
checkData
.
fileId
,
fileName
:
this
.
form
.
checkData
.
fileName
||
this
.
form
.
fileList
[
0
].
name
}).
then
(()
=>
{
this
.
fullscreenLoading
=
false
}).
catch
(()
=>
{
this
.
fullscreenLoading
=
false
})
},
/**
* 下载车卡模板文件
* @time 2022-04-23 15:02:50
*/
downloadTemplateFile
()
{
location
.
href
=
`
${
process
.
env
.
VUE_APP_ROUTER
}
static/template.xlsx`
}
}
}
</
script
>
<
style
scoped
lang=
"scss"
>
.download-template-file
{
margin
:
20px
0
0
0
;
font-size
:
14px
;
font-family
:
PingFangSC-Regular
,
PingFang
SC
;
font-weight
:
400
;
color
:
#71747B
;
.name
{
margin-right
:
16px
;
}
}
.file-upload-wrap
{
margin
:
10px
auto
0
;
display
:
flex
;
justify-content
:
space-between
;
.file-upload-l
{
flex
:
1
;
}
.file-upload-r
{
width
:
238px
;
height
:
144px
;
background
:
url(~@/assets/image/file_upload.png)
no-repeat
0
0
/
238px
144px
;
}
}
.file-upload-check
{
margin
:
20px
auto
0
;
display
:
flex
;
.check-l
{
width
:
483px
;
height
:
200px
;
flex
:
none
;
&
.success
{
background
:
url(~@/assets/image/result_img_success.png)
no-repeat
0
0
;
}
&
.fail
{
background
:
url(~@/assets/image/result_img_fail.png)
no-repeat
0
0
;
}
}
.check-r
{
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
flex-direction
:
column
;
flex
:
1
;
.info
{
font-size
:
16px
;
font-family
:
PingFangSC-Semibold
,
PingFang
SC
;
font-weight
:
600
;
color
:
#111
;
}
.tips
{
margin
:
8px
auto
16px
;
font-family
:
PingFangSC-Regular
,
PingFang
SC
;
font-weight
:
400
;
color
:
rgba
(
132
,
133
,
138
,
0
.7
);
}
}
}
</
style
>
src/views/special-business/car-unbinding/step-one.vue
0 → 100644
View file @
d2c4018b
<
template
>
<div
class=
"page"
>
<pageTitle
title=
"车企实名解绑"
/>
<steps
:data=
"stepsData"
:index=
"stepIndex"
:margin=
"margin"
/>
<car-unbind-file
ref=
"carSimFile"
:data=
"pageData"
@
check=
"onCheck"
/>
<div
class=
"next-step"
>
<el-button
:disabled=
"nextBtnStatus"
size=
"small"
type=
"primary"
@
click=
"onNextStep"
>
下一步
</el-button>
</div>
</div>
</
template
>
<
script
>
import
{
mapGetters
}
from
'
vuex
'
import
CarUnbindFile
from
'
./components/car-unbind-file
'
import
Common
from
'
@/components/Common
'
import
{
checkVinCard
}
from
'
@/api/iccid
'
export
default
{
name
:
'
CarUnbindingStepOne
'
,
components
:
{
CarUnbindFile
},
mixins
:
[
Common
],
data
()
{
return
{
stepsData
:
[
'
车卡信息
'
,
'
车企信息
'
],
stepIndex
:
0
,
margin
:
'
0 200px 0 200px
'
,
pageData
:
{}
}
},
computed
:
{
...
mapGetters
([
'
dict
'
]),
nextBtnStatus
()
{
const
{
failCount
,
totalCount
}
=
this
.
pageData
.
checkData
if
(
failCount
>
0
&&
failCount
===
totalCount
||
!
totalCount
)
{
return
true
}
return
false
}
},
created
()
{
this
.
init
()
},
methods
:
{
init
()
{
this
.
getCacheData
()
if
(
this
.
$route
.
params
.
from
===
'
prev
'
)
{
this
.
restoreCacheData
()
}
else
{
this
.
resetStepData
()
}
},
getCacheData
()
{
this
.
cacheData
=
this
.
cacheGetStepData
(
this
.
cacheKey
)
},
restoreCacheData
()
{
if
(
this
.
isValidObject
(
this
.
cacheData
))
{
this
.
pageData
=
this
.
cloneObject
(
this
.
cacheData
)
}
else
{
this
.
resetStepData
()
}
},
resetStepData
()
{
this
.
pageData
=
{
fileId
:
''
,
checkData
:
{},
fileList
:
[]
}
},
async
onNextStep
()
{
// 写入缓存
const
data
=
this
.
$refs
.
carSimFile
.
getPendingCacheData
()
const
{
fileId
}
=
this
.
pageData
await
checkVinCard
({
fileId
,
businessType
:
9
})
this
.
cacheSetStepData
(
this
.
cacheKey
,
data
)
// 前往下一步
this
.
$router
.
push
({
name
:
'
CarUnbindingStepTwo
'
})
},
onCheck
(
data
)
{
this
.
pageData
=
data
}
}
}
</
script
>
src/views/special-business/car-unbinding/step-two.vue
0 → 100644
View file @
d2c4018b
<
template
>
<div
v-loading.fullscreen.lock=
"fullscreenLoading"
element-loading-spinner=
"page-loading"
class=
"page car-unbinding-page"
>
<pageTitle
title=
"车企实名解绑"
/>
<steps
:data=
"stepsData"
:index=
"stepIndex"
:margin=
"margin"
/>
<el-form
ref=
"form"
:model=
"form"
label-width=
"80px"
label-position=
"top"
size=
"small"
>
<page-module
name=
"车企信息"
icon=
"car"
>
<el-row
:gutter=
"40"
>
<el-col
:span=
"12"
>
<el-form-item
label=
"企业名称"
prop=
"companyName"
>
<el-input
v-model=
"form.companyName"
placeholder=
"请输入企业名称"
clearable
disabled
/>
</el-form-item>
</el-col>
</el-row>
<el-row
:gutter=
"40"
>
<el-col
:span=
"12"
>
<el-form-item
label=
"企业证件类型"
prop=
"companyCertType"
>
<el-select
v-model=
"form.companyCertType"
placeholder=
"请选择企业证件类型"
disabled
>
<el-option
v-for=
"item of dict.companyCertType"
:key=
"item.key"
v-bind=
"item"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row
:gutter=
"40"
>
<el-col
:span=
"12"
>
<el-form-item
label=
"企业证件号码"
prop=
"companyCertNumber"
>
<el-input
v-model=
"form.companyCertNumber"
placeholder=
"请输入企业证件号码"
clearable
disabled
/>
</el-form-item>
</el-col>
</el-row>
<el-row
:gutter=
"40"
>
<el-col
:span=
"12"
>
<el-form-item
label=
"责任人姓名"
prop=
"corporationName"
>
<el-input
v-model=
"form.corporationName"
placeholder=
"请输入责任人姓名"
clearable
disabled
/>
</el-form-item>
</el-col>
</el-row>
<el-row
:gutter=
"40"
>
<el-col
:span=
"12"
>
<el-form-item
label=
"责任人手机号"
prop=
"corporationPhone"
>
<el-input
v-model=
"form.corporationPhone"
placeholder=
"请输入责任人手机号"
clearable
disabled
/>
</el-form-item>
</el-col>
</el-row>
</page-module>
<div
class=
"next-step"
>
<el-button
size=
"small"
plain
@
click=
"handlePrev"
>
上一步
</el-button>
<el-button
size=
"small"
type=
"primary"
@
click=
"handleSendMsg"
>
提交
</el-button>
</div>
</el-form>
<comp-confirm
:show.sync=
"tipVisible"
:show-cancel-btn=
"false"
:desc=
"unbindData.msg"
:type=
"unbindData.type"
@
on-sure=
"closeVisible"
/>
</div>
</
template
>
<
script
>
import
{
mapGetters
}
from
'
vuex
'
import
CompConfirm
from
'
@/components/CompConfirm
'
import
{
manufacturerRnrGetDetail
,
vehicleUnbound
}
from
'
@/api/special-business
'
import
Common
from
'
@/components/Common
'
export
default
{
name
:
'
CarUnbindingStepTwo
'
,
components
:
{
CompConfirm
},
mixins
:
[
Common
],
data
()
{
return
{
fullscreenLoading
:
false
,
stepsData
:
[
'
车卡信息
'
,
'
车企信息
'
],
stepIndex
:
1
,
margin
:
'
0 230px 0 230px
'
,
form
:
{
companyName
:
''
,
companyCertType
:
''
,
companyCertNumber
:
''
,
corporationName
:
''
,
corporationPhone
:
''
},
unbindStatus
:
false
,
// 解绑状态, 默认失败
unbindData
:
{
msg
:
''
,
type
:
''
},
tipVisible
:
false
,
cacheData
:
null
,
fileId
:
''
}
},
computed
:
{
...
mapGetters
([
'
dict
'
])
},
mounted
()
{
this
.
initFuc
()
},
methods
:
{
/**
* 获取车企详情
* @time 2022-04-24 12:16:26
*/
initFuc
()
{
// 获取车企详情
this
.
fullscreenLoading
=
true
manufacturerRnrGetDetail
({})
.
then
(
res
=>
{
this
.
fullscreenLoading
=
false
this
.
form
=
res
})
.
catch
(()
=>
{
this
.
fullscreenLoading
=
false
})
// 获取上一步的缓存, 没有将无法提交
this
.
cacheData
=
this
.
cacheGetStepData
(
'
CarUnbindingStepOne
'
)
if
(
this
.
cacheData
)
{
this
.
fileId
=
this
.
cacheData
.
fileId
}
else
{
// 不应该进入页面, 从头开始
this
.
$router
.
replace
({
name
:
'
CarUnbindingStepOne
'
})
}
},
/**
* 返回上一步
* @time 2022-04-23 15:59:56
*/
handlePrev
()
{
this
.
$router
.
push
({
name
:
'
CarUnbindingStepOne
'
,
params
:
{
from
:
'
prev
'
}
})
},
/**
* 确认弹出
* @time 2022-04-23 14:20:57
*/
handleSendMsg
()
{
// 提交车企解绑信息
this
.
fullscreenLoading
=
true
vehicleUnbound
({
// vehicleCompanyId: '', // 不需要
fileId
:
this
.
fileId
}).
then
(
data
=>
{
this
.
fullscreenLoading
=
false
this
.
unbindStatus
=
true
this
.
unbindData
.
msg
=
'
卡解绑成功
'
this
.
unbindData
.
type
=
'
success
'
this
.
tipVisible
=
true
}).
catch
((
err
)
=>
{
this
.
fullscreenLoading
=
false
this
.
unbindStatus
=
false
this
.
unbindData
.
msg
=
err
.
message
||
'
卡解绑失败
'
this
.
unbindData
.
type
=
'
info
'
this
.
tipVisible
=
true
})
},
/**
* 关闭解绑成功弹出
* @time 2022-04-23 15:59:13
*/
closeVisible
()
{
if
(
this
.
unbindStatus
)
{
// 成功
this
.
$router
.
replace
({
name
:
'
Home
'
})
}
else
{
// 失败
this
.
tipVisible
=
false
}
}
}
}
</
script
>
<
style
lang=
"scss"
>
.car-unbinding-page
{
.is-disabled
{
.el-input__inner
{
color
:
#333
;
}
}
}
</
style
>
src/views/special-business/card-binding/step-one.vue
0 → 100644
View file @
d2c4018b
<
template
>
<div
v-loading.fullscreen.lock=
"fullscreenLoading"
element-loading-spinner=
"page-loading"
class=
"page"
>
<pageTitle
title=
"一车多卡绑定"
/>
<steps
:data=
"stepsData"
:index=
"stepIndex"
:margin=
"margin"
/>
<page-module
name=
"车卡信息"
icon=
"car"
>
<comp-car-card
ref=
"compCarCard"
:data=
"cacheData"
souce-page=
"BIND"
/>
</page-module>
<div
class=
"next-step"
>
<el-button
size=
"small"
type=
"primary"
@
click=
"handleNext"
>
下一步
</el-button>
</div>
</div>
</
template
>
<
script
>
import
Common
from
'
@/components/Common
'
import
CompCarCard
from
'
@/components/CompCarCard
'
import
{
checkVinCard
}
from
'
@/api/iccid
'
export
default
{
name
:
'
CardBindingStepOne
'
,
components
:
{
CompCarCard
},
mixins
:
[
Common
],
data
()
{
return
{
fullscreenLoading
:
false
,
stepsData
:
[
'
车卡信息录入
'
,
'
客户确认
'
],
stepIndex
:
0
,
margin
:
'
0 200px 0 200px
'
,
cacheData
:
null
}
},
created
()
{
this
.
init
()
},
methods
:
{
/**
* 初始化
* @time 2022-04-24 16:50:27
*/
init
()
{
if
(
this
.
$route
.
params
.
from
)
{
// 表明是返回上一步 读缓存
this
.
cacheData
=
this
.
cacheGetStepData
(
this
.
cacheKey
)
}
},
/**
* 下一步操作
* @time 2022-04-24 16:50:14
*/
async
handleNext
()
{
try
{
await
this
.
$refs
.
compCarCard
.
validate
()
const
data
=
this
.
$refs
.
compCarCard
.
getPendingCacheData
()
// 校验车卡关系
const
verifyData
=
{
iccidList
:
[],
vin
:
data
.
vin
,
rnrId
:
data
.
data
,
businessType
:
5
}
data
.
iccidList
.
forEach
(
item
=>
{
if
(
item
.
iccid
!==
''
)
{
verifyData
.
iccidList
.
push
(
item
.
iccid
)
}
})
this
.
fullscreenLoading
=
true
const
retData
=
await
checkVinCard
(
verifyData
)
let
isAlert
=
false
if
(
retData
.
iccidVerifyResults
&&
retData
.
iccidVerifyResults
.
length
>
0
)
{
const
resList
=
retData
.
iccidVerifyResults
for
(
let
i
=
0
;
i
<
resList
.
length
;
i
++
)
{
if
(
!
resList
[
i
].
exist
)
{
// 车卡关系不正常
isAlert
=
true
break
}
}
}
this
.
fullscreenLoading
=
false
if
(
isAlert
)
{
this
.
$message
.
error
(
'
数据校验不通过
'
)
return
false
}
// 写入缓存
this
.
cacheSetStepData
(
this
.
cacheKey
,
{
vin
:
data
.
vin
,
iccidList
:
data
.
iccidList
})
// 前往下一步
this
.
$router
.
push
({
name
:
'
CardBindingStepTwo
'
})
}
catch
(
e
)
{
this
.
fullscreenLoading
=
false
if
(
e
.
anchor
)
{
e
.
anchor
()
}
}
}
}
}
</
script
>
src/views/special-business/card-binding/step-two.vue
0 → 100644
View file @
d2c4018b
<
template
>
<div
v-loading.fullscreen.lock=
"fullscreenLoading"
element-loading-spinner=
"page-loading"
class=
"page"
>
<pageTitle
title=
"一车多卡绑定"
/>
<steps
:data=
"stepsData"
:index=
"stepIndex"
:margin=
"margin"
/>
<comp-client-confirm
ref=
"compClientConfirm"
:form-data=
"formData"
:wait-visible.sync=
"waitVisible"
:opreator-uuid=
"opreatorUuid"
type=
"BIND"
prompt-info=
"操作等待中..."
/>
<div
class=
"next-step"
>
<el-button
size=
"small"
plain
@
click=
"handlePrev"
>
上一步
</el-button>
<el-button
size=
"small"
type=
"primary"
@
click=
"handleSendMsg"
>
发送确认短信
</el-button>
</div>
<comp-confirm
:show.sync=
"tipVisible"
:desc=
"desc"
:show-cancel-btn=
"false"
@
on-sure=
"closeVisible"
/>
</div>
</
template
>
<
script
>
import
Common
from
'
@/components/Common
'
import
CompClientConfirm
from
'
@/components/CompClientConfirm
'
import
CompConfirm
from
'
@/components/CompConfirm
'
import
{
surplusCardBind
}
from
'
@/api/special-business
'
export
default
{
name
:
'
CardBindingStepTwo
'
,
components
:
{
CompClientConfirm
,
CompConfirm
},
mixins
:
[
Common
],
data
()
{
return
{
stepsData
:
[
'
车卡信息录入
'
,
'
客户确认
'
],
stepIndex
:
1
,
margin
:
'
0 230px 0 230px
'
,
waitVisible
:
false
,
formData
:
{},
// 上一步的数据, 需要读取缓存
fullscreenLoading
:
false
,
unbindInfo
:
{},
opreatorUuid
:
''
,
tipVisible
:
false
,
desc
:
''
}
},
created
()
{
this
.
formData
=
this
.
cacheGetStepData
(
'
CardBindingStepOne
'
)
},
methods
:
{
/**
* 返回上一步
* @time 2022-04-23 15:59:56
*/
handlePrev
()
{
this
.
$router
.
push
({
name
:
'
CardBindingStepOne
'
,
params
:
{
from
:
'
prev
'
}
})
},
/**
* 确认弹出
* @time 2022-04-23 14:20:57
*/
handleSendMsg
()
{
// bfd331a547764865b2a0b4309f8c95c3
const
curRnrId
=
this
.
$refs
.
compClientConfirm
.
rnrId
if
(
!
curRnrId
)
{
this
.
$message
.
error
(
'
获取当前车卡的实名信息失败
'
)
return
false
}
this
.
fullscreenLoading
=
true
// 提交绑定剩余卡
const
arr
=
[]
this
.
formData
.
iccidList
.
map
(
item
=>
{
if
(
item
.
iccid
!==
''
)
{
arr
.
push
(
item
.
iccid
)
}
})
surplusCardBind
({
vin
:
this
.
formData
.
vin
,
iccidList
:
arr
,
rnrId
:
curRnrId
}).
then
(
data
=>
{
this
.
opreatorUuid
=
data
.
orderId
this
.
fullscreenLoading
=
false
this
.
waitVisible
=
true
}).
catch
((
err
)
=>
{
this
.
fullscreenLoading
=
false
this
.
tipVisible
=
true
this
.
desc
=
err
.
message
})
},
/**
* 关闭警告
* @time 2022-04-23 15:59:13
*/
closeVisible
()
{
this
.
tipVisible
=
false
}
}
}
</
script
>
src/views/special-business/card-unbinding/components/owner-type.vue
0 → 100644
View file @
d2c4018b
<
template
>
<div>
<page-module
name=
"业务类型"
icon=
"star"
>
<el-radio-group
v-model=
"ownerType"
@
change=
"handleOwnerType"
>
<el-row
:gutter=
"40"
class=
"new-car-owner-box"
>
<el-col
:span=
"12"
>
<el-radio
:label=
"0"
border
class=
"new-car-owner"
>
<el-row>
<el-col
class=
"owner-type-title"
>
原车解绑
</el-col>
<el-col
class=
"owner-type-info"
>
由原车主现场解绑
</el-col>
</el-row>
</el-radio>
</el-col>
<el-col
:span=
"12"
>
<el-radio
:label=
"1"
border
class=
"used-car-new-owner"
>
<el-row>
<el-col
class=
"owner-type-title"
>
二手车解绑
</el-col>
<el-col
class=
"owner-type-info"
>
由新车主代解绑
</el-col>
</el-row>
</el-radio>
</el-col>
</el-row>
</el-radio-group>
</page-module>
<steps
:data=
"stepsData"
:index=
"stepIndex"
:margin=
"margin"
/>
</div>
</
template
>
<
script
>
export
default
{
name
:
'
OwnerType
'
,
props
:
{
curType
:
{
type
:
[
Number
,
String
],
default
:
()
=>
0
},
stepIndex
:
{
type
:
[
Number
,
String
],
default
:
()
=>
0
}
},
data
()
{
return
{
ownerType
:
0
,
stepsData
:
[
'
车卡信息录入
'
,
'
客户确认
'
],
margin
:
'
0 200px 0 200px
'
}
},
watch
:
{
curType
:
{
handler
(
val
,
oldVal
)
{
if
(
val
!==
oldVal
)
{
this
.
ownerType
=
val
if
(
val
===
0
)
{
this
.
stepsData
=
[
'
车卡信息录入
'
,
'
客户确认
'
]
this
.
margin
=
'
0 200px 0 200px
'
}
else
{
this
.
stepsData
=
[
'
车卡信息录入
'
,
'
客户信息录入
'
,
'
人脸识别
'
]
this
.
margin
=
'
0 0 0 0
'
}
}
},
immediate
:
true
}
},
methods
:
{
handleOwnerType
(
val
)
{
if
(
this
.
$route
.
name
===
'
CardUnbindingStepOne
'
)
{
this
.
$emit
(
'
change-type
'
,
val
)
return
false
}
const
owner
=
val
this
.
$router
.
push
({
name
:
'
CardUnbindingStepOne
'
,
params
:
{
owner
}
})
}
}
}
</
script
>
<
style
scoped
lang=
"scss"
>
.special-business-card-binding
{
.new-car-owner-box
.el-radio
{
display
:
flex
;
width
:
346px
;
height
:
106px
;
align-items
:
center
;
padding-left
:
24px
;
}
.new-car-owner
{
background
:
url('~@/assets/special-business/new_car_owner@2x.png')
no-repeat
;
background-size
:
45%
;
background-position
:
right
}
.used-car-new-owner
{
background
:
url('~@/assets/special-business/used_car_new_owner@2x.png')
no-repeat
;
background-size
:
45%
;
background-position
:
right
}
.owner-type-title
{
font-size
:
16px
;
color
:
#212026
;
padding-bottom
:
5px
;
}
.owner-type-info
{
font-size
:
12px
;
color
:
#84858a
;
}
}
</
style
>
src/views/special-business/card-unbinding/step-one.vue
0 → 100644
View file @
d2c4018b
<
template
>
<div
v-loading.fullscreen.lock=
"fullscreenLoading"
element-loading-spinner=
"page-loading"
class=
"page special-business-card-binding"
>
<pageTitle
title=
"卡解绑"
/>
<owner-type
ref=
"ownerTypeRef"
:step-index=
"0"
:cur-type=
"onwnerType"
@
change-type=
"handleOwnerType"
/>
<page-module
name=
"车卡信息"
icon=
"car"
>
<comp-car-card
v-if=
"isExit"
ref=
"compCarCard"
:data=
"cacheData"
:is-bind=
"true"
:souce-page=
"soucePage"
/>
</page-module>
<div
class=
"next-step"
>
<el-button
size=
"small"
type=
"primary"
@
click=
"handleNext"
>
下一步
</el-button>
</div>
</div>
</
template
>
<
script
>
import
Common
from
'
@/components/Common
'
import
OwnerType
from
'
./components/owner-type
'
import
CompCarCard
from
'
@/components/CompCarCard
'
import
{
checkVinCard
}
from
'
@/api/iccid
'
export
default
{
name
:
'
CardUnbindingStepOne
'
,
components
:
{
OwnerType
,
CompCarCard
},
mixins
:
[
Common
],
data
()
{
return
{
fullscreenLoading
:
false
,
onwnerType
:
0
,
cacheData
:
null
,
isExit
:
true
,
soucePage
:
'
SPECIAL
'
}
},
mounted
()
{
this
.
init
()
},
methods
:
{
/**
* 初始化
* @time 2022-04-24 16:50:27
*/
init
()
{
if
(
this
.
$route
.
params
.
owner
)
{
this
.
onwnerType
=
this
.
$route
.
params
.
owner
this
.
soucePage
=
this
.
onwnerType
!==
1
?
'
SPECIAL
'
:
'
UNBIND
'
}
if
(
this
.
$route
.
params
.
from
)
{
// 表明是返回上一步 读缓存
this
.
cacheData
=
this
.
cacheGetStepData
(
this
.
cacheKey
)
if
(
this
.
cacheData
)
{
this
.
onwnerType
=
this
.
cacheData
.
onwnerType
this
.
soucePage
=
this
.
onwnerType
!==
1
?
'
SPECIAL
'
:
'
UNBIND
'
}
}
},
/**
* 重置组件
* @time 2022-05-05 10:19:20
*/
handleOwnerType
(
val
)
{
this
.
onwnerType
=
val
this
.
soucePage
=
this
.
onwnerType
!==
1
?
'
SPECIAL
'
:
'
UNBIND
'
this
.
cacheData
=
null
this
.
isExit
=
false
this
.
$nextTick
(()
=>
{
this
.
isExit
=
true
})
},
/**
* 前往下一步
* @time 2022-05-05 10:20:40
*/
async
handleNext
()
{
try
{
await
this
.
$refs
.
compCarCard
.
validate
()
const
data
=
this
.
$refs
.
compCarCard
.
getPendingCacheData
()
// 校验车卡关系
const
verifyData
=
{
iccidList
:
[],
vin
:
data
.
vin
,
rnrId
:
data
.
rnrId
,
businessType
:
+
this
.
$refs
.
ownerTypeRef
.
ownerType
===
1
?
7
:
6
}
data
.
iccidList
.
forEach
(
item
=>
{
if
(
item
.
iccid
!==
''
)
{
verifyData
.
iccidList
.
push
(
item
.
iccid
)
}
})
this
.
fullscreenLoading
=
true
await
checkVinCard
(
verifyData
)
this
.
fullscreenLoading
=
false
// 写入缓存
this
.
cacheSetStepData
(
this
.
cacheKey
,
{
onwnerType
:
this
.
$refs
.
ownerTypeRef
.
ownerType
,
vin
:
data
.
vin
,
iccidList
:
data
.
iccidList
})
// 前往下一步
const
ownerType
=
this
.
$refs
.
ownerTypeRef
.
ownerType
if
(
ownerType
===
0
)
{
this
.
$router
.
push
({
name
:
'
CardUnbindingStepTwo
'
})
}
else
{
this
.
$router
.
push
({
name
:
'
CardUnbindingStepTwoSnd
'
})
}
}
catch
(
e
)
{
this
.
fullscreenLoading
=
false
if
(
e
.
anchor
)
{
e
.
anchor
()
}
}
}
}
}
</
script
>
src/views/special-business/card-unbinding/step-three.vue
0 → 100644
View file @
d2c4018b
<
template
>
<div
v-loading.fullscreen.lock=
"fullscreenLoading"
element-loading-spinner=
"page-loading"
class=
"page special-business-card-binding"
>
<pageTitle
title=
"卡解绑"
/>
<owner-type
ref=
"ownerTypeRef"
:step-index=
"2"
:cur-type=
"onwnerType"
/>
<PageModuleTabs
:tabs=
"TABS"
v-if=
"device.showTakePhoto"
v-model=
"tabName"
>
<CompFaceRecognition
ref=
"faceRecognition"
:type=
"livenessType"
:take=
"tabName == 'carmer'"
:data=
"faceData"
/>
</PageModuleTabs>
<page-module
v-else
name=
"活体视频上传"
icon=
"video"
>
<CompFaceRecognition
ref=
"faceRecognition"
:type=
"livenessType"
:data=
"faceData"
/>
</page-module>
<div
class=
"next-step"
>
<el-button
size=
"small"
plain
@
click=
"handlePrev"
>
上一步
</el-button>
<el-button
size=
"small"
type=
"primary"
@
click=
"handleNext"
>
提交
</el-button>
</div>
<comp-confirm
:show.sync=
"tipVisible"
:show-cancel-btn=
"false"
:desc=
"unbindData.msg"
:type=
"unbindData.type"
@
on-sure=
"closeVisible"
/>
</div>
</
template
>
<
script
>
import
{
mapGetters
}
from
'
vuex
'
import
PageModuleTabs
from
'
@/components/PageModule/tabs
'
import
Common
from
'
@/components/Common
'
import
CompConfirm
from
'
@/components/CompConfirm
'
import
OwnerType
from
'
./components/owner-type
'
import
CompFaceRecognition
from
'
@/components/CompFaceRecognition
'
import
{
cardUnbindSecondHandPersonal
,
getLivenessCode
}
from
'
@/api/special-business
'
const
TABS
=
[
{
label
:
'
活体视频上传
'
,
value
:
'
video
'
,
icon
:
require
(
'
@/assets/image/video@2x.png
'
)
},
{
label
:
'
在线拍摄视频
'
,
value
:
'
carmer
'
,
icon
:
require
(
'
@/assets/image/icon_user@2x.png
'
)
}
]
export
default
{
name
:
'
CardUnbindingStepThree
'
,
components
:
{
CompConfirm
,
OwnerType
,
CompFaceRecognition
,
PageModuleTabs
},
mixins
:
[
Common
],
data
()
{
return
{
TABS
,
fullscreenLoading
:
false
,
onwnerType
:
1
,
unbindStatus
:
false
,
// 解绑状态, 默认失败
livenessType
:
''
,
unbindData
:
{
msg
:
''
,
type
:
''
},
tipVisible
:
false
,
faceData
:
null
,
tabName
:
'
video
'
}
},
computed
:
{
...
mapGetters
([
'
device
'
])
},
mounted
()
{
this
.
initFuc
()
},
methods
:
{
/**
* 初始化
* @time 2022-05-04 12:35:20
*/
initFuc
()
{
this
.
fullscreenLoading
=
true
getLivenessCode
()
.
then
((
res
)
=>
{
this
.
faceData
=
res
this
.
faceData
.
number
=
res
.
livenessCode
this
.
fullscreenLoading
=
false
this
.
livenessType
=
res
.
livenessType
})
.
catch
((
err
)
=>
{
console
.
log
(
err
)
this
.
$message
.
error
(
'
获取活体数字验证码失败,请刷新页面重试
'
)
this
.
fullscreenLoading
=
false
})
},
/**
* 返回上一步
* @time 2022-04-23 15:59:56
*/
handlePrev
()
{
const
ownerType
=
this
.
$refs
.
ownerTypeRef
.
ownerType
if
(
ownerType
===
0
)
{
this
.
$router
.
push
({
name
:
'
CardUnbindingStepTwo
'
,
params
:
{
from
:
'
prev
'
}
})
}
else
{
this
.
$router
.
push
({
name
:
'
CardUnbindingStepTwoSnd
'
,
params
:
{
from
:
'
prev
'
}
})
}
},
/**
* 提交审核
* @time 2022-04-24 16:00:12
*/
handleNext
()
{
// 二手车解绑
const
fileObj
=
this
.
$refs
.
faceRecognition
.
$refs
.
file
.
$refs
.
formRef
const
cacheData1
=
this
.
cacheGetStepData
(
'
CardUnbindingStepOne
'
)
const
cacheData2
=
this
.
cacheGetStepData
(
'
CardUnbindingStepTwoSnd
'
)
fileObj
.
validate
((
valid
)
=>
{
if
(
valid
)
{
const
iccidArr
=
[]
if
(
cacheData1
&&
cacheData1
.
iccidList
)
{
cacheData1
.
iccidList
.
forEach
(
ele
=>
{
if
(
ele
.
iccid
!==
''
)
{
iccidArr
.
push
(
ele
.
iccid
)
}
})
}
const
{
formData
,
concatData
,
fileList1
,
fileList2
,
certData
}
=
cacheData2
const
certPicArr
=
[]
if
(
certData
&&
certData
.
photoUrls
)
{
certData
.
photoUrls
.
forEach
(
ele
=>
{
certPicArr
.
push
(
ele
.
url
.
id
)
})
}
const
contractPic
=
[]
if
(
fileList1
)
{
fileList1
.
fileList
.
forEach
(
ele
=>
{
contractPic
.
push
(
ele
.
uuid
)
})
}
const
certificatePic
=
[]
if
(
fileList2
)
{
fileList2
.
fileList
.
forEach
(
ele
=>
{
certificatePic
.
push
(
ele
.
uuid
)
})
}
const
videoList
=
this
.
$refs
.
faceRecognition
.
$refs
.
file
.
form
.
fileList
const
videoArr
=
[]
videoList
.
forEach
(
ele
=>
{
videoArr
.
push
(
ele
.
uuid
)
})
// 组装整体数据
const
reqData
=
{
customerType
:
1
,
isConsigner
:
false
,
vin
:
cacheData1
.
vin
,
iccidList
:
iccidArr
,
// 新车主基本
fullName
:
formData
.
fullName
,
gender
:
formData
.
gender
,
// 新车主证件
certType
:
certData
.
type
,
certPic
:
certPicArr
,
certNumber
:
certData
.
no
,
certAddress
:
certData
.
address
,
certExpirationDate
:
certData
.
validDate
,
certEffectiveDate
:
certData
.
certEffectiveDate
,
contactAddress
:
certData
.
connectAddress
,
// 新车主文件
purchaseContractPic
:
contractPic
,
transferCertificatePic
:
certificatePic
,
// 新车主联系
phone
:
concatData
.
phone
,
verificationCode
:
concatData
.
veCode
,
// 人脸识别地址
requestId
:
this
.
faceData
.
requestId
,
liveVerificationVideo
:
videoArr
[
0
]
}
this
.
fullscreenLoading
=
true
cardUnbindSecondHandPersonal
(
reqData
)
.
then
((
res
)
=>
{
this
.
fullscreenLoading
=
false
this
.
unbindStatus
=
true
this
.
unbindData
.
msg
=
'
已转入人工审核, 请注意查询认证进度
'
this
.
unbindData
.
type
=
'
success
'
this
.
tipVisible
=
true
})
.
catch
((
err
)
=>
{
this
.
fullscreenLoading
=
false
this
.
unbindStatus
=
false
this
.
unbindData
.
msg
=
err
.
message
||
'
校验失败, 请重试
'
this
.
unbindData
.
type
=
'
info
'
this
.
tipVisible
=
true
})
}
})
},
/**
* 关闭解绑成功弹出
* @time 2022-04-23 15:59:13
*/
closeVisible
()
{
if
(
this
.
unbindStatus
)
{
// 成功
this
.
$router
.
replace
({
name
:
'
Home
'
})
}
else
{
// 失败
this
.
tipVisible
=
false
}
}
}
}
</
script
>
Prev
1
…
14
15
16
17
18
19
20
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment