You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AngularJS发票计算问题:总计不显示+折扣VAT下拉改输入框

发票计算功能修复与改造方案

核心问题梳理

  1. 总计金额无法显示:HTML中总计行的<strong>标签未绑定{{Sale.TotalAmount}},且错误地将插值表达式写在td的value属性(该属性不适用于表格单元格)。
  2. 交互需求改造:需要将折扣、VAT的下拉选择框替换为手动输入文本框,实现值变更时自动联动计算所有金额。

改造后代码实现

1. HTML部分修改

将折扣、VAT的下拉框改为数字输入框,绑定ng-change事件触发计算,同时修复总计显示:

<div class="row">
    <div class="col-lg-4 col-sm-5">
    </div>
    <div class="col-lg-4 col-sm-5 ml-auto">
        <table class="table table-clear">
            <tbody>
                <tr>
                    <td class="left">
                        <strong>Subtotal</strong>
                    </td>
                    <td class="right">${{Sale.Subtotal || 0}}</td>
                </tr>
                <tr>
                    <td class="left">
                        <strong>
                            Discount %
                            <!-- 替换下拉框为数字输入框,绑定ng-change触发计算 -->
                            <input type="number" ng-model="Sale.DiscountParcentage" 
                                   ng-change="CalculateDiscount();CalculateVat();"
                                   min="0" max="100" placeholder="输入折扣百分比">
                        </strong>
                    </td>
                    <td class="right">${{Sale.DiscountAmount || 0}}</td>
                </tr>
                <tr>
                    <td class="left">
                        <strong>
                            VAT %
                            <!-- 替换下拉框为数字输入框,绑定ng-change触发计算 -->
                            <input type="number" ng-model="Sale.VatParcentage" 
                                   ng-change="CalculateVat();"
                                   min="0" max="100" placeholder="输入VAT百分比">
                        </strong>
                    </td>
                    <td class="right">${{Sale.VatAmount || 0}}</td>
                </tr>
                <tr>
                    <td class="left">
                        <strong>Total</strong>
                    </td>
                    <!-- 修复总计显示,绑定插值表达式到strong标签 -->
                    <td class="right">
                        <strong>${{Sale.TotalAmount || 0}}</strong>
                    </td>
                </tr>
            </tbody>
        </table>
    </div>
</div>

2. JS逻辑优化

确保数值联动计算,处理空值/非数字情况,避免出现NaN:

$scope.AddNewRow = function () {
    $scope.InvoiceCart.push({ ProductId: null, CategoryName: '', UnitPrice: 0, Quantity: 1, LineTotal: 0 });
}

$scope.SetValueOfProduct = function (productId) {
    var dataObj = $filter('filter')($scope.ProductList, { ProductId: parseInt(productId) })[0];
    const index = $scope.InvoiceCart.findIndex((x) => x.ProductId === productId);
    if (dataObj) {
        $scope.InvoiceCart[index].CategoryName = dataObj.CategoryName;
        $scope.InvoiceCart[index].UnitPrice = dataObj.SalesPrice;
        $scope.InvoiceCart[index].LineTotal = $scope.InvoiceCart[index].UnitPrice * $scope.InvoiceCart[index].Quantity;
        // 选择商品后自动计算小计、折扣、VAT和总计
        $scope.SubTotalCalculation();
        $scope.CalculateDiscount();
        $scope.CalculateVat();
    }
}

$scope.OnChangeLineTotalSet = function (productId) {
    const index = $scope.InvoiceCart.findIndex((x) => x.ProductId === productId);
    $scope.InvoiceCart[index].LineTotal = $scope.InvoiceCart[index].UnitPrice * $scope.InvoiceCart[index].Quantity;
    // 修改数量/单价后自动联动计算所有金额
    $scope.SubTotalCalculation();
    $scope.CalculateDiscount();
    $scope.CalculateVat();
}

$scope.SubTotalCalculation = function () {
    $scope.Sale.Subtotal = 0;
    for (var i = 0; i < $scope.InvoiceCart.length; i++) {
        $scope.Sale.Subtotal += $scope.InvoiceCart[i].LineTotal || 0;
    }
}

$scope.CalculateDiscount = function () {
    // 处理空值,默认0
    const discountPercent = $scope.Sale.DiscountParcentage || 0;
    $scope.Sale.DiscountAmount = ($scope.Sale.Subtotal * discountPercent) / 100;
}

$scope.CalculateVat = function () {
    // 处理空值,默认0
    const vatPercent = $scope.Sale.VatParcentage || 0;
    const afterDiscount = $scope.Sale.Subtotal - ($scope.Sale.DiscountAmount || 0);
    $scope.Sale.VatAmount = (afterDiscount * vatPercent) / 100;
    $scope.Sale.TotalAmount = afterDiscount + $scope.Sale.VatAmount;
}

$scope.RowDelete = function (index) {
    if (index > -1) {
        $scope.InvoiceCart.splice(index, 1);
    }
    // 删除行后自动计算所有金额
    $scope.SubTotalCalculation();
    $scope.CalculateDiscount();
    $scope.CalculateVat();
}

$scope.SaveInvoice = function () {
    $scope.Sale.OrderNo = $("#OrderNo").val();
    var data = JSON.stringify({
        sale: $scope.Sale, salesDetails: $scope.InvoiceCart
    });
    return $.ajax({
        contentType: 'application/json; charset=utf-8',
        dataType: 'json',
        type: 'POST',
        url: "/Home/SaveInvoiceSale",
        data: data,
        success: function (result) {
            alert(result.IsSuccess ? "Save Success!" : "Save failed!");
        },
        error: function () {
            alert("Error!")
        }
    });
}

关键改动说明

  1. 输入框替换:将折扣、VAT的下拉框改为type="number"的输入框,添加min/max限制范围,绑定ng-change事件触发计算。
  2. 总计显示修复:将总计金额的插值表达式移到<strong>标签内,同时添加|| 0处理空值,避免显示空白。
  3. 联动计算优化:在商品选择、数量/单价修改、行删除等操作后,自动触发完整的计算流程(小计→折扣→VAT→总计),保证所有数值实时同步。
  4. 空值处理:在计算逻辑中添加|| 0,避免因未输入值导致NaN的出现。

内容的提问来源于stack exchange,提问作者Salman Amjad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 03:24:56