1.对接会员列表 2.对接排队叫号

This commit is contained in:
gyq 2025-03-06 19:28:01 +08:00
parent db3fc1f6dc
commit 5cf2355d28
29 changed files with 1920 additions and 1136 deletions

View File

@ -454,4 +454,8 @@ html {
} }
} }
} }
.height_auto {
overflow-y: auto;
}
</style> </style>

View File

@ -100,3 +100,135 @@ export function shopStaffInfo() {
url: "/account/admin/shopStaff/info", url: "/account/admin/shopStaff/info",
}); });
} }
/**
* 获取店铺用户充值记录
*/
export function shopUserChargeFlow(params) {
return request({
method: "get",
url: "/account/admin/shopUser/flow",
params,
});
}
/**
* 获取店铺用户充值记录
*/
export function addShopUser(data) {
return request({
method: "post",
url: "/account/admin/shopUser",
data,
});
}
/**
* 获取叫号队列
*/
export function callTableQueue(params) {
return request({
method: "get",
url: "/account/admin/callTable/queue",
params,
});
}
/**
* 获取叫号配置
*/
export function callTableConfig(params) {
return request({
method: "get",
url: "/account/admin/callTable/config",
params,
});
}
/**
* 修改叫号配置
*/
export function callTableConfigPut(data) {
return request({
method: "put",
url: "/account/admin/callTable/config",
data,
});
}
/**
* 叫号桌型新增
*/
export function addCallTable(data) {
return request({
method: "post",
url: "/account/admin/callTable",
data,
});
}
/**
* 叫号桌型删除
*/
export function delCallTable(data) {
return request({
method: "delete",
url: "/account/admin/callTable",
data,
});
}
/**
* 获取桌型列表
*/
export function getCallTable(params) {
return request({
method: "get",
url: "/account/admin/callTable",
params,
});
}
/**
* 新增叫号号码
*/
export function takeNumber(data) {
return request({
method: "post",
url: "/account/admin/callTable/takeNumber",
data,
});
}
/**
* 获取桌型列表
*/
export function callRecord(params) {
return request({
method: "get",
url: "/account/admin/callTable/callRecord",
params,
});
}
/**
* 执行叫号
*/
export function callTableCall(data) {
return request({
method: "post",
url: "/account/admin/callTable/call",
data,
});
}
/**
* 修改叫号队列状态
*/
export function callTableCallState(data) {
return request({
method: "put",
url: "/account/admin/callTable/updateState",
data,
});
}

View File

@ -104,3 +104,54 @@ export function getOrderById(params) {
}); });
} }
/**
* 会员充值 - 现金充值
* @param {*} data
* @returns
*/
export function cashPayVip(data) {
return request({
method: "post",
url: "/order/pay/cashPayVip",
data,
});
}
/**
* 会员充值 - 反扫
* @param {*} data
* @returns
*/
export function microPayVip(data) {
return request({
method: "post",
url: "/order/pay/microPayVip",
data,
});
}
/**
* 会员充值 - 会员退款前置接口
* @param {*} data
* @returns
*/
export function refundVipBefore(data) {
return request({
method: "post",
url: "/order/pay/refundVipBefore",
data,
});
}
/**
* 会员充值 - 会员退款
* @param {*} data
* @returns
*/
export function refundVip(data) {
return request({
method: "post",
url: "/order/pay/refundVip",
data,
});
}

View File

