重构 monorepo 并完善网页端订阅与首页体验
- 迁移为 frontend-web、frontend-electron、backend-web 与 docker 部署结构 - 网页端:订阅门禁二次弹窗、套餐/支付组件化、顶栏分组对齐 - 首页:最近文件与模板库布局优化,缩略图对齐,下载与删除操作 - 新增管理后台、支付与云端文件 API,更新 README 与项目规范 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,241 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||
<title>SoonDesign</title>
|
||||
<link rel="stylesheet" href="../vendor/layui/css/layui.css">
|
||||
|
||||
<style>
|
||||
/* =========================================
|
||||
1. 全局布局
|
||||
========================================= */
|
||||
* { box-sizing: border-box; }
|
||||
|
||||
html, body {
|
||||
width: 100%; height: 100%; overflow: hidden; margin: 0; padding: 0;
|
||||
background-color: #1E1E1E;
|
||||
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
|
||||
.layui-fluid.main { height: 100%; padding: 0; display: flex; flex-direction: column; }
|
||||
.layui-row { height: 100%; display: flex; }
|
||||
|
||||
/* =========================================
|
||||
2. 左侧栏 (#31373D)
|
||||
========================================= */
|
||||
.layui-col-md2 {
|
||||
width: 260px !important; flex-shrink: 0;
|
||||
background-color: #31373D; border-right: 1px solid #1E1E1E;
|
||||
height: 100%; overflow-y: auto;
|
||||
}
|
||||
|
||||
.left { padding: 20px; }
|
||||
.left h1 {
|
||||
font-size: 18px; color: #fff; margin-bottom: 25px;
|
||||
border-left: 4px solid #009688; padding-left: 10px;
|
||||
line-height: 1; font-weight: 500;
|
||||
}
|
||||
.left .card { margin-bottom: 25px; cursor: pointer; }
|
||||
|
||||
/* 左侧容器 */
|
||||
.left .rect {
|
||||
width: 100%; height: 150px;
|
||||
background-color: #252A2E; border: 1px solid #444; border-radius: 4px;
|
||||
display: flex; flex-direction: column;
|
||||
align-items: center; justify-content: center;
|
||||
transition: all 0.3s; position: relative;
|
||||
}
|
||||
.left .rect:hover { border-color: #009688; background-color: #3E464F; transform: translateY(-2px); }
|
||||
|
||||
/* 左侧图片:固定 80px */
|
||||
.left .rect img {
|
||||
width: 80px; height: 80px; object-fit: contain;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
/* 左侧卡片不缩放 */
|
||||
.left .rect1 img { transform: none !important; }
|
||||
.left .tip { color: #ccc; font-size: 13px; text-align: center; }
|
||||
|
||||
/* =========================================
|
||||
3. 右侧栏 (#1E252D)
|
||||
========================================= */
|
||||
.layui-col-md10 {
|
||||
flex: 1; background-color: #1E252D; height: 100%;
|
||||
overflow: hidden; position: relative;
|
||||
}
|
||||
.right { padding: 30px; height: 100%; display: flex; flex-direction: column; }
|
||||
|
||||
#openfile {
|
||||
background-color: #009688; border: none; height: 34px; line-height: 34px;
|
||||
padding: 0 20px; font-size: 13px; border-radius: 3px; margin-right: 20px;
|
||||
color: #fff; cursor: pointer;
|
||||
}
|
||||
.recent { font-size: 18px; color: #ddd; vertical-align: middle; font-weight: 500; }
|
||||
|
||||
/* 列表 Grid */
|
||||
.card-list {
|
||||
margin-top: 20px; flex: 1; overflow-y: auto;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
|
||||
gap: 30px; align-content: start;
|
||||
padding: 10px; padding-bottom: 40px;
|
||||
}
|
||||
|
||||
/* 【修复1】统一背景框大小 */
|
||||
.card-list .rect {
|
||||
width: 100%;
|
||||
height: 160px; /* 固定高度,确保对齐 */
|
||||
background-color: #252A2E;
|
||||
border: 1px solid #333;
|
||||
border-radius: 6px;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
transition: all 0.2s;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
}
|
||||
.card-list .rect:hover { border-color: #009688; background-color: #3E464F; }
|
||||
|
||||
/* 【修复2】加大光盘图片尺寸 */
|
||||
.card-list .rect img {
|
||||
width: 100%;
|
||||
height: 135px; /* 【改大】增加图片高度,让光盘看起来很大 */
|
||||
object-fit: contain;
|
||||
margin-bottom: 0;
|
||||
background-color: #1E1E1E;
|
||||
border-radius: 4px;
|
||||
padding: 2px; /* 减少内边距,让图更大 */
|
||||
transition: transform 0.3s;
|
||||
}
|
||||
|
||||
/* 【修复3】卡片单独缩小,背景框不变 */
|
||||
.card-list .rect1 img {
|
||||
transform: scale(0.8);
|
||||
}
|
||||
.card-list .rect1:hover img {
|
||||
transform: scale(0.85);
|
||||
}
|
||||
|
||||
/* 文字 */
|
||||
.card-list .tip {
|
||||
color: #aaa; font-size: 12px; width: 100%; text-align: center;
|
||||
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
||||
height: 25px; line-height: 25px;
|
||||
}
|
||||
.card-list .rect:hover .tip { color: #fff; }
|
||||
|
||||
/* =========================================
|
||||
4. 光盘遮罩 (中心对齐修正)
|
||||
========================================= */
|
||||
.rect:not(.rect1) { position: relative; }
|
||||
|
||||
.rect:not(.rect1)::after {
|
||||
content: ''; position: absolute; left: 50%;
|
||||
/* 【计算修正】
|
||||
Box高 160px, Box中心Y=80px
|
||||
Img高 135px, Img中心Y = 135/2 = 67.5px
|
||||
偏移量 = 67.5 - 80 = -12.5px
|
||||
*/
|
||||
top: 50%;
|
||||
transform: translate(-50%, calc(-50% - 12.5px));
|
||||
|
||||
width: 24px; height: 24px;
|
||||
border-radius: 50%; background-color: #252A2E;
|
||||
box-shadow: inset 0 0 2px rgba(0,0,0,0.8);
|
||||
border: 1px solid rgba(255,255,255,0.1);
|
||||
z-index: 10; pointer-events: none;
|
||||
}
|
||||
|
||||
/* 左侧单独修正 */
|
||||
.left .rect:not(.rect1)::after {
|
||||
width: 16px; height: 16px;
|
||||
/* 左侧Box 150px, Img 80px + margin 15px -> 内容高 95px -> 垂直居中
|
||||
Img中心大概在 Box 顶部偏下的位置,这里微调 */
|
||||
transform: translate(-50%, calc(-50% - 15px));
|
||||
}
|
||||
|
||||
/* =========================================
|
||||
5. 语言选择器
|
||||
========================================= */
|
||||
#language_select {
|
||||
position: absolute; top: 30px; right: 30px;
|
||||
background-color: #31373D; color: #ccc;
|
||||
border: 1px solid #444; padding: 5px;
|
||||
height: 30px; width: 100px;
|
||||
z-index: 999; outline: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="layui-fluid main">
|
||||
<div class="layui-row">
|
||||
<div class="layui-col-md2">
|
||||
<div class="left">
|
||||
<h1 language="m" zh="新建" ozh="新建" en="New"></h1>
|
||||
<div class="card" id="new1">
|
||||
<div class="rect">
|
||||
<img src="../assets/images/bg_1.png">
|
||||
<div class="tip" language="m" zh="空白光盘模板" ozh="空白光碟模闆" en="Disc Template"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card" id="new2">
|
||||
<div class="rect rect1">
|
||||
<img src="../assets/images/bg_2.png">
|
||||
<div class="tip" language="m" zh="空白卡片模板" ozh="空白卡片模闆" en="Card Template"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-col-md10">
|
||||
<div class="right">
|
||||
<div>
|
||||
<button class="layui-btn layui-btn-normal" id="openfile" language="m" zh="打开其他文件" ozh="打開其他文件"
|
||||
en="Open"></button>
|
||||
<span class="recent" language="m" zh="最近文件" ozh="最近文件" en="Recent Files"></span>
|
||||
</div>
|
||||
<div class="card-list">
|
||||
</div>
|
||||
</div>
|
||||
<select class="ui-select" id="language_select">
|
||||
<option value='zh'>中文-简体</option>
|
||||
<option value='ozh'>中文-繁體</option>
|
||||
<option value='en'>English</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="../js/common/asset-base.js"></script>
|
||||
<script src="../vendor/layui/layui.js"></script>
|
||||
<script>
|
||||
(function() {
|
||||
const path = require('path'), fs = require('fs'), remote = require('@electron/remote');
|
||||
const appPath = (() => { try { return remote.app.getAppPath(); } catch(e) { return __dirname || process.cwd(); } })();
|
||||
try {
|
||||
require(path.join(appPath, 'js', 'common', 'asset-base.js'));
|
||||
require(path.join(appPath, 'js', 'platform', 'electron.js'));
|
||||
} catch (e) { console.warn('platform/electron load:', e); }
|
||||
const jsPath = path.join(appPath, 'js', 'index.js');
|
||||
if (fs.existsSync(jsPath)) {
|
||||
try {
|
||||
require(jsPath);
|
||||
console.log('[加载] ✅ index → index.js');
|
||||
} catch(e) {
|
||||
alert('文件加载失败!\n\n错误: ' + e.message);
|
||||
}
|
||||
} else {
|
||||
alert('文件不存在!\n\n请检查:' + jsPath);
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user