This commit is contained in:
2025-10-29 09:14:00 +08:00
parent a3fd6a1c26
commit 260e4c25ad
21 changed files with 757 additions and 466 deletions
@@ -195,6 +195,7 @@ layout("/layouts/platform.html"){
{prop: 'unitName', label: '所属单位', sortable: true},
{prop: 'optionName', label: '所选套餐'},
{prop: 'selectTime', label: '选择时间', width: "160px"},
{prop: 'receiveAddress', label: '邮寄地址', width: "160px"},
{prop: 'isAudit', label: '是否确认'},
{prop: 'auditTime', label: '确认时间'},
{prop: 'bz', label: '备注',width: "200px"},
@@ -69,9 +69,9 @@ layout("/layouts/platform.html"){
<span class="ti-angle-down"></span>
</el-button>
<el-dropdown-menu slot="dropdown">
<!-- <el-dropdown-item :command="{type:'view',data:row}">
查看
</el-dropdown-item>-->
<!-- <el-dropdown-item :command="{type:'view',data:row}">
查看
</el-dropdown-item>-->
<el-dropdown-item :command="{type:'code',data:row}">
二维码
</el-dropdown-item>
@@ -181,6 +181,18 @@ layout("/layouts/platform.html"){
</div>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="24">
医院方提供材料:
<div>
<file-upload :value.sync="item.files"
upload_mode="file"
:upload_number="10" upload_result_category="array"
accept=".doc, .docx, .xls, .xlsx, .pdf, .ppt, .jpg, .jpeg, .png"
complete_result></file-upload>
</div>
</el-col>
</el-row>
<div class="s-options-list" style="margin-top: 10px;">
<el-table :data="item.subjectMoneys" border size="small">
@@ -192,7 +204,7 @@ layout("/layouts/platform.html"){
></el-input>
</template>
</el-table-column>
<el-table-column label="金额">
<el-table-column label="套餐金额">
<template slot-scope="{row}">
<el-input v-model="row.money" autosize
class="text-input"
@@ -200,12 +212,21 @@ layout("/layouts/platform.html"){
></el-input>
</template>
</el-table-column>
<el-table-column label="结算金额">
<template slot-scope="{row}">
<el-input v-model="row.settlementMoney" autosize
class="text-input"
data-type="option"
></el-input>
</template>
</el-table-column>
<el-table-column label="操作" width="200px">
<template slot-scope="{row,$index}" slot="header">
<el-button size="mini" type="primary"
@click="item.subjectMoneys.push({
money:'',
settlementMoney:'',
subjectMoneyName:'',
marriage:'',
})">添加
@@ -430,6 +451,14 @@ layout("/layouts/platform.html"){
"condition-structure-dialog": CONDITION_STRUCTURE_DIALOG
},
methods: {
removeRootGroup() {
// 重置根条件组
this.updateFromData.conditionGroup = {
logic: "AND",
conditions: [],
groups: []
}
},
dropdownCommand(command) {
const {type, data} = command
if (type === 'view') {
@@ -461,9 +490,9 @@ layout("/layouts/platform.html"){
this.subjectMoneyIndex = subjectIndex
this.hospitalIndex = hospitalIndex
this.conditionStructureDialogVisible = true
if(row.matchCnd){
if (row.matchCnd) {
this.conditionGroup = row.matchCnd
}else{
} else {
this.conditionGroup = {
logic: "AND",
conditions: [],
@@ -474,7 +503,7 @@ layout("/layouts/platform.html"){
},
// 条件构造器确认
confirmCnd(){
confirmCnd() {
this.conditionStructureDialogVisible = false
this.$set(this.formData.healthCheckupProjectSubjects[this.hospitalIndex].subjectMoneys[this.subjectMoneyIndex], 'matchCnd', this.conditionGroup)
},
@@ -493,7 +522,7 @@ layout("/layouts/platform.html"){
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
});
const resp = await $.post(loc() + '/createUserList', row)
const resp = await this.$axios.post(loc() + '/createUserList', row)
if (resp.code === 0) {
setTimeout(() => {
@@ -519,7 +548,7 @@ layout("/layouts/platform.html"){
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
});
const resp = await $.post(loc() + '/renewUserList', row)
const resp = await this.$axios.post(loc() + '/renewUserList', row)
loading.close()
if (resp.code === 0) {
this.$message.success('操作成功')
@@ -542,7 +571,7 @@ layout("/layouts/platform.html"){
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
});
const resp = await $.post(loc() + '/resetUserList', row)
const resp = await this.$axios.post(loc() + '/resetUserList', row)
loading.close()
if (resp.code === 0) {
this.$message.success('操作成功')
@@ -568,7 +597,7 @@ layout("/layouts/platform.html"){
async doDelete(id) {
const confirm = await this.$confirm('确定要删除该项目吗?', '提示', {type: 'warning'})
if (confirm) {
const resp = await $.post(loc() + "/doDelete", {id})
const resp = await this.$axios.post(loc() + "/doDelete", {id})
if (resp.code === 0) {
this.pageData()
this.notifySuccess(resp.msg)
@@ -586,7 +615,7 @@ layout("/layouts/platform.html"){
this.$refs.guava.view()
},
async findOne(id) {
const resp = await $.post(loc() + "/findOne", {id: id})
const resp = await this.$axios.post(loc() + "/findOne", {id: id})
if (resp.code === 0) {
resp.data.choiceTime = [resp.data.choiceTimeStart, resp.data.choiceTimeEnd]
return resp.data
@@ -610,7 +639,7 @@ layout("/layouts/platform.html"){
formData.activityGroupName = this.activityGroupList.find(v => v.groupId === this.formData.activityGroupId).groupName
formData.deleteRowIds = JSON.stringify(this.deleteRowIds)
formData.deleteSubjectIds = JSON.stringify(this.deleteSubjectIds)
const resp = await $.post(loc() + "/doAdd", formData)
const resp = await this.$axios.post("/platform/healthCheckup/project/mange/doAdd", formData)
loading.close()
if (resp.code === 0) {
this.pageData()
@@ -656,7 +685,7 @@ layout("/layouts/platform.html"){
this.richTextDialog = false
},
async getActivityGroup() {
const {data} = await $.get('/platform/activity/basic/scope/getActivityUserScopeGroup')
const {data} = await this.$axios.post('/platform/activity/basic/scope/getActivityUserScopeGroup')
this.activityGroupList = data
},
},
@@ -129,7 +129,7 @@ layout("/layouts/platform.html"){
</el-col>
</el-row>
<el-row>
<!-- <el-row>
<el-col :span="12">
<el-form-item label="逾期选择时间" prop="overdueChoiceTimeEnd">
<el-date-picker
@@ -142,7 +142,7 @@ layout("/layouts/platform.html"){
></el-date-picker>
</el-form-item>
</el-col>
</el-row>
</el-row>-->
<el-row>
<el-col :span="4">
@@ -10,9 +10,9 @@ const optionSelect = {
<!-- 选择提示 -->
<div class="welfare-notice">
<el-alert
:title="projectInfo.isCheckBox === 'radio' ? '请选择一项福利' : '您可以选择多项福利,最多可选 ' + (projectInfo.multiSelectNum || projectInfo.options.length) + ' 项'"
type="info"
show-icon>
:title="projectInfo.isCheckBox === 'radio' ? '请选择一项福利' : '您可以选择多项福利,最多可选 ' + (projectInfo.multiSelectNum || projectInfo.options.length) + ' 项'"
type="info"
show-icon>
</el-alert>
</div>
@@ -63,15 +63,15 @@ const optionSelect = {
</div>
<div class="welfare-options-grid">
<div v-for="option in projectInfo.options"
<div v-for="(option,index) in projectInfo.options"
:key="option.id"
class="welfare-option"
:class="{ selected: projectInfo.isCheckBox === 'radio' ? selectedRadioId === option.id : option.selectNum > 0 }"
@click="projectInfo.isCheckBox === 'radio' ? selectRadioOption(option.id) : null">
<el-tag
v-if="projectInfo.isCheckBox === 'radio' ? selectedRadioId === option.id : option.selectNum > 0"
class="option-tag" type="primary" effect="plain">已选择
v-if="projectInfo.isCheckBox === 'radio' ? selectedRadioId === option.id : option.selectNum > 0"
class="option-tag" type="primary" effect="plain">已选择
</el-tag>
<div class="option-image">
@@ -95,11 +95,13 @@ const optionSelect = {
<!-- 多选模式使用步进器 -->
<div class="option-stepper" v-else>
<el-input-number
v-model="option.selectNum"
:min="0"
:max="projectInfo.multiSelectNum || 99"
size="small"
controls-position="right">
:key="'input-number-'+index+'-'+option.selectNumKey|| 0"
v-model="option.selectNum"
:min="0"
:max="projectInfo.multiSelectNum || 99"
size="small"
@change="selectNumChange(index,option.selectNum)"
controls-position="right">
</el-input-number>
</div>
</div>
@@ -116,11 +118,11 @@ const optionSelect = {
<!-- 选项详情弹窗 -->
<el-dialog
title="福利详情"
:visible.sync="showOptionDetailDialog"
width="60%"
append-to-body
custom-class="welfare-detail-dialog">
title="福利详情"
:visible.sync="showOptionDetailDialog"
width="60%"
append-to-body
custom-class="welfare-detail-dialog">
<div class="welfare-detail-popup" v-if="selectedOption">
<div class="welfare-detail-title">{{ selectedOption.optionName }}</div>
<div class="welfare-detail-content" v-html="selectedOption.description"></div>
@@ -129,11 +131,11 @@ const optionSelect = {
<!-- 确认弹窗 -->
<el-dialog
title="确认选择"
:visible.sync="showConfirmDialog"
width="500px"
append-to-body
custom-class="welfare-confirm-dialog">
title="确认选择"
:visible.sync="showConfirmDialog"
width="500px"
append-to-body
custom-class="welfare-confirm-dialog">
<div class="confirm-content">
<!-- 联系电话输入 -->
<div class="confirm-mobile-section">
@@ -141,14 +143,16 @@ const optionSelect = {
<el-form :model="contactForm" ref="contactForm" :rules="contactRules" label-width="80px">
<el-form-item prop="mobile" label="联系电话">
<el-input
v-model="contactForm.mobile"
placeholder="请输入手机号码"
maxlength="11"
clearable>
v-model="contactForm.mobile"
placeholder="请输入手机号码"
maxlength="11"
clearable>
</el-input>
</el-form-item>
<el-form-item v-if="projectInfo.provideMode == 3" prop="receiveAddress" label="收货地址" :rules="[{ required: true, message: '请选择收货地址', trigger: 'change' }]">
<el-select v-model="contactForm.receiveAddress" placeholder="请选择收货地址" style="width: 100%">
<el-form-item v-if="projectInfo.provideMode == 3" prop="receiveAddress" label="收货地址"
:rules="[{ required: true, message: '请选择收货地址', trigger: 'change' }]">
<el-select v-model="contactForm.receiveAddress" placeholder="请选择收货地址"
style="width: 100%">
<el-option v-for="item in addressOptions"
:key="item.id"
:label="item.userName + ' ' + item.tel + ' ' + item.province + ' ' + item.city + ' ' + item.county + ' ' + item.addressDetail"
@@ -165,9 +169,9 @@ const optionSelect = {
<div class="selected-item-left">
<div class="selected-item-image">
<el-image
:src="option.imgUrl"
fit="cover"
:preview-src-list="[option.imgUrl]">
:src="option.imgUrl"
fit="cover"
:preview-src-list="[option.imgUrl]">
<div slot="error" class="image-slot">
<i class="el-icon-picture-outline"></i>
</div>
@@ -183,10 +187,10 @@ const optionSelect = {
</div>
<div class="selected-item-right">
<el-tag
size="small"
type="primary"
effect="plain"
v-if="projectInfo.isCheckBox === 'checkBox'">
size="small"
type="primary"
effect="plain"
v-if="projectInfo.isCheckBox === 'checkBox'">
× {{ option.selectNum }}
</el-tag>
</div>
@@ -235,14 +239,15 @@ const optionSelect = {
},
contactRules: {
mobile: [
{ required: true, message: "请输入联系电话", trigger: "blur" },
{required: true, message: "请输入联系电话", trigger: "blur"},
{
pattern: /^1[3456789]\d{9}$/,
message: "请输入正确的手机号码",
trigger: "blur"
}
]
}
},
addressOptions: []
}
},
computed: {
@@ -334,7 +339,7 @@ const optionSelect = {
// 获取项目信息
getProjectInfo() {
this.$axios.post("/platform/welfare/common/projectInfo", { id: this.projectId }).then((res) => {
this.$axios.post("/platform/welfare/common/projectInfo", {id: this.projectId}).then((res) => {
if (res.code === 0) {
this.projectInfo = res.data
this.deadlineTime = this.projectInfo.choiceTimeEnd
@@ -381,7 +386,7 @@ const optionSelect = {
} else {
if (this.isProxySelect) {
// 否则使用默认手机号
$.post("/platform/welfare/selection/situation/getMobileByUserId", { userId: this.userId }).then((res) => {
$.post("/platform/welfare/selection/situation/getMobileByUserId", {userId: this.userId}).then((res) => {
if (res.code === 0) {
this.contactForm.mobile = res.data
}
@@ -391,7 +396,7 @@ const optionSelect = {
// 地址回显
if (this.projectInfo.provideMode === 3) {
if (this.userSelection && this.userSelection[0].receiveAddress) {
if (this.userSelection.length > 0 && this.userSelection[0].receiveAddress) {
this.contactForm.receiveAddress = this.userSelection[0].receiveAddress
}
}
@@ -542,6 +547,39 @@ const optionSelect = {
if (resp.code === 0) {
this.addressOptions = resp.data
}
},
selectNumChange(index, newValue) {
const option = this.projectInfo.options[index];
const maxSelect = this.projectInfo.multiSelectNum || this.projectInfo.options.length;
// 计算其他所有选项的总和(不包括当前修改的选项)
const totalOfOthers = this.projectInfo.options.reduce((sum, opt, idx) => {
if (idx !== index) {
return sum + (opt.selectNum || 0);
}
return sum; // 跳过当前 index 的选项
}, 0);
// 计算修改后的总数
const totalCountWithNewValue = totalOfOthers + (option.selectNum || 0);
if (totalCountWithNewValue > maxSelect) {
this.$message.warning("所有选项总份数不能超过" + maxSelect + "份");
// 计算当前选项最多可以设置为多少
const maxAllowedForThisOption = Math.max(0, maxSelect - totalOfOthers);
// 如果当前选项的值大于允许的最大值,则调整它
if (option.selectNum > maxAllowedForThisOption) {
option.selectNum = maxAllowedForThisOption;
}
// 如果当前选项的值小于或等于允许的最大值(例如,用户减少了数量导致总数超标,但实际上减少后并未超过 maxSelect,
// 这种情况理论上不应该在 change 时发生,因为 change 是值改变后触发的,且 change 后的值导致了超标),
// 但为了逻辑完整性,我们只处理需要减少的情况。
// 如果是增加导致超标,则 option.selectNum > maxAllowedForThisOption 成立,会执行赋值。
// 无论是否需要调整值,都需要触发 key 更新以确保 el-input-number 重新渲染
this.$set(option, 'selectNumKey', (option.selectNumKey || 0) + 1);
}
}
},
watch: {
@@ -550,18 +588,20 @@ const optionSelect = {
handler(options) {
if (!options) return
const maxSelect = this.projectInfo.multiSelectNum || options.length
const totalCount = options.reduce((sum, option) => sum + (option.selectNum || 0), 0)
/* const maxSelect = this.projectInfo.multiSelectNum || options.length
const totalCount = options.reduce((sum, option) => sum + (option.selectNum || 0), 0)
if (totalCount > maxSelect) {
this.$message.warning("所有选项总份数不能超过" + maxSelect + "份")
// 找到最后修改的选项并调整其值
const lastChanged = options.find((opt) => opt.selectNum > 0)
if (lastChanged) {
const otherCount = totalCount - lastChanged.selectNum
lastChanged.selectNum = Math.max(0, maxSelect - otherCount)
}
}
if (totalCount > maxSelect) {
this.$message.warning("所有选项总份数不能超过" + maxSelect + "份")
// 找到最后修改的选项并调整其值
const lastChanged = options.find((opt) => opt.selectNum > 0)
if (lastChanged) {
console.log(lastChanged)
const otherCount = totalCount - lastChanged.selectNum
lastChanged.selectNum = Math.max(0, maxSelect - otherCount)
this.$forceUpdate()
}
}*/
}
}
},
@@ -8,7 +8,8 @@ layout("/layouts/platform_h5.html"){
</style>
<div id="app">
<van-nav-bar @click-left="historyBack" left-arrow left-text="返回" title="体检项目选择" placeholder fixed></van-nav-bar>
<van-nav-bar @click-left="historyBack" left-arrow left-text="返回" title="体检项目选择" placeholder
fixed></van-nav-bar>
<van-sticky offset-top="46px">
<van-search
:reverse-color="false"
@@ -26,7 +27,7 @@ layout("/layouts/platform_h5.html"){
</van-sticky>
<table-list api="/platform/healthCheckup/h5/pageData" :page_form.sync="pageForm" ref="tableListRef"
@ready="doSearch" img="cover">
@ready="doSearch" img="cover">
<template v-slot="{index,row}">
<table-column label="开始时间">
{{$moment(row.choiceTimeStart).format('MM/DD HH:mm')}}
@@ -45,20 +46,16 @@ layout("/layouts/platform_h5.html"){
</template>
</table-list>
<h5-project-manage-from ref="h5ProjectManageFromRef" @submit_success="doSearch"></h5-project-manage-from>
</div>
<script>
<!--#include('../projectManageForm.js'){}#-->
const vue = new Vue({
el: "#app",
store,
components: {
"h5-project-manage-from":H5_PROJECT_MANAGE_FROM,
},
data() {
return {
viewShow: false,
yearList: [],
pageForm: {
pageNumber: 1,
@@ -78,13 +75,13 @@ layout("/layouts/platform_h5.html"){
},
onView(row) {
/* if(row.selectCount > 0) {
vant.Dialog.alert({
title: '温馨提示',
message: '此项活动您已选择',
})
return
}*/
/* if(row.selectCount > 0) {
vant.Dialog.alert({
title: '温馨提示',
message: '此项活动您已选择',
})
return
}*/
// 检查项目是否已结束
const now = new Date();
const endTime = new Date(row.choiceTimeEnd);
@@ -93,11 +90,7 @@ layout("/layouts/platform_h5.html"){
return;
}
this.viewShow = true
this.$nextTick(() => {
row.projectId=row.id
this.$refs.h5ProjectManageFromRef.onOpen(row)
})
this.$pjaxReplace("/platform/healthCheckup/h5/projectManageForm?projectId=" + row.id)
},
doSearch() {
this.$nextTick(() => {
@@ -19,29 +19,28 @@ layout("/layouts/platform_h5.html"){
<table-column label="项目名称">{{row.name}}</table-column>
<table-column label="开始时间">{{row.choiceTimeStart}}</table-column>
<table-column label="结束时间">{{row.choiceTimeEnd}}</table-column>
<table-column label="选择医院">{{row.optionName}}</table-column>
<table-column label="邮寄地址">{{row.receiveAddress}}</table-column>
</template>
<template #actions="{index,row}">
<div class="action-btn" @click="edit(row)" v-if="new Date().getTime() < new Date(row.choiceTimeEnd).getTime()">
<i class="fa fa-edit"></i>
<span>修改</span>
</div>
<div class="action-btn" @click="cancel(row)" v-if="new Date().getTime() < new Date(row.choiceTimeEnd).getTime()">
<i class="fa fa-edit"></i>
<div class="action-btn delete" @click="cancel(row)" v-if="new Date().getTime() < new Date(row.choiceTimeEnd).getTime()">
<i class="fa fa-trash"></i>
<span>取消</span>
</div>
</template>
</table-list>
<h5-project-manage-from ref="h5ProjectManageFromRef"></h5-project-manage-from>
</div>
<script>
<!--#include('../projectManageForm.js'){}#-->
const vue = new Vue({
el: "#app",
store,
components: {
"h5-project-manage-from":H5_PROJECT_MANAGE_FROM,
},
data() {
return {
@@ -59,7 +58,7 @@ layout("/layouts/platform_h5.html"){
},
methods: {
edit(row) {
this.$refs.h5ProjectManageFromRef.onOpen(row)
this.$pjaxReplace("/platform/healthCheckup/h5/projectManageForm?projectId=" + row.projectId)
},
async cancel(o) {
vant.Dialog.confirm({
@@ -115,13 +114,6 @@ layout("/layouts/platform_h5.html"){
}
})
window.onload = () => {
window.addEventListener('pageshow', e => {
if (e.persisted) {
window.location.reload()
}
})
}
</script>
@@ -1,362 +0,0 @@
let H5_PROJECT_MANAGE_FROM = {
template: /*language=HTML*/ `
<van-action-sheet v-model="visible" title="体检套餐选择">
<div class="form-container">
<van-form ref="formRef" @submit="doSubmit">
<van-cell-group title="基础信息">
<van-field
input-align="right"
label="身份证号"
name="idCard"
readonly
required
placeholder="请联系校工会补充身份证号"
v-model="formData.idCard"
:rules="[{ required: true, message: '请输入身份证号' }]">
</van-field>
<van-cell title="人员类型">{{formData.userState}}</van-cell>
<van-field
input-align="right"
readonly
required
label="婚姻状况"
name="marriage"
placeholder="请联系校工会补充婚姻状况"
v-model="formData.marriage"
:rules="[{ required: true, message: '请选择婚姻状况' }]"></van-field>
<van-cell title="出生年月">{{$moment(formData.birthday).format('YYYY-MM-DD')}}</van-cell>
<van-cell title="单位">{{formData.unitName}}</van-cell>
</van-cell-group>
<van-cell-group title="本年度预约体检医院">
<div class="van-card-body">
<van-radio-group v-model="formData.subjectId" class="basic">
<van-cell-group>
<van-cell
v-for="item in project.healthCheckupProjectSubjects"
:key="item.id"
:title="item.optionName">
<template #label>
<div style="display: flex; justify-content: space-between; margin-left: 8px">
<div>{{ item.optionName }}</div>
<div @click.stop="viewDesc(item)" style="color: #0e78c5">查看说明</div>
</div>
</template>
<template #right-icon>
<van-radio :name="item.id" @click.stop="clickRadio(item)"></van-radio>
</template>
</van-cell>
</van-cell-group>
</van-radio-group>
</div>
<van-field
input-align="right"
readonly
required
label="所选医院额度"
name="marriage"
placeholder="请选择医院"
v-model="formData.money"
:rules="[{ required: true, message: '请选择医院' }]"></van-field>
</van-cell>
</van-cell-group>
<!-- <van-cell-group title="基础信息">
<div class="van-card-body">
<van-field
@click="campusVisible = true"
readonly
is-link
label="院区"
name="campus"
placeholder="请选择体检院区"
v-model="formData.campusName"
:rules="[{ required: true, message: '请选择体检院区' }]">
</van-field>
<van-field
:rules="[{ required: true, message: '请选择家属是否体检' }]"
label="家属体检"
name="isFamily">
<template #input>
<van-radio-group direction="horizontal" v-model="formData.isFamily">
<van-radio name="是" shape="square">是</van-radio>
<van-radio name="否" shape="square">否</van-radio>
</van-radio-group>
</template>
</van-field>
</div>
</van-cell-group>-->
<van-cell-group title="家属信息" v-if="formData.isFamily === '是'">
<div style="padding: 10px;">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;">
<span>家属信息</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 && formData.companionList.length > 0">
<van-tabs v-model="active" type="card" color="#0e78c5" animated>
<van-tab
v-for="(item, index) in formData.companionList"
:key="index"
:title="'家属' + (index + 1)">
<van-field
label="姓名"
name="userName"
placeholder="请填写姓名"
v-model="item.userName"
:rules="[{ required: true, message: '请填写姓名' }]">
</van-field>
<van-field
:rules="[{ required: true, message: '请选择性别' }]"
label="性别"
name="sex">
<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="marry">
<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, message: '请填写年龄' }]"
v-model="item.age">
</van-field>
<van-field
label="身份证号"
name="idCard"
placeholder="请填写身份证号"
type="digit"
:rules="[{ required: true, message: '请填写身份证号' }]"
v-model="item.idCard">
</van-field>
<van-field
label="手机号"
name="mobile"
placeholder="请填写手机号"
type="digit"
:rules="[{ required: true, message: '请填写手机号' }]"
v-model="item.mobile">
</van-field>
</van-tab>
</van-tabs>
</div>
<div v-else class="empty_text">
<span>如有家属,请添加家属</span>
</div>
</div>
</van-cell-group>
<!-- 按钮区域 -->
<div class="form-actions">
<van-button type="primary" native-type="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="onCampusConfirm"
@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>
</van-action-sheet>
`
, store, dicts: ["ASSET_USAGE_STATE"], data() {
return {
visible: false,
viewData: {},
row: null,
formData: {
subjectId: '', campus: '', campusName: '', isFamily: '否', companionList: [], projectId: ''
},
assetUsageStateNameOption: [],
showAssetUsageStateNamePopup: false,
assetUseUserOption: [],
assetUseNameShow: false,
searchKeyword: "",
active: 0,
campusList: [],
campusVisible: false,
descVisible: false,
desc: '',
project: {},
marriageList: ["已婚", "未婚"],
marriageVisible: false,
}
},
methods: {
// 打开表单
async onOpen(row) {
this.formData = {}
this.row = row;
this.visible = true;
await this.getCampus()
await this.findSubject(row.projectId)
if (row.projectId) {
await this.selectInfo(row);
const {idCard, userState, marriage, birthday, unit} = this.$store.state.user
this.$set(this.formData, 'idCard', idCard)
this.$set(this.formData, 'userState', userState)
this.$set(this.formData, 'marriage', marriage)
this.$set(this.formData, 'birthday', birthday)
this.$set(this.formData, 'unitName', unit.name)
}
},
clickRadio(item) {
const toast = this.$toast.loading({
duration: 0, // 持续展示 toast
forbidClick: true,
message: '查询中....',
});
$.post("/platform/healthCheckup/h5/getSubjectMoney", {
id: item.id,
marriage: this.formData.marriage
}).then(resp => {
if (resp.code === 0) {
this.$set(this.formData, 'subjectId', item.id)
this.$set(this.formData, 'money', resp.data.money)
this.$set(this.formData, 'subjectMoneyId', resp.data.subjectMoneyId)
} else {
this.$set(this.formData, 'money', 0)
}
toast.clear();
})
},
async selectInfo(row) {
//this.formData.projectId = row.projectId;
const resp = await this.$axios.post('/platform/healthCheckup/h5/selectInfo', {projectId: row.projectId});
if (resp.data !== null) {
this.formData = resp.data;
/* const o = this.campusList.find(o => o.id === this.formData.campus)
this.formData.campusName = o.campusName*/
}
},
// 查看说明
viewDesc(item) {
if (item.description) {
this.desc = item.description;
this.descVisible = true;
} else {
vant.Toast('暂无详细说明');
}
},
// 执行提交
async doSubmit() {
const formData = clone(this.formData);
formData.projectId = this.row.projectId;
/* if (formData.isFamily === '否') {
formData.companionList = [];
} else {
// 过滤空的家属信息
formData.companionList = formData.companionList.filter(item => item.userName && item.userName.trim() !== '');
}*/
const resp = await this.$axios.post('/platform/healthCheckup/h5/doSubmit', {
userSelection: JSON.stringify(formData),
});
if (resp.code === 0) {
this.visible = false;
this.$toast.success(resp.msg)
this.$emit('submit_success');
}
},
// 添加家属
addCompanion() {
// 检查是否已达到最大数量限制
if (this.companionList && this.formData.companionList.length >= 5) {
vant.Toast('最多只能添加5个家属');
return;
}
if (!this.formData.companionList) {
this.$set(this.formData, 'companionList', []);
}
this.formData.companionList.push({
userName: '', sex: '', marry: '', age: '', idCard: '', mobile: ''
});
},
// 删除家属
delCompanion() {
if (this.formData.companionList && this.formData.companionList.length > 0) {
this.formData.companionList.splice(this.active, 1);
// 确保active索引有效
if (this.active >= this.formData.companionList.length && this.active > 0) {
this.active = this.formData.companionList.length - 1;
}
}
},
// 院区选择确认
onCampusConfirm(value) {
this.formData.campusName = value.campusName;
this.formData.campus = value.id;
this.campusVisible = false;
},
// 婚姻状况确认
onMarriageConfirm(value) {
this.$set(this.formData, 'marriage', value)
this.$set(this.formData, 'subjectId', null)
this.marriageVisible = false;
},
// 查询体检套餐
async findSubject(id) {
try {
const resp = await this.$axios.post('/platform/healthCheckup/project/mange/findOne', {
id: id
});
this.project = resp.data || {};
} catch (error) {
vant.Toast('获取体检套餐失败');
}
},
// 获取院区
async getCampus() {
try {
const resp = await this.$axios.post('/platform/healthCheckup/h5/getCampus');
this.campusList = resp.data || [];
} catch (error) {
vant.Toast('获取院区失败');
}
}
}
}
@@ -0,0 +1,516 @@
<!--#
layout("/layouts/platform_h5.html"){
#-->
<div id="app">
<van-nav-bar @click-left="historyBack" left-arrow left-text="返回" title="体检套餐选择" placeholder
fixed></van-nav-bar>
<div class="form-container">
<van-form ref="formRef" @submit="doSubmit">
<van-cell-group title="基础信息">
<van-field
input-align="right"
label="身份证号"
name="idCard"
readonly
required
placeholder="请联系校工会补充身份证号"
v-model="formData.idCard"
:rules="[{ required: true, message: '请输入身份证号' }]">
</van-field>
<van-cell title="人员类型">{{formData.userState}}</van-cell>
<van-field
input-align="right"
readonly
required
label="婚姻状况"
name="marriage"
placeholder="请联系校工会补充婚姻状况"
v-model="formData.marriage"
:rules="[{ required: true, message: '请选择婚姻状况' }]"></van-field>
<van-cell title="出生年月">{{$moment(formData.birthday).format('YYYY-MM-DD')}}</van-cell>
<van-cell title="单位">{{formData.unitName}}</van-cell>
</van-cell-group>
<van-cell-group title="本年度预约体检医院">
<div class="van-card-body">
<van-radio-group v-model="formData.subjectId" class="basic">
<van-cell-group>
<van-cell
v-for="item in project.healthCheckupProjectSubjects"
:key="item.id"
:title="item.optionName">
<template #label>
<div style="display: flex; justify-content: space-between; margin-left: 8px">
<!-- <div>{{ item.optionName }}</div>-->
<div></div>
<div @click.stop="viewDesc(item)" style="color: #0e78c5">查看说明</div>
</div>
</template>
<template #right-icon>
<van-radio :name="item.id" @click.stop="clickRadio(item)"></van-radio>
</template>
</van-cell>
</van-cell-group>
</van-radio-group>
</div>
<van-field
input-align="right"
readonly
required
label="所选医院额度"
name="marriage"
placeholder="请选择医院"
v-model="formData.money"
:rules="[{ required: true, message: '请选择医院' }]"></van-field>
</van-cell-group>
<van-cell-group title="体检报告邮寄地址">
<van-radio-group v-model="formData.postMethod">
<van-cell-group>
<van-cell title="单位" clickable
@click="formData.postMethod = '1';formData.receiveAddress=formData.unitName">
<template #right-icon>
<van-radio name="1"></van-radio>
</template>
</van-cell>
<van-cell title="自选" clickable
@click="formData.postMethod = '2';formData.receiveAddress=''">
<template #right-icon>
<van-radio name="2"></van-radio>
</template>
</van-cell>
</van-cell-group>
</van-radio-group>
<template>
<van-field
v-if="formData.postMethod === '2'"
v-model="formData.receiveAddress"
label="邮寄地址"
placeholder="请选择邮寄地址"
readonly
type="textarea"
autosize
rows="2"
is-link
@click="editAddressPopup = true"
required
></van-field>
<van-cell title="邮寄地址" v-else>{{formData.receiveAddress}}</van-cell>
</template>
</van-cell-group>
<!-- <van-cell-group title="基础信息">
<div class="van-card-body">
<van-field
@click="campusVisible = true"
readonly
is-link
label="院区"
name="campus"
placeholder="请选择体检院区"
v-model="formData.campusName"
:rules="[{ required: true, message: '请选择体检院区' }]">
</van-field>
<van-field
:rules="[{ required: true, message: '请选择家属是否体检' }]"
label="家属体检"
name="isFamily">
<template #input>
<van-radio-group direction="horizontal" v-model="formData.isFamily">
<van-radio name="是" shape="square">是</van-radio>
<van-radio name="否" shape="square">否</van-radio>
</van-radio-group>
</template>
</van-field>
</div>
</van-cell-group>-->
<van-cell-group title="家属信息" v-if="formData.isFamily === '是'">
<div style="padding: 10px;">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;">
<span>家属信息</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 && formData.companionList.length > 0">
<van-tabs v-model="active" type="card" color="#0e78c5" animated>
<van-tab
v-for="(item, index) in formData.companionList"
:key="index"
:title="'家属' + (index + 1)">
<van-field
label="姓名"
name="userName"
placeholder="请填写姓名"
v-model="item.userName"
:rules="[{ required: true, message: '请填写姓名' }]">
</van-field>
<van-field
:rules="[{ required: true, message: '请选择性别' }]"
label="性别"
name="sex">
<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="marry">
<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, message: '请填写年龄' }]"
v-model="item.age">
</van-field>
<van-field
label="身份证号"
name="idCard"
placeholder="请填写身份证号"
type="digit"
:rules="[{ required: true, message: '请填写身份证号' }]"
v-model="item.idCard">
</van-field>
<van-field
label="手机号"
name="mobile"
placeholder="请填写手机号"
type="digit"
:rules="[{ required: true, message: '请填写手机号' }]"
v-model="item.mobile">
</van-field>
</van-tab>
</van-tabs>
</div>
<div v-else class="empty_text">
<span>如有家属,请添加家属</span>
</div>
</div>
</van-cell-group>
<!-- 按钮区域 -->
<div class="form-actions">
<van-button type="primary" native-type="submit">提交</van-button>
</div>
</van-form>
</div>
<!--体检院区弹出框-->
<van-action-sheet title="体检院区" v-model="campusVisible">
<van-picker
title="院区"
show-toolbar
:columns="campusList"
value-key="campusName"
@confirm="onCampusConfirm"
@cancel="campusVisible = false">
</van-picker>
</van-action-sheet>
<!--查看说明-->
<van-action-sheet title="医院说明" v-model="descVisible" :style="{ height: '60%' }">
<div class="form-container" style="margin: 10px;">
<van-cell-group title="说明"></van-cell-group>
<div v-html="desc" class="pre_text"></div>
<div style="margin-top: 10px">
<van-cell-group title="以下内容由医院方提供"></van-cell-group>
<file-preview :files="files" complete_result></file-preview>
</div>
</div>
</van-action-sheet>
<!-- 收货地址选择弹窗 -->
<van-action-sheet v-model="editAddressPopup" title="选择收货地址" :round="true">
<div style="padding: 16px 0 0">
<div
v-for="address in addressOptions"
:key="address.id"
class="address-item"
@click="selectAddress(address)"
style="padding: 12px 16px; border-bottom: 1px solid #f0f0f0; cursor: pointer"
>
<div style="display: flex; justify-content: space-between; align-items: flex-start">
<div style="flex: 1">
<div style="font-size: 16px; font-weight: 500; color: #323233; margin-bottom: 4px">
{{ address.userName }} {{ address.tel }}
</div>
<div style="font-size: 14px; color: #646566; line-height: 1.4">
{{ address.province }}{{ address.city }}{{ address.county }}{{ address.addressDetail
}}
</div>
</div>
<van-tag v-if="address.isDefault" type="primary" size="mini" style="margin-left: 8px">默认
</van-tag>
</div>
</div>
<div v-if="addressOptions.length === 0"
style="text-align: center; padding: 40px 16px; color: #969799">暂无收货地址
</div>
</div>
<div style="padding: 16px; border-top: 1px solid #f0f0f0; background: #fafafa">
<van-button type="info" block round @click="goToAddressManage">收货地址管理</van-button>
</div>
</van-action-sheet>
</div>
<script>
const vue = new Vue({
el: "#app",
store,
dicts: ["ASSET_USAGE_STATE"],
data() {
return {
viewData: {},
formData: {
subjectId: '',
campus: '',
campusName: '',
isFamily: '否',
companionList: [],
projectId: '',
postMethod: ''
},
assetUsageStateNameOption: [],
showAssetUsageStateNamePopup: false,
assetUseUserOption: [],
assetUseNameShow: false,
searchKeyword: "",
active: 0,
campusList: [],
campusVisible: false,
descVisible: false,
desc: '',
files: [],
project: {},
marriageList: ["已婚", "未婚"],
marriageVisible: false,
editAddressPopup: false,
addressOptions: []
}
},
methods: {
// 选择收货地址
selectAddress(address) {
this.formData.receiveAddress =
address.userName + " " + address.tel + " " + address.province + address.city + address.county + address.addressDetail
this.editAddressPopup = false
},
// 跳转到地址管理页面
goToAddressManage() {
this.$pjaxReplace("/platform/h5/welfare/address/list")
},
// 获取收货地址
getAddress() {
this.$axios.post("/platform/welfare/addressManage/selectUserAddress").then(resp => {
if (resp.code === 0) {
this.addressOptions = resp.data
}
})
},
isEmptyObject(obj) {
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
return false
}
}
return true
},
addressClick() {
},
// 打开表单
async initData() {
await this.getCampus()
this.getAddress()
await this.findSubject(GetQueryString("projectId"))
if (GetQueryString("projectId")) {
await this.selectInfo(GetQueryString("projectId"));
const {idCard, userState, marriage, birthday, unit} = this.$store.state.user
this.$set(this.formData, 'projectId', GetQueryString("projectId"))
this.$set(this.formData, 'idCard', idCard)
this.$set(this.formData, 'userState', userState)
this.$set(this.formData, 'marriage', marriage)
this.$set(this.formData, 'birthday', birthday)
this.$set(this.formData, 'unitName', unit.name)
this.$set(this.formData, 'postMethod', this.formData?.postMethod ? this.formData.postMethod : "1")
this.$set(this.formData, 'receiveAddress', this.formData?.receiveAddress ? this.formData.receiveAddress : unit.name)
}
},
clickRadio(item) {
const toast = this.$toast.loading({
duration: 0, // 持续展示 toast
forbidClick: true,
message: '查询中....',
});
$.post("/platform/healthCheckup/h5/getSubjectMoney", {
id: item.id,
marriage: this.formData.marriage
}).then(resp => {
if (resp.code === 0) {
this.$set(this.formData, 'subjectId', item.id)
this.$set(this.formData, 'money', resp.data.money)
this.$set(this.formData, 'subjectMoneyId', resp.data.subjectMoneyId)
} else {
this.$set(this.formData, 'money', 0)
}
toast.clear();
})
},
async selectInfo(projectId) {
const resp = await this.$axios.post('/platform/healthCheckup/h5/selectInfo', {projectId: projectId});
if (resp.data !== null) {
this.formData = resp.data;
/* const o = this.campusList.find(o => o.id === this.formData.campus)
this.formData.campusName = o.campusName*/
}
},
// 查看说明
viewDesc(item) {
if (item.description || item.files) {
this.files = item.files;
this.desc = item.description;
this.descVisible = true;
} else {
vant.Toast('暂无详细说明');
}
},
// 执行提交
async doSubmit() {
const formData = clone(this.formData);
if (!formData.receiveAddress) {
this.$toast.fail('请填写邮寄地址!')
}
const subject = this.project.healthCheckupProjectSubjects.find(v => v.id === formData.subjectId)
this.$dialog.confirm({
title: '温馨提示',
message: '您确定要提交选择的【' + subject.optionName + '】吗?',
}).then(() => {
const toast = this.$toast.loading({
duration: 0, // 持续展示 toast
forbidClick: true,
message: '提交中....',
});
/* if (formData.isFamily === '否') {
formData.companionList = [];
} else {
// 过滤空的家属信息
formData.companionList = formData.companionList.filter(item => item.userName && item.userName.trim() !== '');
}*/
this.$axios.post('/platform/healthCheckup/h5/doSubmit', {
userSelection: JSON.stringify(formData),
}).then(resp => {
if (resp.code === 0) {
toast.clear();
this.$toast.success(resp.msg)
this.historyBack()
}
})
}).catch(() => {
});
},
// 添加家属
addCompanion() {
// 检查是否已达到最大数量限制
if (this.companionList && this.formData.companionList.length >= 5) {
vant.Toast('最多只能添加5个家属');
return;
}
if (!this.formData.companionList) {
this.$set(this.formData, 'companionList', []);
}
this.formData.companionList.push({
userName: '', sex: '', marry: '', age: '', idCard: '', mobile: ''
});
},
// 删除家属
delCompanion() {
if (this.formData.companionList && this.formData.companionList.length > 0) {
this.formData.companionList.splice(this.active, 1);
// 确保active索引有效
if (this.active >= this.formData.companionList.length && this.active > 0) {
this.active = this.formData.companionList.length - 1;
}
}
},
// 院区选择确认
onCampusConfirm(value) {
this.formData.campusName = value.campusName;
this.formData.campus = value.id;
this.campusVisible = false;
},
// 婚姻状况确认
onMarriageConfirm(value) {
this.$set(this.formData, 'marriage', value)
this.$set(this.formData, 'subjectId', null)
this.marriageVisible = false;
},
// 查询体检套餐
async findSubject(id) {
try {
const resp = await this.$axios.post('/platform/healthCheckup/project/mange/findOne', {
id: id
});
this.project = resp.data || {};
} catch (error) {
vant.Toast('获取体检套餐失败');
}
},
// 获取院区
async getCampus() {
try {
const resp = await this.$axios.post('/platform/healthCheckup/h5/getCampus');
this.campusList = resp.data || [];
} catch (error) {
vant.Toast('获取院区失败');
}
}
},
created() {
this.initData()
}
})
</script>
<!--#
}
#-->
@@ -603,7 +603,7 @@ layout("/layouts/platform_h5.html"){
<!-- 福利选项列表 -->
<div class="welfare-options-container">
<div
v-for="option in projectInfo.options"
v-for="(option,index) in projectInfo.options"
:key="option.id"
class="welfare-option"
:class="{ selected: projectInfo.isCheckBox === 'radio' ? selectedRadioId === option.id : option.selectNum > 0 }"
@@ -638,6 +638,7 @@ layout("/layouts/platform_h5.html"){
<!-- 多选模式使用步进器 -->
<div class="welfare-option-checkbox" v-else>
<van-stepper
:key="'input-number-'+index+'-'+option.selectNumKey|| 0"
v-model="option.selectNum"
integer
disable-input
@@ -646,6 +647,7 @@ layout("/layouts/platform_h5.html"){
:disabled="isDeadlinePassed"
input-width="40px"
button-size="22px"
@change="selectNumChange(index,option.selectNum)"
theme="round"
></van-stepper>
</div>
@@ -795,6 +797,7 @@ layout("/layouts/platform_h5.html"){
},
computed: {
hasSelection() {
if (this.projectInfo.isCheckBox === "radio") {
return !!this.selectedRadioId
@@ -842,6 +845,39 @@ layout("/layouts/platform_h5.html"){
},
methods: {
selectNumChange(index, newValue) {
const option = this.projectInfo.options[index];
const maxSelect = this.projectInfo.multiSelectNum || this.projectInfo.options.length;
// 计算其他所有选项的总和(不包括当前修改的选项)
const totalOfOthers = this.projectInfo.options.reduce((sum, opt, idx) => {
if (idx !== index) {
return sum + (opt.selectNum || 0);
}
return sum; // 跳过当前 index 的选项
}, 0);
// 计算修改后的总数
const totalCountWithNewValue = totalOfOthers + (option.selectNum || 0);
if (totalCountWithNewValue > maxSelect) {
this.$toast.fail("所有选项总份数不能超过" + maxSelect + "份")
// 计算当前选项最多可以设置为多少
const maxAllowedForThisOption = Math.max(0, maxSelect - totalOfOthers);
// 如果当前选项的值大于允许的最大值,则调整它
if (option.selectNum > maxAllowedForThisOption) {
option.selectNum = maxAllowedForThisOption;
}
// 如果当前选项的值小于或等于允许的最大值(例如,用户减少了数量导致总数超标,但实际上减少后并未超过 maxSelect,
// 这种情况理论上不应该在 change 时发生,因为 change 是值改变后触发的,且 change 后的值导致了超标),
// 但为了逻辑完整性,我们只处理需要减少的情况。
// 如果是增加导致超标,则 option.selectNum > maxAllowedForThisOption 成立,会执行赋值。
// 无论是否需要调整值,都需要触发 key 更新以确保 el-input-number 重新渲染
this.$set(option, 'selectNumKey', (option.selectNumKey || 0) + 1);
}
},
getProjectInfo() {
this.$axios.post("/platform/welfare/common/projectInfo", { id: this.projectId }).then((res) => {
if (res.code === 0) {
@@ -888,7 +924,7 @@ layout("/layouts/platform_h5.html"){
// 地址回显
if (this.projectInfo.provideMode === 3) {
if (this.userSelection && this.userSelection[0].receiveAddress) {
if (this.userSelection.length > 0 && this.userSelection[0].receiveAddress) {
this.formData.receiveAddress = this.userSelection[0].receiveAddress
}
}