新增抖音团购券核销

This commit is contained in:
gyq
2024-07-17 18:02:01 +08:00
parent aa25c6be3b
commit c155e8a805
13 changed files with 257 additions and 48 deletions

View File

@@ -11,10 +11,6 @@ VITE_API_WSS = 'wss://cashier.sxczgkj.cn/client'
# 阿伟本地ws # 阿伟本地ws
# VITE_API_WSS = 'ws://192.168.2.17:9998/client' # VITE_API_WSS = 'ws://192.168.2.17:9998/client'
# 测试 php
# VITE_API_PHP_URL = 'http://192.168.2.33:1666/index.php/api'
# 正式 php # 正式 php
VITE_API_PHP_URL = 'http://czgdoumei.sxczgkj.com/index.php/api' VITE_API_PHP_URL = 'http://czgdoumei.sxczgkj.com/index.php/api'

View File

@@ -4,17 +4,8 @@ ENV = production
# 正式ws # 正式ws
VITE_API_WSS = 'wss://cashier.sxczgkj.cn/client' VITE_API_WSS = 'wss://cashier.sxczgkj.cn/client'
#测试ws
# VITE_API_WSS = 'wss://wxcashiertest.sxczgkj.cn/client'
# 测试 php
# VITE_API_PHP_URL = 'http://192.168.2.33:1666/index.php/api'
# 正式 php # 正式 php
VITE_API_PHP_URL = 'http://czgdoumei.sxczgkj.com/index.php/api' VITE_API_PHP_URL = 'http://czgdoumei.sxczgkj.com/index.php/api'
# 测试
# VITE_API_URL = 'https://cashier-client.sxczgkj.cn/cashier-client'
# 线上环境接口地址 # 线上环境接口地址
VITE_API_URL = 'https://cashierclient.sxczgkj.cn/cashier-client/' VITE_API_URL = 'https://cashierclient.sxczgkj.cn/cashier-client/'

17
.env.test Normal file
View File

@@ -0,0 +1,17 @@
# 线上环境
ENV = test
#测试ws
# VITE_API_WSS = 'wss://wxcashiertest.sxczgkj.cn/client'
# 正式ws
VITE_API_WSS = 'wss://cashier.sxczgkj.cn/client'
# 正式 php
VITE_API_PHP_URL = 'http://czgdoumei.sxczgkj.com/index.php/api'
# 测试
# VITE_API_URL = 'https://cashier-client.sxczgkj.cn/cashier-client'
# 正式
VITE_API_URL = 'https://cashierclient.sxczgkj.cn/cashier-client'

View File

