修复打包失败报错问题,修复菜单管理页面ts类型问题

This commit is contained in:
YeMingfei666 2025-02-24 11:37:27 +08:00
parent 59e1995253
commit 220332c0e5
16 changed files with 152 additions and 17796 deletions

View File

@ -1,13 +1,13 @@
# 代理前缀
VITE_APP_BASE_API = '/prod-api'
# WebSocket端点(可选)
#VITE_APP_WS_ENDPOINT=wss://api.youlai.tech/ws
# 接口地址
VITE_APP_BASE_API = 'https://tapi.cashier.sxczgkj.cn/'
VITE_APP_API_URL=https://tapi.cashier.sxczgkj.cn/ # 正式
# WebSocket 端点(不配置则关闭),线上 ws://api.youlai.tech/ws ,本地 ws://localhost:8989/ws

View File

@ -18,7 +18,7 @@ const MenuApi = {
});
},
get(id: string) {
return request<any, MenuVO>({
return request<any, SysMenu>({
url: `${baseURL}/detail`,
method: "get",
params: { id }
@ -103,101 +103,59 @@ export interface addRequest {
/**
*
*/
activeMenu?: string;
activeMenu?: null | string;
/**
*
*/
cache?: number;
cache: number | string;
/**
*
*/
component?: string;
component: number | string;
/**
*
*/
hidden?: number;
hidden: number | string;
/**
*
*/
icon?: string;
icon: string;
/**
*
*/
iFrame?: number;
iFrame: number | string;
/**
*
*/
menuSort?: number;
menuSort: number;
/**
*
*/
name: string;
/**
*
*/
path?: string;
path: number | string;
/**
*
*/
permission?: string;
permission?: null | string;
/**
*
*/
pid?: number;
title: string;
pid?: number | string;
title: string | string;
/**
* 0 1 2
*/
type: number | null;
type: number | string;
[property: string]: any;
}
/**
* MenuEditDTO
*/
export interface editRequest {
/**
* 0 1 2
*/
type: number;
/**
*
*/
activeMenu?: string;
/**
*
*/
cache?: number;
/**
*
*/
component?: string;
/**
*
*/
hidden?: number;
/**
*
*/
icon?: string;
export interface editRequest extends addRequest {
id: number | string;
/**
*
*/
iFrame?: number;
/**
*
*/
menuSort?: number;
/**
*
*/
path?: string;
/**
*
*/
permission?: string;
/**
*
*/
pid: number | string | null;
title: string;
[property: string]: any;
}
/**
@ -305,4 +263,94 @@ export interface MenuVO {
*/
updateTime?: string;
[property: string]: any;
}
/**
*
*
* CzgResult«SysMenu»
*/
export interface SysMenu {
/**
*
*/
activeMenu?: null | string;
/**
*
*/
cache?: boolean | null;
/**
*
*/
component?: null | string;
/**
*
*/
createBy?: null | string;
/**
*
*/
createTime?: null | string;
/**
*
*/
hidden?: boolean | null;
/**
*
*/
icon?: null | string;
/**
*
*/
iFrame?: boolean | null;
/**
* 使 01
*/
isShop?: number | null;
/**
* ID
*/
menuId?: number | null;
/**
*
*/
menuSort?: number | null;
/**
*
*/
name?: null | string;
/**
*
*/
path?: null | string;
/**
*
*/
permission?: null | string;
/**
* ID
*/
pid?: number | null;
/**
*
*/
subCount?: number | null;
/**
*
*/
title?: null | string;
/**
* 0 1 3
*/
type?: number | null;
/**
*
*/
updateBy?: null | string;
/**
*
*/
updateTime?: null | string;
[property: string]: any;
}

View File

@ -54,8 +54,8 @@ export const useUserStore = defineStore("user", () => {
}
localStorage.setItem("shopId", "" + userInfo.value.shopId);
console.log("获取用户信息", data);
Object.assign(userInfo.value, { ...data });
resolve(data);
Object.assign(userInfo.value, { ...data, roles: [], promissionList: [], shopId: userInfo.value.shopId });
resolve(userInfo.value);
})
.catch((error) => {
reject(error);

View File

@ -162,9 +162,14 @@
<el-radio :value="2">接口</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item v-if="formData.iFrame == 1" label="外链地址" prop="path">
<el-input v-model="formData.path" placeholder="请输入外链完整路径" />
<el-form-item label="是否外链" prop="path">
<el-switch
v-model="formData.iFrame"
:active-value="1"
:inactive-value="0"
active-text="是"
inactive-text="否"
/>
</el-form-item>
<el-form-item v-if="formData.type == MenuTypeEnum.MENU" prop="name">
@ -237,8 +242,8 @@
<el-form-item v-if="formData.type === MenuTypeEnum.MENU" label="缓存页面">
<el-radio-group v-model="formData.cache">
<el-radio :value="1">开启</el-radio>
<el-radio :value="0">关闭</el-radio>
<el-radio :value="true">开启</el-radio>
<el-radio :value="false">关闭</el-radio>
</el-radio-group>
</el-form-item>
@ -265,9 +270,9 @@
<icon-select v-model="formData.icon" />
</el-form-item>
<el-form-item v-if="formData.type == MenuTypeEnum.MENU" label="跳转路由">
<!-- <el-form-item v-if="formData.type == MenuTypeEnum.MENU" label="跳转路由">
<el-input v-model="formData.redirect" placeholder="跳转路由" />
</el-form-item>
</el-form-item> -->
</el-form>
<template #footer>
@ -286,7 +291,7 @@ defineOptions({
inheritAttrs: false,
});
import MenuAPI, { getListRequest, editRequest, addRequest, MenuVO } from "@/api/account/menu";
import MenuAPI, { getListRequest, MenuVO, editRequest } from "@/api/account/menu";
import { MenuTypeEnum } from "@/enums/MenuTypeEnum";
const queryFormRef = ref();
@ -305,21 +310,22 @@ const menuTableData = ref<MenuVO[]>([]);
//
const menuOptions = ref<OptionType[]>([]);
//
{
}
const initialeditRequestData = ref<editRequest>({
id: "",
pid: "",
pid: "0",
hidden: 0,
menuSort: 1,
type: 0, //
alwaysShow: 0,
cache: 1,
params: [],
alwaysShow: false,
cache: 0,
title: "",
icon: "",
iFrame: 0,
permission: "",
path: "",
component: "",
name: "",
});
//
const formData = ref({ ...initialeditRequestData.value });
@ -393,19 +399,26 @@ function handleOpenDialog(pid?: string, menuId?: string) {
dialog.title = "编辑菜单";
MenuAPI.get(menuId).then((data) => {
console.log(data);
initialeditRequestData.value = {
...data,
};
data.iFrame;
formData.value = {
...data,
id: data.id || "",
pid: data.pid || "0",
cache: data.cache ? 1 : 0,
hidden: data.hidden ? 1 : 0,
pid: !pid ? "0" : data.pid,
component: data.component || "",
icon: data.icon || "",
iFrame: data.iFrame ? 1 : 0,
menuSort: data.menuSort ?? 0, // Ensure menuSort is always a number
name: data.name || "", // Ensure name is always a string
path: data.path || "", // Ensure path is always a string
title: data.title || "", // Ensure title is always a string
type: data.type ?? 0, // Ensure type is always a number
};
});
} else {
dialog.title = "新增菜单";
formData.value.pid = pid?.toString();
formData.value.pid = pid ? pid : "0";
}
});
}
@ -438,7 +451,7 @@ function handleSubmit() {
...formData.value,
cache: formData.value.cache ? 1 : 0,
hidden: formData.value.hidden ? 1 : 0,
pid: formData.value.pid == 0 ? null : formData.value.pid,
pid: formData.value.pid == 0 ? undefined : String(formData.value.pid),
};
if (menuId) {
//
@ -496,17 +509,19 @@ function resetForm() {
editRequestRef.value.clearValidate();
formData.value = {
id: "",
pid: "",
pid: "0",
hidden: 0,
menuSort: 1,
type: 0, //
alwaysShow: 0,
cache: 1,
params: [],
alwaysShow: false,
cache: 0,
title: "",
icon: "",
iFrame: 0,
permission: "",
path: "",
component: "",
name: "",
};
}

View File

@ -1,270 +0,0 @@
<template>
<div class="select_desk">
<el-dialog width="410px" title="就餐人数" :visible.sync="show">
<div class="select_desk_dialog u-p-b-20">
<key-board
isCanEmpty
v-model="number"
@clear="clear"
:max="max"
:maxTips=" '最多'+max+'位'"
>
<div slot="clear">清空</div>
<div slot="input" class="u-p-l-20 u-p-r-20 u-flex w-full">
<el-input
placeholder="请输入就餐人数"
v-model="number"
@input="inputNumber"
@change="inputChange"
type="number"
>
<template slot="append"></template>
</el-input>
</div>
</key-board>
<div class="confirm_btns">
<el-button size="medium" @click="close">取消</el-button>
<el-button type="primary" size="medium" @click="confirm"
>确定</el-button
>
</div>
</div>
</el-dialog>
</div>
</template>
<script>
import keyBoard from "../keyboard.vue";
export default {
components: { keyBoard },
props:{
max:{
type:Number,
default:99
}
},
data() {
return {
number: "",
show: false,
hasOpen: false,
loading: false,
};
},
watch: {
number(newval) {
if (newval >this.max) {
this.number = this.max;
this.$message("最多只能选择"+this.max+"位就餐人数");
}
// 使
const regex = /^[1-9]\d*$/;
//
if (!regex.test(newval)) {
this.number = newval.substring(0, newval.length - 1);
}
},
},
methods: {
inputNumber(e) {},
inputChange(e) {},
clear(e) {
console.log(e);
this.number = "";
},
confirm() {
if (this.number >this.max) {
return this.$message("最多只能选择"+this.max+"位就餐人数");
}
if (!this.number) {
return this.$message("请选择就餐人数");
}
console.log(this.number)
this.$emit("confirm", this.number);
this.close();
},
open(number) {
this.number = number || "";
this.show = true;
},
close() {
this.show = false;
this.number = "";
},
},
mounted() {},
};
</script>
<style lang="scss" scoped>
::v-deep.el-button {
padding: 12px 20px;
}
::v-deep .el-input__inner::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
::v-deep .el-input__inner::-webkit-outer-spin-button {
-webkit-appearance: none;
margin: 0;
}
::v-deep .el-button--success {
border-color: #22bf64;
background-color: #22bf64;
}
.select_desk .btn {
height: 34px;
}
.tags {
font-size: 16px;
&.using {
color: rgb(234, 64, 37);
}
&.wait {
color: rgb(252, 236, 79);
}
&.idle {
color: rgb(137, 234, 71);
}
&.closed {
color: rgb(221, 221, 221);
filter: grayscale(1);
}
}
::v-deep .inputs .el-input__inner {
border-color: transparent !important;
color: rgba(0, 0, 0, 0.8);
letter-spacing: 1.25px;
font-size: 20px;
}
.select_desk .select_desk_dialog {
display: flex;
flex-direction: column;
align-items: center;
}
.select_desk .select_desk_dialog .nav {
width: 286px;
height: 38px;
background: #dcf0e8;
justify-content: space-around;
}
.select_desk .select_desk_dialog .nav .li,
.select_desk .select_desk_dialog .nav {
border-radius: 4px;
display: flex;
align-items: center;
}
.select_desk .select_desk_dialog .nav .li {
width: 140px;
height: 34px;
color: #0fc161;
justify-content: center;
font-size: 14px;
cursor: pointer;
}
.select_desk .select_desk_dialog .nav .lion {
background: #0fc161;
color: #fff;
}
.select_desk .select_desk_dialog .inputs {
width: 370px;
line-height: 54px;
margin-top: 24px;
height: 54px;
margin-bottom: 20px;
background: #fff;
border: 1px solid #dcdfe6;
border-radius: 4px;
color: rgba(0, 0, 0, 0.8);
letter-spacing: 1.25px;
text-align: center;
font-size: 20px;
position: relative;
}
.select_desk .select_desk_dialog .inputs .close {
color: #aaa;
position: absolute;
right: 10px;
height: 30px;
width: 30px;
line-height: 30px;
top: 50%;
margin-top: -15px;
cursor: pointer;
}
.select_desk .select_desk_dialog .keyboard {
display: flex;
flex-wrap: wrap;
width: 100%;
margin-top: 20px;
margin-bottom: 10px;
border-right: 1px solid #dcdfe6;
border-bottom: 1px solid #dcdfe6;
}
.select_desk .select_desk_dialog .keyboard .li {
height: 60px;
width: 33.333%;
display: flex;
justify-content: center;
align-items: center;
font-size: 24px;
color: #212121;
cursor: pointer;
user-select: none;
border-left: 1px solid #dcdfe6;
border-top: 1px solid #dcdfe6;
transition: all 0.1s;
}
.select_desk .select_desk_dialog .keyboard .li:hover {
background: #dcdfe6;
}
.select_desk .select_desk_dialog .keyboard .li .icon {
font-size: 1.3em;
}
.select_desk .select_desk_dialog .keyboard .confirm {
height: 140px;
background: #ff9f2e;
position: absolute;
bottom: 0;
right: 0;
border-right: none;
}
.select_desk .select_desk_dialog .keyboard .confirm:hover {
background: #f88502;
}
.confirm_btns {
display: flex;
justify-content: space-between;
width: 100%;
}
.confirm_btns .el-button {
width: 175px;
}
</style>

View File

@ -1,289 +0,0 @@
<template>
<el-dialog title="选择用户" width="850px" :visible.sync="show">
<div class="app-container">
<div class="head-container">
<el-form :model="query" inline>
<el-form-item label="">
<el-input
v-model="query.name"
placeholder="请输入昵称或手机号"
></el-input>
</el-form-item>
<!-- <el-form-item label="是否为会员">
<el-select v-model="query.isVip" placeholder="是否是会员">
<el-option value="" label="全部"></el-option>
<el-option :value="1" label="是"></el-option>
<el-option :value="0" label="否"></el-option>
</el-select>
</el-form-item> -->
<el-form-item>
<div class="flex gap-20">
<el-button type="primary" @click="getTableData" size="medium"
>搜索</el-button
>
<!-- <el-button @click="resetHandle" size="medium">重置</el-button> -->
<el-button @click="noChooseUser" size="medium"
>不选择用户</el-button
>
<!-- <el-button @click="resetHandle" size="medium">新建用户</el-button> -->
</div>
</el-form-item>
</el-form>
</div>
<!-- <div class="head-container">
<el-button type="primary" icon="el-icon-plus" @click="$refs.addActive.show()">
添加活动
</el-button>
</div> -->
<div class="head-container">
<el-table :data="tableData.data" v-loading="tableData.loading" @cell-click="cellClick">
<el-table-column label="ID" prop="id"></el-table-column>
<el-table-column label="用户" prop="headImg" width="200px">
<template v-slot="scope">
<div class="user_info">
<el-image
:src="scope.row.headImg"
style="width: 40px; height: 40px; flex-shrink: 0"
>
<div slot="error" class="image-slot">
<i class="el-icon-user"></i>
</div>
</el-image>
<span class="name">{{ scope.row.nickName }}</span>
</div>
</template>
</el-table-column>
<el-table-column
label="手机号"
prop="telephone"
width="160"
></el-table-column>
<!-- <el-table-column label="性别" prop="sex">
<template v-slot="scope">
<el-tag type="priamry">{{ scope.row.sex || "未知" }}</el-tag>
</template>
</el-table-column> -->
<el-table-column label="会员" prop="isVip">
<template v-slot="scope">
<el-tag type="warning" v-if="scope.row.isVip"
>会员等级{{ scope.row.isVip }}</el-tag
>
<span v-else></span>
</template>
</el-table-column>
<el-table-column label="余额" prop="amount"></el-table-column>
<el-table-column label="积分" prop="totalScore"></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>
<!-- <el-button type="text" @click="charge(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 { queryAllShopUser, queryAllShopInfo } from "@/api/shop";
import dayjs from "dayjs";
let cacheData = {};
export default {
data() {
return {
show: false,
query: {
name: "",
},
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){
console.log(user)
this.$emit("chooseUser",user)
this.close()
},
noChooseUser(){
this.$emit("chooseUser",null)
this.close()
},
choose(user) {
this.$emit("chooseUser",user)
this.close()
},
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]);
},
//
async getShopInfo() {
try {
const res = await queryAllShopInfo(this.query);
this.shopInfo = res;
} catch (error) {
console.log(error);
}
},
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 queryAllShopUser({
...this.query,
size: this.tableData.size,
page: this.tableData.page + 1,
});
this.tableData.loading = false;
this.tableData.data = res.content;
this.tableData.total = res.totalElements;
} 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

@ -1,69 +0,0 @@
<template>
<el-dialog title="下载桌码" width="400px" :visible.sync="dialogVisible" @open="reset">
<el-form ref="form" :model="form" label-position="left">
<el-form-item label="下载数量">
<el-input-number v-model="form.number" :min="1" :max="500"></el-input-number>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false"> </el-button>
<el-button type="primary" :loading="loading" @click="onSubmitHandle"> </el-button>
</span>
</el-dialog>
</template>
<script>
import { downloadFile } from "@/utils/index";
import { downloadTableCode } from '@/api/table'
export default {
props: {
total: {
type: [Number, String],
default: 1
}
},
data() {
return {
dialogVisible: false,
loading: false,
form: {
number: 1
},
resetForm: ''
}
},
mounted() {
this.resetForm = { ...this.form }
},
methods: {
async onSubmitHandle() {
try {
this.loading = true
const file = await downloadTableCode({
count: this.form.number,
shopId: localStorage.getItem('shopId')
})
this.loading = false
this.dialogVisible = false
this.$message.success('下载成功')
downloadFile(file, "桌码", "zip");
} catch (error) {
this.loading = false
console.log(error);
}
},
show(obj) {
this.dialogVisible = true
// if (obj && obj.id) {
// this.form = JSON.parse(JSON.stringify(obj))
// }
},
close() {
this.dialogVisible = false
},
reset() {
this.form = { ...this.resetForm }
}
}
}
</script>

View File

@ -1,319 +0,0 @@
<template>
<div class="simple-Keyboard-number">
<div class="carts">
<div class="box_status">
<slot name="input">
<span> {{ number }}</span>
</slot>
</div>
<div class="number_list_box">
<div class="yd-keyboard">
<div class="mini-number-box1">
<div class="mini-number">
<div class="key-line">
<div class="key" @click="keyboradAdd('1')">1</div>
<div class="key" @click="keyboradAdd('2')">2</div>
<div class="key" @click="keyboradAdd('3')">3</div>
</div>
<div class="key-line">
<div class="key" @click="keyboradAdd('4')">4</div>
<div class="key" @click="keyboradAdd('5')">5</div>
<div class="key" @click="keyboradAdd('6')">6</div>
</div>
<div class="key-line">
<div class="key" @click="keyboradAdd('7')">7</div>
<div class="key" @click="keyboradAdd('8')">8</div>
<div class="key" @click="keyboradAdd('9')">9</div>
</div>
<div class="key-line">
<div class="key" @click="clearFunction">
<slot name="clear"> </slot>
</div>
<div class="key" @click="keyboradAdd('0')">0</div>
<div
class="key"
style="font-size: 31px"
@click="keyboradReduce"
>
<svg
t="1723453480343"
class="icon"
viewBox="0 0 1664 1024"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
p-id="1467"
width="32"
height="32"
>
<path
d="M1526.08 1.6H459.84L41.28 416c-53.76 53.248-53.76 139.52 0 192.64l418.624 414.592v-0.064h1066.176a136.96 136.96 0 0 0 137.6-136.256V137.792a136.96 136.96 0 0 0-137.6-136.192z m-331.392 631.168c26.816 26.624 26.816 69.76 0 96.384-26.88 26.56-70.4 26.56-97.28 0l-121.28-120.128-123.328 122.112a69.76 69.76 0 0 1-97.92 0 68.096 68.096 0 0 1 0-96.96L878.208 512l-121.28-120.064a67.648 67.648 0 0 1 0-96.32c26.88-26.624 70.4-26.624 97.28 0l121.216 120.064 122.24-120.96a69.696 69.696 0 0 1 97.92 0 68.032 68.032 0 0 1 0 96.96l-122.24 120.96 121.344 120.064z"
fill="#333333"
p-id="1468"
></path>
</svg>
</div>
</div>
</div>
</div>
</div>
</div>
<template v-if="showConfirm">
<div class="submit" @click="keyboradConfirm">确认</div>
</template>
</div>
</div>
</template>
<script>
export default {
props: {
isCanEmpty: {
type: Boolean,
default: false,
},
maxTips: {
type: String,
default: "输入值超范围",
},
showConfirm: {
type: Boolean,
default: false,
},
max: {
type: Number,
default: Infinity,
},
value: {
type: [String, Number],
default: 0,
},
},
data() {
return {
number: 0,
};
},
watch: {
value(newval) {
this.number = newval;
},
number(newval) {
this.$emit("input", newval);
},
},
methods: {
clearFunction() {
this.$emit("clear", this.number);
},
keyboradAdd(n) {
if (Number(this.number) == 0) {
return (this.number = n);
}
const newval = this.number + n;
if (newval > this.max) {
return this.$message( this.maxTips);
}
this.number = newval;
},
keyboradReduce() {
if (this.number.length <= 1) {
return (this.number = this.isCanEmpty ? "" : "0");
}
this.number = `${this.number}`.substring(0, this.number.length - 1);
},
keyboradConfirm() {
this.$emit("confirm", this.number);
},
},
mounted() {
this.number = `${this.value}`;
},
};
</script>
<style lang="scss" scoped>
.yd-keyboard {
justify-content: center;
margin-bottom: 20px;
}
.mini-number-box1 .mini-number,
.yd-keyboard {
display: flex;
flex-direction: column;
}
.mini-number-box1 .mini-number {
border: 1px solid #dcdfe6;
}
.mini-number-box1 .mini-number .key-line {
margin-top: 0;
}
.mini-number-box1 .mini-number .key {
width: 122px;
height: 60px;
-webkit-box-shadow: none;
box-shadow: none;
border-radius: 0;
margin-left: 0;
}
.mini-number-box1 .mini-number .key:hover {
background-color: #dcdfe6;
}
.mini-number-box1 .mini-number .key:not(:last-child) {
border-right: 1px solid #dcdfe6;
}
.mini-number-box1 .mini-number .key-line:not(:last-child) {
border-bottom: 1px solid #dcdfe6;
}
.mini-number-box2 {
display: flex;
justify-content: center;
}
.mini-number-box2 .key {
width: 80px;
height: 70px;
}
.mini-number-box2 .function-button {
display: flex;
flex-direction: column;
}
.mini-number-box2 .function-button .key {
margin-top: 8px;
}
.key-line {
margin-top: 8px;
}
.key,
.key-line {
display: flex;
justify-content: center;
}
.key {
width: 64px;
height: 64px;
background: #fff;
-webkit-box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.10196078431372549);
border-radius: 4px;
align-items: center;
margin-left: 8px;
font-family: PingFangSC-Regular;
font-weight: 400;
font-size: 20px;
color: rgba(0, 0, 0, 0.8);
text-align: center;
line-height: 34px;
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.10196078431372549);
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.simple-Keyboard-number,
.simple-Keyboard-weight {
min-width: 410px;
background: #fff;
border-radius: 4px;
overflow: hidden;
}
.submit {
width: 366px;
height: 44px;
background: #22bf64;
border-radius: 2px;
display: flex;
justify-content: center;
align-items: center;
font-size: 14px;
color: #fff;
font-family: PingFangSC-Regular;
font-weight: 400;
margin-bottom: 40px;
cursor: pointer;
}
.disabled-box {
position: absolute;
inset: 0;
left: 0;
right: 0;
top: 0;
bottom: 0;
}
.carts {
flex-direction: column;
background: #fff;
height: 100%;
}
.carts .title,
.carts {
display: flex;
align-items: center;
width: 100%;
}
.carts .title {
justify-content: space-between;
height: 64px;
border-bottom: 1px solid #ebebeb;
padding: 20px;
padding-top: 30px;
}
.carts .title .left {
font-family: PingFangSC-Medium;
font-weight: 500;
font-size: 18px;
color: #000;
}
.carts .title .right {
font-size: 14.4px;
cursor: pointer;
}
.carts .box_status {
margin-bottom: 20px;
width: 370px;
height: 58px;
background: #fff;
border: 1px solid #dcdfe6;
border-radius: 4px;
display: flex;
justify-content: center;
align-items: center;
margin-top: 20px;
font-family: MicrosoftYaHei;
font-size: 20px;
color: rgba(0, 0, 0, 0.8);
letter-spacing: 1.25px;
text-align: center;
}
.carts .box_status span {
padding: 0 5px;
}
</style>

View File

@ -1,339 +0,0 @@
<template>
<el-dialog width="330px" :title="title" :visible.sync="show">
<div class="simple-Keyboard-number">
<div class="carts">
<div class="pad-14">
<div class="box_status">
<span class="sym"></span>
<el-input v-model="number" type="text" @input="numberInput"></el-input>
<!-- <span class="inputs" :contenteditable="true" @input="numberInput" type="text" >{{ number }}</span> -->
</div>
</div>
<div class="number_list_box">
<div class="yd-keyboard">
<div class="mini-number-box1">
<div class="mini-number">
<div class="key-line">
<div class="key" @click="keyboradAdd('1')">1</div>
<div class="key" @click="keyboradAdd('2')">2</div>
<div class="key" @click="keyboradAdd('3')">3</div>
<div
class="key"
style="font-size: 31px"
@click="keyboradReduce"
>
<svg
t="1723453480343"
class="icon"
viewBox="0 0 1664 1024"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
p-id="1467"
width="32"
height="32"
>
<path
d="M1526.08 1.6H459.84L41.28 416c-53.76 53.248-53.76 139.52 0 192.64l418.624 414.592v-0.064h1066.176a136.96 136.96 0 0 0 137.6-136.256V137.792a136.96 136.96 0 0 0-137.6-136.192z m-331.392 631.168c26.816 26.624 26.816 69.76 0 96.384-26.88 26.56-70.4 26.56-97.28 0l-121.28-120.128-123.328 122.112a69.76 69.76 0 0 1-97.92 0 68.096 68.096 0 0 1 0-96.96L878.208 512l-121.28-120.064a67.648 67.648 0 0 1 0-96.32c26.88-26.624 70.4-26.624 97.28 0l121.216 120.064 122.24-120.96a69.696 69.696 0 0 1 97.92 0 68.032 68.032 0 0 1 0 96.96l-122.24 120.96 121.344 120.064z"
fill="#333333"
p-id="1468"
></path>
</svg>
</div>
</div>
<div class="key-line">
<div class="key" @click="keyboradAdd('4')">4</div>
<div class="key" @click="keyboradAdd('5')">5</div>
<div class="key" @click="keyboradAdd('6')">6</div>
<div class="key" @click="keyboradAdd('clear')">清空</div>
</div>
<div class="key-line">
<div class="key" @click="keyboradAdd('7')">7</div>
<div class="key" @click="keyboradAdd('8')">8</div>
<div class="key" @click="keyboradAdd('9')">9</div>
<div class="key"></div>
</div>
<div class="key-line">
<div class="key" @click="keyboradAdd('.')">.</div>
<div class="key" @click="keyboradAdd('0')">0</div>
<div class="key" @click="keyboradAdd('00')">00</div>
<div class="key"></div>
</div>
<div class="confirm key" @click="confirm">确认</div>
</div>
</div>
</div>
</div>
<!-- <div class="submit" @click="keyboradConfirm">确认</div> -->
</div>
</div>
</el-dialog>
</template>
<script>
export default {
props: {
title: {
type: String,
default: "支付",
},
value: {
type: [String, Number],
default: 0,
},
},
data() {
return {
number: '0',
show:false
};
},
watch: {
number(newval) {
this.$emit("input", newval);
},
},
methods: {
confirm(){
},
open(){
this.show=true
},
close(){
this.show=false
},
numberInput(val){
console.log(val)
this.number=`${Number(val)}`
},
keyboradAdd(n) {
if (n === "clear") {
return (this.number = '0');
}
if(n==='.'){
return this.number += this.number.includes('.')?'' : '.'
}
if (`${this.number}`.length<=1&&Number(this.number)===0) {
return (this.number = n);
}
this.number += n;
},
keyboradReduce() {
if (this.number.length <= 1) {
return (this.number = this.isCanEmpty ? "" : "0");
}
this.number = this.number.substring(0, this.number.length - 1);
},
keyboradConfirm() {
this.$emit("confirm", this.number);
},
},
mounted() {
this.number = `${this.value}`;
},
};
</script>
<style lang="scss" scoped>
.pad-14 {
padding: 14px;
width: 100%;
}
::v-deep .el-dialog__body {
padding: 0;
}
::v-deep .el-input__inner::-webkit-outer-spin-button{
-webkit-appearance: none;
margin: 0;
}
::v-deep .el-input__inner::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
/* Firefox */
::v-deep .el-input__inner {
-moz-appearance: textfield;
}
.number_list_box,
.yd-keyboard,
.mini-number,
.mini-number-box1,
.key-line {
width: 100%;
}
.yd-keyboard {
justify-content: center;
}
.mini-number-box1 .mini-number,
.yd-keyboard {
display: flex;
position: relative;
flex-direction: column;
}
.mini-number-box1 .mini-number {
border-top: 1px solid #dcdfe6;
}
.mini-number-box2 {
display: flex;
justify-content: center;
}
.mini-number-box2 .function-button {
display: flex;
flex-direction: column;
}
.key,
.key-line {
display: flex;
justify-content: center;
}
.key {
width: 25%;
height: 70px;
box-sizing: border-box;
background: #fff;
align-items: center;
font-family: PingFangSC-Regular;
font-weight: 400;
font-size: 24px;
color: #212121;
text-align: center;
line-height: 34px;
cursor: pointer;
user-select: none;
}
.key:hover {
background-color: #dcdfe6;
}
.key:not(:last-child) {
border-right: 1px solid #dcdfe6;
}
.key-line:not(:last-child) {
border-bottom: 1px solid #dcdfe6;
}
.confirm {
height: 142px;
width: 25%;
background: #22bf64;
color: #fff;
position: absolute;
bottom: 0;
right: 0;
border-right: none;
}
.confirm:hover {
background: rgba(34, 191, 100, 0.8666666666666667);
}
.simple-Keyboard-number,
.simple-Keyboard-weight {
background: #fff;
border-radius: 4px;
overflow: hidden;
}
.submit {
width: 366px;
height: 44px;
background: #22bf64;
border-radius: 2px;
display: flex;
justify-content: center;
align-items: center;
font-size: 14px;
color: #fff;
font-family: PingFangSC-Regular;
font-weight: 400;
margin-bottom: 40px;
cursor: pointer;
}
.disabled-box {
position: absolute;
inset: 0;
left: 0;
right: 0;
top: 0;
bottom: 0;
}
.carts {
flex-direction: column;
background: #fff;
height: 100%;
}
.carts .title,
.carts {
display: flex;
align-items: center;
width: 100%;
}
.carts .title {
justify-content: space-between;
height: 64px;
border-bottom: 1px solid #ebebeb;
padding: 20px;
padding-top: 30px;
}
.carts .title .left {
font-family: PingFangSC-Medium;
font-weight: 500;
font-size: 18px;
color: #000;
}
.carts .title .right {
font-size: 14.4px;
cursor: pointer;
}
.box_status {
box-sizing: border-box;
width: 100%;
background: #fff;
border: 1px solid #dcdfe6;
border-radius: 4px;
display: flex;
padding: 14px;
align-items: flex-end;
font-family: MicrosoftYaHei;
font-size: 20px;
color: rgba(0, 0, 0, 0.8);
letter-spacing: 1.25px;
.sym {
font-size: 24px;
color: #212121;
width: 30px;
margin-bottom: 3px;
}
.inputs {
font-size: 28px;
color: #212121;
outline: none;
line-height: 37px;
border: none;
max-width: 250px;
}
}
::v-deep .el-input--small .el-input__inner{
font-size: 28px;
color: #212121;
outline: none;
line-height: 37px;
border: none;
max-width: 250px;
padding-left: 0;
}
.carts .box_status span {
padding: 0 5px;
}
</style>

View File

@ -1,76 +0,0 @@
<template>
<div>
<div class="title">选择支付方式</div>
<div class="btn_group">
<div class="price_select">
<div class="pay_btns">
<el-button
size="medium"
@click="changeSel(item)"
v-for="(item, index) in list"
:key="index"
:type="sel === item.payType ? 'primary' : ''"
>
{{ item.payName }}
</el-button>
<!-- <el-button size="medium"> 余额支付 </el-button>
<el-button size="medium"> 现金支付 </el-button>
<el-button size="medium"> 挂账 </el-button> -->
</div>
</div>
</div>
</div>
</template>
<script>
import { $getPayType } from "@/api/table";
export default {
props: {
value: {
type: [String, Number],
default: '',
},
},
data() {
return {
list: [],
sel: "",
};
},
watch: {
sel(newval) {
console.log(newval);
this.$emit("input", newval);
},
},
methods: {
changeSel(item) {
this.sel = item.payType;
this.$emit("itemClick", item);
},
async init() {
const res = await $getPayType();
this.list = res.filter(v=>v.isDisplay);
console.log(res[0]);
this.sel = this.sel ? this.sel : res[0].payType;
},
},
mounted() {
this.init();
},
};
</script>
<style lang="scss" scoped>
.title {
font-size: 18px;
color: #000;
font-weight: 600;
padding: 20px 0;
}
.pay_btns .el-button {
margin-left: 0;
margin-right: 10px;
margin-bottom: 10px;
}
</style>

View File

@ -1,269 +0,0 @@
<template>
<el-dialog
title="预约"
:visible.sync="dialogVisible"
width="500px"
@close="reset"
>
<el-form
ref="form"
:model="form"
:rules="rules"
label-width="120px"
label-position="left"
>
<el-form-item label="预约日期" prop="bookingDate">
<!-- <el-date-picker
v-model="form.bookingDate"
type="date"
value-format="yyyy-MM-dd"
:picker-options="pickerOptions"
placeholder="选择预约日期"
style="width: 200px;margin-right: 10px;"
@change="getShopTableList"
/> -->
<el-radio-group
v-model="form.bookingDate"
class="date"
@change="getShopTableList"
>
<el-radio-button
v-for="(item) in dateList"
:key="item.date"
:label="item.date"
>
<div style="font-size: 12px;margin-bottom: 4px;">{{ item.label }} / {{ item.date.substring(8,10) }}</div>
<div style="font-size: 12px;"> {{ item.day }}</div>
</el-radio-button>
</el-radio-group>
</el-form-item>
<el-form-item label="预约类型" prop="bookingType">
<el-radio-group v-model="form.bookingType" @change="getShopTableList">
<el-radio-button label="lunch">午餐</el-radio-button>
<el-radio-button label="dinner">晚餐</el-radio-button>
</el-radio-group>
</el-form-item>
<el-form-item label="就餐时间" prop="bookingTime">
<el-time-picker
v-model="form.bookingTime"
value-format="HH:mm:ss"
placeholder="选择时间"
style="width: 100%;"
/>
</el-form-item>
<el-form-item label="预约桌台" prop="shopTableId">
<el-select v-model="form.shopTableId" placeholder="请选择" style="width: 100%;">
<el-option
v-for="item in shopTableList"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item label="用餐人数" prop="dinerNum">
<el-input-number v-model="form.dinerNum" :min="1" controls-position="right" style="width: 100%;"/>
</el-form-item>
<el-form-item label="订餐人" prop="bookingPerson">
<el-input v-model="form.bookingPerson" style="width: 200px;margin-right: 10px;" placeholder="请输入联系人姓名" />
<el-radio-group v-model="form.gender">
<el-radio-button label="1">先生</el-radio-button>
<el-radio-button label="2">女士</el-radio-button>
</el-radio-group>
</el-form-item>
<el-form-item label="联系电话" prop="phoneNumber">
<el-input v-model="form.phoneNumber" oninput="value= value.replace(/[^0-9]/g, '')" maxlength="11" placeholder="请输入联系电话" />
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false"> </el-button>
<el-button
type="primary"
:loading="loading"
@click="onSubmitHandle"
> </el-button>
</span>
</el-dialog>
</template>
<script>
import { getShopTableList, makeShopTable } from '@/api/table'
import dayjs from 'dayjs'
export default {
data() {
return {
dialogVisible: false,
resetForm: '',
loading: false,
pickerOptions: {
disabledDate(time) {
return time.getTime() < Date.now() - 8.64e7 // 8.64e71
}
},
dateList: [
{ label: '今', day: '', date: '' },
{ label: '明', day: '', date: '' },
{ label: '后', day: '', date: '' }
],
shopTableList: [],
form: {
bookingDate: '',
bookingType: 'lunch',
shopTableId: null,
dinerNum: 1,
bookingPerson: '',
phoneNumber: '',
gender: '1',
bookingTime: '',
diningType: '普通用餐',
focus: '0',
receiveMarketingSms: '0'
},
rules: {
shopTableId: [
{
required: true,
message: '请选择预约桌台',
trigger: ['blur']
}
],
dinerNum: [
{
required: true,
message: '请选择用餐人数',
trigger: ['blur']
}
],
phoneNumber: [
{
required: true,
message: '请输入联系方式',
trigger: ['blur']
}
],
bookingPerson: [
{
required: true,
message: '请输入订餐人姓名',
trigger: ['blur']
}
],
bookingTime: [
{
required: true,
message: '请选择用餐时间',
trigger: ['change']
}
]
}
}
},
mounted() {
this.resetForm = { ...this.form }
},
methods: {
getWeekdays() {
const today = new Date()
const tomorrow = new Date(today)
const dayAfterTomorrow = new Date(today)
//
tomorrow.setDate(today.getDate() + 1)
dayAfterTomorrow.setDate(today.getDate() + 2)
//
const getDayOfWeek = (date) => {
const days = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']
return days[date.getDay()]
}
//
const todayWeekday = getDayOfWeek(today)
const tomorrowWeekday = getDayOfWeek(tomorrow)
const dayAfterTomorrowWeekday = getDayOfWeek(dayAfterTomorrow)
this.dateList[0].day = todayWeekday
this.dateList[1].day = tomorrowWeekday
this.dateList[2].day = dayAfterTomorrowWeekday
this.dateList[0].date = dayjs(today).format('YYYY-MM-DD')
this.dateList[1].date = dayjs(tomorrow).format('YYYY-MM-DD')
this.dateList[2].date = dayjs(dayAfterTomorrow).format('YYYY-MM-DD')
this.form.bookingDate = this.dateList[0].date
},
/**
* 获取桌台数据
*/
async getShopTableList() {
this.form.shopTableId = null
const params = {
bookingDate: this.form.bookingDate,
bookingType: this.form.bookingType
}
const res = await getShopTableList(params)
this.shopTableList = res
console.log(res)
},
onSubmitHandle() {
this.$refs.form.validate(async(valid) => {
if (valid) {
this.loading = true
try {
const bookingTime = this.form.bookingDate + ' ' + this.form.bookingTime
const params = {
...this.form,
shopId: localStorage.getItem('shopId')
}
params.bookingTime = bookingTime
const res = await makeShopTable(params)
this.$emit('success', res)
this.close()
this.$notify({
title: '成功',
message: `预约成功`,
type: 'success'
})
this.loading = false
} catch (error) {
this.loading = false
console.log(error)
}
}
})
},
show(obj) {
this.dialogVisible = true
if (obj && obj.id) {
this.form = JSON.parse(JSON.stringify(obj))
}
this.getShopTableList()
this.getWeekdays()
},
close() {
this.dialogVisible = false
},
reset() {
this.form = { ...this.resetForm }
}
}
}
</script>
<style scoped lang="scss">
.date{
::v-deep .el-form-item__content{
// height: 36px;
// display: flex;
// justify-content: space-between;
}
::v-deep .el-radio-button{
height: 100%;
}
::v-deep .el-radio-button__inner{
padding: 4px 20px;
height: 100%;
}
}
</style>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,141 +0,0 @@
<template>
<el-dialog :title="form.id ? '编辑台桌' : '添加台桌'" :visible.sync="dialogVisible" @open="tbShopAreaGet" @close="reset">
<el-form ref="form" :model="form" :rules="rules" label-width="120px" label-position="left">
<el-form-item label="选择区域" prop="areaId">
<el-select v-model="form.areaId" placeholder="请选择区域">
<el-option :label="item.name" :value="item.id" v-for="item in areaList" :key="item.id"></el-option>
</el-select>
</el-form-item>
<el-form-item label="台桌状态" prop="status" v-if="form.id">
<el-select v-model="form.status" placeholder="请选择台桌状态">
<el-option :label="item.label" :value="item.value" v-for="item in status" :key="item.value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="台桌名称">
<el-input v-model="form.name" placeholder="请输入台桌名称"></el-input>
</el-form-item>
<el-form-item label="客座数">
<el-input-number v-model="form.maxCapacity" :min="0" controls-position="right"></el-input-number>
</el-form-item>
<el-form-item label="清台管理">
<el-radio-group v-model="form.autoClear">
<el-radio-button :label="0">手动清台</el-radio-button>
<el-radio-button :label="1">自动清台</el-radio-button>
</el-radio-group>
</el-form-item>
<el-form-item label="网络预定开关">
<el-switch v-model="form.isPredate" :active-value="1" :inactive-value="2"></el-switch>
</el-form-item>
<el-form-item label="类型">
<el-radio-group v-model="form.type">
<el-radio-button :label="0">低消</el-radio-button>
<el-radio-button :label="2">计时</el-radio-button>
</el-radio-group>
</el-form-item>
<el-form-item label="最低消费" v-if="form.type == 0">
<el-input-number v-model="form.amount" :min="0" controls-position="right"></el-input-number>
</el-form-item>
<el-form-item label="每小时收费" v-if="form.type == 2">
<el-input-number v-model="form.perhour" :min="0" controls-position="right"></el-input-number>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false"> </el-button>
<el-button type="primary" :loading="loading" @click="onSubmitHandle"> </el-button>
</span>
</el-dialog>
</template>
<script>
import { tbShopTable, tbShopAreaGet } from '@/api/table'
import $status from "../status.js";
export default {
data() {
return {
dialogVisible: false,
resetForm: '',
loading: false,
status:[],
form: {
id: '',
name: '',
areaId: '',
maxCapacity: 0,
isPredate: 1,
type: 2,
perhour: 0,
amount: 0,
autoClear: 1,
},
rules: {
areaId: [
{
required: true,
message: '请选择区域',
trigger: 'blur'
}
]
},
areaList: []
}
},
mounted() {
this.resetForm = { ...this.form }
this.status = Object.keys($status).map(key =>{
return {...$status[key],value:key}
});
},
methods: {
onSubmitHandle() {
this.$refs.form.validate(async valid => {
if (valid) {
this.loading = true
try {
let res = await tbShopTable({
...this.form,
qrcode:this.form.tableId,
shopId: localStorage.getItem('shopId')
}, this.form.id ? 'put' : 'post')
this.$emit('success', res)
this.close()
this.$notify({
title: '成功',
message: `${this.form.id ? '编辑' : '添加'}成功`,
type: 'success'
});
this.loading = false
} catch (error) {
this.loading = false
console.log(error)
}
}
})
},
show(obj) {
this.dialogVisible = true
if (obj && obj.id) {
this.form = JSON.parse(JSON.stringify(obj))
}
},
close() {
this.dialogVisible = false
},
reset() {
this.form = { ...this.resetForm }
},
//
async tbShopAreaGet() {
try {
const { content } = await tbShopAreaGet({
shopId: localStorage.getItem('shopId')
})
this.areaList = content
} catch (error) {
console.log(error);
}
}
}
}
</script>