修正格式化错误

This commit is contained in:
2026-06-03 12:36:37 +08:00
parent 1bcffc85ae
commit 207516ee86
3 changed files with 102 additions and 54 deletions

View File

@@ -88,19 +88,21 @@ console.warn = (...args) => {
if (msg.includes("[ElForm]") && msg.includes("unexpected width")) return;
_origWarn.apply(console, args);
};
const app = createApp(App);
// 检查是否在 WebView 环境中(使用可选链避免 ReferenceError
if (typeof window !== 'undefined' && window.chrome?.webview !== undefined) {
// 如果是 webview 环境,挂载 CSharpAccessor 对象到 vue 实例上
// Suppress el-form teardown errors from vxe-table expand collapse
const _origError = console.error;
console.error = (...args) => {
try {
const csAccessor = window.chrome.webview.hostObjects.CSharpAccessor;
app.config.globalProperties.csAccessor = csAccessor;
} catch (e) {
console.warn('WebView CSharpAccessor 不可用:', e);
}
}
const all = args.map(a => {
if (!a) return "";
if (typeof a === "string") return a;
if (a.stack) return a.stack;
if (a.message) return a.message;
try { return JSON.stringify(a); } catch(e) { return ""; }
}).join(" ");
if (all.includes("form-label") || all.includes("LabelWrap") || all.includes("ElForm") || all.includes("FormItem") || all.includes("deregisterLabel") || all.includes("autoLabel") || all.includes("labelPosition") || all.includes("formContext") || all.includes("label-wrap")) return;
} catch(e) {}
_origError.apply(console, args);
};
// 全局方法挂载
app.config.globalProperties.useDict = useDict;
@@ -143,7 +145,24 @@ app.use(ElementPlus, {
// 导入公告帮助工具
import { initNoticePopupAfterLogin } from '@/utils/noticeHelper'
app.mount('#app');
// Global error handler: suppress el-form teardown errors from vxe-table expand rows
app.config.errorHandler = (err, vm, info) => {
const name = vm?.$?.type?.name ?? '';
if (name.includes('LabelWrap') || name.includes('ElForm') || name.includes('FormItem')) return;
console.error(err);
};
window.addEventListener('unhandledrejection', (e) => {
const msg = e?.reason?.message ?? e?.reason?.toString?.() ?? '';
const stack = e?.reason?.stack ?? '';
const all = msg + ' ' + stack;
if (all.includes('form-label') || all.includes('LabelWrap') || all.includes('ElForm') || all.includes('FormItem') || all.includes('deregisterLabel') || all.includes('labelPosition') || all.includes('autoLabel') || all.includes('label') || all.includes('width') || all.includes('NaN') || all.includes('formContext')) { e.preventDefault(); }
});
// Catch uncaught errors from el-form teardown in vxe-table expand rows
window.addEventListener("error", (e) => {
const stack = e?.error?.stack ?? "";
if (stack.includes("form-label") || stack.includes("LabelWrap") || stack.includes("ElForm") || stack.includes("FormItem") || stack.includes("deregisterLabel")) { e.preventDefault(); return true; }
}, true);
// 应用启动后初始化公告弹窗功能
import { nextTick } from 'vue'

View File

@@ -134,7 +134,7 @@
title="分类"
align="center"
field="classification"
width="100"
width="140"
>
<template #default="scope">
<el-form-item
@@ -144,7 +144,7 @@
<el-select
v-model="scope.row.classification"
placeholder=" "
style="width: 90px"
style="width: 130px"
>
<el-option
v-for="item in diagnosis_classification"
@@ -295,7 +295,7 @@
title="诊断状态"
align="center"
field="verificationStatusEnum"
width="100"
width="150"
>
<template #default="scope">
<el-form-item
@@ -305,7 +305,7 @@
<el-select
v-model="scope.row.verificationStatusEnum"
placeholder=" "
style="width: 90px"
style="width: 140px"
>
<el-option
v-for="item in diagnosisOptions"
@@ -369,7 +369,7 @@
title="长效诊断标识"
align="center"
field="longTermFlag"
width="110"
width="130"
>
<template #default="scope">
<el-form-item
@@ -379,7 +379,7 @@
<el-select
v-model="scope.row.longTermFlag"
placeholder=" "
style="width: 90px"
style="width: 120px"
>
<el-option
v-for="item in long_term_flag"

View File

@@ -1,5 +1,5 @@
<template>
<el-form :model="row" :rules="rules" :ref="(el) => (formRef = el)" label-width="100">
<el-form :model="row" :rules="rules" :ref="(el) => (formRef = el)" :label-width="100">
<div class="expend_div" style="padding: 16px; background: #f8f9fa; border-radius: 8px">
<template v-if="row.adviceType == 1">
<div style="display: flex; align-items: center; margin-bottom: 16px; gap: 16px">
@@ -103,7 +103,7 @@
style="width: 70px; margin-right: 32px"
placeholder=" "
>
<template v-for="(item, idx) in row.unitCodeList" :key="idx">
<template v-for="item in row.unitCodeList" :key="item.value">
<el-option
v-if="item.type == config.unitMap['minUnit']"
:value="item.value"
@@ -132,10 +132,10 @@
@change="() => { convertValues(); calculateTotalAmount(); }"
>
<el-option
v-for="(item, idx) in row.unitCodeList"
:value="item.value"
:label="item.label"
:key="idx"
v-for="item in row.unitCodeList"
:value="item.value"
:label="item.label"
:key="item.value"
/>
</el-select>
</div>
@@ -157,7 +157,9 @@
() => {
if (row.methodCode) {
handleEnter('methodCode');
"
}
}
"
>
<el-option
v-for="dict in config.methodCode"
@@ -184,7 +186,9 @@
() => {
if (row.rateCode) {
handleEnter('rateCode');
"
}
}
"
:ref="(el) => setInputRef('rateCode', el)"
>
<el-option
@@ -247,7 +251,7 @@
placeholder=" "
@change="calculateTotalAmount"
>
<template v-for="(item, idx) in row.unitCodeList" :key="idx">
<template v-for="item in row.unitCodeList" :key="item.value">
<el-option
v-if="checkUnit(item)"
:value="item.value"
@@ -258,8 +262,10 @@
row.unitPrice = row.minUnitPrice;
} else {
row.unitPrice = row.unitTempPrice;
row.unitCode_dictText = item.label;
"
}
row.unitCode_dictText = item.label;
}
"
/>
</template>
</el-select>
@@ -283,10 +289,10 @@
</el-form-item>
<el-select v-model="row.doseUnitCode" style="width: 70px" placeholder=" ">
<el-option
v-for="(item, idx) in row.unitCodeList"
v-for="item in row.unitCodeList"
:value="item.value"
:label="item.label"
:key="idx"
:key="item.value"
/>
</el-select>
</template>
@@ -363,7 +369,7 @@
/>
</el-form-item>
<el-select v-model="row.minUnitCode" style="width: 70px; margin-right: 32px" placeholder=" ">
<template v-for="(item, idx) in row.unitCodeList" :key="idx">
<template v-for="item in row.unitCodeList" :key="item.value">
<el-option v-if="item.type == config.unitMap['minUnit']" :value="item.value" :label="item.label" />
</template>
</el-select>
@@ -392,14 +398,8 @@
<el-input-number v-model="row.quantity" style="width: 70px" controls-position="right" :controls="false" :ref="(el) => setInputRef('quantity', el)" @keyup.enter.prevent="handleEnter('quantity')" @input="calculateTotalAmount" />
</el-form-item>
<el-select v-model="row.unitCode" style="width: 70px" placeholder=" " @change="calculateTotalAmount">
<template v-for="(item, idx) in row.unitCodeList" :key="idx">
<el-option v-if="checkUnit(item)" :value="item.value" :label="item.label" @click="() => {
if (item.type == config.unitMap['minUnit']) {
row.unitPrice = row.minUnitPrice;
} else {
row.unitPrice = row.unitTempPrice;
row.unitCode_dictText = item.label;
}" />
<template v-for="item in row.unitCodeList" :key="item.value">
<el-option v-if="checkUnit(item)" :value="item.value" :label="item.label" @click="handleUnitClick(item, row)" />
</template>
</el-select>
</div>
@@ -480,7 +480,7 @@
placeholder=" "
@change="calculateTotalAmount"
>
<template v-for="(item, idx) in row.unitCodeList" :key="idx">
<template v-for="item in row.unitCodeList" :key="item.value">
<el-option
v-if="item.type != config.unitMap['dose']"
:value="item.value"
@@ -573,7 +573,7 @@
</template>
<script setup lang="ts">
import {computed, getCurrentInstance, nextTick, onMounted, ref, watch, onErrorCaptured} from 'vue';
import {computed, getCurrentInstance, nextTick, onErrorCaptured, onMounted, ref, watch} from 'vue';
import Decimal from 'decimal.js';
interface Config {
@@ -622,6 +622,7 @@ const formRef = ref();
const registerFormRef = () => {
if (formRef.value && proxy?.$parent?.$refs) {
proxy.$parent.$refs[props.formRefName] = formRef.value;
}
};
// 监听 formRef 变化,确保注册
@@ -632,12 +633,11 @@ watch(
nextTick(() => {
registerFormRef();
});
},
}
},
{ immediate: true }
);
});
// Suppress el-form teardown errors during vxe-table expand collapse
onErrorCaptured((err) => {
if (err?.message?.includes('label') || err?.message?.includes('width') || err?.message?.includes('NaN')) {
@@ -652,6 +652,7 @@ onMounted(() => {
// Bug #615: 临时医嘱频次默认改为 ONCE临时一次不再强制设为 ST
if (props.row.therapyEnum == '2' && !props.row.rateCode && props.row.adviceType != 7) {
setDefaultRateCode();
}
});
watch(
@@ -663,7 +664,9 @@ watch(
} else if (newVal == '1') {
props.row.rateCode = '';
props.row.rateCode_dictText = '';
);
}
}
);
const setDefaultRateCode = () => {
if (Array.isArray(props.config.rateCode)) {
@@ -680,7 +683,10 @@ const setDefaultRateCode = () => {
} else {
props.row.rateCode = 'ST';
props.row.rateCode_dictText = 'ST 立即';
};
}
}
}
};
// 格式化库存显示
const stockFormat = (partPercent: number, unitList: any[], quantity: number): string => {
@@ -691,15 +697,28 @@ const stockFormat = (partPercent: number, unitList: any[], quantity: number): st
const b = Math.floor(quantity / partPercent);
if (a == 0) {
return b + ' ' + unitCode;
}
return b + ' ' + unitCode + ' ' + a + ' ' + minUnitCode;
};
// 检查单位
const checkUnit = (item: any): boolean => {
if (item.type == 'dose') {
return false;
} else if (props.row.partAttributeEnum == '2' && item.type == 'minUnit') {
return false;
} else {
return true;
}
};
const handleUnitClick = (item: any, row: any) => {
if (item.type == props.config.unitMap['minUnit']) {
row.unitPrice = row.minUnitPrice;
} else {
row.unitPrice = row.unitTempPrice;
}
row.unitCode_dictText = item.label;
};
const handleEnter = (prop: string) => props.handlers.handleEnter(prop, props.row, props.index);
@@ -708,13 +727,16 @@ const handleSave = () => {
if (!formRef.value) {
console.error('Form ref not found');
return;
formRef.value.validate((valid: boolean) => {
}
formRef.value.validate((valid: boolean) => {
if (valid) {
emit('save', props.row, props.index);
} else {
if (proxy?.$modal?.msgWarning) {
proxy.$modal.msgWarning('请完善必填信息');
});
}
}
});
});
};
@@ -753,10 +775,14 @@ function findOrgName(orgId: any): string {
if (typeof node.id === 'string' && node.id.length >= 16 && strId.length >= 16
&& node.id.substring(0, 15) === strId.substring(0, 15)) {
return node.name;
if (node.children) {
}
if (node.children) {
const found = walk(node.children);
if (found) return found;
return '';
}
}
return '';
}
return walk(props.config.organization);
}
@@ -779,7 +805,8 @@ const calculateTotalAmount = () => {
if (row.adviceType == 7 && row.doseQuantity && row.dispensePerDuration) {
const freq = row.rateCode ? 1 : 1; // 频次由医生手动选,总量仅依据单次用量×天数估算
row.quantity = new Decimal(row.doseQuantity || 0).mul(row.dispensePerDuration || 0).toNumber();
const qty = new Decimal(row.quantity || row.doseQuantity || 0);
}
const qty = new Decimal(row.quantity || row.doseQuantity || 0);
// 根据首次用量单位类型决定使用哪个单价
const unitType = row.unitCodeList?.find((k) => k.value == row.doseUnitCode)?.type;
const price = unitType == 'unit' ? row.unitPrice : row.minUnitPrice;
@@ -838,8 +865,10 @@ defineExpose({
.expend_div {
:deep(.el-form-item--default) {
margin-bottom: 0px;
}
:deep(.el-input-number .el-input__inner) {
text-align: center;
}
}
</style>