Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in / Register
Toggle navigation
J
jiayun
Project
Project
Details
Activity
Releases
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
xuchentao
jiayun
Commits
bcc91c4a
Commit
bcc91c4a
authored
Aug 03, 2026
by
xuchentao
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix: 适配咨询入口的桌面端联系方式弹窗
parent
85a3e149
Pipeline
#443
passed with stage
in 15 seconds
Changes
3
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
81 additions
and
0 deletions
+81
-0
ContactDialog.astro
src/components/ContactDialog.astro
+31
-0
Base.astro
src/layouts/Base.astro
+34
-0
global.css
src/styles/global.css
+16
-0
No files found.
src/components/ContactDialog.astro
0 → 100644
View file @
bcc91c4a
---
import { site } from "../data/site";
import Icon from "./Icon.astro";
---
<dialog class="contact-dialog" data-contact-dialog aria-labelledby="contact-dialog-title">
<div class="contact-dialog__panel">
<button class="contact-dialog__close" type="button" data-contact-dialog-close aria-label="关闭联系方式弹窗">×</button>
<p class="eyebrow"><span></span>CONTACT US</p>
<h2 id="contact-dialog-title">联系我们</h2>
<p class="contact-dialog__intro">欢迎电话咨询或到店沟通,我们会结合你的实际情况介绍合适的服务方案。</p>
<dl class="contact-dialog__details">
<div>
<dt><Icon name="phone" size={21} />联系电话</dt>
<dd>{site.contact.phone}</dd>
</div>
<div>
<dt><Icon name="pin" size={21} />线下门店</dt>
<dd>{site.contact.address}</dd>
</div>
<div>
<dt><Icon name="clock" size={21} />服务时间</dt>
<dd>{site.contact.serviceHours}</dd>
</div>
</dl>
<div class="contact-dialog__actions">
<button class="button" type="button" data-copy-phone data-phone={site.contact.phone}>复制电话</button>
<a class="button button--secondary" href="/contact/">查看联系页面 <Icon name="arrow" size={17} /></a>
</div>
<p class="contact-dialog__status" data-copy-phone-status aria-live="polite"></p>
</div>
</dialog>
src/layouts/Base.astro
View file @
bcc91c4a
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
import "../styles/global.css";
import "../styles/global.css";
import logo from "../../白底黑字绿LOGO.svg";
import logo from "../../白底黑字绿LOGO.svg";
import { site } from "../data/site";
import { site } from "../data/site";
import ContactDialog from "../components/ContactDialog.astro";
interface Props {
interface Props {
title: string;
title: string;
...
@@ -67,6 +68,7 @@ const allLd = [organizationLd, ...pageLd.filter((item) => Object.keys(item).leng
...
@@ -67,6 +68,7 @@ const allLd = [organizationLd, ...pageLd.filter((item) => Object.keys(item).leng
<body>
<body>
<a
class=
"skip-link"
href=
"#main-content"
>
跳到主要内容
</a>
<a
class=
"skip-link"
href=
"#main-content"
>
跳到主要内容
</a>
<slot
/>
<slot
/>
<ContactDialog
/>
<script
is:inline
>
<script
is:inline
>
const
header
=
document
.
querySelector
(
'[data-header]'
);
const
header
=
document
.
querySelector
(
'[data-header]'
);
const
syncHeader
=
()
=>
header
?.
classList
.
toggle
(
'is-scrolled'
,
window
.
scrollY
>
12
);
const
syncHeader
=
()
=>
header
?.
classList
.
toggle
(
'is-scrolled'
,
window
.
scrollY
>
12
);
...
@@ -84,6 +86,38 @@ const allLd = [organizationLd, ...pageLd.filter((item) => Object.keys(item).leng
...
@@ -84,6 +86,38 @@ const allLd = [organizationLd, ...pageLd.filter((item) => Object.keys(item).leng
document
.
querySelectorAll
(
'[data-mobile-nav] a'
).
forEach
((
link
)
=>
{
document
.
querySelectorAll
(
'[data-mobile-nav] a'
).
forEach
((
link
)
=>
{
link
.
addEventListener
(
'click'
,
()
=>
link
.
closest
(
'details'
)?.
removeAttribute
(
'open'
));
link
.
addEventListener
(
'click'
,
()
=>
link
.
closest
(
'details'
)?.
removeAttribute
(
'open'
));
});
});
const
contactDialog
=
document
.
querySelector
(
'[data-contact-dialog]'
);
const
mobileUserAgent
=
/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i
.
test
(
navigator
.
userAgent
);
const
isIPadOS
=
/Macintosh/i
.
test
(
navigator
.
userAgent
)
&&
navigator
.
maxTouchPoints
>
1
;
const
isMobileDevice
=
navigator
.
userAgentData
?.
mobile
===
true
||
mobileUserAgent
||
isIPadOS
;
if
(
!
isMobileDevice
&&
contactDialog
instanceof
HTMLDialogElement
)
{
document
.
querySelectorAll
(
'a[href^="tel:"]'
).
forEach
((
link
)
=>
{
link
.
addEventListener
(
'click'
,
(
event
)
=>
{
event
.
preventDefault
();
contactDialog
.
showModal
();
});
});
contactDialog
.
querySelector
(
'[data-contact-dialog-close]'
)?.
addEventListener
(
'click'
,
()
=>
contactDialog
.
close
());
contactDialog
.
addEventListener
(
'click'
,
(
event
)
=>
{
if
(
event
.
target
===
contactDialog
)
contactDialog
.
close
();
});
const
copyButton
=
contactDialog
.
querySelector
(
'[data-copy-phone]'
);
const
copyStatus
=
contactDialog
.
querySelector
(
'[data-copy-phone-status]'
);
copyButton
?.
addEventListener
(
'click'
,
async
()
=>
{
const
phone
=
copyButton
.
getAttribute
(
'data-phone'
)
||
''
;
try
{
if
(
!
navigator
.
clipboard
)
throw
new
Error
(
'Clipboard API unavailable'
);
await
navigator
.
clipboard
.
writeText
(
phone
);
if
(
copyStatus
)
copyStatus
.
textContent
=
`电话
${
phone
}
已复制`
;
}
catch
{
if
(
copyStatus
)
copyStatus
.
textContent
=
`请手动记录电话:
${
phone
}
`
;
}
});
}
</script>
</script>
</body>
</body>
</html>
</html>
src/styles/global.css
View file @
bcc91c4a
...
@@ -33,6 +33,21 @@ h3 { font-size: 21px; }
...
@@ -33,6 +33,21 @@ h3 { font-size: 21px; }
.skip-link
{
position
:
fixed
;
left
:
18px
;
top
:
-80px
;
z-index
:
1000
;
background
:
var
(
--ink
);
color
:
#fff
;
padding
:
10px
16px
;
}
.skip-link
{
position
:
fixed
;
left
:
18px
;
top
:
-80px
;
z-index
:
1000
;
background
:
var
(
--ink
);
color
:
#fff
;
padding
:
10px
16px
;
}
.skip-link
:focus
{
top
:
18px
;
}
.skip-link
:focus
{
top
:
18px
;
}
.contact-dialog
{
width
:
min
(
620px
,
calc
(
100%
-
32px
));
max-width
:
none
;
padding
:
0
;
color
:
var
(
--ink
);
background
:
transparent
;
border
:
0
;
overflow
:
visible
;
}
.contact-dialog
::backdrop
{
background
:
rgba
(
35
,
25
,
22
,
.62
);
backdrop-filter
:
blur
(
5px
);
}
.contact-dialog__panel
{
position
:
relative
;
padding
:
42px
;
background
:
#fff
;
border-radius
:
24px
;
box-shadow
:
0
28px
80px
rgba
(
35
,
25
,
22
,
.24
);
}
.contact-dialog__close
{
position
:
absolute
;
top
:
18px
;
right
:
18px
;
width
:
38px
;
height
:
38px
;
padding
:
0
;
color
:
var
(
--muted
);
background
:
var
(
--background
);
border
:
0
;
border-radius
:
50%
;
font-size
:
26px
;
line-height
:
1
;
cursor
:
pointer
;
}
.contact-dialog__close
:hover
{
color
:
var
(
--primary
);
background
:
var
(
--primary-light
);
}
.contact-dialog
h2
{
margin-bottom
:
14px
;
font-size
:
38px
;
}
.contact-dialog__intro
{
margin-bottom
:
28px
;
color
:
var
(
--muted
);
font-size
:
14px
;
}
.contact-dialog__details
{
display
:
grid
;
gap
:
1px
;
margin
:
0
0
28px
;
overflow
:
hidden
;
background
:
var
(
--border
);
border
:
1px
solid
var
(
--border
);
border-radius
:
14px
;
}
.contact-dialog__details
>
div
{
display
:
grid
;
grid-template-columns
:
120px
1
fr
;
gap
:
20px
;
padding
:
16px
18px
;
background
:
#fff
;
}
.contact-dialog__details
dt
{
display
:
flex
;
align-items
:
center
;
gap
:
8px
;
color
:
var
(
--muted
);
font-size
:
12px
;
font-weight
:
700
;
}
.contact-dialog__details
dt
svg
{
flex
:
none
;
color
:
var
(
--primary
);
}
.contact-dialog__details
dd
{
margin
:
0
;
font-size
:
14px
;
font-weight
:
700
;
text-align
:
right
;
}
.contact-dialog__actions
{
display
:
flex
;
flex-wrap
:
wrap
;
gap
:
12px
;
}
.contact-dialog__status
{
min-height
:
24px
;
margin
:
12px
0
-12px
;
color
:
var
(
--primary
);
font-size
:
12px
;
}
.button
{
display
:
inline-flex
;
align-items
:
center
;
justify-content
:
center
;
gap
:
9px
;
min-height
:
52px
;
padding
:
0
24px
;
border
:
1px
solid
var
(
--primary
);
border-radius
:
999px
;
color
:
#fff
;
background
:
var
(
--primary
);
font-size
:
15px
;
font-weight
:
700
;
transition
:
.24s
ease
;
cursor
:
pointer
;
}
.button
{
display
:
inline-flex
;
align-items
:
center
;
justify-content
:
center
;
gap
:
9px
;
min-height
:
52px
;
padding
:
0
24px
;
border
:
1px
solid
var
(
--primary
);
border-radius
:
999px
;
color
:
#fff
;
background
:
var
(
--primary
);
font-size
:
15px
;
font-weight
:
700
;
transition
:
.24s
ease
;
cursor
:
pointer
;
}
.button
:hover
{
color
:
#fff
;
background
:
var
(
--primary-hover
);
border-color
:
var
(
--primary-hover
);
transform
:
translateY
(
-2px
);
box-shadow
:
0
12px
24px
rgba
(
255
,
125
,
65
,
.24
);
}
.button
:hover
{
color
:
#fff
;
background
:
var
(
--primary-hover
);
border-color
:
var
(
--primary-hover
);
transform
:
translateY
(
-2px
);
box-shadow
:
0
12px
24px
rgba
(
255
,
125
,
65
,
.24
);
}
.button--secondary
{
color
:
var
(
--ink
);
background
:
#fff
;
border-color
:
#d8d3d0
;
}
.button--secondary
{
color
:
var
(
--ink
);
background
:
#fff
;
border-color
:
#d8d3d0
;
}
...
@@ -172,4 +187,5 @@ h3 { font-size: 21px; }
...
@@ -172,4 +187,5 @@ h3 { font-size: 21px; }
.stats-grid
strong
{
font-size
:
26px
;
}
.stats-grid
div
{
padding
:
25px
18px
;
}
.service-grid
,
.article-grid
,
.process-grid
,
.values-grid
,
.fit-grid
,
.certification-cards
{
grid-template-columns
:
1
fr
;
}
.service-card
{
min-height
:
285px
;
}
.trust-proof
{
min-height
:
auto
;
padding
:
36px
28px
;
}
.faq-layout
{
gap
:
16px
;
}
.faq-list
summary
{
min-height
:
82px
;
}
.faq-list
details
>
p
{
padding-left
:
48px
;
}
.stats-grid
strong
{
font-size
:
26px
;
}
.stats-grid
div
{
padding
:
25px
18px
;
}
.service-grid
,
.article-grid
,
.process-grid
,
.values-grid
,
.fit-grid
,
.certification-cards
{
grid-template-columns
:
1
fr
;
}
.service-card
{
min-height
:
285px
;
}
.trust-proof
{
min-height
:
auto
;
padding
:
36px
28px
;
}
.faq-layout
{
gap
:
16px
;
}
.faq-list
summary
{
min-height
:
82px
;
}
.faq-list
details
>
p
{
padding-left
:
48px
;
}
.page-hero
{
padding
:
62px
0
72px
;
}
.page-hero
::after
{
display
:
none
;
}
.breadcrumb
{
margin-bottom
:
30px
;
}
.service-detail-list
{
gap
:
70px
;
}
.about-story__facts
,
.service-detail__summary
,
.visit-panel
{
min-height
:
auto
;
padding
:
36px
28px
;
}
.join-hero
{
padding
:
65px
0
;
}
.join-card
{
padding
:
28px
;
}
.contact-hero
{
padding
:
65px
0
;
}
.contact-number
a
{
font-size
:
32px
;
}
.visit-tips
.container
{
grid-template-columns
:
1
fr
;
}
.visit-tips
.container
>
*
{
padding
:
22px
;
}
.article-card__body
{
padding
:
24px
;
}
.article-page
>
header
{
padding
:
58px
0
;
}
.article-layout
{
padding-top
:
48px
;
padding-bottom
:
80px
;
}
.article-content
{
font-size
:
15px
;
}
.empty-state
{
padding
:
55px
24px
;
}
.page-hero
{
padding
:
62px
0
72px
;
}
.page-hero
::after
{
display
:
none
;
}
.breadcrumb
{
margin-bottom
:
30px
;
}
.service-detail-list
{
gap
:
70px
;
}
.about-story__facts
,
.service-detail__summary
,
.visit-panel
{
min-height
:
auto
;
padding
:
36px
28px
;
}
.join-hero
{
padding
:
65px
0
;
}
.join-card
{
padding
:
28px
;
}
.contact-hero
{
padding
:
65px
0
;
}
.contact-number
a
{
font-size
:
32px
;
}
.visit-tips
.container
{
grid-template-columns
:
1
fr
;
}
.visit-tips
.container
>
*
{
padding
:
22px
;
}
.article-card__body
{
padding
:
24px
;
}
.article-page
>
header
{
padding
:
58px
0
;
}
.article-layout
{
padding-top
:
48px
;
padding-bottom
:
80px
;
}
.article-content
{
font-size
:
15px
;
}
.empty-state
{
padding
:
55px
24px
;
}
.cta-section
{
padding-bottom
:
68px
;
}
.cta-panel
{
padding
:
36px
26px
;
}
.cta-actions
{
width
:
100%
;
}
.cta-actions
.button
{
width
:
100%
;
}
.footer-grid
{
grid-template-columns
:
1
fr
1
fr
;
}
.footer-brand
,
.footer-contact
{
grid-column
:
1
/
-1
;
}
.footer-bottom
{
flex-direction
:
column
;
gap
:
8px
;
}
.footer-logo
{
width
:
170px
;
}
.cta-section
{
padding-bottom
:
68px
;
}
.cta-panel
{
padding
:
36px
26px
;
}
.cta-actions
{
width
:
100%
;
}
.cta-actions
.button
{
width
:
100%
;
}
.footer-grid
{
grid-template-columns
:
1
fr
1
fr
;
}
.footer-brand
,
.footer-contact
{
grid-column
:
1
/
-1
;
}
.footer-bottom
{
flex-direction
:
column
;
gap
:
8px
;
}
.footer-logo
{
width
:
170px
;
}
.contact-dialog__panel
{
padding
:
34px
22px
26px
;
}
.contact-dialog
h2
{
font-size
:
32px
;
}
.contact-dialog__details
>
div
{
grid-template-columns
:
1
fr
;
gap
:
4px
;
}
.contact-dialog__details
dd
{
padding-left
:
29px
;
text-align
:
left
;
}
.contact-dialog__actions
.button
{
width
:
100%
;
}
}
}
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