fix: create page

This commit is contained in:
zzc
2026-02-13 16:43:55 +08:00
parent 71620d6199
commit b06a69bd33
3 changed files with 485 additions and 5 deletions

472
pages/creation/index.vue Normal file
View File

@@ -0,0 +1,472 @@
<template>
<view class="creation-page" :style="{ paddingTop: navBarHeight + 'px' }">
<!-- 自定义导航栏 -->
<view
class="custom-nav"
:style="{
height: navBarHeight + 'px',
paddingTop: statusBarHeight + 'px',
}"
>
<text class="nav-title">创作中心</text>
<view class="search-icon" @tap="handleSearch">
<uni-icons type="search" size="20" color="#333" />
</view>
</view>
<view class="container">
<!-- 今日推荐创作 Banner -->
<view class="recommend-banner" @tap="goToMake">
<view class="banner-content">
<view class="banner-tag">
<view class="tag-line"></view>
<text>灵感瞬间</text>
</view>
<view class="banner-title">今日推荐创作</view>
<view class="banner-main-title">开启你的第一份<br />新春祝福</view>
<view class="go-btn">去制作</view>
</view>
<image
class="banner-decor"
src="/static/icon/celebrate.png"
mode="aspectFit"
/>
</view>
<!-- 快捷制作 -->
<view class="section">
<view class="section-header">
<text class="section-title">快捷制作</text>
</view>
<view class="quick-grid">
<view class="quick-item" @tap="handleQuickAction('card')">
<view class="icon-box card-bg">
<image src="/static/icon/celebrate.png" mode="aspectFit" />
</view>
<text>新春贺卡</text>
</view>
<view class="quick-item" @tap="handleQuickAction('fortune')">
<view class="icon-box fortune-bg">
<image src="/static/icon/yunshi.png" mode="aspectFit" />
</view>
<text>今日运势</text>
</view>
<view class="quick-item" @tap="handleQuickAction('avatar')">
<view class="icon-box avatar-bg">
<image src="/static/icon/guashi.png" mode="aspectFit" />
</view>
<text>头像挂饰</text>
</view>
<view class="quick-item" @tap="handleQuickAction('wallpaper')">
<view class="icon-box wallpaper-bg">
<image src="/static/icon/bizhi.png" mode="aspectFit" />
</view>
<text>精美壁纸</text>
</view>
</view>
</view>
<!-- 按心情创作 -->
<view class="section">
<view class="section-header">
<text class="section-title">按心情创作</text>
</view>
<scroll-view scroll-x class="mood-scroll" show-scrollbar="false">
<view class="mood-list">
<view
v-for="(mood, index) in moods"
:key="index"
class="mood-item"
@tap="handleMoodClick(mood)"
>
<text class="mood-emoji">{{ mood.emoji }}</text>
<text class="mood-name">{{ mood.name }}</text>
</view>
</view>
</scroll-view>
</view>
<!-- 编辑精选 -->
<view class="section">
<view class="section-header">
<text class="section-title">编辑精选</text>
<text class="view-all" @tap="viewAll">查看全部</text>
</view>
<view class="featured-grid">
<view
v-for="(item, index) in featuredList"
:key="index"
class="featured-item"
@tap="onCardClick(item)"
>
<view class="item-cover-wrap">
<image
:src="item.imageUrl"
mode="aspectFill"
class="item-cover"
/>
<view v-if="item.tag" class="item-tag" :class="item.tag">{{
item.tagText
}}</view>
</view>
<text class="item-title">{{ item.title }}</text>
</view>
</view>
</view>
</view>
</view>
</template>
<script setup>
import { ref, onMounted } from "vue";
import { getBavBarHeight, getStatusBarHeight } from "@/utils/system";
import { getRecommendList } from "@/api/system";
import { trackRecord } from "@/utils/common.js";
const navBarHeight = ref(getBavBarHeight());
const statusBarHeight = ref(getStatusBarHeight());
const moods = ref([
{ name: "开心", emoji: "🎉" },
{ name: "想念", emoji: "💌" },
{ name: "加油", emoji: "💪" },
{ name: "好运", emoji: "🧧" },
{ name: "暴富", emoji: "💰" },
]);
const featuredList = ref([]);
onMounted(() => {
fetchFeaturedList();
trackRecord({
eventName: "creation_page_visit",
eventType: "visit",
});
});
const fetchFeaturedList = async () => {
try {
const res = await getRecommendList(1);
const list = res?.list || [];
featuredList.value = list.slice(0, 4).map((item) => ({
...item,
tag: item.tag === "hot" ? "hot" : item.tag === "new" ? "new" : "",
tagText: item.tag === "hot" ? "HOT" : item.tag === "new" ? "NEW" : "",
}));
} catch (e) {
console.error(e);
}
};
const handleSearch = () => {
uni.showToast({ title: "搜索功能开发中", icon: "none" });
};
const goToMake = () => {
uni.navigateTo({ url: "/pages/make/index" });
};
const handleQuickAction = (type) => {
const map = {
card: "/pages/make/index",
fortune: "/pages/fortune/index",
avatar: "/pages/avatar/index",
wallpaper: "/pages/wallpaper/index",
};
uni.navigateTo({ url: map[type] });
};
const handleMoodClick = (mood) => {
uni.showToast({ title: `选择了${mood.name}心情`, icon: "none" });
};
const viewAll = () => {
uni.switchTab({ url: "/pages/index/index" });
};
const onCardClick = (card) => {
const query = `recommendId=${card.recommendId || ""}&type=${card.type || ""}&imageUrl=${encodeURIComponent(card.imageUrl || "")}`;
if (card.type === "card") {
uni.setStorageSync("RECOMMEND_CARD_DATA", {
recommendId: card.recommendId,
imageUrl: card.imageUrl,
type: card.type,
});
uni.navigateTo({ url: "/pages/make/index" });
} else {
uni.navigateTo({
url: `/pages/avatar/index?${query}`,
});
}
};
</script>
<style lang="scss" scoped>
.creation-page {
min-height: 100vh;
background-color: #fbfbfb;
padding-bottom: 40rpx;
}
.custom-nav {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 100;
background-color: #fbfbfb;
display: flex;
align-items: center;
padding: 0 32rpx;
justify-content: space-between;
.nav-title {
font-size: 36rpx;
font-weight: 600;
color: #333;
}
.search-icon {
width: 64rpx;
height: 64rpx;
background: #fff;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
}
}
.container {
padding: 24rpx 32rpx;
}
.recommend-banner {
height: 320rpx;
background: linear-gradient(135deg, #fff5f5 0%, #fff 100%);
border-radius: 32rpx;
padding: 40rpx;
display: flex;
justify-content: space-between;
align-items: center;
position: relative;
box-shadow: 0 8rpx 24rpx rgba(255, 59, 48, 0.05);
margin-bottom: 48rpx;
.banner-content {
flex: 1;
z-index: 1;
}
.banner-tag {
display: flex;
align-items: center;
margin-bottom: 12rpx;
.tag-line {
width: 32rpx;
height: 4rpx;
background: #ff3b30;
margin-right: 12rpx;
}
text {
font-size: 24rpx;
color: #ff3b30;
font-weight: 500;
}
}
.banner-title {
font-size: 28rpx;
color: #333;
margin-bottom: 16rpx;
}
.banner-main-title {
font-size: 40rpx;
font-weight: 700;
color: #000;
line-height: 1.4;
margin-bottom: 24rpx;
}
.go-btn {
display: inline-block;
padding: 12rpx 40rpx;
background: #ff3b30;
color: #fff;
font-size: 26rpx;
font-weight: 600;
border-radius: 32rpx;
box-shadow: 0 8rpx 16rpx rgba(255, 59, 48, 0.2);
}
.banner-decor {
width: 200rpx;
height: 200rpx;
opacity: 0.1;
position: absolute;
right: 20rpx;
bottom: 20rpx;
}
}
.section {
margin-bottom: 48rpx;
.section-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 24rpx;
.section-title {
font-size: 32rpx;
font-weight: 700;
color: #000;
}
.view-all {
font-size: 24rpx;
color: #ff3b30;
font-weight: 500;
}
}
}
.quick-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 24rpx;
.quick-item {
background: #fff;
border-radius: 24rpx;
padding: 32rpx;
display: flex;
flex-direction: column;
align-items: center;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.02);
.icon-box {
width: 96rpx;
height: 96rpx;
border-radius: 24rpx;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 20rpx;
image {
width: 56rpx;
height: 56rpx;
}
&.card-bg {
background: #fff1f1;
}
&.fortune-bg {
background: #fff8e6;
}
&.avatar-bg {
background: #f0f7ff;
}
&.wallpaper-bg {
background: #f0fff4;
}
}
text {
font-size: 26rpx;
font-weight: 600;
color: #333;
}
}
}
.mood-scroll {
width: 100%;
.mood-list {
display: flex;
padding: 8rpx 0;
}
.mood-item {
flex-shrink: 0;
display: flex;
align-items: center;
background: #fff;
padding: 16rpx 32rpx;
border-radius: 40rpx;
margin-right: 20rpx;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.02);
.mood-emoji {
font-size: 32rpx;
margin-right: 12rpx;
}
.mood-name {
font-size: 26rpx;
color: #333;
font-weight: 500;
}
}
}
.featured-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 24rpx;
.featured-item {
.item-cover-wrap {
position: relative;
width: 100%;
height: 320rpx;
border-radius: 24rpx;
overflow: hidden;
margin-bottom: 16rpx;
background: #eee;
.item-cover {
width: 100%;
height: 100%;
}
.item-tag {
position: absolute;
top: 0;
right: 0;
padding: 6rpx 16rpx;
font-size: 20rpx;
font-weight: 700;
color: #fff;
border-bottom-left-radius: 16rpx;
&.hot {
background: #ff3b30;
}
&.new {
background: #007aff;
}
}
}
.item-title {
font-size: 26rpx;
color: #333;
font-weight: 500;
padding: 0 8rpx;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
overflow: hidden;
}
}
}
</style>

View File

@@ -1,5 +1,6 @@
<template>
<view class="make-page" :style="{ paddingTop: getBavBarHeight() + 'px' }">
<view class="make-page">
<NavBar title="祝福贺卡" />
<!-- 顶部步骤条 -->
<view class="top-steps">
<view class="step-bar">
@@ -489,9 +490,7 @@
<script setup>
import { ref, computed, watch } from "vue";
import { getBavBarHeight, getDeviceInfo } from "@/utils/system";
import { generateObjectId, getShareToken } from "@/utils/common";
import {
createCardTmp,
updateCard,
@@ -514,6 +513,7 @@ import {
import { useUserStore } from "@/stores/user";
import LoginPopup from "@/components/LoginPopup/LoginPopup.vue";
import { saveRecordRequest, uploadImage, trackRecord } from "@/utils/common.js";
import NavBar from "@/components/NavBar/NavBar.vue";
const userStore = useUserStore();
const loginPopupRef = ref(null);