fix: create page
This commit is contained in:
12
pages.json
12
pages.json
@@ -89,6 +89,14 @@
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/creation/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "创作中心",
|
||||
"navigationStyle": "custom",
|
||||
"backgroundColor": "#fbfbfb"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/detail/index",
|
||||
"style": {
|
||||
@@ -176,8 +184,8 @@
|
||||
"selectedIconPath": "static/images/tabBar/home_s.png"
|
||||
},
|
||||
{
|
||||
"text": "定制贺卡",
|
||||
"pagePath": "pages/make/index",
|
||||
"text": "创作",
|
||||
"pagePath": "pages/creation/index",
|
||||
"iconPath": "static/images/tabBar/creation.png",
|
||||
"selectedIconPath": "static/images/tabBar/creation_s.png"
|
||||
},
|
||||
|
||||
472
pages/creation/index.vue
Normal file
472
pages/creation/index.vue
Normal 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>
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user