【问题标题】:How should I calculate total sales from multiple tables in a IndexedDB database?我应该如何计算 IndexedDB 数据库中多个表的总销售额?
【发布时间】:2017-03-16 22:55:13
【问题描述】:

我正在尝试使用 Dexie.js 在 JavaScript 中创建一个简单的股票/销售应用程序。我不确定如何在不编写糟糕的递归代码的情况下返回总销售额,该代码只针对一种产品的总销售额多次运行查询。

我的架构有点像这样:

clients: "++id, name, phone",
order: "++id, clientId, daate",
order_content: "orderId, productId, qty",
product: "++id, name, mu, mk_cost, sa_cost, prod_cost",
stock: "++id, date, productId, qty, lot"

我将产品类型与价格和其他详细信息一起存储在“产品”中。下订单时,我将 clientId 存储在 Order 中,然后我使用“order_content”将项目存储在那里,使用 orderId 作为排序键。

我基本上想对每个项目做一个总和。

我尝试在 db.product.each() 循环中运行以下代码,但似乎我自己复杂化了。

var product1Total = 0;
function calculateTotal(productId, price){
db.order_content
.where("productID")
.equals(productId)
.each(function(item){
product1Total += (price * qty)
})
}

谢谢!

【问题讨论】:

    标签: javascript indexeddb dexie


    【解决方案1】:

    如果您的目标是在单个查询中获取特定订单的总价,而 prod_cost 是您的产品成本,并且您想要某个订单的总价,则应执行以下操作:

    function calculateTotal (orderId) {
        return db.order_content
            .where('orderId').equals(orderId).toArray()
        .then(orderContents => {
            return Promise.all(
                orderContents.map(oc => db.product.get(oc.productId))
            ).then (products => {
                return orderContents.reduce (
                    (total, oc, i) => total + oc.qty * producs[i].prod_cost, 0);
            });
        });
    }
    

    或者使用异步函数:

    async function calculateTotal (orderId) {
        let orderContents = await db.order_content
            .where('orderId').equals(orderId).toArray();
    
        let products = await Promise.all(orderContents.map(oc =>
            db.product.get(oc.productId));
    
        return orderContents.reduce (
            (total, oc, i) => total + oc.qty * producs[i].prod_cost, 0);
    }
    

    或者使用香草 ES5 javascript:

    function calculateTotal (orderId) {
        return db.order_content
            .where('orderId').equals(orderId).toArray()
        .then(function (orderContents) {
            return Dexie.Promise.all(
                orderContents.map(function (oc) {
                    return db.product.get(oc.productId);
                })
            ).then (function (products) {
                return orderContents.reduce (
                    function (total, oc, i) {
                        return total + oc.qty * producs[i].prod_cost;
                    }, 0);
            });
        });
    }
    

    【讨论】:

    • 是的,这正是我想要的。很抱歉这个模糊的帖子。是否也可以在 vanilla JS 中做到这一点?
    • 我只是在第一个示例中使用箭头函数。将“orderContents => {...}”替换为“function (orderContents) { ... }”,将“oc => ...”替换为“function (oc) { return ... }”
    【解决方案2】:

    您的查询没有问题,但您应该将其封装在一个返回承诺的函数中。这很容易通过链接从 Dexie 的 Collection.each() 返回的承诺来实现。

    function calculateTotal(productId, price) {
        var total = 0;
        return db.order_content
            .where("productID")
            .equals(productId)
            .each(function(item){
                total += (price * item.qty)
            }).then (function () {
                return total;
            });
    }
    

    或者在 ES7 中:

    async function calculateTotal (productId, price) {
        var total = 0;
    
        await db.order_content
            .where("productID")
            .equals(productId)
            .each (item => total += (price * item.qty));
    
        return total;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-31
      相关资源
      最近更新 更多