@ -13,9 +13,9 @@
</div> </div>
<div class="t1" v-else> <div class="t1" v-else>
<span class="title">会员:</span> <span class="title">会员:</span>
<span class="num">{{ <span class="num">
props.userInfo.id && props.userInfo.telephone {{ props.userInfo.id && props.userInfo.phone }}
}}</span> </span>
</div> </div>
<div class="t2"> <div class="t2">
<span>已付:0.00</span> <span>已付:0.00</span>
@ -59,29 +59,24 @@
</div> </div>
</div> </div>
</div> </div>
<scanModal ref="scanModalRef" fast :amount="money" :money="money" :selecttype="props.type" :orderId="props.userInfo.id" <scanModal ref="scanModalRef" fast :amount="money" :money="money" :selecttype="props.type"
@success="scanCodeSuccess" /> :orderId="props.userInfo.id" @success="scanCodeSuccess" />
<takeFoodCode ref="takeFoodCodeRef" title="支付密码" :type="2" input-type="password" placeholder="请输入支付密码" <takeFoodCode ref="takeFoodCodeRef" title="支付密码" :type="2" input-type="password" placeholder="请输入支付密码"
@success="passwordSuccess" /> @success="passwordSuccess" />
</template> </template>
<script setup> <script setup>
import { onMounted, ref } from "vue"; import { onMounted, ref } from "vue";
import { queryPayType, quickPay } from "@/api/pay"; import { getPayType } from '@/api/account.js'
import { import { cashPayVip } from "@/api/order.js";
queryMembermember,
createMembermember,
membermemberScanPay,
accountPaymember,
} from "@/api/member/index.js";
import { useUser } from "@/store/user.js";
import { clearNoNum } from "@/utils"; import { clearNoNum } from "@/utils";
import md5 from "js-md5"; import md5 from "js-md5";
import { queryPwdInfo } from '@/api/user.js' import { queryPwdInfo } from '@/api/user.js'
import scanModal from "@/components/payCard/scanModal.vue"; import scanModal from "@/components/payCard/scanModal.vue";
import { ElMessage } from "element-plus"; import { ElMessage } from "element-plus";
import takeFoodCode from "@/components/takeFoodCode.vue"; import takeFoodCode from "@/components/takeFoodCode.vue";
import { useUser } from '@/store/user.js'
const takeFoodCodeRef = ref(null); const takeFoodCodeRef = ref(null);
const props = defineProps({ const props = defineProps({
@ -132,14 +127,17 @@ function payTypeChange(index, item) {
async function passwordSuccess(e = '') { async function passwordSuccess(e = '') {
try { try {
payLoading.value = true; payLoading.value = true;
await accountPaymember({ await cashPayVip({
shopId: store.userInfo.shopId, shopId: store.shopInfo.id,
memberId: props.userInfo.id, shopUserId: props.userInfo.id,
amount: money.value, amount: money.value,
pwd: e ? md5(e) : '', // pwd: e ? md5(e) : '',
pwd: e,
orderId: '',
allPack: ''
}); });
payLoading.value = false; payLoading.value = false;
ElMessage.success("支付成功"); ElMessage.success("充值成功");
emit("paySuccess"); emit("paySuccess");
} catch (error) { } catch (error) {
payLoading.value = false; payLoading.value = false;
@ -176,15 +174,12 @@ async function confirmOrder() {
emit("paySuccess"); emit("paySuccess");
} else { } else {
// //
await store.getShopInfo()
let res = await queryPwdInfo() if (store.shopInfo.isMemberInPwd == 1) {
if (res.isMemberIn == 1) {
takeFoodCodeRef.value.show(); takeFoodCodeRef.value.show();
} else { } else {
passwordSuccess() passwordSuccess()
} }
// takeFoodCodeRef.value.show();
// // passwordSuccess()
} }
break; break;
default: default:
@ -215,9 +210,7 @@ function delHandle() {
// //
async function queryPayTypeAjax() { async function queryPayTypeAjax() {
try { try {
const res = await queryPayType({ const res = await getPayType();
shopId: store.userInfo.shopId,
});
const arr = []; const arr = [];
res.map((item) => { res.map((item) => {

View File

@ -1,21 +1,23 @@
<template> <template>
<div class="card"> <div class="card">
<div class="header"> <div class="header">
<div class="left">
<div class="t1"> <div class="t1">
<span class="title">应收:</span> <span class="title">应收:</span>
<span class="num">{{ money }}</span> <span class="num">{{ money }}</span>
</div> </div>
<div class="t2"> <div class="t2">
<span>原价{{ formatDecimal(props.amount) }}</span> <span>原价{{ formatDecimal(props.amount) }}</span>
<span style="margin-left: 20px;">优惠{{ formatDecimal(props.amount - money) }}</span> <span style="margin-left: 20px">优惠{{ formatDecimal(props.amount - money) }}</span>
<span style="margin-left: 20px;" v-if="props.discount" @click="cancelDiscount">折扣{{ <span style="margin-left: 20px" v-if="props.discount" @click="cancelDiscount">折扣{{
formatDecimal(props.discount * 10, 1, true) }} formatDecimal(props.discount * 10, 1, true) }}
<el-icon style="margin-left: 6px;"> <el-icon style="margin-left: 6px">
<CircleClose /> <CircleClose />
</el-icon> </el-icon>
</span> </span>
</div> </div>
</div> </div>
</div>
<div class="number_wrap"> <div class="number_wrap">
<div class="menus"> <div class="menus">
<div class="item" :class="{ active: payActive == index, disabled: item.disabled }" <div class="item" :class="{ active: payActive == index, disabled: item.disabled }"
@ -37,15 +39,18 @@
</div> --> </div> -->
</div> </div>
<div class="input_wrap"> <div class="input_wrap">
<div class="input" style="flex: 1;">储值:{{ money }}</div> <div class="input" style="flex: 1">储值{{ money }}</div>
<!-- <div class="input" v-if="waitPayMoney > 0">待支付:{{ waitPayMoney }}</div> --> <el-button type="primary" style="width: 120px;border-radius: 6px; height: 60px;"
@click="showCouponHandle">添加优惠</el-button>
</div> </div>
<div class="blance"> <div class="blance">
<!-- 可用余额0.00 --> <!-- 可用余额0.00 -->
</div> </div>
<div class="keybord_wrap"> <div class="keybord_wrap">
<div class="left"> <div class="left">
<div class="item" v-for="item in 9" :key="item" @click="amountInput(`${item}`)">{{ item }}</div> <div class="item" v-for="item in 9" :key="item" @click="amountInput(`${item}`)">
{{ item }}
</div>
<div class="item" @click="amountInput('.')">.</div> <div class="item" @click="amountInput('.')">.</div>
<div class="item" @click="amountInput('0')">0</div> <div class="item" @click="amountInput('0')">0</div>
<div class="item" @click="delHandle"> <div class="item" @click="delHandle">
@ -90,7 +95,7 @@
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<el-pagination layout="prev, pager, next, total" background style="margin-top: 20px;" <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" /> :total="Number(tableData.total)" v-model:current-page="tableData.page" @current-change="getMemberList" />
</el-dialog> </el-dialog>
<!-- 选择挂账人员 --> <!-- 选择挂账人员 -->
@ -135,64 +140,84 @@
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<el-pagination layout="prev, pager, next, total" background style="margin-top: 20px;" <el-pagination layout="prev, pager, next, total" background style="margin-top: 20px"
:total="Number(buyerTable.total)" v-model:current-page="buyerTable.page" @current-change="getBuyerList" /> :total="Number(buyerTable.total)" v-model:current-page="buyerTable.page" @current-change="getBuyerList" />
</el-dialog> </el-dialog>
<el-dialog v-model="showCoupon" title="添加优惠">
<el-form ref="couponFormRef" :model="couponForm">
<el-form-item label="会员">
<el-select>
<el-option label="会员1" value="1"></el-option>
</el-select>
</el-form-item>
</el-form>
</el-dialog>
</template> </template>
<script setup> <script setup>
import { onMounted, ref, computed, watch, reactive } from 'vue' import { onMounted, ref, computed, watch, reactive } from "vue";
import { queryPayType, accountPay, vipPay, buyerPage, payCreditPay } from '@/api/pay' import {
import { queryMembermember, createMembermember, membermemberScanPay, accountPaymember } from '@/api/member/index.js' queryPayType,
import { useUser } from "@/store/user.js" accountPay,
import { clearNoNum, formatDecimal } from '@/utils' vipPay,
buyerPage,
payCreditPay,
} from "@/api/pay";
import {
queryMembermember,
createMembermember,
membermemberScanPay,
accountPaymember,
} from "@/api/member/index.js";
import { useUser } from "@/store/user.js";
import { clearNoNum, formatDecimal } from "@/utils";
import { getPayType } from '@/api/account.js' import { getPayType } from "@/api/account.js";
import scanModal from '@/components/payCard/scanModal.vue' import scanModal from "@/components/payCard/scanModal.vue";
import { ElMessage } from "element-plus"; import { ElMessage } from "element-plus";
import { useGlobal } from '@/store/global.js' import { useGlobal } from "@/store/global.js";
import { staffPermission } from '@/api/user.js' import { staffPermission } from "@/api/user.js";
import { cashPay } from '@/api/order.js' import { cashPay } from "@/api/order.js";
import { useGoods } from '@/store/goods.js' import { useGoods } from "@/store/goods.js";
const goodsStore = useGoods() const goodsStore = useGoods();
const global = useGlobal() const global = useGlobal();
const store = useUser() const store = useUser();
const props = defineProps({ const props = defineProps({
amount: { amount: {
type: Number, type: Number,
default: 0 default: 0,
}, },
selecttype: { selecttype: {
type: Number, type: Number,
default: 0 default: 0,
}, },
orderId: { orderId: {
type: [String, Number], type: [String, Number],
default: '' default: "",
}, },
discount: { discount: {
type: [String, Number], type: [String, Number],
default: 0 default: 0,
} },
}) });
const emit = defineEmits(['paySuccess', 'cancelDiscount']) const emit = defineEmits(["paySuccess", "cancelDiscount"]);
const money = ref('0') const money = ref("0");
const scanModalRef = ref(null) const scanModalRef = ref(null);
watch(props, (value) => { watch(props, (value) => {
money.value = `${formatDecimal(props.amount)}` money.value = `${formatDecimal(props.amount)}`;
if (props.discount > 0) { if (props.discount > 0) {
money.value = `${formatDecimal(props.amount * props.discount)}` money.value = `${formatDecimal(props.amount * props.discount)}`;
} }
}) });
// const waitPayMoney = computed(() => { // const waitPayMoney = computed(() => {
// let num = JSON.stringify(props.amount - money.value) // let num = JSON.stringify(props.amount - money.value)
@ -200,54 +225,54 @@ watch(props, (value) => {
// return num // return num
// }) // })
const payActive = ref(0) const payActive = ref(0);
const payType = ref('') const payType = ref("");
const payList = ref([]) const payList = ref([]);
const payLoading = ref(false) const payLoading = ref(false);
const payData = ref({}) const payData = ref({});
// start // start
const showBuyer = ref(false) const showBuyer = ref(false);
const buyerTable = reactive({ const buyerTable = reactive({
keywords: '', keywords: "",
loading: false, loading: false,
page: 1, page: 1,
size: 10, size: 10,
total: 0, total: 0,
list: [] list: [],
}) });
// //
function showBuyerHandle() { function showBuyerHandle() {
showBuyer.value = true showBuyer.value = true;
getBuyerList() getBuyerList();
} }
// //
function resetBuyerTable() { function resetBuyerTable() {
buyerTable.keywords = '' buyerTable.keywords = "";
buyerTable.page = 1 buyerTable.page = 1;
getBuyerList() getBuyerList();
} }
// //
async function getBuyerList() { async function getBuyerList() {
try { try {
buyerTable.loading = true buyerTable.loading = true;
const res = await buyerPage({ const res = await buyerPage({
page: buyerTable.page, page: buyerTable.page,
size: buyerTable.size, size: buyerTable.size,
shopId: store.userInfo.shopId, shopId: store.userInfo.shopId,
keywords: buyerTable.keywords, keywords: buyerTable.keywords,
status: 1, status: 1,
responsiblePerson: '', responsiblePerson: "",
repaymentStatus: '' repaymentStatus: "",
}) });
buyerTable.loading = false buyerTable.loading = false;
buyerTable.list = res.list buyerTable.list = res.list;
buyerTable.total = res.total buyerTable.total = res.total;
} catch (error) { } catch (error) {
buyerTable.loading = false buyerTable.loading = false;
console.log(error); console.log(error);
} }
} }
@ -255,22 +280,23 @@ async function getBuyerList() {
// //
async function payCreditPayHandle(row) { async function payCreditPayHandle(row) {
try { try {
payLoading.value = true payLoading.value = true;
buyerTable.loading = true buyerTable.loading = true;
const res = await payCreditPay({ const res = await payCreditPay({
creditBuyerId: row.id, creditBuyerId: row.id,
orderId: props.orderId, orderId: props.orderId,
payAmount: props.discount > 0 ? money.value : '', payAmount: props.discount > 0 ? money.value : "",
discountAmount: props.discount > 0 ? formatDecimal(props.amount - money.value) : '' discountAmount:
}) props.discount > 0 ? formatDecimal(props.amount - money.value) : "",
showBuyer.value = false });
payLoading.value = false showBuyer.value = false;
buyerTable.loading = false payLoading.value = false;
ElMessage.success('支付成功') buyerTable.loading = false;
emit('paySuccess') ElMessage.success("支付成功");
emit("paySuccess");
} catch (error) { } catch (error) {
buyerTable.loading = false buyerTable.loading = false;
payLoading.value = false payLoading.value = false;
console.log(error); console.log(error);
} }
} }
@ -278,7 +304,7 @@ async function payCreditPayHandle(row) {
// //
function scanCodeSuccess() { function scanCodeSuccess() {
emit('paySuccess') emit("paySuccess");
} }
// //
@ -286,21 +312,21 @@ async function payTypeChange(index, item) {
try { try {
// await staffPermission('yun_xu_shou_kuan') // await staffPermission('yun_xu_shou_kuan')
// if (item.disabled) return // if (item.disabled) return
payActive.value = index payActive.value = index;
payType.value = item.payType payType.value = item.payType;
if (item.payType == 'scanCode') { if (item.payType == "scanCode") {
scanModalRef.value.show() scanModalRef.value.show();
} }
if (item.payType == 'vipPay') { if (item.payType == "vipPay") {
showDialog.value = true showDialog.value = true;
getMemberList() getMemberList();
} }
if (item.payType == 'buyer') { if (item.payType == "buyer") {
showBuyerHandle() showBuyerHandle();
} }
if (payActive.value != 'buyer') { if (payActive.value != "buyer") {
if (payList.value[payActive.value].payType == 'deposit') { if (payList.value[payActive.value].payType == "deposit") {
scanModalRef.value.show() scanModalRef.value.show();
} }
} }
} catch (error) { } catch (error) {
@ -311,27 +337,27 @@ async function payTypeChange(index, item) {
// //
async function confirmOrder() { async function confirmOrder() {
try { try {
payLoading.value = true payLoading.value = true;
// 使 // 使
payData.value.checkOrderPay.orderAmount = formatDecimal(+money.value) payData.value.checkOrderPay.orderAmount = formatDecimal(+money.value);
payData.value.checkOrderPay.roundAmount = formatDecimal(props.amount - money.value) payData.value.checkOrderPay.roundAmount = formatDecimal(props.amount - money.value);
payData.value.checkOrderPay.userId = goodsStore.vipUserInfo.userId ? goodsStore.vipUserInfo.userId : '' payData.value.checkOrderPay.userId = goodsStore.vipUserInfo.userId ? goodsStore.vipUserInfo.userId : "";
payData.value.checkOrderPay.vipPrice = goodsStore.vipUserInfo.userId ? 1 : 0 payData.value.checkOrderPay.vipPrice = goodsStore.vipUserInfo.userId ? 1 : 0;
await cashPay(payData.value) await cashPay(payData.value);
payLoading.value = false payLoading.value = false;
emit('paySuccess') emit("paySuccess");
return return;
await staffPermission('yun_xu_shou_kuan') await staffPermission("yun_xu_shou_kuan");
if (payLoading.value) return if (payLoading.value) return;
if (payActive.value == 'buyer') { if (payActive.value == "buyer") {
showBuyerHandle() showBuyerHandle();
} else if (payList.value[payActive.value].payType == 'scanCode') { } else if (payList.value[payActive.value].payType == "scanCode") {
scanModalRef.value.show() scanModalRef.value.show();
} else { } else {
// if (money.value < props.amount) return // if (money.value < props.amount) return
payLoading.value = true payLoading.value = true;
switch (payList.value[payActive.value].payType) { switch (payList.value[payActive.value].payType) {
case 'deposit':// case "deposit": //
// if (props.selecttype == 1) { // if (props.selecttype == 1) {
// } else { // } else {
@ -341,122 +367,125 @@ async function confirmOrder() {
await accountPay({ await accountPay({
orderId: props.orderId, orderId: props.orderId,
memberId: global.orderMemberInfo.id, memberId: global.orderMemberInfo.id,
memberAccount: '' memberAccount: "",
}) });
} else { } else {
payLoading.value = false payLoading.value = false;
scanModalRef.value.show() scanModalRef.value.show();
return return;
} }
break; break;
case 'cash':// case "cash": //
if (props.selecttype == 1) { if (props.selecttype == 1) {
await accountPaymember({ await accountPaymember({
shopId: store.userInfo.shopId, shopId: store.userInfo.shopId,
memberId: props.orderId, memberId: props.orderId,
amount: props.amount amount: props.amount,
}) });
} else { } else {
await cashPay({ await cashPay({
orderId: props.orderId, orderId: props.orderId,
payAmount: props.discount > 0 ? money.value : '', payAmount: props.discount > 0 ? money.value : "",
discountAmount: props.discount > 0 ? formatDecimal(props.amount - money.value) : '' discountAmount:
}) props.discount > 0
? formatDecimal(props.amount - money.value)
: "",
});
} }
break; break;
case 'vipPay': case "vipPay":
// //
console.log('使用会员id支付'); console.log("使用会员id支付");
payLoading.value = false payLoading.value = false;
showDialog.value = true showDialog.value = true;
return return;
break; break;
default: default:
break; break;
} }
payLoading.value = false payLoading.value = false;
ElMessage.success('支付成功') ElMessage.success("支付成功");
emit('paySuccess') emit("paySuccess");
} }
} catch (error) { } catch (error) {
console.log(error) console.log(error);
payLoading.value = false payLoading.value = false;
scanModalRef.value.loading = false scanModalRef.value.loading = false;
} }
} }
// //
function amountInput(num) { function amountInput(num) {
if (money.value + num <= props.amount) { if (money.value + num <= props.amount) {
money.value = clearNoNum({ value: (money.value += num) }) money.value = clearNoNum({ value: (money.value += num) });
} else { } else {
money.value = clearNoNum({ value: `${props.amount}` }) money.value = clearNoNum({ value: `${props.amount}` });
} }
} }
// //
function delHandle() { function delHandle() {
if (!money.value) return if (!money.value) return;
money.value = money.value.substring(0, money.value.length - 1) money.value = money.value.substring(0, money.value.length - 1);
if (!money.value) { if (!money.value) {
money.value = '0' money.value = "0";
} }
} }
// //
async function queryPayTypeAjax() { async function queryPayTypeAjax() {
try { try {
const res = await getPayType() const res = await getPayType();
res.map(item => { res.map((item) => {
if (props.amount <= 0 && item.payType == 'scanCode') { if (props.amount <= 0 && item.payType == "scanCode") {
item.disabled = true item.disabled = true;
} else { } else {
item.disabled = false item.disabled = false;
} }
}) });
payList.value = res payList.value = res;
if (res[0].payType == 'scanCode' && !res[0].disabled) { if (res[0].payType == "scanCode" && !res[0].disabled) {
scanModalRef.value.show() scanModalRef.value.show();
payType.value = res[0].payType payType.value = res[0].payType;
} }
} catch (error) { } catch (error) {
console.log(error) console.log(error);
} }
} }
const showDialog = ref(false) const showDialog = ref(false);
const tableData = reactive({ const tableData = reactive({
phone: '', phone: "",
loading: false, loading: false,
list: [], list: [],
page: 1, page: 1,
size: 10, size: 10,
total: 0 total: 0,
}) });
// //
function resetTable() { function resetTable() {
tableData.phone = '' tableData.phone = "";
tableData.page = 1 tableData.page = 1;
getMemberList() getMemberList();
} }
// //
async function getMemberList() { async function getMemberList() {
try { try {
tableData.loading = true tableData.loading = true;
const res = await queryMembermember({ const res = await queryMembermember({
shopId: store.userInfo.shopId, shopId: store.userInfo.shopId,
phone: tableData.phone, phone: tableData.phone,
page: tableData.page, page: tableData.page,
pageSize: tableData.size, pageSize: tableData.size,
isFlag: 1 isFlag: 1,
}) });
tableData.loading = false tableData.loading = false;
tableData.list = res.list tableData.list = res.list;
tableData.total = res.total tableData.total = res.total;
} catch (error) { } catch (error) {
console.log(error); console.log(error);
} }
@ -465,36 +494,54 @@ async function getMemberList() {
// //
async function toHomeMember(row) { async function toHomeMember(row) {
try { try {
showDialog.value = false showDialog.value = false;
payLoading.value = true payLoading.value = true;
const res = await vipPay({ const res = await vipPay({
orderId: props.orderId, orderId: props.orderId,
vipUserId: row.id, vipUserId: row.id,
payAmount: props.discount > 0 ? money.value : '', payAmount: props.discount > 0 ? money.value : "",
discountAmount: props.discount > 0 ? formatDecimal(props.amount - money.value) : '' discountAmount:
}) props.discount > 0 ? formatDecimal(props.amount - money.value) : "",
global.setOrderTable() });
global.setOrderMember() global.setOrderTable();
global.setOrderMember();
payLoading.value = false payLoading.value = false;
ElMessage.success('支付成功') ElMessage.success("支付成功");
emit('paySuccess') emit("paySuccess");
} catch (error) { } catch (error) {
payLoading.value = false payLoading.value = false;
console.log(error); console.log(error);
} }
} }
// //
function cancelDiscount() { function cancelDiscount() {
emit('cancelDiscount') emit("cancelDiscount");
} }
/** 添加优惠 start */
const showCoupon = ref(false)
const couponFormRef = ref(null)
const couponForm = ref({
userId: '',
discountRatio: '',
})
//
function showCouponHandle() {
showCoupon.value = true
}
/** 添加优惠 end */
onMounted(() => { onMounted(() => {
money.value = `${formatDecimal(props.amount)}` money.value = `${formatDecimal(props.amount)}`;
payData.value = { payData.value = {
shopId: store.shopInfo.id, shopId: store.shopInfo.id,
buyerRemark: '', // buyerRemark: "", //
checkOrderPay: { checkOrderPay: {
orderId: goodsStore.orderListInfo.id, orderId: goodsStore.orderListInfo.id,
vipPrice: 0, // 使 vipPrice: 0, // 使
@ -507,15 +554,16 @@ onMounted(() => {
productCouponDiscountAmount: 0, // productCouponDiscountAmount: 0, //
fullCouponDiscountAmount: 0, // fullCouponDiscountAmount: 0, //
couponList: [], // 使 couponList: [], // 使
orderAmount: formatDecimal(+goodsStore.cartInfo.totalAmount - goodsStore.cartInfo.packFee), // orderAmount: formatDecimal(
+goodsStore.cartInfo.totalAmount - goodsStore.cartInfo.packFee
), //
roundAmount: 0, // roundAmount: 0, //
pointsDiscountAmount: 0, // (tb_points_basic_setting) pointsDiscountAmount: 0, // (tb_points_basic_setting)
pointsNum: 0 // 使 ( enable_deduction使) pointsNum: 0, // 使 ( enable_deduction使)
} },
} };
queryPayTypeAjax() queryPayTypeAjax();
}) });
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@ -527,6 +575,10 @@ onMounted(() => {
.header { .header {
padding-bottom: var(--el-font-size-base); padding-bottom: var(--el-font-size-base);
border-bottom: 1px solid #ececec; border-bottom: 1px solid #ececec;
display: flex;
.left {
flex: 1;
.t1 { .t1 {
display: flex; display: flex;
@ -555,6 +607,7 @@ onMounted(() => {
} }
} }
} }
}
.number_wrap { .number_wrap {
padding: var(--el-font-size-base) 0; padding: var(--el-font-size-base) 0;

View File

@ -58,7 +58,7 @@ import { scanpay, queryOrder, quickPay, queryQuickPayStatus, accountPay, querySc
import { useUser } from "@/store/user.js"; import { useUser } from "@/store/user.js";
import { useGlobal } from '@/store/global.js' import { useGlobal } from '@/store/global.js'
import { formatDecimal } from '@/utils' import { formatDecimal } from '@/utils'
import { microPay, queryOrderStatus } from '@/api/order.js' import { microPay, queryOrderStatus, microPayVip } from '@/api/order.js'
const store = useUser(); const store = useUser();
const global = useGlobal() const global = useGlobal()
@ -76,6 +76,7 @@ const props = defineProps({
type: [Number, String], type: [Number, String],
default: 0, default: 0,
}, },
// 0 1 2
selecttype: { selecttype: {
type: [Number, String], type: [Number, String],
default: 0, default: 0,
@ -117,8 +118,20 @@ async function submitHandle() {
try { try {
if (!scanCode.value) return; if (!scanCode.value) return;
loading.value = true; loading.value = true;
if (props.selecttype == 1) { if (props.selecttype == 0) {
await microPay(props.payData); //
await microPay({
...props.payData,
authCode: scanCode.value
});
} else if (props.selecttype == 1) {
//
await microPayVip({
shopId: store.shopInfo.id,
shopUserId: props.orderId,
amount: props.amount,
authCode: scanCode.value
})
} else { } else {
if (props.fast) { if (props.fast) {
await quickPay({ await quickPay({
@ -128,11 +141,11 @@ async function submitHandle() {
}); });
} else { } else {
if (props.payType == 'scanCode') { if (props.payType == 'scanCode') {
// if (props.selecttype == 1) {
await microPay({
...props.payData, } else if (props.selecttype == 2) {
authCode: scanCode.value
}); }
emits('success') emits('success')
} }
if (props.payType == 'deposit') { if (props.payType == 'deposit') {

View File

@ -14,22 +14,23 @@
<script setup> <script setup>
import { ref } from 'vue'; import { ref } from 'vue';
import useStorage from '@/utils/useStorage' import userStore from '@/utils/useStorage.js'
import { ElUpload, ElMessage } from 'element-plus'; import { ElUpload, ElMessage } from 'element-plus';
const fileList = ref([]) const fileList = ref([])
// //
const props = defineProps({ const props = defineProps({
uploadUrl: { uploadUrl: {
type: String, type: String,
default: import.meta.env.MODE == 'development' ? '/api/shopInfo/upload' : import.meta.env.VITE_API_URL + '/shopInfo/upload', default: import.meta.env.MODE == 'development' ? '/api/account/admin/common/upload' : import.meta.env.VITE_API_URL + '/account/admin/common/upload',
}, },
headers: { headers: {
type: Object, type: Object,
default: () => ({ default: () => ({
token: useStorage.get("token"), token: userStore.get('token'),
loginName: useStorage.get("userInfo").loginName, shopId: userStore.get('shopInfo').id,
clientType: 'pc' clientType: 'pc'
}), }),
}, },
@ -110,5 +111,3 @@ defineExpose({
init init
}) })
</script> </script>
<style scoped></style>

View File

@ -110,6 +110,44 @@ export const useGlobal = defineStore("global", {
label: "现金支付", label: "现金支付",
}, },
], ],
bizCodes: [
{
type: "cashIn",
label: "现金充值",
},
{
type: "wechatIn",
label: "微信小程序充值",
},
{
type: "alipayIn",
label: "支付宝小程序充值",
},
{
type: "awardIn",
label: "充值奖励",
},
{
type: "rechargeRefund",
label: "充值退款",
},
{
type: "orderPay",
label: "订单消费",
},
{
type: "orderRefund",
label: "订单退款",
},
{
type: "adminIn",
label: "管理员充值",
},
{
type: "adminOut",
label: "管理员消费",
},
],
}), }),
actions: { actions: {
// 更新状态 // 更新状态

View File

@ -385,12 +385,13 @@ export const useGoods = defineStore("goods", {
this.operateCart({ table_code: tableCode }, "cleanup"); this.operateCart({ table_code: tableCode }, "cleanup");
}, },
// 清空购物车回执操作 // 清空购物车回执操作
successClearCart() { successClearCart(clearOrder = false) {
this.cartList = []; this.cartList = [];
this.cartInfo = {}; this.cartInfo = {};
if (clearOrder) {
this.orderList = []; this.orderList = [];
this.orderListInfo = ""; this.orderListInfo = "";
}
this.calcCartInfo(); this.calcCartInfo();
}, },
// 下单成功清除购物车,重新加载订单 // 下单成功清除购物车,重新加载订单

View File

@ -171,7 +171,7 @@ export const useSocket = defineStore("socket", {
startheartbeat() { startheartbeat() {
this.heartbeatTimer = setInterval(() => { this.heartbeatTimer = setInterval(() => {
if (this.log) console.log("发送心跳"); if (this.log) console.log("发送心跳");
this.ws.send(JSON.stringify({ type: "heartbeat" })); this.ws.send(JSON.stringify({ type: "ping_interval" }));
}, 10000); }, 10000);
}, },
// 清除心跳 // 清除心跳

View File

@ -1,5 +1,5 @@
import { defineStore } from "pinia"; import { defineStore } from "pinia";
import { login, shopStaffInfo } from "@/api/account.js"; import { login, shopStaffInfo, shopInfo_detail } from "@/api/account.js";
import useStorage from "@/utils/useStorage"; import useStorage from "@/utils/useStorage";
export const useUser = defineStore("user", { export const useUser = defineStore("user", {
@ -29,5 +29,15 @@ export const useUser = defineStore("user", {
console.log(error); console.log(error);
} }
}, },
// 更新店铺信息
async getShopInfo() {
try {
const res = await shopInfo_detail();
useStorage.set("shopInfo", res);
this.shopInfo = useStorage.get("shopInfo");
} catch (error) {
console.log(error);
}
},
}, },
}); });

View File

@ -178,3 +178,13 @@ export function commOrderPrintData(orderInfo) {
return data; return data;
} }
/**
* 校验手机号
* @param {*} phone
* @returns
*/
export function regPhone(phone) {
let reg = /^(?:(?:\+|00)86)?1\d{10}$/;
return reg.test(phone);
}

View File

@ -194,10 +194,10 @@ function payTypeFilter(t) {
// //
const typeList = reactive([ const typeList = reactive([
{ // {
value: 1, // value: 1,
label: '自营' // label: ''
}, // },
{ {
value: 2, value: 2,
label: '抖音' label: '抖音'

View File

@ -82,7 +82,8 @@
<el-text>{{ item.skuList[0].salePrice }}</el-text> <el-text>{{ item.skuList[0].salePrice }}</el-text>
</template> </template>
<template v-else> <template v-else>
<el-text tag="del" class="del" size="small">{{ item.skuList[0].salePrice }}</el-text> <el-text tag="del" class="del" size="small">{{ item.skuList[0].salePrice
}}</el-text>
<el-text>{{ item.skuList[0].memberPrice }}</el-text> <el-text>{{ item.skuList[0].memberPrice }}</el-text>
</template> </template>
</div> </div>
@ -412,7 +413,7 @@ function searchHandle() {
// //
function skuConfirm(params) { function skuConfirm(params) {
console.log(params); // console.log(params);
let goodsItem = goodsStore.cartList.find(goods => goods.product_id == params.productId && goods.sku_id == params.id) let goodsItem = goodsStore.cartList.find(goods => goods.product_id == params.productId && goods.sku_id == params.id)
if (goodsItem && goodsItem.id) { if (goodsItem && goodsItem.id) {
// //
@ -427,9 +428,13 @@ function skuConfirm(params) {
} }
} else { } else {
// //
if (params.type == 'weight') {
goodsStore.addCart({ ...params, number: params.number })
} else {
goodsStore.addCart({ ...params, number: params.suitNum }) goodsStore.addCart({ ...params, number: params.suitNum })
} }
} }
}
// //
function showMoreMenu() { function showMoreMenu() {
@ -1028,9 +1033,11 @@ defineExpose({
padding: 6px 10px; padding: 6px 10px;
background-color: var(--primary-color); background-color: var(--primary-color);
position: relative; position: relative;
.price_warp { .price_warp {
display: flex; display: flex;
align-items: center; align-items: center;
.del { .del {
color: #fff; color: #fff;
position: relative; position: relative;

View File

@ -34,9 +34,9 @@
<div class="button"> <div class="button">
<el-checkbox v-model="isPrint" border label="打印结算小票" style="width: 100%" /> <el-checkbox v-model="isPrint" border label="打印结算小票" style="width: 100%" />
</div> </div>
<div class="print"> <!-- <div class="print">
<el-button type="warning" :loading="discountLoading" @click="showStaffDiscountHandle">添加折扣</el-button> <el-button type="warning" :loading="discountLoading" @click="showStaffDiscountHandle">添加折扣</el-button>
</div> </div> -->
<div class="print"> <div class="print">
<el-button type="primary" :loading="printLoading" @click="printHandle">打印预结单</el-button> <el-button type="primary" :loading="printLoading" @click="printHandle">打印预结单</el-button>
</div> </div>
@ -297,7 +297,7 @@ function paySuccess() {
dialogVisible.value = false; dialogVisible.value = false;
ElMessage.success('支付成功') ElMessage.success('支付成功')
goodsStore.successClearCart() goodsStore.successClearCart(!cartList.length)
// printOrderLable() // printOrderLable()
// emit("paySuccess"); // emit("paySuccess");
} }

View File

@ -11,10 +11,10 @@
<div class="number" @click="SelectVipUserRef.show()"> <div class="number" @click="SelectVipUserRef.show()">
<div class="left"> <div class="left">
<el-icon class="icon"> <el-icon class="icon">
<UserFilled /> <CirclePlus />
</el-icon> </el-icon>
<template v-if="!goodsStore.vipUserInfo.id"> <template v-if="!goodsStore.vipUserInfo.id">
<el-text class="t">选择会员</el-text> <span class="t">选择会员</span>
</template> </template>
<template v-else> <template v-else>
<div class="user_info" @click="goodsStore.vipUserInfo = ''"> <div class="user_info" @click="goodsStore.vipUserInfo = ''">
@ -69,7 +69,7 @@
<div class="table_info" v-if="goodsStore.tableInfo.name"> <div class="table_info" v-if="goodsStore.tableInfo.name">
<div class="left"> <div class="left">
<span>台桌{{ goodsStore.tableInfo.name }}</span> <span>台桌{{ goodsStore.tableInfo.name }}</span>
<span>{{ goodsStore.tableInfo.num }}</span> <span>{{ goodsStore.tableInfo.num || 1 }}</span>
</div> </div>
<div class="close" @click="goodsStore.selectTable()"> <div class="close" @click="goodsStore.selectTable()">
<el-icon class="icon"> <el-icon class="icon">
@ -390,7 +390,7 @@ function clearVipUserHandle() {
.menu { .menu {
background-color: var(--el-color-warning); background-color: var(--el-color-warning);
color: #fff; color: #fff;
width: 60px; width: 80px;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
@ -415,11 +415,11 @@ function clearVipUserHandle() {
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
background-color: var(--el-color-info-light-7); background-color: var(--el-color-info-light-7);
padding: 0 10px;
.left { .left {
display: flex; display: flex;
align-items: center; align-items: center;
margin-left: 14px;
} }
.icon_wrap { .icon_wrap {
@ -430,8 +430,8 @@ function clearVipUserHandle() {
justify-content: center; justify-content: center;
.u_icon { .u_icon {
font-size: 20px; font-size: 16px;
color: #999; color: var(--el-color-primary);
.i { .i {
display: flex; display: flex;
@ -446,7 +446,10 @@ function clearVipUserHandle() {
.t { .t {
font-size: var(--el-font-size-base); font-size: var(--el-font-size-base);
margin-left: 4px; color: var(--el-color-primary);
margin-left: 6px;
position: relative;
top: -1px;
} }
.user_info { .user_info {
@ -465,8 +468,9 @@ function clearVipUserHandle() {
.p { .p {
width: 83px; width: 83px;
flex: 1; flex: 1;
color: #999; color: var(--el-color-primary);
font-size: 14px; font-size: 14px;
margin-left: 6px;
} }
} }
} }

View File

@ -146,6 +146,8 @@ const submitHandle = () => {
store store
.userlogin(form) .userlogin(form)
.then(async (res) => { .then(async (res) => {
console.log(res);
// //
// useStorage.set('merchantLoginAccount', form.username) // useStorage.set('merchantLoginAccount', form.username)
ElMessage.success("登录成功"); ElMessage.success("登录成功");
@ -156,7 +158,7 @@ const submitHandle = () => {
}); });
}, 1000); }, 1000);
// const douyin = await douyincheckIn({ // const douyin = await douyincheckIn({
// token: res.token, // token: store.token,
// loginName: res.loginName, // loginName: res.loginName,
// clientType: 'pc' // clientType: 'pc'
// }) // })

View File

@ -0,0 +1,163 @@
<template>
<el-dialog v-model="showDialog" title="添加会员" top="10vh" @closed="resetHandle">
<div class="height_auto" style="height: 400px;">
<el-form ref="formRef" :model="form" :rules="rules" label-width="100px" label-position="left">
<el-form-item label="用户头像">
<UploadImg ref="UploadImgRef" @success="e => form.headImg = e" />
</el-form-item>
<el-form-item label="用户昵称" prop="nickName">
<el-input v-model="form.nickName" placeholder="请输入用户昵称"></el-input>
</el-form-item>
<el-form-item label="电话号码" prop="phone">
<el-input v-model="form.phone" placeholder="请输入电话号码"
@input="phoneInput($event, 'phone')"></el-input>
</el-form-item>
<el-form-item label="会员生日">
<el-date-picker v-model="form.birthDay" type="date" format="YYYY-MM-DD" value-format="YYYY-MM-DD"
placeholder="请选择会员生日">
</el-date-picker>
</el-form-item>
<el-form-item label="性别">
<el-radio-group v-model="form.sex">
<el-radio-button label="男" :value="1"></el-radio-button>
<el-radio-button label="女" :value="0"></el-radio-button>
</el-radio-group>
</el-form-item>
<el-form-item label="账户积分">
<el-input v-model="form.accountPoints" placeholder="请输入账户积分"
@input="phoneInput($event, 'accountPoints')"></el-input>
</el-form-item>
<el-form-item label="钱包余额">
<el-input v-model="form.amount" placeholder="请输入钱包余额"
@input="phoneInput($event, 'amount')"></el-input>
</el-form-item>
<el-form-item label="是否会员">
<el-radio-group v-model="form.isVip">
<el-radio-button label="否" :value="0"></el-radio-button>
<el-radio-button label="是" :value="1"></el-radio-button>
</el-radio-group>
</el-form-item>
</el-form>
</div>
<div class="footer">
<div class="btn">
<el-button style="width: 100%;" @click="closeHandle">取消</el-button>
</div>
<div class="btn">
<el-button type="primary" style="width: 100%;" @click="confirmHandle">确定</el-button>
</div>
</div>
</el-dialog>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import UploadImg from '@/components/uploadImg.vue'
import { addShopUser } from '@/api/account.js'
import { ElMessage } from 'element-plus'
import { inputFilterInt, regPhone, inputFilterFloat } from '@/utils/index.js'
const emits = defineEmits(['success'])
const UploadImgRef = ref(null)
const showDialog = ref(false)
const formRef = ref(null)
const form = ref({
headImg: '', //
nickName: '', //
phone: '', //
birthDay: '', //
sex: '', // 0- 1
accountPoints: '', //
amount: '', //
isVip: 0, //
})
const rules = ref({
nickName: [
{
required: true,
message: '请输入用户昵称',
trigger: 'blur',
}
],
phone: [
{
required: true,
validator: (rule, value, callback) => {
if (!value) {
return callback(new Error('请输入电话号码'))
} else if (!regPhone(value)) {
return callback(new Error('请输入正确的电话号码'))
} else {
callback()
}
},
trigger: 'blur',
}
]
})
const resetForm = ref({})
function phoneInput(e, key) {
if (key == 'amount') {
setTimeout(() => {
form.value[key] = inputFilterFloat(e)
}, 50)
} else {
setTimeout(() => {
form.value[key] = inputFilterInt(e)
}, 50)
}
}
//
function confirmHandle() {
formRef.value.validate(async valid => {
try {
if (valid) {
await addShopUser(form.value)
ElMessage.success('添加成功')
closeHandle()
emits('success')
}
} catch (error) {
console.log(error);
}
})
}
function closeHandle() {
showDialog.value = false
}
function resetHandle() {
form.value = { ...resetForm.value }
}
function show() {
showDialog.value = true
}
defineExpose({
show
})
onMounted(() => {
resetForm.value = { ...form.value }
})
</script>
<style scoped lang="scss">
.footer {
display: flex;
gap: var(--el-font-size-base);
padding-top: var(--el-font-size-base);
.btn {
flex: 1;
}
}
</style>

View File

@ -1,26 +1,25 @@
<template> <template>
<el-dialog v-model="visableDialog" title="余额明细" width="500"> <el-dialog v-model="visableDialog" title="余额明细" top="10vh" width="500" @closed="closeHandle">
<div class="box"> <div class="box">
<div class="box1" v-loading="tableData.loading"> <div class="box1" v-loading="tableData.loading">
<div class="dialog_footer" v-for="(item, index) in tableData.list" :key="index"> <div class="dialog_footer" v-for="(item, index) in tableData.list" :key="index">
<div class="dialog_footer_left"> <div class="dialog_footer_left">
<span>{{ item.biz_name }}</span> <span>{{ labelFilter(item.bizCode) }}</span>
<span>{{ dayjs(item.create_time).format("YYYY-MM-DD HH:mm:ss") }}</span> <span>{{ item.createTime }}</span>
</div> </div>
<div class="dialog_footer_right"> <div class="dialog_footer_right">
<span :class="{ active: item.type == '+' }"> <span :class="{ active: item.amount > 0 }">
<template v-if="item.type == '+'">+</template> <template v-if="item.amount > 0">+</template>
<template v-else>-</template>
{{ formatDecimal(item.amount) }} {{ formatDecimal(item.amount) }}
</span> </span>
<span>余额{{ formatDecimal(item.balance) }}</span> <span>余额{{ formatDecimal(item.balance) }}</span>
</div> </div>
<div class="btm" style="width: 80px;"> <div class="btm" style="width: 80px;">
<el-button type="primary" <el-button type="primary"
v-if="item.biz_code == 'scanMemberIn' || item.biz_code == 'cashMemberIn'" v-if="item.bizCode == 'cashIn' || item.bizCode == 'wechatIn' || item.bizCode == 'alipayIn'"
@click="showRefundHandle(item)" :disabled="item.is_return == 1"> @click="showRefundHandle(item)" :disabled="item.refundAmount > 0">
<template v-if="item.is_return == 0">退款</template> <template v-if="item.refundAmount == 0">退款</template>
<template v-if="item.is_return == 1">已退</template> <template v-if="item.refundAmount > 0">已退</template>
</el-button> </el-button>
</div> </div>
</div> </div>
@ -30,11 +29,29 @@
<el-pagination v-model:current-page="tableData.page" background layout="prev, pager, next, total" <el-pagination v-model:current-page="tableData.page" background layout="prev, pager, next, total"
:total="tableData.total" @current-change="memberqueryMemberAccountAjax" /> :total="tableData.total" @current-change="memberqueryMemberAccountAjax" />
</div> </div>
<el-dialog v-model="showDialog" title="会员充值退款"> <el-dialog v-model="showDialog" top="1vh" title="会员充值退款">
<el-form ref="formRef" :model="form" :rules="rules" label-width="100"> <el-form ref="formRef" :model="form" :rules="rules" label-width="100">
<el-form-item label="当前余额">
<span>{{ refundItem.amount }}</span>
</el-form-item>
<el-form-item label="充值金额">
<span>{{ refundItem.inAmount }}</span>
</el-form-item>
<el-form-item label="已退金额">
<el-input v-model="refundItem.inRefundAmount" disabled />
</el-form-item>
<template v-if="refundItem.giftAmount - refundItem.giftRefundAmount > 0">
<el-form-item label="赠送金额">
<el-input v-model="refundItem.giftAmount" disabled />
</el-form-item>
<el-form-item label="已退赠送金额">
<el-input v-model="refundItem.giftRefundAmount" disabled />
</el-form-item>
</template>
<el-form-item label="退款金额" prop="amount"> <el-form-item label="退款金额" prop="amount">
<el-input-number v-model="form.amount" :min="1" :max="refundItem.amount" <el-input-number v-model="form.amount" :min="0.01" :max="form.max" placeholder="请输入退款金额" />
placeholder="请输入退款金额" /> <div class="tips" v-if="refundItem.giftAmount - refundItem.giftRefundAmount > 0">
注意一旦退款赠送金额{{ refundItem.giftAmount }}也将全额退还</div>
</el-form-item> </el-form-item>
<el-form-item label="退款说明"> <el-form-item label="退款说明">
<el-input v-model="form.remark" placeholder="请输入退款说明" /> <el-input v-model="form.remark" placeholder="请输入退款说明" />
@ -55,17 +72,21 @@
<script setup> <script setup>
import md5 from "js-md5"; import md5 from "js-md5";
import { onMounted, reactive, ref } from 'vue' import { reactive, ref } from 'vue'
import { dayjs, ElMessage } from 'element-plus' import { dayjs, ElMessage } from 'element-plus'
import { formatDecimal } from '@/utils/index' import { formatDecimal } from '@/utils/index'
import { shopUserChargeFlow } from '@/api/account.js'
import { refundVipBefore, refundVip } from '@/api/order.js'
import { returnFlow, memberqueryMemberAccount } from '@/api/member/index.js' import { returnFlow, memberqueryMemberAccount } from '@/api/member/index.js'
import { queryPwdInfo, staffPermission } from '@/api/user.js' import { queryPwdInfo, staffPermission } from '@/api/user.js'
import takeFoodCode from "@/components/takeFoodCode.vue"; import takeFoodCode from "@/components/takeFoodCode.vue";
import { useGlobal } from '@/store/global.js'
import { useUser } from '@/store/user.js'
const memberId = ref('') const userStore = useUser()
const globalStore = useGlobal()
const userInfo = ref('')
const visableDialog = ref(false) const visableDialog = ref(false)
const tableData = reactive({ const tableData = reactive({
page: 1, page: 1,
total: 0, total: 0,
@ -73,18 +94,37 @@ const tableData = reactive({
list: [] list: []
}) })
//
function closeHandle() {
tableData.page = 1
tableData.total = 0
tableData.loading = false
tableData.list = []
}
//
function labelFilter(type) {
let item = globalStore.bizCodes.find(item => item.type == type)
if (item) {
return item.label
} else {
return type
}
}
// //
async function memberqueryMemberAccountAjax() { async function memberqueryMemberAccountAjax() {
try { try {
tableData.loading = true tableData.loading = true
let res = await memberqueryMemberAccount({ let res = await shopUserChargeFlow({
memberId: memberId.value, userId: userInfo.value.userId,
bizCode: '',
page: tableData.page, page: tableData.page,
pageSize: 10 pageSize: 10
}) })
tableData.loading = false tableData.loading = false
tableData.total = res.total tableData.total = +res.totalRow
tableData.list = res.list tableData.list = res.records
} catch (error) { } catch (error) {
console.log(error); console.log(error);
} }
@ -95,7 +135,8 @@ const emits = defineEmits(['refund'])
const takeFoodCodeRef = ref(null) const takeFoodCodeRef = ref(null)
const showDialog = ref(false) const showDialog = ref(false)
const form = reactive({ const form = reactive({
amount: 1, amount: 0,
max: 999,
remark: '' remark: ''
}) })
const rules = reactive({ const rules = reactive({
@ -110,12 +151,28 @@ const rules = reactive({
const loading = ref(false) const loading = ref(false)
const refundItem = ref({}) const refundItem = ref({})
const formRef = ref(null) const formRef = ref(null)
const flowItem = ref({})
// 退
async function showRefundHandle(item) { async function showRefundHandle(item) {
try { try {
await staffPermission('yun_xu_tui_kuan') // await staffPermission('yun_xu_tui_kuan')
refundItem.value = item // 退
form.amount = item.amount flowItem.value = item
const res = await refundVipBefore({
shopId: item.shopId,
userId: item.userId,
flowId: item.id
})
refundItem.value = res
if (res.amount - res.giftAmount - res.giftRefundAmount >= (res.inAmount - res.inRefundAmount)) {
form.amount = formatDecimal(res.inAmount - res.inRefundAmount, 2, true)
} else {
form.amount = formatDecimal(res.amount - res.giftAmount - res.giftRefundAmount, 2, true)
}
form.max = form.amount
showDialog.value = true showDialog.value = true
} catch (error) { } catch (error) {
console.log(error); console.log(error);
@ -128,9 +185,10 @@ function refundHandle() {
try { try {
if (valid) { if (valid) {
loading.value = true loading.value = true
let res = await queryPwdInfo() //
await userStore.getShopInfo()
loading.value = false loading.value = false
if (res.isMemberReturn == 1) { if (userStore.shopInfo.isMemberInPwd == 1) {
takeFoodCodeRef.value.show(); takeFoodCodeRef.value.show();
} else { } else {
passwordSuccess() passwordSuccess()
@ -147,11 +205,15 @@ function refundHandle() {
async function passwordSuccess(e = '') { async function passwordSuccess(e = '') {
try { try {
loading.value = true loading.value = true
const res = await returnFlow({ await refundVip({
flowId: refundItem.value.id, shopId: flowItem.value.shopId,
userId: flowItem.value.userId,
flowId: flowItem.value.id,
refAmount: form.amount,
remark: form.remark, remark: form.remark,
amount: form.amount, outOfRange: false,
pwd: e ? md5(e) : '', cashRefund: true,
pwd: e,
}) })
ElMessage.success('退款成功') ElMessage.success('退款成功')
form.amount = 1 form.amount = 1
@ -159,15 +221,15 @@ async function passwordSuccess(e = '') {
showDialog.value = false showDialog.value = false
loading.value = false loading.value = false
emits('refund') emits('refund')
memberqueryMemberAccountAjax() // memberqueryMemberAccountAjax()
} catch (error) { } catch (error) {
loading.value = false loading.value = false
console.log(error); console.log(error);
} }
} }
function show(id) { function show(row) {
memberId.value = id userInfo.value = row
visableDialog.value = true visableDialog.value = true
memberqueryMemberAccountAjax() memberqueryMemberAccountAjax()
} }

View File

@ -33,7 +33,9 @@ function paySuccess() {
function show() { function show() {
dialogVisible.value = true; dialogVisible.value = true;
setTimeout(() => {
fastPayCardRef.value.reset(); fastPayCardRef.value.reset();
}, 100)
} }
defineExpose({ defineExpose({

View File

@ -0,0 +1,807 @@
<template>
<div class="orderbox">
<div class="orderbox_left">
<div class="demo_tabs" v-if="props.membershow == '0'">
<div class="demo_tabs_div">
<el-input v-model="tableData.phone" placeholder="请输入手机号" @input="inputChange" clearable @focus="
global.updateData(false)" @blur="global.updateData(true)" />
<el-button style="margin-left: 10px;" type="primary" @click="addMemberHandle">添加</el-button>
</div>
</div>
<el-table :data="tableData.list" style="width: 100%;margin-top: 10px;height:80%;"
:row-class-name="tableRowClassName" @cell-click="cellclicktableData" v-loading="loading">
<el-table-column prop="name" label="昵称" />
<el-table-column prop="telephone" label="手机" width="200px" />
<el-table-column prop="code" label="编号" width="150px" />
<el-table-column prop="level" label="等级" />
<el-table-column prop="levelConsume" label="积分" />
<el-table-column prop="amount" label="余额" />
</el-table>
<el-pagination layout="prev, pager, next, jumper" style="margin-top: 20px;" :total="Number(tableData.total)"
@current-change="handleCurrentChange" />
</div>
<div class="orderbox_right">
<div class="orderbox_right_top">
<div class="orderbox_right_topdiv">
<span>会员昵称</span>
<span>{{ tableData.list.length != 0 ? tableData.list[datarow].name : '无' }}</span>
</div>
<div class="orderbox_right_topdiv">
<span>手机号码</span>
<span>{{ tableData.list.length != 0 ? tableData.list[datarow].telephone : '无' }}</span>
</div>
<div class="orderbox_right_topdiv">
<span>会员编号</span>
<span>{{ tableData.list.length != 0 ? tableData.list[datarow].code : '无' }}</span>
</div>
<div class="orderbox_right_topdiv">
<span>会员等级</span>
<span>{{ tableData.list.length != 0 ? tableData.list[datarow].level : '无' }}</span>
</div>
<div class="orderbox_right_top_item">
<div class="orderbox_right_top_item_one">
<el-icon :size="24" style="color:#ffbc42 ;">
<Money />
</el-icon>
<span class="orderbox_right_top_item_onespan">会员积分</span>
</div>
<div class="orderbox_right_top_item_tow">{{ tableData.list.length != 0 ?
tableData.list[datarow].levelConsume : '无' }}</div>
</div>
<div class="orderbox_right_top_item" @click="dialogRef.show(tableData.list[datarow].id)">
<div class="orderbox_right_top_item_one">
<el-icon :size="24" style="color:#00b58d ;">
<Box />
</el-icon>
<span class="orderbox_right_top_item_onespan">储值余额</span>
</div>
<div class="orderbox_right_top_item_tow">
<span>{{ tableData.list.length != 0 ? tableData.list[datarow].amount : '无' }}</span>
<el-icon size="10">
<ArrowRight />
</el-icon>
</div>
</div>
<!-- <div class="orderbox_right_top_item">
<div class="orderbox_right_top_item_one">
<el-icon :size="24" style="color:#00b58d ;">
<CopyDocument />
</el-icon>
<span class="orderbox_right_top_item_onespan">优惠券</span>
</div>
<div class="orderbox_right_top_item_tow">
<span>0</span>
<el-icon size="10">
<ArrowRight />
</el-icon>
</div>
</div> -->
</div>
<div class="orderbox_right_input" style="margin-top:20px ;" v-if="props.membershow == '1'">
<el-input placeholder="请输入会员手机号或者编号" v-model="tableData.phone" clearable
@input="inputChange"></el-input>
</div>
<keyboard v-if="props.membershow == '1'" @consumeFees="consumeFees"></keyboard>
<div class="orderbox_right_button" v-if="props.membershow == '0'">
<!-- <el-button style="width: 100%;" @click="toHome">创建订单</el-button> -->
<!-- <el-button style="width: 60%;" type="primary" @click="recharge = true">账户充值</el-button> -->
<el-button style="width: 100%;" type="primary" @click="menberAddNnum">账户充值</el-button>
</div>
<div class="orderbox_right_button" v-if="props.membershow == '1'">
<router-link to="/" style="width: 35%;">
<el-button style="width: 100%;" @click="memberaddshowclose">添加会员</el-button>
</router-link>
<el-button style="width: 60%;" type="primary">确认</el-button>
</div>
</div>
<add ref="dialogRef" @refund="refundSuccess" @page-change="MemberAccount" />
<el-dialog v-model="memberaddshow" title="添加会员" width="600" :before-close="memberaddshowclose"
@open="membrform = { ...resetMembrform }">
<el-form ref="formRef" :rules="rules" :model="membrform" label-width="70px" hide-required-asterisk>
<el-form-item label="手机号" prop="phone">
<el-input v-model="membrform.phone" @focus="
global.updateData(false)" @blur="global.updateData(true)" />
</el-form-item>
<el-form-item label="昵称" prop="nickName">
<el-input v-model="membrform.nickName" @focus="
global.updateData(false)" @blur="global.updateData(true)" />
</el-form-item>
<el-form-item label="生日" prop="birthDay">
<el-col :span="11">
<el-date-picker v-model="membrform.birthDay" type="date" placeholder="请选择生日" style="width: 100%"
@focus="
global.updateData(false)" @blur="global.updateData(true)" />
</el-col>
</el-form-item>
<el-form-item label="性别" prop="sex">
<el-radio-group v-model="membrform.sex">
<el-radio :label="1"></el-radio>
<el-radio :label="2"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="等级" prop="level">
<el-select v-model="membrform.level" placeholder="请选择等级">
<el-option label="等级1" value="1" />
<el-option label="等级2" value="2" />
<el-option label="等级3" value="3" />
<el-option label="等级4" value="4" />
<el-option label="等级5" value="5" />
<el-option label="等级6" value="6" />
</el-select>
</el-form-item>
<el-form-item>
<el-button style="width: 100%;" type="primary" @click="createMembermemberSubmit">确认</el-button>
</el-form-item>
</el-form>
</el-dialog>
<el-dialog v-model="recharge" title="会员充值" width="400" :before-close="handlerecharge">
<div class="recharge_footer">
<!-- <div class="recharge_footer_item">
<div class="recharge_footer_items" v-for="(item, index) in 6" :key="index">
<div>充1000送300</div>
<div>充1000.00到13000.00</div>
</div>
</div> -->
<div class="recharge_footer_itemright">
<div class="recharge_footer_itemright_input">
<div>充值金额</div>
<div v-if="moneys">{{ moneys ? moneys : '请输入充值金额' }}</div>
</div>
<div class='keyboard'>
<cwxeyboard @confirmEvent="confirmEvent" @consumeFee="consumeFee" btn-color="orange" title="支付">
</cwxeyboard>
</div>
</div>
</div>
</el-dialog>
</div>
<el-dialog width="500" v-model="payCarddialogVisible" style="padding: 0; " title="会员充值"
:close-on-click-modal="false">
<payCard :amount="moneys" :orderId="orderId" :selecttype="1" @paySuccess="paySuccess" />
</el-dialog>
<userCharge ref="userChargeRef" :userInfo="tableData.list[datarow]" @paySuccess="asyncqueryMembermember" />
</template>
<script setup>
import { ref, reactive, watch, onMounted } from 'vue'
import { ElMessage, dayjs } from 'element-plus'
import { queryMembermember, createMembermember, memberqueryMemberAccount, accountPaymember } from '@/api/member/index.js'
import { useUser } from "@/store/user.js"
import lodash from 'lodash'
import add from '@/views/member/components/add.vue'
import cwxeyboard from '@/components/cwx-keyboard/cwx-keyboard.vue'
import keyboard from '@/views/home/components/keyboard.vue'
import payCard from '@/components/payCard/payCard.vue'
import { useRouter } from 'vue-router'
import useStorage from '@/utils/useStorage'
import userCharge from './components/userCharge.vue'
import { staffPermission } from '@/api/user.js'
import { useGlobal } from '@/store/global.js'
const global = useGlobal()
const userChargeRef = ref(null)
const router = useRouter()
const store = useUser()
const stored = ref(false)//
const handleClose = async () => {
stored.value = !stored.value
}
const dialogRef = ref(null)
const emit = defineEmits('paySuccess')
function paySuccess() {
payCarddialogVisible.value = false
recharge.value = false
moneys.value = 0
asyncqueryMembermember()
emit('paySuccess')
}
const props = defineProps({//
membershow: {
type: String,
default: '0'
},
placeholder: {
type: String,
default: '提示'
},
amount: {
type: [Number, String],
default: 0
}
})
const loading = ref(false)
const flowingwater = reactive({//
total: '',
list: []
})
const consumeFee = (e) => { //
moneys.value = e
}
const consumeFees = (e) => {
tableData.phone = e
}
const payCarddialogVisible = ref(false)
const orderId = ref('')
//
async function addMemberHandle() {
try {
await staffPermission('yun_xu_guan_li_hui_yuan_xin_xi')
memberaddshow.value = true
} catch (error) {
console.log(error);
}
}
//
async function menberAddNnum() {
try {
await staffPermission('yun_xu_xiu_gai_hui_yuan_yu_e')
userChargeRef.value.show()
} catch (error) {
console.log(error);
}
}
// 退
function refundSuccess() {
asyncqueryMembermember()
MemberAccount()
}
const confirmEvent = async () => {//
orderId.value = tableData.list[datarow.value].id
payCarddialogVisible.value = true
// try {
// let res = await accountPaymember({
// shopId: store.userInfo.shopId,
// memberId: tableData.list[datarow.value].id,
// amount: moneys.value
// })
// if (res == null) {
// recharge.value = false
// moneys.value = 0
// ElMessage({
// message: '',
// type: 'success',
// })
// resetMembrform.value = { ...membrform.value }
// asyncqueryMembermember()
// }
// } catch (error) {
// }
}
const MemberAccount = async (page = 1) => {//
try {
let res = await memberqueryMemberAccount({
memberId: tableData.list[datarow.value].id,
page: page,
pageSize: 10
})
flowingwater.total = res.total
// flowingwater.list = res.list
} catch (error) {
}
}
const recharge = ref(false)//
const memberaddshow = ref(false) //
const memberaddshowclose = () => {
memberaddshow.value = !memberaddshow.value
}
const tableData = reactive({//
list: [],
page: 1,
pageSize: 10,
phone: '',
total: ''
})
const inputChange = lodash.debounce(function () { //
asyncqueryMembermember()
}, 500)
const asyncqueryMembermember = async () => {//
loading.value = true
let res = await queryMembermember({
shopId: store.userInfo.shopId,
page: tableData.page,
pageSize: 10,
phone: tableData.phone,
isFlag: 0
})
if (res) {
setTimeout(() => {
loading.value = false
}, 300)
tableData.list = res.list
MemberAccount()
tableData.total = res.total
}
}
const tableRowClassName = ({ row, rowIndex }) => {//tab
if (rowIndex === datarow.value) {
return 'warning-row'
} return ''
}
const datarow = ref(0) //
const cellclicktableData = (row, column, cell, event) => {
const index = tableData.list.findIndex(item => item.id == row.id)
datarow.value = index
MemberAccount()
}
const handleCurrentChange = (val) => { //
tableData.page = val
datarow.value = 0
asyncqueryMembermember()
}
const handlerecharge = () => {
recharge.value = !recharge.value
}
const resetMembrform = ref({})
const membrform = ref({ //membrform
phone: '',
nickName: '',
level: '',
birthDay: '',
sex: '',
level: ''
})
const formRef = ref(null); //ref membrform
const rules = reactive({ // membrform
phone: [
{
required: true,
message: "请输入11位手机号码",
trigger: "blur",
},
],
nickName: [
{
required: true,
message: "请输入昵称",
trigger: "blur",
},
],
sex: [
{
required: true,
message: "请选择性别",
trigger: 'change',
},
],
level: [
{
required: true,
message: "请选择等级",
trigger: 'change',
},
],
birthDay: [
{
type: 'date',
required: true,
message: '请选择生日日期',
trigger: 'change',
},
],
});
const createMembermemberSubmit = async () => { ///
formRef.value.validate(async (valid) => {
console.log(valid)
if (valid) {
let res = await createMembermember({
shopId: store.userInfo.shopId,
phone: membrform.value.phone,
nickName: membrform.value.nickName,
sex: membrform.value.sex,
level: membrform.value.level,
birthDay: dayjs(membrform.value.birthDay).format("YYYY-MM-DD")
})
if (res == null) {
memberaddshowclose()
ElMessage({
message: '添加成功',
type: 'success',
})
asyncqueryMembermember()
}
}
});
}
const moneys = ref('')//
//
const toHome = () => {
// useStorage.set('memberInfo', tableData.list[datarow.value])
global.setOrderMember(tableData.list[datarow.value])
router.push({
name: 'home'
})
}
onMounted(() => {
// resetMembrform.value = { ...membrform.value }
asyncqueryMembermember()
})
</script>
<style scoped lang="scss">
.orderbox {
display: flex;
height: 100%;
.orderbox_left {
width: 60%;
height: 100%;
background: #fff;
border-radius: 10px;
padding: 16px 0;
.demo_tabs {
.demo_tabs_div {
padding: 0 20px;
display: flex;
}
.demo_tabs_box {
width: 100%;
padding: 10px 20px;
.demo_tabs_boxitem {
width: 100%;
padding: 6px 16px;
border-radius: 6px;
display: flex;
justify-content: space-between;
// background: #eeeeee;
border-bottom: 1px solid #ccc;
.demo_tabs_boxitem_one {
display: flex;
justify-content: flex-start;
.demo_tabs_boxitem_oneone {
display: flex;
margin-left: 20px;
flex-direction: column;
height: 70px;
justify-content: space-around;
}
.demo_tabs_boxitem_onetow {
display: flex;
margin-left: 20px;
flex-direction: column;
height: 70px;
justify-content: space-around;
}
}
}
.demo_tabs_boxitem_tow {
display: flex;
flex-direction: column;
height: 70px;
justify-content: space-around;
align-items: flex-end;
}
}
}
}
.orderbox_right {
position: relative;
width: 40%;
padding: 20px;
margin-left: 10px;
background: #fff;
border-radius: 10px;
.orderbox_right_top {
color: #fff;
width: 100%;
background: #8b008b;
padding: 10px;
border-radius: 10px;
.orderbox_right_topdiv:nth-child(1) {
margin-top: 0px;
}
.orderbox_right_topdiv {
display: flex;
margin-top: 10px;
justify-content: space-between;
}
.orderbox_right_top_item {
position: relative;
background: #fff;
padding: 6px 10px;
display: flex;
margin-top: 10px;
border-radius: 10px;
justify-content: space-between;
align-items: center;
.orderbox_right_top_item_one {
display: flex;
align-items: center;
.orderbox_right_top_item_onespan {
color: black;
margin-left: 10px;
font-size: 16px;
}
}
.orderbox_right_top_item_tow {
color: black;
margin-left: 10px;
font-size: 14px;
font-weight: bold;
}
}
}
.orderbox_right_button {
position: absolute;
width: 90%;
left: 50%;
bottom: 16px;
display: flex;
justify-content: space-between;
align-items: center;
transform: translateX(-50%) !important;
}
}
.dialog_footer:nth-child(1) {
margin-top: 0;
}
.dialog_footer {
margin-top: 10px;
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid #ccc;
padding-bottom: 6px;
.dialog_footer_left {
display: flex;
flex-direction: column;
align-items: flex-start;
span:nth-child(1) {
font-size: 18px;
font-weight: 500;
}
span:nth-child(2) {
margin-top: 10px;
color: #333;
}
}
.dialog_footer_right {
display: flex;
flex-direction: column;
align-items: flex-end;
span:nth-child(1) {
color: #fc3d3d;
font-size: 16px;
}
span:nth-child(2) {
margin-top: 10px;
font-size: 14px;
}
}
}
.recharge_footer {
display: flex;
justify-content: space-between;
.recharge_footer_item {
width: 60%;
background: #f2f2f2;
border-radius: 10px;
padding: 20px;
display: flex;
justify-content: space-between;
flex-flow: wrap;
.recharge_footer_items {
background: #187ead;
padding: 16px 22px;
width: 45%;
height: fit-content;
text-align: center;
border-radius: 10px;
div:nth-child(1) {
color: #fff;
font-size: 20px;
}
div:nth-child(2) {
color: #bad9e7;
font-size: 14px;
}
}
}
.recharge_footer_itemright {
padding-left: 20px;
width: 100%;
position: relative;
bottom: 0;
left: 0;
.recharge_footer_itemright_input {
width: 100%;
background: #333333;
border-radius: 10px;
padding: 0 6px;
display: flex;
height: 60px;
justify-content: space-between;
align-items: center;
div:nth-child(1) {
color: #56792e;
font-size: 16px;
}
div:nth-child(2) {
color: #88937c;
font-size: 20px;
}
}
.keyboard {
width: 100%;
height: 40vh;
background: #FFFFFF;
.key-row {
display: flex;
display: -webkit-flex;
position: relative;
height: 10vh;
line-height: 10vh;
}
}
.keyboard .key-cell {
flex: 1;
-webkit-box-flex: 1;
font-size: 30px;
display: flex;
justify-content: center;
align-items: center;
}
.keyboard .key-confirm {
position: absolute;
text-align: center;
height: 30vh;
width: 25%;
line-height: 30vh;
color: #FFFFFF;
z-index: 5;
right: 0;
bottom: 0;
display: flex;
justify-content: center;
align-items: center;
}
.keyboard .key-confirm2 {
position: absolute;
height: 10vh;
width: 25%;
line-height: 10vh;
z-index: 9999;
right: 0;
top: 60px;
font-size: 30px;
display: flex;
justify-content: center;
align-items: center;
}
.key-zero-and-point {
display: flex;
height: 10vh;
justify-content: center;
align-items: center;
width: 75%;
font-size: 30px;
.zero {
display: flex;
justify-content: center;
align-items: center;
width: 66.66%;
font-size: 30px;
text-align: center;
height: 100%;
}
.point {
display: flex;
justify-content: center;
align-items: center;
width: 33.33%;
font-size: 30px;
text-align: center;
height: 100%;
}
}
.key-cell:active {
color: white;
background: black; //
opacity: 0.1; //
}
.a:active,
.key-confirm2:active {
color: white;
background: black; //
opacity: 0.1; //
}
}
}
}
</style>

File diff suppressed because it is too large Load Diff

View File

@ -1,25 +1,12 @@
<template> <template>
<div class="container"> <div class="container">
<div class="query_wrap"> <div class="query_wrap">
<el-input <el-input v-model="queryForm.orderNo" placeholder="请输入订单编号" style="width: 240px"></el-input>
v-model="queryForm.orderNo"
placeholder="请输入订单编号"
style="width: 240px"
></el-input>
<!-- <el-input v-model="queryForm.productName" placeholder="请输入商品名称" style="width: 200px;"></el-input> --> <!-- <el-input v-model="queryForm.productName" placeholder="请输入商品名称" style="width: 200px;"></el-input> -->
<el-select <el-select v-model="queryForm.status" placeholder="订单状态" style="width: 140px" @change="queryFormHandle">
v-model="queryForm.status"
placeholder="订单状态"
style="width: 140px"
@change="queryFormHandle"
>
<el-option label="全部" value=""></el-option> <el-option label="全部" value=""></el-option>
<el-option <el-option :label="item.label" :value="item.type" v-for="item in globalStore.orderStatus"
:label="item.label" :key="item.type"></el-option>
:value="item.type"
v-for="item in globalStore.orderStatus"
:key="item.type"
></el-option>
</el-select> </el-select>
<DateRange ref="DateRangeRef" @success="dateSucess" /> <DateRange ref="DateRangeRef" @success="dateSucess" />
<div class="flex"> <div class="flex">
@ -29,18 +16,8 @@
</div> </div>
<div class="table_wrap"> <div class="table_wrap">
<div class="table"> <div class="table">
<el-table <el-table :data="tableData.list" v-loading="tableData.loading" border strip height="100%">
:data="tableData.list" <el-table-column label="台桌" prop="tableName" width="80"></el-table-column>
v-loading="tableData.loading"
border
strip
height="100%"
>
<el-table-column
label="台桌"
prop="tableName"
width="80"
></el-table-column>
<el-table-column label="订单信息" width="240"> <el-table-column label="订单信息" width="240">
<template v-slot="scope"> <template v-slot="scope">
<div class="column"> <div class="column">
@ -88,26 +65,14 @@
{{ filterLable("orderStatus", scope.row.status) }} {{ filterLable("orderStatus", scope.row.status) }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column label="操作" width="150" align="center" fixed="right">
label="操作"
width="150"
align="center"
fixed="right"
>
<template v-slot="scope"> <template v-slot="scope">
<div class="column"> <div class="column">
<div class="row"> <div class="row">
<el-button <el-button type="primary" @click="RefundDrawerRef.show(scope.row)">订单退款</el-button>
type="primary"
@click="RefundDrawerRef.show(scope.row)"
>订单退款</el-button
>
</div> </div>
<div class="row" style="margin-top: 10px"> <div class="row" style="margin-top: 10px">
<el-button <el-button type="success" @click="PrintDrawerRef.show(scope.row)">
type="success"
@click="PrintDrawerRef.show(scope.row)"
>
订单打印 订单打印
</el-button> </el-button>
</div> </div>
@ -117,16 +82,9 @@
</el-table> </el-table>
</div> </div>
<div class="pagination"> <div class="pagination">
<el-pagination <el-pagination background v-model:current-page="queryForm.page" v-model:page-size="queryForm.size"
background :page-sizes="[10, 30, 50, 100]" layout="sizes, pager, jumper, total" :total="tableData.total"
v-model:current-page="queryForm.page" @size-change="orderListAjax" @current-change="orderListAjax"></el-pagination>
v-model:page-size="queryForm.size"
:page-sizes="[10, 30, 50, 100]"
layout="sizes, pager, jumper, total"
:total="tableData.total"
@size-change="orderListAjax"
@current-change="orderListAjax"
></el-pagination>
</div> </div>
</div> </div>
</div> </div>

View File

@ -27,6 +27,9 @@
<template #append></template> <template #append></template>
</el-input> </el-input>
</el-form-item> </el-form-item>
<el-form-item label="顺延数量" v-if="addTabForm.isPostpone">
<el-input-number v-model="addTabForm.postponeNum" :min="1" placeholder="请输入顺延数量" />
</el-form-item>
</el-form> </el-form>
<div class="footer" style="display: flex;"> <div class="footer" style="display: flex;">
<el-button style="width: 100%" @click="showAddTable = false"> <el-button style="width: 100%" @click="showAddTable = false">
@ -42,7 +45,7 @@
<script setup> <script setup>
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
import { ref, onMounted } from 'vue' import { ref, onMounted } from 'vue'
import { addCallTable } from '@/api/queue.js' import { addCallTable } from '@/api/account.js'
import { useUser } from "@/store/user.js" import { useUser } from "@/store/user.js"
const store = useUser() const store = useUser()
@ -59,6 +62,7 @@ const addTabForm = ref({
prefix: '', prefix: '',
start: '', start: '',
isPostpone: 0, isPostpone: 0,
postponeNum: 1, //
nearNum: '' nearNum: ''
}) })

View File

@ -26,7 +26,7 @@
<script setup> <script setup>
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
import { onMounted, ref } from 'vue'; import { onMounted, ref } from 'vue';
import { takeNumber } from '@/api/queue.js' import { takeNumber } from '@/api/account.js'
import { useUser } from "@/store/user.js" import { useUser } from "@/store/user.js"
const store = useUser() const store = useUser()
@ -41,7 +41,7 @@ const formRef = ref(null)
const resetForm = ref({}) const resetForm = ref({})
const form = ref({ const form = ref({
callTableId: '', callTableId: '',
shopId: '', userId: '',
phone: '', phone: '',
note: '', note: '',
name: '' name: ''
@ -70,9 +70,12 @@ function confirmHandle() {
try { try {
if (vaild) { if (vaild) {
loading.value = true loading.value = true
form.value.shopId = store.userInfo.shopId
form.value.note = list.value.find(item => item.id == form.value.callTableId).note form.value.note = list.value.find(item => item.id == form.value.callTableId).note
form.value.name = list.value.find(item => item.id == form.value.callTableId).name form.value.name = list.value.find(item => item.id == form.value.callTableId).name
console.log(form.value);
await takeNumber(form.value) await takeNumber(form.value)
loading.value = false loading.value = false
ElMessage.success('取号成功') ElMessage.success('取号成功')
@ -103,6 +106,6 @@ defineExpose({
}) })
onMounted(() => { onMounted(() => {
resetForm.value = { ...form } resetForm.value = { ...form.value }
}) })
</script> </script>

View File

@ -25,8 +25,8 @@
<script setup> <script setup>
import { dayjs } from 'element-plus' import { dayjs } from 'element-plus'
import { onMounted, reactive, ref } from 'vue'; import { reactive, ref } from 'vue';
import { callRecord } from '@/api/queue.js' import { callRecord } from '@/api/account.js'
import { useUser } from "@/store/user.js" import { useUser } from "@/store/user.js"
const store = useUser() const store = useUser()
@ -72,16 +72,16 @@ async function callRecordAjax() {
tableData.loading = true tableData.loading = true
const res = await callRecord({ const res = await callRecord({
callTableId: '', callTableId: '',
shopId: store.userInfo.shopId, shopId: store.shopInfo.id,
page: tableData.page, page: tableData.page,
size: tableData.size size: tableData.size
}) })
tableData.loading = false
tableData.list = res.records tableData.list = res.records
tableData.total = res.total tableData.total = +res.totalRow
} catch (error) { } catch (error) {
console.log(error); console.log(error);
} }
tableData.loading = false
} }
function reset() { function reset() {

View File

@ -3,7 +3,7 @@
<el-dialog title="提示" v-model="visible"> <el-dialog title="提示" v-model="visible">
<div class="content"> <div class="content">
<div style="font-size: 18px;">正在叫号请稍等</div> <div style="font-size: 18px;">正在叫号请稍等</div>
<el-alert :title="statusList[item.status].text" :type="statusList[item.status].type" :closable="false" /> <el-alert :title="statusList[item.state].text" :type="statusList[item.state].type" :closable="false" />
</div> </div>
<div class="footer" style="display: flex;"> <div class="footer" style="display: flex;">
<el-button style="width: 100%" @click="confirmHandle(2)">完成</el-button> <el-button style="width: 100%" @click="confirmHandle(2)">完成</el-button>
@ -13,8 +13,8 @@
</template> </template>
<script setup> <script setup>
import { onMounted, reactive, ref } from 'vue'; import { ref } from 'vue';
import { updateState } from '@/api/queue.js' import { callTableCallState } from '@/api/account.js'
import { useUser } from "@/store/user.js" import { useUser } from "@/store/user.js"
const store = useUser() const store = useUser()
@ -41,8 +41,7 @@ const statusList = {
// //
async function confirmHandle(state) { async function confirmHandle(state) {
try { try {
await updateState({ await callTableCallState({
shopId: store.userInfo.shopId,
callQueueId: item.value.id, callQueueId: item.value.id,
state: state state: state
}) })

View File

@ -36,7 +36,7 @@
<el-form-item label="排队即将排到通知"> <el-form-item label="排队即将排到通知">
<div style="display: flex;flex-direction: column;"> <div style="display: flex;flex-direction: column;">
<el-input disabled style="width: 50%;" v-model="config.nearMsg"></el-input> <el-input disabled style="width: 50%;" v-model="config.nearMsg"></el-input>
<el-input v-model="config.nearNum" disabled style="margin-top: 10px;"> <el-input v-model="config.nearNum" style="margin-top: 10px;">
<template #prepend>前面等待</template> <template #prepend>前面等待</template>
<template #append>桌时提醒</template> <template #append>桌时提醒</template>
</el-input> </el-input>
@ -64,8 +64,8 @@ import UploadImg from '@/components/uploadImg.vue'
import { ElMessageBox, ElMessage } from 'element-plus' import { ElMessageBox, ElMessage } from 'element-plus'
import AddTab from './addTab.vue' import AddTab from './addTab.vue'
import { onMounted, reactive, ref } from 'vue'; import { reactive, ref } from 'vue';
import { callTable, delCallTable, callTableConfig, callTableConfigPut } from '@/api/queue.js' import { callTableConfig, callTableConfigPut, getCallTable, delCallTable } from '@/api/account.js'
import { useUser } from "@/store/user.js" import { useUser } from "@/store/user.js"
const store = useUser() const store = useUser()
@ -103,8 +103,7 @@ function delCallTableHandle(row) {
ElMessageBox.confirm('确认要删除吗?', '注意').then(async () => { ElMessageBox.confirm('确认要删除吗?', '注意').then(async () => {
try { try {
tableData.loading = true tableData.loading = true
const res = await delCallTable({ await delCallTable({
shopId: store.userInfo.shopId,
callTableId: row.id callTableId: row.id
}) })
getTableAjax() getTableAjax()
@ -118,10 +117,10 @@ function delCallTableHandle(row) {
async function getTableAjax() { async function getTableAjax() {
try { try {
tableData.loading = true tableData.loading = true
const res = await callTable({ const res = await getCallTable({
page: 1, page: 1,
size: 100, size: 100,
shopId: store.userInfo.shopId, shopId: store.shopInfo.id,
callTableId: '', callTableId: '',
state: '' state: ''
}) })
@ -138,7 +137,7 @@ const config = ref({})
const UploadImgRef = ref(null) const UploadImgRef = ref(null)
async function callTableConfigAjax() { async function callTableConfigAjax() {
try { try {
const res = await callTableConfig({ shopId: store.userInfo.shopId }) const res = await callTableConfig({ shopId: store.shopInfo.id })
config.value = res config.value = res
form.value.nearNum = res.nearNum form.value.nearNum = res.nearNum
if (res.bgCover) { if (res.bgCover) {

View File

@ -38,7 +38,7 @@
<el-empty description="暂无数据~" v-if="!queueList.list.length" style="width: 100%;" /> <el-empty description="暂无数据~" v-if="!queueList.list.length" style="width: 100%;" />
</div> </div>
</div> </div>
<div class="pagination"> <div class="pagination" style="display: flex;justify-content: flex-end;">
<el-pagination v-model:current-page="queueList.page" v-model:page-size="queueList.size" <el-pagination v-model:current-page="queueList.page" v-model:page-size="queueList.size"
layout="total, prev, pager, next" :total="queueList.total" background layout="total, prev, pager, next" :total="queueList.total" background
@current-change="queueListChange" @size-change="queueListChange"> @current-change="queueListChange" @size-change="queueListChange">
@ -64,7 +64,7 @@ import Record from './components/record.vue'
import GetNumber from './components/getNumber.vue' import GetNumber from './components/getNumber.vue'
import ResultModal from './components/resultModal.vue' import ResultModal from './components/resultModal.vue'
import { onMounted, reactive, ref } from 'vue'; import { onMounted, reactive, ref } from 'vue';
import { callRecord, callTable, callTableQueue, updateState, callTableCall } from '@/api/queue.js' import { callTableQueue, getCallTable, callTableCall, callTableCallState } from '@/api/account.js'
import { useUser } from "@/store/user.js" import { useUser } from "@/store/user.js"
const store = useUser() const store = useUser()
@ -78,10 +78,9 @@ const tabHeader = ref([])
const tabActive = ref('') const tabActive = ref('')
async function callTableAjax() { async function callTableAjax() {
try { try {
const res = await callTable({ const res = await getCallTable({
page: 1, page: 1,
size: 100, size: 100,
shopId: store.userInfo.shopId,
callTableId: '', callTableId: '',
state: '' state: ''
}) })
@ -111,17 +110,16 @@ async function callTableQueueAjax() {
const res = await callTableQueue({ const res = await callTableQueue({
page: queueList.page, page: queueList.page,
size: queueList.size, size: queueList.size,
shopId: store.userInfo.shopId, shopId: store.shopInfo.id,
callTableId: tabActive.value, callTableId: tabActive.value,
state: '' state: ''
}) })
queueList.loading = false
queueList.list = res.records queueList.list = res.records
queueList.total = res.total queueList.total = +res.totalRow
} catch (error) { } catch (error) {
console.log(error); console.log(error);
queueList.loading = false
} }
queueList.loading = false
} }
// end // end
@ -129,8 +127,7 @@ async function callTableQueueAjax() {
function cancaleHandle(item) { function cancaleHandle(item) {
ElMessageBox.confirm('确定要取消排队吗?', '注意').then(async () => { ElMessageBox.confirm('确定要取消排队吗?', '注意').then(async () => {
try { try {
await updateState({ await callTableCallState({
shopId: store.userInfo.shopId,
callQueueId: item.id, callQueueId: item.id,
state: '-1' state: '-1'
}) })
@ -147,7 +144,6 @@ async function callHandle(item) {
try { try {
startSpeech(`${item.callNum}用餐`) startSpeech(`${item.callNum}用餐`)
const res = await callTableCall({ const res = await callTableCall({
shopId: store.userInfo.shopId,
callQueueId: item.id, callQueueId: item.id,
}) })
ResultModalRef.value.show({ ResultModalRef.value.show({