绿满眶商城微信小程序-uniapp
zxl
2 天以前 4c0c7752dc996baba58f33aa101a7385752061a3
厨师
4个文件已修改
3个文件已添加
528 ■■■■■ 已修改文件
api/kitchen.js 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
components/TopBar.vue 27 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
components/custom-tabbar.vue 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages.json 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/kitchen/KitchenCover.vue 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/kitchen/KitchenCustomize.vue 366 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/tabbar/index/home.vue 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
api/kitchen.js
New file
@@ -0,0 +1,30 @@
import { http, Method } from "@/utils/request.js";
export function getKitchenBanner(){
    return http.request({
        url: "/lmk/kitchen/banner",
        method: Method.GET,
    })
}
export function getKitchenTag(){
    return http.request({
        url: "/lmk/kitchen/kitchenTag",
        method: Method.GET,
    })
}
export function getKitchenCover(){
    return http.request({
        url: "/lmk/kitchen/kitchenCover",
        method: Method.GET,
    })
}
export function getKitchenGoods(param){
    return http.request({
        url: "/lmk/kitchen/kitchenGoods",
        method: Method.GET,
        params:param
    })
}
components/TopBar.vue
@@ -1,5 +1,5 @@
<template>
    <view class="top-bar" :style="{paddingTop: statusBarHeight + 'px'}">
    <view class="top-bar" :style="{paddingTop: statusBarHeight + 'px', backgroundColor: bgColor}" :class="{'has-bg': bgColor !== 'transparent'}">
        <view class="top-bar-content">
            <!-- 标题列表 -->
            <scroll-view class="title-scroll" scroll-x="true" scroll-with-animation :scroll-left="scrollLeft">
@@ -31,6 +31,10 @@
            textColor: {
                type: String,
                default: 'white'
            },
            bgColor: {
                type: String,
                default: 'transparent'
            }
        },
        data() {
@@ -44,6 +48,11 @@
                        title: '推荐'
                    },
                    {
                        index: 'kitchenCustomize',
                        pagePath: '/pages/kitchen/KitchenCustomize',
                        title: '厨房定制'
                    },
                    {
                        index: 'shop',
                        pagePath: '/pages/commodity-square/commoditySquare',
                        title: '商品广场'
@@ -53,11 +62,11 @@
                        pagePath: '/pages/mine/activity/reportActivity',
                        title: '活动'
                    },
                    {
                        index: 'health',
                        pagePath: '/pages/health/healthVideo',
                        title: '大健康'
                    }
                    // {
                    //     index: 'health',
                    //     pagePath: '/pages/health/healthVideo',
                    //     title: '大健康'
                    // }
                ]
            };
        },
@@ -98,6 +107,10 @@
            left: 0;
            right: 0;
            z-index: 999;
        }
        .top-bar.has-bg {
            box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
        }
        
        .top-bar .top-bar-content {
@@ -144,4 +157,4 @@
            /* background-color: white; */
            border-radius: 4rpx;
        }
</style>
</style>
components/custom-tabbar.vue
@@ -41,8 +41,9 @@
                        "key": 'index'
                    },
                    {
                        // KitchenVideo
                        // "pagePath": "/pages/tabbar/category/category",
                        "pagePath": "/pages/kitchen/KitchenVideo",
                        "pagePath": "/pages/kitchen/KitchenCover",
                        "iconPath": "/static/tabbar/category.png",
                        "selectedIconPath": "/static/tabbar/category-s.png",
pages.json
@@ -22,7 +22,11 @@
      "style": {
        // "navigationBarTitleText" : "视频",
        "enablePullDownRefresh": false,
        "navigationStyle": "custom"
        "navigationStyle": "custom",
        "componentPlaceholder": {
          "u-icon": "view"
        }
        // 隐藏顶部导航栏
      }
    },
@@ -1919,6 +1923,20 @@
            "navigationStyle": "custom"
            // 隐藏系统导航栏
          }
        },
        {
          "path": "KitchenCustomize",
          "style": {
            "navigationBarTitleText": "神厨定制",
            "navigationStyle": "custom"
          }
        },
        {
          "path": "KitchenCover",
          "style": {
            "navigationBarTitleText": "神厨封面",
            "navigationStyle": "custom"
          }
        }
      ]
    },
