Appearance
常见问题 FAQ
问题解答说明
本 FAQ 基于 JitWord 的实际代码实现和用户反馈整理,涵盖部署、开发、使用等各个方面的常见问题。
🚀 部署相关问题
Q: 如何快速启动 JitWord 开发环境?
A: 按以下步骤启动完整的开发环境:
powershell
# 1. 启动后端服务(端口 3002)
cd server
pnpm install
$env:NODE_ENV="development"; npm run start:win
# 2. 启动前端应用(端口 9999)
cd app
pnpm install
pnpm dev
# 3. 启动文档站点(端口 5173)
cd jitword-doc
pnpm install
pnpm docs:dev
访问地址:
Q: 生产环境如何部署?
A: 推荐使用 PM2 + Nginx 的部署方案:
bash
# 1. 构建前端
cd app && pnpm build
# 2. 构建并启动后端
cd server && pnpm run build:js
$env:NODE_ENV="production"; pm2 start dist/index.js --name jitword-server -i max
# 3. 配置 Nginx 反向代理
# 参考 api.md 中的 Nginx 配置示例
Q: Docker 部署有什么注意事项?
A: Docker 部署的关键配置:
- 多阶段构建:分别构建前端和后端,减少镜像大小
- 数据持久化:挂载
/app/db
和/app/public
目录 - 环境变量:正确配置
NODE_ENV
、JWT_SECRET
等 - 健康检查:配置
/health
端点的健康检查
dockerfile
# 关键配置示例
VOLUME ["/app/db", "/app/public"]
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:3002/health || exit 1
🤝 协作功能问题
Q: 实时协作连接失败怎么办?
A: 按以下步骤排查协作连接问题:
检查 WebSocket 连接:
javascript// 在浏览器控制台检查连接状态 console.log('WebSocket URL:', BASE_WS_URL);
验证防火墙配置:确保 WebSocket 端口(默认 3002)未被阻止
检查代理配置:如果使用 Nginx,确保 WebSocket 升级头配置正确:
nginxproxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade";
验证 JWT Token:确保用户已正确登录且 Token 有效
Q: 多人协作时出现内容冲突怎么办?
A: JitWord 基于 CRDT 算法自动解决冲突,但可以通过以下方式优化:
- 避免同时编辑同一段落:通过协作光标查看其他用户的编辑位置
- 及时保存版本:在重要修改前创建版本快照
- 使用版本对比:如发现异常,可通过版本对比查看变更历史
- 刷新页面重连:极端情况下可刷新页面重新建立协作连接
Q: 协作者光标不显示怎么办?
A: 协作光标显示问题的排查步骤:
- 检查协作连接状态:确保 WebSocket 连接正常
- 验证用户权限:确保用户有文档的编辑权限
- 清除浏览器缓存:清除缓存并重新加载页面
- 检查网络延迟:高延迟网络可能影响光标同步
📚 版本管理问题
Q: 版本历史过多导致性能问题怎么办?
A: 版本管理的性能优化建议:
设置版本上限:
javascript// 在 server/src/router/version.js 中配置 const MAX_VERSIONS_PER_DOC = 1000;
实现版本归档:
javascript// 归档旧版本 async function archiveOldVersions(docId, keepCount = 100) { const versions = await loadVersionList(docId); if (versions.length > keepCount) { const toArchive = versions.slice(0, versions.length - keepCount); await archiveVersions(docId, toArchive); } }
分页加载:前端版本列表使用分页加载,避免一次性加载过多数据
Q: 版本恢复后协作者看不到变化?
A: 版本恢复的正确流程:
- 确认恢复操作:版本恢复会覆盖当前内容,需要用户确认
- 广播更新:恢复操作会自动广播到所有协作者
- 创建恢复点:恢复后建议立即创建新版本作为恢复点
- 通知协作者:通过 SSE 事件通知其他协作者版本恢复操作
Q: 版本对比显示不准确?
A: 版本对比功能的优化建议:
- 检查内容格式:确保版本内容格式一致
- 更新对比算法:使用更精确的文本差异算法
- 处理特殊内容:图表、表格等复杂内容需要特殊处理
- 缓存对比结果:对比结果可以缓存,提升性能
📁 文件处理问题
Q: DOCX 文件导入失败?
A: DOCX 导入问题的排查步骤:
- 检查文件大小:确保文件大小在限制范围内(默认 50MB)
- 验证文件格式:确保是标准的 .docx 格式文件
- 检查文件内容:复杂的 Word 文档可能包含不支持的元素
解决方案:
javascript
// 增强 DOCX 解析错误处理
async function parseDocxWithRetry(filePath, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await parseDocx(filePath);
} catch (error) {
if (i === maxRetries - 1) throw error;
// 等待后重试
await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)));
}
}
}
Q: PDF 解析效果不理想?
A: PDF 解析的优化建议:
- 文本型 PDF:效果最佳,可以完整提取文本和结构
- 图片型 PDF:需要 OCR 识别,可能存在识别错误
- 复杂布局 PDF:多栏布局可能影响文本顺序
改进方案:
javascript
// PDF 解析优化
async function enhancedPdfParse(filePath) {
const result = await parsePdf(filePath);
// 文本清理和格式化
const cleanedText = cleanPdfText(result.text);
// 结构识别
const structure = identifyDocumentStructure(cleanedText);
// 转换为编辑器格式
return convertStructureToEditor(structure);
}
Q: 导出的 Word 文档格式不正确?
A: Word 导出格式问题的解决方案:
- 样式映射:确保编辑器样式正确映射到 Word 样式
- 图片处理:确保图片正确嵌入到 Word 文档
- 表格格式:复杂表格可能需要特殊处理
javascript
// Word 导出优化
export class EnhancedWordExporter {
async export(content, options = {}) {
// 预处理内容
const processedContent = this.preprocessContent(content);
// 生成 Word 文档
const doc = await this.generateWordDocument(processedContent, options);
// 后处理优化
return this.postprocessDocument(doc);
}
preprocessContent(content) {
// 处理图表转图片
// 处理复杂表格
// 处理自定义样式
return processedContent;
}
}
🤖 AI 功能问题
Q: AI 生成内容质量不高?
A: 提升 AI 生成质量的方法:
优化提示词:
javascript// 使用更具体的提示词 const prompt = `请写一份关于${topic}的${documentType},要求: 1. 结构清晰,逻辑严密 2. 内容详实,数据准确 3. 语言专业,表达流畅 4. 长度约${wordCount}字 具体要求:${requirements}`;
调整模型参数:
javascriptconst config = { temperature: 0.7, // 控制创造性(0-1) maxTokens: 2000, // 控制输出长度 topP: 0.9, // 控制词汇多样性 frequencyPenalty: 0.1 // 减少重复内容 };
选择合适模型:
- DeepSeek Chat:适合通用写作和中文内容
- Kimi K2:适合长文档和复杂逻辑
- DeepSeek Reasoner:适合分析和推理类内容
Q: AI 响应速度慢?
A: AI 响应速度优化方案:
启用流式生成:
javascriptconst stream = await aiProvider.generateStream({ prompt: prompt, stream: true // 启用流式输出 });
选择快速模型:使用响应速度更快的模型
优化网络连接:使用国内 AI 服务商或配置代理
缓存常用结果:对常用的生成结果进行缓存
Q: AI 功能无法使用?
A: AI 功能故障排查:
- 检查 API Key:确保 AI 服务商的 API Key 配置正确
- 验证网络连接:确保能够访问 AI 服务商的 API
- 检查配额限制:确认 API 调用次数未超过限制
- 查看错误日志:检查浏览器控制台和服务器日志
javascript
// AI 功能健康检查
async function checkAIHealth() {
const providers = ['deepseek', 'kimi', 'custom'];
const results = {};
for (const provider of providers) {
try {
const response = await testProviderConnection(provider);
results[provider] = { status: 'healthy', latency: response.latency };
} catch (error) {
results[provider] = { status: 'error', error: error.message };
}
}
return results;
}
🔧 开发相关问题
Q: 如何添加自定义扩展组件?
A: 自定义组件开发步骤:
创建组件定义:
javascript// app/src/packages/core/extensions/my-component.js export const MyComponent = Node.create({ name: 'myComponent', addOptions() { return { name: 'myComponent', desc: '我的组件', slash: true }; } });
注册组件:
javascript// app/src/packages/vue3/kit/notion-kit.js import { MyComponent } from '../extensions/my-component'; export default BasicKit.extend({ addExtensions() { return [...this.parent?.(), MyComponent]; } });
添加样式:在相应的 SCSS 文件中添加组件样式
Q: 如何扩展 API 接口?
A: API 扩展开发流程:
创建路由文件:
javascript// server/src/router/my-api.js export default (router, prefix) => { router.get(`${prefix}/my-endpoint`, async (ctx) => { // 业务逻辑 }); };
注册路由:
javascript// server/src/index.js import myApiRouter from './router/my-api.js'; myApiRouter(router, '/api/v1');
前端接口封装:
typescript// app/src/api/my-api.ts export const myApi = { async getData() { return request.get('/my-endpoint'); } };
Q: 如何调试协作功能?
A: 协作功能调试方法:
启用调试日志:
bash$env:DEBUG="jitword:*"; npm run dev
使用多个浏览器窗口:模拟多用户协作场景
监控 WebSocket 连接:
javascript// 在浏览器控制台监控 WebSocket const ws = new WebSocket('ws://localhost:3002/test-doc'); ws.onopen = () => console.log('WebSocket 连接成功'); ws.onmessage = (event) => console.log('收到消息:', event.data); ws.onerror = (error) => console.error('WebSocket 错误:', error);
检查协作状态:使用 SSE 监控协作状态变化
🔐 安全相关问题
Q: 如何配置 JWT 认证?
A: JWT 认证配置步骤:
设置 JWT 密钥:
bash# 生产环境使用强密钥 $env:JWT_SECRET="your-super-secret-jwt-key-here"
配置 Token 过期时间:
javascript// server/src/service/index.js const token = jwt.sign(payload, secret, { expiresIn: '24h' // 24小时过期 });
前端 Token 管理:
javascript// 自动刷新 Token axios.interceptors.response.use( response => response, async error => { if (error.response?.status === 401) { await refreshToken(); return axios.request(error.config); } return Promise.reject(error); } );
Q: 如何实现权限控制?
A: 权限控制实现方案:
基于角色的权限控制(RBAC):
javascriptconst roles = { admin: ['read', 'write', 'delete', 'manage'], editor: ['read', 'write'], viewer: ['read'] }; function checkPermission(userRole, action) { return roles[userRole]?.includes(action) || false; }
文档级权限控制:
javascript// 检查文档权限 async function checkDocumentPermission(userId, docId, action) { const permission = await getDocumentPermission(userId, docId); return permission.includes(action); }
API 权限中间件:
javascriptconst requirePermission = (action) => async (ctx, next) => { const hasPermission = await checkPermission(ctx.state.user, action); if (!hasPermission) { ctx.status = 403; ctx.body = { error: '权限不足' }; return; } await next(); };
📊 性能相关问题
Q: 大文档编辑卡顿怎么办?
A: 大文档性能优化方案:
启用虚拟滚动:
javascript// 长文档虚拟滚动 const VirtualEditor = { setup() { const visibleRange = ref({ start: 0, end: 100 }); // 只渲染可见区域的内容 const visibleContent = computed(() => { return content.value.slice( visibleRange.value.start, visibleRange.value.end ); }); return { visibleContent }; } };
分段加载:将大文档分段加载和渲染
优化渲染:
javascript// 防抖渲染更新 const debouncedRender = debounce(() => { updateEditorContent(); }, 100);
Q: 协作延迟过高?
A: 协作延迟优化方案:
- 检查网络延迟:使用 ping 测试网络延迟
- 优化服务器性能:增加服务器资源或使用更快的服务器
- 启用压缩:对 WebSocket 消息进行压缩
- 减少操作频率:合并频繁的小操作
javascript
// 操作合并优化
class OperationBatcher {
constructor(flushInterval = 50) {
this.operations = [];
this.timer = null;
this.flushInterval = flushInterval;
}
addOperation(operation) {
this.operations.push(operation);
if (!this.timer) {
this.timer = setTimeout(() => {
this.flush();
}, this.flushInterval);
}
}
flush() {
if (this.operations.length > 0) {
const batchedOp = this.mergeOperations(this.operations);
this.sendOperation(batchedOp);
this.operations = [];
}
this.timer = null;
}
}
🔧 配置相关问题
Q: 环境变量配置不生效?
A: 环境变量配置检查:
Windows PowerShell 语法:
powershell# 正确的环境变量设置 $env:NODE_ENV="development" $env:BASE_WS_URL="ws://localhost:3002"
验证环境变量:
javascript// 在代码中验证环境变量 console.log('NODE_ENV:', process.env.NODE_ENV); console.log('BASE_WS_URL:', process.env.BASE_WS_URL);
配置文件优先级:
- 环境变量 > .env 文件 > 默认配置
Q: 静态资源访问 404?
A: 静态资源配置检查:
检查静态目录配置:
javascript// server/src/config/index.js export default { staticDir: path.resolve(__dirname, '../public'), uploadDir: path.resolve(__dirname, '../public/uploads') };
验证文件路径:确保文件确实存在于配置的目录中
检查 Nginx 配置:
nginx# 静态资源配置 location /uploads/ { alias /app/public/uploads/; expires 1y; }
🐛 常见错误解决
端口占用错误
错误信息:Error: listen EADDRINUSE: address already in use :::3002
解决方案:
powershell
# 查找占用端口的进程
netstat -ano | findstr :3002
# 结束占用进程
taskkill /PID <进程ID> /F
# 或者修改端口配置
$env:PORT="3003"; npm run dev
依赖安装失败
错误信息:npm ERR! peer dep missing
解决方案:
powershell
# 清除缓存
npm cache clean --force
# 删除 node_modules 重新安装
Remove-Item -Recurse -Force node_modules
Remove-Item package-lock.json
npm install
# 或使用 pnpm
pnpm install --frozen-lockfile
WebSocket 连接被拒绝
错误信息:WebSocket connection failed
解决方案:
- 检查防火墙设置:确保 WebSocket 端口未被阻止
- 验证代理配置:检查 Nginx 或其他代理的 WebSocket 配置
- 检查 CORS 设置:确保跨域配置正确
javascript
// CORS 配置示例
app.use(cors({
origin: ['http://localhost:9999', 'https://your-domain.com'],
credentials: true,
allowMethods: ['GET', 'POST', 'PUT', 'DELETE'],
allowHeaders: ['Content-Type', 'Authorization']
}));
📈 监控与运维问题
Q: 如何监控系统运行状态?
A: 系统监控配置:
健康检查端点:
javascript// server/src/router/health.js router.get('/health', async (ctx) => { const health = { status: 'healthy', timestamp: new Date().toISOString(), uptime: process.uptime(), memory: process.memoryUsage(), connections: getActiveConnections(), version: packageJson.version }; ctx.body = health; });
性能指标收集:
javascript// 性能监控中间件 app.use(async (ctx, next) => { const start = Date.now(); await next(); const duration = Date.now() - start; // 记录性能指标 recordMetric('api_response_time', { path: ctx.path, method: ctx.method, duration: duration, status: ctx.status }); });
日志配置:
javascript// 结构化日志 const logger = { info: (message, metadata = {}) => { console.log(JSON.stringify({ level: 'info', message: message, timestamp: new Date().toISOString(), ...metadata })); } };
Q: 如何处理内存泄漏?
A: 内存泄漏预防和处理:
WebSocket 连接清理:
javascript// 定期清理无效连接 setInterval(() => { cleanupInactiveConnections(); }, 60000); // 每分钟清理一次
缓存大小限制:
javascript// LRU 缓存配置 const cache = new LRUCache({ max: 1000, // 最大条目数 maxAge: 3600000 // 1小时过期 });
内存监控:
javascript// 内存使用监控 setInterval(() => { const usage = process.memoryUsage(); if (usage.heapUsed > 1024 * 1024 * 1024) { // 1GB console.warn('内存使用过高:', usage); // 触发垃圾回收或重启 } }, 30000);
🔄 数据迁移问题
Q: 如何迁移现有文档数据?
A: 数据迁移方案:
批量导入工具:
javascript// 批量导入脚本 async function batchImportDocuments(sourceDir) { const files = fs.readdirSync(sourceDir); for (const file of files) { if (file.endsWith('.docx')) { const content = await parseDocx(path.join(sourceDir, file)); await createDocument({ title: path.basename(file, '.docx'), content: content }); } } }
数据格式转换:
javascript// 旧格式转新格式 function convertLegacyFormat(oldData) { return { type: 'doc', content: convertOldContent(oldData.content), metadata: { version: '2.0', migrated: true, originalFormat: oldData.format } }; }
增量迁移:支持分批次迁移,避免系统压力过大
Q: 版本数据如何备份和恢复?
A: 数据备份恢复方案:
自动备份脚本:
bash#!/bin/bash # backup.sh DATE=$(date +%Y%m%d_%H%M%S) BACKUP_DIR="/backup/jitword_$DATE" mkdir -p $BACKUP_DIR cp -r server/db $BACKUP_DIR/ cp -r server/public $BACKUP_DIR/ # 压缩备份 tar -czf "$BACKUP_DIR.tar.gz" $BACKUP_DIR rm -rf $BACKUP_DIR
数据恢复:
bash# restore.sh BACKUP_FILE=$1 # 停止服务 pm2 stop jitword-server # 恢复数据 tar -xzf $BACKUP_FILE cp -r backup_*/db server/ cp -r backup_*/public server/ # 重启服务 pm2 start jitword-server
📱 移动端问题
Q: 移动端编辑体验不佳?
A: 移动端优化建议:
触屏优化:
css/* 移动端样式优化 */ @media (max-width: 768px) { .editor-container { padding: 10px; font-size: 16px; /* 防止缩放 */ } .toolbar { position: sticky; top: 0; z-index: 100; } }
虚拟键盘适配:
javascript// 虚拟键盘显示时调整布局 window.addEventListener('resize', () => { const viewport = window.visualViewport; if (viewport) { document.documentElement.style.height = `${viewport.height}px`; } });
手势支持:添加滑动、双击等手势操作支持
🔍 故障排查工具
系统诊断脚本
javascript
// 系统诊断工具
export class SystemDiagnostics {
async runDiagnostics() {
const results = {
system: await this.checkSystemHealth(),
database: await this.checkDatabaseHealth(),
websocket: await this.checkWebSocketHealth(),
ai: await this.checkAIHealth(),
storage: await this.checkStorageHealth()
};
return {
overall: this.calculateOverallHealth(results),
details: results,
recommendations: this.generateRecommendations(results)
};
}
async checkSystemHealth() {
return {
uptime: process.uptime(),
memory: process.memoryUsage(),
cpu: await this.getCPUUsage(),
nodeVersion: process.version,
platform: process.platform
};
}
async checkWebSocketHealth() {
const activeConnections = getActiveWebSocketConnections();
return {
activeConnections: activeConnections.length,
totalConnections: getTotalConnections(),
averageLatency: calculateAverageLatency(),
errorRate: calculateWebSocketErrorRate()
};
}
}
日志分析工具
javascript
// 日志分析工具
export class LogAnalyzer {
analyzeErrorLogs(logs) {
const errors = logs.filter(log => log.level === 'error');
return {
totalErrors: errors.length,
errorsByType: this.groupErrorsByType(errors),
errorsByTime: this.groupErrorsByTime(errors),
topErrors: this.getTopErrors(errors),
errorTrends: this.calculateErrorTrends(errors)
};
}
generateHealthReport(logs) {
const report = {
period: this.getLogPeriod(logs),
summary: {
totalRequests: logs.filter(log => log.module === 'api').length,
errorRate: this.calculateErrorRate(logs),
averageResponseTime: this.calculateAverageResponseTime(logs),
peakConcurrency: this.calculatePeakConcurrency(logs)
},
recommendations: this.generateOptimizationRecommendations(logs)
};
return report;
}
}
📞 技术支持与授权
🎯 源码授权说明
JitWord 提供源码永久授权,具有以下特点:
- ✅ 源码永久授权:一次购买,永久使用,无时间限制
- ✅ 可二次开发:完全开放源码,支持企业定制化开发
- ✅ 可商业使用:支持企业内部使用和对外商业化部署
- ❌ 源码不可二次分发:不得将源码再次销售或分发给第三方
- ✅ 技术支持:提供完整的技术文档和开发指导
📋 授权范围
授权内容 | 说明 | 限制 |
---|---|---|
源码使用 | 完整源码,包含前端和后端 | 不可二次分发 |
商业部署 | 支持企业内部和对外商业化部署 | 需标注原始版权 |
二次开发 | 支持基于源码的定制化开发 | 衍生作品需遵循授权协议 |
技术支持 | 提供技术文档和开发指导 | 不包含 7x24 小时响应 |
🛠️ 获取帮助的方式
- 技术文档:完整的开发文档和 API 说明
- 源码注释:详细的代码注释和开发说明
- 技术微信:cxzk_168(工作时间响应)
- 企业咨询:cxzk_168(微信)
📝 问题反馈模板
markdown
## 问题描述
[详细描述遇到的问题]
## 复现步骤
1. [步骤1]
2. [步骤2]
3. [步骤3]
## 期望结果
[描述期望的正确行为]
## 实际结果
[描述实际发生的情况]
## 环境信息
- 操作系统:[Windows/Linux/macOS]
- 浏览器:[Chrome/Firefox/Safari + 版本]
- Node.js 版本:[版本号]
- JitWord 版本:[版本号]
## 错误日志
[粘贴相关的错误日志]
## 授权信息
- 授权类型:[源码授权/试用版]
- 购买时间:[YYYY-MM-DD]
🚀 企业服务
源码交付服务
- 完整源码包:包含前端、后端、文档的完整源码
- 部署指导:提供详细的部署文档和配置说明
- 开发培训:可选的技术培训和开发指导服务
- 定制开发:交付源码基础上,提供付费的企业定制化开发服务
技术支持级别
- 基础支持:技术文档、邮件咨询(工作时间响应)
- 标准支持:微信技术群、远程协助(工作日响应)
- 企业支持:专属技术顾问、定制开发支持(需单独商议)
⚖️ 法律声明
- 版权保护:JitWord 源码受版权法保护,购买授权后可合法使用
- 使用限制:禁止将源码进行二次销售、分发或开源
- 免责声明:软件按"现状"提供,不承担因使用软件造成的任何损失
- 争议解决:如有争议,以购买时的授权协议为准
持续改进
我们会根据用户反馈持续更新 FAQ 内容,如果您遇到的问题不在此列表中,欢迎联系我们补充。
最后更新时间:2025年9月