微信小程序 SKU設(shè)計(jì)與實(shí)現(xiàn) 前端 數(shù)據(jù)結(jié)構(gòu)分析

預(yù)覽

image

功能說明

  • SKU。存貨單位(英語:stock keeping unit劲装,SKU)胧沫,也翻譯為庫存單元,是一個(gè)會(huì)計(jì)學(xué)名詞占业,定義為庫存管理中的最小可用單元绒怨。例如紡織品中一個(gè)SKU通常表示規(guī)格、顏色谦疾、款式南蹂,而在連鎖零售門店中有時(shí)稱單品為一個(gè)SKU。

  • 以IPhone為例念恍,SKU指的是具體規(guī)格單品(銀色 64GB)六剥,SKU屬性就是會(huì)影響到庫存和價(jià)格的屬性,又叫銷售屬性峰伙,與商品是多對(duì)一的關(guān)系疗疟,比如

    • 顏色:銀色、深空灰
    • 容量:64GB瞳氓、128GB策彤、 512GB
    • 因此所有屬性規(guī)格的排列組合則會(huì)生成 2 * 3 = 6 個(gè)SKU

需求與細(xì)節(jié)分析

  • 僅有一種(一維,如顏色:白匣摘、黑)屬性時(shí)店诗,默認(rèn)選中該屬性第一個(gè)值(如白)
  • 載入數(shù)據(jù)后即需判斷所有組合情況是否有庫存,設(shè)置規(guī)格屬性是否可點(diǎn)擊
  • 每選中或取消選中后音榜,需判斷所有組合情況庞瘸,設(shè)置規(guī)格屬性是否可點(diǎn)擊
  • 應(yīng)提供是否選中所有維度方法,判斷是否選了所有規(guī)格赠叼,用于進(jìn)行購(gòu)買或加入購(gòu)物車時(shí)判斷
  • 僅第一種維度中每個(gè)值可提供不同商品圖片
  • 選中所有維度后更新該規(guī)格屬性對(duì)應(yīng)價(jià)格等商品信息恕洲,否則顯示默認(rèn)商品信息

數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)

  • 每種屬性規(guī)格組合應(yīng)有唯一id
  • 每種維度需提供ks值用于標(biāo)明該維度塔橡,如顏色為s1、容量為s2依次類推
  • 所有排列組合情況和對(duì)應(yīng)庫存應(yīng)全部由后端提供
  • 需記錄當(dāng)前選中的規(guī)格屬性霜第,且一開始初始化所有維度葛家,默認(rèn)值為空
    商品
