Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
P
prd
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
caoxu
prd
Commits
de4a9da9
Commit
de4a9da9
authored
Jan 09, 2026
by
caoxu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add: 新增城市介绍页面
parent
19ad2be1
Pipeline
#508
canceled with stages
Changes
2
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
598 additions
and
0 deletions
+598
-0
index.js
src/router/index.js
+5
-0
CityIntroductionView.vue
src/views/CityIntroductionView.vue
+593
-0
No files found.
src/router/index.js
View file @
de4a9da9
...
...
@@ -16,6 +16,11 @@ const router = createRouter({
path
:
'/museum-night'
,
name
:
'museumNight'
,
component
:
()
=>
import
(
'../views/MuseumNightView.vue'
)
},
{
path
:
'/city-introduction'
,
name
:
'cityIntroduction'
,
component
:
()
=>
import
(
'../views/CityIntroductionView.vue'
)
}
]
})
...
...
src/views/CityIntroductionView.vue
0 → 100644
View file @
de4a9da9
<
template
>
<div
class=
"city-introduction"
>
<div
class=
"header"
>
<button
class=
"back-button"
@
click=
"goBack"
>
←
</button>
<h1
class=
"page-title"
>
墨鱼旅行城市介绍
</h1>
</div>
<div
class=
"main-content"
>
<div
class=
"city-banner"
>
<img
src=
"https://images.unsplash.com/photo-1477959858617-67f85cf4f1df?w=1200&h=400&fit=crop"
alt=
"城市风景"
class=
"banner-image"
/>
</div>
<div
class=
"city-info-section"
>
<h2
class=
"section-title"
>
城市介绍
</h2>
<div
class=
"city-description"
>
<p>
欢迎来到这座充满魅力的城市!这里融合了古老的历史文化与现代都市的繁华,
每一个角落都散发着独特的魅力。漫步在古老的街道上,感受历史的沉淀;
探索现代化的建筑群,体验都市的活力。无论是历史文化爱好者,
还是美食探索者,都能在这里找到属于自己的精彩。
</p>
</div>
</div>
<div
class=
"attractions-section"
>
<h2
class=
"section-title"
>
热门景点
</h2>
<div
class=
"attractions-grid"
>
<div
v-for=
"attraction in attractions"
:key=
"attraction.id"
class=
"attraction-card"
>
<img
:src=
"attraction.image"
:alt=
"attraction.name"
class=
"attraction-image"
/>
<div
class=
"attraction-info"
>
<h3
class=
"attraction-name"
>
{{
attraction
.
name
}}
</h3>
<p
class=
"attraction-description"
>
{{
attraction
.
description
}}
</p>
<div
class=
"attraction-meta"
>
<span
class=
"attraction-rating"
>
⭐
{{
attraction
.
rating
}}
</span>
<span
class=
"attraction-price"
>
¥
{{
attraction
.
price
}}
</span>
</div>
</div>
</div>
</div>
</div>
<div
class=
"nearby-users-section"
>
<h2
class=
"section-title"
>
附近的用户
</h2>
<div
class=
"users-list"
>
<div
v-for=
"user in nearbyUsers"
:key=
"user.id"
class=
"user-card"
>
<img
:src=
"user.avatar"
:alt=
"user.name"
class=
"user-avatar"
/>
<div
class=
"user-info"
>
<h4
class=
"user-name"
>
{{
user
.
name
}}
</h4>
<p
class=
"user-location"
>
{{
user
.
location
}}
</p>
<span
class=
"user-status"
:class=
"user.status"
>
{{
user
.
statusText
}}
</span>
</div>
</div>
</div>
</div>
<div
class=
"destination-dynamics-section"
>
<h2
class=
"section-title"
>
当前目的地动态
</h2>
<div
class=
"dynamics-list"
>
<div
v-for=
"dynamic in dynamics"
:key=
"dynamic.id"
class=
"dynamic-card"
>
<div
class=
"dynamic-header"
>
<img
:src=
"dynamic.userAvatar"
:alt=
"dynamic.userName"
class=
"dynamic-avatar"
/>
<div
class=
"dynamic-user-info"
>
<h4
class=
"dynamic-user-name"
>
{{
dynamic
.
userName
}}
</h4>
<span
class=
"dynamic-time"
>
{{
dynamic
.
time
}}
</span>
</div>
</div>
<p
class=
"dynamic-content"
>
{{
dynamic
.
content
}}
</p>
<div
class=
"dynamic-actions"
>
<button
class=
"action-btn like-btn"
>
<span>
❤️
</span>
<span>
{{
dynamic
.
likes
}}
</span>
</button>
<button
class=
"action-btn comment-btn"
>
<span>
💬
</span>
<span>
{{
dynamic
.
comments
}}
</span>
</button>
</div>
</div>
</div>
</div>
<div
class=
"food-section"
>
<h2
class=
"section-title"
>
特色美食
</h2>
<div
class=
"food-grid"
>
<div
v-for=
"food in foods"
:key=
"food.id"
class=
"food-card"
>
<img
:src=
"food.image"
:alt=
"food.name"
class=
"food-image"
/>
<div
class=
"food-info"
>
<h3
class=
"food-name"
>
{{
food
.
name
}}
</h3>
<p
class=
"food-description"
>
{{
food
.
description
}}
</p>
<div
class=
"food-meta"
>
<span
class=
"food-type"
>
{{
food
.
type
}}
</span>
<span
class=
"food-price"
>
¥
{{
food
.
price
}}
</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</
template
>
<
script
setup
>
import
{
ref
}
from
'vue'
import
{
useRouter
}
from
'vue-router'
const
router
=
useRouter
()
const
attractions
=
ref
([
{
id
:
1
,
name
:
'古城博物馆'
,
description
:
'收藏着千年历史的珍贵文物,展示着古代文明的辉煌成就。'
,
image
:
'https://images.unsplash.com/photo-1554907984-15263bfd63bd?w=400&h=300&fit=crop'
,
rating
:
4.8
,
price
:
80
},
{
id
:
2
,
name
:
'现代艺术中心'
,
description
:
'当代艺术的殿堂,定期举办国际艺术展览。'
,
image
:
'https://images.unsplash.com/photo-1561214115-f2f73c5b4d8c?w=400&h=300&fit=crop'
,
rating
:
4.6
,
price
:
120
},
{
id
:
3
,
name
:
'中央公园'
,
description
:
'城市绿肺,休闲娱乐的理想去处。'
,
image
:
'https://images.unsplash.com/photo-1496417263034-01ec0d5c7b5e?w=400&h=300&fit=crop'
,
rating
:
4.9
,
price
:
0
},
{
id
:
4
,
name
:
'历史街区'
,
description
:
'保存完好的古建筑群,体验传统生活方式。'
,
image
:
'https://images.unsplash.com/photo-1548625361-98a0b2c3a1d?w=400&h=300&fit=crop'
,
rating
:
4.7
,
price
:
0
}
])
const
nearbyUsers
=
ref
([
{
id
:
1
,
name
:
'张三'
,
avatar
:
'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=100&h=100&fit=crop'
,
location
:
'距离您 500m'
,
status
:
'online'
,
statusText
:
'在线'
},
{
id
:
2
,
name
:
'李四'
,
avatar
:
'https://images.unsplash.com/photo-1494790108377-be9c29b29330?w=100&h=100&fit=crop'
,
location
:
'距离您 1.2km'
,
status
:
'traveling'
,
statusText
:
'旅行中'
},
{
id
:
3
,
name
:
'王五'
,
avatar
:
'https://images.unsplash.com/photo-1500648767791-00dcc994a43e?w=100&h=100&fit=crop'
,
location
:
'距离您 2.5km'
,
status
:
'offline'
,
statusText
:
'离线'
},
{
id
:
4
,
name
:
'赵六'
,
avatar
:
'https://images.unsplash.com/photo-1534528741775-53994a69daeb?w=100&h=100&fit=crop'
,
location
:
'距离您 3.8km'
,
status
:
'online'
,
statusText
:
'在线'
}
])
const
dynamics
=
ref
([
{
id
:
1
,
userName
:
'小明'
,
userAvatar
:
'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=100&h=100&fit=crop'
,
time
:
'10分钟前'
,
content
:
'今天参观了古城博物馆,真的太震撼了!强烈推荐大家去看看。'
,
likes
:
128
,
comments
:
32
},
{
id
:
2
,
userName
:
'小红'
,
userAvatar
:
'https://images.unsplash.com/photo-1494790108377-be9c29b29330?w=100&h=100&fit=crop'
,
time
:
'30分钟前'
,
content
:
'在中央公园野餐,天气真好,心情超棒!'
,
likes
:
89
,
comments
:
15
},
{
id
:
3
,
userName
:
'大伟'
,
userAvatar
:
'https://images.unsplash.com/photo-1500648767791-00dcc994a43e?w=100&h=100&fit=crop'
,
time
:
'1小时前'
,
content
:
'历史街区的夜景太美了,拍了很多照片!'
,
likes
:
256
,
comments
:
48
}
])
const
foods
=
ref
([
{
id
:
1
,
name
:
'特色烤鸭'
,
description
:
'百年老店,皮脆肉嫩,香气四溢。'
,
image
:
'https://images.unsplash.com/photo-1544025162-d566946569f2?w=400&h=300&fit=crop'
,
type
:
'传统美食'
,
price
:
88
},
{
id
:
2
,
name
:
'手工拉面'
,
description
:
'劲道爽滑,汤底浓郁,回味无穷。'
,
image
:
'https://images.unsplash.com/photo-1569718212165-3a8278d5f71f?w=400&h=300&fit=crop'
,
type
:
'面食'
,
price
:
35
},
{
id
:
3
,
name
:
'传统糕点'
,
description
:
'精致可口,甜而不腻,送礼佳品。'
,
image
:
'https://images.unsplash.com/photo-1509368959836-f7801b4d6c1a?w=400&h=300&fit=crop'
,
type
:
'甜品'
,
price
:
45
},
{
id
:
4
,
name
:
'本地海鲜'
,
description
:
'新鲜捕捞,烹饪精良,营养丰富。'
,
image
:
'https://images.unsplash.com/photo-1534604973900-85bd99082946?w=400&h=300&fit=crop'
,
type
:
'海鲜'
,
price
:
168
}
])
const
goBack
=
()
=>
{
router
.
back
()
}
</
script
>
<
style
scoped
>
.city-introduction
{
min-height
:
100vh
;
background-color
:
#f5f5f5
;
}
.header
{
display
:
flex
;
align-items
:
center
;
justify-content
:
space-between
;
padding
:
16px
;
background-color
:
white
;
position
:
sticky
;
top
:
0
;
z-index
:
10
;
box-shadow
:
0
1px
3px
rgba
(
0
,
0
,
0
,
0.1
);
}
.back-button
{
background
:
none
;
border
:
none
;
font-size
:
24px
;
cursor
:
pointer
;
padding
:
0
;
color
:
#333
;
width
:
30px
;
height
:
30px
;
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
}
.page-title
{
font-size
:
18px
;
font-weight
:
600
;
margin
:
0
;
color
:
#333
;
flex
:
1
;
text-align
:
center
;
}
.main-content
{
padding
:
16px
;
}
.city-banner
{
width
:
100%
;
height
:
200px
;
overflow
:
hidden
;
border-radius
:
12px
;
margin-bottom
:
24px
;
}
.banner-image
{
width
:
100%
;
height
:
100%
;
object-fit
:
cover
;
}
.city-info-section
,
.attractions-section
,
.nearby-users-section
,
.destination-dynamics-section
,
.food-section
{
background-color
:
white
;
border-radius
:
12px
;
padding
:
20px
;
margin-bottom
:
20px
;
box-shadow
:
0
2px
8px
rgba
(
0
,
0
,
0
,
0.08
);
}
.section-title
{
font-size
:
20px
;
font-weight
:
600
;
color
:
#333
;
margin
:
0
0
16px
0
;
padding-bottom
:
12px
;
border-bottom
:
2px
solid
#42b883
;
}
.city-description
p
{
font-size
:
15px
;
line-height
:
1.8
;
color
:
#666
;
margin
:
0
;
}
.attractions-grid
{
display
:
grid
;
grid-template-columns
:
repeat
(
auto-fill
,
minmax
(
280px
,
1
fr
));
gap
:
16px
;
}
.attraction-card
{
border
:
1px
solid
#e0e0e0
;
border-radius
:
12px
;
overflow
:
hidden
;
transition
:
all
0.3s
ease
;
}
.attraction-card
:hover
{
transform
:
translateY
(
-4px
);
box-shadow
:
0
4px
12px
rgba
(
0
,
0
,
0
,
0.15
);
}
.attraction-image
{
width
:
100%
;
height
:
180px
;
object-fit
:
cover
;
}
.attraction-info
{
padding
:
16px
;
}
.attraction-name
{
font-size
:
18px
;
font-weight
:
600
;
color
:
#333
;
margin
:
0
0
8px
0
;
}
.attraction-description
{
font-size
:
14px
;
color
:
#666
;
margin
:
0
0
12px
0
;
line-height
:
1.6
;
}
.attraction-meta
{
display
:
flex
;
justify-content
:
space-between
;
align-items
:
center
;
}
.attraction-rating
{
font-size
:
14px
;
color
:
#ff9800
;
font-weight
:
500
;
}
.attraction-price
{
font-size
:
18px
;
font-weight
:
700
;
color
:
#ff6b35
;
}
.users-list
{
display
:
grid
;
grid-template-columns
:
repeat
(
auto-fill
,
minmax
(
200px
,
1
fr
));
gap
:
12px
;
}
.user-card
{
display
:
flex
;
align-items
:
center
;
gap
:
12px
;
padding
:
12px
;
background-color
:
#f8f8f8
;
border-radius
:
8px
;
}
.user-avatar
{
width
:
50px
;
height
:
50px
;
border-radius
:
50%
;
object-fit
:
cover
;
}
.user-info
{
flex
:
1
;
}
.user-name
{
font-size
:
16px
;
font-weight
:
600
;
color
:
#333
;
margin
:
0
0
4px
0
;
}
.user-location
{
font-size
:
13px
;
color
:
#999
;
margin
:
0
0
4px
0
;
}
.user-status
{
display
:
inline-block
;
padding
:
4px
8px
;
border-radius
:
12px
;
font-size
:
12px
;
font-weight
:
500
;
}
.user-status.online
{
background-color
:
#e8f5e9
;
color
:
#4caf50
;
}
.user-status.traveling
{
background-color
:
#e3f2fd
;
color
:
#2196f3
;
}
.user-status.offline
{
background-color
:
#f5f5f5
;
color
:
#9e9e9e
;
}
.dynamics-list
{
display
:
flex
;
flex-direction
:
column
;
gap
:
16px
;
}
.dynamic-card
{
border
:
1px
solid
#e0e0e0
;
border-radius
:
12px
;
padding
:
16px
;
background-color
:
#fafafa
;
}
.dynamic-header
{
display
:
flex
;
align-items
:
center
;
gap
:
12px
;
margin-bottom
:
12px
;
}
.dynamic-avatar
{
width
:
40px
;
height
:
40px
;
border-radius
:
50%
;
object-fit
:
cover
;
}
.dynamic-user-info
{
flex
:
1
;
}
.dynamic-user-name
{
font-size
:
15px
;
font-weight
:
600
;
color
:
#333
;
margin
:
0
;
}
.dynamic-time
{
font-size
:
12px
;
color
:
#999
;
margin-left
:
8px
;
}
.dynamic-content
{
font-size
:
15px
;
line-height
:
1.6
;
color
:
#666
;
margin
:
0
0
12px
0
;
}
.dynamic-actions
{
display
:
flex
;
gap
:
16px
;
}
.action-btn
{
display
:
flex
;
align-items
:
center
;
gap
:
4px
;
background
:
none
;
border
:
none
;
font-size
:
14px
;
cursor
:
pointer
;
color
:
#666
;
padding
:
8px
12px
;
border-radius
:
20px
;
transition
:
all
0.3s
ease
;
}
.action-btn
:hover
{
background-color
:
#f0f0f0
;
color
:
#42b883
;
}
.food-grid
{
display
:
grid
;
grid-template-columns
:
repeat
(
auto-fill
,
minmax
(
280px
,
1
fr
));
gap
:
16px
;
}
.food-card
{
border
:
1px
solid
#e0e0e0
;
border-radius
:
12px
;
overflow
:
hidden
;
transition
:
all
0.3s
ease
;
}
.food-card
:hover
{
transform
:
translateY
(
-4px
);
box-shadow
:
0
4px
12px
rgba
(
0
,
0
,
0
,
0.15
);
}
.food-image
{
width
:
100%
;
height
:
180px
;
object-fit
:
cover
;
}
.food-info
{
padding
:
16px
;
}
.food-name
{
font-size
:
18px
;
font-weight
:
600
;
color
:
#333
;
margin
:
0
0
8px
0
;
}
.food-description
{
font-size
:
14px
;
color
:
#666
;
margin
:
0
0
12px
0
;
line-height
:
1.6
;
}
.food-meta
{
display
:
flex
;
justify-content
:
space-between
;
align-items
:
center
;
}
.food-type
{
font-size
:
13px
;
color
:
#42b883
;
background-color
:
#e8f5e9
;
padding
:
4px
8px
;
border-radius
:
4px
;
}
.food-price
{
font-size
:
18px
;
font-weight
:
700
;
color
:
#ff6b35
;
}
</
style
>
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment