ReedawFoodApp/Food/me/menudetail.vue

724 lines
16 KiB
Vue
Raw Normal View History

2026-03-23 16:23:40 +08:00
<template>
<view class="content addFood" :class="[isBle?'maxheight':'']">
<!-- 封面 -->
<view class="topimg">
<image :src="info.cover_pic_url" mode="aspectFill"></image>
</view>
<!-- 信息 -->
<view class="title">
<view class="table">{{info.title}}</view>
<view class="user">
<view class="left">
<image :src="info.create_user_head_pic"></image>
<text>{{info.create_user_nickname}}</text>
</view>
<view class="right">
<uni-icons :type="info.collect_status=='yes'?'heart-filled':'heart'" size="20"
:color="info.collect_status=='yes'?'red':'#999'"></uni-icons>
<text class="ml-5">{{info.likes_num}}</text>
</view>
</view>
</view>
<view class="title title2">
<view class="">菜谱类型</view>
<view>{{menu[cookIndex].name}}</view>
</view>
<!-- 食材 -->
<view class="food">
<view class="desc">
{{info.description}}
</view>
<view class="h4">
<view class="tags">
<view class="tags-item" :class="[index ==ind?'active':'']" v-for="(item,ind) in info.tags"
:key="ind" @click="handleToggle(ind)">{{item.title}}</view>
</view>
<view class="close" @click="handleWeight">
<image src="../../static/lianjie.png"></image>
连接测量
</view>
</view>
<view class="foodlist">
<view class="item" v-for="(ite,ind) in info.tags[index].list" :key="ind"
v-if="info.tags&&info.tags[index].list.length">
<view class="name" style="flex: 1;">{{ite.name}}</view>
<view class="weight">
{{ite.weight}}{{ite.unit}}
</view>
</view>
</view>
</view>
<!-- 步骤 -->
<view class="step">
<view class="stepList" v-for="(ite,ind) in info.step_list" :key="ind"
v-if="info.step_list&&info.step_list.length">
<view class="top">
<text>{{ite.step_num}}</text>
</view>
<view class="right">
<view class="desc">
{{ite.description}}
</view>
<view class="image" v-for="(it,id) in ite.pic_url_list">
<image :src="it" mode="aspectFill" class="mt-10"></image>
</view>
</view>
</view>
</view>
<!-- 底部操作 -->
<view class="foot">
<view class="item" @click="handleCang()">
<uni-icons :type="info.collect_status=='yes'?'heart-filled':'heart'" size="20"
:color="info.collect_status=='yes'?'red':'#999'"></uni-icons>
<text>收藏</text>
</view>
<!-- <view class="item" v-if="type=='我的菜谱'" @click="handleEdit()">
<icon class="iconfont icon-bianji"></icon>
<text>编辑</text>
</view>
<view class="item" v-if="type=='我的菜谱'" @click="handledel()">
<icon class="iconfont icon-ashbin"></icon>
<text>删除</text>
</view> -->
</view>
<!--蓝牙连接区 -->
<view class="wrapper" v-if="isBle">
<view class="bg" @click="isBle = false">
<view class="box weightBox">
<icon class="iconfont icon-error" @click='isBle = false'></icon>
<view class="foodlist" @click.stop>
<view class="text">
<text style="width: 30%;">食材</text>
<text style="width: 18%;">建议</text>
<view class="kcal">
<text>重量</text>
<text>热量</text>
<text>重秤</text>
</view>
</view>
<view class="item" v-for="(ite,ind) in info.tags[0].list" :key="ind"
v-if="info.tags&&info.tags[0].list.length"
:class="[activeType.id&&activeType.id ==ite.id&&!ite.newweight?'active2':'']">
<view class="name">{{ite.name}}</view>
<view class="num" style="width: 18%;">
{{ite.weight}}{{ite.unit}}
</view>
<view class="kcal" v-if="activeType.id&&activeType.id ==ite.id&&!ite.newweight">
正在测量...
</view>
<view class="kcal" v-else>
<view class="num" v-if="ite.newweight">
{{ite.newweight}}{{ite.newunit}}
</view>
<view class="num" v-if="ite.newkcal">
{{ite.newkcal}}
</view>
<view class="refreshempty
" @click="handlechongzhi(ite,ind)" v-if="ite.newweight">
<uni-icons type="refreshempty" size="22"></uni-icons>
</view>
</view>
</view>
</view>
<view class="blue-tooth" :style="{display: (!isWeightType&&iSWeightSub) ? '' : 'none'}" @click.stop>
<blue-tooth ref="blueTooth" @handleDetailNext="handleDetailNext"
@handleDetailSub="handleDetailSub" :weightKcal="weightKcal" :name="activeType.name"
:isLast="isLast" />
</view>
</view>
</view>
</view>
<view class="saveFood" v-if="showSaveFood">
<view class="saveFoodInner">
<view class="title">是否保存至计食为今日饮食</view>
<view class="types">
<view class="type-item" :class="{'active':selectSaveType == index}" v-for="(item,index) in foodItem"
:key="index" @click="selectSaveType=index">{{item.name}}</view>
</view>
<view class="btn-wrap">
<view class="confirm" @click="confirmSaveFood">确定</view>
<view class="cancel" @click="showSaveFood=false">取消</view>
</view>
</view>
</view>
</view>
</template>
<script>
import {
mapState
} from "vuex";
import blueTooth from "@/components/foodIndex/bluetooth.vue"
export default {
data() {
return {
type: "",
info: {},
id: null,
index: 0,
isLast: false,
weightKcal: null,
weightType: 0,
activeType: {},
isBle: false,
isWeightType: true,
iSWeightSub: true,
listInd: 0,
cookIndex: null,
showSaveFood: false,
selectSaveType: 0
}
},
computed: {
...mapState(["user", "configInfo", "bleValue"]),
menu() {
return this.configInfo.cookbook_label
},
foodItem() {
return this.configInfo.meal_list
},
endDate() {
return this.$tools.getDate("start")
},
},
components: {
blueTooth
},
onLoad(options) {
let that = this
let info = {}
if (options && options.info) {
info = JSON.parse(options.info)
that.type = info.pageName
that.info = info
} else {
that.type = options.title
}
that.id = options.id
that.handleHomeInfo(options.id)
},
methods: {
handleToggle(ind) {
this.index = ind
},
handleHomeInfo(id) {
let that = this
that.$model.getCookListDetails({
cookbook_id: id,
aud_id: that.user.aud_id
}).then(res => {
if (res.code != 0) return
that.info = res.data
console.log("11111111",that.menu,res.data.cook_label)
that.cookIndex = that.menu.findIndex(ite => ite.id == res.data.cook_label)
if (that.bleValue.serviceId != '') {
that.handleWeight()
}
})
},
//连接测量
handleWeight() {
let that = this
if (that.isBle) {
return
}
that.listInd = 0
that.isBle = true
that.isLast = false
that.iSWeightSub = true
that.isWeightType = false
that.activeType = that.info.tags[0].list[0]
that.weightKcal = Number(Number(that.activeType.kcal) / 100).toFixed(2)
if (that.info.tags[0].list.length == 1) {
that.isLast = true
}
},
// 下一位
handleDetailNext(weight, dw, kcal) {
let that = this
let ind = that.info.tags[0].list.findIndex(ite => ite.id == that.activeType.id)
that.info.tags[0].list[ind].newweight = weight
that.info.tags[0].list[ind].newunit = dw
that.info.tags[0].list[ind].newkcal = kcal
that.listInd = that.listInd + 1
that.activeType = that.info.tags[0].list[ind + 1]
that.weightKcal = Number(Number(that.activeType.kcal) / 100).toFixed(2)
that.info.tags[0].list[that.listInd].newweight = ""
that.info.tags[0].list[that.listInd].newunit = ""
that.info.tags[0].list[that.listInd].newkcal = ""
if (that.listInd == that.info.tags[0].list.length - 1 || that.listInd == that.info.tags[0].list.length) {
that.isLast = true
console.log('已经测量完成')
}
},
// 结束测量
handleDetailSub(weight, dw, kcal) {
let that = this
let ind = that.info.tags[0].list.findIndex(ite => ite.id == that.activeType.id)
that.info.tags[0].list[ind].newweight = weight
that.info.tags[0].list[ind].newunit = dw
that.info.tags[0].list[ind].newkcal = kcal
that.showSaveFood = true
},
//重置
handlechongzhi(ite, ind) {
let that = this
let weight = that.info.tags[0].list[ind].newweight
that.listInd = ind
that.isLast = false
that.activeType = ite
that.weightKcal = Number(Number(ite.kcal) / 100).toFixed(2)
that.info.tags[0].list[ind].newweight = ""
that.info.tags[0].list[ind].newunit = ""
that.info.tags[0].list[ind].newkcal = ""
if (that.listInd == that.info.tags[0].list.length - 1 || that.listInd == that.info.tags[0].list.length) {
that.isLast = true
}
},
//保存测量结果到计时器
confirmSaveFood() {
let that = this
let newFoodList = []
for (let i = 0; i < that.info.tags[0].list.length; ++i) {
if (that.info.tags[0].list[i].newweight) {
newFoodList.push({
meals_type: that.foodItem[that.selectSaveType].name,
id: that.info.tags[0].list[i].id,
weight: that.info.tags[0].list[i].newweight,
unit: that.info.tags[0].list[i].newunit
})
}
}
console.log("newFoodList", that.info.tags[0].list, newFoodList)
if (newFoodList.length > 0) {
that.$model.getAddIntakeFood({
aud_id: that.user.aud_id,
food_list: newFoodList,
time: that.$tools.getDate("start")
}).then(res => {
if (res.code != 0) return
2026-03-25 17:27:29 +08:00
that.$store.dispatch("getCountFoodInfo", {
aud_id: that.user.aud_id,
time: that.$tools.getDate("start")
})
2026-03-23 16:23:40 +08:00
uni.showToast({
title: '保存成功',
icon: 'success'
})
2026-03-25 17:27:29 +08:00
that.$store.commit("changehomeCard", 1);
uni.switchTab({
url: "/pages/index/index"
})
2026-03-23 16:23:40 +08:00
})
}
that.showSaveFood = false
that.iSWeightSub = false
that.isBle = false
},
handleCang() {
let that = this
that.$model.getCookLike({
cookbook_id: that.id,
aud_id: that.user.aud_id
}).then(res => {
if (res.code != 0) return
that.info.likes_num = res.data.likes_num
that.info.collect_status = res.data.collect_status
})
},
handleEdit() {
uni.navigateTo({
url: "/Food/me/menuEdit?info=" + JSON.stringify(this.info)
})
},
handledel() {
let that = this
uni.showModal({
title: '友情提示',
content: '是否删除当前菜谱?',
success: function(res) {
if (res.confirm) {
that.$model.getMyCookbookDel({
aud_id: that.user.aud_id,
cookbook_id: that.id,
}).then((res) => {
if (res.code != 0) {
that.$tools.msg(res.message)
return
}
that.$tools.msg("删除成功")
uni.navigateBack()
})
} else if (res.cancel) {
that.$tools.msg("您已取消操作!");
}
},
})
}
}
}
</script>
<style lang="scss" scoped>
.content {
padding: 0 30rpx;
}
.maxheight {
max-height: 90vh !important;
overflow: hidden;
}
.topimg {
width: 100%;
height: 340rpx;
background: #fff;
border-radius: 20rpx;
display: flex;
justify-content: center;
align-items: center;
flex-wrap: wrap;
flex-direction: column;
margin: 20rpx 0;
overflow: hidden;
position: relative;
.iconfont {
font-size: 60rpx;
color: $maincolor;
}
text {
display: inline-block;
width: 100%;
text-align: center;
color: #999;
}
.text {
font-size: 16px;
color: #666;
margin-bottom: 3px;
}
image {
width: 100%;
height: inherit;
}
}
.step {
.image {
height: 340rpx;
margin: auto;
background: #f7f7f7;
border-radius: 20rpx;
display: flex;
justify-content: center;
align-items: center;
flex-wrap: wrap;
flex-direction: column;
overflow: hidden;
image {
width: 100%;
height: inherit;
display: inline-table;
}
icon {
font-size: 60rpx;
color: #ff4c4f;
margin-bottom: 5px;
}
}
}
.title {
padding: 20rpx;
.table {
font-size: 16px;
font-weight: bold;
}
.user {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 30rpx;
.left {
display: flex;
align-items: center;
image {
width: 50rpx;
height: 50rpx;
margin-right: 5px;
border-radius: 50%;
}
}
.right {
display: flex;
}
}
}
.desc {
width: 100%;
line-height: 50rpx;
margin-bottom: 20rpx;
}
.h4 {
margin: 20rpx 0;
padding-top: 20rpx;
border-top: 1px solid #f7f7f7;
.tags {
flex: 1;
display: flex;
justify-content: space-around;
.tags-item {
border-bottom: 2px solid transparent;
}
.active {
border-bottom: 2px solid #ff4c4f;
}
}
.close {
color: #fff;
width: 100px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 20rpx;
background-color: $maincolor;
image {
width: 50rpx;
height: 50rpx;
}
}
}
.step {
margin-bottom: 85px;
}
.foodlist {
border-radius: 20rpx;
background: #fff;
.item {
margin-top: 0 !important;
border-radius: 0px !important;
border-bottom: 1px solid #f7f7f7;
}
.name {
border-right: none !important;
}
}
.foot {
position: fixed;
bottom: 0;
left: 0;
right: 0;
background: #fff;
display: flex;
justify-content: space-between;
padding: 5px 0px 40rpx;
border-radius: 20rpx 20rpx 0 0;
box-shadow: 0px 1px 5px 2px #dfe2e1fc;
.item {
width: 25%;
display: flex;
flex-wrap: wrap;
justify-content: center;
icon,
image {
width: 22px;
height: 22px;
font-size: 22px;
}
text {
display: inline-block;
text-align: center;
width: 100%;
}
}
}
//
.weightBox {
top: 40px;
background: #dfdfdf;
.icon-error {
position: absolute;
right: 20rpx;
top: -40rpx;
background: #fff;
font-size: 80rpx;
width: 80rpx;
height: 80rpx;
border-radius: 50%;
}
.foodlist {
border-radius: 0;
height: 40%;
overflow: scroll;
padding: 10px;
border-radius: 10px;
margin-top: 30rpx;
font-size: 14px;
.text {
width: 100%;
font-weight: bold;
display: flex;
height: 80rpx;
line-height: 80rpx;
justify-content: space-between;
}
.item {
display: flex;
align-items: center;
height: 80rpx;
line-height: 80rpx;
font-size: 28rpx;
justify-content: space-between;
}
.name {
width: calc(30% - 10px);
text-align: left !important;
white-space: nowrap;
overflow-x: auto;
font-weight: inherit;
font-size: 28rpx;
margin-right: 10px;
}
.kcal {
width: 52% !important;
display: flex;
justify-content: space-between;
}
}
.blue-tooth {
background: #fff;
border-radius: 10px;
margin-top: 15px;
position: relative;
height: 50%;
}
.groupbtn {
position: absolute;
left: 30rpx;
right: 30rpx;
width: auto;
bottom: 100rpx;
}
}
.saveFood {
display: flex;
justify-content: center;
align-items: center;
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.7);
z-index: 99999;
.saveFoodInner {
display: flex;
flex-direction: column;
align-items: center;
width: 80%;
padding: 30rpx 20rpx;
padding-bottom: 0;
background-color: #fff;
border-radius: 20rpx;
.title {
font-size: 36rpx;
text-align: center;
}
.types {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
margin-top: 30rpx;
width: 100%;
.type-item {
width: 22%;
height: 50rpx;
line-height: 50rpx;
text-align: center;
font-size: 28rpx;
border: 1px solid #f1f1f1;
border-radius: 10rpx;
margin-bottom: 30rpx;
&.active {
border-color: #ff4c4f;
}
}
}
.btn-wrap {
display: flex;
width: 100%;
margin-top: 30rpx;
border-top: 1px solid #f1f1f1;
view {
width: 50%;
height: 80rpx;
line-height: 80rpx;
text-align: center;
font-size: 32rpx;
}
view:first-child {
border-right: 1px solid #f1f1f1;
}
}
}
}
.active2 {
color: #8284f0;
font-weight: bold;
background: #ecedff;
}
.title2 {
display: flex;
align-items: center;
justify-content: space-between;
}
</style>