Files
his/openhis-ui-vue3/src/views/clinicmanagement/dayEnd/index.vue
zhaoyun c9122d58be fix(#568): 请修复 Bug #568:[一般] [收费工作站-门诊日结]排版很乱
根因:
- Bug #请修复 Bug #568 存在的问题

修复:
- ### 变更摘要
- 文件**: `src/views/clinicmanagement/dayEnd/index.vue`
- 1. **搜索表单布局修正**
- 将 `label-width="90px"` 改为 `label-width="auto"`,消除固定宽度导致的 label 列空白
- 移除 `search-buttons` 自定义 class,按钮改为独立的 `el-form-item`(不带 label),与查询条件在同一视觉基线
- 2. **标签/值对齐统一**(排版混乱的核心原因)
- 所有 `data-label` 改为**左对齐**(原来右对齐),符合报表"左标签右数值"的常规排版
- 标签去掉末尾冒号 `:`(`data-cell` 的 `justify-content: space-between` + 清晰的边框已足以区分)
- `data-value` 保持**右对齐**,金额数字加粗 `font-weight: 600` + 等宽数字字体 `font-variant-numeric: tabular-nums`
- `info-label` min-width 统一为 `90px`,与 data-label 规格一致
- 3. **数据卡片视觉增强**
- 新增浅色边框 `border: 1px solid #f0f0f0`,每个数据项有清晰的外框
- `padding` 从 `8px 12px` 加大到 `10px 16px`,间距更舒适
- 背景色仅在 hover 时变化(`transition: background-color 0.2s`)
- 圆角从 `4px` 提升到 `6px`
- 4. **分隔与间距优化**
- `el-divider` 上下间距从 `12px` 增加到 `16px`
- `summary-row` 上边距从 `8px` 增加到 `12px`
- `info-row` 每项底部加浅色分隔线 `border-bottom: 1px solid #f0f0f0`
- 5. **响应式适配**
- 小屏幕下 `data-cell` 缩小内边距,`data-label` 取消固定 min-width
- ### 验证结果
- `eslint` 检查通过 (无错误)
- `vite build` 构建通过 
2026-05-29 01:17:29 +08:00

715 lines
18 KiB
Vue
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="app-container">
<el-form
v-show="showSearch"
ref="queryRef"
:model="queryParams"
:inline="true"
label-width="auto"
>
<el-form-item label="查询日期">
<el-date-picker
v-model="queryTime"
type="daterange"
start-placeholder="开始日期"
end-placeholder="结束日期"
style="width: 300px"
value-format="YYYY-MM-DD"
@change="getValue"
/>
</el-form-item>
<el-form-item label="费用性质">
<el-select
v-model="contractNo"
placeholder="费用性质"
clearable
style="width: 160px"
@change="getValue"
>
<el-option
v-for="item in contractList"
:key="item.busNo"
:label="item.contractName"
:value="item.busNo"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button
type="primary"
plain
icon="Search"
@click="getValue"
>
查询
</el-button>
<el-button
type="primary"
plain
icon="Printer"
@click="print"
>
打印
</el-button>
</el-form-item>
</el-form>
<div
v-loading="loading"
class="report-container"
>
<div class="report-title">
门诊收费日结单
</div>
<el-row
:gutter="20"
class="info-row"
>
<el-col
:xs="24"
:sm="12"
:md="6"
>
<div class="info-cell">
<span class="info-label">经办人姓名</span>
<span class="info-value">{{ userStore.nickName || '全部' }}</span>
</div>
</el-col>
<el-col
:xs="24"
:sm="12"
:md="6"
>
<div class="info-cell">
<span class="info-label">科室</span>
<span class="info-value">{{ userStore.orgName || '-' }}</span>
</div>
</el-col>
<el-col
:xs="24"
:sm="12"
:md="6"
>
<div class="info-cell">
<span class="info-label">机构</span>
<span class="info-value">{{ userStore.hospitalName || '-' }}</span>
</div>
</el-col>
<el-col
:xs="24"
:sm="12"
:md="6"
>
<div class="info-cell">
<span class="info-label">时间</span>
<span class="info-value">{{ queryTime && queryTime.length === 2 ? queryTime[0] + ' ~ ' + queryTime[1] : '-' }}</span>
</div>
</el-col>
</el-row>
<el-divider />
<div class="section-title">
收入汇总
</div>
<el-row
:gutter="16"
class="data-row"
>
<el-col
:xs="24"
:sm="12"
:md="6"
>
<div class="data-cell">
<span class="data-label">总收入</span>
<span class="data-value">{{ formatValue(reportValue.cashSum) }}</span>
</div>
</el-col>
<el-col
:xs="24"
:sm="12"
:md="6"
>
<div class="data-cell">
<span class="data-label">现金</span>
<span class="data-value">{{ formatValue(reportValue.rmbCashSum) }}</span>
</div>
</el-col>
<el-col
:xs="24"
:sm="12"
:md="6"
>
<div class="data-cell">
<span class="data-label">微信</span>
<span class="data-value">{{ formatValue(reportValue.vxCashSum) }}</span>
</div>
</el-col>
<el-col
:xs="24"
:sm="12"
:md="6"
>
<div class="data-cell">
<span class="data-label">支付宝</span>
<span class="data-value">{{ formatValue(reportValue.aliCashSum) }}</span>
</div>
</el-col>
</el-row>
<el-divider />
<div class="section-title">
医保支付
</div>
<el-row
:gutter="16"
class="data-row"
>
<el-col
:xs="24"
:sm="12"
:md="6"
>
<div class="data-cell">
<span class="data-label">统筹支付</span>
<span class="data-value">{{ formatValue(reportValue.tcSum) }}</span>
</div>
</el-col>
<el-col
:xs="24"
:sm="12"
:md="6"
>
<div class="data-cell">
<span class="data-label">账户支付</span>
<span class="data-value">{{ formatValue(reportValue.zhSum) }}</span>
</div>
</el-col>
<el-col
:xs="24"
:sm="12"
:md="6"
>
<div class="data-cell">
<span class="data-label">基金支付总额</span>
<span class="data-value">{{ formatValue(reportValue.fundSum) }}</span>
</div>
</el-col>
<el-col
:xs="24"
:sm="12"
:md="6"
>
<div class="data-cell">
<span class="data-label">医保统筹+账户</span>
<span class="data-value">{{ formatValue(Number(reportValue.zhSum || 0) + Number(reportValue.fundSum || 0)) }}</span>
</div>
</el-col>
</el-row>
<el-divider />
<div class="section-title">
费用明细
</div>
<el-row
:gutter="16"
class="data-row"
>
<el-col
:xs="24"
:sm="12"
:md="6"
>
<div class="data-cell">
<span class="data-label">诊查费</span>
<span class="data-value">{{ formatValue(reportValue.DIAGNOSTIC_FEE) }}</span>
</div>
</el-col>
<el-col
:xs="24"
:sm="12"
:md="6"
>
<div class="data-cell">
<span class="data-label">检查费</span>
<span class="data-value">{{ formatValue(reportValue.CHECK_FEE) }}</span>
</div>
</el-col>
<el-col
:xs="24"
:sm="12"
:md="6"
>
<div class="data-cell">
<span class="data-label">化验费</span>
<span class="data-value">{{ formatValue(reportValue.DIAGNOSTIC_TEST_FEE) }}</span>
</div>
</el-col>
<el-col
:xs="24"
:sm="12"
:md="6"
>
<div class="data-cell">
<span class="data-label">治疗费</span>
<span class="data-value">{{ formatValue(reportValue.MEDICAL_EXPENSE_FEE) }}</span>
</div>
</el-col>
</el-row>
<el-row
:gutter="16"
class="data-row"
>
<el-col
:xs="24"
:sm="12"
:md="6"
>
<div class="data-cell">
<span class="data-label">西药费</span>
<span class="data-value">{{ formatValue(reportValue.WEST_MEDICINE) }}</span>
</div>
</el-col>
<el-col
:xs="24"
:sm="12"
:md="6"
>
<div class="data-cell">
<span class="data-label">中药饮片费</span>
<span class="data-value">{{ formatValue(reportValue.CHINESE_MEDICINE_SLICES_FEE) }}</span>
</div>
</el-col>
<el-col
:xs="24"
:sm="12"
:md="6"
>
<div class="data-cell">
<span class="data-label">中成药费</span>
<span class="data-value">{{ formatValue(reportValue.CHINESE_MEDICINE_FEE) }}</span>
</div>
</el-col>
<el-col
:xs="24"
:sm="12"
:md="6"
>
<div class="data-cell">
<span class="data-label">卫生材料费</span>
<span class="data-value">{{ formatValue(reportValue.SANITARY_MATERIALS_FEE) }}</span>
</div>
</el-col>
</el-row>
<el-row
:gutter="16"
class="data-row"
>
<el-col
:xs="24"
:sm="12"
:md="6"
>
<div class="data-cell">
<span class="data-label">普通挂号费</span>
<span class="data-value">{{ formatValue(reportValue.GENERAL_CONSULTATION_FEE) }}</span>
</div>
</el-col>
<el-col
:xs="24"
:sm="12"
:md="6"
>
<div class="data-cell">
<span class="data-label">挂号费</span>
<span class="data-value">{{ formatValue(reportValue.REGISTRATION_FEE) }}</span>
</div>
</el-col>
<el-col
:xs="24"
:sm="12"
:md="6"
>
<div class="data-cell">
<span class="data-label">其他费用</span>
<span class="data-value">{{ formatValue(reportValue.OTHER_FEE) }}</span>
</div>
</el-col>
<el-col
:xs="24"
:sm="12"
:md="6"
>
<div class="data-cell">
<span class="data-label">退费金额</span>
<span class="data-value">{{ formatValue(reportValue.returnFee) }}</span>
</div>
</el-col>
</el-row>
<el-row
:gutter="16"
class="data-row summary-row"
>
<el-col
:xs="24"
:sm="12"
:md="6"
>
<div class="data-cell summary-cell">
<span class="data-label summary-label">费用总额</span>
<span class="data-value value-highlight">{{ totalFeeAmount }}</span>
</div>
</el-col>
<el-col
:xs="24"
:sm="12"
:md="6"
>
<div class="data-cell summary-cell">
<span class="data-label summary-label">医保报销</span>
<span class="data-value value-highlight">{{ insuranceReimbursement }}</span>
</div>
</el-col>
</el-row>
</div>
</div>
</template>
<script setup name="DayEnd">
import { ref, reactive, toRefs, getCurrentInstance, computed } from 'vue';
import Decimal from 'decimal.js';
import { getTotal, getContractList, getRreportReturnIssue } from './component/api';
import useUserStore from '@/store/modules/user';
import { formatDateStr } from '@/utils/index';
const userStore = useUserStore();
const { proxy } = getCurrentInstance();
const purchaseinventoryList = ref([]);
const reportValue = ref({});
const total = ref(0);
const loading = ref(false);
const showSearch = ref(true);
const ids = ref([]);
const single = ref(true);
const multiple = ref(true);
const occurrenceTime = ref([]);
const contractList = ref([]);
const queryTime = ref([
formatDateStr(new Date(), 'YYYY-MM-DD'),
formatDateStr(new Date(), 'YYYY-MM-DD'),
]);
const contractNo = ref('0000');
const data = reactive({
queryParams: {
form: {},
pageNo: 1,
pageSize: 10,
searchKey: undefined,
purposeLocationId: undefined,
sourceLocationId: undefined,
supplierId: undefined,
approvalTimeSTime: undefined,
approvalTimeETime: undefined,
},
rules: {},
});
const { queryParams, form, rules } = toRefs(data);
getValue();
function getValue() {
loading.value = true;
getTotal({
contractNo: contractNo.value,
startTime: queryTime.value[0] + ' 00:00:00',
endTime: queryTime.value[1] + ' 23:59:59',
entererId: userStore.practitionerId,
}).then((res) => {
loading.value = false;
reportValue.value = res.data;
});
}
getContract();
function getContract() {
getContractList().then((response) => {
contractList.value = response.data;
});
}
function getPharmacyCabinetLists() {
}
/** 查询调拨管理项目列表 */
function getList() {
loading.value = true;
getRreportReturnIssue(queryParams.value).then((res) => {
loading.value = false;
purchaseinventoryList.value = res.data.records;
total.value = res.data.total;
});
}
/** 搜索按钮操作 */
function handleQuery() {
queryParams.value.approvalTimeSTime =
occurrenceTime.value && occurrenceTime.value.length == 2
? occurrenceTime.value[0] + ' 00:00:00'
: '';
queryParams.value.approvalTimeETime =
occurrenceTime.value && occurrenceTime.value.length == 2
? occurrenceTime.value[1] + ' 23:59:59'
: '';
queryParams.value.pageNo = 1;
getList();
}
/** 清空条件按钮操作 */
function handleClear() {
queryParams.value.approvalTimeSTime = '';
queryParams.value.approvalTimeETime = '';
occurrenceTime.value = '';
proxy.resetForm('queryRef');
getList();
}
/** 选择条数 */
function handleSelectionChange(selection) {
ids.value = selection.map((item) => item.id);
single.value = selection.length != 1;
multiple.value = !selection.length;
}
/** 打印门诊日结 */
async function print() {
console.log(reportValue.value, '==reportValue.value==');
const result = {
data: [
{
...reportValue.value,
nickName: userStore.nickName,
orgName: userStore.orgName,
fixmedinsName: userStore.hospitalName,
queryTime: queryTime.value[0] + '~' + queryTime.value[1],
zfAmount: new Decimal(reportValue.value.zhSum || 0).add(reportValue.value.fundSum || 0),
feeAmount: new Decimal(reportValue.value.DIAGNOSTIC_FEE || 0)
.add(reportValue.value.CHECK_FEE || 0)
.add(reportValue.value.DIAGNOSTIC_TEST_FEE || 0)
.add(reportValue.value.MEDICAL_EXPENSE_FEE || 0)
.add(reportValue.value.WEST_MEDICINE || 0)
.add(reportValue.value.CHINESE_MEDICINE_SLICES_FEE || 0)
.add(reportValue.value.CHINESE_MEDICINE_FEE || 0)
.add(reportValue.value.GENERAL_CONSULTATION_FEE || 0)
.add(reportValue.value.REGISTRATION_FEE || 0)
.add(reportValue.value.OTHER_FEE || 0)
.add(reportValue.value.SANITARY_MATERIALS_FEE || 0),
},
],
};
console.log(result, '==result.data==');
let jsonString = JSON.stringify(result, null, 2);
console.log(jsonString, 'jsonstring');
await CefSharp.BindObjectAsync('boundAsync');
await boundAsync
.printReport(getPrintFileName(contractNo.value), jsonString)
.then((response) => {
console.log(response, 'response');
var res = JSON.parse(response);
if (!res.IsSuccess) {
proxy.$modal.msgError('调用打印插件失败:' + res.ErrorMessage);
}
})
.catch((error) => {
proxy.$modal.msgError('调用打印插件失败:' + error);
});
}
function getPrintFileName(value) {
switch (value) {
case '0000':
return '门诊日结单(按登录角色查询)自费.grf';
case '229900':
return '门诊日结单(按登录角色查询)省医保.grf';
case '220100':
return '门诊日结单(按登录角色查询)市医保.grf';
}
}
function formatValue(value) {
return value == null || value == undefined ? '0.00 元' : value.toFixed(2) + ' 元';
}
// 计算属性:费用总额
const totalFeeAmount = computed(() => {
const v = reportValue.value;
const sum =
Number(v.DIAGNOSTIC_FEE || 0) +
Number(v.CHECK_FEE || 0) +
Number(v.DIAGNOSTIC_TEST_FEE || 0) +
Number(v.MEDICAL_EXPENSE_FEE || 0) +
Number(v.WEST_MEDICINE || 0) +
Number(v.CHINESE_MEDICINE_SLICES_FEE || 0) +
Number(v.CHINESE_MEDICINE_FEE || 0) +
Number(v.GENERAL_CONSULTATION_FEE || 0) +
Number(v.REGISTRATION_FEE || 0) +
Number(v.OTHER_FEE || 0) +
Number(v.SANITARY_MATERIALS_FEE || 0);
return formatValue(sum);
});
// 计算属性:医保报销(统筹+账户)
const insuranceReimbursement = computed(() => {
const v = reportValue.value;
const sum = Number(v.tcSum || 0) + Number(v.zhSum || 0);
return formatValue(sum);
});
getList();
getPharmacyCabinetLists();
</script>
<style scoped>
.app-container {
padding: 16px;
}
.report-container {
max-width: 1200px;
margin: 16px auto;
padding: 24px;
background: #fff;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}
.report-title {
text-align: center;
font-size: 20px;
font-weight: 600;
margin: 0 0 20px;
color: #303133;
}
.info-row {
padding: 12px 0;
}
.info-cell {
display: flex;
align-items: center;
padding: 6px 0;
min-height: 32px;
border-bottom: 1px solid #f0f0f0;
}
.info-label {
color: #909399;
font-size: 13px;
white-space: nowrap;
min-width: 90px;
text-align: left;
}
.info-value {
color: #303133;
font-size: 14px;
font-weight: 500;
flex: 1;
}
.data-row {
padding: 4px 0;
}
.data-cell {
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px 16px;
margin-bottom: 6px;
background: #fafafa;
border: 1px solid #f0f0f0;
border-radius: 6px;
min-height: 44px;
transition: background-color 0.2s;
}
.data-cell:hover {
background: #f5f7fa;
}
.data-label {
color: #606266;
font-size: 13px;
white-space: nowrap;
flex-shrink: 0;
}
.data-value {
color: #303133;
font-size: 14px;
font-weight: 600;
text-align: right;
margin-left: 12px;
font-variant-numeric: tabular-nums;
}
.value-highlight {
color: #409eff;
font-weight: 700;
font-size: 15px;
}
.summary-row {
margin-top: 12px;
}
.summary-cell {
background: #ecf5ff;
border: 1px solid #d9ecff;
}
.summary-label {
font-weight: 600;
color: #409eff;
}
.section-title {
font-size: 15px;
font-weight: 600;
color: #409eff;
padding: 8px 0 8px 12px;
margin: 8px 0 6px;
border-left: 3px solid #409eff;
background: linear-gradient(90deg, rgba(64, 158, 255, 0.05) 0%, transparent 100%);
}
:deep(.el-divider--horizontal) {
margin: 16px 0;
}
.el-form--inline .el-form-item {
margin-bottom: 12px;
margin-right: 18px;
}
@media (max-width: 768px) {
.data-label {
min-width: auto;
}
.data-cell {
padding: 8px 12px;
}
.info-label {
min-width: 70px;
}
}
</style>