Merge branch 'main' of http://47.97.125.165:8902/jiangs/lis8.0-vue3
This commit is contained in:
commit
7e876ce499
@ -18,7 +18,7 @@
|
||||
"axios": "0.27.2",
|
||||
"clipboard": "^2.0.11",
|
||||
"echarts": "5.4.3",
|
||||
"element-plus": "2.4.3",
|
||||
"element-plus": "^2.11.2",
|
||||
"file-saver": "2.0.5",
|
||||
"fuse.js": "6.6.2",
|
||||
"jquery": "^3.7.1",
|
||||
@ -30,8 +30,10 @@
|
||||
"pinia": "2.1.7",
|
||||
"pinyin-pro": "^3.26.0",
|
||||
"select2": "^4.1.0-rc.0",
|
||||
"socket.io-client": "^4.8.1",
|
||||
"vue": "3.4.0",
|
||||
"vue-cropper": "1.1.1",
|
||||
"vue-plugin-hiprint": "^0.0.60",
|
||||
"vue-router": "4.2.5",
|
||||
"vue3-print-nb": "^0.1.4",
|
||||
"vue3-select2-component": "^0.1.7",
|
||||
|
||||
1487
pnpm-lock.yaml
generated
1487
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
86
src/api/checkCode/index.ts
Normal file
86
src/api/checkCode/index.ts
Normal file
@ -0,0 +1,86 @@
|
||||
//@ts-ignore js语法检查忽略
|
||||
import request from '@/utils/request';
|
||||
|
||||
// 生成条码
|
||||
export function addObj(query?: Object) {
|
||||
return request({
|
||||
url: 'zyreq/add',
|
||||
method: 'get',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// 查询申请单列表
|
||||
export function fetchCodeList(query?: Object) {
|
||||
return request({
|
||||
url: '/zyreq/query',
|
||||
method: 'get',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
// 查询项目
|
||||
export function fetchCodeDetail(query?: Object) {
|
||||
return request({
|
||||
url: 'zyreq/detail',
|
||||
method: 'get',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
// 执行条码
|
||||
export function fetchCodeExec(query?: Object) {
|
||||
return request({
|
||||
url: '/zyreq/exec',
|
||||
method: 'get',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
// 获取申请单主表信息
|
||||
export function fetchCodeReqmain(query?: Object) {
|
||||
return request({
|
||||
url: 'zyreq/reqmain',
|
||||
method: 'get',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
// 查询报告单列表
|
||||
export function reportList(query?: Object) {
|
||||
return request({
|
||||
url: '/report/ReportList',
|
||||
method: 'post',
|
||||
data: query,
|
||||
});
|
||||
}
|
||||
// 查询报告Pdf
|
||||
export function reportPrintPdf(query?: Object) {
|
||||
return request({
|
||||
url: '/report/pdf',
|
||||
method: 'get',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
// 查询项目报告
|
||||
export function reportResult(query?: Object) {
|
||||
return request({
|
||||
url: '/report/result',
|
||||
method: 'post',
|
||||
data: query,
|
||||
});
|
||||
}
|
||||
// 查询微生物报告
|
||||
export function reportMedList(query?: Object) {
|
||||
return request({
|
||||
url: '/report/MedList',
|
||||
method: 'post',
|
||||
data: query,
|
||||
});
|
||||
}
|
||||
// 查询微生物报告
|
||||
export function reportFsresult(query?: Object) {
|
||||
return request({
|
||||
url: '/report/fsresult',
|
||||
method: 'post',
|
||||
data: query,
|
||||
});
|
||||
}
|
||||
|
||||
@ -2,37 +2,45 @@ import request from '@/utils/request'
|
||||
|
||||
// 查询字典数据列表
|
||||
export function queryComDictListService(query) {
|
||||
return request({
|
||||
url: '/comdict/query',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
return request({
|
||||
url: '/comdict/query',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
//增加字典数据
|
||||
export function addComDictService(data) {
|
||||
return request({
|
||||
url: '/comdict/add',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
return request({
|
||||
url: '/comdict/add',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
//修改字典数据
|
||||
export function updateComDictService(data) {
|
||||
return request({
|
||||
url: '/comdict/update',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
return request({
|
||||
url: '/comdict/update',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
|
||||
}
|
||||
//删除字典数据
|
||||
export function delComDictService(data) {
|
||||
return request({
|
||||
url: '/comdict/del',
|
||||
method: 'delete',
|
||||
data
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
// 根据字典类型查询字典数据信息
|
||||
export function getComDicts(zdlb) {
|
||||
return request({
|
||||
url: '/comdict/getComDicts',
|
||||
method: 'get',
|
||||
params: zdlb
|
||||
})
|
||||
}
|
||||
|
||||
return request({
|
||||
url: '/comdict/getComDicts',
|
||||
method: 'get',
|
||||
params: zdlb
|
||||
})
|
||||
}
|
||||
155
src/api/mzcx/index.ts
Normal file
155
src/api/mzcx/index.ts
Normal file
@ -0,0 +1,155 @@
|
||||
//@ts-ignore js语法检查忽略
|
||||
import request from '@/utils/request';
|
||||
|
||||
|
||||
// 查询条码类别
|
||||
export function feeitemclassList(query?: Object) {
|
||||
return request({
|
||||
url: 'feeitemclass/query',
|
||||
method: 'get',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
// 报告领取规则
|
||||
export function rptgetrules(query?: Object) {
|
||||
return request({
|
||||
url: '/rptgetrule/query',
|
||||
method: 'get',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
// 新增条码类别
|
||||
export function feeitemclassAdd(query?: Object) {
|
||||
return request({
|
||||
url: '/feeitemclass/add',
|
||||
method: 'post',
|
||||
data: query,
|
||||
});
|
||||
}
|
||||
// 修改条码类别
|
||||
export function feeitemclassUpdate(query?: Object) {
|
||||
return request({
|
||||
url: '/feeitemclass/update',
|
||||
method: 'post',
|
||||
data: query,
|
||||
});
|
||||
}
|
||||
// 删除条码类别
|
||||
export function feeitemclassDel(query?: Object) {
|
||||
return request({
|
||||
url: '/feeitemclass/del',
|
||||
method: 'delete',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// 收费项目维护列表
|
||||
export function xmfeeList(query?: Object) {
|
||||
return request({
|
||||
url: 'xmfee/query',
|
||||
method: 'get',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
// 收费项目新增
|
||||
export function xmfeeadd(query?: Object) {
|
||||
return request({
|
||||
url: 'xmfee/addXmfee',
|
||||
method: 'post',
|
||||
data: query,
|
||||
});
|
||||
}
|
||||
// 收费项目修改
|
||||
export function xmfeeUpdate(query?: Object) {
|
||||
return request({
|
||||
url: 'xmfee/update',
|
||||
method: 'post',
|
||||
data: query,
|
||||
});
|
||||
}
|
||||
// 收费项目删除
|
||||
export function xmfeeDel(query?: Object) {
|
||||
return request({
|
||||
url: 'xmfee/del',
|
||||
method: 'delete',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 报告领取规则维护列表
|
||||
export function rptgetruleList(query?: Object) {
|
||||
return request({
|
||||
url: 'rptgetrule/query',
|
||||
method: 'get',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
// 报告领取规则明细列表
|
||||
export function rptgetruleDetail(query?: Object) {
|
||||
return request({
|
||||
url: 'rptgetrule/queryDetail',
|
||||
method: 'get',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
// 报告领取规则新增
|
||||
export function rptgetruleadd(query?: Object) {
|
||||
return request({
|
||||
url: 'rptgetrule/add',
|
||||
method: 'post',
|
||||
data: query,
|
||||
});
|
||||
}
|
||||
// 报告领取规则修改
|
||||
export function rptgetruleUpdate(query?: Object) {
|
||||
return request({
|
||||
url: 'rptgetrule/update',
|
||||
method: 'post',
|
||||
data: query,
|
||||
});
|
||||
}
|
||||
// 报告领取规则删除
|
||||
export function rptgetruleDel(query?: Object) {
|
||||
return request({
|
||||
url: 'rptgetrule/del',
|
||||
method: 'delete',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
// 报告领取规则明细删除
|
||||
export function rptgetruleDelDetail(query?: Object) {
|
||||
return request({
|
||||
url: 'rptgetrule/delDetail',
|
||||
method: 'delete',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
// 查询条码类别与项目对照
|
||||
export function feeitemvsList(query?: Object) {
|
||||
return request({
|
||||
url: '/feeitemvsclass/query',
|
||||
method: 'get',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
// 保存对照的项目
|
||||
export function feeitemvAdd(query?: Object) {
|
||||
return request({
|
||||
url: '/feeitemvsclass/add',
|
||||
method: 'post',
|
||||
data: query,
|
||||
});
|
||||
}
|
||||
// 保存对照的项目
|
||||
export function feeitemvDel(query?: Object) {
|
||||
return request({
|
||||
url: '/feeitemvsclass/del',
|
||||
method: 'delete',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
44
src/api/system/parameter.ts
Normal file
44
src/api/system/parameter.ts
Normal file
@ -0,0 +1,44 @@
|
||||
//@ts-ignore js语法检查忽略
|
||||
import request from '@/utils/request';
|
||||
|
||||
|
||||
// 查询参数列表
|
||||
export function paramList(query?: Object) {
|
||||
return request({
|
||||
url: '/param/query',
|
||||
method: 'get',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
// 新增参数列表
|
||||
export function addParam(query?: Object) {
|
||||
return request({
|
||||
url: '/param/add',
|
||||
method: 'post',
|
||||
data: query,
|
||||
});
|
||||
}
|
||||
// 修改参数列表
|
||||
export function updateParam(query?: Object) {
|
||||
return request({
|
||||
url: '/param/update',
|
||||
method: 'post',
|
||||
data: query,
|
||||
});
|
||||
}
|
||||
// 删除参数列表
|
||||
export function delParam(query?: Object) {
|
||||
return request({
|
||||
url: '/param/del',
|
||||
method: 'delete',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
// 查询参数列表树状结构
|
||||
export function paramTree(query?: Object) {
|
||||
return request({
|
||||
url: '/param/queryTree',
|
||||
method: 'get',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
@ -182,3 +182,9 @@ aside {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.flex-between {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
@ -8,14 +8,16 @@
|
||||
<el-button circle icon="Refresh" @click="refresh()" />
|
||||
</el-tooltip>
|
||||
<el-tooltip class="item" effect="dark" content="显隐列" placement="top" v-if="columns">
|
||||
<el-button circle icon="Menu" @click="showColumn()" v-if="showColumnsType == 'transfer'"/>
|
||||
<el-dropdown trigger="click" :hide-on-click="false" style="padding-left: 12px" v-if="showColumnsType == 'checkbox'">
|
||||
<el-button circle icon="Menu" @click="showColumn()" v-if="showColumnsType == 'transfer'" />
|
||||
<el-dropdown trigger="click" :hide-on-click="false" style="padding-left: 12px"
|
||||
v-if="showColumnsType == 'checkbox'">
|
||||
<el-button circle icon="Menu" />
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<template v-for="item in columns" :key="item.key">
|
||||
<el-dropdown-item>
|
||||
<el-checkbox :checked="item.visible" @change="checkboxChange($event, item.label)" :label="item.label" />
|
||||
<el-checkbox :checked="item.visible" @change="checkboxChange($event, item.label)"
|
||||
:label="item.label" />
|
||||
</el-dropdown-item>
|
||||
</template>
|
||||
</el-dropdown-menu>
|
||||
@ -24,12 +26,7 @@
|
||||
</el-tooltip>
|
||||
</el-row>
|
||||
<el-dialog :title="title" v-model="open" append-to-body>
|
||||
<el-transfer
|
||||
:titles="['显示', '隐藏']"
|
||||
v-model="value"
|
||||
:data="columns"
|
||||
@change="dataChange"
|
||||
></el-transfer>
|
||||
<el-transfer :titles="['显示', '隐藏']" v-model="value" :data="columns" @change="dataChange"></el-transfer>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
@ -62,7 +59,7 @@ const props = defineProps({
|
||||
},
|
||||
})
|
||||
|
||||
const emits = defineEmits(['update:showSearch', 'queryTable']);
|
||||
const emits = defineEmits(['update:showSearch', 'queryTable', 'updateColumns']);
|
||||
|
||||
// 显隐数据
|
||||
const value = ref([]);
|
||||
@ -114,6 +111,9 @@ if (props.showColumnsType == 'transfer') {
|
||||
// 勾选
|
||||
function checkboxChange(event, label) {
|
||||
props.columns.filter(item => item.label == label)[0].visible = event;
|
||||
|
||||
emits("updateColumns", toRaw(props.columns));
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
@ -124,9 +124,11 @@ function checkboxChange(event, label) {
|
||||
display: block;
|
||||
margin-left: 0px;
|
||||
}
|
||||
|
||||
:deep(.el-transfer__button:first-child) {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
:deep(.el-dropdown-menu__item) {
|
||||
line-height: 30px;
|
||||
padding: 0 17px;
|
||||
|
||||
296
src/components/tableCom/index.vue
Normal file
296
src/components/tableCom/index.vue
Normal file
@ -0,0 +1,296 @@
|
||||
<template>
|
||||
<div class="custom-table-wrapper">
|
||||
<!-- 表格主体 -->
|
||||
<el-table ref="tableRef" :data="tableData" v-loading="loading" :stripe="config.stripe || false"
|
||||
:border="config.border" :fit="config.fit !== true" :show-header="config.showHeader !== false"
|
||||
:highlight-current-row="config.highlightCurrentRow || false" :row-class-name="config.rowClassName"
|
||||
:header-cell-style="config.headerCellStyle" :cell-style="config.cellStyle" :max-height="config.maxHeight"
|
||||
:height="config.height" :size="config.size || 'default'" :empty-text="config.emptyText || '暂无数据'"
|
||||
@selection-change="handleSelectionChange" @current-change="handleCurrentChange" @row-click="handleRowClick"
|
||||
@row-dblclick="handleRowDblclick" @sort-change="handleSortChange" v-bind="$attrs">
|
||||
<!-- 多选列 -->
|
||||
<el-table-column v-if="config.selection" type="selection" :width="config.selectionWidth || 55"
|
||||
:fixed="config.selectionFixed" align="center" />
|
||||
|
||||
<!-- 序号列 -->
|
||||
<el-table-column v-if="config.index" type="index" :label="config.indexLabel || '序号'"
|
||||
:width="config.indexWidth || 60" :fixed="config.indexFixed" align="center" :index="getIndex" />
|
||||
|
||||
<!-- 动态列 -->
|
||||
<template v-for="item in columns" :key="item.prop || item.key">
|
||||
<!-- 自定义插槽列 行数据插槽(有row属性) -->
|
||||
<el-table-column v-if="item.slot && item.visible" :prop="item.prop" :label="item.label" :width="item.width"
|
||||
:min-width="item.minWidth" :fixed="item.fixed" :align="item.align || 'left'" :sortable="item.sortable"
|
||||
:show-overflow-tooltip="item.showOverflowTooltip !== false">
|
||||
<template #default="scope">
|
||||
<slot :name="item.slot" :row="scope.row" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 普通列 -->
|
||||
<el-table-column v-if="!item.slot && item.visible" :prop="item.prop" :label="item.label" :width="item.width"
|
||||
:min-width="item.minWidth" :fixed="item.fixed" :align="item.align || 'left'" :sortable="item.sortable"
|
||||
:show-overflow-tooltip="item.showOverflowTooltip !== false" :formatter="item.formatter">
|
||||
<!-- 表头插槽 (无row属性)-->
|
||||
<template v-if="item.headerSlot" #header="scope">
|
||||
<slot :name="item.headerSlot" :column="scope.column" :$index="scope.$index" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
</template>
|
||||
|
||||
<!-- 操作列 -->
|
||||
<el-table-column v-if="$slots.action" :label="config.actionLabel || '操作'" :width="config.actionWidth"
|
||||
:min-width="config.actionMinWidth || 120" :fixed="config.actionFixed || 'right'"
|
||||
:align="config.actionAlign || 'center'">
|
||||
<template #default="scope">
|
||||
<slot name="action" :row="scope.row" :column="scope.column" :$index="scope.$index" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 空数据插槽 -->
|
||||
<template v-if="$slots.empty" #empty>
|
||||
<slot name="empty" />
|
||||
</template>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页组件 -->
|
||||
<div v-if="pagination.show" class="pagination-wrapper">
|
||||
<el-pagination v-model:current-page="currentPage" v-model:page-size="currentPageSize" :total="pagination.total"
|
||||
:page-sizes="pagination.pageSizes || [10, 20, 50, 100]"
|
||||
:layout="pagination.layout || 'total, sizes, prev, pager, next, jumper'"
|
||||
:background="pagination.background !== false" :small="pagination.small || false"
|
||||
:disabled="pagination.disabled || false" @size-change="handleSizeChange"
|
||||
@current-change="handleCurrentPageChange" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { computed, ref, watch, PropType } from "vue";
|
||||
import { TableColumnCtx } from 'element-plus';
|
||||
interface TableColumn {
|
||||
prop?: string;
|
||||
key?: string | number;
|
||||
label?: string;
|
||||
width?: string | number;
|
||||
minWidth?: string | number;
|
||||
fixed?: boolean | string;
|
||||
align?: string;
|
||||
sortable?: boolean;
|
||||
showOverflowTooltip?: boolean;
|
||||
formatter?: Function;
|
||||
slot?: string;
|
||||
headerSlot?: string;
|
||||
visible?: boolean; // 是否显示列
|
||||
}
|
||||
|
||||
// 在子组件中定义插槽类型
|
||||
defineSlots<{
|
||||
// 具名插槽和动态插槽(不含 default)
|
||||
[slotName: string]: (props: { row?: any; column?: any; $index?: number }) => any;
|
||||
}>();
|
||||
|
||||
// Props 定义
|
||||
const props = defineProps({
|
||||
// 表格数据
|
||||
data: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
// 表格列配置
|
||||
columns: {
|
||||
type: Array as PropType<TableColumn[]>,
|
||||
default: () => [],
|
||||
},
|
||||
// 表格配置
|
||||
config: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
// 加载状态
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
// 分页配置
|
||||
pagination: {
|
||||
type: Object,
|
||||
default: () => ({
|
||||
show: false,
|
||||
total: 0,
|
||||
pageSize: 10,
|
||||
currentPage: 1,
|
||||
}),
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
|
||||
// Emits 定义
|
||||
const emit = defineEmits([
|
||||
"selection-change",
|
||||
"current-change",
|
||||
"row-click",
|
||||
"row-dblclick",
|
||||
"sort-change",
|
||||
"page-change",
|
||||
"size-change",
|
||||
]);
|
||||
|
||||
// 响应式数据
|
||||
const tableRef = ref();
|
||||
const currentPage = ref(props.pagination.currentPage || 1); // 第几页
|
||||
const currentPageSize = ref(props.pagination.pageSize || 10); // 一页显示多少条
|
||||
|
||||
// 计算属性
|
||||
const tableData = computed(() => {
|
||||
if (props.pagination.show && props.pagination.clientPaging) {
|
||||
// 客户端分页
|
||||
const start = (currentPage.value - 1) * currentPageSize.value;
|
||||
const end = start + currentPageSize.value;
|
||||
return props.data.slice(start, end);
|
||||
}
|
||||
return props.data;
|
||||
});
|
||||
|
||||
// 序号计算
|
||||
const getIndex = (index: number) => {
|
||||
if (props.pagination.show && !props.pagination.clientPaging) {
|
||||
return (currentPage.value - 1) * currentPageSize.value + index + 1;
|
||||
}
|
||||
return index + 1;
|
||||
};
|
||||
|
||||
// 事件处理
|
||||
const handleSelectionChange = (selection: any[]) => {
|
||||
emit("selection-change", selection);
|
||||
};
|
||||
|
||||
const handleCurrentChange = (currentRow: any, oldCurrentRow: any) => {
|
||||
emit("current-change", currentRow, oldCurrentRow);
|
||||
};
|
||||
|
||||
const handleRowClick = (row: any, column: TableColumnCtx<any>, event: Event) => {
|
||||
emit("row-click", row, column, event);
|
||||
};
|
||||
|
||||
const handleRowDblclick = (row: any, column: TableColumnCtx<any>, event: Event) => {
|
||||
emit("row-dblclick", row, column, event);
|
||||
};
|
||||
|
||||
const handleSortChange = (sortInfo: Object) => {
|
||||
emit("sort-change", sortInfo);
|
||||
};
|
||||
|
||||
const handleSizeChange = (size: number) => {
|
||||
currentPageSize.value = size;
|
||||
currentPage.value = 1;
|
||||
emit("size-change", {
|
||||
pageSize: size,
|
||||
currentPage: 1,
|
||||
});
|
||||
};
|
||||
|
||||
const handleCurrentPageChange = (page: number) => {
|
||||
currentPage.value = page;
|
||||
emit("page-change", {
|
||||
currentPage: page,
|
||||
pageSize: currentPageSize.value,
|
||||
});
|
||||
};
|
||||
|
||||
// 监听分页配置变化
|
||||
watch(
|
||||
() => props.pagination.currentPage,
|
||||
(newVal) => {
|
||||
if (newVal) {
|
||||
currentPage.value = newVal;
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
watch(
|
||||
() => props.pagination.pageSize,
|
||||
(newVal) => {
|
||||
if (newVal) {
|
||||
currentPageSize.value = newVal;
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
// 暴露方法
|
||||
const clearSelection = () => {
|
||||
tableRef.value?.clearSelection();
|
||||
};
|
||||
|
||||
const toggleRowSelection = (row: Object, selected: boolean) => {
|
||||
tableRef.value?.toggleRowSelection(row, selected);
|
||||
};
|
||||
|
||||
const toggleAllSelection = () => {
|
||||
tableRef.value?.toggleAllSelection();
|
||||
};
|
||||
|
||||
const setCurrentRow = (row: Object) => {
|
||||
tableRef.value?.setCurrentRow(row);
|
||||
};
|
||||
|
||||
const clearSort = () => {
|
||||
tableRef.value?.clearSort();
|
||||
};
|
||||
|
||||
const doLayout = () => {
|
||||
tableRef.value?.doLayout();
|
||||
};
|
||||
|
||||
const sort = (prop: string, order: any) => {
|
||||
tableRef.value?.sort(prop, order);
|
||||
};
|
||||
|
||||
// 导出方法
|
||||
defineExpose({
|
||||
clearSelection,
|
||||
toggleRowSelection,
|
||||
toggleAllSelection,
|
||||
setCurrentRow,
|
||||
clearSort,
|
||||
doLayout,
|
||||
sort,
|
||||
tableRef,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.custom-table-wrapper {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.pagination-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
padding: 12px 0;
|
||||
margin-top: 16px;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
/* 修改选中行背景色 */
|
||||
::v-deep .el-table__body tr.current-row>td {
|
||||
background-color: #add7f7 !important;
|
||||
}
|
||||
|
||||
/* 可选:修改悬停颜色 */
|
||||
::v-deep .el-table__body tr.hover-row>td {
|
||||
background-color: #326ca5 !important;
|
||||
}
|
||||
|
||||
/* 响应式设计 */
|
||||
@media (max-width: 768px) {
|
||||
.pagination-wrapper {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.pagination-wrapper :deep(.el-pagination) {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
16
src/env.d.ts
vendored
Normal file
16
src/env.d.ts
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
|
||||
declare global {
|
||||
namespace JSX {
|
||||
interface IntrinsicElements {
|
||||
[elemName: string]: HTMLAttributes
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
declare module '*.vue' {
|
||||
import type { DefineComponent } from 'vue'
|
||||
const component: DefineComponent<{}, {}, any>
|
||||
export default component
|
||||
}
|
||||
@ -1,11 +1,21 @@
|
||||
import axios from 'axios'
|
||||
import { ElLoading, ElMessage } from 'element-plus'
|
||||
import { saveAs } from 'file-saver'
|
||||
import { getToken } from '@/utils/auth'
|
||||
import {
|
||||
ElLoading,
|
||||
ElMessage
|
||||
} from 'element-plus'
|
||||
import {
|
||||
saveAs
|
||||
} from 'file-saver'
|
||||
import {
|
||||
getToken
|
||||
} from '@/utils/auth'
|
||||
import errorCode from '@/utils/errorCode'
|
||||
import { blobValidate } from '@/utils/ruoyi'
|
||||
import {
|
||||
blobValidate
|
||||
} from '@/utils/ruoyi'
|
||||
|
||||
const baseURL = import.meta.env.VITE_APP_BASE_API
|
||||
const baseURL =
|
||||
import.meta.env.VITE_APP_BASE_API
|
||||
let downloadLoadingInstance;
|
||||
|
||||
export default {
|
||||
@ -15,7 +25,24 @@ export default {
|
||||
method: 'get',
|
||||
url: url,
|
||||
responseType: 'blob',
|
||||
headers: { 'Authorization': 'Bearer ' + getToken() }
|
||||
headers: {
|
||||
'Authorization': 'Bearer ' + getToken()
|
||||
},
|
||||
onDownloadProgress: (progressEvent) => {
|
||||
console.log(progressEvent)
|
||||
//progressEvent.loaded 下载文件的当前大小
|
||||
//progressEvent.total 下载文件的总大小 如果后端没有返回 请让他加上
|
||||
let progressPercent = Math.round((progressEvent.loaded / progressEvent.total) * 100);
|
||||
let loading = ElLoading.service({
|
||||
lock: true,
|
||||
text: `下载中,请稍候${progressPercent}%`,
|
||||
background: 'rgba(0, 0, 0, 0.7)',
|
||||
})
|
||||
loading.setText(`下载中,请稍候${progressPercent}%`)
|
||||
if (progressPercent == 100) {
|
||||
loading.close()
|
||||
}
|
||||
}
|
||||
}).then((res) => {
|
||||
const isBlob = blobValidate(res.data);
|
||||
if (isBlob) {
|
||||
@ -32,7 +59,9 @@ export default {
|
||||
method: 'get',
|
||||
url: url,
|
||||
responseType: 'blob',
|
||||
headers: { 'Authorization': 'Bearer ' + getToken() }
|
||||
headers: {
|
||||
'Authorization': 'Bearer ' + getToken()
|
||||
}
|
||||
}).then((res) => {
|
||||
const isBlob = blobValidate(res.data);
|
||||
if (isBlob) {
|
||||
@ -45,16 +74,23 @@ export default {
|
||||
},
|
||||
zip(url, name) {
|
||||
var url = baseURL + url
|
||||
downloadLoadingInstance = ElLoading.service({ text: "正在下载数据,请稍候", background: "rgba(0, 0, 0, 0.7)", })
|
||||
downloadLoadingInstance = ElLoading.service({
|
||||
text: "正在下载数据,请稍候",
|
||||
background: "rgba(0, 0, 0, 0.7)",
|
||||
})
|
||||
axios({
|
||||
method: 'get',
|
||||
url: url,
|
||||
responseType: 'blob',
|
||||
headers: { 'Authorization': 'Bearer ' + getToken() }
|
||||
headers: {
|
||||
'Authorization': 'Bearer ' + getToken()
|
||||
}
|
||||
}).then((res) => {
|
||||
const isBlob = blobValidate(res.data);
|
||||
if (isBlob) {
|
||||
const blob = new Blob([res.data], { type: 'application/zip' })
|
||||
const blob = new Blob([res.data], {
|
||||
type: 'application/zip'
|
||||
})
|
||||
this.saveAs(blob, name)
|
||||
} else {
|
||||
this.printErrMsg(res.data);
|
||||
@ -75,5 +111,4 @@ export default {
|
||||
const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default']
|
||||
ElMessage.error(errMsg);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
26
src/store/modules/printStore.ts
Normal file
26
src/store/modules/printStore.ts
Normal file
@ -0,0 +1,26 @@
|
||||
// 打印状态管理
|
||||
import { defineStore } from 'pinia'
|
||||
|
||||
export const usePrintStore = defineStore('printStore', {
|
||||
state: () => ({
|
||||
isConnected: false, // 存储连接状态
|
||||
clientInfo: null, // 存储客户端信息
|
||||
printerList: [] as any[], // 存储打印机列表
|
||||
defaultPrinter: '' as string, // 存储默认打印机名称
|
||||
}),
|
||||
actions: {
|
||||
setConnected(status: boolean) {
|
||||
this.isConnected = status
|
||||
},
|
||||
setClientInfo(info: any) {
|
||||
this.clientInfo = info
|
||||
},
|
||||
setPrinterList(list: any[]) {
|
||||
this.printerList = list
|
||||
this.defaultPrinter = list.find((p) => p.isDefault)?.name || ''
|
||||
},
|
||||
setDefaultPrinter(printerName: string) {
|
||||
this.defaultPrinter = printerName
|
||||
}
|
||||
}
|
||||
})
|
||||
91
src/utils/classCom.ts
Normal file
91
src/utils/classCom.ts
Normal file
@ -0,0 +1,91 @@
|
||||
|
||||
/**
|
||||
* 颜色处理工具类
|
||||
* 提供十进制颜色值转十六进制颜色码(支持BGR转RGB)及文字对比度计算功能
|
||||
*/
|
||||
|
||||
function decimalToHexColor(decimal: number | string): string {
|
||||
// 处理空值和非数字情况
|
||||
if (decimal === undefined || decimal === null || decimal === '') {
|
||||
return '#FFFFFF';
|
||||
}
|
||||
|
||||
// 统一转换为数字类型
|
||||
const num = typeof decimal === 'string' ? parseFloat(decimal) : decimal;
|
||||
|
||||
if (isNaN(num)) {
|
||||
return '#FFFFFF';
|
||||
}
|
||||
|
||||
// 十进制转十六进制并转为大写
|
||||
let hex = Math.floor(num).toString(16).toUpperCase();
|
||||
let rgbHex = ''
|
||||
// 确保十六进制字符串为6位,不足则补0
|
||||
if (hex.length < 6) {
|
||||
hex = hex.padStart(6, '0');
|
||||
}
|
||||
|
||||
// BGR转RGB(交换前后两位)
|
||||
const r = hex.substring(4, 6);
|
||||
const g = hex.substring(2, 4);
|
||||
const b = hex.substring(0, 2);
|
||||
rgbHex = r + g + b;
|
||||
return `#${rgbHex}`;
|
||||
}
|
||||
|
||||
|
||||
// 处理颜色转换为十进制数字
|
||||
const convertHexToNumber = (hex: string) => {
|
||||
if (!hex) return
|
||||
hex = hex.replace('#', '');
|
||||
const bgr = hex.slice(4, 6) + hex.slice(2, 4) + hex.slice(0, 2);
|
||||
return parseInt(bgr, 16);
|
||||
};
|
||||
/**
|
||||
* 根据背景色计算对比度文字颜色(黑/白)
|
||||
* @param bgColor 十六进制背景色(如#FFFF80)
|
||||
* @returns 对比度文字颜色(#333333或#FFFFFF)
|
||||
*/
|
||||
function getContrastTextColor(bgColor: string): string {
|
||||
// 验证颜色格式
|
||||
if (!/^#([0-9A-F]{6})$/i.test(bgColor)) {
|
||||
throw new Error('Invalid hex color format. Expected #RRGGBB');
|
||||
}
|
||||
|
||||
// 提取RGB分量
|
||||
const r = parseInt(bgColor.slice(1, 3), 16);
|
||||
const g = parseInt(bgColor.slice(3, 5), 16);
|
||||
const b = parseInt(bgColor.slice(5, 7), 16);
|
||||
|
||||
// 计算亮度(标准 luminance 公式)
|
||||
const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
|
||||
|
||||
// 根据亮度返回对比色
|
||||
return luminance > 0.5 ? '#333333' : '#FFFFFF';
|
||||
}
|
||||
// 打印base64 pdf
|
||||
function printPDF(base64: string) {
|
||||
const blob = base64ToBlob(base64);
|
||||
const pdfUrl = URL.createObjectURL(blob);
|
||||
const iframe = document.createElement('iframe');
|
||||
iframe.style.display = 'none';
|
||||
iframe.src = pdfUrl;
|
||||
document.body.appendChild(iframe);
|
||||
iframe.onload = () => {
|
||||
iframe.contentWindow?.print();
|
||||
setTimeout(() => URL.revokeObjectURL(pdfUrl), 1000); // 释放内存
|
||||
};
|
||||
}
|
||||
|
||||
function base64ToBlob(base64: string) {
|
||||
const binaryString = atob(base64.replace(/[\n\r]/g, ''));
|
||||
const bytes = new Uint8Array(binaryString.length);
|
||||
for (let i = 0; i < binaryString.length; i++) {
|
||||
bytes[i] = binaryString.charCodeAt(i);
|
||||
}
|
||||
return new Blob([bytes], { type: 'application/pdf' });
|
||||
}
|
||||
|
||||
|
||||
export const classCom = { decimalToHexColor, convertHexToNumber, getContrastTextColor, printPDF }
|
||||
|
||||
193
src/utils/hiprintPrinter.ts
Normal file
193
src/utils/hiprintPrinter.ts
Normal file
@ -0,0 +1,193 @@
|
||||
// src/utils/hiprintPrinter.ts
|
||||
import { io, Socket } from "socket.io-client";
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { usePrintStore } from '@/store/modules/printStore'
|
||||
import { onUnmounted } from "vue"
|
||||
// @ts-ignore
|
||||
import Download from '@/plugins/download';
|
||||
// ... 类型定义 ...
|
||||
type PrinterInfo = {
|
||||
name: string;
|
||||
isDefault?: boolean;
|
||||
[key: string]: any;
|
||||
};
|
||||
|
||||
|
||||
interface ClientInfo {
|
||||
id?: string;
|
||||
version?: string;
|
||||
os?: string;
|
||||
[key: string]: string | number | boolean | undefined;
|
||||
}
|
||||
|
||||
type OnPrinterUpdate = (printerList: PrinterInfo[]) => void;
|
||||
let socket: Socket | null = null;
|
||||
|
||||
let clientInfo: ClientInfo | null = null;
|
||||
// 初始化 Socket 连接
|
||||
function initSocket(onPrinterUpdate?: OnPrinterUpdate) {
|
||||
const printStore = usePrintStore();
|
||||
|
||||
if (socket) {
|
||||
socket.disconnect();
|
||||
}
|
||||
|
||||
socket = io("http://localhost:17521", {
|
||||
transports: ["websocket"],
|
||||
reconnection: false, //闭自动重连
|
||||
auth: {
|
||||
token: "vue-plugin-hiprint",
|
||||
},
|
||||
});
|
||||
// 连接成功
|
||||
socket.on("connect", () => {
|
||||
printStore.setConnected(true);
|
||||
console.log("✅ 已连接 electron-hiprint 客户端");
|
||||
socket?.emit("getClientInfo");
|
||||
socket?.emit("refreshPrinterList");
|
||||
});
|
||||
// 客户端信息
|
||||
socket.on("clientInfo", (info: ClientInfo) => {
|
||||
printStore.setClientInfo(info);
|
||||
console.log("📱 客户端信息:", info);
|
||||
});
|
||||
// 打印机列表 (更新默认打印机)
|
||||
socket.on("printerList", (list: PrinterInfo[]) => {
|
||||
printStore.setPrinterList(list);
|
||||
onPrinterUpdate?.(list);
|
||||
console.log("🖨️ 打印机列表更新:", list);
|
||||
});
|
||||
// 连接断开
|
||||
socket.on("disconnect", (reason: string) => {
|
||||
printStore.setConnected(false);
|
||||
console.error("❌ 客户端连接断开:", reason);
|
||||
if (reason === "io server disconnect") {
|
||||
socket?.connect();
|
||||
}
|
||||
});
|
||||
|
||||
socket.on("connect_error", (err: Error) => {
|
||||
console.log('连接错误', err);
|
||||
ElMessageBox.alert(
|
||||
`连接失败!<br>请确保目标服务器已<a style="color: #1f79db" onclick="downExe()">下载安装</a> 并<a style="color: #1f79db" onclick="yxHiprint()"> 运行 </a> 打印服务!`,
|
||||
"客户端未连接",
|
||||
{
|
||||
dangerouslyUseHTMLString: true,
|
||||
}
|
||||
)
|
||||
printStore.setConnected(false);
|
||||
socket?.close();
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
const downExe = () => {
|
||||
// 下载逻辑实现
|
||||
// console.log('开始下载打印服务');
|
||||
Download.name('hiprint_win_x64-1.0.13.exe', false)
|
||||
};
|
||||
const yxHiprint = () => {
|
||||
// 唤起客户端
|
||||
window.open("hiprint://");
|
||||
};
|
||||
|
||||
// 挂载到window,使其能被全局访问
|
||||
(window as any).downExe = downExe;
|
||||
(window as any).yxHiprint = yxHiprint;
|
||||
|
||||
|
||||
// 自定义打印参数(可选)
|
||||
interface PrintOptions {
|
||||
orientation?: "portrait" | "landscape"; // 纵向(landscape=横向)
|
||||
copies?: number;
|
||||
monochrome?: boolean; // 是否黑白打印
|
||||
paperName?: 'A2' | 'A3' | 'A4' | 'A5' | 'A6' | 'letter' | 'legal' | 'tabloid' | 'statement'; //纸张大小
|
||||
}
|
||||
/**
|
||||
* 执行批量静默打印
|
||||
* @param urls PDF文件URL数组
|
||||
* @param options 打印选项(可选)
|
||||
*/
|
||||
function silentPrint(urls: string[], options?: PrintOptions) {
|
||||
if (urls.length === 0) return ElMessage.error('没有打印数据');
|
||||
const printStore = usePrintStore();
|
||||
const handlePrint = () => {
|
||||
ElMessage.success('正在打印文件,请稍候...');
|
||||
urls.forEach(url => silentPrintPdf(url, options));
|
||||
};
|
||||
|
||||
// 已连接直接打印,未连接则初始化后打印
|
||||
if (printStore.isConnected) {
|
||||
handlePrint();
|
||||
} else {
|
||||
initSocket((printerList) => {
|
||||
if (printerList.length > 0) {
|
||||
handlePrint();
|
||||
} else {
|
||||
ElMessage.warning('未检测到可用打印机');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
//静默打印单个PDF文件
|
||||
function silentPrintPdf(url: string, options?: PrintOptions) {
|
||||
const printStore = usePrintStore();
|
||||
const templateId = `pdf-print-${Date.now()}`;
|
||||
const targetPrinter = printStore.defaultPrinter;
|
||||
if (!targetPrinter) {
|
||||
console.log("未检测到打印机,请先连接打印机!");
|
||||
return;
|
||||
}
|
||||
socket?.emit("news", {
|
||||
client: clientInfo,
|
||||
printer: targetPrinter,
|
||||
type: "url_pdf",
|
||||
templateId: templateId,
|
||||
pdf_path: url,
|
||||
});
|
||||
// console.log(`🚀 PDF打印请求已发送,任务ID:${templateId},打印机:${targetPrinter}`);
|
||||
|
||||
}
|
||||
// 销毁
|
||||
function destroy() {
|
||||
const printStore = usePrintStore();
|
||||
if (socket) {
|
||||
socket.disconnect();
|
||||
socket = null;
|
||||
printStore.setConnected(false);
|
||||
console.log("🔌 已断开与 electron-hiprint 的连接");
|
||||
}
|
||||
}
|
||||
|
||||
// 更新 getter 函数以从 store 获取值
|
||||
export const HiprintPrinter = {
|
||||
initSocket,
|
||||
silentPrint,
|
||||
silentPrintPdf,
|
||||
destroy,
|
||||
get isConnected() {
|
||||
const printStore = usePrintStore();
|
||||
return printStore.isConnected;
|
||||
},
|
||||
get clientInfo() {
|
||||
const printStore = usePrintStore();
|
||||
return printStore.clientInfo;
|
||||
},
|
||||
get printerList() {
|
||||
const printStore = usePrintStore();
|
||||
return printStore.printerList;
|
||||
},
|
||||
get defaultPrinter() {
|
||||
const printStore = usePrintStore();
|
||||
return printStore.defaultPrinter;
|
||||
},
|
||||
};
|
||||
|
||||
onUnmounted(() => {
|
||||
if ('downExe' in window) {
|
||||
delete (window as any).downExe;
|
||||
}
|
||||
});
|
||||
624
src/views/checkCode/index.vue
Normal file
624
src/views/checkCode/index.vue
Normal file
@ -0,0 +1,624 @@
|
||||
<template>
|
||||
<div class="app-container ">
|
||||
<div ref="compactForm">
|
||||
<el-row :gutter="10" class="compact-form" v-show="showSearch">
|
||||
<el-form :model="queryParams" ref="queryRef" :inline="true" :rules="queryRules">
|
||||
<el-form-item label="日期:" prop="failed1">
|
||||
<el-date-picker v-model="queryParams.times" type="datetimerange" range-separator="-"
|
||||
start-placeholder="开始时间" end-placeholder="结束时间" format="YYYY-MM-DD HH:mm:ss"
|
||||
value-format="YYYY-MM-DD HH:mm:ss" @change="handletime" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="医疗机构:" prop="yljg">
|
||||
<el-select v-model="queryParams.yljg" placeholder="请选择" style="width: 150px;">
|
||||
<el-option v-for="item in dictData.HOS" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="条码状态:" prop="zt">
|
||||
<el-select v-model="queryParams.zt" placeholder="请选择" style="width: 100px;">
|
||||
<el-option v-for="item in dictData.ST" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="" prop="failed4">
|
||||
<el-select v-model="queryParams.failed4" placeholder="请选择" style="width:140px">
|
||||
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="" prop="failed5">
|
||||
<el-input v-model="queryParams.failed5" clearable placeholder="条件搜索" @keyup.enter="handleQuery"
|
||||
@clear="handleQuery" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="">
|
||||
<el-button icon="search" type="primary" @click="handleQuery">
|
||||
搜索
|
||||
</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
|
||||
</div>
|
||||
|
||||
<el-row :gutter="10">
|
||||
<el-col :span="16" class="right-table">
|
||||
<div class="title"> 条码生成 </div>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="printHandle">生成条码</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Edit" @click="selectStatusRows">选中所有未打印</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain @click="printPdf">打印</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="info" plain icon="Upload" @click="openBlock('采样登记')">采样登记</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain @click="openBlock('送检登记')">送检登记</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain @click="goReport">报告查询</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain @click="cancelHandle">条码作废</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain>打印机设置</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain>清单打印</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @updateColumns="updateColumns" @queryTable="handleQuery"
|
||||
:columns="columns"></right-toolbar>
|
||||
</el-row>
|
||||
|
||||
<CustomTable ref="tableRef" :data="tableData" :columns="columns" :config="tableConfig" :loading="loading"
|
||||
@row-click="rowHandle" @selection-change="selectionChange">
|
||||
<template #dy="{ row }">
|
||||
{{ row.zt != 1 ? '✅' : '❌' }}
|
||||
</template>
|
||||
<template #jzbz="{ row }">
|
||||
{{ row.jzbz == '1' ? '急诊' : '非急诊' }}
|
||||
</template>
|
||||
<template #jjzt="{ row }">
|
||||
{{ row.jjzt == '1' ? '计价' : '无' }}
|
||||
</template>
|
||||
<template #brly="{ row }">
|
||||
{{ formatDict(row.brly, 'PT') }}
|
||||
</template>
|
||||
<template #zt="{ row }">
|
||||
{{ formatDict(row.zt.trim(), 'ST') }}
|
||||
</template>
|
||||
<template #yljg="{ row }">
|
||||
{{ formatDict(row.yljg, 'HOS') }}
|
||||
</template>
|
||||
</CustomTable>
|
||||
|
||||
</el-col>
|
||||
<el-col :span="8" class="right-table">
|
||||
<div class="title"> 项目 </div>
|
||||
<!-- <el-button type="danger" class="mb10">拆分选中项目</el-button> -->
|
||||
<CustomTable :data="rightTableData" :columns="rightColumns" :config="rightTableConfig">
|
||||
<template #jjzt="{ row }">
|
||||
{{ row.jjzt == '1' ? '计价' : '无' }}
|
||||
</template>
|
||||
<template #zt="{ row }">
|
||||
{{ formatDict(row.zt, 'ST') }}
|
||||
</template>
|
||||
</CustomTable>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
|
||||
<!-- 采样登记 -->
|
||||
<el-dialog v-model="dialogVisible" :title="title" draggable :close-on-click-modal="false" width="70vw"
|
||||
@close="closeDialog">
|
||||
<div class="flex-between">
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-input v-model="sqhText" clearable placeholder="条形码" @keyup.enter="sqdQuery" @clear="sqdQuery" />
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" @click="sqdQuery" plain>读取</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="delete">删除选中行</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="info" plain>打印</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<!-- <el-button type="primary" plain>保存</el-button> -->
|
||||
</div>
|
||||
<CustomTable :data="cyTableData" :columns="cyColumns" :config="cyTableConfig">
|
||||
<template #zt="{ row }">
|
||||
{{ formatDict(row.zt, 'ST') }}
|
||||
</template>
|
||||
</CustomTable>
|
||||
</el-dialog>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, toRaw, computed, watch, nextTick, onMounted, } from 'vue';
|
||||
import { HiprintPrinter } from '@/utils/hiprintPrinter';
|
||||
import { classCom } from '@/utils/classCom';
|
||||
import CustomTable from '@/components/tableCom/index.vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { usePrintStore } from '@/store/modules/printStore'
|
||||
import { fetchCodeList, addObj, fetchCodeDetail, fetchCodeExec, fetchCodeReqmain } from '@/api/checkCode/index'
|
||||
import { TableColumnCtx } from 'element-plus';
|
||||
import dayjs from 'dayjs';
|
||||
//@ts-ignore
|
||||
import { comDict } from '@/utils/dict'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
const router = useRouter()
|
||||
const printStore = usePrintStore();
|
||||
const compactForm = ref<HTMLElement | null>(null);
|
||||
const heightForm = ref(90);
|
||||
const dialogVisible = ref(false)
|
||||
const title = ref('采样登记')
|
||||
const sqhText = ref('')
|
||||
const tableRef = ref()
|
||||
interface QueryParams {
|
||||
times: string[]; // 明确类型为字符串元组
|
||||
yljg: string;
|
||||
zt: string;
|
||||
failed4: string;
|
||||
failed5: string;
|
||||
}
|
||||
// 提交表单数据
|
||||
const queryParams = reactive<QueryParams>({
|
||||
times: ['2025-07-18 00:00:00', '2025-07-18 23:59:59'],
|
||||
// times: [],
|
||||
yljg: '1',
|
||||
zt: '',
|
||||
failed4: '',
|
||||
failed5: '',
|
||||
});
|
||||
const showSearch = ref(true);
|
||||
const queryRef = ref()
|
||||
// 定义校验规则
|
||||
const queryRules = ref({
|
||||
// clientId: [
|
||||
// { required: true, message: '编号不能为空', trigger: 'blur' },
|
||||
|
||||
// ],
|
||||
|
||||
// failed3: [
|
||||
// { required: true, message: '条码状态不能为空', trigger: 'change' },
|
||||
// ],
|
||||
})
|
||||
const options = [
|
||||
{
|
||||
value: '1',
|
||||
label: '通过姓名搜索',
|
||||
},
|
||||
{
|
||||
value: '2',
|
||||
label: '通过病人号搜索',
|
||||
},
|
||||
{
|
||||
value: '3',
|
||||
label: '通过床号搜索',
|
||||
},
|
||||
]
|
||||
interface DictData {
|
||||
SX?: Array<any>;
|
||||
HOS?: Array<any>;
|
||||
[key: string]: any[] | undefined; // 添加索引签名以支持动态访问
|
||||
}
|
||||
// 字典数据存储
|
||||
const dictData = ref<DictData>({});
|
||||
const handleQuery = async () => {
|
||||
const valid = await queryRef.value.validate().catch(() => { });
|
||||
if (!valid) return false;
|
||||
getList()
|
||||
}
|
||||
// 重置
|
||||
const resetQuery = () => {
|
||||
queryRef.value?.resetFields();
|
||||
|
||||
getList()
|
||||
}
|
||||
|
||||
const loading = ref(true);
|
||||
|
||||
|
||||
|
||||
// 数据源
|
||||
const tableData = ref([])
|
||||
// 配置项
|
||||
const columns = ref([
|
||||
{ prop: 'zt', label: '打印', visible: true, key: 0, sortable: true, slot: 'dy', },
|
||||
{ prop: 'ch', label: '床号', visible: true, key: 0, sortable: true, },
|
||||
{ prop: 'brxm', label: '姓名', visible: true, key: 1, },
|
||||
{ prop: 'brxbname', label: '性别', align: 'center', visible: true, key: 2, },
|
||||
{ prop: 'jymd', label: '项目名称', align: 'center', visible: true, key: 3, width: '140px' },
|
||||
{ prop: 'bgddhname', label: '类别', align: 'center', visible: true, key: 4, width: '120px' },
|
||||
{ prop: 'sampletips', label: '采样提示', align: 'center', visible: true, key: 5, width: '110px' },
|
||||
{ prop: 'jzbz', label: '急诊', align: 'center', visible: true, slot: 'jzbz', key: 6, width: '110px' },
|
||||
{ prop: 'yblx', label: '样本类型', align: 'center', visible: true, key: 7, width: '110px' },
|
||||
{ prop: 'brdh', label: '病人号', align: 'center', visible: true, key: 8, width: '110px' },
|
||||
{ prop: 'ksname', label: '科室名称', align: 'center', visible: true, key: 9, width: '110px' },
|
||||
{ prop: 'sqh', label: '申请号/条码', align: 'center', visible: true, key: 10, width: '110px' },
|
||||
{ prop: 'zt', label: '状态', align: 'center', visible: true, key: 11, slot: 'zt', width: '110px' },
|
||||
{ prop: 'brly', label: '病人来源', align: 'center', visible: true, key: 12, slot: 'brly', width: '110px' },
|
||||
{ prop: 'sqysname', label: '申请医生', align: 'center', visible: true, key: 13, width: '110px' },
|
||||
{ prop: 'sqsj', label: '申请时间', align: 'center', visible: true, key: 14, width: '170px' },
|
||||
{ prop: 'jjzt', label: '计价标志', align: 'center', visible: true, key: 15, slot: 'jjzt', },
|
||||
{ prop: 'zxysname', label: '执行医生', align: 'center', visible: true, key: 16, },
|
||||
{ prop: 'bbsjrname', label: '送检人', align: 'center', visible: true, key: 17, },
|
||||
{ prop: 'yljg', label: '医疗机构', align: 'center', visible: true, slot: 'yljg', key: 18, width: '170px' },
|
||||
])
|
||||
|
||||
const single = ref(true);
|
||||
const multiple = ref(true);
|
||||
const sqhs = ref([]);
|
||||
// 单元格样式
|
||||
const cellStyleHd = ({ row, column, rowIndex, columnIndex }: {
|
||||
row: any;
|
||||
column: any;
|
||||
rowIndex: number;
|
||||
columnIndex: number;
|
||||
}) => {
|
||||
// console.log(row, column, rowIndex, columnIndex);
|
||||
if (column.label == "急诊" && row.jzbz == "1") {
|
||||
return { background: '#f00 !important', color: '#fff' };
|
||||
}
|
||||
|
||||
if (column.label == "类别") {
|
||||
const bgColor = classCom.decimalToHexColor(row.bkcolor);
|
||||
const textColor = classCom.getContrastTextColor(bgColor);
|
||||
return {
|
||||
backgroundColor: `${bgColor} !important`,
|
||||
color: textColor,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const rowClassNameHd = ({ row, rowIndex }: {
|
||||
row: any;
|
||||
rowIndex: number;
|
||||
}) => {
|
||||
return 'custom-row-class'; // 返回自定义类名
|
||||
};
|
||||
// 点击行
|
||||
const rowHandle = (row: any, column: TableColumnCtx<any>, event: Event) => {
|
||||
getRightTable(row)
|
||||
};
|
||||
|
||||
const selectionChange = (selection: any) => {
|
||||
sqhs.value = selection;
|
||||
single.value = selection.length != 1;
|
||||
multiple.value = !selection.length;
|
||||
}
|
||||
|
||||
// 左侧表格配置
|
||||
const tableConfig = ref({
|
||||
// stripe: true, // 斑马纹
|
||||
border: false, // 边框
|
||||
selection: true, // 多选框
|
||||
index: false, // 序号
|
||||
height: '', // 高度
|
||||
highlightCurrentRow: true, // 高亮当前行
|
||||
cellStyle: cellStyleHd,
|
||||
rowClassName: rowClassNameHd,
|
||||
fit: true
|
||||
})
|
||||
// 右侧数据源
|
||||
const rightTableData = ref([])
|
||||
// 配置项
|
||||
const rightColumns = ref([
|
||||
{ prop: 'sqxmdh', label: '项目代号', visible: true, key: 0, sortable: true, width: '110px' },
|
||||
{ prop: 'sqxmmc', label: '项目名称', visible: true, key: 1, width: '120px' },
|
||||
{ prop: 'dj', label: '单价', align: 'center', visible: true, key: 2 },
|
||||
{ prop: 'sl', label: '数量', align: 'center', visible: true, key: 3 },
|
||||
{ prop: 'zt', label: '状态', align: 'center', visible: true, slot: 'zt', key: 4 },
|
||||
{ prop: 'jjzt', label: '计价标志', align: 'center', visible: true, slot: 'jjzt', key: 5 },
|
||||
|
||||
])
|
||||
// 表格配置
|
||||
const rightTableConfig = ref({
|
||||
// stripe: true, // 斑马纹
|
||||
border: false, // 边框
|
||||
// selection: true, // 多选框
|
||||
index: false, // 序号
|
||||
height: '', // 高度
|
||||
highlightCurrentRow: true, // 高亮当前行
|
||||
})
|
||||
|
||||
// 采样数据源
|
||||
const cyTableData = ref([])
|
||||
// 配置项
|
||||
const cyColumns = ref([
|
||||
{ prop: 'sqh', label: '申请号/条形码', visible: true, key: 0, sortable: true, width: '140px' },
|
||||
{ prop: 'ksdh', label: '科室病区', visible: true, key: 1, width: '120px' },
|
||||
{ prop: 'ch', label: '床号', visible: true, key: 2, sortable: true, },
|
||||
{ prop: 'brxm', label: '姓名', visible: true, key: 3, },
|
||||
{ prop: 'brdh', label: '病人号', visible: true, key: 4, },
|
||||
{ prop: 'brxb', label: '性别', align: 'center', visible: true, key: 5, },
|
||||
{ prop: 'yblx', label: '样本类型', align: 'center', visible: true, key: 6 },
|
||||
{ prop: 'zt', label: '状态', align: 'center', visible: true, slot: 'zt', key: 7 },
|
||||
{ prop: 'jzbz', label: '急诊', align: 'center', visible: true, key: 8 },
|
||||
{ prop: 'jjzt', label: '采样人', align: 'center', visible: true, key: 8 },
|
||||
{ prop: 'cysj', label: '采样时间', align: 'center', visible: true, key: 8 },
|
||||
{ prop: 'zxysname', label: '执行医生', align: 'center', visible: true, key: 8 },
|
||||
{ prop: 'zxsj', label: '执行时间', align: 'center', visible: true, key: 8 },
|
||||
])
|
||||
// 表格配置
|
||||
const cyTableConfig = ref({
|
||||
// stripe: true, // 斑马纹
|
||||
border: false, // 边框
|
||||
selection: true, // 多选框
|
||||
index: false, // 序号
|
||||
height: '100%', // 高度
|
||||
highlightCurrentRow: true, // 高亮当前行
|
||||
})
|
||||
|
||||
// 采样登记
|
||||
const openBlock = (value: string) => {
|
||||
if (sqhs.value.length > 0) {
|
||||
ElMessageBox.confirm(`确定操作选中的数据吗?`, "提示", {
|
||||
confirmButtonText: "确认",
|
||||
cancelButtonText: "取消",
|
||||
beforeClose: async (action, instance, done) => {
|
||||
if (action === "confirm") {
|
||||
// 生成请求Promise数组
|
||||
const requests = sqhs.value.map((item: any) => { return item.sqh });
|
||||
fetchCodeExec({
|
||||
sqh: requests.join(','),
|
||||
userid: 'lis',
|
||||
status: value == '采样登记' ? 12 : 13,
|
||||
yljg: 1
|
||||
}).then((res: any) => {
|
||||
if (res.code == 0) {
|
||||
ElMessage.success('调用成功');
|
||||
done();
|
||||
getList()
|
||||
} else {
|
||||
ElMessage.error('调用失败');
|
||||
}
|
||||
})
|
||||
} else {
|
||||
done();
|
||||
}
|
||||
},
|
||||
}).catch(() => { });
|
||||
|
||||
} else {
|
||||
title.value = value
|
||||
dialogVisible.value = true
|
||||
}
|
||||
}
|
||||
// 采样读取
|
||||
const sqdQuery = () => {
|
||||
const index = cyTableData.value.findIndex((item: any) => item.sqh == sqhText.value)
|
||||
if (index !== -1) return ElMessage.warning('该申请单数据已存在!')
|
||||
|
||||
fetchCodeReqmain({ sqh: sqhText.value }).then((res: any) => {
|
||||
if (res.code == 0 && res.data.sqh) {
|
||||
fetchCodeExec({
|
||||
sqh: res.data.sqh,
|
||||
userid: 'lis',
|
||||
status: 12,
|
||||
yljg: 1
|
||||
})
|
||||
cyTableData.value = cyTableData.value.concat(res.data)
|
||||
}
|
||||
})
|
||||
}
|
||||
// 关闭弹窗清空
|
||||
const closeDialog = () => {
|
||||
cyTableData.value = []
|
||||
sqhText.value = ''
|
||||
}
|
||||
|
||||
|
||||
interface ColumnItem {
|
||||
prop: string;
|
||||
label: string;
|
||||
visible: boolean;
|
||||
key: number;
|
||||
align: string;
|
||||
slot: string;
|
||||
width: string;
|
||||
}
|
||||
// 更新列
|
||||
const updateColumns = (arr: Array<ColumnItem>) => {
|
||||
columns.value = arr
|
||||
};
|
||||
|
||||
const getRightTable = (row: any) => {
|
||||
fetchCodeDetail({ sqh: row.sqh }).then((res: any) => {
|
||||
if (res.code == 0) {
|
||||
rightTableData.value = res.data
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
const goReport = () => {
|
||||
// 跳转到报告查询页面
|
||||
router.push('/report')
|
||||
};
|
||||
|
||||
const cancelHandle = () => {
|
||||
if (sqhs.value.length <= 0) return ElMessage.warning('请选择数据!')
|
||||
ElMessageBox.confirm(`确定作废选中的数据吗?`, "提示", {
|
||||
confirmButtonText: "确认",
|
||||
cancelButtonText: "取消",
|
||||
beforeClose: async (action, instance, done) => {
|
||||
if (action === "confirm") {
|
||||
const requests = sqhs.value.map((item: any) => { return item.sqh });
|
||||
fetchCodeExec({
|
||||
sqh: requests.join(','),
|
||||
userid: 'lis',
|
||||
status: 9,
|
||||
yljg: 1
|
||||
}).then((res: any) => {
|
||||
if (res.code == 0) {
|
||||
ElMessage.success('调用成功');
|
||||
done();
|
||||
getList()
|
||||
} else {
|
||||
ElMessage.error('调用失败');
|
||||
}
|
||||
})
|
||||
} else {
|
||||
done();
|
||||
}
|
||||
},
|
||||
}).catch(() => { });
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
// 初始化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);
|
||||
getList()
|
||||
adjustTableHeight();
|
||||
// 加载病人来源字典
|
||||
const dictRefs = await comDict('PT', 'HOS', 'ST');
|
||||
|
||||
// 从 ref 中获取实际数据
|
||||
dictData.value = {
|
||||
PT: toRaw(dictRefs.PT.value) || [],
|
||||
HOS: toRaw(dictRefs.HOS.value) || [],
|
||||
ST: toRaw(dictRefs.ST.value) || [],
|
||||
};
|
||||
});
|
||||
|
||||
// 字典格式化方法
|
||||
const formatDict = (v: string, dictType: string) => {
|
||||
return dictData.value[dictType]?.find((item: any) => item.value == v)?.label;
|
||||
};
|
||||
|
||||
// 计算table高度
|
||||
watch(showSearch, () => {
|
||||
nextTick(() => {
|
||||
adjustTableHeight();
|
||||
})
|
||||
}, { immediate: true });
|
||||
|
||||
function adjustTableHeight() {
|
||||
if (compactForm.value) {
|
||||
// 获取高度
|
||||
heightForm.value = compactForm.value.offsetHeight;
|
||||
tableConfig.value.height = `calc(72vh - ${heightForm.value}px)`; // 设置表格容器的高度
|
||||
rightTableConfig.value.height = `calc(76vh - ${heightForm.value}px)`;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
const handletime = (val: Array<string>) => {
|
||||
// console.log('时间', val);
|
||||
}
|
||||
|
||||
// 生成条码
|
||||
const printHandle = () => {
|
||||
const data = {
|
||||
dept: '0235',
|
||||
userid: 'lis',
|
||||
st: '',
|
||||
et: '',
|
||||
yljg: queryParams.yljg
|
||||
}
|
||||
if (queryParams.times && queryParams.times.length) {
|
||||
data.st = queryParams.times[0]
|
||||
data.et = queryParams.times[1]
|
||||
}
|
||||
addObj(data).then((res: any) => {
|
||||
if (res.code == 0) {
|
||||
getList()
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
// 查询申请单
|
||||
const getList = () => {
|
||||
loading.value = true;
|
||||
const data = {
|
||||
dept: '0235',
|
||||
userid: 'lis',
|
||||
st: queryParams.times[0],
|
||||
et: queryParams.times[1],
|
||||
yljg: queryParams.yljg
|
||||
}
|
||||
fetchCodeList(data).then((response: any) => {
|
||||
if (response.code == 0) {
|
||||
loading.value = false;
|
||||
tableData.value = response.data
|
||||
getRightTable(response.data[0])
|
||||
tableRef.value.setCurrentRow(response.data[0])
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const selectStatusRows = () => {
|
||||
tableRef.value.clearSelection()
|
||||
tableData.value.forEach((item: any) => {
|
||||
if (item.zt == 1) {
|
||||
tableRef.value.toggleRowSelection(item, true)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 打印pdf
|
||||
const printPdf = () => {
|
||||
if (sqhs.value.length <= 0) return ElMessage.warning('请选择数据!')
|
||||
ElMessageBox.confirm(`确定打印选中的数据吗?`, "提示", {
|
||||
confirmButtonText: "确认",
|
||||
cancelButtonText: "取消",
|
||||
beforeClose: async (action, instance, done) => {
|
||||
if (action === "confirm") {
|
||||
const requests = sqhs.value.map((item: any) => { return item.sqh });
|
||||
fetchCodeExec({
|
||||
sqh: requests.join(','),
|
||||
userid: 'lis',
|
||||
status: 11,
|
||||
yljg: 1
|
||||
}).then((res: any) => {
|
||||
if (res.code == 0) {
|
||||
done();
|
||||
getList()
|
||||
HiprintPrinter.silentPrint(res.data);
|
||||
}
|
||||
})
|
||||
} else {
|
||||
done();
|
||||
}
|
||||
},
|
||||
}).catch(() => { });
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.custom-row-class {
|
||||
background-color: #c6c3ff !important;
|
||||
/* 设置行背景色 */
|
||||
}
|
||||
|
||||
.right-table {
|
||||
border: 1px solid #dcdfe6;
|
||||
}
|
||||
|
||||
.title {
|
||||
border-bottom: 1px solid #dcdfe6;
|
||||
margin-bottom: 10px;
|
||||
padding: 10px;
|
||||
font-weight: 700;
|
||||
}
|
||||
</style>
|
||||
700
src/views/checkCode/report/index.vue
Normal file
700
src/views/checkCode/report/index.vue
Normal file
@ -0,0 +1,700 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<div ref="compactForm">
|
||||
<el-row :gutter="10" class="compact-form" v-show="showSearch">
|
||||
<el-form :model="queryParams" ref="queryRef" :inline="true" :rules="queryRules">
|
||||
<el-form-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-form-item label="病人状态:" prop="dybz">
|
||||
<el-select v-model="queryParams.dybz" placeholder="请选择">
|
||||
<el-option label="已打印" value="1" />
|
||||
<el-option label="未打印" value="0" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="科室:" prop="ksdh">
|
||||
<el-select v-model="queryParams.ksdh" placeholder="请选择" filterable clearable>
|
||||
<el-option v-for="item in dictData.DP" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="病人类型:" prop="brly">
|
||||
<el-select v-model="queryParams.brly" placeholder="请选择" style="width: 120px;">
|
||||
<el-option v-for="item in dictData.PT" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="" prop="">
|
||||
<el-checkbox v-model="queryParams.alarmflag" label="仅危急值" @change="alarmHandle" size="large" />
|
||||
<el-checkbox v-model="queryParams.jzbz" label="仅急诊" @change="jzbzHandle" size="large" />
|
||||
</el-form-item>
|
||||
<el-form-item label="姓名" prop="brxm">
|
||||
<el-col :span="1.5">
|
||||
<el-input v-model="queryParams.brxm" clearable placeholder="姓名" @keyup.enter="handleQuery"
|
||||
@clear="handleQuery" />
|
||||
</el-col>
|
||||
</el-form-item>
|
||||
<el-form-item label="病人号" prop="brdh">
|
||||
<el-col :span="1.5">
|
||||
<el-input v-model="queryParams.brdh" clearable placeholder="病人号" @keyup.enter="handleQuery"
|
||||
@clear="handleQuery" />
|
||||
</el-col>
|
||||
</el-form-item>
|
||||
<el-form-item label="条形码" prop="sqh">
|
||||
<el-col :span="1.5">
|
||||
<el-input v-model="queryParams.sqh" clearable placeholder="条形码" @keyup.enter="handleQuery"
|
||||
@clear="handleQuery" />
|
||||
</el-col>
|
||||
</el-form-item>
|
||||
<el-form-item label="">
|
||||
<el-button icon="search" type="primary" @click="handleQuery">
|
||||
搜索
|
||||
</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
</div>
|
||||
<el-row :gutter="10">
|
||||
<el-col :span="14" class="right-table">
|
||||
<el-row :gutter="10" class="mb8 mt10">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus">打印</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Edit" @click="selectStatusRows">勾选中所有未打印</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain :disabled="single" @click="printPdf">打印单张PDF报告</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="info" plain icon="Upload">GUID打印报告</el-button>
|
||||
</el-col>
|
||||
|
||||
<right-toolbar v-model:showSearch="showSearch" @updateColumns="updateColumns" @queryTable="handleQuery"
|
||||
:columns="columns"></right-toolbar>
|
||||
</el-row>
|
||||
|
||||
<CustomTable ref="tableRefs" :data="tableData" :columns="columns" :config="tableConfig" :loading="loading"
|
||||
@selection-change="selectionChange" @row-click="rowHandle">
|
||||
<template #dybz="{ row }">
|
||||
{{ row.dybz == 1 ? '✅' : '❌' }}
|
||||
</template>
|
||||
<template #alarmflag="{ row }">
|
||||
{{ row.alarmflag == 1 ? '是' : '否' }}
|
||||
</template>
|
||||
<template #jzbz="{ row }">
|
||||
{{ row.jzbz == 1 ? '急诊' : '危急诊' }}
|
||||
</template>
|
||||
</CustomTable>
|
||||
|
||||
</el-col>
|
||||
<el-col :span="10" class="right-table">
|
||||
<div class="title">检验结果</div>
|
||||
<div class="mb10">
|
||||
<el-button type="primary" @click="openDB">对比历史</el-button>
|
||||
<el-button type="primary" @click="copyData('All')">复制全部数据</el-button>
|
||||
<el-button type="primary" @click="copyData('N')">复制异常数据</el-button>
|
||||
<el-button type="primary" @click="copyData('Y')">复制正常数据</el-button>
|
||||
<el-button type="primary">知识库</el-button>
|
||||
</div>
|
||||
|
||||
<CustomTable :data="rightTableData" :columns="rightColumns" :config="rightTableConfig" :loading="loading"
|
||||
@row-click="xmrowHandle">
|
||||
</CustomTable>
|
||||
|
||||
<div class="title mt10">抗生素项目</div>
|
||||
<CustomTable :data="bottomTableData" :columns="bottomColumns" :config="bottomTableConfig" :loading="loading">
|
||||
</CustomTable>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
|
||||
<!-- 结果对比 -->
|
||||
<el-dialog v-model="dialogVisible" title="结果对比" draggable :close-on-click-modal="false">
|
||||
<div class="flex-between">
|
||||
|
||||
</div>
|
||||
<el-table :data="compareTableData" style="width: 100%" @row-click="handleRowClick" highlight-current-row
|
||||
max-height="350px">
|
||||
<el-table-column prop="xmdh" label="项目编号" fixed align="center" width="100px" />
|
||||
<el-table-column prop="xmmc" label="项目名称" fixed align="center" />
|
||||
<template v-for="(period) in periods" :key="period">
|
||||
<el-table-column :label="period" :prop="period" :width="150" align="center" />
|
||||
</template>
|
||||
</el-table>
|
||||
|
||||
<div ref="myEcharts" style="width:100%;height: 350px" />
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, toRaw, computed, watch, nextTick, onMounted } from 'vue';
|
||||
import CustomTable from '@/components/tableCom/index.vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { reportList, reportPrintPdf, reportResult, reportMedList, reportFsresult } from '@/api/checkCode/index'
|
||||
import dayjs from 'dayjs';
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { classCom } from '@/utils/classCom'
|
||||
import * as echarts from 'echarts';
|
||||
//@ts-ignore
|
||||
import { comDict } from '@/utils/dict'
|
||||
const router = useRouter()
|
||||
|
||||
const compactForm = ref<HTMLElement | null>(null);
|
||||
const heightForm = ref(90);
|
||||
const dialogVisible = ref(false)
|
||||
const tableRefs = ref()
|
||||
|
||||
const myEcharts = ref()
|
||||
|
||||
interface QueryParams {
|
||||
times: string[]; // 明确类型为字符串元组
|
||||
alarmflag: boolean,
|
||||
jzbz: boolean,
|
||||
ksdh: string,
|
||||
brly: string,
|
||||
brxm: string,
|
||||
brdh: string,
|
||||
sqh: string,
|
||||
dybz: string,
|
||||
}
|
||||
|
||||
// 提交表单数据
|
||||
const queryParams = reactive<QueryParams>({
|
||||
times: ['2025-08-19', '2025-08-19'],
|
||||
ksdh: '',
|
||||
brly: '',
|
||||
alarmflag: false,
|
||||
jzbz: false,
|
||||
brxm: '',
|
||||
brdh: '',
|
||||
sqh: '',
|
||||
dybz: '',
|
||||
});
|
||||
const single = ref(true);
|
||||
const multiple = ref(true);
|
||||
const alarmflag = ref('0')
|
||||
const jzbz = ref('0')
|
||||
const showSearch = ref(true);
|
||||
const queryRef = ref()
|
||||
// 项目点击数据
|
||||
const Info = ref<any>({})
|
||||
// 定义校验规则
|
||||
const queryRules = ref({
|
||||
// clientId: [
|
||||
// { required: true, message: '编号不能为空', trigger: 'blur' },
|
||||
|
||||
// ],
|
||||
|
||||
// failed3: [
|
||||
// { required: true, message: '条码状态不能为空', trigger: 'change' },
|
||||
// ],
|
||||
})
|
||||
|
||||
const handleQuery = async () => {
|
||||
const valid = await queryRef.value.validate().catch(() => { });
|
||||
if (!valid) return false;
|
||||
getList()
|
||||
}
|
||||
// 重置
|
||||
const resetQuery = () => {
|
||||
queryRef.value?.resetFields();
|
||||
getList()
|
||||
}
|
||||
|
||||
const loading = false;
|
||||
// 勾选框数据
|
||||
const rows = ref<any[]>([])
|
||||
// 数据源
|
||||
const tableData = ref([])
|
||||
// 配置项
|
||||
const columns = ref<ColumnItem[]>([
|
||||
{ prop: 'dybz', label: '打印', visible: true, key: 0, slot: 'dybz', },
|
||||
{ prop: 'jzbz', label: '急诊', visible: true, key: 1, slot: 'jzbz', },
|
||||
{ prop: 'alarmflag', label: '危急值', align: 'center', visible: true, key: 2, slot: 'alarmflag' },
|
||||
{ prop: 'jyrq', label: '检验日期', align: 'center', visible: true, key: 3, width: '150px' },
|
||||
{ prop: 'brdh', label: '病人代号', align: 'center', visible: true, key: 4, width: '110px' },
|
||||
{ prop: 'ch', label: '床号', align: 'center', visible: true, key: 5, sortable: true, },
|
||||
{ prop: 'yqdl', label: '仪器', align: 'center', visible: true, key: 6, width: '110px' },
|
||||
{ prop: 'ybh', label: '样本号', align: 'center', visible: true, key: 7, },
|
||||
{ prop: 'yblxname', label: '样本类型', align: 'center', visible: true, key: 8, },
|
||||
{ prop: 'jymd', label: '检验目的', align: 'center', visible: true, key: 9, width: '110px' },
|
||||
{ prop: 'brlyname', label: '病人类型', align: 'center', visible: true, key: 10, },
|
||||
{ prop: 'brxbname', label: '性别', align: 'center', visible: true, key: 11, },
|
||||
{ prop: 'yqmc', label: '仪器名称', align: 'center', visible: true, key: 12, width: '150px' },
|
||||
{ prop: 'yljg', label: '医疗机构', align: 'center', visible: true, key: 13, width: '150px' },
|
||||
])
|
||||
|
||||
const selectionChange = (selection: any) => {
|
||||
rows.value = selection
|
||||
single.value = selection.length != 1;
|
||||
multiple.value = !selection.length;
|
||||
}
|
||||
|
||||
const rowHandle = (row: any) => {
|
||||
Info.value = row
|
||||
const data = {
|
||||
jyrq: row.jyrq,
|
||||
yq: row.yq,
|
||||
ybh: row.ybh,
|
||||
}
|
||||
reportResult(data).then((res: any) => {
|
||||
if (res.code == 0) {
|
||||
rightTableData.value = res.data
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 打印单张Pdf
|
||||
const printPdf = () => {
|
||||
const data = {
|
||||
jyrq: rows.value[0].jyrq,
|
||||
yq: rows.value[0].yq,
|
||||
ybh: rows.value[0].ybh
|
||||
}
|
||||
reportPrintPdf(data).then((res: any) => {
|
||||
if (res.code == 0) {
|
||||
if (!res.data.base64PDF) return
|
||||
classCom.printPDF(res.data.base64PDF)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// 单元格样式
|
||||
const cellStyleHd = ({ row, column, rowIndex, columnIndex }: {
|
||||
row: any;
|
||||
column: any;
|
||||
rowIndex: number;
|
||||
columnIndex: number;
|
||||
}) => {
|
||||
// console.log(row, column, rowIndex, columnIndex);
|
||||
if (column.label == "急诊" && row.jzbz == "1") {
|
||||
return { background: '#f00 !important', color: '#fff' };
|
||||
}
|
||||
if (column.label == "危急值" && row.alarmflag == "1") {
|
||||
return { background: '#f00 !important', color: '#fff' };
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
// 表格配置
|
||||
const tableConfig = ref(
|
||||
{
|
||||
// stripe: true, // 斑马纹
|
||||
// border: true, // 边框
|
||||
selection: true, // 多选框
|
||||
index: false, // 序号
|
||||
height: '', // 高度
|
||||
highlightCurrentRow: true, // 高亮当前行
|
||||
fit: true,
|
||||
cellStyle: cellStyleHd
|
||||
}
|
||||
)
|
||||
|
||||
// 勾选未打印
|
||||
const selectStatusRows = () => {
|
||||
tableRefs.value.clearSelection()
|
||||
tableData.value.forEach((item: any) => {
|
||||
if (item.dybz != 1) {
|
||||
tableRefs.value.toggleRowSelection(item, true)
|
||||
}
|
||||
})
|
||||
}
|
||||
const alarmHandle = (val: boolean) => {
|
||||
if (val) {
|
||||
queryParams.jzbz = false
|
||||
alarmflag.value = '1'
|
||||
} else {
|
||||
alarmflag.value = '0'
|
||||
}
|
||||
|
||||
}
|
||||
const jzbzHandle = (val: boolean) => {
|
||||
if (val) {
|
||||
queryParams.alarmflag = false
|
||||
jzbz.value = '1'
|
||||
} else {
|
||||
jzbz.value = '0'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
interface ColumnItem {
|
||||
prop: string;
|
||||
label: string;
|
||||
visible: boolean;
|
||||
key: number;
|
||||
align?: string;
|
||||
slot?: string;
|
||||
width?: string;
|
||||
sortable?: boolean;
|
||||
}
|
||||
// 更新列
|
||||
const updateColumns = (arr: Array<ColumnItem>) => {
|
||||
columns.value = arr
|
||||
};
|
||||
|
||||
|
||||
// 右侧数据源
|
||||
const rightTableData = ref([])
|
||||
// 配置项
|
||||
const rightColumns = ref([
|
||||
{ prop: 'xmdh', label: '项目代号', align: 'center', visible: true, key: 0, },
|
||||
{ prop: 'xmmc', label: '项目名称', align: 'center', visible: true, key: 1 },
|
||||
{ prop: 'csjg', label: '结果', align: 'center', visible: true, key: 2 },
|
||||
{ prop: 'refs', label: '参考值', align: 'center', visible: true, key: 3 },
|
||||
{ prop: 'dw', label: '单位', align: 'center', visible: true, key: 4 },
|
||||
{ prop: 'jgbz', label: '结果标志', align: 'center', visible: true, key: 5 },
|
||||
])
|
||||
// 表格配置
|
||||
const rightTableConfig = ref(
|
||||
{
|
||||
// stripe: true, // 斑马纹
|
||||
// border: true, // 边框
|
||||
selection: false, // 多选框
|
||||
index: false, // 序号
|
||||
height: '28vh', // 高度
|
||||
highlightCurrentRow: true, // 高亮当前行
|
||||
}
|
||||
)
|
||||
const xmRow = ref<any>({})
|
||||
// 查询抗生素
|
||||
const xmrowHandle = (row: any) => {
|
||||
xmRow.value = row
|
||||
const data = {
|
||||
jyrq: Info.value.jyrq,
|
||||
yq: Info.value.yq,
|
||||
ybh: Info.value.ybh,
|
||||
xmdh: row.xmdh
|
||||
}
|
||||
reportMedList(data).then((res: any) => {
|
||||
if (res.code == 200) {
|
||||
bottomTableData.value = res.rows
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
const periods = ref<string[]>([])
|
||||
|
||||
const compareTableData = ref([])
|
||||
|
||||
const aaaa = () => {
|
||||
|
||||
}
|
||||
// 历史数据对比
|
||||
const openDB = () => {
|
||||
// 00507620
|
||||
compareTableData.value = []
|
||||
if (!xmRow.value.xmdh) return ElMessage.error('至少选择一条数据进行对比')
|
||||
const data = {
|
||||
brdh: Info.value.brdh,
|
||||
xmdh: xmRow.value.xmdh
|
||||
}
|
||||
reportFsresult(data).then((res: any) => {
|
||||
periods.value = []
|
||||
if (res.code == 0) {
|
||||
const arr: string[] = res.data.map((item: any) => item.confirmdt);
|
||||
periods.value = [...new Set(arr)];
|
||||
res.data.forEach((v: any) => {
|
||||
arr.forEach((item: any) => {
|
||||
if (item == v.confirmdt) {
|
||||
v[item] = v.csjg
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
// @ts-ignore 忽略重组数据动态时间key
|
||||
compareTableData.value = formatGroupedData(res.data)
|
||||
dialogVisible.value = true
|
||||
nextTick(() => {
|
||||
handleRowClick(compareTableData.value[0])
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
interface copyItem {
|
||||
xmdh: string;
|
||||
xmmc: string;
|
||||
csjg: string | number;
|
||||
refs: string | number;
|
||||
dw: string;
|
||||
jgbz: string;
|
||||
}
|
||||
// 复制函数
|
||||
const copyData = (type: string) => {
|
||||
let str = ''
|
||||
const getCommonRow = (item: copyItem) => `${item.xmdh}\t${item.xmmc}\t${item.csjg}\t${item.refs}\t${item.dw}\t${item.jgbz}\t\r\n`;
|
||||
rightTableData.value.forEach((v: any) => {
|
||||
if (type == 'All') {
|
||||
str = str + getCommonRow(v)
|
||||
str = str + v.xmmc + v.csjg + v.dw + + ',';
|
||||
}
|
||||
if (type == 'N' && v.jgbz != 'M' && v.jgbz != '') {
|
||||
str = str + getCommonRow(v)
|
||||
}
|
||||
if (type == 'Y' && v.jgbz == 'M' && v.jgbz != '') {
|
||||
str = str + getCommonRow(v)
|
||||
}
|
||||
})
|
||||
|
||||
var input = document.createElement('textarea');
|
||||
if (!str) return ElMessage.error('没有数据可复制');
|
||||
// 把文字放进input中,供复制
|
||||
input.value = str;
|
||||
document.body.appendChild(input);
|
||||
// 选中创建的input
|
||||
input.select();
|
||||
var copy_result = document.execCommand('copy');
|
||||
if (copy_result) {
|
||||
ElMessage.success('复制成功');
|
||||
} else {
|
||||
ElMessage.error('复制失败');
|
||||
}
|
||||
// 移除
|
||||
document.body.removeChild(input);
|
||||
}
|
||||
|
||||
// 数据重组
|
||||
const formatGroupedData = (data: any[]) => {
|
||||
if (!data || data.length === 0) return [];
|
||||
|
||||
const groupMap: any = {};
|
||||
data.forEach(item => {
|
||||
const key = item.xmdh;
|
||||
if (!groupMap[key]) {
|
||||
groupMap[key] = {
|
||||
xmdh: item.xmdh,
|
||||
xmmc: item.xmmc,
|
||||
// confirmdt: item.confirmdt
|
||||
};
|
||||
}
|
||||
const dateKeys = Object.keys(item).filter(key =>
|
||||
/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/.test(key) // 匹配 YYYY-MM-DD HH:mm:ss 时间格式
|
||||
);
|
||||
// 将日期键值对添加到分组对象
|
||||
dateKeys.forEach(dateKey => {
|
||||
groupMap[key][dateKey] = item[dateKey];
|
||||
});
|
||||
});
|
||||
// 将 Map 转为数组
|
||||
return Object.values(groupMap);
|
||||
};
|
||||
|
||||
const handleRowClick = (row: any) => {
|
||||
getEcharts(row)
|
||||
}
|
||||
|
||||
const getEcharts = (data: any) => {
|
||||
const dateKeys = Object.keys(data).filter(key =>
|
||||
/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/.test(key)
|
||||
);
|
||||
const Intance = echarts.init(myEcharts.value);
|
||||
const xData = dateKeys;
|
||||
let seriesData = []
|
||||
seriesData = dateKeys.map(item => data[item]);
|
||||
|
||||
const option = {
|
||||
title: {
|
||||
text: data.xmmc,
|
||||
top: '5',
|
||||
right: '5%',
|
||||
left: '20',
|
||||
// bottom: '20%'
|
||||
// subtext: 'Feature Sample: Gradient Color, Shadow, Click Zoom'
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis'
|
||||
},
|
||||
grid: {
|
||||
top: '20%',
|
||||
left: '3%',
|
||||
right: '4%',
|
||||
// bottom: '3%',
|
||||
height: '80%',
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: xData,
|
||||
axisTick: {
|
||||
show: false
|
||||
},
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
// color: 'rgba(193, 207, 220, 1)',
|
||||
}
|
||||
},
|
||||
axisLabel: {
|
||||
rotate: 30,
|
||||
textStyle: {
|
||||
color: "#8D949B "
|
||||
}
|
||||
},
|
||||
},
|
||||
yAxis: [{
|
||||
// name: '单位(mm)',
|
||||
type: 'value',
|
||||
axisLabel: {
|
||||
textStyle: {
|
||||
color: "#8D949B"
|
||||
},
|
||||
// formatter: '{value}%'
|
||||
|
||||
|
||||
},
|
||||
axisLine: {
|
||||
show: false,
|
||||
lineStyle: {
|
||||
color: '#24abf2'
|
||||
}
|
||||
},
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
type: 'dashed'
|
||||
},
|
||||
},
|
||||
}
|
||||
],
|
||||
series: [{
|
||||
name: data.xmmc,
|
||||
type: 'line',
|
||||
data: seriesData,
|
||||
symbol: 'circle',
|
||||
symbolSize: 5, //标记的大小
|
||||
lineStyle: {
|
||||
normal: {
|
||||
width: 2,
|
||||
color: '#24abf2',
|
||||
}
|
||||
},
|
||||
itemStyle: {
|
||||
normal: {
|
||||
color: '#24abf2',
|
||||
}
|
||||
},
|
||||
smooth: true
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
Intance.setOption(option);
|
||||
}
|
||||
|
||||
// 右侧数据源
|
||||
const bottomTableData = ref([])
|
||||
// 配置项
|
||||
const bottomColumns = ref([
|
||||
{ prop: 'ywdh', label: '抗生素编号', align: 'center', visible: true, key: 0 },
|
||||
{ prop: 'ywmc', label: '抗生素名称', align: 'center', visible: true, key: 1 },
|
||||
{ prop: 'csjg', label: '测试结果', align: 'center', visible: true, key: 2 },
|
||||
{ prop: 'jgbz', label: '结果标志', align: 'center', visible: true, key: 3 },
|
||||
])
|
||||
// 表格配置
|
||||
const bottomTableConfig = ref(
|
||||
{
|
||||
// stripe: true, // 斑马纹
|
||||
// border: true, // 边框
|
||||
selection: false, // 多选框
|
||||
index: false, // 序号
|
||||
height: '28vh', // 高度
|
||||
highlightCurrentRow: true, // 高亮当前行
|
||||
}
|
||||
)
|
||||
interface DictData {
|
||||
DP?: Array<any>;
|
||||
PT?: Array<any>;
|
||||
[key: string]: any[] | undefined; // 添加索引签名以支持动态访问
|
||||
}
|
||||
|
||||
|
||||
// 字典数据存储
|
||||
const dictData = ref<DictData>({});
|
||||
|
||||
onMounted(async () => {
|
||||
// 初始化3天区间(今天-前两天)
|
||||
// const end = dayjs().format('YYYY-MM-DD HH:mm:ss');
|
||||
// const start = dayjs().subtract(1, 'day').format('YYYY-MM-DD HH:mm:ss'); //add 时间往后
|
||||
// queryParams.times = [start, end];
|
||||
// console.log(queryParams.times);
|
||||
getList()
|
||||
adjustTableHeight();
|
||||
|
||||
// 加载病人来源字典
|
||||
const dictRefs = await comDict('PT', 'DP');
|
||||
|
||||
// 从 ref 中获取实际数据
|
||||
dictData.value = {
|
||||
PT: toRaw(dictRefs.PT.value) || [],
|
||||
DP: toRaw(dictRefs.DP.value) || [],
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
const getList = () => {
|
||||
const data = {
|
||||
alarmflag: alarmflag.value,
|
||||
jzbz: jzbz.value,
|
||||
dybz: queryParams.dybz,
|
||||
ksdh: queryParams.ksdh,
|
||||
brly: queryParams.brly,
|
||||
brxm: queryParams.brxm,
|
||||
brdh: queryParams.brdh,
|
||||
sqh: queryParams.sqh,
|
||||
st: '',
|
||||
et: '',
|
||||
yljg: 1
|
||||
}
|
||||
if (queryParams.times && queryParams.times.length) {
|
||||
data.st = queryParams.times[0]
|
||||
data.et = queryParams.times[1]
|
||||
}
|
||||
reportList(data).then((res: any) => {
|
||||
if (res.code == 0) {
|
||||
tableData.value = res.data
|
||||
tableRefs.value.setCurrentRow(res.data[0])
|
||||
rowHandle(res.data[0])
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 计算table高度
|
||||
watch(showSearch, () => {
|
||||
nextTick(() => {
|
||||
adjustTableHeight();
|
||||
})
|
||||
}, { immediate: true });
|
||||
|
||||
function adjustTableHeight() {
|
||||
if (compactForm.value) {
|
||||
// 获取高度
|
||||
heightForm.value = compactForm.value.offsetHeight;
|
||||
tableConfig.value.height = `calc(80vh - ${heightForm.value}px)`;
|
||||
rightTableConfig.value.height = `calc(38vh - ${heightForm.value}px)`;
|
||||
bottomTableConfig.value.height = `calc(35vh - ${heightForm.value} }px)`;
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.right-table {
|
||||
border: 1px solid #dcdfe6;
|
||||
}
|
||||
|
||||
.title {
|
||||
border-bottom: 1px solid #dcdfe6;
|
||||
margin-bottom: 10px;
|
||||
padding: 10px;
|
||||
font-weight: 700;
|
||||
}
|
||||
</style>
|
||||
@ -1,7 +1,8 @@
|
||||
<script setup>
|
||||
import { computed } from "vue";
|
||||
import { computed, reactive, ref, onMounted, nextTick } from "vue";
|
||||
import { getToken } from "@/utils/auth";
|
||||
import {queryComDictListService,addComDictService,updateComDictService} from "../../../api/liswork/dict/ComDict.js";
|
||||
import { queryComDictListService, addComDictService, updateComDictService, delComDictService } from "../../../api/liswork/dict/ComDict.js";
|
||||
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
|
||||
@ -20,6 +21,7 @@ const data = reactive({
|
||||
dictType: [{ required: true, message: "字典类型不能为空", trigger: "blur" }]
|
||||
},
|
||||
});
|
||||
|
||||
const { queryParams, form, rules } = toRefs(data);
|
||||
const single = ref(true);
|
||||
const multiple = ref(true);
|
||||
@ -50,8 +52,32 @@ const upload = reactive({
|
||||
// 上传的地址
|
||||
url: import.meta.env.VITE_APP_BASE_API + "/comdict/importData"
|
||||
});
|
||||
const treeRef = ref(null)
|
||||
const defaultProps = {
|
||||
children: 'children',
|
||||
label: 'zdmc',
|
||||
id: 'zddh'
|
||||
}
|
||||
|
||||
function resetData(zdlb){
|
||||
const info = ref({})
|
||||
watch(zdlbmc, (val) => {
|
||||
console.log(ref(treeRef.value));
|
||||
|
||||
treeRef.value?.filter(val)
|
||||
})
|
||||
|
||||
const filterNode = (value, data) => {
|
||||
if (!value) return true
|
||||
return data.zdmc.includes(value)
|
||||
}
|
||||
|
||||
const nodeHandle = (data) => {
|
||||
queryParams.value.pageNum = 1
|
||||
queryParams.value.zdlb = data.zddh;
|
||||
getList()
|
||||
// resetData(data.zdlb)
|
||||
}
|
||||
function resetData(zdlb) {
|
||||
queryParams.value = {
|
||||
pageNum: 1,
|
||||
pageSize: 15,
|
||||
@ -61,8 +87,7 @@ function resetData(zdlb){
|
||||
yljg: '1'
|
||||
}
|
||||
}
|
||||
|
||||
function getTypeList(){
|
||||
function getTypeList() {
|
||||
loading.value = true;
|
||||
queryParams.value.pageSize = 1000;
|
||||
queryParams.value.zdlb = '00'
|
||||
@ -71,14 +96,11 @@ function getTypeList(){
|
||||
total.value = response.total;
|
||||
loading.value = false;
|
||||
resetData()
|
||||
queryParams.value.zdlb = response.rows[1].zddh
|
||||
getList()
|
||||
});
|
||||
}
|
||||
|
||||
function refreshDetail(zdlb){
|
||||
queryParams.value.zdlb = zdlb;
|
||||
getList()
|
||||
resetData(zdlb)
|
||||
}
|
||||
|
||||
|
||||
/** 查询字典明细列表 */
|
||||
@ -93,7 +115,7 @@ function getList() {
|
||||
}
|
||||
|
||||
//查询
|
||||
function handleQuery(){
|
||||
function handleQuery() {
|
||||
queryParams.value.pageNum = 1;
|
||||
getList();
|
||||
}
|
||||
@ -109,18 +131,16 @@ function reset() {
|
||||
proxy.resetForm("dictRef");
|
||||
}
|
||||
//重置
|
||||
function resetQuery(){
|
||||
queryParams.value = {
|
||||
zdmc: '',
|
||||
zddh: ''
|
||||
}
|
||||
function resetQuery() {
|
||||
queryParams.value.zdmc = ''
|
||||
queryParams.value.zddh = ''
|
||||
proxy.resetForm("queryRef");
|
||||
handleQuery();
|
||||
}
|
||||
|
||||
//新增
|
||||
function handleAdd(){
|
||||
if(queryParams.value.zdlb === undefined || queryParams.value.zdlb === ''){
|
||||
function handleAdd() {
|
||||
if (queryParams.value.zdlb === undefined || queryParams.value.zdlb === '') {
|
||||
proxy.$modal.msgWarning("请先选择字典大类");
|
||||
return;
|
||||
}
|
||||
@ -130,13 +150,20 @@ function handleAdd(){
|
||||
}
|
||||
|
||||
//修改
|
||||
function handleUpdate(){
|
||||
|
||||
function handleUpdate(row) {
|
||||
reset()
|
||||
form.value = row.zdlb ? row : info.value
|
||||
open.value = true;
|
||||
}
|
||||
|
||||
//删除
|
||||
function handleDelete(){
|
||||
|
||||
function handleDelete(row) {
|
||||
proxy.$modal.confirm('是否确认删除字典名称为"' + row.zdmc + '"的数据项?').then(function () {
|
||||
return delComDictService(row);
|
||||
}).then(() => {
|
||||
getList();
|
||||
proxy.$modal.msgSuccess("删除成功");
|
||||
}).catch(() => { });
|
||||
}
|
||||
/** 导入按钮操作 */
|
||||
function handleImport() {
|
||||
@ -147,7 +174,7 @@ function handleImport() {
|
||||
function handleExport() {
|
||||
proxy.download("comdict/export", {
|
||||
...queryParams.value,
|
||||
},`user_${new Date().getTime()}.xlsx`);
|
||||
}, `user_${new Date().getTime()}.xlsx`);
|
||||
};
|
||||
/** 下载模板操作 */
|
||||
function importTemplate() {
|
||||
@ -173,12 +200,13 @@ const handleFileSuccess = (response, file, fileList) => {
|
||||
|
||||
|
||||
//多选框选中数据
|
||||
function handleSelectionChange(){
|
||||
|
||||
function handleSelectionChange(selection) {
|
||||
info.value = selection[0]
|
||||
single.value = selection.length != 1;
|
||||
}
|
||||
|
||||
//查询字典大类
|
||||
function handleQueryDetail(){
|
||||
function handleQueryDetail() {
|
||||
queryParams.value.zdmc = zdlbmc.value
|
||||
getTypeList()
|
||||
resetData()
|
||||
@ -189,182 +217,192 @@ function submitForm() {
|
||||
if (valid) {
|
||||
if (form.value.zdlb != undefined && form.value.zdlb != '') {
|
||||
updateComDictService(form.value).then(response => {
|
||||
proxy.$modal.msgSuccess("修改成功");
|
||||
open.value = false;
|
||||
getList();
|
||||
}).catch(error => {
|
||||
reset();
|
||||
});
|
||||
if (response.code == 0) {
|
||||
proxy.$modal.msgSuccess("修改成功");
|
||||
open.value = false;
|
||||
getList();
|
||||
}
|
||||
})
|
||||
} else {
|
||||
form.value.zdlb = queryParams.value.zdlb;
|
||||
form.value.yljg = 1;
|
||||
addComDictService(form.value).then(response => {
|
||||
proxy.$modal.msgSuccess("新增成功");
|
||||
open.value = false;
|
||||
getList();
|
||||
}).catch(error => {
|
||||
form.value.zdlb = '';
|
||||
});
|
||||
if (response.code == 0) {
|
||||
proxy.$modal.msgSuccess("新增成功");
|
||||
open.value = false;
|
||||
getList();
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 取消操作(保留这一份,删除后面重复的)
|
||||
function cancel() {
|
||||
open.value = false;
|
||||
reset();
|
||||
}
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
getTypeList()
|
||||
})
|
||||
|
||||
|
||||
getTypeList()
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="4" :xs="24">
|
||||
<div class="head-container">
|
||||
<el-input v-model="zdlbmc" clearable placeholder="请输入字典名称" prefix-icon="Search" style="margin-bottom: 20px" @keyup.enter="handleQueryDetail" @clear="handleQueryDetail" />
|
||||
</div>
|
||||
<div class="head-container">
|
||||
<div class="card-content">
|
||||
<p class="clickable" v-for="item in typeList" :key="item.zdlb" @click="refreshDetail(item.zddh)">{{ item.zdmc }}</p>
|
||||
<div class="app-container">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="4" :xs="24">
|
||||
<div class="head-container">
|
||||
<el-input v-model="zdlbmc" clearable placeholder="请输入字典名称" prefix-icon="Search" style="margin-bottom: 20px" />
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<p class="clickable" v-for="item in typeList" :key="item.zdlb" @click="refreshDetail(item.zddh)">{{ item.zdmc }}</p>
|
||||
<div class="head-container">
|
||||
<div class="card-content">
|
||||
<el-tree ref="treeRef" class="filter-tree" :data="typeList" :props="defaultProps" default-expand-all
|
||||
:filter-node-method="filterNode" @node-click="nodeHandle" highlight-current />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<!-- 字典明细-->
|
||||
<el-col :span="20" :xs="24">
|
||||
<!-- 表单区域-->
|
||||
<el-form :model="queryParams" ref="queryRef" :inline="true" label-width="68px">
|
||||
<el-form-item class="cus-el-form-item" label="名称" prop="dictName">
|
||||
<el-input v-model="queryParams.zdmc" placeholder="请输入名称" clearable style="width: 240px" @keyup.enter="handleQuery"/>
|
||||
</el-col>
|
||||
<!-- 字典明细-->
|
||||
<el-col :span="20" :xs="24">
|
||||
<!-- 表单区域-->
|
||||
<el-form :model="queryParams" ref="queryRef" :inline="true" label-width="68px">
|
||||
<el-form-item class="cus-el-form-item" label="名称" prop="dictName">
|
||||
<el-input v-model="queryParams.zdmc" placeholder="请输入名称" clearable style="width: 240px"
|
||||
@keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item class="cus-el-form-item" label="明细代号" prop="status">
|
||||
<el-input v-model="queryParams.zddh" placeholder="请输入明细代号" clearable style="width: 240px"
|
||||
@keyup.enter="handleQuery" />
|
||||
</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"
|
||||
v-hasPermi="['system:dict:add']">新增</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate"
|
||||
v-hasPermi="['system:dict:edit']">修改</el-button>
|
||||
</el-col>
|
||||
<!-- <el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete"
|
||||
v-hasPermi="['system:dict:remove']">删除</el-button>
|
||||
</el-col> -->
|
||||
<el-col :span="1.5">
|
||||
<el-button type="info" plain icon="Upload" @click="handleImport"
|
||||
v-hasPermi="['system:dict:import']">导入</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport"
|
||||
v-hasPermi="['system:dict:export']">导出</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<!-- 表格区域-->
|
||||
<el-table v-loading="loading" :data="typeDetail" @selection-change="handleSelectionChange" height="65vh">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label='字典类型' align="center" prop="zdlb" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="明细代号" align="center" prop="zddh" />
|
||||
<el-table-column label="名称" align="center" prop="zdmc" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="备注" align="center" prop="bz" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="操作" align="center" width="160" class-name="small-padding fixed-width">
|
||||
<template #default="{ row }">
|
||||
<el-button link type="primary" icon="Edit" @click="handleUpdate(row)"
|
||||
v-hasPermi="['system:dict:edit']">修改</el-button>
|
||||
<el-button link type="primary" icon="Delete" @click="handleDelete(row)"
|
||||
v-hasPermi="['system:dict:remove']">删除</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-col>
|
||||
</el-row>
|
||||
|
||||
<!-- 添加或修改参数配置对话框 -->
|
||||
<el-dialog :title="title" v-model="open" width="500px" append-to-body>
|
||||
<el-form ref="dictRef" :model="form" :rules="rules" label-width="80px">
|
||||
<el-form-item label="字典类别" prop="zdlb">
|
||||
<el-input v-model="form.zdlb" disabled></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item class="cus-el-form-item" label="明细代号" prop="status">
|
||||
<el-input v-model="queryParams.zddh" placeholder="请输入明细代号" clearable style="width: 240px" @keyup.enter="handleQuery"/>
|
||||
<el-form-item label="字典代号" prop="zddh">
|
||||
<el-input v-model="form.zddh" placeholder="请输入字典代号" />
|
||||
</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 label="字典名称" prop="zdmc">
|
||||
<el-input v-model="form.zdmc" placeholder="请输入字典名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="bz">
|
||||
<el-input v-model="form.bz" placeholder="请输入内容"></el-input>
|
||||
</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" v-hasPermi="['system:dict:add']">新增</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate" v-hasPermi="['system:dict:edit']">修改</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete" v-hasPermi="['system:dict:remove']">删除</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="info" plain icon="Upload" @click="handleImport" v-hasPermi="['system:dict:import']">导入</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['system:dict:export']">导出</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<!-- 表格区域-->
|
||||
<el-table v-loading="loading" :data="typeDetail" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label='字典类型' align="center" prop="zdlb" :show-overflow-tooltip="true"/>
|
||||
<el-table-column label="明细代号" align="center" prop="zddh" />
|
||||
<el-table-column label="名称" align="center" prop="zdmc" :show-overflow-tooltip="true"/>
|
||||
<el-table-column label="备注" align="center" prop="remark" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="操作" align="center" width="160" class-name="small-padding fixed-width">
|
||||
<template #default="{row}">
|
||||
<el-button link type="primary" icon="Edit" @click="handleUpdate(row)" v-hasPermi="['system:dict:edit']">修改</el-button>
|
||||
<el-button link type="primary" icon="Delete" @click="handleDelete(row)" v-hasPermi="['system:dict:remove']">删除</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-col>
|
||||
</el-row>
|
||||
|
||||
<!-- 添加或修改参数配置对话框 -->
|
||||
<el-dialog :title="title" v-model="open" width="500px" append-to-body>
|
||||
<el-form ref="dictRef" :model="form" :rules="rules" label-width="80px">
|
||||
<el-form-item label="字典类别" prop="zdlb">
|
||||
<el-input v-model="form.zdlb" disabled></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="字典代号" prop="zddh">
|
||||
<el-input v-model="form.zddh" placeholder="请输入字典代号" />
|
||||
</el-form-item>
|
||||
<el-form-item label="字典名称" prop="zdmc">
|
||||
<el-input v-model="form.zdmc" placeholder="请输入字典名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="bz">
|
||||
<el-input v-model="form.bz" placeholder="请输入内容"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<!-- 用户导入对话框 -->
|
||||
<el-dialog :title="upload.title" v-model="upload.open" width="400px" append-to-body>
|
||||
<el-upload
|
||||
ref="uploadRef"
|
||||
:limit="1"
|
||||
accept=".xlsx, .xls"
|
||||
:headers="upload.headers"
|
||||
:action="upload.url + '?updateSupport=' + upload.updateSupport"
|
||||
:disabled="upload.isUploading"
|
||||
:on-progress="handleFileUploadProgress"
|
||||
:on-success="handleFileSuccess"
|
||||
:auto-upload="false"
|
||||
drag
|
||||
>
|
||||
<el-icon class="el-icon--upload"><upload-filled /></el-icon>
|
||||
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
|
||||
<template #tip>
|
||||
<div class="el-upload__tip text-center">
|
||||
<div class="el-upload__tip">
|
||||
<el-checkbox v-model="upload.updateSupport" />是否覆盖已经存在的字典数据
|
||||
</div>
|
||||
<span>仅允许导入xls、xlsx格式文件。</span>
|
||||
<el-link type="primary" :underline="false" style="font-size:12px;vertical-align: baseline;" @click="importTemplate">下载模板</el-link>
|
||||
</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button type="primary" @click="submitFileForm">确 定</el-button>
|
||||
<el-button @click="upload.open = false">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</el-dialog>
|
||||
<!-- 用户导入对话框 -->
|
||||
<el-dialog :title="upload.title" v-model="upload.open" width="400px" append-to-body>
|
||||
<el-upload ref="uploadRef" :limit="1" accept=".xlsx, .xls" :headers="upload.headers"
|
||||
:action="upload.url + '?updateSupport=' + upload.updateSupport" :disabled="upload.isUploading"
|
||||
:on-progress="handleFileUploadProgress" :on-success="handleFileSuccess" :auto-upload="false" drag>
|
||||
<el-icon class="el-icon--upload"><upload-filled /></el-icon>
|
||||
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
|
||||
<template #tip>
|
||||
<div class="el-upload__tip text-center">
|
||||
<div class="el-upload__tip">
|
||||
<el-checkbox v-model="upload.updateSupport" />是否覆盖已经存在的字典数据
|
||||
</div>
|
||||
<span>仅允许导入xls、xlsx格式文件。</span>
|
||||
<el-link type="primary" :underline="false" style="font-size:12px;vertical-align: baseline;"
|
||||
@click="importTemplate">下载模板</el-link>
|
||||
</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button type="primary" @click="submitFileForm">确 定</el-button>
|
||||
<el-button @click="upload.open = false">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
.card-content {
|
||||
.card-content { /* 错误:嵌套了同名类,导致样式不生效 */
|
||||
.card-content {
|
||||
max-height: 450px;
|
||||
/* 设置最大高度 */
|
||||
overflow-y: auto;
|
||||
/* 超出高度时显示垂直滚动条 */
|
||||
padding: 16px;
|
||||
/* 保持与卡片默认一致的内边距 */
|
||||
}
|
||||
.clickable:hover {
|
||||
cursor: pointer; /* 鼠标悬停时显示手型 */
|
||||
transition: all 0.3s; /* 平滑过渡效果 */
|
||||
color: blue;
|
||||
|
||||
}}
|
||||
|
||||
.clickable:hover {
|
||||
cursor: pointer;
|
||||
/* 鼠标悬停时显示手型 */
|
||||
transition: all 0.3s;
|
||||
/* 平滑过渡效果 */
|
||||
color: blue;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.filter-tree {
|
||||
max-height: 70vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
</style>
|
||||
646
src/views/mzcx/blood/index.vue
Normal file
646
src/views/mzcx/blood/index.vue
Normal file
@ -0,0 +1,646 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<div class="table-header">
|
||||
|
||||
<el-button type="primary" @click="handleQuery" class="add-btn"> 查询 </el-button>
|
||||
<el-button type="primary" @click="addNewItem" class="add-btn"> 新增 </el-button>
|
||||
<el-button type="success" @click="save" class="add-btn"> 保存 </el-button>
|
||||
|
||||
</div>
|
||||
<el-table :data="tableData" border style="width: 100%" @cell-click="handleCellClick"
|
||||
:cell-class-name="cellClassName" :row-key="(row: any) => row.id" height="calc(100vh - 260px)"
|
||||
highlight-current-row ref="tableRef">
|
||||
<!-- 分单类别代号 -->
|
||||
<el-table-column prop="sflbdh" label="分单类别代号" width="110">
|
||||
<template #default="scope">
|
||||
<template v-if="isEditing(scope.row, 'sflbdh')">
|
||||
<el-input v-model="scope.row.sflbdh" size="small" @blur="handleSave(scope.row, 'sflbdh')"
|
||||
@keyup.enter="handleSave(scope.row, 'sflbdh')" auto-focus :ref="getInputRef(scope.row.id, 'sflbdh')" />
|
||||
</template>
|
||||
<template v-else>
|
||||
<span @click.stop="handleCellClick(scope.row, { property: 'sflbdh' })">
|
||||
{{ scope.row.sflbdh }}
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 类别名称 -->
|
||||
<el-table-column prop="sflbmc" label="类别名称" width="150">
|
||||
<template #default="scope">
|
||||
<template v-if="isEditing(scope.row, 'sflbmc')">
|
||||
<el-input v-model="scope.row.sflbmc" size="small" @blur="handleSave(scope.row, 'sflbmc')"
|
||||
@keyup.enter="handleSave(scope.row, 'sflbmc')" auto-focus :ref="getInputRef(scope.row.id, 'sflbmc')" />
|
||||
</template>
|
||||
<template v-else>
|
||||
<span @click.stop="handleCellClick(scope.row, { property: 'sflbmc' })">
|
||||
{{ scope.row.sflbmc }}
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 类别简称 -->
|
||||
<el-table-column prop="sflbjc" label="类别简称" width="120">
|
||||
<template #default="scope">
|
||||
<template v-if="isEditing(scope.row, 'sflbjc')">
|
||||
<el-input v-model="scope.row.sflbjc" size="small" @blur="handleSave(scope.row, 'sflbjc')"
|
||||
@keyup.enter="handleSave(scope.row, 'sflbjc')" auto-focus :ref="getInputRef(scope.row.id, 'sflbjc')" />
|
||||
</template>
|
||||
<template v-else>
|
||||
<span @click.stop="handleCellClick(scope.row, { property: 'sflbjc' })">
|
||||
{{ scope.row.sflbjc }}
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 条码类别 -->
|
||||
<el-table-column prop="txmlb" label="条码类别" width="110">
|
||||
<template #default="scope">
|
||||
<template v-if="isEditing(scope.row, 'txmlb')">
|
||||
<el-input v-model="scope.row.txmlb" size="small" @blur="handleSave(scope.row, 'txmlb')"
|
||||
@keyup.enter="handleSave(scope.row, 'txmlb')" auto-focus :ref="getInputRef(scope.row.id, 'txmlb')" />
|
||||
</template>
|
||||
<template v-else>
|
||||
<span @click.stop="handleCellClick(scope.row, { property: 'txmlb' })">
|
||||
{{ scope.row.txmlb }}
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 标本类型 -->
|
||||
<el-table-column prop="yblx" label="标本类型" width="140">
|
||||
<template #default="scope">
|
||||
<template v-if="isEditing(scope.row, 'yblx')">
|
||||
<el-select v-model="scope.row.yblx" size="small" @change="handleSave(scope.row, 'yblx')"
|
||||
@blur="handleSave(scope.row, 'yblx')" auto-focus filterable>
|
||||
<el-option v-for="item in dictData.BT" :key="item.label" :label="item.label" :value="item.label" />
|
||||
</el-select>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span @click.stop="handleCellClick(scope.row, { property: 'yblx' })">
|
||||
{{ scope.row.yblx }}
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 标本采集说明 -->
|
||||
<el-table-column prop="sampletips" label="标本采集说明" width="220">
|
||||
<template #default="scope">
|
||||
<template v-if="isEditing(scope.row, 'sampletips')">
|
||||
<el-input v-model="scope.row.sampletips" size="small" @blur="handleSave(scope.row, 'sampletips')"
|
||||
@keyup.enter.ctrl="handleSave(scope.row, 'sampletips')" auto-focus
|
||||
:ref="getInputRef(scope.row.id, 'sampletips')" />
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="multi-line-text" @click.stop="handleCellClick(scope.row, { property: 'sampletips' })">
|
||||
{{ scope.row.sampletips }}
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 报告领取规则 -->
|
||||
<el-table-column prop="bglqdh" label="报告领取规则" width="160">
|
||||
<template #default="scope">
|
||||
<template v-if="isEditing(scope.row, 'bglqdh')">
|
||||
<el-select v-model="scope.row.bglqdh" size="small" @change="handleSave(scope.row, 'bglqdh')" filterable
|
||||
@blur="handleSave(scope.row, 'bglqdh')" auto-focus>
|
||||
<el-option v-for="item in reportRuleOptions" :key="item.bglqdh" :label="item.bglqmc"
|
||||
:value="item.bglqdh" />
|
||||
</el-select>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span @click.stop="handleCellClick(scope.row, { property: 'bglqdh' })">
|
||||
{{ getOptionLabel(reportRuleOptions, scope.row.bglqdh) }}
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 打印份数 -->
|
||||
<el-table-column prop="printcnt" label="打印份数" width="120" align="center">
|
||||
<template #default="scope">
|
||||
<template v-if="isEditing(scope.row, 'printcnt')">
|
||||
<el-input-number v-model="scope.row.printcnt" :min="1" :max="9" size="small"
|
||||
@blur="handleSave(scope.row, 'printcnt')" @keyup.enter="handleSave(scope.row, 'printcnt')" auto-focus
|
||||
:ref="getInputRef(scope.row.id, 'printcnt')" />
|
||||
</template>
|
||||
<template v-else>
|
||||
<span @click.stop="handleCellClick(scope.row, { property: 'printcnt' })">
|
||||
{{ scope.row.printcnt }}
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 专业组(样本数) -->
|
||||
<el-table-column prop="lisgroup1" label="专业组(样本数)" width="140" align="center">
|
||||
<template #default="scope">
|
||||
<template v-if="isEditing(scope.row, 'lisgroup1')">
|
||||
<el-select v-model="scope.row.lisgroup1" size="small" @change="handleSave(scope.row, 'lisgroup1')"
|
||||
@blur="handleSave(scope.row, 'lisgroup1')" auto-focus filterable>
|
||||
<el-option v-for="item in dictData.LISGROUP1" :key="item.label" :label="item.label" :value="item.label" />
|
||||
</el-select>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span @click.stop="handleCellClick(scope.row, { property: 'lisgroup1' })">
|
||||
{{ scope.row.lisgroup1 }}
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 专业组(周转时间) -->
|
||||
<el-table-column prop="lisgroup2" label="专业组(周转时间)" width="160" align="center">
|
||||
<template #default="scope">
|
||||
<template v-if="isEditing(scope.row, 'lisgroup2')">
|
||||
<el-select v-model="scope.row.lisgroup2" size="small" @change="handleSave(scope.row, 'lisgroup2')"
|
||||
@blur="handleSave(scope.row, 'lisgroup2')" auto-focus filterable>
|
||||
<el-option v-for="item in dictData.LISGROUP2" :key="item.label" :label="item.label" :value="item.label" />
|
||||
</el-select>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span @click.stop="handleCellClick(scope.row, { property: 'lisgroup2' })">
|
||||
{{ scope.row.lisgroup2 }}
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 抗凝 -->
|
||||
<el-table-column prop="kn" label="抗凝" width="100" align="center">
|
||||
<template #default="scope">
|
||||
<el-checkbox v-model="scope.row.kn" :true-value="'1'" :false-value="'0'"
|
||||
@change="handleSave(scope.row, 'kn')" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 血培 -->
|
||||
<el-table-column prop="xpy" label="血培" width="100" align="center">
|
||||
<template #default="scope">
|
||||
<el-checkbox v-model="scope.row.xpy" :true-value="'1'" :false-value="'0'"
|
||||
@change="handleSave(scope.row, 'xpy')" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 标识颜色 -->
|
||||
<el-table-column prop="bkcolor" label="标识颜色" width="140" align="center">
|
||||
<template #default="scope">
|
||||
<template v-if="isEditing(scope.row, 'bkcolor')">
|
||||
<el-color-picker v-model="scope.row.bkcolor" size="small" @change="handleSave(scope.row, 'bkcolor')"
|
||||
@blur="handleSave(scope.row, 'bkcolor')" auto-focus />
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="color-display" @click.stop="handleCellClick(scope.row, { property: 'bkcolor' })">
|
||||
<span class="color-block" :style="{ backgroundColor: scope.row.bkcolor }" />
|
||||
<span class="color-code">{{ scope.row.bkcolor }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!-- 操作列 -->
|
||||
<el-table-column label="操作" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button size="small" type="danger" @click="handleDelete(scope.row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination :total="total" v-model:page="pageNum" v-model:limit="pageSize" @pagination="getList" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, nextTick, onMounted, toRaw, computed } from 'vue';
|
||||
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||
import { feeitemclassList, rptgetrules, feeitemclassAdd, feeitemclassUpdate, feeitemclassDel } from '@/api/mzcx/index';
|
||||
import { classCom } from '@/utils/classCom';
|
||||
// @ts-ignore
|
||||
import { comDict } from '@/utils/dict'
|
||||
const pageNum = ref(1);
|
||||
const pageSize = ref(10);
|
||||
const total = ref(0);
|
||||
|
||||
|
||||
const reportRuleOptions = ref<{ bglqdh: string, bglqmc: string, bz: string }[]>([]);
|
||||
|
||||
interface tableDataItem {
|
||||
id: string,
|
||||
sflbdh: string,
|
||||
sflbmc: string,
|
||||
sflbjc: string,
|
||||
txmlb: string,
|
||||
yblx: string,
|
||||
sampletips: string,
|
||||
bglqdh: number,
|
||||
printcnt: number,
|
||||
lisgroup1: string,
|
||||
lisgroup2: string,
|
||||
kn: string,
|
||||
xpy: string,
|
||||
bkcolor: string,
|
||||
originalData: object,
|
||||
flag: boolean,
|
||||
status: boolean
|
||||
}
|
||||
// 表格数据
|
||||
const tableData = ref<tableDataItem[]>([]);
|
||||
|
||||
const inputRefs = ref<Record<string, any>>({});
|
||||
// 表格引用
|
||||
const tableRef = ref(null);
|
||||
|
||||
const editingState = ref({ rowId: '', field: '' });
|
||||
|
||||
// 设置输入框引用
|
||||
const getInputRef = (rowId: string, field: string) => {
|
||||
return (el: any) => {
|
||||
if (el) {
|
||||
inputRefs.value[`${rowId}-${field}`] = el;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// 判断是否处于编辑状态
|
||||
const isEditing = (row: any, field: string) => {
|
||||
return editingState.value && editingState.value.rowId === row.id && editingState.value.field === field;
|
||||
};
|
||||
|
||||
// 获取选项标签
|
||||
const getOptionLabel = (options: any, value: string) => {
|
||||
const option = options.find((item: any) => item.bglqdh === value);
|
||||
return option ? option.bglqmc : '';
|
||||
};
|
||||
|
||||
// 处理单元格点击 - 核心修复部分
|
||||
const handleCellClick = (row: any, column: any) => {
|
||||
// 忽略操作列
|
||||
if (column.label === '操作') return;
|
||||
|
||||
const field = column.property;
|
||||
|
||||
// 如果点击的是当前编辑的单元格,不重复处理
|
||||
if (isEditing(row, field)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 保存之前编辑的内容
|
||||
if (editingState.value) {
|
||||
const prevRow = tableData.value.find((r: any) => r.id === editingState.value.rowId);
|
||||
if (prevRow) {
|
||||
handleSave(prevRow, editingState.value.field);
|
||||
}
|
||||
}
|
||||
|
||||
// 保存原始值用于恢复
|
||||
row.originalData[field] = JSON.parse(JSON.stringify(row[field]));
|
||||
|
||||
// 设置当前编辑状态
|
||||
editingState.value = {
|
||||
rowId: row.id,
|
||||
field: field
|
||||
};
|
||||
|
||||
// 强制刷新UI后聚焦
|
||||
nextTick(() => {
|
||||
const inputKey = `${row.id}-${field}`;
|
||||
const inputComponent = inputRefs.value[inputKey];
|
||||
if (!inputComponent) return;
|
||||
|
||||
// 不同组件的聚焦方式不同,做适配处理
|
||||
if (inputComponent.focus) {
|
||||
// 基础输入组件直接调用focus方法
|
||||
inputComponent.focus();
|
||||
} else if (inputComponent.$el) {
|
||||
// 查找内部输入元素
|
||||
const inputEl = inputComponent.$el.querySelector('input, textarea') ||
|
||||
inputComponent.$el.querySelector('.el-select__input') ||
|
||||
inputComponent.$el;
|
||||
inputEl?.focus?.();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 保存编辑
|
||||
const handleSave = (row: any, field: string) => {
|
||||
// 非编辑状态不处理
|
||||
if (!isEditing(row, field)) return;
|
||||
|
||||
let isValid = true;
|
||||
let errorMessage = '';
|
||||
|
||||
// 字段验证
|
||||
switch (field) {
|
||||
case 'sflbdh':
|
||||
if (!row[field]?.trim()) {
|
||||
isValid = false;
|
||||
errorMessage = '分单类别代号不能为空';
|
||||
} else {
|
||||
// 验证重复(排除当前行自身)
|
||||
const isDuplicate = tableData.value.some((item: any) => {
|
||||
return item.sflbdh === row.sflbdh && item.id !== row.id;
|
||||
});
|
||||
if (isDuplicate) {
|
||||
isValid = false;
|
||||
errorMessage = '分单类别代号已存在';
|
||||
}
|
||||
}
|
||||
break;
|
||||
// case 'sflbmc':
|
||||
// if (!row[field]?.trim()) {
|
||||
// isValid = false;
|
||||
// errorMessage = '类别名称不能为空';
|
||||
// }
|
||||
// break;
|
||||
// case 'sflbjc':
|
||||
// if (!row[field]?.trim()) {
|
||||
// isValid = false;
|
||||
// errorMessage = '类别简称不能为空';
|
||||
// }
|
||||
// break;
|
||||
case 'printcnt':
|
||||
if (row[field] < 1) {
|
||||
isValid = false;
|
||||
errorMessage = '数值必须大于0';
|
||||
}
|
||||
break;
|
||||
|
||||
case 'bkcolor':
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 验证失败处理
|
||||
if (!isValid) {
|
||||
row[field] = row.originalData[field];
|
||||
ElMessage.error(errorMessage);
|
||||
// 保持编辑状态以便修正
|
||||
return;
|
||||
}
|
||||
|
||||
// 对比原始数据判断是否有变化
|
||||
if (!row.status) {
|
||||
row.status = JSON.stringify(row[field]) !== JSON.stringify(row.originalData[field]);
|
||||
}
|
||||
|
||||
|
||||
// 清除编辑状态
|
||||
editingState.value = { rowId: '', field: '' };
|
||||
console.log('originalData==>', row);
|
||||
};
|
||||
|
||||
interface OperateLists {
|
||||
addList: any[];
|
||||
updateList: any[];
|
||||
}
|
||||
// 保存
|
||||
const save = () => {
|
||||
const { addList, updateList } = tableData.value.reduce<OperateLists>((acc, item) => {
|
||||
const { originalData, id, status, flag, bkcolor, ...restData } = item;
|
||||
const submitData = { ...restData, bkcolor: classCom.convertHexToNumber(bkcolor) };
|
||||
if (status) {
|
||||
flag ? acc.addList.push(submitData) : acc.updateList.push(submitData);
|
||||
}
|
||||
return acc;
|
||||
}, { addList: [], updateList: [] });
|
||||
|
||||
console.log('新增列表:', addList);
|
||||
console.log('更新列表:', updateList);
|
||||
if (addList.length > 0) {
|
||||
feeitemclassAdd(addList).then((res: any) => {
|
||||
if (res.code == 0) {
|
||||
ElMessage.success(res.msg);
|
||||
getList()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if (updateList.length > 0) {
|
||||
feeitemclassUpdate(updateList).then((res: any) => {
|
||||
if (res.code == 0) {
|
||||
ElMessage.success(res.msg);
|
||||
getList()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
// 单元格样式
|
||||
const cellClassName = ({ row, column }: { row: any, column: any }) => {
|
||||
return isEditing(row, column.property)
|
||||
? 'cell-editing'
|
||||
: 'cell-editable';
|
||||
};
|
||||
|
||||
// 新增项
|
||||
const addNewItem = () => {
|
||||
const newId = Array.from({ length: 4 }, () => Math.floor(Math.random() * 10)).join('');
|
||||
tableData.value.unshift({
|
||||
id: newId,
|
||||
sflbdh: `NEW${newId}`,
|
||||
sflbmc: 'test',
|
||||
sflbjc: '',
|
||||
txmlb: '',
|
||||
yblx: '',
|
||||
sampletips: '',
|
||||
bglqdh: 1,
|
||||
printcnt: 1,
|
||||
lisgroup1: '',
|
||||
lisgroup2: '',
|
||||
kn: '0',
|
||||
xpy: '0',
|
||||
bkcolor: '#FFFFFF',
|
||||
originalData: {},
|
||||
flag: true,
|
||||
status: true
|
||||
});
|
||||
// ElMessage.info('已添加新类别,请完善信息');
|
||||
};
|
||||
// 删除项
|
||||
const handleDelete = (row: any) => {
|
||||
ElMessageBox.confirm(
|
||||
`确定删除该${row.sflbdh}吗?`, "提示",
|
||||
{
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
}
|
||||
)
|
||||
.then(() => {
|
||||
feeitemclassDel({ sflbdh: row.sflbdh }).then((res: any) => {
|
||||
if (res.code == 0) {
|
||||
getList()
|
||||
ElMessage.success('删除成功');
|
||||
}
|
||||
})
|
||||
})
|
||||
.catch(() => {
|
||||
|
||||
})
|
||||
|
||||
|
||||
};
|
||||
const handleQuery = () => {
|
||||
pageNum.value = 1
|
||||
getList()
|
||||
}
|
||||
|
||||
|
||||
const getList = () => {
|
||||
feeitemclassList({ pageSize: pageSize.value, pageNum: pageNum.value }).then((res: any) => {
|
||||
if (res.code == 200) {
|
||||
tableData.value = res.rows
|
||||
total.value = res.total
|
||||
tableData.value.forEach((item: any) => {
|
||||
item.originalData = {}
|
||||
item.id = item.sflbdh
|
||||
item.status = false
|
||||
item.bkcolor = classCom.decimalToHexColor(item.bkcolor)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const getRules = () => {
|
||||
rptgetrules().then((res: any) => {
|
||||
reportRuleOptions.value = res.data
|
||||
})
|
||||
}
|
||||
getList()
|
||||
getRules()
|
||||
|
||||
interface DictData {
|
||||
BT?: Array<any>;
|
||||
LISGROUP1?: Array<any>;
|
||||
LISGROUP2?: Array<any>;
|
||||
[key: string]: any[] | undefined; // 添加索引签名以支持动态访问
|
||||
}
|
||||
|
||||
|
||||
// 字典数据存储
|
||||
const dictData = ref<DictData>({});
|
||||
onMounted(async () => {
|
||||
// 加载病人来源字典
|
||||
const dictRefs = await comDict('BT', 'LISGROUP1', 'LISGROUP2');
|
||||
|
||||
// 从 ref 中获取实际数据
|
||||
dictData.value = {
|
||||
BT: toRaw(dictRefs.BT.value) || [],
|
||||
LISGROUP1: toRaw(dictRefs.LISGROUP1.value) || [],
|
||||
LISGROUP2: toRaw(dictRefs.LISGROUP2.value) || [],
|
||||
};
|
||||
})
|
||||
|
||||
|
||||
|
||||
// 字典格式化方法
|
||||
const formatDict = (v: string, dictType: string) => {
|
||||
return dictData.value[dictType]?.find((item: any) => item.value == v)?.label;
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 保持与之前相同的样式 */
|
||||
.editable-table-wrapper {
|
||||
padding: 20px;
|
||||
max-width: 1800px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.table-header {
|
||||
/* display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center; */
|
||||
margin-bottom: 15px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
.table-header h3 {
|
||||
margin: 0;
|
||||
color: #333;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.add-btn {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.table-desc {
|
||||
margin-top: 15px;
|
||||
padding: 10px 15px;
|
||||
background-color: #f5f7fa;
|
||||
border-radius: 4px;
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
/* 单元格样式优化 */
|
||||
::v-deep .cell-editable {
|
||||
cursor: pointer;
|
||||
transition: background-color 0.2s;
|
||||
}
|
||||
|
||||
::v-deep .cell-editable:hover {
|
||||
background-color: #f0f7ff !important;
|
||||
}
|
||||
|
||||
::v-deep .cell-editing {
|
||||
background-color: #e6f7ff !important;
|
||||
}
|
||||
|
||||
::v-deep .el-table .el-table__cell {
|
||||
padding: 6px 0;
|
||||
}
|
||||
|
||||
/* 输入控件样式 */
|
||||
::v-deep .el-input,
|
||||
::v-deep .el-input-number,
|
||||
::v-deep .el-select,
|
||||
::v-deep .el-color-picker,
|
||||
::v-deep .el-textarea {
|
||||
width: 90%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
::v-deep .el-textarea__inner {
|
||||
min-height: 60px;
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
/* 多行文本和颜色显示样式 */
|
||||
.multi-line-text {
|
||||
white-space: pre-wrap;
|
||||
word-break: break-all;
|
||||
line-height: 1.4;
|
||||
padding: 0 5px;
|
||||
}
|
||||
|
||||
.color-display {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.color-block {
|
||||
display: inline-block;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 3px;
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.color-code {
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
max-width: 80px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
</style>
|
||||
168
src/views/mzcx/category/index.vue
Normal file
168
src/views/mzcx/category/index.vue
Normal file
@ -0,0 +1,168 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<!-- 左侧表格 -->
|
||||
<div style="flex:1">
|
||||
<el-input v-model="leftSearchValue" placeholder="请输入类别名称或代号" />
|
||||
<el-table :data="filteredLeftTableData" @row-click="handleLeftRowClick" highlight-current-row
|
||||
:cell-style="cellStyle" height="80vh">
|
||||
<el-table-column prop="sflbdh" label="分单类别代号" width="110" />
|
||||
<el-table-column prop="sflbmc" label="类别名称" />
|
||||
</el-table>
|
||||
</div>
|
||||
|
||||
<!-- 中间表格 -->
|
||||
<div style="flex:2">
|
||||
<el-input v-model="middleSearchValue" placeholder="请输入项目名称或代号" />
|
||||
<el-table :data="filteredMiddleTableData" @row-dblclick="handleMiddleRowDblClick" height="80vh">
|
||||
<el-table-column prop="sfxmdh" label="项目代号" />
|
||||
<el-table-column prop="sfxmmc" label="当前类别包含门诊项目" />
|
||||
</el-table>
|
||||
</div>
|
||||
|
||||
<!-- 右侧表格 -->
|
||||
<div style="flex:3">
|
||||
<el-input v-model="rightSearchValue" placeholder="请输入项目名称、代号或助记符" />
|
||||
<el-table :data="filteredRightTableData" @row-dblclick="handleRightRowDblClick" height="80vh">
|
||||
<el-table-column prop="sfxmdh" label="门诊项目代号" />
|
||||
<el-table-column prop="sfxmmc" label="门诊项目名称" />
|
||||
<el-table-column prop="zjf" label="助记符" />
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue';
|
||||
import { feeitemclassList, feeitemvsList, feeitemvAdd, feeitemvDel } from '@/api/mzcx/index';
|
||||
import { classCom } from '@/utils/classCom';
|
||||
|
||||
interface FeeItem {
|
||||
sfxmdh: string;
|
||||
sfxmmc: string;
|
||||
zjf?: string;
|
||||
xh?: number;
|
||||
sflbdh?: string;
|
||||
}
|
||||
|
||||
const leftSearchValue = ref('');
|
||||
const middleSearchValue = ref('');
|
||||
const rightSearchValue = ref('');
|
||||
|
||||
const leftTableData = ref<Array<{ sflbdh: string; sflbmc: string }>>([]);
|
||||
const middleTableData = ref<FeeItem[]>([]);
|
||||
const rightTableData = ref<FeeItem[]>([]);
|
||||
const sflbdhData = ref<{ sflbdh?: string; sflbmc?: string }>({});
|
||||
|
||||
// 过滤后的数据
|
||||
const filteredLeftTableData = computed(() => {
|
||||
const searchVal = leftSearchValue.value.toLowerCase().trim();
|
||||
if (!searchVal) return leftTableData.value;
|
||||
|
||||
return leftTableData.value.filter(item =>
|
||||
item.sflbdh.toLowerCase().includes(searchVal) ||
|
||||
item.sflbmc.toLowerCase().includes(searchVal)
|
||||
);
|
||||
});
|
||||
|
||||
const filteredMiddleTableData = computed(() => {
|
||||
const searchVal = middleSearchValue.value.toLowerCase().trim();
|
||||
if (!searchVal) return middleTableData.value;
|
||||
|
||||
return middleTableData.value.filter(item =>
|
||||
item.sfxmdh.toLowerCase().includes(searchVal) ||
|
||||
item.sfxmmc.toLowerCase().includes(searchVal)
|
||||
);
|
||||
});
|
||||
|
||||
const filteredRightTableData = computed(() => {
|
||||
const searchVal = rightSearchValue.value.toLowerCase().trim();
|
||||
if (!searchVal) return rightTableData.value;
|
||||
|
||||
return rightTableData.value.filter(item =>
|
||||
item.sfxmdh.toLowerCase().includes(searchVal) ||
|
||||
item.sfxmmc.toLowerCase().includes(searchVal) ||
|
||||
(item.zjf && item.zjf.toLowerCase().includes(searchVal))
|
||||
);
|
||||
});
|
||||
|
||||
// 左侧表格行点击事件
|
||||
const handleLeftRowClick = (row: any) => {
|
||||
sflbdhData.value = row;
|
||||
feeitemvsList({ sflbdh: sflbdhData.value.sflbdh }).then((res: any) => {
|
||||
middleTableData.value = res.data.labFeeitemVsClassList;
|
||||
rightTableData.value = res.data.xmFeeList;
|
||||
}).catch((err: any) => {
|
||||
console.error('请求数据失败:', err);
|
||||
});
|
||||
};
|
||||
|
||||
// 中间表格行双击事件
|
||||
const handleMiddleRowDblClick = (row: any) => {
|
||||
const index = middleTableData.value.findIndex(
|
||||
(item: any) => item.sfxmdh === row.sfxmdh,
|
||||
);
|
||||
if (index !== -1) {
|
||||
const removedItem = middleTableData.value[index];
|
||||
|
||||
feeitemvDel({ sfxmdh: removedItem.sfxmdh }).then((res: any) => {
|
||||
if (res.code == 0) {
|
||||
middleTableData.value.splice(index, 1)
|
||||
rightTableData.value.push(removedItem);
|
||||
}
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
// 右侧表格行双击事件
|
||||
const handleRightRowDblClick = (row: any) => {
|
||||
const index = rightTableData.value.findIndex(
|
||||
(item: any) => item.sfxmdh === row.sfxmdh,
|
||||
);
|
||||
if (index !== -1) {
|
||||
const removedItem = rightTableData.value[index];
|
||||
removedItem.xh = middleTableData.value.length + 1;
|
||||
removedItem.sflbdh = sflbdhData.value.sflbdh;
|
||||
|
||||
feeitemvAdd([removedItem]).then((res: any) => {
|
||||
if (res.code == 0) {
|
||||
rightTableData.value.splice(index, 1)
|
||||
middleTableData.value.push(removedItem);
|
||||
}
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
const getList = () => {
|
||||
feeitemclassList().then((res: any) => {
|
||||
if (res.code == 200) {
|
||||
leftTableData.value = res.rows;
|
||||
handleLeftRowClick(res.rows[0]);
|
||||
}
|
||||
})
|
||||
}
|
||||
getList()
|
||||
|
||||
// 单元格样式
|
||||
const cellStyle = ({ row, column, rowIndex, columnIndex }: {
|
||||
row: any;
|
||||
column: any;
|
||||
rowIndex: number;
|
||||
columnIndex: number;
|
||||
}) => {
|
||||
const bgColor = classCom.decimalToHexColor(row.bkcolor);
|
||||
const textColor = classCom.getContrastTextColor(bgColor);
|
||||
return {
|
||||
backgroundColor: `${bgColor} !important`,
|
||||
color: textColor,
|
||||
};
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.app-container {
|
||||
display: flex;
|
||||
padding: 20px;
|
||||
gap: 35px;
|
||||
|
||||
}
|
||||
</style>
|
||||
722
src/views/mzcx/charge/index.vue
Normal file
722
src/views/mzcx/charge/index.vue
Normal file
@ -0,0 +1,722 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<div class="table-header">
|
||||
<div>
|
||||
项目检索: <el-input v-model="queryParams.sfxmdh" @blur="handleQuery" @keyup.enter="handleQuery" auto-focus
|
||||
style="width: 200px;margin-right: 10px;" />
|
||||
|
||||
<el-button type="primary" @click="handleQuery" class="add-btn"> 查询 </el-button>
|
||||
<el-button type="primary" @click="addNewItem" class="add-btn"> 新增 </el-button>
|
||||
<el-button type="success" @click="save" class="add-btn"> 保存 </el-button>
|
||||
</div>
|
||||
</div>
|
||||
<el-table :data="tableData" border style="width: 100%" @cell-click="handleCellClick" :cell-style="cellStyle"
|
||||
:row-key="(row: any) => row.id" height="calc(100vh - 260px)" highlight-current-row ref="tableRef">
|
||||
<!-- 收费项目代号 -->
|
||||
<el-table-column prop="sfxmdh" label="收费项目代号" width="110">
|
||||
<template #default="scope">
|
||||
<template v-if="isEditing(scope.row, 'sfxmdh')">
|
||||
<el-input v-model="scope.row.sfxmdh" size="small" @blur="handleSave(scope.row, 'sfxmdh')"
|
||||
@keyup.enter="handleSave(scope.row, 'sfxmdh')" auto-focus :ref="getInputRef(scope.row.id, 'sfxmdh')" />
|
||||
</template>
|
||||
<template v-else>
|
||||
<span @click.stop="handleCellClick(scope.row, { property: 'sfxmdh' })">
|
||||
{{ scope.row.sfxmdh }}
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 收费项目名称 -->
|
||||
<el-table-column prop="sfxmmc" label="收费项目名称" width="150">
|
||||
<template #default="scope">
|
||||
<template v-if="isEditing(scope.row, 'sfxmmc')">
|
||||
<el-input v-model="scope.row.sfxmmc" size="small" @blur="handleSave(scope.row, 'sfxmmc')"
|
||||
@keyup.enter="handleSave(scope.row, 'sfxmmc')" auto-focus :ref="getInputRef(scope.row.id, 'sfxmmc')" />
|
||||
</template>
|
||||
<template v-else>
|
||||
<span @click.stop="handleCellClick(scope.row, { property: 'sfxmmc' })">
|
||||
{{ scope.row.sfxmmc }}
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 简称 -->
|
||||
<el-table-column prop="bz" label="简称" width="120">
|
||||
<template #default="scope">
|
||||
<template v-if="isEditing(scope.row, 'bz')">
|
||||
<el-input v-model="scope.row.bz" size="small" @blur="handleSave(scope.row, 'bz')"
|
||||
@keyup.enter="handleSave(scope.row, 'bz')" auto-focus :ref="getInputRef(scope.row.id, 'bz')" />
|
||||
</template>
|
||||
<template v-else>
|
||||
<span @click.stop="handleCellClick(scope.row, { property: 'bz' })">
|
||||
{{ scope.row.bz }}
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 价格 -->
|
||||
<el-table-column prop="dj" label="价格" width="150" align="center">
|
||||
<template #default="scope">
|
||||
<template v-if="isEditing(scope.row, 'dj')">
|
||||
<el-input-number v-model="scope.row.dj" :min="1" :max="100" size="small" @blur="handleSave(scope.row, 'dj')"
|
||||
@keyup.enter="handleSave(scope.row, 'dj')" auto-focus :ref="getInputRef(scope.row.id, 'dj')" />
|
||||
</template>
|
||||
<template v-else>
|
||||
<span @click.stop="handleCellClick(scope.row, { property: 'dj' })">
|
||||
{{ scope.row.dj }}
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!-- 规格 -->
|
||||
<el-table-column prop="spec" label="规格" width="120">
|
||||
<template #default="scope">
|
||||
<template v-if="isEditing(scope.row, 'spec')">
|
||||
<el-input v-model="scope.row.spec" size="small" @blur="handleSave(scope.row, 'spec')"
|
||||
@keyup.enter="handleSave(scope.row, 'spec')" auto-focus :ref="getInputRef(scope.row.id, 'spec')" />
|
||||
</template>
|
||||
<template v-else>
|
||||
<span @click.stop="handleCellClick(scope.row, { property: 'spec' })">
|
||||
{{ scope.row.spec }}
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!-- 科室 -->
|
||||
<el-table-column prop="dept" label="科室" width="150">
|
||||
<template #default="scope">
|
||||
<template v-if="isEditing(scope.row, 'dept')">
|
||||
<el-select v-model="scope.row.dept" size="small" @change="handleSave(scope.row, 'dept')"
|
||||
@blur="handleSave(scope.row, 'dept')" auto-focus filterable style="width: 100%;">
|
||||
<el-option v-for="item in dictData.DP" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span @click.stop="handleCellClick(scope.row, { property: 'dept' })">
|
||||
{{ formatDict(scope.row.dept, 'DP') }}
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 采集样本 -->
|
||||
<el-table-column prop="yblx" label="采集样本" width="140">
|
||||
<template #default="scope">
|
||||
<template v-if="isEditing(scope.row, 'yblx')">
|
||||
<el-select v-model="scope.row.yblx" size="small" @change="handleSave(scope.row, 'yblx')"
|
||||
@blur="handleSave(scope.row, 'yblx')" auto-focus filterable>
|
||||
<el-option v-for="item in dictData.BT" :key="item.label" :label="item.label" :value="item.label" />
|
||||
</el-select>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span @click.stop="handleCellClick(scope.row, { property: 'yblx' })">
|
||||
{{ scope.row.yblx }}
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!-- 报告天数 -->
|
||||
<el-table-column prop="bgts" label="报告天数" width="120" align="center">
|
||||
<template #default="scope">
|
||||
<template v-if="isEditing(scope.row, 'bgts')">
|
||||
<el-input-number v-model="scope.row.bgts" size="small" @blur="handleSave(scope.row, 'bgts')"
|
||||
@keyup.enter="handleSave(scope.row, 'bgts')" auto-focus :ref="getInputRef(scope.row.id, 'bgts')" />
|
||||
</template>
|
||||
<template v-else>
|
||||
<span @click.stop="handleCellClick(scope.row, { property: 'bgts' })">
|
||||
{{ scope.row.bgts }}
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 助记符 -->
|
||||
<el-table-column prop="zjf" label="助记符" width="150" align="center">
|
||||
<template #default="scope">
|
||||
<template v-if="isEditing(scope.row, 'zjf')">
|
||||
<el-input v-model="scope.row.zjf" size="small" @blur="handleSave(scope.row, 'zjf')"
|
||||
@keyup.enter.ctrl="handleSave(scope.row, 'zjf')" auto-focus :ref="getInputRef(scope.row.id, 'zjf')" />
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="multi-line-text" @click.stop="handleCellClick(scope.row, { property: 'zjf' })">
|
||||
{{ scope.row.zjf }}
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 报告领取规则 -->
|
||||
<el-table-column prop="bglqdh" label="报告领取规则" width="160">
|
||||
<template #default="scope">
|
||||
<template v-if="isEditing(scope.row, 'bglqdh')">
|
||||
<el-select v-model="scope.row.bglqdh" size="small" @change="handleSave(scope.row, 'bglqdh')" filterable
|
||||
@blur="handleSave(scope.row, 'bglqdh')" auto-focus>
|
||||
<el-option v-for="item in reportRuleOptions" :key="item.bglqdh" :label="item.bglqmc"
|
||||
:value="item.bglqdh" />
|
||||
</el-select>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span @click.stop="handleCellClick(scope.row, { property: 'bglqdh' })">
|
||||
{{ getOptionLabel(reportRuleOptions, scope.row.bglqdh) }}
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!-- 条码分类 -->
|
||||
<el-table-column prop="sflbmc" label="条码分类" width="130">
|
||||
<template #default="scope">
|
||||
<!-- <template v-if="isEditing(scope.row, 'sflbmc')">
|
||||
<el-select v-model="scope.row.sflbmc" size="small" @change="handleSave(scope.row, 'sflbmc')"
|
||||
@blur="handleSave(scope.row, 'sflbmc')" auto-focus>
|
||||
<el-option v-for="item in sflbmcOptions" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</template> -->
|
||||
{{ scope.row.sflbmc }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 专业组(样本数) -->
|
||||
<el-table-column prop="lisgroup1" label="专业组(样本数)" width="140" align="center">
|
||||
<template #default="scope">
|
||||
<template v-if="isEditing(scope.row, 'lisgroup1')">
|
||||
<el-select v-model="scope.row.lisgroup1" size="small" @change="handleSave(scope.row, 'lisgroup1')"
|
||||
@blur="handleSave(scope.row, 'lisgroup1')" auto-focus filterable>
|
||||
<el-option v-for="item in dictData.LISGROUP1" :key="item.label" :label="item.label" :value="item.label" />
|
||||
</el-select>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span @click.stop="handleCellClick(scope.row, { property: 'lisgroup1' })">
|
||||
{{ scope.row.lisgroup1 }}
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 专业组(周转时间) -->
|
||||
<el-table-column prop="lisgroup2" label="专业组(周转时间)" width="160" align="center">
|
||||
<template #default="scope">
|
||||
<template v-if="isEditing(scope.row, 'lisgroup2')">
|
||||
<el-select v-model="scope.row.lisgroup2" size="small" @change="handleSave(scope.row, 'lisgroup2')"
|
||||
@blur="handleSave(scope.row, 'lisgroup2')" auto-focus filterable>
|
||||
<el-option v-for="item in dictData.LISGROUP2" :key="item.label" :label="item.label" :value="item.label" />
|
||||
</el-select>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span @click.stop="handleCellClick(scope.row, { property: 'lisgroup2' })">
|
||||
{{ scope.row.lisgroup2 }}
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 适应症 -->
|
||||
<el-table-column prop="indication" label="适应症" width="220">
|
||||
<template #default="scope">
|
||||
<template v-if="isEditing(scope.row, 'indication')">
|
||||
<el-input v-model="scope.row.indication" size="small" type="textarea" :rows="2"
|
||||
@blur="handleSave(scope.row, 'indication')" @keyup.enter.ctrl="handleSave(scope.row, 'indication')"
|
||||
auto-focus :ref="getInputRef(scope.row.id, 'indication')" />
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="multi-line-text" @click.stop="handleCellClick(scope.row, { property: 'indication' })">
|
||||
{{ scope.row.indication }}
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 作用 -->
|
||||
<el-table-column prop="affect" label="作用" width="220">
|
||||
<template #default="scope">
|
||||
<template v-if="isEditing(scope.row, 'affect')">
|
||||
<el-input v-model="scope.row.affect" size="small" type="textarea" :rows="2"
|
||||
@blur="handleSave(scope.row, 'affect')" @keyup.enter.ctrl="handleSave(scope.row, 'affect')" auto-focus
|
||||
:ref="getInputRef(scope.row.id, 'affect')" />
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="multi-line-text" @click.stop="handleCellClick(scope.row, { property: 'affect' })">
|
||||
{{ scope.row.affect }}
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 采集要求 -->
|
||||
<el-table-column prop="attention" label="采集要求" width="220">
|
||||
<template #default="scope">
|
||||
<template v-if="isEditing(scope.row, 'attention')">
|
||||
<el-input v-model="scope.row.attention" size="small" type="textarea" :rows="2"
|
||||
@blur="handleSave(scope.row, 'attention')" @keyup.enter.ctrl="handleSave(scope.row, 'attention')"
|
||||
auto-focus :ref="getInputRef(scope.row.id, 'attention')" />
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="multi-line-text" @click.stop="handleCellClick(scope.row, { property: 'attention' })">
|
||||
{{ scope.row.attention }}
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 操作列 -->
|
||||
<el-table-column label="操作" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button size="small" type="danger" @click="handleDelete(scope.row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize"
|
||||
@pagination="getList" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, nextTick, onMounted, toRaw, computed } from 'vue';
|
||||
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||
import { xmfeeList, rptgetrules, xmfeeadd, xmfeeUpdate, xmfeeDel } from '@/api/mzcx/index';
|
||||
import { classCom } from '@/utils/classCom';
|
||||
// @ts-ignore
|
||||
import { comDict } from '@/utils/dict'
|
||||
const total = ref(0);
|
||||
|
||||
|
||||
const deptOptions = [
|
||||
{ label: '全部', value: '' }
|
||||
]
|
||||
|
||||
const queryParams = ref({
|
||||
sfxmdh: '',
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
yljg: 1
|
||||
})
|
||||
|
||||
const reportRuleOptions = ref<{ bglqdh: string, bglqmc: string, bz: string }[]>([]);
|
||||
|
||||
interface tableDataItem {
|
||||
id: string,
|
||||
sfxmdh: string,
|
||||
sfxmmc: string,
|
||||
bz: string,
|
||||
dj: string,
|
||||
dept: string,
|
||||
yblx: string,
|
||||
zjf: string,
|
||||
spec: string,
|
||||
bgts: string,
|
||||
sflbmc: string,
|
||||
bglqdh: number,
|
||||
lisgroup1: string,
|
||||
lisgroup2: string,
|
||||
indication: string,
|
||||
affect: string,
|
||||
attention: string,
|
||||
originalData: object,
|
||||
flag: boolean,
|
||||
status: boolean,
|
||||
yljg: number
|
||||
}
|
||||
// 表格数据
|
||||
const tableData = ref<tableDataItem[]>([]);
|
||||
|
||||
const inputRefs = ref<Record<string, any>>({});
|
||||
// 表格引用
|
||||
const tableRef = ref(null);
|
||||
|
||||
const editingState = ref({ rowId: '', field: '' });
|
||||
|
||||
// 设置输入框引用
|
||||
const getInputRef = (rowId: string, field: string) => {
|
||||
return (el: any) => {
|
||||
if (el) {
|
||||
inputRefs.value[`${rowId}-${field}`] = el;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// 判断是否处于编辑状态
|
||||
const isEditing = (row: any, field: string) => {
|
||||
return editingState.value && editingState.value.rowId === row.id && editingState.value.field === field;
|
||||
};
|
||||
|
||||
// 获取选项标签
|
||||
const getOptionLabel = (options: any, value: string) => {
|
||||
const option = options.find((item: any) => item.bglqdh === value);
|
||||
return option ? option.bglqmc : '';
|
||||
};
|
||||
|
||||
// 处理单元格点击 - 核心修复部分
|
||||
const handleCellClick = (row: any, column: any) => {
|
||||
// 忽略操作列
|
||||
if (column.label === '操作') return;
|
||||
|
||||
const field = column.property;
|
||||
|
||||
// 如果点击的是当前编辑的单元格,不重复处理
|
||||
if (isEditing(row, field)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 保存之前编辑的内容
|
||||
if (editingState.value) {
|
||||
const prevRow = tableData.value.find((r: any) => r.id === editingState.value.rowId);
|
||||
if (prevRow) {
|
||||
handleSave(prevRow, editingState.value.field);
|
||||
}
|
||||
}
|
||||
|
||||
// 保存原始值用于恢复
|
||||
row.originalData[field] = JSON.parse(JSON.stringify(row[field]));
|
||||
|
||||
// 设置当前编辑状态
|
||||
editingState.value = {
|
||||
rowId: row.id,
|
||||
field: field
|
||||
};
|
||||
|
||||
// 强制刷新UI后聚焦
|
||||
nextTick(() => {
|
||||
const inputKey = `${row.id}-${field}`;
|
||||
const inputComponent = inputRefs.value[inputKey];
|
||||
if (!inputComponent) return;
|
||||
|
||||
// 不同组件的聚焦方式不同,做适配处理
|
||||
if (inputComponent.focus) {
|
||||
// 基础输入组件直接调用focus方法
|
||||
inputComponent.focus();
|
||||
} else if (inputComponent.$el) {
|
||||
// 查找内部输入元素
|
||||
const inputEl = inputComponent.$el.querySelector('input, textarea') ||
|
||||
inputComponent.$el.querySelector('.el-select__input') ||
|
||||
inputComponent.$el;
|
||||
inputEl?.focus?.();
|
||||
}
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
// 保存编辑
|
||||
const handleSave = (row: any, field: string) => {
|
||||
// 非编辑状态不处理
|
||||
if (!isEditing(row, field)) return;
|
||||
|
||||
let isValid = true;
|
||||
let errorMessage = '';
|
||||
|
||||
// 字段验证
|
||||
switch (field) {
|
||||
case 'sfxmdh':
|
||||
if (!row[field]?.trim()) {
|
||||
isValid = false;
|
||||
errorMessage = '收费项目代号不能为空';
|
||||
}
|
||||
break;
|
||||
// case 'sfxmmc':
|
||||
// if (!row[field]?.trim()) {
|
||||
// isValid = false;
|
||||
// errorMessage = '收费项目名称不能为空';
|
||||
// }
|
||||
// break;
|
||||
// case 'bz':
|
||||
// if (!row[field]?.trim()) {
|
||||
// isValid = false;
|
||||
// errorMessage = '简称不能为空';
|
||||
// }
|
||||
// break;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
// 验证失败处理
|
||||
if (!isValid) {
|
||||
row[field] = row.originalData[field];
|
||||
ElMessage.error(errorMessage);
|
||||
// 保持编辑状态以便修正
|
||||
return;
|
||||
}
|
||||
|
||||
// 对比原始数据判断是否有变化
|
||||
if (!row.status) {
|
||||
row.status = JSON.stringify(row[field]) !== JSON.stringify(row.originalData[field]);
|
||||
}
|
||||
// 清除编辑状态
|
||||
editingState.value = { rowId: '', field: '' };
|
||||
|
||||
console.log('originalData==>', row);
|
||||
};
|
||||
interface OperateLists {
|
||||
addList: any[];
|
||||
updateList: any[];
|
||||
}
|
||||
// 保存
|
||||
const save = () => {
|
||||
const { addList, updateList } = tableData.value.reduce<OperateLists>((acc, item) => {
|
||||
const { originalData, id, status, flag, ...restData } = item;
|
||||
const submitData = { ...restData, };
|
||||
if (status) {
|
||||
flag ? acc.addList.push(submitData) : acc.updateList.push(submitData);
|
||||
}
|
||||
return acc;
|
||||
}, { addList: [], updateList: [] });
|
||||
|
||||
console.log('新增列表:', addList);
|
||||
console.log('更新列表:', updateList);
|
||||
if (addList.length > 0) {
|
||||
xmfeeadd(addList).then((res: any) => {
|
||||
if (res.code == 0) {
|
||||
ElMessage.success(res.msg);
|
||||
getList()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if (updateList.length > 0) {
|
||||
xmfeeUpdate(updateList).then((res: any) => {
|
||||
if (res.code == 0) {
|
||||
ElMessage.success(res.msg);
|
||||
getList()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 单元格样式
|
||||
const cellClassName = ({ row, column }: { row: any, column: any }) => {
|
||||
return isEditing(row, column.property)
|
||||
? 'cell-editing'
|
||||
: 'cell-editable';
|
||||
};
|
||||
|
||||
// 单元格样式
|
||||
const cellStyle = ({ row, column, rowIndex, columnIndex }: {
|
||||
row: any;
|
||||
column: any;
|
||||
rowIndex: number;
|
||||
columnIndex: number;
|
||||
}) => {
|
||||
if (column.label == "条码分类") {
|
||||
const bgColor = classCom.decimalToHexColor(row.bkcolor);
|
||||
const textColor = classCom.getContrastTextColor(bgColor);
|
||||
return {
|
||||
backgroundColor: `${bgColor} !important`,
|
||||
color: textColor,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
// 新增项
|
||||
const addNewItem = () => {
|
||||
const newId = Array.from({ length: 14 }, () => Math.floor(Math.random() * 10)).join('');
|
||||
tableData.value.unshift({
|
||||
id: newId,
|
||||
sfxmdh: `NEW${newId}`,
|
||||
sfxmmc: 'test',
|
||||
bz: '',
|
||||
dj: '',
|
||||
spec: '',
|
||||
dept: '',
|
||||
yblx: '',
|
||||
bgts: '',
|
||||
zjf: '',
|
||||
bglqdh: 1,
|
||||
sflbmc: '',
|
||||
indication: '',
|
||||
affect: '',
|
||||
attention: '',
|
||||
lisgroup1: '',
|
||||
lisgroup2: '',
|
||||
originalData: {},
|
||||
flag: true,
|
||||
yljg: 1,
|
||||
status: true,
|
||||
});
|
||||
// ElMessage.info('已添加新类别,请完善信息');
|
||||
};
|
||||
// 删除项
|
||||
const handleDelete = (row: any) => {
|
||||
|
||||
ElMessageBox.confirm(
|
||||
`确定删除${row.sfxmdh}数据吗?`, "提示",
|
||||
{
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
}
|
||||
)
|
||||
.then(() => {
|
||||
xmfeeDel({ sfxmdh: row.sfxmdh }).then((res: any) => {
|
||||
if (res.code == 0) {
|
||||
getList()
|
||||
ElMessage.success('删除成功');
|
||||
}
|
||||
})
|
||||
})
|
||||
.catch(() => {
|
||||
|
||||
})
|
||||
};
|
||||
const handleQuery = () => {
|
||||
queryParams.value.pageNum = 1
|
||||
getList()
|
||||
}
|
||||
|
||||
|
||||
const getList = () => {
|
||||
xmfeeList(queryParams.value).then((res: any) => {
|
||||
if (res.code == 200) {
|
||||
tableData.value = res.rows
|
||||
total.value = res.total
|
||||
tableData.value.forEach((item: any) => {
|
||||
item.originalData = {}
|
||||
item.id = item.sfxmdh
|
||||
item.status = false
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const getRules = () => {
|
||||
rptgetrules().then((res: any) => {
|
||||
reportRuleOptions.value = res.data
|
||||
})
|
||||
}
|
||||
getList()
|
||||
getRules()
|
||||
|
||||
interface DictData {
|
||||
BT?: Array<any>;
|
||||
DP?: Array<any>;
|
||||
LISGROUP1?: Array<any>;
|
||||
LISGROUP2?: Array<any>;
|
||||
[key: string]: any[] | undefined; // 添加索引签名以支持动态访问
|
||||
}
|
||||
|
||||
|
||||
// 字典数据存储
|
||||
const dictData = ref<DictData>({});
|
||||
onMounted(async () => {
|
||||
// 加载病人来源字典
|
||||
const dictRefs = await comDict('BT', 'DP', 'LISGROUP1', 'LISGROUP2');
|
||||
|
||||
// 从 ref 中获取实际数据
|
||||
dictData.value = {
|
||||
BT: toRaw(dictRefs.BT.value) || [],
|
||||
DP: toRaw(dictRefs.DP.value) || [],
|
||||
LISGROUP1: toRaw(dictRefs.LISGROUP1.value) || [],
|
||||
LISGROUP2: toRaw(dictRefs.LISGROUP2.value) || [],
|
||||
};
|
||||
})
|
||||
|
||||
|
||||
|
||||
// 字典格式化方法
|
||||
const formatDict = (v: string, dictType: string) => {
|
||||
return dictData.value[dictType]?.find((item: any) => item.value == v)?.label;
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 保持与之前相同的样式 */
|
||||
.editable-table-wrapper {
|
||||
padding: 20px;
|
||||
max-width: 1800px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.table-header {
|
||||
/* display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center; */
|
||||
margin-bottom: 15px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
.table-header h3 {
|
||||
margin: 0;
|
||||
color: #333;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.add-btn {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.table-desc {
|
||||
margin-top: 15px;
|
||||
padding: 10px 15px;
|
||||
background-color: #f5f7fa;
|
||||
border-radius: 4px;
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
/* 单元格样式优化 */
|
||||
::v-deep .cell-editable {
|
||||
cursor: pointer;
|
||||
transition: background-color 0.2s;
|
||||
}
|
||||
|
||||
::v-deep .cell-editable:hover {
|
||||
background-color: #f0f7ff !important;
|
||||
}
|
||||
|
||||
::v-deep .cell-editing {
|
||||
background-color: #e6f7ff !important;
|
||||
}
|
||||
|
||||
::v-deep .el-table .el-table__cell {
|
||||
padding: 6px 0;
|
||||
}
|
||||
|
||||
/* 输入控件样式 */
|
||||
::v-deep .el-input,
|
||||
::v-deep .el-input-number,
|
||||
::v-deep .el-select,
|
||||
::v-deep .el-color-picker,
|
||||
::v-deep .el-textarea {
|
||||
width: 90%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
::v-deep .el-textarea__inner {
|
||||
min-height: 60px;
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
/* 多行文本和颜色显示样式 */
|
||||
.multi-line-text {
|
||||
white-space: pre-wrap;
|
||||
word-break: break-all;
|
||||
line-height: 1.4;
|
||||
padding: 0 5px;
|
||||
}
|
||||
|
||||
.color-display {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.color-block {
|
||||
display: inline-block;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 3px;
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.color-code {
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
max-width: 80px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
</style>
|
||||
@ -1,37 +1,34 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-row :gutter="5" class="compact-form" :span="24" >
|
||||
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-position="left" >
|
||||
<el-row :gutter="5" class="compact-form" :span="24">
|
||||
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-position="left">
|
||||
<el-col :span="24" :xs="24">
|
||||
<el-form-item label="" label-width="0px" prop="brdh" >
|
||||
<el-form-item label="" label-width="0px" prop="brdh">
|
||||
|
||||
<el-col :span="6">
|
||||
<div> 就诊卡号/病历号/磁卡号: </div>
|
||||
<el-input
|
||||
v-model="queryParams.brdh"
|
||||
placeholder="就诊卡号/病历号/磁卡号"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
<el-input v-model="queryParams.brdh" placeholder="就诊卡号/病历号/磁卡号" clearable @keyup.enter="handleQuery" />
|
||||
</el-col>
|
||||
<el-col :span="2">
|
||||
<el-radio-group v-model="queryParams.zt" size="default">
|
||||
<el-radio v-for="(item, index) in showconfirmOptions" :key="index" :label="item.value"
|
||||
:disabled="item.disabled">{{item.label}}</el-radio>
|
||||
:disabled="item.disabled">{{ item.label }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-col>
|
||||
<el-col :span="1"> <div> 申请获取期限: </div></el-col>
|
||||
<el-col :span="1">
|
||||
<div> 申请获取期限: </div>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
|
||||
<el-radio-group v-model="queryParams.subday" size="default">
|
||||
<el-radio v-for="(item, index) in subdayOptions" :key="index" :label="item.value"
|
||||
:disabled="item.disabled">{{item.label}}</el-radio>
|
||||
:disabled="item.disabled">{{ item.label }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-col>
|
||||
<el-col :span="2">
|
||||
<el-select v-model="queryParams.cardtype" placeholder="卡类型" clearable :style="{width: '100%'}">
|
||||
<el-option v-for="(item, index) in cardtypeOptions" :key="index" :label="item.label"
|
||||
:value="item.value" :disabled="item.disabled"></el-option>
|
||||
<el-select v-model="queryParams.cardtype" placeholder="卡类型" clearable :style="{ width: '100%' }">
|
||||
<el-option v-for="(item, index) in cardtypeOptions" :key="index" :label="item.label" :value="item.value"
|
||||
:disabled="item.disabled"></el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
@ -47,112 +44,78 @@
|
||||
</el-row>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
icon="Search"
|
||||
@click="handleQuery"
|
||||
v-hasPermi="['system:reqmain:Search']"
|
||||
>查询</el-button>
|
||||
<el-button type="primary" plain icon="Search" @click="handleQuery"
|
||||
v-hasPermi="['system:reqmain:Search']">查询</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="success"
|
||||
plain
|
||||
icon="Printer"
|
||||
:disabled="single"
|
||||
@click="printAll"
|
||||
v-hasPermi="['system:reqmain:add']"
|
||||
>打印</el-button>
|
||||
<el-button type="success" plain icon="Printer" :disabled="single" @click="printAll"
|
||||
v-hasPermi="['system:reqmain:add']">打印</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="success"
|
||||
plain
|
||||
icon="Printer"
|
||||
:disabled="freesingle"
|
||||
@click="printSigne"
|
||||
v-hasPermi="['system:reqmain:edit']"
|
||||
>单打条码</el-button>
|
||||
<el-button type="success" plain icon="Printer" :disabled="freesingle" @click="printSigne"
|
||||
v-hasPermi="['system:reqmain:edit']">单打条码</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="danger"
|
||||
plain
|
||||
icon="Printer"
|
||||
:disabled="freesingle"
|
||||
@click="printBackpaper"
|
||||
v-hasPermi="['system:reqmain:edit']"
|
||||
>单打回单</el-button>
|
||||
<el-button type="danger" plain icon="Printer" :disabled="freesingle" @click="printBackpaper"
|
||||
v-hasPermi="['system:reqmain:edit']">单打回单</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="warning"
|
||||
plain
|
||||
icon="Delete"
|
||||
@click="cancel"
|
||||
v-hasPermi="['system:reqmain:export']"
|
||||
>取消采样</el-button>
|
||||
<el-button type="warning" plain icon="Delete" @click="cancel"
|
||||
v-hasPermi="['system:reqmain:export']">取消采样</el-button>
|
||||
</el-col>
|
||||
<el-col :span="3">
|
||||
<barcode-printer
|
||||
:printData="printBarcodeData"
|
||||
:disabled="!hasSelectedRows"
|
||||
type="success"
|
||||
icon="Printer"
|
||||
@print-start="showLoading"
|
||||
@print-success="handlePrintSuccess"
|
||||
@print-error="handlePrintError"
|
||||
>
|
||||
<barcode-printer :printData="printBarcodeData" :disabled="!hasSelectedRows" type="success" icon="Printer"
|
||||
@print-start="showLoading" @print-success="handlePrintSuccess" @print-error="handlePrintError">
|
||||
打印条码
|
||||
</barcode-printer>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
|
||||
<el-table ref="tableRef" class="compact-form my-table" :data="reqmainList" @selection-change="handleSelectionChange" @select="handleSelect" height="530px" :cell-style="tableCellStyle">
|
||||
<el-table ref="tableRef" class="compact-form my-table" :data="reqmainList" @selection-change="handleSelectionChange"
|
||||
@select="handleSelect" height="530px" :cell-style="tableCellStyle">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="项目名称" align="center" prop="sqxmmc" width="200" show-overflow-tooltip/>
|
||||
<el-table-column label="项目代码" align="center" prop="sqxmdh" width="100" show-overflow-tooltip/>
|
||||
<el-table-column label="项目名称" align="center" prop="sqxmmc" width="200" show-overflow-tooltip />
|
||||
<el-table-column label="项目代码" align="center" prop="sqxmdh" width="100" show-overflow-tooltip />
|
||||
<el-table-column label="项目类别" align="center" prop="cp_xmlb" />
|
||||
<el-table-column label="样本类型" align="center" prop="yblx" />
|
||||
<el-table-column label="条码号" align="center" prop="sqh" width="150" show-overflow-tooltip/>
|
||||
<el-table-column label="条码号" align="center" prop="sqh" width="150" show-overflow-tooltip />
|
||||
<el-table-column label="申请时间" align="center" prop="sqsj" width="180" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.sqsj, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="病人姓名" align="center" prop="brxm" show-overflow-tooltip/>
|
||||
<el-table-column label="申请医生" align="center" prop="sqys" :formatter="formatDict('SRD')" show-overflow-tooltip/>
|
||||
<el-table-column label="序号" align="center" prop="xh" show-overflow-tooltip/>
|
||||
<el-table-column label="数量" align="center" prop="sl" show-overflow-tooltip/>
|
||||
<el-table-column label="单价" align="center" prop="dj" show-overflow-tooltip/>
|
||||
<el-table-column label="状态" align="center" prop="zt" show-overflow-tooltip/>
|
||||
<el-table-column label="计价" align="center" prop="jjzt" >
|
||||
<el-table-column label="病人姓名" align="center" prop="brxm" show-overflow-tooltip />
|
||||
<el-table-column label="申请医生" align="center" prop="sqys" :formatter="formatDict('SRD')" show-overflow-tooltip />
|
||||
<el-table-column label="序号" align="center" prop="xh" show-overflow-tooltip />
|
||||
<el-table-column label="数量" align="center" prop="sl" show-overflow-tooltip />
|
||||
<el-table-column label="单价" align="center" prop="dj" show-overflow-tooltip />
|
||||
<el-table-column label="状态" align="center" prop="zt" show-overflow-tooltip />
|
||||
<el-table-column label="计价" align="center" prop="jjzt">
|
||||
<template #default="scope">
|
||||
<el-checkbox :model-value="scope.row.jjzt === '1'" disabled>
|
||||
</el-checkbox>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="病人代号" align="center" prop="brdh" show-overflow-tooltip/>
|
||||
<el-table-column label="备注1" align="center" prop="detailBZ1" show-overflow-tooltip/>
|
||||
<el-table-column label="备注2" align="center" prop="detailBZ2" show-overflow-tooltip/>
|
||||
<el-table-column label="颜色" align="center" prop="cp_color" v-if="false" show-overflow-tooltip/>
|
||||
<el-table-column label="确认标识" align="center" prop="cp_cflag" v-if="false" show-overflow-tooltip/>
|
||||
<el-table-column label="科室" align="center" prop="ksdh" :formatter="formatDict('DP')" show-overflow-tooltip/>
|
||||
<el-table-column label="病人类型" align="center" prop="brly" :formatter="formatDict('PT')" show-overflow-tooltip/>
|
||||
<el-table-column label="性别" align="center" prop="brxb" :formatter="formatDict('SX')" show-overflow-tooltip/>
|
||||
<el-table-column label="病人代号" align="center" prop="brdh" show-overflow-tooltip />
|
||||
<el-table-column label="备注1" align="center" prop="detailBZ1" show-overflow-tooltip />
|
||||
<el-table-column label="备注2" align="center" prop="detailBZ2" show-overflow-tooltip />
|
||||
<el-table-column label="颜色" align="center" prop="cp_color" v-if="false" show-overflow-tooltip />
|
||||
<el-table-column label="确认标识" align="center" prop="cp_cflag" v-if="false" show-overflow-tooltip />
|
||||
<el-table-column label="科室" align="center" prop="ksdh" :formatter="formatDict('DP')" show-overflow-tooltip />
|
||||
<el-table-column label="病人类型" align="center" prop="brly" :formatter="formatDict('PT')" show-overflow-tooltip />
|
||||
<el-table-column label="性别" align="center" prop="brxb" :formatter="formatDict('SX')" show-overflow-tooltip />
|
||||
<el-table-column label="生日" align="center" prop="brsr" width="180" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.brsr, '{y}-{m}-{d}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="床号" align="center" prop="ch" width="50" show-overflow-tooltip/>
|
||||
<el-table-column label="诊断" align="center" prop="zd" width="150" show-overflow-tooltip/>
|
||||
<el-table-column label="条码类别" align="center" prop="bgddh" v-if="false" show-overflow-tooltip/>
|
||||
<el-table-column label="年龄" align="center" prop="nl" show-overflow-tooltip/>
|
||||
<el-table-column label="年龄单位" align="center" prop="nldw" :formatter="formatDict('AU')" show-overflow-tooltip/>
|
||||
<el-table-column label="采样时间" align="center" prop="cysj" width="180"show-overflow-tooltip>
|
||||
<el-table-column label="床号" align="center" prop="ch" width="50" show-overflow-tooltip />
|
||||
<el-table-column label="诊断" align="center" prop="zd" width="150" show-overflow-tooltip />
|
||||
<el-table-column label="条码类别" align="center" prop="bgddh" v-if="false" show-overflow-tooltip />
|
||||
<el-table-column label="年龄" align="center" prop="nl" show-overflow-tooltip />
|
||||
<el-table-column label="年龄单位" align="center" prop="nldw" :formatter="formatDict('AU')" show-overflow-tooltip />
|
||||
<el-table-column label="采样时间" align="center" prop="cysj" width="180" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.cysj, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
||||
</template>
|
||||
@ -178,8 +141,8 @@
|
||||
|
||||
<script setup>
|
||||
import { ElMessage } from 'element-plus'; // 引入 Element Plus 消息组件
|
||||
import {querySQD, getReqmain, delReqmain, addReqmain, updateReqmain, printBarcode} from "@/api/mzcx/cydj.js";
|
||||
import BarcodePrinter from './components/BarcodePrinter.vue';
|
||||
import { querySQD, getReqmain, delReqmain, addReqmain, updateReqmain, printBarcode } from "@/api/mzcx/cydj.js";
|
||||
import BarcodePrinter from './BarcodePrinter.vue';
|
||||
const comDict = inject('comDict');
|
||||
// 字典数据存储
|
||||
const dictData = ref({});
|
||||
@ -198,9 +161,9 @@ const idsnew = computed(() => {
|
||||
});
|
||||
const single = ref(true);
|
||||
const freesingle = ref(true);
|
||||
const cardtypeOptions = ref([{"label": "就诊卡","value": 1},{"label": "医保卡","value": 2},{"label": "电子医保卡","value": 3},{"label": "身份证", "value": 4}])
|
||||
const showconfirmOptions = ref([{"label": "未打印", "value": 1},{"label": "已打印", "value": 11}])
|
||||
const subdayOptions = ref([{"label": "1天","value": 1},{"label": "3天", "value": 3},{"label": "1周","value": 7},{"label": "2周","value": 14},{"label": "1月", "value": 30},{"label": "3月", "value": 90},{"label": "1年","value": 365},{"label": "2年","value": 730}])
|
||||
const cardtypeOptions = ref([{ "label": "就诊卡", "value": 1 }, { "label": "医保卡", "value": 2 }, { "label": "电子医保卡", "value": 3 }, { "label": "身份证", "value": 4 }])
|
||||
const showconfirmOptions = ref([{ "label": "未打印", "value": 1 }, { "label": "已打印", "value": 11 }])
|
||||
const subdayOptions = ref([{ "label": "1天", "value": 1 }, { "label": "3天", "value": 3 }, { "label": "1周", "value": 7 }, { "label": "2周", "value": 14 }, { "label": "1月", "value": 30 }, { "label": "3月", "value": 90 }, { "label": "1年", "value": 365 }, { "label": "2年", "value": 730 }])
|
||||
|
||||
const data = reactive({
|
||||
form: {},
|
||||
@ -211,7 +174,7 @@ const data = reactive({
|
||||
klx: null,
|
||||
zt: 1,
|
||||
subday: 3000,
|
||||
cardtype:null
|
||||
cardtype: null
|
||||
},
|
||||
rules: {
|
||||
brdh: [
|
||||
@ -240,7 +203,7 @@ const handleSelect = (selection, row, selected) => {
|
||||
|
||||
// 先收集需要自动勾选的行(避免在循环中修改数据)
|
||||
const rowsToSelect = reqmainList.value.filter(
|
||||
item => item.sqh === targetSqh && item.xh !== targetxh
|
||||
item => item.sqh === targetSqh && item.xh !== targetxh
|
||||
);
|
||||
|
||||
// 如果有需要自动勾选的行,才开启标志位
|
||||
@ -254,10 +217,10 @@ const handleSelect = (selection, row, selected) => {
|
||||
}
|
||||
};
|
||||
// 字典格式化方法
|
||||
const formatDict =(dictType) => {
|
||||
const formatDict = (dictType) => {
|
||||
return (row, column, value) => {
|
||||
// 从全局字典中获取映射值
|
||||
return dictData.value[dictType].find(item => String(item.value) === String(value).trim())?.label||value ;
|
||||
return dictData.value[dictType].find(item => String(item.value) === String(value).trim())?.label || value;
|
||||
};
|
||||
};
|
||||
// 定义“空数据”的判断函数
|
||||
@ -292,14 +255,14 @@ function getDateOffset(days) {
|
||||
return `${year}-${month}-${day} 00:00:00`;
|
||||
}
|
||||
function getSubday() {
|
||||
const days=0 - queryParams.value.subday;
|
||||
queryParams.value.stime=getDateOffset(days);
|
||||
queryParams.value.etime=getDateOffset(1);
|
||||
const days = 0 - queryParams.value.subday;
|
||||
queryParams.value.stime = getDateOffset(days);
|
||||
queryParams.value.etime = getDateOffset(1);
|
||||
}
|
||||
/** 查询采样登记列表 */
|
||||
function getList() {
|
||||
|
||||
if(isEmptyData(queryParams.value.brdh)) proxy.$modal.alert("请刷卡或输入门诊号!");
|
||||
if (isEmptyData(queryParams.value.brdh)) proxy.$modal.alert("请刷卡或输入门诊号!");
|
||||
else {
|
||||
loading.value = true;
|
||||
getSubday();
|
||||
@ -307,7 +270,7 @@ function getList() {
|
||||
if (isEmptyData(response.data)) proxy.$modal.alert("没有检索的数据!");
|
||||
reqmainList.value = response.data;
|
||||
loading.value = false;
|
||||
single.value=false;
|
||||
single.value = false;
|
||||
// 新增:数据加载完成后触发全选
|
||||
// 延迟执行(确保DOM已更新)
|
||||
setTimeout(() => {
|
||||
@ -322,7 +285,7 @@ function getList() {
|
||||
// 取消按钮
|
||||
function cancel() {
|
||||
// open.value = false;
|
||||
// reset();
|
||||
// reset();
|
||||
}
|
||||
|
||||
// 表单重置
|
||||
@ -367,8 +330,8 @@ function reset() {
|
||||
zd: null,
|
||||
cysj: null
|
||||
};
|
||||
freesingle.value=false;
|
||||
single.value=false;
|
||||
freesingle.value = false;
|
||||
single.value = false;
|
||||
proxy.resetForm("reqmainRef");
|
||||
}
|
||||
|
||||
@ -389,7 +352,7 @@ function handleSelectionChange(selection) {
|
||||
selectedRows.value = selection;
|
||||
ids.value = selection.map(item => item.sqh);
|
||||
//console.log('ids:', ids.value);
|
||||
// console.log('selectedRows:', selectedRows.value);
|
||||
// console.log('selectedRows:', selectedRows.value);
|
||||
}
|
||||
|
||||
|
||||
@ -397,13 +360,13 @@ function handleSelectionChange(selection) {
|
||||
/** 打印选择 */
|
||||
function printAll(row) {
|
||||
console.log('idsnew:', idsnew.value);
|
||||
if (idsnew.value.length=== 0) {
|
||||
if (idsnew.value.length === 0) {
|
||||
return;
|
||||
}
|
||||
printBarcode({sqh:"20221201167919"}).then(response => {
|
||||
printBarcode({ sqh: "20221201167919" }).then(response => {
|
||||
proxy.$modal.msgSuccess("打印成功");
|
||||
open.value = false;
|
||||
freesingle.value=false;
|
||||
freesingle.value = false;
|
||||
}).catch(() => {
|
||||
});
|
||||
}
|
||||
@ -415,7 +378,7 @@ function printSigne(row) {
|
||||
apiprintAll(idsnew.value).then(response => {
|
||||
proxy.$modal.msgSuccess("打印成功");
|
||||
open.value = false;
|
||||
freesingle.value=false;
|
||||
freesingle.value = false;
|
||||
}).catch(() => {
|
||||
});
|
||||
}
|
||||
@ -449,8 +412,8 @@ const totalPrice = computed(() => {
|
||||
// 组件挂载时加载字典
|
||||
onMounted(async () => {
|
||||
// 加载病人来源字典
|
||||
const dictRefs = await comDict('PT', 'DP', 'SRD','BT','SX','AU');
|
||||
// 从 ref 中获取实际数据
|
||||
const dictRefs = await comDict('PT', 'DP', 'SRD', 'BT', 'SX', 'AU');
|
||||
// 从 ref 中获取实际数据
|
||||
dictData.value = {
|
||||
PT: toRaw(dictRefs.PT.value) || [],
|
||||
DP: toRaw(dictRefs.DP.value) || [],
|
||||
@ -562,22 +525,32 @@ const handlePrintError = (errorMsg) => {
|
||||
.compact-form .el-form-item__label {
|
||||
padding-bottom: 0px;
|
||||
}
|
||||
|
||||
::v-deep .my-table .el-table__row td {
|
||||
padding: 1px 0; /* 减小行高 */
|
||||
padding: 1px 0;
|
||||
/* 减小行高 */
|
||||
}
|
||||
|
||||
::v-deep .my-table .el-table__header-wrapper th {
|
||||
padding: 6px 0; /* 表头内边距 */
|
||||
background-color: #b3d8ff !important; /* 表头背景色(保留之前的设置) */
|
||||
color: #333; /* 文字颜色加深,提升可读性 */
|
||||
font-weight: 500; /* 文字加粗 */
|
||||
padding: 6px 0;
|
||||
/* 表头内边距 */
|
||||
background-color: #b3d8ff !important;
|
||||
/* 表头背景色(保留之前的设置) */
|
||||
color: #333;
|
||||
/* 文字颜色加深,提升可读性 */
|
||||
font-weight: 500;
|
||||
/* 文字加粗 */
|
||||
}
|
||||
|
||||
::v-deep .my-table .el-table__cell {
|
||||
padding: 0 2px; /* 减小列间距 */
|
||||
padding: 0 2px;
|
||||
/* 减小列间距 */
|
||||
}
|
||||
|
||||
/* 可选:调整表格整体样式 */
|
||||
::v-deep .my-table {
|
||||
font-size: 13px; /* 适当减小字体 */
|
||||
font-size: 13px;
|
||||
/* 适当减小字体 */
|
||||
}
|
||||
|
||||
::v-deep .my-table .el-table__cell,
|
||||
@ -585,17 +558,25 @@ const handlePrintError = (errorMsg) => {
|
||||
border-width: 1px;
|
||||
border-color: #ebeef5;
|
||||
}
|
||||
|
||||
.card-content {
|
||||
max-height: 450px; /* 设置最大高度 */
|
||||
overflow-y: auto; /* 超出高度时显示垂直滚动条 */
|
||||
padding: 5px; /* 保持与卡片默认一致的内边距 */
|
||||
max-height: 450px;
|
||||
/* 设置最大高度 */
|
||||
overflow-y: auto;
|
||||
/* 超出高度时显示垂直滚动条 */
|
||||
padding: 5px;
|
||||
/* 保持与卡片默认一致的内边距 */
|
||||
}
|
||||
|
||||
.clickable:hover {
|
||||
cursor: pointer; /* 鼠标悬停时显示手型 */
|
||||
transition: all 0.3s; /* 平滑过渡效果 */
|
||||
cursor: pointer;
|
||||
/* 鼠标悬停时显示手型 */
|
||||
transition: all 0.3s;
|
||||
/* 平滑过渡效果 */
|
||||
color: blue;
|
||||
|
||||
}
|
||||
|
||||
/* 汇总行样式 */
|
||||
.table-summary {
|
||||
display: flex;
|
||||
@ -607,7 +588,9 @@ const handlePrintError = (errorMsg) => {
|
||||
border: 1px solid #ebeef5;
|
||||
border-radius: 4px;
|
||||
font-weight: 500;
|
||||
line-height: 24px; /* 汇总行文字行高 */
|
||||
line-height: 24px;
|
||||
|
||||
/* 汇总行文字行高 */
|
||||
.summary-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@ -621,12 +604,16 @@ const handlePrintError = (errorMsg) => {
|
||||
.summary-value {
|
||||
color: #303133;
|
||||
min-width: 40px;
|
||||
text-align: left;/* 核心:数值左对齐 */
|
||||
text-align: left;
|
||||
/* 核心:数值左对齐 */
|
||||
}
|
||||
|
||||
/* 单独设置"单价合计"的值为红色 */
|
||||
&:nth-child(3) .summary-value {
|
||||
color: #f56c6c; /* Element UI 红色主题色 */
|
||||
font-weight: 600; /* 可选:加粗字体 */
|
||||
color: #f56c6c;
|
||||
/* Element UI 红色主题色 */
|
||||
font-weight: 600;
|
||||
/* 可选:加粗字体 */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,149 +1,119 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-row :gutter="5" class="compact-form" :span="24" >
|
||||
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-position="left" >
|
||||
<el-col :span="24" :xs="24">
|
||||
<el-form-item label="" label-width="0px" prop="brdh" >
|
||||
<el-row :gutter="5" class="compact-form" :span="24">
|
||||
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-position="left">
|
||||
<el-col :span="24" :xs="24">
|
||||
<el-form-item label="" label-width="0px" prop="brdh">
|
||||
|
||||
<el-col :span="6">
|
||||
<div> 就诊卡号/病历号/磁卡号: </div>
|
||||
<el-input
|
||||
v-model="queryParams.brdh"
|
||||
placeholder="就诊卡号/病历号/磁卡号"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</el-col>
|
||||
<el-col :span="2">
|
||||
<el-radio-group v-model="queryParams.zt" size="default">
|
||||
<el-radio v-for="(item, index) in showconfirmOptions" :key="index" :label="item.value"
|
||||
:disabled="item.disabled">{{item.label}}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-col>
|
||||
<el-col :span="1"> <div> 申请获取期限: </div></el-col>
|
||||
<el-col :span="6">
|
||||
|
||||
<el-radio-group v-model="queryParams.subday" size="default">
|
||||
<el-radio v-for="(item, index) in subdayOptions" :key="index" :label="item.value"
|
||||
:disabled="item.disabled">{{item.label}}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-col>
|
||||
<el-col :span="2">
|
||||
<el-select v-model="queryParams.cardtype" placeholder="卡类型" clearable :style="{width: '100%'}">
|
||||
<el-option v-for="(item, index) in cardtypeOptions" :key="index" :label="item.label"
|
||||
:value="item.value" :disabled="item.disabled"></el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" icon="Search" @click="readCard">读卡</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<PatSearchDialog @select="handlePatientSelect"/>
|
||||
<el-col :span="6">
|
||||
<div> 就诊卡号/病历号/磁卡号: </div>
|
||||
<el-input v-model="queryParams.brdh" placeholder="就诊卡号/病历号/磁卡号" clearable @keyup.enter="handleQuery" />
|
||||
</el-col>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="2">
|
||||
<el-radio-group v-model="queryParams.zt" size="default">
|
||||
<el-radio v-for="(item, index) in showconfirmOptions" :key="index" :label="item.value"
|
||||
:disabled="item.disabled">{{ item.label }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-col>
|
||||
<el-col :span="1">
|
||||
<div> 申请获取期限: </div>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
|
||||
</el-form>
|
||||
<el-radio-group v-model="queryParams.subday" size="default">
|
||||
<el-radio v-for="(item, index) in subdayOptions" :key="index" :label="item.value"
|
||||
:disabled="item.disabled">{{ item.label }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-col>
|
||||
<el-col :span="2">
|
||||
<el-select v-model="queryParams.cardtype" placeholder="卡类型" clearable :style="{ width: '100%' }">
|
||||
<el-option v-for="(item, index) in cardtypeOptions" :key="index" :label="item.label" :value="item.value"
|
||||
:disabled="item.disabled"></el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" icon="Search" @click="readCard">读卡</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<PatSearchDialog @select="handlePatientSelect" />
|
||||
</el-col>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
</el-form>
|
||||
</el-row>
|
||||
<el-row :gutter="5" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
icon="Search"
|
||||
@click="handleQuery"
|
||||
v-hasPermi="['system:reqmain:Search']"
|
||||
>查询</el-button>
|
||||
<el-button type="primary" plain icon="Search" @click="handleQuery"
|
||||
v-hasPermi="['system:reqmain:Search']">查询</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="success"
|
||||
plain
|
||||
icon="Printer"
|
||||
:disabled="single"
|
||||
@click="printAll"
|
||||
v-hasPermi="['system:reqmain:add']"
|
||||
>打印</el-button>
|
||||
<el-button type="success" plain icon="Printer" :disabled="single" @click="printAll"
|
||||
v-hasPermi="['system:reqmain:add']">打印</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="success"
|
||||
plain
|
||||
icon="Printer"
|
||||
:disabled="single"
|
||||
@click="printSigne"
|
||||
v-hasPermi="['system:reqmain:edit']"
|
||||
>单打条码</el-button>
|
||||
<el-button type="success" plain icon="Printer" :disabled="single" @click="printSigne"
|
||||
v-hasPermi="['system:reqmain:edit']">单打条码</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="danger"
|
||||
plain
|
||||
icon="Printer"
|
||||
:disabled="freesingle"
|
||||
@click="printBack"
|
||||
v-hasPermi="['system:reqmain:edit']"
|
||||
>单打回单</el-button>
|
||||
<el-button type="danger" plain icon="Printer" :disabled="freesingle" @click="printBack"
|
||||
v-hasPermi="['system:reqmain:edit']">单打回单</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="warning"
|
||||
plain
|
||||
icon="Delete"
|
||||
@click="cancel"
|
||||
v-hasPermi="['system:reqmain:export']"
|
||||
>取消采样</el-button>
|
||||
<el-button type="warning" plain icon="Delete" @click="cancel"
|
||||
v-hasPermi="['system:reqmain:export']">取消采样</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="5" class="table-container">
|
||||
<el-table ref="tableRef" class="compact-form my-table" :data="reqmainList" @selection-change="handleSelectionChange" @select="handleSelect" height="100%" :cell-style="tableCellStyle">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="项目名称" align="center" prop="sqxmmc" width="200" show-overflow-tooltip/>
|
||||
<el-table-column label="项目代码" align="center" prop="sqxmdh" width="100" show-overflow-tooltip/>
|
||||
<el-table-column label="项目类别" align="center" prop="cp_xmlb" />
|
||||
<el-table-column label="样本类型" align="center" prop="yblx" />
|
||||
<el-table-column label="条码号" align="center" prop="sqh" width="150" show-overflow-tooltip/>
|
||||
<el-table-column label="申请时间" align="center" prop="sqsj" width="180" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.sqsj, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="病人姓名" align="center" prop="brxm" show-overflow-tooltip/>
|
||||
<el-table-column label="申请医生" align="center" prop="sqys" :formatter="formatDict('SRD')" show-overflow-tooltip/>
|
||||
<el-table-column label="序号" align="center" prop="xh" show-overflow-tooltip/>
|
||||
<el-table-column label="数量" align="center" prop="sl" show-overflow-tooltip/>
|
||||
<el-table-column label="单价" align="center" prop="dj" show-overflow-tooltip/>
|
||||
<el-table-column label="状态" align="center" prop="zt" show-overflow-tooltip/>
|
||||
<el-table-column label="计价" align="center" prop="jjzt" >
|
||||
<template #default="scope">
|
||||
<el-checkbox :model-value="scope.row.jjzt === '1'" disabled>
|
||||
</el-checkbox>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="病人代号" align="center" prop="brdh" show-overflow-tooltip/>
|
||||
<el-table-column label="备注1" align="center" prop="detailBZ1" show-overflow-tooltip/>
|
||||
<el-table-column label="备注2" align="center" prop="detailBZ2" show-overflow-tooltip/>
|
||||
<el-table-column label="颜色" align="center" prop="cp_color" v-if="false" show-overflow-tooltip/>
|
||||
<el-table-column label="确认标识" align="center" prop="cp_cflag" v-if="false" show-overflow-tooltip/>
|
||||
<el-table-column label="科室" align="center" prop="ksdh" :formatter="formatDict('DP')" show-overflow-tooltip/>
|
||||
<el-table-column label="病人类型" align="center" prop="brly" :formatter="formatDict('PT')" show-overflow-tooltip/>
|
||||
<el-table-column label="性别" align="center" prop="brxb" :formatter="formatDict('SX')" show-overflow-tooltip/>
|
||||
<el-table-column label="生日" align="center" prop="brsr" width="180" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.brsr, '{y}-{m}-{d}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="床号" align="center" prop="ch" width="50" show-overflow-tooltip/>
|
||||
<el-table-column label="诊断" align="center" prop="zd" width="150" show-overflow-tooltip/>
|
||||
<el-table-column label="条码类别" align="center" prop="bgddh" v-if="false" show-overflow-tooltip/>
|
||||
<el-table-column label="年龄" align="center" prop="nl" show-overflow-tooltip/>
|
||||
<el-table-column label="年龄单位" align="center" prop="nldw" :formatter="formatDict('AU')" show-overflow-tooltip/>
|
||||
<el-table-column label="采样时间" align="center" prop="cysj" width="180"show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.cysj, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-table ref="tableRef" class="compact-form my-table" :data="reqmainList"
|
||||
@selection-change="handleSelectionChange" @select="handleSelect" height="100%" :cell-style="tableCellStyle">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="项目名称" align="center" prop="sqxmmc" width="200" show-overflow-tooltip />
|
||||
<el-table-column label="项目代码" align="center" prop="sqxmdh" width="100" show-overflow-tooltip />
|
||||
<el-table-column label="项目类别" align="center" prop="cp_xmlb" />
|
||||
<el-table-column label="样本类型" align="center" prop="yblx" />
|
||||
<el-table-column label="条码号" align="center" prop="sqh" width="150" show-overflow-tooltip />
|
||||
<el-table-column label="申请时间" align="center" prop="sqsj" width="180" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.sqsj, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="病人姓名" align="center" prop="brxm" show-overflow-tooltip />
|
||||
<el-table-column label="申请医生" align="center" prop="sqys" :formatter="formatDict('SRD')" show-overflow-tooltip />
|
||||
<el-table-column label="序号" align="center" prop="xh" show-overflow-tooltip />
|
||||
<el-table-column label="数量" align="center" prop="sl" show-overflow-tooltip />
|
||||
<el-table-column label="单价" align="center" prop="dj" show-overflow-tooltip />
|
||||
<el-table-column label="状态" align="center" prop="zt" show-overflow-tooltip />
|
||||
<el-table-column label="计价" align="center" prop="jjzt">
|
||||
<template #default="scope">
|
||||
<el-checkbox :model-value="scope.row.jjzt === '1'" disabled>
|
||||
</el-checkbox>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="病人代号" align="center" prop="brdh" show-overflow-tooltip />
|
||||
<el-table-column label="备注1" align="center" prop="detailBZ1" show-overflow-tooltip />
|
||||
<el-table-column label="备注2" align="center" prop="detailBZ2" show-overflow-tooltip />
|
||||
<el-table-column label="颜色" align="center" prop="cp_color" v-if="false" show-overflow-tooltip />
|
||||
<el-table-column label="确认标识" align="center" prop="cp_cflag" v-if="false" show-overflow-tooltip />
|
||||
<el-table-column label="科室" align="center" prop="ksdh" :formatter="formatDict('DP')" show-overflow-tooltip />
|
||||
<el-table-column label="病人类型" align="center" prop="brly" :formatter="formatDict('PT')" show-overflow-tooltip />
|
||||
<el-table-column label="性别" align="center" prop="brxb" :formatter="formatDict('SX')" show-overflow-tooltip />
|
||||
<el-table-column label="生日" align="center" prop="brsr" width="180" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.brsr, '{y}-{m}-{d}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="床号" align="center" prop="ch" width="50" show-overflow-tooltip />
|
||||
<el-table-column label="诊断" align="center" prop="zd" width="150" show-overflow-tooltip />
|
||||
<el-table-column label="条码类别" align="center" prop="bgddh" v-if="false" show-overflow-tooltip />
|
||||
<el-table-column label="年龄" align="center" prop="nl" show-overflow-tooltip />
|
||||
<el-table-column label="年龄单位" align="center" prop="nldw" :formatter="formatDict('AU')" show-overflow-tooltip />
|
||||
<el-table-column label="采样时间" align="center" prop="cysj" width="180" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.cysj, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-row>
|
||||
<!-- 汇总行 -->
|
||||
<div class="table-summary">
|
||||
@ -172,6 +142,7 @@ import {
|
||||
printBarcodeall
|
||||
} from "@/api/mzcx/cydj.js";
|
||||
import PatSearchDialog from './components/OutPatList.vue'
|
||||
import { classCom } from '@/utils/classCom';
|
||||
const comDict = inject('comDict');
|
||||
// 字典数据存储
|
||||
const dictData = ref({});
|
||||
@ -190,9 +161,9 @@ const idsnew = computed(() => {
|
||||
});
|
||||
const single = ref(true);
|
||||
const freesingle = ref(true);
|
||||
const cardtypeOptions = ref([{"label": "就诊卡","value": 1},{"label": "医保卡","value": 2},{"label": "电子医保卡","value": 3},{"label": "身份证", "value": 4}])
|
||||
const showconfirmOptions = ref([{"label": "未打印", "value": 1},{"label": "已打印", "value": 11}])
|
||||
const subdayOptions = ref([{"label": "1天","value": 1},{"label": "3天", "value": 3},{"label": "1周","value": 7},{"label": "2周","value": 14},{"label": "1月", "value": 30},{"label": "3月", "value": 90},{"label": "1年","value": 365},{"label": "2年","value": 730}])
|
||||
const cardtypeOptions = ref([{ "label": "就诊卡", "value": 1 }, { "label": "医保卡", "value": 2 }, { "label": "电子医保卡", "value": 3 }, { "label": "身份证", "value": 4 }])
|
||||
const showconfirmOptions = ref([{ "label": "未打印", "value": 1 }, { "label": "已打印", "value": 11 }])
|
||||
const subdayOptions = ref([{ "label": "1天", "value": 1 }, { "label": "3天", "value": 3 }, { "label": "1周", "value": 7 }, { "label": "2周", "value": 14 }, { "label": "1月", "value": 30 }, { "label": "3月", "value": 90 }, { "label": "1年", "value": 365 }, { "label": "2年", "value": 730 }])
|
||||
|
||||
const data = reactive({
|
||||
form: {},
|
||||
@ -203,7 +174,7 @@ const data = reactive({
|
||||
klx: null,
|
||||
zt: 1,
|
||||
subday: 3000,
|
||||
cardtype:null
|
||||
cardtype: null
|
||||
},
|
||||
rules: {
|
||||
brdh: [
|
||||
@ -232,7 +203,7 @@ const handleSelect = (selection, row, selected) => {
|
||||
|
||||
// 先收集需要自动勾选的行(避免在循环中修改数据)
|
||||
const rowsToSelect = reqmainList.value.filter(
|
||||
item => item.sqh === targetSqh && item.xh !== targetxh
|
||||
item => item.sqh === targetSqh && item.xh !== targetxh
|
||||
);
|
||||
|
||||
// 如果有需要自动勾选的行,才开启标志位
|
||||
@ -246,10 +217,10 @@ const handleSelect = (selection, row, selected) => {
|
||||
}
|
||||
};
|
||||
// 字典格式化方法
|
||||
const formatDict =(dictType) => {
|
||||
const formatDict = (dictType) => {
|
||||
return (row, column, value) => {
|
||||
// 从全局字典中获取映射值
|
||||
return dictData.value[dictType].find(item => String(item.value) === String(value).trim())?.label||value ;
|
||||
return dictData.value[dictType].find(item => String(item.value) === String(value).trim())?.label || value;
|
||||
};
|
||||
};
|
||||
// 定义“空数据”的判断函数
|
||||
@ -277,30 +248,30 @@ function getDateOffset(days) {
|
||||
const year = targetDate.getFullYear();
|
||||
const month = String(targetDate.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(targetDate.getDate()).padStart(2, '0');
|
||||
// const hours = String(targetDate.getHours()).padStart(2, '0');
|
||||
// const minutes = String(targetDate.getMinutes()).padStart(2, '0');
|
||||
// const hours = String(targetDate.getHours()).padStart(2, '0');
|
||||
// const minutes = String(targetDate.getMinutes()).padStart(2, '0');
|
||||
//const seconds = String(targetDate.getSeconds()).padStart(2, '0');
|
||||
// return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
||||
// return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
||||
return `${year}-${month}-${day} 00:00:00`;
|
||||
}
|
||||
function getSubday() {
|
||||
const days=0 - queryParams.value.subday;
|
||||
queryParams.value.stime=getDateOffset(days);
|
||||
queryParams.value.etime=getDateOffset(1);
|
||||
const days = 0 - queryParams.value.subday;
|
||||
queryParams.value.stime = getDateOffset(days);
|
||||
queryParams.value.etime = getDateOffset(1);
|
||||
}
|
||||
/** 查询采样登记列表 */
|
||||
function getList() {
|
||||
freesingle.value=true;
|
||||
if(isEmptyData(queryParams.value.brdh)) proxy.$modal.alert("请刷卡或输入门诊号!");
|
||||
freesingle.value = true;
|
||||
if (isEmptyData(queryParams.value.brdh)) proxy.$modal.alert("请刷卡或输入门诊号!");
|
||||
else {
|
||||
loading.value = true;
|
||||
getSubday();
|
||||
querySQD(queryParams.value).then(response => {
|
||||
if (isEmptyData(response.data)) proxy.$modal.alert("没有检索的数据!");
|
||||
reqmainList.value = response.data;
|
||||
// console.log('response:', response.data);
|
||||
// console.log('response:', response.data);
|
||||
loading.value = false;
|
||||
single.value=false;
|
||||
single.value = false;
|
||||
// 新增:数据加载完成后触发全选
|
||||
// 延迟执行(确保DOM已更新)
|
||||
setTimeout(() => {
|
||||
@ -314,8 +285,8 @@ function getList() {
|
||||
|
||||
// 取消按钮
|
||||
function cancel() {
|
||||
// open.value = false;
|
||||
// reset();
|
||||
// open.value = false;
|
||||
// reset();
|
||||
}
|
||||
|
||||
// 表单重置
|
||||
@ -360,8 +331,8 @@ function reset() {
|
||||
zd: null,
|
||||
cysj: null
|
||||
};
|
||||
freesingle.value=false;
|
||||
single.value=false;
|
||||
freesingle.value = false;
|
||||
single.value = false;
|
||||
proxy.resetForm("reqmainRef");
|
||||
}
|
||||
|
||||
@ -376,8 +347,8 @@ function readCard() {
|
||||
|
||||
// 处理病人选择事件
|
||||
const handlePatientSelect = (patient) => {
|
||||
// console.log('选中的病人:', patient);
|
||||
queryParams.value.brdh=patient
|
||||
// console.log('选中的病人:', patient);
|
||||
queryParams.value.brdh = patient
|
||||
// 处理选中的病人数据
|
||||
handleQuery();
|
||||
};
|
||||
@ -404,7 +375,7 @@ function printSigne(row) {
|
||||
printBarcodeall(idsnew.value).then(response => {
|
||||
proxy.$modal.msgSuccess("打印成功");
|
||||
open.value = false;
|
||||
freesingle.value=false;
|
||||
freesingle.value = false;
|
||||
}).catch(() => {
|
||||
});
|
||||
}
|
||||
@ -412,16 +383,16 @@ function printSigne(row) {
|
||||
|
||||
/** 打印回单 */
|
||||
function printBack(row) {
|
||||
if (idsnew.value.length === 0) {
|
||||
return;
|
||||
}
|
||||
if (idsnew.value.length === 0) {
|
||||
return;
|
||||
}
|
||||
//console.log('idsnew:', idsnew.value)
|
||||
printBackpaper(idsnew.value).then(response => {
|
||||
proxy.$modal.msgSuccess("打印成功");
|
||||
open.value = false;
|
||||
}).catch(() => {
|
||||
});
|
||||
}
|
||||
proxy.$modal.msgSuccess("打印成功");
|
||||
open.value = false;
|
||||
}).catch(() => {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
const totalRows = computed(() => {
|
||||
@ -439,8 +410,8 @@ const totalPrice = computed(() => {
|
||||
// 组件挂载时加载字典
|
||||
onMounted(async () => {
|
||||
// 加载病人来源字典
|
||||
const dictRefs = await comDict('PT', 'DP', 'SRD','BT','SX','AU');
|
||||
// 从 ref 中获取实际数据
|
||||
const dictRefs = await comDict('PT', 'DP', 'SRD', 'BT', 'SX', 'AU');
|
||||
// 从 ref 中获取实际数据
|
||||
dictData.value = {
|
||||
PT: toRaw(dictRefs.PT.value) || [],
|
||||
DP: toRaw(dictRefs.DP.value) || [],
|
||||
@ -458,9 +429,9 @@ const tableCellStyle = ({ row, column }) => {
|
||||
// 只对“项目类别”列生效
|
||||
if (column.label === '项目类别') {
|
||||
// 1. 转换颜色(十进制→十六进制)
|
||||
const bgColor = decimalToHexColor(row.cp_color);
|
||||
const bgColor = classCom.decimalToHexColor(row.cp_color);
|
||||
// 2. 自动计算文字颜色(确保和背景色对比度足够)
|
||||
const textColor = getContrastTextColor(bgColor);
|
||||
const textColor = classCom.getContrastTextColor(bgColor);
|
||||
|
||||
return {
|
||||
backgroundColor: bgColor, // 背景色(转换后的值)
|
||||
@ -472,39 +443,6 @@ const tableCellStyle = ({ row, column }) => {
|
||||
return {}; // 其他列保持默认样式
|
||||
};
|
||||
|
||||
// 十进制颜色值转十六进制颜色码(适配BGR转RGB)
|
||||
const decimalToHexColor = (decimal) => {
|
||||
if (!decimal && decimal !== 0) return '#FFFFFF'; // 空值默认白色
|
||||
|
||||
// 1. 十进制转十六进制(去除前缀0x,大写)
|
||||
let hex = parseInt(decimal, 10).toString(16).toUpperCase();
|
||||
|
||||
// 2. 不足6位则前面补0(确保是6位)
|
||||
if (hex.length < 6) {
|
||||
hex = hex.padStart(6, '0'); // 例如:192→"C0"→补0为"0000C0"
|
||||
}
|
||||
|
||||
// 3. BGR转RGB(反转字节顺序:前两位和后两位交换)
|
||||
// 例:80FFFF → 拆分为80、FF、FF → 反转后FF、FF、80 → FFFF80
|
||||
const r = hex.substring(4, 6); // 取后两位
|
||||
const g = hex.substring(2, 4); // 取中间两位
|
||||
const b = hex.substring(0, 2); // 取前两位
|
||||
const rgbHex = r + g + b;
|
||||
|
||||
return `#${rgbHex}`; // 最终颜色码
|
||||
};
|
||||
// 辅助函数:根据背景色计算文字颜色(黑/白)
|
||||
const getContrastTextColor = (bgColor) => {
|
||||
// 提取RGB值(如#FFFF80 → R=255, G=255, B=128)
|
||||
const r = parseInt(bgColor.slice(1, 3), 16);
|
||||
const g = parseInt(bgColor.slice(3, 5), 16);
|
||||
const b = parseInt(bgColor.slice(5, 7), 16);
|
||||
|
||||
// 计算亮度(标准公式)
|
||||
const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
|
||||
// 亮度>0.5用黑色,否则用白色(确保清晰)
|
||||
return luminance > 0.5 ? '#333333' : '#FFFFFF';
|
||||
};
|
||||
|
||||
</script>
|
||||
|
||||
@ -512,21 +450,31 @@ const getContrastTextColor = (bgColor) => {
|
||||
.app-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 90vh; /* 容器高度等于窗口高度 */
|
||||
height: 90vh;
|
||||
/* 容器高度等于窗口高度 */
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.compact-form {
|
||||
height: 75px; /* 固定高度 */
|
||||
height: 75px;
|
||||
/* 固定高度 */
|
||||
}
|
||||
|
||||
.mb8 {
|
||||
height: 30px; /* 固定高度 */
|
||||
height: 30px;
|
||||
/* 固定高度 */
|
||||
}
|
||||
.table-summary{
|
||||
height: 10px; /* 固定高度 */
|
||||
|
||||
.table-summary {
|
||||
height: 10px;
|
||||
/* 固定高度 */
|
||||
}
|
||||
|
||||
.table-container {
|
||||
flex: 1; /* 占满剩余高度 */
|
||||
overflow: hidden; /* 避免表格超出容器 */
|
||||
flex: 1;
|
||||
/* 占满剩余高度 */
|
||||
overflow: hidden;
|
||||
/* 避免表格超出容器 */
|
||||
}
|
||||
|
||||
.compact-form .el-form-item {
|
||||
@ -537,22 +485,32 @@ const getContrastTextColor = (bgColor) => {
|
||||
.compact-form .el-form-item__label {
|
||||
padding-bottom: 0px;
|
||||
}
|
||||
|
||||
::v-deep .my-table .el-table__row td {
|
||||
padding: 1px 0; /* 减小行高 */
|
||||
padding: 1px 0;
|
||||
/* 减小行高 */
|
||||
}
|
||||
|
||||
::v-deep .my-table .el-table__header-wrapper th {
|
||||
padding: 6px 0; /* 表头内边距 */
|
||||
background-color: #b3d8ff !important; /* 表头背景色(保留之前的设置) */
|
||||
color: #333; /* 文字颜色加深,提升可读性 */
|
||||
font-weight: 500; /* 文字加粗 */
|
||||
padding: 6px 0;
|
||||
/* 表头内边距 */
|
||||
background-color: #b3d8ff !important;
|
||||
/* 表头背景色(保留之前的设置) */
|
||||
color: #333;
|
||||
/* 文字颜色加深,提升可读性 */
|
||||
font-weight: 500;
|
||||
/* 文字加粗 */
|
||||
}
|
||||
|
||||
::v-deep .my-table .el-table__cell {
|
||||
padding: 0 2px; /* 减小列间距 */
|
||||
padding: 0 2px;
|
||||
/* 减小列间距 */
|
||||
}
|
||||
|
||||
/* 可选:调整表格整体样式 */
|
||||
::v-deep .my-table {
|
||||
font-size: 13px; /* 适当减小字体 */
|
||||
font-size: 13px;
|
||||
/* 适当减小字体 */
|
||||
}
|
||||
|
||||
::v-deep .my-table .el-table__cell,
|
||||
@ -560,17 +518,25 @@ const getContrastTextColor = (bgColor) => {
|
||||
border-width: 1px;
|
||||
border-color: #ebeef5;
|
||||
}
|
||||
|
||||
.card-content {
|
||||
max-height: 450px; /* 设置最大高度 */
|
||||
overflow-y: auto; /* 超出高度时显示垂直滚动条 */
|
||||
padding: 5px; /* 保持与卡片默认一致的内边距 */
|
||||
max-height: 450px;
|
||||
/* 设置最大高度 */
|
||||
overflow-y: auto;
|
||||
/* 超出高度时显示垂直滚动条 */
|
||||
padding: 5px;
|
||||
/* 保持与卡片默认一致的内边距 */
|
||||
}
|
||||
|
||||
.clickable:hover {
|
||||
cursor: pointer; /* 鼠标悬停时显示手型 */
|
||||
transition: all 0.3s; /* 平滑过渡效果 */
|
||||
cursor: pointer;
|
||||
/* 鼠标悬停时显示手型 */
|
||||
transition: all 0.3s;
|
||||
/* 平滑过渡效果 */
|
||||
color: blue;
|
||||
|
||||
}
|
||||
|
||||
/* 汇总行样式 */
|
||||
.table-summary {
|
||||
display: flex;
|
||||
@ -582,7 +548,9 @@ const getContrastTextColor = (bgColor) => {
|
||||
border: 1px solid #ebeef5;
|
||||
border-radius: 4px;
|
||||
font-weight: 500;
|
||||
line-height: 24px; /* 汇总行文字行高 */
|
||||
line-height: 24px;
|
||||
|
||||
/* 汇总行文字行高 */
|
||||
.summary-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@ -596,12 +564,16 @@ const getContrastTextColor = (bgColor) => {
|
||||
.summary-value {
|
||||
color: #303133;
|
||||
min-width: 40px;
|
||||
text-align: left;/* 核心:数值左对齐 */
|
||||
text-align: left;
|
||||
/* 核心:数值左对齐 */
|
||||
}
|
||||
|
||||
/* 单独设置"单价合计"的值为红色 */
|
||||
&:nth-child(3) .summary-value {
|
||||
color: #f56c6c; /* Element UI 红色主题色 */
|
||||
font-weight: 600; /* 可选:加粗字体 */
|
||||
color: #f56c6c;
|
||||
/* Element UI 红色主题色 */
|
||||
font-weight: 600;
|
||||
/* 可选:加粗字体 */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
561
src/views/mzcx/reportRules/index.vue
Normal file
561
src/views/mzcx/reportRules/index.vue
Normal file
@ -0,0 +1,561 @@
|
||||
<template>
|
||||
<div class="rule-management-container">
|
||||
<!-- 顶部操作栏 -->
|
||||
<div class="mb20">
|
||||
<el-button type="primary" icon="Search" @click="handleQuery"> 查询</el-button>
|
||||
<el-button type="success" icon="Plus" @click="addgz">新增</el-button>
|
||||
<el-button type="primary" icon="Select" @click="saveHandle">保存</el-button>
|
||||
<!-- :disabled="flag" -->
|
||||
<el-button icon="Plus" @click="addDetail">新增明细</el-button>
|
||||
</div>
|
||||
|
||||
<!-- 左右分栏区域 -->
|
||||
<div class="content-wrapper">
|
||||
<!-- 左侧表格 -->
|
||||
<div class="left-table-area">
|
||||
<el-table :data="ruleList" @row-click="handleRowClick" border style="width: 100%" highlight-current-row
|
||||
class="custom-table">
|
||||
<el-table-column prop="bglqdh" label="规则代号" width="100" />
|
||||
<el-table-column prop="bglqmc" label="规则名称" width="200" />
|
||||
<el-table-column prop="bz" label="备注" />
|
||||
<el-table-column label="操作" align="center" fixed="right" width="100">
|
||||
<template #default="scope">
|
||||
<el-button size="small" type="danger" @click="handleDelete(scope.row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
|
||||
<!-- 右侧表单与明细表格 -->
|
||||
<div class="right-form-area">
|
||||
<el-form :model="currentRule" label-width="80px" class="rule-form">
|
||||
<el-form-item label="规则代号">
|
||||
<el-input v-model="currentRule.bglqdh" disabled />
|
||||
</el-form-item>
|
||||
<el-form-item label="规则名称">
|
||||
<el-input v-model="currentRule.bglqmc" @blur="editHandle(currentRule, 'bglqmc')"
|
||||
@keyup.enter="editHandle(currentRule, 'bglqmc')" />
|
||||
</el-form-item>
|
||||
<el-form-item label="备注">
|
||||
<el-input type="textarea" v-model="currentRule.bz" :rows="2" @blur="editHandle(currentRule, 'bz')"
|
||||
@keyup.enter="editHandle(currentRule, 'bz')" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<div class="detail-table-header">
|
||||
<span>规则明细</span>
|
||||
</div>
|
||||
|
||||
<el-table :data="detailList" border style="width: 100%;" class="detail-table" :cell-class-name="cellClassName">
|
||||
<el-table-column prop="weekday" label="起始日期" width="100">
|
||||
<template #default="scope">
|
||||
<el-select v-model="scope.row.weekday" placeholder="选择星期" size="small" class="week-select"
|
||||
@change="handleDetailChange(scope.row)">
|
||||
<el-option v-for="day in weekDays" :key="day.value" :label="day.label" :value="day.value" />
|
||||
</el-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="weekday1" label="截止日期" width="100">
|
||||
<template #default="scope">
|
||||
<el-select v-model="scope.row.weekday1" placeholder="选择星期" size="small" class="week-select"
|
||||
@change="handleDetailChange(scope.row)">
|
||||
<el-option v-for="day in weekDays" :key="day.value" :label="day.label" :value="day.value" />
|
||||
</el-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="kssj" label="起始时间" width="100">
|
||||
<template #default="scope">
|
||||
<el-input v-model="scope.row.kssj" placeholder="HH:mm" size="small"
|
||||
@input="handleTimeInput(scope.row, 'kssj')" maxlength="5" class="time-input" @focus="handleInputFocus"
|
||||
@blur="handleInputBlur(scope.row, 'kssj')" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="jssj" label="截止时间" width="100">
|
||||
<template #default="scope">
|
||||
<el-input v-model="scope.row.jssj" placeholder="HH:mm" size="small"
|
||||
@input="handleTimeInput(scope.row, 'jssj')" maxlength="5" class="time-input" @focus="handleInputFocus"
|
||||
@blur="handleInputBlur(scope.row, 'jssj')" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="bglqsm" label="报告领取声明">
|
||||
<template #default="scope">
|
||||
<el-input v-model="scope.row.bglqsm" size="small" class="statement-input" @focus="handleInputFocus" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="bgxss" label="所需小时数" width="100">
|
||||
<template #default="scope">
|
||||
<el-input v-model="scope.row.bgxss" placeholder="0" size="small"
|
||||
@input="handleNumberInput(scope.row, 'bgxss')" class="number-input" @focus="handleInputFocus" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="操作" align="center" width="100">
|
||||
<template #default="scope">
|
||||
<el-button size="small" type="danger" @click="delDetail(scope.row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted, computed } from 'vue'
|
||||
import { rptgetruleList, rptgetruleadd, rptgetruleUpdate, rptgetruleDel, rptgetruleDetail, rptgetruleDelDetail } from '@/api/mzcx/index';
|
||||
import { ElMessageBox, ElMessage } from 'element-plus'
|
||||
// 星期选项数据
|
||||
const weekDays = [
|
||||
{ label: '周一', value: '1' },
|
||||
{ label: '周二', value: '2' },
|
||||
{ label: '周三', value: '3' },
|
||||
{ label: '周四', value: '4' },
|
||||
{ label: '周五', value: '5' },
|
||||
{ label: '周六', value: '6' },
|
||||
{ label: '周日', value: '7' }
|
||||
]
|
||||
interface Rule {
|
||||
bglqdh: number,
|
||||
bglqmc: string,
|
||||
bz: string,
|
||||
status: boolean,
|
||||
originalData: object,
|
||||
addFlag: boolean
|
||||
}
|
||||
// 模拟规则列表数据
|
||||
const ruleList = ref<Rule[]>([])
|
||||
|
||||
// 当前选中的规则数据
|
||||
const currentRule = ref({
|
||||
bglqdh: 1,
|
||||
bglqmc: '',
|
||||
bz: '',
|
||||
})
|
||||
interface Detail {
|
||||
weekday: string,
|
||||
weekday1: string,
|
||||
kssj: string,
|
||||
jssj: string,
|
||||
bglqsm: string,
|
||||
bgxss: number,
|
||||
bglqdh: number,
|
||||
xh: number,
|
||||
detaiFlag: boolean
|
||||
status: boolean // 新增:标识明细是否被修改
|
||||
}
|
||||
const detailList = ref<Detail[]>([])
|
||||
const rptgetruledetail = ref<Detail[]>([])
|
||||
// 是否正在编辑输入框
|
||||
const isEditing = ref(false)
|
||||
const handleQuery = () => {
|
||||
getList()
|
||||
}
|
||||
|
||||
|
||||
// 处理时间输入,限制为HH:mm格式
|
||||
const handleTimeInput = (row: any, field: string) => {
|
||||
// 移除非数字和非冒号字符
|
||||
let value = row[field].replace(/[^0-9:]/g, '')
|
||||
|
||||
// 自动添加冒号
|
||||
if (value.length === 2 && !value.includes(':')) {
|
||||
value += ':'
|
||||
}
|
||||
|
||||
row[field] = value
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 处理时间输入失去焦点时的格式化
|
||||
const handleInputBlur = (row: any, field: string) => {
|
||||
isEditing.value = false
|
||||
let value = row[field]
|
||||
|
||||
// 补全时间格式
|
||||
if (field === 'kssj' || field === 'jssj') {
|
||||
if (value.length === 1) {
|
||||
value = `0${value}:00`
|
||||
} else if (value.length === 2 && !value.includes(':')) {
|
||||
value += ':00'
|
||||
} else if (value.length === 3 && value.includes(':')) {
|
||||
value += '0'
|
||||
}
|
||||
|
||||
// 验证小时和分钟范围
|
||||
if (value.includes(':')) {
|
||||
const [hours, minutes] = value.split(':')
|
||||
const validHours = Math.min(Math.max(parseInt(hours) || 0, 0), 23).toString().padStart(2, '0')
|
||||
const validMinutes = Math.min(Math.max(parseInt(minutes) || 0, 0), 59).toString().padStart(2, '0')
|
||||
value = `${validHours}:${validMinutes}`
|
||||
} else {
|
||||
value = '00:00'
|
||||
}
|
||||
row[field] = value
|
||||
row.status = true;
|
||||
}
|
||||
czList()
|
||||
}
|
||||
|
||||
// 处理数字输入,限制为数字
|
||||
const handleNumberInput = (row: any, field: string) => {
|
||||
// 只保留数字和小数点
|
||||
row[field] = row[field].replace(/[^0-9.]/g, '')
|
||||
|
||||
// 确保只有一个小数点
|
||||
const dotIndex = row[field].indexOf('.')
|
||||
if (dotIndex !== -1 && row[field].lastIndexOf('.') !== dotIndex) {
|
||||
row[field] = row[field].slice(0, row[field].lastIndexOf('.'))
|
||||
row.status = true;
|
||||
}
|
||||
|
||||
czList()
|
||||
}
|
||||
|
||||
// 处理明细变化
|
||||
const handleDetailChange = (row: any) => {
|
||||
row.status = true;
|
||||
czList()
|
||||
}
|
||||
|
||||
// 输入框获得焦点
|
||||
const handleInputFocus = () => {
|
||||
isEditing.value = true
|
||||
}
|
||||
|
||||
// 单元格样式类
|
||||
const cellClassName = () => {
|
||||
return 'no-edit-cell'
|
||||
}
|
||||
|
||||
// 行点击事件,实现右侧联动
|
||||
const handleRowClick = (row: any) => {
|
||||
const { bglqdh, bglqmc, bz } = row
|
||||
currentRule.value = row
|
||||
row.originalData = JSON.parse(JSON.stringify(row));
|
||||
getgzList(row)
|
||||
}
|
||||
// 新增规则
|
||||
const addgz = () => {
|
||||
ruleList.value.unshift(
|
||||
{
|
||||
bglqdh: Math.max(...ruleList.value.map((item: any) => item.bglqdh), 0) + 1,
|
||||
bglqmc: 'test',
|
||||
bz: '',
|
||||
status: true,
|
||||
originalData: {},
|
||||
addFlag: true
|
||||
}
|
||||
)
|
||||
currentRule.value = ruleList.value[0]
|
||||
detailList.value = [
|
||||
{
|
||||
bglqdh: Math.max(...ruleList.value.map((item: any) => item.bglqdh), 0),
|
||||
weekday: '1',
|
||||
weekday1: '2',
|
||||
kssj: '09:00',
|
||||
jssj: '18:00',
|
||||
bglqsm: '领取声明',
|
||||
bgxss: 1,
|
||||
xh: detailList.value.length,
|
||||
detaiFlag: true,
|
||||
status: false
|
||||
}
|
||||
]
|
||||
rptgetruledetail.value.push(...detailList.value)
|
||||
}
|
||||
|
||||
// 新增规则明细
|
||||
const addDetail = () => {
|
||||
detailList.value.push({
|
||||
bglqdh: currentRule.value.bglqdh,
|
||||
weekday: '1',
|
||||
weekday1: '2',
|
||||
kssj: '09:00',
|
||||
jssj: '18:00',
|
||||
bglqsm: '领取声明',
|
||||
bgxss: 1,
|
||||
xh: detailList.value.length + 1,
|
||||
detaiFlag: false,
|
||||
status: false
|
||||
})
|
||||
ruleList.value.forEach((item: any) => {
|
||||
if (item.bglqdh == currentRule.value.bglqdh) {
|
||||
item.status = true
|
||||
}
|
||||
});
|
||||
rptgetruledetail.value.push(...detailList.value)
|
||||
}
|
||||
|
||||
const editHandle = (row: any, field: string) => {
|
||||
ruleList.value.forEach((item: any) => {
|
||||
if (item.bglqdh == row.bglqdh) {
|
||||
item[field] = row[field]
|
||||
item.status = JSON.stringify(row[field]) !== JSON.stringify(item.originalData[field]);
|
||||
}
|
||||
});
|
||||
czList()
|
||||
}
|
||||
|
||||
const czList = () => {
|
||||
ruleList.value.forEach((item: any) => {
|
||||
if (item.bglqdh == currentRule.value.bglqdh) {
|
||||
item.status = true
|
||||
}
|
||||
});
|
||||
rptgetruledetail.value = rptgetruledetail.value.filter((item: any) => item.bglqdh !== currentRule.value.bglqdh)
|
||||
rptgetruledetail.value.push(...detailList.value)
|
||||
}
|
||||
|
||||
// 保存
|
||||
const saveHandle = () => {
|
||||
const addList = ruleList.value.filter((item: any) => item.addFlag)
|
||||
const updateList = ruleList.value.filter((item: any) => item.status && !item.addFlag)
|
||||
const addDetailList = rptgetruledetail.value.filter((item: any) => item.detaiFlag)
|
||||
const upadteDetailList = rptgetruledetail.value.filter((item: any) => !item.detaiFlag)
|
||||
|
||||
// 保存成功后的回调处理
|
||||
const handleSuccess = () => {
|
||||
// 重置规则的新增/修改状态
|
||||
ruleList.value.forEach(item => {
|
||||
item.addFlag = false;
|
||||
item.status = false;
|
||||
});
|
||||
// 重置明细的新增/修改状态
|
||||
detailList.value.forEach(item => {
|
||||
item.detaiFlag = false;
|
||||
item.status = false;
|
||||
});
|
||||
ElMessage.success('保存成功');
|
||||
};
|
||||
if (updateList.length > 0) {
|
||||
rptgetruleUpdate({ ruleList: updateList, ruleDetailList: upadteDetailList }).then((res: any) => {
|
||||
if (res.code == 0) {
|
||||
handleSuccess()
|
||||
}
|
||||
})
|
||||
} if (addList.length > 0) {
|
||||
rptgetruleadd({ ruleList: addList, ruleDetailList: addDetailList }).then((res: any) => {
|
||||
if (res.code == 0) {
|
||||
handleSuccess()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
// 删除规则
|
||||
const handleDelete = (row: any) => {
|
||||
ElMessageBox.confirm(
|
||||
`确定删除${row.bglqdh}数据吗?`,
|
||||
'提示',
|
||||
{
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
}
|
||||
)
|
||||
.then(() => {
|
||||
const handleSueess = () => {
|
||||
ruleList.value = ruleList.value.filter((item: any) => item.bglqdh !== row.bglqdh)
|
||||
handleRowClick(ruleList.value[0])
|
||||
};
|
||||
if (row.addFlag) {
|
||||
handleSueess()
|
||||
} else {
|
||||
rptgetruleDel({ bglqdh: row.bglqdh }).then((res: any) => {
|
||||
if (res.code == 0) {
|
||||
ElMessage.success('删除成功');
|
||||
handleSueess()
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
|
||||
})
|
||||
};
|
||||
// 删除规则明细
|
||||
const delDetail = (row: any) => {
|
||||
ElMessageBox.confirm(
|
||||
`确定删除该项数据吗?`, "提示",
|
||||
{
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
}
|
||||
)
|
||||
.then(() => {
|
||||
const handleSueess = () => {
|
||||
detailList.value = detailList.value.filter((item: any) => item.xh !== row.xh)
|
||||
};
|
||||
if (row.detaiFlag) {
|
||||
handleSueess()
|
||||
} else {
|
||||
rptgetruleDelDetail({ bglqdh: row.bglqdh, xh: row.xh }).then((res: any) => {
|
||||
if (res.code == 0) {
|
||||
ElMessage.success('删除成功');
|
||||
handleSueess()
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
|
||||
})
|
||||
|
||||
};
|
||||
const getList = () => {
|
||||
rptgetruleList().then((res: any) => {
|
||||
if (res.code == 0) {
|
||||
ruleList.value = res.data
|
||||
ruleList.value.forEach((item: any) => {
|
||||
item.originalData = {}
|
||||
item.status = false
|
||||
})
|
||||
handleRowClick(ruleList.value[0])
|
||||
getgzList(res.data[0])
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const getgzList = (info: any) => {
|
||||
if (info.status) {
|
||||
detailList.value = rptgetruledetail.value.filter((item: any) => item.bglqdh == info.bglqdh)
|
||||
} else {
|
||||
rptgetruleDetail({ bglqdh: info.bglqdh }).then((res: any) => {
|
||||
if (res.code == 0) {
|
||||
detailList.value = res.data
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
getList()
|
||||
// 初始化默认选中第一行
|
||||
onMounted(() => {
|
||||
|
||||
})
|
||||
|
||||
|
||||
// 替换原flag的定义,改为计算属性
|
||||
const flag = computed(() => {
|
||||
|
||||
// 检查是否有新增规则
|
||||
const hasNewRule = ruleList.value.some(item => item.addFlag);
|
||||
// 检查是否有修改的规则
|
||||
const hasUpdatedRule = ruleList.value.some(item => item.status);
|
||||
// 检查是否有新增明细
|
||||
const hasNewDetail = detailList.value.some(item => item.detaiFlag);
|
||||
// 检查是否有修改的明细
|
||||
const hasUpdatedDetail = detailList.value.some(item => item.status);
|
||||
|
||||
// 当存在任何新增或修改时,按钮可点击(返回false),否则禁用(返回true)
|
||||
return !(hasNewRule || hasUpdatedRule || hasNewDetail || hasUpdatedDetail);
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.rule-management-container {
|
||||
height: 90vh;
|
||||
/* display: flex;
|
||||
flex-direction: column; */
|
||||
padding: 10px;
|
||||
box-sizing: border-box;
|
||||
/* background-color: #f0f2f5; */
|
||||
}
|
||||
|
||||
.top-toolbar {
|
||||
padding: 8px 15px;
|
||||
background-color: #FFF;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
/* ::v-deep .top-toolbar .el-button {
|
||||
margin-right: 8px;
|
||||
} */
|
||||
|
||||
.content-wrapper {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
height: calc(100% - 100px);
|
||||
}
|
||||
|
||||
.left-table-area {
|
||||
width: 50%;
|
||||
background-color: #fff;
|
||||
border: 1px solid #e6e6e6;
|
||||
border-radius: 4px;
|
||||
padding: 5px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.right-form-area {
|
||||
width: 50%;
|
||||
background-color: #e6f7ff;
|
||||
border: 1px solid #91d5ff;
|
||||
border-radius: 4px;
|
||||
padding: 15px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.rule-form {
|
||||
background-color: #fff;
|
||||
padding: 15px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #d9d9d9;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.detail-table-header {
|
||||
padding: 8px 0;
|
||||
font-weight: 500;
|
||||
color: #1890ff;
|
||||
border-bottom: 1px solid #91d5ff;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
::v-deep .custom-table th {
|
||||
background-color: #f5f7fa;
|
||||
}
|
||||
|
||||
::v-deep .detail-table th {
|
||||
background-color: #f0faff;
|
||||
}
|
||||
|
||||
::v-deep .week-select {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
::v-deep .el-table .el-table__cell {
|
||||
padding: 5px 0;
|
||||
}
|
||||
|
||||
::v-deep .el-input__inner {
|
||||
padding: 5px 10px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
/* 禁用单元格点击效果 */
|
||||
/* ::v-deep .no-edit-cell {
|
||||
pointer-events: none;
|
||||
} */
|
||||
|
||||
/* 让输入框可以被点击 */
|
||||
::v-deep .no-edit-cell .el-input,
|
||||
::v-deep .no-edit-cell .el-select {
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
::v-deep .time-input,
|
||||
::v-deep .number-input {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
::v-deep .statement-input {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
337
src/views/system/parameter/index.vue
Normal file
337
src/views/system/parameter/index.vue
Normal file
@ -0,0 +1,337 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-row :gutter="20">
|
||||
<!--部门数据-->
|
||||
<el-col :span="4" :xs="24">
|
||||
<div>
|
||||
<el-input v-model="deptName" placeholder="请输入部门名称" clearable prefix-icon="Search"
|
||||
style="margin-bottom: 20px" />
|
||||
</div>
|
||||
<div class="head-container">
|
||||
<el-tree :data="deptOptions" :props="{ label: 'label', children: 'children' }" :expand-on-click-node="false"
|
||||
:filter-node-method="filterNode" ref="deptTreeRef" node-key="id" highlight-current default-expand-all
|
||||
@node-click="handleNodeClick" />
|
||||
</div>
|
||||
</el-col>
|
||||
<!--用户数据-->
|
||||
<el-col :span="20" :xs="24">
|
||||
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch">
|
||||
<el-form-item label="仪器" prop="yq">
|
||||
<el-input v-model="queryParams.yq" placeholder="请输入仪器" clearable style="width: 240px"
|
||||
@keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="参数代号" prop="xxdh">
|
||||
<el-input v-model="queryParams.xxdh" placeholder="请输入参数代号" clearable style="width: 240px"
|
||||
@keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="参数值" prop="xxqz">
|
||||
<el-input v-model="queryParams.xxqz" placeholder="请输入参数值" clearable style="width: 240px"
|
||||
@keyup.enter="handleQuery" />
|
||||
</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="success" plain icon="Edit" :disabled="single" @click="handleUpdate">修改</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete">删除</el-button>
|
||||
</el-col> -->
|
||||
<!-- <el-col :span="1.5">
|
||||
<el-button type="info" plain icon="Upload" @click="handleImport">导入</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" :columns="columns"></right-toolbar> -->
|
||||
</el-row>
|
||||
|
||||
<el-table v-loading="loading" :data="tableData" height="calc(100vh - 300px)">
|
||||
<!-- <el-table-column type="selection" width="50" align="center" /> -->
|
||||
<el-table-column label="仪器" align="center" prop="yq" />
|
||||
<el-table-column label="代号" align="center" prop="xxdh" />
|
||||
<el-table-column label="类别" align="center" prop="xxlb" />
|
||||
<el-table-column label="参数值" align="center" prop="xxqz" />
|
||||
<el-table-column label="备注" align="center" prop="bz" width="120" />
|
||||
<el-table-column label="操作" align="center">
|
||||
<template #default="scope">
|
||||
<el-button type="text" plain icon="Edit" @click="handleUpdate(scope.row)">修改</el-button>
|
||||
<el-button type="text" plain 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-col>
|
||||
</el-row>
|
||||
|
||||
<!-- 添加或修改用户配置对话框 -->
|
||||
<el-dialog :title="title" v-model="open" width="600px" append-to-body>
|
||||
<el-form :model="form" :rules="rules" ref="csRef" label-width="80px">
|
||||
<el-row>
|
||||
<el-col>
|
||||
<el-form-item label="仪器" prop="yq">
|
||||
<el-input v-model="form.yq" placeholder="请输入仪器" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col>
|
||||
<el-form-item label="代号" prop="xxdh">
|
||||
<el-input v-model="form.xxdh" placeholder="请输入代号" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col>
|
||||
<el-form-item label="类别" prop="xxlb">
|
||||
<el-input v-model="form.xxlb" placeholder="请输入类别" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col>
|
||||
<el-form-item label="参数值" prop="xxqz">
|
||||
<el-input v-model="form.xxqz" placeholder="请输入参数值" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="备注">
|
||||
<el-input v-model="form.bz" type="textarea" placeholder="请输入内容"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
</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 lang="ts" setup>
|
||||
import { ref, reactive, toRaw, computed, watch, nextTick } from 'vue'
|
||||
import { paramList, addParam, updateParam, delParam, paramTree } from '@/api/system/parameter'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||
|
||||
const open = ref(false)
|
||||
const title = ref("")
|
||||
const queryParams = ref({
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
yq: undefined,
|
||||
xxdh: undefined,
|
||||
xxqz: undefined,
|
||||
})
|
||||
const form = ref({
|
||||
yq: undefined,
|
||||
xxdh: undefined,
|
||||
xxqz: undefined,
|
||||
xxlb: undefined,
|
||||
bz: undefined
|
||||
})
|
||||
const tableData = ref([])
|
||||
const loading = ref(true);
|
||||
const showSearch = ref(true);
|
||||
const single = ref(true);
|
||||
const multiple = ref(true);
|
||||
const total = ref(0);
|
||||
const deptName = ref("");
|
||||
|
||||
|
||||
const rules = ref({
|
||||
yq: [{ required: true, message: "仪器不能为空", trigger: "blur" },],
|
||||
xxdh: [{ required: true, message: "代号不能为空", trigger: "blur" }],
|
||||
xxlb: [{ required: true, message: "类别不能为空", trigger: "blur" },],
|
||||
xxqz: [{ required: true, message: "值不能为空", trigger: ["blur", "change"] }],
|
||||
})
|
||||
const ids = ref([]);
|
||||
const csRef = ref()
|
||||
const deptTreeRef = ref()
|
||||
const queryRef = ref()
|
||||
/** 根据名称筛选部门树 */
|
||||
watch(deptName, val => {
|
||||
deptTreeRef.value.filter(val);
|
||||
});
|
||||
|
||||
/** 通过条件过滤节点 */
|
||||
const filterNode = (value: string, data: any) => {
|
||||
if (!value) return true;
|
||||
return data.label.indexOf(value) !== -1;
|
||||
};
|
||||
|
||||
const deptOptions = ref([
|
||||
{
|
||||
label: '全部',
|
||||
children: [
|
||||
{
|
||||
label: '仪器',
|
||||
children: []
|
||||
}
|
||||
]
|
||||
}
|
||||
]);
|
||||
/** 查询下拉树数据 */
|
||||
const getDeptTree = () => {
|
||||
paramTree().then((response: any) => {
|
||||
const level1Nodes: any[] = [];
|
||||
const level2Nodes: any[] = [];
|
||||
|
||||
response.data.forEach((item: any) => {
|
||||
if (item.lx == 1) {
|
||||
level1Nodes.push({ label: item.yq });
|
||||
} else if (item.lx == 2) {
|
||||
level2Nodes.push({ label: item.yq });
|
||||
}
|
||||
});
|
||||
|
||||
deptOptions.value = [
|
||||
{
|
||||
label: '全部',
|
||||
children: [...level1Nodes, { label: '仪器', children: [...level2Nodes] }]
|
||||
}
|
||||
];
|
||||
});
|
||||
};
|
||||
getDeptTree()
|
||||
/** 节点单击事件 */
|
||||
const handleNodeClick = (data: any) => {
|
||||
if (data.label == '仪器') return
|
||||
if (data.label == '全部') {
|
||||
queryParams.value.yq = undefined;
|
||||
handleQuery();
|
||||
} else {
|
||||
queryParams.value.yq = data.label;
|
||||
handleQuery();
|
||||
}
|
||||
|
||||
};
|
||||
const handleAdd = () => {
|
||||
reset();
|
||||
open.value = true;
|
||||
title.value = "添加参数";
|
||||
nextTick(() => {
|
||||
csRef.value?.resetFields();
|
||||
});
|
||||
};
|
||||
const handleUpdate = (row: any) => {
|
||||
reset();
|
||||
open.value = true;
|
||||
title.value = "修改参数";
|
||||
nextTick(() => {
|
||||
csRef.value?.resetFields();
|
||||
form.value = Object.assign({}, row);
|
||||
});
|
||||
|
||||
};
|
||||
const handleImport = () => { };
|
||||
// 保存
|
||||
const submitForm = async () => {
|
||||
const valid = await csRef.value.validate().catch(() => { });
|
||||
if (!valid) return false;
|
||||
if (title.value == "添加参数") {
|
||||
addParam(form.value).then((res: any) => {
|
||||
if (res.code == 0) {
|
||||
ElMessage.success(res.msg);
|
||||
open.value = false;
|
||||
getList()
|
||||
}
|
||||
})
|
||||
} else {
|
||||
updateParam(form.value).then((res: any) => {
|
||||
if (res.code == 0) {
|
||||
ElMessage.success(res.msg);
|
||||
open.value = false;
|
||||
getList()
|
||||
}
|
||||
})
|
||||
}
|
||||
};
|
||||
const cancel = () => {
|
||||
open.value = false;
|
||||
};
|
||||
const handleSelectionChange = (selection: any) => {
|
||||
ids.value = selection[0]
|
||||
single.value = selection.length != 1;
|
||||
multiple.value = !selection.length;
|
||||
};
|
||||
/** 重置操作表单 */
|
||||
function reset() {
|
||||
form.value = {
|
||||
yq: undefined,
|
||||
xxdh: undefined,
|
||||
xxlb: undefined,
|
||||
xxqz: undefined,
|
||||
bz: undefined,
|
||||
};
|
||||
};
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.value.pageNum = 1;
|
||||
getList();
|
||||
};
|
||||
const resetQuery = () => {
|
||||
queryRef.value?.resetFields();
|
||||
getList()
|
||||
}
|
||||
|
||||
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = (row: any) => {
|
||||
ElMessageBox.confirm(
|
||||
`确定删除数据吗?`, "提示",
|
||||
{
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
}
|
||||
)
|
||||
.then(() => {
|
||||
delParam({ xxdh: row.xxdh, yq: row.yq }).then((res: any) => {
|
||||
if (res.code == 0) {
|
||||
getList()
|
||||
ElMessage.success(res.msg);
|
||||
}
|
||||
})
|
||||
})
|
||||
.catch(() => {
|
||||
|
||||
})
|
||||
};
|
||||
/** 导出按钮操作 */
|
||||
const handleExport = () => {
|
||||
// proxy.download("system/user/export", {
|
||||
// ...queryParams.value,
|
||||
// }, `user_${new Date().getTime()}.xlsx`);
|
||||
};
|
||||
|
||||
const getList = () => {
|
||||
paramList(queryParams.value).then((res: any) => {
|
||||
if (res.code == 200) {
|
||||
loading.value = false
|
||||
tableData.value = res.rows
|
||||
total.value = res.total
|
||||
}
|
||||
})
|
||||
}
|
||||
getList()
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.el-form--inline .el-form-item {
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
.head-container {
|
||||
height: 80vh;
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
||||
38
tsconfig.json
Normal file
38
tsconfig.json
Normal file
@ -0,0 +1,38 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "esnext" /* 指定ECMAScript目标版本: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */,
|
||||
"module": "esnext" /* 指定模块代码生成: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */,
|
||||
"lib": ["esnext", "dom", "dom.iterable", "scripthost"] /* 指定要包含在编译中的库文件。 */,
|
||||
"jsx": "preserve" /* 指定JSX代码生成:'preserve'、'react-native'或'react'。 */,
|
||||
"isolatedModules": true /* 将每个文件作为单独的模块进行转译(类似于“ts.transpileModule”)。 */,
|
||||
|
||||
/* 严格的类型检查选项 */
|
||||
"strict": true /* 启用所有严格的类型检查选项。 */,
|
||||
|
||||
/* 模块解析选项 */
|
||||
"moduleResolution": "node" /* 指定模块解析策略:'node'(Node.js)或'classic'(TypeScript 1.6之前版本)。*/,
|
||||
"baseUrl": "." /* 用于解析非绝对模块名称的基准目录。 */,
|
||||
"paths": {
|
||||
"@/*": ["src/*"]
|
||||
} /* 一系列条目,这些条目将导入重新映射到相对于“baseUrl”的查找位置。*/,
|
||||
"types": ["vite/client"] /* 要包含在编译中的类型声明文件。 */,
|
||||
"allowSyntheticDefaultImports": true /*允许从没有默认导出的模块进行默认导入。这不会影响代码生成,只会影响类型检查。*/,
|
||||
"esModuleInterop": true /* 通过为所有导入创建命名空间对象,实现CommonJS和ES模块之间的发射互操作性。这意味着“允许合成默认导入”。 */,
|
||||
"experimentalDecorators": true /*启用对ES7装饰器的实验性支持。 */,
|
||||
|
||||
/* 高级选项 */
|
||||
"skipLibCheck": true /* 跳过声明文件的类型检查. */,
|
||||
"forceConsistentCasingInFileNames": true /*禁止对同一文件使用大小写不一致的引用。 */
|
||||
},
|
||||
"vueCompilerOptions": {
|
||||
// 关键配置:关闭模板中的严格类型检查
|
||||
"strictTemplates": false,
|
||||
// // 可选:如果需要更精细的控制,可以单独关闭某些检查
|
||||
// "templateOptions": {
|
||||
// "allowUnknownInTemplate": true // 允许模板中使用未知属性
|
||||
// }
|
||||
},
|
||||
"types": ["element-plus/global"],
|
||||
"include": ["src/**/*","src/**/*.ts", "src/**/*.vue","src/**/**/*.vue", "src/**/*.tsx", "src/**/*.d.ts", "auto-imports.d.ts"], // **表示任意目录,而 * 表示任意文件。这表明 src 目录中的所有文件都将被编译
|
||||
"exclude": ["node_modules", "dist"] ,// 指示不需要编译的文件目录
|
||||
}
|
||||
@ -1,11 +1,19 @@
|
||||
import { defineConfig, loadEnv } from 'vite'
|
||||
import {
|
||||
defineConfig,
|
||||
loadEnv
|
||||
} from 'vite'
|
||||
import path from 'path'
|
||||
import createVitePlugins from './vite/plugins'
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig(({ mode, command }) => {
|
||||
export default defineConfig(({
|
||||
mode,
|
||||
command
|
||||
}) => {
|
||||
const env = loadEnv(mode, process.cwd())
|
||||
const { VITE_APP_ENV } = env
|
||||
const {
|
||||
VITE_APP_ENV
|
||||
} = env
|
||||
return {
|
||||
// 部署生产环境和开发环境下的URL。
|
||||
// 默认情况下,vite 会假设你的应用是被部署在一个域名的根路径上
|
||||
@ -18,21 +26,21 @@ export default defineConfig(({ mode, command }) => {
|
||||
// 设置路径
|
||||
'~': path.resolve(__dirname, './'),
|
||||
// 设置别名
|
||||
'@': path.resolve(__dirname, './src')
|
||||
'@': path.resolve(__dirname, 'src')
|
||||
},
|
||||
// https://cn.vitejs.dev/config/#resolve-extensions
|
||||
extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue']
|
||||
},
|
||||
// vite 相关配置
|
||||
server: {
|
||||
port: 5173,
|
||||
port: 8888,
|
||||
host: true,
|
||||
open: true,
|
||||
open: false,
|
||||
proxy: {
|
||||
// https://cn.vitejs.dev/config/#server-proxy
|
||||
'/dev-api': {
|
||||
target: 'http://localhost:9801',
|
||||
// target: 'https://api.wzs.pub/mock/13',
|
||||
target: 'http://47.97.125.165:8904',
|
||||
// target: 'http://192.168.1.114:9801',
|
||||
changeOrigin: true,
|
||||
rewrite: (p) => p.replace(/^\/dev-api/, '')
|
||||
},
|
||||
@ -47,22 +55,20 @@ export default defineConfig(({ mode, command }) => {
|
||||
//fix:error:stdin>:7356:1: warning: "@charset" must be the first rule in the file
|
||||
css: {
|
||||
postcss: {
|
||||
plugins: [
|
||||
{
|
||||
postcssPlugin: 'internal:charset-removal',
|
||||
AtRule: {
|
||||
charset: (atRule) => {
|
||||
if (atRule.name === 'charset') {
|
||||
atRule.remove();
|
||||
}
|
||||
plugins: [{
|
||||
postcssPlugin: 'internal:charset-removal',
|
||||
AtRule: {
|
||||
charset: (atRule) => {
|
||||
if (atRule.name === 'charset') {
|
||||
atRule.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
optimizeDeps: {
|
||||
include: ['jquery', 'select2', 'vue3-select2-component']
|
||||
}
|
||||
})
|
||||
})
|
||||
Loading…
x
Reference in New Issue
Block a user