Merge branch 'feature/GFRS-213【待确定】电投问题件-前端开发-new' into release/1106

# Conflicts:
#	src/router/ebiz/index.js
#	src/views/ebiz/sale/Detail.vue
This commit is contained in:
mengxiaolong
2020-11-06 13:22:20 +08:00
8 changed files with 1724 additions and 15 deletions

View File

@@ -0,0 +1,29 @@
import request from '@/assets/js/utils/request'
import getUrl from '@/assets/js/utils/get-url'
// 列表
export function getQuestionList(data = {}) {
return request({
method: 'post',
url: getUrl('/sale/issue/getPrtIssueList', 1),
data
})
}
// 详情
export function getQuestionDetail(data = {}) {
return request({
method: 'post',
url: getUrl('/sale/issue/getPrtIssueDetail', 1),
data
})
}
// 更新
export function updateQuestionDetail(data = {}) {
return request({
method: 'post',
url: getUrl('/sale/issue/updatePrtIssue', 1),
data
})
}

View File

@@ -0,0 +1,234 @@
<template>
<div :class="{ message: 1, show }">
<div class="box">
<div class="title">短信验证</div>
<div class="content">
<p>{{ text }}</p>
<div class="enter" v-if="type === 'confirm'">
<input type="text" v-model="code" placeholder="请输入短信验证码" maxlength="6" />
<button type="button" @click="getMessage" v-no-more-click="3000">
{{ sendTime === 0 ? '获取验证码' : sendTime + 's后重新获取' }}
</button>
</div>
</div>
<div class="bottom">
<div @click="cancel" v-if="type === 'confirm'">取消</div>
<div @click="confirm" :style="{ width: type === 'alert' ? '100%' : '50%' }">确定</div>
</div>
</div>
</div>
</template>
<script>
import { getAuthCode, autchCodeCheck } from '@/api/ebiz/sale/sale'
export default {
name: 'shortMessage',
props: {
phoneNumber: {
type: String,
default: ''
},
show: {
type: Boolean,
default: false
},
text: {
type: String,
default: ''
},
type: {
type: String,
default: 'confirm'
},
sendTime: {
type: Number,
default: 0
}
},
data() {
return {
code: '',
sid: '',
getCaptcha: false,
timer: null
}
},
watch: {
show(n) {
if (n)
return (document.body.style.cssText = `
overflow-y:hidden;
height:100vh;
`)
document.body.style.cssText = `
overflow-y:visible;
height:auto;
`
},
sendTime(nv) {
if (nv === 0) {
clearInterval(this.timer)
this.timer = null
}
if (!this.timer) {
this.timer = setInterval(() => {
if (this.sendTime === 0) {
console.log('clear timer...')
clearInterval(this.timer)
this.timer = null
} else {
this.$emit('update:sendTime', this.sendTime - 1)
}
}, 1000)
}
}
},
methods: {
cancel() {
clearInterval(this.timer)
this.timer = null
this.$emit('update:sendTime', 0)
this.code = ''
this.getCaptcha = false
this.$emit('update:show', false)
},
async confirm() {
if (!this.getCaptcha) {
return this.$toast('请先获取验证码')
}
if (!this.code.trim()) {
return this.$toast('请输入验证码')
}
let res = await autchCodeCheck({
smsId: this.sid,
code: this.code
})
if (res.result === '0') {
this.$emit('getMessage', {
type: 'confirm',
data: true
})
clearInterval(this.timer)
this.timer = null
this.$emit('update:sendTime', 0)
} else {
this.$toast(res.resultMessage)
}
this.code = ''
},
async getMessage() {
if (this.sendTime !== 0) return
this.getCaptcha = true
let data = {
operateType: 'appntInfoEntry',
type: 'H5',
operateCode: this.phoneNumber,
system: 'agentApp',
operateCodeType: '0'
}
//获取验证码
let res = await getAuthCode(data)
if (res.result === '0') {
this.$toast('获取验证码成功')
}
this.sid = res.sessionId
this.$emit('update:sendTime', 60)
}
}
}
</script>
<style lang="scss" scoped>
.message {
position: fixed;
width: 100vw;
height: 100vh;
background: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
top: 0;
left: 0;
z-index: -1;
visibility: hidden;
transition: all 0.2s ease 0.2s;
opacity: 0;
&.show {
z-index: 9;
visibility: visible;
opacity: 1;
transition: all 0.2s;
.box {
transform: translateY(0);
transition: all 0.2s ease 0.2s;
}
}
.box {
width: 300px;
background: #fff;
border-radius: 10px;
position: relative;
overflow: hidden;
transform: translateY(-10px);
transition: all 0.2s;
padding-bottom: 40px;
.title {
text-align: center;
font-size: 14px;
color: #e4393c;
padding: 10px 0;
}
.content {
padding: 0 10px 15px;
p {
font-size: 13px;
padding: 10px 0;
}
.enter {
display: flex;
justify-content: space-between;
input,
button {
border: 0;
height: 30px;
}
input {
width: 150px;
font-size: 14px;
}
button {
background: 0;
border: 1px solid #e4393c;
color: #e4393c;
font-size: 13px;
text-align: center;
width: 90px;
border-radius: 4px;
flex-shrink: 0;
}
}
}
.bottom {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
display: flex;
div {
width: 50%;
height: 40px;
box-sizing: border-box;
text-align: center;
line-height: 40px;
&:first-child {
border-radius: 0 0 0 10px;
border: 1px solid #e4393c;
color: #e4393c;
}
&:last-child {
color: #fff;
background: #e4393c;
}
}
}
}
}
</style>

View File

