Ramda 处理数据结构

570 阅读1分钟

import isEmpty from 'lodash/isEmpty'
import {
  map,
  compose,
  toUpper,
  slice,
  groupBy,
  sort,
  ascend,
  prop,
  keys,
  fromPairs
} from 'ramda/es'
import simplePinyin from 'simple-pinyin'

import { fetchAllCats, fetchSkuTemplate } from '@/services/goods'

export default {
  state: {
    cats: [],
    temp: {},
    catListGroupMap: {},
    formatCatsByLevelThree: [],
    formatCatsByLevelTwo: [],
    lastPublishedGoodsInfo: {}
  },
  reducers: {
    updateState(state, payload) {
      return {
        ...state,
        ...payload
      }
    }
  },
  effects: () => ({
    async initCats(payload, { goods: { cats = [] } = {} }) {
      if (isEmpty(cats)) {
        try {
          await this.getCats()
        } catch (err) {}
      } else {
        return false
      }
    },
    async initTemp(payload, { goods: { temp = {} } = {} }) {
      if (isEmpty(temp)) {
        try {
          await this.getTemp()
        } catch (err) {}
      } else {
        return false
      }
    },
    async getCats(payload, { user: { marketId } = {} }) {
      if (!marketId) {
        return
      }
      try {
        const cats = await fetchAllCats()
        const {
          sortList: catListGroupMap = {},
          formatCatsByLevelThree,
          formatCatsByLevelTwo
        } = await this.formatCats({ cats })
        this.updateState({ cats, catListGroupMap, formatCatsByLevelThree, formatCatsByLevelTwo })
      } catch (err) {}
    },
    // 依次遍历类目到三级,按照首字母拼音排序(groupBy)
    // 最后的数据结构:
    // { 'A': [], 'B': [], 'C': [], ... }
    async formatCats({ cats }) {
      let formatCatsByLevelThree = []
      let formatCatsByLevelTwo = []
      const catList = map(
        ({ catName, ...args }) => ({
          catName,
          ...args,
          firstLetter: compose(
            toUpper,
            slice(0, 1),
            char => simplePinyin(char, { pinyinOnly: true })[0] || '',
            slice(0, 1)
          )(catName)
        }),
        formatCatsByLevelThree
      )
      const catListGroupMap = groupBy(e => e.firstLetter)(catList)
      const sortList = compose(
        fromPairs,
        map(e => [e, catListGroupMap[e]]),
        sort(ascend(prop(0))),
        keys
      )(catListGroupMap)
      return { sortList, formatCatsByLevelThree, formatCatsByLevelTwo }
    },
    async getTemp() {
      const temp = await fetchSkuTemplate()
      this.updateState({ temp })
    }
  })
}