处理开台

This commit is contained in:
2026-01-11 01:49:45 +08:00
parent 9e957d5dea
commit a14a51d575
26 changed files with 2495 additions and 297 deletions

View File

@@ -2,26 +2,67 @@
<view class="page-content">
<view style="z-index: 10000;position: sticky;" :style="'top:0px'">
<view class="top-bar">
<nut-button type="primary" block @click="navigateTo('/pages/index/orderAdd')">
<nut-button type="primary" block @click="navigateTo('/pages/index/orderAdd')">
新增商品订单
</nut-button>
</view>
</view>
<nut-grid :column-num="2" square>
<nut-grid-item v-for="(room, index) in rooms" :key="index">
<view class="grid-item-content">
<view class="room-name">{{room.name}}</view>
<view class="room-footer">
<view class="room-id">尾号: 111111</view>
<view class="remark">备注: 这是一段北湖这是一段北湖这是一段北...</view>
</view>
<view class="buttons">
<nut-button type="primary">预约</nut-button>
<nut-button type="success">开台</nut-button>
<!-- 使用flex布局 -->
<view class="room-grid">
<view v-for="(room, index) in rooms" :key="index" class="room-grid-item" :style="getRoomStyle(room.status)">
<view class="room-grid-card">
<view class="grid-item-content">
<view class="room-name">{{room.room_name}}</view>
<view class="room-info">
<view class="room-id" v-if="room.tel">尾号: {{room.tel}}</view>
<view class="remark" v-if="room.remarks">备注: {{room.remarks}}</view>
</view>
<view class="room-buttons">
<view v-if="room.status === 1">
<nut-button size="small" type="primary" shape="square"
@click="onBooking(room)">预约</nut-button>
</view>
<view v-else-if="room.status === 2">
<nut-button size="small" type="warning" plain shape="square"
@click="onUnBooking(room)">取消预约</nut-button>
</view>
<view v-if="room.status === 3">
<nut-button size="small" type="info" plain shape="square"
@click="navigateTo(`/pages/index/orderEdit?roomId=${room.id}`)">详情</nut-button>
</view>
<view v-else>
<nut-button size="small" type="success" plain shape="square"
@click="navigateTo(`/pages/index/orderAdd?roomId=${room.id}`)">开台</nut-button>
</view>
</view>
</view>
</view>
</nut-grid-item>
</nut-grid>
</view>
</view>
<!-- 弹出 -->
<nut-popup :custom-style="{ height: '60%' }" v-model:visible="visiblePopup" position="bottom"
safe-area-inset-bottom :close-on-click-overlay="true" @close="onClosePopup">
<view>
<view class="title">{{tempRoom?.room_name}} </view>
<nut-form>
<nut-form-item label="尾号">
<nut-input v-model="form.tel" placeholder="请输入尾号"></nut-input>
</nut-form-item>
<nut-form-item label="备注">
<nut-textarea v-model="form.remarks" :rows="3" :adjust-keyboard-to="bottom"
placeholder="请输入备注"></nut-textarea>
</nut-form-item>
</nut-form>
<view style=" padding: 0rpx 80rpx;">
<nut-button type="primary" block @click="onSubmit">
预约
</nut-button>
</view>
</view>
</nut-popup>
</view>
</template>
@@ -37,43 +78,111 @@
onLoad,
onShow,
} from '@dcloudio/uni-app'
import {
navigateTo,
import {
fetchRooms,
fetchBooking,
fetchUnBooking
} from '@/api/index';
import {
navigateTo,
} from '@/utils/helper'
const form = reactive({
room_id: 0,
tel: '',
remarks: ''
})
// 房间列表
const rooms = [{
name: '房间名称 1'
},
{
name: '房间名称 2'
},
{
name: '房间名称 3'
},
{
name: '房间名称 4'
},
{
name: '房间名称 5'
},
{
name: '房间名称 6'
},
{
name: '房间名称 7'
},
{
name: '房间名称 8'
},
{
name: '房间名称 9'
const rooms = ref([]);
const getRoomStyle = (status) => {
let backgroundColor = '';
let borderColor = '';
switch (status) {
case 1: // 空闲/可用
backgroundColor = '#d9d9d9';
break;
case 2: // 已预约
backgroundColor = '#ffa39e';
break;
case 3: // 已占用
backgroundColor = '#b7eb8f';
break;
// case 4: // 打扫中
// backgroundColor = '#f0f5ff';
// borderColor = '#adc6ff';
// break;
default: // 默认
backgroundColor = '#d9d9d9';
}
];
return {
'background-color': backgroundColor,
};
}
const visiblePopup = ref(false)
const tempRoom = reactive({})
const onBooking = (room) => {
console.log("----", room);
Object.assign(tempRoom, room)
form.room_id = room.id
visiblePopup.value = true
}
const onClosePopup = () => {
Object.assign(tempRoom, {})
Object.assign(form, {
room_id: 0,
tel: '',
remarks: ''
})
visiblePopup.value = false
console.log("关闭");
};
const getRooms = () => {
console.log("房间");
fetchRooms().then(res => {
console.log(res);
rooms.value = res;
})
}
// 预约
const onSubmit = () => {
fetchBooking(form).then(res => {
console.log(res);
uni.showToast({
icon: 'none',
title: '预约成功'
})
onClosePopup()
getRooms()
})
}
// 取消预约
const onUnBooking = (room) => {
fetchUnBooking({
id: room.id
}).then(res => {
console.log(res);
uni.showToast({
icon: 'none',
title: '取消预约成功'
})
getRooms()
})
}
const init = () => {
console.log('init');
getRooms()
}
onShow(() => {
console.log("onshow---");
getRooms()
});
onMounted(() => {
init();
})
</script>
<style scoped lang="scss">
@@ -83,6 +192,9 @@
}
.top-bar {
background: #fff;
align-items: center;
@@ -91,6 +203,25 @@
}
/* Grid布局 - 每行两列 */
.room-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
/* 两列等宽 */
gap: 20rpx;
/* 间距 */
padding: 20rpx;
background: #f5f5f5;
}
.room-grid-item {
border-radius: 16rpx;
// overflow: hidden;
// background: white;
// box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
// position: relative;
}
.grid-item-content {
display: flex;
flex-direction: column;
@@ -98,33 +229,64 @@
justify-content: space-between;
height: 100%;
text-align: center;
}
.room-name {
font-size: 32rpx;
// margin-bottom: 20rpx;
}
.room-name {
font-size: 32rpx;
padding: 20rpx 0;
text-align: center;
}
.room-footer {
margin: 20rpx 0;
color: #666;
.room-id {
font-size: 26rpx;
margin-bottom: 10rpx;
}
.remark {
font-size: 24rpx;
padding: 10rpx;
text-align: center;
.room-info {
text-align: left;
padding: 20rpx 10rpx;
color: #666;
width: 100%;
min-height: 160rpx;
box-sizing: border-box;
.room-id {
font-size: 24rpx;
}
.remark {
font-size: 24rpx;
display: -webkit-box;
/* 使元素成为伸缩容器 */
-webkit-box-orient: vertical;
/* 设置伸缩方向为纵向 */
overflow: hidden;
/* 隐藏超出的内容 */
-webkit-line-clamp: 2;
/* 限制显示2行 */
line-height: 36rpx;
word-wrap: break-word;
/* 强制长单词或长数字换行 */
word-break: break-word;
/* 强制长单词或长数字换行 */
white-space: normal;
/* 确保文本正常换行 */
/* 设置行高 */
}
}
.room-buttons {
padding: 20rpx 10rpx;
display: flex;
gap: 20rpx;
justify-content: space-around;
width: 100%;
box-sizing: border-box;
}
}
.buttons {
display: flex;
gap: 16rpx;
.title {
padding: 0 20rpx;
margin-top: 20rpx;
margin-bottom: 20rpx;
font-size: 28rpx;
font-weight: 400;
text-align: center;
}
</style>

View File

@@ -0,0 +1,618 @@
<template>
<view class="page-content">
<view style=" padding: 10rpx;">
<view class="title">基础台费 </view>
<nut-form>
<!-- <nut-form-item>
<template v-slot:label>房间</template>
<template v-slot:default>
<view style="color: black;" @click="visibleRoomsPopup = true">
<text>{{form.room_name}}</text>
</view>
</template>
</nut-form-item> -->
<!-- 台费类型套餐支付状态 三者在同一行布局 -->
<view class="inline-form">
<!-- 台费类型选择 -->
<nut-form-item label-position="top">
<template v-slot:label>结算方式</template>
<template v-slot:default>
<view style="color: black;" @click="visibleFeeTypePopup = true">
<text>{{form.fee_type_name}}</text>
</view>
</template>
</nut-form-item>
<!-- 套餐选择 -->
<nut-form-item label-position="top" v-if="form.fee_type === 1 || form.fee_type === 2">
<template v-slot:label>选择团购</template>
<template v-slot:default>
<view style="color: black;" @click="visibleCombosPopup = true">
<text>{{form.fee_combo_name}}</text>
</view>
</template>
</nut-form-item>
<!-- 金额输入框 -->
<nut-form-item label-position="top" v-else>
<template v-slot:label>线下收款</template>
<template v-slot:default>
<nut-input v-model="form.fee_amount" placeholder="请输入金额" type="number" />
</template>
</nut-form-item>
<!-- 支付状态选择 -->
<nut-form-item label-position="top">
<template v-slot:label>支付状态</template>
<template v-slot:default>
<view style="color: black;" @click="openPayStatusPopup('fee')">
<text>{{form.fee_pay_status_txt}}</text>
</view>
</template>
</nut-form-item>
</view>
</nut-form>
<view class="title">超时收费 </view>
<nut-form>
<!-- 台费类型套餐支付状态 三者在同一行布局 -->
<view class="inline-form">
<!-- 台费类型选择 -->
<nut-form-item label-position="top">
<template v-slot:label>时长(小时)</template>
<template v-slot:default>
<nut-input v-model="form.often" placeholder="请输入小时" type="number" />
</template>
</nut-form-item>
<!-- 金额输入框 -->
<nut-form-item label-position="top">
<template v-slot:label>超时金额</template>
<template v-slot:default>
<nut-input v-model="form.over_amount" placeholder="请输入金额" type="number" />
</template>
</nut-form-item>
<!-- 支付状态选择 -->
<nut-form-item label-position="top">
<template v-slot:label>支付状态</template>
<template v-slot:default>
<view style="color: black;" @click="openPayStatusPopup('over')">
<text>{{form.over_pay_status_txt}}</text>
</view>
</template>
</nut-form-item>
</view>
</nut-form>
<view class="title">商品 </view>
<view class="top-bar">
<nut-button type="primary" plain size="small" @click="addGoods">新增商品</nut-button>
</view>
<nut-form>
<!-- 台费类型套餐支付状态 三者在同一行布局 -->
<view class="inline-goods-form" v-for="(item, index) in orderGoods" :key="index">
<view class="form-row">
<!-- 台费类型选择 -->
<nut-form-item label-position="top">
<template v-slot:label>商品</template>
<template v-slot:default>
<view style="color: black;" @click="visibleGoodsCascader = true;goodsIndex = index">
<text v-if="item.goods_type_name && item.goods_name">
{{ item.goods_type_name }} - {{ item.goods_name }}
</text>
<text v-else>请选择商品</text>
</view>
</template>
</nut-form-item>
<!-- 套餐选择 -->
<nut-form-item label-position="top">
<template v-slot:label>售价</template>
<template v-slot:default>
<view style="color: black;">
<text>{{item.goods_price}}</text>
</view>
</template>
</nut-form-item>
</view>
<view class="form-row">
<!-- 支付状态选择 -->
<nut-form-item label-position="top">
<template v-slot:label>支付状态</template>
<template v-slot:default>
<view style="color: black;" @click="openPayStatusPopup('goods',index)">
<text>{{item.goods_pay_status_txt}}</text>
</view>
</template>
</nut-form-item>
<!-- 套餐选择 -->
<nut-form-item label-position="top">
<template v-slot:label>操作</template>
<template v-slot:default>
<view>
<nut-button type="danger" size="mini" @click="removeGoods(index)">删除商品</nut-button>
</view>
</template>
</nut-form-item>
</view>
</view>
</nut-form>
<view class="title">订单优惠 </view>
<nut-form>
<nut-form-item>
<template v-slot:label>优惠金额</template>
<template v-slot:default>
<nut-input v-model="form.discount_amount" placeholder="请输入金额" type="number" />
</template>
</nut-form-item>
</nut-form>
<view style="align-items: center;text-align: center; padding: 20rpx 60rpx;">
<nut-button type="primary" block @click="submitForm">
保存订单
</nut-button>
</view>
</view>
<nut-cascader title="商品选择" v-model:visible="visibleGoodsCascader" v-model="cascaderGoodsValue"
@change="onGoodsChange" @pathChange="onGoodsPathChange" text-key="label" value-key="value"
children-key="children" :options="selectGoods" :title-ellipsis="false" @open="onOpenGoodsCascader"
@close="onCloseGoodsCascader"></nut-cascader>
<!-- v-model="popupPaymentStatusVal" -->
<nut-popup v-model:visible="visiblePaymentStatusPopup" position="bottom" safe-area-inset-bottom>
<nut-picker :columns="paymentStatuses" :field-names="{text:'label',value:'value'}" title="选择支付状态"
@confirm="onConfirmPaymentStatus" @cancel="visiblePaymentStatusPopup = false">
</nut-picker>
</nut-popup>
<nut-popup v-model:visible="visibleCombosPopup" position="bottom" safe-area-inset-bottom>
<nut-picker v-model="popupCombosVal" :columns="combos" :field-names="{text:'label',value:'value'}"
title="选择团购套餐" @confirm="onConfirmCombos" @cancel="visibleCombosPopup = false">
</nut-picker>
</nut-popup>
<!-- v-model="popupFeeTypeVal" -->
<nut-popup v-model:visible="visibleFeeTypePopup" position="bottom" safe-area-inset-bottom>
<nut-picker :columns="feeTypes" :field-names="{text:'label',value:'value'}" title="选择结算方式"
@confirm="onConfirmFeeType" @cancel="visibleFeeTypePopup = false">
</nut-picker>
</nut-popup>
<!-- <nut-popup v-model:visible="visibleRoomsPopup" position="bottom" safe-area-inset-bottom>
<nut-picker v-model="popupRoomsVal" :columns="rooms" :field-names="{text:'label',value:'value'}"
title="选择房间" @confirm="onConfirmRoom" @cancel="visibleRoomsPopup = false">
</nut-picker>
</nut-popup> -->
</view>
</template>
<script setup>
import {
computed,
onMounted,
reactive,
ref,
toValue
} from 'vue';
import {
fetchCombos,
fetchGoods,
} from '@/api/index';
// // 选择房间弹窗
// const visibleRoomsPopup = ref(false);
// // 选中的房间
// const popupRoomsVal = ref([])
// // 房间列表
// const rooms = [{
// value: 1,
// label: '房间 101'
// },
// {
// value: 2,
// label: '房间 102'
// },
// {
// value: 3,
// label: '房间 103'
// }
// ];
// // 选择房间
// const onConfirmRoom = (selectedValue) => {
// console.log(selectedValue);
// form.room_name = selectedValue.selectedOptions[0].label
// form.room_id = selectedValue.selectedOptions[0].value
// console.log(form);
// visibleRoomsPopup.value = false
// }
// 选择房间弹窗
const visibleFeeTypePopup = ref(false);
// 台费结算类型
// const popupFeeTypeVal = ref([])
// 台费类型选择列表
const feeTypes = [{
value: 1,
label: '美团'
},
{
value: 2,
label: '抖音'
},
{
value: 3,
label: '线下'
}
];
// 选择房间
const onConfirmFeeType = (selectedValue) => {
console.log(selectedValue);
form.fee_type_name = selectedValue.selectedOptions[0].label
form.fee_type = selectedValue.selectedOptions[0].value
console.log(form);
if (form.fee_type !== 3) {
getCombos();
}
visibleFeeTypePopup.value = false
}
const getCombos = () => {
console.log("获取套餐");
fetchCombos({
type: form.fee_type
}).then(res => {
console.log(res);
combos.value = res;
})
}
// 选择套餐弹窗
const visibleCombosPopup = ref(false);
// 选中的套餐
const popupCombosVal = ref([])
// 套餐列表
const combos = ref([]);
// 选择套餐
const onConfirmCombos = (selectedValue) => {
console.log(selectedValue);
form.fee_combo_name = selectedValue.selectedOptions[0].label
form.fee_combo_id = selectedValue.selectedOptions[0].value
console.log(form);
visibleCombosPopup.value = false
}
// 支付状态弹窗
const visiblePaymentStatusPopup = ref(false);
// 选中的支付状态
const popupPaymentStatusVal = ref([])
// 支付类型
const popupPaymentTypeVal = ref('')
// 支付状态
const paymentStatuses = [{
value: 1,
label: '已付'
},
{
value: 2,
label: '未付'
},
{
value: 3,
label: '赠送'
}
];
const openPayStatusPopup = (type, index = -1) => {
popupPaymentTypeVal.value = type
goodsPayIndex.value = index // 只有type = goods 生效
visiblePaymentStatusPopup.value = true
console.log(type);
}
const onConfirmPaymentStatus = (selectedValue) => {
if (popupPaymentTypeVal.value == 'fee') {
form.fee_pay_status_txt = selectedValue.selectedOptions[0].label
form.payment_status = selectedValue.selectedOptions[0].value
}
if (popupPaymentTypeVal.value == 'over') {
form.over_pay_status_txt = selectedValue.selectedOptions[0].label
form.over_pay_status = selectedValue.selectedOptions[0].value
}
if (popupPaymentTypeVal.value == 'goods' && goodsPayIndex.value >= 0) {
console.log("处理商品支付状态", goodsPayIndex.value);
orderGoods.value[goodsPayIndex.value].goods_pay_status_txt = selectedValue.selectedOptions[0].label
orderGoods.value[goodsPayIndex.value].goods_pay_status = selectedValue.selectedOptions[0].value
}
console.log(form);
visiblePaymentStatusPopup.value = false
popupPaymentTypeVal.value = ''
goodsPayIndex.value = -1
}
// 订单商品列表
const orderGoods = ref([
// {
// goods_type_name: null,
// goods_type_id: null,
// goods_name: null,
// goods_id: null,
// goods_price: null,
// goods_pay_status: 0,
// goods_pay_status_txt: "请选择",
// cascader_val: []
// },
])
// 当前操作的商品
const goodsPayIndex = ref(0)
// 当前操作的商品
const goodsIndex = ref(0)
// 添加规则
const addGoods = () => {
console.log(orderGoods.value);
orderGoods.value.push({
goods_type_name: null,
goods_type_id: null,
goods_name: null,
goods_id: null,
goods_price: null,
goods_pay_status: 0,
goods_pay_status_txt: "请选择",
cascader_val: []
})
}
// 删除商品
const removeGoods = (index) => {
orderGoods.value.splice(index, 1)
}
// 显示商品选择
const visibleGoodsCascader = ref(false)
// 商品选中
const cascaderGoodsValue = computed(() => {
let cascader_val = [];
if (goodsIndex.value >= 0) {
return orderGoods.value[goodsIndex.value]?.cascader_val ?? []
} else {
return cascader_val;
}
});
const onGoodsChange = (...args) => {
console.log("onGoodsChange", args);
}
// 选择商品
const onGoodsPathChange = (args) => {
console.log("onGoodsPathChange", args);
console.log("goodsIndex", goodsIndex.value);
console.log("orderGoods.value[goodsIndex.value]", orderGoods.value[goodsIndex.value]);
orderGoods.value[goodsIndex.value].goods_type_name = null
orderGoods.value[goodsIndex.value].goods_type_id = null
orderGoods.value[goodsIndex.value].goods_name = null
orderGoods.value[goodsIndex.value].goods_id = null
orderGoods.value[goodsIndex.value].goods_price = null
if (args.length >= 1 && args[0] !== null) {
orderGoods.value[goodsIndex.value].goods_type_name = args[0].text
orderGoods.value[goodsIndex.value].goods_type_id = args[0].value
}
if (args.length >= 2 && args[1] !== null) {
orderGoods.value[goodsIndex.value].goods_name = args[1].text
orderGoods.value[goodsIndex.value].goods_id = args[1].value
orderGoods.value[goodsIndex.value].goods_price = args[1].goods_price
}
console.log("orderGoods.value[goodsIndex.value]", orderGoods.value[goodsIndex.value]);
}
const onCloseGoodsCascader = () => {
console.log("onCloseGoodsCascader");
console.log("goodsIndex.value", goodsIndex.value);
if (orderGoods.value[goodsIndex.value].goods_type_id && orderGoods.value[goodsIndex.value].goods_id) {
orderGoods.value[goodsIndex.value].cascader_val = [
orderGoods.value[goodsIndex.value].goods_type_id,
orderGoods.value[goodsIndex.value].goods_id
]
}
goodsIndex.value = 0
console.log("goodsIndex.value", goodsIndex.value);
}
const onOpenGoodsCascader = () => {
console.log("onOpenGoodsCascader");
console.log("goodsIndex.value", goodsIndex.value);
}
const form = reactive({
// room_id: 0,
// room_name: '选择房间',
fee_type: 0,
fee_type_name: '选择方式',
fee_combo_id: 0, // 套餐费用ID
fee_combo_name: '请选择', // 套餐费用名称
fee_amount: null, // 线下支付费用
fee_pay_status: 0, // 费用支付状态
fee_pay_status_txt: '请选择', // 费用支付状态
over_often: null, // 超时小时
over_amount: null, // 超时金额
over_pay_status: 0, // 超时支付状态
over_pay_status_txt: "请选择", // 超时支付状态
discount_amount: null, // 优惠金额
})
const selectGoods = ref([])
onMounted(() => {
fetchGoods().then(res => {
selectGoods.value = res;
})
})
// 提交表单
const submitForm = () => {
// const formData = {
// room: room.value,
// feeType: feeType.value,
// selectedPackage: selectedPackage.value,
// amount: amount.value,
// paymentStatus: paymentStatus.value
// };
console.log('提交的订单数据:', orderGoods.value);
};
</script>
<style lang="scss" scoped>
.page-content {
min-height: 100vh;
background-color: #f2f3f5;
}
.title {
padding: 0 20rpx;
margin-top: 20rpx;
margin-bottom: 20rpx;
font-size: 28rpx;
// font-weight: 400;
color: #909ca4;
}
.inline-form {
display: flex;
justify-content: space-between;
gap: 10rpx;
/* 在元素之间添加间距 */
}
.top-bar {
background: #fff;
padding: 20rpx;
display: flex;
justify-content: space-between;
border-top: 1px solid #eee;
// position: sticky;
// bottom: 0;
// z-index: 999;
}
/* 每个商品项容器 */
.inline-goods-form {
// box-sizing: border-box;
}
/* 行容器 */
.form-row {
display: flex;
justify-content: space-between;
align-items: flex-start;
gap: 20rpx;
margin-bottom: 20rpx;
}
// .inline-goods-form {
// display: flex;
// justify-content: space-between;
// gap: 10rpx;
// /* 在元素之间添加间距 */
// }
// .inline-goods-form {
// display: flex;
// flex-wrap: nowrap;
// /* 防止换行 */
// align-items: flex-start;
// gap: 10rpx;
// margin-bottom: 20rpx;
// padding: 20rpx;
// background-color: #f8f9fa;
// border-radius: 16rpx;
// box-sizing: border-box;
// overflow: hidden;
// /* 防止溢出 */
// }
// /* 关键为每个表单项设置适当的flex属性 */
// .inline-goods-form .nut-form-item {
// flex: 1; /* 平均分配空间 */
// min-width: 0; /* 重要:允许内容收缩 */
// max-width: 100%; /* 防止溢出 */
// word-break: break-word; /* 文本换行 */
// overflow: hidden; /* 隐藏溢出内容 */
// }
// /* 确保内部元素不会撑开 */
// .inline-goods-form .nut-form-item__body {
// width: 100%;
// overflow: hidden;
// }
// /* 调整按钮大小 */
// .inline-goods-form .nut-button {
// max-width: 100%;
// white-space: nowrap;
// overflow: hidden;
// text-overflow: ellipsis;
// }
// .inline-goods-form {
// display: flex;
// flex-wrap: wrap; /* 确保元素在不足的宽度时换行 */
// justify-content: space-between;
// gap: 10rpx; /* 设置每个表单项之间的间距 */
// width: 100%;
// // box-sizing: border-box;
// }
// .inline-goods-form-item-50 {
// flex: 0 0 50% !important; /* 第一个表单项占 50% */
// }
// .inline-goods-form-item-25 {
// flex: 0 0 25% !important; /* 其他两个表单项各占 25% */
// }
// .inline-item {
// flex: 1;
// display: flex;
// flex-direction: column;
// }
</style>

View File

@@ -167,7 +167,7 @@
<view style="align-items: center;text-align: center; padding: 20rpx 60rpx;">
<nut-button type="primary" block @click="submitForm">
保存订单
开台
</nut-button>
</view>
</view>
@@ -218,11 +218,27 @@
toValue
} from 'vue';
import {
onLoad,
onShow,
onHide
} from '@dcloudio/uni-app';
import {
fetchCombos,
fetchGoods,
fetchAddOrder,
} from '@/api/index';
onLoad(options => {
console.log('onLoad');
// 获取房间ID
form.room_id = options.roomId
console.log(form);
console.log(options);
})
// // 选择房间弹窗
// const visibleRoomsPopup = ref(false);
@@ -277,29 +293,31 @@
form.fee_type_name = selectedValue.selectedOptions[0].label
form.fee_type = selectedValue.selectedOptions[0].value
console.log(form);
if (form.fee_type !== 3) {
getCombos();
}
visibleFeeTypePopup.value = false
}
const getCombos = () => {
console.log("获取套餐");
fetchCombos({
type: form.fee_type
}).then(res => {
console.log(res);
combos.value = res;
})
}
// 选择套餐弹窗
const visibleCombosPopup = ref(false);
// 选中的套餐
const popupCombosVal = ref([])
// 套餐列表
const combos = [{
value: 1,
label: '美团中包套餐'
},
{
value: 2,
label: '美团小包套餐'
},
{
value: 3,
label: '美团小包套餐'
},
];
const combos = ref([]);
// 选择套餐
const onConfirmCombos = (selectedValue) => {
console.log(selectedValue);
@@ -308,8 +326,6 @@
console.log(form);
visibleCombosPopup.value = false
}
// 支付状态弹窗
const visiblePaymentStatusPopup = ref(false);
// 选中的支付状态
@@ -342,7 +358,7 @@
if (popupPaymentTypeVal.value == 'fee') {
form.fee_pay_status_txt = selectedValue.selectedOptions[0].label
form.payment_status = selectedValue.selectedOptions[0].value
form.fee_pay_status = selectedValue.selectedOptions[0].value
}
if (popupPaymentTypeVal.value == 'over') {
form.over_pay_status_txt = selectedValue.selectedOptions[0].label
@@ -353,7 +369,6 @@
orderGoods.value[goodsPayIndex.value].goods_pay_status_txt = selectedValue.selectedOptions[0].label
orderGoods.value[goodsPayIndex.value].goods_pay_status = selectedValue.selectedOptions[0].value
}
console.log(form);
visiblePaymentStatusPopup.value = false
popupPaymentTypeVal.value = ''
@@ -363,18 +378,18 @@
// 订单商品列表
const orderGoods = ref([
// {
// goods_type_name: null,
// goods_type_id: null,
// goods_name: null,
// goods_id: null,
// goods_price: null,
// goods_pay_status: 0,
// goods_pay_status_txt: "请选择",
// cascader_val: []
// },
])
const orderGoods = ref([
// {
// goods_type_name: null,
// goods_type_id: null,
// goods_name: null,
// goods_id: null,
// goods_price: null,
// goods_pay_status: 0,
// goods_pay_status_txt: "请选择",
// cascader_val: []
// },
])
// 当前操作的商品
const goodsPayIndex = ref(0)
// 当前操作的商品
@@ -454,11 +469,10 @@
const form = reactive({
// room_id: 0,
// room_name: '选择房间',
order_type: 1, // 开台订单
room_id: 0,
fee_type: 0,
fee_type_name: '选择方式',
fee_type_name: '选择',
fee_combo_id: 0, // 套餐费用ID
fee_combo_name: '请选择', // 套餐费用名称
fee_amount: null, // 线下支付费用
@@ -476,6 +490,7 @@
})
// 商品列表
const selectGoods = ref([])
onMounted(() => {
fetchGoods().then(res => {
@@ -494,7 +509,17 @@
// amount: amount.value,
// paymentStatus: paymentStatus.value
// };
console.log('提交的订单数据:', orderGoods.value);
let data = {
order_goods: orderGoods.value,
order: form
}
console.log('提交的订单数据:', data);
// console.log('提交的订单数据:', form);
fetchAddOrder(data).then(res => {
console.log(res);
// selectGoods.value = res;
})
};
</script>
@@ -547,72 +572,4 @@
gap: 20rpx;
margin-bottom: 20rpx;
}
// .inline-goods-form {
// display: flex;
// justify-content: space-between;
// gap: 10rpx;
// /* 在元素之间添加间距 */
// }
// .inline-goods-form {
// display: flex;
// flex-wrap: nowrap;
// /* 防止换行 */
// align-items: flex-start;
// gap: 10rpx;
// margin-bottom: 20rpx;
// padding: 20rpx;
// background-color: #f8f9fa;
// border-radius: 16rpx;
// box-sizing: border-box;
// overflow: hidden;
// /* 防止溢出 */
// }
// /* 关键为每个表单项设置适当的flex属性 */
// .inline-goods-form .nut-form-item {
// flex: 1; /* 平均分配空间 */
// min-width: 0; /* 重要:允许内容收缩 */
// max-width: 100%; /* 防止溢出 */
// word-break: break-word; /* 文本换行 */
// overflow: hidden; /* 隐藏溢出内容 */
// }
// /* 确保内部元素不会撑开 */
// .inline-goods-form .nut-form-item__body {
// width: 100%;
// overflow: hidden;
// }
// /* 调整按钮大小 */
// .inline-goods-form .nut-button {
// max-width: 100%;
// white-space: nowrap;
// overflow: hidden;
// text-overflow: ellipsis;
// }
// .inline-goods-form {
// display: flex;
// flex-wrap: wrap; /* 确保元素在不足的宽度时换行 */
// justify-content: space-between;
// gap: 10rpx; /* 设置每个表单项之间的间距 */
// width: 100%;
// // box-sizing: border-box;
// }
// .inline-goods-form-item-50 {
// flex: 0 0 50% !important; /* 第一个表单项占 50% */
// }
// .inline-goods-form-item-25 {
// flex: 0 0 25% !important; /* 其他两个表单项各占 25% */
// }
// .inline-item {
// flex: 1;
// display: flex;
// flex-direction: column;
// }
</style>

626
pages/index/orderEdit.vue Normal file
View File

@@ -0,0 +1,626 @@
<template>
<view class="page-content">
<view style=" padding: 10rpx;">
<view class="title">基础台费 </view>
<nut-form>
<!-- 台费类型套餐支付状态 三者在同一行布局 -->
<view class="inline-form">
<!-- 台费类型选择 -->
<nut-form-item label-position="top">
<template v-slot:label>结算方式</template>
<template v-slot:default>
<view style="color: black;" @click="visibleFeeTypePopup = true">
<text>{{form.fee_type_name}}</text>
</view>
</template>
</nut-form-item>
<!-- 套餐选择 -->
<nut-form-item label-position="top" v-if="form.fee_type === 1 || form.fee_type === 2">
<template v-slot:label>选择团购</template>
<template v-slot:default>
<view style="color: black;" @click="visibleCombosPopup = true">
<text>{{form.fee_combo_name}}</text>
</view>
</template>
</nut-form-item>
<!-- 金额输入框 -->
<nut-form-item label-position="top" v-else>
<template v-slot:label>线下收款</template>
<template v-slot:default>
<nut-input v-model="form.fee_amount" placeholder="请输入金额" type="number" />
</template>
</nut-form-item>
<!-- 支付状态选择 -->
<nut-form-item label-position="top">
<template v-slot:label>支付状态</template>
<template v-slot:default>
<view style="color: black;" @click="openPayStatusPopup('fee')">
<text>{{form.fee_pay_status_txt}}</text>
</view>
</template>
</nut-form-item>
</view>
</nut-form>
<view class="title">超时收费 </view>
<nut-form>
<!-- 台费类型套餐支付状态 三者在同一行布局 -->
<view class="inline-form">
<!-- 台费类型选择 -->
<nut-form-item label-position="top">
<template v-slot:label>时长(小时)</template>
<template v-slot:default>
<nut-input v-model="form.over_often" placeholder="请输入小时" type="number" />
</template>
</nut-form-item>
<!-- 金额输入框 -->
<nut-form-item label-position="top">
<template v-slot:label>超时金额</template>
<template v-slot:default>
<nut-input v-model="form.over_amount" placeholder="请输入金额" type="number" />
</template>
</nut-form-item>
<!-- 支付状态选择 -->
<nut-form-item label-position="top">
<template v-slot:label>支付状态</template>
<template v-slot:default>
<view style="color: black;" @click="openPayStatusPopup('over')">
<text>{{form.over_pay_status_txt}}</text>
</view>
</template>
</nut-form-item>
</view>
</nut-form>
<view class="title">商品 </view>
<view class="top-bar">
<nut-button type="primary" plain size="small" @click="addGoods">新增商品</nut-button>
</view>
<nut-form>
<!-- 台费类型套餐支付状态 三者在同一行布局 -->
<view class="inline-goods-form" v-for="(item, index) in orderGoods" :key="index">
<view class="form-row">
<!-- 台费类型选择 -->
<nut-form-item label-position="top">
<template v-slot:label>商品</template>
<template v-slot:default>
<view style="color: black;" @click="visibleGoodsCascader = true;goodsIndex = index">
<text v-if="item.goods_type_name && item.goods_name">
{{ item.goods_type_name }} - {{ item.goods_name }}
</text>
<text v-else>请选择商品</text>
</view>
</template>
</nut-form-item>
<!-- 套餐选择 -->
<nut-form-item label-position="top">
<template v-slot:label>售价</template>
<template v-slot:default>
<view style="color: black;">
<text>{{item.goods_price}}</text>
</view>
</template>
</nut-form-item>
</view>
<view class="form-row">
<!-- 支付状态选择 -->
<nut-form-item label-position="top">
<template v-slot:label>支付状态</template>
<template v-slot:default>
<view style="color: black;" @click="openPayStatusPopup('goods',index)">
<text>{{item.goods_pay_status_txt}}</text>
</view>
</template>
</nut-form-item>
<!-- 套餐选择 -->
<nut-form-item label-position="top">
<template v-slot:label>操作</template>
<template v-slot:default>
<view>
<nut-button type="danger" size="mini" @click="removeGoods(index)">删除商品</nut-button>
</view>
</template>
</nut-form-item>
</view>
</view>
</nut-form>
<view class="title">订单优惠 </view>
<nut-form>
<nut-form-item>
<template v-slot:label>优惠金额</template>
<template v-slot:default>
<nut-input v-model="form.discount_amount" placeholder="请输入金额" type="number" />
</template>
</nut-form-item>
</nut-form>
<view style="align-items: center;text-align: center; padding: 20rpx 60rpx;">
<nut-button type="primary" block @click="submitForm">
开台
</nut-button>
</view>
</view>
<nut-cascader title="商品选择" v-model:visible="visibleGoodsCascader" v-model="cascaderGoodsValue"
@change="onGoodsChange" @pathChange="onGoodsPathChange" text-key="label" value-key="value"
children-key="children" :options="selectGoods" :title-ellipsis="false" @open="onOpenGoodsCascader"
@close="onCloseGoodsCascader"></nut-cascader>
<!-- v-model="popupPaymentStatusVal" -->
<nut-popup v-model:visible="visiblePaymentStatusPopup" position="bottom" safe-area-inset-bottom>
<nut-picker :columns="paymentStatuses" :field-names="{text:'label',value:'value'}" title="选择支付状态"
@confirm="onConfirmPaymentStatus" @cancel="visiblePaymentStatusPopup = false">
</nut-picker>
</nut-popup>
<nut-popup v-model:visible="visibleCombosPopup" position="bottom" safe-area-inset-bottom>
<nut-picker v-model="popupCombosVal" :columns="combos" :field-names="{text:'label',value:'value'}"
title="选择团购套餐" @confirm="onConfirmCombos" @cancel="visibleCombosPopup = false">
</nut-picker>
</nut-popup>
<!-- v-model="popupFeeTypeVal" -->
<nut-popup v-model:visible="visibleFeeTypePopup" position="bottom" safe-area-inset-bottom>
<nut-picker :columns="feeTypes" :field-names="{text:'label',value:'value'}" title="选择结算方式"
@confirm="onConfirmFeeType" @cancel="visibleFeeTypePopup = false">
</nut-picker>
</nut-popup>
<!-- <nut-popup v-model:visible="visibleRoomsPopup" position="bottom" safe-area-inset-bottom>
<nut-picker v-model="popupRoomsVal" :columns="rooms" :field-names="{text:'label',value:'value'}"
title="选择房间" @confirm="onConfirmRoom" @cancel="visibleRoomsPopup = false">
</nut-picker>
</nut-popup> -->
</view>
</template>
<script setup>
import {
computed,
onMounted,
reactive,
ref,
toValue
} from 'vue';
import {
onLoad,
onShow,
onHide
} from '@dcloudio/uni-app';
import {
fetchCombos,
fetchGoods,
fetchAddOrder,
fetchRoomOrder,
} from '@/api/index';
onLoad(options => {
console.log('onLoad');
// 获取房间ID
form.room_id = options.roomId
getRoomOrder()
console.log(form);
console.log(options);
})
const getRoomOrder = () => {
fetchRoomOrder(form.room_id).then(res => {
console.log(res);
form.room_id = res.room_id
form.order_type = res.order_type
form.fee_type = res.fee_type.value
form.fee_type_name = res.fee_type.text
form.fee_combo_id = res.fee_combo_id
form.fee_combo_name = res.fee_combo_name
form.fee_amount = res.fee_amount
form.fee_pay_status = res.fee_pay_status.value
form.fee_pay_status_txt = res.fee_pay_status.text
form.over_often = res.over_often
form.over_amount = res.over_amount
form.over_pay_status = res.over_pay_status.value
form.over_pay_status_txt = res.over_pay_status.text
// is_show_edit.value = true;
// console.log("====>", res);
// form.goods_id = res.goods_id
// form.goods_name = res.goods_name
// form.goods_no = res.goods_no
// form.goods_price = res.goods_price
// // form.goods_stock = res.goods_stock
// form.content = res.content
// form.details_content = res.details_content
// form.status = res.status.value.toString()
// form.degree_id = res.degree?.degree_id ?? 0
// form.degree_name = res.degree?.degree_name ?? '未选择'
// form.type_id = res.type?.type_id ?? 0
// form.type_name = res.type?.name ?? '未选择'
// form.brand_id = res.brand?.brand_id ?? 0
// form.brand_name = res.brand?.name ?? '未选择'
// form.product_id = res.product?.product_id ?? 0
// form.product_name = res.product?.name ?? '未选择'
// popup_degree_val.value = [res.degree?.degree_id ?? 0]
// cascader_product_val.value = [res.type?.type_id ?? 0, res.brand?.brand_id ?? 0, res.product
// ?.product_id ?? 0
// ]
// form.images = []
// res.image?.forEach(item => {
// form.images.push({
// id: item.image_id,
// file_path: item.file_path,
// })
// })
})
}
// // 选择房间弹窗
// const visibleRoomsPopup = ref(false);
// // 选中的房间
// const popupRoomsVal = ref([])
// // 房间列表
// const rooms = [{
// value: 1,
// label: '房间 101'
// },
// {
// value: 2,
// label: '房间 102'
// },
// {
// value: 3,
// label: '房间 103'
// }
// ];
// // 选择房间
// const onConfirmRoom = (selectedValue) => {
// console.log(selectedValue);
// form.room_name = selectedValue.selectedOptions[0].label
// form.room_id = selectedValue.selectedOptions[0].value
// console.log(form);
// visibleRoomsPopup.value = false
// }
// 选择房间弹窗
const visibleFeeTypePopup = ref(false);
// 台费结算类型
// const popupFeeTypeVal = ref([])
// 台费类型选择列表
const feeTypes = [{
value: 1,
label: '美团'
},
{
value: 2,
label: '抖音'
},
{
value: 3,
label: '线下'
}
];
// 选择房间
const onConfirmFeeType = (selectedValue) => {
console.log(selectedValue);
form.fee_type_name = selectedValue.selectedOptions[0].label
form.fee_type = selectedValue.selectedOptions[0].value
console.log(form);
if (form.fee_type !== 3) {
getCombos();
}
visibleFeeTypePopup.value = false
}
const getCombos = () => {
console.log("获取套餐");
fetchCombos({
type: form.fee_type
}).then(res => {
console.log(res);
combos.value = res;
})
}
// 选择套餐弹窗
const visibleCombosPopup = ref(false);
// 选中的套餐
const popupCombosVal = ref([])
// 套餐列表
const combos = ref([]);
// 选择套餐
const onConfirmCombos = (selectedValue) => {
console.log(selectedValue);
form.fee_combo_name = selectedValue.selectedOptions[0].label
form.fee_combo_id = selectedValue.selectedOptions[0].value
console.log(form);
visibleCombosPopup.value = false
}
// 支付状态弹窗
const visiblePaymentStatusPopup = ref(false);
// 选中的支付状态
const popupPaymentStatusVal = ref([])
// 支付类型
const popupPaymentTypeVal = ref('')
// 支付状态
const paymentStatuses = [{
value: 1,
label: '已付'
},
{
value: 2,
label: '未付'
},
{
value: 3,
label: '赠送'
}
];
const openPayStatusPopup = (type, index = -1) => {
popupPaymentTypeVal.value = type
goodsPayIndex.value = index // 只有type = goods 生效
visiblePaymentStatusPopup.value = true
console.log(type);
}
const onConfirmPaymentStatus = (selectedValue) => {
if (popupPaymentTypeVal.value == 'fee') {
form.fee_pay_status_txt = selectedValue.selectedOptions[0].label
form.fee_pay_status = selectedValue.selectedOptions[0].value
}
if (popupPaymentTypeVal.value == 'over') {
form.over_pay_status_txt = selectedValue.selectedOptions[0].label
form.over_pay_status = selectedValue.selectedOptions[0].value
}
if (popupPaymentTypeVal.value == 'goods' && goodsPayIndex.value >= 0) {
console.log("处理商品支付状态", goodsPayIndex.value);
orderGoods.value[goodsPayIndex.value].goods_pay_status_txt = selectedValue.selectedOptions[0].label
orderGoods.value[goodsPayIndex.value].goods_pay_status = selectedValue.selectedOptions[0].value
}
console.log(form);
visiblePaymentStatusPopup.value = false
popupPaymentTypeVal.value = ''
goodsPayIndex.value = -1
}
// 订单商品列表
const orderGoods = ref([
// {
// goods_type_name: null,
// goods_type_id: null,
// goods_name: null,
// goods_id: null,
// goods_price: null,
// goods_pay_status: 0,
// goods_pay_status_txt: "请选择",
// cascader_val: []
// },
])
// 当前操作的商品
const goodsPayIndex = ref(0)
// 当前操作的商品
const goodsIndex = ref(0)
// 添加规则
const addGoods = () => {
console.log(orderGoods.value);
orderGoods.value.push({
goods_type_name: null,
goods_type_id: null,
goods_name: null,
goods_id: null,
goods_price: null,
goods_pay_status: 0,
goods_pay_status_txt: "请选择",
cascader_val: []
})
}
// 删除商品
const removeGoods = (index) => {
orderGoods.value.splice(index, 1)
}
// 显示商品选择
const visibleGoodsCascader = ref(false)
// 商品选中
const cascaderGoodsValue = computed(() => {
let cascader_val = [];
if (goodsIndex.value >= 0) {
return orderGoods.value[goodsIndex.value]?.cascader_val ?? []
} else {
return cascader_val;
}
});
const onGoodsChange = (...args) => {
console.log("onGoodsChange", args);
}
// 选择商品
const onGoodsPathChange = (args) => {
console.log("onGoodsPathChange", args);
console.log("goodsIndex", goodsIndex.value);
console.log("orderGoods.value[goodsIndex.value]", orderGoods.value[goodsIndex.value]);
orderGoods.value[goodsIndex.value].goods_type_name = null
orderGoods.value[goodsIndex.value].goods_type_id = null
orderGoods.value[goodsIndex.value].goods_name = null
orderGoods.value[goodsIndex.value].goods_id = null
orderGoods.value[goodsIndex.value].goods_price = null
if (args.length >= 1 && args[0] !== null) {
orderGoods.value[goodsIndex.value].goods_type_name = args[0].text
orderGoods.value[goodsIndex.value].goods_type_id = args[0].value
}
if (args.length >= 2 && args[1] !== null) {
orderGoods.value[goodsIndex.value].goods_name = args[1].text
orderGoods.value[goodsIndex.value].goods_id = args[1].value
orderGoods.value[goodsIndex.value].goods_price = args[1].goods_price
}
console.log("orderGoods.value[goodsIndex.value]", orderGoods.value[goodsIndex.value]);
}
const onCloseGoodsCascader = () => {
console.log("onCloseGoodsCascader");
console.log("goodsIndex.value", goodsIndex.value);
if (orderGoods.value[goodsIndex.value].goods_type_id && orderGoods.value[goodsIndex.value].goods_id) {
orderGoods.value[goodsIndex.value].cascader_val = [
orderGoods.value[goodsIndex.value].goods_type_id,
orderGoods.value[goodsIndex.value].goods_id
]
}
goodsIndex.value = 0
console.log("goodsIndex.value", goodsIndex.value);
}
const onOpenGoodsCascader = () => {
console.log("onOpenGoodsCascader");
console.log("goodsIndex.value", goodsIndex.value);
}
const form = reactive({
order_type: 1, // 开台订单
room_id: 0,
fee_type: 0,
fee_type_name: '请选择',
fee_combo_id: 0, // 套餐费用ID
fee_combo_name: '请选择', // 套餐费用名称
fee_amount: null, // 线下支付费用
fee_pay_status: 0, // 费用支付状态
fee_pay_status_txt: '请选择', // 费用支付状态
over_often: null, // 超时小时
over_amount: null, // 超时金额
over_pay_status: 0, // 超时支付状态
over_pay_status_txt: "请选择", // 超时支付状态
discount_amount: null, // 优惠金额
})
// 商品列表
const selectGoods = ref([])
onMounted(() => {
fetchGoods().then(res => {
selectGoods.value = res;
})
})
// 提交表单
const submitForm = () => {
// const formData = {
// room: room.value,
// feeType: feeType.value,
// selectedPackage: selectedPackage.value,
// amount: amount.value,
// paymentStatus: paymentStatus.value
// };
let data = {
order_goods: orderGoods.value,
order: form
}
console.log('提交的订单数据:', data);
// console.log('提交的订单数据:', form);
fetchAddOrder(data).then(res => {
console.log(res);
// selectGoods.value = res;
})
};
</script>
<style lang="scss" scoped>
.page-content {
min-height: 100vh;
background-color: #f2f3f5;
}
.title {
padding: 0 20rpx;
margin-top: 20rpx;
margin-bottom: 20rpx;
font-size: 28rpx;
// font-weight: 400;
color: #909ca4;
}
.inline-form {
display: flex;
justify-content: space-between;
gap: 10rpx;
/* 在元素之间添加间距 */
}
.top-bar {
background: #fff;
padding: 20rpx;
display: flex;
justify-content: space-between;
border-top: 1px solid #eee;
// position: sticky;
// bottom: 0;
// z-index: 999;
}
/* 每个商品项容器 */
.inline-goods-form {
// box-sizing: border-box;
}
/* 行容器 */
.form-row {
display: flex;
justify-content: space-between;
align-items: flex-start;
gap: 20rpx;
margin-bottom: 20rpx;
}
</style>