提交 b31d680a authored 作者: matian's avatar matian

新增证书查询

上级 55eaa6d4
......@@ -27,6 +27,3 @@ export function uploadFile(data) {
headers: { 'Content-Type': 'multipart/form-data' }
})
}
export function getAllSetting() {
return httpRequest.get('/api/register/v1/util/common-map')
}
......@@ -7,5 +7,5 @@ html{
margin: 0 auto;
}
body {
background: #f7f7f7;
background: #fff;
}
import httpRequest from '@/utils/axios'
// 获取用户信息
export function getUser() {
return httpRequest.get('/api/passport/account/get-user-info')
// 获取证书列表
export function getCardList(params) {
return httpRequest.get('api/cert/v1/frontend/index/list', { params })
}
// 获取活动列表
export function getActivityList(params) {
return httpRequest.get('/api/register/v1/activity/list', { params })
// 获取补齐信息
export function getImproveInfo(params) {
return httpRequest.get('api/cert/v1/frontend/index/save', { params })
}
// 获取活动详情
export function getActivityDetail(params) {
return httpRequest.get('/api/register/v1/activity/view', { params })
// 获取证书详情
export function getCardDetail(params) {
return httpRequest.get('api/cert/v1/frontend/index/view', { params })
}
// 保存步骤信息
export function saveStepInfo(data) {
return httpRequest.post('/api/register/v1/activity/step', data)
}
// 保存步骤信息
export function getPayInfo(data) {
return httpRequest.post('/api/register/v1/activity/qr', data)
}
// 支付状态查询
export function getPayStatus(params) {
return httpRequest.get('/api/register/v1/activity/pay-status', { params })
}
// 支付状态查询
export function getOrderList(params) {
return httpRequest.get('/api/register/v1/activity/order', { params })
}
// 提交下线支付
export function uploadPay(data) {
return httpRequest.post('/api/register/v1/activity/upload-pay', data)
}
/**
* 导入
*/
export function importPeople(data) {
return httpRequest({
url: '/api/register/v1/activity/upload-file',
method: 'post',
headers: { 'Content-Type': 'multipart/form-data' },
timeout: 900000,
data,
withCredentials: true
})
}
// 获取openid
export function getOpenid(data) {
return httpRequest.post('/api/usercenter/v2/frontend/wechat/get-openid', data)
}
// 获取openid
export function updateUserInfo(data) {
return httpRequest.post('/api/usercenter/v2/frontend/user/update-user', data)
// 补全信息
export function ImproveInfo(data) {
return httpRequest.post('api/cert//v1/frontend/index/save', data)
}
<template>
<div class="main">
<!-- 111
<a href="https://webapp-pub.ezijing.com/admission/prp/%E6%8A%A5%E5%90%8D%E8%AE%B0%E5%BD%951111.xlsx">下载</a>
<div @click="idShowPopup = true">aaa</div> -->
<van-popup
round
closeable
close-icon-position="top-right"
v-bind="$attrs"
v-on="$listeners"
position="bottom"
:style="{ height: '30%' }"
class="main_upload"
>
<van-uploader
v-model="fileList"
:before-read="handleBeforeRead"
:after-read="handleAfterRead"
accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel"
:max-count="1"
:upload-icon="icon"
>
</van-uploader>
<div class="upload_tips" v-if="!isMobile" @click="down">下载人员模板</div>
<div class="upload_tips" v-else @click="copyToClipboard">ios暂不支持下载 请点“复制”前往浏览器下载</div>
<van-button class="upload_btn" @click="onSubmit">确定</van-button>
</van-popup>
</div>
</template>
<script>
import { Toast, Notify } from 'vant'
import { importPeople } from '../api.js'
export default {
props: {
stepList: { type: Array },
data: { type: Object }
},
data() {
return {
icon: 'https://webapp-pub.oss-cn-beijing.aliyuncs.com/highway/h5/form_add.png',
fileList: [],
fileData: {}
}
},
computed: {
isMobile() {
let flag = false
const u = window.navigator.userAgent
const isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/)
if (isIOS) {
if (navigator.userAgent.indexOf('MicroMessenger') > 0) {
flag = true
}
}
return flag
}
},
methods: {
copyToClipboard() {
const el = document.createElement('textarea')
el.value = `${window.location.origin}/api/register/v1/activity/download-file?activity_detail_id=${this.data.id}`
el.setAttribute('readonly', '')
el.style.position = 'absolute'
el.style.left = '-9999px'
document.body.appendChild(el)
const selected = document.getSelection().rangeCount > 0 ? document.getSelection().getRangeAt(0) : false
el.select()
document.execCommand('copy')
document.body.removeChild(el)
if (selected) {
document.getSelection().removeAllRanges()
document.getSelection().addRange(selected)
}
Notify({ type: 'success', message: '已复制' })
},
down() {
window.location.href = `${window.location.origin}/api/register/v1/activity/download-file?activity_detail_id=${this.data.id}`
},
// 上传前置处理
handleBeforeRead(file) {
if (file.type !== 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') {
Toast('请上传正确的文件格式')
return false
}
return true
},
// 上传文件后的处理
handleAfterRead(file) {
this.fileData = file.file
},
// 提交
onSubmit() {
const params = {
file: this.fileData,
activity_detail_id: this.data.id
}
importPeople(params).then(res => {
this.$emit('upload', res.data)
})
}
}
}
</script>
<style lang="scss" scoped>
.main {
background-color: #f7f7f7;
.main_content {
padding: 0.21rem 0.3rem 4.13rem 0.3rem;
.main_content_banner {
margin-top: 0.84rem;
width: 100%;
}
.main_content_form {
width: 6.9rem;
opacity: 1;
margin-top: 0.32rem;
}
.main_content_form_list {
border-radius: 20px;
margin-top: 0.43rem;
background: #fff;
padding-bottom: 0.68rem;
padding-top: 0.4rem;
.formItemList_item {
.showTime {
cursor: pointer;
}
.showSelectPicker {
cursor: pointer;
}
}
.btn_minus {
float: right;
width: 0.5072rem;
height: 0.5072rem;
margin: 0.3rem 0.3rem 0 0;
cursor: pointer;
}
}
.btn_operate {
margin-top: 0.15rem;
display: flex;
justify-content: flex-end;
align-items: center;
.btn_import {
width: 2.35rem;
height: 0.81rem;
line-height: 0.81rem;
background: rgba(255, 255, 255, 0.39);
box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.09);
border-radius: 0.44rem;
font-size: 0.28rem;
font-weight: 400;
color: #333333;
text-align: center;
}
img {
width: 0.5072rem;
height: 0.5072rem;
}
.btn_add {
cursor: pointer;
margin-left: 0.3rem;
margin-right: 0.31rem;
}
}
}
.main_footer {
width: 100%;
height: 1.81rem;
background: #fff;
position: fixed;
bottom: 0;
display: flex;
justify-content: space-around;
align-items: flex-start;
flex-direction: column;
.main_footer_top {
font-size: 0.24rem;
font-weight: 400;
color: #999999;
margin-left: 0.8rem;
margin-top: 0.15rem;
}
.main_footer_bottom {
margin: -0.18rem auto;
cursor: pointer;
width: 6.9rem;
display: flex;
justify-content: center;
align-items: center;
.main_content_btn {
background: #b80140;
color: #ffffff;
margin-left: 0.28rem;
margin-top: -0.18rem;
}
.main_content_btn1 {
background: #b80140;
color: #ffffff;
margin-left: 0.28rem;
margin-top: 0.3rem;
}
}
}
.main_upload {
display: flex;
justify-content: space-around;
align-items: center;
flex-direction: column;
padding-top: 1rem;
.upload_tips {
color: #b80140;
font-size: 0.2rem;
}
.upload_btn {
border-radius: 3rem;
width: 3rem;
background: #b80140;
color: #ffffff;
}
}
}
::v-deep {
.van-checkbox__icon {
border-radius: 3px;
overflow: hidden;
}
.main_content_banner p img {
width: 6.9rem;
height: 100%;
border-radius: 0.1rem;
}
.van-uploader__upload {
width: 120px;
height: 120px;
}
}
</style>
<template>
<div class="main_header" id="main_header">
<van-nav-bar :title="title" left-arrow @click-left="onClickLeft">
<template #right v-if="center && pathName === '/'">
<div style="display: flex" @click="onClickRight">
<div class="text" style="font-size: 0.24rem; color: #333333; margin-right: 0.05rem">个人中心</div>
<van-icon name="contact" size="18" />
</div>
</template>
</van-nav-bar>
</div>
</template>
......@@ -71,21 +65,29 @@ export default {
</script>
<style lang="scss" scoped>
::v-deep .van-icon-arrow-left {
cursor: pointer;
::v-deep{
.van-icon-arrow-left {
cursor: pointer;
color: #000;
}
::v-deep .van-nav-bar__text {
.van-nav-bar__text {
color: #000;
}
::v-deep .van-icon-contact {
.van-icon-contact {
color: #000;
}
.main_header {
position: fixed;
top: 0;
z-index: 2000;
width: 100%;
.van-nav-bar__content{
box-shadow: 0px 0.02rem 0.06rem 0 rgba(2,17,44,0.05);
}
}
// .main_header {
// position: fixed;
// top: 0;
// z-index: 2000;
// width: 100%;
// height:0.44rem;
// background: #FFFFFF;
// box-shadow: 0px 2px 6px 0px #02112C;
// }
</style>
<template>
<div class="main">
<commonheader @back="handlePrev" :callBack="true" :title="pagesTitle" />
<!-- 展示页面 -->
<div class="main_content">
<div class="show_content">
<div class="show_content_img" v-html="data.desc"></div>
</div>
<div class="main_content_footer" id="main_content_footer">
<div class="show_content_btn" @click="handleSubmit">{{ data.title }}</div>
</div>
</div>
</div>
</template>
<script>
import Commonheader from '../components/Commonheader.vue'
export default {
components: { Commonheader },
props: {
stepList: { type: Array },
data: { type: Object },
pagesTitle: { type: String }
},
mounted() {
if (this.isPc()) {
document.getElementById('main_content_footer').style.width = '400px'
}
},
methods: {
isPc() {
const userAgentInfo = navigator.userAgent
const Agents = ['Android', 'iPhone', 'SymbianOS', 'Windows Phone', 'iPad', 'iPod']
let flagPc = true
for (let v = 0; v < Agents.length; v++) {
if (userAgentInfo.indexOf(Agents[v]) > 0) {
flagPc = false
break
}
}
return flagPc
},
handlePrev() {
this.$emit('prev')
},
async handleSubmit() {
const isLogin = this.$store.state.user.id || (await this.$store.dispatch('checkLogin'))
if (!isLogin) {
const datas = this.stepList.filter(item => item.type === 1)
if (datas[datas.length - 1].num === this.data.num) {
window.location.href = `https://login.ezijing.com/auth/login/index?rd=${window.location.origin}/SignMainPage?id=${this.$route.query.id}`
} else {
this.$emit('next')
}
} else {
if (this.stepList[this.stepList.length - 1].num === this.data.num) {
this.$router.push({ path: '/' })
} else {
this.$emit('next')
}
}
}
}
}
</script>
<style lang="scss" scoped>
.main {
background: #f7f7f7;
.main_content {
// padding: 0.21rem 0.3rem 3.13rem 0.3rem;
.show_content {
// width: 6.9rem;
margin: 0.84rem auto;
.show_content_img {
// width: 6.9rem;
::v-deep {
p {
font-size: 0.24rem;
}
}
}
}
.main_content_footer {
width: 100%;
height: 1.81rem;
background: #fff;
position: fixed;
bottom: 0;
.show_content_btn {
width: 6.42rem;
height: 0.88rem;
background: #b80140;
border-radius: 0.44rem;
font-weight: 500;
color: #ffffff;
font-size: 0.3rem;
text-align: center;
line-height: 0.88rem;
position: fixed;
bottom: 0.4rem;
left: 50%;
transform: translateX(-50%);
cursor: pointer;
}
}
}
}
::v-deep {
.show_content_img p img {
// width: 6.9rem;
// height: 100%;
width: 100%;
margin: 0 auto;
// border-radius: 0.1rem;
}
}
</style>
<template>
<div>
<van-overlay :show="visible">
<div class="wrapper" @click.stop>
<div class="form-box" v-if="visible === true">
<div class="box-top">
<div></div>
<div class="top_tit">补全信息</div>
<img
class="top_close"
src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/project/pages/highway/road/icon_close.png"
alt=""
@click="handleClose"
/>
</div>
<div class="box_bottom">
<div class="bottom_form">
<div v-for="(item, index) in formList" :key="index">
<div class="bottom_label">{{ item.name }}</div>
<input type="text" :placeholder="item.placeholder" v-model="item.value" />
</div>
</div>
<van-button round type="info" class="bottom_submit" @click="handleDealInfo">保存</van-button>
</div>
</div>
</div>
</van-overlay>
</div>
</template>
<script>
import { getImproveInfo, ImproveInfo } from '../api'
import allFormList from '@/utils/formList'
export default {
props: {
visible: {
type: Boolean,
default: false
},
project_id: {
type: String,
default: ''
},
data() {
return {
improveKeyList: [],
improveList: [],
formList: []
}
}
},
methods: {
// 关闭弹窗
handleClose() {
this.formList.map(item => (item.value = ''))
this.$emit('update:visible', false)
},
getInfoList() {
getImproveInfo({ project_id: this.project_id }).then(res => {
this.improveKeyList = res.data.params
const formListNew = []
allFormList.forEach(item => {
this.improveKeyList.forEach(it => {
if (item.key === it) {
formListNew.push(item)
}
})
})
this.formList = formListNew
})
},
handleDealInfo() {
const list = {}
this.improveKeyList.forEach(item => {
const data = this.formList.find(its => its.key === item)
list[data.key] = data.value
})
const params = Object.assign({ project_id: this.project_id }, list)
ImproveInfo(params).then(res => {
this.formList.map(item => (item.value = ''))
this.$emit('update:visible', false)
this.$emit('update')
})
}
},
created() {
this.getInfoList()
}
}
</script>
<style lang="scss" scoped>
.form-box {
width: 6.54rem;
background: #ffffff;
border-radius: 0.32rem;
border: 1px solid #ccc;
position: absolute;
top: 2.44rem;
left: 50%;
transform: translateX(-50%);
.box-top {
padding: 0.26rem 0.24rem 0 0.24rem;
display: flex;
justify-content: space-between;
align-items: center;
.top_tit {
font-size: 0.32rem;
font-weight: 400;
color: #323233;
}
.top_close {
width: 0.32rem;
height: 0.32rem;
}
}
.box_bottom {
margin-top: 0.42rem;
padding: 0 0.4rem 0.3rem 0.4rem;
.bottom_form {
overflow-y: auto;
max-height: 6.48rem;
}
.bottom_label {
font-size: 0.28rem;
font-weight: 400;
color: #696969;
margin-top: 0.32rem;
}
input {
display: block;
margin-top: 0.08rem;
width: 5.74rem;
height: 0.88rem;
line-height: 0.88rem;
background: #f3f7ff;
font-size: 0.32rem;
border-radius: 0.08rem;
border: 0;
&::placeholder {
font-size: 0.32rem;
font-weight: 400;
color: rgba(0, 0, 0, 0.25);
padding: 0.22rem 0 0.22rem 0.32rem;
}
}
.bottom_submit {
width: 5.58rem;
height: 0.72rem;
background: linear-gradient(74deg, #293176 0%, #295fb9 100%);
border-radius: 0.4rem;
}
}
}
</style>
<template>
<div>
<commonheader title="线下支付" />
<div class="offline-box">
<div class="call" v-if="data.offline_info">线下支付联系方式:{{ data.offline_info }}</div>
<div class="remarks" v-if="data.offline_more_info">
<div class="title">线下支付信息:</div>
<div class="centent" v-html="data.offline_more_info"></div>
</div>
<div class="remarks">
<div class="title">备注信息:</div>
<div class="textarea-content">
<textarea placeholder="请输入备注" v-model="form.comment"></textarea>
</div>
</div>
<div class="upload">
<div class="title">上传支付凭证:</div>
<!-- <van-uploader :after-read="afterRead" /> -->
<upload-image @input="input"></upload-image>
</div>
<div class="confim-btn" @click="uploadPay">确认</div>
</div>
</div>
</template>
<script>
import { uploadPay } from '../api.js'
import Commonheader from './Commonheader.vue'
import UploadImage from '@/components/upload/UploadImage.vue'
import { Toast } from 'vant'
export default {
components: {
UploadImage,
Commonheader
},
props: {
data: {
type: Object
},
stepList: {
type: Array
}
},
data() {
return {
form: {
voucher: [],
comment: ''
}
}
},
mounted() {
},
methods: {
input(imgs) {
this.form.voucher = imgs
},
uploadPay() {
const params = {
voucher: JSON.stringify(this.form.voucher),
comment: this.form.comment
}
if (!this.form.voucher.length) {
Toast('请上传凭证')
return false
}
uploadPay(Object.assign(this.data.params, params)).then(res => {
if (this.stepList.length !== this.data.num) {
this.$router.go(0)
} else {
this.$router.push('/')
}
console.log(res)
})
}
}
}
</script>
<style lang="scss" scoped>
.offline-box{
padding: .3rem;
.call{
font-size: .3rem;
line-height: 100%;
font-weight: bold;
color: #333333;
margin-bottom: .4rem;
}
.remarks{
margin-bottom:.4rem;
.centent{
::v-deep{
p{
font-size: .3rem;
img{
width: 100%;
display: block;
}
}
}
}
.title{
font-size: .3rem;
font-weight: bold;
line-height: 100%;
color: #333333;
margin-bottom: .24rem;
}
.textarea-content{
background: rgba(255, 255, 255, 1);
border-radius: .2rem;
padding: .2rem;
height: 3.05rem;
box-sizing: border-box;
textarea{
width: 100%;
height: 100%;
border:none;
background: none;
font-size: .26rem;
resize: none;
}
}
}
.upload{
.title{
font-size: .3rem;
font-weight: bold;
line-height: 100%;
color: #333333;
margin-bottom: .24rem;
}
}
}
.confim-btn{
width: 6.42rem;
height: .88rem;
background: rgba(184, 1, 64, 1);
border-radius: .44rem;
text-align: center;
line-height: .88rem;
color: #fff;
font-size: .3rem;
margin: 2rem auto;
}
</style>
<template>
<van-overlay :show="visible" >
<div class="wrapper" @click.stop>
<div class="form-box" v-if="visible === true">
<div class="box-top">
<div></div>
<div class="top_tit">查询</div>
<img class="top_close" src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/project/pages/highway/road/icon_close.png" alt="" @click="handleClose">
</div>
<div class="box_bottom">
<div class="bottom_form">
<input type="text" placeholder="请输入编号或者手机号查询" v-model="otherInfo" />
</div>
<van-button round type="info" class="bottom_submit" @click="handleDealInfo">查询</van-button>
</div>
</div>
</div>
</van-overlay>
</template>
<script>
export default {
props: {
visible: {
type: Boolean,
default: false
}
},
data() {
return {
otherInfo: ''
}
},
methods: {
handleClose() {
this.$emit('update:visible', false)
},
handleDealInfo() {
this.$router.push({
path: '/list',
query: {
otherInfo: this.otherInfo,
isSelf: '0'
}
})
this.$emit('update:visible', false)
}
}
}
</script>
<style lang="scss" scoped>
.form-box{
width: 6.54rem;
background: #FFFFFF;
border-radius: 0.32rem;
border:1px solid #ccc;
position: absolute;
top:2.44rem;
left: 50%;
transform: translateX(-50%);
.box-top{
padding:0.26rem 0.24rem 0 0.24rem;
display: flex;
justify-content: space-between;
align-items: center;
.top_tit{
font-size: 0.32rem;
font-weight: 400;
color: #323233;
}
.top_close{
width:0.32rem;
height:0.32rem;
}
}
.box_bottom{
margin-top: 0.9rem;
padding:0 0.4rem 0.3rem 0.4rem;
.bottom_label{
font-size: 0.28rem;
font-weight: 400;
color: #696969;
margin-top: 0.32rem;
}
input{
display: block;
margin-top: 0.08rem;
width: 5.74rem;
height: 0.88rem;
line-height: 0.88rem;
background: #F3F7FF;
font-size: 0.32rem;
border-radius: 0.08rem;
border:0;
&::placeholder{
font-size: 0.32rem;
font-weight: 400;
color: rgba(0,0,0,0.25);
padding:0.22rem 0 0.22rem 0.32rem;
}
}
.bottom_submit{
width: 5.58rem;
height: 0.72rem;
background: linear-gradient(74deg, #293176 0%, #295FB9 100%);
border-radius: 0.4rem;
margin-top: 1.06rem;
}
}
}
</style>
<template>
<div class="main">
<commonheader :title="pagesTitle" @back="handleBack" :callBack="true" />
<div class="main_content">
<div class="main_content_banner" v-html="data.desc"></div>
<div class="main_content_form">
<van-form class="main_content_form_con">
<div v-for="(listIt, formIndex) in data.user_fields" :key="formIndex">
<div class="main_content_form_list">
<img
src="https://webapp-pub.ezijing.com/highway/h5/form_minus.png"
class="btn_minus"
@click="handleMinus(formIndex)"
v-if="!isRemoveInfo(listIt)"
/>
<div class="formItemList_item" v-for="(item, index) in listIt" :key="index">
<!-- 输入框 -->
<div v-if="item.type === 'input'">
<van-field
:type="item.inputType"
ref="input"
v-model="item.value"
:name="item.key"
:label="item.name"
:placeholder="item.placeholder"
:rules="[
{ required: item.required, message: item.placeholder, trigger: item.trigger },
{ pattern: item.pattern, message: item.msg, trigger: item.trigger }
]"
clearable
:border="true"
:disabled="!item.enable_edit"
/>
<div class="line"></div>
</div>
<!-- 单选框 -->
<div v-if="item.type === 'radio'">
<van-field :name="item.key" :label="item.name" border>
<template #input>
<van-radio-group v-model="item.value" direction="horizontal">
<div v-for="(it, index) in item.optionList" :key="index">
<van-radio :name="it.id">{{ it.option }}</van-radio>
</div>
</van-radio-group>
</template>
</van-field>
<div class="line"></div>
</div>
<!-- 选择器 -->
<div v-if="item.type === 'select'">
<van-field
border
clickable
:name="item.key"
v-model="item.value"
:label="item.name"
:placeholder="item.placeholder"
@click="showSelectPicker(formIndex, index)"
class="showSelectPicker"
/>
<!-- 选择弹框 -->
<van-popup v-model="item.showPicker" position="bottom">
<van-picker
show-toolbar
:columns="item.optionList"
@confirm="onConfirm"
@cancel="item.showPicker = false"
/>
</van-popup>
<div class="line"></div>
</div>
<!-- 时间 -->
<div v-if="item.type === 'datetime'">
<van-field
border
clickable
:name="item.key"
v-model="item.value"
:label="item.name"
:placeholder="item.placeholder"
@click="showTime(formIndex, index)"
class="showTime"
/>
<!-- 时间弹框 -->
<van-popup v-model="item.showPicker" position="bottom">
<van-datetime-picker
:min-date="minDate"
type="datetime"
@confirm="onConfirmTime"
@cancel="item.showPicker = false"
/>
</van-popup>
<div class="line"></div>
</div>
</div>
</div>
<div style="display: flex" v-if="formIndex === 0">
<div class="btn_operate" style="margin-left: auto">
<div class="batch-import" @click="isbatchImport = true" v-if="data.can_import == 1">批量导入人员</div>
<img src="https://webapp-pub.ezijing.com/highway/h5/form_add.png" class="btn_add" @click="handleAdd" />
</div>
</div>
</div>
</van-form>
</div>
</div>
<div class="main_footer" id="main_footer">
<div class="main_footer_top" v-if="data.can_skip_pay === 1">
<van-checkbox icon-size="13px" v-model="checkedPay" shape="square" class="main_content_skipPay">
{{ data.skip_pay_title }}</van-checkbox
>
</div>
<div class="main_footer_bottom">
<van-button
round
block
native-type="submit"
@click="onSubmit"
:class="[data.can_skip_pay === 1 ? 'main_content_btn' : 'main_content_btn1']"
>{{ data.title }}</van-button
>
</div>
</div>
<batch-import @upload="upload" :data="data" v-model="isbatchImport"></batch-import>
<div class="mobile-pop" v-if="isBindMobile">
<div class="content">
<div class="title">提示</div>
<div class="tips">您的账号未绑定手机号码,请输入绑定手机号</div>
<van-form @submit="bindMobile">
<van-field
style="margin-top: 20px"
v-model="mobile"
name="手机号"
label="手机号"
placeholder="手机号"
:rules="[
{ required: true, message: '请填写手机号' },
{ pattern: /^1(3|4|7|5|8)([0-9]{9})/, message: '请输入正确的手机号' }
]"
/>
<div style="margin: 16px">
<van-button style="border: none; background: #b80140" round block type="info" native-type="submit"
>提交</van-button
>
</div>
</van-form>
</div>
</div>
</div>
</template>
<script>
import { Toast } from 'vant'
import BatchImport from '../components/BatchImport.vue'
import Commonheader from '../components/Commonheader.vue'
import { saveStepInfo, getOpenid, updateUserInfo } from '../api'
import allFormList from '@/utils/formList'
export default {
components: { Commonheader, BatchImport },
props: {
stepList: { type: Array },
data: { type: Object },
pagesTitle: { type: String }
},
data() {
return {
mobile: '',
isbatchImport: false,
title: '报名',
checkedPay: false, // 勾选是否跳过按钮
index: 0,
cIndex: 0,
minDate: new Date(),
isBindMobile: false
}
},
mounted() {
const userInfo = JSON.parse(window.localStorage.userInfo)
if (userInfo.mobile === '') {
this.isBindMobile = true
}
if (this.isPc()) {
document.getElementById('main_footer').style.width = '400px'
}
},
methods: {
bindMobile() {
updateUserInfo({ mobile: this.mobile }).then(res => {
console.log(res, 'res')
if (res.code === 0) {
const userInfo = JSON.parse(window.localStorage.userInfo)
this.data.user_fields.map(item => {
const d = item.find(i => i.value === userInfo.nickname)
if (d) {
item.map(i => {
if (i.key === 'mobile') {
i.value = this.mobile
i.enable_edit = false
}
return i
})
}
return item
})
this.isBindMobile = false
} else {
Toast(res.msg)
}
})
},
isPc() {
const userAgentInfo = navigator.userAgent
const Agents = ['Android', 'iPhone', 'SymbianOS', 'Windows Phone', 'iPad', 'iPod']
let flagPc = true
for (let v = 0; v < Agents.length; v++) {
if (userAgentInfo.indexOf(Agents[v]) > 0) {
flagPc = false
break
}
}
return flagPc
},
handleBack() {
this.$emit('prev')
},
// 批量上传
upload(data) {
const arr = []
// 回显信息
data.forEach((item, index) => {
arr.push([])
Object.keys(item).forEach(cItem => {
const fd = allFormList.find(f => f.key === cItem)
const clone = Object.assign({}, fd)
clone.value = item[cItem]
cItem === 'gender' ? (clone.value = item[cItem].toString()) : (clone.value = item[cItem])
fd && arr[index].push(Object.assign({}, clone))
})
})
this.data.user_fields = [...this.data.user_fields, ...arr]
this.isbatchImport = false
},
isRemoveInfo(item) {
return !!item.find(f => f.enable_edit === false)
},
// 微信授权
wxAuthorize(call) {
if (!this.$route.query.code) {
const url = encodeURIComponent(window.location.href)
window.location.href = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxa41d0081d4889921&redirect_uri=${url}&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect`
} else {
getOpenid({ code: this.$route.query.code, identity: 'road' }).then(res => {
call(res)
})
}
},
// 提交
onSubmit() {
const params = {
activity_id: this.data.activityInfo.id,
activity_detail_id: this.data.id,
need_skip: this.checkedPay ? 1 : 0
}
if (this.data.join_rand) {
params.join_rand = this.data.join_rand
}
params.users_info = this.data.user_fields.reduce((a, b) => {
const infos = {}
b.forEach(item => {
infos[item.key] = item.value
})
a.push(infos)
return a
}, [])
// 表单提交company_id
params.users_info.forEach(item => {
if (item.company) {
const companyData =
this.$store.state.allSettings.company_map || JSON.parse(window.localStorage.allSetting).company_map
const findData = companyData.find(name => name.company_name === item.company)
if (findData) {
item.company_id = findData.id
}
}
})
let flag = false
params.users_info.forEach(item => {
if (item.check_in_time && item.check_out_time) {
if (item.check_in_time >= item.check_out_time) {
Toast('入住时间要早于离店时间')
flag = true
return false
}
}
})
if (flag) {
return false
} else {
saveStepInfo(params).then(res => {
if (res.code === 0) {
this.data.join_rand = res.data.join_rand
if (this.checkedPay) {
this.stepList.splice(this.stepList.findIndex(i => i.num === this.data.num) + 1, 1)
if (this.stepList[this.stepList.length - 1].num === this.data.num) {
// 完成步骤跳转
this.$router.push({ path: '/' })
} else {
// 是微信才走授权
if (/MicroMessenger/.test(window.navigator.userAgent)) {
if (!window.localStorage.openId) {
this.wxAuthorize(resId => {
window.localStorage.openId = resId.openid
this.$emit('next', res.data)
})
} else {
this.$emit('next', res.data)
}
} else {
this.$emit('next', res.data)
}
}
} else {
if (this.stepList[this.stepList.length - 1].num === this.data.num) {
// 完成步骤跳转
this.$router.push({ path: '/' })
} else {
// 是微信才走授权
if (/MicroMessenger/.test(window.navigator.userAgent)) {
if (!window.localStorage.openId) {
this.wxAuthorize(resId => {
window.localStorage.openId = resId.openid
this.$emit('next', res.data)
})
} else {
this.$emit('next', res.data)
}
} else {
this.$emit('next', res.data)
}
}
}
this.checkedPay = false
}
})
}
},
// 表单项减少
handleMinus(index) {
this.data.user_fields.splice(index, 1)
},
// 表单项增加
handleAdd() {
const baseUserFields = this.data.user_fields[0].map(item => {
const copyItem = Object.assign({}, item)
copyItem.value = ''
copyItem.enable_edit = true
return copyItem
})
this.data.user_fields.splice(1, 0, baseUserFields)
},
// 点击确定选择时间
onConfirmTime(time) {
this.data.user_fields[this.index][this.cIndex].value = this.bgDate(time)
this.data.user_fields[this.index][this.cIndex].showPicker = false
},
// 日期格式化
bgDate(val) {
const d = new Date(val)
const date = `${d.getFullYear()}-${this.toDo(d.getMonth() + 1)}-${this.toDo(d.getDate())} ${this.toDo(
d.getHours()
)}:${this.toDo(d.getMinutes())}:${this.toDo(d.getSeconds())}`
return date
},
// 时间格式化 时分秒变两位数
toDo(n) {
return n < 10 ? `0${n}` : n
},
// 时间弹窗
showTime(index, cIndex) {
this.data.user_fields[index][cIndex].showPicker = true
this.index = index
this.cIndex = cIndex
},
// 选择弹窗
showSelectPicker(index, cIndex) {
this.data.user_fields[index][cIndex].showPicker = true
this.index = index
this.cIndex = cIndex
},
// 点击确定选择项
onConfirm(value) {
this.data.user_fields[this.index][this.cIndex].value = value
this.data.user_fields[this.index][this.cIndex].showPicker = false
}
}
}
</script>
<style lang="scss" scoped>
.main {
background-color: #f7f7f7;
.main_content {
padding: 0.21rem 0.3rem 4.13rem 0.3rem;
.main_content_banner {
margin-top: 0.84rem;
width: 100%;
::v-deep {
p {
font-size: 0.24rem;
}
}
}
.main_content_form {
width: 6.9rem;
opacity: 1;
// margin-top: 0.32rem;
margin: 0.32rem auto;
}
.main_content_form_list {
border-radius: 20px;
margin-top: 0.43rem;
background: #fff;
padding-bottom: 0.68rem;
padding-top: 0.4rem;
.formItemList_item {
.showTime {
cursor: pointer;
}
.showSelectPicker {
cursor: pointer;
}
}
.btn_minus {
float: right;
width: 0.5072rem;
height: 0.5072rem;
margin: 0.3rem 0.3rem 0 0;
cursor: pointer;
}
}
.btn_operate {
padding-top: 0.3rem;
// float: right;
display: flex;
align-items: center;
img {
width: 0.5072rem;
height: 0.5072rem;
}
.btn_add {
cursor: pointer;
margin-left: 0.3rem;
margin-right: 0.31rem;
}
.batch-import {
padding: 0 0.33rem;
height: 0.81rem;
background: rgba(255, 255, 255, 0.39);
box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.09);
border-radius: 0.44rem;
color: #333;
line-height: 0.81rem;
font-size: 0.28rem;
}
}
}
.main_footer {
width: 100%;
height: 1.81rem;
background: #fff;
position: fixed;
bottom: 0;
display: flex;
justify-content: space-around;
align-items: flex-start;
flex-direction: column;
.main_footer_top {
font-size: 0.24rem;
font-weight: 400;
color: #999999;
margin-left: 0.8rem;
margin-top: 0.15rem;
}
.main_footer_bottom {
margin: -0.18rem auto;
cursor: pointer;
.main_content_btn {
width: 6.9rem;
background: #b80140;
color: #ffffff;
margin-left: 0.28rem;
margin-top: -0.18rem;
}
.main_content_btn1 {
width: 6.9rem;
background: #b80140;
color: #ffffff;
margin-left: 0.28rem;
margin-top: 0.3rem;
}
}
}
}
::v-deep {
.van-checkbox__icon {
border-radius: 3px;
overflow: hidden;
}
.main_content_banner p img {
width: 100%;
border-radius: 0.1rem;
}
}
.mobile-pop {
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
background: rgba(0, 0, 0, 0.5);
z-index: 2001;
.content {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 90%;
// height: 210px;
padding-bottom: 10px;
background: #fff;
border-radius: 10px;
text-align: center;
.title {
font-size: 0.34rem;
text-align: center;
color: #333;
padding: 0.2rem;
}
.tips {
font-size: 0.24rem;
padding-left: 0.2rem;
}
input {
width: 100%;
font-size: 0.24rem;
}
}
}
</style>
......@@ -4,35 +4,13 @@ const routes = [
path: '/',
component: () => import('./views/Index.vue')
},
// 个人中心
{
path: '/PersonalCenter',
component: () => import('./views/PersonalCenter.vue')
},
// 我的订单
{
path: '/MyOrder',
component: () => import('./views/MyOrder.vue')
},
// 购物车
{
path: '/OrderConfirm',
component: () => import('./views/OrderConfirm.vue')
},
// 报名页面
{
path: '/SignMainPage',
component: () => import('./views/SignMainPage.vue')
},
// 订单支付
{
path: '/PayDetail',
component: () => import('./views/PayDetail.vue')
},
// 订单支付
{
path: '/list',
component: () => import('./views/List.vue')
},
{
path: '/detail',
component: () => import('./views/Detail.vue')
}
]
......
<template>
<div class="main">
<CommonHeader :title="title" :center="false" />
<div class="main_content">
<div class="content_top">
<img class="info_card" :src="form.url" />
</div>
<div class="content_bottom" v-if="$route.query.isSelf === '1'">
<van-field v-model="form.name" label="姓名" input-align="right" disabled />
<van-field v-model="form.mobile" label="电话" input-align="right" disabled />
<van-field v-model="form.email" label="邮箱" input-align="right" disabled /><van-field
v-model="form.number"
label="编号"
input-align="right"
disabled
/>
<van-field v-model="form.updated_time" label="发证时间" input-align="right" disabled />
</div>
</div>
</div>
</template>
<script>
import { getCardDetail } from '../api'
import CommonHeader from '../components/CommonHeader.vue'
export default {
components: { CommonHeader },
props: {
isSelf: {
type: String,
default: ''
}
},
data() {
return {
form: {
url: '',
name: '',
mobile: '',
email: '',
number: '',
updated_time: '111',
popupVisible: false
}
}
},
methods: {
handleCardDetail() {
const params = {
project_id: this.$route.query.project_id,
student_id: this.$route.query.student_id
}
getCardDetail(params).then(res => {
Object.keys(this.form).forEach(key => {
this.form[key] = res.data[key]
})
})
}
},
mounted() {
this.handleCardDetail()
}
}
</script>
<style lang="scss" scoped>
.main_content {
// padding-top:0.48rem;
.content_top {
width: 7.5rem;
background: #f3f7ff;
.info_card {
width: 6.86rem;
padding: 0.32rem;
}
}
}
::v-deep {
.van-field__label {
font-size: 0.32rem;
font-weight: 400;
color: #212121;
}
.van-field__control {
font-size: 0.28rem;
font-weight: 400;
color: #696969;
}
}
</style>
<template>
<div class="main">
<!-- 头部标题 -->
<commonheader :title="title" />
<div>
<CommonHeader :title="title" :center="false" />
<div class="main_content">
<!-- banner卡片 -->
<img class="main_content_banner" src="https://webapp-pub.ezijing.com/highway/h5/banner-0420.png" alt="" />
<!-- 动态 -->
<div class="main_content_dt">
<div class="main_content_dt_tit">中国公路建设行业协会</div>
<ul class="main-content">
<li v-for="(item, index) in navList" :key="index" @click="handleNav(item)">
<img :src="item.icon" />
<div class="text">{{ item.text }}</div>
</li>
</ul>
</div>
<div class="border-line"></div>
<!-- 会议 -->
<div class="main_content_activity">
<div class="main_content_activity_tit">其他培训交流</div>
<!-- 活动列表 -->
<div
class="main_content_activity_list"
v-for="(item, index) in activityList"
:key="index"
@click="handleSignCheck(item)"
<img class="info_no" src="https://webapp-pub.ezijing.com/project/pages/highway/road/info_no.png" />
<van-button
round
icon="https://webapp-pub.ezijing.com/project/pages/highway/road/icon_other.png"
class="info_btn info_btn1"
@click="handleQueryOther"
>查他人</van-button
>
<van-button
round
icon="https://webapp-pub.ezijing.com/project/pages/highway/road/icon_self.png"
class="info_btn info_btn2"
@click="handleQuerySelf"
>查自己</van-button
>
<div>
<div class="activity_list_top">
<div class="activity_list_top_tit">{{ item.name }}</div>
<van-icon name="arrow" size="14" />
</div>
</div>
</div>
</div>
<!-- <van-pagination
v-model="currentPage"
:total-items="this.total"
:items-per-page="2"
style="margin-top: 10px"
@change="handleChangePage"
force-ellipses
/> -->
</div>
<QueryOther v-if="popupVisible === true" :visible.sync="popupVisible" :isSelf="'0'" />
</div>
</template>
<script>
import { Toast, Dialog } from 'vant'
import { getActivityList, getActivityDetail } from '../api'
import Commonheader from '../components/Commonheader.vue'
import CommonHeader from '../components/CommonHeader.vue'
import QueryOther from '../components/QueryOther.vue'
export default {
components: { Commonheader },
components: { CommonHeader, QueryOther },
data() {
return {
total: '',
currentPage: 1,
title: '首页',
ismySign: true,
isOtherSign: true,
activityList: [], // 活动列表
detailList: {}, // 活动详情
navList: [
{
icon: 'https://webapp-pub.ezijing.com/highway/h5/nav-icon1.png',
text: '培训动态',
url: 'https://pages.ezijing.com/prp/mobile2140014905177.html',
query: {
title: '培训动态',
type: 'b4'
}
},
{
icon: 'https://webapp-pub.ezijing.com/highway/h5/nav-icon2.png',
text: '公益讲堂',
path: 'list',
query: {
title: '公益讲堂',
type: 'b2'
popupVisible: false
}
},
{
icon: 'https://webapp-pub.ezijing.com/highway/h5/nav-icon3.png',
text: '宣贯培训',
path: 'list',
query: {
title: '宣贯培训',
type: 'b3'
}
},
{
icon: 'https://webapp-pub.ezijing.com/highway/h5/nav-icon4.png',
text: '安全培训',
path: '',
query: {
title: '安全培训',
type: 'b4'
}
}
]
created() {
const isLogin = this.$store.state.user.id || this.$store.dispatch('checkLogin')
if (!isLogin) {
window.location.href = `${import.meta.env.VITE_LOGIN_URL}?rd=${encodeURIComponent(window.location.href)}`
}
},
methods: {
handleNav(item) {
if (item.url) {
window.location.href = item.url
} else {
if (item.path) {
handleQuerySelf() {
this.$router.push({
path: '/list',
query: item.query
})
} else {
Toast('暂未开通')
}
}
},
// 点击分页
handleChangePage(val) {
this.currentPage = val
this.getActivityList()
// this.activityList = val
},
// 首页返回按钮
onClickLeft() {},
// 右侧按钮 个人中心
onClickRight() {
this.$router.push('/PersonalCenter')
},
// 获取活动列表
getActivityList() {
const params = {
page: this.currentPage,
'per-page': '50'
}
getActivityList(params).then(res => {
this.activityList = res.data.list
this.total = res.data.total
})
},
// 报名
async handleSignCheck(item) {
// 未登录
this.getActivityDetail(item)
// const isLogin = this.$store.state.user.id || (await this.$store.dispatch('checkLogin'))
// if (!isLogin) {
// this.$router.push({
// path: '/SignMainPage',
// query: {
// stepIndex: 0,
// isLogin: true,
// loginId: item.id
// }
// })
// } else {
// this.getActivityDetail(item)
// }
},
// 获取活动详情
getActivityDetail(item) {
const params = { id: item.id }
getActivityDetail(params).then(res => {
this.detailList = res.data
const isCanJump = this.detailList.activity.details.find(i => i.can_jump === 1)
this.handleSign(item, isCanJump)
})
},
handleSign(item, canJump) {
const time = new Date().getTime()
const startTime = new Date(item.start_time.replace(/-/g, '/')).getTime()
const endTime = new Date(item.end_time.replace(/-/g, '/')).getTime()
if (time >= startTime && time < endTime) {
if (this.detailList.self_fill_in === null && this.detailList.other_fill_in === null) {
this.$router.push({
path: '/SignMainPage',
query: {
id: item.id
}
})
} else {
if (this.detailList.other_fill_in?.need_fill_in_status) {
// 有需要填写的步骤
Dialog.confirm({
title: '提示',
message: '还有报名流程未交费',
confirmButtonText: '继续报名',
cancelButtonText:
this.detailList.self_fill_in.need_fill_in_status === false ? (canJump ? '开始学习' : '') : '',
closeOnClickOverlay: true,
beforeClose: (action, done) => {
if (action === 'overlay') {
window.location.href = window.location.origin
} else {
done(true)
}
isSelf: '1'
}
})
.then(() => {
this.$router.push({
path: '/SignMainPage',
query: {
id: item.id
}
})
})
.catch(() => {
if (canJump) {
window.location.href = canJump.jump_url
}
})
// 没有需要填写的步骤
} else if (!this.detailList.other_fill_in?.need_fill_in_status) {
if (this.detailList.self_fill_in?.need_fill_in_status) {
this.$router.push({
path: '/SignMainPage',
query: {
id: item.id
}
})
} else {
Dialog.confirm({
title: '提示',
message: '',
confirmButtonText: '重新报名',
cancelButtonText: canJump ? '开始学习' : '',
closeOnClickOverlay: true,
beforeClose: (action, done) => {
if (action === 'overlay') {
window.location.href = window.location.origin
} else {
done(true)
}
}
})
.then(() => {
this.$router.push({
path: '/SignMainPage',
query: {
id: item.id
}
})
})
.catch(() => {
if (canJump) {
window.location.href = canJump.jump_url
}
})
}
}
}
} else if (time >= endTime) {
Toast(`该活动将于${item.end_time}结束报名`)
} else if (time < startTime) {
Toast(`该活动将于${item.start_time}开始报名`)
}
}
},
mounted() {
// 获取活动列表
this.getActivityList()
handleQueryOther() {
this.popupVisible = true
}
}
}
</script>
<style lang="scss" scoped>
.main {
background-color: #f7f7f7;
.main_content {
margin-top: 0.46rem;
padding: 0 0.3rem 0.3rem 0.3rem;
.main_content_banner {
margin-top: 1rem;
width: 100%;
height: 2.97rem;
border-radius: 0.1rem;
}
.main_content_dt {
margin: 0.3rem 0 0.4rem 0;
.main_content_dt_tit {
font-size: 0.3rem;
font-weight: 500;
color: #333333;
}
.main_content_dt_con {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 0.3rem;
.dt_con_card2 {
background: url('https://webapp-pub.oss-cn-beijing.aliyuncs.com/highway/h5/dt_bg.png') no-repeat center;
}
.dt_con_card1 {
background: url('https://webapp-pub.oss-cn-beijing.aliyuncs.com/highway/h5/dt_bg1.png') no-repeat center;
}
.dt_con_card {
width: 3.3rem;
height: 2.01rem;
background-color: #c104;
border-radius: 0.15rem;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
background-size: contain;
.dt_con_card_img {
width: 0.8rem;
height: 0.8rem;
}
.dt_con_card_tit {
font-size: 0.28rem;
font-weight: 400;
color: #ffffff;
margin-top: 0.21rem;
}
}
}
}
.main_content_activity {
.main_content_activity_tit {
font-size: 0.3rem;
font-weight: 500;
color: #333333;
}
.main_content_activity_list {
box-sizing: border-box;
padding: 0.2rem 0.25rem 0.2rem 0.3rem;
width: 100%;
// height: 1.12rem;
.main_content {
padding: 1.52rem 1.34rem 0 1.36rem;
display: flex;
// align-items: center;
justify-content: center;
flex-direction: column;
background-color: #fff;
border-radius: 0.2rem;
margin-top: 0.24rem;
div {
cursor: pointer;
}
.activity_list_top {
display: flex;
justify-content: space-between;
align-items: center;
.activity_list_top_tit {
// width: 3.2rem;
font-size: 0.28rem;
.info_no {
width: 4.8rem;
height: 3.2rem;
}
.info_btn {
width: 5.58rem;
height: 1.44rem;
border-radius: 0.96rem;
}
.info_btn1 {
background: linear-gradient(74deg, #eaeeff 0%, #f5f9ff 100%);
margin-top: 1.12rem;
.van-button__text {
font-size: 0.4rem;
font-weight: 400;
color: #333333;
// overflow: hidden;
// text-overflow: ellipsis;
// -o-text-overflow: ellipsis;
// -webkit-text-overflow: ellipsis;
// -moz-text-overflow: ellipsis;
// white-space: nowrap;
}
.activity_list_top_date {
font-size: 0.22rem;
font-weight: 400;
color: #999999;
margin-left: 1rem;
}
}
.activity_list_bottom {
display: flex;
justify-content: flex-end;
align-items: center;
color: #295fb9;
}
}
.info_btn2 {
background: linear-gradient(240deg, #ffffff 0%, #fde6cf 100%);
margin-top: 0.64rem;
.van-button__text {
font-size: 0.4rem;
font-weight: 400;
color: #be6d23;
}
}
}
.main-content {
display: flex;
justify-content: space-between;
padding: 0 0.2rem;
padding-top: 0.25rem;
li {
img {
width: 1.2rem;
display: block;
}
.text {
font-size: 0.24rem;
line-height: 100%;
color: #4e4e4e;
text-align: center;
}
::v-deep {
.van-icon__image {
width: 0.64rem;
height: 0.64rem;
}
}
.border-line {
width: 6.2rem;
margin: 0 auto 0.35rem;
border-bottom: 0.01rem dashed rgba(196, 196, 196, 1);
}
::v-deep .van-icon-arrow {
margin-top: 0.05rem;
}
</style>
<template>
<div>
<commonheader :title="title" :center="false" />
<div class="list-box">
<div
class="main_content_activity_list"
v-for="(item, index) in activityList"
:key="index"
>
<div>
<div class="activity_list_top">
<div class="activity_list_top_tit" v-html="item.name"></div>
<!-- <div class="activity_list_top_date">{{ item.activity_time.split(' ')[0] }}</div> -->
<van-icon name="arrow" size="14" />
<CommonHeader :title="title" :center="false" />
<div class="main_content" v-if="isShowList === true">
<div v-if="cardList.length > 0">
<div class="main_content_list" v-for="(item, index) in cardList" :key="index" @click="handleDetail(item)">
<img class="list_img" :src="item.url" />
<div class="list_right">
<div class="title">证书名称</div>
<div class="desc">
<div class="desc_time">{{ item.updated_time }}</div>
<div class="desc_name">{{ item.name }}</div>
<div class="desc_num">{{ item.number }}</div>
</div>
</div>
</div>
</div>
<!-- <div class="activity_list_bottom">
<van-icon name="arrow" size="14" />
</div> -->
<div class="main_content1" v-else>
<img class="info_no" src="https://webapp-pub.ezijing.com/project/pages/highway/road/info_no.png" />
<div class="info_desc">暂未查询到相关证书</div>
</div>
</div>
<div class="main_content1" v-else>
<img class="info_no" src="https://webapp-pub.ezijing.com/project/pages/highway/road/info_no.png" />
<div class="info_desc">请补全信息查询证书</div>
<van-button round type="info" class="info_btn" @click="handleDealInfo">去补全</van-button>
</div>
<ImproveInfo
v-if="project_id !== ''"
:project_id="project_id"
:visible.sync="popupVisible"
@update="handleGetCardList"
/>
</div>
</template>
<script>
import Commonheader from '../components/Commonheader.vue'
import { getCardList } from '../api'
import ImproveInfo from '../components/ImproveInfo.vue'
import CommonHeader from '../components/CommonHeader.vue'
export default {
components: { Commonheader },
components: { ImproveInfo, CommonHeader },
data() {
return {
title: this.$route.query.title,
activityLists: {
b1: [
{ name: '11', url: '11' }
],
b2: [
{ name: '心里课程”有效亲子沟通“', url: '' }
],
b3: [
{ name: '关于举办第二期全国公路平安百年品质工程<br/>攻关行动系列成果培训的通知', url: '' }
// { name: '', url: '' }
popupVisible: false,
isShowList: true,
cardList: [
{
updated_time: '',
name: '',
time: '',
number: ''
}
],
b4: []
improveList: [],
project_id: ''
}
},
methods: {
// 完善信息弹窗
handleDealInfo() {
this.popupVisible = true
},
// 跳转详情页面
handleDetail(item) {
this.$router.push({
path: '/detail',
query: {
student_id: item.student_id,
project_id: item.project_id,
isSelf: this.$route.query.isSelf
}
})
},
computed: {
activityList() {
return this.activityLists[this.$route.query.type || 'b3']
// 获取证书列表
handleGetCardList() {
const params = {
key: this.$route.query.otherInfo,
page_size: '1000',
page: '1'
}
getCardList(params).then(res => {
this.cardList = res.data.list
this.improveList = res.data.list.filter(item => item.need_save === true)
if (this.improveList.length > 0) {
this.isShowList = false
this.project_id = this.improveList[0].project_id
}
})
}
},
created() {
// 判断是否登录
const isLogin = this.$store.state.user.id || this.$store.dispatch('checkLogin')
if (!isLogin) {
window.location.href = `${import.meta.env.VITE_LOGIN_URL}?rd=${encodeURIComponent(window.location.href)}`
} else {
this.handleGetCardList()
}
}
}
</script>
<style lang="scss" scoped>
.list-box{
padding: 1rem .3rem 0;
}
.main_content_activity_list {
box-sizing: border-box;
padding: .2rem 0.25rem 0.2rem 0.3rem;
width: 100%;
// height: 1.12rem;
display: flex;
// align-items: center;
justify-content: center;
flex-direction: column;
background-color: #fff;
border-radius: 0.2rem;
margin-top: 0.24rem;
div {
cursor: pointer;
}
.activity_list_top {
.main_content {
padding: 0.48rem 0.32rem 0.32rem 0.32rem;
.main_content_list {
display: flex;
justify-content: space-between;
align-items: center;
.activity_list_top_tit {
width: 5.8rem;
font-size: 0.28rem;
border-bottom: 0.02rem solid #f0f0f0;
padding-bottom: 0.32rem;
.list_img {
width: 2.4rem;
height: 1.8rem;
}
.list_right {
margin-left: 0.24rem;
.title {
width: 1.28rem;
font-size: 0.32rem;
font-weight: 400;
color: #333333;
overflow: hidden;
text-overflow: ellipsis;
-o-text-overflow: ellipsis;
-webkit-text-overflow: ellipsis;
-moz-text-overflow: ellipsis;
white-space: nowrap;
}
.activity_list_top_date {
font-size: 0.22rem;
color: #212121;
}
.desc {
margin-top: 0.16rem;
font-size: 0.24rem;
font-weight: 400;
color: #999999;
margin-left: 1rem;
}
}
.activity_list_bottom {
display: flex;
justify-content: flex-end;
align-items: center;
}
}
.main_content1 {
padding: 2.8rem 1.34rem 0 1.36rem;
.info_no {
width: 4.8rem;
height: 3.2rem;
}
.info_desc {
font-size: 0.28rem;
font-weight: 400;
color: #999999;
text-align: center;
}
.info_btn {
width: 3.66rem;
height: 0.72rem;
background: linear-gradient(74deg, #293176 0%, #295fb9 100%);
border-radius: 40px;
margin-left: 0.56rem;
}
}
</style>
<template>
<div class="main">
<commonheader :title="title" @back="handleBack" :callBack="true" :center="false" />
<div class="main_content">
<!-- 头部tab -->
<van-tabs v-model="active" animated sticky>
<van-tab v-for="(it, index) in orderTab" :key="index" :title="it.title">
<div v-if="getDataByType(it.type).length" class="main_content_ticket">
<a href="https://account-show.ezijing.com/h5/payment" style="margin-left: auto">
<van-button round icon="https://webapp-pub.oss-cn-beijing.aliyuncs.com/highway/h5/ticket.png">
开发票
</van-button>
</a>
</div>
<!-- 订单列表 -->
<div v-if="getDataByType(it.type).length" class="main_content_orderList">
<div class="orderList" v-for="(item, index) in getDataByType(it.type)" :key="index">
<div class="orderList_status">{{ payStatus[item.status] }}</div>
<div class="orderList_con">
<div class="orderList_con_left">
<div class="orderList_con_left_tit">{{ item.activity.name }}</div>
<div class="orderList_con_left_num">人数:{{ item.count }}</div>
</div>
<div class="orderList_con_price" v-html="getTotalPrice(item)"></div>
</div>
<div class="orderList_pay">
<div class="orderList_pay_tit">需付款:</div>
<div class="orderList_pay_price" v-html="getTotalPrice(item)"></div>
</div>
<div class="orderList_btn">
<van-button
round
size="small"
style="margin-left: 0.42rem"
v-if="item.status === 0 || item.status === 1"
@click="handlePay(item)"
class="pay_btn"
>查看</van-button
>
</div>
</div>
</div>
<van-empty v-else description="暂无订单" class="main_content_empty" />
</van-tab>
</van-tabs>
</div>
</div>
</template>
<script>
import { getOrderList } from '../api'
import Commonheader from '../components/Commonheader.vue'
export default {
components: { Commonheader },
data() {
return {
title: '我的订单',
active: 0,
payStatus: {
0: '未完成',
1: '部分缴费',
2: '已完成'
},
orderTab: [
{ title: '全部', type: 'all' },
{ title: '未完成', type: 'hasNopay' },
// { title: '部分缴费', type: 'partPay' },
{ title: '已完成', type: 'isFinished' }
],
orderList: []
}
},
mounted() {
this.getOrderList()
if (this.isPc()) {
document.getElementsByClassName('van-sticky')[0].style.width = '400px'
}
},
methods: {
isPc() {
const userAgentInfo = navigator.userAgent
const Agents = ['Android', 'iPhone', 'SymbianOS', 'Windows Phone', 'iPad', 'iPod']
let flagPc = true
for (let v = 0; v < Agents.length; v++) {
if (userAgentInfo.indexOf(Agents[v]) > 0) {
flagPc = false
break
}
}
return flagPc
},
handleBack() {
this.$router.push('/')
},
getTotalPrice(item) {
const splitPrice = item.amount.toFixed(2).split('.')
// //2.重新赋值
return `¥ <span style="font-size:0.34rem;"> ${splitPrice[0]}</span>.<span style="font-size:0.2rem;">${splitPrice[1]}</span>`
},
getOrderList() {
getOrderList().then(res => {
this.orderList = res.data.map(item => {
const listItem = item.list[0]
if (listItem) {
const findItem = item.activity.details.find(i => i.id === listItem.pay_record.activity_detail_id)
item.activity.name = `${item.activity.name}-${findItem.title}`
}
return item
})
})
},
getDataByType(type) {
if (type === 'all') {
return this.orderList
} else if (type === 'hasNopay') {
return this.orderList.filter(item => item.status === 0)
} else if (type === 'partPay') {
return this.orderList.filter(item => item.status === 1)
} else if (type === 'isFinished') {
return this.orderList.filter(item => item.status === 2)
}
},
handlePay(item) {
const payRecord = item.list[0].pay_record
const stepDetails = item.activity.details.find(d => d.id === payRecord.activity_detail_id)
stepDetails.list = item.list
.map((list, index) => {
list.mobile === JSON.parse(window.localStorage.userInfo).mobile ? (list.index = 0) : (list.index = index + 1)
return list
})
.sort((a, b) => a.index - b.index)
stepDetails.pay_price = item.activity.details.find(
id => id.id === item.list[0].pay_record.activity_detail_id
).pay_price
delete item.activity.details
stepDetails.activityInfo = item.activity
stepDetails.join_rand = item.join_rand
window.localStorage.orderStepDetails = JSON.stringify([stepDetails])
this.$router.push({
path: '/SignMainPage'
})
}
}
}
</script>
<style lang="scss" scoped>
.main {
background-color: #f7f7f7;
.main_content {
height: 100%;
margin-top: 0.9rem;
.main_content_ticket {
padding-right: 0.3rem;
// float: right;
display: flex;
margin-bottom: 0.3rem;
margin-top: 0.8rem;
}
.main_content_orderList {
.orderList {
margin: 0.3rem auto;
padding: 0.3rem 0.2rem 0.3rem 0.34rem;
width: 6.9rem;
height: 3.62rem;
background: #fff;
opacity: 1;
border-radius: 0.18rem;
display: flex;
align-items: flex-end;
flex-direction: column;
box-sizing: border-box;
.orderList_status {
font-size: 0.26rem;
font-weight: 400;
line-height: 0.28rem;
color: #c01540;
}
.orderList_con {
width: 100%;
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-top: 0.31rem;
.orderList_con_left {
font-size: 0.28rem;
font-weight: 500;
color: #333333;
.orderList_con_left_tit {
width: 2.52rem;
font-size: 0.28rem;
font-weight: 500;
color: #333333;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.orderList_con_left_num {
font-size: 0.24rem;
font-weight: 400;
color: #9b9b9b;
opacity: 1;
}
}
.orderList_con_price {
font-size: 0.2rem;
font-weight: 400;
color: #333333;
}
}
.orderList_pay {
display: flex;
align-items: center;
margin-top: 0.42rem;
.orderList_pay_tit {
font-size: 0.28rem;
font-weight: 500;
color: #333333;
}
.orderList_pay_price {
font-size: 0.2rem;
font-weight: bold;
color: #333333;
}
}
.orderList_btn {
display: flex;
margin-top: 0.34rem;
cursor: pointer;
}
}
}
.main_content_empty {
margin: 2rem 1rem;
}
}
}
::v-deep .van-sticky {
width: 100%;
position: fixed;
z-index: 1000;
left: 50% !important;
transform: translateX(-50%) !important;
top: 0.8rem;
}
::v-deep .pay_btn {
border-radius: 0.31rem;
border: 1px solid #c01540;
cursor: pointer;
color: #c01540;
font-size: 0.28rem;
}
</style>
<template>
<div class="main">
<div class="order-confirm" v-if="!isQrPageShow">
<!-- 头部标题 -->
<commonheader @back="handlePrev" :callBack="true" :title="title" />
<div class="main_content">
<div class="main_content_list">
<van-checkbox-group v-model="selctOrderData" ref="checkboxGroup">
<div class="main_content_list_card" v-for="(item, index) in data.payData.list" :key="index">
<div class="card_header">
<van-checkbox
@click="checkItem"
:name="item"
v-if="['0', '3'].includes(item.pay_record.pay_status)"
></van-checkbox>
<div v-else class="van-checkbox van-checkbox--disabled">
<div class="van-checkbox__icon van-checkbox__icon--round van-checkbox__icon--disabled">
<i class="van-icon van-icon-success"><!----></i>
</div>
</div>
<div class="card_con">
<p>{{ item.name }} {{ item.mobile }}</p>
</div>
<div :class="item.pay_record.pay_status === '1' ? 'pay-stu yzf' : 'pay-stu'">
{{ getPayStatusValue(item.pay_record.pay_status) }}
</div>
</div>
<div class="card_fotter">
<div class="card_fotter_left">
<span class="price">¥</span>
<span class="price_num" v-html="getPayPrice()"></span>
</div>
<div class="card_fotter_left card_fotter_right" v-if="data.can_company">
<span class="price">单位已优惠</span>
<span class="price">¥</span>
<span class="price_num" v-html="getCompanyPrice(item)"></span>
</div>
</div>
</div>
</van-checkbox-group>
<div class="pay-mode">
<div class="title">选择支付方式</div>
<div class="pay-list">
<van-radio-group v-model="payMode">
<div v-for="(item, index) in data.pay_type" :key="index">
<div class="item" v-if="item == 1">
<img src="https://webapp-pub.ezijing.com/highway/h5/pay-wx.png" class="icon1" />
<div class="text">微信支付</div>
<van-radio name="1" class="checkbox"></van-radio>
</div>
<div class="item" v-if="item == 2">
<img src="https://webapp-pub.ezijing.com/highway/h5/pay-zfb.png" class="icon2" />
<div class="text">支付宝支付</div>
<van-radio name="2" class="checkbox"></van-radio>
</div>
<div class="item" v-if="item == 3">
<img src="https://webapp-pub.ezijing.com/highway/h5/pay-xx.png" class="icon3" />
<div class="text">线下支付</div>
<van-radio name="3" class="checkbox"></van-radio>
</div>
</div>
</van-radio-group>
</div>
</div>
</div>
</div>
<!-- <div class="pay-mode">
<div class="title">选择支付方式</div>
</div> -->
<div class="main_footer" id="main_footer">
<van-checkbox
v-model="isAll"
:disabled="!data.payData.list.filter(item => ['0', '3'].includes(item.pay_record.pay_status)).length"
@click="checkAll"
class="checkAll"
>全选</van-checkbox
>
<div class="main_footer_total">
<div class="main_footer_total_top"></div>
<div class="main_footer_total_top">
<div class="total_text">合计:</div>
<div class="total_sign">¥</div>
<div class="price" v-html="getTotalPrice()"></div>
</div>
<div class="main_footer_total_bottom" v-if="data.can_company">
<div class="company_yh">共优惠</div>
<div class="company_sign">¥</div>
<div class="company_yh" v-html="totalCompanyPrice"></div>
</div>
</div>
<van-button round @click="handlePrev" class="prev_btn">上一页</van-button>
<van-button round :disabled="!selctOrderData.length" @click="onSubmit" class="pay_btn">去支付</van-button>
</div>
</div>
<div v-else>
<template v-if="payMode != 3">
<pay-detail
v-if="Object.keys(payDetail).length"
@next="$emit('next')"
:stepList="stepList"
:data="payDetail"
></pay-detail>
</template>
<offline-pay v-else :stepList="stepList" :data="data"></offline-pay>
</div>
</div>
</template>
<script>
import { getPayInfo, getOpenid } from '../api'
import PayDetail from './PayDetail.vue'
import Commonheader from '../components/Commonheader.vue'
import OfflinePay from '../components/OfflinePay.vue'
export default {
components: { Commonheader, PayDetail, OfflinePay },
props: {
stepList: {
type: Array
},
data: {
type: Object
}
},
data() {
return {
payMode: '3',
isQrPageShow: this.$route.query.qr || false,
title: '订单确认',
isAll: false,
numVsible: true,
payDetail: {},
selctOrderData: [], // 选中的数据
stepOrderInfo: [],
payType: [],
// 判断是否是支付宝
isAlipay: /AlipayClient/.test(window.navigator.userAgent),
// 判断微信
isWx: /MicroMessenger/.test(window.navigator.userAgent)
}
},
computed: {
// 合计价格
totalPrice() {
return this.selctOrderData
.map(item => Number(item.pay_record.pay_amount))
.reduce((pre, nex) => (pre += nex), 0)
.toFixed(2)
},
// 支付金额 每个的实付价
payPrice() {
return this.data.payData.pay_price
},
// 共优惠价格
totalCompanyPrice() {
return this.selctOrderData
.map(item =>
Number(this.payPrice) - Number(item.pay_record.pay_amount) < 0
? 0
: Number(this.payPrice) - Number(item.pay_record.pay_amount)
)
.reduce((pre, nex) => (pre += nex), 0)
.toFixed(2)
}
},
created() {
// if (this.$route.query.qr !== undefined) {
// this.payDetail = JSON.parse(window.localStorage.payDetail)
// }
},
mounted() {
if (this.isPc()) {
document.getElementById('main_footer').style.width = '400px'
}
this.payMode = this.data.pay_type[0]
},
methods: {
isPc() {
const userAgentInfo = navigator.userAgent
const Agents = ['Android', 'iPhone', 'SymbianOS', 'Windows Phone', 'iPad', 'iPod']
let flagPc = true
for (let v = 0; v < Agents.length; v++) {
if (userAgentInfo.indexOf(Agents[v]) > 0) {
flagPc = false
break
}
}
return flagPc
},
getPayStatusValue(n) {
const value = {
0: '未支付',
1: '已支付',
2: '待审核',
3: '驳回'
}
return value[parseInt(n)]
},
// 共优惠价格样式
getTotalTotalCompanyPrice() {
const splitPrice = this.totalCompanyPrice.split('.')
// //2.重新赋值
return `<span style="font-size:0.34rem;">${splitPrice[0]}</span>.<span style="font-size:0.2rem;">${splitPrice[1]}</span>`
},
// 总共价格样式
getTotalPrice() {
const splitPrice = this.totalPrice.split('.')
// //2.重新赋值
return `<span style="font-size:0.34rem;">${splitPrice[0]}</span>.<span style="font-size:0.2rem;">${splitPrice[1]}</span>`
},
// 实付价样式
getPayPrice() {
const splitPrice = this.payPrice.toString().split('.')
// //2.重新赋值
return `<span style="font-size:0.34rem;">${splitPrice[0]}</span>.<span style="font-size:0.2rem;">${splitPrice[1]}</span>`
},
// 优惠价格样式
getCompanyPrice(item) {
const companyPrice = (Number(this.payPrice).toFixed(2) - Number(item.pay_record.pay_amount).toFixed(2)).toFixed(2)
const splitPrice = companyPrice < 0 ? '0.00'.split('.') : companyPrice.split('.')
// //2.重新赋值
return `<span style="font-size:0.34rem;">${splitPrice[0]}</span>.<span style="font-size:0.2rem;">${splitPrice[1]}</span>`
},
checkItem() {
const x = this.data.payData.list.filter(item => ['0', '3'].includes(item.pay_record.pay_status))
if (this.selctOrderData.length === x.length) {
this.isAll = true
} else {
this.isAll = false
}
},
// 返回
handlePrev() {
this.$emit('prev')
},
// 全选
checkAll() {
if (!this.isAll) {
this.selctOrderData = []
} else {
this.data.payData.list.forEach(item => {
if (['0', '3'].includes(item.pay_record.pay_status)) {
const findD = this.selctOrderData.find(d => d.id === item.id)
if (!findD) {
this.selctOrderData.push(item)
}
}
})
}
},
// 提交 去支付
onSubmit() {
this.getPayDetail()
},
// 微信授权
wxAuthorize(call) {
if (!this.$route.query.code) {
const url = encodeURIComponent(window.location.href)
console.log(url)
window.location.href = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxa41d0081d4889921&redirect_uri=${url}&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect`
} else {
getOpenid({ code: this.$route.query.code, identity: 'road' }).then(res => {
call(res)
})
}
},
getPayDetail() {
// 选择微信和支付宝支付走这
if (this.payMode !== '3') {
// const ua = window.navigator.userAgent.toLowerCase()
// 写到这了,本地保存了支付还有页面的信息。此信息用于支付回调渲染页面使用
const params = {
pay_record_ids: this.selctOrderData.map(item => item.pay_record.id).toString(),
join_rand: this.data.payData.join_rand,
pay_type: parseInt(this.payMode) === 1 ? '1' : '11'
}
// 支付宝环境支付
if (this.isAlipay && parseInt(this.payMode) === 2) {
params.pay_type = '12'
const url =
window.location.href.indexOf('?') === -1
? `${encodeURIComponent(window.location.href)}?qr=1`
: `${encodeURIComponent(window.location.href)}&qr=1`
params.redirect_url =
window.location.href.indexOf('qr') !== -1 ? encodeURIComponent(window.location.href) : url
console.log(params, 'par')
this.getPayInfo(params)
} else if (this.isWx && parseInt(this.payMode) === 1) {
// 微信环境支付
params.pay_type = '3'
// 没有openid去授权获取
if (!window.localStorage.openId) {
this.wxAuthorize(res => {
params.openid = res.openid
window.localStorage.openId = res.openid
this.getPayInfo(params)
})
} else {
params.openid = window.localStorage.openId
this.getPayInfo(params)
}
} else {
this.getPayInfo(params)
}
} else {
// 线下支付
this.data.params = {
pay_record_ids: this.selctOrderData.map(item => item.pay_record.id).toString(),
join_rand: this.data.payData.join_rand
}
this.isQrPageShow = true
}
},
getPayInfo(params) {
// 获取支付二维码 订单id
getPayInfo(params).then(res => {
this.data.payMode = this.payMode
if (res.code === 0) {
this.payDetail = Object.assign({ qrData: res.data }, this.data)
this.payDetail.order_id = res.data.order_id
window.localStorage.payDetail = JSON.stringify(this.payDetail)
// 支付宝
if (this.isAlipay && parseInt(this.payMode) === 2) {
window.location.href = res.data.url
} else if (this.isWx && parseInt(this.payMode) === 1) {
// 拉起微信支付
window.WeixinJSBridge.invoke('getBrandWCPayRequest', JSON.parse(res.data.more_info), res => {})
}
this.isQrPageShow = true
}
if (res.code === 100) {
if (this.stepList.length === this.data.num) {
this.$router.push('/')
} else {
this.$emit('next')
}
}
// 订单为0元时,判断该步骤后面是否有步骤,若有就去下一步骤,否则返回首页
if (res.code === 999) {
this.stepList.length === this.data.num ? this.$router.push('/') : this.$emit('next')
}
})
}
}
}
</script>
<style lang="scss" scoped>
.main {
background-color: #f7f7f7;
.main_content {
padding: 0.51rem 0.3rem 0.3rem 0.3rem;
margin-top: 0.9rem;
.main_content_list {
padding-bottom: 1.2rem;
.main_content_list_card {
height: 2.16rem;
background: #fff;
opacity: 1;
border-radius: 0.18rem;
display: flex;
flex-direction: column;
justify-content: space-around;
padding: 0 0.3rem;
margin-bottom: 0.3rem;
.card_header {
display: flex;
align-items: flex-start;
.card_header_title {
width: 2.88rem;
font-size: 0.32rem;
font-weight: 500;
color: #333333;
margin-left: 0.3rem;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.pay-stu {
font-size: 0.24rem;
color: #b80140;
margin-left: auto;
&.yzf {
color: #999999;
}
}
}
.card_con {
font-weight: 400;
color: #999999;
margin-left: 0.33rem;
font-size: 0.24rem;
}
.card_fotter {
display: flex;
justify-content: flex-start;
align-items: center;
margin-left: 0.7rem;
.card_fotter_left {
display: flex;
align-items: center;
justify-items: center;
.price {
font-size: 0.2rem;
color: #b80140;
font-weight: 300;
margin-top: 0.1rem;
}
.price_num {
font-size: 0.28rem;
font-weight: bold;
color: #b80140;
}
}
.card_fotter_right {
margin-left: 0.07rem;
background-color: #f8edf1;
}
}
}
}
}
.main_footer {
width: 100%;
height: 1.48rem;
background: #fff;
position: fixed;
bottom: 0;
display: flex;
justify-content: space-around;
align-items: center;
.checkAll {
cursor: pointer;
}
.main_footer_total {
// background: #000;
// width: 1.7rem;
height: 0.8rem;
display: flex;
flex-direction: column;
justify-content: center;
align-items: flex-start;
.main_footer_total_top {
display: flex;
align-items: flex-end;
.total_text {
font-size: 0.24rem;
font-weight: 400;
color: #333333;
padding-top: 0.11rem;
}
.total_sign {
font-size: 0.2rem;
color: #b80140;
margin-top: 0.18rem;
margin-left: 0.1rem;
}
.price {
font-size: 0.2rem;
font-weight: bold;
color: #b80140;
margin-left: 0.1rem;
margin-top: 0.11rem;
}
}
.main_footer_total_bottom {
display: flex;
align-items: flex-end;
.company_yh {
font-size: 0.24rem;
font-weight: 400;
color: #b80140;
}
.company_sign {
font-size: 0.2rem;
color: #b80140;
}
}
}
.prev_btn {
cursor: pointer;
background: #f5f5f5;
font-size: 0.3rem;
font-weight: 500;
color: #333333;
}
.pay_btn {
background: #b80140;
font-size: 0.3rem;
font-weight: 500;
color: #ffffff;
cursor: pointer;
}
}
}
::v-deep .van-checkbox__label {
font-size: 0.28rem;
font-weight: 400;
color: #999999;
}
.pay-mode {
.title {
font-size: 0.28rem;
line-height: 100%;
color: #666666;
padding-bottom: 0.3rem;
}
.pay-list {
background: rgba(255, 255, 255);
border-radius: 0.18rem;
padding-bottom: 0.38rem;
.item {
display: flex;
align-items: center;
padding-top: 0.38rem;
// mar-borrom
.icon1 {
width: 0.48rem;
margin-left: 0.3rem;
display: block;
}
.icon2 {
width: 0.48rem;
margin-left: 0.3rem;
display: block;
}
.icon3 {
width: 0.46rem;
margin-left: 0.3rem;
display: block;
}
.text {
margin-left: 0.29rem;
font-size: 0.28rem;
color: #333333;
}
.checkbox {
margin-left: auto;
margin-right: 29px;
}
}
}
}
</style>
<template>
<div class="main">
<commonheader :title="title" />
<div class="main_content">
<div class="main_content_desc">{{ getPayText }}</div>
<div class="main_content_qdCode" v-if="isCodeShow">
<qrcode-vue :value="payDetail.url" size="180" ref="qrcode" />
</div>
<div class="main_btn">
<van-button class="main_btn_home" round @click="$router.push('/')" v-if="isLastStep && status == 1"
>首页</van-button
>
<van-button round class="main_btn_home" @click="$router.go(0)" v-if="!isLastStep && status == 1"
>继续报名</van-button
>
<!-- <van-button round class="main_btn_order" @click="repayments" v-if="$route.query.qr && status != 1">重新支付</van-button> -->
<van-button round class="main_btn_order" @click="$router.push('/MyOrder')">我的订单</van-button>
</div>
<div id="value">{{ payDetail.url }}</div>
</div>
</div>
</template>
<script>
import QrcodeVue from 'qrcode.vue'
import { getPayStatus } from '../api'
import commonheader from '../components/Commonheader.vue'
export default {
props: {
data: {
type: Object
},
stepList: {
type: Array
}
},
components: {
QrcodeVue,
commonheader
},
data() {
return {
isLastStep: false, // 判断是不是最后一个步骤 显示不同的按钮
title: '订单支付',
qrcodeUrl: '',
clipboard: null,
status: '', // 支付状态
time: null,
detailList: {},
activity_detail_id: '',
lastStepId: '',
initData: {}
}
},
computed: {
isCodeShow() {
let flag = true
if (parseInt(this.data.payMode) === 1 && /MicroMessenger/.test(window.navigator.userAgent)) {
flag = false
}
if (parseInt(this.data.payMode) === 2 && /AlipayClient/.test(window.navigator.userAgent)) {
flag = false
}
return flag
},
getPayText() {
let text = ''
if (parseInt(this.data.payMode) === 1) {
/MicroMessenger/.test(window.navigator.userAgent) ? text = '微信支付' : text = '微信扫码支付'
}
if (parseInt(this.data.payMode) === 2) {
/AlipayClient/.test(window.navigator.userAgent) ? text = '支付宝支付' : text = '打开支付宝扫码二维码支付,或长按保存二维码打开支付宝支付。'
}
return text
},
isAlipay() {
return /AlipayClient/.test(window.navigator.userAgent)
},
payDetail() {
return this.data.qrData
},
pay_record_ids() {
return this.data.activity_detail_id
}
},
methods: {
repayments() {
window.location.href = window.localStorage.payUrl
},
// 获取二维码
getQrcodeUrl() {
this.qrcodeUrl = this.$refs.qrcode.$el
.querySelector('canvas')
.toDataURL('image/png')
.replace('image/png', 'image/octet-stream')
},
// 获取支付状态
getPayStatus() {
this.getActivityDetail()
const params = {
order_id: this.data.order_id
}
getPayStatus(params).then(res => {
if (res.code === 0) {
this.status = res.data.status
if (res.data.status === 1) {
clearInterval(this.time)
if (this.data.jump_url) {
window.location.href = this.data.jump_url
return false
} else {
this.getActivityDetail()
}
}
}
})
},
// 获取活动详情
getActivityDetail() {
if (this.stepList.length === this.data.num) {
this.isLastStep = true
}
},
continueSign() {
this.$router.push({
path: 'SignMainPage',
query: {
activityId: this.$route.query.activityId
}
})
}
},
destroyed() {
clearInterval(this.time)
},
mounted() {
clearInterval(this.time)
this.time = setInterval(() => {
this.getPayStatus()
}, 5000)
if (this.isCodeShow) {
this.getQrcodeUrl()
}
}
}
</script>
<style lang="scss" scoped>
.main {
background: #f7f7f7;
.main_content {
background: #fff;
display: flex;
align-items: center;
flex-direction: column;
margin: 1.2rem 0.3rem 0.64rem 0.3rem;
border-radius: 0.2rem;
.main_content_desc {
font-size: 0.3rem;
font-weight: 400;
color: #333333;
margin-top: 0.57rem;
margin: 0.57rem 0.3rem 0 0.3rem;
}
.main_content_qdCode {
width: 2.88rem;
height: 2.84rem;
padding: 0.78rem 1.64rem 0 1.34rem;
}
// .main_content_link {
// font-size: 0.3rem;
// font-weight: 400;
// color: #333333;
// margin-top: 1.99rem;
// .link {
// color: #b80140;
// .link_img {
// width: 0.3017rem;
// height: 0.3rem;
// }
// }
// }
.main_btn {
margin-top: 1.12rem;
margin-bottom: 0.64rem;
display: flex;
justify-content: center;
.main_btn_home {
cursor: pointer;
background: #b80140;
color: #fff;
font-size: 0.3rem;
font-weight: 400;
}
.main_btn_order {
cursor: pointer;
margin-left: 0.2rem;
background: #f5f5f5;
font-size: 0.3rem;
font-weight: 400;
color: #333333;
}
}
#value {
font-size: 0.3rem;
opacity: 0;
}
}
}
</style>
<template>
<div class="main">
<!-- 头部标题 -->
<commonheader :title="title" />
<!-- 我的订单 -->
<div class="main_content">
<div class="main_content_order" @click="handleOrder">
<div class="main_content_order_text">我的订单</div>
<van-icon name="arrow" size="14" />
</div>
<div class="main_content_footer" @click="handleLogout">退出登录</div>
</div>
</div>
</template>
<script>
import Commonheader from '../components/Commonheader.vue'
export default {
components: { Commonheader },
data() {
return {
title: '个人中心'
}
},
methods: {
handleOrder() {
this.$router.push({
path: '/myOrder'
})
},
handleLogout() {
window.location.href = `${import.meta.env.VITE_LOGIN_URL}?rd=${encodeURIComponent(window.location.origin)}`
}
}
}
</script>
<style lang="scss" scoped>
.main {
.main_content {
margin-top: 0.46rem;
padding: 0.51rem 0.3rem 0 0.3rem;
background-color: #f7f7f7;
.main_content_order {
cursor: pointer;
width: 6.9rem;
height: 0.7rem;
background: #fff;
opacity: 1;
border-radius: 0.2rem;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 0.25rem 0 0.3rem;
box-sizing: border-box;
margin: 0.21rem auto;
.main_content_order_text {
font-size: 0.28rem;
font-weight: 400;
color: #333333;
opacity: 1;
}
}
.main_content_footer {
width: 6.9rem;
height: 0.88rem;
background: #fff;
border-radius: 0.2rem;
font-size: 0.3rem;
font-weight: 500;
color: #333333;
line-height: 0.88rem;
text-align: center;
position: fixed;
left: 50%;
transform: translateX(-50%);
bottom: 4.37rem;
cursor: pointer;
}
}
}
</style>
<template>
<div class="main">
<!-- <commonheader @back="handlePrev" :callBack="true" /> -->
<!-- 展示 -->
<template v-if="Object.keys(stepList).length">
<img-show
:stepList="stepList"
:data="setpItem"
:pagesTitle="pagesTitle"
@prev="handlePrev"
@next="handleNext"
v-if="setpItem.type === 1"
/>
<!-- 表单 -->
<sign-form
:data="setpItem"
:stepList="stepList"
:pagesTitle="pagesTitle"
@prev="handlePrev"
@next="handleNext"
v-if="setpItem.type === 2 && stepList.length"
/>
<!-- 支付页面 -->
<order-confirm
@prev="handlePrev"
@next="handleNext"
:stepList="stepList"
:data="setpItem"
v-if="setpItem.type === 3 && stepList.length"
></order-confirm>
</template>
</div>
</template>
<script>
import { Dialog } from 'vant'
import allFormList from '@/utils/formList'
import SignForm from '../components/SignForm.vue'
import ImgShow from '../components/ImgShow.vue'
import OrderConfirm from './OrderConfirm.vue'
import { getActivityDetail } from '../api'
export default {
components: { SignForm, ImgShow, OrderConfirm },
data() {
return {
userMobile: '',
title: '报名主页面',
stepIndex: 0,
isShowSkip: '',
stepList: [],
detailList: {
info: {}
},
pagesTitle: ''
}
},
computed: {
setpItem() {
return this.stepList[this.stepIndex]
}
},
mounted() {
if (this.$route.query.qr === undefined) {
if (this.$route.query.id) {
this.getActivityDetail()
} else {
console.log(JSON.parse(window.localStorage.orderStepDetails), '12322')
this.setData(JSON.parse(window.localStorage.orderStepDetails))
}
} else {
const data = JSON.parse(window.localStorage.stepData)
this.stepList = data.stepList
this.stepIndex = data.index
}
},
methods: {
// 获取活动详情
getActivityDetail() {
getActivityDetail({ id: this.$route.query.id }).then(res => {
const data = res.data
// 页面标题
this.pagesTitle = res.data.activity.title || ''
// 复制链接进入活动时,判断活动报名时间弹窗
const time = new Date().getTime()
const startTime = new Date(data.activity.start_time.replace(/-/g, '/')).getTime()
const endTime = new Date(data.activity.end_time.replace(/-/g, '/')).getTime()
if (startTime > time || endTime < time) {
Dialog.alert({
title: '提示',
message: `该活动将于${data.activity.start_time}开始报名`
}).then(() => {
this.$router.push('/')
})
} else if (endTime < time) {
Dialog.alert({
title: '提示',
message: `该活动将于${data.activity.end_time}结束报名`
}).then(() => {
this.$router.push('/')
})
}
let sliceData = []
if (data.other_fill_in?.need_fill_in_status) {
initInfo('other_fill_in')
} else if (data.self_fill_in?.need_fill_in_status) {
initInfo('self_fill_in')
} else {
initInfo()
}
// 初始化拿到数据做的第一步处理:取到需要展示出来的所有页面
function initInfo(fields) {
const activityData = JSON.parse(JSON.stringify(Object.assign({}, data.activity)))
if (fields) {
// *** 继续报名数 || 第一次进报名,据初始化
const index = activityData.details.findIndex(item => item.id === data[fields].need_fill_in_id)
sliceData = activityData.details.slice(index, activityData.details.length)
// list 人员信息
sliceData.map(item => {
const addData = JSON.parse(JSON.stringify(Object.assign({}, data.activity)))
item.activityInfo = addData
// 判断有没有返回人员 没返回吧自己的信息push进去
if (data[fields].list.length) {
// list有可能不会返回自己的信息,不返回push进去
// const findOwn = data[fields].list.find(info => info.mobile === data.info.mobile)
// if (!findOwn) {
// data[fields].list.push(data.info)
// }
item.list = data[fields].list
// 处理list数据
item.list.map((ci, index) => {
const fItem = ci.pay_records.find(cif => cif.activity_detail_id === item.id)
if (fItem) {
item.join_rand = fItem.join_rand
}
// 添加index用于用户排序
ci.mobile === data.info.mobile ? (ci.index = 0) : (ci.index = index + 1)
return item
})
return item
} else {
item.list = []
item.list.push(data.info)
}
return item
})
} else {
// 重新报名初始化数据
sliceData = activityData.details
sliceData.map(item => {
item.list = []
item.activityInfo = Object.assign({}, data.activity)
data.info !== null && item.list.push(data.info)
return item
})
}
}
// 第二步数据处理:字段细节处理
this.setData(sliceData)
})
},
setData(data) {
this.userMobile = window.localStorage.userInfo ? JSON.parse(window.localStorage.userInfo).mobile : ''
// 处理数据
this.stepList = data.reduce((a, b) => {
// type: 1 是展示不用处理
if (parseInt(b.type) === 1) {
a.push(b)
} else {
// 表单类型的数据处理
// 处理需要填写的字段表单
const userFields = JSON.parse(b.user_fields)
const userFieldsStore = []
// 人员信息转换成表单需要的数据(因为第1个永远是自己所以加了排序)
b.list
.sort((a, b) => {
return a.index - b.index
})
.forEach(d => {
const fields = []
userFields.forEach(dd => {
const fData = Object.assign(
{},
allFormList.find(f => f.key === dd.key)
)
fData.value = d[dd.key]
// 判断当前form信息是不是登录人的 是的话给个标记(作为后面表单填写不可编辑的标识)
if (fData.key === 'mobile') {
if (fData.value === this.userMobile) {
fData.enable_edit = false
}
}
fields.push(fData)
})
// console.log(fields.find(f => !f.enable_edit), 'fields')
userFieldsStore.push(fields)
})
b.user_fields = userFieldsStore
a.push(b)
// 处理“开启支付功能” 自定义type3支付页
if (b.can_pay === 1) {
const payPage = {
type: 3,
user_fields: b.user_fields,
activity_detail_id: b.id,
id: b.activity_id,
num: b.num,
offline_info: b.offline_info,
pay_type: b.pay_type.split(','),
can_company: b.can_company,
offline_more_info: b.offline_more_info
}
// 开启支付成功跳转的功能
if (b.can_jump) {
payPage.jump_url = b.jump_url
}
a.push(payPage)
}
}
return a
}, [])
this.stepList.map((item, index) => {
item.num = index + 1
if (!this.$route.query.id) {
if (item.type === 3) {
item.payData = {
list: this.stepList[index - 1].list,
join_rand: data[0].join_rand,
pay_price: data[0].pay_price
}
}
}
return item
})
!this.$route.query.id && this.stepIndex++
if (this.$route.query.stepIndex !== undefined) {
this.stepIndex = this.$route.query.stepIndex
}
},
handlePrev() {
if (this.stepIndex <= 0) {
this.$router.push('/')
} else {
this.stepIndex--
}
},
handleNext(data) {
if (this.setpItem.num !== this.stepList[this.stepList.length - 1].num) {
this.stepIndex++
if (data) {
this.setpItem.payData = data
}
const stringData = {
index: this.stepIndex,
stepList: this.stepList
}
window.localStorage.stepData = JSON.stringify(stringData)
}
},
setQuery() {
const query = {
id: this.$route.query.id,
index: this.stepIndex
}
if (this.$route.query.index) {
if (this.stepIndex !== parseInt(this.$route.query.index)) {
this.$router.push({
path: window.location.pathname,
query: query
})
}
} else {
this.$router.push({
path: window.location.pathname,
query: query
})
}
}
}
}
</script>
import axios from 'axios'
// import queryString from 'query-string'
import { Message } from 'element-ui'
import { Toast } from 'vant'
import router from '../router'
// import store from '../store'
import qs from 'qs'
......@@ -42,6 +43,8 @@ httpRequest.interceptors.response.use(
}
// 未登录
if (data.code === 1) {
Toast(data.message)
// window.location.href = `${import.meta.env.VITE_LOGIN_URL}`
return data
}
......
......@@ -3,296 +3,93 @@ const allFormList = [
type: 'input',
name: '姓名',
placeholder: '请输入姓名',
required: true,
key: 'name',
value: '',
enable_edit: true,
inputType: '',
trigger: 'onBlur',
msg: '',
pattern: ''
value: ''
},
{
type: 'input',
name: '电话',
placeholder: '请输入电话',
required: true,
key: 'mobile',
value: '',
enable_edit: true,
inputType: 'tel',
trigger: 'onBlur',
msg: '请输入正确的手机号',
pattern: /^1(3|4|7|5|8)([0-9]{9})/
value: ''
},
{
type: 'radio',
name: '性别',
key: 'gender',
required: true,
value: '0',
enable_edit: true,
optionList: [
{ id: '0', option: '未知' },
{ id: '1', option: '男' },
{ id: '2', option: '女' }
],
trigger: 'onChange',
msg: '',
pattern: ''
type: 'input',
name: '身份证号码',
placeholder: '请输入身份证号码',
key: 'id_number',
value: ''
},
{
type: 'input',
name: '邮箱',
placeholder: '请输入邮箱',
required: true,
key: 'email',
value: '',
enable_edit: true,
inputType: '',
trigger: 'onBlur',
msg: '请输入正确的邮箱',
pattern: /[\d\w]+\b@[a-zA-ZA-z0-9]+\.[a-z]+/g
value: ''
},
{
type: 'input',
name: '公司',
name: '地址',
placeholder: '请输入地址',
key: 'address',
value: ''
},
{
type: 'input',
name: '单位',
placeholder: '请输入公司',
required: true,
key: 'company',
value: '',
enable_edit: true,
inputType: '',
trigger: 'onBlur',
msg: '',
pattern: ''
value: ''
},
{
type: 'input',
name: '职位',
placeholder: '请输入职位',
required: true,
key: 'position',
value: '',
enable_edit: true,
inputType: '',
trigger: 'onBlur',
msg: '',
pattern: ''
},
{
type: 'input',
name: '身份证号码',
placeholder: '请输入身份证号码',
required: true,
key: 'id_number',
value: '',
enable_edit: true,
inputType: '',
trigger: 'onBlur',
msg: '请输入正确的身份证号码',
pattern: /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/
value: ''
},
{
type: 'input',
name: '编号',
placeholder: '请输入编号',
required: true,
key: 'number',
value: '',
enable_edit: true,
inputType: 'number',
trigger: 'onBlur',
msg: '',
pattern: ''
value: ''
},
{
type: 'input',
name: '国籍',
placeholder: '请输入国籍',
required: true,
key: 'country',
value: '',
enable_edit: true,
inputType: '',
trigger: 'onBlur',
msg: '',
pattern: ''
value: ''
},
{
type: 'input',
name: '省份',
placeholder: '请输入省份',
required: true,
key: 'provinces',
value: '',
enable_edit: true,
inputType: '',
trigger: 'onBlur',
msg: '',
pattern: ''
value: ''
},
{
type: 'input',
name: '城市',
placeholder: '请输入城市',
required: true,
key: 'city',
value: '',
enable_edit: true,
inputType: '',
trigger: 'onBlur',
msg: '',
pattern: ''
},
{
type: 'input',
name: '地址',
placeholder: '请输入地址',
required: true,
key: 'address',
value: '',
enable_edit: true,
inputType: '',
trigger: 'onBlur',
msg: '',
pattern: ''
},
{
type: 'input',
name: '固话',
placeholder: '请输入固话',
required: true,
key: 'fixed_telephone',
value: '',
enable_edit: true,
inputType: 'tel',
trigger: 'onBlur',
msg: '请输入正确的固话',
pattern: ''
value: ''
},
{
type: 'input',
name: '行业',
placeholder: '请输入行业',
required: true,
key: 'industry',
value: '',
enable_edit: true,
inputType: '',
trigger: 'onBlur',
msg: '',
pattern: ''
},
{
type: 'input',
name: 'QQ',
placeholder: '请输入QQ',
required: true,
key: 'qq',
value: '',
enable_edit: true,
inputType: 'number',
trigger: 'onBlur',
msg: ''
value: ''
},
{
type: 'input',
name: '微信',
placeholder: '请输入微信',
required: true,
key: 'wechat',
value: '',
enable_edit: true,
inputType: '',
trigger: 'onBlur',
msg: '',
pattern: ''
},
{
type: 'input',
name: '钉钉',
placeholder: '请输入钉钉',
required: true,
key: 'ding',
value: '',
enable_edit: true,
inputType: '',
trigger: 'onBlur',
msg: '',
pattern: ''
},
{
type: 'input',
name: '微博',
placeholder: '请输入微博',
required: true,
key: 'weibo',
value: '',
enable_edit: true,
inputType: '',
msg: '',
trigger: 'onBlur',
pattern: ''
},
{
type: 'select',
name: '早餐',
key: 'breakfast',
placeholder: '请选择早餐',
value: '',
required: true,
optionList: ['有', '无'],
showPicker: false,
enable_edit: true,
trigger: 'onBlur',
msg: '',
pattern: ''
},
{
type: 'select',
name: '房型',
key: 'room_type',
placeholder: '请选择房型',
required: true,
value: '',
enable_edit: true,
inputType: '',
trigger: 'onChange',
optionList: ['单住', '合住', '不住'],
showPicker: false,
msg: '',
pattern: ''
},
{
type: 'datetime',
name: '入住时间',
key: 'check_in_time',
placeholder: '请选择入住时间',
required: true,
value: '',
enable_edit: true,
inputType: '',
trigger: 'onChange',
optionList: [],
showPicker: false,
msg: '',
pattern: ''
},
{
type: 'datetime',
name: '离店时间',
key: 'check_out_time',
placeholder: '请选择离店时间',
required: true,
value: '',
enable_edit: true,
inputType: '',
optionList: [],
showPicker: false,
trigger: 'onChange',
msg: '',
pattern: ''
value: ''
}
]
export default allFormList
......@@ -14,11 +14,11 @@ export default defineConfig({
cert: fs.readFileSync(path.join(__dirname, './https/dev.ezijing.com.pem'))
},
proxy: {
'/api/register': {
'/api/cert': {
// target: 'http://localhost-activity-frontend.ezijing.com',
target: 'https://activity-frontend-api.ezijing.com',
target: 'https://cert-frontend-api.ezijing.com',
changeOrigin: true,
rewrite: path => path.replace(/^\/api\/register/, '')
rewrite: path => path.replace(/^\/api\/cert/, '')
},
'/api': 'https://app.ezijing.com'
}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论