From cad0747ac4de95287570931bcd8c8e9d0dce1710 Mon Sep 17 00:00:00 2001 From: wangqiong <1322446236@qq.com> Date: Sun, 28 Apr 2024 17:00:13 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E6=8A=8A=E6=B5=8B=E8=AF=95=E7=8E=AF=E5=A2=83=E5=92=8C=E6=AD=A3?= =?UTF-8?q?=E5=BC=8F=E7=8E=AF=E5=A2=83=E5=88=86=E5=BC=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application.yml | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index d7d7fe9..fb3698c 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -22,13 +22,13 @@ spring: datasource: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver - url: jdbc:mysql://121.40.189.20:3306/onlyoffice?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai&useSSL=false + url: jdbc:mysql://121.40.189.20:3306/onlyoffice_test?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai&useSSL=false username: root password: YMzc157# redis: host: 121.40.189.20 port: 6389 - database: 0 + database: 1 mybatis-plus: # global-config: @@ -45,13 +45,29 @@ spring: config: activate: on-profile: dev -filepath: C:/onlyoffice/data/files -serverhost: http://172.16.0.254 + datasource: + type: com.alibaba.druid.pool.DruidDataSource + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://121.40.189.20:3306/onlyoffice_test?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai&useSSL=false + username: root + password: YMzc157# +filepath: /home/ruoyi/uploadPath/onlyoffice/data/files +serverhost: http://121.40.189.20 --- #生产环境属性配置 spring: config: activate: on-profile: prod -filepath: /onlyoffice/data/files + redis: + host: 121.40.189.20 + port: 6389 + database: 0 + datasource: + type: com.alibaba.druid.pool.DruidDataSource + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://121.40.189.20:3306/onlyoffice?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai&useSSL=false + username: root + password: YMzc157# +filepath: /home/ruoyi/uploadPath/onlyoffice/data/files serverhost: http://121.40.189.20 \ No newline at end of file From bbfb6ea88d32609ec06c24854456ab0c12091048 Mon Sep 17 00:00:00 2001 From: wangqiong <1322446236@qq.com> Date: Mon, 29 Apr 2024 16:36:20 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=8D=8F=E5=90=8C?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E6=9F=A5=E7=9C=8B=E5=8A=9F=E8=83=BD=EF=BC=8C?= =?UTF-8?q?=E5=8F=AA=E8=AF=BB=E7=94=A8=E6=88=B7=E5=8F=AF=E4=BB=A5=E6=9F=A5?= =?UTF-8?q?=E7=9C=8B=E5=9C=A8=E7=BA=BF=E7=BC=96=E8=BE=91=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E7=9A=84=E5=86=85=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/impl/OnlyServiceAPIImpl.java | 24 +++++++++++++------ .../oo/onlyoffice/core/FileConfigFactory.java | 17 ++++++++----- .../core/handler/FileHandlerImpl.java | 19 +++++++++++++-- 3 files changed, 45 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/oo/onlyoffice/api/impl/OnlyServiceAPIImpl.java b/src/main/java/com/oo/onlyoffice/api/impl/OnlyServiceAPIImpl.java index a9c5360..492d52a 100644 --- a/src/main/java/com/oo/onlyoffice/api/impl/OnlyServiceAPIImpl.java +++ b/src/main/java/com/oo/onlyoffice/api/impl/OnlyServiceAPIImpl.java @@ -81,29 +81,39 @@ public class OnlyServiceAPIImpl implements OnlyServiceAPI { return documentEdit(map, collaborativeEditing, clientType); } if (VIEW.equals(mode)) { - return documentView(map, clientType); + return documentView(map, collaborativeEditing, clientType); } +// if (VIEW.equals(mode)) { +// return documentView(map, clientType); +// } return null; } private Map documentEdit(Map map, boolean collaborativeEditing, String clientType) { - FileConfig fileConfigDTO = openEditConfig(map, "edit", collaborativeEditing,clientType); + FileConfig fileConfigDTO = openEditConfig(map, "edit", collaborativeEditing, clientType); String json = JSON.toJSONString(fileConfigDTO); Map config = JSON.parseObject(json, Map.class); config.put("type", clientType); return config; } - - private Map documentView(Map map,String clientType) { - FileConfig fileConfigDTO = openEditConfig(map, "view", false,clientType); + private Map documentView(Map map, boolean collaborativeEditing, String clientType) { + FileConfig fileConfigDTO = openEditConfig(map, "view", collaborativeEditing, clientType); String json = JSON.toJSONString(fileConfigDTO); Map config = JSON.parseObject(json, Map.class); config.put("type", clientType); return config; } - private FileConfig openEditConfig(Map map, String mode, boolean collaborativeEditing,String clientType) { + private Map documentView(Map map, String clientType) { + FileConfig fileConfigDTO = openEditConfig(map, "view", false, clientType); + String json = JSON.toJSONString(fileConfigDTO); + Map config = JSON.parseObject(json, Map.class); + config.put("type", clientType); + return config; + } + + private FileConfig openEditConfig(Map map, String mode, boolean collaborativeEditing, String clientType) { try { map.put("mode", mode); log.info("开始生成文件信息"); @@ -111,7 +121,7 @@ public class OnlyServiceAPIImpl implements OnlyServiceAPI { FileMetadata tempFileInfo = fileHandler.handlerFile(map, collaborativeEditing); //生成配置文件 TODO: 控制文件权限 log.info("开始生成编辑器配置信息"); - FileConfig fileConfigDTO = onlyOfficeConfigFactory.buildInitConfig(tempFileInfo.getUrl(), mode, tempFileInfo.getKey(), tempFileInfo.getOldName(),clientType); + FileConfig fileConfigDTO = onlyOfficeConfigFactory.buildInitConfig(tempFileInfo.getUrl(), mode, tempFileInfo.getKey(), tempFileInfo.getOldName(), clientType); log.info("生成编辑器配置信息结束"); // TODO: 添加更多详细的自定义信息 return fileConfigDTO; diff --git a/src/main/java/com/oo/onlyoffice/core/FileConfigFactory.java b/src/main/java/com/oo/onlyoffice/core/FileConfigFactory.java index 7bc0f5f..08f0c37 100644 --- a/src/main/java/com/oo/onlyoffice/core/FileConfigFactory.java +++ b/src/main/java/com/oo/onlyoffice/core/FileConfigFactory.java @@ -1,6 +1,7 @@ package com.oo.onlyoffice.core; import cn.hutool.core.date.DateUtil; +import com.alibaba.fastjson2.JSONObject; import com.oo.onlyoffice.config.OnlyProperties; import com.oo.onlyoffice.dto.DocumentConfig; import com.oo.onlyoffice.dto.EditorConfig; @@ -43,7 +44,7 @@ public class FileConfigFactory implements OnlyOfficeConfigFactory { * @return 配置信息 */ @Override - public FileConfig buildInitConfig(String fileUrl, String mode, String key, String fileName,String clientType) { + public FileConfig buildInitConfig(String fileUrl, String mode, String key, String fileName, String clientType) { Map map = new HashMap<>(); @@ -74,11 +75,15 @@ public class FileConfigFactory implements OnlyOfficeConfigFactory { String callBackUrl = onlyProperties.getLocalhostAddress() + onlyProperties.getCallBackUrl(); EditorConfig editorConfig = new EditorConfig(callBackUrl, mode); - editorConfig.setFileCustomization(getFileCustomization(mode,clientType)); + editorConfig.setFileCustomization(getFileCustomization(mode, clientType)); editorConfig.setFileUser(user); editorConfig.setPlugins(getPlugins()); - - + //共同编辑"coEditing"配置: + // "coEditing": { "mode": "fast","change": true} + JSONObject coEditing = new JSONObject(); + coEditing.put("mode", "fast"); + coEditing.put("change", "true"); + editorConfig.setCoEditing(coEditing); fileConfigDTO.setEditorConfig(editorConfig); map.put("editorConfig", editorConfig); @@ -112,13 +117,13 @@ public class FileConfigFactory implements OnlyOfficeConfigFactory { return LoadConfigUtil.getCustomization(); } - private FileCustomization getFileCustomization(String mode,String clientType) { + private FileCustomization getFileCustomization(String mode, String clientType) { FileCustomization customization = LoadConfigUtil.getCustomization(); if (mode != null && !(mode.trim()).equals("") && mode.equals("edit")) { customization.setAutosave(true); } customization.setMobileForceView(false); - if(clientType!=null&&clientType!=""&&"mobile".equals(clientType)){ + if (clientType != null && clientType != "" && "mobile".equals(clientType)) { customization.setMobileForceView(true); } return customization; diff --git a/src/main/java/com/oo/onlyoffice/core/handler/FileHandlerImpl.java b/src/main/java/com/oo/onlyoffice/core/handler/FileHandlerImpl.java index 2df5dc8..efcbff4 100644 --- a/src/main/java/com/oo/onlyoffice/core/handler/FileHandlerImpl.java +++ b/src/main/java/com/oo/onlyoffice/core/handler/FileHandlerImpl.java @@ -77,8 +77,23 @@ public class FileHandlerImpl implements FileHandler { cache.set(user.getId() + "_" + id, key); cache.set("getID_" + key, id); } - } else {//查看模式 - key = id; + } else { + //查看模式 + if (collaborativeEditing) { + if (cache.get("collaborativeEditing_" + id) != null) { + key = (String) cache.get("collaborativeEditing_" + id); + } else { + key = IdUtil.simpleUUID(); + cache.set("collaborativeEditing_" + id, key); + cache.set("getID_" + key, id); + } + } else { + key = IdUtil.simpleUUID(); + FileUser user = SecurityUtils.getUserSession(); + cache.set(user.getId() + "_" + id, key); + cache.set("getID_" + key, id); + } + // key = id; } From de93471c32a34b2d4711a4192f33f0077274901c Mon Sep 17 00:00:00 2001 From: wangqiong <1322446236@qq.com> Date: Sat, 11 May 2024 16:39:56 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=9B=9E=E8=B0=83?= =?UTF-8?q?=E4=BF=9D=E5=AD=98=E6=8E=A5=E5=8F=A3=EF=BC=88=E8=8B=A5=E4=BC=A0?= =?UTF-8?q?=E9=80=92=E6=96=87=E4=BB=B6id=E5=88=99=E6=AF=8F=E6=AC=A1?= =?UTF-8?q?=E4=BF=9D=E5=AD=98=E5=8F=AA=E6=9B=B4=E6=96=B0=E6=96=87=E4=BB=B6?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../demo/controller/OnlyOfficeController.java | 16 +++++--- .../java/com/oo/demo/service/DemoService.java | 16 +++++++- .../java/com/oo/demo/service/FileService.java | 31 +++++++++++++++- .../com/oo/demo/service/OnFileService.java | 16 +++++++- .../oo/demo/service/OnFileServiceImpl.java | 37 +++++++++++++++++++ .../api/impl/OnlyServiceAPIImpl.java | 10 +++-- .../oo/onlyoffice/core/SaveFileProcessor.java | 7 ++-- 7 files changed, 116 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/oo/demo/controller/OnlyOfficeController.java b/src/main/java/com/oo/demo/controller/OnlyOfficeController.java index 8ec670e..66fba44 100644 --- a/src/main/java/com/oo/demo/controller/OnlyOfficeController.java +++ b/src/main/java/com/oo/demo/controller/OnlyOfficeController.java @@ -236,9 +236,9 @@ public class OnlyOfficeController { * 6 - 正在编辑文档,但保存当前文档状态 * 7 - 强制保存文档时发生错误 */ - @RequestMapping("/onlyOffice/save") + @RequestMapping("/onlyOffice/save/{fileId}") @ResponseBody - public void saveFile(HttpServletRequest request, HttpServletResponse response) { + public void saveFile(HttpServletRequest request, HttpServletResponse response,@PathVariable(required = false) String fileId) { PrintWriter writer = null; try { writer = response.getWriter(); @@ -246,6 +246,11 @@ public class OnlyOfficeController { Scanner scanner = new Scanner(request.getInputStream()).useDelimiter("\\A"); String body = scanner.hasNext() ? scanner.next() : ""; JSONObject jsonObject = JSONObject.parseObject(body); + if(fileId!=null){ + jsonObject.put("fileId",fileId); + }else{ + jsonObject.put("fileId",""); + } log.info("{}", jsonObject); WebsocketResult result = fileService.documentSave(jsonObject); /* @@ -258,9 +263,10 @@ public class OnlyOfficeController { userId = userSession.getId(); } WebSocketServer.sendInfo(JSON.toJSONString(result.getOnFile()), userId); - if (Objects.nonNull(writer)) { - writer.write("{\"error\":0}"); - } +// if (Objects.nonNull(writer)) { +// writer.write("{\"error\":0}"); +// } + writer.write("{\"error\":0}"); } catch (Exception e) { e.printStackTrace(); log.info("报错信息" + e.getMessage()); diff --git a/src/main/java/com/oo/demo/service/DemoService.java b/src/main/java/com/oo/demo/service/DemoService.java index a2040dd..8ad3baa 100644 --- a/src/main/java/com/oo/demo/service/DemoService.java +++ b/src/main/java/com/oo/demo/service/DemoService.java @@ -36,11 +36,23 @@ public class DemoService implements SaveFileProcessor { } + /** + * 存储onlyoffice文件信息 + * @param map 文件元信息 + * @param file 文件 + * @param changes 文件变动信息 + * @param fileId 文件id + * @return + */ @Override - public Map save(Map map, byte[] file, byte[] changes, String key) { - String fileId = ""; + public Map save(Map map, byte[] file, byte[] changes, String fileId) { try { + if(fileId!=null&&fileId!=""){ + onFileService.updateFileByFileId(file, map.get("fileType").toString(),fileId); + }else{ + fileId = ""; fileId = onFileService.saveFile(file, map.get("fileType").toString()); + } } catch (Exception e) { e.printStackTrace(); } diff --git a/src/main/java/com/oo/demo/service/FileService.java b/src/main/java/com/oo/demo/service/FileService.java index 2d8a335..86325d7 100644 --- a/src/main/java/com/oo/demo/service/FileService.java +++ b/src/main/java/com/oo/demo/service/FileService.java @@ -52,6 +52,7 @@ public class FileService { public WebsocketResult documentSave(JSONObject jsonObject) { WebsocketResult result = new WebsocketResult(); String key = ""; + String fileId = jsonObject.getString("fileId"); try { int status = jsonObject.getIntValue("status"); log.info("status[{}]", status); @@ -69,7 +70,13 @@ public class FileService { key = jsonObject.getString("key"); log.info("key:" + JSON.toJSONString(key)); //文件id - String fileId = onlyServiceAPI.getFileId(key); + Boolean isexistid = false; + if (fileId != null && !"".equals(fileId)) { + isexistid = true; + } + if (!isexistid) { + fileId = onlyServiceAPI.getFileId(key); + } log.info("fileId:" + JSON.toJSONString(fileId)); if (fileId != null && !"".equals(fileId)) { //查询之前FileId对应的文件信息 @@ -93,7 +100,11 @@ public class FileService { //处理文件的保存 OnFile file = onlyServiceAPI.handlerStatus(jsonObject); //查询相同案件最新版本的文件信息 - file = getNewFileInofoByCaseId(file.getCaseId()); + if (fileId != null && !"".equals(fileId)) { + file = getNewFileInofoByFileId(fileId); + } else { + file = getNewFileInofoByCaseId(file.getCaseId()); + } result = WebsocketResult.builder().onFile(file).userId(SecurityUtils.getUserSession().getId()).build(); log.info("处理文件的保存:" + JSON.toJSONString(jsonObject)); log.info("保存文件结束"); @@ -101,10 +112,13 @@ public class FileService { return result; } else if (0 == status || 2 == status || 4 == status) { onlyServiceAPI.close(jsonObject); + log.info("文件关闭====",status); } else if (3 == status || 7 == status) { //保存文档错误 onlyServiceAPI.close(jsonObject); + log.info("保存文档错误====",status); } else if (1 == status) { + log.info("文件正在编辑====",status); //文件服务的回调 获取key判断当前文档有多少人在这使用 List actions = JSONObject.parseArray(jsonObject.getString("actions"), Map.class); if ((Integer) actions.get(0).get("type") == 1) { @@ -145,4 +159,17 @@ public class FileService { log.info("caseId:" + caseId + ":fileinfo:" + JSON.toJSONString(file)); return file; } + + /** + * 根据文件的fileid查询文件信息 + */ + private OnFile getNewFileInofoByFileId(String fileId) { + OnFile file = onFileMapper.selectById(fileId); + if (file != null) { + log.info("caseId:" + file.getCaseId() + ":fileinfo:" + JSON.toJSONString(file)); + } else { + log.info("根据文件id未查询到文件信息"); + } + return file; + } } diff --git a/src/main/java/com/oo/demo/service/OnFileService.java b/src/main/java/com/oo/demo/service/OnFileService.java index 6b8cac8..8352b17 100644 --- a/src/main/java/com/oo/demo/service/OnFileService.java +++ b/src/main/java/com/oo/demo/service/OnFileService.java @@ -4,12 +4,12 @@ import com.baomidou.mybatisplus.extension.service.IService; import com.oo.demo.entity.OnFile; import javax.servlet.http.HttpServletResponse; -import java.io.File; public interface OnFileService extends IService { /** * 保存onlyoffice文件 + * * @param bytes * @param fileType * @return @@ -17,14 +17,27 @@ public interface OnFileService extends IService { */ String saveFile(byte[] bytes, String fileType) throws Exception; + /** + * 通过文件id更新onlyoffice文件 + * + * @param bytes + * @param fileType + * @param fileId + * @return + * @throws Exception + */ + String updateFileByFileId(byte[] bytes, String fileType, String fileId) throws Exception; + /** * 删除onlyoffice文件 + * * @param id */ void removeFile(String id); /** * 下载onlyoffice文件 + * * @param id * @param isBrowser * @param response @@ -33,6 +46,7 @@ public interface OnFileService extends IService { /** * 根据文件id查找文件信息 + * * @param id * @return */ diff --git a/src/main/java/com/oo/demo/service/OnFileServiceImpl.java b/src/main/java/com/oo/demo/service/OnFileServiceImpl.java index 27f3d44..3113c3e 100644 --- a/src/main/java/com/oo/demo/service/OnFileServiceImpl.java +++ b/src/main/java/com/oo/demo/service/OnFileServiceImpl.java @@ -56,6 +56,14 @@ public class OnFileServiceImpl extends ServiceImpl impleme removeById(id); } + /** + * 新增文件信息到数据库 + * + * @param bytes + * @param fileType + * @return + * @throws Exception + */ public String saveFile(byte[] bytes, String fileType) throws Exception { String fileId = IdUtil.simpleUUID(); @@ -70,4 +78,33 @@ public class OnFileServiceImpl extends ServiceImpl impleme } return fileId; } + + /** + * 更新文件信息到数据库 + * + * @param bytes + * @param fileType + * @param fileId + * @return + * @throws Exception + */ + public String updateFileByFileId(byte[] bytes, String fileType, String fileId) throws Exception { + Boolean ishaveid = false; + if (fileId != null && fileId != "") { + ishaveid = true; + } + if (!ishaveid) { + fileId = IdUtil.simpleUUID(); + } + File file = new File(path + "/" + fileId + "." + fileType); + File parentFile = file.getParentFile(); + if (!parentFile.exists()) { + parentFile.mkdirs(); + } + try (FileOutputStream out = new FileOutputStream(path + "/" + fileId + "." + fileType)) { + out.write(bytes); + out.flush(); + } + return fileId; + } } diff --git a/src/main/java/com/oo/onlyoffice/api/impl/OnlyServiceAPIImpl.java b/src/main/java/com/oo/onlyoffice/api/impl/OnlyServiceAPIImpl.java index 492d52a..459f4b9 100644 --- a/src/main/java/com/oo/onlyoffice/api/impl/OnlyServiceAPIImpl.java +++ b/src/main/java/com/oo/onlyoffice/api/impl/OnlyServiceAPIImpl.java @@ -170,7 +170,7 @@ public class OnlyServiceAPIImpl implements OnlyServiceAPI { @Override public OnFile handlerStatus(JSONObject jsonObject) throws Exception { OnFile file = new OnFile(); - String fileId = null; + String fileId = jsonObject.getString("fileId"); log.info("开始下载编辑器文件"); int status = jsonObject.getIntValue("status"); log.info("status[{}]:{}", status, jsonObject); @@ -202,10 +202,11 @@ public class OnlyServiceAPIImpl implements OnlyServiceAPI { if (caseId != null) { fileInfoMap.put("caseId", caseId); } - saveFileProcessor.saveBeforeInitialization(tempFile.get().getFileInfo(), fileByte, fileExtension); + //保存文件前进行自定义处理(该方法暂时没有实现业务逻辑) + //saveFileProcessor.saveBeforeInitialization(tempFile.get().getFileInfo(), fileByte, fileExtension); // 保存文件 - Map map = saveFileProcessor.save(tempFile.get().getFileInfo(), fileByte, changes, key); + Map map = saveFileProcessor.save(tempFile.get().getFileInfo(), fileByte, changes, fileId); log.info("文件信息1:" + JSON.toJSONString(tempFile.get().getFileInfo())); log.info("文件信息2:" + JSON.toJSONString(map)); saveFileProcessor.saveAfterInitialization(tempFile.get().getFileInfo(), fileByte, fileExtension); @@ -310,7 +311,8 @@ public class OnlyServiceAPIImpl implements OnlyServiceAPI { log.info("文件变动信息文件url:" + changesurl); // 下载修改后文件 byte[] fileByte = FileUtil.getFileByte(url); - saveFileProcessor.save(tempFile.getFileInfo(), fileByte, null, jsonObject.getString("key")); + saveFileProcessor.save(tempFile.getFileInfo(), fileByte, null, jsonObject.getString("fileId")); + log.info("zouzhele=================="); } removeTempFile(jsonObject); String id = (String) cache.get("getID_" + jsonObject.getString("key")); diff --git a/src/main/java/com/oo/onlyoffice/core/SaveFileProcessor.java b/src/main/java/com/oo/onlyoffice/core/SaveFileProcessor.java index a39c2ca..27bbad1 100644 --- a/src/main/java/com/oo/onlyoffice/core/SaveFileProcessor.java +++ b/src/main/java/com/oo/onlyoffice/core/SaveFileProcessor.java @@ -16,13 +16,14 @@ public interface SaveFileProcessor { void saveBeforeInitialization(Map map,byte[] bytes,String fileExtension) throws Exception; /** - * + * 存储onlyoffice文件信息 * @param map 文件元信息 * @param file 文件 * @param changes 文件变动信息 - * @return 返回新的文件信息 + * @param fileId 文件id + * @return */ - Map save(Map map,byte[] file, byte[] changes,String key); + Map save(Map map,byte[] file, byte[] changes,String fileId); /** * 保存文件后进行自定义处理