1.新增套餐商品
This commit is contained in:
parent
96ab68f463
commit
7c27372c4d
15849
dist-electron/main.js
15849
dist-electron/main.js
File diff suppressed because one or more lines are too long
|
|
@ -158,3 +158,87 @@ export function tglogout(data) {
|
|||
data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 美团团购核销
|
||||
* 绑定-获取绑定状态
|
||||
* @param {*} data
|
||||
* @returns
|
||||
*/
|
||||
export function thirdPartyCoupon_state(data) {
|
||||
return request_php({
|
||||
method: "post",
|
||||
url: "/meituan/searchstorestatus",
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 美团团购核销
|
||||
* 绑定-获取绑定url
|
||||
* @param {*} data
|
||||
* @returns
|
||||
*/
|
||||
export function thirdPartyCoupon_bindUrl(data) {
|
||||
return request_php({
|
||||
method: "post",
|
||||
url: "/meituan/getuisdkurl",
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 美团团购核销
|
||||
* 团购券-获取可用券
|
||||
* @param {*} data
|
||||
* @returns
|
||||
*/
|
||||
export function thirdPartyCoupon_list(data) {
|
||||
return request_php({
|
||||
method: "post",
|
||||
url: "/meituan/fulfilmentcertificateprepare",
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 美团团购核销
|
||||
* 执行核销
|
||||
* @param {*} data
|
||||
* @returns
|
||||
*/
|
||||
export function certificateprepare(data) {
|
||||
return request_php({
|
||||
method: "post",
|
||||
url: "/meituan/certificateprepare",
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 美团团购核销
|
||||
* 团购核销记录
|
||||
* @param {*} data
|
||||
* @returns
|
||||
*/
|
||||
export function meituan_orderlist(data) {
|
||||
return request_php({
|
||||
method: "post",
|
||||
url: "/meituan/orderlist",
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 美团团购核销
|
||||
* 团购撤销
|
||||
* @param {*} data
|
||||
* @returns
|
||||
*/
|
||||
export function meituan_fulfilmentcertificatecancel(data) {
|
||||
return request_php({
|
||||
method: "post",
|
||||
url: "/meituan/fulfilmentcertificatecancel",
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -194,3 +194,55 @@ export function productStock(data) {
|
|||
data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加临时菜
|
||||
* @param {*} data
|
||||
* @returns
|
||||
*/
|
||||
export function temporaryDishes(data) {
|
||||
return request({
|
||||
method: "post",
|
||||
url: "/order/temporaryDishes",
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品单位列表获取
|
||||
* @param {*} params
|
||||
* @returns
|
||||
*/
|
||||
export function getUnitList(params) {
|
||||
return request({
|
||||
method: "get",
|
||||
url: "/unit",
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 单品改价
|
||||
* @param {*} data
|
||||
* @returns
|
||||
*/
|
||||
export function updatePrice(data) {
|
||||
return request({
|
||||
method: "PUT",
|
||||
url: "/order/updatePrice",
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 免厨打印
|
||||
* @param {*} data
|
||||
* @returns
|
||||
*/
|
||||
export function orderPrint(data) {
|
||||
return request({
|
||||
method: "PUT",
|
||||
url: "/order/print",
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { formatDecimal } from "@/utils/index.js";
|
|||
* 打印订单小票
|
||||
*/
|
||||
export default (data) => {
|
||||
console.log('需要打印的订单数据===',data);
|
||||
// console.log("需要打印的订单数据===", data);
|
||||
// console.log("data.deviceName===", data.deviceName);
|
||||
let LODOP = getLodop();
|
||||
LODOP.PRINT_INIT("打印小票");
|
||||
|
|
@ -51,16 +51,41 @@ export default (data) => {
|
|||
|
||||
let table = "";
|
||||
for (let item of data.carts) {
|
||||
if (item.proGroupInfo) {
|
||||
table += `
|
||||
<tr>
|
||||
<td style="font-size: 12px;width:${t1}%" colspan="3">
|
||||
<div>${item.name}</div>
|
||||
</td>
|
||||
<td style="font-size: 12px;width:${t2}%;">${item.totalAmount}</td>
|
||||
</tr>
|
||||
`;
|
||||
|
||||
let proGroupInfo = JSON.parse(item.proGroupInfo);
|
||||
for (let item of proGroupInfo) {
|
||||
table += `
|
||||
<tr>
|
||||
<td style="font-size: 12px;width:${t1}%;">
|
||||
<div>${item.name}</div>
|
||||
<div>>${item.proName}</div>
|
||||
${
|
||||
item.skuName
|
||||
? `<div class="sku">规格:${item.skuName}</div>`
|
||||
: ""
|
||||
}
|
||||
</td>
|
||||
<td style="font-size: 12px;width:${t2}%;">0</td>
|
||||
<td style="font-size: 12px;width:${t2}%;">${item.number}</td>
|
||||
<td style="font-size: 12px;width:${t2}%;">0</td>
|
||||
</tr>
|
||||
`;
|
||||
}
|
||||
} else {
|
||||
table += `
|
||||
<tr>
|
||||
<td style="font-size: 12px;width:${t1}%;">
|
||||
<div>${item.name}</div>
|
||||
${item.skuName ? `<div class="sku">规格:${item.skuName}</div>` : ""}
|
||||
</td>
|
||||
<td style="font-size: 12px;width:${t2}%;">${item.salePrice}</td>
|
||||
<td style="font-size: 12px;width:${t2}%;">${item.number}</td>
|
||||
<td style="font-size: 12px;width:${t2}%;">
|
||||
|
|
@ -69,6 +94,7 @@ export default (data) => {
|
|||
</tr>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
let str = `
|
||||
</table>
|
||||
|
|
|
|||
|
|
@ -208,7 +208,7 @@ defineExpose({
|
|||
|
||||
.drawerbox_bo_box_icon {
|
||||
border-radius: 6px;
|
||||
background: #2196f3;
|
||||
background-color: var(--primary-color);
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
display: flex;
|
||||
|
|
|
|||
|
|
@ -57,3 +57,42 @@ export function formatDecimal(num, decimal = 2, isInt = false) {
|
|||
return parseFloat(num).toFixed(decimal);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 过滤input只能输入整数
|
||||
* @param {*} value
|
||||
* @returns
|
||||
*/
|
||||
export function inputFilterInt(value) {
|
||||
if (!value) return;
|
||||
return value.replace(/[^\d]/g, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* 过滤input只能输入数字,并且最多输入两位小数
|
||||
* @param {*} value
|
||||
* @returns
|
||||
*/
|
||||
export function inputFilterFloat(value) {
|
||||
if (!value) return;
|
||||
// 去除首位小数点
|
||||
if (value.startsWith(".")) {
|
||||
value = value.slice(1);
|
||||
}
|
||||
// 清除非数字和小数点(除了第一个小数点)
|
||||
value = value.replace(/[^\d.]/g, "");
|
||||
// 确保最多只有一个小数点
|
||||
if (value.split(".").length > 2) {
|
||||
value = value.split(".").slice(0, 2).join(".");
|
||||
}
|
||||
// 限制小数位数为两位
|
||||
if (value.split(".")[1] && value.split(".")[1].length > 2) {
|
||||
value = value.split(".")[0] + "." + value.split(".")[1].slice(0, 2);
|
||||
}
|
||||
// 限制首位只能输入一个0
|
||||
if (value.startsWith("0") && value.length > 1 && value[1] === "0") {
|
||||
// 如果首位是0,且第二位也是0,将第二个0及之后的内容清空
|
||||
value = "0";
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@
|
|||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-table ref="douyin_table" :data="groupDetail.goods" border v-if="props.type == 2">
|
||||
<el-table ref="douyin_table" :data="groupDetail.goods" border v-else>
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column label="名称" prop="title"></el-table-column>
|
||||
<el-table-column label="价格" prop="amount"></el-table-column>
|
||||
|
|
@ -100,7 +100,7 @@
|
|||
import _ from "lodash";
|
||||
import { ref } from "vue";
|
||||
import icon from "@/assets/icon_scan.png";
|
||||
import { groupOrderorderInfo, groupOrdergroupScan, douyinfulfilmentcertificateprepare, douyincertificateprepare } from '@/api/group'
|
||||
import { groupOrderorderInfo, groupOrdergroupScan, douyinfulfilmentcertificateprepare, douyincertificateprepare, thirdPartyCoupon_list, certificateprepare } from '@/api/group'
|
||||
import { useUser } from "@/store/user.js";
|
||||
import BindShop from './bindShop.vue'
|
||||
const BindShopRef = ref(null)
|
||||
|
|
@ -173,6 +173,23 @@ async function groupOrdergroupScanHandle() {
|
|||
}
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
// 美团团购
|
||||
{
|
||||
let encrypted_codes = douyin_table.value.getSelectionRows()
|
||||
if (encrypted_codes.length) {
|
||||
groupDetailLoading.value = true
|
||||
let arr = encrypted_codes.map(item => item.encrypted_code)
|
||||
const res = await certificateprepare({
|
||||
couponCode: groupDetail.value.couponCode,
|
||||
num: encrypted_codes.length
|
||||
})
|
||||
} else {
|
||||
ElMessage.error('请选择核销项目')
|
||||
return
|
||||
}
|
||||
}
|
||||
break
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -221,6 +238,23 @@ async function submitHandle() {
|
|||
}, 100)
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
{
|
||||
const res = await thirdPartyCoupon_list({
|
||||
shopId: store.userInfo.shopId,
|
||||
code: scanCode.value
|
||||
});
|
||||
dialogVisible.value = false
|
||||
loading.value = false
|
||||
groupDetail.value = res
|
||||
detailVisible.value = true
|
||||
setTimeout(() => {
|
||||
groupDetail.value.goods.map(item => {
|
||||
douyin_table.value.toggleRowSelection(item)
|
||||
})
|
||||
}, 100)
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
@click="resetHandle">重置</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<el-button type="warning" :icon="FullScreen" @click="scanGroupRef.show()">核销团购券</el-button>
|
||||
<el-button type="warning" :icon="FullScreen" @click="showScanModalHandle">核销团购券</el-button>
|
||||
</div>
|
||||
<div class="tab_container">
|
||||
<el-table :data="tableData.list" height="540px" v-loading="tableData.loading"
|
||||
|
|
@ -101,6 +101,24 @@
|
|||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-table height="540px" :data="tableData.list" v-loading="tableData.loading"
|
||||
v-if="tableData.type == 3">
|
||||
<el-table-column label="名称" prop="dealTitle"></el-table-column>
|
||||
<el-table-column label="总金额" prop="couponBuyPrice" width="100">
|
||||
<template v-slot="scope">
|
||||
<span style="color: var(--primary-color);">¥{{ scope.row.couponBuyPrice }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态" prop="couponStatusDesc" width="150"></el-table-column>
|
||||
<el-table-column label="使用时间" prop="couponUseTime" width="200"></el-table-column>
|
||||
<el-table-column label="操作" prop="douyinCodeGoods" width="100">
|
||||
<template v-slot="scope">
|
||||
<el-button type="danger" size="small" @click="cacelMeittuanHandle(scope.row)">
|
||||
撤销
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="pagination">
|
||||
<el-pagination v-model:current-page="tableData.page" v-model:page-size="tableData.size"
|
||||
|
|
@ -112,11 +130,22 @@
|
|||
<scanGroup ref="scanGroupRef" :title="typeList.find(item => item.value == tableData.type).label"
|
||||
:type="tableData.type" @succcess="groupOrderlistAjax" />
|
||||
<refundDialog ref="refundDialogRef" @success="groupOrderlistAjax" />
|
||||
<el-dialog v-model="showMeituanUrlModal" title="注意">
|
||||
<span style="font-size: 18px;">您的店铺还未绑定美团,请绑定后操作!</span>
|
||||
<template #footer>
|
||||
<div class="dialog-footer" style="padding: 0 15px 15px;">
|
||||
<el-button @click="showMeituanUrlModal = false">取消</el-button>
|
||||
<el-button type="primary" @click="openMeituan">
|
||||
去绑定
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { groupOrderlist, douyinorderlist, douyinfulfilmentcertificatecancel } from '@/api/group'
|
||||
import { groupOrderlist, douyinorderlist, douyinfulfilmentcertificatecancel, thirdPartyCoupon_state, thirdPartyCoupon_bindUrl, meituan_orderlist, meituan_fulfilmentcertificatecancel } from '@/api/group'
|
||||
import { Search, RefreshRight, FullScreen } from '@element-plus/icons-vue'
|
||||
import { ElMessageBox, ElMessage } from 'element-plus'
|
||||
import { ref, onMounted, reactive } from 'vue'
|
||||
|
|
@ -124,6 +153,7 @@ import scanGroup from './components/scanGroup.vue'
|
|||
import refundDialog from './components/refundDialog.vue'
|
||||
import { useUser } from "@/store/user.js"
|
||||
import BindShop from './components/bindShop.vue'
|
||||
import { shell } from 'electron'
|
||||
const store = useUser()
|
||||
|
||||
import { useGlobal } from '@/store/global.js'
|
||||
|
|
@ -144,7 +174,7 @@ function typeStatus(t) {
|
|||
const tableData = reactive({
|
||||
resetLoading: false,
|
||||
proName: '',
|
||||
type: 2,
|
||||
type: 3,
|
||||
status: '',
|
||||
loading: false,
|
||||
list: [],
|
||||
|
|
@ -171,6 +201,10 @@ const typeList = reactive([
|
|||
{
|
||||
value: 2,
|
||||
label: '抖音'
|
||||
},
|
||||
{
|
||||
value: 3,
|
||||
label: '美团'
|
||||
}
|
||||
])
|
||||
|
||||
|
|
@ -229,6 +263,10 @@ function typeChange(e) {
|
|||
case 2:
|
||||
statusList.value = [...dmStatus]
|
||||
break;
|
||||
case 3:
|
||||
statusList.value = [...dmStatus]
|
||||
thirdPartyCoupon_state_ajax()
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -238,6 +276,54 @@ function typeChange(e) {
|
|||
groupOrderlistAjax()
|
||||
}
|
||||
|
||||
// 获取美团绑定状态
|
||||
const meituanStatus = ref(false)
|
||||
async function thirdPartyCoupon_state_ajax() {
|
||||
try {
|
||||
const res = await thirdPartyCoupon_state({
|
||||
shopId: store.userInfo.shopId
|
||||
})
|
||||
if (res.status == 0) {
|
||||
meituanStatus.value = false
|
||||
showMeituanUrlModal.value = true
|
||||
thirdPartyCoupon_bindUrl_ajax()
|
||||
} else {
|
||||
meituanStatus.value = true
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
// 获取美团绑定链接
|
||||
const meituanURL = ref('')
|
||||
const showMeituanUrlModal = ref(false)
|
||||
async function thirdPartyCoupon_bindUrl_ajax() {
|
||||
try {
|
||||
const res = await thirdPartyCoupon_bindUrl({
|
||||
shopId: store.userInfo.shopId
|
||||
})
|
||||
meituanURL.value = res
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
// 确认打开绑定美团链接
|
||||
function openMeituan() {
|
||||
showMeituanUrlModal.value = false
|
||||
shell.openExternal(meituanURL.value);
|
||||
}
|
||||
|
||||
function showScanModalHandle() {
|
||||
// 若果是美团并且没有绑定,则需要先绑定
|
||||
if (tableData.type == 3 && !meituanStatus.value) {
|
||||
showMeituanUrlModal.value = true
|
||||
return
|
||||
}
|
||||
scanGroupRef.value.show()
|
||||
}
|
||||
|
||||
// 状态
|
||||
function statusFilter(t) {
|
||||
return originStatus.find(item => item.value == t)?.label
|
||||
|
|
@ -268,6 +354,21 @@ function cacelDouyinHandle(item) {
|
|||
}).catch(() => { })
|
||||
}
|
||||
|
||||
// 显示美团团购撤销
|
||||
function cacelMeittuanHandle(item) {
|
||||
ElMessageBox.confirm(
|
||||
'是否撤销该团购?',
|
||||
'注意').then(async () => {
|
||||
try {
|
||||
await meituan_fulfilmentcertificatecancel({ couponCode: item.couponCode })
|
||||
ElMessage.success('撤销成功')
|
||||
groupOrderlistAjax()
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}).catch(() => { })
|
||||
}
|
||||
|
||||
// 获取团购订单数据
|
||||
async function groupOrderlistAjax() {
|
||||
try {
|
||||
|
|
@ -300,6 +401,19 @@ async function groupOrderlistAjax() {
|
|||
tableData.list = res.list
|
||||
tableData.total = res.count
|
||||
break;
|
||||
case 3:
|
||||
// 获取美团购数据
|
||||
res = await meituan_orderlist({
|
||||
page: tableData.page,
|
||||
// status: tableData.status,
|
||||
// d_order_id: tableData.proName,
|
||||
date: ''
|
||||
})
|
||||
tableData.resetLoading = false
|
||||
tableData.loading = false
|
||||
tableData.list = res.list
|
||||
tableData.total = res.count
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
</el-icon>
|
||||
</div>
|
||||
<div class="item number" @click="props.item.id && takeFoodCodeRef.show()">
|
||||
<el-text class="num">{{ props.item.number || 1 }}</el-text>
|
||||
<el-text class="num">{{ formatDecimal(props.item.number || 1, 2, true) }}</el-text>
|
||||
</div>
|
||||
<div class="item" @click="numberChange('add')">
|
||||
<el-icon class="icon add">
|
||||
|
|
@ -19,6 +19,12 @@
|
|||
</el-icon>
|
||||
<el-text class="t">规格</el-text>
|
||||
</div>
|
||||
<div class="item" @click="showDiscountModalHandle">
|
||||
<el-icon class="icon">
|
||||
<PriceTag />
|
||||
</el-icon>
|
||||
<el-text class="t">打折</el-text>
|
||||
</div>
|
||||
<div class="item" :class="{ disabled: props.item.isGift == 'true' }" @click="giftPackHandle('isGift')">
|
||||
<el-icon class="icon">
|
||||
<ShoppingBag />
|
||||
|
|
@ -32,6 +38,12 @@
|
|||
</el-icon>
|
||||
<el-text class="t">打包</el-text>
|
||||
</div>
|
||||
<div class="item" :class="{ disabled: props.item.isPrint == 0 }" @click="kitchenPrint">
|
||||
<el-icon class="icon">
|
||||
<DishDot />
|
||||
</el-icon>
|
||||
<el-text class="t">免厨</el-text>
|
||||
</div>
|
||||
<div class="item" @click="props.item.id && emit('delete', props.item)">
|
||||
<el-icon class="icon">
|
||||
<Delete />
|
||||
|
|
@ -54,17 +66,51 @@
|
|||
<takeFoodCode ref="takeFoodCodeRef" title="修改商品数量" placeholder="请输入商品数量" @success="updateNumber" />
|
||||
<!-- 购物车选择规格 -->
|
||||
<skuModal ref="skuModalRef" @success="skuConfirm" />
|
||||
<!-- 单品打折 -->
|
||||
<el-dialog v-model="showDiscountModal" title="单品打折" @open="resetDiscountForm = { ...discountForm }"
|
||||
@closed="discountModalClose">
|
||||
<div class="dialog">
|
||||
<div class="el-popover__title content">
|
||||
<el-form ref="discountFormRef" :model="discountForm" :rules="discountFormRules" label-width="100px"
|
||||
label-position="left">
|
||||
<el-form-item label="价格更改" prop="amount">
|
||||
<el-input v-model="discountForm.amount" placeholder="减8.88元请输入8.88" @input="priceInput">
|
||||
<template #append>元</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="更改原因">
|
||||
<el-input v-model="discountForm.note" type="textarea" placeholder="请输入自定义备注" />
|
||||
<div class="remark_list">
|
||||
<div class="item" v-for="item in noteList" :key="item" @click="addNote(item)">
|
||||
{{ item }}
|
||||
</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div class="footer_wrap">
|
||||
<div class="btn">
|
||||
<el-button style="width: 100%;" @click="showDiscountModal = false">取消</el-button>
|
||||
</div>
|
||||
<div class="btn">
|
||||
<el-button type="primary" style="width: 100%;" :loading="discountFormLoading"
|
||||
@click="discountFormSubmit">确认</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import takeFoodCode from '@/components/takeFoodCode.vue'
|
||||
import skuModal from '@/components/skuModal.vue'
|
||||
import { useShop } from '@/store/shop.js'
|
||||
import { inputFilterFloat, formatDecimal } from '@/utils/index.js'
|
||||
import { updatePrice, orderPrint } from '@/api/product.js'
|
||||
|
||||
const shopStore = useShop()
|
||||
console.log('---------')
|
||||
console.log(shopStore)
|
||||
const props = defineProps({
|
||||
item: {
|
||||
type: Object,
|
||||
|
|
@ -126,6 +172,114 @@ function skuConfirm(e) {
|
|||
if (!props.item.id) return
|
||||
emit('confirm', e)
|
||||
}
|
||||
|
||||
/**单品打折 start */
|
||||
const showDiscountModal = ref(false)
|
||||
const resetDiscountForm = ref({})
|
||||
const discountFormRef = ref(null)
|
||||
const discountFormLoading = ref(false)
|
||||
const discountForm = ref({
|
||||
masterId: '',
|
||||
cartId: '',
|
||||
amount: '',
|
||||
note: '',
|
||||
shopId: ''
|
||||
})
|
||||
|
||||
function validateAmount(rule, value, callback) {
|
||||
if (value == '') {
|
||||
callback(new Error('请输入折扣价格'))
|
||||
} else if (value <= 0) {
|
||||
callback(new Error('输入价格有误'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
|
||||
const discountFormRules = ref({
|
||||
amount: [
|
||||
{
|
||||
required: true,
|
||||
validator: validateAmount,
|
||||
trigger: 'blur',
|
||||
}
|
||||
]
|
||||
})
|
||||
const noteList = ref([
|
||||
'顾客投诉质量...',
|
||||
'友情打折',
|
||||
'临时活动',
|
||||
])
|
||||
|
||||
// 显示
|
||||
function showDiscountModalHandle() {
|
||||
if (props.item.id) {
|
||||
showDiscountModal.value = true
|
||||
}
|
||||
}
|
||||
|
||||
// 过滤价格输入
|
||||
function priceInput(e) {
|
||||
setTimeout(() => {
|
||||
discountForm.value.amount = inputFilterFloat(e)
|
||||
}, 50)
|
||||
}
|
||||
|
||||
// 关闭
|
||||
function discountModalClose() {
|
||||
discountForm.value = { ...resetDiscountForm.value }
|
||||
discountFormRef.value.resetFields()
|
||||
}
|
||||
|
||||
// 添加快捷备注
|
||||
function addNote(str) {
|
||||
if (!discountForm.value.note.length) {
|
||||
discountForm.value.note += str
|
||||
} else {
|
||||
discountForm.value.note += `,${str}`
|
||||
}
|
||||
}
|
||||
|
||||
// 提交
|
||||
function discountFormSubmit() {
|
||||
discountFormRef.value.validate(async valid => {
|
||||
try {
|
||||
if (valid) {
|
||||
discountFormLoading.value = true
|
||||
|
||||
discountForm.value.masterId = props.item.masterId
|
||||
discountForm.value.cartId = props.item.id
|
||||
discountForm.value.shopId = props.item.shopId
|
||||
|
||||
await updatePrice(discountForm.value)
|
||||
discountFormLoading.value = false
|
||||
|
||||
showDiscountModal.value = false
|
||||
ElMessage.success('操作成功')
|
||||
emit('confirm', { isTemporary: true })
|
||||
}
|
||||
} catch (error) {
|
||||
discountFormLoading.value = false
|
||||
console.log(error);
|
||||
}
|
||||
})
|
||||
}
|
||||
/**单品打折 end */
|
||||
|
||||
/**免厨打印 start */
|
||||
async function kitchenPrint() {
|
||||
try {
|
||||
const res = await orderPrint({
|
||||
isPrint: props.item.isPrint ? 0 : 1,
|
||||
shopId: props.item.shopId,
|
||||
cartId: props.item.id
|
||||
})
|
||||
emit('confirm', { isTemporary: true })
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
/**免厨打印 end */
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
|
@ -133,7 +287,7 @@ function skuConfirm(e) {
|
|||
padding: 10px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
gap: 10px;
|
||||
|
||||
.item {
|
||||
width: 70px;
|
||||
|
|
@ -178,4 +332,33 @@ function skuConfirm(e) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dialog {
|
||||
|
||||
.content {
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
.footer_wrap {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
|
||||
.btn {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.remark_list {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
margin-top: 10px;
|
||||
|
||||
.item {
|
||||
padding: 0 10px;
|
||||
border: 1px solid #ddd;
|
||||
color: #999;
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -26,8 +26,12 @@
|
|||
</el-popover>
|
||||
</div>
|
||||
<div class="search_wrap">
|
||||
<el-button :type="showEditor ? 'warning' : ''" @click="showEditorChange">{{ showEditor ? '关闭编辑' : '编辑'
|
||||
}}</el-button>
|
||||
<div class="left">
|
||||
<el-button :type="showEditor ? 'warning' : ''" @click="showEditorChange">
|
||||
{{ showEditor ? '关闭编辑' : '编辑' }}
|
||||
</el-button>
|
||||
<el-button type="warning" icon="Food" @click="showTemporaryDish = true">临时菜</el-button>
|
||||
</div>
|
||||
<div class="right">
|
||||
<div class="input">
|
||||
<el-input placeholder="请输入商品名称查询" v-model="commdityName" clearable @focus="
|
||||
|
|
@ -66,6 +70,7 @@
|
|||
<div class="sell_out" v-if="item.isPauseSale == 1">
|
||||
<img class="sell_out_icon" src="../../../assets/icon_xq.png">
|
||||
</div>
|
||||
<div class="weight" v-if="item.type == 'weigh'">称重</div>
|
||||
</div>
|
||||
<div class="name"><el-text line-clamp="1">{{ item.name }}</el-text></div>
|
||||
<div class="item_empty" v-if="shopListType == 'text'"></div>
|
||||
|
|
@ -160,6 +165,61 @@
|
|||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
<!-- 添加临时菜 -->
|
||||
<el-dialog v-model="showTemporaryDish" title="添加临时菜" top="3vh" @open="showTemporaryDishOpen"
|
||||
@closed="showTemporaryDishClosed">
|
||||
<div class="dialog">
|
||||
<div class="el-popover__title content">
|
||||
<el-form ref="temporaryFormRef" :model="temporaryForm" :rules="temporaryFormRules" label-width="100px"
|
||||
label-position="left">
|
||||
<el-form-item label="菜品名称" prop="name">
|
||||
<el-input v-model="temporaryForm.name" placeholder="请输入菜品名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="菜品分类" prop="categoryId">
|
||||
<el-select v-model="temporaryForm.categoryId" placeholder="请选择菜品分类">
|
||||
<el-option v-for="item in temporaryCategorys" :key="item.id" :label="item.name"
|
||||
:value="item.id"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="价格" prop="price">
|
||||
<el-input v-model="temporaryForm.price" placeholder="请输入价格" @input="priceInput">
|
||||
<template #append>元</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="单位" prop="unit">
|
||||
<el-select v-model="temporaryForm.unit" placeholder="请选择单位">
|
||||
<el-option v-for="item in units" :key="item.id" :label="item.name"
|
||||
:value="item.name"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="下单数量">
|
||||
<el-input-number v-model="temporaryForm.num" :min="1" />
|
||||
</el-form-item>
|
||||
<el-form-item label="备注">
|
||||
<el-input v-model="temporaryForm.note" type="textarea" placeholder="请输入自定义备注" />
|
||||
<div class="remark_list">
|
||||
<div class="item" v-for="item in noteList" :key="item" @click="addNote(item)">
|
||||
{{ item }}
|
||||
</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div class="footer_wrap">
|
||||
<div class="btn">
|
||||
<el-button style="width: 100%;" @click="showTemporaryDish = false">取消</el-button>
|
||||
</div>
|
||||
<div class="btn">
|
||||
<el-button type="primary" style="width: 100%;" :loading="temporaryFormLoading"
|
||||
@click="temporaryFormSubmit">确认</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
<!-- 称重商品弹窗 -->
|
||||
<WeightModal ref="WeightModalRef" @success="skuConfirm" />
|
||||
<!-- 套餐商品弹窗 -->
|
||||
<GroupModal ref="GroupModalRef" @success="skuConfirm" />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
|
@ -169,12 +229,15 @@ import { onMounted, ref } from 'vue'
|
|||
import _ from 'lodash'
|
||||
import useStorage from "@/utils/useStorage";
|
||||
import skuModal from '@/components/skuModal.vue'
|
||||
import { queryCategory, queryNewCommodityInfo, queryProductSku, productStatus, productStock } from '@/api/product'
|
||||
import WeightModal from './weightModal.vue'
|
||||
import GroupModal from './groupModal.vue'
|
||||
import { queryCategory, queryNewCommodityInfo, queryProductSku, productStatus, productStock, getUnitList, temporaryDishes } from '@/api/product'
|
||||
import { useUser } from "@/store/user.js"
|
||||
import { Swiper, SwiperSlide } from 'swiper/vue'
|
||||
import "swiper/swiper-bundle.css";
|
||||
import { staffPermission } from '@/api/user.js'
|
||||
import { useGlobal } from '@/store/global.js'
|
||||
import { inputFilterFloat } from '@/utils/index.js'
|
||||
|
||||
const global = useGlobal()
|
||||
|
||||
|
|
@ -213,6 +276,136 @@ const inputChange = _.debounce(function () {
|
|||
searchHandle()
|
||||
}, 500)
|
||||
|
||||
|
||||
/** 添加临时菜 start */
|
||||
const temporaryCategorys = ref([]) // 分类列表
|
||||
const showTemporaryDish = ref(false) // 显示添加临时菜
|
||||
const units = ref([]) // 单位列表
|
||||
const temporaryFormRef = ref(null)
|
||||
const resetTemporaryForm = ref({})
|
||||
const temporaryForm = ref({
|
||||
masterId: '',
|
||||
shopId: '',
|
||||
tableId: '',
|
||||
name: '',
|
||||
categoryId: '',
|
||||
price: '',
|
||||
unit: '',
|
||||
num: 1,
|
||||
note: '',
|
||||
vipUserId: ''
|
||||
})
|
||||
const temporaryFormLoading = ref(false)
|
||||
|
||||
const noteList = ref([
|
||||
'免葱',
|
||||
'免香菜',
|
||||
'不要辣',
|
||||
])
|
||||
|
||||
function priceInput(e) {
|
||||
setTimeout(() => {
|
||||
temporaryForm.value.price = inputFilterFloat(e)
|
||||
}, 50)
|
||||
}
|
||||
|
||||
// 添加快捷备注
|
||||
function addNote(str) {
|
||||
if (!temporaryForm.value.note.length) {
|
||||
temporaryForm.value.note += str
|
||||
} else {
|
||||
temporaryForm.value.note += `,${str}`
|
||||
}
|
||||
}
|
||||
|
||||
const temporaryFormRules = ref({
|
||||
name: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入菜品名称',
|
||||
trigger: 'blur',
|
||||
}
|
||||
],
|
||||
categoryId: [
|
||||
{
|
||||
required: true,
|
||||
message: '请选择菜品分类',
|
||||
trigger: 'change',
|
||||
}
|
||||
],
|
||||
price: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入价格',
|
||||
trigger: 'blur',
|
||||
}
|
||||
],
|
||||
unit: [
|
||||
{
|
||||
required: true,
|
||||
message: '请选择单位',
|
||||
trigger: 'change',
|
||||
}
|
||||
],
|
||||
})
|
||||
|
||||
// 打开
|
||||
function showTemporaryDishOpen() {
|
||||
resetTemporaryForm.value = { ...temporaryForm.value }
|
||||
}
|
||||
|
||||
// 关闭
|
||||
function showTemporaryDishClosed() {
|
||||
temporaryForm.value = { ...resetTemporaryForm.value }
|
||||
temporaryFormRef.value.resetFields()
|
||||
}
|
||||
|
||||
// 获取单位列表
|
||||
async function getUnitListAjax() {
|
||||
try {
|
||||
const res = await getUnitList({
|
||||
shopId: store.userInfo.shopId,
|
||||
page: 1,
|
||||
size: 100,
|
||||
name: ''
|
||||
})
|
||||
units.value = res.records
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
// 提交临时菜
|
||||
function temporaryFormSubmit() {
|
||||
temporaryFormRef.value.validate(async valid => {
|
||||
try {
|
||||
if (valid) {
|
||||
temporaryFormLoading.value = true
|
||||
|
||||
temporaryForm.value.masterId = props.masterId
|
||||
temporaryForm.value.shopId = store.userInfo.shopId
|
||||
temporaryForm.value.tableId = global.tableInfo.qrcode
|
||||
|
||||
await temporaryDishes(temporaryForm.value)
|
||||
temporaryFormLoading.value = false
|
||||
|
||||
showTemporaryDish.value = false
|
||||
ElMessage.success('添加成功')
|
||||
emit('success', { isTemporary: true })
|
||||
}
|
||||
} catch (error) {
|
||||
temporaryFormLoading.value = false
|
||||
console.log(error);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/** 添加临时菜 end */
|
||||
|
||||
/** 套餐 start */
|
||||
const GroupModalRef = ref(null)
|
||||
/** 套餐 end */
|
||||
|
||||
// 搜索
|
||||
const searchLoading = ref(false)
|
||||
function searchHandle() {
|
||||
|
|
@ -258,6 +451,7 @@ async function showEditorChange() {
|
|||
}
|
||||
|
||||
// 显示sku
|
||||
const WeightModalRef = ref(null)
|
||||
function showSkuHandle(item) {
|
||||
if (showEditor.value) {
|
||||
if (item.isPauseSale == 1) {
|
||||
|
|
@ -288,6 +482,7 @@ function showSkuHandle(item) {
|
|||
})
|
||||
return
|
||||
}
|
||||
if (item.type == 'normal') {
|
||||
if (item.typeEnum == 'sku') {
|
||||
// 多规格
|
||||
skuModalRef.value.show({ ...item })
|
||||
|
|
@ -297,6 +492,16 @@ function showSkuHandle(item) {
|
|||
emit('loading')
|
||||
queryProductSkuAjax(item)
|
||||
}
|
||||
} else if (item.type == 'weigh') {
|
||||
WeightModalRef.value.show(item)
|
||||
} else if (item.type == 'package' && item.groupType == 1) {
|
||||
GroupModalRef.value.show(item)
|
||||
} else if (item.type == 'package' && item.groupType == 0) {
|
||||
// 固定套餐当做单规格处理
|
||||
loading.value = true
|
||||
emit('loading')
|
||||
queryProductSkuAjax(item)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -373,6 +578,7 @@ async function queryCategoryAjax() {
|
|||
page: 1,
|
||||
pageSize: 100
|
||||
})
|
||||
temporaryCategorys.value = [...res.list]
|
||||
categorys.value = res.list
|
||||
categorys.value.unshift({
|
||||
name: '全部',
|
||||
|
|
@ -666,6 +872,7 @@ defineExpose({
|
|||
|
||||
onMounted(async () => {
|
||||
localUpdateShopListType()
|
||||
getUnitListAjax()
|
||||
await updateCategoryActive()
|
||||
await queryCategoryAjax()
|
||||
})
|
||||
|
|
@ -785,6 +992,10 @@ onMounted(async () => {
|
|||
justify-content: space-between;
|
||||
padding: var(--el-font-size-base);
|
||||
|
||||
.left {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.right {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
|
|
@ -872,6 +1083,17 @@ onMounted(async () => {
|
|||
height: 60%;
|
||||
position: relative;
|
||||
|
||||
.weight {
|
||||
position: absolute;
|
||||
left: 5px;
|
||||
bottom: 5px;
|
||||
color: #fff;
|
||||
font-size: 12px;
|
||||
padding: 2px 6px;
|
||||
background-color: var(--el-color-danger);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.el_img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
|
@ -962,4 +1184,17 @@ onMounted(async () => {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.remark_list {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
margin-top: 10px;
|
||||
|
||||
.item {
|
||||
padding: 0 10px;
|
||||
border: 1px solid #ddd;
|
||||
color: #999;
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,206 @@
|
|||
<!-- 称重商品组件 -->
|
||||
<template>
|
||||
<el-dialog title="可选套餐" width="70%" :close-on-click-modal="false" v-model="dialogVisible" top="10vh">
|
||||
<div class="row" v-for="(item, index) in goodsItem.proGroupVo" :key="index">
|
||||
<div class="title_wrap">
|
||||
<div class="item">规格组名:{{ item.title }}</div>
|
||||
<div class="item"
|
||||
v-html="`本组菜品<span style='color: var(--el-color-danger)'>${item.count}</span>选<span style='color: var(--el-color-danger)'>${item.number}</span>`">
|
||||
</div>
|
||||
</div>
|
||||
<div class="error">
|
||||
<span v-if="item.isError">错误:请按规格组选择菜品</span>
|
||||
</div>
|
||||
<el-table border :data="item.goods" ref="tabRefs" @select="selectChange($event, index)"
|
||||
@select-all="selectChange($event, index)">
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column label="名称" prop="proName"></el-table-column>
|
||||
<el-table-column label="规格" prop="skuName"></el-table-column>
|
||||
<el-table-column label="价格" prop="price">
|
||||
<template v-slot="scope">
|
||||
¥{{ formatDecimal(scope.row.price) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="数量" prop="number">
|
||||
<template v-slot="scope">
|
||||
{{ `${scope.row.number}${scope.row.unitName || ''}` }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="footer">
|
||||
<el-button style="width: 100%" @click="dialogVisible = false">
|
||||
取消
|
||||
</el-button>
|
||||
<el-button type="primary" style="width: 100%" :disabled="disabled" @click="confirmHandle">
|
||||
{{ disabled ? '请选择菜品' : '确认' }}
|
||||
</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { inputFilterFloat, formatDecimal } from '@/utils/index.js'
|
||||
|
||||
const dialogVisible = ref(false);
|
||||
const number = ref("");
|
||||
const goodsItem = ref({})
|
||||
|
||||
const emit = defineEmits(["success"]);
|
||||
|
||||
const tabRefs = ref([])
|
||||
|
||||
function show(item) {
|
||||
disabled.value = true
|
||||
dialogVisible.value = true;
|
||||
goodsItem.value = { ...item }
|
||||
goodsItem.value.proGroupVo.map(item => {
|
||||
item.isError = false
|
||||
})
|
||||
setTimeout(() => {
|
||||
tabRefs.value.map(item => {
|
||||
item.clearSelection()
|
||||
})
|
||||
}, 100);
|
||||
}
|
||||
|
||||
// 选择表格触发
|
||||
function selectChange($event, index) {
|
||||
let item = goodsItem.value.proGroupVo[index]
|
||||
let selectNum = tabRefs.value[index].getSelectionRows()
|
||||
|
||||
if (selectNum.length != item.number) {
|
||||
item.isError = true
|
||||
} else {
|
||||
item.isError = false
|
||||
}
|
||||
|
||||
let flags = []
|
||||
|
||||
goodsItem.value.proGroupVo.map((item, index) => {
|
||||
let selectNum = tabRefs.value[index].getSelectionRows()
|
||||
if (selectNum.length != item.number) {
|
||||
flags.push({ flag: false })
|
||||
} else {
|
||||
flags.push({ flag: true })
|
||||
}
|
||||
})
|
||||
|
||||
const arr = flags.find(item => !item.flag)
|
||||
|
||||
if (arr != undefined && !arr.flag) {
|
||||
disabled.value = true
|
||||
return
|
||||
}
|
||||
|
||||
disabled.value = false
|
||||
}
|
||||
|
||||
// 确认
|
||||
const disabled = ref(true)
|
||||
function confirmHandle() {
|
||||
let flags = []
|
||||
|
||||
goodsItem.value.proGroupVo.map((item, index) => {
|
||||
let selectNum = tabRefs.value[index].getSelectionRows()
|
||||
if (selectNum.length != item.number) {
|
||||
flags.push({ flag: false })
|
||||
} else {
|
||||
flags.push({ flag: true })
|
||||
}
|
||||
})
|
||||
|
||||
const arr = flags.find(item => !item.flag)
|
||||
|
||||
if (arr != undefined && !arr.flag) {
|
||||
disabled.value = true
|
||||
return
|
||||
}
|
||||
|
||||
disabled.value = false
|
||||
|
||||
let goodIds = []
|
||||
goodsItem.value.proGroupVo.map((item, index) => {
|
||||
let selectNum = tabRefs.value[index].getSelectionRows()
|
||||
goodIds.push(selectNum)
|
||||
})
|
||||
|
||||
// 将商品数据转为一维数组返回
|
||||
emit("success", {
|
||||
...goodsItem.value,
|
||||
productId: goodsItem.value.id,
|
||||
groupProductIdList: goodIds.flat().map(item => item.proId)
|
||||
});
|
||||
dialogVisible.value = false;
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
show,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.keybord_wrap {
|
||||
padding: var(--el-font-size-base) 0;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
grid-template-rows: 1fr 1fr 1fr 1fr;
|
||||
gap: var(--el-font-size-base);
|
||||
|
||||
:deep(.el-button--large) {
|
||||
height: 50px;
|
||||
}
|
||||
}
|
||||
|
||||
.input_wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 20px;
|
||||
|
||||
.item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.price_item {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
color: var(--el-color-danger);
|
||||
padding: 15px 0;
|
||||
border-top: 1px solid #ececec;
|
||||
}
|
||||
|
||||
.footer {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.row {
|
||||
margin-bottom: 20px;
|
||||
|
||||
.title_wrap {
|
||||
display: flex;
|
||||
gap: 30px;
|
||||
font-size: 16px;
|
||||
// padding-bottom: 10px;
|
||||
|
||||
.item {
|
||||
span {
|
||||
margin: 0 4px;
|
||||
font-weight: bold;
|
||||
color: var(--el-color-danger);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.error {
|
||||
height: 20px;
|
||||
color: var(--el-color-danger);
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
|
|
@ -278,7 +278,8 @@ async function printOrderLable() {
|
|||
number: item.num,
|
||||
skuName: item.productSkuName,
|
||||
salePrice: formatDecimal(item.price),
|
||||
totalAmount: formatDecimal(item.num * item.price)
|
||||
totalAmount: formatDecimal(item.num * item.price),
|
||||
proGroupInfo: item.proGroupInfo
|
||||
}
|
||||
)
|
||||
})
|
||||
|
|
|
|||
|
|
@ -0,0 +1,131 @@
|
|||
<!-- 称重商品组件 -->
|
||||
<template>
|
||||
<el-dialog title="称重商品" width="400" :close-on-click-modal="false" v-model="dialogVisible" top="10vh"
|
||||
@closed="reset">
|
||||
<div class="input_wrap">
|
||||
<div class="item">
|
||||
<div class="title">单价</div>
|
||||
<el-button type="primary" plain>¥{{ goodsItem.lowPrice }}/{{ goodsItem.unitName }}</el-button>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="title">重量</div>
|
||||
<el-input v-model="number" readonly placeholder="请输入">
|
||||
<template #append>{{ goodsItem.unitName }}</template>
|
||||
</el-input>
|
||||
</div>
|
||||
</div>
|
||||
<div class="keybord_wrap">
|
||||
<div v-for="item in 9" :key="item">
|
||||
<el-button plain type="info" style="width: 100%" @click="inputHandle(item)">{{ item }}</el-button>
|
||||
</div>
|
||||
<div>
|
||||
<el-button plain type="info" style="width: 100%" @click="inputHandle('.')">.</el-button>
|
||||
</div>
|
||||
<div>
|
||||
<el-button plain type="info" style="width: 100%" @click="inputHandle(0)">0</el-button>
|
||||
</div>
|
||||
<div>
|
||||
<el-button plain type="info" icon="CloseBold" style="width: 100%" @click="delHandle"></el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="price_item">
|
||||
¥{{ formatDecimal(goodsItem.lowPrice * number) }}
|
||||
</div>
|
||||
<div class="footer">
|
||||
<el-button style="width: 100%" :loading="loading" @click="dialogVisible = false">
|
||||
取消
|
||||
</el-button>
|
||||
<el-button type="primary" style="width: 100%" :loading="loading" :disabled="number <= 0"
|
||||
@click="confirmHandle">
|
||||
确认
|
||||
</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { inputFilterFloat, formatDecimal } from '@/utils/index.js'
|
||||
|
||||
const dialogVisible = ref(false);
|
||||
const number = ref("");
|
||||
const goodsItem = ref({})
|
||||
|
||||
const emit = defineEmits(["success"]);
|
||||
|
||||
function show(item) {
|
||||
dialogVisible.value = true;
|
||||
goodsItem.value = { ...item }
|
||||
}
|
||||
|
||||
function reset() {
|
||||
goodsItem.value = {}
|
||||
number.value = ''
|
||||
}
|
||||
|
||||
// 输入
|
||||
function inputHandle(n) {
|
||||
// number.value += n;
|
||||
number.value = inputFilterFloat(number.value += n)
|
||||
}
|
||||
|
||||
// 删除
|
||||
function delHandle() {
|
||||
if (!number.value) return;
|
||||
number.value = number.value.substring(0, number.value.length - 1);
|
||||
}
|
||||
|
||||
const loading = ref(false)
|
||||
// 确认
|
||||
function confirmHandle() {
|
||||
if (!number.value) return
|
||||
goodsItem.value.productId = goodsItem.value.id
|
||||
goodsItem.value.number = number.value
|
||||
|
||||
emit("success", goodsItem.value);
|
||||
dialogVisible.value = false;
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
show,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.keybord_wrap {
|
||||
padding: var(--el-font-size-base) 0;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
grid-template-rows: 1fr 1fr 1fr 1fr;
|
||||
gap: var(--el-font-size-base);
|
||||
|
||||
:deep(.el-button--large) {
|
||||
height: 50px;
|
||||
}
|
||||
}
|
||||
|
||||
.input_wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 20px;
|
||||
|
||||
.item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.price_item {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
color: var(--el-color-danger);
|
||||
padding: 15px 0;
|
||||
border-top: 1px solid #ececec;
|
||||
}
|
||||
|
||||
.footer {
|
||||
display: flex;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -51,7 +51,11 @@
|
|||
@click="selectCartItemHandle(item, index, i)">
|
||||
<div class="name_wrap">
|
||||
<span>{{ item.name }}</span>
|
||||
<span>¥{{ item.salePrice }}</span>
|
||||
<div class="price">
|
||||
<span :class="{ dis: item.discountSaleAmount }">¥{{ item.salePrice }}</span>
|
||||
<span v-if="item.discountSaleAmount">
|
||||
¥{{ formatDecimal(item.salePrice - item.discountSaleAmount, 2, true) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sku_list" v-if="item.skuName">
|
||||
<div class="tag" v-for="item in item.skuName.split(',')">
|
||||
|
|
@ -60,21 +64,26 @@
|
|||
</div>
|
||||
<div class="num">
|
||||
<div class="left">
|
||||
<div class="icon_item" v-if="item.isGift == 'true'" @click="giftPackHandle('isGift', item)">
|
||||
<el-icon class="icon">
|
||||
<ShoppingBag />
|
||||
</el-icon>
|
||||
<div class="icon_item zen" v-if="item.isGift == 'true'" @click="giftPackHandle('isGift', item)">
|
||||
<span class="t">赠</span>
|
||||
</div>
|
||||
<div class="icon_item" v-if="item.isPack == 'true'" @click="giftPackHandle('isPack', item)">
|
||||
<el-icon class="icon" style="color: var(--primary-color)">
|
||||
<Box />
|
||||
</el-icon>
|
||||
<div class="icon_item bao" v-if="item.isPack == 'true'" @click="giftPackHandle('isPack', item)">
|
||||
<span class="t">包</span>
|
||||
</div>
|
||||
<div class="icon_item" v-if="item.status == 'return'">
|
||||
<span class="t">已退</span>
|
||||
<div class="icon_item tui" v-if="item.status == 'return'">
|
||||
<span class="t">退</span>
|
||||
</div>
|
||||
<div class="icon_item lin" v-if="item.isTemporary == 1">
|
||||
<span class="t">临</span>
|
||||
</div>
|
||||
<div class="icon_item zhe" v-if="item.discountSaleAmount">
|
||||
<span class="t">折</span>
|
||||
</div>
|
||||
<div class="icon_item chu" v-if="item.isPrint == 0">
|
||||
<span class="t">免厨打印</span>
|
||||
</div>
|
||||
</div>
|
||||
<el-text class="t">X{{ item.number }}</el-text>
|
||||
<el-text class="t">X{{ formatDecimal(item.number, 2, true) }}</el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -402,27 +411,43 @@ function selectCartItemHandle(row, index, i) {
|
|||
}
|
||||
|
||||
// 选择完规格开始添加购物车
|
||||
async function addCart(params, type = "add") {
|
||||
async function addCart(params = {}, type = "add") {
|
||||
console.log(params);
|
||||
|
||||
try {
|
||||
cartLoading.value = true;
|
||||
if (params.isTemporary) {
|
||||
await createCodeAjax()
|
||||
cartLoading.value = false;
|
||||
} else {
|
||||
let skuId = ''
|
||||
if (params.skuList && params.skuList.length) {
|
||||
skuId = params.skuList[0].id
|
||||
} else {
|
||||
skuId = type == "add" ? params.id : params.skuId
|
||||
}
|
||||
|
||||
const res = await createCart({
|
||||
productId: params.productId,
|
||||
masterId: masterId.value,
|
||||
tableId: global.tableInfo.qrcode || '',
|
||||
vipUserId: global.orderMemberInfo.id || '',
|
||||
shopId: store.userInfo.shopId,
|
||||
skuId: type == "add" ? params.id : params.skuId,
|
||||
// skuId: type == "add" ? params.id : params.skuId,
|
||||
skuId: skuId,
|
||||
number: params.number || 1,
|
||||
isPack: params.isPack || "false",
|
||||
isGift: params.isGift || "false",
|
||||
cartId: type == "add" ? "" : params.id,
|
||||
uuid: params.uuid || store.userInfo.uuid,
|
||||
type: type,
|
||||
groupProductIdList: params.groupProductIdList || []
|
||||
});
|
||||
cartLoading.value = false;
|
||||
masterId.value = res;
|
||||
goodsRef.value.updateData();
|
||||
queryCartAjax();
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
cartLoading.value = false;
|
||||
|
|
@ -498,7 +523,6 @@ async function addTableNum() {
|
|||
|
||||
// 获取取餐码
|
||||
async function createCodeAjax(type = "0") {
|
||||
console.log(1111)
|
||||
try {
|
||||
// if (!process.env.VITE_DEV_SERVER_URL) {
|
||||
// masterId.value = '#20'
|
||||
|
|
@ -661,6 +685,13 @@ onMounted(() => {
|
|||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: var(--el-font-size-base);
|
||||
|
||||
.dis {
|
||||
color: #999;
|
||||
font-size: 12px;
|
||||
text-decoration: line-through;
|
||||
margin-right: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.sku_list {
|
||||
|
|
@ -686,21 +717,51 @@ onMounted(() => {
|
|||
.left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
padding-right: 10px;
|
||||
|
||||
.icon_item {
|
||||
$size: 30px;
|
||||
width: $size;
|
||||
$size: 20px;
|
||||
height: $size;
|
||||
border-radius: 4px;
|
||||
padding: 0 6px;
|
||||
border-radius: 2px;
|
||||
background-color: #e2e2e2;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-right: 10px;
|
||||
|
||||
.t {
|
||||
color: #fff;
|
||||
font-size: 10px;
|
||||
color: #888;
|
||||
|
||||
&.zen {
|
||||
background-color: #FFB0B1;
|
||||
color: #FF4D4F;
|
||||
}
|
||||
|
||||
&.bao {
|
||||
background-color: #52C41A;
|
||||
}
|
||||
|
||||
&.tui {
|
||||
background-color: var(--el-color-danger);
|
||||
}
|
||||
|
||||
&.lin {
|
||||
background-color: var(--el-color-warning);
|
||||
}
|
||||
|
||||
&.zhe {
|
||||
background-color: var(--primary-color);
|
||||
}
|
||||
|
||||
&.chu {
|
||||
background-color: #ffe7ba;
|
||||
color: #e69f1c;
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: inherit;
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -122,6 +122,7 @@
|
|||
</div>
|
||||
<div class="orderbox_right_list_item" style="margin-top: 20px"
|
||||
v-for="(item, index) in orderDetaildata.detailList" :key="index">
|
||||
<div class="orderbox_right_list_item_row" style="display:flex;">
|
||||
<div>{{ item.productName }} {{ item.productSkuName }}</div>
|
||||
<div style="text-align: center">{{ item.num }}</div>
|
||||
<div style="text-align: center">{{ item.price }}</div>
|
||||
|
|
@ -130,6 +131,16 @@
|
|||
</div>
|
||||
<div v-else>{{ item.priceAmount }}</div>
|
||||
</div>
|
||||
<div class="pro" v-if="item.proGroupInfo" v-for="(val, idx) in JSON.parse(item.proGroupInfo)" :key="idx">
|
||||
<div>
|
||||
<span>>{{ val.proName }}</span>
|
||||
<span v-if="val.skuName">规格:{{ val.skuName }}</span>
|
||||
</div>
|
||||
<div>{{ val.number }}</div>
|
||||
<div>0</div>
|
||||
<div>0</div>
|
||||
</div>
|
||||
</div>
|
||||
<div :style="{ height: reforderboxrightbuttonheight + 'px' }"></div>
|
||||
</div>
|
||||
|
||||
|
|
@ -513,7 +524,8 @@ const print = lodash.throttle(
|
|||
number: item.num,
|
||||
skuName: item.productSkuName,
|
||||
salePrice: formatDecimal(item.price),
|
||||
totalAmount: formatDecimal(item.num * item.price)
|
||||
totalAmount: formatDecimal(item.num * item.price),
|
||||
proGroupInfo: item.proGroupInfo
|
||||
}
|
||||
)
|
||||
})
|
||||
|
|
@ -1098,6 +1110,41 @@ onMounted(() => {
|
|||
}
|
||||
|
||||
.orderbox_right_list_item {
|
||||
.pro {
|
||||
display: flex;
|
||||
font-size: 14px;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding-bottom: 10px;
|
||||
|
||||
div:nth-child(1) {
|
||||
text-align: left;
|
||||
width: 45%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
}
|
||||
|
||||
div:nth-child(2) {
|
||||
width: 15%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
div:nth-child(3) {
|
||||
width: 15%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
div:nth-child(4) {
|
||||
width: 25%;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
}
|
||||
|
||||
.orderbox_right_list_item_row {
|
||||
display: flex;
|
||||
font-size: 14px;
|
||||
justify-content: space-between;
|
||||
|
|
@ -1124,6 +1171,7 @@ onMounted(() => {
|
|||
width: 25%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tableDataclass {
|
||||
width: 100%;
|
||||
|
|
|
|||
Loading…
Reference in New Issue