add(桌台统计,点歌)

This commit is contained in:
YeMingfei666 2024-07-08 10:28:37 +08:00
parent addb27be82
commit c4059d109c
7 changed files with 754 additions and 2 deletions

View File

@ -0,0 +1,54 @@
import request from "@/utils/request";
/**
* 查询歌曲列表
* @returns
*/
export function tbShopSonglist(params) {
return request({
url: "/api/tbShopSong",
method: "get",
params: {
shopId: localStorage.getItem("shopId"),
...params
}
});
}
/**
* 新增歌曲
* @returns
*/
export function tbShopSongAdd(data) {
return request({
url: "/api/tbShopSong",
method: "post",
data: {
shopId: localStorage.getItem("shopId"),
...data
}
});
}
/**
* 修改歌曲
* @returns
*/
export function tbShopSongEdit(data) {
return request({
url: "/api/tbShopSong",
method: "put",
data
});
}
/**
* 删除歌曲
* @returns
*/
export function tbShopSongDel(ids) {
return request({
url: 'api/tbProduct/',
method: 'delete',
data: ids
})
}

View File

@ -85,3 +85,36 @@ export function downloadTableCode(data) {
responseType: "blob"
});
}
/**
* 桌台统计
* @returns
*/
export function summaryTable(params) {
return request({
url: `/api/summary/table`,
method: "get",
params:{
shopId: localStorage.getItem("shopId"),
...params
}
});
}
/**
* 桌台统计导出文档
* @returns
*/
export function summaryTableDownload(data) {
return request({
url: `/api/summary/table/download`,
method: "POST",
data:{
shopId: localStorage.getItem("shopId"),
...data
},
responseType: 'blob'
});
}

View File

@ -52,6 +52,12 @@ export const constantRouterMap = [
component: (resolve) => require(['@/views/home/data_forms'], resolve),
name: 'data_forms',
meta: { title: '数据报表' }
},
{
path: 'data_tables',
component: (resolve) => require(['@/views/home/data_tables'], resolve),
name: 'data_tables',
meta: { title: '桌台统计' }
}
]
},

View File

@ -0,0 +1,139 @@
<template>
<div class="app-container">
<div class="head-container">
<el-button type="primary" icon="el-icon-plus" @click="$refs.addSong.show()">
添加歌曲
</el-button>
</div>
<div class="head-container" id="table_drag">
<el-table :data="tableData.list" v-loading="tableData.loading" row-key="id">
<el-table-column label="排序" sortable prop="sort"></el-table-column>
<el-table-column label="id" prop="id"></el-table-column>
<el-table-column label="歌曲图片" prop="img">
<template v-slot="scope">
<el-image :src="scope.row.img"
style="width:40px;height: 40px;border-radius: 4px;background-color: #efefef;">
<div class="img_error" slot="error">
<i class="icon el-icon-document-delete"></i>
</div>
</el-image>
</template>
</el-table-column>
<el-table-column label="歌曲名称" prop="name"></el-table-column>
<el-table-column label="演出歌手" prop="singer"></el-table-column>
<el-table-column label="单价" prop="price"></el-table-column>
<el-table-column label="点唱次数" prop="salesNumber"></el-table-column>
<el-table-column label="歌曲状态" prop="status">
<template v-slot="scope">
<el-switch v-model="scope.row.status" :active-value="1" :inactive-value="0"
@change="showChange($event, scope.row)"></el-switch>
</template>
</el-table-column>
<el-table-column label="操作" width="240">
<template v-slot="scope">
<!-- <el-button type="text" icon="el-icon-rank" v-if="isPcBowser">排序</el-button>
<el-button type="text" size="mini" round icon="el-icon-edit" @click="$refs.addSong.show(scope.row)"
style="margin-left: 20px !important;">编辑</el-button> -->
<el-button type="text" size="mini" round icon="el-icon-edit" @click="$refs.addSong.show(scope.row)">编辑</el-button>
<el-popconfirm title="确定删除吗?" @confirm="delHandle([scope.row.id])">
<el-button type="text" size="mini" round icon="el-icon-delete" slot="reference">
删除
</el-button>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
</div>
<addSong ref="addSong" @success="addSongSuccess"></addSong>
<el-pagination @size-change="paginationSizeChange" :total="tableData.total" :current-page="tableData.page + 1" :page-size="tableData.size"
@current-change="paginationChange" layout="total, sizes, prev, pager, next, jumper"></el-pagination>
</div>
</template>
<script>
import Sortable from 'sortablejs'
import {
tbShopSonglist,tbShopSongDel,tbShopSongEdit
} from '@/api/application-song'
import addSong from './componentsCompoents/add-song.vue'
export default {
components: {
addSong
},
data() {
return {
tableData: {
page: 0,
size: 10,
total: 0,
loading: false,
list: []
}
}
},
mounted() {
this.getTableData()
},
methods: {
addSongSuccess() {
this.getTableData()
},
paginationSizeChange(e){
this.tableData.size = e
this.getTableData()
},
async showChange(e,row){
try {
this.tableData.loading = true
const data = { ...row }
data.status = e
await tbShopSongEdit(data, 'put')
this.getTableData()
} catch (error) {
console.log(error)
this.tableData.loading = false
}
},
//
resetHandle() {
this.tableData.page = 0;
this.getTableData()
},
//
paginationChange(e) {
this.tableData.page = e - 1
this.getTableData()
},
//
async delHandle(ids) {
try {
await tbShopSongDel(ids)
this.$notify({
title: '成功',
message: `删除成功`,
type: 'success'
});
this.getTableData()
} catch (error) {
console.log(error)
}
},
//
async getTableData() {
try {
this.tableData.loading = true
const res = await tbShopSonglist({
page: this.tableData.page+1,
size: this.tableData.size,
sort: 'id',
shopId: localStorage.getItem('shopId')
})
this.tableData.loading = false
this.tableData.list = res.content
this.tableData.total = res.totalElements
} catch (error) {}
}
}
}
</script>

