xiangyixiangqin/miniapp/pages/butler/index.vue
2026-03-01 18:09:05 +08:00

317 lines
6.1 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>
<view class="butler-page">
<!-- 页面加载状态 -->
<Loading type="page" :loading="pageLoading" />
<!-- 顶部背景图 -->
<view class="top-bg">
<image src="/static/title_bg.png" mode="aspectFill" class="bg-img" />
</view>
<!-- 自定义导航栏 -->
<view class="custom-navbar" :style="{ paddingTop: statusBarHeight + 'px' }">
<view class="navbar-content">
<view class="navbar-back" @click="handleBack">
<text class="back-icon"></text>
</view>
<text class="navbar-title">联系我们</text>
<view class="navbar-placeholder"></view>
</view>
</view>
<!-- 内容区域 - 可滚动 -->
<scroll-view class="content-area" scroll-y
:style="{ marginTop: (statusBarHeight + 44) + 'px', height: 'calc(100vh - ' + (statusBarHeight + 44) + 'px)' }">
<view class="content-wrapper">
<view class="qrcode-card">
<!-- 二维码图片 -->
<view class="qrcode-wrapper">
<image v-if="butlerQrcode" class="qrcode-img" :src="butlerQrcode" mode="widthFix"
@click="previewQrcode" />
<view v-else class="qrcode-placeholder">
<text>暂无二维码</text>
</view>
</view>
<!-- 保存按钮 -->
<button class="btn-save" @click="saveQrcode" :disabled="!butlerQrcode || saving">
{{ saving ? '保存中...' : '保存图片' }}
</button>
</view>
</view>
</scroll-view>
</view>
</template>
<script setup>
import {
ref,
computed,
onMounted
} from 'vue'
import {
useConfigStore
} from '@/store/config.js'
import {
getFullImageUrl
} from '@/utils/image.js'
import Loading from '@/components/Loading/index.vue'
const configStore = useConfigStore()
// 状态栏高度
const statusBarHeight = ref(20)
// 页面状态
const pageLoading = ref(true)
const saving = ref(false)
// 管家二维码
const butlerQrcode = computed(() => {
const qrcode = configStore.butlerQrcode
return qrcode ? getFullImageUrl(qrcode) : ''
})
// 获取系统信息
const getSystemInfo = () => {
try {
const res = uni.getSystemInfoSync()
statusBarHeight.value = res.statusBarHeight || 20
} catch (error) {
console.error('获取系统信息失败:', error)
}
}
// 返回上一页
const handleBack = () => {
uni.navigateBack()
}
// 预览二维码
const previewQrcode = () => {
if (!butlerQrcode.value) return
uni.previewImage({
urls: [butlerQrcode.value]
})
}
// 保存二维码到相册
const saveQrcode = async () => {
if (!butlerQrcode.value || saving.value) return
saving.value = true
try {
// 先下载图片
const downloadRes = await new Promise((resolve, reject) => {
uni.downloadFile({
url: butlerQrcode.value,
success: resolve,
fail: reject
})
})
if (downloadRes.statusCode !== 200) {
throw new Error('下载图片失败')
}
// 保存到相册
await new Promise((resolve, reject) => {
uni.saveImageToPhotosAlbum({
filePath: downloadRes.tempFilePath,
success: resolve,
fail: (err) => {
// 检查是否是权限问题
if (err.errMsg.includes('auth deny') || err.errMsg.includes(
'authorize')) {
uni.showModal({
title: '提示',
content: '需要您授权保存图片到相册',
confirmText: '去设置',
success: (res) => {
if (res.confirm) {
uni.openSetting()
}
}
})
}
reject(err)
}
})
})
uni.showToast({
title: '保存成功',
icon: 'success'
})
} catch (error) {
console.error('保存图片失败:', error)
if (!error.errMsg?.includes('auth')) {
uni.showToast({
title: '保存失败',
icon: 'none'
})
}
} finally {
saving.value = false
}
}
// 初始化页面
const initPage = async () => {
pageLoading.value = true
try {
getSystemInfo()
// 强制重新加载配置以获取最新的二维码
configStore.isLoaded = false
await configStore.loadAppConfig()
} catch (error) {
console.error('初始化页面失败:', error)
} finally {
pageLoading.value = false
}
}
onMounted(() => {
initPage()
})
</script>
<style lang="scss" scoped>
.butler-page {
height: 100vh;
background-color: #f5f6fa;
overflow: hidden;
}
// 顶部背景图
.top-bg {
position: fixed;
top: 0;
left: 0;
right: 0;
height: 400rpx;
z-index: 0;
.bg-img {
width: 100%;
height: 100%;
}
}
// 自定义导航栏
.custom-navbar {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 100;
.navbar-content {
height: 44px;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 24rpx;
.navbar-back {
width: 80rpx;
height: 80rpx;
display: flex;
align-items: center;
justify-content: center;
.back-icon {
font-size: 56rpx;
color: #333;
font-weight: 300;
}
}
.navbar-title {
font-size: 34rpx;
font-weight: 600;
color: #333;
}
.navbar-placeholder {
width: 80rpx;
}
}
}
// 内容区域
.content-area {
position: relative;
z-index: 1;
}
// 内容包裹层
.content-wrapper {
padding: 40rpx 0 80rpx;
}
// 二维码卡片
.qrcode-card {
background: #fff;
width: 90%;
margin: 0 auto;
border-radius: 24rpx;
padding: 60rpx 0;
display: flex;
flex-direction: column;
align-items: center;
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.05);
}
// 二维码容器
.qrcode-wrapper {
width: 100%;
max-width: 600rpx;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 60rpx;
.qrcode-img {
width: 100%;
display: block;
}
.qrcode-placeholder {
width: 100%;
height: 100%;
background: #f5f5f5;
border-radius: 16rpx;
display: flex;
align-items: center;
justify-content: center;
text {
font-size: 28rpx;
color: #999;
}
}
}
// 保存按钮
.btn-save {
width: 320rpx;
height: 88rpx;
line-height: 88rpx;
background: linear-gradient(135deg, #FFBDC2 0%, #FF8A93 100%);
border-radius: 44rpx;
font-size: 32rpx;
color: #fff;
border: none;
&::after {
border: none;
}
&[disabled] {
opacity: 0.6;
}
}
</style>