Compare commits

...

13 Commits

Author SHA1 Message Date
sangchengzhi
e0d491c1d2 收费室退费网页修改bug 2026-02-25 17:04:48 +08:00
sangchengzhi
934c39eede 修改挂号页面,使其来源更明确 2026-02-09 09:28:56 +08:00
sangchengzhi
1dafcb4364 修改住院模块流程页面,修改限额时段 2026-02-06 14:37:09 +08:00
sangchengzhi
6af4a4d549 修改收费室退费界面样式,制作体检首页 2026-02-02 17:44:21 +08:00
sangchengzhi
75cda74389 修改体检公告,收费室界面样式 2026-01-28 18:26:07 +08:00
sangchengzhi
77c7a93017 修改收费室页面,体检页面,和病案邮寄页面 2026-01-28 16:48:01 +08:00
sangchengzhi
3671751428 病案新增打印份数数据 2026-01-21 15:49:26 +08:00
sangchengzhi
1c1a54206b 更改ios适配时间,更改页面挂号顺序 2026-01-18 13:20:54 +08:00
sangchengzhi
7e9bbf73b5 新增病案状态审核不过 2026-01-16 16:52:57 +08:00
sangchengzhi
84a7fc7acc 添加线上签到按钮 2026-01-14 18:20:46 +08:00
sangchengzhi
c4a06501cb 修改住院详情样式,及页面效果 2026-01-14 17:13:03 +08:00
sangchengzhi
812acfc49b 修改驾驶舱权限,及住院的明细查询 2026-01-14 17:02:09 +08:00
sangchengzhi
7b65d52e21 修改预约体检流程感受 2026-01-13 16:51:25 +08:00
27 changed files with 4071 additions and 461 deletions

BIN
dist.zip Normal file

Binary file not shown.

BIN
src/assets/nxwjlogo2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

BIN
src/assets/住院费用.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 878 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 912 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

BIN
src/assets/预交金.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 715 B

View File

@@ -277,6 +277,8 @@ export const apiGetDrugPrice = p => post('/userorder/getDrugPrice', p);
export const apiBayj = p => postFile('/bingan/apiBayj', p);
// 病案邮寄列表
export const apiGetBAList = p => post('/bingan/apiGetBAList', p);
// 病案邮寄列表
export const apiGetBAList2 = p => post('/bingan/apiGetBAList2', p);
// 病案邮寄取消申请
export const apiDeleteApplication = p => post('/bingan/apiDeleteApplication', p);
//病案缴费
@@ -324,6 +326,16 @@ export const selectYbByPatientId = p => post('/sfs/selectYbByPatientId', p);
export const refundOrderOnline = p => post4('/Yb/refundOrderOnline', p);
//查询门诊缴费订单信息
export const selectOrderList = p => post('/sfs/selectOrderList', p);
//更新病案邮寄信息
export const apiUpdateBA = p => post('/bingan/apiUpdateBA', p);
//退费接口
export const WxRefundOrder = p => post('/pay/wxpay/refundOrder', p);
//获取线上缴费金额总数
export const SumWxBalance = p => post('/sfs/SumWxBalance', p);
//获取线上退费金额
export const DelWxBalance = p => post('/sfs/DelWxBalance', p);

View File

