✨ 完善变更记录、客商评分与车辆表单
变更记录详情统一为居中分页弹窗,并去掉经办人等信息行。 客商评分支持删除、提交前自评校验、复评后才能审批,以及 0 分提交。 车辆外廓尺寸和载质量单位改到输入框内,认证审核标签按四字换行,使用部门必填并默认当前部门。 临时额度的 -1 占位金额显示为空。新增项目编号可留空由系统生成。 修复缓存总单页在打开新增项目时误请求缺少 id 的详情接口。 详情页状态与运输方式标签样式统一。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,7 +1,17 @@
|
||||
<template>
|
||||
<div v-loading="loading" class="master-detail">
|
||||
<section v-if="master" class="detail-overview">
|
||||
<div class="detail-heading"><div><h2>多联总单详情 <span>|</span> {{ master.masterNo }}</h2><el-tag :type="statusType(master.businessStatus)" class="status-text">{{ statusName(master.businessStatus) }}</el-tag><el-tag v-if="transportFlowLabel" type="info" class="transport-flow-tag">{{ transportFlowLabel }}</el-tag></div></div>
|
||||
<div class="detail-heading">
|
||||
<div>
|
||||
<h2>多联总单详情 <span>|</span> {{ master.masterNo }}</h2>
|
||||
<el-tag :type="statusType(master.businessStatus)">{{
|
||||
statusName(master.businessStatus)
|
||||
}}</el-tag>
|
||||
<el-tag v-if="transportFlowLabel" type="primary" class="transport-flow-tag">{{
|
||||
transportFlowLabel
|
||||
}}</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
<dl class="detail-meta">
|
||||
<div>
|
||||
<dt>客户</dt>
|
||||
@@ -132,6 +142,7 @@ export default {
|
||||
dateRange() { return this.master?.planStartTime && this.master?.planEndTime ? `${String(this.master.planStartTime).slice(0, 10)} ~ ${String(this.master.planEndTime).slice(0, 10)}` : '-'; },
|
||||
},
|
||||
async mounted() {
|
||||
if (!this.id) return;
|
||||
this.loading = true;
|
||||
try {
|
||||
const res = await api.getDetail(this.id);
|
||||
@@ -282,8 +293,36 @@ export default {
|
||||
<style scoped lang="scss">
|
||||
.master-detail { padding-bottom: 20px; color: #303133; }
|
||||
.detail-overview, .execution-detail-card { margin-bottom: 8px; border: 1px solid #eff1f7; background: #fff; }
|
||||
.detail-heading { display: flex; align-items: center; justify-content: space-between; padding: 18px 24px; h2 { display: inline-block; margin: 0 16px 0 0; font-size: 20px; } h2 span { margin: 0 8px; color: #909399; font-weight: 400; } }
|
||||
.transport-flow-tag { margin-left: 8px; }
|
||||
.detail-heading {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 18px 24px;
|
||||
|
||||
h2 {
|
||||
display: inline-block;
|
||||
margin: 0 16px 0 0;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
h2 span {
|
||||
margin: 0 8px;
|
||||
color: #909399;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
:deep(.el-tag) {
|
||||
height: 28px;
|
||||
padding: 0 12px;
|
||||
border: 0;
|
||||
border-radius: 8px;
|
||||
font-size: 13px;
|
||||
line-height: 28px;
|
||||
}
|
||||
}
|
||||
.transport-flow-tag {
|
||||
margin-left: 8px;
|
||||
}
|
||||
.detail-meta { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 18px 24px; margin: 0; padding: 0 24px 20px; dt { margin-bottom: 6px; color: #909399; font-size: 13px; } dd { display: flex; flex-wrap: wrap; gap: 8px 16px; margin: 0; color: #303133; font-size: 14px; word-break: break-all; } :deep(.el-link) { font-size: 14px; } }
|
||||
.route-map { display: flex; align-items: flex-start; padding: 16px 24px 20px; border-top: 1px solid #eff1f7; overflow-x: auto; }
|
||||
.route-map__node { display: grid; flex: 0 0 150px; justify-items: center; gap: 6px; text-align: center; strong { font-size: 16px; white-space: nowrap; } small { color: #606266; white-space: nowrap; } }
|
||||
|
||||
@@ -295,6 +295,7 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
async load() {
|
||||
if (!this.id) return;
|
||||
this.loading = true;
|
||||
try {
|
||||
const res = await api.getDetail(this.id);
|
||||
|
||||
@@ -1774,12 +1774,17 @@
|
||||
<div class="waybill-manage-page__waybill-heading">
|
||||
<strong>运单详情</strong>
|
||||
<span>{{ detailRow.waybillNo || '-' }}</span>
|
||||
<span class="detail-status-text status-text-success">{{
|
||||
displayStatus(detailRow, 'businessStatus')
|
||||
}}</span>
|
||||
<span class="detail-status-text detail-transport-type">
|
||||
{{ getTransportTypeLabel(waybillTransportMode(detailRow)) || '-' }}
|
||||
</span>
|
||||
<el-tag :type="statusTagType(detailRow.businessStatus)">
|
||||
{{ displayStatus(detailRow, 'businessStatus') }}
|
||||
</el-tag>
|
||||
<el-tag type="primary">
|
||||
{{
|
||||
detailRow.transportTypeName ||
|
||||
getTransportTypeLabel(detailRow.transportType) ||
|
||||
waybillTransportMode(detailRow) ||
|
||||
'-'
|
||||
}}
|
||||
</el-tag>
|
||||
<el-link
|
||||
v-if="detailRow.id"
|
||||
class="waybill-manage-page__waybill-route-change-link"
|
||||
@@ -2184,7 +2189,11 @@
|
||||
/>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="司机上传" name="driverUpload">
|
||||
<el-tab-pane
|
||||
v-if="waybillDriverUploads.length"
|
||||
label="司机上传"
|
||||
name="driverUpload"
|
||||
>
|
||||
<div
|
||||
v-loading="waybillPunchRecordsLoading"
|
||||
class="waybill-manage-page__driver-upload-grid"
|
||||
@@ -2201,11 +2210,6 @@
|
||||
{{ photo.label || '凭证' }}
|
||||
</div>
|
||||
</div>
|
||||
<el-empty
|
||||
v-if="!waybillPunchRecordsLoading && !waybillDriverUploads.length"
|
||||
description="暂无司机上传数据"
|
||||
:image-size="50"
|
||||
/>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
@@ -5265,7 +5269,9 @@ export default {
|
||||
: defaultText;
|
||||
},
|
||||
statusTagType(status) {
|
||||
if ([1, 'pending', 'processing', 'approved', 'change_approved'].includes(status)) {
|
||||
if (
|
||||
[1, 'pending', 'processing', 'running', 'approved', 'change_approved'].includes(status)
|
||||
) {
|
||||
return 'success';
|
||||
}
|
||||
if ([2, 'cancelled', 'withdrawn', 'draft'].includes(status)) {
|
||||
@@ -9763,6 +9769,15 @@ export default {
|
||||
strong {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
:deep(.el-tag) {
|
||||
height: 28px;
|
||||
padding: 0 12px;
|
||||
border: 0;
|
||||
border-radius: 8px;
|
||||
font-size: 13px;
|
||||
line-height: 28px;
|
||||
}
|
||||
}
|
||||
|
||||
&__waybill-route-change-link {
|
||||
|
||||
@@ -966,44 +966,10 @@
|
||||
@close="attachmentImagePreviewVisible = false"
|
||||
/>
|
||||
|
||||
<el-dialog
|
||||
<change-record-detail-dialog
|
||||
v-model="detailChangeRecordVisible"
|
||||
title="变更记录详情"
|
||||
append-to-body
|
||||
destroy-on-close
|
||||
width="1100px"
|
||||
top="10px"
|
||||
class="contract-change-record-detail-dialog"
|
||||
>
|
||||
<div v-if="detailChangeRecord" class="contract-change-record-detail-meta">
|
||||
<span>经办人:{{ detailChangeRecord.handlerUserName || '-' }}</span>
|
||||
<span>变更类型:{{ detailChangeRecord.changeType || '-' }}</span>
|
||||
<span>状态:{{ detailChangeRecord.statusName || detailChangeRecord.status || '-' }}</span>
|
||||
</div>
|
||||
<el-table :data="detailChangeRecordDetailRows" border :show-overflow-tooltip="false">
|
||||
<el-table-column prop="field" label="变更字段" min-width="180" />
|
||||
<el-table-column
|
||||
prop="before"
|
||||
label="变更前"
|
||||
min-width="360"
|
||||
class-name="contract-change-record-detail-value"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="after"
|
||||
label="变更后"
|
||||
min-width="500"
|
||||
class-name="contract-change-record-detail-value"
|
||||
/>
|
||||
</el-table>
|
||||
<el-empty
|
||||
v-if="!detailChangeRecordDetailRows.length"
|
||||
description="暂无变更内容"
|
||||
:image-size="60"
|
||||
/>
|
||||
<template #footer>
|
||||
<el-button type="primary" @click="detailChangeRecordVisible = false">关闭</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
:rows="detailChangeRecordDetailRows"
|
||||
/>
|
||||
|
||||
<billing-plan-editor
|
||||
v-model="detailBillingPlanBox"
|
||||
@@ -1042,6 +1008,7 @@ import { getToken } from '@/utils/auth';
|
||||
import { downloadFileByUrl, downloadXls } from '@/utils/util';
|
||||
import { submitMkApprovalFlow } from '@/utils/mk-approval';
|
||||
import BillingPlanEditor from './components/billing-plan-editor.vue';
|
||||
import ChangeRecordDetailDialog from '@/components/change-record-detail-dialog/main.vue';
|
||||
import ContractAttachmentSection, {
|
||||
attachmentName as sharedAttachmentName,
|
||||
attachmentUrl as sharedAttachmentUrl,
|
||||
@@ -1194,7 +1161,14 @@ const attachmentViewerPlugins = [
|
||||
|
||||
export default {
|
||||
name: 'ContractManage',
|
||||
components: { ContractAttachmentSection, BillingPlanEditor, ElImageViewer, OpenFileViewer, PdfPreview },
|
||||
components: {
|
||||
ContractAttachmentSection,
|
||||
BillingPlanEditor,
|
||||
ChangeRecordDetailDialog,
|
||||
ElImageViewer,
|
||||
OpenFileViewer,
|
||||
PdfPreview,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
api,
|
||||
@@ -2969,25 +2943,6 @@ export default {
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.contract-change-record-detail-meta {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px 32px;
|
||||
margin-bottom: 16px;
|
||||
color: #606266;
|
||||
}
|
||||
|
||||
:deep(.contract-change-record-detail-dialog .el-dialog__body) {
|
||||
max-height: 65vh;
|
||||
overflow: auto;
|
||||
padding-top: 12px;
|
||||
}
|
||||
|
||||
:deep(.contract-change-record-detail-dialog .contract-change-record-detail-value .cell) {
|
||||
white-space: pre-wrap;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
:global(.avue--collapse .contract-manage-page__footer) {
|
||||
left: 60px;
|
||||
}
|
||||
|
||||
@@ -395,14 +395,8 @@
|
||||
<div class="loading-detail__summary">
|
||||
<div class="loading-detail__heading">配载单详情</div>
|
||||
<div>{{ dialogForm.loadingNo || '-' }}</div>
|
||||
<div>
|
||||
<el-tag :type="detailStatusType" class="status-text">{{
|
||||
statusText(dialogForm)
|
||||
}}</el-tag>
|
||||
</div>
|
||||
<div>
|
||||
<el-tag type="warning">{{ transportTypeLabel(dialogForm.transportType) }}</el-tag>
|
||||
</div>
|
||||
<el-tag :type="detailStatusType">{{ statusText(dialogForm) }}</el-tag>
|
||||
<el-tag type="primary">{{ transportTypeLabel(dialogForm.transportType) }}</el-tag>
|
||||
</div>
|
||||
<div class="loading-detail__task-row">
|
||||
<div class="loading-detail__field">
|
||||
@@ -1683,11 +1677,12 @@ export default {
|
||||
const typeMap = {
|
||||
pending: 'success',
|
||||
running: 'success',
|
||||
completed: 'info',
|
||||
processing: 'success',
|
||||
completed: 'primary',
|
||||
cancelled: 'info',
|
||||
draft: 'warning',
|
||||
draft: 'info',
|
||||
};
|
||||
return typeMap[this.dialogForm.businessStatus] || 'info';
|
||||
return typeMap[this.dialogForm.businessStatus] || 'warning';
|
||||
},
|
||||
taskSummary() {
|
||||
return (
|
||||
@@ -3604,8 +3599,17 @@ export default {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 24px;
|
||||
gap: 12px;
|
||||
padding: 4px 0 16px;
|
||||
|
||||
:deep(.el-tag) {
|
||||
height: 28px;
|
||||
padding: 0 12px;
|
||||
border: 0;
|
||||
border-radius: 8px;
|
||||
font-size: 13px;
|
||||
line-height: 28px;
|
||||
}
|
||||
}
|
||||
.loading-detail__heading {
|
||||
font-size: 20px;
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
/>
|
||||
</template>
|
||||
<master-order-dispatch v-else-if="mode === 'dispatch'" :id="routeId" @back="goList" />
|
||||
<master-order-detail v-else :id="routeId" />
|
||||
<master-order-detail v-else-if="mode === 'detail'" :id="routeId" />
|
||||
<el-dialog v-model="confirm.visible" title="提示" width="400px"
|
||||
><span>{{ confirm.message }}</span
|
||||
><template #footer
|
||||
@@ -153,6 +153,10 @@ export default {
|
||||
components: { MasterOrderEditor, MasterOrderDispatch, MasterOrderDetail },
|
||||
data() {
|
||||
return {
|
||||
// 实例创建时锁定所属路由。keep-alive 缓存后 $route 会变成其它页面,
|
||||
// 不能再用全局 query.mode / query.id 决定本页形态,否则打开「新增项目管理」
|
||||
//(mode=add 且无 id)会落入详情分支并请求缺少 id 的详情接口。
|
||||
routePathLocked: this.$route.path,
|
||||
searchExpanded: false,
|
||||
loading: false,
|
||||
records: [],
|
||||
@@ -180,10 +184,15 @@ export default {
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
isOwnedRoute() {
|
||||
return this.$route.path === this.routePathLocked;
|
||||
},
|
||||
mode() {
|
||||
if (!this.isOwnedRoute) return 'list';
|
||||
return this.$route.query.mode || 'list';
|
||||
},
|
||||
routeId() {
|
||||
if (!this.isOwnedRoute) return '';
|
||||
return this.$route.query.id;
|
||||
},
|
||||
masterEditorTitle() {
|
||||
@@ -194,6 +203,7 @@ export default {
|
||||
'$route.query': {
|
||||
immediate: true,
|
||||
handler() {
|
||||
if (!this.isOwnedRoute) return;
|
||||
this.syncTagTitle();
|
||||
if (this.mode === 'list') this.load();
|
||||
},
|
||||
|
||||
@@ -196,7 +196,7 @@
|
||||
<el-form-item label="项目编号" prop="projectCode">
|
||||
<el-input
|
||||
v-model="form.projectCode"
|
||||
placeholder="请输入"
|
||||
:placeholder="dialogType === 'add' ? '若不填写,系统自动生成' : '请输入'"
|
||||
:disabled="dialogType === 'edit'"
|
||||
/>
|
||||
</el-form-item>
|
||||
@@ -703,6 +703,7 @@
|
||||
label="变更内容"
|
||||
min-width="180"
|
||||
align="center"
|
||||
:show-overflow-tooltip="false"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<el-tooltip placement="top" :show-after="200">
|
||||
@@ -730,43 +731,10 @@
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<el-dialog
|
||||
<change-record-detail-dialog
|
||||
v-model="changeRecordDetailVisible"
|
||||
title="变更记录详情"
|
||||
append-to-body
|
||||
destroy-on-close
|
||||
width="1100px"
|
||||
top="10px"
|
||||
class="project-change-record-detail-dialog"
|
||||
>
|
||||
<div v-if="changeRecordDetail" class="project-change-record-detail-meta">
|
||||
<span>变更日期:{{ changeRecordDetail.changeDate || '-' }}</span>
|
||||
<span>变更账号:{{ changeRecordDetail.handler || '-' }}</span>
|
||||
</div>
|
||||
<el-table :data="changeRecordDetailRows" border :show-overflow-tooltip="false">
|
||||
<el-table-column prop="field" label="变更字段" min-width="180" />
|
||||
<el-table-column
|
||||
prop="before"
|
||||
label="变更前"
|
||||
min-width="360"
|
||||
class-name="project-change-record-detail-value"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="after"
|
||||
label="变更后"
|
||||
min-width="500"
|
||||
class-name="project-change-record-detail-value"
|
||||
/>
|
||||
</el-table>
|
||||
<el-empty
|
||||
v-if="!changeRecordDetailRows.length"
|
||||
description="暂无变更内容"
|
||||
:image-size="60"
|
||||
/>
|
||||
<template #footer>
|
||||
<el-button type="primary" @click="changeRecordDetailVisible = false">关闭</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
:rows="changeRecordDetailRows"
|
||||
/>
|
||||
|
||||
<template v-if="isChangeDialog">
|
||||
<div class="dialog-section-title">变更原因</div>
|
||||
@@ -947,6 +915,7 @@ import { submitMkApprovalFlow } from '@/utils/mk-approval';
|
||||
import { ElImageViewer } from 'element-plus';
|
||||
import { OpenFileViewer } from '@open-file-viewer/vue';
|
||||
import PdfPreview from '@/components/pdf-preview/main.vue';
|
||||
import ChangeRecordDetailDialog from '@/components/change-record-detail-dialog/main.vue';
|
||||
import {
|
||||
fallbackPlugin,
|
||||
imagePlugin,
|
||||
@@ -1066,6 +1035,7 @@ export default {
|
||||
name: 'ProjectApply',
|
||||
components: {
|
||||
CustomerArchive: defineAsyncComponent(() => import('@/views/vehicle/customer-archive.vue')),
|
||||
ChangeRecordDetailDialog,
|
||||
ElImageViewer,
|
||||
OpenFileViewer,
|
||||
PdfPreview,
|
||||
@@ -1520,6 +1490,7 @@ export default {
|
||||
this.fillDefaultUsers();
|
||||
return;
|
||||
}
|
||||
if (!id) return;
|
||||
this.api.getDetail(id).then(res => {
|
||||
const detail = res.data.data || {};
|
||||
const isChange = type === 'change';
|
||||
@@ -2999,27 +2970,6 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.project-change-record-detail-dialog .el-dialog__body) {
|
||||
max-height: 65vh;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
:deep(.project-change-record-detail-dialog .project-change-record-detail-value .cell) {
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
overflow: visible;
|
||||
text-overflow: clip;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.project-change-record-detail-meta {
|
||||
display: flex;
|
||||
gap: 32px;
|
||||
margin-bottom: 16px;
|
||||
color: #606266;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
:global(.project-apply-dialog .el-dialog__body) {
|
||||
max-height: 76vh;
|
||||
overflow-y: auto;
|
||||
|
||||
@@ -610,7 +610,12 @@ export default {
|
||||
return value;
|
||||
},
|
||||
applyDetail(detail) {
|
||||
this.form = { ...detail };
|
||||
this.form = {
|
||||
...detail,
|
||||
projectFundLimit: this.blankSentinelAmount(detail.projectFundLimit),
|
||||
usedFundLimit: this.blankSentinelAmount(detail.usedFundLimit),
|
||||
remainingFundLimit: this.blankSentinelAmount(detail.remainingFundLimit),
|
||||
};
|
||||
this.selectedProjectId = detail.projectId || '';
|
||||
this.attachmentRows = this.parseJsonArray(detail.attachmentsJson);
|
||||
this.selectedAttachments = [];
|
||||
@@ -620,6 +625,9 @@ export default {
|
||||
const { projectQuotaInfoTitle, temporaryCreditInfoTitle, ...payload } = row || {};
|
||||
return {
|
||||
...payload,
|
||||
projectFundLimit: this.toOptionalAmount(payload.projectFundLimit),
|
||||
usedFundLimit: this.toOptionalAmount(payload.usedFundLimit),
|
||||
remainingFundLimit: this.toOptionalAmount(payload.remainingFundLimit),
|
||||
applyLimit: payload.applyLimit === '' ? '' : Number(payload.applyLimit),
|
||||
attachmentsJson: JSON.stringify(this.attachmentRows),
|
||||
};
|
||||
@@ -765,8 +773,8 @@ export default {
|
||||
projectName: project.projectName || '',
|
||||
projectCode: project.projectCode || '',
|
||||
undertakeDeptName: project.undertakeDeptName || '',
|
||||
projectFundLimit: project.fundLimit || project.projectFundLimit || 0,
|
||||
usedFundLimit: project.usedFundLimit || 0,
|
||||
projectFundLimit: this.blankSentinelAmount(project.fundLimit ?? project.projectFundLimit),
|
||||
usedFundLimit: this.blankSentinelAmount(project.usedFundLimit),
|
||||
});
|
||||
this.form.remainingFundLimit = this.calculateRemainingFundLimit();
|
||||
getProjectDetail(project.id).then(res => {
|
||||
@@ -774,18 +782,32 @@ export default {
|
||||
Object.assign(this.form, {
|
||||
projectCode: detail.projectCode || this.form.projectCode,
|
||||
undertakeDeptName: detail.undertakeDeptName || this.form.undertakeDeptName,
|
||||
projectFundLimit:
|
||||
detail.fundLimit ?? detail.projectFundLimit ?? this.form.projectFundLimit,
|
||||
usedFundLimit: detail.usedFundLimit ?? this.form.usedFundLimit,
|
||||
projectFundLimit: this.blankSentinelAmount(
|
||||
detail.fundLimit ?? detail.projectFundLimit ?? this.form.projectFundLimit
|
||||
),
|
||||
usedFundLimit: this.blankSentinelAmount(
|
||||
detail.usedFundLimit ?? this.form.usedFundLimit
|
||||
),
|
||||
});
|
||||
this.form.remainingFundLimit = this.calculateRemainingFundLimit();
|
||||
});
|
||||
},
|
||||
blankSentinelAmount(value) {
|
||||
if (value === undefined || value === null || value === '') return '';
|
||||
return Number(value) === -1 ? '' : value;
|
||||
},
|
||||
toOptionalAmount(value) {
|
||||
const amount = this.blankSentinelAmount(value);
|
||||
return amount === '' ? null : amount;
|
||||
},
|
||||
calculateRemainingFundLimit() {
|
||||
const total = Number(this.form.projectFundLimit);
|
||||
const used = Number(this.form.usedFundLimit);
|
||||
if (!Number.isFinite(total) || !Number.isFinite(used)) return '';
|
||||
return Math.round((total - used + Number.EPSILON) * 100) / 100;
|
||||
const total = this.blankSentinelAmount(this.form.projectFundLimit);
|
||||
const used = this.blankSentinelAmount(this.form.usedFundLimit);
|
||||
if (total === '' || used === '') return '';
|
||||
const totalAmount = Number(total);
|
||||
const usedAmount = Number(used);
|
||||
if (!Number.isFinite(totalAmount) || !Number.isFinite(usedAmount)) return '';
|
||||
return Math.round((totalAmount - usedAmount + Number.EPSILON) * 100) / 100;
|
||||
},
|
||||
handleAmountInput(value) {
|
||||
const text = String(value || '').replace(/[^\d.]/g, '');
|
||||
|
||||
Reference in New Issue
Block a user