fix: 需求调整

This commit is contained in:
huxuejian 2026-08-04 16:45:11 +08:00
parent 4baf5d307c
commit 022ed92e38
21 changed files with 522 additions and 283 deletions

View File

@ -1,30 +1,19 @@
<template> <template>
<view v-if="shouldRender"> <view v-if="shouldRender">
<pass-rx-card v-if="payload && payload.data === 'AUDIPASS'" :extension="payload.extension" /> <pass-rx-card v-if="payload && payload.data === 'AUDITPASS'" :extension="payload.extension" />
<view <open-rx-fail-card v-else-if="payload && payload.data === 'AUTORXFAIL'" :extension="payload.extension" />
v-else-if="isVideoConsult && videoConsultDisplayText" <view v-else-if="isVideoConsult && videoConsultDisplayText" class="chat-row"
class="chat-row" :class="[messageFlow === 'out' ? 'chat-row--end' : '']">
:class="[messageFlow === 'out' ? 'chat-row--end' : '']" <image :src="avatarSrc" class="chat-avatar chat-avatar--square"
> :class="[messageFlow === 'out' ? 'chat-avatar--right' : '']" />
<image
:src="avatarSrc"
class="chat-avatar chat-avatar--square"
:class="[messageFlow === 'out' ? 'chat-avatar--right' : '']"
/>
<view class="chat-row-content"> <view class="chat-row-content">
<view <view class="video-record-bubble" :class="[messageFlow === 'out' ? 'my-message' : '']">
class="video-record-bubble"
:class="[messageFlow === 'out' ? 'my-message' : '']"
>
<image class="video-record-icon" :src="videoIconSrc" mode="aspectFit" /> <image class="video-record-icon" :src="videoIconSrc" mode="aspectFit" />
<text class="video-record-text">{{ videoConsultDisplayText }}</text> <text class="video-record-text">{{ videoConsultDisplayText }}</text>
</view> </view>
</view> </view>
</view> </view>
<view <view v-else-if="showSystemTip" class="message-item">
v-else-if="showSystemTip"
class="message-item"
>
系统提示{{ payload.extension }} 系统提示{{ payload.extension }}
</view> </view>
</view> </view>
@ -32,6 +21,7 @@
<script setup> <script setup>
import { computed } from "vue"; import { computed } from "vue";
import PassRxCard from "./rx-pass-card.vue"; import PassRxCard from "./rx-pass-card.vue";
import OpenRxFailCard from "./rx-open-fail-card.vue";
// messageItem.payload data: startChat , endChat , // messageItem.payload data: startChat , endChat ,
const props = defineProps({ const props = defineProps({
@ -96,7 +86,7 @@ const showSystemTip = computed(() => {
const shouldRender = computed(() => { const shouldRender = computed(() => {
const pl = payload.value || {}; const pl = payload.value || {};
return ( return (
(pl && pl.data === "AUDIPASS") || (pl && pl.data === "AUDITPASS") ||
(isVideoConsult.value && !!videoConsultDisplayText.value) || (isVideoConsult.value && !!videoConsultDisplayText.value) ||
showSystemTip.value showSystemTip.value
); );

View File

@ -0,0 +1,111 @@
<template>
<view class="rx-fail-card border shadow-lg rounded" :style="elderVarStyle">
<view class="fail-title-row">
<view class="warning-icon">!</view>
<text class="fail-title">处方开具失败</text>
</view>
<view class="reason-row">
<text class="reason-label">原因</text>
<text class="reason-text">{{ reason }}</text>
</view>
</view>
</template>
<script setup>
import { computed, onMounted } from "vue";
import { storeToRefs } from "pinia";
import useElder from "@/hooks/useElder";
const { elderVarStyle } = storeToRefs(useElder());
const props = defineProps({
extension: {
type: [Object, String],
default: () => ({}),
},
});
const ext = computed(() => {
if (props.extension && typeof props.extension === 'object') {
return props.extension;
}
if (typeof props.extension !== 'string') return {};
const value = props.extension.trim();
if (!value) return {};
try {
const data = JSON.parse(value);
return data && typeof data === 'object' ? data : { reason: String(data || '') };
} catch (e) {
return { reason: value };
}
});
const reason = computed(() => {
const value = ext.value && ext.value.reason;
return typeof value === 'string' && value.trim()
? value.trim()
: '未获取到失败原因,请稍后重试。';
});
onMounted(() => {
uni.$emit('autoRxFail');
})
</script>
<style scoped>
.rx-fail-card {
box-sizing: border-box;
max-width: 100%;
margin-bottom: 30rpx;
padding: 24rpx 30rpx;
background: #fff;
}
.fail-title-row {
display: flex;
align-items: center;
}
.warning-icon {
flex-shrink: 0;
width: 30rpx;
height: 30rpx;
color: #fff;
background: #f04438;
border-radius: 50%;
font-size: 22rpx;
font-weight: 700;
line-height: 30rpx;
text-align: center;
}
.fail-title {
margin-left: 12rpx;
color: #f04438;
font-size: var(--text-base);
font-weight: 500;
line-height: 1.4;
}
.reason-row {
display: flex;
align-items: flex-start;
margin-top: 18rpx;
color: #4b5563;
font-size: var(--text-base);
line-height: 1.75;
}
.reason-label {
flex-shrink: 0;
color: #374151;
}
.reason-text {
flex: 1;
min-width: 0;
color: #4b5563;
word-break: break-all;
}
</style>

View File

@ -25,8 +25,8 @@ const onClick = useDebounce(() => {
} }
.footer-button { .footer-button {
height: 44px; height: 88rpx;
line-height: 43px; line-height: 86rpx;
font-size: var(--text-lg); font-size: var(--text-lg);
background: $theme-brown-primary; background: $theme-brown-primary;
color: #fff; color: #fff;

View File

@ -33,7 +33,7 @@ function refresh() {
} }
.refresh-text{ .refresh-text{
font-size: 24rpx; font-size: 24rpx;
color: #7d451a; color: #0f9f8d;
text-align: center; text-align: center;
} }
</style> </style>

View File

@ -33,7 +33,7 @@
"title": "【测试】支付宝", "title": "【测试】支付宝",
"env": { "env": {
"UNI_PLATFORM": "mp-alipay", "UNI_PLATFORM": "mp-alipay",
"API_BASE_URL": "https://patient.youcan365.com/zyt", "API_BASE_URL": "https://patient.youcan365.com/hn",
"CORP_ID": "4G7H8J2K9L0M1N3P5Q6R7S8T9U", "CORP_ID": "4G7H8J2K9L0M1N3P5Q6R7S8T9U",
"APP_ID": "2021004129669493", "APP_ID": "2021004129669493",
"ORDER_SOURCE": "ALIPAY_MINI", "ORDER_SOURCE": "ALIPAY_MINI",

View File

@ -50,21 +50,20 @@
consult?.orderStatus === 'completed' consult?.orderStatus === 'completed'
"> ">
</consult-countdown> </consult-countdown>
<view v-if="canSendMessage && footerBtnMode === 'settle'" class="bg-light-gray px-15 pb-10" <view v-if="canSendMessage && footerBtnMode === 'reEdit'" class="bg-light-gray px-15 pb-10"
:style="elderVarStyle"> :style="elderVarStyle">
<view class="flex mb-10"> <view class="flex mb-10">
<view class="border bg-white inline px-10 py-5 rounded-full text-base text-dark" <view class="border bg-white inline px-10 py-5 rounded-full text-base text-dark"
@click="footerBtnMode = 'input'">回复医生</view> @click="footerBtnMode = 'input'">回复医生</view>
</view> </view>
<view class="w-full py-12 text-center text-base text-white bg-primary rounded" @click="settleRx()"> <view class="w-full py-12 text-center text-base text-white bg-primary rounded" @click="reEditOrder()">
{{ orderRx.btnText }} 重新编辑问诊信息
</view> </view>
</view> </view>
<template v-else-if="canSendMessage && footerBtnMode === 'input'"> <template v-else-if="canSendMessage && footerBtnMode === 'input'">
<view v-if="orderRx && orderRx.prescriptionType === 'onlineMedicinePurchase'" class="px-15 flex bg-light-gray" <view v-if="canReEdit" class="px-15 flex bg-light-gray" :style="elderVarStyle">
:style="elderVarStyle"> <view class="px-10 py-5 rounded-full bg-primary text-base text-white" @click="reEditOrder()">
<view class="px-10 py-5 rounded-full bg-primary text-base text-white" @click="settleRx()"> 重新编辑问诊信息
{{ orderRx.btnText }}
</view> </view>
</view> </view>
<!-- 若处于接听模式则不显示输入框 --> <!-- 若处于接听模式则不显示输入框 -->
@ -78,19 +77,17 @@
<script setup> <script setup>
import { ref, computed, nextTick, watch, onMounted, onUnmounted } from "vue"; import { ref, computed, nextTick, watch, onMounted, onUnmounted } from "vue";
import { storeToRefs } from "pinia"; import { storeToRefs } from "pinia";
import { onLoad, onUnload, onHide,onShow } from "@dcloudio/uni-app"; import { onLoad, onUnload, onHide } from "@dcloudio/uni-app";
import dayjs from "dayjs"; import dayjs from "dayjs";
import { useIMStore } from "@/store/tim"; import { useIMStore } from "@/store/tim";
import useElder from "@/hooks/useElder"; import useElder from "@/hooks/useElder";
import useUser from "@/hooks/useUser";
import { import {
getPatientOrder, getPatientOrder,
getMrtcConfig, getMrtcConfig,
notifyVideoRoomEnded, notifyVideoRoomEnded,
getRxMedicinePurchaseOrderId,
getRxMedicineOrderStatus
} from "@/utils/api"; } from "@/utils/api";
import { toast, loading as showLoading, hideLoading } from "@/utils/widget"; import { set } from "@/utils/cache";
import { toast } from "@/utils/widget";
import formatMessageTime from "./formatMessageTime"; import formatMessageTime from "./formatMessageTime";
import fullPage from "@/components/full-page.vue"; import fullPage from "@/components/full-page.vue";
@ -104,7 +101,6 @@ import ConsultMessageCustom from "@/components/custom-message/consult-message-cu
// //
const { elderMode, elderVarStyle } = storeToRefs(useElder()); const { elderMode, elderVarStyle } = storeToRefs(useElder());
const { userInfo } = useUser();
const imStore = useIMStore(); const imStore = useIMStore();
const conversationID = ref(""); const conversationID = ref("");
@ -128,8 +124,9 @@ const lastMessageTime = ref(Date.now()); // 最后一次收到消息的时间
const messageTimeoutTimer = ref(null); // const messageTimeoutTimer = ref(null); //
const messageReceiveTimeout = ref(false); // const messageReceiveTimeout = ref(false); //
const MESSAGE_TIMEOUT = 30000; // 30 const MESSAGE_TIMEOUT = 30000; // 30
const orderRx = ref(null); const canReEdit = ref(false);
const footerBtnMode = ref('input'); // input settle const reEditing = ref(false);
const footerBtnMode = ref('input'); // input reEdit
// //
let rtcRingtoneCtx = null; let rtcRingtoneCtx = null;
@ -558,12 +555,10 @@ function endRtcSession() {
// //
onLoad(async (options) => { onLoad(async (options) => {
uni.$on('rxHasAuditPassed', (rx) => { uni.$on('autoRxFail', () => {
orderRx.value = rx; footerBtnMode.value = 'reEdit';
orderRx.value.btnText = '医保结算'; canReEdit.value = true;
footerBtnMode.value = 'settle'; })
getMedicineOrderStatus()
});
if (!imStore.isLogin || !imStore.isSDKReady) { if (!imStore.isLogin || !imStore.isSDKReady) {
uni.reLaunch({ uni.reLaunch({
url: "/pages/home/home", url: "/pages/home/home",
@ -622,54 +617,6 @@ onLoad(async (options) => {
} }
}); });
onShow(() => {
getMedicineOrderStatus();
})
async function settleRx() {
showLoading();
const res = await getRxMedicinePurchaseOrderId({
accountId: userInfo.value.userId,
rpNo: orderRx.value.id
});
hideLoading()
if (res && res.success) {
if (res.status === 'unpay') {
uni.navigateTo({
url: `/pages/consult/drug-purchase-order/drug-purchase-order?id=${res.id}`
})
}
else if (res.status === 'expired') {
toast('订单已过期');
}
else {
uni.navigateTo({
url: `/pages/consult/drug-purchase-list/detail?id=${res.id}`
})
}
} else {
toast(res.message || '获取在线配药订单失败');
}
}
async function getMedicineOrderStatus() {
if (orderRx.value && orderRx.value.id) {
const res = await getRxMedicineOrderStatus({
accountId: userInfo.value.userId,
id: orderRx.value.id
});
if (res && res.success) {
const { expired, orderStatus } = res.data;
if (!expired && ['none', 'unpay'].includes(orderStatus)) {
orderRx.value.btnText = '医保结算';
} else {
orderRx.value.btnText = '查看订单';
}
}
}
}
// //
onMounted(() => { onMounted(() => {
setTimeout(() => { setTimeout(() => {
@ -679,7 +626,7 @@ onMounted(() => {
// //
onUnload(() => { onUnload(() => {
uni.$off('rxHasAuditPassed'); uni.$off('autoRxFail');
// //
imStore.currentConversation = null; imStore.currentConversation = null;
// //
@ -865,16 +812,22 @@ function closeChat() {
} }
async function getOrderDetail(showInfoWindow = false) { async function getOrderDetail(showInfoWindow = false) {
const { success, data, message } = await getPatientOrder({ try {
orderId: orderId.value, const { success, data } = await getPatientOrder({
}); orderId: orderId.value,
if (success) { });
consult.value = data; if (success) {
if (showInfoWindow) { consult.value = data;
judgeDisplayInfoWindow(data); if (showInfoWindow) {
judgeDisplayInfoWindow(data);
}
return data;
} }
} else {
consult.value = null; consult.value = null;
return null;
} catch (error) {
consult.value = null;
return null;
} }
} }
@ -1114,6 +1067,48 @@ const handleMessageTimeout = async () => {
uni.hideLoading(); uni.hideLoading();
} }
}; };
async function reEditOrder() {
if (reEditing.value) return;
const pages = getCurrentPages();
const pageRoutes = pages.map((page) => {
const route = page && (page.route || (page.$page && page.$page.route));
return typeof route === 'string' ? route.replace(/^\/+/, '') : '';
});
const diseasePageIndex = pageRoutes.lastIndexOf('pages/consult/disease-description');
const orderDetailPageIndex = pageRoutes.lastIndexOf('pages/record/order-detail');
if (diseasePageIndex >= 0 && diseasePageIndex > orderDetailPageIndex) {
const delta = pages.length - 1 - diseasePageIndex;
uni.navigateBack({ delta: Math.max(1, delta) });
return;
}
reEditing.value = true;
try {
const record = consult.value && consult.value.orderId === orderId.value
? consult.value
: await getOrderDetail();
if (!record || !record.orderId) {
toast('获取本次问诊资料失败,请稍后重试');
return;
}
if (!set('re-edit-consult-order', record, 300)) {
toast('暂存问诊资料失败,请稍后重试');
return;
}
const feeType = encodeURIComponent(record.feeType || '');
const socialno = encodeURIComponent(record.idCard || record.socialno || '');
const currentOrderId = encodeURIComponent(record.orderId);
uni.redirectTo({
url: `/pages/consult/disease-description?reEdit=1&orderId=${currentOrderId}&feeType=${feeType}&socialno=${socialno}`,
});
} finally {
reEditing.value = false;
}
}
</script> </script>
<style> <style>
@ -1287,16 +1282,16 @@ input {
background-color: #ff4d4f; background-color: #ff4d4f;
color: white; color: white;
font-size: 24rpx; font-size: 24rpx;
padding: 12rpx 24rpx; padding: 0 24rpx;
margin-left: 20rpx; margin-left: 20rpx;
border-radius: 8rpx; border-radius: 8rpx;
line-height: 1.4;
min-width: 100rpx; min-width: 100rpx;
white-space: nowrap; white-space: nowrap;
border: none; border: none;
display: inline-block;
text-align: center; text-align: center;
flex-shrink: 0; flex-shrink: 0;
height: 44rpx;
line-height: 44rpx;
} }
.message-timeout-error { .message-timeout-error {

View File

@ -53,7 +53,7 @@
<radio-group class="radio-group"> <radio-group class="radio-group">
<label v-for="i in history.options" :key="i" class="radio-label"> <label v-for="i in history.options" :key="i" class="radio-label">
<radio :value="i" :checked="form[history.prop] === i" @change="changeHistory(history.prop, i)" <radio :value="i" :checked="form[history.prop] === i" @change="changeHistory(history.prop, i)"
class="custom-radio" color="#b8956a" /> class="custom-radio" :color="themeColor" />
<text>{{ i }}</text> <text>{{ i }}</text>
</label> </label>
</radio-group> </radio-group>
@ -75,6 +75,7 @@ import { get, remove } from "@/utils/cache";
import { uploadUrl, getFullPath } from '@/utils/http'; import { uploadUrl, getFullPath } from '@/utils/http';
import { toast, loading, hideLoading } from '@/utils/widget'; import { toast, loading, hideLoading } from '@/utils/widget';
import { themeBg, themeColor, themeSecondary } from "@/utils/theme-config";
import footerButton from '@/components/footer-button.vue'; import footerButton from '@/components/footer-button.vue';
import fullPage from '@/components/full-page.vue'; import fullPage from '@/components/full-page.vue';
@ -89,7 +90,7 @@ const guessList = [
'储备的药品已用完,要求开方配药' '储备的药品已用完,要求开方配药'
] ]
const { order: form, histories, medTypeList } = storeToRefs(orderStore()); const { order: form, histories, medTypeList } = storeToRefs(orderStore());
const { init: initOrder } = orderStore(); const { init: initOrder, restoreForEdit } = orderStore();
const visible = ref(false); const visible = ref(false);
const guessVisible = ref(false); const guessVisible = ref(false);
const reachBottom = ref(false); const reachBottom = ref(false);
@ -235,9 +236,19 @@ function onReachBottom() {
} }
onLoad((options) => { onLoad((options) => {
const hisArchive = get("current-his-archive"); if (options.reEdit === '1') {
remove("current-his-archive"); const record = get('re-edit-consult-order');
initOrder({ feeType: options.feeType, socialno: options.socialno,hisArchive }); remove('re-edit-consult-order');
if (!record || record.orderId !== options.orderId || !restoreForEdit(record)) {
toast('问诊资料已失效,请重新进入聊天室操作');
uni.navigateBack();
return;
}
} else {
const hisArchive = get("current-his-archive");
remove("current-his-archive");
initOrder({ feeType: options.feeType, socialno: options.socialno, hisArchive });
}
uni.setNavigationBarTitle({ uni.setNavigationBarTitle({
title: titleMap[options.feeType] || '' title: titleMap[options.feeType] || ''
}) })

View File

@ -1,27 +1,25 @@
<template> <template>
<full-page pageStyle="background: #f5f6f7;"> <full-page :pageStyle="`background: ${themeBg};`">
<view v-if="logined" class="container" :class="{ 'container--elder': elderMode }"> <view v-if="logined" class="container">
<view class="header" :class="{ 'header--elder': elderMode }"> <view class="header">
<text class="title" :class="{ 'title--elder': elderMode }">选择就诊人</text> <text class="title">选择就诊人</text>
<button class="scan-button" :class="{ 'scan-button--elder': elderMode }" :disabled="scanning" <button class="scan-button rounded-sm" :disabled="scanning" @click="scanInsuranceCode">扫医保码</button>
@click="scanInsuranceCode">{{ scanning ? "读取中..." : "扫医保码" }}</button>
</view> </view>
<view class="patient-list"> <view class="patient-list">
<view v-for="patient in patientList" :key="patient.id" class="patient-card" <view v-for="patient in patientList" :key="patient.id" class="patient-card"
:class="{ 'patient-card--elder': elderMode }" @click="toggle(patient.id)"> :class="{ 'patient-card--selected': selectedPatientId === patient.id }" @click="toggle(patient.id)">
<view class="patient-info"> <view class="patient-info">
<view class="name" :class="{ 'name--elder': elderMode }"> <view class="name">
{{ patient.name }} {{ patient.name }}
<text v-if="patient.isSelf" class="self-tag">本人</text> <text v-if="patient.isSelf" class="self-tag">本人</text>
</view> </view>
<view class="details" :class="{ 'details--elder': elderMode }"> <view class="details">
<text v-if="patient.sex">{{ patient.sex }}</text> <text v-if="patient.sex">{{ patient.sex }}</text>
<text v-if="patient.age" class="age">{{ patient.age }}</text> <text v-if="patient.age" class="age">{{ patient.age }}</text>
</view> </view>
</view> </view>
<uni-icons v-if="selectedPatientId === patient.id" type="checkbox-filled" color="#3375f6" <uni-icons v-if="selectedPatientId === patient.id" type="checkbox-filled" :color="themeColor" :size="22" />
:size="elderMode ? 34 : 22" />
</view> </view>
<view v-if="!patientList.length" class="empty-text">暂无就诊人</view> <view v-if="!patientList.length" class="empty-text">暂无就诊人</view>
@ -32,13 +30,13 @@
<template v-if="logined" #footer> <template v-if="logined" #footer>
<view class="footer"> <view class="footer">
<view class="button-group" :class="{ 'button-group--elder': elderMode }"> <view class="button-group">
<button class="action-button add-button" @click="toAddPatient">+ 新增就诊人</button> <button class="action-button add-button rounded" @click="toAddPatient">+ 新增就诊人</button>
<button class="action-button next-button" @click="nextStep">下一步</button> <button class="action-button next-button rounded" @click="nextStep">下一步</button>
</view> </view>
<view class="manage-link" :class="{ 'manage-link--elder': elderMode }" @click="toPatientManagement"> <view class="manage-link" @click="toPatientManagement">
<text>最多添加10位就诊人点击就诊人管理</text> <text>最多添加10位就诊人点击就诊人管理</text>
<uni-icons type="right" color="#8b8b8b" :size="elderMode ? 24 : 16" /> <uni-icons type="right" :color="themeSecondary" :size="16" />
</view> </view>
</view> </view>
</template> </template>
@ -53,12 +51,12 @@ import useUser from "@/hooks/useUser";
import { bindHisPatient, getHisCustomer, getScannedCard } from "@/utils/api"; import { bindHisPatient, getHisCustomer, getScannedCard } from "@/utils/api";
import { set } from "@/utils/cache"; import { set } from "@/utils/cache";
import { toast } from "@/utils/widget"; import { toast } from "@/utils/widget";
import { themeBg, themeColor, themeSecondary } from "@/utils/theme-config";
import reLogin from "@/components/re-login.vue"; import reLogin from "@/components/re-login.vue";
import ybPlugin from "@/utils/insurance-plugin"; import ybPlugin from "@/utils/insurance-plugin";
import fullPage from "@/components/full-page.vue"; import fullPage from "@/components/full-page.vue";
const { elderMode } = useElder();
const { const {
logined, logined,
getAuthCode, getAuthCode,
@ -255,7 +253,7 @@ function toPatientManagement() {
.title { .title {
font-size: 28rpx; font-size: 28rpx;
color: #222; color: #344743;
} }
.scan-button { .scan-button {
@ -263,11 +261,10 @@ function toPatientManagement() {
height: 64rpx; height: 64rpx;
margin: 0; margin: 0;
padding: 0; padding: 0;
border-radius: 4rpx; background: #0f9f8d;
background: #3375f6;
color: #fff; color: #fff;
font-size: 26rpx; font-size: 26rpx;
line-height: 64rpx; line-height: 62rpx;
} }
.scan-button::after, .scan-button::after,
@ -276,7 +273,7 @@ function toPatientManagement() {
} }
.patient-list { .patient-list {
background: #eceeef; background: #e8f8f5;
} }
.patient-card { .patient-card {
@ -293,6 +290,11 @@ function toPatientManagement() {
margin-top: 8rpx; margin-top: 8rpx;
} }
.patient-card--selected {
background: #e8f8f5;
box-shadow: inset 4rpx 0 0 #0f9f8d;
}
.patient-info { .patient-info {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@ -305,7 +307,7 @@ function toPatientManagement() {
} }
.self-tag { .self-tag {
color: #116f38; color: #0f9f8d;
} }
.details { .details {
@ -339,78 +341,33 @@ function toPatientManagement() {
} }
.action-button { .action-button {
height: 72rpx; height: 88rpx;
margin: 0; margin: 0;
padding: 0; padding: 0;
border-radius: 4rpx;
font-size: 28rpx; font-size: 28rpx;
line-height: 70rpx; line-height: 88rpx;
} }
.add-button { .add-button {
width: 244rpx; width: 244rpx;
border: 2rpx solid #3375f6; border: 2rpx solid #0f9f8d;
background: #fff; background: #fff;
color: #3375f6; color: #0f9f8d;
} }
.next-button { .next-button {
flex: 1; flex: 1;
background: #3375f6; background: #0f9f8d;
color: #fff; color: #fff;
} }
.manage-link { .manage-link {
min-height: 50rpx; padding: 24rpx 0;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
font-size: 23rpx; font-size: 24rpx;
color: #8b8b8b; color: #344743;
} }
.container--elder {
padding: 0 24rpx 32rpx;
}
.header--elder {
height: 128rpx;
}
.title--elder {
font-size: 38rpx;
}
.scan-button--elder {
width: 196rpx;
height: 80rpx;
font-size: 34rpx;
line-height: 80rpx;
}
.patient-card--elder {
min-height: 156rpx;
padding: 24rpx 40rpx;
}
.name--elder {
font-size: 38rpx;
line-height: 52rpx;
}
.details--elder {
font-size: 32rpx;
line-height: 44rpx;
}
.button-group--elder .action-button {
height: 92rpx;
font-size: 36rpx;
line-height: 90rpx;
}
.manage-link--elder {
min-height: 68rpx;
font-size: 30rpx;
}
</style> </style>

View File

@ -303,6 +303,12 @@ async function checkStock() {
async function submit(ignoreUnsuit = false, ignoreRepeat = false) { async function submit(ignoreUnsuit = false, ignoreRepeat = false) {
if (waiting.value) return; if (waiting.value) return;
const hasDisease = Array.isArray(order.value.diseases)
&& order.value.diseases.some(disease => typeof disease === 'string' && disease.trim());
if (!hasDisease) {
toast('请选择疾病');
return;
}
if (order.value.drugs.length == 0) { if (order.value.drugs.length == 0) {
toast('请添加药品'); toast('请添加药品');
return; return;

View File

@ -1,71 +1,72 @@
<template> <template>
<view class="page-container" :class="{ 'elder-mode': elderMode }"> <full-page mainStyle="background:#f0f0f0" @reachBottom="loadMore">
<view class="search-container" :class="{ 'search-container--elder': elderMode }"> <template #header>
<view class="search" :class="{ 'search--elder': elderMode }"> <view class="search-container" :class="{ 'search-container--elder': elderMode }">
<uni-icons class="search-icon" type="search" :size="elderMode ? 36 : 28"></uni-icons> <view class="search" :class="{ 'search--elder': elderMode }">
<input v-model="keyword" type="text" placeholder="搜索药品" class="search-input" <uni-icons class="search-icon" type="search" :size="elderMode ? 36 : 28"></uni-icons>
:class="{ 'search-input--elder': elderMode }" /> <input v-model="keyword" type="text" placeholder="搜索药品" class="search-input"
<view class="search-btn" :class="{ 'search-btn--elder': elderMode }" :style="keyword ? '' : 'opacity:0'" :class="{ 'search-input--elder': elderMode }" />
@click="clear()">取消</view> <view class="search-btn" :class="{ 'search-btn--elder': elderMode }" :style="keyword ? '' : 'opacity:0'"
</view> @click="clear()">取消</view>
<view class="scan-code flex flex-col items-center" :class="{ 'scan-code--elder': elderMode }" @click="scanCode">
<uni-icons class="" color="#999" type="scan" :size="elderMode ? 36 : 30"></uni-icons>
<view v-if="order.consultType === 'onlineMedicinePurchase'" class="text-dark">条形码</view>
</view>
</view>
<view class="drug-wrapper">
<scroll-view scroll-y="true" class="drug-list" @scrolltolower="loadMore">
<view v-for="drug in list" :key="drug._id" class="drug" :class="{ 'drug--elder': elderMode }"
@click="select(drug)">
<view class="drug-info" :class="{ 'drug-info--elder': elderMode }">
<view class="drug-name" :class="{ 'drug-name--elder': elderMode }">{{ drug.name }}</view>
<view v-if="drug.medication_proof_desc" class="drug-proof-tip"
:class="{ 'drug-proof-tip--elder': elderMode }">{{ proofTipText }}</view>
<view v-if="drug.specification" class="drug-spec" :class="{ 'drug-spec--elder': elderMode }">药品规格{{
drug.specification }}</view>
<view v-if="drug.manufacturer" class="drug-spec" :class="{ 'drug-spec--elder': elderMode }">{{
drug.manufacturer }}</view>
</view>
<view v-if="selectMap[drug._id]" class="drug-btn drug-btn--unactive"
:class="{ 'drug-btn--elder': elderMode }">已选择</view>
<view v-else class="drug-btn" :class="{ 'drug-btn--elder': elderMode }">选择该药</view>
</view> </view>
<uni-load-more v-if="loading && page > 1" status="loading"></uni-load-more> <view class="scan-code flex flex-col items-center" :class="{ 'scan-code--elder': elderMode }" @click="scanCode">
<view v-if="list.length === 0 && order.consultType === 'onlineMedicinePurchase'" <uni-icons class="" color="#999" type="scan" :size="elderMode ? 36 : 30"></uni-icons>
class="lack-tip-container flex flex-col items-center justify-center" :style="elderVarStyle"> <view v-if="order.consultType === 'onlineMedicinePurchase'" class="text-dark">条形码</view>
<image class="lack-img" :class="elderClass" src="/static/empty.svg" /> </view>
<view class="text-lg text-dark">搜索不到该药品</view> </view>
<view class="pt-5" @click="showRegPopup()"> </template>
<text class="mr-5 text-lg text-dark">您可进行</text> <view class="bg-white">
<text class="text-lg text-primary">缺货登记</text> <view v-for="drug in list" :key="drug._id" class="drug" :class="{ 'drug--elder': elderMode }"
</view> @click="select(drug)">
<view class="drug-info" :class="{ 'drug-info--elder': elderMode }">
<view class="drug-name" :class="{ 'drug-name--elder': elderMode }">{{ drug.name }}</view>
<view v-if="drug.medication_proof_desc" class="drug-proof-tip"
:class="{ 'drug-proof-tip--elder': elderMode }">
{{ proofTipText }}</view>
<view v-if="drug.specification" class="drug-spec" :class="{ 'drug-spec--elder': elderMode }">药品规格{{
drug.specification }}</view>
<view v-if="drug.manufacturer" class="drug-spec" :class="{ 'drug-spec--elder': elderMode }">{{
drug.manufacturer }}</view>
</view>
<view v-if="selectMap[drug._id]" class="drug-btn drug-btn--unactive" :class="{ 'drug-btn--elder': elderMode }">
已选择
</view>
<view v-else class="drug-btn" :class="{ 'drug-btn--elder': elderMode }">选择该药</view>
</view>
<uni-load-more v-if="loading && page > 1" status="loading"></uni-load-more>
<view v-if="list.length === 0 && order.consultType === 'onlineMedicinePurchase'"
class="lack-tip-container flex flex-col items-center justify-center" :style="elderVarStyle">
<image class="lack-img" :class="elderClass" src="/static/empty.svg" />
<view class="text-lg text-dark">搜索不到该药品</view>
<view class="pt-5" @click="showRegPopup()">
<text class="mr-5 text-lg text-dark">您可进行</text>
<text class="text-lg text-primary">缺货登记</text>
</view> </view>
</scroll-view>
</view>
<view class="my-drugs-container">
<view v-if="showDrugs" class="shopcart-list">
<my-drugs :drugs="drugs" :elderMode="elderMode" @edit="edit" @remove="cancel" />
</view> </view>
</view> </view>
<template #footer>
<view class="shopcart-footer" :class="{ 'shopcart-footer--elder': elderMode }" @click="showDrugs = !showDrugs"> <view class="my-drugs-container">
<image class="shopcart-icon" :class="{ 'shopcart-icon--elder': elderMode }" src="/static/shopcart.svg" /> <view v-if="showDrugs" class="shopcart-list">
<view class="shopcart-text" :class="{ 'shopcart-text--elder': elderMode }"> <my-drugs :drugs="drugs" :elderMode="elderMode" @edit="edit" @remove="cancel" />
<text>已选</text> </view>
<text class="shopcart-num" :class="{ 'shopcart-num--elder': elderMode }">{{ drugs.length }}</text>
<text>种药品</text>
</view> </view>
<view class="confirm-btn" <view class="shopcart-footer" :class="{ 'shopcart-footer--elder': elderMode }" @click="showDrugs = !showDrugs">
:class="[drugs.length ? '' : 'confirm-btn--unactive', { 'confirm-btn--elder': elderMode }]" <image class="shopcart-icon" :class="{ 'shopcart-icon--elder': elderMode }" src="/static/shopcart.svg" />
@click.stop="confirm">确认</view> <view class="shopcart-text" :class="{ 'shopcart-text--elder': elderMode }">
</view> <text>已选</text>
<view class="safearea-bottom" style="background: white;"></view> <text class="shopcart-num" :class="{ 'shopcart-num--elder': elderMode }">{{ drugs.length }}</text>
</view> <text>种药品</text>
</view>
<view class="confirm-btn"
:class="[drugs.length ? '' : 'confirm-btn--unactive', { 'confirm-btn--elder': elderMode }]"
@click.stop="confirm">确认</view>
</view>
</template>
</full-page>
<edit-popup :consultType="order.consultType" :drug="editDrug" :visible="showEditPopup" :elderMode="elderMode" <edit-popup :consultType="order.consultType" :drug="editDrug" :visible="showEditPopup" :elderMode="elderMode"
@close="showEditPopup = false" @change="changeDrug" /> @close="showEditPopup = false" @change="changeDrug" />
<view v-if="showDrugs" class="mask" @click="showDrugs = false"></view> <view v-if="showDrugs" class="mask" @click="showDrugs = false"></view>
<lack-reg-popup :order="order" :visible="visible" @close="visible = false" /> <lack-reg-popup :order="order" :visible="visible" @close="visible = false" />
<!-- 自定义确认弹窗仅用于本页面 --> <!-- 自定义确认弹窗仅用于本页面 -->
<confirm-popup :visible="customConfirmVisible" :title="customConfirmData.title" :content="customConfirmData.content" <confirm-popup :visible="customConfirmVisible" :title="customConfirmData.title" :content="customConfirmData.content"
:showCancel="customConfirmData.showCancel" :cancelText="customConfirmData.cancelText" :showCancel="customConfirmData.showCancel" :cancelText="customConfirmData.cancelText"
@ -87,6 +88,7 @@ import editPopup from './edit-popup.vue'
import myDrugs from './my-drugs.vue' import myDrugs from './my-drugs.vue'
import lackRegPopup from './lack-reg-popup.vue' import lackRegPopup from './lack-reg-popup.vue'
import confirmPopup from '@/components/confirm-popup.vue' import confirmPopup from '@/components/confirm-popup.vue'
import fullPage from '@/components/full-page.vue';
// //
const { elderMode, elderClass, elderVarStyle } = useElder(); const { elderMode, elderClass, elderVarStyle } = useElder();

View File

@ -108,15 +108,15 @@ watch(() => props.visible, n => {
} }
.cancel-btn { .cancel-btn {
color: #8b6f47; color: #344743;
border: 1px solid #d4c4a8; border: 1px solid #23c7b0;
background: transparent; background: transparent;
} }
.confirm-btn-active { .confirm-btn-active {
color: white; color: white;
background: #b8956a; background: #0f9f8d;
border: none; border: none;
box-shadow: 0 4rpx 12rpx rgba(139, 101, 56, 0.3); box-shadow: 0 4rpx 12rpx #23c7b0;
} }
</style> </style>

View File

@ -56,7 +56,7 @@
</view> </view>
</full-page> </full-page>
<store-popup :drugStore="drugStore" :visible="visible" :elderMode="elderMode" @confirm="confirmStoreInfo()" <store-popup :drugStore="drugStore" :visible="visible" @confirm="confirmStoreInfo()"
@close="visible = false" /> @close="visible = false" />
<confirm-popup title="提示" content="您是否半年内在医院就诊过?" cancelText="否" confirmText="是" :visible="confirmVisible" <confirm-popup title="提示" content="您是否半年内在医院就诊过?" cancelText="否" confirmText="是" :visible="confirmVisible"
@confirm="handleConfirmYes" @cancel="handleConfirmNo" @close="confirmVisible = false" /> @confirm="handleConfirmYes" @cancel="handleConfirmNo" @close="confirmVisible = false" />

View File

@ -103,7 +103,7 @@ watch(() => props.visible, n => {
font-size: 32rpx; font-size: 32rpx;
font-weight: bold; font-weight: bold;
line-height: 50rpx; line-height: 50rpx;
color: #8b6f47; color: #344743;
text-align: center; text-align: center;
&--elder { &--elder {
@ -144,9 +144,9 @@ watch(() => props.visible, n => {
line-height: 64rpx; line-height: 64rpx;
text-align: center; text-align: center;
font-size: 28rpx; font-size: 28rpx;
color: #8b6f47; color: #344743;
border-radius: 16rpx; border-radius: 16rpx;
border: 1px solid #d4c4a8; border: 1px solid #23c7b0;
@at-root &+& { @at-root &+& {
margin-left: 20rpx; margin-left: 20rpx;
@ -164,9 +164,9 @@ watch(() => props.visible, n => {
&__button--active { &__button--active {
color: white; color: white;
background: #b8956a; background: #0f9f8d;
border-color: transparent; border-color: transparent;
box-shadow: 0 4rpx 12rpx rgba(139, 101, 56, 0.3); box-shadow: 0 4rpx 12rpx #23c7b0;
&--elder { &--elder {
font-weight: bold; font-weight: bold;

View File

@ -41,8 +41,14 @@
</view> </view>
<view class="save-footer"> <view class="save-footer">
<view class="save-btn" :class="{ 'save-btn--disabled': loading }" @click="confirm"> <view class="footer-actions">
{{ loading ? '保存中...' : '保存' }} <view v-if="canDelete" class="delete-btn" :class="{ 'delete-btn--disabled': deleting }"
@click="removePatient">
{{ deleting ? '删除中...' : '删除' }}
</view>
<view class="save-btn" :class="{ 'save-btn--disabled': loading || deleting }" @click="confirm">
{{ loading ? '保存中...' : '保存' }}
</view>
</view> </view>
</view> </view>
<view class="safearea-bottom"></view> <view class="safearea-bottom"></view>
@ -59,6 +65,7 @@ import useUser from '@/hooks/useUser';
import { import {
addHisCustomer, addHisCustomer,
addHlwPatient, addHlwPatient,
deleteHlwPatient,
getHisCustomer, getHisCustomer,
getHlwPatient, getHlwPatient,
updateHlwPatient, updateHlwPatient,
@ -72,8 +79,10 @@ const id = ref('');
const type = ref(''); const type = ref('');
const feeType = ref(''); const feeType = ref('');
const loading = ref(false); const loading = ref(false);
const deleting = ref(false);
const elderMode = ref(false); const elderMode = ref(false);
const loadedPatientKey = ref(''); const loadedPatientKey = ref('');
const loadedPatientIsSelf = ref(null);
const scannedCard = ref(null); const scannedCard = ref(null);
const form = ref({ const form = ref({
name: '', name: '',
@ -85,6 +94,11 @@ const form = ref({
const { userInfo, logined, setTemporaryPatient } = useUser(); const { userInfo, logined, setTemporaryPatient } = useUser();
const accountId = computed(() => userInfo.value && userInfo.value.userId ? userInfo.value.userId : ''); const accountId = computed(() => userInfo.value && userInfo.value.userId ? userInfo.value.userId : '');
const isYbQrcode = computed(() => type.value === 'ybQrcode'); const isYbQrcode = computed(() => type.value === 'ybQrcode');
const canDelete = computed(() => (
Boolean(id.value)
&& loadedPatientKey.value === `${accountId.value}:${id.value}`
&& loadedPatientIsSelf.value === false
));
function validateForm() { function validateForm() {
if (!form.value.name.trim()) { if (!form.value.name.trim()) {
@ -124,7 +138,7 @@ function chooseAddress() {
} }
async function confirm() { async function confirm() {
if (loading.value || !validateForm()) return; if (loading.value || deleting.value || !validateForm()) return;
if (!accountId.value) { if (!accountId.value) {
toast('请先登录'); toast('请先登录');
return; return;
@ -165,6 +179,49 @@ async function confirm() {
} }
} }
function confirmDelete() {
return new Promise(resolve => {
uni.showModal({
title: '删除就诊人',
content: '删除后无法恢复,确定删除该就诊人档案吗?',
confirmText: '删除',
confirmColor: '#d14343',
success: result => resolve(Boolean(result.confirm)),
fail: () => resolve(false),
});
});
}
async function removePatient() {
if (loading.value || deleting.value || !canDelete.value) return;
const confirmed = await confirmDelete();
if (!confirmed || !canDelete.value) return;
deleting.value = true;
try {
const res = await deleteHlwPatient({
accountId: accountId.value,
id: id.value,
});
if (!res || !res.success) {
toast((res && res.message) || '删除失败');
return;
}
toast('删除成功');
const pages = getCurrentPages();
if (pages.length > 1) {
uni.navigateBack();
} else {
uni.redirectTo({ url: '/pages/member/list' });
}
} catch (error) {
toast(error.message || error || '删除失败');
} finally {
deleting.value = false;
}
}
async function saveYbQrcodePatient() { async function saveYbQrcodePatient() {
if (!scannedCard.value) { if (!scannedCard.value) {
toast('医保扫码信息已失效,请重新扫码'); toast('医保扫码信息已失效,请重新扫码');
@ -236,6 +293,7 @@ async function loadPatient() {
const patientKey = `${accountId.value}:${id.value}`; const patientKey = `${accountId.value}:${id.value}`;
if (loadedPatientKey.value === patientKey) return; if (loadedPatientKey.value === patientKey) return;
loadedPatientIsSelf.value = null;
loading.value = true; loading.value = true;
try { try {
const res = await getHlwPatient(accountId.value, id.value); const res = await getHlwPatient(accountId.value, id.value);
@ -249,6 +307,9 @@ async function loadPatient() {
mobile: res.data.mobile || '', mobile: res.data.mobile || '',
address: res.data.address || '', address: res.data.address || '',
}; };
const patientCertNo = typeof res.data.certNo === 'string' ? res.data.certNo.trim() : '';
const userCertNo = typeof userInfo.value.certNo === 'string' ? userInfo.value.certNo.trim() : '';
loadedPatientIsSelf.value = userCertNo ? patientCertNo === userCertNo : null;
loadedPatientKey.value = patientKey; loadedPatientKey.value = patientKey;
} catch (error) { } catch (error) {
toast(error.message || error || '查询就诊人失败'); toast(error.message || error || '查询就诊人失败');
@ -383,7 +444,13 @@ watch([id, accountId], loadPatient, { immediate: true });
background: white; background: white;
} }
.footer-actions {
display: flex;
gap: calc(20rpx * var(--spacing-scale));
}
.save-btn { .save-btn {
flex: 1;
height: calc(80rpx * var(--spacing-scale)); height: calc(80rpx * var(--spacing-scale));
background: $theme-brown-primary; background: $theme-brown-primary;
color: white; color: white;
@ -398,6 +465,24 @@ watch([id, accountId], loadPatient, { immediate: true });
} }
} }
.delete-btn {
box-sizing: border-box;
width: calc(220rpx * var(--spacing-scale));
height: calc(80rpx * var(--spacing-scale));
border: 2rpx solid #d14343;
color: #d14343;
background: #fff;
font-size: calc(28rpx * var(--font-scale));
border-radius: calc(16rpx * var(--border-radius-scale));
text-align: center;
line-height: calc(76rpx * var(--spacing-scale));
font-weight: 500;
&--disabled {
opacity: 0.6;
}
}
.safearea-bottom { .safearea-bottom {
height: env(safe-area-inset-bottom); height: env(safe-area-inset-bottom);
flex-shrink: 0; flex-shrink: 0;

View File

@ -21,7 +21,7 @@
<view class="group-name" :class="elderMode ? 'group-name--elder' : ''">其他就诊人</view> <view class="group-name" :class="elderMode ? 'group-name--elder' : ''">其他就诊人</view>
<view v-for="item in otherPatients" :key="item.id" class="user" :class="{ 'user--elder': elderMode }" <view v-for="item in otherPatients" :key="item.id" class="user" :class="{ 'user--elder': elderMode }"
@click="toDetail(item)"> @click="toDetail(item)">
<image class="avatar" src="/static/family-avatar.png"></image> <image class="avatar" src="/static/patient.svg"></image>
<view class="text-info"> <view class="text-info">
<view class="name-bar" :class="{ 'name-bar--elder': elderMode }"> <view class="name-bar" :class="{ 'name-bar--elder': elderMode }">
<view class="name">{{ item.maskName }}</view> <view class="name">{{ item.maskName }}</view>

1
static/patient.svg Normal file
View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1785814427270" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="10752" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M512 0C229.451852 0 0 229.451852 0 512s229.451852 512 512 512 512-229.451852 512-512S794.548148 0 512 0z m242.725926 777.481481c-13.274074 0-24.651852-11.377778-24.651852-24.651851 0-117.57037-96.711111-214.281481-214.281481-214.281482H510.103704c-117.57037 0-214.281481 96.711111-214.281482 214.281482 0 13.274074-11.377778 24.651852-24.651852 24.651851-13.274074 0-24.651852-11.377778-24.651851-24.651851 0-111.881481 70.162963-206.696296 166.874074-244.622223a166.115556 166.115556 0 0 1-68.266667-134.637037c0-91.022222 73.955556-164.977778 164.977778-164.977777 91.022222 0 164.977778 73.955556 164.977777 164.977777 0 54.992593-26.548148 102.4-68.266666 132.740741 98.607407 37.925926 170.666667 132.740741 170.666666 246.518519 1.896296 13.274074-9.481481 24.651852-22.755555 24.651851z" fill="#44C5BB" p-id="10753"></path><path d="M512 373.57037m-115.674074 0a115.674074 115.674074 0 1 0 231.348148 0 115.674074 115.674074 0 1 0-231.348148 0Z" fill="#44C5BB" p-id="10754"></path></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -1 +1,9 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1744714760403" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2460" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M974.5 374.5c-18.4-12.9-44.1-8.5-57.1 10l-33 47.1C846.6 232.8 671.8 81.9 462.2 81.9 225 81.9 32.1 274.9 32.1 512S225 942.1 462.2 942.1c99.4 0 196.4-34.7 273-97.8 17.5-14.4 20-40.2 5.6-57.7s-40.2-20-57.7-5.6c-62 51-140.5 79.1-221 79.1C270.2 860.2 114 704 114 512s156.2-348.2 348.2-348.2c172.9 0 316.3 126.7 343.2 292.1l-59.1-41.5c-18.4-12.9-44.1-8.5-57.1 10-12.9 18.4-8.5 44.1 10 57.1l134.1 94.2c18.4 12.9 44.1 8.5 57.1-10l94.2-134.1c12.9-18.5 8.4-44.1-10.1-57.1z" fill="#7d451a" p-id="2461"></path></svg> <?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg t="1744714760403" class="icon" viewBox="0 0 1024 1024" version="1.1"
xmlns="http://www.w3.org/2000/svg" p-id="2460" xmlns:xlink="http://www.w3.org/1999/xlink"
width="200" height="200">
<path
d="M974.5 374.5c-18.4-12.9-44.1-8.5-57.1 10l-33 47.1C846.6 232.8 671.8 81.9 462.2 81.9 225 81.9 32.1 274.9 32.1 512S225 942.1 462.2 942.1c99.4 0 196.4-34.7 273-97.8 17.5-14.4 20-40.2 5.6-57.7s-40.2-20-57.7-5.6c-62 51-140.5 79.1-221 79.1C270.2 860.2 114 704 114 512s156.2-348.2 348.2-348.2c172.9 0 316.3 126.7 343.2 292.1l-59.1-41.5c-18.4-12.9-44.1-8.5-57.1 10-12.9 18.4-8.5 44.1 10 57.1l134.1 94.2c18.4 12.9 44.1 8.5 57.1-10l94.2-134.1c12.9-18.5 8.4-44.1-10.1-57.1z"
fill="#0f9f8d" p-id="2461"></path>
</svg>

Before

Width:  |  Height:  |  Size: 837 B

After

Width:  |  Height:  |  Size: 855 B

View File

@ -162,17 +162,7 @@ export default defineStore("orderStore", () => {
return; return;
} }
const tmbxx = Array.isArray(hisArchive.tmbxx) ? hisArchive.tmbxx : []; const tmbxx = Array.isArray(hisArchive.tmbxx) ? hisArchive.tmbxx : [];
medTypeList.value = [outpatientMedType, { medTypeList.value = [outpatientMedType, ...tmbxx];
"med_type": "140201", "diseType": "特病",
"dise_codg": "M01600",
"dise_name": "糖尿病"
},
{
"med_type": "140104", "diseType": "慢病",
"dise_codg": "M03900",
"dise_name": "高血压"
}
];
const profile = patientList.value.find((i) => i.socialno === socialno); const profile = patientList.value.find((i) => i.socialno === socialno);
regFee.value = 0; regFee.value = 0;
order.value = { order.value = {
@ -200,6 +190,66 @@ export default defineStore("orderStore", () => {
console.log("order init", order.value); console.log("order init", order.value);
} }
function restoreForEdit(record) {
if (!record || typeof record !== "object") return false;
const medInfo = record.medInfo && typeof record.medInfo === "object"
? { ...record.medInfo }
: { ...outpatientMedType };
const medTypeKey = (item) => [
item && item.med_type,
item && item.diseType,
item && item.dise_codg,
item && item.dise_name,
].join("-");
medTypeList.value = [{ ...outpatientMedType }];
if (medTypeKey(medInfo) !== medTypeKey(outpatientMedType)) {
medTypeList.value.push({ ...medInfo });
}
const restoredOrder = {
accountId: record.accountId || userInfo.value.userId,
hospitalId: record.hospitalId || hospitalId,
areaCode: record.areaCode || "",
diseases: Array.isArray(record.diseases) ? [...record.diseases] : [],
description: typeof record.description === "string" ? record.description : "",
images: Array.isArray(record.images) ? [...record.images] : [],
drugs: Array.isArray(record.drugs)
? record.drugs.filter((drug) => drug && typeof drug === "object").map((drug) => ({
...drug,
proofImages: Array.isArray(drug.proofImages) ? [...drug.proofImages] : drug.proofImages,
}))
: [],
patientId: record.patientId || "",
idCard: record.idCard || record.socialno || "",
name: record.name || "",
mobile: record.mobile || record.tel || "",
blhno: record.blhno || "",
age: record.age || "",
sex: record.sex || "",
address: record.address || "",
orderSource: record.orderSource || orderSource,
feeType: record.feeType || "",
consultType: record.consultType || "",
medInfo,
visitRecord: record.visitRecord && typeof record.visitRecord === "object"
? { ...record.visitRecord }
: null,
};
histories.forEach((item) => {
restoredOrder[item.prop] = item.options.includes(record[item.prop])
? record[item.prop]
: item.options[1];
});
order.value = restoredOrder;
order.value.pastHistoryStr = pastHistoryStr.value;
ybVisitRecord.value = restoredOrder.visitRecord;
const chargeFee = Number(record.chargeFee);
regFee.value = Number.isFinite(chargeFee) ? chargeFee : 0;
return true;
}
function reuse(record) { function reuse(record) {
init(); init();
order.value.diseases = Array.isArray(record.diseases) order.value.diseases = Array.isArray(record.diseases)
@ -229,8 +279,7 @@ export default defineStore("orderStore", () => {
watch(ybVisitRecord, n => { watch(ybVisitRecord, n => {
if (n) { if (n) {
const { date, drugsStr, mdtrtId, medinsName } = n; order.value.visitRecord = { ...n }
order.value.visitRecord = { date, drugsStr, mdtrtId, medinsName }
} else { } else {
order.value.visitRecord = null; order.value.visitRecord = null;
} }
@ -240,6 +289,7 @@ export default defineStore("orderStore", () => {
return { return {
order, order,
init, init,
restoreForEdit,
ybVisitRecord, ybVisitRecord,
medTypeList, medTypeList,
regFee, regFee,

View File

@ -88,8 +88,15 @@ $uni-font-size-paragraph:15px;
/* ==================== 中医药主题色 ==================== */ /* ==================== 中医药主题色 ==================== */
/* 主题色变量 */ /* 主题色变量 */
$theme-brown-primary: #b8956a; // 金棕色 - 主要按钮选中状态 // $theme-brown-primary: #b8956a; // 金棕色 - 主要按钮选中状态
$theme-brown-secondary: #8b6f47; // 深棕色 - 文字图标 // $theme-brown-secondary: #8b6f47; // 深棕色 - 文字图标
$theme-brown-light: #f5ede0; // 浅米色 - 背景标签 // $theme-brown-light: #f5ede0; // 浅米色 - 背景标签
$theme-brown-border: #d4c4a8; // 边框色 // $theme-brown-border: #d4c4a8; // 边框色
$theme-brown-bg: #faf8f3; // 浅背景色 // $theme-brown-bg: #faf8f3; // 浅背景色
$theme-brown-primary: #0f9f8d; // 金棕色 - 主要按钮选中状态
$theme-brown-secondary: #344743; // 深棕色 - 文字图标
$theme-brown-light: #e8f8f5; // 浅米色 - 背景标签
$theme-brown-border: #23c7b0; // 边框色
$theme-brown-bg: #f7fbfa; // 浅背景色

View File

@ -150,6 +150,16 @@ export async function updateHlwPatient(data) {
}); });
} }
export async function deleteHlwPatient(data) {
return await request({
url: "/getYoucanData/hlw",
data: {
type: "deleteHlwPatient",
...data,
},
});
}
export async function sm4Encrypt(data) { export async function sm4Encrypt(data) {
return await request({ return await request({
url: "/getYoucanData/hlw", url: "/getYoucanData/hlw",

View File

@ -5,12 +5,18 @@
export const THEME_COLORS = { export const THEME_COLORS = {
// 中医药主题色 // 中医药主题色
primary: '#b8956a', // 金棕色 - 主要按钮、选中状态 // primary: '#b8956a', // 金棕色 - 主要按钮、选中状态
secondary: '#8b6f47', // 深棕色 - 文字、图标 // secondary: '#8b6f47', // 深棕色 - 文字、图标
light: '#f5ede0', // 浅米色 - 背景、标签 // light: '#f5ede0', // 浅米色 - 背景、标签
border: '#d4c4a8', // 边框色 // border: '#d4c4a8', // 边框色
bg: '#faf8f3', // 浅背景色 // bg: '#faf8f3', // 浅背景色
primary: '#0f9f8d', // 深青绿:主要按钮、选中状态
secondary: '#344743', // 品牌青绿:图标、强调文字
light: '#e8f8f5', // 淡薄荷色:标签、次级区域
border: '#23c7b0', // 明亮青绿:边框、焦点状态
bg: '#f7fbfa',
// 常用颜色 // 常用颜色
gray: '#999', gray: '#999',
darkGray: '#666', darkGray: '#666',