fix: 完成医生设置中心 待完成:诊所设置中心
This commit is contained in:
36
apps/web-antd/src/views/business/store/settings/api/index.ts
Normal file
36
apps/web-antd/src/views/business/store/settings/api/index.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import { requestClient } from '#/api/request';
|
||||
|
||||
const prefix = 'store/';
|
||||
/**
|
||||
* 获取当前登录的诊所信息
|
||||
* @param data
|
||||
*/
|
||||
export async function getStoreInfoApi(data: any) {
|
||||
return requestClient.get<any>(`${prefix}store-info`, { params: data });
|
||||
}
|
||||
/**
|
||||
* 获取当前登录的诊所信息
|
||||
*/
|
||||
export async function getDoctorMyDoctorOrderApi() {
|
||||
return requestClient.get<any>(`${prefix}my-doctor-order`);
|
||||
}
|
||||
/**
|
||||
* 获取当前登录的诊所信息
|
||||
*/
|
||||
export async function getDoctorMyDiseaseListApi() {
|
||||
return requestClient.get<any>(`${prefix}my-disease-list`);
|
||||
}
|
||||
/**
|
||||
* 保存服务价格
|
||||
* @param data
|
||||
*/
|
||||
export async function saveServicePriceApi(data: Record<string, any>) {
|
||||
return requestClient.post<any>(`${prefix}save-service-price`, data);
|
||||
}
|
||||
/**
|
||||
* 创建医嘱
|
||||
* @param content
|
||||
*/
|
||||
export async function createDoctorOrderApi(content: string) {
|
||||
return requestClient.post<any>(`${prefix}create-doctor-order`, { content });
|
||||
}
|
||||
318
apps/web-antd/src/views/business/store/settings/index.vue
Normal file
318
apps/web-antd/src/views/business/store/settings/index.vue
Normal file
@@ -0,0 +1,318 @@
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
|
||||
import { EllipsisText, Page } from '@vben/common-ui';
|
||||
import { useUserStore } from '@vben/stores';
|
||||
|
||||
import {
|
||||
Button,
|
||||
Card, Image,
|
||||
Input,
|
||||
InputGroup,
|
||||
InputNumber,
|
||||
notification,
|
||||
RadioButton,
|
||||
RadioGroup,
|
||||
Rate,
|
||||
Switch,
|
||||
Tag,
|
||||
} from 'ant-design-vue';
|
||||
|
||||
import {getStoreInfoApi} from "#/views/business/store/settings/api";
|
||||
import html2canvas from "html2canvas";
|
||||
|
||||
const userInfoStore = useUserStore();
|
||||
|
||||
// 映射数据(示例)
|
||||
const activeTabBar = ref(1);
|
||||
const tabBar = [
|
||||
{
|
||||
value: 1,
|
||||
label: '诊所资料',
|
||||
},
|
||||
{
|
||||
value: 2,
|
||||
label: '商品价格',
|
||||
},
|
||||
{
|
||||
value: 3,
|
||||
label: '诊所二维码',
|
||||
},
|
||||
];
|
||||
|
||||
// 格式化日期
|
||||
const formatDate = (dateString) => {
|
||||
return new Date(dateString).toLocaleDateString();
|
||||
};
|
||||
const data = ref();
|
||||
/**
|
||||
* 获取当前登录诊所信息
|
||||
*/
|
||||
const getMyInfo = () => {
|
||||
getStoreInfoApi({}).then((res) => {
|
||||
data.value = res;
|
||||
});
|
||||
};
|
||||
getMyInfo();
|
||||
/**
|
||||
* 医嘱列表
|
||||
*/
|
||||
const tabBarChange = () => {
|
||||
switch (activeTabBar.value) {
|
||||
case 1: {
|
||||
getMyInfo();
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const qrCodeUrl = ref('');
|
||||
const htmlToImage = ref('');
|
||||
|
||||
/**
|
||||
* 下载二维码
|
||||
* @param name
|
||||
* @param isQr
|
||||
*/
|
||||
const downloadQRCode = async (name: string, isQr = false) => {
|
||||
const element = isQr ? qrCodeUrl.value : htmlToImage.value;
|
||||
html2canvas(element, {
|
||||
useCORS: true,
|
||||
allowTaint: true,
|
||||
logging: false,
|
||||
}).then((canvas) => {
|
||||
// 创建a标签下载
|
||||
const link = document.createElement('a'); // 创建a标签
|
||||
link.href = canvas.toDataURL(); // 是canvas对象的一种方法,用于将canvas对象转换为base64位编码
|
||||
link.setAttribute('download', `${data.value.name}${name}.png`); // 利用了a标签的download 来下载 canvas图片
|
||||
link.style.display = 'none'; // 将图片隐藏起来
|
||||
document.body.append(link); // 插入到其中
|
||||
link.click();
|
||||
});
|
||||
};
|
||||
|
||||
const saveSalePercent = () => {
|
||||
saveServicePriceApi({
|
||||
z_sale_percent: data.z_sale_percent,
|
||||
}).then((res) => {
|
||||
if (res.code === 200) {
|
||||
notification.success({
|
||||
message: '保存成功',
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Page
|
||||
v-if="data"
|
||||
:title="`${data.name}的配置中心`"
|
||||
auto-content-height
|
||||
>
|
||||
<div class="pb-2">
|
||||
<RadioGroup
|
||||
v-model:value="activeTabBar"
|
||||
button-style="solid"
|
||||
@change="tabBarChange"
|
||||
>
|
||||
<RadioButton
|
||||
v-for="item in tabBar"
|
||||
:key="item.value"
|
||||
:value="item.value"
|
||||
>
|
||||
{{ item.label }}
|
||||
</RadioButton>
|
||||
</RadioGroup>
|
||||
</div>
|
||||
<Card v-if="activeTabBar === 1" title="诊所资料">
|
||||
<!-- 头部信息 -->
|
||||
<div class="mb-8 flex flex-col gap-6 md:flex-row md:gap-8">
|
||||
<div class="flex-1">
|
||||
<div class="mb-3 flex items-center gap-4">
|
||||
<h1 class="text-2xl font-bold md:text-3xl">
|
||||
{{ data.name }}
|
||||
<span
|
||||
v-if="data.star"
|
||||
class="ml-2 rounded-full bg-amber-100 px-3 py-1 text-sm text-amber-700"
|
||||
>
|
||||
{{ data.title.name }}
|
||||
</span>
|
||||
</h1>
|
||||
<p class="flex items-center gap-2">
|
||||
{{ data.contact }}
|
||||
</p>
|
||||
<p class="flex items-center gap-2">
|
||||
{{ data.mobile }}
|
||||
</p>
|
||||
<p class="flex items-center gap-2">
|
||||
入驻时间:{{ formatDate(data.created_at) }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 主要内容 -->
|
||||
<div class="grid gap-8 md:grid-cols-2">
|
||||
<!-- 左侧内容 -->
|
||||
<div class="space-y-6">
|
||||
<h3 class="border-l-4 border-blue-500 pl-3 text-lg font-semibold">
|
||||
营业时间
|
||||
</h3>
|
||||
<EllipsisText :line="3" :tooltip="false" expand>
|
||||
<p>
|
||||
早:
|
||||
<Tag color="#455cda">{{ data.start_time }}</Tag>
|
||||
</p>
|
||||
<p class="mt-3">
|
||||
晚:
|
||||
<Tag color="#455cda">{{ data.end_time }}</Tag>
|
||||
</p>
|
||||
</EllipsisText>
|
||||
<h3 class="border-l-4 border-blue-500 pl-3 text-lg font-semibold">
|
||||
详细地址
|
||||
</h3>
|
||||
<EllipsisText :line="3" :tooltip="false" expand>
|
||||
<div
|
||||
style="text-indent: 2em"
|
||||
>
|
||||
{{ data.province.name
|
||||
}}{{ data.city.name }}{{ data.position }}
|
||||
</div>
|
||||
</EllipsisText>
|
||||
</div>
|
||||
|
||||
<!-- 右侧数据 -->
|
||||
<div class="space-y-6">
|
||||
<h3 class="border-l-4 border-blue-500 pl-3 text-lg font-semibold">
|
||||
执业数据
|
||||
</h3>
|
||||
|
||||
<div class="flex flex-wrap space-y-4">
|
||||
<div
|
||||
class="flex w-1/2 items-center justify-between rounded-lg bg-gray-50 p-4 dark:bg-[#020817]"
|
||||
>
|
||||
<span class="">问诊量</span>
|
||||
<span
|
||||
class="font-semibold text-blue-600"
|
||||
style="font-weight: bold"
|
||||
>{{ data.inquiry_count || 0 }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="space-y-2 rounded-lg bg-gray-50 p-4 dark:bg-[#020817]">
|
||||
<div class="flex justify-between text-sm">
|
||||
<span>接诊率{{ parseFloat(data.inquiry_rate) }}</span>
|
||||
<span class="font-medium">{{ parseFloat(data.inquiry_rate) }}%</span>
|
||||
</div>
|
||||
<div class="h-2 overflow-hidden rounded-full bg-gray-200">
|
||||
<div
|
||||
:style="{ width: `${parseFloat(data.inquiry_rate)}%` }"
|
||||
class="h-full bg-green-500 transition-all duration-500"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
<Card v-else-if="activeTabBar === 2" title="设置商品价格">
|
||||
中药销售比例
|
||||
<InputNumber
|
||||
v-model:value="data.z_sale_percent"
|
||||
style="min-width: 100px"
|
||||
>
|
||||
<template #addonAfter> 元 </template>
|
||||
</InputNumber>
|
||||
<Button type="primary" @click="saveSalePercent">保存</Button>
|
||||
</Card>
|
||||
<Card v-else-if="activeTabBar === 3" title="诊所二维码" >
|
||||
<template #extra>
|
||||
|
||||
<Button
|
||||
style="margin: 20px auto"
|
||||
type="link"
|
||||
@click="downloadQRCode('二维码卡片下载')"
|
||||
>
|
||||
二维码卡片下载
|
||||
</Button>
|
||||
<Button
|
||||
style="margin: 20px auto 20px 20px"
|
||||
type="link"
|
||||
@click="downloadQRCode('二维码下载', true)"
|
||||
>
|
||||
二维码下载
|
||||
</Button>
|
||||
</template>
|
||||
<div class="qrBox" style="text-align: center">
|
||||
<div ref="htmlToImage" class="qrModal">
|
||||
<div id="qrcode" ref="qrCodeUrl" class="qrcode">
|
||||
<div class="qrTitle">{{ data.name }}</div>
|
||||
<Image :preview="false" :src="data.qr_code" height="30" width="30" />
|
||||
<div class="qrAddress">
|
||||
<span class="addressTitle">诊所地址:</span>{{ data.province.name
|
||||
}}{{ data.city.name }}{{ data.position }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
</Page>
|
||||
</template>
|
||||
<style lang="scss" scoped>
|
||||
/* 自定义小标签样式 */
|
||||
//.pill-info {
|
||||
// @apply rounded-full bg-gray-100 px-3 py-1 text-sm ;
|
||||
//}
|
||||
|
||||
/* 优化行高 */
|
||||
.prose {
|
||||
@apply leading-relaxed;
|
||||
}
|
||||
|
||||
/* 悬停动画 */
|
||||
.hover-animate {
|
||||
@apply transition-transform duration-300 hover:scale-[1.02];
|
||||
}
|
||||
.qrModal {
|
||||
// 宽度适应文本长度
|
||||
margin: 0 auto;
|
||||
text-align: center;
|
||||
background: radial-gradient(
|
||||
circle at center,
|
||||
rgba(173, 216, 230, 0.8),
|
||||
rgba(135, 206, 235, 0.8),
|
||||
rgba(100, 149, 237, 0.8)
|
||||
);
|
||||
padding: 20px 30px;
|
||||
|
||||
.qrTitle {
|
||||
font-size: 20px;
|
||||
margin-bottom: 30px;
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.qrAddress {
|
||||
font-size: 12px;
|
||||
margin-top: 30px;
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.addressTitle {
|
||||
color: #3a8ee6;
|
||||
}
|
||||
|
||||
.qrcode {
|
||||
width: fit-content;
|
||||
//width: 50%;
|
||||
margin: 0 auto;
|
||||
text-align: center;
|
||||
padding: 20px 30px;
|
||||
background-color: #fff;
|
||||
border-radius: 20px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -15,12 +15,36 @@ import {
|
||||
import {
|
||||
getDiseaseList,
|
||||
} from '#/views/doctor/doctor-reception/api';
|
||||
import { debounce } from 'lodash-es'; // 或者使用自定义防抖函数
|
||||
import { debounce } from 'lodash-es';
|
||||
import {getDoctorMyDiseaseListApi} from "#/views/doctor/settings/api"; // 或者使用自定义防抖函数
|
||||
|
||||
const searchKey = ref('');
|
||||
const diagnosisList = ref([]);
|
||||
const selectDiagnosisList = ref('');
|
||||
const setUpdateDiagnosis = ref();
|
||||
/**
|
||||
* 常用诊断列表
|
||||
*/
|
||||
const doctorMyDiseaseList = ref([]);
|
||||
const getDoctorMyDiseaseList = () => {
|
||||
getDoctorMyDiseaseListApi().then((res) => {
|
||||
doctorMyDiseaseList.value = res.map((item) => {
|
||||
item.disease.isSelect = 0;
|
||||
if (selectDiagnosisList.value) {
|
||||
// 把values的字符串转为数组根据,分解
|
||||
const valuesArr = selectDiagnosisList.value.split(',');
|
||||
// 判断valuesArr数组中是否有item.disease.name
|
||||
valuesArr.forEach((value) => {
|
||||
if (value === item.disease.name) {
|
||||
item.disease.isSelect = 1;
|
||||
}
|
||||
});
|
||||
}
|
||||
return item;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
const [Modal, modalApi] = useVbenModal({
|
||||
fullscreenButton: false,
|
||||
draggable: true,
|
||||
@@ -41,6 +65,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||
selectDiagnosisList.value = values;
|
||||
}
|
||||
getDiagnosisList();
|
||||
getDoctorMyDiseaseList();
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -111,8 +136,14 @@ 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="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="item.isSelect === 1 ? 'primary': ''" @click="selectDiagnosis(item)">{{ item.name }}</Button>
|
||||
<Button style="margin: 0 10px;" type="primary" :ghost="item.isSelect !== 1" @click="selectDiagnosis(item)">{{ item.name }}</Button>
|
||||
</Badge>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
@@ -107,7 +107,7 @@ const decrypt = (str: string) => str; // 简单base64解码示例
|
||||
<span>处方编号: {{ item.prescription_no }}</span>
|
||||
<div class="prescription-type">普通处方</div>
|
||||
</div>
|
||||
<h2 class="clinic-name">{{ item.content?.doctor.name }} 处方笺</h2>
|
||||
<h2 class="clinic-name">{{ item.content?.patient.name }} 处方笺</h2>
|
||||
<div class="prescription-date">开具日期: {{ item.created_at }}</div>
|
||||
</div>
|
||||
|
||||
@@ -208,9 +208,9 @@ const decrypt = (str: string) => str; // 简单base64解码示例
|
||||
<div class="signature">
|
||||
<label>开方医生:</label>
|
||||
<img
|
||||
v-if="item.doctor_info?.identity?.sign_image"
|
||||
v-if="item.doctor_info?.identity_info?.sign_image"
|
||||
:src="`data:image/jpeg;base64,${
|
||||
item.doctor_info.identity.sign_image
|
||||
item.doctor_info.identity_info.sign_image
|
||||
}`"
|
||||
alt="签名"
|
||||
style="width: 120px; height: 50px; display: inline-block"
|
||||
@@ -232,9 +232,9 @@ const decrypt = (str: string) => str; // 简单base64解码示例
|
||||
<div class="signature">
|
||||
<label>调配人:</label>
|
||||
<img
|
||||
v-if="item.doctor_info?.identity?.sign_image"
|
||||
v-if="item.doctor_info?.identity_info?.sign_image"
|
||||
:src="`data:image/jpeg;base64,${
|
||||
item.doctor_info.identity.sign_image
|
||||
item.doctor_info.identity_info.sign_image
|
||||
}`"
|
||||
alt="签名"
|
||||
style="width: 120px; height: 50px; display: inline-block"
|
||||
@@ -256,9 +256,9 @@ const decrypt = (str: string) => str; // 简单base64解码示例
|
||||
<div class="signature">
|
||||
<label>发药人:</label>
|
||||
<img
|
||||
v-if="item.doctor_info?.identity?.sign_image"
|
||||
v-if="item.doctor_info?.identity_info?.sign_image"
|
||||
:src="`data:image/jpeg;base64,${
|
||||
item.doctor_info.identity.sign_image
|
||||
item.doctor_info.identity_info.sign_image
|
||||
}`"
|
||||
alt="签名"
|
||||
style="width: 120px; height: 50px; display: inline-block"
|
||||
|
||||
@@ -1297,14 +1297,15 @@ watch(
|
||||
item.created_at
|
||||
}}</span>
|
||||
<Tag class="ml-5" :color="item.category === 1? '' : '#455cda'">
|
||||
{{ item.prescription_type === 1 ? '中药处方' : '西药处方' }} /
|
||||
{{ item.prescription_type === 1 ? '中药处方' : item.prescription_type === 5 ? '产品服务包' : '西药处方' }} /
|
||||
{{ item.category === 1 ? '自费' : '医保' }}
|
||||
</Tag>
|
||||
|
||||
<Tag v-if="item.status === 0" color="warning">待审核</Tag>
|
||||
<Tag v-else-if="item.status === 1" color="success">已通过</Tag>
|
||||
<Tag v-else-if="item.status === 2" color="error">未通过</Tag>
|
||||
<Tag v-else-if="item.status === 3" color="#455cda">无需审核(服务包)</Tag>
|
||||
<Tag v-else-if="item.status === 3" color="#455cda">无需审核</Tag>
|
||||
<Tag v-else-if="item.status === 4" color="#455cda">无需审核</Tag>
|
||||
<Tag color="#455cda">处方ID:{{ item.id }}</Tag>
|
||||
<!-- <Tag class="ml-5">-->
|
||||
<!-- {{ item.category === 1 ? '自费' : '医保' }}-->
|
||||
|
||||
36
apps/web-antd/src/views/doctor/settings/api/index.ts
Normal file
36
apps/web-antd/src/views/doctor/settings/api/index.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import { requestClient } from '#/api/request';
|
||||
|
||||
const prefix = 'doctor/';
|
||||
/**
|
||||
* 获取当前登录的医生信息
|
||||
* @param data
|
||||
*/
|
||||
export async function getDoctorMyInfoApi(data: any) {
|
||||
return requestClient.get<any>(`${prefix}my-info`, { params: data });
|
||||
}
|
||||
/**
|
||||
* 获取当前登录的医生信息
|
||||
*/
|
||||
export async function getDoctorMyDoctorOrderApi() {
|
||||
return requestClient.get<any>(`${prefix}my-doctor-order`);
|
||||
}
|
||||
/**
|
||||
* 获取当前登录的医生信息
|
||||
*/
|
||||
export async function getDoctorMyDiseaseListApi() {
|
||||
return requestClient.get<any>(`${prefix}my-disease-list`);
|
||||
}
|
||||
/**
|
||||
* 保存服务价格
|
||||
* @param data
|
||||
*/
|
||||
export async function saveServicePriceApi(data: Record<string, any>) {
|
||||
return requestClient.post<any>(`${prefix}save-service-price`, data);
|
||||
}
|
||||
/**
|
||||
* 创建医嘱
|
||||
* @param content
|
||||
*/
|
||||
export async function createDoctorOrderApi(content: string) {
|
||||
return requestClient.post<any>(`${prefix}create-doctor-order`, { content });
|
||||
}
|
||||
383
apps/web-antd/src/views/doctor/settings/index.vue
Normal file
383
apps/web-antd/src/views/doctor/settings/index.vue
Normal file
@@ -0,0 +1,383 @@
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
|
||||
import { EllipsisText, Page } from '@vben/common-ui';
|
||||
import { useUserStore } from '@vben/stores';
|
||||
|
||||
import {
|
||||
Button,
|
||||
Card,
|
||||
Input,
|
||||
InputGroup,
|
||||
InputNumber,
|
||||
notification,
|
||||
RadioButton,
|
||||
RadioGroup,
|
||||
Rate,
|
||||
Switch,
|
||||
Tag,
|
||||
} from 'ant-design-vue';
|
||||
|
||||
import {
|
||||
createDoctorOrderApi,
|
||||
getDoctorMyDiseaseListApi,
|
||||
getDoctorMyDoctorOrderApi,
|
||||
getDoctorMyInfoApi,
|
||||
saveServicePriceApi,
|
||||
} from '#/views/doctor/settings/api';
|
||||
|
||||
const userInfoStore = useUserStore();
|
||||
|
||||
// 映射数据(示例)
|
||||
const identityMap = { 1: '中医', 2: '西医' };
|
||||
const activeTabBar = ref(1);
|
||||
const tabBar = [
|
||||
{
|
||||
value: 1,
|
||||
label: '个人资料',
|
||||
},
|
||||
// {
|
||||
// value: 2,
|
||||
// label: '我的处方',
|
||||
// },
|
||||
// {
|
||||
// value: 3,
|
||||
// label: '常用方',
|
||||
// },
|
||||
{
|
||||
value: 4,
|
||||
label: '常用医嘱',
|
||||
},
|
||||
{
|
||||
value: 5,
|
||||
label: '常用诊断',
|
||||
},
|
||||
];
|
||||
|
||||
// 格式化日期
|
||||
const formatDate = (dateString) => {
|
||||
return new Date(dateString).toLocaleDateString();
|
||||
};
|
||||
const data = ref();
|
||||
/**
|
||||
* 获取当前登录医生信息
|
||||
*/
|
||||
const getMyInfo = () => {
|
||||
getDoctorMyInfoApi({}).then((res) => {
|
||||
data.value = res;
|
||||
});
|
||||
};
|
||||
getMyInfo();
|
||||
/**
|
||||
* 保存挂号服务
|
||||
*/
|
||||
const saveServicePrice = () => {
|
||||
saveServicePriceApi({
|
||||
status: data.value.service.register_status,
|
||||
price: data.value.service.register_price,
|
||||
}).then(() => {
|
||||
notification.success({
|
||||
message: '保存成功',
|
||||
duration: 2,
|
||||
});
|
||||
// getMyInfo();
|
||||
});
|
||||
};
|
||||
|
||||
const getDoctorMyDoctorOrder = () => {
|
||||
getDoctorMyDoctorOrderApi().then((res) => {
|
||||
doctorOrder.value = res;
|
||||
});
|
||||
};
|
||||
/**
|
||||
* 诊断列表
|
||||
*/
|
||||
const doctorMyDiseaseList = ref([]);
|
||||
const getDoctorMyDiseaseList = () => {
|
||||
getDoctorMyDiseaseListApi().then((res) => {
|
||||
doctorMyDiseaseList.value = res;
|
||||
});
|
||||
};
|
||||
/**
|
||||
* 医嘱列表
|
||||
*/
|
||||
const doctorOrder = ref([]);
|
||||
const tabBarChange = () => {
|
||||
switch (activeTabBar.value) {
|
||||
case 1: {
|
||||
getMyInfo();
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
getDoctorMyDoctorOrder();
|
||||
break;
|
||||
}
|
||||
case 5: {
|
||||
getDoctorMyDiseaseList();
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const doctorOrderContent = ref('');
|
||||
/**
|
||||
* 创建医嘱
|
||||
*/
|
||||
const createDoctorOrder = () => {
|
||||
createDoctorOrderApi(doctorOrderContent.value).then((res) => {
|
||||
doctorOrderContent.value = '';
|
||||
getDoctorMyDoctorOrder();
|
||||
notification.success({
|
||||
message: '添加成功',
|
||||
duration: 2,
|
||||
});
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Page
|
||||
:title="`${userInfoStore.userInfo?.nick_name}的个人中心`"
|
||||
auto-content-height
|
||||
>
|
||||
<div class="pb-2">
|
||||
<RadioGroup
|
||||
v-model:value="activeTabBar"
|
||||
button-style="solid"
|
||||
@change="tabBarChange"
|
||||
>
|
||||
<RadioButton
|
||||
v-for="item in tabBar"
|
||||
:key="item.value"
|
||||
:value="item.value"
|
||||
>
|
||||
{{ item.label }}
|
||||
</RadioButton>
|
||||
</RadioGroup>
|
||||
</div>
|
||||
<Card v-if="data && activeTabBar === 1" title="个人资料">
|
||||
<!-- 头部信息 -->
|
||||
<div class="mb-8 flex flex-col gap-6 md:flex-row md:gap-8">
|
||||
<img
|
||||
:src="data?.avatar"
|
||||
alt="医生头像"
|
||||
class="h-24 w-24 rounded-full border-4 border-white object-cover shadow-lg md:h-32 md:w-32"
|
||||
/>
|
||||
|
||||
<div class="flex-1">
|
||||
<div class="mb-3 flex items-center gap-4">
|
||||
<h1 class="text-2xl font-bold md:text-3xl">
|
||||
{{ data.name }}
|
||||
<span
|
||||
v-if="data.star"
|
||||
class="ml-2 rounded-full bg-amber-100 px-3 py-1 text-sm text-amber-700"
|
||||
>
|
||||
{{ data.title.name }}
|
||||
</span>
|
||||
</h1>
|
||||
<p class="flex items-center gap-2">
|
||||
<PhoneIcon class="h-5 w-5" />
|
||||
{{ data.mobile }}
|
||||
</p>
|
||||
<p class="flex items-center gap-2">
|
||||
<CalendarIcon class="h-5 w-5" />
|
||||
入驻时间:{{ formatDate(data.created_at) }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<Tag color="#455cda">{{ data.title.name }}</Tag>
|
||||
<Tag color="#455cda">{{ identityMap[data.identity] }}</Tag>
|
||||
<Tag color="#455cda">{{ data.depart.name }}</Tag>
|
||||
</div>
|
||||
|
||||
<!-- <div class="mt-4 space-y-1 flex">-->
|
||||
<!-- 签名:-->
|
||||
<!-- <img :src="`data:image/jpeg;base64,${data.identity_info.sign_image}`" style="width: 120px; height: 60px; background-color: white" alt="医生签名" />-->
|
||||
<!-- </div>-->
|
||||
|
||||
<div class="mt-4 space-y-1">
|
||||
诊所:
|
||||
<span v-for="item in data.stores">
|
||||
<Tag v-if="item.store?.name" class="mt-2" color="#455cda">{{
|
||||
item.store?.name
|
||||
}}</Tag>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<div class="mb-3 flex items-center gap-4">
|
||||
挂号服务
|
||||
<Switch
|
||||
v-model:checked="data.service.register_status"
|
||||
:checked-value="1"
|
||||
:un-checked-value="0"
|
||||
/>
|
||||
<InputNumber
|
||||
v-if="data.service.register_status === 1"
|
||||
v-model:value="data.service.register_price"
|
||||
style="min-width: 100px"
|
||||
>
|
||||
<template #addonAfter> 元 </template>
|
||||
</InputNumber>
|
||||
<Button type="primary" @click="saveServicePrice">保存</Button>
|
||||
【{{ data.service.register_status === 1 ? '开启' : '关闭' }}】
|
||||
</div>
|
||||
|
||||
<div class="flex flex-wrap gap-2"></div>
|
||||
|
||||
<div class="mt-4 space-y-1"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 主要内容 -->
|
||||
<div class="grid gap-8 md:grid-cols-2">
|
||||
<!-- 左侧内容 -->
|
||||
<div class="space-y-6">
|
||||
<h3 class="border-l-4 border-blue-500 pl-3 text-lg font-semibold">
|
||||
擅长领域
|
||||
</h3>
|
||||
<EllipsisText :line="3" :tooltip="false" expand>
|
||||
<div
|
||||
class="prose max-w-none whitespace-pre-wrap"
|
||||
style="text-indent: 2em"
|
||||
>
|
||||
{{ data.good_at }}
|
||||
</div>
|
||||
</EllipsisText>
|
||||
|
||||
<h3 class="border-l-4 border-blue-500 pl-3 text-lg font-semibold">
|
||||
医生简介
|
||||
</h3>
|
||||
<EllipsisText :line="3" :tooltip="false" expand>
|
||||
<div
|
||||
class="prose max-w-none whitespace-pre-wrap"
|
||||
style="text-indent: 2em"
|
||||
>
|
||||
{{ data.intro }}
|
||||
</div>
|
||||
</EllipsisText>
|
||||
</div>
|
||||
|
||||
<!-- 右侧数据 -->
|
||||
<div class="space-y-6">
|
||||
<h3 class="border-l-4 border-blue-500 pl-3 text-lg font-semibold">
|
||||
执业数据
|
||||
</h3>
|
||||
|
||||
<div class="flex flex-wrap space-y-4">
|
||||
<div
|
||||
class="flex w-1/2 items-center justify-between rounded-lg bg-gray-50 p-4 dark:bg-[#020817]"
|
||||
>
|
||||
<span class="">问诊量</span>
|
||||
<span
|
||||
class="font-semibold text-blue-600"
|
||||
style="font-weight: bold"
|
||||
>{{ data.inquiries }}</span>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="flex w-1/2 items-center justify-between rounded-lg bg-gray-50 p-4 dark:bg-[#020817]"
|
||||
>
|
||||
<span class="">综合评分</span>
|
||||
<Rate :value="data.grade" disabled style="color: #455cda" />
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="flex w-1/2 items-center justify-between rounded-lg bg-gray-50 p-4 dark:bg-[#020817]"
|
||||
>
|
||||
<span class="">平均回复</span>
|
||||
<span
|
||||
class="font-semibold text-blue-600"
|
||||
style="font-weight: bold"
|
||||
>
|
||||
{{ data.average_response }} 小时
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="space-y-4">
|
||||
<!-- <div class="space-y-2 rounded-lg bg-gray-50 p-4 dark:bg-[#020817]">-->
|
||||
<!-- <div class="flex justify-between text-sm">-->
|
||||
<!-- <span class="">好评率</span>-->
|
||||
<!-- <span class="font-medium">{{ parseFloat(data.applause_rate) }}%</span>-->
|
||||
<!-- </div>-->
|
||||
<!-- <div class="h-2 overflow-hidden rounded-full bg-gray-200">-->
|
||||
<!-- <div-->
|
||||
<!-- :style="{ width: `${parseFloat(data.applause_rate)}%` }"-->
|
||||
<!-- class="h-full bg-blue-500 transition-all duration-500"-->
|
||||
<!-- ></div>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
|
||||
<div class="space-y-2 rounded-lg bg-gray-50 p-4 dark:bg-[#020817]">
|
||||
<div class="flex justify-between text-sm">
|
||||
<span>接诊率{{ parseFloat(data.reception_rate) }}</span>
|
||||
<span class="font-medium">{{ parseFloat(data.reception_rate) }}%</span>
|
||||
</div>
|
||||
<div class="h-2 overflow-hidden rounded-full bg-gray-200">
|
||||
<div
|
||||
:style="{ width: `${parseFloat(data.reception_rate)}%` }"
|
||||
class="h-full bg-green-500 transition-all duration-500"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
<Card v-else-if="data && activeTabBar === 2" title="我的处方" />
|
||||
<Card v-else-if="data && activeTabBar === 3" title="常用方" />
|
||||
<Card v-else-if="doctorOrder && activeTabBar === 4" title="常用医嘱">
|
||||
<div class="w-full">
|
||||
<InputGroup>
|
||||
<Input
|
||||
v-model:value="doctorOrderContent"
|
||||
style="width: calc(100% - 200px)"
|
||||
@keydown.enter="createDoctorOrder"
|
||||
/>
|
||||
<Button type="primary" @click="createDoctorOrder">添加</Button>
|
||||
</InputGroup>
|
||||
</div>
|
||||
<div class="mt-10">
|
||||
<Button
|
||||
v-for="item in doctorOrder"
|
||||
style="margin: 0 10px"
|
||||
type="primary"
|
||||
>
|
||||
{{ item.content }}
|
||||
</Button>
|
||||
</div>
|
||||
</Card>
|
||||
<Card v-else-if="data && activeTabBar === 5" title="常用诊断">
|
||||
<Button
|
||||
v-for="item in doctorMyDiseaseList"
|
||||
style="margin: 0 10px"
|
||||
type="primary"
|
||||
>
|
||||
{{ item.disease.name }}
|
||||
</Button>
|
||||
</Card>
|
||||
</Page>
|
||||
</template>
|
||||
<style lang="scss" scoped>
|
||||
/* 自定义小标签样式 */
|
||||
//.pill-info {
|
||||
// @apply rounded-full bg-gray-100 px-3 py-1 text-sm ;
|
||||
//}
|
||||
|
||||
/* 优化行高 */
|
||||
.prose {
|
||||
@apply leading-relaxed;
|
||||
}
|
||||
|
||||
/* 悬停动画 */
|
||||
.hover-animate {
|
||||
@apply transition-transform duration-300 hover:scale-[1.02];
|
||||
}
|
||||
</style>
|
||||
@@ -5,18 +5,18 @@ import { ref } from 'vue';
|
||||
|
||||
import { Page, useVbenModal } from '@vben/common-ui';
|
||||
|
||||
import { useClipboard } from '@vueuse/core';
|
||||
import { Button, Image, message, Tag } from 'ant-design-vue';
|
||||
|
||||
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||
import { Icon } from '#/components/icon';
|
||||
import QrCodePreview from '#/components/modal/QrCodePreview.vue';
|
||||
import { TableAction } from '#/components/table-action';
|
||||
|
||||
import {deleteStore, openPcWindowsApiByStore, openQrCodeApi} from './api';
|
||||
import { useClipboard } from '@vueuse/core';
|
||||
import { deleteStore, openPcWindowsApiByStore, openQrCodeApi } from './api';
|
||||
import FormModalDemo from './components/modal.vue';
|
||||
import QrCodePreview from "#/components/modal/QrCodePreview.vue";
|
||||
import { formOptions } from './config/search';
|
||||
import { gridOptions } from './config/table';
|
||||
import {Icon} from "#/components/icon";
|
||||
|
||||
const hasTopTableDropDownActions = ref(false);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user