feat(achievement): 成就图标改用 iconify 渲染
机房的老浏览器缺 emoji 字体,成就图标会渲染成方块。后端的 icon 字段 改存 iconify 图标名(noto 集),前端统一走新的 AchievementIcon 组件 渲染成 SVG。 组件按三种形态判断:图片 URL 走 img,含冒号走 Icon,其余当纯文本兜底, 所以存量的 emoji 数据不会瞎掉。 顺带修好解锁弹窗:题单奖章的 icon 是图片 URL,之前当文本渲染,会把 一串路径直接显示出来。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -6,6 +6,7 @@ import {
|
||||
type AdminAchievement,
|
||||
type MetricOption,
|
||||
} from "admin/api"
|
||||
import AchievementIcon from "shared/components/AchievementIcon.vue"
|
||||
|
||||
const props = defineProps<{
|
||||
show: boolean
|
||||
@@ -21,7 +22,7 @@ function emptyForm() {
|
||||
return {
|
||||
name: "",
|
||||
description: "",
|
||||
icon: "🏆",
|
||||
icon: "noto:trophy",
|
||||
rarity: "bronze",
|
||||
hidden: false,
|
||||
metric: "",
|
||||
@@ -99,7 +100,22 @@ async function save() {
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item label="图标">
|
||||
<n-input v-model:value="form.icon" placeholder="emoji,例如 🦉" />
|
||||
<n-flex vertical :size="4" style="flex: 1">
|
||||
<n-flex align="center" :size="10">
|
||||
<n-input
|
||||
v-model:value="form.icon"
|
||||
placeholder="iconify 图标名,例如 noto:owl"
|
||||
/>
|
||||
<div class="icon-preview">
|
||||
<AchievementIcon :icon="form.icon" :size="28" />
|
||||
</div>
|
||||
</n-flex>
|
||||
<n-text depth="3" style="font-size: 12px">
|
||||
填 iconify 图标名(推荐 noto: 开头的彩色 emoji 图标),右侧是实时
|
||||
预览;预览不出来说明名字写错了。图标名可在 icon-sets.iconify.design
|
||||
搜索。
|
||||
</n-text>
|
||||
</n-flex>
|
||||
</n-form-item>
|
||||
<n-form-item label="稀有度">
|
||||
<n-select
|
||||
@@ -158,3 +174,14 @@ async function save() {
|
||||
</template>
|
||||
</n-modal>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.icon-preview {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 40px;
|
||||
height: 34px;
|
||||
flex: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
getAdminAchievements,
|
||||
type AdminAchievement,
|
||||
} from "admin/api"
|
||||
import AchievementIcon from "shared/components/AchievementIcon.vue"
|
||||
import AchievementModal from "./components/AchievementModal.vue"
|
||||
|
||||
const message = useMessage()
|
||||
@@ -57,7 +58,12 @@ function remove(row: AdminAchievement) {
|
||||
}
|
||||
|
||||
const columns: DataTableColumn<AdminAchievement>[] = [
|
||||
{ title: "图标", key: "icon", width: 60 },
|
||||
{
|
||||
title: "图标",
|
||||
key: "icon",
|
||||
width: 60,
|
||||
render: (row) => h(AchievementIcon, { icon: row.icon, size: 24 }),
|
||||
},
|
||||
{ title: "名称", key: "name" },
|
||||
{
|
||||
title: "稀有度",
|
||||
|
||||
Reference in New Issue
Block a user