基础组件封装

This commit is contained in:
wyuu 2025-09-29 17:30:02 +08:00
parent dafc6ea37a
commit bf34cd1ed4
13 changed files with 603 additions and 276 deletions

View File

@ -32,6 +32,7 @@
"pinyin-pro": "^3.26.0", "pinyin-pro": "^3.26.0",
"select2": "^4.1.0-rc.0", "select2": "^4.1.0-rc.0",
"socket.io-client": "^4.8.1", "socket.io-client": "^4.8.1",
"sortablejs": "^1.15.6",
"vue": "3.4.0", "vue": "3.4.0",
"vue-cropper": "1.1.1", "vue-cropper": "1.1.1",
"vue-plugin-hiprint": "^0.0.60", "vue-plugin-hiprint": "^0.0.60",

View File

@ -151,3 +151,12 @@ export function printsample(query?: Object) {
params: query params: query
}) })
} }
// 打印报告单
export function printListwork(query?: Object) {
return request({
url: '/liswork/print',
method: 'get',
params: query
})
}

View File

@ -177,11 +177,7 @@
border-right: 1px solid #1F6DD3 !important; border-right: 1px solid #1F6DD3 !important;
} }
/* 在你的全局样式文件中 */
.el-input__wrapper {
border-color: #96B8D9 !important;
// background-color: #f00;
}
.vxe-table { .vxe-table {
border: 1px solid #96B8D9 !important; border: 1px solid #96B8D9 !important;
@ -189,11 +185,45 @@
border-radius: 8px; border-radius: 8px;
/* 可选:添加边框圆角 */ /* 可选:添加边框圆角 */
overflow: hidden; overflow: hidden;
} }
:deep(.el-input__wrapper) {
// border-color: #96B8D9 !important;
// border-color: #f00 !important;
}
.el-input__wrapper,
.el-select__wrapper {
box-shadow: 0 0 0 1px #96B8D9 inset;
.is-focus {
box-shadow: 0 0 0 1px #1f6dd3 inset !important;
}
&:hover {
box-shadow: 0 0 0 1px #1f6dd3 inset !important;
}
}
.el-date-editor.el-input__wrapper {
box-shadow: 0 0 0 1px #96B8D9 inset;
.is-focus {
box-shadow: 0 0 0 1px #1f6dd3 inset !important;
}
&:hover {
box-shadow: 0 0 0 1px #1f6dd3 inset !important;
}
}
.mytable-style { .mytable-style {
.vxe-header--column { .vxe-header--column {
word-break: break-word; word-break: break-word;

View File

@ -1,7 +1,7 @@
<!-- <!--
* SelectTable 下拉表格组件 * SelectTable 下拉表格组件
* @author: Goal * @author: w
* @since: 2023-11-13 * @since: 2025-9-28
* SelectTable.vue * SelectTable.vue
* *
* 属性(带有[Required]为必填属性) * 属性(带有[Required]为必填属性)
@ -17,26 +17,41 @@
--> -->
<template> <template>
<div> <div>
<el-select ref="selectTable" v-model="state.selectShowValue" :placeholder="props.placeholder" :size="props.size"> <el-select ref="selectTable" v-model="selectShowValue" :placeholder="props.placeholder" :size="props.size"
:style="{ width: props.width }" @visible-change="visibleChange" @clear="clearHandle" clearable>
<template #empty> <template #empty>
<el-table :data="props.tableData" :highlight-current-row="props.isHighlight" style="width: 100%" <div class="select-table-dropdown">
:size="props.size" :border="props.border" @current-change="handleCurrentChange"> <div style="text-align: left;">
<el-input v-model="searchKey" ref="searchInput" size="small" placeholder="快速搜索(支持简拼)" class="mb10" clearable
@clear="filterDataHandle" @input="filterDataHandle" />
</div>
<!-- 数据为空时显示空状态提示 -->
<el-empty v-if="filterData.length === 0" description="没有匹配的数据" :image-size="100" />
<!-- 数据存在时显示表格 -->
<el-table ref="tableRef" v-else :data="filterData" :highlight-current-row="props.isHighlight"
style="width: 100%" :border="props.border" @row-click="handleRowChange" max-height="350px">
<el-table-column v-for="field in props.fields" :prop="field.prop" :label="field.label" :width="field.width" <el-table-column v-for="field in props.fields" :prop="field.prop" :label="field.label" :width="field.width"
:show-overflow-tooltip="field.showTooltip" /> :show-overflow-tooltip="field.showTooltip" align="center" />
</el-table> </el-table>
</div>
</template> </template>
</el-select> </el-select>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { reactive, ref, onMounted } from "vue"; import { reactive, ref, onMounted, watch, nextTick } from "vue";
// @ts-ignore
import { getFirstLetter } from '@/api/pinyin.js';
import { ElEmpty } from 'element-plus';
interface Field { interface Field {
prop: string; prop: string;
label: string; label: string;
width: number; width: number;
showTooltip?: boolean; showTooltip?: boolean;
enablePinyinSearch?: boolean; //是否参与拼音搜索
} }
interface Props { interface Props {
@ -50,103 +65,154 @@ interface Props {
size?: string; size?: string;
placeholder?: string; placeholder?: string;
border?: boolean; border?: boolean;
width?: string | number;
} }
const props = withDefaults(defineProps < Props > (), { const props = withDefaults(defineProps<Props>(), {
placeholder: "请选择", placeholder: "请选择",
size: "default", size: "default",
isHighlight: true, isHighlight: true,
value: undefined, value: undefined,
label: undefined, label: undefined,
border: false, border: false,
width: "100%",
}); });
interface Emits { interface Emits {
(e: "update:data", val: any): void; (e: "update:data", val: any): void;
(e: "getDataValue", val: any): void;
} }
const emits = defineEmits<Emits>();
const emits = defineEmits < Emits > (); const searchKey = ref('');
const tableRef = ref();
onMounted(() => {
//处理数据回显
// debugger;
if (props.data !== null) {
// 配置label则显示label
if (typeof props.label !== "undefined") {
// 配置了value属性,则找到与value属性值一样的表格行对象,将配置的label回显到下拉框
if (typeof props.value !== "undefined") {
let row = props.tableData.find(
(item) => item[props.value] === props.data
);
state.selectShowValue =
typeof row === "undefined" ? props.data : row[props.label];
// 配置了objKey属性,则找到与objKey属性值一样的表格行对象,将配置的label回显到下拉框
} else if (typeof props.objKey !== "undefined") {
let row = props.tableData.find(
(item) => item[props.objKey] === props.data[props.objKey]
);
state.selectShowValue =
typeof row === "undefined"
? props.data[props.objKey]
: row[props.label];
}
//没有配置label属性则回显value或者objKey
} else {
// 配置了value属性,则找到与value属性值一样的表格行对象,将配置的label回显到下拉框
if (typeof props.value !== "undefined") {
let row = props.tableData.find(
(item) => item[props.value] === props.data
);
state.selectShowValue =
typeof row === "undefined" ? props.data : row[props.value];
// 配置了objKey属性,则找到与objKey属性值一样的表格行对象,将配置的label回显到下拉框
} else if (typeof props.objKey !== "undefined") {
let row = props.tableData.find(
(item) => item[props.objKey] === props.data
);
state.selectShowValue =
typeof row === "undefined" ? props.data : row[props.objKey];
}
}
}
});
const selectTable = ref(); const selectTable = ref();
const selectShowValue = ref('');
const searchInput = ref();
const filterData = ref<{ [key: string]: any; pinyinMap: Record<string, string> }[]>([]);
// 存储预处理后的带拼音数据
const processedTableData = ref<{ [key: string]: any; pinyinMap: Record<string, string> }[]>([]);
const state = reactive({ // 预处理数据:生成拼音信息
selectValue: null, const processTableData = (data: object[]) => {
selectShowValue: null, return data.map((item: any) => {
const pinyinMap: Record<string, string> = {};
// 处理label字段拼音
if (item[props.label!]) {
pinyinMap.label = getFirstLetter(item[props.label!]).toLowerCase();
}
// 处理value字段拼音
if (props.value && item[props.value]) {
pinyinMap.value = getFirstLetter(String(item[props.value])).toLowerCase();
}
// 处理其他指定字段拼音
props.fields.forEach(field => {
if (field.enablePinyinSearch && item[field.prop]) {
pinyinMap[field.prop] = getFirstLetter(item[field.prop]).toLowerCase();
}
});
return { ...item, pinyinMap };
});
};
// 隐藏显示处理
const visibleChange = (val: any) => {
searchKey.value = '';
if (val) {
nextTick(() => {
searchInput.value.focus();
});
}
filterDataHandle()
};
// 初始化数据
onMounted(() => {
processedTableData.value = processTableData(props.tableData);
filterData.value = [...processedTableData.value];
}); });
/** // 监听表格数据变化,重新处理
* 点击当前行事件 watch(() => props.tableData, (newVal) => {
* @param val processedTableData.value = processTableData(newVal);
*/ // 数据回显
const handleCurrentChange = (val: any) => { handleDataEcho();
// 如果没有配置label则显示value或者objKey }, { deep: true });
setLabel(val);
// 设置双向绑定值 // 数据回显处理
if (typeof props.value !== "undefined") { const handleDataEcho = () => {
emits("update:data", val[props.value]); if (props.data === null || props.data === undefined) return;
} else { // 查找匹配的行数据
emits("update:data", val); const row: any = props.tableData.find((item: any) => props.objKey && item[props.objKey] === props.data)
selectShowValue.value = row ? (props.label ? row[props.label] : (props.value ? row[props.value] : '')) : '';
};
// 搜索过滤逻辑
const filterDataHandle = () => {
const key = searchKey.value.trim().toLowerCase();
if (!key) {
// 空搜索时显示全部预处理数据
filterData.value = [...processedTableData.value];
return;
} }
selectTable.value.blur();
filterData.value = processedTableData.value.filter((item: any) => {
// 1. 原文本匹配
const matchLabel = props.label && item[props.label]?.toString().toLowerCase().includes(key);
const matchValue = props.value && item[props.value]?.toString().toLowerCase().includes(key);
// 2. 拼音匹配
const matchLabelPinyin = props.label && item.pinyinMap.label?.includes(key);
const matchValuePinyin = props.value && item.pinyinMap.value?.includes(key);
// 3. 其他字段匹配
let matchOtherField = false;
props.fields.forEach(field => {
if (field.enablePinyinSearch) {
const textMatch = item[field.prop]?.toString().toLowerCase().includes(key);
const pinyinMatch = item.pinyinMap[field.prop]?.includes(key);
if (textMatch || pinyinMatch) {
matchOtherField = true;
}
}
});
return matchLabel || matchValue || matchLabelPinyin || matchValuePinyin || matchOtherField;
});
};
const handleRowChange = (val: any) => {
setLabel(val);
emits("update:data", props.value ? val[props.value] : val);
}; };
const setLabel = (val: any) => { const setLabel = (val: any) => {
// 如果没有配置label则显示value或者objKey if (props.label) {
if (typeof props.label === "undefined") { selectShowValue.value = val[props.label];
// 如果配置了value,则显示value } else if (props.value) {
if (typeof props.value !== "undefined") { selectShowValue.value = val[props.value];
state.selectShowValue = val[props.value];
} else if (typeof props.objKey !== "undefined") {
//没有配置value但配置了objKey,则显示objKey
state.selectShowValue = val[props.objKey];
} }
} else { if (props.objKey) {
state.selectShowValue = val[props.label]; emits('getDataValue', val[props.objKey]);
} }
selectTable.value.blur();
};
// 清空值
const clearHandle = () => {
selectShowValue.value = '';
emits("update:data", null);
emits('getDataValue', null);
}; };
</script> </script>
<style scoped></style> <style scoped>
.select-table-dropdown {
padding: 8px;
}
:deep(.el-table .el-table__cell) {
padding: 0;
}
</style>

View File

@ -1,10 +1,6 @@
<template> <template>
<div v-loading="loading" :style="'height:' + height"> <div v-loading="loading" :style="'height:' + height">
<iframe <iframe :src="url" frameborder="no" style="width: 100%; height: 100%" scrolling="auto" />
:src="url"
frameborder="no"
style="width: 100%; height: 100%"
scrolling="auto" />
</div> </div>
</template> </template>

View File

@ -7,30 +7,34 @@
:header-cell-style="config.headerCellStyle" :cell-style="config.cellStyle" :max-height="config.maxHeight" :header-cell-style="config.headerCellStyle" :cell-style="config.cellStyle" :max-height="config.maxHeight"
:height="config.height" :size="config.size || 'default'" :empty-text="config.emptyText || '暂无数据'" :height="config.height" :size="config.size || 'default'" :empty-text="config.emptyText || '暂无数据'"
@selection-change="handleSelectionChange" @current-change="handleCurrentChange" @row-click="handleRowClick" @selection-change="handleSelectionChange" @current-change="handleCurrentChange" @row-click="handleRowClick"
@row-dblclick="handleRowDblclick" @sort-change="handleSortChange" v-bind="$attrs"> header-cell-class-name="el-table-header-cell" @row-dblclick="handleRowDblclick" @sort-change="handleSortChange"
<!-- 多选列 --> v-bind="$attrs">
<el-table-column v-if="config.selection" type="selection" :width="config.selectionWidth || 55"
:fixed="config.selectionFixed" align="center" />
<!-- 序号列 -->
<el-table-column v-if="config.index" type="index" :label="config.indexLabel || '序号'"
:width="config.indexWidth || 60" :fixed="config.indexFixed" align="center" :index="getIndex" />
<!-- 动态列 --> <!-- 动态列 -->
<template v-for="item in columns" :key="item.prop || item.key"> <template v-for="item in columns" :key="item.prop ">
<!-- 多选列 -->
<el-table-column v-if="item.type == 'selection' && item.visible" type="selection" :width="item.width || 55"
:fixed="item.fixed" :align="item.align || 'left'" />
<!-- 序号列 -->
<el-table-column v-if="item.type == 'index' && item.visible" type="index" class-name="el-table-column--index"
:label="item.label || '序号'" :width="item.width || 60" :fixed="item.fixed" :align="item.align || 'left'"
:index="getIndex" />
<!-- 自定义插槽列 行数据插槽(有row属性) --> <!-- 自定义插槽列 行数据插槽(有row属性) -->
<el-table-column v-if="item.slot && item.visible" :prop="item.prop" :label="item.label" :width="item.width" <el-table-column v-if="!item.type && item.slot && item.visible" :prop="item.prop" :label="item.label"
:min-width="item.minWidth" :fixed="item.fixed" :align="item.align || 'left'" :sortable="item.sortable" :width="item.width" :min-width="item.minWidth" :fixed="item.fixed" :align="item.align || 'left'"
:show-overflow-tooltip="item.showOverflowTooltip !== false"> :sortable="item.sortable" :show-overflow-tooltip="item.showOverflowTooltip !== false">
<template #default="scope"> <template #default="scope">
<slot :name="item.slot" :row="scope.row" /> <slot :name="item.slot" :row="scope.row" />
</template> </template>
</el-table-column> </el-table-column>
<!-- 普通列 --> <!-- 普通列 -->
<el-table-column v-if="!item.slot && item.visible" :prop="item.prop" :label="item.label" :width="item.width" <el-table-column v-if="!item.type && !item.slot && item.visible" :prop="item.prop" :label="item.label"
:min-width="item.minWidth" :fixed="item.fixed" :align="item.align || 'left'" :sortable="item.sortable" :width="item.width" :min-width="item.minWidth" :fixed="item.fixed" :align="item.align || 'left'"
:show-overflow-tooltip="item.showOverflowTooltip !== false" :formatter="item.formatter"> :sortable="item.sortable" :show-overflow-tooltip="item.showOverflowTooltip !== false"
:formatter="item.formatter">
<!-- 表头插槽 (无row属性)--> <!-- 表头插槽 (无row属性)-->
<template v-if="item.headerSlot" #header="scope"> <template v-if="item.headerSlot" #header="scope">
<slot :name="item.headerSlot" :column="scope.column" :$index="scope.$index" /> <slot :name="item.headerSlot" :column="scope.column" :$index="scope.$index" />
@ -65,10 +69,13 @@
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { computed, ref, watch, PropType } from "vue"; import { computed, ref, watch, PropType, onMounted } from "vue";
import { TableColumnCtx } from 'element-plus'; import { TableColumnCtx } from 'element-plus';
// @ts-ignore
import Sortable from 'sortablejs'; // 引入sortablejs
interface TableColumn { interface TableColumn {
prop?: string; prop?: string;
type?: string; // 'selection' | 'index' | undefined
key?: string | number; key?: string | number;
label?: string; label?: string;
width?: string | number; width?: string | number;
@ -121,6 +128,11 @@ const props = defineProps({
currentPage: 1, currentPage: 1,
}), }),
}, },
// 拖拽列
enableColumnDrag: {
type: Boolean,
default: false
}
}); });
@ -134,6 +146,7 @@ const emit = defineEmits([
"sort-change", "sort-change",
"page-change", "page-change",
"size-change", "size-change",
"column-drag-end",
]); ]);
// 响应式数据 // 响应式数据
@ -160,6 +173,13 @@ const getIndex = (index: number) => {
return index + 1; return index + 1;
}; };
// const headerCellClassName = (column: TableColumnCtx<any>) => {
// if (!column.column.property) {
// return ''; // 不添加类名
// } else {
// return 'el-table-header-cell'; // 添加自定义类名
// }
// };
// 事件处理 // 事件处理
const handleSelectionChange = (selection: any[]) => { const handleSelectionChange = (selection: any[]) => {
emit("selection-change", selection); emit("selection-change", selection);
@ -198,6 +218,17 @@ const handleCurrentPageChange = (page: number) => {
}); });
}; };
// 初始化列拖拽功能
onMounted(() => {
if (props.enableColumnDrag && tableRef.value) {
initColumnDrag();
}
});
// 监听分页配置变化 // 监听分页配置变化
watch( watch(
() => props.pagination.currentPage, () => props.pagination.currentPage,
@ -208,6 +239,8 @@ watch(
}, },
); );
watch( watch(
() => props.pagination.pageSize, () => props.pagination.pageSize,
(newVal) => { (newVal) => {
@ -217,6 +250,53 @@ watch(
}, },
); );
// 初始化列拖拽
const initColumnDrag = () => {
// 获取表头单元格
const tableHeader = tableRef.value.$el.querySelector('.el-table__header-wrapper thead tr');
console.log('tableHeader==>', tableHeader);
if (!tableHeader) return;
// 初始化拖拽
const sortable = new Sortable(tableHeader, {
animation: 150, // 动画时间
handle: '.el-table-header-cell', // 拖拽手柄
ghostClass: 'sortable-ghost', // 拖拽时的占位符样式
// filter: '.el-table-column--selection, .el-table-column--index', // 排除选择列和序号列
onEnd: (evt: any) => {
console.log('evt==>', evt);
// 排除固定列和选择列、序号列
const visibleColumns = props.columns.filter(col => col.visible !== false);
// 过滤掉固定列
const draggableColumns = visibleColumns.filter(col => !col.fixed);
// 如果发生了位置变化
if (evt.oldIndex !== evt.newIndex && draggableColumns.length) {
// 复制原数组并调整顺序
const newColumns = [...draggableColumns];
const [movedItem] = newColumns.splice(evt.oldIndex, 1);
newColumns.splice(evt.newIndex, 0, movedItem);
// 更新原始columns数组中对应列的位置
const updatedColumns = [...props.columns];
// 先移除所有可拖拽列
const nonDraggableColumns = updatedColumns.filter(col => col.fixed);
// 合并固定列和新顺序的可拖拽列
const resultColumns = nonDraggableColumns.concat(newColumns);
// 触发事件,通知父组件列顺序已改变
emit('column-drag-end', {
oldIndex: evt.oldIndex,
newIndex: evt.newIndex,
columns: resultColumns
});
}
}
});
};
// 暴露方法 // 暴露方法
const clearSelection = () => { const clearSelection = () => {
tableRef.value?.clearSelection(); tableRef.value?.clearSelection();
@ -256,6 +336,7 @@ defineExpose({
doLayout, doLayout,
sort, sort,
tableRef, tableRef,
initColumnDrag
}); });
</script> </script>
@ -264,6 +345,17 @@ defineExpose({
width: 100%; width: 100%;
} }
// 拖拽相关样式
:deep(.sortable-ghost) {
opacity: 0.5;
background-color: #e5e7eb;
}
:deep(.el-table-header-cell) {
cursor: move;
user-select: none;
}
.pagination-wrapper { .pagination-wrapper {
display: flex; display: flex;
align-items: center; align-items: center;

View File

@ -76,7 +76,8 @@
</el-row> </el-row>
<CustomTable ref="tableRef" :data="tableData" :columns="columns" :config="tableConfig" :loading="loading" <CustomTable ref="tableRef" :data="tableData" :columns="columns" :config="tableConfig" :loading="loading"
@row-click="rowHandle" @selection-change="selectionChange"> @row-click="rowHandle" @selection-change="selectionChange" :enable-column-drag="true"
@column-drag-end="handleColumnDragEnd">
<template #dy="{ row }"> <template #dy="{ row }">
{{ row.zt != 1 ? '✅' : '❌' }} {{ row.zt != 1 ? '✅' : '❌' }}
</template> </template>
@ -234,26 +235,28 @@ const loading = ref(true);
const tableData = ref([]) const tableData = ref([])
// 配置项 // 配置项
const columns = ref([ const columns = ref([
{ prop: 'zt', label: '打印', visible: true, key: 0, sortable: true, slot: 'dy', }, { type: 'selection', visible: true, align: 'center', width: 55, label: '多选框' },
{ prop: 'ch', label: '床号', visible: true, key: 0, sortable: true, }, // { type: 'index', visible: true, align: 'center', width: 60, label: '序号' },
{ prop: 'brxm', label: '姓名', visible: true, key: 1, }, { prop: 'zt', label: '打印', visible: true, align: 'center', slot: 'dy', },
{ prop: 'brxbname', label: '性别', align: 'center', visible: true, key: 2, }, { prop: 'ch', label: '床号', visible: true, align: 'center', sortable: true, },
{ prop: 'jymd', label: '项目名称', align: 'center', visible: true, key: 3, width: '140px' }, { prop: 'brxm', label: '姓名', align: 'center', visible: true, },
{ prop: 'bgddhname', label: '类别', align: 'center', visible: true, key: 4, width: '120px' }, { prop: 'brxbname', label: '性别', align: 'center', visible: true, },
{ prop: 'sampletips', label: '采样提示', align: 'center', visible: true, key: 5, width: '110px' }, { prop: 'jymd', label: '项目名称', align: 'center', visible: true, width: '140px' },
{ prop: 'jzbz', label: '急诊', align: 'center', visible: true, slot: 'jzbz', key: 6, width: '110px' }, { prop: 'bgddhname', label: '类别', align: 'center', visible: true, width: '120px' },
{ prop: 'yblx', label: '样本类型', align: 'center', visible: true, key: 7, width: '110px' }, { prop: 'sampletips', label: '采样提示', align: 'center', visible: true, width: '110px' },
{ prop: 'brdh', label: '病人号', align: 'center', visible: true, key: 8, width: '110px' }, { prop: 'jzbz', label: '急诊', align: 'center', visible: true, slot: 'jzbz', width: '110px' },
{ prop: 'ksname', label: '科室名称', align: 'center', visible: true, key: 9, width: '110px' }, { prop: 'yblx', label: '样本类型', align: 'center', visible: true, width: '110px' },
{ prop: 'sqh', label: '申请号/条码', align: 'center', visible: true, key: 10, width: '110px' }, { prop: 'brdh', label: '病人号', align: 'center', visible: true, width: '110px' },
{ prop: 'zt', label: '状态', align: 'center', visible: true, key: 11, slot: 'zt', width: '110px' }, { prop: 'ksname', label: '科室名称', align: 'center', visible: true, width: '110px' },
{ prop: 'brly', label: '病人来源', align: 'center', visible: true, key: 12, slot: 'brly', width: '110px' }, { prop: 'sqh', label: '申请号/条码', align: 'center', visible: true, width: '110px' },
{ prop: 'sqysname', label: '申请医生', align: 'center', visible: true, key: 13, width: '110px' }, { prop: 'zt', label: '状态', align: 'center', visible: true, slot: 'zt', width: '110px' },
{ prop: 'sqsj', label: '申请时间', align: 'center', visible: true, key: 14, width: '170px' }, { prop: 'brly', label: '病人来源', align: 'center', visible: true, slot: 'brly', width: '110px' },
{ prop: 'jjzt', label: '计价标志', align: 'center', visible: true, key: 15, slot: 'jjzt', }, { prop: 'sqysname', label: '申请医生', align: 'center', visible: true, width: '110px' },
{ prop: 'zxysname', label: '执行医生', align: 'center', visible: true, key: 16, }, { prop: 'sqsj', label: '申请时间', align: 'center', visible: true, width: '170px' },
{ prop: 'bbsjrname', label: '送检人', align: 'center', visible: true, key: 17, }, { prop: 'jjzt', label: '计价标志', align: 'center', visible: true, slot: 'jjzt', },
{ prop: 'yljg', label: '医疗机构', align: 'center', visible: true, slot: 'yljg', key: 18, width: '170px' }, { prop: 'zxysname', label: '执行医生', align: 'center', visible: true, },
{ prop: 'bbsjrname', label: '送检人', align: 'center', visible: true, },
{ prop: 'yljg', label: '医疗机构', align: 'center', visible: true, slot: 'yljg', width: '170px' },
]) ])
const single = ref(true); const single = ref(true);
@ -299,12 +302,19 @@ const selectionChange = (selection: any) => {
multiple.value = !selection.length; multiple.value = !selection.length;
} }
const handleColumnDragEnd = (data: any) => {
// 更新列配置
columns.value = data.columns;
// 可以在这里保存列顺序到本地存储等
// localStorage.setItem('tableColumnOrder', JSON.stringify(data.columns));
};
// 左侧表格配置 // 左侧表格配置
const tableConfig = ref({ const tableConfig = ref({
// stripe: true, // 斑马纹 // stripe: true, // 斑马纹
border: false, // 边框 border: true, // 边框
selection: true, // 多选框
index: false, // 序号 index: true, // 序号
height: '', // 高度 height: '', // 高度
highlightCurrentRow: true, // 高亮当前行 highlightCurrentRow: true, // 高亮当前行
cellStyle: cellStyleHd, cellStyle: cellStyleHd,
@ -315,20 +325,20 @@ const tableConfig = ref({
const rightTableData = ref([]) const rightTableData = ref([])
// 配置项 // 配置项
const rightColumns = ref([ const rightColumns = ref([
{ prop: 'sqxmdh', label: '项目代号', visible: true, key: 0, sortable: true, width: '110px' }, { prop: 'sqxmdh', label: '项目代号', visible: true, sortable: true, width: '110px' },
{ prop: 'sqxmmc', label: '项目名称', visible: true, key: 1, width: '120px' }, { prop: 'sqxmmc', label: '项目名称', visible: true, width: '120px' },
{ prop: 'dj', label: '单价', align: 'center', visible: true, key: 2 }, { prop: 'dj', label: '单价', align: 'center', visible: true, },
{ prop: 'sl', label: '数量', align: 'center', visible: true, key: 3 }, { prop: 'sl', label: '数量', align: 'center', visible: true, },
{ prop: 'zt', label: '状态', align: 'center', visible: true, slot: 'zt', key: 4 }, { prop: 'zt', label: '状态', align: 'center', visible: true, slot: 'zt', },
{ prop: 'jjzt', label: '计价标志', align: 'center', visible: true, slot: 'jjzt', key: 5 }, { prop: 'jjzt', label: '计价标志', align: 'center', visible: true, slot: 'jjzt', },
]) ])
// 表格配置 // 表格配置
const rightTableConfig = ref({ const rightTableConfig = ref({
// stripe: true, // 斑马纹 // stripe: true, // 斑马纹
border: false, // 边框 border: false, // 边框
// selection: true, // 多选框 //
index: false, // 序号
height: '', // 高度 height: '', // 高度
highlightCurrentRow: true, // 高亮当前行 highlightCurrentRow: true, // 高亮当前行
}) })
@ -337,26 +347,24 @@ const rightTableConfig = ref({
const cyTableData = ref([]) const cyTableData = ref([])
// 配置项 // 配置项
const cyColumns = ref([ const cyColumns = ref([
{ prop: 'sqh', label: '申请号/条形码', visible: true, key: 0, sortable: true, width: '140px' }, { prop: 'sqh', label: '申请号/条形码', align: 'center', visible: true, sortable: true, width: 140 },
{ prop: 'ksdh', label: '科室病区', visible: true, key: 1, width: '120px' }, { prop: 'ksdh', label: '科室病区', align: 'center', visible: true, width: 120 },
{ prop: 'ch', label: '床号', visible: true, key: 2, sortable: true, }, { prop: 'ch', label: '床号', align: 'center', visible: true, sortable: true, },
{ prop: 'brxm', label: '姓名', visible: true, key: 3, }, { prop: 'brxm', label: '姓名', align: 'center', visible: true, },
{ prop: 'brdh', label: '病人号', visible: true, key: 4, }, { prop: 'brdh', label: '病人号', align: 'center', visible: true, },
{ prop: 'brxb', label: '性别', align: 'center', visible: true, key: 5, }, { prop: 'brxb', label: '性别', align: 'center', visible: true, },
{ prop: 'yblx', label: '样本类型', align: 'center', visible: true, key: 6 }, { prop: 'yblx', label: '样本类型', align: 'center', visible: true, },
{ prop: 'zt', label: '状态', align: 'center', visible: true, slot: 'zt', key: 7 }, { prop: 'zt', label: '状态', align: 'center', visible: true, slot: 'zt', },
{ prop: 'jzbz', label: '急诊', align: 'center', visible: true, key: 8 }, { prop: 'jzbz', label: '急诊', align: 'center', visible: true, },
{ prop: 'jjzt', label: '采样人', align: 'center', visible: true, key: 8 }, { prop: 'jjzt', label: '采样人', align: 'center', visible: true, },
{ prop: 'cysj', label: '采样时间', align: 'center', visible: true, key: 8 }, { prop: 'cysj', label: '采样时间', align: 'center', visible: true, },
{ prop: 'zxysname', label: '执行医生', align: 'center', visible: true, key: 8 }, { prop: 'zxysname', label: '执行医生', align: 'center', visible: true, },
{ prop: 'zxsj', label: '执行时间', align: 'center', visible: true, key: 8 }, { prop: 'zxsj', label: '执行时间', align: 'center', visible: true, },
]) ])
// 表格配置 // 表格配置
const cyTableConfig = ref({ const cyTableConfig = ref({
// stripe: true, // 斑马纹 // stripe: true, // 斑马纹
border: false, // 边框 border: false, // 边框
selection: true, // 多选框
index: false, // 序号
height: '100%', // 高度 height: '100%', // 高度
highlightCurrentRow: true, // 高亮当前行 highlightCurrentRow: true, // 高亮当前行
}) })

View File

@ -320,8 +320,8 @@ const tableConfig = ref(
{ {
// stripe: true, // 斑马纹 // stripe: true, // 斑马纹
border: true, // 边框 border: true, // 边框
selection: true, // 多选框
index: false, // 序号
height: '', // 高度 height: '', // 高度
highlightCurrentRow: true, // 高亮当前行 highlightCurrentRow: true, // 高亮当前行
fit: true, fit: true,
@ -392,7 +392,7 @@ const rightTableConfig = ref(
// stripe: true, // 斑马纹 // stripe: true, // 斑马纹
border: true, // 边框 border: true, // 边框
selection: false, // 多选框 selection: false, // 多选框
index: false, // 序号
height: '40vh', // 高度 height: '40vh', // 高度
highlightCurrentRow: true, // 高亮当前行 highlightCurrentRow: true, // 高亮当前行
} }
@ -647,7 +647,7 @@ const bottomTableConfig = ref(
// stripe: true, // 斑马纹 // stripe: true, // 斑马纹
border: true, // 边框 border: true, // 边框
selection: false, // 多选框 selection: false, // 多选框
index: false, // 序号
height: '37vh', // 高度 height: '37vh', // 高度
highlightCurrentRow: true, // 高亮当前行 highlightCurrentRow: true, // 高亮当前行
} }

View File

@ -1,24 +1,37 @@
<template> <template>
<div> <div>
<!-- <h3>浏览器指纹识别</h3> <SelectTable v-model:data="query" :fields="fields" :tableData="tableData" label="name" objKey="id" :border="true"
:width="'300px'" placeholder="请选择指定项" @getDataValue="getDataValue" />
<div v-if="loading">
<p>正在获取指纹信息...</p>
</div>
<div v-if="error" class="error-message">
<p>获取失败: {{ error.message }}</p>
</div>
<div v-if="fingerprint && !loading && !error" class="fingerprint-result">
<p>您的浏览器指纹: {{ fingerprint }}</p>
<button @click="refreshFingerprint">重新获取</button>
</div> -->
</div> </div>
</template> </template>
<script setup> <script setup>
import { useFingerprint } from '@/utils/useFingerprint'; import { useFingerprint } from '@/utils/useFingerprint';
import SelectTable from '@/components/SelectTable/index.vue';
const query = ref(6);
const fields = [
{ prop: 'name', label: '名称', width: 150, enablePinyinSearch: true },
{ prop: 'value', label: '值', width: 150, enablePinyinSearch: true },
{ prop: 'description', label: '描述', width: 300, showTooltip: true }
];
const tableData = [
{ id: 1, name: '指纹', value: 'fingerprint', description: '唯一标识用户的指纹信息' },
{ id: 2, name: '浏览器', value: 'browser', description: '用户使用的浏览器信息' },
{ id: 3, name: '操作系统', value: 'os', description: '用户使用的操作系统信息' },
{ id: 4, name: 'IP地址', value: 'ip', description: '用户的IP地址信息' },
{ id: 5, name: '设备信息', value: 'device', description: '用户使用的设备信息' },
{ id: 6, name: '地理位置', value: 'location', description: '用户使用的地理位置信息' },
{ id: 7, name: '浏览器语言', value: 'language', description: '用户使用的浏览器语言' },
{ id: 8, name: '屏幕分辨率', value: 'screen', description: '用户使用的屏幕分辨率信息' },
{ id: 9, name: '时区', value: 'timezone', description: '用户使用的时区信息' },
];
const getDataValue = (key) => {
console.log('SelectTable组件绑定对应值:', key);
}
// 使用自定义hook获取指纹信息 // 使用自定义hook获取指纹信息
const { const {

View File

@ -5,13 +5,13 @@
<el-button type="primary">打印条码</el-button> <el-button type="primary">打印条码</el-button>
</div> </div>
<el-form :model="labPat" label-width="70px" class="compact-form" label-position="right" <el-form :model="labPat" label-width="70px" class="compact-form" label-position="right"
:disabled="labPat.jgbz && labPat.jgbz != 0"> :disabled="lastJgbz != null && lastJgbz != 0">
<div :class="['sh_box', getColor(labPat.jgbz)]" v-if="labPat.jgbz != 0"> <div :class="['sh_box', getColor(lastJgbz)]" v-if="lastJgbz != null && lastJgbz != 0">
<div>{{ getLableType(labPat.jgbz) }}</div> <div>{{ getLableType(lastJgbz) }}</div>
</div> </div>
<el-form-item label="病人来源"> <el-form-item label="病人来源">
<el-col :span="14"> <el-col :span="14">
<el-select v-model="labPat.brly" placeholder="请选择" style="width: 100%;" filterable <el-select v-model="labPat.brly" placeholder="请选择" style="width: 100%;" filterable size="small"
@change="handleFieldChange"> @change="handleFieldChange">
<el-option v-for="item in dictData.PT" :key="item.value" :label="item.label" :value="item.value" /> <el-option v-for="item in dictData.PT" :key="item.value" :label="item.label" :value="item.value" />
</el-select> </el-select>
@ -22,15 +22,16 @@
</el-col> </el-col>
</el-form-item> </el-form-item>
<el-form-item label="病 历 号"> <el-form-item label="病 历 号">
<el-input v-model="labPat.brdh" placeholder="请输入病历号" @blur="handleFieldChange" <el-input v-model="labPat.brdh" placeholder="请输入病历号" @blur="handleFieldChange" @keyup.enter="handleFieldChange"
@keyup.enter="handleFieldChange"></el-input> size="small" />
</el-form-item> </el-form-item>
<el-form-item label="姓 名"> <el-form-item label="姓 名">
<el-input v-model="labPat.brxm" placeholder="请输入姓名" @blur="handleFieldChange" <el-input v-model="labPat.brxm" placeholder="请输入姓名" @blur="handleFieldChange" @keyup.enter="handleFieldChange"
@keyup.enter="handleFieldChange"></el-input> size="small" />
</el-form-item> </el-form-item>
<el-form-item label="性 别"> <el-form-item label="性 别">
<el-select v-model="labPat.brxb" placeholder="请选择" style="width: 100%;" @change="handleFieldChange"> <el-select v-model="labPat.brxb" placeholder="请选择" style="width: 100%;" @change="handleFieldChange"
size="small">
<el-option v-for="item in dictData.SX" :key="item.value" :label="item.label" :value="item.value" /> <el-option v-for="item in dictData.SX" :key="item.value" :label="item.label" :value="item.value" />
</el-select> </el-select>
</el-form-item> </el-form-item>
@ -38,10 +39,10 @@
<el-row :gutter="5"> <el-row :gutter="5">
<el-col :span="14"> <el-col :span="14">
<el-input v-model="labPat.nl" placeholder="年龄" @blur="handleFieldChange" @keyup.enter="handleFieldChange" <el-input v-model="labPat.nl" placeholder="年龄" @blur="handleFieldChange" @keyup.enter="handleFieldChange"
style="width:100%"></el-input> style="width:100%" size="small" />
</el-col> </el-col>
<el-col :span="10"> <el-col :span="10">
<el-select v-model="labPat.nldw" placeholder="请选择" style="width: 100%;" filterable <el-select v-model="labPat.nldw" placeholder="请选择" style="width: 100%;" filterable size="small"
@change="handleFieldChange"> @change="handleFieldChange">
<el-option v-for="item in dictData.AU" :key="item.value" :label="item.label" :value="item.value" /> <el-option v-for="item in dictData.AU" :key="item.value" :label="item.label" :value="item.value" />
</el-select> </el-select>
@ -49,54 +50,57 @@
</el-row> </el-row>
</el-form-item> </el-form-item>
<el-form-item label="送检科室"> <el-form-item label="送检科室">
<el-select v-model="labPat.ksdh" placeholder="请选择" style="width: 100%;" filterable @change="handleFieldChange"> <el-select v-model="labPat.ksdh" placeholder="请选择" style="width: 100%;" filterable @change="handleFieldChange"
size="small">
<el-option v-for="item in dictData.DP" :key="item.value" :label="item.label" :value="item.value" /> <el-option v-for="item in dictData.DP" :key="item.value" :label="item.label" :value="item.value" />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="床 号"> <el-form-item label="床 号">
<el-input v-model="labPat.ch" placeholder="请输入床号" @blur="handleFieldChange" <el-input v-model="labPat.ch" placeholder="请输入床号" @blur="handleFieldChange" @keyup.enter="handleFieldChange"
@keyup.enter="handleFieldChange"></el-input> size="small" />
</el-form-item> </el-form-item>
<el-form-item label="样本类型"> <el-form-item label="样本类型">
<el-select v-model="labPat.yblx" placeholder="请选择" style="width: 100%;" @change="handleFieldChange" filterable> <el-select v-model="labPat.yblx" placeholder="请选择" style="width: 100%;" @change="handleFieldChange" filterable
size="small">
<el-option v-for="item in dictData.BT" :key="item.value" :label="item.label" :value="item.value" /> <el-option v-for="item in dictData.BT" :key="item.value" :label="item.label" :value="item.value" />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="申请医生"> <el-form-item label="申请医生">
<el-select v-model="labPat.sjys" placeholder="请选择" style="width: 100%;" @change="handleFieldChange" filterable> <el-select v-model="labPat.sjys" placeholder="请选择" style="width: 100%;" @change="handleFieldChange" filterable
size="small">
<el-option v-for="item in dictData.SRD" :key="item.value" :label="item.label" :value="item.value" /> <el-option v-for="item in dictData.SRD" :key="item.value" :label="item.label" :value="item.value" />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="上机时间"> <el-form-item label="上机时间">
<el-date-picker v-model="labPat.sqsj" type="datetime" placeholder="上机时间" format="YYYY-MM-DD HH:mm:ss" <el-date-picker v-model="labPat.sqsj" type="datetime" placeholder="上机时间" format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss" @blur="handleFieldChange" value-format="YYYY-MM-DD HH:mm:ss" @blur="handleFieldChange" @keyup.enter="handleFieldChange" size="small"
@keyup.enter="handleFieldChange"></el-date-picker> style="width: 100%;" />
</el-form-item> </el-form-item>
<el-form-item label="采样时间"> <el-form-item label="采样时间">
<el-date-picker v-model="labPat.cyrq" type="datetime" placeholder="采样时间" format="YYYY-MM-DD HH:mm:ss" <el-date-picker v-model="labPat.cyrq" type="datetime" placeholder="采样时间" format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss" @blur="handleFieldChange" value-format="YYYY-MM-DD HH:mm:ss" @blur="handleFieldChange" @keyup.enter="handleFieldChange" size="small"
@keyup.enter="handleFieldChange"></el-date-picker> style="width: 100%;" />
</el-form-item> </el-form-item>
<el-form-item label="报告时间"> <el-form-item label="报告时间">
<el-date-picker v-model="labPat.dysj" type="datetime" placeholder="报告时间" format="YYYY-MM-DD HH:mm:ss" <el-date-picker v-model="labPat.dysj" type="datetime" placeholder="报告时间" format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss" @blur="handleFieldChange" value-format="YYYY-MM-DD HH:mm:ss" @blur="handleFieldChange" @keyup.enter="handleFieldChange" size="small"
@keyup.enter="handleFieldChange"></el-date-picker> style="width: 100%;" />
</el-form-item> </el-form-item>
<el-form-item label="临床诊断"> <el-form-item label="临床诊断">
<el-input v-model="labPat.zd" placeholder="请输入临床诊断" @blur="handleFieldChange" <el-input v-model="labPat.zd" placeholder="请输入临床诊断" @blur="handleFieldChange" @keyup.enter="handleFieldChange"
@keyup.enter="handleFieldChange"></el-input> size="small" />
</el-form-item> </el-form-item>
<el-form-item label="备 注"> <el-form-item label="备 注">
<el-input v-model="labPat.bz" placeholder="请输入备注" @blur="handleFieldChange" <el-input v-model="labPat.bz" placeholder="请输入备注" @blur="handleFieldChange" @keyup.enter="handleFieldChange"
@keyup.enter="handleFieldChange"></el-input> size="small" />
</el-form-item> </el-form-item>
<el-form-item label="检验医生"> <el-form-item label="检验医生">
<el-input v-model="labPat.yhdh" placeholder="请输入检验医生" @blur="handleFieldChange" <el-input v-model="labPat.yhdh" placeholder="请输入检验医生" @blur="handleFieldChange" @keyup.enter="handleFieldChange"
@keyup.enter="handleFieldChange"></el-input> size="small" />
</el-form-item> </el-form-item>
<el-form-item label="审核医生"> <el-form-item label="审核医生">
<el-input v-model="labPat.hdys" placeholder="请输入审核医生" @blur="handleFieldChange" <el-input v-model="labPat.hdys" placeholder="请输入审核医生" @blur="handleFieldChange" @keyup.enter="handleFieldChange"
@keyup.enter="handleFieldChange"></el-input> size="small" />
</el-form-item> </el-form-item>
<el-form-item label="审核状态"> <el-form-item label="审核状态">
<el-radio-group v-model="labPat.jgbz"> <el-radio-group v-model="labPat.jgbz">
@ -131,9 +135,10 @@ const props = defineProps({
default: () => { } default: () => { }
} }
}); });
const lastJgbz = ref();
watch(() => props.labPat, (newVal) => { watch(() => props.labPat, (newVal) => {
lastValue.value = JSON.stringify(newVal); lastValue.value = JSON.stringify(newVal);
lastJgbz.value = newVal.jgbz;
}) })
// 计算属性:将布尔值转换为 0/1 绑定到 labPat.jzbz // 计算属性:将布尔值转换为 0/1 绑定到 labPat.jzbz
const jzbzSwitch = ref(0); const jzbzSwitch = ref(0);
@ -291,13 +296,59 @@ const resetMain = () => {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
overflow: hidden; overflow: hidden;
}
.flex-between {
height: 32px;
}
.compact-form { :deep(.el-input__wrapper) {
box-shadow: 0 0 0 1px #96B8D9 inset;
background-color: rgba(236, 244, 251, 0.5);
color: #08355E;
.is-focus {
box-shadow: 0 0 0 1px #1f6dd3 inset !important;
}
&:hover {
box-shadow: 0 0 0 1px #1f6dd3 inset !important;
}
// .el-input__placeholder {
// color: none !important;
// }
}
:deep(.el-select__wrapper) {
box-shadow: 0 0 0 1px #96B8D9 inset;
background-color: rgba(236, 244, 251, 0.5);
color: #08355E;
.is-focus {
box-shadow: 0 0 0 1px #1f6dd3 inset !important;
}
&:hover {
box-shadow: 0 0 0 1px #1f6dd3 inset !important;
}
.el-select__placeholder {
color: #08355E !important;
}
}
:deep(.el-input__inner) {
color: #08355E !important;
-webkit-text-fill-color: #08355E;
}
:deep(.el-select__input) {
color: #08355E !important;
}
.compact-form {
flex: 1; flex: 1;
position: relative; position: relative;
height: 100%; height: 100%;
@ -306,16 +357,36 @@ const resetMain = () => {
.el-form-item { .el-form-item {
margin-bottom: 5px; margin-bottom: 0px;
} }
.el-form-item__label { .el-form-item__label {
padding-bottom: 5px; padding-bottom: 0px;
color: #08355E;
font-size: 12px;
} }
// pointer-events: none; // pointer-events: none;
:deep(.el-radio__label) {
color: #08355E;
}
}
:deep(.el-switch__label) {
color: #08355E;
}
} }
.flex-between {
height: 32px;
}
.sh_box { .sh_box {
position: absolute; position: absolute;
top: 0; top: 0;

View File

@ -5,8 +5,10 @@
<el-button class="btn_green" @click="handleCheck(1)">初审</el-button> <el-button class="btn_green" @click="handleCheck(1)">初审</el-button>
<el-button class="btn_green" v-if="labPat.jgbz != 2" @click="handleCheck(2)">审核</el-button> <el-button class="btn_green" v-if="labPat.jgbz != 2" @click="handleCheck(2)">审核</el-button>
<el-button class="btn_green" v-if="labPat.jgbz == 2" @click="handleCheck(3)">取消审核</el-button> <el-button class="btn_green" v-if="labPat.jgbz == 2" @click="handleCheck(3)">取消审核</el-button>
<el-button type="primary" plain @click="openItemDictDialog">新增</el-button> <el-button type="primary" plain :disabled="labPat.jgbz != null && labPat.jgbz != 0"
<el-button type="primary" plain @click="handleBatchDelete">删除</el-button> @click="openItemDictDialog">新增</el-button>
<el-button type="primary" :disabled="labPat.jgbz != null && labPat.jgbz != 0" plain
@click="handleBatchDelete">删除</el-button>
</div> </div>
<div> <div>
<el-button type="primary" plain icon="Files" @click="printHandle">打印</el-button> <el-button type="primary" plain icon="Files" @click="printHandle">打印</el-button>
@ -23,8 +25,10 @@
</el-table-column> </el-table-column>
<el-table-column prop="csjg" label="结果"> <el-table-column prop="csjg" label="结果">
<template #default="scope"> <template #default="scope">
<el-input v-model="scope.row.csjg" size="small" class="full-width-input" :disabled="readonly" <el-input v-if="labPat.jgbz == 0 || labPat.jgbz == null" v-model="scope.row.csjg" size="small"
@blur="handleCsjgEnter(scope.row)" @keyup.enter="handleCsjgEnter(scope.row)"></el-input> class="full-width-input" :disabled="readonly" @blur="handleCsjgEnter(scope.row)"
@keyup.enter="handleCsjgEnter(scope.row)"></el-input>
<span v-else>{{ scope.row.csjg }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="refs" label="参考值" show-overflow-tooltip> <el-table-column prop="refs" label="参考值" show-overflow-tooltip>
@ -131,10 +135,10 @@
<script setup> <script setup>
import { ref, toRefs, watch, nextTick, onMounted } from "vue"; import { ref, toRefs, watch, nextTick, onMounted } from "vue";
import { check1, check2, uncheck2, unconfirmlog, checkuser, reglimit, queryXmInfo, deleteresult, changeresult, newresult, printsample } from "@/api/liswork/work/LisWork"; import { check1, check2, uncheck2, unconfirmlog, checkuser, reglimit, queryXmInfo, deleteresult, changeresult, newresult, printsample, printListwork } from "@/api/liswork/work/LisWork";
import { ElMessageBox, ElMessage } from "element-plus"; import { ElMessageBox, ElMessage } from "element-plus";
import ItemInput from "@/views/liswork/work/components/ItemInput.vue"; import ItemInput from "@/views/liswork/work/components/ItemInput.vue";
import { log } from "vxe-pc-ui"; import { classCom } from '@/utils/classCom'
// 组件属性定义 // 组件属性定义
const props = defineProps({ const props = defineProps({
tableData: { type: Array, default: () => [] }, tableData: { type: Array, default: () => [] },
@ -424,6 +428,7 @@ const handleItemSelect = async (selectedItem) => {
const emits = defineEmits([ const emits = defineEmits([
'fetchLabResults', 'fetchLabResults',
'changeStatus', 'changeStatus',
'previewHandle'
]); ]);
// 解构props // 解构props
@ -469,10 +474,10 @@ const getRowUniqueKey = (row) => {
*/ */
const handleCsjgEnter = async (row) => { const handleCsjgEnter = async (row) => {
await saveCsjgChange(row); await saveCsjgChange(row);
// nextTick(() => { nextTick(() => {
// const input = document.activeElement; const input = document.activeElement;
// if (input.tagName === "INPUT") input.blur(); if (input.tagName === "INPUT") input.blur();
// }); });
}; };
@ -671,14 +676,30 @@ const handleBatchDelete = () => {
}; };
const printHandle = () => { const printHandle = () => {
printsample(tableKey.value).then(res => { const data = {
jyrq: tableKey.value.jyrq,
yq: tableKey.value.yq,
ybh: tableKey.value.ybh,
sqh: tableKey.value.sqh
}
printListwork(data).then(res => {
if (res.code == 0) { if (res.code == 0) {
// ElMessage.success("打印成功"); classCom.printBase64PDF(res.data)
} }
}) })
}; };
const previewHandle = () => { const previewHandle = () => {
// emits('previewHandle', props.tableKey); const data = {
jyrq: tableKey.value.jyrq,
yq: tableKey.value.yq,
ybh: tableKey.value.ybh,
sqh: tableKey.value.sqh
}
printListwork(data).then(res => {
if (res.code == 0) {
emits('previewHandle', res.data);
}
})
}; };

View File

@ -14,16 +14,23 @@
style="width:140px"></el-date-picker> style="width:140px"></el-date-picker>
</el-form-item> </el-form-item>
<el-form-item label="部门:" prop="instrGroup"> <el-form-item label="部门:" prop="instrGroup">
<el-select v-model="queryParams.instrGroup" placeholder="请选择" style="width:140px" filterable <!-- <el-select v-model="queryParams.instrGroup" placeholder="请选择" style="width:140px" filterable
@change="handleinstrGroupChange"> @change="handleinstrGroupChange">
<el-option v-for="item in instrGroupOptions" :key="item.zddh" :label="item.zdmc" :value="item.zddh" /> <el-option v-for="item in instrGroupOptions" :key="item.zddh" :label="item.zdmc" :value="item.zddh" />
</el-select> </el-select> -->
<SelectTable v-model:data="queryParams.instrGroup" :fields="instrGroupFields"
:tableData="instrGroupOptions" label="zdmc" objKey="zddh" :border="true" width="140px"
placeholder="请选择部门" @getDataValue="handleinstrGroupChange" />
</el-form-item> </el-form-item>
<el-form-item label="仪器:" prop="yq"> <el-form-item label="仪器:" prop="yq">
<el-select v-model="queryParams.yq" placeholder="请选择" style="width:140px" @change="yqHandleChange" <!-- <el-select v-model="queryParams.yq" placeholder="请选择" style="width:140px" @change="yqHandleChange"
filterable> filterable>
<el-option v-for="item in instrOptions" :key="item.value" :label="item.label" :value="item.value" /> <el-option v-for="item in instrOptions" :key="item.value" :label="item.label" :value="item.value" />
</el-select> </el-select> -->
<SelectTable v-model:data="queryParams.yq" :fields="yqFields" :tableData="instrOptions" label="yqmc"
objKey="yq" :border="true" width="140px" placeholder="请选择仪器" @getDataValue="yqHandleChange" />
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-icon color="#3c80d9" size="20" style="margin-right: 10px;" class="cp"> <el-icon color="#3c80d9" size="20" style="margin-right: 10px;" class="cp">
@ -36,11 +43,11 @@
</el-form> </el-form>
<el-row :gutter="5"> <el-row :gutter="5">
<el-col :span="8"> <el-col :span="8">
<LabPat ref="labPatRef" v-model:labPat="labPat" :labPatKey="queryParams" :dictData="dictData" /> <LabPat ref="labPatRef" v-model:labPat="labPat" :labPatKey="labPat" :dictData="dictData" />
</el-col> </el-col>
<el-col :span="16"> <el-col :span="16">
<LabResult ref="labResultRef" v-model:labPat="labPat" :tableData="labResuts" :tableKey="queryParams" <LabResult ref="labResultRef" v-model:labPat="labPat" :tableData="labResuts" :tableKey="labPat"
@fetchLabResults="fetchLabResults" @changeStatus="changeStatus" /> @fetchLabResults="fetchLabResults" @changeStatus="changeStatus" @previewHandle="previewHandle" />
</el-col> </el-col>
</el-row> </el-row>
</div> </div>
@ -104,13 +111,18 @@
</el-col> </el-col>
</el-row> </el-row>
<el-dialog v-model="previewShow" title="预览" width="90vw" :close-on-click-modal="false">
<iFrame v-if="pdfUrl" :src="pdfUrl" />
</el-dialog>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, nextTick, onMounted, toRaw } from 'vue'; import { ref, nextTick, onMounted, toRaw } from 'vue';
import LabPat from './components/labpat.vue'; import LabPat from './components/labpat.vue';
import SelectTable from '@/components/SelectTable/index.vue';
// @ts-ignore
import iFrame from "@/components/iFrame/index.vue";
// @ts-ignore // @ts-ignore
import LabResult from './components/labresult.vue'; import LabResult from './components/labresult.vue';
import LabPatList from './components/labpatlist.vue'; import LabPatList from './components/labpatlist.vue';
@ -124,7 +136,9 @@ import { querylabInstrList, querylabInstrListByLisgroup } from "@/api/liswork/di
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 { log } from 'vxe-pc-ui';
const previewShow = ref(false);
const queryParams = ref({ const queryParams = ref({
pageNum: 1, pageNum: 1,
@ -181,9 +195,15 @@ const loading = ref(false)
const total = ref(0) const total = ref(0)
const rules = ref([]) const rules = ref([])
const instrGroupOptions = ref<{ zdmc: string, zddh: string }[]>([]) const instrGroupOptions = ref<any[]>([])
const instrOptions = ref<{ label: string, value: string }[]>([]) const instrOptions = ref<{ label: string, value: string }[]>([])
const pdfUrl = ref('')
const previewHandle = (url: string) => {
if (!url) return ElMessage.warning('未查询到文件')
pdfUrl.value = `data:application/pdf;base64,${url}`
previewShow.value = true
}
const handleinstrGroupChange = (val: string) => { const handleinstrGroupChange = (val: string) => {
queryParams.value.instrGroup = val queryParams.value.instrGroup = val
queryParams.value.yq = '' queryParams.value.yq = ''
@ -199,6 +219,10 @@ const yqHandleChange = (val: string) => {
labPat.value = {} labPat.value = {}
fetchlabPatList() fetchlabPatList()
} }
const instrGroupFields = ref([
{ prop: 'zddh', label: '代号', width: 80, enablePinyinSearch: true },
{ prop: 'zdmc', label: '名称', width: 150, enablePinyinSearch: true },
])
// 部门 // 部门
const loadinstrGroupOptions = () => { const loadinstrGroupOptions = () => {
@ -209,14 +233,19 @@ const loadinstrGroupOptions = () => {
getYqConfig() getYqConfig()
}); });
} }
const yqFields = ref([
{ prop: 'yq', label: '代号', width: 80, enablePinyinSearch: true },
{ prop: 'yqmc', label: '名称', width: 150, enablePinyinSearch: true },
])
// 仪器 // 仪器
const getYqConfig = () => { const getYqConfig = () => {
querylabInstrListByLisgroup({ pageNum: 1, pageSize: 100, lisgroup: queryParams.value.instrGroup }) querylabInstrListByLisgroup({ pageNum: 1, pageSize: 100, lisgroup: queryParams.value.instrGroup })
.then((res: any) => { .then((res: any) => {
if (res.code == 200) { if (res.code == 200) {
instrOptions.value = res.rows.map((item: any) => ({ instrOptions.value = res.rows.map((item: any) => ({
value: item.yq.trim(), yq: item.yq.trim(),
label: item.yqmc yqmc: item.yqmc
})) }))
} }
}) })

View File

@ -3,29 +3,17 @@
<el-form ref="loginRef" :model="loginForm" :rules="loginRules" class="login-form"> <el-form ref="loginRef" :model="loginForm" :rules="loginRules" class="login-form">
<h3 class="title">实验室管理系统</h3> <h3 class="title">实验室管理系统</h3>
<el-form-item prop="username"> <el-form-item prop="username">
<el-input <el-input v-model="loginForm.username" type="text" size="large" auto-complete="off" placeholder="账号">
v-model="loginForm.username"
type="text"
size="large"
auto-complete="off"
placeholder="账号"
>
<template #prefix><svg-icon icon-class="user" class="el-input__icon input-icon" /></template> <template #prefix><svg-icon icon-class="user" class="el-input__icon input-icon" /></template>
</el-input> </el-input>
</el-form-item> </el-form-item>
<el-form-item prop="password"> <el-form-item prop="password">
<el-input <el-input v-model="loginForm.password" type="password" size="large" auto-complete="off" placeholder="密码"
v-model="loginForm.password" @keyup.enter="handleLogin">
type="password"
size="large"
auto-complete="off"
placeholder="密码"
@keyup.enter="handleLogin"
>
<template #prefix><svg-icon icon-class="password" class="el-input__icon input-icon" /></template> <template #prefix><svg-icon icon-class="password" class="el-input__icon input-icon" /></template>
</el-input> </el-input>
</el-form-item> </el-form-item>
<el-form-item prop="code" v-if="captchaEnabled"> <!-- <el-form-item prop="code" v-if="captchaEnabled">
<el-input <el-input
v-model="loginForm.code" v-model="loginForm.code"
size="large" size="large"
@ -39,16 +27,10 @@
<div class="login-code"> <div class="login-code">
<img :src="codeUrl" @click="getCode" class="login-code-img"/> <img :src="codeUrl" @click="getCode" class="login-code-img"/>
</div> </div>
</el-form-item> </el-form-item> -->
<el-checkbox v-model="loginForm.rememberMe" style="margin:0px 0px 25px 0px;">记住密码</el-checkbox> <el-checkbox v-model="loginForm.rememberMe" style="margin:0px 0px 25px 0px;">记住密码</el-checkbox>
<el-form-item style="width:100%;"> <el-form-item style="width:100%;">
<el-button <el-button :loading="loading" size="large" type="primary" style="width:100%;" @click.prevent="handleLogin">
:loading="loading"
size="large"
type="primary"
style="width:100%;"
@click.prevent="handleLogin"
>
<span v-if="!loading">登 录</span> <span v-if="!loading">登 录</span>
<span v-else>登 录 中...</span> <span v-else>登 录 中...</span>
</el-button> </el-button>
@ -171,6 +153,7 @@ getCookie();
background-image: url("../assets/images/login-background.jpg"); background-image: url("../assets/images/login-background.jpg");
background-size: cover; background-size: cover;
} }
.title { .title {
margin: 0px auto 30px auto; margin: 0px auto 30px auto;
text-align: center; text-align: center;
@ -182,32 +165,39 @@ getCookie();
background: #ffffff; background: #ffffff;
width: 400px; width: 400px;
padding: 25px 25px 5px 25px; padding: 25px 25px 5px 25px;
.el-input { .el-input {
height: 40px; height: 40px;
input { input {
height: 40px; height: 40px;
} }
} }
.input-icon { .input-icon {
height: 39px; height: 39px;
width: 14px; width: 14px;
margin-left: 0px; margin-left: 0px;
} }
} }
.login-tip { .login-tip {
font-size: 13px; font-size: 13px;
text-align: center; text-align: center;
color: #bfbfbf; color: #bfbfbf;
} }
.login-code { .login-code {
width: 33%; width: 33%;
height: 40px; height: 40px;
float: right; float: right;
img { img {
cursor: pointer; cursor: pointer;
vertical-align: middle; vertical-align: middle;
} }
} }
.el-login-footer { .el-login-footer {
height: 40px; height: 40px;
line-height: 40px; line-height: 40px;
@ -220,6 +210,7 @@ getCookie();
font-size: 12px; font-size: 12px;
letter-spacing: 1px; letter-spacing: 1px;
} }
.login-code-img { .login-code-img {
height: 40px; height: 40px;
padding-left: 12px; padding-left: 12px;