feat: add community tag icons

This commit is contained in:
hajimi
2026-08-02 02:14:40 +08:00
parent 73f1c2ceba
commit a6531a3ab1
4 changed files with 39 additions and 2 deletions
+17 -1
View File
@@ -33,6 +33,12 @@
<el-table size="large" v-loading="pager.loading" :data="pager.lists">
<el-table-column label="ID" prop="id" min-width="60" />
<el-table-column label="标签名称" prop="name" min-width="120" />
<el-table-column label="图标" min-width="80">
<template #default="{ row }">
<el-avatar v-if="row.icon" :src="row.icon" :size="36" shape="square" />
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="帖子数" prop="post_count" min-width="80" />
<el-table-column label="排序" prop="sort" min-width="80" />
<el-table-column label="热门" min-width="80">
@@ -83,6 +89,14 @@
<el-form-item label="标签名称" prop="name">
<el-input v-model="editData.name" placeholder="请输入标签名称" />
</el-form-item>
<el-form-item label="标签图标" prop="icon">
<div>
<material-picker v-model="editData.icon" :limit="1" size="80px" />
<div class="form-tips">
建议上传正方形图标未上传时用户端显示默认图标
</div>
</div>
</el-form-item>
<el-form-item label="排序" prop="sort">
<el-input-number v-model="editData.sort" :min="0" :max="9999" />
</el-form-item>
@@ -125,6 +139,7 @@ const editFormRef = ref<FormInstance>()
const editData = reactive({
id: 0,
name: '',
icon: '',
sort: 0,
is_hot: 0,
status: 1
@@ -135,7 +150,7 @@ const editRules = {
}
const handleAdd = () => {
Object.assign(editData, { id: 0, name: '', sort: 0, is_hot: 0, status: 1 })
Object.assign(editData, { id: 0, name: '', icon: '', sort: 0, is_hot: 0, status: 1 })
showEdit.value = true
}
@@ -143,6 +158,7 @@ const handleEdit = (row: any) => {
Object.assign(editData, {
id: row.id,
name: row.name,
icon: row.icon || '',
sort: row.sort,
is_hot: row.is_hot,
status: row.status
@@ -10,12 +10,14 @@ class CommunityTagValidate extends BaseValidate
protected $rule = [
'id' => 'require|checkTag',
'name' => 'require|length:1,50',
'icon' => 'max:500',
];
protected $message = [
'id.require' => '标签id不能为空',
'name.require' => '标签名称不能为空',
'name.length' => '标签名称长度须在1-50位字符',
'icon.max' => '标签图标地址不能超过500个字符',
];
public function sceneAdd()
@@ -3,8 +3,19 @@
namespace app\common\model\community;
use app\common\model\BaseModel;
use app\common\service\FileService;
class CommunityTag extends BaseModel
{
protected $name = 'community_tag';
public function getIconAttr($value): string
{
return trim((string) $value) ? FileService::getFileUrl((string) $value) : '';
}
public function setIconAttr($value): string
{
return trim((string) $value) ? FileService::setFileUrl($value) : '';
}
}
+9 -1
View File
@@ -33,7 +33,8 @@
<view class="community-topics__list">
<view v-for="tag in displayTags" :key="tag.id" class="community-topic"
:class="{ 'community-topic--active': activeTagId === tag.id }" @tap="selectTag(tag)">
<text class="community-topic__icon" :style="{ color: tag.theme.color }">{{ tag.theme.icon }}</text>
<image v-if="tag.icon" class="community-topic__icon-image" :src="tag.icon" mode="aspectFit" />
<text v-else class="community-topic__icon" :style="{ color: tag.theme.color }">{{ tag.theme.icon }}</text>
<text>{{ tag.name }}</text>
</view>
</view>
@@ -129,6 +130,7 @@ const TOPIC_THEMES = [
const displayTags = computed(() => {
return tagList.value.map((tag, index) => ({
...tag,
icon: typeof tag.icon === 'string' ? tag.icon.trim() : '',
theme: TOPIC_THEMES[index % TOPIC_THEMES.length]
}))
})
@@ -546,6 +548,12 @@ onShow(() => {
line-height: 1;
}
&__icon-image {
width: 32rpx;
height: 32rpx;
flex-shrink: 0;
}
&--active {
border-color: #1468f5;
color: #1468f5;