feat: 增加美团抖音扫码核销

This commit is contained in:
2025-03-07 19:29:10 +08:00
parent 63a4ed9e73
commit cec6ea62df
7 changed files with 600 additions and 6 deletions

View File

@@ -432,8 +432,10 @@ export const useCartsStore = defineStore("carts", () => {
// console.log('oldOrder.detailMap', oldOrder.value.detailMap)
// const cache_table_code = localStorage.getItem('cache_table_code');
// const randomTableCode = cache_table_code ? cache_table_code : ('APC' + (1000 + Math.floor(Math.random() * 9000)))
initParams.table_code = initParams.table_code ? initParams.table_code : ''
table_code.value = initParams.table_code
if (initParams) {
initParams.table_code = initParams.table_code ? initParams.table_code : ''
table_code.value = initParams.table_code
}
// localStorage.setItem('cache_table_code', table_code.value);
WebSocketManager.subscribeToTopic(initParams, (msg) => {

View File

@@ -35,7 +35,7 @@ service.interceptors.response.use(
});
return;
}
if (data.code == 439) {
if (data.code == 439 || data.code == 303) {
ElNotification.error({
title: "请登录",
duration: 5000,

View File

@@ -193,9 +193,7 @@ function handleLogin() {
.then(async (res) => {
await userStore.getUserInfo();
await $douyin_checkIn();
const { path, queryParams } = parseRedirect();
console.log(res, "Denglv返回");
router.push({ path: path, query: queryParams });
})
.catch(() => {

View File

@@ -0,0 +1,160 @@
<template>
<el-dialog title="选择商品" width="450px" v-model="show">
<div class="app-container">
<div class="head-container">
<el-table
:data="tableData"
ref="table"
@selection-change="handleSelectionChange"
@cell-click="cellClick"
>
<el-table-column type="selection" width="55"></el-table-column>
<el-table-column label="套餐名称" prop="title"></el-table-column>
<el-table-column label="原价" prop="amount"></el-table-column>
</el-table>
<div class="u-flex u-row-center u-m-t-50 gap-20">
<el-button @click="close">取消</el-button>
<el-button type="primary" @click="confirm">确认核销</el-button>
</div>
</div>
</div>
</el-dialog>
</template>
<script>
import { ElMessage } from "element-plus";
import { $douyin_certificateprepare, $meituan_certificateprepare } from "@/api/coup/index";
export default {
data() {
return {
show: false,
data: {},
tableData: [],
selArr: [],
types: "douyin", //douyin meituan
};
},
filters: {},
mounted() {
// this.getTableData();
},
methods: {
handleSelectionChange(e) {
this.selArr = e;
console.log(e);
},
cellClick(user) {
this.$refs.table.toggleRowSelection(user);
},
async choose(user) {
console.log(user);
},
close() {
this.show = false;
},
async confirm() {
console.log(this.selArr.length);
if (this.selArr.length <= 0) {
return ElMessage.error("请选择套餐商品");
}
console.log(this.types);
if (this.types == "meituan") {
//美团
const mRes = await $meituan_certificateprepare({
couponCode: this.data.couponCode,
num: this.selArr.length,
});
}
//抖音
if (this.types == "douyin") {
const res = await $douyin_certificateprepare({
verify_token: this.data.verify_token,
encrypted_codes: this.selArr.map((item) => item.encrypted_code).join(","),
id: this.data.id,
});
}
ElMessage.success("核销成功");
this.close();
this.$emit("hexiaoSuccess");
},
open(res, types) {
this.data = res;
this.types = types ? types : this.types;
this.tableData = res.goods;
this.show = true;
this.$nextTick(() => {
this.$refs.table.toggleAllSelection();
});
},
},
};
</script>
<style scoped lang="scss">
.user_info {
display: flex;
align-items: center;
.name {
margin-left: 10px;
}
}
::v-deep .el-input--small .el-input__inner {
height: 36px;
line-height: 36px;
}
::v-deep .image-slot {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
background-color: #efefef;
font-size: 20px;
color: #999;
}
.card {
background-color: #f5f5f5;
padding: 0 14px;
.title {
font-size: 22px;
padding-top: 14px;
}
.row {
display: flex;
padding: 20px 0;
.item {
flex: 1;
.t {
text-align: center;
color: #555;
}
.n {
color: #000;
font-size: 20px;
font-weight: bold;
padding-top: 6px;
text-align: center;
}
}
}
}
.flex {
display: flex;
align-items: center;
}
.gap-20 {
gap: 20px;
}
</style>

View File

@@ -0,0 +1,208 @@
<template>
<el-dialog title="绑定门店" width="450px" v-model="show">
<div class="app-container">
<div class="head-container">
<el-table :data="tableData.data" v-loading="tableData.loading" @cell-click="cellClick">
<el-table-column label="店铺名称" prop="poi_name"></el-table-column>
<el-table-column label="店铺地址" prop="address"></el-table-column>
<el-table-column label="操作" width="90" fixed="right">
<template v-slot="scope">
<el-button type="primary" size="mini" @click="choose(scope.row)">绑定门店</el-button>
</template>
</el-table-column>
</el-table>
</div>
<div class="head-container">
<el-pagination
:total="tableData.total"
:current-page="tableData.page + 1"
:page-size="tableData.size"
@size-change="sizeChange"
@current-change="paginationChange"
layout="total, sizes, prev, pager, next, jumper"
></el-pagination>
</div>
</div>
</el-dialog>
</template>
<script>
import { $douyin_storelist, $douyin_bindstore } from "@/api/coup/index";
import dayjs from "dayjs";
import { ElMessage } from "element-plus";
let cacheData = {};
export default {
data() {
return {
show: false,
query: {},
shopInfo: {
balanceTotal: 0,
userTotal: 0,
chageTotal: 0,
},
tableData: {
data: [],
page: 0,
size: 10,
loading: false,
total: 0,
},
};
},
filters: {
timeFilter(s) {
return dayjs(s).format("YYYY-MM-DD HH:mm:ss");
},
},
mounted() {
// this.getTableData();
},
methods: {
cellClick(user) {
this.choose(user);
},
async choose(user) {
this.$emit("chooseUser", user);
const res = $douyin_bindstore({
poi_id: user.poi_id,
}).then((res) => {
this.close();
});
console.log(user);
},
charge(user) {
console.log(user);
},
close() {
this.show = false;
},
open() {
this.getTableData();
this.show = true;
},
toPage(type) {
const pages = {
charge: "charge_list",
cost: "cost_list",
};
this.$router.push({
name: pages[type],
});
console.log(pages[type]);
},
// 获取商家用户概述信息
sizeChange() {
this.tableData.page = 0;
this.getTableData();
},
// 切换状态
async statusChange(e, row) {
try {
this.tableData.loading = true;
const data = { ...row };
data.status = e;
await modityActivate(data);
this.getTableData();
} catch (error) {
console.log(error);
this.tableData.loading = false;
}
},
// 重置查询
resetHandle() {
this.query.name = "";
this.getTableData();
},
// 分页回调
paginationChange(e) {
this.tableData.page = e - 1;
this.getTableData();
},
async getTableData() {
this.tableData.loading = true;
try {
const res = await $douyin_storelist({
...this.query,
size: this.tableData.size,
page: this.tableData.page + 1,
});
console.log(res);
this.tableData.loading = false;
this.tableData.data = res.list;
this.tableData.total = res.count;
} catch (error) {
console.log(error);
}
},
},
};
</script>
<style scoped lang="scss">
.user_info {
display: flex;
align-items: center;
.name {
margin-left: 10px;
}
}
::v-deep .el-input--small .el-input__inner {
height: 36px;
line-height: 36px;
}
::v-deep .image-slot {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
background-color: #efefef;
font-size: 20px;
color: #999;
}
.card {
background-color: #f5f5f5;
padding: 0 14px;
.title {
font-size: 22px;
padding-top: 14px;
}
.row {
display: flex;
padding: 20px 0;
.item {
flex: 1;
.t {
text-align: center;
color: #555;
}
.n {
color: #000;
font-size: 20px;
font-weight: bold;
padding-top: 6px;
text-align: center;
}
}
}
}
.flex {
display: flex;
align-items: center;
}
.gap-20 {
gap: 20px;
}
</style>

View File

@@ -0,0 +1,217 @@
<template>
<div>
<el-dialog width="400px" :title="title" v-model="show" @close="reset">
<div class="u-p-15">
<div v-if="openSwitch">
<el-button
@click="changeKey('paysSel', index)"
v-for="(item, index) in pays"
:key="index"
:type="paysSel == index ? 'primary' : ''"
>
{{ item.text }}
</el-button>
</div>
<div class="u-m-t-20">
<el-alert :closable="false" v-if="tips" :title="tips" type="warning" show-icon></el-alert>
</div>
<div class="u-m-t-20">
<el-form label-width="90px" label-position="left">
<el-form-item label="券码">
<el-input
v-model="form.code"
@change="codeInputChange"
placeholder="请扫码或者输入券码"
ref="refInputCode"
></el-input>
</el-form-item>
<div class="u-flex u-row-center u-m-t-50">
<el-button @click="close">取消</el-button>
<el-button type="primary" @click="confirm">确定</el-button>
</div>
</el-form>
</div>
</div>
</el-dialog>
<bind-shop ref="refBindShop"></bind-shop>
<choose-goods ref="refChooseGoods" @hexiaoSuccess="hexiaoSuccess"></choose-goods>
</div>
</template>
<script>
import * as $Api from "@/api/coup/index.js";
import orderApi from "@/api/order/order";
import bindShop from "./douyin-quan-bind-shop.vue";
import chooseGoods from "./choose-quan-goods.vue";
import { ElMessage } from "element-plus";
export default {
components: { bindShop, chooseGoods },
props: {
openSwitch: {
type: Boolean,
default: true,
},
order: {
type: Object,
default: () => ({}),
},
title: {
type: String,
default: "团购券核销",
},
price: {
type: [String, Number],
default: 0,
},
defaultTips: {
type: String,
default: "请使用扫码枪扫描付券码",
},
},
filters: {
to2(n) {
return n.toFixed(2);
},
},
data() {
return {
tips: "",
paysSel: 0,
form: {
code: "",
},
pays: [
{
text: "美团",
},
{
text: "抖音",
},
],
show: false,
};
},
watch: {
defaultTips(val) {
this.tips = val;
},
price(val) {
console.log(val);
this.form.money = Number(val).toFixed(2);
},
number(newval) {
this.$emit("input", newval);
},
},
methods: {
refChooseGoodsOpen(data, types) {
this.$refs.refChooseGoods.open(data, types);
},
refBindShopOpen() {
this.$refs.refBindShop.open();
},
clear() {
clearInterval(this.timer);
},
hexiaoSuccess() {
this.reset();
this.close();
},
async getOrderDetail() {
const res = await tbOrderInfoDetail(this.order.id);
if (res.status == "closed") {
this.clear();
this.$emit("paySuccess");
}
},
codeInputChange(e) {
console.log(e);
// this.$emit("confirm", this.form.code);
},
reset() {
// this.form.money=''
this.form.code = "";
this.paysSel = 0;
this.clear();
},
changeKey(key, val) {
this[key] = val;
this.$nextTick(() => {
this.$refs.refInputCode.focus(); //获取焦点
});
},
async confirm() {
if (!this.form.code) {
return ElMessage.error("请输入或扫付券码");
}
if (this.paysSel === 1) {
//抖音
const res = await $Api.$douyin_fulfilmentcertificateprepare({
object_id: this.form.code,
});
if (res.code == 4399) {
this.refBindShopOpen();
} else {
console.log(res, 1111);
// if (res.code == 1) {
this.refChooseGoodsOpen(res);
// }
}
return;
}
if (this.paysSel === 0) {
//美团
const res = await $Api.$meituan_searchstorestatus({});
if (res.status == 0) {
const res2 = await $Api.$meituan_getuisdkurl({});
window.open(res2);
return;
}
const res1 = await $Api.$meituan_fulfilmentcertificateprepare({
code: this.form.code,
});
if (res1) {
const types = "meituan";
this.refChooseGoodsOpen(res1, types);
}
}
// ElMessage.success("核销成功");
},
open(data) {
this.show = true;
$Api.$douyin_checkIn().then((res) => {
console.log(res);
localStorage.setItem("bausertoken", res.userInfo.token);
});
setTimeout(() => {
this.$refs.refInputCode.focus();
}, 100);
},
close() {
this.show = false;
},
numberInput(val) {
console.log(val);
this.number = `${Number(val)}`;
},
keyboradConfirm() {
this.$emit("confirm", this.number);
},
},
mounted() {
this.number = `${this.value}`;
this.tips = this.defaultTips;
},
};
</script>
<style lang="scss" scoped>
.codeImg {
width: 164px;
border: 1px solid rgb(220, 223, 230);
height: 164px;
overflow: hidden;
}
</style>

View File

@@ -56,7 +56,7 @@
<el-button>{{ table.name ? "桌台号:" + table.name : "选择桌号" }}</el-button>
</template>
</el-popover>
<el-button type="warning">扫码验券</el-button>
<el-button type="warning" @click="refQuanHexiaoOpen">扫码验券</el-button>
</div>
</div>
<div class="right">
@@ -207,11 +207,14 @@
<dinerNumber ref="refDinerNumber" @confirm="dinerNumberConfirm"></dinerNumber>
<!-- 退菜 -->
<returnCart ref="refReturnCart" @confirm="refReturnCartConfirm"></returnCart>
<!-- 美团抖音核销 -->
<quanHexiao ref="refQuanHexiao"></quanHexiao>
</div>
</template>
<script setup>
import Controls from "./components/control.vue";
import dinerNumber from "./components/diner-number.vue";
import quanHexiao from "./components/popup-quan-hexiao.vue";
import note from "./components/note.vue";
import Order from "./components/order.vue";
import pack from "./components/pack.vue";
@@ -240,6 +243,12 @@ const shopUser = useUserStore();
const route = useRoute();
const router = useRouter();
//美团抖音核销
const refQuanHexiao = ref();
function refQuanHexiaoOpen() {
refQuanHexiao.value.open();
}
//退菜
const refReturnCart = ref();
async function refReturnCartConfirm(e) {