Files
cashierdesktop/src/views/group_buy/components/scanGroup.vue
2024-12-06 14:41:58 +08:00

525 lines
16 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!-- 扫码弹窗 -->
<template>
<div class="dialog">
<el-dialog :title="`核销${props.title}团购券`" width="600" v-model="dialogVisible" @open="reset" @close="close">
<div class="content">
<div class="left">
<el-image :src="icon" style="width: 60px; height: 60px"></el-image>
</div>
<div class="right" v-if="!userPayWait">
<div class="amount">
<span class="t">扫码核销</span>
<!-- <span class="n">{{ props.amount }}</span> -->
</div>
<div class="input">
<el-input ref="inputRef" v-model="scanCode"
style="height: calc(var(--el-component-size-large) + 30px)" placeholder="请扫描团购券" clearable
@change="inputChange"></el-input>
<div class="tips">注意扫码支付请保证输入框获得焦点输入内容结束后会自动核销请勿重复操作</div>
</div>
<!-- <div class="number_warp">
<div class="item" v-for="item in 9" :key="item" @click="inputHandle(item)">{{ item }}</div>
<div class="item disabled">.</div>
<div class="item" @click="inputHandle(0)">0</div>
<div class="item" @click="delHandle">
<el-icon>
<CloseBold />
</el-icon>
</div>
</div> -->
<div class="btn">
<el-button type="primary" style="width: 100%" v-loading="loading">立即核销</el-button>
</div>
</div>
<div class="pay_wait" v-else>
<div class="loading" v-loading="loading" element-loading-text="用户支付中..."></div>
<div class="btn">
<el-button type="primary" style="width: 100%" v-loading="checkPayStatusLoading"
@click="checkPayStauts">
<span v-if="!checkPayStatusLoading">查询用户支付状态</span>
<span v-else>查询中...</span>
</el-button>
</div>
<div class="btn">
<el-button style="width: 100%" @click="resetScanCode">
重新扫码
</el-button>
</div>
</div>
</div>
</el-dialog>
<el-dialog title="团购券详情" width="600" v-model="detailVisible">
<div class="group_detil">
<div class="shop_info" v-if="props.type == 1">
<el-image :src="groupDetail.images[0]" style="width: 50px;height: 50px;"></el-image>
<div class="info">
<div class="name">{{ groupDetail.productName }}</div>
<div class="price">
<span class="p">{{ groupDetail.salePrice }}</span>
<span class="o">{{ groupDetail.originPrice }}</span>
</div>
</div>
</div>
<div class="table">
<el-table :data="groupDetail.productList" border v-if="props.type == 1">
<el-table-column label="名称" prop="title"></el-table-column>
<el-table-column label="数量" prop="number"></el-table-column>
<el-table-column label="商品信息">
<template v-slot="scope">
<div class="shop_list">
<div class="item" v-for="(item, index) in scope.row.goods" :key="item.id">
<span class="dot"></span>
<div class="name">
<div class="t">{{ item.name }}</div>
<div class="t">x{{ item.groupNum }}</div>
</div>
</div>
</div>
</template>
</el-table-column>
</el-table>
<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>
</el-table>
</div>
</div>
<div class="footer">
<el-button style="width: 100%;" @click="detailVisible = false">取消</el-button>
<el-button type="primary" style="width: 100%;" :loading="groupDetailLoading"
@click="groupOrdergroupScanHandle">确认核销</el-button>
</div>
</el-dialog>
<BindShop ref="BindShopRef" @success="submitHandle()" />
</div>
</template>
<script setup>
import _ from "lodash";
import { ref } from "vue";
import icon from "@/assets/icon_scan.png";
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)
const store = useUser();
import {
queryMembermember,
createMembermember,
membermemberScanPay,
accountPaymember,
} from "@/api/member/index.js";
import { ElMessage } from "element-plus";
import { useGlobal } from '@/store/global.js'
const global = useGlobal()
const emits = defineEmits(["success"]);
const props = defineProps({
title: {
type: String,
default: ''
},
type: {
type: Number,
default: 1
}
});
const dialogVisible = ref(false);
const scanCode = ref("");
const inputRef = ref(null);
const loading = ref(false);
const userPayWait = ref(false);
const checkPayStatusLoading = ref(false);
const fastOrder = ref('')
const groupDetailLoading = ref(false)
const groupDetail = ref({})
const detailVisible = ref(false)
// 团购卷核销(仅核销待使用订单)
async function groupOrdergroupScanHandle() {
try {
switch (props.type) {
case 1:
{
groupDetailLoading.value = true
const res = await groupOrdergroupScan({
id: groupDetail.value.id
})
}
break;
case 2:
{
let encrypted_codes = douyin_table.value.getSelectionRows()
if (encrypted_codes.length) {
groupDetailLoading.value = true
let arr = encrypted_codes.map(item => item.encrypted_code)
console.log(encrypted_codes);
const res = await douyincertificateprepare({
verify_token: groupDetail.value.verify_token,
encrypted_codes: arr.join(','),
id: groupDetail.value.id
})
} else {
ElMessage.error('请选择核销项目')
return
}
}
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;
}
groupDetailLoading.value = false
detailVisible.value = false
scanCode.value = ''
inputRef.value.focus();
ElMessage.success('核销成功')
emits('succcess')
} catch (error) {
groupDetailLoading.value = false
console.log('groupOrdergroupScanHandle.error', error);
}
}
const douyin_table = ref(null)
// 核销券码
async function submitHandle() {
try {
loading.value = true
switch (props.type) {
case 1:
{
const res = await groupOrderorderInfo({
coupon: scanCode.value,
});
loading.value = false
groupDetail.value = res
detailVisible.value = true
}
break;
case 2:
{
const res = await douyinfulfilmentcertificateprepare({
object_id: decodeURI(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;
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;
}
} catch (error) {
loading.value = false
console.log('submitHandle.error', error);
if (error.code == 4399) {
BindShopRef.value.show()
}
}
}
// 重新扫码
function resetScanCode() {
userPayWait.value = false;
loading.value = false;
scanCode.value = "";
inputRef.value.focus();
}
// 输入
function inputHandle(n) {
scanCode.value += n;
inputRef.value.focus();
}
// 删除
function delHandle() {
if (!scanCode.value) return;
scanCode.value = scanCode.value.substring(0, scanCode.value.length - 1);
inputRef.value.focus();
}
// 监听扫码枪回车事件
// function enterHandle() {
// inputRef.value.focus()
// }
const inputChange = _.debounce(function (e) {
// console.log(e);
if (scanCode.value) {
submitHandle();
}
}, 500);
function show() {
global.updateData(false)
dialogVisible.value = true;
setTimeout(() => {
inputRef.value.focus();
}, 500);
}
function close() {
global.updateData(true)
dialogVisible.value = false;
}
function reset() {
loading.value = false;
scanCode.value = "";
}
defineExpose({
show,
close,
loading,
submitHandle
});
</script>
<style scoped lang="scss">
.footer {
display: flex;
padding: 0 14px 14px;
}
.group_detil {
padding: 14px;
.shop_info {
display: flex;
.info {
flex: 1;
padding-left: 10px;
.name {
font-size: 18px;
font-weight: bold;
color: #000;
}
.price {
.p {
font-size: 20px;
font-weight: bold;
color: red;
}
.o {
color: #999;
text-decoration: line-through;
margin-left: 10px;
}
}
}
}
.table {
padding-top: 14px;
}
.shop_list {
.item {
display: flex;
align-items: center;
&:not(:first-child) {
margin-top: 6px;
}
.dot {
$size: 6px;
width: $size;
height: $size;
border-radius: 50%;
background-color: #1890FF;
}
.name {
flex: 1;
display: flex;
margin-left: 10px;
align-items: center;
.t {
color: #333;
font-size: 14px;
width: 100px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
margin-right: 10px;
}
}
.del {
font-size: 14px;
color: #999;
&:hover {
cursor: pointer;
color: #555;
}
}
}
}
}
.tips {
padding-top: 10px;
color: #999;
}
.dialog :deep(.el-dialog__body) {
padding: 0 !important;
}
.content {
display: flex;
.left {
width: 200px;
display: flex;
align-items: center;
justify-content: center;
background-color: #efefef;
}
.right {
flex: 1;
padding: var(--el-font-size-base);
.amount {
display: flex;
height: calc(var(--el-component-size-large) + 20px);
display: flex;
align-items: center;
justify-content: space-between;
color: var(--primary-color);
background-color: #555;
border-radius: 6px;
padding: 0 var(--el-font-size-base);
font-size: calc(var(--el-font-size-base) + 10px);
}
.input {
padding: var(--el-font-size-base) 0;
:deep(.el-input__inner) {
font-size: calc(var(--el-font-size-base) + 10px);
}
}
.number_warp {
--h: 50px;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: var(--h) var(--h) var(--h) var(--h);
gap: 8px;
.item {
background-color: #dddddd;
display: flex;
align-items: center;
justify-content: center;
font-size: calc(var(--el-font-size-base) + 10px);
border-radius: 4px;
&.disabled {
color: #999;
background-color: #efefef;
&:active {
background-color: #efefef;
}
}
&:active {
background-color: #b9b9b9;
}
}
}
// .btn {
// padding-top: 20px;
// }
}
.pay_wait {
flex: 1;
padding: 0 var(--el-font-size-base);
height: 400px;
padding-bottom: 100px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.loading {
width: 200px;
height: 200px;
--el-loading-spinner-size: 100px;
:deep(.el-loading-text) {
font-size: 20px;
}
}
.btn {
width: 200px;
padding-top: var(--el-font-size-base);
}
}
}
</style>