diff --git a/README-UEditor.md b/README-UEditor.md
new file mode 100644
index 0000000..a1b1a66
--- /dev/null
+++ b/README-UEditor.md
@@ -0,0 +1,351 @@
+# UEditor 富文本编辑器组件
+
+## 概述
+
+UEditor 是一个基于 `vue-ueditor-wrap` 的富文本编辑器组件,专门为文章管理、内容编辑等场景设计。该组件已经集成到文章管理系统中,支持富文本编辑、图片上传、表格插入等功能。
+
+## 功能特性
+
+### 🎯 核心功能
+- **富文本编辑**:支持文本格式化、段落样式、列表等
+- **图片管理**:支持图片上传、插入、编辑
+- **表格功能**:支持表格插入、编辑、合并单元格
+- **媒体支持**:支持视频、附件插入
+- **代码插入**:支持代码块插入和语法高亮
+- **内容导入**:支持Word、Markdown文档导入
+
+### 🚀 增强功能
+- **自动保存**:60秒自动保存,防止内容丢失
+- **全屏编辑**:支持全屏模式,提升编辑体验
+- **响应式设计**:自适应不同屏幕尺寸
+- **右键菜单**:支持右键快捷操作
+- **工具栏定制**:丰富的工具栏配置
+
+## 快速开始
+
+### 1. 基本用法
+
+```vue
+
+
+
+
+
+```
+
+### 2. 表单集成
+
+```vue
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+### 3. 条件显示
+
+```vue
+
+
+
+```
+
+## 配置说明
+
+### 编辑器配置
+
+```javascript
+const editorConfig = {
+ // 文件上传接口
+ serverUrl: '/admin/api/admin/system/editor',
+
+ // 请求头配置
+ serverHeaders: {
+ 'Authorization': 'Bearer ' + localStorage.getItem('token')
+ },
+
+ // 编辑器尺寸
+ initialFrameHeight: 500,
+ initialFrameWidth: '100%',
+
+ // 自动保存
+ enableAutoSave: true,
+ autoSaveInterval: 60000,
+
+ // 其他配置
+ loadConfigFromServer: true,
+ enableContextMenu: true,
+ catchRemoteImageEnable: false
+};
+```
+
+### 工具栏配置
+
+工具栏包含以下功能组:
+
+#### 基础编辑
+- `undo` - 撤销
+- `redo` - 重做
+- `formatmatch` - 格式刷
+- `autotypeset` - 自动排版
+
+#### 文本格式
+- `bold` - 加粗
+- `italic` - 斜体
+- `underline` - 下划线
+- `forecolor` - 字体颜色
+- `backcolor` - 背景色
+- `fontfamily` - 字体
+- `fontsize` - 字号
+
+#### 段落格式
+- `justifyleft` - 左对齐
+- `justifycenter` - 居中对齐
+- `justifyright` - 右对齐
+- `justifyjustify` - 两端对齐
+- `indent` - 首行缩进
+- `lineheight` - 行间距
+
+#### 插入功能
+- `simpleupload` - 单图上传
+- `insertimage` - 多图上传
+- `insertvideo` - 视频插入
+- `attachment` - 附件插入
+- `inserttable` - 表格插入
+- `link` - 超链接
+- `insertcode` - 代码插入
+
+#### 高级功能
+- `contentimport` - 内容导入
+- `template` - 模板
+- `formula` - 公式
+- `print` - 打印
+- `preview` - 预览
+
+## 在文章管理中的应用
+
+### 文章编辑表单
+
+文章管理系统中已经集成了UEditor组件,用于编辑文章内容:
+
+```vue
+
+
+
+
请在此处编辑文章内容,支持富文本格式、图片上传、表格等功能
+
+
+
+```
+
+### 表单验证
+
+```javascript
+const rules = {
+ articleContent: [{
+ required: !isLinkChecked.value,
+ message: '内容 必填',
+ validator: (rule, value) => {
+ if (isLinkChecked.value) {
+ return Promise.resolve();
+ }
+ if (!value || value.trim() === '') {
+ return Promise.reject('内容 必填');
+ }
+ return Promise.resolve();
+ }
+ }]
+};
+```
+
+### 内容处理
+
+```javascript
+// 获取纯文本内容
+if (form.articleContent) {
+ form.articleContentText = form.articleContent.replace(/<[^>]*>/g, '');
+}
+```
+
+## 样式定制
+
+### 编辑器容器样式
+
+```css
+.editor-container {
+ position: relative;
+ border: 1px solid #d9d9d9;
+ border-radius: 4px;
+ padding: 10px;
+ background-color: #fafafa;
+ min-height: 200px;
+}
+
+.editor-tip {
+ position: absolute;
+ top: 10px;
+ left: 10px;
+ background-color: #fff;
+ padding: 5px 10px;
+ border-radius: 4px;
+ font-size: 12px;
+ color: #8c8c8c;
+ z-index: 1;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+}
+```
+
+### 组件样式优化
+
+UEditor组件本身已经包含了样式优化:
+
+```css
+.uebox {
+ width: 100%;
+ border-radius: 6px;
+ overflow: hidden;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+}
+
+.uebox :deep(.edui-editor-toolbarbox) {
+ background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
+ border-bottom: 1px solid #e8e8e8;
+}
+```
+
+## 注意事项
+
+### 1. ID唯一性
+每个UEditor实例必须有唯一的ID,避免冲突:
+
+```vue
+
+
+```
+
+### 2. 数据绑定
+使用v-model进行双向数据绑定:
+
+```vue
+
+```
+
+### 3. 表单验证
+在表单验证规则中正确处理富文本内容:
+
+```javascript
+// 检查内容是否为空
+if (!form.content || form.content.trim() === '') {
+ return Promise.reject('内容不能为空');
+}
+```
+
+### 4. 内容安全
+提交时注意HTML内容的处理和安全过滤:
+
+```javascript
+// 简单的HTML标签移除
+const plainText = htmlContent.replace(/<[^>]*>/g, '');
+
+// 或者使用专门的HTML清理库
+import DOMPurify from 'dompurify';
+const cleanHtml = DOMPurify.sanitize(htmlContent);
+```
+
+### 5. 性能优化
+避免在同一个页面中使用过多编辑器实例,合理控制数量。
+
+## 测试页面
+
+项目包含了一个测试页面用于验证UEditor组件功能:
+
+**文件位置**: `src/views/business/ueditor-test.vue`
+
+测试页面包含:
+- 基本功能测试
+- 表单集成测试
+- 内容预览
+- 操作按钮测试
+
+## 文件结构
+
+```
+src/
+├── components/
+│ └── business/
+│ └── ueditor.vue # UEditor组件
+├── views/
+│ └── business/
+│ └── case-clinical-article/
+│ ├── case-clinical-article-form.vue # 文章编辑表单
+│ └── case-clinical-article-list.vue # 文章列表
+└── public/
+ └── UEditorPlus/ # UEditor资源文件
+ ├── ueditor.all.js
+ ├── ueditor.config.js
+ ├── ueditor.parse.js
+ └── ...
+```
+
+## 依赖说明
+
+- **vue-ueditor-wrap**: Vue3的UEditor包装器
+- **UEditorPlus**: 富文本编辑器核心库
+- **Ant Design Vue**: UI组件库(用于表单和样式)
+
+## 更新日志
+
+### v1.0.0 (当前版本)
+- ✅ 基础富文本编辑功能
+- ✅ 图片上传和管理
+- ✅ 表格插入和编辑
+- ✅ 自动保存功能
+- ✅ 响应式设计
+- ✅ 文章管理集成
+- ✅ 样式优化
+
+## 技术支持
+
+如有问题,请检查:
+1. 控制台错误信息
+2. 网络请求状态
+3. 组件导入路径
+4. ID唯一性
+5. 数据绑定正确性
+
+## 相关链接
+
+- [UEditorPlus 官方文档](https://doc.ueditorplus.com/)
+- [vue-ueditor-wrap 文档](https://github.com/HaoChuan9421/vue-ueditor-wrap)
+- [Ant Design Vue 文档](https://antdv.com/)
\ No newline at end of file
diff --git a/UEditor使用示例.md b/UEditor使用示例.md
new file mode 100644
index 0000000..3b7963d
--- /dev/null
+++ b/UEditor使用示例.md
@@ -0,0 +1,255 @@
+# UEditor 富文本编辑器使用示例
+
+## 组件介绍
+
+UEditor 是一个基于 vue-ueditor-wrap 的富文本编辑器组件,专门为文章管理、内容编辑等场景设计。
+
+## 基本用法
+
+### 1. 导入组件
+
+```vue
+import UEditor from '/@/components/business/ueditor.vue';
+```
+
+### 2. 在模板中使用
+
+```vue
+
+
+
+```
+
+## 文章管理中的使用示例
+
+### 文章编辑表单
+
+```vue
+
+
+
+
+
+
+
+
+
+
请在此处编辑文章内容,支持富文本格式、图片上传、表格等功能
+
+
+
+
+
+
+
+ 取消
+ 保存
+
+
+
+
+
+
+
+
+```
+
+### 文章列表中的使用
+
+```vue
+
+
+
新建文章
+
+
+
+
+
+ 编辑
+ 查看
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+## 组件特性
+
+### 1. 自动保存
+- 支持60秒自动保存
+- 防止内容丢失
+
+### 2. 丰富的工具栏
+- 文本格式化(加粗、斜体、下划线等)
+- 段落样式(对齐、缩进、行距等)
+- 图片上传和管理
+- 表格插入和编辑
+- 链接和锚点
+- 代码插入
+- 内容导入(支持Word、Markdown)
+
+### 3. 响应式设计
+- 自适应宽度
+- 可调整高度
+- 支持全屏编辑
+
+### 4. 文件上传
+- 图片上传
+- 附件上传
+- 支持拖拽上传
+
+## 配置说明
+
+### 编辑器配置
+
+```javascript
+const editorConfig = {
+ serverUrl: '/admin/api/admin/system/editor', // 文件上传接口
+ initialFrameHeight: 500, // 编辑器高度
+ initialFrameWidth: '100%', // 编辑器宽度
+ enableAutoSave: true, // 启用自动保存
+ autoSaveInterval: 60000, // 自动保存间隔(毫秒)
+ enableContextMenu: true, // 启用右键菜单
+ catchRemoteImageEnable: false, // 是否抓取远程图片
+};
+```
+
+### 工具栏配置
+
+工具栏包含以下主要功能组:
+- **基础编辑**:撤销、重做、格式刷等
+- **文本格式**:字体、字号、颜色、背景色等
+- **段落格式**:对齐、缩进、行距等
+- **插入功能**:图片、视频、表格、链接等
+- **高级功能**:代码、公式、模板等
+
+## 注意事项
+
+1. **ID唯一性**:每个UEditor实例必须有唯一的ID
+2. **数据绑定**:使用v-model进行双向数据绑定
+3. **表单验证**:在表单验证规则中正确处理富文本内容
+4. **内容处理**:提交时注意HTML内容的处理和安全过滤
+5. **性能优化**:避免在同一个页面中使用过多编辑器实例
+
+## 常见问题
+
+### Q: 编辑器不显示怎么办?
+A: 检查是否正确导入了组件,确保ID唯一,检查控制台是否有错误信息。
+
+### Q: 图片上传失败怎么办?
+A: 检查serverUrl配置是否正确,确保后端接口正常工作。
+
+### Q: 如何获取纯文本内容?
+A: 可以通过正则表达式去除HTML标签:`content.replace(/<[^>]*>/g, '')`
+
+### Q: 编辑器高度可以调整吗?
+A: 可以通过initialFrameHeight配置项调整,也支持动态调整。
+
+## 更多示例
+
+更多使用示例请参考:
+- `src/views/business/case-clinical-article/case-clinical-article-form.vue`
+- `src/components/business/ueditor.vue`
\ No newline at end of file
diff --git a/UEditor导入路径修正说明.md b/UEditor导入路径修正说明.md
new file mode 100644
index 0000000..50c1ab0
--- /dev/null
+++ b/UEditor导入路径修正说明.md
@@ -0,0 +1,160 @@
+# UEditor 组件导入路径修正说明
+
+## 问题描述
+
+在项目运行过程中出现以下错误:
+
+```
+[plugin:vite:import-analysis] Failed to resolve import "/@/utils/ueditor.vue" from "src/views/business/case-clinical-article/case-clinical-article-form.vue". Does the file exist?
+```
+
+## 问题原因
+
+1. **文件位置变更**:UEditor组件已经从 `src/utils/ueditor.vue` 移动到 `src/components/business/ueditor.vue`
+2. **导入路径错误**:多个Vue组件文件中仍在使用旧的导入路径
+3. **路径解析失败**:Vite无法找到指定路径的文件,导致构建失败
+
+## 修正内容
+
+### 1. 文章管理表单修正
+
+**文件**: `src/views/business/case-clinical-article/case-clinical-article-form.vue`
+
+**修正前**:
+```javascript
+import UEditor from '/@/utils/ueditor.vue';
+```
+
+**修正后**:
+```javascript
+import UEditor from '/@/components/business/ueditor.vue';
+```
+
+### 2. 病例交流表单修正
+
+**文件**: `src/views/business/case-exchange/case-exchange-form.vue`
+
+**修正前**:
+```javascript
+import UEditor from '/@/utils/ueditor.vue';
+```
+
+**修正后**:
+```javascript
+import UEditor from '/@/components/business/ueditor.vue';
+```
+
+## 文件结构说明
+
+### 修正后的文件结构
+
+```
+src/
+├── components/
+│ └── business/
+│ └── ueditor.vue # UEditor组件(当前位置)
+├── views/
+│ └── business/
+│ ├── case-clinical-article/
+│ │ └── case-clinical-article-form.vue # 文章管理表单
+│ └── case-exchange/
+│ └── case-exchange-form.vue # 病例交流表单
+```
+
+### 导入路径规范
+
+- **组件导入**: `/@/components/business/ueditor.vue`
+- **资源文件**: `/UEditorPlus/` (对应 `public/UEditorPlus/` 目录)
+
+## 修正验证
+
+### 1. 检查导入路径
+
+所有使用UEditor的组件现在都使用正确的导入路径:
+
+```javascript
+// ✅ 正确
+import UEditor from '/@/components/business/ueditor.vue';
+
+// ❌ 错误(已修正)
+import UEditor from '/@/utils/ueditor.vue';
+```
+
+### 2. 检查组件使用
+
+UEditor组件在以下文件中正常使用:
+
+- `case-clinical-article-form.vue` - 文章内容编辑
+- `case-exchange-form.vue` - 病例交流内容编辑
+
+### 3. 检查依赖加载
+
+UEditor依赖文件正确配置:
+
+```javascript
+const editorDependencies = [
+ '/UEditorPlus/ueditor.config.js',
+ '/UEditorPlus/ueditor.all.js',
+ '/UEditorPlus/lang/zh-cn/zh-cn.js'
+]
+```
+
+## 注意事项
+
+### 1. 路径别名
+
+项目使用 `/@/` 作为 `src/` 目录的别名:
+
+```javascript
+// 这些路径是等价的
+import UEditor from '/@/components/business/ueditor.vue';
+import UEditor from 'src/components/business/ueditor.vue';
+```
+
+### 2. 组件位置
+
+UEditor组件现在位于 `src/components/business/` 目录下,这是更合理的组织方式:
+
+- `components/` - 可复用组件
+- `business/` - 业务相关组件
+- `ueditor.vue` - 富文本编辑器组件
+
+### 3. 依赖管理
+
+确保UEditor的资源文件位于正确位置:
+
+```
+public/
+└── UEditorPlus/
+ ├── ueditor.config.js
+ ├── ueditor.all.js
+ ├── ueditor.parse.js
+ └── lang/
+ └── zh-cn/
+ └── zh-cn.js
+```
+
+## 测试建议
+
+1. **构建测试**: 确保项目能正常构建,没有导入错误
+2. **组件渲染**: 验证UEditor组件能正常显示
+3. **功能测试**: 测试富文本编辑、图片上传等功能
+4. **路径验证**: 确认浏览器控制台没有404或500错误
+
+## 相关文件
+
+- **UEditor组件**: `src/components/business/ueditor.vue`
+- **文章管理表单**: `src/views/business/case-clinical-article/case-clinical-article-form.vue`
+- **病例交流表单**: `src/views/business/case-exchange/case-exchange-form.vue`
+- **UEditor资源**: `public/UEditorPlus/`
+
+## 总结
+
+通过修正UEditor组件的导入路径,解决了以下问题:
+
+1. ✅ 修复了Vite构建时的导入解析错误
+2. ✅ 统一了组件的导入路径规范
+3. ✅ 确保了UEditor组件能正常加载和使用
+4. ✅ 维护了项目文件结构的清晰性
+
+现在UEditor组件应该能正常工作,不会再出现导入路径相关的错误。
\ No newline at end of file
diff --git a/UEditor故障排除指南.md b/UEditor故障排除指南.md
new file mode 100644
index 0000000..e4a51ee
--- /dev/null
+++ b/UEditor故障排除指南.md
@@ -0,0 +1,215 @@
+# UEditor 故障排除指南
+
+## 常见错误及解决方案
+
+### 1. 资源加载失败错误
+
+**错误信息:**
+```
+Uncaught (in promise) Error: [vue-ueditor-wrap] UEditor 资源加载失败!请检查资源是否存在,UEDITOR_HOME_URL 是否配置正确!
+```
+
+**可能原因:**
+- UEditor资源文件路径不正确
+- 配置文件加载失败
+- 依赖文件缺失
+
+**解决方案:**
+
+#### 方案1:检查文件路径
+确保以下文件存在于正确位置:
+```
+public/
+└── UEditorPlus/
+ ├── ueditor.config.simple.js # 简化配置文件
+ ├── ueditor.all.js # 核心文件
+ ├── ueditor.config.js # 原始配置文件
+ └── lang/
+ └── zh-cn/
+ └── zh-cn.js # 中文语言包
+```
+
+#### 方案2:使用简化配置
+在UEditor组件中使用简化的配置文件:
+
+```javascript
+const editorDependencies = [
+ '/UEditorPlus/ueditor.config.simple.js', // 使用简化配置
+ '/UEditorPlus/ueditor.all.js'
+]
+```
+
+#### 方案3:检查网络请求
+在浏览器开发者工具中检查:
+1. Network标签页是否有404错误
+2. Console标签页是否有JavaScript错误
+3. 确认UEditor资源文件能正常访问
+
+### 2. 导入路径错误
+
+**错误信息:**
+```
+Failed to resolve import "/@/utils/ueditor.vue" from "src/views/business/case-clinical-article/case-clinical-article-form.vue". Does the file exist?
+```
+
+**解决方案:**
+更新所有使用UEditor的组件导入路径:
+
+```javascript
+// ❌ 错误路径
+import UEditor from '/@/utils/ueditor.vue';
+
+// ✅ 正确路径
+import UEditor from '/@/components/business/ueditor.vue';
+```
+
+### 3. 配置文件问题
+
+**问题描述:**
+UEditor配置文件过于复杂或压缩,导致解析失败。
+
+**解决方案:**
+使用简化的配置文件 `ueditor.config.simple.js`,包含基本功能配置。
+
+## 调试步骤
+
+### 步骤1:检查控制台错误
+1. 打开浏览器开发者工具
+2. 查看Console标签页的错误信息
+3. 查看Network标签页的资源加载状态
+
+### 步骤2:验证文件路径
+在浏览器中直接访问以下URL,确认文件存在:
+- `http://localhost:8081/UEditorPlus/ueditor.config.simple.js`
+- `http://localhost:8081/UEditorPlus/ueditor.all.js`
+
+### 步骤3:检查组件配置
+确认UEditor组件的配置正确:
+
+```vue
+
+
+
+
+
+
+
+```
+
+### 步骤4:测试简单配置
+使用最简单的配置测试:
+
+```vue
+
+```
+
+## 常见配置问题
+
+### 1. 路径配置
+```javascript
+// ❌ 错误:相对路径
+UEDITOR_HOME_URL: 'UEditorPlus/'
+
+// ✅ 正确:绝对路径
+UEDITOR_HOME_URL: '/UEditorPlus/'
+```
+
+### 2. 依赖配置
+```javascript
+// ❌ 错误:缺少依赖
+:editorDependencies="[]"
+
+// ✅ 正确:包含必要依赖
+:editorDependencies="[
+ '/UEditorPlus/ueditor.config.simple.js',
+ '/UEditorPlus/ueditor.all.js'
+]"
+```
+
+### 3. 服务器配置
+```javascript
+// ❌ 错误:从服务器加载配置
+loadConfigFromServer: true
+
+// ✅ 正确:使用本地配置
+loadConfigFromServer: false
+```
+
+## 测试建议
+
+### 1. 创建测试页面
+创建一个简单的测试页面来验证UEditor功能:
+
+```vue
+
+
+
+```
+
+### 2. 逐步添加功能
+从基本配置开始,逐步添加功能:
+1. 基本文本编辑
+2. 工具栏配置
+3. 文件上传配置
+4. 样式定制
+
+### 3. 检查依赖版本
+确认 `vue-ueditor-wrap` 版本兼容性:
+```json
+{
+ "vue-ueditor-wrap": "^3.0.8"
+}
+```
+
+## 联系支持
+
+如果问题仍然存在,请提供以下信息:
+1. 错误截图
+2. 控制台错误信息
+3. 网络请求状态
+4. 项目配置文件
+5. 浏览器版本信息
+
+## 相关文件
+
+- **UEditor组件**: `src/components/business/ueditor.vue`
+- **简化配置**: `public/UEditorPlus/ueditor.config.simple.js`
+- **测试页面**: `src/views/business/ueditor-simple-test.vue`
+- **故障排除**: `UEditor故障排除指南.md`
\ No newline at end of file
diff --git a/UEditor配置修正说明.md b/UEditor配置修正说明.md
new file mode 100644
index 0000000..0619d2b
--- /dev/null
+++ b/UEditor配置修正说明.md
@@ -0,0 +1,149 @@
+# UEditor 组件配置修正说明
+
+## 修正内容
+
+### 1. 导入问题修正
+
+**修正前:**
+```javascript
+import { computed, onMounted, reactive, ref } from 'vue'
+import userApi from "../api/user";
+```
+
+**修正后:**
+```javascript
+import { computed, reactive } from 'vue'
+// 移除了不存在的 userApi 导入
+// 移除了未使用的 onMounted, ref 导入
+```
+
+### 2. 文件上传接口修正
+
+**修正前:**
+```javascript
+serverUrl: '/admin/api/admin/system/editor', // 不存在的接口
+```
+
+**修正后:**
+```javascript
+serverUrl: '/support/file/upload', // 使用项目中已存在的文件上传接口
+```
+
+### 3. UEditor路径配置修正
+
+**修正前:**
+```javascript
+UEDITOR_HOME_URL: import.meta.env.MODE=="development"?'/static/UEditorPlus/':'/admin/web/static/UEditorPlus/',
+UEDITOR_CORS_URL: import.meta.env.MODE=="development"?'/static/UEditorPlus/':'/admin/web/static/UEditorPlus/',
+```
+
+**修正后:**
+```javascript
+UEDITOR_HOME_URL: '/UEditorPlus/',
+UEDITOR_CORS_URL: '/UEditorPlus/',
+```
+
+### 4. 配置加载方式修正
+
+**修正前:**
+```javascript
+loadConfigFromServer: true, // 从服务器加载配置
+```
+
+**修正后:**
+```javascript
+loadConfigFromServer: false, // 使用本地配置,避免服务器配置冲突
+```
+
+## 新增配置
+
+### 文件上传配置
+
+```javascript
+// 图片上传配置
+imageActionName: 'uploadimage',
+imageFieldName: 'file',
+imageMaxSize: 2048000, // 2MB
+imageAllowFiles: ['.png', '.jpg', '.jpeg', '.gif', '.bmp'],
+imageCompressEnable: true,
+imageCompressBorder: 1600,
+
+// 视频上传配置
+videoActionName: 'uploadvideo',
+videoFieldName: 'file',
+videoMaxSize: 102400000, // 100MB
+videoAllowFiles: ['.flv', '.swf', '.mkv', '.avi', '.rm', '.rmvb', '.mp4', '.webm'],
+
+// 附件上传配置
+fileActionName: 'uploadfile',
+fileFieldName: 'file',
+fileMaxSize: 51200000, // 50MB
+fileAllowFiles: ['.doc', '.docx', '.pdf', '.zip', '.rar', '.txt', '.md']
+```
+
+### 错误处理配置
+
+```javascript
+tipError: function(message, title) {
+ console.error('UEditor Error:', message);
+ // 可以在这里集成项目的消息提示组件
+}
+```
+
+## 文件上传流程
+
+UEditor组件现在使用项目中的标准文件上传接口:
+
+1. **接口地址**: `/support/file/upload`
+2. **认证方式**: Bearer Token (从localStorage获取)
+3. **文件字段**: `file`
+4. **支持格式**: 根据文件类型自动识别
+
+## 使用说明
+
+### 基本用法
+
+```vue
+
+
+
+
+
+```
+
+### 在文章管理中使用
+
+```vue
+
+
+
+
+
+```
+
+## 注意事项
+
+1. **文件上传**: 确保后端接口 `/support/file/upload` 正常工作
+2. **认证**: 确保用户已登录且token有效
+3. **文件大小**: 图片限制2MB,视频限制100MB,附件限制50MB
+4. **路径配置**: UEditor资源文件位于 `/public/UEditorPlus/` 目录
+
+## 测试建议
+
+1. 测试基本文本编辑功能
+2. 测试图片上传功能
+3. 测试视频和附件上传功能
+4. 检查文件上传后的显示效果
+5. 验证错误处理是否正常工作
+
+## 相关文件
+
+- **组件文件**: `src/components/business/ueditor.vue`
+- **资源文件**: `public/UEditorPlus/`
+- **文件上传API**: `src/api/support/file-api.js`
+- **文章管理表单**: `src/views/business/case-clinical-article/case-clinical-article-form.vue`
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 471213e..0a8488a 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -35,6 +35,7 @@
"vue": "3.4.27",
"vue-i18n": "9.13.1",
"vue-router": "4.3.2",
+ "vue-ueditor-wrap": "^3.0.8",
"vue3-json-viewer": "2.2.2"
},
"devDependencies": {
@@ -6262,6 +6263,17 @@
"node": ">=0.10.0"
}
},
+ "node_modules/vue-ueditor-wrap": {
+ "version": "3.0.8",
+ "resolved": "https://registry.npmjs.org/vue-ueditor-wrap/-/vue-ueditor-wrap-3.0.8.tgz",
+ "integrity": "sha512-U1s30pKcz8rr6v2F2ivnomOf1vF1N+n+aNClas4jXfiEf4E5FEtNwkFJBugcyf2VTRFK0UVpx5WspX5nwmImYw==",
+ "dependencies": {
+ "@babel/runtime": "7.x"
+ },
+ "peerDependencies": {
+ "vue": "^3.0.0"
+ }
+ },
"node_modules/vue3-json-viewer": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/vue3-json-viewer/-/vue3-json-viewer-2.2.2.tgz",
diff --git a/package.json b/package.json
index a1b983d..5e5ca74 100644
--- a/package.json
+++ b/package.json
@@ -44,6 +44,7 @@
"vue": "3.4.27",
"vue-i18n": "9.13.1",
"vue-router": "4.3.2",
+ "vue-ueditor-wrap": "^3.0.8",
"vue3-json-viewer": "2.2.2"
},
"devDependencies": {
diff --git a/public/UEditorPlus/dialogs/anchor/anchor.html b/public/UEditorPlus/dialogs/anchor/anchor.html
new file mode 100644
index 0000000..37a16d5
--- /dev/null
+++ b/public/UEditorPlus/dialogs/anchor/anchor.html
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/public/UEditorPlus/dialogs/attachment/attachment.css b/public/UEditorPlus/dialogs/attachment/attachment.css
new file mode 100644
index 0000000..0591493
--- /dev/null
+++ b/public/UEditorPlus/dialogs/attachment/attachment.css
@@ -0,0 +1,3 @@
+/*! UEditorPlus v2.0.0*/
+
+@charset "utf-8";.wrapper{zoom:1;width:630px;*width:626px;height:380px;margin:0 auto;padding:10px;position:relative;font-family:sans-serif}.tabhead{float:left}.tabbody{width:100%;height:346px;position:relative;clear:both}.tabbody .panel{position:absolute;width:0;height:0;background:#fff;overflow:hidden;display:none}.tabbody .panel.focus{width:100%;height:346px;display:block}.tabbody #upload.panel{width:0;height:0;overflow:hidden;position:absolute!important;clip:rect(1px,1px,1px,1px);background:#fff;display:block}.tabbody #upload.panel.focus{width:100%;height:346px;display:block;clip:auto}#upload .queueList{margin:0;width:100%;height:100%;position:absolute;overflow:hidden}#upload p{margin:0}.element-invisible{width:0!important;height:0!important;border:0;padding:0;margin:0;overflow:hidden;position:absolute!important;clip:rect(1px,1px,1px,1px)}#upload .placeholder{margin:10px;border:2px dashed #e6e6e6;*border:0 dashed #e6e6e6;height:172px;padding-top:150px;text-align:center;background:url(./images/image.png) center 70px no-repeat;color:#ccc;font-size:18px;position:relative;top:0;*top:10px}#upload .placeholder .webuploader-pick{font-size:18px;background:#00b7ee;border-radius:3px;line-height:44px;padding:0 30px;*width:120px;color:#fff;display:inline-block;margin:0 auto 20px;cursor:pointer;box-shadow:0 1px 1px rgba(0,0,0,.1)}#upload .placeholder .webuploader-pick-hover{background:#00a2d4}#filePickerContainer{text-align:center}#upload .placeholder .flashTip{color:#666;font-size:12px;position:absolute;width:100%;text-align:center;bottom:20px}#upload .placeholder .flashTip a{color:#0785d1;text-decoration:none}#upload .placeholder .flashTip a:hover{text-decoration:underline}#upload .placeholder.webuploader-dnd-over{border-color:#999}#upload .filelist{list-style:none;margin:0;padding:0;overflow-x:hidden;overflow-y:auto;position:relative;height:300px}#upload .filelist:after{content:'';display:block;width:0;height:0;overflow:hidden;clear:both}#upload .filelist li{width:113px;height:113px;background:url(./images/bg.png);text-align:center;margin:9px 0 0 9px;*margin:6px 0 0 6px;position:relative;display:block;float:left;overflow:hidden;font-size:12px}#upload .filelist li p.log{position:relative;top:-45px}#upload .filelist li p.title{position:absolute;top:0;left:0;width:100%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;top:5px;text-indent:5px;text-align:left}#upload .filelist li p.progress{position:absolute;width:100%;bottom:0;left:0;height:8px;overflow:hidden;z-index:50;margin:0;border-radius:0;background:0 0;-webkit-box-shadow:0 0 0}#upload .filelist li p.progress span{display:none;overflow:hidden;width:0;height:100%;background:#1483d8 url(./images/progress.png) repeat-x;-webit-transition:width 200ms linear;-moz-transition:width 200ms linear;-o-transition:width 200ms linear;-ms-transition:width 200ms linear;transition:width 200ms linear;-webkit-animation:progressmove 2s linear infinite;-moz-animation:progressmove 2s linear infinite;-o-animation:progressmove 2s linear infinite;-ms-animation:progressmove 2s linear infinite;animation:progressmove 2s linear infinite;-webkit-transform:translateZ(0)}@-webkit-keyframes progressmove{0%{background-position:0 0}100%{background-position:17px 0}}@-moz-keyframes progressmove{0%{background-position:0 0}100%{background-position:17px 0}}@keyframes progressmove{0%{background-position:0 0}100%{background-position:17px 0}}#upload .filelist li p.imgWrap{position:relative;z-index:2;line-height:113px;vertical-align:middle;overflow:hidden;width:113px;height:113px;-webkit-transform-origin:50% 50%;-moz-transform-origin:50% 50%;-o-transform-origin:50% 50%;-ms-transform-origin:50% 50%;transform-origin:50% 50%;-webit-transition:200ms ease-out;-moz-transition:200ms ease-out;-o-transition:200ms ease-out;-ms-transition:200ms ease-out;transition:200ms ease-out}#upload .filelist li p.imgWrap.notimage{margin-top:0;width:111px;height:111px;border:1px #eee solid}#upload .filelist li p.imgWrap.notimage i.file-preview{margin-top:15px}#upload .filelist li img{width:100%}#upload .filelist li p.error{background:#f43838;color:#fff;position:absolute;bottom:0;left:0;height:28px;line-height:28px;width:100%;z-index:100;display:none}#upload .filelist li .success{display:block;position:absolute;left:0;bottom:0;height:40px;width:100%;z-index:200;background:url(./images/success.png) no-repeat right bottom;background-image:url(./images/success.gif) \9}#upload .filelist li.filePickerBlock{width:113px;height:113px;background:url(./images/image.png) no-repeat center 12px;border:1px solid #eee;border-radius:0}#upload .filelist li.filePickerBlock div.webuploader-pick{width:100%;height:100%;margin:0;padding:0;opacity:0;background:0 0;font-size:0}#upload .filelist div.file-panel{position:absolute;height:0;filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#80000000', endColorstr='#80000000') \0;background:rgba(0,0,0,.5);width:100%;top:0;left:0;overflow:hidden;z-index:300}#upload .filelist div.file-panel span{width:24px;height:24px;display:inline;float:right;text-indent:-9999px;overflow:hidden;background:url(./images/icons.png) no-repeat;background:url(./images/icons.gif) no-repeat \9;margin:5px 1px 1px;cursor:pointer;-webkit-tap-highlight-color:rgba(0,0,0,0);-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}#upload .filelist div.file-panel span.rotateLeft{display:none;background-position:0 -24px}#upload .filelist div.file-panel span.rotateLeft:hover{background-position:0 0}#upload .filelist div.file-panel span.rotateRight{display:none;background-position:-24px -24px}#upload .filelist div.file-panel span.rotateRight:hover{background-position:-24px 0}#upload .filelist div.file-panel span.cancel{background-position:-48px -24px}#upload .filelist div.file-panel span.cancel:hover{background-position:-48px 0}#upload .statusBar{height:45px;border-bottom:1px solid #dadada;margin:0 10px;padding:0;line-height:45px;vertical-align:middle;position:relative}#upload .statusBar .progress{border:1px solid #1483d8;width:198px;background:#fff;height:18px;position:absolute;top:12px;display:none;text-align:center;line-height:18px;color:#6dbfff;margin:0 10px 0 0}#upload .statusBar .progress span.percentage{width:0;height:100%;left:0;top:0;background:#1483d8;position:absolute}#upload .statusBar .progress span.text{position:relative;z-index:10}#upload .statusBar .info{display:inline-block;font-size:14px;color:#666}#upload .statusBar .btns{position:absolute;top:7px;right:0;line-height:30px}#filePickerBtn{display:inline-block;float:left}#upload .statusBar .btns .webuploader-pick,#upload .statusBar .btns .uploadBtn,#upload .statusBar .btns .uploadBtn.state-uploading,#upload .statusBar .btns .uploadBtn.state-paused{background:#fff;border:1px solid #cfcfcf;color:#565656;padding:0 18px;display:inline-block;border-radius:3px;margin-left:10px;cursor:pointer;font-size:14px;float:left;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}#upload .statusBar .btns .webuploader-pick-hover,#upload .statusBar .btns .uploadBtn:hover,#upload .statusBar .btns .uploadBtn.state-uploading:hover,#upload .statusBar .btns .uploadBtn.state-paused:hover{background:#f0f0f0}#upload .statusBar .btns .uploadBtn,#upload .statusBar .btns .uploadBtn.state-paused{background:#00b7ee;color:#fff;border-color:transparent}#upload .statusBar .btns .uploadBtn:hover,#upload .statusBar .btns .uploadBtn.state-paused:hover{background:#00a2d4}#upload .statusBar .btns .uploadBtn.disabled{pointer-events:none;filter:alpha(opacity=60);-moz-opacity:.6;-khtml-opacity:.6;opacity:.6}#online{width:100%;height:336px;padding:10px 0 0}#online #fileList{width:100%;height:100%;overflow-x:hidden;overflow-y:auto;position:relative}#online ul{display:block;list-style:none;margin:0;padding:0}#online li{float:left;display:block;list-style:none;padding:0;width:113px;height:113px;margin:0 0 9px 9px;*margin:0 0 6px 6px;background-color:#eee;overflow:hidden;cursor:pointer;position:relative}#online li.clearFloat{float:none;clear:both;display:block;width:0;height:0;margin:0;padding:0}#online li img{cursor:pointer}#online li div.file-wrapper{cursor:pointer;position:absolute;display:block;width:111px;height:111px;border:1px solid #eee;background:url(./images/bg.png) repeat}#online li div span.file-title{display:block;padding:0 3px;margin:3px 0 0;font-size:12px;height:15px;color:#555;text-align:center;width:107px;white-space:nowrap;word-break:break-all;overflow:hidden;text-overflow:ellipsis}#online li .icon{cursor:pointer;width:113px;height:113px;position:absolute;top:0;left:0;z-index:2;border:0;background-repeat:no-repeat}#online li .icon:hover{width:107px;height:107px;border:3px solid #1094fa}#online li.selected .icon{background-image:url(images/success.png);background-image:url(images/success.gif) \9;background-position:75px 75px}#online li.selected .icon:hover{width:107px;height:107px;border:3px solid #1094fa;background-position:72px 72px}i.file-preview{display:block;margin:10px auto;width:70px;height:70px;background-image:url(./images/file-icons.png);background-image:url(./images/file-icons.gif) \9;background-position:-140px center;background-repeat:no-repeat}i.file-preview.file-type-dir{background-position:0 center}i.file-preview.file-type-file{background-position:-140px center}i.file-preview.file-type-filelist{background-position:-210px center}i.file-preview.file-type-zip,i.file-preview.file-type-rar,i.file-preview.file-type-7z,i.file-preview.file-type-tar,i.file-preview.file-type-gz,i.file-preview.file-type-bz2{background-position:-280px center}i.file-preview.file-type-xls,i.file-preview.file-type-xlsx{background-position:-350px center}i.file-preview.file-type-doc,i.file-preview.file-type-docx{background-position:-420px center}i.file-preview.file-type-ppt,i.file-preview.file-type-pptx{background-position:-490px center}i.file-preview.file-type-vsd{background-position:-560px center}i.file-preview.file-type-pdf{background-position:-630px center}i.file-preview.file-type-txt,i.file-preview.file-type-md,i.file-preview.file-type-json,i.file-preview.file-type-htm,i.file-preview.file-type-xml,i.file-preview.file-type-html,i.file-preview.file-type-js,i.file-preview.file-type-css,i.file-preview.file-type-php,i.file-preview.file-type-jsp,i.file-preview.file-type-asp{background-position:-700px center}i.file-preview.file-type-apk{background-position:-770px center}i.file-preview.file-type-exe{background-position:-840px center}i.file-preview.file-type-ipa{background-position:-910px center}i.file-preview.file-type-mp4,i.file-preview.file-type-swf,i.file-preview.file-type-mkv,i.file-preview.file-type-avi,i.file-preview.file-type-flv,i.file-preview.file-type-mov,i.file-preview.file-type-mpg,i.file-preview.file-type-mpeg,i.file-preview.file-type-ogv,i.file-preview.file-type-webm,i.file-preview.file-type-rm,i.file-preview.file-type-rmvb{background-position:-980px center}i.file-preview.file-type-ogg,i.file-preview.file-type-wav,i.file-preview.file-type-wmv,i.file-preview.file-type-mid,i.file-preview.file-type-mp3{background-position:-1050px center}i.file-preview.file-type-jpg,i.file-preview.file-type-jpeg,i.file-preview.file-type-gif,i.file-preview.file-type-bmp,i.file-preview.file-type-png,i.file-preview.file-type-psd{background-position:-140px center}
\ No newline at end of file
diff --git a/public/UEditorPlus/dialogs/attachment/attachment.html b/public/UEditorPlus/dialogs/attachment/attachment.html
new file mode 100644
index 0000000..2c38228
--- /dev/null
+++ b/public/UEditorPlus/dialogs/attachment/attachment.html
@@ -0,0 +1,61 @@
+
+
+
+
+ ueditor图片对话框
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/public/UEditorPlus/dialogs/attachment/attachment.js b/public/UEditorPlus/dialogs/attachment/attachment.js
new file mode 100644
index 0000000..7523e91
--- /dev/null
+++ b/public/UEditorPlus/dialogs/attachment/attachment.js
@@ -0,0 +1,2 @@
+/*! UEditorPlus v2.0.0*/
+!function(){function initTabs(){for(var a=$G("tabhead").children,b=0;b'+"还有2个未上传文件".replace(/[\d]/,e)+""),!1;break;case"online":b=onlineFile.getInsertList()}editor.execCommand("insertfile",b)}}function UploadFile(a){this.$wrap=a.constructor==String?$("#"+a):$(a),this.init()}function OnlineFile(a){this.container=utils.isString(a)?document.getElementById(a):a,this.init()}var uploadFile,onlineFile;window.onload=function(){initTabs(),initButtons()},UploadFile.prototype={init:function(){this.fileList=[],this.initContainer(),this.initUploader()},initContainer:function(){this.$queue=this.$wrap.find(".filelist")},initUploader:function(){function a(a){var b=h(''+a.name+'
'),c=h(''+lang.uploadDelete+''+lang.uploadTurnRight+''+lang.uploadTurnLeft+"
").appendTo(b),d=b.find("p.progress span"),e=b.find("p.imgWrap"),g=h('').hide().appendTo(b),i=function(a){switch(a){case"exceed_size":text=lang.errorExceedSize;break;case"interrupt":text=lang.errorInterrupt;break;case"http":text=lang.errorHttp;break;case"not_allow_type":text=lang.errorFileType;break;default:text=lang.errorUploadRetry}g.text(text).show()};"invalid"===a.getStatus()?i(a.statusText):(e.text(lang.uploadPreview),"|png|jpg|jpeg|bmp|gif|".indexOf("|"+a.ext.toLowerCase()+"|")==-1?e.empty().addClass("notimage").append(''+a.name+""):browser.ie&&browser.version<=7?e.text(lang.uploadNoPreview):f.makeThumb(a,function(a,b){if(a||!b)e.text(lang.uploadNoPreview);else{var c=h('
');e.empty().append(c),c.on("error",function(){e.text(lang.uploadNoPreview)})}},t,u),w[a.id]=[a.size,0],a.rotation=0,a.ext&&A.indexOf(a.ext.toLowerCase())!=-1||(i("not_allow_type"),f.removeFile(a))),a.on("statuschange",function(e,f){"progress"===f?d.hide().width(0):"queued"===f&&(b.off("mouseenter mouseleave"),c.remove()),"error"===e||"invalid"===e?(i(a.statusText),w[a.id][1]=1):"interrupt"===e?i("interrupt"):"queued"===e?w[a.id][1]=0:"progress"===e&&(g.hide(),d.css("display","block")),b.removeClass("state-"+f).addClass("state-"+e)}),b.on("mouseenter",function(){c.stop().animate({height:30})}),b.on("mouseleave",function(){c.stop().animate({height:0})}),c.on("click","span",function(){var b,c=h(this).index();switch(c){case 0:return void f.removeFile(a);case 1:a.rotation+=90;break;case 2:a.rotation-=90}x?(b="rotate("+a.rotation+"deg)",e.css({"-webkit-transform":b,"-mos-transform":b,"-o-transform":b,transform:b})):e.css("filter","progid:DXImageTransform.Microsoft.BasicImage(rotation="+~~(a.rotation/90%4+4)%4+")")}),b.insertBefore(n)}function b(a){var b=h("#"+a.id);delete w[a.id],c(),b.off().find(".file-panel").off().end().remove()}function c(){var a,b=0,c=0,d=p.children();h.each(w,function(a,d){c+=d[0],b+=d[0]*d[1]}),a=c?b/c:0,d.eq(0).text(Math.round(100*a)+"%"),d.eq(1).css("width",Math.round(100*a)+"%"),e()}function d(a,b){if(a!=v){var c=f.getStats();switch(m.removeClass("state-"+v),m.addClass("state-"+a),a){case"pedding":j.addClass("element-invisible"),k.addClass("element-invisible"),o.removeClass("element-invisible"),p.hide(),l.hide(),f.refresh();break;case"ready":o.addClass("element-invisible"),j.removeClass("element-invisible"),k.removeClass("element-invisible"),p.hide(),l.show(),m.text(lang.uploadStart),f.refresh();break;case"uploading":p.show(),l.hide(),m.text(lang.uploadPause);break;case"paused":p.show(),l.hide(),m.text(lang.uploadContinue);break;case"confirm":if(p.show(),l.hide(),m.text(lang.uploadStart),c=f.getStats(),c.successNum&&!c.uploadFailNum)return void d("finish");break;case"finish":p.hide(),l.show(),c.uploadFailNum?m.text(lang.uploadRetry):m.text(lang.uploadStart)}v=a,e()}g.getQueueCount()?m.removeClass("disabled"):m.addClass("disabled")}function e(){var a,b="";"ready"===v?b=lang.updateStatusReady.replace("_",q).replace("_KB",WebUploader.formatSize(r)):"confirm"===v?(a=f.getStats(),a.uploadFailNum&&(b=lang.updateStatusConfirm.replace("_",a.successNum).replace("_",a.successNum))):(a=f.getStats(),b=lang.updateStatusFinish.replace("_",q).replace("_KB",WebUploader.formatSize(r)).replace("_",a.successNum),a.uploadFailNum&&(b+=lang.updateStatusError.replace("_",a.uploadFailNum))),l.html(b)}var f,g=this,h=jQuery,i=g.$wrap,j=i.find(".filelist"),k=i.find(".statusBar"),l=k.find(".info"),m=i.find(".uploadBtn"),n=(i.find(".filePickerBtn"),i.find(".filePickerBlock")),o=i.find(".placeholder"),p=k.find(".progress").hide(),q=0,r=0,s=window.devicePixelRatio||1,t=113*s,u=113*s,v="",w={},x=function(){var a=document.createElement("p").style,b="transition"in a||"WebkitTransition"in a||"MozTransition"in a||"msTransition"in a||"OTransition"in a;return a=null,b}(),y=editor.getActionUrl(editor.getOpt("fileActionName")),z=editor.getOpt("fileMaxSize"),A=(editor.getOpt("fileAllowFiles")||[]).join("").replace(/\./g,",").replace(/^[,]/,"");return WebUploader.Uploader.support()?editor.getOpt("fileActionName")?(f=g.uploader=WebUploader.create({pick:{id:"#filePickerReady",label:lang.uploadSelectFile},swf:"../../third-party/webuploader/Uploader.swf",server:y,fileVal:editor.getOpt("fileFieldName"),duplicate:!0,fileSingleSizeLimit:z,headers:editor.getOpt("serverHeaders")||{},compress:!1}),f.addButton({id:"#filePickerBlock"}),f.addButton({id:"#filePickerBtn",label:lang.uploadAddFile}),d("pedding"),f.on("fileQueued",function(b){b.ext&&A.indexOf(b.ext.toLowerCase())!=-1&&b.size<=z&&(q++,r+=b.size),1===q&&(o.addClass("element-invisible"),k.show()),a(b)}),f.on("fileDequeued",function(a){a.ext&&A.indexOf(a.ext.toLowerCase())!=-1&&a.size<=z&&(q--,r-=a.size),b(a),c()}),f.on("filesQueued",function(a){f.isInProgress()||"pedding"!=v&&"finish"!=v&&"confirm"!=v&&"ready"!=v||d("ready"),c()}),f.on("all",function(a,b){switch(a){case"uploadFinished":d("confirm",b);break;case"startUpload":var c=utils.serializeParam(editor.queryCommandValue("serverparam"))||"",e=utils.formatUrl(y+(y.indexOf("?")==-1?"?":"&")+"encode=utf-8&"+c);f.option("server",e),d("uploading",b);break;case"stopUpload":d("paused",b)}}),f.on("uploadBeforeSend",function(a,b,c){y.toLowerCase().indexOf("jsp")!=-1&&(c.X_Requested_With="XMLHttpRequest")}),f.on("uploadProgress",function(a,b){var d=h("#"+a.id),e=d.find(".progress span");e.css("width",100*b+"%"),w[a.id][1]=b,c()}),f.on("uploadSuccess",function(a,b){var c=h("#"+a.id);try{var d=b._raw||b,e=utils.str2json(d);e=editor.getOpt("serverResponsePrepare")(e),"SUCCESS"==e.state?(g.fileList.push(e),c.append(''),editor.fireEvent("uploadsuccess",{res:e,type:"file"})):c.find(".error").text(e.state).show()}catch(f){c.find(".error").text(lang.errorServerUpload).show()}}),f.on("uploadError",function(a,b){}),f.on("error",function(a,b,c){"F_EXCEED_SIZE"===a?editor.getOpt("tipError")(lang.errorExceedSize+" "+(b/1024/1024).toFixed(1)+"MB"):console.log("error",a,b,c)}),f.on("uploadComplete",function(a,b){}),m.on("click",function(){return!h(this).hasClass("disabled")&&void("ready"===v?f.upload():"paused"===v?f.upload():"uploading"===v&&f.stop())}),m.addClass("state-"+v),void c()):void h("#filePickerReady").after(h("").html(lang.errorLoadConfig)).hide():void h("#filePickerReady").after(h("
").html(lang.errorNotSupport)).hide()},getQueueCount:function(){var a,b,c,d=0,e=this.uploader.getFiles();for(b=0;a=e[b++];)c=a.getStatus(),"queued"!=c&&"uploading"!=c&&"progress"!=c||d++;return d},getInsertList:function(){var a,b,c,d=[],e=editor.getOpt("fileUrlPrefix");for(a=0;a
=json.total&&(_this.listEnd=!0),_this.isLoadingData=!1)}catch(e){if(r.responseText.indexOf("ue_separate_ue")!=-1){var list=r.responseText.split(r.responseText);_this.pushData(list),_this.listIndex=parseInt(list.length),_this.listEnd=!0,_this.isLoadingData=!1}}},onerror:function(){_this.isLoadingData=!1}}))},pushData:function(a){var b,c,d,e,f,g=this,h=editor.getOpt("fileManagerUrlPrefix");for(b=0;b=f?(a.width=b,a.height=c*f/e,a.style.marginLeft="-"+parseInt((a.width-b)/2)+"px"):(a.width=b*e/f,a.height=c,a.style.marginTop="-"+parseInt((a.height-c)/2)+"px"):e>=f?(a.width=b*e/f,a.height=c,a.style.marginLeft="-"+parseInt((a.width-b)/2)+"px"):(a.width=b,a.height=c*f/e,a.style.marginTop="-"+parseInt((a.height-c)/2)+"px")},getInsertList:function(){var a,b=this.list.children,c=[];for(a=0;a
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 外链音频支持MP3格式
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/public/UEditorPlus/dialogs/audio/audio.js b/public/UEditorPlus/dialogs/audio/audio.js
new file mode 100644
index 0000000..bcc3a83
--- /dev/null
+++ b/public/UEditorPlus/dialogs/audio/audio.js
@@ -0,0 +1,2 @@
+/*! UEditorPlus v2.0.0*/
+!function(){function a(){for(var a=$G("tabHeads").children,b=0;b",'',""];return c.join("")}function k(a){a&&($G("preview").innerHTML=''+lang.urlError+'
")}function l(){var a=[],b=editor.getOpt("audioUrlPrefix"),c=f("upload_alignment","name")||"none";for(var d in p){var e=p[d];a.push({url:b+e.url,align:c})}var g=o.getQueueCount();return g?($(".info","#queueList").html(''+"还有2个未上传文件".replace(/[\d]/,g)+""),!1):void editor.execCommand("insertaudio",a,"upload")}function m(){o=new n("queueList")}function n(a){this.$wrap=a.constructor==String?$("#"+a):$(a),this.init()}var o,p=[],q=!1,r={};window.onload=function(){r=editor.getOpt("audioConfig"),$focus($G("audioUrl")),a(),b(),m()},n.prototype={init:function(){this.fileList=[],this.initContainer(),this.initUploader()},initContainer:function(){this.$queue=this.$wrap.find(".filelist")},initUploader:function(){function a(a){var b=h(''+a.name+'
'),c=h(''+lang.uploadDelete+''+lang.uploadTurnRight+''+lang.uploadTurnLeft+"
").appendTo(b),d=b.find("p.progress span"),e=b.find("p.imgWrap"),g=h('').hide().appendTo(b),i=function(a){switch(a){case"exceed_size":text=lang.errorExceedSize;break;case"interrupt":text=lang.errorInterrupt;break;case"http":text=lang.errorHttp;break;case"not_allow_type":text=lang.errorFileType;break;default:text=lang.errorUploadRetry}g.text(text).show()};"invalid"===a.getStatus()?i(a.statusText):(e.text(lang.uploadPreview),"|png|jpg|jpeg|bmp|gif|".indexOf("|"+a.ext.toLowerCase()+"|")==-1?e.empty().addClass("notimage").append(''+a.name+""):browser.ie&&browser.version<=7?e.text(lang.uploadNoPreview):f.makeThumb(a,function(a,b){if(a||!b||/^data:/.test(b)&&browser.ie&&browser.version<=7)e.text(lang.uploadNoPreview);else{var c=h('
');e.empty().append(c),c.on("error",function(){e.text(lang.uploadNoPreview)})}},u,v),x[a.id]=[a.size,0],a.rotation=0,a.ext&&B.indexOf(a.ext.toLowerCase())!=-1||(i("not_allow_type"),f.removeFile(a))),a.on("statuschange",function(e,f){"progress"===f?d.hide().width(0):"queued"===f&&(b.off("mouseenter mouseleave"),c.remove()),"error"===e||"invalid"===e?(i(a.statusText),x[a.id][1]=1):"interrupt"===e?i("interrupt"):"queued"===e?x[a.id][1]=0:"progress"===e&&(g.hide(),d.css("display","block")),b.removeClass("state-"+f).addClass("state-"+e)}),b.on("mouseenter",function(){c.stop().animate({height:30})}),b.on("mouseleave",function(){c.stop().animate({height:0})}),c.on("click","span",function(){var b,c=h(this).index();switch(c){case 0:return void f.removeFile(a);case 1:a.rotation+=90;break;case 2:a.rotation-=90}y?(b="rotate("+a.rotation+"deg)",e.css({"-webkit-transform":b,"-mos-transform":b,"-o-transform":b,transform:b})):e.css("filter","progid:DXImageTransform.Microsoft.BasicImage(rotation="+~~(a.rotation/90%4+4)%4+")")}),b.insertBefore(n)}function b(a){var b=h("#"+a.id);delete x[a.id],c(),b.off().find(".file-panel").off().end().remove()}function c(){var a,b=0,c=0,d=q.children();h.each(x,function(a,d){c+=d[0],b+=d[0]*d[1]}),a=c?b/c:0,d.eq(0).text(Math.round(100*a)+"%"),d.eq(1).css("width",Math.round(100*a)+"%"),e()}function d(a,b){if(a!=w){var c=f.getStats();switch(m.removeClass("state-"+w),m.addClass("state-"+a),a){case"pedding":j.addClass("element-invisible"),k.addClass("element-invisible"),o.removeClass("element-invisible"),q.hide(),l.hide(),f.refresh();break;case"ready":o.addClass("element-invisible"),j.removeClass("element-invisible"),k.removeClass("element-invisible"),q.hide(),l.show(),m.text(lang.uploadStart),f.refresh();break;case"uploading":q.show(),l.hide(),m.text(lang.uploadPause);break;case"paused":q.show(),l.hide(),m.text(lang.uploadContinue);break;case"confirm":if(q.show(),l.hide(),m.text(lang.uploadStart),c=f.getStats(),c.successNum&&!c.uploadFailNum)return void d("finish");break;case"finish":q.hide(),l.show(),c.uploadFailNum?m.text(lang.uploadRetry):m.text(lang.uploadStart)}w=a,e()}g.getQueueCount()?m.removeClass("disabled"):m.addClass("disabled")}function e(){var a,b="";"ready"===w?b=lang.updateStatusReady.replace("_",r).replace("_KB",WebUploader.formatSize(s)):"confirm"===w?(a=f.getStats(),a.uploadFailNum&&(b=lang.updateStatusConfirm.replace("_",a.successNum).replace("_",a.successNum))):(a=f.getStats(),b=lang.updateStatusFinish.replace("_",r).replace("_KB",WebUploader.formatSize(s)).replace("_",a.successNum),a.uploadFailNum&&(b+=lang.updateStatusError.replace("_",a.uploadFailNum))),l.html(b)}var f,g=this,h=jQuery,i=g.$wrap,j=i.find(".filelist"),k=i.find(".statusBar"),l=k.find(".info"),m=i.find(".uploadBtn"),n=(i.find(".filePickerBtn"),i.find(".filePickerBlock")),o=i.find(".placeholder"),q=k.find(".progress").hide(),r=0,s=0,t=window.devicePixelRatio||1,u=113*t,v=113*t,w="",x={},y=function(){var a=document.createElement("p").style,b="transition"in a||"WebkitTransition"in a||"MozTransition"in a||"msTransition"in a||"OTransition"in a;return a=null,b}(),z=editor.getActionUrl(editor.getOpt("audioActionName")),A=editor.getOpt("audioMaxSize"),B=(editor.getOpt("audioAllowFiles")||[]).join("").replace(/\./g,",").replace(/^[,]/,"");return WebUploader.Uploader.support()?editor.getOpt("audioActionName")?(f=g.uploader=WebUploader.create({pick:{id:"#filePickerReady",label:lang.uploadSelectFile},swf:"../../third-party/webuploader/Uploader.swf",server:z,fileVal:editor.getOpt("audioFieldName"),duplicate:!0,fileSingleSizeLimit:A,headers:editor.getOpt("serverHeaders")||{},compress:!1}),f.addButton({id:"#filePickerBlock"}),f.addButton({id:"#filePickerBtn",label:lang.uploadAddFile}),d("pedding"),f.on("fileQueued",function(b){r++,s+=b.size,1===r&&(o.addClass("element-invisible"),k.show()),a(b)}),f.on("fileDequeued",function(a){r--,s-=a.size,b(a),c()}),f.on("filesQueued",function(a){f.isInProgress()||"pedding"!=w&&"finish"!=w&&"confirm"!=w&&"ready"!=w||d("ready"),c()}),f.on("all",function(a,b){switch(a){case"uploadFinished":d("confirm",b);break;case"startUpload":var c=utils.serializeParam(editor.queryCommandValue("serverparam"))||"",e=utils.formatUrl(z+(z.indexOf("?")==-1?"?":"&")+"encode=utf-8&"+c);f.option("server",e),d("uploading",b);break;case"stopUpload":d("paused",b)}}),f.on("uploadBeforeSend",function(a,b,c){z.toLowerCase().indexOf("jsp")!=-1&&(c.X_Requested_With="XMLHttpRequest")}),f.on("uploadProgress",function(a,b){var d=h("#"+a.id),e=d.find(".progress span");e.css("width",100*b+"%"),x[a.id][1]=b,c()}),f.on("uploadSuccess",function(a,b){var c=h("#"+a.id);try{var d=b._raw||b,e=utils.str2json(d);e=editor.getOpt("serverResponsePrepare")(e),"SUCCESS"==e.state?(p.push({url:e.url,type:e.type,original:e.original}),c.append('')):c.find(".error").text(e.state).show()}catch(f){c.find(".error").text(lang.errorServerUpload).show()}}),f.on("uploadError",function(a,b){}),f.on("error",function(a,b,c){"F_EXCEED_SIZE"===a?editor.getOpt("tipError")(lang.errorExceedSize+" "+(b/1024/1024).toFixed(1)+"MB"):console.log("error",a,b,c)}),f.on("uploadComplete",function(a,b){}),m.on("click",function(){return!h(this).hasClass("disabled")&&void("ready"===w?f.upload():"paused"===w?f.upload():"uploading"===w&&f.stop())}),m.addClass("state-"+w),void c()):void h("#filePickerReady").after(h("").html(lang.errorLoadConfig)).hide():void h("#filePickerReady").after(h("
").html(lang.errorNotSupport)).hide()},getQueueCount:function(){var a,b,c,d=0,e=this.uploader.getFiles();for(b=0;a=e[b++];)c=a.getStatus(),"queued"!=c&&"uploading"!=c&&"progress"!=c||d++;return d},refresh:function(){this.uploader.refresh()}}}();
\ No newline at end of file
diff --git a/public/UEditorPlus/dialogs/audio/images/bg.png b/public/UEditorPlus/dialogs/audio/images/bg.png
new file mode 100644
index 0000000..580be0a
Binary files /dev/null and b/public/UEditorPlus/dialogs/audio/images/bg.png differ
diff --git a/public/UEditorPlus/dialogs/audio/images/center_focus.jpg b/public/UEditorPlus/dialogs/audio/images/center_focus.jpg
new file mode 100644
index 0000000..262b029
Binary files /dev/null and b/public/UEditorPlus/dialogs/audio/images/center_focus.jpg differ
diff --git a/public/UEditorPlus/dialogs/audio/images/file-icons.gif b/public/UEditorPlus/dialogs/audio/images/file-icons.gif
new file mode 100644
index 0000000..d8c02c2
Binary files /dev/null and b/public/UEditorPlus/dialogs/audio/images/file-icons.gif differ
diff --git a/public/UEditorPlus/dialogs/audio/images/file-icons.png b/public/UEditorPlus/dialogs/audio/images/file-icons.png
new file mode 100644
index 0000000..3ff82c8
Binary files /dev/null and b/public/UEditorPlus/dialogs/audio/images/file-icons.png differ
diff --git a/public/UEditorPlus/dialogs/audio/images/icons.gif b/public/UEditorPlus/dialogs/audio/images/icons.gif
new file mode 100644
index 0000000..78459de
Binary files /dev/null and b/public/UEditorPlus/dialogs/audio/images/icons.gif differ
diff --git a/public/UEditorPlus/dialogs/audio/images/icons.png b/public/UEditorPlus/dialogs/audio/images/icons.png
new file mode 100644
index 0000000..12e4700
Binary files /dev/null and b/public/UEditorPlus/dialogs/audio/images/icons.png differ
diff --git a/public/UEditorPlus/dialogs/audio/images/image.png b/public/UEditorPlus/dialogs/audio/images/image.png
new file mode 100644
index 0000000..19699f6
Binary files /dev/null and b/public/UEditorPlus/dialogs/audio/images/image.png differ
diff --git a/public/UEditorPlus/dialogs/audio/images/left_focus.jpg b/public/UEditorPlus/dialogs/audio/images/left_focus.jpg
new file mode 100644
index 0000000..7886d27
Binary files /dev/null and b/public/UEditorPlus/dialogs/audio/images/left_focus.jpg differ
diff --git a/public/UEditorPlus/dialogs/audio/images/none_focus.jpg b/public/UEditorPlus/dialogs/audio/images/none_focus.jpg
new file mode 100644
index 0000000..7c768dc
Binary files /dev/null and b/public/UEditorPlus/dialogs/audio/images/none_focus.jpg differ
diff --git a/public/UEditorPlus/dialogs/audio/images/progress.png b/public/UEditorPlus/dialogs/audio/images/progress.png
new file mode 100644
index 0000000..717c486
Binary files /dev/null and b/public/UEditorPlus/dialogs/audio/images/progress.png differ
diff --git a/public/UEditorPlus/dialogs/audio/images/right_focus.jpg b/public/UEditorPlus/dialogs/audio/images/right_focus.jpg
new file mode 100644
index 0000000..173e10d
Binary files /dev/null and b/public/UEditorPlus/dialogs/audio/images/right_focus.jpg differ
diff --git a/public/UEditorPlus/dialogs/audio/images/success.gif b/public/UEditorPlus/dialogs/audio/images/success.gif
new file mode 100644
index 0000000..8d4f311
Binary files /dev/null and b/public/UEditorPlus/dialogs/audio/images/success.gif differ
diff --git a/public/UEditorPlus/dialogs/audio/images/success.png b/public/UEditorPlus/dialogs/audio/images/success.png
new file mode 100644
index 0000000..94f968d
Binary files /dev/null and b/public/UEditorPlus/dialogs/audio/images/success.png differ
diff --git a/public/UEditorPlus/dialogs/background/background.css b/public/UEditorPlus/dialogs/background/background.css
new file mode 100644
index 0000000..13684ab
--- /dev/null
+++ b/public/UEditorPlus/dialogs/background/background.css
@@ -0,0 +1,3 @@
+/*! UEditorPlus v2.0.0*/
+
+.wrapper{width:424px;margin:10px auto;zoom:1;position:relative}.tabbody{height:225px}.tabbody .panel{position:absolute;width:100%;height:100%;background:#fff;display:none}.tabbody .focus{display:block}body{font-size:12px;color:#888;overflow:hidden}input,label{vertical-align:middle}.clear{clear:both}.pl{padding-left:18px;padding-left:23px \9}#imageList{width:420px;height:215px;margin-top:10px;overflow:hidden;overflow-y:auto}#imageList div{float:left;width:100px;height:95px;margin:5px 10px}#imageList img{cursor:pointer;border:2px solid #fff}.bgarea{margin:10px;padding:5px;height:84%;border:1px solid #A8A297}.content div{margin:10px 0 10px 5px}.content .iptradio{margin:0 5px 5px 0}.txt{width:280px}.wrapcolor{height:19px}div.color{float:left;margin:0}#colorPicker{width:17px;height:17px;border:1px solid #CCC;display:inline-block;border-radius:3px;box-shadow:2px 2px 5px #D3D6DA;margin:0;float:left}div.alignment,#custom{margin-left:23px;margin-left:28px \9}#custom input{height:15px;min-height:15px;width:20px}#repeatType{width:100px}#imgManager{width:100%;height:225px}#imgManager #imageList{width:100%;overflow-x:hidden;overflow-y:auto}#imgManager ul{display:block;list-style:none;margin:0;padding:0}#imgManager li{float:left;display:block;list-style:none;padding:0;width:113px;height:113px;margin:9px 0 0 19px;background-color:#eee;overflow:hidden;cursor:pointer;position:relative}#imgManager li.clearFloat{float:none;clear:both;display:block;width:0;height:0;margin:0;padding:0}#imgManager li img{cursor:pointer}#imgManager li .icon{cursor:pointer;width:113px;height:113px;position:absolute;top:0;left:0;z-index:2;border:0;background-repeat:no-repeat}#imgManager li .icon:hover{width:107px;height:107px;border:3px solid #1094fa}#imgManager li.selected .icon{background-image:url(images/success.png);background-position:75px 75px}#imgManager li.selected .icon:hover{width:107px;height:107px;border:3px solid #1094fa;background-position:72px 72px}
\ No newline at end of file
diff --git a/public/UEditorPlus/dialogs/background/background.html b/public/UEditorPlus/dialogs/background/background.html
new file mode 100644
index 0000000..faebd7f
--- /dev/null
+++ b/public/UEditorPlus/dialogs/background/background.html
@@ -0,0 +1,59 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/public/UEditorPlus/dialogs/background/background.js b/public/UEditorPlus/dialogs/background/background.js
new file mode 100644
index 0000000..378c996
--- /dev/null
+++ b/public/UEditorPlus/dialogs/background/background.js
@@ -0,0 +1,2 @@
+/*! UEditorPlus v2.0.0*/
+!function(){function initTabs(){for(var a=$G("tabHeads").children,b=0;b
=json.total&&(_this.listEnd=!0),_this.isLoadingData=!1)}catch(e){if(r.responseText.indexOf("ue_separate_ue")!=-1){var list=r.responseText.split(r.responseText);_this.pushData(list),_this.listIndex=parseInt(list.length),_this.listEnd=!0,_this.isLoadingData=!1}}},onerror:function(){_this.isLoadingData=!1}})}},pushData:function(a){var b,c,d,e,f=this,g=editor.getOpt("imageManagerUrlPrefix");for(b=0;b=f?(a.width=b,a.height=c*f/e,a.style.marginLeft="-"+parseInt((a.width-b)/2)+"px"):(a.width=b*e/f,a.height=c,a.style.marginTop="-"+parseInt((a.height-c)/2)+"px"):e>=f?(a.width=b*e/f,a.height=c,a.style.marginLeft="-"+parseInt((a.width-b)/2)+"px"):(a.width=b,a.height=c*f/e,a.style.marginTop="-"+parseInt((a.height-c)/2)+"px")},getInsertList:function(){var a,b=this.list.children,c=[],d=getAlign();for(a=0;a
+
+
+
+
+
+
+
+
+
+
+
+ 支持文档格式
+
+
+
+ - Word:docx
+ - Markdown:md
+
+
+
+
+
+
+
+
+
+
+
+
+