feat(appicon): AppIcon 资产库接入(应用网格矢量图标渲染,YschAppIcons 10-04 轮 P3)

- AppIcon.vue:矢量图标渲染组件(iconKey+iconColor → mask data-uri,无键无 URL 回退关键词映射占位)
- constants/appIconRules.ts:应用名关键词→图标键兜底映射(D4,两端各持一份,与 MobilePortal 关键词列一致;仅 icon_key 未配置且无 URL 时生效,有 URL 恒定位图零回归)
- AppList/SearchPanel/index:应用网格与搜索结果图标位换 AppIcon
- appicon.mask.css:资产库 mask 样式;yunhai-logo.svg:站点 Logo 矢量件
- main.scss/_app_container.scss:网格图标容器样式配套
依据:根目录《AppIcon资产库落地-执行报告-20261004.md》P3 UserHome(PC)接入
This commit is contained in:
chenxing
2026-10-06 20:20:32 +08:00
parent 93249cf5f5
commit 4d9da5e3a6
9 changed files with 226 additions and 7 deletions
+19 -5
View File
@@ -30,7 +30,9 @@
]"
>
<a @click="linkPage(citem.webAddr, citem)">
<img :src="$utils.appIconPath(citem.icon)" />
<AppIcon v-if="vectorIconOf(citem)" :name="vectorIconOf(citem)" scene="tile"
:tint="citem.iconColor" />
<img v-else :src="$utils.appIconPath(citem.icon)" />
<div class="app-name">{{ citem.name }}</div>
</a>
</ContextMenu>
@@ -60,10 +62,10 @@
]"
>
<a @click="linkPage(item.webAddr, item)">
<img
:src="requireImg('defappicon.png')"
v-real-img="$utils.appIconPath(item.icon)"
/>
<AppIcon v-if="vectorIconOf(item)" :name="vectorIconOf(item)" scene="tile"
:tint="item.iconColor" />
<img v-else :src="requireImg('defappicon.png')"
v-real-img="$utils.appIconPath(item.icon)" />
<div class="app-name">{{ item.name }}</div>
</a>
</ContextMenu>
@@ -79,6 +81,7 @@
<script lang="ts" setup>
import ContextMenu from "@/components/ContextMenu.vue";
import AppIcon from "@/components/AppIcon.vue";
import vuescroll from "vuescroll";
import { ref, onMounted, onUnmounted, computed, watch } from "vue";
import BaseApi from "@/api/BaseApi";
@@ -92,6 +95,17 @@ import UserSettingApi from "@/api/UserSettingApi";
import { Message } from "view-ui-plus";
import { bschLinkPage } from "@/utils/bschLinkPage";
import useCurrentInstance from "@/utils/hook/useCurrentInstance";
import { appiconKeyOf } from "@/constants/appIconRules";
/**
* 矢量渲染判定(方案 §5.4 回退链,与 index.vue / SearchPanel.vue 同口径):
* icon_key 命中 → 矢量;有位图 URL → 位图(存量零回归);URL 空且关键词命中 → 矢量;否则默认图。
*/
function vectorIconOf(app: any): string {
if (app?.iconKey) return app.iconKey;
if (app?.icon) return "";
return appiconKeyOf(app?.name || "");
}
// 仅在内容溢出时显示原生滚动条,避免空内容时也常驻滚动条
const scrollOps = {