docs(release-notes): 添加住院护士站划价功能说明和发版记录

- 新增住院护士站划价服务流程说明文档,详细描述了从参数预处理到结果响应的五大阶段流程
- 包含耗材类医嘱和诊疗活动类医嘱的差异化处理逻辑
- 添加完整的发版内容记录,涵盖新增菜单功能和各模块优化点
- 记录了住院相关功能的新增和门诊业务流程的修复
```
This commit is contained in:
2025-12-25 14:13:14 +08:00
parent 85fcb7c2e2
commit abc0674531
920 changed files with 107068 additions and 14495 deletions

View File

@@ -0,0 +1,136 @@
<template>
<el-input
:model-value="displayValue"
:placeholder="placeholder"
:disabled="disabled"
:clearable="clearable"
@input="handleInput"
@blur="handleBlur"
@change="handleChange"
>
<template v-if="suffix" #suffix>{{ suffix }}</template>
</el-input>
</template>
<script setup>
import { ref, computed, watch } from 'vue';
const props = defineProps({
modelValue: [Number, String],
placeholder: String,
disabled: Boolean,
clearable: {
type: Boolean,
default: true,
},
suffix: String,
precision: Number, // 小数位数
min: Number,
max: Number,
});
const emit = defineEmits(['update:modelValue', 'blur', 'change']);
const displayValue = computed(() => {
if (props.modelValue === null || props.modelValue === undefined || props.modelValue === '') {
return '';
}
return String(props.modelValue);
});
const handleInput = (value) => {
// 只允许数字、小数点和负号
let newValue = value.replace(/[^\d.-]/g, '');
// 只允许一个小数点
const parts = newValue.split('.');
if (parts.length > 2) {
newValue = parts[0] + '.' + parts.slice(1).join('');
}
// 只允许一个负号,且必须在开头
if (newValue.indexOf('-') > 0) {
newValue = newValue.replace(/-/g, '');
}
if (newValue.startsWith('-') && newValue.split('-').length > 2) {
newValue = '-' + newValue.replace(/-/g, '');
}
// 如果为空,直接返回空字符串
if (newValue === '' || newValue === '-') {
emit('update:modelValue', '');
return;
}
// 转换为数字
const numValue = parseFloat(newValue);
if (isNaN(numValue)) {
emit('update:modelValue', '');
return;
}
// 限制最小值
if (props.min !== undefined && numValue < props.min) {
newValue = String(props.min);
}
// 限制最大值
if (props.max !== undefined && numValue > props.max) {
newValue = String(props.max);
}
// 处理精度
if (props.precision !== undefined && newValue.includes('.')) {
const parts = newValue.split('.');
if (parts[1] && parts[1].length > props.precision) {
parts[1] = parts[1].substring(0, props.precision);
newValue = parts.join('.');
}
}
emit('update:modelValue', newValue);
};
const handleBlur = (event) => {
const value = event.target.value;
if (value === '' || value === '-') {
emit('update:modelValue', '');
emit('blur', event);
return;
}
const numValue = parseFloat(value);
if (isNaN(numValue)) {
emit('update:modelValue', '');
emit('blur', event);
return;
}
// 应用精度
let finalValue = numValue;
if (props.precision !== undefined) {
finalValue = parseFloat(numValue.toFixed(props.precision));
}
// 限制范围
if (props.min !== undefined && finalValue < props.min) {
finalValue = props.min;
}
if (props.max !== undefined && finalValue > props.max) {
finalValue = props.max;
}
emit('update:modelValue', String(finalValue));
emit('blur', event);
};
const handleChange = (value) => {
emit('change', value);
};
</script>
<style scoped lang="scss">
:deep(.el-input__inner) {
text-align: left;
}
</style>