pages/kitchen/KitchenCover.vue
New file
@@ -0,0 +1,70 @@
<template>
    <view class="page-container">
        <scroll-view scroll-y="true" class="scroll-view">
            <image v-if="coverUrl" :src="coverUrl" mode="widthFix" class="bg-image"></image>
            <view v-else class="empty-text">暂无</view>
            <!-- 底部留出导航栏高度的空间 -->
            <view class="safe-area-bottom"></view>
        </scroll-view>
        <custom-tabbar bgColor="#ffffff" selected="kitchen"></custom-tabbar>
    </view>
</template>
<script>
    import { getKitchenCover } from "@/api/kitchen.js";
    export default {
        data() {
            return {
                coverUrl: ''
            };
        },
        onLoad() {
            this.fetchCover();
        },
        methods: {
            async fetchCover() {
                try {
                    const res = await getKitchenCover();
                    if (res.statusCode === 200 && res.data.data && res.data.data.length > 0) {
                        this.coverUrl = res.data.data[0].coverUrl;
                    }
                } catch (e) {
                    console.error("获取神厨封面失败", e);
                }
            }
        }
    }
</script>
<style lang="scss" scoped>
    .page-container {
        width: 100vw;
        height: 100vh;
        position: relative;
        overflow: hidden;
        background-color: #ffffff;
    }
    .scroll-view {
        width: 100%;
        height: 100%;
    }
    .bg-image {
        width: 100%;
        display: block;
    }
    .empty-text {
        text-align: center;
        padding-top: 300rpx;
        color: #999;
        font-size: 28rpx;
    }
    .safe-area-bottom {
        height: 120rpx; // 为底部导航栏留出空间
        width: 100%;
    }
</style>
pages/kitchen/KitchenCustomize.vue
New file
@@ -0,0 +1,366 @@
<template>
    <view class="page">
        <top-bar selectedTitleIndex="kitchenCustomize" textColor="black" bgColor="#ffffff" @changeTab="topBarChange"></top-bar>
        <view class="banner">
            <image class="banner-img" :src="banner" mode="aspectFill"></image>
        </view>
        <view class="content">
            <scroll-view class="tags-scroll" scroll-x="true" :show-scrollbar="false">
                <view class="tags">
                    <view v-for="tag in tags" :key="tag.value" class="tag" :class="{ active: tag.selected }"
                        @click="toggleTag(tag)">
                        <text>{{ tag.label }}</text>
                    </view>
                </view>
            </scroll-view>
            <!-- 新增商品列表 -->
            <view class="product-list">
                <view v-for="item in products" :key="item.id" class="product-card" @click="goToDetail(item)">
                    <image class="product-img" :src="item.coverImg" mode="aspectFill"></image>
                    <view>
                        <view class="product-top">
                            <view class="product-name">{{ item.comboName }}</view>
                            <view class="product-num">{{ item.num }}</view>
                        </view>
                        <view class="product-info">
                            <view class="product-remark">{{ item.remark }}</view>
                            <view class="product-bottom">
                                <view class="product-orign-price">
                                    <text class="symbol">原价¥</text>
                                    <text class="value">{{ item.orginPrice }}</text>
                                </view>
                                <view class="product-price">
                                    <text class="symbol">¥</text>
                                    <text class="value">{{ item.price }}</text>
                                </view>
                            </view>
                        </view>
                    </view>
                </view>
                <view v-if="products.length === 0" class="empty-tip">
                    暂无相关商品
                </view>
                <!-- 加载更多提示 -->
                <view class="load-more-tip" v-else>
                    <text v-if="loadStatus === 'loading'">加载中...</text>
                    <text v-else-if="loadStatus === 'noMore'">没有更多了</text>
                    <text v-else>上拉加载更多</text>
                </view>
            </view>
        </view>
    </view>
