V1.2.0需求完成测试版
This commit is contained in:
parent
4e764d2d17
commit
bc0cd959f0
|
@ -0,0 +1,244 @@
|
|||
# CKEditor 4 集成说明
|
||||
|
||||
## 📋 功能概述
|
||||
|
||||
`editorDocument.vue` 页面已集成 CKEditor 4 富文本编辑器,具备以下功能:
|
||||
|
||||
- ✅ **富文本编辑** - 完整的文本格式化功能
|
||||
- ✅ **发布功能** - 一键发布文档到后端
|
||||
- ✅ **预览功能** - 实时预览文档效果
|
||||
- ✅ **使用指南** - 详细的操作说明
|
||||
- ✅ **自动保存草稿** - 30秒自动保存到本地存储
|
||||
|
||||
## 🚀 快速开始
|
||||
|
||||
### 1. 引入 CKEditor 4
|
||||
|
||||
在 `public/index.html` 中添加 CKEditor 4 的 CDN 引入:
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<!-- 其他标签 -->
|
||||
|
||||
<!-- CKEditor 4 引入 -->
|
||||
<script src="https://cdn.ckeditor.com/4.16.2/standard/ckeditor.js"></script>
|
||||
|
||||
<!-- 中文语言包 -->
|
||||
<script src="https://cdn.ckeditor.com/4.16.2/standard/lang/zh-cn.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<!-- 页面内容 -->
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
### 2. 路由配置
|
||||
|
||||
在 `src/router/index.js` 中添加路由:
|
||||
|
||||
```javascript
|
||||
import Vue from 'vue'
|
||||
import Router from 'vue-router'
|
||||
|
||||
// 引入编辑器页面
|
||||
import EditorDocument from '@/views/editorDocument.vue'
|
||||
|
||||
export default new Router({
|
||||
routes: [
|
||||
// 其他路由...
|
||||
{
|
||||
path: '/editor',
|
||||
name: 'EditorDocument',
|
||||
component: EditorDocument,
|
||||
meta: {
|
||||
title: 'CKEditor 文档编辑器'
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
```
|
||||
|
||||
### 3. 访问页面
|
||||
|
||||
访问 `/editor` 路径即可使用 CKEditor 4 编辑器。
|
||||
|
||||
## 🛠️ 功能详解
|
||||
|
||||
### 编辑器配置
|
||||
|
||||
```javascript
|
||||
editorConfig: {
|
||||
height: 400, // 编辑器高度
|
||||
language: 'zh-cn', // 中文界面
|
||||
toolbar: [ // 工具栏配置
|
||||
{ name: 'document', items: ['Source', '-', 'Save', 'NewPage', 'Preview', 'Print', '-', 'Templates'] },
|
||||
{ name: 'clipboard', items: ['Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord', '-', 'Undo', 'Redo'] },
|
||||
{ name: 'editing', items: ['Find', 'Replace', '-', 'SelectAll', '-', 'SpellChecker', 'Scayt'] },
|
||||
'/',
|
||||
{ name: 'basicstyles', items: ['Bold', 'Italic', 'Underline', 'Strike', 'Subscript', 'Superscript', '-', 'RemoveFormat'] },
|
||||
{ name: 'paragraph', items: ['NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', '-', 'Blockquote', 'CreateDiv', '-', 'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock', '-', 'BidiLtr', 'BidiRtl'] },
|
||||
{ name: 'links', items: ['Link', 'Unlink', 'Anchor'] },
|
||||
{ name: 'insert', items: ['Image', 'Flash', 'Table', 'HorizontalRule', 'Smiley', 'SpecialChar', 'PageBreak', 'Iframe'] },
|
||||
'/',
|
||||
{ name: 'styles', items: ['Styles', 'Format', 'Font', 'FontSize'] },
|
||||
{ name: 'colors', items: ['TextColor', 'BGColor'] },
|
||||
{ name: 'tools', items: ['Maximize', 'ShowBlocks'] }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 自动保存功能
|
||||
|
||||
- **自动保存间隔**: 30秒
|
||||
- **保存位置**: 浏览器本地存储 (localStorage)
|
||||
- **保存内容**: 标题、内容、类型、时间戳
|
||||
- **状态显示**: 实时显示保存状态
|
||||
|
||||
```javascript
|
||||
// 自动保存逻辑
|
||||
autoSave() {
|
||||
if (!this.documentForm.content || this.documentForm.content === this.lastSavedContent) {
|
||||
return
|
||||
}
|
||||
|
||||
const draftData = {
|
||||
title: this.documentForm.title,
|
||||
content: this.documentForm.content,
|
||||
type: this.documentForm.type,
|
||||
timestamp: new Date().toISOString()
|
||||
}
|
||||
|
||||
localStorage.setItem('ckeditor_draft', JSON.stringify(draftData))
|
||||
this.lastSavedContent = this.documentForm.content
|
||||
}
|
||||
```
|
||||
|
||||
### 发布功能
|
||||
|
||||
集成后端 `addDocument` API,支持:
|
||||
|
||||
- 文档标题验证
|
||||
- 文档类型选择
|
||||
- 内容获取和传输
|
||||
- 发布状态反馈
|
||||
- 成功后清空本地草稿
|
||||
|
||||
## 🎨 样式特性
|
||||
|
||||
### 统一内容显示
|
||||
|
||||
使用 `.content-display` 类确保预览和最终显示一致:
|
||||
|
||||
```css
|
||||
.content-display {
|
||||
white-space: pre-wrap !important; /* 保持空格和换行 */
|
||||
word-wrap: break-word !important; /* 防止长单词溢出 */
|
||||
word-break: break-word !important; /* 长单词换行 */
|
||||
|
||||
/* 列表样式优化 */
|
||||
:deep(ul), :deep(ol) {
|
||||
padding-left: 0 !important;
|
||||
list-style-position: inside !important; /* 圆点紧靠文字 */
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 响应式设计
|
||||
|
||||
- 移动端适配
|
||||
- 工具栏自适应
|
||||
- 快捷键说明
|
||||
|
||||
## 📱 使用指南
|
||||
|
||||
### 基本操作
|
||||
|
||||
1. **创建文档**: 输入标题和选择类型
|
||||
2. **编辑内容**: 使用CKEditor工具栏进行格式化
|
||||
3. **预览效果**: 点击"预览文档"查看最终效果
|
||||
4. **保存草稿**: 点击"保存草稿"或等待自动保存
|
||||
5. **发布文档**: 点击"发布文档"正式发布
|
||||
|
||||
### 快捷键
|
||||
|
||||
- `Ctrl + B` - 粗体
|
||||
- `Ctrl + I` - 斜体
|
||||
- `Ctrl + U` - 下划线
|
||||
- `Ctrl + K` - 插入链接
|
||||
- `Ctrl + Z` - 撤销
|
||||
- `Ctrl + Y` - 重做
|
||||
|
||||
### 工具栏功能
|
||||
|
||||
- **文字格式**: 粗体、斜体、下划线、删除线
|
||||
- **颜色设置**: 字体颜色、背景颜色
|
||||
- **对齐方式**: 左对齐、居中、右对齐、两端对齐
|
||||
- **列表功能**: 有序列表、无序列表
|
||||
- **插入功能**: 链接、图片、表格
|
||||
- **视图功能**: 源码查看、全屏编辑
|
||||
|
||||
## 🔧 自定义配置
|
||||
|
||||
### 修改工具栏
|
||||
|
||||
```javascript
|
||||
toolbar: [
|
||||
// 自定义工具栏按钮
|
||||
{ name: 'basicstyles', items: ['Bold', 'Italic', 'Underline'] },
|
||||
{ name: 'paragraph', items: ['NumberedList', 'BulletedList'] },
|
||||
{ name: 'links', items: ['Link', 'Unlink'] }
|
||||
]
|
||||
```
|
||||
|
||||
### 修改自动保存间隔
|
||||
|
||||
```javascript
|
||||
startAutoSave() {
|
||||
this.autoSaveTimer = setInterval(() => {
|
||||
this.autoSave()
|
||||
}, 60000) // 改为60秒
|
||||
}
|
||||
```
|
||||
|
||||
### 添加自定义插件
|
||||
|
||||
```javascript
|
||||
editorConfig: {
|
||||
extraPlugins: 'your-custom-plugin',
|
||||
// 其他配置...
|
||||
}
|
||||
```
|
||||
|
||||
## 🐛 常见问题
|
||||
|
||||
### Q: CKEditor 未加载?
|
||||
A: 确保在 `index.html` 中正确引入了 CKEditor 的 CDN 脚本。
|
||||
|
||||
### Q: 中文界面不显示?
|
||||
A: 确保引入了中文语言包 `zh-cn.js`。
|
||||
|
||||
### Q: 自动保存不工作?
|
||||
A: 检查浏览器是否支持 localStorage,以及是否有足够权限。
|
||||
|
||||
### Q: 预览样式不一致?
|
||||
A: 确保使用了 `.content-display` 样式类,并检查CSS优先级。
|
||||
|
||||
## 📚 相关资源
|
||||
|
||||
- [CKEditor 4 官方文档](https://ckeditor.com/docs/ckeditor4/)
|
||||
- [CKEditor 4 API 文档](https://ckeditor.com/docs/ckeditor4/latest/api/)
|
||||
- [CKEditor 4 配置指南](https://ckeditor.com/docs/ckeditor4/latest/guide/dev_configuration.html)
|
||||
|
||||
## 🎯 总结
|
||||
|
||||
CKEditor 4 编辑器已成功集成到项目中,提供了完整的富文本编辑体验:
|
||||
|
||||
- ✅ 功能完整:包含所有常用编辑功能
|
||||
- ✅ 用户体验:自动保存、实时预览、使用指南
|
||||
- ✅ 数据一致:编辑器、预览、发布内容完全一致
|
||||
- ✅ 响应式设计:支持各种设备访问
|
||||
- ✅ 易于维护:清晰的代码结构和配置
|
||||
|
||||
现在您可以开始使用这个强大的富文本编辑器来创建和管理文档了!🎉
|
|
@ -0,0 +1,198 @@
|
|||
# CKEditor 4 npm安装和使用指南
|
||||
|
||||
## 安装完成 ✅
|
||||
|
||||
CKEditor 4 已成功通过npm安装到项目中:
|
||||
|
||||
```bash
|
||||
npm install ckeditor4
|
||||
```
|
||||
|
||||
## 安装信息
|
||||
|
||||
- **包名**: ckeditor4
|
||||
- **版本**: 4.25.1
|
||||
- **安装位置**: `node_modules/ckeditor4/`
|
||||
- **依赖状态**: 已添加到 `package.json` 的 dependencies 中
|
||||
|
||||
## 配置说明
|
||||
|
||||
### 1. 全局引入
|
||||
|
||||
在 `src/main.js` 中添加了全局引入:
|
||||
|
||||
```javascript
|
||||
// 引入CKEditor 4
|
||||
import 'ckeditor4'
|
||||
```
|
||||
|
||||
### 2. 编辑器组件
|
||||
|
||||
编辑器组件位于:`src/views/editorDocument.vue`
|
||||
|
||||
主要功能:
|
||||
- ✅ 富文本编辑
|
||||
- ✅ 自动保存草稿
|
||||
- ✅ 实时预览
|
||||
- ✅ 发布功能
|
||||
- ✅ 错误处理
|
||||
- ✅ 加载状态显示
|
||||
|
||||
### 3. 路由配置
|
||||
|
||||
编辑器页面路由已配置:
|
||||
- **路径**: `/editorDocument`
|
||||
- **组件**: `EditorDocument`
|
||||
- **权限**: `all` (所有用户可访问)
|
||||
|
||||
## 使用方法
|
||||
|
||||
### 访问编辑器
|
||||
|
||||
1. 启动开发服务器:
|
||||
```bash
|
||||
npm run serve
|
||||
```
|
||||
|
||||
2. 访问编辑器页面:
|
||||
```
|
||||
http://localhost:8080/editorDocument
|
||||
```
|
||||
|
||||
### 编辑器功能
|
||||
|
||||
1. **基本编辑**
|
||||
- 文字格式化(粗体、斜体、下划线)
|
||||
- 字体颜色和背景色
|
||||
- 文本对齐
|
||||
- 列表(有序/无序)
|
||||
- 链接和图片插入
|
||||
|
||||
2. **文档管理**
|
||||
- 自动保存(每30秒)
|
||||
- 草稿恢复
|
||||
- 手动保存
|
||||
- 发布文档
|
||||
|
||||
3. **预览功能**
|
||||
- 实时预览
|
||||
- 弹窗预览
|
||||
|
||||
## 故障排除
|
||||
|
||||
### 常见问题
|
||||
|
||||
1. **编辑器不显示**
|
||||
- 检查控制台是否有错误信息
|
||||
- 确认 `ckeditor4` 包已正确安装
|
||||
- 检查网络连接
|
||||
|
||||
2. **工具栏不完整**
|
||||
- 检查编辑器配置中的 `toolbar` 设置
|
||||
- 确认所有需要的插件都已加载
|
||||
|
||||
3. **中文显示问题**
|
||||
- 确认语言包已正确加载
|
||||
- 检查 `language` 配置项
|
||||
|
||||
### 调试方法
|
||||
|
||||
1. **查看控制台**
|
||||
```javascript
|
||||
console.log('CKEditor状态:', typeof window.CKEDITOR)
|
||||
```
|
||||
|
||||
2. **检查编辑器实例**
|
||||
```javascript
|
||||
console.log('编辑器实例:', this.editorInstance)
|
||||
```
|
||||
|
||||
3. **测试编辑器功能**
|
||||
- 点击"插入测试内容"按钮
|
||||
- 尝试各种编辑功能
|
||||
- 检查自动保存是否工作
|
||||
|
||||
## 配置选项
|
||||
|
||||
### 编辑器配置
|
||||
|
||||
```javascript
|
||||
editorConfig: {
|
||||
height: 400,
|
||||
language: 'zh-cn',
|
||||
toolbar: [
|
||||
// 工具栏配置
|
||||
],
|
||||
removeButtons: '',
|
||||
format_tags: 'p;h1;h2;h3;pre',
|
||||
removeDialogTabs: 'image:advanced;link:advanced'
|
||||
}
|
||||
```
|
||||
|
||||
### 自定义配置
|
||||
|
||||
可以根据需要修改以下配置:
|
||||
|
||||
1. **工具栏按钮**
|
||||
- 添加/删除工具栏按钮
|
||||
- 自定义按钮分组
|
||||
|
||||
2. **编辑器高度**
|
||||
- 修改 `height` 属性
|
||||
|
||||
3. **语言设置**
|
||||
- 修改 `language` 属性
|
||||
|
||||
4. **内容样式**
|
||||
- 修改 `contentsCss` 属性
|
||||
|
||||
## 生产环境部署
|
||||
|
||||
### 构建项目
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
||||
### 注意事项
|
||||
|
||||
1. **文件大小**
|
||||
- CKEditor会增加构建包的大小
|
||||
- 考虑使用CDN版本以减少包大小
|
||||
|
||||
2. **性能优化**
|
||||
- 可以按需加载编辑器
|
||||
- 考虑使用懒加载
|
||||
|
||||
3. **兼容性**
|
||||
- 确保目标浏览器支持CKEditor 4
|
||||
- 测试各种设备和浏览器
|
||||
|
||||
## 更新和维护
|
||||
|
||||
### 更新CKEditor
|
||||
|
||||
```bash
|
||||
npm update ckeditor4
|
||||
```
|
||||
|
||||
### 版本兼容性
|
||||
|
||||
- 当前版本:4.25.1
|
||||
- 支持Vue 2.x
|
||||
- 支持现代浏览器
|
||||
|
||||
## 技术支持
|
||||
|
||||
如果遇到问题,可以:
|
||||
|
||||
1. 查看CKEditor官方文档
|
||||
2. 检查项目控制台错误信息
|
||||
3. 查看网络请求状态
|
||||
4. 测试编辑器基本功能
|
||||
|
||||
---
|
||||
|
||||
**安装完成时间**: 2024年
|
||||
**安装方式**: npm
|
||||
**状态**: ✅ 正常
|
|
@ -0,0 +1,321 @@
|
|||
# 分屏编辑器使用说明
|
||||
|
||||
## 📌 概述
|
||||
|
||||
分屏编辑器是一个支持实时预览的富文本编辑器组件,完美解决了您需要边编辑边查看效果的需求。支持三种显示模式:编辑、预览、分屏。
|
||||
|
||||
## 🚀 快速开始
|
||||
|
||||
### 1. 访问演示页面
|
||||
|
||||
在浏览器中访问:`http://localhost:8080/zh/splitEditorDemo` (假设您的项目运行在8080端口)
|
||||
|
||||
### 2. 三种显示模式
|
||||
|
||||
#### 📝 编辑模式
|
||||
- 只显示编辑器,专注于内容编写
|
||||
- 点击工具栏中的"编辑"按钮激活
|
||||
|
||||
#### 👀 预览模式
|
||||
- 只显示预览效果,方便查看最终结果
|
||||
- 点击工具栏中的"预览"按钮激活
|
||||
|
||||
#### 🔀 分屏模式(推荐)
|
||||
- **左边编辑,右边实时预览**
|
||||
- 所见即所得,完美解决圆点在预览时才显示的问题
|
||||
- 点击工具栏中的"分屏"按钮激活
|
||||
|
||||
## ✨ 圆点功能使用
|
||||
|
||||
### 方法一:使用专用按钮
|
||||
1. 在分屏模式下,点击编辑器面板头部的"插入圆点"按钮
|
||||
2. 或者在富文本编辑器的工具栏中找到"• 圆点"按钮
|
||||
3. 圆点将自动插入到光标位置
|
||||
|
||||
### 方法二:直接输入
|
||||
在编辑器中直接输入:`• 您的内容`
|
||||
|
||||
### 方法三:列表功能
|
||||
使用编辑器的无序列表功能,会自动生成带圆点的列表
|
||||
|
||||
## 🎯 圆点列表示例
|
||||
|
||||
```
|
||||
• ALEO矿工必须质押一定数量的ALEO代币
|
||||
• 否则将无法提交PoW工作量证明(即算力)
|
||||
• 质押金额直接影响挖矿收益
|
||||
```
|
||||
|
||||
## 📋 组件使用方法
|
||||
|
||||
### 在Vue页面中使用
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div>
|
||||
<!-- 使用分屏编辑器组件 -->
|
||||
<SplitScreenEditor
|
||||
ref="splitEditor"
|
||||
v-model="content"
|
||||
:height="500"
|
||||
:options="editorOptions"
|
||||
@change="handleContentChange"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SplitScreenEditor from '@/components/SplitScreenEditor.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
SplitScreenEditor
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
content: '',
|
||||
editorOptions: {
|
||||
height: 500,
|
||||
// 其他TinyMCE配置选项
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleContentChange(content) {
|
||||
console.log('内容变化:', content);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
### 组件属性
|
||||
|
||||
| 属性 | 类型 | 默认值 | 说明 |
|
||||
|------|------|--------|------|
|
||||
| `value` | String | '' | 编辑器内容(支持v-model) |
|
||||
| `height` | String/Number | 500 | 编辑器高度 |
|
||||
| `options` | Object | {} | TinyMCE配置选项 |
|
||||
|
||||
### 组件事件
|
||||
|
||||
| 事件 | 参数 | 说明 |
|
||||
|------|------|------|
|
||||
| `input` | content | 内容变化时触发(v-model) |
|
||||
| `change` | content | 内容变化时触发 |
|
||||
| `publish` | publishResult | 发布操作完成时触发,包含发布结果 |
|
||||
|
||||
#### publish 事件参数详解
|
||||
|
||||
**发布成功时:**
|
||||
```javascript
|
||||
{
|
||||
success: true,
|
||||
documentId: 123, // 后端返回的文档ID
|
||||
title: "文档标题",
|
||||
content: "文档内容",
|
||||
wordCount: 1250,
|
||||
timestamp: "2024-01-01T12:00:00Z",
|
||||
response: { /* 后端完整响应数据 */ }
|
||||
}
|
||||
```
|
||||
|
||||
**发布失败时:**
|
||||
```javascript
|
||||
{
|
||||
success: false,
|
||||
error: "错误信息",
|
||||
title: "文档标题",
|
||||
content: "文档内容"
|
||||
}
|
||||
```
|
||||
|
||||
### 组件方法
|
||||
|
||||
| 方法 | 参数 | 说明 |
|
||||
|------|------|------|
|
||||
| `getContent()` | - | 获取编辑器内容 |
|
||||
| `setContent(content)` | content | 设置编辑器内容 |
|
||||
| `clear()` | - | 清空编辑器内容 |
|
||||
|
||||
## 🛠️ 高级功能
|
||||
|
||||
### 全屏编辑
|
||||
- 点击"全屏"按钮进入全屏编辑模式
|
||||
- 按ESC键退出全屏
|
||||
|
||||
### 字数统计
|
||||
- 实时显示当前内容的字符数量
|
||||
- 自动排除HTML标签
|
||||
|
||||
### 复制HTML
|
||||
- 在预览区域点击"复制HTML"按钮
|
||||
- 将生成的HTML代码复制到剪贴板
|
||||
|
||||
### 使用指南
|
||||
- 点击工具栏中的"使用指南"按钮
|
||||
- 展开详细的TinyMCE功能说明
|
||||
- 包含快捷键、操作步骤、专用功能介绍
|
||||
- 支持展开/收起切换
|
||||
|
||||
### 发布功能
|
||||
- 点击工具栏中的"发布"按钮
|
||||
- 自动验证内容是否为空
|
||||
- **两步式发布流程**:
|
||||
1. 输入文档标题(自动生成默认标题)
|
||||
2. 选择文档类型(其他、服务条款、API文档、挖矿教程)
|
||||
- **直接调用后端接口**:使用 `addDocument` API 发布到文档管理系统
|
||||
- **完整的状态反馈**:发布中状态、成功通知、错误处理
|
||||
- **自动清理**:发布成功后自动清空本地草稿
|
||||
- **事件回调**:触发 `publish` 事件,返回发布结果和文档ID
|
||||
|
||||
### 自动保存
|
||||
- 演示页面包含2秒防抖的自动保存功能
|
||||
- 自动保存到浏览器本地存储
|
||||
- 页面刷新后自动恢复草稿
|
||||
|
||||
## 🎨 自定义样式
|
||||
|
||||
### 编辑器样式
|
||||
可以通过`options.content_style`自定义编辑器内容区域的样式:
|
||||
|
||||
```javascript
|
||||
editorOptions: {
|
||||
content_style: `
|
||||
body {
|
||||
font-family: 'Arial', sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
ul, ol {
|
||||
padding-left: 24px;
|
||||
}
|
||||
li {
|
||||
margin: 6px 0;
|
||||
}
|
||||
`
|
||||
}
|
||||
```
|
||||
|
||||
### 预览区域样式
|
||||
预览区域的样式已经过优化,确保与编辑器样式保持一致。
|
||||
|
||||
## 🔧 配置选项
|
||||
|
||||
### 推荐的TinyMCE配置
|
||||
|
||||
```javascript
|
||||
editorOptions: {
|
||||
height: 500,
|
||||
menubar: false,
|
||||
plugins: [
|
||||
'advlist', 'autolink', 'lists', 'link', 'image', 'charmap',
|
||||
'preview', 'anchor', 'searchreplace', 'visualblocks', 'code',
|
||||
'fullscreen', 'insertdatetime', 'media', 'table', 'help', 'wordcount'
|
||||
],
|
||||
toolbar: [
|
||||
'undo redo | formatselect | bold italic underline strikethrough',
|
||||
'forecolor backcolor | alignleft aligncenter alignright alignjustify',
|
||||
'bullist numlist outdent indent | link image table',
|
||||
'code preview fullscreen | removeformat help'
|
||||
].join(' | '),
|
||||
language: 'zh_CN',
|
||||
branding: false,
|
||||
resize: false
|
||||
}
|
||||
```
|
||||
|
||||
## 📱 响应式支持
|
||||
|
||||
组件完全支持响应式设计:
|
||||
- 移动设备上工具栏自动调整布局
|
||||
- 分屏模式在小屏幕上自动变为垂直布局
|
||||
- 字体大小和间距自动适配
|
||||
|
||||
## 🐛 常见问题
|
||||
|
||||
### Q: 圆点在编辑时看不到?
|
||||
A: 这是正常现象,请切换到分屏模式,右侧预览区域会实时显示圆点效果。
|
||||
|
||||
### Q: 如何自定义编辑器工具栏?
|
||||
A: 通过`options.toolbar`配置项自定义工具栏按钮。
|
||||
|
||||
### Q: 支持哪些文件格式?
|
||||
A: 组件输出标准HTML格式,支持所有富文本编辑器的常见功能。
|
||||
|
||||
### Q: 如何集成到现有项目?
|
||||
A: 复制`SplitScreenEditor.vue`组件到您的项目中,然后按照上述方法使用即可。
|
||||
|
||||
## 📚 TinyMCE 功能详解
|
||||
|
||||
### 📝 基础文本编辑
|
||||
- **撤销/重做**: `Ctrl + Z` / `Ctrl + Y` - 快速回退或恢复编辑操作
|
||||
- **字体样式**: `Ctrl + B` 粗体 | `Ctrl + I` 斜体 | `Ctrl + U` 下划线
|
||||
|
||||
### 🎨 格式与样式
|
||||
- **段落格式**: 标题1-6、段落、预格式化文本
|
||||
- **颜色设置**: 字体颜色和背景颜色选择
|
||||
- **文本对齐**: 左对齐、居中、右对齐、两端对齐
|
||||
|
||||
### 📋 列表与缩进
|
||||
- **无序列表(圆点)**: 创建带圆点的项目列表
|
||||
- **有序列表(数字)**: 创建带数字编号的项目列表
|
||||
- **缩进控制**: `Tab` 增加缩进 | `Shift + Tab` 减少缩进
|
||||
|
||||
### 🔗 插入与媒体
|
||||
- **链接插入**: `Ctrl + K` - 插入超链接
|
||||
- **图片插入**: 支持上传图片或插入图片链接
|
||||
- **表格插入**: 创建和编辑表格数据
|
||||
|
||||
### 🛠️ 高级功能
|
||||
- **搜索替换**: `Ctrl + F` 查找 | `Ctrl + H` 替换
|
||||
- **源码编辑**: 查看和编辑HTML源代码
|
||||
- **全屏编辑**: `F11` 或点击全屏按钮
|
||||
|
||||
### ⌨️ 快捷键汇总
|
||||
| 功能 | 快捷键 | 说明 |
|
||||
|------|--------|------|
|
||||
| 撤销 | `Ctrl + Z` | 撤销上一步操作 |
|
||||
| 重做 | `Ctrl + Y` | 重做操作 |
|
||||
| 粗体 | `Ctrl + B` | 加粗选中文字 |
|
||||
| 斜体 | `Ctrl + I` | 倾斜选中文字 |
|
||||
| 下划线 | `Ctrl + U` | 给选中文字加下划线 |
|
||||
| 插入链接 | `Ctrl + K` | 为选中文字插入超链接 |
|
||||
| 全屏 | `F11` | 进入/退出全屏模式 |
|
||||
| 查找 | `Ctrl + F` | 搜索文本内容 |
|
||||
| 替换 | `Ctrl + H` | 查找并替换文本 |
|
||||
|
||||
## 🔄 更新日志
|
||||
|
||||
### v1.2.0 (LATEST!)
|
||||
- ✅ **完整发布功能** - 直接调用 addDocument 接口发布文档
|
||||
- ✅ **文档类型选择** - 支持4种文档类型分类(其他、服务条款、API文档、挖矿教程)
|
||||
- ✅ **两步式发布流程** - 标题输入 + 类型选择
|
||||
- ✅ **发布状态管理** - 加载中、成功、失败状态处理
|
||||
- ✅ **智能默认值** - 自动生成文档标题和时间戳
|
||||
- ✅ **演示编辑器** - 在使用指南中直接体验功能
|
||||
|
||||
### v1.1.0
|
||||
- ✅ **使用指南功能** - 点击显示详细的TinyMCE功能说明
|
||||
- ✅ **发布按钮** - 一键发布内容,支持事件回调
|
||||
- ✅ **完整快捷键说明** - 涵盖所有常用快捷键
|
||||
- ✅ **功能分类展示** - 按类别组织功能说明
|
||||
- ✅ **响应式指南面板** - 适配各种屏幕尺寸
|
||||
|
||||
### v1.0.0
|
||||
- ✅ 支持三种显示模式(编辑/预览/分屏)
|
||||
- ✅ 专用圆点插入功能
|
||||
- ✅ 实时预览效果
|
||||
- ✅ 全屏编辑支持
|
||||
- ✅ 字数统计功能
|
||||
- ✅ HTML复制功能
|
||||
- ✅ 响应式设计
|
||||
- ✅ 自动保存机制
|
||||
|
||||
## 📞 技术支持
|
||||
|
||||
如有任何问题或建议,请联系开发团队。
|
||||
|
||||
---
|
||||
|
||||
> **提示**: 建议在分屏模式下使用编辑器,这样可以实时看到圆点和其他格式化效果,大大提升编辑体验!
|
|
@ -1150,6 +1150,14 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"@babel/runtime-corejs3": {
|
||||
"version": "7.28.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.28.2.tgz",
|
||||
"integrity": "sha512-FVFaVs2/dZgD3Y9ZD+AKNKjyGKzwu0C54laAXWUXgLcVXcCX6YZ6GhK2cp7FogSN2OA0Fu+QT8dP3FUdo9ShSQ==",
|
||||
"requires": {
|
||||
"core-js-pure": "^3.43.0"
|
||||
}
|
||||
},
|
||||
"@babel/template": {
|
||||
"version": "7.26.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.26.9.tgz",
|
||||
|
@ -1827,11 +1835,6 @@
|
|||
"resolved": "https://registry.npmjs.org/@tinymce/tinymce-vue/-/tinymce-vue-6.2.0.tgz",
|
||||
"integrity": "sha512-HiXKB+M3mJnWO6/8kY0HsP255+8zLZw5JMqHKVUvsXvzYyHW+splXXwYDYOkCYqf39R5nBqQaK2l2WL9rz3y5w=="
|
||||
},
|
||||
"@transloadit/prettier-bytes": {
|
||||
"version": "0.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@transloadit/prettier-bytes/-/prettier-bytes-0.0.7.tgz",
|
||||
"integrity": "sha512-VeJbUb0wEKbcwaSlj5n+LscBl9IPgLPkHVGBkh00cztv6X4L/TJXK58LzFuBKX7/GAfiGhIwH67YTLTlzvIzBA=="
|
||||
},
|
||||
"@trysound/sax": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz",
|
||||
|
@ -1902,11 +1905,6 @@
|
|||
"integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/event-emitter": {
|
||||
"version": "0.3.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/event-emitter/-/event-emitter-0.3.5.tgz",
|
||||
"integrity": "sha512-zx2/Gg0Eg7gwEiOIIh5w9TrhKKTeQh7CPCOPNc0el4pLSwzebA8SmnHwZs2dWlLONvyulykSwGSQxQHLhjGLvQ=="
|
||||
},
|
||||
"@types/express": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz",
|
||||
|
@ -2089,53 +2087,6 @@
|
|||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@uppy/companion-client": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@uppy/companion-client/-/companion-client-2.2.2.tgz",
|
||||
"integrity": "sha512-5mTp2iq97/mYSisMaBtFRry6PTgZA6SIL7LePteOV5x0/DxKfrZW3DEiQERJmYpHzy7k8johpm2gHnEKto56Og==",
|
||||
"requires": {
|
||||
"@uppy/utils": "^4.1.2",
|
||||
"namespace-emitter": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"@uppy/core": {
|
||||
"version": "2.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@uppy/core/-/core-2.3.4.tgz",
|
||||
"integrity": "sha512-iWAqppC8FD8mMVqewavCz+TNaet6HPXitmGXpGGREGrakZ4FeuWytVdrelydzTdXx6vVKkOmI2FLztGg73sENQ==",
|
||||
"requires": {
|
||||
"@transloadit/prettier-bytes": "0.0.7",
|
||||
"@uppy/store-default": "^2.1.1",
|
||||
"@uppy/utils": "^4.1.3",
|
||||
"lodash.throttle": "^4.1.1",
|
||||
"mime-match": "^1.0.2",
|
||||
"namespace-emitter": "^2.0.1",
|
||||
"nanoid": "^3.1.25",
|
||||
"preact": "^10.5.13"
|
||||
}
|
||||
},
|
||||
"@uppy/store-default": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@uppy/store-default/-/store-default-2.1.1.tgz",
|
||||
"integrity": "sha512-xnpTxvot2SeAwGwbvmJ899ASk5tYXhmZzD/aCFsXePh/v8rNvR2pKlcQUH7cF/y4baUGq3FHO/daKCok/mpKqQ=="
|
||||
},
|
||||
"@uppy/utils": {
|
||||
"version": "4.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@uppy/utils/-/utils-4.1.3.tgz",
|
||||
"integrity": "sha512-nTuMvwWYobnJcytDO3t+D6IkVq/Qs4Xv3vyoEZ+Iaf8gegZP+rEyoaFT2CK5XLRMienPyqRqNbIfRuFaOWSIFw==",
|
||||
"requires": {
|
||||
"lodash.throttle": "^4.1.1"
|
||||
}
|
||||
},
|
||||
"@uppy/xhr-upload": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@uppy/xhr-upload/-/xhr-upload-2.1.3.tgz",
|
||||
"integrity": "sha512-YWOQ6myBVPs+mhNjfdWsQyMRWUlrDLMoaG7nvf/G6Y3GKZf8AyjFDjvvJ49XWQ+DaZOftGkHmF1uh/DBeGivJQ==",
|
||||
"requires": {
|
||||
"@uppy/companion-client": "^2.2.2",
|
||||
"@uppy/utils": "^4.1.2",
|
||||
"nanoid": "^3.1.25"
|
||||
}
|
||||
},
|
||||
"@vue/babel-helper-vue-jsx-merge-props": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@vue/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-1.4.0.tgz",
|
||||
|
@ -2758,88 +2709,6 @@
|
|||
"integrity": "sha512-Iu8Tbg3f+emIIMmI2ycSI8QcEuAUgPTgHwesDU1eKMLE4YC/c/sFbGc70QgMq31ijRftV0R7vCm9co6rldCeOA==",
|
||||
"dev": true
|
||||
},
|
||||
"@wangeditor/basic-modules": {
|
||||
"version": "1.1.7",
|
||||
"resolved": "https://registry.npmjs.org/@wangeditor/basic-modules/-/basic-modules-1.1.7.tgz",
|
||||
"integrity": "sha512-cY9CPkLJaqF05STqfpZKWG4LpxTMeGSIIF1fHvfm/mz+JXatCagjdkbxdikOuKYlxDdeqvOeBmsUBItufDLXZg==",
|
||||
"requires": {
|
||||
"is-url": "^1.2.4"
|
||||
}
|
||||
},
|
||||
"@wangeditor/code-highlight": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@wangeditor/code-highlight/-/code-highlight-1.0.3.tgz",
|
||||
"integrity": "sha512-iazHwO14XpCuIWJNTQTikqUhGKyqj+dUNWJ9288Oym9M2xMVHvnsOmDU2sgUDWVy+pOLojReMPgXCsvvNlOOhw==",
|
||||
"requires": {
|
||||
"prismjs": "^1.23.0"
|
||||
}
|
||||
},
|
||||
"@wangeditor/core": {
|
||||
"version": "1.1.19",
|
||||
"resolved": "https://registry.npmjs.org/@wangeditor/core/-/core-1.1.19.tgz",
|
||||
"integrity": "sha512-KevkB47+7GhVszyYF2pKGKtCSj/YzmClsD03C3zTt+9SR2XWT5T0e3yQqg8baZpcMvkjs1D8Dv4fk8ok/UaS2Q==",
|
||||
"requires": {
|
||||
"@types/event-emitter": "^0.3.3",
|
||||
"event-emitter": "^0.3.5",
|
||||
"html-void-elements": "^2.0.0",
|
||||
"i18next": "^20.4.0",
|
||||
"scroll-into-view-if-needed": "^2.2.28",
|
||||
"slate-history": "^0.66.0"
|
||||
}
|
||||
},
|
||||
"@wangeditor/editor": {
|
||||
"version": "5.1.23",
|
||||
"resolved": "https://registry.npmjs.org/@wangeditor/editor/-/editor-5.1.23.tgz",
|
||||
"integrity": "sha512-0RxfeVTuK1tktUaPROnCoFfaHVJpRAIE2zdS0mpP+vq1axVQpLjM8+fCvKzqYIkH0Pg+C+44hJpe3VVroSkEuQ==",
|
||||
"requires": {
|
||||
"@uppy/core": "^2.1.1",
|
||||
"@uppy/xhr-upload": "^2.0.3",
|
||||
"@wangeditor/basic-modules": "^1.1.7",
|
||||
"@wangeditor/code-highlight": "^1.0.3",
|
||||
"@wangeditor/core": "^1.1.19",
|
||||
"@wangeditor/list-module": "^1.0.5",
|
||||
"@wangeditor/table-module": "^1.1.4",
|
||||
"@wangeditor/upload-image-module": "^1.0.2",
|
||||
"@wangeditor/video-module": "^1.1.4",
|
||||
"dom7": "^3.0.0",
|
||||
"is-hotkey": "^0.2.0",
|
||||
"lodash.camelcase": "^4.3.0",
|
||||
"lodash.clonedeep": "^4.5.0",
|
||||
"lodash.debounce": "^4.0.8",
|
||||
"lodash.foreach": "^4.5.0",
|
||||
"lodash.isequal": "^4.5.0",
|
||||
"lodash.throttle": "^4.1.1",
|
||||
"lodash.toarray": "^4.4.0",
|
||||
"nanoid": "^3.2.0",
|
||||
"slate": "^0.72.0",
|
||||
"snabbdom": "^3.1.0"
|
||||
}
|
||||
},
|
||||
"@wangeditor/editor-for-vue": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@wangeditor/editor-for-vue/-/editor-for-vue-1.0.2.tgz",
|
||||
"integrity": "sha512-BOENvAXJVtVXlE2X50AAvjV82YlCUeu5cbeR0cvEQHQjYtiVnJtq7HSoj85r2kTgGouI5OrpJG9BBEjSjUSPyA=="
|
||||
},
|
||||
"@wangeditor/list-module": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@wangeditor/list-module/-/list-module-1.0.5.tgz",
|
||||
"integrity": "sha512-uDuYTP6DVhcYf7mF1pTlmNn5jOb4QtcVhYwSSAkyg09zqxI1qBqsfUnveeDeDqIuptSJhkh81cyxi+MF8sEPOQ=="
|
||||
},
|
||||
"@wangeditor/table-module": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@wangeditor/table-module/-/table-module-1.1.4.tgz",
|
||||
"integrity": "sha512-5saanU9xuEocxaemGdNi9t8MCDSucnykEC6jtuiT72kt+/Hhh4nERYx1J20OPsTCCdVr7hIyQenFD1iSRkIQ6w=="
|
||||
},
|
||||
"@wangeditor/upload-image-module": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@wangeditor/upload-image-module/-/upload-image-module-1.0.2.tgz",
|
||||
"integrity": "sha512-z81lk/v71OwPDYeQDxj6cVr81aDP90aFuywb8nPD6eQeECtOymrqRODjpO6VGvCVxVck8nUxBHtbxKtjgcwyiA=="
|
||||
},
|
||||
"@wangeditor/video-module": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@wangeditor/video-module/-/video-module-1.1.4.tgz",
|
||||
"integrity": "sha512-ZdodDPqKQrgx3IwWu4ZiQmXI8EXZ3hm2/fM6E3t5dB8tCaIGWQZhmqd6P5knfkRAd3z2+YRSRbxOGfoRSp/rLg=="
|
||||
},
|
||||
"@webassemblyjs/ast": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz",
|
||||
|
@ -3663,6 +3532,7 @@
|
|||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz",
|
||||
"integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"call-bind-apply-helpers": "^1.0.0",
|
||||
"es-define-property": "^1.0.0",
|
||||
|
@ -4112,11 +3982,6 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"compute-scroll-into-view": {
|
||||
"version": "1.0.20",
|
||||
"resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-1.0.20.tgz",
|
||||
"integrity": "sha512-UCB0ioiyj8CRjtrvaceBLqqhZCVP+1B8+NWQhmdsm0VXOJtobBCf1dBQmebCCo34qZmUwZfIH2MZLqNHazrfjg=="
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
|
@ -4250,6 +4115,11 @@
|
|||
"browserslist": "^4.24.3"
|
||||
}
|
||||
},
|
||||
"core-js-pure": {
|
||||
"version": "3.44.0",
|
||||
"resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.44.0.tgz",
|
||||
"integrity": "sha512-gvMQAGB4dfVUxpYD0k3Fq8J+n5bB6Ytl15lqlZrOIXFzxOhtPaObfkQGHtMRdyjIf7z2IeNULwi1jEwyS+ltKQ=="
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
|
||||
|
@ -4491,15 +4361,6 @@
|
|||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
||||
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
|
||||
},
|
||||
"d": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/d/-/d-1.0.2.tgz",
|
||||
"integrity": "sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==",
|
||||
"requires": {
|
||||
"es5-ext": "^0.10.64",
|
||||
"type": "^2.7.2"
|
||||
}
|
||||
},
|
||||
"de-indent": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz",
|
||||
|
@ -4525,19 +4386,6 @@
|
|||
"resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz",
|
||||
"integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ=="
|
||||
},
|
||||
"deep-equal": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.2.tgz",
|
||||
"integrity": "sha512-5tdhKF6DbU7iIzrIOa1AOUt39ZRm13cmL1cGEh//aqR8x9+tNfbywRf0n5FD/18OKMdo7DNEtrX2t22ZAkI+eg==",
|
||||
"requires": {
|
||||
"is-arguments": "^1.1.1",
|
||||
"is-date-object": "^1.0.5",
|
||||
"is-regex": "^1.1.4",
|
||||
"object-is": "^1.1.5",
|
||||
"object-keys": "^1.1.1",
|
||||
"regexp.prototype.flags": "^1.5.1"
|
||||
}
|
||||
},
|
||||
"deep-is": {
|
||||
"version": "0.1.4",
|
||||
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
|
||||
|
@ -4652,6 +4500,7 @@
|
|||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
|
||||
"integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"es-define-property": "^1.0.0",
|
||||
"es-errors": "^1.3.0",
|
||||
|
@ -4668,6 +4517,7 @@
|
|||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz",
|
||||
"integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"define-data-property": "^1.0.1",
|
||||
"has-property-descriptors": "^1.0.0",
|
||||
|
@ -4777,14 +4627,6 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"dom7": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/dom7/-/dom7-3.0.0.tgz",
|
||||
"integrity": "sha512-oNlcUdHsC4zb7Msx7JN3K0Nro1dzJ48knvBOnDPKJ2GV9wl1i5vydJZUSyOfrkKFDZEud/jBsTk92S/VGSAe/g==",
|
||||
"requires": {
|
||||
"ssr-window": "^3.0.0-alpha.1"
|
||||
}
|
||||
},
|
||||
"domelementtype": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
|
||||
|
@ -5084,27 +4926,6 @@
|
|||
"hasown": "^2.0.2"
|
||||
}
|
||||
},
|
||||
"es5-ext": {
|
||||
"version": "0.10.64",
|
||||
"resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.64.tgz",
|
||||
"integrity": "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==",
|
||||
"requires": {
|
||||
"es6-iterator": "^2.0.3",
|
||||
"es6-symbol": "^3.1.3",
|
||||
"esniff": "^2.0.1",
|
||||
"next-tick": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"es6-iterator": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
|
||||
"integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==",
|
||||
"requires": {
|
||||
"d": "1",
|
||||
"es5-ext": "^0.10.35",
|
||||
"es6-symbol": "^3.1.1"
|
||||
}
|
||||
},
|
||||
"es6-promise": {
|
||||
"version": "4.2.8",
|
||||
"resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz",
|
||||
|
@ -5118,15 +4939,6 @@
|
|||
"es6-promise": "^4.0.3"
|
||||
}
|
||||
},
|
||||
"es6-symbol": {
|
||||
"version": "3.1.4",
|
||||
"resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.4.tgz",
|
||||
"integrity": "sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==",
|
||||
"requires": {
|
||||
"d": "^1.0.2",
|
||||
"ext": "^1.7.0"
|
||||
}
|
||||
},
|
||||
"escalade": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
|
||||
|
@ -5525,17 +5337,6 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"esniff": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz",
|
||||
"integrity": "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==",
|
||||
"requires": {
|
||||
"d": "^1.0.1",
|
||||
"es5-ext": "^0.10.62",
|
||||
"event-emitter": "^0.3.5",
|
||||
"type": "^2.7.2"
|
||||
}
|
||||
},
|
||||
"espree": {
|
||||
"version": "7.3.1",
|
||||
"resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz",
|
||||
|
@ -5629,15 +5430,6 @@
|
|||
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
|
||||
"integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="
|
||||
},
|
||||
"event-emitter": {
|
||||
"version": "0.3.5",
|
||||
"resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz",
|
||||
"integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==",
|
||||
"requires": {
|
||||
"d": "1",
|
||||
"es5-ext": "~0.10.14"
|
||||
}
|
||||
},
|
||||
"event-pubsub": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/event-pubsub/-/event-pubsub-4.3.0.tgz",
|
||||
|
@ -5740,19 +5532,6 @@
|
|||
"vary": "~1.1.2"
|
||||
}
|
||||
},
|
||||
"ext": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz",
|
||||
"integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==",
|
||||
"requires": {
|
||||
"type": "^2.7.2"
|
||||
}
|
||||
},
|
||||
"extend": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
|
||||
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
|
||||
},
|
||||
"extend-shallow": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
|
||||
|
@ -6193,11 +5972,6 @@
|
|||
"integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==",
|
||||
"dev": true
|
||||
},
|
||||
"functions-have-names": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
|
||||
"integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ=="
|
||||
},
|
||||
"gensync": {
|
||||
"version": "1.0.0-beta.2",
|
||||
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
|
||||
|
@ -6342,6 +6116,7 @@
|
|||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
|
||||
"integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"es-define-property": "^1.0.0"
|
||||
}
|
||||
|
@ -6521,11 +6296,6 @@
|
|||
"integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==",
|
||||
"dev": true
|
||||
},
|
||||
"html-void-elements": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-2.0.1.tgz",
|
||||
"integrity": "sha512-0quDb7s97CfemeJAnW9wC0hw78MtW7NU3hqtCD75g2vFlDLt36llsYD7uB7SUzojLMP24N5IatXf7ylGXiGG9A=="
|
||||
},
|
||||
"html-webpack-plugin": {
|
||||
"version": "5.6.3",
|
||||
"resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.3.tgz",
|
||||
|
@ -6634,14 +6404,6 @@
|
|||
"integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
|
||||
"dev": true
|
||||
},
|
||||
"i18next": {
|
||||
"version": "20.6.1",
|
||||
"resolved": "https://registry.npmjs.org/i18next/-/i18next-20.6.1.tgz",
|
||||
"integrity": "sha512-yCMYTMEJ9ihCwEQQ3phLo7I/Pwycf8uAx+sRHwwk5U9Aui/IZYgQRyMqXafQOw5QQ7DM1Z+WyEXWIqSuJHhG2A==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.12.0"
|
||||
}
|
||||
},
|
||||
"iconv-lite": {
|
||||
"version": "0.4.24",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
||||
|
@ -6675,11 +6437,6 @@
|
|||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"immer": {
|
||||
"version": "9.0.21",
|
||||
"resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz",
|
||||
"integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA=="
|
||||
},
|
||||
"immutable": {
|
||||
"version": "5.0.3",
|
||||
"resolved": "https://registry.npmjs.org/immutable/-/immutable-5.0.3.tgz",
|
||||
|
@ -6746,15 +6503,6 @@
|
|||
"hasown": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"is-arguments": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz",
|
||||
"integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==",
|
||||
"requires": {
|
||||
"call-bound": "^1.0.2",
|
||||
"has-tostringtag": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"is-arrayish": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
|
||||
|
@ -6800,15 +6548,6 @@
|
|||
"hasown": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"is-date-object": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz",
|
||||
"integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==",
|
||||
"requires": {
|
||||
"call-bound": "^1.0.2",
|
||||
"has-tostringtag": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"is-descriptor": {
|
||||
"version": "0.1.7",
|
||||
"resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz",
|
||||
|
@ -6856,11 +6595,6 @@
|
|||
"is-extglob": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"is-hotkey": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/is-hotkey/-/is-hotkey-0.2.0.tgz",
|
||||
"integrity": "sha512-UknnZK4RakDmTgz4PI1wIph5yxSs/mvChWs9ifnlXsKuXgWmOkY/hAE0H/k2MIqH0RlRye0i1oC07MCRSD28Mw=="
|
||||
},
|
||||
"is-interactive": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz",
|
||||
|
@ -6904,17 +6638,6 @@
|
|||
"isobject": "^3.0.1"
|
||||
}
|
||||
},
|
||||
"is-regex": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz",
|
||||
"integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==",
|
||||
"requires": {
|
||||
"call-bound": "^1.0.2",
|
||||
"gopd": "^1.2.0",
|
||||
"has-tostringtag": "^1.0.2",
|
||||
"hasown": "^2.0.2"
|
||||
}
|
||||
},
|
||||
"is-stream": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
|
||||
|
@ -6927,11 +6650,6 @@
|
|||
"integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
|
||||
"dev": true
|
||||
},
|
||||
"is-url": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz",
|
||||
"integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww=="
|
||||
},
|
||||
"is-what": {
|
||||
"version": "3.14.1",
|
||||
"resolved": "https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz",
|
||||
|
@ -7297,11 +7015,6 @@
|
|||
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
|
||||
"integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="
|
||||
},
|
||||
"lodash.camelcase": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
|
||||
"integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA=="
|
||||
},
|
||||
"lodash.clonedeep": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
|
||||
|
@ -7310,7 +7023,8 @@
|
|||
"lodash.debounce": {
|
||||
"version": "4.0.8",
|
||||
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
|
||||
"integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow=="
|
||||
"integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==",
|
||||
"dev": true
|
||||
},
|
||||
"lodash.defaultsdeep": {
|
||||
"version": "4.6.1",
|
||||
|
@ -7318,11 +7032,6 @@
|
|||
"integrity": "sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA==",
|
||||
"dev": true
|
||||
},
|
||||
"lodash.foreach": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz",
|
||||
"integrity": "sha512-aEXTF4d+m05rVOAUG3z4vZZ4xVexLKZGF0lIxuHZ1Hplpk/3B6Z1+/ICICYRLm7c41Z2xiejbkCkJoTlypoXhQ=="
|
||||
},
|
||||
"lodash.isequal": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
|
||||
|
@ -7352,16 +7061,6 @@
|
|||
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
|
||||
"dev": true
|
||||
},
|
||||
"lodash.throttle": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz",
|
||||
"integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ=="
|
||||
},
|
||||
"lodash.toarray": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.toarray/-/lodash.toarray-4.4.0.tgz",
|
||||
"integrity": "sha512-QyffEA3i5dma5q2490+SgCvDN0pXLmRGSyAANuVi0HQ01Pkfr9fuoKQW8wm1wGBnJITs/mS7wQvS6VshUEBFCw=="
|
||||
},
|
||||
"lodash.truncate": {
|
||||
"version": "4.4.2",
|
||||
"resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz",
|
||||
|
@ -7640,21 +7339,6 @@
|
|||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
||||
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="
|
||||
},
|
||||
"mime-match": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/mime-match/-/mime-match-1.0.2.tgz",
|
||||
"integrity": "sha512-VXp/ugGDVh3eCLOBCiHZMYWQaTNUHv2IJrut+yXA6+JbLPXHglHwfS/5A5L0ll+jkCY7fIzRJcH6OIunF+c6Cg==",
|
||||
"requires": {
|
||||
"wildcard": "^1.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"wildcard": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/wildcard/-/wildcard-1.1.2.tgz",
|
||||
"integrity": "sha512-DXukZJxpHA8LuotRwL0pP1+rS6CS7FF2qStDDE1C7DDg2rLud2PXRMuEDYIPhgEezwnlHNL4c+N6MfMTjCGTng=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"mime-types": {
|
||||
"version": "2.1.35",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
|
||||
|
@ -7866,11 +7550,6 @@
|
|||
"thenify-all": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"namespace-emitter": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/namespace-emitter/-/namespace-emitter-2.0.1.tgz",
|
||||
"integrity": "sha512-N/sMKHniSDJBjfrkbS/tpkPj4RAbvW3mr8UAzvlMHyun93XEm83IAvhWtJVHo+RHn/oO8Job5YN4b+wRjSVp5g=="
|
||||
},
|
||||
"nanoid": {
|
||||
"version": "3.3.8",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz",
|
||||
|
@ -7934,11 +7613,6 @@
|
|||
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
|
||||
"dev": true
|
||||
},
|
||||
"next-tick": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz",
|
||||
"integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ=="
|
||||
},
|
||||
"nice-try": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
|
||||
|
@ -8053,7 +7727,8 @@
|
|||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="
|
||||
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
|
||||
"dev": true
|
||||
},
|
||||
"object-copy": {
|
||||
"version": "0.1.0",
|
||||
|
@ -8088,19 +7763,11 @@
|
|||
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
|
||||
"integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew=="
|
||||
},
|
||||
"object-is": {
|
||||
"version": "1.1.6",
|
||||
"resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz",
|
||||
"integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==",
|
||||
"requires": {
|
||||
"call-bind": "^1.0.7",
|
||||
"define-properties": "^1.2.1"
|
||||
}
|
||||
},
|
||||
"object-keys": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
|
||||
"integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="
|
||||
"integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
|
||||
"dev": true
|
||||
},
|
||||
"object-visit": {
|
||||
"version": "1.0.1",
|
||||
|
@ -8891,11 +8558,6 @@
|
|||
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
|
||||
"dev": true
|
||||
},
|
||||
"preact": {
|
||||
"version": "10.26.9",
|
||||
"resolved": "https://registry.npmjs.org/preact/-/preact-10.26.9.tgz",
|
||||
"integrity": "sha512-SSjF9vcnF27mJK1XyFMNJzFd5u3pQiATFqoaDy03XuN00u4ziveVVEGt5RKJrDR8MHE/wJo9Nnad56RLzS2RMA=="
|
||||
},
|
||||
"prelude-ls": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
|
||||
|
@ -8918,11 +8580,6 @@
|
|||
"renderkid": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"prismjs": {
|
||||
"version": "1.30.0",
|
||||
"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz",
|
||||
"integrity": "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw=="
|
||||
},
|
||||
"process-nextick-args": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
||||
|
@ -9256,19 +8913,6 @@
|
|||
"safe-regex": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"regexp.prototype.flags": {
|
||||
"version": "1.5.4",
|
||||
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz",
|
||||
"integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==",
|
||||
"requires": {
|
||||
"call-bind": "^1.0.8",
|
||||
"define-properties": "^1.2.1",
|
||||
"es-errors": "^1.3.0",
|
||||
"get-proto": "^1.0.1",
|
||||
"gopd": "^1.2.0",
|
||||
"set-function-name": "^2.0.2"
|
||||
}
|
||||
},
|
||||
"regexpp": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz",
|
||||
|
@ -9616,14 +9260,6 @@
|
|||
"ajv-keywords": "^3.5.2"
|
||||
}
|
||||
},
|
||||
"scroll-into-view-if-needed": {
|
||||
"version": "2.2.31",
|
||||
"resolved": "https://registry.npmjs.org/scroll-into-view-if-needed/-/scroll-into-view-if-needed-2.2.31.tgz",
|
||||
"integrity": "sha512-dGCXy99wZQivjmjIqihaBQNjryrz5rueJY7eHfTdyWEiR4ttYpsajb14rn9s5d4DY4EcY6+4+U/maARBXJedkA==",
|
||||
"requires": {
|
||||
"compute-scroll-into-view": "^1.0.20"
|
||||
}
|
||||
},
|
||||
"select-hose": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
|
||||
|
@ -9755,6 +9391,7 @@
|
|||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
|
||||
"integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"define-data-property": "^1.1.4",
|
||||
"es-errors": "^1.3.0",
|
||||
|
@ -9764,17 +9401,6 @@
|
|||
"has-property-descriptors": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"set-function-name": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz",
|
||||
"integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==",
|
||||
"requires": {
|
||||
"define-data-property": "^1.1.4",
|
||||
"es-errors": "^1.3.0",
|
||||
"functions-have-names": "^1.2.3",
|
||||
"has-property-descriptors": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"set-value": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz",
|
||||
|
@ -9958,38 +9584,6 @@
|
|||
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
|
||||
"dev": true
|
||||
},
|
||||
"slate": {
|
||||
"version": "0.72.8",
|
||||
"resolved": "https://registry.npmjs.org/slate/-/slate-0.72.8.tgz",
|
||||
"integrity": "sha512-/nJwTswQgnRurpK+bGJFH1oM7naD5qDmHd89JyiKNT2oOKD8marW0QSBtuFnwEbL5aGCS8AmrhXQgNOsn4osAw==",
|
||||
"requires": {
|
||||
"immer": "^9.0.6",
|
||||
"is-plain-object": "^5.0.0",
|
||||
"tiny-warning": "^1.0.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"is-plain-object": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
|
||||
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"slate-history": {
|
||||
"version": "0.66.0",
|
||||
"resolved": "https://registry.npmjs.org/slate-history/-/slate-history-0.66.0.tgz",
|
||||
"integrity": "sha512-6MWpxGQZiMvSINlCbMW43E2YBSVMCMCIwQfBzGssjWw4kb0qfvj0pIdblWNRQZD0hR6WHP+dHHgGSeVdMWzfng==",
|
||||
"requires": {
|
||||
"is-plain-object": "^5.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"is-plain-object": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
|
||||
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"slice-ansi": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz",
|
||||
|
@ -10012,11 +9606,6 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"snabbdom": {
|
||||
"version": "3.6.2",
|
||||
"resolved": "https://registry.npmjs.org/snabbdom/-/snabbdom-3.6.2.tgz",
|
||||
"integrity": "sha512-ig5qOnCDbugFntKi6c7Xlib8bA6xiJVk8O+WdFrV3wxbMqeHO0hXFQC4nAhPVWfZfi8255lcZkNhtIBINCc4+Q=="
|
||||
},
|
||||
"snapdragon": {
|
||||
"version": "0.8.2",
|
||||
"resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
|
||||
|
@ -10277,11 +9866,6 @@
|
|||
"integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
|
||||
"dev": true
|
||||
},
|
||||
"ssr-window": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ssr-window/-/ssr-window-3.0.0.tgz",
|
||||
"integrity": "sha512-q+8UfWDg9Itrg0yWK7oe5p/XRCJpJF9OBtXfOPgSJl+u3Xd5KI328RUEvUqSMVM9CiQUEf1QdBzJMkYGErj9QA=="
|
||||
},
|
||||
"ssri": {
|
||||
"version": "8.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz",
|
||||
|
@ -10711,11 +10295,6 @@
|
|||
"integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==",
|
||||
"dev": true
|
||||
},
|
||||
"tiny-warning": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz",
|
||||
"integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA=="
|
||||
},
|
||||
"to-object-path": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
|
||||
|
@ -10776,11 +10355,6 @@
|
|||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz",
|
||||
"integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="
|
||||
},
|
||||
"type": {
|
||||
"version": "2.7.3",
|
||||
"resolved": "https://registry.npmjs.org/type/-/type-2.7.3.tgz",
|
||||
"integrity": "sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ=="
|
||||
},
|
||||
"type-check": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
|
||||
|
@ -11171,60 +10745,6 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"vue-quill-editor": {
|
||||
"version": "3.0.6",
|
||||
"resolved": "https://registry.npmjs.org/vue-quill-editor/-/vue-quill-editor-3.0.6.tgz",
|
||||
"integrity": "sha512-g20oSZNWg8Hbu41Kinjd55e235qVWPLfg4NvsLW6d+DhgBTFbEuMpcWlUdrD6qT3+Noim6DRu18VLM9lVShXOQ==",
|
||||
"requires": {
|
||||
"object-assign": "^4.1.1",
|
||||
"quill": "^1.3.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"clone": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
|
||||
"integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w=="
|
||||
},
|
||||
"eventemitter3": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-2.0.3.tgz",
|
||||
"integrity": "sha512-jLN68Dx5kyFHaePoXWPsCGW5qdyZQtLYHkxkg02/Mz6g0kYpDx4FyP6XfArhQdlOC4b8Mv+EMxPo/8La7Tzghg=="
|
||||
},
|
||||
"fast-diff": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.1.2.tgz",
|
||||
"integrity": "sha512-KaJUt+M9t1qaIteSvjc6P3RbMdXsNhK61GRftR6SNxqmhthcd9MGIi4T+o0jD8LUSpSnSKXE20nLtJ3fOHxQig=="
|
||||
},
|
||||
"parchment": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/parchment/-/parchment-1.1.4.tgz",
|
||||
"integrity": "sha512-J5FBQt/pM2inLzg4hEWmzQx/8h8D0CiDxaG3vyp9rKrQRSDgBlhjdP5jQGgosEajXPSQouXGHOmVdgo7QmJuOg=="
|
||||
},
|
||||
"quill": {
|
||||
"version": "1.3.7",
|
||||
"resolved": "https://registry.npmjs.org/quill/-/quill-1.3.7.tgz",
|
||||
"integrity": "sha512-hG/DVzh/TiknWtE6QmWAF/pxoZKYxfe3J/d/+ShUWkDvvkZQVTPeVmUJVu1uE6DDooC4fWTiCLh84ul89oNz5g==",
|
||||
"requires": {
|
||||
"clone": "^2.1.1",
|
||||
"deep-equal": "^1.0.1",
|
||||
"eventemitter3": "^2.0.3",
|
||||
"extend": "^3.0.2",
|
||||
"parchment": "^1.1.4",
|
||||
"quill-delta": "^3.6.2"
|
||||
}
|
||||
},
|
||||
"quill-delta": {
|
||||
"version": "3.6.3",
|
||||
"resolved": "https://registry.npmjs.org/quill-delta/-/quill-delta-3.6.3.tgz",
|
||||
"integrity": "sha512-wdIGBlcX13tCHOXGMVnnTVFtGRLoP0imqxM696fIPwIf5ODIYUHIvHbZcyvGlZFiFhK5XzDC2lpjbxRhnM05Tg==",
|
||||
"requires": {
|
||||
"deep-equal": "^1.0.1",
|
||||
"extend": "^3.0.2",
|
||||
"fast-diff": "1.1.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"vue-router": {
|
||||
"version": "3.6.5",
|
||||
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.6.5.tgz",
|
||||
|
@ -11289,6 +10809,16 @@
|
|||
"resolved": "https://registry.npmjs.org/vuex/-/vuex-3.6.2.tgz",
|
||||
"integrity": "sha512-ETW44IqCgBpVomy520DT5jf8n0zoCac+sxWnn+hMe/CzaSejb/eVw2YToiXYX+Ex/AuHHia28vWTq4goAexFbw=="
|
||||
},
|
||||
"wangeditor": {
|
||||
"version": "4.7.15",
|
||||
"resolved": "https://registry.npmjs.org/wangeditor/-/wangeditor-4.7.15.tgz",
|
||||
"integrity": "sha512-aPTdREd8BxXVyJ5MI+LU83FQ7u1EPd341iXIorRNYSOvoimNoZ4nPg+yn3FGbB93/owEa6buLw8wdhYnMCJQLg==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.11.2",
|
||||
"@babel/runtime-corejs3": "^7.11.2",
|
||||
"tslib": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"watchpack": {
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz",
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"serve": "vue-cli-service serve",
|
||||
"serve": "set NODE_OPTIONS=--max-old-space-size=8192 && vue-cli-service serve",
|
||||
"build": "vue-cli-service build",
|
||||
"test": "vue-cli-service build --mode staging --dest test",
|
||||
"lint": "vue-cli-service lint"
|
||||
|
@ -12,8 +12,6 @@
|
|||
"@dreysolano/prerender-spa-plugin": "^1.0.3",
|
||||
"@stomp/stompjs": "^7.1.1",
|
||||
"@tinymce/tinymce-vue": "^6.2.0",
|
||||
"@wangeditor/editor": "^5.1.23",
|
||||
"@wangeditor/editor-for-vue": "^1.0.2",
|
||||
"amfe-flexible": "^2.2.1",
|
||||
"axios": "^1.8.4",
|
||||
"core-js": "^3.8.3",
|
||||
|
@ -25,9 +23,9 @@
|
|||
"vue": "^2.6.14",
|
||||
"vue-i18n": "^8.22.2",
|
||||
"vue-meta-info": "^0.1.7",
|
||||
"vue-quill-editor": "^3.0.6",
|
||||
"vue-router": "^3.5.1",
|
||||
"vuex": "^3.6.2"
|
||||
"vuex": "^3.6.2",
|
||||
"wangeditor": "^4.7.15"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.12.16",
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
.dynamic-content {
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
font-family: 'PingFang SC', 'Microsoft YaHei', Arial, sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.7;
|
||||
color: #222;
|
||||
// 富文本样式
|
||||
:deep(table) {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
margin: 16px 0;
|
||||
}
|
||||
|
||||
:deep(th), :deep(td) {
|
||||
border: 1px solid #d1d5db;
|
||||
padding: 8px 12px;
|
||||
text-align: left;
|
||||
}
|
||||
:deep(th) {
|
||||
background: #f3f4f6;
|
||||
font-weight: bold;
|
||||
}
|
||||
:deep(strong), :deep(b) {
|
||||
font-weight: bold !important;
|
||||
color: inherit !important;
|
||||
font-style: normal !important;
|
||||
}
|
||||
:deep(em), :deep(i) {
|
||||
font-style: italic !important;
|
||||
color: inherit !important;
|
||||
}
|
||||
:deep(a) {
|
||||
color: #661FFB !important;
|
||||
text-decoration: none !important;
|
||||
&:hover {
|
||||
text-decoration: underline !important;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -297,7 +297,7 @@ export default {
|
|||
// 使用 name 进行导航,避免重复的路由参数
|
||||
this.$router.push({
|
||||
path:url,
|
||||
params: {
|
||||
query: {
|
||||
lang: lang,
|
||||
coin: this.activeItemCoin.value,
|
||||
imgUrl: this.activeItemCoin.imgUrl
|
||||
|
|
|
@ -108,6 +108,47 @@ export const backendSystem_zh = {
|
|||
commonProblems:"常见问题",
|
||||
other:"其他",
|
||||
announcementCenter:"公告中心",
|
||||
search:"搜索",
|
||||
recommendContent:"推荐内容",
|
||||
recentActivities:"最近活动",
|
||||
viewMore:"查看更多活动公告",
|
||||
documentType:"文档类型",
|
||||
documentTitle:"文档标题",
|
||||
wangeditor:"wangeditor 富文本文档编辑器",
|
||||
insertAnchor:"插入锚点",
|
||||
previewDocument:"预览文档",
|
||||
saveDocument:"保存文档",
|
||||
publishDocument:"发布文档",
|
||||
reset:"重置",
|
||||
documentConfiguration:"文档配置",
|
||||
navigationTitle:"导航标题",
|
||||
pleaseInputDocumentTitle:"请输入文档标题",
|
||||
pleaseSelectDocumentType:"请选择文档类型",
|
||||
titleImageAddress:"标题图片地址",
|
||||
pleaseInputImageAddress:"请输入图片地址",
|
||||
articleAccessAddress:"文章访问地址",
|
||||
pleaseInputAccessAddress:"请输入访问地址",
|
||||
richTextEditor:"富文本编辑器",
|
||||
documentPreview:"文档预览",
|
||||
printPreview:"打印预览",
|
||||
close:"关闭",
|
||||
noContent:"暂无内容",
|
||||
modifyDocument:"修改文档",
|
||||
contentSaved:"内容已保存到本地,请尽快发布,关闭页面可能丢失内容",
|
||||
|
||||
pleaseInputAnchorName:"请输入锚点名称(不能重复)",
|
||||
anchorNameErrorMessage:"锚点名只能包含字母、数字、下划线和中划线",
|
||||
anchorInserted:"锚点已插入",
|
||||
confirm:"确定",
|
||||
pleaseSelectHeader:"请先选中一个标题(h1~h6)",
|
||||
pleaseInputAnchorID:"请输入锚点ID(不能重复)",
|
||||
titleAnchor:"标题锚点",
|
||||
anchorIDErrorMessage:"ID只能包含字母、数字、下划线和中划线",
|
||||
anchorIDAdded:"锚点ID已添加",
|
||||
contentReset:"内容已重置",
|
||||
selectCurrency:"选择币种",
|
||||
pleaseSelectCurrency2:"添加挖矿教程,请选择币种",
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -222,7 +263,46 @@ export const backendSystem_en = {
|
|||
commonProblems:"Common Problems",
|
||||
other:"Other",
|
||||
announcementCenter:"Announcement Center",
|
||||
|
||||
search:"Search",
|
||||
recommendContent:"Recommend Content",
|
||||
recentActivities:"Recent Activities",
|
||||
viewMore:"View More Activity Announcements",
|
||||
documentType:"Document Type",
|
||||
documentTitle:"Document Title",
|
||||
wangeditor:"wangeditor Rich Text Editor",
|
||||
insertAnchor:"Insert Anchor",
|
||||
previewDocument:"Preview Document",
|
||||
saveDocument:"Save Document",
|
||||
publishDocument:"Publish Document",
|
||||
reset:"Reset",
|
||||
documentConfiguration:"Document Configuration",
|
||||
navigationTitle:"Navigation Title",
|
||||
pleaseInputDocumentTitle:"Please input document title",
|
||||
pleaseSelectDocumentType:"Please select document type",
|
||||
titleImageAddress:"Title Image Address",
|
||||
pleaseInputImageAddress:"Please input image address",
|
||||
articleAccessAddress:"Article Access Address",
|
||||
pleaseInputAccessAddress:"Please input access address",
|
||||
richTextEditor:"Rich Text Editor",
|
||||
documentPreview:"Document Preview",
|
||||
printPreview:"Print Preview",
|
||||
close:"Close",
|
||||
noContent:"No Content",
|
||||
modifyDocument:"Modify Document",
|
||||
contentSaved:"Content has been saved to local, please publish it as soon as possible, the content may be lost if the page is closed",
|
||||
|
||||
pleaseInputAnchorName:"Please input anchor name (cannot be repeated)",
|
||||
anchorNameErrorMessage:"Anchor name can only contain letters, numbers, underscores, and hyphens",
|
||||
anchorInserted:"Anchor inserted",
|
||||
confirm:"Confirm",
|
||||
pleaseSelectHeader:"Please select a title (h1~h6)",
|
||||
pleaseInputAnchorID:"Please input anchor ID (cannot be repeated)",
|
||||
titleAnchor:"Title Anchor",
|
||||
anchorIDErrorMessage:"ID can only contain letters, numbers, underscores, and hyphens",
|
||||
anchorIDAdded:"Anchor ID added",
|
||||
contentReset:"Content has been reset",
|
||||
selectCurrency:"Select Currency",
|
||||
pleaseSelectCurrency2:"Please select a currency when adding mining tutorials",
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -85,8 +85,11 @@ export const home_zh = {
|
|||
noData:"暂无公告",
|
||||
viewAll:"查看所有",
|
||||
articles:"篇文章",
|
||||
|
||||
|
||||
allocationExplanation:"矿池分配及转账规则",
|
||||
loadingContent:"正在加载内容...",
|
||||
noContent:"暂无内容",
|
||||
unknownType:"未知类型",
|
||||
other:"其他",
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -177,6 +180,11 @@ export const home_en = {
|
|||
noData:"No data",
|
||||
viewAll:"View all",
|
||||
articles:" articles",
|
||||
allocationExplanation:"Pool allocation and transfer rules",
|
||||
loadingContent:"Loading content...",
|
||||
noContent:"No content",
|
||||
unknownType:"Unknown Type",
|
||||
other:"Other",
|
||||
|
||||
}
|
||||
}
|
|
@ -108,22 +108,7 @@ const childrenRoutes = [
|
|||
|
||||
}
|
||||
},
|
||||
{//编辑器测试markdown
|
||||
path: 'markdown',
|
||||
name: 'Markdown',
|
||||
component: () => import('../views/markdown.vue'),
|
||||
meta: {
|
||||
title: 'markdown编辑器测试',
|
||||
// description: i18n.t(`seo.helpCenter`),
|
||||
allAuthority: [`all`],
|
||||
// keywords: {
|
||||
// en: 'Help Center,Beginner Guide,Mining Data,Frequently Asked Questions,Announcement Center,Other',
|
||||
// zh: '帮助中心,新手入门,常见问题,公告中心'
|
||||
// }
|
||||
|
||||
|
||||
}
|
||||
},
|
||||
{//广播页面
|
||||
path: 'broadcast',
|
||||
name: 'Broadcast',
|
||||
|
@ -911,67 +896,7 @@ router.beforeEach((to, from, next) => {
|
|||
|
||||
|
||||
|
||||
// if (jurisdiction && jurisdiction.roleKey == `back_admin`) {
|
||||
// if (to.name == 'Login' || to.name == 'Register' || jurisdiction && jurisdiction.roleKey && to.meta.allAuthority.includes(jurisdiction.roleKey)) {
|
||||
// return next();
|
||||
// } else {
|
||||
// // 无权限
|
||||
// Message({
|
||||
// showClose: true,
|
||||
// message: `当前身份只能访问后台管理系统`,
|
||||
// type: 'error'
|
||||
// });
|
||||
// localStorage.setItem("activeIndex", `1`);
|
||||
// return next({ path: `/${lang}/broadcast` });
|
||||
|
||||
|
||||
// }
|
||||
// } else {
|
||||
// // 未登录
|
||||
// if (!token) {
|
||||
// console.log(`未登录`);
|
||||
// if (
|
||||
// to.meta.allAuthority &&
|
||||
// (
|
||||
// to.meta.allAuthority[0] === 'all' ||
|
||||
// (jurisdiction && jurisdiction.roleKey && to.meta.allAuthority.includes(jurisdiction.roleKey))
|
||||
// )
|
||||
// ) {
|
||||
// return next();
|
||||
// } else {
|
||||
|
||||
|
||||
// // 无权限
|
||||
// Message({
|
||||
// showClose: true,
|
||||
// message: i18n.t(`mining.jurisdiction`),
|
||||
// type: 'error'
|
||||
// });
|
||||
// return next({ path: `/${lang}/login` });
|
||||
// }
|
||||
|
||||
// } else {
|
||||
// if (to.name === 'Login' || to.name === 'Register') {
|
||||
// return next({ path: `/${lang}` });
|
||||
// } else if (to.meta.allAuthority &&
|
||||
// (
|
||||
// to.meta.allAuthority[0] === 'all' ||
|
||||
// (jurisdiction && jurisdiction.roleKey && to.meta.allAuthority.includes(jurisdiction.roleKey))
|
||||
// )
|
||||
// ) {
|
||||
// return next();
|
||||
// } else {
|
||||
// // 无权限
|
||||
// Message({
|
||||
// showClose: true,
|
||||
// message: i18n.t(`mining.jurisdiction`),
|
||||
// type: 'error'
|
||||
// });
|
||||
// return next({ path: `/${lang}/login` });
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
// --------------------------
|
||||
// 未登录
|
||||
if (!token) {
|
||||
|
@ -1000,9 +925,11 @@ if (!token) {
|
|||
|
||||
|
||||
if (jurisdiction && jurisdiction.roleKey == `back_admin`) {
|
||||
if (to.name == 'Login' || to.name == 'Register' || to.path == `/${lang}` || jurisdiction && jurisdiction.roleKey && to.meta.allAuthority.includes(jurisdiction.roleKey)) {
|
||||
if (to.name == 'Login' || to.name == 'Register' || jurisdiction && jurisdiction.roleKey && to.meta.allAuthority.includes(jurisdiction.roleKey)) {
|
||||
return next();
|
||||
} else {
|
||||
} else if(to.path == `/${lang}`) {
|
||||
return next({ path: `/${lang}/userManagement` });
|
||||
}else {
|
||||
// 无权限
|
||||
Message({
|
||||
showClose: true,
|
||||
|
@ -1014,6 +941,7 @@ if (!token) {
|
|||
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (to.name === 'Login' || to.name === 'Register') {
|
||||
|
|
|
@ -297,26 +297,28 @@ export default {
|
|||
// if (this.$route.name =="AccessMiningPool" ) {
|
||||
// this.$router.go(-1);
|
||||
// }
|
||||
|
||||
|
||||
this.fetchAllList(this.listParams)
|
||||
|
||||
if (this.$route.params.coin) {
|
||||
this.activeCoin = this.$route.params.coin
|
||||
console.log(this.$route, "this.$route.query.coin");
|
||||
|
||||
if (this.$route.query.coin) {
|
||||
this.activeCoin = this.$route.query.coin
|
||||
// this.currencyPath = this.$route.query.imgUrl
|
||||
this.imgUrl = this.$route.params.imgUrl
|
||||
this.currencyPath = this.$route.params.imgUrl
|
||||
this.params.coin = this.$route.params.coin
|
||||
this.imgUrl = this.$route.query.imgUrl
|
||||
this.currencyPath = this.$route.query.imgUrl
|
||||
this.params.coin = this.$route.query.coin
|
||||
this.$addStorageEvent(1, `activeCoin`, JSON.stringify(this.activeCoin))
|
||||
this.activeItem = this.currencyList.find(item => { return item.value == this.params.coin })
|
||||
const item = this.currencyList.find(item => { return item.value == this.params.coin })
|
||||
|
||||
if (item && item.path) {
|
||||
// this.clickJump(item)
|
||||
const mockEvent = {
|
||||
stopPropagation: () => {},
|
||||
currentTarget: document.getElementById('menu1')
|
||||
};
|
||||
this.changeMenuName(mockEvent, item)
|
||||
const item = this.navList.find(item => { return item.coin == this.params.coin })
|
||||
console.log(item, "item65656565",this.navList,this.$route.query.coin);
|
||||
|
||||
if (item && item.coin) {
|
||||
this.clickJump(item)
|
||||
// const mockEvent = {
|
||||
// stopPropagation: () => {},
|
||||
// currentTarget: document.getElementById('menu1')
|
||||
// };
|
||||
// this.changeMenuName(mockEvent, item)
|
||||
}
|
||||
|
||||
|
||||
|
@ -358,25 +360,25 @@ export default {
|
|||
|
||||
}
|
||||
// 从本地存储获取activeItem
|
||||
const savedActiveItem = localStorage.getItem('activeItem');
|
||||
if (savedActiveItem) {
|
||||
try {
|
||||
this.activeItem = JSON.parse(savedActiveItem);
|
||||
} catch (error) {
|
||||
console.error('Parse activeItem failed:', error);
|
||||
// 使用默认值
|
||||
this.activeItem = this.currencyList[0];
|
||||
}
|
||||
} else {
|
||||
// 没有存储值时使用默认值
|
||||
this.activeItem = this.currencyList[0];
|
||||
}
|
||||
// const savedActiveItem = localStorage.getItem('activeItem');
|
||||
// if (savedActiveItem) {
|
||||
// try {
|
||||
// this.activeItem = JSON.parse(savedActiveItem);
|
||||
// } catch (error) {
|
||||
// console.error('Parse activeItem failed:', error);
|
||||
// // 使用默认值
|
||||
// this.activeItem = this.currencyList[0];
|
||||
// }
|
||||
// } else {
|
||||
// // 没有存储值时使用默认值
|
||||
// this.activeItem = this.currencyList[0];
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
this.fetchAllList(this.listParams)
|
||||
|
||||
|
||||
|
||||
},
|
||||
|
@ -386,16 +388,28 @@ export default {
|
|||
const res = await documentsList(params)
|
||||
console.log(res,"res");
|
||||
|
||||
if (res.code === 200) {
|
||||
if (res && res.code === 200) {
|
||||
this.navList = res.rows
|
||||
|
||||
const item = this.navList.find(item => { return item.coin == this.params.coin })
|
||||
|
||||
if (this.$route.query.id) {
|
||||
|
||||
if (item && item.coin) {
|
||||
this.DetailsParams.id= item.id
|
||||
this.DetailsParams.coin = item.coin
|
||||
this.clickJump(item)
|
||||
|
||||
}else if (this.$route.query.id) {
|
||||
this.DetailsParams.id = this.$route.query.id
|
||||
|
||||
}else{
|
||||
this.DetailsParams.id = this.navList[0].id;
|
||||
this.DetailsParams.id = res.rows[0].id;
|
||||
}
|
||||
this.fetchProblemDetails(this.DetailsParams)
|
||||
|
||||
if (this.DetailsParams.id) {
|
||||
this.fetchProblemDetails(this.DetailsParams)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
@ -465,6 +479,8 @@ export default {
|
|||
clickJump(item) {
|
||||
|
||||
this.DetailsParams.id = item.id
|
||||
this.DetailsParams.coin = item.coin
|
||||
this.activeCoin = item.coin
|
||||
this.fetchProblemDetails(this.DetailsParams)
|
||||
// if (!item.path) return; // 添加路径检查
|
||||
// this.activeCoin = item.value
|
||||
|
|
|
@ -50,10 +50,10 @@
|
|||
<section class="menu">
|
||||
|
||||
<ul>
|
||||
|
||||
{{ DetailsParams.coin }}
|
||||
<li
|
||||
|
||||
:class="{ active: DetailsParams.id == item.id }"
|
||||
:class="{ active: DetailsParams.coin == item.coin }"
|
||||
@click="clickJump(item)"
|
||||
v-for="item in navList"
|
||||
:key="item.id"
|
||||
|
@ -61,6 +61,7 @@
|
|||
<img :src="item.titleUrl" alt="coin" />
|
||||
<span>
|
||||
{{ item.title }}
|
||||
{{ item.coin }}
|
||||
</span>
|
||||
</li>
|
||||
<!-- <li
|
||||
|
@ -84,11 +85,11 @@
|
|||
|
||||
<section class="rightContent">
|
||||
<div v-if="tutorialLoading" class="loading-container">
|
||||
<span class="loading-text">正在加载内容...</span>
|
||||
<span class="loading-text">{{ $t('home.loadingContent') || '正在加载内容...' }}</span>
|
||||
</div>
|
||||
<div v-else-if="info && info.trim()" class="dynamic-content" v-html="info"></div>
|
||||
<div v-else class="no-content">
|
||||
<p>暂无内容</p>
|
||||
<p>{{ $t('home.noContent') || '暂无内容' }}</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
@ -794,20 +795,25 @@ export default {
|
|||
.dynamic-content {
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
|
||||
font-family: 'PingFang SC', 'Microsoft YaHei', Arial, sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.7;
|
||||
color: #222;
|
||||
// 富文本样式
|
||||
:deep(table) {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
margin: 16px 0;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
:deep(th), :deep(td) {
|
||||
border: 1px solid #d1d5db;
|
||||
padding: 8px 12px;
|
||||
text-align: left;
|
||||
}
|
||||
:deep(th) {
|
||||
background: #f3f4f6;
|
||||
background: #D2C3EA;
|
||||
font-weight: bold;
|
||||
}
|
||||
:deep(strong), :deep(b) {
|
||||
|
@ -820,13 +826,22 @@ export default {
|
|||
color: inherit !important;
|
||||
}
|
||||
:deep(a) {
|
||||
color: #007bff !important;
|
||||
color: #661FFB !important;
|
||||
text-decoration: none !important;
|
||||
&:hover {
|
||||
text-decoration: underline !important;
|
||||
}
|
||||
}
|
||||
:deep(p) {
|
||||
text-align: justify !important;
|
||||
text-justify: inter-ideograph !important;
|
||||
text-indent: 2em !important;
|
||||
line-height: 2 !important;
|
||||
margin: 0.8em 0 !important;
|
||||
word-break: break-all;
|
||||
}
|
||||
}
|
||||
|
||||
.loading-container {
|
||||
text-align: center;
|
||||
padding: 40px 0;
|
||||
|
|
|
@ -8,11 +8,11 @@
|
|||
</section>
|
||||
<section class="rightContent">
|
||||
<div v-if="problemLoading" class="loading-container">
|
||||
<span class="loading-text">正在加载内容...</span>
|
||||
<span class="loading-text">{{ $t('home.loadingContent') || '正在加载内容...' }}</span>
|
||||
</div>
|
||||
<div v-else-if="info && info.trim()" class="dynamic-content" v-html="info"></div>
|
||||
<div v-else class="no-content">
|
||||
<p>暂无内容</p>
|
||||
<p>{{ $t('home.noContent') || '暂无内容' }}</p>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
|
|
|
@ -7,8 +7,10 @@ export default {
|
|||
listParams: {
|
||||
lang: `${this.$i18n.locale}`,
|
||||
childType: 3,
|
||||
pageNum:1,
|
||||
pageSize:50
|
||||
},
|
||||
navContentParams: {
|
||||
DetailsParams: {
|
||||
lang: `${this.$i18n.locale}`,
|
||||
childType:3,//1服务条款、2费率、3API文档 childType
|
||||
},
|
||||
|
@ -22,16 +24,30 @@ export default {
|
|||
},
|
||||
mounted() {
|
||||
this.getDocumentsList(this.listParams)
|
||||
this.fetchProblemDetails(this.navContentParams)
|
||||
|
||||
},
|
||||
methods: {
|
||||
async getDocumentsList(params) {
|
||||
try {
|
||||
const res = await documentsList(params)
|
||||
console.log(res,"res");
|
||||
if (res && res.code === 200) {
|
||||
this.navList = res.rows
|
||||
|
||||
this.navList = res.data
|
||||
console.log('文档列表:', res)
|
||||
if (this.$route.query.id) {
|
||||
this.DetailsParams.id = this.$route.query.id
|
||||
|
||||
}else{
|
||||
this.DetailsParams.id = res.rows[0].id;
|
||||
}
|
||||
if (this.DetailsParams.id) {
|
||||
this.fetchProblemDetails(this.DetailsParams)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
} catch (error) {
|
||||
console.error('获取文档列表失败:', error)
|
||||
}
|
||||
|
@ -158,6 +174,13 @@ export default {
|
|||
html += '</table>\n'
|
||||
return html
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
clickJump(item) {
|
||||
|
||||
this.DetailsParams.id = item.id
|
||||
this.fetchProblemDetails(this.DetailsParams)
|
||||
|
||||
},
|
||||
}
|
||||
}
|
|
@ -937,9 +937,9 @@
|
|||
<section class="leftMenu">
|
||||
<ul>
|
||||
|
||||
<li>
|
||||
<li v-for="item in navList" :class="{navActive:String(item.id) === String(DetailsParams.id)}" :key="item.id" @click="clickJump(item)">
|
||||
<i class="iconfont icon-baogao file"></i
|
||||
>{{ $t(`apiFile.leftMenu`) }}
|
||||
>{{ item.title}}
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
@ -948,11 +948,11 @@
|
|||
|
||||
<section class="rightContent">
|
||||
<div v-if="documentLoading" class="loading-container">
|
||||
<span class="loading-text">正在加载内容...</span>
|
||||
<span class="loading-text">{{ $t('home.loadingContent') || '正在加载内容...' }}</span>
|
||||
</div>
|
||||
<div v-else-if="info && info.trim()" class="dynamic-content" v-html="info"></div>
|
||||
<div v-else class="no-content">
|
||||
<p>暂无内容</p>
|
||||
<p>{{ $t('home.noContent') || '暂无内容' }}</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
@ -2093,10 +2093,12 @@ a{
|
|||
|
||||
ul {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
li {
|
||||
width: 100%;
|
||||
list-style: none;
|
||||
min-height: 40px;
|
||||
display: flex;
|
||||
|
@ -2460,20 +2462,49 @@ a{
|
|||
.dynamic-content {
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
|
||||
font-family: 'PingFang SC', 'Microsoft YaHei', Arial, sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.7;
|
||||
color: #222;
|
||||
|
||||
// 富文本样式
|
||||
:deep(table) {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
margin: 16px 0;
|
||||
font-size: 14px;
|
||||
}
|
||||
:deep(ul) {
|
||||
background: #f4f4f4;
|
||||
padding: 10px;
|
||||
padding-left: 18px;
|
||||
|
||||
}
|
||||
:deep(li) {
|
||||
margin-top: 10px;
|
||||
|
||||
}
|
||||
:deep(code) {
|
||||
line-height: 1px !important;
|
||||
|
||||
|
||||
}
|
||||
:deep(span) {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
:deep(pre) {
|
||||
background: #f4f4f4;
|
||||
line-height: 1 !important;
|
||||
padding: 18px 8px;
|
||||
}
|
||||
|
||||
:deep(th), :deep(td) {
|
||||
border: 1px solid #d1d5db;
|
||||
padding: 8px 12px;
|
||||
text-align: left;
|
||||
}
|
||||
:deep(th) {
|
||||
background: #f3f4f6;
|
||||
background: #D2C3EA;
|
||||
font-weight: bold;
|
||||
}
|
||||
:deep(strong), :deep(b) {
|
||||
|
@ -2486,12 +2517,25 @@ a{
|
|||
color: inherit !important;
|
||||
}
|
||||
:deep(a) {
|
||||
color: #007bff !important;
|
||||
color: #661FFB !important;
|
||||
text-decoration: none !important;
|
||||
&:hover {
|
||||
text-decoration: underline !important;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(p) {
|
||||
text-align: justify !important;
|
||||
text-justify: inter-ideograph !important;
|
||||
|
||||
line-height: 2 !important;
|
||||
margin: 0.8em 0 !important;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/* 加载动画 */
|
||||
|
@ -2521,4 +2565,8 @@ a{
|
|||
padding: 25px 15px;
|
||||
}
|
||||
}
|
||||
|
||||
.navActive{
|
||||
background: #AC85E0 !important;
|
||||
}
|
||||
</style>
|
|
@ -8,11 +8,11 @@
|
|||
</section>
|
||||
<section class="rightContent">
|
||||
<div v-if="problemLoading" class="loading-container">
|
||||
<span class="loading-text">正在加载内容...</span>
|
||||
<span class="loading-text">{{ $t('home.loadingContent') || '正在加载内容...' }}</span>
|
||||
</div>
|
||||
<div v-else-if="info && info.trim()" class="dynamic-content" v-html="info"></div>
|
||||
<div v-else class="no-content">
|
||||
<p>暂无内容</p>
|
||||
<p>{{ $t('home.noContent') || '暂无内容' }}</p>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
|
|
|
@ -2,17 +2,17 @@ import { findDataInfo } from "../../../api/documentManagement"
|
|||
export default{
|
||||
data(){
|
||||
return{
|
||||
|
||||
typeArray:[],
|
||||
|
||||
}
|
||||
},
|
||||
mounted(){
|
||||
// this.fetchDataInfo()
|
||||
|
||||
|
||||
|
||||
if (this.$route.query.id) {
|
||||
this.fetchDataInfo({id:this.$route.query.id})
|
||||
}
|
||||
// if (this.$route.query.id) {
|
||||
// this.fetchDataInfo({id:this.$route.query.id})
|
||||
// }
|
||||
|
||||
},
|
||||
methods:{
|
||||
|
@ -20,13 +20,49 @@ export default{
|
|||
const res = await findDataInfo(params)
|
||||
if (res && res.code === 200) {
|
||||
this.modifyData = res.data
|
||||
this.addParams.content = this.modifyData.content
|
||||
this.addParams = this.modifyData
|
||||
// 确保type字段为字符串类型,以便与TypeList中的value匹配
|
||||
this.addParams.type = String(this.addParams.type)
|
||||
|
||||
|
||||
|
||||
this.addParams.childType = String(this.addParams.childType)
|
||||
this.typeArray = [this.addParams.type]
|
||||
// 标记已从后台获取数据,避免被本地存储覆盖
|
||||
this.hasBackendData = true
|
||||
// 强制用接口数据刷新编辑器内容
|
||||
if (this.editor && this.addParams.content) {
|
||||
this.editor.txt.html(this.addParams.content)
|
||||
this.html = this.addParams.content
|
||||
}
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 币种选择变更处理
|
||||
* @param {string} scope - 选择的币种
|
||||
*/
|
||||
changeScreen(scope) {
|
||||
let brand = scope
|
||||
for (let index in this.currencyList) {
|
||||
let aa = this.currencyList[index];
|
||||
let value = aa.value;
|
||||
if (brand === value) {
|
||||
this.$refs.screen.$el.children[0].children[0].setAttribute('style', "background:url(" + aa.imgUrl + ") no-repeat 10PX;background-size: 20PX 20PX;color:#333;padding-left: 33PX;");
|
||||
}
|
||||
}
|
||||
|
||||
// 保存用户选择的币种到localStorage
|
||||
localStorage.setItem('userManagement_selectedCurrency', scope);
|
||||
|
||||
|
||||
|
||||
},
|
||||
|
||||
handleClearScreen(){
|
||||
// 清除币种图片样式
|
||||
if (this.$refs.screen && this.$refs.screen.$el) {
|
||||
this.$refs.screen.$el.children[0].children[0].style.background = '';
|
||||
this.$refs.screen.$el.children[0].children[0].style.paddingLeft = '';
|
||||
}
|
||||
// 也可以清除 localStorage 里的币种选择
|
||||
localStorage.removeItem('userManagement_selectedCurrency');
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,29 +1,49 @@
|
|||
<template>
|
||||
<div class="editor-page" v-loading="addLoading">
|
||||
<div
|
||||
class="editor-page"
|
||||
v-loading="addLoading"
|
||||
:class="{ 'no-scroll': addLoading }"
|
||||
>
|
||||
<h2 style="margin-bottom: 20px">
|
||||
{{ $t("backendSystem.addDocument") || "新增文档" }}
|
||||
</h2>
|
||||
|
||||
<!-- 页面头部 -->
|
||||
|
||||
<div class="page-header">
|
||||
<div class="header-left">
|
||||
<div class="title-section">
|
||||
<i class="el-icon-edit-outline title-icon"></i>
|
||||
<h1 class="page-title">wangeditor 富文本文档编辑器</h1>
|
||||
<h1 class="page-title">
|
||||
{{
|
||||
$t("backendSystem.wangeditor") || "wangeditor 富文本文档编辑器"
|
||||
}}
|
||||
</h1>
|
||||
</div>
|
||||
<p class="page-description">
|
||||
使用富文本编辑器创建和管理文档,支持文本格式化、链接、列表等功能
|
||||
</p>
|
||||
</div>
|
||||
<div class="header-actions">
|
||||
<el-button
|
||||
type="primary"
|
||||
icon="el-icon-link"
|
||||
@click="handleInsertAnchor"
|
||||
>
|
||||
{{ $t("backendSystem.insertAnchor") || "插入锚点" }}
|
||||
</el-button>
|
||||
<el-button type="info" icon="el-icon-view" @click="handlePreview">
|
||||
预览文档
|
||||
{{ $t("backendSystem.previewDocument") || "预览文档" }}
|
||||
</el-button>
|
||||
<el-button type="success" icon="el-icon-document" @click="handleSave">
|
||||
保存文档
|
||||
{{ $t("backendSystem.saveDocument") || "保存文档" }}
|
||||
</el-button>
|
||||
<el-button
|
||||
type="warning"
|
||||
icon="el-icon-upload2"
|
||||
@click="handelAddDocument"
|
||||
>
|
||||
发布文档
|
||||
{{ $t("backendSystem.publishDocument") || "发布文档" }}
|
||||
</el-button>
|
||||
<el-button type="danger" icon="el-icon-delete" @click="handleReset">
|
||||
{{ $t("backendSystem.reset") || "重置" }}
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -32,49 +52,45 @@
|
|||
<div class="config-section">
|
||||
<div class="section-header">
|
||||
<i class="el-icon-setting"></i>
|
||||
<span>文档配置</span>
|
||||
<span>{{
|
||||
$t("backendSystem.documentConfiguration") || "文档配置"
|
||||
}}</span>
|
||||
</div>
|
||||
|
||||
<div class="config-content">
|
||||
<div class="config-row">
|
||||
<div class="config-item">
|
||||
<label>导航标题</label>
|
||||
<label>{{
|
||||
$t("backendSystem.navigationTitle") || "导航标题"
|
||||
}}</label>
|
||||
<el-input
|
||||
v-model="addParams.title"
|
||||
placeholder="请输入文档标题"
|
||||
:placeholder="
|
||||
$t('backendSystem.pleaseInputDocumentTitle') || '请输入文档标题'
|
||||
"
|
||||
@input="handleAutoSave"
|
||||
size="medium"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="config-item">
|
||||
<label class="required">文档类型</label>
|
||||
<label class="required">{{
|
||||
$t("backendSystem.documentType") || "文档类型"
|
||||
}}</label>
|
||||
<el-cascader
|
||||
:options="TypeList"
|
||||
v-model="typeArray"
|
||||
@change="handleAutoSaveType(typeArray)"
|
||||
clearable
|
||||
placeholder="请选择文档类型"
|
||||
:placeholder="
|
||||
$t('backendSystem.pleaseSelectDocumentType') || '请选择文档类型'
|
||||
"
|
||||
:props="{
|
||||
label: 'label',
|
||||
value: 'value',
|
||||
children: 'children',
|
||||
}"
|
||||
/>
|
||||
<!-- <el-select
|
||||
v-model="addParams.type"
|
||||
placeholder="请选择文档类型"
|
||||
@change="handleAutoSaveType(addParams.type)"
|
||||
size="medium"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in TypeList"
|
||||
:key="item.value"
|
||||
:label="$t(item.label)"
|
||||
:value="item.value"
|
||||
>
|
||||
</el-option>
|
||||
</el-select> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -82,75 +98,102 @@
|
|||
<div class="config-content">
|
||||
<div class="config-row">
|
||||
<div class="config-item">
|
||||
<label>标题图片地址</label>
|
||||
<label>{{
|
||||
$t("backendSystem.titleImageAddress") || "标题图片地址"
|
||||
}}</label>
|
||||
<el-input
|
||||
v-model="addParams.titleUrl"
|
||||
placeholder="请输入图片地址"
|
||||
:placeholder="
|
||||
$t('backendSystem.pleaseInputImageAddress') || '请输入图片地址'
|
||||
"
|
||||
@input="handleAutoSave"
|
||||
size="medium"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="config-item">
|
||||
<label>文章访问地址</label>
|
||||
<label>{{
|
||||
$t("backendSystem.articleAccessAddress") || "文章访问地址"
|
||||
}}</label>
|
||||
<el-input
|
||||
v-model="addParams.articleUrl"
|
||||
placeholder="请输入访问地址"
|
||||
:placeholder="
|
||||
$t('backendSystem.pleaseInputAccessAddress') || '请输入访问地址'
|
||||
"
|
||||
@input="handleAutoSave"
|
||||
size="medium"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="config-content">
|
||||
<div class="config-row">
|
||||
<div class="config-item">
|
||||
<label >{{
|
||||
$t("backendSystem.coin2") || "币种"
|
||||
}}</label>
|
||||
<el-select
|
||||
class="input"
|
||||
size="middle"
|
||||
ref="screen"
|
||||
@change="changeScreen(screenCurrency)"
|
||||
v-model="screenCurrency"
|
||||
clearable
|
||||
@clear="handleClearScreen"
|
||||
:placeholder="$t(`backendSystem.selectCurrency`)"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in currencyList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
>
|
||||
|
||||
<div style="display: flex; align-items: center">
|
||||
<img :src="item.imgUrl" style="float: left; width: 20px" />
|
||||
<span style="float: left; margin-left: 5px">
|
||||
{{ item.label }}</span
|
||||
>
|
||||
</div>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 编辑器区域 -->
|
||||
<div class="editor-section">
|
||||
<div class="section-header">
|
||||
<i class="el-icon-edit-outline"></i>
|
||||
<span>富文本编辑器</span>
|
||||
<span>{{ $t("backendSystem.richTextEditor") || "富文本编辑器" }}</span>
|
||||
</div>
|
||||
|
||||
<div class="editor-container">
|
||||
<Toolbar
|
||||
:editor="editor"
|
||||
:defaultConfig="toolbarConfig"
|
||||
:mode="mode"
|
||||
style="border-bottom: 1px solid #ccc"
|
||||
/>
|
||||
<Editor
|
||||
style="height: 600px; overflow-y: hidden"
|
||||
v-model="addParams.content"
|
||||
:defaultConfig="editorConfig"
|
||||
:mode="mode"
|
||||
@onCreated="onCreated"
|
||||
@onChange="handleEditorChange"
|
||||
/>
|
||||
<div ref="editor" style="height: 600px"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 预览文档对话框 -->
|
||||
<el-dialog
|
||||
title="文档预览"
|
||||
:title="$t('backendSystem.documentPreview') || '文档预览'"
|
||||
:visible.sync="previewVisible"
|
||||
width="80%"
|
||||
:before-close="handlePreviewClose"
|
||||
class="preview-dialog"
|
||||
class="preview-dialog wangeditor-preview"
|
||||
>
|
||||
<div class="preview-content">
|
||||
<div v-html="addParams.content" class="dynamic-content"></div>
|
||||
|
||||
<div v-if="!addParams.content" class="preview-empty">
|
||||
<i class="el-icon-document"></i>
|
||||
<p>暂无内容</p>
|
||||
<p>{{ $t("backendSystem.noContent") || "暂无内容" }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="previewVisible = false">关闭</el-button>
|
||||
<el-button type="primary" @click="handlePrintPreview"
|
||||
>打印预览</el-button
|
||||
>
|
||||
<el-button @click="previewVisible = false">{{
|
||||
$t("backendSystem.close") || "关闭"
|
||||
}}</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
|
@ -158,36 +201,16 @@
|
|||
|
||||
<script>
|
||||
import Vue from "vue";
|
||||
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
|
||||
import E from "wangeditor";
|
||||
import { addDocument } from "../../../api/documentManagement";
|
||||
import Index from "./index";
|
||||
export default Vue.extend({
|
||||
components: { Editor, Toolbar },
|
||||
mixins: [Index],
|
||||
data() {
|
||||
return {
|
||||
editor: null,
|
||||
html: "<p>hello</p>",
|
||||
toolbarConfig: {
|
||||
excludeKeys: [],
|
||||
insertKeys: {
|
||||
index: 0,
|
||||
keys: [
|
||||
"bold",
|
||||
"italic",
|
||||
"underline",
|
||||
"through",
|
||||
"code",
|
||||
"sub",
|
||||
"sup",
|
||||
"clearStyle",
|
||||
],
|
||||
},
|
||||
},
|
||||
editorConfig: {
|
||||
placeholder: "请在此输入文档内容...",
|
||||
MENU_CONF: {},
|
||||
},
|
||||
html: "", // 编辑器内容
|
||||
hasSetEditorContent: false, // 避免重复 set 内容
|
||||
mode: "default",
|
||||
addParams: {
|
||||
title: "",
|
||||
|
@ -196,7 +219,8 @@ export default Vue.extend({
|
|||
lang: "",
|
||||
titleUrl: "",
|
||||
articleUrl: "",
|
||||
childType:""
|
||||
childType: "",
|
||||
coin: "",
|
||||
},
|
||||
lastSaveTime: "",
|
||||
autoSaveTimer: null,
|
||||
|
@ -224,15 +248,19 @@ export default Vue.extend({
|
|||
|
||||
addLoading: false,
|
||||
typeArray: [],
|
||||
currencyList: [],
|
||||
screenCurrency: "",
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
|
||||
|
||||
|
||||
this.currencyList = JSON.parse(localStorage.getItem("currencyList"));
|
||||
window.addEventListener("setItem", () => {
|
||||
this.currencyList = JSON.parse(localStorage.getItem("currencyList"));
|
||||
});
|
||||
try {
|
||||
this.TypeList = JSON.parse(localStorage.getItem("TypeList"));
|
||||
this.TypeList = this.TypeList.map((item) => ({ // 翻译label
|
||||
this.TypeList = this.TypeList.map((item) => ({
|
||||
// 翻译label
|
||||
...item,
|
||||
label: this.$t(item.label),
|
||||
children: item.children
|
||||
|
@ -242,7 +270,6 @@ export default Vue.extend({
|
|||
}))
|
||||
: undefined,
|
||||
}));
|
||||
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
@ -253,39 +280,134 @@ export default Vue.extend({
|
|||
// 添加页面卸载前的保存保护
|
||||
window.addEventListener("beforeunload", this.handleBeforeUnload);
|
||||
|
||||
// 延迟设置默认内容,避免覆盖恢复的数据
|
||||
setTimeout(() => {
|
||||
if (!this.addParams.content) {
|
||||
this.html = "<p>模拟 Ajax 异步设置内容 HTML</p>";
|
||||
}
|
||||
}, 1500);
|
||||
// 删除默认内容设置,保持编辑器初始化为空
|
||||
// setTimeout(() => {
|
||||
// if (!this.addParams.content) {
|
||||
// this.html = "<p>模拟 Ajax 异步设置内容 HTML</p>";
|
||||
// }
|
||||
// }, 1500);
|
||||
|
||||
this.editor = new E(this.$refs.editor);
|
||||
this.editor.config.height = 600;
|
||||
this.editor.config.onchange = (html) => {
|
||||
this.html = html;
|
||||
this.addParams.content = html;
|
||||
};
|
||||
//配置颜色
|
||||
this.editor.config.colors = [
|
||||
`#651FFF`,
|
||||
`#FF4081`,
|
||||
`#FF9900`,
|
||||
`#FFC107`,
|
||||
`#FF5722`,
|
||||
`#9C27B0`,
|
||||
`#673AB7`,
|
||||
`#3F51B5`,
|
||||
"#000000", // 黑色
|
||||
"#ffffff", // 白色
|
||||
"#eeece0", // 浅米色
|
||||
"#1c487f", // 深蓝
|
||||
"#4d80bf", // 蓝色
|
||||
"#c24f4a", // 红色
|
||||
"#8baa4a", // 绿色
|
||||
"#a96b59", // 棕色
|
||||
"#2b2b2b", // 深灰
|
||||
"#b6975a", // 金色
|
||||
"#5b9bd5", // 天蓝
|
||||
"#70ad47", // 草绿
|
||||
"#ed7d31", // 橙色
|
||||
"#ffc000", // 黄色
|
||||
"#7030a0", // 紫色
|
||||
"#f4b084", // 浅橙
|
||||
"#bdd7ee", // 浅蓝
|
||||
"#a9d08e", // 浅绿
|
||||
"#ffe699", // 浅黄
|
||||
"#d9d9d9", // 浅灰
|
||||
"#f8cbad", // 浅棕
|
||||
"#e2efda", // 淡绿
|
||||
"#fff2cc", // 淡黄
|
||||
"#dbe5f1", // 淡蓝
|
||||
"#e4dfec", // 淡紫
|
||||
"#fbeee6", // 淡橙
|
||||
"#f6f6f6", // 极浅灰
|
||||
"#ff0000", // 纯红
|
||||
"#00b050", // 纯绿
|
||||
"#0070c0", // 纯蓝
|
||||
"#7030a0", // 纯紫
|
||||
"#ff9900", // 纯橙
|
||||
"#808080", // 中灰
|
||||
];
|
||||
//配置字体
|
||||
(this.editor.config.fontNames = [
|
||||
// 对象形式 v4.6.16
|
||||
{ name: "黑体", value: "黑体" },
|
||||
{ name: "绝绝字体", value: "Times New Roman" },
|
||||
// 字符串形式
|
||||
"黑体",
|
||||
"仿宋",
|
||||
"楷体",
|
||||
"标楷体",
|
||||
"华文仿宋",
|
||||
"华文楷体",
|
||||
"宋体",
|
||||
"微软雅黑",
|
||||
"Arial",
|
||||
"Tahoma",
|
||||
"Verdana",
|
||||
"Times New Roman",
|
||||
"Courier New",
|
||||
]),
|
||||
// 不自定义菜单,使用官方默认菜单栏
|
||||
this.editor.create();
|
||||
// 只在初始化时 set 一次内容
|
||||
if (this.addParams.content && !this.hasSetEditorContent) {
|
||||
this.editor.txt.html(this.addParams.content);
|
||||
this.html = this.addParams.content;
|
||||
this.hasSetEditorContent = true;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async fetchAddDocument(params) {
|
||||
this.setLoading("addLoading", true);
|
||||
const res = await addDocument(params);
|
||||
if (res && res.code == 200) {
|
||||
this.$message.success(this.$t("backendSystem.addSuccess"));
|
||||
this.$message.success(this.$t("backendSystem.updateSuccess"));
|
||||
// 发布成功后清除本地草稿
|
||||
const LOCAL_STORAGE_KEY = "editor_draft_add";
|
||||
localStorage.removeItem(LOCAL_STORAGE_KEY);
|
||||
this.$router.push({ path: `/${this.$i18n.locale}/documentManagement` });
|
||||
for (const key in this.addParams) {
|
||||
this.addParams[key] = "";
|
||||
}
|
||||
if (this.editor) {
|
||||
this.editor.txt.clear();
|
||||
}
|
||||
}
|
||||
this.setLoading("addLoading", false);
|
||||
},
|
||||
|
||||
/**
|
||||
* 编辑器创建后回调,确保 this.editor 正确赋值
|
||||
* @param {Object} editor wangEditor 实例
|
||||
*/
|
||||
onCreated(editor) {
|
||||
this.editor = Object.seal(editor);
|
||||
this.editor = editor;
|
||||
console.log("编辑器已初始化", this.editor);
|
||||
|
||||
// 编辑器创建后,如果有恢复的内容,设置到编辑器中
|
||||
if (this.addParams.content) {
|
||||
this.$nextTick(() => {
|
||||
editor.setHtml(this.addParams.content);
|
||||
this.editor.txt.html(this.addParams.content);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
handelAddDocument() {
|
||||
if (!this.addParams.type) {
|
||||
if (!this.addParams.type || this.addParams.type == "0") {
|
||||
this.$message({
|
||||
message: "请填写文档类型",
|
||||
message:
|
||||
this.$t("backendSystem.pleaseSelectDocumentType") ||
|
||||
"请填写文档类型",
|
||||
type: "warning",
|
||||
duration: 4000,
|
||||
showClose: true,
|
||||
|
@ -293,11 +415,31 @@ export default Vue.extend({
|
|||
return;
|
||||
}
|
||||
|
||||
// 确保获取最新的编辑器内容
|
||||
if (this.editor) {
|
||||
this.addParams.content = this.editor.getHtml();
|
||||
|
||||
if (this.addParams.type == "1" && !this.screenCurrency) {
|
||||
this.$message({
|
||||
message:
|
||||
this.$t("backendSystem.pleaseSelectCurrency2") ||
|
||||
"添加挖矿教程,请选择币种",
|
||||
type: "warning",
|
||||
duration: 4000,
|
||||
showClose: true,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.addParams.content) {
|
||||
//锚点定位的A标签 去掉target="_blank"
|
||||
this.addParams.content = this.addParams.content.replace(
|
||||
/<a([^>]*href="#[^"]*")[^>]*>/gi,
|
||||
function (match) {
|
||||
return match.replace(/\s*target="_blank"/gi, "");
|
||||
}
|
||||
);
|
||||
}
|
||||
this.addParams.coin = this.screenCurrency
|
||||
console.log(this.addParams.content, "this.addParams.content");
|
||||
|
||||
this.fetchAddDocument(this.addParams);
|
||||
},
|
||||
|
||||
|
@ -317,49 +459,20 @@ export default Vue.extend({
|
|||
this.previewVisible = false;
|
||||
},
|
||||
|
||||
handlePrintPreview() {
|
||||
const printWindow = window.open("", "_blank");
|
||||
if (printWindow) {
|
||||
printWindow.document.write(`
|
||||
<html>
|
||||
<head>
|
||||
<title>${this.addParams.title || "文档预览"}</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: 'Arial', sans-serif;
|
||||
line-height: 1.6;
|
||||
color: #333;
|
||||
margin: 20px;
|
||||
}
|
||||
.preview-empty {
|
||||
text-align: center;
|
||||
padding: 50px 0;
|
||||
color: #95a5a6;
|
||||
}
|
||||
.preview-empty i {
|
||||
font-size: 40px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
${
|
||||
this.addParams.content ||
|
||||
'<div class="preview-empty"><i>📄</i><p>暂无内容</p></div>'
|
||||
}
|
||||
</body>
|
||||
</html>
|
||||
`);
|
||||
printWindow.document.close();
|
||||
printWindow.print();
|
||||
printWindow.close();
|
||||
}
|
||||
},
|
||||
|
||||
handleSave() {
|
||||
// 保存前彻底去除所有锚点链接的 target="_blank"
|
||||
this.addParams.content = this.addParams.content.replace(
|
||||
/<a([^>]*href="#([^"]*)")[^>]*>/gi,
|
||||
function (match) {
|
||||
// 去掉 target="_blank"
|
||||
return match.replace(/\s*target="_blank"/gi, "");
|
||||
}
|
||||
);
|
||||
this.manualSave();
|
||||
this.$message({
|
||||
message: "内容已保存到本地,请尽快发布,关闭页面可能丢失内容",
|
||||
message:
|
||||
this.$t("backendSystem.contentSaved") ||
|
||||
"内容已保存到本地,请尽快发布,关闭页面可能丢失内容",
|
||||
type: "success",
|
||||
duration: 4000,
|
||||
showClose: true,
|
||||
|
@ -378,7 +491,7 @@ export default Vue.extend({
|
|||
this.addParams.articleUrl = "";
|
||||
}
|
||||
this.addParams.type = type[0];
|
||||
this.addParams.childType= type[1];
|
||||
this.addParams.childType = type[1];
|
||||
} catch (error) {
|
||||
console.log(error, "error");
|
||||
}
|
||||
|
@ -420,7 +533,7 @@ export default Vue.extend({
|
|||
try {
|
||||
// 确保获取最新的编辑器内容
|
||||
if (this.editor) {
|
||||
this.addParams.content = this.editor.getHtml();
|
||||
this.addParams.content = this.editor.txt.html();
|
||||
}
|
||||
|
||||
const saveData = {
|
||||
|
@ -439,7 +552,8 @@ export default Vue.extend({
|
|||
lastModified: Date.now(),
|
||||
};
|
||||
|
||||
localStorage.setItem("editor_draft", JSON.stringify(saveData));
|
||||
const LOCAL_STORAGE_KEY = "editor_draft_add";
|
||||
localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(saveData));
|
||||
this.lastSaveTime = saveData.timestamp;
|
||||
this.isSaving = false;
|
||||
} catch (error) {
|
||||
|
@ -450,7 +564,8 @@ export default Vue.extend({
|
|||
|
||||
loadFromLocalStorage() {
|
||||
try {
|
||||
const savedData = localStorage.getItem("editor_draft");
|
||||
const LOCAL_STORAGE_KEY = "editor_draft_add";
|
||||
const savedData = localStorage.getItem(LOCAL_STORAGE_KEY);
|
||||
if (savedData) {
|
||||
const data = JSON.parse(savedData);
|
||||
|
||||
|
@ -460,7 +575,7 @@ export default Vue.extend({
|
|||
|
||||
if (isExpired) {
|
||||
console.log("本地数据已过期,清除缓存");
|
||||
localStorage.removeItem("editor_draft");
|
||||
localStorage.removeItem(LOCAL_STORAGE_KEY);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -474,7 +589,7 @@ export default Vue.extend({
|
|||
|
||||
// 如果编辑器已经创建,直接设置内容
|
||||
if (this.editor) {
|
||||
this.editor.setHtml(data.content || "");
|
||||
this.editor.txt.html(data.content || "");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -484,7 +599,8 @@ export default Vue.extend({
|
|||
},
|
||||
|
||||
clearDraft() {
|
||||
localStorage.removeItem("editor_draft");
|
||||
const LOCAL_STORAGE_KEY = "editor_draft_add";
|
||||
localStorage.removeItem(LOCAL_STORAGE_KEY);
|
||||
this.lastSaveTime = "";
|
||||
this.isSaving = false;
|
||||
},
|
||||
|
@ -493,7 +609,7 @@ export default Vue.extend({
|
|||
manualSave() {
|
||||
// 确保获取最新的编辑器内容
|
||||
if (this.editor) {
|
||||
this.addParams.content = this.editor.getHtml();
|
||||
this.addParams.content = this.editor.txt.html();
|
||||
}
|
||||
this.saveToLocalStorage();
|
||||
},
|
||||
|
@ -504,7 +620,7 @@ export default Vue.extend({
|
|||
if (this.addParams.title || this.addParams.content) {
|
||||
// 确保获取最新的编辑器内容
|
||||
if (this.editor) {
|
||||
this.addParams.content = this.editor.getHtml();
|
||||
this.addParams.content = this.editor.txt.html();
|
||||
}
|
||||
this.saveToLocalStorage();
|
||||
}
|
||||
|
@ -525,31 +641,110 @@ export default Vue.extend({
|
|||
return "未知类型";
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 插入锚点(源码模式下插入HTML)
|
||||
*/
|
||||
handleInsertAnchor() {
|
||||
if (!this.editor) {
|
||||
this.$message.warning("编辑器尚未初始化");
|
||||
return;
|
||||
}
|
||||
this.$prompt(
|
||||
this.$t("backendSystem.pleaseInputAnchorName") ||
|
||||
"请输入锚点名称(不能重复)",
|
||||
this.$t("backendSystem.insertAnchor") || "插入锚点",
|
||||
{
|
||||
confirmButtonText: this.$t("backendSystem.confirm") || "确定",
|
||||
cancelButtonText: this.$t("backendSystem.cancel") || "取消",
|
||||
inputPattern: /^[a-zA-Z0-9_-]+$/,
|
||||
inputErrorMessage:
|
||||
this.$t("backendSystem.anchorNameErrorMessage") ||
|
||||
"锚点名只能包含字母、数字、下划线和中划线",
|
||||
}
|
||||
)
|
||||
.then(({ value }) => {
|
||||
this.editor.cmd.do("insertHTML", `<span id="${value}"></span>`);
|
||||
this.html = this.editor.txt.html();
|
||||
this.addParams.content = this.html;
|
||||
this.$message.success(
|
||||
this.$t("backendSystem.anchorInserted") || "锚点已插入"
|
||||
);
|
||||
})
|
||||
.catch(() => {});
|
||||
},
|
||||
|
||||
/**
|
||||
* 给选中的标题添加id属性作为锚点
|
||||
*/
|
||||
handleAddHeadingId() {
|
||||
if (!this.editor) {
|
||||
this.$message.warning("编辑器尚未初始化");
|
||||
return;
|
||||
}
|
||||
// 获取当前选中的标题节点
|
||||
const headers = this.editor.getElemsByTypePrefix("header");
|
||||
if (!headers || headers.length === 0) {
|
||||
this.$message.warning(
|
||||
this.$t("backendSystem.pleaseSelectHeader") ||
|
||||
"请先选中一个标题(h1~h6)"
|
||||
);
|
||||
return;
|
||||
}
|
||||
const node = headers[0];
|
||||
this.$prompt(
|
||||
this.$t("backendSystem.pleaseInputAnchorID") ||
|
||||
"请输入锚点ID(不能重复)",
|
||||
this.$t("backendSystem.titleAnchor") || "标题锚点",
|
||||
{
|
||||
confirmButtonText: this.$t("backendSystem.confirm") || "确定",
|
||||
cancelButtonText: this.$t("backendSystem.cancel") || "取消",
|
||||
inputPattern: /^[a-zA-Z0-9_-]+$/,
|
||||
inputErrorMessage:
|
||||
this.$t("backendSystem.anchorIDErrorMessage") ||
|
||||
"ID只能包含字母、数字、下划线和中划线",
|
||||
}
|
||||
)
|
||||
.then(({ value }) => {
|
||||
this.editor.setElemAttribute(node, "id", value);
|
||||
this.$message.success(
|
||||
this.$t("backendSystem.anchorIDAdded") || "锚点ID已添加"
|
||||
);
|
||||
})
|
||||
.catch(() => {});
|
||||
},
|
||||
|
||||
/**
|
||||
* 重置表单和编辑器内容
|
||||
*/
|
||||
handleReset() {
|
||||
// 清空表单数据
|
||||
for (const key in this.addParams) {
|
||||
this.addParams[key] = "";
|
||||
}
|
||||
// 清空富文本编辑器内容
|
||||
if (this.editor) {
|
||||
this.editor.txt.clear();
|
||||
}
|
||||
// 清除本地草稿
|
||||
const LOCAL_STORAGE_KEY = "editor_draft_add";
|
||||
localStorage.removeItem(LOCAL_STORAGE_KEY);
|
||||
this.$message.success(
|
||||
this.$t("backendSystem.contentReset") || "内容已重置"
|
||||
);
|
||||
},
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
// 确保获取最新的编辑器内容
|
||||
if (this.editor) {
|
||||
this.addParams.content = this.editor.getHtml();
|
||||
this.editor.destroy();
|
||||
}
|
||||
this.saveToLocalStorage();
|
||||
|
||||
// 移除事件监听器
|
||||
window.removeEventListener("beforeunload", this.handleBeforeUnload);
|
||||
|
||||
if (this.autoSaveTimer) {
|
||||
clearTimeout(this.autoSaveTimer);
|
||||
}
|
||||
|
||||
const editor = this.editor;
|
||||
if (editor == null) return;
|
||||
editor.destroy();
|
||||
},
|
||||
|
||||
beforeRouteLeave(to, from, next) {
|
||||
// 确保获取最新的编辑器内容
|
||||
if (this.editor) {
|
||||
this.addParams.content = this.editor.getHtml();
|
||||
this.addParams.content = this.editor.txt.html();
|
||||
}
|
||||
this.saveToLocalStorage();
|
||||
next();
|
||||
|
@ -704,12 +899,20 @@ export default Vue.extend({
|
|||
overflow: hidden;
|
||||
background: white;
|
||||
min-height: 650px;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/* 设置编辑器高度 */
|
||||
.editor-container .w-e-text-container {
|
||||
::v-deep .editor-container .w-e-text-container {
|
||||
height: 600px !important;
|
||||
min-height: 600px !important;
|
||||
z-index: 1 !important;
|
||||
position: relative;
|
||||
}
|
||||
::v-deep .w-e-toolbar {
|
||||
z-index: 10 !important;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* 编辑器内容区域样式 */
|
||||
|
@ -752,6 +955,7 @@ export default Vue.extend({
|
|||
padding: 20px;
|
||||
max-height: 70vh;
|
||||
overflow-y: auto;
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
.preview-dialog .el-dialog__header {
|
||||
|
@ -876,46 +1080,47 @@ export default Vue.extend({
|
|||
font-weight: 500;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* -------富文本样式-------------- */
|
||||
.dynamic-content {
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
|
||||
|
||||
:deep(table) {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
margin: 16px 0;
|
||||
}
|
||||
:deep(th), :deep(td) {
|
||||
border: 1px solid #d1d5db;
|
||||
padding: 8px 12px;
|
||||
text-align: left;
|
||||
}
|
||||
:deep(th) {
|
||||
background: #f3f4f6;
|
||||
font-weight: bold;
|
||||
}
|
||||
:deep(strong), :deep(b) {
|
||||
font-weight: bold !important;
|
||||
color: inherit !important;
|
||||
font-style: normal !important;
|
||||
}
|
||||
:deep(em), :deep(i) {
|
||||
font-style: italic !important;
|
||||
color: inherit !important;
|
||||
}
|
||||
:deep(a) {
|
||||
color: #007bff !important;
|
||||
text-decoration: none !important;
|
||||
&:hover {
|
||||
text-decoration: underline !important;
|
||||
}
|
||||
}
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
|
||||
:deep(table) {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
margin: 16px 0;
|
||||
}
|
||||
:deep(th),
|
||||
:deep(td) {
|
||||
border: 1px solid #d1d5db;
|
||||
padding: 8px 12px;
|
||||
text-align: left;
|
||||
}
|
||||
:deep(th) {
|
||||
background: #f3f4f6;
|
||||
font-weight: bold;
|
||||
}
|
||||
:deep(strong),
|
||||
:deep(b) {
|
||||
font-weight: bold !important;
|
||||
color: inherit !important;
|
||||
font-style: normal !important;
|
||||
}
|
||||
:deep(em),
|
||||
:deep(i) {
|
||||
font-style: italic !important;
|
||||
color: inherit !important;
|
||||
}
|
||||
:deep(a) {
|
||||
color: #007bff !important;
|
||||
text-decoration: none !important;
|
||||
&:hover {
|
||||
text-decoration: underline !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<style src="@wangeditor/editor/dist/css/style.css"></style>
|
||||
.no-scroll {
|
||||
overflow: hidden !important;
|
||||
}
|
||||
</style>
|
|
@ -13,7 +13,7 @@
|
|||
class="demo-form-inline"
|
||||
ref="formRef"
|
||||
>
|
||||
<el-form-item label="文档类型" prop="type">
|
||||
<el-form-item :label="$t('backendSystem.documentType')|| '文档类型'" prop="type">
|
||||
<el-select
|
||||
class="input"
|
||||
clearable
|
||||
|
@ -38,7 +38,7 @@
|
|||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="搜索" style="margin-left: 5vw" prop="minerUser">
|
||||
<el-form-item :label="$t('backendSystem.search')|| '搜索'" style="margin-left: 5vw" prop="minerUser">
|
||||
<el-input
|
||||
v-model="queryParams.keyword"
|
||||
:placeholder="$t('backendSystem.pleaseInput')"
|
||||
|
@ -65,7 +65,7 @@
|
|||
<el-table-column prop="id" label="ID" width="60" />
|
||||
<el-table-column
|
||||
prop="createTime"
|
||||
label="创建时间"
|
||||
:label="$t('backendSystem.createTime')|| '创建时间'"
|
||||
width="160"
|
||||
show-overflow-tooltip
|
||||
>
|
||||
|
@ -76,20 +76,20 @@
|
|||
|
||||
<el-table-column
|
||||
prop="createUser"
|
||||
label="创建人"
|
||||
:label="$t('backendSystem.createUser')|| '创建人'"
|
||||
width="160"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
<el-table-column prop="content" label="文档内容" show-overflow-tooltip />
|
||||
<el-table-column prop="content" :label="$t('backendSystem.content')|| '文档内容'" show-overflow-tooltip />
|
||||
<el-table-column
|
||||
prop="title"
|
||||
label="文档标题"
|
||||
:label="$t('backendSystem.documentTitle')|| '文档标题'"
|
||||
width="200"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
<el-table-column
|
||||
prop="type"
|
||||
label="文档类型"
|
||||
:label="$t('backendSystem.documentType')|| '文档类型'"
|
||||
width="100"
|
||||
show-overflow-tooltip
|
||||
>
|
||||
|
@ -100,7 +100,7 @@
|
|||
|
||||
<el-table-column
|
||||
prop="updateTime"
|
||||
label="修改时间"
|
||||
:label="$t('backendSystem.updateTime')|| '修改时间'"
|
||||
width="160"
|
||||
show-overflow-tooltip
|
||||
>
|
||||
|
@ -110,7 +110,7 @@
|
|||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="updateUser"
|
||||
label="修改人"
|
||||
:label="$t('backendSystem.updateUser')|| '修改人'"
|
||||
width="160"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
|
|
|
@ -3,12 +3,17 @@ export default{
|
|||
data(){
|
||||
return{
|
||||
typeArray:[],
|
||||
currencyList: [],
|
||||
screenCurrency: "",
|
||||
|
||||
}
|
||||
},
|
||||
mounted(){
|
||||
// this.fetchDataInfo()
|
||||
|
||||
this.currencyList = JSON.parse(localStorage.getItem("currencyList"));
|
||||
window.addEventListener("setItem", () => {
|
||||
this.currencyList = JSON.parse(localStorage.getItem("currencyList"));
|
||||
});
|
||||
|
||||
if (this.$route.query.id) {
|
||||
this.fetchDataInfo({id:this.$route.query.id})
|
||||
|
@ -27,8 +32,33 @@ export default{
|
|||
this.typeArray = [this.addParams.type]
|
||||
// 标记已从后台获取数据,避免被本地存储覆盖
|
||||
this.hasBackendData = true
|
||||
// 删除 editor.setHtml 的调用,内容初始化交由 onCreated 统一处理
|
||||
this.screenCurrency = this.addParams.coin
|
||||
// 强制用接口数据刷新编辑器内容
|
||||
if (this.editor && this.addParams.content) {
|
||||
this.editor.txt.html(this.addParams.content)
|
||||
this.html = this.addParams.content
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 币种选择变更处理
|
||||
* @param {string} scope - 选择的币种
|
||||
*/
|
||||
changeScreen(scope) {
|
||||
let brand = scope
|
||||
for (let index in this.currencyList) {
|
||||
let aa = this.currencyList[index];
|
||||
let value = aa.value;
|
||||
if (brand === value) {
|
||||
this.$refs.screen.$el.children[0].children[0].setAttribute('style', "background:url(" + aa.imgUrl + ") no-repeat 10PX;background-size: 20PX 20PX;color:#333;padding-left: 33PX;");
|
||||
}
|
||||
}
|
||||
|
||||
// 保存用户选择的币种到localStorage
|
||||
localStorage.setItem('userManagement_selectedCurrency', scope);
|
||||
|
||||
|
||||
|
||||
},
|
||||
}
|
||||
}
|
|
@ -1,29 +1,37 @@
|
|||
<template>
|
||||
<div class="editor-page" v-loading="addLoading">
|
||||
|
||||
<div class="editor-page" v-loading="addLoading" :class="{ 'no-scroll': addLoading }">
|
||||
|
||||
<h2 style="margin-bottom: 20px;">{{ $t('backendSystem.modifyDocument') || '修改文档' }}</h2>
|
||||
<!-- 页面头部 -->
|
||||
<div class="page-header">
|
||||
<div class="header-left">
|
||||
<div class="title-section">
|
||||
<i class="el-icon-edit-outline title-icon"></i>
|
||||
<h1 class="page-title">wangeditor 富文本文档编辑器</h1>
|
||||
<h1 class="page-title">{{ $t('backendSystem.wangeditor') || 'wangeditor 富文本文档编辑器' }}</h1>
|
||||
</div>
|
||||
<p class="page-description">
|
||||
使用富文本编辑器创建和管理文档,支持文本格式化、链接、列表等功能
|
||||
</p>
|
||||
|
||||
</div>
|
||||
<div class="header-actions">
|
||||
<el-button
|
||||
type="primary"
|
||||
icon="el-icon-link"
|
||||
@click="handleInsertAnchor"
|
||||
>
|
||||
{{ $t('backendSystem.insertAnchor') || '插入锚点' }}
|
||||
</el-button>
|
||||
<el-button type="info" icon="el-icon-view" @click="handlePreview">
|
||||
预览文档
|
||||
{{ $t('backendSystem.previewDocument') || '预览文档' }}
|
||||
</el-button>
|
||||
<el-button type="success" icon="el-icon-document" @click="handleSave">
|
||||
保存文档
|
||||
{{ $t('backendSystem.saveDocument') || '保存文档' }}
|
||||
</el-button>
|
||||
<el-button
|
||||
type="warning"
|
||||
icon="el-icon-upload2"
|
||||
@click="handelAddDocument"
|
||||
>
|
||||
修改文档
|
||||
{{ $t('backendSystem.modifyDocument') || '修改文档' }}
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -32,36 +40,35 @@
|
|||
<div class="config-section">
|
||||
<div class="section-header">
|
||||
<i class="el-icon-setting"></i>
|
||||
<span>文档配置</span>
|
||||
<span>{{ $t('backendSystem.documentConfiguration') || '文档配置' }}</span>
|
||||
</div>
|
||||
|
||||
<div class="config-content">
|
||||
<div class="config-row">
|
||||
<div class="config-item">
|
||||
<label>导航标题</label>
|
||||
<label>{{ $t('backendSystem.navigationTitle') || '导航标题' }}</label>
|
||||
<el-input
|
||||
v-model="addParams.title"
|
||||
placeholder="请输入文档标题"
|
||||
:placeholder="$t('backendSystem.pleaseInputDocumentTitle') || '请输入文档标题'"
|
||||
@input="handleAutoSave"
|
||||
size="medium"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="config-item">
|
||||
<label class="required">文档类型</label>
|
||||
<label class="required">{{ $t('backendSystem.documentType') || '文档类型' }}</label>
|
||||
<el-cascader
|
||||
:options="TypeList"
|
||||
v-model="typeArray"
|
||||
@change="handleAutoSaveType(typeArray)"
|
||||
clearable
|
||||
placeholder="请选择文档类型"
|
||||
:placeholder="$t('backendSystem.pleaseSelectDocumentType') || '请选择文档类型'"
|
||||
:props="{
|
||||
label: 'label',
|
||||
value: 'value',
|
||||
children: 'children',
|
||||
}"
|
||||
/>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -69,113 +76,115 @@
|
|||
<div class="config-content">
|
||||
<div class="config-row">
|
||||
<div class="config-item">
|
||||
<label>标题图片地址</label>
|
||||
<label>{{ $t('backendSystem.titleImageAddress') || '标题图片地址' }}</label>
|
||||
<el-input
|
||||
v-model="addParams.titleUrl"
|
||||
placeholder="请输入图片地址"
|
||||
:placeholder="$t('backendSystem.pleaseInputImageAddress') || '请输入图片地址'"
|
||||
@input="handleAutoSave"
|
||||
size="medium"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="config-item">
|
||||
<label>文章访问地址</label>
|
||||
<label>{{ $t('backendSystem.articleAccessAddress') || '文章访问地址' }}</label>
|
||||
<el-input
|
||||
v-model="addParams.articleUrl"
|
||||
placeholder="请输入访问地址"
|
||||
:placeholder="$t('backendSystem.pleaseInputAccessAddress') || '请输入访问地址'"
|
||||
@input="handleAutoSave"
|
||||
size="medium"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="config-content">
|
||||
<div class="config-row">
|
||||
<div class="config-item">
|
||||
<label >{{
|
||||
$t("backendSystem.coin2") || "币种"
|
||||
}}</label>
|
||||
<el-select
|
||||
class="input"
|
||||
size="middle"
|
||||
ref="screen"
|
||||
@change="changeScreen(screenCurrency)"
|
||||
v-model="screenCurrency"
|
||||
|
||||
:placeholder="$t(`backendSystem.selectCurrency`)"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in currencyList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
>
|
||||
|
||||
<div style="display: flex; align-items: center">
|
||||
<img :src="item.imgUrl" style="float: left; width: 20px" />
|
||||
<span style="float: left; margin-left: 5px">
|
||||
{{ item.label }}</span
|
||||
>
|
||||
</div>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 编辑器区域 -->
|
||||
<div class="editor-section">
|
||||
<div class="section-header">
|
||||
<i class="el-icon-edit-outline"></i>
|
||||
<span>富文本编辑器</span>
|
||||
<span>{{ $t('backendSystem.richTextEditor') || '富文本编辑器' }}</span>
|
||||
</div>
|
||||
|
||||
<div class="editor-container">
|
||||
<Toolbar
|
||||
:editor="editor"
|
||||
:defaultConfig="toolbarConfig"
|
||||
:mode="mode"
|
||||
style="border-bottom: 1px solid #ccc"
|
||||
/>
|
||||
<Editor
|
||||
style="height: 600px; overflow-y: hidden"
|
||||
v-model="addParams.content"
|
||||
:defaultConfig="editorConfig"
|
||||
:mode="mode"
|
||||
@onCreated="onCreated"
|
||||
@onChange="handleEditorChange"
|
||||
/>
|
||||
<div ref="editor" style="height: 600px"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- 预览文档对话框 -->
|
||||
<el-dialog
|
||||
title="文档预览"
|
||||
:title="$t('backendSystem.documentPreview') || '文档预览'"
|
||||
:visible.sync="previewVisible"
|
||||
width="80%"
|
||||
:before-close="handlePreviewClose"
|
||||
class="preview-dialog wangeditor-preview"
|
||||
>
|
||||
<div class="preview-content">
|
||||
<div v-html="addParams.content" class="dynamic-content" ></div>
|
||||
<div v-html="addParams.content" class="dynamic-content"></div>
|
||||
|
||||
<div v-if="!addParams.content" class="preview-empty">
|
||||
<i class="el-icon-document"></i>
|
||||
<p>暂无内容</p>
|
||||
<p>{{ $t('backendSystem.noContent') || '暂无内容' }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="previewVisible = false">关闭</el-button>
|
||||
<el-button type="primary" @click="handlePrintPreview"
|
||||
>打印预览</el-button
|
||||
>
|
||||
<el-button @click="previewVisible = false">{{ $t('backendSystem.close') || '关闭' }}</el-button>
|
||||
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Vue from "vue";
|
||||
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
|
||||
import E from "wangeditor";
|
||||
import { updateDocument } from "../../../api/documentManagement";
|
||||
|
||||
import Index from "./index";
|
||||
export default Vue.extend({
|
||||
components: { Editor, Toolbar },
|
||||
mixins: [Index],
|
||||
data() {
|
||||
return {
|
||||
editor: null,
|
||||
html: "<p>hello</p>",
|
||||
toolbarConfig: {
|
||||
excludeKeys: [],
|
||||
insertKeys: {
|
||||
index: 0,
|
||||
keys: [
|
||||
"bold",
|
||||
"italic",
|
||||
"underline",
|
||||
"through",
|
||||
"code",
|
||||
"sub",
|
||||
"sup",
|
||||
"clearStyle",
|
||||
],
|
||||
},
|
||||
},
|
||||
editorConfig: {
|
||||
placeholder: "请在此输入文档内容...",
|
||||
MENU_CONF: {},
|
||||
},
|
||||
html: "", // 编辑器内容
|
||||
hasSetEditorContent: false, // 避免重复 set 内容
|
||||
mode: "default",
|
||||
addParams: {
|
||||
title: "",
|
||||
|
@ -184,7 +193,8 @@ export default Vue.extend({
|
|||
lang: "",
|
||||
titleUrl: "",
|
||||
articleUrl: "",
|
||||
childType:""
|
||||
childType: "",
|
||||
coin: "",
|
||||
},
|
||||
lastSaveTime: "",
|
||||
autoSaveTimer: null,
|
||||
|
@ -215,11 +225,10 @@ export default Vue.extend({
|
|||
};
|
||||
},
|
||||
mounted() {
|
||||
|
||||
|
||||
try {
|
||||
this.TypeList = JSON.parse(localStorage.getItem("TypeList"));
|
||||
this.TypeList = this.TypeList.map((item) => ({ // 翻译label
|
||||
this.TypeList = this.TypeList.map((item) => ({
|
||||
// 翻译label
|
||||
...item,
|
||||
label: this.$t(item.label),
|
||||
children: item.children
|
||||
|
@ -229,7 +238,6 @@ export default Vue.extend({
|
|||
}))
|
||||
: undefined,
|
||||
}));
|
||||
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
@ -247,12 +255,87 @@ export default Vue.extend({
|
|||
}
|
||||
}, 1500);
|
||||
|
||||
|
||||
|
||||
this.editor = new E(this.$refs.editor);
|
||||
this.editor.config.height = 600;
|
||||
this.editor.config.onchange = (html) => {
|
||||
this.html = html;
|
||||
this.addParams.content = html;
|
||||
};
|
||||
//配置颜色
|
||||
this.editor.config.colors = [
|
||||
`#651FFF`,
|
||||
`#FF4081`,
|
||||
`#FF9900`,
|
||||
`#FFC107`,
|
||||
`#FF5722`,
|
||||
`#9C27B0`,
|
||||
`#673AB7`,
|
||||
`#3F51B5`,
|
||||
"#000000", // 黑色
|
||||
"#ffffff", // 白色
|
||||
"#eeece0", // 浅米色
|
||||
"#1c487f", // 深蓝
|
||||
"#4d80bf", // 蓝色
|
||||
"#c24f4a", // 红色
|
||||
"#8baa4a", // 绿色
|
||||
"#a96b59", // 棕色
|
||||
"#2b2b2b", // 深灰
|
||||
"#b6975a", // 金色
|
||||
"#5b9bd5", // 天蓝
|
||||
"#70ad47", // 草绿
|
||||
"#ed7d31", // 橙色
|
||||
"#ffc000", // 黄色
|
||||
"#7030a0", // 紫色
|
||||
"#f4b084", // 浅橙
|
||||
"#bdd7ee", // 浅蓝
|
||||
"#a9d08e", // 浅绿
|
||||
"#ffe699", // 浅黄
|
||||
"#d9d9d9", // 浅灰
|
||||
"#f8cbad", // 浅棕
|
||||
"#e2efda", // 淡绿
|
||||
"#fff2cc", // 淡黄
|
||||
"#dbe5f1", // 淡蓝
|
||||
"#e4dfec", // 淡紫
|
||||
"#fbeee6", // 淡橙
|
||||
"#f6f6f6", // 极浅灰
|
||||
"#ff0000", // 纯红
|
||||
"#00b050", // 纯绿
|
||||
"#0070c0", // 纯蓝
|
||||
"#7030a0", // 纯紫
|
||||
"#ff9900", // 纯橙
|
||||
"#808080", // 中灰
|
||||
];
|
||||
//配置字体
|
||||
this.editor.config.fontNames = [
|
||||
// 对象形式 v4.6.16
|
||||
{name:"黑体",value:"黑体"},
|
||||
{name:"绝绝字体",value:"Times New Roman"},
|
||||
// 字符串形式
|
||||
'黑体',
|
||||
'仿宋',
|
||||
'楷体',
|
||||
'标楷体',
|
||||
'华文仿宋',
|
||||
'华文楷体',
|
||||
'宋体',
|
||||
'微软雅黑',
|
||||
'Arial',
|
||||
'Tahoma',
|
||||
'Verdana',
|
||||
'Times New Roman',
|
||||
'Courier New',
|
||||
],
|
||||
|
||||
// 不自定义菜单,使用官方默认菜单栏
|
||||
this.editor.create();
|
||||
// 只在初始化时 set 一次内容
|
||||
if (this.addParams.content && !this.hasSetEditorContent) {
|
||||
this.editor.txt.html(this.addParams.content);
|
||||
this.html = this.addParams.content;
|
||||
this.hasSetEditorContent = true;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
async fetchUpdateDocument(params) {
|
||||
this.setLoading("addLoading", true);
|
||||
const res = await updateDocument(params);
|
||||
|
@ -263,24 +346,28 @@ export default Vue.extend({
|
|||
this.setLoading("addLoading", false);
|
||||
},
|
||||
|
||||
/**
|
||||
* 编辑器创建后回调,确保 this.editor 正确赋值
|
||||
* @param {Object} editor wangEditor 实例
|
||||
*/
|
||||
onCreated(editor) {
|
||||
this.editor = Object.seal(editor);
|
||||
this.editor = editor;
|
||||
console.log("编辑器已初始化", this.editor);
|
||||
|
||||
// 编辑器创建后,如果有恢复的内容,设置到编辑器中
|
||||
if (this.addParams.content) {
|
||||
this.$nextTick(() => {
|
||||
editor.setHtml(this.addParams.content);
|
||||
this.editor.txt.html(this.addParams.content);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
console.log(editor.getAllMenuKeys(),"Editor.getAllMenuKe就啊哈啊ys()");
|
||||
},
|
||||
|
||||
handelAddDocument() {
|
||||
if (!this.addParams.type) {
|
||||
|
||||
|
||||
if (!this.addParams.type || this.addParams.type == "0") {
|
||||
this.$message({
|
||||
message: "请填写文档类型",
|
||||
message: this.$t('backendSystem.pleaseInputType') || '请填写文档类型',
|
||||
type: "warning",
|
||||
duration: 4000,
|
||||
showClose: true,
|
||||
|
@ -288,11 +375,34 @@ export default Vue.extend({
|
|||
return;
|
||||
}
|
||||
|
||||
// 确保获取最新的编辑器内容
|
||||
if (this.editor) {
|
||||
this.addParams.content = this.editor.getHtml();
|
||||
console.log(this.screenCurrency, "this.screenCurrency",this.addParams.type);
|
||||
|
||||
if (this.addParams.type == "1" && !this.screenCurrency) {
|
||||
this.$message({
|
||||
message:
|
||||
this.$t("backendSystem.pleaseSelectCurrency2") ||
|
||||
"添加挖矿教程,请选择币种",
|
||||
type: "warning",
|
||||
duration: 4000,
|
||||
showClose: true,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.addParams.content) {
|
||||
//锚点定位的A标签 去掉target="_blank"
|
||||
this.addParams.content = this.addParams.content.replace(
|
||||
/<a([^>]*href="#[^"]*")[^>]*>/gi,
|
||||
function (match) {
|
||||
return match.replace(/\s*target="_blank"/gi, "");
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
this.addParams.coin = this.screenCurrency
|
||||
|
||||
console.log(this.addParams.content, "this.addParams.content");
|
||||
|
||||
this.fetchUpdateDocument(this.addParams);
|
||||
},
|
||||
|
||||
|
@ -312,49 +422,20 @@ export default Vue.extend({
|
|||
this.previewVisible = false;
|
||||
},
|
||||
|
||||
handlePrintPreview() {
|
||||
const printWindow = window.open("", "_blank");
|
||||
if (printWindow) {
|
||||
printWindow.document.write(`
|
||||
<html>
|
||||
<head>
|
||||
<title>${this.addParams.title || "文档预览"}</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: 'Arial', sans-serif;
|
||||
line-height: 1.6;
|
||||
color: #333;
|
||||
margin: 20px;
|
||||
}
|
||||
.preview-empty {
|
||||
text-align: center;
|
||||
padding: 50px 0;
|
||||
color: #95a5a6;
|
||||
}
|
||||
.preview-empty i {
|
||||
font-size: 40px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
${
|
||||
this.addParams.content ||
|
||||
'<div class="preview-empty"><i>📄</i><p>暂无内容</p></div>'
|
||||
}
|
||||
</body>
|
||||
</html>
|
||||
`);
|
||||
printWindow.document.close();
|
||||
printWindow.print();
|
||||
printWindow.close();
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
handleSave() {
|
||||
// 保存前彻底去除所有锚点链接的 target="_blank"
|
||||
this.addParams.content = this.addParams.content.replace(
|
||||
/<a([^>]*href="#([^"]*)")[^>]*>/gi,
|
||||
function (match) {
|
||||
// 去掉 target="_blank"
|
||||
return match.replace(/\s*target="_blank"/gi, "");
|
||||
}
|
||||
);
|
||||
this.manualSave();
|
||||
this.$message({
|
||||
message: "内容已保存到本地,请尽快发布,关闭页面可能丢失内容",
|
||||
message: this.$t('backendSystem.contentSaved') || '内容已保存到本地,请尽快发布,关闭页面可能丢失内容',
|
||||
type: "success",
|
||||
duration: 4000,
|
||||
showClose: true,
|
||||
|
@ -373,7 +454,7 @@ export default Vue.extend({
|
|||
this.addParams.articleUrl = "";
|
||||
}
|
||||
this.addParams.type = type[0];
|
||||
this.addParams.childType= type[1];
|
||||
this.addParams.childType = type[1];
|
||||
} catch (error) {
|
||||
console.log(error, "error");
|
||||
}
|
||||
|
@ -415,7 +496,7 @@ export default Vue.extend({
|
|||
try {
|
||||
// 确保获取最新的编辑器内容
|
||||
if (this.editor) {
|
||||
this.addParams.content = this.editor.getHtml();
|
||||
this.addParams.content = this.editor.txt.html();
|
||||
}
|
||||
|
||||
const saveData = {
|
||||
|
@ -469,7 +550,7 @@ export default Vue.extend({
|
|||
|
||||
// 如果编辑器已经创建,直接设置内容
|
||||
if (this.editor) {
|
||||
this.editor.setHtml(data.content || "");
|
||||
this.editor.txt.html(data.content || "");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -488,7 +569,7 @@ export default Vue.extend({
|
|||
manualSave() {
|
||||
// 确保获取最新的编辑器内容
|
||||
if (this.editor) {
|
||||
this.addParams.content = this.editor.getHtml();
|
||||
this.addParams.content = this.editor.txt.html();
|
||||
}
|
||||
this.saveToLocalStorage();
|
||||
},
|
||||
|
@ -499,7 +580,7 @@ export default Vue.extend({
|
|||
if (this.addParams.title || this.addParams.content) {
|
||||
// 确保获取最新的编辑器内容
|
||||
if (this.editor) {
|
||||
this.addParams.content = this.editor.getHtml();
|
||||
this.addParams.content = this.editor.txt.html();
|
||||
}
|
||||
this.saveToLocalStorage();
|
||||
}
|
||||
|
@ -509,46 +590,80 @@ export default Vue.extend({
|
|||
getDocumentTypeName(type) {
|
||||
switch (type) {
|
||||
case "1":
|
||||
return "服务条款";
|
||||
return "home.serviceTerms";//服务条款
|
||||
case "2":
|
||||
return "api文档";
|
||||
return "home.APIfile";//api文档
|
||||
case "3":
|
||||
return "挖矿教程";
|
||||
return "home.miningTutorial";//挖矿教程
|
||||
case "0":
|
||||
return "其他";
|
||||
return "home.other";//其他
|
||||
default:
|
||||
return "未知类型";
|
||||
return "home.unknownType";//未知类型
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 插入锚点(源码模式下插入HTML)
|
||||
*/
|
||||
handleInsertAnchor() {
|
||||
if (!this.editor) {
|
||||
this.$message.warning("编辑器尚未初始化");
|
||||
return;
|
||||
}
|
||||
this.$prompt(this.$t('backendSystem.pleaseInputAnchorName') || '请输入锚点名称(不能重复)', this.$t('backendSystem.insertAnchor') || '插入锚点', {
|
||||
confirmButtonText: this.$t('backendSystem.confirm') || '确定',
|
||||
cancelButtonText: this.$t('backendSystem.cancel') || '取消',
|
||||
inputPattern: /^[a-zA-Z0-9_-]+$/,
|
||||
inputErrorMessage: this.$t('backendSystem.anchorNameErrorMessage') || '锚点名只能包含字母、数字、下划线和中划线',
|
||||
})
|
||||
.then(({ value }) => {
|
||||
this.editor.cmd.do("insertHTML", `<span id="${value}"></span>`);
|
||||
this.html = this.editor.txt.html();
|
||||
this.addParams.content = this.html;
|
||||
this.$message.success(this.$t('backendSystem.anchorInserted') || '锚点已插入');
|
||||
})
|
||||
.catch(() => {});
|
||||
},
|
||||
|
||||
/**
|
||||
* 给选中的标题添加id属性作为锚点
|
||||
*/
|
||||
handleAddHeadingId() {
|
||||
if (!this.editor) {
|
||||
this.$message.warning("编辑器尚未初始化");
|
||||
return;
|
||||
}
|
||||
// 获取当前选中的标题节点
|
||||
const headers = this.editor.getElemsByTypePrefix("header");
|
||||
if (!headers || headers.length === 0) {
|
||||
this.$message.warning(this.$t('backendSystem.pleaseSelectHeader') || '请先选中一个标题(h1~h6)');
|
||||
return;
|
||||
}
|
||||
const node = headers[0];
|
||||
this.$prompt(this.$t('backendSystem.pleaseInputAnchorID') || '请输入锚点ID(不能重复)', this.$t('backendSystem.titleAnchor') || '标题锚点', {
|
||||
confirmButtonText: this.$t('backendSystem.confirm') || '确定',
|
||||
cancelButtonText: this.$t('backendSystem.cancel') || '取消',
|
||||
inputPattern: /^[a-zA-Z0-9_-]+$/,
|
||||
inputErrorMessage: this.$t('backendSystem.anchorIDErrorMessage') || 'ID只能包含字母、数字、下划线和中划线',
|
||||
})
|
||||
.then(({ value }) => {
|
||||
this.editor.setElemAttribute(node, "id", value);
|
||||
this.$message.success(this.$t('backendSystem.anchorIDAdded') || '锚点ID已添加');
|
||||
})
|
||||
.catch(() => {});
|
||||
},
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
// 确保获取最新的编辑器内容
|
||||
if (this.editor) {
|
||||
this.addParams.content = this.editor.getHtml();
|
||||
this.editor.destroy();
|
||||
}
|
||||
this.saveToLocalStorage();
|
||||
|
||||
// 移除事件监听器
|
||||
window.removeEventListener("beforeunload", this.handleBeforeUnload);
|
||||
|
||||
if (this.autoSaveTimer) {
|
||||
clearTimeout(this.autoSaveTimer);
|
||||
}
|
||||
|
||||
const editor = this.editor;
|
||||
if (editor == null) return;
|
||||
editor.destroy();
|
||||
|
||||
|
||||
|
||||
|
||||
},
|
||||
|
||||
beforeRouteLeave(to, from, next) {
|
||||
// 确保获取最新的编辑器内容
|
||||
if (this.editor) {
|
||||
this.addParams.content = this.editor.getHtml();
|
||||
this.addParams.content = this.editor.txt.html();
|
||||
}
|
||||
this.saveToLocalStorage();
|
||||
next();
|
||||
|
@ -565,6 +680,7 @@ export default Vue.extend({
|
|||
background: #f8f9fa;
|
||||
min-height: 60vh;
|
||||
overflow-y: auto;
|
||||
|
||||
}
|
||||
|
||||
/* 页面头部样式 */
|
||||
|
@ -703,12 +819,20 @@ export default Vue.extend({
|
|||
overflow: hidden;
|
||||
background: white;
|
||||
min-height: 650px;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/* 设置编辑器高度 */
|
||||
.editor-container .w-e-text-container {
|
||||
::v-deep .editor-container .w-e-text-container {
|
||||
height: 600px !important;
|
||||
min-height: 600px !important;
|
||||
z-index: 1 !important;
|
||||
position: relative;
|
||||
}
|
||||
::v-deep .w-e-toolbar {
|
||||
z-index: 10 !important;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* 编辑器内容区域样式 */
|
||||
|
@ -751,6 +875,7 @@ export default Vue.extend({
|
|||
padding: 20px;
|
||||
max-height: 70vh;
|
||||
overflow-y: auto;
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
.preview-dialog .el-dialog__header {
|
||||
|
@ -877,42 +1002,44 @@ export default Vue.extend({
|
|||
|
||||
/* -------富文本样式-------------- */
|
||||
.dynamic-content {
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
|
||||
|
||||
:deep(table) {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
margin: 16px 0;
|
||||
}
|
||||
:deep(th), :deep(td) {
|
||||
border: 1px solid #d1d5db;
|
||||
padding: 8px 12px;
|
||||
text-align: left;
|
||||
}
|
||||
:deep(th) {
|
||||
background: #f3f4f6;
|
||||
font-weight: bold;
|
||||
}
|
||||
:deep(strong), :deep(b) {
|
||||
font-weight: bold !important;
|
||||
color: inherit !important;
|
||||
font-style: normal !important;
|
||||
}
|
||||
:deep(em), :deep(i) {
|
||||
font-style: italic !important;
|
||||
color: inherit !important;
|
||||
}
|
||||
:deep(a) {
|
||||
color: #007bff !important;
|
||||
text-decoration: none !important;
|
||||
&:hover {
|
||||
text-decoration: underline !important;
|
||||
}
|
||||
}
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
|
||||
:deep(table) {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
margin: 16px 0;
|
||||
}
|
||||
:deep(th),
|
||||
:deep(td) {
|
||||
border: 1px solid #d1d5db;
|
||||
padding: 8px 12px;
|
||||
text-align: left;
|
||||
}
|
||||
:deep(th) {
|
||||
background: #f3f4f6;
|
||||
font-weight: bold;
|
||||
}
|
||||
:deep(strong),
|
||||
:deep(b) {
|
||||
font-weight: bold !important;
|
||||
color: inherit !important;
|
||||
font-style: normal !important;
|
||||
}
|
||||
:deep(em),
|
||||
:deep(i) {
|
||||
font-style: italic !important;
|
||||
color: inherit !important;
|
||||
}
|
||||
:deep(a) {
|
||||
color: #007bff !important;
|
||||
text-decoration: none !important;
|
||||
&:hover {
|
||||
text-decoration: underline !important;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<style src="@wangeditor/editor/dist/css/style.css"></style>
|
||||
}
|
||||
}
|
||||
.no-scroll {
|
||||
overflow: hidden !important;
|
||||
}
|
||||
</style>
|
|
@ -114,11 +114,11 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import Vue from 'vue'
|
||||
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
|
||||
import { addDocument } from '../api/documentManagement'
|
||||
import Vue from "vue";
|
||||
import E from "wangeditor";
|
||||
import { addDocument } from '../api/documentManagement'
|
||||
|
||||
export default Vue.extend({
|
||||
export default Vue.extend({
|
||||
components: { Editor, Toolbar },
|
||||
data() {
|
||||
return {
|
||||
|
@ -757,6 +757,4 @@
|
|||
border-radius: 6px;
|
||||
font-weight: 500;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style src="@wangeditor/editor/dist/css/style.css"></style>
|
||||
</style>
|
|
@ -10,17 +10,17 @@ export default{
|
|||
selectedLanguage: 'zh',
|
||||
/** 分类按钮数据 */
|
||||
categories: [
|
||||
{ id: 1, name: 'API文档', route: 'apiFile' },
|
||||
{ id: 2, name: '挖矿教程', route: 'AccessMiningPool/nexaAccess' },
|
||||
{ id: 3, name: '服务条款', route: 'ServiceTerms' },
|
||||
{ id: 4, name: '费率', route: 'rate' },
|
||||
{ id: 5, name: '公告中心', route: 'announcements' },
|
||||
{ id: 6, name: '常见问题', route: 'commonProblem' },
|
||||
{ id: 1, name: 'home.APIfile', route: 'apiFile' },//API文档
|
||||
{ id: 2, name: 'home.miningTutorial', route: 'AccessMiningPool/nexaAccess' },//挖矿教程
|
||||
{ id: 3, name: 'home.serviceTerms', route: 'ServiceTerms' },//服务条款
|
||||
{ id: 4, name: 'home.rate', route: 'rate' },//费率
|
||||
{ id: 5, name: 'home.announcements', route: 'announcements' },//公告中心
|
||||
{ id: 6, name: 'home.commonProblem', route: 'commonProblem' },//常见问题
|
||||
|
||||
],
|
||||
/** 推荐内容数据 */
|
||||
recommendedItems: [
|
||||
{ id: 1, description: '矿池分配及转账规则' ,route:"allocationExplanation"},
|
||||
{ id: 1, description: 'home.allocationExplanation' ,route:"allocationExplanation"},//矿池分配及转账规则
|
||||
// { id: 2, description: '余额不足如何任何偿还,该如何规划运营?' },
|
||||
// { id: 3, description: '矿池选择它已经拥有综合的优势时间,怎么办?' }
|
||||
],
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
<input
|
||||
v-model="searchQuery"
|
||||
type="text"
|
||||
placeholder="搜索"
|
||||
:placeholder="$t('backendSystem.search') || '搜索'"
|
||||
class="search-input"
|
||||
@keyup.enter="handleSearch"
|
||||
/>
|
||||
|
@ -32,13 +32,13 @@
|
|||
@keydown.enter="handleCategoryClick(category)"
|
||||
tabindex="0"
|
||||
>
|
||||
{{ category.name }}
|
||||
{{ $t(category.name )}}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- 推荐内容区域 -->
|
||||
<div class="recommended-section">
|
||||
<h3 class="section-title">推荐的内容</h3>
|
||||
<h3 class="section-title">{{ $t('backendSystem.recommendContent') || '推荐的内容' }}</h3>
|
||||
<div class="recommended-items">
|
||||
<div
|
||||
v-for="item in recommendedItems"
|
||||
|
@ -46,14 +46,14 @@
|
|||
class="recommended-item"
|
||||
@click="handleCategoryClick(item)"
|
||||
>
|
||||
<p class="item-description" >{{ item.description }}</p>
|
||||
<p class="item-description" >{{ $t(item.description) }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 最近活动区域 -->
|
||||
<div class="recent-activities">
|
||||
<h3 class="section-title">最近的活动</h3>
|
||||
<h3 class="section-title">{{ $t('backendSystem.recentActivities') || '最近活动' }}</h3>
|
||||
<div class="activities-list">
|
||||
<div
|
||||
v-for="activity in activities"
|
||||
|
@ -75,7 +75,7 @@
|
|||
<!-- 查看更多链接 -->
|
||||
<div class="view-more">
|
||||
<a href="#" class="view-more-link" @click="handleViewMore">
|
||||
查看更多活动公告
|
||||
{{ $t('backendSystem.viewMore') || '查看更多活动公告' }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1569,7 +1569,7 @@ export default {
|
|||
// 使用 name 进行导航,避免重复的路由参数
|
||||
this.$router.push({
|
||||
path:url,
|
||||
params: {
|
||||
query: {
|
||||
lang: this.lang,
|
||||
coin: this.params.coin,
|
||||
imgUrl: this.currencyPath
|
||||
|
|
|
@ -257,6 +257,133 @@ export default {
|
|||
countDownTime: 60,
|
||||
timer: null,
|
||||
lang: "en",
|
||||
currencyList: [
|
||||
{
|
||||
path: "nexaAccess",
|
||||
value: "nexa",
|
||||
label: "nexa",
|
||||
img: require("../../assets/img/currency-nexa.png"),
|
||||
imgUrl: `${this.$baseApi}img/nexa.png`,
|
||||
name: "course.NEXAcourse",
|
||||
show: true,
|
||||
amount: 10000,
|
||||
|
||||
},
|
||||
{
|
||||
path: "grsAccess",
|
||||
value: "grs",
|
||||
label: "grs",
|
||||
img: require("../../assets/img/currency/grs.svg"),
|
||||
imgUrl: `${this.$baseApi}img/grs.svg`,
|
||||
name: "course.GRScourse",
|
||||
show: true,
|
||||
amount: 1,
|
||||
|
||||
},
|
||||
{
|
||||
path: "monaAccess",
|
||||
value: "mona",
|
||||
label: "mona",
|
||||
img: require("../../assets/img/currency/mona.svg"),
|
||||
imgUrl: `${this.$baseApi}img/mona.svg`,
|
||||
name: "course.MONAcourse",
|
||||
show: true,
|
||||
amount: 1,
|
||||
|
||||
},
|
||||
{
|
||||
path: "dgbsAccess",
|
||||
value: "dgbs",
|
||||
// label: "dgb-skein-pool1",
|
||||
label: "dgb(skein)",
|
||||
img: require("../../assets/img/currency/DGB.svg"),
|
||||
imgUrl: `${this.$baseApi}img/dgb.svg`,
|
||||
name: "course.dgbsCourse",
|
||||
show: true,
|
||||
amount: 1,
|
||||
},
|
||||
{
|
||||
path: "dgbqAccess",
|
||||
value: "dgbq",
|
||||
// label: "dgb(qubit-pool1)",
|
||||
label: "dgb(qubit)",
|
||||
img: require("../../assets/img/currency/DGB.svg"),
|
||||
imgUrl: `${this.$baseApi}img/dgb.svg`,
|
||||
name: "course.dgbqCourse",
|
||||
show: true,
|
||||
amount: 1,
|
||||
},
|
||||
{
|
||||
path: "dgboAccess",
|
||||
value: "dgbo",
|
||||
// label: "dgb-odocrypt-pool1",
|
||||
label: "dgb(odocrypt)",
|
||||
img: require("../../assets/img/currency/DGB.svg"),
|
||||
imgUrl: `${this.$baseApi}img/dgb.svg`,
|
||||
name: "course.dgboCourse",
|
||||
show: true,
|
||||
amount: 1,
|
||||
},
|
||||
{
|
||||
path: "rxdAccess",
|
||||
value: "rxd",
|
||||
label: "radiant(rxd)",
|
||||
img: require("../../assets/img/currency/rxd.png"),
|
||||
imgUrl: `${this.$baseApi}img/rxd.png`,
|
||||
name: "course.RXDcourse",
|
||||
show: true,
|
||||
amount: 100,
|
||||
|
||||
},
|
||||
{
|
||||
path: "enxAccess",
|
||||
value: "enx",
|
||||
label: "Entropyx(enx)",
|
||||
img: require("../../assets/img/currency/enx.svg"),
|
||||
imgUrl: `${this.$baseApi}img/enx.svg`,
|
||||
name: "course.ENXcourse",
|
||||
show: true,
|
||||
amount: 5000,
|
||||
|
||||
},
|
||||
{
|
||||
path: "alphminingPool",
|
||||
value: "alph",
|
||||
label: "alephium",
|
||||
img: require("../../assets/img/currency/alph.svg"),
|
||||
imgUrl: `${this.$baseApi}img/alph.svg`,
|
||||
name: "course.alphCourse",
|
||||
show: true,
|
||||
amount: 1,
|
||||
|
||||
},
|
||||
|
||||
// { //告知已删除此币种 Radiant
|
||||
// value: "dgb2_odo",
|
||||
// label: "dgb-odocrypt-pool2",
|
||||
// img: require("../../assets/img/currency/DGB.svg"),
|
||||
// imgUrl: "https://s2.coinmarketcap.com/static/img/coins/64x64/109.png",
|
||||
// },
|
||||
// {
|
||||
// value: "dgb_qubit_a10",
|
||||
// label: "dgb-qubit-pool2",
|
||||
// img: require("../../assets/img/currency/DGB.svg"),
|
||||
// imgUrl: "https://s2.coinmarketcap.com/static/img/coins/64x64/109.png",
|
||||
// },
|
||||
// {
|
||||
// value: "dgb_skein_a10",
|
||||
// label: "dgb-skein-pool2",
|
||||
// img: require("../../assets/img/currency/DGB.svg"),
|
||||
// imgUrl: "https://s2.coinmarketcap.com/static/img/coins/64x64/109.png",
|
||||
// },
|
||||
// {
|
||||
// value: "dgb_odo_b20",
|
||||
// label: "dgb-odoscrypt-pool3",
|
||||
// img: require("../../assets/img/currency/DGB.svg"),
|
||||
// imgUrl: "https://s2.coinmarketcap.com/static/img/coins/64x64/109.png",
|
||||
// },
|
||||
|
||||
],
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -300,6 +427,7 @@ export default {
|
|||
// }
|
||||
},
|
||||
mounted() {
|
||||
this.$addStorageEvent(1, `currencyList`, JSON.stringify(this.currencyList))
|
||||
// this.lang = this.$i18n.locale; // 初始化语言值
|
||||
// this.radio = localStorage.getItem("lang")
|
||||
// ? localStorage.getItem("lang")
|
||||
|
|
|
@ -93,15 +93,48 @@ export default {
|
|||
DetailsParams:{
|
||||
lang:this.$i18n.locale,
|
||||
childType:2,//1服务条款、2费率、3API文档 childType
|
||||
id:'',
|
||||
},
|
||||
info:"",
|
||||
rateLoading:false
|
||||
rateLoading:false,
|
||||
|
||||
listParams:{
|
||||
// type:"1",//挖矿教程
|
||||
lang:this.$i18n.locale,
|
||||
pageNum:1,
|
||||
pageSize:50,
|
||||
childType:2,//1服务条款、2费率、3API文档 childType
|
||||
},
|
||||
navList:[],
|
||||
|
||||
}
|
||||
},
|
||||
mounted(){
|
||||
this.fetchProblemDetails(this.DetailsParams)
|
||||
this.fetchAllList(this.listParams)
|
||||
// this.fetchProblemDetails(this.DetailsParams)
|
||||
},
|
||||
methods:{
|
||||
async fetchAllList(params){
|
||||
this.setLoading('rateLoading', true);
|
||||
const res = await documentsList(params)
|
||||
console.log(res,"res");
|
||||
|
||||
if (res && res.code === 200) {
|
||||
this.navList = res.rows
|
||||
|
||||
if (this.$route.query.id) {
|
||||
this.DetailsParams.id = this.$route.query.id
|
||||
|
||||
}else{
|
||||
this.DetailsParams.id = res.rows[0].id;
|
||||
}
|
||||
if (this.DetailsParams.id) {
|
||||
this.fetchProblemDetails(this.DetailsParams)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
async fetchProblemDetails(params) {
|
||||
this.setLoading('rateLoading', true);
|
||||
const res = await findDataInfo(params)
|
||||
|
@ -112,5 +145,16 @@ export default {
|
|||
}
|
||||
this.setLoading('rateLoading', false);
|
||||
},
|
||||
|
||||
|
||||
clickJump(item) {
|
||||
|
||||
this.DetailsParams.id = item.id
|
||||
this.fetchProblemDetails(this.DetailsParams)
|
||||
|
||||
|
||||
|
||||
|
||||
},
|
||||
}
|
||||
}
|
|
@ -57,8 +57,12 @@
|
|||
<section class="rateBox" v-else>
|
||||
|
||||
<section class="leftMenu">
|
||||
<ul>
|
||||
<!-- <ul>
|
||||
<li>{{$t(`course.rateRelated`)}}</li>
|
||||
</ul> -->
|
||||
|
||||
<ul>
|
||||
<li v-for="item in navList" :class="{navActive:String(item.id) === String(DetailsParams.id)}" :key="item.id" @click="clickJump(item)">{{item.title}}</li>
|
||||
</ul>
|
||||
|
||||
</section>
|
||||
|
@ -66,11 +70,11 @@
|
|||
|
||||
<section class="rightContent">
|
||||
<div v-if="rateLoading" class="loading-container">
|
||||
<span class="loading-text">正在加载内容...</span>
|
||||
<span class="loading-text">{{ $t('home.loadingContent') || '正在加载内容...' }}</span>
|
||||
</div>
|
||||
<div v-else-if="info && info.trim()" class="dynamic-content" v-html="info"></div>
|
||||
<div v-else class="no-content">
|
||||
<p>暂无内容</p>
|
||||
<p>{{ $t('home.noContent') || '暂无内容' }}</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
@ -242,6 +246,7 @@ export default {
|
|||
font-size: 0.9rem;
|
||||
|
||||
}
|
||||
|
||||
.rateBox{
|
||||
width: 80%;
|
||||
margin: 0 auto;
|
||||
|
@ -265,11 +270,11 @@ export default {
|
|||
overflow: hidden;
|
||||
padding: 10px;
|
||||
ul{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
li{
|
||||
width: 100%;
|
||||
list-style: none;
|
||||
min-height: 40PX;
|
||||
display: flex;
|
||||
|
@ -283,9 +288,14 @@ export default {
|
|||
padding:8px 8px;
|
||||
font-size: 0.9rem;
|
||||
text-align: left;
|
||||
cursor: pointer;
|
||||
&:hover{
|
||||
background: #D2C3EA;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.rightText{
|
||||
box-sizing: border-box;
|
||||
width: 80%;
|
||||
|
@ -368,42 +378,50 @@ export default {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
.dynamic-content {
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
font-family: 'PingFang SC', 'Microsoft YaHei', Arial, sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.7;
|
||||
color: #222;
|
||||
// 富文本样式
|
||||
:deep(table) {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
|
||||
// 富文本样式
|
||||
:deep(table) {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
margin: 16px 0;
|
||||
}
|
||||
:deep(th), :deep(td) {
|
||||
border: 1px solid #d1d5db;
|
||||
padding: 8px 12px;
|
||||
text-align: left;
|
||||
}
|
||||
:deep(th) {
|
||||
background: #f3f4f6;
|
||||
font-weight: bold;
|
||||
}
|
||||
:deep(strong), :deep(b) {
|
||||
font-weight: bold !important;
|
||||
color: inherit !important;
|
||||
font-style: normal !important;
|
||||
}
|
||||
:deep(em), :deep(i) {
|
||||
font-style: italic !important;
|
||||
color: inherit !important;
|
||||
}
|
||||
:deep(a) {
|
||||
color: #007bff !important;
|
||||
margin: 16px 0;
|
||||
}
|
||||
|
||||
:deep(th), :deep(td) {
|
||||
border: 1px solid #d1d5db;
|
||||
padding: 8px 8px;
|
||||
text-align: left;
|
||||
}
|
||||
:deep(th) {
|
||||
background: #D2C3EA;
|
||||
font-weight: bold;
|
||||
}
|
||||
:deep(strong), :deep(b) {
|
||||
font-weight: bold !important;
|
||||
color: inherit !important;
|
||||
font-style: normal !important;
|
||||
}
|
||||
:deep(em), :deep(i) {
|
||||
font-style: italic !important;
|
||||
color: inherit !important;
|
||||
}
|
||||
:deep(a) {
|
||||
color: #661FFB !important;
|
||||
text-decoration: none !important;
|
||||
&:hover {
|
||||
text-decoration: underline !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.navActive{
|
||||
background: #AC85E0 !important;
|
||||
}
|
||||
|
||||
</style>
|
|
@ -1,851 +0,0 @@
|
|||
<template>
|
||||
<div class="rich-text-editor-page">
|
||||
<!-- 页面头部 -->
|
||||
<div class="page-header">
|
||||
<div class="header-content">
|
||||
<h1 class="page-title">
|
||||
<i class="el-icon-edit-outline"></i>
|
||||
富文本文档编辑器
|
||||
</h1>
|
||||
<p class="page-subtitle">使用富文本编辑器创建和管理文档,支持文本格式化、链接、列表等功能</p>
|
||||
</div>
|
||||
<div class="header-actions">
|
||||
<el-button @click="previewDocument" icon="el-icon-view" size="small" type="primary">预览文档</el-button>
|
||||
<el-button @click="saveDocument" :loading="saveLoading" icon="el-icon-document" size="small" type="success">保存文档</el-button>
|
||||
<el-button @click="publishDocument" :loading="publishLoading" icon="el-icon-upload" size="small" type="warning">发布文档</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 文档配置区域 -->
|
||||
<el-card class="document-config" shadow="never">
|
||||
<div slot="header">
|
||||
<span><i class="el-icon-setting"></i> 文档配置</span>
|
||||
</div>
|
||||
|
||||
<el-form :model="documentForm" label-width="100px" class="config-form">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="文档标题" required>
|
||||
<el-input v-model="documentForm.title" placeholder="请输入文档标题" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="文档类型" required>
|
||||
<el-select v-model="documentForm.type" placeholder="请选择文档类型" style="width: 100%">
|
||||
<el-option label="服务条款" value="1" />
|
||||
<el-option label="API文档" value="2" />
|
||||
<el-option label="挖矿教程" value="3" />
|
||||
<el-option label="其他" value="0" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="文档状态">
|
||||
<el-tag :type="documentForm.status === 'published' ? 'success' : 'info'">
|
||||
{{ documentForm.status === 'published' ? '已发布' : '草稿' }}
|
||||
</el-tag>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<!-- TinyMCE编辑器区域 -->
|
||||
<el-card class="editor-container" shadow="never">
|
||||
<div slot="header">
|
||||
<span><i class="el-icon-edit"></i> Quill文本编辑器</span>
|
||||
</div>
|
||||
|
||||
<!-- Quill编辑器 -->
|
||||
<div class="quill-wrapper">
|
||||
<quill-editor
|
||||
ref="quillEditor"
|
||||
v-model="documentForm.content"
|
||||
:options="quillConfig"
|
||||
@blur="onEditorBlur($event)"
|
||||
@focus="onEditorFocus($event)"
|
||||
@ready="onEditorReady($event)"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<!-- 使用指南 -->
|
||||
<el-card class="usage-guide" shadow="never">
|
||||
<div slot="header">
|
||||
<span><i class="el-icon-question"></i> 使用指南</span>
|
||||
</div>
|
||||
|
||||
<el-collapse v-model="activeGuide" accordion>
|
||||
<el-collapse-item title="📝 基本操作指南" name="basic">
|
||||
<div class="guide-content">
|
||||
<h4>工具栏功能说明:</h4>
|
||||
<ul>
|
||||
<li><strong>文字格式:</strong>粗体、斜体、下划线、删除线</li>
|
||||
<li><strong>字体颜色:</strong>选中文字后点击颜色按钮,选择文字颜色</li>
|
||||
<li><strong>背景颜色:</strong>选中文字后点击背景色按钮,设置文字背景色</li>
|
||||
<li><strong>字体大小:</strong>选择小号、正常、大号、超大字体</li>
|
||||
<li><strong>文本对齐:</strong>设置段落的左对齐、居中、右对齐</li>
|
||||
<li><strong>有序/无序列表:</strong>创建编号列表或项目符号列表,圆点会紧靠文字显示</li>
|
||||
<li><strong>链接:</strong>选中文字后点击链接按钮,输入网址创建超链接</li>
|
||||
<li><strong>标题:</strong>选择不同级别的标题格式</li>
|
||||
<li><strong>代码块:</strong>插入代码片段</li>
|
||||
<li><strong>清除格式:</strong>移除选中文字的所有格式</li>
|
||||
</ul>
|
||||
</div>
|
||||
</el-collapse-item>
|
||||
|
||||
<el-collapse-item title="💾 文档管理" name="document">
|
||||
<div class="guide-content">
|
||||
<h4>文档配置:</h4>
|
||||
<ul>
|
||||
<li><strong>文档标题:</strong>必填项,为您的文档起一个有意义的标题</li>
|
||||
<li><strong>文档类型:</strong>选择合适的文档类型(服务条款、API文档、挖矿教程等)</li>
|
||||
<li><strong>文档状态:</strong>显示当前文档是草稿还是已发布状态</li>
|
||||
</ul>
|
||||
|
||||
<h4>保存和发布:</h4>
|
||||
<ul>
|
||||
<li><strong>保存文档:</strong>将文档保存为草稿,可以稍后继续编辑</li>
|
||||
<li><strong>发布文档:</strong>正式发布文档,用户可以查看</li>
|
||||
<li><strong>预览文档:</strong>在发布前查看文档的最终效果</li>
|
||||
</ul>
|
||||
</div>
|
||||
</el-collapse-item>
|
||||
|
||||
<el-collapse-item title="🔧 使用技巧" name="tips">
|
||||
<div class="guide-content">
|
||||
<h4>编辑技巧:</h4>
|
||||
<ul>
|
||||
<li><strong>快速格式化:</strong>选中文字后直接点击工具栏按钮</li>
|
||||
<li><strong>颜色设置:</strong>先选中文字,再点击颜色按钮选择颜色</li>
|
||||
<li><strong>段落格式:</strong>光标在段落中时,点击标题按钮可设置整个段落</li>
|
||||
<li><strong>段落缩进:</strong>使用工具栏的缩进按钮或Tab键进行段落缩进,空格缩进在预览时可能不显示</li>
|
||||
<li><strong>列表嵌套:</strong>在列表项中按Tab键可以创建子列表</li>
|
||||
<li><strong>列表格式:</strong>无序列表的圆点现在会紧靠文字第一个字显示,编辑器和预览保持一致</li>
|
||||
<li><strong>链接编辑:</strong>点击已有链接可以修改链接地址</li>
|
||||
<li><strong>代码块:</strong>适合插入代码示例或技术文档</li>
|
||||
<li><strong>组合格式:</strong>可以同时使用多种格式(如红色粗体字)</li>
|
||||
<li><strong>空格保持:</strong>现在预览功能已优化,能正确显示文本前的空格缩进</li>
|
||||
</ul>
|
||||
|
||||
<h4>注意事项:</h4>
|
||||
<ul>
|
||||
<li>发布前建议先使用预览功能检查文档效果</li>
|
||||
<li>文档标题和类型是必填项,发布时会进行验证</li>
|
||||
<li>定期保存草稿以防止内容丢失</li>
|
||||
<li>使用适当的标题层级可以让文档结构更清晰</li>
|
||||
<li><strong>颜色使用建议:</strong>适度使用颜色,避免过多颜色影响阅读</li>
|
||||
<li><strong>对比度:</strong>确保文字颜色与背景有足够对比度,便于阅读</li>
|
||||
<li><strong>内容一致性:</strong>系统已优化,确保编辑器、预览、保存后显示的效果完全一致</li>
|
||||
<li><strong>空格缩进:</strong>现在完美支持空格缩进,编辑器中的空格会在预览和最终显示中保持</li>
|
||||
</ul>
|
||||
</div>
|
||||
</el-collapse-item>
|
||||
|
||||
<el-collapse-item title="⌨️ 快捷键" name="shortcuts">
|
||||
<div class="guide-content">
|
||||
<h4>常用快捷键:</h4>
|
||||
<div class="shortcut-list">
|
||||
<div class="shortcut-item">
|
||||
<span class="shortcut-key">Ctrl + B</span>
|
||||
<span class="shortcut-desc">粗体</span>
|
||||
</div>
|
||||
<div class="shortcut-item">
|
||||
<span class="shortcut-key">Ctrl + I</span>
|
||||
<span class="shortcut-desc">斜体</span>
|
||||
</div>
|
||||
<div class="shortcut-item">
|
||||
<span class="shortcut-key">Ctrl + U</span>
|
||||
<span class="shortcut-desc">下划线</span>
|
||||
</div>
|
||||
<div class="shortcut-item">
|
||||
<span class="shortcut-key">Ctrl + K</span>
|
||||
<span class="shortcut-desc">插入链接</span>
|
||||
</div>
|
||||
<div class="shortcut-item">
|
||||
<span class="shortcut-key">Ctrl + Z</span>
|
||||
<span class="shortcut-desc">撤销</span>
|
||||
</div>
|
||||
<div class="shortcut-item">
|
||||
<span class="shortcut-key">Ctrl + Y</span>
|
||||
<span class="shortcut-desc">重做</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-collapse-item>
|
||||
</el-collapse>
|
||||
</el-card>
|
||||
|
||||
<!-- 预览对话框 -->
|
||||
<el-dialog
|
||||
title="文档预览"
|
||||
:visible.sync="previewVisible"
|
||||
width="80%"
|
||||
top="5vh"
|
||||
class="preview-dialog"
|
||||
>
|
||||
<div class="preview-content content-display" v-html="getPreviewContent()"></div>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="previewVisible = false">关闭预览</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { quillEditor } from 'vue-quill-editor'
|
||||
import 'quill/dist/quill.core.css'
|
||||
import 'quill/dist/quill.snow.css'
|
||||
import 'quill/dist/quill.bubble.css'
|
||||
import { addDocument } from '../api/documentManagement'
|
||||
|
||||
export default {
|
||||
name: 'QuillEditor',
|
||||
components: {
|
||||
quillEditor
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 文档表单数据
|
||||
documentForm: {
|
||||
title: '',
|
||||
type: '',
|
||||
content: '',
|
||||
status: 'draft'
|
||||
},
|
||||
|
||||
// 加载状态
|
||||
saveLoading: false,
|
||||
publishLoading: false,
|
||||
|
||||
// 预览对话框
|
||||
previewVisible: false,
|
||||
|
||||
// 使用指南折叠面板
|
||||
activeGuide: '',
|
||||
|
||||
// Quill编辑器配置 - 包含颜色功能
|
||||
quillConfig: {
|
||||
theme: 'snow',
|
||||
placeholder: '请在此输入文档内容...',
|
||||
modules: {
|
||||
toolbar: [
|
||||
['bold', 'italic', 'underline', 'strike'],
|
||||
[{ 'color': [] }, { 'background': [] }], // 字体颜色和背景颜色
|
||||
[{ 'align': [] }],
|
||||
[{ 'list': 'ordered'}, { 'list': 'bullet' }],
|
||||
['link'],
|
||||
[{ 'header': [1, 2, 3, false] }],
|
||||
[{ 'size': ['small', false, 'large', 'huge'] }], // 字体大小
|
||||
['code-block'],
|
||||
['clean']
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
/**
|
||||
* 编辑器准备就绪
|
||||
*/
|
||||
onEditorReady(quill) {
|
||||
console.log('编辑器已准备就绪:', quill)
|
||||
},
|
||||
|
||||
/**
|
||||
* 编辑器获取焦点
|
||||
*/
|
||||
onEditorFocus(quill) {
|
||||
console.log('编辑器获取焦点:', quill)
|
||||
},
|
||||
|
||||
/**
|
||||
* 编辑器失去焦点
|
||||
*/
|
||||
onEditorBlur(quill) {
|
||||
console.log('编辑器失去焦点:', quill)
|
||||
// 确保内容一致性
|
||||
this.normalizeContent()
|
||||
},
|
||||
|
||||
/**
|
||||
* 规范化内容 - 确保编辑器、预览、后端传输内容一致
|
||||
*/
|
||||
normalizeContent() {
|
||||
if (this.documentForm.content) {
|
||||
// 统一空格和换行处理
|
||||
let normalizedContent = this.documentForm.content
|
||||
|
||||
// 确保HTML标签正确闭合
|
||||
normalizedContent = this.ensureProperHTMLStructure(normalizedContent)
|
||||
|
||||
// 更新绑定的内容
|
||||
this.documentForm.content = normalizedContent
|
||||
|
||||
console.log('内容规范化完成:', {
|
||||
original: this.documentForm.content.substring(0, 100),
|
||||
normalized: normalizedContent.substring(0, 100)
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 确保HTML结构正确
|
||||
*/
|
||||
ensureProperHTMLStructure(content) {
|
||||
// 创建临时DOM元素来规范化HTML
|
||||
const tempDiv = document.createElement('div')
|
||||
tempDiv.innerHTML = content
|
||||
|
||||
// 返回规范化后的HTML
|
||||
return tempDiv.innerHTML
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取用于传输的内容(确保与预览一致)
|
||||
*/
|
||||
getContentForTransfer() {
|
||||
// 先规范化内容
|
||||
this.normalizeContent()
|
||||
|
||||
// 返回最终要传给后端的内容
|
||||
return this.documentForm.content
|
||||
},
|
||||
|
||||
/**
|
||||
* 预览文档
|
||||
*/
|
||||
previewDocument() {
|
||||
if (!this.documentForm.content.trim()) {
|
||||
this.$message.warning('文档内容为空')
|
||||
return
|
||||
}
|
||||
|
||||
// 确保预览使用规范化的内容
|
||||
this.normalizeContent()
|
||||
|
||||
console.log('预览文档:', {
|
||||
contentLength: this.documentForm.content.length,
|
||||
contentPreview: this.documentForm.content.substring(0, 200)
|
||||
})
|
||||
|
||||
this.previewVisible = true
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取用于预览的内容(确保与后端传输一致)
|
||||
*/
|
||||
getPreviewContent() {
|
||||
// 返回规范化的内容用于预览
|
||||
return this.getContentForTransfer()
|
||||
},
|
||||
|
||||
/**
|
||||
* 保存文档
|
||||
*/
|
||||
async saveDocument() {
|
||||
if (!this.documentForm.title.trim()) {
|
||||
this.$message.warning('请输入文档标题')
|
||||
return
|
||||
}
|
||||
|
||||
this.saveLoading = true
|
||||
|
||||
try {
|
||||
// 获取规范化的内容
|
||||
const normalizedContent = this.getContentForTransfer()
|
||||
|
||||
const documentData = {
|
||||
title: this.documentForm.title,
|
||||
content: normalizedContent,
|
||||
type: this.documentForm.type || '0',
|
||||
lang: this.$i18n?.locale || 'zh',
|
||||
isDraft: true
|
||||
}
|
||||
|
||||
console.log('保存文档数据:', {
|
||||
title: documentData.title,
|
||||
contentLength: documentData.content.length,
|
||||
contentPreview: documentData.content.substring(0, 200)
|
||||
})
|
||||
|
||||
const response = await addDocument(documentData)
|
||||
|
||||
if (response && response.code === 200) {
|
||||
this.$message.success('文档保存成功')
|
||||
this.documentForm.status = 'draft'
|
||||
} else {
|
||||
throw new Error(response?.message || '保存失败')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('保存文档失败:', error)
|
||||
this.$message.error('保存失败: ' + (error.message || '未知错误'))
|
||||
} finally {
|
||||
this.saveLoading = false
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 发布文档
|
||||
*/
|
||||
async publishDocument() {
|
||||
if (!this.documentForm.title.trim()) {
|
||||
this.$message.warning('请输入文档标题')
|
||||
return
|
||||
}
|
||||
|
||||
if (!this.documentForm.content.trim()) {
|
||||
this.$message.warning('请输入文档内容')
|
||||
return
|
||||
}
|
||||
|
||||
if (!this.documentForm.type) {
|
||||
this.$message.warning('请选择文档类型')
|
||||
return
|
||||
}
|
||||
|
||||
this.publishLoading = true
|
||||
|
||||
try {
|
||||
// 获取规范化的内容
|
||||
const normalizedContent = this.getContentForTransfer()
|
||||
|
||||
const documentData = {
|
||||
title: this.documentForm.title,
|
||||
content: normalizedContent,
|
||||
type: this.documentForm.type,
|
||||
lang: this.$i18n?.locale || 'zh',
|
||||
isDraft: false
|
||||
}
|
||||
|
||||
console.log('发布文档数据:', {
|
||||
title: documentData.title,
|
||||
contentLength: documentData.content.length,
|
||||
contentPreview: documentData.content.substring(0, 200),
|
||||
hasIndentation: documentData.content.includes(' '), // 检查是否包含缩进
|
||||
hasNbsp: documentData.content.includes(' ') // 检查是否包含不间断空格
|
||||
})
|
||||
|
||||
const response = await addDocument(documentData)
|
||||
|
||||
if (response && response.code === 200) {
|
||||
this.$message.success('文档发布成功')
|
||||
this.documentForm.status = 'published'
|
||||
|
||||
this.$notify({
|
||||
title: '发布成功',
|
||||
message: `文档 "${this.documentForm.title}" 已成功发布`,
|
||||
type: 'success',
|
||||
duration: 3000
|
||||
})
|
||||
} else {
|
||||
throw new Error(response?.message || '发布失败')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('发布文档失败:', error)
|
||||
this.$message.error('发布失败: ' + (error.message || '未知错误'))
|
||||
} finally {
|
||||
this.publishLoading = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.rich-text-editor-page {
|
||||
padding: 20px;
|
||||
background: #f5f7fa;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
/* 页面头部 */
|
||||
.page-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 24px;
|
||||
padding: 20px;
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.header-content {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
margin: 0 0 8px 0;
|
||||
color: #2c3e50;
|
||||
font-size: 28px;
|
||||
font-weight: 600;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
|
||||
i {
|
||||
color: #5721E4;
|
||||
font-size: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
.page-subtitle {
|
||||
margin: 0;
|
||||
color: #7f8c8d;
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.header-actions {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
/* 文档配置 */
|
||||
.document-config {
|
||||
margin-bottom: 20px;
|
||||
|
||||
:deep(.el-card__header) {
|
||||
background: #f8f9fa;
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
font-weight: 600;
|
||||
color: #2c3e50;
|
||||
|
||||
i {
|
||||
color: #5721E4;
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.config-form {
|
||||
.el-form-item {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 编辑器容器 */
|
||||
.editor-container {
|
||||
margin-bottom: 20px;
|
||||
|
||||
:deep(.el-card__header) {
|
||||
background: #f8f9fa;
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
font-weight: 600;
|
||||
color: #2c3e50;
|
||||
|
||||
i {
|
||||
color: #5721E4;
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.quill-wrapper {
|
||||
:deep(.ql-editor) {
|
||||
min-height: 400px;
|
||||
font-size: 14px;
|
||||
line-height: 1.6;
|
||||
white-space: pre-wrap; /* 保持编辑器中的空格 */
|
||||
}
|
||||
|
||||
/* 编辑器中的列表样式 - 确保圆点显示正确 */
|
||||
:deep(.ql-editor ul) {
|
||||
padding-left: 0 !important;
|
||||
list-style-position: inside !important;
|
||||
}
|
||||
|
||||
:deep(.ql-editor ol) {
|
||||
padding-left: 0 !important;
|
||||
list-style-position: inside !important;
|
||||
}
|
||||
|
||||
:deep(.ql-editor li) {
|
||||
padding-left: 0 !important;
|
||||
text-indent: 0 !important;
|
||||
}
|
||||
|
||||
:deep(.ql-toolbar) {
|
||||
border-top: 1px solid #e0e0e0;
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
:deep(.ql-container) {
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
border-left: 1px solid #e0e0e0;
|
||||
border-right: 1px solid #e0e0e0;
|
||||
border-radius: 0 0 6px 6px;
|
||||
}
|
||||
|
||||
:deep(.ql-toolbar) {
|
||||
border-radius: 6px 6px 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* 使用指南 */
|
||||
.usage-guide {
|
||||
margin-bottom: 20px;
|
||||
|
||||
:deep(.el-card__header) {
|
||||
background: #f8f9fa;
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
font-weight: 600;
|
||||
color: #2c3e50;
|
||||
|
||||
i {
|
||||
color: #5721E4;
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.guide-content {
|
||||
padding: 16px 0;
|
||||
|
||||
h4 {
|
||||
color: #2c3e50;
|
||||
margin-top: 0;
|
||||
margin-bottom: 12px;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin: 0;
|
||||
padding-left: 20px;
|
||||
|
||||
li {
|
||||
margin-bottom: 8px;
|
||||
line-height: 1.6;
|
||||
color: #555;
|
||||
|
||||
strong {
|
||||
color: #2c3e50;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.shortcut-list {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||
gap: 12px;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.shortcut-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 8px 12px;
|
||||
background: #f8f9fa;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #e0e0e0;
|
||||
|
||||
.shortcut-key {
|
||||
font-family: 'Monaco', 'Consolas', monospace;
|
||||
background: #2c3e50;
|
||||
color: white;
|
||||
padding: 2px 6px;
|
||||
border-radius: 3px;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.shortcut-desc {
|
||||
color: #555;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.usage-guide .el-collapse) {
|
||||
border: none;
|
||||
|
||||
.el-collapse-item__header {
|
||||
background: #f8f9fa;
|
||||
border: 1px solid #e0e0e0;
|
||||
border-radius: 6px;
|
||||
margin-bottom: 8px;
|
||||
padding: 0 16px;
|
||||
font-weight: 500;
|
||||
color: #2c3e50;
|
||||
|
||||
&:hover {
|
||||
background: #e9ecef;
|
||||
}
|
||||
}
|
||||
|
||||
.el-collapse-item__content {
|
||||
padding: 0 16px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.el-collapse-item__wrap {
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* 统一的内容显示样式 - 确保编辑器、预览、后端显示一致 */
|
||||
.content-display {
|
||||
/* 核心样式 - 确保空格和格式保持 */
|
||||
white-space: pre-wrap !important; /* 保持空格和换行 */
|
||||
word-wrap: break-word !important; /* 防止长单词溢出 */
|
||||
word-break: break-word !important; /* 长单词换行 */
|
||||
|
||||
/* 字体和行高 */
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif !important;
|
||||
font-size: 14px !important;
|
||||
line-height: 1.6 !important;
|
||||
color: #2c3e50 !important;
|
||||
|
||||
/* 段落和元素间距 */
|
||||
:deep(p) {
|
||||
margin: 10px 0 !important;
|
||||
line-height: 1.6 !important;
|
||||
}
|
||||
|
||||
:deep(h1), :deep(h2), :deep(h3) {
|
||||
color: #2c3e50 !important;
|
||||
margin: 24px 0 12px 0 !important;
|
||||
font-weight: 600 !important;
|
||||
}
|
||||
|
||||
:deep(ul), :deep(ol) {
|
||||
margin: 10px 0 !important;
|
||||
padding-left: 0 !important; /* 移除默认的左边距 */
|
||||
list-style-position: inside !important; /* 圆点在内部,紧靠文字 */
|
||||
line-height: 1.6 !important;
|
||||
}
|
||||
|
||||
:deep(li) {
|
||||
margin: 6px 0 !important;
|
||||
line-height: 1.6 !important;
|
||||
padding-left: 0 !important; /* 移除li的内边距 */
|
||||
text-indent: 0 !important; /* 确保文字不缩进 */
|
||||
}
|
||||
|
||||
/* 表格样式 */
|
||||
:deep(table) {
|
||||
border-collapse: collapse !important;
|
||||
width: 100% !important;
|
||||
margin: 16px 0 !important;
|
||||
|
||||
th, td {
|
||||
border: 1px solid #ddd !important;
|
||||
padding: 8px !important;
|
||||
text-align: left !important;
|
||||
}
|
||||
|
||||
th {
|
||||
background-color: #f5f5f5 !important;
|
||||
font-weight: 600 !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* 代码样式 */
|
||||
:deep(pre) {
|
||||
background: #f8f9fa !important;
|
||||
padding: 16px !important;
|
||||
border-radius: 4px !important;
|
||||
overflow-x: auto !important;
|
||||
white-space: pre-wrap !important;
|
||||
}
|
||||
|
||||
:deep(code) {
|
||||
background: #f4f4f4 !important;
|
||||
padding: 2px 4px !important;
|
||||
border-radius: 3px !important;
|
||||
font-family: 'Monaco', 'Consolas', monospace !important;
|
||||
}
|
||||
|
||||
/* 链接样式 */
|
||||
:deep(a) {
|
||||
color: #5721E4 !important;
|
||||
text-decoration: none !important;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* 强调样式 */
|
||||
:deep(strong) {
|
||||
font-weight: 600 !important;
|
||||
}
|
||||
|
||||
:deep(em) {
|
||||
font-style: italic !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* 预览对话框 */
|
||||
.preview-dialog {
|
||||
:deep(.el-dialog__body) {
|
||||
max-height: 60vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.preview-content {
|
||||
padding: 20px;
|
||||
background: #fff;
|
||||
border: 1px solid #e0e0e0;
|
||||
border-radius: 6px;
|
||||
/* 特殊样式组件 */
|
||||
:deep(.anchor-point) {
|
||||
background: #e6f7ff !important;
|
||||
border: 1px dashed #1890ff !important;
|
||||
padding: 2px 6px !important;
|
||||
border-radius: 3px !important;
|
||||
color: #1890ff !important;
|
||||
font-weight: 500 !important;
|
||||
}
|
||||
|
||||
:deep(.important-note) {
|
||||
background: #f6ffed !important;
|
||||
border: 1px solid #b7eb8f !important;
|
||||
border-radius: 4px !important;
|
||||
padding: 12px !important;
|
||||
margin: 12px 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* 响应式设计 */
|
||||
@media screen and (max-width: 768px) {
|
||||
.rich-text-editor-page {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.page-header {
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.header-actions {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
font-size: 24px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.config-form .el-row .el-col {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.shortcut-list {
|
||||
grid-template-columns: 1fr;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.shortcut-item {
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
</style>
|
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
|
@ -1 +1 @@
|
|||
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1"><meta name=google-site-verification content=pKAZogQ0NQ6L4j9-V58WJMjm7zYCFwkJXSJzWu9UDM8><meta name=robots content="index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1"><meta name=googlebot content="index, follow"><meta name=googlebot-news content="index, follow"><meta name=bingbot content="index, follow"><link rel=alternate hreflang=zh href=https://m2pool.com/zh><link rel=alternate hreflang=en href=https://m2pool.com/en><link rel=alternate hreflang=x-default href=https://m2pool.com/en><meta property=og:title content="M2pool - Stable leading high-yield mining pool"><meta property=og:description content="M2Pool provides professional mining services, supporting multiple cryptocurrency mining"><meta property=og:url content=https://m2pool.com/en><meta property=og:site_name content=M2Pool><meta property=og:type content=website><meta property=og:image content=https://m2pool.com/logo.png><link rel=icon href=/favicon.ico><link rel=stylesheet href=//at.alicdn.com/t/c/font_4582735_7i8wfzc0art.css><title>M2pool - Stable leading high-yield mining pool</title><meta name=keywords content="M2Pool, cryptocurrency mining pool,Entropyx(enx),entropyx, bitcoin mining, DGB mining, mining pool service, 加密货币矿池, 比特币挖矿, DGB挖矿"><meta name=description content="M2Pool provides professional mining services, supporting multiple cryptocurrency mining, including nexa, grs, mona, dgb, rxd, enx"><meta name=format-detection content="telephone=no"><meta name=apple-mobile-web-app-capable content=yes><script defer src=/js/chunk-vendors-945ce2fe.648a91a9.js></script><script defer src=/js/chunk-vendors-aacc2dbb.d317c558.js></script><script defer src=/js/chunk-vendors-bc050c32.3f2f14d2.js></script><script defer src=/js/chunk-vendors-3003db77.d0b93d36.js></script><script defer src=/js/chunk-vendors-9d134daf.bb668c99.js></script><script defer src=/js/chunk-vendors-439af1fa.48a48f35.js></script><script defer src=/js/chunk-vendors-5c533fba.b9c00e08.js></script><script defer src=/js/chunk-vendors-96cecd74.a7d9b845.js></script><script defer src=/js/chunk-vendors-c5c6856a.635a8cad.js></script><script defer src=/js/chunk-vendors-cca472bf.9545e49e.js></script><script defer src=/js/chunk-vendors-377fed06.79dbd1e2.js></script><script defer src=/js/chunk-vendors-0dc8c06b.8c238ff1.js></script><script defer src=/js/chunk-vendors-5fc483a3.764e837b.js></script><script defer src=/js/chunk-vendors-5a805870.4cfc0ae8.js></script><script defer src=/js/chunk-vendors-cf2e0a28.c6e99da0.js></script><script defer src=/js/app-42f9d7e6.a72a71c4.js></script><script defer src=/js/app-89ec8940.10a6eac4.js></script><script defer src=/js/app-d363ae0c.4e837441.js></script><script defer src=/js/app-5c551db8.f371968e.js></script><script defer src=/js/app-b4c4f6ec.694d520a.js></script><script defer src=/js/app-45954fd3.3eca7309.js></script><script defer src=/js/app-a6ba6ead.99f4f586.js></script><script defer src=/js/app-93e14cbe.808377ef.js></script><script defer src=/js/app-72600b29.6108bda3.js></script><script defer src=/js/app-f035d474.34668127.js></script><script defer src=/js/app-7023e5b0.a956a90d.js></script><script defer src=/js/app-113c6c50.eedc8429.js></script><link href=/css/chunk-vendors-5c533fba.6f97509c.css rel=stylesheet><link href=/css/chunk-vendors-cca472bf.3cf4fa64.css rel=stylesheet><link href=/css/app-189e7968.a2f5d347.css rel=stylesheet><link href=/css/app-b4c4f6ec.6e507abe.css rel=stylesheet><link href=/css/app-72600b29.84aa355f.css rel=stylesheet><link href=/css/app-f035d474.0348646a.css rel=stylesheet><link href=/css/app-7023e5b0.87f1eef9.css rel=stylesheet><link href=/css/app-113c6c50.ed286d28.css rel=stylesheet></head><body><div id=app></div></body></html>
|
||||
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1"><meta name=google-site-verification content=pKAZogQ0NQ6L4j9-V58WJMjm7zYCFwkJXSJzWu9UDM8><meta name=robots content="index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1"><meta name=googlebot content="index, follow"><meta name=googlebot-news content="index, follow"><meta name=bingbot content="index, follow"><link rel=alternate hreflang=zh href=https://m2pool.com/zh><link rel=alternate hreflang=en href=https://m2pool.com/en><link rel=alternate hreflang=x-default href=https://m2pool.com/en><meta property=og:title content="M2pool - Stable leading high-yield mining pool"><meta property=og:description content="M2Pool provides professional mining services, supporting multiple cryptocurrency mining"><meta property=og:url content=https://m2pool.com/en><meta property=og:site_name content=M2Pool><meta property=og:type content=website><meta property=og:image content=https://m2pool.com/logo.png><link rel=icon href=/favicon.ico><link rel=stylesheet href=//at.alicdn.com/t/c/font_4582735_7i8wfzc0art.css><title>M2pool - Stable leading high-yield mining pool</title><meta name=keywords content="M2Pool, cryptocurrency mining pool,Entropyx(enx),entropyx, bitcoin mining, DGB mining, mining pool service, 加密货币矿池, 比特币挖矿, DGB挖矿"><meta name=description content="M2Pool provides professional mining services, supporting multiple cryptocurrency mining, including nexa, grs, mona, dgb, rxd, enx"><meta name=format-detection content="telephone=no"><meta name=apple-mobile-web-app-capable content=yes><script defer src=/js/chunk-vendors-945ce2fe.648a91a9.js></script><script defer src=/js/chunk-vendors-aacc2dbb.d317c558.js></script><script defer src=/js/chunk-vendors-bc050c32.3f2f14d2.js></script><script defer src=/js/chunk-vendors-3003db77.d0b93d36.js></script><script defer src=/js/chunk-vendors-9d134daf.bb668c99.js></script><script defer src=/js/chunk-vendors-439af1fa.48a48f35.js></script><script defer src=/js/chunk-vendors-5c533fba.b9c00e08.js></script><script defer src=/js/chunk-vendors-96cecd74.a7d9b845.js></script><script defer src=/js/chunk-vendors-c5c6856a.635a8cad.js></script><script defer src=/js/chunk-vendors-cca472bf.9545e49e.js></script><script defer src=/js/chunk-vendors-377fed06.79dbd1e2.js></script><script defer src=/js/chunk-vendors-0dc8c06b.8c238ff1.js></script><script defer src=/js/chunk-vendors-5fc483a3.764e837b.js></script><script defer src=/js/chunk-vendors-5a805870.4cfc0ae8.js></script><script defer src=/js/chunk-vendors-cf2e0a28.c6e99da0.js></script><script defer src=/js/chunk-vendors-c9ff040c.57bd8c18.js></script><script defer src=/js/app-42f9d7e6.a2ad6942.js></script><script defer src=/js/app-d87c119a.ee3211eb.js></script><script defer src=/js/app-5c551db8.905e7865.js></script><script defer src=/js/app-b4c4f6ec.f05c7060.js></script><script defer src=/js/app-45954fd3.d2156f4b.js></script><script defer src=/js/app-a6ba6ead.0e42fe00.js></script><script defer src=/js/app-af2560cd.85129667.js></script><script defer src=/js/app-0a0a89cb.265f0701.js></script><script defer src=/js/app-abee3193.b1fe66b4.js></script><script defer src=/js/app-f035d474.a2a8f5af.js></script><script defer src=/js/app-7023e5b0.3fe9d138.js></script><script defer src=/js/app-113c6c50.88a0041a.js></script><link href=/css/chunk-vendors-5c533fba.6f97509c.css rel=stylesheet><link href=/css/chunk-vendors-cca472bf.3cf4fa64.css rel=stylesheet><link href=/css/app-42f9d7e6.3510b1e0.css rel=stylesheet><link href=/css/app-d87c119a.e332b0bd.css rel=stylesheet><link href=/css/app-b4c4f6ec.61949656.css rel=stylesheet><link href=/css/app-0a0a89cb.2754ed98.css rel=stylesheet><link href=/css/app-abee3193.46a8002a.css rel=stylesheet><link href=/css/app-f035d474.0348646a.css rel=stylesheet><link href=/css/app-7023e5b0.e2d4ad34.css rel=stylesheet><link href=/css/app-113c6c50.4361cf69.css rel=stylesheet></head><body><div id=app></div></body></html>
|
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
|
@ -1 +1 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns:video="http://www.google.com/schemas/sitemap-video/1.1"><url><loc>https://m2pool.com/en</loc><lastmod>2025-07-16T08:11:32.323Z</lastmod><changefreq>daily</changefreq><priority>1.0</priority></url><url><loc>https://m2pool.com/en/dataDisplay</loc><lastmod>2025-07-16T08:11:32.323Z</lastmod><changefreq>weekly</changefreq><priority>0.8</priority></url><url><loc>https://m2pool.com/en/ServiceTerms</loc><lastmod>2025-07-16T08:11:32.323Z</lastmod><changefreq>monthly</changefreq><priority>0.6</priority></url><url><loc>https://m2pool.com/en/apiFile</loc><lastmod>2025-07-16T08:11:32.323Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/en/rate</loc><lastmod>2025-07-16T08:11:32.323Z</lastmod><changefreq>weekly</changefreq><priority>0.8</priority></url><url><loc>https://m2pool.com/en/AccessMiningPool/nexaAccess</loc><lastmod>2025-07-16T08:11:32.323Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/en/AccessMiningPool/grsAccess</loc><lastmod>2025-07-16T08:11:32.323Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/en/AccessMiningPool/monaAccess</loc><lastmod>2025-07-16T08:11:32.323Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/en/AccessMiningPool/dgbsAccess</loc><lastmod>2025-07-16T08:11:32.323Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/en/AccessMiningPool/dgbqAccess</loc><lastmod>2025-07-16T08:11:32.323Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/en/AccessMiningPool/dgboAccess</loc><lastmod>2025-07-16T08:11:32.323Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/en/AccessMiningPool/rxdAccess</loc><lastmod>2025-07-16T08:11:32.323Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url></urlset>
|
||||
<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns:video="http://www.google.com/schemas/sitemap-video/1.1"><url><loc>https://m2pool.com/en</loc><lastmod>2025-07-31T07:15:06.269Z</lastmod><changefreq>daily</changefreq><priority>1.0</priority></url><url><loc>https://m2pool.com/en/dataDisplay</loc><lastmod>2025-07-31T07:15:06.269Z</lastmod><changefreq>weekly</changefreq><priority>0.8</priority></url><url><loc>https://m2pool.com/en/ServiceTerms</loc><lastmod>2025-07-31T07:15:06.269Z</lastmod><changefreq>monthly</changefreq><priority>0.6</priority></url><url><loc>https://m2pool.com/en/apiFile</loc><lastmod>2025-07-31T07:15:06.269Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/en/rate</loc><lastmod>2025-07-31T07:15:06.269Z</lastmod><changefreq>weekly</changefreq><priority>0.8</priority></url><url><loc>https://m2pool.com/en/AccessMiningPool/nexaAccess</loc><lastmod>2025-07-31T07:15:06.269Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/en/AccessMiningPool/grsAccess</loc><lastmod>2025-07-31T07:15:06.269Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/en/AccessMiningPool/monaAccess</loc><lastmod>2025-07-31T07:15:06.269Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/en/AccessMiningPool/dgbsAccess</loc><lastmod>2025-07-31T07:15:06.269Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/en/AccessMiningPool/dgbqAccess</loc><lastmod>2025-07-31T07:15:06.269Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/en/AccessMiningPool/dgboAccess</loc><lastmod>2025-07-31T07:15:06.269Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/en/AccessMiningPool/rxdAccess</loc><lastmod>2025-07-31T07:15:06.269Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url></urlset>
|
Binary file not shown.
|
@ -1 +1 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns:video="http://www.google.com/schemas/sitemap-video/1.1"><url><loc>https://m2pool.com/zh</loc><lastmod>2025-07-16T08:11:32.315Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/dataDisplay</loc><lastmod>2025-07-16T08:11:32.315Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/ServiceTerms</loc><lastmod>2025-07-16T08:11:32.315Z</lastmod><changefreq>monthly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/apiFile</loc><lastmod>2025-07-16T08:11:32.315Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/rate</loc><lastmod>2025-07-16T08:11:32.315Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/AccessMiningPool/nexaAccess</loc><lastmod>2025-07-16T08:11:32.315Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/AccessMiningPool/grsAccess</loc><lastmod>2025-07-16T08:11:32.315Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/AccessMiningPool/monaAccess</loc><lastmod>2025-07-16T08:11:32.315Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/AccessMiningPool/dgbsAccess</loc><lastmod>2025-07-16T08:11:32.315Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/AccessMiningPool/dgbqAccess</loc><lastmod>2025-07-16T08:11:32.315Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/AccessMiningPool/dgboAccess</loc><lastmod>2025-07-16T08:11:32.315Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/AccessMiningPool/rxdAccess</loc><lastmod>2025-07-16T08:11:32.315Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url></urlset>
|
||||
<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns:video="http://www.google.com/schemas/sitemap-video/1.1"><url><loc>https://m2pool.com/zh</loc><lastmod>2025-07-31T07:15:06.261Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/dataDisplay</loc><lastmod>2025-07-31T07:15:06.261Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/ServiceTerms</loc><lastmod>2025-07-31T07:15:06.261Z</lastmod><changefreq>monthly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/apiFile</loc><lastmod>2025-07-31T07:15:06.261Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/rate</loc><lastmod>2025-07-31T07:15:06.261Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/AccessMiningPool/nexaAccess</loc><lastmod>2025-07-31T07:15:06.261Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/AccessMiningPool/grsAccess</loc><lastmod>2025-07-31T07:15:06.261Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/AccessMiningPool/monaAccess</loc><lastmod>2025-07-31T07:15:06.261Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/AccessMiningPool/dgbsAccess</loc><lastmod>2025-07-31T07:15:06.261Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/AccessMiningPool/dgbqAccess</loc><lastmod>2025-07-31T07:15:06.261Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/AccessMiningPool/dgboAccess</loc><lastmod>2025-07-31T07:15:06.261Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url><url><loc>https://m2pool.com/zh/AccessMiningPool/rxdAccess</loc><lastmod>2025-07-31T07:15:06.261Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url></urlset>
|
Binary file not shown.
Loading…
Reference in New Issue