283 lines
5.3 KiB
Vue
283 lines
5.3 KiB
Vue
<template>
|
|
<div
|
|
class="prompt-card-horizontal"
|
|
draggable="true"
|
|
@dragstart="onDragStart"
|
|
@click="handleClick"
|
|
>
|
|
<!-- 左侧图片 -->
|
|
<div v-if="prompt.referenceImage" class="card-image">
|
|
<img :src="prompt.referenceImage" :alt="prompt.title" />
|
|
</div>
|
|
|
|
<!-- 右侧内容 -->
|
|
<div class="card-content">
|
|
<div class="card-header">
|
|
<h4 class="card-title">{{ prompt.title }}</h4>
|
|
<el-tag :type="typeTagType" size="small">{{ getTypeLabel(prompt.type) }}</el-tag>
|
|
</div>
|
|
<div class="card-body">
|
|
<p class="card-description">{{ prompt.content }}</p>
|
|
</div>
|
|
<div class="card-footer">
|
|
<el-button
|
|
text
|
|
size="small"
|
|
@click.stop="$emit('edit', prompt)"
|
|
class="action-btn edit"
|
|
>
|
|
<el-icon><EditPen /></el-icon>
|
|
{{ t('common.edit') }}
|
|
</el-button>
|
|
<el-button
|
|
text
|
|
size="small"
|
|
@click.stop="handleDelete"
|
|
class="action-btn delete"
|
|
>
|
|
<el-icon><Delete /></el-icon>
|
|
{{ t('common.delete') }}
|
|
</el-button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 生效标识 -->
|
|
<div class="active-badge">
|
|
<el-icon><Check /></el-icon>
|
|
{{ t('admin.promptManagement.active') }}
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { computed } from 'vue'
|
|
import { useI18n } from 'vue-i18n'
|
|
import { EditPen, Delete, Check } from '@element-plus/icons-vue'
|
|
|
|
const { t } = useI18n()
|
|
|
|
// 组件属性
|
|
const props = defineProps({
|
|
prompt: {
|
|
type: Object,
|
|
required: true,
|
|
default: () => ({
|
|
id: '',
|
|
title: '',
|
|
content: '',
|
|
type: '',
|
|
referenceImage: '',
|
|
isActive: false
|
|
})
|
|
},
|
|
isActive: {
|
|
type: Boolean,
|
|
default: false
|
|
}
|
|
})
|
|
|
|
// 事件定义
|
|
const emit = defineEmits(['edit', 'delete', 'drag-start', 'click'])
|
|
|
|
// 根据类型获取标签类型
|
|
const typeTagType = computed(() => {
|
|
const typeMap = {
|
|
animal: 'success',
|
|
person: 'warning',
|
|
general: 'info'
|
|
}
|
|
return typeMap[props.prompt.type] || 'info'
|
|
})
|
|
|
|
// 获取类型标签
|
|
const getTypeLabel = (type) => {
|
|
const typeMap = {
|
|
animal: t('admin.promptManagement.animal'),
|
|
person: t('admin.promptManagement.person'),
|
|
general: t('admin.promptManagement.general')
|
|
}
|
|
return typeMap[type] || type
|
|
}
|
|
|
|
// 拖拽开始事件
|
|
const onDragStart = (event) => {
|
|
event.dataTransfer.effectAllowed = 'move'
|
|
emit('drag-start', props.prompt)
|
|
}
|
|
|
|
// 点击卡片事件
|
|
const handleClick = () => {
|
|
emit('click', props.prompt)
|
|
}
|
|
|
|
// 删除提示词事件
|
|
const handleDelete = () => {
|
|
emit('delete', props.prompt.id)
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.prompt-card-horizontal {
|
|
background: white;
|
|
border: 1px solid #e5e7eb;
|
|
border-radius: 12px;
|
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
|
overflow: hidden;
|
|
cursor: pointer;
|
|
transition: all 0.2s ease;
|
|
position: relative;
|
|
display: flex;
|
|
min-height: 120px;
|
|
}
|
|
|
|
.prompt-card-horizontal:hover {
|
|
transform: translateY(-2px);
|
|
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1);
|
|
border-color: #a78bfa;
|
|
}
|
|
|
|
/* 左侧图片 */
|
|
.card-image {
|
|
width: 120px;
|
|
flex-shrink: 0;
|
|
overflow: hidden;
|
|
background: #f9fafb;
|
|
min-height: 100%;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.card-image img {
|
|
width: 100%;
|
|
height: 100%;
|
|
object-fit: cover;
|
|
transition: transform 0.3s ease;
|
|
display: block;
|
|
}
|
|
|
|
.prompt-card-horizontal:hover .card-image img {
|
|
transform: scale(1.05);
|
|
}
|
|
|
|
/* 右侧内容 */
|
|
.card-content {
|
|
flex: 1;
|
|
padding: 16px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 8px;
|
|
min-width: 0;
|
|
}
|
|
|
|
/* 卡片头部 */
|
|
.card-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: flex-start;
|
|
gap: 8px;
|
|
}
|
|
|
|
.card-title {
|
|
font-size: 16px;
|
|
font-weight: 600;
|
|
color: #374151;
|
|
margin: 0;
|
|
line-height: 1.4;
|
|
display: -webkit-box;
|
|
-webkit-line-clamp: 1;
|
|
-webkit-box-orient: vertical;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
}
|
|
|
|
/* 卡片内容 */
|
|
.card-body {
|
|
flex: 1;
|
|
overflow: hidden;
|
|
min-height: 0;
|
|
}
|
|
|
|
.card-description {
|
|
font-size: 14px;
|
|
color: #6b7280;
|
|
margin: 0;
|
|
line-height: 1.5;
|
|
display: -webkit-box;
|
|
-webkit-line-clamp: 3;
|
|
-webkit-box-orient: vertical;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
}
|
|
|
|
/* 卡片底部 */
|
|
.card-footer {
|
|
display: flex;
|
|
gap: 8px;
|
|
justify-content: flex-end;
|
|
margin-top: auto;
|
|
}
|
|
|
|
.action-btn {
|
|
padding: 0;
|
|
font-size: 14px;
|
|
transition: color 0.2s ease;
|
|
}
|
|
|
|
.action-btn.edit:hover {
|
|
color: #6b7280;
|
|
}
|
|
|
|
.action-btn.delete:hover {
|
|
color: #ef4444;
|
|
}
|
|
|
|
/* 生效标识 */
|
|
.active-badge {
|
|
position: absolute;
|
|
top: 8px;
|
|
right: 8px;
|
|
background: #10b981;
|
|
color: white;
|
|
font-size: 12px;
|
|
padding: 4px 8px;
|
|
border-radius: 12px;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 4px;
|
|
font-weight: 500;
|
|
z-index: 1;
|
|
}
|
|
|
|
.active-badge .el-icon {
|
|
font-size: 10px;
|
|
}
|
|
|
|
/* 无图片的卡片 */
|
|
.prompt-card-horizontal:not(:has(.card-image)) {
|
|
min-height: 100px;
|
|
}
|
|
|
|
.prompt-card-horizontal:not(:has(.card-image)) .card-content {
|
|
padding: 16px;
|
|
}
|
|
|
|
/* 响应式设计 */
|
|
@media (max-width: 768px) {
|
|
.prompt-card-horizontal {
|
|
flex-direction: column;
|
|
}
|
|
|
|
.card-image {
|
|
width: 100%;
|
|
height: 120px;
|
|
}
|
|
|
|
.card-header {
|
|
flex-direction: column;
|
|
align-items: flex-start;
|
|
gap: 4px;
|
|
}
|
|
}
|
|
</style>
|