@@ -24,6 +24,7 @@ import performance from './performance'
import attendance from './attendance' import attendance from './attendance'
import renewalManage from './renewalManage' import renewalManage from './renewalManage'
import question from './question'
export default [ export default [
...proposal, ...proposal,
...sale, ...sale,
@@ -47,5 +48,6 @@ export default [
...performance, ...performance,
...attendance, ...attendance,
...congratulation, ...congratulation,
...renewalManage ...renewalManage,
...question
] //根据需要进行删减 ] //根据需要进行删减

View File

@@ -0,0 +1,31 @@
const g = filename => () => import(`@/views/ebiz/questions/${filename}.vue`)
export default [
{
path: '/questions/list',
name: 'QuestionsList',
component: g('QuestionsList'),
meta: {
title: '投保问题件',
index: 1
}
},
{
path: '/questions/detail/:id/:type',
name: 'QuestionsDetail',
component: g('QuestionsDetail'),
meta: {
title: '问题处理',
index: 1
}
},
{
path: '/questions/result/:result',
name: 'result',
component: g('Result'),
meta: {
title: '提交结果',
index: 1
}
}
]

View File

@@ -0,0 +1,925 @@
<template>
<div class="detail-container">
<div class="pdf">
<iframe :src="src + pdfUrl" class="iframe"></iframe>
</div>
<!-- 补充材料问题件 -->
<div class="update" v-if="issueType === '828601'">
<div class="updateInfo">
<div class="title">请上传补充资料</div>
<div class="content">
<div class="query">
<div>问题说明</div>
<p>
{{ problemDetail.issueContent }}
</p>
</div>
<van-uploader :after-read="uploadSupplementImg" :before-delete="deleteSupplementImg" v-model="imageList" />
</div>
</div>
</div>
<!-- 新契约基本问题件 -->
<div class="feedback" v-if="issueType === 'TB89'">
<div class="title">问题件回复</div>
<textarea placeholder="请输入" v-model="newContract.feedback"></textarea>
</div>
<div class="checkedBox" v-if="issueType !== '818901'">
<van-checkbox v-model="checked" class="checked" icon-size="16px" shape="square"
>本人认真阅读本新契约基本问题件对其有关内容已全部了解确认所上传资料均为真实资料如有虚假资料或不如实告知一切法律后果本人承担同意将其作为投保要约的有效组成部分并承诺遵守</van-checkbox
>
</div>
<!-- 转账不成功基本问题件 -->
<div class="selectList" v-if="issueType === '818901'">
<div class="item">
<van-field label-class="labels" label="处理方式">
<template #input>
<van-radio-group :disabled="handleType" v-model="transfer.mode" direction="horizontal" class="radioGroup" @change="modeChange">
<van-radio :name="1" icon-size="16px">继续转账</van-radio>
<van-radio :name="2" icon-size="16px">终止转账</van-radio>
<van-radio :name="3" icon-size="16px">更换卡号</van-radio>
</van-radio-group>
</template>
</van-field>
</div>
<div v-if="this.transfer.mode === 3">
<div class="item">
<van-field v-model="transfer.bank" @click="getBankListItem" label-class="labels" readonly label="开户银行" placeholder="请选择"> </van-field>
</div>
<div class="item">
<van-field v-model="transfer.card" :maxlength="19" label-class="labels" label="银行卡号" placeholder="请输入银行卡号"
><template #button>
<van-button size="small" class="button" round color="#e4393c" type="primary" @click.stop="toggleCardScan(true)">银行卡扫描</van-button>
</template>
</van-field>
</div>
<div class="item">
<van-field label-class="labels" readonly label="银行卡照片"></van-field>
<div class="cardList">
<van-uploader :max-count="1" :after-read="cardUpload" @delete="transferBankCardDelete" name="bankcardA" v-model="transfer.cardPhoto" />
</div>
</div>
</div>
<div class="checkedBox" v-if="issueType === '818901'">
<van-checkbox v-model="checked" class="checked" icon-size="16px" shape="square"
>本人已认真阅读和理解上述通知书内容同意将其作为投保要约的有效组成部分并承诺遵守</van-checkbox
>
</div>
</div>
<!-- end -->
<div class="autograph">
<div class="list">
<span>投保人<span v-if="releationType">/被保险人</span>亲笔签名</span>
<van-button type="danger" size="small" @click="autograph(0)">{{ policyholderSigned ? '已签名' : '未签名' }}</van-button>
</div>
<div class="list" v-if="!releationType">
<span>被保险人/监护人亲笔签名</span>
<van-button type="danger" size="small" @click="autograph(1)">{{ insurantSigned ? '已签名' : '未签名' }}</van-button>
</div>
</div>
<div class="bg-white bottom-btn">
<van-button type="danger" size="large" block @click="submit">下一步</van-button>
</div>
<short-message
:phoneNumber="phoneNum"
:sendTime.sync="sendTime"
:show.sync="dialog.show"
:type="dialog.type"
:text="dialog.text"
@getMessage="getMessage"
></short-message>
<van-popup v-model="transfer.show" position="bottom">
<ul class="bankList">
<li v-for="item in transfer.bankList" :key="item.code" @click="getBankListItem(item)">{{ item.bankName }}</li>
</ul>
</van-popup>
<div :class="{ showDiscern: 1, show: transfer.showDiscern }">
<van-icon name="cross" class="icon" @click.stop="toggleCardScan(false)" size="20" />
<bank-card-scan class="backContent" :scanShow="true" :clear="transfer.clear" @getScanInfo="getBankNo"></bank-card-scan>
</div>
<!-- 转账不成功问题件提示框 -->
<van-dialog v-model="showConfirm" title="标题" :show-confirm-button="false">
<p style="margin: 1em;" v-if="transfer.mode === 2">
如您选择终止转账我公司将按照承保前撤单处 请您谨慎选择
</p>
<p style="margin: 1em;" v-if="transfer.mode === 3">
变更银行账号后续期保险费如有默认使用新账 号信息进行转账支付
</p>
<van-button type="danger" block @click="showConfirm = false">确定</van-button>
</van-dialog>
</div>
</template>
<script>
import { Uploader, Checkbox, Field, Radio, RadioGroup, Popup, Overlay, Dialog } from 'vant'
import { getBankList, uploadImg } from '@/api/ebiz/sale/sale'
import { getQuestionDetail, updateQuestionDetail } from '@/api/ebiz/questions'
import BankCardScan from '@/components/ebiz/sale/BankCardScan'
import ShortMessage from '@/components/ebiz/question/ShortMessage.vue'
import config from '@/config'
export default {
name: 'QuestionsDetail',
components: {
[Uploader.name]: Uploader,
[Checkbox.name]: Checkbox,
ShortMessage,
BankCardScan,
[Field.name]: Field,
[Radio.name]: Radio,
[RadioGroup.name]: RadioGroup,
[Popup.name]: Popup,
[Overlay.name]: Overlay,
[Dialog.name]: Dialog
},
data() {
let isWeixin = this.$utils.device().isWeixin
return {
releationType: null,
imageList: [],
imageResultList: [],
sendTime: 0,
isWeixin,
problemInfo: {},
problemDetail: {},
newContract: {
// 新契约
feedback: ''
},
transfer: {
// 转账失败
mode: 1,
bank: '',
bankCode: '',
card: '',
cardPhoto: [],
bankList: [],
show: false, //显示银行列表
showDiscern: false, //是否开启银行卡识别
clear: false, //是否清空银行卡识别数据
cardUploadResult: null
},
// 勾选协议
checked: false,
dialog: {
// 弹窗
show: false,
type: 'confirm',
text: ''
},
issueType: 0,
// 投保人是否已签名
policyholderSigned: false,
policyholderBase64: '',
// 被保人是否已签名
insurantSigned: false,
insurantBase64: '',
// 接收验证码手机号码
phoneNum: '',
showConfirm: false,
src: location.origin + '/pdfjs/web/viewer.html?file=',
pdfUrl: '',
// 转账不成功处理方式是否不可用
handleType: false
}
},
methods: {
// 补充资料问题件被保人上传身份证照片
async uploadSupplementImg() {
if (this.isWeixin) {
localStorage.setItem('supplementImages', JSON.stringify(this.imageList))
}
},
deleteSupplementImg() {
if (this.isWeixin) {
localStorage.setItem('supplementImages', JSON.stringify(this.imageList))
}
return true
},
checkSupplementData() {
return this.imageList.length !== 0
},
// 转账不成功问题件添加银行卡照片
async cardUpload(file, detail) {
// 供微信签名回调回显图片
if (this.isWeixin) {
localStorage.setItem(detail.name, file.content)
}
let res = await this.afterRead(file)
if (res.result === '0') {
this.transfer.cardUploadResult = {
rgssUrl: res.path,
imageInfoType: '3',
subBusinessType: '0'
}
if (this.isWeixin) {
localStorage.setItem('transferCardUploadResult', JSON.stringify(this.transfer.cardUploadResult))
}
} else {
this.$toast(res.resultMessage)
}
},
// 转账不成功问题件删除银行卡照片
transferBankCardDelete() {
this.transfer.cardUploadResult = null
},
// 签名
async autograph(personType) {
if (this.isWeixin && this.checked) {
localStorage.setItem('agreementChecked', true)
}
// 新契约问题件签名前必须输入回复内容
if (this.issueType === 'TB89') {
let reply = this.newContract.feedback.trim()
if (!reply) {
return this.$toast('请填写具体回复信息')
} else if (reply.length < 4 || reply.length > 400) {
return this.$toast('请输入4-400个字符')
} else {
localStorage.setItem('problemReplay', reply)
}
}
// 转账不成功签名前必须选择处理方式
if (this.issueType === '818901') {
if (this.transfer.mode === '') {
return this.$toast('请先选择处理方式')
} else {
localStorage.setItem('resolveType', this.transfer.mode)
}
// 非终止转账
if (this.transfer.mode === 3) {
// 校验开户行
if (!this.transfer.bank) {
return this.$toast('请选择开户银行')
}
// 银行卡号校验
if (this.transfer.card.trim() === '') {
return this.$toast('请填写银行卡信息')
}
let regx = /^(\d{16}|\d{18}|\d{19})$/
if (!regx.test(this.transfer.card)) {
return this.$toast('银行卡号不符合规则')
}
if (this.transfer.cardPhoto.length === 0) {
return this.$toast('请上传银行卡照片')
}
}
if (this.transfer.bank) {
localStorage.setItem('problemBank', this.transfer.bank)
}
if (this.transfer.bankCode) {
localStorage.setItem('problemBankCode', this.transfer.bankCode)
}
if (this.transfer.card) {
localStorage.setItem('problemCard', this.transfer.card)
}
}
let name = personType === 0 ? this.problemInfo.appntName : this.problemInfo.insuredName
let number = personType === 0 ? this.problemInfo.appntIdCardNo : this.problemInfo.insuredIdCardNo
let keyword = ''
if (personType === 1) {
keyword = '被保险人/监护人签名:'
}
if (personType === 0) {
if (this.releationType) {
keyword = '投保人/被保险人签名:'
} else {
keyword = '投保人签名:'
}
}
if (!this.isWeixin) {
let signParam = {
name,
type: '1',
number,
keyword,
pageNo: '1',
index: 1,
offset: 20,
pos: 3,
signatureWidth: this.$utils.signParams().signatureWidth,
signatureHeight: this.$utils.signParams().signatureHeight
}
console.dir(signParam)
// eslint-disable-next-line
const res = await EWebBridge.webCallAppInJs('ca_sign', signParam)
let signRes = JSON.parse(res)
// 投保人签名
if (personType === 0 && signRes.state === '1') {
this.policyholderBase64 = decodeURI(signRes.sign)
this.policyholderSigned = true
}
// 被保人签名
else if (personType === 1 && signRes.state === '1') {
this.insurantBase64 = decodeURI(signRes.sign)
this.insurantSigned = true
}
} else {
if (personType === 0) {
if (this.releationType) {
this.toAirSign('0', '投保人/被保险人签名:', '10', '2', personType)
} else {
this.toAirSign('0', '投保人签名:', '10', '2', personType)
}
} else {
let keyword = '被保险人/监护人签名:'
this.toAirSign('0', keyword, '10', '2', personType)
}
}
},
getBankNo(data) {
console.log(data)
},
toggleCardScan(data) {
this.transfer.showDiscern = data
if (data) {
localStorage.setItem('cardScanningType', 0)
} else {
localStorage.removeItem('cardScanningType')
}
},
getBankListItem(item) {
this.transfer.show = !this.transfer.show
this.transfer.bank = item.bankName
this.transfer.bankCode = item.code
},
async getBankList() {
this.transfer.bankList = (
await getBankList({
operateType: 'bank_type'
})
).content
},
appCallBack(data) {
let title = ''
if (this.issueType === 'TB89') {
title = '国富人寿基本问题件处理'
} else if (this.issueType === '828601') {
title = '国富人寿补充资料问题件处理'
} else {
title = '国富人寿转账不成功问题件处理'
}
let shareObj = {
title: title,
content: '签字进行',
url: `${location.origin}/#/questions/detail/${this.problemDetail.issueId}/${this.problemDetail.issueType}?&token=${localStorage.token}&receiveType=${this.problemDetail.receiveType}&prtNo=${this.$route.query.prtNo}`,
img: this.$assetsUrl + 'images/logo.png'
}
if (data.trigger == 'right_button_click') {
// eslint-disable-next-line no-undef
EWebBridge.webCallAppInJs('bridge', {
flag: 'share',
extra: shareObj
})
}
},
modeChange(mode) {
if (mode !== 1) {
this.showConfirm = true
}
this.transfer.bankCode = ''
this.transfer.bank = ''
this.transfer.card = ''
this.transfer.cardPhoto.splice(0)
this.transfer.cardUploadResult.splice(0)
},
async afterRead(file) {
let data = new FormData()
data.append('imgPath', file.file)
return await uploadImg(data)
},
// 下一步
async submit() {
// 校验回复内容
if (this.issueType === 'TB89') {
let reply = this.newContract.feedback.trim()
if (reply === '') return this.$toast('请填写具体回复信息')
if (reply.length < 4 || reply.length > 400) return this.$toast('请输入4-400个字符')
}
// 校验补充资料
if (this.issueType === '828601') {
if (!this.checkSupplementData()) return this.$toast('请上传补充资料')
this.$toast.loading({
duration: 0
})
this.imageResultList.splice(0)
/**
* 上传补充资料
* 微信端特殊处理:
* 因为微信端签名会跳转页面, 为了签名回跳回显用户填过的信息, 用户填写过的信息都会被保存在localstorage中
* 补充资料图片是以base64格式存储, 所以需要转换为file之后再上传
*/
if (this.isWeixin) {
for (let image of this.imageList) {
let file = this.dataURLtoFile(image.content, '.png')
let res = await this.afterRead({ file: file })
if (res.result === '0') {
let result = {
rgssUrl: res.path,
imageInfoType: 1,
subBusinessType: '0'
}
this.imageResultList.push(result)
} else {
return this.$toast(res.resultMessage)
}
}
} else {
for (let image of this.imageList) {
let res = await this.afterRead({ file: image.file })
if (res.result === '0') {
let result = {
rgssUrl: res.path,
imageInfoType: 1,
subBusinessType: '0'
}
this.imageResultList.push(result)
} else {
return this.$toast(res.resultMessage)
}
}
}
this.$toast.clear()
}
// 转账不成功
if (this.issueType === '818901') {
// 非终止转账
if (this.transfer.mode === 3) {
// 校验开户行
if (!this.transfer.bank) {
return this.$toast('请选择开户银行')
}
// 银行卡号校验
if (this.transfer.card.trim() === '') {
return this.$toast('请填写银行卡信息')
}
let regx = /^(\d{16,19})$/
if (!regx.test(this.transfer.card)) {
return this.$toast('银行卡号不符合规则')
}
if (this.transfer.cardPhoto.length === 0) {
return this.$toast('请上传银行卡照片')
}
}
}
if (!this.checked) {
return this.$toast('请先阅读并勾选协议')
}
// 校验签名
if (this.releationType) {
if (!this.policyholderSigned) return this.$toast('签名未完成, 请先进行签名')
} else {
if (!this.policyholderSigned || !this.insurantSigned) return this.$toast('签名未完成, 请先进行签名')
}
this.phoneNum = this.problemInfo.phoneNo
let phoneStrArr = this.problemInfo.phoneNo.split('')
phoneStrArr.splice(3, 4, '****')
let encryptPhone = phoneStrArr.join('')
// 短信校验
this.dialog = {
type: 'confirm',
show: true,
text: `为确定用户身份,我们将向${encryptPhone}此手机号发送验证码`
}
},
async getMessage({ data }) {
let signInfo = []
if (this.policyholderBase64) signInfo.push(this.policyholderBase64)
if (this.insurantBase64) signInfo.push(this.insurantBase64)
let problemData = {
id: this.$route.params.id,
businessType: this.$route.params.type,
content: '',
disposeStatus: '',
bankType: '',
bankName: '',
bankNo: '',
list: [],
signInfo: signInfo
}
// 验证码验证成功
if (data) {
// 关闭短信弹窗
this.dialog.show = false
// 契约问题件
if (this.issueType === 'TB89') {
problemData.content = this.newContract.feedback
}
// 补充资料类问题件
else if (this.issueType === '828601') {
problemData.list.push(...this.imageResultList)
}
// 转账不成功问题件
else {
problemData.disposeStatus = this.transfer.mode
problemData.bankType = this.transfer.bankCode
problemData.bankName = this.transfer.bank
problemData.bankNo = this.transfer.card
// 选择非终止转账时上传银行卡照片
if (this.transfer.mode === 3) {
problemData.list.push(this.transfer.cardUploadResult)
}
}
// 更新问题件数据
try {
this.$toast.loading({
duration: 0
})
let res = await updateQuestionDetail(problemData)
this.$toast.clear()
if (res.result === '1') {
localStorage.setItem('failedReason', res.resultMessage)
}
this.$jump({
flag: 'h5',
extra: {
url: location.origin + `/#/questions/result/${res.result}`,
forbidSwipeBack: '1'
},
routerInfo: {
path: `/questions/result/${res.result}`
}
})
} catch (reason) {
console.log('网络异常')
}
}
},
async getQuestionDetail() {
const rs = await getQuestionDetail({
id: this.$route.params.id,
prtNo: this.$route.query.prtNo,
userType: Number(this.$route.query.receiveType)
})
if (rs.result === '0') {
// 已处理问题件跳转至列表页
if (rs.content && rs.content.status === '1') {
Dialog({
message: '问题件已被处理',
confirmButtonColor: 'red',
beforeClose: (action, done) => {
done()
this.$jump({
flag: 'h5',
extra: {
url: location.origin + `/#/questions/list`,
forbidSwipeBack: '1'
},
routerInfo: {
path: `/questions/list`
}
})
}
})
return
}
// 是否投被同人
this.releationType = rs.content.releation === '00'
// 包含投保人和被保人证件id和姓名
this.problemInfo = rs.content
this.pdfUrl = encodeURIComponent(config.imgDomain + `/returnDirectStream?imgPath=${this.problemInfo.pdfUrl}`)
this.problemDetail = this.problemInfo.list[0]
// 问题件接收人类型: 0投保人, 1被保人
this.problemDetail.receiveType = this.$route.query.receiveType
} else {
this.$toast(rs.resultMessage)
}
},
// 微信空签
toAirSign(status, keyword, offset, originStatus, personType) {
sessionStorage.removeItem('twoimgBase64Data')
sessionStorage.removeItem('twowxSigned')
localStorage.removeItem('signInfo')
localStorage.setItem('signedPersonType', personType)
localStorage.setItem(
'signInfo',
JSON.stringify({
originStatus: originStatus,
idNo: personType === 0 ? this.problemInfo.appntIdCardNo : this.problemInfo.insuredIdCardNo,
name: personType === 0 ? this.problemInfo.appntName : this.problemInfo.insuredName,
type: '1',
keyword: keyword,
status: status,
offset: offset,
originUrl: location.href + '&fromSign=true'
})
)
window.location.href = this.$mainUrl + '/sign/index.html'
},
dataURLtoFile(dataurl, filename) {
// 将base64转换为文件dataurl为base64字符串filename为文件名必须带后缀名如.jpg,.png
var arr = dataurl.split(','),
mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]),
n = bstr.length,
u8arr = new Uint8Array(n)
while (n--) {
u8arr[n] = bstr.charCodeAt(n)
}
return new File([u8arr], filename, { type: mime })
}
},
async created() {
// 问题件类型
this.issueType = this.$route.params.type
// 根据问题件类型修改标题
if (this.issueType === 'TB89') {
document.title = '新契约基本问题件通知书'
} else if (this.issueType === '818901') {
document.title = '转账不成功问题件'
} else if (this.issueType === '828601') {
document.title = '补充资料通知书'
}
if (this.isWeixin) {
localStorage.setItem('token', this.$route.query.token)
let imgBase64Data = sessionStorage.getItem('twoimgBase64Data')
let signInfo = JSON.parse(localStorage.getItem('signInfo'))
if (this.$route.query.fromSign) {
// 0代表投保人签名
if (Number(localStorage.getItem('signedPersonType')) === 0) {
if (signInfo.status == '0') {
localStorage.setItem('policyholderSignInfo', imgBase64Data)
}
}
// 1代表被保人签名
else {
if (signInfo.status == '0') {
localStorage.setItem('insurantSignInfo', imgBase64Data)
}
}
} else {
// 不是微信签名回调时清空保存的数据
localStorage.removeItem('insurantSignInfo')
localStorage.removeItem('policyholderSignInfo')
localStorage.removeItem('agreementChecked')
localStorage.removeItem('problemReplay')
// 转账不成功类型保存的数据
localStorage.removeItem('resolveType')
localStorage.removeItem('problemBank')
localStorage.removeItem('problemCard')
localStorage.removeItem('problemBankCode')
// 补充资料问题件保存数据
localStorage.removeItem('supplementImages')
}
// localstorage存在投保人签名信息
if (localStorage.getItem('policyholderSignInfo')) {
this.policyholderBase64 = localStorage.getItem('policyholderSignInfo')
this.policyholderSigned = true
}
// localstorage存在被保人签名信息
if (localStorage.getItem('insurantSignInfo')) {
this.insurantBase64 = localStorage.getItem('insurantSignInfo')
this.insurantSigned = true
}
// localstorage存在回复内容时回显回复内容
if (localStorage.getItem('problemReplay')) {
this.newContract.feedback = localStorage.getItem('problemReplay')
}
// 微信签名后回显同意协议
if (localStorage.getItem('agreementChecked') === 'true') {
this.checked = true
}
// 转账不成功问题件
{
// localstorage存在处理类型回显处理类型
if (localStorage.getItem('resolveType')) {
this.transfer.mode = Number(localStorage.getItem('resolveType'))
}
// localstorage存在银行名称回显银行名称
if (localStorage.getItem('problemBank')) {
this.transfer.bank = localStorage.getItem('problemBank')
}
// localstorage存在银行卡号回显银行卡号
if (localStorage.getItem('problemCard')) {
this.transfer.card = localStorage.getItem('problemCard')
}
if (localStorage.getItem('problemBankCode')) {
this.transfer.bankCode = localStorage.getItem('problemBankCode')
}
// 签名回调回显银行卡照片
if (localStorage.getItem('bankcardA')) {
this.transfer.cardPhoto.push({
content: localStorage.getItem('bankcardA')
})
}
}
{
// 微信签名后回显补充资料照片
if (localStorage.getItem('supplementImages')) {
let images = JSON.parse(localStorage.getItem('supplementImages'))
this.imageList.push(...images)
}
}
}
this.getBankList()
this.getQuestionDetail()
},
mounted() {
setTimeout(() => {
// 拦截原生右上角按钮
if (!this.isWeixin) {
window.EWebBridge.webCallAppInJs('webview_right_button', {
btns: [
{
img: this.$assetsUrl + 'images/share@3x.png'
}
]
})
}
}, 1000)
window['appCallBack'] = this.appCallBack
}
}
</script>
<style lang="scss" scoped>
.iframe {
width: 99%;
height: 70vh;
}
.uploadTitle {
font-size: 14px;
margin-bottom: 0.5em;
}
.bottom-btn {
z-index: 1;
}
/deep/ .van-dialog__header {
padding-top: 1em;
}
/deep/ .van-search {
font-size: 10px;
}
#app .van-cell:not(:last-child):after {
border: 0;
}
.detail-container {
min-height: 100vh;
background: #fff;
padding-bottom: 40px;
box-sizing: border-box;
.showDiscern {
position: fixed;
z-index: -1;
left: 0;
top: 0;
width: 100vw;
height: 100vh;
background: rgba(0, 0, 0, 0.5);
opacity: 0;
visibility: hidden;
transition: all 0.3s ease 0.3s;
display: flex;
align-items: flex-end;
justify-content: center;
background: #fff;
&.show {
z-index: 999;
opacity: 1;
visibility: visible;
transition: all 0.3s;
.backContent {
transform: translateY(0);
transition: all 0.3s ease 0.3s;
}
}
.icon {
position: absolute;
right: 10px;
top: 10px;
z-index: 1;
}
.backContent {
transition: all 0.3s;
width: 100%;
transform: translateY(10px);
height: 95%;
background: #fff;
border-radius: 5px;
overflow: hidden;
}
}
.bankList {
height: 300px;
li {
text-align: center;
padding: 10px 0;
font-size: 14px;
border-bottom: 1px solid #eee;
}
}
.pdf {
width: 100vw;
}
.checkedBox {
padding: 10px;
.checked {
font-size: 10px;
color: #666;
line-height: 1.5;
}
}
.update {
margin-bottom: 10px;
.updateInfo {
border-bottom: 1px solid #eee;
.title {
border-bottom: 1px solid #eee;
height: 30px;
line-height: 30px;
font-size: 14px;
padding: 0 10px;
}
.content {
padding: 10px 20px;
.query {
color: #e4393c;
font-size: 13px;
div {
padding-bottom: 2px;
}
p {
line-height: 22px;
}
}
}
}
}
.feedback {
border-bottom: 1px solid #eee;
margin-bottom: 10px;
padding: 0 10px;
.title {
font-size: 14px;
padding: 10px 0;
}
textarea {
font-size: 13px;
border: 0;
width: 100%;
height: 60px;
}
}
.selectList {
.item {
border-bottom: 1px solid #eee;
/deep/.labels {
font-size: 13px;
}
.radioGroup {
display: flex;
justify-content: space-between;
font-size: 13px;
}
.button {
height: 18px;
line-height: 18px;
}
.cardList {
padding: 10px 10px 0;
border-top: 1px solid #eee;
}
}
}
.autograph {
padding: 10px 10px 20px 10px;
font-size: 12px;
.list {
&:first-child {
margin-bottom: 5px;
}
.button {
border-radius: 5px;
height: 18px;
line-height: 18px;
}
}
}
.next {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
height: 40px;
}
}
</style>