@@ -1,11 +1,12 @@
{ {
"name": "vite-electron", "name": "vite-electron",
"private": true, "private": true,
"version": "1.4.3", "version": "1.4.6",
"main": "dist-electron/main.js", "main": "dist-electron/main.js",
"scripts": { "scripts": {
"dev": "chcp 65001 && vite", "dev": "chcp 65001 && vite",
"build": "node ./addVersion.js && vite build && electron-builder", "build": "node ./addVersion.js && vite build && electron-builder",
"build:test": "vite build --mode test && electron-builder",
"preview": "vite preview", "preview": "vite preview",
"build:win": "node ./addVersion.js && vite build && electron-builder --w" "build:win": "node ./addVersion.js && vite build && electron-builder --w"
}, },

View File

@@ -171,8 +171,8 @@ const updateInfo = _.throttle(function () {
// let info = navigator.connection // let info = navigator.connection
console.log(isOnLine); console.log(isOnLine);
// console.log(info); // console.log(info);
if (store.userInfo && store.userInfo.shopId) { if (store.userInfo && store.userInfo.shopId) {
if (isOnLine) { if (isOnLine) {
console.log('有网了重新连接ws~'); console.log('有网了重新连接ws~');
socket.init(); socket.init();
} else { } else {
@@ -193,7 +193,6 @@ onMounted(() => {
} }
ipcRenderer.on('showCloseDialog', (event, arg) => { ipcRenderer.on('showCloseDialog', (event, arg) => {
console.log('阻止系统关闭软件');
ElMessageBox.confirm("确定要关闭软件吗?") ElMessageBox.confirm("确定要关闭软件吗?")
.then(() => { .then(() => {
ipcRenderer.send("quitHandler", "退出吧"); ipcRenderer.send("quitHandler", "退出吧");

View File

@@ -119,3 +119,29 @@ export function douyinfulfilmentcertificatecancel(data) {
data, data,
}); });
} }
/**
* 门店列表
* @param {*} data
* @returns
*/
export function douyinstorelist(data) {
return request_php({
method: "post",
url: "douyin/storelist",
data,
});
}
/**
* 绑定门店
* @param {*} data
* @returns
*/
export function douyinbindstore(data) {
return request_php({
method: "post",
url: "douyin/bindstore",
data,
});
}

View File

@@ -7,7 +7,7 @@ const service = axios.create({
baseURL: baseURL:
import.meta.env.MODE == "development" import.meta.env.MODE == "development"
? "/php/" ? "/php/"
: import.meta.env.VITE_API_URL, : import.meta.env.VITE_API_PHP_URL,
// withCredentials: true, // 跨域请求时发送 cookies // withCredentials: true, // 跨域请求时发送 cookies
timeout: 5000, // 请求超时 timeout: 5000, // 请求超时
}); });

View File

@@ -0,0 +1,104 @@
<template>
<el-dialog title="绑定门店" v-model="showDialog" width="80%">
<div class="dialog">
<div class="tips">注意门店绑定后无法更改请谨慎选择</div>
<el-table :data="tableData.list" height="240px" border v-loading="tableData.loading">
<el-table-column label="门店名称" prop="poi_name"></el-table-column>
<el-table-column label="门店地址" prop="address"></el-table-column>
<el-table-column label="操作" width="120px">
<template v-slot="scope">
<el-button type="primary" size="small"
@click="bindShopHandle(scope.row.poi_id)">选择门店</el-button>
</template>
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination @current-change="paginationChange" :current-page="tableData.page"
:page-size="tableData.size" layout="total, prev, pager, next, jumper" :total="tableData.total"
background>
</el-pagination>
</div>
</div>
</el-dialog>
</template>
<script setup>
import { ElMessage } from 'element-plus'
import { onMounted, reactive, ref } from 'vue';
import { douyinstorelist, douyinbindstore } from '@/api/group.js'
const emits = defineEmits(['success'])
const showDialog = ref(false)
const tableData = reactive({
page: 1,
size: 10,
total: 0,
loading: false,
list: []
})
// 绑定门店
async function bindShopHandle(poi_id) {
try {
await douyinbindstore({
poi_id: poi_id
})
showDialog.value = false
ElMessage.success('绑定成功')
emits('success')
} catch (error) {
console.log(error);
}
}
// 分页变化
function paginationChange(e) {
tableData.page = e
getTableData()
}
// 获取门店列表
async function getTableData() {
try {
tableData.loading = true
const { list, count } = await douyinstorelist({
page: tableData.page,
size: tableData.size
})
tableData.loading = false
tableData.list = list
tableData.total = count
} catch (error) {
console.log(error);
}
}
// 显示
function show() {
showDialog.value = true;
getTableData()
}
defineExpose({
show
})
</script>
<style scoped lang="scss">
.tips {
color: var(--el-color-danger);
padding-bottom: 14px;
}
.pagination {
display: flex;
padding: 0 14px;
margin-top: 14px;
}
.dialog {
padding: 14px;
}
</style>

View File

@@ -2,7 +2,7 @@
<template> <template>
<div class="dialog"> <div class="dialog">
<el-dialog :title="`核销${props.title}团购券`" width="600" v-model="dialogVisible" @open="reset"> <el-dialog :title="`核销${props.title}团购券`" width="600" v-model="dialogVisible" @open="reset" @close="close">
<div class="content"> <div class="content">
<div class="left"> <div class="left">
<el-image :src="icon" style="width: 60px; height: 60px"></el-image> <el-image :src="icon" style="width: 60px; height: 60px"></el-image>
@@ -79,8 +79,7 @@
</template> </template>
</el-table-column> </el-table-column>
</el-table> </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-if="props.type == 2">
@selection-change="douyinSelectionChange">
<el-table-column type="selection" width="55" /> <el-table-column type="selection" width="55" />
<el-table-column label="名称" prop="title"></el-table-column> <el-table-column label="名称" prop="title"></el-table-column>
<el-table-column label="价格" prop="amount"></el-table-column> <el-table-column label="价格" prop="amount"></el-table-column>
@@ -93,6 +92,7 @@
@click="groupOrdergroupScanHandle">确认核销</el-button> @click="groupOrdergroupScanHandle">确认核销</el-button>
</div> </div>
</el-dialog> </el-dialog>
<BindShop ref="BindShopRef" @success="submitHandle()" />
</div> </div>
</template> </template>
@@ -102,6 +102,8 @@ import { ref } from "vue";
import icon from "@/assets/icon_scan.png"; import icon from "@/assets/icon_scan.png";
import { groupOrderorderInfo, groupOrdergroupScan, douyinfulfilmentcertificateprepare, douyincertificateprepare } from '@/api/group' import { groupOrderorderInfo, groupOrdergroupScan, douyinfulfilmentcertificateprepare, douyincertificateprepare } from '@/api/group'
import { useUser } from "@/store/user.js"; import { useUser } from "@/store/user.js";
import BindShop from './bindShop.vue'
const BindShopRef = ref(null)
const store = useUser(); const store = useUser();
import { import {
queryMembermember, queryMembermember,
@@ -110,6 +112,10 @@ import {
accountPaymember, accountPaymember,
} from "@/api/member/index.js"; } from "@/api/member/index.js";
import { ElMessage } from "element-plus"; import { ElMessage } from "element-plus";
import { useGlobal } from '@/store/global.js'
const global = useGlobal()
const emits = defineEmits(["success"]); const emits = defineEmits(["success"]);
const props = defineProps({ const props = defineProps({
@@ -152,7 +158,8 @@ async function groupOrdergroupScanHandle() {
case 2: case 2:
{ {
groupDetailLoading.value = true groupDetailLoading.value = true
let encrypted_codes = groupDetail.value.goods.map(item => item.encrypted_code) let encrypted_codes = douyin_table.value.getSelectionRows().map(item => item.encrypted_code)
console.log(encrypted_codes);
const res = await douyincertificateprepare({ const res = await douyincertificateprepare({
verify_token: groupDetail.value.verify_token, verify_token: groupDetail.value.verify_token,
encrypted_codes: encrypted_codes.join(','), encrypted_codes: encrypted_codes.join(','),
@@ -171,17 +178,12 @@ async function groupOrdergroupScanHandle() {
emits('succcess') emits('succcess')
} catch (error) { } catch (error) {
groupDetailLoading.value = false groupDetailLoading.value = false
console.log(error); console.log('groupOrdergroupScanHandle.error', error);
} }
} }
const douyin_table = ref(null) const douyin_table = ref(null)
// 选择要核销的券
function douyinSelectionChange(e) {
console.log(e);
}
// 核销券码 // 核销券码
async function submitHandle() { async function submitHandle() {
try { try {
@@ -202,6 +204,7 @@ async function submitHandle() {
const res = await douyinfulfilmentcertificateprepare({ const res = await douyinfulfilmentcertificateprepare({
object_id: decodeURI(scanCode.value), object_id: decodeURI(scanCode.value),
}); });
dialogVisible.value = false
loading.value = false loading.value = false
groupDetail.value = res groupDetail.value = res
detailVisible.value = true detailVisible.value = true
@@ -217,7 +220,10 @@ async function submitHandle() {
} }
} catch (error) { } catch (error) {
loading.value = false loading.value = false
console.log(error); console.log('submitHandle.error', error);
if (error.code == 4399) {
BindShopRef.value.show()
}
} }
} }
@@ -255,6 +261,7 @@ const inputChange = _.debounce(function (e) {
}, 500); }, 500);
function show() { function show() {
global.updateData(true)
dialogVisible.value = true; dialogVisible.value = true;
setTimeout(() => { setTimeout(() => {
inputRef.value.focus(); inputRef.value.focus();
@@ -262,6 +269,7 @@ function show() {
} }
function close() { function close() {
global.updateData(false)
dialogVisible.value = false; dialogVisible.value = false;
} }
@@ -274,6 +282,7 @@ defineExpose({
show, show,
close, close,
loading, loading,
submitHandle
}); });
</script> </script>

View File

@@ -3,7 +3,7 @@
<div class="cart_wrap card"> <div class="cart_wrap card">
<div class="header"> <div class="header">
<div class="left"> <div class="left">
<el-select v-model="tableData.type" placeholder="核销类型"> <el-select v-model="tableData.type" placeholder="核销类型" @change="typeChange">
<el-option v-for="item in typeList" :key="item.value" :value="item.value" <el-option v-for="item in typeList" :key="item.value" :value="item.value"
:label="item.label"></el-option> :label="item.label"></el-option>
</el-select> </el-select>
@@ -79,14 +79,16 @@
<template v-slot="scope"> <template v-slot="scope">
<div class="goods_list"> <div class="goods_list">
<div class="row" v-for="item in scope.row.douyinCodeGoods" :key="item.id"> <div class="row" v-for="item in scope.row.douyinCodeGoods" :key="item.id">
<div class="item" style="flex: 1;white-space: nowrap;margin-right: 10px;"> <div class="item" style="width: 240px;">
{{ item.title }} {{ item.title }}
</div> </div>
<div class="item" style="flex: 1;margin-right: 10px;color: var(--primary-color);"> <div class="item" style="width: 100px;color: var(--primary-color);">
{{ item.pay_amount }} {{ item.pay_amount }}
</div> </div>
<div class="item" style="margin-right: 10px;"> <div class="item"
<el-tag type="success" disable-transitions size="default" effect="light" round> style="margin-right: 10px;display: flex;justify-content: flex-end;">
<el-tag :type="typeStatus(item.status)" disable-transitions size="default"
effect="light" round>
{{ item.status_text }} {{ item.status_text }}
</el-tag> </el-tag>
</div> </div>
@@ -102,8 +104,7 @@
</div> </div>
<div class="pagination"> <div class="pagination">
<el-pagination @current-change="paginationChange" :current-page="tableData.page" <el-pagination @current-change="paginationChange" :current-page="tableData.page"
:page-size="tableData.size" layout="total, prev, pager, next, jumper" :total="tableData.total" :page-size="tableData.size" layout="total, prev, pager, next" :total="tableData.total" background>
background>
</el-pagination> </el-pagination>
</div> </div>
</div> </div>
@@ -121,6 +122,7 @@ import { ref, onMounted, reactive } from 'vue'
import scanGroup from './components/scanGroup.vue' import scanGroup from './components/scanGroup.vue'
import refundDialog from './components/refundDialog.vue' import refundDialog from './components/refundDialog.vue'
import { useUser } from "@/store/user.js" import { useUser } from "@/store/user.js"
import BindShop from './components/bindShop.vue'
const store = useUser() const store = useUser()
import { useGlobal } from '@/store/global.js' import { useGlobal } from '@/store/global.js'
@@ -129,10 +131,19 @@ const global = useGlobal()
const scanGroupRef = ref(null) const scanGroupRef = ref(null)
const refundDialogRef = ref(null) const refundDialogRef = ref(null)
function typeStatus(t) {
const m = {
0: 'warning',
1: 'success',
2: 'danger'
}
return m[t]
}
const tableData = reactive({ const tableData = reactive({
resetLoading: false, resetLoading: false,
proName: '', proName: '',
type: 1, type: 2,
status: '', status: '',
loading: false, loading: false,
list: [], list: [],
@@ -162,7 +173,8 @@ const typeList = reactive([
} }
]) ])
const statusList = reactive([ // 本店团购订单状态
const originStatus = [
{ {
value: 'unpaid', value: 'unpaid',
label: '待付款' label: '待付款'
@@ -187,7 +199,39 @@ const statusList = reactive([
value: 'cancelled', value: 'cancelled',
label: '已取消' label: '已取消'
} }
]) ]
// 抖音美团
const dmStatus = [
{
value: 0,
label: '等待验券'
},
{
value: 1,
label: '成功'
},
{
value: 2,
label: '失败'
}
]
const statusList = ref([])
// 切换筛选条件
function typeChange(e) {
switch (e) {
case 1:
statusList.value = [...originStatus]
break;
case 2:
statusList.value = [...dmStatus]
break;
default:
break;
}
}
// 状态 // 状态
function statusFilter(t) { function statusFilter(t) {
@@ -243,7 +287,9 @@ async function groupOrderlistAjax() {
case 2: case 2:
// 获取抖音团购数据 // 获取抖音团购数据
res = await douyinorderlist({ res = await douyinorderlist({
page: tableData.page page: tableData.page,
status: tableData.status,
d_order_id: tableData.proName
}) })
tableData.resetLoading = false tableData.resetLoading = false
tableData.loading = false tableData.loading = false
@@ -260,6 +306,7 @@ async function groupOrderlistAjax() {
} }
onMounted(() => { onMounted(() => {
typeChange(tableData.type)
groupOrderlistAjax() groupOrderlistAjax()
}) })
</script> </script>

View File

@@ -22,7 +22,16 @@
<el-input v-model="form.loginName" placeholder="请输入11位手机号码"></el-input> <el-input v-model="form.loginName" placeholder="请输入11位手机号码"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="登录密码" prop="password"> <el-form-item label="登录密码" prop="password">
<el-input v-model="form.password" type="password" placeholder="请输入登录密码"></el-input> <el-input v-model="form.password" :type="passwordType" placeholder="请输入登录密码">
<template #suffix>
<el-icon class="el-input__icon" v-if="passwordType == 'password'" @click="passwordType = 'text'">
<Hide />
</el-icon>
<el-icon class="el-input__icon" v-else @click="passwordType = 'password'">
<View />
</el-icon>
</template>
</el-input>
</el-form-item> </el-form-item>
<!-- <el-form-item> <!-- <el-form-item>
<div style="width: 100%; display: flex; justify-content: flex-end"> <div style="width: 100%; display: flex; justify-content: flex-end">
@@ -54,7 +63,8 @@
import packageData from "../../package.json"; import packageData from "../../package.json";
import logo from "@/assets/logo.png"; import logo from "@/assets/logo.png";
import { ElMessage, ElMessageBox } from "element-plus"; import { ElMessage, ElMessageBox } from "element-plus";
import { reactive, ref } from "vue"; import { Hide, View } from '@element-plus/icons-vue'
import { onMounted, reactive, ref } from "vue";
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
import { ipcRenderer } from "electron"; import { ipcRenderer } from "electron";
import { RandomNumBoth } from "@/utils"; import { RandomNumBoth } from "@/utils";
@@ -69,6 +79,7 @@ const socket = useSocket();
const router = useRouter(); const router = useRouter();
const formRef = ref(null); const formRef = ref(null);
const loading = ref(false); const loading = ref(false);
const passwordType = ref('password')
const form = reactive({ const form = reactive({
serialNumber: RandomNumBoth(1000, 9999), serialNumber: RandomNumBoth(1000, 9999),
@@ -110,12 +121,6 @@ const submitHandle = () => {
store store
.userlogin(form) .userlogin(form)
.then(async (res) => { .then(async (res) => {
// const douyin = await douyincheckIn({
// token: res.token,
// loginName: res.loginName,
// clientType: 'pc'
// })
// useStorage.set('douyin', douyin.userInfo)
ElMessage.success("登录成功"); ElMessage.success("登录成功");
socket.init(); socket.init();
setTimeout(() => { setTimeout(() => {
@@ -123,6 +128,12 @@ const submitHandle = () => {
name: "home", name: "home",
}); });
}, 1000); }, 1000);
const douyin = await douyincheckIn({
token: res.token,
loginName: res.loginName,
clientType: 'pc'
})
useStorage.set('douyin', douyin.userInfo)
}) })
.catch((err) => { .catch((err) => {
loading.value = false; loading.value = false;
@@ -138,6 +149,10 @@ const logout = () => {
}) })
.catch(() => { }); .catch(() => { });
}; };
onMounted(() => {
passwordType.icon = Hide
})
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">

View File

@@ -215,6 +215,7 @@ const exit = async () => {
// useStorage.clear() // useStorage.clear()
useStorage.del('userInfo') useStorage.del('userInfo')
useStorage.del('token') useStorage.del('token')
useStorage.del('douyin')
ElMessage.success("交班成功"); ElMessage.success("交班成功");
setTimeout(() => { setTimeout(() => {
router.replace({ router.replace({

View File

@@ -34,5 +34,8 @@ export default defineConfig(({ command, mode }) => {
"@": path.resolve(__dirname, "./src"), "@": path.resolve(__dirname, "./src"),
}, },
}, },
esbuild: {
drop: ["console"],
},
}; };
}); });