View File

@ -0,0 +1,161 @@
<template>
<el-dialog :title="title" width="500px" :visible.sync="dialogVisible">
<el-form ref="form" :model="form" :rules="rules" label-width="120px" label-position="left">
<el-form-item label="商品图片">
<uploadImg ref="uploadImg" :limit="1" @success="uploadSuccess" @remove="uploadRemove" />
<div class="tips">第一张图为商品封面图图片尺寸为750×750</div>
</el-form-item>
<el-form-item label="歌曲名称" prop="name">
<el-input v-model="form.name"></el-input>
</el-form-item>
<el-form-item label="原唱歌手">
<el-input v-model="form.originSinger"></el-input>
</el-form-item>
<el-form-item label="演出歌手名称" prop="singer">
<el-input v-model="form.singer"></el-input>
</el-form-item>
<el-form-item label="单价" prop="price">
<el-input type="number" v-model="form.price"></el-input>
</el-form-item>
<el-form-item label="排序" prop="sort">
<el-input type="number" v-model="form.sort"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false"> </el-button>
<el-button type="primary" @click="onSubmitHandle"> </el-button>
</span>
</el-dialog>
</template>
<script>
import uploadImg from '@/components/uploadImg'
import {
tbShopSongAdd,tbShopSongEdit
} from '@/api/application-song'
export default {
components: {
uploadImg
},
data() {
return {
title: '新增歌曲',
dialogVisible: false,
rules: {
name: [{
required: true,
message: '歌曲名称必填',
trigger: 'blur'
}],
singer: [{
required: true,
message: '演出歌手名称必填',
trigger: 'blur'
}],
price: [{
required: true,
message: '单价必填',
trigger: 'blur'
}],
sort: [{
required: true,
message: '排序必填',
trigger: 'blur'
}]
},
form: {
img: '',
name: '',
singer: '',
originSinger: '',
price: 0,
sort: 0
}
}
},
mounted() {
console.log(this.form);
},
methods: {
uploadSuccess(res) {
this.form.img = res[0]
console.log(this.form.img);
},
uploadRemove() {
this.form.img = ''
},
//
onSubmitHandle() {
console.log(this.form)
this.$refs.form.validate(async valid => {
if (valid) {
try {
let res = ''
if (this.form.id) { //
res = await tbShopSongEdit(this.form)
this.$notify({
title: '成功',
message: `修改成功`,
type: 'success'
});
} else {
//
res = await tbShopSongAdd(this.form)
this.$notify({
title: '成功',
message: `添加成功`,
type: 'success'
});
}
this.$emit('success', res)
this.close()
} catch (error) {
console.log(error)
}
}
})
},
async show(obj = {}, wine = false) {
console.log(obj);
this.dialogVisible = true
if (obj && obj.id) {
this.form = {
...obj
}
}
if (obj && obj.img) {
this.form.img = obj.img
requestAnimationFrame(()=>{
this.$refs.uploadImg.fileList = [{
url: obj.img
}]
})
}
},
close() {
this.dialogVisible = false
},
reset() {
this.form = {
...this.resetForm
}
}
}
}
</script>
<style scoped lang="scss">
.goods_info {
background-color: #f9f9f9;
padding: 10px;
display: flex;
align-items: center;
.info {
flex: 1;
padding-left: 10px;
}
}
</style>

