Browse Source

Merge branch 'redesign‌-260706' of git.huaml.com:zhh/front-end into redesign‌-260706

shizhongqi 3 weeks ago
parent
commit
aa65539771

+ 94 - 0
hdApp/src/components/sprite-icon/index.vue

@@ -0,0 +1,94 @@
+<!--
+  雪碧图图标组件
+  用途:按 sheet + name 从 SPRITE_SHEETS 裁切显示图标,支持多张雪碧图
+  小程序:外层裁切 + 内层 view absolute 位移 + image 铺满(position 不能写在 image 上)
+-->
+<template>
+  <view
+    class="sprite-icon"
+    :class="customClass"
+    :style="wrapStyle"
+    @click="$emit('click', $event)"
+  >
+    <view class="sprite-inner" :style="innerStyle">
+      <image
+        class="sprite-image"
+        :src="spriteUrl"
+        :style="imageStyle"
+        mode="scaleToFill"
+      />
+    </view>
+  </view>
+</template>
+
+<script>
+import { getSpriteSheetUrl, resolveSprite, spriteImageStyle } from "@/utils/mainIndexSprite";
+
+export default {
+  name: "SpriteIcon",
+  options: {
+    externalClasses: ["custom-class"]
+  },
+  props: {
+    /** 图标名,需在对应 sheet 的 icons 中配置 */
+    name: {
+      type: String,
+      required: true
+    },
+    /** 雪碧图 key,如 main / stock;不传则按图标名自动匹配 */
+    sheet: {
+      type: String,
+      default: ""
+    },
+    /** 显示宽度 rpx */
+    size: {
+      type: [Number, String],
+      default: 48
+    },
+    /** 额外 class,配合页面 ::v-deep 写间距 */
+    customClass: {
+      type: [String, Array, Object],
+      default: ""
+    }
+  },
+  computed: {
+    resolvedSprite() {
+      return resolveSprite(this.name, this.sheet);
+    },
+    spriteUrl() {
+      if (!this.resolvedSprite) {
+        return "";
+      }
+      return getSpriteSheetUrl(this.resolvedSprite.sheetKey);
+    },
+    spriteLayout() {
+      return spriteImageStyle(this.name, this.size, this.sheet);
+    },
+    wrapStyle() {
+      return this.spriteLayout.wrap;
+    },
+    innerStyle() {
+      return this.spriteLayout.inner;
+    },
+    imageStyle() {
+      return this.spriteLayout.image;
+    }
+  }
+};
+</script>
+
+<style scoped>
+.sprite-icon {
+  display: inline-block;
+  flex-shrink: 0;
+  vertical-align: middle;
+}
+
+.sprite-inner {
+  line-height: 0;
+}
+
+.sprite-image {
+  display: block;
+}
+</style>

+ 3 - 0
hdApp/src/main.js

@@ -15,6 +15,9 @@ Vue.mixin(globalMixins);
 import kdEntrance from "@/components/kd_entrance";
 Vue.component('kd-entrance', kdEntrance)
 
+import SpriteIcon from '@/components/sprite-icon/index.vue';
+Vue.component('sprite-icon', SpriteIcon);
+
 import store from "./store";
 Vue.prototype.$store = store;
 

+ 6 - 0
hdApp/src/pages.json

