更新订单管理模块

This commit is contained in:
2024-09-28 15:08:21 +08:00
parent 5a7aaad0a4
commit 90eb77d891
9 changed files with 409 additions and 125 deletions

View File

@@ -2,7 +2,12 @@
<view class="default-box-padding bg-fff border-r-12 u-m-t-20">
<view class="u-flex u-row-between">
<view class="font-bold">附加费</view>
<my-button plain shape="circle" :width="160" :height="56">退菜</my-button>
<template v-if="orderInfo.status=='unpaid'">
<my-button plain shape="circle" :width="160" :height="56" @click="tuicai">退菜</my-button>
</template>
<template v-if="orderInfo.status=='closed'">
<my-button plain shape="circle" :width="160" :height="56" @click="tuikuan">退款</my-button>
</template>
</view>
<view class="u-flex u-row-between u-m-t-20">
<view>{{data.name||'餐位费'}}</view>
@@ -18,6 +23,10 @@
type: Object,
default: () => {}
},
orderInfo:{
type: Object,
default: () => {}
},
table:{
type: Object,
default: () => {}
@@ -27,9 +36,16 @@
const statusMap={
unpaid:'未支付'
}
const emits=defineEmits(['tuicai','tuikuan','printOrder'])
function returnStatus(status){
return statusMap[status]||''
}
function tuikuan(){
emits('tuikuan',props.data)
}
function tuicai(){
emits('tuicai',props.data)
}
</script>
<style lang="scss" scoped>

View File

@@ -17,15 +17,23 @@
<view class="u-p-l-30 u-flex-1">
<view class="u-flex u-row-between u-col-top">
<view class="u-flex">
<view class="tui" v-if="item.status=='return'">
已退
<view class="">
<view class="u-flex">
<view class="tui" v-if="item.status=='return'">
已退
</view>
<view :class="{'line-th':item.status=='return'}">{{item.name||item.productName}}</view>
</view>
<view :class="{'line-th':item.status=='return'}">{{item.name||item.productName}}</view>
<view class="color-999 u-font-24 u-m-t-10">{{item.productSkuName||''}}</view>
</view>
<view class="u-text-right">
<view>{{item.salePrice||item.price}}</view>
<view v-if="item.status=='return'" class="line-th color-666 u-font-24">{{item.salePrice||item.price}}</view>
<template v-if="item.status=='return'">
<view >0.00</view>
<view class="line-th color-666 u-font-24">{{item.salePrice||item.price}}</view>
</template>
<template v-else>
<view >{{item.salePrice||item.price}}</view>
</template>
<view class="u-m-t-10 u-font-24">X{{item.number||item.num}}</view>
</view>
</view>

View File

@@ -6,7 +6,7 @@
</view>
<view class="u-flex u-row-between u-m-t-20">
<view>订单类型</view>
<view>堂食</view>
<view>{{returnUseType(data.useType)}}</view>
</view>
<view class="u-flex u-row-between u-m-t-20">
<view>桌位号</view>
@@ -26,7 +26,7 @@
</view>
<view class="u-flex u-row-between u-m-t-20">
<view>下单时间</view>
<view ><up-text v-if="data.createdAt" mode="date" :text="data.createdAt"></up-text></view>
<view><up-text v-if="data.createdAt" mode="date" :text="data.createdAt"></up-text></view>
</view>
<view class="u-flex u-row-between u-m-t-20">
<view>订单编号</view>
@@ -46,19 +46,28 @@
type: Object,
default: () => {}
},
table:{
table: {
type: Object,
default: () => {}
},
seatFee:{
seatFee: {
type: Object,
default: () => {totalNumber:0}
default: () => {
totalNumber: 0
}
}
})
function returnStatus(status){
const item=orderEnum.status.find(v=>v.key==status)
return item?item.label:''
function returnStatus(status) {
const item = orderEnum.status.find(v => v.key == status)
return item ? item.label : ''
}
function returnUseType(useType) {
if (!useType) {
return ''
}
return useType == "takeout" ? '堂食' : '自取';
}
</script>

View File

@@ -5,9 +5,11 @@
<text class="color-666">桌位号</text>
<text class="font-bold">{{orderDetail.info.tableName}}</text>
</view>
<goods-list @printOrder="onPrintOrder" @tuikuan="onTuikuan" :orderInfo="orderDetail.info" :data="orderDetail.goodsList" :seatFee="orderDetail.seatFee.totalAmount"
@tuicai="onTuiCai"></goods-list>
<extra-vue :data="orderDetail.seatFee"></extra-vue>
<goods-list @printOrder="onPrintOrder" @tuikuan="onTuikuan" :orderInfo="orderDetail.info"
:data="orderDetail.goodsList" :seatFee="orderDetail.seatFee.totalAmount" @tuicai="onTuiCai"></goods-list>
<template v-if="orderDetail.seatFee.totalNumber&&orderDetail.seatFee.totalAmount">
<extra-vue @tuicai="onSeatFeeTuicai" @tuikuan="onSeatFeeTuiKuan" :orderInfo="orderDetail.info" :data="orderDetail.seatFee"></extra-vue>
</template>
<order-vue :data="orderDetail.info" :table="options" :seatFee="orderDetail.seatFee"></order-vue>
<step-vue></step-vue>
<view style="height: 200rpx;"></view>
@@ -51,58 +53,84 @@
onHide
} from '@dcloudio/uni-app';
import {
reactive, ref
reactive,
ref
} from 'vue';
import OrderDetail from './page.js'
const tuicai = reactive({
show: false,
isSeatFee:false,
selGoods: {}
})
function onSeatFeeTuicai(seatFee){
tuicai.show = true
tuicai.isSeatFee = seatFee
tuicai.selGoods = seatFee
}
function onSeatFeeTuiKuan(seatFee){
go.to('PAGES_ORDER_TUIKUAN', {
})
}
function onTuiCai(goods, index) {
console.log(goods);
tuicai.show = true
tuicai.selGoods = goods
}
async function printDishes(){
try{
const res= await Api.$printDishes({
tableId:orderDetail.info.tableId
})
infoBox.showToast('已发送打印请求')
}catch(e){
infoBox.showToast('发送打印请求失败')
//TODO handle the exception
}
}
function onPrintOrder(){
uni.showModal({
title:'提示',
content:'是否打印当前台桌菜品',
success(res) {
if(res.confirm){
printDishes()
}
}
})
}
function onTuikuan(goods, index){
go.to('PAGES_ORDER_TUIKUAN',{
})
}
async function tuicaiConfirm() {
console.log(tuicai.selGoods);
const res = await Api.$returnCart({
cartId:tuicai.selGoods.hasOwnProperty('cartId')? tuicai.selGoods.cartId:tuicai.selGoods.id,
cartId: tuicai.selGoods.hasOwnProperty('cartId') ? tuicai.selGoods.cartId : tuicai.selGoods.id,
tableId: orderDetail.info.tableId,
})
tuicai.selGoods.status = 'return'
tuicai.show = false
}
async function printDishes() {
try {
const res = await Api.$printDishes({
tableId: orderDetail.info.tableId
})
infoBox.showToast('已发送打印请求')
} catch (e) {
infoBox.showToast('发送打印请求失败')
//TODO handle the exception
}
}
function onPrintOrder() {
uni.showModal({
title: '提示',
content: '是否打印当前台桌菜品',
success(res) {
if (res.confirm) {
printDishes()
}
}
})
}
function onTuikuan(goods, index) {
const {id,productId,productSkuId,productName,productSkuName,cartId,num,priceAmount,price}=goods
go.to('PAGES_ORDER_TUIKUAN', {
id,
cartId,
productId,
productSkuId,
productName,
num,
number:0,
productSkuName:productSkuName||'',
priceAmount,price
})
}
const uiPage = new OrderDetail()
setTimeout(() => {
uiPage.setVal('user', {
@@ -112,8 +140,8 @@
function diancan() {
go.to('PAGES_CREATE_ORDER', {
tableId: options.tableId,
tableName: options.name,
tableId: options.tableId || orderDetail.info.tableId,
name: options.name || orderDetail.info.tableName,
type: 'add'
})
}
@@ -138,13 +166,13 @@
const options = reactive({})
async function init() {
const res = await orderApi.tbOrderInfoDetail(options.id)
if(res.detailList.length){
uni.setStorageSync('useType',res.detailList[0].useType)
if (res.detailList.length) {
uni.setStorageSync('useType', res.detailList[0].useType)
}
const masterId = res.masterId
options.masterId = res.masterId
if (res.status == 'unpaid') {
// if (false) {
// if (res.status == 'unpaid') {
if (false) {
const {
records,
seatFee
@@ -161,6 +189,7 @@
for (let i in res.detailList) {
const goods = res.detailList[i]
if (goods.productName != '客座费') {
console.log(goods);
if (goodsMap.hasOwnProperty(goods.placeNum)) {
goodsMap[goods.placeNum].push(goods)
} else {
@@ -181,7 +210,6 @@
}))
console.log(orderDetail.goodsList);
}
console.log(orderDetail);
orderDetail.info = res
}
@@ -192,20 +220,21 @@
init()
})
}
// 监听选择用户事件
let user = ref(null)
//更新选择用户
function setUser(par) {
const submitPar = {
masterId: option.masterId,
tableId: option.tableId,
masterId: options.masterId,
tableId: options.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) => {
@@ -214,15 +243,15 @@
setUser()
})
}
onShow(() => {
watchEmit()
watchChooseuser()
init()
})
onLoad((opt) => {
Object.assign(options, opt)
console.log(options);
init()
})
</script>

View File

@@ -96,7 +96,8 @@
}
}
goodsMapInit()
watch(() => props.data.detailList, (newval) => {
watch(() => props.data.detailList.length, (newval) => {
goodsNumber.value=0
goodsMapInit()
})
@@ -111,8 +112,10 @@
}
function sendTypeFilter(t) {
console.log(t);
if (t) {
return orderEnum.sendType.find(item => item.key == t).label;
const item=orderEnum.sendType.find(item => item.key == t)
return item?item.label:'';
} else {
return t;
}

View File

@@ -1,7 +1,7 @@
<template>
<view class="list">
<view v-for="(item,index) in list" :key="index">
<order-item @printOrder="print" :data="item" :index="index"></order-item>
<order-item @printOrder="print" :key="index" :data="item" :index="index"></order-item>
</view>
<view v-if="hasAjax&&!list.length">
<my-img-empty tips="亲,你还没有订单哦~"></my-img-empty>

View File

@@ -4,16 +4,18 @@
<view class="search bg-fff u-p-t-32 u-p-l-28 u-p-r-28 u-p-b-32">
<up-search v-bind="search" v-model="search.val"></up-search>
</view>
<filter-vue v-model:time="pageData.order.query.createdAt"></filter-vue>
<filter-vue v-model:time="order.data.query.createdAt"></filter-vue>
</view>
<order-list @printOrder="onPrintOrder" :hasAjax="pageData.order.hasAjax" :list="pageData.order.list"></order-list>
<my-pagination :totalElements="pageData.order.totalElements"></my-pagination>
<order-list @printOrder="onPrintOrder" :hasAjax="order.data.hasAjax" :list="order.data.list"></order-list>
<my-pagination @change="pageChange" :totalElements="order.data.total"></my-pagination>
<view style="height: 100rpx;"></view>
</view>
</template>
<script setup>
import {onLoad,onShow,onPullDownRefresh} from '@dcloudio/uni-app'
import * as Api from '@/http/yskApi/order.js'
import LIST from '@/commons/class/list.js'
import {$printOrder} from '@/http/yskApi/Instead.js'
import filterVue from './compoents/filter.vue';
import orderList from './compoents/order-list.vue';
@@ -21,6 +23,7 @@
import {
reactive, watch
} from 'vue';
const search = reactive({
val: '',
placeholder: '搜索单号/昵称/姓名/手机号码/商品名称',
@@ -33,36 +36,47 @@
}
})
const pageData = reactive({
order: {
list: [],
totalElements:0,
hasAjax:false,
query: {
createdAt: [],
id: "",
orderNo: "",
orderType: "0",
page: 0,
pageSize: 10,
payType: "",
productName: "",
status: ""
}
const order=new LIST({
list: [],
query: {
createdAt: [],
id: "",
orderNo: "",
orderType: "0",
page: 0,
pageSize: 10,
payType: "",
productName: "",
status: ""
}
})
watch(()=>pageData.order.query.createdAt,(newval)=>{
function pageChange(e){
order.setVal('page',e)
console.log(e);
console.log(order.data.page);
init()
}
console.log(order.list);
watch(()=>order.data.query.createdAt,(newval)=>{
init()
})
async function init() {
const {content,totalElements}=await Api.tbOrderInfoData(pageData.order.query)
pageData.order.hasAjax=true
pageData.order.totalElements=totalElements
pageData.order.list=content
console.log(content);
const {content,totalElements}=await Api.tbOrderInfoData({...order.data.query,page:order.data.page})
uni.stopPullDownRefresh()
order.setVal('list',content)
console.log(order.data.list);
order.setVal('total',totalElements)
order.setVal('hasAjax',true)
}
init()
onPullDownRefresh(()=>{
pageData.order.query.page=0
init()
})
onShow(init)
async function printOrder(item){
try{
console.log(item);

View File

@@ -49,51 +49,54 @@
<text>余额</text>
<text>0.00</text>
</view> -->
<my-radio @click="changePayType(index)" :modelValue="index==pays.payTypes.selIndex">
<my-radio @click="changePayType(index)"
:modelValue="index==pays.payTypes.selIndex">
</my-radio>
</view>
</view>
</view>
</view>
<view class="u-m-t-60 u-p-b-30">
<my-button @click="payOrder">确认付款</my-button>
<my-button @click="payOrderClick">确认付款</my-button>
</view>
</template>
<template v-else>
<view class="">
<view class="u-font-32 u-m-t-40 u-text-center">请让顾客使用微信扫码</view>
<view class="u-flex u-row-center u-m-t-40 ">
<up-qrcode :size="140" val="uview-plus"></up-qrcode>
<up-qrcode :size="140" :val="payCodeUrl"></up-qrcode>
</view>
</view>
</template>
</view>
<!-- 二维码支付扫码 -->
<template v-if="pays.selIndex==1">
<template v-if="pays.selIndex==1">
<view class="card border-bottom top u-m-t-32">
</view>
<view class="bg-fff card bottom border-r-12 u-p-32">
<view class="font-bold u-font-32 u-text-center">
{{discount.currentPrice?discount.currentPrice: order.amount}}</view>
<view class="u-flex u-row-center u-m-t-24">
<up-loading-icon size="14" text="等待支付"></up-loading-icon>
<view class="u-flex pay-success">
<up-icon color="#5CBB6F" name="checkmark-circle-fill"></up-icon>
<view class="u-m-l-6">支付成功</view>
</view>
<template v-if="order.status=='unpaid'">
<up-loading-icon size="14" text="等待支付"></up-loading-icon>
</template>
<template v-if="order.status=='closed'">
<view class="u-flex pay-success">
<up-icon color="#5CBB6F" name="checkmark-circle-fill"></up-icon>
<view class="u-m-l-6">支付成功</view>
</view>
</template>
</view>
</view>
</template>
</view>
</view>
@@ -107,7 +110,8 @@
reactive,
onMounted,
watch,
ref
ref,
onBeforeUnmount
} from 'vue';
import {
onLoad
@@ -119,6 +123,12 @@
let payStatus = ref(null) //loading success
let timer = null
function clear() {
clearInterval(timer)
timer = null
}
const pays = reactive({
list: ['扫码收款', '二维码收款'],
@@ -129,6 +139,22 @@
}
})
watch(() => pays.selIndex, (newval) => {
clearInterval(timer)
if (newval) {
timer = setInterval(() => {
orderApi.tbOrderInfoDetail(order.orderId).then(res => {
order.status=res.status
if(res.status=='closed'){
paySuccess()
}
})
}, 2000)
} else {
}
})
const models = new Map();
function setModel(el) {
@@ -169,6 +195,15 @@
})
}, 500)
}
function payOrderClick(){
const payType = pays.payTypes.list[pays.payTypes.selIndex].payType
console.log(payType);
if(payType=='scanCode'||payType=='deposit'){
return saomaPay()
}
payOrder()
}
async function payOrder() {
const payType = pays.payTypes.list[pays.payTypes.selIndex].payType
await Api.$payOrder({
@@ -190,6 +225,8 @@
amount: 0
})
function saomaPay() {
const item = pays.payTypes.list[pays.payTypes.selIndex]
uni.scanCode({
@@ -223,14 +260,26 @@
return saomaPay('scanCode')
}
})
let payCodeUrl = ref('')
async function init() {
const res = await orderApi.tbOrderInfoDetail(order.orderId)
Object.assign(order, res)
}
onLoad((opt) => {
orderApi.$getOrderPayUrl({
orderId: opt.orderId
}).then(res => {
payCodeUrl.value = res
})
console.log(opt);
Object.assign(order, opt)
init()
})
onBeforeUnmount(() => {
clear()
})
</script>
<style lang="scss" scoped>

View File

@@ -1,22 +1,178 @@
<template>
<view>
<view class="min-page bg-gray u-p-30">
<view class="bg-fff u-p-24 border-r-12 u-flex u-row-between">
<view>全退</view>
<view>
<my-radio v-model="allTui"></my-radio>
</view>
</view>
<view class="bg-fff border-r-12 list u-m-t-32">
<view class="u-flex u-row-between border-top item u-p-t-32 u-p-b-32"
v-for="(item,index) in orderDetail.goodsList" :key="index">
<view>
<view>{{item.productName}}</view>
<view class="u-m-t-10 color-999 u-font-24">{{item.productSkuName||""}}</view>
<view class="u-m-t-10 color-999 u-font-24">最多可退×{{item.num}}</view>
</view>
<view class="u-flex">
<view class="color-red">{{item.priceAmount}}</view>
<view class="u-flex u-m-l-32 u-col-center">
<up-icon @click="changeItem(item,-1)" :size="20" name="minus-circle"></up-icon>
<view class="u-m-l-28 u-m-r-28">{{item.number}}</view>
<up-icon @click="changeItem(item,1)" :color="color.ColorMain" :size="20"
name="plus-circle-fill"></up-icon>
</view>
</view>
</view>
</view>
<view class="bg-fff u-m-t-32 u-p-24 border-r-12 u-flex u-row-between">
<view>支付金额</view>
<view>
{{to2(totalPrice)}}
</view>
</view>
<view class="bg-fff u-m-t-32 u-p-24 border-r-12 u-flex u-row-between">
<view>退款金额</view>
<view class="color-red">
{{to2(tuikuanPrice)}}
</view>
</view>
<view class="bg-fff u-p-24 border-r-12 u-m-t-32">
<view>退回优惠券</view>
<view class="u-font-24 color-999 u-m-t-16">
该订单未使用优惠券
</view>
</view>
<view class="bg-fff u-p-24 border-r-12 u-m-t-32">
<view>
<text class="color-red">*</text>
<text>退款原因</text>
</view>
<view class="u-m-t-24 u-flex u-flex-wrap gap-28">
<view class="tag" @click="changeTuiKuanSel(index)" v-for="(item,index) in tuikuan.list" :key="index">
{{item}}
</view>
</view>
<view class="u-m-t-24">
<up-textarea placeholder="选填" v-model="note"></up-textarea>
</view>
</view>
<view style="height: 200rpx;"></view>
<view class="fixed-b">
<up-button text="确认退款" shape="circle" type="primary" size="large" :color="color.ColorMain"></up-button>
</view>
</view>
</template>
<script>
export default {
data() {
return {
}
},
methods: {
}
<script setup>
import color from '@/commons/color.js';
import * as orderApi from '@/http/yskApi/order.js'
import {
onLoad,
onShow,
onHide
} from '@dcloudio/uni-app';
import {
computed,
reactive,
ref,
watch
} from 'vue';
let allTui = ref(false)
let note = ref('')
const tuikuan = reactive({
list: ['点错', '数量点错', '客人要求', '协商退费'],
sel: 0
})
function changeTuiKuanSel(i) {
tuikuan.sel = i
}
const orderDetail = reactive({
goodsList: [],
info: {},
seatFee: {
totalAmount: 0
}
})
watch(()=>allTui.value,(newval)=>{
orderDetail.goodsList.map(v=>{
v.number=newval?v.num:0
})
})
const totalPrice = computed(() => {
return orderDetail.goodsList.reduce((prve, cur) => {
return prve+cur.priceAmount*1
}, 0)
})
const tuikuanPrice = computed(() => {
return orderDetail.goodsList.reduce((prve, cur) => {
return prve+cur.number*cur.price
}, 0)
})
function to2(n){
return Number(n).toFixed(2)
}
function changeItem(item, step) {
console.log(item);
let newval = item.number * 1 + step * 1
if (newval <= 0) {
newval = 0
}
if (newval >= item.num) {
newval = item.num
}
item.number = newval
}
onLoad((opt) => {
if (Array.isArray(opt)) {
orderDetail.goodsList = opt
} else {
orderDetail.goodsList = [opt]
}
console.log(opt);
})
</script>
<style>
<style lang="scss" scoped>
.fixed-b {
position: fixed;
left: 110rpx;
right: 110rpx;
bottom: calc(env(safe-area-inset-bottom) + 32rpx);
/* #ifdef H5 */
bottom: 100rpx;
/* #endif */
}
</style>
.gap-28 {
gap: 28rpx;
font-size: 24rpx;
}
.list {
padding: 0 24rpx;
}
.list .item:first-child {
border: none;
}
.tag {
padding: 8rpx 16rpx 6rpx 16rpx;
border: 1px solid #E5E5E5;
border-radius: 4rpx;
&.active {
border-color: #E6F0FF;
color: $my-main-color;
}
}
</style>