View File

@@ -0,0 +1,340 @@
<template>
<div class="question-container">
<div class="header">
<van-search show-action @cancel="searchCancel" v-model="searchValue" placeholder="请输入投保人/被保人/险种名称/问题件类型关键字">
<template #action>
<div @click="searchProblems">搜索</div>
</template>
</van-search>
<!-- <van-tabs v-model="active" @change="changeProblemList">
<van-tab title="待处理"> -->
<van-list
class="vanList"
:immediate-check="false"
v-model="pendingListLoading"
:finished="pendingListFinished"
finished-text="没有更多了"
@load="loadMore"
>
<van-notice-bar wrapable :scrollable="false" text="温馨提示请在收到问题件之日起10日内处理否则系统将逾期自动撤单。" />
<div class="item" v-for="item in pendingList" :key="item.id">
<div class="time">{{ item.createdTime }}</div>
<div class="top">
<div class="col">
<van-tag class="tag" plain type="primary" color="#77bbff">投保</van-tag>
<div class="text">{{ item.prtName }}</div>
</div>
<div class="col">
<van-tag class="tag" plain type="primary" color="#da9887">被保</van-tag>
<div class="text">{{ item.insuredName }}</div>
</div>
<div class="col">
<van-tag class="tag" plain type="primary" color="#95ddd1">主险</van-tag>
<div class="text">{{ item.mainRiskName }}</div>
</div>
<div class="col">
<van-tag class="tag" plain type="primary" color="#ffcc99">类型</van-tag>
<div class="text">{{ item.statusComment }}</div>
</div>
</div>
<div class="bottom">
<div class="list">
<van-tag class="tag" plain color="#77bbff">投保单号</van-tag>
<div class="text">{{ item.prtNo }}</div>
</div>
<div class="list">
<van-tag class="tag" plain>状态</van-tag>
<div class="text">{{ item.status | stateFilter }}</div>
</div>
</div>
<div class="buttons">
<van-button class="button" round type="info" size="small" color="#e4393c" @click="toDetail(item)">去处理</van-button>
</div>
</div>
</van-list>
<!-- </van-tab>
<van-tab title="已处理">
<van-list
class="vanList"
:immediate-check="false"
v-model="processedListLoading"
:finished="processedListFinished"
finished-text="没有更多了"
@load="loadMore"
>
<div class="item" v-for="item in processedList" :key="item.id">
<div class="time">{{ item.createdTime }}</div>
<div class="top">
<div class="col">
<van-tag class="tag" plain type="primary" color="#77bbff">投保</van-tag>
<div class="text">{{ item.prtName }}</div>
</div>
<div class="col">
<van-tag class="tag" plain type="primary" color="#da9887">被保</van-tag>
<div class="text">{{ item.insuredName }}</div>
</div>
<div class="col">
<van-tag class="tag" plain type="primary" color="#95ddd1">主险</van-tag>
<div class="text">{{ item.mainRiskName }}</div>
</div>
<div class="col">
<van-tag class="tag" plain type="primary" color="#ffcc99">类型</van-tag>
<div class="text">{{ item.statusComment }}</div>
</div>
</div>
<div class="bottom">
<div class="list">
<van-tag class="tag" plain type="primary" color="#77bbff">投保单号</van-tag>
<div class="text">{{ item.prtNo }}</div>
</div>
<div class="list">
<van-tag class="tag" plain>状态</van-tag>
<div class="text">{{ item.status | stateFilter }}</div>
</div>
</div>
</div>
</van-list>
</van-tab>
</van-tabs> -->
</div>
</div>
</template>
<script>
import { getQuestionList } from '@/api/ebiz/questions'
import { Sticky, Search, Swipe, SwipeItem, List, Tag, Tabs, Tab, NoticeBar } from 'vant'
export default {
name: 'questionsList',
components: {
[Sticky.name]: Sticky,
[Search.name]: Search,
[Swipe.name]: Swipe,
[SwipeItem.name]: SwipeItem,
[List.name]: List,
[Tag.name]: Tag,
[Tabs.name]: Tabs,
[Tab.name]: Tab,
[NoticeBar.name]: NoticeBar
},
data() {
return {
active: 0,
pendingListLoading: true,
processedListLoading: false,
pendingListFinished: false,
processedListFinished: false,
pendingList: [],
processedList: [],
searchValue: '',
currentPage: 1,
pageSize: 10,
searchCurrentPage: 1
}
},
methods: {
toDetail(item) {
// 保存当前选择的问题件信息
localStorage.setItem('currentProblemItem', JSON.stringify(item))
this.$jump({
flag: 'h5',
extra: {
url: `${window.location.origin}/#/questions/detail/${item.id}/${item.businessType}?receiveType=${item.receiveType}&prtNo=${item.prtNo}`
},
routerInfo: {
path: `/questions/detail/${item.id}/${item.businessType}?receiveType=${item.receiveType}&prtNo=${item.prtNo}`
}
})
},
searchCancel() {
this.searchValue = ''
},
async loadMore() {
try {
const rs = await getQuestionList({
type: this.active,
pageInfo: {
pageNum: this.currentPage,
pageSize: this.pageSize
},
keyword: this.searchValue ? this.searchValue : ''
})
if (rs && rs.result === '0') {
this.currentPage++
if (this.active === 0) {
this.pendingListLoading = false
this.pendingList.push(...rs.content.list)
this.pendingList.reverse()
} else {
this.processedListLoading = false
this.processedList.push(...rs.content.list)
this.processedList.reverse()
}
if (rs.content.pageNum >= rs.content.pages && this.active === 0) {
this.pendingListFinished = true
} else if (rs.content.pageNum >= rs.content.pages && this.active === 1) {
this.processedListFinished = true
}
} else {
this.pendingListFinished = true
this.processedListFinished = true
this.pendingListLoading = false
this.processedListLoading = false
}
} catch (reson) {
this.pendingListLoading = false
this.pendingListFinished = true
this.processedListLoading = false
this.processedListFinished = true
}
},
changeProblemList() {
this.currentPage = 1
this.pendingList.splice(0)
this.processedList.splice(0)
this.pendingListFinished = false
this.processedListFinished = false
this.searchValue = ''
if (this.active === 0) {
this.pendingListLoading = true
} else {
this.processedListLoading = true
}
this.loadMore()
},
async searchProblems() {
// 每次搜索查询第一页
this.currentPage = 1
// 开启loading, 复位finished
if (this.active === 0) {
this.pendingListLoading = true
this.pendingListFinished = false
this.pendingList.splice(0)
} else {
this.processedListLoading = true
this.processedListFinished = false
this.processedList.splice(0)
}
this.loadMore()
},
appCallBack(data) {
if (data.trigger == 'left_button_click') {
this.$jump({
flag: 'service'
})
}
}
},
created() {
setTimeout(() => {
// eslint-disable-next-line no-undef
EWebBridge.webCallAppInJs('webview_left_button', {
// 是否拦截原生返回事件 1是 其他否
intercept: '1'
})
}, 100)
// 筛选按钮的点击事件
window.appCallBack = this.appCallBack
localStorage.removeItem('currentProblemItem')
this.loadMore()
},
filters: {
stateFilter(val) {
switch (val) {
case '0':
case '2':
return '待客户处理问题件'
case '1':
return '待核心处理问题件'
case '3':
return '已线下打印通知书,待客户处理'
case '4':
return '问题件逾期未处理,已撤单'
default:
return ''
}
}
}
}
</script>
<style lang="scss" scoped>
/deep/ .van-field__body {
font-size: 12px;
}
.question-container {
overflow-x: hidden;
.contentList {
box-sizing: border-box;
width: 750px;
display: flex;
transition: all 0.4s;
position: relative;
overflow-y: auto;
.vanList {
width: 375px;
}
}
.alert {
background: rgba(255, 204, 153, 1);
color: #e4393c;
font-size: 12px;
white-space: nowrap;
height: 24px;
line-height: 24px;
}
.item {
padding: 0 20px;
margin-bottom: 10px;
background: #fff;
.time {
text-align: center;
font-size: 12px;
color: #888;
padding: 10px 0;
}
.top {
.col {
display: flex;
align-items: center;
margin-bottom: 0.5em;
font-size: 12px;
line-height: 12px;
.tag {
text-align: center;
margin-right: 1em;
padding: 0.5em 1em;
}
}
}
.bottom {
padding: 0.5em 0;
border-top: 1px solid #efefef;
.list {
display: flex;
align-items: center;
margin-bottom: 0.5em;
.tag {
padding: 0.5em 1.5em;
width: 5em;
text-align: center;
margin-right: 1em;
font-size: 12px;
line-height: 12px;
}
.text {
font-size: 12px;
line-height: 12px;
}
}
}
.buttons {
display: flex;
flex-direction: row-reverse;
padding-bottom: 0.5em;
.button {
width: 83px;
line-height: 22px;
}
}
}
}
</style>

