根因: - Bug #请修复 Bug #591 存在的问题 修复: - ### 变更摘要 - 全链路数据流分析**:录取(弹窗输入)→ 保存(API传入)→ 查询(Mapper返回)→ 修改(Service记录)→ 删除/停止(状态变更)→ 关联(列表展示) - ### 后端变更(4个文件) - 1. `AdviceBatchOpParam.java`** — 停嘱参数添加 `stopTime` 字段 - 新增 `@JsonFormat Date stopTime`,支持前端传入停嘱时间 - 2. `RequestBaseDto.java`** — 查询DTO添加 `stopUserName`、`stopTime` 字段 - 新增 `String stopUserName`(停嘱医生姓名) - 新增 `Date stopTime`(停嘱时间) - 3. `AdviceManageAppServiceImpl.java`** — 停嘱Service增强 - 优先使用前端传入的 `stopTime`,兜底用当前时间 - 通过 `SecurityUtils.getNickName()` 获取当前操作用户昵称,记录到 `updateBy` - 药品和诊疗两个更新入口均已同步修改 - 4. `AdviceManageAppMapper.xml`** — 三个UNION ALL子查询添加字段 - 药品子查询:`T1.effective_dose_end AS stop_time` + `T1.update_by AS stop_user_name` - 耗材子查询:`NULL AS stop_time` + `'' AS stop_user_name` - 诊疗子查询:`T1.occurrence_end_time AS stop_time` + `T1.update_by AS stop_user_name` - ### 前端变更(1个文件) - `order/index.vue`**: - 1. **停嘱时间弹窗** — 点击「停嘱」后弹出 `el-dialog`,内含 `el-date-picker`(datetime类型,默认当前时间),确定后才调用API - 2. **表格列** — 在「皮试」列后面、「诊断」列前面新增两列: - 「停嘱医生」`prop="stopUserName"`,宽度120px - 「停嘱时间」`prop="stopTime"`,宽度170px - 3. **`handleStopAdvice`** — 保留原有校验(未保存/未签发/已停止检查),校验通过后弹出时间选择弹窗而非直接调API - 4. **`confirmStopAdvice`** — 新增确认函数,将 `stopTime` 拼入请求参数后调用 `stopAdvice` API - ### 验证结果 - ✅ 前端 Lint 检查通过(仅1个预存的 `vue/no-dupe-keys` 警告) - ✅ 后端 Maven 编译通过(BUILD SUCCESS)
258 lines
6.2 KiB
Vue
Executable File
258 lines
6.2 KiB
Vue
Executable File
<template>
|
||
<el-dialog
|
||
v-model="props.openDialog"
|
||
title="药品追溯码"
|
||
width="842"
|
||
append-to-body
|
||
destroy-on-close
|
||
:draggable="true"
|
||
@close="cancel"
|
||
@opened="
|
||
() => {
|
||
traceNoTempRef.focus();
|
||
}
|
||
"
|
||
>
|
||
<div>
|
||
<div style="font-size: 16px">
|
||
<div style="margin-bottom: 15px">
|
||
药品名称: {{ props.ypName }}
|
||
</div>
|
||
扫描追溯码
|
||
<el-input
|
||
ref="traceNoTempRef"
|
||
v-model="traceNoTemp"
|
||
type="textarea"
|
||
:rows="1"
|
||
style="width: 180px; margin-right: 20px"
|
||
@input="throttledGetList(traceNoTemp)"
|
||
/>
|
||
输入追溯码
|
||
<el-input
|
||
v-model="traceNoInput"
|
||
style="width: 180px; margin-right: 20px"
|
||
@keyup.enter="handelTraceNo(traceNoInput)"
|
||
/>
|
||
<el-button
|
||
type="primary"
|
||
plain
|
||
icon="CircleClose"
|
||
@click="handleReturn"
|
||
>
|
||
撤回
|
||
</el-button>
|
||
<el-button
|
||
type="danger"
|
||
plain
|
||
icon="CircleClose"
|
||
@click="handleClear"
|
||
>
|
||
清除
|
||
</el-button>
|
||
</div>
|
||
<!-- <el-input
|
||
ref="inputRef"
|
||
v-model="traceNo"
|
||
type="textarea"
|
||
:rows="15"
|
||
disabled
|
||
@input="throttledGetList"
|
||
style="width: 100%; margin-top: 10px; margin-right: 20px"
|
||
/> -->
|
||
<div
|
||
style="
|
||
background: #f5f7fa;
|
||
margin-top: 10px;
|
||
padding: 10px;
|
||
width: 780px;
|
||
height: 350px;
|
||
border: solid 1px #ebeef5;
|
||
overflow-y: auto;
|
||
"
|
||
>
|
||
<div style="display: flex; flex-wrap: wrap; gap: 8px">
|
||
<div
|
||
v-for="(item, index) in traceNoList"
|
||
:key="item + index"
|
||
style="
|
||
display: inline-flex;
|
||
align-items: center;
|
||
background: white;
|
||
padding: 4px 8px 4px 12px;
|
||
border-radius: 12px;
|
||
"
|
||
>
|
||
<span style="margin-right: 6px">
|
||
[{{ index + 1 }}]
|
||
<template v-if="index < 9"> </template>
|
||
<template v-else />
|
||
{{ item }}
|
||
</span>
|
||
<div
|
||
style="
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: 16px;
|
||
height: 16px;
|
||
background: #f56c6c;
|
||
border-radius: 50%;
|
||
cursor: pointer;
|
||
"
|
||
@click="removeTraceNo(index)"
|
||
>
|
||
<el-icon
|
||
size="10"
|
||
color="white"
|
||
>
|
||
<Close />
|
||
</el-icon>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div>
|
||
追溯码:{{ existenceTraceNoList[rowData ? rowData.itemId : 0] }}
|
||
</div>
|
||
</div>
|
||
<template #footer>
|
||
<div class="dialog-footer">
|
||
<el-button
|
||
type="primary"
|
||
@click="submit"
|
||
>
|
||
确 定
|
||
</el-button>
|
||
<el-button @click="cancel">
|
||
取 消
|
||
</el-button>
|
||
</div>
|
||
</template>
|
||
</el-dialog>
|
||
</template>
|
||
|
||
<script setup>
|
||
import {watch} from 'vue';
|
||
import {searchTraceNo} from '@/api/public';
|
||
import {debounce} from 'lodash-es';
|
||
|
||
const props = defineProps({
|
||
openDialog: {
|
||
type: Boolean,
|
||
default: false,
|
||
},
|
||
ypName: {
|
||
type: String,
|
||
default: '',
|
||
},
|
||
rowData: {
|
||
type: Object,
|
||
default: () => {},
|
||
},
|
||
});
|
||
const openTraceNo = ref(false);
|
||
const traceNo = ref('');
|
||
const traceNoList = ref([]);
|
||
const existenceTraceNoList = ref([]);
|
||
const traceNoTemp = ref('');
|
||
const traceNoInput = ref('');
|
||
const traceNoTempRef = ref();
|
||
const emit = defineEmits(['submit', 'cancel']);
|
||
|
||
watch(
|
||
() => props.rowData,
|
||
async (newRowData) => {
|
||
if (newRowData && Object.keys(newRowData).length > 0) {
|
||
const { itemType, itemId, locationId, lotNumber } = newRowData;
|
||
|
||
try {
|
||
const response = await searchTraceNo({
|
||
itemType,
|
||
itemId,
|
||
locationId,
|
||
lotNumber,
|
||
});
|
||
|
||
// 处理返回数据,例如更新 traceNoList
|
||
existenceTraceNoList.value = response.data || [];
|
||
} catch (error) {
|
||
console.error('获取追溯码失败:', error);
|
||
}
|
||
}
|
||
},
|
||
{ deep: true, immediate: true }
|
||
);
|
||
|
||
// 撤回最后一条追溯码
|
||
function handleReturn() {
|
||
if (traceNoList.value.length !== 0) {
|
||
// 1. 从数组中移除最后一项
|
||
traceNoList.value.pop();
|
||
// 2. 重新构建显示文本
|
||
traceNo.value = traceNoList.value
|
||
.map((item, index) => {
|
||
return index < 9 ? `[${index + 1}] ${item}` : `[${index + 1}] ${item}`;
|
||
})
|
||
.join(', ');
|
||
if (traceNoList.value != 0) {
|
||
traceNo.value += '\n';
|
||
}
|
||
}
|
||
traceNoTempRef.value.focus();
|
||
}
|
||
|
||
function removeTraceNo(index) {
|
||
traceNoList.value.splice(index, 1);
|
||
traceNoTempRef.value.focus();
|
||
}
|
||
|
||
function formatValue(index) {
|
||
if (index >= 10) {
|
||
return ` `;
|
||
} else {
|
||
return ` `;
|
||
}
|
||
}
|
||
|
||
function handleClear() {
|
||
traceNo.value = '';
|
||
traceNoList.value = [];
|
||
}
|
||
const throttledGetList = debounce(handelTraceNo, 500);
|
||
function handelTraceNo(value) {
|
||
let list = value.trim().split('\n');
|
||
list.forEach((item) => {
|
||
if(traceNoList.value.indexOf(item) === -1) {
|
||
traceNoList.value.push(item);
|
||
}
|
||
});
|
||
traceNo.value = traceNoList.value
|
||
.map((item, index) => {
|
||
return index < 9 ? `[${index + 1}] ${item}` : `[${index + 1}] ${item}`;
|
||
})
|
||
.join(', ');
|
||
if (traceNoList.value != 0) {
|
||
traceNo.value += '\n';
|
||
}
|
||
traceNoTemp.value = '';
|
||
traceNoInput.value = '';
|
||
// let saveValue = value.substring(inputValue.length + 5, value.length);
|
||
// inputValue = value;
|
||
// console.log(value);
|
||
// console.log(saveValue);
|
||
// traceNoList.value.push(saveValue);
|
||
// traceNo.value = value + '[' + (traceNoList.value.length + 1) + ']' + ' ';
|
||
}
|
||
function cancel() {
|
||
emit('cancel');
|
||
traceNoList.value = [];
|
||
traceNo.value = '';
|
||
}
|
||
|
||
function submit() {
|
||
emit('submit', traceNoList.value.join(','));
|
||
openTraceNo.value = false;
|
||
traceNoList.value = [];
|
||
traceNo.value = '';
|
||
}
|
||
</script> |