nailart/na-frontend/src/pages/HomePage.vue

440 lines
12 KiB
Vue
Raw Normal View History

<template>
2025-07-29 14:51:28 +08:00
<div class="homepage">
<!-- 固定顶部导航栏 -->
<NavBar class="nav-bar" />
<div class="images">
2025-08-18 00:04:55 +08:00
<van-swipe class="swipe" :autoplay="2000" indicator-color="white">
<van-swipe-item v-for="(image, index) in info.headImgs" :key="index">
<img fill="contain" v-lazy="image.url" />
</van-swipe-item>
</van-swipe>
</div>
2025-07-29 14:51:28 +08:00
<div class="info">
2025-08-18 00:04:55 +08:00
<div class="title">
<div class="name">{{ info.name }}</div>
<div class="environment" @click="showEnvironmentPopup = true">
<span>查看店内环境</span>
</div>
</div>
<van-divider />
<div class="worktime">
<div>{{ info.status }} {{ info.worktime }}</div>
</div>
<van-divider />
<div class="location">
<div class="left">
<span style="color: black; font-size: 15px;">{{ info.location }}</span>
<br>
<van-icon name="location-o" size="12" />
<span>距您驾车或者打车8.0公里 需10分钟</span>
<br>
<van-icon name="guide-o" size="12" />
<span>距离1号线微电园站1号口步行400米 需8分钟</span>
</div>
<div class="right">
<van-icon name="wechat" size="25" @click="clickWechatAndPhone('wechat')" />
<van-icon name="phone" size="25" @click="clickWechatAndPhone('phone')" />
</div>
</div>
2025-07-29 14:51:28 +08:00
</div>
2025-08-18 00:04:55 +08:00
<van-divider>新品展示</van-divider>
2025-07-29 14:51:28 +08:00
<div class="new">
2025-08-18 00:04:55 +08:00
<van-swipe class="swipe" :autoplay="2000" indicator-color="white">
<van-swipe-item v-for="(image, index) in info.newPortfolioImgs" :key="index">
<img fill="contain" v-lazy="image.url" />
</van-swipe-item>
</van-swipe>
2025-07-29 14:51:28 +08:00
</div>
2025-08-18 00:04:55 +08:00
<van-popup v-model="showEnvironmentPopup" position="bottom" closeable style="height: 50vh;">
<div class="environment-images">
<van-swipe class="swipe" :autoplay="2000" indicator-color="white">
<van-swipe-item v-for="(image, index) in info.environmentImgs" :key="index">
<img fill="contain" v-lazy="image.url" />
</van-swipe-item>
</van-swipe>
</div>
</van-popup>
<van-overlay :show="showpublicityImg" @click="show = false">
<div class="wrapper" @click.stop>
<div class="block">
<img v-lazy="info.publicityImg.length > 0 ? info.publicityImg[0].url : ''" />
<div class="coress">
<van-icon name="add" @click="showpublicityImg = false" size="24" style="transform: rotate(45deg)"
color="white" />
</div>
</div>
</div>
</van-overlay>
<div style="height: 200px;"></div>
2025-07-29 14:51:28 +08:00
<!-- 固定底部TabBar -->
<TabBar class="tab-bar" />
</div>
2025-08-18 00:04:55 +08:00
</template>
<script>
2025-07-29 14:51:28 +08:00
import TabBar from '@/components/TabBar.vue';
import NavBar from '@/components/NavBar.vue';
export default {
name: 'HomePage',
components: {
2025-07-29 14:51:28 +08:00
TabBar,
NavBar
},
props: {},
data() {
return {
2025-08-18 00:04:55 +08:00
info: {
id: 1,
headImgs: [],
guide: '距离1号线微电园站1号口步行400米 需8分钟',
wechat: '',
phone: '',
newPortfolioImgs: [],
locationImgs: [],
environmentImgs: [
2025-07-29 14:51:28 +08:00
2025-08-18 00:04:55 +08:00
],
publicityImg: [],
status: ""
},
storageUrl: 'http://xiaowangnas.com:9000/yumiartnail',
showEnvironmentPopup: false,
showpublicityImg: false,
};
},
watch: {},
computed: {},
2025-08-18 00:04:55 +08:00
methods: {
async getInfo() {
const res = await this.$axios.get('/mainInfo/getMainInfo');
if (res.code == 200) {
this.id = res.data.id;
this.info.headImgs = this.convertToObjectArray(res.data.headImg.split('&&'));
this.info.name = res.data.name;
this.info.status = res.data.status == 0 ? '休息中' : '营业中';
this.info.worktime = res.data.worktime;
this.info.location = res.data.address;
this.info.wechat = res.data.wechat;
this.info.phone = res.data.phone;
this.info.locationImgs = this.convertToObjectArray(res.data.locationImg.split('&&'));
this.info.newPortfolioImgs = this.convertToObjectArray(res.data.newPortfolioImg.split('&&'));
this.info.environmentImgs = this.convertToObjectArray(res.data.environmentImg.split('&&'));
this.info.publicityImg = [{ url: this.storageUrl + res.data.publicityImg }];
}
if (this.info.publicityImg.length > 0) {
this.showpublicityImg = true;
} else {
this.showpublicityImg = false;
}
console.log(this.info);
},
convertToObjectArray(urls) {
return urls.map(url => {
if (!url) return { url: '' }; // 处理空字符串
const modifiedUrl = this.storageUrl + url;
return { url: modifiedUrl }
});
},
convertUrlsToString(arr) {
return arr.map(item => {
let modifiedUrl = item.url.replace(this.storageUrl, '');
return modifiedUrl;
}).join('&&');
},
clickWechatAndPhone(type) {
this.$dialog.confirm({
title: type == 'wechat' ? '微信号' : '电话号码',
message: type == 'wechat' ? this.info.wechat : this.info.phone,
confirmButtonText: '一键复制',
})
.then(() => {
this.textToCopy = type == 'wechat' ? this.info.wechat : this.info.phone;
this.handleCopy();
})
.catch(() => {
// on cancel
});
},
async handleCopy() {
try {
// 首先检查是否支持navigator.clipboard
if (navigator.clipboard) {
// 请求剪贴板写入权限(适用于需要权限的浏览器)
if ('permissions' in navigator) {
const permissionStatus = await navigator.permissions.query({ name: 'clipboard-write' });
if (permissionStatus.state === 'granted' || (permissionStatus.state === 'prompt' && await permissionStatus.request() === 'granted')) {
await navigator.clipboard.writeText(this.textToCopy);
this.$toast.success('已复制到剪贴板');
} else {
console.error('未获得剪贴板写入权限');
this.$toast.fail('未获得剪贴板写入权限,请手动复制');
}
} else {
// 如果不需要权限请求,直接复制
await navigator.clipboard.writeText(this.textToCopy);
this.$toast.success('已复制到剪贴板');
}
} else {
// 如果不支持navigator.clipboard尝试使用document.execCommand旧方法兼容性更好但有局限性
const textArea = document.createElement('textarea');
textArea.value = this.textToCopy;
document.body.appendChild(textArea);
textArea.select();
try {
document.execCommand('copy');
this.$toast.success('已复制到剪贴板');
} catch (err) {
console.error('复制失败:', err);
this.$toast.fail('复制失败,请手动复制');
}
document.body.removeChild(textArea);
}
} catch (err) {
console.error('复制失败:', err);
this.$toast.fail('复制失败,请手动复制');
}
},
// 记录当前时间到localStorage
recordCurrentTime(storageKey = 'recordedTime') {
// 获取当前时间的时间戳(毫秒)
const currentTime = new Date().getTime();
// 存储到localStorage
localStorage.setItem(storageKey, currentTime.toString());
return currentTime;
},
// 从localStorage获取记录的时间并计算与当前时间的差值
getTimeDifference(storageKey = 'recordedTime') {
// 从localStorage获取记录的时间
const storedTimeStr = localStorage.getItem(storageKey);
// 检查是否存在记录
if (!storedTimeStr) {
console.error('没有找到记录的时间');
return null;
}
// 转换为数字类型
const storedTime = parseInt(storedTimeStr, 10);
// 检查转换是否成功
if (isNaN(storedTime)) {
console.error('存储的时间格式不正确');
return null;
}
// 获取当前时间戳
const currentTime = new Date().getTime();
// 计算差值(毫秒)并转换为秒
const differenceInSeconds = Math.floor((currentTime - storedTime) / 1000);
return differenceInSeconds;
}
},
created() {
// 检查是否有记录的时间
const recordedTime = localStorage.getItem('recordedTime');
if (recordedTime) {
// 如果有记录的时间,计算与当前时间的差值
const timeDifference = this.getTimeDifference();
console.log(`与上次记录的时间差为 ${timeDifference}`);
if (timeDifference >= 60 * 60 * 24) {
// 超过24小时执行相应操作
this.recordCurrentTime();
this.showpublicityImg = true;
} else {
// 在24小时内执行相应操作
console.log('在24小时内');
this.showpublicityImg = false;
}
} else {
console.log('没有找到记录的时间');
}
},
mounted() {
this.getInfo();
},
beforeDestroy() {
// 在组件销毁前,可以清理一些资源或状态
this.showEnvironmentPopup = false;
this.showpublicityImg = false;
this.recordCurrentTime();
}
};
</script>
<style lang="less" scoped>
2025-08-18 00:04:55 +08:00
@base-bg: #f9fafb;
@card-bg: white;
@text-primary: #1f2937;
@text-secondary: #6b7280;
@accent-color: #3b82f6;
@accent-dark: #2563eb;
@danger-color: #ef4444;
@gray-light: #d1d5db;
@shadow-base: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
@shadow-active: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
.homepage {
width: 100vw;
2025-07-29 14:51:28 +08:00
height: 100vh;
overflow: auto;
2025-08-18 00:04:55 +08:00
max-width: 800px;
margin: 0 auto;
2025-07-29 14:51:28 +08:00
.images {
width: 100%;
2025-08-18 00:04:55 +08:00
height: 35vh;
overflow: hidden;
min-height: 200px;
max-height: 500px;
.swipe {
width: 100%;
height: 100%;
img {
width: 100%;
height: 100%;
}
}
2025-07-29 14:51:28 +08:00
}
.info {
width: 100%;
2025-08-18 00:04:55 +08:00
padding: 10px;
.title {
display: flex;
justify-content: space-between;
align-items: center;
.name {
font-size: 40px;
color: @text-primary;
font-weight: bold;
cursor: pointer;
}
.environment {
cursor: pointer;
span {
font-size: 12px;
color: #525050;
}
}
}
.location {
display: flex;
.left {
width: 70%;
span {
font-size: 12px;
color: #a19e9e;
margin-bottom: 10px;
}
}
.right {
width: 30%;
display: flex;
justify-content: space-evenly;
align-items: center;
color: #a19e9e;
}
}
2025-07-29 14:51:28 +08:00
}
.new {
2025-08-18 00:04:55 +08:00
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
width: 95%;
height: 25vh;
overflow: hidden;
min-height: 200px;
max-height: 500px;
margin: auto;
border-radius: 10px;
.swipe {
width: 100%;
height: 100%;
img {
width: 100%;
height: 100%;
}
}
2025-07-29 14:51:28 +08:00
}
.navigation {
width: 100%;
}
2025-08-18 00:04:55 +08:00
.environment-images {
width: 100%;
overflow: hidden;
max-height: 500px;
.swipe {
width: 100%;
height: 100%;
img {
width: 100%;
height: 100%;
}
}
}
.wrapper {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
position: relative;
width: 100%;
.block {
padding: 10px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
img {
width: 100%;
object-fit: contain;
border-radius: 10px;
}
.coress {
padding-top: 20px;
}
}
}
2025-07-29 14:51:28 +08:00
}
</style>