Commit 488d1643 by lijiabin

【需求 21133】 feat: 加入YAYA表情包

parent 7c1cf367
<script setup lang="ts">
import { computed, ref } from 'vue'
import emojis from '@/utils/emoji/face.json'
import yayas from '@/utils/emoji/yaya.json'
import type { IEmoji } from '@/utils/emoji/type'
const emit = defineEmits<{
selectEmoji: [emoji: IEmoji]
}>()
type EmojiTab = 'face' | 'yaya'
const activeTab = ref<EmojiTab>('face')
const emojiTabs: Array<{
key: EmojiTab
label: string
list: Array<Pick<IEmoji, 'name' | 'url' | 'group'>>
}> = [
{
key: 'face',
label: '默认表情',
list: emojis,
},
{
key: 'yaya',
label: 'YAYA表情',
list: yayas,
},
]
const currentEmojiList = computed(() => {
return emojiTabs.find((tab) => tab.key === activeTab.value)?.list ?? []
})
</script>
<template>
<div
class="w-8 h-8 text-gray-500 hover:bg-gray-100 hover:text-gray-700 rounded-lg flex items-center justify-center"
class="flex h-8 w-8 items-center justify-center rounded-lg text-gray-500 transition-all hover:bg-orange-50 hover:text-orange-500"
>
<el-popover placement="bottom" trigger="click" width="384">
<el-popover placement="bottom" trigger="click" :width="384" popper-class="emoji-popover">
<template #reference>
<el-icon size="20" @mousedown.prevent>
<svg-icon name="icon_face" class="cursor-pointer"
/></el-icon>
<svg-icon name="icon_face" class="cursor-pointer" />
</el-icon>
</template>
<!-- 表情面板 -->
<el-scrollbar class="h-50">
<div class="flex flex-wrap">
<span
v-for="item in emojis"
:key="item.name"
class="cursor-pointer hover:bg-gray-100 rounded p-1 flex items-center justify-center"
@click="emit('selectEmoji', item)"
<div class="emoji-panel">
<div class="emoji-tabs">
<button
v-for="tab in emojiTabs"
:key="tab.key"
type="button"
class="emoji-tab"
:class="{ 'emoji-tab--active': activeTab === tab.key }"
@click="activeTab = tab.key"
>
<img :src="item.url" alt="" class="w-6 h-6" />
</span>
{{ tab.label }}
</button>
</div>
</el-scrollbar>
<el-scrollbar class="emoji-scrollbar">
<div class="emoji-grid">
<button
v-for="item in currentEmojiList"
:key="item.name"
type="button"
class="emoji-item"
:title="item.name"
@click="emit('selectEmoji', item as IEmoji)"
>
<img
:src="item.url"
:alt="item.name"
class="h-6 w-6 object-contain"
:class="{ 'h-8 w-8': item.group === 'yaya' }"
/>
</button>
</div>
</el-scrollbar>
</div>
</el-popover>
</div>
</template>
<style scoped></style>
<style scoped>
.emoji-tabs {
display: flex;
align-items: center;
gap: 16px;
margin-bottom: 8px;
padding: 0 6px 8px;
border-bottom: 1px solid #f5f5f5;
}
.emoji-tab {
position: relative;
border: 0;
background: transparent;
color: #9ca3af;
border-radius: 0;
font-size: 12px;
font-weight: 500;
cursor: pointer;
transition:
color 0.18s ease,
transform 0.18s ease;
}
.emoji-tab:hover {
color: #f97316;
}
.emoji-tab--active {
color: #ea580c;
transform: none;
}
.emoji-tab--active::after {
content: '';
position: absolute;
left: 0;
bottom: -9px;
width: 100%;
height: 2px;
border-radius: 999px;
background: linear-gradient(90deg, #fb923c 0%, #f97316 100%);
}
.emoji-scrollbar {
height: 188px;
}
.emoji-grid {
display: grid;
grid-template-columns: repeat(8, minmax(0, 1fr));
gap: 6px;
padding: 2px 4px 10px;
}
.emoji-item {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 34px;
border: 0;
border-radius: 10px;
background: #fff;
cursor: pointer;
transition:
transform 0.18s ease,
background-color 0.18s ease,
box-shadow 0.18s ease;
}
.emoji-item:hover {
background: linear-gradient(180deg, #fff7ed 0%, #ffedd5 100%);
box-shadow: 0 6px 14px rgb(251 146 60 / 16%);
transform: translateY(-1px);
}
</style>
import emojis from './face.json'
import yayas from './yaya.json'
type EmojiAsset = {
name: string
url: string
group: string
}
const emojiList: EmojiAsset[] = [...emojis, ...yayas]
function escapeHTML(str: string) {
return str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')
......@@ -9,18 +18,19 @@ export const parseEmoji = (content: string) => {
let html = escapeHTML(content)
emojis.forEach((item) => {
emojiList.forEach((item) => {
const escapedName = item.name.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
const reg = new RegExp(escapedName, 'g')
console.log(item.group)
html = html.replace(
reg,
`<img
src="${item.url}"
alt="${item.name}"
class="${item.className || 'emoji_small'} inline-block align-text-bottom w-6 h-6"
/>`,
class="${item.group === 'yaya' ? 'w-8 h-8' : 'w-6 h-6'}"
/>`,
)
})
......
[
{
"name": "[YAYA_OK]",
"url": "https://soundasia.oss-cn-shenzhen.aliyuncs.com/OA/png/2026/03/30/Common/1774842153149.png",
"group": "yaya"
},
{
"name": "[YAYA_OK1]",
"url": "https://soundasia.oss-cn-shenzhen.aliyuncs.com/OA/png/2026/03/30/Common/1774842183051.png",
"group": "yaya"
},
{
"name": "[YAYA_OKK]",
"url": "https://soundasia.oss-cn-shenzhen.aliyuncs.com/OA/png/2026/03/30/Common/1774842204358.png",
"group": "yaya"
},
{
"name": "[YAYA_拜托]",
"url": "https://soundasia.oss-cn-shenzhen.aliyuncs.com/OA/png/2026/03/30/Common/1774842337245.png",
"group": "yaya"
},
{
"name": "[YAYA_点赞]",
"url": "https://soundasia.oss-cn-shenzhen.aliyuncs.com/OA/png/2026/03/30/Common/1774842370496.png",
"group": "yaya"
},
{
"name": "[YAYA_非常感谢]",
"url": "https://soundasia.oss-cn-shenzhen.aliyuncs.com/OA/png/2026/03/30/Common/1774842403468.png",
"group": "yaya"
},
{
"name": "[YAYA_恭喜]",
"url": "https://soundasia.oss-cn-shenzhen.aliyuncs.com/OA/png/2026/03/30/Common/1774842433720.png",
"group": "yaya"
},
{
"name": "[YAYA_恭喜1]",
"url": "https://soundasia.oss-cn-shenzhen.aliyuncs.com/OA/png/2026/03/30/Common/1774842456906.png",
"group": "yaya"
},
{
"name": "[YAYA_好滴]",
"url": "https://soundasia.oss-cn-shenzhen.aliyuncs.com/OA/png/2026/03/30/Common/1774842482423.png",
"group": "yaya"
},
{
"name": "[YAYA_加油]",
"url": "https://soundasia.oss-cn-shenzhen.aliyuncs.com/OA/png/2026/03/30/Common/1774842512339.png",
"group": "yaya"
},
{
"name": "[YAYA_焦急]",
"url": "https://soundasia.oss-cn-shenzhen.aliyuncs.com/OA/png/2026/03/30/Common/1774842540763.png",
"group": "yaya"
},
{
"name": "[YAYA_开心]",
"url": "https://soundasia.oss-cn-shenzhen.aliyuncs.com/OA/png/2026/03/30/Common/1774842564724.png",
"group": "yaya"
},
{
"name": "[YAYA_哭泣]",
"url": "https://soundasia.oss-cn-shenzhen.aliyuncs.com/OA/png/2026/03/30/Common/1774842593525.png",
"group": "yaya"
},
{
"name": "[YAYA_努力]",
"url": "https://soundasia.oss-cn-shenzhen.aliyuncs.com/OA/png/2026/03/30/Common/1774842629597.png",
"group": "yaya"
},
{
"name": "[YAYA_谢谢]",
"url": "https://soundasia.oss-cn-shenzhen.aliyuncs.com/OA/png/2026/03/30/Common/1774842649971.png",
"group": "yaya"
},
{
"name": "[YAYA_亚声人]",
"url": "https://soundasia.oss-cn-shenzhen.aliyuncs.com/OA/png/2026/03/30/Common/1774842693166.png",
"group": "yaya"
}
]
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment