All files / public/admin category-domain.js

97.67% Statements 42/43
88.23% Branches 45/51
100% Functions 19/19
97.43% Lines 38/39

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 1037x       49x       11x 26x 26x 26x         2x 4x 3x           1x 1x 2x         2x       1x 4x 4x 4x         1x 3x 3x         3x 3x 9x   9x     9x     3x 3x 1x   2x         3x 3x       2x 2x 2x 1x   1x         2x           7x                        
(function (global) {
  "use strict";
 
  function normalizeCategory(value) {
    return typeof value === "string" ? value.trim() : "";
  }
 
  function uniqueCategories(values) {
    return (Array.isArray(values) ? values : []).reduce(function (result, value) {
      var category = normalizeCategory(value);
      if (category && result.indexOf(category) === -1) result.push(category);
      return result;
    }, []);
  }
 
  function sortCategories(values) {
    return uniqueCategories(values).sort(function (left, right) {
      if (left < right) return -1;
      Eif (left > right) return 1;
      return 0;
    });
  }
 
  function missingCategories(selected, library) {
    var known = uniqueCategories(library);
    return uniqueCategories(selected).filter(function (category) {
      return known.indexOf(category) === -1;
    });
  }
 
  function mergeCategories(library, additions) {
    return sortCategories(uniqueCategories(library).concat(uniqueCategories(additions)));
  }
 
  function countUsage(entries) {
    return (Array.isArray(entries) ? entries : []).reduce(function (usage, entry) {
      var category = normalizeCategory(entry && entry.data && entry.data.category);
      if (category) usage[category] = (usage[category] || 0) + 1;
      return usage;
    }, Object.create(null));
  }
 
  function categoryStats(categories, usage) {
    return uniqueCategories(categories).map(function (category) {
      var count = usage && Object.hasOwn(usage, category) ? usage[category] : 0;
      return { name: category, count: count, used: count > 0 };
    });
  }
 
  function filterCategoryStats(items, query, filter, sort) {
    var term = normalizeCategory(query).toLocaleLowerCase();
    var result = (Array.isArray(items) ? items : []).filter(function (item) {
      var matchesQuery = !term || item.name.toLocaleLowerCase().includes(term);
      var matchesFilter =
        filter === "used" ? item.used :
        filter === "unused" ? !item.used :
        true;
      return matchesQuery && matchesFilter;
    });
 
    return result.sort(function (left, right) {
      if (sort === "usage") {
        return right.count - left.count || left.name.localeCompare(right.name, "zh-CN");
      }
      return left.name.localeCompare(right.name, "zh-CN");
    });
  }
 
  function canDelete(category, usage) {
    var normalized = normalizeCategory(category);
    return !usage || !Object.hasOwn(usage, normalized) || usage[normalized] === 0;
  }
 
  function renamePlan(library, source, target, usage) {
    var oldCategory = normalizeCategory(source);
    var newCategory = normalizeCategory(target);
    if (!oldCategory || !newCategory || oldCategory === newCategory) {
      throw new Error("源分类和目标分类必须不同且不能为空");
    }
    return {
      source: oldCategory,
      target: newCategory,
      affectedCount: usage && usage[oldCategory] ? usage[oldCategory] : 0,
      library: mergeCategories(
        uniqueCategories(library).filter(function (category) { return category !== oldCategory; }),
        [newCategory],
      ),
    };
  }
 
  global.DecapCategoryDomain = {
    normalizeCategory: normalizeCategory,
    uniqueCategories: uniqueCategories,
    missingCategories: missingCategories,
    mergeCategories: mergeCategories,
    countUsage: countUsage,
    categoryStats: categoryStats,
    filterCategoryStats: filterCategoryStats,
    canDelete: canDelete,
    renamePlan: renamePlan,
  };
})(window);