修改样式
This commit is contained in:
+1011
-279
File diff suppressed because it is too large
Load Diff
+290
-68
@@ -1,11 +1,13 @@
|
||||
<script setup lang="ts">
|
||||
import { debounce } from 'throttle-debounce'
|
||||
import {appCollectListPost, appCollectCollectPost} from "@/service";
|
||||
import FoodBox from "@/pages/home/components/tabbar-home/components/food-box/index.vue";
|
||||
import Collection from "@/components/collection/index.vue";
|
||||
import {CollectionType} from "@/constant/enums";
|
||||
|
||||
const {t} = useI18n()
|
||||
const emit = defineEmits<{
|
||||
(e: 'batch-delete-success'): void
|
||||
}>()
|
||||
const props = defineProps({
|
||||
currentIndex: {
|
||||
type: Number,
|
||||
@@ -15,6 +17,18 @@ const props = defineProps({
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
batchDeleteMode: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
})
|
||||
|
||||
const selectedIds = ref<string[]>([])
|
||||
|
||||
watch(() => props.batchDeleteMode, (v) => {
|
||||
if (!v) {
|
||||
selectedIds.value = []
|
||||
}
|
||||
})
|
||||
|
||||
// (1, "菜谱")(2, "菜品")(3, "配菜")(4, "商家")
|
||||
@@ -35,7 +49,7 @@ const {paging, dataList, queryList, loading} = usePage<any>((pageNum: number, pa
|
||||
pageSize,
|
||||
},
|
||||
body: {
|
||||
targetType: typeList[props.currentIndex]
|
||||
targetType: typeList[props.index]
|
||||
}
|
||||
}),
|
||||
)
|
||||
@@ -51,6 +65,106 @@ function navigateToDishes(item: any) {
|
||||
})
|
||||
}
|
||||
|
||||
function getDishInfo(item: any) {
|
||||
return item?.merchantDishVo || item || {}
|
||||
}
|
||||
|
||||
function getDishImage(item: any) {
|
||||
const dish = getDishInfo(item)
|
||||
return dish?.dishImage?.split?.(',')?.[0] || dish?.dishImage || ''
|
||||
}
|
||||
|
||||
/** 当前列表 tab 对应的收藏目标 id(与 appCollectCollectPost 一致) */
|
||||
function getCollectTargetId(item: any): string {
|
||||
const i = props.index
|
||||
if (i === 0) {
|
||||
return String(item.merchantVo?.id ?? item.merchantId ?? getDishInfo(item).merchantId ?? item.id ?? '')
|
||||
}
|
||||
if (i === 1) {
|
||||
return String(item.merchantDishVo?.id ?? getDishInfo(item).id ?? item.id ?? '')
|
||||
}
|
||||
if (i === 2) {
|
||||
return String(item.merchantRecipeVo?.id ?? item.id ?? '')
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
function toggleSelect(item: any) {
|
||||
if (!props.batchDeleteMode) return
|
||||
const id = getCollectTargetId(item)
|
||||
if (!id) return
|
||||
const idx = selectedIds.value.indexOf(id)
|
||||
if (idx >= 0) {
|
||||
selectedIds.value.splice(idx, 1)
|
||||
} else {
|
||||
selectedIds.value.push(id)
|
||||
}
|
||||
}
|
||||
|
||||
function isSelected(item: any) {
|
||||
const id = getCollectTargetId(item)
|
||||
return id ? selectedIds.value.includes(id) : false
|
||||
}
|
||||
|
||||
function onStoreOrDishRowClick(item: any) {
|
||||
if (props.batchDeleteMode) {
|
||||
toggleSelect(item)
|
||||
return
|
||||
}
|
||||
navigateToDishes(getDishInfo(item))
|
||||
}
|
||||
|
||||
function onRecipeCardClick(item: any) {
|
||||
if (props.batchDeleteMode) {
|
||||
toggleSelect(item)
|
||||
return
|
||||
}
|
||||
navigateToRecipeDetail(item.merchantRecipeVo?.id ?? item.id)
|
||||
}
|
||||
|
||||
function runBatchDelete() {
|
||||
if (selectedIds.value.length === 0) {
|
||||
uni.showToast({
|
||||
title: t('pages.mine.collectionSelectFirst'),
|
||||
icon: 'none',
|
||||
})
|
||||
return
|
||||
}
|
||||
uni.showModal({
|
||||
title: t('common.prompt.system-prompt'),
|
||||
content: t('pages.mine.collectionBatchDeleteConfirm', { count: selectedIds.value.length }),
|
||||
success: (res) => {
|
||||
if (!res.confirm) return
|
||||
const targetType = typeList[props.index] as number
|
||||
const ids = [...selectedIds.value]
|
||||
;(async () => {
|
||||
try {
|
||||
for (const targetId of ids) {
|
||||
await appCollectCollectPost({
|
||||
body: {
|
||||
targetId,
|
||||
targetType,
|
||||
},
|
||||
})
|
||||
}
|
||||
selectedIds.value = []
|
||||
emit('batch-delete-success')
|
||||
paging.value?.reload()
|
||||
uni.showToast({
|
||||
title: t('toast.deleteSuccess'),
|
||||
icon: 'none',
|
||||
})
|
||||
} catch {
|
||||
uni.showToast({
|
||||
title: t('common.prompt.request-incorrect'),
|
||||
icon: 'none',
|
||||
})
|
||||
}
|
||||
})()
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// 收藏菜谱
|
||||
function handleSubmitCollectRecipe(item:any) {
|
||||
debouncedEmit(item.merchantRecipeVo?.isCollect, item.merchantRecipeVo?.id, CollectionType.RECIPE, ()=> {
|
||||
@@ -58,12 +172,6 @@ function handleSubmitCollectRecipe(item:any) {
|
||||
})
|
||||
}
|
||||
|
||||
// 收藏菜品
|
||||
function handleDishCollectionClick(item: any) {
|
||||
debouncedEmit(item.isCollect, item.id, CollectionType.DISH, ()=> {
|
||||
item.isCollect = !item.isCollect
|
||||
})
|
||||
}
|
||||
// 防抖处理函数
|
||||
const debouncedEmit = debounce(1300, (isCollected: boolean, id: string, type: CollectionType, callback: ()=> void) => {
|
||||
// 收藏接口
|
||||
@@ -94,6 +202,7 @@ function refresh() {
|
||||
defineExpose({
|
||||
reload,
|
||||
refresh,
|
||||
runBatchDelete,
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -101,71 +210,66 @@ defineExpose({
|
||||
<view class="h-full">
|
||||
<z-paging ref="paging" v-model="dataList" @query="queryList" :fixed="false" :auto="false">
|
||||
<view class="p-30rpx">
|
||||
<template v-if="currentIndex == 0">
|
||||
<!--商家-->
|
||||
<view v-for="item in dataList" :key="item.id">
|
||||
<food-box :item="item.merchantVo" />
|
||||
</view>
|
||||
</template>
|
||||
<template v-if="currentIndex == 1">
|
||||
<!--菜品-->
|
||||
<view class="grid grid-cols-2 gap-30rpx">
|
||||
<template v-for="item in dataList">
|
||||
<view @click="navigateToDishes(item.merchantDishVo)" class="w-100% mb-10rpx rounded-16rpx">
|
||||
<view class="relative h-248rpx rounded-24rpx mb-28rpx">
|
||||
<view @click.stop="handleDishCollectionClick(item.merchantDishVo)" class="w-68rpx h-68rpx absolute z-2 top-0 right-0">
|
||||
<image
|
||||
v-if="!item.merchantDishVo.isCollect"
|
||||
src="@img-store/1334.png"
|
||||
mode="aspectFill"
|
||||
class="w-full h-full"
|
||||
/>
|
||||
<image
|
||||
v-else
|
||||
src="@img-store/1337.png"
|
||||
mode="aspectFill"
|
||||
class="w-full h-full"
|
||||
/>
|
||||
</view>
|
||||
<image
|
||||
:src="item.merchantDishVo?.dishImage?.split(',')[0]"
|
||||
mode="aspectFill"
|
||||
class="w-full h-full rounded-24rpx"
|
||||
/>
|
||||
</view>
|
||||
<view class="line-clamp-1 text-30rpx lh-30rpx text-#333 font-500 mb-12rpx">
|
||||
{{ item.merchantDishVo.dishName }}
|
||||
</view>
|
||||
<view class="flex-center-sb">
|
||||
<text class="text-30rpx lh-30rpx text-#333 font-500">US${{ item.merchantDishVo.discountPrice }}</text>
|
||||
<view
|
||||
v-if="Number(item.merchantDishVo.memberPrice) > 0"
|
||||
class="member-price-tag text-[#FBE3C3] text-18rpx center pl-6rpx"
|
||||
>
|
||||
{{ t('pages-store.store.members') }}: ${{ item.merchantDishVo.memberPrice }}
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex-center-sb mt-12rpx">
|
||||
<view class="text-28rpx text-#999">
|
||||
<view class="line-through">US${{ item.merchantDishVo.originalPrice }}</view>
|
||||
<view>{{ t('pages-store.store.sales') }}:{{ item.merchantDishVo.salesCount }}</view>
|
||||
</view>
|
||||
|
||||
<view class="center w-64rpx h-64rpx rounded-50% bg-white shadow-lg">
|
||||
<image
|
||||
src="@img/chef/1285.png"
|
||||
class="w-30rpx h-30rpx shrink-0"
|
||||
></image>
|
||||
</view>
|
||||
<template v-if="currentIndex == 0 || currentIndex == 1">
|
||||
<view class="collection-list">
|
||||
<view
|
||||
v-for="item in dataList"
|
||||
:key="item.id"
|
||||
class="collection-item"
|
||||
@click="onStoreOrDishRowClick(item)"
|
||||
>
|
||||
<view
|
||||
v-if="batchDeleteMode"
|
||||
class="collection-item__check"
|
||||
@click.stop="toggleSelect(item)"
|
||||
>
|
||||
<view class="check-box" :class="{ 'is-on': isSelected(item) }">
|
||||
<text v-if="isSelected(item)" class="check-tick">✓</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<image
|
||||
:src="getDishImage(item)"
|
||||
mode="aspectFill"
|
||||
class="collection-item__image"
|
||||
/>
|
||||
<view class="collection-item__content">
|
||||
<view class="collection-item__name line-clamp-1">{{ getDishInfo(item).dishName }}</view>
|
||||
<view class="collection-item__price-row mt-10rpx">
|
||||
<text class="collection-item__price">${{ getDishInfo(item).discountPrice }}</text>
|
||||
<text
|
||||
v-if="Number(getDishInfo(item).originalPrice) > 0"
|
||||
class="collection-item__original ml-10rpx"
|
||||
>
|
||||
${{ getDishInfo(item).originalPrice }}
|
||||
</text>
|
||||
</view>
|
||||
<view v-if="Number(getDishInfo(item).memberPrice) > 0" class="collection-item__member mt-12rpx">
|
||||
<image src="@img-store/1339.png" class="w-22rpx h-22rpx mr-6rpx" />
|
||||
{{ t('pages.browse.brandTag') }} {{ t('pages-store.store.members') }}: ${{ getDishInfo(item).memberPrice }}
|
||||
</view>
|
||||
<view class="collection-item__sales mt-10rpx">
|
||||
{{ t('pages-store.store.sales') }} : {{ getDishInfo(item).salesCount || 0 }}
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="!batchDeleteMode" class="collection-item__add center">
|
||||
<text class="text-42rpx text-#333">+</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<template v-if="currentIndex == 2">
|
||||
<view class="grid grid-cols-2 gap-30rpx">
|
||||
<view v-for="item in dataList">
|
||||
<view @click="navigateToRecipeDetail(item.id)" class="w-312rpx">
|
||||
<view v-for="item in dataList" :key="item.id" class="recipe-card-wrap">
|
||||
<view
|
||||
v-if="batchDeleteMode"
|
||||
class="recipe-card__check"
|
||||
@click.stop="toggleSelect(item)"
|
||||
>
|
||||
<view class="check-box" :class="{ 'is-on': isSelected(item) }">
|
||||
<text v-if="isSelected(item)" class="check-tick">✓</text>
|
||||
</view>
|
||||
</view>
|
||||
<view @click="onRecipeCardClick(item)" class="w-312rpx">
|
||||
<image
|
||||
:src="item.merchantRecipeVo?.recipeImage?.split(',')[0]"
|
||||
class="w-310rpx h-296rpx rounded-24rpx mb-26rpx"
|
||||
@@ -175,7 +279,7 @@ defineExpose({
|
||||
<text class="text-30rpx lh-30rpx text-#333 line-clamp-1 tracking-[.04em] font-500"
|
||||
>{{ item.merchantRecipeVo?.recipeName }}</text
|
||||
>
|
||||
<view class="w-40rpx h-40rpx ml-14rpx shrink-0">
|
||||
<view v-if="!batchDeleteMode" class="w-40rpx h-40rpx ml-14rpx shrink-0">
|
||||
<collection
|
||||
:is-collected="item.merchantRecipeVo?.isCollect"
|
||||
@collectionChange="handleSubmitCollectRecipe(item)"
|
||||
@@ -192,5 +296,123 @@ defineExpose({
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.collection-list {
|
||||
.collection-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 24rpx 0;
|
||||
border-bottom: 1rpx solid #f1f1f1;
|
||||
}
|
||||
|
||||
.collection-item__image {
|
||||
width: 168rpx;
|
||||
height: 168rpx;
|
||||
border-radius: 20rpx;
|
||||
background: #f4f4f4;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.collection-item__content {
|
||||
flex: 1;
|
||||
margin-left: 20rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.collection-item__name {
|
||||
font-size: 30rpx;
|
||||
line-height: 38rpx;
|
||||
color: #222;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.collection-item__price-row {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
}
|
||||
|
||||
.collection-item__price {
|
||||
color: #e7362f;
|
||||
font-size: 42rpx;
|
||||
line-height: 42rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.collection-item__original {
|
||||
color: #a5a5a5;
|
||||
font-size: 28rpx;
|
||||
line-height: 28rpx;
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
.collection-item__member {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
color: #c5883f;
|
||||
font-size: 26rpx;
|
||||
line-height: 26rpx;
|
||||
}
|
||||
|
||||
.collection-item__sales {
|
||||
width: fit-content;
|
||||
height: 42rpx;
|
||||
padding: 0 14rpx;
|
||||
border-radius: 10rpx;
|
||||
background: #f1f2f4;
|
||||
color: #9b9b9b;
|
||||
font-size: 24rpx;
|
||||
line-height: 42rpx;
|
||||
}
|
||||
|
||||
.collection-item__add {
|
||||
width: 56rpx;
|
||||
height: 56rpx;
|
||||
border-radius: 50%;
|
||||
border: 1rpx solid #e6e6e6;
|
||||
margin-left: 14rpx;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.collection-item__check {
|
||||
width: 44rpx;
|
||||
margin-right: 12rpx;
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
.check-box {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
border-radius: 50%;
|
||||
border: 2rpx solid #c8c8c8;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.check-box.is-on {
|
||||
border-color: #111;
|
||||
background: #111;
|
||||
}
|
||||
|
||||
.check-tick {
|
||||
font-size: 24rpx;
|
||||
line-height: 24rpx;
|
||||
color: #fff;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.recipe-card-wrap {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.recipe-card__check {
|
||||
position: absolute;
|
||||
z-index: 3;
|
||||
left: 8rpx;
|
||||
top: 8rpx;
|
||||
}
|
||||
</style>
|
||||
@@ -1,6 +1,26 @@
|
||||
<script setup lang="ts">
|
||||
import OrderSwiperList from "./components/order-swiper-list/order-swiper-list.vue";
|
||||
import { useUserStore } from "@/store";
|
||||
import { onShow } from "@dcloudio/uni-app";
|
||||
|
||||
const {t} = useI18n()
|
||||
const userStore = useUserStore();
|
||||
|
||||
const cartBadgeTotal = computed(() => {
|
||||
const list = userStore.userCartAllData;
|
||||
if (!Array.isArray(list) || list.length === 0) return 0;
|
||||
let n = 0;
|
||||
for (const m of list) {
|
||||
n +=
|
||||
(m as { merchantCartVoList?: unknown[] })?.merchantCartVoList
|
||||
?.length || 0;
|
||||
}
|
||||
return n;
|
||||
});
|
||||
|
||||
onShow(() => {
|
||||
userStore.getUserCartAllData();
|
||||
});
|
||||
const segmentedValue = ref(0);
|
||||
const segmentedList = [
|
||||
'Store',
|
||||
@@ -8,26 +28,106 @@ const segmentedList = [
|
||||
'Recipe',
|
||||
]
|
||||
|
||||
function handleSwiperChange(e) {
|
||||
function handleSwiperChange(e: any) {
|
||||
segmentedValue.value = e.detail.current;
|
||||
}
|
||||
|
||||
const orderSwiperListRef = ref()
|
||||
|
||||
const batchDeleteMode = ref(false)
|
||||
|
||||
onMounted(()=> {
|
||||
nextTick(()=> {
|
||||
orderSwiperListRef.value[segmentedValue.value].reload()
|
||||
})
|
||||
})
|
||||
|
||||
function exitBatchDeleteMode() {
|
||||
batchDeleteMode.value = false
|
||||
}
|
||||
|
||||
function handleBatchDeleteSuccess() {
|
||||
batchDeleteMode.value = false
|
||||
}
|
||||
|
||||
function navigateBack() {
|
||||
uni.navigateBack({
|
||||
delta: 1,
|
||||
})
|
||||
}
|
||||
|
||||
function handleDeleteCollection() {
|
||||
if (!batchDeleteMode.value) {
|
||||
batchDeleteMode.value = true
|
||||
uni.showToast({
|
||||
title: t('pages.mine.collectionBatchModeHint'),
|
||||
icon: 'none',
|
||||
})
|
||||
return
|
||||
}
|
||||
const inst = orderSwiperListRef.value?.[segmentedValue.value]
|
||||
inst?.runBatchDelete?.()
|
||||
}
|
||||
|
||||
function navigateToCart() {
|
||||
uni.navigateTo({
|
||||
url: '/pages-user/pages/cart/index'
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view>
|
||||
<view class="collection-page">
|
||||
<z-paging-swiper>
|
||||
<template #top>
|
||||
<navbar/>
|
||||
<view class="px-30rpx">
|
||||
<view class="text-46rpx lh-46rpx text-#333 font-bold mb-52rpx">{{ t('pages.mine.collection') }}</view>
|
||||
<l-segmented v-model="segmentedValue" :options="segmentedList" shape="round" bg-color="#F2F2F2" active-color="#333" />
|
||||
<status-bar />
|
||||
<view class="header-wrap px-30rpx pt-14rpx">
|
||||
<view class="flex items-center justify-between mb-34rpx">
|
||||
<image
|
||||
@click="navigateBack"
|
||||
src="@img/chef/1327.png"
|
||||
mode="aspectFill"
|
||||
class="w-48rpx h-48rpx"
|
||||
/>
|
||||
<view class="text-38rpx lh-38rpx text-#111 font-600">{{ t('pages.mine.collection') }}</view>
|
||||
<view class="flex items-center gap-16rpx">
|
||||
<text
|
||||
v-if="batchDeleteMode"
|
||||
class="text-28rpx text-#666"
|
||||
@click="exitBatchDeleteMode"
|
||||
>{{ t('common.cancel') }}</text>
|
||||
<view
|
||||
v-if="!batchDeleteMode"
|
||||
class="collection-header-cart w-66rpx h-66rpx rounded-50% bg-#F5F5F5 center shrink-0"
|
||||
@click="navigateToCart"
|
||||
>
|
||||
<view class="i-carbon:shopping-cart text-36rpx text-#14181b"></view>
|
||||
<view
|
||||
v-if="userStore.isLogin && cartBadgeTotal > 0"
|
||||
class="collection-header-cart-badge"
|
||||
>{{ cartBadgeTotal > 99 ? "99+" : cartBadgeTotal }}</view
|
||||
>
|
||||
</view>
|
||||
<view
|
||||
v-if="!batchDeleteMode"
|
||||
class="w-66rpx h-66rpx rounded-50% bg-#F5F5F5 center"
|
||||
@click="handleDeleteCollection"
|
||||
>
|
||||
<image src="@img/chef/1278.png" mode="aspectFill" class="w-66rpx h-66rpx" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<l-segmented
|
||||
v-model="segmentedValue"
|
||||
:options="segmentedList"
|
||||
shape="round"
|
||||
bg-color="#F2F3F5"
|
||||
active-color="#fff"
|
||||
color="#5E5E5E"
|
||||
padding="0rpx"
|
||||
slider-color="#000"
|
||||
height="62rpx"
|
||||
/>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
@@ -35,15 +135,95 @@ onMounted(()=> {
|
||||
:current="segmentedValue"
|
||||
@change="handleSwiperChange">
|
||||
<swiper-item class="swiper-item" v-for="(item, index) in segmentedList" :key="index">
|
||||
<order-swiper-list ref="orderSwiperListRef" :currentIndex="segmentedValue" :index="index"></order-swiper-list>
|
||||
<order-swiper-list
|
||||
ref="orderSwiperListRef"
|
||||
:currentIndex="segmentedValue"
|
||||
:index="index"
|
||||
:batch-delete-mode="batchDeleteMode"
|
||||
@batch-delete-success="handleBatchDeleteSuccess"
|
||||
/>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
</z-paging-swiper>
|
||||
|
||||
<view class="cart-bar-wrap px-24rpx pb-24rpx" v-if="batchDeleteMode">
|
||||
<view class="delete-bar">
|
||||
<view class="text-30rpx text-#1d1d1d ml-20rpx" style="color: #fff;">{{ t('common.delete') || '删除' }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
<style scoped lang="scss">
|
||||
page {
|
||||
background-color: white;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.collection-page {
|
||||
min-height: 100vh;
|
||||
background: #fff;
|
||||
padding-bottom: constant(safe-area-inset-bottom);
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
}
|
||||
|
||||
.header-wrap {
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
:deep(.l-segmented) {
|
||||
height: 62rpx !important;
|
||||
border-radius: 34rpx !important;
|
||||
}
|
||||
|
||||
:deep(.l-segmented-item) {
|
||||
font-size: 30rpx !important;
|
||||
color: #666 !important;
|
||||
}
|
||||
|
||||
:deep(.l-segmented-item--active) {
|
||||
color: #fff !important;
|
||||
font-weight: 600 !important;
|
||||
background: #111 !important;
|
||||
}
|
||||
|
||||
.cart-bar-wrap {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 20;
|
||||
background: linear-gradient(to top, #fff 65%, rgba(255, 255, 255, 0));
|
||||
}
|
||||
|
||||
.collection-header-cart {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.collection-header-cart-badge {
|
||||
position: absolute;
|
||||
top: 2rpx;
|
||||
right: 2rpx;
|
||||
min-width: 28rpx;
|
||||
height: 28rpx;
|
||||
padding: 0 6rpx;
|
||||
font-size: 18rpx;
|
||||
line-height: 28rpx;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
background: #e23636;
|
||||
border-radius: 999rpx;
|
||||
}
|
||||
|
||||
.delete-bar {
|
||||
height: 96rpx;
|
||||
border-radius: 48rpx;
|
||||
background: #000;
|
||||
box-shadow: 0 -2rpx 16rpx rgba(0, 0, 0, 0.06);
|
||||
border: 1rpx solid #efefef;
|
||||
padding: 0 26rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
</style>
|
||||
@@ -42,8 +42,13 @@ function handleClickLeft() {
|
||||
<view class="i-carbon:chevron-left text-50rpx text-#3D3D3D ml-[-10rpx]"></view>
|
||||
</view>
|
||||
</template>
|
||||
<template #title>
|
||||
<view class="invite-navbar-title-wrap">
|
||||
<text class="invite-navbar-title">{{ t('pages.mine.the-person-invited') }}</text>
|
||||
<text class="invite-navbar-count">({{ dataList.length }})</text>
|
||||
</view>
|
||||
</template>
|
||||
</wd-navbar>
|
||||
<view class="mb-46rpx mt-18rpx pl-30rpx text-#333 text-46rpx lh-46rpx font-bold">{{ t('pages.mine.the-person-invited') }} ({{ dataList.length }})</view>
|
||||
</template>
|
||||
<view class="px-18rpx">
|
||||
<view
|
||||
@@ -111,4 +116,30 @@ function handleClickLeft() {
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
<style lang="scss" scoped>
|
||||
.invite-navbar-title-wrap {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
align-items: center;
|
||||
align-content: center;
|
||||
height: 100%;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
padding-left: 8rpx;
|
||||
gap: 8rpx;
|
||||
}
|
||||
|
||||
.invite-navbar-title {
|
||||
font-size: 34rpx;
|
||||
line-height: 42rpx;
|
||||
font-weight: 700;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.invite-navbar-count {
|
||||
font-size: 28rpx;
|
||||
line-height: 34rpx;
|
||||
font-weight: 600;
|
||||
color: #666;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -15,6 +15,29 @@ import {formatTimestamp, formatTimestampWithMonthName} from "@/utils/utils";
|
||||
import {useUserStore, useConfigStore} from "@/store";
|
||||
const userStore = useUserStore()
|
||||
const configStore = useConfigStore()
|
||||
|
||||
function normalizeTimestamp(input: unknown): number | null {
|
||||
if (input == null || input === '') return null
|
||||
const raw = Number(input)
|
||||
if (!Number.isFinite(raw) || raw <= 0) return null
|
||||
|
||||
// 10位秒级、13位毫秒级、16位微秒级都做兼容
|
||||
if (raw < 1e11) return Math.trunc(raw * 1000)
|
||||
if (raw > 1e14) return Math.trunc(raw / 1000)
|
||||
return Math.trunc(raw)
|
||||
}
|
||||
|
||||
function formatRecipeTime(value: unknown): string {
|
||||
const ts = normalizeTimestamp(value)
|
||||
if (!ts) return '--'
|
||||
return formatTimestamp(ts)
|
||||
}
|
||||
|
||||
function formatCommentTime(value: unknown): string {
|
||||
const ts = normalizeTimestamp(value)
|
||||
if (!ts) return '--'
|
||||
return formatTimestampWithMonthName(ts)
|
||||
}
|
||||
// 加载状态
|
||||
const loading = ref(true);
|
||||
// 获取菜谱详情
|
||||
@@ -108,7 +131,7 @@ function getCommentList() {
|
||||
user_name: userInfo.user_name, // 用户名
|
||||
user_avatar: userInfo.user_avatar, // 用户头像地址
|
||||
user_content: item.content, // 用户评论内容
|
||||
create_time: formatTimestampWithMonthName(item.createTime), // 创建时间
|
||||
create_time: formatCommentTime(item.createTime), // 创建时间
|
||||
}
|
||||
})
|
||||
tableTotal.value = res.total
|
||||
@@ -192,7 +215,7 @@ function handleSend() {
|
||||
>{{ recipeDetail?.recipeName || '' }}</view
|
||||
>
|
||||
<view class="flex-center-sb text-28rpx text-#fff">
|
||||
<text>{{ formatTimestamp(recipeDetail?.createTime) }}</text>
|
||||
<text>{{ formatRecipeTime(recipeDetail?.createTime) }}</text>
|
||||
<view class="flex items-center">
|
||||
<image
|
||||
src="@img/chef/1326.png"
|
||||
|
||||
@@ -6,6 +6,7 @@ export const useLogicStore = defineStore('store-list-logic', () => {
|
||||
const searchLoading = ref(false)
|
||||
|
||||
const setPlacesList = (list: any) => {
|
||||
console.log('setPlacesList', list)
|
||||
if (Array.isArray(list)) {
|
||||
placesList.value = list
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user