POS机的基本要求与解释如下:
需求描述
商店里进行购物结算时会使用收银机(POS)系统,这台收银机会在结算时根据客户的购物车(Cart)中的商品(Item)和商店正在进行的优惠活动(Promotion)进行结算和打印购物清单。
已知该商店正在对部分商品进行“买三送一”的优惠活动,即买三件商品其中一件是送的,按照两件商品价格结算。
我们需要实现一个名为printInventory
函数,该函数能够将指定格式的数据作为参数输入,然后在浏览器的控制台中输出结算清单的文本。
输入格式(样例):
javascript
[ 'ITEM000001', 'ITEM000001', 'ITEM000001', 'ITEM000001', 'ITEM000001', 'ITEM000003-2', 'ITEM000005', 'ITEM000005', 'ITEM000005' ]
其中对'ITEM000003-2'来说,"-"之前的是标准的条形码,"-"之后的是数量。 当我们购买需要称量的物品的时候,由称量的机器生成此类条形码,收银机负责识别生成小票。 (当点击"保存并提交代码"按钮的时候,我们会调用函数printInventory将上面的数据作为参数(inputs)传入该函数。)
清单内容(样例,其中的打印时间为打印时的实际时间):
***<没钱赚商店>购物清单*** 打印时间:2014年08月04日 08:09:05 ---------------------- 名称:可口可乐,数量:3瓶,单价:3.00(元),小计:6.00(元) 名称:羽毛球,数量:5个,单价:1.00(元),小计:4.00(元) 名称:苹果,数量:2斤,单:5.50(元),小计:11.00(元) ---------------------- 挥泪赠送商品: 名称:可口可乐,数量:1瓶 名称:羽毛球,数量:1个 ---------------------- 总计:21.00(元) 节省:4.00(元) **********************
作业要求
- 请尽可能的使用面向对象的思想;
- 根据
main-spec.js
中的测试用例,在main.js
文件中实现printInventory
函数; - 请在保证代码可读性的前提下,尽可能用最少的代码行数完成作业; 注意:所有的标点符号均为英文符号
-
作业提示
代码如下
这道题我们构造了两个类,我们先构造出一个Order类用来处理和输出结果
function Order (items, promotions, inputs) { this.items = {}; //存储已购商品清单 this.total = 0; //存储需付款总价 this.original = 0; //存储优惠前总价 this.initiate(items, promotions, inputs); //调用初始化函数 }
现在对Oredr()进行初始化
Order.prototype.initiate = function (items,promotions,inputs){ var self = this; // 此处重点,要注意作用域 _.each(inputs,function(input){ var rawed_barcode = input.substring(0,10); var item = {}; if(self.items.hasOwnProperty(rawed_barcode)==true) { item = self.items[rawed_barcode]; //console.log(JSON.stringify(item)); }else { var rawItem = _(items).findWhere({barcode: rawed_barcode}); var newItem = new Item(rawItem.barcode, rawItem.name, rawItem.unit, rawItem.price); item = newItem; } self.original += item.addCount(input); self.items[rawed_barcode] = item; }); var two_with_one_list = _(promotions).findWhere({type: 'BUY_TWO_GET_ONE_FREE'}).barcodes; _(two_with_one_list).each(function (barcode) { self.items[barcode] && self.items[barcode].getPromotion(); // console.log(JSON.stringify(self.items[barcode])); }); this.total = _(self.items).reduce(function (sum, item){ return sum + item.subtotal;}, 0); //reduce 求和的方法,详情与具体用法请自行查询 }
下面是Order类的原型方法,用于获取商品列表的部分内容
Order.prototype.getLists = function() { function getBoughtItem (item) { return '名称:' + item.name + ',数量:' + item.count + item.unit + ',单价:' + item.price.toFixed(2) + '(元)' + ',小计:' + item.subtotal.toFixed(2) + '(元)\n'; } function getFreeItem (item) { if(item.free!==0){ return '名称:' + item.name + ',数量:' + item.free + item.unit +'\n'; } else{ return ""; } } var first_title="***<没钱赚商店>购物清单***\n" var boughtList = '----------------------\n'; var freeList = '----------------------\n' + '挥泪赠送商品:\n'; _(this.items).each(function (item) { boughtList += getBoughtItem(item); item.promotion && (freeList += getFreeItem(item)); }); this.boughtList = boughtList; this.freeList = freeList; this.first_title=first_title; }
Order.prototype.getStats = function() { return '----------------------\n' + '总计:' + this.total.toFixed(2) + '(元)\n' + '节省:' + (this.original - this.total).toFixed(2) + '(元)\n'+"**********************"; }
下面我们构造一个Item类
function Item(barcode, name, unit, price) { this.barcode = barcode; this.name = name; this.unit = unit; this.price = price || 0.00; this.subtotal = 0; this.count = 0; this.promotion = false; }
根据需要写出Item的原型方法:
计算数量信息和subtotal等
Item.prototype.addCount = function(input) { var bought_number = parseInt(input.substring(11)) || 1; this.count += bought_number; this.subtotal = this.count * this.price; return bought_number * this.price; }
计算优惠部分
Item.prototype.getPromotion = function() { this.promotion = true; this.free = Math.floor(this.count / 3); this.subtotal = (this.count - this.free) * this.price; }
最后我们在构造一个Order的原型方法来获取时间即可
Order.prototype.getDateTime = function() { var myDate = new Date(); var year=myDate.getFullYear(); var month=myDate.getMonth(); var newMonth = (month+1)>9?(month+1):"0"+(month+1); var day=myDate.getDate(); var newday = day>9?day:"0"+day; var hours=myDate.getHours(); var newhours = hours>9?hours:"0"+hours; var minutes=myDate.getMinutes(); var newminutes = minutes>9?minutes:"0"+minutes; var seconds=myDate.getSeconds(); var newseconds= seconds>9?seconds:"0"+seconds; var now_time='打印时间:' + year+"年"+ newMonth+"月"+newday+"日 "+ newhours+":"+newminutes+":"+newseconds+"\n"; return now_time }
时间可以根据自己的需要来编写,可以写出不同的时间格式。具体写法延伸可以根据以前博客 链接为http://1397548794.iteye.com/admin/blogs/2411939
最后我们对Order方法进行实例化并输出我们想要的内容
function printInventory(inputs) { var order = new Order(loadAllItems(),loadPromotions(),inputs); order.getLists(); console.log(order.first_title+order.getDateTime()+order.boughtList + order.freeList + order.getStats()); }
我们通过对Order()和Item()构造prototype方法,把一些不变的属性和函数单独提出来,节省了内存,经过函数的封装和继承,实现了面向对象的编写。
loadAllItems(),loadPromotions()等详情我们没有写出,全面的代码与题详情请见网页 http://www.codefordream.com/courses/js-pos-boot-camp/sections/section_1/practices/normal/practice_6/items/code