first commit
This commit is contained in:
commit
3093b9cbe7
100
index.html
Normal file
100
index.html
Normal file
@ -0,0 +1,100 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>广告投放 - 精准触达您的目标用户</title>
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<div class="logo">自媒体维基</div>
|
||||
<h1>广告投放</h1>
|
||||
<p class="subtitle">在[自媒体维基] - 广告投放,精准触达您的目标用户</p>
|
||||
<p class="subtitle">本页面价格为实时价格,根据访问量实时计算,请截图预定图片后发送给客服</p>
|
||||
</header>
|
||||
|
||||
<div class="ad-restrictions">
|
||||
<h2>广告投放限制说明</h2>
|
||||
<p>为维护网站质量和用户体验,以下类型广告拒绝投放:</p>
|
||||
<ul>
|
||||
<li>医药类广告</li>
|
||||
<li>健康类广告</li>
|
||||
<li>含捆绑的PE类工具</li>
|
||||
<li>含捆绑的U盘类工具</li>
|
||||
<li>游戏类广告 (页游、小程序游戏)</li>
|
||||
<li>金融理财贷款类</li>
|
||||
<li>H.D.D类目广告</li>
|
||||
<li>飞机、梯子等科学上网类型广告</li>
|
||||
<li>付费替换热门网址的链接</li>
|
||||
<li>电子烟类广告(包括雾化、喷雾、可吸、水果味等)*2024年更新</li>
|
||||
</ul>
|
||||
<p class="restriction-note">如有疑问,请联系客服咨询。</p>
|
||||
</div>
|
||||
|
||||
<main>
|
||||
<section class="ad-positions">
|
||||
<!-- 广告位卡片将在这里动态生成 -->
|
||||
</section>
|
||||
|
||||
<section class="ad-stats">
|
||||
<h2>广告效果数据</h2>
|
||||
<div class="stats-grid">
|
||||
<div class="stat-item">
|
||||
<h3>平均点击率</h3>
|
||||
<p>3.5%</p>
|
||||
</div>
|
||||
<div class="stat-item">
|
||||
<h3>上月曝光量</h3>
|
||||
<p>1,200,000+</p>
|
||||
</div>
|
||||
<div class="stat-item">
|
||||
<h3>客户满意度</h3>
|
||||
<p>98%</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="contact">
|
||||
<h2>联系我们</h2>
|
||||
<div class="contact-info">
|
||||
<div class="wechat-contact">
|
||||
<div class="wechat-qrcode">
|
||||
<img src="https://mtq.jicelue.com/wp-content/uploads/2024/02/20240229213759714.webp" alt="微信二维码">
|
||||
</div>
|
||||
<p class="wechat-id">扫描上方微信号:zx0899999 添加时请务必备注“自媒体导航广告”</p>
|
||||
</div>
|
||||
<!-- <p>客服QQ:123456789</p>
|
||||
<p>客服微信:adservice</p>
|
||||
<p>联系电话:400-123-4567</p>
|
||||
<p>联系邮箱:ad@example.com</p> -->
|
||||
</div>
|
||||
<form class="contact-form">
|
||||
<!-- <input type="text" placeholder="您的姓名" required>
|
||||
<input type="email" placeholder="您的邮箱" required>
|
||||
<input type="tel" placeholder="联系电话">
|
||||
<textarea placeholder="您的需求" required></textarea>
|
||||
<button type="submit">提交咨询</button> -->
|
||||
</form>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<!-- 图片预览模态框 -->
|
||||
<div class="preview-modal" id="previewModal">
|
||||
<div class="preview-modal-content">
|
||||
<span class="preview-close">×</span>
|
||||
<img src="" alt="广告位预览" class="preview-modal-img">
|
||||
<div class="preview-modal-info">
|
||||
<div class="preview-modal-title"></div>
|
||||
<div class="preview-modal-dimensions"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer>
|
||||
<p>© 2025 自媒体维基. All rights reserved.</p>
|
||||
</footer>
|
||||
|
||||
<script src="script.js"></script>
|
||||
</body>
|
||||
</html>
|
152
readme.md
Normal file
152
readme.md
Normal file
@ -0,0 +1,152 @@
|
||||
# 自媒体维基广告投放页面
|
||||
|
||||
## 项目简介
|
||||
这是一个基于访问量动态定价的广告投放系统,专为自媒体维基网站设计。系统能够根据网站实时访问量自动调整广告位价格,为广告主提供透明、公平的广告投放服务。
|
||||
|
||||
## 技术架构
|
||||
### 前端技术栈
|
||||
- HTML5:页面结构
|
||||
- CSS3:样式设计
|
||||
- JavaScript:交互逻辑
|
||||
- WebP:图片格式(优化加载速度)
|
||||
|
||||
### 核心功能模块
|
||||
1. **动态定价系统**
|
||||
- 基于访问量的价格计算
|
||||
- 自动价格更新机制
|
||||
- 多种支付方式支持
|
||||
|
||||
2. **广告位管理**
|
||||
- 多类型广告位支持
|
||||
- 预订状态管理
|
||||
- 图片预览功能
|
||||
|
||||
3. **数据统计**
|
||||
- 实时访问量统计
|
||||
- 价格系数计算
|
||||
- 预订状态追踪
|
||||
|
||||
## 文件结构
|
||||
```
|
||||
project/
|
||||
├── index.html # 主页面
|
||||
├── styles.css # 样式文件
|
||||
├── script.js # 核心逻辑
|
||||
├── info.php # 访问量数据接口(需要自己写一个数据获取API)
|
||||
└── images/ # 图片资源目录
|
||||
```
|
||||
|
||||
## 核心配置说明
|
||||
|
||||
### 1. 广告位配置 (script.js)
|
||||
```javascript
|
||||
const AD_POSITIONS = {
|
||||
'ad-id': {
|
||||
id: 'ad-id', // 广告位唯一标识
|
||||
title: '广告位标题', // 显示标题
|
||||
image: '图片URL', // 预览图片
|
||||
dimensions: '尺寸', // 广告位尺寸
|
||||
prices: {
|
||||
monthly: 价格, // 月付价格
|
||||
yearly: 价格 // 年付价格
|
||||
}
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
### 2. 访问量价格系数 (script.js)
|
||||
```javascript
|
||||
const VISIT_COEFFICIENTS = {
|
||||
'low': { min: 0, max: 30000, coefficient: 0.8 }, // 低访问量,价格打8折
|
||||
'medium': { min: 30001, max: 60000, coefficient: 1 }, // 中等访问量,原价
|
||||
'high': { min: 60001, max: 100000, coefficient: 1.2 }, // 高访问量,价格上浮20%
|
||||
'veryHigh': { min: 100001, max: Infinity, coefficient: 1.5 } // 极高访问量,价格上浮50%
|
||||
};
|
||||
```
|
||||
|
||||
### 3. 预订状态管理 (script.js)
|
||||
```javascript
|
||||
const BOOKED_STATUS = {
|
||||
'ad-id': {
|
||||
isBooked: true/false, // 是否已预订
|
||||
endDate: '到期时间' // ISO格式的到期时间
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
## 维护指南
|
||||
|
||||
### 1. 添加新广告位
|
||||
1. 在 `AD_POSITIONS` 中添加新配置
|
||||
2. 在 `BOOKED_STATUS` 中添加状态管理
|
||||
3. 确保图片资源已上传
|
||||
|
||||
### 2. 修改价格系数
|
||||
1. 编辑 `VISIT_COEFFICIENTS` 对象
|
||||
2. 调整各访问量区间的系数
|
||||
3. 系统会自动应用新的价格计算规则
|
||||
|
||||
### 3. 更新预订状态
|
||||
1. 修改 `BOOKED_STATUS` 中的状态
|
||||
2. 设置 `isBooked` 为 true/false
|
||||
3. 更新 `endDate` 为新的到期时间
|
||||
|
||||
### 4. 图片资源管理
|
||||
1. 使用 WebP 格式优化加载速度
|
||||
2. 图片尺寸建议:
|
||||
- Banner广告:1200×200px
|
||||
- 侧边栏广告:300×600px
|
||||
- 分类页广告:800×150px
|
||||
- 文末广告:600×300px
|
||||
- 网址推荐:800×100px
|
||||
|
||||
## 数据接口说明
|
||||
|
||||
### 访问量数据接口 (info.php)
|
||||
```php
|
||||
// 返回格式
|
||||
{
|
||||
"today_uv": 今日UV,
|
||||
"today_pv": 今日PV,
|
||||
"yesterday_uv": 昨日UV,
|
||||
"yesterday_pv": 昨日PV,
|
||||
"last_month_pv": 上月PV,
|
||||
"last_year_pv": 去年PV
|
||||
}
|
||||
```
|
||||
|
||||
## 价格计算规则
|
||||
1. 基础价格 × 访问量系数 = 实际价格
|
||||
2. 访问量系数根据月PV自动调整
|
||||
3. 价格每5分钟自动更新一次
|
||||
|
||||
## 预订流程
|
||||
1. 用户选择广告位
|
||||
2. 系统计算实际价格
|
||||
3. 用户确认预订
|
||||
4. 更新预订状态
|
||||
5. 显示预订成功信息
|
||||
|
||||
## 注意事项
|
||||
1. 确保 info.php 接口正确返回访问量数据
|
||||
2. 定期检查图片资源是否可用
|
||||
3. 及时更新预订状态
|
||||
4. 保持价格系数的合理性
|
||||
|
||||
## 更新日志
|
||||
### 2024-02-29
|
||||
- 初始版本发布
|
||||
- 实现动态定价系统
|
||||
- 添加广告位预览功能
|
||||
- 优化移动端显示效果
|
||||
|
||||
## 未来计划
|
||||
|
||||
可在线支付的自助广告系统
|
||||
|
||||
绑定对应广告位的动态码
|
||||
|
||||
实现全程自助下单并完成广告投放
|
||||
|
||||
## 版权信息
|
||||
© 2025 自媒体维基. All rights reserved.
|
381
script.js
Normal file
381
script.js
Normal file
@ -0,0 +1,381 @@
|
||||
// 广告位配置
|
||||
const AD_POSITIONS = {
|
||||
'home-banner-1': {
|
||||
id: 'home-banner-1',
|
||||
title: '首页顶部Banner广告位1',
|
||||
image: 'https://img.apicdo.top/i/3/2025/05/02/f5ed5e0cb518ff37f5ba9a0798c17f1e-3.webp',
|
||||
dimensions: '1200×200px',
|
||||
prices: {
|
||||
monthly: 250,
|
||||
yearly: 500
|
||||
}
|
||||
},
|
||||
'home-banner-2': {
|
||||
id: 'home-banner-2',
|
||||
title: '首页顶部Banner广告位2',
|
||||
image: 'https://img.apicdo.top/i/3/2025/05/02/f5ed5e0cb518ff37f5ba9a0798c17f1e-3.webp',
|
||||
dimensions: '1200×200px',
|
||||
prices: {
|
||||
monthly: 250,
|
||||
yearly: 500
|
||||
}
|
||||
},
|
||||
'home-sidebar': {
|
||||
id: 'home-sidebar',
|
||||
title: '首页侧边栏广告位',
|
||||
image: 'https://img.apicdo.top/i/3/2025/05/02/988551d49a8dd3ca779c89a133c247bd-3.webp',
|
||||
dimensions: '300×600px',
|
||||
prices: {
|
||||
yearly: 300
|
||||
}
|
||||
},
|
||||
'category-top': {
|
||||
id: 'category-top',
|
||||
title: '分类页置顶广告位',
|
||||
image: 'https://img.apicdo.top/i/3/2025/05/02/2d4c99afe306a9a6392d32d089b6fe5a-3.webp',
|
||||
dimensions: '800×150px',
|
||||
prices: {
|
||||
monthly: 100
|
||||
}
|
||||
},
|
||||
'article-end': {
|
||||
id: 'article-end',
|
||||
title: '文末广告位',
|
||||
image: 'https://img.apicdo.top/i/3/2025/05/02/33c6903b27f7db523fd2ba87e20689ae-3.webp',
|
||||
dimensions: '600×300px',
|
||||
prices: {
|
||||
yearly: 200
|
||||
}
|
||||
},
|
||||
'url-top': {
|
||||
id: 'url-top',
|
||||
title: '网址置顶推荐',
|
||||
image: 'https://img.apicdo.top/i/3/2025/05/02/04a1033cb71dcf2e7566f5503bec91bb-3.webp',
|
||||
dimensions: '800×100px',
|
||||
prices: {
|
||||
monthly: 200,
|
||||
yearly: 500
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 访问量数据(从API获取)
|
||||
let visitData = {
|
||||
today_uv: 0,
|
||||
today_pv: 0,
|
||||
yesterday_uv: 0,
|
||||
yesterday_pv: 0,
|
||||
last_month_pv: 0,
|
||||
last_year_pv: 0
|
||||
};
|
||||
|
||||
// 访问量价格系数配置
|
||||
const VISIT_COEFFICIENTS = {
|
||||
'low': { min: 0, max: 30000, coefficient: 0.8 }, // 低访问量,价格打8折
|
||||
'medium': { min: 30001, max: 60000, coefficient: 1 }, // 中等访问量,原价
|
||||
'high': { min: 60001, max: 100000, coefficient: 1.2 }, // 高访问量,价格上浮20%
|
||||
'veryHigh': { min: 100001, max: Infinity, coefficient: 1.5 } // 极高访问量,价格上浮50%
|
||||
};
|
||||
|
||||
// 广告位预订状态(实际项目中应该从数据库获取)
|
||||
const BOOKED_STATUS = {
|
||||
'home-banner-1': {
|
||||
isBooked: false,
|
||||
endDate: null
|
||||
},
|
||||
'home-banner-2': {
|
||||
isBooked: false,
|
||||
endDate: null
|
||||
},
|
||||
'home-sidebar': {
|
||||
isBooked: true,
|
||||
endDate: new Date('2026-12-31').toISOString()
|
||||
},
|
||||
'category-top': {
|
||||
isBooked: false,
|
||||
endDate: null
|
||||
},
|
||||
'article-end': {
|
||||
isBooked: false,
|
||||
endDate: null
|
||||
},
|
||||
'url-top': {
|
||||
isBooked: false,
|
||||
endDate: null
|
||||
}
|
||||
};
|
||||
|
||||
// 生成广告位HTML
|
||||
function generateAdCardHtml(adId, adConfig) {
|
||||
const status = BOOKED_STATUS[adId];
|
||||
const isBooked = status.isBooked;
|
||||
const endDate = status.endDate ? new Date(status.endDate) : null;
|
||||
|
||||
let statusHtml = '<span class="status-available">可预订</span>';
|
||||
if (isBooked && endDate) {
|
||||
const formattedDate = endDate.toLocaleDateString('zh-CN', {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric'
|
||||
});
|
||||
statusHtml = `
|
||||
<span class="status-booked">
|
||||
已预订
|
||||
<span class="end-date">到期时间:${formattedDate}</span>
|
||||
</span>
|
||||
`;
|
||||
}
|
||||
|
||||
let priceHtml = '';
|
||||
if (adConfig.prices.monthly) {
|
||||
priceHtml += `<p>月付价格:<span id="${adId}-monthly">计算中...</span> 元/月</p>`;
|
||||
}
|
||||
if (adConfig.prices.yearly) {
|
||||
priceHtml += `<p>年付价格:<span id="${adId}-yearly">计算中...</span> 元/年</p>`;
|
||||
}
|
||||
|
||||
let bookingButtons = '';
|
||||
if (!isBooked) {
|
||||
if (adConfig.prices.monthly && adConfig.prices.yearly) {
|
||||
bookingButtons = `
|
||||
<div class="booking-options">
|
||||
<button class="book-btn" onclick="bookAd('${adId}', 'monthly')">月付预订</button>
|
||||
<button class="book-btn" onclick="bookAd('${adId}', 'yearly')">年付预订</button>
|
||||
</div>
|
||||
`;
|
||||
} else if (adConfig.prices.monthly) {
|
||||
bookingButtons = `<button class="book-btn" onclick="bookAd('${adId}', 'monthly')">月付预订</button>`;
|
||||
} else if (adConfig.prices.yearly) {
|
||||
bookingButtons = `<button class="book-btn" onclick="bookAd('${adId}', 'yearly')">年付预订</button>`;
|
||||
}
|
||||
}
|
||||
|
||||
return `
|
||||
<div class="ad-card" id="${adId}">
|
||||
<h2>${adConfig.title}</h2>
|
||||
<div class="ad-preview">
|
||||
<a href="${adConfig.image}" target="_blank">
|
||||
<img src="${adConfig.image}" alt="${adConfig.title}预览" class="preview-img">
|
||||
<div class="preview-overlay">
|
||||
<span class="preview-hint">点击查看大图</span>
|
||||
<div class="ad-dimensions">尺寸:${adConfig.dimensions}</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="ad-stats">
|
||||
${priceHtml}
|
||||
</div>
|
||||
<div class="ad-status" id="${adId}-status">
|
||||
${statusHtml}
|
||||
</div>
|
||||
${bookingButtons}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
// 初始化广告位
|
||||
function initAdPositions() {
|
||||
const adPositionsContainer = document.querySelector('.ad-positions');
|
||||
if (!adPositionsContainer) return;
|
||||
|
||||
let html = '';
|
||||
Object.entries(AD_POSITIONS).forEach(([adId, adConfig]) => {
|
||||
html += generateAdCardHtml(adId, adConfig);
|
||||
});
|
||||
|
||||
adPositionsContainer.innerHTML = html;
|
||||
}
|
||||
|
||||
// 获取访问量数据
|
||||
async function fetchVisitData() {
|
||||
try {
|
||||
const response = await fetch('info.php');
|
||||
if (!response.ok) {
|
||||
throw new Error('获取访问量数据失败');
|
||||
}
|
||||
visitData = await response.json();
|
||||
console.log('访问量数据已更新:', visitData);
|
||||
} catch (error) {
|
||||
console.error('获取访问量数据时出错:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// 根据访问量获取价格系数
|
||||
function getPriceCoefficient(monthlyPV) {
|
||||
for (const [key, range] of Object.entries(VISIT_COEFFICIENTS)) {
|
||||
if (monthlyPV >= range.min && monthlyPV <= range.max) {
|
||||
return range.coefficient;
|
||||
}
|
||||
}
|
||||
return 1; // 默认系数
|
||||
}
|
||||
|
||||
// 计算实际价格
|
||||
function calculateActualPrice(basePrice, monthlyPV) {
|
||||
const coefficient = getPriceCoefficient(monthlyPV);
|
||||
return Math.round(basePrice * coefficient);
|
||||
}
|
||||
|
||||
// 更新所有广告位的价格显示
|
||||
function updateAllAdPrices() {
|
||||
console.log('开始更新价格...');
|
||||
try {
|
||||
Object.entries(AD_POSITIONS).forEach(([adId, adConfig]) => {
|
||||
const prices = adConfig.prices;
|
||||
|
||||
// 更新月付价格显示
|
||||
if (prices.monthly) {
|
||||
const monthlyElement = document.getElementById(`${adId}-monthly`);
|
||||
if (monthlyElement) {
|
||||
const actualPrice = calculateActualPrice(prices.monthly, visitData.last_month_pv);
|
||||
monthlyElement.textContent = actualPrice.toLocaleString();
|
||||
}
|
||||
}
|
||||
|
||||
// 更新年付价格显示
|
||||
if (prices.yearly) {
|
||||
const yearlyElement = document.getElementById(`${adId}-yearly`);
|
||||
if (yearlyElement) {
|
||||
const actualPrice = calculateActualPrice(prices.yearly, visitData.last_month_pv);
|
||||
yearlyElement.textContent = actualPrice.toLocaleString();
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('更新价格时出错:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// 处理广告预订
|
||||
function bookAd(adPosition, paymentType) {
|
||||
const status = BOOKED_STATUS[adPosition];
|
||||
if (status.isBooked) {
|
||||
alert('该广告位已被预订,请选择其他广告位或等待到期后再预订。');
|
||||
return;
|
||||
}
|
||||
|
||||
const adConfig = AD_POSITIONS[adPosition];
|
||||
const basePrice = adConfig.prices[paymentType];
|
||||
|
||||
if (!basePrice) {
|
||||
alert('该广告位不支持此支付方式');
|
||||
return;
|
||||
}
|
||||
|
||||
const actualPrice = calculateActualPrice(basePrice, visitData.last_month_pv);
|
||||
const duration = paymentType === 'yearly' ? 365 : 30;
|
||||
const confirmMessage = `您选择的广告位:${adConfig.title}\n支付方式:${paymentType === 'yearly' ? '年付' : '月付'}\n总价格:${actualPrice}元\n\n是否确认预订?`;
|
||||
|
||||
if (confirm(confirmMessage)) {
|
||||
// 计算到期时间
|
||||
const endDate = new Date();
|
||||
endDate.setDate(endDate.getDate() + duration);
|
||||
|
||||
// 更新预订状态
|
||||
BOOKED_STATUS[adPosition] = {
|
||||
isBooked: true,
|
||||
endDate: endDate.toISOString()
|
||||
};
|
||||
|
||||
// 重新生成广告位卡片
|
||||
const adCard = document.getElementById(adPosition);
|
||||
if (adCard) {
|
||||
adCard.outerHTML = generateAdCardHtml(adPosition, adConfig);
|
||||
}
|
||||
|
||||
alert('预订成功!我们的客服人员将尽快与您联系。');
|
||||
}
|
||||
}
|
||||
|
||||
// 图片预览功能
|
||||
function initImagePreview() {
|
||||
const modal = document.getElementById('previewModal');
|
||||
const modalImg = modal.querySelector('.preview-modal-img');
|
||||
const modalTitle = modal.querySelector('.preview-modal-title');
|
||||
const modalDimensions = modal.querySelector('.preview-modal-dimensions');
|
||||
const closeBtn = modal.querySelector('.preview-close');
|
||||
|
||||
// 确保模态框初始状态正确
|
||||
modal.style.display = 'none';
|
||||
|
||||
// 点击预览图打开模态框
|
||||
document.querySelectorAll('.preview-img').forEach(img => {
|
||||
img.addEventListener('click', function() {
|
||||
const card = this.closest('.ad-card');
|
||||
const title = card.querySelector('h2').textContent;
|
||||
const dimensions = card.querySelector('.ad-dimensions').textContent;
|
||||
|
||||
modalImg.src = this.src;
|
||||
modalTitle.textContent = title;
|
||||
modalDimensions.textContent = dimensions;
|
||||
|
||||
// 显示模态框
|
||||
modal.style.display = 'flex';
|
||||
setTimeout(() => {
|
||||
modal.classList.add('show');
|
||||
}, 10);
|
||||
|
||||
// 禁用滚动
|
||||
document.body.style.overflow = 'hidden';
|
||||
});
|
||||
});
|
||||
|
||||
// 点击关闭按钮
|
||||
closeBtn.addEventListener('click', function() {
|
||||
modal.classList.remove('show');
|
||||
setTimeout(() => {
|
||||
modal.style.display = 'none';
|
||||
document.body.style.overflow = '';
|
||||
}, 300);
|
||||
});
|
||||
|
||||
// 点击模态框背景关闭
|
||||
modal.addEventListener('click', function(e) {
|
||||
if (e.target === modal) {
|
||||
modal.classList.remove('show');
|
||||
setTimeout(() => {
|
||||
modal.style.display = 'none';
|
||||
document.body.style.overflow = '';
|
||||
}, 300);
|
||||
}
|
||||
});
|
||||
|
||||
// 按ESC键关闭
|
||||
document.addEventListener('keydown', function(e) {
|
||||
if (e.key === 'Escape' && modal.classList.contains('show')) {
|
||||
modal.classList.remove('show');
|
||||
setTimeout(() => {
|
||||
modal.style.display = 'none';
|
||||
document.body.style.overflow = '';
|
||||
}, 300);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 处理联系表单提交
|
||||
document.querySelector('.contact-form').addEventListener('submit', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
const formData = new FormData(this);
|
||||
const data = Object.fromEntries(formData.entries());
|
||||
|
||||
// 这里可以添加表单验证逻辑
|
||||
|
||||
// 模拟表单提交
|
||||
alert('感谢您的咨询!我们的客服人员将尽快与您联系。');
|
||||
this.reset();
|
||||
});
|
||||
|
||||
// 确保页面完全加载后再执行
|
||||
window.onload = async function() {
|
||||
console.log('页面加载完成,开始初始化...');
|
||||
initAdPositions();
|
||||
await fetchVisitData();
|
||||
updateAllAdPrices();
|
||||
|
||||
// 每5分钟更新一次访问量数据
|
||||
setInterval(async () => {
|
||||
await fetchVisitData();
|
||||
updateAllAdPrices();
|
||||
}, 5 * 60 * 1000);
|
||||
};
|
468
styles.css
Normal file
468
styles.css
Normal file
@ -0,0 +1,468 @@
|
||||
/* 全局样式 */
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'PingFang SC', 'Microsoft YaHei', sans-serif;
|
||||
line-height: 1.6;
|
||||
color: #333;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
/* 头部样式 */
|
||||
header {
|
||||
background: linear-gradient(135deg, #1e3c72 0%, #2a5298 100%);
|
||||
color: white;
|
||||
padding: 2rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.logo {
|
||||
font-size: 2rem;
|
||||
font-weight: bold;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2.5rem;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
font-size: 1.2rem;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
/* 主要内容区域 */
|
||||
main {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
/* 广告位卡片样式 */
|
||||
.ad-positions {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
||||
gap: 2rem;
|
||||
margin-bottom: 3rem;
|
||||
}
|
||||
|
||||
.ad-card {
|
||||
background: white;
|
||||
border-radius: 10px;
|
||||
padding: 1.5rem;
|
||||
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.ad-card:hover {
|
||||
transform: translateY(-5px);
|
||||
}
|
||||
|
||||
/* 广告预览图片样式 */
|
||||
.ad-preview {
|
||||
position: relative;
|
||||
margin: 1rem 0;
|
||||
background: #f0f0f0;
|
||||
height: 150px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 5px;
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.ad-preview:hover {
|
||||
transform: scale(1.02);
|
||||
}
|
||||
|
||||
.ad-preview a {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.ad-preview img {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.preview-overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
|
||||
.ad-preview:hover .preview-overlay {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.preview-hint {
|
||||
color: white;
|
||||
font-size: 1.2em;
|
||||
margin-bottom: 10px;
|
||||
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.ad-dimensions {
|
||||
color: white;
|
||||
font-size: 0.9em;
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
padding: 4px 8px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
/* 预览模态框样式 */
|
||||
.preview-modal {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.9);
|
||||
z-index: 1000;
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease;
|
||||
display: none;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.preview-modal.show {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.preview-modal-content {
|
||||
position: relative;
|
||||
max-width: 90%;
|
||||
max-height: 90vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
background: #fff;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 0 20px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.preview-modal-img {
|
||||
max-width: 100%;
|
||||
max-height: 80vh;
|
||||
object-fit: contain;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.preview-modal-info {
|
||||
margin-top: 20px;
|
||||
color: #333;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.preview-modal-title {
|
||||
font-size: 1.2em;
|
||||
font-weight: bold;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.preview-modal-dimensions {
|
||||
font-size: 0.9em;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.preview-close {
|
||||
position: absolute;
|
||||
top: -40px;
|
||||
right: 0;
|
||||
color: white;
|
||||
font-size: 35px;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
|
||||
.preview-close:hover {
|
||||
color: #ff4444;
|
||||
}
|
||||
|
||||
/* 响应式调整 */
|
||||
@media (max-width: 768px) {
|
||||
.preview-modal-content {
|
||||
max-width: 95%;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.preview-modal-img {
|
||||
max-height: 70vh;
|
||||
}
|
||||
|
||||
.preview-hint {
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
.ad-dimensions {
|
||||
font-size: 0.8em;
|
||||
}
|
||||
}
|
||||
|
||||
.ad-stats {
|
||||
margin: 1rem 0;
|
||||
}
|
||||
|
||||
.ad-stats p {
|
||||
margin: 0.5rem 0;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.note {
|
||||
color: #666;
|
||||
font-size: 0.9rem;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.booking-options {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.booking-options .book-btn {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.book-btn {
|
||||
background: #1e3c72;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 0.8rem 1.5rem;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
font-size: 1.1rem;
|
||||
transition: background 0.3s ease;
|
||||
}
|
||||
|
||||
.book-btn:hover {
|
||||
background: #2a5298;
|
||||
}
|
||||
|
||||
/* 广告效果数据区域 */
|
||||
.ad-stats {
|
||||
background: white;
|
||||
padding: 2rem;
|
||||
border-radius: 10px;
|
||||
margin-bottom: 3rem;
|
||||
}
|
||||
|
||||
.stats-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||
gap: 2rem;
|
||||
margin-top: 1.5rem;
|
||||
}
|
||||
|
||||
.stat-item {
|
||||
text-align: center;
|
||||
padding: 1.5rem;
|
||||
background: #f8f9fa;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.stat-item h3 {
|
||||
color: #666;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.stat-item p {
|
||||
font-size: 1.5rem;
|
||||
font-weight: bold;
|
||||
color: #1e3c72;
|
||||
}
|
||||
|
||||
/* 联系方式区域 */
|
||||
.contact {
|
||||
background: white;
|
||||
padding: 2rem;
|
||||
border-radius: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.contact-info {
|
||||
margin: 1.5rem 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.wechat-contact {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
padding: 1.5rem;
|
||||
background: #f8f9fa;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.wechat-contact:hover {
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.wechat-qrcode {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.wechat-qrcode img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.wechat-id {
|
||||
font-size: 1.1rem;
|
||||
color: #333;
|
||||
font-weight: 500;
|
||||
margin: 0;
|
||||
padding: 0.5rem 1rem;
|
||||
background: #fff;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
/* 响应式设计 */
|
||||
@media (max-width: 768px) {
|
||||
.contact {
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.wechat-contact {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.wechat-qrcode {
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
|
||||
.wechat-id {
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* 页脚样式 */
|
||||
footer {
|
||||
text-align: center;
|
||||
padding: 2rem;
|
||||
background: #1e3c72;
|
||||
color: white;
|
||||
margin-top: 3rem;
|
||||
}
|
||||
|
||||
/* 响应式设计 */
|
||||
@media (max-width: 768px) {
|
||||
.ad-positions {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.stats-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.contact-info {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.booking-options {
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
|
||||
/* 广告限制说明样式 */
|
||||
.ad-restrictions {
|
||||
background-color: #fff8f8;
|
||||
border: 1px solid #ffd6d6;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
margin: 20px auto;
|
||||
max-width: 800px;
|
||||
}
|
||||
|
||||
.ad-restrictions h2 {
|
||||
color: #d32f2f;
|
||||
margin-top: 0;
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
.ad-restrictions ul {
|
||||
list-style-type: none;
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
.ad-restrictions li {
|
||||
position: relative;
|
||||
padding-left: 25px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.ad-restrictions li:before {
|
||||
content: "×";
|
||||
color: #d32f2f;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.restriction-note {
|
||||
color: #666;
|
||||
font-style: italic;
|
||||
margin-top: 15px;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
/* 广告位状态样式 */
|
||||
.ad-status {
|
||||
margin: 10px 0;
|
||||
padding: 8px 12px;
|
||||
border-radius: 4px;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.status-available {
|
||||
color: #4caf50;
|
||||
background-color: #e8f5e9;
|
||||
}
|
||||
|
||||
.status-booked {
|
||||
color: #f44336;
|
||||
background-color: #ffebee;
|
||||
}
|
||||
|
||||
.status-booked .end-date {
|
||||
display: block;
|
||||
font-size: 0.9em;
|
||||
font-weight: normal;
|
||||
margin-top: 4px;
|
||||
}
|
129
设计方案.md
Normal file
129
设计方案.md
Normal file
@ -0,0 +1,129 @@
|
||||
# 广告商投放页面设计方案
|
||||
|
||||
|
||||
|
||||
## 页面结构
|
||||
|
||||
### 1. 头部区域
|
||||
|
||||
- 网站Logo
|
||||
- "广告投放"标题
|
||||
- 简短说明:"在[网站名称] - 广告投放,精准触达您的目标用户"
|
||||
|
||||
### 2. 广告位展示区
|
||||
|
||||
#### 首页顶部Banner广告位
|
||||
|
||||
- 位置示意图
|
||||
- 实时访问量显示:[从统计页面API获取数据]
|
||||
- 价格计算公式:`费用 = 统计页面API日均访问量 × 投放时间 × 系数`
|
||||
- 实时计算价格展示
|
||||
- "立即预订"按钮
|
||||
|
||||
#### 首页侧边栏广告位
|
||||
|
||||
- 位置示意图
|
||||
- 实时访问量显示
|
||||
- 价格计算公式:`费用 = 统计页面API日均访问量 × 投放时间 × 系数`
|
||||
- 实时计算价格展示
|
||||
- "立即预订"按钮
|
||||
|
||||
#### 分类页顶部广告位
|
||||
|
||||
- 位置示意图
|
||||
- 实时访问量显示
|
||||
- 价格计算公式:`费用 = 统计页面API日均访问量 × 投放时间 × 系数`
|
||||
- 实时计算价格展示
|
||||
- "立即预订"按钮
|
||||
|
||||
#### 文末广告位
|
||||
|
||||
- 位置示意图
|
||||
- 实时访问量显示
|
||||
- 价格计算公式:`费用 = 统计页面API日均访问量 × 投放时间 × 系数`
|
||||
- 实时计算价格展示
|
||||
- "立即预订"按钮
|
||||
|
||||
### 3. 广告效果数据展示
|
||||
|
||||
- "我们的广告位平均点击率:X%"
|
||||
- "上月广告位平均曝光量:X次"
|
||||
- "典型客户案例展示"
|
||||
|
||||
### 4. 联系方式
|
||||
|
||||
- 客服QQ/微信
|
||||
- 联系电话
|
||||
- 联系邮箱
|
||||
- 在线咨询表单
|
||||
|
||||
## 技术实现方案
|
||||
|
||||
### 访问量获取
|
||||
|
||||
```javascript
|
||||
// 从统计API获取访问量数据
|
||||
async function getVisitStats() {
|
||||
try {
|
||||
const response = await fetch('tongji.com');
|
||||
const data = await response.json();
|
||||
return data.visits; // 假设返回的JSON中有visits字段
|
||||
} catch (error) {
|
||||
console.error('获取访问量失败:', error);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 价格计算公式实现
|
||||
|
||||
```javascript
|
||||
// 广告位系数
|
||||
const COEFFICIENTS = {
|
||||
'home-banner': 0.0,
|
||||
'home-sidebar': 0.0,
|
||||
'category-top': 0.0,
|
||||
'article-end': 0.0
|
||||
};
|
||||
|
||||
// 计算广告价格
|
||||
function calculateAdPrice(dailyVisits, coefficient) {
|
||||
return Math.round(dailyVisits * 365 * coefficient);
|
||||
}
|
||||
|
||||
// 更新所有广告位的价格显示
|
||||
async function updateAllAdPrices() {
|
||||
const dailyVisits = await getVisitStats();
|
||||
|
||||
Object.keys(COEFFICIENTS).forEach(adPosition => {
|
||||
const price = calculateAdPrice(dailyVisits, COEFFICIENTS[adPosition]);
|
||||
document.getElementById(`${adPosition}-price`).textContent = price;
|
||||
});
|
||||
}
|
||||
|
||||
// 页面加载时更新价格
|
||||
window.addEventListener('load', updateAllAdPrices);
|
||||
```
|
||||
|
||||
## 定价策略说明
|
||||
|
||||
我们采用透明、公平的定价策略,基于以下原则:
|
||||
|
||||
1. **位置价值**:首页等核心位置系数较高,次要位置系数较低
|
||||
2. **访问量基础**:价格随网站流量增长而自然调整
|
||||
3. **长期合作优惠**:年付模式比月付模式优惠20%
|
||||
|
||||
## 广告位系数建议表
|
||||
|
||||
| 广告位类型 | 建议系数范围 | 说明 |
|
||||
| -------------- | ------------ | ---------------------- |
|
||||
| 首页顶部Banner | 0 | 最显眼位置,品牌曝光强 |
|
||||
| 首页侧边栏 | 0 | 次重要位置 |
|
||||
| 分类页顶部 | 0 | 精准分类流量 |
|
||||
| 文末/页脚位置 | 0 | 补充曝光,价格亲民 |
|
||||
|
||||
## 说明
|
||||
|
||||
1. 投放时长选项(最低30天,分别是月付,季付,年付,也可以自定义时长);
|
||||
2. 广告位预定日历,显示已被占用的时间段;
|
||||
3. 为长期客户提供梯度折扣(如2年9折,3年8折等)。
|
Loading…
x
Reference in New Issue
Block a user