![]()
+
+
+
+
{
+
+
+
+
+
@@ -489,15 +523,22 @@ watch(isDialogVisible, async (newValue) => {
.activity-item {
position: relative;
- padding: 0;
+ padding: 16px;
background: #fff;
border-radius: 16px;
- overflow: hidden;
+ overflow: visible;
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
border: 2px solid transparent;
background-clip: padding-box;
+ // 清除浮动,确保父容器高度正确
+ &::after {
+ content: '';
+ display: table;
+ clear: both;
+ }
+
&::before {
content: '';
position: absolute;
@@ -525,9 +566,8 @@ watch(isDialogVisible, async (newValue) => {
opacity: 1;
}
- .activity-image {
- transform: scale(1.1);
- filter: brightness(1.05);
+ .activity-image-wrapper {
+ box-shadow: 0 8px 24px rgba(102, 126, 234, 0.2);
}
.detail-link {
@@ -545,10 +585,31 @@ watch(isDialogVisible, async (newValue) => {
.activity-image-wrapper {
position: relative;
- width: 100%;
- height: 220px;
+ float: right;
+ width: 160px;
+ height: 160px;
+ margin-left: 16px;
+ margin-bottom: 8px;
+ border-radius: 12px;
overflow: hidden;
background: linear-gradient(135deg, #667eea15 0%, #764ba215 100%);
+ shape-outside: inset(0);
+ transition: box-shadow 0.3s;
+ cursor: pointer;
+ z-index: 1; // 确保在内容之上
+
+ &:hover {
+ box-shadow: 0 4px 16px rgba(102, 126, 234, 0.3);
+ }
+
+ &:hover .activity-image {
+ transform: scale(1.1);
+ }
+
+ &:hover .zoom-icon {
+ opacity: 1;
+ transform: translate(-50%, -50%) scale(1);
+ }
&::before {
content: '';
@@ -560,6 +621,7 @@ watch(isDialogVisible, async (newValue) => {
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent);
z-index: 1;
animation: shine 3s infinite;
+ pointer-events: none; // 确保不拦截鼠标事件
}
&::after {
@@ -587,22 +649,22 @@ watch(isDialogVisible, async (newValue) => {
.activity-image {
width: 100%;
height: 100%;
- object-fit: cover;
+ object-fit: contain; // 等比例缩放,完整显示图片,不裁剪
transition: all 0.6s cubic-bezier(0.4, 0, 0.2, 1);
}
.activity-status-badge {
position: absolute;
- top: 16px;
- right: 16px;
+ top: 12px;
+ right: 12px;
z-index: 2;
animation: fadeInScale 0.5s ease-out 0.3s both;
:deep(.el-tag) {
- border-radius: 20px;
- padding: 7px 18px;
+ border-radius: 16px;
+ padding: 5px 14px;
font-weight: 700;
- font-size: 13px;
+ font-size: 11px;
border: none;
backdrop-filter: blur(12px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
@@ -648,24 +710,52 @@ watch(isDialogVisible, async (newValue) => {
}
}
+ .zoom-icon {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%) scale(0.8);
+ width: 48px;
+ height: 48px;
+ background: rgba(0, 0, 0, 0.6);
+ backdrop-filter: blur(8px);
+ border-radius: 50%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ opacity: 0;
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
+ pointer-events: none; // 不拦截鼠标事件,让父容器接收hover
+ z-index: 10; // 提高层级,确保在状态标签之上
+
+ svg {
+ width: 24px;
+ height: 24px;
+ color: #fff;
+ stroke-width: 2;
+ }
+ }
+
.activity-body {
- padding: 20px;
+ // 内容会自动环绕浮动的图片
+ position: relative;
+ z-index: 0; // 确保在浮动图片之下
}
.activity-header {
display: flex;
align-items: center;
gap: 12px;
- margin-bottom: 12px;
+ margin-bottom: 8px;
}
.activity-title {
margin: 0;
- font-size: 18px;
+ font-size: 16px;
font-weight: 700;
color: #1a1a1a;
flex: 1;
- line-height: 1.4;
+ line-height: 1.3;
background: linear-gradient(135deg, #1a1a1a 0%, #4a5568 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
@@ -679,23 +769,23 @@ watch(isDialogVisible, async (newValue) => {
.activity-content-list {
padding: 0;
- margin: 0 0 16px 0;
+ margin: 0 0 12px 0;
color: #4a5568;
- font-size: 14px;
- line-height: 1.8;
+ font-size: 13px;
+ line-height: 1.6;
.content-line {
- margin: 8px 0;
- padding-left: 18px;
+ margin: 6px 0;
+ padding-left: 16px;
position: relative;
&::before {
content: '';
position: absolute;
left: 0;
- top: 11px;
- width: 6px;
- height: 6px;
+ top: 9px;
+ width: 5px;
+ height: 5px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border-radius: 50%;
}
@@ -715,8 +805,9 @@ watch(isDialogVisible, async (newValue) => {
justify-content: space-between;
align-items: center;
gap: 16px;
- padding-top: 16px;
+ padding-top: 12px;
border-top: 1px dashed #e8e9eb;
+ clear: both; // 清除浮动,始终在新行显示,占满100%宽度
}
.activity-time-range {
@@ -727,7 +818,7 @@ watch(isDialogVisible, async (newValue) => {
}
.activity-time {
- font-size: 13px;
+ font-size: 12px;
color: #718096;
display: flex;
align-items: center;
@@ -735,19 +826,19 @@ watch(isDialogVisible, async (newValue) => {
&:first-child::before {
content: '🕐';
- font-size: 14px;
+ font-size: 13px;
}
}
.detail-link {
display: inline-flex;
align-items: center;
- gap: 8px;
- padding: 10px 18px;
+ gap: 6px;
+ padding: 8px 16px;
background: linear-gradient(135deg, #f0f1f3 0%, #e8eaed 100%);
color: #667eea;
- border-radius: 24px;
- font-size: 13px;
+ border-radius: 20px;
+ font-size: 12px;
font-weight: 700;
text-decoration: none;
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
@@ -1095,16 +1186,27 @@ watch(isDialogVisible, async (newValue) => {
.activity-item {
border-radius: 10px;
- }
-
- .activity-image-wrapper {
- height: 180px;
+ padding: 0;
}
.activity-body {
padding: 16px;
}
+ .activity-image-wrapper {
+ float: none;
+ width: 100%;
+ height: 180px;
+ min-height: 180px;
+ margin: 0 0 16px 0;
+ border-radius: 10px 10px 0 0;
+ }
+
+ .activity-status-badge {
+ top: 12px;
+ right: 12px;
+ }
+
.activity-header {
margin-bottom: 10px;
}
@@ -1183,7 +1285,18 @@ watch(isDialogVisible, async (newValue) => {
.activity-content {
.activity-image-wrapper {
+ float: none;
+ width: 100%;
height: 200px;
+ margin: 0 0 16px 0;
+ }
+
+ .activity-item {
+ padding: 0;
+ }
+
+ .activity-body {
+ padding: 18px;
}
}
diff --git a/Yi.Ai.Vue3/src/pages/chat/image/components/ImageGenerator.vue b/Yi.Ai.Vue3/src/pages/chat/image/components/ImageGenerator.vue
index 5e328ee7..2da2ecfa 100644
--- a/Yi.Ai.Vue3/src/pages/chat/image/components/ImageGenerator.vue
+++ b/Yi.Ai.Vue3/src/pages/chat/image/components/ImageGenerator.vue
@@ -46,6 +46,8 @@ const generating = ref(false);
const currentTaskId = ref('');
const currentTask = ref
(null);
const showViewer = ref(false);
+const referenceImageViewerVisible = ref(false);
+const referenceImagePreviewUrl = ref('');
let pollTimer: any = null;
let debounceTimer: any = null;
@@ -130,6 +132,17 @@ function handleRemove(file: UploadFile) {
fileList.value.splice(index, 1);
}
+function handlePreview(file: UploadFile) {
+ if (file.url) {
+ referenceImagePreviewUrl.value = file.url;
+ referenceImageViewerVisible.value = true;
+ }
+}
+
+function closeReferenceImageViewer() {
+ referenceImageViewerVisible.value = false;
+}
+
// Handle paste event for reference images
function handlePaste(event: ClipboardEvent) {
const items = event.clipboardData?.items;
@@ -510,6 +523,7 @@ onUnmounted(() => {
:limit="2"
:on-change="handleFileChange"
:on-remove="handleRemove"
+ :on-preview="handlePreview"
accept=".jpg,.jpeg,.png,.bmp,.webp"
:class="{ 'hide-upload-btn': fileList.length >= 2 }"
>
@@ -644,6 +658,15 @@ onUnmounted(() => {