cashier_admin_app/pagesCreateOrder/index/index - 副本 (2).vue

618 lines
13 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="u-wrap">
<view class="top bg-fff w-full">
<view class="u-flex u-row-between choose-user" @tap="chooseUser">
<view>
<view v-if="!user">选择用户</view>
<view class="u-flex" v-else>
<image class="headeimg" src="@/static/uni.png" mode=""></image>
<view class="u-m-l-20">{{user.name}}</view>
<view class="color-main u-m-l-10 u-font-24">{{user.isVip?'永久会员':'' }}</view>
</view>
</view>
<view class="u-flex">
<uni-icons type="right" size="20" color="#999"></uni-icons>
</view>
</view>
<view class="search u-flex u-col-center ">
<view class="u-flex-1">
<uni-search-bar bgColor="#F9F9F9" cancelButton="none" placeholder="搜索店内商品" @confirm="search"
:focus="true" v-model="searchValue">
</uni-search-bar>
</view>
<view class="u-flex">
<image src="/pagesCreateOrder/static/images/icon-saoma.svg" class="icon-saoma" mode=""></image>
</view>
</view>
</view>
<view class="u-menu-wrap">
<scroll-view scroll-y scroll-with-animation class="u-tab-view menu-scroll-view" :scroll-top="data.scrollTop"
:scroll-into-view="data.itemId">
<view v-for="(item,index) in data.tabbar" :key="index" class="u-tab-item"
:class="[data.current == index ? 'u-tab-item-active' : '']" @tap.stop="swichMenu(index)">
<text class="u-line-1">{{item.name}}</text>
</view>
</scroll-view>
<scroll-view :scroll-top="data.scrollRightTop" scroll-y scroll-with-animation class="right-box"
@scroll="rightScroll">
<view class="page-view u-p-l-24">
<view class="lingshi" @tap="toLinshi">
<uni-icons type="plus-filled" size="24" :color="color.ColorMain"></uni-icons>
<view class="u-m-t-24 color-main">临时菜</view>
</view>
<view class="class-item" :id="'item' + index" v-for="(item , index) in data.tabbar" :key="index">
<view class="item-title">
<text>{{item.name}}</text>
</view>
<view class="item-container">
<view class="thumb-box" v-for="(goodsItem, goodsIndex) in item.foods" :key="goodsIndex">
<!-- <image class="item-menu-image" :src="item1.icon" mode=""></image>
<view class="item-menu-name">{{item1.name}}</view> -->
<goods-item @chooseGuige="chooseGuige($event,index)" @add="goodsAdd($event,index)"
@reduce="goodsReduce($event,index)" :index="goodsIndex"
:data="goodsItem"></goods-item>
</view>
<template v-if="item.name==='附加费'">
<view class="addCai" @tap="surchargeShow">
<uni-icons type="plus-filled" size="24" :color="color.ColorMain"></uni-icons>
<view class="u-m-t-24 color-main">自定义添加</view>
</view>
</template>
</view>
</view>
</view>
</scroll-view>
</view>
<view class="bottom w-full">
<my-car :data="cars"></my-car>
</view>
</view>
<!-- 选择规格 -->
<guige-model @confirm="guigeConfirm" ref="chooseGuigeModel" :title="guigeModelData.title"
:data="guigeModelData.chooseGoods.skus"></guige-model>
<!-- 添加附加费 -->
<my-surcharge @confirm="surchargeConfirm" ref="surcharge" title="添加附加费"></my-surcharge>
</template>
<script setup>
import * as Api from '@/http/yskApi/Instead.js'
import {
$tbShopCategory
} from '@/http/yskApi/goods.js'
import classifyData from './classify.data.js';
import color from '@/commons/color.js';
import guigeModel from './components/guige'
import goodsItem from './components/goods-item'
import mySurcharge from './components/surcharge'
import {
onLoad,
onReady,
onShow,
onPageScroll,
onPullDownRefresh
} from '@dcloudio/uni-app';
import {
onBeforeUnmount,
computed,
reactive,
ref,
nextTick
} from 'vue';
import myCar from './components/car'
import go from '@/commons/utils/go.js';
async function init() {
const {
content
} = await $tbShopCategory({
page: 0,
size: 300
})
const category = content.reduce((prve, cur) => {
prve.push({
...cur,
childrenList: null
});
return [...prve, ...cur.childrenList];
}, []);
console.log(category);
const {records}= await Api.getGoodsLists({
page: 0,
size: 300
})
const goods=records
console.log(goods);
}
// 监听选择用户事件
let user = ref(null)
function watchChooseuser() {
uni.$off('choose-user')
uni.$on('choose-user', (data) => {
user.value = data
console.log(user.value);
})
}
watchChooseuser()
onBeforeUnmount(() => {
})
const surcharge = ref(null)
function surchargeConfirm(e) {
data.tabbar[data.tabbar.length - 1].foods.unshift({
...e,
chooseNumber: 0
})
}
function surchargeShow() {
surcharge.value.open()
}
let searchValue = ref('')
function search() {
}
function chooseUser() {
go.to('PAGES_CHOOSE_USER')
}
function toLinshi() {
go.to('PAGES_ADD_TEMP_CUISINE')
}
const chooseGuigeModel = ref(null)
const guigeModelData = reactive({
title: '',
chooseGoods: {
item: '',
skus: [{
title: '口味',
skds: [{
title: '麻辣',
id: 1
},
{
title: '中辣',
id: 2
},
{
title: '微辣',
id: 3
},
{
title: '不辣',
id: 4
},
{
title: '三鲜',
id: 5
}
]
},
{
title: '辣度',
skds: [{
title: '麻辣',
id: 1
},
{
title: '中辣',
id: 2
},
{
title: '微辣',
id: 3
},
{
title: '不辣',
id: 4
},
{
title: '三鲜',
id: 5
}
]
},
{
title: '配料',
skds: [{
title: '丸子',
id: 1
},
{
title: '五花肉',
id: 2
},
{
title: '鸡块',
id: 3
},
{
title: '排骨',
id: 4
},
{
title: '火腿',
id: 5
}
]
}
]
}
})
function chooseGuige(foodsindex, index) {
const $goods = data.tabbar[index].foods[foodsindex]
guigeModelData.title = $goods.name
chooseGuigeModel.value.open()
}
function guigeConfirm(e) {
console.log(e);
}
function goodsAdd(foodsindex, index) {
const $goods = data.tabbar[index].foods[foodsindex]
const newval = $goods.chooseNumber + 1
$goods.chooseNumber = newval
let item = cars.find(v => v.id == $goods.id)
if (item) {
item.number += 1
} else {
cars.push({
...$goods,
number: 1
})
}
}
function goodsReduce(foodsindex, index) {
const $goods = data.tabbar[index].foods[foodsindex]
const newval = $goods.chooseNumber - 1
$goods.chooseNumber = newval <= 0 ? 0 : newval
}
const cars = reactive([])
const tabbar = classifyData.map(v => {
return {
...v,
foods: v.foods.map((goods, index) => {
return {
...goods,
chooseNumber: 0,
price: Math.ceil(Math.random() * 100),
isDan: index % 2 === 0
}
})
}
})
tabbar.push({
name: '附加费',
foods: [{
name: "小费",
price: Math.ceil(Math.random() * 10),
chooseNumber: 0,
isDan: true
},
{
name: "打包费",
price: 1,
chooseNumber: 0,
isDan: true
}
]
})
const data = reactive({
scrollTop: 0, //tab标题的滚动条位置
oldScrollTop: 0,
current: 0, // 预设当前项的值
menuHeight: 0, // 左边菜单的高度
menuItemHeight: 0, // 左边菜单item的高度
itemId: '', // 栏目右边scroll-view用于滚动的id
tabbar: tabbar,
menuItemPos: [],
arr: [],
scrollRightTop: 0, // 右边栏目scroll-view的滚动条高度
timer: null, // 定时器
topZhanwei: 136 + 24
})
onReady(() => {
getMenuItemTop()
})
// 点击左边的栏目切换
async function swichMenu(index) {
if (data.arr.length == 0) {
await getMenuItemTop();
}
if (index == data.current) return;
data.scrollRightTop = data.oldScrollTop;
nextTick(function() {
data.scrollRightTop = data.arr[index] + data.topZhanwei;
data.current = index;
leftMenuStatus(index);
})
}
// 获取一个目标元素的高度
function getElRect(elClass, dataVal) {
new Promise((resolve, reject) => {
const query = uni.createSelectorQuery().in(this);
query.select('.' + elClass).fields({
size: true
}, res => {
// 如果节点尚未生成res值为null循环调用执行
if (!res) {
setTimeout(() => {
getElRect(elClass);
}, 10);
return;
}
data[dataVal] = res.height;
resolve();
}).exec();
})
}
// 观测元素相交状态
async function observer() {
tabbar.map((val, index) => {
let observer = uni.createIntersectionObserver(this);
// 检测右边scroll-view的id为itemxx的元素与right-box的相交状态
// 如果跟.right-box底部相交就动态设置左边栏目的活动状态
observer.relativeTo('.right-box', {
top: 0
}).observe('#item' + index, res => {
if (res.intersectionRatio > 0) {
let id = res.id.substring(4);
leftMenuStatus(id);
}
})
})
}
// 设置左边菜单的滚动状态
async function leftMenuStatus(index) {
data.current = index;
// 如果为0意味着尚未初始化
if (data.menuHeight == 0 || data.menuItemHeight == 0) {
await getElRect('menu-scroll-view', 'menuHeight');
await getElRect('u-tab-item', 'menuItemHeight');
}
// 将菜单活动item垂直居中
data.scrollTop = index * data.menuItemHeight + data.menuItemHeight / 2 - data.menuHeight / 2;
}
// 获取右边菜单每个item到顶部的距离
function getMenuItemTop() {
new Promise(resolve => {
let selectorQuery = uni.createSelectorQuery();
selectorQuery.selectAll('.class-item').boundingClientRect((rects) => {
// 如果节点尚未生成rects值为[](因为用selectAll所以返回的是数组),循环调用执行
if (!rects.length) {
setTimeout(() => {
getMenuItemTop();
}, 10);
return;
}
rects.forEach((rect) => {
// 这里减去rects[0].top是因为第一项顶部可能不是贴到导航栏(比如有个搜索框的情况)
data.arr.push(rect.top - rects[0].top);
resolve();
})
}).exec()
})
}
// 右边菜单滚动
async function rightScroll(e) {
data.oldScrollTop = e.detail.scrollTop;
if (data.arr.length == 0) {
await getMenuItemTop();
}
if (data.timer) return;
if (!data.menuHeight) {
await getElRect('menu-scroll-view', 'menuHeight');
}
setTimeout(() => { // 节流
data.timer = null;
// scrollHeight为右边菜单垂直中点位置
let scrollHeight = e.detail.scrollTop + data.menuHeight / 2 + data.topZhanwei / 2;
for (let i = 0; i < data.arr.length; i++) {
let height1 = data.arr[i];
let height2 = data.arr[i + 1];
// 如果不存在height2意味着数据循环已经到了最后一个设置左边菜单为最后一项即可
if (!height2 || scrollHeight >= height1 && scrollHeight < height2) {
leftMenuStatus(i);
return;
}
}
}, 10)
}
onLoad(() => {
init()
})
</script>
<style lang="scss" scoped>
.choose-user {
background: #F9F9F9;
padding: 22rpx 28rpx;
}
.search {
padding-right: 28rpx;
}
.icon-saoma {
margin-left: 20rpx;
width: 34rpx;
height: 32rpx;
}
$u-tips-color: $my-main-color;
$u-primary: $my-main-color;
$u-main-color: $my-main-color;
.u-wrap {
height: calc(100vh);
/* #ifdef H5 */
height: calc(100vh - var(--window-top));
/* #endif */
display: flex;
flex-direction: column;
}
.headeimg {
width: 60rpx;
height: 60rpx;
}
.u-menu-wrap {
flex: 1;
display: flex;
overflow: hidden;
}
.u-search-inner {
// background-color: rgb(234, 234, 234);
background-color: #fff;
border-radius: 100rpx;
display: flex;
align-items: center;
padding: 10rpx 16rpx;
}
.u-search-text {
font-size: 26rpx;
color: $u-tips-color;
margin-left: 10rpx;
}
.u-tab-view {
width: 178rpx;
height: 100%;
}
.u-tab-item {
height: 110rpx;
background: #f6f6f6;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: center;
font-size: 26rpx;
color: #444;
font-weight: 400;
line-height: 1;
}
.u-tab-item-active {
position: relative;
color: #000;
font-size: 30rpx;
font-weight: 600;
background: #fff;
}
.u-tab-item-active::before {
content: "";
position: absolute;
border-left: 4px solid $u-primary;
left: 0;
top: 0;
bottom: 0;
}
.u-tab-view {
height: 100%;
}
.addCai {
width: 250rpx;
height: 272rpx;
border-radius: 8rpx 8rpx 8rpx 8rpx;
box-sizing: border-box;
border: 4rpx solid #90BDF6;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.lingshi {
width: 250rpx;
height: 136px;
background: #FFFFFF;
border-radius: 8rpx 8rpx 8rpx 8rpx;
border: 4rpx solid #90BDF6;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
margin-bottom: 24px;
}
.right-box {
width: 572rpx;
// background-color: rgb(250, 250, 250);
background-color: rgb(255, 255, 255);
}
.page-view {
// padding: 24rpx 28rpx 24rpx 24rpx;
}
.class-item {
margin-bottom: 30rpx;
background-color: #fff;
border-radius: 8rpx;
}
.class-item:last-child {
min-height: 100vh;
}
.item-title {
font-size: 26rpx;
color: $u-main-color;
font-weight: bold;
}
.item-menu-name {
font-weight: normal;
font-size: 24rpx;
color: $u-main-color;
}
.item-container {
display: flex;
flex-wrap: wrap;
margin-top: 24rpx;
}
.thumb-box {
margin-right: 24rpx;
margin-bottom: 24rpx;
}
.item-menu-image {
width: 120rpx;
height: 120rpx;
}
</style>