612 lines
24 KiB
HTML
612 lines
24 KiB
HTML
<!--#
|
|
layout("/mobile/platform.html"){
|
|
#-->
|
|
|
|
<style>
|
|
.van-doc-card {
|
|
background-color: #fff;
|
|
border-radius: 6px;
|
|
box-shadow: 0 8px 12px #ebedf0;
|
|
line-height: 20px;
|
|
position: relative;
|
|
}
|
|
|
|
.van-doc-card > div:first-child {
|
|
border: 2px #0e78c5 solid;
|
|
width: 26px;
|
|
border-radius: 6px;
|
|
position: absolute;
|
|
top: 0;
|
|
left: 20px;
|
|
}
|
|
|
|
.van-card-header {
|
|
padding: 14px 20px;
|
|
border-bottom: 1px solid #ebeef5;
|
|
box-sizing: border-box;
|
|
color: #0e78c5;
|
|
font-weight: bold;
|
|
}
|
|
|
|
.van-card-body {
|
|
padding: 0px 10px 0px 10px;
|
|
}
|
|
|
|
.join_content {
|
|
padding: 10px;
|
|
overflow-y: auto;
|
|
height: calc(100vh - 46px - 20px - 60px);
|
|
}
|
|
|
|
.basic .van-cell {
|
|
flex-direction: row-reverse;
|
|
}
|
|
|
|
.van-cell__label {
|
|
color: #323233;
|
|
font-size: 14px;
|
|
line-height: 24px;
|
|
margin-top: 0;
|
|
}
|
|
|
|
.empty_text {
|
|
text-align: center;
|
|
padding: 10px 0px;
|
|
font-size: 14px;
|
|
color: grey;
|
|
}
|
|
|
|
.van-tabs__wrap {
|
|
margin: 6px;
|
|
}
|
|
|
|
.van-tabs__nav--card {
|
|
border: none;
|
|
}
|
|
|
|
.van-tabs__nav--card .van-tab.van-tab--active {
|
|
border-radius: 6px;
|
|
}
|
|
|
|
.van-tabs__nav--card .van-tab {
|
|
border-right: 0 !important;
|
|
}
|
|
|
|
.footer {
|
|
background-color: white;
|
|
position: fixed;
|
|
bottom: 0;
|
|
width: 100%;
|
|
height: 60px;
|
|
display: flex;
|
|
justify-content: space-evenly;
|
|
align-items: center;
|
|
left: 0;
|
|
z-index: 99;
|
|
}
|
|
|
|
.footer .van-button {
|
|
height: 34px;
|
|
border-radius: 6px;
|
|
width: 90% !important;
|
|
}
|
|
|
|
.join {
|
|
background-color: #0e78c5;
|
|
color: white;
|
|
}
|
|
|
|
.join_submit {
|
|
width: 90% !important;
|
|
}
|
|
|
|
.van-hairline--top-bottom::after,
|
|
.van-hairline-unset--top-bottom::after {
|
|
border: none;
|
|
}
|
|
|
|
.pre_text {
|
|
white-space: break-spaces;
|
|
padding-left: 7px;
|
|
/*margin-top: 30px;*/
|
|
}
|
|
|
|
.right_content {
|
|
width: calc(100% - 150px);
|
|
padding-left: 20px;
|
|
padding-right: 10px;
|
|
position: relative;
|
|
height: 100px;
|
|
}
|
|
</style>
|
|
|
|
<div id="app" v-cloak>
|
|
<van-sticky>
|
|
<van-nav-bar title="体检套餐选择" left-arrow @click-left="pjaxReplace('/mobile/healthCheckup/list')"></van-nav-bar>
|
|
</van-sticky>
|
|
|
|
<div class="join_content">
|
|
<van-form @submit="joinSubmit">
|
|
<div class="van-doc-card" style="margin-bottom: 16px">
|
|
<div></div>
|
|
<div class="van-card-header">体检套餐</div>
|
|
<div class="van-card-body">
|
|
<van-radio-group v-model="formData.subjectId" class="basic">
|
|
<van-cell-group>
|
|
<van-cell title="" :key="item.id" v-for="item in project.healthCheckupProjectSubjects">
|
|
<template #label>
|
|
<div style="display: flex; justify-content: space-between; width: 100%; padding: 10px 0">
|
|
<van-image
|
|
:src="FILE_STREAM_PREVIEW_ADDRESS+'?id='+item.imgUrl"
|
|
fit="contain"
|
|
style="width: 60px; height: 60px; border-radius: 10px; margin-left: 10px"
|
|
></van-image>
|
|
<div>{{ item.optionName }}</div>
|
|
</div>
|
|
<div style="display: flex; justify-content: flex-end; margin-top: -20px">
|
|
<div @click="viewDesc(item)" style="color: #0e78c5">查看说明</div>
|
|
</div>
|
|
</template>
|
|
<template #right-icon>
|
|
<van-radio :name="item.id"></van-radio>
|
|
</template>
|
|
</van-cell>
|
|
</van-cell-group>
|
|
</van-radio-group>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="van-doc-card" style="margin-bottom: 16px">
|
|
<div></div>
|
|
<div class="van-card-header">基础信息</div>
|
|
<div class="van-card-body">
|
|
<!--<van-field
|
|
@click="campusVisible = true"
|
|
readonly
|
|
required
|
|
is-link
|
|
label="院区"
|
|
name="campus"
|
|
placeholder="请选择体检院区"
|
|
v-model="formData.campusName"
|
|
:rules="[{ required: true }]"
|
|
></van-field>-->
|
|
<van-field
|
|
label="姓名"
|
|
name="username"
|
|
required
|
|
placeholder="请填写姓名"
|
|
v-model="formData.username"
|
|
:rules="[{ required: true }]"
|
|
></van-field>
|
|
<van-field
|
|
required
|
|
readonly
|
|
label="性别"
|
|
name="sex"
|
|
placeholder="输入身份证后自动匹配"
|
|
:rules="[{ required: true }]"
|
|
v-model="formData.sex"
|
|
></van-field>
|
|
<van-field
|
|
label="年龄"
|
|
name="age"
|
|
required
|
|
readonly
|
|
placeholder="输入身份证后自动计算"
|
|
type="digit"
|
|
:rules="[{ required: true }]"
|
|
v-model="formData.age"
|
|
></van-field>
|
|
<span style="font-size: 13px; margin-left: 1.4vh; color: #bc2a25">输入身份证后自动匹配性别和年龄</span>
|
|
<van-field
|
|
label="联系方式"
|
|
name="mobile"
|
|
required
|
|
placeholder="请填写联系方式"
|
|
type="digit"
|
|
maxlength="11"
|
|
:rules="[{ required: true }]"
|
|
v-model="formData.mobile"
|
|
></van-field>
|
|
<van-field
|
|
label="身份证号"
|
|
name="idcard"
|
|
required
|
|
maxlength="18"
|
|
placeholder="请填写身份证号"
|
|
@input="getAgeAndSex"
|
|
:rules="[{ required: true }]"
|
|
v-model="formData.idcard"
|
|
></van-field>
|
|
|
|
<!-- <van-field :rules="[{ required: true, message: '请选择家属是否体检' }]" label="家属体检" name="validator">
|
|
<template #input>
|
|
<van-radio-group direction="horizontal" v-model="formData.isFamily" disabled>
|
|
<van-radio name="是" shape="square">是</van-radio>
|
|
<van-radio name="否" shape="square">否</van-radio>
|
|
</van-radio-group>
|
|
</template>
|
|
</van-field>-->
|
|
</div>
|
|
</div>
|
|
|
|
<div class="van-doc-card" style="margin-bottom: 16px" v-if="formData.isFamily === '是'">
|
|
<div></div>
|
|
<div class="van-card-header" style="display: flex; justify-content: space-between; align-items: center">
|
|
<span style="float: left">家属信息</span>
|
|
<div>
|
|
<van-tag @click="delCompanion" size="large" type="primary" color="lightgrey">删除家属</van-tag>
|
|
<van-tag @click="addCompanion" size="large" type="primary" color="#1867b0">添加家属</van-tag>
|
|
</div>
|
|
</div>
|
|
<div v-if="formData.companionList.length > 0" class="van-card-body">
|
|
<van-tabs v-model="active" type="card" color="#0e78c5" animated>
|
|
<van-tab v-for="item, index in formData.companionList" :title="'家属' + (index + 1)">
|
|
<van-field
|
|
label="姓名"
|
|
name="userName"
|
|
placeholder="请填写姓名"
|
|
v-model="item.userName"
|
|
:rules="[{ required: true }]"
|
|
></van-field>
|
|
<van-field :rules="[{ required: true, message: '请选择性别' }]" label="性别" name="validator">
|
|
<template #input>
|
|
<van-radio-group direction="horizontal" v-model="item.sex">
|
|
<van-radio name="男" shape="square">男</van-radio>
|
|
<van-radio name="女" shape="square">女</van-radio>
|
|
</van-radio-group>
|
|
</template>
|
|
</van-field>
|
|
<van-field :rules="[{ required: true, message: '请选择婚否' }]" label="婚否" name="validator">
|
|
<template #input>
|
|
<van-radio-group direction="horizontal" v-model="item.marry">
|
|
<van-radio name="未婚" shape="square">未婚</van-radio>
|
|
<van-radio name="已婚" shape="square">已婚</van-radio>
|
|
</van-radio-group>
|
|
</template>
|
|
</van-field>
|
|
<van-field
|
|
label="年龄"
|
|
name="age"
|
|
placeholder="请填写年龄"
|
|
type="digit"
|
|
:rules="[{ required: true }]"
|
|
v-model="item.age"
|
|
></van-field>
|
|
<van-field
|
|
label="身份证号"
|
|
name="idCard"
|
|
placeholder="请填写身份证号"
|
|
type="digit"
|
|
:rules="[{ required: true }]"
|
|
v-model="item.idCard"
|
|
></van-field>
|
|
<van-field
|
|
label="手机号"
|
|
name="mobile"
|
|
placeholder="请填写手机号"
|
|
type="digit"
|
|
:rules="[{ required: true }]"
|
|
v-model="item.mobile"
|
|
></van-field>
|
|
</van-tab>
|
|
</van-tabs>
|
|
</div>
|
|
<div v-if="formData.companionList.length == 0" class="empty_text">
|
|
<span>如有家属,请添加家属</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="footer">
|
|
<van-button class="join join_submit">提交选择</van-button>
|
|
</div>
|
|
</van-form>
|
|
</div>
|
|
|
|
<!--体检院区弹出框-->
|
|
<!--<van-popup position="bottom" round v-model="campusVisible">
|
|
<van-picker
|
|
title="院区"
|
|
show-toolbar
|
|
:columns="campusList"
|
|
value-key="campusName"
|
|
@confirm="(value, index) => {formData.campusName = value.campusName; formData.campus = value.id; campusVisible = false}"
|
|
@cancel="campusVisible = false"
|
|
></van-picker>
|
|
</van-popup>-->
|
|
|
|
<!--查看说明-->
|
|
<van-popup position="bottom" round v-model="descVisible" :style="{ height: '60%' }">
|
|
<div v-html="desc" class="pre_text"></div>
|
|
</van-popup>
|
|
|
|
<div>
|
|
<van-tabbar v-model="tarBarActive">
|
|
<van-tabbar-item icon="home-o" replace url="/mobile/healthCheckup/list">体检选择</van-tabbar-item>
|
|
<van-tabbar-item icon="manager-o" replace url="/mobile/healthCheckup/mine">我的体检</van-tabbar-item>
|
|
</van-tabbar>
|
|
</div>
|
|
</div>
|
|
<script>
|
|
const vue = new Vue({
|
|
el: "#app",
|
|
mixins: [mobileMixins],
|
|
data() {
|
|
return {
|
|
tarBarActive: 0,
|
|
id: "",
|
|
selectId: "",
|
|
active: 0,
|
|
project: {},
|
|
formData: {
|
|
companionList: [],
|
|
isFamily: "否"
|
|
},
|
|
campusList: [],
|
|
campusVisible: false,
|
|
descVisible: false,
|
|
desc: ""
|
|
}
|
|
},
|
|
methods: {
|
|
getAgeAndSex(value) {
|
|
try {
|
|
const age = this.calculateAgeFromIdCard(value)
|
|
this.$set(this.formData, "age", age)
|
|
|
|
const sex = this.getGenderFromIdCard(value)
|
|
this.$set(this.formData, "sex", sex)
|
|
} catch (error) {
|
|
console.log(error)
|
|
}
|
|
},
|
|
calculateAgeFromIdCard(idCard) {
|
|
// 检查身份证号码是否合法
|
|
if (!idCard) {
|
|
throw new Error("Invalid ID card format")
|
|
}
|
|
|
|
let birthDateStr
|
|
let birthYear, birthMonth, birthDay
|
|
|
|
// 处理18位身份证号码
|
|
if (idCard.length === 18) {
|
|
birthDateStr = idCard.substring(6, 14)
|
|
birthYear = parseInt(birthDateStr.substring(0, 4), 10)
|
|
birthMonth = parseInt(birthDateStr.substring(4, 6), 10) - 1 // 月份从0开始
|
|
birthDay = parseInt(birthDateStr.substring(6, 8), 10)
|
|
}
|
|
// 处理15位身份证号码
|
|
else if (idCard.length === 15) {
|
|
birthDateStr = idCard.substring(6, 12)
|
|
birthYear = parseInt("19" + birthDateStr.substring(0, 2), 10) // 使用字符串拼接
|
|
birthMonth = parseInt(birthDateStr.substring(2, 4), 10) - 1 // 月份从0开始
|
|
birthDay = parseInt(birthDateStr.substring(4, 6), 10)
|
|
} else {
|
|
throw new Error("Invalid ID card format. Only 15 or 18 digits are supported.")
|
|
}
|
|
|
|
// 获取当前日期
|
|
const currentDate = new Date()
|
|
|
|
// 计算年龄
|
|
let age = currentDate.getFullYear() - birthYear
|
|
|
|
// 如果当前日期还没过生日,则年龄减1
|
|
if (currentDate.getMonth() < birthMonth || (currentDate.getMonth() === birthMonth && currentDate.getDate() < birthDay)) {
|
|
age -= 1
|
|
}
|
|
|
|
return age
|
|
},
|
|
getGenderFromIdCard(idCard) {
|
|
// 检查身份证号码是否合法
|
|
if (!idCard) {
|
|
throw new Error("Invalid ID card format")
|
|
}
|
|
|
|
let genderDigit
|
|
|
|
// 处理18位身份证号码
|
|
if (idCard.length === 18) {
|
|
genderDigit = parseInt(idCard.charAt(16), 10) // 第17位
|
|
}
|
|
// 处理15位身份证号码
|
|
else if (idCard.length === 15) {
|
|
genderDigit = parseInt(idCard.charAt(14), 10) // 第15位
|
|
} else {
|
|
throw new Error("Invalid ID card format. Only 15 or 18 digits are supported.")
|
|
}
|
|
|
|
// 判断性别
|
|
if (genderDigit % 2 === 0) {
|
|
return "女"
|
|
} else {
|
|
return "男"
|
|
}
|
|
},
|
|
viewDesc(o) {
|
|
if (o.description) {
|
|
this.desc = o.description
|
|
this.descVisible = true
|
|
} else {
|
|
vant.Toast("暂无详细说明")
|
|
}
|
|
},
|
|
async joinSubmit() {
|
|
if (!this.formData.subjectId) {
|
|
vant.Toast("请选择体检套餐")
|
|
return
|
|
}
|
|
|
|
if (!this.validatePhoneNumber(this.formData.mobile)) {
|
|
vant.Toast("请填写正确的手机号")
|
|
return
|
|
}
|
|
if (!this.validateIdCard(this.formData.idcard)) {
|
|
vant.Toast("请填写正确的身份证号")
|
|
return
|
|
}
|
|
|
|
//如果等于家属
|
|
if (this.project.healthCheckupType === "js" && this.formData.companionList && this.formData.companionList.length === 0) {
|
|
vant.Toast("当前体检项目需要填写家属信息,请填写家属信息。")
|
|
return
|
|
}
|
|
const p = this.project.healthCheckupProjectSubjects.find((o) => o.id === this.formData.subjectId)
|
|
const res = await $.post("/mobile/healthCheckup/validCondition", {
|
|
cndId: p.conditionStructureId
|
|
})
|
|
if (res.code !== 0) {
|
|
vant.Dialog.alert({
|
|
title: "提示",
|
|
message: res.msg,
|
|
confirmButtonColor: "#1867b0"
|
|
})
|
|
return
|
|
}
|
|
vant.Dialog.confirm({
|
|
title: "温馨提醒",
|
|
message: "您确定要选择" + p.optionName + "吗?"
|
|
})
|
|
.then(async () => {
|
|
const toast = vant.Toast.loading({
|
|
duration: 0,
|
|
forbidClick: true,
|
|
overlay: true,
|
|
message: "努力提交中"
|
|
})
|
|
const cloneData = clone(this.formData)
|
|
if (cloneData.isFmaily === "否") {
|
|
cloneData.companionList = []
|
|
}
|
|
cloneData.companionList.forEach((item, index) => {
|
|
if (item.userName === "") {
|
|
cloneData.companionList.splice(index, 1)
|
|
}
|
|
})
|
|
cloneData.projectId = this.id
|
|
const resp = await $.post("/mobile/healthCheckup/doSubmit", {
|
|
userSelection: JSON.stringify(cloneData)
|
|
})
|
|
setTimeout(() => {
|
|
if (resp.code === 0) {
|
|
toast.message = "提交成功"
|
|
toast.type = "success"
|
|
} else {
|
|
toast.message = resp.msg
|
|
toast.type = "fail"
|
|
}
|
|
setTimeout(() => {
|
|
toast.clear()
|
|
}, 500)
|
|
if (resp.code === 0) {
|
|
location.href = "/mobile/healthCheckup/mine"
|
|
}
|
|
}, 1000)
|
|
})
|
|
.catch(() => {})
|
|
},
|
|
addCompanion() {
|
|
this.formData.companionList.push({ userName: "", sex: "", marry: "" })
|
|
},
|
|
delCompanion() {
|
|
this.formData.companionList.splice(this.active, 1)
|
|
},
|
|
//查询有哪些体检套餐
|
|
async findSubject() {
|
|
const resp = await $.post("/platform/healthCheckup/project/mange/findOne", { id: this.id })
|
|
this.project = resp.data
|
|
this.formData.isFamily = this.project.healthCheckupType === "jzg" ? "否" : "是"
|
|
//const sex = "${@shiro.getPrincipalProperty('sex')}";
|
|
//this.project.healthCheckupProjectSubjects = this.project.healthCheckupProjectSubjects.filter(o => o.sex === sex || o.sex === '' || o.sex === null)
|
|
},
|
|
//获取院区
|
|
async getCampus() {
|
|
const resp = await $.post("/mobile/healthCheckup/getCampus")
|
|
this.campusList = resp.data
|
|
},
|
|
//获取报名信息
|
|
async getSelectInfo() {
|
|
const resp = await $.post("/mobile/healthCheckup/getSelectInfo", { id: this.selectId })
|
|
this.formData = resp.data
|
|
// const o = this.campusList.find((o) => o.id === this.formData.campus)
|
|
// this.formData.campusName = o.campusName
|
|
},
|
|
async getUserInfo() {
|
|
const resp = await $.post("/mobile/healthCheckup/getUserInfo")
|
|
if (resp.code === 0) {
|
|
this.$set(this.formData, "username", resp.data.username)
|
|
this.$set(this.formData, "sex", resp.data.sex)
|
|
this.$set(this.formData, "mobile", resp.data.mobile)
|
|
this.$set(this.formData, "idcard", resp.data.idcard)
|
|
this.$set(this.formData, "age", resp.data.age)
|
|
}
|
|
},
|
|
validateIdCard(idCard) {
|
|
if (!idCard) {
|
|
return false
|
|
}
|
|
|
|
// 18位身份证号码校验
|
|
if (idCard.length === 18) {
|
|
const idCardRegex = /^[1-9]\d{5}(18|19|20)?\d{2}((0[1-9])|(10|11|12))(([0|1|2][0-9])|10|20|30|31)\d{3}(\d|[Xx])$/
|
|
if (!idCardRegex.test(idCard)) {
|
|
return false
|
|
}
|
|
|
|
// 校验码计算
|
|
const weights = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
|
|
const checksums = ["1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"]
|
|
let sum = 0
|
|
for (let i = 0; i < 17; i++) {
|
|
sum += idCard[i] * weights[i]
|
|
}
|
|
const checksum = checksums[sum % 11]
|
|
return checksum === idCard[17].toUpperCase()
|
|
}
|
|
|
|
// 15位身份证号码校验
|
|
else if (idCard.length === 15) {
|
|
const idCardRegex = /^[1-9]\d{5}\d{2}((0[1-9])|(10|11|12))(([0|1|2][0-9])|10|20|30|31)\d{3}$/
|
|
return idCardRegex.test(idCard)
|
|
}
|
|
|
|
// 外国人或其他情况
|
|
else {
|
|
return false
|
|
}
|
|
},
|
|
validatePhoneNumber(phoneNumber) {
|
|
if (!phoneNumber) {
|
|
return false
|
|
}
|
|
const phoneRegex = /^1[3-9]\d{9}$/
|
|
return phoneRegex.test(phoneNumber)
|
|
}
|
|
},
|
|
async created() {
|
|
this.id = GetQueryString("projectId")
|
|
this.selectId = GetQueryString("selectId")
|
|
await this.getCampus()
|
|
if (GetQueryString("selectId")) {
|
|
await this.getSelectInfo()
|
|
} else {
|
|
this.getUserInfo()
|
|
}
|
|
await this.findSubject()
|
|
}
|
|
})
|
|
window.onload = () => {
|
|
window.addEventListener("pageshow", (e) => {
|
|
if (e.persisted) {
|
|
window.location.reload()
|
|
}
|
|
})
|
|
}
|
|
</script>
|
|
<!--#
|
|
}
|
|
#-->
|