Merge branch 'main' of http://47.97.125.165:8902/jiangs/lis8.0-vue3
This commit is contained in:
commit
fe03afe569
@ -131,4 +131,52 @@ export function getmediumList(data?: Object) {
|
|||||||
method: 'get',
|
method: 'get',
|
||||||
params: data
|
params: data
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
//获取培养基字典
|
||||||
|
export function getbactmediumList(data?: Object) {
|
||||||
|
return request({
|
||||||
|
url: '/lisworkgerm/getbactmedium',
|
||||||
|
method: 'get',
|
||||||
|
params: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
//新增培养基
|
||||||
|
export function insertmedium(data?: Object) {
|
||||||
|
return request({
|
||||||
|
url: '/lisworkgerm/insertmedium',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
//修改培养基
|
||||||
|
export function updatemedium(data?: Object) {
|
||||||
|
return request({
|
||||||
|
url: '/lisworkgerm/updatemedium',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
//删除培养基
|
||||||
|
export function deletemedium(data?: Object) {
|
||||||
|
return request({
|
||||||
|
url: '/lisworkgerm/deletemedium',
|
||||||
|
method: 'delete',
|
||||||
|
params: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
//删除培养基 Array
|
||||||
|
export function deletemediums(data?: Object) {
|
||||||
|
return request({
|
||||||
|
url: '/lisworkgerm/deletemedium',
|
||||||
|
method: 'delete',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
//微生物报告审核
|
||||||
|
export function cbebCheck(data?: Object) {
|
||||||
|
return request({
|
||||||
|
url: '/lisworkgerm/check',
|
||||||
|
method: 'get',
|
||||||
|
params: data
|
||||||
|
})
|
||||||
}
|
}
|
||||||
@ -1,12 +1,13 @@
|
|||||||
import request from '@/utils/request'
|
import request from '@/utils/request'
|
||||||
|
|
||||||
// 登录方法
|
// 登录方法
|
||||||
export function login(username, password, code, uuid) {
|
export function login(username, password, code, uuid,loginParam) {
|
||||||
const data = {
|
const data = {
|
||||||
username,
|
username,
|
||||||
password,
|
password,
|
||||||
code,
|
code,
|
||||||
uuid
|
uuid,
|
||||||
|
loginParam
|
||||||
}
|
}
|
||||||
return request({
|
return request({
|
||||||
url: '/login',
|
url: '/login',
|
||||||
@ -28,6 +29,17 @@ export function loginAnonymous(data) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getLocalconfig(data) {
|
||||||
|
return request({
|
||||||
|
url: '/getLocalconfig',
|
||||||
|
headers: {
|
||||||
|
isToken: false
|
||||||
|
},
|
||||||
|
method: 'get',
|
||||||
|
params: data,
|
||||||
|
timeout: 20000
|
||||||
|
})
|
||||||
|
}
|
||||||
// 注册方法
|
// 注册方法
|
||||||
export function register(data) {
|
export function register(data) {
|
||||||
return request({
|
return request({
|
||||||
|
|||||||
BIN
src/assets/images/logo_new.png
Normal file
BIN
src/assets/images/logo_new.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 79 KiB After Width: | Height: | Size: 6.7 KiB |
@ -286,4 +286,21 @@ aside {
|
|||||||
width: 3.125rem;
|
width: 3.125rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.next_box {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
|
.jtIcon {
|
||||||
|
width: 2.5rem;
|
||||||
|
height: 2rem;
|
||||||
|
line-height: 2rem;
|
||||||
|
font-size: 1rem;
|
||||||
|
text-align: center;
|
||||||
|
background-color: #1f6dd3;
|
||||||
|
color: #fff;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -395,6 +395,9 @@
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.el-table--default .cell {
|
||||||
|
padding: 0 0 0 .3125rem !important;
|
||||||
|
}
|
||||||
|
|
||||||
// 表格input宽度,表格select宽度
|
// 表格input宽度,表格select宽度
|
||||||
.full-width-input .el-input__inner .el-select__inner {
|
.full-width-input .el-input__inner .el-select__inner {
|
||||||
@ -411,6 +414,7 @@
|
|||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
background: transparent !important;
|
background: transparent !important;
|
||||||
padding: 0 !important;
|
padding: 0 !important;
|
||||||
|
padding-left: .3125rem !important;
|
||||||
outline: none;
|
outline: none;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
@ -422,6 +426,7 @@
|
|||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
background: transparent !important;
|
background: transparent !important;
|
||||||
padding: 0 !important;
|
padding: 0 !important;
|
||||||
|
padding-left: .3125rem !important;
|
||||||
outline: none;
|
outline: none;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
|
|||||||
0
src/components/Ballpit/index.vue
Normal file
0
src/components/Ballpit/index.vue
Normal file
@ -113,7 +113,7 @@ const visibleChange = (val: any) => {
|
|||||||
currentIndex.value = filterData.value.findIndex(item => item[props.value!] === props.data);
|
currentIndex.value = filterData.value.findIndex(item => item[props.value!] === props.data);
|
||||||
if (currentIndex.value >= 0) {
|
if (currentIndex.value >= 0) {
|
||||||
tableRef.value.setCurrentRow(filterData.value[currentIndex.value]);
|
tableRef.value.setCurrentRow(filterData.value[currentIndex.value]);
|
||||||
tableRef.value.setScrollTop(currentIndex.value * 25);
|
tableRef.value.setScrollTop(currentIndex.value * 30);
|
||||||
}
|
}
|
||||||
}, 10);
|
}, 10);
|
||||||
}
|
}
|
||||||
@ -235,7 +235,7 @@ const handleKeydown = (e: any) => {
|
|||||||
tableRef.value.setCurrentRow(filterData.value[currentIndex.value]);
|
tableRef.value.setCurrentRow(filterData.value[currentIndex.value]);
|
||||||
|
|
||||||
// 滚动到当前行
|
// 滚动到当前行
|
||||||
tableRef.value.setScrollTop(currentIndex.value * 25);
|
tableRef.value.setScrollTop(currentIndex.value * 30);
|
||||||
|
|
||||||
// 回车确认
|
// 回车确认
|
||||||
if (e.key === "Enter") {
|
if (e.key === "Enter") {
|
||||||
|
|||||||
@ -26,7 +26,10 @@
|
|||||||
<el-table-column v-if="!item.type && item.slot && item.visible" :prop="item.prop" :label="item.label"
|
<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'"
|
:width="item.width" :min-width="item.minWidth" :fixed="item.fixed" :align="item.align || 'left'"
|
||||||
:sortable="item.sortable" :show-overflow-tooltip="item.showOverflowTooltip !== false">
|
:sortable="item.sortable" :show-overflow-tooltip="item.showOverflowTooltip !== false">
|
||||||
<template #default="scope">
|
<template v-if="item.headerSlot" #header="scope">
|
||||||
|
<slot :name="item.headerSlot" :column="scope.column" :$index="scope.$index" />
|
||||||
|
</template>
|
||||||
|
<template v-if="item.slot" #default="scope">
|
||||||
<slot :name="item.slot" :row="scope.row" :$index="scope.$index" />
|
<slot :name="item.slot" :row="scope.row" :$index="scope.$index" />
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|||||||
@ -1,54 +1,67 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="navbar">
|
<div class="navbar">
|
||||||
<hamburger id="hamburger-container" :is-active="appStore.sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" />
|
<!-- 侧边栏折叠按钮(保留原有功能) -->
|
||||||
<breadcrumb id="breadcrumb-container" class="breadcrumb-container" v-if="!settingsStore.topNav" />
|
<hamburger
|
||||||
<top-nav id="topmenu-container" class="topmenu-container" v-if="settingsStore.topNav" />
|
id="hamburger-container"
|
||||||
|
:is-active="appStore.sidebar.opened"
|
||||||
|
class="hamburger-container"
|
||||||
|
@toggleClick="toggleSideBar"
|
||||||
|
/>
|
||||||
|
|
||||||
<div class="right-menu">
|
<!-- 核心改造:替换面包屑/顶部导航,改为产品名称 + 登录信息布局 -->
|
||||||
<template v-if="appStore.device !== 'mobile'">
|
<div class="custom-header-content">
|
||||||
<header-search id="header-search" class="right-menu-item" />
|
<!-- 左侧:APP产品名称 -->
|
||||||
|
<div class="app-name">
|
||||||
<!-- <el-tooltip content="源码地址" effect="dark" placement="bottom">
|
仙桃市第一人民医院检验系统 <!-- 替换为实际产品名 -->
|
||||||
<ruo-yi-git id="ruoyi-git" class="right-menu-item hover-effect" />
|
</div>
|
||||||
</el-tooltip> -->
|
|
||||||
|
|
||||||
<!-- <el-tooltip content="文档地址" effect="dark" placement="bottom">
|
|
||||||
<ruo-yi-doc id="ruoyi-doc" class="right-menu-item hover-effect" />
|
|
||||||
</el-tooltip> -->
|
|
||||||
|
|
||||||
|
<!-- 右侧:功能按钮 + 登录信息 + 原生设置菜单 -->
|
||||||
|
<div class="right-content">
|
||||||
|
<!-- 保留原有功能按钮(搜索、全屏、布局大小)
|
||||||
|
<template v-if="appStore.device !== 'mobile'">
|
||||||
|
<header-search id="header-search" class="right-menu-item" />
|
||||||
|
<screenfull id="screenfull" class="right-menu-item hover-effect" />
|
||||||
|
<el-tooltip content="布局大小" effect="dark" placement="bottom">
|
||||||
|
<size-select id="size-select" class="right-menu-item hover-effect" />
|
||||||
|
</el-tooltip>
|
||||||
|
</template>
|
||||||
|
-->
|
||||||
|
<!-- 登录人信息(姓名 + 角色) -->
|
||||||
|
<div class="user-info" v-if="userStore.nickName">
|
||||||
|
欢迎,{{ userStore.nickName }}({{ userStore.roleName }})
|
||||||
|
</div>
|
||||||
<screenfull id="screenfull" class="right-menu-item hover-effect" />
|
<screenfull id="screenfull" class="right-menu-item hover-effect" />
|
||||||
|
|
||||||
<el-tooltip content="布局大小" effect="dark" placement="bottom">
|
<!-- 原生个人信息/设置菜单(保留原有功能) -->
|
||||||
<size-select id="size-select" class="right-menu-item hover-effect" />
|
<div class="avatar-container">
|
||||||
</el-tooltip>
|
<el-dropdown @command="handleCommand" class="right-menu-item hover-effect" trigger="click">
|
||||||
</template>
|
<div class="avatar-wrapper">
|
||||||
<div class="avatar-container">
|
<img :src="userStore.avatar" class="user-avatar" />
|
||||||
<el-dropdown @command="handleCommand" class="right-menu-item hover-effect" trigger="click">
|
<el-icon><caret-bottom /></el-icon>
|
||||||
<div class="avatar-wrapper">
|
</div>
|
||||||
<img :src="userStore.avatar" class="user-avatar" />
|
<template #dropdown>
|
||||||
<el-icon><caret-bottom /></el-icon>
|
<el-dropdown-menu>
|
||||||
</div>
|
<router-link to="/user/profile">
|
||||||
<template #dropdown>
|
<el-dropdown-item>个人中心</el-dropdown-item>
|
||||||
<el-dropdown-menu>
|
</router-link>
|
||||||
<router-link to="/user/profile">
|
<el-dropdown-item command="setLayout" v-if="settingsStore.showSettings">
|
||||||
<el-dropdown-item>个人中心</el-dropdown-item>
|
<span>布局设置</span>
|
||||||
</router-link>
|
</el-dropdown-item>
|
||||||
<el-dropdown-item command="setLayout" v-if="settingsStore.showSettings">
|
<el-dropdown-item divided command="logout">
|
||||||
<span>布局设置</span>
|
<span>退出登录</span>
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
<el-dropdown-item divided command="logout">
|
</el-dropdown-menu>
|
||||||
<span>退出登录</span>
|
</template>
|
||||||
</el-dropdown-item>
|
</el-dropdown>
|
||||||
</el-dropdown-menu>
|
</div>
|
||||||
</template>
|
|
||||||
</el-dropdown>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ElMessageBox } from 'element-plus'
|
import {ElMessageBox} from 'element-plus'
|
||||||
|
// 引入原有组件
|
||||||
import Breadcrumb from '@/components/Breadcrumb'
|
import Breadcrumb from '@/components/Breadcrumb'
|
||||||
import TopNav from '@/components/TopNav'
|
import TopNav from '@/components/TopNav'
|
||||||
import Hamburger from '@/components/Hamburger'
|
import Hamburger from '@/components/Hamburger'
|
||||||
@ -57,14 +70,34 @@ import SizeSelect from '@/components/SizeSelect'
|
|||||||
import HeaderSearch from '@/components/HeaderSearch'
|
import HeaderSearch from '@/components/HeaderSearch'
|
||||||
import RuoYiGit from '@/components/RuoYi/Git'
|
import RuoYiGit from '@/components/RuoYi/Git'
|
||||||
import RuoYiDoc from '@/components/RuoYi/Doc'
|
import RuoYiDoc from '@/components/RuoYi/Doc'
|
||||||
|
// 引入Store
|
||||||
import useAppStore from '@/store/modules/app'
|
import useAppStore from '@/store/modules/app'
|
||||||
import useUserStore from '@/store/modules/user'
|
import useUserStore from '@/store/modules/user'
|
||||||
import useSettingsStore from '@/store/modules/settings'
|
import useSettingsStore from '@/store/modules/settings'
|
||||||
|
// 引入图标和默认头像(可替换为你的默认头像)
|
||||||
|
import {CaretBottom} from '@element-plus/icons-vue'
|
||||||
|
|
||||||
const appStore = useAppStore()
|
const appStore = useAppStore()
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
const settingsStore = useSettingsStore()
|
const settingsStore = useSettingsStore()
|
||||||
|
|
||||||
|
// 处理角色名称(取第一个角色,多角色可自定义)
|
||||||
|
const roleName = computed(() => {
|
||||||
|
if (!userStore.roles || userStore.roles.length === 0) {
|
||||||
|
return '普通用户'
|
||||||
|
}
|
||||||
|
// 角色编码映射表:key 是你的 roles 编码,value 是要显示的中文
|
||||||
|
const roleMap = {
|
||||||
|
'ROLE_DEFAULT': '普通用户',
|
||||||
|
'admin': '管理员',
|
||||||
|
'ROLE_ADMIN': '超级管理员',
|
||||||
|
'ROLE_OPERATOR': '操作员' // 按你的实际角色编码添加
|
||||||
|
}
|
||||||
|
// 取第一个角色编码,映射为中文
|
||||||
|
return roleMap[userStore.roles[0]] || userStore.roles[0]
|
||||||
|
})
|
||||||
|
|
||||||
|
// 原有方法保留
|
||||||
function toggleSideBar() {
|
function toggleSideBar() {
|
||||||
appStore.toggleSideBar()
|
appStore.toggleSideBar()
|
||||||
}
|
}
|
||||||
@ -91,10 +124,12 @@ function logout() {
|
|||||||
userStore.logOut().then(() => {
|
userStore.logOut().then(() => {
|
||||||
location.href = '/index';
|
location.href = '/index';
|
||||||
})
|
})
|
||||||
}).catch(() => { });
|
}).catch(() => {
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const emits = defineEmits(['setLayout'])
|
const emits = defineEmits(['setLayout'])
|
||||||
|
|
||||||
function setLayout() {
|
function setLayout() {
|
||||||
emits('setLayout');
|
emits('setLayout');
|
||||||
}
|
}
|
||||||
@ -102,16 +137,20 @@ function setLayout() {
|
|||||||
|
|
||||||
<style lang='scss' scoped>
|
<style lang='scss' scoped>
|
||||||
.navbar {
|
.navbar {
|
||||||
height: 50px;
|
height: 50px; /* 固定高度,与原有一致 */
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
position: relative;
|
position: relative;
|
||||||
background: #fff;
|
//background: #fff;
|
||||||
box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
|
background: #0d9488;
|
||||||
|
box-shadow: 0 1px 4px rgba(0, 21, 41, 0.15);
|
||||||
|
//box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
|
||||||
|
display: flex; /* 改为flex布局,确保子元素对齐 */
|
||||||
|
align-items: center; /* 垂直居中 */
|
||||||
|
|
||||||
.hamburger-container {
|
.hamburger-container {
|
||||||
line-height: 46px;
|
line-height: 50px; /* 与导航栏高度一致 */
|
||||||
height: 100%;
|
height: 100%;
|
||||||
float: left;
|
padding: 0 16px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: background 0.3s;
|
transition: background 0.3s;
|
||||||
-webkit-tap-highlight-color: transparent;
|
-webkit-tap-highlight-color: transparent;
|
||||||
@ -121,71 +160,94 @@ function setLayout() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.breadcrumb-container {
|
/* 核心布局:产品名称 + 右侧内容容器 */
|
||||||
float: left;
|
.custom-header-content {
|
||||||
}
|
|
||||||
|
|
||||||
.topmenu-container {
|
|
||||||
position: absolute;
|
|
||||||
left: 50px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.errLog-container {
|
|
||||||
display: inline-block;
|
|
||||||
vertical-align: top;
|
|
||||||
}
|
|
||||||
|
|
||||||
.right-menu {
|
|
||||||
float: right;
|
|
||||||
height: 100%;
|
|
||||||
line-height: 50px;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
flex: 1; /* 占满剩余宽度 */
|
||||||
|
padding: 0 20px;
|
||||||
|
height: 100%;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
&:focus {
|
/* 产品名称样式 */
|
||||||
outline: none;
|
.app-name {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #fff; /* 若依主题色,可替换为品牌色 */
|
||||||
|
white-space: nowrap; /* 防止换行 */
|
||||||
|
font-style: italic; /* 关键:字体倾斜 */
|
||||||
|
/* 可选优化:增加倾斜角度控制(默认 italic 约 14 度,可自定义) */
|
||||||
|
/* transform: skewX(-10deg); /* 向左倾斜 10 度,正负值控制倾斜方向 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 右侧内容容器(功能按钮 + 用户信息 + 头像菜单) */
|
||||||
|
.right-content {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px; /* 元素间距,可调整 */
|
||||||
|
white-space: nowrap; /* 防止换行 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 用户信息样式 */
|
||||||
|
.user-info {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 600;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
color: #e6f7f4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 原有右侧菜单样式调整 */
|
||||||
|
.right-menu-item {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 0 8px;
|
||||||
|
height: 100%;
|
||||||
|
font-size: 18px;
|
||||||
|
color: #5a5e66;
|
||||||
|
vertical-align: text-bottom;
|
||||||
|
|
||||||
|
&.hover-effect {
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background 0.3s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: rgba(0, 0, 0, 0.025);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.right-menu-item {
|
/* 头像容器样式调整 */
|
||||||
display: inline-block;
|
.avatar-container {
|
||||||
padding: 0 8px;
|
.avatar-wrapper {
|
||||||
height: 100%;
|
position: relative;
|
||||||
font-size: 18px;
|
display: flex;
|
||||||
color: #5a5e66;
|
align-items: center;
|
||||||
vertical-align: text-bottom;
|
gap: 4px; /* 头像与下拉图标间距 */
|
||||||
|
|
||||||
&.hover-effect {
|
.user-avatar {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: background 0.3s;
|
width: 36px; /* 调整头像大小 */
|
||||||
|
height: 36px;
|
||||||
|
border-radius: 50%; /* 圆形头像,可改为10px保持原有风格 */
|
||||||
|
object-fit: cover; /* 防止头像变形 */
|
||||||
|
}
|
||||||
|
|
||||||
&:hover {
|
i {
|
||||||
background: rgba(0, 0, 0, 0.025);
|
cursor: pointer;
|
||||||
}
|
font-size: 12px;
|
||||||
|
color: #5a5e66;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.avatar-container {
|
/* 隐藏原有面包屑和顶部导航(已替换) */
|
||||||
margin-right: 40px;
|
.breadcrumb-container,
|
||||||
|
.topmenu-container {
|
||||||
.avatar-wrapper {
|
display: none !important;
|
||||||
margin-top: 5px;
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
.user-avatar {
|
|
||||||
cursor: pointer;
|
|
||||||
width: 40px;
|
|
||||||
height: 40px;
|
|
||||||
border-radius: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
i {
|
|
||||||
cursor: pointer;
|
|
||||||
position: absolute;
|
|
||||||
right: -20px;
|
|
||||||
top: 25px;
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
191
src/layout/components/Navbarold.vue
Normal file
191
src/layout/components/Navbarold.vue
Normal file
@ -0,0 +1,191 @@
|
|||||||
|
<template>
|
||||||
|
<div class="navbar">
|
||||||
|
<hamburger id="hamburger-container" :is-active="appStore.sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" />
|
||||||
|
<breadcrumb id="breadcrumb-container" class="breadcrumb-container" v-if="!settingsStore.topNav" />
|
||||||
|
<top-nav id="topmenu-container" class="topmenu-container" v-if="settingsStore.topNav" />
|
||||||
|
|
||||||
|
<div class="right-menu">
|
||||||
|
<template v-if="appStore.device !== 'mobile'">
|
||||||
|
<header-search id="header-search" class="right-menu-item" />
|
||||||
|
|
||||||
|
<!-- <el-tooltip content="源码地址" effect="dark" placement="bottom">
|
||||||
|
<ruo-yi-git id="ruoyi-git" class="right-menu-item hover-effect" />
|
||||||
|
</el-tooltip> -->
|
||||||
|
|
||||||
|
<!-- <el-tooltip content="文档地址" effect="dark" placement="bottom">
|
||||||
|
<ruo-yi-doc id="ruoyi-doc" class="right-menu-item hover-effect" />
|
||||||
|
</el-tooltip> -->
|
||||||
|
|
||||||
|
<screenfull id="screenfull" class="right-menu-item hover-effect" />
|
||||||
|
|
||||||
|
<el-tooltip content="布局大小" effect="dark" placement="bottom">
|
||||||
|
<size-select id="size-select" class="right-menu-item hover-effect" />
|
||||||
|
</el-tooltip>
|
||||||
|
</template>
|
||||||
|
<div class="avatar-container">
|
||||||
|
<el-dropdown @command="handleCommand" class="right-menu-item hover-effect" trigger="click">
|
||||||
|
<div class="avatar-wrapper">
|
||||||
|
<img :src="userStore.avatar" class="user-avatar" />
|
||||||
|
<el-icon><caret-bottom /></el-icon>
|
||||||
|
</div>
|
||||||
|
<template #dropdown>
|
||||||
|
<el-dropdown-menu>
|
||||||
|
<router-link to="/user/profile">
|
||||||
|
<el-dropdown-item>个人中心</el-dropdown-item>
|
||||||
|
</router-link>
|
||||||
|
<el-dropdown-item command="setLayout" v-if="settingsStore.showSettings">
|
||||||
|
<span>布局设置</span>
|
||||||
|
</el-dropdown-item>
|
||||||
|
<el-dropdown-item divided command="logout">
|
||||||
|
<span>退出登录</span>
|
||||||
|
</el-dropdown-item>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</template>
|
||||||
|
</el-dropdown>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ElMessageBox } from 'element-plus'
|
||||||
|
import Breadcrumb from '@/components/Breadcrumb'
|
||||||
|
import TopNav from '@/components/TopNav'
|
||||||
|
import Hamburger from '@/components/Hamburger'
|
||||||
|
import Screenfull from '@/components/Screenfull'
|
||||||
|
import SizeSelect from '@/components/SizeSelect'
|
||||||
|
import HeaderSearch from '@/components/HeaderSearch'
|
||||||
|
import RuoYiGit from '@/components/RuoYi/Git'
|
||||||
|
import RuoYiDoc from '@/components/RuoYi/Doc'
|
||||||
|
import useAppStore from '@/store/modules/app'
|
||||||
|
import useUserStore from '@/store/modules/user'
|
||||||
|
import useSettingsStore from '@/store/modules/settings'
|
||||||
|
|
||||||
|
const appStore = useAppStore()
|
||||||
|
const userStore = useUserStore()
|
||||||
|
const settingsStore = useSettingsStore()
|
||||||
|
|
||||||
|
function toggleSideBar() {
|
||||||
|
appStore.toggleSideBar()
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleCommand(command) {
|
||||||
|
switch (command) {
|
||||||
|
case "setLayout":
|
||||||
|
setLayout();
|
||||||
|
break;
|
||||||
|
case "logout":
|
||||||
|
logout();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function logout() {
|
||||||
|
ElMessageBox.confirm('确定注销并退出系统吗?', '提示', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
}).then(() => {
|
||||||
|
userStore.logOut().then(() => {
|
||||||
|
location.href = '/index';
|
||||||
|
})
|
||||||
|
}).catch(() => { });
|
||||||
|
}
|
||||||
|
|
||||||
|
const emits = defineEmits(['setLayout'])
|
||||||
|
function setLayout() {
|
||||||
|
emits('setLayout');
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang='scss' scoped>
|
||||||
|
.navbar {
|
||||||
|
height: 50px;
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
background: #fff;
|
||||||
|
box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
|
||||||
|
|
||||||
|
.hamburger-container {
|
||||||
|
line-height: 46px;
|
||||||
|
height: 100%;
|
||||||
|
float: left;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background 0.3s;
|
||||||
|
-webkit-tap-highlight-color: transparent;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: rgba(0, 0, 0, 0.025);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.breadcrumb-container {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.topmenu-container {
|
||||||
|
position: absolute;
|
||||||
|
left: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.errLog-container {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-menu {
|
||||||
|
float: right;
|
||||||
|
height: 100%;
|
||||||
|
line-height: 50px;
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-menu-item {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 0 8px;
|
||||||
|
height: 100%;
|
||||||
|
font-size: 18px;
|
||||||
|
color: #5a5e66;
|
||||||
|
vertical-align: text-bottom;
|
||||||
|
|
||||||
|
&.hover-effect {
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background 0.3s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: rgba(0, 0, 0, 0.025);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar-container {
|
||||||
|
margin-right: 40px;
|
||||||
|
|
||||||
|
.avatar-wrapper {
|
||||||
|
margin-top: 5px;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.user-avatar {
|
||||||
|
cursor: pointer;
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
i {
|
||||||
|
cursor: pointer;
|
||||||
|
position: absolute;
|
||||||
|
right: -20px;
|
||||||
|
top: 25px;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -17,6 +17,8 @@ const useUserStore = defineStore(
|
|||||||
token: getToken(),
|
token: getToken(),
|
||||||
id: '',
|
id: '',
|
||||||
name: '',
|
name: '',
|
||||||
|
nickName: '',
|
||||||
|
roleName: '',
|
||||||
avatar: '',
|
avatar: '',
|
||||||
roles: [],
|
roles: [],
|
||||||
permissions: []
|
permissions: []
|
||||||
@ -46,8 +48,9 @@ const useUserStore = defineStore(
|
|||||||
const password = userInfo.password
|
const password = userInfo.password
|
||||||
const code = userInfo.code
|
const code = userInfo.code
|
||||||
const uuid = userInfo.uuid
|
const uuid = userInfo.uuid
|
||||||
|
const loginParam=userInfo.loginParam
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
login(username, password, code, uuid).then(res => {
|
login(username, password, code, uuid,loginParam).then(res => {
|
||||||
setToken(res.token)
|
setToken(res.token)
|
||||||
this.token = res.token
|
this.token = res.token
|
||||||
resolve()
|
resolve()
|
||||||
@ -61,6 +64,10 @@ const useUserStore = defineStore(
|
|||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
getInfo().then(res => {
|
getInfo().then(res => {
|
||||||
const user = res.user
|
const user = res.user
|
||||||
|
const rolelist = user.roles
|
||||||
|
if (rolelist && rolelist.length > 0) {
|
||||||
|
this.roleName=rolelist[0].roleName
|
||||||
|
}
|
||||||
const avatar = (user.avatar == "" || user.avatar == null) ? defAva : import.meta.env.VITE_APP_BASE_API + user.avatar;
|
const avatar = (user.avatar == "" || user.avatar == null) ? defAva : import.meta.env.VITE_APP_BASE_API + user.avatar;
|
||||||
|
|
||||||
if (res.roles && res.roles.length > 0) { // 验证返回的roles是否是一个非空数组
|
if (res.roles && res.roles.length > 0) { // 验证返回的roles是否是一个非空数组
|
||||||
@ -71,6 +78,7 @@ const useUserStore = defineStore(
|
|||||||
}
|
}
|
||||||
this.id = user.userId
|
this.id = user.userId
|
||||||
this.name = user.userName
|
this.name = user.userName
|
||||||
|
this.nickName= user.nickName
|
||||||
this.avatar = avatar
|
this.avatar = avatar
|
||||||
resolve(res)
|
resolve(res)
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
|
|||||||
@ -100,9 +100,12 @@ const getInfoList = () => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(() => props.queryParams, (newValue) => {
|
watch(() => queryParams, (newValue) => {
|
||||||
getInfoList()
|
getInfoList()
|
||||||
}, { immediate: true })
|
}, {
|
||||||
|
immediate: true,
|
||||||
|
deep: true
|
||||||
|
})
|
||||||
|
|
||||||
const getMxInfo = (row: any) => {
|
const getMxInfo = (row: any) => {
|
||||||
const data = {
|
const data = {
|
||||||
|
|||||||
@ -13,7 +13,6 @@ const info = ref('')
|
|||||||
const getClinicalInfo = (data: any) => {
|
const getClinicalInfo = (data: any) => {
|
||||||
clinicInfo(data).then((res: any) => {
|
clinicInfo(data).then((res: any) => {
|
||||||
if (res.code == 0) {
|
if (res.code == 0) {
|
||||||
console.log('临床意义==>', res.data);
|
|
||||||
info.value = res.data
|
info.value = res.data
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -26,7 +25,6 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
emitter.on('refreshClinical', (data) => {
|
emitter.on('refreshClinical', (data) => {
|
||||||
console.log('data==>', data);
|
|
||||||
getClinicalInfo(data)
|
getClinicalInfo(data)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@ -58,7 +58,10 @@ const getCombination = () => {
|
|||||||
};
|
};
|
||||||
watch(() => props.queryParams.yq, (newValue) => {
|
watch(() => props.queryParams.yq, (newValue) => {
|
||||||
getCombination()
|
getCombination()
|
||||||
}, { immediate: true })
|
}, {
|
||||||
|
immediate: true,
|
||||||
|
deep: true
|
||||||
|
})
|
||||||
|
|
||||||
const changeLxsr = (row: any) => {
|
const changeLxsr = (row: any) => {
|
||||||
const lxsrs = tableData.value.filter((item: any) => item.lxsr).map((item: any) => item.mbmc);
|
const lxsrs = tableData.value.filter((item: any) => item.lxsr).map((item: any) => item.mbmc);
|
||||||
|
|||||||
@ -203,7 +203,10 @@ const getList = () => {
|
|||||||
|
|
||||||
watch(() => props.queryParams, (newValue) => {
|
watch(() => props.queryParams, (newValue) => {
|
||||||
getList()
|
getList()
|
||||||
}, { immediate: true })
|
}, {
|
||||||
|
immediate: true,
|
||||||
|
deep: true
|
||||||
|
})
|
||||||
|
|
||||||
const handleRowClick = (row: any) => {
|
const handleRowClick = (row: any) => {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
|
|||||||
@ -171,7 +171,10 @@ const getOthersInfo = () => {
|
|||||||
|
|
||||||
watch(() => props.queryParams, (newValue) => {
|
watch(() => props.queryParams, (newValue) => {
|
||||||
getOthersInfo()
|
getOthersInfo()
|
||||||
}, { immediate: true })
|
}, {
|
||||||
|
immediate: true,
|
||||||
|
deep: true
|
||||||
|
})
|
||||||
|
|
||||||
// 获取明细
|
// 获取明细
|
||||||
const handleRowClick = (row: any) => {
|
const handleRowClick = (row: any) => {
|
||||||
|
|||||||
@ -56,7 +56,10 @@ const getReexamination = () => {
|
|||||||
|
|
||||||
watch(() => queryParams.value, () => {
|
watch(() => queryParams.value, () => {
|
||||||
getReexamination();
|
getReexamination();
|
||||||
}, { immediate: true })
|
}, {
|
||||||
|
immediate: true,
|
||||||
|
deep: true
|
||||||
|
})
|
||||||
|
|
||||||
const tableRef = ref();
|
const tableRef = ref();
|
||||||
const itemDictRef = ref(); // DictInput组件引用
|
const itemDictRef = ref(); // DictInput组件引用
|
||||||
@ -111,7 +114,6 @@ const addRowFromDict = async (rowData: any) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleCsjgEnter = (row: any) => {
|
const handleCsjgEnter = (row: any) => {
|
||||||
console.log('复查结果修改', row);
|
|
||||||
saveRedo(row)
|
saveRedo(row)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -43,7 +43,10 @@ const getResultGraph = () => {
|
|||||||
|
|
||||||
watch(() => props.queryParams, (newValue) => {
|
watch(() => props.queryParams, (newValue) => {
|
||||||
getResultGraph()
|
getResultGraph()
|
||||||
}, { immediate: true })
|
}, {
|
||||||
|
immediate: true,
|
||||||
|
deep: true
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|||||||
@ -195,7 +195,10 @@ const getInfo = () => {
|
|||||||
|
|
||||||
watch(() => props.queryParams, (newValue) => {
|
watch(() => props.queryParams, (newValue) => {
|
||||||
getInfo()
|
getInfo()
|
||||||
}, { immediate: true })
|
}, {
|
||||||
|
immediate: true,
|
||||||
|
deep: true
|
||||||
|
})
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
const data = { status: 0, del_flag: 0, pageSize: 1000, pageNum: 1 }
|
const data = { status: 0, del_flag: 0, pageSize: 1000, pageNum: 1 }
|
||||||
|
|||||||
@ -7,14 +7,28 @@
|
|||||||
class="compact-form">
|
class="compact-form">
|
||||||
<el-row :gutter="5">
|
<el-row :gutter="5">
|
||||||
<el-col :span="6">
|
<el-col :span="6">
|
||||||
<el-form-item label="样本号:" prop="ybh">
|
<el-form-item label="" prop="ybh">
|
||||||
<el-input v-model="labInfo.ybh" placeholder="样本编号" @keyup.enter="handleQuery" style="width:100%" />
|
<div class="next_box">
|
||||||
|
<div class="jtIcon" @click="handlePrev">
|
||||||
|
<el-icon>
|
||||||
|
<ArrowUpBold />
|
||||||
|
</el-icon>
|
||||||
|
</div>
|
||||||
|
<el-input v-model="queryParams.ybh" placeholder="样本编号" @keyup.enter="handleQuery"
|
||||||
|
style="width:100%" />
|
||||||
|
<div class="jtIcon" @click="handleNext">
|
||||||
|
<el-icon>
|
||||||
|
<ArrowDownBold />
|
||||||
|
</el-icon>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="6">
|
<el-col :span="6">
|
||||||
<el-form-item label="日期:" prop="jyrq">
|
<el-form-item label="日期:" prop="jyrq">
|
||||||
<el-date-picker v-model="labInfo.jyrq" type="date" label-width="1.25rem" placeholder="检验日期"
|
<el-date-picker v-model="ybJyrq" type="date" label-width="1.25rem" placeholder="检验日期"
|
||||||
value-format="YYYY-MM-DD" :clearable="false" @change="" style="width:100%"></el-date-picker>
|
value-format="YYYY-MM-DD" :clearable="false" @change="jyrqChange"
|
||||||
|
style="width:100%"></el-date-picker>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="6">
|
<el-col :span="6">
|
||||||
@ -51,25 +65,22 @@
|
|||||||
<el-col :span="16">
|
<el-col :span="16">
|
||||||
<el-tabs v-model="activeName" type="card" class="demo-tabs">
|
<el-tabs v-model="activeName" type="card" class="demo-tabs">
|
||||||
<el-tab-pane label="鉴定(终报)结果" name="first">
|
<el-tab-pane label="鉴定(终报)结果" name="first">
|
||||||
<ZbReport ref="labResultRef" v-model:labPat="labInfo" :labPatKey="queryParams" :dictData="dictData"
|
<ZbReport ref="labResultRef" v-model:labPat="labInfo" :labPatKey="queryParams"
|
||||||
:labResutsData="zbLabResuts" @fetchLabResults="resultsHandle" @changeStatus="changeStatus"
|
@update:labPatKey="queryParams = $event" :dictData="dictData" :labResutsData="zbLabResuts"
|
||||||
@previewHandle="previewHandle" />
|
@fetchLabResults="resultsHandle" @changeStatus="changeStatus" @previewHandle="previewHandle" />
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane label="初级和二级报告" name="second">
|
<el-tab-pane label="初级和二级报告" name="second">
|
||||||
<CbReport v-model:labPat="labInfo" :labPatKey="queryParams" :instrdComOpt="instrdComOpt"
|
<CbReport v-model:labPat="labInfo" :labPatKey="queryParams" @update:labPatKey="queryParams = $event"
|
||||||
:dictData="dictData" @changeStatus="changeStatus" @previewHandle="previewHandle" />
|
:instrdComOpt="instrdComOpt" :dictData="dictData" @changeStatus="changeStatus" :userList="userList"
|
||||||
|
@previewHandle="previewHandle" />
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane label="培养基接种" name="third">
|
<el-tab-pane label="培养基接种" name="third">
|
||||||
<Byj :labPat="labInfo" :labPatKey="queryParams" />
|
<Pyj :labPat="labPat" :labPatKey="queryParams" :userList="userList" />
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane label="操作记录" name="fourth">
|
<el-tab-pane label="操作记录" name="fourth">
|
||||||
<Record :labPat="labInfo" :labPatKey="queryParams" />
|
<Record :labPat="labInfo" :labPatKey="queryParams" />
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
|
|
||||||
<!-- <LabResult ref="labResultRef" v-model:labPat="labInfo" :labPatKey="queryParams" :dictData="dictData"
|
|
||||||
:labResutsData="labResuts" @fetchLabResults="resultsHandle" @changeStatus="changeStatus"
|
|
||||||
@previewHandle="previewHandle" /> -->
|
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</div>
|
</div>
|
||||||
@ -102,7 +113,11 @@
|
|||||||
<el-radio :value="60">近60天</el-radio>
|
<el-radio :value="60">近60天</el-radio>
|
||||||
<el-radio :value="90">近90天</el-radio>
|
<el-radio :value="90">近90天</el-radio>
|
||||||
<el-radio :value="7">近7天</el-radio>
|
<el-radio :value="7">近7天</el-radio>
|
||||||
<el-radio :value="0">此日 -></el-radio>
|
<el-radio :value="0">此日
|
||||||
|
<el-icon>
|
||||||
|
<Right />
|
||||||
|
</el-icon>
|
||||||
|
</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
<el-date-picker v-model="queryParams.jyrq" type="date" :size="aotuSize" @change="fetchlabPatList"
|
<el-date-picker v-model="queryParams.jyrq" type="date" :size="aotuSize" @change="fetchlabPatList"
|
||||||
style="width: 9.375rem;" />
|
style="width: 9.375rem;" />
|
||||||
@ -111,9 +126,6 @@
|
|||||||
:tableKey="queryParams" :dictData="dictData" @search="searchJobs" />
|
:tableKey="queryParams" :dictData="dictData" @search="searchJobs" />
|
||||||
|
|
||||||
<div class="button-group">
|
<div class="button-group">
|
||||||
<!-- <div class="text1">样本总数:<span>{{ ybs }}</span></div>
|
|
||||||
<div class="text2">未审:<span>{{ ws }}</span></div>
|
|
||||||
<div class="text3">危:<span>{{ wjs }}</span></div> -->
|
|
||||||
<el-pagination v-model:current-page="queryParams.pageNum" v-model:page-size="queryParams.pageSize"
|
<el-pagination v-model:current-page="queryParams.pageNum" v-model:page-size="queryParams.pageSize"
|
||||||
:page-sizes="[300, 600, 1000]" :size="aotuSize" background
|
:page-sizes="[300, 600, 1000]" :size="aotuSize" background
|
||||||
layout="total, sizes, prev, pager, next, jumper" :total="total" @size-change="handleSizeChange"
|
layout="total, sizes, prev, pager, next, jumper" :total="total" @size-change="handleSizeChange"
|
||||||
@ -129,6 +141,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
<!-- 校验用户 -->
|
||||||
|
<CheckUser ref="checkUserRef" @onConfirm="handleCheckUserConfirm" @onCancel="checkUserCancel" />
|
||||||
<!-- 批量扫码弹窗 -->
|
<!-- 批量扫码弹窗 -->
|
||||||
<BatchCode ref="batchRef" v-model:labPat="labPat" :labPatKey="queryParams" :dictData="dictData"
|
<BatchCode ref="batchRef" v-model:labPat="labPat" :labPatKey="queryParams" :dictData="dictData"
|
||||||
:totalCount="labPatList.length" @goNext="handleNext" @goPrev="handlePrev" @goLast="handleLast"
|
:totalCount="labPatList.length" @goNext="handleNext" @goPrev="handlePrev" @goLast="handleLast"
|
||||||
@ -147,8 +161,6 @@ import SelectTable from '@/components/SelectTable/index.vue';
|
|||||||
import tabView from '@/components/tabViews/index.vue';
|
import tabView from '@/components/tabViews/index.vue';
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import iFrame from "@/components/iFrame/index.vue";
|
import iFrame from "@/components/iFrame/index.vue";
|
||||||
// @ts-ignore
|
|
||||||
import LabResult from './labresult/index.vue';
|
|
||||||
import LabPatList from './labpatlist.vue';
|
import LabPatList from './labpatlist.vue';
|
||||||
import History from '../components/history/index.vue'
|
import History from '../components/history/index.vue'
|
||||||
import Others from '../components/others/index.vue'
|
import Others from '../components/others/index.vue'
|
||||||
@ -158,14 +170,15 @@ import Combination from '../components/combination/index.vue'
|
|||||||
import Clinical from '../components/clinical/index.vue'
|
import Clinical from '../components/clinical/index.vue'
|
||||||
import Sample from '../components/sample/index.vue'
|
import Sample from '../components/sample/index.vue'
|
||||||
import ResultGraph from '../components/resultGraph/index.vue'
|
import ResultGraph from '../components/resultGraph/index.vue'
|
||||||
|
import CheckUser from '../work/components/CheckUser.vue';
|
||||||
// 中间部分
|
// 中间部分
|
||||||
import ZbReport from './labresult/zbReport.vue';
|
import ZbReport from './labresult/zbReport.vue';
|
||||||
import CbReport from './labresult/cbReport.vue';
|
import CbReport from './labresult/cbReport.vue';
|
||||||
import Byj from './labresult/byj.vue';
|
import Pyj from './labresult/pyj.vue';
|
||||||
import Record from './labresult/record.vue';
|
import Record from './labresult/record.vue';
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import { comDict } from '@/utils/dict'
|
import { comDict } from '@/utils/dict'
|
||||||
import { queryLabResults, loadDefault, queryLabPat, instrdconfig, delSample, getGroupInstrdList } from "@/api/liswork/work/LisWork";
|
import { queryLabResults, loadDefault, queryLabPat, instrdconfig, delSample, getGroupInstrdList, checkuser, updateLabPat } from "@/api/liswork/work/LisWork";
|
||||||
import { wswsamplelistpage, sampleMedInfo } from "@/api/liswork/micro/index";
|
import { wswsamplelistpage, sampleMedInfo } from "@/api/liswork/micro/index";
|
||||||
import { getComDicts, queryComDictListService } from "@/api/liswork/dict/ComDict";
|
import { getComDicts, queryComDictListService } from "@/api/liswork/dict/ComDict";
|
||||||
import { ElMessage, ElMessageBox } from "element-plus";
|
import { ElMessage, ElMessageBox } from "element-plus";
|
||||||
@ -190,11 +203,12 @@ const queryParams = ref({
|
|||||||
problemId: 0,
|
problemId: 0,
|
||||||
days: -1,
|
days: -1,
|
||||||
pageSize: 600,
|
pageSize: 600,
|
||||||
pageNum: 1
|
pageNum: 1,
|
||||||
|
yhdh: ''
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
const activeName = ref('second');
|
const activeName = ref('first');
|
||||||
|
|
||||||
const total = ref(0)
|
const total = ref(0)
|
||||||
const ybs = ref(0)
|
const ybs = ref(0)
|
||||||
@ -235,9 +249,7 @@ const searchText = ref('')
|
|||||||
const rules = ref([])
|
const rules = ref([])
|
||||||
const instrGroupOptions = ref<any[]>([])
|
const instrGroupOptions = ref<any[]>([])
|
||||||
const instrOptions = ref<{ yq: string; yqmc: string }[]>([])
|
const instrOptions = ref<{ yq: string; yqmc: string }[]>([])
|
||||||
|
|
||||||
const pdfUrl = ref('')
|
const pdfUrl = ref('')
|
||||||
|
|
||||||
// 初始查询参数(可选)
|
// 初始查询参数(可选)
|
||||||
const initialParams = {}
|
const initialParams = {}
|
||||||
|
|
||||||
@ -251,11 +263,55 @@ interface QueryParams {
|
|||||||
finish?: string | number
|
finish?: string | number
|
||||||
autojgbz?: string | number
|
autojgbz?: string | number
|
||||||
}
|
}
|
||||||
|
const ybJyrq = ref('')
|
||||||
|
|
||||||
watch(() => labPat.value, (newValue) => {
|
watch(() => labPat.value, (newValue) => {
|
||||||
queryParams.value.ybh = newValue.ybh;
|
queryParams.value.ybh = newValue.ybh;
|
||||||
|
ybJyrq.value = newValue.jyrq;
|
||||||
}, { deep: true });
|
}, { deep: true });
|
||||||
|
|
||||||
|
const checkUserRef = ref()
|
||||||
|
const jyrqChange = (val: string) => {
|
||||||
|
ElMessageBox.confirm(
|
||||||
|
`确定修改当前样本检验日期?`,
|
||||||
|
'提示',
|
||||||
|
{
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning',
|
||||||
|
}
|
||||||
|
).then(() => {
|
||||||
|
if (!queryParams.value.yhdh) {
|
||||||
|
checkUserRef.value.open();
|
||||||
|
} else {
|
||||||
|
updateJyrq()
|
||||||
|
}
|
||||||
|
}).catch(() => {
|
||||||
|
fetchLabPat();
|
||||||
|
})
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleCheckUserConfirm = (info: { yhdh: string, mm: string }) => {
|
||||||
|
checkuser({ yhdh: info.yhdh, mm: info.mm }).then((response: any) => {
|
||||||
|
if (response.code == 0) {
|
||||||
|
queryParams.value.yhdh = info.yhdh;
|
||||||
|
updateJyrq()
|
||||||
|
} else {
|
||||||
|
fetchLabPat();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
const checkUserCancel = () => {
|
||||||
|
fetchLabPat();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 更新检验日期
|
||||||
|
const updateJyrq = () => {
|
||||||
|
// updateLabPat({ ...queryParams.value, ...labPat.value })
|
||||||
|
};
|
||||||
|
|
||||||
// 模糊查询
|
// 模糊查询
|
||||||
const searchQuery = () => {
|
const searchQuery = () => {
|
||||||
let filterMhList = [...originalLabPatList.value];
|
let filterMhList = [...originalLabPatList.value];
|
||||||
@ -280,7 +336,6 @@ const searchQuery = () => {
|
|||||||
selectJob(firstRow);
|
selectJob(firstRow);
|
||||||
} else {
|
} else {
|
||||||
labPat.value = {};
|
labPat.value = {};
|
||||||
labInfo.value = {};
|
|
||||||
zbLabResuts.value = [];
|
zbLabResuts.value = [];
|
||||||
highlightRowIndex.value = -1;
|
highlightRowIndex.value = -1;
|
||||||
}
|
}
|
||||||
@ -318,7 +373,6 @@ const handleQueryResult = (params: QueryParams) => {
|
|||||||
selectJob(firstRow);
|
selectJob(firstRow);
|
||||||
} else {
|
} else {
|
||||||
labPat.value = {};
|
labPat.value = {};
|
||||||
labInfo.value = {};
|
|
||||||
zbLabResuts.value = [];
|
zbLabResuts.value = [];
|
||||||
highlightRowIndex.value = -1;
|
highlightRowIndex.value = -1;
|
||||||
}
|
}
|
||||||
@ -341,7 +395,6 @@ const mbStore = useCommonStore();
|
|||||||
const yqHandleChange = (val: any) => {
|
const yqHandleChange = (val: any) => {
|
||||||
zbLabResuts.value = [];
|
zbLabResuts.value = [];
|
||||||
labPat.value = {}
|
labPat.value = {}
|
||||||
labInfo.value = {}
|
|
||||||
mbStore.setLxsrList([]);
|
mbStore.setLxsrList([]);
|
||||||
getSysList()
|
getSysList()
|
||||||
fetchlabPatList()
|
fetchlabPatList()
|
||||||
@ -399,7 +452,7 @@ const selectJob = (job: any) => {
|
|||||||
}
|
}
|
||||||
const zbLabResuts = ref([])
|
const zbLabResuts = ref([])
|
||||||
//载入样本结果表单(中间labresult.vue组件)
|
//载入样本结果表单(中间labresult.vue组件)
|
||||||
const fetchLabResults = async () => {
|
const fetchLabResults = () => {
|
||||||
sampleMedInfo({ jyrq: labInfo.value.jyrq ? labInfo.value.jyrq : queryParams.value.jyrq, yq: labInfo.value.yq, ybh: labInfo.value.ybh }).then((response: any) => {
|
sampleMedInfo({ jyrq: labInfo.value.jyrq ? labInfo.value.jyrq : queryParams.value.jyrq, yq: labInfo.value.yq, ybh: labInfo.value.ybh }).then((response: any) => {
|
||||||
zbLabResuts.value = response.data;
|
zbLabResuts.value = response.data;
|
||||||
})
|
})
|
||||||
@ -423,6 +476,7 @@ const lastRow: any = ref({})
|
|||||||
const ybhChangeTb = (val: string) => {
|
const ybhChangeTb = (val: string) => {
|
||||||
// console.log('val==>', val);
|
// console.log('val==>', val);
|
||||||
labInfo.value.ybh = val
|
labInfo.value.ybh = val
|
||||||
|
queryParams.value.ybh = val
|
||||||
handleQuery();
|
handleQuery();
|
||||||
}
|
}
|
||||||
const handleQuery = () => {
|
const handleQuery = () => {
|
||||||
@ -431,6 +485,7 @@ const handleQuery = () => {
|
|||||||
highlightRowIndex.value = -1;
|
highlightRowIndex.value = -1;
|
||||||
ElMessage.warning('请输入样本编号')
|
ElMessage.warning('请输入样本编号')
|
||||||
labInfo.value.ybh = lastRow.value.ybh
|
labInfo.value.ybh = lastRow.value.ybh
|
||||||
|
queryParams.value.ybh = lastRow.value.ybh
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// queryParams.value = { ...queryParams.value };
|
// queryParams.value = { ...queryParams.value };
|
||||||
@ -454,11 +509,10 @@ const handleQuery = () => {
|
|||||||
|
|
||||||
// 创建新样本
|
// 创建新样本
|
||||||
const handleCreate = () => {
|
const handleCreate = () => {
|
||||||
labInfo.value.jyrq = ''
|
ybJyrq.value = ''
|
||||||
loadDefault({ ...queryParams.value }).then((response: any) => {
|
loadDefault({ ...queryParams.value }).then((response: any) => {
|
||||||
if (response.code == 0) {
|
if (response.code == 0) {
|
||||||
labPat.value = response.data;
|
labPat.value = response.data;
|
||||||
labInfo.value = response.data;
|
|
||||||
labPat.value.id = `temp_${Date.now()}_${Math.random().toString(36).substr(2, 8)}`;
|
labPat.value.id = `temp_${Date.now()}_${Math.random().toString(36).substr(2, 8)}`;
|
||||||
zbLabResuts.value = [];
|
zbLabResuts.value = [];
|
||||||
labPatListRef.value?.clearCurrentRow();
|
labPatListRef.value?.clearCurrentRow();
|
||||||
@ -512,11 +566,14 @@ const handlePrev = () => {
|
|||||||
if (!lbFlag.value) {
|
if (!lbFlag.value) {
|
||||||
const ybh = getPreviousNumber(labInfo.value.ybh) as string;
|
const ybh = getPreviousNumber(labInfo.value.ybh) as string;
|
||||||
labInfo.value.ybh = ybh;
|
labInfo.value.ybh = ybh;
|
||||||
|
queryParams.value.ybh = ybh;
|
||||||
const index = labPatList.value.findIndex((item: any) => item.ybh == ybh)
|
const index = labPatList.value.findIndex((item: any) => item.ybh == ybh)
|
||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
highlightRowIndex.value = index;
|
highlightRowIndex.value = index;
|
||||||
const row = labPatList.value[index];
|
const row = labPatList.value[index];
|
||||||
labPatListRef.value.setCurrentRow(row);
|
if (activeTab.value == 'LabPatList') {
|
||||||
|
labPatListRef.value.setCurrentRow(row);
|
||||||
|
}
|
||||||
selectJob(row);
|
selectJob(row);
|
||||||
} else {
|
} else {
|
||||||
handleCreate();
|
handleCreate();
|
||||||
@ -525,7 +582,9 @@ const handlePrev = () => {
|
|||||||
if (highlightRowIndex.value > 0) {
|
if (highlightRowIndex.value > 0) {
|
||||||
highlightRowIndex.value--;
|
highlightRowIndex.value--;
|
||||||
const row = labPatList.value[highlightRowIndex.value];
|
const row = labPatList.value[highlightRowIndex.value];
|
||||||
labPatListRef.value.setCurrentRow(row);
|
if (activeTab.value == 'LabPatList') {
|
||||||
|
labPatListRef.value.setCurrentRow(row);
|
||||||
|
}
|
||||||
selectJob(row);
|
selectJob(row);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -537,11 +596,14 @@ const handleNext = () => {
|
|||||||
if (!lbFlag.value) {
|
if (!lbFlag.value) {
|
||||||
const ybh = getNextNumber(labInfo.value.ybh) as string;
|
const ybh = getNextNumber(labInfo.value.ybh) as string;
|
||||||
labInfo.value.ybh = ybh;
|
labInfo.value.ybh = ybh;
|
||||||
|
queryParams.value.ybh = ybh;
|
||||||
const index = labPatList.value.findIndex((item: any) => item.ybh == ybh)
|
const index = labPatList.value.findIndex((item: any) => item.ybh == ybh)
|
||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
highlightRowIndex.value = index;
|
highlightRowIndex.value = index;
|
||||||
const row = labPatList.value[index];
|
const row = labPatList.value[index];
|
||||||
labPatListRef.value.setCurrentRow(row);
|
if (activeTab.value == 'LabPatList') {
|
||||||
|
labPatListRef.value.setCurrentRow(row);
|
||||||
|
}
|
||||||
selectJob(row);
|
selectJob(row);
|
||||||
} else {
|
} else {
|
||||||
handleCreate();
|
handleCreate();
|
||||||
@ -550,10 +612,13 @@ const handleNext = () => {
|
|||||||
if (highlightRowIndex.value < labPatList.value.length - 1) {
|
if (highlightRowIndex.value < labPatList.value.length - 1) {
|
||||||
highlightRowIndex.value++;
|
highlightRowIndex.value++;
|
||||||
const row = labPatList.value[highlightRowIndex.value];
|
const row = labPatList.value[highlightRowIndex.value];
|
||||||
labPatListRef.value.setCurrentRow(row);
|
if (activeTab.value == 'LabPatList') {
|
||||||
|
labPatListRef.value.setCurrentRow(row);
|
||||||
|
}
|
||||||
selectJob(row);
|
selectJob(row);
|
||||||
} else {
|
} else {
|
||||||
labInfo.value.ybh = getNextNumber(labInfo.value.ybh) as string;
|
labInfo.value.ybh = getNextNumber(labInfo.value.ybh) as string;
|
||||||
|
queryParams.value.ybh = labInfo.value.ybh;
|
||||||
handleCreate();
|
handleCreate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -561,6 +626,7 @@ const handleNext = () => {
|
|||||||
// 最后一个样本
|
// 最后一个样本
|
||||||
const handleLast = () => {
|
const handleLast = () => {
|
||||||
labInfo.value.ybh = labPatList.value[labPatList.value.length - 1].ybh;
|
labInfo.value.ybh = labPatList.value[labPatList.value.length - 1].ybh;
|
||||||
|
queryParams.value.ybh = labPatList.value[labPatList.value.length - 1].ybh;
|
||||||
handleNext();
|
handleNext();
|
||||||
}
|
}
|
||||||
const batchRef = ref()
|
const batchRef = ref()
|
||||||
@ -578,7 +644,6 @@ const changeStatus = (updatedPat: any, flag: boolean) => {
|
|||||||
queryLabPat(data).then((response: any) => {
|
queryLabPat(data).then((response: any) => {
|
||||||
if (response.code == 0) {
|
if (response.code == 0) {
|
||||||
labPat.value = response.data;
|
labPat.value = response.data;
|
||||||
labInfo.value = response.data;
|
|
||||||
const index = labPatList.value.findIndex((item: any) => item.ybh == updatedPat.ybh);
|
const index = labPatList.value.findIndex((item: any) => item.ybh == updatedPat.ybh);
|
||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
labPatList.value = labPatList.value.map((item, i) =>
|
labPatList.value = labPatList.value.map((item, i) =>
|
||||||
@ -757,6 +822,8 @@ const sendMessage = () => {
|
|||||||
background: #F0F3F8;
|
background: #F0F3F8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
:deep(.el-tabs--card>.el-tabs__header) {
|
:deep(.el-tabs--card>.el-tabs__header) {
|
||||||
height: 1.875rem !important;
|
height: 1.875rem !important;
|
||||||
margin-bottom: 0px;
|
margin-bottom: 0px;
|
||||||
|
|||||||
@ -1,73 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div>
|
|
||||||
<div class="mb5">
|
|
||||||
<el-button type="primary" plain size="small">打印培养基条码</el-button>
|
|
||||||
<el-checkbox v-model="checked">自动打印培养基条码</el-checkbox>
|
|
||||||
</div>
|
|
||||||
<CustomTable ref="tableRef" :data="tableData" :columns="columns" :config="tableConfig" :enable-column-drag="true"
|
|
||||||
@column-drag-end="handleColumnDragEnd">
|
|
||||||
</CustomTable>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import CustomTable from '@/components/elTable/index.vue';
|
|
||||||
import { getmediumList } from '@/api/liswork/micro/index'
|
|
||||||
|
|
||||||
const props = defineProps({
|
|
||||||
labPat: {
|
|
||||||
type: Object,
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
//结果主键
|
|
||||||
labPatKey: {
|
|
||||||
type: Object,
|
|
||||||
default: () => { }
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const { labPat, labPatKey } = toRefs(props);
|
|
||||||
|
|
||||||
const checked = ref(false);
|
|
||||||
const tableRef = ref();
|
|
||||||
const tableData = ref([]);
|
|
||||||
const columns = ref([
|
|
||||||
{ label: "培养基", prop: "zhxmdh", align: 'center', visible: true, headerSlot: 'xmdh', width: 100 },
|
|
||||||
{ label: "接种时间", prop: "zhxmdh", align: 'center', visible: true, width: 100 },
|
|
||||||
{ label: "培养基结果", prop: "zhxmdh", align: 'center', visible: true, width: 100 },
|
|
||||||
{ label: "转种类型", prop: "zhxmdh", align: 'center', visible: true, width: 100 },
|
|
||||||
{ label: "培养周期(小时)", prop: "zhxmdh", align: 'center', visible: true, width: 100 },
|
|
||||||
{ label: "观察间隔(小时)", prop: "zhxmdh", align: 'center', visible: true, width: 100 },
|
|
||||||
]);
|
|
||||||
const tableConfig = ref({
|
|
||||||
border: true,
|
|
||||||
height: '100%',
|
|
||||||
})
|
|
||||||
|
|
||||||
const handleColumnDragEnd = (data: any) => {
|
|
||||||
columns.value = data.columns;
|
|
||||||
}
|
|
||||||
|
|
||||||
const getbyjList = () => {
|
|
||||||
const data = {
|
|
||||||
jyrq: labPat.value.jyrq,
|
|
||||||
yq: labPat.value.yq,
|
|
||||||
ybh: labPat.value.ybh,
|
|
||||||
}
|
|
||||||
getmediumList(data).then((res: any) => {
|
|
||||||
if (res.code == 0) {
|
|
||||||
tableData.value = res.data
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
watch(() => props.labPat, (newValue) => {
|
|
||||||
if (newValue.jyrq && newValue.ybh && newValue.yq) {
|
|
||||||
getbyjList()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped></style>
|
|
||||||
@ -2,24 +2,26 @@
|
|||||||
<div>
|
<div>
|
||||||
<div class="title">
|
<div class="title">
|
||||||
<div>
|
<div>
|
||||||
<span>初报人:</span>{{ cbInfo?.confirmer }} <span>报告时间:</span>{{ cbInfo?.confirmdt }}
|
<span>初报人:</span>{{ formatUser(cbInfo?.confirmer) }} <span>报告时间:</span>{{ cbInfo?.confirmdt
|
||||||
|
}}
|
||||||
</div>
|
</div>
|
||||||
<div><span>{{ cbInfo?.jgbz == '2' ? '已初报' : '' }}</span></div>
|
<div><span>{{ cbInfo?.jgbz == '2' ? '已初报' : '' }}</span></div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<el-button class="btn_green btns_box" :size="autoSize" v-if="cbInfo?.jgbz != 2"
|
<el-button class="btn_green btns_box" :size="autoSize" v-if="cbInfo?.jgbz != 2"
|
||||||
@click="handleCheck(1, 'cb')">初报审核</el-button>
|
@click="handleCheck(3)">初报审核</el-button>
|
||||||
<el-button class="btns_box" :size="autoSize" v-if="cbInfo?.jgbz == 2"
|
<el-button class="btns_box" :size="autoSize" v-if="cbInfo?.jgbz == 2" @click="handleCheck(-3)">取消审核</el-button>
|
||||||
@click="handleCheck(2, 'cb')">取消审核</el-button>
|
|
||||||
<el-button class="btns_box" type="primary" :size="autoSize" plain :disabled="cbInfo?.jgbz == '2'"
|
<el-button class="btns_box" type="primary" :size="autoSize" plain :disabled="cbInfo?.jgbz == '2'"
|
||||||
@click="openItemDictDialog(1)">新增</el-button>
|
@click="openItemDictDialog(1)">新增</el-button>
|
||||||
<el-button class="btns_box" type="danger" :size="autoSize" :disabled="cbInfo?.jgbz == '2'" plain
|
<el-button class="btns_box" type="danger" :size="autoSize" :disabled="cbInfo?.jgbz == '2'" plain
|
||||||
@click="handleBatchDelete(1)">删除</el-button>
|
@click="handleBatchDelete(1)">删除</el-button>
|
||||||
<el-button class="btn_green btns_box" :size="autoSize" :disabled="cbInfo?.jgbz == '2'"
|
<el-button class="btn_green btns_box" :size="autoSize" :disabled="cbInfo?.jgbz == '2'"
|
||||||
@click="zhHandel(1)">组合项目</el-button>
|
@click="zhHandel(1)">组合项目</el-button>
|
||||||
|
<el-button type="primary" plain class=" btns_box" @click="printHandle(1)">打印</el-button>
|
||||||
|
<el-button type="primary" plain class=" btns_box" @click="previewHandle(2)">预览</el-button>
|
||||||
</div>
|
</div>
|
||||||
<CustomTable :data="tableData" :columns="columns" :config="tableConfig" :enable-column-drag="true"
|
<CustomTable :data="tableData" :columns="columns" :config="tableConfig" :enable-column-drag="true"
|
||||||
@column-drag-end="handleColumnDragEnd">
|
@column-drag-end="handleColumnDragEnd" @row-click="cbRowClick">
|
||||||
<template #xmdh="{ column }">
|
<template #xmdh="{ column }">
|
||||||
细菌/结果({{ tableData.length }})项
|
细菌/结果({{ tableData.length }})项
|
||||||
</template>
|
</template>
|
||||||
@ -62,24 +64,26 @@
|
|||||||
|
|
||||||
<div class="title ertext">
|
<div class="title ertext">
|
||||||
<div>
|
<div>
|
||||||
<span>二报人:</span>{{ erInfo?.confirmer }} <span>报告时间:</span>{{ erInfo?.confirmdt }}
|
<span>二报人:</span>{{ formatUser(erInfo?.confirmer) }} <span>报告时间:</span>{{ erInfo?.confirmdt
|
||||||
|
}}
|
||||||
</div>
|
</div>
|
||||||
<div><span>{{ erInfo?.jgbz == '2' ? '已二报' : '' }}</span></div>
|
<div><span>{{ erInfo?.jgbz == '2' ? '已二报' : '' }}</span></div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<el-button class="btn_green btns_box" :size="autoSize" v-if="erInfo?.jgbz != 2"
|
<el-button class="btn_green btns_box" :size="autoSize" v-if="erInfo?.jgbz != 2"
|
||||||
@click="handleCheck(1, 'erb')">二报审核</el-button>
|
@click="handleCheck(4)">二报审核</el-button>
|
||||||
<el-button class="btns_box" :size="autoSize" v-if="erInfo?.jgbz == 2"
|
<el-button class="btns_box" :size="autoSize" v-if="erInfo?.jgbz == 2" @click="handleCheck(-4)">取消审核</el-button>
|
||||||
@click="handleCheck(2, 'erb')">取消审核</el-button>
|
|
||||||
<el-button class="btns_box" type="primary" :size="autoSize" plain :disabled="erInfo?.jgbz == '2'"
|
<el-button class="btns_box" type="primary" :size="autoSize" plain :disabled="erInfo?.jgbz == '2'"
|
||||||
@click="openItemDictDialog(2)">新增</el-button>
|
@click="openItemDictDialog(2)">新增</el-button>
|
||||||
<el-button class="btns_box" type="danger" :size="autoSize" :disabled="erInfo?.jgbz == '2'" plain
|
<el-button class="btns_box" type="danger" :size="autoSize" :disabled="erInfo?.jgbz == '2'" plain
|
||||||
@click="handleBatchDelete(2)">删除</el-button>
|
@click="handleBatchDelete(2)">删除</el-button>
|
||||||
<el-button class="btn_green btns_box" :size="autoSize" :disabled="erInfo?.jgbz == '2'"
|
<el-button class="btn_green btns_box" :size="autoSize" :disabled="erInfo?.jgbz == '2'"
|
||||||
@click="zhHandel(2)">组合项目</el-button>
|
@click="zhHandel(2)">组合项目</el-button>
|
||||||
|
<el-button type="primary" plain class=" btns_box" @click="printHandle(2)">打印</el-button>
|
||||||
|
<el-button type="primary" plain class=" btns_box" @click="previewHandle(2)">预览</el-button>
|
||||||
</div>
|
</div>
|
||||||
<CustomTable :data="tableData2" :columns="columns" :config="tableConfig" :enable-column-drag="true"
|
<CustomTable :data="tableData2" :columns="columns" :config="tableConfig" :enable-column-drag="true"
|
||||||
@column-drag-end="handleColumnDragEnd">
|
@column-drag-end="handleColumnDragEnd" @row-click="erbRowClick">
|
||||||
<template #xmdh="{ column }">
|
<template #xmdh="{ column }">
|
||||||
细菌/结果({{ tableData2.length }})项
|
细菌/结果({{ tableData2.length }})项
|
||||||
</template>
|
</template>
|
||||||
@ -129,25 +133,34 @@
|
|||||||
|
|
||||||
<!-- 组合项目 -->
|
<!-- 组合项目 -->
|
||||||
<Combined ref="combinedRef" :queryParams="labPatKey" @dbMbHandle="combinedHandel" />
|
<Combined ref="combinedRef" :queryParams="labPatKey" @dbMbHandle="combinedHandel" />
|
||||||
|
|
||||||
|
<!-- 校验用户 -->
|
||||||
|
<CheckUser ref="checkUserRef" :title="checktitle" @onConfirm="handleCheckUserConfirm" />
|
||||||
|
|
||||||
|
<!-- 取消审核操作原因 -->
|
||||||
|
<Unconfirmlog ref="unconfirmlogRef" :reasonText="reasonText" :tableKey="labPatKey" @onConfirm="proceedCheck" />
|
||||||
|
|
||||||
|
<!-- 危急值结果上报 -->
|
||||||
|
<UploadWarning ref="uploadwarningRef" :warningMsgdata="warningMsgdata" :tableKey="labPatKey"
|
||||||
|
@onupload="proceedCheck" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import CustomTable from '@/components/elTable/index.vue'
|
import CustomTable from '@/components/elTable/index.vue'
|
||||||
import { LabResultItem, ymTableDataItem } from '@/types/index';
|
import { LabResultItem } from '@/types/index';
|
||||||
import { changeresult, saveresult, newresult, sampleMedInfo } from '@/api/liswork/micro/index';
|
import { changeresult, saveresult, newresult, sampleMedInfo, cbebCheck } from '@/api/liswork/micro/index';
|
||||||
import {
|
import { deleteresult, queryXmVal, setinputmdl, queryLabPat, checkuser, printListwork } from "@/api/liswork/work/LisWork";
|
||||||
check1, check2, uncheck2, unconfirmlog, checkuser, reglimit, deleteresult, allPatquery, emrquery, datalink, changeLinkList,
|
import CheckUser from "../../work/components/CheckUser.vue";
|
||||||
viewBackup, queryXmVal, printListwork, getresultchangelog, setinputmdl, lockSample, unLockSample, clearnotComplete, clearPrintflag,
|
import Unconfirmlog from "../../work/components/unconfirmlog.vue";
|
||||||
noiteMresult, queryXmInfo, setitemInter, queryLabPat
|
import UploadWarning from "../../work/components/uploadwarning.vue";
|
||||||
} from "@/api/liswork/work/LisWork";
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import ProjectDetails from "@/components/projectDetails/index.vue";
|
import ProjectDetails from "@/components/projectDetails/index.vue";
|
||||||
import projectsJg from "@/components/projectsjg/index.vue";
|
import projectsJg from "@/components/projectsjg/index.vue";
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import Combined from "./components/combinedDialog.vue";
|
import Combined from "./components/combinedDialog.vue";
|
||||||
import emitter from '@/utils/mitt';
|
import emitter from '@/utils/mitt';
|
||||||
import { ElMessage } from 'element-plus';
|
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||||
import { useCommonStore } from "@/store/modules/commonStore";
|
import { useCommonStore } from "@/store/modules/commonStore";
|
||||||
import { classCom } from '@/utils/classCom';
|
import { classCom } from '@/utils/classCom';
|
||||||
const autoSize = classCom.useAutoSize();
|
const autoSize = classCom.useAutoSize();
|
||||||
@ -170,10 +183,14 @@ const props = defineProps({
|
|||||||
dictData: {
|
dictData: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => { }
|
default: () => { }
|
||||||
}
|
},
|
||||||
|
userList: {
|
||||||
|
type: Array as () => Array<any>,
|
||||||
|
default: () => []
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const { labPat, labPatKey, instrdComOpt } = toRefs(props);
|
const { labPat, labPatKey, instrdComOpt, userList } = toRefs(props);
|
||||||
|
|
||||||
const tableData = ref<LabResultItem[]>([])
|
const tableData = ref<LabResultItem[]>([])
|
||||||
const tableData2 = ref<LabResultItem[]>([])
|
const tableData2 = ref<LabResultItem[]>([])
|
||||||
@ -266,12 +283,13 @@ const mbList = (type: number) => {
|
|||||||
const emits = defineEmits([
|
const emits = defineEmits([
|
||||||
'fetchLabResults',
|
'fetchLabResults',
|
||||||
'changeStatus',
|
'changeStatus',
|
||||||
'previewHandle'
|
'previewHandle',
|
||||||
|
'update:labPatKey'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
||||||
const columns = ref([
|
const columns = ref([
|
||||||
{ label: "细菌/结果", prop: "zhxmdh", align: 'center', visible: true, headerSlot: 'xmdh', width: 150 },
|
{ label: "细菌/结果", prop: "zhxmdh", visible: true, headerSlot: 'xmdh', width: 150 },
|
||||||
{ label: "菌落计数", prop: "od", align: 'center', visible: true, slot: 'od' },
|
{ label: "菌落计数", prop: "od", align: 'center', visible: true, slot: 'od' },
|
||||||
{ label: "检验结果", prop: "csjg", align: 'center', visible: true, slot: 'csjg' },
|
{ label: "检验结果", prop: "csjg", align: 'center', visible: true, slot: 'csjg' },
|
||||||
{ label: "阴阳性", prop: "jgbz", align: 'center', visible: true, slot: 'jgbz', showOverflowTooltip: false },
|
{ label: "阴阳性", prop: "jgbz", align: 'center', visible: true, slot: 'jgbz', showOverflowTooltip: false },
|
||||||
@ -325,7 +343,7 @@ const CellStyleHd = ({ row, column, rowIndex, columnIndex }: {
|
|||||||
const tableConfig = ref({
|
const tableConfig = ref({
|
||||||
height: '32vh',
|
height: '32vh',
|
||||||
border: true,
|
border: true,
|
||||||
// highlightCurrentRow: true,
|
highlightCurrentRow: true,
|
||||||
cellStyle: CellStyleHd
|
cellStyle: CellStyleHd
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -333,62 +351,94 @@ const handleColumnDragEnd = (data: any) => {
|
|||||||
columns.value = data.columns;
|
columns.value = data.columns;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const checktitle = ref('');
|
||||||
|
|
||||||
const shType = ref('') // 审核类型 cb初报 erb二报
|
const shType = ref('') // 审核类型 cb初报 erb二报
|
||||||
const bgType = ref(1) // 报告类型 1初报 2二报
|
const bgType = ref(1) // 报告类型 1初报 2二报
|
||||||
|
const checkUserRef = ref();
|
||||||
const handleCheck = (checkType: number, shtype: string) => {
|
const unconfirmlogRef = ref();
|
||||||
shType.value = shtype
|
const uploadwarningRef = ref();
|
||||||
// yhdh = checkuserid.value
|
const runnextstepname = ref(-1);
|
||||||
switch (checkType) {
|
const reasonText = ref('');
|
||||||
// case 1: // 初审
|
const warningMsgdata = ref('');
|
||||||
// check1({ ...labPatKey.value, jyrq: labPat.value.jyrq, yhdh: props.labPat.yhdh }).then((res: any) => {
|
const handleCheck = (checkType: number,) => {
|
||||||
// emits("changeStatus", props.labPat);
|
runnextstepname.value = checkType
|
||||||
// })
|
labPatKey.value.problemId = 0;
|
||||||
// break;
|
if (!labPatKey.value.yhdh) {
|
||||||
case 1: // 审核
|
checktitle.value = '审核人工号密码验证'
|
||||||
labPatKey.value.problemId = 0
|
checkUserRef.value.open()
|
||||||
shHandleCheck()
|
} else {
|
||||||
break;
|
proceedCheck()
|
||||||
case 2: // 取消审核
|
|
||||||
labPatKey.value.problemId = 0
|
|
||||||
unShHandle()
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const unCheckshow = ref(false);
|
const handleCheckUserConfirm = (info: { yhdh: string, mm: string }) => {
|
||||||
const reasonText = ref('');
|
checkuser({ yhdh: info.yhdh, mm: info.mm }).then((response: any) => {
|
||||||
const warningMsgdata = ref('');
|
if (response.code == 0) {
|
||||||
const showuploadwarning = ref(false);
|
emits('update:labPatKey', {
|
||||||
|
...labPatKey.value,
|
||||||
|
yhdh: info.yhdh
|
||||||
|
});
|
||||||
|
proceedCheck()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const shHandleCheck = () => {
|
const proceedCheck = () => {
|
||||||
check2({ ...labPatKey.value, jyrq: labPat.value.jyrq, yhdh: labPat.value.yhdh, yq: labPat.value.yq }).then((res: any) => {
|
const data = {
|
||||||
|
yq: labPat.value.yq,
|
||||||
|
yhdh: labPat.value.yhdh,
|
||||||
|
ybh: labPat.value.ybh,
|
||||||
|
jyrq: labPat.value.jyrq,
|
||||||
|
jgbz: runnextstepname.value,
|
||||||
|
}
|
||||||
|
cbebCheck(data).then((res: any) => {
|
||||||
if (res.code == "4" && res.problemId === 4) {
|
if (res.code == "4" && res.problemId === 4) {
|
||||||
labPatKey.value.problemId = res.problemId;
|
labPatKey.value.problemId = res.problemId;
|
||||||
warningMsgdata.value = res.msg;
|
warningMsgdata.value = res.msg;
|
||||||
showuploadwarning.value = true;
|
uploadwarningRef.value.open();
|
||||||
}
|
}
|
||||||
getLabPatInfo()
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
const unShHandle = () => {
|
|
||||||
uncheck2({ ...labPatKey.value, jyrq: labPat.value.jyrq, yhdh: labPat.value.yhdh, yq: labPat.value.yq }).then((res: any) => {
|
|
||||||
if (res.code == "4") {
|
if (res.code == "4") {
|
||||||
labPatKey.value.problemId = res.problemId;
|
labPatKey.value.problemId = res.problemId;
|
||||||
reasonText.value = res.msg;
|
reasonText.value = res.msg;
|
||||||
unCheckshow.value = true;
|
unconfirmlogRef.value.open();
|
||||||
}
|
}
|
||||||
getLabPatInfo()
|
emits("changeStatus", labPat.value);
|
||||||
})
|
})
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const selectedRows = ref<LabResultItem[]>([])
|
||||||
|
|
||||||
|
const erbRowClick = (row: LabResultItem) => {
|
||||||
|
bgType.value = 2
|
||||||
|
selectedRows.value = [row];
|
||||||
|
}
|
||||||
|
const cbRowClick = (row: LabResultItem) => {
|
||||||
|
bgType.value = 1
|
||||||
|
selectedRows.value = [row];
|
||||||
|
}
|
||||||
const handleBatchDelete = (type: number) => {
|
const handleBatchDelete = (type: number) => {
|
||||||
bgType.value = type
|
if (selectedRows.value.length === 0) return ElMessage.warning("请先选择要删除的记录");
|
||||||
|
ElMessageBox.confirm(
|
||||||
|
`确定要删除选中的 ${selectedRows.value.length} 条记录吗?`,
|
||||||
|
'提示',
|
||||||
|
{
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
}
|
||||||
|
).then(() => {
|
||||||
|
deleteresult(selectedRows.value).then((res: any) => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
ElMessage.success('删除成功');
|
||||||
|
getResultList()
|
||||||
|
selectedRows.value = []
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}).catch(() => {
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 项目结果保存
|
// 项目结果保存
|
||||||
@ -428,7 +478,35 @@ const handleCsjgEnter = async (row: any, type: number) => {
|
|||||||
// if (input?.tagName === "INPUT") input?.blur();
|
// if (input?.tagName === "INPUT") input?.blur();
|
||||||
// });
|
// });
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const printHandle = (type: number) => {
|
||||||
|
const yq = type === 1 ? instrdComOpt.value.yq1 : instrdComOpt.value.yq2
|
||||||
|
const data = {
|
||||||
|
jyrq: labPat.value.jyrq,
|
||||||
|
yq: yq,
|
||||||
|
ybh: labPat.value.ybh,
|
||||||
|
sqh: labPat.value.sqh
|
||||||
|
}
|
||||||
|
printListwork(data).then((res: any) => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
classCom.printBase64PDF(res.data)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
};
|
||||||
|
const previewHandle = (type: number) => {
|
||||||
|
const yq = type === 1 ? instrdComOpt.value.yq1 : instrdComOpt.value.yq2
|
||||||
|
const data = {
|
||||||
|
jyrq: labPat.value.jyrq,
|
||||||
|
yq: yq,
|
||||||
|
ybh: labPat.value.ybh,
|
||||||
|
sqh: labPat.value.sqh
|
||||||
|
}
|
||||||
|
printListwork(data).then((res: any) => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
emits('previewHandle', res.data);
|
||||||
|
}
|
||||||
|
})
|
||||||
};
|
};
|
||||||
const itemDictRef = ref();
|
const itemDictRef = ref();
|
||||||
const openItemDictDialog = (type: number) => {
|
const openItemDictDialog = (type: number) => {
|
||||||
@ -515,6 +593,7 @@ const zhHandel = (type: number) => {
|
|||||||
|
|
||||||
const combinedHandel = (row: any) => {
|
const combinedHandel = (row: any) => {
|
||||||
const targetTable = bgType.value === 1 ? tableData.value : tableData2.value;
|
const targetTable = bgType.value === 1 ? tableData.value : tableData2.value;
|
||||||
|
const yq = bgType.value === 1 ? instrdComOpt.value.yq1 : instrdComOpt.value.yq2;
|
||||||
const data = {
|
const data = {
|
||||||
...labPatKey.value,
|
...labPatKey.value,
|
||||||
mbmc: row.mbmc,
|
mbmc: row.mbmc,
|
||||||
@ -524,7 +603,7 @@ const combinedHandel = (row: any) => {
|
|||||||
const existingNames = new Set(targetTable.map((item: any) => item.xmdh))
|
const existingNames = new Set(targetTable.map((item: any) => item.xmdh))
|
||||||
res.data?.forEach((item: any) => {
|
res.data?.forEach((item: any) => {
|
||||||
if (!existingNames.has(item.xmdh)) {
|
if (!existingNames.has(item.xmdh)) {
|
||||||
targetTable.push({ ...item, jyrq: labPat.value.jyrq, zhxmdh: item.xmdh + ' ' + item.xmmc })
|
targetTable.push({ ...item, jyrq: labPat.value.jyrq, zhxmdh: item.xmdh + ' ' + item.xmmc, yq })
|
||||||
existingNames.add(item.xmdh)
|
existingNames.add(item.xmdh)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -541,6 +620,9 @@ const formatDict = (v: string, dictType: string) => {
|
|||||||
const formatJgbz = (v: string) => {
|
const formatJgbz = (v: string) => {
|
||||||
return v == 'H' ? '高' : v == 'L' ? '低' : v == 'N' ? '阴性' : v == 'P' ? '阳性' : v == 'Q' ? '弱阳性' : v == 'M' ? '正常' : ''
|
return v == 'H' ? '高' : v == 'L' ? '低' : v == 'N' ? '阴性' : v == 'P' ? '阳性' : v == 'Q' ? '弱阳性' : v == 'M' ? '正常' : ''
|
||||||
}
|
}
|
||||||
|
const formatUser = (yhdh: string) => {
|
||||||
|
return userList.value.find((item: any) => item.userName == yhdh)?.nickName || yhdh
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|||||||
161
src/views/liswork/micro/labresult/components/pyjDict.vue
Normal file
161
src/views/liswork/micro/labresult/components/pyjDict.vue
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
<template>
|
||||||
|
<div class="dict-input-wrapper">
|
||||||
|
<!-- 字典选择弹窗 -->
|
||||||
|
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="30vw" :close-on-click-modal="false" :draggable="true"
|
||||||
|
@close="handleDialogClose">
|
||||||
|
<el-input ref="inputRef" v-model="searchKey" placeholder="搜索(支持名称、编码、简拼)..." class="mb10" clearable
|
||||||
|
@clear="filterDictData" @input="filterDictData" />
|
||||||
|
|
||||||
|
<el-table :data="filteredDictData" height="300px" border @row-dblclick="selectItem" highlight-current-row>
|
||||||
|
<el-table-column prop="value" label="培养基代号" align="center" width="150" />
|
||||||
|
<el-table-column prop="label" label="培养基名称" align="center" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="pinyin" label="简拼" align="center" width="150" /> <!-- 显示简拼便于调试 -->
|
||||||
|
</el-table>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, computed, watch, onMounted } from 'vue';
|
||||||
|
import { getbactmediumList } from '@/api/liswork/micro/index';
|
||||||
|
// @ts-ignore
|
||||||
|
import { getFirstLetter } from '@/utils/pinyin.js'; // 引入拼音处理工具
|
||||||
|
// 组件参数
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: { type: [String, Number], default: '' },
|
||||||
|
dictType: { type: String },
|
||||||
|
placeholder: { type: String, default: '请输入或双击选择' },
|
||||||
|
clearable: { type: Boolean, default: true },
|
||||||
|
disabled: { type: Boolean, default: false },
|
||||||
|
dialogTitle: { type: String, default: '选择字典项' },
|
||||||
|
tableKey: { type: Object, default: () => { } },
|
||||||
|
});
|
||||||
|
|
||||||
|
// 组件事件
|
||||||
|
const emit = defineEmits(['select']);
|
||||||
|
|
||||||
|
|
||||||
|
const dictData = ref([]); // 存储带简拼的字典数据
|
||||||
|
const filteredDictData = ref([]);
|
||||||
|
const isDictLoading = ref(false);
|
||||||
|
const dialogVisible = ref(false);
|
||||||
|
const searchKey = ref('');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 加载字典数据(并添加简拼字段)
|
||||||
|
const loadDictData = async () => {
|
||||||
|
try {
|
||||||
|
isDictLoading.value = true;
|
||||||
|
|
||||||
|
const response = await getbactmediumList();
|
||||||
|
|
||||||
|
const rawData = response.data.map((item: any, index: number) => {
|
||||||
|
return {
|
||||||
|
value: item.mediumno || `未知编码_${index}`, // 确保value存在
|
||||||
|
label: item.mediumname || `未知名称_${index}`, // 确保label存在
|
||||||
|
};
|
||||||
|
});
|
||||||
|
// 为每个字典项添加简拼字段
|
||||||
|
dictData.value = (rawData || []).map((item: any) => ({
|
||||||
|
...item,
|
||||||
|
pinyin: getFirstLetter(item.label) // 新增pinyin字段存储简拼
|
||||||
|
}));
|
||||||
|
|
||||||
|
filteredDictData.value = [...dictData.value];
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`加载${props.dictType}字典失败:`, error);
|
||||||
|
dictData.value = [];
|
||||||
|
filteredDictData.value = [];
|
||||||
|
} finally {
|
||||||
|
isDictLoading.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 核心搜索逻辑(支持模糊搜索+简拼搜索)
|
||||||
|
const filterDictData = () => {
|
||||||
|
const key = searchKey.value.trim().toLowerCase();
|
||||||
|
if (!key) {
|
||||||
|
filteredDictData.value = [...dictData.value];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
filteredDictData.value = dictData.value.filter((item: any) => {
|
||||||
|
// 1. 模糊搜索:匹配label(名称)或value(编码)
|
||||||
|
const matchLabel = item.label.toLowerCase().includes(key);
|
||||||
|
const matchValue = String(item.value).toLowerCase().includes(key);
|
||||||
|
|
||||||
|
// 2. 简拼搜索:匹配首字母简拼
|
||||||
|
const matchPinyin = item.pinyin.toLowerCase().includes(key);
|
||||||
|
|
||||||
|
// 满足任一条件即匹配
|
||||||
|
return matchLabel || matchValue || matchPinyin;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const inputRef = ref()
|
||||||
|
// 关键修改:打开弹窗时重新加载数据
|
||||||
|
const openDictSelector = async () => {
|
||||||
|
if (props.disabled || isDictLoading.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 打开弹窗前先加载数据(确保每次打开都是最新的)
|
||||||
|
await loadDictData();
|
||||||
|
|
||||||
|
// 数据加载完成后再显示弹窗
|
||||||
|
dialogVisible.value = true;
|
||||||
|
searchKey.value = '';
|
||||||
|
nextTick(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
inputRef.value.focus();
|
||||||
|
}, 100);
|
||||||
|
});
|
||||||
|
filterDictData();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// 选择字典项
|
||||||
|
const selectItem = (item: any) => {
|
||||||
|
emit('select', item);
|
||||||
|
dialogVisible.value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const handleDialogClose = () => {
|
||||||
|
dialogVisible.value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
openDictSelector, // 暴露打开弹窗的方法
|
||||||
|
// 可选:暴露其他可能需要的方法(如刷新字典数据)
|
||||||
|
loadDictData,
|
||||||
|
handleDialogClose
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
/* 样式保持不变 */
|
||||||
|
.dict-input-wrapper {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select-icon {
|
||||||
|
cursor: pointer;
|
||||||
|
color: #666;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select-icon:hover {
|
||||||
|
color: #409eff;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-input__suffix) {
|
||||||
|
gap: 4px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
210
src/views/liswork/micro/labresult/pyj.vue
Normal file
210
src/views/liswork/micro/labresult/pyj.vue
Normal file
@ -0,0 +1,210 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div class="top-btns">
|
||||||
|
<el-button type="primary" plain :size="autoSize" @click="addItem">新增</el-button>
|
||||||
|
<el-button type="danger" plain :size="autoSize" @click="deleteItem">删除</el-button>
|
||||||
|
<el-button type="primary" plain :size="autoSize" @click="printHandle">打印培养基条码</el-button>
|
||||||
|
<el-checkbox v-model="checked" :size="autoSize" class="ml5">自动打印培养基条码</el-checkbox>
|
||||||
|
</div>
|
||||||
|
<CustomTable ref="tableRef" :data="tableData" :columns="columns" :config="tableConfig" :enable-column-drag="true"
|
||||||
|
@column-drag-end="handleColumnDragEnd" @selection-change="handleSelectionChange">
|
||||||
|
<template #mediumnameHeadTitle="{ column }">
|
||||||
|
培养基 {{ tableData?.length }}个
|
||||||
|
</template>
|
||||||
|
<template #mediumname="{ row }">
|
||||||
|
<el-input v-model="row.mediumname" size="small" class="full-width-input" @change="handleCsjgEnter(row)"
|
||||||
|
@dblclick="handleInputFocus(row)" />
|
||||||
|
</template>
|
||||||
|
<template #sheetdate="{ row }">
|
||||||
|
<el-date-picker v-model="row.sheetdate" type="datetime" format="YYYY-MM-DD HH:mm:ss"
|
||||||
|
class="full-width-input no-prefix-icon" value-format="YYYY-MM-DD HH:mm:ss" @change="handleCsjgEnter(row)" />
|
||||||
|
|
||||||
|
</template>
|
||||||
|
<template #sheetuser="{ row }">
|
||||||
|
<SelectTable v-model:data="row.sheetuser" :fields="ysFields" :tableData="userList" label="nickName"
|
||||||
|
class="full-width-input" value="userName" objKey="userName" :border="true" size="small"
|
||||||
|
@getDataValue="handleCsjgEnter(row)" placeholder="" :clearable="false" />
|
||||||
|
</template>
|
||||||
|
<template #mediu="{ row }">
|
||||||
|
<el-input v-model="row.mediu" size="small" class="full-width-input" @change="handleCsjgEnter(row)" />
|
||||||
|
</template>
|
||||||
|
<template #comments="{ row }">
|
||||||
|
<el-input v-model="row.comments" size="small" class="full-width-input" @change="handleCsjgEnter(row)" />
|
||||||
|
</template>
|
||||||
|
<template #conidtions="{ row }">
|
||||||
|
<el-input v-model="row.conidtions" size="small" class="full-width-input" @change="handleCsjgEnter(row)" />
|
||||||
|
</template>
|
||||||
|
<template #watchinterval="{ row }">
|
||||||
|
<el-input v-model="row.watchinterval" size="small" class="full-width-input" @change="handleCsjgEnter(row)" />
|
||||||
|
</template>
|
||||||
|
</CustomTable>
|
||||||
|
<PyjDict ref="pyjRef" :dialogTitle="'培养基选择'" @select="selectItem" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import CustomTable from '@/components/elTable/index.vue';
|
||||||
|
import { getmediumList, insertmedium, updatemedium, deletemedium, deletemediums } from '@/api/liswork/micro/index';
|
||||||
|
import { classCom } from '@/utils/classCom';
|
||||||
|
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||||
|
import PyjDict from './components/pyjDict.vue';
|
||||||
|
import SelectTable from '@/components/SelectTable/index.vue';
|
||||||
|
// @ts-ignore
|
||||||
|
import useUserStore from '@/store/modules/user'
|
||||||
|
const autoSize = classCom.useAutoSize()
|
||||||
|
const userStore = useUserStore()
|
||||||
|
const props = defineProps({
|
||||||
|
labPat: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
//结果主键
|
||||||
|
labPatKey: {
|
||||||
|
type: Object,
|
||||||
|
default: () => { }
|
||||||
|
},
|
||||||
|
userList: {
|
||||||
|
type: Array as PropType<object[]>,
|
||||||
|
default: () => []
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const { labPat, labPatKey } = toRefs(props);
|
||||||
|
|
||||||
|
const checked = ref(false);
|
||||||
|
const tableRef = ref();
|
||||||
|
const tableData: any = ref([]);
|
||||||
|
const columns = ref([
|
||||||
|
{ type: "selection", width: 40, align: 'center', visible: true },
|
||||||
|
{ label: "培养基", prop: "mediumname", align: 'center', visible: true, width: 80, headerSlot: 'mediumnameHeadTitle', slot: 'mediumname' },
|
||||||
|
{ label: "接种时间", prop: "sheetdate", align: 'center', visible: true, width: 150, slot: 'sheetdate', showOverflowTooltip: false },
|
||||||
|
{ label: "接种人", prop: "sheetuser", align: 'center', visible: true, width: 80, slot: 'sheetuser' },
|
||||||
|
{ label: "培养基结果", prop: "mediu", align: 'center', visible: true, slot: 'mediu' },
|
||||||
|
{ label: "转种类型", prop: "comments", align: 'center', visible: true, slot: 'comments' },
|
||||||
|
{ label: "培养周期(小时)", prop: "conidtions", align: 'center', visible: true, width: 100, slot: 'conidtions' },
|
||||||
|
{ label: "观察间隔(小时)", prop: "watchinterval", align: 'center', visible: true, width: 100, slot: 'watchinterval' },
|
||||||
|
]);
|
||||||
|
const tableConfig = ref({
|
||||||
|
border: true,
|
||||||
|
height: '74vh',
|
||||||
|
// highlightCurrentRow: true,
|
||||||
|
})
|
||||||
|
const pyjRef = ref();
|
||||||
|
const handleColumnDragEnd = (data: any) => {
|
||||||
|
columns.value = data.columns;
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateItem: any = ref(null);
|
||||||
|
|
||||||
|
const handleCsjgEnter = (row: any) => {
|
||||||
|
updatemedium(row)
|
||||||
|
}
|
||||||
|
const handleInputFocus = (row: any) => {
|
||||||
|
updateItem.value = row;
|
||||||
|
pyjRef.value.openDictSelector();
|
||||||
|
console.log('row', row);
|
||||||
|
}
|
||||||
|
const selectItem = (item: any) => {
|
||||||
|
if (updateItem.value) {
|
||||||
|
tableData.value.forEach((v: any) => {
|
||||||
|
if (updateItem.value.gsid == v.gsid) {
|
||||||
|
v.mediumno = item.value;
|
||||||
|
v.mediumname = item.label;
|
||||||
|
updatemedium(v).then((res: any) => {
|
||||||
|
updateItem.value = null
|
||||||
|
pyjRef.value.handleDialogClose();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.log('labPat==>', labPat.value);
|
||||||
|
const data = {
|
||||||
|
mediumno: item.value,
|
||||||
|
mediumname: item.label,
|
||||||
|
jyrq: labPat.value.jyrq,
|
||||||
|
yq: labPat.value.yq,
|
||||||
|
ybh: labPat.value.ybh,
|
||||||
|
sheetdate: labPat.value.sqsj,
|
||||||
|
sheetuser: userStore.name,
|
||||||
|
}
|
||||||
|
insertmedium(data).then((res: any) => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
tableData.value.push(data)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const ysFields = ref([
|
||||||
|
{ prop: 'userName', label: '用户代号', width: 80, enablePinyinSearch: true },
|
||||||
|
{ prop: 'nickName', label: '用户姓名', width: 150, enablePinyinSearch: true },
|
||||||
|
])
|
||||||
|
|
||||||
|
const selectedRows: any = ref([]);
|
||||||
|
const handleSelectionChange = (selection: any) => {
|
||||||
|
selectedRows.value = selection;
|
||||||
|
}
|
||||||
|
|
||||||
|
const addItem = () => {
|
||||||
|
pyjRef.value.openDictSelector();
|
||||||
|
}
|
||||||
|
|
||||||
|
const deleteItem = () => {
|
||||||
|
if (selectedRows.value.length === 0) return ElMessage.warning('请选择要删除的培养基!');
|
||||||
|
ElMessageBox.confirm(
|
||||||
|
`确定删除当前${selectedRows.value.length}个培养基?`,
|
||||||
|
'提示',
|
||||||
|
{
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning',
|
||||||
|
}
|
||||||
|
).then(() => {
|
||||||
|
const arr = selectedRows.value.map((item: any) => item.gsid);
|
||||||
|
deletemediums(arr).then((res: any) => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
ElMessage.success('删除成功');
|
||||||
|
getbyjList();
|
||||||
|
selectedRows.value = []
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const printHandle = () => {
|
||||||
|
console.log('打印培养基条码');
|
||||||
|
}
|
||||||
|
|
||||||
|
const getbyjList = () => {
|
||||||
|
const data = {
|
||||||
|
jyrq: labPat.value.jyrq,
|
||||||
|
yq: labPat.value.yq,
|
||||||
|
ybh: labPat.value.ybh,
|
||||||
|
}
|
||||||
|
getmediumList(data).then((res: any) => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
tableData.value = res.data
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(() => props.labPat, (newValue) => {
|
||||||
|
if (newValue.jyrq && newValue.ybh && newValue.yq) {
|
||||||
|
getbyjList()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.top-btns {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin: .3125rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-input__prefix) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -127,7 +127,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<!-- 新增明细 -->
|
<!-- 新增明细 -->
|
||||||
<ProjectDetails ref="itemDictRef" :dialog-title="'选择检验项目'" :tableKey="labPatKey" @select="handleItemSelect" />
|
<ProjectDetails ref="itemDictRef" :dialog-title="'选择检验项目'" :tableKey="labPatKey" @select="handleItemSelect" />
|
||||||
|
|
||||||
@ -144,34 +143,15 @@
|
|||||||
<!-- 抗生素组模板 -->
|
<!-- 抗生素组模板 -->
|
||||||
<kssMb ref="kssMbRef" :dialog-title="'抗生素组选择'" :tableKey="labPatKey" @select="kssSelect" />
|
<kssMb ref="kssMbRef" :dialog-title="'抗生素组选择'" :tableKey="labPatKey" @select="kssSelect" />
|
||||||
|
|
||||||
<!-- 操作原因 -->
|
<!-- 校验用户 -->
|
||||||
<el-dialog v-model="unCheckshow" title="操作原因" width="500" :close-on-click-modal="false" :draggable="true"
|
<CheckUser ref="checkUserRef" :title="checktitle" @onConfirm="handleCheckUserConfirm" />
|
||||||
@close="unconfirmlogCancel">
|
|
||||||
<div class="dialog-body mb10">
|
|
||||||
<p class="reason-text mb5">{{ reasonText }} </p>
|
|
||||||
<el-form ref="uncheckFormRef" style="max-width: 600px" :model="uncheckForm" :rules="rules" label-width="auto">
|
|
||||||
<template v-if="labPatKey.problemId == 4">
|
|
||||||
<el-input type="textarea" v-model="uncheckForm.reason" class="reason-input" placeholder="请输入操作原因..."
|
|
||||||
:rows="4"></el-input>
|
|
||||||
</template>
|
|
||||||
<template v-if="labPatKey.problemId == 6">
|
|
||||||
<el-form-item label="用户工号:" prop="yhdh">
|
|
||||||
<el-input v-model.trim="uncheckForm.yhdh" placeholder="请输入用户工号" maxlength="20"
|
|
||||||
@keyup.enter="submitForm" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="密码:" prop="mm">
|
|
||||||
<el-input v-model.trim="uncheckForm.mm" placeholder="请输入密码" type="mm" maxlength="20" show-password
|
|
||||||
@keyup.enter="submitForm" />
|
|
||||||
</el-form-item>
|
|
||||||
</template>
|
|
||||||
</el-form>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div style="text-align: center; width: 100%;">
|
<!-- 取消审核操作原因 -->
|
||||||
<el-button type="primary" @click="unconfirmlogConfirm()"> 确认 </el-button>
|
<Unconfirmlog ref="unconfirmlogRef" :reasonText="reasonText" :tableKey="labPatKey" @onConfirm="unShHandle" />
|
||||||
<el-button @click="unconfirmlogCancel">取消</el-button>
|
|
||||||
</div>
|
<!-- 危急值结果上报 -->
|
||||||
</el-dialog>
|
<UploadWarning ref="uploadwarningRef" :warningMsgdata="warningMsgdata" :tableKey="labPatKey"
|
||||||
|
@onupload="shHandleCheck" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -184,6 +164,9 @@ import {
|
|||||||
} from '@/api/liswork/micro/index';
|
} from '@/api/liswork/micro/index';
|
||||||
import { check2, uncheck2, unconfirmlog, checkuser, deleteresult, queryXmVal, setinputmdl, } from "@/api/liswork/work/LisWork";
|
import { check2, uncheck2, unconfirmlog, checkuser, deleteresult, queryXmVal, setinputmdl, } from "@/api/liswork/work/LisWork";
|
||||||
import { useCommonStore } from "@/store/modules/commonStore";
|
import { useCommonStore } from "@/store/modules/commonStore";
|
||||||
|
import CheckUser from "../../work/components/CheckUser.vue";
|
||||||
|
import Unconfirmlog from "../../work/components/unconfirmlog.vue";
|
||||||
|
import UploadWarning from "../../work/components/uploadwarning.vue";
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import ProjectDetails from "@/components/projectDetails/index.vue";
|
import ProjectDetails from "@/components/projectDetails/index.vue";
|
||||||
import projectsJg from "@/components/projectsjg/index.vue";
|
import projectsJg from "@/components/projectsjg/index.vue";
|
||||||
@ -223,14 +206,15 @@ const { labPat, labPatKey, labResutsData, dictData } = toRefs(props);
|
|||||||
const emits = defineEmits([
|
const emits = defineEmits([
|
||||||
'fetchLabResults',
|
'fetchLabResults',
|
||||||
'changeStatus',
|
'changeStatus',
|
||||||
'previewHandle'
|
'previewHandle',
|
||||||
|
'update:labPatKey'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const activeName2 = ref('first')
|
const activeName2 = ref('first')
|
||||||
const textarea = ref('')
|
const textarea = ref('')
|
||||||
|
|
||||||
const columns = ref([
|
const columns = ref([
|
||||||
{ label: "细菌/结果", prop: "zhxmdh", align: 'center', visible: true, headerSlot: 'xmdh', width: 150 },
|
{ label: "细菌/结果", prop: "zhxmdh", visible: true, headerSlot: 'xmdh', width: 150 },
|
||||||
{ label: "菌落计数", prop: "od", align: 'center', visible: true, slot: 'od' },
|
{ label: "菌落计数", prop: "od", align: 'center', visible: true, slot: 'od' },
|
||||||
{ label: "检验结果", prop: "csjg", align: 'center', visible: true, slot: 'csjg' },
|
{ label: "检验结果", prop: "csjg", align: 'center', visible: true, slot: 'csjg' },
|
||||||
{ label: "阴阳性", prop: "jgbz", align: 'center', visible: true, slot: 'jgbz', showOverflowTooltip: false },
|
{ label: "阴阳性", prop: "jgbz", align: 'center', visible: true, slot: 'jgbz', showOverflowTooltip: false },
|
||||||
@ -292,18 +276,36 @@ const handleColumnDragEnd = (data: any) => {
|
|||||||
columns.value = data.columns;
|
columns.value = data.columns;
|
||||||
}
|
}
|
||||||
|
|
||||||
const unCheckshow = ref(false);
|
|
||||||
const reasonText = ref('');
|
const reasonText = ref('');
|
||||||
const warningMsgdata = ref('');
|
const warningMsgdata = ref('');
|
||||||
const showuploadwarning = ref(false);
|
const checktitle = ref('');
|
||||||
|
const checkUserRef = ref();
|
||||||
|
const runnextstepname = ref(-1);
|
||||||
const handleCheck = (checkType: number) => {
|
const handleCheck = (checkType: number) => {
|
||||||
// yhdh = checkuserid.value
|
runnextstepname.value = checkType
|
||||||
switch (checkType) {
|
labPatKey.value.problemId = 0;
|
||||||
// case 1: // 初审
|
if (!labPatKey.value.yhdh) {
|
||||||
// check1({ ...labPatKey.value, jyrq: labPat.value.jyrq, yhdh: props.labPat.yhdh }).then((res: any) => {
|
checktitle.value = '审核人工号密码验证'
|
||||||
// emits("changeStatus", props.labPat);
|
checkUserRef.value.open()
|
||||||
// })
|
} else {
|
||||||
// break;
|
proceedCheck(checkType)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleCheckUserConfirm = (info: { yhdh: string, mm: string }) => {
|
||||||
|
checkuser({ yhdh: info.yhdh, mm: info.mm }).then((response: any) => {
|
||||||
|
if (response.code == 0) {
|
||||||
|
emits('update:labPatKey', {
|
||||||
|
...labPatKey.value,
|
||||||
|
yhdh: info.yhdh
|
||||||
|
});
|
||||||
|
proceedCheck(runnextstepname.value)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const proceedCheck = (type: number) => {
|
||||||
|
switch (type) {
|
||||||
case 2: // 审核
|
case 2: // 审核
|
||||||
labPatKey.value.problemId = 0
|
labPatKey.value.problemId = 0
|
||||||
shHandleCheck()
|
shHandleCheck()
|
||||||
@ -315,96 +317,34 @@ const handleCheck = (checkType: number) => {
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
const uploadwarningRef = ref();
|
||||||
const shHandleCheck = () => {
|
const shHandleCheck = () => {
|
||||||
check2({ ...labPatKey.value, jyrq: labPat.value.jyrq, yhdh: props.labPat.yhdh }).then((res: any) => {
|
check2({ ...labPatKey.value, jyrq: labPat.value.jyrq, yhdh: props.labPat.yhdh }).then((res: any) => {
|
||||||
emits("changeStatus", props.labPat);
|
emits("changeStatus", props.labPat);
|
||||||
if (res.code == "4" && res.problemId === 4) {
|
if (res.code == "4" && res.problemId === 4) {
|
||||||
labPatKey.value.problemId = res.problemId;
|
labPatKey.value.problemId = res.problemId;
|
||||||
warningMsgdata.value = res.msg;
|
warningMsgdata.value = res.msg;
|
||||||
showuploadwarning.value = true;
|
uploadwarningRef.value.open();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
const unconfirmlogRef = ref();
|
||||||
|
|
||||||
const unShHandle = () => {
|
const unShHandle = () => {
|
||||||
uncheck2({ ...labPatKey.value, jyrq: labPat.value.jyrq, yhdh: props.labPat.yhdh }).then((res: any) => {
|
uncheck2({ ...labPatKey.value, jyrq: labPat.value.jyrq, yhdh: props.labPat.yhdh }).then((res: any) => {
|
||||||
if (res.code == "4") {
|
if (res.code == "4") {
|
||||||
labPatKey.value.problemId = res.problemId;
|
labPatKey.value.problemId = res.problemId;
|
||||||
reasonText.value = res.msg;
|
reasonText.value = res.msg;
|
||||||
unCheckshow.value = true;
|
unconfirmlogRef.value.open();
|
||||||
}
|
}
|
||||||
emits("changeStatus", props.labPat);
|
emits("changeStatus", props.labPat);
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
const uncheckFormRef = ref();
|
|
||||||
const uncheckForm = ref({
|
|
||||||
reason: '',
|
|
||||||
yhdh: '',
|
|
||||||
mm: '',
|
|
||||||
})
|
|
||||||
// 取消审核原因
|
|
||||||
const unconfirmlogConfirm = async () => {
|
|
||||||
if (labPatKey.value.problemId == 4) {
|
|
||||||
// if (!uncheckForm.value.inputValue) return ElMessage.warning("请输入操作原因")
|
|
||||||
} else if (labPatKey.value.problemId == 6) {
|
|
||||||
const valid = await uncheckFormRef.value.validate().catch(() => { });
|
|
||||||
if (!valid) return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
unconfirmlog({ ...labPatKey.value, jyrq: labPat.value.jyrq, ...uncheckForm.value }).then((response: any) => {
|
|
||||||
if (response.code == "0") {
|
|
||||||
unCheckshow.value = false;
|
|
||||||
unShHandle();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
const checkuserid = ref()
|
|
||||||
const checkShow = ref(false);
|
|
||||||
const ruleForm = ref({
|
|
||||||
yhdh: '',
|
|
||||||
mm: ''
|
|
||||||
});
|
|
||||||
|
|
||||||
const rules = ref(
|
|
||||||
{
|
|
||||||
yhdh: [{ required: true, message: "请输入用户工号", trigger: "blur" },
|
|
||||||
{ min: 3, max: 20, message: "长度在 3 到 20 个字符", trigger: "blur" }
|
|
||||||
],
|
|
||||||
mm: [{ required: true, message: "请输入密码", trigger: "blur" },
|
|
||||||
{ min: 6, max: 20, message: "长度在 6 到 20 个字符", trigger: "blur" }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
);
|
|
||||||
const unconfirmlogCancel = () => {
|
|
||||||
unCheckshow.value = false;
|
|
||||||
uncheckForm.value.reason = '';
|
|
||||||
uncheckForm.value.yhdh = '';
|
|
||||||
uncheckForm.value.mm = '';
|
|
||||||
uncheckFormRef.value.resetFields();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const ruleFormRef = ref();
|
|
||||||
|
|
||||||
const submitForm = () => {
|
|
||||||
ruleFormRef.value.validate((valid: boolean) => {
|
|
||||||
if (valid) {
|
|
||||||
checkuser(ruleForm.value).then((res: any) => {
|
|
||||||
if (res.code == 0) {
|
|
||||||
checkuserid.value = ruleForm.value.yhdh
|
|
||||||
checkShow.value = false;
|
|
||||||
ElMessage.success("验证成功");
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const itemDictRef = ref();
|
const itemDictRef = ref();
|
||||||
const openItemDictDialog = () => {
|
const openItemDictDialog = () => {
|
||||||
@ -664,7 +604,7 @@ const ymColumns = ref([
|
|||||||
{ label: "Mic", prop: "mic", align: 'center', visible: true, width: 60, slot: 'mic' },
|
{ label: "Mic", prop: "mic", align: 'center', visible: true, width: 60, slot: 'mic' },
|
||||||
{ label: "KB", prop: "rad", align: 'center', visible: true, width: 50, slot: 'rad' },
|
{ label: "KB", prop: "rad", align: 'center', visible: true, width: 50, slot: 'rad' },
|
||||||
{ label: "结果", prop: "csjg", align: 'center', visible: true, width: 60, slot: 'csjg' },
|
{ label: "结果", prop: "csjg", align: 'center', visible: true, width: 60, slot: 'csjg' },
|
||||||
{ label: "结果标志", prop: "jgbz", align: 'center', visible: true, slot: 'jgbz', width: 200, showOverflowTooltip: false },
|
{ label: "结果标志", prop: "jgbz", align: 'center', visible: true, slot: 'jgbz', width: 180, showOverflowTooltip: false },
|
||||||
{ label: "折点", prop: "ckz", align: 'center', visible: true, },
|
{ label: "折点", prop: "ckz", align: 'center', visible: true, },
|
||||||
{ label: "分组", prop: "bz", align: 'center', visible: true, slot: 'bz' },
|
{ label: "分组", prop: "bz", align: 'center', visible: true, slot: 'bz' },
|
||||||
{ label: "专家值", prop: "txtresult", align: 'center', visible: true, slot: 'txtresult' },
|
{ label: "专家值", prop: "txtresult", align: 'center', visible: true, slot: 'txtresult' },
|
||||||
|
|||||||
@ -1,89 +1,33 @@
|
|||||||
<template>
|
<template>
|
||||||
<!-- 遮罩层 -->
|
<div>
|
||||||
<div
|
<el-dialog v-model="checkShow" :title="title" width="500" :close-on-click-modal="false" :draggable="true"
|
||||||
v-if="visible"
|
@close="handleCancel">
|
||||||
class="dialog-mask"
|
<el-form ref="ruleFormRef" style="max-width: 600px" :model="ruleForm" :rules="rules" label-width="auto">
|
||||||
@click="handleCancel"
|
<el-form-item label="用户工号:" prop="yhdh">
|
||||||
></div>
|
<el-input ref="yhdhRef" v-model.trim="ruleForm.yhdh" placeholder="请输入用户工号" maxlength="20"
|
||||||
|
@keyup.enter="handleConfirm" />
|
||||||
<!-- 弹窗主体 -->
|
</el-form-item>
|
||||||
<div
|
<el-form-item label="密码:" prop="mm">
|
||||||
v-if="visible"
|
<el-input v-model.trim="ruleForm.mm" placeholder="请输入密码" type="mm" maxlength="20" show-password
|
||||||
class="dialog-container"
|
@keyup.enter="handleConfirm" />
|
||||||
>
|
</el-form-item>
|
||||||
<div class="dialog-box">
|
<el-form-item>
|
||||||
<!-- 标题区域 -->
|
<div style="text-align: center; width: 100%;">
|
||||||
<div class="dialog-header">
|
<el-button type="primary" @click="handleConfirm()"> 确认 </el-button>
|
||||||
<h3 class="dialog-title">{{ title }}</h3>
|
<el-button @click="handleCancel">取消</el-button>
|
||||||
<button
|
</div>
|
||||||
class="dialog-close"
|
</el-form-item>
|
||||||
@click="handleCancel"
|
</el-form>
|
||||||
aria-label="关闭"
|
</el-dialog>
|
||||||
>
|
|
||||||
<span>×</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 内容区域 -->
|
|
||||||
<div class="dialog-body">
|
|
||||||
<!-- 工号输入 -->
|
|
||||||
<div class="form-item">
|
|
||||||
<label class="form-label">用户工号</label>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
v-model.trim="userId"
|
|
||||||
class="form-input"
|
|
||||||
placeholder="请输入用户工号"
|
|
||||||
@keyup.enter="handleConfirm"
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 密码输入 -->
|
|
||||||
<div class="form-item">
|
|
||||||
<label class="form-label">密码</label>
|
|
||||||
<input
|
|
||||||
type="password"
|
|
||||||
v-model="password"
|
|
||||||
class="form-input"
|
|
||||||
placeholder="请输入密码"
|
|
||||||
@keyup.enter="handleConfirm"
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 错误提示 -->
|
|
||||||
<p v-if="errorMsg" class="error-message">{{ errorMsg }}</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 按钮区域 -->
|
|
||||||
<div class="dialog-footer">
|
|
||||||
<button
|
|
||||||
class="btn btn-cancel"
|
|
||||||
@click="handleCancel"
|
|
||||||
>
|
|
||||||
取消
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
class="btn btn-confirm"
|
|
||||||
@click="handleConfirm"
|
|
||||||
:disabled="!userId || !password"
|
|
||||||
>
|
|
||||||
确认验证
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup lang="ts">
|
||||||
|
import { set } from '@vueuse/core';
|
||||||
import { defineProps, defineEmits, ref, watch } from 'vue';
|
import { defineProps, defineEmits, ref, watch } from 'vue';
|
||||||
|
|
||||||
// 组件属性
|
// 组件属性
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
// 控制弹窗显示/隐藏
|
|
||||||
visible: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
// 弹窗标题(由外部参数控制)
|
// 弹窗标题(由外部参数控制)
|
||||||
title: {
|
title: {
|
||||||
type: String,
|
type: String,
|
||||||
@ -103,221 +47,61 @@ const props = defineProps({
|
|||||||
|
|
||||||
// 组件事件
|
// 组件事件
|
||||||
const emit = defineEmits([
|
const emit = defineEmits([
|
||||||
'update:visible', // 控制弹窗显示状态
|
|
||||||
'onConfirm', // 验证成功回调
|
'onConfirm', // 验证成功回调
|
||||||
'onCancel' // 取消验证回调
|
'onCancel'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// 表单数据
|
// 表单数据
|
||||||
const userId = ref('');
|
const ruleForm = ref({
|
||||||
const password = ref('');
|
yhdh: '',
|
||||||
const errorMsg = ref('');
|
mm: '',
|
||||||
|
});
|
||||||
|
|
||||||
// 监听弹窗显示状态,重置表单
|
const rules = ref(
|
||||||
watch(
|
{
|
||||||
() => props.visible,
|
yhdh: [{ required: true, message: "请输入用户工号", trigger: "blur" },
|
||||||
(newVal) => {
|
{ min: 3, max: 20, message: "长度在 3 到 20 个字符", trigger: "blur" }
|
||||||
if (newVal) {
|
],
|
||||||
// 打开弹窗时重置表单
|
mm: [{ required: true, message: "请输入密码", trigger: "blur" },
|
||||||
userId.value = '';
|
{ min: 6, max: 20, message: "长度在 6 到 20 个字符", trigger: "blur" }
|
||||||
password.value = '';
|
]
|
||||||
errorMsg.value = '';
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
const yhdhRef = ref();
|
||||||
|
const open = () => {
|
||||||
|
checkShow.value = true;
|
||||||
|
nextTick(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
yhdhRef.value.focus();
|
||||||
|
}, 100);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const checkShow = ref(false);
|
||||||
|
const ruleFormRef = ref();
|
||||||
// 处理确认验证
|
// 处理确认验证
|
||||||
const handleConfirm = () => {
|
const handleConfirm = () => {
|
||||||
// 基础验证
|
ruleFormRef.value.validate((valid: boolean) => {
|
||||||
if (!userId.value) {
|
if (valid) {
|
||||||
errorMsg.value = '请输入用户工号';
|
emit('onConfirm', { yhdh: ruleForm.value.yhdh, mm: ruleForm.value.mm });
|
||||||
return;
|
checkShow.value = false;
|
||||||
}
|
} else {
|
||||||
|
return false;
|
||||||
if (!password.value) {
|
}
|
||||||
errorMsg.value = '请输入密码';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 应用外部传入的验证规则
|
|
||||||
if (userId.value.length < props.validationRules.userIdMinLength) {
|
|
||||||
errorMsg.value = `工号长度不能少于${props.validationRules.userIdMinLength}位`;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (password.value.length < props.validationRules.passwordMinLength) {
|
|
||||||
errorMsg.value = `密码长度不能少于${props.validationRules.passwordMinLength}位`;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 验证通过,返回用户工号
|
|
||||||
emit('onConfirm', {
|
|
||||||
userId: userId.value,
|
|
||||||
password: password.value
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// 关闭弹窗
|
|
||||||
emit('update:visible', false);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// 处理取消
|
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
|
checkShow.value = false;
|
||||||
|
ruleForm.value.yhdh = '';
|
||||||
|
ruleForm.value.mm = '';
|
||||||
|
ruleFormRef.value.resetFields();
|
||||||
emit('onCancel');
|
emit('onCancel');
|
||||||
emit('update:visible', false);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
open,
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped lang="scss"></style>
|
||||||
/* 遮罩层 */
|
|
||||||
.dialog-mask {
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
background-color: rgba(0, 0, 0, 0.5);
|
|
||||||
z-index: 1000;
|
|
||||||
transition: opacity 0.3s;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 弹窗容器 */
|
|
||||||
.dialog-container {
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
z-index: 1001;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
padding: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 弹窗主体 */
|
|
||||||
.dialog-box {
|
|
||||||
width: 100%;
|
|
||||||
max-width: 400px;
|
|
||||||
background-color: #fff;
|
|
||||||
border-radius: 8px;
|
|
||||||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 标题区域 */
|
|
||||||
.dialog-header {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: 16px 20px;
|
|
||||||
border-bottom: 1px solid #f0f0f0;
|
|
||||||
background-color: #f9fafb;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dialog-title {
|
|
||||||
margin: 0;
|
|
||||||
font-size: 16px;
|
|
||||||
font-weight: 600;
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dialog-close {
|
|
||||||
padding: 0;
|
|
||||||
background: transparent;
|
|
||||||
border: none;
|
|
||||||
font-size: 20px;
|
|
||||||
color: #999;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: color 0.2s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dialog-close:hover {
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 内容区域 */
|
|
||||||
.dialog-body {
|
|
||||||
padding: 24px 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-item {
|
|
||||||
margin-bottom: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-label {
|
|
||||||
display: block;
|
|
||||||
margin-bottom: 8px;
|
|
||||||
font-size: 14px;
|
|
||||||
color: #666;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-input {
|
|
||||||
width: 100%;
|
|
||||||
padding: 10px 12px;
|
|
||||||
border: 1px solid #dcdfe6;
|
|
||||||
border-radius: 4px;
|
|
||||||
font-size: 14px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
transition: border-color 0.2s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-input:focus {
|
|
||||||
outline: none;
|
|
||||||
border-color: #4096ff;
|
|
||||||
box-shadow: 0 0 0 2px rgba(64, 150, 255, 0.2);
|
|
||||||
}
|
|
||||||
|
|
||||||
.error-message {
|
|
||||||
margin: 8px 0 0;
|
|
||||||
color: #f56c6c;
|
|
||||||
font-size: 12px;
|
|
||||||
line-height: 1.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 按钮区域 */
|
|
||||||
.dialog-footer {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-end;
|
|
||||||
padding: 12px 20px;
|
|
||||||
border-top: 1px solid #f0f0f0;
|
|
||||||
background-color: #f9fafb;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn {
|
|
||||||
padding: 8px 16px;
|
|
||||||
border-radius: 4px;
|
|
||||||
font-size: 14px;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: all 0.2s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-cancel {
|
|
||||||
margin-right: 10px;
|
|
||||||
border: 1px solid #dcdfe6;
|
|
||||||
background-color: #fff;
|
|
||||||
color: #606266;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-cancel:hover {
|
|
||||||
background-color: #f5f7fa;
|
|
||||||
border-color: #c0c4cc;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-confirm {
|
|
||||||
border: 1px solid #4096ff;
|
|
||||||
background-color: #4096ff;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-confirm:hover {
|
|
||||||
background-color: #66b1ff;
|
|
||||||
border-color: #66b1ff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-confirm:disabled {
|
|
||||||
opacity: 0.6;
|
|
||||||
cursor: not-allowed;
|
|
||||||
background-color: #4096ff;
|
|
||||||
border-color: #4096ff;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|||||||
@ -76,82 +76,13 @@
|
|||||||
<ProjectDetails ref="itemDictRef" :dialog-title="'选择检验项目'" :tableKey="tableKey" @select="handleItemSelect" />
|
<ProjectDetails ref="itemDictRef" :dialog-title="'选择检验项目'" :tableKey="tableKey" @select="handleItemSelect" />
|
||||||
|
|
||||||
<!-- 校验用户 -->
|
<!-- 校验用户 -->
|
||||||
<el-dialog v-model="checkShow" title="用户身份验证" width="500" :close-on-click-modal="false" :draggable="true"
|
<CheckUser ref="checkUserRef" :title="checktitle" @onConfirm="handleCheckUserConfirm" />
|
||||||
@close="resetForm">
|
|
||||||
<el-form ref="ruleFormRef" style="max-width: 600px" :model="ruleForm" :rules="rules" label-width="auto">
|
|
||||||
<el-form-item label="用户工号:" prop="yhdh">
|
|
||||||
<el-input v-model.trim="ruleForm.yhdh" placeholder="请输入用户工号" maxlength="20" @keyup.enter="submitForm" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="密码:" prop="mm">
|
|
||||||
<el-input v-model.trim="ruleForm.mm" placeholder="请输入密码" type="mm" maxlength="20" show-password
|
|
||||||
@keyup.enter="submitForm" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<div style="text-align: center; width: 100%;">
|
|
||||||
<el-button type="primary" @click="submitForm()"> 确认 </el-button>
|
|
||||||
<el-button @click="resetForm">取消</el-button>
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
</el-dialog>
|
|
||||||
|
|
||||||
<!-- 危急值结果上报 -->
|
<!-- 危急值结果上报 -->
|
||||||
<el-dialog v-model="showuploadwarning" title="危急值结果上报" width="500" :close-on-click-modal="false" :draggable="true"
|
<UploadWarning ref="uploadwarningRef" :warningMsgdata="warningMsgdata" :tableKey="tableKey"
|
||||||
@close="warningResetForm">
|
@onupload="shHandleCheck" />
|
||||||
<div class="red-static-text">{{ warningMsgdata }}</div>
|
|
||||||
<el-form ref="warningFormRef" style="max-width: 600px" :model="warningForm" :rules="wrules" label-width="auto">
|
|
||||||
<el-form-item label="上报方式:" prop="uploadTp">
|
|
||||||
<el-radio-group v-model="warningForm.uploadTp" size="default">
|
|
||||||
<el-radio value="1">系统通知</el-radio>
|
|
||||||
<el-radio value="2">电话通知</el-radio>
|
|
||||||
</el-radio-group>
|
|
||||||
</el-form-item>
|
|
||||||
<template v-if="warningForm.uploadTp == 2">
|
|
||||||
<el-form-item label="电话通知人:" prop="userId">
|
|
||||||
<el-input v-model.trim="warningForm.userId" class="form-input" placeholder="请输入医生工号" @keyup.enter=" " />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="联系电话:" prop="phone">
|
|
||||||
<el-input v-model="warningForm.phone" class="form-input" placeholder="请输入联系电话" @keyup.enter=" " />
|
|
||||||
</el-form-item>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<el-form-item>
|
|
||||||
<div style="text-align: center; width: 100%;">
|
|
||||||
<el-button type="primary" @click="handleWarningSuccess()"> 确认 </el-button>
|
|
||||||
<el-button @click="warningResetForm">取消</el-button>
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
</el-dialog>
|
|
||||||
|
|
||||||
<!-- 操作原因 -->
|
<!-- 操作原因 -->
|
||||||
<el-dialog v-model="unCheckshow" title="操作原因" width="500" :close-on-click-modal="false" :draggable="true"
|
<Unconfirmlog ref="unconfirmlogRef" :reasonText="reasonText" :tableKey="tableKey" @onConfirm="unShHandle" />
|
||||||
@close="unconfirmlogCancel">
|
|
||||||
<div class="dialog-body mb10">
|
|
||||||
<p class="reason-text mb5">{{ reasonText }} </p>
|
|
||||||
<el-form ref="uncheckFormRef" style="max-width: 600px" :model="uncheckForm" :rules="rules" label-width="auto">
|
|
||||||
<template v-if="tableKey.problemId == 4">
|
|
||||||
<el-input type="textarea" v-model="uncheckForm.reason" class="reason-input" placeholder="请输入操作原因..."
|
|
||||||
:rows="4"></el-input>
|
|
||||||
</template>
|
|
||||||
<template v-if="tableKey.problemId == 6">
|
|
||||||
<el-form-item label="用户工号:" prop="yhdh">
|
|
||||||
<el-input v-model.trim="uncheckForm.yhdh" placeholder="请输入用户工号" maxlength="20"
|
|
||||||
@keyup.enter="submitForm" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="密码:" prop="mm">
|
|
||||||
<el-input v-model.trim="uncheckForm.mm" placeholder="请输入密码" type="mm" maxlength="20" show-password
|
|
||||||
@keyup.enter="submitForm" />
|
|
||||||
</el-form-item>
|
|
||||||
</template>
|
|
||||||
</el-form>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div style="text-align: center; width: 100%;">
|
|
||||||
<el-button type="primary" @click="unconfirmlogConfirm()"> 确认 </el-button>
|
|
||||||
<el-button @click="unconfirmlogCancel">取消</el-button>
|
|
||||||
</div>
|
|
||||||
</el-dialog>
|
|
||||||
|
|
||||||
|
|
||||||
<!-- 合并当前病人其他结果 -->
|
<!-- 合并当前病人其他结果 -->
|
||||||
@ -261,7 +192,6 @@
|
|||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -280,6 +210,9 @@ import { classCom } from '@/utils/classCom'
|
|||||||
import CustomTable from '@/components/elTable/index.vue'
|
import CustomTable from '@/components/elTable/index.vue'
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import emitter from "@/utils/mitt";
|
import emitter from "@/utils/mitt";
|
||||||
|
import CheckUser from "./CheckUser.vue";
|
||||||
|
import Unconfirmlog from './unconfirmlog.vue';
|
||||||
|
import UploadWarning from "./uploadwarning.vue";
|
||||||
import { useCommonStore } from "@/store/modules/commonStore";
|
import { useCommonStore } from "@/store/modules/commonStore";
|
||||||
import ContextMenu from "@/components/contextMenu/index.vue";
|
import ContextMenu from "@/components/contextMenu/index.vue";
|
||||||
import ViewBackup from "./viewBackup.vue";
|
import ViewBackup from "./viewBackup.vue";
|
||||||
@ -785,53 +718,12 @@ const beforeEnter = (row) => {
|
|||||||
lastResult.value = res.data || {}
|
lastResult.value = res.data || {}
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const warningForm = ref({
|
|
||||||
userId: '',
|
|
||||||
phone: '',
|
|
||||||
uploadTp: '1'
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
const uncheckForm = ref({
|
|
||||||
reason: '',
|
|
||||||
yhdh: '',
|
|
||||||
mm: '',
|
|
||||||
})
|
|
||||||
|
|
||||||
const wrules = ref({
|
|
||||||
userId: [{ required: true, message: "请输入用户工号", trigger: "blur" },
|
|
||||||
{ min: 3, max: 20, message: "长度在 3 到 20 个字符", trigger: "blur" }
|
|
||||||
],
|
|
||||||
phone: [{ required: true, message: "请输入联系电话", trigger: "blur" },
|
|
||||||
{ min: 6, max: 20, message: "长度在 6 到 20 个字符", trigger: "blur" }
|
|
||||||
]
|
|
||||||
})
|
|
||||||
|
|
||||||
const unCheckshow = ref(false);
|
|
||||||
const inputValue = ref('');
|
|
||||||
const reasonText = ref('');
|
const reasonText = ref('');
|
||||||
const warningMsgdata = ref('');
|
const warningMsgdata = ref('');
|
||||||
const showuploadwarning = ref(false);
|
|
||||||
const checkuserid = ref()
|
const checkuserid = ref()
|
||||||
const checkShow = ref(false);
|
const checkShow = ref(false);
|
||||||
const ruleForm = ref({
|
const checktitle = ref('');
|
||||||
yhdh: '',
|
const checkUserRef = ref();
|
||||||
mm: ''
|
|
||||||
});
|
|
||||||
|
|
||||||
const rules = ref(
|
|
||||||
{
|
|
||||||
yhdh: [{ required: true, message: "请输入用户工号", trigger: "blur" },
|
|
||||||
{ min: 3, max: 20, message: "长度在 3 到 20 个字符", trigger: "blur" }
|
|
||||||
],
|
|
||||||
mm: [{ required: true, message: "请输入密码", trigger: "blur" },
|
|
||||||
{ min: 6, max: 20, message: "长度在 6 到 20 个字符", trigger: "blur" }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const csjgRef = ref();
|
const csjgRef = ref();
|
||||||
|
|
||||||
@ -839,9 +731,32 @@ const itemDictRef = ref(); // DictInput组件引用
|
|||||||
|
|
||||||
const tableRef = ref();
|
const tableRef = ref();
|
||||||
|
|
||||||
|
const runnextstepname = ref(-1)
|
||||||
const handleCheck = (checkType) => {
|
const handleCheck = (checkType) => {
|
||||||
// yhdh = checkuserid.value
|
runnextstepname.value = checkType
|
||||||
|
tableKey.value.problemId = 0;
|
||||||
|
// tableKey.value.yhdh = checkuserid.value
|
||||||
|
if (!tableKey.value.yhdh) {
|
||||||
|
checktitle.value = '审核人工号密码验证'
|
||||||
|
checkUserRef.value.open()
|
||||||
|
} else {
|
||||||
|
proceedCheck(checkType)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleCheckUserConfirm = (info) => {
|
||||||
|
checkuser({ yhdh: info.yhdh, mm: info.mm }).then(response => {
|
||||||
|
if (response.code == 0) {
|
||||||
|
emits('update:tableKey', {
|
||||||
|
...tableKey.value,
|
||||||
|
yhdh: info.yhdh
|
||||||
|
});
|
||||||
|
proceedCheck(runnextstepname.value)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const proceedCheck = (checkType) => {
|
||||||
switch (checkType) {
|
switch (checkType) {
|
||||||
case 1: // 初审
|
case 1: // 初审
|
||||||
check1({ ...tableKey.value, yhdh: props.labPat.yhdh }).then(res => {
|
check1({ ...tableKey.value, yhdh: props.labPat.yhdh }).then(res => {
|
||||||
@ -859,89 +774,34 @@ const handleCheck = (checkType) => {
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
const uploadwarningRef = ref();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const shHandleCheck = () => {
|
const shHandleCheck = () => {
|
||||||
check2({ ...props.tableKey, yhdh: props.labPat.yhdh }).then(res => {
|
check2({ ...props.tableKey, yhdh: props.labPat.yhdh }).then(res => {
|
||||||
emits("changeStatus", props.labPat);
|
emits("changeStatus", props.labPat);
|
||||||
if (res.code == "4" && res.problemId === 4) {
|
if (res.code == "4" && res.problemId === 4) {
|
||||||
tableKey.value.problemId = res.problemId;
|
tableKey.value.problemId = res.problemId;
|
||||||
warningMsgdata.value = res.msg;
|
warningMsgdata.value = res.msg;
|
||||||
showuploadwarning.value = true;
|
uploadwarningRef.value.open();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
const warningFormRef = ref(null);
|
|
||||||
|
|
||||||
const warningResetForm = () => {
|
|
||||||
warningForm.value.userId = '';
|
|
||||||
warningForm.value.phone = '';
|
|
||||||
warningForm.value.uploadTp = '1';
|
|
||||||
warningFormRef.value.resetFields();
|
|
||||||
showuploadwarning.value = false;
|
|
||||||
};
|
|
||||||
// 处理危急值登记
|
|
||||||
const handleWarningSuccess = async () => {
|
|
||||||
if (warningForm.value.uploadTp == 2) {
|
|
||||||
const valid = await warningFormRef.value.validate().catch(() => { });
|
|
||||||
if (!valid) return false;
|
|
||||||
}
|
|
||||||
reglimit({ ...tableKey.value, qrr: warningForm.value.userId, tzfs: warningForm.value.uploadTp, phone: warningForm.value.phone }).then(response => {
|
|
||||||
showuploadwarning.value = false;
|
|
||||||
if (response.code == 0) {
|
|
||||||
shHandleCheck();
|
|
||||||
}
|
|
||||||
if (response.code == 4) {
|
|
||||||
ElMessageBox.confirm(response.msg, '系统提示', { confirmButtonText: '是', cancelButtonText: '否', type: 'warning' }).then(() => {
|
|
||||||
tableKey.value.problemId = tableKey.value.problemId + 1;
|
|
||||||
handleWarningSuccess();
|
|
||||||
}).catch(() => {
|
|
||||||
shHandleCheck();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
|
const unconfirmlogRef = ref();
|
||||||
const unShHandle = () => {
|
const unShHandle = () => {
|
||||||
uncheck2({ ...tableKey.value, yhdh: props.labPat.yhdh }).then(res => {
|
uncheck2({ ...tableKey.value, yhdh: props.labPat.yhdh }).then(res => {
|
||||||
|
console.log('res',res);
|
||||||
if (res.code == "4") {
|
if (res.code == "4") {
|
||||||
tableKey.value.problemId = res.problemId;
|
tableKey.value.problemId = res.problemId;
|
||||||
reasonText.value = res.msg;
|
reasonText.value = res.msg;
|
||||||
unCheckshow.value = true;
|
unconfirmlogRef.value.open();
|
||||||
}
|
}
|
||||||
emits("changeStatus", props.labPat);
|
emits("changeStatus", props.labPat);
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
const uncheckFormRef = ref();
|
|
||||||
// 取消审核原因
|
|
||||||
const unconfirmlogConfirm = async () => {
|
|
||||||
if (tableKey.value.problemId == 4) {
|
|
||||||
if (!uncheckForm.value.inputValue) return ElMessage.warning("请输入操作原因")
|
|
||||||
} else if (tableKey.value.problemId == 6) {
|
|
||||||
const valid = await uncheckFormRef.value.validate().catch(() => { });
|
|
||||||
if (!valid) return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
unconfirmlog({ ...tableKey.value, ...uncheckForm.value }).then(response => {
|
|
||||||
if (response.code == "0") {
|
|
||||||
unCheckshow.value = false;
|
|
||||||
unShHandle();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
const unconfirmlogCancel = () => {
|
|
||||||
unCheckshow.value = false;
|
|
||||||
uncheckForm.value.reason = '';
|
|
||||||
uncheckForm.value.yhdh = '';
|
|
||||||
uncheckForm.value.mm = '';
|
|
||||||
uncheckFormRef.value.resetFields();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const ruleFormRef = ref(null);
|
const ruleFormRef = ref(null);
|
||||||
@ -963,12 +823,7 @@ const submitForm = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const resetForm = () => {
|
|
||||||
checkShow.value = false;
|
|
||||||
ruleForm.value.userId = '';
|
|
||||||
ruleForm.value.mm = '';
|
|
||||||
ruleFormRef.value.resetFields();
|
|
||||||
};
|
|
||||||
// 2. 打开项目选择弹窗
|
// 2. 打开项目选择弹窗
|
||||||
const openItemDictDialog = () => {
|
const openItemDictDialog = () => {
|
||||||
itemDictRef.value.openDictSelector();
|
itemDictRef.value.openDictSelector();
|
||||||
@ -1022,7 +877,8 @@ const addRowFromDict = async (rowData) => {
|
|||||||
const emits = defineEmits([
|
const emits = defineEmits([
|
||||||
'fetchLabResults',
|
'fetchLabResults',
|
||||||
'changeStatus',
|
'changeStatus',
|
||||||
'previewHandle'
|
'previewHandle',
|
||||||
|
'update:tableKey'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const csjgTableData = ref([]);
|
const csjgTableData = ref([]);
|
||||||
|
|||||||
@ -1,186 +1,113 @@
|
|||||||
<template>
|
<template>
|
||||||
<!-- 遮罩层 -->
|
<div>
|
||||||
<div
|
<el-dialog v-model="unCheckshow" title="操作原因" width="500" :close-on-click-modal="false" :draggable="true"
|
||||||
v-if="visible"
|
@close="unconfirmlogCancel">
|
||||||
class="dialog-mask"
|
<div class="dialog-body mb10">
|
||||||
@click="handleMaskClick"
|
<p class="reason-text mb5">{{ reasonText }} </p>
|
||||||
></div>
|
<el-form ref="uncheckFormRef" style="max-width: 600px" :model="uncheckForm" :rules="rules" label-width="auto">
|
||||||
|
<template v-if="tableKey.problemId == 4">
|
||||||
<!-- 弹窗主体 -->
|
<el-input type="textarea" v-model="uncheckForm.reason" class="reason-input" placeholder="请输入操作原因..."
|
||||||
<div
|
:rows="4"></el-input>
|
||||||
v-if="visible"
|
</template>
|
||||||
class="dialog-wrapper"
|
<template v-if="tableKey.problemId == 6">
|
||||||
>
|
<el-form-item label="用户工号:" prop="yhdh">
|
||||||
<div class="dialog-container">
|
<el-input v-model.trim="uncheckForm.yhdh" placeholder="请输入用户工号" maxlength="20"
|
||||||
<!-- 标题 -->
|
@keyup.enter="unconfirmlogConfirm" />
|
||||||
<div class="dialog-header">
|
</el-form-item>
|
||||||
<h3>操作原因</h3>
|
<el-form-item label="密码:" prop="mm">
|
||||||
<button class="close-btn" @click="handleCancel">×</button>
|
<el-input v-model.trim="uncheckForm.mm" placeholder="请输入密码" type="mm" maxlength="20" show-password
|
||||||
|
@keyup.enter="unconfirmlogConfirm" />
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</el-form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 内容区 -->
|
<div style="text-align: center; width: 100%;">
|
||||||
<div class="dialog-body">
|
<el-button type="primary" @click="unconfirmlogConfirm()"> 确认 </el-button>
|
||||||
<p class="reason-text">{{ reasonText }}</p>
|
<el-button @click="unconfirmlogCancel">取消</el-button>
|
||||||
<textarea
|
|
||||||
v-model="inputValue"
|
|
||||||
class="reason-input"
|
|
||||||
placeholder="请输入操作原因..."
|
|
||||||
rows="4"
|
|
||||||
></textarea>
|
|
||||||
</div>
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
<!-- 按钮区 -->
|
|
||||||
<div class="dialog-footer">
|
|
||||||
<button class="btn cancel" @click="handleCancel">取消</button>
|
|
||||||
<button class="btn confirm" @click="handleConfirm">确认</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup lang="ts">
|
||||||
import { defineProps, defineEmits, ref } from 'vue';
|
import { ElMessage } from 'element-plus';
|
||||||
|
import { unconfirmlog } from "@/api/liswork/work/LisWork";
|
||||||
|
|
||||||
|
|
||||||
// 组件属性
|
// 组件属性
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
visible: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
reasonText: {
|
reasonText: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '请填写操作原因'
|
default: '请填写操作原因'
|
||||||
|
},
|
||||||
|
tableKey: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const { tableKey } = toRefs(props);
|
||||||
|
|
||||||
// 组件事件
|
// 组件事件
|
||||||
const emit = defineEmits(['update:visible', 'onConfirm', 'onCancel']);
|
const emit = defineEmits(['onConfirm']);
|
||||||
|
|
||||||
|
const uncheckForm = ref({
|
||||||
|
reason: '',
|
||||||
|
yhdh: '',
|
||||||
|
mm: '',
|
||||||
|
})
|
||||||
|
|
||||||
|
const rules = ref({
|
||||||
|
yhdh: [{ required: true, message: "请输入用户工号", trigger: "blur" },
|
||||||
|
{ min: 3, max: 20, message: "长度在 3 到 20 个字符", trigger: "blur" }
|
||||||
|
],
|
||||||
|
mm: [{ required: true, message: "请输入联系电话", trigger: "blur" },
|
||||||
|
{ min: 6, max: 20, message: "长度在 6 到 20 个字符", trigger: "blur" }
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
// 输入框内容
|
// 输入框内容
|
||||||
const inputValue = ref('');
|
const inputValue = ref('');
|
||||||
|
const unCheckshow = ref(false);
|
||||||
// 确认按钮点击
|
const open = () => {
|
||||||
const handleConfirm = () => {
|
unCheckshow.value = true;
|
||||||
emit('onConfirm', inputValue.value); // 传递输入值
|
|
||||||
emit('update:visible', false);
|
|
||||||
inputValue.value = ''; // 重置输入
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// 取消按钮点击
|
|
||||||
const handleCancel = () => {
|
const uncheckFormRef = ref();
|
||||||
emit('onCancel');
|
// 取消审核原因
|
||||||
emit('update:visible', false);
|
const unconfirmlogConfirm = async () => {
|
||||||
inputValue.value = ''; // 重置输入
|
if (tableKey.value.problemId == 4) {
|
||||||
|
if (!uncheckForm.value.reason) return ElMessage.warning("请输入操作原因")
|
||||||
|
} else if (tableKey.value.problemId == 6) {
|
||||||
|
const valid = await uncheckFormRef.value.validate().catch(() => { });
|
||||||
|
if (!valid) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
unconfirmlog({ ...tableKey.value, ...uncheckForm.value }).then((response: any) => {
|
||||||
|
if (response.code == "0") {
|
||||||
|
emit('onConfirm');
|
||||||
|
unCheckshow.value = false;
|
||||||
|
}
|
||||||
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
// 遮罩层点击
|
const unconfirmlogCancel = () => {
|
||||||
const handleMaskClick = () => {
|
unCheckshow.value = false;
|
||||||
handleCancel();
|
uncheckForm.value.reason = '';
|
||||||
};
|
uncheckForm.value.yhdh = '';
|
||||||
|
uncheckForm.value.mm = '';
|
||||||
|
uncheckFormRef.value.resetFields();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
open,
|
||||||
|
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped></style>
|
||||||
/* 基础样式与之前保持一致,确保按钮边框和输入框正常 */
|
|
||||||
.dialog-mask {
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
background: rgba(0, 0, 0, 0.5);
|
|
||||||
z-index: 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dialog-wrapper {
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
z-index: 1001;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
padding: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dialog-container {
|
|
||||||
width: 100%;
|
|
||||||
max-width: 500px;
|
|
||||||
background: #fff;
|
|
||||||
border: 1px solid #ddd;
|
|
||||||
border-radius: 8px;
|
|
||||||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.dialog-header {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
padding: 15px 20px;
|
|
||||||
border-bottom: 1px solid #eee;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dialog-header h3 {
|
|
||||||
margin: 0;
|
|
||||||
font-size: 16px;
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
.close-btn {
|
|
||||||
background: none;
|
|
||||||
border: none;
|
|
||||||
font-size: 20px;
|
|
||||||
color: #999;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dialog-body {
|
|
||||||
padding: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.reason-text {
|
|
||||||
margin: 0 0 15px 0;
|
|
||||||
color: #666;
|
|
||||||
}
|
|
||||||
|
|
||||||
.reason-input {
|
|
||||||
width: 100%;
|
|
||||||
padding: 10px;
|
|
||||||
border: 1px solid #ddd;
|
|
||||||
border-radius: 4px;
|
|
||||||
resize: vertical;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.reason-input:focus {
|
|
||||||
outline: none;
|
|
||||||
border-color: #4096ff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dialog-footer {
|
|
||||||
padding: 15px 20px;
|
|
||||||
border-top: 1px solid #eee;
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn {
|
|
||||||
padding: 6px 16px;
|
|
||||||
border-radius: 4px;
|
|
||||||
font-size: 14px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cancel {
|
|
||||||
margin-right: 10px;
|
|
||||||
border: 1px solid #ddd;
|
|
||||||
background: #fff;
|
|
||||||
color: #666;
|
|
||||||
}
|
|
||||||
|
|
||||||
.confirm {
|
|
||||||
border: 1px solid #4096ff;
|
|
||||||
background: #4096ff;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|||||||
@ -1,179 +1,113 @@
|
|||||||
<template>
|
<template>
|
||||||
<!-- 遮罩层 -->
|
<div>
|
||||||
<div
|
<el-dialog v-model="showuploadwarning" title="危急值结果上报" width="500" :close-on-click-modal="false" :draggable="true"
|
||||||
v-if="visible"
|
@close="warningResetForm">
|
||||||
class="dialog-mask"
|
<div class="red-static-text">{{ warningMsgdata }}</div>
|
||||||
@click="handleCancel"
|
<el-form ref="warningFormRef" style="max-width: 600px" :model="warningForm" :rules="wrules" label-width="auto">
|
||||||
></div>
|
<el-form-item label="上报方式:" prop="uploadTp">
|
||||||
|
<el-radio-group v-model="warningForm.uploadTp" size="default">
|
||||||
<!-- 弹窗主体 -->
|
<el-radio value="1">系统通知</el-radio>
|
||||||
<div
|
<el-radio value="2">电话通知</el-radio>
|
||||||
v-if="visible"
|
</el-radio-group>
|
||||||
class="dialog-container"
|
</el-form-item>
|
||||||
>
|
<template v-if="warningForm.uploadTp == '2'">
|
||||||
<div class="dialog-box">
|
<el-form-item label="电话通知人:" prop="userId">
|
||||||
<!-- 标题区域 -->
|
<el-input v-model.trim="warningForm.userId" class="form-input" placeholder="请输入医生工号" @keyup.enter=" " />
|
||||||
<div class="dialog-header">
|
|
||||||
<h3 class="dialog-title">危急值结果上报</h3>
|
|
||||||
<button
|
|
||||||
class="dialog-close"
|
|
||||||
@click="handleCancel"
|
|
||||||
aria-label="关闭"
|
|
||||||
>
|
|
||||||
<span>×</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 内容区域 -->
|
|
||||||
<div class="dialog-body">
|
|
||||||
<div class="red-static-text">{{ msgdata }}</div>
|
|
||||||
<el-col :span="1">
|
|
||||||
<el-form-item label="上报方式" prop="uploadTp">
|
|
||||||
<el-radio-group v-model="uploadTp" size="default">
|
|
||||||
<el-radio v-for="(item, index) in uploadtypeptions" :key="index" :label="item.value"
|
|
||||||
:disabled="item.disabled">{{item.label}}</el-radio>
|
|
||||||
</el-radio-group>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
<el-form-item label="联系电话:" prop="phone">
|
||||||
<div class="form-item" v-if="uploadTp === 2">
|
<el-input v-model="warningForm.phone" class="form-input" placeholder="请输入联系电话" @keyup.enter=" " />
|
||||||
<label class="form-label">电话通知人</label>
|
</el-form-item>
|
||||||
<input
|
</template>
|
||||||
type="text"
|
|
||||||
v-model.trim="userId"
|
|
||||||
class="form-input"
|
|
||||||
placeholder="请输入医生工号"
|
|
||||||
@keyup.enter="handleupload"
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
<div class="form-item" v-if="uploadTp === 2">
|
|
||||||
<label class="form-label">联系电话</label>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
v-model="phone"
|
|
||||||
class="form-input"
|
|
||||||
placeholder="请输入联系电话"
|
|
||||||
@keyup.enter="handleupload"
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 错误提示 -->
|
<el-form-item>
|
||||||
<p v-if="errorMsg" class="error-message">{{ errorMsg }}</p>
|
<div style="text-align: center; width: 100%;">
|
||||||
</div>
|
<el-button type="primary" @click="handleWarningSuccess()"> 确认 </el-button>
|
||||||
|
<el-button @click="warningResetForm">取消</el-button>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
<!-- 按钮区域 -->
|
|
||||||
<div class="dialog-footer">
|
|
||||||
<button
|
|
||||||
class="btn btn-cancel"
|
|
||||||
@click="handleCancel"
|
|
||||||
>
|
|
||||||
取消
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
class="btn btn-upload"
|
|
||||||
@click="handleupload"
|
|
||||||
:disabled="isSubmitDisabled"
|
|
||||||
>
|
|
||||||
确认上报
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup lang="ts">
|
||||||
import { defineProps, defineEmits, ref, watch } from 'vue';
|
import { reglimit } from "@/api/liswork/work/LisWork";
|
||||||
const uploadtypeptions = ref([{
|
import { ElMessageBox } from "element-plus";
|
||||||
"label": "系统通知",
|
|
||||||
"value": 1
|
|
||||||
}, {
|
|
||||||
"label": "电话通知",
|
|
||||||
"value": 2
|
|
||||||
}])
|
|
||||||
// 组件属性
|
// 组件属性
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
// 控制弹窗显示/隐藏
|
tableKey: {
|
||||||
visible: {
|
type: Object,
|
||||||
type: Boolean,
|
required: true
|
||||||
default: false
|
|
||||||
},
|
},
|
||||||
// 弹窗内容
|
|
||||||
msgdata: {
|
warningMsgdata: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: ''
|
||||||
},
|
|
||||||
// 显示规则
|
|
||||||
showRules: {
|
|
||||||
type: Number,
|
|
||||||
default:1
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const { tableKey, warningMsgdata } = toRefs(props);
|
||||||
|
|
||||||
// 组件事件
|
// 组件事件
|
||||||
const emit = defineEmits([
|
const emits = defineEmits(['onupload',]);
|
||||||
'update:visible', // 控制弹窗显示状态
|
const showuploadwarning = ref(false);
|
||||||
'onupload', // 验证成功回调
|
|
||||||
'onCancel' // 取消验证回调
|
|
||||||
]);
|
|
||||||
|
|
||||||
// 表单数据
|
|
||||||
const uploadTp = ref('1');
|
|
||||||
const userId = ref('');
|
|
||||||
const phone = ref('');
|
|
||||||
const errorMsg = ref('');
|
|
||||||
|
|
||||||
// 监听弹窗显示状态,重置表单
|
|
||||||
watch(
|
const warningForm = ref({
|
||||||
() => props.visible,
|
userId: '',
|
||||||
(newVal) => {
|
phone: '',
|
||||||
if (newVal) {
|
uploadTp: '1'
|
||||||
// 打开弹窗时重置表单
|
})
|
||||||
uploadTp.value = 1; // 打开弹窗时默认选中1
|
|
||||||
userId.value = '';
|
const wrules = ref({
|
||||||
phone.value = '';
|
userId: [{ required: true, message: "请输入用户工号", trigger: "blur" },
|
||||||
errorMsg.value = '';
|
{ min: 3, max: 20, message: "长度在 3 到 20 个字符", trigger: "blur" }
|
||||||
}
|
],
|
||||||
}
|
phone: [{ required: true, message: "请输入联系电话", trigger: "blur" },
|
||||||
);
|
{ min: 6, max: 20, message: "长度在 6 到 20 个字符", trigger: "blur" }
|
||||||
const isSubmitDisabled = computed(() => {
|
]
|
||||||
// 系统通知(1):无需其他字段,直接可提交
|
})
|
||||||
if (uploadTp.value === 1) {
|
const open = () => {
|
||||||
return false;
|
showuploadwarning.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const warningFormRef = ref();
|
||||||
|
|
||||||
|
const warningResetForm = () => {
|
||||||
|
warningForm.value.userId = '';
|
||||||
|
warningForm.value.phone = '';
|
||||||
|
warningForm.value.uploadTp = '1';
|
||||||
|
warningFormRef.value.resetFields();
|
||||||
|
showuploadwarning.value = false;
|
||||||
|
};
|
||||||
|
// 处理危急值登记
|
||||||
|
const handleWarningSuccess = async () => {
|
||||||
|
if (warningForm.value.uploadTp == '2') {
|
||||||
|
const valid = await warningFormRef.value.validate().catch(() => { });
|
||||||
|
if (!valid) return false;
|
||||||
}
|
}
|
||||||
// 电话通知(2):需填写通知人和电话
|
reglimit({ ...tableKey.value, qrr: warningForm.value.userId, tzfs: warningForm.value.uploadTp, phone: warningForm.value.phone }).then((response: any) => {
|
||||||
return !userId.value || !phone.value;
|
showuploadwarning.value = false;
|
||||||
|
if (response.code == 0) {
|
||||||
|
emits('onupload');
|
||||||
|
}
|
||||||
|
if (response.code == 4) {
|
||||||
|
ElMessageBox.confirm(response.msg, '系统提示', { confirmButtonText: '是', cancelButtonText: '否', type: 'warning' }).then(() => {
|
||||||
|
tableKey.value.problemId = tableKey.value.problemId + 1;
|
||||||
|
handleWarningSuccess();
|
||||||
|
}).catch(() => {
|
||||||
|
emits('onupload');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
open
|
||||||
});
|
});
|
||||||
// 处理确认验证
|
|
||||||
const handleupload = () => {
|
|
||||||
errorMsg.value = ''; // 清空之前的错误提示
|
|
||||||
// 基础验证
|
|
||||||
if(uploadTp.value===2) {
|
|
||||||
if (!userId.value) {
|
|
||||||
errorMsg.value = '请输入用户工号';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(props.showRules===3) {
|
|
||||||
if (!phone.value) {
|
|
||||||
errorMsg.value = '请输入电话';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 验证通过,返回用户工号
|
|
||||||
emit('onupload', {
|
|
||||||
userId: userId.value,
|
|
||||||
phone: phone.value,
|
|
||||||
uploadTp:uploadTp.value
|
|
||||||
});
|
|
||||||
|
|
||||||
// 关闭弹窗
|
|
||||||
emit('update:visible', false);
|
|
||||||
};
|
|
||||||
|
|
||||||
// 处理取消
|
|
||||||
const handleCancel = () => {
|
|
||||||
emit('onCancel');
|
|
||||||
emit('update:visible', false);
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
@ -329,10 +263,14 @@ const handleCancel = () => {
|
|||||||
background-color: #4096ff;
|
background-color: #4096ff;
|
||||||
border-color: #4096ff;
|
border-color: #4096ff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.red-static-text {
|
.red-static-text {
|
||||||
color: red; /* 字体颜色设为红色 */
|
color: red;
|
||||||
white-space: pre-wrap; /* 保留空格和换行(可选,配合 pre 标签或手动换行时使用) */
|
/* 字体颜色设为红色 */
|
||||||
line-height: 1.6; /* 行高,增强多行可读性 */
|
white-space: pre-wrap;
|
||||||
|
/* 保留空格和换行(可选,配合 pre 标签或手动换行时使用) */
|
||||||
|
line-height: 1.6;
|
||||||
|
/* 行高,增强多行可读性 */
|
||||||
/* 可选:添加其他样式 */
|
/* 可选:添加其他样式 */
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
margin: 10px 0;
|
margin: 10px 0;
|
||||||
|
|||||||
@ -7,9 +7,21 @@
|
|||||||
class="compact-form">
|
class="compact-form">
|
||||||
<el-row :gutter="5">
|
<el-row :gutter="5">
|
||||||
<el-col :span="6">
|
<el-col :span="6">
|
||||||
<el-form-item label="样本号:" prop="ybh">
|
<el-form-item label="" prop="ybh">
|
||||||
<el-input v-model="queryParams.ybh" placeholder="样本编号" @keyup.enter="handleQuery"
|
<div class="next_box">
|
||||||
style="width:100%" />
|
<div class="jtIcon" @click="handlePrev">
|
||||||
|
<el-icon>
|
||||||
|
<ArrowUpBold />
|
||||||
|
</el-icon>
|
||||||
|
</div>
|
||||||
|
<el-input v-model="queryParams.ybh" placeholder="样本编号" @keyup.enter="handleQuery"
|
||||||
|
style="width:100%" />
|
||||||
|
<div class="jtIcon" @click="handleNext">
|
||||||
|
<el-icon>
|
||||||
|
<ArrowDownBold />
|
||||||
|
</el-icon>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="6">
|
<el-col :span="6">
|
||||||
@ -52,8 +64,9 @@
|
|||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="16">
|
<el-col :span="16">
|
||||||
<LabResult ref="labResultRef" :labPat="labPat" :tableData="labResuts" :tableKey="queryParams"
|
<LabResult ref="labResultRef" :labPat="labPat" :tableData="labResuts" :tableKey="queryParams"
|
||||||
:userList="userList" :resultSysList="resultConfig" @fetchLabResults="resultsHandle" :dictData="dictData"
|
@update:tableKey="queryParams = $event" :userList="userList" :resultSysList="resultConfig"
|
||||||
@changeStatus="changeStatus" @previewHandle="previewHandle" />
|
@fetchLabResults="resultsHandle" :dictData="dictData" @changeStatus="changeStatus"
|
||||||
|
@previewHandle="previewHandle" />
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</div>
|
</div>
|
||||||
@ -151,6 +164,7 @@ const queryParams = ref({
|
|||||||
instrGroup: '02',
|
instrGroup: '02',
|
||||||
problemId: 0,
|
problemId: 0,
|
||||||
days: 0,
|
days: 0,
|
||||||
|
yhdh: ''
|
||||||
})
|
})
|
||||||
const ybs = ref(0)
|
const ybs = ref(0)
|
||||||
const ws = ref(0)
|
const ws = ref(0)
|
||||||
@ -466,7 +480,9 @@ const handlePrev = () => {
|
|||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
highlightRowIndex.value = index;
|
highlightRowIndex.value = index;
|
||||||
const row = labPatList.value[index];
|
const row = labPatList.value[index];
|
||||||
labPatListRef.value.setCurrentRow(row);
|
if (activeTab.value == 'LabPatList') {
|
||||||
|
labPatListRef.value.setCurrentRow(row);
|
||||||
|
}
|
||||||
selectJob(row);
|
selectJob(row);
|
||||||
} else {
|
} else {
|
||||||
handleCreate();
|
handleCreate();
|
||||||
@ -475,7 +491,9 @@ const handlePrev = () => {
|
|||||||
if (highlightRowIndex.value > 0) {
|
if (highlightRowIndex.value > 0) {
|
||||||
highlightRowIndex.value--;
|
highlightRowIndex.value--;
|
||||||
const row = labPatList.value[highlightRowIndex.value];
|
const row = labPatList.value[highlightRowIndex.value];
|
||||||
labPatListRef.value.setCurrentRow(row);
|
if (activeTab.value == 'LabPatList') {
|
||||||
|
labPatListRef.value.setCurrentRow(row);
|
||||||
|
}
|
||||||
selectJob(row);
|
selectJob(row);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -491,7 +509,9 @@ const handleNext = () => {
|
|||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
highlightRowIndex.value = index;
|
highlightRowIndex.value = index;
|
||||||
const row = labPatList.value[index];
|
const row = labPatList.value[index];
|
||||||
labPatListRef.value.setCurrentRow(row);
|
if (activeTab.value == 'LabPatList') {
|
||||||
|
labPatListRef.value.setCurrentRow(row);
|
||||||
|
}
|
||||||
selectJob(row);
|
selectJob(row);
|
||||||
} else {
|
} else {
|
||||||
handleCreate();
|
handleCreate();
|
||||||
@ -500,7 +520,9 @@ const handleNext = () => {
|
|||||||
if (highlightRowIndex.value < labPatList.value.length - 1) {
|
if (highlightRowIndex.value < labPatList.value.length - 1) {
|
||||||
highlightRowIndex.value++;
|
highlightRowIndex.value++;
|
||||||
const row = labPatList.value[highlightRowIndex.value];
|
const row = labPatList.value[highlightRowIndex.value];
|
||||||
labPatListRef.value.setCurrentRow(row);
|
if (activeTab.value == 'LabPatList') {
|
||||||
|
labPatListRef.value.setCurrentRow(row);
|
||||||
|
}
|
||||||
selectJob(row);
|
selectJob(row);
|
||||||
} else {
|
} else {
|
||||||
queryParams.value.ybh = getNextNumber(queryParams.value.ybh) as string;
|
queryParams.value.ybh = getNextNumber(queryParams.value.ybh) as string;
|
||||||
@ -651,8 +673,7 @@ onMounted(async () => {
|
|||||||
|
|
||||||
const initSocket = () => {
|
const initSocket = () => {
|
||||||
initWebSocket({
|
initWebSocket({
|
||||||
// fullUrl: `ws://47.97.125.165:8904/ws/instr/${mbStore.fingerprint}`,
|
fullUrl: `ws://47.97.125.165:8904/ws/instr/${mbStore.fingerprint}`,
|
||||||
fullUrl: `ws://192.168.1.151:9801/ws/instr/${mbStore.fingerprint}`,
|
|
||||||
onOpen: () => {
|
onOpen: () => {
|
||||||
console.log('WebSocket连接成功');
|
console.log('WebSocket连接成功');
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,103 +1,173 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="login">
|
<div class="login">
|
||||||
<el-form ref="loginRef" :model="loginForm" :rules="loginRules" class="login-form">
|
<el-form ref="loginRef" class="login-form">
|
||||||
<h3 class="title">实验室管理系统</h3>
|
<div class="login-header">
|
||||||
<el-form-item prop="username">
|
<div class="login-logo">
|
||||||
<el-input v-model="loginForm.username" type="text" size="large" auto-complete="off" placeholder="账号">
|
<img src="@/assets/images/logo_new.png" alt="系统Logo" />
|
||||||
<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">
|
|
||||||
<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-input
|
|
||||||
v-model="loginForm.code"
|
|
||||||
size="large"
|
|
||||||
auto-complete="off"
|
|
||||||
placeholder="验证码"
|
|
||||||
style="width: 63%"
|
|
||||||
@keyup.enter="handleLogin"
|
|
||||||
>
|
|
||||||
<template #prefix><svg-icon icon-class="validCode" class="el-input__icon input-icon" /></template>
|
|
||||||
</el-input>
|
|
||||||
<div class="login-code">
|
|
||||||
<img :src="codeUrl" @click="getCode" class="login-code-img"/>
|
|
||||||
</div>
|
</div>
|
||||||
</el-form-item> -->
|
<div class="login-split"></div>
|
||||||
<el-checkbox v-model="loginForm.rememberMe" style="margin:0px 0px 25px 0px;">记住密码</el-checkbox>
|
<div class="login-title">
|
||||||
<el-form-item style="width:100%;">
|
<h1>{{ oem.appname}}</h1>
|
||||||
<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>
|
|
||||||
<div style="float: right;" v-if="register">
|
|
||||||
<router-link class="link-type" :to="'/register'">立即注册</router-link>
|
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</div>
|
||||||
|
|
||||||
|
<!-- Tab切换容器 -->
|
||||||
|
<el-tabs v-model="activeName" type="card" @tab-click="handleClick" class="login-tabs">
|
||||||
|
<!-- 工号登录 Tab -->
|
||||||
|
<el-tab-pane label="账号密码登录" name="first">
|
||||||
|
<el-form-item label="医疗机构:" prop="loginYLJG"class="custom-select">
|
||||||
|
<el-select
|
||||||
|
v-model="loginForm.loginParam.loginYLJG"
|
||||||
|
placeholder="请选择医疗机构"
|
||||||
|
style="width: 100%"
|
||||||
|
>
|
||||||
|
<template #prefix>
|
||||||
|
<svg-icon icon-class="international" class="el-input__icon input-icon" />
|
||||||
|
</template>
|
||||||
|
<el-option
|
||||||
|
v-for="item in selectOptions"
|
||||||
|
:key="item.id"
|
||||||
|
:label="item.name"
|
||||||
|
:value="item.id"
|
||||||
|
></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="用户代号:" prop="username">
|
||||||
|
<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 label="登录密码:" prop="password">
|
||||||
|
<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,验证码关闭时不渲染任何内容 -->
|
||||||
|
<el-form-item prop="code" v-if="!captchaEnabled" size="large">
|
||||||
|
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item prop="code" label="验 证 码 :" v-if="captchaEnabled">
|
||||||
|
<el-input
|
||||||
|
|
||||||
|
v-model="loginForm.code"
|
||||||
|
size="large"
|
||||||
|
auto-complete="off"
|
||||||
|
placeholder="验证码"
|
||||||
|
style="width: 53%"
|
||||||
|
@keyup.enter="handleLogin"
|
||||||
|
>
|
||||||
|
<template #prefix>
|
||||||
|
<svg-icon icon-class="validCode" class="el-input__icon input-icon" />
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
<div class="login-code">
|
||||||
|
<img :src="codeUrl" @click="getCode" class="login-code-img" />
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item style="width: 100%;">
|
||||||
|
<el-button :loading="loading" size="large" type="primary" class="login-btn" style="width: 100%;" @click.prevent="handleLogin">
|
||||||
|
<span v-if="!loading">登 录</span>
|
||||||
|
<span v-else>登 录 中...</span>
|
||||||
|
</el-button>
|
||||||
|
<div style="float: right;" v-if="register">
|
||||||
|
<router-link class="link-type" :to="'/register'">立即注册</router-link>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
</el-tab-pane>
|
||||||
|
|
||||||
|
<el-tab-pane label="扫码登录" name="second">
|
||||||
|
<div class="tab-placeholder">
|
||||||
|
<el-icon class="placeholder-icon"><Sms /></el-icon>
|
||||||
|
<p>正在加载二维码...</p>
|
||||||
|
<el-button type="success" icon="wechat" class="wechat-login-btn">刷新二维码</el-button>
|
||||||
|
</div>
|
||||||
|
</el-tab-pane>
|
||||||
|
|
||||||
|
<el-tab-pane label="UKEY登录" name="third">
|
||||||
|
<div class="tab-placeholder">
|
||||||
|
<el-icon class="placeholder-icon"><Wechat /></el-icon>
|
||||||
|
<p>UKEY登录功能开发中...</p>
|
||||||
|
</div>
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
</el-form>
|
</el-form>
|
||||||
<!-- 底部 -->
|
|
||||||
<div class="el-login-footer">
|
<div class="el-login-footer">
|
||||||
<!-- <span>Copyright © 2018-2023 ruoyi.vip All Rights Reserved.</span> -->
|
<span>版权所有(R)2022-2026 {{ oem.compay}} 电话:{{oem.phone}} E-mail:{{oem.Email}} version:{{oem.version}}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { getCodeImg } from "@/api/login";
|
import { ref, watch, getCurrentInstance, onMounted } from 'vue';
|
||||||
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
|
import { useFingerprint } from '@/utils/useFingerprint';
|
||||||
|
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';
|
||||||
|
|
||||||
const userStore = useUserStore()
|
// 初始化响应式变量
|
||||||
|
const activeName = ref('first');
|
||||||
|
const userStore = useUserStore();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { proxy } = getCurrentInstance();
|
const oem = ref({
|
||||||
|
appname: "实验室信息管理系统",
|
||||||
|
phone: "",
|
||||||
|
compay: "",
|
||||||
|
version: "",
|
||||||
|
Email: ""
|
||||||
|
});
|
||||||
|
const loginRef = ref(null); // 修复:直接用ref获取表单引用
|
||||||
const loginForm = ref({
|
const loginForm = ref({
|
||||||
username: "admin",
|
username: "admin",
|
||||||
password: "", //admin123
|
password: "",
|
||||||
rememberMe: false,
|
rememberMe: false,
|
||||||
code: "",
|
code: "",
|
||||||
uuid: ""
|
uuid: "",
|
||||||
|
loginParam:{loginYLJG:"",localid:""}
|
||||||
});
|
});
|
||||||
|
const selectOptions = ref([{ id: '1', name: '总院' }]);
|
||||||
const loginRules = {
|
const loginRules = ref({ // 修复:改为ref响应式,方便动态修改
|
||||||
username: [{ required: true, trigger: "blur", message: "请输入您的账号" }],
|
username: [{ required: true, trigger: "blur", message: "请输入您的账号" }],
|
||||||
password: [{ required: true, trigger: "blur", message: "请输入您的密码" }],
|
// password: [{ required: true, trigger: "blur", message: "请输入您的密码" }],
|
||||||
|
hospid: [{ required: true, message: '请选择医疗机构', trigger: 'change' }],
|
||||||
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(true);
|
||||||
// 注册开关
|
|
||||||
const register = ref(false);
|
const register = ref(false);
|
||||||
const redirect = ref(undefined);
|
const redirect = ref(undefined);
|
||||||
|
|
||||||
watch(route, (newRoute) => {
|
// 路由监听(优化版)
|
||||||
redirect.value = newRoute.query && newRoute.query.redirect;
|
watch(
|
||||||
}, { immediate: true });
|
() => route.query.redirect,
|
||||||
|
(newRedirect) => {
|
||||||
function handleLogin() {
|
if (redirect.value !== newRedirect) {
|
||||||
proxy.$refs.loginRef.validate(valid => {
|
redirect.value = newRedirect || '';
|
||||||
if (valid) {
|
|
||||||
loading.value = true;
|
|
||||||
// 勾选了需要记住密码设置在 cookie 中设置记住用户名和密码
|
|
||||||
if (loginForm.value.rememberMe) {
|
|
||||||
Cookies.set("username", loginForm.value.username, { expires: 30 });
|
|
||||||
Cookies.set("password", encrypt(loginForm.value.password), { expires: 30 });
|
|
||||||
Cookies.set("rememberMe", loginForm.value.rememberMe, { expires: 30 });
|
|
||||||
} else {
|
|
||||||
// 否则移除
|
|
||||||
Cookies.remove("username");
|
|
||||||
Cookies.remove("password");
|
|
||||||
Cookies.remove("rememberMe");
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{ immediate: true, deep: false }
|
||||||
|
);
|
||||||
|
|
||||||
|
// 登录方法(修复proxy.$refs问题)
|
||||||
|
const handleLogin = async () => {
|
||||||
|
loginForm.value.loginParam.loginYLJG
|
||||||
|
loading.value = true;
|
||||||
|
Cookies.set("czlis_username", loginForm.value.username, { expires: 30 });
|
||||||
|
Cookies.set("czlis_loginYLJG", loginForm.value.loginParam.loginYLJG, {expires: 30});
|
||||||
// 调用action的登录方法
|
// 调用action的登录方法
|
||||||
userStore.login(loginForm.value).then(() => {
|
userStore.login(loginForm.value).then(() => {
|
||||||
const query = route.query;
|
const query = route.query;
|
||||||
@ -107,7 +177,10 @@ function handleLogin() {
|
|||||||
}
|
}
|
||||||
return acc;
|
return acc;
|
||||||
}, {});
|
}, {});
|
||||||
router.push({ path: redirect.value || "/", query: otherQueryParams });
|
const targetPath = redirect.value || "/";
|
||||||
|
if (route.path !== targetPath) {
|
||||||
|
router.push({ path: targetPath, query: otherQueryParams });
|
||||||
|
}
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
// 重新获取验证码
|
// 重新获取验证码
|
||||||
@ -115,33 +188,90 @@ function handleLogin() {
|
|||||||
getCode();
|
getCode();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function getCode() {
|
// 获取验证码
|
||||||
|
const getCode = () => {
|
||||||
getCodeImg().then(res => {
|
getCodeImg().then(res => {
|
||||||
captchaEnabled.value = res.captchaEnabled === undefined ? true : res.captchaEnabled;
|
captchaEnabled.value = res.captchaEnabled ?? true;
|
||||||
if (captchaEnabled.value) {
|
if (captchaEnabled.value) {
|
||||||
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: "请输入验证码"}];
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
function getCookie() {
|
// 从Cookie获取账号密码
|
||||||
const username = Cookies.get("username");
|
const getCookie = () => {
|
||||||
const password = Cookies.get("password");
|
const cookieUsername = Cookies.get("czlis_username");
|
||||||
const rememberMe = Cookies.get("rememberMe");
|
const cookieloginYLJG = Cookies.get("czlis_loginYLJG");
|
||||||
loginForm.value = {
|
//console.log('cookieloginYLJG', cookieloginYLJG);
|
||||||
username: username === undefined ? loginForm.value.username : username,
|
if (cookieUsername !== undefined && cookieUsername !== null&& cookieUsername !=="") {
|
||||||
password: password === undefined ? loginForm.value.password : decrypt(password),
|
loginForm.value.username = cookieUsername;
|
||||||
rememberMe: rememberMe === undefined ? false : Boolean(rememberMe)
|
}
|
||||||
};
|
if (cookieloginYLJG !== undefined && cookieloginYLJG !== null&& cookieloginYLJG !=="") {
|
||||||
}
|
loginForm.value.loginParam.loginYLJG = cookieloginYLJG;
|
||||||
|
}
|
||||||
|
//console.log('loginForm', loginForm);
|
||||||
|
};
|
||||||
|
|
||||||
getCode();
|
// 获取本地配置
|
||||||
getCookie();
|
const Localconfig = (localid) => {
|
||||||
|
getLocalconfig({localid}).then(res => {
|
||||||
|
if (res) {
|
||||||
|
const {localconfig, hosplist, oem: oemData} = res;
|
||||||
|
// 修复:赋值oem数据,显示动态标题
|
||||||
|
if (oemData) oem.value = oemData;
|
||||||
|
// console.log('oemData', oemData);
|
||||||
|
// console.log('oem', oem.value);
|
||||||
|
// 修复:判重后更新下拉选项,避免递归
|
||||||
|
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 => {
|
||||||
|
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手动赋值,避免递归)
|
||||||
|
const handleClick = (tab) => {
|
||||||
|
console.log('当前Tab:', tab.name);
|
||||||
|
// 仅在切回账号密码登录时刷新验证码
|
||||||
|
if (tab.name === 'first' && captchaEnabled.value) {
|
||||||
|
getCode();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 页面挂载时初始化
|
||||||
|
onMounted(() => {
|
||||||
|
refreshFingerprint();
|
||||||
|
getCode();
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang='scss' scoped>
|
<style lang='scss' scoped>
|
||||||
@ -149,22 +279,20 @@ getCookie();
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
height: 100%;
|
height: 100vh;
|
||||||
background-image: url("../assets/images/login-background.jpg");
|
background-image: url("../assets/images/login-background.jpg");
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
}
|
}
|
||||||
|
|
||||||
.title {
|
|
||||||
margin: 0px auto 30px auto;
|
|
||||||
text-align: center;
|
|
||||||
color: #707070;
|
|
||||||
}
|
|
||||||
|
|
||||||
.login-form {
|
.login-form {
|
||||||
border-radius: 6px;
|
background: rgba(255, 255, 255, 0.4);
|
||||||
background: #ffffff;
|
backdrop-filter: blur(10px);
|
||||||
width: 400px;
|
-webkit-backdrop-filter: blur(10px);
|
||||||
padding: 25px 25px 5px 25px;
|
border: 1px solid rgba(255, 255, 255, 0.9);
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
|
||||||
|
width: 480px;
|
||||||
|
padding: 35px 35px 5px 35px;
|
||||||
|
|
||||||
.el-input {
|
.el-input {
|
||||||
height: 40px;
|
height: 40px;
|
||||||
@ -181,12 +309,6 @@ getCookie();
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.login-tip {
|
|
||||||
font-size: 13px;
|
|
||||||
text-align: center;
|
|
||||||
color: #bfbfbf;
|
|
||||||
}
|
|
||||||
|
|
||||||
.login-code {
|
.login-code {
|
||||||
width: 33%;
|
width: 33%;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
@ -195,6 +317,9 @@ getCookie();
|
|||||||
img {
|
img {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
object-fit: cover;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,8 +336,87 @@ getCookie();
|
|||||||
letter-spacing: 1px;
|
letter-spacing: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.login-code-img {
|
/* Logo和标题样式 */
|
||||||
height: 40px;
|
.login-header {
|
||||||
padding-left: 12px;
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 30px;
|
||||||
}
|
}
|
||||||
</style>
|
|
||||||
|
.login-logo img {
|
||||||
|
height: 40px;
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-split {
|
||||||
|
width: 1px;
|
||||||
|
height: 30px;
|
||||||
|
background-color: #ccc;
|
||||||
|
margin: 0 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-title h1 {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 24px;
|
||||||
|
color: #1989fa;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tab容器样式(修复冲突) */
|
||||||
|
.login-tabs {
|
||||||
|
width: 100%;
|
||||||
|
height: 350px;
|
||||||
|
overflow: hidden;
|
||||||
|
border-radius: 8px;
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
-webkit-backdrop-filter: blur(10px);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||||
|
padding: 1px 10px 10px;
|
||||||
|
background: transparent;
|
||||||
|
|
||||||
|
:deep(.el-tabs__header) {
|
||||||
|
background: transparent;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-tabs__nav-prev),
|
||||||
|
:deep(.el-tabs__nav-next) {
|
||||||
|
display: none !important; // 隐藏Tab左右箭头
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-tabs__nav-wrap) {
|
||||||
|
overflow: visible !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-select {
|
||||||
|
margin-top: 20px; /* 可根据需求调整数值 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tab占位样式 */
|
||||||
|
.tab-placeholder {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 40px 0;
|
||||||
|
color: #666;
|
||||||
|
height: calc(100% - 40px); // 适配Tab容器高度
|
||||||
|
|
||||||
|
.placeholder-icon {
|
||||||
|
font-size: 48px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
color: #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wechat-login-btn {
|
||||||
|
margin-top: 20px;
|
||||||
|
width: 200px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 隐藏必填项星号 */
|
||||||
|
:deep(.el-form-item.is-required:not(.is-no-asterisk) .el-form-item__label-wrap .el-form-item__asterisk) {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
448
src/views/logincopy.vue
Normal file
448
src/views/logincopy.vue
Normal file
@ -0,0 +1,448 @@
|
|||||||
|
<template>
|
||||||
|
<div class="login">
|
||||||
|
<el-form ref="loginRef" class="login-form">
|
||||||
|
<div class="login-header">
|
||||||
|
<div class="login-logo">
|
||||||
|
<img src="@/assets/images/logo_new.png" alt="系统Logo" />
|
||||||
|
</div>
|
||||||
|
<div class="login-split"></div>
|
||||||
|
<div class="login-title">
|
||||||
|
<h1>{{ oem.appname}}</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Tab切换容器 -->
|
||||||
|
<el-tabs v-model="activeName" type="card" @tab-click="handleClick" class="login-tabs">
|
||||||
|
<!-- 工号登录 Tab -->
|
||||||
|
<el-tab-pane label="账号密码登录" name="first">
|
||||||
|
<el-form-item label="医疗机构:" prop="hospid"class="custom-select">
|
||||||
|
<el-select
|
||||||
|
v-model="loginForm.hospid"
|
||||||
|
placeholder="请选择医疗机构"
|
||||||
|
style="width: 100%"
|
||||||
|
>
|
||||||
|
<template #prefix>
|
||||||
|
<svg-icon icon-class="international" class="el-input__icon input-icon" />
|
||||||
|
</template>
|
||||||
|
<el-option
|
||||||
|
v-for="item in selectOptions"
|
||||||
|
:key="item.id"
|
||||||
|
:label="item.name"
|
||||||
|
:value="item.id"
|
||||||
|
></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="用户代号:" prop="username">
|
||||||
|
<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 label="登录密码:" prop="password">
|
||||||
|
<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,验证码关闭时不渲染任何内容 -->
|
||||||
|
<el-form-item prop="code" v-if="!captchaEnabled" size="large">
|
||||||
|
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item prop="code" label="验 证 码 :" v-if="captchaEnabled">
|
||||||
|
<el-input
|
||||||
|
|
||||||
|
v-model="loginForm.code"
|
||||||
|
size="large"
|
||||||
|
auto-complete="off"
|
||||||
|
placeholder="验证码"
|
||||||
|
style="width: 53%"
|
||||||
|
@keyup.enter="handleLogin"
|
||||||
|
>
|
||||||
|
<template #prefix>
|
||||||
|
<svg-icon icon-class="validCode" class="el-input__icon input-icon" />
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
<div class="login-code">
|
||||||
|
<img :src="codeUrl" @click="getCode" class="login-code-img" />
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item style="width: 100%;">
|
||||||
|
<el-button :loading="loading" size="large" type="primary" class="login-btn" style="width: 100%;" @click.prevent="handleLogin">
|
||||||
|
<span v-if="!loading">登 录</span>
|
||||||
|
<span v-else>登 录 中...</span>
|
||||||
|
</el-button>
|
||||||
|
<div style="float: right;" v-if="register">
|
||||||
|
<router-link class="link-type" :to="'/register'">立即注册</router-link>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
</el-tab-pane>
|
||||||
|
|
||||||
|
<el-tab-pane label="扫码登录" name="second">
|
||||||
|
<div class="tab-placeholder">
|
||||||
|
<el-icon class="placeholder-icon"><Sms /></el-icon>
|
||||||
|
<p>正在加载二维码...</p>
|
||||||
|
<el-button type="success" icon="wechat" class="wechat-login-btn">刷新二维码</el-button>
|
||||||
|
</div>
|
||||||
|
</el-tab-pane>
|
||||||
|
|
||||||
|
<el-tab-pane label="UKEY登录" name="third">
|
||||||
|
<div class="tab-placeholder">
|
||||||
|
<el-icon class="placeholder-icon"><Wechat /></el-icon>
|
||||||
|
<p>UKEY登录功能开发中...</p>
|
||||||
|
</div>
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<div class="el-login-footer">
|
||||||
|
<span>版权所有(R)2022-2026 {{ oem.compay}} 电话:{{oem.phone}} E-mail:{{oem.Email}} version:{{oem.version}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, watch, getCurrentInstance, onMounted } from 'vue';
|
||||||
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
|
import { useFingerprint } from '@/utils/useFingerprint';
|
||||||
|
import { getCodeImg, getInfo, getLocalconfig } from "@/api/login";
|
||||||
|
import Cookies from "js-cookie";
|
||||||
|
import { encrypt, decrypt } from "@/utils/jsencrypt";
|
||||||
|
import useUserStore from '@/store/modules/user';
|
||||||
|
|
||||||
|
// 初始化响应式变量
|
||||||
|
const activeName = ref('first');
|
||||||
|
const userStore = useUserStore();
|
||||||
|
const route = useRoute();
|
||||||
|
const router = useRouter();
|
||||||
|
const oem = ref({
|
||||||
|
appname: "实验室信息管理系统",
|
||||||
|
phone: "",
|
||||||
|
compay: "",
|
||||||
|
version: "",
|
||||||
|
Email: ""
|
||||||
|
});
|
||||||
|
const loginRef = ref(null); // 修复:直接用ref获取表单引用
|
||||||
|
const loginForm = ref({
|
||||||
|
username: "admin",
|
||||||
|
password: "",
|
||||||
|
rememberMe: false,
|
||||||
|
code: "",
|
||||||
|
uuid: "",
|
||||||
|
hospid: "1"
|
||||||
|
});
|
||||||
|
const selectOptions = ref([{ id: '1', name: '总院' }]);
|
||||||
|
const loginRules = ref({ // 修复:改为ref响应式,方便动态修改
|
||||||
|
username: [{ required: true, trigger: "blur", message: "请输入您的账号" }],
|
||||||
|
password: [{ required: true, trigger: "blur", message: "请输入您的密码" }],
|
||||||
|
hospid: [{ required: true, message: '请选择医疗机构', trigger: 'change' }],
|
||||||
|
code: [{ required: true, trigger: "change", message: "请输入验证码" }]
|
||||||
|
});
|
||||||
|
const codeUrl = ref("");
|
||||||
|
const loading = ref(false);
|
||||||
|
const captchaEnabled = ref(true);
|
||||||
|
const register = ref(false);
|
||||||
|
const redirect = ref(undefined);
|
||||||
|
|
||||||
|
// 路由监听(优化版)
|
||||||
|
watch(
|
||||||
|
() => route.query.redirect,
|
||||||
|
(newRedirect) => {
|
||||||
|
if (redirect.value !== newRedirect) {
|
||||||
|
redirect.value = newRedirect || '';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ immediate: true, deep: false }
|
||||||
|
);
|
||||||
|
|
||||||
|
// 登录方法(修复proxy.$refs问题)
|
||||||
|
const handleLogin = async () => {
|
||||||
|
console.log("sss",loginForm.value)
|
||||||
|
try {
|
||||||
|
const valid = await loginRef.value.validate(); // 直接用ref.validate()
|
||||||
|
if (valid) {
|
||||||
|
loading.value = true;
|
||||||
|
// 记住密码逻辑
|
||||||
|
if (loginForm.value.rememberMe) {
|
||||||
|
Cookies.set("username", loginForm.value.username, { expires: 30 });
|
||||||
|
Cookies.set("password", encrypt(loginForm.value.password), { expires: 30 });
|
||||||
|
Cookies.set("rememberMe", loginForm.value.rememberMe, { expires: 30 });
|
||||||
|
} else {
|
||||||
|
Cookies.remove("username");
|
||||||
|
Cookies.remove("password");
|
||||||
|
Cookies.remove("rememberMe");
|
||||||
|
}
|
||||||
|
// 调用action的登录方法
|
||||||
|
userStore.login(loginForm.value).then(() => {
|
||||||
|
const query = route.query;
|
||||||
|
const otherQueryParams = Object.keys(query).reduce((acc, cur) => {
|
||||||
|
if (cur !== "redirect") {
|
||||||
|
acc[cur] = query[cur];
|
||||||
|
}
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
if (route.path !== targetPath) {
|
||||||
|
router.push({path: redirect.value || "/", query: otherQueryParams});
|
||||||
|
}
|
||||||
|
}).catch(() => {
|
||||||
|
loading.value = false;
|
||||||
|
// 重新获取验证码
|
||||||
|
if (captchaEnabled.value) {
|
||||||
|
getCode();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
/*
|
||||||
|
// 调用登录接口
|
||||||
|
await userStore.login(loginForm.value);
|
||||||
|
// 路由跳转(防重复跳转)
|
||||||
|
const query = route.query;
|
||||||
|
const otherQueryParams = Object.keys(query).reduce((acc, cur) => {
|
||||||
|
if (cur !== "redirect") acc[cur] = query[cur];
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
const targetPath = redirect.value || "/";
|
||||||
|
if (route.path !== targetPath) {
|
||||||
|
router.push({ path: targetPath, query: otherQueryParams });
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error("登录验证失败:", err);
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
if (captchaEnabled.value) getCode(); // 失败后刷新验证码
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取验证码
|
||||||
|
const getCode = () => {
|
||||||
|
getCodeImg().then(res => {
|
||||||
|
captchaEnabled.value = res.captchaEnabled ?? true;
|
||||||
|
if (captchaEnabled.value) {
|
||||||
|
codeUrl.value = "data:image/gif;base64," + res.img;
|
||||||
|
loginForm.value.uuid = res.uuid;
|
||||||
|
}
|
||||||
|
// 验证码关闭时移除校验规则,避免报错
|
||||||
|
if (!captchaEnabled.value) {
|
||||||
|
loginRules.value.code = [];
|
||||||
|
} else {
|
||||||
|
loginRules.value.code = [{ required: true, trigger: "change", message: "请输入验证码" }];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 从Cookie获取账号密码
|
||||||
|
const getCookie = () => {
|
||||||
|
const username = Cookies.get("username");
|
||||||
|
const password = Cookies.get("password");
|
||||||
|
const rememberMe = Cookies.get("rememberMe");
|
||||||
|
loginForm.value = {
|
||||||
|
...loginForm.value,
|
||||||
|
username: username ?? loginForm.value.username,
|
||||||
|
password: password ? decrypt(password) : loginForm.value.password,
|
||||||
|
rememberMe: rememberMe ? Boolean(rememberMe) : false
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取本地配置
|
||||||
|
const Localconfig = (localid) => {
|
||||||
|
getLocalconfig({ localid }).then(res => {
|
||||||
|
if (res) {
|
||||||
|
const { localconfig, hosplist, oem: oemData } = res;
|
||||||
|
console.log('本地配置:', localconfig, '医院列表:', hosplist);
|
||||||
|
// 修复:赋值oem数据,显示动态标题
|
||||||
|
if (oemData) oem.value = oemData;
|
||||||
|
// 修复:判重后更新下拉选项,避免递归
|
||||||
|
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.hospid = selectOptions.value[0]?.id || '1';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).catch(err => {
|
||||||
|
console.error("获取本地配置失败:", err);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取指纹并加载配置
|
||||||
|
const { getFingerprint } = useFingerprint();
|
||||||
|
const refreshFingerprint = async () => {
|
||||||
|
try {
|
||||||
|
const res = await getFingerprint();
|
||||||
|
Localconfig(res.visitorId);
|
||||||
|
} catch (err) {
|
||||||
|
console.error("获取指纹失败:", err);
|
||||||
|
Localconfig("default"); // 兜底使用默认ID
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Tab切换事件(移除activeName手动赋值,避免递归)
|
||||||
|
const handleClick = (tab) => {
|
||||||
|
console.log('当前Tab:', tab.name);
|
||||||
|
// 仅在切回账号密码登录时刷新验证码
|
||||||
|
if (tab.name === 'first' && captchaEnabled.value) {
|
||||||
|
getCode();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 页面挂载时初始化
|
||||||
|
onMounted(() => {
|
||||||
|
refreshFingerprint();
|
||||||
|
getCode();
|
||||||
|
getCookie();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang='scss' scoped>
|
||||||
|
.login {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 100vh;
|
||||||
|
background-image: url("../assets/images/login-background.jpg");
|
||||||
|
background-size: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-form {
|
||||||
|
background: rgba(255, 255, 255, 0.4);
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
-webkit-backdrop-filter: blur(10px);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.9);
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
|
||||||
|
width: 480px;
|
||||||
|
padding: 35px 35px 5px 35px;
|
||||||
|
|
||||||
|
.el-input {
|
||||||
|
height: 40px;
|
||||||
|
|
||||||
|
input {
|
||||||
|
height: 40px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-icon {
|
||||||
|
height: 39px;
|
||||||
|
width: 14px;
|
||||||
|
margin-left: 0px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-code {
|
||||||
|
width: 33%;
|
||||||
|
height: 40px;
|
||||||
|
float: right;
|
||||||
|
|
||||||
|
img {
|
||||||
|
cursor: pointer;
|
||||||
|
vertical-align: middle;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-login-footer {
|
||||||
|
height: 40px;
|
||||||
|
line-height: 40px;
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
color: #fff;
|
||||||
|
font-family: Arial;
|
||||||
|
font-size: 12px;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Logo和标题样式 */
|
||||||
|
.login-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-logo img {
|
||||||
|
height: 40px;
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-split {
|
||||||
|
width: 1px;
|
||||||
|
height: 30px;
|
||||||
|
background-color: #ccc;
|
||||||
|
margin: 0 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-title h1 {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 24px;
|
||||||
|
color: #1989fa;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tab容器样式(修复冲突) */
|
||||||
|
.login-tabs {
|
||||||
|
width: 100%;
|
||||||
|
height: 350px;
|
||||||
|
overflow: hidden;
|
||||||
|
border-radius: 8px;
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
-webkit-backdrop-filter: blur(10px);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||||
|
padding: 1px 10px 10px;
|
||||||
|
background: transparent;
|
||||||
|
|
||||||
|
:deep(.el-tabs__header) {
|
||||||
|
background: transparent;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-tabs__nav-prev),
|
||||||
|
:deep(.el-tabs__nav-next) {
|
||||||
|
display: none !important; // 隐藏Tab左右箭头
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-tabs__nav-wrap) {
|
||||||
|
overflow: visible !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.custom-select {
|
||||||
|
margin-top: 20px; /* 可根据需求调整数值 */
|
||||||
|
}
|
||||||
|
/* Tab占位样式 */
|
||||||
|
.tab-placeholder {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 40px 0;
|
||||||
|
color: #666;
|
||||||
|
height: calc(100% - 40px); // 适配Tab容器高度
|
||||||
|
|
||||||
|
.placeholder-icon {
|
||||||
|
font-size: 48px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
color: #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wechat-login-btn {
|
||||||
|
margin-top: 20px;
|
||||||
|
width: 200px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 隐藏必填项星号 */
|
||||||
|
:deep(.el-form-item.is-required:not(.is-no-asterisk) .el-form-item__label-wrap .el-form-item__asterisk) {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Loading…
x
Reference in New Issue
Block a user