476 lines
14 KiB
Vue
476 lines
14 KiB
Vue
<!-- 扫码弹窗 -->
|
||
|
||
<template>
|
||
<div class="dialog">
|
||
<el-dialog :title="`核销${props.title}团购券`" width="600" v-model="dialogVisible" @open="reset">
|
||
<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-if="props.type == 2"
|
||
@selection-change="douyinSelectionChange">
|
||
<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>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup>
|
||
import _ from "lodash";
|
||
import { ref } from "vue";
|
||
import icon from "@/assets/icon_scan.png";
|
||
import { groupOrderorderInfo, groupOrdergroupScan, douyinfulfilmentcertificateprepare, douyincertificateprepare } from '@/api/group'
|
||
import { useUser } from "@/store/user.js";
|
||
const store = useUser();
|
||
import {
|
||
queryMembermember,
|
||
createMembermember,
|
||
membermemberScanPay,
|
||
accountPaymember,
|
||
} from "@/api/member/index.js";
|
||
import { ElMessage } from "element-plus";
|
||
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:
|
||
{
|
||
groupDetailLoading.value = true
|
||
let encrypted_codes = groupDetail.value.goods.map(item => item.encrypted_code)
|
||
const res = await douyincertificateprepare({
|
||
verify_token: groupDetail.value.verify_token,
|
||
encrypted_codes: encrypted_codes.join(','),
|
||
id: groupDetail.value.id
|
||
})
|
||
}
|
||
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(error);
|
||
}
|
||
}
|
||
|
||
const douyin_table = ref(null)
|
||
|
||
// 选择要核销的券
|
||
function douyinSelectionChange(e) {
|
||
console.log(e);
|
||
}
|
||
|
||
// 核销券码
|
||
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),
|
||
});
|
||
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(error);
|
||
}
|
||
}
|
||
|
||
// 重新扫码
|
||
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() {
|
||
dialogVisible.value = true;
|
||
setTimeout(() => {
|
||
inputRef.value.focus();
|
||
}, 500);
|
||
}
|
||
|
||
function close() {
|
||
dialogVisible.value = false;
|
||
}
|
||
|
||
function reset() {
|
||
loading.value = false;
|
||
scanCode.value = "";
|
||
}
|
||
|
||
defineExpose({
|
||
show,
|
||
close,
|
||
loading,
|
||
});
|
||
</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> |