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

初始化代码

parent de8a8ae5
Pipeline #3105 failed with stages
in 0 seconds
<template>
<div class="user-operation">
<el-dialog
:visible.sync="dialogVisible"
:title="dialogTitle"
center
>
<el-form ref="formRef" :model="formData" :disabled="disabledForm" label-position="left" label-width="80px">
<el-form-item label="姓名">
<el-input v-model="formData.username" />
</el-form-item>
<el-form-item label="昵称">
<el-input v-model="formData.nickname" />
</el-form-item>
<el-form-item label="手机号">
<el-input v-model="formData.phone" />
</el-form-item>
<el-form-item label="账号">
<el-input v-model="formData.accountNumber" />
</el-form-item>
<el-form-item v-if="operationMode === 'add'" label="密码">
<el-input v-model="formData.password" />
</el-form-item>
<el-form-item v-if="operationMode === 'add'" label="确认密码">
<el-input v-model="formData.confirmPassword" />
</el-form-item>
<el-form-item label="所属组织">
<el-select v-model="formData.companyNo" disabled>
<el-option label="组织1" value="1" />
</el-select>
</el-form-item>
<el-form-item label="角色">
<el-select v-model="formData.role" placeholder="请选择">
<el-option
v-for="item in roleList"
:key="item.value"
:label="item.label"
:value="item.value"/>
</el-select>
</el-form-item>
</el-form>
<el-row>
<el-col>
<el-button type="text" @click="handleUserRights">用户权限</el-button>
</el-col>
<el-col>
<el-tree v-if="userPermissionConfig" :data="data" :props="defaultProps" @node-click="handleNodeClick"/>
</el-col>
</el-row>
<span slot="footer" class="dialog-footer">
<el-button @click="cancel">取 消</el-button>
<el-button v-if="operationMode !== 'details'" type="primary" @click="handleSave">保 存</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
export default {
props: {
visible: {
type: Boolean,
default: false
},
formData: {
type: Object,
default: () => {}
},
dialogTitle: {
type: String,
default: '新增用户'
},
operationMode: {
type: String,
default: 'add'
}
},
data() {
return {
roleList: [
{
value: '业务操作员'
}
],
disabledForm: false,
data: [{
label: '一级 1',
children: [{
label: '二级 1-1',
children: [{
label: '三级 1-1-1'
}]
}]
}, {
label: '一级 2',
children: [{
label: '二级 2-1',
children: [{
label: '三级 2-1-1'
}]
}]
}],
defaultProps: {
children: 'children',
label: 'label'
},
userPermissionConfig: false
}
},
computed: {
dialogVisible: {
get() {
return this.visible
},
set(val) {
console.log(val)
this.$emit('updateVisible', val) // dialogVisible改变的时候通知父组件
}
}
},
watch: {
operationMode(res) {
if (res === 'details') {
this.disabledForm = true
} else {
this.disabledForm = false
}
}
},
methods: {
cancel() {
this.$emit('updateVisible', false)
},
handleSave() {
console.log(this.formData)
},
handleUserRights() {
this.userPermissionConfig = true
},
handleNodeClick(data) {
console.log(data)
this.userPermissionConfig = false
}
}
}
</script>
<style scoped lang="scss">
.user-operation{
}
</style>
<template>
<el-form ref="form" :rules="rules" :model="form" label-width="80px" label-position="top" size="small">
<el-row :gutter="40">
<el-col :span="12">
<el-form-item label="企业名称" prop="companyName">
<el-select v-model="form.companyName" :remote-method="getData" :loading="loading" clearable filterable remote placeholder="请输入企业名称" @change="onChange">
<el-option v-for="(item, index) in companyOptions" :key="index" :label="item" :value="item"/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="原责任人姓名" prop="corporationName">
<el-select v-model="form.corporationName" placeholder="请选择原责任人">
<el-option v-for="(item, index) in corporationOptions" :key="index" :label="item" :value="item"/>
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-form>
</template>
<script>
import { queryEnterprise } from '@/api/person-change'
export default {
name: 'EnterpriseInfo',
props: {
data: {
type: Object,
default: () => ({})
}
},
data() {
return {
form: {
companyName: '',
corporationName: ''
},
loading: false,
options: [],
rules: {
companyName: [
{ required: true, message: '请输入企业名称', trigger: 'blur' }
],
corporationName: [
{ required: true, message: '请选择原责任人姓名', trigger: 'blur' }
]
}
}
},
computed: {
/**
* 公司下拉选项
*/
companyOptions() {
const options = []
// 遍历所有的接口返回的数据
this.options.forEach(option => {
if (!options.some(companyName => companyName === option.companyName)) {
options.push(option.companyName)
}
})
return options
},
/**
* 责任人下拉列表
*/
corporationOptions() {
const options = []
const { companyName } = this.form
this.options.forEach(option => {
if (option.companyName === companyName) {
options.push(option.corporationName)
}
})
return options
}
},
watch: {
data() {
this.updateInternalData()
}
},
created() {
this.init()
},
methods: {
init() {
this.updateInternalData()
},
updateInternalData() {
if (typeof this.data === 'object' && this.data !== null) {
const { companyName, corporationName } = this.data
this.form = {
companyName,
corporationName
}
} else {
this.form = {
companyName: '',
corporationName: ''
}
}
},
getPendingCacheData() {
return this.getFormData()
},
/**
* 获取数据
* @time 2022-04-23 20:38:03
*/
getData(companyName) {
// 如果当前输入的不正确,则直接清空数据
if (!companyName) {
this.options = []
return
}
this.loading = true
return queryEnterprise({ companyName }).then(data => {
this.loading = false
this.options = data.list || []
}).catch(() => {
this.loading = false
this.options = []
})
},
/**
* change事件
* @time 2022-04-23 20:37:35
*/
onChange() {
this.$nextTick(() => {
this.form.corporationName = this.corporationOptions[0]
})
},
/**
* 获取当前模块数据
* @time 2022-04-23 15:50:05
*/
async validate(isErrorAnchor = false) {
try {
await this.$refs.form.validate()
return true
} catch (e) {
if (isErrorAnchor) {
this.$refs.form.fields.filter(item => item.validateState === 'error')[0].$el.scrollIntoView(true)
}
let temp = {
anchor: () => {
this.$refs.form.fields.filter(item => item.validateState === 'error')[0].$el.scrollIntoView(true)
temp = null
}
}
throw temp
}
},
/**
* 获取表单数据
* @time 2022-04-23 18:02:02
*/
getFormData() {
return this.form
}
}
}
</script>
<template>
<div class="page">
<pageTitle title="企业责任人变更" />
<steps :data="dict.personChangeSteps" :index="0" margin="0 160px" />
<page-module name="企业基本信息" icon="info">
<EnterpriseInfo ref="enterpriseInfo" :data="enterpriseData" />
</page-module>
<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">
<FileInfo ref="fileInfo" :data="fileData" label="企业实名认证授权书"/>
</page-module>
<page-module name="新责任人联系信息" icon="tel">
<CompConcatInfo ref="concatInfo" :data="concatData" biz-type="enterprise_change" />
</page-module>
<div class="next-step">
<el-button size="small" type="primary" @click="onNextStep">下一步</el-button>
</div>
</div>
</template>
<script>
import { checkSmsCaptcha } from '@/api/realname-person'
import { mapGetters } from 'vuex'
import EnterpriseInfo from './components/enterprise-info'
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: 'PersonChangeStep1',
components: {
EnterpriseInfo,
CompBasicInfo,
CompCertificateInfo,
FileInfo,
CompConcatInfo
},
mixins: [Common],
data() {
return {
pageData: {
enterpriseData: {},
baseData: {},
certData: {},
fileData: {},
concatData: {}
}
}
},
computed: {
...mapGetters(['dict']),
enterpriseData() {
return this.pageData.enterpriseData || {}
},
baseData() {
return this.pageData.baseData || {}
},
certData() {
return this.pageData.certData || {}
},
fileData() {
return this.pageData.fileData || {}
},
concatData() {
return this.pageData.concatData || {}
}
},
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 = {
enterpriseData: {},
baseData: {},
certData: {},
fileData: {},
concatData: {}
}
},
onReadCert(data) {
this.$set(this.pageData.baseData, 'name', data.name)
this.$set(this.pageData.baseData, 'sex', data.gender)
},
async onNextStep() {
try {
await Promise.all([
this.$refs.enterpriseInfo.validate(),
this.$refs.baseInfo.validate(),
this.$refs.certInfo.validate(),
this.$refs.fileInfo.validate(),
this.$refs.concatInfo.validate()
])
const enterpriseData = this.$refs.enterpriseInfo.getPendingCacheData()
const baseData = this.$refs.baseInfo.getPendingCacheData()
const certData = this.$refs.certInfo.getPendingCacheData()
const fileData = this.$refs.fileInfo.getPendingCacheData()
const concatData = this.$refs.concatInfo.getPendingCacheData()
// 校验手机号输入是否正确
await checkSmsCaptcha({
bizType: 'enterprise_change',
phone: concatData.phone,
captcha: concatData.veCode
})
this.cacheSetStepData(this.cacheKey, { enterpriseData, baseData, certData, fileData, concatData })
this.$router.push({ name: 'PersonChangeStep2' })
} catch (e) {
e.anchor()
}
}
}
}
</script>
<template>
<div v-loading.fullscreen.lock="fullscreenLoading" class="page">
<pageTitle title="企业责任人变更" />
<steps :data="dict.personChangeSteps" :index="1" margin="0 160px" />
<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="visible"
:desc="content"
:show-cancel-btn="false"
type="success"
@on-sure="onSure"
/>
<comp-confirm
:show.sync="showErrorConfirm"
:desc="errorConfirmDesc"
/>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
import PageModuleTabs from '@/components/PageModule/tabs'
import { submitEnterpriseChange, getLivenessCode } from '@/api/person-change'
import CompFaceRecognition from '@/components/CompFaceRecognition'
import CompConfirm from '@/components/CompConfirm'
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: 'PersonChangeStep1',
components: {
CompFaceRecognition,
CompConfirm,
PageModuleTabs
},
mixins: [Common],
data() {
return {
TABS,
fullscreenLoading: false,
visible: false,
content: '已转入人工审核,请注意查询认证进度',
pageData: {},
showErrorConfirm: false,
livenessType: '',
errorConfirmDesc: '',
tabName: 'video'
}
},
computed: {
...mapGetters(['dict', 'device']),
faceData() {
return this.pageData.faceData || {}
}
},
created() {
this.init()
},
methods: {
errorTips(errMsg) {
this.showErrorConfirm = true
this.errorConfirmDesc = errMsg
},
onPrevStep() {
this.$router.push({ name: 'PersonChangeStep1', params: { from: 'prev' }})
},
getSubmitData() {
const step1Data = this.cacheGetStepData('PersonChangeStep1')
const ret = {
companyName: step1Data.enterpriseData.companyName,
corporationCertAddress: step1Data.certData.address,
corporationCertExpirationDate: step1Data.certData.validDate,
corporationCertEffectiveDate: step1Data.certData.certEffectiveDate,
corporationCertPic: step1Data.certData.photoUrls.filter(item => item.url.id !== null).map(item => item.url.id),
corporationCertNumber: step1Data.certData.no,
corporationCertType: step1Data.certData.type,
corporationContactAddress: step1Data.certData.connectAddress,
corporationGender: step1Data.baseData.sex,
corporationName: step1Data.baseData.name,
corporationPhone: step1Data.concatData.phone,
captcha: step1Data.concatData.veCode,
corporationVideo: this.$refs.faceInfo.getFormData().fileList[0].uuid,
authorizationLetterPic: step1Data.fileData.fileList.map(item => item.uuid),
origCorporationName: step1Data.enterpriseData.corporationName,
requestId: this._remoteLiveData.requestId
}
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.submitEnterpriseChange(this.getSubmitData())
this.fullscreenLoading = false
if (!respData.isOk) {
this.errorTips(respData.data.message || '责任人变更失败')
return
}
this.visible = true
} catch (e) {
e.anchor()
}
},
async getLivenessCode() {
try {
const ret = await getLivenessCode()
return ret
} catch (e) {
return null
}
},
async submitEnterpriseChange(params) {
try {
const respData = await submitEnterpriseChange({
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>
<template>
<el-form ref="form" :rules="rules" :model="form" label-width="80px" label-position="top" size="small">
<el-row :gutter="40">
<el-col :span="12">
<el-form-item label="企业名称" prop="companyName">
<el-input v-model="form.companyName" placeholder="请输入企业名称" disabled />
</el-form-item>
</el-col>
<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" :label="item.label" :value="item.value"/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="企业证件号码" prop="companyCertNumber">
<el-input v-model="form.companyCertNumber" placeholder="请输入企业证件号码" disabled />
</el-form-item>
</el-col>
</el-row>
</el-form>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
name: 'FlowEnterpriseInfo',
props: {
data: {
type: Object,
default: () => ({})
}
},
data() {
return {
form: {
companyName: '',
companyCertType: '',
companyCertNumber: ''
},
rules: {
companyName: [{ required: true, message: '请输入企业名称', trigger: 'blur' }],
companyCertType: [{ required: true, message: '请选择企业证件类型', trigger: 'blur, change' }],
companyCertNumber: [{ required: true, message: '请输入企业证件号码', trigger: 'blur' }]
}
}
},
computed: {
...mapGetters(['dict'])
},
watch: {
data() {
this.updateInternalData()
}
},
created() {
this.init()
},
methods: {
init() {
this.updateInternalData()
},
updateInternalData() {
if (typeof this.data === 'object' && this.data !== null) {
const { companyName, companyCertType, companyCertNumber } = this.data
this.form = {
companyName,
companyCertType,
companyCertNumber
}
} else {
this.form = {
companyName: '',
companyCertType: '',
companyCertNumber: ''
}
}
},
getPendingCacheData() {
return this.getFormData()
},
/**
* 获取当前模块数据
* @time 2022-04-23 15:50:05
*/
async validate(isErrorAnchor = false) {
try {
await this.$refs.form.validate()
return true
} catch (e) {
if (isErrorAnchor) {
this.$refs.form.fields.filter(item => item.validateState === 'error')[0].$el.scrollIntoView(true)
}
let temp = {
anchor: () => {
this.$refs.form.fields.filter(item => item.validateState === 'error')[0].$el.scrollIntoView(true)
temp = null
}
}
throw temp
}
},
/**
* 获取表单数据
* @time 2022-04-23 18:02:02
*/
getFormData() {
return this.form
}
}
}
</script>
<template>
<el-form ref="form" :rules="rules" :model="form" label-width="80px" label-position="top" size="small">
<el-row :gutter="40">
<el-col :span="12">
<el-form-item label="责任人姓名" prop="name">
<el-input v-model="form.name" placeholder="请输入责任人姓名" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="手机号码" prop="phone">
<el-input v-model="form.phone" placeholder="请输入手机号码" disabled />
</el-form-item>
</el-col>
</el-row>
</el-form>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
name: 'FlowPersonInfo',
props: {
data: {
type: Object,
default: () => ({})
}
},
data() {
return {
form: {
name: '',
phone: ''
},
rules: {
name: [{ required: true, message: '请输入责任人姓名', trigger: 'blur' }],
phone: [{ required: true, message: '请输入手机号码', trigger: 'blur' }]
}
}
},
computed: {
...mapGetters(['dict'])
},
watch: {
data() {
this.updateInternalData()
}
},
created() {
this.init()
},
methods: {
init() {
this.updateInternalData()
},
updateInternalData() {
if (typeof this.data === 'object' && this.data !== null) {
const { name, phone } = this.data
this.form = {
name,
phone
}
} else {
this.form = {
name: '',
phone: ''
}
}
},
getPendingCacheData() {
return this.getFormData()
},
/**
* 获取当前模块数据
* @time 2022-04-23 15:50:05
*/
async validate(isErrorAnchor = false) {
try {
await this.$refs.form.validate()
return true
} catch (e) {
if (isErrorAnchor) {
this.$refs.form.fields.filter(item => item.validateState === 'error')[0].$el.scrollIntoView(true)
}
let temp = {
anchor: () => {
this.$refs.form.fields.filter(item => item.validateState === 'error')[0].$el.scrollIntoView(true)
temp = null
}
}
throw temp
}
},
/**
* 获取表单数据
* @time 2022-04-23 18:02:02
*/
getFormData() {
return this.form
}
}
}
</script>
<template>
<div class="page">
<pageTitle title="车企实名认证" />
<steps :data="dict.carEnterpriseRealnameSteps" :index="0" />
<CarSimFile 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 CarSimFile from '../realname-enterprise/components/car-sim-file'
import Common from '@/components/Common'
import { checkVinCard } from '@/api/iccid'
export default {
name: 'CarEnterpriseRealnameFlow1',
components: {
CarSimFile
},
mixins: [Common],
data() {
return {
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 { fileId } = this.pageData
await checkVinCard({ fileId, businessType: 4 })
const data = this.$refs.carSimFile.getPendingCacheData()
this.cacheSetStepData(this.cacheKey, data)
this.$router.push({ name: 'CarEnterpriseRealnameFlow2' })
},
onCheck(data) {
this.pageData = data
}
}
}
</script>
<template>
<div v-loading.fullscreen.lock="fullscreenLoading" class="page">
<pageTitle title="车企实名认证" />
<steps :data="dict.carEnterpriseRealnameSteps" :index="1" />
<page-module name="基本信息" icon="info">
<FlowEnterpriseInfo ref="baseInfo" :data="pageData" />
</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>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
import FlowEnterpriseInfo from './components/flow-enterprise-info'
import Common from '@/components/Common'
import { queryCarEnterpriseDetail } from '@/api/realname-car-enterprise'
export default {
name: 'CarEnterpriseRealnameFlow2',
components: {
FlowEnterpriseInfo
},
mixins: [Common],
data() {
return {
fullscreenLoading: false,
pageData: {}
}
},
computed: {
...mapGetters(['dict'])
},
created() {
// this.init()
this.getBaseInfo()
},
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 = {
// companyName: '',
// companyCertType: '',
// companyCertNumber: ''
// }
// },
getBaseInfo() {
this.fullscreenLoading = true
return queryCarEnterpriseDetail({}).then(data => {
this.pageData = {
companyName: data.companyName,
companyCertType: data.companyCertType,
companyCertNumber: data.companyCertNumber
}
this.fullscreenLoading = false
}).catch(() => {
this.fullscreenLoading = false
})
},
onPrevStep() {
this.$router.push({ name: 'CarEnterpriseRealnameFlow1', params: { from: 'prev' }})
},
onNextStep() {
// const data = this.$refs.baseInfo.getPendingCacheData()
// this.cacheSetStepData(this.cacheKey, data)
this.$router.push({ name: 'CarEnterpriseRealnameFlow3' })
}
}
}
</script>
<template>
<div v-loading.fullscreen.lock="fullscreenLoading" class="page">
<pageTitle title="车企实名认证" />
<steps :data="dict.carEnterpriseRealnameSteps" :index="2" />
<page-module name="责任人信息" icon="info">
<FlowPersonInfo ref="personInfo" :data="personData"/>
</page-module>
<page-module name="文件信息" icon="folder">
<el-row>
<el-col :span="12">
<FileInfo ref="contractInfo" :data="contractData" :upload-type="['camera', 'sign']" sign-key="companyAgreement" mode="preview" label="入网协议"/>
</el-col>
<el-col :span="12">
<FileInfo ref="fileInfo" :data="fileData" mode="preview" label="企业实名认证授权书"/>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<FileInfo ref="dutyInfo" :data="dutyData" :upload-type="['camera', 'sign']" sign-key="realnameNotice" mode="preview" label="责任告知书"/>
</el-col>
</el-row>
</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 FlowPersonInfo from './components/flow-person-info'
import FileInfo from '@/components/FileInfo'
import Common from '@/components/Common'
import CompConfirm from '@/components/CompConfirm'
import { queryCarEnterpriseDetail, submitRnrFollowUp } from '@/api/realname-car-enterprise'
export default {
name: 'CarEnterpriseRealnameFlow3',
components: {
FlowPersonInfo,
FileInfo,
CompConfirm
},
mixins: [Common],
data() {
return {
fullscreenLoading: false,
pageData: {
fileData: {},
contractData: {},
dutyData: {}
},
showSuccessConfirm: false,
successConfirmDesc: '',
showErrorConfirm: false,
errorConfirmDesc: ''
}
},
computed: {
...mapGetters(['dict']),
personData() {
return this.pageData.personData || {}
},
fileData() {
return this.pageData.fileData || {}
},
dutyData() {
return this.pageData.dutyData || {}
},
contractData() {
return this.pageData.contractData || {}
}
},
created() {
this.getBaseInfo()
// 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 = {
// personData: {},
// fileData: {}
// }
// },
errorTips(errMsg) {
this.showErrorConfirm = true
this.errorConfirmDesc = errMsg
},
successTips(msg) {
this.showSuccessConfirm = true
this.successConfirmDesc = msg
},
getBaseInfo() {
this.fullscreenLoading = true
return queryCarEnterpriseDetail({}).then(data => {
this.pageData = {
personData: {
name: data.corporationName,
phone: data.corporationPhone
},
fileData: {
fileList: data.authorizationLetterPic.map(item => {
return {
accessUrl: `data:image/png;base64,${item}`
}
})
},
dutyData: {
fileList: data.dutyPic.map(item => {
return {
accessUrl: `data:image/png;base64,${item}`
}
})
},
contractData: {
fileList: data.contractPic.map(item => {
return {
accessUrl: `data:image/png;base64,${item}`
}
})
}
}
this._submitData = data
this.fullscreenLoading = false
}).catch(() => {
this.fullscreenLoading = false
})
},
onPrevStep() {
this.$router.push({ name: 'CarEnterpriseRealnameFlow2', params: { from: 'prev' }})
},
/**
* 下一步
* @time 2022-04-23 15:50:05
*/
async onSubmit() {
try {
await Promise.all([
this.$refs.personInfo.validate(),
this.$refs.dutyInfo.validate(),
this.$refs.fileInfo.validate(),
this.$refs.contractInfo.validate()
])
const flowStep1Data = this.cacheGetStepData('CarEnterpriseRealnameFlow1')
// 提交数据
this.fullscreenLoading = true
const respData = await this.carEnterpriseSubmitRnr({
fileId: flowStep1Data.checkData.fileId,
vehicleEnterpriseId: this._submitData.vehicleEnterpriseId
// liveVerificationVideo: this._submitData.liveVerificationVideo
})
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) {
e.anchor()
}
},
async carEnterpriseSubmitRnr(params) {
try {
const respData = await submitRnrFollowUp({
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>
<template>
<div class="page">
<pageTitle title="车企实名认证" />
<steps :data="dict.enterpriseRealnameSteps" :index="0" />
<CarSimFile 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 CarSimFile from '../realname-enterprise/components/car-sim-file'
import Common from '@/components/Common'
import { checkVinCard } from '@/api/iccid'
export default {
name: 'CarEnterpriseRealnameStep1',
components: {
CarSimFile
},
mixins: [Common],
data() {
return {
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 { fileId } = this.pageData
await checkVinCard({ fileId, businessType: 4 })
const data = this.$refs.carSimFile.getPendingCacheData()
this.cacheSetStepData(this.cacheKey, data)
this.$router.push({ name: 'CarEnterpriseRealnameStep2' })
},
onCheck(data) {
this.pageData = data
}
}
}
</script>
<template>
<div class="page">
<pageTitle title="车企实名认证" />
<steps :data="dict.enterpriseRealnameSteps" :index="1" />
<page-module name="基本信息" icon="info">
<BaseInfo ref="baseInfo" :data="baseData" type="car-enterprise"/>
</page-module>
<page-module name="证件信息" icon="info">
<CertInfo ref="certInfo" :data="certData"/>
</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>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
import BaseInfo from '../realname-enterprise/components/base-info'
import CertInfo from '../realname-enterprise/components/cert-info'
import Common from '@/components/Common'
export default {
name: 'CarEnterpriseRealnameStep2',
components: {
BaseInfo,
CertInfo
},
mixins: [Common],
data() {
return {
pageData: {}
}
},
computed: {
...mapGetters(['dict']),
baseData() {
return this.pageData.baseData || {}
},
certData() {
return this.pageData.certData || {}
}
},
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 = {
baseData: {},
certData: {}
}
},
onPrevStep() {
this.$router.push({ name: 'CarEnterpriseRealnameStep1', params: { from: 'prev' }})
},
async onNextStep() {
try {
const valid = [
this.$refs.baseInfo.validate(),
this.$refs.certInfo.validate()
]
await Promise.all(valid)
const baseData = this.$refs.baseInfo.getPendingCacheData()
const certData = this.$refs.certInfo.getPendingCacheData()
this.cacheSetStepData(this.cacheKey, { baseData, certData })
this.$router.push({ name: 'CarEnterpriseRealnameStep3' })
} catch (e) {
e.anchor()
}
}
}
}
</script>
<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']" sign-key="companyAgreement" label="入网协议"/>
</el-col>
<el-col :span="12">
<FileInfo ref="fileInfo" 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>
</div>
</template>
<script>
import { checkSmsCaptcha } from '@/api/realname-person'
import { mapGetters } from 'vuex'
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: 'CarEnterpriseRealnameStep3',
components: {
CompBasicInfo,
CompCertificateInfo,
FileInfo,
CompConcatInfo
},
mixins: [Common],
data() {
return {
pageData: {
baseData: {},
certData: {},
fileData: {},
concatData: {}
}
}
},
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()
},
methods: {
init() {
this.getCacheData()
if (this.$route.params.from === 'prev') {
this.restoreCacheData()
} else {
this.resetStepData()
}
// 从缓存中取出数据
const stepPc = this.cacheGetStepData('CarEnterpriseRealnameStep1') || {}
this.attachment = {
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: 'CarEnterpriseRealnameStep2', params: { from: 'prev' }})
},
/**
* 下一步
* @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()
// 校验手机号输入是否正确
await checkSmsCaptcha({
phone: concatData.phone,
captcha: concatData.veCode
})
this.cacheSetStepData(this.cacheKey, { baseData, certData, fileData, contractData, dutyData, concatData })
this.$router.push({ name: 'CarEnterpriseRealnameStep4' })
} catch (e) {
e.anchor()
}
}
}
}
</script>
<template>
<div v-loading.fullscreen.lock="fullscreenLoading" class="page">
<pageTitle 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, carEnterpriseSubmitRnr } from '@/api/realname-car-enterprise'
import CompFaceRecognition from '@/components/CompFaceRecognition'
import PageModuleTabs from '@/components/PageModule/tabs'
import CompConfirm from '@/components/CompConfirm'
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: 'CarEnterpriseRealnameStep4',
components: {
CompFaceRecognition,
CompConfirm,
PageModuleTabs
},
mixins: [Common],
data() {
return {
TABS,
fullscreenLoading: false,
showSuccessConfirm: false,
successConfirmDesc: '',
pageData: {},
showErrorConfirm: false,
livenessType: '',
errorConfirmDesc: '',
tabName: 'video'
}
},
computed: {
...mapGetters(['dict', 'device']),
faceData() {
return this.pageData.faceData || {}
}
},
created() {
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: 'CarEnterpriseRealnameStep3', params: { from: 'prev' }})
},
getSubmitData() {
const step1Data = this.cacheGetStepData('CarEnterpriseRealnameStep1')
const step2Data = this.cacheGetStepData('CarEnterpriseRealnameStep2')
const step3Data = this.cacheGetStepData('CarEnterpriseRealnameStep3')
const ret = {
companyName: step2Data.baseData.companyName,
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: 1
}
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.carEnterpriseSubmitRnr(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) {
e.anchor()
}
},
async getLivenessCode() {
try {
const ret = await getLivenessCode()
return ret
} catch (e) {
return null
}
},
async carEnterpriseSubmitRnr(params) {
try {
const respData = await carEnterpriseSubmitRnr({
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>
<template>
<el-form ref="form" :rules="rules" :model="form" label-width="80px" label-position="top" size="small">
<el-row :gutter="40">
<el-col :span="12">
<el-form-item label="企业名称" prop="companyName">
<el-input v-model="form.companyName" placeholder="请输入企业名称" clearable />
</el-form-item>
</el-col>
</el-row>
<el-row v-if="type === 'enterprise'" :gutter="40">
<el-col :span="12">
<el-form-item label="企业性质" prop="companyType">
<el-select v-model="form.companyType" placeholder="请选择企业性质" clearable>
<el-option v-for="item of dict.companyType" :key="item.key" :label="item.label" :value="item.value"/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="行业类型" prop="industryType">
<el-select v-model="form.industryType" placeholder="请选择行业类型" clearable>
<el-option v-for="item of dict.industryType" :key="item.key" :label="item.label" :value="item.value"/>
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-form>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
name: 'BaseInfo',
props: {
type: {
type: String,
default: 'enterprise' // enterprise: 企业, car-enterprise: 车企
},
data: {
type: Object,
default() {
return {}
}
}
},
data() {
return {
form: {
companyName: '',
companyType: '',
industryType: ''
},
rules: {
companyName: [
{ required: true, message: '请输入企业名称', trigger: 'blur' }
]
}
}
},
computed: {
...mapGetters(['dict'])
},
watch: {
data() {
this.updateInternalData()
}
},
created() {
this.init()
},
methods: {
init() {
this.updateInternalData()
},
updateInternalData() {
if (typeof this.data === 'object' && this.data !== null) {
this.form = {
companyName: this.data.companyName || '',
companyType: this.data.companyType || '',
industryType: this.data.industryType || ''
}
} else {
this.form = {
companyName: '',
companyType: '',
industryType: ''
}
}
},
/**
* 获取当前模块数据
* @time 2022-04-23 15:50:05
*/
async validate(isErrorAnchor = false) {
try {
await this.$refs.form.validate()
return true
} catch (e) {
if (isErrorAnchor) {
this.$refs.form.fields.filter(item => item.validateState === 'error')[0].$el.scrollIntoView(true)
}
let temp = {
anchor: () => {
this.$refs.form.fields.filter(item => item.validateState === 'error')[0].$el.scrollIntoView(true)
temp = null
}
}
throw temp
}
},
/**
* 获取表单数据
* @time 2022-04-23 18:02:02
*/
getFormData() {
return this.form
},
/**
* 获取待缓存数据
* @time 2022-04-24 19:43:57
*/
getPendingCacheData() {
return this.getFormData()
}
}
}
</script>
<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">
<template v-if="form.checkData.failCount > 0">
<div class="info">{{ form.checkData.failCount }}条车卡数据验证{{ form.checkData.totalCount === 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 { verifyVinCardsTemplateUrl, postVinUpload, verifyVinCards, downloadFailFile } from '@/api/realname-car-enterprise'
export default {
name: 'CarSimFile',
components: {},
props: {
data: {
type: Object,
default() {
return {}
}
}
},
data() {
return {
fullscreenLoading: false,
upload: {
data: {
rootPath: '',
path: ''
},
headers: {
'Authorization': `bearer ${getToken()}`
},
action: postVinUpload
},
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 verifyVinCards({ 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
}).then(() => {
this.fullscreenLoading = false
}).catch(() => {
this.fullscreenLoading = false
})
},
/**
* 下载车卡模板文件
* @time 2022-04-23 15:02:50
*/
downloadTemplateFile() {
location.href = verifyVinCardsTemplateUrl
}
}
}
</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>
<template>
<el-form ref="form" :rules="rules" :model="form" label-width="80px" label-position="top" size="small">
<el-row :gutter="40">
<el-col :span="12">
<el-form-item label="企业证件类型" prop="companyCertType">
<el-select v-model="form.companyCertType" placeholder="请选择证件类型" clearable>
<el-option v-for="item of dict.companyCertType" :key="item.key" :label="item.label" :value="item.value"/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="40">
<el-col :span="12">
<el-form-item label="企业证件照片" prop="licenseImages">
<div class="device-wrap">
<uploader
ref="fileUpload"
v-model="form.licenseImages"
:data="upload.data"
:action="upload.action"
:before-upload="onUploadBefore"
:limit="5"
:security="true"
placeholder="上传照片"
list-type="picture-card"
accept="image/png, image/jpeg, image/jpg, application/pdf"
@on-error="onUploadError"
@on-success="onUploadSuccess"
@on-remove="onUploadRemove"
/>
<i v-if="device.showTakePhoto" class="icon-device-video" @click="showDialog = true" />
</div>
</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 />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="企业证件地址" prop="companyCertAddress">
<el-input v-model="form.companyCertAddress" placeholder="请输入企业证件地址" clearable />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="企业通讯地址" prop="companyContactAddress">
<el-input v-model="form.companyContactAddress" placeholder="请输入企业通讯地址" clearable />
</el-form-item>
</el-col>
</el-row>
<device-dialog :show.sync="showDialog" :security="true" :data="form.licenseImages" :limit="5" @getPhoto="getPhoto" />
</el-form>
</template>
<script>
import { mapGetters } from 'vuex'
import { getToken } from '@/utils/auth'
import { cuscImageUpload } from '@/api/realname-enterprise'
import Uploader from '@/components/Uploader'
import deviceDialog from '@/components/Device/dialog'
export default {
name: 'CertForm',
components: {
Uploader,
deviceDialog
},
props: {
data: {
type: Object,
default() {
return {}
}
}
},
data() {
const checkLicenseImages = (rule, value, callback) => {
if (value.length === 0) {
callback(new Error('请上传企业证件照片'))
} else {
callback()
}
}
return {
showDialog: false,
upload: {
data: {
rootPath: '',
path: ''
},
headers: {
'Authorization': `bearer ${getToken()}`
},
action: cuscImageUpload
},
form: {
companyCertType: '0',
licenseImages: [],
companyCertNumber: '',
companyCertAddress: '',
companyContactAddress: ''
},
rules: {
licenseImages: [
{ required: true, validator: checkLicenseImages, trigger: 'blur, change' }
],
companyCertNumber: [
{ required: true, message: '请输入企业证件号码', trigger: 'blur' }
],
companyCertAddress: [
{ required: true, message: '请输入企业证件地址', trigger: 'blur' }
],
companyContactAddress: [
{ required: true, message: '请输入企业通讯地址', trigger: 'blur' }
]
}
}
},
computed: {
...mapGetters(['dict', 'device'])
},
watch: {
data() {
this.updateInternalData()
}
},
created() {
this.init()
},
methods: {
init() {
this.updateInternalData()
},
updateInternalData() {
if (typeof this.data === 'object' && this.data !== null) {
this.form = {
companyCertType: this.data.companyCertType || '0',
licenseImages: this.data.licenseImages || [],
companyCertNumber: this.data.companyCertNumber || '',
companyCertAddress: this.data.companyCertAddress || '',
companyContactAddress: this.data.companyContactAddress || ''
}
} else {
this.form = {
companyCertType: '0',
licenseImages: [],
companyCertNumber: '',
companyCertAddress: '',
companyContactAddress: ''
}
}
},
/**
* 获取图片
* @time 2022-05-11 23:32:36
*/
getPhoto(data) {
this.form.licenseImages = data
},
/**
* 获取当前模块数据
* @time 2022-04-23 15:50:05
*/
async validate(isErrorAnchor = false) {
try {
await this.$refs.form.validate()
return true
} catch (e) {
if (isErrorAnchor) {
this.$refs.form.fields.filter(item => item.validateState === 'error')[0].$el.scrollIntoView(true)
}
let temp = {
anchor: () => {
this.$refs.form.fields.filter(item => item.validateState === 'error')[0].$el.scrollIntoView(true)
temp = null
}
}
throw temp
}
},
/**
* 获取表单数据
* @time 2022-04-23 18:02:02
*/
getFormData() {
return this.form
},
/**
* 获取待缓存数据
* @time 2022-04-24 19:43:57
*/
getPendingCacheData() {
return this.getFormData()
},
/**
* 凭证上传校验
* @time 2022-04-11 09:16:44
*/
onUploadBefore(file) {
const isJPG = file.type === 'image/jpeg'
const isPNG = file.type === 'image/png'
const isPDF = file.type === 'application/pdf'
const isLt5M = file.size / 1024 / 1024 < 5
if (!isJPG && !isPNG && !isPDF) {
this.$message.error('证件照片格式不对!')
return false
}
if (!isLt5M) {
this.$message.error('证件照片大小不能超过5MB!')
return false
}
},
/**
* 凭证上传成功
* @time 2022-04-09 17:22:21
*/
onUploadSuccess() {
this.$nextTick(() => {
this.$refs.form.validateField('licenseImages')
})
},
/**
* 凭证上传失败
* @time 2022-04-09 17:22:21
*/
onUploadError() {
this.$message.error('文件上传失败')
this.$refs.fileUpload.$refs.fileUpload.clearFiles()
this.onUploadRemove()
},
/**
* 移除上传凭证
* @time 2022-04-09 17:22:21
*/
onUploadRemove() {
this.$nextTick(() => {
this.$refs.form.validateField('licenseImages')
})
}
}
}
</script>
<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 ? 'EnterpriseRealnameStepPad1' : 'HomePage')">{{ status === STATUS.FAIL ? '重新认证' : '返回首页' }}</el-button>
</div>
</section>
</div>
</template>
<script>
import { enterpriseLivenessCallback } from '@/api/realname-enterprise'
// 状态
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 enterpriseLivenessCallback({
...(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>
<template>
<div class="page">
<pageTitle title="企业实名认证" />
<steps :data="dict.enterpriseRealnameSteps" :index="0" />
<page-module name="车卡信息" icon="car">
<CompVinCard ref="vinCardRef" :data="carCardData" @on-canenable="carCardLoading = !$event" :is-bind="false" />
</page-module>
<div class="next-step">
<el-button :disabled="carCardLoading" size="small" type="primary" @click="onNextStep">下一步</el-button>
</div>
</div>
</template>
<script>
import CompVinCard from '@/components/CompVinCard'
import { mapGetters } from 'vuex'
import CarSimFile from './components/car-sim-file'
import Common from '@/components/Common'
export default {
name: 'EnterpriseRealnameStep1',
components: {
CarSimFile,
CompVinCard
},
mixins: [Common],
data() {
return {
carCardData: {},
carCardLoading: false,
pageData: {
vinList: []
}
}
},
computed: {
...mapGetters(['dict'])
},
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 = {
vinList: []
}
},
async onNextStep() {
const data = this.$refs.vinCardRef.getPendingCacheData()
// 如果当前没有输入vin
if (data.vinList.length === 0) {
return
}
// 校验输入
await this.$refs.vinCardRef.validate()
this.cacheSetStepData(this.cacheKey, this.$refs.vinCardRef.getPendingCacheData())
this.cacheDelStepData('EnterpriseRealnameStep2')
this.cacheDelStepData('EnterpriseRealnameStep3')
this.cacheDelStepData('EnterpriseRealnameStep4')
this.$router.push({ name: 'EnterpriseRealnameStep2' })
},
onCheck(data) {
this.pageData = data
}
}
}
</script>
<template>
<div class="page">
<pageTitle title="企业实名认证" />
<steps :data="dict.enterpriseRealnameSteps" :index="0" />
<CarSimFile 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 CarSimFile from './components/car-sim-file'
import Common from '@/components/Common'
import { checkVinCard } from '@/api/iccid'
export default {
name: 'EnterpriseRealnameStep1',
components: {
CarSimFile
},
mixins: [Common],
data() {
return {
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 { fileId } = this.pageData
await checkVinCard({ fileId, businessType: 3 })
const data = this.$refs.carSimFile.getPendingCacheData()
this.cacheSetStepData(this.cacheKey, data)
this.$router.push({ name: 'EnterpriseRealnameStep2' })
},
onCheck(data) {
this.pageData = data
}
}
}
</script>
<template>
<div class="page">
<pageTitle title="企业实名认证" />
<steps :data="dict.enterpriseRealnameSteps" :index="1" />
<page-module name="企业基本信息" icon="info">
<BaseInfo ref="baseInfo" :data="baseData"/>
</page-module>
<page-module name="证件信息" icon="info">
<CertInfo ref="certInfo" :data="certData" />
</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>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
import BaseInfo from './components/base-info'
import CertInfo from './components/cert-info'
import Common from '@/components/Common'
export default {
name: 'EnterpriseRealnameStep2',
components: {
BaseInfo,
CertInfo
},
mixins: [Common],
data() {
return {
pageData: {}
}
},
computed: {
...mapGetters(['dict']),
baseData() {
return this.pageData.baseData || {}
},
certData() {
return this.pageData.certData || {}
}
},
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 = {
baseData: {},
certData: {}
}
},
/**
* 上一步
* @time 2022-04-23 16:33:24
*/
onPrevStep() {
this.$router.push({ name: window.OS.isTablet ? 'EnterpriseRealnameStepPad1' : 'EnterpriseRealnameStep1', params: { from: 'prev' }})
},
/**
* 下一步
* @time 2022-04-23 15:50:05
*/
async onNextStep() {
try {
const valid = [
this.$refs.baseInfo.validate(),
this.$refs.certInfo.validate()
]
await Promise.all(valid)
const baseData = this.$refs.baseInfo.getPendingCacheData()
const certData = this.$refs.certInfo.getPendingCacheData()
this.cacheSetStepData(this.cacheKey, { baseData, certData })
this.$router.push({ name: 'EnterpriseRealnameStep3' })
} catch (e) {
e.anchor()
}
}
}
}
</script>
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment