优化商品编辑

This commit is contained in:
gyq 2025-03-12 18:24:33 +08:00
parent 48c9f24d4c
commit cfe9f7bb36
18 changed files with 574 additions and 223 deletions

View File

@ -194,3 +194,16 @@ export function vipPay(data) {
data,
});
}
/**
* 订单打印
* @param {*} data
* @returns
*/
export function orderPrint(data) {
return request({
method: "post",
url: "/order/admin/order/print",
data,
});
}

View File

@ -25,3 +25,29 @@ export function productPage(params) {
params,
});
}
/**
* 商品上下架
* @param {*} data
* @returns
*/
export function productOnOff(data) {
return request({
method: "post",
url: "/product/admin/product/onOff",
data,
});
}
/**
* 商品售罄
* @param {*} data
* @returns
*/
export function markIsSoldOut(data) {
return request({
method: "post",
url: "/product/admin/product/markIsSoldOut",
data,
});
}

View File

@ -12,7 +12,7 @@ export default (data) => {
LODOP.SET_PRINTER_INDEX(data.deviceName);
// 文字内容
let html = `
<div style="font-size: 30px;display:flex;justify-content:center;">
<div style="font-size: 24px;display:flex;justify-content:center;">
${data.shopName}
</div>
<div style="font-size: 16px;display: flex; justify-content:center;margin-top:6px;">

View File

@ -17,20 +17,15 @@ export default (data) => {
let t1 = 40;
let t2 = (100 - t1) / 3;
let html = `
<div style="font-size: 22px;display:flex;justify-content:center;">
<div style="font-size: 24px;display:flex;justify-content:center;">
${data.shop_name}
</div>
<div style="font-size: 16px;display: flex; justify-content:center;margin-top:6px;">
${data.isBefore ? "预" : ""}结算单${
data.orderInfo.masterId ? data.orderInfo.masterId : ""
}
${data.isBefore ? "预" : ""}结算单
</div>
<div style="font-size: 16px;display: flex; justify-content:center;margin-top:6px;">
桌号${data.orderInfo && data.orderInfo.tableName || ''}
</div>
<div style="font-size: 16px;display: flex; justify-content:center;margin-top:20px;">
${data.orderInfo.outNumber ? data.orderInfo.outNumber : ""}
</div>
<div style="margin-top: 30px;font-size: 12px;">
订单号${data.orderInfo && data.orderInfo.orderNo}
</div>

View File

@ -13,12 +13,9 @@ export default (data) => {
let t1 = 40;
let t2 = (100 - t1) / 3;
let html = `
<div style="font-size: 30px;display:flex;justify-content:center;">
<div style="font-size: 24px;display:flex;justify-content:center;">
${data.shop_name}
</div>
<div style="font-size: 16px;display: flex; justify-content:center;margin-top:6px;">
退款单${data.orderInfo.masterId ? data.orderInfo.masterId : ""}
</div>
<div style="font-size: 16px;display: flex; justify-content:center;margin-top:6px;">
桌号${data.orderInfo && data.orderInfo.tableName || ''}
</div>

View File

@ -43,8 +43,48 @@ export const useGoods = defineStore("goods", {
originGoodsList: [], // 原始商品列表
orderList: [], // 订单列表
orderListInfo: "", // 历史订单信息
cartType: "cart", // cart order
cartOrderItem: "",
}),
actions: {
// 选中订单中的商品
selectOrderItem(index = null, i) {
this.orderList.map((item) => {
item.goods.map((val) => {
val.active = false;
});
});
if (index !== null) {
this.selectCartItemHandle();
this.cartType = "order";
if (this.orderList.length) {
if (!this.orderList[index].goods[i].active) {
this.orderList[index].goods[i].active = true;
} else {
this.orderList[index].goods[i].active = false;
}
this.cartOrderItem = this.orderList[index].goods[i];
}
}
},
// 选中购物车商品
selectCartItemHandle(index = null) {
this.cartList.map((val) => {
val.active = false;
});
if (index !== null) {
this.selectOrderItem();
this.cartType = "cart";
this.cartActiveIndex = index;
if (this.cartList.length) {
this.cartList[index].active = true;
}
}
},
// 手动选择台桌
selectTable(tableInfo = {}) {
const socket = useSocket();
@ -95,6 +135,9 @@ export const useGoods = defineStore("goods", {
async initGoods() {
await this.getCategoryList();
await this.getGoodsList();
let tableCode = useStorage.get("tableCode");
if (tableCode) this.historyOrderAjax(tableCode);
},
// 切换商品分类
setCategoryIndex(index) {
@ -104,7 +147,11 @@ export const useGoods = defineStore("goods", {
if (index == 0) {
// this.getGoodsList();
this.goodsList = _.chunk(this.originGoodsList, 12);
} else {
}
// else if (this.categoryList[index].id == "off_sale") {
// // 筛选已下架的商品
// }
else {
// 除了全部,其他只做本地筛选
this.goodsList = _.chunk(
this.originGoodsList.filter(
@ -138,7 +185,7 @@ export const useGoods = defineStore("goods", {
});
// this.categoryList.push({
// name: "已下架",
// id: "-1",
// id: "off_sale",
// });
} catch (error) {
console.log(error);
@ -169,17 +216,6 @@ export const useGoods = defineStore("goods", {
console.log(error);
}
},
// 选中购物车商品
selectCartItemHandle(index) {
this.cartActiveIndex = index;
if (this.cartList.length) {
this.cartList.map((val) => {
val.active = false;
});
this.cartList[index].active = true;
}
},
// 获取购物车列表,数据必须由长链接返回
async getCartList(arr) {
const store = useUser();
@ -436,6 +472,7 @@ export const useGoods = defineStore("goods", {
arr.map((val, index) => {
let lowPrice = 0;
let number = val.number - (val.returnNum || 0);
if (this.vipUserInfo.id && store.shopInfo.isMemberPrice) {
lowPrice = val.memberPrice;
@ -443,7 +480,7 @@ export const useGoods = defineStore("goods", {
lowPrice = val.lowPrice;
}
total += +val.number;
total += number;
if (+val.pack_number && !val.is_temporary) {
packFeeNumber += +val.pack_number;
@ -452,39 +489,39 @@ export const useGoods = defineStore("goods", {
if (val.is_temporary) {
if (val.is_gift) {
gifNumber += +val.number;
gifNumberAmount += +val.number * +val.discount_sale_amount;
gifNumber += +number;
gifNumberAmount += +number * +val.discount_sale_amount;
} else {
// 临时菜使用discount_sale_amount计算价格
totalAmount += val.number * val.discount_sale_amount;
totalAmount += number * val.discount_sale_amount;
}
} else {
if (val.is_gift) {
// 赠送
if (+val.discount_sale_amount) {
// 且有折扣
gifNumber += +val.number;
gifNumberAmount += +val.number * val.discount_sale_amount;
gifNumber += +number;
gifNumberAmount += +number * val.discount_sale_amount;
saleNumber += +val.number;
saleNumber += +number;
saleNumberAmount +=
val.number * (lowPrice - val.discount_sale_amount);
number * (lowPrice - val.discount_sale_amount);
} else {
gifNumber += +val.number;
gifNumberAmount += +val.number * +lowPrice;
gifNumber += +number;
gifNumberAmount += +number * +lowPrice;
}
} else {
if (+val.discount_sale_amount) {
// 代表打过折
saleNumber += +val.number;
saleNumber += +number;
saleNumberAmount +=
val.number * (lowPrice - val.discount_sale_amount);
number * (lowPrice - val.discount_sale_amount);
// 使用正常价减去折扣价格计算
totalAmount += val.number * val.discount_sale_amount;
totalAmount += number * val.discount_sale_amount;
} else {
// 使用正常价格计算
totalAmount += val.number * lowPrice;
totalAmount += number * lowPrice;
}
}
}

View File

@ -102,7 +102,7 @@ export const usePrint = defineStore("print", {
// 执行打印操作
this.startLabelPrint();
} else {
console.log("没有标签打印机");
console.log("标签打印:未在本机查询到打印机");
}
},
// 开始打印标签数据
@ -154,7 +154,7 @@ export const usePrint = defineStore("print", {
this.receiptList.push(props);
this.startReceiptPrint();
} else {
console.log("订单小票:没有小票打印机");
console.log("订单小票:未在本机查询到打印机");
}
}
},
@ -177,10 +177,10 @@ export const usePrint = defineStore("print", {
this.deviceNoteList.length &&
this.checkLocalPrint(this.deviceNoteList[0].address)
) {
data.address = this.deviceNoteList[0].address;
data.deviceName = this.deviceNoteList[0].address;
lodopPrintWork(data);
} else {
console.log("交班小票:没有小票打印机");
console.log("交班小票:未在本机查询到打印机");
}
},
// 打印订单发票
@ -189,10 +189,10 @@ export const usePrint = defineStore("print", {
this.deviceNoteList.length &&
this.checkLocalPrint(this.deviceNoteList[0].address)
) {
data.address = this.deviceNoteList[0].address;
data.deviceName = this.deviceNoteList[0].address;
invoicePrint(data);
} else {
console.log("订单发票:没有小票打印机");
console.log("订单发票:未在本机查询到打印机");
}
},
// 打印退单小票
@ -201,10 +201,10 @@ export const usePrint = defineStore("print", {
this.deviceNoteList.length &&
this.checkLocalPrint(this.deviceNoteList[0].address)
) {
data.address = this.deviceNoteList[0].address;
data.deviceName = this.deviceNoteList[0].address;
refundPrint(data);
} else {
console.log("退单小票:没有小票打印机");
console.log("退单小票:未在本机查询到打印机");
}
},
},

View File

@ -66,10 +66,6 @@ export const useUser = defineStore("user", {
this.token = "";
socket.close();
setTimeout(() => {
window.onload();
}, 1000);
} catch (error) {
console.log(error);
}

View File

@ -65,8 +65,8 @@
<div class="icon_item bao" v-if="+props.item.pack_number">
<span class="t">打包({{ +props.item.pack_number }})</span>
</div>
<div class="icon_item tui" v-if="props.item.status == 'return'">
<span class="t">退</span>
<div class="icon_item tui" v-if="props.item.returnNum">
<span class="t">退({{ props.item.returnNum }})</span>
</div>
<div class="icon_item lin" v-if="props.item.is_temporary == 1">
<span class="t"></span>
@ -117,8 +117,8 @@ const props = defineProps({
function selectCartItemHandle() {
if (props.type == 'cart') {
goodsStore.selectCartItemHandle(props.index)
} else {
} else if (props.type == 'order') {
goodsStore.selectOrderItem(props.index, props.i)
}
}
</script>

View File

@ -1,89 +1,167 @@
<template>
<div class="operation_wrap">
<div class="item"
:class="{ disabled: goodsStore.cartList.length && (!goodsStore.cartList[goodsStore.cartActiveIndex].id || (goodsStore.cartList[goodsStore.cartActiveIndex].goods_type == 'package' && goodsStore.cartList[goodsStore.cartActiveIndex].group_type == 1)) }"
@click="numberChange('sub')">
<el-icon class="icon">
<SemiSelect />
</el-icon>
</div>
<div class="item number"
:class="{ disabled: goodsStore.cartList.length && (goodsStore.cartList[goodsStore.cartActiveIndex].goods_type == 'package' && goodsStore.cartList[goodsStore.cartActiveIndex].group_type == 1) }"
@click="showEditNumber">
<el-text class="num">
{{ formatDecimal(goodsStore.cartList.length ? +goodsStore.cartList[goodsStore.cartActiveIndex].number :
1, 2, true) }}
</el-text>
</div>
<div class="item"
:class="{ disabled: goodsStore.cartList.length && (goodsStore.cartList[goodsStore.cartActiveIndex].goods_type == 'package' && goodsStore.cartList[goodsStore.cartActiveIndex].group_type == 1) }"
@click="numberChange('add')">
<el-icon class="icon add">
<CloseBold />
</el-icon>
</div>
<div class="item"
:class="{ disabled: (goodsStore.cartList.length && goodsStore.cartList[goodsStore.cartActiveIndex].id && goodsStore.cartList[goodsStore.cartActiveIndex].goods_type != 'sku' && goodsStore.cartList[goodsStore.cartActiveIndex].group_type != 1) }"
@click="showSkuModal">
<el-icon class="icon">
<Filter />
</el-icon>
<el-text class="t">规格</el-text>
</div>
<div class="item"
:class="{ disabled: goodsStore.cartList.length && goodsStore.cartList[goodsStore.cartActiveIndex].is_temporary || goodsStore.cartList.length && goodsStore.cartList[goodsStore.cartActiveIndex].is_gift }"
@click="showDiscountModalHandle">
<el-icon class="icon">
<PriceTag />
</el-icon>
<el-text class="t">改价</el-text>
</div>
<div class="item"
:class="{ disabled: goodsStore.cartList.length && goodsStore.cartList[goodsStore.cartActiveIndex].is_gift }"
@click="giftPackHandle('is_gift')">
<el-icon class="icon">
<ShoppingBag />
</el-icon>
<el-text class="t">赠送</el-text>
</div>
<div class="item" @click="packHandle">
<el-icon class="icon">
<Box />
</el-icon>
<el-text class="t">打包</el-text>
</div>
<div class="item"
:class="{ disabled: goodsStore.cartList.length && goodsStore.cartList[goodsStore.cartActiveIndex].is_print == 0 }"
@click="giftPackHandle('is_print')">
<el-icon class="icon">
<DishDot />
</el-icon>
<el-text class="t">免厨</el-text>
</div>
<div class="item" @click="deleteHandle">
<el-icon class="icon">
<Delete />
</el-icon>
<el-text class="t">删除</el-text>
</div>
<!-- <div class="item" @click="props.item.id && emit('pending', props.item)">
<template v-if="goodsStore.cartType == 'cart'">
<div class="item"
:class="{ disabled: goodsStore.cartList.length && (!goodsStore.cartList[goodsStore.cartActiveIndex].id || (goodsStore.cartList[goodsStore.cartActiveIndex].goods_type == 'package' && goodsStore.cartList[goodsStore.cartActiveIndex].group_type == 1)) }"
@click="numberChange('sub')">
<el-icon class="icon">
<SemiSelect />
</el-icon>
</div>
<div class="item number"
:class="{ disabled: goodsStore.cartList.length && (goodsStore.cartList[goodsStore.cartActiveIndex].goods_type == 'package' && goodsStore.cartList[goodsStore.cartActiveIndex].group_type == 1) }"
@click="showEditNumber">
<el-text class="num">
{{ formatDecimal(goodsStore.cartList.length ?
+goodsStore.cartList[goodsStore.cartActiveIndex].number :
1, 2, true) }}
</el-text>
</div>
<div class="item"
:class="{ disabled: goodsStore.cartList.length && (goodsStore.cartList[goodsStore.cartActiveIndex].goods_type == 'package' && goodsStore.cartList[goodsStore.cartActiveIndex].group_type == 1) }"
@click="numberChange('add')">
<el-icon class="icon add">
<CloseBold />
</el-icon>
</div>
<div class="item"
:class="{ disabled: (goodsStore.cartList.length && goodsStore.cartList[goodsStore.cartActiveIndex].id && goodsStore.cartList[goodsStore.cartActiveIndex].goods_type != 'sku' && goodsStore.cartList[goodsStore.cartActiveIndex].group_type != 1) }"
@click="showSkuModal">
<el-icon class="icon">
<Filter />
</el-icon>
<el-text class="t">规格</el-text>
</div>
<div class="item"
:class="{ disabled: goodsStore.cartList.length && goodsStore.cartList[goodsStore.cartActiveIndex].is_temporary || goodsStore.cartList.length && goodsStore.cartList[goodsStore.cartActiveIndex].is_gift }"
@click="showDiscountModalHandle">
<el-icon class="icon">
<PriceTag />
</el-icon>
<el-text class="t">改价</el-text>
</div>
<div class="item"
:class="{ disabled: goodsStore.cartList.length && goodsStore.cartList[goodsStore.cartActiveIndex].is_gift }"
@click="giftPackHandle('is_gift')">
<el-icon class="icon">
<ShoppingBag />
</el-icon>
<el-text class="t">赠送</el-text>
</div>
<div class="item" @click="packHandle">
<el-icon class="icon">
<Box />
</el-icon>
<el-text class="t">打包</el-text>
</div>
<div class="item"
:class="{ disabled: goodsStore.cartList.length && goodsStore.cartList[goodsStore.cartActiveIndex].is_print == 0 }"
@click="giftPackHandle('is_print')">
<el-icon class="icon">
<DishDot />
</el-icon>
<el-text class="t">免厨</el-text>
</div>
<div class="item" @click="deleteHandle">
<el-icon class="icon">
<Delete />
</el-icon>
<el-text class="t">删除</el-text>
</div>
<!-- <div class="item" @click="props.item.id && emit('pending', props.item)">
<el-icon class="icon">
<Sell />
</el-icon>
<el-text class="t">挂单</el-text>
</div> -->
<div class="item" @click="tableMergingRef.show()">
<el-icon class="icon">
<EditPen />
</el-icon>
<el-text class="t">转桌</el-text>
</div>
<div class="item" @click="clearCart">
<el-icon class="icon">
<RefreshRight />
</el-icon>
<el-text class="t">清空</el-text>
</div>
</template>
<template v-if="goodsStore.cartType == 'order'">
<div class="item disabled">
<el-icon class="icon">
<SemiSelect />
</el-icon>
</div>
<div class="item number disabled">
<el-text class="num">
{{ formatDecimal(goodsStore.cartList.length ?
+goodsStore.cartList[goodsStore.cartActiveIndex].number :
1, 2, true) }}
</el-text>
</div>
<div class="item disabled">
<el-icon class="icon add">
<CloseBold />
</el-icon>
</div>
<div class="item disabled">
<el-icon class="icon">
<Filter />
</el-icon>
<el-text class="t">规格</el-text>
</div>
<div class="item disabled">
<el-icon class="icon">
<PriceTag />
</el-icon>
<el-text class="t">改价</el-text>
</div>
<div class="item disabled">
<el-icon class="icon">
<ShoppingBag />
</el-icon>
<el-text class="t">赠送</el-text>
</div>
<div class="item disabled">
<el-icon class="icon">
<Box />
</el-icon>
<el-text class="t">打包</el-text>
</div>
<div class="item disabled">
<el-icon class="icon">
<DishDot />
</el-icon>
<el-text class="t">免厨</el-text>
</div>
<div class="item"
:class="{ disabled: goodsStore.cartOrderItem.returnNum >= goodsStore.cartOrderItem.number }"
@click="returnOrderItemHandle">
<el-icon class="icon">
<Delete />
</el-icon>
<el-text class="t">退菜</el-text>
</div>
<!-- <div class="item" @click="props.item.id && emit('pending', props.item)">
<el-icon class="icon">
<Sell />
</el-icon>
<el-text class="t">挂单</el-text>
</div> -->
<div class="item" @click="tableMergingRef.show()">
<el-icon class="icon">
<EditPen />
</el-icon>
<el-text class="t">转桌</el-text>
</div>
<div class="item" @click="clearCart">
<el-icon class="icon">
<RefreshRight />
</el-icon>
<el-text class="t">清空</el-text>
</div>
<div class="item" @click="tableMergingRef.show()">
<el-icon class="icon">
<EditPen />
</el-icon>
<el-text class="t">转桌</el-text>
</div>
<div class="item disabled">
<el-icon class="icon">
<RefreshRight />
</el-icon>
<el-text class="t">清空</el-text>
</div>
</template>
</div>
<takeFoodCode ref="takeFoodCodeRef" title="修改商品数量" placeholder="请输入商品数量" @success="updateNumber" />
<!-- 购物车选择规格 -->
@ -147,6 +225,27 @@
</el-dialog>
<!-- 合并/转桌 -->
<tableMerging ref="tableMergingRef" @success="" />
<!-- 退菜数量 -->
<el-dialog
:title="`退菜:${goodsStore.cartOrderItem.product_name} x ${goodsStore.cartOrderItem.number - goodsStore.cartOrderItem.returnNum}`"
v-model="showReturnForm" width="350" top="20%">
<el-form :model="returnForm" label-width="0" label-position="left">
<el-form-item prop="num">
<el-input-number v-model="returnForm.num" :min="1"
:max="goodsStore.cartOrderItem.number - goodsStore.cartOrderItem.returnNum" style="width: 100%;">
</el-input-number>
</el-form-item>
</el-form>
<div class="footer_wrap">
<div class="btn">
<el-button style="width: 100%;" @click="showReturnForm = false">取消</el-button>
</div>
<div class="btn">
<el-button type="primary" style="width: 100%;" :loading="returnFormLoading"
@click="returnFormSubmit">确认</el-button>
</div>
</div>
</el-dialog>
</template>
<script setup>
@ -159,6 +258,7 @@ import { useShop } from '@/store/shop.js'
import { useGoods } from '@/store/goods.js'
import { inputFilterFloat, formatDecimal } from '@/utils/index.js'
import { updatePrice, orderPrint } from '@/api/product.js'
import { refundOrder } from '@/api/order.js'
const shopStore = useShop()
const goodsStore = useGoods()
@ -176,6 +276,62 @@ const emit = defineEmits(['confirm', 'delete', 'pending', 'clearCart', 'merging'
const takeFoodCodeRef = ref(null)
const skuModalRef = ref([])
const showReturnForm = ref(false)
const returnFormLoading = ref(false)
const returnForm = ref({
num: 1
})
// 退
async function returnOrderItemHandle() {
if (goodsStore.cartOrderItem.returnNum >= goodsStore.cartOrderItem.number) return
if (goodsStore.cartOrderItem.number == 1) {
returnOrderItemAjax()
} else {
showReturnForm.value = true
}
}
// 退
async function returnFormSubmit() {
try {
returnFormLoading.value = true
await returnOrderItemAjax(returnForm.value.num)
showReturnForm.value = false
ElMessage.success('退菜成功')
} catch (error) {
console.log('退菜失败了');
}
returnFormLoading.value = false
}
// 退
async function returnOrderItemAjax(num = 1) {
try {
let data = {
orderId: goodsStore.orderListInfo.id,
refundAmount: 0,
modify: 0,
cash: false,
refundReason: '',
refundDetails: [
{
id: goodsStore.cartOrderItem.id,
returnAmount: goodsStore.cartOrderItem.lowPrice,
num: num
}
]
}
await refundOrder(data)
goodsStore.cartOrderItem.returnNum += num
goodsStore.calcCartInfo()
// await goodsStore.historyOrderAjax('', data.orderId)
} catch (error) {
console.log(error);
}
}
//
function packHandle() {
let item = goodsStore.cartList[goodsStore.cartActiveIndex]
@ -499,20 +655,21 @@ function packFormSubmit() {
}
}
.footer_wrap {
display: flex;
gap: 20px;
.btn {
flex: 1;
}
}
.dialog {
.content {
padding-bottom: 20px;
}
.footer_wrap {
display: flex;
gap: 20px;
.btn {
flex: 1;
}
}
}
.remark_list {

View File

@ -51,7 +51,7 @@
<transition name="el-fade-in">
<div class="more" v-if="item.showMore" @click.stop>
<div class="ul">
<template v-if="categorys[categorysActive].id == '-1'">
<template v-if="goodsStore.categoryList[goodsStore.categoryIndex].id == '-1'">
<div class="li" @click.stop="showPutawayHandle(item)">上架</div>
</template>
<template v-else>
@ -67,7 +67,7 @@
<div class="cover" v-if="shopListType == 'img'">
<el-image :src="`${item.coverImg}?x-oss-process=image/resize,m_lfit,w_150,h_150`"
class="el_img" fit="cover"></el-image>
<div class="sell_out" v-if="item.isPauseSale == 1">
<div class="sell_out" v-if="item.isSoldStock">
<img class="sell_out_icon" src="../../../assets/icon_xq.png">
</div>
<div class="weight" v-if="item.type == 'weight'">称重</div>
@ -83,7 +83,7 @@
</template>
<template v-else>
<el-text tag="del" class="del" size="small">{{ item.skuList[0].salePrice
}}</el-text>
}}</el-text>
<el-text>{{ item.skuList[0].memberPrice }}</el-text>
</template>
</div>
@ -250,6 +250,7 @@ import "swiper/swiper-bundle.css";
import { staffPermission } from '@/api/user.js'
import { useGlobal } from '@/store/global.js'
import { inputFilterFloat, clearNoNum } from '@/utils/index.js'
import { productOnOff, markIsSoldOut } from '@/api/product_new.js'
const swiperRef = ref(null)
@ -444,10 +445,10 @@ function showMoreMenu() {
// /
async function showEditorChange() {
try {
await staffPermission('yun_xu_xiu_gai_shang_pin')
// await staffPermission('yun_xu_xiu_gai_shang_pin')
if (showEditor.value) {
showEditor.value = false
goodsStore.goodsList.value.map(item => {
goodsStore.goodsList.map(item => {
item.map(val => {
val.showMore = false
})
@ -464,11 +465,11 @@ async function showEditorChange() {
const WeightModalRef = ref(null)
function showSkuHandle(item) {
if (showEditor.value) {
if (item.isPauseSale == 1) {
if (item.isSoldStock) {
goodEditorItem.value = item
showCloseSell.value = true
} else {
goodsStore.goodsList.value.map(item => {
goodsStore.goodsList.map(item => {
item.map(val => {
val.showMore = false
})
@ -476,7 +477,7 @@ function showSkuHandle(item) {
item.showMore = true
}
} else {
if (item.isPauseSale == 1) {
if (item.isSoldStock) {
ElMessage({
type: 'error',
message: '该商品已售罄',
@ -484,7 +485,7 @@ function showSkuHandle(item) {
})
return
}
if (goodsStore.categoryList[goodsStore.categoryIndex].id == '-1') {
if (!item.isSale) {
ElMessage({
type: 'error',
message: '该商品已下架,请上架后操作',
@ -492,7 +493,6 @@ function showSkuHandle(item) {
})
return
}
let goodsItem = goodsStore.cartList.find(goods => goods.product_id == item.id)
if (item.type == 'sku') {
//
@ -606,13 +606,14 @@ const goodEditorEmun = ref({
//
async function goodEditor(item, t) {
try {
if (t == 0) {
await staffPermission('yun_xu_shang_xia_jia_shang_pin')
} else if (t == 1) {
await staffPermission('yun_xu_shou_qing_shang_pin')
}
// if (t == 0) {
// await staffPermission('yun_xu_shang_xia_jia_shang_pin')
// } else if (t == 1) {
// await staffPermission('yun_xu_shou_qing_shang_pin')
// }
goodEditorItem.value = item
if (item.isPauseSale == 1) {
if (item.isSoldStock) {
showCloseSell.value = true
} else {
goodEditorType.value = t
showGoodEditor.value = true
@ -628,11 +629,10 @@ const closeSellLoading = ref(false)
async function closeSellHandle() {
try {
closeSellLoading.value = true
const res = await productStatus({
shopId: store.userInfo.shopId,
productId: goodEditorItem.value.id,
type: 1,
state: 0
await markIsSoldOut({
type: 'product',
id: goodEditorItem.value.id,
isSoldOut: 0
})
closeSellLoading.value = false
showCloseSell.value = false
@ -688,12 +688,22 @@ async function putawayHandle(item) {
async function goodEditorConfirm() {
try {
goodEditorLoading.value = true
const res = await productStatus({
shopId: store.userInfo.shopId,
productId: goodEditorItem.value.id,
type: goodEditorType.value,
state: goodEditorType.value == 0 ? 0 : 1
})
if (goodEditorType.value == 0) {
//
await productOnOff({
type: 'product',
id: goodEditorItem.value.id,
isSale: 0
})
} else if (goodEditorType.value == 1) {
await markIsSoldOut({
type: 'product',
id: goodEditorItem.value.id,
isSoldOut: 1
})
}
goodEditorLoading.value = false
showGoodEditor.value = false
ElMessage({
@ -922,7 +932,7 @@ defineExpose({
position: absolute;
top: 0;
left: 0;
z-index: 10;
z-index: 999;
background-color: rgba(0, 0, 0, .6);
backdrop-filter: blur(2px);
border-radius: 10px;

View File

@ -94,6 +94,7 @@ import { useGlobal } from '@/store/global.js'
import { usePrint } from '@/store/print.js'
import { useGoods } from '@/store/goods.js'
import { useSocket } from '@/store/socket.js'
import { orderPrint } from '@/api/order.js'
import { staffPermission } from '@/api/user.js'
@ -193,13 +194,12 @@ async function printOrderLable(isBefore = false) {
printStore.pushReceiptData(commOrderPrintData({ ...data, isBefore: isBefore }));
} else {
// 使
await print({
type: "normal",
ispre: true,
orderId: props.orderInfo.id,
await orderPrint({
type: isBefore ? 1 : 0,
id: goodsStore.orderListInfo.id,
});
printLoading.value = false;
ElMessage.success("打印成功");
ElMessage.success(`云打印${isBefore ? '预' : ''}结算单成功`);
}
} catch (error) {
console.log(error);
@ -211,7 +211,7 @@ function paySuccess() {
emits('success')
dialogVisible.value = false;
ElMessage.success('支付成功')
printOrderLable()
if (isPrint.value) printOrderLable()
useStorage.del('tableCode')
socket.cartInit()
goodsStore.successClearCart()

View File

@ -56,6 +56,20 @@
</span>
</div>
</div>
<div class="gift_wrap" v-if="item.returnNum">
<div class="name">
<span>[退菜]</span>
</div>
<div class="n">x{{ item.returnNum }}</div>
<div class="p">
<span>
-<template v-if="item.is_temporary || +item.discount_sale_amount">
{{ formatDecimal(item.discount_sale_amount * item.returnNum) }}
</template>
<template v-else>{{ formatDecimal(item.lowPrice * item.returnNum) }}</template>
</span>
</div>
</div>
<div class="gift_wrap" v-if="!item.is_temporary && !item.is_gift && +item.discount_sale_amount">
<div class="name">
<span>[改价优惠]</span>
@ -133,6 +147,10 @@ const props = defineProps({
color: #999;
font-size: 16px;
.n {
color: #999;
}
.p {
color: var(--el-color-danger);
}

View File

@ -370,7 +370,7 @@ function clearVipUserHandle() {
.order_num {
font-size: 12px;
color: #999;
padding: var(--el-font-size-base) var(--el-font-size-base) 0;
padding: var(--el-font-size-base) var(--el-font-size-base) 10px;
}
}

View File

@ -3,7 +3,8 @@
<div class="left_content">
<div class="query_wrap">
<div class="form">
<el-input v-model="queryForm.key" placeholder="请输入昵称或手机号查询" style="width: 230px;"></el-input>
<el-input v-model="queryForm.key" placeholder="请输入昵称或手机号查询" style="width: 230px;"
@input="phoneInput"></el-input>
<el-select v-model="queryForm.isVip" placeholder="是否为会员" style="width: 150px;"
@change="getUserList">
<el-option label="全部" value=""></el-option>
@ -20,10 +21,11 @@
<div class="table_wrap">
<el-table ref="tableRef" :data="tableData.list" v-loading="tableData.loading" border strip height="100%"
highlight-current-row @current-change="handleCurrentChange">
<el-table-column label="昵称" prop="nickName" width="150">
<el-table-column label="昵称" prop="nickName" width="200">
<template v-slot="scope">
<div class="info">
<el-image :src="scope.row.headImg" style="width: 40px;height: 40px;"></el-image>
<el-image :src="scope.row.headImg"
style="width: 40px;height: 40px;flex-shrink: 0;"></el-image>
<span>{{ scope.row.nickName }}</span>
</div>
</template>
@ -60,28 +62,36 @@
<div class="top_info">
<div class="row">
<span>会员昵称</span>
<span>{{ currentRow.nickName }}</span>
<span v-if="currentRow">{{ currentRow.nickName || '' }}</span>
</div>
<div class="row">
<span>手机号码</span>
<span>{{ currentRow.phone }}</span>
<span v-if="currentRow">{{ currentRow.phone || '' }}</span>
</div>
<div class="row">
<span>会员编号</span>
<span>{{ currentRow.code }}</span>
<span v-if="currentRow">{{ currentRow.code || '' }}</span>
</div>
<div class="row">
<span>会员等级</span>
<span>{{ currentRow.code }}</span>
<span>会员生日</span>
<span v-if="currentRow">{{ currentRow.birthDay || '' }}</span>
</div>
<div class="row">
<div class="fit_row">
<span>会员积分{{ currentRow.accountPoints || 0 }}</span>
<div class="flex">
<span>会员积分</span>
<span v-if="currentRow">{{ currentRow.accountPoints || 0 }}</span>
<span v-else>0</span>
</div>
</div>
</div>
<div class="row" @click="RecordDialogRef.show(currentRow)">
<div class="fit_row">
<span>储值余额{{ currentRow.amount || 0 }}</span>
<div class="flex">
<span>储值余额 </span>
<span v-if="currentRow">{{ currentRow.amount || 0 }}</span>
<span v-else>0</span>
</div>
<el-icon class="icon">
<ArrowRight />
</el-icon>
@ -108,6 +118,7 @@
</template>
<script setup>
import _ from 'lodash'
import { ref, onMounted } from 'vue'
import { shopUserList } from '@/api/account.js'
import UserCharge from './components/userCharge.vue'
@ -159,6 +170,11 @@ function resetHandle() {
getUserList()
}
//
const phoneInput = _.debounce(function (e) {
getUserList()
}, 800)
//
async function getUserList() {
try {
@ -167,7 +183,14 @@ async function getUserList() {
tableData.value.list = res.records
tableData.value.total = +res.totalRow
setCurrent(res.records[0])
if (res.records.length) {
console.log('有数据');
//
setCurrent(res.records[0])
} else {
console.log('没有数据');
currentRow.value = {}
}
} catch (error) {
console.log(error);
}
@ -246,6 +269,10 @@ onMounted(() => {
color: #fff;
border-radius: 6px;
.flex {
display: flex;
}
.row {
display: flex;

View File

@ -6,7 +6,7 @@
<template #default>
<div class="prinr_wrap" v-loading="loading">
<div class="header center">{{ userStore.shopInfo.shopName }}</div>
<div class="row center">结算单{{ orderInfo.tableCode }}</div>
<div class="row center">结算单</div>
<div class="row center">桌号{{ orderInfo.tableName }}</div>
<div class="row" style="margin-top: 20px">
订单号{{ orderInfo.orderNo }}
@ -99,6 +99,8 @@ import {
getOrderByIdAjax,
commOrderPrintData,
} from "@/utils/index.js";
import { orderPrint } from "@/api/order.js";
import { ElMessage } from 'element-plus'
const userStore = useUser();
const printStore = usePrint();
@ -109,23 +111,35 @@ const loading = ref(false);
const printLoading = ref(false);
//
function printHandle(type) {
printLoading.value = true;
switch (type) {
case "normal":
//
printStore.pushReceiptData(commOrderPrintData(orderInfo.value));
break;
case "label":
//
printStore.labelPrint(commOrderPrintData(orderInfo.value));
break;
default:
break;
async function printHandle(type) {
try {
printLoading.value = true;
switch (type) {
case "normal":
//
if (printStore.deviceNoteList.length) {
printStore.pushReceiptData(commOrderPrintData(orderInfo.value));
} else {
await orderPrint({
id: orderInfo.value.id,
type: 0 // 0 1 2退
})
ElMessage.success('云打印小票成功')
}
break;
case "label":
//
printStore.labelPrint(commOrderPrintData(orderInfo.value));
break;
default:
break;
}
setTimeout(() => {
printLoading.value = false;
}, 1500);
} catch (error) {
console.log(error);
}
setTimeout(() => {
printLoading.value = false;
}, 1500);
}
async function show(row) {

View File

@ -109,10 +109,11 @@
<template #footer>
<div class="drawer_footer">
<div class="btn">
<el-button style="width: 100%;" @click="handleRefund">手动退款</el-button>
<el-button style="width: 100%;" :loading="loading" @click="handleRefund">手动退款</el-button>
</div>
<div class="btn">
<el-button type="primary" style="width: 100%;" @click="refundHandle()">原路退回</el-button>
<el-button type="primary" style="width: 100%;" :loading="loading"
@click="refundHandle()">原路退回</el-button>
</div>
</div>
</template>
@ -120,14 +121,19 @@
</template>
<script setup>
import { ref, onMounted } from 'vue'
import { ref } from 'vue'
import { useGlobal } from '@/store/global.js'
import { formatDecimal, inputFilterFloat } from "@/utils/index.js";
import { refundOrder } from '@/api/order.js'
import { ElNotification, ElMessageBox } from 'element-plus'
import { refundOrder, orderPrint } from '@/api/order.js'
import { ElNotification, ElMessageBox, ElMessage } from 'element-plus'
import { usePrint } from "@/store/print.js";
import { useUser } from '@/store/user.js'
import dayjs from 'dayjs'
const emits = defineEmits(['success'])
const store = useUser()
const printStore = usePrint();
const globalStore = useGlobal()
const isShow = ref(false)
const item = ref({})
@ -144,6 +150,7 @@ const remarkTagList = ref([
'商品不满意',
'服务态度不满意'
])
const loading = ref(false)
// 退
function handleRefund() {
@ -208,6 +215,15 @@ async function refundHandle(cash = false) {
break;
}
if (refundAmount <= 0) {
ElNotification({
title: '错误',
message: '无可退金额',
type: 'error',
})
return
}
let data = {
orderId: item.value.id,
refundAmount: refundAmount,
@ -217,19 +233,64 @@ async function refundHandle(cash = false) {
refundDetails: refundDetails
};
// console.log(data);
// return
loading.value = true
await refundOrder(data)
ElNotification({
title: '提示',
message: '退款成功',
type: 'success',
})
await printRefund(rows)
isShow.value = false
emits('success')
} catch (error) {
console.log(error);
}
loading.value = false
}
// 退
async function printRefund(rows) {
try {
if (printStore.deviceNoteList.length) {
//
const data = {
shop_name: store.shopInfo.shopName,
loginAccount: store.userInfo.name,
carts: [],
amount: item.value.orderAmount,
remark: item.value.remark,
orderInfo: item.value,
outNumber: item.value.id,
createdAt: item.value.createTime,
printTime: dayjs().format("YYYY-MM-DD HH:mm:ss"),
}
rows.map(item => {
data.carts.push(
{
name: item.productName,
number: item.num,
skuName: item.skuName,
salePrice: formatDecimal(item.payAmount / item.num),
totalAmount: formatDecimal(item.payAmount)
}
)
})
printStore.printRefund(data);
} else {
//
await orderPrint({ id: item.value.id, type: 2 })
ElNotification({
title: '提示',
message: '云打印退款单成功',
type: 'success',
})
}
} catch (error) {
console.log(error);
}
}
//

View File

@ -23,6 +23,16 @@
<span v-else></span>
</template>
</el-table-column>
<el-table-column label="商品信息" width="150">
<template v-slot="scope">
{{ goodsNameFilter(scope.row.goods) }}
</template>
</el-table-column>
<el-table-column label="状态" width="100">
<template v-slot="scope">
{{ filterLable("orderStatus", scope.row.status) }}
</template>
</el-table-column>
<el-table-column label="订单信息" width="340">
<template v-slot="scope">
<div class="column">
@ -49,7 +59,7 @@
<div class="row">
支付类型{{ filterLable("payType", scope.row.payType) }}
</div>
<div class="row">支付单号{{ scope.row.payOrderNo }}</div>
<!-- <div class="row">支付单号{{ scope.row.payOrderNo }}</div> -->
<div class="row">支付金额{{ scope.row.payAmount }}</div>
<div class="row">支付时间{{ scope.row.paidTime }}</div>
<div class="row">
@ -61,16 +71,6 @@
</div>
</template>
</el-table-column>
<el-table-column label="商品信息" width="150">
<template v-slot="scope">
{{ goodsNameFilter(scope.row.goods) }}
</template>
</el-table-column>
<el-table-column label="状态" width="100">
<template v-slot="scope">
{{ filterLable("orderStatus", scope.row.status) }}
</template>
</el-table-column>
<el-table-column label="操作" width="150" align="center" fixed="right">
<template v-slot="scope">
<div class="column">