Files
lilishop-ui/seller/src/views/main-components/store-qrcode.vue
2026-08-26 10:59:52 +08:00

203 lines
5.6 KiB
Vue

<template>
<div v-if="storeId && (showH5 || showMp)" class="store-qr-group">
<el-popover v-if="showH5" trigger="hover" placement="bottom" :width="220">
<template #reference>
<div class="store-qr-thumb">
<vue-qr v-if="h5Url" :text="h5Url" :margin="0" color-dark="#000" color-light="#fff" :size="40" />
<el-icon v-else class="store-qr-empty"><Picture /></el-icon>
<span>H5</span>
</div>
</template>
<div class="store-qr-panel">
<vue-qr v-if="h5Url" :text="h5Url" :margin="0" color-dark="#000" color-light="#fff" :size="160" />
<div v-else class="store-qr-tip">请先在系统设置中填写 wap 站点地址</div>
<div class="store-qr-title">H5 店铺首页</div>
<el-button v-if="h5Url" size="small" @click="copyText(h5Url)">复制链接</el-button>
</div>
</el-popover>
<el-popover v-if="showMp" trigger="hover" placement="bottom" :width="220">
<template #reference>
<div class="store-qr-thumb">
<img v-if="mpQrSrc" :src="mpQrSrc" width="40" height="40" alt="小程序码" />
<el-icon v-else class="store-qr-empty"><Picture /></el-icon>
<span>小程序</span>
</div>
</template>
<div class="store-qr-panel">
<img v-if="mpQrSrc" :src="mpQrSrc" width="160" height="160" alt="小程序码" />
<div v-else class="store-qr-tip">{{ mpError || "小程序码生成中..." }}</div>
<div class="store-qr-title">小程序店铺首页</div>
<el-button v-if="mpQrSrc" size="small" @click="downloadMp">下载二维码</el-button>
</div>
</el-popover>
</div>
</template>
<script>
import Cookies from "js-cookie";
import vueQr from "vue-qr";
import { Picture } from "@element-plus/icons-vue";
import { getStoreMpQrcode } from "@/api/index";
import { getBaseSite } from "@/api/common.js";
export default {
name: "store-qrcode",
components: { "vue-qr": vueQr, Picture },
data() {
return {
storeId: "",
wapUrl: "",
showH5: false,
showMp: false,
mpQrcode: "",
mpError: "",
};
},
computed: {
h5Url() {
if (!this.storeId || !this.wapUrl) return "";
return `${String(this.wapUrl).replace(/\/$/, "")}/pages/product/shopPage?id=${this.storeId}`;
},
mpQrSrc() {
return this.mpQrcode ? `data:image/png;base64,${this.mpQrcode}` : "";
},
},
mounted() {
this.initStore();
this.loadSiteSetting();
},
methods: {
initStore() {
try {
const userInfo = JSON.parse(Cookies.get("userInfoSeller") || "{}") || {};
this.storeId = userInfo.id || userInfo.storeId || "";
} catch (e) {
this.storeId = "";
}
},
parseSettingValue(raw) {
if (!raw) return {};
if (typeof raw === "object") return raw;
try {
return JSON.parse(raw);
} catch (e) {
return {};
}
},
loadSiteSetting() {
getBaseSite()
.then((res) => {
if (!res || !res.success || !res.result) return;
const data = this.parseSettingValue(res.result.settingValue || res.result);
this.showH5 = data.showStoreH5Address === true;
this.showMp = data.showStoreMpAddress === true;
this.wapUrl =
data.staticPageWapAddress ||
(typeof window !== "undefined" && window.BASE && window.BASE.WAP_URL) ||
"";
if (this.showMp) {
this.loadMpQrcode();
}
})
.catch(() => {
this.showH5 = false;
this.showMp = false;
});
},
loadMpQrcode() {
if (!this.storeId) return;
getStoreMpQrcode()
.then((res) => {
if (res && res.success && res.result) {
if (String(res.result).startsWith("eyJ")) {
this.mpError = "请先配置微信小程序";
return;
}
this.mpQrcode = res.result;
this.mpError = "";
} else {
this.mpError = (res && res.message) || "小程序码生成失败";
}
})
.catch(() => {
this.mpError = "请先配置微信小程序";
});
},
copyText(text) {
if (!text) return;
const textArea = document.createElement("textarea");
textArea.value = text;
document.body.appendChild(textArea);
textArea.focus();
textArea.select();
try {
document.execCommand("copy");
this.$Message.success("复制成功");
} catch (e) {
this.$Message.error("复制失败");
}
document.body.removeChild(textArea);
},
downloadMp() {
if (!this.mpQrSrc) return;
const link = document.createElement("a");
link.href = this.mpQrSrc;
link.download = "店铺小程序码.png";
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
},
},
};
</script>
<style scoped lang="scss">
.store-qr-group {
display: inline-flex;
align-items: center;
gap: 12px;
margin-right: 16px;
}
.store-qr-thumb {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
cursor: pointer;
line-height: 1.2;
span {
margin-top: 2px;
font-size: 12px;
color: #666;
}
}
.store-qr-empty {
width: 40px;
height: 40px;
font-size: 22px;
color: #ccc;
}
.store-qr-panel {
display: flex;
flex-direction: column;
align-items: center;
gap: 8px;
padding: 4px 0;
}
.store-qr-title {
font-size: 13px;
color: #333;
}
.store-qr-tip {
width: 160px;
min-height: 80px;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
font-size: 12px;
color: #999;
}
</style>