View File

@@ -0,0 +1,103 @@
<template>
<div class="result-container">
<div class="success" v-if="$route.params.result === '0'">
<van-icon name="checked" color="#99CCFF" size="120" />
<p>提交成功</p>
</div>
<div class="fail" v-if="$route.params.result === '1'">
<van-icon name="clear" color="#FF6633" size="120" />
<p>提交失败</p>
<div class="reason">失败原因: {{ reason }}</div>
</div>
<div class="bg-white bottom-btn">
<van-button type="danger" size="large" block @click="goBack">返回</van-button>
</div>
</div>
</template>
<script>
export default {
data() {
return {
reason: ''
}
},
created() {
setTimeout(() => {
// eslint-disable-next-line no-undef
EWebBridge.webCallAppInJs('webview_left_button', {
img: this.$assetsUrl + 'images/del-close-btn@3x.png',
intercept: '1' //是否拦截原生返回事件 1是 其他否
})
}, 100)
// 筛选按钮的点击事件
window.appCallBack = this.appCallBack
if (this.$route.params.result === '1') {
this.reason = localStorage.getItem('failedReason')
}
},
methods: {
appCallBack(data) {
if (data.trigger == 'left_button_click') {
this.$jump({
flag: 'h5',
extra: {
title: '提交结果',
// 当前页面禁止右滑返回
forbidSwipeBack: 1,
url: location.origin + `/#/questions/list`
},
routerInfo: {
path: `/questions/list`
}
})
}
},
goBack() {
this.$jump({
flag: 'h5',
extra: {
title: '电投问题件',
// 当前页面禁止右滑返回
forbidSwipeBack: 1,
url: location.origin + `/#/questions/list`
},
routerInfo: {
path: `/questions/list`
}
})
}
}
}
</script>
<style lang="scss" scoped>
.result-container {
background: #fff;
min-height: 100vh;
padding-top: 150px;
box-sizing: border-box;
& > div {
display: flex;
flex-direction: column;
align-items: center;
p {
padding: 10px;
font-size: 18px;
}
&.success {
p {
color: #99ccff;
}
}
&.fail {
p {
color: #ff6633;
}
.reason {
padding: 0 40px;
text-align: center;
font-size: 14px;
}
}
}
}
</style>

