Explorar o código

调整账单四舍五入取整问题

chenjun hai 1 mes
pai
achega
11bf16c422

+ 47 - 65
src/components/Table2/index.vue

@@ -16,11 +16,11 @@
     <el-table-column
       type="selection"
       :selectable="handleSelectable"
-      width="55"
+      width="40"
       v-if="props.selection"
       fixed
     />
-    <el-table-column header-align="center" align="center" label="编号" width="70" fixed>
+    <el-table-column header-align="center" align="center" label="编号" width="62" fixed>
       <template #default="scope">
         {{
           scope.$index +
@@ -280,15 +280,14 @@
         :width="item.width"
       >
         <template #default="scope">
-          <el-popover
-            :title="scope.row.elderName"
-            :width="530"
-            placement="top-start"
-          >
+          <el-popover :title="scope.row.elderName" :width="530" placement="top-start">
             <template #reference>
-              <el-tag :type="(!scope.row.otherFiles || scope.row.otherFiles == '') ? 'warning' : 'primary'">{{
-                  (!scope.row.otherFiles || scope.row.otherFiles == '') ? '未上传' : '已上传'
-                }}</el-tag>
+              <el-tag
+                :type="!scope.row.otherFiles || scope.row.otherFiles == '' ? 'warning' : 'primary'"
+                >{{
+                  !scope.row.otherFiles || scope.row.otherFiles == '' ? '未上传' : '已上传'
+                }}</el-tag
+              >
             </template>
             <el-table :data="parsingJSON(scope.row.otherFiles)">
               <el-table-column label="预览" width="80" align="center">
@@ -303,16 +302,22 @@
                   <Icon v-else icon="ep:document" style="font-size: 20px; color: #909399" />
                 </template>
               </el-table-column>
-              <el-table-column width="150" property="fileName" label="附件名称" show-overflow-tooltip/>
+              <el-table-column
+                width="150"
+                property="fileName"
+                label="附件名称"
+                show-overflow-tooltip
+              />
               <el-table-column width="180" property="createTime" label="创建时间" />
-              <el-table-column width="90"  label="操作" align="center">
-                <template #default="{row}">
-                  <el-button type="primary" link size="small" @click="handleDownload(row)">下载</el-button>
+              <el-table-column width="90" label="操作" align="center">
+                <template #default="{ row }">
+                  <el-button type="primary" link size="small" @click="handleDownload(row)"
+                    >下载</el-button
+                  >
                 </template>
               </el-table-column>
             </el-table>
           </el-popover>
-
         </template>
       </el-table-column>
     </template>
@@ -443,13 +448,13 @@ import { TableColumn } from '@/types/table'
 import { dateFormatter, dateFormatter2 } from '@/utils/formatTime'
 import { getDictLabel, getDictOptions } from '@/utils/dict'
 import { useAppStore } from '@/store/modules/app'
-import { fixedNum, formatCeil, formatNum, formatRound } from '@/utils/formatter'
+import { fixedNum, formatCeil, formatNum, formatRound, formatTrunc } from '@/utils/formatter'
 import { tableHeaderColor } from '@/utils/table'
 import { breakpointsTailwind, useBreakpoints } from '@vueuse/core'
 import { formatTime } from '@/utils'
 import { useUserStore } from '@/store/modules/user'
 import { useSettingStore } from '@/store/modules/setting'
-import {FileItem, isImageFile} from "@/components/UploadFile";
+import { FileItem, isImageFile } from '@/components/UploadFile'
 const userStore = useUserStore()
 const settingStore = useSettingStore()
 const radioId = ref() // 单选表格
@@ -548,13 +553,12 @@ const toFixedNum = (num: any) => {
 }
 
 const parsingJSON = (row) => {
-  if(!row || row==''){
+  if (!row || row == '') {
     return []
-  }else {
+  } else {
     let json = JSON.parse(row)
     return json
   }
-
 }
 
 const handleSelectable = (row) => {
@@ -564,7 +568,6 @@ const handleSelectable = (row) => {
   return true
 }
 
-
 const handleDownload = (row: FileItem) => {
   console.log(row)
   fetch(row.fileUrl)
@@ -645,59 +648,34 @@ const tableHeight = () => {
 }
 
 const formatActualPrice = (item, type) => {
+  // 统一口径:先对各分量求和成总额 rawSum,再对总额做一次性取整/保留小数。
+  // 不可逐项取整再加总——分量为负时直接向 0 截断/取整会放大误差(如 -787.5→-787 使 3712.5 变 3713)
+  const rawSum =
+    Number(item['bedAmount']) +
+    Number(item['nurseAmount']) +
+    Number(item['mealAmount']) +
+    Number(item['otherAmount']) +
+    Number(item['insuranceAmount'])
   if (item.type == 1) {
     if (settingStore.getAdmissionBill == 2) {
       // 向上取整
-      return formatNum(
-        Number(formatCeil(item['bedAmount'])) +
-          Number(formatCeil(item['nurseAmount'])) +
-          Number(formatCeil(item['mealAmount'])) +
-          Number(formatRound(item['otherAmount'])) +
-          Number(formatRound(item['insuranceAmount']))
-      )
+      return formatNum(formatCeil(rawSum))
     } else if (settingStore.getAdmissionBill == 3) {
       // 四舍五入保留两位
-      return formatNum(
-        Number(fixedNum(item['bedAmount'])) +
-          Number(fixedNum(item['nurseAmount'])) +
-          Number(fixedNum(item['mealAmount'])) +
-          Number(fixedNum(item['otherAmount'])) +
-          Number(fixedNum(item['insuranceAmount']))
-      )
+      return formatNum(fixedNum(rawSum))
     } else if (settingStore.getAdmissionBill == 4) {
       // 四舍五入取整
-      return formatNum(
-        Number(formatRound(item['bedAmount'])) +
-          Number(formatRound(item['nurseAmount'])) +
-          Number(formatRound(item['mealAmount'])) +
-          Number(formatRound(item['otherAmount'])) +
-          Number(formatRound(item['insuranceAmount']))
-      )
+      return formatNum(formatRound(rawSum))
     } else {
-      return formatNum(
-        Number(item['bedAmount']) +
-          Number(item['nurseAmount']) +
-          Number(item['mealAmount']) +
-          Number(item['otherAmount']) +
-          Number(item['insuranceAmount'])
-      )
+      // 应收,不取整
+      return formatNum(rawSum)
     }
   } else if (settingStore.getRounding) {
-    return formatNum(
-      Number(formatRound(item['bedAmount'])) +
-        Number(formatRound(item['nurseAmount'])) +
-        Number(formatRound(item['mealAmount'])) +
-        Number(formatRound(item['otherRoundAmount'])) +
-        Number(formatRound(item['insuranceAmount']))
-    )
+    // 直丢小数
+    return formatNum(formatTrunc(rawSum))
   } else if (settingStore.getFix2Num) {
-    return formatNum(
-      Number(fixedNum(item['bedAmount'])) +
-        Number(fixedNum(item['nurseAmount'])) +
-        Number(fixedNum(item['mealAmount'])) +
-        Number(fixedNum(item['otherAmount'])) +
-        Number(fixedNum(item['insuranceAmount']))
-    )
+    // 四舍五入保留两位
+    return formatNum(fixedNum(rawSum))
   } else {
     return formatNum(item[type.field])
   }
@@ -718,7 +696,7 @@ const formatAdmissionBillRoundUp = (item, type) => {
       return formatNum(item[type.field])
     }
   } else if (settingStore.getRounding) {
-    return formatRound(item[type.field])
+    return formatTrunc(item[type.field])
   } else if (settingStore.getFix2Num) {
     return fixedNum(item[type.field])
   } else {
@@ -727,8 +705,12 @@ const formatAdmissionBillRoundUp = (item, type) => {
 }
 
 const calcPrice = (row, item) => {
-  if (settingStore.getRounding || (row.type == 1 && settingStore.getAdmissionBill == 4)) {
+  // 入院账单"四舍五入取整"(getAdmissionBill==4)仍走四舍五入
+  if (row.type == 1 && settingStore.getAdmissionBill == 4) {
     return formatRound(row[item.otherField || item.field])
+  } else if (settingStore.getRounding) {
+    // 账单金额单项取整设置:直丢小数
+    return formatTrunc(row[item.otherField || item.field])
   } else if (settingStore.getFix2Num) {
     return fixedNum(row[item.field])
   } else {

+ 14 - 6
src/utils/formatter.ts

@@ -12,9 +12,8 @@ export const fenToYuanFormat = (_, __, cellValue: any, ___) => {
 
 //四舍五入 保留两位小数
 export const fixedNum = (num) => {
-  if (num != undefined) {
-    num = parseFloat(num).toFixed(2)
-    return num
+  if (num !== undefined && num !== null && num !== '' && !isNaN(Number(num))) {
+    return new Decimal(num).toFixed(2)
   }
 }
 
@@ -34,7 +33,7 @@ export const formatNum = (val: string | number) => {
 
 export const formatCeil = (val: string | number) => {
   if (val && !isNaN(Number(val)) && (val !== undefined && val !== null)) {
-   return Math.ceil(val).toFixed(2)
+   return new Decimal(val).ceil().toFixed(2)
   }else if(val === 0){
     return val
   }
@@ -43,8 +42,17 @@ export const formatCeil = (val: string | number) => {
 
 // 取整后保留两位小数
 export const formatRound = (val) => {
-  if (!isNaN(Number(val))) {
-    return Math.round(val).toFixed(2)
+  if (val !== undefined && val !== null && val !== '' && !isNaN(Number(val))) {
+    return new Decimal(val).round().toFixed(2)
+  }
+  return ''
+}
+
+// 直丢小数(向 0 截断,不四舍五入),取整后保留两位小数
+// 用于"账单金额单项取整设置" value=2,期望是抹掉所有小数而不是四舍五入
+export const formatTrunc = (val) => {
+  if (val !== undefined && val !== null && val !== '' && !isNaN(Number(val))) {
+    return new Decimal(val).trunc().toFixed(2)
   }
   return ''
 }

+ 1 - 1
src/views/elderly/fee/bill-pay/preview.vue

@@ -270,7 +270,7 @@ const open = async (id, row) => {
       const payLine =
         getDictLabel(DICT_TYPE.BILL_PAY_TYPE, info.payType) +
         ':' +
-        info.payAmount +
+        formatNum(info.payAmount) +
         '元(支付时间:' +
         formatPayCreatedTime(info.createdTime) +
         ')'

+ 5 - 3
src/views/elderly/fee/bill-pay/unpay-preview.vue

@@ -68,8 +68,10 @@
             <td :colspan="8">
               <div>
                 金额:{{ billTotalPrice }}元;已缴费共计:&nbsp;{{
-                  formatNum(payTotal)
-                }}&nbsp;元;剩余未缴费:&nbsp;{{ formatNum(unPayTotal) }}&nbsp;元
+                  rounding ? formatTrunc(payTotal) : formatNum(payTotal)
+                }}&nbsp;元;剩余未缴费:&nbsp;{{
+                  rounding ? formatTrunc(unPayTotal) : formatNum(unPayTotal)
+                }}&nbsp;元
               </div>
               <div
                 v-show="tempResValue.payInfos && tempResValue.payInfos.length > 0"
@@ -127,7 +129,7 @@
 <script setup lang="ts">
 import { getExpenseOrderDetail } from '@/api/elderly/fee/bill-pay'
 import { useUserStore } from '@/store/modules/user'
-import { formatNum, formatCeil, formatRound } from '@/utils/formatter'
+import { formatNum, formatCeil, formatRound, formatTrunc } from '@/utils/formatter'
 import { DICT_TYPE, getDictLabel } from '@/utils/dict'
 import { useSettingStore } from '@/store/modules/setting'
 import { formatDateTime } from '@/components/UploadFile'

+ 4 - 4
src/views/elderly/fee/column.ts

@@ -73,19 +73,19 @@ export const BillPayColumns = reactive([
   {
     label: '长者姓名',
     field: 'elderName',
-    width: 120,
+    width: 110,
     fixed: true
   },
   {
     label: '床位号',
     field: 'bedName',
-    width: 180,
+    width: 150,
     fixed: true
   },
   {
     label: '账单月',
     field: 'billingMonth',
-    width: 120,
+    width: 82,
     fixed: true
   },
   // {
@@ -100,7 +100,7 @@ export const BillPayColumns = reactive([
     field: 'payStatus',
     dictArr: DICT_TYPE.PAY_TYPE,
     type: '2',
-    width: 100
+    width: 80
   },
   {
     label: '缴费时间',

+ 2 - 2
src/views/elderly/fee/leave-settle/Form.vue

@@ -15,7 +15,7 @@
 <!--            <el-button plain @click="handleEdit" class="mr-10px"  v-hasPermi="['leave_update_fee']">修改押金费用</el-button>-->
 
             <span>{{ dataForm.refundAmount > 0 ? '应收' : '应退' }}金额</span>
-            <span class="price ml-1">¥ {{ rounding ? formatRound(dataForm.refundAmount) : formatNum(dataForm.refundAmount) }}</span></span
+            <span class="price ml-1">¥ {{ rounding ? formatTrunc(dataForm.refundAmount) : formatNum(dataForm.refundAmount) }}</span></span
           >
           <!-- <span class="underline tr"><span class="text">原{{ totalAmount > 0 ? '应退' : '应收' }}金额</span> {{ formatNum(Math.abs(totalAmount)) }}</span> -->
         </div>
@@ -260,7 +260,7 @@ import {
 } from '@/api/elderly/fee/leave-settle'
 import { tableHeaderColor } from '@/utils/table'
 import { DICT_TYPE, getDictLabel, getDictOptions } from '@/utils/dict'
-import { fixedNum, formatDecimal, formatNum, formatRid, formatRound } from '@/utils/formatter'
+import { fixedNum, formatDecimal, formatNum, formatRid, formatRound, formatTrunc } from '@/utils/formatter'
 import Detail from './Detail.vue'
 import { useTagsViewStore } from '@/store/modules/tagsView'
 import { useTagsView } from '@/hooks/web/useTagsView'

+ 3 - 3
src/views/elderly/fee/leave-settle/Print.vue

@@ -105,7 +105,7 @@ import {
 } from '@/api/elderly/fee/leave-settle'
 import { formatDate } from '@/utils/formatTime'
 import { getDictLabel, DICT_TYPE } from '@/utils/dict'
-import { formatDecimal, formatNum, formatRid, dealBigMoney, formatRound } from '@/utils/formatter'
+import { formatDecimal, formatNum, formatRid, dealBigMoney, formatRound, formatTrunc } from '@/utils/formatter'
 import { formatTime } from '@/utils'
 import { useSettingStore } from '@/store/modules/setting'
 defineOptions({ name: 'RefundSettlePrint' })
@@ -154,7 +154,7 @@ const open = async (id,detail:boolean) => {
       dataForm.value.orderNumber = result.orderNumber
       dataForm.value.settlementPersonName = result.settlementPersonName
       dataForm.value.settlementTime = result.settlementTime
-      totalAmount.value = rounding.value ? formatRound(result.refundAmount) : result.refundAmount
+      totalAmount.value = rounding.value ? formatTrunc(result.refundAmount) : result.refundAmount
       for (const item of result.refundSettlementOrderItems){
        // item.amount =  rounding.value ? formatRound(item.amount) : item.amount
        // item.amount =  item.amount
@@ -170,7 +170,7 @@ const open = async (id,detail:boolean) => {
       dataForm.value.orderNumber = result.orderNumber
       dataForm.value.settlementPersonName = result.settlementPersonName
       dataForm.value.settlementTime = result.settlementTime
-      totalAmount.value = rounding.value ? formatRound(result.payOrder.payAmount) : result.payOrder.payAmount
+      totalAmount.value = rounding.value ? formatTrunc(result.payOrder.payAmount) : result.payOrder.payAmount
       for (const item of result.items){
         //item.amount =  rounding.value ? formatRound(item.actualRefundAmount) : item.actualRefundAmount
         item.amount =  item.actualRefundAmount