@@ -1,4 +1,10 @@
 {
+	"easycom": {
+		"autoscan": true,
+		"custom": {
+			"^sprite-icon$": "@/components/sprite-icon/index.vue"
+		}
+	},
 	"pages": [
 		{ "path": "admin/home/workbench", "style": { "navigationBarTitleText": "进货", "enablePullDownRefresh": true, "navigationStyle": "custom" } },
 		{ "path": "admin/home/mall", "style": { "navigationBarTitleText": "店铺", "enablePullDownRefresh": true, "navigationStyle": "custom" } },

+ 218 - 0
hdApp/src/utils/mainIndexSprite.js

@@ -0,0 +1,218 @@
+/**
+ * 雪碧图注册表
+ * 用途:sprite-icon 按 sheet + name 从多张 CDN 雪碧图裁切显示图标
+ * 图片地址随 ext.json / 环境 imgHost 变化,必须用函数运行时读取
+ */
+import constant from "@/constant/index";
+
+/** 默认图床(ext 未配置 imgHost 时的兜底) */
+const DEFAULT_IMG_HOST = "https://img.huaml.com";
+
+/** 未传 sheet 时默认使用的雪碧图 key */
+const DEFAULT_SHEET_KEY = "main";
+
+/**
+ * 雪碧图注册表:每张图含 path、原图尺寸、icons 坐标
+ * icons 的 x/y 为左上角,w/h 为截取区域(基于原图测量)
+ */
+export const SPRITE_SHEETS = {
+  main: {
+    path: "/hzg/sprite_icon/main_index.webp",
+    width: 500,
+    height: 500,
+    icons: {
+      "dengji-biandong": { x: 14, y: 17, w: 32, h: 28 },
+    }
+  },
+  /** 进货/供货商专用雪碧图,坐标待设计稿测量后补全 */
+  /* stock: {
+    path: "/hzg/sprite_icon/main_index.webp?time=2607101747",
+    width: 500,
+    height: 500,
+    icons: {
+      "yue-biandong": { x: 60, y: 17, w: 28, h: 28 }
+				}
+  } */
+};
+
+/** tabBar 未选中 / 选中 图标名映射(main 雪碧图) */
+export const TAB_SPRITE_MAP = {
+  home: { normal: "dianpu-line", active: "dianpu-fill" },
+  order: { normal: "huoche-lv", active: "huoche-da" },
+  mine: { normal: "gou-quan", active: "qianbao" }
+};
+
+/** @deprecated 兼容旧引用,等同 SPRITE_SHEETS.main 尺寸 */
+export const MAIN_INDEX_SPRITE = {
+  width: SPRITE_SHEETS.main.width,
+  height: SPRITE_SHEETS.main.height
+};
+
+/** @deprecated 兼容旧引用,等同 SPRITE_SHEETS.main.icons */
+export const MAIN_INDEX_ICONS = SPRITE_SHEETS.main.icons;
+
+/**
+ * 构建全局唯一图标名 -> sheetKey 索引
+ * @param {object} sheets
+ * @returns {object}
+ */
+function buildIconSheetIndex(sheets) {
+  const index = {};
+  Object.keys(sheets).forEach((sheetKey) => {
+    const icons = sheets[sheetKey].icons || {};
+    Object.keys(icons).forEach((name) => {
+      if (index[name] && index[name] !== sheetKey && process.env.NODE_ENV !== "production") {
+        console.warn(`[sprite] 图标名 "${name}" 在 ${index[name]} 与 ${sheetKey} 中重复,以 ${sheetKey} 为准`);
+      }
+      index[name] = sheetKey;
+    });
+  });
+  return index;
+}
+
+const ICON_SHEET_INDEX = buildIconSheetIndex(SPRITE_SHEETS);
+
+/**
+ * 获取图床根地址(HTTPS)
+ * @returns {string}
+ */
+function getImgHostBase() {
+  let base = (constant.imgUrl || DEFAULT_IMG_HOST).replace(/\/$/, "");
+  if (base.indexOf("http://") === 0) {
+    base = `https://${base.slice(7)}`;
+  }
+  return base;
+}
+
+/**
+ * rpx 转 px;小程序 absolute 位移必须用 px
+ * @param {number} rpx
+ * @returns {number}
+ */
+function rpx2px(rpx) {
+  if (typeof uni !== "undefined" && typeof uni.upx2px === "function") {
+    return uni.upx2px(rpx);
+  }
+  return rpx;
+}
+
+/**
+ * 解析图标所属雪碧图与坐标
+ * @param {string} name 图标名
+ * @param {string} sheetKey 可选,指定雪碧图 key;空则按索引或 main 查找
+ * @returns {{ sheetKey: string, sheet: object, icon: object }|null}
+ */
+export function resolveSprite(name, sheetKey = "") {
+  if (!name) {
+    return null;
+  }
+  let key = sheetKey;
+  if (!key) {
+    key = ICON_SHEET_INDEX[name] || DEFAULT_SHEET_KEY;
+  }
+  const sheet = SPRITE_SHEETS[key];
+  if (!sheet) {
+    return null;
+  }
+  const icon = (sheet.icons || {})[name];
+  if (!icon) {
+    return null;
+  }
+  return { sheetKey: key, sheet, icon };
+}
+
+/**
+ * 获取指定雪碧图完整 URL
+ * @param {string} sheetKey
+ * @returns {string}
+ */
+export function getSpriteSheetUrl(sheetKey = DEFAULT_SHEET_KEY) {
+  const sheet = SPRITE_SHEETS[sheetKey];
+  if (!sheet) {
+    return "";
+  }
+  return `${getImgHostBase()}${sheet.path}`;
+}
+
+/**
+ * 生成雪碧图 image 裁切样式(小程序 absolute 定位)
+ * @param {string} name
+ * @param {number|string} size 显示宽度 rpx
+ * @param {string} sheetKey 可选雪碧图 key
+ * @returns {{ wrap: string, inner: string, image: string }}
+ */
+export function spriteImageStyle(name, size = 48, sheetKey = "") {
+  const resolved = resolveSprite(name, sheetKey);
+  if (!resolved) {
+    if (process.env.NODE_ENV !== "production") {
+      console.warn(`[sprite-icon] 未找到图标: name=${name}${sheetKey ? ` sheet=${sheetKey}` : ""}`);
+    }
+    return { wrap: "", inner: "", image: "" };
+  }
+  const { sheet, icon } = resolved;
+  const displayW = Number(size) || 48;
+  const scale = displayW / icon.w;
+  const displayH = Math.round(icon.h * scale);
+  const sheetW = sheet.width * scale;
+  const sheetH = sheet.height * scale;
+  const left = -rpx2px(icon.x * scale);
+  const top = -rpx2px(icon.y * scale);
+  const sheetWPx = rpx2px(sheetW);
+  const sheetHPx = rpx2px(sheetH);
+  return {
+    wrap: `position:relative;width:${displayW}rpx;height:${displayH}rpx;overflow:hidden;line-height:0;`,
+    inner: `position:absolute;left:${left}px;top:${top}px;width:${sheetWPx}px;height:${sheetHPx}px;`,
+    image: "width:100%;height:100%;display:block;"
+  };
+}
+
+/**
+ * 生成雪碧图行内样式(view + background)
+ * @param {string} name
+ * @param {number|string} size
+ * @param {string} sheetKey
+ * @returns {string}
+ */
+export function spriteStyle(name, size = 48, sheetKey = "") {
+  const resolved = resolveSprite(name, sheetKey);
+  if (!resolved) {
+    return "";
+  }
+  const { sheetKey: key, sheet, icon } = resolved;
+  const displayW = Number(size) || 48;
+  const scale = displayW / icon.w;
+  const displayH = Math.round(icon.h * scale);
+  const sheetW = sheet.width * scale;
+  const sheetH = sheet.height * scale;
+  const posX = rpx2px(icon.x * scale);
+  const posY = rpx2px(icon.y * scale);
+  const sheetWPx = rpx2px(sheetW);
+  const sheetHPx = rpx2px(sheetH);
+  const url = getSpriteSheetUrl(key);
+  return [
+    `width:${displayW}rpx`,
+    `height:${displayH}rpx`,
+    `background-image:url(${url})`,
+    `background-size:${sheetWPx}px ${sheetHPx}px`,
+    `background-position:-${posX}px -${posY}px`,
+    "background-repeat:no-repeat",
+    "display:inline-block",
+    "flex-shrink:0",
+    "vertical-align:middle"
+  ].join(";");
+}
+
+/** @deprecated 兼容旧 API */
+export function getMainIndexSpriteUrl() {
+  return getSpriteSheetUrl(DEFAULT_SHEET_KEY);
+}
+
+/** @deprecated 兼容旧 API */
+export function mainIndexSpriteImageStyle(name, size = 48) {
+  return spriteImageStyle(name, size, DEFAULT_SHEET_KEY);
+}
+
+/** @deprecated 兼容旧 API */
+export function mainIndexSpriteStyle(name, size = 48) {
+  return spriteStyle(name, size, DEFAULT_SHEET_KEY);
+}

+ 21 - 9
mallApp/src/components/sprite-icon/index.vue

@@ -1,5 +1,6 @@
 <!--
   雪碧图图标组件
+  用途:按 sheet + name 从 SPRITE_SHEETS 裁切显示图标,支持多张雪碧图
   小程序:外层裁切 + 内层 view absolute 位移 + image 铺满(position 不能写在 image 上)
 -->
 <template>
@@ -21,7 +22,7 @@
 </template>
 
 <script>
-import { getMainIndexSpriteUrl, mainIndexSpriteImageStyle } from "@/utils/mainIndexSprite";
+import { getSpriteSheetUrl, resolveSprite, spriteImageStyle } from "@/utils/mainIndexSprite";
 
 export default {
   name: "SpriteIcon",
@@ -29,11 +30,16 @@ export default {
     externalClasses: ["custom-class"]
   },
   props: {
-    /** MAIN_INDEX_ICONS 中的图标名 */
+    /** 图标名,需在对应 sheet 的 icons 中配置 */
     name: {
       type: String,
       required: true
     },
+    /** 雪碧图 key,如 main / stock;不传则按图标名自动匹配 */
+    sheet: {
+      type: String,
+      default: ""
+    },
     /** 显示宽度 rpx */
     size: {
       type: [Number, String],
@@ -46,19 +52,25 @@ export default {
     }
   },
   computed: {
-    spriteUrl () {
-      return getMainIndexSpriteUrl();
+    resolvedSprite() {
+      return resolveSprite(this.name, this.sheet);
+    },
+    spriteUrl() {
+      if (!this.resolvedSprite) {
+        return "";
+      }
+      return getSpriteSheetUrl(this.resolvedSprite.sheetKey);
     },
-    spriteLayout () {
-      return mainIndexSpriteImageStyle(this.name, this.size);
+    spriteLayout() {
+      return spriteImageStyle(this.name, this.size, this.sheet);
     },
-    wrapStyle () {
+    wrapStyle() {
       return this.spriteLayout.wrap;
     },
-    innerStyle () {
+    innerStyle() {
       return this.spriteLayout.inner;
     },
-    imageStyle () {
+    imageStyle() {
       return this.spriteLayout.image;
     }
   }

+ 130 - 74
mallApp/src/utils/mainIndexSprite.js

@@ -1,74 +1,98 @@
 /**
- * main_index.webp 雪碧图配置
+ * 雪碧图注册表
+ * 用途:sprite-icon 按 sheet + name 从多张 CDN 雪碧图裁切显示图标
  * 图片地址随 ext.json / 环境 imgHost 变化,必须用函数运行时读取,不能用 this.$constant
  */
 import constant from "@/constant/index";
 
-/** 雪碧图相对路径(拼在 imgHost 后) */
-const MAIN_INDEX_SPRITE_PATH = "/ghs/main_index.webp?time=2607101747";
-
 /** 默认图床(ext 未配置 imgHost 时的兜底) */
 const DEFAULT_IMG_HOST = "https://img.huaml.com";
 
-/**
- * 获取雪碧图完整 URL(运行时读取 imgHost)
- * @returns {string}
- */
-export function getMainIndexSpriteUrl() {
-  let base = (constant.imgUrl || DEFAULT_IMG_HOST).replace(/\/$/, "");
-  // 真机端网络图要求 HTTPS,ext 里 imgHost 常为 http
-  if (base.indexOf("http://") === 0) {
-    base = `https://${base.slice(7)}`;
-  }
-  return `${base}${MAIN_INDEX_SPRITE_PATH}`;
-}
-
-export const MAIN_INDEX_SPRITE = {
-  width: 500,
-  height: 500
-};
+/** 未传 sheet 时默认使用的雪碧图 key */
+const DEFAULT_SHEET_KEY = "main";
 
 /**
- * 雪碧图内各图标坐标(基于 500×500 原图测量)
- * x/y 为图标左上角,w/h 为截取区域宽高
+ * 雪碧图注册表:每张图含 path、原图尺寸、icons 坐标
  */
-export const MAIN_INDEX_ICONS = {
-  "dengji-biandong": { x: 14, y: 17, w: 32, h: 28 },
-  "yue-biandong": { x: 60, y: 17, w: 28, h: 28 },
-  "huiyuan-quanyi": { x: 102, y: 17, w: 28, h: 28 },
-  "lianxikefu": { x: 145, y: 17, w: 28, h: 28 },
-  "huangguan": { x: 189, y: 20, w: 22, h: 21 },
-  "shezhi": { x: 13, y: 62, w: 34, h: 36 },
-  "shaixuan": { x: 71, y: 67, w: 25, h: 25 },
-  "dianpu-fill": { x: 116, y: 63, w: 31, h: 30 },
-  "huoche-cheng": { x: 171, y: 68, w: 23, h: 21 },
-  "huoche-lv": { x: 204, y: 68, w: 23, h: 21 },
-  "gou-quan": { x: 246, y: 68, w: 22, h: 21 },
-  "huashu": { x:4, y: 118, w: 52, h: 49 },
-  "hua": { x: 94, y: 118, w: 52, h: 49 },
-  "dianpu-line": { x: 167, y: 114, w: 51, h: 51 },
-  "tuichu": { x: 243, y: 111, w: 49, h: 51 },
-  "xiaoxi": { x: 8, y: 186, w: 43, h: 44 },
-  "qianbao": { x: 65, y: 180, w: 58, h: 52 },
-  "huoche-da": { x: 140, y: 184, w: 63, h: 53 },
-  "baoguo": { x: 218, y: 180, w: 57, h: 53 },
-  "fanghu-yuan": { x: 299, y: 174, w: 53, h: 61 },
-  "youhuiquan": { x: 382, y: 183, w: 51, h: 49 },
-  "gengduo-quan": { x: 274, y: 102, w: 52, h: 52 }
+export const SPRITE_SHEETS = {
+  main: {
+    path: "/ghs/main_index.webp?time=2607101747",
+    width: 500,
+    height: 500,
+    icons: {
+      "dengji-biandong": { x: 14, y: 17, w: 32, h: 28 },
+      "yue-biandong": { x: 60, y: 17, w: 28, h: 28 },
+      "huiyuan-quanyi": { x: 102, y: 17, w: 28, h: 28 },
+      "lianxikefu": { x: 145, y: 17, w: 28, h: 28 },
+      "huangguan": { x: 189, y: 20, w: 22, h: 21 },
+      "shezhi": { x: 13, y: 62, w: 34, h: 36 },
+      "shaixuan": { x: 71, y: 67, w: 25, h: 25 },
+      "dianpu-fill": { x: 116, y: 63, w: 31, h: 30 },
+      "huoche-cheng": { x: 171, y: 68, w: 23, h: 21 },
+      "huoche-lv": { x: 204, y: 68, w: 23, h: 21 },
+      "gou-quan": { x: 246, y: 68, w: 22, h: 21 },
+      "huashu": { x: 4, y: 118, w: 52, h: 49 },
+      "hua": { x: 94, y: 118, w: 52, h: 49 },
+      "dianpu-line": { x: 167, y: 114, w: 51, h: 51 },
+      "tuichu": { x: 243, y: 111, w: 49, h: 51 },
+      "xiaoxi": { x: 8, y: 186, w: 43, h: 44 },
+      "qianbao": { x: 65, y: 180, w: 58, h: 52 },
+      "huoche-da": { x: 140, y: 184, w: 63, h: 53 },
+      "baoguo": { x: 218, y: 180, w: 57, h: 53 },
+      "fanghu-yuan": { x: 299, y: 174, w: 53, h: 61 },
+      "youhuiquan": { x: 382, y: 183, w: 51, h: 49 },
+      "gengduo-quan": { x: 274, y: 102, w: 52, h: 52 }
+    }
+  },
+  /** 进货/供货商专用雪碧图,坐标待设计稿测量后补全 */
+  stock: {
+    path: "/retail/stock_sprite.webp?time=2607140000",
+    width: 500,
+    height: 500,
+    icons: {}
+  }
 };
 
-/** tabBar 未选中 / 选中 图标名映射 */
+/** tabBar 未选中 / 选中 图标名映射(main 雪碧图) */
 export const TAB_SPRITE_MAP = {
   home: { normal: "dianpu-line", active: "dianpu-fill" },
   order: { normal: "huoche-lv", active: "huoche-da" },
   mine: { normal: "gou-quan", active: "qianbao" }
 };
 
-/**
- * rpx 转 px;小程序 transform / margin 位移必须用 px,rpx 在 transform 里常不生效
- * @param {number} rpx
- * @returns {number}
- */
+/** @deprecated 兼容旧引用 */
+export const MAIN_INDEX_SPRITE = {
+  width: SPRITE_SHEETS.main.width,
+  height: SPRITE_SHEETS.main.height
+};
+
+/** @deprecated 兼容旧引用 */
+export const MAIN_INDEX_ICONS = SPRITE_SHEETS.main.icons;
+
+function buildIconSheetIndex(sheets) {
+  const index = {};
+  Object.keys(sheets).forEach((sheetKey) => {
+    const icons = sheets[sheetKey].icons || {};
+    Object.keys(icons).forEach((name) => {
+      if (index[name] && index[name] !== sheetKey && process.env.NODE_ENV !== "production") {
+        console.warn(`[sprite] 图标名 "${name}" 在 ${index[name]} 与 ${sheetKey} 中重复,以 ${sheetKey} 为准`);
+      }
+      index[name] = sheetKey;
+    });
+  });
+  return index;
+}
+
+const ICON_SHEET_INDEX = buildIconSheetIndex(SPRITE_SHEETS);
+
+function getImgHostBase() {
+  let base = (constant.imgUrl || DEFAULT_IMG_HOST).replace(/\/$/, "");
+  if (base.indexOf("http://") === 0) {
+    base = `https://${base.slice(7)}`;
+  }
+  return base;
+}
+
 function rpx2px(rpx) {
   if (typeof uni !== "undefined" && typeof uni.upx2px === "function") {
     return uni.upx2px(rpx);
@@ -76,22 +100,47 @@ function rpx2px(rpx) {
   return rpx;
 }
 
-/**
- * 生成雪碧图 image 裁切样式(小程序用 absolute 定位,避免 transform/rpx 兼容问题)
- * @param {string} name
- * @param {number|string} size 显示宽度 rpx
- * @returns {{ wrap: string, inner: string, image: string }}
- */
-export function mainIndexSpriteImageStyle(name, size = 48) {
-  const icon = MAIN_INDEX_ICONS[name];
+export function resolveSprite(name, sheetKey = "") {
+  if (!name) {
+    return null;
+  }
+  let key = sheetKey;
+  if (!key) {
+    key = ICON_SHEET_INDEX[name] || DEFAULT_SHEET_KEY;
+  }
+  const sheet = SPRITE_SHEETS[key];
+  if (!sheet) {
+    return null;
+  }
+  const icon = (sheet.icons || {})[name];
   if (!icon) {
+    return null;
+  }
+  return { sheetKey: key, sheet, icon };
+}
+
+export function getSpriteSheetUrl(sheetKey = DEFAULT_SHEET_KEY) {
+  const sheet = SPRITE_SHEETS[sheetKey];
+  if (!sheet) {
+    return "";
+  }
+  return `${getImgHostBase()}${sheet.path}`;
+}
+
+export function spriteImageStyle(name, size = 48, sheetKey = "") {
+  const resolved = resolveSprite(name, sheetKey);
+  if (!resolved) {
+    if (process.env.NODE_ENV !== "production") {
+      console.warn(`[sprite-icon] 未找到图标: name=${name}${sheetKey ? ` sheet=${sheetKey}` : ""}`);
+    }
     return { wrap: "", inner: "", image: "" };
   }
+  const { sheet, icon } = resolved;
   const displayW = Number(size) || 48;
   const scale = displayW / icon.w;
   const displayH = Math.round(icon.h * scale);
-  const sheetW = MAIN_INDEX_SPRITE.width * scale;
-  const sheetH = MAIN_INDEX_SPRITE.height * scale;
+  const sheetW = sheet.width * scale;
+  const sheetH = sheet.height * scale;
   const left = -rpx2px(icon.x * scale);
   const top = -rpx2px(icon.y * scale);
   const sheetWPx = rpx2px(sheetW);
@@ -103,27 +152,22 @@ export function mainIndexSpriteImageStyle(name, size = 48) {
   };
 }
 
-/**
- * 生成雪碧图行内样式(view + background,小程序端裁切最稳定)
- * @param {string} name
- * @param {number|string} size 显示宽度 rpx
- * @returns {string}
- */
-export function mainIndexSpriteStyle(name, size = 48) {
-  const icon = MAIN_INDEX_ICONS[name];
-  if (!icon) {
+export function spriteStyle(name, size = 48, sheetKey = "") {
+  const resolved = resolveSprite(name, sheetKey);
+  if (!resolved) {
     return "";
   }
+  const { sheetKey: key, sheet, icon } = resolved;
   const displayW = Number(size) || 48;
   const scale = displayW / icon.w;
   const displayH = Math.round(icon.h * scale);
-  const sheetW = MAIN_INDEX_SPRITE.width * scale;
-  const sheetH = MAIN_INDEX_SPRITE.height * scale;
+  const sheetW = sheet.width * scale;
+  const sheetH = sheet.height * scale;
   const posX = rpx2px(icon.x * scale);
   const posY = rpx2px(icon.y * scale);
   const sheetWPx = rpx2px(sheetW);
   const sheetHPx = rpx2px(sheetH);
-  const url = getMainIndexSpriteUrl();
+  const url = getSpriteSheetUrl(key);
   return [
     `width:${displayW}rpx`,
     `height:${displayH}rpx`,
@@ -136,3 +180,15 @@ export function mainIndexSpriteStyle(name, size = 48) {
     "vertical-align:middle"
   ].join(";");
 }
+
+export function getMainIndexSpriteUrl() {
+  return getSpriteSheetUrl(DEFAULT_SHEET_KEY);
+}
+
+export function mainIndexSpriteImageStyle(name, size = 48) {
+  return spriteImageStyle(name, size, DEFAULT_SHEET_KEY);
+}
+
+export function mainIndexSpriteStyle(name, size = 48) {
+  return spriteStyle(name, size, DEFAULT_SHEET_KEY);
+}