View File

@@ -7,6 +7,9 @@
<van-cell title="投保单号" :value="OrderInfoDTO.orderNo" /> <van-cell title="投保单号" :value="OrderInfoDTO.orderNo" />
<van-cell title="投保日期" :value="OrderInfoDTO.appntDateLabel" /> <van-cell title="投保日期" :value="OrderInfoDTO.appntDateLabel" />
<van-cell title="订单状态" :value="OrderInfoDTO.orderStatus | orderStatusFilter" /> <van-cell title="订单状态" :value="OrderInfoDTO.orderStatus | orderStatusFilter" />
<van-cell v-if="problemList.length" title="问题件状态">
<div v-for="(problem, index) in problemList" :key="index">{{ problem.comment }} - {{ problem.state }}</div>
</van-cell>
<van-cell v-if="reason" title="原因" :value="reason | reasonFilter" /> <van-cell v-if="reason" title="原因" :value="reason | reasonFilter" />
</van-cell-group> </van-cell-group>
</van-collapse-item> </van-collapse-item>
@@ -97,6 +100,7 @@ import { Collapse, CollapseItem, Cell, CellGroup, Button } from 'vant'
import { getDetail } from '@/api/ebiz/sale/sale' import { getDetail } from '@/api/ebiz/sale/sale'
import { formatAllRisk } from '@/assets/js/utils/formatRiskList' import { formatAllRisk } from '@/assets/js/utils/formatRiskList'
import dataDictionary from '@/assets/js/utils/data-dictionary' import dataDictionary from '@/assets/js/utils/data-dictionary'
import { getQuestionList } from '@/api/ebiz/questions'
export default { export default {
data() { data() {
return { return {
@@ -111,14 +115,14 @@ export default {
// 保单号 // 保单号
contNo: '', contNo: '',
list: [], list: [],
reason: '' reason: '',
problemList: []
} }
}, },
created() { created() {
let that = this let that = this
// 获取保单详情 // 获取保单详情
that.getPolicyDetail() that.getPolicyDetail()
// console.log(formatAllRisk)
}, },
components: { components: {
[Collapse.name]: Collapse, [Collapse.name]: Collapse,
@@ -129,23 +133,33 @@ export default {
}, },
methods: { methods: {
// 获取保单详情 // 获取保单详情
getPolicyDetail() { async getPolicyDetail() {
let that = this
let data = { let data = {
orderNo: window.localStorage.getItem('orderNo'), orderNo: window.localStorage.getItem('orderNo'),
desensitizType: this.$route.query.type ? 0 : 1 desensitizType: this.$route.query.type ? 0 : 1
// orderNo: '8186270000000806'
} }
getDetail(data).then(res => { let params = {
console.log(res) type: 3,
pageInfo: {
pageNum: 1,
pageSize: 10
},
prtNo: window.localStorage.getItem('orderNo')
}
try {
let results = await Promise.all([getDetail(data), getQuestionList(params)])
// 保单详情响应数据
let res = results[0]
// // 问题件状态响应数据
let problemResult = results[1]
if (res.result == '0') { if (res.result == '0') {
if (res.orderDTO.orderInfoDTO.bnfFlag == '1') { if (res.orderDTO.orderInfoDTO.bnfFlag == '1') {
res.orderDTO.orderInfoDTO.bnfFlag = '指定受益人' res.orderDTO.orderInfoDTO.bnfFlag = '指定受益人'
} else if (res.orderDTO.orderInfoDTO.bnfFlag == '0') { } else if (res.orderDTO.orderInfoDTO.bnfFlag == '0') {
res.orderDTO.orderInfoDTO.bnfFlag = '法定受益人' res.orderDTO.orderInfoDTO.bnfFlag = '法定受益人'
} }
that.OrderInfoDTO = res.orderDTO.orderInfoDTO this.OrderInfoDTO = res.orderDTO.orderInfoDTO
that.appntDTO = res.orderDTO.appntDTO this.appntDTO = res.orderDTO.appntDTO
this.reason = res.orderDTO.reason this.reason = res.orderDTO.reason
// 投保人信息 // 投保人信息
@@ -329,13 +343,44 @@ export default {
this.list = formatAllRisk(this.insuredDTOs[0].riskDTOLst) this.list = formatAllRisk(this.insuredDTOs[0].riskDTOLst)
} else { } else {
this.$toast(res.resultMessage) this.$toast(res.resultMessage)
// EWebBridge.webCallAppInJs('bridge', {
// flag: 'webview_toast',
// extra: { content: res.resultMessage }
// })
} }
// 问题件状态显示
if (problemResult.result === '0') {
if (problemResult.content && problemResult.content.list) {
this.problemList.splice(0)
let lists = problemResult.content.list
for (let list of lists) {
let state = this.mapOrderState(list.status)
this.problemList.push({
comment: list.statusComment,
state
}) })
} }
}
} else {
this.$toast(problemResult.resultMessage)
}
} catch (error) {
this.$toast('网络异常,')
}
},
mapOrderState(state) {
switch (state) {
case '0':
return '待客户处理'
case '1':
return '待核心处理'
case '2':
return '已打印'
case '3':
return '已回扫'
case '4':
return '逾期关闭'
case '5':
return '已回销'
}
}
}, },
filters: { filters: {
orderStatusFilter(val) { orderStatusFilter(val) {