更新折扣优惠和代客下单

This commit is contained in:
gyq 2024-08-26 18:28:24 +08:00
parent 48a3443c5f
commit fbfee69b25
15 changed files with 611 additions and 169 deletions

View File

@ -26,6 +26,9 @@ VITE_API_KP_URL = 'https://invoice.sxczgkj.cn/api'
# 鹏辉
# VITE_API_URL = 'http://192.168.1.106:10589/cashier-client'
# 杰哥
# VITE_API_URL = 'http://192.168.1.34:10589/cashier-client'
# 测试
VITE_API_URL = 'https://cashier-client.sxczgkj.cn/cashier-client'

View File

@ -1,7 +1,7 @@
{
"name": "vite-electron",
"private": true,
"version": "1.4.16",
"version": "1.4.17",
"main": "dist-electron/main.js",
"scripts": {
"dev": "chcp 65001 && vite",

View File

@ -101,3 +101,29 @@ export function getsendMessage(params) {
params,
});
}
/**
* 订单详情
* @param {*} params
* @returns
*/
export function orderDetail(params) {
return request({
method: "get",
url: "/order/orderDetail",
params,
});
}
/**
* 获取员工最大优惠点
* @param {*} params
* @returns
*/
export function getStaffDiscount(params) {
return request({
method: "get",
url: "/pay/getOrderDiscount",
params,
});
}

View File

