Merge branch 'addwork'
This commit is contained in:
commit
0b3047f469
@ -8,6 +8,7 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
||||
<link rel="icon" href="/favicon.ico">
|
||||
<title>实验室检验系统</title>
|
||||
|
||||
<!--[if lt IE 11]><script>window.location.href='/html/ie.html';</script><![endif]-->
|
||||
<style>
|
||||
html,
|
||||
|
||||
@ -21,14 +21,18 @@
|
||||
"element-plus": "2.4.3",
|
||||
"file-saver": "2.0.5",
|
||||
"fuse.js": "6.6.2",
|
||||
"jquery": "^3.7.1",
|
||||
"js-beautify": "^1.14.11",
|
||||
"js-cookie": "3.0.5",
|
||||
"jsencrypt": "3.3.2",
|
||||
"nprogress": "0.2.0",
|
||||
"pinia": "2.1.7",
|
||||
"pinyin-pro": "^3.26.0",
|
||||
"select2": "^4.1.0-rc.0",
|
||||
"vue": "3.4.0",
|
||||
"vue-cropper": "1.1.1",
|
||||
"vue-router": "4.2.5",
|
||||
"vue3-select2-component": "^0.1.7",
|
||||
"vuedraggable": "^4.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@ -8,7 +8,6 @@ export function queryComDictListService(query) {
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
//增加字典数据
|
||||
export function addComDictService(data) {
|
||||
return request({
|
||||
@ -25,4 +24,15 @@ export function updateComDictService(data) {
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 根据字典类型查询字典数据信息
|
||||
export function getComDicts(zdlb) {
|
||||
return request({
|
||||
url: '/comdict/getComDicts',
|
||||
method: 'get',
|
||||
params: zdlb
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
18
src/api/liswork/dict/LabInstr.js
Normal file
18
src/api/liswork/dict/LabInstr.js
Normal file
@ -0,0 +1,18 @@
|
||||
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
|
||||
})
|
||||
}
|
||||
59
src/api/liswork/work/LisWork.js
Normal file
59
src/api/liswork/work/LisWork.js
Normal file
@ -0,0 +1,59 @@
|
||||
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 addLabPatService(data) {
|
||||
return request({
|
||||
url: '/liswork/add',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
//修改字典数据
|
||||
export function updateLabPatService(data) {
|
||||
return request({
|
||||
url: '/liswork/update',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
// 查询数据列表
|
||||
export function queryLabResults(query) {
|
||||
return request({
|
||||
url: '/liswork/resultinfo',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
// 批量删除结果
|
||||
export function deleteresult(data) {
|
||||
return request({
|
||||
url: '/liswork/deleteresult',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
44
src/api/mzcx/cydj.js
Normal file
44
src/api/mzcx/cydj.js
Normal file
@ -0,0 +1,44 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 查询采样登记列表
|
||||
export function querySQD(query) {
|
||||
return request({
|
||||
url: '/mzcx/querySQD',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询采样登记详细
|
||||
export function getReqmain(sqh) {
|
||||
return request({
|
||||
url: '/system/reqmain/' + sqh,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 新增采样登记
|
||||
export function addReqmain(data) {
|
||||
return request({
|
||||
url: '/system/reqmain',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改采样登记
|
||||
export function updateReqmain(data) {
|
||||
return request({
|
||||
url: '/system/reqmain',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除采样登记
|
||||
export function delReqmain(sqh) {
|
||||
return request({
|
||||
url: '/system/reqmain/' + sqh,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
43
src/api/pinyin.js
Normal file
43
src/api/pinyin.js
Normal file
@ -0,0 +1,43 @@
|
||||
// pinyin.js - 拼音转换工具
|
||||
// src/utils/pinyin-utils.js
|
||||
import { pinyin } from 'pinyin-pro';
|
||||
|
||||
/**
|
||||
* 获取文本的拼音首字母
|
||||
* @param {string} text - 要转换的文本
|
||||
* @returns {string} - 拼音首字母字符串
|
||||
*/
|
||||
export function getFirstLetter(text) {
|
||||
if (!text) return '';
|
||||
|
||||
// 获取拼音(不带音调,数组形式)
|
||||
const pinyinArray = pinyin(text, { toneType: "none", type: "array" });
|
||||
|
||||
// 提取每个拼音的首字母并连接
|
||||
return pinyinArray.map(word => word.charAt(0)).join('');
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文本的拼音全拼
|
||||
* @param {string} text - 要转换的文本
|
||||
* @returns {string} - 拼音全拼字符串
|
||||
*/
|
||||
export function getFullPinyin(text) {
|
||||
if (!text) return '';
|
||||
|
||||
// 获取拼音(不带音调,字符串形式)
|
||||
return pinyin(text, { toneType: "none" }).replace(/\s+/g, '');
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理选项数据,添加拼音和首字母属性
|
||||
* @param {Array} options - 原始选项数组,每个元素包含id和text属性
|
||||
* @returns {Array} - 处理后的选项数组,每个元素包含pinyin和firstLetters属性
|
||||
*/
|
||||
export function processOptions(options) {
|
||||
return options.map(option => ({
|
||||
...option,
|
||||
pinyin: getFullPinyin(option.text),
|
||||
firstLetters: getFirstLetter(option.text)
|
||||
}));
|
||||
}
|
||||
12
src/main.js
12
src/main.js
@ -7,6 +7,11 @@ import 'element-plus/dist/index.css'
|
||||
import locale from 'element-plus/es/locale/lang/zh-cn'
|
||||
|
||||
import '@/assets/styles/index.scss' // global css
|
||||
// 先导入 jQuery 并设置全局变量
|
||||
|
||||
import * as $ from 'jquery';
|
||||
window.jQuery = $;
|
||||
window.$ = $;
|
||||
|
||||
import App from './App'
|
||||
import store from './store'
|
||||
@ -24,7 +29,7 @@ import elementIcons from '@/components/SvgIcon/svgicon'
|
||||
|
||||
import './permission' // permission control
|
||||
|
||||
import { useDict } from '@/utils/dict'
|
||||
import {useDict, comDict} from '@/utils/dict'
|
||||
import { parseTime, resetForm, addDateRange, handleTree, selectDictLabel, selectDictLabels } from '@/utils/ruoyi'
|
||||
|
||||
// 分页组件
|
||||
@ -47,6 +52,7 @@ import DictTag from '@/components/DictTag'
|
||||
const app = createApp(App)
|
||||
|
||||
// 全局方法挂载
|
||||
|
||||
app.config.globalProperties.useDict = useDict
|
||||
app.config.globalProperties.download = download
|
||||
app.config.globalProperties.parseTime = parseTime
|
||||
@ -66,12 +72,14 @@ app.component('ImagePreview', ImagePreview)
|
||||
app.component('RightToolbar', RightToolbar)
|
||||
app.component('Editor', Editor)
|
||||
|
||||
//VUE3标准方法注入全局方法
|
||||
app.provide('comDict', comDict);
|
||||
|
||||
app.use(router)
|
||||
app.use(store)
|
||||
app.use(plugins)
|
||||
app.use(elementIcons)
|
||||
app.component('svg-icon', SvgIcon)
|
||||
|
||||
directive(app)
|
||||
|
||||
// 使用element-plus 并且设置全局的大小
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import useDictStore from '@/store/modules/dict'
|
||||
import { getDicts } from '@/api/system/dict/data'
|
||||
|
||||
import { getComDicts } from '@/api/liswork/dict/ComDict.js'
|
||||
/**
|
||||
* 获取字典数据
|
||||
*/
|
||||
@ -21,4 +21,45 @@ export function useDict(...args) {
|
||||
})
|
||||
return toRefs(res.value);
|
||||
})()
|
||||
}
|
||||
/**
|
||||
* 获取字典数据(改进版)
|
||||
* 返回 Promise,确保所有字典数据加载完成后才 resolve
|
||||
*/
|
||||
export function comDict(...args) {
|
||||
const res = ref({});
|
||||
const promises = [];
|
||||
|
||||
args.forEach((dictType) => {
|
||||
res.value[dictType] = [];
|
||||
|
||||
const dicts = useDictStore().getDict(dictType);
|
||||
if (dicts) {
|
||||
// 缓存存在,直接赋值
|
||||
res.value[dictType] = dicts;
|
||||
} else {
|
||||
// 缓存不存在,发起请求并记录 Promise
|
||||
const promise = getComDicts({ zdlb: dictType }).then(resp => {
|
||||
const dictList = resp.data.map(p => ({
|
||||
label: p.zdmc,
|
||||
value: p.zddh,
|
||||
elTagType: "",
|
||||
elTagClass: ""
|
||||
}));
|
||||
|
||||
res.value[dictType] = dictList;
|
||||
useDictStore().setDict(dictType, dictList);
|
||||
// console.log(`${dictType} 字典加载完成`, dictList);
|
||||
return dictList;
|
||||
});
|
||||
|
||||
promises.push(promise);
|
||||
}
|
||||
});
|
||||
|
||||
// 等待所有 Promise 完成后才返回
|
||||
return Promise.all(promises).then(() => {
|
||||
// console.log('所有请求的字典已加载完成', res.value);
|
||||
return toRefs(res.value);
|
||||
});
|
||||
}
|
||||
@ -100,7 +100,7 @@ service.interceptors.response.use(res => {
|
||||
} else if (code === 601) {
|
||||
ElMessage({ message: msg, type: 'warning' })
|
||||
return Promise.reject(new Error(msg))
|
||||
} else if (code !== 200) {
|
||||
} else if (code !== 200 && code !== 0) {
|
||||
ElNotification.error({ title: msg })
|
||||
return Promise.reject('error')
|
||||
} else {
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
<script setup>
|
||||
import { computed } from "vue";
|
||||
import { getToken } from "@/utils/auth";
|
||||
import {queryComDictListService,addComDictService,updateComDictService} from "../../../api/liswork/dict/ComDict.js";
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
@ -34,12 +35,26 @@ const title = ref('');
|
||||
// return item.zddh+'('+item.zdmc+')';
|
||||
// });
|
||||
// });
|
||||
|
||||
/*** 用户导入参数 */
|
||||
const upload = reactive({
|
||||
// 是否显示弹出层(用户导入)
|
||||
open: false,
|
||||
// 弹出层标题(用户导入)
|
||||
title: "",
|
||||
// 是否禁用上传
|
||||
isUploading: false,
|
||||
// 是否更新已经存在的用户数据
|
||||
updateSupport: 0,
|
||||
// 设置上传的请求头部
|
||||
headers: { Authorization: "Bearer " + getToken() },
|
||||
// 上传的地址
|
||||
url: import.meta.env.VITE_APP_BASE_API + "/comdict/importData"
|
||||
});
|
||||
|
||||
function resetData(zdlb){
|
||||
queryParams.value = {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
pageSize: 15,
|
||||
zdmc: undefined,
|
||||
zdlb: zdlb,
|
||||
zddh: undefined,
|
||||
@ -123,11 +138,39 @@ function handleUpdate(){
|
||||
function handleDelete(){
|
||||
|
||||
}
|
||||
/** 导入按钮操作 */
|
||||
function handleImport() {
|
||||
upload.title = "字典导入";
|
||||
upload.open = true;
|
||||
};
|
||||
/** 导出按钮操作 */
|
||||
function handleExport() {
|
||||
proxy.download("comdict/export", {
|
||||
...queryParams.value,
|
||||
},`user_${new Date().getTime()}.xlsx`);
|
||||
};
|
||||
/** 下载模板操作 */
|
||||
function importTemplate() {
|
||||
proxy.download("comdict/importTemplate", {
|
||||
}, `user_template_${new Date().getTime()}.xlsx`);
|
||||
};
|
||||
/** 提交上传文件 */
|
||||
function submitFileForm() {
|
||||
proxy.$refs["uploadRef"].submit();
|
||||
};
|
||||
/**文件上传中处理 */
|
||||
const handleFileUploadProgress = (event, file, fileList) => {
|
||||
upload.isUploading = true;
|
||||
};
|
||||
/** 文件上传成功处理 */
|
||||
const handleFileSuccess = (response, file, fileList) => {
|
||||
upload.open = false;
|
||||
upload.isUploading = false;
|
||||
proxy.$refs["uploadRef"].handleRemove(file);
|
||||
proxy.$alert("<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" + response.msg + "</div>", "导入结果", { dangerouslyUseHTMLString: true });
|
||||
handleQuery()
|
||||
};
|
||||
|
||||
//导出
|
||||
function handleExport(){
|
||||
|
||||
}
|
||||
|
||||
//多选框选中数据
|
||||
function handleSelectionChange(){
|
||||
@ -173,6 +216,38 @@ function cancel() {
|
||||
}
|
||||
|
||||
|
||||
//提交表单数据
|
||||
function submitForm() {
|
||||
proxy.$refs["dictRef"].validate(valid => {
|
||||
if (valid) {
|
||||
if (form.value.zdlb != undefined && form.value.zdlb != '') {
|
||||
updateComDictService(form.value).then(response => {
|
||||
proxy.$modal.msgSuccess("修改成功");
|
||||
open.value = false;
|
||||
getList();
|
||||
}).catch(error => {
|
||||
reset();
|
||||
});
|
||||
} else {
|
||||
form.value.zdlb = queryParams.value.zdlb;
|
||||
addComDictService(form.value).then(response => {
|
||||
proxy.$modal.msgSuccess("新增成功");
|
||||
open.value = false;
|
||||
getList();
|
||||
}).catch(error => {
|
||||
form.value.zdlb = '';
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function cancel() {
|
||||
open.value = false;
|
||||
reset();
|
||||
}
|
||||
|
||||
|
||||
getTypeList()
|
||||
|
||||
</script>
|
||||
@ -188,6 +263,9 @@ getTypeList()
|
||||
<div class="card-content">
|
||||
<p class="clickable" v-for="item in typeList" :key="item.zdlb" @click="refreshDetail(item.zddh)">{{ item.zdmc }}</p>
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<p class="clickable" v-for="item in typeList" :key="item.zdlb" @click="refreshDetail(item.zddh)">{{ item.zdmc }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<!-- 字典明细-->
|
||||
@ -216,6 +294,9 @@ getTypeList()
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete" v-hasPermi="['system:dict:remove']">删除</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="info" plain icon="Upload" @click="handleImport" v-hasPermi="['system:dict:import']">导入</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['system:dict:export']">导出</el-button>
|
||||
</el-col>
|
||||
@ -263,11 +344,45 @@ getTypeList()
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<!-- 用户导入对话框 -->
|
||||
<el-dialog :title="upload.title" v-model="upload.open" width="400px" append-to-body>
|
||||
<el-upload
|
||||
ref="uploadRef"
|
||||
:limit="1"
|
||||
accept=".xlsx, .xls"
|
||||
:headers="upload.headers"
|
||||
:action="upload.url + '?updateSupport=' + upload.updateSupport"
|
||||
:disabled="upload.isUploading"
|
||||
:on-progress="handleFileUploadProgress"
|
||||
:on-success="handleFileSuccess"
|
||||
:auto-upload="false"
|
||||
drag
|
||||
>
|
||||
<el-icon class="el-icon--upload"><upload-filled /></el-icon>
|
||||
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
|
||||
<template #tip>
|
||||
<div class="el-upload__tip text-center">
|
||||
<div class="el-upload__tip">
|
||||
<el-checkbox v-model="upload.updateSupport" />是否覆盖已经存在的字典数据
|
||||
</div>
|
||||
<span>仅允许导入xls、xlsx格式文件。</span>
|
||||
<el-link type="primary" :underline="false" style="font-size:12px;vertical-align: baseline;" @click="importTemplate">下载模板</el-link>
|
||||
</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button type="primary" @click="submitFileForm">确 定</el-button>
|
||||
<el-button @click="upload.open = false">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
.card-content {
|
||||
.card-content {
|
||||
max-height: 450px; /* 设置最大高度 */
|
||||
overflow-y: auto; /* 超出高度时显示垂直滚动条 */
|
||||
|
||||
214
src/views/liswork/work/components/DictInput.vue
Normal file
214
src/views/liswork/work/components/DictInput.vue
Normal file
@ -0,0 +1,214 @@
|
||||
<template>
|
||||
<div class="dict-input-wrapper">
|
||||
<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>
|
||||
</template>
|
||||
<template #suffix>
|
||||
<el-icon @click="openDictSelector" size="16" class="select-icon">
|
||||
<ArrowDown />
|
||||
</el-icon>
|
||||
</template>
|
||||
</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-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>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, watch, onMounted } from 'vue';
|
||||
import { Loading, ArrowDown } from '@element-plus/icons-vue';
|
||||
|
||||
import { getFirstLetter } from '@/api/pinyin.js'; // 引入拼音处理工具
|
||||
// 组件参数
|
||||
const props = defineProps({
|
||||
modelValue: { type: [String, Number], default: '' },
|
||||
dictType: { type: String, required: true },
|
||||
placeholder: { type: String, default: '请输入或双击选择' },
|
||||
clearable: { type: Boolean, default: true },
|
||||
disabled: {type: Boolean, default: false},
|
||||
fetchDict: {type: Function, required: true},
|
||||
dialogTitle: {type: String, default: '选择字典项'}
|
||||
});
|
||||
|
||||
// 组件事件
|
||||
const emit = defineEmits(['update:modelValue', 'update:labelValue', 'select']);
|
||||
|
||||
// 内部状态
|
||||
const tempValue = ref('');
|
||||
const labelValue = ref('');
|
||||
const dictData = ref([]); // 存储带简拼的字典数据
|
||||
const filteredDictData = ref([]);
|
||||
const isDictLoading = ref(true);
|
||||
const dialogVisible = ref(false);
|
||||
const searchKey = ref('');
|
||||
|
||||
// 显示值计算
|
||||
const displayValue = computed({
|
||||
get() {
|
||||
return labelValue.value || tempValue.value || props.modelValue || '';
|
||||
},
|
||||
set(newValue) {
|
||||
tempValue.value = newValue;
|
||||
if (labelValue.value && newValue !== labelValue.value) {
|
||||
labelValue.value = '';
|
||||
emit('update:labelValue', '');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
// 加载字典数据(并添加简拼字段)
|
||||
const loadDictData = async () => {
|
||||
try {
|
||||
isDictLoading.value = true;
|
||||
const rawData = await props.fetchDict(props.dictType);
|
||||
// 为每个字典项添加简拼字段
|
||||
dictData.value = (rawData || []).map(item => ({
|
||||
...item,
|
||||
pinyin: getFirstLetter(item.label) // 新增pinyin字段存储简拼
|
||||
}));
|
||||
|
||||
filteredDictData.value = [...dictData.value];
|
||||
} catch (error) {
|
||||
console.error(`加载${props.dictType}字典失败:`, error);
|
||||
dictData.value = [];
|
||||
filteredDictData.value = [];
|
||||
} finally {
|
||||
isDictLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 核心搜索逻辑(支持模糊搜索+简拼搜索)
|
||||
const filterDictData = () => {
|
||||
const key = searchKey.value.trim().toLowerCase();
|
||||
if (!key) {
|
||||
filteredDictData.value = [...dictData.value];
|
||||
return;
|
||||
}
|
||||
|
||||
filteredDictData.value = dictData.value.filter(item => {
|
||||
// 1. 模糊搜索:匹配label(名称)或value(编码)
|
||||
const matchLabel = item.label.toLowerCase().includes(key);
|
||||
const matchValue = String(item.value).toLowerCase().includes(key);
|
||||
|
||||
// 2. 简拼搜索:匹配首字母简拼
|
||||
const matchPinyin = item.pinyin.toLowerCase().includes(key);
|
||||
|
||||
// 满足任一条件即匹配
|
||||
return matchLabel || matchValue || matchPinyin;
|
||||
});
|
||||
};
|
||||
|
||||
// 双击事件处理
|
||||
const handleDblClick = () => {
|
||||
if (!props.disabled && !isDictLoading.value) {
|
||||
dialogVisible.value = true;
|
||||
}
|
||||
};
|
||||
|
||||
// 打开弹窗
|
||||
const openDictSelector = () => {
|
||||
if (!props.disabled && !isDictLoading.value) {
|
||||
dialogVisible.value = true;
|
||||
searchKey.value = '';
|
||||
filterDictData();
|
||||
}
|
||||
};
|
||||
|
||||
// 选择字典项
|
||||
const selectItem = (item) => {
|
||||
emit('update:modelValue', item.value);
|
||||
emit('update:labelValue', item.label);
|
||||
emit('select', item);
|
||||
tempValue.value = item.value;
|
||||
labelValue.value = item.label;
|
||||
dialogVisible.value = false;
|
||||
};
|
||||
|
||||
// 其他方法(失焦、清空等)保持不变
|
||||
const handleBlur = () => { /* ... */
|
||||
};
|
||||
const handleClear = () => { /* ... */
|
||||
};
|
||||
const handleDialogClose = () => {
|
||||
dialogVisible.value = false;
|
||||
};
|
||||
|
||||
// 监听初始值变化
|
||||
watch(() => props.modelValue, (newVal) => {
|
||||
tempValue.value = newVal || '';
|
||||
if (newVal && !isDictLoading.value) {
|
||||
const matched = dictData.value.find(item => String(item.value) === String(newVal));
|
||||
labelValue.value = matched?.label || newVal;
|
||||
emit('update:labelValue', labelValue.value);
|
||||
}
|
||||
}, {immediate: true});
|
||||
|
||||
// 组件挂载时加载字典
|
||||
onMounted(async () => {
|
||||
await loadDictData();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 样式保持不变 */
|
||||
.dict-input-wrapper {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.select-icon {
|
||||
cursor: pointer;
|
||||
color: #666;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.select-icon:hover {
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
:deep(.el-input__suffix) {
|
||||
gap: 4px;
|
||||
}
|
||||
</style>
|
||||
102
src/views/liswork/work/components/ddlb.vue
Normal file
102
src/views/liswork/work/components/ddlb.vue
Normal file
@ -0,0 +1,102 @@
|
||||
<template>
|
||||
<div class="custom-select2">
|
||||
<Select2
|
||||
v-model="currentValue"
|
||||
:options="processedOptions"
|
||||
:settings="select2Settings"
|
||||
@update:modelValue="handleChange"
|
||||
:disabled="isDisabled"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
//import { ref, computed, watch, defineProps, defineEmits } from 'vue';
|
||||
import Select2 from 'vue3-select2-component';
|
||||
import 'select2/dist/css/select2.min.css';
|
||||
import { processOptions } from '@/api/pinyin.js'; // 引入拼音处理工具
|
||||
|
||||
// 定义组件props
|
||||
const props = defineProps({
|
||||
options: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
value: {
|
||||
type: [String, Number, Object],
|
||||
default: null
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: '请选择'
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
width: {
|
||||
type: String,
|
||||
default: '200px'
|
||||
}
|
||||
});
|
||||
|
||||
// 定义组件emits
|
||||
const emits = defineEmits(['update:modelValue', 'change']);
|
||||
|
||||
// 处理选项数据
|
||||
const processedOptions = computed(() => {
|
||||
return processOptions(props.options);
|
||||
});
|
||||
|
||||
// 当前值
|
||||
const currentValue = ref(props.value);
|
||||
|
||||
// Select2设置
|
||||
const select2Settings = computed(() => ({
|
||||
placeholder: props.placeholder,
|
||||
allowClear: true,
|
||||
width: props.width,
|
||||
dropdownAutoWidth: false,
|
||||
|
||||
// 自定义搜索函数
|
||||
matcher: (params, data) => {
|
||||
if (!params.term || params.term.trim() === '') {
|
||||
return data;
|
||||
}
|
||||
|
||||
const term = params.term.toLowerCase();
|
||||
|
||||
// 检查文本、拼音或拼音首字母是否匹配
|
||||
if (
|
||||
data.text.toLowerCase().includes(term) ||
|
||||
data.pinyin.toLowerCase().includes(term) ||
|
||||
data.firstLetters.toLowerCase().includes(term)
|
||||
) {
|
||||
return data;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}));
|
||||
|
||||
// 跟踪禁用状态
|
||||
const isDisabled = computed(() => props.disabled);
|
||||
|
||||
// 监听外部值变化
|
||||
watch(() => props.value, (newVal) => {
|
||||
currentValue.value = newVal;
|
||||
});
|
||||
|
||||
// 处理值变更
|
||||
const handleChange = (value) => {
|
||||
currentValue.value = value;
|
||||
emits('update:modelValue', value);
|
||||
emits('change', value);
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.custom-select2 {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
144
src/views/liswork/work/components/labpat.vue
Normal file
144
src/views/liswork/work/components/labpat.vue
Normal file
@ -0,0 +1,144 @@
|
||||
<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="选择病人来源"/>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-switch v-model="labPat.jzbz" active-text="急诊" active-color="#FD0101"></el-switch>
|
||||
</el-col>
|
||||
</el-form-item>
|
||||
<el-form-item label="病 历 号" label-width="70px">
|
||||
<el-input v-model="labPat.brdh" placeholder="请输入病历号"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="姓 名" label-width="70px">
|
||||
<el-input v-model="labPat.brxm" placeholder="请输入姓名"></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"/>
|
||||
</el-col>
|
||||
<el-col :span="4"><div>年龄</div></el-col>
|
||||
<el-col :span="6">
|
||||
<el-input v-model="labPat.nl" placeholder="年龄"></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"/>
|
||||
</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"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="床 号" label-width="70px">
|
||||
<el-input v-model="labPat.ch" placeholder="请输入床号"></el-input>
|
||||
</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"/>
|
||||
</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"/>
|
||||
</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"></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"></el-date-picker>
|
||||
</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"></el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="临床诊断" label-width="70px">
|
||||
<el-input v-model="labPat.zd" placeholder="请输入临床诊断"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="备 注" label-width="70px">
|
||||
<el-input v-model="labPat.bz" placeholder="请输入备注"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="检验医生" label-width="70px">
|
||||
<el-input v-model="labPat.yhdh" placeholder="请输入检验医生"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="审核医生" label-width="70px">
|
||||
<el-input v-model="labPat.hdys" placeholder="请输入审核医生"></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-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';
|
||||
const props = defineProps({
|
||||
labPat: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
//结果主键
|
||||
labPatKey:{
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
});
|
||||
const emit = defineEmits(['update:labPat']);
|
||||
// 通过inject获取全局方法
|
||||
const comDict = inject('comDict');
|
||||
|
||||
// 保存方法
|
||||
const saveMain = () => {
|
||||
// 提交时可获取原始值(brly)和标签(brlyLabel)
|
||||
console.log('提交数据:', {
|
||||
rawValue: props.labPat.brly,
|
||||
label: props.labPat.brlyLabel,
|
||||
...props.labPat
|
||||
});
|
||||
// 实际项目中调用接口提交数据
|
||||
};
|
||||
// 重置方法
|
||||
const resetMain = () => {
|
||||
emit('update:labPat', {
|
||||
brly: '',
|
||||
brlyLabel: '',
|
||||
ksdh: '',
|
||||
ksdhLabel: '',
|
||||
sjys: '',
|
||||
sjysLabel: '',
|
||||
brxb: '',
|
||||
brxbLabel: '',
|
||||
nldw: '',
|
||||
nldwLabel: '',
|
||||
yblx: '',
|
||||
yblxLabel: '',
|
||||
// 保留其他字段的默认值
|
||||
...props.labPat,
|
||||
jzbz: props.labPat.jzbz || 0,
|
||||
jgbz: props.labPat.jgbz || 0
|
||||
});
|
||||
}
|
||||
// 字典获取方法(适配子组件)
|
||||
const fetchDict = async (dictType) => {
|
||||
const dictRefs = await comDict(dictType);
|
||||
// 根据实际字典结构返回数组(需与子组件匹配)
|
||||
return dictRefs[dictType]?.value || [];
|
||||
};
|
||||
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.compact-form .el-form-item {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.compact-form .el-form-item__label {
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
</style>
|
||||
206
src/views/liswork/work/components/labpatlist.vue
Normal file
206
src/views/liswork/work/components/labpatlist.vue
Normal file
@ -0,0 +1,206 @@
|
||||
<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">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.finish === 1 ? '已完成' : '未完成' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="jgbz" label="审核" width="25" align="center" header-align="center" >
|
||||
<template #default="scope">
|
||||
<el-checkbox :model-value="scope.row.jgbz === '2'" disabled>
|
||||
</el-checkbox>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="alarmflag" label="报警" width="25">
|
||||
<template #default="scope">
|
||||
<el-checkbox :model-value="scope.row.alarmflag === '1'" disabled>
|
||||
</el-checkbox>
|
||||
</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" >
|
||||
<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 >
|
||||
<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">
|
||||
<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>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const props = defineProps({
|
||||
labPatList: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
total: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
})
|
||||
|
||||
const emits = defineEmits(['select', 'search', 'page-change'])
|
||||
|
||||
const searchText = ref('')
|
||||
const pageSize = ref(15)
|
||||
const currentPage = ref(1)
|
||||
|
||||
const search = () => {
|
||||
emits('search', searchText.value, currentPage.value, pageSize.value)
|
||||
}
|
||||
|
||||
const handleRowClick = (row) => {
|
||||
emits('select', 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)
|
||||
})
|
||||
// 设置列头颜色
|
||||
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'
|
||||
}; // 默认不设置样式
|
||||
};
|
||||
</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; /* 文字颜色 */
|
||||
}
|
||||
|
||||
.card-content.el-table__row.current-row:hover {
|
||||
background-color: #d6e8ff !important;
|
||||
}
|
||||
</style>
|
||||
240
src/views/liswork/work/components/labresult.vue
Normal file
240
src/views/liswork/work/components/labresult.vue
Normal file
@ -0,0 +1,240 @@
|
||||
<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>
|
||||
</el-table-column>
|
||||
<el-table-column prop="xmmc" label="名称" width="100" show-overflow-tooltip>
|
||||
</el-table-column>
|
||||
<el-table-column prop="csjg" label="结果" width="100" >
|
||||
<template #default="scope">
|
||||
<el-input v-model="scope.row.csjg" size="small" class="full-width-input"></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>
|
||||
<el-table-column prop="cutoff" label="SCO" 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>
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
</el-table>
|
||||
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
//import {ref, reactive, watch, toRefs, nextTick} from 'vue';
|
||||
import {deleteresult, queryLabResults} from "@/api/liswork/work/LisWork.js";
|
||||
import {delType} from "@/api/system/dict/type.js";
|
||||
import {ElMessageBox} from "element-plus";
|
||||
const { proxy } = getCurrentInstance();
|
||||
const props = defineProps({
|
||||
// 表格数据
|
||||
tableData: {type: Array,default: () => []},
|
||||
//主键
|
||||
tableKey:{type: Array, default: () => []},
|
||||
// 部门选项
|
||||
// departments: {
|
||||
// type: Array,
|
||||
// default: () => []
|
||||
// },
|
||||
// 是否只读
|
||||
readonly: {type: Boolean, default: false}
|
||||
});
|
||||
const { tableData, tableKey, readonly,undeleteflag,hasChanges } = toRefs(props);
|
||||
const emits = defineEmits([
|
||||
'add', // 新增行
|
||||
'save', // 保存数据
|
||||
'delete', // 删除行
|
||||
'batch-delete', // 批量删除
|
||||
'fetchLabResults' //刷新数据
|
||||
]);
|
||||
// 选中的行
|
||||
const selectedRows = ref([]);
|
||||
const filteredList = ref([]);
|
||||
// 原始数据副本,用于检测变化
|
||||
const originalData = ref(JSON.parse(JSON.stringify(props.tableData)));
|
||||
// 处理选择变化
|
||||
|
||||
const handleSelectionChange = (val) => {
|
||||
selectedRows.value = val;
|
||||
if (val.length === 0) {
|
||||
emits('delfalg', true);
|
||||
}else{
|
||||
emits('delfalg', false);
|
||||
}
|
||||
};
|
||||
// 新增行
|
||||
const handleAdd = () => {
|
||||
// emits('add');
|
||||
// 创建新行数据
|
||||
const newRow = {
|
||||
jyrq: tableKey.jyrq,
|
||||
yq: tableKey.yq,
|
||||
ybh: tableKey.ybh
|
||||
};
|
||||
// 添加到表格数据
|
||||
tableData.value.push(newRow);
|
||||
// 动画结束后移除标记
|
||||
// 可选:滚动到表格底部并聚焦到第一个输入框
|
||||
nextTick(() => {
|
||||
const tableData = document.querySelector('.el-table__body-wrapper');
|
||||
if (tableData) {
|
||||
tableData.scrollTop = tableData.scrollHeight;
|
||||
}
|
||||
|
||||
// 聚焦到新行的第一个输入框
|
||||
const inputs = document.querySelectorAll('.el-input__inner');
|
||||
if (inputs.length > 0) {
|
||||
inputs[4].focus(); // 通常最后一个是操作列的按钮,所以取倒数第二个
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
// 保存数据
|
||||
const handleSave = () => {
|
||||
if (hasChanges.value) {
|
||||
emits('save', props.tableData);
|
||||
// 保存后更新原始数据
|
||||
// originalData.value = JSON.parse(JSON.stringify(props.tableData));
|
||||
hasChanges.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 删除行
|
||||
const handleDelete = (row) => {
|
||||
emits('delete', row);
|
||||
tableData.value = tableData.value.filter(item => item.id !== row.id);
|
||||
};
|
||||
|
||||
// 批量删除(调用API)
|
||||
const handleBatchDelete = async () => {
|
||||
try {
|
||||
if (selectedRows.length === 0) {
|
||||
return;
|
||||
}
|
||||
// 确认删除
|
||||
await ElMessageBox.confirm(
|
||||
`确定要删除选中的 ${selectedRows.value.length} 条记录吗?`,
|
||||
'提示',
|
||||
{
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}
|
||||
);
|
||||
|
||||
await deleteresult(selectedRows.value);
|
||||
fetchLabResults();
|
||||
} catch (error) {
|
||||
// 错误已经在拦截器中处理,这里可以不做处理或添加额外逻辑
|
||||
console.error('删除失败:', error);
|
||||
}
|
||||
|
||||
}
|
||||
// 重置表格的修改状态
|
||||
const resetChange = () => {
|
||||
// 原始数据副本,用于检测变化
|
||||
originalData.value = JSON.parse(JSON.stringify(props.tableData));
|
||||
hasChanges.value = false;
|
||||
};
|
||||
const fetchLabResults = () => {
|
||||
emits('fetchLabResults');
|
||||
}
|
||||
// 监听数据变化
|
||||
watch(() => props.tableData, (newVal, oldVal) => {
|
||||
// 简单比较数据是否有变化
|
||||
//hasChanges.value = JSON.stringify(newVal) !== JSON.stringify(originalData.value);
|
||||
}, { deep: true });
|
||||
|
||||
|
||||
// 获取行号(支持分页时显示正确行号)
|
||||
const getRowIndex = (index) => {
|
||||
// 如果有分页,可以根据当前页码计算真实行号
|
||||
// return (currentPage - 1) * pageSize + index + 1;
|
||||
// 无分页时直接返回索引+1
|
||||
return index + 1;
|
||||
};
|
||||
|
||||
// 暴露方法给父组件
|
||||
defineExpose({
|
||||
handleAdd,
|
||||
handleDelete,
|
||||
handleSave,
|
||||
handleBatchDelete
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 移除单元格内边距 */
|
||||
.custom-table-container /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 {
|
||||
width: 100%;
|
||||
height: calc(var(--table-row-height) - 2px); /* 减去上下边框 */
|
||||
padding: 0 0px; /* 减小内边距 */
|
||||
border: 0px solid #dcdfe6;
|
||||
border-radius: 0;
|
||||
box-sizing: border-box;
|
||||
background-color: transparent; /* 可选:透明背景 */
|
||||
}
|
||||
|
||||
/* 输入框聚焦效果 */
|
||||
.full-width-input /deep/ .el-input__inner:focus {
|
||||
border-color: #409eff;
|
||||
box-shadow: 0 0 0 0px 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>
|
||||
505
src/views/liswork/work/index.vue
Normal file
505
src/views/liswork/work/index.vue
Normal file
@ -0,0 +1,505 @@
|
||||
<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="handleCheck" 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="info" 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-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" ref="labPatRef" @save="savelabPat" @reset="resetlabPat" />
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="10" :xs="24">
|
||||
<div class="compact-form">
|
||||
<LabResultForm ref="labResultRef"
|
||||
:tableData="labResuts"
|
||||
:tableKey="queryParams"
|
||||
@add="addLabResult"
|
||||
@delete="deleteLabResults"
|
||||
@edit="editLabResult"
|
||||
@delfalg="setdelResultFlag"
|
||||
@changefalg="setchangeResultFlag"
|
||||
@fetchLabResults="fetchLabResults"
|
||||
/>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="9" :xs="24">
|
||||
<div class="compact-form">
|
||||
<LabPatListForm
|
||||
:labPatList="labPatList"
|
||||
:labPatKey="queryParams"
|
||||
:total="total"
|
||||
@select="selectJob"
|
||||
@search="searchJobs"
|
||||
@page-change="pageChange"
|
||||
/>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {getDate,queryLabPatList,queryLabResults,updateLabPatService,queryLabPat} from "../../../api/liswork/work/LisWork.js";
|
||||
import {querylabInstrList,querylabInstrListByLisgroup} from "../../../api/liswork/dict/LabInstr.js";
|
||||
import {getComDicts, queryComDictListService} from "../../../api/liswork/dict/ComDict.js";
|
||||
import LabPatForm from './components/labpat.vue'
|
||||
import LabResultForm from './components/labresult.vue'
|
||||
import LabPatListForm from './components/labpatlist.vue'
|
||||
import Ddlb from './components/ddlb.vue'
|
||||
|
||||
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 querydata = reactive({
|
||||
form: {},
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
jyrq: formatDate(new Date()),
|
||||
yq: '1',
|
||||
ybh: '1',
|
||||
days: 1,
|
||||
instrGroup:'#'
|
||||
},
|
||||
rules: {
|
||||
ybh: [],
|
||||
jyrq: [],
|
||||
instrGroup: [],
|
||||
yq: [],
|
||||
}
|
||||
,
|
||||
});
|
||||
const { queryParams, form, rules } = toRefs(querydata);
|
||||
//子组件labResult.vue
|
||||
const labResultRef = ref(null);
|
||||
//子组件labPatRef.vue
|
||||
const labPatRef = ref(null);
|
||||
|
||||
// 页面载入时获取基本默认值参数信息,后面有扩展需要都放这里
|
||||
const loadYqConfig = async () => {
|
||||
// 使用 .value 获取响应式数据的值
|
||||
jyrq0.value='2022-06-19';//formatDate(new Date());
|
||||
yq0.value='COBAS';
|
||||
ybh0.value='1';
|
||||
querydata.queryParams.jyrq = jyrq0.value;
|
||||
querydata.queryParams.yq = yq0.value;
|
||||
querydata.queryParams.ybh = ybh0.value;
|
||||
querydata.queryParams.instrGroup = 'A2';
|
||||
}
|
||||
// 加载部门下拉列表
|
||||
function loadinstrGroupOptions(){
|
||||
loading.value = true;
|
||||
getComDicts({zdlb: 'GROUP'}).then(response => {
|
||||
instrGroupOptions.value = response.data.map(item => ({
|
||||
id: item.zddh,
|
||||
text: item.zdmc
|
||||
}));
|
||||
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;
|
||||
}) .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()
|
||||
//await nextTick();
|
||||
// 获取对应的明细数据
|
||||
await fetchLabPat();
|
||||
await fetchLabResults();
|
||||
}
|
||||
//样本列表检索时刷新列表信息
|
||||
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();
|
||||
};
|
||||
function handleUpdate(){
|
||||
}
|
||||
function handleDelete(){
|
||||
labResultRef.value?.handleBatchDelete();
|
||||
}
|
||||
function loadingPatLabel(){
|
||||
// labPatRef.value?.loadingLabel();
|
||||
}
|
||||
function handleCheck(){
|
||||
}
|
||||
function handleUnCheck(){
|
||||
}
|
||||
function handlePrint(){
|
||||
}
|
||||
function handleQueryDetail(){
|
||||
}
|
||||
//切换仪器或检验日期时载入
|
||||
const handleQuery= async()=>{
|
||||
if (checkQuery()===false) return false
|
||||
// resetData();
|
||||
await loadlabPatList();
|
||||
//暂时默认打开1号样本,后面由参数控制
|
||||
querydata.queryParams.ybh='1';
|
||||
await handleQueryYbh();
|
||||
}
|
||||
//切换样本号时载入
|
||||
const handleQueryYbh = async()=>{
|
||||
if (checkQuery()===false) return false
|
||||
await fetchLabPat();
|
||||
await fetchLabResults();
|
||||
}
|
||||
//主键空置拦截
|
||||
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
|
||||
}
|
||||
|
||||
//打开页面需要先初始化的内容都放这里
|
||||
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;
|
||||
|
||||
}
|
||||
</style>
|
||||
582
src/views/mzcx/cydj/index.vue
Normal file
582
src/views/mzcx/cydj/index.vue
Normal file
@ -0,0 +1,582 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-row :gutter="5" class="compact-form" :span="24" >
|
||||
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-position="left" >
|
||||
<el-col :span="24" :xs="24">
|
||||
<el-form-item label="" label-width="0px" prop="brdh" >
|
||||
|
||||
<el-col :span="6">
|
||||
<div> 就诊卡号/病历号/磁卡号: </div>
|
||||
<el-input
|
||||
v-model="queryParams.brdh"
|
||||
placeholder="就诊卡号/病历号/磁卡号"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</el-col>
|
||||
<el-col :span="2">
|
||||
<el-radio-group v-model="queryParams.zt" size="default">
|
||||
<el-radio v-for="(item, index) in showconfirmOptions" :key="index" :label="item.value"
|
||||
:disabled="item.disabled">{{item.label}}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-col>
|
||||
<el-col :span="1"> <div> 申请获取期限: </div></el-col>
|
||||
<el-col :span="6">
|
||||
|
||||
<el-radio-group v-model="queryParams.subday" size="default">
|
||||
<el-radio v-for="(item, index) in subdayOptions" :key="index" :label="item.value"
|
||||
:disabled="item.disabled">{{item.label}}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-col>
|
||||
<el-col :span="2">
|
||||
<el-select v-model="queryParams.cardtype" placeholder="卡类型" clearable :style="{width: '100%'}">
|
||||
<el-option v-for="(item, index) in cardtypeOptions" :key="index" :label="item.label"
|
||||
:value="item.value" :disabled="item.disabled"></el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">读卡</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button icon="Refresh" @click="resetQuery">查找病人</el-button>
|
||||
</el-col>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
</el-form>
|
||||
</el-row>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
icon="Search"
|
||||
@click="handleQuery"
|
||||
v-hasPermi="['system:reqmain:Search']"
|
||||
>查询</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="success"
|
||||
plain
|
||||
icon="Printer"
|
||||
:disabled="single"
|
||||
@click="printAll"
|
||||
v-hasPermi="['system:reqmain:add']"
|
||||
>打印</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="success"
|
||||
plain
|
||||
icon="Printer"
|
||||
:disabled="freesingle"
|
||||
@click="printSigne"
|
||||
v-hasPermi="['system:reqmain:edit']"
|
||||
>单打条码</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="danger"
|
||||
plain
|
||||
icon="Printer"
|
||||
:disabled="freesingle"
|
||||
@click="printBackpaper"
|
||||
v-hasPermi="['system:reqmain:edit']"
|
||||
>单打回单</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="warning"
|
||||
plain
|
||||
icon="Delete"
|
||||
@click="cancel"
|
||||
v-hasPermi="['system:reqmain:export']"
|
||||
>取消采样</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
|
||||
<el-table ref="tableRef" class="compact-form my-table" :data="reqmainList" @selection-change="handleSelectionChange" @select="handleSelect" height="530px" :cell-style="tableCellStyle">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="项目名称" align="center" prop="sqxmmc" width="200" show-overflow-tooltip/>
|
||||
<el-table-column label="项目代码" align="center" prop="sqxmdh" width="100" show-overflow-tooltip/>
|
||||
<el-table-column label="项目类别" align="center" prop="cp_xmlb" />
|
||||
<el-table-column label="样本类型" align="center" prop="yblx" />
|
||||
<el-table-column label="条码号" align="center" prop="sqh" width="150" show-overflow-tooltip/>
|
||||
<el-table-column label="申请时间" align="center" prop="sqsj" width="180" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.sqsj, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="病人姓名" align="center" prop="brxm" show-overflow-tooltip/>
|
||||
<el-table-column label="申请医生" align="center" prop="sqys" :formatter="formatDict('SRD')" show-overflow-tooltip/>
|
||||
<el-table-column label="序号" align="center" prop="xh" show-overflow-tooltip/>
|
||||
<el-table-column label="数量" align="center" prop="sl" show-overflow-tooltip/>
|
||||
<el-table-column label="单价" align="center" prop="dj" show-overflow-tooltip/>
|
||||
<el-table-column label="状态" align="center" prop="zt" show-overflow-tooltip/>
|
||||
<el-table-column label="计价" align="center" prop="jjzt" >
|
||||
<template #default="scope">
|
||||
<el-checkbox :model-value="scope.row.jjzt === '1'" disabled>
|
||||
</el-checkbox>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="病人代号" align="center" prop="brdh" show-overflow-tooltip/>
|
||||
<el-table-column label="备注1" align="center" prop="detailBZ1" show-overflow-tooltip/>
|
||||
<el-table-column label="备注2" align="center" prop="detailBZ2" show-overflow-tooltip/>
|
||||
<el-table-column label="颜色" align="center" prop="cp_color" v-if="false" show-overflow-tooltip/>
|
||||
<el-table-column label="确认标识" align="center" prop="cp_cflag" v-if="false" show-overflow-tooltip/>
|
||||
<el-table-column label="科室" align="center" prop="ksdh" :formatter="formatDict('DP')" show-overflow-tooltip/>
|
||||
<el-table-column label="病人类型" align="center" prop="brly" :formatter="formatDict('PT')" show-overflow-tooltip/>
|
||||
<el-table-column label="性别" align="center" prop="brxb" :formatter="formatDict('SX')" show-overflow-tooltip/>
|
||||
<el-table-column label="生日" align="center" prop="brsr" width="180" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.brsr, '{y}-{m}-{d}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="床号" align="center" prop="ch" width="50" show-overflow-tooltip/>
|
||||
<el-table-column label="诊断" align="center" prop="zd" width="150" show-overflow-tooltip/>
|
||||
<el-table-column label="条码类别" align="center" prop="bgddh" v-if="false" show-overflow-tooltip/>
|
||||
<el-table-column label="年龄" align="center" prop="nl" show-overflow-tooltip/>
|
||||
<el-table-column label="年龄单位" align="center" prop="nldw" :formatter="formatDict('AU')" show-overflow-tooltip/>
|
||||
<el-table-column label="采样时间" align="center" prop="cysj" width="180"show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.cysj, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 汇总行 -->
|
||||
<div class="table-summary">
|
||||
<div class="summary-item">
|
||||
<span class="summary-label">条码数:</span>
|
||||
<span class="summary-value">{{ idsnew.length }}</span>
|
||||
</div>
|
||||
<div class="summary-item">
|
||||
<span class="summary-label">项目数:</span>
|
||||
<span class="summary-value">{{ totalRows }}</span>
|
||||
</div>
|
||||
<div class="summary-item">
|
||||
<span class="summary-label">合计金额:</span>
|
||||
<span class="summary-value">{{ totalPrice.toFixed(2) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { querySQD, getReqmain, delReqmain, addReqmain, updateReqmain } from "@/api/mzcx/cydj.js";
|
||||
const comDict = inject('comDict');
|
||||
// 字典数据存储
|
||||
const dictData = ref({});
|
||||
const tableRef = ref(null);
|
||||
const { proxy } = getCurrentInstance();
|
||||
// 选中的行
|
||||
const selectedRows = ref([]);
|
||||
const reqmainList = ref([]);
|
||||
const open = ref(false);
|
||||
const loading = ref(true);
|
||||
const showSearch = ref(true);
|
||||
const ids = ref([]);
|
||||
// 新增:计算属性,返回去重后的ids数组
|
||||
const idsnew = computed(() => {
|
||||
return [...new Set(ids.value)];
|
||||
});
|
||||
const single = ref(true);
|
||||
const freesingle = ref(true);
|
||||
const cardtypeOptions = ref([{"label": "就诊卡","value": 1},{"label": "医保卡","value": 2},{"label": "电子医保卡","value": 3},{"label": "身份证", "value": 4}])
|
||||
const showconfirmOptions = ref([{"label": "未打印", "value": 1},{"label": "已打印", "value": 11}])
|
||||
const subdayOptions = ref([{"label": "1天","value": 1},{"label": "3天", "value": 3},{"label": "1周","value": 7},{"label": "2周","value": 14},{"label": "1月", "value": 30},{"label": "3月", "value": 90},{"label": "1年","value": 365},{"label": "2年","value": 730}])
|
||||
|
||||
const data = reactive({
|
||||
form: {},
|
||||
queryParams: {
|
||||
brdh: null,
|
||||
stime: null,
|
||||
etime: null,
|
||||
klx: null,
|
||||
zt: 1,
|
||||
subday: 3000,
|
||||
cardtype:null
|
||||
},
|
||||
rules: {
|
||||
brdh: [
|
||||
{ required: true, message: "病人代码不能为空", trigger: "blur" }
|
||||
],
|
||||
subday: [],
|
||||
}
|
||||
});
|
||||
|
||||
const { queryParams, form, rules } = toRefs(data);
|
||||
// 标志位:是否是程序自动勾选(避免循环触发事件)
|
||||
const isAutoSelect = ref(false);
|
||||
|
||||
/**
|
||||
* 监听单选勾选/取消事件
|
||||
* @param {Array} selection 目前已选中的行
|
||||
* @param {Object} row 当前操作的行数据
|
||||
* @param {Boolean} selected 是否勾选(true=勾选,false=取消)
|
||||
*/
|
||||
const handleSelect = (selection, row, selected) => {
|
||||
if (isAutoSelect.value) return;
|
||||
|
||||
const targetSqh = row.sqh;
|
||||
const targetxh = row.xh;
|
||||
if (!targetSqh) return;
|
||||
|
||||
// 先收集需要自动勾选的行(避免在循环中修改数据)
|
||||
const rowsToSelect = reqmainList.value.filter(
|
||||
item => item.sqh === targetSqh && item.xh !== targetxh
|
||||
);
|
||||
|
||||
// 如果有需要自动勾选的行,才开启标志位
|
||||
if (rowsToSelect.length > 0) {
|
||||
|
||||
rowsToSelect.forEach(item => {
|
||||
tableRef.value.toggleRowSelection(item, selected);
|
||||
isAutoSelect.value = true;
|
||||
});
|
||||
setTimeout(() => isAutoSelect.value = false, 0);
|
||||
}
|
||||
};
|
||||
// 字典格式化方法
|
||||
const formatDict =(dictType) => {
|
||||
return (row, column, value) => {
|
||||
// 从全局字典中获取映射值
|
||||
return dictData.value[dictType].find(item => String(item.value) === String(value).trim())?.label||value ;
|
||||
};
|
||||
};
|
||||
// 定义“空数据”的判断函数
|
||||
const isEmptyData = (data) => {
|
||||
// 处理 null/undefined
|
||||
if (data === null || data === undefined) return true;
|
||||
// 处理空数组
|
||||
if (Array.isArray(data) && data.length === 0) return true;
|
||||
// 处理空对象(无任何属性)
|
||||
if (typeof data === 'object' && Object.keys(data).length === 0) return true;
|
||||
// 处理空字符串
|
||||
if (typeof data === 'string' && data.trim() === '') return true;
|
||||
return false;
|
||||
};
|
||||
/**
|
||||
* 获取指定天数偏移后的日期时间字符串
|
||||
* @param {number} days 偏移天数(正数表示未来,负数表示过去)
|
||||
* @returns {string} 格式化的日期时间字符串 'yyyy-mm-dd HH:MM:SS'
|
||||
*/
|
||||
function getDateOffset(days) {
|
||||
const now = new Date();
|
||||
const offsetTimestamp = now.getTime() + days * 24 * 60 * 60 * 1000;
|
||||
const targetDate = new Date(offsetTimestamp);
|
||||
|
||||
const year = targetDate.getFullYear();
|
||||
const month = String(targetDate.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(targetDate.getDate()).padStart(2, '0');
|
||||
// const hours = String(targetDate.getHours()).padStart(2, '0');
|
||||
// const minutes = String(targetDate.getMinutes()).padStart(2, '0');
|
||||
//const seconds = String(targetDate.getSeconds()).padStart(2, '0');
|
||||
// return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
||||
return `${year}-${month}-${day} 00:00:00`;
|
||||
}
|
||||
function getSubday() {
|
||||
const days=0 - queryParams.value.subday;
|
||||
queryParams.value.stime=getDateOffset(days);
|
||||
queryParams.value.etime=getDateOffset(1);
|
||||
}
|
||||
/** 查询采样登记列表 */
|
||||
function getList() {
|
||||
|
||||
if(isEmptyData(queryParams.value.brdh)) proxy.$modal.alert("请刷卡或输入门诊号!");
|
||||
else {
|
||||
loading.value = true;
|
||||
getSubday();
|
||||
querySQD(queryParams.value).then(response => {
|
||||
if (isEmptyData(response.data)) proxy.$modal.alert("没有检索的数据!");
|
||||
reqmainList.value = response.data;
|
||||
loading.value = false;
|
||||
single.value=false;
|
||||
// 新增:数据加载完成后触发全选
|
||||
// 延迟执行(确保DOM已更新)
|
||||
setTimeout(() => {
|
||||
if (tableRef.value) {
|
||||
tableRef.value.toggleAllSelection(); // 调用全选方法
|
||||
}
|
||||
}, 0);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 取消按钮
|
||||
function cancel() {
|
||||
// open.value = false;
|
||||
// reset();
|
||||
}
|
||||
|
||||
// 表单重置
|
||||
function reset() {
|
||||
form.value = {
|
||||
sqh: null,
|
||||
xh: null,
|
||||
sqxmdh: null,
|
||||
sqxmmc: null,
|
||||
sl: null,
|
||||
dj: null,
|
||||
detailZT: null,
|
||||
detailJJZT: null,
|
||||
ksdh: null,
|
||||
sqys: null,
|
||||
sqsj: null,
|
||||
jsys: null,
|
||||
jssj: null,
|
||||
brly: null,
|
||||
brdh: null,
|
||||
brxm: null,
|
||||
zt: null,
|
||||
jjzt: null,
|
||||
brxb: null,
|
||||
brsr: null,
|
||||
jzbz: null,
|
||||
cp_xmlb: null,
|
||||
cp_color: null,
|
||||
cp_cflag: null,
|
||||
detailBZ1: null,
|
||||
ch: null,
|
||||
detailBZ2: null,
|
||||
bz1: null,
|
||||
bz2: null,
|
||||
bz3: null,
|
||||
yblx: null,
|
||||
zxys: null,
|
||||
zxsj: null,
|
||||
bgddh: null,
|
||||
nl: null,
|
||||
nldw: null,
|
||||
zd: null,
|
||||
cysj: null
|
||||
};
|
||||
freesingle.value=false;
|
||||
single.value=false;
|
||||
proxy.resetForm("reqmainRef");
|
||||
}
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
function handleQuery() {
|
||||
getList();
|
||||
}
|
||||
|
||||
/** 重置按钮操作 */
|
||||
function resetQuery() {
|
||||
proxy.resetForm("queryRef");
|
||||
handleQuery();
|
||||
}
|
||||
|
||||
// 多选框选中数据
|
||||
function handleSelectionChange(selection) {
|
||||
if (isAutoSelect.value) return;
|
||||
selectedRows.value = selection;
|
||||
ids.value = selection.map(item => item.sqh);
|
||||
//console.log('ids:', ids.value);
|
||||
// console.log('selectedRows:', selectedRows.value);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** 打印选择 */
|
||||
function printAll(row) {
|
||||
console.log('idsnew:', idsnew.value);
|
||||
if (idsnew.value.length=== 0) {
|
||||
return;
|
||||
}
|
||||
apiprintAll(idsnew.value).then(response => {
|
||||
proxy.$modal.msgSuccess("打印成功");
|
||||
open.value = false;
|
||||
freesingle.value=false;
|
||||
}).catch(() => {
|
||||
});
|
||||
}
|
||||
/** 单打条码*/
|
||||
function printSigne(row) {
|
||||
if (idsnew.value.length === 0) {
|
||||
return;
|
||||
}
|
||||
apiprintAll(idsnew.value).then(response => {
|
||||
proxy.$modal.msgSuccess("打印成功");
|
||||
open.value = false;
|
||||
freesingle.value=false;
|
||||
}).catch(() => {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/** 打印回单 */
|
||||
function printBackpaper(row) {
|
||||
if (idsnew.value.length === 0) {
|
||||
return;
|
||||
}
|
||||
apiprintAll(idsnew.value).then(response => {
|
||||
proxy.$modal.msgSuccess("打印成功");
|
||||
open.value = false;
|
||||
}).catch(() => {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
const totalRows = computed(() => {
|
||||
return reqmainList.value.length || 0;
|
||||
});
|
||||
|
||||
const totalPrice = computed(() => {
|
||||
return reqmainList.value.reduce((sum, row) => {
|
||||
const price = parseFloat(row.dj) || 0;
|
||||
return sum + price;
|
||||
}, 0);
|
||||
});
|
||||
|
||||
|
||||
// 组件挂载时加载字典
|
||||
onMounted(async () => {
|
||||
// 加载病人来源字典
|
||||
const dictRefs = await comDict('PT', 'DP', 'SRD','BT','SX','AU');
|
||||
// 从 ref 中获取实际数据
|
||||
dictData.value = {
|
||||
PT: toRaw(dictRefs.PT.value) || [],
|
||||
DP: toRaw(dictRefs.DP.value) || [],
|
||||
SRD: toRaw(dictRefs.SRD.value) || [],
|
||||
BT: toRaw(dictRefs.BT.value) || [],
|
||||
SX: toRaw(dictRefs.SX.value) || [],
|
||||
AU: toRaw(dictRefs.AU.value) || []
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
|
||||
// 表格单元格样式(仅作用于“项目类别”列)
|
||||
const tableCellStyle = ({ row, column }) => {
|
||||
// 只对“项目类别”列生效
|
||||
if (column.label === '项目类别') {
|
||||
// 1. 转换颜色(十进制→十六进制)
|
||||
const bgColor = decimalToHexColor(row.cp_color);
|
||||
// 2. 自动计算文字颜色(确保和背景色对比度足够)
|
||||
const textColor = getContrastTextColor(bgColor);
|
||||
|
||||
return {
|
||||
backgroundColor: bgColor, // 背景色(转换后的值)
|
||||
color: textColor, // 文字色(自动适配)
|
||||
textAlign: 'center', // 文字居中
|
||||
fontWeight: '500' // 文字加粗(提升可读性)
|
||||
};
|
||||
}
|
||||
return {}; // 其他列保持默认样式
|
||||
};
|
||||
|
||||
// 十进制颜色值转十六进制颜色码(适配BGR转RGB)
|
||||
const decimalToHexColor = (decimal) => {
|
||||
if (!decimal && decimal !== 0) return '#FFFFFF'; // 空值默认白色
|
||||
|
||||
// 1. 十进制转十六进制(去除前缀0x,大写)
|
||||
let hex = parseInt(decimal, 10).toString(16).toUpperCase();
|
||||
|
||||
// 2. 不足6位则前面补0(确保是6位)
|
||||
if (hex.length < 6) {
|
||||
hex = hex.padStart(6, '0'); // 例如:192→"C0"→补0为"0000C0"
|
||||
}
|
||||
|
||||
// 3. BGR转RGB(反转字节顺序:前两位和后两位交换)
|
||||
// 例:80FFFF → 拆分为80、FF、FF → 反转后FF、FF、80 → FFFF80
|
||||
const r = hex.substring(4, 6); // 取后两位
|
||||
const g = hex.substring(2, 4); // 取中间两位
|
||||
const b = hex.substring(0, 2); // 取前两位
|
||||
const rgbHex = r + g + b;
|
||||
|
||||
return `#${rgbHex}`; // 最终颜色码
|
||||
};
|
||||
// 辅助函数:根据背景色计算文字颜色(黑/白)
|
||||
const getContrastTextColor = (bgColor) => {
|
||||
// 提取RGB值(如#FFFF80 → R=255, G=255, B=128)
|
||||
const r = parseInt(bgColor.slice(1, 3), 16);
|
||||
const g = parseInt(bgColor.slice(3, 5), 16);
|
||||
const b = parseInt(bgColor.slice(5, 7), 16);
|
||||
|
||||
// 计算亮度(标准公式)
|
||||
const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
|
||||
// 亮度>0.5用黑色,否则用白色(确保清晰)
|
||||
return luminance > 0.5 ? '#333333' : '#FFFFFF';
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.compact-form .el-form-item {
|
||||
padding: 5px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.compact-form .el-form-item__label {
|
||||
padding-bottom: 0px;
|
||||
}
|
||||
::v-deep .my-table .el-table__row td {
|
||||
padding: 1px 0; /* 减小行高 */
|
||||
}
|
||||
::v-deep .my-table .el-table__header-wrapper th {
|
||||
padding: 6px 0; /* 表头内边距 */
|
||||
background-color: #b3d8ff !important; /* 表头背景色(保留之前的设置) */
|
||||
color: #333; /* 文字颜色加深,提升可读性 */
|
||||
font-weight: 500; /* 文字加粗 */
|
||||
}
|
||||
::v-deep .my-table .el-table__cell {
|
||||
padding: 0 2px; /* 减小列间距 */
|
||||
}
|
||||
|
||||
/* 可选:调整表格整体样式 */
|
||||
::v-deep .my-table {
|
||||
font-size: 13px; /* 适当减小字体 */
|
||||
}
|
||||
|
||||
::v-deep .my-table .el-table__cell,
|
||||
::v-deep .my-table .el-table__header-wrapper th {
|
||||
border-width: 1px;
|
||||
border-color: #ebeef5;
|
||||
}
|
||||
.card-content {
|
||||
max-height: 450px; /* 设置最大高度 */
|
||||
overflow-y: auto; /* 超出高度时显示垂直滚动条 */
|
||||
padding: 5px; /* 保持与卡片默认一致的内边距 */
|
||||
}
|
||||
.clickable:hover {
|
||||
cursor: pointer; /* 鼠标悬停时显示手型 */
|
||||
transition: all 0.3s; /* 平滑过渡效果 */
|
||||
color: blue;
|
||||
|
||||
}
|
||||
/* 汇总行样式 */
|
||||
.table-summary {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
padding: 6px 16px;
|
||||
margin-top: 8px;
|
||||
background-color: #f5f7fa;
|
||||
border: 1px solid #ebeef5;
|
||||
border-radius: 4px;
|
||||
font-weight: 500;
|
||||
line-height: 24px; /* 汇总行文字行高 */
|
||||
.summary-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-left: 24px;
|
||||
|
||||
.summary-label {
|
||||
color: #606266;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.summary-value {
|
||||
color: #303133;
|
||||
min-width: 40px;
|
||||
text-align: left;/* 核心:数值左对齐 */
|
||||
}
|
||||
/* 单独设置"单价合计"的值为红色 */
|
||||
&:nth-child(3) .summary-value {
|
||||
color: #f56c6c; /* Element UI 红色主题色 */
|
||||
font-weight: 600; /* 可选:加粗字体 */
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -62,4 +62,7 @@ export default defineConfig(({ mode, command }) => {
|
||||
}
|
||||
}
|
||||
}
|
||||
optimizeDeps: {
|
||||
include: ['jquery', 'select2', 'vue3-select2-component']
|
||||
}
|
||||
})
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user