diff --git a/o2server/x_message_assemble_communicate/src/main/java/com/x/message/assemble/communicate/factory/IMConversationFactory.java b/o2server/x_message_assemble_communicate/src/main/java/com/x/message/assemble/communicate/factory/IMConversationFactory.java index 34a09f4659a4ef94c0ce3fcd8f2e3bc078f4d9b4..81ded7918beba5db38c18c009cceb65471e7856a 100644 --- a/o2server/x_message_assemble_communicate/src/main/java/com/x/message/assemble/communicate/factory/IMConversationFactory.java +++ b/o2server/x_message_assemble_communicate/src/main/java/com/x/message/assemble/communicate/factory/IMConversationFactory.java @@ -122,6 +122,22 @@ public class IMConversationFactory extends AbstractFactory { .getResultList(); } + /** + * 根据会话id查询所有的消息id + * 清空聊天记录用 + * @param conversationId 会话id + * @return + * @throws Exception + */ + public List listAllMsgIdsWithConversationId(String conversationId) throws Exception { + EntityManager em = this.entityManagerContainer().get(IMMsg.class); + CriteriaBuilder cb = em.getCriteriaBuilder(); + CriteriaQuery cq = cb.createQuery(String.class); + Root root = cq.from(IMMsg.class); + Predicate p = cb.equal(root.get(IMMsg_.conversationId), conversationId); + return em.createQuery(cq.select(root.get(IMMsg_.id)).where(p)).getResultList(); + } + /** * 查询会话聊天消息总数 * 分页查询需要 diff --git a/o2server/x_message_assemble_communicate/src/main/java/com/x/message/assemble/communicate/jaxrs/im/ActionDeleteConversationMsgs.java b/o2server/x_message_assemble_communicate/src/main/java/com/x/message/assemble/communicate/jaxrs/im/ActionDeleteConversationMsgs.java new file mode 100644 index 0000000000000000000000000000000000000000..d1378362d2be2d9a21e69babbf3d1d4e071c35f5 --- /dev/null +++ b/o2server/x_message_assemble_communicate/src/main/java/com/x/message/assemble/communicate/jaxrs/im/ActionDeleteConversationMsgs.java @@ -0,0 +1,60 @@ +package com.x.message.assemble.communicate.jaxrs.im; + +import com.x.base.core.container.EntityManagerContainer; +import com.x.base.core.container.factory.EntityManagerContainerFactory; +import com.x.base.core.project.http.ActionResult; +import com.x.base.core.project.http.EffectivePerson; +import com.x.base.core.project.http.WrapOutBoolean; +import com.x.base.core.project.logger.Logger; +import com.x.base.core.project.logger.LoggerFactory; +import com.x.message.assemble.communicate.Business; +import com.x.message.core.entity.IMConversation; +import com.x.message.core.entity.IMMsg; +import org.apache.commons.lang3.StringUtils; + +import java.util.List; + + +public class ActionDeleteConversationMsgs extends BaseAction { + + private static Logger logger = LoggerFactory.getLogger(ActionDeleteConversationMsgs.class); + + ActionResult execute(EffectivePerson effectivePerson, String conversationId) throws Exception { + ActionResult result = new ActionResult<>(); + if (StringUtils.isEmpty(conversationId)) { + throw new ExceptionEmptyId(); + } + try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) { + Wo wo = new Wo(); + Business business = new Business(emc); + // 判断权限 群聊只有管理员能清空 + IMConversation conversation = emc.find(conversationId, IMConversation.class); + if (conversation == null) { + throw new ExceptionConversationNotExist(); + } + if (conversation.getType().equals(IMConversation.CONVERSATION_TYPE_GROUP) && + !effectivePerson.getDistinguishedName().equals(conversation.getAdminPerson())) { + throw new ExceptionConvClearMsgsNoPermission(); + } + + List msgIds = business.imConversationFactory().listAllMsgIdsWithConversationId(conversationId); + if (msgIds == null || msgIds.isEmpty()) { + logger.info("没有聊天记录,无需清空! conversationId:"+conversationId); + } else { + // 这里是1条条删除的 优化一下? + emc.beginTransaction(IMMsg.class); + emc.delete(IMMsg.class, msgIds); + emc.commit(); + logger.info("成功清空聊天记录!conversationId:" + conversationId + " msg size:" + msgIds.size() + " person:" + effectivePerson.getDistinguishedName()); + } + wo.setValue(true); + result.setData(wo); + } + return result; + } + + + static class Wo extends WrapOutBoolean { + + } +} diff --git a/o2server/x_message_assemble_communicate/src/main/java/com/x/message/assemble/communicate/jaxrs/im/ActionWriteImConfig.java b/o2server/x_message_assemble_communicate/src/main/java/com/x/message/assemble/communicate/jaxrs/im/ActionWriteImConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..41b332eb81c181a541e981546e23b9a664e0a6cf --- /dev/null +++ b/o2server/x_message_assemble_communicate/src/main/java/com/x/message/assemble/communicate/jaxrs/im/ActionWriteImConfig.java @@ -0,0 +1,177 @@ +package com.x.message.assemble.communicate.jaxrs.im; + +import com.google.gson.JsonElement; +import com.x.base.core.project.annotation.FieldDescribe; +import com.x.base.core.project.config.Config; +import com.x.base.core.project.config.WebServers; +import com.x.base.core.project.connection.ActionResponse; +import com.x.base.core.project.connection.CipherConnectionAction; +import com.x.base.core.project.gson.GsonPropertyObject; +import com.x.base.core.project.http.ActionResult; +import com.x.base.core.project.http.EffectivePerson; +import com.x.base.core.project.http.WrapOutBoolean; +import com.x.base.core.project.logger.Logger; +import com.x.base.core.project.logger.LoggerFactory; + +import java.util.LinkedHashMap; +import java.util.Map; + +public class ActionWriteImConfig extends BaseAction { + + private static Logger logger = LoggerFactory.getLogger(ActionWriteImConfig.class); + + + ActionResult execute(EffectivePerson effectivePerson, JsonElement jsonElement) throws Exception { + ActionResult result = new ActionResult(); + Wi wi = this.convertToWrapIn(jsonElement, Wi.class); + LinkedHashMap map = new LinkedHashMap<>(); + for (Map.Entry en : Config.web().entrySet()) { + map.put(en.getKey(), en.getValue()); + } + map.put(Wi.IM_CONFIG_KEY_NAME, wi); + String content = gson.toJson(map); + String fileName = "web.json"; + logger.info("更新配置文件。。。。。。。。。。。。。。"); + logger.info("文件:" + fileName); + logger.info("内容:" + content); + WebConfigSaveWi saveWi = new WebConfigSaveWi(); + saveWi.setFileName(fileName); + saveWi.setFileContent(content); + ActionResponse response = CipherConnectionAction.post(false, Config.url_x_program_center_jaxrs("config", "save"), saveWi); + Wo wo = new Wo(); + if (response != null) { + SaveConfigWo saveWo = response.getData(SaveConfigWo.class); + if (saveWo != null && saveWo.getStatus() != null) { + logger.info("修改保存["+fileName+"]配置文件成功!"); + try { + WebServers.updateWebServerConfigJson(); + logger.info("更新 config.json 成功!!!!"); + wo.setValue(true); + result.setData(wo); + } catch (Exception e) { + logger.info("更新前端 config.json 出错"); + wo.setValue(false); + result.setData(wo); + logger.error(e); + } + } else { + logger.info("保存["+fileName+"]配置文件data返回为空!!!!"); + wo.setValue(false); + result.setData(wo); + } + } else { + logger.info("保存["+fileName+"]配置文件 返回为空!!"); + wo.setValue(false); + result.setData(wo); + } + + return result; + } + + + + public static class WebConfigSaveWi extends GsonPropertyObject { + private String fileName; + private String fileContent; + + public String getFileName() { + return fileName; + } + + public void setFileName(String fileName) { + this.fileName = fileName; + } + + public String getFileContent() { + return fileContent; + } + + public void setFileContent(String fileContent) { + this.fileContent = fileContent; + } + } + + /** + * IM的配置文件,这个配置文件默认写入到 web.json key=imConfig + */ + static class Wi extends GsonPropertyObject { + + public static final String IM_CONFIG_KEY_NAME = "imConfig"; // 这个配置会已对象写入到 web.json ,已imConfig作为key名称 + + + @FieldDescribe("是否开启清空聊天记录的功能.") + private Boolean enableClearMsg; + + public Boolean getEnableClearMsg() { + return enableClearMsg; + } + + public void setEnableClearMsg(Boolean enableClearMsg) { + this.enableClearMsg = enableClearMsg; + } + } + + static class Wo extends WrapOutBoolean { + + } + + + public static class SaveConfigWo extends GsonPropertyObject { + + @FieldDescribe("执行时间") + private String time; + + @FieldDescribe("执行结果") + private String status; + + @FieldDescribe("执行消息") + private String message; + + @FieldDescribe("config文件内容") + private String fileContent; + + @FieldDescribe("是否Sample") + private boolean isSample; + + public String getTime() { + return time; + } + + public void setTime(String time) { + this.time = time; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getFileContent() { + return fileContent; + } + + public void setFileContent(String fileContent) { + this.fileContent = fileContent; + } + + public boolean isSample() { + return isSample; + } + + public void setSample(boolean isSample) { + this.isSample = isSample; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + } +} diff --git a/o2server/x_message_assemble_communicate/src/main/java/com/x/message/assemble/communicate/jaxrs/im/ExceptionConvClearMsgsNoPermission.java b/o2server/x_message_assemble_communicate/src/main/java/com/x/message/assemble/communicate/jaxrs/im/ExceptionConvClearMsgsNoPermission.java new file mode 100644 index 0000000000000000000000000000000000000000..ea568232eb5c88a71acf5c2b6a4d570d69f66a7d --- /dev/null +++ b/o2server/x_message_assemble_communicate/src/main/java/com/x/message/assemble/communicate/jaxrs/im/ExceptionConvClearMsgsNoPermission.java @@ -0,0 +1,14 @@ +package com.x.message.assemble.communicate.jaxrs.im; + +import com.x.base.core.project.exception.PromptException; + +class ExceptionConvClearMsgsNoPermission extends PromptException { + + private static final long serialVersionUID = 4132300948670472899L; + + ExceptionConvClearMsgsNoPermission() { + super("没有权限清空聊天记录!"); + } + + +} diff --git a/o2server/x_message_assemble_communicate/src/main/java/com/x/message/assemble/communicate/jaxrs/im/ExceptionConversationNotExist.java b/o2server/x_message_assemble_communicate/src/main/java/com/x/message/assemble/communicate/jaxrs/im/ExceptionConversationNotExist.java new file mode 100644 index 0000000000000000000000000000000000000000..e694fe7e5ead29d69031ac779f8e438036621fc2 --- /dev/null +++ b/o2server/x_message_assemble_communicate/src/main/java/com/x/message/assemble/communicate/jaxrs/im/ExceptionConversationNotExist.java @@ -0,0 +1,12 @@ +package com.x.message.assemble.communicate.jaxrs.im; + +import com.x.base.core.project.exception.PromptException; + +class ExceptionConversationNotExist extends PromptException { + + private static final long serialVersionUID = 4132300948670472899L; + + ExceptionConversationNotExist() { + super("会话不存在!"); + } +} diff --git a/o2server/x_message_assemble_communicate/src/main/java/com/x/message/assemble/communicate/jaxrs/im/ImAction.java b/o2server/x_message_assemble_communicate/src/main/java/com/x/message/assemble/communicate/jaxrs/im/ImAction.java index 99becb5f7f91cc4efc5da09b08b9c32aee63e060..12b0c0e7a3c0f1ebeccf84da9adbc08758b0ebf3 100644 --- a/o2server/x_message_assemble_communicate/src/main/java/com/x/message/assemble/communicate/jaxrs/im/ImAction.java +++ b/o2server/x_message_assemble_communicate/src/main/java/com/x/message/assemble/communicate/jaxrs/im/ImAction.java @@ -3,13 +3,7 @@ package com.x.message.assemble.communicate.jaxrs.im; import java.util.List; import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.PUT; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; +import javax.ws.rs.*; import javax.ws.rs.container.AsyncResponse; import javax.ws.rs.container.Suspended; import javax.ws.rs.core.Context; @@ -39,6 +33,26 @@ public class ImAction extends StandardJaxrsAction { private static Logger logger = LoggerFactory.getLogger(ImAction.class); + /**************** im manager ************/ + + + @JaxrsMethodDescribe(value = "更新IM配置.", action = ActionWriteImConfig.class) + @POST + @Path("manager/config") + @Produces(HttpMediaType.APPLICATION_JSON_UTF_8) + @Consumes(MediaType.APPLICATION_JSON) + public void config(@Suspended final AsyncResponse asyncResponse, @Context HttpServletRequest request, + JsonElement jsonElement) { + ActionResult result = new ActionResult<>(); + EffectivePerson effectivePerson = this.effectivePerson(request); + try { + result = new ActionWriteImConfig().execute( effectivePerson, jsonElement ); + } catch (Exception e) { + logger.error(e, effectivePerson, request, jsonElement); + result.error(e); + } + asyncResponse.resume(ResponseFactory.getEntityTagActionResultResponse(request, result)); + } /************* im conversation ************/ @@ -174,6 +188,24 @@ public class ImAction extends StandardJaxrsAction { asyncResponse.resume(ResponseFactory.getEntityTagActionResultResponse(request, result)); } + @JaxrsMethodDescribe(value = "清空会话的所有消息.", action = ActionDeleteConversationMsgs.class) + @DELETE + @Path("conversation/{id}/clear/all/msg") + @Produces(HttpMediaType.APPLICATION_JSON_UTF_8) + @Consumes(MediaType.APPLICATION_JSON) + public void clearConversationMsg(@Suspended final AsyncResponse asyncResponse, @Context HttpServletRequest request, + @JaxrsParameterDescribe("会话ID") @PathParam("id") String id) { + ActionResult result = new ActionResult<>(); + EffectivePerson effectivePerson = this.effectivePerson(request); + try { + result = new ActionDeleteConversationMsgs().execute(effectivePerson, id); + } catch (Exception e) { + logger.error(e, effectivePerson, request, null); + result.error(e); + } + asyncResponse.resume(ResponseFactory.getEntityTagActionResultResponse(request, result)); + } + /************* im message ************/ diff --git a/o2web/source/x_component_IMV2/$Main/default/chat.html b/o2web/source/x_component_IMV2/$Main/default/chat.html index af70936981ed1c8a4af9f41cb3beea0f8b698b8d..86bd79f2aa521a3627a9ce553df9fb4219eecbc9 100644 --- a/o2web/source/x_component_IMV2/$Main/default/chat.html +++ b/o2web/source/x_component_IMV2/$Main/default/chat.html @@ -6,6 +6,8 @@
{{$.lp.modifyGroupName}}
{{$.lp.modifyMember}}
+ @@ -21,7 +23,7 @@
-
Ctrl + Enter 换行
+
{{$.lp.sendKeyTips}}
{{$.lp.send}}
diff --git a/o2web/source/x_component_IMV2/$Main/default/icons/icon_setting.png b/o2web/source/x_component_IMV2/$Main/default/icons/icon_setting.png new file mode 100644 index 0000000000000000000000000000000000000000..7055fc6f69b6edd735274e44f86f0e3c4c0839d3 Binary files /dev/null and b/o2web/source/x_component_IMV2/$Main/default/icons/icon_setting.png differ diff --git a/o2web/source/x_component_IMV2/$Main/default/im.html b/o2web/source/x_component_IMV2/$Main/default/im.html index afadaea7ea7439657fbe85890d3155f5df6fd436..e215e03344e97187c9a04b53749e7ddcbddef85f 100644 --- a/o2web/source/x_component_IMV2/$Main/default/im.html +++ b/o2web/source/x_component_IMV2/$Main/default/im.html @@ -8,6 +8,7 @@
{{$.lp.createGroup}}
+