</template>
<script>
import { getKitchenTag, getKitchenBanner, getKitchenGoods } from "@/api/kitchen.js";
import TopBar from "@/components/TopBar.vue";
export default {
    components: {
        TopBar,
    },
    data() {
        return {
            banner: '',
            tags: [],
            // 新增模拟商品数据
            queryParams: {
                tagId: '',
                pageSize: 5,
                pageNumber: 1,
            },
            loadStatus: 'more', // more, loading, noMore
            products: []
        };
    },
    computed: {
        // 新增过滤逻辑
        // filteredProducts() {
        //     const selectedValues = this.tags.filter(t => t.selected).map(t => t.value);
        //     if (selectedValues.length === 0) {
        //         return this.products;
        //     }
        //     // 新增判断是否包含'全部'标签
        //     if (selectedValues.includes('all')) {
        //         return this.products;
        //     }
        //     return this.products.filter(item => selectedValues.includes(item.category));
        // }
    },
    onLoad() {
        this.initData();
    },
    onReachBottom() {
        if (this.loadStatus === 'more') {
            this.queryParams.pageNumber++;
            this.getProductList();
        }
    },
    methods: {
        async initData() {
            await getKitchenBanner().then(res => {
                if (res.statusCode === 200) {
                    this.banner = res.data.data[0].coverUrl;
                    console.log(res)
                }
            });
            await getKitchenTag().then(res => {
                if (res.statusCode === 200) {
                    if (res.data.data.length > 0) {
                        this.tags = res.data.data
                            .sort((a, b) => (a.sort || 0) - (b.sort || 0))
                            .map((item, index) => ({
                                label: item.tagName,
                                value: item.id,
                                selected: index === 0
                            }));
                    }
                }
            });
            this.queryParams.tagId = this.tags[0].value;
            this.getProductList();
        },
        getProductList() {
            if (this.loadStatus === 'loading') return;
            this.loadStatus = 'loading';
            getKitchenGoods(this.queryParams).then(res => {
                if (res.statusCode === 200) {
                    const newList = res.data.data || [];
                    if (this.queryParams.pageNumber === 1) {
                        this.products = newList;
                    } else {
                        this.products = this.products.concat(newList);
                    }
                    // 判断是否还有更多数据
                    if (newList.length < this.queryParams.pageSize) {
                        this.loadStatus = 'noMore';
                    } else {
                        this.loadStatus = 'more';
                    }
                } else {
                    this.loadStatus = 'more';
                }
            }).catch(() => {
                this.loadStatus = 'more';
            });
        },
        toggleTag(tag) {
            console.log("点击了标签:", tag);
            if (tag.selected) return; // 已经是选中状态则不重复加载
            // 将所有标签设为未选中,然后将当前点击的标签设为选中(单选逻辑)
            this.tags.forEach(t => {
                t.selected = (t.value === tag.value);
            });
            // 重置分页参数
            this.queryParams.tagId = tag.value;
            this.queryParams.pageNumber = 1;
            this.products = [];
            this.loadStatus = 'more';
            // 重新获得商品
            this.getProductList();
        },
        goToDetail(item) {
            console.log("跳转详情:", item);
            uni.navigateTo({
                url: `/pages/product/goods?id=${item.skuId}&goodsId=${item.goodsId}`
            });
        },
        topBarChange(titleObj) {
            console.log("顶部导航切换:", titleObj);
            if (titleObj.pagePath) {
                if (titleObj.pagePath.includes('home')) {
                    uni.reLaunch({
                        url: titleObj.pagePath
                    });
                } else {
                    uni.navigateTo({
                        url: titleObj.pagePath
                    });
                }
            }
        }
    }
};
</script>
<style lang="scss" scoped>
.page {
    min-height: 100vh;
    background-color: #f4f4f4;
    padding-top: 160rpx; // 增加空间,确保不与导航栏重叠
}
.banner {
    width: 100%;
    height: 450rpx;
    padding: 24rpx;
    border-radius: 24rpx;
    box-sizing: border-box;
    margin-top: 10rpx; // 额外增加一点间距
}
.banner-img {
    width: 100%;
    height: 100%;
    border-radius: 24rpx;
}
.content {
    padding: 24rpx;
}
.tags-scroll {
    width: 100%;
    white-space: nowrap;
}
.tags {
    display: flex;
    flex-wrap: nowrap;
    padding: 10rpx 0;
}
.tag {
    height: 80rpx;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 30rpx;
    color: black;
    border: 1rpx solid #e5e5e5;
    border-radius: 25rpx 25rpx 0 0;
    background-color: #f7f7f7;
    white-space: nowrap;
    flex-shrink: 0;
}
.tag.active {
    background: linear-gradient(to bottom, #d2c29e, #FFFFFF);
    border-color: linear-gradient(to bottom, #d2c29e, #FFFFFF);
}
// 新增商品列表样式
.product-list {
    display: flex;
    flex-direction: column;
    gap: 24rpx;
}
.product-card {
    background-color: #ffffff;
    border-radius: 20rpx;
    padding: 20rpx;
    box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
}
.product-img {
    background-color: #999;
    width: 100%;
    height: 350rpx;
    border-radius: 12rpx;
    flex-shrink: 0;
}
.product-info {
    flex: 1;
    margin-left: 20rpx;
    display: flex;
    align-items: center;
    justify-content: space-between;
    overflow: hidden; // 确保子元素溢出隐藏
}
.product-top {
    flex: 1;
    margin-left: 20rpx;
    display: flex;
    // flex-direction: column;
    // justify-content: space-between;
}
.product-name {
    font-size: 30rpx;
    font-weight: bold;
    color: #333;
    line-height: 1.4;
}
.product-num {
    width: 80rpx;
    border-radius: 25rpx;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 24rpx;
    margin-left: 10rpx;
    color: #ae9e7f;
    background-color: #f6f2e3;
}
.product-remark {
    font-size: 24rpx;
    color: #999;
    flex: 1; // 占据剩余空间
    margin-right: 20rpx;
    white-space: nowrap; // 不换行
    overflow: hidden; // 溢出隐藏
    text-overflow: ellipsis; // 显示省略号
}
.product-bottom {
    display: flex;
    justify-content: space-between;
    align-items: flex-end;
}
.product-orign-price {
    font-size:24rpx;
    color: #999;
    text-decoration: line-through;
}
.product-price {
    color: #ff573e;
    .symbol {
        font-size: 24rpx;
    }
    .value {
        font-size: 50rpx;
        font-weight: bold;
    }
}
.buy-btn {
    padding: 10rpx 24rpx;
    background-color: #333;
    color: #fff;
    font-size: 24rpx;
    border-radius: 30rpx;
}
.empty-tip {
    text-align: center;
    padding: 100rpx 0;
    color: #999;
    font-size: 28rpx;
}
.load-more-tip {
    text-align: center;
    padding: 30rpx 0;
    color: #999;
    font-size: 24rpx;
}
.topBar {
    position: fixed;
    top: 20rpx;
    left: 20rpx;
    z-index: 1000
}
</style>
pages/tabbar/index/home.vue
@@ -402,12 +402,14 @@
    },
    onShow() {
        getSessionId().then(res=>{
            console.log('res',JSON.stringify(res))
      if (res.code === 200){
            console.log('执行了onshow')
      if (res.statusCode === 200){
        this.pageSessionNo = res.data.data
        if(this.pageSessionNo){
          let    param = Object.assign({},this.actionParam);
          console.log("打印param",param)
          this.actionParam.sessionId = this.pageSessionNo
          console.log("打印this.actionParam",this.actionParam)
          param.sessionId = this.pageSessionNo
          userAction(param)
        }
@@ -457,7 +459,8 @@
    if (this.sendOnShow)return
    param.pageStatus = "LEAVE"
    // if (this.isNotEmpty(param.sessionId)){
      console.log("离开页面开始记录")
    console.log(param)
      console.log("onUnload离开页面开始记录")
      //TODO 页面刷新 导致onshow未执行,导致sessionId未赋值
      userAction(param)
    // }
@@ -472,8 +475,9 @@
    userAction(param)
  },
    onLoad(option) {
        console.log('触发onLoad')
        if(option.shareId){
            console.log('触发onLoad')
            this.actionParam.shareId = option.shareId;
            this.actionParam.joinType = 'SHARE'
            uni.setStorage({