初始化鸿蒙应用展示平台项目 - 前后端分离架构
This commit is contained in:
589
templates/recommend.html
Executable file
589
templates/recommend.html
Executable file
@@ -0,0 +1,589 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<!-- 推荐应用展示区域 -->
|
||||
<div class="app-recommendation">
|
||||
<a href="javascript:history.back()" class="close-button">×</a>
|
||||
|
||||
<div class="app-header">
|
||||
<div class="header-title-row">
|
||||
<div class="app-header-icon">
|
||||
<img src="{{ url_for('static', filename='shuli.png') }}" alt="书立">
|
||||
</div>
|
||||
<div class="title-section">
|
||||
<h1>书立<a href="https://appgallery.huawei.com/app/detail?id=com.codeartel.slinote" class="header-install-button">安装</a></h1>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="app-description">
|
||||
书立是一款本地优先的富文本笔记软件,拥有出众的性能,丝滑的动画,小巧的体积,丰富的功能。
|
||||
</div>
|
||||
|
||||
<div class="feature-list">
|
||||
<div class="feature-item">
|
||||
<div class="feature-icon">🎨</div>
|
||||
<div class="feature-content">
|
||||
<div class="feature-title">富文本编辑器</div>
|
||||
<div class="feature-description">
|
||||
编辑器作为笔记软件的核心,其强大与否直接决定了软件的上限,书立的编辑器支持大量富文本结构,并且渲染速度很快,可以编辑超过千万字的文档。
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="showcase-wrapper">
|
||||
<div class="showcase-image">
|
||||
<img src="{{ url_for('static', filename='showcase1.png') }}" alt="富文本编辑器展示">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="feature-item">
|
||||
<div class="feature-icon">🎋</div>
|
||||
<div class="feature-content">
|
||||
<div class="feature-title">富目录树</div>
|
||||
<div class="feature-description">
|
||||
书立的目录树也是富文本,笔记的标题与大纲自动生成目录树,对标题与大纲设置的富文本会自动渲染到目录中,由此可以设计出丰富的目录结构,如:图文目录,表情目录,任务目录,彩色目录。
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="showcase-wrapper">
|
||||
<div class="showcase-image">
|
||||
<img src="{{ url_for('static', filename='showcase2.png') }}" alt="富目录树展示">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="feature-item">
|
||||
<div class="feature-icon">🗒</div>
|
||||
<div class="feature-content">
|
||||
<div class="feature-title">嵌套表格</div>
|
||||
<div class="feature-description">
|
||||
嵌套表格是书立的一大亮点,支持表格的笔记软件有很多,支持表格内富文本编辑的也有一些,支持表格内嵌套表格的软件很少,书立是少数支持表格嵌套还能富文本编辑的软件之一。书立的表格不仅可以规划信息结构,还可以做UI布局,比如使用表格嵌套+合并单元格设计一个康奈尔笔记模板,或者做四象限任务管理。
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="showcase-wrapper">
|
||||
<div class="showcase-image">
|
||||
<img src="{{ url_for('static', filename='showcase3.png') }}" alt="嵌套表格展示">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="feature-item">
|
||||
<div class="feature-icon">🪐️</div>
|
||||
<div class="feature-content">
|
||||
<div class="feature-title">体积小巧</div>
|
||||
<div class="feature-description">
|
||||
鸿蒙移动端安装包体积只有 827kb(富目录树 + 富文本编辑器 + 富文本嵌套表格 + 全文搜索 + 导入导出 + 浮动目录 )
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="app-info">
|
||||
<div class="company-info">
|
||||
<div class="company-logo">
|
||||
<img src="{{ url_for('static', filename='shuli.png') }}" alt="书立">
|
||||
</div>
|
||||
<h3 class="app-name">书立</h3>
|
||||
<p class="app-category">实用工具 | 笔记</p>
|
||||
<p class="company-name">北京源码觉醒科技有限公司</p>
|
||||
</div>
|
||||
<div class="install-section">
|
||||
<a href="https://appgallery.huawei.com/app/detail?id=com.codeartel.slinote" class="download-button">安装</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bottom-popup">
|
||||
<div class="popup-content">
|
||||
<div class="popup-app-info">
|
||||
<img src="{{ url_for('static', filename='shuli.png') }}" alt="书立" class="popup-app-icon">
|
||||
<span class="popup-app-name">书立</span>
|
||||
</div>
|
||||
<a href="https://appgallery.huawei.com/app/detail?id=com.codeartel.slinote" class="popup-install-button">安装</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.app-recommendation {
|
||||
background: white;
|
||||
border-radius: 24px;
|
||||
padding: 20px;
|
||||
margin: 20px auto;
|
||||
max-width: 800px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.close-button {
|
||||
position: fixed;
|
||||
top: 20px;
|
||||
right: 20px;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
backdrop-filter: blur(20px);
|
||||
-webkit-backdrop-filter: blur(20px);
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 24px;
|
||||
color: #666;
|
||||
text-decoration: none;
|
||||
line-height: 1;
|
||||
transition: all 0.2s ease;
|
||||
cursor: pointer;
|
||||
z-index: 1001;
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.close-button:hover {
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
/* 暗色模式适配 */
|
||||
[data-theme="dark"] .close-button {
|
||||
background: rgba(26, 26, 26, 0.8);
|
||||
border-color: rgba(255, 255, 255, 0.1);
|
||||
color: #999;
|
||||
}
|
||||
|
||||
[data-theme="dark"] .close-button:hover {
|
||||
background: rgba(26, 26, 26, 0.9);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.close-button {
|
||||
top: 16px;
|
||||
right: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.header-title-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 15px;
|
||||
margin-top: 25px;
|
||||
}
|
||||
|
||||
.header-title-row h1 {
|
||||
font-size: 28px;
|
||||
font-weight: 600;
|
||||
margin: 0;
|
||||
color: #333;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
.header-install-button {
|
||||
background: #0066ff;
|
||||
color: white;
|
||||
padding: 6px 24px;
|
||||
border-radius: 100px;
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
text-decoration: none;
|
||||
transition: background-color 0.2s ease;
|
||||
margin-left: 15px;
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.header-install-button:active {
|
||||
background: #0052cc;
|
||||
}
|
||||
|
||||
.site-header {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.app-description {
|
||||
font-size: 16px;
|
||||
line-height: 1.6;
|
||||
color: #666;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.feature-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 25px;
|
||||
}
|
||||
|
||||
.feature-item {
|
||||
display: flex;
|
||||
gap: 15px;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.feature-icon {
|
||||
font-size: 24px;
|
||||
color: #7a5af8;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.feature-content {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.feature-title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
margin: 0 0 8px 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.feature-description {
|
||||
font-size: 15px;
|
||||
line-height: 1.6;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
|
||||
.app-info {
|
||||
margin: 30px 0 0px 0;
|
||||
padding: 20px 20px 30px 20px;
|
||||
text-align: center;
|
||||
border: 1px solid #eee;
|
||||
border-radius: 12px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.company-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.company-logo {
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
margin-bottom: 12px;
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.company-logo img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.company-name {
|
||||
font-size: 14px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.install-section {
|
||||
margin-top: 20px;
|
||||
padding: 0 20px;
|
||||
max-width: 500px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.download-button {
|
||||
background: #0066ff;
|
||||
color: white;
|
||||
padding: 6px 24px;
|
||||
border-radius: 100px;
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
text-decoration: none;
|
||||
transition: background-color 0.2s ease;
|
||||
}
|
||||
|
||||
download-button:active {
|
||||
background: #0052cc;
|
||||
}
|
||||
|
||||
[data-theme="dark"] .close-button {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
[data-theme="dark"] .close-button:hover {
|
||||
background: rgba(255, 255, 255, 0.15);
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.app-recommendation {
|
||||
margin: 10px;
|
||||
padding: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
.app-header {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.app-header-icon {
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.app-header-icon img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.showcase-wrapper {
|
||||
margin: 5px 0 25px;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.showcase-image {
|
||||
width: auto;
|
||||
height: auto;
|
||||
max-width: 100%;
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
background: #f5f5f5;
|
||||
}
|
||||
|
||||
.showcase-image img {
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
/* 暗色模式适配 */
|
||||
[data-theme="dark"] .showcase-image {
|
||||
background: #2a2a2a;
|
||||
}
|
||||
|
||||
/* 响应式调整 */
|
||||
@media (max-width: 768px) {
|
||||
.showcase-image {
|
||||
width: auto;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
|
||||
/* 暗色模式适配 */
|
||||
[data-theme="dark"] .app-info {
|
||||
border-color: #333;
|
||||
background: #242424;
|
||||
}
|
||||
|
||||
.title-section {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.app-name {
|
||||
font-size: 80px;
|
||||
font-weight: 700;
|
||||
color: #333;
|
||||
margin: 0 0 4px;
|
||||
}
|
||||
|
||||
.app-category {
|
||||
font-size: 13px;
|
||||
color: #666;
|
||||
margin: 0 0 8px;
|
||||
}
|
||||
|
||||
/* 暗色模式适配 */
|
||||
[data-theme="dark"] .app-name {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
[data-theme="dark"] .app-category {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
footer,
|
||||
.footer {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* 暗色模式适配 */
|
||||
[data-theme="dark"] .download-button {
|
||||
background: linear-gradient(to right, #0066ff, #0052cc);
|
||||
}
|
||||
|
||||
.bottom-popup {
|
||||
position: fixed;
|
||||
bottom: 20px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%) translateY(200px);
|
||||
width: calc(100% - 40px);
|
||||
max-width: 800px;
|
||||
background: rgba(255, 255, 255, 0.6);
|
||||
backdrop-filter: blur(25px) saturate(180%);
|
||||
-webkit-backdrop-filter: blur(25px) saturate(180%);
|
||||
padding: 16px 24px;
|
||||
border-radius: 16px;
|
||||
transition-property: transform, opacity, visibility;
|
||||
transition-duration: 0.6s;
|
||||
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
||||
z-index: 1000;
|
||||
box-shadow: 0 4px 24px rgba(0, 0, 0, 0.15);
|
||||
border: 1px solid rgba(255, 255, 255, 0.3);
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.bottom-popup.show {
|
||||
transform: translateX(-50%) translateY(0);
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
transition-duration: 0.4s; /* 显示时可以快一点 */
|
||||
}
|
||||
|
||||
.popup-content {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.popup-app-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.popup-app-icon {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 8px;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.popup-app-name {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.popup-install-button {
|
||||
background: #0066ff;
|
||||
color: white;
|
||||
padding: 8px 24px;
|
||||
border-radius: 100px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
text-decoration: none;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.popup-install-button:active {
|
||||
background: #0052cc;
|
||||
transform: scale(0.98);
|
||||
}
|
||||
|
||||
/* 暗色模式适配 */
|
||||
[data-theme="dark"] .bottom-popup {
|
||||
background: rgba(26, 26, 26, 0.6);
|
||||
border-color: rgba(255, 255, 255, 0.15);
|
||||
box-shadow: 0 4px 24px rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
|
||||
[data-theme="dark"] .popup-app-name {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.bottom-popup {
|
||||
bottom: 16px;
|
||||
width: calc(100% - 32px);
|
||||
padding: 12px 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.app-info .app-name {
|
||||
font-size: 20px;
|
||||
font-weight: 800;
|
||||
color: #333;
|
||||
margin: 0 0 8px;
|
||||
}
|
||||
|
||||
/* 暗色模式适配 */
|
||||
[data-theme="dark"] .app-info .app-name {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* 调整过渡动画 */
|
||||
.bottom-popup {
|
||||
transition-property: transform, opacity, visibility !important;
|
||||
transition-duration: 0.6s !important;
|
||||
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1) !important;
|
||||
}
|
||||
|
||||
.bottom-popup.show {
|
||||
transition-duration: 0.4s !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const popup = document.querySelector('.bottom-popup');
|
||||
const appInfo = document.querySelector('.app-info');
|
||||
let isTransitioning = false;
|
||||
|
||||
function checkScroll() {
|
||||
const appInfoRect = appInfo.getBoundingClientRect();
|
||||
const windowHeight = window.innerHeight;
|
||||
|
||||
// 当 app-info 的顶部进入视口底部 100px 范围内时就隐藏弹窗
|
||||
if (appInfoRect.top <= windowHeight + 100) {
|
||||
if (!isTransitioning && popup.classList.contains('show')) {
|
||||
isTransitioning = true;
|
||||
popup.style.transition = 'all 0.6s cubic-bezier(0.4, 0, 0.2, 1)';
|
||||
popup.classList.remove('show');
|
||||
setTimeout(() => {
|
||||
isTransitioning = false;
|
||||
}, 600);
|
||||
}
|
||||
} else {
|
||||
if (!isTransitioning && !popup.classList.contains('show')) {
|
||||
isTransitioning = true;
|
||||
popup.style.transition = 'all 0.4s cubic-bezier(0.4, 0, 0.2, 1)';
|
||||
popup.classList.add('show');
|
||||
setTimeout(() => {
|
||||
isTransitioning = false;
|
||||
}, 400);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 使用 throttle 优化滚动事件
|
||||
let ticking = false;
|
||||
window.addEventListener('scroll', () => {
|
||||
if (!ticking) {
|
||||
window.requestAnimationFrame(() => {
|
||||
checkScroll();
|
||||
ticking = false;
|
||||
});
|
||||
ticking = true;
|
||||
}
|
||||
});
|
||||
|
||||
// 初始检查
|
||||
checkScroll();
|
||||
});
|
||||
</script>
|
||||
|
||||
{% endblock %}
|
||||
{% block footer %}{% endblock %}
|
||||
Reference in New Issue
Block a user