@ -15,53 +15,53 @@ export function queryPayType(params) {
/**
* 付款
* @param {*} params
* @param {*} data
* @returns
*/
export function payOrder(api, params) {
export function payOrder(api, data) {
return request({
method: "get",
method: "post",
url: api,
params,
data,
});
}
/**
* 扫码支付
* @param {*} params
* @param {*} data
* @returns
*/
export function scanpay(params) {
export function scanpay(data) {
return request({
method: "get",
method: "post",
url: "pay/scanpay",
params,
data,
});
}
/**
* 储值卡付款
* @param {*} params
* @param {*} data
* @returns
*/
export function accountPay(params) {
export function accountPay(data) {
return request({
method: "get",
method: "post",
url: "pay/accountPay",
params,
data,
});
}
/**
* 现金付款
* @param {*} params
* @param {*} data
* @returns
*/
export function cashPay(params) {
export function cashPay(data) {
return request({
method: "get",
method: "post",
url: "pay/cashPay",
params,
data,
});
}
@ -129,3 +129,16 @@ export function queryScanPay(params) {
params,
});
}
/**
* 会员余额支付
* @param {*} data
* @returns
*/
export function vipPay(data) {
return request({
method: "post",
url: "/pay/vipPay",
data,
});
}

View File

@ -1,4 +1,6 @@
import getLodop from "./LodopFuncs.js";
import { formatDecimal } from "@/utils/index.js";
/**
* 打印订单小票
*/
@ -75,16 +77,22 @@ export default (data) => {
</div>
<div style="margin-top: 6px; font-size: 22px;display:flex;justify-content: space-between;">
<span>应收</span>
<span>${data.amount}</span>
<span>${data.discountAmount}</span>
</div>
<div style="margin-top: 4px; font-size: 12px;">
<span>余额</span>
<span>0.00</span>
<span>共计:</span>
<span>${data.amount}</span>
<span style="margin-left: 10px;">优惠:</span>
<span>${formatDecimal(data.amount - data.discountAmount)}(${
data.discount
})</span>
</div>
<div style="margin-top: 6px;margin-bottom: 6px;width: 100%">
<hr/>
</div>
<div style="margin-top: 4px; font-size: 16px;font-weight: bold;">备注${data.remark}</div>
<div style="margin-top: 4px; font-size: 16px;font-weight: bold;">备注${
data.remark
}</div>
<div style="margin-top: 4px; font-size: 12px;">
打印时间${data.printTime}
</div>

View File

@ -3,17 +3,22 @@
<div class="header">
<div class="t1">
<span class="title">应收:</span>
<span class="num">{{ props.amount }}</span>
<span class="num">{{ money }}</span>
</div>
<div class="t2">
<span>已付:0.00</span>
<span>优惠:0.00</span>
<span>共计{{ props.amount }}</span>
<span style="margin-left: 20px;">优惠{{ formatDecimal(props.amount - money) }}</span>
<span v-if="props.discount" @click="cancelDiscount">{{ formatDecimal(props.discount * 10, 1, true) }}
<el-icon>
<CircleClose />
</el-icon>
</span>
</div>
</div>
<div class="number_wrap">
<div class="menus">
<div class="item" :class="{ active: payActive == index }" v-for="(item, index) in payList"
:key="item.id" @click="payTypeChange(index, item)">
<div class="item" :class="{ active: payActive == index, disabled: item.disabled }"
v-for="(item, index) in payList" :key="item.id" @click="payTypeChange(index, item)">
<div class="icon">
<el-image :src="item.icon" class="img"></el-image>
</div>
@ -22,7 +27,7 @@
</div>
<div class="input_wrap">
<div class="input" style="flex: 1;">储值:{{ money }}</div>
<div class="input" v-if="waitPayMoney > 0">待支付:{{ waitPayMoney }}</div>
<!-- <div class="input" v-if="waitPayMoney > 0">待支付:{{ waitPayMoney }}</div> -->
</div>
<div class="blance">
<!-- 可用余额0.00 -->
@ -45,16 +50,46 @@
</div>
</div>
</div>
<scanModal ref="scanModalRef" :amount="props.amount" :orderId="props.orderId" :selecttype="props.selecttype"
:payType="payType" @success="scanCodeSuccess" />
<scanModal ref="scanModalRef" :amount="props.amount" :money="money" :orderId="props.orderId"
:selecttype="props.selecttype" :payType="payType" @success="scanCodeSuccess" />
<el-dialog :title="`选择会员`" top="3vh" v-model="showDialog" width="80%">
<el-form inline>
<el-form-item>
<el-input placeholder="请输入手机号搜索会员" v-model="tableData.phone" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="getMemberList">搜索</el-button>
<el-button @click="resetTable">重置</el-button>
</el-form-item>
</el-form>
<el-table :data="tableData.list" height="440px" border stripe v-loading="tableData.loading">
<el-table-column prop="name" label="昵称" width="120px" />
<el-table-column prop="telephone" label="手机" width="150px" />
<el-table-column prop="code" label="编号" width="120px" />
<el-table-column prop="level" label="等级" />
<el-table-column prop="levelConsume" label="积分" />
<el-table-column prop="amount" label="余额" width="100px">
<template v-slot="scope">
{{ formatDecimal(scope.row.amount) }}
</template>
</el-table-column>
<el-table-column label="操作" width="120px">
<template v-slot="scope">
<el-button type="primary" @click="toHomeMember(scope.row)">选择</el-button>
</template>
</el-table-column>
</el-table>
<el-pagination layout="prev, pager, next, total" background style="margin-top: 20px;"
:total="Number(tableData.total)" v-model:current-page="tableData.page" @current-change="getMemberList" />
</el-dialog>
</template>
<script setup>
import { onMounted, ref, computed, watch } from 'vue'
import { queryPayType, accountPay, cashPay } from '@/api/pay'
import { onMounted, ref, computed, watch, reactive } from 'vue'
import { queryPayType, accountPay, cashPay, vipPay } from '@/api/pay'
import { queryMembermember, createMembermember, membermemberScanPay, accountPaymember } from '@/api/member/index.js'
import { useUser } from "@/store/user.js"
import { clearNoNum } from '@/utils'
import { clearNoNum, formatDecimal } from '@/utils'
import scanModal from '@/components/payCard/scanModal.vue'
import { ElMessage } from "element-plus";
@ -76,23 +111,30 @@ const props = defineProps({
orderId: {
type: [String, Number],
default: ''
},
discount: {
type: [String, Number],
default: 0
}
})
const emit = defineEmits(['paySuccess'])
const emit = defineEmits(['paySuccess', 'cancelDiscount'])
const money = ref('0')
const scanModalRef = ref(null)
watch(props, (value) => {
money.value = `${props.amount}`
if (props.discount > 0) {
money.value = `${formatDecimal(props.amount * props.discount)}`
}
})
const waitPayMoney = computed(() => {
let num = JSON.stringify(props.amount - money.value)
num = Math.floor(num * 100) / 100
return num
})
// const waitPayMoney = computed(() => {
// let num = JSON.stringify(props.amount - money.value)
// num = Math.floor(num * 100) / 100
// return num
// })
const payActive = ref(0)
const payType = ref('')
@ -106,11 +148,16 @@ function scanCodeSuccess() {
//
function payTypeChange(index, item) {
if (item.disabled) return
payActive.value = index
payType.value = item.payType
if (item.payType == 'scanCode') {
scanModalRef.value.show()
}
if (item.payType == 'vipPay') {
showDialog.value = true
getMemberList()
}
if (payList.value[payActive.value].payType == 'deposit' && !global.orderMemberInfo.id) {
scanModalRef.value.show()
}
@ -123,7 +170,7 @@ async function confirmOrder() {
if (payList.value[payActive.value].payType == 'scanCode') {
scanModalRef.value.show()
} else {
if (money.value < props.amount) return
// if (money.value < props.amount) return
payLoading.value = true
switch (payList.value[payActive.value].payType) {
case 'deposit'://
@ -153,16 +200,18 @@ async function confirmOrder() {
})
} else {
await cashPay({
orderId: props.orderId
orderId: props.orderId,
payAmount: props.discount > 0 ? money.value : '',
discountAmount: props.discount > 0 ? formatDecimal(props.amount - money.value) : ''
})
}
break;
case 'bank'://
if (props.selecttype == 1) {//1
} else {
}
case 'vipPay':
//
console.log('使用会员id支付');
payLoading.value = false
showDialog.value = true
return
break;
default:
break;
@ -202,8 +251,17 @@ async function queryPayTypeAjax() {
const res = await queryPayType({
shopId: store.userInfo.shopId
})
res.map(item => {
if (props.amount <= 0 && item.payType == 'scanCode') {
item.disabled = true
} else {
item.disabled = false
}
})
payList.value = res
if (res[0].payType == 'scanCode' || res[0].payType == 'deposit') {
if ((res[0].payType == 'scanCode' && !res[0].disabled) || res[0].payType == 'deposit') {
scanModalRef.value.show()
payType.value = res[0].payType
}
@ -212,6 +270,69 @@ async function queryPayTypeAjax() {
}
}
const showDialog = ref(false)
const tableData = reactive({
phone: '',
loading: false,
list: [],
page: 1,
size: 10,
total: 0
})
//
function resetTable() {
tableData.phone = ''
tableData.page = 1
getMemberList()
}
//
async function getMemberList() {
try {
tableData.loading = true
const res = await queryMembermember({
shopId: store.userInfo.shopId,
phone: tableData.phone,
page: tableData.page,
pageSize: tableData.size
})
tableData.loading = false
tableData.list = res.list
tableData.total = res.total
} catch (error) {
console.log(error);
}
}
//
async function toHomeMember(row) {
try {
showDialog.value = false
payLoading.value = true
const res = await vipPay({
orderId: props.orderId,
vipUserId: row.id,
payAmount: props.discount > 0 ? money.value : '',
discountAmount: props.discount > 0 ? formatDecimal(props.amount - money.value) : ''
})
global.setOrderTable()
global.setOrderMember()
payLoading.value = false
ElMessage.success('支付成功')
emit('paySuccess')
} catch (error) {
payLoading.value = false
console.log(error);
}
}
//
function cancelDiscount() {
emit('cancelDiscount')
}
onMounted(() => {
money.value = `${props.amount}`
queryPayTypeAjax()
@ -247,9 +368,13 @@ onMounted(() => {
.t2 {
display: flex;
gap: var(--el-font-size-base);
color: #999;
padding-top: 10px;
span {
display: flex;
align-items: center;
}
}
}
@ -273,6 +398,10 @@ onMounted(() => {
position: relative;
$lineHeight: 4px;
&.disabled {
filter: grayscale(1);
}
&.active {
&::after {
content: "";

View File

@ -10,7 +10,7 @@
<div class="right" v-if="!userPayWait">
<div class="amount">
<span class="t">扫码支付</span>
<span class="n">{{ props.amount }}</span>
<span class="n">{{ props.money }}</span>
</div>
<div class="input">
<el-input ref="inputRef" v-model="scanCode" style="height: calc(var(--el-component-size-large) + 30px)"
@ -57,6 +57,7 @@ import icon from "@/assets/icon_scan.png";
import { scanpay, queryOrder, quickPay, queryQuickPayStatus, accountPay, queryScanPay } from "@/api/pay";
import { useUser } from "@/store/user.js";
import { useGlobal } from '@/store/global.js'
import { formatDecimal } from '@/utils'
const store = useUser();
const global = useGlobal()
import {
@ -88,6 +89,10 @@ const props = defineProps({
payType: {
type: [Number, String],
default: "",
},
money: {
type: [Number, String],
default: 0,
}
});
@ -112,6 +117,8 @@ async function submitHandle() {
memberId: props.orderId,
amount: props.amount,
authCode: scanCode.value,
payAmount: props.money < props.amount ? props.money : '',
discountAmount: props.money < props.amount ? formatDecimal(props.amount - props.money) : ''
});
} else {
if (props.fast) {
@ -125,13 +132,17 @@ async function submitHandle() {
await scanpay({
orderId: props.orderId,
authCode: scanCode.value,
payAmount: props.money < props.amount ? props.money : '',
discountAmount: props.money < props.amount ? formatDecimal(props.amount - props.money) : ''
});
}
if (props.payType == 'deposit') {
await accountPay({
orderId: props.orderId,
memberId: '',
memberAccount: scanCode.value
memberAccount: scanCode.value,
payAmount: props.money < props.amount ? props.money : '',
discountAmount: props.money < props.amount ? formatDecimal(props.amount - props.money) : ''
})
}
}

View File

@ -7,8 +7,8 @@
<div class="sku_wrap">
<!-- <div class="item" :class="{ active: val.active }" v-for="(val, i) in item.value" :key="i"
@click="selectedSku(index, i)">{{ val.name }}</div> -->
<el-button :plain="!val.active" type="primary" v-for="(val, i) in item.selectSpecResult
" :key="i" @click="selectedSku(index, i)" class="btn">{{ val.name }}</el-button>
<el-button :plain="!val.active" type="primary" v-for="(val, i) in item.selectSpecResult
" :key="i" :disabled="val.disabled" @click="selectedSku(index, i)" class="btn">{{ val.name }}</el-button>
</div>
</div>
</div>
@ -51,6 +51,8 @@ const goodsInfo = ref({})
const loading = ref(false)
const selecSkuArray = ref([])
//
function submitSku() {
dialogVisible.value = false
@ -67,10 +69,48 @@ function submitSku() {
}
//
function selectedSku(index, i) {
function selectedSku(index = 0, i = 0) {
goods.value.selectSpec[index].selectSpecResult.map(item => {
item.active = false
})
if (index == 0) {
selecSkuArray.value = []
}
if (selecSkuArray.value.length - 1 > index) {
// console.log(selecSkuArray.value.length - 1);
// console.log(index);
selecSkuArray.value.splice(index + 1, selecSkuArray.value.length)
}
selecSkuArray.value[index] = goods.value.selectSpec[index].selectSpecResult[i].name
if (index < goods.value.selectSpec.length - 1) {
selectedSkuNum.value = 0
goods.value.selectSpec.map((item, idx) => {
if (index < idx) {
item.selectSpecResult.map(val => {
val.disabled = true
val.active = false
})
}
})
goods.value.selectSpec[index + 1].selectSpecResult.map(item => {
goods.value.groundingSpecInfo.map(val => {
// console.log(val);
// console.log(`${selecSkuArray.value.join(',')},${item.name}`);
// console.log(val.specSnap.indexOf(`${selecSkuArray.value.join(',')},${item.name}`));
if (val.specSnap.indexOf(`${selecSkuArray.value.join(',')},${item.name}`) != -1 && val.isGrounding) {
item.disabled = false
}
})
})
}
if (goods.value.selectSpec[index].selectSpecResult[i].active) {
goods.value.selectSpec[index].selectSpecResult[i].active = false
selectedSkuNum.value--
@ -78,6 +118,7 @@ function selectedSku(index, i) {
goods.value.selectSpec[index].selectSpecResult[i].active = true
selectedSkuNum.value++
}
selectedSuccess()
}
@ -99,6 +140,8 @@ function selectedSuccess() {
if (selectedSkuNum.value >= goods.value.selectSpec.length) {
//
queryProductSkuAjax()
} else {
goodsInfo.value = {}
}
}
@ -134,14 +177,23 @@ function show(item, t = 'shop') {
goods.value = item
type.value = t
goods.value.selectSpec = JSON.parse(goods.value.selectSpec)
goods.value.selectSpec.map(item => {
goods.value.selectSpec.map((item, index) => {
let arr = []
item.selectSpecResult.map(val => {
switch (type.value) {
case 'shop':
let disabled = true
if (index == 0) {
goods.value.groundingSpecInfo.map(item => {
if (item.specSnap.indexOf(val) != -1 && item.isGrounding) {
disabled = false
}
})
}
arr.push({
active: false,
name: val
name: val,
disabled: index == 0 ? disabled : true
})
break;
case 'cart':
@ -149,7 +201,8 @@ function show(item, t = 'shop') {
const skus = goods.value.skuName.split(',')
arr.push({
active: !!skus.find(item => item === val),
name: val
name: val,
disabled: true
})
break;
default:

View File

@ -179,6 +179,8 @@ const printData = reactive({
}
],
amount: '30.00',
discountAmount: '30.00',
discount: 0,
remark: '给我多放点辣椒,谢谢老板',
orderInfo: {
masterId: '#002',

View File

@ -159,8 +159,8 @@ const canvasRef = ref(null)
const printData = ref({
deviceName: '',
outNumber: '123',
name: '甜橙马黛茶',
skuName: '加奶、加珍珠',
name: '【测试勿管】甜橙马黛茶',
skuName: '测试、加珍珠',
masterId: '#A9',
createdAt: dayjs().format('YYYY-MM-DD HH:mm:ss')
})

View File

@ -392,7 +392,8 @@ async function productqueryCommodityInfoAjax() {
commdityName: commdityName.value,
page: goodsPage.value,
pageSize: goodsPageSize.value,
masterId: props.masterId
masterId: props.masterId,
tableId: global.tableInfo.qrcode || '',
})
if (res.list.length < goodsPageSize.value) {
finish.value = true

View File

@ -56,14 +56,37 @@
<el-checkbox v-model="isPrint" border label="打印结算小票" style="width: 100%" />
</div>
<div class="print">
<el-button type="primary" v-loading="printLoading" @click="printHandle">打印预结单</el-button>
<el-button type="warning" :loading="discountLoading" @click="showStaffDiscountHandle">添加折扣</el-button>
</div>
<div class="print">
<el-button type="primary" :loading="printLoading" @click="printHandle">打印预结单</el-button>
</div>
</div>
</div>
<div class="pay_wrap">
<payCard :amount="props.amount" :orderId="props.orderInfo.id" @paySuccess="paySuccess" />
<payCard :amount="props.amount" :discount="propsDiscount" :orderId="props.orderInfo.id" @paySuccess="paySuccess"
@cancelDiscount="propsDiscount = 0" />
</div>
</div>
<el-dialog v-model="showStaffDiscount" title="员工折扣" @close="global.updateData(true)">
<el-form>
<el-form-item label="折扣比例">
<div>
<el-input-number v-model="discount" :min="staffDiscount" :max="0.99" :step="0.1"
:disabled="staffDiscount == 0" />
<div class="tips">最低折扣比例{{ staffDiscount }}</div>
</div>
</el-form-item>
</el-form>
<div class="footer_wrap">
<div class="btn">
<el-button style="width: 100%;" @click="showStaffDiscount = false">取消</el-button>
</div>
<div class="btn">
<el-button type="primary" style="width: 100%;" @click="discountConfirm">确认</el-button>
</div>
</div>
</el-dialog>
</el-drawer>
</template>
@ -73,7 +96,7 @@ import { onMounted, ref } from "vue";
import { useUser } from "@/store/user.js";
import payCard from "@/components/payCard/payCard.vue";
import { print } from "@/api/pay";
import { orderfindOrder } from '@/api/order/index.js'
import { orderfindOrder, getStaffDiscount } from '@/api/order/index.js'
import { ElMessage } from "element-plus";
import dayjs from "dayjs";
import useStorage from '@/utils/useStorage'
@ -92,6 +115,11 @@ const emit = defineEmits("paySuccess");
const printLoading = ref(false);
const showStaffDiscount = ref(false)
const staffDiscount = ref(0)
const discount = ref(0)
const propsDiscount = ref(0)
const dialogVisible = ref(false);
const props = defineProps({
cart: {
@ -122,6 +150,43 @@ const props = defineProps({
const isPrint = ref(true);
const discountLoading = ref(false)
//
async function showStaffDiscountHandle() {
discountLoading.value = true
await getStaffDiscountAjax()
discountLoading.value = false
if (staffDiscount.value <= 0) {
ElMessage.error('暂无折扣,请稍后再试')
} else {
showStaffDiscount.value = true
discountLoading.value = false
global.updateData(false)
}
}
//
async function getStaffDiscountAjax() {
try {
const res = await getStaffDiscount({
orderId: props.orderInfo.id,
staffId: store.userInfo.staffId
})
staffDiscount.value = res
} catch (error) {
console.log(error);
}
}
//
function discountConfirm() {
if (discount.value >= staffDiscount.value) {
propsDiscount.value = discount.value
}
showStaffDiscount.value = false
}
//
const printHandle = _.throttle(async function () {
try {
@ -132,7 +197,9 @@ const printHandle = _.throttle(async function () {
loginAccount: store.userInfo.loginAccount,
isBefore: true,
carts: props.cart,
amount: props.amount,
amount: formatDecimal(props.amount),
discountAmount: propsDiscount.value > 0 ? formatDecimal(props.amount * propsDiscount.value) : formatDecimal(props.amount),
discount: formatDecimal(propsDiscount.value * 10, 1, true),
remark: props.remark,
orderInfo: props.orderInfo,
createdAt: dayjs(props.orderInfo.createdAt).format("YYYY-MM-DD HH:mm:ss"),
@ -176,7 +243,9 @@ async function printOrderLable() {
shop_name: store.userInfo.shopName,
loginAccount: store.userInfo.loginAccount,
carts: [],
amount: printLabelOrder.orderAmount,
amount: formatDecimal(printLabelOrder.orderAmount),
discountAmount: printLabelOrder.discountRatio > 0 ? formatDecimal(printLabelOrder.orderAmount - printLabelOrder.discountAmount) : formatDecimal(printLabelOrder.orderAmount),
discount: formatDecimal(printLabelOrder.discountRatio * 10, 1, true) || 0,
remark: printLabelOrder.remark,
orderInfo: printLabelOrder,
outNumber: printLabelOrder.outNumber,
@ -219,6 +288,7 @@ async function printOrderLable() {
//
function paySuccess() {
propsDiscount.value = 0
dialogVisible.value = false;
global.setOrderMember({})
global.setOrderTable({})
@ -243,6 +313,15 @@ defineExpose({
</style>
<style scoped lang="scss">
.footer_wrap {
display: flex;
gap: 10px;
.btn {
flex: 1;
}
}
.drawer_wrap {
width: 100%;
height: 100%;
@ -310,12 +389,13 @@ defineExpose({
}
.list_wrap {
padding: var(--el-font-size-base);
padding: 0 var(--el-font-size-base);
height: calc(100vh - 200px);
overflow-y: auto;
.item {
padding-bottom: var(--el-font-size-base);
padding: var(--el-font-size-base) 0;
border-bottom: 1px solid #ececec;
.top {
display: flex;
@ -326,11 +406,12 @@ defineExpose({
}
.n {
margin-right: 50px;
width: 50px;
color: #555;
}
.p {
width: 50px;
color: #555;
}
}
@ -345,8 +426,6 @@ defineExpose({
.tag_wrap {
display: flex;
flex-wrap: wrap;
padding-top: 10px;
padding-bottom: 10px;
.tag {
padding: 2px 6px;

View File

@ -99,8 +99,13 @@
<div class="button">
<el-button type="primary" style="width: 100%" :disabled="!cartList.length" v-loading="createOrderLoading"
@click="createOrderHandle">
<span v-if="!createOrderLoading">结算({{ cartInfo.totalAmount || 0 }})</span>
<span v-else>下单中...</span>
<template v-if="!createOrderLoading">
<template v-if="!global.tableInfo.id">
结算
</template>
<template v-else>下单</template>
({{ cartInfo.totalAmount || 0 }})</template>
<template v-else>下单中...</template>
</el-button>
</div>
</div>
@ -161,6 +166,7 @@ import {
//
import goods from "@/views/home/components/goods.vue";
import member from "@/views/member/index.vue";
import { ElMessage } from "element-plus";
const global = useGlobal()
@ -200,10 +206,19 @@ async function createOrderHandle() {
masterId: masterId.value,
shopId: store.userInfo.shopId,
remark: remark.value,
vipUserId: global.orderMemberInfo.id || '',
tableId: global.tableInfo.qrcode || ''
});
orderInfo.value = res;
settleAccountRef.value.show();
createOrderLoading.value = false;
if (global.tableInfo.id) {
ElMessage.success('下单成功')
global.setOrderTable({})
createCodeAjax(1)
} else {
orderInfo.value = res;
settleAccountRef.value.show();
}
} catch (error) {
console.log(error);
createOrderLoading.value = false;
@ -216,6 +231,7 @@ async function clearCartHandle() {
await clearCart({
shopId: store.userInfo.shopId,
masterId: masterId.value,
tableId: global.tableInfo.qrcode || ''
});
queryCartAjax();
@ -247,6 +263,8 @@ async function pendingCart(params, status = true) {
masterId: params.masterId,
status: status,
uuid: params.uuid,
vipUserId: global.orderMemberInfo.id || '',
tableId: global.tableInfo.qrcode || ''
});
if (status && cartList.value.length) {
await createCodeAjax();
@ -255,6 +273,7 @@ async function pendingCart(params, status = true) {
cartLoading.value = false;
}
} catch (error) {
cartLoading.value = false;
console.log(error);
}
}
@ -317,7 +336,8 @@ async function addCart(params, type = "add") {
const res = await createCart({
productId: params.productId,
masterId: masterId.value,
tableId: global.tableInfo.id || '',
tableId: global.tableInfo.qrcode || '',
vipUserId: global.orderMemberInfo.id || '',
shopId: store.userInfo.shopId,
skuId: type == "add" ? params.id : params.skuId,
number: params.number || 1,
@ -343,6 +363,8 @@ async function queryCartAjax() {
const res = await queryCart({
masterId: masterId.value,
shopId: store.userInfo.shopId,
tableId: global.tableInfo.qrcode || '',
vipUserId: global.orderMemberInfo.id || ''
});
cartList.value = res.list;
cartInfo.value = res.amount;
@ -376,11 +398,15 @@ async function createCodeAjax(type = "0") {
// })
// masterId.value = res.code
// }
const res = await createCode({
shopId: store.userInfo.shopId,
type: type,
});
masterId.value = res.code;
if (global.tableInfo.masterId) {
masterId.value = global.tableInfo.masterId
} else {
const res = await createCode({
shopId: store.userInfo.shopId,
type: type,
});
masterId.value = res.code;
}
queryCartAjax();
if (type == 1) {
@ -396,6 +422,7 @@ async function createCodeAjax(type = "0") {
function clearMember() {
global.setOrderMember({})
global.setOrderTable({})
createCodeAjax()
}
onMounted(() => {

View File

@ -15,70 +15,66 @@
</el-icon>
<span class="t">{{ status[props.tableInfo.status] }}</span>
</div>
<div class="place_order">
<div class="cart" v-if="props.tableInfo.status == 'using'">
<div class="cart_list">
<div class="item" v-for="item in cartList" :key="item.id">
<div class="top">
<span class="name">{{ item.name }}</span>
<span class="n">x{{ item.number }}</span>
<span class="p">{{ item.salePrice }}</span>
</div>
<div class="tag_wrap" v-if="item.skuName">
<div class="tag" v-for="item in item.skuName.split(',')">
{{ item }}
</div>
</div>
</div>
</div>
<div class="btn_container">
<div class="btn_wrap">
<el-button type="success" style="width: 100%;" @click="toOrderMeal(1)">加菜</el-button>
</div>
<div class="btn_wrap">
<el-button type="primary" :loading="payLoading" style="width: 100%;" @click="showPayHandle">结算({{
orderInfo.orderAmount || 0 }})</el-button>
</div>
</div>
</div>
<div class="place_order" v-else>
<div class="btn">
<div class="top">
<el-icon class="icon">
<TakeawayBox />
</el-icon>
<span class="t">点单</span>
<!-- <span class="t">点单</span> -->
</div>
<!-- <span class="tips">开始新订单</span> -->
<div class="btn_wrap">
<el-button type="primary" style="width: 100%;" @click="toOrderMeal(1)">直接点单</el-button>
</div>
<div class="btn_wrap">
<el-button type="primary" style="width: 100%;" @click="toOrderMeal(2)">选择会员点单</el-button>
<div class="btn_wrap" v-if="props.tableInfo.status == 'idle'">
<el-button type="primary" style="width: 100%;" @click="toOrderMeal(1)">开始新订单</el-button>
</div>
</div>
</div>
<el-dialog :title="`台桌:${props.tableInfo.name} - 选择会员`" v-model="showDialog" width="80%">
<el-form inline>
<el-form-item>
<el-input placeholder="请输入手机号搜索会员" v-model="tableData.phone" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="getMemberList">搜索</el-button>
<el-button @click="resetTable">重置</el-button>
</el-form-item>
</el-form>
<el-table :data="tableData.list" height="300px" border stripe v-loading="tableData.loading">
<el-table-column prop="name" label="昵称" width="120px" />
<el-table-column prop="telephone" label="手机" width="150px" />
<el-table-column prop="code" label="编号" width="120px" />
<el-table-column prop="level" label="等级" />
<el-table-column prop="levelConsume" label="积分" />
<el-table-column prop="amount" label="余额" width="100px">
<template v-slot="scope">
{{ formatDecimal(scope.row.amount) }}
</template>
</el-table-column>
<el-table-column label="操作" width="120px">
<template v-slot="scope">
<el-button type="primary" @click="toHomeMember(scope.row)">选择</el-button>
</template>
</el-table-column>
</el-table>
<el-pagination layout="prev, pager, next, total" background style="margin-top: 20px;"
:total="Number(tableData.total)" v-model:current-page="tableData.page"
@current-change="getMemberList" />
</el-dialog>
<!-- 结算订单 -->
<settleAccount ref="settleAccountRef" :cart="cartList" :amount="orderInfo.orderAmount"
:remark="orderInfo.remark" :masterId="orderInfo.masterId" :orderInfo="orderInfo" @paySuccess="paySuccess" />
</div>
</template>
<script setup>
import { ref, reactive } from 'vue'
import { ref, reactive, onMounted, watch } from 'vue'
import { useRouter } from 'vue-router'
import { useUser } from "@/store/user.js"
import { useGlobal } from '@/store/global.js'
import { queryMembermember } from '@/api/member/index.js'
import { orderDetail } from '@/api/order/index.js'
import { formatDecimal } from '@/utils/index.js'
import settleAccount from "@/views/home/components/settleAccount.vue";
const router = useRouter()
const global = useGlobal()
const store = useUser()
const emit = defineEmits(['close'])
const emits = defineEmits(['close', 'success'])
const props = defineProps({
tableInfo: {
@ -87,16 +83,61 @@ const props = defineProps({
}
})
watch(props, () => {
getOrderDetail()
})
const settleAccountRef = ref(null)
const orderInfo = ref({})
const cartList = ref([])
const status = ref({
'subscribe': '预定',
'closed': '关台',
'opening': '开台中',
'idle': '空闲',
'using': '开台中',
'pending': '挂单中',
'paying': '结算中',
'cleaning': '台桌清理中'
})
const payLoading = ref(false)
//
function showPayHandle() {
settleAccountRef.value.show()
}
//
async function getOrderDetail() {
try {
if (!props.tableInfo.status == 'using') return
payLoading.value = true
const res = await orderDetail({
shopId: store.userInfo.shopId,
id: props.tableInfo.orderId
})
payLoading.value = false
orderInfo.value = res
cartList.value = res.detailList.map(item => {
let obj = {
name: item.productName,
number: item.num,
salePrice: item.price,
skuName: item.productSkuName
}
return obj
})
} catch (error) {
payLoading.value = false
console.log(error);
}
}
//
function close() {
emit('close')
emits('close')
}
//
@ -114,49 +155,14 @@ function toOrderMeal(t) {
}
}
const showDialog = ref(false)
const tableData = reactive({
phone: '',
loading: false,
list: [],
page: 1,
size: 10,
total: 0
function paySuccess() {
getOrderDetail()
emits('success')
}
onMounted(() => {
getOrderDetail()
})
//
function resetTable() {
tableData.phone = ''
tableData.page = 1
getMemberList()
}
//
async function getMemberList() {
try {
tableData.loading = true
const res = await queryMembermember({
shopId: store.userInfo.shopId,
phone: tableData.phone,
page: tableData.page,
pageSize: tableData.size
})
tableData.loading = false
tableData.list = res.list
tableData.total = res.total
} catch (error) {
console.log(error);
}
}
//
function toHomeMember(row) {
global.setOrderTable(props.tableInfo)
global.setOrderMember(row)
router.push({
name: 'home',
})
}
</script>
<style scoped lang="scss">
@ -202,6 +208,74 @@ function toHomeMember(row) {
}
}
.cart {
height: calc(100vh - 160px);
display: flex;
flex-direction: column;
.cart_list {
flex: 1;
border-radius: 6px;
background-color: #efefef;
padding: 0 var(--el-font-size-base);
overflow-y: auto;
.item {
padding: var(--el-font-size-base) 0;
&:not(:last-child) {
border-bottom: 1px solid #ddd;
}
.top {
display: flex;
padding-bottom: 6px;
.name {
flex: 1;
padding-right: 10px;
}
.n {
width: 50px;
color: #555;
}
.p {
width: 50px;
color: #555;
}
}
.tag_wrap {
display: flex;
flex-wrap: wrap;
.tag {
padding: 2px 6px;
background-color: var(--el-color-danger);
color: #fff;
margin-right: 10px;
margin-bottom: 10px;
font-size: 12px;
}
}
}
}
.btn_container {
display: flex;
gap: 10px;
.btn_wrap {
flex: 1;
padding-top: var(--el-font-size-base);
}
}
}
.place_order {
background-color: #efefef;
height: calc(100vh - 160px);

View File

@ -45,7 +45,7 @@
<!-- 台桌统计 -->
<countCard v-if="!slectTable.id" />
<!-- 台桌信息 -->
<tableInfo v-else :tableInfo="slectTable" @close="slectTableClose" />
<tableInfo v-else :tableInfo="slectTable" @close="slectTableClose" @success="paySuccess" />
</div>
</div>
</template>
@ -65,15 +65,15 @@ const tabActive = ref(0)
const tabAreas = ref([
{
label: '全部',
type: 0,
type: '',
},
{
label: '空闲',
type: 1,
type: 'idle',
},
{
label: '使用中',
type: 2,
type: 'using'
},
// {
// label: '',
@ -96,6 +96,13 @@ const slectTable = ref('')
//
function tabChange(item, index) {
tabActive.value = index
queryShopTableAjax()
}
//
async function paySuccess() {
await queryShopTableAjax()
slectTableHandle(tableItemActive.value, tableList.value[tableItemActive.value])
}
//
@ -134,7 +141,7 @@ async function queryShopTableAjax() {
const res = await queryShopTable({
shopId: store.userInfo.shopId,
areaId: area.value,
status: '',
status: tabAreas.value[tabActive.value].type,
page: 1,
pageSize: 500
})
@ -250,6 +257,7 @@ onMounted(() => {
justify-content: space-between;
padding: 0 10px;
color: #fff;
background-color: #999;
&.subscribe {
background-color: var(--el-color-success);
@ -259,12 +267,20 @@ onMounted(() => {
background-color: #999;
}
&.idle {
background-color: var(--primary-color);
}
&.using {
background-color: var(--el-color-success);
}
&.opening {
background-color: var(--primary-color);
}
&.cleaning {
background-color: var(--el-color-danger);
background-color: #999;
}
}