Merge branch 'master' into gancao
This commit is contained in:
@@ -91,6 +91,70 @@ export function getRecordsByPatient(params: any) {
|
||||
return request.get({ url: '/tcm.bloodRecord/getRecordsByPatient', params })
|
||||
}
|
||||
|
||||
// 获取血糖趋势图数据
|
||||
export function getBloodSugarTrend(params: any) {
|
||||
return request.get({ url: '/tcm.bloodRecord/getBloodSugarTrend', params })
|
||||
}
|
||||
|
||||
// ========== 饮食记录 ==========
|
||||
|
||||
// 添加饮食记录
|
||||
export function dietRecordAdd(params: any) {
|
||||
return request.post({ url: '/tcm.dietRecord/add', params })
|
||||
}
|
||||
|
||||
// 编辑饮食记录
|
||||
export function dietRecordEdit(params: any) {
|
||||
return request.post({ url: '/tcm.dietRecord/edit', params })
|
||||
}
|
||||
|
||||
// 删除饮食记录
|
||||
export function dietRecordDelete(params: any) {
|
||||
return request.post({ url: '/tcm.dietRecord/delete', params })
|
||||
}
|
||||
|
||||
// 饮食记录详情
|
||||
export function dietRecordDetail(params: any) {
|
||||
return request.get({ url: '/tcm.dietRecord/detail', params })
|
||||
}
|
||||
|
||||
// 获取患者的饮食记录列表
|
||||
export function getDietRecordsByPatient(params: any) {
|
||||
return request.get({ url: '/tcm.dietRecord/getRecordsByPatient', params })
|
||||
}
|
||||
|
||||
// ========== 运动记录 ==========
|
||||
|
||||
// 添加运动记录
|
||||
export function exerciseRecordAdd(params: any) {
|
||||
return request.post({ url: '/tcm.exerciseRecord/add', params })
|
||||
}
|
||||
|
||||
// 编辑运动记录
|
||||
export function exerciseRecordEdit(params: any) {
|
||||
return request.post({ url: '/tcm.exerciseRecord/edit', params })
|
||||
}
|
||||
|
||||
// 删除运动记录
|
||||
export function exerciseRecordDelete(params: any) {
|
||||
return request.post({ url: '/tcm.exerciseRecord/delete', params })
|
||||
}
|
||||
|
||||
// 运动记录详情
|
||||
export function exerciseRecordDetail(params: any) {
|
||||
return request.get({ url: '/tcm.exerciseRecord/detail', params })
|
||||
}
|
||||
|
||||
// 获取患者的运动记录列表
|
||||
export function getExerciseRecordsByPatient(params: any) {
|
||||
return request.get({ url: '/tcm.exerciseRecord/getRecordsByPatient', params })
|
||||
}
|
||||
|
||||
// 获取运动趋势图数据
|
||||
export function getExerciseTrend(params: any) {
|
||||
return request.get({ url: '/tcm.exerciseRecord/getExerciseTrend', params })
|
||||
}
|
||||
|
||||
// ========== 音视频通话 ==========
|
||||
|
||||
// 获取通话签名(忽略取消令牌,避免 open + 会话切换 watch 重复请求互斥取消)
|
||||
|
||||
@@ -951,7 +951,7 @@
|
||||
</div>
|
||||
|
||||
<!-- 物流信息 -->
|
||||
<div class="form-section">
|
||||
<!-- <div class="form-section">
|
||||
<div class="section-title">
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20 7l-8-4-8 4m16 0l-8 4m8-4v10l-8 4m0-10L4 7m8 4v10M4 7v10l8 4" />
|
||||
@@ -977,7 +977,7 @@
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<!-- 关联收款 -->
|
||||
<div class="form-section">
|
||||
@@ -1072,7 +1072,7 @@
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="订单金额" prop="amount">
|
||||
<el-form-item label="订单总金额" prop="amount">
|
||||
<el-input-number
|
||||
v-model="createOrderForm.amount"
|
||||
:min="createOrderAmountInputMin"
|
||||
@@ -1309,8 +1309,12 @@ const transformRegionData = (data: any[]) => {
|
||||
const loadRegionData = async () => {
|
||||
try {
|
||||
console.log('开始加载省市区数据...')
|
||||
// 使用代理路径,需要在vite.config.ts中配置代理
|
||||
const response = await fetch('/api-proxy/area/ChinaCitys.json')
|
||||
// 开发环境使用代理,生产环境使用环境变量中的基础URL
|
||||
const apiUrl = import.meta.env.DEV
|
||||
? '/api-proxy/area/ChinaCitys.json'
|
||||
: `https://cos.zhenyangtang.com.cn/area/ChinaCitys.json`
|
||||
|
||||
const response = await fetch(apiUrl)
|
||||
console.log('响应状态:', response.status)
|
||||
|
||||
if (!response.ok) {
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<<<<<<< HEAD
|
||||
<el-card class="!border-none shadow-sm mb-4" shadow="never">
|
||||
<div class="flex flex-col gap-3">
|
||||
<div class="flex items-center gap-2 flex-wrap">
|
||||
@@ -40,6 +41,32 @@
|
||||
@click="handlePayAuditTabClick(tab.value)"
|
||||
>
|
||||
<span class="font-medium">{{ tab.label }}</span>
|
||||
=======
|
||||
<!-- 状态标签页 -->
|
||||
<el-card class="!border-none shadow-sm mb-4" shadow="never">
|
||||
<div class="flex items-center gap-2 flex-wrap">
|
||||
<div
|
||||
v-for="tab in statusTabs"
|
||||
:key="tab.value"
|
||||
:class="[
|
||||
'px-4 py-2 rounded-lg cursor-pointer transition-all duration-200 select-none',
|
||||
queryParams.fulfillment_status === tab.value
|
||||
? 'bg-primary text-white shadow-md'
|
||||
: 'bg-gray-50 text-gray-600 hover:bg-gray-100'
|
||||
]"
|
||||
@click="handleStatusTabClick(tab.value)"
|
||||
>
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="font-medium">{{ tab.label }}</span>
|
||||
<span v-if="tab.count !== undefined" :class="[
|
||||
'text-xs px-1.5 py-0.5 rounded',
|
||||
queryParams.fulfillment_status === tab.value
|
||||
? 'bg-white/20'
|
||||
: 'bg-gray-200'
|
||||
]">
|
||||
{{ tab.count }}
|
||||
</span>
|
||||
>>>>>>> master
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -63,15 +90,6 @@
|
||||
@keyup.enter="resetPage"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="w-[180px]" label="履约状态">
|
||||
<el-select v-model="queryParams.fulfillment_status" placeholder="全部" clearable>
|
||||
<el-option label="待双审通过" :value="1" />
|
||||
<el-option label="履约中" :value="2" />
|
||||
<el-option label="已发货" :value="5" />
|
||||
<el-option label="已完成" :value="3" />
|
||||
<el-option label="已取消" :value="4" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="resetPage">查询</el-button>
|
||||
<el-button @click="handleReset">重置</el-button>
|
||||
@@ -88,8 +106,6 @@
|
||||
<el-table-column label="订单号" prop="order_no" min-width="150" show-overflow-tooltip />
|
||||
<el-table-column label="处方ID" prop="prescription_id" width="86" />
|
||||
<el-table-column label="诊单ID" prop="diagnosis_id" width="86" />
|
||||
<el-table-column label="开方人" prop="doctor_name" width="90" show-overflow-tooltip />
|
||||
<el-table-column label="创建人" prop="creator_name" width="90" show-overflow-tooltip />
|
||||
<el-table-column label="收货人" min-width="100">
|
||||
<template #default="{ row }">
|
||||
<div>{{ row.recipient_name || '—' }}</div>
|
||||
@@ -170,6 +186,9 @@
|
||||
{{ formatTime(row.create_time) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="开方人" prop="doctor_name" width="90" show-overflow-tooltip />
|
||||
<el-table-column label="创建人" prop="creator_name" width="90" show-overflow-tooltip />
|
||||
|
||||
<el-table-column label="操作" width="310" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<div class="flex items-center gap-1 flex-wrap">
|
||||
@@ -372,19 +391,19 @@
|
||||
<el-row :gutter="16" class="mb-5">
|
||||
<el-col :xs="12" :sm="8">
|
||||
<el-card shadow="never" class="stat-card border border-gray-100 bg-gray-50/50">
|
||||
<div class="stat-title text-gray-500 text-xs mb-1">业务金额</div>
|
||||
<div class="stat-title text-gray-500 text-xs mb-1">总金额</div>
|
||||
<div class="stat-value text-red-500 font-bold text-xl">¥{{ detailData.amount }}</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :xs="12" :sm="8">
|
||||
<el-card shadow="never" class="stat-card border border-gray-100 bg-gray-50/50">
|
||||
<div class="stat-title text-gray-500 text-xs mb-1">关联订单总额</div>
|
||||
<div class="stat-title text-gray-500 text-xs mb-1">已付总额</div>
|
||||
<div class="stat-value text-green-600 font-bold text-xl">¥{{ detailData.linked_pay_paid_total || 0 }}</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :xs="12" :sm="8">
|
||||
<el-card shadow="never" class="stat-card border border-gray-100 bg-gray-50/50">
|
||||
<div class="stat-title text-gray-500 text-xs mb-1">关联收款笔数</div>
|
||||
<div class="stat-title text-gray-500 text-xs mb-1">已付笔数</div>
|
||||
<div class="stat-value text-primary font-bold text-xl">{{ detailLinkedPayOrders.length }} 笔</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
@@ -764,222 +783,277 @@
|
||||
<el-dialog
|
||||
v-model="editVisible"
|
||||
title="编辑业务订单"
|
||||
width="680px"
|
||||
width="800px"
|
||||
:close-on-click-modal="false"
|
||||
destroy-on-close
|
||||
@closed="editFormRef?.clearValidate()"
|
||||
>
|
||||
<el-form
|
||||
v-loading="editDialogLoading"
|
||||
ref="editFormRef"
|
||||
:model="editForm"
|
||||
:rules="editRules"
|
||||
label-width="110px"
|
||||
class="pr-4"
|
||||
>
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="收货人" prop="recipient_name">
|
||||
<el-input v-model="editForm.recipient_name" maxlength="50" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="收货手机" prop="recipient_phone">
|
||||
<el-input v-model="editForm.recipient_phone" maxlength="20" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-form-item label="省/市/区" prop="region">
|
||||
<el-cascader
|
||||
v-model="editForm.region"
|
||||
:options="regionOptions"
|
||||
:props="{ emitPath: true }"
|
||||
placeholder="请选择省/市/区"
|
||||
clearable
|
||||
filterable
|
||||
class="w-full"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="详细地址" prop="shipping_address">
|
||||
<el-input v-model="editForm.shipping_address" type="textarea" :rows="2" maxlength="500" show-word-limit />
|
||||
</el-form-item>
|
||||
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="是否复诊">
|
||||
<el-switch v-model="editForm.is_follow_up" :active-value="1" :inactive-value="0" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="用药疗程">
|
||||
<el-input-number v-model="editForm.medication_days" :min="1" :max="999" :step="1" class="w-full" placeholder="天数(选填)">
|
||||
<template #append>天</template>
|
||||
</el-input-number>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="剂数" prop="dose_count">
|
||||
<el-input-number
|
||||
v-model="editForm.dose_count"
|
||||
:min="1"
|
||||
placeholder="剂数"
|
||||
<div v-loading="editDialogLoading" class="max-h-[70vh] overflow-y-auto px-2">
|
||||
<el-form
|
||||
ref="editFormRef"
|
||||
:model="editForm"
|
||||
:rules="editRules"
|
||||
label-width="90px"
|
||||
>
|
||||
<!-- 收货信息 -->
|
||||
<div class="mb-4 pb-4 border-b border-gray-100">
|
||||
<div class="text-sm font-medium text-gray-700 mb-3 flex items-center gap-2">
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z" />
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 11a3 3 0 11-6 0 3 3 0 016 0z" />
|
||||
</svg>
|
||||
<span>收货信息</span>
|
||||
</div>
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="收货人" prop="recipient_name">
|
||||
<el-input v-model="editForm.recipient_name" maxlength="50" placeholder="请输入收货人" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="收货手机" prop="recipient_phone">
|
||||
<el-input v-model="editForm.recipient_phone" maxlength="20" placeholder="请输入手机号" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-form-item label="省/市/区" prop="region">
|
||||
<el-cascader
|
||||
v-model="editForm.region"
|
||||
:options="regionOptions"
|
||||
:props="{ emitPath: true }"
|
||||
placeholder="请选择省/市/区"
|
||||
clearable
|
||||
filterable
|
||||
class="w-full"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="剂量单位" prop="dose_unit">
|
||||
<el-select v-model="editForm.dose_unit" placeholder="请选择" class="w-full">
|
||||
<el-option label="剂" value="剂" />
|
||||
<el-option label="丸" value="丸" />
|
||||
<el-option label="袋" value="袋" />
|
||||
<el-option label="盒" value="盒" />
|
||||
<el-option label="瓶" value="瓶" />
|
||||
<el-option label="膏" value="膏" />
|
||||
<el-option label="贴" value="贴" />
|
||||
</el-select>
|
||||
|
||||
<el-form-item label="详细地址" prop="shipping_address">
|
||||
<el-input v-model="editForm.shipping_address" type="textarea" :rows="2" maxlength="500" show-word-limit placeholder="请输入详细地址" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
|
||||
<!-- 甘草预下单测试按钮 -->
|
||||
<el-row v-if="editForm.id" :gutter="24">
|
||||
<el-col :span="24">
|
||||
<el-form-item label="甘草预下单">
|
||||
<!-- 处方信息 -->
|
||||
<div class="mb-4 pb-4 border-b border-gray-100">
|
||||
<div class="text-sm font-medium text-gray-700 mb-3 flex items-center gap-2">
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
|
||||
</svg>
|
||||
<span>处方信息</span>
|
||||
</div>
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="是否复诊">
|
||||
<el-switch v-model="editForm.is_follow_up" :active-value="1" :inactive-value="0" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="用药疗程">
|
||||
<div class="flex items-center gap-2">
|
||||
<el-input-number
|
||||
v-model="editForm.medication_days"
|
||||
:min="1"
|
||||
:max="999"
|
||||
:step="1"
|
||||
class="flex-1"
|
||||
placeholder="天数"
|
||||
controls-position="right"
|
||||
/>
|
||||
<span class="text-gray-600 text-sm">天</span>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="上次医生">
|
||||
<el-input v-model="editForm.prev_staff" maxlength="100" placeholder="医生/医助" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="12">
|
||||
<el-form-item :label="doseCountLabel" prop="dose_count">
|
||||
<el-input-number
|
||||
v-model="editForm.dose_count"
|
||||
:min="1"
|
||||
:placeholder="doseCountLabel"
|
||||
class="w-full"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="剂量单位" prop="dose_unit">
|
||||
<el-select v-model="editForm.dose_unit" placeholder="请选择" class="w-full">
|
||||
<el-option label="剂" value="剂" />
|
||||
<el-option label="丸" value="丸" />
|
||||
<el-option label="袋" value="袋" />
|
||||
<el-option label="盒" value="盒" />
|
||||
<el-option label="瓶" value="瓶" />
|
||||
<el-option label="膏" value="膏" />
|
||||
<el-option label="贴" value="贴" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
|
||||
<!-- 服务信息 -->
|
||||
<div class="mb-4 pb-4 border-b border-gray-100">
|
||||
<div class="text-sm font-medium text-gray-700 mb-3 flex items-center gap-2">
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 13.255A23.931 23.931 0 0112 15c-3.183 0-6.22-.62-9-1.745M16 6V4a2 2 0 00-2-2h-4a2 2 0 00-2 2v2m4 6h.01M5 20h14a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
|
||||
</svg>
|
||||
<span>服务信息</span>
|
||||
</div>
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="服务渠道">
|
||||
<el-input v-model="editForm.service_channel" maxlength="100" placeholder="请输入服务渠道" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="服务套餐">
|
||||
<el-select
|
||||
v-model="editForm.service_package"
|
||||
multiple
|
||||
collapse-tags
|
||||
collapse-tags-tooltip
|
||||
placeholder="请选择服务套餐"
|
||||
clearable
|
||||
class="w-full"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in servicePackageOptions"
|
||||
:key="item.value"
|
||||
:label="item.name"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
|
||||
<!-- 物流信息 -->
|
||||
<div class="mb-4 pb-4 border-b border-gray-100">
|
||||
<div class="text-sm font-medium text-gray-700 mb-3 flex items-center gap-2">
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 8h14M5 8a2 2 0 110-4h14a2 2 0 110 4M5 8v10a2 2 0 002 2h10a2 2 0 002-2V8m-9 4h4" />
|
||||
</svg>
|
||||
<span>物流信息</span>
|
||||
</div>
|
||||
<el-form-item label="物流设置">
|
||||
<div class="flex gap-2 w-full">
|
||||
<el-select v-model="editForm.express_company" placeholder="承运商" class="w-[140px]">
|
||||
<el-option label="自动识别" value="auto" />
|
||||
<el-option label="顺丰速运" value="sf" />
|
||||
<el-option label="京东快递" value="jd" />
|
||||
<el-option label="极兔速递" value="jt" />
|
||||
</el-select>
|
||||
<el-input v-model="editForm.tracking_number" maxlength="80" placeholder="快递单号" class="flex-1" />
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 甘草预下单测试按钮 -->
|
||||
<el-form-item v-if="editForm.id" label="甘草预下单">
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
size="small"
|
||||
:loading="gancaoPreviewLoading"
|
||||
:icon="Search"
|
||||
@click="testGancaoPreview"
|
||||
>
|
||||
测试价格
|
||||
</el-button>
|
||||
<span class="ml-3 text-xs text-gray-400">
|
||||
<span class="ml-2 text-xs text-gray-400">
|
||||
测试当前配置的甘草预下单价格(不会真实提交订单)
|
||||
</span>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-form-item label="上次医生">
|
||||
<el-input v-model="editForm.prev_staff" maxlength="100" placeholder="上次诊疗的医生/医助" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="服务渠道">
|
||||
<el-input v-model="editForm.service_channel" maxlength="100" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="服务套餐">
|
||||
<el-select
|
||||
v-model="editForm.service_package"
|
||||
multiple
|
||||
collapse-tags
|
||||
collapse-tags-tooltip
|
||||
placeholder="请选择服务套餐"
|
||||
clearable
|
||||
class="w-full"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in servicePackageOptions"
|
||||
:key="item.value"
|
||||
:label="item.name"
|
||||
:value="item.value"
|
||||
/>
|
||||
<!-- 费用信息 -->
|
||||
<div class="mb-4">
|
||||
<div class="text-sm font-medium text-gray-700 mb-3 flex items-center gap-2">
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||
</svg>
|
||||
<span>费用信息</span>
|
||||
</div>
|
||||
|
||||
<el-form-item label="费用类别" prop="fee_type">
|
||||
<el-select v-model="editForm.fee_type" class="w-full">
|
||||
<el-option label="挂号费" :value="1" />
|
||||
<el-option label="问诊费" :value="2" />
|
||||
<el-option label="药品费用" :value="3" />
|
||||
<el-option label="首付费用" :value="4" />
|
||||
<el-option label="尾款费用" :value="5" />
|
||||
<el-option label="其他费用" :value="6" />
|
||||
<el-option label="全部费用" :value="7" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-form-item label="物流设置">
|
||||
<div class="flex gap-2 w-full">
|
||||
<el-select v-model="editForm.express_company" placeholder="承运商" class="w-[140px]">
|
||||
<el-option label="自动识别" value="auto" />
|
||||
<el-option label="顺丰速运" value="sf" />
|
||||
<el-option label="京东快递" value="jd" />
|
||||
<el-option label="极兔速递" value="jt" />
|
||||
</el-select>
|
||||
<el-input v-model="editForm.tracking_number" maxlength="80" placeholder="快递单号" class="flex-1" />
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="费用类别" prop="fee_type">
|
||||
<el-select v-model="editForm.fee_type" class="w-full">
|
||||
<el-option label="挂号费" :value="1" />
|
||||
<el-option label="问诊费" :value="2" />
|
||||
<el-option label="药品费用" :value="3" />
|
||||
<el-option label="首付费用" :value="4" />
|
||||
<el-option label="尾款费用" :value="5" />
|
||||
<el-option label="其他费用" :value="6" />
|
||||
<el-option label="全部费用" :value="7" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="关联支付单">
|
||||
<el-select
|
||||
v-model="editForm.pay_order_ids"
|
||||
class="w-full"
|
||||
multiple
|
||||
collapse-tags
|
||||
collapse-tags-tooltip
|
||||
placeholder="多选本诊单已支付收款单"
|
||||
:loading="editPaidOrdersLoading"
|
||||
>
|
||||
<el-option
|
||||
v-for="o in editPaidOrders"
|
||||
:key="o.id"
|
||||
:label="`${o.order_no} · ¥${o.amount} · ${formatPoCategory(o.order_type)}`"
|
||||
:value="o.id"
|
||||
class="!h-auto py-1.5"
|
||||
>
|
||||
<div class="flex flex-col gap-0.5" style="line-height: normal;">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="font-medium text-[13px] text-gray-800">{{ o.order_no }}</span>
|
||||
<span class="text-orange-500 font-medium ml-4">¥{{ o.amount }}</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between text-xs text-gray-400 mt-1">
|
||||
<span class="truncate pr-2">{{ formatPoCategory(o.order_type) }}<template v-if="o.remark"> · {{ o.remark }}</template></span>
|
||||
<span class="shrink-0">{{ String(o.create_time || '').substring(0, 16) }}</span>
|
||||
</div>
|
||||
|
||||
<el-form-item label="关联支付单">
|
||||
<el-select
|
||||
v-model="editForm.pay_order_ids"
|
||||
class="w-full"
|
||||
multiple
|
||||
collapse-tags
|
||||
collapse-tags-tooltip
|
||||
placeholder="多选本诊单已支付收款单"
|
||||
:loading="editPaidOrdersLoading"
|
||||
>
|
||||
<el-option
|
||||
v-for="o in editPaidOrders"
|
||||
:key="o.id"
|
||||
:label="`${o.order_no} · ¥${o.amount} · ${formatPoCategory(o.order_type)}`"
|
||||
:value="o.id"
|
||||
class="!h-auto py-1.5"
|
||||
>
|
||||
<div class="flex flex-col gap-0.5" style="line-height: normal;">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="font-medium text-[13px] text-gray-800">{{ o.order_no }}</span>
|
||||
<span class="text-orange-500 font-medium ml-4">¥{{ o.amount }}</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between text-xs text-gray-400 mt-1">
|
||||
<span class="truncate pr-2">{{ formatPoCategory(o.order_type) }}<template v-if="o.remark"> · {{ o.remark }}</template></span>
|
||||
<span class="shrink-0">{{ String(o.create_time || '').substring(0, 16) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</el-option>
|
||||
</el-select>
|
||||
<div class="text-xs text-gray-500 mt-1.5 leading-normal">
|
||||
已选收款合计:<span class="text-primary font-medium">¥{{ formatMoney(editLinkedPaidTotal) }}</span>
|
||||
</div>
|
||||
</el-option>
|
||||
</el-select>
|
||||
<div class="text-xs text-gray-500 mt-1.5 leading-normal">
|
||||
可对照此处关联收款记录。已选收款合计:<span class="text-primary font-medium">¥{{ formatMoney(editLinkedPaidTotal) }}</span>。
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="订单金额" prop="amount">
|
||||
<el-input-number
|
||||
v-model="editForm.amount"
|
||||
:min="editAmountInputMin"
|
||||
:step="0.01"
|
||||
:precision="2"
|
||||
class="w-full font-medium"
|
||||
/>
|
||||
<div v-if="editDepositMin > 0" class="text-xs text-amber-500 mt-1.5 leading-normal">
|
||||
须 ≥ 定金门槛 ¥{{ formatMoney(editDepositMin) }}。若您手动填写的金额比关联的支付总额小,请确保符合您的业务逻辑。
|
||||
<el-form-item label="订单金额" prop="amount">
|
||||
<el-input-number
|
||||
v-model="editForm.amount"
|
||||
:min="editAmountInputMin"
|
||||
:step="0.01"
|
||||
:precision="2"
|
||||
class="w-full font-medium"
|
||||
/>
|
||||
<div v-if="editDepositMin > 0" class="text-xs text-amber-500 mt-1.5 leading-normal">
|
||||
须 ≥ 定金门槛 ¥{{ formatMoney(editDepositMin) }}
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item
|
||||
v-perms="['finance.account_log/lists']"
|
||||
label="内部成本"
|
||||
>
|
||||
<el-input-number v-model="editForm.internal_cost" :min="0" :step="0.01" :precision="2" class="w-full" placeholder="内部管理核算(选填)" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="备注补充">
|
||||
<el-input v-model="editForm.remark_extra" type="textarea" :rows="2" maxlength="500" show-word-limit placeholder="可选填备注信息" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item
|
||||
v-perms="['finance.account_log/lists']"
|
||||
label="内部成本"
|
||||
>
|
||||
<el-input-number v-model="editForm.internal_cost" :min="0" :step="0.01" :precision="2" class="w-full" placeholder="内部管理核算(选填)" />
|
||||
</el-form-item>
|
||||
<el-form-item label="备注补充">
|
||||
<el-input v-model="editForm.remark_extra" type="textarea" :rows="2" maxlength="500" show-word-limit />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-form>
|
||||
</div>
|
||||
<template #footer>
|
||||
<el-button @click="editVisible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="editSaving" @click="submitEdit">确认保存</el-button>
|
||||
@@ -1555,8 +1629,12 @@ const transformRegionData = (data: any[]) => {
|
||||
const loadRegionData = async () => {
|
||||
try {
|
||||
console.log('开始加载省市区数据...')
|
||||
// 使用代理路径,需要在vite.config.ts中配置代理
|
||||
const response = await fetch('/api-proxy/area/ChinaCitys.json')
|
||||
// 开发环境使用代理,生产环境使用环境变量中的基础URL
|
||||
const apiUrl = import.meta.env.DEV
|
||||
? '/api-proxy/area/ChinaCitys.json'
|
||||
: `https://cos.zhenyangtang.com.cn/area/ChinaCitys.json`
|
||||
|
||||
const response = await fetch(apiUrl)
|
||||
console.log('响应状态:', response.status)
|
||||
|
||||
if (!response.ok) {
|
||||
@@ -1572,40 +1650,7 @@ const loadRegionData = async () => {
|
||||
} catch (error) {
|
||||
console.error('加载省市区数据失败:', error)
|
||||
// 如果加载失败,使用基本的省市数据作为后备
|
||||
regionOptions.value = [
|
||||
{
|
||||
value: '四川省',
|
||||
label: '四川省',
|
||||
children: [
|
||||
{
|
||||
value: '成都市',
|
||||
label: '成都市',
|
||||
children: [
|
||||
{ value: '武侯区', label: '武侯区' },
|
||||
{ value: '锦江区', label: '锦江区' },
|
||||
{ value: '青羊区', label: '青羊区' },
|
||||
{ value: '金牛区', label: '金牛区' },
|
||||
{ value: '成华区', label: '成华区' }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
value: '北京市',
|
||||
label: '北京市',
|
||||
children: [
|
||||
{
|
||||
value: '北京市',
|
||||
label: '北京市',
|
||||
children: [
|
||||
{ value: '朝阳区', label: '朝阳区' },
|
||||
{ value: '海淀区', label: '海淀区' },
|
||||
{ value: '东城区', label: '东城区' }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
regionOptions.value = []
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1621,6 +1666,22 @@ const loadServicePackageOptions = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
// 状态标签页配置
|
||||
const statusTabs = ref([
|
||||
{ label: '全部', value: '' as number | '', count: undefined },
|
||||
{ label: '待双审通过', value: 1, count: undefined },
|
||||
{ label: '履约中', value: 2, count: undefined },
|
||||
{ label: '已发货', value: 5, count: undefined },
|
||||
{ label: '已完成', value: 3, count: undefined },
|
||||
{ label: '已取消', value: 4, count: undefined }
|
||||
])
|
||||
|
||||
// 处理状态标签点击
|
||||
const handleStatusTabClick = (value: number | '') => {
|
||||
queryParams.fulfillment_status = value
|
||||
resetPage()
|
||||
}
|
||||
|
||||
const queryParams = reactive({
|
||||
order_no: '',
|
||||
prescription_id: '' as string | number,
|
||||
@@ -1979,6 +2040,12 @@ const detailFullAddress = computed(() => {
|
||||
return parts.length > 0 ? parts.join(' ') : '—'
|
||||
})
|
||||
|
||||
// 动态剂数标签(根据剂量单位变化)
|
||||
const doseCountLabel = computed(() => {
|
||||
const unit = editForm.dose_unit || '剂'
|
||||
return `${unit}数`
|
||||
})
|
||||
|
||||
function consumerRxAuditText(s: number | undefined) {
|
||||
const n = Number(s)
|
||||
if (n === 1) return '已通过'
|
||||
|
||||
@@ -2,14 +2,53 @@
|
||||
<div class="blood-record-list">
|
||||
<div class="mb-4">
|
||||
<el-button type="primary" @click="handleAdd">添加记录</el-button>
|
||||
<el-select v-model="trendDays" @change="handleTrendDaysChange" class="ml-2" style="width: 150px">
|
||||
<el-option label="最近7天" :value="7" />
|
||||
<el-option label="最近30天" :value="30" />
|
||||
<el-option label="最近90天" :value="90" />
|
||||
<el-option label="最近一年" :value="365" />
|
||||
<el-option label="自定义" :value="0" />
|
||||
</el-select>
|
||||
<el-date-picker
|
||||
v-if="trendDays === 0"
|
||||
v-model="customDateRange"
|
||||
type="daterange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
@change="loadTrendData"
|
||||
class="ml-2"
|
||||
style="width: 300px"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<el-table :data="recordList" border>
|
||||
|
||||
<div class="mb-4">
|
||||
<el-card>
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>血糖趋势图</span>
|
||||
</div>
|
||||
</template>
|
||||
<div ref="chartRef" style="width: 100%; height: 400px"></div>
|
||||
</el-card>
|
||||
</div>
|
||||
|
||||
<el-table :data="recordList" border style="width: 100%">
|
||||
<el-table-column prop="record_date" label="记录日期" width="120" />
|
||||
<el-table-column prop="record_time" label="记录时间" width="100" />
|
||||
<el-table-column prop="blood_sugar" label="血糖(mmol/L)" width="120">
|
||||
<el-table-column label="空腹血糖(mmol/L)" width="120">
|
||||
<template #default="{ row }">
|
||||
{{ row.blood_sugar || '-' }}
|
||||
{{ row.fasting_blood_sugar || '-' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="餐后2小时血糖(mmol/L)" width="150">
|
||||
<template #default="{ row }">
|
||||
{{ row.postprandial_blood_sugar || '-' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="其他血糖(mmol/L)" width="120">
|
||||
<template #default="{ row }">
|
||||
{{ row.other_blood_sugar || '-' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="血压(mmHg)" width="150">
|
||||
@@ -20,6 +59,8 @@
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="western_medicine" label="西药" show-overflow-tooltip />
|
||||
<el-table-column prop="insulin" label="胰岛素" show-overflow-tooltip />
|
||||
<el-table-column prop="remark" label="备注" show-overflow-tooltip />
|
||||
<el-table-column label="操作" width="150" fixed="right">
|
||||
<template #default="{ row }">
|
||||
@@ -50,14 +91,36 @@
|
||||
class="w-full"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="血糖值">
|
||||
<el-form-item label="空腹血糖">
|
||||
<el-input-number
|
||||
v-model="recordForm.blood_sugar"
|
||||
v-model="recordForm.fasting_blood_sugar"
|
||||
:precision="2"
|
||||
:step="0.1"
|
||||
:min="0"
|
||||
:max="50"
|
||||
placeholder="请输入血糖值"
|
||||
placeholder="请输入空腹血糖"
|
||||
/>
|
||||
<span class="ml-2">mmol/L</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="餐后2小时血糖">
|
||||
<el-input-number
|
||||
v-model="recordForm.postprandial_blood_sugar"
|
||||
:precision="2"
|
||||
:step="0.1"
|
||||
:min="0"
|
||||
:max="50"
|
||||
placeholder="请输入餐后2小时血糖"
|
||||
/>
|
||||
<span class="ml-2">mmol/L</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="其他血糖">
|
||||
<el-input-number
|
||||
v-model="recordForm.other_blood_sugar"
|
||||
:precision="2"
|
||||
:step="0.1"
|
||||
:min="0"
|
||||
:max="50"
|
||||
placeholder="请输入其他血糖"
|
||||
/>
|
||||
<span class="ml-2">mmol/L</span>
|
||||
</el-form-item>
|
||||
@@ -79,6 +142,18 @@
|
||||
/>
|
||||
<span class="ml-2">mmHg</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="西药">
|
||||
<el-input
|
||||
v-model="recordForm.western_medicine"
|
||||
placeholder="请输入西药"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="胰岛素">
|
||||
<el-input
|
||||
v-model="recordForm.insulin"
|
||||
placeholder="请输入胰岛素"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注">
|
||||
<el-input
|
||||
v-model="recordForm.remark"
|
||||
@@ -97,8 +172,10 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { bloodRecordAdd, bloodRecordEdit, bloodRecordDelete, getRecordsByPatient } from '@/api/tcm'
|
||||
import { bloodRecordAdd, bloodRecordEdit, bloodRecordDelete, getRecordsByPatient, getBloodSugarTrend } from '@/api/tcm'
|
||||
import feedback from '@/utils/feedback'
|
||||
import * as echarts from 'echarts'
|
||||
import { nextTick } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
diagnosisId: {
|
||||
@@ -115,6 +192,18 @@ const recordList = ref([])
|
||||
const dialogVisible = ref(false)
|
||||
const submitting = ref(false)
|
||||
const dialogTitle = computed(() => recordForm.value.id ? '编辑记录' : '添加记录')
|
||||
const trendDays = ref(7)
|
||||
const customDateRange = ref<[Date, Date] | null>(null)
|
||||
const trendData = ref({
|
||||
dates: [],
|
||||
fasting: [],
|
||||
postprandial_2h: [],
|
||||
other: []
|
||||
})
|
||||
const chartRef = ref()
|
||||
let chartInstance: any = null
|
||||
let renderRetryCount = 0
|
||||
const MAX_RETRY_COUNT = 5
|
||||
|
||||
const recordForm = ref({
|
||||
id: '',
|
||||
@@ -122,12 +211,144 @@ const recordForm = ref({
|
||||
patient_id: props.patientId,
|
||||
record_date: '',
|
||||
record_time: '',
|
||||
blood_sugar: null,
|
||||
systolic_pressure: null,
|
||||
diastolic_pressure: null,
|
||||
fasting_blood_sugar: 0,
|
||||
postprandial_blood_sugar: 0,
|
||||
other_blood_sugar: 0,
|
||||
systolic_pressure: 0,
|
||||
diastolic_pressure: 0,
|
||||
western_medicine: '',
|
||||
insulin: '',
|
||||
remark: ''
|
||||
})
|
||||
|
||||
const loadTrendData = async () => {
|
||||
if (!props.diagnosisId && !props.patientId) {
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
const params: any = {
|
||||
diagnosis_id: props.diagnosisId,
|
||||
patient_id: props.patientId
|
||||
}
|
||||
|
||||
if (trendDays.value === 0 && customDateRange.value) {
|
||||
params.start_date = Math.floor(customDateRange.value[0].getTime() / 1000)
|
||||
params.end_date = Math.floor(customDateRange.value[1].getTime() / 1000)
|
||||
} else {
|
||||
params.days = trendDays.value
|
||||
}
|
||||
|
||||
const data = await getBloodSugarTrend(params)
|
||||
trendData.value = data
|
||||
renderChart()
|
||||
} catch (error) {
|
||||
console.error('获取趋势图数据失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
const handleTrendDaysChange = () => {
|
||||
if (trendDays.value !== 0) {
|
||||
customDateRange.value = null
|
||||
}
|
||||
loadTrendData()
|
||||
}
|
||||
|
||||
const renderChart = () => {
|
||||
nextTick(() => {
|
||||
setTimeout(() => {
|
||||
if (!chartRef.value) {
|
||||
return
|
||||
}
|
||||
|
||||
const container = chartRef.value
|
||||
|
||||
if (container.clientWidth === 0 || container.clientHeight === 0) {
|
||||
if (renderRetryCount < MAX_RETRY_COUNT) {
|
||||
renderRetryCount++
|
||||
setTimeout(() => renderChart(), 100)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 重置重试计数器
|
||||
renderRetryCount = 0
|
||||
|
||||
if (chartInstance) {
|
||||
chartInstance.dispose()
|
||||
}
|
||||
|
||||
chartInstance = echarts.init(container)
|
||||
|
||||
// 准备数据,确保每个日期都有对应的值
|
||||
const prepareData = (dataArray: any[], dates: string[]) => {
|
||||
const dataMap = new Map()
|
||||
dataArray.forEach(item => {
|
||||
dataMap.set(item.date, item.value)
|
||||
})
|
||||
return dates.map(date => dataMap.get(date) || null)
|
||||
}
|
||||
|
||||
const fastingData = prepareData(trendData.value.fasting, trendData.value.dates)
|
||||
const postprandialData = prepareData(trendData.value.postprandial_2h, trendData.value.dates)
|
||||
const otherData = prepareData(trendData.value.other, trendData.value.dates)
|
||||
|
||||
const option = {
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'cross'
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
data: ['空腹血糖', '餐后2小时血糖', '其他血糖']
|
||||
},
|
||||
grid: {
|
||||
left: '3%',
|
||||
right: '4%',
|
||||
bottom: '3%',
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
data: trendData.value.dates
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
name: '血糖值 (mmol/L)'
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '空腹血糖',
|
||||
type: 'line',
|
||||
data: fastingData,
|
||||
smooth: true,
|
||||
connectNulls: true
|
||||
},
|
||||
{
|
||||
name: '餐后2小时血糖',
|
||||
type: 'line',
|
||||
data: postprandialData,
|
||||
smooth: true,
|
||||
connectNulls: true
|
||||
},
|
||||
{
|
||||
name: '其他血糖',
|
||||
type: 'line',
|
||||
data: otherData,
|
||||
smooth: true,
|
||||
connectNulls: true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
chartInstance.setOption(option)
|
||||
chartInstance.resize()
|
||||
}, 100)
|
||||
})
|
||||
}
|
||||
|
||||
// 获取记录列表
|
||||
const getRecords = async () => {
|
||||
if (!props.diagnosisId && !props.patientId) {
|
||||
@@ -153,9 +374,13 @@ const handleAdd = () => {
|
||||
patient_id: props.patientId,
|
||||
record_date: '',
|
||||
record_time: '',
|
||||
blood_sugar: null,
|
||||
systolic_pressure: null,
|
||||
diastolic_pressure: null,
|
||||
fasting_blood_sugar: 0,
|
||||
postprandial_blood_sugar: 0,
|
||||
other_blood_sugar: 0,
|
||||
systolic_pressure: 0,
|
||||
diastolic_pressure: 0,
|
||||
western_medicine: '',
|
||||
insulin: '',
|
||||
remark: ''
|
||||
}
|
||||
dialogVisible.value = true
|
||||
@@ -163,7 +388,14 @@ const handleAdd = () => {
|
||||
|
||||
// 编辑记录
|
||||
const handleEdit = (row: any) => {
|
||||
recordForm.value = { ...row }
|
||||
recordForm.value = {
|
||||
...row,
|
||||
fasting_blood_sugar: parseFloat(row.fasting_blood_sugar) || 0,
|
||||
postprandial_blood_sugar: parseFloat(row.postprandial_blood_sugar) || 0,
|
||||
other_blood_sugar: parseFloat(row.other_blood_sugar) || 0,
|
||||
systolic_pressure: parseInt(row.systolic_pressure) || 0,
|
||||
diastolic_pressure: parseInt(row.diastolic_pressure) || 0
|
||||
}
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
@@ -197,6 +429,7 @@ const handleSubmit = async () => {
|
||||
}
|
||||
dialogVisible.value = false
|
||||
getRecords()
|
||||
loadTrendData()
|
||||
} catch (error) {
|
||||
console.error('提交失败:', error)
|
||||
} finally {
|
||||
@@ -205,12 +438,33 @@ const handleSubmit = async () => {
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getRecords()
|
||||
// 延迟加载数据,确保DOM完全渲染
|
||||
setTimeout(() => {
|
||||
getRecords()
|
||||
loadTrendData()
|
||||
}, 500)
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
if (chartInstance) {
|
||||
chartInstance.dispose()
|
||||
}
|
||||
})
|
||||
|
||||
// 监听props变化
|
||||
watch(() => [props.diagnosisId, props.patientId], () => {
|
||||
getRecords()
|
||||
loadTrendData()
|
||||
})
|
||||
|
||||
// 监听组件可见性变化(Tab切换时)
|
||||
watch(() => props.diagnosisId, (newVal) => {
|
||||
if (newVal) {
|
||||
// 当组件变为可见时,延迟重新渲染图表
|
||||
setTimeout(() => {
|
||||
renderChart()
|
||||
}, 500)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
@@ -0,0 +1,236 @@
|
||||
<template>
|
||||
<div class="diet-record-list">
|
||||
<div class="mb-4">
|
||||
<el-button type="primary" @click="handleAdd">添加记录</el-button>
|
||||
</div>
|
||||
|
||||
<el-table :data="recordList" border>
|
||||
<el-table-column prop="record_date" label="记录日期" width="120" />
|
||||
<el-table-column label="早餐" min-width="200">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row.breakfast_foods">{{ row.breakfast_foods }}</div>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="午餐" min-width="200">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row.lunch_foods">{{ row.lunch_foods }}</div>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="晚餐" min-width="200">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row.dinner_foods">{{ row.dinner_foods }}</div>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="note" label="备注" show-overflow-tooltip />
|
||||
<el-table-column label="操作" width="150" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button link type="primary" @click="handleEdit(row)">编辑</el-button>
|
||||
<el-button link type="danger" @click="handleDelete(row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="800px">
|
||||
<el-form :model="recordForm" label-width="100px">
|
||||
<el-form-item label="记录日期" required>
|
||||
<el-date-picker
|
||||
v-model="recordForm.record_date"
|
||||
type="date"
|
||||
placeholder="选择日期"
|
||||
value-format="YYYY-MM-DD"
|
||||
class="w-full"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-divider content-position="left">早餐</el-divider>
|
||||
<el-form-item label="食物描述">
|
||||
<el-input
|
||||
v-model="recordForm.breakfast_foods"
|
||||
type="textarea"
|
||||
:rows="2"
|
||||
placeholder="请输入早餐食物"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="图片">
|
||||
<material-picker
|
||||
v-model="recordForm.breakfast_images"
|
||||
:limit="3"
|
||||
type="image"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-divider content-position="left">午餐</el-divider>
|
||||
<el-form-item label="食物描述">
|
||||
<el-input
|
||||
v-model="recordForm.lunch_foods"
|
||||
type="textarea"
|
||||
:rows="2"
|
||||
placeholder="请输入午餐食物"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="图片">
|
||||
<material-picker
|
||||
v-model="recordForm.lunch_images"
|
||||
:limit="3"
|
||||
type="image"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-divider content-position="left">晚餐</el-divider>
|
||||
<el-form-item label="食物描述">
|
||||
<el-input
|
||||
v-model="recordForm.dinner_foods"
|
||||
type="textarea"
|
||||
:rows="2"
|
||||
placeholder="请输入晚餐食物"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="图片">
|
||||
<material-picker
|
||||
v-model="recordForm.dinner_images"
|
||||
:limit="3"
|
||||
type="image"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="备注">
|
||||
<el-input
|
||||
v-model="recordForm.note"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="请输入备注"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" :loading="submitting">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { dietRecordAdd, dietRecordEdit, dietRecordDelete, getDietRecordsByPatient } from '@/api/tcm'
|
||||
import feedback from '@/utils/feedback'
|
||||
|
||||
const props = defineProps({
|
||||
diagnosisId: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
patientId: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
})
|
||||
|
||||
const recordList = ref([])
|
||||
const dialogVisible = ref(false)
|
||||
const submitting = ref(false)
|
||||
const dialogTitle = computed(() => recordForm.value.id ? '编辑记录' : '添加记录')
|
||||
|
||||
const recordForm = ref({
|
||||
id: '',
|
||||
diagnosis_id: props.diagnosisId,
|
||||
patient_id: props.patientId,
|
||||
record_date: '',
|
||||
breakfast_foods: '',
|
||||
breakfast_images: [],
|
||||
lunch_foods: '',
|
||||
lunch_images: [],
|
||||
dinner_foods: '',
|
||||
dinner_images: [],
|
||||
note: ''
|
||||
})
|
||||
|
||||
const getRecords = async () => {
|
||||
if (!props.diagnosisId && !props.patientId) {
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
const data = await getDietRecordsByPatient({
|
||||
diagnosis_id: props.diagnosisId,
|
||||
patient_id: props.patientId
|
||||
})
|
||||
recordList.value = data
|
||||
} catch (error) {
|
||||
console.error('获取记录失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
const handleAdd = () => {
|
||||
recordForm.value = {
|
||||
id: '',
|
||||
diagnosis_id: props.diagnosisId,
|
||||
patient_id: props.patientId,
|
||||
record_date: '',
|
||||
breakfast_foods: '',
|
||||
breakfast_images: [],
|
||||
lunch_foods: '',
|
||||
lunch_images: [],
|
||||
dinner_foods: '',
|
||||
dinner_images: [],
|
||||
note: ''
|
||||
}
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
const handleEdit = (row: any) => {
|
||||
recordForm.value = { ...row }
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
const handleDelete = async (row: any) => {
|
||||
await feedback.confirm('确定要删除这条记录吗?')
|
||||
try {
|
||||
await dietRecordDelete({ id: row.id })
|
||||
feedback.msgSuccess('删除成功')
|
||||
getRecords()
|
||||
} catch (error) {
|
||||
console.error('删除失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (!recordForm.value.record_date) {
|
||||
feedback.msgWarning('请选择记录日期')
|
||||
return
|
||||
}
|
||||
|
||||
submitting.value = true
|
||||
try {
|
||||
if (recordForm.value.id) {
|
||||
await dietRecordEdit(recordForm.value)
|
||||
feedback.msgSuccess('编辑成功')
|
||||
} else {
|
||||
await dietRecordAdd(recordForm.value)
|
||||
feedback.msgSuccess('添加成功')
|
||||
}
|
||||
dialogVisible.value = false
|
||||
getRecords()
|
||||
} catch (error) {
|
||||
console.error('提交失败:', error)
|
||||
} finally {
|
||||
submitting.value = false
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getRecords()
|
||||
})
|
||||
|
||||
watch(() => [props.diagnosisId, props.patientId], () => {
|
||||
getRecords()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.diet-record-list {
|
||||
padding: 20px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,227 @@
|
||||
<template>
|
||||
<div class="exercise-record-list">
|
||||
<div class="mb-4">
|
||||
<el-button type="primary" @click="handleAdd">添加记录</el-button>
|
||||
</div>
|
||||
|
||||
<el-table :data="recordList" border style="width: 100%">
|
||||
<el-table-column prop="record_date" label="记录日期" width="120" />
|
||||
<el-table-column prop="exercise_type" label="运动类型" width="150" />
|
||||
<el-table-column prop="duration" label="运动时长" width="100">
|
||||
<template #default="{ row }">
|
||||
{{ row.duration }} 分钟
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="运动强度" width="100">
|
||||
<template #default="{ row }">
|
||||
{{ getIntensityText(row.intensity) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="note" label="备注" show-overflow-tooltip />
|
||||
<el-table-column label="操作" width="150" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button link type="primary" @click="handleEdit(row)">编辑</el-button>
|
||||
<el-button link type="danger" @click="handleDelete(row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="600px">
|
||||
<el-form :model="recordForm" label-width="120px">
|
||||
<el-form-item label="记录日期" required>
|
||||
<el-date-picker
|
||||
v-model="recordForm.record_date"
|
||||
type="date"
|
||||
placeholder="选择日期"
|
||||
value-format="YYYY-MM-DD"
|
||||
class="w-full"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="运动类型" required>
|
||||
<el-select v-model="recordForm.exercise_type" placeholder="请选择运动类型" class="w-full">
|
||||
<el-option label="散步" :value="'散步'" />
|
||||
<el-option label="慢跑" :value="'慢跑'" />
|
||||
<el-option label="游泳" :value="'游泳'" />
|
||||
<el-option label="瑜伽" :value="'瑜伽'" />
|
||||
<el-option label="骑自行车" :value="'骑自行车'" />
|
||||
<el-option label="打太极拳" :value="'打太极拳'" />
|
||||
<el-option label="其他" :value="'其他'" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="运动时长(分钟)" required>
|
||||
<el-input-number
|
||||
v-model="recordForm.duration"
|
||||
:min="0"
|
||||
:max="300"
|
||||
placeholder="请输入运动时长"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="运动强度" required>
|
||||
<el-select v-model="recordForm.intensity" placeholder="请选择运动强度" class="w-full">
|
||||
<el-option label="低强度" :value="1" />
|
||||
<el-option label="中强度" :value="2" />
|
||||
<el-option label="高强度" :value="3" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="运动图片">
|
||||
<material-picker
|
||||
v-model="recordForm.images"
|
||||
:limit="3"
|
||||
type="image"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注">
|
||||
<el-input
|
||||
v-model="recordForm.note"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="请输入备注"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" :loading="submitting">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { exerciseRecordAdd, exerciseRecordEdit, exerciseRecordDelete, getExerciseRecordsByPatient } from '@/api/tcm'
|
||||
import feedback from '@/utils/feedback'
|
||||
|
||||
const props = defineProps({
|
||||
diagnosisId: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
patientId: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
})
|
||||
|
||||
const recordList = ref([])
|
||||
const dialogVisible = ref(false)
|
||||
const submitting = ref(false)
|
||||
const dialogTitle = computed(() => recordForm.value.id ? '编辑记录' : '添加记录')
|
||||
|
||||
const recordForm = ref({
|
||||
id: '',
|
||||
diagnosis_id: props.diagnosisId,
|
||||
patient_id: props.patientId,
|
||||
record_date: '',
|
||||
exercise_type: '',
|
||||
duration: 0,
|
||||
intensity: 1,
|
||||
images: [],
|
||||
note: ''
|
||||
})
|
||||
|
||||
const intensityOptions = [
|
||||
{ label: '低强度', value: 1 },
|
||||
{ label: '中强度', value: 2 },
|
||||
{ label: '高强度', value: 3 }
|
||||
]
|
||||
|
||||
const getIntensityText = (intensity: number) => {
|
||||
const option = intensityOptions.find(opt => opt.value === intensity)
|
||||
return option ? option.label : '未知'
|
||||
}
|
||||
|
||||
const getRecords = async () => {
|
||||
if (!props.diagnosisId && !props.patientId) {
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
const data = await getExerciseRecordsByPatient({
|
||||
diagnosis_id: props.diagnosisId,
|
||||
patient_id: props.patientId
|
||||
})
|
||||
recordList.value = data
|
||||
} catch (error) {
|
||||
console.error('获取记录失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
const handleAdd = () => {
|
||||
recordForm.value = {
|
||||
id: '',
|
||||
diagnosis_id: props.diagnosisId,
|
||||
patient_id: props.patientId,
|
||||
record_date: '',
|
||||
exercise_type: '',
|
||||
duration: 0,
|
||||
intensity: 1,
|
||||
images: [],
|
||||
note: ''
|
||||
}
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
const handleEdit = (row: any) => {
|
||||
recordForm.value = { ...row }
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
const handleDelete = async (row: any) => {
|
||||
await feedback.confirm('确定要删除这条记录吗?')
|
||||
try {
|
||||
await exerciseRecordDelete({ id: row.id })
|
||||
feedback.msgSuccess('删除成功')
|
||||
getRecords()
|
||||
} catch (error) {
|
||||
console.error('删除失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (!recordForm.value.record_date) {
|
||||
feedback.msgWarning('请选择记录日期')
|
||||
return
|
||||
}
|
||||
|
||||
if (!recordForm.value.exercise_type) {
|
||||
feedback.msgWarning('请选择运动类型')
|
||||
return
|
||||
}
|
||||
|
||||
if (!recordForm.value.duration) {
|
||||
feedback.msgWarning('请输入运动时长')
|
||||
return
|
||||
}
|
||||
|
||||
submitting.value = true
|
||||
try {
|
||||
if (recordForm.value.id) {
|
||||
await exerciseRecordEdit(recordForm.value)
|
||||
feedback.msgSuccess('编辑成功')
|
||||
} else {
|
||||
await exerciseRecordAdd(recordForm.value)
|
||||
feedback.msgSuccess('添加成功')
|
||||
}
|
||||
dialogVisible.value = false
|
||||
getRecords()
|
||||
} catch (error) {
|
||||
console.error('提交失败:', error)
|
||||
} finally {
|
||||
submitting.value = false
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getRecords()
|
||||
})
|
||||
|
||||
watch(() => [props.diagnosisId, props.patientId], () => {
|
||||
getRecords()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.exercise-record-list {
|
||||
padding: 20px;
|
||||
}
|
||||
</style>
|
||||
@@ -513,6 +513,27 @@
|
||||
/>
|
||||
<el-empty v-else description="请先保存诊单后再添加血糖血压记录" />
|
||||
</el-tab-pane>
|
||||
|
||||
<!-- 饮食记录标签页 -->
|
||||
<el-tab-pane label="饮食记录" name="diet" :disabled="!formData.id">
|
||||
<diet-record-list
|
||||
v-if="formData.id"
|
||||
:diagnosis-id="Number(formData.id)"
|
||||
:patient-id="Number(formData.patient_id)"
|
||||
/>
|
||||
<el-empty v-else description="请先保存诊单后再添加饮食记录" />
|
||||
</el-tab-pane>
|
||||
|
||||
<!-- 运动打卡记录标签页 -->
|
||||
<el-tab-pane label="运动打卡记录" name="exercise" :disabled="!formData.id">
|
||||
<exercise-record-list
|
||||
v-if="formData.id"
|
||||
:diagnosis-id="Number(formData.id)"
|
||||
:patient-id="Number(formData.patient_id)"
|
||||
/>
|
||||
<el-empty v-else description="请先保存诊单后再添加运动打卡记录" />
|
||||
</el-tab-pane>
|
||||
|
||||
<!-- 病历记录标签页(开方后自动显示) -->
|
||||
<el-tab-pane label="处方" name="bingli" :disabled="!formData.id" v-if="hasPermission(['tcm.diagnosis/chufang'])">
|
||||
<div v-if="formData.id" class="bingli-tab-content">
|
||||
@@ -650,6 +671,8 @@ import useAppStore from '@/stores/modules/app'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { QuestionFilled } from '@element-plus/icons-vue'
|
||||
import BloodRecordList from './components/BloodRecordList.vue'
|
||||
import DietRecordList from './components/DietRecordList.vue'
|
||||
import ExerciseRecordList from './components/ExerciseRecordList.vue'
|
||||
import CaseRecordList from './components/CaseRecordList.vue'
|
||||
import CallRecordPanel from './components/CallRecordPanel.vue'
|
||||
import ImChatRecordPanel from './components/ImChatRecordPanel.vue'
|
||||
|
||||
Reference in New Issue
Block a user