feat: 样式调整

This commit is contained in:
zerosaturation 2026-06-04 15:57:42 +08:00
parent 6c18bb7564
commit 71b8e454ee
28 changed files with 234 additions and 173 deletions

View File

@ -11,8 +11,10 @@ import { getLaserApiBaseUrl } from '@/utils/api.js'
import { buildRenderConfigs } from '@/utils/laser-card/laserPresets.js' import { buildRenderConfigs } from '@/utils/laser-card/laserPresets.js'
/** /**
* 镭射专用 fetch直接请求本地 Gateway不走远程 DEV_BASE * 镭射专用请求直接请求本地 Gateway不走远程 DEV_BASE
* 返回格式与 api.js request() 一致{ code, message, data } * 返回格式与 api.js request() 一致{ code, message, data }
*
* 注意uni-app 移动端没有 fetch 全局必须用 uni.request 封装 Promise
*/ */
async function laserRequest(opts) { async function laserRequest(opts) {
const base = getLaserApiBaseUrl() const base = getLaserApiBaseUrl()
@ -22,19 +24,26 @@ async function laserRequest(opts) {
if (token) { if (token) {
headers['Authorization'] = `Bearer ${token}` headers['Authorization'] = `Bearer ${token}`
} }
const fetchOpts = { return new Promise((resolve, reject) => {
uni.request({
url,
method: opts.method || 'GET', method: opts.method || 'GET',
headers, data: opts.data || {},
header: headers,
timeout: 60000,
success: (res) => {
if (res.statusCode < 200 || res.statusCode >= 300) {
reject(new Error(res.data?.message || `HTTP ${res.statusCode}`))
return
} }
if (opts.data) { // 兼容后端返回的两种结构:{code, message, data} 或 裸 data
fetchOpts.body = JSON.stringify(opts.data) resolve(res.data)
} },
const resp = await fetch(url, fetchOpts) fail: (err) => {
const json = await resp.json() reject(new Error(err.errMsg || '网络请求失败'))
if (resp.status < 200 || resp.status >= 300) { },
throw new Error(json?.message || `HTTP ${resp.status}`) })
} })
return json
} }
export function useLaserDifyGenerate() { export function useLaserDifyGenerate() {

View File

@ -3,7 +3,7 @@
"appid" : "__UNI__F199FF4", "appid" : "__UNI__F199FF4",
"description" : "", "description" : "",
"versionName" : "1.0.5", "versionName" : "1.0.5",
"versionCode" : 106, "versionCode" : 107,
"transformPx" : false, "transformPx" : false,
/* 5+App */ /* 5+App */
"app-plus" : { "app-plus" : {

View File

@ -6,9 +6,9 @@
<view v-if="isLaserCardCraft" class="laser-bg-veil" aria-hidden="true" /> <view v-if="isLaserCardCraft" class="laser-bg-veil" aria-hidden="true" />
<!-- 镭射卡左上角关闭 --> <!-- 镭射卡左上角关闭 -->
<view v-if="isLaserCardCraft" class="laser-close-hit" @click="handleBack"> <!-- <view v-if="isLaserCardCraft" class="laser-close-hit" @click="handleBack">
<text class="laser-close-x">×</text> <text class="laser-close-x">×</text>
</view> </view> -->
<!-- 主内容区域 --> <!-- 主内容区域 -->
<scroll-view <scroll-view

View File

@ -508,7 +508,7 @@ defineExpose({
.star-activity-list { .star-activity-list {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 8rpx; /* gap: 8rpx; */
/* width: 68rpx; */ /* width: 68rpx; */
/* 控制整体宽度,根据图标大小调整 */ /* 控制整体宽度,根据图标大小调整 */
height: 156rpx; height: 156rpx;

View File

@ -11,7 +11,11 @@
<!-- 渐变标题 --> <!-- 渐变标题 -->
<view class="title-wrap"> <view class="title-wrap">
<text class="header-title">数据看板</text> <image
class="title-icon"
src="/static/dashboard/dashboard-title.png"
mode="aspectFit"
/>
</view> </view>
<view class="header-content"> <view class="header-content">
@ -105,7 +109,7 @@ defineEmits(["update:activeTab"]);
position: relative; position: relative;
z-index: 2; z-index: 2;
padding: 0 32rpx 32rpx; padding: 0 32rpx 32rpx;
top: 192rpx; top: 272rpx;
} }
.mascot { .mascot {
@ -122,18 +126,32 @@ defineEmits(["update:activeTab"]);
.title-wrap { .title-wrap {
margin-bottom: 24rpx; margin-bottom: 24rpx;
/* 让出 iOS 状态栏 + 顶部 nav 区域,避免标题被遮挡 */
// padding-top: 64rpx;
position: absolute;
right: 40rpx;
top: 160rpx;
}
.title-icon{
width: 240rpx;
height: 64rpx;
} }
.header-title { .header-title {
font-size: 48rpx; font-size: 48rpx;
font-weight: 700; font-weight: 700;
/* 实色兜底:在不支持 -webkit-background-clip 的环境(微信小程序、部分 Android WebView、老 iOS WebView)也能看见 */
color: #ffb199;
/* 渐变文字效果:现代环境(H5/新版 WebView)会用渐变覆盖实色 */
background: linear-gradient(90deg, #ffe5b4 0%, #ffb199 50%, #ff8a95 100%); background: linear-gradient(90deg, #ffe5b4 0%, #ffb199 50%, #ff8a95 100%);
-webkit-background-clip: text; -webkit-background-clip: text;
background-clip: text; background-clip: text;
color: transparent; -webkit-text-fill-color: transparent;
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.4); text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.4);
} }
.header-tabs { .header-tabs {
display: flex; display: flex;
// background: rgba(0, 0, 0, 0.15); // background: rgba(0, 0, 0, 0.15);
@ -172,9 +190,11 @@ defineEmits(["update:activeTab"]);
.tab-icon { .tab-icon {
width: 160rpx; width: 160rpx;
height: 160rpx; height: 160rpx;
position: fixed; /* 修复:原来是 position: fixed; left: 0; top: 0; (典型复制粘贴 bug,会让两个 tab 图标都叠在屏幕左上角) */
left: 0; position: absolute;
top: 0; left: 50%;
top: 50%;
transform: translate(-50%, -50%);
z-index: 0; z-index: 0;
opacity: 0.7; opacity: 0.7;
} }

View File

@ -145,7 +145,7 @@ onShow(() => {
} }
.nav-back { .nav-back {
position: fixed; position: absolute;
top: 96rpx; top: 96rpx;
left: 32rpx; left: 32rpx;
width: 80rpx; width: 80rpx;

View File

@ -1,28 +1,19 @@
<template> <template>
<view class="banner-carousel" @click.stop> <view class="banner-carousel" @click.stop>
<swiper <swiper class="banner-swiper" :autoplay="true" :interval="4000" :duration="400" :circular="true"
class="banner-swiper" :indicator-dots="false" @change="onSwiperChange">
:autoplay="true" <!-- <swiper-item @click.stop="$emit('top3Click')" style="display: flex;
:interval="4000"
:duration="400"
:circular="true"
:indicator-dots="false"
@change="onSwiperChange"
>
<swiper-item @click.stop="$emit('top3Click')" style="display: flex;
align-items: center;"> align-items: center;">
<BannerTop3 @dataLoaded="onTop3DataLoaded" @top3Click="$emit('top3Click')" /> <BannerTop3 @dataLoaded="onTop3DataLoaded" @top3Click="$emit('top3Click')" />
</swiper-item> -->
<swiper-item v-for="item in bannerActivities" :key="item.id" @tap.stop="$emit('activityClick', item)">
<image class="banner-activity-img" :src="item.cover_image || '/static/avatar/1.jpeg'" mode="aspectFill" />
</swiper-item> </swiper-item>
<swiper-item <swiper-item v-for="(banner, index) in banners" :key="banner.id || index" @click="emit('bannerClick', banner)">
v-for="item in bannerActivities" <image class="banner-image" :src="banner.image_url" mode="widthFill"></image>
:key="item.id" <!-- <view class="banner-overlay">
@tap.stop="$emit('activityClick', item)" <text class="banner-title">{{ banner.title }}</text>
> </view> -->
<image
class="banner-activity-img"
:src="item.cover_image || '/static/avatar/1.jpeg'"
mode="aspectFill"
/>
</swiper-item> </swiper-item>
</swiper> </swiper>
</view> </view>
@ -33,9 +24,14 @@ import { ref } from 'vue'
import BannerTop3 from '../../components/BannerTop3.vue' import BannerTop3 from '../../components/BannerTop3.vue'
defineProps({ defineProps({
bannerActivities: { type: Array, default: () => [] } bannerActivities: { type: Array, default: () => [] },
//
banners: {
type: Array,
default: () => []
}
}) })
defineEmits(['activityClick', 'top3Click']) const emit = defineEmits(['activityClick', 'top3Click', 'bannerClick'])
const currentIndex = ref(0) const currentIndex = ref(0)
@ -69,10 +65,34 @@ const onTop3DataLoaded = (items) => {
.banner-activity-img { .banner-activity-img {
width: 100%; width: 100%;
height: 312rpx; height: 344rpx;
display: block; display: block;
border-radius: 24rpx; border-radius: 24rpx;
position: relative; position: relative;
top: 24rpx; /* top: 24rpx; */
}
.banner-image {
width: 100%;
height: 356rpx;
display: block;
border-radius: 24rpx;
position: relative;
bottom: 8rpx;
}
.banner-overlay {
position: absolute;
bottom: 0;
left: 0;
right: 0;
padding: 24rpx;
background: linear-gradient(to top, rgba(0, 0, 0, 0.6), transparent);
}
.banner-title {
font-size: 28rpx;
color: #fff;
font-weight: 600;
} }
</style> </style>

View File

@ -121,9 +121,9 @@ const likingMap = ref({});
// //
const TOP_FRAME_MAP = { const TOP_FRAME_MAP = {
0: "/static/square/top/TOP1biankuang.png", 0: "/static/square/top/TOP1biankuang1.png",
1: "/static/square/top/TOP2biankuang.png", 1: "/static/square/top/TOP2biankuang2.png",
2: "/static/square/top/TOP3biankuangpng.png", 2: "/static/square/top/TOP3biankuangpng3.png",
}; };
const TOP_ICON_MAP = { const TOP_ICON_MAP = {
0: "/static/square/top/TOP1icon.png", 0: "/static/square/top/TOP1icon.png",
@ -209,7 +209,7 @@ onUnmounted(() => {
.hot-category-block { .hot-category-block {
padding: 19rpx 9.5rpx; padding: 19rpx 9.5rpx;
border-radius: 24rpx; border-radius: 24rpx;
opacity: 0.8; /* opacity: 0.8; */
background: linear-gradient( background: linear-gradient(
161.28deg, 161.28deg,
rgba(255, 90, 93, 0.2) 16.63%, rgba(255, 90, 93, 0.2) 16.63%,
@ -337,11 +337,11 @@ onUnmounted(() => {
/* 第一排3个大图突出显示 */ /* 第一排3个大图突出显示 */
.grid-card:nth-child(-n + 3) { .grid-card:nth-child(-n + 3) {
width: calc(33% - 18rpx); width: calc(33% - 24rpx);
} }
.grid-card:nth-child(-n + 3) .card-image { .grid-card:nth-child(-n + 3) .card-image {
height: 252rpx; height: 264rpx;
box-shadow: 3px 3px 4.5px 2px rgba(0, 0, 0, 0.15); box-shadow: 3px 3px 4.5px 2px rgba(0, 0, 0, 0.15);
backdrop-filter: blur(0px); backdrop-filter: blur(0px);
padding: 8rpx; padding: 8rpx;
@ -350,7 +350,7 @@ onUnmounted(() => {
.card-image { .card-image {
width: 100%; width: 100%;
height: 192rpx; height: 224rpx;
display: block; display: block;
} }
@ -401,6 +401,7 @@ onUnmounted(() => {
border-radius: 16rpx; border-radius: 16rpx;
overflow: hidden; overflow: hidden;
position: relative; position: relative;
box-shadow: 2px 2px 4.5px 0px #F04B4B40;
} }
.card-bottom-1, .card-bottom-1,

View File

@ -1,9 +1,23 @@
import { ref } from 'vue' import { ref } from 'vue'
import { getActivityListApi } from '@/utils/api.js' import { getActivityListApi, getMintingActivitiesApi } from '@/utils/api.js'
// 默认 banner(接口失败/无数据时兜底)
const FALLBACK_BANNER = [
{
image_url: '/static/sucai/image-05.png',
title: '这河非遇美学宇宙联名',
link_type: 'activity',
link_value: '1'
}
]
export function useBanner() { export function useBanner() {
// 旧的活动 banner(square 顶部)
const bannerActivities = ref([]) const bannerActivities = ref([])
// 新的运营 banner(铸造活动)
const banners = ref([])
const loadBannerActivities = async () => { const loadBannerActivities = async () => {
try { try {
const starId = uni.getStorageSync('star_id') || null const starId = uni.getStorageSync('star_id') || null
@ -12,7 +26,6 @@ export function useBanner() {
if (res.code === 200 && res.data?.activities) { if (res.code === 200 && res.data?.activities) {
const activities = res.data.activities const activities = res.data.activities
// 过滤掉已过期的活动 // 过滤掉已过期的活动
// bannerActivities.value = activities
bannerActivities.value = activities.filter(item => item.status !== 'expired') bannerActivities.value = activities.filter(item => item.status !== 'expired')
} }
} catch (e) { } catch (e) {
@ -20,8 +33,38 @@ export function useBanner() {
} }
} }
// 加载运营 banner(铸造活动)
const loadBanners = async () => {
try {
const res = await getMintingActivitiesApi(null, 1, 10)
if (res.code === 200 && res.data?.activities) {
// 将后端数据映射为 BannerCarousel 约定的字段
banners.value = res.data.activities.map(activity => ({
id: activity.id,
image_url: activity.cover_image,
title: activity.title,
link_type: 'activity',
link_value: String(activity.id),
description: activity.description,
route: activity.route
}))
}
// 无数据兜底
if (banners.value.length === 0) {
banners.value = [...FALLBACK_BANNER]
}
} catch (e) {
console.error('[useBanner] 加载运营 banner 失败', e?.message ?? e)
banners.value = [...FALLBACK_BANNER]
}
}
return { return {
bannerActivities, bannerActivities,
banners,
loadBannerActivities, loadBannerActivities,
loadBanners
} }
} }

View File

@ -63,7 +63,7 @@
/> />
<view class="creation-info"> <view class="creation-info">
<view class="creation-id"> <view class="creation-id">
<text class="id-text">#{{ item.certificate_id }}</text> <text class="id-text">链上编号: #{{ item.certificate_id }}</text>
</view> </view>
<view class="creation-meta"> <view class="creation-meta">
<view class="creator-info"> <view class="creator-info">

View File

@ -1,81 +1,46 @@
<template> <template>
<view class="square-container"> <view class="square-container">
<!-- 背景图片 --> <!-- 背景图片 -->
<image <!-- <image
class="bg-wrapper" class="bg-wrapper"
src="/static/square/squearbj1.png" src="/static/square/squearbj11.png"
mode="aspectFill" mode="aspectFill"
></image> ></image> -->
<!-- Header组件 --> <!-- Header组件 -->
<Header <Header :showGuideIcon="true" :showTaskIcon="true" :showStarActivityIcon="true" backIconColor="#e6e6e6" />
:showGuideIcon="true"
:showTaskIcon="true"
:showStarActivityIcon="true"
backIconColor="#e6e6e6"
/>
<!-- 蒙层 - 导航栏展开时显示 --> <!-- 蒙层 - 导航栏展开时显示 -->
<view <view v-if="navExpanded" class="nav-mask" @click="navExpanded = false"></view>
v-if="navExpanded"
class="nav-mask"
@click="navExpanded = false"
></view>
<!-- 排行榜弹窗 --> <!-- 排行榜弹窗 -->
<RankingModal <RankingModal :visible="showRankingModal" :parent-active="true" :star-id="currentStarId"
:visible="showRankingModal" @update:visible="handleRankingModalClose" @visit="handleRankingVisit" />
:parent-active="true"
:star-id="currentStarId"
@update:visible="handleRankingModalClose"
@visit="handleRankingVisit"
/>
<!-- 底部导航栏 --> <!-- 底部导航栏 -->
<BottomNav <BottomNav :activeTab="4" :isExpanded="navExpanded" @update:activeTab="handleTabChange"
:activeTab="4" @update:isExpanded="navExpanded = $event" />
:isExpanded="navExpanded"
@update:activeTab="handleTabChange"
@update:isExpanded="navExpanded = $event"
/>
<!-- 全局引导遮罩 --> <!-- 全局引导遮罩 -->
<GuideOverlay /> <GuideOverlay />
<!-- 内容区域 --> <!-- 内容区域 -->
<scroll-view <scroll-view class="content-wrapper" :class="{ 'spotlight-ready': isH5 }" scroll-y :show-scrollbar="false"
class="content-wrapper" :bounce="false" @scroll="onScroll" @touchstart="onTouchStart" @touchmove="onTouchMove"
:class="{ 'spotlight-ready': isH5 }" @scrolltolower="handleScrollToLower">
scroll-y
:show-scrollbar="false"
:bounce="false"
@scroll="onScroll"
@touchstart="onTouchStart"
@touchmove="onTouchMove"
@scrolltolower="handleScrollToLower"
>
<!-- 区域一顶部运营轮播图 --> <!-- 区域一顶部运营轮播图 -->
<view ref="bannerSectionRef" class="banner-section"> <view ref="bannerSectionRef" class="banner-section">
<BannerCarousel <BannerCarousel :bannerActivities="bannerActivities" :banners="banners"
:bannerActivities="bannerActivities" @activityClick="handleActivityClick" @top3Click="showRankingModal = true"
@activityClick="handleActivityClick" @bannerClick="handleBannerClick" />
@top3Click="showRankingModal = true"
/>
</view> </view>
<ContentTabs <ContentTabs ref="contentTabsRef" class="tabs" :modelValue="activeContentTab"
ref="contentTabsRef" @update:modelValue="activeContentTab = $event" />
class="tabs"
:modelValue="activeContentTab"
@update:modelValue="activeContentTab = $event"
/>
<!-- 在线榜单区块 --> <!-- 在线榜单区块 -->
<view ref="hotCategoryRef" class="hot-category-wrapper"> <view ref="hotCategoryRef" class="hot-category-wrapper">
<HotCategoryBlock <HotCategoryBlock :dimension="activeContentTab" @cardClick="handleCardClick" />
:dimension="activeContentTab"
@cardClick="handleCardClick"
/>
<view class="hot-more-btn" @click="goToHotCategoryMore"> <view class="hot-more-btn" @click="goToHotCategoryMore">
<text class="hot-more-text">查看更多</text> <text class="hot-more-text">查看更多</text>
</view> </view>
@ -83,25 +48,15 @@
<!-- 区域二主Tab标签区星卡/吧唧/海报 --> <!-- 区域二主Tab标签区星卡/吧唧/海报 -->
<view ref="mainTabsRef" class="main-tab-section"> <view ref="mainTabsRef" class="main-tab-section">
<view <view v-for="(tab, index) in mainTabs" :key="index" class="tab-item"
v-for="(tab, index) in mainTabs" :style="{ '--tab-delay': index * 0.06 + 's' }" @click="handleMainTabClick(tab)">
:key="index"
class="tab-item"
:style="{ '--tab-delay': index * 0.06 + 's' }"
@click="handleMainTabClick(tab)"
>
<view class="tab-icon-wrap"> <view class="tab-icon-wrap">
<image <image class="tab-icon" :src="tab.icon" mode="aspectFit" :style="{
class="tab-icon"
:src="tab.icon"
mode="aspectFit"
:style="{
width: tab.width + 'rpx', width: tab.width + 'rpx',
height: tab.height + 'rpx', height: tab.height + 'rpx',
borderRadius: tab.type === 'badge' ? '50%' : '0', borderRadius: tab.type === 'badge' ? '50%' : '0',
transform: 'rotate(' + tab.rotate + 'deg)', transform: 'rotate(' + tab.rotate + 'deg)',
}" }">
>
</image> </image>
</view> </view>
<text class="tab-name">{{ tab.name }}</text> <text class="tab-name">{{ tab.name }}</text>
@ -109,42 +64,23 @@
</view> </view>
<!-- 区域三分类标签区 --> <!-- 区域三分类标签区 -->
<view <view ref="categoryRef" id="category-section" class="category-section"
ref="categoryRef" :class="{ fixed: isFixed, 'just-fixed': justFixed }">
id="category-section"
class="category-section"
:class="{ fixed: isFixed, 'just-fixed': justFixed }"
>
<scroll-view class="category-scroll" scroll-x :show-scrollbar="false"> <scroll-view class="category-scroll" scroll-x :show-scrollbar="false">
<view <view v-for="(category, index) in categories" :key="index" class="category-item"
v-for="(category, index) in categories" :class="{ active: activeCategoryTab === category.value }" @click="handleCategoryChange(category.value)">
:key="index"
class="category-item"
:class="{ active: activeCategoryTab === category.value }"
@click="handleCategoryChange(category.value)"
>
<text class="category-text">{{ category.label }}</text> <text class="category-text">{{ category.label }}</text>
</view> </view>
</scroll-view> </scroll-view>
</view> </view>
<!-- fixed 时占位避免下方内容跳变 --> <!-- fixed 时占位避免下方内容跳变 -->
<view <view v-if="isFixed && categoryHeight > 0" class="category-placeholder"
v-if="isFixed && categoryHeight > 0" :style="{ height: categoryHeight + 'px' }"></view>
class="category-placeholder"
:style="{ height: categoryHeight + 'px' }"
></view>
<!-- 区域四创作网格列表 --> <!-- 区域四创作网格列表 -->
<CreationGrid <CreationGrid :screenWidth="screenWidth" :screenHeight="screenHeight" :bannerBottom="bannerBottomPx"
:screenWidth="screenWidth" :category="activeCategoryTab" :isActive="isActive" @cardClick="handleCardClick" @loaded="onGridLoaded"
:screenHeight="screenHeight" ref="creationGridRef" />
:bannerBottom="bannerBottomPx"
:category="activeCategoryTab"
:isActive="isActive"
@cardClick="handleCardClick"
@loaded="onGridLoaded"
ref="creationGridRef"
/>
</scroll-view> </scroll-view>
</view> </view>
</template> </template>
@ -310,7 +246,7 @@ const screenWidth = ref(375);
const screenHeight = ref(812); const screenHeight = ref(812);
// ========== Composables ========== // ========== Composables ==========
const { bannerActivities, loadBannerActivities } = useBanner(); const { bannerActivities, banners, loadBannerActivities, loadBanners } = useBanner();
// banner(216+360rpx) + tab(16+80rpx) + (8rpx) 680rpx // banner(216+360rpx) + tab(16+80rpx) + (8rpx) 680rpx
const bannerBottomPx = computed(() => const bannerBottomPx = computed(() =>
@ -361,6 +297,25 @@ const handleActivityClick = (item) => {
}); });
}; };
// banner ()
const handleBannerClick = (banner) => {
console.log('[square] banner click', banner);
// 使 route
if (banner.route) {
return uni.navigateTo({ url: banner.route });
}
if (banner.link_type === 'activity') {
return uni.navigateTo({
url: `/pages/castlove/detail?id=${banner.link_value}`,
});
}
if (banner.link_type === 'topic') {
return uni.navigateTo({
url: `/pages/topic/detail?id=${banner.link_value}`,
});
}
};
const handleRankingVisit = ({ userId, nickname }) => { const handleRankingVisit = ({ userId, nickname }) => {
showRankingModal.value = false; showRankingModal.value = false;
uni.navigateTo({ uni.navigateTo({
@ -435,6 +390,7 @@ onMounted(() => {
resetSquare(); resetSquare();
loadBannerActivities(); loadBannerActivities();
loadBanners();
// DOM section / + spotlight // DOM section / + spotlight
nextTick(() => { nextTick(() => {
@ -499,13 +455,26 @@ onUnmounted(() => {
}); });
</script> </script>
<style scoped> <style lang="scss" scoped>
.square-container { .square-container {
position: relative; position: relative;
background: linear-gradient(179.98deg, rgba(255, 229, 229, 0.25) -32.49%, rgba(243, 160, 161, 0.25) -32.49%, rgba(255, 156, 156, 0.25) 86.46%, rgba(255, 32, 36, 0.25) 180.79%);
backdrop-filter: blur(4px);
width: 100vw; width: 100vw;
height: 100vh; height: 100vh;
min-height: 100vh; min-height: 100vh;
overflow: hidden; overflow: hidden;
&::before {
content: "";
position: absolute;
inset: 0;
background: url("/static/dashboard/bj.png") center / cover no-repeat;
opacity: 0.2; // 0=1=
pointer-events: none;
z-index: 0;
}
} }
/* 背景图片 */ /* 背景图片 */
@ -551,11 +520,9 @@ onUnmounted(() => {
justify-content: space-around; justify-content: space-around;
width: 200rpx; width: 200rpx;
height: 200rpx; height: 200rpx;
background: linear-gradient( background: linear-gradient(135deg,
135deg,
rgba(240, 228, 177, 0.3), rgba(240, 228, 177, 0.3),
rgba(240, 131, 153, 0.3) rgba(240, 131, 153, 0.3));
);
border-radius: 24rpx; border-radius: 24rpx;
box-shadow: 0 8rpx 24rpx rgba(255, 107, 157, 0.2); box-shadow: 0 8rpx 24rpx rgba(255, 107, 157, 0.2);
transition: all 0.3s; transition: all 0.3s;
@ -652,11 +619,9 @@ onUnmounted(() => {
border-radius: 20rpx; border-radius: 20rpx;
opacity: 0.66; opacity: 0.66;
padding: 8rpx 20rpx; padding: 8rpx 20rpx;
background: linear-gradient( background: linear-gradient(90deg,
90deg,
rgba(255, 222, 8, 0.61) -17.54%, rgba(255, 222, 8, 0.61) -17.54%,
rgba(255, 0, 25, 0.61) 116.67% rgba(255, 0, 25, 0.61) 116.67%);
);
box-shadow: 2px 2px 4px 0px #f2151578; box-shadow: 2px 2px 4px 0px #f2151578;
display: flex; display: flex;
justify-content: center; justify-content: center;
@ -757,6 +722,7 @@ onUnmounted(() => {
/* 动效减弱的可访问性兜底 */ /* 动效减弱的可访问性兜底 */
@media (prefers-reduced-motion: reduce) { @media (prefers-reduced-motion: reduce) {
.spotlight, .spotlight,
.spotlight-ready .banner-section, .spotlight-ready .banner-section,
.spotlight-ready .tabs, .spotlight-ready .tabs,

Binary file not shown.

Before

Width:  |  Height:  |  Size: 232 KiB

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 261 KiB

After

Width:  |  Height:  |  Size: 336 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 336 KiB

After

Width:  |  Height:  |  Size: 149 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 121 KiB

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 140 KiB

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 149 KiB

After

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 KiB

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 870 KiB

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 359 KiB

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 297 KiB

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 502 KiB

After

Width:  |  Height:  |  Size: 70 KiB

View File

@ -713,6 +713,7 @@ function parseSegmentPortraitResponse(statusCode, rawBody) {
return body return body
} }
// #ifdef H5
function isH5SpecialImagePath(path) { function isH5SpecialImagePath(path) {
return /^blob:/i.test(path) || /^data:image\//i.test(path) return /^blob:/i.test(path) || /^data:image\//i.test(path)
} }
@ -747,6 +748,7 @@ async function segmentPortraitApiH5(filePath, imageBase64) {
const text = await uploadRes.text() const text = await uploadRes.text()
return parseSegmentPortraitResponse(uploadRes.status, text) return parseSegmentPortraitResponse(uploadRes.status, text)
} }
// #endif
/** /**
* 人像抠图multipart POST /api/v1/segment?scene=portrait * 人像抠图multipart POST /api/v1/segment?scene=portrait