This commit is contained in:
2025-04-02 10:35:17 +08:00
commit 89db955ec1
701 changed files with 91082 additions and 0 deletions

View File

@@ -0,0 +1,854 @@
<template>
<view class="page-gray color-333 u-font-28">
<template v-if="true">
<view class="block u-p-t-32 u-p-b-32" v-if="table&&table.tableId">
<view>桌位号</view>
<view class="font-bold u-font-32 u-m-t-16">
{{table.name||''}}
</view>
</view>
<view class="block">
<view class="u-p-b-24 u-m-b-24 border-bottom">
<view>选择用户</view>
<view class="u-m-t-24 u-flex u-row-between " @tap="chooseUser">
<view v-if="!user||!user.id">选择用户</view>
<view class="u-flex" v-if="user&&user.id">
<up-avatar :src="user.headImg" shape="square" :size="30"></up-avatar>
<!-- <view class="headeimg">
<image class="img" :src="user.headImg" mode=""></image>
</view> -->
<view class="u-m-l-20">
<!-- <view class="color-main u-font-24 no-wrap">{{user.isVip?'会员':'' }}</view> -->
<view class="">{{user.nickName}}</view>
</view>
<view class="u-font-24 u-m-l-30 u-text-center"><text>余额</text><text
class="color-main">{{user.amount}}</text>
</view>
<view class="u-font-24 u-m-l-30 u-text-center"><text>积分</text><text
class="color-main">{{user.accountPoints}}</text></view>
</view>
<uni-icons type="right" color="#999" size="20" bold></uni-icons>
</view>
</view>
<view class=" ">
<view>就餐类型</view>
<view class="u-m-t-24 u-flex ">
<view class="u-flex color-666">
<up-radio-group :disabled="option.type=='add'" v-model="eatTypes.active" placement="row">
<up-radio :customStyle="{marginRight: '30px'}" v-for="(item, index) in eatTypes.list"
:key="index" :label="item.name" :name="item.value">
</up-radio>
</up-radio-group>
</view>
</view>
</view>
<!-- <view class="u-p-b-24 u-m-b-24 border-bottom">
<view>就餐类型</view>
<view class="u-m-t-24 u-flex ">
<view class="u-flex color-666">
<up-radio-group :disabled="option.type=='add'" v-model="eatTypes.active" placement="row">
<up-radio :customStyle="{marginRight: '30px'}" v-for="(item, index) in eatTypes.list"
:key="index" :label="item.name" :name="item.value">
</up-radio>
</up-radio-group>
</view>
</view>
</view>
<view class=" " @tap="chooseTable">
<view>选择桌码</view>
<view class="u-m-t-24 u-flex u-row-between ">
<view>
<text v-if="table">{{table.name}}</text>
<text v-else>不选择桌台</text>
</view>
<uni-icons type="right" color="#999" size="16"></uni-icons>
</view>
</view> -->
</view>
<template v-if="user&&user.id">
<view class="block">
<view class="">
<view class="u-flex border-bottom u-p-b-24 ">
<up-avatar :src="user.headImg" shape="square" :size="60"></up-avatar>
<!-- <image class="headeimg" src="@/static/uni.png" mode=""></image> -->
<view class="u-m-l-32">
<view class="">{{user.nickName}}</view>
<view class="color-main u-font-24">{{user.isVip?'会员':'' }}</view>
</view>
</view>
<view class="u-flex u-m-t-24 u-row-between u-font-24 color-999">
<view class="u-flex">
<view>余额</view>
<view class="color-333 u-m-l-10"> {{user.amount}}</view>
</view>
<view class="u-flex">
<view>积分</view>
<view class="color-333 u-m-l-10"> {{user.accountPoints}}</view>
</view>
<view class="u-flex">
<view class="u-text-center">订单数量</view>
<view class="color-333 u-m-l-10">{{user.orderNumber||0}}</view>
</view>
</view>
</view>
</view>
</template>
<template v-if="!$shop.isTableFee">
<!-- 不免餐位费 -->
<view class="block">
<view class=" ">
<view>用餐人数</view>
<picker @change="userNumberChange" :value="userNumbers.defaultCateIndex"
:range="userNumbers.list">
<view class="u-m-t-24 u-flex u-row-between ">
<view class="color-333">{{userNumbers.defaultCateIndex*1+1+'人'}}</view>
<uni-icons type="right" color="#999" size="16"></uni-icons>
</view>
</picker>
</view>
</view>
</template>
</template>
<view class="block">
<view class="u-p-b-24 ">
<view class="font-bold">订单备注</view>
<view class="u-m-t-32 u-flex ">
<uni-easyinput type="textarea" v-model="note" placeholder="请输入备注"></uni-easyinput>
</view>
</view>
</view>
<view class="block u-m-b-0">
<view class="u-flex">
<view></view>
<view class="fen font-bold">{{goodsNumber}}</view>
<view>份菜品</view>
</view>
<view class="goods u-m-t-32">
<view class="item u-m-b-48" @click="changeGoodsSel(index)" v-for="(item,index) in goods.list"
:key="index">
<view class="u-flex u-row-between ">
<view class="u-flex">
<image class="img" :src="item.coverImg" mode=""></image>
<view class="u-m-l-32">
<view class="u-flex">
<view class="u-flex u-m-r-20" v-if="item.isWait">
<uni-tag text="等叫"
custom-style="background-color: #FFF0DF; border-color: #FFF0DF; color: #FF9F2E;">
</uni-tag>
</view>
<view class="u-m-r-20 u-flex" v-if="item.isGift">
<uni-tag text="赠送"
custom-style="background-color: #FFF0DF; border-color: #FFF0DF; color: #FF9F2E;">
</uni-tag>
</view>
<view class="u-m-r-20 u-flex" v-if="item.isPack">
<uni-tag
custom-style="background-color: #E6F0FF; border-color: #E6F0FF; color: #318AFE;"
size="small" text="打包" inverted type="success" />
</view>
<view>
{{item.name}}
</view>
</view>
<view class="u-font-24 color-999 u-m-t-10">{{item.specSnap||' '}}</view>
</view>
</view>
<view class="">
<view class=" u-relative">
<template v-if="item.isGift">
<text class="line-th color-999">{{formatPrice(item.salePrice*item.number) }}</text>
<view class="u-absolute" style="right: 0;bottom: 100%;">
<text class="font-bold">0</text>
</view>
</template>
<template v-else>
<template v-if="isVip&&item.memberPrice&&item.memberPrice*1!=item.salePrice*1">
<text
class="line-th color-999">{{formatPrice(item.salePrice*item.number) }}</text>
<view class="u-absolute" style="right: 0;bottom: 100%;">
<text class="font-bold">{{formatPrice(item.memberPrice*item.number) }}</text>
</view>
</template>
<template v-else>
<view class="font-bold">
<text></text>
<text class="">{{formatPrice(item.salePrice*item.number) }}</text>
</view>
</template>
</template>
</view>
<view class="color-999 u-text-right u-font-24 u-m-t-12">×{{item.number}}</view>
</view>
</view>
<template v-if="item.note">
<view class="u-p-20 bg-gray u-m-t-16">
{{item.note}}
</view>
</template>
<scroll-view class="u-m-t-32" scroll-x="true" v-if="index==goods.sel">
<view class=" u-flex no-wrap ">
<!-- <view class="u-flex u-m-r-20 u-m-b-20">
<button class="tag" hover-class="hover-class" @tap="showModel('discount')">单品打折</button>
</view> -->
<view class="u-flex u-m-r-20 ">
<!-- <button class="tag" hover-class="hover-class" @tap="showModel('giveFood')">赠菜</button> -->
<button class="tag" hover-class="hover-class"
@tap="toggleGoodsItemKey(item,index,'isGift')">{{item.isGift?'取消赠送':'赠送'}}</button>
</view>
<view class="u-flex u-m-r-20 ">
<button class="tag" hover-class="hover-class"
@tap="toggleGoodsItemKey(item,index,'isPack')">{{item.isPack?'取消打包':'打包'}}</button>
</view>
<!-- <view class="u-flex u-m-r-20 u-m-b-20">
<button class="tag" hover-class="hover-class"
@tap="toggleWait(item)">{{item.isWait?'取消等叫':'等叫'}}</button>
</view> -->
<view class="u-flex u-m-r-20 ">
<button class="tag" hover-class="hover-class"
@tap="showModel('remark',index)">单品备注</button>
</view>
</view>
</scroll-view>
</view>
</view>
<view class="border-bottom">
<template v-if="$seatFee&&$seatFee.totalAmount">
<view class="u-flex u-row-between u-m-t-18 u-p-b-34 ">
<view>
<text>桌位费</text>
</view>
<view>{{$seatFee.totalAmount||'0.00'}}</view>
</view>
</template>
<template v-if="$packFee>0">
<view class="u-flex u-row-between u-m-t-18 u-p-b-34 ">
<view>
<text>打包费</text>
</view>
<view>{{$packFee||'0.00'}}</view>
</view>
</template>
</view>
<view class="u-flex u-row-between u-m-t-38">
<!-- <template v-if="$shop.registerType=='munchies'">
<view class="color-main" @tap="showModel('editMoney')">修改</view>
</template> -->
<view class="u-flex">
<view class="u-flex price" v-if="youhui*1>0">
<view class="">优惠金额</view>
<view class="font-bold u-font-32">{{formatPrice(youhui) }}</view>
</view>
</view>
<view class="u-flex price u-m-l-32">
<view class="">实收金额</view>
<view class="font-bold u-font-32">{{formatPrice(allPrice) }}</view>
</view>
</view>
</view>
<view :style="{height:bottomHeight+'px'}"></view>
<view class="safe-bottom fixed">
<!-- <view class="u-m-b-48">
<label class="radio">
<radio value="" class="scale7" /><text>打印预结算</text>
</label>
</view> -->
<view class="btn ">
<my-button shape="circle" @click="createOrder">
<view class="font-bold u-font-32">
{{($shop.registerType=='munchies'||eatTypes.active=='takeout')?'结算': '下单'}}
</view>
</my-button>
</view>
</view>
<model-discount title="菜品打折/减免" :ref="setModel" name="discount" :price="allPrice"></model-discount>
<give-food title="赠菜" :ref="setModel" name="giveFood"></give-food>
<one-remark @confirm="goodsOneRemarkConfirm" title="单品备注" :ref="setModel" name="remark"></one-remark>
<edit-discount title="优惠金额" :ref="setModel" name="editMoney" :price="allPrice"></edit-discount>
</view>
</template>
<script setup>
import {
onLoad,
onReady,
onShow
} from '@dcloudio/uni-app'
import {
ref,
onBeforeUnmount,
reactive,
computed,
watch
} from 'vue';
import {
getSafeBottomHeight
} from '@/commons/utils/safe-bottom.js'
import modelDiscount from './components/discount'
import giveFood from './components/give-food'
import oneRemark from './components/remark'
import editDiscount from '@/pagesCreateOrder/components/edit-discount.vue'
import go from '@/commons/utils/go.js';
import {
returnBoolean
} from '@/commons/utils/format.js';
import color from '@/commons/color.js';
import * as Api from '@/http/yskApi/Instead.js'
import $storageManage from '@/commons/utils/storageManage.js'
import {
tbShopInfo
} from '@/http/yskApi/user.js'
import {
getNowCart
} from '@/pagesCreateOrder/util.js'
import {
hasPermission
} from '@/commons/utils/hasPermission.js'
const models = new Map();
const modelData = reactive({
data: {},
selIndex: -1
})
//备注
let note = ref('')
function setModel(el) {
if (el && el.$attrs['name']) {
models.set(el.$attrs['name'], el);
}
}
function showModel(key, index) {
modelData.data = goods.list[index]
modelData.selIndex = index
const model = models.get(key)
model && model.open({
remark: modelData.data.note || ''
})
}
function formatPrice(n) {
return Number(n).toFixed(2)
}
//用餐人数
const userNumbers = reactive({
list: new Array(100).fill(1).map((v, index) => {
// return index === 0 ? '无' : index + '人'
return (index + 1) + '人'
}),
defaultCateIndex: 0,
})
watch(() => userNumbers.defaultCateIndex, (newval) => {
updateChoseCount()
})
//更新就餐人数
async function updateChoseCount() {
console.log($shop.value);
const maxCapacity = table.value.tableId ? (table.value.maxCapacity || 0) : 100
if (table.value.tableId && userNumbers.defaultCateIndex * 1 + 1 > maxCapacity) {
uni.showToast({
title: '当前台桌最大人数为: ' + maxCapacity
})
userNumbers.defaultCateIndex = maxCapacity - 1
return
}
if (!$shop.value.isTableFee && table.value.tableId) {
//不免餐位费
const res = await Api.$choseCount({
masterId: option.masterId,
tableId: table.value.tableId || '',
num: userNumbers.defaultCateIndex * 1 + 1,
})
Object.assign($seatFee, res)
userNumbers.defaultCateIndex = res.totalNumber - 1
}
}
function userNumberChange(e) {
console.log(e);
userNumbers.defaultCateIndex = e.detail.value
}
const form = reactive({})
//切换商品状态
async function toggleGoodsItemKey(item, index, key) {
const {
productId,
skuId,
id,
number,
isPack,
isGift
} = item
const par = {
cartId: id,
isPack,
isGift,
masterId: option.masterId,
tableId: table.value.tableId || '',
productId,
num: number,
skuId
}
par[key] = !item[key]
const res = await Api.$updateCart(par)
goods.list[index][key] = returnBoolean(res[key])
if (key == 'isPack') {
getCart()
}
}
//等叫
function toggleWait(item) {
item.isWait = !item.isWait
}
const eatTypes = reactive({
list: [{
name: "堂食",
value: "dine-in",
},
{
name: "自取",
value: "takeout",
}
],
active: 'dine-in'
})
const $packFee = computed(() => {
return goods.list.reduce((prve, cur) => {
return prve + cur.packFee
}, 0).toFixed(2)
})
function chooseUser() {
go.to('PAGES_CHOOSE_USER')
}
function chooseTable() {
go.to('PAGES_CHOOSE_TABLE', {
...table.value
})
}
const option = reactive({
masterId: '',
tableId: ""
})
// 监听选择用户事件
let user = ref(null)
//更新选择用户
function setUser(par) {
console.log(option);
const submitPar = {
masterId: option.masterId,
tableId: table.value.tableId || "",
vipUserId: user.value.id ? user.value.id : '',
type: user.value.id ? 0 : 1 //0 设置 1 取消
}
Object.assign(submitPar, par)
return Api.$setUser(submitPar)
}
function watchChooseuser() {
uni.$off('choose-user')
uni.$on('choose-user', (data) => {
console.log(data);
user.value = data
setUser()
})
}
let table = ref(null)
//监听桌台改变
watch(() => table.value, (newval, oldval) => {
if (newval && oldval) {
// Api.$choseTable({
// orderId: 4462,
// oldTableId: oldval.tableId,
// newTableId: newval.tableId,
// })
}
})
function watchChooseTable() {
uni.$off('choose-table')
uni.$on('choose-table', (data) => {
table.value = data
console.log(table.value);
})
}
const goods = reactive({
list: [],
sel: 0
})
const goodsNumber = computed(() => {
const result = goods.list.reduce((prve, cur) => {
return prve + cur.number
}, 0)
return result
})
//餐位费
const $seatFee = reactive({
totalNumber: 0,
totalAmount: 0,
})
const isVip=computed(()=>{
return $shop.value.isMemberPrice&& user.value&&user.value.id&&user.value.isVip
})
const goodsPrice = computed(() => {
const goodsTotalPrice = goods.list.reduce((prve, cur) => {
const memberPrice=cur.memberPrice?cur.memberPrice:cur.salePrice
const tPrice = (isVip.value? memberPrice:cur.salePrice) * cur.number
const tpackFee = cur.isPack ? cur.packFee * 1 : 0
return prve + (cur.isGift ? 0 : tPrice) + tpackFee
}, 0)
return (goodsTotalPrice || 0).toFixed(2)
})
const allPrice = computed(() => {
console.log(goodsPrice.value);
const n = goodsPrice.value * 1 + $seatFee.totalAmount
return n.toFixed(2)
// const goodsTotalPrice = goods.list.reduce((prve, cur) => {
// return prve + cur.salePrice * cur.number * (cur.isGift ? 0 : 1)
// }, 0)
// return (goodsTotalPrice + ($seatFee.totalAmount || 0)).toFixed(2)
})
const youhui=computed(()=>{
if(user.value&&user.value.id&&user.value.isVip){
const goodsTotalPrice = goods.list.reduce((prve, cur) => {
const tPrice = cur.salePrice * cur.number
const tpackFee = cur.isPack ? cur.packFee * 1 : 0
return prve + tPrice + tpackFee
}, 0)
return goodsTotalPrice-allPrice.value
}else{
return 0
}
return goodsTotalPrice
})
function setGoodsItem(key, val) {
item[key] = val
}
function changeGoodsSel(index) {
goods.sel = index
}
//获取购物车数据
async function getCart(par = {
page: 0,
size: 300,
masterId: option.masterId,
tableId: table.value.tableId || ''
}) {
const {
records,
seatFee
} = await Api.getCart(par)
let useType=''
if (seatFee && seatFee.useType) {
useType=seatFee.useType
$storageManage.useType(useType)
}else{
useType=records[0].info[0].useType
$storageManage.useType(useType)
}
console.log(useType);
eatTypes.active =useType == 'takeout' ? useType : useType.replace(
/-after|-before/g, '');
goods.list = getNowCart(records)
if (seatFee && seatFee.totalNumber) {
userNumbers.defaultCateIndex = seatFee.totalNumber - 1 || 0
Object.assign($seatFee, seatFee)
} else {
$seatFee.totalAmount = 0
}
console.log(userNumbers.defaultCateIndex);
}
let $shop = ref({
registerType: ''
})
// 获取账号信息
async function getTbShopInfo() {
const res = await tbShopInfo()
$shop.value = res
console.log(res);
return res
}
// 创建订单
async function createOrder(par = {
masterId: option.masterId,
vipUserId: user.value ? user.value.id : '',
note: note.value,
postPay: true,
orderId: '',
tableId: table.value.tableId || ''
}) {
if (!$shop.value.isTableFee) {
//不免餐位费
await Api.$choseCount({
masterId: option.masterId,
tableId: table.value.tableId || "",
num: userNumbers.defaultCateIndex + 1,
})
}
if ($shop.value.registerType == 'munchies' || eatTypes.active == 'takeout') {
const canJiesuan = await hasPermission('允许收款')
if (!canJiesuan) {
return
}
}
// updateChoseCount()
const res = await Api.$createOrder(par)
uni.$emit('update:createOrderIndex')
console.log($shop.value);
console.log(res);
if ($shop.value.registerType == 'munchies' || eatTypes.active == 'takeout') {
//先付
return go.to('PAGES_ORDER_PAY', {
orderId: res.id,
isNowPay: true
}, 'redirect')
} else {
//后付
console.log(option.isCreateOrderToDetail);
if (option.isCreateOrderToDetail != '0') {
console.log('PAGES_ORDER_DETAIL');
go.to('PAGES_ORDER_DETAIL', {
id: res.id
}, 'redirect')
} else {
console.log('back');
uni.navigateBack({
delta: 2
})
}
// return go.to('PAGES_ORDER_DETAIL', {
// id: res.id
// })
}
uni.showToast({
title: '提交成功',
icon: 'none'
})
// setTimeout(() => {
// uni.$emit('orderDetail:update')
// uni.navigateBack({
// delta: 2
// })
// }, 500)
}
//单品备注确认
async function goodsOneRemarkConfirm(e) {
const cart = goods.list[modelData.selIndex]
await Api.$updateCart({
cartId: cart.id,
productId: cart.productId,
skuId: cart.skuId,
tableId: option.tableId || "",
note: e.remark,
num: cart.number // 0会删除此商品
})
cart.note = e.remark
}
async function init() {
await getTbShopInfo()
await getCart()
console.log($seatFee);
if (!$seatFee.totalNumber) {
updateChoseCount()
}
}
onLoad((opt) => {
Object.assign(option, opt)
console.log(opt);
if (opt) {
table.value = {
...option,
tableId: opt.tableId || '',
name: opt.name
}
userNumbers.list = new Array(opt.maxCapacity ? opt.maxCapacity * 1 : 100).fill(1).map((v, index) => {
return (index + 1) + '人'
})
// console.log(userNumbers.list);
}
init()
// updateChoseCount()
})
let bottomHeight = ref(100)
onReady(() => {
getSafeBottomHeight('safe-bottom').then(res => {
console.log(res);
bottomHeight.value = res
})
})
async function changeUseType() {
const {
registerType
} = $shop.value
//munchies 先付 restaurant 后付
const isPayAfter = registerType == "munchies" ? false : true;
let useType = "takeout";
if (eatTypes.active == "takeout") {
uni.setStorageSync("useType", "takeout");
} else {
//堂食
useType = `dine-in-${isPayAfter? "after" : "before"}`;
uni.setStorageSync("useType", useType);
}
const tableId = useType == 'takeout' ? undefined : table.value.tableId;
if (!goods.list.length) {
return
}
const res = await Api.$changeUseType({
useType,
tableId: tableId || '',
cartIds: goods.list.map((v) => v.id),
})
getCart()
return res
}
watch(() => eatTypes.active, (newval) => {
changeUseType()
})
onBeforeUnmount(() => {
})
onShow(() => {
watchChooseuser()
watchChooseTable()
})
</script>
<style lang="scss" scoped>
.fen {
color: #FF9F2E;
}
.page-gray {
padding: 32rpx 28rpx 0 28rpx;
}
.headeimg {
width: 84rpx;
height: 84rpx;
border-radius: 12rpx 12rpx 12rpx 12rpx;
}
.block {
background-color: #fff;
padding: 32rpx 24rpx;
border-radius: 18rpx;
margin-bottom: 32rpx;
}
.textarea {
border-radius: 12rpx 12rpx 12rpx 12rpx;
padding: 32rpx 0 32rpx 24rpx;
border: 1px solid #999999;
overflow: hidden;
}
.goods {
// padding-bottom: 30rpx;
border-bottom: 1px dashed #E5E5E5;
.item {
.img {
width: 84rpx;
height: 84rpx;
border-radius: 8rpx 8rpx 8rpx 8rpx;
}
}
}
.headeimg {
width: 60rpx;
height: 60rpx;
display: flex;
background-color: #eee;
border-radius: 12rpx;
overflow: hidden;
.img {
width: 60rpx;
height: 60rpx;
}
}
.price {
color: #EB4F4F;
}
.opacity0 {
opacity: 0;
}
.fixed {
position: fixed;
}
.safe-bottom {
padding: 34rpx 28rpx;
background-color: #fff;
left: 0;
right: 0;
bottom: 0;
z-index: 10;
.btn {
padding: 0 88rpx 56rpx 88rpx;
}
}
.tag {
background-color: #fff;
border: 1px solid #E5E5E5;
line-height: inherit;
font-size: 24rpx;
color: #666666;
padding: 6rpx 16rpx;
border-radius: 100rpx;
}
.hover-class {
background-color: #E5E5E5;
}
</style>