This commit is contained in:
Your Name
2026-03-01 14:17:59 +08:00
parent 65aa12f146
commit a07e844c47
6071 changed files with 777651 additions and 0 deletions
@@ -0,0 +1,158 @@
<template>
<!-- modal:隐私授权弹窗-->
<view v-if="show" class="modal-box" @tap.stop>
<view class="dialog" @tap.stop>
<view class="title">隐私政策提示</view>
<view class="content">
欢迎使用{{
appStore.getWebsiteConfig.shop_name
}}小程序请您在使用前点击
<text
class="text-[#243245]"
hover-class="hover"
@click="openContract"
>
{{ name }}
</text>
并仔细阅读如您同意全部内容请点击同意开始使用我们的服务
</view>
<view class="btn-box">
<button
class="btn disagree"
hover-class="hover"
@click="disagreePrivacy"
>
不同意
</button>
<button
class="btn bg-primary text-white"
hover-class="hover"
id="agree-btn"
open-type="agreePrivacyAuthorization"
@agreeprivacyauthorization="agreePrivacy"
>
同意
</button>
</view>
</view>
</view>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { useAppStore } from '@/stores/app'
const appStore = useAppStore()
const name = ref<string>('')
const show = ref<boolean>(false)
interface PrivacyRes {
errMsg: string
privacyContractName: string
needAuthorization: boolean
}
if (wx.getPrivacySetting) {
wx.getPrivacySetting({
success(res: PrivacyRes) {
console.log(res)
name.value = res.privacyContractName
show.value = res.needAuthorization
}
})
}
const openContract = () => {
wx.openPrivacyContract({
success: () => {},
fail: () => {}
})
}
const disagreeHandle = () => {
// 用户点击拒绝后
show.value = false
}
const disagreePrivacy = () => {
uni.$u.toast('同意隐私政策后可继续使用')
// wx.exitMiniProgram()
}
const agreePrivacy = () => {
show.value = false
}
</script>
<style scoped>
.modal-box {
height: 100vh;
width: 100vw;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.6);
z-index: 99999;
}
.modal-box .dialog {
box-sizing: border-box;
position: absolute;
bottom: 0;
width: 100%;
padding: 40rpx;
padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
background: #ffffff;
border-radius: 20rpx 20rpx 0 0;
}
.modal-box .title {
text-align: center;
color: #333;
font-weight: bold;
font-size: 34rpx;
}
.modal-box .content {
display: block;
font-size: 28rpx;
color: #666;
margin-top: 20rpx;
text-align: justify;
line-height: 1.6;
padding: 10rpx 20rpx;
}
.modal-box .btn-box {
margin-top: 50rpx;
padding: 0 30rpx;
padding-bottom: 30rpx;
display: flex;
text-align: center;
}
.modal-box .btn::after {
border: none;
display: none;
}
.modal-box .btn-box .btn {
width: 50%;
height: 76rpx;
line-height: 76rpx;
margin: 0 10rpx;
padding: 0;
align-items: center;
justify-content: center;
border-radius: 60px;
font-size: 28rpx;
font-weight: 500;
}
.modal-box .disagree {
color: #0f0f0f;
background: #f5f5f5;
}
</style>
+183
View File
@@ -0,0 +1,183 @@
<template>
<page-meta :page-style="$theme.pageStyle">
<!-- #ifndef H5 -->
<navigation-bar
:front-color="$theme.navColor"
:background-color="$theme.navBgColor"
/>
<!-- #endif -->
</page-meta>
<view class="index" :style="pageStyle">
<!-- 组件 -->
<template
v-for="(item, index) in state.pages"
:key="index"
>
<template v-if="item.name == 'search'">
<w-search
:pageMeta="state.meta"
:content="item.content"
:styles="item.styles"
:percent="percent"
:isLargeScreen="isLargeScreen"
/>
</template>
<template v-if="item.name == 'banner'">
<w-banner
:content="item.content"
:styles="item.styles"
:isLargeScreen="isLargeScreen"
@change="handleBanner"
/>
</template>
<template v-if="item.name == 'nav'">
<w-nav :content="item.content" :styles="item.styles"/>
</template>
<template v-if="item.name == 'middle-banner'">
<w-middle-banner :content="item.content" :styles="item.styles" />
</template>
</template>
<view class="article" v-if="state.article.length">
<view
class="flex items-center article-title mx-[20rpx] my-[30rpx] text-lg font-medium"
>
最新资讯
</view>
<news-card
v-for="item in state.article"
:key="item.id"
:news-id="item.id"
:item="item"
/>
</view>
<!-- #ifdef H5 -->
<view class="text-center py-4 mb-12">
<router-navigate
class="mx-1 text-xs text-[#495770]"
:to="{
path: '/pages/webview/webview',
query: {
url: item.value
}
}"
v-for="item in appStore.getCopyrightConfig"
:key="item.key"
>
{{ item.key }}
</router-navigate>
</view>
<!-- #endif -->
<!-- 返回顶部按钮 -->
<u-back-top
:scroll-top="scrollTop"
:top="100"
:customStyle="{
backgroundColor: '#FFF',
color: '#000',
boxShadow: '0px 3px 6px rgba(0, 0, 0, 0.1)'
}"
>
</u-back-top>
<!-- #ifdef MP -->
<!-- 微信小程序隐私弹窗 -->
<MpPrivacyPopup></MpPrivacyPopup>
<!-- #endif -->
<tabbar/>
</view>
</template>
<script setup lang="ts">
import {getIndex} from '@/api/shop'
import {onLoad, onPageScroll} from "@dcloudio/uni-app";
import {computed, reactive, ref} from 'vue'
import {useAppStore} from '@/stores/app'
// #ifdef MP
import MpPrivacyPopup from './component/mp-privacy-popup.vue'
// #endif
const appStore = useAppStore()
const state = reactive<{
pages: any[]
meta: any[]
article: any[]
bannerImage: string
}>({
pages: [],
meta: [],
article: [],
bannerImage: ''
})
const scrollTop = ref<number>(0)
const percent = ref<number>(0)
// 是否联动背景图
const isLinkage = computed(() => {
return state.pages.find((item: any) => item.name === 'banner')?.content.bg_style === 1
})
// 是否大屏banner
const isLargeScreen = computed(() => {
return state.pages.find((item: any) => item.name === 'banner')?.content.style === 2
})
// 根页面样式
const pageStyle = computed(() => {
const {bg_type, bg_color, bg_image} = state.meta[0]?.content ?? {}
if (!isLinkage.value) {
return bg_type == 1 ?
{'background-color': bg_color} :
{'background-image': `url(${bg_image})`}
}
else return {'background-image': `url(${state.bannerImage})`}
})
const handleBanner = (url: string) => {
state.bannerImage = url
}
const getData = async () => {
const data = await getIndex()
state.pages = JSON.parse(data?.page?.data)
state.meta = JSON.parse(data?.page?.meta)
state.article = data.article
uni.setNavigationBarTitle({
title: state.meta[0].content.title
})
}
onPageScroll((event: any) => {
scrollTop.value = event.scrollTop
const top = uni.upx2px(100)
percent.value = event.scrollTop / top > 1 ? 1 : event.scrollTop / top
})
onLoad(() => { getData() })
</script>
<style lang="scss" scoped>
.index {
position: relative;
background-repeat: no-repeat;
background-size: 100% auto;
overflow: hidden;
width: 100%;
transition: all 1s;
min-height: calc(100vh - env(safe-area-inset-bottom));
}
.article-title {
&::before {
content: '';
width: 8rpx;
height: 34rpx;
display: block;
margin-right: 10rpx;
@apply bg-primary;
}
}
</style>