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:
@@ -0,0 +1,36 @@
|
||||
<template>
|
||||
<i class="appicon" :class="classes" :style="styles" aria-hidden="true"></i>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
/**
|
||||
* 矢量应用图标(AppIcon 资产库,CSS mask 版)。
|
||||
* - name:资产库图标键(appicon-<名>,形状来自全局 appicon.mask.css,data-uri 自包含)
|
||||
* - scene:tile 方块底 / circle 正圆底 / plain 无底线性(三档端侧 token,见 _app_container.scss)
|
||||
* - tint:人工配置色(application_info.icon_color)——tile/circle 覆盖底色、plain 覆盖图标色;空=场景默认
|
||||
* 渲染契约(方案 §4):图标资源只管形状,容器管底色与图标色。
|
||||
*/
|
||||
import { computed } from "vue";
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
name?: string;
|
||||
scene?: "tile" | "circle" | "plain";
|
||||
tint?: string;
|
||||
}>(), {
|
||||
name: "",
|
||||
scene: "tile",
|
||||
tint: "",
|
||||
});
|
||||
|
||||
const classes = computed(() => [
|
||||
`appicon-${props.scene}`,
|
||||
...(props.name ? [`appicon-${props.name}`] : []),
|
||||
]);
|
||||
|
||||
const styles = computed<Record<string, string> | undefined>(() => {
|
||||
if (!props.tint) return undefined;
|
||||
return props.scene === "plain"
|
||||
? { color: props.tint }
|
||||
: { backgroundColor: props.tint };
|
||||
});
|
||||
</script>
|
||||
@@ -13,7 +13,9 @@
|
||||
<vuescroll>
|
||||
<div class="app-search-list">
|
||||
<div v-for="(item, index) in appList" class="app-container">
|
||||
<img :src="$utils.appIconPath(item.icon)" />
|
||||
<AppIcon v-if="vectorIconOf(item)" :name="vectorIconOf(item)" scene="tile"
|
||||
:tint="item.iconColor" />
|
||||
<img v-else :src="$utils.appIconPath(item.icon)" />
|
||||
<div class="app-name">{{ item.name }}</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -26,10 +28,22 @@
|
||||
import { useDefaultStore } from "@/store";
|
||||
import { ref, inject, computed, onMounted, watch } from "vue";
|
||||
import vuescroll from "vuescroll";
|
||||
import AppIcon from "@/components/AppIcon.vue";
|
||||
import { appiconKeyOf } from "@/constants/appIconRules";
|
||||
import useCurrentInstance from "@/utils/hook/useCurrentInstance";
|
||||
|
||||
const { $utils } = useCurrentInstance();
|
||||
|
||||
/**
|
||||
* 矢量渲染判定(方案 §5.4 回退链,与 AppList.vue / index.vue 同口径):
|
||||
* icon_key 命中 → 矢量;有位图 URL → 位图(存量零回归);URL 空且关键词命中 → 矢量;否则默认图。
|
||||
*/
|
||||
function vectorIconOf(item: any): string {
|
||||
if (item?.iconKey) return item.iconKey;
|
||||
if (item?.icon) return "";
|
||||
return appiconKeyOf(item?.name || "");
|
||||
}
|
||||
|
||||
const refInput = ref();
|
||||
|
||||
const searchName = ref();
|
||||
|
||||
Reference in New Issue
Block a user