瀏覽代碼

活动首页样式

zhb 3 月之前
父節點
當前提交
224c44c1d6
共有 4 個文件被更改,包括 247 次插入161 次删除
  1. 7 0
      components/cwg-page-wrapper.vue
  2. 179 116
      pages/activities/components/ActivityCard.vue
  3. 29 12
      pages/activities/index.vue
  4. 32 33
      static/scss/global/global.scss

+ 7 - 0
components/cwg-page-wrapper.vue

@@ -145,4 +145,11 @@ onShow(() => {
   align-items: center;
   justify-content: center;
 }
+
+// 针对不同屏幕尺寸的响应式调整
+@media screen and (max-width: 767px) {
+  .content-wrapper-padding {
+    padding: px2rpx(0) !important;
+  }
+}
 </style>

+ 179 - 116
pages/activities/components/ActivityCard.vue

@@ -1,55 +1,53 @@
 <template>
-    <view class="active-box">
-        <!-- 热门标签 -->
-        <view v-if="config.hot" class="btn-tag-star">
-            <uni-icons type="star-filled" size="16" color="#ffd700"></uni-icons>
-        </view>
-
-        <!-- 图片区域 -->
-        <view class="img crm-cursor" @click="handleClick">
-            <image :src="imageSrc" mode="aspectFill" />
-            <view v-if="config.imageTitle" class="imgTitle">{{ t(config.imageTitle) }}</view>
-        </view>
-
-        <!-- 内容区域 -->
-        <view class="content">
-            <view class="title">
-                <span class="name crm-cursor crm-one-font" @click="handleClick">
-                    {{ t(config.title) }}
-                </span>
-                <span v-if="config.time" class="time">{{ config.time }}</span>
+    <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8">
+        <view class="active-box">
+            <!-- 热门标签 -->
+            <view v-if="config.hot" class="btn-tag-star">
+                <uni-icons type="star-filled" size="16" color="#ffd700"></uni-icons>
             </view>
 
-            <view v-if="config.description" class="des crm-one-font">
-                {{ t(config.description) }}
+            <!-- 图片区域 -->
+            <view class="img crm-cursor" @click="handleClick">
+                <image :src="imageSrc" mode="widthFix" />
+                <!-- <view v-if="config.imageTitle" class="imgTitle">{{ t(config.imageTitle) }}</view> -->
             </view>
 
-            <!-- 按钮区域 -->
-            <view class="bottom">
-                <template v-for="(btn, index) in config.buttons" :key="index">
-                    <span v-if="shouldShowButton(btn)" :class="['btn', getButtonType(btn)]" @click="handleButtonClick(btn)">
-                        {{ t(btn.text) }}
-                        <template v-if="btn.suffix && state[btn.suffix]">
-                            {{ state[btn.suffix] }}
-                        </template>
-                        <template v-if="btn.suffixText">
-                            {{ t(btn.suffixText) }}
+            <!-- 内容区域 -->
+            <view class="content">
+                <view class="content-box">
+                    <view v-if="config.time" class="time">{{ config.time }}</view>
+                    <view class="title" @click="handleClick">{{ t(config.title) }}</view>
+                    <view v-if="config.description" class="des crm-one-font">{{ t(config.description) }}</view>
+
+                    <!-- 按钮区域 -->
+                    <view class="bottom">
+                        <template v-for="(btn, index) in config.buttons" :key="index">
+                            <span v-if="shouldShowButton(btn)" :class="['btn', getButtonType(btn)]"
+                                @click="handleButtonClick(btn)">
+                                {{ t(btn.text) }}
+                                <template v-if="btn.suffix && state[btn.suffix]">
+                                    {{ state[btn.suffix] }}
+                                </template>
+                                <template v-if="btn.suffixText">
+                                    {{ t(btn.suffixText) }}
+                                </template>
+                            </span>
+                            <span v-else-if="btn.elseType && btn.condition" :class="['btn', btn.elseType]">
+                                {{ t(btn.text) }}
+                            </span>
                         </template>
-                    </span>
-                    <span v-else-if="btn.elseType && btn.condition" :class="['btn', btn.elseType]">
-                        {{ t(btn.text) }}
-                    </span>
-                </template>
+                    </view>
+                </view>
             </view>
         </view>
-    </view>
+    </uni-col>
 </template>
 
 <script setup lang="ts">
 import { computed } from 'vue'
 import { useI18n } from 'vue-i18n'
 
-const { t, locale} = useI18n()
+const { t, locale } = useI18n()
 
 const props = defineProps<{
     config: any
@@ -71,7 +69,7 @@ const imageSrc = computed(() => {
 const shouldShowButton = (btn: any): boolean => {
     if (!btn.condition) return true
     if (!props.state) return false
-    
+
     try {
         const conditionStr = btn.condition
         const evalStr = conditionStr.replace(/([a-zA-Z_][a-zA-Z0-9_.]*)/g, (match) => {
@@ -123,132 +121,197 @@ const handleButtonClick = (btn: any) => {
 </script>
 
 <style scoped lang="scss">
+@import "@/uni.scss";
+
 .active-box {
+    width: 100%;
     position: relative;
-    display: flex;
-    background-color: #fff;
-    border-radius: 16rpx;
-    padding: 30rpx;
-    margin-bottom: 20rpx;
-    box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1);
+    margin-bottom: px2rpx(20);
+    padding: 0;
+    // overflow: hidden;
+    aspect-ratio: 3 / 4;
 
     .btn-tag-star {
         position: absolute;
-        top: 0;
-        left: 0;
-        z-index: 1;
+        top: px2rpx(30);
+        left: px2rpx(30);
+        z-index: 2;
+        background: linear-gradient(135deg, #ffd700 0%, #ffb347 100%);
+        padding: px2rpx(12) px2rpx(28);
+        border-radius: px2rpx(40);
+        font-size: px2rpx(26);
+        font-weight: bold;
+        color: #0f1423;
+        display: flex;
+        align-items: center;
+        gap: px2rpx(8);
+        box-shadow: 0 px2rpx(4) px2rpx(12) rgba(255, 215, 0, 0.3);
+        letter-spacing: px2rpx(1);
+        text-transform: uppercase;
+
+        .uni-icons {
+            font-size: px2rpx(28) !important;
+        }
     }
 
     .img {
-        width: 200rpx;
-        height: 200rpx;
-        margin-right: 30rpx;
-        border-radius: 12rpx;
-        overflow: hidden;
+        width: 100%;
         position: relative;
+        overflow: hidden;
 
         image {
             width: 100%;
-            height: 100%;
             object-fit: cover;
-        }
-
-        .imgTitle {
-            position: absolute;
-            bottom: 0;
-            left: 0;
-            right: 0;
-            background: rgba(0, 0, 0, 0.5);
-            color: #fff;
-            font-size: 24rpx;
-            padding: 8rpx;
-            text-align: center;
+            transition: transform 0.6s ease;
         }
     }
 
     .content {
-        flex: 1;
-        display: flex;
-        flex-direction: column;
+        width: 100%;
+        padding: 0 px2rpx(14);
+        box-sizing: border-box;
+        margin-top: px2rpx(-20);
 
-        .title {
+
+        .content-box {
+            width: 100%;
+            height: 100%;
             display: flex;
-            align-items: center;
-            justify-content: space-between;
-            margin-bottom: 10rpx;
-
-            .name {
-                font-size: 32rpx;
-                font-weight: bold;
-                color: #333;
-                flex: 1;
-                overflow: hidden;
-                text-overflow: ellipsis;
-                white-space: nowrap;
-            }
+            flex-direction: column;
+            padding: 0 px2rpx(14);
+            box-sizing: border-box;
+            background-color: var(--color-white);
+            z-index: 1;
+            position: relative;
+        }
 
-            .time {
-                font-size: 24rpx;
-                color: #999;
-                margin-left: 16rpx;
-                white-space: nowrap;
-            }
+        .title {
+            width: 100%;
+            margin: px2rpx(20) 0;
+            font-size: px2rpx(24);
+            font-weight: 700;
+            color: var(--color-error);
+            line-height: 1.3;
+            display: block;
+            margin-bottom: px2rpx(12);
+            overflow: hidden;
+            text-overflow: ellipsis;
+            white-space: nowrap;
+        }
+
+        .time {
+            margin-top: px2rpx(20);
+            width: fit-content;
+            font-size: px2rpx(12);
+            color: var(--color-error);
+            background-color:
+                color-mix(in oklab, var(--color-error) 10%, transparent);
+            line-height: px2rpx(20);
+            padding: px2rpx(5) px2rpx(7);
+            border-radius: px2rpx(2);
         }
 
         .des {
-            font-size: 28rpx;
-            color: #666;
-            margin-bottom: 20rpx;
+            width: 100%;
+            font-size: px2rpx(14);
+            color: var(--color-slate-900);
+            margin-bottom: px2rpx(40);
             display: -webkit-box;
             -webkit-line-clamp: 2;
             -webkit-box-orient: vertical;
             overflow: hidden;
-            line-height: 1.4;
+            line-height: 1.2;
         }
 
         .bottom {
             display: flex;
             flex-wrap: wrap;
-            gap: 16rpx;
+            align-items: center;
+            gap: px2rpx(20);
 
             .btn {
-                padding: 10rpx 24rpx;
-                border-radius: 40rpx;
-                font-size: 24rpx;
-                font-weight: 500;
-                transition: all 0.3s;
+                color: var(--color-white);
+                padding: px2rpx(16);
+                font-size: px2rpx(14);
+                font-weight: 600;
+                transition: all 0.3s ease;
                 display: inline-flex;
                 align-items: center;
                 justify-content: center;
                 white-space: nowrap;
+                letter-spacing: px2rpx(1);
+                text-transform: uppercase;
 
                 &.red {
-                    background-color: #ff4d4f;
-                    color: #fff;
-                    border: 1rpx solid #ff4d4f;
-
-                    &:active {
-                        opacity: 0.8;
-                    }
+                    width: 100%;
+                    background-color: var(--color-secondary);
+                    border: 1px solid #333333;
                 }
 
                 &.gray {
-                    background-color: #f5f5f5;
-                    color: #999;
-                    border: 1rpx solid #e5e5e5;
+                    padding: px2rpx(8) px2rpx(16);
+                    font-size: px2rpx(11);
+                    background-color: var(--color-navy-200);
+                    border: 1px solid var(--color-sky-100);
                 }
 
                 &.check {
-                    background-color: #e6f7ff;
-                    color: #1890ff;
-                    border: 1rpx solid #91d5ff;
-
-                    &:active {
-                        opacity: 0.8;
-                    }
+                    padding: px2rpx(8) px2rpx(16);
+                    font-size: px2rpx(11);
+                    background-color: var(--color-error);
                 }
             }
         }
     }
+
+    // 列表项样式(用于底部链接)
+    .link-list {
+        display: flex;
+        gap: px2rpx(30);
+        flex-wrap: wrap;
+        margin-top: px2rpx(30);
+        padding-top: px2rpx(30);
+        border-top: px2rpx(1) solid rgba(255, 215, 0, 0.2);
+
+        .link-item {
+            color: #8e9aaf;
+            font-size: px2rpx(26);
+            transition: color 0.3s;
+
+            &:active {
+                color: #ffd700;
+            }
+
+            &::before {
+                content: '•';
+                color: #ffd700;
+                margin-right: px2rpx(8);
+            }
+        }
+    }
+}
+
+// 针对不同屏幕尺寸的响应式调整
+@media screen and (max-width: 767px) {
+    .active-box {
+
+        .title {
+            width: px2rpx(200)  !important;
+        }
+    }
 }
+
+// 添加悬停效果(仅H5)
+/* #ifdef H5 */
+.active-box:hover {
+    // transform: translateY(-6rpx);
+    // box-shadow: 0 p 60rpx rgba(0, 0, 0, 0.5);
+    // transition: all 0.3s ease;
+
+    .img image {
+        transform: scale(1.05);
+    }
+}
+
+/* #endif */
 </style>

+ 29 - 12
pages/activities/index.vue

@@ -18,20 +18,29 @@
                                 <text class="loading-text">{{ t('common.loading') }}</text>
                             </view>
                         </view>
+                        <view class="activity-list">
+                            <uni-row class="demo-uni-row uni-row1">
+                                
+                                <!-- 遍历静态活动配置 -->
+                                <ActivityCard v-for="activity in visibleStaticActivities" :key="activity.id"
+                                    :config="activity" :state="activityState" :lang="lang"
+                                    @action="handleActivityAction" />
+
+                                <!-- 动态活动列表 -->
+                                <ActivityCard v-for="item in tableData" :key="'dynamic-' + item.id"
+                                    :config="createDynamicConfig(item)" :state="activityState" :lang="lang"
+                                    @action="handleActivityAction" />
+
+                                <!-- 赠送活动列表 -->
+                                <ActivityCard v-for="item in tableDataGive" :key="'give-' + item.id"
+                                    :config="createGiveConfig(item)" :state="activityState" :lang="lang"
+                                    @action="handleActivityAction" />
+                            </uni-row>
 
-                        <!-- 遍历静态活动配置 -->
-                        <ActivityCard v-for="activity in visibleStaticActivities" :key="activity.id" :config="activity"
-                            :state="activityState" :lang="lang" @action="handleActivityAction" />
 
-                        <!-- 动态活动列表 -->
-                        <ActivityCard v-for="item in tableData" :key="'dynamic-' + item.id"
-                            :config="createDynamicConfig(item)" :state="activityState" :lang="lang"
-                            @action="handleActivityAction" />
+                        </view>
+
 
-                        <!-- 赠送活动列表 -->
-                        <ActivityCard v-for="item in tableDataGive" :key="'give-' + item.id"
-                            :config="createGiveConfig(item)" :state="activityState" :lang="lang"
-                            @action="handleActivityAction" />
 
                         <!-- 加载更多状态 -->
                         <view v-if="loadingMore" class="loading-more">
@@ -554,6 +563,7 @@ onReachBottom(() => {
 </script>
 
 <style scoped lang="scss">
+@import "@/uni.scss";
 .custom_activities {
     height: 100vh;
     display: flex;
@@ -578,7 +588,7 @@ onReachBottom(() => {
 
         .tab {
             height: 100%;
-            padding: 20rpx;
+            padding-top: px2rpx(20);
         }
     }
 
@@ -692,5 +702,12 @@ onReachBottom(() => {
             }
         }
     }
+
+    .activity-list {
+        display: flex;
+        flex-direction: column;
+        flex-wrap: wrap;
+        gap: 20rpx;
+    }
 }
 </style>

+ 32 - 33
static/scss/global/global.scss

@@ -851,48 +851,47 @@ body {
     font-weight: bold;
 }
 
-.crm-form {
-    :deep(.uni-row1) {
-        .uni-col {
-            padding: 0 10px !important;
-        }
+:deep(.uni-row1) {
+    .uni-col {
+        padding: 0 10px !important;
+        box-sizing: border-box;
+    }
 
-        .base-info-form>span {
-            display: contents;
-        }
+    .base-info-form>span {
+        display: contents;
+    }
 
-        .uni-forms-item {
-            min-height: px2rpx(79);
-            margin-bottom: px2rpx(10);
-        }
+    .uni-forms-item {
+        min-height: px2rpx(79);
+        margin-bottom: px2rpx(10);
+    }
 
-        .uni-select,
-        .uni-combox,
-        .uni-easyinput__content,
-        .uni-date-editor--x {
-            border: none !important;
-            background-color: var(--color-zinc-100) !important;
+    .uni-select,
+    .uni-combox,
+    .uni-easyinput__content,
+    .uni-date-editor--x {
+        border: none !important;
+        background-color: var(--color-zinc-100) !important;
 
-        }
+    }
 
-        .uni-date-x {
-            border: none !important;
-            background-color: rgba(195, 195, 195, 0) !important;
-        }
+    .uni-date-x {
+        border: none !important;
+        background-color: rgba(195, 195, 195, 0) !important;
+    }
 
-        .uni-easyinput__content {
-            padding: 0 !important;
-        }
+    .uni-easyinput__content {
+        padding: 0 !important;
+    }
 
-        .checklist-text {
-            color: #666 !important;
-        }
+    .checklist-text {
+        color: #666 !important;
+    }
 
-        .checklist-box.is--default.is-checked .checkbox__inner {
-            border-color: var(--color-error) !important;
-            background-color: var(--color-error) !important;
+    .checklist-box.is--default.is-checked .checkbox__inner {
+        border-color: var(--color-error) !important;
+        background-color: var(--color-error) !important;
 
-        }
     }
 }