基础组件封装
This commit is contained in:
parent
dafc6ea37a
commit
bf34cd1ed4
@ -32,6 +32,7 @@
|
||||
"pinyin-pro": "^3.26.0",
|
||||
"select2": "^4.1.0-rc.0",
|
||||
"socket.io-client": "^4.8.1",
|
||||
"sortablejs": "^1.15.6",
|
||||
"vue": "3.4.0",
|
||||
"vue-cropper": "1.1.1",
|
||||
"vue-plugin-hiprint": "^0.0.60",
|
||||
|
||||
@ -151,3 +151,12 @@ export function printsample(query?: Object) {
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 打印报告单
|
||||
export function printListwork(query?: Object) {
|
||||
return request({
|
||||
url: '/liswork/print',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
@ -177,11 +177,7 @@
|
||||
border-right: 1px solid #1F6DD3 !important;
|
||||
}
|
||||
|
||||
/* 在你的全局样式文件中 */
|
||||
.el-input__wrapper {
|
||||
border-color: #96B8D9 !important;
|
||||
// background-color: #f00;
|
||||
}
|
||||
|
||||
|
||||
.vxe-table {
|
||||
border: 1px solid #96B8D9 !important;
|
||||
@ -189,11 +185,45 @@
|
||||
border-radius: 8px;
|
||||
/* 可选:添加边框圆角 */
|
||||
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 {
|
||||
.vxe-header--column {
|
||||
word-break: break-word;
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<!--
|
||||
* SelectTable 下拉表格组件
|
||||
* @author: Goal
|
||||
* @since: 2023-11-13
|
||||
* @author: w
|
||||
* @since: 2025-9-28
|
||||
* SelectTable.vue
|
||||
*
|
||||
* 属性(带有[Required]为必填属性)
|
||||
@ -17,26 +17,41 @@
|
||||
-->
|
||||
<template>
|
||||
<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>
|
||||
<el-table :data="props.tableData" :highlight-current-row="props.isHighlight" style="width: 100%"
|
||||
:size="props.size" :border="props.border" @current-change="handleCurrentChange">
|
||||
<div class="select-table-dropdown">
|
||||
<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"
|
||||
:show-overflow-tooltip="field.showTooltip" />
|
||||
:show-overflow-tooltip="field.showTooltip" align="center" />
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
</el-select>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<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 {
|
||||
prop: string;
|
||||
label: string;
|
||||
width: number;
|
||||
showTooltip?: boolean;
|
||||
enablePinyinSearch?: boolean; //是否参与拼音搜索
|
||||
}
|
||||
|
||||
interface Props {
|
||||
@ -50,103 +65,154 @@ interface Props {
|
||||
size?: string;
|
||||
placeholder?: string;
|
||||
border?: boolean;
|
||||
width?: string | number;
|
||||
}
|
||||
const props = withDefaults(defineProps < Props > (), {
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
placeholder: "请选择",
|
||||
size: "default",
|
||||
isHighlight: true,
|
||||
value: undefined,
|
||||
label: undefined,
|
||||
border: false,
|
||||
width: "100%",
|
||||
});
|
||||
|
||||
interface Emits {
|
||||
(e: "update:data", val: any): void;
|
||||
(e: "getDataValue", val: any): void;
|
||||
}
|
||||
|
||||
const emits = defineEmits < Emits > ();
|
||||
|
||||
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 emits = defineEmits<Emits>();
|
||||
const searchKey = ref('');
|
||||
const tableRef = 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,
|
||||
selectShowValue: null,
|
||||
// 预处理数据:生成拼音信息
|
||||
const processTableData = (data: object[]) => {
|
||||
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];
|
||||
});
|
||||
|
||||
/**
|
||||
* 点击当前行事件
|
||||
* @param val
|
||||
*/
|
||||
const handleCurrentChange = (val: any) => {
|
||||
// 如果没有配置label则显示value或者objKey
|
||||
setLabel(val);
|
||||
// 设置双向绑定值
|
||||
if (typeof props.value !== "undefined") {
|
||||
emits("update:data", val[props.value]);
|
||||
} else {
|
||||
emits("update:data", val);
|
||||
// 监听表格数据变化,重新处理
|
||||
watch(() => props.tableData, (newVal) => {
|
||||
processedTableData.value = processTableData(newVal);
|
||||
// 数据回显
|
||||
handleDataEcho();
|
||||
}, { deep: true });
|
||||
|
||||
// 数据回显处理
|
||||
const handleDataEcho = () => {
|
||||
if (props.data === null || props.data === undefined) return;
|
||||
// 查找匹配的行数据
|
||||
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) => {
|
||||
// 如果没有配置label则显示value或者objKey
|
||||
if (typeof props.label === "undefined") {
|
||||
// 如果配置了value,则显示value
|
||||
if (typeof props.value !== "undefined") {
|
||||
state.selectShowValue = val[props.value];
|
||||
} else if (typeof props.objKey !== "undefined") {
|
||||
//没有配置value但配置了objKey,则显示objKey
|
||||
state.selectShowValue = val[props.objKey];
|
||||
if (props.label) {
|
||||
selectShowValue.value = val[props.label];
|
||||
} else if (props.value) {
|
||||
selectShowValue.value = val[props.value];
|
||||
}
|
||||
} else {
|
||||
state.selectShowValue = val[props.label];
|
||||
if (props.objKey) {
|
||||
emits('getDataValue', val[props.objKey]);
|
||||
}
|
||||
selectTable.value.blur();
|
||||
};
|
||||
// 清空值
|
||||
const clearHandle = () => {
|
||||
selectShowValue.value = '';
|
||||
emits("update:data", null);
|
||||
emits('getDataValue', null);
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
<style scoped>
|
||||
.select-table-dropdown {
|
||||
padding: 8px;
|
||||
|
||||
}
|
||||
|
||||
:deep(.el-table .el-table__cell) {
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
||||
@ -1,10 +1,6 @@
|
||||
<template>
|
||||
<div v-loading="loading" :style="'height:' + height">
|
||||
<iframe
|
||||
:src="url"
|
||||
frameborder="no"
|
||||
style="width: 100%; height: 100%"
|
||||
scrolling="auto" />
|
||||
<iframe :src="url" frameborder="no" style="width: 100%; height: 100%" scrolling="auto" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@ -7,30 +7,34 @@
|
||||
:header-cell-style="config.headerCellStyle" :cell-style="config.cellStyle" :max-height="config.maxHeight"
|
||||
:height="config.height" :size="config.size || 'default'" :empty-text="config.emptyText || '暂无数据'"
|
||||
@selection-change="handleSelectionChange" @current-change="handleCurrentChange" @row-click="handleRowClick"
|
||||
@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" />
|
||||
header-cell-class-name="el-table-header-cell" @row-dblclick="handleRowDblclick" @sort-change="handleSortChange"
|
||||
v-bind="$attrs">
|
||||
|
||||
<!-- 序号列 -->
|
||||
<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属性) -->
|
||||
<el-table-column v-if="item.slot && item.visible" :prop="item.prop" :label="item.label" :width="item.width"
|
||||
:min-width="item.minWidth" :fixed="item.fixed" :align="item.align || 'left'" :sortable="item.sortable"
|
||||
:show-overflow-tooltip="item.showOverflowTooltip !== false">
|
||||
<el-table-column v-if="!item.type && item.slot && item.visible" :prop="item.prop" :label="item.label"
|
||||
:width="item.width" :min-width="item.minWidth" :fixed="item.fixed" :align="item.align || 'left'"
|
||||
:sortable="item.sortable" :show-overflow-tooltip="item.showOverflowTooltip !== false">
|
||||
<template #default="scope">
|
||||
<slot :name="item.slot" :row="scope.row" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 普通列 -->
|
||||
<el-table-column v-if="!item.slot && item.visible" :prop="item.prop" :label="item.label" :width="item.width"
|
||||
:min-width="item.minWidth" :fixed="item.fixed" :align="item.align || 'left'" :sortable="item.sortable"
|
||||
:show-overflow-tooltip="item.showOverflowTooltip !== false" :formatter="item.formatter">
|
||||
<el-table-column v-if="!item.type && !item.slot && item.visible" :prop="item.prop" :label="item.label"
|
||||
:width="item.width" :min-width="item.minWidth" :fixed="item.fixed" :align="item.align || 'left'"
|
||||
:sortable="item.sortable" :show-overflow-tooltip="item.showOverflowTooltip !== false"
|
||||
:formatter="item.formatter">
|
||||
<!-- 表头插槽 (无row属性)-->
|
||||
<template v-if="item.headerSlot" #header="scope">
|
||||
<slot :name="item.headerSlot" :column="scope.column" :$index="scope.$index" />
|
||||
@ -65,10 +69,13 @@
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { computed, ref, watch, PropType } from "vue";
|
||||
import { computed, ref, watch, PropType, onMounted } from "vue";
|
||||
import { TableColumnCtx } from 'element-plus';
|
||||
// @ts-ignore
|
||||
import Sortable from 'sortablejs'; // 引入sortablejs
|
||||
interface TableColumn {
|
||||
prop?: string;
|
||||
type?: string; // 'selection' | 'index' | undefined
|
||||
key?: string | number;
|
||||
label?: string;
|
||||
width?: string | number;
|
||||
@ -121,6 +128,11 @@ const props = defineProps({
|
||||
currentPage: 1,
|
||||
}),
|
||||
},
|
||||
// 拖拽列
|
||||
enableColumnDrag: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@ -134,6 +146,7 @@ const emit = defineEmits([
|
||||
"sort-change",
|
||||
"page-change",
|
||||
"size-change",
|
||||
"column-drag-end",
|
||||
]);
|
||||
|
||||
// 响应式数据
|
||||
@ -160,6 +173,13 @@ const getIndex = (index: number) => {
|
||||
return index + 1;
|
||||
};
|
||||
|
||||
// const headerCellClassName = (column: TableColumnCtx<any>) => {
|
||||
// if (!column.column.property) {
|
||||
// return ''; // 不添加类名
|
||||
// } else {
|
||||
// return 'el-table-header-cell'; // 添加自定义类名
|
||||
// }
|
||||
// };
|
||||
// 事件处理
|
||||
const handleSelectionChange = (selection: any[]) => {
|
||||
emit("selection-change", selection);
|
||||
@ -198,6 +218,17 @@ const handleCurrentPageChange = (page: number) => {
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
|
||||
// 初始化列拖拽功能
|
||||
onMounted(() => {
|
||||
if (props.enableColumnDrag && tableRef.value) {
|
||||
initColumnDrag();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
// 监听分页配置变化
|
||||
watch(
|
||||
() => props.pagination.currentPage,
|
||||
@ -208,6 +239,8 @@ watch(
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
|
||||
watch(
|
||||
() => props.pagination.pageSize,
|
||||
(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 = () => {
|
||||
tableRef.value?.clearSelection();
|
||||
@ -256,6 +336,7 @@ defineExpose({
|
||||
doLayout,
|
||||
sort,
|
||||
tableRef,
|
||||
initColumnDrag
|
||||
});
|
||||
</script>
|
||||
|
||||
@ -264,6 +345,17 @@ defineExpose({
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
// 拖拽相关样式
|
||||
:deep(.sortable-ghost) {
|
||||
opacity: 0.5;
|
||||
background-color: #e5e7eb;
|
||||
}
|
||||
|
||||
:deep(.el-table-header-cell) {
|
||||
cursor: move;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.pagination-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
@ -76,7 +76,8 @@
|
||||
</el-row>
|
||||
|
||||
<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 }">
|
||||
{{ row.zt != 1 ? '✅' : '❌' }}
|
||||
</template>
|
||||
@ -234,26 +235,28 @@ const loading = ref(true);
|
||||
const tableData = ref([])
|
||||
// 配置项
|
||||
const columns = ref([
|
||||
{ prop: 'zt', label: '打印', visible: true, key: 0, sortable: true, slot: 'dy', },
|
||||
{ prop: 'ch', label: '床号', visible: true, key: 0, sortable: true, },
|
||||
{ prop: 'brxm', label: '姓名', visible: true, key: 1, },
|
||||
{ prop: 'brxbname', label: '性别', align: 'center', visible: true, key: 2, },
|
||||
{ prop: 'jymd', label: '项目名称', align: 'center', visible: true, key: 3, width: '140px' },
|
||||
{ prop: 'bgddhname', label: '类别', align: 'center', visible: true, key: 4, width: '120px' },
|
||||
{ prop: 'sampletips', label: '采样提示', align: 'center', visible: true, key: 5, width: '110px' },
|
||||
{ prop: 'jzbz', label: '急诊', align: 'center', visible: true, slot: 'jzbz', key: 6, width: '110px' },
|
||||
{ prop: 'yblx', label: '样本类型', align: 'center', visible: true, key: 7, width: '110px' },
|
||||
{ prop: 'brdh', label: '病人号', align: 'center', visible: true, key: 8, width: '110px' },
|
||||
{ prop: 'ksname', label: '科室名称', align: 'center', visible: true, key: 9, width: '110px' },
|
||||
{ prop: 'sqh', label: '申请号/条码', align: 'center', visible: true, key: 10, width: '110px' },
|
||||
{ prop: 'zt', label: '状态', align: 'center', visible: true, key: 11, slot: 'zt', width: '110px' },
|
||||
{ prop: 'brly', label: '病人来源', align: 'center', visible: true, key: 12, slot: 'brly', width: '110px' },
|
||||
{ prop: 'sqysname', label: '申请医生', align: 'center', visible: true, key: 13, width: '110px' },
|
||||
{ prop: 'sqsj', label: '申请时间', align: 'center', visible: true, key: 14, width: '170px' },
|
||||
{ prop: 'jjzt', label: '计价标志', align: 'center', visible: true, key: 15, slot: 'jjzt', },
|
||||
{ prop: 'zxysname', label: '执行医生', align: 'center', visible: true, key: 16, },
|
||||
{ prop: 'bbsjrname', label: '送检人', align: 'center', visible: true, key: 17, },
|
||||
{ prop: 'yljg', label: '医疗机构', align: 'center', visible: true, slot: 'yljg', key: 18, width: '170px' },
|
||||
{ type: 'selection', visible: true, align: 'center', width: 55, label: '多选框' },
|
||||
// { type: 'index', visible: true, align: 'center', width: 60, label: '序号' },
|
||||
{ prop: 'zt', label: '打印', visible: true, align: 'center', slot: 'dy', },
|
||||
{ prop: 'ch', label: '床号', visible: true, align: 'center', sortable: true, },
|
||||
{ prop: 'brxm', label: '姓名', align: 'center', visible: true, },
|
||||
{ prop: 'brxbname', label: '性别', align: 'center', visible: true, },
|
||||
{ prop: 'jymd', label: '项目名称', align: 'center', visible: true, width: '140px' },
|
||||
{ prop: 'bgddhname', label: '类别', align: 'center', visible: true, width: '120px' },
|
||||
{ prop: 'sampletips', label: '采样提示', align: 'center', visible: true, width: '110px' },
|
||||
{ prop: 'jzbz', label: '急诊', align: 'center', visible: true, slot: 'jzbz', width: '110px' },
|
||||
{ prop: 'yblx', label: '样本类型', align: 'center', visible: true, width: '110px' },
|
||||
{ prop: 'brdh', label: '病人号', align: 'center', visible: true, width: '110px' },
|
||||
{ prop: 'ksname', label: '科室名称', align: 'center', visible: true, width: '110px' },
|
||||
{ prop: 'sqh', label: '申请号/条码', align: 'center', visible: true, width: '110px' },
|
||||
{ prop: 'zt', label: '状态', align: 'center', visible: true, slot: 'zt', width: '110px' },
|
||||
{ prop: 'brly', label: '病人来源', align: 'center', visible: true, slot: 'brly', width: '110px' },
|
||||
{ prop: 'sqysname', label: '申请医生', align: 'center', visible: true, width: '110px' },
|
||||
{ prop: 'sqsj', label: '申请时间', align: 'center', visible: true, width: '170px' },
|
||||
{ prop: 'jjzt', label: '计价标志', align: 'center', visible: true, slot: 'jjzt', },
|
||||
{ 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);
|
||||
@ -299,12 +302,19 @@ const selectionChange = (selection: any) => {
|
||||
multiple.value = !selection.length;
|
||||
}
|
||||
|
||||
const handleColumnDragEnd = (data: any) => {
|
||||
// 更新列配置
|
||||
columns.value = data.columns;
|
||||
// 可以在这里保存列顺序到本地存储等
|
||||
// localStorage.setItem('tableColumnOrder', JSON.stringify(data.columns));
|
||||
};
|
||||
|
||||
// 左侧表格配置
|
||||
const tableConfig = ref({
|
||||
// stripe: true, // 斑马纹
|
||||
border: false, // 边框
|
||||
selection: true, // 多选框
|
||||
index: false, // 序号
|
||||
border: true, // 边框
|
||||
|
||||
index: true, // 序号
|
||||
height: '', // 高度
|
||||
highlightCurrentRow: true, // 高亮当前行
|
||||
cellStyle: cellStyleHd,
|
||||
@ -315,20 +325,20 @@ const tableConfig = ref({
|
||||
const rightTableData = ref([])
|
||||
// 配置项
|
||||
const rightColumns = ref([
|
||||
{ prop: 'sqxmdh', label: '项目代号', visible: true, key: 0, sortable: true, width: '110px' },
|
||||
{ prop: 'sqxmmc', label: '项目名称', visible: true, key: 1, width: '120px' },
|
||||
{ prop: 'dj', label: '单价', align: 'center', visible: true, key: 2 },
|
||||
{ prop: 'sl', label: '数量', align: 'center', visible: true, key: 3 },
|
||||
{ prop: 'zt', label: '状态', align: 'center', visible: true, slot: 'zt', key: 4 },
|
||||
{ prop: 'jjzt', label: '计价标志', align: 'center', visible: true, slot: 'jjzt', key: 5 },
|
||||
{ prop: 'sqxmdh', label: '项目代号', visible: true, sortable: true, width: '110px' },
|
||||
{ prop: 'sqxmmc', label: '项目名称', visible: true, width: '120px' },
|
||||
{ prop: 'dj', label: '单价', align: 'center', visible: true, },
|
||||
{ prop: 'sl', label: '数量', align: 'center', visible: true, },
|
||||
{ prop: 'zt', label: '状态', align: 'center', visible: true, slot: 'zt', },
|
||||
{ prop: 'jjzt', label: '计价标志', align: 'center', visible: true, slot: 'jjzt', },
|
||||
|
||||
])
|
||||
// 表格配置
|
||||
const rightTableConfig = ref({
|
||||
// stripe: true, // 斑马纹
|
||||
border: false, // 边框
|
||||
// selection: true, // 多选框
|
||||
index: false, // 序号
|
||||
//
|
||||
|
||||
height: '', // 高度
|
||||
highlightCurrentRow: true, // 高亮当前行
|
||||
})
|
||||
@ -337,26 +347,24 @@ const rightTableConfig = ref({
|
||||
const cyTableData = ref([])
|
||||
// 配置项
|
||||
const cyColumns = ref([
|
||||
{ prop: 'sqh', label: '申请号/条形码', visible: true, key: 0, sortable: true, width: '140px' },
|
||||
{ prop: 'ksdh', label: '科室病区', visible: true, key: 1, width: '120px' },
|
||||
{ prop: 'ch', label: '床号', visible: true, key: 2, sortable: true, },
|
||||
{ prop: 'brxm', label: '姓名', visible: true, key: 3, },
|
||||
{ prop: 'brdh', label: '病人号', visible: true, key: 4, },
|
||||
{ prop: 'brxb', label: '性别', align: 'center', visible: true, key: 5, },
|
||||
{ prop: 'yblx', label: '样本类型', align: 'center', visible: true, key: 6 },
|
||||
{ prop: 'zt', label: '状态', align: 'center', visible: true, slot: 'zt', key: 7 },
|
||||
{ prop: 'jzbz', label: '急诊', align: 'center', visible: true, key: 8 },
|
||||
{ prop: 'jjzt', label: '采样人', align: 'center', visible: true, key: 8 },
|
||||
{ prop: 'cysj', label: '采样时间', align: 'center', visible: true, key: 8 },
|
||||
{ prop: 'zxysname', label: '执行医生', align: 'center', visible: true, key: 8 },
|
||||
{ prop: 'zxsj', label: '执行时间', align: 'center', visible: true, key: 8 },
|
||||
{ prop: 'sqh', label: '申请号/条形码', align: 'center', visible: true, sortable: true, width: 140 },
|
||||
{ prop: 'ksdh', label: '科室病区', align: 'center', visible: true, width: 120 },
|
||||
{ prop: 'ch', label: '床号', align: 'center', visible: true, sortable: true, },
|
||||
{ prop: 'brxm', label: '姓名', align: 'center', visible: true, },
|
||||
{ prop: 'brdh', label: '病人号', align: 'center', visible: true, },
|
||||
{ prop: 'brxb', label: '性别', align: 'center', visible: true, },
|
||||
{ prop: 'yblx', label: '样本类型', align: 'center', visible: true, },
|
||||
{ prop: 'zt', label: '状态', align: 'center', visible: true, slot: 'zt', },
|
||||
{ prop: 'jzbz', label: '急诊', align: 'center', visible: true, },
|
||||
{ prop: 'jjzt', label: '采样人', align: 'center', visible: true, },
|
||||
{ prop: 'cysj', label: '采样时间', align: 'center', visible: true, },
|
||||
{ prop: 'zxysname', label: '执行医生', align: 'center', visible: true, },
|
||||
{ prop: 'zxsj', label: '执行时间', align: 'center', visible: true, },
|
||||
])
|
||||
// 表格配置
|
||||
const cyTableConfig = ref({
|
||||
// stripe: true, // 斑马纹
|
||||
border: false, // 边框
|
||||
selection: true, // 多选框
|
||||
index: false, // 序号
|
||||
height: '100%', // 高度
|
||||
highlightCurrentRow: true, // 高亮当前行
|
||||
})
|
||||
|
||||
@ -320,8 +320,8 @@ const tableConfig = ref(
|
||||
{
|
||||
// stripe: true, // 斑马纹
|
||||
border: true, // 边框
|
||||
selection: true, // 多选框
|
||||
index: false, // 序号
|
||||
|
||||
|
||||
height: '', // 高度
|
||||
highlightCurrentRow: true, // 高亮当前行
|
||||
fit: true,
|
||||
@ -392,7 +392,7 @@ const rightTableConfig = ref(
|
||||
// stripe: true, // 斑马纹
|
||||
border: true, // 边框
|
||||
selection: false, // 多选框
|
||||
index: false, // 序号
|
||||
|
||||
height: '40vh', // 高度
|
||||
highlightCurrentRow: true, // 高亮当前行
|
||||
}
|
||||
@ -647,7 +647,7 @@ const bottomTableConfig = ref(
|
||||
// stripe: true, // 斑马纹
|
||||
border: true, // 边框
|
||||
selection: false, // 多选框
|
||||
index: false, // 序号
|
||||
|
||||
height: '37vh', // 高度
|
||||
highlightCurrentRow: true, // 高亮当前行
|
||||
}
|
||||
|
||||
@ -1,24 +1,37 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- <h3>浏览器指纹识别</h3>
|
||||
|
||||
<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> -->
|
||||
<SelectTable v-model:data="query" :fields="fields" :tableData="tableData" label="name" objKey="id" :border="true"
|
||||
:width="'300px'" placeholder="请选择指定项" @getDataValue="getDataValue" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
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获取指纹信息
|
||||
const {
|
||||
|
||||
@ -5,13 +5,13 @@
|
||||
<el-button type="primary">打印条码</el-button>
|
||||
</div>
|
||||
<el-form :model="labPat" label-width="70px" class="compact-form" label-position="right"
|
||||
:disabled="labPat.jgbz && labPat.jgbz != 0">
|
||||
<div :class="['sh_box', getColor(labPat.jgbz)]" v-if="labPat.jgbz != 0">
|
||||
<div>{{ getLableType(labPat.jgbz) }}</div>
|
||||
:disabled="lastJgbz != null && lastJgbz != 0">
|
||||
<div :class="['sh_box', getColor(lastJgbz)]" v-if="lastJgbz != null && lastJgbz != 0">
|
||||
<div>{{ getLableType(lastJgbz) }}</div>
|
||||
</div>
|
||||
<el-form-item label="病人来源">
|
||||
<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">
|
||||
<el-option v-for="item in dictData.PT" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
@ -22,15 +22,16 @@
|
||||
</el-col>
|
||||
</el-form-item>
|
||||
<el-form-item label="病 历 号">
|
||||
<el-input v-model="labPat.brdh" placeholder="请输入病历号" @blur="handleFieldChange"
|
||||
@keyup.enter="handleFieldChange"></el-input>
|
||||
<el-input v-model="labPat.brdh" placeholder="请输入病历号" @blur="handleFieldChange" @keyup.enter="handleFieldChange"
|
||||
size="small" />
|
||||
</el-form-item>
|
||||
<el-form-item label="姓 名">
|
||||
<el-input v-model="labPat.brxm" placeholder="请输入姓名" @blur="handleFieldChange"
|
||||
@keyup.enter="handleFieldChange"></el-input>
|
||||
<el-input v-model="labPat.brxm" placeholder="请输入姓名" @blur="handleFieldChange" @keyup.enter="handleFieldChange"
|
||||
size="small" />
|
||||
</el-form-item>
|
||||
<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-select>
|
||||
</el-form-item>
|
||||
@ -38,10 +39,10 @@
|
||||
<el-row :gutter="5">
|
||||
<el-col :span="14">
|
||||
<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 :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">
|
||||
<el-option v-for="item in dictData.AU" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
@ -49,54 +50,57 @@
|
||||
</el-row>
|
||||
</el-form-item>
|
||||
<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-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="床 号">
|
||||
<el-input v-model="labPat.ch" placeholder="请输入床号" @blur="handleFieldChange"
|
||||
@keyup.enter="handleFieldChange"></el-input>
|
||||
<el-input v-model="labPat.ch" placeholder="请输入床号" @blur="handleFieldChange" @keyup.enter="handleFieldChange"
|
||||
size="small" />
|
||||
</el-form-item>
|
||||
<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-select>
|
||||
</el-form-item>
|
||||
<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-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="上机时间">
|
||||
<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"
|
||||
@keyup.enter="handleFieldChange"></el-date-picker>
|
||||
value-format="YYYY-MM-DD HH:mm:ss" @blur="handleFieldChange" @keyup.enter="handleFieldChange" size="small"
|
||||
style="width: 100%;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="采样时间">
|
||||
<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"
|
||||
@keyup.enter="handleFieldChange"></el-date-picker>
|
||||
value-format="YYYY-MM-DD HH:mm:ss" @blur="handleFieldChange" @keyup.enter="handleFieldChange" size="small"
|
||||
style="width: 100%;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="报告时间">
|
||||
<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"
|
||||
@keyup.enter="handleFieldChange"></el-date-picker>
|
||||
value-format="YYYY-MM-DD HH:mm:ss" @blur="handleFieldChange" @keyup.enter="handleFieldChange" size="small"
|
||||
style="width: 100%;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="临床诊断">
|
||||
<el-input v-model="labPat.zd" placeholder="请输入临床诊断" @blur="handleFieldChange"
|
||||
@keyup.enter="handleFieldChange"></el-input>
|
||||
<el-input v-model="labPat.zd" placeholder="请输入临床诊断" @blur="handleFieldChange" @keyup.enter="handleFieldChange"
|
||||
size="small" />
|
||||
</el-form-item>
|
||||
<el-form-item label="备 注">
|
||||
<el-input v-model="labPat.bz" placeholder="请输入备注" @blur="handleFieldChange"
|
||||
@keyup.enter="handleFieldChange"></el-input>
|
||||
<el-input v-model="labPat.bz" placeholder="请输入备注" @blur="handleFieldChange" @keyup.enter="handleFieldChange"
|
||||
size="small" />
|
||||
</el-form-item>
|
||||
<el-form-item label="检验医生">
|
||||
<el-input v-model="labPat.yhdh" placeholder="请输入检验医生" @blur="handleFieldChange"
|
||||
@keyup.enter="handleFieldChange"></el-input>
|
||||
<el-input v-model="labPat.yhdh" placeholder="请输入检验医生" @blur="handleFieldChange" @keyup.enter="handleFieldChange"
|
||||
size="small" />
|
||||
</el-form-item>
|
||||
<el-form-item label="审核医生">
|
||||
<el-input v-model="labPat.hdys" placeholder="请输入审核医生" @blur="handleFieldChange"
|
||||
@keyup.enter="handleFieldChange"></el-input>
|
||||
<el-input v-model="labPat.hdys" placeholder="请输入审核医生" @blur="handleFieldChange" @keyup.enter="handleFieldChange"
|
||||
size="small" />
|
||||
</el-form-item>
|
||||
<el-form-item label="审核状态">
|
||||
<el-radio-group v-model="labPat.jgbz">
|
||||
@ -131,9 +135,10 @@ const props = defineProps({
|
||||
default: () => { }
|
||||
}
|
||||
});
|
||||
|
||||
const lastJgbz = ref();
|
||||
watch(() => props.labPat, (newVal) => {
|
||||
lastValue.value = JSON.stringify(newVal);
|
||||
lastJgbz.value = newVal.jgbz;
|
||||
})
|
||||
// 计算属性:将布尔值转换为 0/1 绑定到 labPat.jzbz
|
||||
const jzbzSwitch = ref(0);
|
||||
@ -291,13 +296,59 @@ const resetMain = () => {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
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;
|
||||
position: relative;
|
||||
height: 100%;
|
||||
@ -306,16 +357,36 @@ const resetMain = () => {
|
||||
|
||||
|
||||
.el-form-item {
|
||||
margin-bottom: 5px;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
.el-form-item__label {
|
||||
padding-bottom: 5px;
|
||||
padding-bottom: 0px;
|
||||
color: #08355E;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
// pointer-events: none;
|
||||
|
||||
:deep(.el-radio__label) {
|
||||
color: #08355E;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
:deep(.el-switch__label) {
|
||||
color: #08355E;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
.flex-between {
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.sh_box {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
|
||||
@ -5,8 +5,10 @@
|
||||
<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(3)">取消审核</el-button>
|
||||
<el-button type="primary" plain @click="openItemDictDialog">新增</el-button>
|
||||
<el-button type="primary" plain @click="handleBatchDelete">删除</el-button>
|
||||
<el-button type="primary" plain :disabled="labPat.jgbz != null && labPat.jgbz != 0"
|
||||
@click="openItemDictDialog">新增</el-button>
|
||||
<el-button type="primary" :disabled="labPat.jgbz != null && labPat.jgbz != 0" plain
|
||||
@click="handleBatchDelete">删除</el-button>
|
||||
</div>
|
||||
<div>
|
||||
<el-button type="primary" plain icon="Files" @click="printHandle">打印</el-button>
|
||||
@ -23,8 +25,10 @@
|
||||
</el-table-column>
|
||||
<el-table-column prop="csjg" label="结果">
|
||||
<template #default="scope">
|
||||
<el-input v-model="scope.row.csjg" size="small" class="full-width-input" :disabled="readonly"
|
||||
@blur="handleCsjgEnter(scope.row)" @keyup.enter="handleCsjgEnter(scope.row)"></el-input>
|
||||
<el-input v-if="labPat.jgbz == 0 || labPat.jgbz == null" v-model="scope.row.csjg" size="small"
|
||||
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>
|
||||
</el-table-column>
|
||||
<el-table-column prop="refs" label="参考值" show-overflow-tooltip>
|
||||
@ -131,10 +135,10 @@
|
||||
|
||||
<script setup>
|
||||
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 ItemInput from "@/views/liswork/work/components/ItemInput.vue";
|
||||
import { log } from "vxe-pc-ui";
|
||||
import { classCom } from '@/utils/classCom'
|
||||
// 组件属性定义
|
||||
const props = defineProps({
|
||||
tableData: { type: Array, default: () => [] },
|
||||
@ -424,6 +428,7 @@ const handleItemSelect = async (selectedItem) => {
|
||||
const emits = defineEmits([
|
||||
'fetchLabResults',
|
||||
'changeStatus',
|
||||
'previewHandle'
|
||||
]);
|
||||
|
||||
// 解构props
|
||||
@ -469,10 +474,10 @@ const getRowUniqueKey = (row) => {
|
||||
*/
|
||||
const handleCsjgEnter = async (row) => {
|
||||
await saveCsjgChange(row);
|
||||
// nextTick(() => {
|
||||
// const input = document.activeElement;
|
||||
// if (input.tagName === "INPUT") input.blur();
|
||||
// });
|
||||
nextTick(() => {
|
||||
const input = document.activeElement;
|
||||
if (input.tagName === "INPUT") input.blur();
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
@ -671,14 +676,30 @@ const handleBatchDelete = () => {
|
||||
};
|
||||
|
||||
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) {
|
||||
// ElMessage.success("打印成功");
|
||||
classCom.printBase64PDF(res.data)
|
||||
}
|
||||
})
|
||||
};
|
||||
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);
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -14,16 +14,23 @@
|
||||
style="width:140px"></el-date-picker>
|
||||
</el-form-item>
|
||||
<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">
|
||||
<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 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>
|
||||
<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-icon color="#3c80d9" size="20" style="margin-right: 10px;" class="cp">
|
||||
@ -36,11 +43,11 @@
|
||||
</el-form>
|
||||
<el-row :gutter="5">
|
||||
<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 :span="16">
|
||||
<LabResult ref="labResultRef" v-model:labPat="labPat" :tableData="labResuts" :tableKey="queryParams"
|
||||
@fetchLabResults="fetchLabResults" @changeStatus="changeStatus" />
|
||||
<LabResult ref="labResultRef" v-model:labPat="labPat" :tableData="labResuts" :tableKey="labPat"
|
||||
@fetchLabResults="fetchLabResults" @changeStatus="changeStatus" @previewHandle="previewHandle" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
@ -104,13 +111,18 @@
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
|
||||
<el-dialog v-model="previewShow" title="预览" width="90vw" :close-on-click-modal="false">
|
||||
<iFrame v-if="pdfUrl" :src="pdfUrl" />
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, nextTick, onMounted, toRaw } from '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
|
||||
import LabResult from './components/labresult.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 { ElMessage, ElMessageBox } from "element-plus";
|
||||
import { log } from 'vxe-pc-ui';
|
||||
|
||||
|
||||
const previewShow = ref(false);
|
||||
|
||||
const queryParams = ref({
|
||||
pageNum: 1,
|
||||
@ -181,9 +195,15 @@ const loading = ref(false)
|
||||
const total = ref(0)
|
||||
|
||||
const rules = ref([])
|
||||
const instrGroupOptions = ref<{ zdmc: string, zddh: string }[]>([])
|
||||
const instrGroupOptions = ref<any[]>([])
|
||||
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) => {
|
||||
queryParams.value.instrGroup = val
|
||||
queryParams.value.yq = ''
|
||||
@ -199,6 +219,10 @@ const yqHandleChange = (val: string) => {
|
||||
labPat.value = {}
|
||||
fetchlabPatList()
|
||||
}
|
||||
const instrGroupFields = ref([
|
||||
{ prop: 'zddh', label: '代号', width: 80, enablePinyinSearch: true },
|
||||
{ prop: 'zdmc', label: '名称', width: 150, enablePinyinSearch: true },
|
||||
])
|
||||
|
||||
// 部门
|
||||
const loadinstrGroupOptions = () => {
|
||||
@ -209,14 +233,19 @@ const loadinstrGroupOptions = () => {
|
||||
getYqConfig()
|
||||
});
|
||||
}
|
||||
|
||||
const yqFields = ref([
|
||||
{ prop: 'yq', label: '代号', width: 80, enablePinyinSearch: true },
|
||||
{ prop: 'yqmc', label: '名称', width: 150, enablePinyinSearch: true },
|
||||
])
|
||||
// 仪器
|
||||
const getYqConfig = () => {
|
||||
querylabInstrListByLisgroup({ pageNum: 1, pageSize: 100, lisgroup: queryParams.value.instrGroup })
|
||||
.then((res: any) => {
|
||||
if (res.code == 200) {
|
||||
instrOptions.value = res.rows.map((item: any) => ({
|
||||
value: item.yq.trim(),
|
||||
label: item.yqmc
|
||||
yq: item.yq.trim(),
|
||||
yqmc: item.yqmc
|
||||
}))
|
||||
}
|
||||
})
|
||||
|
||||
@ -3,29 +3,17 @@
|
||||
<el-form ref="loginRef" :model="loginForm" :rules="loginRules" class="login-form">
|
||||
<h3 class="title">实验室管理系统</h3>
|
||||
<el-form-item prop="username">
|
||||
<el-input
|
||||
v-model="loginForm.username"
|
||||
type="text"
|
||||
size="large"
|
||||
auto-complete="off"
|
||||
placeholder="账号"
|
||||
>
|
||||
<el-input 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>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="password">
|
||||
<el-input
|
||||
v-model="loginForm.password"
|
||||
type="password"
|
||||
size="large"
|
||||
auto-complete="off"
|
||||
placeholder="密码"
|
||||
@keyup.enter="handleLogin"
|
||||
>
|
||||
<el-input v-model="loginForm.password" 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>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="code" v-if="captchaEnabled">
|
||||
<!-- <el-form-item prop="code" v-if="captchaEnabled">
|
||||
<el-input
|
||||
v-model="loginForm.code"
|
||||
size="large"
|
||||
@ -39,16 +27,10 @@
|
||||
<div class="login-code">
|
||||
<img :src="codeUrl" @click="getCode" class="login-code-img"/>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-form-item> -->
|
||||
<el-checkbox v-model="loginForm.rememberMe" style="margin:0px 0px 25px 0px;">记住密码</el-checkbox>
|
||||
<el-form-item style="width:100%;">
|
||||
<el-button
|
||||
:loading="loading"
|
||||
size="large"
|
||||
type="primary"
|
||||
style="width:100%;"
|
||||
@click.prevent="handleLogin"
|
||||
>
|
||||
<el-button :loading="loading" size="large" type="primary" style="width:100%;" @click.prevent="handleLogin">
|
||||
<span v-if="!loading">登 录</span>
|
||||
<span v-else>登 录 中...</span>
|
||||
</el-button>
|
||||
@ -171,6 +153,7 @@ getCookie();
|
||||
background-image: url("../assets/images/login-background.jpg");
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin: 0px auto 30px auto;
|
||||
text-align: center;
|
||||
@ -182,32 +165,39 @@ getCookie();
|
||||
background: #ffffff;
|
||||
width: 400px;
|
||||
padding: 25px 25px 5px 25px;
|
||||
|
||||
.el-input {
|
||||
height: 40px;
|
||||
|
||||
input {
|
||||
height: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
.input-icon {
|
||||
height: 39px;
|
||||
width: 14px;
|
||||
margin-left: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
.login-tip {
|
||||
font-size: 13px;
|
||||
text-align: center;
|
||||
color: #bfbfbf;
|
||||
}
|
||||
|
||||
.login-code {
|
||||
width: 33%;
|
||||
height: 40px;
|
||||
float: right;
|
||||
|
||||
img {
|
||||
cursor: pointer;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
.el-login-footer {
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
@ -220,6 +210,7 @@ getCookie();
|
||||
font-size: 12px;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
.login-code-img {
|
||||
height: 40px;
|
||||
padding-left: 12px;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user