fix: 常用诊断、常用医嘱
This commit is contained in:
@@ -4,11 +4,15 @@ import {ref} from 'vue';
|
||||
import {Page, useVbenModal} from '@vben/common-ui';
|
||||
|
||||
import {
|
||||
Badge,
|
||||
PlusOutlined,
|
||||
DeleteOutlined,
|
||||
} from '@ant-design/icons-vue';
|
||||
import {
|
||||
Button,
|
||||
Col,
|
||||
InputSearch,
|
||||
message,
|
||||
Popconfirm,
|
||||
Row,
|
||||
} from 'ant-design-vue';
|
||||
|
||||
@@ -16,7 +20,11 @@ import {
|
||||
getDiseaseList,
|
||||
} from '#/views/doctor/doctor-reception/api';
|
||||
import { debounce } from 'lodash-es';
|
||||
import {getDoctorMyDiseaseListApi} from "#/views/doctor/settings/api"; // 或者使用自定义防抖函数
|
||||
import {
|
||||
getDoctorMyDiseaseListApi,
|
||||
addDoctorMyDiseaseApi,
|
||||
deleteDoctorMyDiseaseApi,
|
||||
} from "#/views/doctor/settings/api";
|
||||
|
||||
const searchKey = ref('');
|
||||
const diagnosisList = ref([]);
|
||||
@@ -78,6 +86,10 @@ function getDiagnosisList(searchKey = '') {
|
||||
getDiseaseList(searchKey).then((res) => {
|
||||
diagnosisList.value = res.map((item) => {
|
||||
item.isSelect = 0;
|
||||
// 检查是否已在常用诊断中
|
||||
item.isInMyList = doctorMyDiseaseList.value.some(
|
||||
(myItem) => myItem.disease.id === item.id
|
||||
);
|
||||
if (selectDiagnosisList.value) {
|
||||
// 把values的字符串转为数组根据,分解
|
||||
const valuesArr = selectDiagnosisList.value.split(',');
|
||||
@@ -96,6 +108,7 @@ function getDiagnosisList(searchKey = '') {
|
||||
const getDiagnosisListChage = debounce(async (searchText = '') => {
|
||||
getDiagnosisList(searchText);
|
||||
}, 300)
|
||||
|
||||
/**
|
||||
* 选择诊断
|
||||
* @param item
|
||||
@@ -119,10 +132,48 @@ function selectDiagnosis(item) {
|
||||
// 将数组转回字符串更新到响应式变量
|
||||
selectDiagnosisList.value = arr.join(',');
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加到常用诊断
|
||||
* @param item 诊断项
|
||||
*/
|
||||
async function addToMyDiagnosis(item) {
|
||||
try {
|
||||
await addDoctorMyDiseaseApi(item.id);
|
||||
message.success(`已将「${item.name}」添加到常用诊断`);
|
||||
// 刷新常用诊断列表
|
||||
await getDoctorMyDiseaseList();
|
||||
// 更新搜索结果中的状态
|
||||
item.isInMyList = true;
|
||||
} catch (error) {
|
||||
message.error('添加失败,请重试');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从常用诊断中删除
|
||||
* @param item 常用诊断项(包含id和disease)
|
||||
*/
|
||||
async function removeFromMyDiagnosis(item) {
|
||||
try {
|
||||
await deleteDoctorMyDiseaseApi(item.id);
|
||||
message.success(`已将「${item.disease.name}」从常用诊断中移除`);
|
||||
// 刷新常用诊断列表
|
||||
await getDoctorMyDiseaseList();
|
||||
// 更新搜索结果中的状态
|
||||
const searchItem = diagnosisList.value.find(
|
||||
(d) => d.id === item.disease.id
|
||||
);
|
||||
if (searchItem) {
|
||||
searchItem.isInMyList = false;
|
||||
}
|
||||
} catch (error) {
|
||||
message.error('删除失败,请重试');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- <Modal class="w-[60%]" title="西(中成)药列表">-->
|
||||
<Modal class="w-[60%]" title="常用诊断">
|
||||
<Page>
|
||||
<Row :gutter="12">
|
||||
@@ -136,19 +187,152 @@ function selectDiagnosis(item) {
|
||||
/>
|
||||
</Col>
|
||||
<Col :span="24">
|
||||
<h1 class="mt-3" v-if="doctorMyDiseaseList.length > 0">常用</h1>
|
||||
<Badge v-for="item in doctorMyDiseaseList" :count="0" class="mt-5">
|
||||
<Button style="margin: 0 10px;" type="primary" :ghost="item.disease.isSelect !== 1" @click="selectDiagnosis(item.disease)">{{ item.disease.name }}</Button>
|
||||
</Badge>
|
||||
<!-- 常用诊断列表 -->
|
||||
<h1 class="diagnosis-section-title" v-if="doctorMyDiseaseList.length > 0">常用</h1>
|
||||
<div class="diagnosis-list">
|
||||
<div
|
||||
v-for="item in doctorMyDiseaseList"
|
||||
:key="item.id"
|
||||
class="diagnosis-item"
|
||||
:class="{ 'is-selected': item.disease.isSelect === 1 }"
|
||||
>
|
||||
<Button
|
||||
type="primary"
|
||||
:ghost="item.disease.isSelect !== 1"
|
||||
@click="selectDiagnosis(item.disease)"
|
||||
>
|
||||
{{ item.disease.name }}
|
||||
</Button>
|
||||
<div class="diagnosis-actions" @click.stop>
|
||||
<Popconfirm
|
||||
title="确定从常用诊断中移除吗?"
|
||||
@confirm="removeFromMyDiagnosis(item)"
|
||||
>
|
||||
<Button
|
||||
type="text"
|
||||
size="small"
|
||||
danger
|
||||
class="action-btn"
|
||||
>
|
||||
<template #icon><DeleteOutlined /></template>
|
||||
</Button>
|
||||
</Popconfirm>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h1 class="mt-3" v-if="diagnosisList.length > 0">搜索结果</h1>
|
||||
<Badge v-for="item in diagnosisList" :count="0" class="mt-5">
|
||||
<Button style="margin: 0 10px;" type="primary" :ghost="item.isSelect !== 1" @click="selectDiagnosis(item)">{{ item.name }}</Button>
|
||||
</Badge>
|
||||
<!-- 搜索结果列表 -->
|
||||
<h1 class="diagnosis-section-title" v-if="diagnosisList.length > 0">搜索结果</h1>
|
||||
<div class="diagnosis-list">
|
||||
<div
|
||||
v-for="item in diagnosisList"
|
||||
:key="item.id"
|
||||
class="diagnosis-item"
|
||||
:class="{ 'is-selected': item.isSelect === 1 }"
|
||||
>
|
||||
<Button
|
||||
type="primary"
|
||||
:ghost="item.isSelect !== 1"
|
||||
@click="selectDiagnosis(item)"
|
||||
>
|
||||
{{ item.name }}
|
||||
</Button>
|
||||
<div class="diagnosis-actions" @click.stop>
|
||||
<Button
|
||||
v-if="!item.isInMyList"
|
||||
type="text"
|
||||
size="small"
|
||||
class="action-btn add-btn"
|
||||
@click="addToMyDiagnosis(item)"
|
||||
>
|
||||
<template #icon><PlusOutlined /></template>
|
||||
<span class="action-text">加入常用</span>
|
||||
</Button>
|
||||
<span v-else class="already-added">已添加</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
</Page>
|
||||
</Modal>
|
||||
</template>
|
||||
<style lang="scss">
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.diagnosis-section-title {
|
||||
margin-top: 12px;
|
||||
margin-bottom: 8px;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.dark .diagnosis-section-title {
|
||||
color: #e5e7eb;
|
||||
}
|
||||
|
||||
.diagnosis-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.diagnosis-item {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
margin: 4px 0;
|
||||
|
||||
&:hover .diagnosis-actions {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
|
||||
.diagnosis-actions {
|
||||
position: absolute;
|
||||
right: -8px;
|
||||
top: -8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 2px;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transition: all 0.2s ease;
|
||||
background: #fff;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.dark .diagnosis-actions {
|
||||
background: #374151;
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 12px;
|
||||
padding: 2px 6px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.add-btn {
|
||||
color: #1890ff;
|
||||
|
||||
&:hover {
|
||||
color: #40a9ff;
|
||||
background: rgba(24, 144, 255, 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
.action-text {
|
||||
margin-left: 2px;
|
||||
}
|
||||
|
||||
.already-added {
|
||||
font-size: 11px;
|
||||
color: #999;
|
||||
padding: 2px 6px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -4,23 +4,36 @@ import {ref} from 'vue';
|
||||
import {Page, useVbenModal} from '@vben/common-ui';
|
||||
|
||||
import {
|
||||
Badge,
|
||||
PlusOutlined,
|
||||
DeleteOutlined,
|
||||
} from '@ant-design/icons-vue';
|
||||
import {
|
||||
Button,
|
||||
Col,
|
||||
InputSearch,
|
||||
Input,
|
||||
message,
|
||||
Popconfirm,
|
||||
Row,
|
||||
} from 'ant-design-vue';
|
||||
|
||||
import {
|
||||
getDiseaseList, getDoctorOrderList,
|
||||
getDoctorOrderList,
|
||||
} from '#/views/doctor/doctor-reception/api';
|
||||
import {
|
||||
createDoctorOrderApi,
|
||||
deleteDoctorOrderApi,
|
||||
} from '#/views/doctor/settings/api';
|
||||
|
||||
const searchKey = ref('');
|
||||
const doctorOrderCommonList = ref([]);
|
||||
const doctorOrderMyList = ref([]);
|
||||
const selectDiagnosisList = ref('');
|
||||
const setUpdateDoctorOrder = ref();
|
||||
|
||||
// 新增医嘱相关
|
||||
const newOrderContent = ref('');
|
||||
const showAddInput = ref(false);
|
||||
|
||||
const [Modal, modalApi] = useVbenModal({
|
||||
fullscreenButton: false,
|
||||
draggable: true,
|
||||
@@ -40,16 +53,15 @@ const [Modal, modalApi] = useVbenModal({
|
||||
if (values) {
|
||||
selectDiagnosisList.value = values;
|
||||
}
|
||||
getDiagnosisList();
|
||||
getDoctorOrderListData();
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* 获取诊断列表
|
||||
* @param searchKey
|
||||
* 获取医嘱列表
|
||||
*/
|
||||
function getDiagnosisList() {
|
||||
function getDoctorOrderListData() {
|
||||
getDoctorOrderList().then((res) => {
|
||||
doctorOrderCommonList.value = res.common.map((item) => {
|
||||
item.isSelect = 0;
|
||||
@@ -83,10 +95,11 @@ function getDiagnosisList() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 选择诊断
|
||||
* 选择医嘱
|
||||
* @param item
|
||||
* @param type 1=我的医嘱(content字段), 2=公共医嘱(name字段)
|
||||
*/
|
||||
function selectDiagnosis(item, type = 1) {
|
||||
function selectDoctorOrder(item, type = 1) {
|
||||
// 将当前值转换为数组(过滤空值)
|
||||
let arr = selectDiagnosisList.value ? selectDiagnosisList.value.split(',').filter(Boolean) : [];
|
||||
|
||||
@@ -119,34 +132,258 @@ function selectDiagnosis(item, type = 1) {
|
||||
// 将数组转回字符串更新到响应式变量
|
||||
selectDiagnosisList.value = arr.join(',');
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加自定义医嘱
|
||||
*/
|
||||
async function addMyDoctorOrder() {
|
||||
if (!newOrderContent.value.trim()) {
|
||||
message.warning('请输入医嘱内容');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await createDoctorOrderApi(newOrderContent.value.trim());
|
||||
message.success('添加成功');
|
||||
newOrderContent.value = '';
|
||||
showAddInput.value = false;
|
||||
// 刷新列表
|
||||
await getDoctorOrderListData();
|
||||
} catch (error) {
|
||||
message.error('添加失败,请重试');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除我的医嘱
|
||||
* @param item 医嘱项
|
||||
*/
|
||||
async function deleteMyDoctorOrder(item) {
|
||||
try {
|
||||
await deleteDoctorOrderApi(item.id);
|
||||
message.success('删除成功');
|
||||
// 刷新列表
|
||||
await getDoctorOrderListData();
|
||||
} catch (error) {
|
||||
message.error('删除失败,请重试');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消添加
|
||||
*/
|
||||
function cancelAdd() {
|
||||
newOrderContent.value = '';
|
||||
showAddInput.value = false;
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- <Modal class="w-[60%]" title="西(中成)药列表">-->
|
||||
<Modal class="w-[60%]" title="常用医嘱">
|
||||
<Page>
|
||||
<Row :gutter="12">
|
||||
<!-- 我的医嘱 -->
|
||||
<Col :span="24">
|
||||
<InputSearch
|
||||
:model="searchKey"
|
||||
enter-button
|
||||
placeholder="请输想要搜索的内容..."
|
||||
@search="getDiagnosisList"
|
||||
/>
|
||||
<h1 class="order-section-title">我的医嘱</h1>
|
||||
<div class="order-list">
|
||||
<div
|
||||
v-for="item in doctorOrderMyList"
|
||||
:key="item.id"
|
||||
class="order-item"
|
||||
:class="{ 'is-selected': item.isSelect === 1 }"
|
||||
>
|
||||
<Button
|
||||
type="primary"
|
||||
:ghost="item.isSelect !== 1"
|
||||
@click="selectDoctorOrder(item, 1)"
|
||||
>
|
||||
{{ item.content }}
|
||||
</Button>
|
||||
<div class="order-actions" @click.stop>
|
||||
<Popconfirm
|
||||
title="确定删除这条医嘱吗?"
|
||||
@confirm="deleteMyDoctorOrder(item)"
|
||||
>
|
||||
<Button
|
||||
type="text"
|
||||
size="small"
|
||||
danger
|
||||
class="action-btn"
|
||||
>
|
||||
<template #icon><DeleteOutlined /></template>
|
||||
</Button>
|
||||
</Popconfirm>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 添加医嘱按钮/输入框 -->
|
||||
<div
|
||||
v-if="!showAddInput"
|
||||
class="add-order-btn"
|
||||
@click="showAddInput = true"
|
||||
>
|
||||
<PlusOutlined />
|
||||
<span>添加医嘱</span>
|
||||
</div>
|
||||
|
||||
<div v-else class="add-order-input">
|
||||
<Input
|
||||
v-model:value="newOrderContent"
|
||||
placeholder="输入医嘱内容"
|
||||
@pressEnter="addMyDoctorOrder"
|
||||
/>
|
||||
<div class="add-actions">
|
||||
<Button size="small" @click="cancelAdd">取消</Button>
|
||||
<Button type="primary" size="small" @click="addMyDoctorOrder">
|
||||
添加
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Col>
|
||||
|
||||
<!-- 公共医嘱 -->
|
||||
<Col :span="24">
|
||||
<Badge v-for="item in doctorOrderMyList" :count="0" class="mt-5">
|
||||
<Button style="margin: 0 10px;" type="primary" :ghost="item.isSelect !== 1" @click="selectDiagnosis(item)">{{ item.content }}</Button>
|
||||
</Badge>
|
||||
</Col>
|
||||
<Col :span="24">
|
||||
<Badge v-for="item in doctorOrderCommonList" :count="0" class="mt-5">
|
||||
<Button style="margin: 0 10px;" type="primary" :ghost="item.isSelect !== 1" @click="selectDiagnosis(item, 2)">{{ item.name }}</Button>
|
||||
</Badge>
|
||||
<h1 class="order-section-title" v-if="doctorOrderCommonList.length > 0">公共医嘱</h1>
|
||||
<div class="order-list">
|
||||
<div
|
||||
v-for="item in doctorOrderCommonList"
|
||||
:key="item.id"
|
||||
class="order-item"
|
||||
:class="{ 'is-selected': item.isSelect === 1 }"
|
||||
>
|
||||
<Button
|
||||
type="primary"
|
||||
:ghost="item.isSelect !== 1"
|
||||
@click="selectDoctorOrder(item, 2)"
|
||||
>
|
||||
{{ item.name }}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
</Page>
|
||||
</Modal>
|
||||
</template>
|
||||
<style lang="scss">
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.order-section-title {
|
||||
margin-top: 12px;
|
||||
margin-bottom: 8px;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.dark .order-section-title {
|
||||
color: #e5e7eb;
|
||||
}
|
||||
|
||||
.order-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.order-item {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
margin: 4px 0;
|
||||
|
||||
&:hover .order-actions {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
|
||||
.order-actions {
|
||||
position: absolute;
|
||||
right: -8px;
|
||||
top: -8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 2px;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transition: all 0.2s ease;
|
||||
background: #fff;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.dark .order-actions {
|
||||
background: #374151;
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 12px;
|
||||
padding: 2px 6px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.add-order-btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
padding: 6px 12px;
|
||||
border: 1px dashed #d9d9d9;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
font-size: 13px;
|
||||
color: #666;
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover {
|
||||
border-color: #1890ff;
|
||||
color: #1890ff;
|
||||
}
|
||||
}
|
||||
|
||||
.dark .add-order-btn {
|
||||
border-color: #4b5563;
|
||||
color: #9ca3af;
|
||||
|
||||
&:hover {
|
||||
border-color: #3b82f6;
|
||||
color: #3b82f6;
|
||||
}
|
||||
}
|
||||
|
||||
.add-order-input {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 4px;
|
||||
border: 1px solid #1890ff;
|
||||
border-radius: 6px;
|
||||
background: #fff;
|
||||
|
||||
:deep(.ant-input) {
|
||||
flex: 1;
|
||||
border: none;
|
||||
outline: none;
|
||||
box-shadow: none;
|
||||
font-size: 13px;
|
||||
|
||||
&:focus {
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dark .add-order-input {
|
||||
background: #374151;
|
||||
border-color: #3b82f6;
|
||||
}
|
||||
|
||||
.add-actions {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -34,3 +34,27 @@ export async function saveServicePriceApi(data: Record<string, any>) {
|
||||
export async function createDoctorOrderApi(content: string) {
|
||||
return requestClient.post<any>(`${prefix}create-doctor-order`, { content });
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除医嘱
|
||||
* @param id 医嘱ID
|
||||
*/
|
||||
export async function deleteDoctorOrderApi(id: number) {
|
||||
return requestClient.post<any>(`${prefix}delete-doctor-order`, { id });
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加常用诊断
|
||||
* @param disease_id 疾病ID
|
||||
*/
|
||||
export async function addDoctorMyDiseaseApi(disease_id: number) {
|
||||
return requestClient.post<any>(`${prefix}add-my-disease`, { disease_id });
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除常用诊断
|
||||
* @param id 常用诊断记录ID
|
||||
*/
|
||||
export async function deleteDoctorMyDiseaseApi(id: number) {
|
||||
return requestClient.post<any>(`${prefix}delete-my-disease`, { id });
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ export const gridOptions: VxeGridProps<RowType> = {
|
||||
columns: [
|
||||
{ field: 'id', align: 'left', title: 'ID', width: 100 },
|
||||
{ field: 'desc', align: 'left', title: '协议名称' },
|
||||
{ field: 'content', title: '协议介绍', slots: { default: 'content' } },
|
||||
// { field: 'content', title: '协议介绍', slots: { default: 'content' } },
|
||||
{ field: 'end_txt', title: '协议端口' },
|
||||
{ field: 'created_at', title: '创建时间' },
|
||||
{ type: 'html', title: '操作', slots: { default: 'action' } },
|
||||
|
||||
Reference in New Issue
Block a user