申请单签收查询

This commit is contained in:
wuyy 2026-03-19 18:00:24 +08:00
parent e71eb5929f
commit eb35f434d8
16 changed files with 1071 additions and 338 deletions

View File

@ -5,7 +5,7 @@ import request from '@/utils/request';
// 查询条码类别 // 查询条码类别
export function feeitemclassList(query?: Object) { export function feeitemclassList(query?: Object) {
return request({ return request({
url: 'feeitemclass/query', url: '/transitdict/itemclass/list',
method: 'get', method: 'get',
params: query, params: query,
}); });
@ -129,10 +129,18 @@ export function rptgetruleDelDetail(query?: Object) {
params: query, params: query,
}); });
} }
// 查询条码类别与项目对照 // 获取条码已对照项目
export function feeitemvsList(query?: Object) { export function feeitemvsList(query?: Object) {
return request({ return request({
url: '/feeitemvsclass/query', url: '/item/compare',
method: 'get',
params: query,
});
}
// 获取条码未对照项目
export function noCompareList(query?: Object) {
return request({
url: '/item/noCompare',
method: 'get', method: 'get',
params: query, params: query,
}); });
@ -145,11 +153,11 @@ export function feeitemvAdd(query?: Object) {
data: query, data: query,
}); });
} }
// 保存对照的项目 // 删除对照的项目
export function feeitemvDel(query?: Object) { export function feeitemvDel(query?: Object) {
return request({ return request({
url: '/feeitemvsclass/del', url: '/item/update',
method: 'delete', method: 'post',
params: query, data: query,
}); });
} }

View File

@ -56,4 +56,45 @@ export function getallcount(query?: Object) {
method: 'get', method: 'get',
params: query params: query
}) })
} }
// 获取流转项目列表
export function getXmList(query?: Object) {
return request({
url: '/item/getList',
method: 'get',
params: query
})
}
// 新增项目
export function addXmInfo(query?: Object) {
return request({
url: '/item/add',
method: 'post',
data: query
})
}
// 修改项目
export function updateXmInfo(query?: Object) {
return request({
url: '/item/update',
method: 'post',
data: query
})
}
// 删除项目
export function deleteXmInfo(query?: Object) {
return request({
url: '/item/delete',
method: 'post',
data: query
})
}
// 获取已打印的条码数据
export function sampleCollect(query?: Object) {
return request({
url: '/transit/sampleCollect',
method: 'get',
params: query
})
}

View File

@ -28,6 +28,9 @@
</template> </template>
</vxe-column> </vxe-column>
<vxe-column v-bind="column" v-if="column.field"> <vxe-column v-bind="column" v-if="column.field">
<template v-if="column.headerSlot" #header="scope">
<slot :name="column.headerSlot" :column="scope.column" :$index="scope.$index" />
</template>
<!-- 自定义列模板 --> <!-- 自定义列模板 -->
<template v-if="column.slotName" #default="scope"> <template v-if="column.slotName" #default="scope">
<slot :name="column.slotName" :row="scope.row" :$index="scope.$rowIndex"></slot> <slot :name="column.slotName" :row="scope.row" :$index="scope.$rowIndex"></slot>
@ -37,7 +40,7 @@
<!-- 操作列 --> <!-- 操作列 -->
<vxe-column v-if="$slots.action" :title="config.actionLabel || '操作'" :width="config.actionWidth" <vxe-column v-if="$slots.action" :title="config.actionLabel || '操作'" :width="config.actionWidth"
:fixed="config.actionFixed || 'right'" :align="config.actionAlign || 'center'"> :fixed="config.actionFixed || ''" :align="config.actionAlign || 'center'">
<template #default="scope"> <template #default="scope">
<slot name="action" :row="scope.row" :column="scope.column" :$index="scope.$index" /> <slot name="action" :row="scope.row" :column="scope.column" :$index="scope.$index" />
</template> </template>

View File

@ -49,7 +49,7 @@ export const constantRoutes = [
}, },
// 大屏 // 大屏
{ {
path: '/regional/statistics/overview', path: '/statistics/overview',
component: () => import('@/views/regional/statistics/overview/index.vue'), component: () => import('@/views/regional/statistics/overview/index.vue'),
hidden: true hidden: true
}, },

145
src/utils/groupHelper.ts Normal file
View File

@ -0,0 +1,145 @@
// 定义通用类型
interface GroupOriginValues {
[key: string]: string | number | null | undefined
}
interface GroupMetaItem {
groupSeq: number
key: string
originValues: GroupOriginValues
itemCount: number
firstRowIndex: number | null
}
// @ts-ignore
interface GroupedItem<T> extends T {
rowSeq: number // 组内行序号
groupSeq?: number // 组序号(可选)
}
interface GroupData<T> {
groupSeq: number
key: string
originValues: GroupOriginValues
items: GroupedItem<T>[]
}
interface UseGroupTableDataReturn<T> {
tableData: ComputedRef<(GroupedItem<T> & { [key: string]: string | number | '' })[]>
groupMeta: ComputedRef<GroupMetaItem[]>
groupedData: ComputedRef<GroupData<T>[]>
}
/**
* 通用多字段分组函数
* @param rawList - 原始数据列表
* @param groupFields - 分组字段(单个字段传字符串,多个传数组)
* @param showFields - 每组仅第一条显示的字段
* @param sortField - 排序字段(默认按orderDate降序)
* @param originalData - 原始数据赋值字段(可选)
* @returns 表格渲染数据 + 分组元信息
*/
export function useGroupTableData<T extends Record<string, any>>(
rawList: string[],
groupFields: string,
showFields: string | string[],
sortField: string = 'orderDate',
originalData: string[]
): UseGroupTableDataReturn<T> {
// 处理参数格式:确保为数组
const groupFieldArr = Array.isArray(groupFields) ? groupFields : [groupFields]
const showFieldArr = Array.isArray(showFields) ? showFields : [showFields]
// 1. 核心分组逻辑
const groupedData = computed<GroupData<T>[]>(() => {
const groups: Record<string, {
key: string
originValues: GroupOriginValues
items: GroupedItem<T>[]
}> = {}
rawList.forEach((item: any) => {
// 生成分组key(多字段拼接,避免重复)
const groupKey = groupFieldArr.map(field => item[field] ?? '').join('_')
if (!groups[groupKey]) {
groups[groupKey] = {
key: groupKey,
originValues: groupFieldArr.reduce((obj, field) => {
obj[field] = item[field] ?? ''
return obj
}, {} as GroupOriginValues),
items: []
}
}
// 处理仅第一条显示的字段
showFieldArr.forEach((field, i) => {
originalData.forEach((v, _i) => {
if (i == _i) {
item[field] = item[v]
}
})
})
// 添加组内行序号
groups[groupKey].items.push({
...item,
rowSeq: groups[groupKey].items.length + 1
})
})
// 2. 按指定字段降序排序分组
const sortedGroupKeys = Object.keys(groups).sort((a, b) => {
const aSortValue = groups[a].originValues[sortField] ?? ''
const bSortValue = groups[b].originValues[sortField] ?? ''
// 兼容日期/字符串/数字排序
if (aSortValue && bSortValue && !isNaN(new Date(aSortValue).getTime())) {
return new Date(bSortValue).getTime() - new Date(aSortValue).getTime()
}
return String(bSortValue).localeCompare(String(aSortValue))
})
// 3. 生成带组序号的分组数据
return sortedGroupKeys.map((key, groupIndex) => ({
groupSeq: groupIndex + 1,
...groups[key]
}))
})
// 4. 构造扁平化表格数据
const tableData = computed(() => {
const result: (GroupedItem<T> & { [key: string]: string | number | '' })[] = []
groupedData.value.forEach(group => {
group.items.forEach((item, idx) => {
const processedItem = { ...item }
// 处理仅第一条显示的字段
showFieldArr.forEach(field => {
processedItem[field] = idx === 0 ? (item[field] ?? '') : ''
})
// 组序号仅每组第一条显示
processedItem.groupSeq = idx === 0 ? group.groupSeq : ''
result.push(processedItem)
})
})
return result
})
// 5. 生成分组元信息(用于合并单元格)
const groupMeta = computed<GroupMetaItem[]>(() => {
return groupedData.value.map(group => ({
groupSeq: group.groupSeq,
key: group.key,
originValues: group.originValues,
itemCount: group.items.length,
firstRowIndex: null
}))
})
return {
tableData,
groupMeta,
groupedData
}
}

View File

