打印
This commit is contained in:
parent
030a068b66
commit
4be4bf155f
@ -163,3 +163,19 @@ export function copyQcSample(data?: Object) {
|
|||||||
params: data
|
params: data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
//删除靶值
|
||||||
|
export function delQcSample(data?: Object) {
|
||||||
|
return request({
|
||||||
|
url: '/qc/delQcSample',
|
||||||
|
method: 'delete',
|
||||||
|
params: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
//查询质控室内数据(月统计)
|
||||||
|
export function getmonthst(data?: Object) {
|
||||||
|
return request({
|
||||||
|
url: '/qcstat/getmonthst',
|
||||||
|
method: 'get',
|
||||||
|
params: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@ -17,10 +17,20 @@ export const usePrintStore = defineStore('printStore', {
|
|||||||
},
|
},
|
||||||
setPrinterList(list: any[]) {
|
setPrinterList(list: any[]) {
|
||||||
this.printerList = list
|
this.printerList = list
|
||||||
this.defaultPrinter = list.find((p) => p.isDefault)?.name || ''
|
|
||||||
},
|
},
|
||||||
|
|
||||||
setDefaultPrinter(printerName: string) {
|
setDefaultPrinter(printerName: string) {
|
||||||
this.defaultPrinter = printerName
|
this.defaultPrinter = printerName
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 持久化配置
|
||||||
|
persist: {
|
||||||
|
// 指定要持久化的状态字段
|
||||||
|
pick: ['defaultPrinter',],
|
||||||
|
// 可选配置:自定义存储键名(默认是store的id)
|
||||||
|
// key: 'common_store',
|
||||||
|
// 可选配置:指定存储位置(默认是localStorage 也可以用sessionStorage)
|
||||||
|
storage: localStorage,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -21,7 +21,8 @@ const useUserStore = defineStore(
|
|||||||
roleName: '',
|
roleName: '',
|
||||||
avatar: '',
|
avatar: '',
|
||||||
roles: [],
|
roles: [],
|
||||||
permissions: []
|
permissions: [],
|
||||||
|
sysLoginParam: {}, // 登录参数
|
||||||
}),
|
}),
|
||||||
actions: {
|
actions: {
|
||||||
// 单点登录
|
// 单点登录
|
||||||
@ -48,9 +49,9 @@ const useUserStore = defineStore(
|
|||||||
const password = userInfo.password
|
const password = userInfo.password
|
||||||
const code = userInfo.code
|
const code = userInfo.code
|
||||||
const uuid = userInfo.uuid
|
const uuid = userInfo.uuid
|
||||||
const loginParam=userInfo.loginParam
|
const loginParam = userInfo.loginParam
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
login(username, password, code, uuid,loginParam).then(res => {
|
login(username, password, code, uuid, loginParam).then(res => {
|
||||||
setToken(res.token)
|
setToken(res.token)
|
||||||
this.token = res.token
|
this.token = res.token
|
||||||
resolve()
|
resolve()
|
||||||
@ -65,8 +66,9 @@ const useUserStore = defineStore(
|
|||||||
getInfo().then(res => {
|
getInfo().then(res => {
|
||||||
const user = res.user
|
const user = res.user
|
||||||
const rolelist = user.roles
|
const rolelist = user.roles
|
||||||
|
this.sysLoginParam = user.sysLoginParam
|
||||||
if (rolelist && rolelist.length > 0) {
|
if (rolelist && rolelist.length > 0) {
|
||||||
this.roleName=rolelist[0].roleName
|
this.roleName = rolelist[0].roleName
|
||||||
}
|
}
|
||||||
const avatar = (user.avatar == "" || user.avatar == null) ? defAva : import.meta.env.VITE_APP_BASE_API + user.avatar;
|
const avatar = (user.avatar == "" || user.avatar == null) ? defAva : import.meta.env.VITE_APP_BASE_API + user.avatar;
|
||||||
|
|
||||||
@ -78,7 +80,7 @@ const useUserStore = defineStore(
|
|||||||
}
|
}
|
||||||
this.id = user.userId
|
this.id = user.userId
|
||||||
this.name = user.userName
|
this.name = user.userName
|
||||||
this.nickName= user.nickName
|
this.nickName = user.nickName
|
||||||
this.avatar = avatar
|
this.avatar = avatar
|
||||||
resolve(res)
|
resolve(res)
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
|
|||||||
@ -110,12 +110,11 @@ interface PrintOptions {
|
|||||||
* @param urls PDF文件URL数组
|
* @param urls PDF文件URL数组
|
||||||
* @param options 打印选项(可选)
|
* @param options 打印选项(可选)
|
||||||
*/
|
*/
|
||||||
function silentPrint(urls: string[], options?: PrintOptions) {
|
function silentPrint(urls: string[], printName: string, options?: PrintOptions) {
|
||||||
if (urls.length === 0) return ElMessage.error('没有打印数据');
|
if (urls.length === 0) return ElMessage.error('没有打印数据');
|
||||||
const printStore = usePrintStore();
|
const printStore = usePrintStore();
|
||||||
const handlePrint = () => {
|
const handlePrint = () => {
|
||||||
ElMessage.success('正在打印文件,请稍候...');
|
urls.forEach(url => silentPrintPdf(url, printName, options));
|
||||||
urls.forEach(url => silentPrintPdf(url, options));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// 已连接直接打印,未连接则初始化后打印
|
// 已连接直接打印,未连接则初始化后打印
|
||||||
@ -133,14 +132,11 @@ function silentPrint(urls: string[], options?: PrintOptions) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//静默打印单个PDF文件
|
//静默打印单个PDF文件
|
||||||
function silentPrintPdf(url: string, options?: PrintOptions) {
|
function silentPrintPdf(url: string, printName: string, options?: PrintOptions) {
|
||||||
const printStore = usePrintStore();
|
const printStore = usePrintStore();
|
||||||
const templateId = `pdf-print-${Date.now()}`;
|
const templateId = `pdf-print-${Date.now()}`;
|
||||||
const targetPrinter = printStore.defaultPrinter;
|
const targetPrinter = printName;
|
||||||
if (!targetPrinter) {
|
ElMessage.success('正在打印文件,请稍候...');
|
||||||
console.log("未检测到打印机,请先连接打印机!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
socket?.emit("news", {
|
socket?.emit("news", {
|
||||||
client: clientInfo,
|
client: clientInfo,
|
||||||
printer: targetPrinter,
|
printer: targetPrinter,
|
||||||
@ -148,7 +144,7 @@ function silentPrintPdf(url: string, options?: PrintOptions) {
|
|||||||
templateId: templateId,
|
templateId: templateId,
|
||||||
pdf_path: url,
|
pdf_path: url,
|
||||||
});
|
});
|
||||||
// console.log(`🚀 PDF打印请求已发送,任务ID:${templateId},打印机:${targetPrinter}`);
|
console.log(`🚀 PDF打印请求已发送,任务ID:${templateId},打印机:${targetPrinter}`);
|
||||||
|
|
||||||
}
|
}
|
||||||
// 销毁
|
// 销毁
|
||||||
|
|||||||
@ -67,12 +67,14 @@
|
|||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button type="warning" :size="aotuSize" plain @click="cancelHandle">条码作废</el-button>
|
<el-button type="warning" :size="aotuSize" plain @click="cancelHandle">条码作废</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
<!-- <el-col :span="1.5">
|
|
||||||
<el-button type="warning" :size="aotuSize" plain>打印机设置</el-button>
|
|
||||||
</el-col>-->
|
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button type="warning" :size="aotuSize" plain @click="sendSampleHandle">清单打印</el-button>
|
<el-button type="warning" :size="aotuSize" plain @click="sendSampleHandle">清单打印</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
<el-col :span="4">
|
||||||
|
<el-select v-model="printName" placeholder="打印机设置" @visible-change="visibleChange" @change="changePrinter">
|
||||||
|
<el-option v-for="item in printerList" :key="item.name" :label="item.name" :value="item.name" />
|
||||||
|
</el-select>
|
||||||
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<CustomVxeTable :table-data="tableData" :loading="loading" :columns="columns" @current-change="rowHandle"
|
<CustomVxeTable :table-data="tableData" :loading="loading" :columns="columns" @current-change="rowHandle"
|
||||||
@ -186,12 +188,15 @@ const router = useRouter()
|
|||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
const printStore = usePrintStore();
|
const printStore = usePrintStore();
|
||||||
|
const printerList = computed(() => printStore.printerList);
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
import { getDicts } from '@/api/system/dict/data'
|
import { getDicts } from '@/api/system/dict/data'
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
const { proxy } = getCurrentInstance();
|
const { proxy } = getCurrentInstance();
|
||||||
const { lis_reqcx_type } = proxy.useDict("lis_reqcx_type"); //参数类别
|
const { lis_reqcx_type } = proxy.useDict("lis_reqcx_type"); //参数类别
|
||||||
const compactForm = ref<HTMLElement | null>(null);
|
const printName = ref(printStore.defaultPrinter || '');
|
||||||
|
|
||||||
|
|
||||||
const lisReqs: any = ref([])
|
const lisReqs: any = ref([])
|
||||||
const nickName = ref('')
|
const nickName = ref('')
|
||||||
const dialogVisible = ref(false)
|
const dialogVisible = ref(false)
|
||||||
@ -213,7 +218,7 @@ const queryParams = reactive<QueryParams>({
|
|||||||
st: '2025-07-18',
|
st: '2025-07-18',
|
||||||
et: '2025-07-18',
|
et: '2025-07-18',
|
||||||
yljg: '1',
|
yljg: '1',
|
||||||
zt: '2',
|
zt: '1',
|
||||||
queryType: '',
|
queryType: '',
|
||||||
queryValue: '',
|
queryValue: '',
|
||||||
ksdh: '',
|
ksdh: '',
|
||||||
@ -595,6 +600,18 @@ const sendSampleHandle = () => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const visibleChange = (visible: boolean) => {
|
||||||
|
if (visible) {
|
||||||
|
if (!printerList.value.length) {
|
||||||
|
HiprintPrinter.initSocket()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const changePrinter = (value: string) => {
|
||||||
|
printStore.setDefaultPrinter(value);
|
||||||
|
};
|
||||||
|
|
||||||
const timeDate = () => {
|
const timeDate = () => {
|
||||||
// 获取当前日期(当天)
|
// 获取当前日期(当天)
|
||||||
const today = dayjs();
|
const today = dayjs();
|
||||||
@ -735,6 +752,7 @@ const selectStatusRows = () => {
|
|||||||
|
|
||||||
// 打印pdf
|
// 打印pdf
|
||||||
const printPdf = () => {
|
const printPdf = () => {
|
||||||
|
if (!printName.value) return ElMessage.warning("未设置打印机,请先设置打印机!");
|
||||||
const selections = tableRef.value.allSelection()
|
const selections = tableRef.value.allSelection()
|
||||||
if (selections.length <= 0) return ElMessage.warning('请选择数据!')
|
if (selections.length <= 0) return ElMessage.warning('请选择数据!')
|
||||||
ElMessageBox.confirm(`确定打印选中的数据吗?`, "提示", {
|
ElMessageBox.confirm(`确定打印选中的数据吗?`, "提示", {
|
||||||
@ -752,7 +770,7 @@ const printPdf = () => {
|
|||||||
if (res.code == 0) {
|
if (res.code == 0) {
|
||||||
done();
|
done();
|
||||||
getList()
|
getList()
|
||||||
HiprintPrinter.silentPrint(res.data);
|
HiprintPrinter.silentPrint(res.data, printName.value);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -88,15 +88,12 @@
|
|||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button type="primary" plain icon="Upload" :size="aotuSize" @click="printPdf">打印报告</el-button>
|
<el-button type="primary" plain icon="Upload" :size="aotuSize" @click="printPdf">打印报告</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<!-- <right-toolbar v-model:showSearch="showSearch" @updateColumns="updateColumns" @queryTable="handleQuery"
|
|
||||||
:columns="columns"></right-toolbar> -->
|
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<CustomVxeTable :table-data="tableData" :loading="loading" :columns="columns" @current-change="rowHandle"
|
<CustomVxeTable :table-data="tableData" :loading="loading" :columns="columns" @current-change="rowHandle"
|
||||||
size="small" :scrollYConfig="{ enabled: true, rSize: 30, height: '100%', }" class="mytable-style"
|
size="small" :scrollYConfig="{ enabled: true, rSize: 30, height: '100%', }" class="mytable-style"
|
||||||
ref="tableRefs" :cell-style="cellStyleHd" @selection-change="selectionChange" :config="tableConfig"
|
ref="tableRefs" :row-style="rowClassNameHd" :cell-style="cellStyleHd" @selection-change="selectionChange"
|
||||||
:enable-column-drag="true" @column-drag-end="handleColumnDragEnd">
|
:config="tableConfig" :enable-column-drag="true" @column-drag-end="handleColumnDragEnd">
|
||||||
<template #dybz="{ row }">
|
<template #dybz="{ row }">
|
||||||
<svg-icon v-if="row.dybz == 1" icon-class="lvgou" />
|
<svg-icon v-if="row.dybz == 1" icon-class="lvgou" />
|
||||||
</template>
|
</template>
|
||||||
@ -186,6 +183,8 @@ import { HiprintPrinter } from '@/utils/hiprintPrinter';
|
|||||||
import * as echarts from 'echarts';
|
import * as echarts from 'echarts';
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
import { comDict } from '@/utils/dict'
|
import { comDict } from '@/utils/dict'
|
||||||
|
//@ts-ignore
|
||||||
|
import { getDicts } from '@/api/system/dict/data'
|
||||||
import { usePrintStore } from '@/store/modules/printStore'
|
import { usePrintStore } from '@/store/modules/printStore'
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
import useUserStore from '@/store/modules/user'
|
import useUserStore from '@/store/modules/user'
|
||||||
@ -194,7 +193,7 @@ const route = useRoute()
|
|||||||
const aotuSize = classCom.useAutoSize();
|
const aotuSize = classCom.useAutoSize();
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
const compactForm = ref<HTMLElement | null>(null);
|
const compactForm = ref<HTMLElement | null>(null);
|
||||||
const heightForm = ref(90);
|
const lisReqs: any = ref([])
|
||||||
const dialogVisible = ref(false)
|
const dialogVisible = ref(false)
|
||||||
const tableRefs = ref()
|
const tableRefs = ref()
|
||||||
const diaTableRef = ref()
|
const diaTableRef = ref()
|
||||||
@ -413,13 +412,35 @@ const cellStyleHd = ({ row, column, rowIndex, columnIndex }: {
|
|||||||
rowIndex: number;
|
rowIndex: number;
|
||||||
columnIndex: number;
|
columnIndex: number;
|
||||||
}) => {
|
}) => {
|
||||||
// console.log(row, column, rowIndex, columnIndex);
|
// // console.log(row, column, rowIndex, columnIndex);
|
||||||
if (column.title == "急" && row.jzbz == "1") {
|
// if (column.title == "急" && row.jzbz == "1") {
|
||||||
return { color: '#f00' };
|
// return { color: '#f00' };
|
||||||
|
// }
|
||||||
|
// if (column.title == "危" && row.alarmflag == "1") {
|
||||||
|
// return { color: '#f00' };
|
||||||
|
// }
|
||||||
|
};
|
||||||
|
|
||||||
|
const rowClassNameHd = ({ row, rowIndex }: {
|
||||||
|
row: any;
|
||||||
|
rowIndex: number;
|
||||||
|
}) => {
|
||||||
|
// 最高优先级:警告/异常
|
||||||
|
if (row.jzbz == "1" || row.alarmflag == "1") {
|
||||||
|
return {
|
||||||
|
backgroundColor: '#f00 !important',
|
||||||
|
color: '#000 !important',
|
||||||
|
};
|
||||||
}
|
}
|
||||||
if (column.title == "危" && row.alarmflag == "1") {
|
|
||||||
return { color: '#f00' };
|
if (row.jgbz == '2') {
|
||||||
|
return { background: '#C0FFC0 !important' };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (row.dybz == '1') {
|
||||||
|
return { background: '#C0C0C0 !important' };
|
||||||
|
}
|
||||||
|
return 'custom-row-class'; // 返回自定义类名
|
||||||
};
|
};
|
||||||
|
|
||||||
// 表格配置
|
// 表格配置
|
||||||
@ -852,8 +873,10 @@ onMounted(async () => {
|
|||||||
// 计算前6天的日期(当天 + 前6天 = 7天)
|
// 计算前6天的日期(当天 + 前6天 = 7天)
|
||||||
const startOfWeek = today.subtract(6, 'day');
|
const startOfWeek = today.subtract(6, 'day');
|
||||||
|
|
||||||
queryParams.st = route.query.startdate ? String(route.query.startdate) : startOfWeek.format('YYYY-MM-DD');
|
// queryParams.st = route.query.startdate ? String(route.query.startdate) : startOfWeek.format('YYYY-MM-DD');
|
||||||
queryParams.et = route.query.endate ? String(route.query.endate) : today.format('YYYY-MM-DD');
|
// queryParams.et = route.query.endate ? String(route.query.endate) : today.format('YYYY-MM-DD');
|
||||||
|
queryParams.st = '2025-08-07'
|
||||||
|
queryParams.et = '2025-08-14'
|
||||||
|
|
||||||
|
|
||||||
queryParams.ksdh = (route.query.deptcode as string) ? (route.query.deptcode as string) : '';
|
queryParams.ksdh = (route.query.deptcode as string) ? (route.query.deptcode as string) : '';
|
||||||
@ -863,6 +886,16 @@ onMounted(async () => {
|
|||||||
// 进入页面单点登录
|
// 进入页面单点登录
|
||||||
const result = await userStore.loginAnonymous({ name: queryParams.userid, yljg: queryParams.yljg })
|
const result = await userStore.loginAnonymous({ name: queryParams.userid, yljg: queryParams.yljg })
|
||||||
if (result) {
|
if (result) {
|
||||||
|
// 获取状态字典
|
||||||
|
getDicts('lis_req_type').then((resp: any) => {
|
||||||
|
lisReqs.value = resp.data.map((p: any) => ({
|
||||||
|
label: p.dictLabel,
|
||||||
|
value: p.dictValue,
|
||||||
|
elTagType: p.listClass,
|
||||||
|
elTagClass: p.cssClass
|
||||||
|
}))
|
||||||
|
|
||||||
|
})
|
||||||
getList()
|
getList()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1044,5 +1077,7 @@ const getList = () => {
|
|||||||
pointer-events: auto;
|
pointer-events: auto;
|
||||||
/* 允许鼠标交互 */
|
/* 允许鼠标交互 */
|
||||||
cursor: default;
|
cursor: default;
|
||||||
|
font-size: .875rem;
|
||||||
|
margin-top: .3125rem;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@ -2,62 +2,141 @@
|
|||||||
<div class="app-container">
|
<div class="app-container">
|
||||||
<div ref="compactForm">
|
<div ref="compactForm">
|
||||||
<el-row :gutter="5" class="compact-form" v-show="showSearch">
|
<el-row :gutter="5" class="compact-form" v-show="showSearch">
|
||||||
<el-form :model="queryParams" ref="queryRef" label-width="100px" :rules="queryRules" style="width: 100%;">
|
<el-form :model="queryParams" ref="queryRef" label-width="5rem" :rules="queryRules" style="width: 100%;"
|
||||||
|
size="small">
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="6">
|
<el-col :span="3">
|
||||||
<el-form-item label="标本日期:" prop="times">
|
<el-form-item label="部门组别:" prop="instrGroup">
|
||||||
<el-date-picker v-model="queryParams.times" type="daterange" range-separator="-"
|
<SelectTable v-model:data="queryParams.instrGroup" :fields="instrGroupFields"
|
||||||
start-placeholder="开始时间" end-placeholder="结束时间" format="YYYY-MM-DD" value-format="YYYY-MM-DD"
|
:tableData="instrGroupOptions" label="zdmc" value="zddh" objKey="zddh" :border="true" size="small"
|
||||||
@change="handletime" />
|
placeholder="请选择部门" :clearable="false" @get-data-value="getYqConfig" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="5">
|
<el-col :span="3">
|
||||||
<el-form-item label="打印状态:" prop="dybz">
|
<el-form-item label="仪器:" prop="yq">
|
||||||
<el-select v-model="queryParams.dybz" placeholder="请选择" clearable @change="handleQuery">
|
<SelectTable v-model:data="queryParams.yq" :tableData="instrOptions" width="100%" placeholder="请选择仪器"
|
||||||
<el-option label="已打印" value="1" />
|
clearable size="small" @getDataValue="getXmList" />
|
||||||
<el-option label="未打印" value="0" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="5">
|
|
||||||
<el-form-item label="科室:" prop="ksdh">
|
|
||||||
<SelectTable v-model:data="queryParams.ksdh" :fields="ksdhFields" :tableData="dictData.DP || []"
|
|
||||||
label="label" value="value" objKey="value" placeholder="请选择科室" @getDataValue="handleQuery" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="5">
|
|
||||||
<el-form-item label="病人类型:" prop="brlyname">
|
|
||||||
<SelectTable v-model:data="queryParams.brlyname" :fields="brlxFields" :tableData="dictData.PT || []"
|
|
||||||
label="label" value="label" objKey="label" placeholder="请选择" @getDataValue="handleQuery" />
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
</el-row>
|
<el-col :span="3">
|
||||||
<el-row>
|
<el-form-item label="申请号:" prop="sqh">
|
||||||
<el-col :span="6">
|
<el-input v-model="queryParams.sqh" clearable placeholder="请输入" @keyup.enter="handleQuery"
|
||||||
<el-form-item label-width="50px">
|
@clear="handleQuery" />
|
||||||
<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>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="5">
|
<el-col :span="3">
|
||||||
|
<el-form-item label="身份证号:" prop="brxm">
|
||||||
|
<el-input v-model="queryParams.sqh" clearable placeholder="请输入" @keyup.enter="handleQuery"
|
||||||
|
@clear="handleQuery" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="3">
|
||||||
|
<el-form-item label="病人类型:" prop="brly">
|
||||||
|
<SelectTable v-model:data="queryParams.brly" dictType="PT" placeholder="请选择" size="small"
|
||||||
|
@getDataValue="handleQuery" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="3">
|
||||||
|
<el-form-item label="送检医生:" prop="sjys">
|
||||||
|
<SelectTable v-model:data="queryParams.sjys" :fields="ysFields" :tableData="userList || []" size="small"
|
||||||
|
label="nickName" value="userName" objKey="userName" placeholder="请选择" @getDataValue="handleQuery" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<el-col :span="3">
|
||||||
|
<el-form-item label="检验医生:" prop="yhdh">
|
||||||
|
<SelectTable v-model:data="queryParams.yhdh" :fields="ysFields" :tableData="userList || []" size="small"
|
||||||
|
label="nickName" value="userName" objKey="userName" placeholder="请选择" @getDataValue="handleQuery" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<el-col :span="3">
|
||||||
|
<el-form-item label="标本类型:" prop="yblx">
|
||||||
|
<SelectTable v-model:data="queryParams.yblx" dictType="BT" placeholder="请选择" size="small"
|
||||||
|
@getDataValue="handleQuery" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
|
||||||
|
<el-col :span="3">
|
||||||
|
<el-form-item label="标本号:" prop="brxm">
|
||||||
|
<el-input v-model="queryParams.ch" clearable placeholder="请输入" @keyup.enter="handleQuery"
|
||||||
|
@clear="handleQuery" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="3">
|
||||||
|
<el-form-item label="检验项:" prop="brxm">
|
||||||
|
<SelectTable v-model:data="queryParams.yblx" :tableData="xmList" placeholder="请选择" size="small"
|
||||||
|
@getDataValue="handleQuery" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
|
||||||
|
<el-col :span="3">
|
||||||
|
<el-form-item label="科室:" prop="ksdh">
|
||||||
|
<SelectTable v-model:data="queryParams.ksdh" dictType='DP' placeholder="请选择科室" size="small"
|
||||||
|
@getDataValue="handleQuery" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<el-col :span="3">
|
||||||
<el-form-item label="姓名:" prop="brxm">
|
<el-form-item label="姓名:" prop="brxm">
|
||||||
<el-input v-model="queryParams.brxm" clearable placeholder="请输入姓名" @keyup.enter="handleQuery"
|
<el-input v-model="queryParams.brxm" clearable placeholder="请输入姓名" @keyup.enter="handleQuery"
|
||||||
@clear="handleQuery" />
|
@clear="handleQuery" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="5">
|
<el-col :span="3">
|
||||||
<el-form-item label="病人号:" prop="brdh">
|
<el-form-item label="病人号:" prop="brdh">
|
||||||
<el-input v-model="queryParams.brdh" clearable placeholder="请输入病人号" @keyup.enter="handleQuery"
|
<el-input v-model="queryParams.brdh" clearable placeholder="请输入病人号" @keyup.enter="handleQuery"
|
||||||
@clear="handleQuery" />
|
@clear="handleQuery" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="5">
|
<el-col :span="3">
|
||||||
<el-form-item label="床号:" prop="ch">
|
<el-form-item label="床号:" prop="ch">
|
||||||
<el-input v-model="queryParams.ch" clearable placeholder="请输入床号" @keyup.enter="handleQuery"
|
<el-input v-model="queryParams.ch" clearable placeholder="请输入床号" @keyup.enter="handleQuery"
|
||||||
@clear="handleQuery" />
|
@clear="handleQuery" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
<el-col :span="3">
|
||||||
|
<el-form-item label="打印状态:" prop="dybz">
|
||||||
|
<el-select v-model="queryParams.dybz" placeholder="请选择" clearable @change="handleQuery">
|
||||||
|
<el-option label="未打印" value="0" />
|
||||||
|
<el-option label="已打印" value="1" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="3">
|
||||||
|
<el-form-item label="审核状态:" prop="jgbz">
|
||||||
|
<el-select v-model="queryParams.jgbz" placeholder="请选择" clearable @change="handleQuery">
|
||||||
|
<el-option label="未审核" value="0" />
|
||||||
|
<el-option label="已审核" value="2" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
|
<el-form-item label="标本日期:" prop="times">
|
||||||
|
<el-date-picker v-model="queryParams.st" type="date" format="YYYY-MM-DD" value-format="YYYY-MM-DD"
|
||||||
|
@change="handletime" style="width: 47%" /> -
|
||||||
|
<el-date-picker v-model="queryParams.et" type="date" format="YYYY-MM-DD" value-format="YYYY-MM-DD"
|
||||||
|
@change="handletime" style="width: 47%" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="3">
|
||||||
|
<el-form-item label="备注:" prop="bz">
|
||||||
|
<el-input v-model="queryParams.bz" clearable placeholder="请输入" @keyup.enter="handleQuery"
|
||||||
|
@clear="handleQuery" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="3">
|
||||||
|
<el-form-item label="医疗机构:" prop="yljg">
|
||||||
|
<SelectTable v-model:data="queryParams.yljg" dictType="HOS" placeholder="请选择" size="small"
|
||||||
|
@getDataValue="handleQuery" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<el-checkbox v-model="queryParams.jzbz" label="急诊" true-value="1" false-value="0" />
|
||||||
|
<el-checkbox v-model="queryParams.dcny" label="多重耐药(细菌查询用)" true-value="1" false-value="0" />
|
||||||
<el-col :span="3">
|
<el-col :span="3">
|
||||||
<el-form-item label-width="50px">
|
<el-form-item label-width="50px">
|
||||||
<el-button icon="search" type="primary" @click="handleQuery">
|
<el-button icon="search" type="primary" @click="handleQuery">
|
||||||
@ -116,6 +195,20 @@
|
|||||||
</div>
|
</div>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
|
<!-- 样本流程 -->
|
||||||
|
<div class="time-line-box">
|
||||||
|
<div v-for="(item, i) in timelineItems" :key="i" class="time-line-item">
|
||||||
|
<div v-if="i != 0" class="timeline-connector">
|
||||||
|
<img class="timg" src="@/assets/images/yjt.png" alt="">
|
||||||
|
</div>
|
||||||
|
<div :class="['timeline-content', i > lastTimeIndex ? 'no_active' : '']">
|
||||||
|
<div :class="['index', lastTimeIndex == i ? 'active' : '']">{{ i + 1 }}</div>
|
||||||
|
<div class="timeline-title">{{ item.title }}</div>
|
||||||
|
<div class="timeline-time">{{ item.time }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -129,23 +222,30 @@ import SelectTable from '@/components/SelectTable/index.vue';
|
|||||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
import { classCom } from '@/utils/classCom'
|
import { classCom } from '@/utils/classCom'
|
||||||
import { HiprintPrinter } from '@/utils/hiprintPrinter';
|
import { HiprintPrinter } from '@/utils/hiprintPrinter';
|
||||||
import * as echarts from 'echarts';
|
import YQSelectTable from '@/components/SelectTable/YQSelectTable/index.vue';
|
||||||
//@ts-ignore
|
// @ts-ignore
|
||||||
import { comDict } from '@/utils/dict'
|
import { listhospital } from "@/api/regional/dict/hospital.js";
|
||||||
|
// @ts-ignore
|
||||||
|
import { listUser } from '@/api/system/user.js'
|
||||||
import { usePrintStore } from '@/store/modules/printStore'
|
import { usePrintStore } from '@/store/modules/printStore'
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
import useUserStore from '@/store/modules/user'
|
import useUserStore from '@/store/modules/user'
|
||||||
import { useRoute, useRouter } from 'vue-router'
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
|
import { getComDicts } from '@/api/liswork/dict/ComDict';
|
||||||
|
import { getGroupInstrdList, queryXmInfo } from '@/api/liswork/work/LisWork';
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const aotuSize = classCom.useAutoSize();
|
const aotuSize = classCom.useAutoSize();
|
||||||
|
const userStore = useUserStore()
|
||||||
const tableRefs = ref()
|
const tableRefs = ref()
|
||||||
|
|
||||||
|
|
||||||
interface QueryParams {
|
interface QueryParams {
|
||||||
times: string[]; // 明确类型为字符串元组
|
// times: string[]; // 明确类型为字符串元组
|
||||||
|
instrGroup: string;
|
||||||
|
yq: string;
|
||||||
|
st: string;
|
||||||
|
et: string;
|
||||||
alarmflag: boolean,
|
alarmflag: boolean,
|
||||||
jzbz: boolean,
|
jzbz: boolean,
|
||||||
ksdh: string,
|
ksdh: string,
|
||||||
@ -157,14 +257,25 @@ interface QueryParams {
|
|||||||
sqh: string,
|
sqh: string,
|
||||||
userid: string,
|
userid: string,
|
||||||
yljg: string,
|
yljg: string,
|
||||||
|
bz: string,
|
||||||
|
yblx: string,
|
||||||
|
yhdh: string,
|
||||||
|
sjys: string,
|
||||||
|
brly: string,
|
||||||
|
jgbz: string,
|
||||||
|
dcny: string
|
||||||
}
|
}
|
||||||
|
|
||||||
// 提交表单数据
|
// 提交表单数据
|
||||||
const queryParams = reactive<QueryParams>({
|
const queryParams = reactive<QueryParams>({
|
||||||
times: ['2025-08-19', '2025-08-19'],
|
// times: ['2025-08-19', '2025-08-19'],
|
||||||
|
instrGroup: '',
|
||||||
|
yq: '',
|
||||||
|
st: '',
|
||||||
|
et: '',
|
||||||
ksdh: '0210',
|
ksdh: '0210',
|
||||||
brlyname: '',
|
brlyname: '',
|
||||||
sqh: '25080109476',
|
sqh: '',
|
||||||
alarmflag: false,
|
alarmflag: false,
|
||||||
jzbz: false,
|
jzbz: false,
|
||||||
brxm: '',
|
brxm: '',
|
||||||
@ -172,7 +283,14 @@ const queryParams = reactive<QueryParams>({
|
|||||||
ch: '',
|
ch: '',
|
||||||
dybz: '',
|
dybz: '',
|
||||||
userid: '',
|
userid: '',
|
||||||
yljg: '1'
|
yljg: userStore.sysLoginParam.loginYLJG,
|
||||||
|
bz: '',
|
||||||
|
yblx: '',
|
||||||
|
yhdh: '',
|
||||||
|
sjys: '',
|
||||||
|
brly: '',
|
||||||
|
jgbz: '',
|
||||||
|
dcny: ''
|
||||||
});
|
});
|
||||||
|
|
||||||
const single = ref(true);
|
const single = ref(true);
|
||||||
@ -187,18 +305,39 @@ const Info = ref<any>({})
|
|||||||
const queryRules = ref({
|
const queryRules = ref({
|
||||||
|
|
||||||
})
|
})
|
||||||
|
const ysFields = ref([
|
||||||
|
{ prop: 'userName', label: '用户代号', width: 80, enablePinyinSearch: true },
|
||||||
|
{ prop: 'nickName', label: '用户姓名', width: 150, enablePinyinSearch: true },
|
||||||
|
])
|
||||||
const handletime = (val: Array<string>) => {
|
const handletime = (val: Array<string>) => {
|
||||||
// console.log('时间', val);
|
|
||||||
// 校验日期格式
|
// 校验日期格式
|
||||||
const dayDiff = getDayDiff(val[0], val[1]);
|
const dayDiff = getDayDiff(queryParams.st, queryParams.et);
|
||||||
if (dayDiff === -1) return ElMessage.warning('请选择有效的日期范围');
|
if (dayDiff === -1 || dayDiff === -2) return ElMessage.warning('请选择有效的日期范围');
|
||||||
//校验是否超过7天
|
|
||||||
if (dayDiff > 7) return ElMessage.warning('查询时间范围不能超过7天,请重新选择');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 时间线数据
|
||||||
|
const timelineItems = ref(
|
||||||
|
[
|
||||||
|
{ title: '检验申请', time: '' },
|
||||||
|
{ title: '标本采集', time: '' },
|
||||||
|
{ title: '上机检验', time: '' },
|
||||||
|
{ title: '标本送检', time: '' },
|
||||||
|
// { title: '检验接收', time: '' },
|
||||||
|
{ title: '标本签收', time: '' },
|
||||||
|
{ title: '结果审核', time: '' },
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
// 计算最后一个有时间的节点索引
|
||||||
|
const lastTimeIndex = computed(() => {
|
||||||
|
|
||||||
|
const lastIndex = timelineItems.value.findLastIndex(item => item.time);
|
||||||
|
if (lastIndex === -1) {
|
||||||
|
return -1
|
||||||
|
} else {
|
||||||
|
return lastIndex;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const handleQuery = async () => {
|
const handleQuery = async () => {
|
||||||
const valid = await queryRef.value.validate().catch(() => { });
|
const valid = await queryRef.value.validate().catch(() => { });
|
||||||
@ -245,7 +384,7 @@ const columns = ref([
|
|||||||
{ field: 'hdys', title: '核对医生', align: 'center', resizable: true, width: 60 },
|
{ field: 'hdys', title: '核对医生', align: 'center', resizable: true, width: 60 },
|
||||||
{ field: 'zd', title: '临床诊断', align: 'center', resizable: true, width: 100 },
|
{ field: 'zd', title: '临床诊断', align: 'center', resizable: true, width: 100 },
|
||||||
{ field: 'bz', title: '备注', align: 'center', resizable: true, width: 100 },
|
{ field: 'bz', title: '备注', align: 'center', resizable: true, width: 100 },
|
||||||
{ field: 'sjysname', title: '审核人', align: 'center', resizable: true, width: 60 },
|
{ field: 'shysname', title: '审核人', align: 'center', resizable: true, width: 60 },
|
||||||
{ field: 'confirmtime', title: '审核时间', align: 'center', resizable: true, width: 80 },
|
{ field: 'confirmtime', title: '审核时间', align: 'center', resizable: true, width: 80 },
|
||||||
{ field: 'zh', title: '最后修改人', align: 'center', resizable: true, width: 100 },
|
{ field: 'zh', title: '最后修改人', align: 'center', resizable: true, width: 100 },
|
||||||
{ field: 'zhtime', title: '最后修改时间', align: 'center', resizable: true, width: 100 },
|
{ field: 'zhtime', title: '最后修改时间', align: 'center', resizable: true, width: 100 },
|
||||||
@ -276,6 +415,16 @@ const rowHandle = (row: any) => {
|
|||||||
rightColumns.value[6].visible = false
|
rightColumns.value[6].visible = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
timelineItems.value =
|
||||||
|
[
|
||||||
|
{ title: '检验申请', time: row.sqsj },
|
||||||
|
{ title: '标本采集', time: row.cysj },
|
||||||
|
{ title: '上机检验', time: row.zxsj },
|
||||||
|
{ title: '标本送检', time: row.bbsjsj },
|
||||||
|
// { title: '检验接收', time: row.jssj},
|
||||||
|
{ title: '标本签收', time: row.jssj },
|
||||||
|
{ title: '结果审核', time: row.confirmtime },
|
||||||
|
]
|
||||||
|
|
||||||
Info.value = row
|
Info.value = row
|
||||||
const data = {
|
const data = {
|
||||||
@ -416,18 +565,22 @@ const jzbzHandle = (val: boolean) => {
|
|||||||
getList()
|
getList()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const xmList = ref([])
|
||||||
|
const getXmList = () => {
|
||||||
const ksdhFields = ref([
|
const data = {
|
||||||
{ prop: 'value', label: '代号', width: 80, enablePinyinSearch: true },
|
yq: queryParams.yq,
|
||||||
{ prop: 'label', label: '名称', enablePinyinSearch: true },
|
pageSize: 1000,
|
||||||
])
|
pageNum: 1
|
||||||
|
}
|
||||||
const brlxFields = ref([
|
queryXmInfo(data).then((res: any) => {
|
||||||
{ prop: 'value', label: '代号', width: 80, enablePinyinSearch: true },
|
xmList.value = res.data.map((item: any) => {
|
||||||
{ prop: 'label', label: '名称', enablePinyinSearch: true },
|
return {
|
||||||
])
|
label: item.xmmc,
|
||||||
|
value: item.xmdh
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// 右侧数据源
|
// 右侧数据源
|
||||||
@ -472,7 +625,7 @@ const rightTableConfig = ref(
|
|||||||
{
|
{
|
||||||
// stripe: true, // 斑马纹
|
// stripe: true, // 斑马纹
|
||||||
border: true, // 边框
|
border: true, // 边框
|
||||||
height: '68vh', // 高度
|
height: '63vh', // 高度
|
||||||
highlightCurrentRow: true, // 高亮当前行
|
highlightCurrentRow: true, // 高亮当前行
|
||||||
cellStyle: rightCellStyleHd
|
cellStyle: rightCellStyleHd
|
||||||
}
|
}
|
||||||
@ -512,7 +665,7 @@ const xmrowHandle = (row: any) => {
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
rightTableConfig.value.height = `68vh`
|
rightTableConfig.value.height = `63vh`
|
||||||
rightTableRef.value?.doLayout && rightTableRef.value.doLayout();
|
rightTableRef.value?.doLayout && rightTableRef.value.doLayout();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -520,12 +673,6 @@ const xmrowHandle = (row: any) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const periods = ref<string[]>([])
|
|
||||||
|
|
||||||
const compareTableData = ref([])
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 右侧数据源
|
// 右侧数据源
|
||||||
const bottomTableData = ref([])
|
const bottomTableData = ref([])
|
||||||
// 配置项
|
// 配置项
|
||||||
@ -554,63 +701,83 @@ const bottomTableConfig = ref(
|
|||||||
{
|
{
|
||||||
// stripe: true, // 斑马纹
|
// stripe: true, // 斑马纹
|
||||||
border: true, // 边框
|
border: true, // 边框
|
||||||
height: '37vh', // 高度
|
height: '32vh', // 高度
|
||||||
highlightCurrentRow: true, // 高亮当前行
|
highlightCurrentRow: true, // 高亮当前行
|
||||||
cellStyle: botCellStyleHd
|
cellStyle: botCellStyleHd
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
interface DictData {
|
|
||||||
DP?: Array<any>;
|
|
||||||
PT?: Array<any>;
|
const instrGroupOptions = ref<any[]>([])
|
||||||
[key: string]: any[] | undefined; // 添加索引签名以支持动态访问
|
const instrGroupFields = ref([
|
||||||
|
{ prop: 'zddh', label: '代号', width: 80, enablePinyinSearch: true },
|
||||||
|
{ prop: 'zdmc', label: '名称', width: 150, enablePinyinSearch: true },
|
||||||
|
])
|
||||||
|
// 部门
|
||||||
|
const getinstrGroupOptions = () => {
|
||||||
|
getComDicts({ zdlb: 'GROUP' }).then((res: any) => {
|
||||||
|
instrGroupOptions.value = res.data
|
||||||
|
instrGroupOptions.value.push({ zddh: 'ALL', zdmc: '所有仪器' })
|
||||||
|
// getYqConfig()
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
const instrOptions = ref([])
|
||||||
|
// 仪器
|
||||||
// 字典数据存储
|
const getYqConfig = () => {
|
||||||
const dictData = ref<DictData>({});
|
getGroupInstrdList({ lisgroup: queryParams.instrGroup })
|
||||||
|
.then((res: any) => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
instrOptions.value = res.data.map((item: any) => ({
|
||||||
|
value: item.yq.trim(),
|
||||||
|
label: item.yqmc
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const userList = ref([]);
|
||||||
|
const hosList = ref([]);
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
|
const data = { status: 0, del_flag: 0, pageSize: 1000, pageNum: 1 }
|
||||||
|
listUser(data).then((res: any) => {
|
||||||
|
userList.value = res.rows;
|
||||||
|
});
|
||||||
|
getinstrGroupOptions()
|
||||||
// 获取当前日期(当天)
|
// 获取当前日期(当天)
|
||||||
const today = dayjs();
|
const today = dayjs();
|
||||||
|
|
||||||
// 计算前6天的日期(当天 + 前6天 = 7天)
|
// 计算前6天的日期(当天 + 前6天 = 7天)
|
||||||
const startOfWeek = today.subtract(6, 'day');
|
const startOfWeek = today.subtract(6, 'day');
|
||||||
|
|
||||||
const startDate = route.query.startdate ? String(route.query.startdate) : startOfWeek.format('YYYY-MM-DD');
|
queryParams.st = route.query.startdate ? String(route.query.startdate) : startOfWeek.format('YYYY-MM-DD');
|
||||||
const endDate = route.query.endate ? String(route.query.endate) : today.format('YYYY-MM-DD');
|
queryParams.et = route.query.endate ? String(route.query.endate) : today.format('YYYY-MM-DD');
|
||||||
|
|
||||||
// queryParams.times = [startDate, endDate];
|
// queryParams.times = [startDate, endDate];
|
||||||
|
|
||||||
|
listhospital().then((res: any) => {
|
||||||
|
hosList.value = res.rows.map((item: any) => {
|
||||||
|
return {
|
||||||
|
label: item.hospitalName,
|
||||||
|
value: item.hospitalId.toString()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
getList()
|
getList()
|
||||||
|
|
||||||
|
|
||||||
// 加载病人来源字典
|
|
||||||
const dictRefs = await comDict('PT', 'DP');
|
|
||||||
|
|
||||||
// 从 ref 中获取实际数据
|
|
||||||
dictData.value = {
|
|
||||||
PT: toRaw(dictRefs.PT.value) || [],
|
|
||||||
DP: toRaw(dictRefs.DP.value) || [],
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const formatDict = (v: string, dictType: string) => {
|
|
||||||
return dictData.value[dictType]?.find((item: any) => item.value == v)?.label || v;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 计算两个日期的天数差(支持带时分秒)
|
// 计算两个日期的天数差(支持带时分秒)
|
||||||
const getDayDiff = (start: string, end: string): number => {
|
const getDayDiff = (start: string, end: string): number => {
|
||||||
const startTime = new Date(start).getTime();
|
const startTime = new Date(start).getTime();
|
||||||
const endTime = new Date(end).getTime();
|
const endTime = new Date(end).getTime();
|
||||||
|
|
||||||
// 校验日期有效性
|
|
||||||
if (isNaN(startTime) || isNaN(endTime)) {
|
if (isNaN(startTime) || isNaN(endTime)) {
|
||||||
return -1; // 无效日期
|
return -2; // -2 表示日期无效
|
||||||
}
|
}
|
||||||
|
|
||||||
// 计算毫秒差 → 转换为天数(向上取整,避免因时分秒导致的误差)
|
const dayDiff = Math.ceil((endTime - startTime) / (24 * 60 * 60 * 1000));
|
||||||
return Math.ceil((endTime - startTime) / (24 * 60 * 60 * 1000));
|
return dayDiff < 0 ? -1 : dayDiff; // -1 表示结束时间早于开始时间,>=0 为正常天数
|
||||||
};
|
};
|
||||||
const getList = () => {
|
const getList = () => {
|
||||||
|
|
||||||
@ -624,27 +791,17 @@ const getList = () => {
|
|||||||
brdh: queryParams.brdh,
|
brdh: queryParams.brdh,
|
||||||
ch: queryParams.ch,
|
ch: queryParams.ch,
|
||||||
userid: queryParams.userid,
|
userid: queryParams.userid,
|
||||||
st: '',
|
st: queryParams.st,
|
||||||
et: '',
|
et: queryParams.et,
|
||||||
yljg: queryParams.yljg,
|
yljg: queryParams.yljg,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!data.ksdh) return ElMessage.error('科室代号不能为空');
|
if (!data.ksdh) return ElMessage.error('科室代号不能为空');
|
||||||
if (!data.yljg) return ElMessage.error('医疗机构yljg不能为空');
|
if (!data.yljg) return ElMessage.error('医疗机构yljg不能为空');
|
||||||
// 校验日期格式
|
// 校验日期格式
|
||||||
const dayDiff = getDayDiff(queryParams.times[0], queryParams.times[1]);
|
const dayDiff = getDayDiff(queryParams.st, queryParams.et);
|
||||||
if (dayDiff === -1) return ElMessage.warning('请选择有效的日期范围');
|
if (dayDiff === -1 || dayDiff === -2) return ElMessage.warning('请选择有效的日期范围');
|
||||||
|
|
||||||
//校验是否超过7天
|
|
||||||
if (dayDiff > 7) return ElMessage.warning('查询时间范围不能超过7天,请重新选择');
|
|
||||||
|
|
||||||
if (queryParams.times && queryParams.times.length) {
|
|
||||||
data.st = queryParams.times[0]
|
|
||||||
data.et = queryParams.times[1]
|
|
||||||
} else {
|
|
||||||
data.st = ''
|
|
||||||
data.et = ''
|
|
||||||
}
|
|
||||||
loading.value = true
|
loading.value = true
|
||||||
reportList(data).then((res: any) => {
|
reportList(data).then((res: any) => {
|
||||||
if (res.code == 0) {
|
if (res.code == 0) {
|
||||||
@ -667,7 +824,7 @@ const getList = () => {
|
|||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.mytable-style {
|
.mytable-style {
|
||||||
height: 68vh;
|
height: 63vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tips {
|
.tips {
|
||||||
@ -682,7 +839,7 @@ const getList = () => {
|
|||||||
border-bottom: 1px solid #E1E9F7;
|
border-bottom: 1px solid #E1E9F7;
|
||||||
|
|
||||||
.el-form-item {
|
.el-form-item {
|
||||||
margin-bottom: .625rem;
|
margin-bottom: .3125rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -43,7 +43,7 @@
|
|||||||
{{ row.xmdh }} {{ row.xmmc }}
|
{{ row.xmdh }} {{ row.xmmc }}
|
||||||
</template>
|
</template>
|
||||||
<template #zkbz="{ row }">
|
<template #zkbz="{ row }">
|
||||||
<el-input v-model="row.zkbz" class="full-width-input" />
|
<el-input v-model="row.zkbz" class="full-width-input" @change="handleZkbzEnter(row)" />
|
||||||
</template>
|
</template>
|
||||||
<template #sd="{ row }">
|
<template #sd="{ row }">
|
||||||
<el-input v-model="row.sd" class="full-width-input" @change="handleSdEnter(row)" />
|
<el-input v-model="row.sd" class="full-width-input" @change="handleSdEnter(row)" />
|
||||||
@ -90,8 +90,8 @@
|
|||||||
<template #sjph="{ row }">
|
<template #sjph="{ row }">
|
||||||
{{ formatDict(row.sjph, 'LOT') }}
|
{{ formatDict(row.sjph, 'LOT') }}
|
||||||
</template>
|
</template>
|
||||||
<template #action="{ row }">
|
<template #action="{ row, $index }">
|
||||||
<el-button type="danger" text @click="delBzHandle(row)">删除</el-button>
|
<el-button type="danger" v-if="$index != 0" text @click="delBzHandle(row)">删除</el-button>
|
||||||
</template>
|
</template>
|
||||||
</CustomTable>
|
</CustomTable>
|
||||||
</div>
|
</div>
|
||||||
@ -193,7 +193,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { queryBatch, queryValXmdh, queryBatchXm, delBatchno, addBatchno, updateBatchno, saveBtQcSample, copyQcSample } from '@/api/liswork/qualityControl'
|
import { queryBatch, queryValXmdh, queryBatchXm, delBatchno, addBatchno, updateBatchno, saveBtQcSample, copyQcSample, delQcSample } from '@/api/liswork/qualityControl'
|
||||||
import { templateRef } from '@vueuse/core'
|
import { templateRef } from '@vueuse/core'
|
||||||
import { formatDict, getDictData, dictData } from '@/hooks';
|
import { formatDict, getDictData, dictData } from '@/hooks';
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
@ -393,6 +393,11 @@ const batchClick = (row: any) => {
|
|||||||
getXmList(row)
|
getXmList(row)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleZkbzEnter = (row: any) => {
|
||||||
|
// cv = sd * 100 / zkbz
|
||||||
|
row.cv = row.sd * 100 / row.zkbz
|
||||||
|
}
|
||||||
|
|
||||||
const handleSdEnter = (row: any) => {
|
const handleSdEnter = (row: any) => {
|
||||||
// cv = sd * 100 / zkbz
|
// cv = sd * 100 / zkbz
|
||||||
row.cv = row.sd * 100 / row.zkbz
|
row.cv = row.sd * 100 / row.zkbz
|
||||||
@ -412,6 +417,7 @@ const getBatchList = () => {
|
|||||||
tableData.value = res.data || []
|
tableData.value = res.data || []
|
||||||
if (tableData.value.length) {
|
if (tableData.value.length) {
|
||||||
getXmList(tableData.value[0])
|
getXmList(tableData.value[0])
|
||||||
|
batchInfo.value = tableData.value[0]
|
||||||
leftTableRef.value.setCurrentRow(tableData.value[0])
|
leftTableRef.value.setCurrentRow(tableData.value[0])
|
||||||
} else {
|
} else {
|
||||||
topTableData.value = []
|
topTableData.value = []
|
||||||
@ -446,7 +452,7 @@ const subHandle = () => {
|
|||||||
zkph: selectedRow.value.zkph,
|
zkph: selectedRow.value.zkph,
|
||||||
newyq: copyFormData.value.yq,
|
newyq: copyFormData.value.yq,
|
||||||
newzkpph: copyFormData.value.newzkpph,
|
newzkpph: copyFormData.value.newzkpph,
|
||||||
newzkph: selectedRow.value.zkph,
|
newzkph: copyFormData.value.newzkph,
|
||||||
newstartda: copyFormData.value.newstartda,
|
newstartda: copyFormData.value.newstartda,
|
||||||
newdtflag: copyFormData.value.newdtflag
|
newdtflag: copyFormData.value.newdtflag
|
||||||
}
|
}
|
||||||
@ -481,7 +487,12 @@ const delBzHandle = (row: any) => {
|
|||||||
ElMessageBox.confirm('确定要删除这个靶值吗,可能会影响其区间内的质控计算?', '提示', {
|
ElMessageBox.confirm('确定要删除这个靶值吗,可能会影响其区间内的质控计算?', '提示', {
|
||||||
type: 'warning'
|
type: 'warning'
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
console.log("🚀 ~ delBzHandle ~ row:", row)
|
delQcSample(row).then((res: any) => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
ElMessage.success('删除成功')
|
||||||
|
batchClick(batchInfo.value)
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
const handleSave = () => {
|
const handleSave = () => {
|
||||||
|
|||||||
173
src/views/liswork/qualityControl/indoorStatistics/index.vue
Normal file
173
src/views/liswork/qualityControl/indoorStatistics/index.vue
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
/**
|
||||||
|
* @file index.vue 室内质控数据统计表
|
||||||
|
* @author: w
|
||||||
|
* @since: 2026-01-22
|
||||||
|
*/
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<el-form :model="queryParams" inline class="demo-form-inline">
|
||||||
|
<el-form-item label="仪器:">
|
||||||
|
<YQSelectTable v-model:data="queryParams.yq" style="width: 150px;" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="质控月份:">
|
||||||
|
<el-date-picker v-model="queryParams.zkrq" type="month" placeholder="请选择检查时间" value-format="YYYY-MM" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="质控品号:">
|
||||||
|
<el-input v-model="queryParams.zkph" placeholder="请输入" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="质控批号:">
|
||||||
|
<el-input v-model="queryParams.zkpph" placeholder="请输入" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="getList">查询</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<div>
|
||||||
|
<el-button type="primary" plain @click="printHandle">打印</el-button>
|
||||||
|
<el-button type="primary" plain @click="viewHandle">预览</el-button>
|
||||||
|
<el-button type="primary" plain @click="skHandle">失控总结</el-button>
|
||||||
|
<el-button type="primary" plain @click="byHandle">本月总结</el-button>
|
||||||
|
</div>
|
||||||
|
<div class="title">{{ formatDict(userStore.sysLoginParam.loginYLJG, 'HOS') }}</div>
|
||||||
|
<div class="content">室内质控数据统计表</div>
|
||||||
|
<div class="info">
|
||||||
|
<div> 专业组:<span></span></div>
|
||||||
|
<div> 仪器:<span>{{ queryParams.yq }}</span> </div>
|
||||||
|
<div> 浓度: <span></span></div>
|
||||||
|
<div> 质控品号:<span>{{ queryParams.zkph }}</span> </div>
|
||||||
|
<div> 质控月份:<span>{{ queryParams.zkrq }}</span> </div>
|
||||||
|
</div>
|
||||||
|
<div class="table-container">
|
||||||
|
<el-table :data="tableData" height="100%" border highlightCurrentRow>
|
||||||
|
<el-table-column label="质控项目" prop="xmdh" align="center" />
|
||||||
|
<el-table-column label="测定数" prop="cnt" align="center" />
|
||||||
|
<el-table-column label="失控数" prop="badcnt" align="center" />
|
||||||
|
<el-table-column label="失控率%" prop="skl" align="center" />
|
||||||
|
<el-table-column label="处理率%" prop="cll" align="center" />
|
||||||
|
<el-table-column label="绘图基准数据" align="center">
|
||||||
|
<el-table-column label="靶值" prop="avg0" align="center" />
|
||||||
|
<el-table-column label="基准SD" prop="sd0" align="center" />
|
||||||
|
<el-table-column label="CV(%)" prop="cv0" align="center" />
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="本月原始数据" align="center">
|
||||||
|
<el-table-column label="原始均值" prop="avg1" align="center" />
|
||||||
|
<el-table-column label="SD" prop="sd1" align="center" />
|
||||||
|
<el-table-column label="CV(%)" prop="cv1" align="center" />
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="本月非失控数据" align="center">
|
||||||
|
<el-table-column label="在控均值" prop="avg2" align="center" />
|
||||||
|
<el-table-column label="SD" prop="sd2" align="center" />
|
||||||
|
<el-table-column label="CV(%)" prop="cv2" align="center" />
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="累计数据" align="center">
|
||||||
|
<el-table-column label="累计次数" prop="cnt3" align="center" />
|
||||||
|
<el-table-column label="累计均值" prop="avg3" align="center" />
|
||||||
|
<el-table-column label="SD" prop="sd3" align="center" />
|
||||||
|
<el-table-column label="CV(%)" prop="cv3" align="center" />
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="质控批号" prop="zkpph" align="center" />
|
||||||
|
<el-table-column label="标准CV(%)" prop="qccv" align="center" />
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-dialog v-model="dialogVisible" :title="title" width="30%">
|
||||||
|
<el-input v-model="inputValue" type="textarea" :rows="10" placeholder="请输入内容" />
|
||||||
|
<template #footer>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
|
<el-button type="primary" @click="subHandle">确 定</el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup name="IndoorStatistics">
|
||||||
|
import { getDictData, formatDict } from '@/hooks'
|
||||||
|
import { useCommonStore } from '@/store/modules/commonStore';
|
||||||
|
import useUserStore from '@/store/modules/user'
|
||||||
|
import YQSelectTable from '@/components/SelectTable/YQSelectTable/index.vue'
|
||||||
|
import { getmonthst } from '@/api/liswork/qualityControl/index'
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
const userStore = useUserStore()
|
||||||
|
const mbStore = useCommonStore();
|
||||||
|
const tableData = ref([])
|
||||||
|
|
||||||
|
const queryParams = reactive({
|
||||||
|
yq: mbStore.defaultConfig.defaultinstr || '1',
|
||||||
|
zkrq: dayjs().format('YYYY-MM'),
|
||||||
|
zkph: '1',
|
||||||
|
zkpph: ''
|
||||||
|
})
|
||||||
|
|
||||||
|
const inputValue = ref('')
|
||||||
|
const dialogVisible = ref(false)
|
||||||
|
const title = ref('')
|
||||||
|
|
||||||
|
const printHandle = () => {
|
||||||
|
|
||||||
|
}
|
||||||
|
const viewHandle = () => {
|
||||||
|
|
||||||
|
}
|
||||||
|
const skHandle = () => {
|
||||||
|
title.value = '失控总结'
|
||||||
|
dialogVisible.value = true
|
||||||
|
}
|
||||||
|
const byHandle = () => {
|
||||||
|
title.value = '本月总结'
|
||||||
|
dialogVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const subHandle = () => {
|
||||||
|
inputValue.value = ''
|
||||||
|
dialogVisible.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
const getList = () => {
|
||||||
|
getmonthst(queryParams).then((res) => {
|
||||||
|
tableData.value = res.data || []
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
getList()
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getDictData('HOS')
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.title {
|
||||||
|
font-size: 20px;
|
||||||
|
text-align: center;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
font-size: 16px;
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 10px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
margin: 10px 0;
|
||||||
|
|
||||||
|
span {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 5px 10px;
|
||||||
|
border-bottom: 1px solid #000;
|
||||||
|
min-width: 100px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-container {
|
||||||
|
height: calc(100% - 200px);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
372
src/views/liswork/qualityControl/qcgraph/index.vue
Normal file
372
src/views/liswork/qualityControl/qcgraph/index.vue
Normal file
@ -0,0 +1,372 @@
|
|||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<el-form :model="queryParams" ref="queryRef" :inline="true" label-width="40px">
|
||||||
|
<!-- 原有表单项 -->
|
||||||
|
<el-form-item label="区间">
|
||||||
|
<el-date-picker v-model="queryParams.st" type="date" format="YYYY-MM-DD" value-format="YYYY-MM-DD"
|
||||||
|
style="width:150px" /> -
|
||||||
|
<el-date-picker v-model="queryParams.et" type="date" format="YYYY-MM-DD" value-format="YYYY-MM-DD"
|
||||||
|
style="width:150px" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="仪器">
|
||||||
|
<SelectTable v-model:data="queryParams.yq" :tableData="instrOptions" width="150px" clearable
|
||||||
|
@get-data-value="getDataValue" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-checkbox label="不分批号" value="1" />
|
||||||
|
<el-checkbox label="多图" v-model="isMultiChart" @change="getEcharts" />
|
||||||
|
<el-checkbox label="最好值画图" value="1" />
|
||||||
|
</el-form-item>
|
||||||
|
<div>
|
||||||
|
<el-form-item label=" ">
|
||||||
|
<el-radio-group v-model="queryParams.radio1">
|
||||||
|
<el-radio value="1">单仪器</el-radio>
|
||||||
|
<el-radio value="2">多仪器</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label=" ">
|
||||||
|
<el-checkbox-group v-model="selectedLevels" @change="handleLevelChange">
|
||||||
|
<el-checkbox v-for="level in 6" :key="level" :label="`水平${level}`" :value="level" />
|
||||||
|
</el-checkbox-group>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<el-row :gutter="10" class="table-row">
|
||||||
|
<!-- 原有表格和图表容器 -->
|
||||||
|
<el-col :span="4" class="table-col">
|
||||||
|
<div style="height: 30%">
|
||||||
|
<CustomTable ref="topTableRef" :data="topTableData" :columns="topColumns"
|
||||||
|
:config="{ border: true, highlightCurrentRow: true, height: '100%', }" />
|
||||||
|
</div>
|
||||||
|
<div style="height: 70%">
|
||||||
|
<CustomTable ref="bottomTableRef" :data="bottomTableData" :columns="bottomColumns"
|
||||||
|
:config="{ border: true, highlightCurrentRow: true, height: '100%', }">
|
||||||
|
<template #xmdh="{ row }">
|
||||||
|
{{ row.xmdh }} {{ row.xmmc }}
|
||||||
|
</template>
|
||||||
|
</CustomTable>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="20" class="table-col">
|
||||||
|
<div class="tips">
|
||||||
|
仪器:{{ yqmc }} 质控项目:{{ xmInfo.xmdh }} {{ xmInfo.xmmc }}
|
||||||
|
区间:{{ queryParams.st }} - {{ queryParams.et }}
|
||||||
|
</div>
|
||||||
|
<div class="echarts-box">
|
||||||
|
<div v-if="isMultiChart" class="charts-container">
|
||||||
|
<div v-for="(item, index) in filteredChartData" :key="index" ref="multiEcharts"
|
||||||
|
style="width: 100%; height: 300px; margin-bottom: 10px;"></div>
|
||||||
|
</div>
|
||||||
|
<div v-else ref="myEcharts" style="width: 100%; height: 300px;"></div>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { getGroupInstrdList } from '@/api/liswork/work/LisWork';
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
import { queryBatch, queryBatchXm } from '@/api/liswork/qualityControl';
|
||||||
|
import { useCommonStore } from '@/store/modules/commonStore';
|
||||||
|
const mbStore = useCommonStore();
|
||||||
|
import * as echarts from 'echarts';
|
||||||
|
|
||||||
|
const isMultiChart = ref(false);
|
||||||
|
// 原始水平图表数据
|
||||||
|
const chartData = ref([
|
||||||
|
{ label: '水平1', arr: [1, 2, 0, 4, 5, 3] },
|
||||||
|
{ label: '水平2', arr: [2, -3, 2, 3, 4, 5] },
|
||||||
|
{ label: '水平3', arr: [5, 4, 3, -2, 1, -2.3] },
|
||||||
|
{ label: '水平4', arr: [0, 1, 2.1, 3, 4, 5] },
|
||||||
|
{ label: '水平5', arr: [3, 3, -3, 3.2, 3, 3] },
|
||||||
|
{ label: '水平6', arr: [6, 5, -4, 3, 2, 1] },
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 定义选中的水平数组(双向绑定复选框)
|
||||||
|
const selectedLevels = ref([1, 2]); // 默认选中水平1
|
||||||
|
|
||||||
|
// 计算属性 - 根据选中的水平过滤图表数据
|
||||||
|
const filteredChartData = computed(() => {
|
||||||
|
if (selectedLevels.value.length === 0) return []; // 未选中时返回空
|
||||||
|
return chartData.value.filter(item => {
|
||||||
|
// 从label中提取水平数字(如"水平1"→1)
|
||||||
|
const level = Number(item.label.replace('水平', ''));
|
||||||
|
return selectedLevels.value.includes(level);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const queryParams = reactive({
|
||||||
|
yq: mbStore.defaultConfig.defaultinstr || '46',
|
||||||
|
st: "",
|
||||||
|
et: "",
|
||||||
|
radio1: "1"
|
||||||
|
});
|
||||||
|
|
||||||
|
const yqmc = ref("")
|
||||||
|
const topTableData = ref([])
|
||||||
|
const topColumns = [
|
||||||
|
{ label: "批号", prop: "zkpph", visible: true },
|
||||||
|
{ label: "启用日期", prop: "startda", visible: true },
|
||||||
|
];
|
||||||
|
|
||||||
|
const bottomTableData = ref([])
|
||||||
|
const bottomColumns = [
|
||||||
|
{ label: "项目", prop: "xmdh", visible: true, slot: 'xmdh' },
|
||||||
|
];
|
||||||
|
|
||||||
|
const getBatchList = async () => {
|
||||||
|
const res = await queryBatch(queryParams);
|
||||||
|
if (res.code == 0) {
|
||||||
|
topTableData.value = res.data;
|
||||||
|
if (res.data.length) {
|
||||||
|
getXmList(res.data[0])
|
||||||
|
} else {
|
||||||
|
bottomTableData.value = []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const xmInfo = ref({})
|
||||||
|
const getXmList = async (row) => {
|
||||||
|
queryBatchXm({ yq: queryParams.yq, zkpph: row.zkpph, zkph: row.zkph }).then((res) => {
|
||||||
|
bottomTableData.value = res.data
|
||||||
|
xmInfo.value = res.data[0]
|
||||||
|
getEcharts()
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 单/多图表容器
|
||||||
|
const myEcharts = ref();
|
||||||
|
const multiEcharts = ref([]);
|
||||||
|
// 颜色配置(扩展到6个水平)
|
||||||
|
const color = ['#6696ee', '#5da761', '#2b63b3', '#ff646a', '#f99b11', '#9370db'];
|
||||||
|
|
||||||
|
// 封装转折点颜色判断函数
|
||||||
|
const getSymbolColor = (value, defaultColor) => {
|
||||||
|
if (Math.abs(value) > 3) {
|
||||||
|
return '#ff0000'; // 红色
|
||||||
|
} else if (Math.abs(value) > 2) {
|
||||||
|
return '#ffc0cb'; // 粉色
|
||||||
|
}
|
||||||
|
return defaultColor; // 其他值用默认颜色
|
||||||
|
};
|
||||||
|
|
||||||
|
const getEcharts = () => {
|
||||||
|
const xAxisData = ['1', '2', '3', '4', '5', '6'];
|
||||||
|
|
||||||
|
// 多图模式
|
||||||
|
if (isMultiChart.value) {
|
||||||
|
// 清空原有图表实例
|
||||||
|
multiEcharts.value.forEach(chartDom => {
|
||||||
|
if (chartDom) {
|
||||||
|
const chartInstance = echarts.getInstanceByDom(chartDom);
|
||||||
|
if (chartInstance) chartInstance.dispose();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 遍历过滤后的水平数据渲染图表
|
||||||
|
filteredChartData.value.forEach((item, index) => {
|
||||||
|
const chartDom = multiEcharts.value[index];
|
||||||
|
if (!chartDom) return;
|
||||||
|
|
||||||
|
const instance = echarts.init(chartDom);
|
||||||
|
const seriesData = [{
|
||||||
|
name: item.label,
|
||||||
|
type: 'line',
|
||||||
|
symbol: 'circle',
|
||||||
|
showAllSymbol: true,
|
||||||
|
symbolSize: 7,
|
||||||
|
smooth: true,
|
||||||
|
lineStyle: { color: color[index], width: 1.5 }, // 线条保持原有颜色
|
||||||
|
itemStyle: {
|
||||||
|
// 按数据点数值动态设置转折点颜色
|
||||||
|
color: (params) => getSymbolColor(params.value, color[index]),
|
||||||
|
shadowColor: color[index],
|
||||||
|
shadowBlur: index === 0 ? 10 : 0,
|
||||||
|
},
|
||||||
|
data: item.arr,
|
||||||
|
}];
|
||||||
|
|
||||||
|
const option = {
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
tooltip: { show: true },
|
||||||
|
grid: { top: '10%', left: '2%', right: '10%', bottom: '10%', containLabel: true },
|
||||||
|
legend: {
|
||||||
|
show: true,
|
||||||
|
left: '5%',
|
||||||
|
bottom: '0%',
|
||||||
|
itemWidth: 7,
|
||||||
|
itemHeight: 7,
|
||||||
|
itemGap: 15,
|
||||||
|
textStyle: { color: '#000', fontSize: 12 },
|
||||||
|
data: [{
|
||||||
|
name: item.label,
|
||||||
|
icon: index > 2 ? 'path://m0.010277,5.945418l24.979446,0l0,2.109164l-24.979446,0l0,-2.109164z' : 'circle',
|
||||||
|
itemStyle: { shadowColor: color[index], shadowBlur: index === 0 ? 10 : 0 },
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
boundaryGap: true,
|
||||||
|
data: xAxisData,
|
||||||
|
axisLine: { lineStyle: { color: '#305cd0' } },
|
||||||
|
axisTick: { show: true, alignWithLabel: true },
|
||||||
|
axisLabel: { color: '#474747' },
|
||||||
|
},
|
||||||
|
yAxis: [{
|
||||||
|
name: 'SD',
|
||||||
|
type: 'value',
|
||||||
|
inverse: false,
|
||||||
|
splitLine: { show: true, lineStyle: { type: 'dashed' } },
|
||||||
|
axisLabel: { formatter: '{value}', color: '#474747', fontSize: 14 },
|
||||||
|
axisTick: { show: false },
|
||||||
|
}],
|
||||||
|
series: seriesData,
|
||||||
|
};
|
||||||
|
|
||||||
|
instance.setOption(option);
|
||||||
|
window.addEventListener('resize', () => instance.resize());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// 单图模式
|
||||||
|
else {
|
||||||
|
// 清空原有单图表实例
|
||||||
|
if (myEcharts.value) {
|
||||||
|
const chartInstance = echarts.getInstanceByDom(myEcharts.value);
|
||||||
|
if (chartInstance) chartInstance.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
const instance = echarts.init(myEcharts.value);
|
||||||
|
const seriesData = [];
|
||||||
|
const legendData = [];
|
||||||
|
|
||||||
|
// 遍历过滤后的水平数据
|
||||||
|
filteredChartData.value.forEach((item, index) => {
|
||||||
|
seriesData.push({
|
||||||
|
name: item.label,
|
||||||
|
type: 'line',
|
||||||
|
symbol: 'circle',
|
||||||
|
showAllSymbol: true,
|
||||||
|
symbolSize: 7,
|
||||||
|
smooth: true, // 折线图圆滑
|
||||||
|
lineStyle: { color: color[index], width: 1.5 }, // 线条保持原有颜色
|
||||||
|
itemStyle: {
|
||||||
|
// 按数据点数值动态设置转折点颜色
|
||||||
|
color: (params) => getSymbolColor(params.value, color[index]),
|
||||||
|
shadowColor: color[index],
|
||||||
|
shadowBlur: index === 0 ? 10 : 0,
|
||||||
|
},
|
||||||
|
data: item.arr,
|
||||||
|
});
|
||||||
|
|
||||||
|
legendData.push({
|
||||||
|
name: item.label,
|
||||||
|
icon: index > 2 ? 'path://m0.010277,5.945418l24.979446,0l0,2.109164l-24.979446,0l0,-2.109164z' : 'circle',
|
||||||
|
itemStyle: { shadowColor: color[index], shadowBlur: index === 0 ? 10 : 0 },
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const option = {
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
tooltip: { show: true },
|
||||||
|
grid: { top: '10%', left: '2%', right: '10%', bottom: '10%', containLabel: true },
|
||||||
|
legend: {
|
||||||
|
show: true,
|
||||||
|
left: '5%',
|
||||||
|
bottom: '0%',
|
||||||
|
itemWidth: 7,
|
||||||
|
itemHeight: 7,
|
||||||
|
itemGap: 15,
|
||||||
|
textStyle: { color: '#000', fontSize: 12 },
|
||||||
|
data: legendData,
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
boundaryGap: true,
|
||||||
|
data: xAxisData,
|
||||||
|
axisLine: { lineStyle: { color: '#305cd0' } },
|
||||||
|
axisTick: { show: true, alignWithLabel: true },
|
||||||
|
axisLabel: { color: '#474747' },
|
||||||
|
},
|
||||||
|
yAxis: [{
|
||||||
|
name: 'SD',
|
||||||
|
type: 'value',
|
||||||
|
inverse: false,
|
||||||
|
splitLine: { show: true, lineStyle: { type: 'dashed' } },
|
||||||
|
// axisLine: { show: true, lineStyle: { color: '#305cd0' } },
|
||||||
|
axisLabel: { formatter: '{value}', color: '#474747', fontSize: 14 },
|
||||||
|
axisTick: { show: false },
|
||||||
|
}],
|
||||||
|
series: seriesData,
|
||||||
|
};
|
||||||
|
|
||||||
|
instance.setOption(option);
|
||||||
|
window.addEventListener('resize', () => instance.resize());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//水平复选框变化时重新渲染图表
|
||||||
|
const handleLevelChange = () => {
|
||||||
|
getEcharts();
|
||||||
|
};
|
||||||
|
|
||||||
|
getBatchList();
|
||||||
|
|
||||||
|
const getDataValue = (value) => {
|
||||||
|
console.log('value==>', value);
|
||||||
|
yqmc.value = value.yqmc;
|
||||||
|
};
|
||||||
|
|
||||||
|
const instrOptions = ref([]);
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
const today = dayjs();
|
||||||
|
const startOfWeek = today.subtract(6, 'day');
|
||||||
|
queryParams.st = startOfWeek.format('YYYY-MM-DD');
|
||||||
|
queryParams.et = today.format('YYYY-MM-DD');
|
||||||
|
|
||||||
|
getGroupInstrdList().then((res) => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
instrOptions.value = res.data.map((item) => ({
|
||||||
|
value: item.yq.trim(),
|
||||||
|
label: item.yqmc,
|
||||||
|
}));
|
||||||
|
yqmc.value = instrOptions.value.find(item => item.value === queryParams.yq)?.label;
|
||||||
|
getEcharts(); // 初始化时渲染图表
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.table-row {
|
||||||
|
height: calc(100% - 90px);
|
||||||
|
|
||||||
|
.table-col {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.echarts-box {
|
||||||
|
height: calc(100% - 50px);
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-form-item {
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tips {
|
||||||
|
font-family: SourceHanSansCN, SourceHanSansCN;
|
||||||
|
font-size: 16px;
|
||||||
|
color: #409eff;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.charts-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -67,8 +67,11 @@
|
|||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button type="warning" :size="aotuSize" plain>清单打印</el-button>
|
<el-button type="warning" :size="aotuSize" plain>清单打印</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
<!-- <right-toolbar v-model:showSearch="showSearch" @updateColumns="updateColumns" @queryTable="handleQuery"
|
<el-col :span="4">
|
||||||
:columns="columns"></right-toolbar> -->
|
<el-select v-model="printName" placeholder="打印机设置" @visible-change="visibleChange" @change="changePrinter">
|
||||||
|
<el-option v-for="item in printerList" :key="item.name" :label="item.name" :value="item.name" />
|
||||||
|
</el-select>
|
||||||
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<CustomTable ref="tableRef" :data="tableData" :columns="columns" :config="tableConfig" :loading="loading"
|
<CustomTable ref="tableRef" :data="tableData" :columns="columns" :config="tableConfig" :loading="loading"
|
||||||
@ -174,6 +177,8 @@ import SelectTable from '@/components/SelectTable/index.vue';
|
|||||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const printStore = usePrintStore();
|
const printStore = usePrintStore();
|
||||||
|
const printerList = computed(() => printStore.printerList);
|
||||||
|
const printName = ref(printStore.defaultPrinter || '');
|
||||||
const compactForm = ref<HTMLElement | null>(null);
|
const compactForm = ref<HTMLElement | null>(null);
|
||||||
const heightForm = ref(90);
|
const heightForm = ref(90);
|
||||||
const dialogVisible = ref(false)
|
const dialogVisible = ref(false)
|
||||||
@ -543,6 +548,18 @@ const cancelHandle = () => {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const visibleChange = (visible: boolean) => {
|
||||||
|
if (visible) {
|
||||||
|
if (!printerList.value.length) {
|
||||||
|
HiprintPrinter.initSocket()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const changePrinter = (value: string) => {
|
||||||
|
printStore.setDefaultPrinter(value);
|
||||||
|
};
|
||||||
|
|
||||||
const hosList = ref([])
|
const hosList = ref([])
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
// 初始化3天区间(今天-前两天)
|
// 初始化3天区间(今天-前两天)
|
||||||
@ -653,6 +670,7 @@ const selectStatusRows = () => {
|
|||||||
|
|
||||||
// 打印pdf
|
// 打印pdf
|
||||||
const printPdf = () => {
|
const printPdf = () => {
|
||||||
|
if (!printName.value) return ElMessage.warning("未设置打印机,请先设置打印机!");
|
||||||
if (sqhs.value.length <= 0) return ElMessage.warning('请选择数据!')
|
if (sqhs.value.length <= 0) return ElMessage.warning('请选择数据!')
|
||||||
ElMessageBox.confirm(`确定打印选中的数据吗?`, "提示", {
|
ElMessageBox.confirm(`确定打印选中的数据吗?`, "提示", {
|
||||||
confirmButtonText: "确认",
|
confirmButtonText: "确认",
|
||||||
@ -669,7 +687,7 @@ const printPdf = () => {
|
|||||||
if (res.code == 0) {
|
if (res.code == 0) {
|
||||||
done();
|
done();
|
||||||
getList()
|
getList()
|
||||||
HiprintPrinter.silentPrint(res.data);
|
HiprintPrinter.silentPrint(res.data, printName.value);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user