检验录入
This commit is contained in:
parent
7e876ce499
commit
dafc6ea37a
@ -13,6 +13,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@element-plus/icons-vue": "2.3.1",
|
||||
"@fingerprintjs/fingerprintjs": "^4.6.2",
|
||||
"@vueup/vue-quill": "1.2.0",
|
||||
"@vueuse/core": "10.6.1",
|
||||
"axios": "0.27.2",
|
||||
@ -37,7 +38,9 @@
|
||||
"vue-router": "4.2.5",
|
||||
"vue3-print-nb": "^0.1.4",
|
||||
"vue3-select2-component": "^0.1.7",
|
||||
"vuedraggable": "^4.1.0"
|
||||
"vuedraggable": "^4.1.0",
|
||||
"vxe-pc-ui": "^4.3.2",
|
||||
"vxe-table": "^4.9.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.27.0",
|
||||
|
||||
@ -51,14 +51,22 @@ export function reportList(query?: Object) {
|
||||
data: query,
|
||||
});
|
||||
}
|
||||
// 查询报告Pdf
|
||||
export function reportPrintPdf(query?: Object) {
|
||||
// 查询报告Pdf预览
|
||||
export function reportViewPdf(query?: Object) {
|
||||
return request({
|
||||
url: '/report/pdf',
|
||||
method: 'get',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
// 查询报告Pdf打印
|
||||
export function reportPrintPdf(query?: Object) {
|
||||
return request({
|
||||
url: '/report/print',
|
||||
method: 'post',
|
||||
data: query,
|
||||
});
|
||||
}
|
||||
// 查询项目报告
|
||||
export function reportResult(query?: Object) {
|
||||
return request({
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
// @ts-ignore
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 查询字典数据列表
|
||||
export function queryComDictListService(query) {
|
||||
export function queryComDictListService(query?: Object) {
|
||||
return request({
|
||||
url: '/comdict/query',
|
||||
method: 'get',
|
||||
@ -9,7 +10,7 @@ export function queryComDictListService(query) {
|
||||
})
|
||||
}
|
||||
//增加字典数据
|
||||
export function addComDictService(data) {
|
||||
export function addComDictService(data?: Object) {
|
||||
return request({
|
||||
url: '/comdict/add',
|
||||
method: 'post',
|
||||
@ -18,7 +19,7 @@ export function addComDictService(data) {
|
||||
}
|
||||
|
||||
//修改字典数据
|
||||
export function updateComDictService(data) {
|
||||
export function updateComDictService(data?: Object) {
|
||||
return request({
|
||||
url: '/comdict/update',
|
||||
method: 'post',
|
||||
@ -27,7 +28,7 @@ export function updateComDictService(data) {
|
||||
|
||||
}
|
||||
//删除字典数据
|
||||
export function delComDictService(data) {
|
||||
export function delComDictService(data?: Object) {
|
||||
return request({
|
||||
url: '/comdict/del',
|
||||
method: 'delete',
|
||||
@ -37,7 +38,7 @@ export function delComDictService(data) {
|
||||
}
|
||||
|
||||
// 根据字典类型查询字典数据信息
|
||||
export function getComDicts(zdlb) {
|
||||
export function getComDicts(zdlb?: Object) {
|
||||
return request({
|
||||
url: '/comdict/getComDicts',
|
||||
method: 'get',
|
||||
@ -1,18 +0,0 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 查询字典数据列表
|
||||
export function querylabInstrList(query) {
|
||||
return request({
|
||||
url: '/instr/query',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
// 查询字典数据列表
|
||||
export function querylabInstrListByLisgroup(query) {
|
||||
return request({
|
||||
url: '/instr/querybylisgroup',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
19
src/api/liswork/dict/LabInstr.ts
Normal file
19
src/api/liswork/dict/LabInstr.ts
Normal file
@ -0,0 +1,19 @@
|
||||
// @ts-ignore
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 查询字典数据列表
|
||||
export function querylabInstrList(query?: Object) {
|
||||
return request({
|
||||
url: '/instr/query',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
// 查询字典数据列表
|
||||
export function querylabInstrListByLisgroup(query?: Object) {
|
||||
return request({
|
||||
url: '/instr/querybylisgroup',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
@ -1,125 +0,0 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 查询数据列表
|
||||
export function queryLabPatList(query) {
|
||||
return request({
|
||||
url: '/liswork/samplelist',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询数据
|
||||
export function queryLabPat(query) {
|
||||
return request({
|
||||
url: '/liswork/sampleinfo',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询服务器时间
|
||||
export function getDate() {
|
||||
return request({
|
||||
url: '/liswork/getdate',
|
||||
method: 'get',
|
||||
})
|
||||
}
|
||||
|
||||
//
|
||||
export function changeresult(data) {
|
||||
return request({
|
||||
url: '/lisworkoper/changeresult',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
//修改病人信息
|
||||
export function updateLabPat(data) {
|
||||
return request({
|
||||
url: '/lisworkoper/changepat',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
export function changepatcolumn(query) {
|
||||
return request({
|
||||
url: '/lisworkoper/changepatcolumn',
|
||||
method: 'get',
|
||||
params:query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询结果数据列表
|
||||
export function queryLabResults(query) {
|
||||
return request({
|
||||
url: '/liswork/resultinfo',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
// 查询检验项目
|
||||
export function queryXmInfo(query) {
|
||||
return request({
|
||||
url: '/liswork/queryxminfo',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
// 查询常用取值
|
||||
export function queryXmVal(query) {
|
||||
return request({
|
||||
url: '/liswork/queryxmval',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
// 批量删除结果
|
||||
export function deleteresult(data) {
|
||||
return request({
|
||||
url: '/liswork/deleteresult',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
|
||||
}
|
||||
//审核
|
||||
export function check2(query) {
|
||||
return request({
|
||||
url: '/lisworkoper/check2',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
|
||||
}
|
||||
//取消审核
|
||||
export function uncheck2(query) {
|
||||
return request({
|
||||
url: '/lisworkoper/uncheck2',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
//取消审核
|
||||
export function unconfirmlog(query) {
|
||||
return request({
|
||||
url: '/lisworkoper/unconfirmlog',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
export function checkuser(query) {
|
||||
return request({
|
||||
url: '/liswork/checkuserid',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
export function reglimit(query) {
|
||||
return request({
|
||||
url: '/lisworkoper/reglimit',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
153
src/api/liswork/work/LisWork.ts
Normal file
153
src/api/liswork/work/LisWork.ts
Normal file
@ -0,0 +1,153 @@
|
||||
// @ts-ignore
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 查询数据列表
|
||||
export function queryLabPatList(query?: Object) {
|
||||
return request({
|
||||
url: '/liswork/samplelist',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询数据
|
||||
export function queryLabPat(query?: Object) {
|
||||
return request({
|
||||
url: '/liswork/sampleinfo',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询服务器时间
|
||||
export function getDate() {
|
||||
return request({
|
||||
url: '/liswork/getdate',
|
||||
method: 'get',
|
||||
})
|
||||
}
|
||||
|
||||
//新增结果明细
|
||||
export function newresult(data?: Object) {
|
||||
return request({
|
||||
url: '/lisworkoper/newresult',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
//修改结果明细
|
||||
export function changeresult(data?: Object) {
|
||||
return request({
|
||||
url: '/lisworkoper/changeresult',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
//修改病人信息
|
||||
export function updateLabPat(data?: Object) {
|
||||
return request({
|
||||
url: '/lisworkoper/changepat',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
export function changepatcolumn(query?: Object) {
|
||||
return request({
|
||||
url: '/lisworkoper/changepatcolumn',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询结果数据列表
|
||||
export function queryLabResults(query?: Object) {
|
||||
return request({
|
||||
url: '/liswork/resultinfo',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
// 查询检验项目
|
||||
export function queryXmInfo(query?: Object) {
|
||||
return request({
|
||||
url: '/liswork/queryxminfo',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
// 查询常用取值
|
||||
export function queryXmVal(query?: Object) {
|
||||
return request({
|
||||
url: '/liswork/queryxmval',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
// 批量删除结果
|
||||
export function deleteresult(data?: Object) {
|
||||
return request({
|
||||
url: '/liswork/deleteresult',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
|
||||
}
|
||||
//审核
|
||||
export function check2(query?: Object) {
|
||||
return request({
|
||||
url: '/lisworkoper/check2',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
|
||||
}
|
||||
//取消审核
|
||||
export function uncheck2(query?: Object) {
|
||||
return request({
|
||||
url: '/lisworkoper/uncheck2',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
//取消审核原因
|
||||
export function unconfirmlog(query?: Object) {
|
||||
return request({
|
||||
url: '/lisworkoper/unconfirmlog',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
//取消审核原因
|
||||
export function check1(query?: Object) {
|
||||
return request({
|
||||
url: 'lisworkoper/check1',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 获取操作userId
|
||||
export function checkuser(query?: Object) {
|
||||
return request({
|
||||
url: '/liswork/checkuserid',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
export function reglimit(query?: Object) {
|
||||
return request({
|
||||
url: '/lisworkoper/reglimit',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
export function printsample(query?: Object) {
|
||||
return request({
|
||||
url: '/lisworkoper/printsample',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
@ -19,6 +19,15 @@ export function login(username, password, code, uuid) {
|
||||
})
|
||||
}
|
||||
|
||||
// 单点登录
|
||||
export function loginAnonymous(data) {
|
||||
return request({
|
||||
url: '/loginAnonymous',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 注册方法
|
||||
export function register(data) {
|
||||
return request({
|
||||
|
||||
@ -123,7 +123,7 @@ aside {
|
||||
|
||||
//main-container全局样式
|
||||
.app-container {
|
||||
padding: 20px;
|
||||
padding: 10px 10px 0 10px;
|
||||
}
|
||||
|
||||
.components-container {
|
||||
|
||||
@ -7,53 +7,83 @@
|
||||
.pt5 {
|
||||
padding-top: 5px;
|
||||
}
|
||||
|
||||
.pr5 {
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
.pb5 {
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
.mt5 {
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.mr5 {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.mb5 {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.mb8 {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.ml5 {
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.mt10 {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.mr10 {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.mb10 {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.ml10 {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.mt20 {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.mr20 {
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.mb20 {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.ml20 {
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
.h1, .h2, .h3, .h4, .h5, .h6, h1, h2, h3, h4, h5, h6 {
|
||||
.cp {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.h1,
|
||||
.h2,
|
||||
.h3,
|
||||
.h4,
|
||||
.h5,
|
||||
.h6,
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
font-family: inherit;
|
||||
font-weight: 500;
|
||||
line-height: 1.1;
|
||||
@ -63,6 +93,17 @@
|
||||
.el-form .el-form-item__label {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.el-form--inline .el-form-item {
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
.el-form-item__label {
|
||||
font-weight: 400;
|
||||
font-size: 14px;
|
||||
color: #08355E;
|
||||
}
|
||||
|
||||
.el-dialog:not(.is-fullscreen) {
|
||||
margin-top: 6vh !important;
|
||||
}
|
||||
@ -75,22 +116,123 @@
|
||||
}
|
||||
|
||||
.el-table {
|
||||
.el-table__header-wrapper, .el-table__fixed-header-wrapper {
|
||||
padding: 0 !important;
|
||||
border-radius: 10px !important;
|
||||
|
||||
.el-table__header-wrapper,
|
||||
.el-table__fixed-header-wrapper {
|
||||
th {
|
||||
word-break: break-word;
|
||||
background-color: #f8f8f9 !important;
|
||||
color: #515a6e;
|
||||
background-color: #1F6DD3 !important;
|
||||
color: #FFF;
|
||||
height: 40px !important;
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
|
||||
.el-table__body-wrapper {
|
||||
.el-button [class*="el-icon-"]+span {
|
||||
margin-left: 1px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* 表格最外层边框(可选) */
|
||||
.el-table--border {
|
||||
border: 1px solid #1F6DD3 !important;
|
||||
}
|
||||
|
||||
.el-scrollbar__thumb {
|
||||
background-color: #6491D6 !important;
|
||||
|
||||
}
|
||||
|
||||
/* 修改选中行背景色 */
|
||||
.el-table__body tr.current-row>td {
|
||||
background-color: #a4beef !important;
|
||||
}
|
||||
|
||||
// /* 可选:修改悬停颜色 */
|
||||
// .el-table__body tr.hover-row>td {
|
||||
// background-color: #a4beef !important;
|
||||
// }
|
||||
}
|
||||
|
||||
.el-table--border {
|
||||
border: 1px solid #96B8D9 !important;
|
||||
border-top: none !important;
|
||||
}
|
||||
|
||||
.el-table td.el-table__cell,
|
||||
.el-table th.el-table__cell.is-leaf {
|
||||
border-bottom: 1px solid #96B8D9 !important;
|
||||
}
|
||||
|
||||
.el-table--border .el-table__cell {
|
||||
border-right: 1px solid #96B8D9 !important;
|
||||
}
|
||||
|
||||
/* 表格内部边框(可选) */
|
||||
.el-table--border th.el-table__cell {
|
||||
border-right: 1px solid #1F6DD3 !important;
|
||||
}
|
||||
|
||||
/* 在你的全局样式文件中 */
|
||||
.el-input__wrapper {
|
||||
border-color: #96B8D9 !important;
|
||||
// background-color: #f00;
|
||||
}
|
||||
|
||||
.vxe-table {
|
||||
border: 1px solid #96B8D9 !important;
|
||||
/* 蓝色外边框 */
|
||||
border-radius: 8px;
|
||||
/* 可选:添加边框圆角 */
|
||||
overflow: hidden;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
.mytable-style {
|
||||
.vxe-header--column {
|
||||
word-break: break-word;
|
||||
background-color: #1F6DD3 !important;
|
||||
color: #FFF;
|
||||
height: 40px !important;
|
||||
font-size: 13px;
|
||||
border-color: #1F6DD3 !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 高亮
|
||||
.vxe-table--render-default .vxe-body--row.row--current {
|
||||
background-color: #a4beef !important;
|
||||
}
|
||||
|
||||
// 滚动条
|
||||
.mytable-style ::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
}
|
||||
|
||||
.mytable-style ::-webkit-scrollbar-thumb {
|
||||
background-color: #e1e9f7;
|
||||
}
|
||||
|
||||
.mytable-style ::-webkit-scrollbar-thumb:hover {
|
||||
background-color: #e1e9f7;
|
||||
}
|
||||
|
||||
.btn_green {
|
||||
background-color: #aef5ef !important;
|
||||
color: #148A7F;
|
||||
border-color: #aef5ef;
|
||||
}
|
||||
|
||||
|
||||
/** 表单布局 **/
|
||||
.form-header {
|
||||
font-size: 15px;
|
||||
@ -131,6 +273,7 @@
|
||||
.pagination-container .el-pagination>.el-pagination__jump {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.pagination-container .el-pagination>.el-pagination__sizes {
|
||||
display: none !important;
|
||||
}
|
||||
@ -145,11 +288,12 @@
|
||||
/** 表格更多操作下拉样式 */
|
||||
.el-table .el-dropdown-link {
|
||||
cursor: pointer;
|
||||
color: #409EFF;
|
||||
color: #1F6DD3;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.el-table .el-dropdown, .el-icon-arrow-down {
|
||||
.el-table .el-dropdown,
|
||||
.el-icon-arrow-down {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
|
||||
@ -36,7 +36,7 @@ $base-sub-menu-background:#000c17;
|
||||
$base-sub-menu-hover:#001528;
|
||||
*/
|
||||
|
||||
$--color-primary: #409EFF;
|
||||
$--color-primary: #1F6DD3;
|
||||
$--color-success: #67C23A;
|
||||
$--color-warning: #E6A23C;
|
||||
$--color-danger: #F56C6C;
|
||||
|
||||
152
src/components/SelectTable/index.vue
Normal file
152
src/components/SelectTable/index.vue
Normal file
@ -0,0 +1,152 @@
|
||||
<!--
|
||||
* SelectTable 下拉表格组件
|
||||
* @author: Goal
|
||||
* @since: 2023-11-13
|
||||
* SelectTable.vue
|
||||
*
|
||||
* 属性(带有[Required]为必填属性)
|
||||
* data[Required]: 双向绑定数据
|
||||
* fields[Required]: 表格列对象
|
||||
* tableData[Required]: 表格数据对象
|
||||
* value: 双向绑定数据的值(为空时data属性为表格当前行数据对象)
|
||||
* label: 选择框显示的文本内容(为空时分别查看value和objKey是否为空,若value和objKey都有值,则value优先级大于objKey)
|
||||
* objKey: 对象key(绑定值的唯一标识,绑定值为对象时必填)
|
||||
* placeholder: 选择框占位文本
|
||||
* size: 组件大小
|
||||
* border: 表格是否带有边框
|
||||
-->
|
||||
<template>
|
||||
<div>
|
||||
<el-select ref="selectTable" v-model="state.selectShowValue" :placeholder="props.placeholder" :size="props.size">
|
||||
<template #empty>
|
||||
<el-table :data="props.tableData" :highlight-current-row="props.isHighlight" style="width: 100%"
|
||||
:size="props.size" :border="props.border" @current-change="handleCurrentChange">
|
||||
<el-table-column v-for="field in props.fields" :prop="field.prop" :label="field.label" :width="field.width"
|
||||
:show-overflow-tooltip="field.showTooltip" />
|
||||
</el-table>
|
||||
</template>
|
||||
</el-select>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { reactive, ref, onMounted } from "vue";
|
||||
|
||||
interface Field {
|
||||
prop: string;
|
||||
label: string;
|
||||
width: number;
|
||||
showTooltip?: boolean;
|
||||
}
|
||||
|
||||
interface Props {
|
||||
data: any;
|
||||
fields: Field[];
|
||||
tableData: object[];
|
||||
label?: string;
|
||||
value?: string;
|
||||
objKey?: string;
|
||||
isHighlight?: boolean;
|
||||
size?: string;
|
||||
placeholder?: string;
|
||||
border?: boolean;
|
||||
}
|
||||
const props = withDefaults(defineProps < Props > (), {
|
||||
placeholder: "请选择",
|
||||
size: "default",
|
||||
isHighlight: true,
|
||||
value: undefined,
|
||||
label: undefined,
|
||||
border: false,
|
||||
});
|
||||
|
||||
interface Emits {
|
||||
(e: "update:data", val: any): void;
|
||||
}
|
||||
|
||||
const emits = defineEmits < Emits > ();
|
||||
|
||||
onMounted(() => {
|
||||
//处理数据回显
|
||||
// debugger;
|
||||
if (props.data !== null) {
|
||||
// 配置label则显示label
|
||||
if (typeof props.label !== "undefined") {
|
||||
// 配置了value属性,则找到与value属性值一样的表格行对象,将配置的label回显到下拉框
|
||||
if (typeof props.value !== "undefined") {
|
||||
let row = props.tableData.find(
|
||||
(item) => item[props.value] === props.data
|
||||
);
|
||||
state.selectShowValue =
|
||||
typeof row === "undefined" ? props.data : row[props.label];
|
||||
// 配置了objKey属性,则找到与objKey属性值一样的表格行对象,将配置的label回显到下拉框
|
||||
} else if (typeof props.objKey !== "undefined") {
|
||||
let row = props.tableData.find(
|
||||
(item) => item[props.objKey] === props.data[props.objKey]
|
||||
);
|
||||
state.selectShowValue =
|
||||
typeof row === "undefined"
|
||||
? props.data[props.objKey]
|
||||
: row[props.label];
|
||||
}
|
||||
//没有配置label属性则回显value或者objKey
|
||||
} else {
|
||||
// 配置了value属性,则找到与value属性值一样的表格行对象,将配置的label回显到下拉框
|
||||
if (typeof props.value !== "undefined") {
|
||||
let row = props.tableData.find(
|
||||
(item) => item[props.value] === props.data
|
||||
);
|
||||
state.selectShowValue =
|
||||
typeof row === "undefined" ? props.data : row[props.value];
|
||||
// 配置了objKey属性,则找到与objKey属性值一样的表格行对象,将配置的label回显到下拉框
|
||||
} else if (typeof props.objKey !== "undefined") {
|
||||
let row = props.tableData.find(
|
||||
(item) => item[props.objKey] === props.data
|
||||
);
|
||||
state.selectShowValue =
|
||||
typeof row === "undefined" ? props.data : row[props.objKey];
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const selectTable = ref();
|
||||
|
||||
const state = reactive({
|
||||
selectValue: null,
|
||||
selectShowValue: null,
|
||||
});
|
||||
|
||||
/**
|
||||
* 点击当前行事件
|
||||
* @param val
|
||||
*/
|
||||
const handleCurrentChange = (val: any) => {
|
||||
// 如果没有配置label则显示value或者objKey
|
||||
setLabel(val);
|
||||
// 设置双向绑定值
|
||||
if (typeof props.value !== "undefined") {
|
||||
emits("update:data", val[props.value]);
|
||||
} else {
|
||||
emits("update:data", val);
|
||||
}
|
||||
selectTable.value.blur();
|
||||
};
|
||||
|
||||
const setLabel = (val: any) => {
|
||||
// 如果没有配置label则显示value或者objKey
|
||||
if (typeof props.label === "undefined") {
|
||||
// 如果配置了value,则显示value
|
||||
if (typeof props.value !== "undefined") {
|
||||
state.selectShowValue = val[props.value];
|
||||
} else if (typeof props.objKey !== "undefined") {
|
||||
//没有配置value但配置了objKey,则显示objKey
|
||||
state.selectShowValue = val[props.objKey];
|
||||
}
|
||||
} else {
|
||||
state.selectShowValue = val[props.label];
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@ -1,15 +1,8 @@
|
||||
<template>
|
||||
<el-menu
|
||||
:default-active="activeMenu"
|
||||
mode="horizontal"
|
||||
@select="handleSelect"
|
||||
:ellipsis="false"
|
||||
>
|
||||
<el-menu :default-active="activeMenu" mode="horizontal" @select="handleSelect" :ellipsis="false">
|
||||
<template v-for="(item, index) in topMenus">
|
||||
<el-menu-item :style="{ '--theme': theme }" :index="item.path" :key="index" v-if="index < visibleNumber">
|
||||
<svg-icon
|
||||
v-if="item.meta && item.meta.icon && item.meta.icon !== '#'"
|
||||
:icon-class="item.meta.icon"/>
|
||||
<svg-icon v-if="item.meta && item.meta.icon && item.meta.icon !== '#'" :icon-class="item.meta.icon" />
|
||||
{{ item.meta.title }}
|
||||
</el-menu-item>
|
||||
</template>
|
||||
@ -18,13 +11,8 @@
|
||||
<el-sub-menu :style="{ '--theme': theme }" index="more" v-if="topMenus.length > visibleNumber">
|
||||
<template #title>更多菜单</template>
|
||||
<template v-for="(item, index) in topMenus">
|
||||
<el-menu-item
|
||||
:index="item.path"
|
||||
:key="index"
|
||||
v-if="index >= visibleNumber">
|
||||
<svg-icon
|
||||
v-if="item.meta && item.meta.icon && item.meta.icon !== '#'"
|
||||
:icon-class="item.meta.icon"/>
|
||||
<el-menu-item :index="item.path" :key="index" v-if="index >= visibleNumber">
|
||||
<svg-icon v-if="item.meta && item.meta.icon && item.meta.icon !== '#'" :icon-class="item.meta.icon" />
|
||||
{{ item.meta.title }}
|
||||
</el-menu-item>
|
||||
</template>
|
||||
@ -179,7 +167,8 @@ onMounted(() => {
|
||||
margin: 0 10px !important;
|
||||
}
|
||||
|
||||
.topmenu-container.el-menu--horizontal > .el-menu-item.is-active, .el-menu--horizontal > .el-sub-menu.is-active .el-submenu__title {
|
||||
.topmenu-container.el-menu--horizontal>.el-menu-item.is-active,
|
||||
.el-menu--horizontal>.el-sub-menu.is-active .el-submenu__title {
|
||||
border-bottom: 2px solid #{'var(--theme)'} !important;
|
||||
color: #303133;
|
||||
}
|
||||
@ -195,7 +184,9 @@ onMounted(() => {
|
||||
}
|
||||
|
||||
/* 背景色隐藏 */
|
||||
.topmenu-container.el-menu--horizontal>.el-menu-item:not(.is-disabled):focus, .topmenu-container.el-menu--horizontal>.el-menu-item:not(.is-disabled):hover, .topmenu-container.el-menu--horizontal>.el-submenu .el-submenu__title:hover {
|
||||
.topmenu-container.el-menu--horizontal>.el-menu-item:not(.is-disabled):focus,
|
||||
.topmenu-container.el-menu--horizontal>.el-menu-item:not(.is-disabled):hover,
|
||||
.topmenu-container.el-menu--horizontal>.el-submenu .el-submenu__title:hover {
|
||||
background-color: #ffffff !important;
|
||||
}
|
||||
|
||||
|
||||
@ -273,15 +273,15 @@ defineExpose({
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
/* 修改选中行背景色 */
|
||||
::v-deep .el-table__body tr.current-row>td {
|
||||
background-color: #add7f7 !important;
|
||||
}
|
||||
// /* 修改选中行背景色 */
|
||||
// ::v-deep .el-table__body tr.current-row>td {
|
||||
// background-color: #a4beef !important;
|
||||
// }
|
||||
|
||||
/* 可选:修改悬停颜色 */
|
||||
::v-deep .el-table__body tr.hover-row>td {
|
||||
background-color: #326ca5 !important;
|
||||
}
|
||||
// /* 可选:修改悬停颜色 */
|
||||
// ::v-deep .el-table__body tr.hover-row>td {
|
||||
// background-color: #a4beef !important;
|
||||
// }
|
||||
|
||||
/* 响应式设计 */
|
||||
@media (max-width: 768px) {
|
||||
|
||||
@ -8,8 +8,10 @@
|
||||
<img src="@/assets/images/dark.svg" alt="dark" />
|
||||
<div v-if="sideTheme === 'theme-dark'" class="setting-drawer-block-checbox-selectIcon" style="display: block;">
|
||||
<i aria-label="图标: check" class="anticon anticon-check">
|
||||
<svg viewBox="64 64 896 896" data-icon="check" width="1em" height="1em" :fill="theme" aria-hidden="true" focusable="false" class>
|
||||
<path d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 0 0-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z" />
|
||||
<svg viewBox="64 64 896 896" data-icon="check" width="1em" height="1em" :fill="theme" aria-hidden="true"
|
||||
focusable="false" class>
|
||||
<path
|
||||
d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 0 0-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z" />
|
||||
</svg>
|
||||
</i>
|
||||
</div>
|
||||
@ -18,8 +20,10 @@
|
||||
<img src="@/assets/images/light.svg" alt="light" />
|
||||
<div v-if="sideTheme === 'theme-light'" class="setting-drawer-block-checbox-selectIcon" style="display: block;">
|
||||
<i aria-label="图标: check" class="anticon anticon-check">
|
||||
<svg viewBox="64 64 896 896" data-icon="check" width="1em" height="1em" :fill="theme" aria-hidden="true" focusable="false" class>
|
||||
<path d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 0 0-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z" />
|
||||
<svg viewBox="64 64 896 896" data-icon="check" width="1em" height="1em" :fill="theme" aria-hidden="true"
|
||||
focusable="false" class>
|
||||
<path
|
||||
d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 0 0-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z" />
|
||||
</svg>
|
||||
</i>
|
||||
</div>
|
||||
@ -92,7 +96,7 @@ const showSettings = ref(false);
|
||||
const theme = ref(settingsStore.theme);
|
||||
const sideTheme = ref(settingsStore.sideTheme);
|
||||
const storeSettings = computed(() => settingsStore);
|
||||
const predefineColors = ref(["#409EFF", "#ff4500", "#ff8c00", "#ffd700", "#90ee90", "#00ced1", "#1e90ff", "#c71585"]);
|
||||
const predefineColors = ref(["#1F6DD3", "#ff4500", "#ff8c00", "#ffd700", "#90ee90", "#00ced1", "#1e90ff", "#c71585"]);
|
||||
|
||||
/** 是否需要topnav */
|
||||
function topNavChange(val) {
|
||||
@ -144,10 +148,12 @@ defineExpose({
|
||||
color: rgba(0, 0, 0, 0.85);
|
||||
line-height: 22px;
|
||||
font-weight: bold;
|
||||
|
||||
.drawer-title {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.setting-drawer-block-checbox {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
|
||||
30
src/main.js
30
src/main.js
@ -1,11 +1,16 @@
|
||||
import { createApp } from 'vue'
|
||||
import {
|
||||
createApp
|
||||
} from 'vue'
|
||||
|
||||
import Cookies from 'js-cookie'
|
||||
|
||||
import ElementPlus from 'element-plus'
|
||||
import 'element-plus/dist/index.css'
|
||||
import locale from 'element-plus/es/locale/lang/zh-cn'
|
||||
|
||||
import VxeUI from 'vxe-pc-ui'
|
||||
import 'vxe-pc-ui/lib/style.css'
|
||||
import VXETable from 'vxe-table'
|
||||
import 'vxe-table/lib/style.css'
|
||||
import '@/assets/styles/index.scss' // global css
|
||||
// 先导入 jQuery 并设置全局变量
|
||||
|
||||
@ -20,7 +25,9 @@ import directive from './directive' // directive
|
||||
|
||||
// 注册指令
|
||||
import plugins from './plugins' // plugins
|
||||
import { download } from '@/utils/request'
|
||||
import {
|
||||
download
|
||||
} from '@/utils/request'
|
||||
|
||||
// svg图标
|
||||
import 'virtual:svg-icons-register'
|
||||
@ -29,8 +36,18 @@ import elementIcons from '@/components/SvgIcon/svgicon'
|
||||
|
||||
import './permission' // permission control
|
||||
|
||||
import {useDict, comDict} from '@/utils/dict'
|
||||
import { parseTime, resetForm, addDateRange, handleTree, selectDictLabel, selectDictLabels } from '@/utils/ruoyi'
|
||||
import {
|
||||
useDict,
|
||||
comDict
|
||||
} from '@/utils/dict'
|
||||
import {
|
||||
parseTime,
|
||||
resetForm,
|
||||
addDateRange,
|
||||
handleTree,
|
||||
selectDictLabel,
|
||||
selectDictLabels
|
||||
} from '@/utils/ruoyi'
|
||||
|
||||
// 分页组件
|
||||
import Pagination from '@/components/Pagination'
|
||||
@ -82,7 +99,8 @@ app.use(plugins)
|
||||
app.use(elementIcons)
|
||||
app.component('svg-icon', SvgIcon)
|
||||
directive(app)
|
||||
|
||||
app.use(VxeUI)
|
||||
app.use(VXETable)
|
||||
// 使用element-plus 并且设置全局的大小
|
||||
app.use(ElementPlus, {
|
||||
locale: locale,
|
||||
|
||||
@ -1,17 +1,27 @@
|
||||
import router from './router'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import {
|
||||
ElMessage
|
||||
} from 'element-plus'
|
||||
import NProgress from 'nprogress'
|
||||
import 'nprogress/nprogress.css'
|
||||
import { getToken } from '@/utils/auth'
|
||||
import { isHttp } from '@/utils/validate'
|
||||
import { isRelogin } from '@/utils/request'
|
||||
import {
|
||||
getToken
|
||||
} from '@/utils/auth'
|
||||
import {
|
||||
isHttp
|
||||
} from '@/utils/validate'
|
||||
import {
|
||||
isRelogin
|
||||
} from '@/utils/request'
|
||||
import useUserStore from '@/store/modules/user'
|
||||
import useSettingsStore from '@/store/modules/settings'
|
||||
import usePermissionStore from '@/store/modules/permission'
|
||||
|
||||
NProgress.configure({ showSpinner: false });
|
||||
NProgress.configure({
|
||||
showSpinner: false
|
||||
});
|
||||
|
||||
const whiteList = ['/login', '/register'];
|
||||
const whiteList = ['/login', '/register', '/report'];
|
||||
|
||||
router.beforeEach((to, from, next) => {
|
||||
NProgress.start()
|
||||
@ -19,7 +29,9 @@ router.beforeEach((to, from, next) => {
|
||||
to.meta.title && useSettingsStore().setTitle(to.meta.title)
|
||||
/* has token*/
|
||||
if (to.path === '/login') {
|
||||
next({ path: '/' })
|
||||
next({
|
||||
path: '/'
|
||||
})
|
||||
NProgress.done()
|
||||
} else if (whiteList.indexOf(to.path) !== -1) {
|
||||
next()
|
||||
@ -36,12 +48,17 @@ router.beforeEach((to, from, next) => {
|
||||
router.addRoute(route) // 动态添加可访问路由表
|
||||
}
|
||||
})
|
||||
next({ ...to, replace: true }) // hack方法 确保addRoutes已完成
|
||||
next({
|
||||
...to,
|
||||
replace: true
|
||||
}) // hack方法 确保addRoutes已完成
|
||||
})
|
||||
}).catch(err => {
|
||||
useUserStore().logOut().then(() => {
|
||||
ElMessage.error(err)
|
||||
next({ path: '/' })
|
||||
next({
|
||||
path: '/'
|
||||
})
|
||||
})
|
||||
})
|
||||
} else {
|
||||
|
||||
@ -1,4 +1,7 @@
|
||||
import { createWebHistory, createRouter } from 'vue-router'
|
||||
import {
|
||||
createWebHistory,
|
||||
createRouter
|
||||
} from 'vue-router'
|
||||
/* Layout */
|
||||
import Layout from '@/layout'
|
||||
|
||||
@ -25,17 +28,14 @@ import Layout from '@/layout'
|
||||
*/
|
||||
|
||||
// 公共路由
|
||||
export const constantRoutes = [
|
||||
{
|
||||
export const constantRoutes = [{
|
||||
path: '/redirect',
|
||||
component: Layout,
|
||||
hidden: true,
|
||||
children: [
|
||||
{
|
||||
children: [{
|
||||
path: '/redirect/:path(.*)',
|
||||
component: () => import('@/views/redirect/index.vue')
|
||||
}
|
||||
]
|
||||
}]
|
||||
},
|
||||
{
|
||||
path: '/login',
|
||||
@ -47,6 +47,11 @@ export const constantRoutes = [
|
||||
component: () => import('@/views/register'),
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: '/report',
|
||||
component: () => import('@/views/checkCode/report'),
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: "/:pathMatch(.*)*",
|
||||
component: () => import('@/views/error/404'),
|
||||
@ -61,102 +66,109 @@ export const constantRoutes = [
|
||||
path: '',
|
||||
component: Layout,
|
||||
redirect: '/index',
|
||||
children: [
|
||||
{
|
||||
children: [{
|
||||
path: '/index',
|
||||
component: () => import('@/views/index'),
|
||||
name: 'Index',
|
||||
meta: { title: '首页', icon: 'dashboard', affix: true }
|
||||
meta: {
|
||||
title: '首页',
|
||||
icon: 'dashboard',
|
||||
affix: true
|
||||
}
|
||||
]
|
||||
}]
|
||||
},
|
||||
{
|
||||
path: '/user',
|
||||
component: Layout,
|
||||
hidden: true,
|
||||
redirect: 'noredirect',
|
||||
children: [
|
||||
{
|
||||
children: [{
|
||||
path: 'profile',
|
||||
component: () => import('@/views/system/user/profile/index'),
|
||||
name: 'Profile',
|
||||
meta: { title: '个人中心', icon: 'user' }
|
||||
meta: {
|
||||
title: '个人中心',
|
||||
icon: 'user'
|
||||
}
|
||||
]
|
||||
}]
|
||||
}
|
||||
]
|
||||
|
||||
// 动态路由,基于用户权限动态去加载
|
||||
export const dynamicRoutes = [
|
||||
{
|
||||
export const dynamicRoutes = [{
|
||||
path: '/system/user-auth',
|
||||
component: Layout,
|
||||
hidden: true,
|
||||
permissions: ['system:user:edit'],
|
||||
children: [
|
||||
{
|
||||
children: [{
|
||||
path: 'role/:userId(\\d+)',
|
||||
component: () => import('@/views/system/user/authRole'),
|
||||
name: 'AuthRole',
|
||||
meta: { title: '分配角色', activeMenu: '/system/user' }
|
||||
meta: {
|
||||
title: '分配角色',
|
||||
activeMenu: '/system/user'
|
||||
}
|
||||
]
|
||||
}]
|
||||
},
|
||||
{
|
||||
path: '/system/role-auth',
|
||||
component: Layout,
|
||||
hidden: true,
|
||||
permissions: ['system:role:edit'],
|
||||
children: [
|
||||
{
|
||||
children: [{
|
||||
path: 'user/:roleId(\\d+)',
|
||||
component: () => import('@/views/system/role/authUser'),
|
||||
name: 'AuthUser',
|
||||
meta: { title: '分配用户', activeMenu: '/system/role' }
|
||||
meta: {
|
||||
title: '分配用户',
|
||||
activeMenu: '/system/role'
|
||||
}
|
||||
]
|
||||
}]
|
||||
},
|
||||
{
|
||||
path: '/system/dict-data',
|
||||
component: Layout,
|
||||
hidden: true,
|
||||
permissions: ['system:dict:list'],
|
||||
children: [
|
||||
{
|
||||
children: [{
|
||||
path: 'index/:dictId(\\d+)',
|
||||
component: () => import('@/views/system/dict/data'),
|
||||
name: 'Data',
|
||||
meta: { title: '字典数据', activeMenu: '/system/dict' }
|
||||
meta: {
|
||||
title: '字典数据',
|
||||
activeMenu: '/system/dict'
|
||||
}
|
||||
]
|
||||
}]
|
||||
},
|
||||
{
|
||||
path: '/monitor/job-log',
|
||||
component: Layout,
|
||||
hidden: true,
|
||||
permissions: ['monitor:job:list'],
|
||||
children: [
|
||||
{
|
||||
children: [{
|
||||
path: 'index/:jobId(\\d+)',
|
||||
component: () => import('@/views/monitor/job/log'),
|
||||
name: 'JobLog',
|
||||
meta: { title: '调度日志', activeMenu: '/monitor/job' }
|
||||
meta: {
|
||||
title: '调度日志',
|
||||
activeMenu: '/monitor/job'
|
||||
}
|
||||
]
|
||||
}]
|
||||
},
|
||||
{
|
||||
path: '/tool/gen-edit',
|
||||
component: Layout,
|
||||
hidden: true,
|
||||
permissions: ['tool:gen:edit'],
|
||||
children: [
|
||||
{
|
||||
children: [{
|
||||
path: 'index/:tableId(\\d+)',
|
||||
component: () => import('@/views/tool/gen/editTable'),
|
||||
name: 'GenEdit',
|
||||
meta: { title: '修改生成配置', activeMenu: '/tool/gen' }
|
||||
meta: {
|
||||
title: '修改生成配置',
|
||||
activeMenu: '/tool/gen'
|
||||
}
|
||||
]
|
||||
}]
|
||||
}
|
||||
]
|
||||
|
||||
@ -167,7 +179,9 @@ const router = createRouter({
|
||||
if (savedPosition) {
|
||||
return savedPosition
|
||||
} else {
|
||||
return { top: 0 }
|
||||
return {
|
||||
top: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
@ -1,16 +1,25 @@
|
||||
import defaultSettings from '@/settings'
|
||||
import { useDynamicTitle } from '@/utils/dynamicTitle'
|
||||
import {
|
||||
useDynamicTitle
|
||||
} from '@/utils/dynamicTitle'
|
||||
|
||||
const { sideTheme, showSettings, topNav, tagsView, fixedHeader, sidebarLogo, dynamicTitle } = defaultSettings
|
||||
const {
|
||||
sideTheme,
|
||||
showSettings,
|
||||
topNav,
|
||||
tagsView,
|
||||
fixedHeader,
|
||||
sidebarLogo,
|
||||
dynamicTitle
|
||||
} = defaultSettings
|
||||
|
||||
const storageSetting = JSON.parse(localStorage.getItem('layout-setting')) || ''
|
||||
|
||||
const useSettingsStore = defineStore(
|
||||
'settings',
|
||||
{
|
||||
'settings', {
|
||||
state: () => ({
|
||||
title: '', //标题
|
||||
theme: storageSetting.theme || '#409EFF', //主题颜色
|
||||
theme: storageSetting.theme || '#1F6DD3', //主题颜色
|
||||
sideTheme: storageSetting.sideTheme || sideTheme, //侧边栏主题
|
||||
showSettings: showSettings, //是否显示设置按钮
|
||||
topNav: storageSetting.topNav === undefined ? topNav : storageSetting.topNav, //顶部导航
|
||||
@ -22,7 +31,10 @@ const useSettingsStore = defineStore(
|
||||
actions: {
|
||||
// 修改布局设置
|
||||
changeSetting(data) {
|
||||
const { key, value } = data
|
||||
const {
|
||||
key,
|
||||
value
|
||||
} = data
|
||||
if (this.hasOwnProperty(key)) {
|
||||
this[key] = value
|
||||
}
|
||||
|
||||
@ -1,10 +1,18 @@
|
||||
import { login, logout, getInfo } from '@/api/login'
|
||||
import { getToken, setToken, removeToken } from '@/utils/auth'
|
||||
import {
|
||||
login,
|
||||
logout,
|
||||
getInfo,
|
||||
loginAnonymous
|
||||
} from '@/api/login'
|
||||
import {
|
||||
getToken,
|
||||
setToken,
|
||||
removeToken
|
||||
} from '@/utils/auth'
|
||||
import defAva from '@/assets/images/profile.jpg'
|
||||
|
||||
const useUserStore = defineStore(
|
||||
'user',
|
||||
{
|
||||
'user', {
|
||||
state: () => ({
|
||||
token: getToken(),
|
||||
id: '',
|
||||
@ -14,6 +22,20 @@ const useUserStore = defineStore(
|
||||
permissions: []
|
||||
}),
|
||||
actions: {
|
||||
// 单点登录
|
||||
loginAnonymous(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
loginAnonymous({
|
||||
username: data.name
|
||||
}).then(res => {
|
||||
setToken(res.token)
|
||||
this.token = res.token
|
||||
resolve()
|
||||
}).catch(error => {
|
||||
reject(error)
|
||||
})
|
||||
})
|
||||
},
|
||||
// 登录
|
||||
login(userInfo) {
|
||||
const username = userInfo.username.trim()
|
||||
|
||||
@ -63,8 +63,26 @@ function getContrastTextColor(bgColor: string): string {
|
||||
// 根据亮度返回对比色
|
||||
return luminance > 0.5 ? '#333333' : '#FFFFFF';
|
||||
}
|
||||
|
||||
// 打印https pdf
|
||||
function printPDF(pdfUrl: string) {
|
||||
// 验证URL是否为HTTPS
|
||||
if (pdfUrl.startsWith('http')) {
|
||||
console.warn('PDF URL不是HTTPS协议,可能存在安全风险');
|
||||
}
|
||||
|
||||
const iframe = document.createElement('iframe');
|
||||
iframe.style.display = 'none';
|
||||
iframe.src = pdfUrl;
|
||||
document.body.appendChild(iframe);
|
||||
iframe.onload = () => {
|
||||
iframe.contentWindow?.print();
|
||||
setTimeout(() => URL.revokeObjectURL(pdfUrl), 1000); // 释放内存
|
||||
};
|
||||
}
|
||||
|
||||
// 打印base64 pdf
|
||||
function printPDF(base64: string) {
|
||||
function printBase64PDF(base64: string) {
|
||||
const blob = base64ToBlob(base64);
|
||||
const pdfUrl = URL.createObjectURL(blob);
|
||||
const iframe = document.createElement('iframe');
|
||||
@ -87,5 +105,8 @@ function base64ToBlob(base64: string) {
|
||||
}
|
||||
|
||||
|
||||
export const classCom = { decimalToHexColor, convertHexToNumber, getContrastTextColor, printPDF }
|
||||
|
||||
|
||||
|
||||
export const classCom = { decimalToHexColor, convertHexToNumber, getContrastTextColor, printBase64PDF, printPDF }
|
||||
|
||||
|
||||
@ -1,6 +1,10 @@
|
||||
import useDictStore from '@/store/modules/dict'
|
||||
import { getDicts } from '@/api/system/dict/data'
|
||||
import { getComDicts } from '@/api/liswork/dict/ComDict.js'
|
||||
import {
|
||||
getDicts
|
||||
} from '@/api/system/dict/data'
|
||||
import {
|
||||
getComDicts
|
||||
} from '@/api/liswork/dict/ComDict'
|
||||
/**
|
||||
* 获取字典数据
|
||||
*/
|
||||
@ -14,7 +18,12 @@ export function useDict(...args) {
|
||||
res.value[dictType] = dicts;
|
||||
} else {
|
||||
getDicts(dictType).then(resp => {
|
||||
res.value[dictType] = resp.data.map(p => ({ label: p.dictLabel, value: p.dictValue, elTagType: p.listClass, elTagClass: p.cssClass }))
|
||||
res.value[dictType] = resp.data.map(p => ({
|
||||
label: p.dictLabel,
|
||||
value: p.dictValue,
|
||||
elTagType: p.listClass,
|
||||
elTagClass: p.cssClass
|
||||
}))
|
||||
useDictStore().setDict(dictType, res.value[dictType]);
|
||||
})
|
||||
}
|
||||
@ -39,7 +48,9 @@ export function comDict(...args) {
|
||||
res.value[dictType] = dicts;
|
||||
} else {
|
||||
// 缓存不存在,发起请求并记录 Promise
|
||||
const promise = getComDicts({ zdlb: dictType }).then(resp => {
|
||||
const promise = getComDicts({
|
||||
zdlb: dictType
|
||||
}).then(resp => {
|
||||
const dictList = resp.data.map(p => ({
|
||||
label: p.zdmc,
|
||||
value: p.zddh,
|
||||
|
||||
@ -1,16 +1,33 @@
|
||||
import { createVNode, render } from 'vue';
|
||||
import {
|
||||
createVNode,
|
||||
render
|
||||
} from 'vue';
|
||||
import axios from 'axios'
|
||||
import { ElNotification , ElMessageBox, ElMessage, ElLoading } from 'element-plus'
|
||||
import { getToken } from '@/utils/auth'
|
||||
import {
|
||||
ElNotification,
|
||||
ElMessageBox,
|
||||
ElMessage,
|
||||
ElLoading
|
||||
} from 'element-plus'
|
||||
import {
|
||||
getToken
|
||||
} from '@/utils/auth'
|
||||
import errorCode from '@/utils/errorCode'
|
||||
import { tansParams, blobValidate } from '@/utils/ruoyi'
|
||||
import {
|
||||
tansParams,
|
||||
blobValidate
|
||||
} from '@/utils/ruoyi'
|
||||
import cache from '@/plugins/cache'
|
||||
import { saveAs } from 'file-saver'
|
||||
import {
|
||||
saveAs
|
||||
} from 'file-saver'
|
||||
import useUserStore from '@/store/modules/user'
|
||||
|
||||
let downloadLoadingInstance;
|
||||
// 是否显示重新登录
|
||||
export let isRelogin = { show: false };
|
||||
export let isRelogin = {
|
||||
show: false
|
||||
};
|
||||
|
||||
axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
|
||||
// 创建axios实例
|
||||
@ -106,7 +123,11 @@ service.interceptors.response.use(res => {
|
||||
if (code === 401) {
|
||||
if (!isRelogin.show) {
|
||||
isRelogin.show = true;
|
||||
ElMessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning' }).then(() => {
|
||||
ElMessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', {
|
||||
confirmButtonText: '重新登录',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
isRelogin.show = false;
|
||||
useUserStore().logOut().then(() => {
|
||||
location.href = '/index';
|
||||
@ -117,25 +138,43 @@ service.interceptors.response.use(res => {
|
||||
}
|
||||
return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
|
||||
} else if (code === 500) {
|
||||
ElMessage({ message: msg, type: 'error' })
|
||||
ElMessage({
|
||||
message: msg,
|
||||
type: 'error'
|
||||
})
|
||||
return Promise.reject(new Error(msg))
|
||||
} else if (code === 601) {
|
||||
ElMessage({ message: msg, type: 'warning' })
|
||||
ElMessage({
|
||||
message: msg,
|
||||
type: 'warning'
|
||||
})
|
||||
return Promise.reject(new Error(msg))
|
||||
} else if (code === 3) {
|
||||
//提示并成功
|
||||
ElMessage({ message: msg, type: 'success' })
|
||||
ElMessage({
|
||||
message: msg,
|
||||
type: 'success'
|
||||
})
|
||||
return Promise.resolve(res.data)
|
||||
} else if (code === 2) {
|
||||
//选择是否后续操作
|
||||
ElMessageBox.confirm(msg, '系统提示', { confirmButtonText: '是', cancelButtonText: '否', type: 'warning' }).then(() => {
|
||||
ElMessageBox.confirm(msg, '系统提示', {
|
||||
confirmButtonText: '是',
|
||||
cancelButtonText: '否',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
return Promise.resolve(res.data);
|
||||
})
|
||||
return Promise.reject('error');
|
||||
} else if (code === 1) {
|
||||
//提示并失败
|
||||
ElMessage({ message: msg, type: 'error' })
|
||||
return Promise.reject(new Error(msg))
|
||||
ElNotification({
|
||||
title: '提示',
|
||||
message: msg,
|
||||
type: 'error',
|
||||
duration: 0,
|
||||
})
|
||||
return Promise.resolve(res.data)
|
||||
} else if (code === 4) {
|
||||
//返回特定值,需要后续处理,表示当前操作需要处理后再调用,problemId是步骤关键参数,需要再次调用时引入
|
||||
return Promise.resolve(res.data)
|
||||
@ -161,7 +200,12 @@ service.interceptors.response.use(res => {
|
||||
cancelButtonText: '否',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
const { url, method, data: data0, params: params0 } = res.data;
|
||||
const {
|
||||
url,
|
||||
method,
|
||||
data: data0,
|
||||
params: params0
|
||||
} = res.data;
|
||||
// 4. 构造新请求参数,携带问题ID(根据后端要求决定传递方式)
|
||||
const newParams = {
|
||||
...params0,
|
||||
@ -189,7 +233,9 @@ service.interceptors.response.use(res => {
|
||||
});
|
||||
});
|
||||
} else if (code !== 200 && code !== 0) {
|
||||
ElNotification.error({ title: msg })
|
||||
ElNotification.error({
|
||||
title: msg
|
||||
})
|
||||
return Promise.reject('error')
|
||||
} else {
|
||||
return Promise.resolve(res.data)
|
||||
@ -197,7 +243,9 @@ service.interceptors.response.use(res => {
|
||||
},
|
||||
error => {
|
||||
console.log('err' + error)
|
||||
let { message } = error;
|
||||
let {
|
||||
message
|
||||
} = error;
|
||||
if (message == "Network Error") {
|
||||
message = "后端接口连接异常";
|
||||
} else if (message.includes("timeout")) {
|
||||
@ -205,17 +253,28 @@ service.interceptors.response.use(res => {
|
||||
} else if (message.includes("Request failed with status code")) {
|
||||
message = "系统接口" + message.substr(message.length - 3) + "异常";
|
||||
}
|
||||
ElMessage({ message: message, type: 'error', duration: 5 * 1000 })
|
||||
ElMessage({
|
||||
message: message,
|
||||
type: 'error',
|
||||
duration: 5 * 1000
|
||||
})
|
||||
return Promise.reject(error)
|
||||
}
|
||||
)
|
||||
|
||||
// 通用下载方法
|
||||
export function download(url, params, filename, config) {
|
||||
downloadLoadingInstance = ElLoading.service({ text: "正在下载数据,请稍候", background: "rgba(0, 0, 0, 0.7)", })
|
||||
downloadLoadingInstance = ElLoading.service({
|
||||
text: "正在下载数据,请稍候",
|
||||
background: "rgba(0, 0, 0, 0.7)",
|
||||
})
|
||||
return service.post(url, params, {
|
||||
transformRequest: [(params) => { return tansParams(params) }],
|
||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||||
transformRequest: [(params) => {
|
||||
return tansParams(params)
|
||||
}],
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
},
|
||||
responseType: 'blob',
|
||||
...config
|
||||
}).then(async (data) => {
|
||||
|
||||
53
src/utils/useFingerprint.js
Normal file
53
src/utils/useFingerprint.js
Normal file
@ -0,0 +1,53 @@
|
||||
import {
|
||||
ref,
|
||||
onMounted
|
||||
} from 'vue';
|
||||
import FingerprintJS from '@fingerprintjs/fingerprintjs';
|
||||
|
||||
export function useFingerprint() {
|
||||
const fingerprint = ref('');
|
||||
const loading = ref(true);
|
||||
const error = ref(null);
|
||||
|
||||
// 初始化FingerprintJS并获取指纹
|
||||
const getFingerprint = async () => {
|
||||
try {
|
||||
loading.value = true;
|
||||
// 初始化代理
|
||||
const fp = await FingerprintJS.load({
|
||||
// 可选配置
|
||||
monitoring: false,
|
||||
// 扩展结果数据
|
||||
extendedResult: true
|
||||
});
|
||||
|
||||
// 获取指纹信息
|
||||
const result = await fp.get();
|
||||
|
||||
// 指纹标识符
|
||||
fingerprint.value = result.visitorId;
|
||||
|
||||
// 可以获取更多详细信息
|
||||
console.log('指纹详细信息:', result);
|
||||
return result;
|
||||
} catch (err) {
|
||||
error.value = err;
|
||||
console.error('获取指纹失败:', err);
|
||||
return null;
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 组件挂载时自动获取指纹
|
||||
onMounted(() => {
|
||||
getFingerprint();
|
||||
});
|
||||
|
||||
return {
|
||||
fingerprint,
|
||||
loading,
|
||||
error,
|
||||
getFingerprint
|
||||
};
|
||||
}
|
||||
@ -516,9 +516,8 @@ function adjustTableHeight() {
|
||||
if (compactForm.value) {
|
||||
// 获取高度
|
||||
heightForm.value = compactForm.value.offsetHeight;
|
||||
tableConfig.value.height = `calc(72vh - ${heightForm.value}px)`; // 设置表格容器的高度
|
||||
rightTableConfig.value.height = `calc(76vh - ${heightForm.value}px)`;
|
||||
|
||||
tableConfig.value.height = `calc(78vh - ${heightForm.value}px)`; // 设置表格容器的高度
|
||||
rightTableConfig.value.height = `calc(83vh - ${heightForm.value}px)`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -2,77 +2,89 @@
|
||||
<div class="app-container">
|
||||
<div ref="compactForm">
|
||||
<el-row :gutter="10" class="compact-form" v-show="showSearch">
|
||||
<el-form :model="queryParams" ref="queryRef" :inline="true" :rules="queryRules">
|
||||
<el-form :model="queryParams" ref="queryRef" label-width="100px" :rules="queryRules" style="width: 100%;">
|
||||
<el-row>
|
||||
<el-col :span="5">
|
||||
<el-form-item label="日期:" prop="times">
|
||||
<el-date-picker v-model="queryParams.times" type="daterange" range-separator="-" start-placeholder="开始时间"
|
||||
end-placeholder="结束时间" format="YYYY-MM-DD" value-format="YYYY-MM-DD" />
|
||||
<el-date-picker v-model="queryParams.times" type="daterange" range-separator="-"
|
||||
start-placeholder="开始时间" end-placeholder="结束时间" format="YYYY-MM-DD" value-format="YYYY-MM-DD" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="病人状态:" prop="dybz">
|
||||
<el-select v-model="queryParams.dybz" placeholder="请选择">
|
||||
</el-col>
|
||||
<el-col :span="5">
|
||||
<el-form-item label="打印状态:" prop="dybz">
|
||||
<el-select v-model="queryParams.dybz" placeholder="请选择" style=" ">
|
||||
<el-option label="已打印" value="1" />
|
||||
<el-option label="未打印" value="0" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="5">
|
||||
<el-form-item label="科室:" prop="ksdh">
|
||||
<el-select v-model="queryParams.ksdh" placeholder="请选择" filterable clearable>
|
||||
<el-option v-for="item in dictData.DP" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="5">
|
||||
<el-form-item label="病人类型:" prop="brly">
|
||||
<el-select v-model="queryParams.brly" placeholder="请选择" style="width: 120px;">
|
||||
<el-select v-model="queryParams.brly" placeholder="请选择">
|
||||
<el-option v-for="item in dictData.PT" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-form-item label="" prop="">
|
||||
<el-checkbox v-model="queryParams.alarmflag" label="仅危急值" @change="alarmHandle" size="large" />
|
||||
<el-checkbox v-model="queryParams.jzbz" label="仅急诊" @change="jzbzHandle" size="large" />
|
||||
</el-form-item>
|
||||
<el-form-item label="姓名" prop="brxm">
|
||||
<el-col :span="1.5">
|
||||
<el-input v-model="queryParams.brxm" clearable placeholder="姓名" @keyup.enter="handleQuery"
|
||||
@clear="handleQuery" />
|
||||
</el-col>
|
||||
</el-form-item>
|
||||
<el-form-item label="病人号" prop="brdh">
|
||||
<el-col :span="1.5">
|
||||
<el-input v-model="queryParams.brdh" clearable placeholder="病人号" @keyup.enter="handleQuery"
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="5">
|
||||
<el-form-item label="姓名:" prop="brxm">
|
||||
<el-input v-model="queryParams.brxm" clearable placeholder="请输入姓名" @keyup.enter="handleQuery"
|
||||
@clear="handleQuery" />
|
||||
</el-col>
|
||||
</el-form-item>
|
||||
<el-form-item label="条形码" prop="sqh">
|
||||
<el-col :span="1.5">
|
||||
<el-input v-model="queryParams.sqh" clearable placeholder="条形码" @keyup.enter="handleQuery"
|
||||
</el-col>
|
||||
<el-col :span="5">
|
||||
<el-form-item label="病人号:" prop="brdh">
|
||||
<el-input v-model="queryParams.brdh" clearable placeholder="请输入病人号" @keyup.enter="handleQuery"
|
||||
@clear="handleQuery" />
|
||||
</el-col>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="5">
|
||||
<el-form-item label="床号:" prop="ch">
|
||||
<el-input v-model="queryParams.ch" clearable placeholder="请输入床号" @keyup.enter="handleQuery"
|
||||
@clear="handleQuery" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="5">
|
||||
<el-form-item label="">
|
||||
<el-button icon="search" type="primary" @click="handleQuery">
|
||||
搜索
|
||||
</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
</el-form>
|
||||
</el-row>
|
||||
</div>
|
||||
<el-row :gutter="10">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="14" class="right-table">
|
||||
<el-row :gutter="10" class="mb8 mt10">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus">打印</el-button>
|
||||
<el-button type="primary" plain icon="Edit" @click="selectStatusRows">勾选所有未打印</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Edit" @click="selectStatusRows">勾选中所有未打印</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain :disabled="single" @click="printPdf">打印单张PDF报告</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="info" plain icon="Upload">GUID打印报告</el-button>
|
||||
<el-button type="primary" plain icon="Upload" @click="printPdf">打印报告</el-button>
|
||||
</el-col>
|
||||
|
||||
<right-toolbar v-model:showSearch="showSearch" @updateColumns="updateColumns" @queryTable="handleQuery"
|
||||
:columns="columns"></right-toolbar>
|
||||
<!-- <right-toolbar v-model:showSearch="showSearch" @updateColumns="updateColumns" @queryTable="handleQuery"
|
||||
:columns="columns"></right-toolbar> -->
|
||||
</el-row>
|
||||
|
||||
<CustomTable ref="tableRefs" :data="tableData" :columns="columns" :config="tableConfig" :loading="loading"
|
||||
@ -90,21 +102,22 @@
|
||||
|
||||
</el-col>
|
||||
<el-col :span="10" class="right-table">
|
||||
<div class="title">检验结果</div>
|
||||
<div class="mb10">
|
||||
<!-- <div class="title">检验结果</div> -->
|
||||
<div class="mb8 mt10">
|
||||
<el-button type="primary" @click="openDB">对比历史</el-button>
|
||||
<el-button type="primary" @click="copyData('All')">复制全部数据</el-button>
|
||||
<el-button type="primary" @click="copyData('N')">复制异常数据</el-button>
|
||||
<el-button type="primary" @click="copyData('Y')">复制正常数据</el-button>
|
||||
<el-button type="primary">知识库</el-button>
|
||||
<el-select class="ml10" placeholder="请选择复制" style="width: 140px" @change="copyData">
|
||||
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
<!-- <el-button type="primary">知识库</el-button> -->
|
||||
</div>
|
||||
|
||||
<CustomTable :data="rightTableData" :columns="rightColumns" :config="rightTableConfig" :loading="loading"
|
||||
@row-click="xmrowHandle">
|
||||
@row-click="xmrowHandle" ref="rightTableRef">
|
||||
</CustomTable>
|
||||
|
||||
<div class="title mt10">抗生素项目</div>
|
||||
<CustomTable :data="bottomTableData" :columns="bottomColumns" :config="bottomTableConfig" :loading="loading">
|
||||
<div class="mt10" v-if="bottomTableData.length > 0"></div>
|
||||
<CustomTable v-if="bottomTableData.length > 0" :data="bottomTableData" :columns="bottomColumns"
|
||||
:config="bottomTableConfig" :loading="loading">
|
||||
</CustomTable>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@ -115,9 +128,9 @@
|
||||
<div class="flex-between">
|
||||
|
||||
</div>
|
||||
<el-table :data="compareTableData" style="width: 100%" @row-click="handleRowClick" highlight-current-row
|
||||
<el-table :data="compareTableData" style="width: 100%" @row-click="handleRowClick" highlight-current-row border
|
||||
max-height="350px">
|
||||
<el-table-column prop="xmdh" label="项目编号" fixed align="center" width="100px" />
|
||||
<el-table-column prop="xmdh" label="项目编号" fixed align="center" width="150px" />
|
||||
<el-table-column prop="xmmc" label="项目名称" fixed align="center" />
|
||||
<template v-for="(period) in periods" :key="period">
|
||||
<el-table-column :label="period" :prop="period" :width="150" align="center" />
|
||||
@ -137,18 +150,27 @@ import { reportList, reportPrintPdf, reportResult, reportMedList, reportFsresult
|
||||
import dayjs from 'dayjs';
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { classCom } from '@/utils/classCom'
|
||||
import { HiprintPrinter } from '@/utils/hiprintPrinter';
|
||||
import * as echarts from 'echarts';
|
||||
//@ts-ignore
|
||||
import { comDict } from '@/utils/dict'
|
||||
const router = useRouter()
|
||||
import { usePrintStore } from '@/store/modules/printStore'
|
||||
//@ts-ignore
|
||||
import useUserStore from '@/store/modules/user'
|
||||
|
||||
const userStore = useUserStore()
|
||||
const compactForm = ref<HTMLElement | null>(null);
|
||||
const heightForm = ref(90);
|
||||
const dialogVisible = ref(false)
|
||||
const tableRefs = ref()
|
||||
|
||||
const myEcharts = ref()
|
||||
|
||||
const options = ref([
|
||||
{ label: '复制全部数据', value: 'All' },
|
||||
{ label: '复制异常数据', value: 'N' },
|
||||
{ label: '复制正常数据', value: 'Y' },
|
||||
]
|
||||
)
|
||||
interface QueryParams {
|
||||
times: string[]; // 明确类型为字符串元组
|
||||
alarmflag: boolean,
|
||||
@ -157,26 +179,29 @@ interface QueryParams {
|
||||
brly: string,
|
||||
brxm: string,
|
||||
brdh: string,
|
||||
sqh: string,
|
||||
ch: string,
|
||||
dybz: string,
|
||||
sqh: string,
|
||||
}
|
||||
|
||||
// 提交表单数据
|
||||
const queryParams = reactive<QueryParams>({
|
||||
times: ['2025-08-19', '2025-08-19'],
|
||||
ksdh: '',
|
||||
// ksdh: '0203',
|
||||
ksdh: '0210',
|
||||
brly: '',
|
||||
sqh: '25080109476',
|
||||
alarmflag: false,
|
||||
jzbz: false,
|
||||
brxm: '',
|
||||
brdh: '',
|
||||
sqh: '',
|
||||
ch: '',
|
||||
dybz: '',
|
||||
});
|
||||
const single = ref(true);
|
||||
const multiple = ref(true);
|
||||
const alarmflag = ref('0')
|
||||
const jzbz = ref('0')
|
||||
const alarmflag = ref()
|
||||
const jzbz = ref()
|
||||
const showSearch = ref(true);
|
||||
const queryRef = ref()
|
||||
// 项目点击数据
|
||||
@ -211,18 +236,19 @@ const rows = ref<any[]>([])
|
||||
const tableData = ref([])
|
||||
// 配置项
|
||||
const columns = ref<ColumnItem[]>([
|
||||
{ prop: 'dybz', label: '打印', visible: true, key: 0, slot: 'dybz', },
|
||||
{ prop: 'jzbz', label: '急诊', visible: true, key: 1, slot: 'jzbz', },
|
||||
{ prop: 'dybz', label: '打印', align: 'center', visible: true, key: 0, slot: 'dybz', width: '60px' },
|
||||
{ prop: 'jzbz', label: '急诊', align: 'center', visible: true, key: 1, slot: 'jzbz', },
|
||||
{ prop: 'alarmflag', label: '危急值', align: 'center', visible: true, key: 2, slot: 'alarmflag' },
|
||||
{ prop: 'jyrq', label: '检验日期', align: 'center', visible: true, key: 3, width: '150px' },
|
||||
{ prop: 'jyrq', label: '检验日期', align: 'center', visible: true, key: 3, sortable: true, width: '150px' },
|
||||
{ prop: 'brdh', label: '病人代号', align: 'center', visible: true, key: 4, width: '110px' },
|
||||
{ prop: 'ch', label: '床号', align: 'center', visible: true, key: 5, sortable: true, },
|
||||
{ prop: 'brxm', label: '病人姓名', align: 'center', visible: true, key: 4, },
|
||||
{ prop: 'brxbname', label: '性别', align: 'center', visible: true, key: 11, },
|
||||
{ prop: 'ch', label: '床号', align: 'center', visible: true, key: 5, },
|
||||
{ prop: 'yqdl', label: '仪器', align: 'center', visible: true, key: 6, width: '110px' },
|
||||
{ prop: 'ybh', label: '样本号', align: 'center', visible: true, key: 7, },
|
||||
{ prop: 'yblxname', label: '样本类型', align: 'center', visible: true, key: 8, },
|
||||
{ prop: 'jymd', label: '检验目的', align: 'center', visible: true, key: 9, width: '110px' },
|
||||
{ prop: 'brlyname', label: '病人类型', align: 'center', visible: true, key: 10, },
|
||||
{ prop: 'brxbname', label: '性别', align: 'center', visible: true, key: 11, },
|
||||
{ prop: 'yqmc', label: '仪器名称', align: 'center', visible: true, key: 12, width: '150px' },
|
||||
{ prop: 'yljg', label: '医疗机构', align: 'center', visible: true, key: 13, width: '150px' },
|
||||
])
|
||||
@ -233,6 +259,7 @@ const selectionChange = (selection: any) => {
|
||||
multiple.value = !selection.length;
|
||||
}
|
||||
|
||||
const rightTableRef = ref()
|
||||
const rowHandle = (row: any) => {
|
||||
Info.value = row
|
||||
const data = {
|
||||
@ -243,28 +270,33 @@ const rowHandle = (row: any) => {
|
||||
reportResult(data).then((res: any) => {
|
||||
if (res.code == 0) {
|
||||
rightTableData.value = res.data
|
||||
rightTableRef.value.setCurrentRow(res.data[0])
|
||||
xmrowHandle(res.data[0])
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 打印单张Pdf
|
||||
const printPdf = () => {
|
||||
const data = {
|
||||
jyrq: rows.value[0].jyrq,
|
||||
yq: rows.value[0].yq,
|
||||
ybh: rows.value[0].ybh
|
||||
}
|
||||
reportPrintPdf(data).then((res: any) => {
|
||||
const printStore = usePrintStore();
|
||||
const merge = rows.value.map((item: any) => { return `${item.jyrqname.replace(/-/g, '')}_${item.yq.trim()}_${item.ybh}` })
|
||||
// const merge = [
|
||||
// "20250819_11_1",
|
||||
// "20250819_11_10",
|
||||
// "20250819_11_11"
|
||||
// ]
|
||||
reportPrintPdf(merge).then((res: any) => {
|
||||
if (res.code == 0) {
|
||||
if (!res.data.base64PDF) return
|
||||
classCom.printPDF(res.data.base64PDF)
|
||||
classCom.printBase64PDF(res.data)
|
||||
// if (printStore.isConnected) {
|
||||
// HiprintPrinter.silentPrint([res.data])
|
||||
// } else {
|
||||
// classCom.printBase64PDF(res.data)
|
||||
// }
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// 单元格样式
|
||||
const cellStyleHd = ({ row, column, rowIndex, columnIndex }: {
|
||||
row: any;
|
||||
@ -287,7 +319,7 @@ const cellStyleHd = ({ row, column, rowIndex, columnIndex }: {
|
||||
const tableConfig = ref(
|
||||
{
|
||||
// stripe: true, // 斑马纹
|
||||
// border: true, // 边框
|
||||
border: true, // 边框
|
||||
selection: true, // 多选框
|
||||
index: false, // 序号
|
||||
height: '', // 高度
|
||||
@ -310,17 +342,19 @@ const alarmHandle = (val: boolean) => {
|
||||
if (val) {
|
||||
queryParams.jzbz = false
|
||||
alarmflag.value = '1'
|
||||
jzbz.value = null
|
||||
} else {
|
||||
alarmflag.value = '0'
|
||||
alarmflag.value = null
|
||||
}
|
||||
|
||||
}
|
||||
const jzbzHandle = (val: boolean) => {
|
||||
if (val) {
|
||||
queryParams.alarmflag = false
|
||||
alarmflag.value = null
|
||||
jzbz.value = '1'
|
||||
} else {
|
||||
jzbz.value = '0'
|
||||
jzbz.value = null
|
||||
}
|
||||
}
|
||||
|
||||
@ -356,10 +390,10 @@ const rightColumns = ref([
|
||||
const rightTableConfig = ref(
|
||||
{
|
||||
// stripe: true, // 斑马纹
|
||||
// border: true, // 边框
|
||||
border: true, // 边框
|
||||
selection: false, // 多选框
|
||||
index: false, // 序号
|
||||
height: '28vh', // 高度
|
||||
height: '40vh', // 高度
|
||||
highlightCurrentRow: true, // 高亮当前行
|
||||
}
|
||||
)
|
||||
@ -376,8 +410,18 @@ const xmrowHandle = (row: any) => {
|
||||
reportMedList(data).then((res: any) => {
|
||||
if (res.code == 200) {
|
||||
bottomTableData.value = res.rows
|
||||
if (res.rows.length > 0) {
|
||||
nextTick(() => {
|
||||
rightTableConfig.value.height = `calc(55vh - ${heightForm.value}px)`
|
||||
rightTableRef.value?.doLayout && rightTableRef.value.doLayout();
|
||||
});
|
||||
} else {
|
||||
nextTick(() => {
|
||||
rightTableConfig.value.height = `calc(93vh - ${heightForm.value}px)`
|
||||
rightTableRef.value?.doLayout && rightTableRef.value.doLayout();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
@ -385,9 +429,7 @@ const periods = ref<string[]>([])
|
||||
|
||||
const compareTableData = ref([])
|
||||
|
||||
const aaaa = () => {
|
||||
|
||||
}
|
||||
// 历史数据对比
|
||||
const openDB = () => {
|
||||
// 00507620
|
||||
@ -603,10 +645,10 @@ const bottomColumns = ref([
|
||||
const bottomTableConfig = ref(
|
||||
{
|
||||
// stripe: true, // 斑马纹
|
||||
// border: true, // 边框
|
||||
border: true, // 边框
|
||||
selection: false, // 多选框
|
||||
index: false, // 序号
|
||||
height: '28vh', // 高度
|
||||
height: '37vh', // 高度
|
||||
highlightCurrentRow: true, // 高亮当前行
|
||||
}
|
||||
)
|
||||
@ -626,6 +668,8 @@ onMounted(async () => {
|
||||
// const start = dayjs().subtract(1, 'day').format('YYYY-MM-DD HH:mm:ss'); //add 时间往后
|
||||
// queryParams.times = [start, end];
|
||||
// console.log(queryParams.times);
|
||||
// 进入页面单点登录
|
||||
userStore.loginAnonymous({ name: 'admin' })
|
||||
getList()
|
||||
adjustTableHeight();
|
||||
|
||||
@ -641,6 +685,7 @@ onMounted(async () => {
|
||||
|
||||
|
||||
const getList = () => {
|
||||
if (!queryParams.ksdh) return ElMessage.error('科室代号不能为空');
|
||||
const data = {
|
||||
alarmflag: alarmflag.value,
|
||||
jzbz: jzbz.value,
|
||||
@ -649,7 +694,7 @@ const getList = () => {
|
||||
brly: queryParams.brly,
|
||||
brxm: queryParams.brxm,
|
||||
brdh: queryParams.brdh,
|
||||
sqh: queryParams.sqh,
|
||||
ch: queryParams.ch,
|
||||
st: '',
|
||||
et: '',
|
||||
yljg: 1
|
||||
@ -676,11 +721,13 @@ watch(showSearch, () => {
|
||||
|
||||
function adjustTableHeight() {
|
||||
if (compactForm.value) {
|
||||
// 获取高度
|
||||
heightForm.value = compactForm.value.offsetHeight;
|
||||
tableConfig.value.height = `calc(80vh - ${heightForm.value}px)`;
|
||||
rightTableConfig.value.height = `calc(38vh - ${heightForm.value}px)`;
|
||||
bottomTableConfig.value.height = `calc(35vh - ${heightForm.value} }px)`;
|
||||
|
||||
nextTick(() => {
|
||||
tableConfig.value.height = `calc(93vh - ${heightForm.value}px)`
|
||||
tableRefs.value?.doLayout && tableRefs.value.doLayout();
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -688,7 +735,7 @@ function adjustTableHeight() {
|
||||
|
||||
<style scoped lang="scss">
|
||||
.right-table {
|
||||
border: 1px solid #dcdfe6;
|
||||
// border: 1px solid #dcdfe6;
|
||||
}
|
||||
|
||||
.title {
|
||||
|
||||
1061
src/views/index copy.vue
Normal file
1061
src/views/index copy.vue
Normal file
File diff suppressed because it is too large
Load Diff
1076
src/views/index.vue
1076
src/views/index.vue
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,7 @@
|
||||
<script setup>
|
||||
import { computed, reactive, ref, onMounted, nextTick } from "vue";
|
||||
import { getToken } from "@/utils/auth";
|
||||
import { queryComDictListService, addComDictService, updateComDictService, delComDictService } from "../../../api/liswork/dict/ComDict.js";
|
||||
import { queryComDictListService, addComDictService, updateComDictService, delComDictService } from "../../../api/liswork/dict/ComDict";
|
||||
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
|
||||
@ -1,55 +1,28 @@
|
||||
<template>
|
||||
<div class="dict-input-wrapper">
|
||||
<el-input
|
||||
v-model="displayValue"
|
||||
:placeholder="placeholder"
|
||||
:clearable="clearable"
|
||||
:disabled="isDictLoading || disabled"
|
||||
@blur="handleBlur"
|
||||
@clear="handleClear"
|
||||
@dblclick="handleDblClick"
|
||||
>
|
||||
<!-- <el-input v-model="displayValue" :placeholder="placeholder" :clearable="clearable"
|
||||
:disabled="isDictLoading || disabled" @blur="handleBlur" @clear="handleClear" @dblclick="handleDblClick">
|
||||
<template #prefix>
|
||||
<el-icon v-if="isDictLoading" size="16"><Loading /></el-icon>
|
||||
<el-icon v-if="isDictLoading" size="16">
|
||||
<Loading />
|
||||
</el-icon>
|
||||
</template>
|
||||
<template #suffix>
|
||||
<el-icon @click="openDictSelector" size="16" class="select-icon">
|
||||
<ArrowDown />
|
||||
</el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-input> -->
|
||||
|
||||
<!-- 字典选择弹窗 -->
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:title="dialogTitle"
|
||||
width="500px"
|
||||
@close="handleDialogClose"
|
||||
>
|
||||
<el-input
|
||||
v-model="searchKey"
|
||||
placeholder="搜索(支持名称、编码、简拼)..."
|
||||
class="mb-4"
|
||||
clearable
|
||||
@clear="filterDictData"
|
||||
@input="filterDictData"
|
||||
/>
|
||||
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="30vw" @close="handleDialogClose">
|
||||
<el-input v-model="searchKey" placeholder="搜索(支持名称、编码、简拼)..." class="mb10" clearable @clear="filterDictData"
|
||||
@input="filterDictData" />
|
||||
|
||||
<el-table
|
||||
:data="filteredDictData"
|
||||
height="300px"
|
||||
border
|
||||
@row-click="selectItem"
|
||||
@row-dblclick="selectItem"
|
||||
>
|
||||
<el-table-column prop="value" label="编码" width="100" />
|
||||
<el-table-column prop="label" label="名称" width="200" />
|
||||
<el-table-column prop="pinyin" label="简拼" width="150" /> <!-- 显示简拼便于调试 -->
|
||||
<el-table-column label="操作" width="100">
|
||||
<template #default="scope">
|
||||
<el-button size="small" type="primary" @click="selectItem(scope.row)">选择</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table :data="filteredDictData" height="300px" border @row-click="selectItem" @row-dblclick="selectItem">
|
||||
<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="100" /> <!-- 显示简拼便于调试 -->
|
||||
</el-table>
|
||||
</el-dialog>
|
||||
</div>
|
||||
|
||||
@ -1,133 +1,120 @@
|
||||
<template>
|
||||
<div class="compact-form">
|
||||
<el-col :span="24" :xs="24">
|
||||
<el-form :model="labPat" label-width="100px" class="compact-form" label-position="left">
|
||||
<el-form-item label="病人来源" label-width="70px">
|
||||
<el-col :span="16">
|
||||
<dict-input v-model="labPat.brly" :dict-type="'PT'" placeholder="请输入病人来源" :fetch-dict="fetchDict"
|
||||
@update:labelValue="(label) => labPat.brlyLabel = label" dialog-title="选择病人来源"
|
||||
@blur="handleFieldChange"
|
||||
@keyup.enter="handleFieldChange"
|
||||
@select="handleDictSelect"
|
||||
/>
|
||||
<div class="labpat_box">
|
||||
<div class="flex-between mb5">
|
||||
<el-input placeholder="条码号" class="mr10" style="width:100%" />
|
||||
<el-button type="primary">打印条码</el-button>
|
||||
</div>
|
||||
<el-form :model="labPat" label-width="70px" class="compact-form" label-position="right"
|
||||
:disabled="labPat.jgbz && labPat.jgbz != 0">
|
||||
<div :class="['sh_box', getColor(labPat.jgbz)]" v-if="labPat.jgbz != 0">
|
||||
<div>{{ getLableType(labPat.jgbz) }}</div>
|
||||
</div>
|
||||
<el-form-item label="病人来源">
|
||||
<el-col :span="14">
|
||||
<el-select v-model="labPat.brly" placeholder="请选择" style="width: 100%;" filterable
|
||||
@change="handleFieldChange">
|
||||
<el-option v-for="item in dictData.PT" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-switch v-model="jzbzSwitch" active-text="急诊" active-color="#FD0101" @change="handleFieldChange"></el-switch>
|
||||
<el-col :span="10">
|
||||
<el-switch v-model="jzbzSwitch" active-text="急诊" active-color="#FD0101"
|
||||
@change="handleFieldChange"></el-switch>
|
||||
</el-col>
|
||||
</el-form-item>
|
||||
<el-form-item label="病 历 号" label-width="70px">
|
||||
<el-input v-model="labPat.brdh" placeholder="请输入病历号"
|
||||
@blur="handleFieldChange"
|
||||
<el-form-item label="病 历 号">
|
||||
<el-input v-model="labPat.brdh" placeholder="请输入病历号" @blur="handleFieldChange"
|
||||
@keyup.enter="handleFieldChange"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="姓 名" label-width="70px">
|
||||
<el-input v-model="labPat.brxm" placeholder="请输入姓名"
|
||||
@blur="handleFieldChange"
|
||||
<el-form-item label="姓 名">
|
||||
<el-input v-model="labPat.brxm" placeholder="请输入姓名" @blur="handleFieldChange"
|
||||
@keyup.enter="handleFieldChange"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="性 别" label-width="70px">
|
||||
<el-col :span="8">
|
||||
<dict-input v-model="labPat.brxb" placeholder="性别" :dict-type="'SX'" :fetch-dict="fetchDict"
|
||||
@update:labelValue="(label) => labPat.brxbLabel = label"
|
||||
@blur="handleFieldChange"
|
||||
@keyup.enter="handleFieldChange"
|
||||
@select="handleDictSelect"
|
||||
/>
|
||||
<el-form-item label="性 别">
|
||||
<el-select v-model="labPat.brxb" placeholder="请选择" style="width: 100%;" @change="handleFieldChange">
|
||||
<el-option v-for="item in dictData.SX" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="年龄">
|
||||
<el-row :gutter="5">
|
||||
<el-col :span="14">
|
||||
<el-input v-model="labPat.nl" placeholder="年龄" @blur="handleFieldChange" @keyup.enter="handleFieldChange"
|
||||
style="width:100%"></el-input>
|
||||
</el-col>
|
||||
<el-col :span="4"><div>年龄</div></el-col>
|
||||
<el-col :span="6">
|
||||
<el-input v-model="labPat.nl" placeholder="年龄"
|
||||
@blur="handleFieldChange"
|
||||
<el-col :span="10">
|
||||
<el-select v-model="labPat.nldw" placeholder="请选择" style="width: 100%;" filterable
|
||||
@change="handleFieldChange">
|
||||
<el-option v-for="item in dictData.AU" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form-item>
|
||||
<el-form-item label="送检科室">
|
||||
<el-select v-model="labPat.ksdh" placeholder="请选择" style="width: 100%;" filterable @change="handleFieldChange">
|
||||
<el-option v-for="item in dictData.DP" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="床 号">
|
||||
<el-input v-model="labPat.ch" placeholder="请输入床号" @blur="handleFieldChange"
|
||||
@keyup.enter="handleFieldChange"></el-input>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<dict-input v-model="labPat.nldw" placeholder="年月" :dict-type="'AU'" :fetch-dict="fetchDict"
|
||||
@update:labelValue="(label) => labPat.nldwLabel = label"
|
||||
@blur="handleFieldChange"
|
||||
@keyup.enter="handleFieldChange"
|
||||
@select="handleDictSelect"
|
||||
/>
|
||||
</el-col>
|
||||
</el-form-item>
|
||||
<el-form-item label="送检科室" label-width="70px">
|
||||
<dict-input v-model="labPat.ksdh" placeholder="请输入科室" :dict-type="'DP'" :fetch-dict="fetchDict"
|
||||
@update:labelValue="(label) => labPat.ksdhLabel = label"
|
||||
@blur="handleFieldChange"
|
||||
@keyup.enter="handleFieldChange"
|
||||
@select="handleDictSelect"
|
||||
/>
|
||||
<el-form-item label="样本类型">
|
||||
<el-select v-model="labPat.yblx" placeholder="请选择" style="width: 100%;" @change="handleFieldChange" filterable>
|
||||
<el-option v-for="item in dictData.BT" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="床 号" label-width="70px">
|
||||
<el-input v-model="labPat.ch" placeholder="请输入床号"
|
||||
@blur="handleFieldChange"
|
||||
@keyup.enter="handleFieldChange"
|
||||
></el-input>
|
||||
<el-form-item label="申请医生">
|
||||
<el-select v-model="labPat.sjys" placeholder="请选择" style="width: 100%;" @change="handleFieldChange" filterable>
|
||||
<el-option v-for="item in dictData.SRD" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="样本类型" label-width="70px">
|
||||
<dict-input v-model="labPat.yblx" placeholder="请输入样本类型" :dict-type="'BT'" :fetch-dict="fetchDict"
|
||||
@update:labelValue="(label) => labPat.yblxLabel = label"
|
||||
@blur="handleFieldChange"
|
||||
@keyup.enter="handleFieldChange"
|
||||
@select="handleDictSelect"
|
||||
/>
|
||||
<el-form-item label="上机时间">
|
||||
<el-date-picker v-model="labPat.sqsj" type="datetime" placeholder="上机时间" format="YYYY-MM-DD HH:mm:ss"
|
||||
value-format="YYYY-MM-DD HH:mm:ss" @blur="handleFieldChange"
|
||||
@keyup.enter="handleFieldChange"></el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="申请医生" label-width="70px">
|
||||
<dict-input v-model="labPat.sjys" placeholder="请输入申请医生" :dict-type="'SRD'" :fetch-dict="fetchDict"
|
||||
@update:labelValue="(label) => labPat.sjysLabel = label"
|
||||
@blur="handleFieldChange"
|
||||
@keyup.enter="handleFieldChange"
|
||||
@select="handleDictSelect"
|
||||
/>
|
||||
<el-form-item label="采样时间">
|
||||
<el-date-picker v-model="labPat.cyrq" type="datetime" placeholder="采样时间" format="YYYY-MM-DD HH:mm:ss"
|
||||
value-format="YYYY-MM-DD HH:mm:ss" @blur="handleFieldChange"
|
||||
@keyup.enter="handleFieldChange"></el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="上机时间" label-width="70px">
|
||||
<el-date-picker v-model="labPat.sqsj" type="datetime" placeholder="上机时间" format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss"
|
||||
@blur="handleFieldChange"
|
||||
@keyup.enter="handleFieldChange"
|
||||
></el-date-picker>
|
||||
<el-form-item label="报告时间">
|
||||
<el-date-picker v-model="labPat.dysj" type="datetime" placeholder="报告时间" format="YYYY-MM-DD HH:mm:ss"
|
||||
value-format="YYYY-MM-DD HH:mm:ss" @blur="handleFieldChange"
|
||||
@keyup.enter="handleFieldChange"></el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="采样时间" label-width="70px">
|
||||
<el-date-picker v-model="labPat.cyrq" type="datetime" placeholder="采样时间" format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss"
|
||||
@blur="handleFieldChange"
|
||||
@keyup.enter="handleFieldChange"
|
||||
></el-date-picker>
|
||||
<el-form-item label="临床诊断">
|
||||
<el-input v-model="labPat.zd" placeholder="请输入临床诊断" @blur="handleFieldChange"
|
||||
@keyup.enter="handleFieldChange"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="报告时间" label-width="70px">
|
||||
<el-date-picker v-model="labPat.dysj" type="datetime" placeholder="报告时间" format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss"
|
||||
@blur="handleFieldChange"
|
||||
@keyup.enter="handleFieldChange"
|
||||
></el-date-picker>
|
||||
<el-form-item label="备 注">
|
||||
<el-input v-model="labPat.bz" placeholder="请输入备注" @blur="handleFieldChange"
|
||||
@keyup.enter="handleFieldChange"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="临床诊断" label-width="70px">
|
||||
<el-input v-model="labPat.zd" placeholder="请输入临床诊断" @blur="handleFieldChange" @keyup.enter="handleFieldChange"></el-input>
|
||||
<el-form-item label="检验医生">
|
||||
<el-input v-model="labPat.yhdh" placeholder="请输入检验医生" @blur="handleFieldChange"
|
||||
@keyup.enter="handleFieldChange"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="备 注" label-width="70px">
|
||||
<el-input v-model="labPat.bz" placeholder="请输入备注" @blur="handleFieldChange" @keyup.enter="handleFieldChange"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="检验医生" label-width="70px">
|
||||
<el-input v-model="labPat.yhdh" placeholder="请输入检验医生" @blur="handleFieldChange" @keyup.enter="handleFieldChange"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="审核医生" label-width="70px">
|
||||
<el-input v-model="labPat.hdys" placeholder="请输入审核医生" @blur="handleFieldChange" @keyup.enter="handleFieldChange"></el-input>
|
||||
<el-form-item label="审核医生">
|
||||
<el-input v-model="labPat.hdys" placeholder="请输入审核医生" @blur="handleFieldChange"
|
||||
@keyup.enter="handleFieldChange"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="审核状态">
|
||||
<el-radio-group v-model="labPat.jgbz">
|
||||
<el-radio :label="0">未审核</el-radio>
|
||||
<el-radio :label="2">已审核</el-radio>
|
||||
<el-radio :label="'0'">未审核</el-radio>
|
||||
<el-radio :label="'2'">已审核</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
|
||||
</el-form>
|
||||
<div class="compact-form">
|
||||
<el-button type="primary" @click="saveMain">保存</el-button>
|
||||
<el-button @click="resetMain">重置</el-button>
|
||||
</div>
|
||||
</el-col>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import DictInput from './DictInput.vue';
|
||||
import {changepatcolumn, updateLabPat} from "@/api/liswork/work/LisWork.js";
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, watch, toRaw, computed, onMounted } from 'vue';
|
||||
import { changepatcolumn, updateLabPat } from "@/api/liswork/work/LisWork";
|
||||
//@ts-ignore
|
||||
import { comDict } from '@/utils/dict'
|
||||
const loading = ref(true);
|
||||
const props = defineProps({
|
||||
labPat: {
|
||||
@ -136,108 +123,121 @@ const props = defineProps({
|
||||
},
|
||||
//结果主键
|
||||
labPatKey: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
});
|
||||
// 计算属性:将布尔值转换为 0/1 绑定到 labPat.jzbz
|
||||
const jzbzSwitch = computed({
|
||||
get() {
|
||||
// 后端返回的 0/1 转换为布尔值(供开关显示)
|
||||
return props.labPat.jzbz == "1";
|
||||
type: Object,
|
||||
default: () => { }
|
||||
},
|
||||
set(checked) {
|
||||
// 开关的 true/false 转换为 1/0 存到实体中
|
||||
props.labPat.jzbz = checked ? "1" : "0";
|
||||
dictData: {
|
||||
type: Object,
|
||||
default: () => { }
|
||||
}
|
||||
});
|
||||
|
||||
watch(() => props.labPat, (newVal) => {
|
||||
lastValue.value = JSON.stringify(newVal);
|
||||
})
|
||||
// 计算属性:将布尔值转换为 0/1 绑定到 labPat.jzbz
|
||||
const jzbzSwitch = ref(0);
|
||||
const emit = defineEmits(['update:labPat']);
|
||||
// 通过inject获取全局方法
|
||||
const comDict = inject('comDict');
|
||||
const lastValue = ref(JSON.stringify(props.labPat));
|
||||
const prevFieldState = ref(null); // 记录当前修改的字段及旧值 { field: '字段名', oldValue: 旧值 }
|
||||
const lastValue = ref('');
|
||||
/**
|
||||
* 通用字段变化处理(失焦、回车触发)
|
||||
*/
|
||||
const handleFieldChange = async () => {
|
||||
await triggerApiUpdate();
|
||||
// 将当前labPat转为字符串用于比较
|
||||
const currentValue = JSON.stringify(props.labPat);
|
||||
// 对比与上一次保存的值是否有变化
|
||||
if (currentValue !== lastValue.value) {
|
||||
// 找出变化的字段
|
||||
const oldObj = JSON.parse(lastValue.value);
|
||||
const newObj = props.labPat;
|
||||
const changedField = getChangedField(oldObj, newObj);
|
||||
console.log('changedField==>', changedField);
|
||||
console.log('oldObj, newObj==>', oldObj, newObj);
|
||||
if (changedField) {
|
||||
// 这里可以添加实际的更新逻辑,比如调用接口
|
||||
try {
|
||||
changepatcolumn({ ...props.labPatKey, column: changedField?.field, value: changedField?.newValue }).then((res: any) => {
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('更新失败:', error);
|
||||
// 失败时可以恢复旧值
|
||||
emit('update:labPat', oldObj);
|
||||
lastValue.value = JSON.stringify(oldObj);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 完善字段变化检测方法
|
||||
const getChangedField = (oldObj: { [key: string]: any }, newObj: { [key: string]: any }) => {
|
||||
const oldKeys = Object.keys(oldObj);
|
||||
for (const key of oldKeys) {
|
||||
const oldVal = oldObj[key];
|
||||
const newVal = newObj[key];
|
||||
|
||||
if (oldVal instanceof Date && newVal instanceof Date) {
|
||||
if (oldVal.getTime() !== newVal.getTime()) {
|
||||
return { field: key, oldValue: oldVal, newValue: newVal };
|
||||
}
|
||||
} else if (oldVal !== newVal) {
|
||||
return { field: key, oldValue: oldVal, newValue: newVal };
|
||||
}
|
||||
}
|
||||
|
||||
const newKeys = Object.keys(newObj);
|
||||
for (const key of newKeys) {
|
||||
if (!(key in oldObj)) {
|
||||
return { field: key, oldValue: undefined, newValue: newObj[key] };
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
|
||||
const getLableType = (type: string) => {
|
||||
switch (type) {
|
||||
case '1':
|
||||
return '初审';
|
||||
case '2':
|
||||
return '已审核';
|
||||
case '3':
|
||||
return '初报';
|
||||
case '4':
|
||||
return '二报';
|
||||
case '5':
|
||||
return '锁定';
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
const getColor = (type: string) => {
|
||||
switch (type) {
|
||||
case '1':
|
||||
return 'cs_color';
|
||||
case '2':
|
||||
return 'sh_color';
|
||||
case '3':
|
||||
return 'cb_color';
|
||||
case '4':
|
||||
return 'eb_color';
|
||||
case '5':
|
||||
return 'sd_color';
|
||||
default:
|
||||
return 'default';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 字典选择完成处理(弹窗选择后触发)
|
||||
*/
|
||||
const handleDictSelect = async () => {
|
||||
// 字典选择后直接触发更新
|
||||
await triggerApiUpdate();
|
||||
};
|
||||
/**
|
||||
* 对比新旧对象,找出修改的字段及旧值
|
||||
* @param oldObj 旧对象
|
||||
* @param newObj 新对象
|
||||
* @returns { field: string, oldValue: any } | null
|
||||
*/
|
||||
const getChangedField = (oldObj, newObj) => {
|
||||
const oldKeys = Object.keys(oldObj);
|
||||
for (const key of oldKeys) {
|
||||
if (newObj[key] !== oldObj[key]) {
|
||||
return { field: key, oldValue: oldObj[key], newValue: newObj[key] };
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
/**
|
||||
* 触发API更新的核心方法
|
||||
*/
|
||||
const triggerApiUpdate = async () => {
|
||||
const currentLabPat = toRaw(props.labPat);
|
||||
const currentValue = JSON.stringify(currentLabPat);
|
||||
const oldValue = lastValue.value;
|
||||
// 只有值发生变化时才调用API
|
||||
if (currentValue !== lastValue.value) {
|
||||
// 2. 找出修改的字段及旧值(用于回滚)
|
||||
const oldObj = JSON.parse(oldValue);
|
||||
const changedField = getChangedField(oldObj, currentLabPat);
|
||||
prevFieldState.value = changedField; // 记录修改前的状态
|
||||
console.log('prevFieldState:', prevFieldState.value)
|
||||
console.log('labPatKey:', props.labPatKey)
|
||||
try {
|
||||
loading.value = true;
|
||||
changepatcolumn({...props.labPatKey,column:changedField?.field,value:changedField?.newValue}).then(response => {
|
||||
console.log('response:', response)
|
||||
console.log('表单更新成功');
|
||||
lastValue.value = currentValue;
|
||||
loading.value = false;
|
||||
}) .catch(error => {
|
||||
console.error('表单更新失败', error);
|
||||
loading.value = false;
|
||||
if (prevFieldState.value) {
|
||||
const { field, oldValue,newValue } = prevFieldState.value;
|
||||
// 回滚字段值(通过emit触发父组件更新,避免直接修改props)
|
||||
emit('update:labPat', {
|
||||
...toRaw(props.labPat),
|
||||
[field]: oldValue
|
||||
});
|
||||
} else {
|
||||
// 若未找到具体字段,整体回滚
|
||||
emit('update:labPat', JSON.parse(oldValue));
|
||||
}
|
||||
// 回滚后更新缓存
|
||||
lastValue.value = oldValue;
|
||||
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('更新接口调用失败:', error);
|
||||
}finally {
|
||||
loading.value = false;
|
||||
prevFieldState.value = null; // 清空临时记录
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
};
|
||||
// 手动保存
|
||||
const saveMain = async () => {
|
||||
await triggerApiUpdate();
|
||||
};
|
||||
// 重置方法
|
||||
const resetMain = () => {
|
||||
const resetData = {
|
||||
@ -257,20 +257,104 @@ const resetMain = () => {
|
||||
lastValue.value = JSON.stringify(resetData);
|
||||
};
|
||||
|
||||
// 字典获取方法(适配子组件)
|
||||
const fetchDict = async (dictType) => {
|
||||
const dictRefs = await comDict(dictType);
|
||||
// 根据实际字典结构返回数组(需与子组件匹配)
|
||||
return dictRefs[dictType]?.value || [];
|
||||
};
|
||||
// interface DictData {
|
||||
// PT?: Array<any>;
|
||||
// AU?: Array<any>;
|
||||
// SX?: Array<any>;
|
||||
// DP?: Array<any>;
|
||||
// BT?: Array<any>;
|
||||
// SRD?: Array<any>;
|
||||
// [key: string]: any[] | undefined; // 添加索引签名以支持动态访问
|
||||
// }
|
||||
// // 字典数据存储
|
||||
// const dictData = ref<DictData>({});
|
||||
|
||||
// onMounted(async () => {
|
||||
// // 加载病人来源字典
|
||||
// const dictRefs = await comDict('PT', 'AU', 'SX', 'DP', 'BT', 'SRD');
|
||||
|
||||
// // 从 ref 中获取实际数据
|
||||
// dictData.value = {
|
||||
// PT: toRaw(dictRefs.PT.value) || [],
|
||||
// AU: toRaw(dictRefs.AU.value) || [],
|
||||
// SX: toRaw(dictRefs.SX.value) || [],
|
||||
// DP: toRaw(dictRefs.DP.value) || [],
|
||||
// BT: toRaw(dictRefs.BT.value) || [],
|
||||
// SRD: toRaw(dictRefs.SRD.value) || [],
|
||||
// };
|
||||
// });
|
||||
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.compact-form .el-form-item {
|
||||
margin-bottom: 10px;
|
||||
.labpat_box {
|
||||
height: calc(90vh - 95px);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.compact-form .el-form-item__label {
|
||||
.flex-between {
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.compact-form {
|
||||
flex: 1;
|
||||
position: relative;
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
|
||||
|
||||
.el-form-item {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.el-form-item__label {
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
// pointer-events: none;
|
||||
}
|
||||
|
||||
.sh_box {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0);
|
||||
z-index: 9;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
writing-mode: vertical-rl;
|
||||
font-weight: 500;
|
||||
font-size: 137px;
|
||||
|
||||
// pointer-events: none;
|
||||
}
|
||||
|
||||
.cs_color {
|
||||
color: rgba(40, 189, 187, 0.44);
|
||||
}
|
||||
|
||||
.sh_color {
|
||||
color: rgba(238, 8, 8, 0.44);
|
||||
}
|
||||
|
||||
.cb_color {
|
||||
color: rgba(255, 165, 0, 0.44);
|
||||
}
|
||||
|
||||
.eb_color {
|
||||
color: rgba(0, 128, 0, 0.44);
|
||||
}
|
||||
|
||||
.sd_color {
|
||||
color: rgba(128, 128, 128, 0.44);
|
||||
}
|
||||
|
||||
.default {
|
||||
color: rgba(40, 189, 187, 0.44);
|
||||
}
|
||||
</style>
|
||||
@ -1,94 +1,68 @@
|
||||
<template>
|
||||
<div class="table-container">
|
||||
<el-input
|
||||
v-model="searchText"
|
||||
placeholder="输入条码号搜索"
|
||||
class="mb-4"
|
||||
@keyup.enter="search"
|
||||
>
|
||||
<template #append>
|
||||
<el-button @click="search">搜索</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
<el-table
|
||||
:data="labPatList"
|
||||
stripe
|
||||
class="card-content"
|
||||
:header-cell-style="headerCellStyle"
|
||||
:cell-style="cellStyle"
|
||||
@row-click="handleRowClick"
|
||||
style="width: 100%"
|
||||
border
|
||||
|
||||
>
|
||||
<el-table-column prop="finish" label="完成" width="70">
|
||||
<vxe-table :data="labPatList" :loading="loading" border height="auto" class="mytable-style"
|
||||
:row-config="{ isHover: true, height: 30 }" show-overflow @current-change="handleRowClick" ref="tableRef"
|
||||
:current-row="currentRow" highlight-current-row round row-id="ybh">
|
||||
<vxe-column field="finish" title="完成" width="60" align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.finish === 1 ? '已完成' : '未完成' }}</span>
|
||||
<span>{{ scope.row.finish == 1 ? '✅' : '❌' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="jgbz" label="审核" width="25" align="center" header-align="center" >
|
||||
</vxe-column>
|
||||
<vxe-column field="jgbz" title="审核" width="60" align="center">
|
||||
<template #default="scope">
|
||||
<el-checkbox :model-value="scope.row.jgbz === '2'" disabled>
|
||||
</el-checkbox>
|
||||
<el-checkbox v-model="scope.row.jgbz" true-value="2" disabled />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="alarmflag" label="报警" width="25">
|
||||
</vxe-column>
|
||||
<vxe-column field="alarmflag" title="报警" width="60" align="center">
|
||||
<template #default="scope">
|
||||
<el-checkbox :model-value="scope.row.alarmflag === '1'" disabled>
|
||||
</el-checkbox>
|
||||
<el-checkbox :model-value="scope.row.alarmflag == '1'" disabled />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="brly" label="类型" width="50" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column prop="autojgbz" label="自审" width="25" >
|
||||
</vxe-column>
|
||||
<vxe-column field="brly" title="类型" width="60" align="center">
|
||||
<template #default="scope">
|
||||
{{ formatDict(scope.row.brly, 'PT') }}
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="autojgbz" title="自审" width="60" align="center">
|
||||
<template #default="scope">
|
||||
<el-checkbox :model-value="scope.row.autojgbz === '1'" disabled>
|
||||
</el-checkbox>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="ybh" label="样本号" width="80" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column prop="brxm" label="病人姓名" width="100" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column prop="brdh" label="病历号" width="80" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column prop="ch" label="床号" width="80" show-overflow-tooltip ></el-table-column>
|
||||
<el-table-column prop="brxb" label="病人性别" width="80" show-overflow-tooltip ></el-table-column>
|
||||
<el-table-column prop="nl" label="年" width="40" show-overflow-tooltip ></el-table-column>
|
||||
<el-table-column prop="nldw" label="龄" width="30" show-overflow-tooltip ></el-table-column>
|
||||
<el-table-column prop="ksdh" label="科室" width="80" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column prop="yblx" label="标本" width="80" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column prop="dybz" label="打印" width="25" show-overflow-tooltip >
|
||||
</vxe-column>
|
||||
<vxe-column field="ybh" title="样本号" width="120" align="center" />
|
||||
<vxe-column field="brxm" title="病人姓名" width="120" align="center" />
|
||||
<vxe-column field="brdh" title="病历号" width="120" align="center" />
|
||||
<vxe-column field="ch" title="床号" width="60" align="center" />
|
||||
<vxe-column field="brxb" title="病人性别" width="100" align="center" />
|
||||
<vxe-column field="nl" title="年" width="60" align="center" />
|
||||
<vxe-column field="nldw" title="龄" width="60" align="center" />
|
||||
<vxe-column field="ksdh" title="科室" width="60" align="center" />
|
||||
<vxe-column field="yblx" title="标本" width="60" align="center" />
|
||||
<vxe-column field="dybz" title="打印" width="60" show-overflow align="center">
|
||||
<template #default="scope">
|
||||
<el-checkbox :model-value="scope.row.dybz === '1'" disabled>
|
||||
</el-checkbox>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="fslx" label="发送" width="25">
|
||||
</vxe-column>
|
||||
<vxe-column field="fslx" title="发送" width="60" align="center">
|
||||
<template #default="scope">
|
||||
<el-checkbox :model-value="scope.row.dybz === '1'" disabled>
|
||||
</el-checkbox>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="shcs" label="次数" width="25" show-overflow-tooltip ></el-table-column>
|
||||
<el-table-column prop="sqh" label="申请号/条码" width="100" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column prop="jymd" label="检验目的" width="100" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column prop="yhdh" label="检验医生" width="80" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column prop="yljg" label="送检医院" width="80" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column prop="jyrq" label="检验日期" v-if="false"></el-table-column>
|
||||
<el-table-column prop="yq" label="仪器" v-if="false"></el-table-column>
|
||||
</el-table>
|
||||
<el-pagination
|
||||
class="mt-4"
|
||||
background
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="total"
|
||||
:page-sizes="[5, 10, 15, 20]"
|
||||
:page-size="pageSize"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
>
|
||||
</el-pagination>
|
||||
</vxe-column>
|
||||
<vxe-column field="shcs" title="次数" show-overflow width="60" align="center" />
|
||||
<vxe-column field="sqh" title="申请号/条码" width="150" show-overflow align="center" />
|
||||
<vxe-column field="jymd" title="检验目的" show-overflow width="120" align="center" />
|
||||
<vxe-column field="yhdh" title="检验医生" show-overflow width="120" align="center" />
|
||||
<vxe-column field="yljg" title="送检医院" show-overflow width="120" align="center" />
|
||||
|
||||
</vxe-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, nextTick } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
labPatList: {
|
||||
type: Array,
|
||||
@ -97,110 +71,74 @@ const props = defineProps({
|
||||
total: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
dictData: {
|
||||
type: Object,
|
||||
default: () => { }
|
||||
}
|
||||
})
|
||||
|
||||
const emits = defineEmits(['select', 'search', 'page-change'])
|
||||
const tableRef = ref<any>();
|
||||
const emits = defineEmits(['select', 'search',])
|
||||
|
||||
const searchText = ref('')
|
||||
const pageSize = ref(15)
|
||||
const currentPage = ref(1)
|
||||
|
||||
const search = () => {
|
||||
emits('search', searchText.value, currentPage.value, pageSize.value)
|
||||
}
|
||||
|
||||
const handleRowClick = (row) => {
|
||||
const currentRow = ref<any>(null);
|
||||
const handleRowClick = ({ row }: { row: any }) => {
|
||||
emits('select', row)
|
||||
}
|
||||
const setCurrentRow = (row: any) => {
|
||||
tableRef.value.setCurrentRow(row)
|
||||
|
||||
const handleSizeChange = (val) => {
|
||||
pageSize.value = val
|
||||
emits('page-change', currentPage.value, pageSize.value)
|
||||
}
|
||||
|
||||
const handleCurrentChange = (val) => {
|
||||
currentPage.value = val
|
||||
emits('page-change', currentPage.value, pageSize.value)
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
emits('page-change', currentPage.value, pageSize.value)
|
||||
nextTick(() => {
|
||||
tableRef.value.scrollToRow(row)
|
||||
})
|
||||
// 设置列头颜色
|
||||
const headerCellStyle = ({ row, column, rowIndex, columnIndex }) => {
|
||||
return {
|
||||
// backgroundColor: '#A6CAF0', // 浅蓝色
|
||||
color: '#0050b3', // 文字颜色
|
||||
fontWeight: 'bold' // 文字加粗
|
||||
};
|
||||
};
|
||||
//设置内容格式
|
||||
const cellStyle = ({ row, column, rowIndex, columnIndex }) => {
|
||||
// console.log('检查单元格样式:', row, column); // 调试输出
|
||||
|
||||
// 使用 === 比较时注意值的类型(数字 vs 字符串)
|
||||
if (column.property === 'finish' && row.status === '1') {
|
||||
return {
|
||||
backgroundColor: '#006400', // 使用驼峰式写法(可选)
|
||||
fontWeight: 'bold',
|
||||
color: 'white', // 添加文字颜色,确保可读性
|
||||
height: '25px',
|
||||
lineHeight: '25px'
|
||||
};
|
||||
}
|
||||
|
||||
if (column.property === 'jgbz' && row.status === '2') {
|
||||
return {
|
||||
backgroundColor: '#FF69B4',
|
||||
fontWeight: 'bold',
|
||||
height: '25px',
|
||||
lineHeight: '25px'
|
||||
};
|
||||
}
|
||||
|
||||
if (column.property === 'alarmflag' && row.status === '1') {
|
||||
return {
|
||||
backgroundColor: '#FF0000',
|
||||
fontWeight: 'bold',
|
||||
color: 'white',
|
||||
height: '25px',
|
||||
lineHeight: '25px'
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
height: '25px',
|
||||
lineHeight: '25px',
|
||||
padding: '0 0px'
|
||||
}; // 默认不设置样式
|
||||
// 字典格式化方法
|
||||
const formatDict = (v: string, dictType: string) => {
|
||||
return props.dictData[dictType]?.find((item: any) => item.value == v)?.label;
|
||||
};
|
||||
|
||||
|
||||
// 导出方法
|
||||
defineExpose({
|
||||
setCurrentRow,
|
||||
tableRef,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.compact-form .el-form-item {
|
||||
padding: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.compact-form .el-form-item__label {
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
.card-content {
|
||||
max-height: 620px; /* 设置最大高度 */
|
||||
overflow-y: auto; /* 超出高度时显示垂直滚动条 */
|
||||
padding: 10px; /* 保持与卡片默认一致的内边距 */
|
||||
}
|
||||
.clickable:hover {
|
||||
cursor: pointer; /* 鼠标悬停时显示手型 */
|
||||
transition: all 0.3s; /* 平滑过渡效果 */
|
||||
color: blue;
|
||||
|
||||
}
|
||||
.card-content.el-table__row.current-row {
|
||||
background-color: #e6f4ff !important;
|
||||
color: #0050b3 !important; /* 文字颜色 */
|
||||
.table-container {
|
||||
height: calc(90vh - 250px);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.card-content.el-table__row.current-row:hover {
|
||||
background-color: #d6e8ff !important;
|
||||
.vxe-table--border tbody tr,
|
||||
.vxe-table--border td,
|
||||
.vxe-table--border th {
|
||||
border-color: #f00 !important;
|
||||
/* 设置边框颜色为红色 */
|
||||
}
|
||||
|
||||
/* 2. 表头区域边框 */
|
||||
::v-deep .vxe-header--row th {
|
||||
border-color: #1F6DD3 !important;
|
||||
}
|
||||
|
||||
/* 3. 内容区域边框 */
|
||||
::v-deep .vxe-body--row td {
|
||||
border-color: #409eff !important;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.mytable-style {
|
||||
flex: 1;
|
||||
}
|
||||
</style>
|
||||
193
src/views/liswork/work/components/labpatlist2.vue
Normal file
193
src/views/liswork/work/components/labpatlist2.vue
Normal file
@ -0,0 +1,193 @@
|
||||
<template>
|
||||
<div class="table-container">
|
||||
<el-table :data="labPatList" class="card-content" :cell-style="cellStyle" @row-click="handleRowClick" border
|
||||
height="100%" highlight-current-row ref="tableRef" v-loading="loading" :row-style="{ height: '30px' }"
|
||||
:row-key="(row: any) => row.ybh">
|
||||
<el-table-column prop="finish" label="完成" align="center" width="60px">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.finish === 1 ? '✅' : '❌' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="jgbz" label="审核" align="center" width="60px">
|
||||
<template #default="scope">
|
||||
<el-checkbox v-model="scope.row.jgbz" true-value="2" disabled />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="alarmflag" label="报警" align="center" width="60px">
|
||||
<template #default="scope">
|
||||
<el-checkbox :model-value="scope.row.alarmflag == '1'" disabled />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="brly" label="类型" align="center" width="60px">
|
||||
<template #default="scope">
|
||||
{{ formatDict(scope.row.brly, 'PT') }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="autojgbz" label="自审" align="center" width="60px">
|
||||
<template #default="scope">
|
||||
<el-checkbox :model-value="scope.row.autojgbz === '1'" disabled>
|
||||
</el-checkbox>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="ybh" label="样本号" align="center" />
|
||||
<el-table-column prop="brxm" label="病人姓名" align="center" />
|
||||
<el-table-column prop="brdh" label="病历号" align="center" width="120" />
|
||||
<el-table-column prop="ch" label="床号" align="center" />
|
||||
<el-table-column prop="brxb" label="病人性别" align="center" />
|
||||
<el-table-column prop="nl" label="年" align="center" />
|
||||
<el-table-column prop="nldw" label="龄" align="center" />
|
||||
<el-table-column prop="ksdh" label="科室" align="center" />
|
||||
<el-table-column prop="yblx" label="标本" align="center" />
|
||||
<el-table-column prop="dybz" label="打印" align="center" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<el-checkbox :model-value="scope.row.dybz === '1'" disabled>
|
||||
</el-checkbox>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="fslx" label="发送" align="center">
|
||||
<template #default="scope">
|
||||
<el-checkbox :model-value="scope.row.dybz === '1'" disabled>
|
||||
</el-checkbox>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="shcs" label="次数" align="center" show-overflow-tooltip />
|
||||
<el-table-column prop="sqh" label="申请号/条码" width="150" show-overflow-tooltip />
|
||||
<el-table-column prop="jymd" label="检验目的" show-overflow-tooltip align="center" width="120px" />
|
||||
<el-table-column prop="yhdh" label="检验医生" align="center" show-overflow-tooltip />
|
||||
<el-table-column prop="yljg" label="送检医院" align="center" show-overflow-tooltip />
|
||||
</el-table>
|
||||
<el-pagination class="mt10 page-box" background layout="total, sizes, prev, pager, next, jumper" :total="total"
|
||||
:page-sizes="[10, 20, 30, 50]" v-model:current-page="currentPage" v-model:page-size="pageSize"
|
||||
@size-change="handleSizeChange" @current-change="handleCurrentChange">
|
||||
</el-pagination>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, nextTick } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
labPatList: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
total: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
dictData: {
|
||||
type: Object,
|
||||
default: () => { }
|
||||
}
|
||||
})
|
||||
const tableRef = ref()
|
||||
const emits = defineEmits(['select', 'search', 'page-change'])
|
||||
const pageSize = ref(50)
|
||||
const currentPage = ref(1)
|
||||
const searchText = ref('')
|
||||
|
||||
|
||||
const setCurrentRow = (index: number, row: any) => {
|
||||
tableRef.value.setCurrentRow(row)
|
||||
nextTick(() => {
|
||||
tableRef.value.setScrollTop(32 * index)
|
||||
})
|
||||
}
|
||||
const doLayout = () => {
|
||||
tableRef.value?.doLayout();
|
||||
};
|
||||
|
||||
const handleSizeChange = (val: number) => {
|
||||
pageSize.value = val
|
||||
emits('page-change', currentPage.value, pageSize.value)
|
||||
}
|
||||
|
||||
const handleCurrentChange = (val: number) => {
|
||||
currentPage.value = val
|
||||
emits('page-change', currentPage.value, pageSize.value)
|
||||
}
|
||||
// 字典格式化方法
|
||||
const formatDict = (v: string, dictType: string) => {
|
||||
return props.dictData[dictType]?.find((item: any) => item.value == v)?.label;
|
||||
};
|
||||
|
||||
// 导出方法
|
||||
defineExpose({
|
||||
setCurrentRow,
|
||||
doLayout,
|
||||
tableRef,
|
||||
});
|
||||
const search = () => {
|
||||
// emits('search', searchText.value, currentPage.value, pageSize.value)
|
||||
}
|
||||
|
||||
const handleRowClick = (row: any) => {
|
||||
emits('select', row)
|
||||
}
|
||||
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
})
|
||||
|
||||
//设置内容格式
|
||||
const cellStyle = ({ row, column }: { row: any, column: any }) => {
|
||||
// console.log('检查单元格样式:', row, column); // 调试输出
|
||||
|
||||
// 使用 === 比较时注意值的类型(数字 vs 字符串)
|
||||
if (column.property === 'finish' && row.status === '1') {
|
||||
return {
|
||||
backgroundColor: '#006400', // 使用驼峰式写法(可选)
|
||||
fontWeight: 'bold',
|
||||
color: 'white', // 添加文字颜色,确保可读性
|
||||
height: '25px',
|
||||
lineHeight: '25px'
|
||||
};
|
||||
}
|
||||
|
||||
if (column.property === 'jgbz' && row.status === '2') {
|
||||
return {
|
||||
backgroundColor: '#FF69B4',
|
||||
fontWeight: 'bold',
|
||||
height: '25px',
|
||||
lineHeight: '25px'
|
||||
};
|
||||
}
|
||||
|
||||
if (column.property === 'alarmflag' && row.status === '1') {
|
||||
return {
|
||||
backgroundColor: '#FF0000',
|
||||
fontWeight: 'bold',
|
||||
color: 'white',
|
||||
height: '25px',
|
||||
lineHeight: '25px'
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
height: '25px',
|
||||
lineHeight: '25px',
|
||||
padding: '0 0px'
|
||||
}; // 默认不设置样式
|
||||
};
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.table-container {
|
||||
height: calc(90vh - 250px);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
|
||||
.card-content {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.page-box {
|
||||
height: 32px;
|
||||
}
|
||||
</style>
|
||||
@ -1,84 +1,429 @@
|
||||
<template>
|
||||
<div class="compact-form">
|
||||
<el-table
|
||||
:data="tableData"
|
||||
border
|
||||
stripe
|
||||
highlight-current-row
|
||||
@selection-change="handleSelectionChange"
|
||||
class="custom-table-container"
|
||||
height="640px"
|
||||
style="width: 100%; --table-row-height: 32px;"
|
||||
:header-cell-style="{ backgroundColor: '#f5f7fa' }"
|
||||
>
|
||||
<el-table-column
|
||||
type="index"
|
||||
prop="id"
|
||||
label=""
|
||||
width="45"
|
||||
:index="getRowIndex"
|
||||
></el-table-column>
|
||||
<el-table-column type="selection" width="30"></el-table-column>
|
||||
<el-table-column prop="jyrq" label="检验日期" v-if="false"></el-table-column>
|
||||
<el-table-column prop="yq" label="仪器" v-if="false"></el-table-column>
|
||||
<el-table-column prop="ybh" label="样本号" v-if="false"></el-table-column>
|
||||
|
||||
<el-table-column prop="xmdh" label="项目" width="60" show-overflow-tooltip>
|
||||
<div class="result-container">
|
||||
<div class="flex-between mb10">
|
||||
<div>
|
||||
<el-button class="btn_green" @click="handleCheck(1)">初审</el-button>
|
||||
<el-button class="btn_green" v-if="labPat.jgbz != 2" @click="handleCheck(2)">审核</el-button>
|
||||
<el-button class="btn_green" v-if="labPat.jgbz == 2" @click="handleCheck(3)">取消审核</el-button>
|
||||
<el-button type="primary" plain @click="openItemDictDialog">新增</el-button>
|
||||
<el-button type="primary" plain @click="handleBatchDelete">删除</el-button>
|
||||
</div>
|
||||
<div>
|
||||
<el-button type="primary" plain icon="Files" @click="printHandle">打印</el-button>
|
||||
<el-button type="primary" plain icon="View" @click="previewHandle">预览</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<el-table :data="tableData" border ref="tableRef" highlight-current-row class="custom-table-container" height="100%"
|
||||
@row-click="handleRowClick">
|
||||
<el-table-column type="index" prop="id" label="" width="45" :index="getRowIndex"></el-table-column>
|
||||
<!-- <el-table-column type="selection" width="40" align="center"></el-table-column> -->
|
||||
<el-table-column prop="xmdh" label="项目" show-overflow-tooltip>
|
||||
</el-table-column>
|
||||
<el-table-column prop="xmmc" label="名称" width="100" show-overflow-tooltip>
|
||||
<el-table-column prop="xmmc" label="名称" show-overflow-tooltip>
|
||||
</el-table-column>
|
||||
<el-table-column prop="csjg" label="结果" width="100" >
|
||||
<el-table-column prop="csjg" label="结果">
|
||||
<template #default="scope">
|
||||
<el-input
|
||||
v-model="scope.row.csjg"
|
||||
size="small"
|
||||
class="full-width-input"
|
||||
:disabled="readonly"
|
||||
@blur="handleCsjgBlur(scope.row)"
|
||||
@keyup.enter="handleCsjgEnter(scope.row)"
|
||||
></el-input>
|
||||
<el-input v-model="scope.row.csjg" size="small" class="full-width-input" :disabled="readonly"
|
||||
@blur="handleCsjgEnter(scope.row)" @keyup.enter="handleCsjgEnter(scope.row)"></el-input>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="od" label="OD" width="60" v-if="false">
|
||||
<template #default="scope">
|
||||
<el-input v-model="scope.row.od" size="small" class="full-width-input"></el-input>
|
||||
</template>
|
||||
<el-table-column prop="refs" label="参考值" show-overflow-tooltip>
|
||||
</el-table-column>
|
||||
<el-table-column prop="cutoff" label="SCO" width="60" v-if="false">
|
||||
<template #default="scope">
|
||||
<el-input v-model="scope.row.cutoff" size="small" class="full-width-input"></el-input>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="refs" label="参考值" width="100" show-overflow-tooltip>
|
||||
</el-table-column>
|
||||
<el-table-column prop="dw" label="单位" width="100" show-overflow-tooltip >
|
||||
<el-table-column prop="dw" label="单位" show-overflow-tooltip>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- <div class="flex-between mt10">
|
||||
<div>
|
||||
<el-button class="btn_green" @click=" ">初报</el-button>
|
||||
<el-button class="btn_green" @click=" ">二报</el-button>
|
||||
<el-button class="btn_green" @click=" ">锁定</el-button>
|
||||
</div>
|
||||
<div>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<!-- 新增明细 -->
|
||||
<ItemInput ref="itemDictRef" v-model="selectedItemValue" :label-value.sync="selectedItemLabel"
|
||||
:dict-type="'LAB_ITEM'" :fetch-dict="fetchLabItemDict" :dialog-title="'选择检验项目'" :disabled="false"
|
||||
:load-on-mount="false" :table-data.sync="labResuts" class="hidden-dict-input" @select="handleItemSelect" />
|
||||
|
||||
<!-- 校验用户 -->
|
||||
<el-dialog v-model="checkShow" title="用户身份验证" width="500" :close-on-click-modal="false" :draggable="true"
|
||||
@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"
|
||||
@close="warningResetForm">
|
||||
<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"
|
||||
@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>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, toRefs, watch, nextTick, onMounted } from "vue";
|
||||
import { deleteresult, changeresult } from "@/api/liswork/work/LisWork.js";
|
||||
import { check1, check2, uncheck2, unconfirmlog, checkuser, reglimit, queryXmInfo, deleteresult, changeresult, newresult, printsample } from "@/api/liswork/work/LisWork";
|
||||
import { ElMessageBox, ElMessage } from "element-plus";
|
||||
|
||||
import ItemInput from "@/views/liswork/work/components/ItemInput.vue";
|
||||
import { log } from "vxe-pc-ui";
|
||||
// 组件属性定义
|
||||
const props = defineProps({
|
||||
tableData: { type: Array, default: () => [] },
|
||||
tableKey: { type: Array, default: () => [] },
|
||||
tableKey: { type: Object, default: () => { } },
|
||||
readonly: { type: Boolean, default: false },
|
||||
hasChanges: { type: Boolean, default: false }
|
||||
hasChanges: { type: Boolean, default: false },
|
||||
labPat: { type: Object, required: true },
|
||||
});
|
||||
|
||||
|
||||
watch(() => props.tableData, (newVal) => {
|
||||
selectedRows.value = [];
|
||||
});
|
||||
|
||||
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 warningMsgdata = ref('');
|
||||
const showuploadwarning = ref(false);
|
||||
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 itemDictRef = ref(); // DictInput组件引用
|
||||
const selectedItemValue = ref(""); // 选择的项目编码xmdh
|
||||
const selectedItemLabel = ref(""); // 选择的项目名称xmmc
|
||||
const labResuts = ref([])
|
||||
const tableRef = ref();
|
||||
const fetchLabItemDict = async (dictType) => {
|
||||
// 日志1:确认方法被调用
|
||||
try {
|
||||
// 1. 验证必要参数(如当前仪器yq)
|
||||
if (!tableKey.value.yq) {
|
||||
console.error("[fetchLabItemDict] 缺少必要参数:yq(仪器)");
|
||||
ElMessage.error("请先选择仪器");
|
||||
return [];
|
||||
}
|
||||
|
||||
// 日志2:打印请求参数
|
||||
const requestParams = {
|
||||
pageNum: 1,
|
||||
pageSize: 1000, // 加载足够多的项目
|
||||
yq: tableKey.value.yq, // 当前选中的仪器
|
||||
};
|
||||
|
||||
// 2. 调用API(确保queryXmInfo是正确的API方法)
|
||||
const response = await queryXmInfo(requestParams);
|
||||
|
||||
// 日志3:打印原始响应
|
||||
|
||||
// 3. 验证响应格式
|
||||
if (!response) {
|
||||
throw new Error("API返回为空");
|
||||
}
|
||||
if (response.code !== "0") { // 假设0为成功状态码
|
||||
throw new Error(`API返回错误:${response.msg || "未知错误"}`);
|
||||
}
|
||||
if (!Array.isArray(response.data)) {
|
||||
throw new Error(`API返回data不是数组,实际为:${typeof response.data}`);
|
||||
}
|
||||
|
||||
// 4. 格式化数据(适配DictInput的{value, label}结构)
|
||||
const formattedData = response.data.map((item, index) => {
|
||||
// 验证项目数据完整性
|
||||
if (!item.xmdh) {
|
||||
console.warn(`[fetchLabItemDict] 第${index}条数据缺少xmdh(项目编码):`, item);
|
||||
}
|
||||
if (!item.xmmc) {
|
||||
console.warn(`[fetchLabItemDict] 第${index}条数据缺少xmmc(项目名称):`, item);
|
||||
}
|
||||
|
||||
return {
|
||||
value: item.xmdh || `未知编码_${index}`, // 确保value存在
|
||||
label: item.xmmc || `未知名称_${index}`, // 确保label存在
|
||||
dw: item.dw || "", // 单位(可选)
|
||||
refs: item.refs || "", // 参考值(可选)
|
||||
};
|
||||
});
|
||||
|
||||
// 日志4:打印格式化后的数据量
|
||||
return formattedData;
|
||||
|
||||
} catch (error) {
|
||||
// 日志5:捕获并显示错误
|
||||
console.error(`[fetchLabItemDict] 加载失败:`, error.message);
|
||||
ElMessage.error(`项目字典加载失败:${error.message}`);
|
||||
return []; // 失败时返回空数组,避免弹窗报错
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const handleCheck = (checkType) => {
|
||||
// yhdh = checkuserid.value
|
||||
switch (checkType) {
|
||||
case 1: // 初审
|
||||
check1({ ...tableKey.value, yhdh: 'admin' }).then(res => {
|
||||
emits("changeStatus", props.labPat);
|
||||
})
|
||||
break;
|
||||
case 2: // 审核
|
||||
tableKey.value.problemId = 0
|
||||
shHandleCheck()
|
||||
break;
|
||||
case 3: // 取消审核
|
||||
tableKey.value.problemId = 0
|
||||
unShHandle()
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const shHandleCheck = () => {
|
||||
check2({ ...props.tableKey, yhdh: 'admin' }).then(res => {
|
||||
emits("changeStatus", props.labPat);
|
||||
if (res.code == "4" && res.problemId === 4) {
|
||||
tableKey.value.problemId = res.problemId;
|
||||
warningMsgdata.value = res.msg;
|
||||
showuploadwarning.value = true;
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
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 unShHandle = () => {
|
||||
uncheck2({ ...tableKey.value, yhdh: 'admin' }).then(res => {
|
||||
if (res.code == "4") {
|
||||
tableKey.value.problemId = res.problemId;
|
||||
reasonText.value = res.msg;
|
||||
unCheckshow.value = true;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
tableKey.value.problemId = 0
|
||||
|
||||
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 submitForm = () => {
|
||||
ruleFormRef.value.validate((valid) => {
|
||||
if (valid) {
|
||||
checkuser(ruleForm.value).then(res => {
|
||||
if (res.code == 0) {
|
||||
checkuserid.value = ruleForm.value.yhdh
|
||||
checkShow.value = false;
|
||||
ElMessage.success("验证成功");
|
||||
}
|
||||
})
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
const resetForm = () => {
|
||||
checkShow.value = false;
|
||||
ruleForm.value.userId = '';
|
||||
ruleForm.value.mm = '';
|
||||
ruleFormRef.value.resetFields();
|
||||
};
|
||||
// 2. 打开项目选择弹窗
|
||||
const openItemDictDialog = () => {
|
||||
if (itemDictRef.value && typeof itemDictRef.value.openDictSelector === 'function') {
|
||||
itemDictRef.value.openDictSelector(); // 确保方法存在再调用
|
||||
} else {
|
||||
console.warn("DictInput组件未加载完成或方法未暴露");
|
||||
}
|
||||
};
|
||||
|
||||
// 3. 处理项目选择结果:传递给labresult子组件新增行
|
||||
const handleItemSelect = async (selectedItem) => {
|
||||
// 1. 构造新增行数据
|
||||
const newRow = {
|
||||
id: `temp_${Date.now()}_${Math.random().toString(36).substr(2, 8)}`,
|
||||
xmdh: selectedItem.value,
|
||||
xmmc: selectedItem.label,
|
||||
dw: selectedItem.dw || "",
|
||||
refs: selectedItem.refs || "",
|
||||
jyrq: tableKey.value.jyrq,
|
||||
yq: tableKey.value.yq,
|
||||
ybh: tableKey.value.ybh,
|
||||
};
|
||||
|
||||
|
||||
addRowFromDict(newRow);
|
||||
// ElMessage.success(`已新增项目:${newRow.xmmc}`);
|
||||
};
|
||||
|
||||
// 事件定义
|
||||
const emits = defineEmits([
|
||||
'add',
|
||||
'save',
|
||||
'delete',
|
||||
'batch-delete',
|
||||
'fetchLabResults',
|
||||
'delfalg',
|
||||
'update:tableData'
|
||||
'changeStatus',
|
||||
]);
|
||||
|
||||
// 解构props
|
||||
@ -117,93 +462,26 @@ const getRowUniqueKey = (row) => {
|
||||
return row.id || row.xmdh;
|
||||
};
|
||||
|
||||
/**
|
||||
* csjg输入框失焦触发保存
|
||||
*/
|
||||
const handleCsjgBlur = async (row) => {
|
||||
if (isEnterHandled.value) return;
|
||||
await saveCsjgChange(row);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* csjg输入框回车触发保存
|
||||
*/
|
||||
const handleCsjgEnter = async (row) => {
|
||||
isEnterHandled.value = true;
|
||||
await saveCsjgChange(row);
|
||||
nextTick(() => {
|
||||
const input = document.activeElement;
|
||||
if (input.tagName === "INPUT") input.blur();
|
||||
});
|
||||
setTimeout(() => {
|
||||
isEnterHandled.value = false;
|
||||
}, 100);
|
||||
// nextTick(() => {
|
||||
// const input = document.activeElement;
|
||||
// if (input.tagName === "INPUT") input.blur();
|
||||
// });
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* 核心:保存csjg修改(调用API + 失败回滚)
|
||||
*/
|
||||
const saveCsjgChange = async (row) => {
|
||||
const uniqueKey = getRowUniqueKey(row);
|
||||
|
||||
// 防止重复提交
|
||||
if (isSaving.value[uniqueKey]) return;
|
||||
|
||||
const oldCsjg = originalCsjgMap.value[uniqueKey] || "";
|
||||
let newCsjg = row.csjg || "";
|
||||
|
||||
// 标准化处理
|
||||
newCsjg = String(newCsjg).trim();
|
||||
|
||||
// 调试日志
|
||||
console.log(`
|
||||
行${uniqueKey} 比较:
|
||||
缓存旧值:"${oldCsjg}"(类型:${typeof oldCsjg})
|
||||
当前新值:"${newCsjg}"(类型:${typeof newCsjg})
|
||||
是否相等:${oldCsjg === newCsjg}
|
||||
`);
|
||||
|
||||
// 无变化或只读状态,直接返回
|
||||
if (oldCsjg === newCsjg || readonly.value) {
|
||||
console.log("值未变化,无需保存");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// 设置提交中标记
|
||||
isSaving.value[uniqueKey] = true;
|
||||
|
||||
const requestParams = {
|
||||
...row,
|
||||
csjg: newCsjg
|
||||
};
|
||||
|
||||
console.log('提交参数:', requestParams);
|
||||
changeresult(requestParams).then(response => {
|
||||
originalCsjgMap.value[uniqueKey] = newCsjg;
|
||||
emits("update:hasChanges", true);
|
||||
ElMessage.success("结果保存成功");
|
||||
}) .catch(error => {
|
||||
ElMessage.error(error.message || "保存接口调用失败,已恢复原结果");
|
||||
row.csjg = oldCsjg;
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('保存失败:', error);
|
||||
ElMessage.error(error.message || "保存接口调用失败,已恢复原结果");
|
||||
// 回滚值
|
||||
row.csjg = oldCsjg;
|
||||
} finally {
|
||||
// 清除提交中标记
|
||||
isSaving.value[uniqueKey] = false;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 处理选择变化
|
||||
*/
|
||||
const handleSelectionChange = (val) => {
|
||||
selectedRows.value = val;
|
||||
emits('delfalg', val.length === 0);
|
||||
const handleRowClick = (row) => {
|
||||
selectedRows.value = [row];
|
||||
};
|
||||
|
||||
/**
|
||||
@ -259,11 +537,10 @@ const addRowFromDict = async (rowData) => {
|
||||
const newRow = { ...rowData, csjg: "" };
|
||||
|
||||
// 4. 添加到表格数据
|
||||
tableData.value.push(newRow);
|
||||
tableData.value.unshift(newRow);
|
||||
console.log("子组件新增行:", newRow);
|
||||
|
||||
// 3. emit同步给父组件(更新父组件的labResuts)
|
||||
emit('update:tableData', [...tableData.value]);
|
||||
|
||||
// 4. 同步缓存
|
||||
await nextTick();
|
||||
updateOriginalCsjgMap();
|
||||
@ -271,13 +548,83 @@ const addRowFromDict = async (rowData) => {
|
||||
|
||||
// 5. 自动聚焦
|
||||
nextTick(() => {
|
||||
const lastInput = document.querySelector(`.el-table__row:last-child .csjg-input .el-input__inner`);
|
||||
if (lastInput) lastInput.focus();
|
||||
selectedRows.value = [newRow];
|
||||
tableRef.value.setCurrentRow(newRow);
|
||||
nextTick(() => {
|
||||
tableRef.value.setScrollTop(30 * tableRef.value.length)
|
||||
})
|
||||
// const lastInput = document.querySelector(`.el-table__row:last-child .csjg-input .el-input__inner`);
|
||||
// if (lastInput) lastInput.focus();
|
||||
});
|
||||
|
||||
console.log(`成功新增项目行:`, newRow);
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* 核心:保存csjg修改(调用API + 失败回滚)
|
||||
*/
|
||||
const saveCsjgChange = async (row) => {
|
||||
const uniqueKey = getRowUniqueKey(row);
|
||||
|
||||
// 防止重复提交
|
||||
// if (isSaving.value[uniqueKey]) return;
|
||||
|
||||
const oldCsjg = originalCsjgMap.value[uniqueKey] || "";
|
||||
let newCsjg = row.csjg || "";
|
||||
|
||||
// 标准化处理
|
||||
newCsjg = String(newCsjg).trim();
|
||||
|
||||
// 调试日志
|
||||
console.log(`
|
||||
行${uniqueKey} 比较:
|
||||
缓存旧值:"${oldCsjg}"(类型:${typeof oldCsjg})
|
||||
当前新值:"${newCsjg}"(类型:${typeof newCsjg})
|
||||
是否相等:${oldCsjg === newCsjg}
|
||||
`);
|
||||
|
||||
// 无变化或只读状态,直接返回
|
||||
if (oldCsjg === newCsjg || readonly.value) {
|
||||
console.log("值未变化,无需保存");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// 设置提交中标记
|
||||
// isSaving.value[uniqueKey] = true;
|
||||
|
||||
const requestParams = {
|
||||
...row,
|
||||
csjg: newCsjg
|
||||
};
|
||||
|
||||
console.log('提交参数:', requestParams);
|
||||
if (row.id) {
|
||||
newresult(requestParams).then(response => {
|
||||
originalCsjgMap.value[uniqueKey] = newCsjg;
|
||||
ElMessage.success("结果保存成功");
|
||||
emits('fetchLabResults');
|
||||
}).catch(error => {
|
||||
emits('fetchLabResults');
|
||||
// 清除提交中标记
|
||||
// isSaving.value[uniqueKey] = false;
|
||||
});
|
||||
} else {
|
||||
changeresult(requestParams).then(response => {
|
||||
originalCsjgMap.value[uniqueKey] = newCsjg;
|
||||
ElMessage.success("结果保存成功");
|
||||
emits('fetchLabResults');
|
||||
}).catch(error => {
|
||||
emits('fetchLabResults');
|
||||
// 清除提交中标记
|
||||
// isSaving.value[uniqueKey] = false;
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* 保存数据
|
||||
*/
|
||||
@ -289,23 +636,16 @@ const handleSave = () => {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除行
|
||||
*/
|
||||
const handleDelete = (row) => {
|
||||
emits("delete", row);
|
||||
tableData.value = tableData.value.filter((item) => item.id !== row.id);
|
||||
updateOriginalCsjgMap();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* 批量删除
|
||||
*/
|
||||
const handleBatchDelete = async () => {
|
||||
if (selectedRows.value.length === 0) return;
|
||||
const handleBatchDelete = () => {
|
||||
if (selectedRows.value.length === 0) return ElMessage.warning("请先选择要删除的记录");
|
||||
const arr = selectedRows.value.filter(row => !row.id);
|
||||
|
||||
try {
|
||||
await ElMessageBox.confirm(
|
||||
ElMessageBox.confirm(
|
||||
`确定要删除选中的 ${selectedRows.value.length} 条记录吗?`,
|
||||
'提示',
|
||||
{
|
||||
@ -313,34 +653,35 @@ const handleBatchDelete = async () => {
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}
|
||||
);
|
||||
|
||||
await deleteresult(selectedRows.value);
|
||||
emits('fetchLabResults');
|
||||
).then(() => {
|
||||
if (arr.length == 0) {
|
||||
const index = tableData.value.findIndex(item => item.xmdh === selectedRows.value[0].xmdh);
|
||||
if (index > -1) tableData.value.splice(index, 1);
|
||||
selectedRows.value = [];
|
||||
} else {
|
||||
deleteresult(arr).then(res => {
|
||||
if (res.code == 0) {
|
||||
ElMessage.success('删除成功');
|
||||
} catch (error) {
|
||||
if (error !== 'cancel') { // 排除用户取消的情况
|
||||
ElMessage.error('删除失败: ' + (error.message || '未知错误'));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 重置表格的修改状态
|
||||
*/
|
||||
const resetChange = () => {
|
||||
originalData.value = JSON.parse(JSON.stringify(props.tableData));
|
||||
updateOriginalCsjgMap();
|
||||
emits("update:hasChanges", false);
|
||||
};
|
||||
|
||||
/**
|
||||
* 刷新数据
|
||||
*/
|
||||
const fetchLabResults = () => {
|
||||
emits('fetchLabResults');
|
||||
}
|
||||
})
|
||||
}
|
||||
}).catch(() => {
|
||||
});
|
||||
};
|
||||
|
||||
const printHandle = () => {
|
||||
printsample(tableKey.value).then(res => {
|
||||
if (res.code == 0) {
|
||||
// ElMessage.success("打印成功");
|
||||
}
|
||||
})
|
||||
};
|
||||
const previewHandle = () => {
|
||||
// emits('previewHandle', props.tableKey);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* 获取行号
|
||||
*/
|
||||
@ -367,52 +708,44 @@ watch(
|
||||
}
|
||||
);
|
||||
|
||||
// 暴露方法给父组件
|
||||
defineExpose({
|
||||
handleAdd,
|
||||
handleDelete,
|
||||
handleSave,
|
||||
handleBatchDelete,
|
||||
resetChange,
|
||||
addRowFromDict,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.custom-table-container /deep/ .el-table__cell {
|
||||
<style scoped lang="scss">
|
||||
.result-container {
|
||||
height: calc(90vh - 95px);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.flex-between {
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.custom-table-container {
|
||||
flex: 1;
|
||||
|
||||
:deep(.el-table__cell) {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.custom-table-container /deep/ .el-table__row {
|
||||
height: var(--table-row-height) !important;
|
||||
}
|
||||
|
||||
.full-width-input /deep/ .el-input__inner {
|
||||
|
||||
|
||||
.full-width-input .el-input__inner {
|
||||
width: 100%;
|
||||
height: calc(var(--table-row-height) - 2px);
|
||||
padding: 0 8px; /* 增加内边距提升输入体验 */
|
||||
padding: 0 8px;
|
||||
/* 增加内边距提升输入体验 */
|
||||
border: 0px solid #dcdfe6;
|
||||
border-radius: 0;
|
||||
box-sizing: border-box;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.full-width-input /deep/ .el-input__inner:focus {
|
||||
.full-width-input .el-input__inner:focus {
|
||||
border-color: #409eff;
|
||||
box-shadow: 0 0 0 1px rgba(64, 158, 255, 0.2);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.el-table__body-wrapper {
|
||||
overflow: visible !important;
|
||||
}
|
||||
|
||||
.new-row-enter-active {
|
||||
animation: fadeIn 0.5s ease;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from { opacity: 0; transform: translateY(10px); }
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
}
|
||||
</style>
|
||||
|
||||
870
src/views/liswork/work/index copy.vue
Normal file
870
src/views/liswork/work/index copy.vue
Normal file
@ -0,0 +1,870 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-row :gutter="10" class="compact-form">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['system:dict:add']">新增明细</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Delete" :disabled="delResultFlag" @click="handleDelete"
|
||||
v-hasPermi="['system:dict:remove']">删除明细</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="Edit" :disabled="changeResultFlag" @click="handleUpdate"
|
||||
v-hasPermi="['system:dict:edit']">保存</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="Edit" @click="handleCheck0"
|
||||
v-hasPermi="['system:dict:import']">初报</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="Download" @click="handleCheck"
|
||||
v-hasPermi="['system:dict:import']">初审</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="info" plain icon="Upload" @click="handleUnCheck"
|
||||
v-hasPermi="['system:dict:export']">取消初审</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="Download" @click="handleCheck"
|
||||
v-hasPermi="['system:dict:import']">审核</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="Upload" @click="handleUnCheck"
|
||||
v-hasPermi="['system:dict:export']">取消审核</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Edit" @click="handleUnCheck"
|
||||
v-hasPermi="['system:dict:export']">预览</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Edit" @click="handleUnCheck"
|
||||
v-hasPermi="['system:dict:export']">打印</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="Upload" @click="handleUnCheck"
|
||||
v-hasPermi="['system:dict:export']">上一个</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="Download" @click="handleUnCheck"
|
||||
v-hasPermi="['system:dict:export']">下一个</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="10" class="compact-form">
|
||||
<el-form :model="queryParams" ref="queryRef" :inline="true" :rules="rules">
|
||||
<el-form-item class="compact-form" label="" label-width="0px" prop="ybh">
|
||||
<el-col :span="1.5">样本编号</el-col>
|
||||
<el-col :span="4.5">
|
||||
<el-input v-model="queryParams.ybh" clearable placeholder="样本编号" prefix-icon="Search"
|
||||
@keyup.enter="handleQueryYbh" @clear="handleQueryYbh" />
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<div>检验日期</div>
|
||||
</el-col>
|
||||
<el-col :span="3.5">
|
||||
<el-date-picker v-model="queryParams.jyrq" type="date" label-width="20px" placeholder="检验日期"
|
||||
value-format="YYYY-MM-DD" :clearable="false" @change="handleQuery"></el-date-picker>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<div>部门组别</div>
|
||||
</el-col>
|
||||
<el-col :span="3.5">
|
||||
<!-- <Ddlb v-model="queryParams.instrGroup" :options="instrGroupOptions" placeholder="请选择部门组别"
|
||||
@change="handleinstrGroupChange" :value="setInstrGroup" label-width="40px" /> -->
|
||||
<el-select v-model="queryParams.instrGroup" placeholder="请选择" style="width:140px"
|
||||
@change="handleinstrGroupChange">
|
||||
<el-option v-for="item in instrGroupOptions" :key="item.zddh" :label="item.zdmc" :value="item.zddh" />
|
||||
</el-select>
|
||||
</el-col><el-col :span="1">
|
||||
<div>仪器</div>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<Ddlb v-model="queryParams.yq" :options="instrOptions" placeholder="请选择仪器" @change="handleYqChange"
|
||||
:value="setInstr" />
|
||||
</el-col>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="5">
|
||||
<el-col :span="5" :xs="24">
|
||||
<div class="compact-form">
|
||||
<LabPatForm v-model:labPat="labPat" :labPatKey="queryParams" ref="labPatRef" @save="savelabPat"
|
||||
@reset="resetlabPat" />
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="8" :xs="24">
|
||||
<div class="compact-form">
|
||||
<LabResultForm ref="labResultRef" :tableData="labResuts" :tableKey="queryParams"
|
||||
:is-data-refreshed="isDataRefreshed" @add="addLabResult" @delete="deleteLabResults" @edit="editLabResult"
|
||||
@delfalg="setdelResultFlag" @changefalg="setchangeResultFlag" @fetchLabResults="fetchLabResults" />
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="11" :xs="24">
|
||||
<div class="compact-form">
|
||||
<LabPatListForm :labPatList="labPatList" :labPatKey="queryParams" :total="total" @select="selectJob"
|
||||
@search="searchJobs" @page-change="pageChange" />
|
||||
</div>
|
||||
</el-col>
|
||||
<ItemInput ref="itemDictRef" v-model="selectedItemValue" :label-value.sync="selectedItemLabel"
|
||||
:dict-type="'LAB_ITEM'" :fetch-dict="fetchLabItemDict" :dialog-title="'选择检验项目'" :disabled="false"
|
||||
:load-on-mount="false" :table-data.sync="labResuts" class="hidden-dict-input" @select="handleItemSelect" />
|
||||
</el-row>
|
||||
<!-- 引入弹窗组件 -->
|
||||
<unconfirmlog v-model:visible="dialogVisible" :reason-text="currentReason" @onConfirm="unconfirmlogConfirm"
|
||||
@onCancel="unconfirmlogCancel" />
|
||||
<CheckUser v-model:visible="showCheckUser" :title="checktitle"
|
||||
:validation-rules="{ userIdMinLength: 4, passwordMinLength: 6 }" @onConfirm="handleAuthSuccess"
|
||||
@onCancel="handleAuthCancel" />
|
||||
<uploadwarning v-model:visible="showuploadwarning" :msgdata="warningMsgdata" :showRules=1
|
||||
@onupload="handleWarningSuccess" @onCancel="handleWarningCancel" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
getDate,
|
||||
queryLabPatList,
|
||||
queryLabResults,
|
||||
updateLabPat,
|
||||
queryLabPat,
|
||||
check2, uncheck2, unconfirmlog, checkuser, reglimit, queryXmInfo
|
||||
} from "../../../api/liswork/work/LisWork";
|
||||
import { querylabInstrList, querylabInstrListByLisgroup } from "../../../api/liswork/dict/LabInstr";
|
||||
import { getComDicts, queryComDictListService } from "../../../api/liswork/dict/ComDict";
|
||||
import LabPatForm from './components/labpat.vue'
|
||||
import LabResultForm from './components/labresult.vue'
|
||||
import LabPatListForm from './components/labpatlist.vue'
|
||||
import Unconfirmlog from './components/unconfirmlog.vue'
|
||||
import Ddlb from './components/ddlb.vue'
|
||||
import CheckUser from './components/CheckUser.vue'
|
||||
import uploadwarning from './components/uploadwarning.vue'
|
||||
import UCKDictInput from './components/DictInput.vue';
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
import ItemInput from "@/views/liswork/work/components/ItemInput.vue";
|
||||
|
||||
|
||||
const showuploadwarning = ref(false);
|
||||
const single = ref(true);
|
||||
const delResultFlag = ref(true);
|
||||
const changeResultFlag = ref(true);
|
||||
const loading = ref(true);
|
||||
const instrGroupOptions = ref([]);
|
||||
const instrOptions = ref([]);
|
||||
const labPatList = ref([])
|
||||
const patdata = reactive({
|
||||
form: {},
|
||||
labPat: {
|
||||
// jyrq: '',
|
||||
// yq: '',
|
||||
// ybh: '',
|
||||
// brly: '',
|
||||
// jzbz: '',
|
||||
// brdh: '',
|
||||
// brxm: '',
|
||||
// brxb: '',
|
||||
// nl: null,
|
||||
// nldw: '1',
|
||||
// ksdh: '',
|
||||
// ch: '',
|
||||
// sjys: '',
|
||||
// sqsj: '',
|
||||
// cyrq: '',
|
||||
// dysj: '',
|
||||
// zd: '',
|
||||
// bz: '',
|
||||
// yhdh: '',
|
||||
// hdys: '',
|
||||
// jgbz: '0',
|
||||
// yblx: ''
|
||||
},
|
||||
rules: {}
|
||||
});
|
||||
const { labPat } = toRefs(patdata);
|
||||
const labResuts = ref([])
|
||||
const total = ref(0)
|
||||
const currentLabResults = ref([])
|
||||
const searchText = ref('')
|
||||
const pageSize = ref(10)
|
||||
const currentPage = ref(1)
|
||||
const setInstrGroup = ref('')
|
||||
const setInstr = ref('')
|
||||
const yq0 = ref('')
|
||||
const jyrq0 = ref('')
|
||||
const ybh0 = ref('')
|
||||
const checktitle = ref('操作人身份验证')
|
||||
const nextstepname = ref('')
|
||||
const warningMsgdata = ref('')
|
||||
const checkuserid = ref('')
|
||||
const querydata = reactive({
|
||||
form: {},
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
jyrq: formatDate(new Date()),
|
||||
yq: '1',
|
||||
ybh: '1',
|
||||
days: 1,
|
||||
instrGroup: '02',
|
||||
problemId: 0,
|
||||
yhdh: '46'
|
||||
},
|
||||
rules: {
|
||||
ybh: [],
|
||||
jyrq: [],
|
||||
instrGroup: [],
|
||||
yq: [],
|
||||
}
|
||||
,
|
||||
});
|
||||
// 父组件:新增“数据刷新标记”,初始为false
|
||||
const isDataRefreshed = ref(false);
|
||||
// 新增:控制标记的重置(避免持续触发子组件缓存更新)
|
||||
const resetDataRefreshFlag = () => {
|
||||
// 延迟重置,确保子组件有足够时间接收标记并更新缓存
|
||||
setTimeout(() => {
|
||||
isDataRefreshed.value = false;
|
||||
}, 100);
|
||||
};
|
||||
const { queryParams, form, rules } = toRefs(querydata);
|
||||
//子组件labResult.vue
|
||||
const labResultRef = ref(null);
|
||||
//子组件labPatRef.vue
|
||||
const labPatRef = ref(null);
|
||||
// 弹窗控制状态
|
||||
const dialogVisible = ref(false);
|
||||
const showCheckUser = ref(false);
|
||||
// 弹窗显示的原因文本
|
||||
const currentReason = ref('');
|
||||
// 存储需要传递给API的参数
|
||||
const apiParams = ref(null);
|
||||
// 处理弹窗确认(获取返回值后调用API)
|
||||
const unconfirmlogConfirm = async (inputValue) => {
|
||||
try {
|
||||
console.log('用户输入的操作原因:', inputValue);
|
||||
// 调用API,携带用户输入的原因和之前保存的参数
|
||||
loading.value = true;
|
||||
unconfirmlog({ ...queryParams.value, reason: inputValue }).then(response => {
|
||||
console.log('response:', response)
|
||||
loading.value = false;
|
||||
if (response.code == "0") {
|
||||
runnextstepname();
|
||||
}
|
||||
}).catch(error => {
|
||||
console.error('审核失败', error);
|
||||
loading.value = false;
|
||||
});
|
||||
|
||||
// API调用成功后的处理
|
||||
console.log('操作成功:', response);
|
||||
// 可以添加成功提示、刷新数据等逻辑
|
||||
} catch (error) {
|
||||
console.error('操作失败:', error);
|
||||
// 错误处理
|
||||
} finally {
|
||||
// 重置参数
|
||||
apiParams.value = null;
|
||||
}
|
||||
};
|
||||
// 处理弹窗取消
|
||||
const unconfirmlogCancel = () => {
|
||||
console.log('用户取消了操作');
|
||||
// 重置参数
|
||||
apiParams.value = null;
|
||||
cancalnextstepname();
|
||||
};
|
||||
// 处理验证成功
|
||||
const handleAuthSuccess = async (userInfo) => {
|
||||
console.log('验证信息:', userInfo);
|
||||
// 调用后端接口进行实际验证
|
||||
loading.value = true;
|
||||
checkuser({ yhdh: userInfo.userId, mm: userInfo.password }).then(response => {
|
||||
console.log('response:', response)
|
||||
loading.value = false;
|
||||
console.log('userInfo:', userInfo);
|
||||
if (response.code == "0") {
|
||||
checkuserid.value = userInfo.userId;
|
||||
runnextstepname();
|
||||
}
|
||||
}).catch(error => {
|
||||
console.error('验证接口调用失败', error);
|
||||
loading.value = false;
|
||||
checkuserid.value = '';
|
||||
});
|
||||
};
|
||||
|
||||
// 处理取消验证
|
||||
const handleAuthCancel = () => {
|
||||
console.log('用户取消了验证');
|
||||
// 执行取消后的操作
|
||||
cancalnextstepname();
|
||||
};
|
||||
// 处理危急值登记
|
||||
const handleWarningSuccess = async (userInfo) => {
|
||||
console.log('处理危急值登记:', userInfo);
|
||||
// 调用后端接口进行实际验证
|
||||
loading.value = true;
|
||||
reglimit({ ...queryParams.value, qrr: userInfo.userId, tzfs: userInfo.uploadTp, phone: userInfo.phone }).then(response => {
|
||||
console.log('危急值response:', response.code);
|
||||
loading.value = false;
|
||||
if (response.code == "0") {
|
||||
runnextstepname();
|
||||
}
|
||||
if (response.code == "4") {
|
||||
ElMessageBox.confirm(response.msg, '系统提示', { confirmButtonText: '是', cancelButtonText: '否', type: 'warning' }).then(() => {
|
||||
queryParams.value.problemId = queryParams.value.problemId + 1;
|
||||
handleWarningSuccess(userInfo);
|
||||
}).catch(() => {
|
||||
runnextstepname();
|
||||
});
|
||||
}
|
||||
}).catch(error => {
|
||||
console.error('处理危急值登记接口调用失败', error);
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
|
||||
// 处理取消验证
|
||||
const handleWarningCancel = () => {
|
||||
console.log('用户取消了登记');
|
||||
// 执行取消后的操作
|
||||
cancalnextstepname();
|
||||
};
|
||||
// 页面载入时获取基本默认值参数信息,后面有扩展需要都放这里
|
||||
const loadYqConfig = async () => {
|
||||
// 使用 .value 获取响应式数据的值
|
||||
jyrq0.value = '2025-08-19';//formatDate(new Date());
|
||||
yq0.value = 'COBAS';
|
||||
ybh0.value = '1';
|
||||
querydata.queryParams.jyrq = jyrq0.value;
|
||||
querydata.queryParams.yq = 46;
|
||||
querydata.queryParams.ybh = ybh0.value;
|
||||
querydata.queryParams.instrGroup = '02';
|
||||
}
|
||||
// 加载部门下拉列表
|
||||
function loadinstrGroupOptions() {
|
||||
loading.value = true;
|
||||
getComDicts({ zdlb: 'GROUP' }).then(response => {
|
||||
instrGroupOptions.value = response.data
|
||||
loading.value = false;
|
||||
setInstrGroup.value = querydata.queryParams.instrGroup;
|
||||
});
|
||||
loadYqConfig();
|
||||
}
|
||||
// 部门组别变化时更新仪器下拉框
|
||||
const handleinstrGroupChange = (value) => {
|
||||
queryParams.value.instrGroup = value
|
||||
// 清空仪器选择并重新加载
|
||||
// queryParams.value.yq = '';
|
||||
instrOptions.value = [];
|
||||
// 加载对应组别的仪器数据
|
||||
loadinstrOptions();
|
||||
}
|
||||
// 仪器变化时的处理函数
|
||||
const handleYqChange = (value) => {
|
||||
if (value === null || value === '') {
|
||||
queryParams.value.yq = yq0.value;
|
||||
setInstr.value = yq0.value;
|
||||
} else {
|
||||
yq0.value = value;
|
||||
queryParams.value.yq = value;
|
||||
handleQuery();
|
||||
}
|
||||
}
|
||||
// 加载仪器下拉列表
|
||||
const loadinstrOptions = () => {
|
||||
loading.value = true;
|
||||
querylabInstrListByLisgroup({ pageNum: 1, pageSize: 100, lisgroup: queryParams.value.instrGroup })
|
||||
.then(response => {
|
||||
if (response.rows) {
|
||||
instrOptions.value = toRaw(response.rows).map(item => ({
|
||||
id: item.yq.trimEnd(),
|
||||
text: item.yqmc
|
||||
}))
|
||||
loading.value = false;
|
||||
setInstr.value = querydata.queryParams.yq;
|
||||
} else {
|
||||
throw new Error('仪器响应数据为空');
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('仪器数据加载失败', error);
|
||||
loading.value = false;
|
||||
});
|
||||
// console.error('aaa', queryParams.value);
|
||||
//console.log('test22:', instrOptions.value);
|
||||
}
|
||||
//获取服务器时间
|
||||
const serverDate = computed(() => {
|
||||
return formatDate(new Date());
|
||||
});
|
||||
//切换仪器或检验日期后重置页码
|
||||
function resetData() {
|
||||
queryParams.value = {
|
||||
pageNum: 1,
|
||||
pageSize: 15,
|
||||
}
|
||||
searchText.value = ''
|
||||
currentPage.value = 1
|
||||
pageSize.value = 15
|
||||
}
|
||||
//载入样本列表(右边labpatlist.vue组件)
|
||||
const fetchlabPatList = async (search = '', page = 1, size = 15) => {
|
||||
loading.value = true;
|
||||
queryParams.value.pageSize = size;
|
||||
queryParams.value.pageNum = page;
|
||||
queryLabPatList(queryParams.value).then(response => {
|
||||
labPatList.value = response.rows;
|
||||
total.value = response.total;
|
||||
loading.value = false;
|
||||
}).catch(error => {
|
||||
console.error('列表数据加载失败', error);
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
//载入样本编辑表单(左边labpat.vue组件)
|
||||
const fetchLabPat = async () => {
|
||||
loading.value = true;
|
||||
queryLabPat(queryParams.value).then(response => {
|
||||
labPat.value = response.data;
|
||||
loadingPatLabel();
|
||||
loading.value = false;
|
||||
}).catch(error => {
|
||||
console.error('列表数据加载失败', error);
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
//载入样本结果表单(中间labresult.vue组件)
|
||||
const fetchLabResults = async () => {
|
||||
loading.value = true;
|
||||
// console.log('test', queryParams.value);
|
||||
queryLabResults({ jyrq: queryParams.value.jyrq, yq: queryParams.value.yq, ybh: queryParams.value.ybh }).then(response => {
|
||||
// console.log('RESULT:', response);
|
||||
labResuts.value = response.data;
|
||||
loading.value = false;
|
||||
// 关键:设置“数据刷新标记”为true(删除后数据变化,需更新子组件缓存)
|
||||
isDataRefreshed.value = true;
|
||||
// 数据刷新后重置标记
|
||||
resetDataRefreshFlag();
|
||||
}).catch(error => {
|
||||
console.error('列表数据加载失败', error);
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
//保存样本表单
|
||||
const savelabPat = async (labPat) => {
|
||||
// 实际项目中这里应该是API调用
|
||||
console.log('保存主表:', labPat)
|
||||
|
||||
if (!labPat.id) {
|
||||
// 新增
|
||||
labPat.id = Date.now()
|
||||
labPatList.value.unshift({ ...labPat })
|
||||
} else {
|
||||
// 更新
|
||||
const index = labPatList.value.findIndex(item => item.id === labPat.id)
|
||||
if (index !== -1) {
|
||||
labPatList.value.splice(index, 1, { ...labPat })
|
||||
}
|
||||
}
|
||||
|
||||
alert('保存成功')
|
||||
}
|
||||
//重置结果表单
|
||||
const resetlabPat = () => {
|
||||
labResuts.value = []
|
||||
currentLabResults.value = []
|
||||
}
|
||||
//新增结果列
|
||||
const addLabResult = async (LabResult) => {
|
||||
// 实际项目中这里应该是API调用
|
||||
console.log('添加明细:', LabResult)
|
||||
|
||||
if (!LabResult.xh) {
|
||||
LabResult.xh = currentLabResults.value.length + 1
|
||||
}
|
||||
|
||||
const index = currentLabResults.value.findIndex(item => item.xh === LabResult.xh)
|
||||
if (index !== -1) {
|
||||
currentLabResults.value.splice(index, 1, { ...LabResult })
|
||||
} else {
|
||||
currentLabResults.value.push({ ...LabResult })
|
||||
}
|
||||
|
||||
alert('添加成功')
|
||||
}
|
||||
//删除结果列
|
||||
const deleteLabResults = async (xhList) => {
|
||||
// 实际项目中这里应该是API调用
|
||||
console.log('删除明细:', xhList)
|
||||
|
||||
currentLabResults.value = currentLabResults.value.filter(item => !xhList.includes(item.xh))
|
||||
|
||||
alert('删除成功')
|
||||
}
|
||||
//修改结果列
|
||||
const editLabResult = (LabResult) => {
|
||||
console.log('编辑明细:', LabResult)
|
||||
// 在表单中填充数据
|
||||
// 这里不需要做任何事情,因为组件已经绑定了数据
|
||||
}
|
||||
//样本列表点击切换样本信息,同步载入左边样本信息表单和中间结果表单
|
||||
const selectJob = async (job) => {
|
||||
// 复制选中的job数据到当前编辑状态
|
||||
// Object.assign(labPat.value, {...job})
|
||||
queryParams.value.jyrq = job.jyrq;
|
||||
queryParams.value.yq = job.yq;
|
||||
queryParams.value.ybh = job.ybh;
|
||||
|
||||
checkQuery()
|
||||
isDataRefreshed.value = true;
|
||||
//await nextTick();
|
||||
// 获取对应的明细数据
|
||||
await fetchLabPat();
|
||||
await fetchLabResults();
|
||||
resetDataRefreshFlag();
|
||||
}
|
||||
//样本列表检索时刷新列表信息
|
||||
const searchJobs = async (text, page, size) => {
|
||||
searchText.value = text
|
||||
currentPage.value = page
|
||||
pageSize.value = size
|
||||
loadlabPatList()
|
||||
}
|
||||
//样本列表翻页时刷新列表信息
|
||||
const pageChange = async (page, size) => {
|
||||
currentPage.value = page
|
||||
pageSize.value = size
|
||||
loadlabPatList()
|
||||
}
|
||||
//刷新样本列表方法封装
|
||||
const loadlabPatList = async () => {
|
||||
await fetchlabPatList(searchText.value, currentPage.value, pageSize.value)
|
||||
}
|
||||
/** 查询服务器时间 */
|
||||
function getdate() {
|
||||
getDate().then(response => {
|
||||
serverDate.value = formatDate(new Date(response.data));
|
||||
})
|
||||
}
|
||||
//日期格式化
|
||||
function formatDate(date) {
|
||||
const year = date.getFullYear();
|
||||
// 月份是从0开始的,所以要加1
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(date.getDate()).padStart(2, '0');
|
||||
return `${year}-${month}-${day} 00:00:00`;
|
||||
}
|
||||
const setdelResultFlag = (value) => {
|
||||
delResultFlag.value = value;
|
||||
}
|
||||
const setchangeResultFlag = (value) => {
|
||||
changeResultFlag.value = value;
|
||||
}
|
||||
//新增
|
||||
const handleAdd = () => {
|
||||
// labResultRef.value?.handleAdd();
|
||||
openItemDictDialog();
|
||||
};
|
||||
function handleUpdate() {
|
||||
}
|
||||
function handleDelete() {
|
||||
labResultRef.value?.handleBatchDelete();
|
||||
}
|
||||
function loadingPatLabel() {
|
||||
// labPatRef.value?.loadingLabel();
|
||||
}
|
||||
function handleCheck0() {
|
||||
|
||||
}
|
||||
function handleCheck() {
|
||||
queryParams.value.problemId = 0;
|
||||
nextstepname.value = 'handleCheck2';
|
||||
queryParams.value.yhdh = checkuserid.value
|
||||
if (queryParams.value.yhdh == '') {
|
||||
checktitle.value = '审核人工号密码验证'
|
||||
showCheckUser.value = true;
|
||||
} else {
|
||||
handleCheck2();
|
||||
}
|
||||
}
|
||||
function handleCheck2() {
|
||||
loading.value = true;
|
||||
console.log('queryParams:', queryParams.value)
|
||||
queryParams.value.yhdh = checkuserid.value
|
||||
check2(queryParams.value).then(response => {
|
||||
loading.value = false;
|
||||
if (response.code == "4" && response.problemId === 4) {
|
||||
console.log('queryParams1111:', queryParams.value)
|
||||
nextstepname.value = 'handleCheck2';
|
||||
queryParams.value.problemId = response.problemId;
|
||||
// 保存需要传递给API的参数
|
||||
apiParams.value = queryParams;
|
||||
// 设置弹窗显示的原因文本
|
||||
warningMsgdata.value = response.msg;
|
||||
// 显示弹窗
|
||||
showuploadwarning.value = true;
|
||||
}
|
||||
console.log('response:', response)
|
||||
|
||||
}).catch(error => {
|
||||
console.error('审核失败', error);
|
||||
loading.value = false;
|
||||
});
|
||||
|
||||
}
|
||||
function handleUnCheck() {
|
||||
queryParams.value.problemId = 0;
|
||||
nextstepname.value = 'handleuncheck2';
|
||||
queryParams.value.yhdh = checkuserid.value
|
||||
if (queryParams.value.yhdh == '') {
|
||||
checktitle.value = '取消审核人工号密码验证'
|
||||
showCheckUser.value = true;
|
||||
} else {
|
||||
handleuncheck2();
|
||||
}
|
||||
}
|
||||
function handleuncheck2() {
|
||||
loading.value = true;
|
||||
queryParams.value.yhdh = checkuserid.value
|
||||
uncheck2(queryParams.value).then(response => {
|
||||
loading.value = false;
|
||||
if (response.code == "4") {
|
||||
nextstepname.value = 'handleuncheck2';
|
||||
queryParams.value.problemId = response.problemId;
|
||||
// 保存需要传递给API的参数
|
||||
apiParams.value = queryParams;
|
||||
// 设置弹窗显示的原因文本
|
||||
currentReason.value = response.msg;
|
||||
// 显示弹窗
|
||||
dialogVisible.value = true;
|
||||
}
|
||||
|
||||
}).catch(error => {
|
||||
console.error('解除审核失败', error);
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
function handlePrint() {
|
||||
}
|
||||
function handleQueryDetail() {
|
||||
}
|
||||
//切换仪器或检验日期时载入
|
||||
const handleQuery = async () => {
|
||||
if (checkQuery() === false) return false
|
||||
// resetData();
|
||||
await loadlabPatList();
|
||||
//暂时默认打开1号样本,后面由参数控制
|
||||
querydata.queryParams.ybh = '1';
|
||||
isDataRefreshed.value = true;
|
||||
await handleQueryYbh();
|
||||
resetDataRefreshFlag();
|
||||
}
|
||||
//切换样本号时载入
|
||||
const handleQueryYbh = async () => {
|
||||
if (checkQuery() === false) return false
|
||||
isDataRefreshed.value = true;
|
||||
await fetchLabPat();
|
||||
await fetchLabResults();
|
||||
resetDataRefreshFlag();
|
||||
}
|
||||
//主键空置拦截
|
||||
function checkQuery() {
|
||||
if (querydata.queryParams.jyrq === '' || querydata.queryParams.jyrq === null) {
|
||||
querydata.queryParams.jyrq = jyrq0.value
|
||||
return false;
|
||||
}
|
||||
if (querydata.queryParams.yq === '' || querydata.queryParams.yq === null) {
|
||||
querydata.queryParams.yq = yq0.value
|
||||
return false;
|
||||
}
|
||||
if (querydata.queryParams.ybh === '' || querydata.queryParams.ybh === null) {
|
||||
querydata.queryParams.ybh = ybh0.value
|
||||
return false;
|
||||
}
|
||||
jyrq0.value = querydata.queryParams.jyrq
|
||||
yq0.value = querydata.queryParams.yq
|
||||
ybh0.value = querydata.queryParams.ybh
|
||||
}
|
||||
function runnextstepname() {
|
||||
if (nextstepname.value != '') {
|
||||
switch (nextstepname.value) {
|
||||
case 'handleuncheck2':
|
||||
handleuncheck2();
|
||||
break;
|
||||
case 'handleCheck2':
|
||||
handleCheck2();
|
||||
break;
|
||||
default:
|
||||
// 当所有case都不匹配时执行(可选)
|
||||
}
|
||||
}
|
||||
}
|
||||
function cancalnextstepname() {
|
||||
if (nextstepname.value != '') {
|
||||
switch (nextstepname.value) {
|
||||
case 'handleuncheck2':
|
||||
ElMessage({ message: '取消操作,撤销审核失败!', type: 'error' })
|
||||
break;
|
||||
case 'handleCheck2':
|
||||
ElMessage({ message: '取消操作,审核失败!', type: 'error' })
|
||||
break;
|
||||
default:
|
||||
// 当所有case都不匹配时执行(可选)
|
||||
}
|
||||
}
|
||||
}
|
||||
// -------------------------- 项目选择相关变量 --------------------------
|
||||
const itemDictRef = ref(null); // DictInput组件引用
|
||||
const selectedItemValue = ref(""); // 选择的项目编码xmdh
|
||||
const selectedItemLabel = ref(""); // 选择的项目名称xmmc
|
||||
|
||||
// -------------------------- 1. 项目字典API调用方法(传递给DictInput) --------------------------
|
||||
/**
|
||||
* 项目字典加载方法:适配DictInput的fetchDict参数格式
|
||||
* @param {String} dictType - 父组件传递的dict-type(无实际意义,可忽略)
|
||||
* @returns {Promise<Array>} - 项目字典数据(格式需匹配DictInput要求:{value, label})
|
||||
*/
|
||||
// 父组件中:完善的项目字典加载方法
|
||||
const fetchLabItemDict = async (dictType) => {
|
||||
// 日志1:确认方法被调用
|
||||
try {
|
||||
// 1. 验证必要参数(如当前仪器yq)
|
||||
if (!queryParams.value.yq) {
|
||||
console.error("[fetchLabItemDict] 缺少必要参数:yq(仪器)");
|
||||
ElMessage.error("请先选择仪器");
|
||||
return [];
|
||||
}
|
||||
|
||||
// 日志2:打印请求参数
|
||||
const requestParams = {
|
||||
pageNum: 1,
|
||||
pageSize: 1000, // 加载足够多的项目
|
||||
yq: queryParams.value.yq, // 当前选中的仪器
|
||||
};
|
||||
|
||||
// 2. 调用API(确保queryXmInfo是正确的API方法)
|
||||
const response = await queryXmInfo(requestParams);
|
||||
|
||||
// 日志3:打印原始响应
|
||||
|
||||
// 3. 验证响应格式
|
||||
if (!response) {
|
||||
throw new Error("API返回为空");
|
||||
}
|
||||
if (response.code !== "0") { // 假设0为成功状态码
|
||||
throw new Error(`API返回错误:${response.msg || "未知错误"}`);
|
||||
}
|
||||
if (!Array.isArray(response.data)) {
|
||||
throw new Error(`API返回data不是数组,实际为:${typeof response.data}`);
|
||||
}
|
||||
|
||||
// 4. 格式化数据(适配DictInput的{value, label}结构)
|
||||
const formattedData = response.data.map((item, index) => {
|
||||
// 验证项目数据完整性
|
||||
if (!item.xmdh) {
|
||||
console.warn(`[fetchLabItemDict] 第${index}条数据缺少xmdh(项目编码):`, item);
|
||||
}
|
||||
if (!item.xmmc) {
|
||||
console.warn(`[fetchLabItemDict] 第${index}条数据缺少xmmc(项目名称):`, item);
|
||||
}
|
||||
|
||||
return {
|
||||
value: item.xmdh || `未知编码_${index}`, // 确保value存在
|
||||
label: item.xmmc || `未知名称_${index}`, // 确保label存在
|
||||
dw: item.dw || "", // 单位(可选)
|
||||
refs: item.refs || "", // 参考值(可选)
|
||||
};
|
||||
});
|
||||
|
||||
// 日志4:打印格式化后的数据量
|
||||
return formattedData;
|
||||
|
||||
} catch (error) {
|
||||
// 日志5:捕获并显示错误
|
||||
console.error(`[fetchLabItemDict] 加载失败:`, error.message);
|
||||
ElMessage.error(`项目字典加载失败:${error.message}`);
|
||||
return []; // 失败时返回空数组,避免弹窗报错
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// -------------------------- 2. 打开项目选择弹窗 --------------------------
|
||||
const openItemDictDialog = () => {
|
||||
if (itemDictRef.value && typeof itemDictRef.value.openDictSelector === 'function') {
|
||||
itemDictRef.value.openDictSelector(); // 确保方法存在再调用
|
||||
} else {
|
||||
console.warn("DictInput组件未加载完成或方法未暴露");
|
||||
}
|
||||
};
|
||||
|
||||
// -------------------------- 3. 处理项目选择结果:传递给labresult子组件新增行 --------------------------
|
||||
const handleItemSelect = async (selectedItem) => {
|
||||
// 1. 构造新增行数据
|
||||
const newRow = {
|
||||
id: `temp_${Date.now()}_${Math.random().toString(36).substr(2, 8)}`,
|
||||
xmdh: selectedItem.value,
|
||||
xmmc: selectedItem.label,
|
||||
dw: selectedItem.dw || "",
|
||||
refs: selectedItem.refs || "",
|
||||
jyrq: queryParams.value.jyrq,
|
||||
yq: queryParams.value.yq,
|
||||
ybh: queryParams.value.ybh,
|
||||
};
|
||||
// 2. 调用子组件方法新增行(仅一次)
|
||||
if (labResultRef.value && typeof labResultRef.value.addRowFromDict === 'function') {
|
||||
await labResultRef.value.addRowFromDict(newRow);
|
||||
ElMessage.success(`已新增项目:${newRow.xmmc}`);
|
||||
}
|
||||
};
|
||||
//打开页面需要先初始化的内容都放这里
|
||||
onMounted(() => {
|
||||
loadYqConfig();
|
||||
loadinstrGroupOptions(); // 页面加载时获取部门组别数据
|
||||
loadinstrOptions();
|
||||
loadlabPatList();
|
||||
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.compact-form .el-form-item {
|
||||
padding: 5px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.compact-form .el-form-item__label {
|
||||
padding-bottom: 0px;
|
||||
}
|
||||
|
||||
.card-content {
|
||||
max-height: 450px;
|
||||
/* 设置最大高度 */
|
||||
overflow-y: auto;
|
||||
/* 超出高度时显示垂直滚动条 */
|
||||
padding: 5px;
|
||||
/* 保持与卡片默认一致的内边距 */
|
||||
}
|
||||
|
||||
.clickable:hover {
|
||||
cursor: pointer;
|
||||
/* 鼠标悬停时显示手型 */
|
||||
transition: all 0.3s;
|
||||
/* 平滑过渡效果 */
|
||||
color: blue;
|
||||
|
||||
}
|
||||
|
||||
.hidden-dict-input {
|
||||
/* 定位到屏幕左侧外,视觉上不可见 */
|
||||
position: absolute;
|
||||
left: -9999px;
|
||||
top: auto;
|
||||
/* 防止占用布局空间 */
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
/* 防止意外聚焦 */
|
||||
outline: none;
|
||||
}
|
||||
</style>
|
||||
File diff suppressed because it is too large
Load Diff
@ -336,7 +336,7 @@ onMounted(() => {
|
||||
|
||||
|
||||
|
||||
$lighterBlue: #409EFF;
|
||||
$lighterBlue: #1F6DD3;
|
||||
|
||||
.container {
|
||||
position: relative;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user