product: {
      id: 0,
      picUrl: "https://img11.360buyimg.com/n1/s450x450_jfs/t1/62813/33/2131/584186/5d079803E03084b0d/2b4970456b7bf49f.png", // 默認(rèn)商品圖片
      promotion: 1, // 促銷活動(dòng) 0無 1限時(shí)購(gòu) 2領(lǐng)劵
      gallery: [{
        picUrl: "https://img11.360buyimg.com/n1/s450x450_jfs/t1/62813/33/2131/584186/5d079803E03084b0d/2b4970456b7bf49f.png",
        sortOrder: 1
      },
      {
        picUrl: "https://img10.360buyimg.com/n1/s450x450_jfs/t1/4176/23/3653/281477/5b9a15d4E97e09d00/887e76e6c525324c.jpg",
        sortOrder: 2
      }
      ], // 輪播圖
      title: "Apple iPhone XS Max (A2104)",
      description: "A12仿生芯片流暢體驗(yàn),支持雙卡泌类!",
      defaultPrice: 1.00, // 默認(rèn)顯示價(jià)格
      price: 1.00,
      originPrice: 9588.00,
      detail: '<div><img src="https://img14.360buyimg.com/cms/jfs/t1/25195/1/9487/388554/5c7f80a5E8b8f8f0c/46818404849d6ec6.jpg"><img src="https://img12.360buyimg.com/cms/jfs/t1/15853/18/9628/325164/5c7f80a5E7172b236/ba9f3f63a83a9b65.jpg"></div>', // 商品詳情
      tags: [{
        id: 1,
        title: "官方自營(yíng)品牌"
      },
      {
        id: 2,
        title: "新品"
      }
      ],
      serviceList: [{
        id: 1,
        title: "48小時(shí)快速退款",
        desc: "收到退貨包裹并確認(rèn)無誤后癞谒,將在48小時(shí)內(nèi)辦理退款,退款將原路返回刃榨,不同銀行處理時(shí)間不同弹砚,預(yù)計(jì)1-5個(gè)工作日到賬。"
      },
      {
        id: 2,
        title: "滿88元免郵費(fèi)",
        desc: "單筆訂單金額(不含運(yùn)費(fèi))枢希,大陸地區(qū)滿88元免郵桌吃,不滿88元收取10元郵費(fèi);港澳臺(tái)地區(qū)滿500元免郵苞轿,不滿500元收取30元運(yùn)費(fèi)茅诱;海外地區(qū)以下單頁提示運(yùn)費(fèi)為準(zhǔn)。"
      }
      ],
      comment: {
        goodCommentRate: 100, // 好評(píng)率
        count: 3986, // 評(píng)論計(jì)數(shù)
        goodComment: {
          nickname: "Exrick",
          avatar: "https://wx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTJTqQ5hNKicCNEwW3cATfOTaXk6xMlNEfh1gm0kicPDtJrXwTf5YEqQXYea3m5vsuPyJUXc3U0OicXtA/132",
          content: "很好搬卒,手機(jī)很有質(zhì)感瑟俭,值得購(gòu)買。",
          rate: 5,
          time: "2019.06.18",
          spec: "銀色 64G",
          pics: [
            "https://img30.360buyimg.com/shaidan/s616x405_jfs/t1/65005/20/4818/92581/5d2ffdb6Ebcbf3018/35411a583e29d52d.jpg",
            "https://img30.360buyimg.com/shaidan/s616x405_jfs/t1/74460/28/4830/96562/5d2ffdb7Ed5e9ce7a/e764b3daa92a9c67.jpg"
          ]
        } // 精選評(píng)論
      }

SKU

sku: {
      show: false, // 顯示屬性規(guī)格
      noneSku: false, // 有無規(guī)格選擇
      quota: 100, // 限購(gòu)數(shù)量
      productId: 1, // 商品id
      picUrl: "", // 當(dāng)前選擇圖片
      specText: "", // 所選規(guī)格屬性
      specTextNoCount: "", // 所選規(guī)格屬性 無數(shù)量
      tree: [
        {
          k: '顏色', // skuKeyName:規(guī)格類目名稱
          v: [
            {
              id: 1, // skuValueId:規(guī)格值 id
              name: '銀色', // skuValueName:規(guī)格值名稱
              picUrl: 'https://img11.360buyimg.com/n1/s450x450_jfs/t1/62813/33/2131/584186/5d079803E03084b0d/2b4970456b7bf49f.png', // 規(guī)格類目圖片契邀,只有第一個(gè)規(guī)格類目可以定義圖片
              selected: false, // 是否選擇
              disabled: false // 禁用
            },
            {
              id: 2,
              name: '深空灰色',
              picUrl: 'https://img14.360buyimg.com/n0/jfs/t1/3/15/4536/138660/5b997bf8Ed72ebce7/819dcf182d743897.jpg',
              selected: false,
              disabled: false
            }
          ],
          ks: 's1' // skuKeyStr:sku 組合列表(下方 list)中當(dāng)前類目對(duì)應(yīng)的 key 值摆寄,value 值會(huì)是從屬于當(dāng)前類目的一個(gè)規(guī)格值 id
        },
        {
          k: '內(nèi)存',
          v: [
            {
              id: 3,
              name: '64GB',
              picUrl: '',
              selected: false,
              disabled: false
            },
            {
              id: 4,
              name: '256GB',
              picUrl: '',
              selected: false,
              disabled: false
            },
            {
              id: 5,
              name: '512GB',
              picUrl: '',
              selected: false,
              disabled: false
            }
          ],
          ks: 's2'
        }
      ],
      // 所有 sku 的組合列表,比如紅色坯门、M 碼為一個(gè) sku 組合微饥,紅色、S 碼為另一個(gè)組合
      list: [
        {
          id: 1, // skuId古戴,下單時(shí)后端需要
          price: 1.00, // 價(jià)格
          s1: 1, // 規(guī)格類目 ks 為 s1 的對(duì)應(yīng)規(guī)格值 id
          s2: 3, // 規(guī)格類目 ks 為 s2 的對(duì)應(yīng)規(guī)格值 id
          stockNum: 50 // 當(dāng)前 sku 組合對(duì)應(yīng)的庫存
        },
        {
          id: 2,
          price: 2.00,
          s1: 1,
          s2: 4,
          stockNum: 100
        },
        {
          id: 3,
          price: 3.00,
          s1: 1,
          s2: 5,
          stockNum: 0
        },
        {
          id: 4,
          price: 4.00,
          s1: 2,
          s2: 3,
          stockNum: 100
        },
        {
          id: 5,
          price: 5.00,
          s1: 2,
          s2: 4,
          stockNum: 100
        },
        {
          id: 6,
          price: 6.00,
          s1: 2,
          s2: 5,
          stockNum: 50
        }
      ],
      // 選擇的 sku 組合
      selectedSku: {
      },
      count: 1 // 選擇的商品數(shù)量
}

關(guān)鍵實(shí)現(xiàn)方法

  • 初始化
    // 加載sku后初始化selectedSku
    let tree = this.data.sku.tree;
    for (let i = 0; i < tree.length; i++) {
      let s = 'sku.selectedSku.' + tree[i].ks;
      this.setData({
        [s]: ''
      })
    }

    // 只有一種 sku 規(guī)格值時(shí)默認(rèn)選中第一個(gè)
    if (tree.length == 1) {
      let k = 'sku.selectedSku.' + this.data.sku.tree[0].ks;
      this.setData({
        [`sku.tree[${0}].v[${0}].selected`]: true,
        [k]: this.data.sku.tree[0].v[0].id
      });
    }
  • 核心判斷所有屬性是否可選
    • 每當(dāng)點(diǎn)擊一個(gè)規(guī)格屬性后畜号,循環(huán)判斷其他所有規(guī)格屬性,模擬依次點(diǎn)擊組合其他所有規(guī)格屬性允瞧,與所有排列組合匹配简软,統(tǒng)計(jì)庫存總數(shù),若庫存總數(shù)>0則可選述暂,詳見下方isSkuChoosable方法
  // 循環(huán)判斷所有屬性是否可選
  judgeAllItem: function () {
    // 判斷庫存
    let tree = this.data.sku.tree;
    for (let i = 0; i < tree.length; i++) {
      let v = tree[i].v;
      for (let j = 0; j < v.length; j++) {
        if (this.isSkuChoosable(tree[i].ks, v[j].id)) {
          // 可點(diǎn)擊
          this.setData({
            [`sku.tree[${i}].v[${j}].disabled`]: false
          })
        } else {
          // 不可點(diǎn)擊
          this.setData({
            [`sku.tree[${i}].v[${j}].disabled`]: true
          })
        }
      }
    }
   ... ...
  }
  • 關(guān)鍵判斷方法
isSkuChoosable: function (ks, vId) {

    let selectedSku = this.data.sku.selectedSku;
    let list = this.data.sku.list;

    // 先假設(shè)sku已選中痹升,拼入已選中sku對(duì)象中
    let matchedSku = Object.assign({}, selectedSku, {
      [ks]: vId
    });

    // 再判斷剩余sku是否全部不可選,若不可選則當(dāng)前sku不可選中
    let skusToCheck = Object.keys(matchedSku).filter(
      skuKey => matchedSku[skuKey] != ''
    );

    let filteredSku = list.filter(sku => (
      skusToCheck.every(
        skuKey => String(matchedSku[skuKey]) == String(sku[skuKey])
      )
    ));

    let stock = filteredSku.reduce((total, sku) => {
      total += sku.stockNum;
      return total;
    }, 0);
    return stock > 0;
}
  • 是否所有維度規(guī)格屬性已選
  // 是否所有規(guī)格已選
  isAllSelected: function () {
    let selectedSku = this.data.sku.selectedSku;
    let selected = Object.keys(selectedSku).filter(
      skuKeyStr => selectedSku[skuKeyStr] != ""
    );
    return this.data.sku.tree.length == selected.length;
  }

源碼獲取

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末畦韭,一起剝皮案震驚了整個(gè)濱河市疼蛾,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌艺配,老刑警劉巖察郁,帶你破解...
    沈念sama閱讀 207,248評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件衍慎,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡皮钠,警方通過查閱死者的電腦和手機(jī)稳捆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來麦轰,“玉大人乔夯,你說我怎么就攤上這事】钋郑” “怎么了?”我有些...
    開封第一講書人閱讀 153,443評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵新锈,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我妹笆,道長(zhǎng)块请,這世上最難降的妖魔是什么晾浴? 我笑而不...
    開封第一講書人閱讀 55,475評(píng)論 1 279
  • 正文 為了忘掉前任脊凰,我火速辦了婚禮,結(jié)果婚禮上狸涌,老公的妹妹穿的比我還像新娘。我一直安慰自己最岗,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,458評(píng)論 5 374
  • 文/花漫 我一把揭開白布般渡。 她就那樣靜靜地躺著,像睡著了一般驯用。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蝴乔,一...
    開封第一講書人閱讀 49,185評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音薇正,去河邊找鬼囚衔。 笑死,一個(gè)胖子當(dāng)著我的面吹牛雕沿,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播晦炊,決...
    沈念sama閱讀 38,451評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼鞠鲜,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了断国?” 一聲冷哼從身側(cè)響起贤姆,我...
    開封第一講書人閱讀 37,112評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎稳衬,沒想到半個(gè)月后霞捡,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體难菌,經(jīng)...
    沈念sama閱讀 43,609評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡围段,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,083評(píng)論 2 325
  • 正文 我和宋清朗相戀三年蛙粘,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了皂贩。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片馍忽。...
    茶點(diǎn)故事閱讀 38,163評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡夜只,死狀恐怖九榔,靈堂內(nèi)的尸體忽然破棺而出芳室,到底是詐尸還是另有隱情板丽,我是刑警寧澤呈枉,帶...
    沈念sama閱讀 33,803評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站埃碱,受9級(jí)特大地震影響猖辫,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜砚殿,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,357評(píng)論 3 307
  • 文/蒙蒙 一啃憎、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧似炎,春花似錦辛萍、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至传睹,卻和暖如春耳幢,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評(píng)論 1 261
  • 我被黑心中介騙來泰國(guó)打工睛藻, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留启上,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,636評(píng)論 2 355
  • 正文 我出身青樓店印,卻偏偏與公主長(zhǎng)得像冈在,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子按摘,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,925評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容