fix: 协议勾选控制+news详情页样式修复+支付页重做
This commit is contained in:
@@ -9,72 +9,111 @@
|
||||
<view class="nav-placeholder"></view>
|
||||
</view>
|
||||
|
||||
<!-- 头部 -->
|
||||
<view class="payment-header">
|
||||
<text class="header-title">解锁 AI 维度 Pro</text>
|
||||
<text class="header-desc">无限 AI 问答 · 全量知识解锁 · 每日趋势优先推送</text>
|
||||
</view>
|
||||
|
||||
<!-- 方案选择 -->
|
||||
<view class="plan-selector">
|
||||
<view
|
||||
class="plan-tag"
|
||||
:class="{ active: selectedPlan === 'pro' }"
|
||||
@click="selectedPlan = 'pro'"
|
||||
>
|
||||
<text class="plan-name">Pro</text>
|
||||
<text class="plan-price">¥19.9<span class="unit">/月</span></text>
|
||||
<text class="plan-badge">推荐</text>
|
||||
<scroll-view scroll-y class="scroll-area">
|
||||
<!-- 头部 -->
|
||||
<view class="payment-header">
|
||||
<view class="header-icon-wrap">
|
||||
<text class="header-icon">✦</text>
|
||||
</view>
|
||||
<text class="header-title">解锁 AI 维度 Pro</text>
|
||||
<text class="header-desc">无限 AI 问答 · 全量知识 · 趋势优先推送</text>
|
||||
</view>
|
||||
<view
|
||||
class="plan-tag vip"
|
||||
:class="{ active: selectedPlan === 'vip' }"
|
||||
@click="selectedPlan = 'vip'"
|
||||
>
|
||||
<text class="plan-name">VIP</text>
|
||||
<text class="plan-price">¥39.9<span class="unit">/月</span></text>
|
||||
<text class="plan-desc">含 Pro 全部权益</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 权益对比 -->
|
||||
<view class="benefits">
|
||||
<view class="benefit-item" v-for="(item, idx) in benefits" :key="idx">
|
||||
<text class="b-icon">{{ item.icon }}</text>
|
||||
<text class="b-text">{{ item.text }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 套餐选择 -->
|
||||
<view class="duration-section">
|
||||
<text class="duration-title">选择套餐</text>
|
||||
<view class="duration-list">
|
||||
<!-- 方案选择卡片 -->
|
||||
<view class="plan-selector">
|
||||
<view
|
||||
class="duration-item"
|
||||
:class="{ active: selectedDuration === item.key }"
|
||||
v-for="item in durations"
|
||||
:key="item.key"
|
||||
@click="selectedDuration = item.key"
|
||||
class="plan-card"
|
||||
:class="{ active: selectedPlan === 'pro' }"
|
||||
@click="selectedPlan = 'pro'"
|
||||
>
|
||||
<text class="d-label">{{ item.label }}</text>
|
||||
<text class="d-price">¥{{ item.price }}</text>
|
||||
<text class="d-save" v-if="item.save">省 {{ item.save }}</text>
|
||||
<view class="plan-top">
|
||||
<text class="plan-name">Pro</text>
|
||||
<view class="plan-badge" v-if="selectedPlan === 'pro'">推荐</view>
|
||||
</view>
|
||||
<text class="plan-price">¥19.9</text>
|
||||
<text class="plan-unit">/ 月</text>
|
||||
<view class="plan-features">
|
||||
<text class="plan-feature">✓ AI 问答无限次</text>
|
||||
<text class="plan-feature">✓ 全量知识解锁</text>
|
||||
<text class="plan-feature">✓ 收藏无限容量</text>
|
||||
</view>
|
||||
</view>
|
||||
<view
|
||||
class="plan-card vip"
|
||||
:class="{ active: selectedPlan === 'vip' }"
|
||||
@click="selectedPlan = 'vip'"
|
||||
>
|
||||
<view class="plan-top">
|
||||
<text class="plan-name">VIP</text>
|
||||
<view class="plan-badge vip-badge" v-if="selectedPlan === 'vip'">尊享</view>
|
||||
</view>
|
||||
<text class="plan-price vip-price">¥39.9</text>
|
||||
<text class="plan-unit">/ 月</text>
|
||||
<view class="plan-features">
|
||||
<text class="plan-feature">✓ 含 Pro 全部权益</text>
|
||||
<text class="plan-feature">✓ 专属客服支持</text>
|
||||
<text class="plan-feature">✓ 专属会员标识</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 支付按钮 -->
|
||||
<view class="pay-section">
|
||||
<button class="pay-btn" :loading="loading" @click="handlePay">
|
||||
立即支付 ¥{{ currentPrice }}
|
||||
</button>
|
||||
<text class="pay-agreement">
|
||||
点击支付即同意《用户协议》和《隐私政策》
|
||||
</text>
|
||||
</view>
|
||||
<!-- 套餐时长 -->
|
||||
<view class="duration-section">
|
||||
<text class="section-title">选择套餐</text>
|
||||
<view class="duration-list">
|
||||
<view
|
||||
class="duration-item"
|
||||
:class="{ active: selectedDuration === item.key }"
|
||||
v-for="item in durationOptions"
|
||||
:key="item.key"
|
||||
@click="selectedDuration = item.key"
|
||||
>
|
||||
<text class="d-label">{{ item.label }}</text>
|
||||
<text class="d-price">¥{{ item.price }}</text>
|
||||
<text class="d-save" v-if="item.save">省 {{ item.save }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 底部 -->
|
||||
<text class="footer-text">如有问题请联系客服 · 支持 7 天无理由退款</text>
|
||||
<!-- 权益清单 -->
|
||||
<view class="benefits-section">
|
||||
<text class="section-title">权益对比</text>
|
||||
<view class="benefits-card">
|
||||
<view
|
||||
class="benefit-row"
|
||||
v-for="(item, idx) in benefitList"
|
||||
:key="idx"
|
||||
>
|
||||
<view class="benefit-left">
|
||||
<text class="benefit-icon">{{ item.icon }}</text>
|
||||
<text class="benefit-text">{{ item.text }}</text>
|
||||
</view>
|
||||
<view class="benefit-check">
|
||||
<text class="check-mark" :class="{ 'pro-only': item.proOnly, 'vip-only': !item.proOnly }">
|
||||
{{ item.proOnly ? 'Pro' : (item.hasPro ? 'Pro+VIP' : 'VIP') }}
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 支付按钮 -->
|
||||
<view class="pay-section">
|
||||
<button
|
||||
class="pay-btn"
|
||||
:loading="loading"
|
||||
:disabled="loading"
|
||||
@click="handlePay"
|
||||
>
|
||||
<text class="pay-btn-text">立即支付 ¥{{ currentPrice }}</text>
|
||||
</button>
|
||||
<text class="pay-agreement">
|
||||
点击支付即表示同意《用户协议》和《隐私政策》
|
||||
</text>
|
||||
</view>
|
||||
|
||||
<view class="footer-spacer"></view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
@@ -85,32 +124,28 @@ import { useUserStore } from '@/stores/user'
|
||||
|
||||
const userStore = useUserStore()
|
||||
|
||||
// 方案
|
||||
const selectedPlan = ref('pro')
|
||||
|
||||
// 套餐时长
|
||||
const durations = ref([
|
||||
{ key: 'pro-monthly', label: 'Pro 月付', price: 19.9 },
|
||||
{ key: 'pro-quarterly', label: 'Pro 季付', price: 49.9, save: '省 ¥10' },
|
||||
{ key: 'vip-monthly', label: 'VIP 月付', price: 39.9 },
|
||||
{ key: 'vip-quarterly', label: 'VIP 季付', price: 99.9, save: '省 ¥20' }
|
||||
])
|
||||
|
||||
const selectedDuration = ref('pro-monthly')
|
||||
|
||||
// 权益
|
||||
const benefits = ref([
|
||||
{ icon: '🤖', text: 'AI 问答无限次' },
|
||||
{ icon: '📚', text: '全量知识内容解锁' },
|
||||
{ icon: '📡', text: '每日趋势优先推送' },
|
||||
{ icon: '⭐', text: '收藏夹无限容量' },
|
||||
{ icon: '🎁', text: '专属会员标识' },
|
||||
{ icon: '💬', text: '专属客服支持' }
|
||||
const durationOptions = computed(() => {
|
||||
const isPro = selectedPlan.value === 'pro'
|
||||
return [
|
||||
{ key: isPro ? 'pro-monthly' : 'vip-monthly', label: '月付', price: isPro ? 19.9 : 39.9 },
|
||||
{ key: isPro ? 'pro-quarterly' : 'vip-quarterly', label: '季付', price: isPro ? 49.9 : 99.9, save: isPro ? '¥10' : '¥20' }
|
||||
]
|
||||
})
|
||||
|
||||
const benefitList = ref([
|
||||
{ icon: '🤖', text: 'AI 问答无限次', proOnly: true, hasPro: true },
|
||||
{ icon: '📚', text: '全量知识内容解锁', proOnly: true, hasPro: true },
|
||||
{ icon: '📡', text: '每日趋势优先推送', proOnly: true, hasPro: true },
|
||||
{ icon: '⭐', text: '收藏夹无限容量', proOnly: true, hasPro: true },
|
||||
{ icon: '💬', text: '专属客服支持', proOnly: false, hasPro: false },
|
||||
{ icon: '🎁', text: '专属会员标识', proOnly: false, hasPro: false }
|
||||
])
|
||||
|
||||
// 当前价格
|
||||
const currentPrice = computed(() => {
|
||||
const item = durations.value.find(d => d.key === selectedDuration.value)
|
||||
const item = durationOptions.value.find(d => d.key === selectedDuration.value)
|
||||
return item ? item.price : 19.9
|
||||
})
|
||||
|
||||
@@ -122,24 +157,14 @@ async function handlePay() {
|
||||
return
|
||||
}
|
||||
|
||||
// 找到对应的 productId
|
||||
const productMap = {
|
||||
'pro-monthly': 'pro-monthly',
|
||||
'pro-quarterly': 'pro-quarterly',
|
||||
'vip-monthly': 'vip-monthly',
|
||||
'vip-quarterly': 'vip-quarterly'
|
||||
}
|
||||
const productId = selectedDuration.value
|
||||
|
||||
loading.value = true
|
||||
try {
|
||||
// 调用后端创建订单
|
||||
const data = await paymentApi.createOrder(productMap[selectedDuration.value], userStore.token)
|
||||
|
||||
// 获取微信支付参数
|
||||
const data = await paymentApi.createOrder(productId, userStore.token)
|
||||
const payParam = data.payParams || data.wechatParam || data.paymentData
|
||||
|
||||
if (payParam) {
|
||||
// 调起微信支付
|
||||
uni.requestPayment({
|
||||
provider: 'wxpay',
|
||||
timeStamp: payParam.timeStamp || payParam.timestamp,
|
||||
@@ -154,7 +179,7 @@ async function handlePay() {
|
||||
}, 1500)
|
||||
},
|
||||
fail: (err) => {
|
||||
if (err.errMsg.includes('cancel')) {
|
||||
if (err.errMsg && err.errMsg.includes('cancel')) {
|
||||
uni.showToast({ title: '已取消支付', icon: 'none' })
|
||||
} else {
|
||||
uni.showToast({ title: '支付失败,请重试', icon: 'none' })
|
||||
@@ -179,19 +204,20 @@ function goBack() {
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.page-payment {
|
||||
min-height: 100vh;
|
||||
padding: 0 20px;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: var(--bg-primary);
|
||||
}
|
||||
|
||||
.status-bar-placeholder { height: 44px; }
|
||||
|
||||
// 导航
|
||||
.nav-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 12px 0;
|
||||
padding: 12px 20px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.nav-back {
|
||||
@@ -214,23 +240,45 @@ function goBack() {
|
||||
width: 30px;
|
||||
}
|
||||
|
||||
.scroll-area {
|
||||
flex: 1;
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
// 头部
|
||||
.payment-header {
|
||||
text-align: center;
|
||||
padding: 10px 0 20px;
|
||||
padding: 10px 0 24px;
|
||||
}
|
||||
|
||||
.header-icon-wrap {
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
border-radius: 16px;
|
||||
background: linear-gradient(135deg, var(--dim1-color), var(--dim3-color));
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin: 0 auto 16px;
|
||||
box-shadow: 0 8px 24px rgba(99,102,241,0.25);
|
||||
}
|
||||
|
||||
.header-icon {
|
||||
font-size: 28px;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.header-title {
|
||||
font-size: 22px;
|
||||
font-size: 24px;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
display: block;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.header-desc {
|
||||
font-size: 12px;
|
||||
font-size: 13px;
|
||||
color: var(--text-tertiary);
|
||||
margin-top: 6px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
@@ -238,181 +286,235 @@ function goBack() {
|
||||
.plan-selector {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
margin-bottom: 20px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.plan-tag {
|
||||
.plan-card {
|
||||
flex: 1;
|
||||
padding: 16px;
|
||||
padding: 20px 16px;
|
||||
background: var(--glass-bg);
|
||||
border: 1px solid var(--glass-border);
|
||||
border-radius: 14px;
|
||||
text-align: center;
|
||||
border: 1.5px solid var(--glass-border);
|
||||
border-radius: 16px;
|
||||
position: relative;
|
||||
transition: all 0.3s;
|
||||
|
||||
&.active {
|
||||
border-color: var(--dim1-color);
|
||||
box-shadow: 0 0 0 1px rgba(99,102,241,0.2), 0 8px 24px rgba(99,102,241,0.1);
|
||||
background: linear-gradient(135deg, rgba(99,102,241,0.06), rgba(99,102,241,0.02));
|
||||
}
|
||||
|
||||
&.vip.active {
|
||||
border-color: #ffa726;
|
||||
box-shadow: 0 0 0 1px rgba(255,167,38,0.2), 0 8px 24px rgba(255,167,38,0.1);
|
||||
background: linear-gradient(135deg, rgba(255,167,38,0.06), rgba(255,167,38,0.02));
|
||||
}
|
||||
}
|
||||
|
||||
.plan-tag.active {
|
||||
background: linear-gradient(135deg, rgba(124, 77, 255, 0.15), rgba(0, 0, 0, 0.2));
|
||||
border-color: rgba(124, 77, 255, 0.3);
|
||||
}
|
||||
|
||||
.plan-tag.vip.active {
|
||||
background: linear-gradient(135deg, rgba(255, 152, 0, 0.15), rgba(0, 0, 0, 0.2));
|
||||
border-color: rgba(255, 152, 0, 0.3);
|
||||
.plan-top {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.plan-name {
|
||||
font-size: 18px;
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
display: block;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.plan-price {
|
||||
font-size: 24px;
|
||||
font-weight: 700;
|
||||
color: var(--dim1-color);
|
||||
display: block;
|
||||
}
|
||||
|
||||
.plan-tag.vip .plan-price {
|
||||
color: #ffa726;
|
||||
}
|
||||
|
||||
.unit {
|
||||
font-size: 12px;
|
||||
color: var(--text-tertiary);
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.plan-badge {
|
||||
position: absolute;
|
||||
top: -8px;
|
||||
right: 12px;
|
||||
background: linear-gradient(135deg, #ff9800, #ff5722);
|
||||
color: white;
|
||||
font-size: 10px;
|
||||
font-weight: 600;
|
||||
padding: 2px 10px;
|
||||
border-radius: 10px;
|
||||
background: linear-gradient(135deg, var(--dim1-color), #7c4dff);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.plan-desc {
|
||||
font-size: 11px;
|
||||
color: var(--text-muted);
|
||||
margin-top: 4px;
|
||||
display: block;
|
||||
.vip-badge {
|
||||
background: linear-gradient(135deg, #ffa726, #ff7043);
|
||||
}
|
||||
|
||||
// 权益
|
||||
.benefits {
|
||||
background: var(--glass-bg);
|
||||
border: 1px solid var(--glass-border);
|
||||
border-radius: 14px;
|
||||
padding: 16px;
|
||||
margin-bottom: 20px;
|
||||
.plan-price {
|
||||
font-size: 28px;
|
||||
font-weight: 700;
|
||||
color: var(--dim1-color);
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.benefit-item {
|
||||
.plan-card.vip .plan-price {
|
||||
color: #ffa726;
|
||||
}
|
||||
|
||||
.plan-unit {
|
||||
font-size: 12px;
|
||||
color: var(--text-tertiary);
|
||||
margin-left: 2px;
|
||||
}
|
||||
|
||||
.plan-features {
|
||||
margin-top: 14px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 8px 0;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.benefit-item:not(:last-child) {
|
||||
border-bottom: 1px solid var(--glass-border);
|
||||
}
|
||||
|
||||
.b-icon { font-size: 16px; }
|
||||
|
||||
.b-text {
|
||||
font-size: 13px;
|
||||
.plan-feature {
|
||||
font-size: 12px;
|
||||
color: var(--text-secondary);
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
// 套餐时长
|
||||
.duration-section {
|
||||
margin-bottom: 20px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.duration-title {
|
||||
.section-title {
|
||||
font-size: 14px;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
margin-bottom: 10px;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
display: block;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.duration-list {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.duration-item {
|
||||
flex: 1;
|
||||
padding: 12px 8px;
|
||||
padding: 14px 12px;
|
||||
background: var(--glass-bg);
|
||||
border: 1px solid var(--glass-border);
|
||||
border-radius: 12px;
|
||||
border: 1.5px solid var(--glass-border);
|
||||
border-radius: 14px;
|
||||
text-align: center;
|
||||
}
|
||||
transition: all 0.3s;
|
||||
|
||||
.duration-item.active {
|
||||
background: rgba(124, 77, 255, 0.12);
|
||||
border-color: rgba(124, 77, 255, 0.3);
|
||||
&.active {
|
||||
border-color: var(--dim1-color);
|
||||
background: linear-gradient(135deg, rgba(99,102,241,0.1), rgba(99,102,241,0.05));
|
||||
}
|
||||
}
|
||||
|
||||
.d-label {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
font-size: 13px;
|
||||
color: var(--text-secondary);
|
||||
display: block;
|
||||
margin-bottom: 4px;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.d-price {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: var(--dim1-color);
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
display: block;
|
||||
}
|
||||
|
||||
.d-save {
|
||||
font-size: 10px;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
color: #4db6ac;
|
||||
display: block;
|
||||
margin-top: 2px;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
// 权益对比
|
||||
.benefits-section {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.benefits-card {
|
||||
background: var(--glass-bg);
|
||||
border: 1px solid var(--glass-border);
|
||||
border-radius: 14px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.benefit-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 14px 16px;
|
||||
|
||||
&:not(:last-child) {
|
||||
border-bottom: 1px solid var(--glass-border);
|
||||
}
|
||||
}
|
||||
|
||||
.benefit-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.benefit-icon {
|
||||
font-size: 16px;
|
||||
width: 24px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.benefit-text {
|
||||
font-size: 13px;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.benefit-check {
|
||||
.check-mark {
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
padding: 2px 10px;
|
||||
border-radius: 8px;
|
||||
|
||||
&.pro-only {
|
||||
background: rgba(99,102,241,0.1);
|
||||
color: var(--dim1-color);
|
||||
}
|
||||
|
||||
&.vip-only {
|
||||
background: rgba(255,167,38,0.1);
|
||||
color: #ffa726;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 支付
|
||||
.pay-section {
|
||||
margin-top: 20px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.pay-btn {
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
height: 52px;
|
||||
background: linear-gradient(135deg, var(--dim1-color), var(--dim3-color));
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 12px;
|
||||
border-radius: 14px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0 6px 20px rgba(99,102,241,0.3);
|
||||
|
||||
&[disabled] {
|
||||
opacity: 0.6;
|
||||
}
|
||||
}
|
||||
|
||||
.pay-btn-text {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
box-shadow: 0 4px 16px rgba(179, 136, 255, 0.3);
|
||||
}
|
||||
|
||||
.pay-agreement {
|
||||
font-size: 10px;
|
||||
font-size: 11px;
|
||||
color: var(--text-muted);
|
||||
text-align: center;
|
||||
margin-top: 10px;
|
||||
margin-top: 12px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.footer-text {
|
||||
font-size: 10px;
|
||||
color: var(--text-muted);
|
||||
text-align: center;
|
||||
margin-top: 20px;
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
.footer-spacer { height: 40px; }
|
||||
</style>
|
||||
Reference in New Issue
Block a user