[: currentTime | date:'mm:ss' :] [: timeLeft | date:'mm:ss' :]

示例参考

结果
HTML
CSS
JS
运行
整页预览
<main>
  <div class="row">
    <div id="overview" class="even">
    </div>
  </div>
  <div id="type-list" class="row"></div>
</main>
* {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}

:root {
  font-family: sans-serif;
  color: #444;
  font-size: 15px;
  background: #ccc;
}

img {
  max-width: 100%;
}

body {
  margin: 0;
}

input, button {
  padding: .6rem;
  border: 1px solid rgba(0, 0, 0, .1);
  outline: 0;
  font-size: .8rem;
}

input:focus,
button:focus {
  outline: 2px solid #cfa8ff;
}

form label,
form input {
  display: block;
  width: 100%;
  margin: .3rem 0;
}

main {
  max-width: 50em;
  margin-left: auto;
  margin-right: auto;
  padding: 1em;
}

dt, dd {
  display: inline-block;
}

dt {
  color: #0006;
}

dd {
  margin-left: 1em;
  font-weight: bold;
}

[hidden] {
  display: none !important;
}

.row {
  display: flex;
  flex-wrap: wrap;
  margin-left: -.3em;
  margin-right: -.3em;
}

.even {
  flex: 1;
  padding: .3em;
}

.half {
  width: 50%;
  padding: .3em;
}

.card {
  padding: .5em 1em;
  -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, .2);-moz-box-shadow: 0 1px 3px rgba(0, 0, 0, .2);box-shadow: 0 1px 3px rgba(0, 0, 0, .2);
  background: #fff;
  -webkit-border-radius: 3px;-moz-border-radius: 3px;border-radius: 3px;
}

.card .title {
  font-weight: bold;
  margin: .5em 0;
}

.dollar:before {
  content: '$ ';
  color: #0008;
  font-weight: lighter;
}
class Panel {
  constructor (stock, overviewSelector, typeListSelector) {
    this.stock    = stock;
    this.overview = document.querySelector(overviewSelector);
    this.typeList = document.querySelector(typeListSelector);

    this.render();
  }

  render () {
    this.renderOverview();
    this.renderTypes();
  }

  renderOverview () {
    let stock = this.stock;

    this.overview.innerHTML = `
    <div class="card">
        <div class="title">概览</div>
        <div class="row">
          <dl class="even">
            <dt>货物总数</dt>
            <dd>${stock.getTotal()}</dd>
          </dl>
          <dl class="even">
            <dt>货物价值</dt>
            <dd>${stock.getSum()}</dd>
          </dl>
          <dl class="even">
            <dt>货物类型</dt>
            <dd>${stock.getTotalTypes()}</dd>
          </dl>
        </div>
      </div>
    `;
  }

  renderTypes () {
    let types = this.stock.types;

    for (let type in types) {
      let it = types[ type ];
      let el = document.createElement('div');
      el.classList.add('even');
      el.innerHTML = `<div class="card">
        <div class="title">${type}</div>
        <dl>
          <dt>总数</dt>
          <dd>${it.count}</dd>
        </dl>
        <dl>
          <dt>总价</dt>
          <dd>${it.sum}</dd>
        </dl>
      </div>`;

      this.typeList.appendChild(el);
    }
  }
}

/**
 * 仓库
 */
class Stock {
  constructor () {
    if (Stock.instance)
      return Stock.instance;
    else
      Stock.instance = this;

    this.sum   = 0;
    this.list  = [];
    this.maxId = 0;
    this.types = {
      // phone: {
      //  count: 2
      // },
      // computer: {},
    };
  }

  /**
   * 入库
   * @param {Product} product
   */
  input (product) {
    product.id = this.generateId();
    this.sum += product.price;
    this.list.push(product);
    this.updateTypes(product.type, 1, product.price);
  }

  /**
   * 出库
   * @param {number} id
   * @return {boolean}
   */
  output (id) {
    // 通过id找索引
    let index = this.list.findIndex(it => {
      return it.id === id;
    });

    if (index == -1)
      return false;

    let product = this.list[ index ];

    // 减去总价
    this.sum -= product.price;
    // 删除产品
    this.list.splice(index, 1);
    this.updateTypes(product.type, -1, product.price);
  }

  /**
   * 更新货物类型统计
   * @param type
   * @param num 新增数量
   * @param price 价格
   */
  updateTypes (type, num, price) {
    let select = this.types[ type ];

    if (!select)
      select = this.types[ type ] = { count : 0, sum : 0 };

    select.count += num;
    select.sum += price * num;
  }

  /**
   * 获取商品总价
   * @return {number}
   */
  getSum () {
    return this.sum;
  }

  /**
   * 获取商品总数
   * @return {number}
   */
  getTotal () {
    return this.list.length;
  }

  /**
   * 获取商品类型总数
   * @return {number}
   */
  getTotalTypes () {
    return Object.keys(this.types).length;
  }

  /**
   * 生成id
   * @return {number}
   */
  generateId () {
    return ++this.maxId;
  }

  /**
   * 获取所有商品
   * @return {Array}
   */
  all () {
    return this.list;
  }
}

/**
 * 产品
 */
class Product {
  constructor (type, price) {
    this.type  = type;
    this.price = price;
  }
}

let p1 = new Product('phone', 100);
let p2 = new Product('phone', 200);
let p3 = new Product('phone', 300);
let c1 = new Product('computer', 300);

let stock = new Stock();

stock.input(p1);
stock.input(p2);
stock.input(p3);
stock.input(c1);

new Panel(stock, '#overview', '#type-list');
登录后评论