@ -1,8 +1,8 @@
<template> <template>
<div class="labpat_box"> <div class="labpat_box">
<el-form :model="labPat" label-width="5rem" label-position="right" class="left-form "> <el-form :model="labPat" label-width="5rem" label-position="right" class="left-form">
<div :class="['sh_box', getColor(lastJgbz)]" v-if="lastJgbz > 10"> <div :class="['sh_box', getColor(newStatus)]" v-if="newStatus > 10">
<div class="text">{{ getLableType(lastJgbz) }}</div> <div class="text">{{ getLableType(newStatus) }}</div>
</div> </div>
<el-form-item label="病人来源"> <el-form-item label="病人来源">
<!-- <el-col :span="16"> --> <!-- <el-col :span="16"> -->
@ -14,7 +14,7 @@
</el-col> --> </el-col> -->
</el-form-item> </el-form-item>
<el-form-item label="病人代号" required> <el-form-item label="病人代号" required>
<el-input v-model="labPat.patId" @keyup.enter="brdhHandle" /> <el-input v-model="labPat.patId" @change="brdhHandle" />
</el-form-item> </el-form-item>
<el-form-item label="姓 名" required> <el-form-item label="姓 名" required>
<el-input v-model="labPat.patName" @change="handleFieldChange" /> <el-input v-model="labPat.patName" @change="handleFieldChange" />
@ -38,11 +38,11 @@
</el-form-item> </el-form-item>
<el-form-item label="送检医生"> <el-form-item label="送检医生">
<SelectTable v-model:data="labPat.doctorCode" :tableData="dictData.DOCTOR" placeholder="" <SelectTable v-model:data="labPat.doctorCode" :tableData="dictData.DOCTOR" placeholder=""
@getDataValue="handleFieldChange" /> @getDataValue="doctorHandle" />
</el-form-item> </el-form-item>
<el-form-item label="送检科室"> <el-form-item label="送检科室">
<SelectTable v-model:data="labPat.execDeptCode" :table-data="dictData.DEPT" placeholder="" <SelectTable v-model:data="labPat.execDeptCode" :table-data="dictData.DEPT" placeholder=""
@getDataValue="handleFieldChange" /> @getDataValue="deptHandle" />
</el-form-item> </el-form-item>
<el-form-item label="床 号"> <el-form-item label="床 号">
<el-input v-model="labPat.patBed" @change="handleFieldChange" /> <el-input v-model="labPat.patBed" @change="handleFieldChange" />
@ -80,13 +80,9 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
// import { queryPatInfo } from '@/api/liswork/order'
import SelectTable from '@/components/SelectTable/index.vue'; import SelectTable from '@/components/SelectTable/index.vue';
import { getDictData, formatDict, dictData } from '@/hooks' import { getDictData, formatDict, dictData } from '@/hooks'
// @ts-ignore
import { listUser } from '@/api/system/user.js'
//@ts-ignore
import { getDicts } from '@/api/system/dict/data'
const props = defineProps({ const props = defineProps({
labPat: { labPat: {
type: Object, type: Object,
@ -98,15 +94,13 @@ const props = defineProps({
default: () => { } default: () => { }
}, },
}); });
const lastJgbz = ref(); const newStatus = ref('');
watch(() => props.labPat, (newVal: any) => { watch(() => props.labPat.status, (newVal: any) => {
lastValue.value = JSON.stringify(newVal); newStatus.value = newVal;
lastJgbz.value = newVal.status;
}) })
const emit = defineEmits(['update:labPat']); const emit = defineEmits(['update:labPat', 'getBrdh']);
const lastValue = ref('');
const brlyFields = ref([ const brlyFields = ref([
{ prop: 'value', label: '代号', width: 80, enablePinyinSearch: true }, { prop: 'value', label: '代号', width: 80, enablePinyinSearch: true },
@ -117,31 +111,16 @@ const ysFields = ref([
{ prop: 'userName', label: '用户代号', width: 80, enablePinyinSearch: true }, { prop: 'userName', label: '用户代号', width: 80, enablePinyinSearch: true },
{ prop: 'nickName', label: '用户姓名', width: 150, enablePinyinSearch: true }, { prop: 'nickName', label: '用户姓名', width: 150, enablePinyinSearch: true },
]) ])
/**
* 通用字段变化处理(失焦、回车触发)
*/
const handleFieldChange = async () => {
// // 将当前labPat转为字符串用于比较
// const currentValue = JSON.stringify(props.labPat);
// // 对比与上一次保存的值是否有变化
// if (currentValue !== lastValue.value) {
// // 找出变化的字段 const doctorHandle = (data) => {
// const oldObj = JSON.parse(lastValue.value); props.labPat.doctorName = data.label
// const newObj = props.labPat; }
// const changedField = getChangedField(oldObj, newObj); const deptHandle = (data) => {
// if (changedField) { props.labPat.execDeptName = data.label
// // 这里可以添加实际的更新逻辑,比如调用接口 }
// try {
// // saveLabPat(changedField) const handleFieldChange = async () => {
// } catch (error) {
// console.error('更新失败:', error);
// // 失败时可以恢复旧值
// // emit('update:labPat', oldObj);
// lastValue.value = JSON.stringify(oldObj);
// }
// }
// }
}; };
const getLableType = (type: string) => { const getLableType = (type: string) => {
@ -170,22 +149,11 @@ const getColor = (type: string) => {
// 病人代号查询病人信息的逻辑 // 病人代号查询病人信息的逻辑
const brdhHandle = () => { const brdhHandle = () => {
// queryPatInfo({ brdh: props.labPat.brdh }).then((res: any) => { emit('getBrdh', props.labPat.patId)
// if (res.data) {
// emit('update:labPat', { ...props.labPat, ...res.data })
// }
// })
} }
const userList = ref([]);
onMounted(() => { onMounted(() => {
const data = { status: '0', del_flag: '0', pageSize: 1000, pageNum: 1 }
listUser(data).then((res: any) => {
userList.value = res.rows;
});
}) })
@ -259,14 +227,13 @@ onMounted(() => {
} }
.left-form { .left-form {
flex: 1; flex: 1;
position: relative; position: relative;
height: 100%; height: 100%;
overflow-y: auto; overflow-y: auto;
overflow-x: hidden; overflow-x: hidden;
padding-top: 5px;
.el-form-item { .el-form-item {
margin-bottom: 8px; margin-bottom: 8px;

View File

@ -13,6 +13,8 @@
<el-col :span="7"> <el-col :span="7">
<el-button type="primary" size="small" :loading="saveLoading" @click="saveHandle">保存</el-button> <el-button type="primary" size="small" :loading="saveLoading" @click="saveHandle">保存</el-button>
<el-button type="primary" size="small" @click="addHandle">新增</el-button> <el-button type="primary" size="small" @click="addHandle">新增</el-button>
<el-button type="primary" size="small" @click="printHandle">打印</el-button>
<el-button type="danger" size="small" @click="deleteHandle">作废</el-button>
</el-col> </el-col>
<el-col :span="17"> <el-col :span="17">
<div class="tips"> <div class="tips">
@ -23,7 +25,7 @@
</el-row> </el-row>
<el-row :gutter="5" style="height: 100%;"> <el-row :gutter="5" style="height: 100%;">
<el-col :span="7"> <el-col :span="7">
<Info v-model:labPat="labpat" /> <Info v-model:labPat="labpat" @getBrdh="getBrdhHandle" />
</el-col> </el-col>
<el-col :span="17" style="height: 100%;"> <el-col :span="17" style="height: 100%;">
<el-tabs v-model="activeName" type="card" class="tabs_box" @tab-click="handleTabClick"> <el-tabs v-model="activeName" type="card" class="tabs_box" @tab-click="handleTabClick">
@ -32,7 +34,7 @@
</el-tabs> </el-tabs>
<div style="height: calc(60% - 1.875rem)" class="mb5"> <div style="height: calc(60% - 1.875rem)" class="mb5">
<CustomVxeTable :table-data="filterData" :columns="xmColumns" @cell-dblclick="dbRowclick" <CustomVxeTable :table-data="filterData" :columns="xmColumns" @cell-dblclick="dbRowclick"
:cell-style="cellStyle" keyField='applyid' :cell-style="xmcellStyle" keyField='applyid'
:scrollYConfig="{ enabled: true, rSize: 30, height: '100%', }" class="mytable-style"> :scrollYConfig="{ enabled: true, rSize: 30, height: '100%', }" class="mytable-style">
<template #itemclass="{ row }"> <template #itemclass="{ row }">
{{itemclassList.find((item) => item.itemclassCode == row.itemclass)?.itemclassName}} {{itemclassList.find((item) => item.itemclassCode == row.itemclass)?.itemclassName}}
@ -40,20 +42,25 @@
</CustomVxeTable> </CustomVxeTable>
</div> </div>
<div style="height: calc(40% - 30px)"> <div style="height: calc(40% - 30px)">
<CustomVxeTable :table-data="sqXmList" :columns="sqXmColumns" keyField='uid' :cell-style="cellStyle" <CustomVxeTable :table-data="sqxmCzList" :columns="sqXmColumns" keyField='uid' :cell-style="cellStyle"
:config="tableConfig" :scrollYConfig="{ enabled: true, rSize: 30, height: '100%', }" ref="xmRef" :config="tableConfig" :scrollYConfig="{ enabled: true, rSize: 30, height: '100%', }" ref="xmRef"
@selection-change="selectionChange" class="mytable-style"> @selection-change="selectionChange" class="mytable-style">
<template #itemclass="{ row }"> <template #newitemclass="{ row }">
{{itemclassList.find((item) => item.itemclassCode == row.itemclass)?.itemclassName}} {{itemclassList.find((item) => item.itemclassCode == row.newitemclass)?.itemclassName}}
</template>
<template #newbarcode="{ row }">
条码号({{ barcodes }}条)
</template> </template>
<template #itemclass_yblx="{ row }"> <template #itemclass_yblx="{ row }">
<SelectTable v-model:data="row.itemclass_yblx" :tableData="dictData.BT" placeholder="请选择" <SelectTable v-model:data="row.itemclass_yblx" :tableData="dictData.BT" placeholder="请选择"
value="label" class="full-width-input" /> :clearable="false" v-if="labpat.status < 20 || !labpat.status" value="label"
@getDataValue="(data) => { getyblxData(data, row) }" class="full-width-input" />
<span v-else> {{ formatDict(row.itemclass_yblx, 'BT') }}</span>
</template> </template>
<template #zt="{ row }"> <template #status="{ row }">
{{ formatDict(labpat.status, 'ZT') }} <span v-if="row.rowSeq == 1"> {{ formatDict(labpat.status, 'ZT') }}</span>
</template> </template>
<template #action="{ row }" v-if="labpat.status < 20"> <template #action="{ row }" v-if="labpat.status < 20 || !labpat.status">
<el-button type="danger" :text='true' size="small" @click="delItem(row)">删除</el-button> <el-button type="danger" :text='true' size="small" @click="delItem(row)">删除</el-button>
</template> </template>
</CustomVxeTable> </CustomVxeTable>
@ -73,8 +80,7 @@
<SelectTable v-model:data="searchForm.status" :tableData="dictData.ZT" clearable style="width: 9.5rem;" <SelectTable v-model:data="searchForm.status" :tableData="dictData.ZT" clearable style="width: 9.5rem;"
placeholder="请选择状态" size="small" @getDataValue="handleQuery" /> placeholder="请选择状态" size="small" @getDataValue="handleQuery" />
</el-form-item> </el-form-item>
<el-button type="primary" size="small" @click="printHandle">打印</el-button>
<el-button type="danger" size="small" @click="deleteHandle">作废</el-button>
<el-form-item label="" prop="begdate"> <el-form-item label="" prop="begdate">
<div class="radio_box"> <div class="radio_box">
<el-radio-group v-model="searchForm.days" @change="changeDays"> <el-radio-group v-model="searchForm.days" @change="changeDays">
@ -99,7 +105,7 @@
</el-form> </el-form>
<div class="table-box"> <div class="table-box">
<CustomVxeTable :table-data="labPatList" :loading="loading" :columns="tableColumns" <CustomVxeTable :table-data="labPatList" :loading="loading" :columns="tableColumns"
@current-change="handleRowClick" size="small" keyField='applyid' @cell-click="handleRowClick" size="small" keyField='applyid' :cell-style="sqdcellStyle"
:scrollYConfig="{ enabled: true, rSize: 30, height: '100%', }" class="mytable-style" ref="tableRef"> :scrollYConfig="{ enabled: true, rSize: 30, height: '100%', }" class="mytable-style" ref="tableRef">
<template #status="{ row }"> <template #status="{ row }">
{{ formatDict(row.status, 'ZT') }} {{ formatDict(row.status, 'ZT') }}
@ -124,6 +130,7 @@ import { listregdict } from "@/api/regional/dict/regdict.ts";
import { checkPrintService } from '@/utils/printHelper.ts'; import { checkPrintService } from '@/utils/printHelper.ts';
import { listitemclass } from "@/api/regional/dict/itemclass.ts"; import { listitemclass } from "@/api/regional/dict/itemclass.ts";
import { classCom } from '@/utils/classCom'; import { classCom } from '@/utils/classCom';
import { useGroupTableData } from '@/utils/groupHelper'
const { proxy } = getCurrentInstance(); const { proxy } = getCurrentInstance();
const labpat = ref({}) const labpat = ref({})
const saveLoading = ref(false) const saveLoading = ref(false)
@ -136,6 +143,10 @@ const activeName = ref('')
const today = ref(dayjs().format('YYYY-MM-DD')) const today = ref(dayjs().format('YYYY-MM-DD'))
// 记录初始数据(用于对比是否有变化)
const initialLabPat = ref({})
const initialSqxmCzList = ref([])
const searchForm = ref({ const searchForm = ref({
brxm: '', brxm: '',
status: '', status: '',
@ -145,45 +156,84 @@ const searchForm = ref({
}) })
const tableColumns = ref([ const tableColumns = ref([
{ field: 'inputDate', title: '登记时间', width: 80, align: 'center', resizable: true },
{ field: 'rowSeq', title: 'No', width: 40, align: 'center', resizable: true },
{ field: 'patName', title: '姓名', width: 80, align: 'center', resizable: true, }, { field: 'patName', title: '姓名', width: 80, align: 'center', resizable: true, },
{ field: 'status', title: '状态', width: 80, align: 'center', slotName: 'status', resizable: true, }, { field: 'status', title: '状态', width: 80, align: 'center', slotName: 'status', resizable: true, },
{ field: 'orderTime', title: '登记时间', width: 80, align: 'center', resizable: true },
{ field: 'userName', title: '登记人', width: 80, align: 'center', resizable: true }, { field: 'userName', title: '登记人', width: 80, align: 'center', resizable: true },
{ field: 'reqDetailName', title: '项目', align: 'center', resizable: true }, { field: 'reqDetailName', title: '项目', width: 200, align: 'center', resizable: true },
{ field: 'patId', title: '病人代号', align: 'center', width: 80, resizable: true },
]) ])
const rowStyle = ({ row }) => { const sqdcellStyle = ({ row, column }) => {
if (column.title == "状态") {
return {
backgroundColor: getColor(row.status),
// color: ,
}
}
} }
const cellStyle = ({ row, column }) => { const getColor = (type) => {
if (column.title == "类别") { switch (type) {
const bkcolor = itemclassList.value.find((item) => item.itemclassCode == row.itemclass)?.itemclassBkcolor; case '10':
const bgColor = classCom.decimalToHexColor(bkcolor); return '';
const textColor = classCom.getContrastTextColor(bgColor); case '20':
return { return ' rgba(238, 8, 8, 0.25)';
backgroundColor: `${bgColor} !important`, case '30':
color: textColor, return 'rgba(0, 128, 0, 0.25)';
}; case '40':
return 'rgba(255, 165, 0, 0.25)';
case '50':
return 'rgba(255, 165, 0, 0.25)';
default:
return 'rgba(40, 189, 187, 0.25)';
} }
} }
const deepClone = (data) => {
return JSON.parse(JSON.stringify(data))
}
// 更新初始数据(在新增/加载数据时调用)
const updateInitialData = () => {
initialLabPat.value = deepClone(labpat.value)
initialSqxmCzList.value = deepClone(sqxmCzList.value)
}
// 判断数据是否有变化
const isDataChanged = () => {
const labPatChanged = JSON.stringify(labpat.value) !== JSON.stringify(initialLabPat.value)
const sqxmChanged = JSON.stringify(sqxmCzList.value) !== JSON.stringify(initialSqxmCzList.value)
return labPatChanged || sqxmChanged
}
const rowInfo = ref({}) const rowInfo = ref({})
const handleRowClick = (row) => { const handleRowClick = ({ row }) => {
rowInfo.value = row rowInfo.value = row
if (!row?.applyid) return
queryReqDetail({ applyId: row.applyid }).then(res => { queryReqDetail({ applyId: row.applyid }).then(res => {
labpat.value = res.data.regApply labpat.value = res.data.regApply
sqXmList.value = res.data.regApplyDetailList.map(item => ({ sqXmList.value = res.data.regApplyDetailList.map(item => ({
itemcode: item.orderItemCode, itemcode: item.orderItemCode,
itemname: item.orderItemName, itemname: item.orderItemName,
itemclass_yblx: item.sampleTypeName, itemclass_yblx: item.sampleTypeName,
dj: item.amount, amount: item.amount,
applyid: item.applyid, applyid: item.applyid,
uid: item.uid, uid: item.uid,
classid: item.classid, classid: item.classid,
barcode: item.barcode, barcode: item.barcode,
itemclass: item.itemclass, itemclass: item.itemclass,
itemclass_tips: item.itemclass_tips
})) }))
// 异步初始化数据
nextTick(() => {
setTimeout(() => {
updateInitialData()
}, 10);
})
}) })
} }
@ -207,14 +257,35 @@ const dateHandle = (val) => {
searchForm.value.enddate = dayjs(searchForm.value.begdate).format('YYYY-MM-DD') + ' 23:59:59' searchForm.value.enddate = dayjs(searchForm.value.begdate).format('YYYY-MM-DD') + ' 23:59:59'
handleQuery() handleQuery()
} }
const handleQuery = () => { const handleQuery = () => {
rowInfo.value = {} rowInfo.value = {}
queryRegRequestInfo(searchForm.value).then(res => { queryRegRequestInfo(searchForm.value).then(res => {
labPatList.value = res.data // 数据分组
const { tableData } = useGroupTableData(
res.data,
'orderDate', // 分组字段
['inputDate',], // 仅第一条显示的字段
'orderDate', // 排序字段
['orderDate'],//原数据赋值对应字段
)
labPatList.value = tableData.value
if (!labpat.value.status) {
const item = res.data.find(item => item.patId == labpat.value.patId)
nextTick(() => {
tableRef.value.setCurrentRow(item)
handleRowClick({ row: item })
})
}
}) })
} }
// 获取病人代号查询信息
const getBrdhHandle = (val) => {
console.log("🚀 ~ getBrdhHandle ~ val:", val)
}
//保存
const saveHandle = () => { const saveHandle = () => {
if (!labpat.value.patId) return ElMessage.warning('病人代号不能为空!') if (!labpat.value.patId) return ElMessage.warning('病人代号不能为空!')
if (!labpat.value.patName) return ElMessage.warning('病人姓名不能为空!') if (!labpat.value.patName) return ElMessage.warning('病人姓名不能为空!')
@ -224,12 +295,12 @@ const saveHandle = () => {
labpat.value.status = labpat.value.status ? labpat.value.status : '' labpat.value.status = labpat.value.status ? labpat.value.status : ''
const data = { const data = {
regApply: labpat.value, regApply: labpat.value,
regApplyDetailList: sqXmList.value.map(item => ({ regApplyDetailList: sqxmCzList.value.map(item => ({
orderItemCode: item.itemcode, orderItemCode: item.itemcode,
orderItemName: item.itemname, orderItemName: item.itemname,
sampleTypeCode: item.itemclass_yblx, sampleTypeCode: item.itemclass_yblx,
sampleTypeName: item.itemclass_yblx, sampleTypeName: item.itemclass_yblx,
amount: item.dj, amount: item.amount,
applyid: labpat.value.applyid, applyid: labpat.value.applyid,
uid: item.uid uid: item.uid
})) }))
@ -238,9 +309,8 @@ const saveHandle = () => {
saveReqInfo(data).then(res => { saveReqInfo(data).then(res => {
if (res.code == 0) { if (res.code == 0) {
ElMessage.success('保存成功!') ElMessage.success('保存成功!')
labpat.value = {}
sqXmList.value = []
handleQuery() handleQuery()
updateInitialData()
} }
}).finally(() => { }).finally(() => {
saveLoading.value = false saveLoading.value = false
@ -250,6 +320,7 @@ const saveHandle = () => {
const addHandle = () => { const addHandle = () => {
labpat.value = {} labpat.value = {}
sqXmList.value = [] sqXmList.value = []
updateInitialData()
} }
const deleteHandle = () => { const deleteHandle = () => {
if (!rowInfo.value.applyid) return ElMessage.warning('请选择要作废的申请单!') if (!rowInfo.value.applyid) return ElMessage.warning('请选择要作废的申请单!')
@ -269,7 +340,19 @@ const deleteHandle = () => {
} }
const printHandle = () => { const printHandle = () => {
let arr = xmRef.value.allSelection().map(item => { if (isDataChanged()) {
ElMessageBox.confirm('数据已修改,请先保存后再打印!', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}).then(() => {
saveHandle()
}).catch(() => { })
return
}
const selectList = xmRef.value.allSelection()
let arr = selectList.map(item => {
return { return {
applyId: item.applyid, applyId: item.applyid,
barcode: item.barcode, barcode: item.barcode,
@ -291,8 +374,9 @@ const printHandle = () => {
if (!isConnected) return if (!isConnected) return
reqPrint(uniqueData).then(res => { reqPrint(uniqueData).then(res => {
if (res.code == 0) { if (res.code == 0) {
handleQuery() handleRowClick({ row: rowInfo.value })
ElMessage.success('正在打印中...') ElMessage.success('正在打印中...')
handleQuery()
} }
}) })
}) })
@ -304,12 +388,24 @@ const filterData = ref([])
const xmColumns = ref([ const xmColumns = ref([
{ field: 'itemcode', title: '代号', align: 'center', resizable: true }, { field: 'itemcode', title: '代号', align: 'center', resizable: true },
{ field: 'itemname', title: '简称', align: 'center', width: 280, resizable: true }, { field: 'itemname', title: '简称', align: 'center', width: 280, resizable: true },
{ field: 'dj', title: '单价', align: 'center', resizable: true }, { field: 'price', title: '单价', align: 'center', resizable: true },
{ field: 'itemclass', title: '类别', align: 'center', slotName: 'itemclass', resizable: true }, { field: 'itemclass', title: '类别', align: 'center', slotName: 'itemclass', resizable: true },
{ field: 'itemclass_tips', title: '采样提示', align: 'center', resizable: true }, { field: 'itemclass_tips', title: '采样提示', align: 'center', resizable: true },
{ field: 'itemclass_yblx', title: '样本', align: 'center', resizable: true }, { field: 'itemclass_yblx', title: '样本', align: 'center', resizable: true },
]) ])
const xmcellStyle = ({ row, column }) => {
if (column.title == "类别") {
const bkcolor = itemclassList.value.find((item) => item.itemclassCode == row.itemclass)?.itemclassBkcolor;
const bgColor = classCom.decimalToHexColor(bkcolor);
const textColor = classCom.getContrastTextColor(bgColor);
return {
backgroundColor: `${bgColor} !important`,
color: textColor,
};
}
}
const searchList = ref([]) const searchList = ref([])
const handleTabClick = (tab) => { const handleTabClick = (tab) => {
@ -332,8 +428,9 @@ const filterDictData = () => {
} }
filterData.value = searchList.value.filter((item) => { filterData.value = searchList.value.filter((item) => {
const matchName = item.itemname.toString().toLowerCase().includes(key);
const matchLabel = item.pinyin.toString().toLowerCase().includes(key); const matchLabel = item.pinyin.toString().toLowerCase().includes(key);
return matchLabel; return matchLabel || matchName;
}) })
} }
@ -349,17 +446,73 @@ const sqXmList = ref([])
const sqXmColumns = ref([ const sqXmColumns = ref([
{ type: 'selection', field: '', title: '', resizable: true, align: 'center', width: 40 }, { type: 'selection', field: '', title: '', resizable: true, align: 'center', width: 40 },
{ field: 'itemclass', title: '类别', align: 'center', width: 100, slotName: 'itemclass', resizable: true }, { field: 'newitemclass', title: '类别', align: 'center', width: 100, slotName: 'newitemclass', resizable: true },
{ field: 'itemcode', title: '代号', align: 'center', resizable: true }, { field: 'newitemclass_tips', title: '采样提示', align: 'center', width: 80, resizable: true },
{ field: 'itemname', title: '简称', align: 'center', width: 150, resizable: true }, { field: 'itemname', title: '简称', align: 'center', resizable: true },
{ field: 'barcode', title: '条码号', align: 'center', width: 150, resizable: true }, { field: 'newbarcode', title: '条码号', align: 'center', width: 120, resizable: true, headerSlot: 'newbarcode' },
{ field: 'dj', title: '单价', align: 'center', resizable: true }, { field: 'amount', title: '单价', align: 'center', width: 60, resizable: true },
{ field: 'itemclass_yblx', title: '样本', align: 'center', slotName: 'itemclass_yblx', resizable: true }, { field: 'itemclass_yblx', title: '样本', align: 'center', width: 80, slotName: 'itemclass_yblx', resizable: true },
{ field: 'zt', title: '状态', align: 'center', resizable: true, slotName: 'zt' }, { field: 'status', title: '状态', align: 'center', resizable: true, width: 80, slotName: 'status' },
]) ])
const cellStyle = ({ row, column }) => {
if (column.title == "类别" && row.newitemclass) {
const bkcolor = itemclassList.value.find((item) => item.itemclassCode == row.itemclass)?.itemclassBkcolor;
const bgColor = classCom.decimalToHexColor(bkcolor);
const textColor = classCom.getContrastTextColor(bgColor);
return {
backgroundColor: `${bgColor} !important`,
color: textColor,
};
}
}
const getyblxData = (data, row) => {
sqXmList.value.forEach(item => {
if (row.uid == item.uid) {
item.itemclass_yblx = data.label
}
})
}
// 已申请的项目
const sqxmCzList = computed(() => {
// 数据分组
const { tableData } = useGroupTableData(
sqXmList.value,
'itemclass',
['newitemclass', 'newbarcode', 'newitemclass_tips'],
'orderDate',
['itemclass', 'barcode', 'itemclass_tips'],
)
return tableData.value
})
watch(
sqxmCzList,
() => {
nextTick(() => {
// 等待 DOM 渲染完成后执行勾选
if (labpat.value.status < 20 && xmRef.value) {
sqxmCzList.value.forEach(item => {
xmRef.value.toggleRowSelection(item, true)
});
}
});
},
{ deep: true, immediate: true }
);
const barcodes = computed(() => {
return Array.from(new Set(sqxmCzList.value.map(item => item.barcode))).length
})
const tableConfig = ref({ const tableConfig = ref({
actionWidth: 60,
// 复选框配置 // 复选框配置
checkboxConfig: { checkboxConfig: {
// 可选配置项 // 可选配置项
@ -371,13 +524,12 @@ const tableConfig = ref({
} }
}) })
const xmRef = useTemplateRef('xmRef') const xmRef = useTemplateRef('xmRef')
const selectionChange = (checked, row, selection) => { const selectionChange = (checked, row, selection) => {
// console.log('==>', checked, row, selection); // console.log('==>', checked, row, selection);
sqXmList.value.forEach(item => { sqxmCzList.value.forEach(item => {
if (row.barcode === item.barcode) { if (row.barcode === item.barcode) {
xmRef.value.toggleRowSelection(item, checked) xmRef.value.toggleRowSelection(item, checked)
} }
@ -399,7 +551,7 @@ const dbRowclick = ({ row }) => {
ElMessage.warning('已存在该项目') ElMessage.warning('已存在该项目')
return return
} }
sqXmList.value.push(row) sqXmList.value.push({ ...row, amount: row.price })
} }
const getXmList = () => { const getXmList = () => {
@ -424,6 +576,9 @@ onMounted(() => {
listitemclass({ pageSize: 9999, pageNum: 1 }).then(response => { listitemclass({ pageSize: 9999, pageNum: 1 }).then(response => {
itemclassList.value = response.rows; itemclassList.value = response.rows;
}) })
// 初始化初始值
updateInitialData()
}) })
</script> </script>

View File

@ -4,26 +4,25 @@
<el-form :model="queryParams" ref="queryRef" label-width="5rem" style="width: 100%;" :size="aotuSize"> <el-form :model="queryParams" ref="queryRef" label-width="5rem" style="width: 100%;" :size="aotuSize">
<el-row :gutter="10"> <el-row :gutter="10">
<el-col :span="4"> <el-col :span="4">
<el-form-item label="委托机构:" prop="SrcHospName"> <el-form-item label="委托机构:" prop="srcHospName">
<SelectTable v-model:data="queryParams.SrcHospName" :fields="ksdhFields" :tableData="hosList" <el-input v-model="queryParams.srcHospName" :size="aotuSize" readonly />
label="label" :size="aotuSize" value="label" objKey="label" :border="true" placeholder="请选择委托机构" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="4"> <el-col :span="4">
<el-form-item label="检测医院:" prop="DstHospName"> <el-form-item label="检测医院:" prop="dstHospName">
<SelectTable v-model:data="queryParams.DstHospName" :fields="ksdhFields" :tableData="hosList" <SelectTable v-model:data="queryParams.dstHospName" :fields="ksdhFields" :tableData="hosList"
label="label" :size="aotuSize" value="label" objKey="label" :border="true" placeholder="请选择" /> label="label" :size="aotuSize" value="label" placeholder="请选择" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="4"> <el-col :span="4">
<el-form-item label="条码号:" prop="Barcode"> <el-form-item label="条码号:" prop="barcode">
<el-input v-model="queryParams.Barcode" placeholder="请输入条码号" clearable /> <el-input v-model="queryParams.barcode" placeholder="请输入条码号" clearable />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="4"> <el-col :span="4">
<el-form-item label="姓名:" prop="PatName"> <el-form-item label="姓名:" prop="patName">
<el-input v-model="queryParams.PatName" placeholder="请输入姓名" clearable /> <el-input v-model="queryParams.patName" placeholder="请输入姓名" clearable />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="4"> <el-col :span="4">
@ -39,18 +38,18 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="4"> <el-col :span="4">
<el-form-item label="采样人:" prop="AffirmUserName"> <el-form-item label="采样人:" prop="affirmUserName">
<el-input v-model="queryParams.AffirmUserName" placeholder="请输入采样人" clearable /> <el-input v-model="queryParams.affirmUserName" placeholder="请输入采样人" clearable />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="4"> <el-col :span="4">
<el-form-item label="签收人:" prop="SignInUserName"> <el-form-item label="签收人:" prop="signInUserName">
<el-input v-model="queryParams.SignInUserName" placeholder="请输入签收人" clearable /> <el-input v-model="queryParams.signInUserName" placeholder="请输入签收人" clearable />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="4"> <el-col :span="4">
<el-form-item label="时间类型:" prop="DateType"> <el-form-item label="时间类型:" prop="dateType">
<el-select v-model="queryParams.DateType" placeholder="请选择"> <el-select v-model="queryParams.dateType" placeholder="请选择">
<el-option label="登记时间" value="登记时间" /> <el-option label="登记时间" value="登记时间" />
<el-option label="采样时间" value="采样时间" /> <el-option label="采样时间" value="采样时间" />
<el-option label="送出时间" value="送出时间" /> <el-option label="送出时间" value="送出时间" />
@ -75,10 +74,10 @@
<CustomTable ref="tableRefs" :data="tableData" :columns="columns" :config="tableConfig" :pagination="pagination" <CustomTable ref="tableRefs" :data="tableData" :columns="columns" :config="tableConfig" :pagination="pagination"
@size-change="sizeChange" @page-change="currentChange" @row-click="rowHandle"> @size-change="sizeChange" @page-change="currentChange" @row-click="rowHandle">
<template #patAge="{ row }"> <template #patAge="{ row }">
{{ row.patAge }}{{ row.ageUnit }} {{ row.patAge }}{{ formatDict(row.ageUnit, 'AU') }}
</template> </template>
<template #status="{ row }"> <template #status="{ row }">
{{ formatDict(row.status, regdictList) }} {{ formatDicts(row.status, regdictList) }}
</template> </template>
<template #patSex="{ row }"> <template #patSex="{ row }">
{{ row.patSex == 1 ? '男' : '女' }} {{ row.patSex == 1 ? '男' : '女' }}
@ -92,7 +91,7 @@
<img class="timg" src="@/assets/images/yjt.png" alt=""> <img class="timg" src="@/assets/images/yjt.png" alt="">
</div> </div>
<div :class="['timeline-content', i > lastTimeIndex ? 'no_active' : '']"> <div :class="['timeline-content', i > lastTimeIndex ? 'no_active' : '']">
<div :class="['index', lastTimeIndex == i ? 'active' : '']">{{ i + 1 }} <div :class="['index', lastTimeIndex == i ? 'active' : '']">{{ Number(i) + 1 }}
</div> </div>
<div class="timeline-title">{{ item.title }}</div> <div class="timeline-title">{{ item.title }}</div>
<div class="timeline-time">{{ item.time }}</div> <div class="timeline-time">{{ item.time }}</div>
@ -109,27 +108,31 @@ import { querySample } from '@/api/regional/index'
import SelectTable from '@/components/SelectTable/index.vue'; import SelectTable from '@/components/SelectTable/index.vue';
import { classCom } from '@/utils/classCom'; import { classCom } from '@/utils/classCom';
const aotuSize = classCom.useAutoSize(); const aotuSize = classCom.useAutoSize();
// @ts-ignore import { listhospital } from "@/api/regional/dict/hospital";
import { listhospital } from "@/api/regional/dict/hospital.ts"; import { listregdict } from "@/api/regional/dict/regdict";
// @ts-ignore import useUserStore from '@/store/modules/user'
import { listregdict } from "@/api/regional/dict/regdict.ts"; import dayjs from 'dayjs';
import { getDictData, formatDict, dictData } from '@/hooks'
const userStore = useUserStore()
const queryParams: any = ref({ const queryParams: any = ref({
pageSize: 50, pageSize: 50,
pageNum: 1, pageNum: 1,
srcHospName: userStore.sysLoginParam.loginYLJGName,
times: []
}) })
const tableData: any = ref([]) const tableData: any = ref([])
const columns: any = ref([ const columns: any = ref([
{ prop: 'barcode', label: '条码号', align: 'center', visible: true, width: 150 }, { prop: 'barcode', label: '条码号', align: 'center', visible: true, width: 150 },
{ prop: 'srcHospName', label: '委托机构', align: 'center', visible: true, width: 200 }, { prop: 'srcHospName', label: '委托机构', align: 'center', visible: true, width: 250 },
{ prop: 'patName', label: '姓名', align: 'center', visible: true, width: 70 }, { prop: 'patName', label: '姓名', align: 'center', visible: true, width: 100 },
{ prop: 'patSex', label: '性别', align: 'center', visible: true, width: 60, slot: "patSex" }, { prop: 'patSex', label: '性别', align: 'center', visible: true, width: 60, slot: "patSex" },
{ prop: 'patAge', label: '年龄', align: 'center', visible: true, slot: "patAge", width: 60 }, { prop: 'patAge', label: '年龄', align: 'center', visible: true, slot: "patAge", width: 60 },
{ prop: 'checkPUR', label: '申请项目', align: 'center', visible: true, width: 200 }, { prop: 'checkPUR', label: '申请项目', align: 'center', visible: true, width: 300 },
{ prop: 'sampleTypeName', label: '标本类型', align: 'center', visible: true, }, { prop: 'sampleTypeName', label: '标本类型', align: 'center', visible: true, },
{ prop: 'tubeName', label: '采集容器', align: 'center', visible: true, }, { prop: 'itemclass_tips', label: '采集容器', align: 'center', visible: true, },
{ prop: 'status', label: '标本状态', align: 'center', visible: true, slot: "status" }, { prop: 'status', label: '标本状态', align: 'center', visible: true, slot: "status" },
// { prop: 'moveStateName', label: '流转状态', align: 'center', visible: true, },
{ prop: 'affirmUserName', label: '采样人', align: 'center', visible: true, }, { prop: 'affirmUserName', label: '采样人', align: 'center', visible: true, },
{ prop: 'affirmTime', label: '采样时间', align: 'center', visible: true, width: 150 }, { prop: 'affirmTime', label: '采样时间', align: 'center', visible: true, width: 150 },
{ prop: 'signInUserName', label: '签收人', align: 'center', visible: true, }, { prop: 'signInUserName', label: '签收人', align: 'center', visible: true, },
@ -161,11 +164,9 @@ const timelineItems = ref(
{ title: '检验申请', time: '' }, { title: '检验申请', time: '' },
{ title: '标本采集', time: '' }, { title: '标本采集', time: '' },
{ title: '标本送检', time: '' }, { title: '标本送检', time: '' },
{ title: '标本外送', time: '' },
{ title: '标本签收', time: '' }, { title: '标本签收', time: '' },
{ title: '上机检测', time: '' }, { title: '上机检验', time: '' },
{ title: '结果审核', time: '' }, { title: '结果审核', time: '' },
{ title: '报告发布', time: '' },
] ]
); );
@ -182,11 +183,11 @@ const lastTimeIndex = computed(() => {
const handleQuery = () => { const handleQuery = () => {
if (queryParams.value.times && queryParams.value.times.length > 0) { if (queryParams.value.times && queryParams.value.times.length > 0) {
queryParams.value.DateStart = queryParams.value.times[0] queryParams.value.dateStart = queryParams.value.times[0]
queryParams.value.DateEnd = queryParams.value.times[1] queryParams.value.dateEnd = queryParams.value.times[1]
} else { } else {
queryParams.value.DateStart = '' queryParams.value.dateStart = ''
queryParams.value.DateEnd = '' queryParams.value.dateEnd = ''
} }
getList() getList()
@ -198,6 +199,7 @@ const resetHandle = () => {
pageSize: 50, pageSize: 50,
pageNum: 1, pageNum: 1,
} }
getDays()
handleQuery() handleQuery()
} }
const currentChange = (page: { currentPage: number, pageSize: number }) => { const currentChange = (page: { currentPage: number, pageSize: number }) => {
@ -214,12 +216,10 @@ const rowHandle = (row: any) => {
[ [
{ title: '检验申请', time: row.orderTime }, { title: '检验申请', time: row.orderTime },
{ title: '标本采集', time: row.affirmTime }, { title: '标本采集', time: row.affirmTime },
{ title: '标本送检', time: row.signInDate }, { title: '标本送检', time: row.sendPackTime },
{ title: '标本外送', time: row.sendPackTime },
{ title: '标本签收', time: row.signInTime }, { title: '标本签收', time: row.signInTime },
{ title: '上机检测', time: row.testDate }, { title: '上机检验', time: row.sjsj },
{ title: '结果审核', time: row.auditTime }, { title: '结果审核', time: row.confirmtime },
{ title: '报告发布', time: row.reportTime },
] ]
} }
@ -232,10 +232,18 @@ const getList = () => {
rowHandle(res.rows[0]) rowHandle(res.rows[0])
}) })
} }
const getDays = () => {
const end = dayjs().format('YYYY-MM-DD');
const start = dayjs().subtract(2, 'day').format('YYYY-MM-DD'); //add 时间往后
queryParams.value.times = [start, end];
}
const hosList = ref([]) const hosList = ref([])
const regdictList: any = ref([]) const regdictList: any = ref([])
onMounted(() => { onMounted(() => {
getList() getDays()
handleQuery()
listhospital().then((res: any) => { listhospital().then((res: any) => {
hosList.value = res.rows.map((item: any) => { hosList.value = res.rows.map((item: any) => {
return { return {
@ -248,10 +256,11 @@ onMounted(() => {
listregdict({ pageSize: 100, pageNum: 1, dictType: 'ZT' }).then((res: any) => { listregdict({ pageSize: 100, pageNum: 1, dictType: 'ZT' }).then((res: any) => {
regdictList.value = res.rows; regdictList.value = res.rows;
}) })
getDictData('AU')
}) })
const formatDict = (v: string, arr: Array<any>) => { const formatDicts = (v: string, arr: Array<any>) => {
return arr.find((item: any) => item.dictCode == v)?.dictName || v; return arr.find((item: any) => item.dictCode == v)?.dictName || v;
}; };
</script> </script>

View File

@ -4,25 +4,24 @@
<el-form :model="queryParams" ref="queryRef" label-width="5rem" style="width: 100%;" :size="aotuSize"> <el-form :model="queryParams" ref="queryRef" label-width="5rem" style="width: 100%;" :size="aotuSize">
<el-row :gutter="10"> <el-row :gutter="10">
<el-col :span="5"> <el-col :span="5">
<el-form-item label="委托机构:" prop="SrcHospName"> <el-form-item label="委托机构:" prop="srcHospName">
<SelectTable v-model:data="queryParams.SrcHospName" :fields="ksdhFields" :tableData="hosList" <el-input v-model="queryParams.srcHospName" :size="aotuSize" readonly />
label="label" :size="aotuSize" value="value" objKey="value" :border="true" placeholder="请选择委托机构" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="5"> <el-col :span="5">
<el-form-item label="检测医院:" prop="DstHospName"> <el-form-item label="检测医院:" prop="dstHospName">
<SelectTable v-model:data="queryParams.DstHospName" :fields="ksdhFields" :tableData="hosList" <SelectTable v-model:data="queryParams.dstHospName" :fields="ksdhFields" :tableData="hosList"
label="label" :size="aotuSize" value="label" objKey="label" :border="true" placeholder="请选择" /> label="label" :size="aotuSize" value="label" placeholder="请选择" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="5"> <el-col :span="5">
<el-form-item label="条码号:" prop="Barcode"> <el-form-item label="条码号:" prop="barcode">
<el-input v-model="queryParams.Barcode" placeholder="请输入条码号" clearable /> <el-input v-model="queryParams.barcode" placeholder="请输入条码号" clearable />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="5"> <el-col :span="5">
<el-form-item label="姓名:" prop="PatName"> <el-form-item label="姓名:" prop="patName">
<el-input v-model="queryParams.PatName" placeholder="请输入姓名" clearable /> <el-input v-model="queryParams.patName" placeholder="请输入姓名" clearable />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="5"> <el-col :span="5">
@ -31,16 +30,16 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="5"> <!-- <el-col :span="5">
<el-form-item label="时间类型:" prop="DateType"> <el-form-item label="时间类型:" prop="dateType">
<el-select v-model="queryParams.DateType" placeholder="请选择"> <el-select v-model="queryParams.dateType" placeholder="请选择">
<el-option label="登记时间" value="登记时间" /> <el-option label="登记时间" value="登记时间" />
<el-option label="采样时间" value="采样时间" /> <el-option label="采样时间" value="采样时间" />
<el-option label="送出时间" value="送出时间" /> <el-option label="送出时间" value="送出时间" />
<el-option label="签收时间" value="签收时间" /> <el-option label="签收时间" value="签收时间" />
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col> -->
<el-col :span="5"> <el-col :span="5">
<el-form-item label="日期:" prop="times"> <el-form-item label="日期:" prop="times">
<el-date-picker v-model="queryParams.times" type="daterange" range-separator="-" start-placeholder="开始时间" <el-date-picker v-model="queryParams.times" type="daterange" range-separator="-" start-placeholder="开始时间"
@ -57,17 +56,17 @@
<div class="mb10"> <div class="mb10">
<el-button type="primary" @click="qsHandle(50)">标本签收</el-button> <el-button type="primary" @click="qsHandle(50)">标本签收</el-button>
<el-button type="primary" @click="qsHandle(110)">标本拒签</el-button> <!-- <el-button type="primary" @click="qsHandle(110)">标本拒签</el-button> -->
<el-button type="primary" plain @click="bbThHandle">标本退回</el-button> <el-button type="primary" plain @click="bbThHandle">标本退回</el-button>
</div> </div>
<div style="height: calc(100% - 180px)"> <div style="height: calc(100% - 180px)">
<CustomTable ref="tableRefs" :data="tableData" :columns="columns" :config="tableConfig" :pagination="pagination" <CustomTable ref="tableRefs" :data="tableData" :columns="columns" :config="tableConfig" :pagination="pagination"
@selection-change="handleSelectionChange" @size-change="sizeChange" @page-change="currentChange"> @selection-change="handleSelectionChange" @size-change="sizeChange" @page-change="currentChange">
<template #patAge="{ row }"> <template #patAge="{ row }">
{{ row.patAge }}{{ row.ageUnit }} {{ row.patAge }}{{ formatDict(row.ageUnit, 'AU') }}
</template> </template>
<template #status="{ row }"> <template #status="{ row }">
{{ formatDict(row.status, regdictList) }} {{ formatDicts(row.status, regdictList) }}
</template> </template>
<template #patSex="{ row }"> <template #patSex="{ row }">
{{ row.patSex == 1 ? '男' : '女' }} {{ row.patSex == 1 ? '男' : '女' }}
@ -81,34 +80,37 @@
import CustomTable from '@/components/elTable/index.vue' import CustomTable from '@/components/elTable/index.vue'
import { querySampleSign, sampleSign } from '@/api/regional/index' import { querySampleSign, sampleSign } from '@/api/regional/index'
import SelectTable from '@/components/SelectTable/index.vue'; import SelectTable from '@/components/SelectTable/index.vue';
// @ts-ignore import { listhospital } from "@/api/regional/dict/hospital";
import { listhospital } from "@/api/regional/dict/hospital.ts"; import { getDictData, formatDict, dictData } from '@/hooks'
// @ts-ignore import { listregdict } from "@/api/regional/dict/regdict";
import { listregdict } from "@/api/regional/dict/regdict.ts";
import { classCom } from '@/utils/classCom'; import { classCom } from '@/utils/classCom';
import { ElMessage, ElMessageBox } from 'element-plus'; import { ElMessage, ElMessageBox } from 'element-plus';
import useUserStore from '@/store/modules/user'
import dayjs from 'dayjs';
const userStore = useUserStore()
const aotuSize = classCom.useAutoSize(); const aotuSize = classCom.useAutoSize();
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
const router = useRouter() const router = useRouter()
const queryParams: any = ref({ const queryParams: any = ref({
pageSize: 50, pageSize: 50,
pageNum: 1 pageNum: 1,
srcHospName: userStore.sysLoginParam.loginYLJGName,
times: []
}) })
const tableData: any = ref([]) const tableData: any = ref([])
const columns: any = ref([ const columns: any = ref([
{ type: 'selection', align: 'center', visible: true, width: 40 }, { type: 'selection', align: 'center', visible: true, width: 40 },
{ prop: 'barcode', label: '条码号', align: 'center', visible: true, width: 150 }, { prop: 'barcode', label: '条码号', align: 'center', visible: true, width: 150 },
{ prop: 'srcHospName', label: '委托机构', align: 'center', visible: true, width: 250 }, { prop: 'srcHospName', label: '委托机构', align: 'center', visible: true, width: 250 },
{ prop: 'patName', label: '姓名', align: 'center', visible: true, width: 70 }, { prop: 'patName', label: '姓名', align: 'center', visible: true, width: 100 },
{ prop: 'patSex', label: '性别', align: 'center', visible: true, width: 60, slot: "patSex" }, { prop: 'patSex', label: '性别', align: 'center', visible: true, width: 60, slot: "patSex" },
{ prop: 'patAge', label: '年龄', align: 'center', visible: true, slot: "patAge", width: 60 }, { prop: 'patAge', label: '年龄', align: 'center', visible: true, slot: "patAge", width: 60 },
{ prop: 'checkPUR', label: '申请项目', align: 'center', visible: true, width: 250 }, { prop: 'checkPUR', label: '申请项目', align: 'center', visible: true, width: 300 },
{ prop: 'sampleTypeName', label: '标本类型', align: 'center', visible: true, }, { prop: 'sampleTypeName', label: '标本类型', align: 'center', visible: true, },
{ prop: 'tubeName', label: '采集容器', align: 'center', visible: true, }, { prop: 'itemclass_tips', label: '采集容器', align: 'center', visible: true, },
{ prop: 'status', label: '标本状态', align: 'center', visible: true, slot: "status" }, { prop: 'status', label: '标本状态', align: 'center', visible: true, slot: "status" },
// { prop: 'moveStateName', label: '流转状态', align: 'center', visible: true, }, { prop: 'sendPackTime', label: '送检时间', align: 'center', visible: true, width: 150 },
{ prop: 'affirmUserName', label: '采样人', align: 'center', visible: true, }, { prop: 'sendUserName', label: '送检人', align: 'center', visible: true, width: 150 },
{ prop: 'affirmTime', label: '采样时间', align: 'center', visible: true, width: 150 },
{ prop: 'dstHospName', label: '检测机构名称', align: 'center', visible: true, width: 150 }, { prop: 'dstHospName', label: '检测机构名称', align: 'center', visible: true, width: 150 },
]) ])
const tableConfig = ref({ const tableConfig = ref({
@ -171,10 +173,10 @@ const resetHandle = () => {
pageSize: 50, pageSize: 50,
pageNum: 1, pageNum: 1,
} }
getDays()
handleQuery() handleQuery()
} }
const currentChange = (page: { currentPage: number, pageSize: number }) => { const currentChange = (page: { currentPage: number, pageSize: number }) => {
console.log('page==>', page);
queryParams.value.pageNum = page.currentPage queryParams.value.pageNum = page.currentPage
handleQuery() handleQuery()
} }
@ -186,11 +188,11 @@ const sizeChange = (page: { currentPage: number, pageSize: number }) => {
const handleQuery = () => { const handleQuery = () => {
if (queryParams.value.times && queryParams.value.times.length > 0) { if (queryParams.value.times && queryParams.value.times.length > 0) {
queryParams.value.DateStart = queryParams.value.times[0] queryParams.value.dateStart = queryParams.value.times[0]
queryParams.value.DateEnd = queryParams.value.times[1] queryParams.value.dateEnd = queryParams.value.times[1]
} else { } else {
queryParams.value.DateStart = '' queryParams.value.dateStart = ''
queryParams.value.DateEnd = '' queryParams.value.dateEnd = ''
} }
getList() getList()
@ -202,10 +204,16 @@ const getList = () => {
pagination.value.total = res.total pagination.value.total = res.total
}) })
} }
const getDays = () => {
const end = dayjs().format('YYYY-MM-DD');
const start = dayjs().subtract(2, 'day').format('YYYY-MM-DD'); //add 时间往后
queryParams.value.times = [start, end];
}
const hosList = ref([]) const hosList = ref([])
const regdictList: any = ref([]) const regdictList: any = ref([])
onMounted(() => { onMounted(() => {
getList() getDays()
listhospital().then((res: any) => { listhospital().then((res: any) => {
hosList.value = res.rows.map((item: any) => { hosList.value = res.rows.map((item: any) => {
return { return {
@ -218,10 +226,12 @@ onMounted(() => {
listregdict({ pageSize: 100, pageNum: 1, dictType: 'ZT' }).then((res: any) => { listregdict({ pageSize: 100, pageNum: 1, dictType: 'ZT' }).then((res: any) => {
regdictList.value = res.rows; regdictList.value = res.rows;
}) })
getDictData('AU')
handleQuery()
}) })
const formatDict = (v: string, arr: Array<any>) => { const formatDicts = (v: string, arr: Array<any>) => {
return arr.find((item: any) => item.dictCode == v)?.dictName || v; return arr.find((item: any) => item.dictCode == v)?.dictName || v;
}; };
</script> </script>

View File

@ -1,141 +1,82 @@
<template> <template>
<div class="app-container"> <div class="app-container">
<div class="compact-form"> <el-row :gutter="10">
<el-form :model="queryParams" ref="queryRef" label-width="5rem" style="width: 100%;" :size="aotuSize"> <el-col :span="5">
<el-row :gutter="10"> <el-input v-model="queryParams.barcode" placeholder="请输入条码号" clearable @keyup.enter.prevent="getList" />
<el-col :span="5"> </el-col>
<el-form-item label="委托机构:" prop="SrcHospName"> <el-col :span="4">
<SelectTable v-model:data="queryParams.SrcHospName" :fields="ksdhFields" :tableData="hosList" <el-button type="primary" @click="getList">扫码</el-button>
label="label" :size="aotuSize" value="value" objKey="value" :border="true" placeholder="请选择委托机构" /> </el-col>
</el-form-item> </el-row>
</el-col>
<el-col :span="5">
<el-form-item label="检测医院:" prop="DstHospName">
<SelectTable v-model:data="queryParams.DstHospName" :fields="ksdhFields" :tableData="hosList"
label="label" :size="aotuSize" value="label" objKey="label" :border="true" placeholder="请选择" />
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="条码号:" prop="Barcode">
<el-input v-model="queryParams.Barcode" placeholder="请输入条码号" clearable @change="handleQuery" />
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="姓名:" prop="PatName">
<el-input v-model="queryParams.PatName" placeholder="请输入姓名" clearable @change="handleQuery" />
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="申请项目:" prop="checkPUR">
<el-input v-model="queryParams.checkPUR" placeholder="请输入申请项目" clearable @change="handleQuery" />
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="时间类型:" prop="DateType">
<el-select v-model="queryParams.DateType" placeholder="请选择">
<el-option label="登记时间" value="登记时间" />
<el-option label="采样时间" value="采样时间" />
<el-option label="送出时间" value="送出时间" />
<el-option label="签收时间" value="签收时间" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="日期:" prop="times">
<el-date-picker v-model="queryParams.times" type="daterange" range-separator="-" start-placeholder="开始时间"
end-placeholder="结束时间" format="YYYY-MM-DD" value-format="YYYY-MM-DD" />
</el-form-item>
</el-col>
<el-col :span="4">
<el-button type="primary" @click="handleQuery">查询</el-button>
<el-button @click="resetHandle">重置</el-button>
</el-col>
</el-row>
</el-form>
</div>
<div class="cz_box"> <div class="cz_box">
<el-row :gutter="10"> <el-row :gutter="10">
<el-col :span="1.5"> 送检医院:</el-col> <el-col :span="5">
<el-col :span="4"> <SelectTable v-model:data="dstHospCode" :tableData="hosList" :size="aotuSize" :fields="ksdhFields"
<SelectTable v-model:data="dstHospCode" :fields="ksdhFields" :tableData="hosList" label="label" placeholder="请选择送检医院" @get-data-value="getValue" />
:size="aotuSize" value="value" objKey="value" :border="true" placeholder="请选择" @get-data-value="getValue" />
</el-col> </el-col>
<el-col :span="1.5"> <el-button type="primary" :size="aotuSize" @click="sjHandle(30)">标本送检</el-button></el-col> <el-col :span="1.5"> <el-button type="primary" :size="aotuSize" @click="sjHandle(30)">标本送检</el-button></el-col>
<el-col :span="1.5"> <el-button type="primary" :size="aotuSize" @click="sjHandle(20)">取消送检</el-button></el-col> <el-col :span="1.5"> <el-button type="primary" :size="aotuSize" @click="sjHandle(20)">取消送检</el-button></el-col>
</el-row> </el-row>
</div> </div>
<div style="height: calc(100% - 80px)">
<CustomTable ref="tableRefs" :data="tableData" :columns="columns" :config="tableConfig" :pagination="pagination" <CustomTable ref="tableRefs" :data="tableData" :columns="columns" :config="tableConfig"
@selection-change="handleSelectionChange" @size-change="sizeChange" @page-change="currentChange"> @selection-change="handleSelectionChange">
<template #patAge="{ row }"> <template #patAge="{ row }">
{{ row.patAge }}{{ row.ageUnit }} {{ row.patAge }}{{ formatDict(row.ageUnit, 'AU') }}
</template> </template>
<template #status="{ row }"> <template #status="{ row }">
{{ formatDict(row.status, regdictList) }} {{ formatDicts(row.status, regdictList) }}
</template> </template>
<template #patSex="{ row }"> <template #patSex="{ row }">
{{ row.patSex == 1 ? '男' : '女' }} {{ row.patSex == 1 ? '男' : '女' }}
</template> </template>
</CustomTable> </CustomTable>
</div>
</div> </div>
</template> </template>
<script setup lang="ts" name="Sjdj"> <script setup lang="ts" name="Sjdj">
import CustomTable from '@/components/elTable/index.vue' import CustomTable from '@/components/elTable/index.vue'
import { querySample, sampleSign } from '@/api/regional/index' import { querySample, sampleSign, sampleCollect } from '@/api/regional/index'
// @ts-ignore import { listhospital } from "@/api/regional/dict/hospital";
import { listhospital } from "@/api/regional/dict/hospital.ts"; import { listregdict } from "@/api/regional/dict/regdict";
// @ts-ignore
import { listregdict } from "@/api/regional/dict/regdict.ts";
import SelectTable from '@/components/SelectTable/index.vue'; import SelectTable from '@/components/SelectTable/index.vue';
import { classCom } from '@/utils/classCom'; import { classCom } from '@/utils/classCom';
import { ElMessage } from 'element-plus'; import { ElMessage } from 'element-plus';
import dayjs from 'dayjs';
import { getDictData, formatDict, dictData } from '@/hooks'
const aotuSize = classCom.useAutoSize(); const aotuSize = classCom.useAutoSize();
const queryParams: any = ref({ const queryParams: any = ref({
pageSize: 50, barcode: '',
pageNum: 1,
Status: '30'
}) })
const tableData: any = ref([]) const tableData: any = ref([])
const columns: any = ref([ const columns: any = ref([
{ type: 'selection', align: 'center', visible: true, width: 40 }, { type: 'selection', align: 'center', visible: true, width: 40 },
{ prop: 'barcode', label: '条码号', align: 'center', visible: true, }, { prop: 'barcode', label: '条码号', align: 'center', visible: true, },
{ prop: 'srcHospName', label: '委托机构', align: 'center', visible: true, width: 250 }, { prop: 'srcHospName', label: '委托机构', align: 'center', visible: true, width: 250 },
{ prop: 'patName', label: '姓名', align: 'center', visible: true, width: 60 }, { prop: 'patName', label: '姓名', align: 'center', visible: true, width: 100 },
{ prop: 'patSex', label: '性别', align: 'center', visible: true, width: 60, slot: "patSex" }, { prop: 'patSex', label: '性别', align: 'center', visible: true, width: 60, slot: "patSex" },
{ prop: 'patAge', label: '年龄', align: 'center', visible: true, slot: "patAge", width: 60 }, { prop: 'patAge', label: '年龄', align: 'center', visible: true, slot: "patAge", width: 60 },
{ prop: 'checkPUR', label: '申请项目', align: 'center', visible: true, width: 250 }, { prop: 'checkPUR', label: '申请项目', align: 'center', visible: true, width: 300 },
{ prop: 'sampleTypeName', label: '标本类型', align: 'center', visible: true, }, { prop: 'sampleTypeName', label: '标本类型', align: 'center', visible: true, },
{ prop: 'status', label: '标本状态', align: 'center', visible: true, slot: "status" }, { prop: 'status', label: '标本状态', align: 'center', visible: true, slot: "status" },
{ prop: 'affirmUserName', label: '采样人', align: 'center', visible: true, }, { prop: 'affirmUserName', label: '采样人', align: 'center', visible: true, },
{ prop: 'affirmTime', label: '采样时间', align: 'center', visible: true, width: 150 }, { prop: 'affirmTime', label: '采样时间', align: 'center', visible: true, width: 200 },
{ prop: 'affirmTime', label: '送检时间', align: 'center', visible: true, },
{ prop: 'dstHospName', label: '检测机构名称', align: 'center', visible: true, },
]) ])
const tableConfig = ref({ const tableConfig = ref({
border: true, // 边框 border: true, // 边框
height: '70vh', // 高度 height: '100%', // 高度
highlightCurrentRow: true, // 高亮当前行 highlightCurrentRow: true, // 高亮当前行
// fit: true, // 列宽自适应 // fit: true, // 列宽自适应
}) })
const pagination = ref({
show: true,
total: 0,
pageSize: 50,
currentPage: 1,
})
const ksdhFields = ref([ const ksdhFields = ref([
{ prop: 'label', label: '名称', width: 150, enablePinyinSearch: true }, { prop: 'label', label: '名称', width: 200, enablePinyinSearch: true },
{ prop: 'value', label: '代号', width: 120, enablePinyinSearch: true }, { prop: 'value', label: '代号', width: 200, enablePinyinSearch: true },
]) ])
const dstHospName = ref('') const dstHospName = ref('')
@ -146,7 +87,6 @@ const handleSelectionChange = (val: any) => {
barcodes.value = val.map((item: any) => item.barcode) barcodes.value = val.map((item: any) => item.barcode)
} }
const getValue = (val: any) => { const getValue = (val: any) => {
console.log('val==>', val);
dstHospName.value = val.label dstHospName.value = val.label
} }
const sjHandle = (val: number) => { const sjHandle = (val: number) => {
@ -158,56 +98,44 @@ const sjHandle = (val: number) => {
dstHospCode: dstHospCode.value, dstHospCode: dstHospCode.value,
status: val status: val
} }
sampleSign(params).then((res: any) => { sampleSign(params).then((res: any) => {
if (res.code == 0) { if (res.code == 0) {
ElMessage.success('操作成功!') ElMessage.success('操作成功!')
handleQuery()
dstHospCode.value = '' dstHospCode.value = ''
barcodes.value.forEach((item) => {
tableData.value.forEach((element, index) => {
if (item == element.barcode) {
tableData.value.splice(index, 1)
}
});
});
} }
}) })
} }
const currentChange = (page: { currentPage: number, pageSize: number }) => {
queryParams.value.pageNum = page.currentPage
handleQuery()
}
const sizeChange = (page: { currentPage: number, pageSize: number }) => {
queryParams.value.pageSize = page.pageSize
handleQuery()
}
const handleQuery = () => {
if (queryParams.value.times && queryParams.value.times.length > 0) {
queryParams.value.DateStart = queryParams.value.times[0]
queryParams.value.DateEnd = queryParams.value.times[1]
} else {
queryParams.value.DateStart = ''
queryParams.value.DateEnd = ''
}
getList()
}
const resetHandle = () => {
queryParams.value = {
pageSize: 50,
pageNum: 1,
Status: '30'
}
handleQuery()
}
const getList = () => { const getList = () => {
querySample(queryParams.value).then((res: any) => { const index = tableData.value.findIndex((item: any) => item.barcode == queryParams.value.barcode)
tableData.value = res.rows if (index != -1) {
pagination.value.total = res.total ElMessage.warning('条码号已存在!')
return
}
sampleCollect({ barcode: queryParams.value.barcode }).then((res: any) => {
tableData.value.push(res.data)
queryParams.value.barcode = ''
}) })
} }
const hosList = ref([]) const hosList = ref([])
const regdictList: any = ref([]) const regdictList: any = ref([])
onMounted(() => { onMounted(() => {
getList()
listhospital().then((res: any) => { listhospital().then((res: any) => {
hosList.value = res.rows.map((item: any) => { hosList.value = res.rows.map((item: any) => {
return { return {
@ -220,9 +148,10 @@ onMounted(() => {
listregdict({ pageSize: 100, pageNum: 1, dictType: 'ZT' }).then((res: any) => { listregdict({ pageSize: 100, pageNum: 1, dictType: 'ZT' }).then((res: any) => {
regdictList.value = res.rows; regdictList.value = res.rows;
}) })
getDictData('AU')
}) })
const formatDict = (v: string, arr: Array<any>) => { const formatDicts = (v: string, arr: Array<any>) => {
return arr.find((item: any) => item.dictCode == v)?.dictName || v; return arr.find((item: any) => item.dictCode == v)?.dictName || v;
}; };
</script> </script>
@ -250,6 +179,6 @@ const formatDict = (v: string, arr: Array<any>) => {
.cz_box { .cz_box {
padding: .3125rem 0; padding: .3125rem 0;
border-top: 1px solid #ccc; // border-top: 1px solid #ccc;
} }
</style> </style>

View File

@ -9,8 +9,8 @@
value-format="YYYY-MM-DD HH:mm:ss" @change="handletime" style="width: 25rem;" /> value-format="YYYY-MM-DD HH:mm:ss" @change="handletime" style="width: 25rem;" />
</el-form-item> </el-form-item>
<el-form-item label="委托机构:" prop="SrcHospName"> <el-form-item label="委托机构:" prop="srcHospName">
<SelectTable v-model:data="queryParams.SrcHospName" :fields="ksdhFields" :tableData="hosList" label="label" <SelectTable v-model:data="queryParams.srcHospName" :fields="ksdhFields" :tableData="hosList" label="label"
width="12.5rem" :size="aotuSize" value="label" objKey="label" :border="true" placeholder="请选择委托机构" /> width="12.5rem" :size="aotuSize" value="label" objKey="label" :border="true" placeholder="请选择委托机构" />
</el-form-item> </el-form-item>
<el-form-item label="条码状态:" prop="zt"> <el-form-item label="条码状态:" prop="zt">
@ -165,7 +165,7 @@ import CustomTable from '@/components/elTable/index.vue'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import { usePrintStore } from '@/store/modules/printStore' import { usePrintStore } from '@/store/modules/printStore'
import { fetchCodeList, addObj, fetchCodeDetail, fetchCodeExec, fetchCodeReqmain, printSendSample, printsetup } from '@/api/checkCode/index' import { fetchCodeList, addObj, fetchCodeDetail, fetchCodeExec, fetchCodeReqmain, printSendSample, printsetup } from '@/api/checkCode/index'
import dayjs from 'dayjs';
import { listhospital } from "@/api/regional/dict/hospital"; import { listhospital } from "@/api/regional/dict/hospital";
const aotuSize = classCom.useAutoSize(); const aotuSize = classCom.useAutoSize();
import useUserStore from '@/store/modules/user' import useUserStore from '@/store/modules/user'
@ -189,7 +189,7 @@ interface QueryParams {
zt: string; zt: string;
failed4: string; failed4: string;
failed5: string; failed5: string;
SrcHospName: string; srcHospName: string;
userid: string; userid: string;
} }
// 提交表单数据 // 提交表单数据
@ -198,7 +198,7 @@ const queryParams = reactive<QueryParams>({
userid: '', userid: '',
yljg: '1', yljg: '1',
zt: '', zt: '',
SrcHospName: userStore.sysLoginParam.loginYLJGName, srcHospName: userStore.sysLoginParam.loginYLJGName,
failed4: '', failed4: '',
failed5: '', failed5: '',
}); });
@ -244,7 +244,9 @@ const handleQuery = async () => {
// 重置 // 重置
const resetQuery = () => { const resetQuery = () => {
queryRef.value?.resetFields(); queryRef.value?.resetFields();
queryParams.value.times = ['2025-07-18 00:00:00', '2025-07-18 23:59:59'];
queryParams.value.srcHospName = userStore.sysLoginParam.loginYLJGName,
getDays()
getList() getList()
} }
@ -569,12 +571,16 @@ const changePrinter = (value: string) => {
}) })
}; };
const getDays = () => {
const end = dayjs().format('YYYY-MM-DD HH:mm:ss');
const start = dayjs().subtract(2, 'day').format('YYYY-MM-DD HH:mm:ss'); //add 时间往后
queryParams.times = [start, end];
}
const hosList = ref([]) const hosList = ref([])
onMounted(async () => { onMounted(async () => {
// 初始化3天区间(今天-前两天) // 初始化3天区间(今天-前两天)
// const end = dayjs().format('YYYY-MM-DD HH:mm:ss');
// const start = dayjs().subtract(2, 'day').format('YYYY-MM-DD HH:mm:ss'); //add 时间往后
// queryParams.times = [start, end];
// console.log(queryParams.times); // console.log(queryParams.times);
getList() getList()
adjustTableHeight(); adjustTableHeight();

View File

@ -42,7 +42,11 @@
<el-table-column label="序号" align="center" prop="hospitalId" /> <el-table-column label="序号" align="center" prop="hospitalId" />
<el-table-column label="医疗机构编码" align="center" prop="hospitalCode" /> <el-table-column label="医疗机构编码" align="center" prop="hospitalCode" />
<el-table-column label="医疗机构名称" align="center" prop="hospitalName" /> <el-table-column label="医疗机构名称" align="center" prop="hospitalName" />
<el-table-column label="级别" align="center" prop="hospital_type" /> <el-table-column label="级别" align="center" prop="hospital_type">
<template #default="scope">
{{yljbList.find(item => item.dictCode === scope.row.hospital_type)?.dictName}}
</template>
</el-table-column>
<el-table-column label="状态" align="center" prop="status"> <el-table-column label="状态" align="center" prop="status">
<template #default="scope"> <template #default="scope">
<dict-tag :options="sys_normal_disable" :value="scope.row.status" /> <dict-tag :options="sys_normal_disable" :value="scope.row.status" />

View File

@ -1,11 +1,215 @@
<script setup lang="ts">
</script>
<template> <template>
<div class="cate_container">
<!-- 左侧表格 -->
<div class="left_box">
<el-input v-model="leftSearchValue" placeholder="请输入类别名称或代号" class="mb10" />
<el-table :data="filteredLeftTableData" @row-click="handleLeftRowClick" highlight-current-row border
:cell-style="cellStyle" height="80vh" style="width: 100%;">
<el-table-column prop="itemclassCode" label="分单类别代号" width="110" />
<el-table-column prop="itemclassName" label="类别名称" />
</el-table>
</div>
<!-- 中间表格 -->
<div class="m_box">
<el-input v-model="middleSearchValue" placeholder="请输入项目名称或代号" class="mb10" />
<el-table :data="filteredMiddleTableData" @row-dblclick="handleMiddleRowDblClick" highlight-current-row
style="width: 100%;" height="80vh" border>
<el-table-column prop="itemcode" label="项目代号" width="100" />
<el-table-column prop="itemname" label="当前类别包含门诊项目" />
</el-table>
</div>
<!-- 右侧表格 -->
<div class="right_box">
<el-row :gutter="20" class="mb10">
<el-col :span="12">
<el-input v-model="rightSearchValue" placeholder="请输入项目名称或代号" />
</el-col>
<el-col :span="12">
<el-select v-model="compareStatus" placeholder="请选择" style="width: 200px;" @change="handleSelectChange">
<el-option label="未对照" value="1"></el-option>
<el-option label="其他类别项目" value="2"></el-option>
</el-select>
</el-col>
</el-row>
<el-table :data="filteredRightTableData" @row-dblclick="handleRightRowDblClick" highlight-current-row
height="80vh" border style="width: 100%;">
<el-table-column prop="itemclass" label="类别" width="100">
<template #default="{ row }">
{{leftTableData.find(item => item.itemclassCode === row.itemclass)?.itemclassName}}
</template>
</el-table-column>
<el-table-column prop="itemcode" label="门诊项目代号" width="100" />
<el-table-column prop="itemname" label="门诊项目名称" />
<!-- <el-table-column prop="zjf" label="助记符" /> -->
</el-table>
</div>
</div>
</template> </template>
<style scoped lang="scss"> <script setup lang="ts">
import { feeitemclassList, feeitemvsList, noCompareList, feeitemvAdd, feeitemvDel } from '@/api/mzcx/index';
import { classCom } from '@/utils/classCom';
import { ElMessage, ElMessageBox } from 'element-plus'
import { getFirstLetter } from '@/utils/pinyin';
interface FeeItem {
itemcode: string;
itemname: string;
zjf?: string;
xh?: number;
itemclassCode?: string;
}
const leftSearchValue = ref('');
const middleSearchValue = ref('');
const rightSearchValue = ref('');
const compareStatus = ref('1');
const leftTableData = ref<Array<{ itemclassCode: string; itemclassName: string }>>([]);
const middleTableData = ref<FeeItem[]>([]);
const rightTableData = ref<FeeItem[]>([]);
const itemclassCodeData = ref<{ itemclassCode?: string; itemclassName?: string }>({});
// 过滤后的数据
const filteredLeftTableData = computed(() => {
const searchVal = leftSearchValue.value.toLowerCase().trim();
if (!searchVal) return leftTableData.value;
return leftTableData.value.filter(item =>
item.itemclassCode.toLowerCase().includes(searchVal) ||
item.itemclassName.toLowerCase().includes(searchVal) ||
item.pinyin.toLowerCase().includes(searchVal)
);
});
const filteredMiddleTableData = computed(() => {
const searchVal = middleSearchValue.value.toLowerCase().trim();
if (!searchVal) return middleTableData.value;
return middleTableData.value.filter(item =>
item.itemcode.toLowerCase().includes(searchVal) ||
item.itemname.toLowerCase().includes(searchVal) ||
item.pinyin.toLowerCase().includes(searchVal)
);
});
const filteredRightTableData = computed(() => {
const searchVal = rightSearchValue.value.toLowerCase().trim();
if (!searchVal) return rightTableData.value;
return rightTableData.value.filter(item =>
item.itemcode.toLowerCase().includes(searchVal) ||
item.itemname.toLowerCase().includes(searchVal) ||
item.pinyin.toLowerCase().includes(searchVal)
);
});
const handleSelectChange = () => {
noCompareList({ itemclass: itemclassCodeData.value.itemclassCode, compareStatus: compareStatus.value }).then((res: any) => {
rightTableData.value = processTableData(res.data, 'itemname');
}).catch((err: any) => {
console.error('请求数据失败:', err);
});
};
// 左侧表格行点击事件
const handleLeftRowClick = (row: any) => {
itemclassCodeData.value = row;
feeitemvsList({ itemclass: itemclassCodeData.value.itemclassCode }).then((res: any) => {
middleTableData.value = processTableData(res.data, 'itemname');
}).catch((err: any) => {
console.error('请求数据失败:', err);
});
noCompareList({ itemclass: itemclassCodeData.value.itemclassCode, compareStatus: compareStatus.value }).then((res: any) => {
rightTableData.value = processTableData(res.data, 'itemname');
}).catch((err: any) => {
console.error('请求数据失败:', err);
});
};
// 中间表格行双击事件
const handleMiddleRowDblClick = (row: any) => {
feeitemvDel({ ...row, itemclass: '' }).then((res: any) => {
if (res.code == 0) {
ElMessage.success(res.msg)
handleLeftRowClick(itemclassCodeData.value)
}
})
};
// 右侧表格行双击事件
const handleRightRowDblClick = (row: any) => {
feeitemvDel({ ...row, itemclass: itemclassCodeData.value.itemclassCode }).then((res: any) => {
if (res.code == 0) {
ElMessage.success(res.msg)
handleLeftRowClick(itemclassCodeData.value)
}
})
};
const getList = () => {
feeitemclassList({ pageSize: 999, pageNum: 1 }).then((res: any) => {
if (res.code == 200) {
leftTableData.value = processTableData(res.rows, 'itemclassName')
handleLeftRowClick(res.rows[0]);
}
})
}
const processTableData = (data, calss) => {
return data.map((item) => {
const pinyinMap = {};
pinyinMap['pinyin'] = getFirstLetter(item[calss]).toLowerCase();
return { ...item, ...pinyinMap };
});
};
getList()
// 单元格样式
const cellStyle = ({ row, column, rowIndex, columnIndex }: {
row: any;
column: any;
rowIndex: number;
columnIndex: number;
}) => {
if (column.label == "类别名称") {
const bgColor = classCom.decimalToHexColor(row.itemclassBkcolor);
const textColor = classCom.getContrastTextColor(bgColor);
return {
backgroundColor: `${bgColor}`,
color: textColor,
};
}
}
</script>
<style scoped>
.cate_container {
display: flex;
justify-content: space-between;
padding: 10px;
}
.left_box {
width: 20%;
padding: 10px;
background-color: rgb(214, 240, 252);
}
.m_box {
width: 30%;
padding: 10px;
background-color: rgb(214, 240, 252);
}
.right_box {
width: 49%;
padding: 10px;
background-color: rgb(214, 240, 252);
}
</style> </style>

View File

@ -69,7 +69,7 @@
<el-form ref="regdictRef" :model="form" :rules="rules" label-width="150px"> <el-form ref="regdictRef" :model="form" :rules="rules" label-width="150px">
<el-form-item :label="`${menuname}编码`" prop="dictCode"> <el-form-item :label="`${menuname}编码`" prop="dictCode">
<el-input v-model="form.dictCode" disabled /> <el-input v-model="form.dictCode" />
</el-form-item> </el-form-item>
<el-form-item :label="`${menuname}名称`" prop="dictName"> <el-form-item :label="`${menuname}名称`" prop="dictName">
<el-input v-model="form.dictName" :placeholder="`请输入${menuname}名称`" /> <el-input v-model="form.dictName" :placeholder="`请输入${menuname}名称`" />

View File

@ -0,0 +1,252 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch">
<el-form-item label="项目编码" prop="itemcode">
<el-input v-model="queryParams.itemcode" placeholder="请输入项目编码" clearable style="width: 200px"
@keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="项目名称" prop="itemname">
<el-input v-model="queryParams.itemname" placeholder="请输入项目名称" clearable style="width: 200px"
@keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" placeholder="有效状态" clearable style="width: 200px">
<el-option v-for="dict in sys_normal_disable" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="handleAdd">新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="warning" plain icon="Download" @click="handleExport">导出</el-button>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="postList" @selection-change="handleSelectionChange"
:cell-style="tableCellStyle" height="calc(100vh - 250px)">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="类别" align="center" prop="hospital_type" width="100">
<template #default="{ row }">
{{itemclassList.find((item) => item.itemclassCode == row.itemclass)?.itemclassName}}
</template>
</el-table-column>
<el-table-column label="项目编码" align="center" prop="itemcode" />
<el-table-column label="项目名称" align="center" prop="itemname" width="300" />
<el-table-column label="默认单价" align="center" prop="dj" />
<el-table-column label="一级单价" align="center" prop="dj1" />
<el-table-column label="二级单价" align="center" prop="dj2" />
<el-table-column label="三级单价" align="center" prop="dj3" />
<el-table-column label="状态" align="center" prop="status">
<template #default="scope">
<dict-tag :options="sys_normal_disable" :value="scope.row.status" />
</template>
</el-table-column>
<el-table-column label="操作" width="180" align="center" class-name="small-padding fixed-width">
<template #default="scope">
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)">修改</el-button>
<!-- <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)">删除</el-button> -->
</template>
</el-table-column>
</el-table>
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize" @pagination="getList" />
<!-- 添加或修改项目对话框 -->
<el-dialog :title="title" v-model="open" width="35vw" append-to-body>
<el-form ref="postRef" :model="form" :rules="rules" label-width="150px">
<el-form-item label="项目名称" prop="itemname">
<el-input v-model="form.itemname" placeholder="请输入项目名称" />
</el-form-item>
<el-form-item label="项目编码" prop="itemcode">
<el-input v-model="form.itemcode" placeholder="请输入编码名称" />
</el-form-item>
<el-form-item label="默认单价" prop="dj">
<el-input v-model="form.dj" placeholder="请输入单价" />
</el-form-item>
<el-form-item label="一级单价" prop="dj">
<el-input v-model="form.dj1" placeholder="请输入单价" />
</el-form-item>
<el-form-item label="二级单价" prop="dj">
<el-input v-model="form.dj2" placeholder="请输入单价" />
</el-form-item>
<el-form-item label="三级单价" prop="dj">
<el-input v-model="form.dj3" placeholder="请输入单价" />
</el-form-item>
<!-- <el-form-item label="项目级别" prop="hospital_type">
<el-select v-model="form.hospital_type" placeholder="请选择项目级别" clearable style="width: 100%">
<el-option v-for="item in yljbList" :key="item.dictCode" :label="item.dictName" :value="item.dictCode" />
</el-select>
</el-form-item> -->
<el-form-item label="项目状态" prop="status">
<el-radio-group v-model="form.status">
<el-radio v-for="dict in sys_normal_disable" :key="dict.value" :value="dict.value">{{ dict.label
}}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitForm">确 定</el-button>
<el-button @click="cancel">取 消</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup name="hospital">
import { getXmList, addXmInfo, deleteXmInfo, updateXmInfo } from "@/api/regional/index.ts";
import { getComDicts } from "@/api/liswork/dict/ComDict";
import { listitemclass } from "@/api/regional/dict/itemclass.ts";
import { classCom } from "@/utils/classCom.ts";
const { proxy } = getCurrentInstance();
const { sys_normal_disable } = proxy.useDict("sys_normal_disable");
const postList = ref([]);
const open = ref(false);
const loading = ref(true);
const showSearch = ref(true);
const ids = ref([]);
const single = ref(true);
const multiple = ref(true);
const total = ref(0);
const title = ref("");
const yljbList = ref([]);
const data = reactive({
form: {},
queryParams: {
pageNum: 1,
pageSize: 15,
itemcode: undefined,
itemname: undefined,
status: undefined
},
rules: {
itemname: [{ required: true, message: "项目名称不能为空", trigger: "blur" }],
itemcode: [{ required: true, message: "项目编码不能为空", trigger: "blur" }],
}
});
const { queryParams, form, rules } = toRefs(data);
const tableCellStyle = ({ row, column }) => {
if (column.label == "类别") {
const bkcolor = itemclassList.value.find((item) => item.itemclassCode == row.itemclass)?.itemclassBkcolor;
const bgColor = classCom.decimalToHexColor(bkcolor);
const textColor = classCom.getContrastTextColor(bgColor);
return {
backgroundColor: `${bgColor} !important`,
color: textColor,
};
}
}
/** 查询项目列表 */
function getList() {
loading.value = true;
getXmList(queryParams.value).then(response => {
postList.value = response.rows;
total.value = response.total;
loading.value = false;
});
}
/** 取消按钮 */
function cancel() {
open.value = false;
reset();
}
/** 表单重置 */
function reset() {
form.value = {};
proxy.resetForm("postRef");
}
/** 搜索按钮操作 */
function handleQuery() {
queryParams.value.pageNum = 1;
getList();
}
/** 重置按钮操作 */
function resetQuery() {
proxy.resetForm("queryRef");
handleQuery();
}
/** 多选框选中数据 */
function handleSelectionChange(selection) {
ids.value = selection.map(item => item.hospitalId);
single.value = selection.length != 1;
multiple.value = !selection.length;
}
/** 新增按钮操作 */
function handleAdd() {
reset();
open.value = true;
title.value = "添加项目";
}
/** 修改按钮操作 */
function handleUpdate(row) {
reset();
form.value = JSON.parse(JSON.stringify(row));
open.value = true;
title.value = "修改项目";
}
/** 提交按钮 */
function submitForm() {
proxy.$refs["postRef"].validate(valid => {
if (valid) {
if (title.value == "修改项目") {
updateXmInfo(form.value).then(response => {
proxy.$modal.msgSuccess("修改成功");
open.value = false;
getList();
});
} else {
addXmInfo(form.value).then(response => {
proxy.$modal.msgSuccess("新增成功");
open.value = false;
getList();
});
}
}
});
}
/** 删除按钮操作 */
function handleDelete(row) {
const hospitalIds = row.hospitalId || ids.value;
proxy.$modal.confirm('是否确认删除项目编号为"' + hospitalIds + '"的数据项?').then(function () {
return deleteXmInfo(hospitalIds);
}).then(() => {
getList();
proxy.$modal.msgSuccess("删除成功");
}).catch(() => { });
}
/** 导出按钮操作 */
function handleExport() {
// proxy.download("transitdict/hospital/export", {
// ...queryParams.value
// }, `hospital_${new Date().getTime()}.xlsx`);
}
getList();
const itemclassList = ref([])
onMounted(() => {
listitemclass({ pageSize: 9999, pageNum: 1 }).then(response => {
itemclassList.value = response.rows;
})
getComDicts({ dict_type: 'HTYPE' }).then(response => {
yljbList.value = response.data;
});
})
</script>

View File

@ -13,7 +13,7 @@
"strict": true, "strict": true,
"skipLibCheck": true, "skipLibCheck": true,
"forceConsistentCasingInFileNames": true, "forceConsistentCasingInFileNames": true,
"noImplicitAny": false,
// 模块和兼容性相关配置 // 模块和兼容性相关配置
"allowSyntheticDefaultImports": true, "allowSyntheticDefaultImports": true,
"esModuleInterop": true, "esModuleInterop": true,