hn-hlw-app/pages/home/home.vue

433 lines
9.6 KiB
Vue
Raw Normal View History

2026-07-27 11:26:39 +08:00
<template>
2026-07-30 16:48:56 +08:00
<full-page pageStyle="background:#fff">
<view class="home-page">
<image class="page-background" src="/static/_home/bg.png" mode="widthFix" />
<view class="hero">
<view class="nav-bar" :style="{ paddingTop: statusBarHeight + 'px' }">
<view class="nav-content">
2026-08-06 18:26:58 +08:00
<text class="hospital-name">海宁康华医院互联网医院</text>
2026-07-27 11:26:39 +08:00
</view>
</view>
2026-07-30 16:48:56 +08:00
<view class="user-bar">
<image class="avatar" src="/static/_home/avatar.png" mode="aspectFill" />
<template v-if="logined">
<text class="user-name">{{ userInfo.maskName || userInfo.userName || '已登录' }}</text>
<view class="login-button logout-button" @click="loginout">退出</view>
</template>
<view v-else class="login-button" @click="login">登录</view>
2026-07-27 11:26:39 +08:00
</view>
2026-07-30 16:48:56 +08:00
</view>
2026-07-27 11:26:39 +08:00
2026-07-30 16:48:56 +08:00
<view class="page-content">
<view class="prescription-list">
<view v-for="item in mainMenuList" :key="item.key" class="prescription-card" :class="item.cardClass"
@click="handleMainMenuClick(item)">
<view class="card-copy">
<text class="card-title">{{ item.title }}</text>
<text class="card-description">{{ item.desc }}</text>
2026-07-27 11:26:39 +08:00
</view>
2026-07-30 16:48:56 +08:00
<text class="card-arrow"></text>
<image class="card-watermark" :src="item.watermark" mode="aspectFit" />
</view>
</view>
<view class="service-section">
<text class="section-title">院内服务</text>
<view class="service-list">
<view v-for="item in menuList" :key="item.title" class="service-item" @click="gotoPage(item)">
<view class="service-icon-wrap">
2026-07-27 11:26:39 +08:00
<uni-badge :text="count[item.badgeKey]" absolute="rightTop" size="small"
2026-07-30 16:48:56 +08:00
:custom-style="item.badgeKey && count[item.badgeKey] > 0 ? {} : { display: 'none' }">
<image class="service-icon" :src="item.icon" mode="aspectFit" />
2026-07-27 11:26:39 +08:00
</uni-badge>
</view>
2026-07-30 16:48:56 +08:00
<text class="service-title">{{ item.title }}</text>
2026-07-27 11:26:39 +08:00
</view>
2026-07-30 16:48:56 +08:00
</view>
2026-07-27 11:26:39 +08:00
</view>
</view>
</view>
</full-page>
2026-07-30 16:48:56 +08:00
2026-08-07 10:50:56 +08:00
<store-popup :drugStore="drugStore" :visible="visible" @confirm="confirmStoreInfo()" @close="visible = false" />
2026-07-30 16:48:56 +08:00
<confirm-popup title="提示" content="您是否半年内在医院就诊过?" cancelText="否" confirmText="是" :visible="confirmVisible"
2026-07-27 11:26:39 +08:00
@confirm="handleConfirmYes" @cancel="handleConfirmNo" @close="confirmVisible = false" />
</template>
<script setup>
2026-07-30 16:48:56 +08:00
import { ref, onUnmounted } from "vue";
import { onLoad, onHide } from "@dcloudio/uni-app";
2026-07-27 11:26:39 +08:00
import useUser from "@/hooks/useUser";
2026-08-07 10:50:56 +08:00
import { autoAddHlwPatient, isDoctorOnline } from '@/utils/api'
2026-08-07 14:59:48 +08:00
import { toast } from "@/utils/widget";
2026-07-27 11:26:39 +08:00
import fullPage from "@/components/full-page.vue";
import confirmPopup from "./confirm-popup.vue";
2026-07-31 16:21:41 +08:00
import storePopup from "./store-popup.vue";
2026-07-27 11:26:39 +08:00
const mainMenuList = [
{
title: "医保处方",
desc: "医保结算,到店取药",
2026-07-30 16:48:56 +08:00
key: "YB",
cardClass: "insurance-card",
watermark: "/static/_home/watermark-insurance.png",
2026-07-27 11:26:39 +08:00
},
{
title: "自费处方",
desc: "全额自费,到店取药",
2026-07-30 16:48:56 +08:00
key: "ZF",
cardClass: "selfpay-card",
watermark: "/static/_home/watermark-selfpay.png",
},
];
2026-07-27 11:26:39 +08:00
const menuList = [
{
title: "处方记录",
2026-07-30 16:48:56 +08:00
icon: "/static/_home/rx-record.png",
2026-07-27 11:26:39 +08:00
url: "/pages/record/prescription-record",
2026-07-30 16:48:56 +08:00
badgeKey: "rxUnpay",
2026-07-27 11:26:39 +08:00
},
{
title: "诊疗记录",
2026-07-30 16:48:56 +08:00
icon: "/static/_home/cure-record.png",
2026-07-27 11:26:39 +08:00
url: "/pages/record/consult-record",
},
{
title: "就诊人管理",
2026-07-30 16:48:56 +08:00
icon: "/static/_home/patient-management.png",
2026-07-27 11:26:39 +08:00
url: "/pages/member/list",
},
];
2026-07-30 16:48:56 +08:00
2026-08-07 10:50:56 +08:00
const { userInfo, logined, login, loginout, drugStore, getStore, storeId } = useUser();
2026-07-30 16:48:56 +08:00
const statusBarHeight = ref(20);
const count = ref({ rxUnpay: 0 });
const confirmVisible = ref(false);
const confirmResolve = ref(null);
2026-07-27 11:26:39 +08:00
const confirmReject = ref(null);
2026-07-30 16:48:56 +08:00
const feeType = ref("");
2026-07-31 16:21:41 +08:00
const visible = ref(false)
2026-07-30 16:48:56 +08:00
function goBack() {
uni.navigateBack();
}
2026-07-27 11:26:39 +08:00
function confirmAuth() {
uni.navigateTo({
2026-07-30 16:48:56 +08:00
url: `/pages/consult/index?feeType=${feeType.value}`,
});
2026-07-27 11:26:39 +08:00
}
async function checkLogin() {
2026-07-30 16:48:56 +08:00
if (logined.value) return true;
2026-07-27 11:26:39 +08:00
await login();
2026-07-30 16:48:56 +08:00
return logined.value ? true : Promise.reject("login fail");
2026-07-27 11:26:39 +08:00
}
async function handleMainMenuClick(item) {
await checkLogin();
2026-08-07 10:50:56 +08:00
await checkCanBuy()
2026-07-30 16:48:56 +08:00
await autoAddPatient();
feeType.value = item.key;
confirmVisible.value = true;
2026-07-27 11:26:39 +08:00
}
2026-07-31 16:21:41 +08:00
async function handleConfirmYes() {
2026-07-30 16:48:56 +08:00
confirmVisible.value = false;
2026-07-31 16:21:41 +08:00
await getStore();
visible.value = true
2026-07-27 11:26:39 +08:00
if (confirmResolve.value) {
2026-07-30 16:48:56 +08:00
confirmResolve.value();
cleanupConfirmPromise();
2026-07-27 11:26:39 +08:00
}
}
2026-08-07 10:50:56 +08:00
2026-07-31 16:21:41 +08:00
function confirmStoreInfo() {
visible.value = false
confirmAuth();
}
2026-07-27 11:26:39 +08:00
function handleConfirmNo() {
2026-07-30 16:48:56 +08:00
confirmVisible.value = false;
2026-07-27 11:26:39 +08:00
if (confirmReject.value) {
2026-07-30 16:48:56 +08:00
confirmReject.value();
cleanupConfirmPromise();
2026-07-27 11:26:39 +08:00
}
}
function cleanupConfirmPromise() {
2026-07-30 16:48:56 +08:00
confirmResolve.value = null;
confirmReject.value = null;
2026-07-27 11:26:39 +08:00
}
2026-08-07 10:50:56 +08:00
async function checkCanBuy() {
const res = await isDoctorOnline()
if (res.data === true) {
return
}
toast('很抱歉!互联网问诊医生因线下门诊等原因暂时不在线!请稍后再试!')
return Promise.reject('no online doctor')
2026-07-27 11:26:39 +08:00
}
2026-07-30 16:48:56 +08:00
async function gotoPage(item) {
2026-07-27 11:26:39 +08:00
await checkLogin();
2026-07-30 16:48:56 +08:00
if (item.title === "就诊人管理") {
await autoAddPatient()
}
uni.navigateTo({ url: item.url });
2026-07-27 11:26:39 +08:00
}
2026-07-30 16:48:56 +08:00
async function autoAddPatient() {
await autoAddHlwPatient({
name: userInfo.value.userName,
certNo: userInfo.value.certNo,
mobile: userInfo.value.mobile,
accountId: userInfo.value.userId,
})
2026-07-27 11:26:39 +08:00
}
2026-07-31 18:26:48 +08:00
onLoad((opts) => {
if (opts.storeId) {
storeId.value = opts.storeId
}
2026-07-30 16:48:56 +08:00
const systemInfo = uni.getSystemInfoSync();
statusBarHeight.value = systemInfo.statusBarHeight || 20;
});
2026-07-27 11:26:39 +08:00
onHide(() => {
2026-07-30 16:48:56 +08:00
if (confirmReject.value) confirmReject.value();
cleanupConfirmPromise();
confirmVisible.value = false;
});
2026-07-27 11:26:39 +08:00
onUnmounted(() => {
2026-07-30 16:48:56 +08:00
cleanupConfirmPromise();
});
2026-07-27 11:26:39 +08:00
</script>
<style lang="scss" scoped>
2026-07-30 16:48:56 +08:00
.home-page {
2026-07-27 11:26:39 +08:00
position: relative;
2026-07-30 16:48:56 +08:00
min-height: 100%;
overflow: hidden;
background: #fff;
color: #132d59;
box-sizing: border-box;
2026-07-27 11:26:39 +08:00
}
2026-07-30 16:48:56 +08:00
.page-background {
2026-07-27 11:26:39 +08:00
position: absolute;
2026-07-30 16:48:56 +08:00
z-index: 0;
2026-07-27 11:26:39 +08:00
left: 0;
2026-07-30 16:48:56 +08:00
right: 0;
bottom: 0;
2026-07-27 11:26:39 +08:00
width: 100%;
}
2026-07-30 16:48:56 +08:00
.hero {
2026-07-27 11:26:39 +08:00
position: relative;
z-index: 1;
box-sizing: border-box;
2026-07-30 16:48:56 +08:00
background:
radial-gradient(circle at 76% 20%, rgba(43, 202, 202, 0.08) 0, rgba(43, 202, 202, 0.08) 28rpx, transparent 29rpx),
radial-gradient(circle at 92% 88%, rgba(255, 255, 255, 0.7) 0, rgba(255, 255, 255, 0.7) 86rpx, transparent 87rpx),
linear-gradient(135deg, #effafb 0%, #f5fbfc 60%, #edf7f8 100%);
2026-07-27 11:26:39 +08:00
}
2026-07-30 16:48:56 +08:00
.nav-bar {
box-sizing: border-box;
2026-07-27 11:26:39 +08:00
}
2026-07-30 16:48:56 +08:00
.nav-content {
height: 88rpx;
2026-07-27 11:26:39 +08:00
display: flex;
align-items: center;
2026-08-07 17:38:26 +08:00
padding: 0 30rpx 0 60rpx;
2026-07-30 16:48:56 +08:00
box-sizing: border-box;
2026-07-27 11:26:39 +08:00
}
2026-07-30 16:48:56 +08:00
.back-button {
width: 44rpx;
height: 64rpx;
2026-07-27 11:26:39 +08:00
display: flex;
align-items: center;
}
2026-07-30 16:48:56 +08:00
.back-arrow {
width: 20rpx;
height: 20rpx;
border-left: 4rpx solid #17386b;
border-bottom: 4rpx solid #17386b;
transform: rotate(45deg);
}
.hospital-name {
margin-left: 12rpx;
font-size: 34rpx;
line-height: 48rpx;
color: #143466;
font-weight: 600;
white-space: nowrap;
2026-07-27 11:26:39 +08:00
}
.user-bar {
display: flex;
align-items: center;
2026-08-07 17:38:26 +08:00
padding: 24rpx 30rpx 20rpx;
2026-07-27 11:26:39 +08:00
}
.avatar {
2026-07-30 16:48:56 +08:00
width: 54rpx;
height: 54rpx;
margin-right: 18rpx;
border-radius: 50%;
2026-07-27 11:26:39 +08:00
}
2026-07-30 16:48:56 +08:00
.user-name {
max-width: 240rpx;
margin-right: 18rpx;
2026-07-27 11:26:39 +08:00
overflow: hidden;
2026-07-30 16:48:56 +08:00
color: #17345f;
font-size: 26rpx;
2026-07-27 11:26:39 +08:00
text-overflow: ellipsis;
white-space: nowrap;
}
2026-07-30 16:48:56 +08:00
.login-button {
min-width: 94rpx;
height: 46rpx;
padding: 0 20rpx;
border: 2rpx solid #23c7b0;
border-radius: 25rpx;
box-sizing: border-box;
color: #13bba5;
font-size: 25rpx;
line-height: 42rpx;
text-align: center;
2026-08-07 17:38:26 +08:00
margin-top: 0;
transform: translateY(1px);
2026-07-27 11:26:39 +08:00
}
2026-07-30 16:48:56 +08:00
.logout-button {
margin-left: auto;
2026-07-27 11:26:39 +08:00
}
2026-07-30 16:48:56 +08:00
.page-content {
position: relative;
z-index: 1;
padding: 36rpx 30rpx 450rpx;
2026-07-27 11:26:39 +08:00
}
2026-07-30 16:48:56 +08:00
.prescription-list {
2026-07-27 11:26:39 +08:00
display: flex;
justify-content: space-between;
}
2026-07-30 16:48:56 +08:00
.prescription-card {
2026-07-27 11:26:39 +08:00
position: relative;
2026-07-30 16:48:56 +08:00
width: 328rpx;
height: 196rpx;
2026-07-27 11:26:39 +08:00
overflow: hidden;
2026-07-30 16:48:56 +08:00
border-radius: 12rpx;
box-sizing: border-box;
color: #fff;
2026-07-27 11:26:39 +08:00
}
2026-07-30 16:48:56 +08:00
.insurance-card {
background: linear-gradient(135deg, #27d0b3 0%, #0bbda9 100%);
2026-07-27 11:26:39 +08:00
}
2026-07-30 16:48:56 +08:00
.selfpay-card {
background: linear-gradient(135deg, #28b6f4 0%, #129cf0 100%);
2026-07-27 11:26:39 +08:00
}
2026-07-30 16:48:56 +08:00
.card-copy {
position: relative;
z-index: 2;
2026-07-27 11:26:39 +08:00
display: flex;
flex-direction: column;
2026-07-30 16:48:56 +08:00
padding: 30rpx 26rpx;
2026-07-27 11:26:39 +08:00
}
2026-07-30 16:48:56 +08:00
.card-title {
2026-08-07 17:38:26 +08:00
font-size: 40rpx;
2026-07-30 16:48:56 +08:00
line-height: 44rpx;
2026-08-07 17:38:26 +08:00
font-weight: bold;
2026-07-27 11:26:39 +08:00
}
2026-07-30 16:48:56 +08:00
.card-description {
2026-08-07 17:38:26 +08:00
margin-top: 20rpx;
font-size: 28rpx;
2026-07-30 16:48:56 +08:00
line-height: 32rpx;
2026-07-27 11:26:39 +08:00
white-space: nowrap;
}
2026-07-30 16:48:56 +08:00
.card-arrow {
position: absolute;
z-index: 2;
top: 28rpx;
right: 24rpx;
font-family: Arial, sans-serif;
font-size: 48rpx;
font-weight: 300;
line-height: 38rpx;
2026-07-27 11:26:39 +08:00
}
2026-07-30 16:48:56 +08:00
.card-watermark {
position: absolute;
right: 22rpx;
bottom: 16rpx;
width: 48rpx;
height: 54rpx;
2026-08-07 17:38:26 +08:00
opacity: 0.9;
2026-07-27 11:26:39 +08:00
}
2026-07-30 16:48:56 +08:00
.service-section {
2026-08-07 17:38:26 +08:00
margin-top: 36rpx;
2026-07-27 11:26:39 +08:00
}
2026-07-30 16:48:56 +08:00
.section-title {
display: block;
font-size: 34rpx;
line-height: 48rpx;
2026-07-27 11:26:39 +08:00
font-weight: 600;
2026-07-30 16:48:56 +08:00
color: #183663;
2026-07-27 11:26:39 +08:00
}
2026-07-30 16:48:56 +08:00
.service-list {
2026-07-27 11:26:39 +08:00
display: flex;
2026-07-30 16:48:56 +08:00
justify-content: space-between;
2026-08-07 17:38:26 +08:00
margin-top: 24rpx;
2026-07-27 11:26:39 +08:00
}
2026-07-30 16:48:56 +08:00
.service-item {
width: 190rpx;
2026-07-27 11:26:39 +08:00
display: flex;
flex-direction: column;
align-items: center;
}
2026-07-30 16:48:56 +08:00
.service-icon-wrap {
height: 104rpx;
2026-07-27 11:26:39 +08:00
display: flex;
align-items: center;
2026-07-30 16:48:56 +08:00
justify-content: center;
2026-07-27 11:26:39 +08:00
}
2026-07-30 16:48:56 +08:00
.service-icon {
width: 92rpx;
height: 104rpx;
2026-07-27 11:26:39 +08:00
}
2026-07-30 16:48:56 +08:00
.service-title {
margin-top: 24rpx;
color: #183663;
2026-07-27 11:26:39 +08:00
font-size: 28rpx;
2026-08-07 17:38:26 +08:00
line-height: 1em;
2026-07-30 16:48:56 +08:00
font-weight: 500;
white-space: nowrap;
2026-07-27 11:26:39 +08:00
}
</style>