Преглед изворни кода

add new tools: poster maker

zxlie пре 9 месеци
родитељ
комит
d6ca7ea8d2

+ 5 - 3
.cursorignore

@@ -5,6 +5,8 @@
 node_modules/
 package-lock.json
 Users/
-output/apps/
-output-firefox/apps/
-output-edge/apps/
+output/
+output-firefox/
+output-edge/
+
+# 配置文件

+ 8 - 0
apps/background/tools.js

@@ -248,6 +248,14 @@ let toolMap = {
             text: '图表制作工具'
         }]
     },
+    'poster-maker': {
+        name: '海报生成工具',
+        tips: '快速创建营销推广海报,支持朋友圈、小红书等多种模板,可自定义文字、图片和配色',
+        menuConfig: [{
+            icon: '🖼️',
+            text: '海报生成工具'
+        }]
+    },
     'svg-converter': {
         name: 'SVG转为图片',
         tips: '支持SVG文件转换为PNG、JPG、WEBP等格式,可自定义输出尺寸,支持文件拖放和URL导入',

+ 3 - 0
apps/options/market.css

@@ -1,3 +1,6 @@
+body{
+    margin: 0;
+}
 .market-container {
     padding: 20px;
     margin-top: 10px;

Разлика између датотеке није приказан због своје велике величине
+ 5 - 0
apps/poster-maker/css/all.min.css


+ 676 - 0
apps/poster-maker/css/main.css

@@ -0,0 +1,676 @@
+@import url("all.min.css");
+
+/* 全局样式 */
+:root {
+  --primary-color: #4a6bff;
+  --secondary-color: #6c757d;
+  --background-color: #f8f9fa;
+  --card-bg: #ffffff;
+  --text-color: #333333;
+  --border-color: #e0e0e0;
+  --success-color: #28a745;
+  --danger-color: #dc3545;
+  --shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
+  --radius: 8px;
+  --transition: all 0.3s ease;
+}
+
+* {
+  margin: 0;
+  padding: 0;
+  box-sizing: border-box;
+}
+
+body {
+  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
+  background-color: var(--background-color);
+  color: var(--text-color);
+  line-height: 1.6;
+}
+
+.app-container {
+  max-width: 1200px;
+  margin: 0 auto;
+  padding: 0 20px 20px;
+}
+
+/* 头部样式 */
+.app-header {
+  text-align: center;
+  margin-bottom: 20px;
+  padding: 15px 0;
+  border-bottom: 1px solid var(--border-color);
+}
+
+.app-header h1 {
+  font-size: 2.2rem;
+  color: var(--primary-color);
+  margin-bottom: 5px;
+}
+
+.app-description {
+  font-size: 1rem;
+  color: var(--secondary-color);
+}
+
+/* 主内容区域 */
+.app-main {
+  display: flex;
+  gap: 20px;
+  max-height: calc(100vh - 150px);
+}
+
+.tool-panel {
+  flex: 1;
+  display: flex;
+  flex-direction: column;
+  background-color: var(--card-bg);
+  border-radius: var(--radius);
+  box-shadow: var(--shadow);
+  overflow: hidden;
+}
+
+.preview-panel {
+  flex: 1;
+  background-color: var(--card-bg);
+  border-radius: var(--radius);
+  padding: 15px;
+  box-shadow: var(--shadow);
+  display: flex;
+  flex-direction: column;
+}
+
+/* 面板选项卡 */
+.panel-tabs {
+  display: flex;
+  border-bottom: 1px solid var(--border-color);
+}
+
+.panel-tab {
+  flex: 1;
+  padding: 12px 15px;
+  background: none;
+  border: none;
+  font-size: 0.95rem;
+  font-weight: 500;
+  color: var(--secondary-color);
+  cursor: pointer;
+  transition: var(--transition);
+}
+
+.panel-tab:hover {
+  background-color: rgba(0, 0, 0, 0.03);
+}
+
+.panel-tab.active {
+  color: var(--primary-color);
+  border-bottom: 2px solid var(--primary-color);
+}
+
+.panel-content {
+  flex: 1;
+  overflow: hidden;
+  position: relative;
+}
+
+.tab-content {
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  padding: 15px;
+  overflow-y: auto;
+  display: none;
+}
+
+.tab-content.active {
+  display: block;
+}
+
+/* 模板选择区域 */
+.template-selection {
+  height: 100%;
+}
+
+.template-categories {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 8px;
+  margin-bottom: 12px;
+}
+
+.category-btn {
+  padding: 5px 10px;
+  border-radius: 16px;
+  border: 1px solid var(--border-color);
+  background-color: white;
+  font-size: 0.85rem;
+  cursor: pointer;
+  transition: var(--transition);
+}
+
+.category-btn:hover {
+  background-color: var(--background-color);
+}
+
+.category-btn.active {
+  background-color: var(--primary-color);
+  color: white;
+  border-color: var(--primary-color);
+}
+
+.templates-container {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
+  gap: 12px;
+  height: calc(100% - 40px);
+  overflow-y: auto;
+  padding: 5px;
+  align-items: start; /* 确保项目从顶部对齐 */
+}
+
+.template-item {
+  border: 2px solid transparent;
+  border-radius: var(--radius);
+  overflow: hidden;
+  cursor: pointer;
+  transition: var(--transition);
+  position: relative;
+  display: flex;
+  flex-direction: column;
+  height: 130px; /* 固定高度 */
+}
+
+.template-item:hover {
+  transform: translateY(-3px);
+  box-shadow: var(--shadow);
+}
+
+.template-item.selected {
+  border-color: var(--primary-color);
+}
+
+.template-thumbnail {
+  width: 100%;
+  height: 100%;
+  object-fit: cover;
+  flex: 1;
+}
+
+.template-name {
+  font-size: 0.8rem;
+  text-align: center;
+  padding: 4px;
+  background-color: rgba(0, 0, 0, 0.7);
+  color: white;
+  position: absolute;
+  bottom: 0;
+  width: 100%;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+
+/* 编辑区域 */
+.editor-panel {
+  height: 100%;
+}
+
+.edit-form {
+  display: flex;
+  flex-direction: column;
+  gap: 12px;
+  max-height: 100%;
+  overflow-y: auto;
+  padding-right: 5px;
+}
+
+.form-group {
+  display: flex;
+  flex-direction: column;
+}
+
+.form-group label {
+  margin-bottom: 4px;
+  font-weight: 500;
+  font-size: 0.9rem;
+}
+
+.form-control {
+  padding: 8px 10px;
+  border: 1px solid var(--border-color);
+  border-radius: var(--radius);
+  font-size: 0.95rem;
+  transition: var(--transition);
+}
+
+.form-control:focus {
+  outline: none;
+  border-color: var(--primary-color);
+  box-shadow: 0 0 0 2px rgba(74, 107, 255, 0.2);
+}
+
+.color-picker {
+  height: 36px;
+  padding: 4px;
+  border: 1px solid var(--border-color);
+  border-radius: var(--radius);
+}
+
+/* 高级选项区域 */
+.advanced-options {
+  display: flex;
+  flex-direction: column;
+  gap: 20px;
+}
+
+.option-group {
+  background-color: #f8f9fa;
+  border-radius: var(--radius);
+  padding: 15px;
+}
+
+.option-group h3 {
+  font-size: 1rem;
+  margin-bottom: 12px;
+  color: var(--primary-color);
+  font-weight: 600;
+}
+
+.range-slider-container {
+  display: flex;
+  align-items: center;
+  gap: 10px;
+}
+
+.range-slider {
+  flex: 1;
+  -webkit-appearance: none;
+  height: 6px;
+  border-radius: 3px;
+  background: #ddd;
+  outline: none;
+}
+
+.range-slider::-webkit-slider-thumb {
+  -webkit-appearance: none;
+  appearance: none;
+  width: 16px;
+  height: 16px;
+  border-radius: 50%;
+  background: var(--primary-color);
+  cursor: pointer;
+}
+
+.range-value {
+  width: 40px;
+  font-size: 0.85rem;
+  text-align: right;
+}
+
+.watermark-options {
+  margin-top: 10px;
+  padding-top: 10px;
+  border-top: 1px dashed var(--border-color);
+}
+
+/* 预览区域标题栏 */
+.preview-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 15px;
+  padding-bottom: 10px;
+  border-bottom: 1px solid var(--border-color);
+}
+
+.preview-header h2 {
+  margin: 0;
+  color: var(--primary-color);
+  font-size: 1.2rem;
+}
+
+.zoom-controls {
+  display: flex;
+  gap: 8px;
+}
+
+.zoom-btn {
+  padding: 4px 12px;
+  border: 1px solid var(--border-color);
+  border-radius: 4px;
+  background-color: white;
+  color: var(--text-color);
+  font-size: 13px;
+  cursor: pointer;
+  transition: var(--transition);
+}
+
+.zoom-btn:hover {
+  background-color: var(--background-color);
+  border-color: var(--primary-color);
+  color: var(--primary-color);
+}
+
+/* 预览区域 */
+.preview-container {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  flex: 1;
+  margin-bottom: 15px;
+  background-color: #f0f2f5;
+  border-radius: var(--radius);
+  padding: 15px;
+  overflow: hidden;
+  position: relative;
+}
+
+.poster-preview {
+  width: 375px;
+  height: 667px;
+  background-color: white;
+  box-shadow: var(--shadow);
+  border-radius: var(--radius);
+  overflow: hidden;
+  position: relative;
+  transform-origin: center;
+  transition: transform 0.3s ease;
+}
+
+.poster-preview.with-filter {
+  filter: brightness(var(--brightness, 100%)) contrast(var(--contrast, 100%)) saturate(var(--saturation, 100%));
+}
+
+.poster-preview-container {
+  position: relative;
+}
+
+.poster-watermark {
+  position: absolute;
+  color: white;
+  font-size: 16px;
+  padding: 5px 10px;
+  font-weight: 500;
+  text-shadow: 0 1px 2px rgba(0,0,0,0.5);
+  pointer-events: none;
+}
+
+/* 图片上传 */
+.image-upload {
+  display: flex;
+  flex-direction: column;
+  gap: 10px;
+}
+
+.upload-preview {
+  max-width: 100%;
+  height: 120px;
+  border: 1px dashed var(--border-color);
+  border-radius: var(--radius);
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  overflow: hidden;
+}
+
+.upload-preview img {
+  max-width: 100%;
+  max-height: 100%;
+  object-fit: contain;
+}
+
+.upload-btn {
+  display: inline-block;
+  padding: 6px 12px;
+  background-color: var(--secondary-color);
+  color: white;
+  border: none;
+  border-radius: var(--radius);
+  cursor: pointer;
+  transition: var(--transition);
+  font-size: 0.9rem;
+}
+
+.upload-btn:hover {
+  background-color: #5a6268;
+}
+
+.placeholder-message {
+  text-align: center;
+  color: var(--secondary-color);
+  padding: 20px;
+}
+
+.detection-notice {
+  margin-bottom: 15px;
+}
+
+.info-message {
+  padding: 10px;
+  background-color: rgba(74, 107, 255, 0.1);
+  border-radius: var(--radius);
+  display: flex;
+  align-items: center;
+  gap: 8px;
+  font-size: 0.9rem;
+  color: var(--primary-color);
+}
+
+.info-message i {
+  font-size: 1rem;
+}
+
+/* 按钮样式 */
+.action-buttons {
+  display: flex;
+  justify-content: center;
+  gap: 15px;
+  margin-top: 10px;
+}
+
+.btn {
+  padding: 10px 20px;
+  border: none;
+  border-radius: var(--radius);
+  font-size: 1rem;
+  font-weight: 500;
+  cursor: pointer;
+  transition: var(--transition);
+  display: flex;
+  align-items: center;
+  gap: 8px;
+}
+
+.btn i {
+  font-size: 1.1rem;
+}
+
+.primary-btn {
+  background-color: var(--primary-color);
+  color: white;
+}
+
+.primary-btn:hover {
+  background-color: #3a5bd9;
+}
+
+.secondary-btn {
+  background-color: var(--secondary-color);
+  color: white;
+}
+
+.secondary-btn:hover {
+  background-color: #5a6268;
+}
+
+.btn:disabled {
+  background-color: #cccccc;
+  cursor: not-allowed;
+}
+
+/* 模态框样式 */
+.overlay {
+  position: fixed;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  background-color: rgba(0, 0, 0, 0.5);
+  z-index: 999;
+  display: none;
+}
+
+.modal {
+  position: fixed;
+  top: 50%;
+  left: 50%;
+  transform: translate(-50%, -50%);
+  background-color: white;
+  padding: 30px;
+  border-radius: var(--radius);
+  box-shadow: var(--shadow);
+  z-index: 1000;
+  width: 80%;
+  max-width: 500px;
+  display: none;
+}
+
+.close-modal {
+  position: absolute;
+  right: 20px;
+  top: 15px;
+  font-size: 1.5rem;
+  cursor: pointer;
+  color: var(--secondary-color);
+}
+
+.close-modal:hover {
+  color: var(--danger-color);
+}
+
+.modal h2 {
+  margin-bottom: 20px;
+  color: var(--primary-color);
+}
+
+.share-options {
+  display: flex;
+  justify-content: space-around;
+  margin-bottom: 30px;
+}
+
+.share-option {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  gap: 10px;
+  cursor: pointer;
+  transition: var(--transition);
+}
+
+.share-option i {
+  font-size: 2rem;
+  color: var(--primary-color);
+}
+
+.share-option:hover {
+  transform: translateY(-5px);
+}
+
+.share-instructions {
+  background-color: var(--background-color);
+  padding: 15px;
+  border-radius: var(--radius);
+}
+
+.share-instructions p {
+  margin-bottom: 8px;
+}
+
+/* 响应式设计 */
+@media (max-width: 992px) {
+  .app-main {
+    flex-direction: column;
+  }
+  
+  .preview-panel {
+    margin-top: 20px;
+  }
+}
+
+@media (max-width: 576px) {
+  .app-header h1 {
+    font-size: 2rem;
+  }
+  
+  .templates-container {
+    grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
+  }
+  
+  .action-buttons {
+    flex-direction: column;
+  }
+  
+  .btn {
+    width: 100%;
+    justify-content: center;
+  }
+}
+
+/* 动画效果 */
+@keyframes fadeIn {
+  from { opacity: 0; }
+  to { opacity: 1; }
+}
+
+.fade-in {
+  animation: fadeIn 0.5s ease forwards;
+}
+
+/* 导航栏样式 */
+.main-navbar {
+  background-color: #fff;
+  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+  padding: 10px 20px;
+  margin-bottom: 20px;
+}
+
+.navbar-brand {
+  display: flex;
+  align-items: center;
+}
+
+.brand-link {
+  display: flex;
+  align-items: center;
+  text-decoration: none;
+  color: var(--text-color);
+}
+
+.brand-link img {
+  width: 24px;
+  height: 24px;
+  margin-right: 8px;
+}
+
+.brand-text {
+  font-size: 18px;
+  font-weight: 600;
+  margin-right: 8px;
+}
+
+.brand-subtitle {
+  font-size: 14px;
+  color: var(--secondary-color);
+  padding-left: 8px;
+  border-left: 1px solid var(--border-color);
+}
+
+/* 移除旧的预览面板标题样式 */
+.preview-panel h2 {
+  margin-bottom: 0;
+  padding-bottom: 0;
+  border-bottom: none;
+}

+ 220 - 0
apps/poster-maker/index.html

@@ -0,0 +1,220 @@
+<!DOCTYPE html>
+<html lang="zh-CN">
+<head>
+  <meta charset="UTF-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  <title>海报生成工具</title>
+  
+  <!-- 本地CSS文件 -->
+  <link rel="stylesheet" href="css/main.css">
+  
+</head>
+<body>
+  <div class="main-navbar">
+    <div class="navbar-brand">
+      <a href="#" class="brand-link">
+        <img src="../static/img/fe-48.png" alt="fehelper"/> 
+        <span class="brand-text">FeHelper</span>
+        <span class="brand-subtitle">海报生成工具</span>
+      </a>
+    </div>
+  </div>
+
+  <div class="app-container">
+    <main class="app-main">
+      <div class="tool-panel">
+        <div class="panel-tabs">
+          <button class="panel-tab active" data-tab="templates-tab">模板</button>
+          <button class="panel-tab" data-tab="editor-tab">编辑</button>
+          <button class="panel-tab" data-tab="advanced-tab">高级</button>
+        </div>
+        
+        <div class="panel-content">
+          <div class="tab-content active" id="templates-tab">
+            <div class="template-selection">
+              <div class="template-categories">
+                <button class="category-btn active" data-category="all">全部</button>
+                <button class="category-btn" data-category="promotion">促销</button>
+                <button class="category-btn" data-category="social">社交</button>
+                <button class="category-btn" data-category="work">工作</button>
+                <button class="category-btn" data-category="tech">技术</button>
+                <button class="category-btn" data-category="product">产品</button>
+                <button class="category-btn" data-category="operation">运营</button>
+                <button class="category-btn" data-category="other">其他</button>
+              </div>
+              <div class="templates-container" id="templates-container"></div>
+            </div>
+          </div>
+          
+          <div class="tab-content" id="editor-tab">
+            <div class="editor-panel">
+              <div class="edit-form" id="edit-form">
+                <p class="placeholder-message">请先选择一个模板</p>
+              </div>
+            </div>
+          </div>
+          
+          <div class="tab-content" id="advanced-tab">
+            <div class="advanced-options">
+              <div class="option-group">
+                <h3>布局调整</h3>
+                <div class="form-group">
+                  <label for="poster-width">宽度比例</label>
+                  <div class="range-slider-container">
+                    <input type="range" id="poster-width" min="80" max="120" value="100" class="range-slider">
+                    <span class="range-value">100%</span>
+                  </div>
+                </div>
+                <div class="form-group">
+                  <label for="poster-height">高度比例</label>
+                  <div class="range-slider-container">
+                    <input type="range" id="poster-height" min="80" max="120" value="100" class="range-slider">
+                    <span class="range-value">100%</span>
+                  </div>
+                </div>
+              </div>
+              
+              <div class="option-group">
+                <h3>滤镜效果</h3>
+                <div class="form-group">
+                  <label for="brightness">亮度</label>
+                  <div class="range-slider-container">
+                    <input type="range" id="brightness" min="50" max="150" value="100" class="range-slider">
+                    <span class="range-value">100%</span>
+                  </div>
+                </div>
+                <div class="form-group">
+                  <label for="contrast">对比度</label>
+                  <div class="range-slider-container">
+                    <input type="range" id="contrast" min="50" max="150" value="100" class="range-slider">
+                    <span class="range-value">100%</span>
+                  </div>
+                </div>
+                <div class="form-group">
+                  <label for="saturation">饱和度</label>
+                  <div class="range-slider-container">
+                    <input type="range" id="saturation" min="0" max="200" value="100" class="range-slider">
+                    <span class="range-value">100%</span>
+                  </div>
+                </div>
+              </div>
+              
+              <div class="option-group">
+                <h3>导出选项</h3>
+                <div class="form-group">
+                  <label for="export-quality">导出质量</label>
+                  <div class="range-slider-container">
+                    <input type="range" id="export-quality" min="70" max="100" value="90" class="range-slider">
+                    <span class="range-value">90%</span>
+                  </div>
+                </div>
+                <div class="form-group">
+                  <label for="export-format">导出格式</label>
+                  <select id="export-format" class="form-control">
+                    <option value="png">PNG (透明背景)</option>
+                    <option value="jpeg">JPEG (高兼容性)</option>
+                  </select>
+                </div>
+              </div>
+              
+              <div class="option-group">
+                <h3>水印设置</h3>
+                <div class="form-group">
+                  <label>
+                    <input type="checkbox" id="enable-watermark"> 添加水印
+                  </label>
+                </div>
+                <div class="watermark-options" style="display: none;">
+                  <div class="form-group">
+                    <label for="watermark-text">水印文字</label>
+                    <input type="text" id="watermark-text" class="form-control" value="我的品牌">
+                  </div>
+                  <div class="form-group">
+                    <label for="watermark-position">位置</label>
+                    <select id="watermark-position" class="form-control">
+                      <option value="bottom-right">右下角</option>
+                      <option value="bottom-left">左下角</option>
+                      <option value="top-right">右上角</option>
+                      <option value="top-left">左上角</option>
+                      <option value="center">中央</option>
+                    </select>
+                  </div>
+                  <div class="form-group">
+                    <label for="watermark-opacity">透明度</label>
+                    <div class="range-slider-container">
+                      <input type="range" id="watermark-opacity" min="10" max="100" value="30" class="range-slider">
+                      <span class="range-value">30%</span>
+                    </div>
+                  </div>
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+      
+      <div class="preview-panel">
+        <div class="preview-header">
+          <h2>预览</h2>
+          <div class="zoom-controls">
+            <button class="zoom-btn" id="zoom-out">缩小</button>
+            <button class="zoom-btn" id="zoom-reset">重置</button>
+            <button class="zoom-btn" id="zoom-in">放大</button>
+          </div>
+        </div>
+        <div class="preview-container">
+          <div id="poster-preview" class="poster-preview"></div>
+        </div>
+        <div class="action-buttons">
+          <button id="download-btn" class="btn primary-btn" disabled>
+            <i class="fas fa-download"></i> 下载海报
+          </button>
+          <button id="share-btn" class="btn secondary-btn" disabled>
+            <i class="fas fa-share-alt"></i> 分享
+          </button>
+        </div>
+      </div>
+    </main>
+
+    <!-- 分享模态框 -->
+    <div id="share-modal" class="modal">
+      <div class="modal-content">
+        <span class="close-modal">&times;</span>
+        <h2>分享到社交平台</h2>
+        <div class="share-options">
+          <div class="share-option" data-platform="wechat">
+            <i class="fab fa-weixin"></i>
+            <span>微信</span>
+          </div>
+          <div class="share-option" data-platform="weibo">
+            <i class="fab fa-weibo"></i>
+            <span>微博</span>
+          </div>
+          <div class="share-option" data-platform="xiaohongshu">
+            <i class="fas fa-book"></i>
+            <span>小红书</span>
+          </div>
+          <div class="share-option" data-platform="qq">
+            <i class="fab fa-qq"></i>
+            <span>QQ</span>
+          </div>
+        </div>
+        <div class="share-instructions">
+          <p>1. 点击下载海报</p>
+          <p>2. 打开对应社交软件</p>
+          <p>3. 从相册中选择刚刚下载的海报</p>
+        </div>
+      </div>
+    </div>
+    
+    <div id="overlay" class="overlay"></div>
+  </div>
+
+  <!-- 依赖库 -->
+  <script src="../chart-maker/lib/html2canvas.min.js"></script>
+  <script src="./js/FileSaver.min.js"></script>
+  
+  <!-- 本地JS文件 -->
+  <script type="module" src="./js/index.js"></script>
+</body>
+</html>

+ 112 - 0
apps/poster-maker/index.js

@@ -0,0 +1,112 @@
+import { templates } from './js/templateData.js';
+import { renderTemplates, initializeEditor } from './js/templateRenderer.js';
+import { setupEventListeners } from './js/eventHandlers.js';
+import { setupImageUpload } from './js/imageUpload.js';
+
+document.addEventListener('DOMContentLoaded', () => {
+  // 渲染所有模板缩略图
+  renderTemplates(templates);
+  
+  // 设置事件监听器
+  setupEventListeners();
+  
+  // 初始化图片上传功能
+  setupImageUpload();
+  
+  // 添加预览区域的缩放控制
+  setupPreviewZoom();
+  
+  // 默认选择第一个模板
+  setTimeout(() => {
+    const firstTemplate = document.querySelector('.template-item');
+    if (firstTemplate) {
+      firstTemplate.click();
+    }
+  }, 100);
+});
+
+// 设置预览区域的缩放控制
+function setupPreviewZoom() {
+  const previewContainer = document.querySelector('.preview-container');
+  const posterPreview = document.getElementById('poster-preview');
+  
+  if (!previewContainer || !posterPreview) return;
+  
+  // 创建缩放控制按钮容器
+  const zoomControls = document.createElement('div');
+  zoomControls.className = 'zoom-controls';
+  
+  // 创建放大按钮
+  const zoomInBtn = document.createElement('button');
+  zoomInBtn.className = 'zoom-btn';
+  zoomInBtn.innerHTML = '<i class="fas fa-search-plus"></i>';
+  zoomInBtn.title = '放大';
+  
+  // 创建缩小按钮
+  const zoomOutBtn = document.createElement('button');
+  zoomOutBtn.className = 'zoom-btn';
+  zoomOutBtn.innerHTML = '<i class="fas fa-search-minus"></i>';
+  zoomOutBtn.title = '缩小';
+  
+  // 创建重置按钮
+  const resetZoomBtn = document.createElement('button');
+  resetZoomBtn.className = 'zoom-btn';
+  resetZoomBtn.innerHTML = '<i class="fas fa-sync-alt"></i>';
+  resetZoomBtn.title = '重置大小';
+  
+  // 添加按钮到控制容器
+  zoomControls.appendChild(zoomOutBtn);
+  zoomControls.appendChild(resetZoomBtn);
+  zoomControls.appendChild(zoomInBtn);
+  
+  // 添加控制容器到预览区域
+  previewContainer.appendChild(zoomControls);
+  
+  // 设置当前缩放级别
+  let currentZoom = 1;
+  const zoomStep = 0.1;
+  const maxZoom = 1.5;
+  const minZoom = 0.5;
+  
+  // 添加放大事件
+  zoomInBtn.addEventListener('click', () => {
+    if (currentZoom < maxZoom) {
+      currentZoom += zoomStep;
+      applyZoom();
+    }
+  });
+  
+  // 添加缩小事件
+  zoomOutBtn.addEventListener('click', () => {
+    if (currentZoom > minZoom) {
+      currentZoom -= zoomStep;
+      applyZoom();
+    }
+  });
+  
+  // 添加重置事件
+  resetZoomBtn.addEventListener('click', () => {
+    currentZoom = 1;
+    applyZoom();
+  });
+  
+  // 应用缩放
+  function applyZoom() {
+    posterPreview.style.transform = `scale(${currentZoom})`;
+  }
+  
+  // 添加鼠标滚轮缩放
+  previewContainer.addEventListener('wheel', (e) => {
+    e.preventDefault();
+    
+    if (e.deltaY < 0 && currentZoom < maxZoom) {
+      // 向上滚动,放大
+      currentZoom += zoomStep;
+    } else if (e.deltaY > 0 && currentZoom > minZoom) {
+      // 向下滚动,缩小
+      currentZoom -= zoomStep;
+    }
+    
+    applyZoom();
+  });
+} 

Разлика између датотеке није приказан због своје велике величине
+ 0 - 0
apps/poster-maker/js/FileSaver.min.js


+ 258 - 0
apps/poster-maker/js/eventHandlers.js

@@ -0,0 +1,258 @@
+// 事件处理器
+
+// 设置所有事件监听器
+export function setupEventListeners() {
+  // 面板选项卡切换
+  const panelTabs = document.querySelectorAll('.panel-tab');
+  if (panelTabs) {
+    panelTabs.forEach(tab => {
+      tab.addEventListener('click', () => {
+        // 移除所有选项卡的active类
+        panelTabs.forEach(t => t.classList.remove('active'));
+        
+        // 隐藏所有内容面板
+        document.querySelectorAll('.tab-content').forEach(content => {
+          content.classList.remove('active');
+        });
+        
+        // 添加当前选项卡的active类
+        tab.classList.add('active');
+        
+        // 显示对应的内容面板
+        const tabId = tab.dataset.tab;
+        const tabContent = document.getElementById(tabId);
+        if (tabContent) {
+          tabContent.classList.add('active');
+        }
+      });
+    });
+  }
+  
+  // 分类筛选按钮
+  const categoryBtns = document.querySelectorAll('.category-btn');
+  if (categoryBtns) {
+    categoryBtns.forEach(btn => {
+      btn.addEventListener('click', () => {
+        // 移除所有按钮的active类
+        categoryBtns.forEach(b => b.classList.remove('active'));
+        
+        // 添加当前按钮的active类
+        btn.classList.add('active');
+        
+        // 获取分类值并渲染模板
+        const category = btn.dataset.category;
+        window.renderTemplates(window.templates, category);
+      });
+    });
+  }
+  
+  // 下载按钮
+  const downloadBtn = document.getElementById('download-btn');
+  if (downloadBtn) {
+    downloadBtn.addEventListener('click', () => {
+      // 获取导出设置
+      const exportFormat = document.getElementById('export-format')?.value || 'png';
+      const exportQuality = document.getElementById('export-quality')?.value / 100 || 0.9;
+      
+      // 下载海报
+      window.downloadPoster(exportFormat, exportQuality);
+    });
+  }
+  
+  // 分享按钮
+  const shareBtn = document.getElementById('share-btn');
+  const shareModal = document.getElementById('share-modal');
+  const overlay = document.getElementById('overlay');
+  const closeModal = document.querySelector('.close-modal');
+  
+  if (shareBtn && shareModal && overlay && closeModal) {
+    // 打开分享模态框
+    shareBtn.addEventListener('click', () => {
+      shareModal.style.display = 'block';
+      overlay.style.display = 'block';
+    });
+    
+    // 关闭分享模态框
+    closeModal.addEventListener('click', () => {
+      shareModal.style.display = 'none';
+      overlay.style.display = 'none';
+    });
+    
+    // 点击遮罩层关闭模态框
+    overlay.addEventListener('click', () => {
+      shareModal.style.display = 'none';
+      overlay.style.display = 'none';
+    });
+    
+    // 设置分享选项点击事件
+    const shareOptions = document.querySelectorAll('.share-option');
+    shareOptions.forEach(option => {
+      option.addEventListener('click', () => {
+        // 先下载海报
+        window.downloadPoster();
+        
+        const platform = option.dataset.platform;
+        alert(`已下载海报,请在${getPlatformName(platform)}中分享`);
+        
+        // 关闭模态框
+        shareModal.style.display = 'none';
+        overlay.style.display = 'none';
+      });
+    });
+  }
+  
+  // 设置高级选项事件监听器
+  setupAdvancedOptions();
+}
+
+// 获取平台名称
+function getPlatformName(platform) {
+  const platforms = {
+    wechat: '微信',
+    weibo: '微博',
+    xiaohongshu: '小红书',
+    qq: 'QQ'
+  };
+  
+  return platforms[platform] || '社交平台';
+}
+
+// 设置高级选项事件监听器
+function setupAdvancedOptions() {
+  // 布局调整
+  const posterWidth = document.getElementById('poster-width');
+  const posterHeight = document.getElementById('poster-height');
+  const posterPreview = document.getElementById('poster-preview');
+  
+  if (posterWidth && posterHeight && posterPreview) {
+    posterWidth.addEventListener('input', (e) => {
+      const value = e.target.value;
+      posterWidth.nextElementSibling.textContent = `${value}%`;
+      posterPreview.style.width = `${375 * value / 100}px`;
+    });
+    
+    posterHeight.addEventListener('input', (e) => {
+      const value = e.target.value;
+      posterHeight.nextElementSibling.textContent = `${value}%`;
+      posterPreview.style.height = `${667 * value / 100}px`;
+    });
+  }
+  
+  // 滤镜效果
+  const brightness = document.getElementById('brightness');
+  const contrast = document.getElementById('contrast');
+  const saturation = document.getElementById('saturation');
+  
+  if (brightness && contrast && saturation && posterPreview) {
+    const updateFilter = () => {
+      const brightnessValue = brightness.value;
+      const contrastValue = contrast.value;
+      const saturationValue = saturation.value;
+      
+      posterPreview.style.setProperty('--brightness', `${brightnessValue}%`);
+      posterPreview.style.setProperty('--contrast', `${contrastValue}%`);
+      posterPreview.style.setProperty('--saturation', `${saturationValue}%`);
+      posterPreview.classList.add('with-filter');
+      
+      brightness.nextElementSibling.textContent = `${brightnessValue}%`;
+      contrast.nextElementSibling.textContent = `${contrastValue}%`;
+      saturation.nextElementSibling.textContent = `${saturationValue}%`;
+    };
+    
+    brightness.addEventListener('input', updateFilter);
+    contrast.addEventListener('input', updateFilter);
+    saturation.addEventListener('input', updateFilter);
+  }
+  
+  // 导出质量
+  const exportQuality = document.getElementById('export-quality');
+  if (exportQuality) {
+    exportQuality.addEventListener('input', (e) => {
+      const value = e.target.value;
+      exportQuality.nextElementSibling.textContent = `${value}%`;
+    });
+  }
+  
+  // 水印设置
+  const enableWatermark = document.getElementById('enable-watermark');
+  const watermarkOptions = document.querySelector('.watermark-options');
+  const watermarkText = document.getElementById('watermark-text');
+  const watermarkPosition = document.getElementById('watermark-position');
+  const watermarkOpacity = document.getElementById('watermark-opacity');
+  
+  if (enableWatermark && watermarkOptions) {
+    enableWatermark.addEventListener('change', (e) => {
+      if (e.target.checked) {
+        watermarkOptions.style.display = 'block';
+        updateWatermark();
+      } else {
+        watermarkOptions.style.display = 'none';
+        removeWatermark();
+      }
+    });
+    
+    if (watermarkText && watermarkPosition && watermarkOpacity) {
+      watermarkText.addEventListener('input', updateWatermark);
+      watermarkPosition.addEventListener('change', updateWatermark);
+      watermarkOpacity.addEventListener('input', () => {
+        watermarkOpacity.nextElementSibling.textContent = `${watermarkOpacity.value}%`;
+        updateWatermark();
+      });
+    }
+  }
+}
+
+// 更新水印
+function updateWatermark() {
+  const posterPreview = document.getElementById('poster-preview');
+  if (!posterPreview) return;
+  
+  // 移除现有水印
+  removeWatermark();
+  
+  const watermarkText = document.getElementById('watermark-text').value;
+  const watermarkPosition = document.getElementById('watermark-position').value;
+  const watermarkOpacity = document.getElementById('watermark-opacity').value / 100;
+  
+  // 创建水印元素
+  const watermark = document.createElement('div');
+  watermark.className = 'poster-watermark';
+  watermark.textContent = watermarkText;
+  watermark.style.opacity = watermarkOpacity;
+  
+  // 设置水印位置
+  switch (watermarkPosition) {
+    case 'bottom-right':
+      watermark.style.bottom = '10px';
+      watermark.style.right = '10px';
+      break;
+    case 'bottom-left':
+      watermark.style.bottom = '10px';
+      watermark.style.left = '10px';
+      break;
+    case 'top-right':
+      watermark.style.top = '10px';
+      watermark.style.right = '10px';
+      break;
+    case 'top-left':
+      watermark.style.top = '10px';
+      watermark.style.left = '10px';
+      break;
+    case 'center':
+      watermark.style.top = '50%';
+      watermark.style.left = '50%';
+      watermark.style.transform = 'translate(-50%, -50%)';
+      break;
+  }
+  
+  posterPreview.appendChild(watermark);
+}
+
+// 移除水印
+function removeWatermark() {
+  const posterPreview = document.getElementById('poster-preview');
+  const watermark = posterPreview?.querySelector('.poster-watermark');
+  if (watermark) {
+    watermark.remove();
+  }
+}

+ 51 - 0
apps/poster-maker/js/imageUpload.js

@@ -0,0 +1,51 @@
+// 设置图片上传功能
+// 图片上传功能
+export function setupImageUpload() {
+  // 这个函数为未来可能的拖放上传功能预留
+  // 目前基本的图片上传功能已经在templateRenderer.js中实现
+  
+  // 未来可以添加:
+  // 1. 拖放上传
+  // 2. 图片裁剪
+  // 3. 图片滤镜
+  // 4. 图片调整大小
+  
+  // 示例: 如果添加拖放上传功能
+  /*
+  const uploadPreviews = document.querySelectorAll('.upload-preview');
+  
+  uploadPreviews.forEach(preview => {
+    preview.addEventListener('dragover', (e) => {
+      e.preventDefault();
+      preview.classList.add('drag-over');
+    });
+    
+    preview.addEventListener('dragleave', () => {
+      preview.classList.remove('drag-over');
+    });
+    
+    preview.addEventListener('drop', (e) => {
+      e.preventDefault();
+      preview.classList.remove('drag-over');
+      
+      const files = e.dataTransfer.files;
+      if (files.length > 0 && files[0].type.startsWith('image/')) {
+        // 找到对应的input元素
+        const inputId = preview.querySelector('img').id.replace('preview-', 'field-');
+        const input = document.getElementById(inputId);
+        
+        if (input) {
+          // 触发input的change事件
+          const dataTransfer = new DataTransfer();
+          dataTransfer.items.add(files[0]);
+          input.files = dataTransfer.files;
+          
+          // 手动触发change事件
+          const event = new Event('change', { bubbles: true });
+          input.dispatchEvent(event);
+        }
+      }
+    });
+  });
+  */
+}

+ 85 - 0
apps/poster-maker/js/index.js

@@ -0,0 +1,85 @@
+import { templates } from './templateData.js';
+import { renderTemplates } from './templateRenderer.js';
+import { setupEventListeners } from './eventHandlers.js';
+import { setupImageUpload } from './imageUpload.js';
+
+document.addEventListener('DOMContentLoaded', () => {
+  // 渲染所有模板缩略图
+  renderTemplates(templates);
+  
+  // 设置事件监听器
+  setupEventListeners();
+  
+  // 初始化图片上传功能
+  setupImageUpload();
+  
+  // 添加预览区域的缩放控制
+  setupPreviewZoom();
+  
+  // 默认选择第一个模板
+  setTimeout(() => {
+    const firstTemplate = document.querySelector('.template-item');
+    if (firstTemplate) {
+      firstTemplate.click();
+    }
+  }, 100);
+});
+
+// 设置预览区域的缩放控制
+function setupPreviewZoom() {
+  const posterPreview = document.getElementById('poster-preview');
+  const zoomInBtn = document.getElementById('zoom-in');
+  const zoomOutBtn = document.getElementById('zoom-out');
+  const resetZoomBtn = document.getElementById('zoom-reset');
+  const previewContainer = document.querySelector('.preview-container');
+  
+  if (!posterPreview || !zoomInBtn || !zoomOutBtn || !resetZoomBtn || !previewContainer) return;
+  
+  // 设置当前缩放级别
+  let currentZoom = 1;
+  const zoomStep = 0.1;
+  const maxZoom = 1.5;
+  const minZoom = 0.5;
+  
+  // 添加放大事件
+  zoomInBtn.addEventListener('click', () => {
+    if (currentZoom < maxZoom) {
+      currentZoom += zoomStep;
+      applyZoom();
+    }
+  });
+  
+  // 添加缩小事件
+  zoomOutBtn.addEventListener('click', () => {
+    if (currentZoom > minZoom) {
+      currentZoom -= zoomStep;
+      applyZoom();
+    }
+  });
+  
+  // 添加重置事件
+  resetZoomBtn.addEventListener('click', () => {
+    currentZoom = 1;
+    applyZoom();
+  });
+  
+  // 应用缩放
+  function applyZoom() {
+    posterPreview.style.transform = `scale(${currentZoom})`;
+  }
+  
+  // 添加鼠标滚轮缩放
+  previewContainer.addEventListener('wheel', (e) => {
+    e.preventDefault();
+    
+    if (e.deltaY < 0 && currentZoom < maxZoom) {
+      // 向上滚动,放大
+      currentZoom += zoomStep;
+    } else if (e.deltaY > 0 && currentZoom > minZoom) {
+      // 向下滚动,缩小
+      currentZoom -= zoomStep;
+    }
+    
+    applyZoom();
+  });
+}

+ 994 - 0
apps/poster-maker/js/templateData.js

@@ -0,0 +1,994 @@
+// 模板数据
+export const templates = [
+  {
+    id: 'social-promo-1',
+    name: '社交促销模板1',
+    category: 'promotion',
+    thumbnail: 'https://images.unsplash.com/photo-1607082349566-187342175e2f?ixlib=rb-4.0.3&auto=format&fit=crop&w=240&h=240&q=80',
+    fields: [
+      { name: 'title', type: 'text', label: '标题', default: '限时优惠' },
+      { name: 'subtitle', type: 'text', label: '副标题', default: '全场商品5折起' },
+      { name: 'date', type: 'text', label: '日期', default: '2023年12月1日-12月31日' },
+      { name: 'mainImage', type: 'image', label: '主图', default: 'https://images.unsplash.com/photo-1607082349566-187342175e2f?ixlib=rb-4.0.3&auto=format&fit=crop&w=600&q=80' },
+      { name: 'bgColor', type: 'color', label: '背景颜色', default: '#ff5e62' },
+      { name: 'textColor', type: 'color', label: '文字颜色', default: '#ffffff' },
+      { name: 'footerText', type: 'text', label: '底部提示文字', default: '扫码或长按识别二维码' },
+      { name: 'footerSubText', type: 'text', label: '底部副提示文字', default: '了解更多详情' }
+    ],
+    template: (data) => `
+      <div style="width: 100%; height: 100%; background-color: ${data.bgColor}; color: ${data.textColor}; padding: 30px; font-family: Arial, sans-serif; position: relative; overflow: hidden;">
+        <div style="position: absolute; top: 0; left: 0; width: 100%; height: 40%; overflow: hidden;">
+          <img src="${data.mainImage}" style="width: 100%; height: 100%; object-fit: cover;" alt="主图">
+        </div>
+        <div style="position: absolute; bottom: 0; left: 0; width: 100%; height: 65%; background: linear-gradient(to bottom, rgba(0,0,0,0), ${data.bgColor} 20%); padding: 30px; display: flex; flex-direction: column; justify-content: flex-end;">
+          <h1 style="font-size: 36px; margin-bottom: 15px; font-weight: 800; text-shadow: 2px 2px 4px rgba(0,0,0,0.3);">${data.title}</h1>
+          <h2 style="font-size: 24px; margin-bottom: 20px; font-weight: 600;">${data.subtitle}</h2>
+          <p style="font-size: 18px; margin-bottom: 30px;">${data.date}</p>
+          <div style="width: 60px; height: 5px; background-color: ${data.textColor}; margin-bottom: 20px;"></div>
+          <p style="font-size: 16px; font-style: italic;">${data.footerText}<br>${data.footerSubText}</p>
+        </div>
+      </div>
+    `
+  },
+  {
+    id: 'event-invitation-1',
+    name: '活动邀请模板1',
+    category: 'event',
+    thumbnail: 'https://images.unsplash.com/photo-1492684223066-81342ee5ff30?ixlib=rb-4.0.3&auto=format&fit=crop&w=240&h=240&q=80',
+    fields: [
+      { name: 'eventName', type: 'text', label: '活动名称', default: '新品发布会' },
+      { name: 'eventDate', type: 'text', label: '活动日期', default: '2023年12月15日 14:00' },
+      { name: 'eventLocation', type: 'text', label: '活动地点', default: '上海市浦东新区XX大厦' },
+      { name: 'mainImage', type: 'image', label: '主图', default: 'https://images.unsplash.com/photo-1492684223066-81342ee5ff30?ixlib=rb-4.0.3&auto=format&fit=crop&w=600&q=80' },
+      { name: 'bgColor', type: 'color', label: '背景颜色', default: '#1a2a6c' },
+      { name: 'accentColor', type: 'color', label: '强调色', default: '#fdbb2d' },
+      { name: 'buttonText', type: 'text', label: '按钮文字', default: '诚挚邀请' },
+      { name: 'footerText', type: 'text', label: '底部文字', default: '扫描二维码报名参加' }
+    ],
+    template: (data) => `
+      <div style="width: 100%; height: 100%; background: linear-gradient(to bottom, ${data.bgColor}, #000000); color: white; font-family: 'Helvetica', sans-serif; position: relative; overflow: hidden;">
+        <div style="position: absolute; top: 0; left: 0; width: 100%; height: 50%; overflow: hidden;">
+          <img src="${data.mainImage}" style="width: 100%; height: 100%; object-fit: cover; opacity: 0.8;" alt="活动图片">
+        </div>
+        <div style="position: absolute; top: 50%; left: 0; width: 100%; height: 50%; padding: 30px; display: flex; flex-direction: column; justify-content: center; align-items: center; text-align: center;">
+          <h1 style="font-size: 32px; margin-bottom: 20px; color: ${data.accentColor}; text-transform: uppercase; letter-spacing: 2px;">${data.eventName}</h1>
+          <div style="width: 50px; height: 3px; background-color: ${data.accentColor}; margin-bottom: 20px;"></div>
+          <p style="font-size: 18px; margin-bottom: 10px;"><i class="fas fa-calendar-alt" style="margin-right: 10px; color: ${data.accentColor};"></i> ${data.eventDate}</p>
+          <p style="font-size: 18px; margin-bottom: 30px;"><i class="fas fa-map-marker-alt" style="margin-right: 10px; color: ${data.accentColor};"></i> ${data.eventLocation}</p>
+          <div style="padding: 15px 30px; background-color: ${data.accentColor}; color: #000; font-size: 18px; font-weight: bold; border-radius: 30px;">${data.buttonText}</div>
+        </div>
+        <div style="position: absolute; bottom: 20px; width: 100%; text-align: center; font-size: 14px; opacity: 0.7;">
+          <p>${data.footerText}</p>
+        </div>
+      </div>
+    `
+  },
+  {
+    id: 'product-launch-1',
+    name: '产品发布模板1',
+    category: 'product',
+    thumbnail: 'https://images.unsplash.com/photo-1505740420928-5e560c06d30e?ixlib=rb-4.0.3&auto=format&fit=crop&w=240&h=240&q=80',
+    fields: [
+      { name: 'productName', type: 'text', label: '产品名称', default: '智能手表 Pro' },
+      { name: 'tagline', type: 'text', label: '产品标语', default: '科技引领未来' },
+      { name: 'price', type: 'text', label: '产品价格', default: '¥1999' },
+      { name: 'productImage', type: 'image', label: '产品图片', default: 'https://images.unsplash.com/photo-1505740420928-5e560c06d30e?ixlib=rb-4.0.3&auto=format&fit=crop&w=600&q=80' },
+      { name: 'bgColor', type: 'color', label: '背景颜色', default: '#f6f6f6' },
+      { name: 'accentColor', type: 'color', label: '强调色', default: '#ff6b6b' }
+    ],
+    template: (data) => `
+      <div style="width: 100%; height: 100%; background-color: ${data.bgColor}; font-family: 'Arial', sans-serif; position: relative; overflow: hidden;">
+        <div style="position: absolute; top: 0; left: 0; width: 100%; height: 40%; background-color: ${data.accentColor}; border-bottom-right-radius: 50%; border-bottom-left-radius: 50%;"></div>
+        <div style="position: absolute; top: 50px; left: 0; width: 100%; text-align: center; color: white;">
+          <h1 style="font-size: 28px; font-weight: 700; margin-bottom: 10px;">${data.productName}</h1>
+          <p style="font-size: 16px; font-style: italic;">${data.tagline}</p>
+        </div>
+        <div style="position: absolute; top: 180px; left: 50%; transform: translateX(-50%); width: 250px; height: 250px; border-radius: 50%; background-color: white; display: flex; justify-content: center; align-items: center; box-shadow: 0 10px 30px rgba(0,0,0,0.1);">
+          <img src="${data.productImage}" style="max-width: 80%; max-height: 80%; object-fit: contain;" alt="产品图片">
+        </div>
+        <div style="position: absolute; bottom: 100px; left: 0; width: 100%; text-align: center;">
+          <p style="font-size: 16px; color: #666; margin-bottom: 15px;">限时特惠价</p>
+          <h2 style="font-size: 36px; color: ${data.accentColor}; font-weight: 700; margin-bottom: 20px;">${data.price}</h2>
+          <div style="padding: 12px 30px; background-color: ${data.accentColor}; color: white; font-size: 18px; font-weight: bold; border-radius: 30px; display: inline-block;">立即购买</div>
+        </div>
+        <div style="position: absolute; bottom: 30px; width: 100%; text-align: center; font-size: 14px; color: #666;">
+          <p>长按识别二维码了解更多</p>
+        </div>
+      </div>
+    `
+  },
+  {
+    id: 'quote-1',
+    name: '名言分享模板1',
+    category: 'social',
+    thumbnail: 'https://images.unsplash.com/photo-1507608616759-54f48f0af0ee?ixlib=rb-4.0.3&auto=format&fit=crop&w=240&h=240&q=80',
+    fields: [
+      { name: 'quote', type: 'textarea', label: '名言内容', default: '生活不是等待风暴过去,而是学会在雨中翩翩起舞。' },
+      { name: 'author', type: 'text', label: '作者', default: '佚名' },
+      { name: 'bgImage', type: 'image', label: '背景图片', default: 'https://images.unsplash.com/photo-1507608616759-54f48f0af0ee?ixlib=rb-4.0.3&auto=format&fit=crop&w=600&q=80' },
+      { name: 'overlayColor', type: 'color', label: '遮罩颜色', default: 'rgba(0, 0, 0, 0.4)' },
+      { name: 'textColor', type: 'color', label: '文字颜色', default: '#ffffff' }
+    ],
+    template: (data) => `
+      <div style="width: 100%; height: 100%; position: relative; font-family: 'Georgia', serif; overflow: hidden;">
+        <div style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;">
+          <img src="${data.bgImage}" style="width: 100%; height: 100%; object-fit: cover;" alt="背景图片">
+        </div>
+        <div style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: ${data.overlayColor};"></div>
+        <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 80%; text-align: center; color: ${data.textColor};">
+          <div style="font-size: 30px; margin-bottom: 20px;">"</div>
+          <p style="font-size: 24px; line-height: 1.5; margin-bottom: 20px;">${data.quote}</p>
+          <div style="font-size: 30px; margin-bottom: 20px;">"</div>
+          <div style="width: 50px; height: 2px; background-color: ${data.textColor}; margin: 0 auto 20px;"></div>
+          <p style="font-size: 18px; font-style: italic;">— ${data.author}</p>
+        </div>
+        <div style="position: absolute; bottom: 30px; width: 100%; text-align: center; color: ${data.textColor}; font-size: 14px;">
+          <p>分享你的感悟</p>
+        </div>
+      </div>
+    `
+  },
+  {
+    id: 'food-recipe-1',
+    name: '美食菜谱模板1',
+    category: 'food',
+    thumbnail: 'https://images.unsplash.com/photo-1476224203421-9ac39bcb3327?ixlib=rb-4.0.3&auto=format&fit=crop&w=240&h=240&q=80',
+    fields: [
+      { name: 'dishName', type: 'text', label: '菜品名称', default: '香煎三文鱼' },
+      { name: 'description', type: 'textarea', label: '简短描述', default: '鲜嫩多汁,营养丰富的美味佳肴' },
+      { name: 'cookTime', type: 'text', label: '烹饪时间', default: '25分钟' },
+      { name: 'foodImage', type: 'image', label: '菜品图片', default: 'https://images.unsplash.com/photo-1476224203421-9ac39bcb3327?ixlib=rb-4.0.3&auto=format&fit=crop&w=600&q=80' },
+      { name: 'bgColor', type: 'color', label: '背景颜色', default: '#ffffff' },
+      { name: 'accentColor', type: 'color', label: '强调色', default: '#ff9a3c' }
+    ],
+    template: (data) => `
+      <div style="width: 100%; height: 100%; background-color: ${data.bgColor}; font-family: 'Montserrat', sans-serif; position: relative; overflow: hidden;">
+        <div style="position: absolute; top: 0; left: 0; width: 100%; height: 60%; overflow: hidden;">
+          <img src="${data.foodImage}" style="width: 100%; height: 100%; object-fit: cover;" alt="菜品图片">
+        </div>
+        <div style="position: absolute; top: 60%; left: 0; width: 100%; height: 40%; padding: 30px;">
+          <div style="width: 60px; height: 5px; background-color: ${data.accentColor}; margin-bottom: 15px;"></div>
+          <h1 style="font-size: 28px; color: #333; margin-bottom: 10px; font-weight: 700;">${data.dishName}</h1>
+          <p style="font-size: 16px; color: #666; margin-bottom: 20px; line-height: 1.5;">${data.description}</p>
+          <div style="display: flex; align-items: center; margin-bottom: 20px;">
+            <div style="display: flex; align-items: center; margin-right: 20px;">
+              <i class="fas fa-clock" style="color: ${data.accentColor}; margin-right: 8px;"></i>
+              <span style="color: #666;">${data.cookTime}</span>
+            </div>
+            <div style="display: flex; align-items: center;">
+              <i class="fas fa-utensils" style="color: ${data.accentColor}; margin-right: 8px;"></i>
+              <span style="color: #666;">2人份</span>
+            </div>
+          </div>
+          <div style="padding: 10px 20px; background-color: ${data.accentColor}; color: white; font-size: 16px; font-weight: 600; border-radius: 30px; display: inline-block;">查看完整食谱</div>
+        </div>
+        <div style="position: absolute; bottom: 20px; right: 20px; background-color: white; border-radius: 50%; width: 60px; height: 60px; display: flex; justify-content: center; align-items: center; box-shadow: 0 4px 8px rgba(0,0,0,0.1);">
+          <i class="fas fa-qrcode" style="font-size: 30px; color: ${data.accentColor};"></i>
+        </div>
+      </div>
+    `
+  },
+  {
+    id: 'travel-1',
+    name: '旅行分享模板1',
+    category: 'travel',
+    thumbnail: 'https://images.unsplash.com/photo-1519451241324-20b4ea2c4220?ixlib=rb-4.0.3&auto=format&fit=crop&w=240&h=240&q=80',
+    fields: [
+      { name: 'location', type: 'text', label: '地点名称', default: '巴厘岛' },
+      { name: 'tagline', type: 'text', label: '标语', default: '遇见天堂般的美景' },
+      { name: 'date', type: 'text', label: '日期', default: '2023年夏' },
+      { name: 'travelImage', type: 'image', label: '旅行图片', default: 'https://images.unsplash.com/photo-1519451241324-20b4ea2c4220?ixlib=rb-4.0.3&auto=format&fit=crop&w=600&q=80' },
+      { name: 'overlayColor', type: 'color', label: '遮罩颜色', default: 'rgba(0, 0, 0, 0.3)' },
+      { name: 'accentColor', type: 'color', label: '强调色', default: '#4ecdc4' }
+    ],
+    template: (data) => `
+      <div style="width: 100%; height: 100%; position: relative; font-family: 'Roboto', sans-serif; overflow: hidden;">
+        <div style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;">
+          <img src="${data.travelImage}" style="width: 100%; height: 100%; object-fit: cover;" alt="旅行图片">
+        </div>
+        <div style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: linear-gradient(to bottom, ${data.overlayColor}, rgba(0,0,0,0.7));"></div>
+        <div style="position: absolute; bottom: 80px; left: 30px; color: white;">
+          <p style="font-size: 18px; margin-bottom: 10px; letter-spacing: 2px;">${data.date}</p>
+          <h1 style="font-size: 42px; font-weight: 700; margin-bottom: 15px; text-shadow: 2px 2px 4px rgba(0,0,0,0.5);">${data.location}</h1>
+          <div style="width: 60px; height: 4px; background-color: ${data.accentColor}; margin-bottom: 15px;"></div>
+          <p style="font-size: 20px; font-style: italic; text-shadow: 1px 1px 3px rgba(0,0,0,0.5);">${data.tagline}</p>
+        </div>
+        <div style="position: absolute; bottom: 30px; left: 30px; display: flex; align-items: center;">
+          <div style="width: 40px; height: 40px; border-radius: 50%; background-color: ${data.accentColor}; display: flex; justify-content: center; align-items: center; margin-right: 15px;">
+            <i class="fas fa-map-marker-alt" style="color: white; font-size: 20px;"></i>
+          </div>
+          <p style="color: white; font-size: 16px;">查看我的旅行攻略</p>
+        </div>
+      </div>
+    `
+  }
+];
+
+// 添加更多模板...
+
+// 小红书风格模板
+export const xiaohongshuTemplates = [
+  {
+    id: 'xiaohongshu-1',
+    name: '小红书风格1',
+    category: 'xiaohongshu',
+    thumbnail: 'https://images.unsplash.com/photo-1487412720507-e7ab37603c6f?ixlib=rb-4.0.3&auto=format&fit=crop&w=240&h=240&q=80',
+    fields: [
+      { name: 'title', type: 'text', label: '标题', default: '这家店也太好吃了吧!绝对五星推荐!' },
+      { name: 'content', type: 'textarea', label: '内容', default: '无意中发现的宝藏小店,环境超级好,菜品颜值和口味都很赞,价格也很实惠,强烈推荐大家来打卡!' },
+      { name: 'tags', type: 'text', label: '标签', default: '#美食探店 #宝藏餐厅 #推荐' },
+      { name: 'mainImage', type: 'image', label: '主图', default: 'https://images.unsplash.com/photo-1487412720507-e7ab37603c6f?ixlib=rb-4.0.3&auto=format&fit=crop&w=600&q=80' },
+      { name: 'bgColor', type: 'color', label: '背景颜色', default: '#ffffff' },
+      { name: 'accentColor', type: 'color', label: '强调色', default: '#ff4757' }
+    ],
+    template: (data) => `
+      <div style="width: 100%; height: 100%; background-color: ${data.bgColor}; font-family: 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', sans-serif; position: relative; overflow: hidden;">
+        <div style="position: absolute; top: 0; left: 0; width: 100%; height: 60%; overflow: hidden;">
+          <img src="${data.mainImage}" style="width: 100%; height: 100%; object-fit: cover;" alt="主图">
+        </div>
+        <div style="position: absolute; top: 60%; left: 0; width: 100%; height: 40%; padding: 20px; background-color: white; border-top-left-radius: 20px; border-top-right-radius: 20px; box-shadow: 0 -5px 15px rgba(0,0,0,0.05);">
+          <h1 style="font-size: 20px; font-weight: 600; color: #333; margin-bottom: 15px; line-height: 1.4;">${data.title}</h1>
+          <p style="font-size: 15px; color: #666; margin-bottom: 15px; line-height: 1.5; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; text-overflow: ellipsis;">${data.content}</p>
+          <p style="font-size: 14px; color: ${data.accentColor}; margin-bottom: 15px;">${data.tags}</p>
+          <div style="display: flex; align-items: center; justify-content: space-between;">
+            <div style="display: flex; align-items: center;">
+              <div style="width: 30px; height: 30px; border-radius: 50%; background-color: #f5f5f5; margin-right: 10px; overflow: hidden;">
+                <img src="https://images.unsplash.com/photo-1494790108377-be9c29b29330?ixlib=rb-4.0.3&auto=format&fit=crop&w=60&h=60&q=80" style="width: 100%; height: 100%; object-fit: cover;" alt="用户头像">
+              </div>
+              <span style="font-size: 14px; color: #333;">小红薯123</span>
+            </div>
+            <div style="display: flex; align-items: center;">
+              <div style="display: flex; align-items: center; margin-right: 15px;">
+                <i class="fas fa-heart" style="color: ${data.accentColor}; margin-right: 5px; font-size: 14px;"></i>
+                <span style="font-size: 12px; color: #999;">258</span>
+              </div>
+              <div style="display: flex; align-items: center;">
+                <i class="fas fa-comment" style="color: #999; margin-right: 5px; font-size: 14px;"></i>
+                <span style="font-size: 12px; color: #999;">36</span>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    `
+  },
+  {
+    id: 'xiaohongshu-2',
+    name: '小红书风格2',
+    category: 'xiaohongshu',
+    thumbnail: 'https://images.unsplash.com/photo-1469594292607-7bd90f8d3ba4?ixlib=rb-4.0.3&auto=format&fit=crop&w=240&h=240&q=80',
+    fields: [
+      { name: 'title', type: 'text', label: '标题', default: '超治愈的周末旅行,放空自己的绝佳去处' },
+      { name: 'content', type: 'textarea', label: '内容', default: '周末和闺蜜一起去了这个小众景点,环境超级好,人也不多,拍照很出片,完全治愈了工作的疲惫~' },
+      { name: 'tags', type: 'text', label: '标签', default: '#周末出行 #小众景点 #旅行 #治愈系' },
+      { name: 'mainImage', type: 'image', label: '主图', default: 'https://images.unsplash.com/photo-1469594292607-7bd90f8d3ba4?ixlib=rb-4.0.3&auto=format&fit=crop&w=600&q=80' },
+      { name: 'bgColor', type: 'color', label: '背景颜色', default: '#f9f9f9' },
+      { name: 'accentColor', type: 'color', label: '强调色', default: '#ff4757' }
+    ],
+    template: (data) => `
+      <div style="width: 100%; height: 100%; background-color: ${data.bgColor}; font-family: 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', sans-serif; position: relative; overflow: hidden; padding: 15px;">
+        <div style="background-color: white; border-radius: 15px; overflow: hidden; height: 100%; box-shadow: 0 5px 15px rgba(0,0,0,0.05);">
+          <div style="height: 55%; overflow: hidden;">
+            <img src="${data.mainImage}" style="width: 100%; height: 100%; object-fit: cover;" alt="主图">
+          </div>
+          <div style="padding: 20px; height: 45%; overflow: hidden;">
+            <h1 style="font-size: 18px; font-weight: 600; color: #333; margin-bottom: 10px; line-height: 1.4; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; text-overflow: ellipsis;">${data.title}</h1>
+            <p style="font-size: 14px; color: #666; margin-bottom: 10px; line-height: 1.5; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; text-overflow: ellipsis;">${data.content}</p>
+            <p style="font-size: 13px; color: ${data.accentColor}; margin-bottom: 15px;">${data.tags}</p>
+            <div style="display: flex; align-items: center; justify-content: space-between;">
+              <div style="display: flex; align-items: center;">
+                <div style="width: 28px; height: 28px; border-radius: 50%; background-color: #f5f5f5; margin-right: 8px; overflow: hidden;">
+                  <img src="https://images.unsplash.com/photo-1517841905240-472988babdf9?ixlib=rb-4.0.3&auto=format&fit=crop&w=60&h=60&q=80" style="width: 100%; height: 100%; object-fit: cover;" alt="用户头像">
+                </div>
+                <span style="font-size: 13px; color: #333;">旅行达人</span>
+              </div>
+              <div style="display: flex; align-items: center;">
+                <i class="fas fa-heart" style="color: ${data.accentColor}; margin-right: 3px; font-size: 13px;"></i>
+                <span style="font-size: 12px; color: #999; margin-right: 10px;">462</span>
+                <i class="fas fa-bookmark" style="color: #999; margin-right: 3px; font-size: 13px;"></i>
+                <span style="font-size: 12px; color: #999;">89</span>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    `
+  }
+];
+
+// 朋友圈风格模板
+export const wechatMomentsTemplates = [
+  {
+    id: 'wechat-moments-1',
+    name: '朋友圈风格1',
+    category: 'wechat',
+    thumbnail: 'https://images.unsplash.com/photo-1504674900247-0877df9cc836?ixlib=rb-4.0.3&auto=format&fit=crop&w=240&h=240&q=80',
+    fields: [
+      { name: 'content', type: 'textarea', label: '内容', default: '今天的晚餐,色香味俱全,自己做的就是香!#美食 #晚餐' },
+      { name: 'mainImage', type: 'image', label: '主图', default: 'https://images.unsplash.com/photo-1504674900247-0877df9cc836?ixlib=rb-4.0.3&auto=format&fit=crop&w=600&q=80' },
+      { name: 'location', type: 'text', label: '位置', default: '家里的小厨房' },
+      { name: 'bgColor', type: 'color', label: '背景颜色', default: '#f7f7f7' },
+      { name: 'textColor', type: 'color', label: '文字颜色', default: '#333333' }
+    ],
+    template: (data) => `
+      <div style="width: 100%; height: 100%; background-color: ${data.bgColor}; font-family: 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', sans-serif; position: relative; overflow: hidden; padding: 20px;">
+        <div style="background-color: white; border-radius: 8px; overflow: hidden; box-shadow: 0 2px 10px rgba(0,0,0,0.05); padding: 15px;">
+          <div style="display: flex; align-items: center; margin-bottom: 15px;">
+            <div style="width: 40px; height: 40px; border-radius: 50%; background-color: #f5f5f5; margin-right: 10px; overflow: hidden;">
+              <img src="https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?ixlib=rb-4.0.3&auto=format&fit=crop&w=80&h=80&q=80" style="width: 100%; height: 100%; object-fit: cover;" alt="用户头像">
+            </div>
+            <div>
+              <p style="font-size: 15px; font-weight: 600; color: ${data.textColor}; margin-bottom: 3px;">美食达人</p>
+              <p style="font-size: 12px; color: #999;">2小时前</p>
+            </div>
+          </div>
+          <p style="font-size: 15px; color: ${data.textColor}; margin-bottom: 15px; line-height: 1.5;">${data.content}</p>
+          <div style="border-radius: 8px; overflow: hidden; margin-bottom: 12px;">
+            <img src="${data.mainImage}" style="width: 100%; object-fit: cover;" alt="分享图片">
+          </div>
+          <div style="display: flex; align-items: center; margin-bottom: 12px;">
+            <i class="fas fa-map-marker-alt" style="color: #999; margin-right: 5px; font-size: 12px;"></i>
+            <span style="font-size: 12px; color: #576b95;">${data.location}</span>
+          </div>
+          <div style="display: flex; justify-content: flex-end; border-top: 1px solid #f0f0f0; padding-top: 12px;">
+            <div style="display: flex; align-items: center; margin-right: 20px;">
+              <i class="far fa-thumbs-up" style="color: #576b95; margin-right: 5px; font-size: 16px;"></i>
+              <span style="font-size: 14px; color: #576b95;">赞</span>
+            </div>
+            <div style="display: flex; align-items: center;">
+              <i class="far fa-comment" style="color: #576b95; margin-right: 5px; font-size: 16px;"></i>
+              <span style="font-size: 14px; color: #576b95;">评论</span>
+            </div>
+          </div>
+        </div>
+        <div style="position: absolute; bottom: 20px; width: 100%; text-align: center; left: 0; font-size: 12px; color: #999;">
+          <p>长按图片保存,发朋友圈</p>
+        </div>
+      </div>
+    `
+  },
+  {
+    id: 'wechat-moments-2',
+    name: '朋友圈风格2',
+    category: 'wechat',
+    thumbnail: 'https://images.unsplash.com/photo-1529156069898-49953e39b3ac?ixlib=rb-4.0.3&auto=format&fit=crop&w=240&h=240&q=80',
+    fields: [
+      { name: 'content', type: 'textarea', label: '内容', default: '和好友共度美好时光,感恩遇见 🙏' },
+      { name: 'mainImage', type: 'image', label: '主图', default: 'https://images.unsplash.com/photo-1529156069898-49953e39b3ac?ixlib=rb-4.0.3&auto=format&fit=crop&w=600&q=80' },
+      { name: 'time', type: 'text', label: '时间', default: '昨天 20:30' },
+      { name: 'bgColor', type: 'color', label: '背景颜色', default: '#f7f7f7' },
+      { name: 'accentColor', type: 'color', label: '强调色', default: '#576b95' }
+    ],
+    template: (data) => `
+      <div style="width: 100%; height: 100%; background-color: ${data.bgColor}; font-family: 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', sans-serif; position: relative; overflow: hidden; padding: 20px;">
+        <div style="margin-bottom: 15px; display: flex; justify-content: space-between; align-items: center;">
+          <div style="display: flex; align-items: center;">
+            <div style="width: 36px; height: 36px; border-radius: 50%; background-color: #f5f5f5; margin-right: 10px; overflow: hidden;">
+              <img src="https://images.unsplash.com/photo-1438761681033-6461ffad8d80?ixlib=rb-4.0.3&auto=format&fit=crop&w=80&h=80&q=80" style="width: 100%; height: 100%; object-fit: cover;" alt="用户头像">
+            </div>
+            <p style="font-size: 15px; font-weight: 600; color: #333;">生活记录者</p>
+          </div>
+          <p style="font-size: 12px; color: #999;">${data.time}</p>
+        </div>
+        <div style="background-color: white; border-radius: 8px; overflow: hidden; box-shadow: 0 2px 10px rgba(0,0,0,0.05); padding: 15px;">
+          <p style="font-size: 15px; color: #333; margin-bottom: 15px; line-height: 1.5;">${data.content}</p>
+          <div style="border-radius: 8px; overflow: hidden; margin-bottom: 15px;">
+            <img src="${data.mainImage}" style="width: 100%; object-fit: cover;" alt="分享图片">
+          </div>
+          <div style="display: flex; align-items: center; margin-top: 10px;">
+            <div style="display: flex; align-items: center; margin-right: 15px;">
+              <i class="fas fa-heart" style="color: ${data.accentColor}; margin-right: 5px; font-size: 14px;"></i>
+              <span style="font-size: 14px; color: ${data.accentColor};">25</span>
+            </div>
+            <div style="height: 14px; width: 1px; background-color: #e0e0e0; margin-right: 15px;"></div>
+            <div style="display: flex; align-items: center;">
+              <i class="fas fa-comment" style="color: ${data.accentColor}; margin-right: 5px; font-size: 14px;"></i>
+              <span style="font-size: 14px; color: ${data.accentColor};">8</span>
+            </div>
+          </div>
+        </div>
+        <div style="margin-top: 15px; background-color: white; border-radius: 8px; padding: 12px 15px; box-shadow: 0 2px 10px rgba(0,0,0,0.05);">
+          <div style="display: flex; margin-bottom: 8px;">
+            <span style="font-size: 14px; color: ${data.accentColor}; font-weight: 500; margin-right: 5px;">张三:</span>
+            <span style="font-size: 14px; color: #333;">真羡慕你们!下次带上我~</span>
+          </div>
+          <div style="display: flex;">
+            <span style="font-size: 14px; color: ${data.accentColor}; font-weight: 500; margin-right: 5px;">李四:</span>
+            <span style="font-size: 14px; color: #333;">看起来很开心,地点在哪里?</span>
+          </div>
+        </div>
+        <div style="position: absolute; bottom: 20px; width: 100%; text-align: center; left: 0; font-size: 12px; color: #999;">
+          <p>长按图片保存,发朋友圈</p>
+        </div>
+      </div>
+    `
+  }
+];
+
+// 工作群分享模板
+export const workGroupTemplates = [
+  {
+    id: 'work-group-1',
+    name: '工作群分享1',
+    category: 'work',
+    thumbnail: 'https://images.unsplash.com/photo-1542744173-8e7e53415bb0?ixlib=rb-4.0.3&auto=format&fit=crop&w=240&h=240&q=80',
+    fields: [
+      { name: 'title', type: 'text', label: '标题', default: '本周业绩回顾与下周计划' },
+      { name: 'content', type: 'textarea', label: '内容', default: '团队本周超额完成销售目标,达成率120%。下周将重点关注新产品推广和客户回访工作。' },
+      { name: 'date', type: 'text', label: '日期', default: '2023年12月15日' },
+      { name: 'chartImage', type: 'image', label: '图表图片', default: 'https://images.unsplash.com/photo-1542744173-8e7e53415bb0?ixlib=rb-4.0.3&auto=format&fit=crop&w=600&q=80' },
+      { name: 'bgColor', type: 'color', label: '背景颜色', default: '#ffffff' },
+      { name: 'accentColor', type: 'color', label: '强调色', default: '#2c3e50' },
+      { name: 'targetValue', type: 'text', label: '目标达成率', default: '120%' },
+      { name: 'growthValue', type: 'text', label: '同比增长率', default: '+15%' },
+      { name: 'satisfactionValue', type: 'text', label: '客户满意度', default: '89%' },
+      { name: 'authorTitle', type: 'text', label: '作者职位', default: '销售总监' },
+      { name: 'authorRole', type: 'text', label: '作者角色', default: '团队负责人' },
+      { name: 'buttonText', type: 'text', label: '按钮文字', default: '查看详情' }
+    ],
+    template: (data) => `
+      <div style="width: 100%; height: 100%; background-color: ${data.bgColor}; font-family: 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', sans-serif; position: relative; overflow: hidden; padding: 20px;">
+        <div style="background-color: white; border-radius: 10px; overflow: hidden; box-shadow: 0 5px 15px rgba(0,0,0,0.08); height: calc(100% - 40px);">
+          <div style="background-color: ${data.accentColor}; color: white; padding: 20px; position: relative;">
+            <h1 style="font-size: 22px; font-weight: 600; margin-bottom: 10px;">${data.title}</h1>
+            <p style="font-size: 14px;">${data.date}</p>
+            <div style="position: absolute; top: 20px; right: 20px; width: 40px; height: 40px; border-radius: 50%; background-color: rgba(255,255,255,0.2); display: flex; justify-content: center; align-items: center;">
+              <i class="fas fa-chart-line" style="color: white; font-size: 20px;"></i>
+            </div>
+          </div>
+          <div style="padding: 20px;">
+            <p style="font-size: 16px; color: #333; margin-bottom: 20px; line-height: 1.6;">${data.content}</p>
+            <div style="border-radius: 8px; overflow: hidden; margin-bottom: 20px; box-shadow: 0 2px 8px rgba(0,0,0,0.1);">
+              <img src="${data.chartImage}" style="width: 100%; object-fit: cover;" alt="图表">
+            </div>
+            <div style="display: flex; justify-content: space-between; margin-top: 30px;">
+              <div style="text-align: center; flex: 1;">
+                <div style="font-size: 24px; font-weight: 600; color: ${data.accentColor}; margin-bottom: 5px;">${data.targetValue}</div>
+                <p style="font-size: 14px; color: #666;">目标达成</p>
+              </div>
+              <div style="width: 1px; background-color: #e0e0e0;"></div>
+              <div style="text-align: center; flex: 1;">
+                <div style="font-size: 24px; font-weight: 600; color: ${data.accentColor}; margin-bottom: 5px;">${data.growthValue}</div>
+                <p style="font-size: 14px; color: #666;">同比增长</p>
+              </div>
+              <div style="width: 1px; background-color: #e0e0e0;"></div>
+              <div style="text-align: center; flex: 1;">
+                <div style="font-size: 24px; font-weight: 600; color: ${data.accentColor}; margin-bottom: 5px;">${data.satisfactionValue}</div>
+                <p style="font-size: 14px; color: #666;">客户满意度</p>
+              </div>
+            </div>
+          </div>
+          <div style="padding: 15px 20px; border-top: 1px solid #f0f0f0; display: flex; justify-content: space-between; align-items: center;">
+            <div style="display: flex; align-items: center;">
+              <div style="width: 32px; height: 32px; border-radius: 50%; background-color: #f5f5f5; margin-right: 10px; overflow: hidden;">
+                <img src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-4.0.3&auto=format&fit=crop&w=80&h=80&q=80" style="width: 100%; height: 100%; object-fit: cover;" alt="用户头像">
+              </div>
+              <div>
+                <p style="font-size: 14px; font-weight: 500; color: #333; margin-bottom: 2px;">${data.authorTitle}</p>
+                <p style="font-size: 12px; color: #999;">${data.authorRole}</p>
+              </div>
+            </div>
+            <div style="padding: 8px 15px; background-color: ${data.accentColor}; color: white; font-size: 14px; border-radius: 20px;">
+              ${data.buttonText}
+            </div>
+          </div>
+        </div>
+      </div>
+    `
+  },
+  {
+    id: 'work-group-2',
+    name: '工作群分享2',
+    category: 'work',
+    thumbnail: 'https://images.unsplash.com/photo-1552664730-d307ca884978?ixlib=rb-4.0.3&auto=format&fit=crop&w=240&h=240&q=80',
+    fields: [
+      { name: 'title', type: 'text', label: '标题', default: '项目进度报告' },
+      { name: 'projectName', type: 'text', label: '项目名称', default: '新零售系统升级' },
+      { name: 'progress', type: 'text', label: '进度百分比', default: '75' },
+      { name: 'startDate', type: 'text', label: '开始日期', default: '2023年10月15日' },
+      { name: 'deadline', type: 'text', label: '截止日期', default: '2023年12月31日' },
+      { name: 'projectImage', type: 'image', label: '项目图片', default: 'https://images.unsplash.com/photo-1552664730-d307ca884978?ixlib=rb-4.0.3&auto=format&fit=crop&w=600&q=80' },
+      { name: 'bgColor', type: 'color', label: '背景颜色', default: '#f8f9fa' },
+      { name: 'accentColor', type: 'color', label: '强调色', default: '#3498db' },
+      { name: 'teamMemberCount', type: 'text', label: '额外团队成员数', default: '+3' },
+      { name: 'reportLinkText', type: 'text', label: '报告链接文字', default: '查看详细报告' },
+      { name: 'shareLinkText', type: 'text', label: '分享链接文字', default: '分享' },
+      { name: 'teamMembersLabel', type: 'text', label: '团队成员标签', default: '团队成员' },
+      { name: 'progressLabel', type: 'text', label: '进度标签', default: '项目进度' },
+      { name: 'startDateLabel', type: 'text', label: '开始日期标签', default: '开始日期' },
+      { name: 'deadlineLabel', type: 'text', label: '截止日期标签', default: '截止日期' }
+    ],
+    template: (data) => `
+      <div style="width: 100%; height: 100%; background-color: ${data.bgColor}; font-family: 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', sans-serif; position: relative; overflow: hidden; padding: 20px;">
+        <div style="background-color: white; border-radius: 12px; overflow: hidden; box-shadow: 0 5px 15px rgba(0,0,0,0.08); height: calc(100% - 40px);">
+          <div style="height: 40%; overflow: hidden; position: relative;">
+            <img src="${data.projectImage}" style="width: 100%; height: 100%; object-fit: cover; filter: brightness(0.85);" alt="项目图片">
+            <div style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: linear-gradient(to bottom, rgba(0,0,0,0.2), rgba(0,0,0,0.6)); display: flex; flex-direction: column; justify-content: flex-end; padding: 20px;">
+              <h1 style="font-size: 24px; font-weight: 600; color: white; margin-bottom: 10px;">${data.title}</h1>
+              <div style="display: flex; align-items: center;">
+                <div style="width: 10px; height: 10px; border-radius: 50%; background-color: #2ecc71; margin-right: 8px;"></div>
+                <p style="font-size: 14px; color: white;">${data.projectName}</p>
+              </div>
+            </div>
+          </div>
+          <div style="padding: 25px;">
+            <div style="margin-bottom: 25px;">
+              <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;">
+                <p style="font-size: 16px; color: #333; font-weight: 500;">${data.progressLabel}</p>
+                <p style="font-size: 16px; font-weight: 600; color: ${data.accentColor};">${data.progress}%</p>
+              </div>
+              <div style="width: 100%; height: 8px; background-color: #e0e0e0; border-radius: 4px; overflow: hidden;">
+                <div style="width: ${data.progress}%; height: 100%; background-color: ${data.accentColor};"></div>
+              </div>
+            </div>
+            <div style="display: flex; margin-bottom: 25px;">
+              <div style="flex: 1; border-right: 1px solid #e0e0e0; padding-right: 15px;">
+                <p style="font-size: 13px; color: #666; margin-bottom: 5px;">${data.startDateLabel}</p>
+                <p style="font-size: 15px; color: #333; font-weight: 500;">${data.startDate}</p>
+              </div>
+              <div style="flex: 1; padding-left: 15px;">
+                <p style="font-size: 13px; color: #666; margin-bottom: 5px;">${data.deadlineLabel}</p>
+                <p style="font-size: 15px; color: #333; font-weight: 500;">${data.deadline}</p>
+              </div>
+            </div>
+            <div style="margin-bottom: 25px;">
+              <p style="font-size: 16px; color: #333; font-weight: 500; margin-bottom: 10px;">${data.teamMembersLabel}</p>
+              <div style="display: flex;">
+                <div style="width: 36px; height: 36px; border-radius: 50%; background-color: #f5f5f5; border: 2px solid white; overflow: hidden; margin-right: -10px; box-shadow: 0 2px 5px rgba(0,0,0,0.1);">
+                  <img src="https://images.unsplash.com/photo-1500648767791-00dcc994a43e?ixlib=rb-4.0.3&auto=format&fit=crop&w=80&h=80&q=80" style="width: 100%; height: 100%; object-fit: cover;" alt="成员1">
+                </div>
+                <div style="width: 36px; height: 36px; border-radius: 50%; background-color: #f5f5f5; border: 2px solid white; overflow: hidden; margin-right: -10px; box-shadow: 0 2px 5px rgba(0,0,0,0.1);">
+                  <img src="https://images.unsplash.com/photo-1494790108377-be9c29b29330?ixlib=rb-4.0.3&auto=format&fit=crop&w=80&h=80&q=80" style="width: 100%; height: 100%; object-fit: cover;" alt="成员2">
+                </div>
+                <div style="width: 36px; height: 36px; border-radius: 50%; background-color: #f5f5f5; border: 2px solid white; overflow: hidden; margin-right: -10px; box-shadow: 0 2px 5px rgba(0,0,0,0.1);">
+                  <img src="https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?ixlib=rb-4.0.3&auto=format&fit=crop&w=80&h=80&q=80" style="width: 100%; height: 100%; object-fit: cover;" alt="成员3">
+                </div>
+                <div style="width: 36px; height: 36px; border-radius: 50%; background-color: ${data.accentColor}; border: 2px solid white; overflow: hidden; display: flex; justify-content: center; align-items: center; color: white; font-size: 14px; box-shadow: 0 2px 5px rgba(0,0,0,0.1);">
+                  ${data.teamMemberCount}
+                </div>
+              </div>
+            </div>
+          </div>
+          <div style="padding: 15px; border-top: 1px solid #f0f0f0; display: flex; justify-content: space-between;">
+            <div style="display: flex; align-items: center; color: ${data.accentColor}; font-size: 14px;">
+              <i class="fas fa-file-alt" style="margin-right: 8px;"></i>
+              <span>${data.reportLinkText}</span>
+            </div>
+            <div style="display: flex; align-items: center; color: ${data.accentColor}; font-size: 14px;">
+              <i class="fas fa-share-alt" style="margin-right: 8px;"></i>
+              <span>${data.shareLinkText}</span>
+            </div>
+          </div>
+        </div>
+      </div>
+    `
+  }
+];
+
+// 技术团队模板
+export const techTemplates = [
+  {
+    id: 'tech-report-1',
+    name: '技术周报模板',
+    category: 'tech',
+    thumbnail: 'https://images.unsplash.com/photo-1555066931-4365d14bab8c?ixlib=rb-4.0.3&auto=format&fit=crop&w=240&h=240&q=80',
+    fields: [
+      { name: 'title', type: 'text', label: '标题', default: '技术团队周报' },
+      { name: 'week', type: 'text', label: '周期', default: '2023年第48周' },
+      { name: 'achievements', type: 'textarea', label: '主要成果', default: '1. 完成用户中心重构\n2. 修复了5个关键性Bug\n3. 性能优化提升30%' },
+      { name: 'nextWeek', type: 'textarea', label: '下周计划', default: '1. 开始新功能开发\n2. 进行代码审查\n3. 优化CI/CD流程' },
+      { name: 'bgImage', type: 'image', label: '背景图片', default: 'https://images.unsplash.com/photo-1555066931-4365d14bab8c?ixlib=rb-4.0.3&auto=format&fit=crop&w=600&q=80' },
+      { name: 'bgColor', type: 'color', label: '背景颜色', default: '#1e272e' },
+      { name: 'accentColor', type: 'color', label: '强调色', default: '#0984e3' },
+      { name: 'bugFixCount', type: 'text', label: 'Bug修复数量', default: '5' },
+      { name: 'newFeatureCount', type: 'text', label: '新功能数量', default: '2' },
+      { name: 'performanceImprovement', type: 'text', label: '性能提升', default: '30%' },
+      { name: 'bugFixLabel', type: 'text', label: 'Bug修复标签', default: 'Bug修复' },
+      { name: 'newFeatureLabel', type: 'text', label: '新功能标签', default: '新功能' },
+      { name: 'performanceLabel', type: 'text', label: '性能标签', default: '性能提升' },
+      { name: 'achievementsTitle', type: 'text', label: '成果标题', default: '本周成果' },
+      { name: 'nextWeekTitle', type: 'text', label: '计划标题', default: '下周计划' },
+      { name: 'footerText', type: 'text', label: '页脚文本', default: '技术团队 © 2023' }
+    ],
+    template: (data) => `
+      <div style="width: 100%; height: 100%; background-color: ${data.bgColor}; font-family: 'Roboto', 'PingFang SC', sans-serif; position: relative; overflow: hidden; padding: 20px; color: white;">
+        <div style="position: absolute; top: 0; left: 0; width: 100%; height: 30%; opacity: 0.2;">
+          <img src="${data.bgImage}" style="width: 100%; height: 100%; object-fit: cover;" alt="背景图片">
+        </div>
+        <div style="position: relative; z-index: 2; padding: 15px;">
+          <h1 style="font-size: 28px; font-weight: 700; margin-bottom: 10px; color: white;">${data.title}</h1>
+          <div style="width: 50px; height: 4px; background-color: ${data.accentColor}; margin-bottom: 15px;"></div>
+          <p style="font-size: 16px; margin-bottom: 25px; color: #dfe6e9;">${data.week}</p>
+          
+          <div style="margin-bottom: 25px;">
+            <h2 style="font-size: 18px; font-weight: 600; margin-bottom: 15px; color: ${data.accentColor};">${data.achievementsTitle}</h2>
+            <div style="background-color: rgba(0, 0, 0, 0.2); border-radius: 8px; padding: 15px;">
+              <p style="font-size: 15px; line-height: 1.6; white-space: pre-line;">${data.achievements}</p>
+            </div>
+          </div>
+          
+          <div style="margin-bottom: 25px;">
+            <h2 style="font-size: 18px; font-weight: 600; margin-bottom: 15px; color: ${data.accentColor};">${data.nextWeekTitle}</h2>
+            <div style="background-color: rgba(0, 0, 0, 0.2); border-radius: 8px; padding: 15px;">
+              <p style="font-size: 15px; line-height: 1.6; white-space: pre-line;">${data.nextWeek}</p>
+            </div>
+          </div>
+          
+          <div style="display: flex; justify-content: space-between; margin-top: 30px;">
+            <div style="text-align: center; background-color: rgba(0, 0, 0, 0.3); padding: 10px; border-radius: 8px; flex: 1; margin-right: 10px;">
+              <p style="font-size: 24px; font-weight: 700; color: ${data.accentColor};">${data.bugFixCount}</p>
+              <p style="font-size: 14px; color: #dfe6e9;">${data.bugFixLabel}</p>
+            </div>
+            <div style="text-align: center; background-color: rgba(0, 0, 0, 0.3); padding: 10px; border-radius: 8px; flex: 1; margin-right: 10px;">
+              <p style="font-size: 24px; font-weight: 700; color: ${data.accentColor};">${data.newFeatureCount}</p>
+              <p style="font-size: 14px; color: #dfe6e9;">${data.newFeatureLabel}</p>
+            </div>
+            <div style="text-align: center; background-color: rgba(0, 0, 0, 0.3); padding: 10px; border-radius: 8px; flex: 1;">
+              <p style="font-size: 24px; font-weight: 700; color: ${data.accentColor};">${data.performanceImprovement}</p>
+              <p style="font-size: 14px; color: #dfe6e9;">${data.performanceLabel}</p>
+            </div>
+          </div>
+        </div>
+        <div style="position: absolute; bottom: 20px; right: 20px; font-size: 14px; color: #dfe6e9;">
+          <p>${data.footerText}</p>
+        </div>
+      </div>
+    `
+  },
+  {
+    id: 'code-share-1',
+    name: '代码分享模板',
+    category: 'tech',
+    thumbnail: 'https://images.unsplash.com/photo-1498050108023-c5249f4df085?ixlib=rb-4.0.3&auto=format&fit=crop&w=240&h=240&q=80',
+    fields: [
+      { name: 'title', type: 'text', label: '标题', default: '优雅的代码解决方案' },
+      { name: 'language', type: 'text', label: '编程语言', default: 'JavaScript' },
+      { name: 'description', type: 'textarea', label: '描述', default: '这个优化方案将原本O(n²)的算法复杂度降低到了O(n),大幅提升了性能。' },
+      { name: 'codeImage', type: 'image', label: '代码截图', default: 'https://images.unsplash.com/photo-1498050108023-c5249f4df085?ixlib=rb-4.0.3&auto=format&fit=crop&w=600&q=80' },
+      { name: 'bgColor', type: 'color', label: '背景颜色', default: '#282c34' },
+      { name: 'accentColor', type: 'color', label: '强调色', default: '#61dafb' }
+    ],
+    template: (data) => `
+      <div style="width: 100%; height: 100%; background-color: ${data.bgColor}; font-family: 'Fira Code', 'Source Code Pro', monospace; position: relative; overflow: hidden; padding: 20px; color: #abb2bf;">
+        <div style="position: relative; z-index: 2;">
+          <div style="display: flex; align-items: center; margin-bottom: 20px;">
+            <div style="width: 12px; height: 12px; border-radius: 50%; background-color: #ff5f56; margin-right: 8px;"></div>
+            <div style="width: 12px; height: 12px; border-radius: 50%; background-color: #ffbd2e; margin-right: 8px;"></div>
+            <div style="width: 12px; height: 12px; border-radius: 50%; background-color: #27c93f; margin-right: 15px;"></div>
+            <p style="font-size: 14px; color: #dfe6e9;">${data.language} - Code Snippet</p>
+          </div>
+          
+          <h1 style="font-size: 24px; font-weight: 600; margin-bottom: 15px; color: ${data.accentColor};">${data.title}</h1>
+          
+          <div style="background-color: rgba(0, 0, 0, 0.3); border-radius: 8px; padding: 15px; margin-bottom: 20px; max-height: 300px; overflow: hidden;">
+            <img src="${data.codeImage}" style="width: 100%; object-fit: contain;" alt="代码截图">
+          </div>
+          
+          <div style="background-color: rgba(0, 0, 0, 0.2); border-radius: 8px; padding: 15px; margin-bottom: 20px;">
+            <p style="font-size: 15px; line-height: 1.6;">${data.description}</p>
+          </div>
+          
+          <div style="display: flex; justify-content: space-between; margin-top: 30px;">
+            <div style="display: flex; align-items: center;">
+              <div style="width: 36px; height: 36px; border-radius: 50%; background-color: #2d3436; margin-right: 10px; overflow: hidden;">
+                <img src="https://images.unsplash.com/photo-1531427186611-ecfd6d936c79?ixlib=rb-4.0.3&auto=format&fit=crop&w=80&h=80&q=80" style="width: 100%; height: 100%; object-fit: cover;" alt="用户头像">
+              </div>
+              <div>
+                <p style="font-size: 14px; color: white; margin-bottom: 2px;">高级开发工程师</p>
+                <p style="font-size: 12px; color: #dfe6e9;">技术架构组</p>
+              </div>
+            </div>
+            <div style="display: flex; align-items: center;">
+              <div style="padding: 8px 15px; background-color: ${data.accentColor}; color: ${data.bgColor}; font-size: 14px; border-radius: 4px; font-weight: 600;">
+                查看完整代码
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    `
+  }
+];
+
+// 产品团队模板
+export const productTemplates = [
+  {
+    id: 'product-roadmap-1',
+    name: '产品路线图',
+    category: 'product',
+    thumbnail: 'https://images.unsplash.com/photo-1572177812156-58036aae439c?ixlib=rb-4.0.3&auto=format&fit=crop&w=240&h=240&q=80',
+    fields: [
+      { name: 'title', type: 'text', label: '标题', default: '2024年产品路线图' },
+      { name: 'q1Goals', type: 'textarea', label: 'Q1目标', default: '用户体验优化\n核心功能重构\n新用户引导流程' },
+      { name: 'q2Goals', type: 'textarea', label: 'Q2目标', default: '数据分析平台\n企业版功能\nAPI升级' },
+      { name: 'productImage', type: 'image', label: '产品图片', default: 'https://images.unsplash.com/photo-1572177812156-58036aae439c?ixlib=rb-4.0.3&auto=format&fit=crop&w=600&q=80' },
+      { name: 'bgColor', type: 'color', label: '背景颜色', default: '#ffffff' },
+      { name: 'accentColor', type: 'color', label: '强调色', default: '#6c5ce7' }
+    ],
+    template: (data) => `
+      <div style="width: 100%; height: 100%; background-color: ${data.bgColor}; font-family: 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', sans-serif; position: relative; overflow: hidden;">
+        <div style="position: absolute; top: 0; left: 0; width: 100%; height: 40%; overflow: hidden;">
+          <img src="${data.productImage}" style="width: 100%; height: 100%; object-fit: cover; filter: brightness(0.9);" alt="产品图片">
+          <div style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: linear-gradient(to bottom, rgba(0,0,0,0), ${data.bgColor});"></div>
+        </div>
+        
+        <div style="position: absolute; top: 30px; left: 30px; right: 30px;">
+          <h1 style="font-size: 28px; font-weight: 700; color: white; text-shadow: 0 2px 4px rgba(0,0,0,0.3);">${data.title}</h1>
+        </div>
+        
+        <div style="position: absolute; top: 35%; left: 0; width: 100%; padding: 30px;">
+          <div style="display: flex; margin-bottom: 30px;">
+            <div style="flex: 1; margin-right: 20px;">
+              <div style="display: flex; align-items: center; margin-bottom: 15px;">
+                <div style="width: 30px; height: 30px; border-radius: 50%; background-color: ${data.accentColor}; color: white; display: flex; justify-content: center; align-items: center; margin-right: 10px; font-weight: 600;">Q1</div>
+                <h2 style="font-size: 18px; font-weight: 600; color: #333;">1-3月</h2>
+              </div>
+              <div style="background-color: #f5f7fa; border-radius: 8px; padding: 15px; border-left: 4px solid ${data.accentColor};">
+                <p style="font-size: 15px; line-height: 1.6; color: #333; white-space: pre-line;">${data.q1Goals}</p>
+              </div>
+            </div>
+            <div style="flex: 1;">
+              <div style="display: flex; align-items: center; margin-bottom: 15px;">
+                <div style="width: 30px; height: 30px; border-radius: 50%; background-color: ${data.accentColor}; color: white; display: flex; justify-content: center; align-items: center; margin-right: 10px; font-weight: 600;">Q2</div>
+                <h2 style="font-size: 18px; font-weight: 600; color: #333;">4-6月</h2>
+              </div>
+              <div style="background-color: #f5f7fa; border-radius: 8px; padding: 15px; border-left: 4px solid ${data.accentColor};">
+                <p style="font-size: 15px; line-height: 1.6; color: #333; white-space: pre-line;">${data.q2Goals}</p>
+              </div>
+            </div>
+          </div>
+          
+          <div style="background-color: ${data.accentColor}; border-radius: 8px; padding: 20px; color: white;">
+            <h3 style="font-size: 18px; font-weight: 600; margin-bottom: 10px;">关键指标</h3>
+            <div style="display: flex; justify-content: space-between;">
+              <div style="text-align: center; flex: 1;">
+                <p style="font-size: 24px; font-weight: 700; margin-bottom: 5px;">+30%</p>
+                <p style="font-size: 14px;">用户增长</p>
+              </div>
+              <div style="text-align: center; flex: 1;">
+                <p style="font-size: 24px; font-weight: 700; margin-bottom: 5px;">-25%</p>
+                <p style="font-size: 14px;">流失率</p>
+              </div>
+              <div style="text-align: center; flex: 1;">
+                <p style="font-size: 24px; font-weight: 700; margin-bottom: 5px;">+45%</p>
+                <p style="font-size: 14px;">转化率</p>
+              </div>
+            </div>
+          </div>
+        </div>
+        
+        <div style="position: absolute; bottom: 20px; right: 30px; display: flex; align-items: center;">
+          <p style="font-size: 14px; color: #666; margin-right: 10px;">由产品团队制作</p>
+          <div style="width: 30px; height: 30px; border-radius: 50%; background-color: ${data.accentColor}; display: flex; justify-content: center; align-items: center;">
+            <i class="fas fa-rocket" style="color: white; font-size: 14px;"></i>
+          </div>
+        </div>
+      </div>
+    `
+  },
+  {
+    id: 'user-research-1',
+    name: '用户研究报告',
+    category: 'product',
+    thumbnail: 'https://images.unsplash.com/photo-1551836022-d5d88e9218df?ixlib=rb-4.0.3&auto=format&fit=crop&w=240&h=240&q=80',
+    fields: [
+      { name: 'title', type: 'text', label: '标题', default: '用户研究报告' },
+      { name: 'subtitle', type: 'text', label: '副标题', default: '核心用户行为分析' },
+      { name: 'findings', type: 'textarea', label: '主要发现', default: '1. 80%的用户在首次使用时遇到了导航困难\n2. 核心功能的使用频率低于预期\n3. 用户对新功能的接受度高' },
+      { name: 'recommendations', type: 'textarea', label: '改进建议', default: '1. 优化首页导航结构\n2. 增强核心功能的引导\n3. 加快新功能的迭代速度' },
+      { name: 'researchImage', type: 'image', label: '研究图片', default: 'https://images.unsplash.com/photo-1551836022-d5d88e9218df?ixlib=rb-4.0.3&auto=format&fit=crop&w=600&q=80' },
+      { name: 'bgColor', type: 'color', label: '背景颜色', default: '#f5f7fa' },
+      { name: 'accentColor', type: 'color', label: '强调色', default: '#00b894' }
+    ],
+    template: (data) => `
+      <div style="width: 100%; height: 100%; background-color: ${data.bgColor}; font-family: 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', sans-serif; position: relative; overflow: hidden; padding: 25px;">
+        <div style="background-color: white; border-radius: 12px; overflow: hidden; box-shadow: 0 5px 15px rgba(0,0,0,0.05); height: calc(100% - 50px);">
+          <div style="padding: 25px;">
+            <div style="display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 20px;">
+              <div>
+                <h1 style="font-size: 24px; font-weight: 700; color: #333; margin-bottom: 8px;">${data.title}</h1>
+                <p style="font-size: 16px; color: #666;">${data.subtitle}</p>
+              </div>
+              <div style="width: 50px; height: 50px; border-radius: 50%; background-color: ${data.accentColor}; display: flex; justify-content: center; align-items: center;">
+                <i class="fas fa-user-check" style="color: white; font-size: 20px;"></i>
+              </div>
+            </div>
+            
+            <div style="display: flex; gap: 20px; margin-bottom: 25px;">
+              <div style="flex: 1;">
+                <img src="${data.researchImage}" style="width: 100%; height: 180px; object-fit: cover; border-radius: 8px;" alt="研究图片">
+              </div>
+              <div style="flex: 1; display: flex; flex-direction: column; justify-content: space-between;">
+                <div style="background-color: ${data.accentColor}; border-radius: 8px; padding: 15px; color: white; margin-bottom: 10px;">
+                  <p style="font-size: 14px; margin-bottom: 5px;">参与用户</p>
+                  <p style="font-size: 28px; font-weight: 700;">120</p>
+                </div>
+                <div style="display: flex; gap: 10px;">
+                  <div style="flex: 1; background-color: #f5f7fa; border-radius: 8px; padding: 15px;">
+                    <p style="font-size: 14px; color: #666; margin-bottom: 5px;">满意度</p>
+                    <p style="font-size: 22px; font-weight: 600; color: #333;">78%</p>
+                  </div>
+                  <div style="flex: 1; background-color: #f5f7fa; border-radius: 8px; padding: 15px;">
+                    <p style="font-size: 14px; color: #666; margin-bottom: 5px;">完成率</p>
+                    <p style="font-size: 22px; font-weight: 600; color: #333;">65%</p>
+                  </div>
+                </div>
+              </div>
+            </div>
+            
+            <div style="margin-bottom: 25px;">
+              <h2 style="font-size: 18px; font-weight: 600; color: #333; margin-bottom: 12px; display: flex; align-items: center;">
+                <i class="fas fa-lightbulb" style="color: ${data.accentColor}; margin-right: 8px;"></i>
+                主要发现
+              </h2>
+              <div style="background-color: #f5f7fa; border-radius: 8px; padding: 15px;">
+                <p style="font-size: 15px; line-height: 1.6; color: #333; white-space: pre-line;">${data.findings}</p>
+              </div>
+            </div>
+            
+            <div>
+              <h2 style="font-size: 18px; font-weight: 600; color: #333; margin-bottom: 12px; display: flex; align-items: center;">
+                <i class="fas fa-clipboard-check" style="color: ${data.accentColor}; margin-right: 8px;"></i>
+                改进建议
+              </h2>
+              <div style="background-color: #f5f7fa; border-radius: 8px; padding: 15px;">
+                <p style="font-size: 15px; line-height: 1.6; color: #333; white-space: pre-line;">${data.recommendations}</p>
+              </div>
+            </div>
+          </div>
+          
+          <div style="padding: 15px 25px; border-top: 1px solid #f0f0f0; display: flex; justify-content: space-between; align-items: center;">
+            <div style="display: flex; align-items: center;">
+              <div style="width: 36px; height: 36px; border-radius: 50%; background-color: #f5f7fa; margin-right: 10px; overflow: hidden;">
+                <img src="https://images.unsplash.com/photo-1573497019940-1c28c88b4f3e?ixlib=rb-4.0.3&auto=format&fit=crop&w=80&h=80&q=80" style="width: 100%; height: 100%; object-fit: cover;" alt="用户头像">
+              </div>
+              <div>
+                <p style="font-size: 14px; font-weight: 500; color: #333; margin-bottom: 2px;">用户体验设计师</p>
+                <p style="font-size: 12px; color: #999;">产品团队</p>
+              </div>
+            </div>
+            <p style="font-size: 14px; color: #999;">2023年12月</p>
+          </div>
+        </div>
+      </div>
+    `
+  }
+];
+
+// 运营团队模板
+export const operationTemplates = [
+  {
+    id: 'data-report-1',
+    name: '数据分析报告',
+    category: 'operation',
+    thumbnail: 'https://images.unsplash.com/photo-1551288049-bebda4e38f71?ixlib=rb-4.0.3&auto=format&fit=crop&w=240&h=240&q=80',
+    fields: [
+      { name: 'title', type: 'text', label: '标题', default: '11月营销活动分析报告' },
+      { name: 'highlights', type: 'textarea', label: '亮点', default: '1. 新用户增长率达到35%,超过目标25%\n2. 活动转化率提升40%\n3. 社交媒体互动量增长60%' },
+      { name: 'nextSteps', type: 'textarea', label: '下一步计划', default: '1. 扩大社交媒体投放\n2. 优化转化漏斗\n3. 增加会员专属活动' },
+      { name: 'chartImage', type: 'image', label: '图表图片', default: 'https://images.unsplash.com/photo-1551288049-bebda4e38f71?ixlib=rb-4.0.3&auto=format&fit=crop&w=600&q=80' },
+      { name: 'bgColor', type: 'color', label: '背景颜色', default: '#ffffff' },
+      { name: 'accentColor', type: 'color', label: '强调色', default: '#fd79a8' }
+    ],
+    template: (data) => `
+      <div style="width: 100%; height: 100%; background-color: ${data.bgColor}; font-family: 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', sans-serif; position: relative; overflow: hidden; padding: 20px;">
+        <div style="background: linear-gradient(135deg, ${data.accentColor}, #a29bfe); border-radius: 15px 15px 0 0; padding: 25px; color: white;">
+          <h1 style="font-size: 24px; font-weight: 700; margin-bottom: 10px;">${data.title}</h1>
+          <p style="font-size: 14px; opacity: 0.9;">运营数据分析 · 2023年11月</p>
+        </div>
+        
+        <div style="background-color: white; border-radius: 0 0 15px 15px; padding: 25px; box-shadow: 0 5px 15px rgba(0,0,0,0.05);">
+          <div style="margin-bottom: 25px;">
+            <img src="${data.chartImage}" style="width: 100%; height: 200px; object-fit: cover; border-radius: 8px;" alt="数据图表">
+          </div>
+          
+          <div style="display: flex; justify-content: space-between; margin-bottom: 25px;">
+            <div style="text-align: center; flex: 1; padding: 15px; border-radius: 8px; background-color: #f8f9fa;">
+              <p style="font-size: 28px; font-weight: 700; color: ${data.accentColor}; margin-bottom: 5px;">35%</p>
+              <p style="font-size: 14px; color: #666;">新用户增长</p>
+            </div>
+            <div style="text-align: center; flex: 1; padding: 15px; border-radius: 8px; background-color: #f8f9fa; margin: 0 15px;">
+              <p style="font-size: 28px; font-weight: 700; color: ${data.accentColor}; margin-bottom: 5px;">40%</p>
+              <p style="font-size: 14px; color: #666;">转化率提升</p>
+            </div>
+            <div style="text-align: center; flex: 1; padding: 15px; border-radius: 8px; background-color: #f8f9fa;">
+              <p style="font-size: 28px; font-weight: 700; color: ${data.accentColor}; margin-bottom: 5px;">60%</p>
+              <p style="font-size: 14px; color: #666;">互动量增长</p>
+            </div>
+          </div>
+          
+          <div style="margin-bottom: 25px;">
+            <h2 style="font-size: 18px; font-weight: 600; color: #333; margin-bottom: 12px; display: flex; align-items: center;">
+              <i class="fas fa-chart-line" style="color: ${data.accentColor}; margin-right: 8px;"></i>
+              活动亮点
+            </h2>
+            <div style="background-color: #f8f9fa; border-radius: 8px; padding: 15px;">
+              <p style="font-size: 15px; line-height: 1.6; color: #333; white-space: pre-line;">${data.highlights}</p>
+            </div>
+          </div>
+          
+          <div>
+            <h2 style="font-size: 18px; font-weight: 600; color: #333; margin-bottom: 12px; display: flex; align-items: center;">
+              <i class="fas fa-tasks" style="color: ${data.accentColor}; margin-right: 8px;"></i>
+              下一步计划
+            </h2>
+            <div style="background-color: #f8f9fa; border-radius: 8px; padding: 15px;">
+              <p style="font-size: 15px; line-height: 1.6; color: #333; white-space: pre-line;">${data.nextSteps}</p>
+            </div>
+          </div>
+        </div>
+        
+        <div style="position: absolute; bottom: 30px; right: 30px; display: flex; align-items: center;">
+          <div style="width: 36px; height: 36px; border-radius: 50%; background-color: #f5f7fa; margin-right: 10px; overflow: hidden;">
+            <img src="https://images.unsplash.com/photo-1573497019940-1c28c88b4f3e?ixlib=rb-4.0.3&auto=format&fit=crop&w=80&h=80&q=80" style="width: 100%; height: 100%; object-fit: cover;" alt="用户头像">
+          </div>
+          <div>
+            <p style="font-size: 14px; font-weight: 500; color: #333; margin-bottom: 2px;">增长运营专家</p>
+            <p style="font-size: 12px; color: #999;">运营团队</p>
+          </div>
+        </div>
+      </div>
+    `
+  },
+  {
+    id: 'campaign-1',
+    name: '营销活动海报',
+    category: 'operation',
+    thumbnail: 'https://images.unsplash.com/photo-1557804506-669a67965ba0?ixlib=rb-4.0.3&auto=format&fit=crop&w=240&h=240&q=80',
+    fields: [
+      { name: 'title', type: 'text', label: '活动标题', default: '年末狂欢购物节' },
+      { name: 'subtitle', type: 'text', label: '副标题', default: '全场低至5折,多重好礼等你拿' },
+      { name: 'period', type: 'text', label: '活动时间', default: '12月18日-12月31日' },
+      { name: 'highlights', type: 'textarea', label: '活动亮点', default: '1. 爆品限时秒杀\n2. 满300减100\n3. 新用户专享券\n4. 会员额外95折' },
+      { name: 'campaignImage', type: 'image', label: '活动图片', default: 'https://images.unsplash.com/photo-1557804506-669a67965ba0?ixlib=rb-4.0.3&auto=format&fit=crop&w=600&q=80' },
+      { name: 'bgColor', type: 'color', label: '背景颜色', default: '#ffeaa7' },
+      { name: 'accentColor', type: 'color', label: '强调色', default: '#d63031' }
+    ],
+    template: (data) => `
+      <div style="width: 100%; height: 100%; background-color: ${data.bgColor}; font-family: 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', sans-serif; position: relative; overflow: hidden;">
+        <div style="position: absolute; top: 0; left: 0; width: 100%; height: 50%; overflow: hidden;">
+          <img src="${data.campaignImage}" style="width: 100%; height: 100%; object-fit: cover;" alt="活动图片">
+          <div style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: linear-gradient(to bottom, rgba(0,0,0,0.1), rgba(0,0,0,0.4));"></div>
+        </div>
+        
+        <div style="position: absolute; top: 30px; right: 30px; background-color: ${data.accentColor}; color: white; padding: 8px 15px; border-radius: 20px; font-size: 14px; font-weight: 600; transform: rotate(5deg); box-shadow: 0 3px 10px rgba(0,0,0,0.2);">
+          限时活动
+        </div>
+        
+        <div style="position: absolute; top: 50%; left: 0; width: 100%; transform: translateY(-50%); padding: 0 30px; text-align: center;">
+          <h1 style="font-size: 36px; font-weight: 800; color: white; margin-bottom: 10px; text-shadow: 0 2px 5px rgba(0,0,0,0.3);">${data.title}</h1>
+          <p style="font-size: 18px; color: white; margin-bottom: 5px; text-shadow: 0 1px 3px rgba(0,0,0,0.3);">${data.subtitle}</p>
+        </div>
+        
+        <div style="position: absolute; bottom: 0; left: 0; width: 100%; height: 50%; background-color: white; border-top-left-radius: 30px; border-top-right-radius: 30px; padding: 30px; box-shadow: 0 -5px 20px rgba(0,0,0,0.1);">
+          <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px;">
+            <h2 style="font-size: 20px; font-weight: 600; color: #333;">活动详情</h2>
+            <div style="padding: 5px 12px; background-color: #f8f9fa; border-radius: 15px; font-size: 14px; color: #666;">${data.period}</div>
+          </div>
+          
+          <div style="margin-bottom: 25px;">
+            <div style="background-color: #f8f9fa; border-radius: 12px; padding: 15px;">
+              <p style="font-size: 15px; line-height: 1.8; color: #333; white-space: pre-line;">${data.highlights}</p>
+            </div>
+          </div>
+          
+          <div style="display: flex; justify-content: center; margin-top: 20px;">
+            <div style="padding: 12px 30px; background-color: ${data.accentColor}; color: white; font-size: 16px; font-weight: 600; border-radius: 25px; box-shadow: 0 4px 10px rgba(214, 48, 49, 0.3);">
+              立即参与
+            </div>
+          </div>
+        </div>
+        
+        <div style="position: absolute; bottom: 20px; left: 30px; display: flex; align-items: center;">
+          <div style="width: 30px; height: 30px; border-radius: 50%; background-color: ${data.accentColor}; display: flex; justify-content: center; align-items: center; margin-right: 10px;">
+            <i class="fas fa-qrcode" style="color: white; font-size: 14px;"></i>
+          </div>
+          <p style="font-size: 14px; color: #666;">扫码了解更多</p>
+        </div>
+      </div>
+    `
+  }
+];
+
+// 合并所有模板
+templates.push(...xiaohongshuTemplates, ...wechatMomentsTemplates, ...workGroupTemplates, ...techTemplates, ...productTemplates, ...operationTemplates);

+ 375 - 0
apps/poster-maker/js/templateRenderer.js

@@ -0,0 +1,375 @@
+// 模板渲染器
+
+// 渲染模板缩略图列表
+export function renderTemplates(templates, category = 'all') {
+  const templatesContainer = document.getElementById('templates-container');
+  
+  if (!templatesContainer) return;
+  
+  templatesContainer.innerHTML = '';
+  
+  // 根据分类筛选模板
+  const filteredTemplates = category === 'all' 
+    ? templates 
+    : templates.filter(template => template.category === category);
+  
+  // 创建一个文档片段,减少DOM操作
+  const fragment = document.createDocumentFragment();
+  
+  filteredTemplates.forEach(template => {
+    const templateItem = document.createElement('div');
+    templateItem.className = 'template-item';
+    templateItem.dataset.templateId = template.id;
+    
+    const thumbnail = document.createElement('img');
+    // 使用较小的缩略图尺寸来加快加载
+    thumbnail.src = template.thumbnail;
+    thumbnail.className = 'template-thumbnail';
+    thumbnail.alt = template.name;
+    thumbnail.loading = 'lazy'; // 懒加载图片
+    
+    const templateName = document.createElement('div');
+    templateName.className = 'template-name';
+    templateName.textContent = template.name;
+    
+    templateItem.appendChild(thumbnail);
+    templateItem.appendChild(templateName);
+    fragment.appendChild(templateItem);
+    
+    // 添加点击事件
+    templateItem.addEventListener('click', () => {
+      // 移除其他模板的选中状态
+      document.querySelectorAll('.template-item').forEach(item => {
+        item.classList.remove('selected');
+      });
+      
+      // 添加选中状态
+      templateItem.classList.add('selected');
+      
+      // 初始化编辑器
+      initializeEditor(template);
+    });
+  });
+  
+  // 一次性将所有元素添加到容器中
+  templatesContainer.appendChild(fragment);
+}
+
+// 初始化编辑器
+export function initializeEditor(template) {
+  const editForm = document.getElementById('edit-form');
+  const posterPreview = document.getElementById('poster-preview');
+  const downloadBtn = document.getElementById('download-btn');
+  const shareBtn = document.getElementById('share-btn');
+  
+  if (!editForm || !posterPreview) return;
+  
+  // 清空编辑表单
+  editForm.innerHTML = '';
+  
+  // 存储当前模板数据
+  window.currentTemplate = template;
+  window.currentValues = {};
+  
+  // 创建一个空的数据对象,用于生成模板HTML
+  const emptyData = {};
+  template.fields.forEach(field => {
+    // 为每个字段提供默认值,避免undefined
+    emptyData[field.name] = field.default || '';
+  });
+  
+  // 检查模板HTML中是否有硬编码的内容
+  const templateHTML = template.template(emptyData);
+  const hardcodedTexts = findHardcodedTexts(templateHTML);
+  
+  // 组合所有需要编辑的字段
+  let allFields = [...template.fields];
+  
+  // 添加从模板中检测到的硬编码文本作为可编辑字段
+  const existingDefaults = allFields.map(field => field.default);
+  
+  hardcodedTexts.forEach((text, index) => {
+    // 检查文本是否已存在于字段中,或者是否是常见文本
+    if (!existingDefaults.includes(text) && !isCommonText(text)) {
+      // 为检测到的文本创建一个更有意义的标签
+      let label = '检测到的文本';
+      
+      if (text.length > 15) {
+        label = `${text.substring(0, 15)}...`;
+      } else {
+        label = text;
+      }
+      
+      allFields.push({
+        name: `detected_text_${index}`,
+        type: 'text',
+        label: label,
+        default: text
+      });
+    }
+  });
+  
+  // 为每个字段创建表单控件
+  allFields.forEach(field => {
+    // 确保字段有默认值,避免undefined
+    if (field.default === undefined || field.default === null) {
+      field.default = '';
+    }
+    
+    // 如果是检测到的文本字段,但内容过短或不需要编辑,则跳过
+    if (field.name.startsWith('detected_text_') && isCommonText(field.default)) {
+      return;
+    }
+    
+    const formGroup = document.createElement('div');
+    formGroup.className = 'form-group';
+    
+    const label = document.createElement('label');
+    label.textContent = field.label;
+    label.setAttribute('for', `field-${field.name}`);
+    
+    let input;
+    
+    // 根据字段类型创建不同的输入控件
+    switch (field.type) {
+      case 'textarea':
+        input = document.createElement('textarea');
+        input.className = 'form-control';
+        input.id = `field-${field.name}`;
+        input.value = field.default || '';
+        input.rows = 3;
+        break;
+        
+      case 'color':
+        input = document.createElement('input');
+        input.type = 'color';
+        input.className = 'color-picker';
+        input.id = `field-${field.name}`;
+        input.value = field.default || '#000000';
+        break;
+        
+      case 'image':
+        const imageUpload = document.createElement('div');
+        imageUpload.className = 'image-upload';
+        
+        const imagePreview = document.createElement('div');
+        imagePreview.className = 'upload-preview';
+        
+        const img = document.createElement('img');
+        img.src = field.default || '';
+        img.id = `preview-${field.name}`;
+        imagePreview.appendChild(img);
+        
+        const uploadButton = document.createElement('label');
+        uploadButton.className = 'upload-btn';
+        uploadButton.textContent = '选择图片';
+        uploadButton.setAttribute('for', `field-${field.name}`);
+        
+        input = document.createElement('input');
+        input.type = 'file';
+        input.accept = 'image/*';
+        input.id = `field-${field.name}`;
+        input.style.display = 'none';
+        
+        // 添加图片预览功能
+        input.addEventListener('change', function(e) {
+          const file = e.target.files[0];
+          if (file) {
+            const reader = new FileReader();
+            reader.onload = function(event) {
+              img.src = event.target.result;
+              window.currentValues[field.name] = event.target.result;
+              updatePosterPreview();
+            };
+            reader.readAsDataURL(file);
+          }
+        });
+        
+        imageUpload.appendChild(imagePreview);
+        imageUpload.appendChild(uploadButton);
+        imageUpload.appendChild(input);
+        
+        formGroup.appendChild(label);
+        formGroup.appendChild(imageUpload);
+        editForm.appendChild(formGroup);
+        
+        // 存储默认值
+        window.currentValues[field.name] = field.default || '';
+        
+        return;
+        
+      default: // text 和其他类型
+        input = document.createElement('input');
+        input.type = 'text';
+        input.className = 'form-control';
+        input.id = `field-${field.name}`;
+        input.value = field.default || '';
+    }
+    
+    // 添加输入事件监听器
+    input.addEventListener('input', function(e) {
+      window.currentValues[field.name] = e.target.value;
+      updatePosterPreview();
+    });
+    
+    // 存储默认值
+    window.currentValues[field.name] = field.default || '';
+    
+    formGroup.appendChild(label);
+    formGroup.appendChild(input);
+    editForm.appendChild(formGroup);
+  });
+  
+  // 启用下载和分享按钮
+  if (downloadBtn) downloadBtn.disabled = false;
+  if (shareBtn) shareBtn.disabled = false;
+  
+  // 更新预览
+  updatePosterPreview();
+  
+  // 自动切换到编辑标签页
+  const editorTab = document.querySelector('.panel-tab[data-tab="editor-tab"]');
+  if (editorTab) {
+    editorTab.click();
+  }
+  
+  // 添加一个提示信息,如果检测到了额外文本
+  const detectedCount = allFields.filter(f => f.name.startsWith('detected_text_')).length;
+  if (detectedCount > 0 && !document.querySelector('.detection-notice')) {
+    const notice = document.createElement('div');
+    notice.className = 'detection-notice';
+    notice.innerHTML = `
+      <div class="info-message">
+        <i class="fas fa-info-circle"></i>
+        <span>已自动检测到模板中的额外可编辑文本</span>
+      </div>
+    `;
+    editForm.insertBefore(notice, editForm.firstChild);
+  }
+}
+
+// 查找模板中的硬编码文本
+function findHardcodedTexts(html) {
+  const texts = new Set();
+  
+  // 创建一个临时的DOM元素来解析HTML
+  const temp = document.createElement('div');
+  temp.innerHTML = html;
+  
+  // 递归收集文本节点
+  const collectTextNodes = (element) => {
+    Array.from(element.childNodes).forEach(node => {
+      if (node.nodeType === Node.TEXT_NODE) {
+        const text = node.textContent.trim();
+        if (text && !isFontAwesomeClass(text) && !isCssValue(text)) {
+          texts.add(text);
+        }
+      } else if (node.nodeType === Node.ELEMENT_NODE) {
+        collectTextNodes(node);
+      }
+    });
+  };
+  
+  collectTextNodes(temp);
+  return Array.from(texts);
+}
+
+// 检查是否是Font Awesome类名
+function isFontAwesomeClass(text) {
+  return text.startsWith('fa-') || text.startsWith('fas ') || text.startsWith('far ') || text.startsWith('fab ');
+}
+
+// 检查是否是CSS值
+function isCssValue(text) {
+  // CSS单位和值的正则表达式
+  const cssValueRegex = /^-?\d+(\.\d+)?(px|em|rem|%|vh|vw|deg|s|ms)?$/;
+  const colorRegex = /^#[0-9a-f]{3,6}$/i;
+  const rgbaRegex = /^rgba?\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*(?:,\s*[\d.]+\s*)?\)$/;
+  
+  return cssValueRegex.test(text) || colorRegex.test(text) || rgbaRegex.test(text);
+}
+
+// 检查是否是常见文本
+function isCommonText(text) {
+  // 如果文本太短,可能不需要编辑
+  if (text.length < 3) return true;
+  
+  // 常见的不需要编辑的文本
+  const commonTexts = [
+    '选择图片',
+    '上传',
+    '下载',
+    '分享',
+    '编辑',
+    '预览',
+    '确定',
+    '取消'
+  ];
+  
+  return commonTexts.includes(text);
+}
+
+// 更新海报预览
+function updatePosterPreview() {
+  const posterPreview = document.getElementById('poster-preview');
+  if (!posterPreview || !window.currentTemplate) return;
+  
+  // 生成预览HTML
+  const previewHTML = window.currentTemplate.template(window.currentValues);
+  posterPreview.innerHTML = previewHTML;
+}
+
+// 下载海报
+window.downloadPoster = function(format = 'png', quality = 0.9) {
+  const posterPreview = document.getElementById('poster-preview');
+  
+  if (!posterPreview) return;
+  
+  // 临时移除水印(如果有)以便导出时不包含水印
+  const watermark = posterPreview.querySelector('.poster-watermark');
+  let watermarkData = null;
+  
+  if (watermark) {
+    watermarkData = {
+      element: watermark,
+      parent: watermark.parentNode
+    };
+    watermark.remove();
+  }
+  
+  // 使用全局的html2canvas将预览区域转换为图片
+  html2canvas(posterPreview, {
+    scale: 2, // 提高图片质量
+    useCORS: true, // 允许加载跨域图片
+    allowTaint: true,
+    backgroundColor: format === 'png' ? null : 'white'
+  }).then(canvas => {
+    // 根据格式选择导出方式
+    if (format === 'png') {
+      canvas.toBlob(blob => {
+        const templateName = window.currentTemplate ? window.currentTemplate.name : 'poster';
+        // 使用全局的saveAs
+        saveAs(blob, `${templateName}-${Date.now()}.png`);
+      }, 'image/png');
+    } else {
+      canvas.toBlob(blob => {
+        const templateName = window.currentTemplate ? window.currentTemplate.name : 'poster';
+        // 使用全局的saveAs
+        saveAs(blob, `${templateName}-${Date.now()}.jpg`);
+      }, 'image/jpeg', quality);
+    }
+    
+    // 导出完成后恢复水印
+    if (watermarkData) {
+      watermarkData.parent.appendChild(watermarkData.element);
+    }
+  }).catch(error => {
+    console.error('下载海报失败:', error);
+    alert('下载失败,请重试');
+    
+    // 出错时也恢复水印
+    if (watermarkData) {
+      watermarkData.parent.appendChild(watermarkData.element);
+    }
+  });
+}

BIN
apps/poster-maker/webfonts/fa-solid-900.ttf


BIN
apps/poster-maker/webfonts/fa-solid-900.woff2


Неке датотеке нису приказане због велике количине промена