Merge remote-tracking branch 'origin/develop' into develop
# Conflicts: # openhis-ui-vue3/src/views/clinicmanagement/bargain/component/prescriptionlist.vue
This commit is contained in:
@@ -143,8 +143,8 @@ watch(
|
||||
() => props.adviceQueryParams,
|
||||
(newValue) => {
|
||||
queryParams.value.searchKey = newValue.searchKey;
|
||||
if (newValue.adviceType) {
|
||||
queryParams.value.adviceTypes = [newValue.adviceType].join(',');
|
||||
if (newValue.adviceTypes) {
|
||||
queryParams.value.adviceTypes = [newValue.adviceTypes].join(',');
|
||||
} else {
|
||||
queryParams.value.adviceTypes = '1,2,3';
|
||||
}
|
||||
|
||||
@@ -1003,18 +1003,6 @@ export function deleteInspectionApplication(applyNo) {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成检验申请单号
|
||||
* 规则:LS + YYYYMMDD + 5位流水号(每日从1开始递增)
|
||||
* @returns {Promise} { code: 200, data: { applyNo: string } }
|
||||
*/
|
||||
export function generateInspectionApplyNo() {
|
||||
return request({
|
||||
url: '/doctor-station/inspection/generate-apply-no',
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页获取检验类型列表(分类)
|
||||
* @param {Object} queryParams - 查询参数
|
||||
|
||||
@@ -108,7 +108,7 @@
|
||||
<el-tab-pane label="申请单" name="application">
|
||||
<el-form class="application-form" :model="formData" label-width="auto">
|
||||
<el-form-item label="申请单号" style="margin-bottom: 1px">
|
||||
<el-input v-model="formData.applyNo" readonly size="small" />
|
||||
<el-input v-model="formData.applyNo" disabled size="small" />
|
||||
</el-form-item>
|
||||
|
||||
<!-- 患者信息行 -->
|
||||
@@ -141,14 +141,10 @@
|
||||
<!--申请日期-->
|
||||
<el-col :span="8">
|
||||
<el-form-item label="申请日期" required>
|
||||
<el-date-picker
|
||||
<el-input
|
||||
v-model="formData.applyTime"
|
||||
type="datetime"
|
||||
placeholder="选择日期时间"
|
||||
readonly
|
||||
size="small"
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@@ -539,17 +535,15 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {onMounted, reactive, ref, watch, computed, getCurrentInstance} from 'vue'
|
||||
import {onMounted, onUnmounted, reactive, ref, watch, computed, getCurrentInstance} from 'vue'
|
||||
import {ElMessage, ElMessageBox} from 'element-plus'
|
||||
import { DocumentChecked, Plus, Document, Printer, Delete, Check, Loading } from '@element-plus/icons-vue'
|
||||
import {
|
||||
checkInspectionApplicationNo,
|
||||
deleteInspectionApplication, getApplyList,
|
||||
saveInspectionApplication,
|
||||
getInspectionTypeList,
|
||||
getInspectionItemList,
|
||||
getEncounterDiagnosis,
|
||||
generateInspectionApplyNo,
|
||||
getInspectionApplyDetail
|
||||
} from '../api'
|
||||
import useUserStore from '@/store/modules/user.js'
|
||||
@@ -588,14 +582,16 @@ const loading = ref(false)
|
||||
const saving = ref(false) // 保存状态
|
||||
const total = ref(0)
|
||||
const leftActiveTab = ref('application')
|
||||
const isGeneratingNewApplyNo = ref(false) // 标志:是否正在生成新申请单号
|
||||
|
||||
// 申请日期实时更新定时器
|
||||
let applyTimeTimer = null
|
||||
|
||||
// 用户信息store
|
||||
const userStore = useUserStore()
|
||||
const { id: userId, name: userName, nickName: userNickName } = storeToRefs(userStore)
|
||||
|
||||
// 修改 initData 函数
|
||||
async function initData() {
|
||||
const initData = async () => {
|
||||
// 先初始化患者信息(如果有)
|
||||
if (props.patientInfo && props.patientInfo.encounterId) {
|
||||
queryParams.encounterId = props.patientInfo.encounterId
|
||||
@@ -606,15 +602,16 @@ async function initData() {
|
||||
formData.applyDepartment = props.patientInfo.organizationName || ''
|
||||
formData.applyDocName = userNickName.value || userName.value || ''
|
||||
formData.applyDocCode = userId.value || ''
|
||||
//此处样本数据暂时固定为血液,后续根据实际情况调整
|
||||
formData.specimenName = '血液'
|
||||
formData.applyDeptCode = props.patientInfo.organizationName || ''
|
||||
formData.applyOrganizationId = props.patientInfo.orgId || ''
|
||||
formData.encounterId = props.patientInfo.encounterId
|
||||
|
||||
// 生成申请单号
|
||||
generateApplicationNo().then((newApplyNo) => {
|
||||
formData.applyNo = newApplyNo
|
||||
})
|
||||
// 申请单号在保存时由后端生成,此处显示"自动生成"
|
||||
formData.applyNo = '自动生成'
|
||||
// 申请日期实时更新(启动定时器)
|
||||
startApplyTimeTimer()
|
||||
|
||||
// 获取主诊断信息
|
||||
try {
|
||||
@@ -657,7 +654,7 @@ const formData = reactive({
|
||||
patientName: '',
|
||||
medicalrecordNumber: '',
|
||||
natureofCost: 'self',
|
||||
applyTime: new Date(),
|
||||
applyTime: '', // 初始值设为空字符串,在新增时设置为当前时间
|
||||
applyDepartment: '',
|
||||
applyDocName: '',
|
||||
executeDepartment: '',
|
||||
@@ -728,7 +725,7 @@ const PAGE_SIZE = 50
|
||||
const SEARCH_DEBOUNCE_TIME = 300
|
||||
|
||||
// 加载检验类型分类列表(只加载分类,项目懒加载)
|
||||
async function loadInspectionData() {
|
||||
const loadInspectionData = async () => {
|
||||
// 如果已经加载过分类,直接返回
|
||||
if (inspectionCategories.value.length > 0) {
|
||||
return
|
||||
@@ -776,7 +773,7 @@ async function loadInspectionData() {
|
||||
}
|
||||
|
||||
// 懒加载分类项目(分页)
|
||||
async function loadCategoryItems(categoryKey, loadMore = false) {
|
||||
const loadCategoryItems = async (categoryKey, loadMore = false) => {
|
||||
const category = inspectionCategories.value.find(c => c.key === categoryKey)
|
||||
if (!category) return
|
||||
|
||||
@@ -860,7 +857,7 @@ async function loadCategoryItems(categoryKey, loadMore = false) {
|
||||
}
|
||||
|
||||
// 加载更多项目
|
||||
function loadMoreItems(categoryKey) {
|
||||
const loadMoreItems = (categoryKey) => {
|
||||
const category = inspectionCategories.value.find(c => c.key === categoryKey)
|
||||
if (!category || !category.hasMore || category.loading) return
|
||||
|
||||
@@ -869,7 +866,7 @@ function loadMoreItems(categoryKey) {
|
||||
}
|
||||
|
||||
// 处理滚动事件(无限滚动)
|
||||
function handleScroll({ scrollTop, scrollHeight, clientHeight }) {
|
||||
const handleScroll = ({ scrollTop, scrollHeight, clientHeight }) => {
|
||||
// 距离底部 50px 时触发加载更多
|
||||
if (scrollHeight - scrollTop - clientHeight < 50) {
|
||||
const expandedCategory = inspectionCategories.value.find(c => c.expanded)
|
||||
@@ -916,7 +913,7 @@ const getFilteredItems = (categoryKey) => {
|
||||
}
|
||||
|
||||
// 搜索建议查询(自动完成)
|
||||
async function querySearchInspectionItems(queryString, cb) {
|
||||
const querySearchInspectionItems = async (queryString, cb) => {
|
||||
if (!queryString) {
|
||||
cb([])
|
||||
return
|
||||
@@ -954,7 +951,7 @@ async function querySearchInspectionItems(queryString, cb) {
|
||||
}
|
||||
|
||||
// 搜索选择处理
|
||||
function handleSearchSelect(item) {
|
||||
const handleSearchSelect = (item) => {
|
||||
// 直接添加到已选列表
|
||||
if (!isItemSelected(item)) {
|
||||
selectedInspectionItems.value.push({
|
||||
@@ -967,12 +964,12 @@ function handleSearchSelect(item) {
|
||||
}
|
||||
|
||||
// 搜索框清空处理
|
||||
function handleSearchClear() {
|
||||
const handleSearchClear = () => {
|
||||
searchKeyword.value = ''
|
||||
}
|
||||
|
||||
// 获取检验申请单列表
|
||||
function getInspectionList() {
|
||||
const getInspectionList = () => {
|
||||
// 如果没有encounterId,不调用接口
|
||||
if (!queryParams.encounterId) {
|
||||
return
|
||||
@@ -1024,7 +1021,7 @@ function getInspectionList() {
|
||||
}
|
||||
|
||||
// 合并检验申请单记录:将同一个申请单的多个明细合并成一条记录
|
||||
function mergeInspectionApplyRecords(records) {
|
||||
const mergeInspectionApplyRecords = (records) => {
|
||||
if (!records || records.length === 0) {
|
||||
return []
|
||||
}
|
||||
@@ -1052,7 +1049,7 @@ function mergeInspectionApplyRecords(records) {
|
||||
}
|
||||
|
||||
// 格式化金额:确保显示两位小数
|
||||
function formatAmount(amount) {
|
||||
const formatAmount = (amount) => {
|
||||
if (amount === null || amount === undefined || amount === '') {
|
||||
return '0.00'
|
||||
}
|
||||
@@ -1063,53 +1060,60 @@ function formatAmount(amount) {
|
||||
return num.toFixed(2)
|
||||
}
|
||||
|
||||
// 格式化日期时间为字符串 YYYY-MM-DD HH:mm:ss
|
||||
const formatDateTime = (date) => {
|
||||
if (!date) return ''
|
||||
const d = new Date(date)
|
||||
const year = d.getFullYear()
|
||||
const month = String(d.getMonth() + 1).padStart(2, '0')
|
||||
const day = String(d.getDate()).padStart(2, '0')
|
||||
const hours = String(d.getHours()).padStart(2, '0')
|
||||
const minutes = String(d.getMinutes()).padStart(2, '0')
|
||||
const seconds = String(d.getSeconds()).padStart(2, '0')
|
||||
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
|
||||
}
|
||||
|
||||
// 启动申请日期实时更新定时器
|
||||
const startApplyTimeTimer = () => {
|
||||
// 先清除已存在的定时器
|
||||
stopApplyTimeTimer()
|
||||
// 立即更新一次
|
||||
formData.applyTime = formatDateTime(new Date())
|
||||
// 每秒更新
|
||||
applyTimeTimer = setInterval(() => {
|
||||
formData.applyTime = formatDateTime(new Date())
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
// 停止申请日期实时更新定时器
|
||||
const stopApplyTimeTimer = () => {
|
||||
if (applyTimeTimer) {
|
||||
clearInterval(applyTimeTimer)
|
||||
applyTimeTimer = null
|
||||
}
|
||||
}
|
||||
|
||||
// 新增申请单
|
||||
async function handleNewApplication() {
|
||||
const handleNewApplication = async () => {
|
||||
resetForm()
|
||||
// 生成新的申请单号
|
||||
formData.applyNo = await generateApplicationNo()
|
||||
// 申请单号在保存时由后端生成,此处显示"待生成"
|
||||
formData.applyNo = '自动生成'
|
||||
// 申请日期实时更新(启动定时器)
|
||||
startApplyTimeTimer()
|
||||
// 确保申请医生是当前登录医生
|
||||
formData.applyDocName = userNickName.value || userName.value || ''
|
||||
leftActiveTab.value = 'application'
|
||||
}
|
||||
|
||||
// 查询数据库中是否已存在指定申请单号
|
||||
const checkApplicationNoExists = async (applyNo) => {
|
||||
try {
|
||||
// 这里调用API检查申请单号是否已存在
|
||||
// 注意:你需要根据实际API接口调整此调用
|
||||
const response = await checkInspectionApplicationNo(applyNo);
|
||||
// 后端返回格式:如果存在返回{applyNo: "..."},不存在返回null
|
||||
return response.code === 200 && response.data && response.data.applyNo;
|
||||
} catch (error) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// 调用后端接口生成申请单号(LS + YYYYMMDD + 5位流水号)
|
||||
// 后端使用 Redis 原子递增保证并发安全
|
||||
const generateApplicationNo = async () => {
|
||||
try {
|
||||
const res = await generateInspectionApplyNo();
|
||||
if (res.code === 200 && res.data && res.data.applyNo) {
|
||||
return res.data.applyNo;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} catch (error) {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
// 重置表单
|
||||
async function resetForm() {
|
||||
const resetForm = async () => {
|
||||
Object.assign(formData, {
|
||||
applicationId: null,
|
||||
applyOrganizationId: props.patientInfo.orgId || '',
|
||||
patientName: props.patientInfo.patientName || '',
|
||||
medicalrecordNumber: props.patientInfo.identifierNo || '',
|
||||
natureofCost: 'self',
|
||||
applyTime: new Date(),
|
||||
applyTime: '', // 申请日期由定时器实时更新
|
||||
applyDepartment: props.patientInfo.organizationName || '',
|
||||
applyDeptCode: props.patientInfo.organizationName,
|
||||
applyDocCode: userId.value || '',
|
||||
@@ -1164,9 +1168,10 @@ async function resetForm() {
|
||||
}
|
||||
|
||||
// 保存
|
||||
function handleSave() {
|
||||
// 如果正在保存,直接返回
|
||||
const handleSave = () => {
|
||||
// P1:防重复提交 - 立即设置标志
|
||||
if (saving.value) return
|
||||
saving.value = true
|
||||
|
||||
// 重置验证错误状态
|
||||
Object.keys(validationErrors).forEach(key => {
|
||||
@@ -1175,6 +1180,20 @@ function handleSave() {
|
||||
|
||||
let hasErrors = false
|
||||
|
||||
// P0:检查患者信息是否已加载
|
||||
if (!formData.patientName?.trim() || !formData.medicalrecordNumber?.trim()) {
|
||||
ElMessage.error('患者信息未加载,请稍后重试')
|
||||
saving.value = false
|
||||
return
|
||||
}
|
||||
|
||||
// P0:检查就诊信息是否有效
|
||||
if (!formData.encounterId) {
|
||||
ElMessage.error('就诊信息无效,请重新选择患者')
|
||||
saving.value = false
|
||||
return
|
||||
}
|
||||
|
||||
// 检查必填字段,执行科室
|
||||
if (!formData.executeDepartment) {
|
||||
validationErrors.executeDepartment = true
|
||||
@@ -1205,16 +1224,14 @@ function handleSave() {
|
||||
validationErrors.labApplyItemList = true
|
||||
hasErrors = true
|
||||
ElMessage.error('请至少选择一项检验项目')
|
||||
saving.value = false
|
||||
return
|
||||
}
|
||||
// 检查必填字段,申请日期
|
||||
if(!formData.applyTime || (typeof formData.applyTime === 'string' && !formData.applyTime?.trim())) {
|
||||
validationErrors.applyTime = true
|
||||
hasErrors = true
|
||||
}
|
||||
// 申请日期由后端在保存时自动生成,无需前端校验
|
||||
|
||||
if (hasErrors) {
|
||||
ElMessage.error('请填写所有必填字段')
|
||||
saving.value = false
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1229,87 +1246,36 @@ function handleSave() {
|
||||
...formData,
|
||||
labApplyItemList,
|
||||
physicalExamination: formData.physicalExam, // 字段名映射:前端 physicalExam -> 后端 physicalExamination
|
||||
inspectionItemsText: selectedInspectionItems.value.map(item => item.itemName).join('+'),
|
||||
amount: selectedInspectionItems.value.reduce((sum, item) => sum + item.itemAmount, 0),
|
||||
serviceFee: selectedInspectionItems.value.reduce((sum, item) => sum + (item.serviceFee || 0), 0),
|
||||
totalAmount: selectedInspectionItems.value.reduce((sum, item) => sum + item.itemAmount + (item.serviceFee || 0), 0)
|
||||
inspectionItemsText: selectedInspectionItems.value.map(item => item.itemName).join('+')
|
||||
// 金额由后端计算,前端不传递
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 先检查申请单号是否已存在
|
||||
if (isGeneratingNewApplyNo.value) {
|
||||
// 正在使用新生成的单号,直接保存
|
||||
isGeneratingNewApplyNo.value = false; // 重置标志
|
||||
const saveData = prepareSaveData();
|
||||
executeSave(saveData);
|
||||
return;
|
||||
}
|
||||
|
||||
checkInspectionApplicationNo(formData.applyNo).then((res) => {
|
||||
if (res.code === 200 && res.data) {
|
||||
// res.data有值表示申请单存在
|
||||
// 注意:res.data可能是{applyNo: "..."}或包含其他字段
|
||||
const exists = res.data && (res.data.applyNo || res.data.exists);
|
||||
if (exists) {
|
||||
// 申请单号已存在,提示用户
|
||||
ElMessageBox.confirm(
|
||||
'当前申请单号已重复,将重新为您生成新的申请单号',
|
||||
'提示',
|
||||
{
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
}
|
||||
).then(() => {
|
||||
// 设置标志,表示正在生成新申请单号
|
||||
isGeneratingNewApplyNo.value = true;
|
||||
// 重新生成申请单号
|
||||
generateApplicationNo().then((newApplyNo) => {
|
||||
if (newApplyNo && newApplyNo.trim() !== '') {
|
||||
formData.applyNo = newApplyNo;
|
||||
ElMessage.success('新申请单号已生成,请点击保存按钮继续,请核对数据');
|
||||
// 不自动保存,等待用户再次点击保存
|
||||
} else {
|
||||
isGeneratingNewApplyNo.value = false;
|
||||
}
|
||||
});
|
||||
}).catch((error) => {
|
||||
// 用户点击取消或其他原因导致的拒绝
|
||||
if (error !== 'cancel' && error !== 'close') {
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// 申请单号不存在,继续保存操作
|
||||
const saveData = prepareSaveData();
|
||||
executeSave(saveData);
|
||||
}
|
||||
} else {
|
||||
// 其他情况继续保存
|
||||
const saveData = prepareSaveData();
|
||||
executeSave(saveData);
|
||||
}
|
||||
}).catch(() => {
|
||||
// 如果检查过程出错,仍然继续保存操作,以免影响正常使用
|
||||
const saveData = prepareSaveData();
|
||||
executeSave(saveData);
|
||||
})
|
||||
// 申请单号由后端在保存时生成,直接保存
|
||||
const saveData = prepareSaveData();
|
||||
executeSave(saveData);
|
||||
|
||||
}
|
||||
const executeSave = (saveData) => {
|
||||
saving.value = true
|
||||
saveInspectionApplication(saveData).then((res) => {
|
||||
if (res.code === 200) {
|
||||
ElMessage.success('保存成功')
|
||||
// 停止申请日期实时更新
|
||||
stopApplyTimeTimer()
|
||||
// 从后端返回获取生成的申请单号
|
||||
if (res.data && res.data.applyNo) {
|
||||
ElMessage.info(`申请单号:${res.data.applyNo}`)
|
||||
// 显示后端返回的实际申请时间
|
||||
if (res.data.applyTime) {
|
||||
formData.applyTime = res.data.applyTime
|
||||
}
|
||||
}
|
||||
emit('save', res.data) // 通知父组件保存成功
|
||||
resetForm()
|
||||
// 生成新的申请单号
|
||||
generateApplicationNo().then((newApplyNo) => {
|
||||
if (newApplyNo && newApplyNo.trim() !== '') {
|
||||
formData.applyNo = newApplyNo;
|
||||
} else {
|
||||
}
|
||||
});
|
||||
// 设置下一个新单为"待生成"
|
||||
formData.applyNo = '自动生成'
|
||||
// 启动新的申请日期实时更新
|
||||
startApplyTimeTimer()
|
||||
leftActiveTab.value = 'application'
|
||||
// 刷新列表
|
||||
getInspectionList()
|
||||
@@ -1331,7 +1297,9 @@ const executeSave = (saveData) => {
|
||||
|
||||
|
||||
// 查看详情
|
||||
function handleView(row) {
|
||||
const handleView = (row) => {
|
||||
// 停止申请日期实时更新(查看已保存的申请单)
|
||||
stopApplyTimeTimer()
|
||||
// 加载表单数据
|
||||
Object.assign(formData, row)
|
||||
|
||||
@@ -1350,7 +1318,7 @@ function handleView(row) {
|
||||
}
|
||||
|
||||
// 切换分类(修改为懒加载)
|
||||
function switchCategory(category) {
|
||||
const switchCategory = (category) => {
|
||||
if (activeCategory.value === category) {
|
||||
// 如果点击的是当前激活的分类,则收起
|
||||
activeCategory.value = ''
|
||||
@@ -1365,7 +1333,7 @@ function switchCategory(category) {
|
||||
inspectionCategories.value.forEach(cat => {
|
||||
cat.expanded = cat.key === category
|
||||
})
|
||||
|
||||
|
||||
// 懒加载该分类的项目
|
||||
const targetCategory = inspectionCategories.value.find(c => c.key === category)
|
||||
if (targetCategory && !targetCategory.loaded) {
|
||||
@@ -1375,17 +1343,17 @@ function switchCategory(category) {
|
||||
}
|
||||
|
||||
// 处理项目项点击(排除勾选框点击)
|
||||
function handleItemClick(item) {
|
||||
const handleItemClick = (item) => {
|
||||
toggleInspectionItem(item)
|
||||
}
|
||||
|
||||
// 判断项目是否已选择
|
||||
function isItemSelected(item) {
|
||||
const isItemSelected = (item) => {
|
||||
return selectedInspectionItems.value.some(selected => selected.itemId === item.itemId)
|
||||
}
|
||||
|
||||
// 切换检验项目选择
|
||||
function toggleInspectionItem(item) {
|
||||
const toggleInspectionItem = (item) => {
|
||||
const index = selectedInspectionItems.value.findIndex(selected => selected.itemId === item.itemId)
|
||||
if (index > -1) {
|
||||
selectedInspectionItems.value.splice(index, 1)
|
||||
@@ -1400,7 +1368,7 @@ function toggleInspectionItem(item) {
|
||||
}
|
||||
|
||||
// 移除检验项目
|
||||
function removeInspectionItem(item) {
|
||||
const removeInspectionItem = (item) => {
|
||||
const index = selectedInspectionItems.value.findIndex(selected => selected.itemId === item.itemId)
|
||||
if (index > -1) {
|
||||
selectedInspectionItems.value.splice(index, 1)
|
||||
@@ -1408,27 +1376,27 @@ function removeInspectionItem(item) {
|
||||
}
|
||||
|
||||
// 清空所有选择
|
||||
function clearAllSelected() {
|
||||
const clearAllSelected = () => {
|
||||
selectedInspectionItems.value = []
|
||||
}
|
||||
|
||||
// 分页大小改变
|
||||
function handleSizeChange(size) {
|
||||
const handleSizeChange = (size) => {
|
||||
queryParams.pageSize = size
|
||||
getInspectionList()
|
||||
}
|
||||
|
||||
function handleCurrentChange(page) {
|
||||
const handleCurrentChange = (page) => {
|
||||
queryParams.pageNo = page
|
||||
getInspectionList()
|
||||
}
|
||||
|
||||
// 选择框变化
|
||||
function handleSelectionChange(selection) {
|
||||
const handleSelectionChange = (selection) => {
|
||||
selectedRows.value = selection
|
||||
}
|
||||
|
||||
function handlePrint(row) {
|
||||
const handlePrint = (row) => {
|
||||
// 切换到申请单TAB
|
||||
leftActiveTab.value = 'application'
|
||||
|
||||
@@ -1449,7 +1417,7 @@ function handlePrint(row) {
|
||||
}
|
||||
|
||||
// 删除申请单
|
||||
function handleDelete(row) {
|
||||
const handleDelete = (row) => {
|
||||
ElMessageBox.confirm(
|
||||
`确定要删除申请单 "${row.applyNo}" 吗?此操作将同时删除对应的医嘱。`,
|
||||
'删除确认',
|
||||
@@ -1480,7 +1448,7 @@ function handleDelete(row) {
|
||||
}
|
||||
|
||||
// 单元格点击 - 点击表格行时加载申请单详情
|
||||
function handleCellClick(row, column) {
|
||||
const handleCellClick = (row, column) => {
|
||||
// 点击表格行时,将该申请单的数据加载到表单中
|
||||
// 使用 applyNo 判断是否有效
|
||||
if (row && row.applyNo) {
|
||||
@@ -1489,7 +1457,7 @@ function handleCellClick(row, column) {
|
||||
}
|
||||
|
||||
// 行点击事件处理
|
||||
function handleRowClick(currentRow, oldRow) {
|
||||
const handleRowClick = (currentRow, oldRow) => {
|
||||
// 点击表格行时,将该申请单的数据加载到表单中
|
||||
// 使用 applyNo 判断是否有效
|
||||
if (currentRow && currentRow.applyNo) {
|
||||
@@ -1498,7 +1466,9 @@ function handleRowClick(currentRow, oldRow) {
|
||||
}
|
||||
|
||||
// 提取公共方法加载申请单到表单
|
||||
async function loadApplicationToForm(row) {
|
||||
const loadApplicationToForm = async (row) => {
|
||||
// 停止申请日期实时更新(加载已保存的申请单)
|
||||
stopApplyTimeTimer()
|
||||
// 切换到申请单 TAB
|
||||
leftActiveTab.value = 'application'
|
||||
|
||||
@@ -1640,6 +1610,11 @@ onMounted(async () => {
|
||||
await loadInspectionData()
|
||||
})
|
||||
|
||||
// 组件卸载时清除定时器
|
||||
onUnmounted(() => {
|
||||
stopApplyTimeTimer()
|
||||
})
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
getList: getInspectionList
|
||||
|
||||
@@ -191,12 +191,18 @@
|
||||
<template v-if="scope.row.adviceType == 1">
|
||||
<div style="display: flex; align-items: center; margin-bottom: 16px; gap: 16px">
|
||||
<span class="medicine-title">
|
||||
{{ scope.row.adviceName }} {{ scope.row.volume }}
|
||||
<template v-if="scope.row.partPercent !== null && scope.row.partPercent !== undefined && scope.row.partPercent - 1 > 0">
|
||||
[1{{ scope.row.unitCode_dictText }}={{ scope.row.partPercent }}{{ scope.row.minUnitCode_dictText }}]
|
||||
</template>
|
||||
[{{ (scope.row.unitPrice !== undefined && scope.row.unitPrice !== null && !isNaN(scope.row.unitPrice) &&
|
||||
isFinite(scope.row.unitPrice)) ? Number(scope.row.unitPrice).toFixed(2) : '-' }} 元/{{ scope.row.unitCode_dictText }}]
|
||||
{{
|
||||
scope.row.adviceName +
|
||||
' ' +
|
||||
scope.row.volume +
|
||||
' [' +
|
||||
(scope.row.unitPrice !== undefined && scope.row.unitPrice !== null && !isNaN(scope.row.unitPrice) &&
|
||||
isFinite(scope.row.unitPrice) ? Number(scope.row.unitPrice).toFixed(2) : '-') +
|
||||
' 元' +
|
||||
'/' +
|
||||
scope.row.unitCode_dictText +
|
||||
']'
|
||||
}}
|
||||
</span>
|
||||
<el-form-item prop="lotNumber" label="药房:">
|
||||
<el-select v-model="scope.row.inventoryId" style="width: 330px; margin-right: 20px"
|
||||
@@ -261,7 +267,6 @@
|
||||
<div class="form-group">
|
||||
<el-form-item label="给药途径:" prop="methodCode" class="required-field" data-prop="methodCode">
|
||||
<el-select v-model="scope.row.methodCode" placeholder="给药途径" clearable filterable
|
||||
style="width: 150px"
|
||||
:ref="(el) => (inputRefs.methodCode = el)" @keyup.enter.prevent="
|
||||
() => {
|
||||
if (scope.row.methodCode) {
|
||||
@@ -284,9 +289,7 @@
|
||||
}
|
||||
// inputRefs.rateCode.blur();
|
||||
}
|
||||
"
|
||||
@change="calculateTotalAmount(scope.row, scope.$index)"
|
||||
:ref="(el) => (inputRefs.rateCode = el)">
|
||||
" :ref="(el) => (inputRefs.rateCode = el)">
|
||||
<el-option v-for="dict in rate_code" @click="() => (scope.row.rateCode_dictText = dict.label)"
|
||||
:key="dict.value" :label="dict.label" :value="dict.value" />
|
||||
</el-select>
|
||||
@@ -307,10 +310,7 @@
|
||||
controls-position="right" :controls="false" :ref="(el) => (inputRefs.dispensePerDuration = el)"
|
||||
@keyup.enter.prevent="
|
||||
handleEnter('dispensePerDuration', scope.row, scope.$index)
|
||||
"
|
||||
@change="calculateTotalAmount(scope.row, scope.$index)"
|
||||
@blur="calculateTotalAmount(scope.row, scope.$index)"
|
||||
@input="calculateTotalAmount(scope.row, scope.$index)">
|
||||
">
|
||||
<template #suffix>天</template>
|
||||
</el-input-number>
|
||||
</el-form-item>
|
||||
@@ -321,8 +321,8 @@
|
||||
@keyup.enter.prevent="handleEnter('quantity', scope.row, scope.$index)"
|
||||
@input="calculateTotalPrice(scope.row, scope.$index)" />
|
||||
</el-form-item>
|
||||
<el-form-item style="margin-left: -10px;">
|
||||
<el-select v-model="scope.row.unitCode" style="width: 70px; margin-right: 10px" placeholder=" "
|
||||
<el-form-item>
|
||||
<el-select v-model="scope.row.unitCode" style="width: 70px; margin-right: 20px" placeholder=" "
|
||||
@change="calculateTotalAmount(scope.row, scope.$index)">
|
||||
<template v-for="item in scope.row.unitCodeList" :key="item.value">
|
||||
<el-option v-if="checkUnit(item, scope.row)" :value="item.value" :label="item.label" @click="
|
||||
@@ -342,13 +342,7 @@
|
||||
" />
|
||||
</template>
|
||||
</el-select>
|
||||
<span v-if="scope.row.unitCode_dictText" class="unit-text">{{ scope.row.unitCode_dictText }}</span>
|
||||
</el-form-item>
|
||||
<!-- 🔧 Bug #273 拆零比提示 -->
|
||||
<span v-if="scope.row.partPercent !== null && scope.row.partPercent !== undefined && scope.row.partPercent - 1 > 0 && scope.row.unitCode !== scope.row.minUnitCode"
|
||||
class="part-percent-hint">
|
||||
{{ scope.row.partPercent }}<template v-if="scope.row.minUnitCode_dictText">{{ scope.row.minUnitCode_dictText }}</template><template v-else>袋</template>/<template v-if="scope.row.unitCode_dictText">{{ scope.row.unitCode_dictText }}</template><template v-else>盒</template>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div style="
|
||||
@@ -687,6 +681,7 @@
|
||||
style="width: 60px"
|
||||
size="small"
|
||||
@change="calculateTotalPrice(scope.row, scope.$index)"
|
||||
@input="calculateTotalPrice(scope.row, scope.$index)"
|
||||
/>
|
||||
<span style="margin-left: 4px">{{ scope.row.unitCode_dictText }}</span>
|
||||
</template>
|
||||
@@ -734,7 +729,7 @@
|
||||
size="small"
|
||||
/>
|
||||
<span style="margin: 0 2px; font-size: 12px;">天</span>
|
||||
<el-select v-model="scope.row.methodCode" size="small" style="width: 120px" placeholder="用法">
|
||||
<el-select v-model="scope.row.methodCode" size="small" style="width: 65px" placeholder="用法">
|
||||
<el-option v-for="item in method_code" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</template>
|
||||
@@ -1580,11 +1575,6 @@ function getListInfo(addNewRow) {
|
||||
console.log('BugFix#219: 过滤掉已作废的会诊医嘱, requestId=', item.requestId);
|
||||
return false;
|
||||
}
|
||||
// 🔧 Bug Fix: 过滤掉项目名称为空的无效医嘱
|
||||
if (!item.adviceName || item.adviceName.trim() === '') {
|
||||
console.log('BugFix: 过滤掉空白医嘱, requestId=', item.requestId, 'adviceType=', item.adviceType);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
@@ -2028,7 +2018,6 @@ function handleDelete() {
|
||||
adviceType: item.adviceType,
|
||||
statusEnum: item.statusEnum,
|
||||
requestId: item.requestId,
|
||||
adviceName: item.adviceName
|
||||
})));
|
||||
|
||||
// 🔧 BugFix: 放宽条件,只要有requestId的会诊医嘱都可以尝试删除
|
||||
@@ -2133,18 +2122,13 @@ function handleDelete() {
|
||||
adviceType: item.adviceType,
|
||||
statusEnum: item.statusEnum,
|
||||
requestId: item.requestId,
|
||||
adviceName: item.adviceName,
|
||||
uniqueKey: item.uniqueKey
|
||||
})));
|
||||
|
||||
console.log('BugFix#219: prescriptionList 中的所有医嘱=', prescriptionList.value.map(item => ({
|
||||
adviceType: item.adviceType,
|
||||
statusEnum: item.statusEnum,
|
||||
adviceName: item.adviceName,
|
||||
uniqueKey: item.uniqueKey,
|
||||
totalPrice: item.totalPrice,
|
||||
dose: item.dose,
|
||||
doseQuantity: item.doseQuantity
|
||||
uniqueKey: item.uniqueKey
|
||||
})));
|
||||
|
||||
for (let i = prescriptionList.value.length - 1; i >= 0; i--) {
|
||||
@@ -2333,10 +2317,14 @@ function handleSave(prescriptionId) {
|
||||
|
||||
// 签发核心逻辑
|
||||
function executeSaveLogic() {
|
||||
// 🔧 Bug Fix: 获取当前选中的费用性质,保持字符串类型避免大整数精度丢失
|
||||
// 🔧 Bug Fix: 获取当前选中的费用性质,如果是'ZIFEI'或0则转为null,让后端查询默认账户
|
||||
let finalAccountId = accountId.value;
|
||||
if (finalAccountId === 'ZIFEI' || finalAccountId === 0) {
|
||||
finalAccountId = null;
|
||||
} else if (finalAccountId && !isNaN(Number(finalAccountId))) {
|
||||
finalAccountId = Number(finalAccountId);
|
||||
} else {
|
||||
finalAccountId = null;
|
||||
}
|
||||
|
||||
// 🔧 Bug Fix: 校验患者信息完整性
|
||||
@@ -2349,7 +2337,11 @@ function handleSave(prescriptionId) {
|
||||
saveList.forEach((item) => {
|
||||
item.patientId = props.patientInfo.patientId;
|
||||
item.encounterId = props.patientInfo.encounterId;
|
||||
item.accountId = finalAccountId;
|
||||
// 🔧 使用项目自己的 accountId,而不是全局的 finalAccountId
|
||||
// 这样自动带出的耗材才能保持与药品相同的账户
|
||||
if (!item.accountId) {
|
||||
item.accountId = finalAccountId;
|
||||
}
|
||||
item.dbOpType = '1';
|
||||
});
|
||||
|
||||
@@ -2359,7 +2351,7 @@ function handleSave(prescriptionId) {
|
||||
// 先解析contentJson
|
||||
let parsedContent = JSON.parse(item.contentJson || '{}');
|
||||
// 🔧 Bug Fix: 强制将accountId设为正确的值
|
||||
parsedContent.accountId = finalAccountId;
|
||||
parsedContent.accountId = item.accountId || finalAccountId; // 🔧 使用 item 自己的 accountId
|
||||
|
||||
// --- 【修改点2:Bug 2 修复 (单位换算)】 ---
|
||||
let finalQuantity = item.quantity;
|
||||
@@ -2426,7 +2418,6 @@ function handleSave(prescriptionId) {
|
||||
}
|
||||
|
||||
console.log('保存医嘱参数:', {
|
||||
adviceName: item.adviceName,
|
||||
adviceType: item.adviceType,
|
||||
saveAdviceType: saveAdviceType,
|
||||
adviceTableName: adviceTableNameVal,
|
||||
@@ -2452,15 +2443,28 @@ function handleSave(prescriptionId) {
|
||||
adviceTableName: adviceTableNameVal,
|
||||
locationId: locationIdVal,
|
||||
// 🔧 确保 methodCode 被传递(用于触发耗材绑定逻辑)
|
||||
methodCode: item.methodCode || parsedContent.methodCode
|
||||
methodCode: item.methodCode || parsedContent.methodCode,
|
||||
// 🔧 确保 accountId 被传递(用于预结算)
|
||||
accountId: item.accountId || parsedContent.accountId,
|
||||
// 🔧 更新 contentJson 中的 adviceType,确保后端分类正确
|
||||
contentJson: JSON.stringify({
|
||||
...parsedContent,
|
||||
adviceType: saveAdviceType
|
||||
})
|
||||
};
|
||||
});
|
||||
|
||||
// 提交签发请求
|
||||
isSaving.value = true;
|
||||
console.log('签发处方参数:', {
|
||||
organizationId: props.patientInfo.orgId,
|
||||
adviceSaveList: list,
|
||||
console.log('organizationId:', props.patientInfo.orgId);
|
||||
console.log('adviceSaveList:', list);
|
||||
list.forEach((item, idx) => {
|
||||
console.log(`项目${idx + 1}:`, {
|
||||
adviceName: item.adviceName,
|
||||
adviceType: item.adviceType,
|
||||
accountId: item.accountId,
|
||||
methodCode: item.methodCode
|
||||
});
|
||||
});
|
||||
|
||||
savePrescriptionSign({
|
||||
@@ -2613,7 +2617,8 @@ function handleOrderBindInfo(bindIdInfo, currentMethodCode) {
|
||||
uniqueKey: nextId.value++,
|
||||
patientId: props.patientInfo.patientId,
|
||||
encounterId: props.patientInfo.encounterId,
|
||||
accountId: accountId.value,
|
||||
accountId: accountId.value, // 🔧 使用当前全局的 accountId
|
||||
requestId: undefined, // 🔧 耗材的 requestId 设为 undefined,让后端自动生成
|
||||
quantity: item.quantity,
|
||||
methodCode: item.methodCode, // 🔧 现在 item.methodCode 有值了
|
||||
rateCode: item.rateCode,
|
||||
@@ -2624,7 +2629,7 @@ function handleOrderBindInfo(bindIdInfo, currentMethodCode) {
|
||||
unitCode: item.unitCode,
|
||||
unitCode_dictText: item.unitCodeName || '',
|
||||
statusEnum: 1,
|
||||
dbOpType: prescriptionList.value[rowIndex.value].requestId ? '2' : '1',
|
||||
dbOpType: '1', // 🔧 新耗材总是 INSERT
|
||||
conditionId: conditionId.value,
|
||||
conditionDefinitionId: conditionDefinitionId.value,
|
||||
encounterDiagnosisId: encounterDiagnosisId.value,
|
||||
@@ -2902,10 +2907,11 @@ function handleSaveBatch(prescriptionId) {
|
||||
}
|
||||
|
||||
// 🔧 Bug Fix: 在保存时才转换 accountId
|
||||
// 保持为字符串类型,避免 JavaScript 大整数精度丢失问题
|
||||
let finalAccountId = accountId.value;
|
||||
if (finalAccountId === 'ZIFEI' || finalAccountId === 0) {
|
||||
if (finalAccountId === 'ZIFEI') {
|
||||
finalAccountId = null;
|
||||
} else if (finalAccountId && !isNaN(Number(finalAccountId))) {
|
||||
finalAccountId = Number(finalAccountId);
|
||||
}
|
||||
|
||||
// 更新到处方对象
|
||||
@@ -3006,10 +3012,12 @@ function handleSaveBatch(prescriptionId) {
|
||||
};
|
||||
const contentJson = JSON.stringify(itemToSave);
|
||||
|
||||
// 🔧 Bug Fix: 处理accountId,保持字符串类型避免大整数精度丢失
|
||||
// 🔧 Bug Fix: 处理accountId,如果是'ZIFEI'或0则转为null,让后端查询默认账户
|
||||
let itemAccountId = finalAccountId;
|
||||
if (itemAccountId === 'ZIFEI' || itemAccountId === 0) {
|
||||
itemAccountId = null;
|
||||
} else if (itemAccountId && !isNaN(Number(itemAccountId))) {
|
||||
itemAccountId = Number(itemAccountId);
|
||||
}
|
||||
|
||||
// 🔧 Bug Fix: 确保库存匹配成功的关键字段
|
||||
@@ -3183,12 +3191,6 @@ function syncGroupFields(row) {
|
||||
}
|
||||
|
||||
function setValue(row) {
|
||||
// 🔧 Bug Fix: 强制设置耗材类型,确保 adviceType 为 4
|
||||
// 如果 adviceTableName 是 adm_device_definition,强制设为耗材类型
|
||||
if (row.adviceTableName === 'adm_device_definition') {
|
||||
row.adviceType = 4;
|
||||
}
|
||||
|
||||
unitCodeList.value = [];
|
||||
unitCodeList.value.push({ value: row.unitCode, label: row.unitCode_dictText, type: 'unit' });
|
||||
unitCodeList.value.push({
|
||||
@@ -3561,7 +3563,6 @@ function handleSingOut() {
|
||||
let selectRows = prescriptionRef.value.getSelectionRows();
|
||||
console.log('BugFix#219: handleSingOut called, selectRows=', selectRows);
|
||||
console.log('BugFix#219: 选中行详情:', selectRows.map(item => ({
|
||||
adviceName: item.adviceName,
|
||||
adviceType: item.adviceType,
|
||||
statusEnum: item.statusEnum,
|
||||
statusEnumType: typeof item.statusEnum,
|
||||
@@ -3579,7 +3580,6 @@ function handleSingOut() {
|
||||
|
||||
console.log('BugFix#219: consultationRows=', consultationRows.length, 'normalRows=', normalRows.length);
|
||||
console.log('BugFix#219: normalRows详情:', normalRows.map(item => ({
|
||||
adviceName: item.adviceName,
|
||||
statusEnum: item.statusEnum,
|
||||
statusEnumType: typeof item.statusEnum,
|
||||
requestId: item.requestId
|
||||
@@ -3592,7 +3592,6 @@ function handleSingOut() {
|
||||
adviceType: item.adviceType,
|
||||
statusEnum: item.statusEnum,
|
||||
requestId: item.requestId,
|
||||
adviceName: item.adviceName
|
||||
})));
|
||||
|
||||
// 🔧 BugFix: 放宽条件,只要有requestId的会诊医嘱都可以处理
|
||||
@@ -3695,7 +3694,6 @@ function handleSingOut() {
|
||||
adviceType: item.adviceType,
|
||||
statusEnum: item.statusEnum,
|
||||
requestId: item.requestId,
|
||||
adviceName: item.adviceName
|
||||
})));
|
||||
|
||||
// 🔧 BugFix: 将requestId转换为数字类型
|
||||
@@ -3935,9 +3933,8 @@ function convertValues(row, index) {
|
||||
row.dose = row.doseQuantity / row.partPercent;
|
||||
break;
|
||||
}
|
||||
// 🔧 Bug #273 修复:单次剂量变化后重新计算总量
|
||||
calculateTotalAmount(row, index);
|
||||
});
|
||||
// calculateTotalAmount(row, index);
|
||||
}
|
||||
|
||||
// 单次剂量数量改变时自动计算总量
|
||||
@@ -3963,106 +3960,25 @@ function convertDoseValues(row, index) {
|
||||
row.doseQuantity = row.dose * row.partPercent;
|
||||
break;
|
||||
}
|
||||
// 🔧 Bug #273 修复:单次剂量变化后重新计算总量
|
||||
calculateTotalAmount(row, index);
|
||||
});
|
||||
// calculateTotalAmount(row, index);
|
||||
}
|
||||
|
||||
// 总量计算,仅适用只有两种单位的情况
|
||||
function calculateTotalAmount(row, index) {
|
||||
nextTick(() => {
|
||||
// 🔧 Bug #273 调试日志
|
||||
console.log('[calculateTotalAmount] 开始计算', {
|
||||
adviceType: row.adviceType,
|
||||
rateCode: row.rateCode,
|
||||
dispensePerDuration: row.dispensePerDuration,
|
||||
doseQuantity: row.doseQuantity,
|
||||
partAttributeEnum: row.partAttributeEnum,
|
||||
unitCode: row.unitCode,
|
||||
minUnitCode: row.minUnitCode
|
||||
});
|
||||
|
||||
// 项目为西药或中成药时
|
||||
if (row.adviceType != 1 && row.adviceType != 2) {
|
||||
console.log('[calculateTotalAmount] 非西药/中成药,跳过计算');
|
||||
if (row.adviceType == 2) {
|
||||
calculateTotalPrice(row, index);
|
||||
return;
|
||||
}
|
||||
|
||||
// 🔧 Bug #273 修复:使用字典数据计算频次对应的每日次数
|
||||
function getRateCount(rateCode) {
|
||||
// 先从字典中查找
|
||||
const rateDict = rate_code.value?.find(item => item.value === rateCode);
|
||||
if (rateDict && rateDict.remark) {
|
||||
return Number(rateDict.remark);
|
||||
}
|
||||
// 回退到固定映射
|
||||
const frequencyMap = {
|
||||
ST: 1, QD: 1, BID: 2, TID: 3, QID: 4, QN: 1,
|
||||
QOD: 0.5, QW: 1/7, BIW: 2/7, TIW: 3/7, QOW: 1/14
|
||||
};
|
||||
return frequencyMap[rateCode] || 1;
|
||||
}
|
||||
|
||||
// 情况1: 根据用药天数和频次计算
|
||||
if (row.rateCode && row.dispensePerDuration) {
|
||||
const rateCount = getRateCount(row.rateCode);
|
||||
const count = rateCount * row.dispensePerDuration;
|
||||
console.log('[calculateTotalAmount] 计算count:', { rateCount, days: row.dispensePerDuration, count });
|
||||
if (!count) return;
|
||||
|
||||
let quantity;
|
||||
if (row.unitCode == row.minUnitCode) {
|
||||
// 🔧 使用最小单位时,计算的是最小单位数量(如袋数)
|
||||
quantity = calculateQuantityBySplitType(row.partAttributeEnum, row.doseQuantity, count, row.partPercent);
|
||||
row.quantity = quantity;
|
||||
row.totalPrice = (quantity * row.minUnitPrice).toFixed(2);
|
||||
console.log('[calculateTotalAmount] 计算结果(最小单位):', { quantity, totalPrice: row.totalPrice, partPercent: row.partPercent });
|
||||
} else {
|
||||
// 🔧 使用包装单位时,计算的是包装单位数量(如盒数)
|
||||
quantity = calculateQuantity(
|
||||
row.partAttributeEnum,
|
||||
row.doseQuantity,
|
||||
count,
|
||||
row.partPercent
|
||||
);
|
||||
row.quantity = quantity;
|
||||
row.totalPrice = (quantity * row.unitPrice).toFixed(2);
|
||||
console.log('[calculateTotalAmount] 计算结果(包装单位):', { quantity, totalPrice: row.totalPrice, partPercent: row.partPercent });
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('[calculateTotalAmount] 条件不满足,未计算(rateCode或dispensePerDuration为空)');
|
||||
});
|
||||
}
|
||||
|
||||
// 总量计算,仅适用只有两种单位的情况
|
||||
function calculateTotalAmount2(row, index) {
|
||||
nextTick(() => {
|
||||
// 项目为西药或中成药时
|
||||
if (row.adviceType != 1 && row.adviceType != 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 🔧 Bug #273 修复:使用字典数据计算频次对应的每日次数
|
||||
function getRateCount(rateCode) {
|
||||
// 先从字典中查找
|
||||
const rateDict = rate_code.value?.find(item => item.value === rateCode);
|
||||
if (rateDict && rateDict.remark) {
|
||||
return Number(rateDict.remark);
|
||||
}
|
||||
// 回退到固定映射
|
||||
const frequencyMap = {
|
||||
ST: 1, QD: 1, BID: 2, TID: 3, QID: 4, QN: 1,
|
||||
QOD: 0.5, QW: 1/7, BIW: 2/7, TIW: 3/7, QOW: 1/14
|
||||
};
|
||||
return frequencyMap[rateCode] || 1;
|
||||
}
|
||||
|
||||
// 情况1: 根据用药天数和频次计算
|
||||
if (row.rateCode && row.dispensePerDuration) {
|
||||
const rateCount = getRateCount(row.rateCode);
|
||||
const count = rateCount * row.dispensePerDuration;
|
||||
const count = calculateQuantityByDays(row.rateCode, row.dispensePerDuration);
|
||||
if (!count) return;
|
||||
|
||||
let quantity;
|
||||
@@ -4082,62 +3998,100 @@ function calculateTotalAmount2(row, index) {
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 情况2: 中成药兼容旧逻辑
|
||||
if (row.adviceType == 2) {
|
||||
if (row.partPercent == 1) {
|
||||
row.totalPrice = (row.quantity * row.unitPrice).toFixed(6);
|
||||
} else {
|
||||
// 拆零比不为1时, 如果当前总量单位是大单位,总价等于数量乘以大单位价格 否则总价等于数量乘以小单位价格
|
||||
if (row.unitCodeList.find((k) => k.value == row.unitCode).type == 'unit') {
|
||||
row.totalPrice = (row.quantity * row.unitPrice).toFixed(6);
|
||||
} else {
|
||||
row.totalPrice = (row.quantity * row.minUnitPrice).toFixed(6);
|
||||
}
|
||||
}
|
||||
} else if (row.adviceType == 1) {
|
||||
if (row.rateCode && row.dispensePerDuration) {
|
||||
// 根据用药天数和用药频次计算数量,医生按顺序填的情况
|
||||
let count = calculateQuantityByDays(row.rateCode, row.dispensePerDuration);
|
||||
if (count) {
|
||||
let quantity;
|
||||
if (row.unitCode == row.minUnitCode) {
|
||||
quantity = calculateQuantityBySplitType(row.partAttributeEnum, row.doseQuantity, count);
|
||||
prescriptionList.value[index].quantity = quantity;
|
||||
prescriptionList.value[index].totalPrice = (quantity * row.minUnitPrice).toFixed(6);
|
||||
} else {
|
||||
quantity = calculateQuantity(
|
||||
row.partAttributeEnum,
|
||||
row.doseQuantity,
|
||||
count,
|
||||
row.partPercent
|
||||
);
|
||||
prescriptionList.value[index].quantity = quantity;
|
||||
prescriptionList.value[index].totalPrice = (quantity * row.unitPrice).toFixed(6);
|
||||
}
|
||||
}
|
||||
} else if (row.quantity) {
|
||||
// 如果医生开药先填总量 直接计算总价格
|
||||
if (row.unitCode == row.minUnitCode) {
|
||||
prescriptionList.value[index].totalPrice = (row.quantity * row.minUnitPrice).toFixed(6);
|
||||
} else {
|
||||
prescriptionList.value[index].totalPrice = (row.quantity * row.unitPrice).toFixed(6);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 情况3: 医生先填总量
|
||||
if (row.quantity) {
|
||||
if (row.unitCode == row.minUnitCode) {
|
||||
prescriptionList.value[index].totalPrice = (row.quantity * row.minUnitPrice).toFixed(6);
|
||||
} else {
|
||||
prescriptionList.value[index].totalPrice = (row.quantity * row.unitPrice).toFixed(6);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据门诊拆分类型计算总药量 - 最小单位
|
||||
* 🔧 Bug #273 修复:统一使用拆零比计算
|
||||
* 根据门诊拆分类型计算总药量
|
||||
*
|
||||
* @param type 门诊拆分类型
|
||||
* @param dose 单次剂量 最小单位
|
||||
* @param count 用药频次和用药天数计算出的总数
|
||||
* @param partPercent 拆零比
|
||||
*/
|
||||
function calculateQuantityBySplitType(type, dose, count, partPercent) {
|
||||
// 先计算最小单位总量
|
||||
const minUnitTotal = dose * count;
|
||||
|
||||
function calculateQuantityBySplitType(type, dose, count) {
|
||||
switch (type) {
|
||||
case 1: // 门诊按最小单位每次量向上取整
|
||||
// 每次用量向上取整,然后计算总量
|
||||
return Math.ceil(Math.ceil(dose) * count / partPercent);
|
||||
return Math.ceil(dose) * count;
|
||||
case 2: // 门诊按包装单位不可拆分
|
||||
// 总量向上取整到包装单位
|
||||
return Math.ceil(minUnitTotal / partPercent);
|
||||
return Math.ceil(dose * count);
|
||||
case 3: // 门诊按最小单位总量向上取整
|
||||
// 总量向上取整,然后转换为包装单位
|
||||
return Math.ceil(minUnitTotal / partPercent);
|
||||
return Math.ceil(dose * count);
|
||||
case 4: // 门诊按包装单位每次量向上取整
|
||||
// 每次用量转换为包装单位后向上取整
|
||||
return Math.ceil(Math.ceil(dose / partPercent) * count);
|
||||
return Math.ceil(dose) * count;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据门诊拆分类型计算总药量 - 包装单位
|
||||
* 🔧 Bug #273 修复:统一使用拆零比计算
|
||||
* 根据门诊拆分类型计算总药量
|
||||
*
|
||||
* @param type 门诊拆分类型
|
||||
* @param dose 单次剂量 最小单位
|
||||
* @param count 用药频次和用药天数计算出的总数
|
||||
* @param partPercent 拆零比
|
||||
*/
|
||||
function calculateQuantity(type, dose, count, partPercent) {
|
||||
// 先计算最小单位总量
|
||||
const minUnitTotal = dose * count;
|
||||
|
||||
switch (type) {
|
||||
case 1: // 门诊按最小单位每次量向上取整
|
||||
// 每次用量向上取整,然后计算总量
|
||||
return Math.ceil(Math.ceil(dose) * count / partPercent);
|
||||
return Math.ceil(dose / partPercent) * count;
|
||||
case 2: // 门诊按包装单位不可拆分
|
||||
// 总量向上取整到包装单位
|
||||
return Math.ceil(minUnitTotal / partPercent);
|
||||
return Math.ceil(dose * count);
|
||||
case 3: // 门诊按最小单位总量向上取整
|
||||
// 总量向上取整,然后转换为包装单位
|
||||
return Math.ceil(minUnitTotal / partPercent);
|
||||
return Math.ceil((dose / partPercent) * count);
|
||||
case 4: // 门诊按包装单位每次量向上取整
|
||||
// 每次用量转换为包装单位后向上取整
|
||||
return Math.ceil(Math.ceil(dose / partPercent) * count);
|
||||
return Math.ceil(dose) * count;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4521,16 +4475,6 @@ defineExpose({ getListInfo, getDiagnosisInfo });
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
/* 🔧 Bug #273 拆零比提示样式 */
|
||||
.part-percent-hint {
|
||||
color: #909399;
|
||||
font-size: 12px;
|
||||
white-space: nowrap;
|
||||
margin-left: 8px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* V1.3 风格侧边栏 - 组套列表样式 */
|
||||
.order-group-container {
|
||||
display: flex;
|
||||
|
||||
Reference in New Issue
Block a user