632 lines
20 KiB
Vue
632 lines
20 KiB
Vue
<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>
|