Files
cashier-web/src/views/shop/config/components/shopInfo.vue
2025-11-28 18:01:53 +08:00

632 lines
20 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div>
<div>
<el-form ref="form" :model="form" :rules="rules" label-width="160px" label-position="left">
<el-form-item label="门店名称" prop="shopName">
<el-input
v-model.trim="form.shopName"
placeholder="请输入门店名称"
style="width: 500px"
></el-input>
</el-form-item>
<el-form-item label="连锁店扩展店名">
<el-input
v-model.trim="form.chainName"
placeholder="请输入连锁店扩展店名"
style="width: 500px"
></el-input>
</el-form-item>
<el-form-item label="门店logo">
<div class="img_box">
<single-image-upload
style="width: 80px; height: 80px"
v-model="form.logo"
></single-image-upload>
</div>
</el-form-item>
<!-- <el-form-item label="门店照片">
<div class="img_box">
<el-image :src="form.coverImg || require('@/assets/images/upload.png')" fit="contain"
style="width: 80px;height: 80px;" @click="
showUpload = true;
uploadIndex = 2;
"></el-image>
<el-button type="primary" plain v-if="form.coverImg"
@click="downloadImgHandle(form.coverImg)">下载</el-button>
</div>
</el-form-item> -->
<el-form-item label="门店收款码">
<div class="img_box">
<canvas ref="canvas" id="QRCode_header" style="width: 80px; height: 80px"></canvas>
<el-button
size="small"
plain
v-if="form.paymentQrcode"
@click="downloadCanvas(form.paymentQrcode)"
>
下载
</el-button>
</div>
</el-form-item>
<el-form-item label="微信二维码">
<div class="img_box">
<single-image-upload
style="width: 80px; height: 80px"
v-model="form.shopQrcode"
></single-image-upload>
</div>
</el-form-item>
<!-- <el-form-item label="店铺小程序码">
<div class="img_box">
<el-image :src="form.smallQrcode || img_download_error" fit="contain"
style="width: 80px; height: 80px"></el-image>
<el-button size="small" plain v-if="form.shopQrcode" @click="downloadImgHandle(form.smallQrcode)">
下载
</el-button>
</div>
</el-form-item> -->
<el-form-item label="经营模式「单选」">
<el-radio-group v-model="form.registerType">
<el-radio value="before">快餐版先支付后下单</el-radio>
<el-radio value="after">餐饮版先下单后支付</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="就餐模式「多选」" prop="eatModel">
<el-checkbox-group v-model="form.eatModel">
<el-checkbox value="dine-in">堂食自取</el-checkbox>
<el-checkbox value="take-out">允许打包</el-checkbox>
</el-checkbox-group>
</el-form-item>
<!-- <el-form-item label="积分群体">
<el-radio-group v-model="form.consumeColony">
<el-radio label="all">所有</el-radio>
<el-radio label="vip">仅针对会员</el-radio>
</el-radio-group>
</el-form-item> -->
<el-form-item label="联系电话" prop="phone">
<el-input
v-model.trim="form.phone"
placeholder="请输入联系电话"
style="width: 500px"
></el-input>
</el-form-item>
<!-- <el-form-item label="外卖起送金额">
<el-input-number v-model="form.takeaway_money" placeholder="0.00" controls-position="right"
:min="0"></el-input-number>
</el-form-item> -->
<el-form-item label="店铺经度" prop="provinces">
<el-row :gutter="6">
<el-col :span="9" v-if="form.provinces">
<el-input :value="`${form.provinces}-${form.cities}-${form.districts}`" disabled />
</el-col>
<el-col :span="4" v-if="form.lng">
<el-input v-model="form.lng" placeholder="经度" disabled></el-input>
</el-col>
<el-col :span="4" v-if="form.lng">
<el-input v-model="form.lat" placeholder="纬度" disabled></el-input>
</el-col>
<el-col :span="4">
<el-button type="primary" plain icon="place" @click="chooseAddressShow">
选择坐标
</el-button>
</el-col>
</el-row>
<div style="color: #999">准确的定位便于用户导航到店铺</div>
</el-form-item>
<el-form-item label="门店详细地址">
<el-input
type="textarea"
v-model.trim="form.address"
placeholder="请输入门店详细地址"
style="width: 500px"
></el-input>
</el-form-item>
<el-form-item label="营业时间">
<div class="u-flex gap-2" style="width: 50%">
<el-select v-model="form.businessStartDay" placeholder="周几开始">
<el-option
:value="item.label"
:label="item.label"
v-for="item in weeks"
:key="item.value"
></el-option>
</el-select>
<el-select v-model="form.businessEndDay" placeholder="周几结束">
<el-option
:value="item.label"
:label="item.label"
v-for="item in weeks"
:key="item.value"
></el-option>
</el-select>
<el-time-picker
placeholder="起始时间"
v-model="startTime"
:picker-options="{
selectableRange: '00:00:00 - 23:59:59',
format: 'HH:mm',
}"
format="HH:mm"
value-format="HH:mm"
></el-time-picker>
<el-time-picker
placeholder="结束时间"
v-model="endTime"
:picker-options="{
selectableRange: '00:00:00 - 23:59:59',
}"
format="HH:mm"
value-format="HH:mm"
></el-time-picker>
</div>
</el-form-item>
<el-form-item label="桌位费/位/元">
<el-input-number :disabled="!!form.isTableFee" v-model="form.tableFee" :min="0" />
<!-- <el-checkbox v-model="form.isTableFee" :label="1">免餐位费</el-checkbox> -->
<el-switch
class="u-m-l-10"
v-model.trim="form.isTableFee"
:active-value="1"
:inactive-value="0"
active-text="免餐位费"
></el-switch>
</el-form-item>
<!-- <el-form-item label="是否开启8折活动">
<el-switch v-model.trim="form.isOpenYhq" active-value="true" inactive-value="false"></el-switch>
<div style="color: #999;">是否允许用户在小程序端支付订单</div>
</el-form-item> -->
<!-- <el-form-item label="是否启用商品会员价">
<el-switch v-model.trim="form.isMemberPrice" :active-value="1" ::inactive-value="0"></el-switch>
<div style="color: #999;">是否允许用户在小程序端支付订单</div>
</el-form-item>
<el-form-item label="是否开启会员余额支付">
<el-switch v-model.trim="form.isAccountPay" :active-value="1" :inactive-value="0"></el-switch>
<div style="color: #999;">是否允许用户在小程序端支付订单</div>
</el-form-item> -->
<!-- <el-form-item label="结算类型">
<el-radio-group v-model="form.settleType">
<el-radio :label="0">今日</el-radio>
<el-radio :label="1">次日</el-radio>
</el-radio-group>
</el-form-item> -->
<!-- <el-form-item label="结算时间" prop="settleTime">
<el-time-picker
placeholder="请选择结算时间"
v-model="form.settleTime"
:picker-options="{
selectableRange: '00:00:00 - 23:59:59',
format: 'HH:mm'
}"
format="HH:mm"
value-format="HH:mm"
>
</el-time-picker>
</el-form-item> -->
<el-form-item label="店铺简介">
<el-input
type="textarea"
v-model.trim="form.detail"
placeholder="请输入店铺简介"
style="width: 500px"
></el-input>
</el-form-item>
<el-form-item label="台桌预订短信">
<el-input
type="textarea"
v-model.trim="form.bookingSms"
placeholder="请输入台桌预订短信"
style="width: 500px"
></el-input>
</el-form-item>
<el-form-item label="电子围栏" prop="isOrderFence">
<div class="column">
<div class="center" style="display: flex; align-items: center; gap: 14px">
<el-switch
v-model="form.isOrderFence"
:active-value="1"
:inactive-value="0"
></el-switch>
<div class="tips" style="font-size: 14px; color: #999">
开启后用户只能在店铺附近xx公里内点餐
</div>
</div>
<div class="center" v-if="form.isOrderFence == 1">
<el-input
v-model="form.orderFenceDistance"
placeholder="请输入"
@input="(e) => (form.orderFenceDistance = filterNumberInput(e))"
style="width: 250px"
input-style="text-align: center;"
>
<template #prepend>限制</template>
<template #append>公里</template>
</el-input>
</div>
</div>
</el-form-item>
<el-form-item label="上菜时间(分钟)" prop="isServeTimeControl">
<div class="column">
<div class="center" style="display: flex; align-items: center; gap: 14px">
<el-switch
v-model="form.isServeTimeControl"
:active-value="1"
:inactive-value="0"
></el-switch>
<div class="tips" style="font-size: 14px; color: #999">
起菜到上菜的时间间隔开启后会有超时提示
</div>
</div>
<div class="center" v-if="form.isServeTimeControl == 1">
<el-input
v-model="form.serveTime"
placeholder="请输入"
@input="(e) => (form.serveTime = filterNumberInput(e))"
style="width: 250px"
input-style="text-align: center;"
>
<template #prepend>限制</template>
<template #append>分钟</template>
</el-input>
</div>
</div>
</el-form-item>
<el-form-item label="状态">
<el-radio-group v-model="form.status">
<el-radio :value="1">营业中</el-radio>
<el-radio :value="2">休息中</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitHandle" :loading="formLoading">
<span v-if="!formLoading">保存</span>
<span v-else>保存中...</span>
</el-button>
</el-form-item>
</el-form>
</div>
<ChooseAddress ref="refChooseAddress" @choose="chooseAddressConfirm"></ChooseAddress>
<el-dialog
v-model="showUpload"
:close-on-click-modal="false"
append-to-body
width="500px"
@close="showUpload = false"
>
<el-upload
:before-remove="handleBeforeRemove"
:on-success="handleSuccess"
:on-error="handleError"
:file-list="fileList"
:headers="headers"
:action="qiNiuUploadApi"
:limit="1"
list-type="picture"
class="upload-demo"
>
<el-button size="small" type="primary">点击上传</el-button>
<template #tip>
<div style="display: block" class="el-upload__tip">请勿上传违法文件且文件不超过15M</div>
</template>
</el-upload>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="doSubmit">确认</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script>
import { ElMessage } from "element-plus";
import QRCode from "qrcode";
import img_download_error from "@/assets/images/img_download_error.png";
import ShopApi from "@/api/account/shop";
import { filterNumberInput } from "@/utils/index";
// import { tbShopInfo, tbShopInfoPut } from "@/api/user";
// import { geocode } from "@/api/shop";
export default {
data() {
return {
filterNumberInput,
img_download_error,
showUpload: false,
uploadIndex: 1,
startTime: "",
endTime: "",
formLoading: false,
form: {
eatModel: [],
paymentQrcode: "",
consumeColony: "all",
},
rules: {
eatModel: [
{
required: true,
message: "请至少选择一种就餐模式",
trigger: "blur",
},
],
shopName: [
{
required: true,
message: "请输入门店名称",
trigger: "blur",
},
],
phone: [
{
required: true,
message: "请输入联系电话",
trigger: "blur",
},
],
settleTime: [
{
required: true,
message: " ",
trigger: "blur",
},
],
isOrderFence: [
{
trigger: "blur",
validator: (rule, value, callback) => {
if (
this.form.isOrderFence === 1 &&
(!this.form.orderFenceDistance || this.form.orderFenceDistance <= 0)
) {
callback(new Error("请输入限制公里数"));
} else {
callback();
}
},
},
],
},
fileList: [],
files: [],
searchOption: {
city: "西安",
citylimit: false,
},
locationSearchList: [],
amapOptions: {
center: [108.946465, 34.347984],
position: [],
},
weeks: [
{
value: "1",
label: "周一",
},
{
value: "2",
label: "周二",
},
{
value: "3",
label: "周三",
},
{
value: "4",
label: "周四",
},
{
value: "5",
label: "周五",
},
{
value: "6",
label: "周六",
},
{
value: "7",
label: "周天",
},
],
};
},
mounted() {
this.tbShopInfo();
},
methods: {
chooseAddressConfirm(e) {
console.log(e);
this.$refs.refChooseAddress.close();
this.selectLocationHandle(e);
},
chooseAddressShow() {
this.$refs.refChooseAddress.open();
},
// 下载url图片
downloadImgHandle(url) {
if (url) window.open(url, "_blank");
},
// 下载图片
downloadCanvas(url) {
if (url) {
this.saveCanvasAsImage(this.$refs.canvas, "pay_code");
}
},
saveCanvasAsImage(canvas, filename) {
// 获取canvas的数据URL
const dataURL = canvas.toDataURL("image/png");
// 创建一个a标签用于下载
const downloadLink = document.createElement("a");
downloadLink.href = dataURL;
downloadLink.download = filename;
document.body.appendChild(downloadLink);
// 触发下载
downloadLink.click();
// 清理临时元素
document.body.removeChild(downloadLink);
},
onSearchResult(res) {
this.locationSearchList = res;
this.amapOptions.center = [res[0].lng, res[0].lat];
},
// 确认地址选择
async selectLocationHandle(item) {
this.form.lng = item.location.lng;
this.form.lat = item.location.lat;
this.form.address = item.address;
const position = `${item.location.lng},${item.location.lat}`;
this.form.provinces = item.pname;
this.form.cities = item.cityname;
this.form.districts = item.adname;
},
async tbShopInfo() {
try {
const shopId = localStorage.getItem("shopId");
const res = await ShopApi.get();
this.form = { ...res, eatModel: res.eatModel ? res.eatModel.split(",") : [] };
this.form.orderFenceDistance = res.orderFenceDistance / 1000;
if (res.businessTime) {
const businessTime = res.businessTime.split("-");
this.startTime = businessTime[0];
this.endTime = businessTime[1];
}
QRCode.toCanvas(
this.$refs.canvas,
this.form.paymentQrcode,
{ margin: 0 },
function (error) {
console.log(error);
}
);
} catch (error) {
console.log(error);
}
},
// 保存
submitHandle() {
this.$refs.form.validate(async (valid) => {
if (valid) {
try {
this.formLoading = true;
if (this.startTime && this.endTime) {
this.form.businessTime = `${this.startTime}-${this.endTime}`;
}
const data = { ...this.form };
if (this.form.isOrderFence == 1) {
data.orderFenceDistance = this.form.orderFenceDistance * 1000;
}
await ShopApi.edit({
...data,
eatModel: this.form.eatModel.join(","),
});
ElMessage.success({
title: "成功",
message: "提交成功",
});
} catch (error) {
console.log(error);
}
setTimeout(() => {
this.formLoading = false;
}, 500);
}
});
},
handleSuccess(response, file, fileList) {
// const uid = file.uid
// const id = response.id
// this.files.push({ uid, id })
console.log("上传成功", response);
this.files = response.data;
},
handleBeforeRemove(file, fileList) {
for (let i = 0; i < this.files.length; i++) {
if (this.files[i].uid === file.uid) {
crudQiNiu.del([this.files[i].id]).then((res) => {});
return true;
}
}
},
handlePictureCardPreview(file) {
this.dialogImageUrl = file.url;
this.dialogVisible = true;
},
// 监听上传失败
handleError(e, file, fileList) {
const msg = JSON.parse(e.message);
this.crud.notify(msg.message, CRUD.NOTIFICATION_TYPE.ERROR);
},
// 刷新列表数据
doSubmit() {
this.fileList = [];
this.showUpload = false;
switch (this.uploadIndex) {
case 1:
this.form.logo = this.files[0];
break;
case 2:
this.form.coverImg = this.files[0];
break;
case 3:
this.form.shopQrcode = this.files[0];
break;
default:
break;
}
},
},
};
</script>
<style scoped lang="scss">
.img_box {
display: flex;
align-items: flex-end;
gap: 20px;
padding-bottom: 20px;
}
.map_box {
width: 100%;
position: relative;
.map {
height: 300px;
}
.search_box {
position: absolute;
top: 10px;
left: 10px;
}
.search_wrap {
padding: 6px 0;
.item {
display: flex;
padding: 12px 0;
.left {
flex: 1;
display: flex;
flex-direction: column;
padding-right: 20px;
.location {
color: #999;
padding-top: 4px;
}
}
}
}
}
</style>