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",
|
"axios": "0.27.2",
|
||||||
"clipboard": "^2.0.11",
|
"clipboard": "^2.0.11",
|
||||||
"echarts": "5.4.3",
|
"echarts": "5.4.3",
|
||||||
"element-plus": "2.4.3",
|
"element-plus": "^2.11.2",
|
||||||
"file-saver": "2.0.5",
|
"file-saver": "2.0.5",
|
||||||
"fuse.js": "6.6.2",
|
"fuse.js": "6.6.2",
|
||||||
"jquery": "^3.7.1",
|
"jquery": "^3.7.1",
|
||||||
@ -30,8 +30,10 @@
|
|||||||
"pinia": "2.1.7",
|
"pinia": "2.1.7",
|
||||||
"pinyin-pro": "^3.26.0",
|
"pinyin-pro": "^3.26.0",
|
||||||
"select2": "^4.1.0-rc.0",
|
"select2": "^4.1.0-rc.0",
|
||||||
|
"socket.io-client": "^4.8.1",
|
||||||
"vue": "3.4.0",
|
"vue": "3.4.0",
|
||||||
"vue-cropper": "1.1.1",
|
"vue-cropper": "1.1.1",
|
||||||
|
"vue-plugin-hiprint": "^0.0.60",
|
||||||
"vue-router": "4.2.5",
|
"vue-router": "4.2.5",
|
||||||
"vue3-print-nb": "^0.1.4",
|
"vue3-print-nb": "^0.1.4",
|
||||||
"vue3-select2-component": "^0.1.7",
|
"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,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@ -25,6 +25,15 @@ export function updateComDictService(data) {
|
|||||||
data
|
data
|
||||||
})
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
//删除字典数据
|
||||||
|
export function delComDictService(data) {
|
||||||
|
return request({
|
||||||
|
url: '/comdict/del',
|
||||||
|
method: 'delete',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 根据字典类型查询字典数据信息
|
// 根据字典类型查询字典数据信息
|
||||||
@ -35,4 +44,3 @@ export function getComDicts(zdlb) {
|
|||||||
params: zdlb
|
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;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.flex-between {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
@ -9,13 +9,15 @@
|
|||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip class="item" effect="dark" content="显隐列" placement="top" v-if="columns">
|
<el-tooltip class="item" effect="dark" content="显隐列" placement="top" v-if="columns">
|
||||||
<el-button circle icon="Menu" @click="showColumn()" v-if="showColumnsType == 'transfer'" />
|
<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-dropdown trigger="click" :hide-on-click="false" style="padding-left: 12px"
|
||||||
|
v-if="showColumnsType == 'checkbox'">
|
||||||
<el-button circle icon="Menu" />
|
<el-button circle icon="Menu" />
|
||||||
<template #dropdown>
|
<template #dropdown>
|
||||||
<el-dropdown-menu>
|
<el-dropdown-menu>
|
||||||
<template v-for="item in columns" :key="item.key">
|
<template v-for="item in columns" :key="item.key">
|
||||||
<el-dropdown-item>
|
<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>
|
</el-dropdown-item>
|
||||||
</template>
|
</template>
|
||||||
</el-dropdown-menu>
|
</el-dropdown-menu>
|
||||||
@ -24,12 +26,7 @@
|
|||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-dialog :title="title" v-model="open" append-to-body>
|
<el-dialog :title="title" v-model="open" append-to-body>
|
||||||
<el-transfer
|
<el-transfer :titles="['显示', '隐藏']" v-model="value" :data="columns" @change="dataChange"></el-transfer>
|
||||||
:titles="['显示', '隐藏']"
|
|
||||||
v-model="value"
|
|
||||||
:data="columns"
|
|
||||||
@change="dataChange"
|
|
||||||
></el-transfer>
|
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -62,7 +59,7 @@ const props = defineProps({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const emits = defineEmits(['update:showSearch', 'queryTable']);
|
const emits = defineEmits(['update:showSearch', 'queryTable', 'updateColumns']);
|
||||||
|
|
||||||
// 显隐数据
|
// 显隐数据
|
||||||
const value = ref([]);
|
const value = ref([]);
|
||||||
@ -114,6 +111,9 @@ if (props.showColumnsType == 'transfer') {
|
|||||||
// 勾选
|
// 勾选
|
||||||
function checkboxChange(event, label) {
|
function checkboxChange(event, label) {
|
||||||
props.columns.filter(item => item.label == label)[0].visible = event;
|
props.columns.filter(item => item.label == label)[0].visible = event;
|
||||||
|
|
||||||
|
emits("updateColumns", toRaw(props.columns));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
@ -124,9 +124,11 @@ function checkboxChange(event, label) {
|
|||||||
display: block;
|
display: block;
|
||||||
margin-left: 0px;
|
margin-left: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.el-transfer__button:first-child) {
|
:deep(.el-transfer__button:first-child) {
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.el-dropdown-menu__item) {
|
:deep(.el-dropdown-menu__item) {
|
||||||
line-height: 30px;
|
line-height: 30px;
|
||||||
padding: 0 17px;
|
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 axios from 'axios'
|
||||||
import { ElLoading, ElMessage } from 'element-plus'
|
import {
|
||||||
import { saveAs } from 'file-saver'
|
ElLoading,
|
||||||
import { getToken } from '@/utils/auth'
|
ElMessage
|
||||||
|
} from 'element-plus'
|
||||||
|
import {
|
||||||
|
saveAs
|
||||||
|
} from 'file-saver'
|
||||||
|
import {
|
||||||
|
getToken
|
||||||
|
} from '@/utils/auth'
|
||||||
import errorCode from '@/utils/errorCode'
|
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;
|
let downloadLoadingInstance;
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@ -15,7 +25,24 @@ export default {
|
|||||||
method: 'get',
|
method: 'get',
|
||||||
url: url,
|
url: url,
|
||||||
responseType: 'blob',
|
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) => {
|
}).then((res) => {
|
||||||
const isBlob = blobValidate(res.data);
|
const isBlob = blobValidate(res.data);
|
||||||
if (isBlob) {
|
if (isBlob) {
|
||||||
@ -32,7 +59,9 @@ export default {
|
|||||||
method: 'get',
|
method: 'get',
|
||||||
url: url,
|
url: url,
|
||||||
responseType: 'blob',
|
responseType: 'blob',
|
||||||
headers: { 'Authorization': 'Bearer ' + getToken() }
|
headers: {
|
||||||
|
'Authorization': 'Bearer ' + getToken()
|
||||||
|
}
|
||||||
}).then((res) => {
|
}).then((res) => {
|
||||||
const isBlob = blobValidate(res.data);
|
const isBlob = blobValidate(res.data);
|
||||||
if (isBlob) {
|
if (isBlob) {
|
||||||
@ -45,16 +74,23 @@ export default {
|
|||||||
},
|
},
|
||||||
zip(url, name) {
|
zip(url, name) {
|
||||||
var url = baseURL + url
|
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({
|
axios({
|
||||||
method: 'get',
|
method: 'get',
|
||||||
url: url,
|
url: url,
|
||||||
responseType: 'blob',
|
responseType: 'blob',
|
||||||
headers: { 'Authorization': 'Bearer ' + getToken() }
|
headers: {
|
||||||
|
'Authorization': 'Bearer ' + getToken()
|
||||||
|
}
|
||||||
}).then((res) => {
|
}).then((res) => {
|
||||||
const isBlob = blobValidate(res.data);
|
const isBlob = blobValidate(res.data);
|
||||||
if (isBlob) {
|
if (isBlob) {
|
||||||
const blob = new Blob([res.data], { type: 'application/zip' })
|
const blob = new Blob([res.data], {
|
||||||
|
type: 'application/zip'
|
||||||
|
})
|
||||||
this.saveAs(blob, name)
|
this.saveAs(blob, name)
|
||||||
} else {
|
} else {
|
||||||
this.printErrMsg(res.data);
|
this.printErrMsg(res.data);
|
||||||
@ -76,4 +112,3 @@ export default {
|
|||||||
ElMessage.error(errMsg);
|
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>
|
<script setup>
|
||||||
import { computed } from "vue";
|
import { computed, reactive, ref, onMounted, nextTick } from "vue";
|
||||||
import { getToken } from "@/utils/auth";
|
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();
|
const { proxy } = getCurrentInstance();
|
||||||
|
|
||||||
@ -20,6 +21,7 @@ const data = reactive({
|
|||||||
dictType: [{ required: true, message: "字典类型不能为空", trigger: "blur" }]
|
dictType: [{ required: true, message: "字典类型不能为空", trigger: "blur" }]
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const { queryParams, form, rules } = toRefs(data);
|
const { queryParams, form, rules } = toRefs(data);
|
||||||
const single = ref(true);
|
const single = ref(true);
|
||||||
const multiple = ref(true);
|
const multiple = ref(true);
|
||||||
@ -50,7 +52,31 @@ const upload = reactive({
|
|||||||
// 上传的地址
|
// 上传的地址
|
||||||
url: import.meta.env.VITE_APP_BASE_API + "/comdict/importData"
|
url: import.meta.env.VITE_APP_BASE_API + "/comdict/importData"
|
||||||
});
|
});
|
||||||
|
const treeRef = ref(null)
|
||||||
|
const defaultProps = {
|
||||||
|
children: 'children',
|
||||||
|
label: 'zdmc',
|
||||||
|
id: 'zddh'
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
function resetData(zdlb) {
|
||||||
queryParams.value = {
|
queryParams.value = {
|
||||||
pageNum: 1,
|
pageNum: 1,
|
||||||
@ -61,7 +87,6 @@ function resetData(zdlb){
|
|||||||
yljg: '1'
|
yljg: '1'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTypeList() {
|
function getTypeList() {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
queryParams.value.pageSize = 1000;
|
queryParams.value.pageSize = 1000;
|
||||||
@ -71,14 +96,11 @@ function getTypeList(){
|
|||||||
total.value = response.total;
|
total.value = response.total;
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
resetData()
|
resetData()
|
||||||
|
queryParams.value.zdlb = response.rows[1].zddh
|
||||||
|
getList()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function refreshDetail(zdlb){
|
|
||||||
queryParams.value.zdlb = zdlb;
|
|
||||||
getList()
|
|
||||||
resetData(zdlb)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** 查询字典明细列表 */
|
/** 查询字典明细列表 */
|
||||||
@ -110,10 +132,8 @@ function reset() {
|
|||||||
}
|
}
|
||||||
//重置
|
//重置
|
||||||
function resetQuery() {
|
function resetQuery() {
|
||||||
queryParams.value = {
|
queryParams.value.zdmc = ''
|
||||||
zdmc: '',
|
queryParams.value.zddh = ''
|
||||||
zddh: ''
|
|
||||||
}
|
|
||||||
proxy.resetForm("queryRef");
|
proxy.resetForm("queryRef");
|
||||||
handleQuery();
|
handleQuery();
|
||||||
}
|
}
|
||||||
@ -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() {
|
function handleImport() {
|
||||||
@ -173,8 +200,9 @@ const handleFileSuccess = (response, file, fileList) => {
|
|||||||
|
|
||||||
|
|
||||||
//多选框选中数据
|
//多选框选中数据
|
||||||
function handleSelectionChange(){
|
function handleSelectionChange(selection) {
|
||||||
|
info.value = selection[0]
|
||||||
|
single.value = selection.length != 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//查询字典大类
|
//查询字典大类
|
||||||
@ -189,36 +217,38 @@ function submitForm() {
|
|||||||
if (valid) {
|
if (valid) {
|
||||||
if (form.value.zdlb != undefined && form.value.zdlb != '') {
|
if (form.value.zdlb != undefined && form.value.zdlb != '') {
|
||||||
updateComDictService(form.value).then(response => {
|
updateComDictService(form.value).then(response => {
|
||||||
|
if (response.code == 0) {
|
||||||
proxy.$modal.msgSuccess("修改成功");
|
proxy.$modal.msgSuccess("修改成功");
|
||||||
open.value = false;
|
open.value = false;
|
||||||
getList();
|
getList();
|
||||||
}).catch(error => {
|
}
|
||||||
reset();
|
})
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
form.value.zdlb = queryParams.value.zdlb;
|
form.value.zdlb = queryParams.value.zdlb;
|
||||||
|
form.value.yljg = 1;
|
||||||
addComDictService(form.value).then(response => {
|
addComDictService(form.value).then(response => {
|
||||||
|
if (response.code == 0) {
|
||||||
proxy.$modal.msgSuccess("新增成功");
|
proxy.$modal.msgSuccess("新增成功");
|
||||||
open.value = false;
|
open.value = false;
|
||||||
getList();
|
getList();
|
||||||
}).catch(error => {
|
}
|
||||||
form.value.zdlb = '';
|
})
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 取消操作(保留这一份,删除后面重复的)
|
|
||||||
function cancel() {
|
function cancel() {
|
||||||
open.value = false;
|
open.value = false;
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
|
||||||
getTypeList()
|
getTypeList()
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -227,14 +257,12 @@ getTypeList()
|
|||||||
<el-row :gutter="20">
|
<el-row :gutter="20">
|
||||||
<el-col :span="4" :xs="24">
|
<el-col :span="4" :xs="24">
|
||||||
<div class="head-container">
|
<div class="head-container">
|
||||||
<el-input v-model="zdlbmc" clearable placeholder="请输入字典名称" prefix-icon="Search" style="margin-bottom: 20px" @keyup.enter="handleQueryDetail" @clear="handleQueryDetail" />
|
<el-input v-model="zdlbmc" clearable placeholder="请输入字典名称" prefix-icon="Search" style="margin-bottom: 20px" />
|
||||||
</div>
|
</div>
|
||||||
<div class="head-container">
|
<div class="head-container">
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<p class="clickable" v-for="item in typeList" :key="item.zdlb" @click="refreshDetail(item.zddh)">{{ item.zdmc }}</p>
|
<el-tree ref="treeRef" class="filter-tree" :data="typeList" :props="defaultProps" default-expand-all
|
||||||
</div>
|
:filter-node-method="filterNode" @node-click="nodeHandle" highlight-current />
|
||||||
<div class="card-content">
|
|
||||||
<p class="clickable" v-for="item in typeList" :key="item.zdlb" @click="refreshDetail(item.zddh)">{{ item.zdmc }}</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-col>
|
</el-col>
|
||||||
@ -243,10 +271,12 @@ getTypeList()
|
|||||||
<!-- 表单区域-->
|
<!-- 表单区域-->
|
||||||
<el-form :model="queryParams" ref="queryRef" :inline="true" label-width="68px">
|
<el-form :model="queryParams" ref="queryRef" :inline="true" label-width="68px">
|
||||||
<el-form-item class="cus-el-form-item" label="名称" prop="dictName">
|
<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-input v-model="queryParams.zdmc" placeholder="请输入名称" clearable style="width: 240px"
|
||||||
|
@keyup.enter="handleQuery" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item class="cus-el-form-item" label="明细代号" prop="status">
|
<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-input v-model="queryParams.zddh" placeholder="请输入明细代号" clearable style="width: 240px"
|
||||||
|
@keyup.enter="handleQuery" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||||
@ -256,37 +286,45 @@ getTypeList()
|
|||||||
|
|
||||||
<el-row :gutter="10" class="mb8">
|
<el-row :gutter="10" class="mb8">
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['system:dict:add']">新增</el-button>
|
<el-button type="primary" plain icon="Plus" @click="handleAdd"
|
||||||
|
v-hasPermi="['system:dict:add']">新增</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate" v-hasPermi="['system:dict:edit']">修改</el-button>
|
<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>
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete" v-hasPermi="['system:dict:remove']">删除</el-button>
|
<el-button type="warning" plain icon="Download" @click="handleExport"
|
||||||
</el-col>
|
v-hasPermi="['system:dict:export']">导出</el-button>
|
||||||
<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-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<!-- 表格区域-->
|
<!-- 表格区域-->
|
||||||
<el-table v-loading="loading" :data="typeDetail" @selection-change="handleSelectionChange">
|
<el-table v-loading="loading" :data="typeDetail" @selection-change="handleSelectionChange" height="65vh">
|
||||||
<el-table-column type="selection" width="55" align="center" />
|
<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="zdlb" :show-overflow-tooltip="true" />
|
||||||
<el-table-column label="明细代号" align="center" prop="zddh" />
|
<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="zdmc" :show-overflow-tooltip="true" />
|
||||||
<el-table-column label="备注" align="center" prop="remark" :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">
|
<el-table-column label="操作" align="center" width="160" class-name="small-padding fixed-width">
|
||||||
<template #default="{ row }">
|
<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="Edit" @click="handleUpdate(row)"
|
||||||
<el-button link type="primary" icon="Delete" @click="handleDelete(row)" v-hasPermi="['system:dict:remove']">删除</el-button>
|
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>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList"/>
|
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum"
|
||||||
|
v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||||
|
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
@ -316,18 +354,9 @@ getTypeList()
|
|||||||
</el-dialog>
|
</el-dialog>
|
||||||
<!-- 用户导入对话框 -->
|
<!-- 用户导入对话框 -->
|
||||||
<el-dialog :title="upload.title" v-model="upload.open" width="400px" append-to-body>
|
<el-dialog :title="upload.title" v-model="upload.open" width="400px" append-to-body>
|
||||||
<el-upload
|
<el-upload ref="uploadRef" :limit="1" accept=".xlsx, .xls" :headers="upload.headers"
|
||||||
ref="uploadRef"
|
:action="upload.url + '?updateSupport=' + upload.updateSupport" :disabled="upload.isUploading"
|
||||||
:limit="1"
|
:on-progress="handleFileUploadProgress" :on-success="handleFileSuccess" :auto-upload="false" drag>
|
||||||
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>
|
<el-icon class="el-icon--upload"><upload-filled /></el-icon>
|
||||||
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
|
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
|
||||||
<template #tip>
|
<template #tip>
|
||||||
@ -336,7 +365,8 @@ getTypeList()
|
|||||||
<el-checkbox v-model="upload.updateSupport" />是否覆盖已经存在的字典数据
|
<el-checkbox v-model="upload.updateSupport" />是否覆盖已经存在的字典数据
|
||||||
</div>
|
</div>
|
||||||
<span>仅允许导入xls、xlsx格式文件。</span>
|
<span>仅允许导入xls、xlsx格式文件。</span>
|
||||||
<el-link type="primary" :underline="false" style="font-size:12px;vertical-align: baseline;" @click="importTemplate">下载模板</el-link>
|
<el-link type="primary" :underline="false" style="font-size:12px;vertical-align: baseline;"
|
||||||
|
@click="importTemplate">下载模板</el-link>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-upload>
|
</el-upload>
|
||||||
@ -351,20 +381,28 @@ getTypeList()
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|
||||||
.card-content {
|
.card-content {
|
||||||
.card-content { /* 错误:嵌套了同名类,导致样式不生效 */
|
.card-content {
|
||||||
max-height: 450px;
|
max-height: 450px;
|
||||||
|
/* 设置最大高度 */
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
/* 超出高度时显示垂直滚动条 */
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
|
/* 保持与卡片默认一致的内边距 */
|
||||||
}
|
}
|
||||||
|
|
||||||
.clickable:hover {
|
.clickable:hover {
|
||||||
cursor: pointer; /* 鼠标悬停时显示手型 */
|
cursor: pointer;
|
||||||
transition: all 0.3s; /* 平滑过渡效果 */
|
/* 鼠标悬停时显示手型 */
|
||||||
|
transition: all 0.3s;
|
||||||
|
/* 平滑过渡效果 */
|
||||||
color: blue;
|
color: blue;
|
||||||
|
|
||||||
}}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.filter-tree {
|
||||||
|
max-height: 70vh;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
</style>
|
</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>
|
||||||
@ -7,12 +7,7 @@
|
|||||||
|
|
||||||
<el-col :span="6">
|
<el-col :span="6">
|
||||||
<div> 就诊卡号/病历号/磁卡号: </div>
|
<div> 就诊卡号/病历号/磁卡号: </div>
|
||||||
<el-input
|
<el-input v-model="queryParams.brdh" placeholder="就诊卡号/病历号/磁卡号" clearable @keyup.enter="handleQuery" />
|
||||||
v-model="queryParams.brdh"
|
|
||||||
placeholder="就诊卡号/病历号/磁卡号"
|
|
||||||
clearable
|
|
||||||
@keyup.enter="handleQuery"
|
|
||||||
/>
|
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="2">
|
<el-col :span="2">
|
||||||
<el-radio-group v-model="queryParams.zt" size="default">
|
<el-radio-group v-model="queryParams.zt" size="default">
|
||||||
@ -20,7 +15,9 @@
|
|||||||
:disabled="item.disabled">{{ item.label }}</el-radio>
|
:disabled="item.disabled">{{ item.label }}</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="1"> <div> 申请获取期限: </div></el-col>
|
<el-col :span="1">
|
||||||
|
<div> 申请获取期限: </div>
|
||||||
|
</el-col>
|
||||||
<el-col :span="6">
|
<el-col :span="6">
|
||||||
|
|
||||||
<el-radio-group v-model="queryParams.subday" size="default">
|
<el-radio-group v-model="queryParams.subday" size="default">
|
||||||
@ -30,8 +27,8 @@
|
|||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="2">
|
<el-col :span="2">
|
||||||
<el-select v-model="queryParams.cardtype" placeholder="卡类型" clearable :style="{ width: '100%' }">
|
<el-select v-model="queryParams.cardtype" placeholder="卡类型" clearable :style="{ width: '100%' }">
|
||||||
<el-option v-for="(item, index) in cardtypeOptions" :key="index" :label="item.label"
|
<el-option v-for="(item, index) in cardtypeOptions" :key="index" :label="item.label" :value="item.value"
|
||||||
:value="item.value" :disabled="item.disabled"></el-option>
|
:disabled="item.disabled"></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
@ -47,70 +44,36 @@
|
|||||||
</el-row>
|
</el-row>
|
||||||
<el-row :gutter="10" class="mb8">
|
<el-row :gutter="10" class="mb8">
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button
|
<el-button type="primary" plain icon="Search" @click="handleQuery"
|
||||||
type="primary"
|
v-hasPermi="['system:reqmain:Search']">查询</el-button>
|
||||||
plain
|
|
||||||
icon="Search"
|
|
||||||
@click="handleQuery"
|
|
||||||
v-hasPermi="['system:reqmain:Search']"
|
|
||||||
>查询</el-button>
|
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button
|
<el-button type="success" plain icon="Printer" :disabled="single" @click="printAll"
|
||||||
type="success"
|
v-hasPermi="['system:reqmain:add']">打印</el-button>
|
||||||
plain
|
|
||||||
icon="Printer"
|
|
||||||
:disabled="single"
|
|
||||||
@click="printAll"
|
|
||||||
v-hasPermi="['system:reqmain:add']"
|
|
||||||
>打印</el-button>
|
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button
|
<el-button type="success" plain icon="Printer" :disabled="freesingle" @click="printSigne"
|
||||||
type="success"
|
v-hasPermi="['system:reqmain:edit']">单打条码</el-button>
|
||||||
plain
|
|
||||||
icon="Printer"
|
|
||||||
:disabled="freesingle"
|
|
||||||
@click="printSigne"
|
|
||||||
v-hasPermi="['system:reqmain:edit']"
|
|
||||||
>单打条码</el-button>
|
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button
|
<el-button type="danger" plain icon="Printer" :disabled="freesingle" @click="printBackpaper"
|
||||||
type="danger"
|
v-hasPermi="['system:reqmain:edit']">单打回单</el-button>
|
||||||
plain
|
|
||||||
icon="Printer"
|
|
||||||
:disabled="freesingle"
|
|
||||||
@click="printBackpaper"
|
|
||||||
v-hasPermi="['system:reqmain:edit']"
|
|
||||||
>单打回单</el-button>
|
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button
|
<el-button type="warning" plain icon="Delete" @click="cancel"
|
||||||
type="warning"
|
v-hasPermi="['system:reqmain:export']">取消采样</el-button>
|
||||||
plain
|
|
||||||
icon="Delete"
|
|
||||||
@click="cancel"
|
|
||||||
v-hasPermi="['system:reqmain:export']"
|
|
||||||
>取消采样</el-button>
|
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="3">
|
<el-col :span="3">
|
||||||
<barcode-printer
|
<barcode-printer :printData="printBarcodeData" :disabled="!hasSelectedRows" type="success" icon="Printer"
|
||||||
:printData="printBarcodeData"
|
@print-start="showLoading" @print-success="handlePrintSuccess" @print-error="handlePrintError">
|
||||||
:disabled="!hasSelectedRows"
|
|
||||||
type="success"
|
|
||||||
icon="Printer"
|
|
||||||
@print-start="showLoading"
|
|
||||||
@print-success="handlePrintSuccess"
|
|
||||||
@print-error="handlePrintError"
|
|
||||||
>
|
|
||||||
打印条码
|
打印条码
|
||||||
</barcode-printer>
|
</barcode-printer>
|
||||||
</el-col>
|
</el-col>
|
||||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||||
</el-row>
|
</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 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="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="sqxmdh" width="100" show-overflow-tooltip />
|
||||||
@ -179,7 +142,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ElMessage } from 'element-plus'; // 引入 Element Plus 消息组件
|
import { ElMessage } from 'element-plus'; // 引入 Element Plus 消息组件
|
||||||
import { querySQD, getReqmain, delReqmain, addReqmain, updateReqmain, printBarcode } from "@/api/mzcx/cydj.js";
|
import { querySQD, getReqmain, delReqmain, addReqmain, updateReqmain, printBarcode } from "@/api/mzcx/cydj.js";
|
||||||
import BarcodePrinter from './components/BarcodePrinter.vue';
|
import BarcodePrinter from './BarcodePrinter.vue';
|
||||||
const comDict = inject('comDict');
|
const comDict = inject('comDict');
|
||||||
// 字典数据存储
|
// 字典数据存储
|
||||||
const dictData = ref({});
|
const dictData = ref({});
|
||||||
@ -562,22 +525,32 @@ const handlePrintError = (errorMsg) => {
|
|||||||
.compact-form .el-form-item__label {
|
.compact-form .el-form-item__label {
|
||||||
padding-bottom: 0px;
|
padding-bottom: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
::v-deep .my-table .el-table__row td {
|
::v-deep .my-table .el-table__row td {
|
||||||
padding: 1px 0; /* 减小行高 */
|
padding: 1px 0;
|
||||||
|
/* 减小行高 */
|
||||||
}
|
}
|
||||||
|
|
||||||
::v-deep .my-table .el-table__header-wrapper th {
|
::v-deep .my-table .el-table__header-wrapper th {
|
||||||
padding: 6px 0; /* 表头内边距 */
|
padding: 6px 0;
|
||||||
background-color: #b3d8ff !important; /* 表头背景色(保留之前的设置) */
|
/* 表头内边距 */
|
||||||
color: #333; /* 文字颜色加深,提升可读性 */
|
background-color: #b3d8ff !important;
|
||||||
font-weight: 500; /* 文字加粗 */
|
/* 表头背景色(保留之前的设置) */
|
||||||
|
color: #333;
|
||||||
|
/* 文字颜色加深,提升可读性 */
|
||||||
|
font-weight: 500;
|
||||||
|
/* 文字加粗 */
|
||||||
}
|
}
|
||||||
|
|
||||||
::v-deep .my-table .el-table__cell {
|
::v-deep .my-table .el-table__cell {
|
||||||
padding: 0 2px; /* 减小列间距 */
|
padding: 0 2px;
|
||||||
|
/* 减小列间距 */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 可选:调整表格整体样式 */
|
/* 可选:调整表格整体样式 */
|
||||||
::v-deep .my-table {
|
::v-deep .my-table {
|
||||||
font-size: 13px; /* 适当减小字体 */
|
font-size: 13px;
|
||||||
|
/* 适当减小字体 */
|
||||||
}
|
}
|
||||||
|
|
||||||
::v-deep .my-table .el-table__cell,
|
::v-deep .my-table .el-table__cell,
|
||||||
@ -585,17 +558,25 @@ const handlePrintError = (errorMsg) => {
|
|||||||
border-width: 1px;
|
border-width: 1px;
|
||||||
border-color: #ebeef5;
|
border-color: #ebeef5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-content {
|
.card-content {
|
||||||
max-height: 450px; /* 设置最大高度 */
|
max-height: 450px;
|
||||||
overflow-y: auto; /* 超出高度时显示垂直滚动条 */
|
/* 设置最大高度 */
|
||||||
padding: 5px; /* 保持与卡片默认一致的内边距 */
|
overflow-y: auto;
|
||||||
|
/* 超出高度时显示垂直滚动条 */
|
||||||
|
padding: 5px;
|
||||||
|
/* 保持与卡片默认一致的内边距 */
|
||||||
}
|
}
|
||||||
|
|
||||||
.clickable:hover {
|
.clickable:hover {
|
||||||
cursor: pointer; /* 鼠标悬停时显示手型 */
|
cursor: pointer;
|
||||||
transition: all 0.3s; /* 平滑过渡效果 */
|
/* 鼠标悬停时显示手型 */
|
||||||
|
transition: all 0.3s;
|
||||||
|
/* 平滑过渡效果 */
|
||||||
color: blue;
|
color: blue;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 汇总行样式 */
|
/* 汇总行样式 */
|
||||||
.table-summary {
|
.table-summary {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -607,7 +588,9 @@ const handlePrintError = (errorMsg) => {
|
|||||||
border: 1px solid #ebeef5;
|
border: 1px solid #ebeef5;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
line-height: 24px; /* 汇总行文字行高 */
|
line-height: 24px;
|
||||||
|
|
||||||
|
/* 汇总行文字行高 */
|
||||||
.summary-item {
|
.summary-item {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -621,12 +604,16 @@ const handlePrintError = (errorMsg) => {
|
|||||||
.summary-value {
|
.summary-value {
|
||||||
color: #303133;
|
color: #303133;
|
||||||
min-width: 40px;
|
min-width: 40px;
|
||||||
text-align: left;/* 核心:数值左对齐 */
|
text-align: left;
|
||||||
|
/* 核心:数值左对齐 */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 单独设置"单价合计"的值为红色 */
|
/* 单独设置"单价合计"的值为红色 */
|
||||||
&:nth-child(3) .summary-value {
|
&:nth-child(3) .summary-value {
|
||||||
color: #f56c6c; /* Element UI 红色主题色 */
|
color: #f56c6c;
|
||||||
font-weight: 600; /* 可选:加粗字体 */
|
/* Element UI 红色主题色 */
|
||||||
|
font-weight: 600;
|
||||||
|
/* 可选:加粗字体 */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,12 +7,7 @@
|
|||||||
|
|
||||||
<el-col :span="6">
|
<el-col :span="6">
|
||||||
<div> 就诊卡号/病历号/磁卡号: </div>
|
<div> 就诊卡号/病历号/磁卡号: </div>
|
||||||
<el-input
|
<el-input v-model="queryParams.brdh" placeholder="就诊卡号/病历号/磁卡号" clearable @keyup.enter="handleQuery" />
|
||||||
v-model="queryParams.brdh"
|
|
||||||
placeholder="就诊卡号/病历号/磁卡号"
|
|
||||||
clearable
|
|
||||||
@keyup.enter="handleQuery"
|
|
||||||
/>
|
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="2">
|
<el-col :span="2">
|
||||||
<el-radio-group v-model="queryParams.zt" size="default">
|
<el-radio-group v-model="queryParams.zt" size="default">
|
||||||
@ -20,7 +15,9 @@
|
|||||||
:disabled="item.disabled">{{ item.label }}</el-radio>
|
:disabled="item.disabled">{{ item.label }}</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="1"> <div> 申请获取期限: </div></el-col>
|
<el-col :span="1">
|
||||||
|
<div> 申请获取期限: </div>
|
||||||
|
</el-col>
|
||||||
<el-col :span="6">
|
<el-col :span="6">
|
||||||
|
|
||||||
<el-radio-group v-model="queryParams.subday" size="default">
|
<el-radio-group v-model="queryParams.subday" size="default">
|
||||||
@ -30,8 +27,8 @@
|
|||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="2">
|
<el-col :span="2">
|
||||||
<el-select v-model="queryParams.cardtype" placeholder="卡类型" clearable :style="{ width: '100%' }">
|
<el-select v-model="queryParams.cardtype" placeholder="卡类型" clearable :style="{ width: '100%' }">
|
||||||
<el-option v-for="(item, index) in cardtypeOptions" :key="index" :label="item.label"
|
<el-option v-for="(item, index) in cardtypeOptions" :key="index" :label="item.label" :value="item.value"
|
||||||
:value="item.value" :disabled="item.disabled"></el-option>
|
:disabled="item.disabled"></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
@ -47,56 +44,29 @@
|
|||||||
</el-row>
|
</el-row>
|
||||||
<el-row :gutter="5" class="mb8">
|
<el-row :gutter="5" class="mb8">
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button
|
<el-button type="primary" plain icon="Search" @click="handleQuery"
|
||||||
type="primary"
|
v-hasPermi="['system:reqmain:Search']">查询</el-button>
|
||||||
plain
|
|
||||||
icon="Search"
|
|
||||||
@click="handleQuery"
|
|
||||||
v-hasPermi="['system:reqmain:Search']"
|
|
||||||
>查询</el-button>
|
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button
|
<el-button type="success" plain icon="Printer" :disabled="single" @click="printAll"
|
||||||
type="success"
|
v-hasPermi="['system:reqmain:add']">打印</el-button>
|
||||||
plain
|
|
||||||
icon="Printer"
|
|
||||||
:disabled="single"
|
|
||||||
@click="printAll"
|
|
||||||
v-hasPermi="['system:reqmain:add']"
|
|
||||||
>打印</el-button>
|
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button
|
<el-button type="success" plain icon="Printer" :disabled="single" @click="printSigne"
|
||||||
type="success"
|
v-hasPermi="['system:reqmain:edit']">单打条码</el-button>
|
||||||
plain
|
|
||||||
icon="Printer"
|
|
||||||
:disabled="single"
|
|
||||||
@click="printSigne"
|
|
||||||
v-hasPermi="['system:reqmain:edit']"
|
|
||||||
>单打条码</el-button>
|
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button
|
<el-button type="danger" plain icon="Printer" :disabled="freesingle" @click="printBack"
|
||||||
type="danger"
|
v-hasPermi="['system:reqmain:edit']">单打回单</el-button>
|
||||||
plain
|
|
||||||
icon="Printer"
|
|
||||||
:disabled="freesingle"
|
|
||||||
@click="printBack"
|
|
||||||
v-hasPermi="['system:reqmain:edit']"
|
|
||||||
>单打回单</el-button>
|
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button
|
<el-button type="warning" plain icon="Delete" @click="cancel"
|
||||||
type="warning"
|
v-hasPermi="['system:reqmain:export']">取消采样</el-button>
|
||||||
plain
|
|
||||||
icon="Delete"
|
|
||||||
@click="cancel"
|
|
||||||
v-hasPermi="['system:reqmain:export']"
|
|
||||||
>取消采样</el-button>
|
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row :gutter="5" class="table-container">
|
<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 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 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="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="sqxmdh" width="100" show-overflow-tooltip />
|
||||||
@ -172,6 +142,7 @@ import {
|
|||||||
printBarcodeall
|
printBarcodeall
|
||||||
} from "@/api/mzcx/cydj.js";
|
} from "@/api/mzcx/cydj.js";
|
||||||
import PatSearchDialog from './components/OutPatList.vue'
|
import PatSearchDialog from './components/OutPatList.vue'
|
||||||
|
import { classCom } from '@/utils/classCom';
|
||||||
const comDict = inject('comDict');
|
const comDict = inject('comDict');
|
||||||
// 字典数据存储
|
// 字典数据存储
|
||||||
const dictData = ref({});
|
const dictData = ref({});
|
||||||
@ -458,9 +429,9 @@ const tableCellStyle = ({ row, column }) => {
|
|||||||
// 只对“项目类别”列生效
|
// 只对“项目类别”列生效
|
||||||
if (column.label === '项目类别') {
|
if (column.label === '项目类别') {
|
||||||
// 1. 转换颜色(十进制→十六进制)
|
// 1. 转换颜色(十进制→十六进制)
|
||||||
const bgColor = decimalToHexColor(row.cp_color);
|
const bgColor = classCom.decimalToHexColor(row.cp_color);
|
||||||
// 2. 自动计算文字颜色(确保和背景色对比度足够)
|
// 2. 自动计算文字颜色(确保和背景色对比度足够)
|
||||||
const textColor = getContrastTextColor(bgColor);
|
const textColor = classCom.getContrastTextColor(bgColor);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
backgroundColor: bgColor, // 背景色(转换后的值)
|
backgroundColor: bgColor, // 背景色(转换后的值)
|
||||||
@ -472,39 +443,6 @@ const tableCellStyle = ({ row, column }) => {
|
|||||||
return {}; // 其他列保持默认样式
|
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>
|
</script>
|
||||||
|
|
||||||
@ -512,21 +450,31 @@ const getContrastTextColor = (bgColor) => {
|
|||||||
.app-container {
|
.app-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
height: 90vh; /* 容器高度等于窗口高度 */
|
height: 90vh;
|
||||||
|
/* 容器高度等于窗口高度 */
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.compact-form {
|
.compact-form {
|
||||||
height: 75px; /* 固定高度 */
|
height: 75px;
|
||||||
|
/* 固定高度 */
|
||||||
}
|
}
|
||||||
|
|
||||||
.mb8 {
|
.mb8 {
|
||||||
height: 30px; /* 固定高度 */
|
height: 30px;
|
||||||
|
/* 固定高度 */
|
||||||
}
|
}
|
||||||
|
|
||||||
.table-summary {
|
.table-summary {
|
||||||
height: 10px; /* 固定高度 */
|
height: 10px;
|
||||||
|
/* 固定高度 */
|
||||||
}
|
}
|
||||||
|
|
||||||
.table-container {
|
.table-container {
|
||||||
flex: 1; /* 占满剩余高度 */
|
flex: 1;
|
||||||
overflow: hidden; /* 避免表格超出容器 */
|
/* 占满剩余高度 */
|
||||||
|
overflow: hidden;
|
||||||
|
/* 避免表格超出容器 */
|
||||||
}
|
}
|
||||||
|
|
||||||
.compact-form .el-form-item {
|
.compact-form .el-form-item {
|
||||||
@ -537,22 +485,32 @@ const getContrastTextColor = (bgColor) => {
|
|||||||
.compact-form .el-form-item__label {
|
.compact-form .el-form-item__label {
|
||||||
padding-bottom: 0px;
|
padding-bottom: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
::v-deep .my-table .el-table__row td {
|
::v-deep .my-table .el-table__row td {
|
||||||
padding: 1px 0; /* 减小行高 */
|
padding: 1px 0;
|
||||||
|
/* 减小行高 */
|
||||||
}
|
}
|
||||||
|
|
||||||
::v-deep .my-table .el-table__header-wrapper th {
|
::v-deep .my-table .el-table__header-wrapper th {
|
||||||
padding: 6px 0; /* 表头内边距 */
|
padding: 6px 0;
|
||||||
background-color: #b3d8ff !important; /* 表头背景色(保留之前的设置) */
|
/* 表头内边距 */
|
||||||
color: #333; /* 文字颜色加深,提升可读性 */
|
background-color: #b3d8ff !important;
|
||||||
font-weight: 500; /* 文字加粗 */
|
/* 表头背景色(保留之前的设置) */
|
||||||
|
color: #333;
|
||||||
|
/* 文字颜色加深,提升可读性 */
|
||||||
|
font-weight: 500;
|
||||||
|
/* 文字加粗 */
|
||||||
}
|
}
|
||||||
|
|
||||||
::v-deep .my-table .el-table__cell {
|
::v-deep .my-table .el-table__cell {
|
||||||
padding: 0 2px; /* 减小列间距 */
|
padding: 0 2px;
|
||||||
|
/* 减小列间距 */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 可选:调整表格整体样式 */
|
/* 可选:调整表格整体样式 */
|
||||||
::v-deep .my-table {
|
::v-deep .my-table {
|
||||||
font-size: 13px; /* 适当减小字体 */
|
font-size: 13px;
|
||||||
|
/* 适当减小字体 */
|
||||||
}
|
}
|
||||||
|
|
||||||
::v-deep .my-table .el-table__cell,
|
::v-deep .my-table .el-table__cell,
|
||||||
@ -560,17 +518,25 @@ const getContrastTextColor = (bgColor) => {
|
|||||||
border-width: 1px;
|
border-width: 1px;
|
||||||
border-color: #ebeef5;
|
border-color: #ebeef5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-content {
|
.card-content {
|
||||||
max-height: 450px; /* 设置最大高度 */
|
max-height: 450px;
|
||||||
overflow-y: auto; /* 超出高度时显示垂直滚动条 */
|
/* 设置最大高度 */
|
||||||
padding: 5px; /* 保持与卡片默认一致的内边距 */
|
overflow-y: auto;
|
||||||
|
/* 超出高度时显示垂直滚动条 */
|
||||||
|
padding: 5px;
|
||||||
|
/* 保持与卡片默认一致的内边距 */
|
||||||
}
|
}
|
||||||
|
|
||||||
.clickable:hover {
|
.clickable:hover {
|
||||||
cursor: pointer; /* 鼠标悬停时显示手型 */
|
cursor: pointer;
|
||||||
transition: all 0.3s; /* 平滑过渡效果 */
|
/* 鼠标悬停时显示手型 */
|
||||||
|
transition: all 0.3s;
|
||||||
|
/* 平滑过渡效果 */
|
||||||
color: blue;
|
color: blue;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 汇总行样式 */
|
/* 汇总行样式 */
|
||||||
.table-summary {
|
.table-summary {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -582,7 +548,9 @@ const getContrastTextColor = (bgColor) => {
|
|||||||
border: 1px solid #ebeef5;
|
border: 1px solid #ebeef5;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
line-height: 24px; /* 汇总行文字行高 */
|
line-height: 24px;
|
||||||
|
|
||||||
|
/* 汇总行文字行高 */
|
||||||
.summary-item {
|
.summary-item {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -596,12 +564,16 @@ const getContrastTextColor = (bgColor) => {
|
|||||||
.summary-value {
|
.summary-value {
|
||||||
color: #303133;
|
color: #303133;
|
||||||
min-width: 40px;
|
min-width: 40px;
|
||||||
text-align: left;/* 核心:数值左对齐 */
|
text-align: left;
|
||||||
|
/* 核心:数值左对齐 */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 单独设置"单价合计"的值为红色 */
|
/* 单独设置"单价合计"的值为红色 */
|
||||||
&:nth-child(3) .summary-value {
|
&:nth-child(3) .summary-value {
|
||||||
color: #f56c6c; /* Element UI 红色主题色 */
|
color: #f56c6c;
|
||||||
font-weight: 600; /* 可选:加粗字体 */
|
/* 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 path from 'path'
|
||||||
import createVitePlugins from './vite/plugins'
|
import createVitePlugins from './vite/plugins'
|
||||||
|
|
||||||
// https://vitejs.dev/config/
|
// https://vitejs.dev/config/
|
||||||
export default defineConfig(({ mode, command }) => {
|
export default defineConfig(({
|
||||||
|
mode,
|
||||||
|
command
|
||||||
|
}) => {
|
||||||
const env = loadEnv(mode, process.cwd())
|
const env = loadEnv(mode, process.cwd())
|
||||||
const { VITE_APP_ENV } = env
|
const {
|
||||||
|
VITE_APP_ENV
|
||||||
|
} = env
|
||||||
return {
|
return {
|
||||||
// 部署生产环境和开发环境下的URL。
|
// 部署生产环境和开发环境下的URL。
|
||||||
// 默认情况下,vite 会假设你的应用是被部署在一个域名的根路径上
|
// 默认情况下,vite 会假设你的应用是被部署在一个域名的根路径上
|
||||||
@ -18,21 +26,21 @@ export default defineConfig(({ mode, command }) => {
|
|||||||
// 设置路径
|
// 设置路径
|
||||||
'~': path.resolve(__dirname, './'),
|
'~': path.resolve(__dirname, './'),
|
||||||
// 设置别名
|
// 设置别名
|
||||||
'@': path.resolve(__dirname, './src')
|
'@': path.resolve(__dirname, 'src')
|
||||||
},
|
},
|
||||||
// https://cn.vitejs.dev/config/#resolve-extensions
|
// https://cn.vitejs.dev/config/#resolve-extensions
|
||||||
extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue']
|
extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue']
|
||||||
},
|
},
|
||||||
// vite 相关配置
|
// vite 相关配置
|
||||||
server: {
|
server: {
|
||||||
port: 5173,
|
port: 8888,
|
||||||
host: true,
|
host: true,
|
||||||
open: true,
|
open: false,
|
||||||
proxy: {
|
proxy: {
|
||||||
// https://cn.vitejs.dev/config/#server-proxy
|
// https://cn.vitejs.dev/config/#server-proxy
|
||||||
'/dev-api': {
|
'/dev-api': {
|
||||||
target: 'http://localhost:9801',
|
target: 'http://47.97.125.165:8904',
|
||||||
// target: 'https://api.wzs.pub/mock/13',
|
// target: 'http://192.168.1.114:9801',
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
rewrite: (p) => p.replace(/^\/dev-api/, '')
|
rewrite: (p) => p.replace(/^\/dev-api/, '')
|
||||||
},
|
},
|
||||||
@ -47,8 +55,7 @@ export default defineConfig(({ mode, command }) => {
|
|||||||
//fix:error:stdin>:7356:1: warning: "@charset" must be the first rule in the file
|
//fix:error:stdin>:7356:1: warning: "@charset" must be the first rule in the file
|
||||||
css: {
|
css: {
|
||||||
postcss: {
|
postcss: {
|
||||||
plugins: [
|
plugins: [{
|
||||||
{
|
|
||||||
postcssPlugin: 'internal:charset-removal',
|
postcssPlugin: 'internal:charset-removal',
|
||||||
AtRule: {
|
AtRule: {
|
||||||
charset: (atRule) => {
|
charset: (atRule) => {
|
||||||
@ -57,8 +64,7 @@ export default defineConfig(({ mode, command }) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}]
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user