优化
This commit is contained in:
parent
38189dfd11
commit
29990c0ba9
@ -178,4 +178,20 @@ export function querymbmc(data?: Object) {
|
|||||||
method: 'get',
|
method: 'get',
|
||||||
params: data
|
params: data
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
// 查询调整列表
|
||||||
|
export function queryInputcol(data?: Object) {
|
||||||
|
return request({
|
||||||
|
url: '/inputcol/query',
|
||||||
|
method: 'get',
|
||||||
|
params: data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// 整体调整列表
|
||||||
|
export function saveInputcol(data?: Object) {
|
||||||
|
return request({
|
||||||
|
url: '/inputcol/save',
|
||||||
|
method: 'put',
|
||||||
|
data: data
|
||||||
|
});
|
||||||
}
|
}
|
||||||
@ -17,9 +17,10 @@
|
|||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<div class="select-table-container">
|
<div class="select-table-container">
|
||||||
<el-select ref="selectTable" v-model="selectShowValue" :placeholder="props.placeholder" :size="props.size"
|
<el-select ref="selectTable" class="select-table__wrapper" v-model="selectShowValue"
|
||||||
:style="{ width: props.width }" @visible-change="visibleChange" @clear="clearHandle" :clearable="props.clearable"
|
:placeholder="props.placeholder" :size="props.size" :style="{ width: props.width }"
|
||||||
:disabled="disabled" v-bind="$attrs">
|
@visible-change="visibleChange" @clear="clearHandle" :clearable="props.clearable" :disabled="disabled"
|
||||||
|
v-bind="$attrs">
|
||||||
<template #empty>
|
<template #empty>
|
||||||
<div class="select-table-dropdown">
|
<div class="select-table-dropdown">
|
||||||
<div style="text-align: left;">
|
<div style="text-align: left;">
|
||||||
@ -215,6 +216,7 @@ watch(() => props.data, (newVal) => {
|
|||||||
|
|
||||||
// 输入框键盘事件处理(专门处理上下键)
|
// 输入框键盘事件处理(专门处理上下键)
|
||||||
const handleInputKeydown = (e: KeyboardEvent) => {
|
const handleInputKeydown = (e: KeyboardEvent) => {
|
||||||
|
|
||||||
// 仅处理上下方向回车键
|
// 仅处理上下方向回车键
|
||||||
if (!['ArrowUp', 'ArrowDown', 'Enter'].includes(e.key)) return;
|
if (!['ArrowUp', 'ArrowDown', 'Enter'].includes(e.key)) return;
|
||||||
// 阻止事件冒泡到输入框父元素
|
// 阻止事件冒泡到输入框父元素
|
||||||
@ -267,8 +269,14 @@ const handleKeydown = (e: any) => {
|
|||||||
tableRef.value.scrollToRow(filterData.value[currentIndex.value])
|
tableRef.value.scrollToRow(filterData.value[currentIndex.value])
|
||||||
// 回车确认
|
// 回车确认
|
||||||
if (e.key === "Enter") {
|
if (e.key === "Enter") {
|
||||||
|
if (searchKey.value.trim() !== '') {
|
||||||
|
// 如果输入框有内容,回车时先触发一次输入框的筛选逻辑,确保数据是最新的
|
||||||
|
filterDataHandle();
|
||||||
|
return
|
||||||
|
}
|
||||||
const currentRow = filterData.value[currentIndex.value];
|
const currentRow = filterData.value[currentIndex.value];
|
||||||
handleRowChange(currentRow);
|
handleRowChange(currentRow);
|
||||||
|
emits('enter-press');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -346,9 +354,9 @@ const setLabel = (val: any) => {
|
|||||||
const clearHandle = () => {
|
const clearHandle = () => {
|
||||||
selectShowValue.value = '';
|
selectShowValue.value = '';
|
||||||
currentRow.value = null;
|
currentRow.value = null;
|
||||||
tableRef.value.clearCurrentRow();
|
|
||||||
emits("update:data", null);
|
emits("update:data", null);
|
||||||
emits('getDataValue', null);
|
emits('getDataValue', null);
|
||||||
|
tableRef.value?.clearCurrentRow();
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -16,7 +16,8 @@
|
|||||||
<vxe-table :data="tableData" :loading="loading" border :checkbox-config="config.checkboxConfig"
|
<vxe-table :data="tableData" :loading="loading" border :checkbox-config="config.checkboxConfig"
|
||||||
:height="scrollYConfig.height" @checkbox-change="handleCheckboxChange" :row-config="rowConfig"
|
:height="scrollYConfig.height" @checkbox-change="handleCheckboxChange" :row-config="rowConfig"
|
||||||
:show-overflow="showOverflow" @current-change="handleRowClick" ref="tableRef" :size="size"
|
:show-overflow="showOverflow" @current-change="handleRowClick" ref="tableRef" :size="size"
|
||||||
:current-row="currentRow" :scroll-y="scrollYConfig" :tooltip-config="{ appendToBody: true, zIndex: 3000 }"
|
:class="{ 'drag-table': enableRowDrag }" :current-row="currentRow" :scroll-y="scrollYConfig"
|
||||||
|
:tooltip-config="{ appendToBody: true, zIndex: 3000 }"
|
||||||
:header-cell-class-name="enableColumnDrag ? 'el-table-header-cell' : ''" v-bind="$attrs">
|
:header-cell-class-name="enableColumnDrag ? 'el-table-header-cell' : ''" v-bind="$attrs">
|
||||||
<!-- 动态渲染列 -->
|
<!-- 动态渲染列 -->
|
||||||
<template v-for="(column, i) in columns" :key="`${column.field}-${i}`">
|
<template v-for="(column, i) in columns" :key="`${column.field}-${i}`">
|
||||||
@ -111,10 +112,15 @@ const props = defineProps({
|
|||||||
enableColumnDrag: {
|
enableColumnDrag: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
|
},
|
||||||
|
// 拖拽行
|
||||||
|
enableRowDrag: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const emits = defineEmits(['current-change', "column-drag-end", "selection-change"])
|
const emits = defineEmits(['current-change', "column-drag-end", "row-drag-end", "selection-change"])
|
||||||
|
|
||||||
const tableRef = ref<any>(null)
|
const tableRef = ref<any>(null)
|
||||||
const currentRow = ref<any>(null)
|
const currentRow = ref<any>(null)
|
||||||
@ -164,6 +170,10 @@ onMounted(() => {
|
|||||||
if (props.enableColumnDrag && tableRef.value) {
|
if (props.enableColumnDrag && tableRef.value) {
|
||||||
initColumnDrag();
|
initColumnDrag();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (props.enableRowDrag && tableRef.value) {
|
||||||
|
initRowDrag();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 监听数据变化时重置当前行
|
// 监听数据变化时重置当前行
|
||||||
@ -219,6 +229,38 @@ const initColumnDrag = () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 初始化行拖拽
|
||||||
|
const initRowDrag = () => {
|
||||||
|
|
||||||
|
const tableBody = tableRef.value.$el.querySelector('.vxe-table--body-wrapper tbody');
|
||||||
|
const sortable = new Sortable(tableBody, {
|
||||||
|
animation: 150, // 拖拽动画时长
|
||||||
|
ghostClass: 'sortable-ghost', // 拖拽占位符样式
|
||||||
|
chosenClass: 'sortable-chosen', // 选中行样式
|
||||||
|
// 拖拽结束回调
|
||||||
|
onEnd: (evt: any) => {
|
||||||
|
const { oldIndex, newIndex } = evt
|
||||||
|
if (oldIndex === newIndex) return // 未改变位置则不处理
|
||||||
|
|
||||||
|
// 调整数组顺序
|
||||||
|
const moveRow = props.tableData.splice(oldIndex, 1)[0]
|
||||||
|
props.tableData.splice(newIndex, 0, moveRow)
|
||||||
|
|
||||||
|
// 重新更新排序值
|
||||||
|
props.tableData.forEach((item: any, index) => {
|
||||||
|
item.sort = index + 1
|
||||||
|
})
|
||||||
|
// console.log("🚀 ~ initRowDrag ~ props.tableData:", props.tableData)
|
||||||
|
emits('row-drag-end', {
|
||||||
|
oldIndex,
|
||||||
|
newIndex,
|
||||||
|
list: props.tableData
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 暴露公共方法
|
// 暴露公共方法
|
||||||
defineExpose({
|
defineExpose({
|
||||||
|
|||||||
@ -142,7 +142,7 @@ onMounted(() => {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
position: relative;
|
position: relative;
|
||||||
//background: #fff;
|
//background: #fff;
|
||||||
background: #0d9488;
|
background: #304156;
|
||||||
box-shadow: 0 1px 4px rgba(0, 21, 41, 0.15);
|
box-shadow: 0 1px 4px rgba(0, 21, 41, 0.15);
|
||||||
//box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
|
//box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
1
src/types/SelectTable.d.ts
vendored
1
src/types/SelectTable.d.ts
vendored
@ -1,6 +1,7 @@
|
|||||||
export interface Emits {
|
export interface Emits {
|
||||||
(e: "update:data", val: any): void;
|
(e: "update:data", val: any): void;
|
||||||
(e: "getDataValue", val: any): void;
|
(e: "getDataValue", val: any): void;
|
||||||
|
(e: "enter-press"): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
|
|||||||
@ -258,7 +258,7 @@ interface QueryParams {
|
|||||||
const ybJyrq = ref('')
|
const ybJyrq = ref('')
|
||||||
|
|
||||||
watch(() => labPat.value, (newValue) => {
|
watch(() => labPat.value, (newValue) => {
|
||||||
queryParams.value.ybh = newValue.ybh;
|
queryParams.value.ybh = newValue.ybh ? newValue.ybh : '1';
|
||||||
ybJyrq.value = newValue.jyrq;
|
ybJyrq.value = newValue.jyrq;
|
||||||
if (newValue.jgbz == '2') {
|
if (newValue.jgbz == '2') {
|
||||||
activeName.value = 'first'
|
activeName.value = 'first'
|
||||||
@ -407,7 +407,7 @@ const handleinstrGroupChange = () => {
|
|||||||
}
|
}
|
||||||
const mbStore = useCommonStore();
|
const mbStore = useCommonStore();
|
||||||
const yqHandleChange = () => {
|
const yqHandleChange = () => {
|
||||||
queryParams.value.ybh = ''
|
queryParams.value.ybh = '1'
|
||||||
zbLabResuts.value = [];
|
zbLabResuts.value = [];
|
||||||
labPat.value = {}
|
labPat.value = {}
|
||||||
mbStore.setLxsrList([]);
|
mbStore.setLxsrList([]);
|
||||||
@ -454,7 +454,7 @@ const resultsHandle = (flag: boolean) => {
|
|||||||
}
|
}
|
||||||
fetchLabResults()
|
fetchLabResults()
|
||||||
}
|
}
|
||||||
const labInfo: any = ref({})
|
const labInfo: any = ref({}) // 当前选中样本的基本信息,用于左边和中间表单数据载入和更新
|
||||||
const highlightRowIndex = ref(-1)
|
const highlightRowIndex = ref(-1)
|
||||||
const labPatListRef = ref()
|
const labPatListRef = ref()
|
||||||
//样本列表点击切换样本信息,同步载入左边样本信息表单和中间结果表单
|
//样本列表点击切换样本信息,同步载入左边样本信息表单和中间结果表单
|
||||||
@ -702,14 +702,6 @@ const searchJobs = async (text: string, page: number, size: number) => {
|
|||||||
fetchlabPatList()
|
fetchlabPatList()
|
||||||
}
|
}
|
||||||
|
|
||||||
// const handleSizeChange = (size: number) => {
|
|
||||||
// queryParams.value.pageSize = size
|
|
||||||
// fetchlabPatList()
|
|
||||||
// }
|
|
||||||
// const handleCurrentChange = (page: number) => {
|
|
||||||
// queryParams.value.pageNum = page
|
|
||||||
// fetchlabPatList()
|
|
||||||
// }
|
|
||||||
|
|
||||||
//载入样本列表(右边labpatlist.vue组件)
|
//载入样本列表(右边labpatlist.vue组件)
|
||||||
const fetchlabPatList = () => {
|
const fetchlabPatList = () => {
|
||||||
@ -735,7 +727,7 @@ const fetchlabPatList = () => {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
labInfo.value = {}
|
labInfo.value = {}
|
||||||
labPat.value = {}
|
labPat.value = { ybh: '1' }
|
||||||
zbLabResuts.value = []
|
zbLabResuts.value = []
|
||||||
handleCreate()
|
handleCreate()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,17 +5,17 @@
|
|||||||
@keyup.enter="handleInputFocus" />
|
@keyup.enter="handleInputFocus" />
|
||||||
<el-button type="primary" :size="aotuSize" @click="batchHandle">扫码</el-button>
|
<el-button type="primary" :size="aotuSize" @click="batchHandle">扫码</el-button>
|
||||||
</div>
|
</div>
|
||||||
<el-form :model="labPat" label-width="4.5rem" class="compact-form" label-position="right">
|
<el-form :model="labPat" ref="formInfoRefs" label-width="4.5rem" class="compact-form" label-position="right">
|
||||||
<div :class="['sh_box', getColor(lastJgbz)]" v-if="lastJgbz != null && lastJgbz != 0 && lastJgbz != 'C'">
|
<div :class="['sh_box', getColor(lastJgbz)]" v-if="lastJgbz != null && lastJgbz != 0 && lastJgbz != 'C'">
|
||||||
<div class="text">{{ getLableType(lastJgbz) }}</div>
|
<div class="text">{{ getLableType(lastJgbz) }}</div>
|
||||||
</div>
|
</div>
|
||||||
<template v-for="v in labSysList" :key="v.xh">
|
<template v-for="(v, index) in labSysList" :key="v.xh">
|
||||||
<el-row :gutter="10" v-if="v.mrts == '病人来源'">
|
<el-row :gutter="10" v-if="v.mrts == '病人来源'">
|
||||||
<el-col :span="18">
|
<el-col :span="18">
|
||||||
<el-form-item :label="v.zdts" v-if="v.kj == '1'">
|
<el-form-item :label="v.zdts" v-if="v.kj == '1'">
|
||||||
<SelectTable v-model:data="labPat[v.zdmc]" :fields="brlyFields" :dictType="v.dict" placeholder=""
|
<SelectTable v-model:data="labPat[v.zdmc]" :fields="brlyFields" :dictType="v.dict" placeholder=""
|
||||||
label="label" value="value" objKey="value" :border="true" size="small"
|
label="label" value="value" objKey="value" :border="true" size="small" @getDataValue="handleFieldChange"
|
||||||
@getDataValue="handleFieldChange" />
|
@enter-press="selectEnter(index)" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="6">
|
<el-col :span="6">
|
||||||
@ -25,37 +25,44 @@
|
|||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<el-form-item :label="v.zdts" v-if="v.kj == '1' && !v.dict && v.mrts != '年龄'">
|
<el-form-item :label="v.zdts" v-if="v.kj == '1' && !v.dict && v.mrts != '年龄'">
|
||||||
<el-input v-if="v.zdlb == '1'" v-model="labPat[v.zdmc]" @change="handleFieldChange" size="small" />
|
<el-input v-if="v.zdlb == '1'" v-model="labPat[v.zdmc]" @change="handleFieldChange" size="small"
|
||||||
|
@keydown.enter="nextFocus" />
|
||||||
|
|
||||||
|
|
||||||
<el-date-picker v-if="v.zdlb == '3'" v-model="labPat[v.zdmc]" type="datetime" format="YYYY-MM-DD HH:mm:ss"
|
<el-date-picker v-if="v.zdlb == '3'" v-model="labPat[v.zdmc]" type="datetime" format="YYYY-MM-DD HH:mm:ss"
|
||||||
value-format="YYYY-MM-DD HH:mm:ss" @change="handleFieldChange" size="small" style="width: 100%;" />
|
value-format="YYYY-MM-DD HH:mm:ss" @change="handleFieldChange" size="small" style="width: 100%;"
|
||||||
|
@keydown.enter="nextFocus" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
|
|
||||||
<el-form-item :label="v.zdts" v-if="v.kj == '1' && v.mrts == '年龄'">
|
<el-form-item :label="v.zdts" v-if="v.kj == '1' && v.mrts == '年龄'">
|
||||||
<el-col :span="14" v-if="v.mrts == '年龄'">
|
<el-col :span="14" v-if="v.mrts == '年龄'">
|
||||||
<el-input v-model="labPat[v.zdmc]" @change="handleFieldChange" style="width:100%" size="small" />
|
<el-input v-model="labPat[v.zdmc]" @change="handleFieldChange" style="width:100%" size="small"
|
||||||
|
@keydown.enter="nextFocus" />
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="10">
|
<el-col :span="10">
|
||||||
<SelectTable v-model:data="labPat.nldw" :fields="ksdhFields" dictType="AU" label="label" value="value"
|
<SelectTable v-model:data="labPat.nldw" :fields="ksdhFields" dictType="AU" label="label" value="value"
|
||||||
objKey="value" :border="true" size="small" @getDataValue="handleFieldChange" placeholder="" />
|
objKey="value" :border="true" size="small" @getDataValue="handleFieldChange" placeholder=""
|
||||||
|
@enter-press="selectEnter(index + 1)" />
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item :label="v.zdts"
|
<el-form-item :label="v.zdts"
|
||||||
v-if="v.dict && v.kj == '1' && v.mrts != '病人来源' && v.mrts != '年龄单位' && v.mrts != '检验医师' && v.mrts != '核对医师'">
|
v-if="v.dict && v.kj == '1' && v.mrts != '病人来源' && v.mrts != '年龄单位' && v.mrts != '检验医师' && v.mrts != '核对医师'">
|
||||||
<SelectTable v-model:data="labPat[v.zdmc]" :fields="ksdhFields" :dictType="v.dict" label="label" value="value"
|
<SelectTable v-model:data="labPat[v.zdmc]" :fields="ksdhFields" :dictType="v.dict" label="label" value="value"
|
||||||
objKey="value" :border="true" size="small" @getDataValue="handleFieldChange" placeholder="" />
|
objKey="value" :border="true" size="small" @getDataValue="handleFieldChange" placeholder=""
|
||||||
|
@enter-press="selectEnter(index + 1)" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item :label="v.zdts" v-if="v.mrts == '检验医师' && v.kj == '1'">
|
<el-form-item :label="v.zdts" v-if="v.mrts == '检验医师' && v.kj == '1'">
|
||||||
<SelectTable v-model:data="labPat[v.zdmc]" :fields="ysFields" :tableData="userList || []" label="nickName"
|
<SelectTable v-model:data="labPat[v.zdmc]" :fields="ysFields" :tableData="userList || []" label="nickName"
|
||||||
value="userName" objKey="userName" :border="true" size="small" @getDataValue="getJyysData" placeholder="" />
|
value="userName" objKey="userName" :border="true" size="small" @getDataValue="getJyysData" placeholder=""
|
||||||
|
@enter-press="selectEnter(index + 1)" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="v.zdts" v-if="v.mrts == '核对医师' && v.kj == '1'">
|
<el-form-item :label="v.zdts" v-if="v.mrts == '核对医师' && v.kj == '1'">
|
||||||
<SelectTable v-model:data="labPat[v.zdmc]" :fields="ysFields" :tableData="userList || []" label="nickName"
|
<SelectTable v-model:data="labPat[v.zdmc]" :fields="ysFields" :tableData="userList || []" label="nickName"
|
||||||
value="userName" objKey="userName" :border="true" size="small" @getDataValue="getHdysData" placeholder="" />
|
value="userName" objKey="userName" :border="true" size="small" @getDataValue="getHdysData" placeholder=""
|
||||||
|
@enter-press="selectEnter(index + 1)" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
</el-form>
|
</el-form>
|
||||||
@ -332,6 +339,63 @@ const getColor = (type: string) => {
|
|||||||
return 'default';
|
return 'default';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const formInfoRefs = useTemplateRef('formInfoRefs')
|
||||||
|
const currentTarget = ref(null);
|
||||||
|
// 回车跳转到下一个表单元素
|
||||||
|
const nextFocus = (e?: Event, idx?: number) => {
|
||||||
|
if (e) e.preventDefault() // 禁止回车提交表单
|
||||||
|
|
||||||
|
// 找到所有可聚焦的表单项:
|
||||||
|
const els = formInfoRefs.value.$el.querySelectorAll(
|
||||||
|
'input:not([type="hidden"]):not([disabled]), select:not([disabled]), textarea:not([disabled]), ' +
|
||||||
|
'.select-table__wrapper .el-select__input:not([disabled]), ' + '.el-date-editor input:not([disabled])'
|
||||||
|
);
|
||||||
|
|
||||||
|
const arr = Array.from(els).filter((el: any) => {
|
||||||
|
// 额外过滤:排除隐藏元素、禁用状态的父级封装组件(如 SelectTable 被 disabled 时)
|
||||||
|
const isHidden = el.offsetParent === null;
|
||||||
|
const isDisabled = el.hasAttribute('disabled') || el.parentElement?.closest('.is-disabled') !== null;
|
||||||
|
return !isHidden && !isDisabled;
|
||||||
|
});
|
||||||
|
|
||||||
|
let index: number;
|
||||||
|
if (!idx) {
|
||||||
|
// 找到当前触发元素在列表中的位置
|
||||||
|
currentTarget.value = e?.target as HTMLElement;
|
||||||
|
// 兼容 SelectTable:如果点击的是组件外层,定位到内部输入框
|
||||||
|
if (currentTarget.value.closest('.select-table-container')) {
|
||||||
|
currentTarget.value = currentTarget.value.closest('.select-table-container').querySelector('.el-select__input');
|
||||||
|
}
|
||||||
|
|
||||||
|
index = arr.findIndex((item: any) => item === currentTarget.value || item.contains(currentTarget.value));
|
||||||
|
} else {
|
||||||
|
index = idx;
|
||||||
|
}
|
||||||
|
console.log('arr==>', arr);
|
||||||
|
|
||||||
|
// 跳转到下一个可聚焦元素(循环到第一个 if 最后一个)
|
||||||
|
if (index > -1) {
|
||||||
|
const nextIndex = (index + 1) % arr.length;
|
||||||
|
// 确保下一个元素存在且可聚焦
|
||||||
|
if (arr[nextIndex]) {
|
||||||
|
nextTick(() => {
|
||||||
|
(arr[nextIndex] as HTMLElement)?.focus();
|
||||||
|
});
|
||||||
|
console.log('arr[nextIndex]==>', arr[nextIndex], index, nextIndex);
|
||||||
|
// 针对 SelectTable 额外处理:聚焦后激活下拉框
|
||||||
|
if ((arr[nextIndex] as HTMLElement).closest('.select-table-container')) {
|
||||||
|
(arr[nextIndex] as HTMLElement).dispatchEvent(new Event('click'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const selectEnter = (index: number) => {
|
||||||
|
const emptyEvent = new Event('keydown', { cancelable: true });
|
||||||
|
nextFocus(emptyEvent, index + 1)
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// 监听保存病人结果
|
// 监听保存病人结果
|
||||||
emitter.on('wswSaveResult', () => {
|
emitter.on('wswSaveResult', () => {
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<el-dialog v-model="visible" :title="title" :width="500" :close-on-click-modal="false" :draggable="true">
|
<el-dialog v-model="visible" :title="title" :width="500" :close-on-click-modal="false" :draggable="true"
|
||||||
|
@close="cancel">
|
||||||
<el-form ref="formRef" :model="formValue" label-width="100px">
|
<el-form ref="formRef" :model="formValue" label-width="100px">
|
||||||
<!-- 用户代号 -->
|
<!-- 用户代号 -->
|
||||||
<el-form-item label="用户代号:">
|
<el-form-item label="用户代号:">
|
||||||
@ -99,9 +100,12 @@ const handleConfirm = async () => {
|
|||||||
// 表单验证
|
// 表单验证
|
||||||
const valid = await formRef.value.validate();
|
const valid = await formRef.value.validate();
|
||||||
if (valid) {
|
if (valid) {
|
||||||
checkYsUser({ ...props.formValue, ...props.labPatKey }).then((res: any) => {
|
console.log('Form is valid', props.formValue);
|
||||||
|
|
||||||
|
checkYsUser({ ...props.labPatKey, ...props.formValue, }).then((res: any) => {
|
||||||
if (res.code == 0) {
|
if (res.code == 0) {
|
||||||
emit('confirm', props.formValue)
|
emit('confirm', props.formValue)
|
||||||
|
visible.value = false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@ -302,7 +302,7 @@ const handleinstrGroupChange = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const yqHandleChange = () => {
|
const yqHandleChange = () => {
|
||||||
queryParams.value.ybh = ''
|
queryParams.value.ybh = '1'
|
||||||
labResuts.value = []
|
labResuts.value = []
|
||||||
labPat.value = {}
|
labPat.value = {}
|
||||||
mbStore.setLxsrList([]);
|
mbStore.setLxsrList([]);
|
||||||
|
|||||||
@ -5,17 +5,17 @@
|
|||||||
@keyup.enter="handleInputFocus" />
|
@keyup.enter="handleInputFocus" />
|
||||||
<el-button type="primary" :size="aotuSize" @click="batchHandle">扫码</el-button>
|
<el-button type="primary" :size="aotuSize" @click="batchHandle">扫码</el-button>
|
||||||
</div>
|
</div>
|
||||||
<el-form :model="labPat" label-width="4.5rem" class="compact-form" label-position="right">
|
<el-form :model="labPat" ref="formInfoRefs" label-width="4.5rem" class="compact-form" label-position="right">
|
||||||
<div :class="['sh_box', getColor(lastJgbz)]" v-if="lastJgbz != null && lastJgbz != 0 && lastJgbz != 'C'">
|
<div :class="['sh_box', getColor(lastJgbz)]" v-if="lastJgbz != null && lastJgbz != 0 && lastJgbz != 'C'">
|
||||||
<div class="text">{{ getLableType(lastJgbz) }}</div>
|
<div class="text">{{ getLableType(lastJgbz) }}</div>
|
||||||
</div>
|
</div>
|
||||||
<template v-for="v in labSysList" :key="v.xh">
|
<template v-for="(v, index) in labSysList" :key="v.xh">
|
||||||
<el-row :gutter="10" v-if="v.mrts == '病人来源'">
|
<el-row :gutter="10" v-if="v.mrts == '病人来源'">
|
||||||
<el-col :span="18">
|
<el-col :span="18">
|
||||||
<el-form-item :label="v.zdts" v-if="v.kj == '1'">
|
<el-form-item :label="v.zdts" v-if="v.kj == '1'">
|
||||||
<SelectTable v-model:data="labPat[v.zdmc]" :fields="brlyFields" :dictType="v.dict" placeholder=""
|
<SelectTable v-model:data="labPat[v.zdmc]" :fields="brlyFields" :dictType="v.dict" placeholder=""
|
||||||
label="label" value="value" objKey="value" :border="true" size="small"
|
label="label" value="value" objKey="value" size="small" @getDataValue="handleFieldChange"
|
||||||
@getDataValue="handleFieldChange" />
|
@enter-press="selectEnter(index)" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="6">
|
<el-col :span="6">
|
||||||
@ -25,37 +25,44 @@
|
|||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<el-form-item :label="v.zdts" v-if="v.kj == '1' && !v.dict && v.mrts != '年龄'">
|
<el-form-item :label="v.zdts" v-if="v.kj == '1' && !v.dict && v.mrts != '年龄'">
|
||||||
<el-input v-if="v.zdlb == '1'" v-model="labPat[v.zdmc]" @change="handleFieldChange" size="small" />
|
<el-input v-if="v.zdlb == '1'" v-model="labPat[v.zdmc]" @change="handleFieldChange" size="small"
|
||||||
|
@keydown.enter="nextFocus" />
|
||||||
|
|
||||||
|
|
||||||
<el-date-picker v-if="v.zdlb == '3'" v-model="labPat[v.zdmc]" type="datetime" format="YYYY-MM-DD HH:mm:ss"
|
<el-date-picker v-if="v.zdlb == '3'" v-model="labPat[v.zdmc]" type="datetime" format="YYYY-MM-DD HH:mm:ss"
|
||||||
value-format="YYYY-MM-DD HH:mm:ss" @change="handleFieldChange" size="small" style="width: 100%;" />
|
value-format="YYYY-MM-DD HH:mm:ss" @change="handleFieldChange" size="small" style="width: 100%;"
|
||||||
|
@keydown.enter="nextFocus" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
|
|
||||||
<el-form-item :label="v.zdts" v-if="v.kj == '1' && v.mrts == '年龄'">
|
<el-form-item :label="v.zdts" v-if="v.kj == '1' && v.mrts == '年龄'">
|
||||||
<el-col :span="14" v-if="v.mrts == '年龄'">
|
<el-col :span="14" v-if="v.mrts == '年龄'">
|
||||||
<el-input v-model="labPat[v.zdmc]" @change="handleFieldChange" style="width:100%" size="small" />
|
<el-input v-model="labPat[v.zdmc]" @change="handleFieldChange" style="width:100%" size="small"
|
||||||
|
@keydown.enter="nextFocus" />
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="10">
|
<el-col :span="10">
|
||||||
<SelectTable v-model:data="labPat.nldw" :fields="ksdhFields" dictType="AU" label="label" value="value"
|
<SelectTable v-model:data="labPat.nldw" :fields="ksdhFields" dictType="AU" label="label" value="value"
|
||||||
objKey="value" :border="true" size="small" @getDataValue="handleFieldChange" placeholder="" />
|
objKey="value" size="small" @getDataValue="handleFieldChange" placeholder=""
|
||||||
|
@enter-press="selectEnter(index + 1)" />
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item :label="v.zdts"
|
<el-form-item :label="v.zdts"
|
||||||
v-if="v.dict && v.kj == '1' && v.mrts != '病人来源' && v.mrts != '年龄单位' && v.mrts != '检验医师' && v.mrts != '核对医师'">
|
v-if="v.dict && v.kj == '1' && v.mrts != '病人来源' && v.mrts != '年龄单位' && v.mrts != '检验医师' && v.mrts != '核对医师'">
|
||||||
<SelectTable v-model:data="labPat[v.zdmc]" :fields="ksdhFields" :dictType="v.dict" label="label" value="value"
|
<SelectTable v-model:data="labPat[v.zdmc]" :fields="ksdhFields" :dictType="v.dict" label="label" value="value"
|
||||||
objKey="value" :border="true" size="small" @getDataValue="handleFieldChange" placeholder="" />
|
objKey="value" size="small" @getDataValue="handleFieldChange" placeholder=""
|
||||||
|
@enter-press="selectEnter(index + 1)" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item :label="v.zdts" v-if="v.mrts == '检验医师' && v.kj == '1'">
|
<el-form-item :label="v.zdts" v-if="v.mrts == '检验医师' && v.kj == '1'">
|
||||||
<SelectTable v-model:data="labPat[v.zdmc]" :fields="ysFields" :tableData="userList || []" label="nickName"
|
<SelectTable v-model:data="labPat[v.zdmc]" :fields="ysFields" :tableData="userList || []" label="nickName"
|
||||||
value="userName" objKey="userName" :border="true" size="small" @getDataValue="getJyysData" placeholder="" />
|
value="userName" objKey="userName" size="small" @getDataValue="getJyysData" placeholder=""
|
||||||
|
@enter-press="selectEnter(index + 1)" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="v.zdts" v-if="v.mrts == '核对医师' && v.kj == '1'">
|
<el-form-item :label="v.zdts" v-if="v.mrts == '核对医师' && v.kj == '1'">
|
||||||
<SelectTable v-model:data="labPat[v.zdmc]" :fields="ysFields" :tableData="userList || []" label="nickName"
|
<SelectTable v-model:data="labPat[v.zdmc]" :fields="ysFields" :tableData="userList || []" label="nickName"
|
||||||
value="userName" objKey="userName" :border="true" size="small" @getDataValue="getHdysData" placeholder="" />
|
value="userName" objKey="userName" size="small" @getDataValue="getHdysData" placeholder=""
|
||||||
|
@enter-press="selectEnter(index + 1)" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
</el-form>
|
</el-form>
|
||||||
@ -112,7 +119,6 @@ const lastJgbz = ref();
|
|||||||
const sqhValue = ref(''); // 条码号
|
const sqhValue = ref(''); // 条码号
|
||||||
const sqhRef = ref();
|
const sqhRef = ref();
|
||||||
watch(() => props.labPat, (newVal) => {
|
watch(() => props.labPat, (newVal) => {
|
||||||
// console.log('newVal==>', newVal);
|
|
||||||
lastValue.value = JSON.stringify(newVal);
|
lastValue.value = JSON.stringify(newVal);
|
||||||
lastJgbz.value = newVal?.jgbz;
|
lastJgbz.value = newVal?.jgbz;
|
||||||
sqhValue.value = '';
|
sqhValue.value = '';
|
||||||
@ -326,6 +332,62 @@ const getColor = (type: string) => {
|
|||||||
return 'default';
|
return 'default';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const formInfoRefs = useTemplateRef('formInfoRefs')
|
||||||
|
const currentTarget = ref(null);
|
||||||
|
// 回车跳转到下一个表单元素
|
||||||
|
const nextFocus = (e?: Event, idx?: number) => {
|
||||||
|
if (e) e.preventDefault() // 禁止回车提交表单
|
||||||
|
|
||||||
|
// 找到所有可聚焦的表单项:
|
||||||
|
const els = formInfoRefs.value.$el.querySelectorAll(
|
||||||
|
'input:not([type="hidden"]):not([disabled]), select:not([disabled]), textarea:not([disabled]), ' +
|
||||||
|
'.select-table__wrapper .el-select__input:not([disabled]), ' + '.el-date-editor input:not([disabled])'
|
||||||
|
);
|
||||||
|
|
||||||
|
const arr = Array.from(els).filter((el: any) => {
|
||||||
|
// 额外过滤:排除隐藏元素、禁用状态的父级封装组件(如 SelectTable 被 disabled 时)
|
||||||
|
const isHidden = el.offsetParent === null;
|
||||||
|
const isDisabled = el.hasAttribute('disabled') || el.parentElement?.closest('.is-disabled') !== null;
|
||||||
|
return !isHidden && !isDisabled;
|
||||||
|
});
|
||||||
|
|
||||||
|
let index: number;
|
||||||
|
if (!idx) {
|
||||||
|
// 找到当前触发元素在列表中的位置
|
||||||
|
currentTarget.value = e?.target as HTMLElement;
|
||||||
|
// 兼容 SelectTable:如果点击的是组件外层,定位到内部输入框
|
||||||
|
if (currentTarget.value.closest('.select-table-container')) {
|
||||||
|
currentTarget.value = currentTarget.value.closest('.select-table-container').querySelector('.el-select__input');
|
||||||
|
}
|
||||||
|
|
||||||
|
index = arr.findIndex((item: any) => item === currentTarget.value || item.contains(currentTarget.value));
|
||||||
|
} else {
|
||||||
|
index = idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 跳转到下一个可聚焦元素(循环到第一个 if 最后一个)
|
||||||
|
if (index > -1) {
|
||||||
|
const nextIndex = (index + 1) % arr.length;
|
||||||
|
// 确保下一个元素存在且可聚焦
|
||||||
|
if (arr[nextIndex]) {
|
||||||
|
nextTick(() => {
|
||||||
|
(arr[nextIndex] as HTMLElement)?.focus();
|
||||||
|
});
|
||||||
|
|
||||||
|
// 针对 SelectTable 额外处理:聚焦后激活下拉框
|
||||||
|
if ((arr[nextIndex] as HTMLElement).closest('.select-table-container')) {
|
||||||
|
(arr[nextIndex] as HTMLElement).dispatchEvent(new Event('click'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const selectEnter = (index: number) => {
|
||||||
|
const emptyEvent = new Event('keydown', { cancelable: true });
|
||||||
|
nextFocus(emptyEvent, index + 1)
|
||||||
|
}
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// 监听保存病人结果
|
// 监听保存病人结果
|
||||||
emitter.on('saveResult', () => {
|
emitter.on('saveResult', () => {
|
||||||
|
|||||||
@ -0,0 +1,117 @@
|
|||||||
|
/**
|
||||||
|
* @file index.vue 仪器默认参数设置
|
||||||
|
* @author: w
|
||||||
|
* @since: 2026-04-03
|
||||||
|
*/
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="params-box">
|
||||||
|
<el-row :gutter="10" class="table-toolbar">
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button type="primary" plain icon="Check" @click="handleSave">保存</el-button>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<div class="table-box">
|
||||||
|
<CustomVxeTable :table-data="tableData" :columns="tableColumns" size="small"
|
||||||
|
:scrollYConfig="{ enabled: true, rSize: 30, height: '100%', }" class="mytable-style" ref="tableRef"
|
||||||
|
:enableRowDrag="true" @row-drag-end="handleRowDragEnd">
|
||||||
|
<template #zdts="{ row }">
|
||||||
|
<el-input v-model="row.zdts" placeholder="请输入内容" class="full-width-input" />
|
||||||
|
</template>
|
||||||
|
<!-- 默认值 -->
|
||||||
|
<template #mrz="{ row }">
|
||||||
|
<SelectTable v-model:data="row.mrz" v-if="row.dict" :dictType="row.dict" objKey="value"
|
||||||
|
class="full-width-input" placeholder="" />
|
||||||
|
<el-input v-model="row.mrz" placeholder="请输入内容" class="full-width-input" v-else />
|
||||||
|
</template>
|
||||||
|
<template #mrts="{ row }">
|
||||||
|
<el-input v-model="row.mrts" placeholder="请输入内容" class="full-width-input" />
|
||||||
|
</template>
|
||||||
|
<template #kj="{ row }">
|
||||||
|
<el-checkbox v-model="row.kj" true-value="1" false-value="0" />
|
||||||
|
</template>
|
||||||
|
<template #kybj="{ row }">
|
||||||
|
<el-checkbox v-model="row.kybj" true-value="1" false-value="0" />
|
||||||
|
</template>
|
||||||
|
</CustomVxeTable>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { queryInputcol, saveInputcol } from '@/api/liswork/xtwh/ComOpt'
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
|
||||||
|
const yq = defineModel<string>()
|
||||||
|
const tableData = ref([])
|
||||||
|
const tableColumns = ref([
|
||||||
|
{ field: 'zdts', title: '字段名称', align: 'center', slotName: 'zdts', resizable: true },
|
||||||
|
{ field: 'mrz', title: '默认值', align: 'center', slotName: 'mrz', resizable: true },
|
||||||
|
{ field: 'mrts', title: '提示文字', align: 'center', slotName: 'mrts', resizable: true },
|
||||||
|
{ field: 'kj', title: '可见', align: 'center', slotName: 'kj', resizable: true },
|
||||||
|
{ field: 'kybj', title: '可以编辑', align: 'center', slotName: 'kybj', resizable: true },
|
||||||
|
])
|
||||||
|
|
||||||
|
const handleRowDragEnd = (data: any) => {
|
||||||
|
tableData.value = []
|
||||||
|
// 更新行顺序
|
||||||
|
nextTick(() => {
|
||||||
|
tableData.value = data.list.map((item: any) => {
|
||||||
|
return {
|
||||||
|
...item,
|
||||||
|
xh: item.sort * 10,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const tableRef = useTemplateRef('tableRef')
|
||||||
|
|
||||||
|
const handleSave = () => {
|
||||||
|
saveInputcol(tableData.value).then(res => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
ElMessage.success('保存成功')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const getParamsList = async () => {
|
||||||
|
queryInputcol({ yq: yq.value }).then(res => {
|
||||||
|
tableData.value = res.data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(yq, (newVal) => {
|
||||||
|
if (newVal) {
|
||||||
|
getParamsList()
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
immediate: true,
|
||||||
|
deep: true
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.params-box {
|
||||||
|
height: calc(100% - 58px);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-box {
|
||||||
|
height: calc(100% - 45px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-toolbar {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
height: 36px;
|
||||||
|
line-height: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 可拖拽表格行样式提示 */
|
||||||
|
:deep(.drag-table .vxe-body--row) {
|
||||||
|
cursor: move;
|
||||||
|
/* 鼠标移入行显示拖拽光标 */
|
||||||
|
transition: background-color 0.2s;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -14,7 +14,8 @@
|
|||||||
</el-col> -->
|
</el-col> -->
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<el-form ref="form" :model="formData" :rules="rules" label-width="120px" class="form-inline" inline>
|
<el-form ref="form" :model="formData" :rules="rules" label-width="120px" class="form-inline" inline
|
||||||
|
:validate-on-rule-change="false">
|
||||||
<div style="display: flex;">
|
<div style="display: flex;">
|
||||||
<el-form-item label="项目" prop="xmdh">
|
<el-form-item label="项目" prop="xmdh">
|
||||||
<SelectTable v-model:data="xmdh" :tableData="xmList" style="width: 12rem;" @getDataValue='getXmInfo' />
|
<SelectTable v-model:data="xmdh" :tableData="xmList" style="width: 12rem;" @getDataValue='getXmInfo' />
|
||||||
|
|||||||
@ -54,7 +54,7 @@ const tableConfig = ref({
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
//退拽属性
|
//拖拽属性
|
||||||
const handleRowDragEnd = (data: any) => {
|
const handleRowDragEnd = (data: any) => {
|
||||||
// 更新行顺序
|
// 更新行顺序
|
||||||
dataList.value = data.list.map((item: any) => {
|
dataList.value = data.list.map((item: any) => {
|
||||||
|
|||||||
@ -49,6 +49,7 @@ import { useCommonStore } from '@/store/modules/commonStore';
|
|||||||
import SysGlobal from './components/sysGlobal/index.vue'
|
import SysGlobal from './components/sysGlobal/index.vue'
|
||||||
import SysInput from './components/sysInput/index.vue'
|
import SysInput from './components/sysInput/index.vue'
|
||||||
import SysReport from './components/sysReport/index.vue'
|
import SysReport from './components/sysReport/index.vue'
|
||||||
|
import SysDefaultParams from './components/sysDefaultParams/index.vue'
|
||||||
import SysParameter from './components/sysParameter/index.vue'
|
import SysParameter from './components/sysParameter/index.vue'
|
||||||
import SysChannel from './components/sysChannel/index.vue'
|
import SysChannel from './components/sysChannel/index.vue'
|
||||||
import SysSort from './components/sysSort/index.vue'
|
import SysSort from './components/sysSort/index.vue'
|
||||||
@ -108,12 +109,13 @@ const queryParams = ref<QueryParams>({
|
|||||||
const tabList = [
|
const tabList = [
|
||||||
{ key: 'SysGlobal', label: '全局设定', component: SysGlobal },
|
{ key: 'SysGlobal', label: '全局设定', component: SysGlobal },
|
||||||
{ key: 'SysInput', label: '界面设定', component: SysInput },
|
{ key: 'SysInput', label: '界面设定', component: SysInput },
|
||||||
|
{ key: 'SysDefaultParams', label: '默认界面参数', component: SysDefaultParams },
|
||||||
{ key: 'SysParameter', label: '参数', component: SysParameter },
|
{ key: 'SysParameter', label: '参数', component: SysParameter },
|
||||||
{ key: 'SysChannel', label: '通道号', component: SysChannel },
|
{ key: 'SysChannel', label: '通道号', component: SysChannel },
|
||||||
{ key: 'SysSort', label: '项目排序', component: SysSort },
|
{ key: 'SysSort', label: '项目排序', component: SysSort },
|
||||||
{ key: 'SysReport', label: '报告单设置', component: SysReport },
|
{ key: 'SysReport', label: '报告单设置', component: SysReport },
|
||||||
]
|
]
|
||||||
const activeName = ref('SysGlobal')
|
const activeName = ref('SysDefaultParams')
|
||||||
|
|
||||||
// 计算当前要渲染的组件
|
// 计算当前要渲染的组件
|
||||||
const currentComponent = computed(() => {
|
const currentComponent = computed(() => {
|
||||||
|
|||||||
@ -1,8 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="login">
|
<div class="login">
|
||||||
<!-- <FloatingLines :enabled-waves="['top', 'middle', 'bottom']" :line-count="[10, 15, 20]" :line-distance="[8, 6, 4]"
|
<el-form ref="loginRef" class="login-form" :model="loginForm" :rules="loginRules" :hide-required-asterisk="true">
|
||||||
:bend-radius="5.0" :bend-strength="-0.5" :interactive="true" :parallax="true" /> -->
|
|
||||||
<el-form ref="loginRef" class="login-form">
|
|
||||||
<div class="login-header">
|
<div class="login-header">
|
||||||
<div class="login-logo">
|
<div class="login-logo">
|
||||||
<img src="@/assets/images/logo_new.png" alt="系统Logo" />
|
<img src="@/assets/images/logo_new.png" alt="系统Logo" />
|
||||||
@ -17,8 +15,9 @@
|
|||||||
<el-tabs v-model="activeName" type="card" @tab-click="handleClick" class="login-tabs">
|
<el-tabs v-model="activeName" type="card" @tab-click="handleClick" class="login-tabs">
|
||||||
<!-- 工号登录 Tab -->
|
<!-- 工号登录 Tab -->
|
||||||
<el-tab-pane label="账号密码登录" name="first">
|
<el-tab-pane label="账号密码登录" name="first">
|
||||||
<el-form-item label="医疗机构:" prop="loginYLJG" class="custom-select">
|
<el-form-item label="医疗机构:" prop="loginParam.loginYLJG" class="custom-select">
|
||||||
<el-select v-model="loginForm.loginParam.loginYLJG" placeholder="请选择医疗机构" style="width: 100%">
|
<el-select v-model="loginForm.loginParam.loginYLJG" placeholder="请选择医疗机构" style="width: 100%"
|
||||||
|
@change="handleChange">
|
||||||
<template #prefix>
|
<template #prefix>
|
||||||
<svg-icon icon-class="international" class="el-input__icon input-icon" />
|
<svg-icon icon-class="international" class="el-input__icon input-icon" />
|
||||||
</template>
|
</template>
|
||||||
@ -26,7 +25,7 @@
|
|||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="用户代号:" prop="username">
|
<el-form-item label="用户工号:" 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>
|
<template #prefix>
|
||||||
<svg-icon icon-class="user" class="el-input__icon input-icon" />
|
<svg-icon icon-class="user" class="el-input__icon input-icon" />
|
||||||
@ -42,12 +41,6 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<!-- 修复:移除空的el-form-item,验证码关闭时不渲染任何内容 -->
|
|
||||||
<el-form-item prop="code" v-if="!captchaEnabled" size="large">
|
|
||||||
|
|
||||||
</el-form-item>
|
|
||||||
|
|
||||||
<el-form-item prop="code" label="验 证 码 :" v-if="captchaEnabled">
|
<el-form-item prop="code" label="验 证 码 :" v-if="captchaEnabled">
|
||||||
<el-input v-model="loginForm.code" size="large" auto-complete="off" placeholder="验证码" style="width: 53%"
|
<el-input v-model="loginForm.code" size="large" auto-complete="off" placeholder="验证码" style="width: 53%"
|
||||||
@keyup.enter="handleLogin">
|
@keyup.enter="handleLogin">
|
||||||
@ -75,7 +68,7 @@
|
|||||||
<el-tab-pane label="扫码登录" name="second">
|
<el-tab-pane label="扫码登录" name="second">
|
||||||
<div class="tab-placeholder">
|
<div class="tab-placeholder">
|
||||||
<el-icon class="placeholder-icon">
|
<el-icon class="placeholder-icon">
|
||||||
<Sms />
|
<!-- <Sms /> -->
|
||||||
</el-icon>
|
</el-icon>
|
||||||
<p>正在加载二维码...</p>
|
<p>正在加载二维码...</p>
|
||||||
<el-button type="success" icon="wechat" class="wechat-login-btn">刷新二维码</el-button>
|
<el-button type="success" icon="wechat" class="wechat-login-btn">刷新二维码</el-button>
|
||||||
@ -85,7 +78,7 @@
|
|||||||
<el-tab-pane label="UKEY登录" name="third">
|
<el-tab-pane label="UKEY登录" name="third">
|
||||||
<div class="tab-placeholder">
|
<div class="tab-placeholder">
|
||||||
<el-icon class="placeholder-icon">
|
<el-icon class="placeholder-icon">
|
||||||
<Wechat />
|
<!-- <Wechat /> -->
|
||||||
</el-icon>
|
</el-icon>
|
||||||
<p>UKEY登录功能开发中...</p>
|
<p>UKEY登录功能开发中...</p>
|
||||||
</div>
|
</div>
|
||||||
@ -94,7 +87,9 @@
|
|||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<div class="el-login-footer">
|
<div class="el-login-footer">
|
||||||
<span>版权所有(R)2022-2026 {{ oem.compay }} 电话:{{ oem.phone }} E-mail:{{ oem.Email }} version:{{ oem.version }}</span>
|
<span>版权所有(R){{ oem.copyrightyear }} {{ oem.compay }} 电话:{{ oem.phone }} E-mail:{{ oem.Email }} version:{{
|
||||||
|
oem.version
|
||||||
|
}}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -102,12 +97,11 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref, watch, getCurrentInstance, onMounted } from 'vue';
|
import { ref, watch, getCurrentInstance, onMounted } from 'vue';
|
||||||
import { useRoute, useRouter } from 'vue-router';
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
import { useFingerprint } from '@/utils/useFingerprint';
|
import { getCodeImg, getInfo, getLocalconfig, login } from "@/api/login";
|
||||||
import { getCodeImg, getInfo, getLocalconfig } from "@/api/login";
|
|
||||||
import Cookies from "js-cookie";
|
import Cookies from "js-cookie";
|
||||||
import { encrypt, decrypt } from "@/utils/jsencrypt";
|
import { encrypt, decrypt } from "@/utils/jsencrypt";
|
||||||
import useUserStore from '@/store/modules/user';
|
import useUserStore from '@/store/modules/user';
|
||||||
import FloatingLines from '@/components/Ballpit/index.vue';
|
|
||||||
import { useCommonStore } from '@/store/modules/commonStore'
|
import { useCommonStore } from '@/store/modules/commonStore'
|
||||||
const mbStore = useCommonStore();
|
const mbStore = useCommonStore();
|
||||||
// 初始化响应式变量
|
// 初始化响应式变量
|
||||||
@ -116,31 +110,32 @@ const userStore = useUserStore();
|
|||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const oem = ref({
|
const oem = ref({
|
||||||
appname: "实验室信息管理系统",
|
appname: "区域检验数据平台",
|
||||||
phone: "",
|
phone: "",
|
||||||
compay: "",
|
compay: "",
|
||||||
version: "",
|
version: "",
|
||||||
Email: ""
|
Email: "",
|
||||||
|
copyrightyear: ""
|
||||||
});
|
});
|
||||||
const loginRef = ref(null); // 修复:直接用ref获取表单引用
|
const loginRef = useTemplateRef('loginRef');
|
||||||
const loginForm = ref({
|
const loginForm = ref({
|
||||||
username: "admin",
|
username: "",
|
||||||
password: "",
|
password: "",
|
||||||
rememberMe: false,
|
rememberMe: false,
|
||||||
code: "",
|
code: "",
|
||||||
uuid: "",
|
uuid: "",
|
||||||
loginParam: { loginYLJG: "", localid: "" }
|
loginParam: { loginYLJG: '1', localid: undefined, loginYLJGName: '' }
|
||||||
});
|
});
|
||||||
const selectOptions = ref([{ id: '1', name: '总院' }]);
|
const selectOptions = ref([]);
|
||||||
const loginRules = ref({ // 修复:改为ref响应式,方便动态修改
|
const loginRules = ref({
|
||||||
username: [{ required: true, trigger: "blur", message: "请输入您的账号" }],
|
'loginParam.loginYLJG': [{ required: true, message: '请选择医疗机构', trigger: 'change' }],
|
||||||
// password: [{ required: true, trigger: "blur", message: "请输入您的密码" }],
|
username: [{ required: true, trigger: "blur", message: "请输入您的工号" }],
|
||||||
hospid: [{ required: true, message: '请选择医疗机构', trigger: 'change' }],
|
password: [{ required: true, trigger: "blur", message: "请输入您的密码" }],
|
||||||
code: [{ required: true, trigger: "change", message: "请输入验证码" }]
|
code: [{ required: true, trigger: "change", message: "请输入验证码" }]
|
||||||
});
|
});
|
||||||
const codeUrl = ref("");
|
const codeUrl = ref("");
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const captchaEnabled = ref(true);
|
const captchaEnabled = ref(false);
|
||||||
const register = ref(false);
|
const register = ref(false);
|
||||||
const redirect = ref(undefined);
|
const redirect = ref(undefined);
|
||||||
|
|
||||||
@ -155,32 +150,43 @@ watch(
|
|||||||
{ immediate: true, deep: false }
|
{ immediate: true, deep: false }
|
||||||
);
|
);
|
||||||
|
|
||||||
// 登录方法(修复proxy.$refs问题)
|
const handleChange = (value) => {
|
||||||
|
const item = selectOptions.value.find(item => item.id == value);
|
||||||
|
loginForm.value.loginParam.loginYLJG = value;
|
||||||
|
loginForm.value.loginParam.loginYLJGName = item?.name || '';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 登录方法
|
||||||
const handleLogin = async () => {
|
const handleLogin = async () => {
|
||||||
loginForm.value.loginParam.loginYLJG
|
loginRef.value.validate((valid) => {
|
||||||
loading.value = true;
|
if (valid) {
|
||||||
Cookies.set("czlis_username", loginForm.value.username, { expires: 30 });
|
loading.value = true;
|
||||||
Cookies.set("czlis_loginYLJG", loginForm.value.loginParam.loginYLJG, { expires: 30 });
|
Cookies.set("czlis_username", loginForm.value.username, { expires: 30 });
|
||||||
// 调用action的登录方法
|
Cookies.set("czlis_loginYLJG", loginForm.value.loginParam.loginYLJG, { expires: 30 });
|
||||||
userStore.login(loginForm.value).then(() => {
|
Cookies.set("czlis_loginYLJGName", loginForm.value.loginParam.loginYLJGName, { expires: 30 });
|
||||||
const query = route.query;
|
// loginForm.value.password = encrypt(loginForm.value.password); // 密码加密
|
||||||
const otherQueryParams = Object.keys(query).reduce((acc, cur) => {
|
|
||||||
if (cur !== "redirect") {
|
userStore.login(loginForm.value).then(() => {
|
||||||
acc[cur] = query[cur];
|
const query = route.query;
|
||||||
}
|
const otherQueryParams = Object.keys(query).reduce((acc, cur) => {
|
||||||
return acc;
|
if (cur !== "redirect") {
|
||||||
}, {});
|
acc[cur] = query[cur];
|
||||||
const targetPath = redirect.value || "/";
|
}
|
||||||
if (route.path !== targetPath) {
|
return acc;
|
||||||
router.push({ path: targetPath, query: otherQueryParams });
|
}, {});
|
||||||
|
const targetPath = redirect.value || "/";
|
||||||
|
if (route.path !== targetPath) {
|
||||||
|
router.push({ path: targetPath, query: otherQueryParams });
|
||||||
|
}
|
||||||
|
}).catch(() => {
|
||||||
|
loading.value = false;
|
||||||
|
// 重新获取验证码
|
||||||
|
if (captchaEnabled.value) {
|
||||||
|
getCode();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}).catch(() => {
|
})
|
||||||
loading.value = false;
|
|
||||||
// 重新获取验证码
|
|
||||||
if (captchaEnabled.value) {
|
|
||||||
getCode();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// 获取验证码
|
// 获取验证码
|
||||||
@ -191,12 +197,6 @@ const getCode = () => {
|
|||||||
codeUrl.value = "data:image/gif;base64," + res.img;
|
codeUrl.value = "data:image/gif;base64," + res.img;
|
||||||
loginForm.value.uuid = res.uuid;
|
loginForm.value.uuid = res.uuid;
|
||||||
}
|
}
|
||||||
// 验证码关闭时移除校验规则,避免报错
|
|
||||||
if (!captchaEnabled.value) {
|
|
||||||
loginRules.value.code = [];
|
|
||||||
} else {
|
|
||||||
loginRules.value.code = [{ required: true, trigger: "change", message: "请输入验证码" }];
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -204,70 +204,44 @@ const getCode = () => {
|
|||||||
const getCookie = () => {
|
const getCookie = () => {
|
||||||
const cookieUsername = Cookies.get("czlis_username");
|
const cookieUsername = Cookies.get("czlis_username");
|
||||||
const cookieloginYLJG = Cookies.get("czlis_loginYLJG");
|
const cookieloginYLJG = Cookies.get("czlis_loginYLJG");
|
||||||
//console.log('cookieloginYLJG', cookieloginYLJG);
|
loginForm.value.username = cookieUsername;
|
||||||
if (cookieUsername !== undefined && cookieUsername !== null && cookieUsername !== "") {
|
if (cookieloginYLJG) {
|
||||||
loginForm.value.username = cookieUsername;
|
|
||||||
}
|
|
||||||
if (cookieloginYLJG !== undefined && cookieloginYLJG !== null && cookieloginYLJG !== "") {
|
|
||||||
loginForm.value.loginParam.loginYLJG = cookieloginYLJG;
|
loginForm.value.loginParam.loginYLJG = cookieloginYLJG;
|
||||||
|
loginForm.value.loginParam.loginYLJGName = selectOptions.value.find(item => item.id == cookieloginYLJG)?.name || '';
|
||||||
|
} else {
|
||||||
|
loginForm.value.loginParam.loginYLJG = selectOptions.value[0]?.id || '1';
|
||||||
|
loginForm.value.loginParam.loginYLJGName = selectOptions.value[0]?.name || '';
|
||||||
}
|
}
|
||||||
//console.log('loginForm', loginForm);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// 获取本地配置
|
// 获取本地配置
|
||||||
const Localconfig = (localid) => {
|
const Localconfig = () => {
|
||||||
getLocalconfig({ localid }).then(res => {
|
getLocalconfig().then(res => {
|
||||||
if (res) {
|
if (res) {
|
||||||
const { localconfig, hosplist, oem: oemData } = res;
|
const { localconfig, hosplist, oem: oemData } = res;
|
||||||
mbStore.setDefaultConfig(localconfig)
|
mbStore.setDefaultConfig(localconfig)
|
||||||
// 修复:赋值oem数据,显示动态标题
|
|
||||||
if (oemData) oem.value = oemData;
|
if (oemData) oem.value = oemData;
|
||||||
// console.log('oemData', oemData);
|
selectOptions.value = hosplist || [];
|
||||||
// console.log('oem', oem.value);
|
getCookie();
|
||||||
// 修复:判重后更新下拉选项,避免递归
|
|
||||||
if (JSON.stringify(selectOptions.value) !== JSON.stringify(hosplist)) {
|
|
||||||
selectOptions.value = hosplist || [{ id: '1', name: '总院' }];
|
|
||||||
// 判重后赋值,避免重复修改触发更新
|
|
||||||
if (!selectOptions.value.some(item => item.id === loginForm.value.hospid)) {
|
|
||||||
loginForm.value.loginParam.loginYLJG = selectOptions.value[0]?.id || '1';
|
|
||||||
}
|
|
||||||
getCookie();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
console.error("获取本地配置失败:", err);
|
console.error("获取本地配置失败:", err);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// 获取指纹并加载配置
|
|
||||||
const { getFingerprint } = useFingerprint();
|
|
||||||
const refreshFingerprint = async () => {
|
|
||||||
try {
|
|
||||||
const res = await getFingerprint();
|
|
||||||
loginForm.value.loginParam.localid = res.visitorId
|
|
||||||
Localconfig(res.visitorId);
|
|
||||||
} catch (err) {
|
|
||||||
console.error("获取指纹失败:", err);
|
|
||||||
Localconfig("default"); // 兜底使用默认ID
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Tab切换事件(移除activeName手动赋值,避免递归)
|
// Tab切换事件(移除activeName手动赋值,避免递归)
|
||||||
const handleClick = (tab) => {
|
const handleClick = (tab) => {
|
||||||
console.log('当前Tab:', tab.name);
|
// console.log('当前Tab:', tab.name);
|
||||||
// 仅在切回账号密码登录时刷新验证码
|
// 仅在切回账号密码登录时刷新验证码
|
||||||
if (tab.name === 'first' && captchaEnabled.value) {
|
if (tab.name === 'first' && captchaEnabled.value) {
|
||||||
getCode();
|
getCode();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 页面挂载时初始化
|
|
||||||
onMounted(() => {
|
Localconfig();
|
||||||
refreshFingerprint();
|
getCode();
|
||||||
getCode();
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang='scss' scoped>
|
<style lang='scss' scoped>
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
/* 严格的类型检查选项 */
|
/* 严格的类型检查选项 */
|
||||||
"strict": true /* 启用所有严格的类型检查选项。 */,
|
"strict": true /* 启用所有严格的类型检查选项。 */,
|
||||||
|
"noImplicitAny": false,
|
||||||
/* 模块解析选项 */
|
/* 模块解析选项 */
|
||||||
"moduleResolution": "node" /* 指定模块解析策略:'node'(Node.js)或'classic'(TypeScript 1.6之前版本)。*/,
|
"moduleResolution": "node" /* 指定模块解析策略:'node'(Node.js)或'classic'(TypeScript 1.6之前版本)。*/,
|
||||||
"baseUrl": "." /* 用于解析非绝对模块名称的基准目录。 */,
|
"baseUrl": "." /* 用于解析非绝对模块名称的基准目录。 */,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user