commit
6dd58ae5e3
4 changed files with 181 additions and 0 deletions
@ -0,0 +1,36 @@ |
|||
from flask import Flask, jsonify, send_from_directory |
|||
|
|||
app = Flask(__name__, static_folder="public", static_url_path="") |
|||
|
|||
# 根路径返回 index.html |
|||
@app.route("/") |
|||
def serve_index(): |
|||
return send_from_directory(app.static_folder, "index.html") |
|||
|
|||
# API 子路径,提供菏泽宣传数据 |
|||
@app.route("/api/heze") |
|||
def api_heze(): |
|||
heze_data = { |
|||
"message": "欢迎来到山东菏泽", |
|||
"data": { |
|||
"about": "菏泽是中国牡丹之都,位于山东省西南部,以其丰富的历史文化和美丽的自然景观而闻名。", |
|||
"places": [ |
|||
{"name": "曹州牡丹园", "description": "世界上最大的牡丹园,每年春季举办牡丹花会,吸引众多游客。"}, |
|||
{"name": "孙膑旅游城", "description": "以古代军事家孙膑为主题的文化旅游区,展示了丰富的历史遗迹。"}, |
|||
{"name": "水浒好汉城", "description": "以《水浒传》为背景的文化景区,重现了宋朝时期的建筑和民俗。"} |
|||
], |
|||
"food": [ |
|||
{"name": "菏泽酱菜", "description": "菏泽特色酱菜,口感爽脆,风味独特。"}, |
|||
{"name": "曹州烧饼", "description": "菏泽传统小吃,外皮酥脆,内馅丰富。"}, |
|||
{"name": "牡丹饼", "description": "以牡丹花瓣为原料制作的特色糕点,香气扑鼻。"} |
|||
], |
|||
"culture": [ |
|||
{"name": "菏泽戏曲", "description": "菏泽是山东梆子、大平调等多种戏曲的发源地,戏曲文化丰富多彩。"}, |
|||
{"name": "菏泽剪纸", "description": "菏泽剪纸是中国非物质文化遗产之一,技艺精湛,图案精美。"} |
|||
] |
|||
} |
|||
} |
|||
return jsonify(heze_data) |
|||
|
|||
if __name__ == "__main__": |
|||
app.run(debug=True, port=80) |
@ -0,0 +1,28 @@ |
|||
<!DOCTYPE html> |
|||
<html lang="en"> |
|||
<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> |
|||
<div class="container"> |
|||
<h1>欢迎来到山东菏泽</h1> |
|||
<p id="about"></p> |
|||
<div class="section"> |
|||
<h2>特色景点</h2> |
|||
<div id="places-container"></div> |
|||
</div> |
|||
<div class="section"> |
|||
<h2>菏泽美食</h2> |
|||
<div id="food-container"></div> |
|||
</div> |
|||
<div class="section"> |
|||
<h2>菏泽文化</h2> |
|||
<div id="culture-container"></div> |
|||
</div> |
|||
</div> |
|||
<script src="script.js"></script> |
|||
</body> |
|||
</html> |
@ -0,0 +1,72 @@ |
|||
document.addEventListener("DOMContentLoaded", function () { |
|||
fetch("/api/heze") |
|||
.then(response => response.json()) |
|||
.then(data => { |
|||
const about = document.getElementById("about"); |
|||
about.textContent = data.data.about; |
|||
|
|||
const placesContainer = document.getElementById("places-container"); |
|||
const foodContainer = document.getElementById("food-container"); |
|||
const cultureContainer = document.getElementById("culture-container"); |
|||
|
|||
// 渲染景点
|
|||
data.data.places.forEach(place => { |
|||
const placeItem = document.createElement("div"); |
|||
placeItem.classList.add("item"); |
|||
|
|||
const placeName = document.createElement("div"); |
|||
placeName.classList.add("item-name"); |
|||
placeName.textContent = place.name; |
|||
|
|||
const placeDescription = document.createElement("div"); |
|||
placeDescription.classList.add("item-description"); |
|||
placeDescription.textContent = place.description; |
|||
|
|||
placeItem.appendChild(placeName); |
|||
placeItem.appendChild(placeDescription); |
|||
|
|||
placesContainer.appendChild(placeItem); |
|||
}); |
|||
|
|||
// 渲染美食
|
|||
data.data.food.forEach(food => { |
|||
const foodItem = document.createElement("div"); |
|||
foodItem.classList.add("item"); |
|||
|
|||
const foodName = document.createElement("div"); |
|||
foodName.classList.add("item-name"); |
|||
foodName.textContent = food.name; |
|||
|
|||
const foodDescription = document.createElement("div"); |
|||
foodDescription.classList.add("item-description"); |
|||
foodDescription.textContent = food.description; |
|||
|
|||
foodItem.appendChild(foodName); |
|||
foodItem.appendChild(foodDescription); |
|||
|
|||
foodContainer.appendChild(foodItem); |
|||
}); |
|||
|
|||
// 渲染文化
|
|||
data.data.culture.forEach(culture => { |
|||
const cultureItem = document.createElement("div"); |
|||
cultureItem.classList.add("item"); |
|||
|
|||
const cultureName = document.createElement("div"); |
|||
cultureName.classList.add("item-name"); |
|||
cultureName.textContent = culture.name; |
|||
|
|||
const cultureDescription = document.createElement("div"); |
|||
cultureDescription.classList.add("item-description"); |
|||
cultureDescription.textContent = culture.description; |
|||
|
|||
cultureItem.appendChild(cultureName); |
|||
cultureItem.appendChild(cultureDescription); |
|||
|
|||
cultureContainer.appendChild(cultureItem); |
|||
}); |
|||
}) |
|||
.catch(error => { |
|||
console.error("Error fetching data:", error); |
|||
}); |
|||
}); |
@ -0,0 +1,45 @@ |
|||
body { |
|||
font-family: Arial, sans-serif; |
|||
background-color: #f4f4f9; |
|||
margin: 0; |
|||
padding: 0; |
|||
} |
|||
|
|||
.container { |
|||
max-width: 800px; |
|||
margin: 20px auto; |
|||
padding: 20px; |
|||
background: #fff; |
|||
border-radius: 8px; |
|||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); |
|||
} |
|||
|
|||
h1, h2 { |
|||
text-align: center; |
|||
color: #333; |
|||
} |
|||
|
|||
.section { |
|||
margin-top: 20px; |
|||
} |
|||
|
|||
.item { |
|||
margin-bottom: 15px; |
|||
padding: 10px; |
|||
border-bottom: 1px solid #ddd; |
|||
} |
|||
|
|||
.item:last-child { |
|||
border-bottom: none; |
|||
} |
|||
|
|||
.item-name { |
|||
font-size: 1.2em; |
|||
font-weight: bold; |
|||
color: #444; |
|||
} |
|||
|
|||
.item-description { |
|||
font-size: 0.9em; |
|||
color: #666; |
|||
} |
Loading…
Reference in new issue