@@ -88,6 +88,11 @@ import ybsuccess from "../views/ybsuccess.vue";
import Zhdz_ai from "../views/Zhdz_ai.vue";
import tui from "../views/tui.vue";
import ybAUTH from "../views/ybAUTH.vue";
import Zstj_home from "../views/Zstj_home.vue";
import ZYindex2 from "../views/ZYindex2.vue";
import ZYdetail from "../views/ZYdetail.vue";
Vue.use(VueRouter);
const router = new VueRouter({
@@ -176,6 +181,14 @@ const router = new VueRouter({
title: "指南详情",
},
},
{
path: "/Zstj_home",
name: "Zstj_home",
component: Zstj_home,
meta: {
title: "体检首页",
},
},
{
path: "/Zstj",
name: "Zstj",
@@ -290,6 +303,7 @@ const router = new VueRouter({
},
},
{
path: "/Zstj_yy",
name: "Zstj_yy",
@@ -627,6 +641,22 @@ const router = new VueRouter({
meta: {
title: "住院管理",
},
},
{
path: "/ZYindex2",
name: "ZYindex2",
component: ZYindex2,
meta: {
title: "住院列表",
},
},
{
path: "/ZYdetail",
name: "ZYdetail",
component: ZYdetail,
meta: {
title: "住院详情",
},
},
{
path: "/ZYCharge",

View File

@@ -297,6 +297,10 @@
<span class="detail-label">领取方式</span>
<span class="detail-value">{{ deliveryType === '1' ? '到场自取' : '快递邮寄' }}</span>
</div>
<div class="detail-item">
<span class="detail-label">打印份数</span>
<span class="detail-value">{{ formData.copies }}</span>
</div>
<div class="detail-item">
<span class="detail-label">病人姓名</span>
<span class="detail-value">{{ formData.patientName }}</span>
@@ -421,6 +425,7 @@ export default {
recipientName: '',
recipientPhone: '',
recipientIdNumber: '',
copies: 1, // 打印份数默认1份
idFrontUrl: '',
idBackUrl: '',
recipientIdFrontUrl: '',
@@ -629,6 +634,9 @@ export default {
if (!this.deliveryType) {
errors.deliveryType = '请选择领取方式';
}
if (!this.formData.copies) {
errors.copies = '请选择打印份数';
}
break;
case 1:
@@ -795,6 +803,7 @@ export default {
formData.append('reName', this.formData.recipientName || '');
formData.append('reId', this.formData.recipientIdNumber || '');
formData.append('rePhone', this.formData.recipientPhone || '');
formData.append('copies', this.formData.copies);
const userId = localStorage.getItem("userid");
const token = localStorage.getItem("token");
@@ -867,6 +876,7 @@ export default {
recipientName: '',
recipientPhone: '',
recipientIdNumber: '',
copies: 1, // 打印份数默认1份
idFrontFile: null,
idBackFile: null,
recipientIdFrontFile: null,
@@ -1232,6 +1242,45 @@ export default {
color: #555;
}
.copies-options {
display: flex;
gap: 0.3rem;
margin-top: 0.2rem;
flex-wrap: wrap;
}
.copy-option {
display: flex;
align-items: center;
justify-content: center;
gap: 0.15rem;
cursor: pointer;
padding: 0.25rem 0.3rem;
border-radius: 0.05rem;
transition: all 0.2s;
border: 1px solid #ddd;
background-color: white;
}
.copy-option:hover {
background-color: #f5f5f5;
}
.copy-radio {
width: 0.32rem;
height: 0.32rem;
}
.copy-text {
font-size: 0.38rem;
color: #555;
}
.copy-option:has(.copy-radio:checked) {
border-color: #4299e1;
background-color: #f0f7ff;
}
.handling-option:has(.handling-radio:checked),
.delivery-option:has(.delivery-radio:checked) {
border-color: #4299e1;

View File

@@ -43,6 +43,10 @@
<span class="label">病案页数</span>
<span class="value">{{ item.pages || '等待病案室医生审核填写' }}</span>
</div>
<div class="info-row">
<span class="label">打印份数</span>
<span class="value">{{ item.copies || 1 }}</span>
</div>
<div class="info-row">
<span class="label">办理人</span>
@@ -72,9 +76,12 @@
<div class="action-buttons">
<button class="cancel-btn" v-if="canCancelApplication(item)" @click="showCancelConfirm(item)">
取消申请
取消/删除
</button>
<button class="copies-btn" v-if="item.amount !== null && item.status === 1 && item.send === 0"
@click="goToSetCopies(item)">
修改份数
</button>
<button class="pay-btn" v-if="item.amount !== null && item.status === 1 && item.send === 0"
@click="goToPayment(item)">
去缴费
@@ -111,11 +118,88 @@
</div>
</div>
</div>
<!-- 支付确认弹窗 -->
<div v-if="showPaymentConfirmDialog" class="dialog-overlay">
<div class="dialog">
<div class="dialog-header">
<h3>确认支付</h3>
</div>
<div class="dialog-content">
<p>当前费用为{{ currentItem.copies || 1 }}份的价格</p>
<p>如需修改打印份数请点击修改份数按钮调整后再缴费</p>
<p>确认按当前份数缴费吗</p>
</div>
<div class="dialog-footer">
<button class="dialog-btn cancel" @click="cancelPayment">
取消
</button>
<button class="dialog-btn confirm" @click="confirmPayment">
确认缴费
</button>
</div>
</div>
</div>
<!-- 修改份数弹窗 -->
<div v-if="showSetCopiesDialog" class="dialog-overlay">
<div class="dialog set-copies-dialog">
<div class="dialog-header">
<h3>修改打印份数</h3>
</div>
<div class="dialog-content">
<div class="copies-info">
<div class="info-item">
<span class="info-label">固定查询费</span>
<span class="info-value">¥10.00</span>
</div>
<div class="info-item">
<span class="info-label">页数</span>
<span class="info-value">{{ currentItem.pages || 0 }}</span>
</div>
<div class="info-item">
<span class="info-label">每页单价</span>
<span class="info-value">¥0.50/</span>
</div>
</div>
<div class="copies-selection">
<h4>选择打印份数</h4>
<div class="copies-controls">
<button class="copies-btn" @click="decreaseCopies">-</button>
<input type="number" v-model.number="selectedCopies" @input="onCopiesChange" min="1" class="copies-input">
<button class="copies-btn" @click="increaseCopies">+</button>
</div>
</div>
<div class="amount-calculation">
<div class="calculation-item">
<span class="calculation-label">金额计算</span>
<span class="calculation-value">
¥10.00 + ({{ currentItem.pages || 0 }} × ¥0.50/ × {{ selectedCopies }})
</span>
</div>
<div class="total-amount">
<span class="total-label">待支付金额</span>
<span class="total-value">¥{{ calculatedAmount.toFixed(2) }}</span>
</div>
</div>
</div>
<div class="dialog-footer">
<button class="dialog-btn cancel" @click="cancelSetCopies">
取消
</button>
<button class="dialog-btn confirm" @click="confirmSetCopies">
确认修改
</button>
</div>
</div>
</div>
</div>
</template>
<script>
import { apiGetBAList, apiDeleteApplication, apiBAPay, apiOpWxQuery } from "@/request/api.js";
import { apiGetBAList, apiDeleteApplication, apiBAPay, apiOpWxQuery,apiUpdateBA } from "@/request/api.js";
import { Toast } from "vant";
export default {
@@ -123,9 +207,13 @@ export default {
return {
applications: [],
showCancelDialog: false,
currentItem: null, // 存储当前要删除的item
isPaying: false, // 新增:标记是否正在支付中
showPaymentConfirmDialog: false, // 控制支付确认弹窗的显示
showSetCopiesDialog: false, // 控制修改份数弹窗的显示
currentItem: null, // 存储当前操作的item
isPaying: false, // 标记是否正在支付中
fetchTimer: null, // 定时器ID
selectedCopies: 1, // 当前选择的份数
calculatedAmount: 0, // 计算后的金额
};
},
@@ -165,7 +253,7 @@ export default {
},
canCancelApplication(item) {
return [3, 1].includes(item.status);
return [3, 1, 4].includes(item.status); // 新增:允许审核不过的申请删除
},
showCancelConfirm(item) {
@@ -204,26 +292,140 @@ export default {
this.currentItem = null;
});
},
goToSetCopies(item) {
console.log("修改份数", item);
// 保存当前要修改份数的item
this.currentItem = item;
// 初始化选择的份数为当前份数默认为1
this.selectedCopies = 1;
// 计算初始金额
this.calculateAmount();
// 显示修改份数弹窗
this.showSetCopiesDialog = true;
},
// 计算金额
calculateAmount() {
if (!this.currentItem) return;
console.log("计算金额",this.currentItem);
const fixedFee = 10; // 固定查询费10元
const pageFee = 0.5; // 每页0.5元
const pages = this.currentItem.pages || 0; // 页数
const copies = this.selectedCopies || 1; // 份数
// 计算总金额:固定查询费 + 页数x每页费用x份数
this.calculatedAmount = fixedFee + (pages * pageFee * copies);
},
// 增加份数
increaseCopies() {
this.selectedCopies++;
this.calculateAmount();
},
// 减少份数
decreaseCopies() {
if (this.selectedCopies > 1) {
this.selectedCopies--;
this.calculateAmount();
}
},
// 输入份数变化
onCopiesChange(event) {
let value = parseInt(event.target.value);
// 确保份数至少为1
if (isNaN(value) || value < 1) {
value = 1;
}
this.selectedCopies = value;
this.calculateAmount();
},
// 确认修改份数
confirmSetCopies() {
if (!this.currentItem) return;
console.log("更新当前item的选择份数",this.selectedCopies)
console.log("更新当前item的金额",this.calculatedAmount)
this.currentItem.amount = this.calculatedAmount;
this.currentItem.copies = this.selectedCopies;
let params = {
"id": this.currentItem.id,
"copies": this.selectedCopies,
"amount": this.calculatedAmount,
}
// console.log("更新当前item的选择份数",params)
apiUpdateBA(params).then(res => {
if (res.code === 200) {
// 关闭弹窗
this.showSetCopiesDialog = false;
// 提示用户修改成功
Toast.success(`份数已修改为${this.selectedCopies}份,金额已更新`);
this.fetchApplications(); // 重新获取列表数据
} else {
Toast(`修改失败:${res.message || '服务器异常'}`);
}
}).catch(err => {
console.error('修改接口调用失败:', err);
Toast('网络异常,修改失败,请稍后重试');
});
// this.currentItem.pages = this.currentItem.pages*this.selectedCopies;
},
// 取消修改份数
cancelSetCopies() {
// 关闭弹窗
this.showSetCopiesDialog = false;
},
goToPayment(item) {
// 防止重复点击:如果正在支付中,直接返回
if (this.isPaying) return;
// 保存当前要支付的item
this.currentItem = item;
// 显示支付确认弹窗
this.showPaymentConfirmDialog = true;
},
console.log("去支付", item);
this.isPaying = true; // 标记为支付中
// 显示加载中Toast
Toast.loading({
forbidClick: true, // 禁止背景点击
message: '处理中...',
duration: 0 // 不自动关闭
});
this.handleWechatPay(item);
// 确认支付
confirmPayment() {
// 检查当前时间是否在23:00-00:01之间这个时间段内禁止充值
const now = new Date();
const hours = now.getHours();
const minutes = now.getMinutes();
if ((hours === 23 && minutes >= 0) || (hours === 0 && minutes <= 1)) {
Toast({
message: '当前时间段(23:00-00:01)正在对账暂不支持支付操作请0点过后再试',
duration: 5000
});
return;
}
// 防止重复点击:如果正在支付中,直接返回
if (this.isPaying) return;
console.log("去支付", this.currentItem);
this.isPaying = true; // 标记为支付中
// 显示加载中Toast
Toast.loading({
forbidClick: true, // 禁止背景点击
message: '处理中...',
duration: 0 // 不自动关闭
});
this.handleWechatPay(this.currentItem);
// 关闭弹窗
this.showPaymentConfirmDialog = false;
},
// 取消支付
cancelPayment() {
// 关闭弹窗
this.showPaymentConfirmDialog = false;
},
handleWechatPay(item) {
let params = {
id: item.id,
amount: item.amount,
pages: item.pages,
pages: item.pages*item.copies,
selectAmount: item.selectAmount,
userId: item.userId
}
@@ -430,6 +632,7 @@ export default {
if (item.status === 2) return 'paid';
if (item.amount !== null && item.status === 1) return 'unpaid';
if (item.amount === null && item.status === 3) return 'pending';
if (item.status === 4) return 'rejected'; // 新增:审核不过状态
return null;
},
@@ -440,7 +643,8 @@ export default {
unpaid: '待支付',
paid: '已支付',
picked: '已自取',
shipped: '已邮寄'
shipped: '已邮寄',
rejected: '审核未通过' // 新增:审核不过文本
};
return texts[type] || '';
},
@@ -492,6 +696,19 @@ export default {
background-color: #096dd9;
}
}
.copies-btn {
background-color: #fa8c16;
color: white;
border: none;
border-radius: 0.08rem;
padding: 0.15rem 0.35rem;
font-size: 0.35rem;
cursor: pointer;
transition: background-color 0.2s;
&:hover {
background-color: #d46b08;
}
}
.ship-btn {
background-color: #52c41a;
@@ -615,6 +832,12 @@ export default {
background-color: rgba(140, 140, 140, 0.05);
}
.watermark.rejected {
color: #ff4d4f;
border-color: #ff4d4f;
background-color: rgba(255, 77, 79, 0.05);
}
.info-row {
display: flex;
margin-bottom: 0.25rem;
@@ -768,6 +991,99 @@ export default {
}
}
/* 修改份数弹窗样式 */
.set-copies-dialog {
width: 90%;
max-width: 500px;
}
.copies-info {
background-color: #f8f9fa;
padding: 0.3rem;
border-radius: 0.08rem;
margin-bottom: 0.4rem;
}
.info-item {
display: flex;
justify-content: space-between;
margin-bottom: 0.15rem;
font-size: 0.35rem;
}
.info-item:last-child {
margin-bottom: 0;
}
.info-label {
color: #666;
}
.info-value {
color: #333;
font-weight: 500;
}
.copies-selection {
margin-bottom: 0.4rem;
}
.copies-selection h4 {
margin-bottom: 0.2rem;
font-size: 0.38rem;
color: #333;
}
.copies-controls {
display: flex;
align-items: center;
justify-content: center;
gap: 0.2rem;
}
.copies-input {
width: 1.2rem;
height: 0.6rem;
text-align: center;
font-size: 0.38rem;
border: 1px solid #ddd;
border-radius: 0.08rem;
padding: 0;
box-sizing: border-box;
}
.amount-calculation {
background-color: #e6f7ff;
padding: 0.3rem;
border-radius: 0.08rem;
margin-bottom: 0.3rem;
}
.calculation-item {
margin-bottom: 0.15rem;
font-size: 0.35rem;
color: #333;
}
.total-amount {
display: flex;
justify-content: space-between;
align-items: center;
padding-top: 0.2rem;
border-top: 1px solid #bae7ff;
font-size: 0.4rem;
font-weight: 600;
}
.total-label {
color: #333;
}
.total-value {
color: #f5222d;
font-size: 0.45rem;
}
@keyframes fadeIn {
from {
opacity: 0;

View File

@@ -358,14 +358,14 @@ export default {
Toast("请选择支付方式");
return;
}
// 检查当前时间是否在23:48-00:01之间这个时间段内禁止充值
// 检查当前时间是否在23:00-00:01之间这个时间段内禁止充值
const now = new Date();
const hours = now.getHours();
const minutes = now.getMinutes();
if ((hours === 23 && minutes >= 48) || (hours === 0 && minutes <= 1)) {
if ((hours === 23 && minutes >= 0) || (hours === 0 && minutes <= 1)) {
Toast({
message: '当前时间段(23:48-00:01)正在对账暂不支持支付操作请0点过后再试',
message: '当前时间段(23:00-00:01)正在对账暂不支持支付操作请0点过后再试',
duration: 5000
});
return;

View File

@@ -79,15 +79,15 @@
</router-link>
</li>
<li>
<router-link to="ZYindex">
<router-link to="ZYindex2">
<img src="../assets/住院管理-功能按键.png" alt="住院管理" />
</router-link>
</li>
</ul>
</div>
<router-link to="/jkzd" class="gg_image">
<img src="../assets/健康体检.png"/>
<router-link to="/Zstj_home" class="gg_image">
<img src="../assets/健康体检2.png"/>
</router-link>
<div class="in_box1">
<div class="bt">
@@ -104,9 +104,9 @@
<img src="../assets/in_box1_pic1.png" alt/>
<p>就诊须知</p>
</router-link>
<router-link to="Zstj_yy">
<router-link to="Member_pdjh">
<img src="../assets/in_box1_pic2.png" alt/>
<p>体检预约</p>
<p>排队叫号信息</p>
</router-link>
<router-link to="jkzd">
<img src="../assets/in_box1_pic3.png" alt/>
@@ -133,6 +133,18 @@
<img src="../assets/in_box1_pic4.png" alt/>
<p>满意度评价</p>
</router-link>
<router-link to="Wjcx" class="service-item">
<img src="../assets/in_box1_pic5.png" alt/>
<p>物价查询</p>
</router-link>
<router-link to="Hospital_dh1" class="service-item">
<img src="../assets/in_box1_pic6.png" alt/>
<p>地图导航</p>
</router-link>
<router-link to="Yylb" class="service-item">
<img src="../assets/in_box1_pic7.png" alt/>
<p>挂号记录</p>
</router-link>
<!-- 其他服务项 -->
</div>
</div>

View File

@@ -262,9 +262,9 @@ export default {
const hours = now.getHours();
const minutes = now.getMinutes();
if ((hours === 23 && minutes >= 48) || (hours === 0 && minutes <= 1)) {
if ((hours === 23 && minutes >= 0) || (hours === 0 && minutes <= 1)) {
Toast({
message: '当前时间段(23:48-00:01)正在对账暂不支持支付操作请0点过后再试',
message: '当前时间段(23:00-00:01)正在对账暂不支持支付操作请0点过后再试',
duration: 5000
});
return;

View File

@@ -230,7 +230,7 @@ export default {
apiUserInfo().then((res) => {
console.log(res.data);
this.info = res.data;
if (res.data.role === 1) {
if (res.data.role >= 1) {
this.hasDataCockpitPermission = true;
}
});

View File

@@ -133,7 +133,8 @@ beforeDestroy() {
this.list = res.DiagnosticInfos || [];
// 按签到时间倒序排列(最新的在前面)
this.list.sort((a, b) => {
return new Date(`2025-10-29 ${b.DiagnosticOrderTime}`) - new Date(`2025-10-29 ${a.DiagnosticOrderTime}`);
// 修复iOS日期兼容性问题
return new Date(`2025/10/29 ${b.DiagnosticOrderTime}`) - new Date(`2025/10/29 ${a.DiagnosticOrderTime}`);
});
this.finished = true;
} else {

View File

@@ -506,12 +506,17 @@ console.log(item);
let that = this;
that.list = [];
that.lislist = [];
// 计算加1天后的结束日期
let endDate = new Date(that.enddate);
endDate.setDate(endDate.getDate() + 1);
let formattedEndDate = that.formatDate(endDate);
let formData = {
QueryCode: that.card.cardNo,
//QueryCode:"0001238384",
QueryType: 1,
StartTime: that.startdate + " 00:00:00",
EndTime: that.enddate + " 23:59:59",
EndTime: formattedEndDate+ " 23:59:59",
};
if (that.card.cardNo == null) {
Toast("请选择就诊人");

View File

@@ -100,7 +100,7 @@
<p>{{ item.DOCTORNAME }}</p>
<p>
就诊时间{{
item.REGISTERDATE.split(" ")[0] + " " + item.TIMEINTERVAL
item.REGISTERDATE.split(" ")[0] + " " + getTime(item.TIMEINTERVAL)
}}
</p>
<!--em>{{item.OrderNo}}</em-->
@@ -171,6 +171,17 @@ let that = this;
that.getList();
}
},
// 解析日期兼容iOS
parseDate(dateStr) {
if (!dateStr) return new Date();
// 替换掉"-"分隔符为"/"以兼容iOS
if (dateStr.indexOf('-') > -1 && dateStr.indexOf('T') === -1) {
dateStr = dateStr.replace(/-/g, '/');
}
return new Date(dateStr);
},
getTime(time) {
switch (time) {
case "AM":
@@ -240,6 +251,10 @@ let that = this;
console.log(res);
if (res.data != null) {
_this.list = res.data;
// 添加排序:按就诊时间从近到远(距离最近的排最上面)
_this.list.sort((a, b) => {
return _this.parseDate(b.REGISTERDATE) - _this.parseDate(a.REGISTERDATE);
});
}
});
} else {
@@ -263,6 +278,28 @@ let that = this;
} else {
_this.list.push(jsonObj2.response.data.data_row);
}
// 添加排序:按就诊时间从近到远(距离最近的排最上面)
_this.list.sort((a, b) => {
// 将日期和时间段组合成可比较的日期对象
const timeWeight = {
'AM': 0,
'PM': 1,
'AL': 0.5,
'NT': 2
};
const dateA = _this.parseDate(a.REGISTERDATE);
const dateB = _this.parseDate(b.REGISTERDATE);
// 先比较日期(最近的排在前面)
if (dateA.getTime() !== dateB.getTime()) {
return dateB - dateA;
}
// 日期相同时,比较时间段(上午在前,下午在后)
return (timeWeight[a.TIMEINTERVAL] || 0) - (timeWeight[b.TIMEINTERVAL] || 0);
});
}
});
}

View File

@@ -41,6 +41,10 @@
<h2>挂号金额</h2>
<h3>¥{{ money }}</h3>
</li>
<li>
<h2>挂号来源</h2>
<h3>{{ RefundSTATE == 'Y' ? '公众号' : ZZJ == 'Y' ? '自助机' : '收费室' }}</h3>
</li>
</ul>
</div>
@@ -59,13 +63,13 @@
线下就诊需通过该码到自助机/报到机处点击就诊签到扫码签到排号
</p>
<van-button
<div class="btn-group">
<van-button
class="btn"
color="#166bcc"
:loading="loading"
type="primary"
loading-text="处理中..."
style="margin-bottom: 15px;"
@click="handleCancel2"
v-if="RefundSTATE == 'Y'"
>
@@ -84,6 +88,17 @@
</van-button>
<van-button
class="btn"
color="#166bcc"
:loading="loading"
type="primary"
loading-text="处理中..."
@click="handleSignIn"
v-if="RefundSTATE == 'Y'"
>
线上签到
</van-button>
<van-button
class="btn"
color="#166bcc"
:loading="loading"
@@ -94,6 +109,9 @@
>
取消
</van-button>
</div>
<!-- 遮罩层加载效果 -->
<van-overlay :show="show" z-index="999">
@@ -130,6 +148,8 @@ export default {
status: '',
RefundSTATE: 'N',
CancleSTATE: 'N',
ZZJ:'N',//自助机
SFS:'N',//收费室
PowerTranID: '',
OrderNo: '',
paytype: '',
@@ -165,6 +185,12 @@ export default {
}
},
methods: {
handleSignIn() {
Toast({
message: '目前请到自助机/签到机上进行签到',
duration: 5000
});
},
CancelGH() {
this.show = true;
apiopRegisterCancel({ hisorderno: this.OrderNo })
@@ -197,6 +223,10 @@ export default {
this.PowerTranID = data.data.PowerTranID;
this.paytype = data.data.PayType;
this.hisopernum = data.data.HisOperNum;
}else if(data.data.HisOperNum === "zzj"){
this.ZZJ = 'Y';
}else{
this.SFS = 'Y';
}
}
})
@@ -368,12 +398,17 @@ export default {
}
}
.btn-group {
display: flex;
justify-content: space-between;
padding: 0 .3rem;
}
.btn {
width: 90%;
margin: 10px auto 0;
// margin-top: 1rem;
flex: 1;
margin: .2rem .3rem 0;
border-radius: 0.375rem;
display: block;
min-width: 0;
}
.qrcode {

View File

@@ -1,8 +1,8 @@
<template>
<div class="home">
<nav-bar></nav-bar>
<div class="lxr" @click="handleCardSelect">
<div class="lxrr" v-if="card && card.id">
<div class="lxr" @click="handleCardSelect" v-if="card && card.id">
<div class="lxrr">
<h2>
{{ card.name }}
<p>卡号{{ card.cardNo }}</p>
@@ -11,7 +11,6 @@
<i class="van-icon van-icon-arrow van-cell__right-icon"></i>
</h3>
</div>
<van-contact-card type="add" add-text="请选择就诊人" v-else />
</div>
<div v-if="showbox">
<van-cell-group class="cell_box">
@@ -39,17 +38,17 @@
<h2>3000</h2>
</div>
</div>
<div class="chargemoneybox2">
<!-- <div class="chargemoneybox2">
<div :class="this.chargemoney == 4000 ? 'box1' : 'box'" @click="clickmoney(4000)">
<h2>4000</h2>
</div>
<div :class="this.chargemoney == 5000 ? 'box1' : 'box'" @click="clickmoney(5000)">
<h2>5000</h2>
</div>
<!-- <div :class="this.chargemoney == 8000 ? 'box1' : 'box'" @click="clickmoney(8000)">
<div :class="this.chargemoney == 8000 ? 'box1' : 'box'" @click="clickmoney(8000)">
<h2>8000</h2>
</div> -->
</div>
</div>
</div> -->
</div>
<van-cell-group>
<van-field type="number" v-model="qtchargemoney" label="其他金额" class="qtchargemoneybt" placeholder="请输入金额"
@@ -132,7 +131,7 @@ export default {
Dialog.alert({
title: '住院预交金缴纳须知',
messageAlign: 'left',
message: '尊敬的患者及家属:\n\n现就住院预交金缴纳事宜告知如下\n\n1、办理住院 24 小时内,暂不支持线上缴预交金,需充值请前往住院收费窗口办理。\n2、24 小时后可通过掌上医院缴费,但每位患者每日最高限 5000 元;超 5000 元需到窗口办理。\n3、窗口办理请携带患者有效身份证件、住院病历号或押金单疑问可咨询护士站或收费窗口。\n\n感谢配合祝您早日康复'
message: '尊敬的患者及家属:\n\n现就住院预交金缴纳事宜告知如下\n\n1、办理住院 24 小时内,暂不支持线上缴预交金,需充值请前往住院收费窗口办理。\n2、24 小时后可通过掌上医院缴费,但每位患者每日最高限 3000 元;超 3000 元需到窗口办理。\n3、窗口办理请携带患者有效身份证件、住院病历号或押金单疑问可咨询护士站或收费窗口。\n\n感谢配合祝您早日康复'
}).then(() => {
// 弹窗关闭后的回调操作
});
@@ -162,11 +161,45 @@ export default {
patientIds: [], // 存储多个 PatientId
patientId: null, // 选中的 PatientId
showPatientSelector: false,
yjjxes :5000
yjjxes :3000//限额修改
};
},
created() {
// 优先检查是否有 hospitalizationItem 数据
const hospitalizationItem = sessionStorage.getItem('hospitalizationItem');
if (hospitalizationItem) {
const item = JSON.parse(hospitalizationItem);
this.patientId = item.INHOSPATIENTID; // 使用 INHOSPATIENTID 作为 patientId
this.zyinfo = {
INHOSNUM: item.INHOSNUM,
PATIENTNAME: item.PATIENTNAME,
PATIENTSEX: item.PATIENTSEX,
BIRTHDAY: item.BIRTHDAY,
PHONENUM: item.PHONENUM,
ADDRESS: item.ADDRESS,
IDCARDNO: item.IDCARDNO,
DEPARTCODE: item.DEPARTCODE,
DEPTNAME: item.DEPTNAME || item.SECTIONTYPE,
BEDNO: item.BEDNO,
HOSDATE: item.HOSDATE,
OUTHOSDATE: item.OUTHOSDATE,
HOSSTATE: item.HOSSTATE,
HOSBALANCE: item.HOSBALANCE,
PATIENTSOURCE: item.PATIENTSOURCE,
};
// 获取预交金限额
this.yjjxe().then((res) => {
this.zyinfo.YJJKC = this.yjjxes - res;
this.showbox = true;
}).catch(() => {
// 如果获取限额失败仍然显示页面但限额默认为3000
this.zyinfo.YJJKC = this.yjjxes;
this.showbox = true;
});
return;
}
// 如果没有 hospitalizationItem 数据,执行原来的逻辑
this.card = JSON.parse(sessionStorage.getItem("card"));
if (this.card) {
this.getZYInfo();
@@ -213,9 +246,9 @@ return;
const hours = now.getHours();
const minutes = now.getMinutes();
if ((hours === 23 && minutes >= 48) || (hours === 0 && minutes <= 1)) {
if ((hours === 23 && minutes >= 0) || (hours === 0 && minutes <= 1)) {
Toast({
message: '当前时间段(23:48-00:01)正在对账暂不支持支付操作请0点过后再试',
message: '当前时间段(23:00-00:01)正在对账暂不支持支付操作请0点过后再试',
duration: 5000
});
return;
@@ -233,13 +266,13 @@ return;
// });
}
if(this.patientId != "90134173"){
Toast({
message: '因医院原因,暂时不开放线上充值预交金功能,请到门诊缴费窗口充值!',
duration: 3000 // 设置显示时长为 3 秒
});
return;
}
// if(this.patientId != "90134173"){
// Toast({
// message: '因医院原因,暂时不开放线上充值预交金功能,请到门诊缴费窗口充值!',
// duration: 3000 // 设置显示时长为 3 秒
// });
// return;
// }
if(this.zyinfo.HOSDATE ){
@@ -487,11 +520,13 @@ return;
if (jsonObj2.response.returnresult.returncode == "1") {
if (Array.isArray(dataRows)) {
for (var i = 0; i < dataRows.length; i++) {
if (dataRows[i].HOSSTATE == "0" || dataRows[i].HOSSTATE == "") {
// 创建一个局部变量保存当前的 dataRow
let currentDataRow = dataRows[i];
if (currentDataRow.HOSSTATE == "0" || currentDataRow.HOSSTATE == "") {
_this.yjjxe().then(money => {
dataRows[i].YJJKC = _this.yjjxes - money;
_this.zyinfo = dataRows[i];
_this.showbox = true;
currentDataRow.YJJKC = _this.yjjxes - money;
_this.zyinfo = currentDataRow;
_this.showbox = true;
});
}
}

View File

@@ -2,8 +2,8 @@
<div class="home">
<nav-bar></nav-bar>
<div class="bj"></div>
<div class="lxr" @click="handleCardSelect">
<div class="lxrr" v-if="card && card.id">
<div class="lxr" @click="handleCardSelect" v-if="card && card.id">
<div class="lxrr">
<h2>
{{ card.name }}
<p>卡号{{ card.cardNo }}</p>
@@ -12,7 +12,6 @@
<i class="van-icon van-icon-arrow van-cell__right-icon"></i>
</h3>
</div>
<van-contact-card type="add" add-text="请选择就诊人" v-else />
</div>
<div v-if="showbox">
<div class="cellbody">
@@ -79,7 +78,7 @@
<div class="listbt">{{ startdate }}{{ enddate }}清单</div>
<div class="listbody">
<div class="scrollable-content">
<van-row>
<van-row class="header-row">
<van-col span="9" class="colblack">项目名称</van-col>
<van-col span="3" class="colblack">类型</van-col>
<van-col span="3" class="colblack">单价</van-col>
@@ -87,18 +86,29 @@
<van-col span="3" class="colblack">单位</van-col>
<van-col span="3" class="colblack">总价</van-col>
</van-row>
<van-row v-for="item in List" :key="item">
<van-col span="9" class="colgray">{{ item.ITEMNAME }}</van-col>
<van-col span="3" class="colgray">{{ item.ACCTYPE }}</van-col>
<van-col span="3" class="colgray">{{ item.ITEMPRICE }}</van-col>
<van-col span="3" class="colgray">{{ item.ITEMCOUNT }}</van-col>
<van-col span="3" class="colgray">{{ item.ITEMUNIT }}</van-col>
<van-col span="3" class="colgray">{{ item.ITEMAMOUNT }}</van-col>
</van-row>
<!-- 按日期分组显示 -->
<div v-for="group in groupedList" :key="group.date" class="date-group">
<!-- 日期标题栏 -->
<div class="date-header">
<span class="date-text">{{ group.date }}收费如下:</span>
<span class="daily-total">当日合计{{ group.total }}</span>
</div>
<!-- 当日费用明细 -->
<van-row v-for="item in group.items" :key="item" class="item-row">
<van-col span="9" class="colgray">{{ item.ITEMNAME }}</van-col>
<van-col span="3" class="colgray">{{ item.ACCTYPE }}</van-col>
<van-col span="3" class="colgray">{{ item.ITEMPRICE }}</van-col>
<van-col span="3" class="colgray">{{ item.ITEMCOUNT }}</van-col>
<van-col span="3" class="colgray">{{ item.ITEMUNIT }}</van-col>
<van-col span="3" class="colgray">{{ item.ITEMAMOUNT }}</van-col>
</van-row>
</div>
</div>
<van-row class="fixed-total">
<van-col offset="14" span="10" class="colblack">合计{{ money }}
<van-col span="24" class="colblack text-right">{{ startdate }}{{ enddate }}合计{{ money }}
</van-col>
</van-row>
@@ -161,9 +171,39 @@ export default {
patientIds: [],
patientId: "",
showPatientSelector: false, // 控制是否显示选择弹窗
groupedList: [], // 按日期分组后的费用明细
};
},
created() {
// 首先检查 sessionStorage 中是否有 hospitalizationItem 数据
const hospitalizationItem = sessionStorage.getItem('hospitalizationItem');
if (hospitalizationItem) {
const item = JSON.parse(hospitalizationItem);
this.INHOSNUM = item.INHOSNUM;
this.zyinfo = {
INHOSNUM: item.INHOSNUM,
PATIENTNAME: item.PATIENTNAME,
PATIENTSEX: item.PATIENTSEX,
BIRTHDAY: item.BIRTHDAY,
PHONENUM: item.PHONENUM,
ADDRESS: item.ADDRESS,
IDCARDNO: item.IDCARDNO,
DEPARTCODE: item.DEPARTCODE,
DEPTNAME: item.DEPTNAME,
BEDNO: item.BEDNO,
HOSDATE: item.HOSDATE,
OUTHOSDATE: item.OUTHOSDATE,
HOSSTATE: item.HOSSTATE,
HOSBALANCE: item.HOSBALANCE,
PATIENTSOURCE: item.PATIENTSOURCE,
};
this.startdate = this.formatDate(item.HOSDATE);
this.enddate = this.formatDate(item.OUTHOSDATE);
this.showbox = true;
return;
}
// 如果没有 hospitalizationItem 数据,执行原来的逻辑
this.card = JSON.parse(sessionStorage.getItem("card"));
if (this.card) {
this.getZYInfo();
@@ -287,10 +327,31 @@ export default {
});
},
formatDate(date) {
let year = date.getFullYear();
let month = date.getMonth() + 1;
// 处理空值、undefined、null 或空字符串
if (!date || date === '') {
return '';
}
let dateObj;
if (typeof date === 'string') {
// 如果是字符串,将空格替换为 'T' 以兼容 iOS然后创建 Date 对象
dateObj = new Date(date.replace(' ', 'T'));
} else if (date instanceof Date) {
// 如果是 Date 对象,直接使用
dateObj = date;
} else {
return '';
}
// 检查是否是有效的日期
if (isNaN(dateObj.getTime())) {
return '';
}
let year = dateObj.getFullYear();
let month = dateObj.getMonth() + 1;
month = month > 9 ? month : "0" + month;
let day = date.getDate();
let day = dateObj.getDate();
day = day > 9 ? day : "0" + day;
return year + "-" + month + "-" + day;
}
@@ -339,15 +400,38 @@ export default {
// 检查数据是否存在
if (jsonObj2 && jsonObj2.response && jsonObj2.response.data && jsonObj2.response.data.data_row && jsonObj2.response.data.data_row.length > 0) {
that.List = jsonObj2.response.data.data_row;
// 原始数据列表
const originalList = jsonObj2.response.data.data_row;
// 按日期分组
const groupedData = {};
originalList.forEach(item => {
// 假设TRDATETIME格式为YYYY-MM-DD HH:MM:SS提取日期部分"2026-01-12 23:00:14"
const date = item.TRDATETIME ? item.TRDATETIME.split(' ')[0] : '未知日期';
if (!groupedData[date]) {
groupedData[date] = {
date: date,
items: [],
total: 0
};
}
groupedData[date].items.push(item);
groupedData[date].total = (parseFloat(groupedData[date].total) + parseFloat(item.ITEMAMOUNT)).toFixed(2);
});
// 转换为数组格式
that.groupedList = Object.values(groupedData).sort((a, b) => new Date(a.date) - new Date(b.date));
// 计算总金额
that.money = 0;
for (let i = 0; i < jsonObj2.response.data.data_row.length; i++) {
that.money = (parseFloat(that.money) + parseFloat(jsonObj2.response.data.data_row[i].ITEMAMOUNT)).toFixed(2);
}
that.groupedList.forEach(group => {
that.money = (parseFloat(that.money) + parseFloat(group.total)).toFixed(2);
});
that.resultshow = true;
} else {
// 数据为空的情况
that.List = [];
that.groupedList = [];
that.money = 0;
that.resultshow = true;
Toast("暂无该时间段收费详情信息");
@@ -512,7 +596,7 @@ export default {
font-family: PingFang SC;
background-color: #fff;
border-radius: 15px;
padding: 0 0 0 0.5rem;
.van-row {
padding: 20px 0;
}
@@ -558,16 +642,58 @@ export default {
overflow-y: auto;
flex: 1;
.van-row {
.header-row {
padding: 15px 0;
border-bottom: 2px solid #ddd;
}
.date-group {
margin-bottom: 20px;
border: 1px solid #f0f0f0;
border-radius: 8px;
overflow: hidden;
}
.date-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 15px;
background-color: #f5f5f5;
font-weight: 600;
border-bottom: 1px solid #eee;
}
.date-text {
font-size: 28px;
color: #333;
}
.daily-total {
font-size: 26px;
color: #166bcc;
}
.item-row {
padding: 10px 0;
border-bottom: 1px solid #f0f0f0;
&:last-child {
border-bottom: none;
}
}
}
.fixed-total {
flex-shrink: 0; // 防止压缩
padding: 20px 0;
border-top: 1px solid #eee;
//padding: 20px;
border-top: 2px solid #ddd;
background-color: #fff;
font-size: 32px;
}
.text-right {
text-align: right;
}
}
</style>

299
src/views/ZYdetail.vue Normal file
View File

@@ -0,0 +1,299 @@
<template>
<div class="home">
<nav-bar></nav-bar>
<div class="bj"></div>
<!-- 顶部信息区域 -->
<div class="header-info" v-if="hospitalizationItem">
<div class="info-header">
<div class="info-left">
<div class="info-item">
<span class="info-label">住院号</span>
<span class="info-value">{{ hospitalizationItem.INHOSNUM }}</span>
</div>
<div class="info-item">
<span class="info-label">姓名</span>
<span class="info-value">{{ hospitalizationItem.PATIENTNAME }}</span>
</div>
<div class="info-item">
<span class="info-label">住院科室</span>
<span class="info-value">{{ hospitalizationItem.SECTIONTYPE }}</span>
</div>
</div>
<!-- 修改点1替换Vant Tag为自定义状态标签删除van-tag相关代码 -->
<div class="info-right">
<div class="state-tag state-tag--out" v-if="hospitalizationItem.HOSSTATE == '2'">已出院</div>
<div class="state-tag state-tag--in" v-else>住院中</div>
</div>
</div>
<!-- 费用信息 -->
<div class="cost-info">
<div class="cost-item">
<span class="cost-value">{{ hospitalizationItem.HOSBALANCE }}</span>
<span class="cost-label">可用余额</span>
</div>
<div class="cost-item">
<span class="cost-value">{{ hospitalizationItem.BEDNO || '暂无' }}</span>
<span class="cost-label">病床号</span>
</div>
<div class="cost-item">
<span class="cost-value">{{ hospitalizationItem.PATIENTSOURCE == '1' ? '门诊患者' : '转诊患者' }}</span>
<span class="cost-label">患者来源</span>
</div>
</div>
</div>
<!-- 业务办理模块 -->
<div class="business-section">
<h3 class="section-title">业务办理</h3>
<div class="business-item" @click="navigateToZYCharge">
<div class="business-icon">
<img src="../assets/预交金.png" alt="预交金查询" />
</div>
<div class="business-content">
<h4 class="business-title">我的预交金</h4>
<p class="business-desc">查询充值记录在线充值预交金</p>
</div>
<van-icon name="arrow" class="business-arrow" />
</div>
<div class="business-item" @click="navigateToZYdailylist">
<div class="business-icon">
<img src="../assets/住院费用清单.png" alt="日清单查询" />
</div>
<div class="business-content">
<h4 class="business-title">日清单查询</h4>
<p class="business-desc">每日费用明细</p>
</div>
<van-icon name="arrow" class="business-arrow" />
</div>
</div>
</template>
<script>
import Vue from "vue";
import { Icon } from "vant"; // 【修改点2】删除Tag的引入只保留Icon即可
Vue.use(Icon); // 【修改点3】只注册Icon删除Tag的注册
export default {
mounted() {
this.title = this.$route.meta.title;
},
computed: {},
data() {
return {
title: "住院详情",
hospitalizationItem: null
};
},
created() {
const item = sessionStorage.getItem('hospitalizationItem');
if (item) {
this.hospitalizationItem = JSON.parse(item);
}
},
methods: {
navigateToZYCharge() {
sessionStorage.setItem('hospitalizationItem', JSON.stringify(this.hospitalizationItem));
this.$router.push({ path: "/ZYCharge" });
},
navigateToZYdailylist() {
sessionStorage.setItem('hospitalizationItem', JSON.stringify(this.hospitalizationItem));
this.$router.push({ path: "/ZYdailylist" });
}
}
}
</script>
<style scoped lang="scss">
// 背景样式
.bj {
background: #f5f5f5;
position: fixed;
width: 100%;
height: 100%;
top: 0px;
left: 0px;
z-index: -2;
}
// 顶部信息区域
.header-info {
background-color: #d4e8ff;
background-image: linear-gradient(#d4e8ff, #e7f1fe);
border-radius: 15px;
margin: 15px;
padding: 20px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}
.info-header {
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-bottom: 20px;
}
.info-left {
flex: 1;
}
.info-item {
margin-bottom: 12px;
font-size: .4rem;
}
.info-item:first-child{
font-size: .45rem;
font-weight: 700;
}
.info-item:first-child .info-value{
color: black;
font-weight: 700;
}
.info-item:first-child .info-label{
color: black;
font-weight: 700;
}
.info-label {
color: #666;
margin-right: 10px;
}
.info-value {
color: #333;
font-weight: 500;
}
.info-right {
margin-left: 15px;
// 让标签垂直靠上对齐,和左侧信息匹配
display: flex;
align-items: flex-start;
}
// 【新增核心样式】自定义状态标签(住院中/已出院)
.state-tag {
display: inline-flex;
align-items: center;
gap: 4px; // 圆点和文字的间距
padding: 4px 12px; // 内边距,上下小左右大,更精致
font-size: .36rem; // 适配移动端的字体大小
font-weight: 500;
border-radius: 20px; // 超大圆角,柔化边缘
white-space: nowrap; // 防止文字换行
// 状态小圆点的通用样式
&::before {
content: '';
display: block;
width: 6px;
height: 6px;
border-radius: 50%; // 圆形圆点
}
}
// 住院中标签样式
.state-tag--in {
background-color: #e6f7ef;
color: #36c779;
&::before {
background-color: #36c779; // 圆点和文字同色,视觉统一
}
}
// 已出院标签样式
.state-tag--out {
background-color: #f5f2f8;
color: #9061c7;
&::before {
background-color: #9061c7;
}
}
// 费用信息
.cost-info {
display: flex;
justify-content: space-around;
padding-top: 15px;
border-top: 1px solid #f0f0f0;
}
.cost-item {
text-align: center;
}
.cost-value {
display: block;
font-size: .44rem;
font-weight: 600;
color: #2196F3;
margin-bottom: 5px;
}
.cost-label {
font-size: .35rem;
color: #666;
}
// 业务办理模块
.business-section {
background-color: #fff;
border-radius: 15px;
margin: 0 15px 15px;
padding: 20px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}
.section-title {
font-size: 26px;
font-weight: 600;
color: #333;
margin: 0 0 20px;
}
.business-item {
display: flex;
align-items: center;
padding: .5rem 0;
border-bottom: 2px solid #f0f0f0;
margin: 5px 0;
}
.business-item:last-child {
border-bottom: none;
}
.business-icon {
width: 1rem;
height: 1rem;
border-radius: 50%;
background-color: #E3F2FD;
display: flex;
align-items: center;
justify-content: center;
margin-right: 15px;
img {
width: .6rem;
object-fit: contain;
}
}
.business-content {
flex: 1;
}
.business-title {
font-size: .4rem;
font-weight: 500;
color: #333;
margin: 0 0 5px;
}
.business-desc {
font-size: .32rem;
color: #999;
margin: 0;
}
.business-arrow {
font-size: .4rem;
color: #1296db;
}
</style>

817
src/views/ZYindex2.vue Normal file
View File

@@ -0,0 +1,817 @@
<template>
<div class="home">
<nav-bar></nav-bar>
<div class="bj"></div>
<div class="lxr" @click="handleCardSelect">
<div class="lxrr" v-if="card && card.id">
<h2>
{{ card.name }}
<p>卡号{{ card.cardNo }}</p>
</h2>
<h3>
<i class="van-icon van-icon-arrow van-cell__right-icon"></i>
</h3>
</div>
<van-contact-card type="add" add-text="请选择就诊人" v-else />
</div>
<div v-if="showbox">
<div class="header-section">
<h3 class="list-title">住院信息</h3>
<span class="filter-text" @click="showFilter = true">筛选</span>
</div>
<!-- 筛选弹窗 -->
<van-popup v-model="showFilter" position="bottom" :style="{ height: '50%' }">
<div class="filter-popup">
<div class="filter-header">
<h4>筛选条件</h4>
<van-icon name="cross" @click="showFilter = false" class="close-icon" />
</div>
<div class="filter-content">
<div class="filter-item">
<span class="filter-label">住院状态</span>
<van-radio-group v-model="filterState">
<van-radio name="">全部</van-radio>
<van-radio name="hospitalized">住院中</van-radio>
<van-radio name="discharged">已出院</van-radio>
</van-radio-group>
</div>
<div class="filter-item">
<span class="filter-label">住院病区</span>
<van-dropdown-menu>
<van-dropdown-item v-model="filterDepartment" :options="departmentOptions" placeholder="全部" />
</van-dropdown-menu>
</div>
<div class="filter-item">
<span class="filter-label">住院时间范围</span>
<van-radio-group v-model="filterTimeRange">
<van-radio name="">全部</van-radio>
<van-radio name="7">近7天</van-radio>
<van-radio name="30">近30天</van-radio>
<van-radio name="90">近90天</van-radio>
</van-radio-group>
</div>
</div>
<div class="filter-footer">
<van-button type="default" @click="resetFilter" class="reset-button">重置</van-button>
<van-button type="primary" @click="applyFilter" class="apply-button">确认筛选</van-button>
</div>
</div>
</van-popup>
<div class="hospitalization-list">
<div v-for="(item, index) in filteredList" :key="index" class="hospitalization-item" @click="navigateToDetail(item)">
<div class="item-header">
<h4>{{ item.SECTIONTYPE }}</h4>
<span :class="['status-tag', item.HOSSTATE == '2' ? 'discharged' : 'hospitalized']">
{{ item.HOSSTATE == '2' ? '出院' : '住院' }}
</span>
</div>
<div class="item-content">
<div class="info-row">
<span class="info-label">入院时间</span>
<span class="info-value">{{ item.HOSDATE }}</span>
</div>
<!-- <div class="info-row">
<span class="info-label">出院时间</span>
<span class="info-value">{{ item.OUTHOSDATE }}</span>
</div> -->
<div class="info-row last-row">
<div class="left-content">
<span class="info-label">住院编号</span>
<span class="info-value">{{ item.INHOSNUM }}-{{ item.ZYCS }}</span>
</div>
<div class="right-content">
<span class="info-value">住院{{ item.hospitalDays }}</span>
</div>
</div>
</div>
</div>
</div>
</div>
<van-empty description="住院处暂无该患者信息" v-else style="padding-top:90px" />
<van-action-sheet
v-model="showPatientSelector"
title="请选择使用的患者ID"
:actions="patientActions"
@select="onPatientSelect"
cancel-text="取消"
@cancel="showPatientSelector = false"
/>
</div>
</template>
<script>
import {
apiUserCardList,
apiInHosPatientInfoQuery,
getUserCategory
} from "@/request/api.js";
import Vue from "vue";
import { ActionSheet } from "vant";
Vue.use(ActionSheet);
export default {
mounted() {
this.title = this.$route.meta.title;
},
computed: {
patientActions() {
return this.patientIds.map(id => ({ name: `患者ID: ${id}`, id }));
}
},
data() {
return {
title: "",
card: {},
showbox: false,
zyinfo: {},
hospitalizationList: [], // 原始住院记录列表
filteredList: [], // 筛选后的住院记录列表
patientIds: [],
patientId: "",
showPatientSelector: false, // 控制是否显示选择弹窗
showFilter: false, // 控制是否显示筛选弹窗
filterState: "", // 筛选状态:空-全部hospitalized-住院discharged-出院
filterDepartment: "", // 筛选病区
filterTimeRange: "", // 筛选时间范围:空-全部7-近7天30-近30天90-近90天
departmentOptions: [], // 病区选项
};
},
created() {
this.card = JSON.parse(sessionStorage.getItem("card"));
if (this.card) {
this.getZYInfo();
return;
}
apiUserCardList({ isYes: 0 }).then((res) => {
this.card = res.data[0];
this.getZYInfo();
});
},
methods: {
onPatientSelect(action) {
this.patientId = action.id;
this.showPatientSelector = false;
console.log("选中的 patientId:", this.patientId);
// 如果需要根据 patientId 做其他查询,可在这里调用
let formData2 = {
QueryCode: this.patientId,
QueryType: 2,
};
this.apiInHosPatientInfoQuery(formData2);
},
apiInHosPatientInfoQuery(formData) {
apiInHosPatientInfoQuery(formData).then((res) => {
console.log(res);
let jsonObj = this.$x2js.xml2js(res.data);
console.log(jsonObj);
let jsonObj2 = this.$x2js.xml2js(
jsonObj.Envelope.Body.MOP_InHosPatientInfoQueryResponse
.MOP_InHosPatientInfoQueryResult
);
console.log(jsonObj2);
let dataRows = jsonObj2.response.data.data_row;
if (jsonObj2.response.returnresult.returncode == "1") {
this.hospitalizationList = [];
if (Array.isArray(dataRows)) {
// 处理数组形式的数据
for (var i = 0; i < dataRows.length; i++) {
let item = dataRows[i];
let hospitalizationItem = {
ADDRESS: item.ADDRESS,
BEDNO: item.BEDNO,
BIRTHDAY: item.BIRTHDAY,
DEPARTCODE: item.DEPARTCODE,
DEPTNAME: item.DEPTNAME,
HOSBALANCE: item.HOSBALANCE,
HOSDATE: item.HOSDATE,
HOSNATURE: item.HOSNATURE,
HOSSTATE: item.HOSSTATE,
IDCARDNO: item.IDCARDNO,
IDTYPE: item.IDTYPE,
INHOSNUM: item.INHOSNUM,
INHOSPATIENTID: item.INHOSPATIENTID,
OUTHOSDATE: item.OUTHOSDATE,
PATIENTNAME: item.PATIENTNAME,
PATIENTSEX: item.PATIENTSEX,
PATIENTSOURCE: item.PATIENTSOURCE,
PHONENUM: item.PHONENUM,
SECTIONTYPE: item.SECTIONTYPE || item.DEPTNAME,
ZYCS: item.ZYCS,
hospitalDays: this.calculateHospitalDays(item.HOSDATE, item.OUTHOSDATE, item.HOSSTATE)
};
this.hospitalizationList.push(hospitalizationItem);
}
} else {
// 处理单个对象形式的数据
let item = dataRows;
let hospitalizationItem = {
ADDRESS: item.ADDRESS,
BEDNO: item.BEDNO,
BIRTHDAY: item.BIRTHDAY,
DEPARTCODE: item.DEPARTCODE,
DEPTNAME: item.DEPTNAME,
HOSBALANCE: item.HOSBALANCE,
HOSDATE: item.HOSDATE,
HOSNATURE: item.HOSNATURE,
HOSSTATE: item.HOSSTATE,
IDCARDNO: item.IDCARDNO,
IDTYPE: item.IDTYPE,
INHOSNUM: item.INHOSNUM,
INHOSPATIENTID: item.INHOSPATIENTID,
OUTHOSDATE: item.OUTHOSDATE,
PATIENTNAME: item.PATIENTNAME,
PATIENTSEX: item.PATIENTSEX,
PATIENTSOURCE: item.PATIENTSOURCE,
PHONENUM: item.PHONENUM,
SECTIONTYPE: item.SECTIONTYPE || item.DEPTNAME,
ZYCS: item.ZYCS,
hospitalDays: this.calculateHospitalDays(item.HOSDATE, item.OUTHOSDATE, item.HOSSTATE)
};
this.hospitalizationList.push(hospitalizationItem);
}
// 设置患者基本信息(使用第一条记录的数据)
if (this.hospitalizationList.length > 0) {
let firstItem = this.hospitalizationList[0];
this.zyinfo = {
PATIENTNAME: firstItem.PATIENTNAME,
PATIENTSEX: firstItem.PATIENTSEX
};
// 初始化筛选列表
this.filteredList = [...this.hospitalizationList];
// 提取病区列表
this.extractDepartments();
this.showbox = true;
}
}
})
},
// 计算住院天数
calculateHospitalDays(hosDate, outHosDate, hosState) {
// 处理日期字符串,确保在 iOS 上兼容
let startDate = this.parseDate(hosDate);
let endDate;
if (outHosDate && hosState == '2') {
// 已出院,使用出院日期
endDate = this.parseDate(outHosDate);
} else {
// 未出院,使用今天日期
endDate = new Date();
}
// 计算天数差
let timeDiff = Math.abs(endDate.getTime() - startDate.getTime());
let dayDiff = Math.ceil(timeDiff / (1000 * 3600 * 24));
return dayDiff;
},
// 解析日期字符串,确保在 iOS 上兼容
parseDate(dateString) {
if (!dateString) return new Date();
// 将 "2025-07-17 11:59:05" 格式转换为 "2025-07-17T11:59:05" 格式,确保 iOS 兼容
const isoDateString = dateString.replace(' ', 'T');
return new Date(isoDateString);
},
getZYInfo() {
let _this = this;
console.log(_this.card);
let formData = {
queryCode: _this.card.idNo,
queryType: 7,
};
getUserCategory(formData).then((res) => {
console.log(res);
let jsonObj = this.$x2js.xml2js(res.data);
let jsonObj2 = jsonObj.Envelope.Body.MOP_OutpPatInfoQueryResponse
.request;
console.log(jsonObj2);
if (Array.isArray(jsonObj2.request.data)) {
// 如果是数组,遍历获取每个元素的 PatientId
this.patientIds = jsonObj2.request.data.map(item => item.PatientId);
} else {
// 如果不是数组,说明只有一个对象
this.patientIds = [jsonObj2.request.data.PatientId];
}
if (this.patientIds.length === 1) {
this.patientId = this.patientIds[0];
let formData2 = {
QueryCode: this.patientId,
QueryType: 2,
};
this.apiInHosPatientInfoQuery(formData2);
} else if (this.patientIds.length > 1) {
this.showPatientSelector = true; // 弹出选择器
}
console.log(this.patientIds);
});
},
handleCardSelect() {
this.$router.push({ path: "/Member_jzr", query: { f: 1 } });
},
// 跳转到住院详情页面
navigateToDetail(item) {
// 使用 sessionStorage 存储住院记录数据,避免通过地址栏传递大量参数
sessionStorage.setItem('hospitalizationItem', JSON.stringify(item));
// 跳转到住院详情页面
this.$router.push({ path: "/ZYdetail" });
},
// 提取病区列表
extractDepartments() {
const departments = new Set();
this.hospitalizationList.forEach(item => {
if (item.SECTIONTYPE) {
departments.add(item.SECTIONTYPE);
}
});
// 生成符合 van-dropdown-item 要求的 options 格式
this.departmentOptions = Array.from(departments).map(dept => ({
value: dept,
text: dept
}));
},
// 应用筛选条件
applyFilter() {
this.filteredList = this.hospitalizationList.filter(item => {
// 筛选住院状态
if (this.filterState) {
if (this.filterState === 'hospitalized' && item.HOSSTATE === '2') {
return false;
}
if (this.filterState === 'discharged' && item.HOSSTATE !== '2') {
return false;
}
}
// 筛选病区
if (this.filterDepartment && item.SECTIONTYPE !== this.filterDepartment) {
return false;
}
// 筛选时间范围
if (this.filterTimeRange) {
const days = parseInt(this.filterTimeRange);
const cutoffDate = new Date();
cutoffDate.setDate(cutoffDate.getDate() - days);
const hosDate = this.parseDate(item.HOSDATE);
if (hosDate < cutoffDate) {
return false;
}
}
return true;
});
this.showFilter = false;
},
// 重置筛选条件
resetFilter() {
this.filterState = '';
this.filterDepartment = '';
this.filterTimeRange = '';
this.filteredList = [...this.hospitalizationList];
this.showFilter = false;
}
},
}
</script>
<style scoped lang="scss">
// 背景样式
.bj {
background: #f5f5f5;
position: fixed;
width: 100%;
height: 100%;
top: 0px;
left: 0px;
z-index: -2;
}
// 就诊人卡片样式
.lxr {
.van-cell--center {
border-radius: 15px;
padding: 20px;
background: url(../assets/lxrbj.png) no-repeat;
background-size: 100% 100%;
background-position: center center;
color: #fff;
.van-cell__value--alone {
color: #fff;
}
.van-cell__right-icon {
color: #fff;
}
}
.van-contact-card::before {
background: none;
}
::v-deep .van-contact-card--add .van-cell__left-icon {
color: #fff;
opacity: 0.6;
}
.lxrr {
border-radius: 15px;
padding: 20px;
background: url(../assets/lxrbj.png) no-repeat;
background-size: 100% 100%;
background-position: center center;
color: #fff;
padding: 30px;
display: flex;
align-items: center;
justify-content: space-between;
h2 {
font-size: 32px;
p {
font-size: 28px;
padding-top: 10px;
}
}
h3 .van-cell__right-icon {
color: #fff;
}
}
}
// 通用文字颜色
.colblack {
color: #000;
font-weight: 600;
}
.colgray {
color: #aaa;
}
/* 头部标题和筛选按钮布局 */
.header-section {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 10px;
padding: 0 5px;
}
.list-title {
font-size: 28px;
font-weight: 600;
color: #333;
margin: 0;
}
.filter-text {
font-size: 24px;
color: #2196F3;
cursor: pointer;
padding: 5px;
}
// ---------------------- 优化后的筛选弹窗样式 ----------------------
::v-deep .van-popup {
&.van-popup--bottom {
border-top-left-radius: 20px;
border-top-right-radius: 20px;
box-shadow: 0 -5px 15px rgba(0, 0, 0, 0.05);
overflow: hidden;
}
}
.filter-popup {
height: 100%;
display: flex;
flex-direction: column;
background-color: #ffffff;
}
// 筛选弹窗头部
.filter-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 16px 24px;
border-bottom: 1px solid #f5f7fa;
h4 {
font-size: 30px;
font-weight: 700;
color: #1a1a1a;
margin: 0;
}
.close-icon {
font-size: 32px;
color: #999999;
padding: 8px;
border-radius: 50%;
transition: all 0.2s ease;
&:active {
background-color: #f5f7fa;
color: #666666;
}
}
}
// 筛选弹窗内容区域
.filter-content {
flex: 1;
padding: 24px;
overflow-y: auto;
background-color: #fafbfc;
// 单个筛选项容器
.filter-item {
margin-bottom: 32px;
background-color: #ffffff;
padding: 20px;
border-radius: 16px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.03);
&:last-child {
margin-bottom: 0;
}
// 筛选项标签
.filter-label {
font-size: 26px;
font-weight: 600;
color: #333333;
margin-bottom: 16px;
display: block;
padding-left: 4px;
}
}
// 单选框组样式(住院状态/时间范围)
::v-deep .van-radio-group {
display: flex;
flex-wrap: wrap;
gap: 12px;
padding: 4px 0;
.van-radio {
flex: 1;
min-width: 120px;
height: 80px;
margin: 0;
.van-radio__wrapper {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
border: 2px solid #e5e7eb;
border-radius: 12px;
background-color: #ffffff;
transition: all 0.2s ease;
padding: 0;
// 单选框圆点隐藏(用背景色区分选中状态,更直观)
.van-radio__input {
display: none;
}
// 单选框文字
.van-radio__label {
font-size: 24px;
color: #666666;
margin: 0;
transition: all 0.2s ease;
}
}
// 选中状态样式
&.van-radio--checked {
.van-radio__wrapper {
border-color: #2196F3;
background-color: #E3F2FD;
}
.van-radio__label {
color: #2196F3;
font-weight: 600;
}
}
// 触摸反馈
&:active {
.van-radio__wrapper {
opacity: 0.8;
transform: scale(0.98);
}
}
}
}
// 病区选择器样式
.department-select-wrap {
height: 80px;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 20px;
border: 2px solid #e5e7eb;
border-radius: 12px;
background-color: #ffffff;
transition: all 0.2s ease;
&:active {
opacity: 0.8;
transform: scale(0.98);
}
.department-value {
font-size: 24px;
color: #333333;
}
.department-icon {
font-size: 24px;
color: #999999;
}
}
// 病区picker样式优化穿透vant
::v-deep .department-picker {
.van-picker__toolbar {
background-color: #fafbfc;
border-bottom: 1px solid #f5f7fa;
.van-picker__cancel,
.van-picker__confirm {
font-size: 26px;
font-weight: 600;
color: #2196F3;
}
}
.van-picker__column {
text-align: center;
.van-picker__option {
font-size: 26px;
color: #333333;
}
}
}
}
// 筛选弹窗底部按钮
.filter-footer {
padding: 20px 24px;
background-color: #ffffff;
display: flex;
justify-content: space-between;
gap: 16px;
.reset-button,
.apply-button {
flex: 1;
height: 88px;
font-size: 28px;
font-weight: 600;
border-radius: 16px;
border: none;
transition: all 0.2s ease;
&:active {
opacity: 0.8;
transform: scale(0.98);
}
}
.reset-button {
background-color: #f5f7fa;
color: #666666;
border: 2px solid #e5e7eb;
&:hover {
background-color: #eff1f5;
}
}
.apply-button {
background-color: #2196F3;
color: #ffffff;
&:hover {
background-color: #1976D2;
}
}
}
/* 住院记录列表样式 */
.hospitalization-list {
margin-top: 15px;
}
.hospitalization-item {
background-color: #fff;
border-radius: 15px;
padding: 20px;
margin-bottom: 15px;
position: relative;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}
.item-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15px;
h4 {
font-size: .47rem;
font-weight: 600;
color: #333;
}
}
/* 状态标签样式 */
.status-tag {
font-size: .42rem;
padding: 4px 12px;
border-radius: 12px;
}
.status-tag.discharged {
color: #4CAF50;
background-color: #E8F5E9;
}
.status-tag.hospitalized {
color: #2196F3;
background-color: #E3F2FD;
}
/* 信息行样式 */
.item-content {
.info-row {
display: flex;
align-items: center;
margin-bottom: 10px;
font-size: .38rem;
}
.info-label {
color: #666;
margin-right: 10px;
min-width: 100px;
}
.info-value {
color: #333;
font-weight: 500;
}
.right-label {
margin-left: 30px;
}
}
/* 最后一行特殊处理 */
.item-content .info-row:last-child {
justify-content: space-between;
}
/* 住院编号和住院天数布局 */
.info-row.last-row {
display: flex;
justify-content: space-between;
align-items: center;
}
.left-content {
display: flex;
align-items: center;
}
.right-content {
display: flex;
align-items: center;
}
</style>

View File

@@ -271,8 +271,11 @@ yuyue() {
apiOpTjYy(formData)
.then(res => {
if (res.code === 200) {
Toast.success("预约成功");
this.$router.push('Zstj_yy');
Toast.success({ message: "预约成功", duration: 3000 });
// 延时3秒后跳转到预约页面
setTimeout(() => {
this.$router.push('Zstj_yy');
}, 4000);
} else {
Toast.fail(res.message || "预约失败,请重试");
}

778
src/views/Zstj_home.vue Normal file
View File

@@ -0,0 +1,778 @@
<template>
<div class="home">
<nav-bar />
<div class="bj"></div>
<!-- 顶部医院图片 -->
<div class="hospital-header">
<div class="hospital-img-container">
<img src="../assets/back.webp" alt="医院大楼" class="hospital-img" />
</div>
</div>
<!-- 医院信息盒子 -->
<div class="hospital-info-box">
<div class="hospital-info">
<div class="info-header">
<!-- 医院logo -->
<div class="hospital-logo">
<img :src="hospitalData.logo" alt="医院logo" v-if="hospitalData.logo" />
<!-- 兜底图片防止接口返回logo为空 -->
<img src="../assets/nxwjlogo2.jpg" alt="医院logo" v-else />
</div>
<!-- 医院名称和标签 -->
<div class="info-content">
<h1 class="hospital-name">{{ hospitalData.name || "宁夏武警总队医院" }}</h1>
<div class="info-row">
<div class="hospital-level">{{ hospitalData.label || "二级甲等" }}</div>
<div class="hospital-tags">
<!-- <span class="tag">周末上班</span> -->
<span class="tag">现场加项</span>
</div>
</div>
</div>
</div>
<!-- 地址信息 -->
<div class="address-info" @click="navigateTo('/Hospital_dh1')">
<van-icon name="location" />
<span>{{ hospitalData.address || "银川市兴庆区清和南街895号" }}</span>
</div>
<!-- 体检时间 -->
<div class="time-info">
<van-icon name="clock" />
<div>
<div>体检时间{{ examTime.weekday }} {{ examTime.timeRange }}</div>
</div>
</div>
<!-- 公告栏 -->
<van-notice-bar scrollable left-icon="volume" background="#fff" style="padding:0 !important;">
{{ noticeContent }}
</van-notice-bar>
</div>
</div>
<!-- 功能按钮区域 -->
<div class="feature-buttons">
<!-- 体检套餐按钮 -->
<div class="feature-button" @click="navigateTo('/Zstj_yy')">
<div class="button-content">
<h3>体检套餐</h3>
<p>超值套餐任意选</p>
</div>
<div class="button-image">
<img src="../assets/zstj_pic3.png" alt="体检套餐" />
</div>
</div>
<!-- 报告查询按钮 -->
<div class="feature-button" @click="navigateTo('/Member_wdbg')">
<div class="button-content">
<h3>报告查询</h3>
<p>体检报告随时查</p>
</div>
<div class="button-image">
<img src="../assets/zstj_pic1.png" alt="报告查询" />
</div>
</div>
</div>
<!-- 热门体检套餐推荐复用apiOpTiQuery接口和体检页面一致 -->
<div class="hot-packages">
<div class="section-title">
<h3>热门体检套餐</h3>
<span @click="navigateTo('/Zstj_yy')" class="more">查看更多 ></span>
</div>
<!-- 加载状态 -->
<div class="loading-container" v-if="packageLoading">
<van-loading type="spinner" color="#46c3b0" />
<p class="loading-text">正在加载套餐数据...</p>
</div>
<!-- 空数据提示 -->
<div class="empty-container" v-else-if="hotPackageList.length === 0">
<van-empty description="暂无热门套餐数据" image="empty" />
</div>
<!-- 套餐列表适配体检页面字段映射 -->
<div class="package-list" v-else>
<div
class="package-card"
v-for="(pkg, index) in hotPackageList"
:key="index"
@click="navigateToPackage(pkg)"
>
<div class="package-tag" v-if="index === 0">爆款</div>
<div class="package-name">{{ pkg.program_name || "默认体检套餐" }}</div>
<div class="package-price">
<span class="price">¥{{ pkg.price || 0 }}</span>
</div>
<div class="package-desc">{{ pkg.description || "包含基础体检项目,满足日常健康筛查需求" }}</div>
<button class="package-btn">立即预约</button>
</div>
</div>
</div>
<!-- 常见问题 -->
<div class="faq-section">
<div class="section-title">
<h3>常见问题</h3>
</div>
<div class="faq-list">
<div class="faq-item">
<h4>体检需要提前预约吗</h4>
<p>是的为了确保体检服务质量建议提前1-3天在线预约</p>
</div>
<div class="faq-item">
<h4>体检前需要做哪些准备</h4>
<p>体检前三天保持正常饮食勿饮酒避免剧烈运动体检当天需空腹8-12小时</p>
</div>
<div class="faq-item">
<h4>体检报告多久可以获取</h4>
<p>一般情况下体检后1-5个工作日可以通过本平台查询电子报告</p>
</div>
<div class="faq-item">
<h4>体检当天需要携带什么证件</h4>
<p>请携带本人身份证原件以便登记和核实身份信息</p>
</div>
<div class="faq-item">
<h4>可以调整体检套餐内容吗</h4>
<p>是的您可以根据个人需求在预约时或到院后咨询医生进行套餐内容的调整</p>
</div>
</div>
</div>
</div>
</template>
<script>
// 引入所需Vant组件和体检页面一致
import { NoticeBar, Icon, Loading, Empty, Toast } from 'vant';
// 复用体检页面的apiOpTiQuery接口无需额外接口
import { apiOpTiQuery, apiGetHospitalInfo } from "@/request/api.js";
export default {
components: {
[NoticeBar.name]: NoticeBar,
[Icon.name]: Icon,
[Loading.name]: Loading,
[Empty.name]: Empty
},
data() {
return {
// 公告内容
noticeContent: '关注健康 定期体检 - 为您的健康保驾护航 - 体检注意事项周一至周五上午8:00-10:30体检体检前三天保持正常饮食勿饮酒避免剧烈运动体检当天需空腹8-12小时慢性病患者请携带平时服用的药物女性特殊时期请告知医护人员体检当天穿宽松的衣裤。',
// 体检时间信息
examTime: {
weekday: '周一到周五',
timeRange: '08:00-10:30',
bloodTime: '10:30'
},
// 医院信息(接口返回)
hospitalData: {},
// 热门套餐相关(复用体检页面接口逻辑)
hotPackageList: [], // 存储前2条热门套餐数据
packageLoading: true, // 加载状态
same_day: '', // 默认日期(和体检页面一致)
allDataCache: {} // 缓存数据(和体检页面缓存格式一致)
};
},
mounted() {
// 初始化日期和体检页面initDateList逻辑一致
this.initDateList();
// 获取医院信息
this.getData();
// 获取热门套餐数据复用apiOpTiQuery
this.getHotPackageData();
},
methods: {
// 路由跳转(和体检页面一致,跳转至套餐列表页)
navigateTo(path) {
this.$router.push(path);
},
navigateToPackage(pkg) {
// 跳转到 Zstj_tc 页面并传递套餐信息,以便自动勾选
this.$router.push({
path: '/Zstj_tc',
query: {
preSelectedItems: JSON.stringify([{
id: pkg.program_id || `package_${Date.now()}`,
name: pkg.category || "体检套餐",
price: pkg.price || 0,
explain: pkg.program_name || "默认体检套餐"
}])
}
});
},
// 获取医院信息
getData() {
apiGetHospitalInfo().then((res) => {
console.log("医院信息:", res.data);
this.hospitalData = res.data || {};
}).catch(err => {
console.error("获取医院信息失败:", err);
this.hospitalData = {};
});
},
// 初始化日期(完全复用体检页面逻辑,保证日期一致)
initDateList() {
const today = new Date();
const todayDay = today.getDay();
let start = new Date(today);
// 如果今天是周末,跳到下周一
if (todayDay === 0) start.setDate(today.getDate() + 1);
else if (todayDay === 6) start.setDate(today.getDate() + 2);
const weekDays = ['日', '一', '二', '三', '四', '五', '六'];
const dates = [];
let current = new Date(start);
for (let i = 0; i < 5; i++) {
const d = current.getDate();
const m = current.getMonth() + 1;
const dateString = `${current.getFullYear()}-${m}-${d}`;
const week = `${weekDays[current.getDay()]}`;
const name = `${m}.${d}`;
dates.push({ date: dateString, week, name });
current.setDate(current.getDate() + 1);
while (current.getDay() === 0 || current.getDay() === 6) {
current.setDate(current.getDate() + 1);
}
}
this.same_day = dates[0].date;
},
// 日期格式化(完全复用体检页面方法,保证接口参数一致)
formatDateForAPI(dateStr) {
const [year, month, day] = dateStr.split('-').map(Number);
return `${year}/${String(month).padStart(2, '0')}/${String(day).padStart(2, '0')}`;
},
// 获取热门套餐数据复用apiOpTiQuery接口和体检页面逻辑一致
getHotPackageData() {
this.packageLoading = true;
const apiDate = this.formatDateForAPI(this.same_day);
const cacheKey = apiDate + '_1'; // 1=套餐类型和体检页面缓存key格式一致
// 优先从缓存获取,避免重复请求
if (this.allDataCache[cacheKey]) {
this.handlePackageData(this.allDataCache[cacheKey]);
this.packageLoading = false;
return;
}
// 调用体检页面同款接口,请求套餐类型数据
apiOpTiQuery({
startDate: apiDate,
endDate: apiDate,
HospitalZone: "",
Type: '1' // 1=套餐类型,和体检页面一致
}).then((res) => {
console.log("热门套餐数据apiOpTiQuery", res.data);
const data = res.data?.data || [];
// 缓存数据(和体检页面缓存格式一致)
this.allDataCache[cacheKey] = data;
// 处理热门套餐数据取前2条
this.handlePackageData(data);
}).catch((err) => {
console.error("套餐数据加载失败:", err);
this.hotPackageList = [];
Toast.fail('加载失败');
}).finally(() => {
this.packageLoading = false;
Toast.clear();
});
},
// 处理热门套餐数据取前2条适配字段映射
handlePackageData(rawData) {
// 过滤有效数据取前2条作为热门套餐
const validData = rawData.filter(item => item.program_id && item.program_name);
this.hotPackageList = validData.slice(0, 2); // 取前2条保持页面简洁
}
}
}
</script>
<style scoped lang="scss">
.bj {
background: #fff;
position: fixed;
width: 100%;
height: 100%;
top: 0px;
left: 0px;
z-index: -1;
}
/* 顶部医院图片 */
.hospital-header {
position: relative;
margin-bottom: -30px; /* 为信息盒子留出覆盖空间 */
}
/* 医院图片容器 */
.hospital-img-container {
width: 100%;
height: 5rem;
overflow: hidden;
}
.hospital-img {
width: 100%;
height: 100%;
object-fit: cover;
}
/* 医院信息盒子 */
.hospital-info-box {
background: white;
border-radius: 20px 20px 0 0; /* 只有上圆角 */
box-shadow: 0 -5px 20px rgba(0,0,0,0.1); /* 顶部阴影 */
padding-top: 40px; /* 为logo留出空间 */
position: relative;
z-index: 10;
}
/* 医院信息 */
.hospital-info {
padding: 0 20px 20px;
}
/* 信息头部logo + 名称和标签 */
.info-header {
display: flex;
align-items: flex-start;
gap: 20px;
margin-bottom: 20px;
}
/* 医院logo */
.hospital-logo {
width: 2.5rem;
height: 2.5rem;
border-radius: 50%;
overflow: hidden;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
flex-shrink: 0;
position: absolute;
top: -1rem; /* 向上超出盒子 */
left: 20px;
background: white;
border: 3px solid white;
}
.hospital-logo img {
width: 100%;
height: 100%;
object-fit: contain;
}
/* 医院名称和标签 */
.info-content {
flex: 1;
margin-left: 3rem; /* 为logo留出空间 */
}
.hospital-name {
font-size: .5rem;
font-weight: bold;
margin: 0 0 10px 0;
color: #333;
}
.info-row {
display: flex;
align-items: center;
gap: 15px;
}
.hospital-level {
font-size: .3rem;
color: #666;
font-weight: 500;
}
.hospital-tags {
display: flex;
gap: 8px;
}
.tag {
background: #e6f7ff;
color: #1890ff;
padding: 4px 10px;
border-radius: 12px;
font-size: .3rem;
font-weight: 500;
}
.address-info,
.time-info {
display: flex;
align-items: flex-start;
margin-bottom: 15px;
font-size: .35rem;
color: #666;
position: relative;
}
.address-info {
padding-bottom: 15px;
border-bottom: 1px solid #e0e0e0;
}
.time-info {
padding-bottom: 15px;
border-bottom: 1px solid #e0e0e0;
margin-bottom: 15px;
}
.van-notice-bar {
margin-top: 15px;
}
.address-info van-icon,
.time-info van-icon {
margin-right: 8px;
margin-top: 2px;
color: #999;
}
.time-info div {
flex: 1;
}
.time-info div:first-child {
font-weight: 500;
margin-bottom: 2px;
}
/* 功能按钮区域 */
.feature-buttons {
margin-top: 25px;
padding: 0 15px 20px;
display: flex;
flex-direction: column;
gap: 20px;
}
.feature-button {
background: white;
border-radius: 16px;
padding: 20px;
display: flex;
justify-content: space-between;
align-items: center;
box-shadow: 0 4px 16px rgba(0,0,0,0.08);
transition: all 0.3s ease;
cursor: pointer;
position: relative;
overflow: hidden;
}
.feature-button::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 6px;
height: 100%;
border-radius: 16px 0 0 16px;
}
.feature-button:hover {
transform: translateY(-3px);
box-shadow: 0 8px 24px rgba(0,0,0,0.12);
}
/* 体检套餐按钮样式 */
.feature-button:first-child {
background: linear-gradient(135deg, #fff9e6 0%, #fff3cd 100%);
}
.feature-button:first-child::before {
background: linear-gradient(180deg, #ffc107 0%, #ff9800 100%);
}
/* 报告查询按钮样式 */
.feature-button:last-child {
background: linear-gradient(135deg, #e6f7ff 0%, #b3d9ff 100%);
}
.feature-button:last-child::before {
background: linear-gradient(180deg, #1890ff 0%, #096dd9 100%);
}
.button-content {
flex: 1;
}
.button-content h3 {
font-size: .5rem;
font-weight: bold;
margin: 0 0 5px 0;
}
.button-content p {
font-size: .3rem;
color: #666;
margin: 0;
}
.button-image {
width: 1rem;
height: 1rem;
display: flex;
align-items: center;
justify-content: center;
}
.button-image img {
width: 50px;
height: 50px;
object-fit: contain;
}
/* 通用标题样式 */
.section-title {
padding: 0 15px;
margin-bottom: 15px;
}
.section-title h3 {
font-size: .4rem;
font-weight: 600;
color: #333;
margin: 0;
display: inline-block;
position: relative;
padding-left: 12px;
}
.section-title h3::before {
content: '';
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
width: 4px;
height: 16px;
background: linear-gradient(180deg, #46c3b0 0%, #3aa897 100%);
border-radius: 2px;
}
/* 热门体检套餐样式(适配体检页面超长描述) */
.hot-packages {
margin-top: 20px;
padding: 0 15px;
}
.more {
font-size: .3rem;
color: #46c3b0;
cursor: pointer;
margin-left: 10px;
}
/* 加载状态样式 */
.loading-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 30px 0;
background: #fff;
border-radius: 12px;
box-shadow: 0 2px 10px rgba(0,0,0,0.08);
.loading-text {
font-size: .3rem;
color: #999;
margin-top: 10px;
}
}
/* 空数据样式 */
.empty-container {
padding: 20px 0;
background: #fff;
border-radius: 12px;
box-shadow: 0 2px 10px rgba(0,0,0,0.08);
}
.package-list {
display: flex;
gap: 15px;
overflow-x: auto;
padding-bottom: 10px;
/* 隐藏滚动条,保留滚动功能,适配移动端 */
&::-webkit-scrollbar {
display: none;
}
}
.package-card {
min-width: 4.5rem;
background: white;
border-radius: 12px;
padding: 20px 15px;
box-shadow: 0 2px 10px rgba(0,0,0,0.08);
position: relative;
cursor: pointer;
transition: all 0.3s ease;
&:hover {
transform: translateY(-2px);
box-shadow: 0 4px 15px rgba(0,0,0,0.1);
}
.package-tag {
position: absolute;
top: 15px;
right: 15px;
background: #46c3b0;
color: #fff;
font-size: .25rem;
padding: 2px 8px;
border-radius: 8px;
}
.package-name {
font-size: .37rem;
font-weight: 600;
color: #333;
margin: 0 0 10px 0;
}
.package-price {
margin-bottom: 10px;
.price {
font-size: .4rem;
font-weight: bold;
color: #d62e25;
}
}
.package-desc {
font-size: .28rem;
color: #666;
margin-bottom: 15px;
line-height: 1.4;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 3; /* 显示3行超出隐藏 */
-webkit-box-orient: vertical;
}
.package-btn {
width: 100%;
background: linear-gradient(135deg, #46c3b0 0%, #3aa897 100%);
color: #fff;
border: none;
border-radius: 8px;
padding: 8px 0;
font-size: .35rem;
cursor: pointer;
transition: background 0.3s ease;
&:hover {
opacity: 0.9;
}
}
}
/* 常见问题 */
.faq-section {
margin-top: 30px;
margin-bottom: 30px;
padding: 0 15px;
}
.faq-list {
display: flex;
flex-direction: column;
gap: 10px;
}
.faq-item {
background: white;
border-radius: 12px;
padding: 15px;
box-shadow: 0 2px 10px rgba(0,0,0,0.08);
transition: all 0.3s ease;
}
.faq-item:hover {
transform: translateY(-2px);
box-shadow: 0 4px 15px rgba(0,0,0,0.1);
}
.faq-item h4 {
font-size: .37rem;
font-weight: 600;
color: #333;
margin: 0 0 8px 0;
display: flex;
align-items: center;
}
.faq-item h4::before {
content: '?';
width: 20px;
height: 20px;
border-radius: 50%;
background: linear-gradient(135deg, #46c3b0 0%, #3aa897 100%);
color: white;
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
font-weight: bold;
margin-right: 10px;
flex-shrink: 0;
}
.faq-item p {
font-size: .32rem;
color: #666;
margin: 0;
line-height: 1.5;
padding-left: 30px;
}
/* 响应式设计 */
@media screen and (min-width: 768px) {
.home {
max-width: 600px;
margin: 0 auto;
background: white;
min-height: 100vh;
}
.hospital-img {
height: 250px;
}
.faq-section {
padding: 0 30px;
}
.section-title {
padding: 0 30px;
}
.hot-packages {
padding: 0 30px;
}
}
</style>

View File

@@ -5,7 +5,7 @@
<!-- 搜索框 -->
<div class="zstj_tc">
<div class="container">
<div>
<div class="search">
<div class="searchBox">
<input
@@ -53,14 +53,82 @@
<!-- 项目列表 -->
<div class="container-wrapper">
<div class="container">
<div class="zstj_tc1">
<!-- 套餐模板容器 -->
<div v-if="typeSelection === '1'" class="zstj_tc1">
<van-list v-model="loading" :finished="finished" finished-text="没有更多了">
<ul>
<li
v-for="item in filteredList"
:key="item.id"
class="package-item"
>
<div
class="package-header"
@click="togglePackageExpand(item.id)"
>
<div class="checkbox-container" @click.stop="toggleSelection(item.id)">
<div class="checkbox" :class="{ checked: selectedItems.includes(item.id) }">
<span v-if="selectedItems.includes(item.id)"></span>
</div>
</div>
<div class="content">
<h2>
<p>{{ item.explain }}</p>
</h2>
<div class="price-arrow">
<h3>¥{{ item.price }}</h3>
<div class="arrow" :class="{ rotated: expandedPackageId === item.id }"></div>
</div>
</div>
</div>
<!-- 手风琴展开部分 -->
<div
v-if="expandedPackageId === item.id"
class="package-details"
>
<div class="details-header">
<span>项目</span>
<span>价格</span>
</div>
<div class="details-content">
<div
v-for="(detail, index) in packageDetails[item.id] || []"
:key="index"
class="detail-item"
>
<span>{{ detail.name }}</span>
<span>¥{{ detail.price }}</span>
</div>
</div>
</div>
</li>
</ul>
</van-list>
</div>
<!-- 单项模板容器 -->
<div v-else class="single-item-wrapper">
<div class="single-item-container">
<!-- 左侧分类列表 -->
<div class="category-list">
<div
v-for="category in singleItemCategories"
:key="category"
class="category-item"
:class="{ active: selectedCategory === category }"
@click="selectCategory(category)"
>
{{ category }}
</div>
</div>
<!-- 右侧项目列表 -->
<div class="single-item-list">
<div
v-for="item in filteredSingleItems"
:key="item.id"
:class="{ selected: selectedItems.includes(item.id) }"
@click="toggleSelection(item.id)"
class="single-item-card"
>
<div class="checkbox-container">
<div class="checkbox" :class="{ checked: selectedItems.includes(item.id) }">
@@ -69,37 +137,29 @@
</div>
<div class="content">
<h2>
{{ item.name }}
{{ item.category }}
<p>{{ item.explain }}</p>
<p>{{ item.description }}</p>
</h2>
<h3>¥{{ item.price }}</h3>
</div>
</li>
</ul>
</van-list>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 底部预约列表按钮 -->
<div class="cart-button-container">
<div
class="cart-button"
@click="openCartPopup"
v-if="selectedItems.length > 0"
>
<van-icon name="records" class="cart-icon" />
<div class="cart-text">预约列表</div>
<div class="cart-count">{{ selectedItems.length }}</div>
<div class="total-price">
<!-- <span>总价</span> -->
<span class="price">¥{{ totalPrice }}</span>
</div>
<div
class="cart-button empty"
@click="openCartPopup"
v-else
class="reserve-button"
@click="directAppointment"
>
<van-icon name="records" class="cart-icon" />
<div class="cart-text">预约列表</div>
立即预约
</div>
</div>
@@ -210,10 +270,30 @@ export default {
typeSelection: "1", // 1: 套餐, 2: 单项
showCartPopup: false, // 控制预约列表弹窗显示
checkedItems: [], // 控制弹窗中选择的项目
};
// 手风琴展开状态管理
expandedPackageId: null, // 当前展开的套餐ID
packageDetails: {}, // 存储套餐详情数据
singleItemMap: {}, // 单项ID到单项数据的映射
// 单项分类数据处理
singleItemCategories: [], // 单项分类数据
selectedCategory: '', // 当前选中的分类
filteredSingleItems: [], // 根据分类筛选后的单项数据
}
},
computed: {
// 计算总价格
totalPrice() {
return this.selectedItemsDetails.reduce((total, item) => {
return total + parseFloat(item.price) || 0;
}, 0).toFixed(2);
}
},
created() {
this.initDateList();
this.handlePreSelectedItems(); // 处理从其他页面传入的预选择项目
},
activated() {
const apiDate = this.formatDateForAPI(this.same_day);
@@ -240,6 +320,51 @@ export default {
this.checkedItems = [...this.selectedItems];
},
// 切换套餐展开/收起状态
togglePackageExpand(itemId) {
if (this.expandedPackageId === itemId) {
this.expandedPackageId = null;
} else {
this.expandedPackageId = itemId;
// 获取套餐详情
this.getPackageDetails(itemId);
}
},
// 选择单项分类
selectCategory(category) {
this.selectedCategory = category;
// 筛选单项数据
if (category) {
this.filteredSingleItems = this.list.filter(item => item.description === category);
} else {
this.filteredSingleItems = [...this.list];
}
},
// 获取套餐详情
getPackageDetails(packageId) {
const packageItem = this.list.find(item => item.id === packageId);
if (!packageItem) return;
// 从单项数据中获取套餐项目详情
const details = [];
// 假设packageItem.programList存储了套餐包含的单项ID列表
if (packageItem.programList) {
packageItem.programList.forEach(singleItemId => {
const singleItem = this.singleItemMap[singleItemId];
if (singleItem) {
details.push({
name: singleItem.explain,
price: singleItem.price
});
}
});
}
this.$set(this.packageDetails, packageId, details);
},
// 打开预约列表弹窗
openCartPopup() {
if (this.selectedItems.length === 0) {
@@ -324,6 +449,26 @@ export default {
Toast.success(`已选择 ${selectedForAppointment.length} 个项目进行预约`);
},
// 直接预约(无弹窗)
directAppointment() {
if (this.selectedItems.length === 0) {
Toast('请先选择项目');
return;
}
// 提交所有选中的项目
const selectedForAppointment = this.selectedItemsDetails;
this.$router.push({
path: 'Zstj_detail',
query: {
items: JSON.stringify(selectedForAppointment),
seldate: this.same_day
}
});
Toast.success(`已选择 ${selectedForAppointment.length} 个项目进行预约`);
},
handleSearch() {
const keyword = this.searchKeyword.trim().toLowerCase();
if (!keyword) {
@@ -380,6 +525,9 @@ export default {
this.searchKeyword = "";
this.list = [];
this.filteredList = [];
this.expandedPackageId = null; // 重置手风琴展开状态
this.selectedCategory = ''; // 重置分类选择
this.filteredSingleItems = []; // 重置单项筛选数据
const apiDate = this.formatDateForAPI(this.same_day);
const cacheKey = apiDate + '_' + this.typeSelection;
@@ -425,20 +573,119 @@ export default {
name: item.category,
price: item.price,
explain: item.program_name,
description:item.description,
type: this.typeSelection// 添加类型标识
description: item.description,
type: this.typeSelection,
programList: item.program_list ? this.parseProgramList(item.program_list) : []
}));
this.filteredList = [...this.list];
// 套餐类型按program_id排序
if (this.typeSelection === '1') {
this.filteredList.sort((a, b) => a.id.localeCompare(b.id));
}
// 处理单项数据
if (this.typeSelection === '2') {
// 构建单项ID到单项数据的映射
this.singleItemMap = {};
rawData.forEach(item => {
this.singleItemMap[item.program_id] = {
id: item.program_id,
name: item.description, // 使用description作为分类
price: item.price,
explain: item.program_name,
description: item.description
};
});
// 提取单项分类按description
const categories = [...new Set(rawData.map(item => item.description))];
this.singleItemCategories = categories;
// 默认选择第一个分类
if (categories.length > 0 && !this.selectedCategory) {
this.selectCategory(categories[0]);
}
} else {
// 处理套餐数据时,主动加载单项数据以构建映射
this.loadSingleItemData();
}
this.finished = true; // 一次性加载完成
},
// 加载单项数据
loadSingleItemData() {
const apiDate = this.formatDateForAPI(this.same_day);
const singleItemCacheKey = apiDate + '_2';
// 检查是否已有缓存
if (this.allDataCache[singleItemCacheKey]) {
const singleItemData = this.allDataCache[singleItemCacheKey];
this.buildSingleItemMap(singleItemData);
} else {
// 如果没有缓存,主动请求单项数据
this.fetchSingleItemData();
}
},
// 构建单项数据映射
buildSingleItemMap(singleItemData) {
this.singleItemMap = {};
singleItemData.forEach(item => {
this.singleItemMap[item.program_id] = {
id: item.program_id,
name: item.description, // 使用description作为分类
price: item.price,
explain: item.program_name,
description: item.description
};
});
},
// 请求单项数据
async fetchSingleItemData() {
const apiDate = this.formatDateForAPI(this.same_day);
const singleItemCacheKey = apiDate + '_2';
try {
const res = await apiOpTiQuery({
startDate: apiDate,
endDate: apiDate,
HospitalZone: "",
Type: '2' // 单项类型
});
const data = res.data?.data || [];
this.allDataCache[singleItemCacheKey] = data;
this.buildSingleItemMap(data);
} catch (err) {
console.error("请求单项数据失败:", err);
}
},
// 解析program_list处理以0开头的数字
parseProgramList(programListStr) {
try {
// 替换所有以0开头的数字为字符串
const processedStr = programListStr.replace(/\b0(\d+)\b/g, '"0$1"');
return JSON.parse(processedStr);
} catch (error) {
console.error('解析program_list失败:', error);
return [];
}
},
handleTypeChange() {
// 切换类型时重新加载数据
this.list = [];
this.filteredList = [];
this.finished = false;
this.loading = false;
this.expandedPackageId = null; // 重置手风琴展开状态
this.selectedCategory = ''; // 重置分类选择
this.filteredSingleItems = []; // 重置单项筛选数据
const apiDate = this.formatDateForAPI(this.same_day);
if (this.allDataCache[apiDate + '_' + this.typeSelection]) {
@@ -451,6 +698,38 @@ export default {
formatDateForAPI(dateStr) {
const [year, month, day] = dateStr.split('-').map(Number);
return `${year}/${String(month).padStart(2, '0')}/${String(day).padStart(2, '0')}`;
},
// 处理从其他页面传入的预选择项目
handlePreSelectedItems() {
// 从路由参数中获取预选择项目
const preSelectedStr = this.$route.query.preSelectedItems;
if (preSelectedStr) {
try {
const preSelectedItems = JSON.parse(preSelectedStr);
if (Array.isArray(preSelectedItems)) {
// 清空现有选择状态
this.selectedItems = [];
this.selectedItemsDetails = [];
// 添加预选择项目
preSelectedItems.forEach(item => {
if (item.id) {
this.selectedItems.push(item.id);
this.selectedItemsDetails.push(item);
}
});
// 同步弹窗选择状态
this.checkedItems = [...this.selectedItems];
// 提示用户已预选择项目
Toast.success(`已为您预选择 ${preSelectedItems.length} 个项目`);
}
} catch (error) {
console.error('解析预选择项目失败:', error);
}
}
}
}
};
@@ -580,21 +859,19 @@ ul.timeSlelct {
padding-bottom: 100px;
}
.zstj_tc1 ul {
list-style: none;
padding: 0;
margin: 0;
}
.zstj_tc1 ul li {
margin-bottom: 40px;
display: flex;
align-items: center;
margin-bottom: 1px;
background: #fff;
border-radius: 24px;
box-sizing: border-box;
padding: 20px;
cursor: pointer;
// padding: 20px;
transition: all 0.3s;
&.selected {
border: 2px solid #46c3b0;
background-color: #f0f9f8;
}
}
.checkbox-container {
@@ -655,7 +932,7 @@ ul.timeSlelct {
.container-wrapper {
position: fixed;
top: 4.6rem;
top: 5.3rem;
left: 0;
right: 0;
bottom: 1.5rem;
@@ -666,73 +943,59 @@ ul.timeSlelct {
height: 100%;
overflow-y: auto;
background: #f5f5f5;
padding: 0 15px;
}
/* 预约列表按钮样式 */
.cart-button-container {
position: fixed;
bottom: 0.6rem;
left: 50%;
transform: translateX(-50%);
bottom: 0;
left: 0;
right: 0;
z-index: 100;
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
padding: 15px 20px;
background: white;
box-shadow: 0 -5px 20px rgba(0, 0, 0, 0.1);
}
.cart-button {
display: flex;
align-items: center;
justify-content: center;
.total-price {
font-size: .6rem;
font-weight: bold;
color: #333;
}
.total-price .price {
color: #d62e25;
margin-left: 5px;
}
.reserve-button {
background: linear-gradient(135deg, #46c3b0 0%, #3aa897 100%);
color: white;
padding: 15px 30px;
border-radius: 50px;
box-shadow: 0 5px 20px rgba(70, 195, 176, 0.3);
padding: 12px 30px;
border-radius: 8px;
box-shadow: 0 3px 15px rgba(70, 195, 176, 0.3);
cursor: pointer;
transition: all 0.3s;
font-weight: bold;
font-size: 24px;
position: relative;
// font-size: 20px;
white-space: nowrap;
margin-right: .76rem;
}
.cart-button:hover {
.reserve-button:hover {
transform: translateY(-3px);
box-shadow: 0 8px 25px rgba(70, 195, 176, 0.4);
box-shadow: 0 6px 20px rgba(70, 195, 176, 0.4);
}
.cart-button:active {
.reserve-button:active {
transform: translateY(-1px);
}
.cart-button.empty {
background: #f5f5f5;
color: #666;
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.1);
}
.cart-button.empty:hover {
background: #e8e8e8;
}
.cart-icon {
font-size: 32px;
margin-right: 10px;
}
.cart-count {
position: absolute;
top: -10px;
right: -10px;
background: #ff4d4f;
color: white;
border-radius: 50%;
width: 30px;
height: 30px;
display: flex;
align-items: center;
justify-content: center;
font-size: 18px;
font-weight: bold;
}
/* 预约列表弹窗样式 */
.cart-popup {
height: 100%;
@@ -801,4 +1064,241 @@ ul.timeSlelct {
padding-bottom: env(safe-area-inset-bottom) !important;
}
}
/* 套餐手风琴样式 */
.package-item {
//margin-bottom: 40px;
border-radius: 24px;
overflow: hidden;
background: #fff;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
transition: all 0.3s;
&.selected {
border: 2px solid #46c3b0;
background-color: #f0f9f8;
}
}
.package-header {
display: flex;
align-items: center;
padding: 20px;
cursor: pointer;
transition: all 0.3s;
width: auto;
&:hover {
background-color: #f9f9f9;
}
}
.price-arrow {
display: flex;
align-items: center;
gap: 10px;
}
.arrow {
font-size: 16px;
color: #999;
transition: transform 0.3s;
&.rotated {
transform: rotate(180deg);
}
}
/* 套餐详情部分 */
.package-details {
background-color: #f9f9f9;
border-top: 1px solid #eee;
animation: slideDown 0.3s ease;
width: 100%;
position: relative;
left: 0;
top: 0;
}
.details-header {
display: flex;
justify-content: space-between;
padding: 25px 20px;
background-color: #f0f0f0;
font-weight: bold;
color: #333;
font-size: 40px;
}
.details-content {
padding: 15px 20px 25px;
}
.detail-item {
display: flex;
justify-content: space-between;
padding: 15px 0;
border-bottom: 1px solid #eee;
font-size: 36px;
&:last-child {
border-bottom: none;
}
}
/* 单项分类容器样式 - 确保父容器高度固定,子元素可占满 */
.single-item-container {
display: flex;
flex-direction: row;
height: 600px; /* 固定父容器高度子元素100%高度生效 */
background: #fff;
border-radius: 24px;
overflow: hidden;
margin-bottom: 40px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
width: 100%;
list-style: none;
flex-wrap: nowrap;
/* 移除内边距,避免子元素高度占满后出现空隙 */
padding: 0;
margin: 0 0 40px 0;
}
/* 左侧分类列表样式 - 核心修改:占满高度,隐藏滚动条 */
.category-list {
width: 200px;
flex-shrink: 0;
background-color: #f5f5f5;
border-right: 1px solid #eee;
overflow-y: auto; /* 保留滚动功能 */
height: 100%; /* 占满父容器高度 */
box-sizing: border-box; /* 确保内边距不超出高度 */
padding: 0; /* 移除内边距,避免高度不足 */
margin: 0; /* 移除外边距,避免高度不足 */
/* 隐藏滚动条 - 兼容所有主流浏览器 */
::-webkit-scrollbar {
display: none; /* Chrome、Safari、Edge */
}
-ms-overflow-style: none; /* IE/Edge 旧版本 */
scrollbar-width: none; /* Firefox */
}
.category-item {
padding: 20px;
text-align: center;
cursor: pointer;
transition: all 0.3s;
border-bottom: 1px solid #eee;
font-size: 30px;
margin: 0; /* 移除外边距 */
&:hover {
background-color: #e8e8e8;
}
&.active {
background-color: #46c3b0;
color: white;
font-weight: bold;
}
}
/* 右侧单项列表样式 - 核心修改:占满高度 */
.single-item-list {
flex: 1;
padding: 20px;
overflow-y: auto;
height: 100%; /* 占满父容器高度 */
box-sizing: border-box; /* 确保内边距不超出高度 */
margin: 0; /* 移除外边距 */
}
/* 单项模板容器样式 */
.single-item-wrapper {
height: 100%;
overflow: hidden;
}
/* 修改单项分类容器样式 */
.single-item-container {
height: 100% !important;
margin-bottom: 0 !important;
}
/* 修改左侧分类列表样式 */
.category-list {
overflow-y: auto !important;
}
/* 修改右侧单项列表样式 */
.single-item-list {
overflow-y: auto !important;
}
/* 单项卡片样式 */
.single-item-card {
margin-bottom: 15px;
display: flex;
align-items: center;
background: #f9f9f9;
border-radius: 12px;
box-sizing: border-box;
padding: 15px;
cursor: pointer;
transition: all 0.3s;
&.selected {
border: 2px solid #46c3b0;
background-color: #f0f9f8;
}
&:hover {
transform: translateY(-2px);
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.1);
}
}
/* 动画效果 */
@keyframes slideDown {
from {
max-height: 0;
opacity: 0;
}
to {
max-height: 1200px;
opacity: 1;
}
}
/* 响应式设计 */
@media (max-width: 768px) {
.category-list {
width: 150px; /* 小屏缩小左侧宽度,保持占满高度 */
}
.category-item {
padding: 15px;
font-size: 20px;
}
.single-item-list {
padding: 15px;
}
.single-item-card {
padding: 12px;
margin-bottom: 12px;
}
.details-header {
font-size: 32px;
padding: 20px 15px;
}
.detail-item {
font-size: 28px;
padding: 12px 0;
}
}
</style>

View File

@@ -96,7 +96,7 @@ export default {
},
getDefaultNotice(){
return `
<p>体检时间: 周一至周五上午8:30-11:30。</p>
<p>体检时间: 周一至周五上午8:00-10:30。</p>
<p>网上预约体检项目不收费,需到线下进行体检项目缴费。</p>
<p>体检前三天,请您保持正常饮食,勿饮酒,避免剧烈运动。</p>
<p>体检当天需进行抽血、腹部B超检查请您在受检前8-12小时禁食禁饮进行抽血、腹部B超后方可进食糖尿病患者凭特病卡优先检查抽血及B超。</p>

File diff suppressed because it is too large Load Diff