fix: 常用方、患者管理
Some checks failed
CI / Test (ubuntu-latest) (push) Has been cancelled
CI / Test (windows-latest) (push) Has been cancelled
CI / Lint (ubuntu-latest) (push) Has been cancelled
CI / Lint (windows-latest) (push) Has been cancelled
CI / Check (ubuntu-latest) (push) Has been cancelled
CI / Check (windows-latest) (push) Has been cancelled
CodeQL / Analyze (javascript-typescript) (push) Has been cancelled
Deploy Website on push / Deploy Push Playground Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Docs Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Antd Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Element Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Naive Ftp (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
CI / CI OK (push) Has been cancelled
Lock Threads / action (push) Has been cancelled
Issue Close Require / close-issues (push) Has been cancelled
Close stale issues / stale (push) Has been cancelled

This commit is contained in:
2025-12-26 16:48:46 +08:00
parent 7dc90731dc
commit 5c1f59e351
5 changed files with 210 additions and 6 deletions

View File

@@ -1,3 +1,4 @@
# 开发环境配置`n
# 应用标题
VITE_APP_TITLE=萧康云医
@@ -6,3 +7,6 @@ VITE_APP_NAMESPACE=xk-admin-
# 应用版本
XK_APP_VERSION=1.0.0
# WebSocket 连接地址
VITE_WS_URL=ws://localhost:12080/ws

View File

@@ -1,3 +1,4 @@
# 生产环境配置
VITE_BASE=/
# 接口地址
@@ -17,3 +18,6 @@ VITE_INJECT_APP_LOADING=true
# 打包后是否生成dist.zip
VITE_ARCHIVER=true
# WebSocket 连接地址
VITE_WS_URL=wss://api.ws.g.xiaokang88.com/ws

View File

@@ -5,6 +5,30 @@ import { isFunction } from '@vben/utils';
import SysAudioMp3 from '/public/audio/sys.mp3';
/**
* 检测是否为开发环境
* @returns boolean
*/
export const isDev = (): boolean => {
return import.meta.env.DEV;
};
/**
* 检测是否为生产环境
* @returns boolean
*/
export const isProd = (): boolean => {
return import.meta.env.PROD;
};
/**
* 获取 WebSocket URL
* @returns string WebSocket 连接地址
*/
export const getWebSocketUrl = (): string => {
return import.meta.env.VITE_WS_URL || 'ws://localhost:12080/ws';
};
export const playOnceAndDestroySys = () => {
const audio = new Audio(SysAudioMp3);

View File

@@ -1,5 +1,7 @@
import { onMounted, onUnmounted, ref } from 'vue';
import { getWebSocketUrl } from '#/util/tool';
import { useChatStore } from '../stores/chat';
import { useUserStore } from '../stores/user';
// useVbenUserStore
@@ -21,10 +23,7 @@ export function useWebSocket() {
chatStore.connectionStatus = 'connecting';
try {
// const wsUrl = import.meta.env.VITE_WS_URL || "wss://g-ws.nailaoyun.cn/ws"
const wsUrl = import.meta.env.VITE_WS_URL || 'ws://localhost:12080/ws';
// const wsUrl = 'wss://api.ws.g.xiaokang88.com/ws';
// const wsUrl = import.meta.env.VITE_WS_URL || "wss://g-ws.nailaoyun.cn/ws"
const wsUrl = getWebSocketUrl();
socket.value = new WebSocket(wsUrl);
socket.value.addEventListener('open', handleOpen);

View File

@@ -9,7 +9,7 @@
* @author 系统
* @date 2024
*/
import { ref } from 'vue';
import { h, ref } from 'vue';
import { Page, useVbenModal } from '@vben/common-ui';
@@ -31,10 +31,13 @@ import {
} from 'ant-design-vue';
import { UserOutlined } from '@ant-design/icons-vue';
import PrescriptionDetail from '#/views/doctor/doctor-reception/components/PrescriptionDetail.vue';
import {
getPatientDetailApi,
getPatientRegisterListApi,
getPatientPrescriptionListApi,
getPatientBaseInfoApi,
savePatientRemarkApi,
updatePatientRemarkApi,
type PatientDetail,
@@ -42,6 +45,27 @@ import {
type PrescriptionItem,
} from '../api';
// ==================== 类型定义 ====================
/**
* 健康信息类型
*/
interface UserPatientHealthInquiry {
id: number;
user_patient_id: number;
liver_function: number;
renal_function: number;
liver_index: string;
renal_index: string;
person_history: string;
allergic_history: string;
person_status: number;
allergic_status: number;
family_status: number;
family_history: string;
is_delete: number;
}
// ==================== 响应式数据 ====================
/**
@@ -104,6 +128,35 @@ const remarkContent = ref('');
*/
const hasRemark = ref(false);
/**
* 健康信息数据
*/
const healthInfo = ref<UserPatientHealthInquiry | null>(null);
// ==================== 处方详情弹窗 ====================
const [PrescriptionDetailModal, PrescriptionDetailModalApi] = useVbenModal({
connectedComponent: PrescriptionDetail,
});
/**
* 打开处方详情
* @param prescriptionId 处方ID
*/
function openPrescriptionDetail(prescriptionId: number) {
PrescriptionDetailModalApi.setData({ values: prescriptionId });
PrescriptionDetailModalApi.open();
}
/**
* 分割字符串为数组
* @param str 逗号分隔的字符串
*/
function splitString(str: string): string[] {
if (!str) return [];
return str.split(',').filter((item) => item.trim());
}
// ==================== 表格列配置 ====================
/**
@@ -126,7 +179,21 @@ const registerColumns = [
* 处方记录表格列
*/
const prescriptionColumns = [
{ title: '处方编号', dataIndex: 'prescription_no', key: 'prescription_no' },
{
title: '处方编号',
dataIndex: 'prescription_no',
key: 'prescription_no',
customRender: ({ text, record }: { text: string; record: PrescriptionItem }) => {
return h(
Button,
{
type: 'link',
onClick: () => openPrescriptionDetail(record.id),
},
() => text,
);
},
},
{
title: '类型',
dataIndex: 'prescription_type',
@@ -196,6 +263,8 @@ async function loadPatientDetail() {
patientDetail.value = res;
remarkContent.value = res.remark || '';
hasRemark.value = !!res.remark;
// 同时加载健康信息
loadHealthInfo();
} catch (error) {
console.error('获取患者详情失败:', error);
message.error('获取患者详情失败');
@@ -204,6 +273,19 @@ async function loadPatientDetail() {
}
}
/**
* 加载健康信息
*/
async function loadHealthInfo() {
try {
const res = await getPatientBaseInfoApi(patientId.value);
healthInfo.value = res || null;
} catch (error) {
console.error('获取健康信息失败:', error);
healthInfo.value = null;
}
}
/**
* 加载挂号记录
*/
@@ -401,6 +483,96 @@ function getSexText(sex: number): string {
</div>
</div>
</Card>
<!-- 健康信息 -->
<Card title="健康信息" class="mt-4">
<Descriptions
v-if="healthInfo"
:column="{ xxl: 2, xl: 2, lg: 2, md: 2, sm: 2, xs: 2 }"
bordered
>
<Descriptions.Item label="肝功能">
<span>{{
healthInfo.liver_function === 0 ? '正常' : '异常'
}}</span>
<p
v-if="healthInfo.liver_function === 1"
class="mt-3"
>
<Tag
v-for="item in splitString(healthInfo.liver_index)"
:key="item"
color="#455cda"
>
{{ item }}
</Tag>
</p>
</Descriptions.Item>
<Descriptions.Item label="肾功能">
<span>{{
healthInfo.renal_function === 0 ? '正常' : '异常'
}}</span>
<p
v-if="healthInfo.renal_function === 1"
class="mt-3"
>
<Tag
v-for="item in splitString(healthInfo.renal_index)"
:key="item"
color="#455cda"
>
{{ item }}
</Tag>
</p>
</Descriptions.Item>
<Descriptions.Item label="既往史">
<span>{{
healthInfo.person_status === 0 ? '无' : '有'
}}</span>
<p v-if="healthInfo.person_status === 1" class="mt-3">
<Tag
v-for="item in splitString(healthInfo.person_history)"
:key="item"
color="#455cda"
>
{{ item }}
</Tag>
</p>
</Descriptions.Item>
<Descriptions.Item label="过敏史">
<span>{{
healthInfo.allergic_status === 0 ? '无' : '有'
}}</span>
<p
v-if="healthInfo.allergic_status === 1"
class="mt-3"
>
<Tag
v-for="item in splitString(healthInfo.allergic_history)"
:key="item"
color="#455cda"
>
{{ item }}
</Tag>
</p>
</Descriptions.Item>
<Descriptions.Item label="家庭遗传史">
<span>{{
healthInfo.family_status === 0 ? '无' : '有'
}}</span>
<p v-if="healthInfo.family_status === 1" class="mt-3">
<Tag
v-for="item in splitString(String(healthInfo.family_history))"
:key="item"
color="#455cda"
>
{{ item }}
</Tag>
</p>
</Descriptions.Item>
</Descriptions>
<Empty v-else description="暂无健康信息" />
</Card>
</Col>
</Row>
</div>
@@ -442,6 +614,7 @@ function getSexText(sex: number): string {
</Spin>
</Page>
</Modal>
<PrescriptionDetailModal />
</template>
<style lang="scss" scoped>