View File

@ -0,0 +1,358 @@
<template>
<div class="app-container">
<!-- <el-tabs v-model="orderType" @tab-click="getTableData">
<el-tab-pane label="收款" name="1"></el-tab-pane>
<el-tab-pane label="销量" name="2"></el-tab-pane>
</el-tabs> -->
<div class="head-container">
<el-form :model="query" inline label-position="left">
<el-radio-group v-model="timeValue" @change="timeChange">
<el-radio-button label="">全部</el-radio-button>
<el-radio-button label="0">今天</el-radio-button>
<el-radio-button label="-1">昨天</el-radio-button>
<el-radio-button label="-7">最近7天</el-radio-button>
<el-radio-button label="-30">最近30天</el-radio-button>
<el-radio-button label="week">本周</el-radio-button>
<el-radio-button label="month">本月</el-radio-button>
<el-radio-button label="custom">自定义</el-radio-button>
</el-radio-group>
<el-date-picker v-model="query.createdAt" type="daterange" range-separator="" start-placeholder="开始日期"
end-placeholder="结束日期" :default-time="['00:00:00', '23:59:59']" value-format="yyyy-MM-dd HH:mm:ss"
>
</el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="getTableData">查询</el-button>
<el-button @click="resetHandle">重置</el-button>
<el-button icon="el-icon-download" v-loading="downloadLoading" @click="downloadHandle">
<span v-if="!downloadLoading">导出Excel</span>
<span v-else>下载中...</span>
</el-button>
</el-form-item>
</el-form>
</div>
<!-- <div class="head-container">
<div class="collect_wrap">
<div class="item" v-for="item in payCountList" :key="item.id">
<div class="icon_wrap" style="--bg-color:#C978EE">
<i class="icon" :class="item.icon"></i>
</div>
<div class="info">
<div class="m">
<template v-if="item.isAmount == 1"></template>
{{ item.payAmount }}
</div>
<div class="t">{{ item.payType }}</div>
</div>
</div>
</div>
</div> -->
<div class="head-container">
<el-table :data="tableData.data" v-loading="tableData.loading" v-if="orderType == 1">
<el-table-column label="ID" prop="id"></el-table-column>
<el-table-column label="区域id" prop="areaId"></el-table-column>
<el-table-column label="区域名称" prop="areaName"></el-table-column>
<el-table-column label="门店id" prop="shopId"></el-table-column>
<el-table-column label="台桌id" prop="tableId"></el-table-column>
<el-table-column label="订单金额" prop="orderAmount"></el-table-column>
<el-table-column label="订单数量" prop="orderCount"></el-table-column>
</el-table>
<!-- <el-table :data="tableData.data" v-loading="tableData.loading" v-if="orderType == 2">
<el-table-column label="商品名称" prop="productName"></el-table-column>
<el-table-column label="商品分类" prop="cateName"></el-table-column>
<el-table-column label="商品描述" prop="productSkuName"></el-table-column>
<el-table-column label="销量" prop="salesNum"></el-table-column>
<el-table-column label="退单量" prop="refNum"></el-table-column>
<el-table-column label="销售金额" prop="salesAmount">
<template v-slot="scope">
{{ scope.row.salesAmount }}
</template>
</el-table-column>
<el-table-column label="退款金额" prop="refAmount">
<template v-slot="scope">
{{ scope.row.refAmount }}
</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"
@current-change="paginationChange" @size-change="sizeChange"
layout="total, sizes, prev, pager, next, jumper"></el-pagination>
</div>
</div>
</template>
<script>
import { summaryTable,summaryTableDownload } from '@/api/table'
import dayjs from "dayjs";
import { downloadFile } from "@/utils/index";
export default {
data() {
return {
timeValue: "",
resetQuery: null,
orderType: "1",
categorys: [],
query: {
createdAt: [],
proName: '',
cateId: ''
},
tableData: {
data: [],
page: 0,
size: 10,
loading: false,
total: 0
},
downloadLoading: false,
payCountList: "",
payCountTotal: 0
};
},
filters: {
timeFilter(time) {
return dayjs(time).format("YYYY-MM-DD HH:mm:ss");
}
},
mounted() {
this.resetQuery = { ...this.query };
this.getTableData();
},
methods: {
// Excel
async downloadHandle() {
try {
this.downloadLoading = true;
const file = await summaryTableDownload({
startTime: this.query.createdAt[0],
endTime: this.query.createdAt[1],
});
downloadFile(file, "数据", "xlsx");
this.downloadLoading = false;
} catch (error) {
this.downloadLoading = false;
console.log(error);
}
},
//
resetHandle() {
this.timeValue = "";
this.query = { ...this.resetQuery };
this.page = 0;
this.getTableData();
},
//
sizeChange(e) {
this.tableData.size = e;
this.getTableData();
},
//
paginationChange(e) {
this.tableData.page = e - 1;
this.getTableData();
},
async getTableData() {
this.tableData.loading = true;
try {
const res = await summaryTable({
page: this.tableData.page+1,
size: this.tableData.size,
startTime:this.query.createdAt[0],
endTime:this.query.createdAt[1]
});
this.tableData.loading = false;
this.tableData.data = res;
this.tableData.total = res.length;
} catch (error) {
console.log(error);
}
},
//
timeChange(e) {
const format = ["YYYY-MM-DD 00:00:00", "YYYY-MM-DD 23:59:59"];
switch (e) {
case "":
//
this.query.createdAt = [];
break;
case "0":
//
this.query.createdAt = [
dayjs().format(format[0]),
dayjs().format(format[1])
];
break;
case "-1":
//
this.query.createdAt = [
dayjs()
.add(-1, "d")
.format(format[0]),
dayjs()
.add(-1, "d")
.format(format[1])
];
break;
case "-7":
// 7
this.query.createdAt = [
dayjs()
.add(-7, "d")
.format(format[0]),
dayjs().format(format[1])
];
break;
case "-30":
// 7
this.query.createdAt = [
dayjs()
.add(-30, "d")
.format(format[0]),
dayjs().format(format[1])
];
break;
case "week":
//
this.query.createdAt = [
dayjs()
.startOf("week")
.format(format[0]),
dayjs()
.endOf("week")
.format(format[1])
];
break;
case "month":
//
this.query.createdAt = [
dayjs()
.startOf("month")
.format(format[0]),
dayjs()
.endOf("month")
.format(format[1])
];
break;
case "custom":
//
this.query.createdAt = [];
break;
default:
break;
}
}
}
};
</script>
<style scoped lang="scss">
.collect_wrap {
display: flex;
gap: 14px;
.item {
flex: 1;
display: flex;
align-items: center;
background-color: #f5f5f5;
padding: 20px;
.icon_wrap {
$size: 34px;
$border: 6px;
width: $size;
height: $size;
display: flex;
align-items: center;
justify-content: center;
background-color: var(--bg-color);
border-radius: 50%;
position: relative;
&::after {
content: "";
width: $size + $border;
height: $size + $border;
border-radius: 50%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: var(--bg-color);
opacity: 0.3;
}
.icon {
font-size: 16px;
color: #fff;
}
.img {
width: 20px;
height: 20px;
}
}
.info {
flex: 1;
display: flex;
flex-direction: column;
padding-left: 10px;
.m {
font-weight: bold;
}
.t {
font-size: 12px;
color: #999;
padding-top: 4px;
}
}
}
}
.refund {
color: #ff9731;
font-weight: bold;
}
.table_order_info {
.order_no {
color: #999;
}
.type {
color: #e6a23c;
}
}
.goods_info {
.row {
display: flex;
&:not(:first-child) {
margin-top: 10px;
}
.cover {
width: 40px;
height: 40px;
}
.info {
flex: 1;
display: flex;
flex-direction: column;
padding-left: 10px;
.sku {
color: #999;
}
}
}
}
</style>

View File

@ -51,7 +51,7 @@
{{ `${scope.row.number} ${scope.row.unitName}` }}
</template>
</el-table-column>
<el-table-column label="库存开关">
<template v-slot="scope">
<el-switch v-model="scope.row.isStock" :active-value="1" :inactive-value="0"
@ -178,6 +178,7 @@ export default {
paginationSizeChange(e){
console.log(e);
this.tableData.size = e
this.getTableData()
},
//
paginationChange(e) {
@ -227,4 +228,4 @@ export default {
gap: 10px;
}
}
</style>
</style>