|
|
@@ -1,36 +1,37 @@
|
|
|
<template>
|
|
|
- <div class="flash-sale-container">
|
|
|
- <el-card shadow="hover">
|
|
|
- <!-- 标题区域(可点击编辑) -->
|
|
|
- <div class="section-header" @click="handleEditHeader">
|
|
|
+ <div class="flash-sale-page">
|
|
|
+ <div class="flash-sale-container">
|
|
|
+ <!-- 标题区域(独立卡片) -->
|
|
|
+ <div class="section-header-card" @click="handleEditHeader">
|
|
|
<div class="header-left">
|
|
|
- <h2 class="section-title">{{ headerConfig.title }}</h2>
|
|
|
+ <span class="section-title">{{ headerConfig.title }}</span>
|
|
|
<span class="section-subtitle">{{ headerConfig.subtitle }}</span>
|
|
|
</div>
|
|
|
<div class="header-right">
|
|
|
- <el-link type="primary" :underline="false" @click.stop="handleLinkClick">{{ headerConfig.linkText }}></el-link>
|
|
|
+ <span class="more-link" @click.stop="handleLinkClick">{{ headerConfig.linkText }} ></span>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
- <!-- 品牌展示区域 -->
|
|
|
- <div class="brand-showcase">
|
|
|
+ <!-- 品牌展示区域(独立卡片) -->
|
|
|
+ <div class="brand-showcase-card">
|
|
|
<!-- 左侧大图(可点击编辑) -->
|
|
|
- <div class="showcase-left">
|
|
|
- <el-image :src="bannerConfig.imageUrl || 'https://via.placeholder.com/300x400/1a1a2e/FFFFFF?text=Featured'" fit="cover" class="featured-image">
|
|
|
+ <div class="showcase-left" @click="handleEditBanner">
|
|
|
+ <el-image :src="bannerConfig.imageUrl || defaultBannerUrl" fit="cover" class="featured-image">
|
|
|
<template #error>
|
|
|
<div class="image-slot"><el-icon><Picture /></el-icon></div>
|
|
|
</template>
|
|
|
</el-image>
|
|
|
- <div class="edit-overlay" @click="handleEditBanner">
|
|
|
- <span>点击编辑</span>
|
|
|
- </div>
|
|
|
- <el-button type="warning" class="view-all-btn" @click.stop="handleViewAll">查看全部></el-button>
|
|
|
+ <el-button type="warning" size="small" class="view-all-btn" @click.stop="handleViewAll">查看全部 ></el-button>
|
|
|
</div>
|
|
|
|
|
|
<!-- 右侧品牌网格 -->
|
|
|
<div class="showcase-right">
|
|
|
- <div v-for="item in brandList" :key="item.id" class="brand-item">
|
|
|
- <el-icon class="close-icon" @click="handleRemove(item)"><Close /></el-icon>
|
|
|
+ <div v-for="(item, index) in brandList" :key="item.id" class="brand-item">
|
|
|
+ <el-icon class="close-icon" @click.stop="handleRemoveBrand(index)"><CircleClose /></el-icon>
|
|
|
+ <div class="sort-icon" @click.stop="handleSort(index)">
|
|
|
+ <span class="arrow-down">↓</span>
|
|
|
+ <span class="arrow-up">↑</span>
|
|
|
+ </div>
|
|
|
<div class="brand-logo">
|
|
|
<el-image :src="item.logoUrl" fit="contain" class="logo-image">
|
|
|
<template #error>
|
|
|
@@ -46,27 +47,27 @@
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
- <!-- 搜索区域 -->
|
|
|
- <div class="search-section">
|
|
|
- <h3 class="search-title">品牌闪购搜索列表</h3>
|
|
|
+ <!-- 搜索区域(独立卡片) -->
|
|
|
+ <div class="search-section-card">
|
|
|
+ <div class="search-title">品牌闪购搜索列表</div>
|
|
|
<div class="search-bar">
|
|
|
- <el-input v-model="searchKeyword" placeholder="请输入品牌编号或名称" clearable style="width: 300px" @keyup.enter="handleSearch" />
|
|
|
+ <el-input v-model="searchKeyword" placeholder="请输入品牌编号或名称" clearable style="width: 280px" />
|
|
|
<el-button type="primary" @click="handleSearch">搜索</el-button>
|
|
|
</div>
|
|
|
</div>
|
|
|
- </el-card>
|
|
|
+ </div>
|
|
|
|
|
|
<!-- 编辑标题对话框 -->
|
|
|
<el-dialog v-model="headerDialog.visible" title="编辑标题" width="600px" append-to-body>
|
|
|
<el-form :model="headerForm" label-width="100px">
|
|
|
<el-row :gutter="20">
|
|
|
<el-col :span="12">
|
|
|
- <el-form-item label="标题名称" required>
|
|
|
+ <el-form-item label="标题名称">
|
|
|
<el-input v-model="headerForm.title" placeholder="请输入标题名称" />
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
|
<el-col :span="12">
|
|
|
- <el-form-item label="副标题" required>
|
|
|
+ <el-form-item label="副标题">
|
|
|
<el-input v-model="headerForm.subtitle" placeholder="请输入副标题" />
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
|
@@ -83,18 +84,6 @@
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
|
</el-row>
|
|
|
- <el-row :gutter="20">
|
|
|
- <el-col :span="12">
|
|
|
- <el-form-item label="背景色">
|
|
|
- <el-color-picker v-model="headerForm.bgColor" />
|
|
|
- </el-form-item>
|
|
|
- </el-col>
|
|
|
- <el-col :span="12">
|
|
|
- <el-form-item label="字体颜色">
|
|
|
- <el-color-picker v-model="headerForm.textColor" />
|
|
|
- </el-form-item>
|
|
|
- </el-col>
|
|
|
- </el-row>
|
|
|
</el-form>
|
|
|
<template #footer>
|
|
|
<el-button type="primary" @click="saveHeaderConfig">确 认</el-button>
|
|
|
@@ -105,381 +94,303 @@
|
|
|
<!-- 编辑左侧大图对话框 -->
|
|
|
<el-dialog v-model="bannerDialog.visible" title="编辑品牌广告" width="500px" append-to-body>
|
|
|
<el-form :model="bannerForm" label-width="80px">
|
|
|
- <el-form-item label="链接">
|
|
|
- <el-input v-model="bannerForm.link" placeholder="请输入跳转链接" />
|
|
|
- </el-form-item>
|
|
|
<el-form-item label="图片">
|
|
|
<image-upload v-model="bannerForm.imageUrl" :limit="1" />
|
|
|
</el-form-item>
|
|
|
+ <el-form-item label="链接">
|
|
|
+ <el-input v-model="bannerForm.link" placeholder="请输入跳转链接" />
|
|
|
+ </el-form-item>
|
|
|
</el-form>
|
|
|
<template #footer>
|
|
|
<el-button type="primary" @click="saveBannerConfig">确 认</el-button>
|
|
|
<el-button @click="bannerDialog.visible = false">取 消</el-button>
|
|
|
</template>
|
|
|
</el-dialog>
|
|
|
+
|
|
|
+ <!-- 排序对话框 -->
|
|
|
+ <el-dialog v-model="sortDialog.visible" title="排序商品" width="400px" append-to-body>
|
|
|
+ <el-form label-width="60px">
|
|
|
+ <el-form-item label="排序">
|
|
|
+ <el-input-number v-model="sortDialog.sortValue" :min="0" controls-position="right" style="width: 200px" />
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ <template #footer>
|
|
|
+ <el-button type="primary" @click="saveSortConfig">确 认</el-button>
|
|
|
+ <el-button @click="sortDialog.visible = false">取 消</el-button>
|
|
|
+ </template>
|
|
|
+ </el-dialog>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script setup name="FlashSale" lang="ts">
|
|
|
import { ref, reactive, onMounted } from 'vue';
|
|
|
import { ElMessage } from 'element-plus';
|
|
|
-import { Picture, Close } from '@element-plus/icons-vue';
|
|
|
+import { Picture, CircleClose } from '@element-plus/icons-vue';
|
|
|
import { getDecorationSectionByType, addDecorationSection, updateDecorationSection } from '@/api/decoration/section';
|
|
|
import { listAdContent, addAdContent, updateAdContent } from '@/api/ad/content';
|
|
|
import { listByIds } from '@/api/system/oss';
|
|
|
|
|
|
const searchKeyword = ref('');
|
|
|
+const defaultBannerUrl = 'https://via.placeholder.com/200x300/1a237e/FFFFFF?text=品牌广告';
|
|
|
|
|
|
// 左侧大图配置
|
|
|
-const bannerConfig = ref({
|
|
|
- id: null as number | null,
|
|
|
- imageUrl: '',
|
|
|
- link: ''
|
|
|
-});
|
|
|
-
|
|
|
+const bannerConfig = ref({ id: null as number | null, imageUrl: '', imageOssId: '', link: '' });
|
|
|
const bannerDialog = reactive({ visible: false });
|
|
|
-const bannerForm = reactive({
|
|
|
- id: null as number | null,
|
|
|
- title: '品牌闪购大图',
|
|
|
- imageUrl: '',
|
|
|
- link: '',
|
|
|
- adType: 'flash_sale_banner',
|
|
|
- status: 1
|
|
|
-});
|
|
|
-
|
|
|
-// 加载左侧大图
|
|
|
+const bannerForm = reactive({ id: null as number | null, title: '品牌闪购大图', imageUrl: '', link: '', adType: 'flash_sale_banner', status: 1 });
|
|
|
+
|
|
|
const loadBannerConfig = async () => {
|
|
|
try {
|
|
|
const res = await listAdContent({ adType: 'flash_sale_banner', pageNum: 1, pageSize: 1 });
|
|
|
if (res.rows && res.rows.length > 0) {
|
|
|
const data = res.rows[0];
|
|
|
- let imageUrl = data.imageUrl || '';
|
|
|
- // 把 ossId 转换成真正的图片 URL
|
|
|
- if (imageUrl && /^\d+$/.test(imageUrl)) {
|
|
|
+ const ossId = data.imageUrl || '';
|
|
|
+ let displayUrl = ossId;
|
|
|
+ if (ossId && /^\d+$/.test(ossId)) {
|
|
|
try {
|
|
|
- const ossRes = await listByIds(imageUrl);
|
|
|
- if (ossRes.data && ossRes.data.length > 0) {
|
|
|
- imageUrl = ossRes.data[0].url;
|
|
|
- }
|
|
|
- } catch (e) {
|
|
|
- console.error('获取图片URL失败', e);
|
|
|
- }
|
|
|
+ const ossRes = await listByIds(ossId);
|
|
|
+ if (ossRes.data && ossRes.data.length > 0) displayUrl = ossRes.data[0].url;
|
|
|
+ } catch (e) { console.error('获取图片URL失败', e); }
|
|
|
}
|
|
|
- bannerConfig.value = {
|
|
|
- id: data.id,
|
|
|
- imageUrl: imageUrl,
|
|
|
- link: data.link || ''
|
|
|
- };
|
|
|
+ bannerConfig.value = { id: data.id, imageUrl: displayUrl, imageOssId: ossId, link: data.link || '' };
|
|
|
}
|
|
|
- } catch (error) {
|
|
|
- console.error('加载大图配置失败', error);
|
|
|
- }
|
|
|
+ } catch (error) { console.error('加载大图配置失败', error); }
|
|
|
};
|
|
|
|
|
|
const handleEditBanner = () => {
|
|
|
- Object.assign(bannerForm, bannerConfig.value, { adType: 'flash_sale_banner', status: 1 });
|
|
|
+ // 编辑时用ossId,这样image-upload组件才能正确回显
|
|
|
+ Object.assign(bannerForm, {
|
|
|
+ id: bannerConfig.value.id,
|
|
|
+ imageUrl: bannerConfig.value.imageOssId,
|
|
|
+ link: bannerConfig.value.link,
|
|
|
+ adType: 'flash_sale_banner',
|
|
|
+ status: 1
|
|
|
+ });
|
|
|
bannerDialog.visible = true;
|
|
|
};
|
|
|
|
|
|
const saveBannerConfig = async () => {
|
|
|
try {
|
|
|
- if (bannerForm.id) {
|
|
|
- await updateAdContent(bannerForm);
|
|
|
- } else {
|
|
|
- await addAdContent(bannerForm);
|
|
|
- }
|
|
|
+ if (bannerForm.id) await updateAdContent(bannerForm);
|
|
|
+ else await addAdContent(bannerForm);
|
|
|
await loadBannerConfig();
|
|
|
bannerDialog.visible = false;
|
|
|
- ElMessage.success('大图配置已保存');
|
|
|
- } catch (error) {
|
|
|
- ElMessage.error('保存失败');
|
|
|
- }
|
|
|
+ ElMessage.success('保存成功');
|
|
|
+ } catch (error) { ElMessage.error('保存失败'); }
|
|
|
};
|
|
|
|
|
|
// 标题配置
|
|
|
-const headerConfig = ref({
|
|
|
- id: null as number | null,
|
|
|
- title: '大牌推荐',
|
|
|
- subtitle: '甄选大牌,优质好品',
|
|
|
- linkText: '查看更多品牌信息',
|
|
|
- linkUrl: 'https://www.yoe365.com/brand',
|
|
|
- bgColor: '#ffffff',
|
|
|
- textColor: '#303133'
|
|
|
-});
|
|
|
-
|
|
|
+const headerConfig = ref({ id: null as number | null, title: '大牌推荐', subtitle: '甄选大牌,优质好品', linkText: '查看更多品牌信息', linkUrl: '' });
|
|
|
const headerDialog = reactive({ visible: false });
|
|
|
-const headerForm = reactive({
|
|
|
- id: null as number | null,
|
|
|
- title: '',
|
|
|
- subtitle: '',
|
|
|
- linkText: '',
|
|
|
- linkUrl: '',
|
|
|
- bgColor: '#ffffff',
|
|
|
- textColor: '#303133'
|
|
|
-});
|
|
|
-
|
|
|
-// 加载标题配置
|
|
|
+const headerForm = reactive({ id: null as number | null, title: '', subtitle: '', linkText: '', linkUrl: '' });
|
|
|
+
|
|
|
const loadHeaderConfig = async () => {
|
|
|
try {
|
|
|
const res = await getDecorationSectionByType('flash_sale');
|
|
|
if (res.rows && res.rows.length > 0) {
|
|
|
const data = res.rows[0];
|
|
|
- headerConfig.value = {
|
|
|
- id: data.id,
|
|
|
- title: data.title || '大牌推荐',
|
|
|
- subtitle: data.subtitle || '甄选大牌,优质好品',
|
|
|
- linkText: data.linkText || '查看更多品牌信息',
|
|
|
- linkUrl: data.linkUrl || 'https://www.yoe365.com/brand',
|
|
|
- bgColor: data.bgColor || '#ffffff',
|
|
|
- textColor: data.textColor || '#303133'
|
|
|
- };
|
|
|
+ headerConfig.value = { id: data.id, title: data.title || '大牌推荐', subtitle: data.subtitle || '甄选大牌,优质好品', linkText: data.linkText || '查看更多品牌信息', linkUrl: data.linkUrl || '' };
|
|
|
}
|
|
|
- } catch (error) {
|
|
|
- console.error('加载标题配置失败', error);
|
|
|
- }
|
|
|
+ } catch (error) { console.error('加载标题配置失败', error); }
|
|
|
};
|
|
|
|
|
|
-const handleEditHeader = () => {
|
|
|
- Object.assign(headerForm, headerConfig.value);
|
|
|
- headerDialog.visible = true;
|
|
|
-};
|
|
|
+const handleEditHeader = () => { Object.assign(headerForm, headerConfig.value); headerDialog.visible = true; };
|
|
|
|
|
|
const saveHeaderConfig = async () => {
|
|
|
try {
|
|
|
- const data = {
|
|
|
- ...headerForm,
|
|
|
- sectionType: 'flash_sale'
|
|
|
- };
|
|
|
- if (headerForm.id) {
|
|
|
- await updateDecorationSection(data);
|
|
|
- } else {
|
|
|
- await addDecorationSection(data);
|
|
|
- }
|
|
|
+ const data = { ...headerForm, sectionType: 'flash_sale' };
|
|
|
+ if (headerForm.id) await updateDecorationSection(data);
|
|
|
+ else await addDecorationSection(data);
|
|
|
await loadHeaderConfig();
|
|
|
headerDialog.visible = false;
|
|
|
- ElMessage.success('标题配置已保存');
|
|
|
- } catch (error) {
|
|
|
- ElMessage.error('保存失败');
|
|
|
- }
|
|
|
+ ElMessage.success('保存成功');
|
|
|
+ } catch (error) { ElMessage.error('保存失败'); }
|
|
|
};
|
|
|
|
|
|
-onMounted(() => {
|
|
|
- loadHeaderConfig();
|
|
|
- loadBannerConfig();
|
|
|
-});
|
|
|
-
|
|
|
+// 品牌列表(静态数据,等商品接口开发完成后再改)
|
|
|
const brandList = ref([
|
|
|
- { id: 1, title: '联想', description: '联想', logoUrl: 'https://via.placeholder.com/120x60/FFFFFF/333333?text=Lenovo' },
|
|
|
- { id: 2, title: '惠普', description: '惠普', logoUrl: 'https://via.placeholder.com/120x60/FFFFFF/333333?text=HP' },
|
|
|
- { id: 3, title: '奔图', description: '奔图', logoUrl: 'https://via.placeholder.com/120x60/FFFFFF/333333?text=PANTUM' },
|
|
|
- { id: 4, title: 'MAXHUB', description: 'MAXHUB', logoUrl: 'https://via.placeholder.com/120x60/FFFFFF/333333?text=MAXHUB' },
|
|
|
- { id: 5, title: '苹果', description: '苹果', logoUrl: 'https://via.placeholder.com/120x60/FFFFFF/333333?text=Apple' },
|
|
|
- { id: 6, title: '飞利浦', description: '飞利浦', logoUrl: 'https://via.placeholder.com/120x60/FFFFFF/333333?text=PHILIPS' },
|
|
|
- { id: 7, title: '美的', description: '美的', logoUrl: 'https://via.placeholder.com/120x60/FFFFFF/333333?text=Midea' },
|
|
|
- { id: 8, title: '格力', description: '<p><br></p>', logoUrl: 'https://via.placeholder.com/120x60/FFFFFF/333333?text=GREE' }
|
|
|
+ { id: 1, title: '联想', description: '联想', logoUrl: '/img/联想.jpg' },
|
|
|
+ { id: 2, title: '惠普', description: '惠普', logoUrl: '/img/惠普.jpg' },
|
|
|
+ { id: 3, title: '奔图', description: '奔图', logoUrl: '/img/奔图.jpg' },
|
|
|
+ { id: 4, title: 'MAXHUB', description: 'MAXHUB', logoUrl: '/img/MAXHUB.jpg' },
|
|
|
+ { id: 5, title: '飞利浦', description: '飞利浦', logoUrl: '/img/PHILIPS.jpg' },
|
|
|
+ { id: 6, title: '美的', description: '美的', logoUrl: '/img/Midea.jpg' },
|
|
|
+ { id: 7, title: '格力', description: '格力', logoUrl: '/img/格力.jpg' }
|
|
|
]);
|
|
|
|
|
|
-const handleViewAll = () => {
|
|
|
- if (bannerConfig.value.link) {
|
|
|
- window.open(bannerConfig.value.link, '_blank');
|
|
|
- } else {
|
|
|
- ElMessage.info('暂未配置跳转链接');
|
|
|
- }
|
|
|
-};
|
|
|
+const handleViewAll = () => { if (bannerConfig.value.link) window.open(bannerConfig.value.link, '_blank'); else ElMessage.info('暂未配置跳转链接'); };
|
|
|
+const handleSearch = () => { ElMessage.info(`搜索: ${searchKeyword.value || '全部'}`); };
|
|
|
+const handleLinkClick = () => { if (headerConfig.value.linkUrl) window.open(headerConfig.value.linkUrl, '_blank'); };
|
|
|
|
|
|
-const handleRemove = (item: any) => {
|
|
|
- ElMessage.success(`已移除品牌: ${item.title}`);
|
|
|
-};
|
|
|
+// 品牌操作
|
|
|
+const handleRemoveBrand = (index: number) => { brandList.value.splice(index, 1); ElMessage.success('已移除'); };
|
|
|
|
|
|
-const handleSearch = () => {
|
|
|
- ElMessage.info(`搜索: ${searchKeyword.value || '全部'}`);
|
|
|
+// 排序对话框
|
|
|
+const sortDialog = reactive({ visible: false, index: 0, sortValue: 0 });
|
|
|
+const handleSort = (index: number) => {
|
|
|
+ sortDialog.index = index;
|
|
|
+ sortDialog.sortValue = index;
|
|
|
+ sortDialog.visible = true;
|
|
|
};
|
|
|
-
|
|
|
-const handleLinkClick = () => {
|
|
|
- if (headerConfig.value.linkUrl) {
|
|
|
- window.open(headerConfig.value.linkUrl, '_blank');
|
|
|
- }
|
|
|
+const saveSortConfig = () => {
|
|
|
+ // 这里可以保存排序值到后端,目前只是前端展示
|
|
|
+ sortDialog.visible = false;
|
|
|
+ ElMessage.success('排序已保存');
|
|
|
};
|
|
|
+
|
|
|
+onMounted(() => { loadHeaderConfig(); loadBannerConfig(); });
|
|
|
</script>
|
|
|
|
|
|
+
|
|
|
<style scoped lang="scss">
|
|
|
+.flash-sale-page {
|
|
|
+ min-height: 100vh;
|
|
|
+ background: #f5f5f5;
|
|
|
+ padding: 20px;
|
|
|
+}
|
|
|
+
|
|
|
.flash-sale-container {
|
|
|
- height: 100%;
|
|
|
+ max-width: 1100px;
|
|
|
+ margin: 0 auto;
|
|
|
}
|
|
|
|
|
|
-.section-header {
|
|
|
+// 标题区域卡片
|
|
|
+.section-header-card {
|
|
|
display: flex;
|
|
|
justify-content: space-between;
|
|
|
align-items: center;
|
|
|
- margin-bottom: 20px;
|
|
|
- padding: 12px 16px;
|
|
|
- background: #f8f9fa;
|
|
|
+ padding: 15px 20px;
|
|
|
+ background: #fff;
|
|
|
border-radius: 4px;
|
|
|
+ margin-bottom: 12px;
|
|
|
cursor: pointer;
|
|
|
- transition: background 0.3s;
|
|
|
|
|
|
- &:hover {
|
|
|
- background: #ebeef5;
|
|
|
- }
|
|
|
+ &:hover { background: #fafafa; }
|
|
|
|
|
|
.header-left {
|
|
|
display: flex;
|
|
|
align-items: baseline;
|
|
|
gap: 12px;
|
|
|
|
|
|
- .section-title {
|
|
|
- margin: 0;
|
|
|
- font-size: 20px;
|
|
|
- font-weight: 600;
|
|
|
- color: #303133;
|
|
|
- }
|
|
|
- .section-subtitle {
|
|
|
- font-size: 14px;
|
|
|
- color: #909399;
|
|
|
- }
|
|
|
+ .section-title { font-size: 16px; font-weight: 600; color: #333; }
|
|
|
+ .section-subtitle { font-size: 12px; color: #999; }
|
|
|
+ }
|
|
|
+
|
|
|
+ .header-right {
|
|
|
+ .more-link { font-size: 12px; color: #666; cursor: pointer; &:hover { color: #333; } }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-.brand-showcase {
|
|
|
+// 品牌展示卡片
|
|
|
+.brand-showcase-card {
|
|
|
display: flex;
|
|
|
- gap: 16px;
|
|
|
- margin-bottom: 30px;
|
|
|
- padding: 16px;
|
|
|
- background: #f8f9fa;
|
|
|
- border-radius: 8px;
|
|
|
+ gap: 10px;
|
|
|
+ margin-bottom: 12px;
|
|
|
}
|
|
|
|
|
|
.showcase-left {
|
|
|
position: relative;
|
|
|
width: 200px;
|
|
|
flex-shrink: 0;
|
|
|
+ cursor: pointer;
|
|
|
+ background: #fff;
|
|
|
+ border-radius: 4px;
|
|
|
+ overflow: hidden;
|
|
|
|
|
|
- .featured-image {
|
|
|
- width: 100%;
|
|
|
- height: 280px;
|
|
|
- border-radius: 8px;
|
|
|
- }
|
|
|
-
|
|
|
- .edit-overlay {
|
|
|
- position: absolute;
|
|
|
- top: 0;
|
|
|
- left: 0;
|
|
|
- right: 0;
|
|
|
- bottom: 60px;
|
|
|
- background: rgba(0, 0, 0, 0.3);
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- justify-content: center;
|
|
|
- border-radius: 8px 8px 0 0;
|
|
|
- cursor: pointer;
|
|
|
- opacity: 0;
|
|
|
- transition: opacity 0.3s;
|
|
|
- color: #fff;
|
|
|
- font-size: 14px;
|
|
|
- }
|
|
|
-
|
|
|
- &:hover .edit-overlay {
|
|
|
- opacity: 1;
|
|
|
- }
|
|
|
-
|
|
|
- .view-all-btn {
|
|
|
- position: absolute;
|
|
|
- bottom: 20px;
|
|
|
- left: 50%;
|
|
|
- transform: translateX(-50%);
|
|
|
- }
|
|
|
-
|
|
|
- .image-slot {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- justify-content: center;
|
|
|
- width: 100%;
|
|
|
- height: 100%;
|
|
|
- background: #e0e0e0;
|
|
|
- color: #999;
|
|
|
- font-size: 40px;
|
|
|
- }
|
|
|
+ .featured-image { width: 100%; height: 100%; min-height: 260px; display: block; }
|
|
|
+ .image-slot { display: flex; align-items: center; justify-content: center; width: 100%; height: 260px; background: #f5f5f5; color: #999; font-size: 40px; }
|
|
|
+ .view-all-btn { position: absolute; bottom: 20px; left: 50%; transform: translateX(-50%); z-index: 10; white-space: nowrap; }
|
|
|
}
|
|
|
|
|
|
.showcase-right {
|
|
|
flex: 1;
|
|
|
display: grid;
|
|
|
- grid-template-columns: repeat(4, 1fr);
|
|
|
- gap: 12px;
|
|
|
-
|
|
|
- @media (max-width: 1200px) {
|
|
|
- grid-template-columns: repeat(3, 1fr);
|
|
|
- }
|
|
|
+ grid-template-columns: repeat(5, 1fr);
|
|
|
+ grid-template-rows: repeat(2, 1fr);
|
|
|
+ gap: 10px;
|
|
|
}
|
|
|
|
|
|
.brand-item {
|
|
|
position: relative;
|
|
|
background: #fff;
|
|
|
- border: 1px solid #e4e7ed;
|
|
|
- border-radius: 8px;
|
|
|
- padding: 16px;
|
|
|
+ padding: 20px 15px;
|
|
|
text-align: center;
|
|
|
- transition: all 0.3s;
|
|
|
+ cursor: pointer;
|
|
|
+ border-radius: 4px;
|
|
|
+ border: 1px solid #e8e8e8;
|
|
|
|
|
|
- &:hover {
|
|
|
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
|
- .close-icon { opacity: 1; }
|
|
|
+
|
|
|
+
|
|
|
+ &:hover { background: #fafafa; }
|
|
|
+
|
|
|
+ .close-icon {
|
|
|
+ position: absolute;
|
|
|
+ top: 8px;
|
|
|
+ right: 8px;
|
|
|
+ font-size: 18px;
|
|
|
+ color: #999;
|
|
|
+ cursor: pointer;
|
|
|
+ &:hover { color: #f56c6c; }
|
|
|
}
|
|
|
|
|
|
- .close-icon {
|
|
|
+ .sort-icon {
|
|
|
position: absolute;
|
|
|
- top: 8px;
|
|
|
- right: 8px;
|
|
|
- font-size: 16px;
|
|
|
- color: #909399;
|
|
|
+ top: 50%;
|
|
|
+ right: 6px;
|
|
|
+ transform: translateY(-50%);
|
|
|
cursor: pointer;
|
|
|
- opacity: 0;
|
|
|
- transition: opacity 0.3s;
|
|
|
+ display: flex;
|
|
|
+ gap: 0;
|
|
|
|
|
|
- &:hover { color: #f56c6c; }
|
|
|
+ .arrow-down, .arrow-up {
|
|
|
+ font-size: 16px;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #999;
|
|
|
+ &:hover { color: #409eff; }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
.brand-logo {
|
|
|
- height: 50px;
|
|
|
+ height: 36px;
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
justify-content: center;
|
|
|
- margin-bottom: 12px;
|
|
|
+ margin-bottom: 10px;
|
|
|
+
|
|
|
+ .logo-image {
|
|
|
+ max-height: 36px;
|
|
|
+ max-width: 90%;
|
|
|
|
|
|
- .logo-image { max-height: 100%; max-width: 100%; }
|
|
|
- .logo-text { font-size: 18px; font-weight: 600; color: #303133; }
|
|
|
+ :deep(img) {
|
|
|
+ object-fit: contain !important;
|
|
|
+ max-height: 36px;
|
|
|
+ max-width: 100%;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .logo-text { font-size: 14px; font-weight: 600; color: #333; }
|
|
|
}
|
|
|
|
|
|
.brand-info {
|
|
|
- .brand-name {
|
|
|
- margin: 0 0 4px 0;
|
|
|
- font-size: 14px;
|
|
|
- font-weight: 500;
|
|
|
- color: #303133;
|
|
|
- }
|
|
|
- .brand-desc {
|
|
|
- margin: 0;
|
|
|
- font-size: 12px;
|
|
|
- color: #909399;
|
|
|
- }
|
|
|
+ .brand-name { margin: 0 0 4px 0; font-size: 13px; font-weight: 500; color: #333; }
|
|
|
+ .brand-desc { margin: 0; font-size: 11px; color: #999; }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-.search-section {
|
|
|
- padding: 20px;
|
|
|
- background: #f8f9fa;
|
|
|
- border-radius: 8px;
|
|
|
-
|
|
|
- .search-title {
|
|
|
- margin: 0 0 16px 0;
|
|
|
- font-size: 16px;
|
|
|
- font-weight: 600;
|
|
|
- color: #303133;
|
|
|
- }
|
|
|
+// 搜索区域卡片
|
|
|
+.search-section-card {
|
|
|
+ background: #fff;
|
|
|
+ border-radius: 4px;
|
|
|
|
|
|
- .search-bar {
|
|
|
- display: flex;
|
|
|
- gap: 12px;
|
|
|
+ .search-title {
|
|
|
+ font-size: 14px;
|
|
|
+ font-weight: 500;
|
|
|
+ color: #333;
|
|
|
+ padding: 12px 20px;
|
|
|
+ border-bottom: 1px solid #e8e8e8;
|
|
|
+ }
|
|
|
+ .search-bar {
|
|
|
+ display: flex;
|
|
|
+ gap: 10px;
|
|
|
+ padding: 16px 20px;
|
|
|
}
|
|
|
}
|
|
|
</style>
|