项目结果
This commit is contained in:
parent
f6f4efa0c4
commit
310ec41122
17
src/App.vue
17
src/App.vue
@ -6,13 +6,28 @@
|
|||||||
import useSettingsStore from '@/store/modules/settings'
|
import useSettingsStore from '@/store/modules/settings'
|
||||||
import { handleThemeStyle } from '@/utils/theme'
|
import { handleThemeStyle } from '@/utils/theme'
|
||||||
import { ref, onMounted, onUnmounted, nextTick } from 'vue';
|
import { ref, onMounted, onUnmounted, nextTick } from 'vue';
|
||||||
|
import { useFingerprint } from '@/utils/useFingerprint';
|
||||||
|
import { useCommonStore } from '@/store/modules/commonStore'
|
||||||
|
const mbStore = useCommonStore();
|
||||||
|
// 使用自定义hook获取指纹信息
|
||||||
|
const {
|
||||||
|
fingerprint,
|
||||||
|
loading,
|
||||||
|
error,
|
||||||
|
getFingerprint
|
||||||
|
} = useFingerprint();
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
// 初始化主题样式
|
// 初始化主题样式
|
||||||
handleThemeStyle(useSettingsStore().theme)
|
handleThemeStyle(useSettingsStore().theme)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if (!mbStore.fingerprint) {
|
||||||
|
// 重新获取指纹
|
||||||
|
getFingerprint();
|
||||||
|
mbStore.setFingerprint(fingerprint)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -21,11 +21,27 @@ export function wswsamplelistpage(query?: Object) {
|
|||||||
// 获取微生物样本信息
|
// 获取微生物样本信息
|
||||||
export function sampleMedInfo(query?: Object) {
|
export function sampleMedInfo(query?: Object) {
|
||||||
return request({
|
return request({
|
||||||
url: '/lisworkgerm/sampleMedInfo',
|
url: '/lisworkgerm/getresultlist',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
params: query
|
params: query
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
// 获取药敏数据
|
||||||
|
export function getresultmedList(query?: Object) {
|
||||||
|
return request({
|
||||||
|
url: '/lisworkgerm/getresultmedlist',
|
||||||
|
method: 'get',
|
||||||
|
params: query
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 写入专家评语
|
||||||
|
export function savetestResult(query?: Object) {
|
||||||
|
return request({
|
||||||
|
url: '/lisworkgerm/savetestresult',
|
||||||
|
method: 'post',
|
||||||
|
data: query
|
||||||
|
})
|
||||||
|
}
|
||||||
// 获取操作记录
|
// 获取操作记录
|
||||||
export function getComLog(query?: Object) {
|
export function getComLog(query?: Object) {
|
||||||
return request({
|
return request({
|
||||||
@ -34,3 +50,29 @@ export function getComLog(query?: Object) {
|
|||||||
params: query
|
params: query
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//新增结果明细
|
||||||
|
export function newresult(data?: Object) {
|
||||||
|
return request({
|
||||||
|
url: '/lisworkgerm/newresult',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
//修改结果明细
|
||||||
|
export function changeresult(data?: Object) {
|
||||||
|
return request({
|
||||||
|
url: '/lisworkgerm/changeresult',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//修改结果明细
|
||||||
|
export function saveresult(data?: Object) {
|
||||||
|
return request({
|
||||||
|
url: '/lisworkgerm/saveresult',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
@ -4,10 +4,15 @@ import { defineStore } from 'pinia'
|
|||||||
export const useCommonStore = defineStore('commonStore', {
|
export const useCommonStore = defineStore('commonStore', {
|
||||||
state: () => ({
|
state: () => ({
|
||||||
lxsrs: [] as string[], // 存储项目模板名称
|
lxsrs: [] as string[], // 存储项目模板名称
|
||||||
|
fingerprint: '',// 存储指纹信息
|
||||||
}),
|
}),
|
||||||
actions: {
|
actions: {
|
||||||
setLxsrList(list: any[]) {
|
setLxsrList(list: any[]) {
|
||||||
this.lxsrs = list
|
this.lxsrs = list
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setFingerprint(fingerprint: string) {
|
||||||
|
this.fingerprint = fingerprint
|
||||||
|
},
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
103
src/utils/webSocket.ts
Normal file
103
src/utils/webSocket.ts
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
// WebSocket连接配置
|
||||||
|
type WebSocketOptions = {
|
||||||
|
fullUrl: string;
|
||||||
|
onMessage?: (data: string) => void;
|
||||||
|
onOpen?: () => void;
|
||||||
|
onError?: (error: Event) => void;
|
||||||
|
onClose?: () => void;
|
||||||
|
reconnectInterval?: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
let websocket: WebSocket | null = null;
|
||||||
|
let reconnectTimer: any = null;
|
||||||
|
let isManualClose = false;
|
||||||
|
|
||||||
|
// 初始化WebSocket连接
|
||||||
|
export function initWebSocket(options: WebSocketOptions) {
|
||||||
|
const {
|
||||||
|
fullUrl,
|
||||||
|
onMessage,
|
||||||
|
onOpen,
|
||||||
|
onError,
|
||||||
|
onClose,
|
||||||
|
reconnectInterval = 3000
|
||||||
|
} = options;
|
||||||
|
|
||||||
|
// 关闭旧连接
|
||||||
|
if (websocket) {
|
||||||
|
websocket.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查浏览器支持性
|
||||||
|
if (!('WebSocket' in window)) {
|
||||||
|
console.error('当前浏览器不支持WebSocket');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建WebSocket连接
|
||||||
|
try {
|
||||||
|
websocket = new WebSocket(fullUrl);
|
||||||
|
|
||||||
|
// 连接成功回调
|
||||||
|
websocket.onopen = () => {
|
||||||
|
clearTimeout(reconnectTimer!);
|
||||||
|
isManualClose = false;
|
||||||
|
onOpen?.();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 接收消息回调
|
||||||
|
websocket.onmessage = (event) => {
|
||||||
|
onMessage?.(event.data);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 错误回调
|
||||||
|
websocket.onerror = (error) => {
|
||||||
|
onError?.(error);
|
||||||
|
startReconnect(() => initWebSocket(options), reconnectInterval);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 关闭回调
|
||||||
|
websocket.onclose = () => {
|
||||||
|
onClose?.();
|
||||||
|
if (!isManualClose) {
|
||||||
|
startReconnect(() => initWebSocket(options), reconnectInterval);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
console.error('WebSocket连接创建失败:', error);
|
||||||
|
startReconnect(() => initWebSocket(options), reconnectInterval);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 发送消息
|
||||||
|
export function sendWebSocketMessage(message: any): boolean {
|
||||||
|
if (websocket && websocket.readyState === WebSocket.OPEN) {
|
||||||
|
websocket.send(JSON.stringify(message));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
console.error('WebSocket未连接,无法发送消息');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 手动关闭WebSocket
|
||||||
|
export function closeWebSocket(): void {
|
||||||
|
isManualClose = true;
|
||||||
|
if (reconnectTimer) {
|
||||||
|
clearTimeout(reconnectTimer);
|
||||||
|
}
|
||||||
|
websocket?.close();
|
||||||
|
websocket = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 启动重连
|
||||||
|
function startReconnect(connectCallback: () => void, interval: number): void {
|
||||||
|
if (reconnectTimer) {
|
||||||
|
clearTimeout(reconnectTimer);
|
||||||
|
}
|
||||||
|
reconnectTimer = setTimeout(connectCallback, interval);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取当前连接状态
|
||||||
|
export function getWebSocketState(): number | null {
|
||||||
|
return websocket?.readyState || null;
|
||||||
|
}
|
||||||
@ -490,13 +490,13 @@ const brlxFields = ref([
|
|||||||
const rightTableData = ref([])
|
const rightTableData = ref([])
|
||||||
// 配置项
|
// 配置项
|
||||||
const rightColumns = ref([
|
const rightColumns = ref([
|
||||||
{ prop: 'xmdh', label: '项目代号', align: 'center', visible: true, }, //0
|
{ prop: 'xmdh', label: '项目代号', align: 'center', visible: true, },
|
||||||
{ prop: 'xmmc', label: '项目名称', align: 'center', visible: true, }, //1
|
{ prop: 'xmmc', label: '项目名称', align: 'center', visible: true, },
|
||||||
{ prop: 'xmmc', label: '培养结果', align: 'center', visible: true, width: 150 },//2
|
{ prop: 'xmmc', label: '培养结果', align: 'center', visible: true, width: 150 },
|
||||||
{ prop: 'csjg', label: '检验结果', align: 'center', visible: true, },//3
|
{ prop: 'csjg', label: '检验结果', align: 'center', visible: true, },
|
||||||
{ prop: 'refs', label: '参考值', align: 'center', visible: true, },//4
|
{ prop: 'refs', label: '参考值', align: 'center', visible: true, },
|
||||||
{ prop: 'dw', label: '单位', align: 'center', visible: true, },//5
|
{ prop: 'dw', label: '单位', align: 'center', visible: true, },
|
||||||
{ prop: 'od', label: '菌落计数', align: 'center', visible: true, },//6
|
{ prop: 'od', label: '菌落计数', align: 'center', visible: true, },
|
||||||
// { prop: 'jgbz', label: '结果标志', align: 'center', visible: true, slot: 'jgbz' },
|
// { prop: 'jgbz', label: '结果标志', align: 'center', visible: true, slot: 'jgbz' },
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|||||||
@ -5,20 +5,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { useFingerprint } from '@/utils/useFingerprint';
|
|
||||||
|
|
||||||
// 使用自定义hook获取指纹信息
|
|
||||||
const {
|
|
||||||
fingerprint,
|
|
||||||
loading,
|
|
||||||
error,
|
|
||||||
getFingerprint
|
|
||||||
} = useFingerprint();
|
|
||||||
|
|
||||||
// 重新获取指纹
|
|
||||||
const refreshFingerprint = async () => {
|
|
||||||
await getFingerprint();
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped></style>
|
||||||
@ -49,7 +49,9 @@
|
|||||||
:userList="userList" @changeStatus="changeStatus" @batchShow="handleBatchScan" />
|
:userList="userList" @changeStatus="changeStatus" @batchShow="handleBatchScan" />
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="16">
|
<el-col :span="16">
|
||||||
<LabResult ref="labResultRef" v-model:labPat="labPat" :labPatKey="queryParams" />
|
<LabResult ref="labResultRef" v-model:labPat="labInfo" :labPatKey="queryParams" :dictData="dictData"
|
||||||
|
:labResutsData="labResuts" @fetchLabResults="resultsHandle" @changeStatus="changeStatus"
|
||||||
|
@previewHandle="previewHandle" />
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</div>
|
</div>
|
||||||
@ -84,7 +86,7 @@
|
|||||||
<el-radio :value="7">近7天</el-radio>
|
<el-radio :value="7">近7天</el-radio>
|
||||||
<el-radio :value="1">此日 -></el-radio>
|
<el-radio :value="1">此日 -></el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
<el-date-picker v-model="queryParams.jyrq" type="date" :size="aotuSize" />
|
<el-date-picker v-model="queryParams.jyrq" type="date" :size="aotuSize" @change="fetchlabPatList" />
|
||||||
</div>
|
</div>
|
||||||
<LabPatList ref="labPatListRef" :labPatList="labPatList" :loading="loading" @select="selectJob"
|
<LabPatList ref="labPatListRef" :labPatList="labPatList" :loading="loading" @select="selectJob"
|
||||||
:tableKey="queryParams" :dictData="dictData" @search="searchJobs" />
|
:tableKey="queryParams" :dictData="dictData" @search="searchJobs" />
|
||||||
@ -129,6 +131,14 @@ import iFrame from "@/components/iFrame/index.vue";
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import LabResult from './labresult/index.vue';
|
import LabResult from './labresult/index.vue';
|
||||||
import LabPatList from './labpatlist.vue';
|
import LabPatList from './labpatlist.vue';
|
||||||
|
import History from '../conponents/history/index.vue'
|
||||||
|
import Others from '../conponents/others/index.vue'
|
||||||
|
import Reexamination from '../conponents/reexamination/index.vue'
|
||||||
|
import Charge from '../conponents/charge/index.vue'
|
||||||
|
import Combination from '../conponents/combination/index.vue'
|
||||||
|
import Clinical from '../conponents/clinical/index.vue'
|
||||||
|
import Sample from '../conponents/sample/index.vue'
|
||||||
|
import ResultGraph from '../conponents/resultGraph/index.vue'
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import { comDict } from '@/utils/dict'
|
import { comDict } from '@/utils/dict'
|
||||||
import { queryLabResults, loadDefault, queryLabPat, instrdconfig, delSample, getGroupInstrdList } from "@/api/liswork/work/LisWork";
|
import { queryLabResults, loadDefault, queryLabPat, instrdconfig, delSample, getGroupInstrdList } from "@/api/liswork/work/LisWork";
|
||||||
@ -144,6 +154,7 @@ import PatientQueryForm from '@/components/selectSearch/index.vue'
|
|||||||
import { listUser } from '@/api/system/user.js'
|
import { listUser } from '@/api/system/user.js'
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
const aotuSize = classCom.useAutoSize();
|
const aotuSize = classCom.useAutoSize();
|
||||||
|
import { initWebSocket, sendWebSocketMessage, closeWebSocket, getWebSocketState } from '@/utils/webSocket';
|
||||||
|
|
||||||
const previewShow = ref(false);
|
const previewShow = ref(false);
|
||||||
const lbFlag = ref(false);
|
const lbFlag = ref(false);
|
||||||
@ -175,7 +186,14 @@ const tabList = ref([
|
|||||||
])
|
])
|
||||||
|
|
||||||
const activeTabMap = {
|
const activeTabMap = {
|
||||||
|
ResultGraph,
|
||||||
|
History,
|
||||||
|
Others,
|
||||||
|
Reexamination,
|
||||||
|
Charge,
|
||||||
|
Combination,
|
||||||
|
Clinical,
|
||||||
|
Sample
|
||||||
}
|
}
|
||||||
|
|
||||||
const activeTabName = computed(() => activeTabMap[activeTab.value as keyof typeof activeTabMap] || 'LabPatList');
|
const activeTabName = computed(() => activeTabMap[activeTab.value as keyof typeof activeTabMap] || 'LabPatList');
|
||||||
@ -297,6 +315,7 @@ const yqHandleChange = (val: any) => {
|
|||||||
mbStore.setLxsrList([]);
|
mbStore.setLxsrList([]);
|
||||||
getSysList()
|
getSysList()
|
||||||
fetchlabPatList()
|
fetchlabPatList()
|
||||||
|
sendMessage()
|
||||||
}
|
}
|
||||||
const instrGroupFields = ref([
|
const instrGroupFields = ref([
|
||||||
{ prop: 'zddh', label: '代号', width: 80, enablePinyinSearch: true },
|
{ prop: 'zddh', label: '代号', width: 80, enablePinyinSearch: true },
|
||||||
@ -351,7 +370,7 @@ const selectJob = (job: any) => {
|
|||||||
const labResuts = ref([])
|
const labResuts = ref([])
|
||||||
//载入样本结果表单(中间labresult.vue组件)
|
//载入样本结果表单(中间labresult.vue组件)
|
||||||
const fetchLabResults = async () => {
|
const fetchLabResults = async () => {
|
||||||
queryLabResults({ jyrq: queryParams.value.jyrq, yq: queryParams.value.yq, ybh: labInfo.value.ybh }).then((response: any) => {
|
sampleMedInfo({ jyrq: labInfo.value.jyrq, yq: labInfo.value.yq, ybh: labInfo.value.ybh }).then((response: any) => {
|
||||||
labResuts.value = response.data;
|
labResuts.value = response.data;
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -365,6 +384,7 @@ const fetchLabPat = () => {
|
|||||||
}
|
}
|
||||||
queryLabPat(data).then((response: any) => {
|
queryLabPat(data).then((response: any) => {
|
||||||
labPat.value = response.data;
|
labPat.value = response.data;
|
||||||
|
labInfo.value = response.data;
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -372,7 +392,7 @@ const lastRow: any = ref({})
|
|||||||
|
|
||||||
// 批量扫码ybh同步样本编号
|
// 批量扫码ybh同步样本编号
|
||||||
const ybhChangeTb = (val: string) => {
|
const ybhChangeTb = (val: string) => {
|
||||||
console.log('val==>', val);
|
// console.log('val==>', val);
|
||||||
labInfo.value.ybh = val
|
labInfo.value.ybh = val
|
||||||
handleQuery();
|
handleQuery();
|
||||||
}
|
}
|
||||||
@ -649,7 +669,7 @@ onMounted(async () => {
|
|||||||
userList.value = res.rows;
|
userList.value = res.rows;
|
||||||
});
|
});
|
||||||
// 加载病人来源字典
|
// 加载病人来源字典
|
||||||
const dictRefs = await comDict('PT', 'AU', 'SX', 'DP', 'BT', 'SRD', 'HOS', 'ST');
|
const dictRefs = await comDict('PT', 'AU', 'SX', 'DP', 'BT', 'SRD', 'HOS', 'ST', 'germclass');
|
||||||
// 从 ref 中获取实际数据
|
// 从 ref 中获取实际数据
|
||||||
dictData.value = {
|
dictData.value = {
|
||||||
PT: toRaw(dictRefs.PT.value) || [],
|
PT: toRaw(dictRefs.PT.value) || [],
|
||||||
@ -660,8 +680,48 @@ onMounted(async () => {
|
|||||||
SRD: toRaw(dictRefs.SRD.value) || [],
|
SRD: toRaw(dictRefs.SRD.value) || [],
|
||||||
HOS: toRaw(dictRefs.HOS.value) || [],
|
HOS: toRaw(dictRefs.HOS.value) || [],
|
||||||
ST: toRaw(dictRefs.ST.value) || [],
|
ST: toRaw(dictRefs.ST.value) || [],
|
||||||
|
germclass: toRaw(dictRefs.germclass.value) || [],
|
||||||
};
|
};
|
||||||
|
// 初始化Socket
|
||||||
|
initSocket()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const initSocket = () => {
|
||||||
|
initWebSocket({
|
||||||
|
// fullUrl: `ws://47.97.125.165:8904/ws/instr/${mbStore.fingerprint}`,
|
||||||
|
fullUrl: `ws://192.168.1.151:9801/ws/instr/${mbStore.fingerprint}`,
|
||||||
|
onOpen: () => {
|
||||||
|
console.log('WebSocket连接成功');
|
||||||
|
},
|
||||||
|
onMessage: (data) => {
|
||||||
|
console.log(`收到消息: `, JSON.parse(data));
|
||||||
|
},
|
||||||
|
onError: (error) => {
|
||||||
|
console.log(`连接错误: ${error.type}`);
|
||||||
|
},
|
||||||
|
onClose: () => {
|
||||||
|
console.log('WebSocket连接已关闭');
|
||||||
|
},
|
||||||
|
reconnectInterval: 3000 // 重连间隔(毫秒)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 页面卸载时清理
|
||||||
|
onUnmounted(() => {
|
||||||
|
closeWebSocket();
|
||||||
|
});
|
||||||
|
|
||||||
|
// 发送消息
|
||||||
|
const sendMessage = () => {
|
||||||
|
const isSuccess = sendWebSocketMessage({ yq: queryParams.value.yq });
|
||||||
|
if (isSuccess) {
|
||||||
|
console.log(`发送消息`);
|
||||||
|
} else {
|
||||||
|
console.log('发送失败:连接未建立');
|
||||||
|
}
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|||||||
@ -336,7 +336,7 @@ const getColor = (type: string) => {
|
|||||||
}
|
}
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// 监听保存病人结果
|
// 监听保存病人结果
|
||||||
emitter.on('saveResult', () => {
|
emitter.on('wswSaveResult', () => {
|
||||||
saveLabPat(null)
|
saveLabPat(null)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@ -134,7 +134,7 @@ const handleMenuSelect = ((item: ContextMenuItem) => {
|
|||||||
// 表格列配置
|
// 表格列配置
|
||||||
const tableColumns = ref([
|
const tableColumns = ref([
|
||||||
{ field: 'jyrq', title: '录入时间', width: 80, align: 'center', resizable: true },
|
{ field: 'jyrq', title: '录入时间', width: 80, align: 'center', resizable: true },
|
||||||
{ field: 'finish', title: '敏', width: 30, align: 'center', slotName: 'finish', resizable: true },
|
{ field: 'finish', title: '药敏', width: 30, align: 'center', slotName: 'finish', resizable: true },
|
||||||
{ field: 'alarmflag', title: '警', width: 30, align: 'center', slotName: 'alarmflag', resizable: true },
|
{ field: 'alarmflag', title: '警', width: 30, align: 'center', slotName: 'alarmflag', resizable: true },
|
||||||
{ field: 'cp_pyzq', title: '培养周期', width: 60, align: 'center', resizable: true },
|
{ field: 'cp_pyzq', title: '培养周期', width: 60, align: 'center', resizable: true },
|
||||||
{ field: 'jgbz', title: '状态', width: 50, align: 'center', resizable: true, slotName: 'jgbz' },
|
{ field: 'jgbz', title: '状态', width: 50, align: 'center', resizable: true, slotName: 'jgbz' },
|
||||||
|
|||||||
@ -1,10 +1,86 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
初级
|
<CustomTable :data="labResutsData.labResultList" :columns="columns" :config="tableConfig" :enable-column-drag="true"
|
||||||
|
@column-drag-end="handleColumnDragEnd">
|
||||||
|
</CustomTable>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import CustomTable from '@/components/elTable/index.vue'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
labResutsData: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
//结果主键
|
||||||
|
labPat: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
const columns = ref([
|
||||||
|
{ label: "细菌/结果", prop: "xmdh", align: 'center', visible: true, slot: 'xmdh', width: 150 },
|
||||||
|
{ label: "检验结果", prop: "csjg", align: 'center', visible: true, slot: 'csjg' },
|
||||||
|
{ label: "阴阳性", prop: "jgbz", align: 'center', visible: true, slot: 'jgbz' },
|
||||||
|
{ label: "危急值", prop: "alarm_flag", align: 'center', visible: true, slot: 'alarm_flag' },
|
||||||
|
{ label: "菌属", prop: "xmmc", align: 'center', visible: true },
|
||||||
|
])
|
||||||
|
|
||||||
|
const CellStyleHd = ({ row, column, rowIndex, columnIndex }: {
|
||||||
|
row: any;
|
||||||
|
column: any;
|
||||||
|
rowIndex: number;
|
||||||
|
columnIndex: number;
|
||||||
|
}) => {
|
||||||
|
if (column.label == "细菌/结果" && (row.alarm_flag ?? "").trim().length > 0) {
|
||||||
|
return { background: '#f00 !important', color: '#FFF' };
|
||||||
|
}
|
||||||
|
if (column.label == "危急值" && (row.alarm_flag ?? "").trim().length > 0) {
|
||||||
|
return { background: '#f00 !important', color: '#FFF' };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (column.label == "检验结果" && row.jgbz == "H") {
|
||||||
|
return { background: '#ffc0c0 !important', color: '#606266' };
|
||||||
|
}
|
||||||
|
if (column.label == "检验结果" && row.jgbz == "L") {
|
||||||
|
return { background: '#8080ff !important', color: '#fff' };
|
||||||
|
}
|
||||||
|
if (column.label == "检验结果" && row.jgbz == "P") {
|
||||||
|
return { background: '#ffc0c0 !important', color: '#606266' };
|
||||||
|
}
|
||||||
|
if (column.label == "检验结果" && row.jgbz == "Q") {
|
||||||
|
return { background: '#ffff80 !important', color: '#606266' };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (column.label == "阴阳性" && row.jgbz == "H") {
|
||||||
|
return { background: '#ffc0c0 !important', color: '#606266' };
|
||||||
|
}
|
||||||
|
if (column.label == "阴阳性" && row.jgbz == "L") {
|
||||||
|
return { background: '#8080ff !important', color: '#fff' };
|
||||||
|
}
|
||||||
|
if (column.label == "阴阳性" && row.jgbz == "P") {
|
||||||
|
return { background: '#ffc0c0 !important', color: '#606266' };
|
||||||
|
}
|
||||||
|
if (column.label == "阴阳性" && row.jgbz == "Q") {
|
||||||
|
return { background: '#ffff80 !important', color: '#606266' };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const tableConfig = ref({
|
||||||
|
height: '28vh',
|
||||||
|
border: true,
|
||||||
|
highlightCurrentRow: true,
|
||||||
|
cellStyle: CellStyleHd
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleColumnDragEnd = (data: any) => {
|
||||||
|
columns.value = data.columns;
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -51,8 +51,8 @@ const getRecordList = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
watch(() => props.labPat, (newValue) => {
|
watch(() => props.labPat, (newValue) => {
|
||||||
// getRecordList()
|
getRecordList()
|
||||||
}, { immediate: true })
|
})
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -1,87 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<CustomTable :data="tableData" :columns="columns" :config="tableConfig" :enable-column-drag="true"
|
|
||||||
@column-drag-end="handleColumnDragEnd">
|
|
||||||
</CustomTable>
|
|
||||||
|
|
||||||
<el-tabs v-model="activeName" type="card" class="demo-tabs">
|
|
||||||
<el-tab-pane label="药敏结果" name="first">
|
|
||||||
<CustomTable :data="ymTableData" :columns="ymColumns" :config="ymTableConfig" :enable-column-drag="true"
|
|
||||||
@column-drag-end="ymHandleColumnDragEnd">
|
|
||||||
</CustomTable>
|
|
||||||
<div class="btns">
|
|
||||||
<el-button type="primary" plain :size="autoSize">更换抗生素组</el-button>
|
|
||||||
<el-button type="primary" plain :size="autoSize">添加抗生素组</el-button>
|
|
||||||
<span>{{ ymTableData.length }}项</span>
|
|
||||||
</div>
|
|
||||||
</el-tab-pane>
|
|
||||||
<el-tab-pane label="专家评语" name="second">
|
|
||||||
<el-input v-model="textarea" style="width: 100%" :rows="20" type="textarea" />
|
|
||||||
</el-tab-pane>
|
|
||||||
</el-tabs>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import CustomTable from "@/components/elTable/index.vue";
|
|
||||||
import { classCom } from "@/utils/classCom";
|
|
||||||
const autoSize = classCom.useAutoSize();
|
|
||||||
const activeName = ref('first')
|
|
||||||
const textarea = ref('')
|
|
||||||
const tableData = ref([]);
|
|
||||||
|
|
||||||
const columns = ref([
|
|
||||||
{ label: "细菌/结果", prop: "instrid", align: 'center', visible: true },
|
|
||||||
{ label: "菌落计数", prop: "instrid", align: 'center', visible: true },
|
|
||||||
{ label: "检验结果", prop: "instrid", align: 'center', visible: true },
|
|
||||||
{ label: "阴阳性", prop: "instrid", align: 'center', visible: true },
|
|
||||||
{ label: "鉴定率", prop: "instrid", align: 'center', visible: true },
|
|
||||||
{ label: "危急值", prop: "instrid", align: 'center', visible: true },
|
|
||||||
{ label: "菌属", prop: "instrid", align: 'center', visible: true },
|
|
||||||
])
|
|
||||||
|
|
||||||
const tableConfig = ref({
|
|
||||||
height: '28vh',
|
|
||||||
border: true,
|
|
||||||
highlightCurrentRow: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
const handleColumnDragEnd = (data: any) => {
|
|
||||||
columns.value = data.columns;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ymTableData = ref([]);
|
|
||||||
|
|
||||||
const ymColumns = ref([
|
|
||||||
{ label: "抗生素", prop: "instrid", align: 'center', visible: true },
|
|
||||||
{ label: "Mic", prop: "instrid", align: 'center', visible: true },
|
|
||||||
{ label: "KB", prop: "instrid", align: 'center', visible: true },
|
|
||||||
{ label: "结果", prop: "instrid", align: 'center', visible: true },
|
|
||||||
{ label: "结果标志", prop: "instrid", align: 'center', visible: true },
|
|
||||||
{ label: "分组", prop: "instrid", align: 'center', visible: true },
|
|
||||||
{ label: "专家值", prop: "instrid", align: 'center', visible: true },
|
|
||||||
{ label: "折点", prop: "instrid", align: 'center', visible: true },
|
|
||||||
{ label: "引用说明", prop: "instrid", align: 'center', visible: true },
|
|
||||||
])
|
|
||||||
|
|
||||||
const ymTableConfig = ref({
|
|
||||||
height: '43vh',
|
|
||||||
border: true,
|
|
||||||
highlightCurrentRow: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
const ymHandleColumnDragEnd = (data: any) => {
|
|
||||||
ymColumns.value = data.columns;
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss"></style>
|
||||||
.btns {
|
|
||||||
margin-top: .625rem;
|
|
||||||
|
|
||||||
span {
|
|
||||||
color: #1f6dd3;
|
|
||||||
margin-left: 15px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@ -2,10 +2,86 @@
|
|||||||
<div>
|
<div>
|
||||||
<el-tabs v-model="activeName" type="card" class="demo-tabs">
|
<el-tabs v-model="activeName" type="card" class="demo-tabs">
|
||||||
<el-tab-pane label="鉴定(终报)结果" name="first">
|
<el-tab-pane label="鉴定(终报)结果" name="first">
|
||||||
<ZbReport />
|
<div>
|
||||||
|
<el-button class="btn_green" :size="aotuSize" v-if="labPat.jgbz != 2" @click="handleCheck(2)">审核</el-button>
|
||||||
|
<el-button class="btn_green" :size="aotuSize" v-if="labPat.jgbz == 2" @click="handleCheck(3)">取消审核</el-button>
|
||||||
|
<el-button class="btn_green" type="primary" :size="aotuSize" plain
|
||||||
|
:disabled="labPat.jgbz != null && labPat.jgbz != 0" @click="openItemDictDialog">新增</el-button>
|
||||||
|
<el-button class="btn_green" type="primary" :size="aotuSize"
|
||||||
|
:disabled="labPat.jgbz != null && labPat.jgbz != 0" plain @click="handleBatchDelete">删除</el-button>
|
||||||
|
</div>
|
||||||
|
<CustomTable ref="tableRef" :data="labResutsData" :columns="columns" :config="tableConfig"
|
||||||
|
:enable-column-drag="true" @column-drag-end="handleColumnDragEnd" @row-click="rowHandle">
|
||||||
|
<template #xmdh="{ row }">
|
||||||
|
{{ row.xmdh }} {{ row.xmmc }}
|
||||||
|
</template>
|
||||||
|
<template #od="{ row }">
|
||||||
|
<el-input v-model="row.od" v-if="labPat.jgbz == 0 || labPat.jgbz == null" size="small"
|
||||||
|
class="full-width-input" @change="handleCsjgEnter(row)" />
|
||||||
|
<span v-else>{{ row.od }}</span>
|
||||||
|
</template>
|
||||||
|
<template #csjg="{ row }">
|
||||||
|
<el-input v-model="row.csjg" v-if="labPat.jgbz == 0 || labPat.jgbz == null" size="small"
|
||||||
|
class="full-width-input" @change="handleCsjgEnter(row)" />
|
||||||
|
<span v-else>{{ row.csjg }}</span>
|
||||||
|
</template>
|
||||||
|
<template #jgbz="{ row }">
|
||||||
|
<el-select v-model="row.jgbz" class="full-width-input" v-if="labPat.jgbz == 0 || labPat.jgbz == null"
|
||||||
|
@change="handleCsjgEnter(row)">
|
||||||
|
<el-option label="阳性" value="P" />
|
||||||
|
<el-option label="阴性" value="N" />
|
||||||
|
</el-select>
|
||||||
|
<span v-else> {{ formatJgbz(row.jgbz) }}</span>
|
||||||
|
</template>
|
||||||
|
<template #cutoff="{ row }">
|
||||||
|
<el-input v-model="row.cutoff" v-if="labPat.jgbz == 0 || labPat.jgbz == null" size="small"
|
||||||
|
class="full-width-input" @change="handleCsjgEnter(row)" />
|
||||||
|
<span v-else>{{ row.cutoff }}</span>
|
||||||
|
</template>
|
||||||
|
<template #alarm_flag="{ row }">
|
||||||
|
<el-select v-model="row.alarm_flag" class="full-width-input" v-if="labPat.jgbz == 0 || labPat.jgbz == null"
|
||||||
|
@change="handleCsjgEnter(row)">
|
||||||
|
<el-option label="危急值" value="H" />
|
||||||
|
<el-option label="无" value="" />
|
||||||
|
</el-select>
|
||||||
|
<span v-else> {{ row.alarm_flag == 'H' ? '危急值' : '' }}</span>
|
||||||
|
</template>
|
||||||
|
<template #germclass="{ row }">
|
||||||
|
{{ formatDict(row.germclass, 'germclass') }}
|
||||||
|
</template>
|
||||||
|
</CustomTable>
|
||||||
|
|
||||||
|
<el-tabs v-model="activeName2" type="card" class="demo-tabs">
|
||||||
|
<el-tab-pane label="药敏结果" name="first">
|
||||||
|
<CustomTable :data="ymTableData" :columns="ymColumns" :config="ymTableConfig" :enable-column-drag="true"
|
||||||
|
@column-drag-end="ymHandleColumnDragEnd">
|
||||||
|
<template #ywdh="{ row }">
|
||||||
|
{{ row.ywdh }} {{ row.ywmc }}
|
||||||
|
</template>
|
||||||
|
<template #jgbz="{ row }">
|
||||||
|
<el-radio-group v-model="row.jgbz">
|
||||||
|
<el-radio value="R">R</el-radio>
|
||||||
|
<el-radio value="I">I</el-radio>
|
||||||
|
<el-radio value="S">S</el-radio>
|
||||||
|
<el-radio value="N">N</el-radio>
|
||||||
|
<el-radio value="SDD">SDD</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</template>
|
||||||
|
</CustomTable>
|
||||||
|
<div class="btns">
|
||||||
|
<el-button type="primary" plain :size="autoSize">更换抗生素组</el-button>
|
||||||
|
<el-button type="primary" plain :size="autoSize">添加抗生素组</el-button>
|
||||||
|
<span>{{ ymTableData.length }}项</span>
|
||||||
|
</div>
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane label="专家评语" name="second">
|
||||||
|
<el-input v-model="textarea" style="width: 100%" :rows="20" type="textarea"
|
||||||
|
@keyup.enter="handleTextareaEnter" />
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane label="初级和二级报告" name="second">
|
<el-tab-pane label="初级和二级报告" name="second">
|
||||||
<CbReport />
|
<CbReport :labResutsData="labResutsData" :labPat="labPat" />
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane label="培养基接种" name="third">
|
<el-tab-pane label="培养基接种" name="third">
|
||||||
<Byj />
|
<Byj />
|
||||||
@ -14,16 +90,28 @@
|
|||||||
<Record :labPat="labPat" :labPatKey="labPatKey" />
|
<Record :labPat="labPat" :labPatKey="labPatKey" />
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
|
<!-- 新增明细 -->
|
||||||
|
<ProjectDetails ref="itemDictRef" :dialog-title="'选择检验项目'" :tableKey="labPatKey" @select="handleItemSelect" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import ZbReport from './components/zbReport.vue';
|
import CustomTable from "@/components/elTable/index.vue";
|
||||||
|
import { classCom } from "@/utils/classCom";
|
||||||
import CbReport from './components/cbReport.vue';
|
import CbReport from './components/cbReport.vue';
|
||||||
import Byj from './components/byj.vue';
|
import Byj from './components/byj.vue';
|
||||||
import Record from './components/record.vue';
|
import Record from './components/record.vue';
|
||||||
|
import { getresultmedList, savetestResult, changeresult, saveresult, newresult, } from '@/api/liswork/micro/index';
|
||||||
|
import {
|
||||||
|
check1, check2, uncheck2, unconfirmlog, checkuser, reglimit, deleteresult, allPatquery, emrquery, datalink, changeLinkList,
|
||||||
|
viewBackup, queryXmVal, printListwork, getresultchangelog, setinputmdl, lockSample, unLockSample, clearnotComplete, clearPrintflag,
|
||||||
|
noiteMresult, queryXmInfo, setitemInter
|
||||||
|
} from "@/api/liswork/work/LisWork";
|
||||||
|
// @ts-ignore
|
||||||
|
import ProjectDetails from "@/components/projectDetails/index.vue";
|
||||||
|
import { ElMessage, ElMessageBox } from "element-plus";
|
||||||
|
import emitter from "@/utils/mitt";
|
||||||
|
const aotuSize = classCom.useAutoSize();
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
labPat: {
|
labPat: {
|
||||||
type: Object,
|
type: Object,
|
||||||
@ -34,11 +122,341 @@ const props = defineProps({
|
|||||||
type: Object,
|
type: Object,
|
||||||
default: () => { }
|
default: () => { }
|
||||||
},
|
},
|
||||||
|
labResutsData: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
},
|
||||||
|
dictData: {
|
||||||
|
type: Object,
|
||||||
|
default: () => { }
|
||||||
|
}
|
||||||
});
|
});
|
||||||
const { labPat, labPatKey } = toRefs(props);
|
const { labPat, labPatKey, labResutsData, dictData } = toRefs(props);
|
||||||
|
|
||||||
|
// 事件定义
|
||||||
|
const emits = defineEmits([
|
||||||
|
'fetchLabResults',
|
||||||
|
'changeStatus',
|
||||||
|
'previewHandle'
|
||||||
|
]);
|
||||||
|
|
||||||
const activeName = ref('first')
|
const activeName = ref('first')
|
||||||
|
|
||||||
|
|
||||||
|
const autoSize = classCom.useAutoSize();
|
||||||
|
const activeName2 = ref('first')
|
||||||
|
const textarea = ref('')
|
||||||
|
|
||||||
|
const columns = ref([
|
||||||
|
{ label: "细菌/结果", prop: "xmdh", align: 'center', visible: true, slot: 'xmdh', width: 150 },
|
||||||
|
{ label: "菌落计数", prop: "od", align: 'center', visible: true, slot: 'od' },
|
||||||
|
{ label: "检验结果", prop: "csjg", align: 'center', visible: true, slot: 'csjg' },
|
||||||
|
{ label: "阴阳性", prop: "jgbz", align: 'center', visible: true, slot: 'jgbz' },
|
||||||
|
{ label: "危急值", prop: "alarm_flag", align: 'center', visible: true, slot: 'alarm_flag' },
|
||||||
|
{ label: "菌属", prop: "germclass", align: 'center', visible: true, slot: 'germclass' },
|
||||||
|
{ label: "鉴定率", prop: "cutoff", align: 'center', visible: true, slot: 'cutoff' },
|
||||||
|
])
|
||||||
|
|
||||||
|
const CellStyleHd = ({ row, column, rowIndex, columnIndex }: {
|
||||||
|
row: any;
|
||||||
|
column: any;
|
||||||
|
rowIndex: number;
|
||||||
|
columnIndex: number;
|
||||||
|
}) => {
|
||||||
|
if (column.label == "细菌/结果" && (row.alarm_flag ?? "").trim().length > 0) {
|
||||||
|
return { background: '#f00 !important', color: '#FFF' };
|
||||||
|
}
|
||||||
|
if (column.label == "危急值" && (row.alarm_flag ?? "").trim().length > 0) {
|
||||||
|
return { background: '#f00 !important', color: '#FFF' };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (column.label == "检验结果" && row.jgbz == "H") {
|
||||||
|
return { background: '#ffc0c0 !important', color: '#606266' };
|
||||||
|
}
|
||||||
|
if (column.label == "检验结果" && row.jgbz == "L") {
|
||||||
|
return { background: '#8080ff !important', color: '#fff' };
|
||||||
|
}
|
||||||
|
if (column.label == "检验结果" && row.jgbz == "P") {
|
||||||
|
return { background: '#ffc0c0 !important', color: '#606266' };
|
||||||
|
}
|
||||||
|
if (column.label == "检验结果" && row.jgbz == "Q") {
|
||||||
|
return { background: '#ffff80 !important', color: '#606266' };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (column.label == "阴阳性" && row.jgbz == "H") {
|
||||||
|
return { background: '#ffc0c0 !important', color: '#606266' };
|
||||||
|
}
|
||||||
|
if (column.label == "阴阳性" && row.jgbz == "L") {
|
||||||
|
return { background: '#8080ff !important', color: '#fff' };
|
||||||
|
}
|
||||||
|
if (column.label == "阴阳性" && row.jgbz == "P") {
|
||||||
|
return { background: '#ffc0c0 !important', color: '#606266' };
|
||||||
|
}
|
||||||
|
if (column.label == "阴阳性" && row.jgbz == "Q") {
|
||||||
|
return { background: '#ffff80 !important', color: '#606266' };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const tableConfig = ref({
|
||||||
|
height: '28vh',
|
||||||
|
border: true,
|
||||||
|
highlightCurrentRow: true,
|
||||||
|
cellStyle: CellStyleHd
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleColumnDragEnd = (data: any) => {
|
||||||
|
columns.value = data.columns;
|
||||||
|
}
|
||||||
|
|
||||||
|
const unCheckshow = ref(false);
|
||||||
|
const reasonText = ref('');
|
||||||
|
const warningMsgdata = ref('');
|
||||||
|
const showuploadwarning = ref(false);
|
||||||
|
const handleCheck = (checkType: number) => {
|
||||||
|
// yhdh = checkuserid.value
|
||||||
|
switch (checkType) {
|
||||||
|
case 1: // 初审
|
||||||
|
check1({ ...labPatKey.value, yhdh: props.labPat.yhdh }).then((res: any) => {
|
||||||
|
emits("changeStatus", props.labPat);
|
||||||
|
})
|
||||||
|
break;
|
||||||
|
case 2: // 审核
|
||||||
|
labPatKey.value.problemId = 0
|
||||||
|
shHandleCheck()
|
||||||
|
break;
|
||||||
|
case 3: // 取消审核
|
||||||
|
labPatKey.value.problemId = 0
|
||||||
|
unShHandle()
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const shHandleCheck = () => {
|
||||||
|
check2({ ...labPatKey.value, yhdh: props.labPat.yhdh }).then((res: any) => {
|
||||||
|
emits("changeStatus", props.labPat);
|
||||||
|
if (res.code == "4" && res.problemId === 4) {
|
||||||
|
labPatKey.value.problemId = res.problemId;
|
||||||
|
warningMsgdata.value = res.msg;
|
||||||
|
showuploadwarning.value = true;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
const unShHandle = () => {
|
||||||
|
uncheck2({ ...labPatKey.value, yhdh: props.labPat.yhdh }).then((res: any) => {
|
||||||
|
if (res.code == "4") {
|
||||||
|
labPatKey.value.problemId = res.problemId;
|
||||||
|
reasonText.value = res.msg;
|
||||||
|
unCheckshow.value = true;
|
||||||
|
}
|
||||||
|
emits("changeStatus", props.labPat);
|
||||||
|
})
|
||||||
|
};
|
||||||
|
const uncheckFormRef = ref();
|
||||||
|
const uncheckForm = ref({
|
||||||
|
reason: '',
|
||||||
|
yhdh: '',
|
||||||
|
mm: '',
|
||||||
|
})
|
||||||
|
// 取消审核原因
|
||||||
|
const unconfirmlogConfirm = async () => {
|
||||||
|
if (labPatKey.value.problemId == 4) {
|
||||||
|
// if (!uncheckForm.value.inputValue) return ElMessage.warning("请输入操作原因")
|
||||||
|
} else if (labPatKey.value.problemId == 6) {
|
||||||
|
const valid = await uncheckFormRef.value.validate().catch(() => { });
|
||||||
|
if (!valid) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
unconfirmlog({ ...labPatKey.value, ...uncheckForm.value }).then((response: any) => {
|
||||||
|
if (response.code == "0") {
|
||||||
|
unCheckshow.value = false;
|
||||||
|
unShHandle();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
const itemDictRef = ref();
|
||||||
|
const openItemDictDialog = () => {
|
||||||
|
itemDictRef.value.openDictSelector();
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleItemSelect = async (selectedItem: any) => {
|
||||||
|
// 1. 构造新增行数据
|
||||||
|
const newRow = {
|
||||||
|
id: `temp_${Date.now()}_${Math.random().toString(36).substr(2, 8)}`,
|
||||||
|
xmdh: selectedItem.value,
|
||||||
|
xmmc: selectedItem.label,
|
||||||
|
dw: selectedItem.dw || "",
|
||||||
|
refs: selectedItem.refs || "",
|
||||||
|
jyrq: labPatKey.value.jyrq,
|
||||||
|
yq: labPatKey.value.yq,
|
||||||
|
ybh: labPatKey.value.ybh,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
addRowFromDict(newRow);
|
||||||
|
// ElMessage.success(`已新增项目:${newRow.xmmc}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
const selectedRows: any = ref([])
|
||||||
|
const tableRef = ref()
|
||||||
|
// 新增行核心方法:接收父组件传递的项目数据
|
||||||
|
const addRowFromDict = async (rowData: any) => {
|
||||||
|
if (!rowData.xmdh) return ElMessage.error("新增失败:项目编码不能为空");
|
||||||
|
|
||||||
|
const isDuplicate = labResutsData.value.some((item: any) => item.xmdh === rowData.xmdh);
|
||||||
|
if (isDuplicate) return ElMessage.warning(`项目【${rowData.xmmc}】已存在`);
|
||||||
|
|
||||||
|
const newRow = { ...rowData, csjg: "" };
|
||||||
|
labResutsData.value.push(newRow);
|
||||||
|
|
||||||
|
// 5. 自动聚焦
|
||||||
|
nextTick(() => {
|
||||||
|
selectedRows.value = [newRow];
|
||||||
|
tableRef.value.setCurrentRow(newRow);
|
||||||
|
tableRef.value.setScrollTo(labResutsData.value.length - 1)
|
||||||
|
// 聚焦到新行的输入框
|
||||||
|
const inputs = Array.from(document.querySelectorAll('.full-width-input .el-input__inner'))
|
||||||
|
.filter(el => el instanceof HTMLElement) as HTMLElement[];
|
||||||
|
if (inputs.length > 0) {
|
||||||
|
inputs[inputs.length - 1].focus();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const handleBatchDelete = () => {
|
||||||
|
if (selectedRows.value.length === 0) return ElMessage.warning("请先选择要删除的记录");
|
||||||
|
const arr = selectedRows.value.filter((row: any) => !row.id);
|
||||||
|
|
||||||
|
ElMessageBox.confirm(
|
||||||
|
`确定要删除选中的 ${selectedRows.value.length} 条记录吗?`,
|
||||||
|
'提示',
|
||||||
|
{
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
}
|
||||||
|
).then(() => {
|
||||||
|
if (arr.length == 0) {
|
||||||
|
const index = labResutsData.value.findIndex((item: any) => item.xmdh === selectedRows.value[0].xmdh);
|
||||||
|
if (index > -1) labResutsData.value.splice(index, 1);
|
||||||
|
selectedRows.value = [];
|
||||||
|
} else {
|
||||||
|
deleteresult(arr).then((res: any) => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
ElMessage.success('删除成功');
|
||||||
|
emits('fetchLabResults');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}).catch(() => {
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
watch(labResutsData, (newVal: any) => {
|
||||||
|
if (newVal.length) {
|
||||||
|
rowHandle(newVal[0])
|
||||||
|
textarea.value = newVal[0]?.textresult
|
||||||
|
} else {
|
||||||
|
textarea.value = ''
|
||||||
|
rowInfo.value = {}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const handleTextareaEnter = () => {
|
||||||
|
if (!rowInfo.value.xmdh) return
|
||||||
|
savetestResult({ ...rowInfo.value, textresult: textarea.value })
|
||||||
|
};
|
||||||
|
const rowInfo: any = ref({})
|
||||||
|
const rowHandle = (row: any) => {
|
||||||
|
rowInfo.value = row
|
||||||
|
const data = {
|
||||||
|
ybh: labPat.value.ybh,
|
||||||
|
yq: labPat.value.yq,
|
||||||
|
jyrq: labPat.value.jyrq,
|
||||||
|
xmdh: row.xmdh
|
||||||
|
}
|
||||||
|
getresultmedList(data).then((res: any) => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
ymTableData.value = res.data
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const ymTableData = ref([]);
|
||||||
|
|
||||||
|
const ymColumns = ref([
|
||||||
|
{ label: "抗生素(肠杆菌补充药物)", prop: "ywdh", visible: true, slot: 'ywdh', width: 150 },
|
||||||
|
{ label: "Mic", prop: "mic", align: 'center', visible: true, width: 60 },
|
||||||
|
{ label: "KB", prop: "rad", align: 'center', visible: true, width: 40 },
|
||||||
|
{ label: "结果", prop: "csjg", align: 'center', visible: true, width: 50 },
|
||||||
|
{ label: "结果标志", prop: "jgbz", align: 'center', visible: true, slot: 'jgbz', width: 230 },
|
||||||
|
{ label: "折点", prop: "ckz", align: 'center', visible: true },
|
||||||
|
{ label: "分组", prop: "bz", align: 'center', visible: true },
|
||||||
|
{ label: "专家值", prop: "txtresult", align: 'center', visible: true },
|
||||||
|
{ label: "引用说明", prop: "cp_bz", align: 'center', visible: true },
|
||||||
|
])
|
||||||
|
|
||||||
|
const ymTableConfig = ref({
|
||||||
|
height: '40vh',
|
||||||
|
border: true,
|
||||||
|
highlightCurrentRow: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
const ymHandleColumnDragEnd = (data: any) => {
|
||||||
|
ymColumns.value = data.columns;
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleCsjgEnter = async (row: any) => {
|
||||||
|
// 判断数据中包含模板新增的数据 flag
|
||||||
|
if (labResutsData.value.length == 0) return
|
||||||
|
const flag = labResutsData.value.some((item: any) => item.changeflag == 2)
|
||||||
|
if (flag) {
|
||||||
|
saveresult(labResutsData.value).then((res: any) => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
emitter.emit('wswSaveResult');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
if (!row) return
|
||||||
|
if (row && row.id) {
|
||||||
|
emitter.emit('wswSaveResult');
|
||||||
|
newresult(row).then((response: any) => {
|
||||||
|
ElMessage.success("结果保存成功");
|
||||||
|
emits('fetchLabResults');
|
||||||
|
}).catch((error: any) => {
|
||||||
|
emits('fetchLabResults');
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
changeresult(row).then((response: any) => {
|
||||||
|
ElMessage.success("结果保存成功");
|
||||||
|
emits('fetchLabResults');
|
||||||
|
}).catch((error: any) => {
|
||||||
|
emits('fetchLabResults');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// nextTick(() => {
|
||||||
|
// const input = document.activeElement;
|
||||||
|
// if (input?.tagName === "INPUT") input?.blur();
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const formatDict = (v: string, dictType: string) => {
|
||||||
|
return props.dictData[dictType]?.find((item: any) => item.value == v)?.label || v;
|
||||||
|
}
|
||||||
|
const formatJgbz = (v: string) => {
|
||||||
|
return v == 'H' ? '高' : v == 'L' ? '低' : v == 'N' ? '阴性' : v == 'P' ? '阳性' : v == 'Q' ? '弱阳性' : v == 'M' ? '正常' : ''
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -56,4 +474,27 @@ const activeName = ref('first')
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.btns {
|
||||||
|
margin-top: .625rem;
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: #1f6dd3;
|
||||||
|
margin-left: 15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.el-radio {
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn_green {
|
||||||
|
padding: .3125rem .625rem !important;
|
||||||
|
font-size: .875rem;
|
||||||
|
height: 1.25rem !important;
|
||||||
|
margin: 5px 0;
|
||||||
|
margin-left: .625rem !important;
|
||||||
|
border-radius: 0 !important;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
@ -123,14 +123,14 @@ import { comDict } from '@/utils/dict'
|
|||||||
import { queryLabPatList, queryLabResults, loadDefault, queryLabPat, instrdconfig, delSample, getGroupInstrdList } from "@/api/liswork/work/LisWork";
|
import { queryLabPatList, queryLabResults, loadDefault, queryLabPat, instrdconfig, delSample, getGroupInstrdList } from "@/api/liswork/work/LisWork";
|
||||||
import { getComDicts, queryComDictListService } from "@/api/liswork/dict/ComDict";
|
import { getComDicts, queryComDictListService } from "@/api/liswork/dict/ComDict";
|
||||||
import { ElMessage, ElMessageBox } from "element-plus";
|
import { ElMessage, ElMessageBox } from "element-plus";
|
||||||
import History from './history/index.vue'
|
import History from '../conponents/history/index.vue'
|
||||||
import Others from './others/index.vue'
|
import Others from '../conponents/others/index.vue'
|
||||||
import Reexamination from './reexamination/index.vue'
|
import Reexamination from '../conponents/reexamination/index.vue'
|
||||||
import Charge from './charge/index.vue'
|
import Charge from '../conponents/charge/index.vue'
|
||||||
import Combination from './combination/index.vue'
|
import Combination from '../conponents/combination/index.vue'
|
||||||
import Clinical from './clinical/index.vue'
|
import Clinical from '../conponents/clinical/index.vue'
|
||||||
import Sample from './sample/index.vue'
|
import Sample from '../conponents/sample/index.vue'
|
||||||
import ResultGraph from './resultGraph/index.vue'
|
import ResultGraph from '../conponents/resultGraph/index.vue'
|
||||||
import { getNextNumber, getPreviousNumber } from "@/utils/getNextNumber";
|
import { getNextNumber, getPreviousNumber } from "@/utils/getNextNumber";
|
||||||
import { useCommonStore } from '@/store/modules/commonStore';
|
import { useCommonStore } from '@/store/modules/commonStore';
|
||||||
import { classCom } from '@/utils/classCom';
|
import { classCom } from '@/utils/classCom';
|
||||||
@ -140,6 +140,7 @@ import BatchCode from './components/batchCode.vue';
|
|||||||
import { listUser } from '@/api/system/user.js'
|
import { listUser } from '@/api/system/user.js'
|
||||||
|
|
||||||
const aotuSize = classCom.useAutoSize();
|
const aotuSize = classCom.useAutoSize();
|
||||||
|
import { initWebSocket, sendWebSocketMessage, closeWebSocket, getWebSocketState } from '@/utils/webSocket';
|
||||||
|
|
||||||
const previewShow = ref(false);
|
const previewShow = ref(false);
|
||||||
const lbFlag = ref(false);
|
const lbFlag = ref(false);
|
||||||
@ -644,7 +645,46 @@ onMounted(async () => {
|
|||||||
HOS: toRaw(dictRefs.HOS.value) || [],
|
HOS: toRaw(dictRefs.HOS.value) || [],
|
||||||
ST: toRaw(dictRefs.ST.value) || [],
|
ST: toRaw(dictRefs.ST.value) || [],
|
||||||
};
|
};
|
||||||
|
// 初始化Socket
|
||||||
|
initSocket()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const initSocket = () => {
|
||||||
|
initWebSocket({
|
||||||
|
// fullUrl: `ws://47.97.125.165:8904/ws/instr/${mbStore.fingerprint}`,
|
||||||
|
fullUrl: `ws://192.168.1.151:9801/ws/instr/${mbStore.fingerprint}`,
|
||||||
|
onOpen: () => {
|
||||||
|
console.log('WebSocket连接成功');
|
||||||
|
},
|
||||||
|
onMessage: (data) => {
|
||||||
|
console.log(`收到消息: `, JSON.parse(data));
|
||||||
|
},
|
||||||
|
onError: (error) => {
|
||||||
|
console.log(`连接错误: ${error.type}`);
|
||||||
|
},
|
||||||
|
onClose: () => {
|
||||||
|
console.log('WebSocket连接已关闭');
|
||||||
|
},
|
||||||
|
reconnectInterval: 3000 // 重连间隔(毫秒)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 页面卸载时清理
|
||||||
|
onUnmounted(() => {
|
||||||
|
closeWebSocket();
|
||||||
|
});
|
||||||
|
|
||||||
|
// 发送消息
|
||||||
|
const sendMessage = () => {
|
||||||
|
const isSuccess = sendWebSocketMessage({ yq: queryParams.value.yq });
|
||||||
|
if (isSuccess) {
|
||||||
|
console.log(`发送消息`);
|
||||||
|
} else {
|
||||||
|
console.log('发送失败:连接未建立');
|
||||||
|
}
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user