diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 00000000..c61ec553 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,42 @@ +# Use the latest 2.1 version of CircleCI pipeline process engine. +# See: https://circleci.com/docs/configuration-reference +version: 2.1 + +# Define a job to be invoked later in a workflow. +# See: https://circleci.com/docs/configuration-reference/#jobs +jobs: + # Below is the definition of your job to build and test your app, you can rename and customize it as you want. + package-build-push: + # These next lines define a Docker executor: https://circleci.com/docs/executor-types/ + # You can specify an image from Dockerhub or use one of our Convenience Images from CircleCI's Developer Hub. + # Be sure to update the Docker image tag below to openjdk version of your application. + # A list of available CircleCI Docker Convenience Images are available here: https://circleci.com/developer/images/image/cimg/openjdk + docker: + - image: cimg/openjdk:17.0.7 + # Add steps to the job + # See: https://circleci.com/docs/configuration-reference/#steps + steps: + # Checkout the code as the first step. + - checkout + - setup_remote_docker + - run: + name: Login DockerHub + command: | + echo "$DOCKERHUB_USERPASS" | docker login -u "$DOCKERHUB_USERNAME" --password-stdin + - run: + name: Build Contact Center Docker Image + command: cd $CIRCLE_WORKING_DIRECTORY/contact-center && ./admin/build.sh + - run: + name: Push Contact Center Docker Image to DockerHub + command: cd $CIRCLE_WORKING_DIRECTORY/contact-center && ./admin/push.sh + +# Invoke jobs via workflows +# See: https://circleci.com/docs/configuration-reference/#workflows +workflows: + dockerize: # This is the name of the workflow, feel free to change it to better match your workflow. + # Inside the workflow, you define the jobs you want to run. + jobs: + - package-build-push: + filters: + branches: + only: develop \ No newline at end of file diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 00000000..51db45b1 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,18 @@ +# https://github.com/cskefu/cskefu/issues/758 + +# defaults +* @cskefu/reviewers + +# Order is important; the last matching pattern takes the most +# precedence. When someone opens a pull request that only +# modifies JS files, only @js-owner and not the global +# owner(s) will be requested for a review. +*.js @lecjy +*.ts @lecjy +*.pug @lecjy +*.java @lecjy +*.sql @lecjy +pom.xml @lecjy + +docs/* @SAMZONG +README* @SAMZONG \ No newline at end of file diff --git a/.gitignore b/.gitignore index f3f99e28..512f45fb 100644 --- a/.gitignore +++ b/.gitignore @@ -22,4 +22,4 @@ build.gradle nohup.out docker-compose.dev.yml docker-compose.custom.yml -private +private/ diff --git a/CHANGELOG.md b/CHANGELOG.md index 83d92693..2ed3e4fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,15 @@ -以下为概述,各版本发布详情,请访问[春松客服专栏博客](https://chatopera.blog.csdn.net/)。 +各版本发布更新情况描述。 + +# 8.0.0 + +- 更新春松客服应用的开源许可证,使用[春松许可证, v1.0](https://www.cskefu.com/2023/06/25/chunsong-public-license-1-0) +- 更新 MySQL 数据库表结构,大量优化 Table 定义,去掉冗余字段,大幅度提升性能 +- 使用 Java 17 API & SDK,利用 JDK 新功能,大幅度提升性能 +- 从 Springboot 1.5.x 升级到 Springboot 3.x 版本,大幅度提升性能 +- 去掉了对中间件服务 Elasticsearch 的依赖,大幅度提升性能 +- 去掉了冗余的第三方代码,提升编译性能,减少潜在风险 +- 修补若干安全漏洞,如 [#735](https://github.com/cskefu/cskefu/issues/735), [#435](https://github.com/cskefu/cskefu/issues/435), [#177](https://github.com/cskefu/cskefu/issues/177) +- Fixed [#476](https://github.com/cskefu/cskefu/issues/476) every SQL execution slowly on first run # 7.0.1 diff --git a/LICENSE b/LICENSE index 5ed0db7d..411c2b55 100644 --- a/LICENSE +++ b/LICENSE @@ -1,201 +1,13 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ +Copyright 2023 Beijing Huaxia Chunsong Technology Co., Ltd. - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION +Licensed under the Chunsong Public License, Version 1.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at - 1. Definitions. + https://docs.cskefu.com/licenses/v1.html - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2018-2022 北京华夏春松科技有限公司 - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. \ No newline at end of file diff --git a/README.md b/README.md index 3d9dca97..d11ee3ea 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,21 @@
-[主页](https://www.cskefu.com/) | [开源许可协议](https://www.cskefu.com/2022/06/24/cskefu-opensource-license/) | [邮件列表](https://lists.cskefu.com/cgi-bin/mailman/listinfo/dev) | [路线图](https://chatopera.github.io/cskefu.roadmap/) +[主页](https://www.cskefu.com/) | [开源许可协议](https://docs.cskefu.com/licenses/v1.html) | [工单列表](https://github.com/cskefu/cskefu/issues) | [路线图](https://github.com/orgs/cskefu/projects/1)
# 春松客服 -[![GitHub Stargazers](https://img.shields.io/github/stars/chatopera/cskefu.svg?style=social&label=Star&maxAge=2592000)](https://github.com/cskefu/cskefu/stargazers) [![GitHub Forks](https://img.shields.io/github/forks/chatopera/cskefu.svg?style=social&label=Fork&maxAge=2592000)](https://github.com/cskefu/cskefu/network/members) [![License](https://img.shields.io/github/license/chatopera/cskefu.svg)](https://www.cskefu.com/2022/06/24/cskefu-opensource-license/ "开源许可协议") [![GitHub Issues](https://img.shields.io/github/issues/chatopera/cskefu.svg)](https://github.com/cskefu/cskefu/issues) [![GitHub Issues Closed](https://img.shields.io/github/issues-closed/chatopera/cskefu.svg)](https://github.com/cskefu/cskefu/issues?q=is%3Aissue+is%3Aclosed) [![docker](https://img.shields.io/docker/pulls/chatopera/contact-center.svg "Docker Pulls")](https://hub.docker.com/r/chatopera/contact-center/) +[![GitHub Stargazers](https://img.shields.io/github/stars/chatopera/cskefu.svg?style=social&label=Star&maxAge=2592000)](https://github.com/cskefu/cskefu/stargazers) [![GitHub Forks](https://img.shields.io/github/forks/chatopera/cskefu.svg?style=social&label=Fork&maxAge=2592000)](https://github.com/cskefu/cskefu/network/members) [![License](https://cdndownload2.chatopera.com/cskefu/licenses/chunsong1.0.svg)](https://www.cskefu.com/licenses/v1.html "开源许可协议") [![GitHub Issues](https://img.shields.io/github/issues/chatopera/cskefu.svg)](https://github.com/cskefu/cskefu/issues) [![GitHub Issues Closed](https://img.shields.io/github/issues-closed/chatopera/cskefu.svg)](https://github.com/cskefu/cskefu/issues?q=is%3Aissue+is%3Aclosed) [![docker](https://img.shields.io/docker/pulls/chatopera/contact-center.svg "Docker Pulls")](https://hub.docker.com/r/chatopera/contact-center/) [![All Contributors](https://img.shields.io/badge/all_contributors-33-orange.svg?style=flat-square)](#contributors-) [https://www.cskefu.com](https://www.cskefu.com/) -| 版本 | 文档中心 | Git 分支 | -| --- | --- | --- | -| v8.x | [v8](https://docs.cskefu.com/docs/) | [GitHub](https://github.com/cskefu/cskefu/tree/develop) \| [Gitee](https://gitee.com/cskefu/cskefu/tree/develop/) | -| v7.x | [v7](https://docs.cskefu.com/docs/v7/) | [GitHub](https://github.com/cskefu/cskefu/tree/master) \| [Gitee](https://gitee.com/cskefu/cskefu/tree/master/) | +| 版本 | 文档中心 | Git 分支 | 状态 | +| --- | --- | --- | --- | +| v8.x | [v8](https://docs.cskefu.com/docs/) | [GitHub](https://github.com/cskefu/cskefu/tree/develop) \| [Gitee](https://gitee.com/cskefu/cskefu/tree/develop/) | Active, 维护中 | +| v7.x | [v7](https://docs.cskefu.com/docs/v7/) | [GitHub](https://github.com/cskefu/cskefu/tree/v7) \| [Gitee](https://gitee.com/cskefu/cskefu/tree/v7/) | Sunset, 维护终止 | :hearts: 春松客服的愿景: @@ -29,7 +29,7 @@ 春松客服宣言视频: [Bilibili](https://www.bilibili.com/video/BV1hu411o76r/) | [YouTube](https://youtu.be/ILf3BWpq4Ns) - +新版本介绍:[观看春松客服 v8 新版本发布会 @ 2023-07-01](https://www.cskefu.com/2023/07/03/community-conf/) ## 媒体报道 @@ -233,7 +233,7 @@ 在春松客服开源社区,我们建立关系、发现认同、合作共赢! -- 了解春松客服采用的开源许可协议,参考[文档](https://www.cskefu.com/2022/06/24/cskefu-opensource-license/) +- 了解春松客服采用的开源许可协议,参考[文档](https://www.cskefu.com/2023/06/25/chunsong-public-license-1-0/) - 了解春松客服的开发计划,参考[文档](https://chatopera.github.io/cskefu.roadmap/) - 加入开源社区运营,成为社区合伙人,参考[文档](https://mp.weixin.qq.com/s/TLE87YX4k097iOXnV4WVSw) - 加入春松客服开源社区,参考[文档](https://www.cskefu.com/join-us/) @@ -293,8 +293,8 @@ ## 开源许可协议 -Copyright (2018-2023) 北京华夏春松科技有限公司 +Copyright 2023 Beijing Huaxia Chunsong Technology Co., Ltd. -[Apache License Version 2.0](https://www.cskefu.com/2022/06/24/cskefu-opensource-license/) +[Chunsong Public License, version 1.0](https://docs.cskefu.com/licenses/v1.html) ![image](./public/assets/screenshot-20220323-163051.jpg) diff --git a/contact-center/Dockerfile b/contact-center/Dockerfile index 5c307b06..0758f624 100644 --- a/contact-center/Dockerfile +++ b/contact-center/Dockerfile @@ -1,6 +1,5 @@ -FROM chatopera/java:11 +FROM chatopera/java:17 MAINTAINER Hai Liang Wang -# base image is built with config/base/build.sh ARG DEBIAN_FRONTEND=noninteractive ARG VCS_REF diff --git a/contact-center/README.md b/contact-center/README.md index 680f75f6..f2ad3e9b 100644 --- a/contact-center/README.md +++ b/contact-center/README.md @@ -1,7 +1,7 @@ -# 春松客服:智能客服系统 +# Chatopera Contact Center 前三代呼叫中心均是以电话为主要的服务渠道。在 2000 年,伴随着互联网以及移动通信的发展与普及,将电子邮件、互联网、手机短信等渠道接入呼叫中心,成为第四代呼叫中心的标志。第四代呼叫中心也称为多媒体呼叫中心或联络中心(Contact Center)。它相对传统呼叫中心来说接入渠道丰富,同时引入了多渠道接入与多渠道统一排队等概念。 ## 文档 - + diff --git a/contact-center/admin/build.sh b/contact-center/admin/build.sh index 5c88c8f7..cd9b7804 100755 --- a/contact-center/admin/build.sh +++ b/contact-center/admin/build.sh @@ -15,10 +15,6 @@ imagename=cskefu/contact-center [ -z "${BASH_SOURCE[0]}" -o "${BASH_SOURCE[0]}" = "$0" ] || return # build cd $appHome -if [ -d ../private ]; then - registryPrefix=dockerhub.qingcloud.com/ -fi - TIMESTAMP=`date "+%Y%m%d.%H%M%S"` PACKAGE_VERSION=`git rev-parse --short HEAD` APPLICATION_CUSTOMER_ENTITY=${APPLICATION_CUSTOMER_ENTITY:-"OpenSource Community"} diff --git a/contact-center/admin/compile.sh b/contact-center/admin/compile.sh index 25a37221..d4b2c19d 100755 --- a/contact-center/admin/compile.sh +++ b/contact-center/admin/compile.sh @@ -10,4 +10,10 @@ baseDir=$(cd `dirname "$0"`;pwd) # main [ -z "${BASH_SOURCE[0]}" -o "${BASH_SOURCE[0]}" = "$0" ] || return cd $baseDir/../app -mvn clean compile +mvn -DskipTests clean compile +# take too long time with dev002 for uploading artifact, skip this operation +# $baseDir/deploy.app.sh + +if [ ! $? -eq 0 ]; then + exit 1 +fi \ No newline at end of file diff --git a/contact-center/admin/db-setup.sql.sh b/contact-center/admin/db-setup.sql.sh new file mode 100644 index 00000000..f7a9e511 --- /dev/null +++ b/contact-center/admin/db-setup.sql.sh @@ -0,0 +1,30 @@ +#! /bin/bash +########################################### +# Create standalone SQL file to setup db +########################################### + +# constants +baseDir=$(cd `dirname "$0"`;pwd) +cwdDir=$PWD +export PYTHONUNBUFFERED=1 +export PATH=/opt/miniconda3/envs/venv-py3/bin:$PATH +export TS=$(date +%Y%m%d%H%M%S) +export DATE=`date "+%Y%m%d"` +export DATE_WITH_TIME=`date "+%Y%m%d-%H%M%S"` #add %3N as we want millisecond too + +# functions + +# main +[ -z "${BASH_SOURCE[0]}" -o "${BASH_SOURCE[0]}" = "$0" ] || return + +cd $baseDir/.. + +if [ ! -e tmp ]; then + mkdir tmp +fi + +cat config/sql/001.mysql-create-db.sql > tmp/db-setup.sql +echo "" >> tmp/db-setup.sql +cat config/sql/002.mysql-create-schemas.sql >> tmp/db-setup.sql + +echo "Setup Script created in" `pwd`/tmp/db-setup.sql \ No newline at end of file diff --git a/contact-center/admin/push.sh b/contact-center/admin/push.sh index 087e32aa..121b8de8 100755 --- a/contact-center/admin/push.sh +++ b/contact-center/admin/push.sh @@ -17,9 +17,5 @@ imagename=cskefu/contact-center cd $appHome PACKAGE_VERSION=`git rev-parse --short HEAD` -if [ -d ../private ]; then - registryPrefix=dockerhub.qingcloud.com/ -fi - docker push $registryPrefix$imagename:$PACKAGE_VERSION docker push $registryPrefix$imagename:develop \ No newline at end of file diff --git a/contact-center/app/.gitignore b/contact-center/app/.gitignore index b7453245..165c3b07 100644 --- a/contact-center/app/.gitignore +++ b/contact-center/app/.gitignore @@ -1,9 +1,11 @@ # dev profile src/main/resources/application-dev.properties -# ignore app views within plugins +# ignore plugins: app views, classes src/main/resources/templates/apps/callout src/main/resources/templates/apps/callcenter +src/main/java/com/cskefu/cc/plugins/botplt # ignore logs logs/ +data/ diff --git a/contact-center/app/pom.xml b/contact-center/app/pom.xml index e36fd107..01da5fe9 100644 --- a/contact-center/app/pom.xml +++ b/contact-center/app/pom.xml @@ -1,15 +1,25 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.cskefu.cc contact-center war cc-core - 春松客服:上线开源客服系统 + 春松客服:开源客服系统 + + + Chunsong Public License, version 1.0 + https://docs.cskefu.com/licenses/v1.html + + Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + + + com.cskefu.cc cc-root - 7.0.0-SNAPSHOT + 8.0.0-SNAPSHOT @@ -18,21 +28,6 @@ contact-center - - org.springframework.boot - spring-boot-maven-plugin - - - - repackage - - - - - - org.apache.maven.plugins - maven-resources-plugin - pl.project13.maven git-commit-id-plugin @@ -72,28 +67,6 @@ true - - org.springframework.boot - spring-boot-maven-plugin - - true - - - - org.springframework - springloaded - 1.2.8.RELEASE - - - - - maven-compiler-plugin - - 1.8 - 1.8 - UTF-8 - - org.apache.maven.plugins maven-war-plugin @@ -110,7 +83,29 @@ - 2.1.1 + 3.3.2 + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + org.springframework + springloaded + 1.2.8.RELEASE + + + + + org.apache.maven.plugins + maven-resources-plugin compile @@ -132,7 +127,7 @@ hain Hai Liang Wang - h@cskefu.com + hai@chatopera.com https://github.com/hailiang-wang Chatopera Inc. https://www.chatopera.com diff --git a/contact-center/app/src/main/java/com/cskefu/cc/.gitignore b/contact-center/app/src/main/java/com/cskefu/cc/.gitignore deleted file mode 100644 index e69de29b..00000000 diff --git a/contact-center/app/src/main/java/com/cskefu/cc/Application.java b/contact-center/app/src/main/java/com/cskefu/cc/Application.java index 4b6c5650..e034f128 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/Application.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/Application.java @@ -1,50 +1,48 @@ /* - * Copyright (C) 2017 优客服-多渠道客服系统 - * Modifications copyright (C) 2018-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2018- Jun. 2023 Chatopera Inc, , Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (C) 2017 优客服-多渠道客服系统, Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc; -import com.chatopera.cc.BlessingAndUnblessing; import com.cskefu.cc.basic.Constants; import com.cskefu.cc.basic.MainContext; import com.cskefu.cc.config.AppCtxRefreshEventListener; import com.cskefu.cc.util.SystemEnvHelper; import com.cskefu.cc.util.mobile.MobileNumberUtils; -import org.apache.commons.lang.StringUtils; +import jakarta.servlet.MultipartConfigElement; +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.Banner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.jms.JmsPoolConnectionFactoryFactory; import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer; -import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer; -import org.springframework.boot.web.servlet.ErrorPage; +import org.springframework.boot.web.server.ConfigurableWebServerFactory; +import org.springframework.boot.web.server.ErrorPage; +import org.springframework.boot.web.server.WebServerFactoryCustomizer; import org.springframework.boot.web.servlet.MultipartConfigFactory; import org.springframework.context.annotation.Bean; -import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.http.HttpStatus; import org.springframework.transaction.annotation.EnableTransactionManagement; +import org.springframework.util.unit.DataSize; -import javax.servlet.MultipartConfigElement; import java.io.IOException; @SpringBootApplication @EnableJpaRepositories("com.cskefu.cc.persistence.repository") -@EnableElasticsearchRepositories("com.cskefu.cc.persistence.es") @EnableTransactionManagement public class Application { @@ -54,10 +52,10 @@ public class Application { private String uploaddir; @Value("${spring.servlet.multipart.max-file-size}") - private String multipartMaxUpload; + private Long multipartMaxUpload; @Value("${spring.servlet.multipart.max-request-size}") - private String multipartMaxRequest; + private Long multipartMaxRequest; /** * 加载模块 @@ -67,7 +65,6 @@ public class Application { if (StringUtils.equalsIgnoreCase(SystemEnvHelper.parseFromApplicationProps("cskefu.modules.contacts"), "true")) { MainContext.enableModule(Constants.CSKEFU_MODULE_CONTACTS); } - // 会话监控模块 Customer Chats Audit if (StringUtils.equalsIgnoreCase(SystemEnvHelper.parseFromApplicationProps("cskefu.modules.cca"), "true")) { MainContext.enableModule(Constants.CSKEFU_MODULE_CCA); @@ -84,21 +81,14 @@ public class Application { } } - /** - * 开源许可协议 - */ - protected static void license(){ - System.out.println(">> 春松客服采用开源许可证:Apache License 2.0"); - System.out.println(">> 详细介绍:https://www.cskefu.com/cskefu-opensource-license"); - System.out.println(">> CSKeFu is released under Apache License 2.0"); - System.out.println(">> Get details about CSKeFu License with https://www.cskefu.com/cskefu-opensource-license"); - } - /** * Init local resources */ protected static void serve(final String[] args) { try { + // Tune druid params, https://github.com/cskefu/cskefu/issues/835 + System.setProperty("druid.mysql.usePingMethod", "false"); + MobileNumberUtils.init(); /************************ * 该APP中加载多个配置文件 @@ -107,8 +97,6 @@ public class Application { SpringApplication app = new SpringApplicationBuilder(Application.class) .properties("spring.config.name:application,git") .build(); - Application.license(); - BlessingAndUnblessing.print(); app.setBannerMode(Banner.Mode.CONSOLE); app.setAddCommandLineProperties(false); app.addListeners(new AppCtxRefreshEventListener()); @@ -120,27 +108,34 @@ public class Application { } } + // TODO lecjy @Bean public MultipartConfigElement multipartConfigElement() { MultipartConfigFactory factory = new MultipartConfigFactory(); - factory.setMaxFileSize(multipartMaxUpload); //KB,MB - factory.setMaxRequestSize(multipartMaxRequest); + factory.setMaxFileSize(DataSize.ofMegabytes(multipartMaxUpload)); //KB,MB + factory.setMaxRequestSize(DataSize.ofMegabytes(multipartMaxRequest)); factory.setLocation(uploaddir); return factory.createMultipartConfig(); } + // TODO lecjy @Bean - public EmbeddedServletContainerCustomizer containerCustomizer() { - return new EmbeddedServletContainerCustomizer() { - @Override - public void customize(ConfigurableEmbeddedServletContainer container) { - ErrorPage error = new ErrorPage("/error.html"); - container.addErrorPages(error); - } + public WebServerFactoryCustomizer webServerFactoryCustomizer() { + return factory -> { + // 定义404错误页 + HttpStatus notFound = HttpStatus.NOT_FOUND; + // 定义404错误页 + ErrorPage errorPage = new ErrorPage(notFound, "/error.html"); + // 追加错误页,替换springboot默认的错误页 + factory.addErrorPages(errorPage); }; } public static void main(String[] args) { - Application.serve(args); + try { + Application.serve(args); + } catch (Exception e) { + e.printStackTrace(); + } } } diff --git a/contact-center/app/src/main/java/com/cskefu/cc/ServletInitializer.java b/contact-center/app/src/main/java/com/cskefu/cc/ServletInitializer.java deleted file mode 100644 index 5fe75820..00000000 --- a/contact-center/app/src/main/java/com/cskefu/cc/ServletInitializer.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2017 优客服-多渠道客服系统 - * Modifications copyright (C) 2018-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.cskefu.cc; - -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.boot.web.support.SpringBootServletInitializer; - -public class ServletInitializer extends SpringBootServletInitializer{ - - @Override - protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { - return application.sources(Application.class); - } -} diff --git a/contact-center/app/src/main/java/com/cskefu/cc/acd/ACDAgentDispatcher.java b/contact-center/app/src/main/java/com/cskefu/cc/acd/ACDAgentDispatcher.java index cd74bf5e..b34c507b 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/acd/ACDAgentDispatcher.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/acd/ACDAgentDispatcher.java @@ -1,17 +1,15 @@ -/* - * Copyright (C) 2019-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * +/* + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2019-2022 Chatopera Inc, , + * Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.acd; @@ -63,26 +61,26 @@ public class ACDAgentDispatcher implements IACDDispatcher { * 1)将该坐席状态置为"非就绪" * 2) 将该坐席的访客重新分配给其它坐席 * - * @param ctx agentno和orgi为必填 + * @param ctx agentno为必填 * @return 有没有成功将所有其服务的访客都分配出去 */ @Override public void dequeue(final ACDComposeContext ctx) { // 先将该客服切换到非就绪状态 - final AgentStatus agentStatus = cache.findOneAgentStatusByAgentnoAndOrig(ctx.getAgentno(), ctx.getOrgi()); + final AgentStatus agentStatus = cache.findOneAgentStatusByAgentno(ctx.getAgentno()); if (agentStatus != null) { agentStatus.setBusy(false); agentStatus.setUpdatetime(new Date()); agentStatus.setStatus(MainContext.AgentStatusEnum.NOTREADY.toString()); agentStatusRes.save(agentStatus); - cache.putAgentStatusByOrgi(agentStatus, ctx.getOrgi()); + cache.putAgentStatus(agentStatus); } // 然后将该坐席的访客分配给其它坐席 // 获得该租户在线的客服的多少 // TODO 对于agentUser的技能组过滤,在下面再逐个考虑? // 该信息同样也包括当前用户 - List agentUsers = cache.findInservAgentUsersByAgentnoAndOrgi(ctx.getAgentno(), ctx.getOrgi()); + List agentUsers = cache.findInservAgentUsersByAgentno(ctx.getAgentno()); int sz = agentUsers.size(); for (final AgentUser x : agentUsers) { try { @@ -96,7 +94,7 @@ public class ACDAgentDispatcher implements IACDDispatcher { // 因为重新分配该访客,将其从撤离的坐席中服务集合中删除 // 此处类似于 Transfer redisCommand.removeSetVal( - RedisKey.getInServAgentUsersByAgentnoAndOrgi(ctx.getAgentno(), ctx.getOrgi()), x.getUserid()); + RedisKey.getInServAgentUsersByAgentno(ctx.getAgentno()), x.getUserid()); sz--; } catch (Exception e) { logger.warn("[dequeue] throw error:", e); diff --git a/contact-center/app/src/main/java/com/cskefu/cc/acd/ACDAgentService.java b/contact-center/app/src/main/java/com/cskefu/cc/acd/ACDAgentService.java index d5a3502b..223a38b2 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/acd/ACDAgentService.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/acd/ACDAgentService.java @@ -1,17 +1,15 @@ -/* - * Copyright (C) 2019-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * +/* + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2019-2022 Chatopera Inc, , + * Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.acd; @@ -33,10 +31,11 @@ import com.cskefu.cc.socketio.client.NettyClients; import com.cskefu.cc.socketio.message.Message; import com.cskefu.cc.util.HashMapUtils; import com.cskefu.cc.util.SerializeUtil; -import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; import java.util.Date; @@ -61,6 +60,7 @@ public class ACDAgentService { private ACDPolicyService acdPolicyService; @Autowired + @Lazy private PeerSyncIM peerSyncIM; @Autowired @@ -79,7 +79,7 @@ public class ACDAgentService { private AgentStatusRepository agentStatusRes; @Autowired - private OnlineUserRepository onlineUserRes; + private PassportWebIMUserRepository onlineUserRes; @Autowired private UserRepository userRes; @@ -94,7 +94,7 @@ public class ACDAgentService { * @param ctx */ public void notifyAgentUserProcessResult(final ACDComposeContext ctx) { - Objects.requireNonNull(ctx,"ctx can not be null"); + Objects.requireNonNull(ctx, "ctx can not be null"); if (StringUtils.isBlank(ctx.getMessage())) { logger.info("[onConnect] can not find available agent for user {}", ctx.getOnlineUserId()); return; @@ -132,7 +132,7 @@ public class ACDAgentService { } MainContext.getPeerSyncIM().send(MainContext.ReceiverType.VISITOR, - MainContext.ChannelType.toValue(ctx.getChannel()), + MainContext.ChannelType.toValue(ctx.getChannelType()), ctx.getAppid(), MainContext.MessageType.NEW, ctx.getOnlineUserId(), outMessage, true); @@ -144,30 +144,26 @@ public class ACDAgentService { * * @param agentno * @param agentUser - * @param orgi - * @return * @throws Exception */ - public AgentService assignVisitorAsInvite( + public void assignVisitorAsInvite( final String agentno, - final AgentUser agentUser, - final String orgi + final AgentUser agentUser ) throws Exception { - final AgentStatus agentStatus = cache.findOneAgentStatusByAgentnoAndOrig(agentno, orgi); - return pickupAgentUserInQueue(agentUser, agentStatus); + final AgentStatus agentStatus = cache.findOneAgentStatusByAgentno(agentno); + pickupAgentUserInQueue(agentUser, agentStatus); } /** * 为坐席批量分配用户 * * @param agentno - * @param orgi */ - public void assignVisitors(String agentno, String orgi) { - logger.info("[assignVisitors] agentno {}, orgi {}", agentno, orgi); + public void assignVisitors(String agentno) { + logger.info("[assignVisitors] agentno {}", agentno); // 获得目标坐席的状态 AgentStatus agentStatus = SerializeUtil.deserialize( - redisCommand.getHashKV(RedisKey.getAgentStatusReadyHashKey(orgi), agentno)); + redisCommand.getHashKV(RedisKey.getAgentStatusReadyHashKey(), agentno)); if (agentStatus == null) { logger.warn("[assignVisitors] can not find AgentStatus for agentno {}", agentno); @@ -185,12 +181,12 @@ public class ACDAgentService { } // 获得所有待服务访客的列表 - final Map pendingAgentUsers = cache.getAgentUsersInQueByOrgi(orgi); + final Map pendingAgentUsers = cache.getAgentUsersInQue(); // 本次批量分配访客数目 Map assigned = new HashMap<>(); - int currentAssigned = cache.getInservAgentUsersSizeByAgentnoAndOrgi( - agentStatus.getAgentno(), agentStatus.getOrgi()); + int currentAssigned = cache.getInservAgentUsersSizeByAgentno( + agentStatus.getAgentno()); logger.info( "[assignVisitors] agentno {}, name {}, current assigned {}, batch size in queue {}", @@ -229,7 +225,7 @@ public class ACDAgentService { } // 坐席未达到最大咨询访客数量,并且单次批量分配小于坐席就绪时分配最大访客数量(initMaxuser) - final SessionConfig sessionConfig = acdPolicyService.initSessionConfig(agentUser.getSkill(), orgi); + final SessionConfig sessionConfig = acdPolicyService.initSessionConfig(agentUser.getSkill()); if ((ACDServiceRouter.getAcdPolicyService().getAgentUsersBySkill(agentStatus, agentUser.getSkill()) < sessionConfig.getMaxuser()) && (assigned.getOrDefault(agentUser.getSkill(), 0) < sessionConfig.getInitmaxuser())) { assigned.merge(agentUser.getSkill(), 1, Integer::sum); pickupAgentUserInQueue(agentUser, agentStatus); @@ -242,7 +238,7 @@ public class ACDAgentService { break; } } - agentStatusProxy.broadcastAgentsStatus(orgi, "agent", "success", agentno); + agentStatusProxy.broadcastAgentsStatus("agent", "success", agentno); } /** @@ -254,19 +250,18 @@ public class ACDAgentService { */ public AgentService pickupAgentUserInQueue(final AgentUser agentUser, final AgentStatus agentStatus) { // 从排队队列移除 - cache.deleteAgentUserInqueByAgentUserIdAndOrgi(agentUser.getUserid(), agentUser.getOrgi()); + cache.deleteAgentUserInqueByAgentUserId(agentUser.getUserid()); AgentService agentService = null; // 下面开始处理其加入到服务中的队列 try { agentService = resolveAgentService( - agentStatus, agentUser, agentUser.getOrgi(), false); + agentStatus, agentUser, false); // 处理完成得到 agentService Message outMessage = new Message(); outMessage.setMessage(acdMessageHelper.getSuccessMessage( agentService, - agentUser.getChannel(), - agentUser.getOrgi())); + agentUser.getChanneltype())); outMessage.setMessageType(MainContext.MediaType.TEXT.toString()); outMessage.setCalltype(MainContext.CallType.IN.toString()); outMessage.setCreatetime(MainUtils.dateFormate.format(new Date())); @@ -278,7 +273,7 @@ public class ACDAgentService { // 向访客推送消息 peerSyncIM.send( MainContext.ReceiverType.VISITOR, - MainContext.ChannelType.toValue(agentUser.getChannel()), agentUser.getAppid(), + MainContext.ChannelType.toValue(agentUser.getChanneltype()), agentUser.getAppid(), MainContext.MessageType.STATUS, agentUser.getUserid(), outMessage, true ); @@ -288,7 +283,7 @@ public class ACDAgentService { MainContext.MessageType.NEW, agentUser.getAgentno(), outMessage, true); // 通知更新在线数据 - agentStatusProxy.broadcastAgentsStatus(agentUser.getOrgi(), "agent", "pickup", agentStatus.getAgentno()); + agentStatusProxy.broadcastAgentsStatus("agent", "pickup", agentStatus.getAgentno()); } } catch (Exception ex) { logger.warn("[assignVisitors] fail to process service", ex); @@ -300,10 +295,9 @@ public class ACDAgentService { * 访客服务结束 * * @param agentUser - * @param orgi * @throws Exception */ - public void finishAgentService(final AgentUser agentUser, final String orgi) { + public void finishAgentService(final AgentUser agentUser) { if (agentUser != null) { /** * 设置AgentUser @@ -312,7 +306,7 @@ public class ACDAgentService { AgentStatus agentStatus = null; if (StringUtils.equals(MainContext.AgentUserStatusEnum.INSERVICE.toString(), agentUser.getStatus()) && agentUser.getAgentno() != null) { - agentStatus = cache.findOneAgentStatusByAgentnoAndOrig(agentUser.getAgentno(), orgi); + agentStatus = cache.findOneAgentStatusByAgentno(agentUser.getAgentno()); } // 设置新AgentUser的状态 @@ -324,18 +318,18 @@ public class ACDAgentService { // 从缓存中删除agentUser缓存 agentUserRes.save(agentUser); - final SessionConfig sessionConfig = acdPolicyService.initSessionConfig(agentUser.getSkill(), orgi); + final SessionConfig sessionConfig = acdPolicyService.initSessionConfig(agentUser.getSkill()); /** * 坐席服务 */ AgentService service = null; if (StringUtils.isNotBlank(agentUser.getAgentserviceid())) { - service = agentServiceRes.findByIdAndOrgi(agentUser.getAgentserviceid(), agentUser.getOrgi()); + service = agentServiceRes.findById(agentUser.getAgentserviceid()).orElse(null); } else if (agentStatus != null) { // 该访客没有和坐席对话,因此没有 AgentService // 当做留言处理,创建一个新的 AgentService - service = resolveAgentService(agentStatus, agentUser, orgi, true); + service = resolveAgentService(agentStatus, agentUser, true); } if (service != null) { @@ -345,8 +339,7 @@ public class ACDAgentService { service.setSessiontimes(System.currentTimeMillis() - service.getServicetime().getTime()); } - final AgentUserTask agentUserTask = agentUserTaskRes.findOne( - agentUser.getId()); + final AgentUserTask agentUserTask = agentUserTaskRes.findById(agentUser.getId()).orElse(null); if (agentUserTask != null) { service.setAgentreplyinterval(agentUserTask.getAgentreplyinterval()); service.setAgentreplytime(agentUserTask.getAgentreplytime()); @@ -378,7 +371,7 @@ public class ACDAgentService { */ if (agentStatus != null) { agentStatus.setUsers( - cache.getInservAgentUsersSizeByAgentnoAndOrgi(agentStatus.getAgentno(), agentStatus.getOrgi())); + cache.getInservAgentUsersSizeByAgentno(agentStatus.getAgentno())); agentStatusRes.save(agentStatus); } @@ -387,12 +380,12 @@ public class ACDAgentService { /** * 发送到访客端的通知 */ - switch (MainContext.ChannelType.toValue(agentUser.getChannel())) { + switch (MainContext.ChannelType.toValue(agentUser.getChanneltype())) { case WEBIM: // WebIM 发送对话结束事件 // 向访客发送消息 outMessage.setAgentStatus(agentStatus); - outMessage.setMessage(acdMessageHelper.getServiceFinishMessage(agentUser.getChannel(), agentUser.getSkill(), orgi)); + outMessage.setMessage(acdMessageHelper.getServiceFinishMessage(agentUser.getChanneltype(), agentUser.getSkill())); outMessage.setMessageType(MainContext.AgentUserStatusEnum.END.toString()); outMessage.setCalltype(MainContext.CallType.IN.toString()); outMessage.setCreatetime(MainUtils.dateFormate.format(new Date())); @@ -401,7 +394,7 @@ public class ACDAgentService { // 向访客发送消息 peerSyncIM.send( MainContext.ReceiverType.VISITOR, - MainContext.ChannelType.toValue(agentUser.getChannel()), agentUser.getAppid(), + MainContext.ChannelType.toValue(agentUser.getChanneltype()), agentUser.getAppid(), MainContext.MessageType.STATUS, agentUser.getUserid(), outMessage, true ); @@ -423,7 +416,7 @@ public class ACDAgentService { break; case MESSENGER: outMessage.setAgentStatus(agentStatus); - outMessage.setMessage(acdMessageHelper.getServiceFinishMessage(agentUser.getChannel(), agentUser.getSkill(), orgi)); + outMessage.setMessage(acdMessageHelper.getServiceFinishMessage(agentUser.getChanneltype(), agentUser.getSkill())); outMessage.setMessageType(MainContext.AgentUserStatusEnum.END.toString()); outMessage.setCalltype(MainContext.CallType.IN.toString()); outMessage.setCreatetime(MainUtils.dateFormate.format(new Date())); @@ -432,7 +425,7 @@ public class ACDAgentService { // 向访客发送消息 peerSyncIM.send( MainContext.ReceiverType.VISITOR, - MainContext.ChannelType.toValue(agentUser.getChannel()), agentUser.getAppid(), + MainContext.ChannelType.toValue(agentUser.getChanneltype()), agentUser.getAppid(), MainContext.MessageType.STATUS, agentUser.getUserid(), outMessage, true ); @@ -448,30 +441,30 @@ public class ACDAgentService { default: logger.info( "[finishAgentService] ignore notify agent service end for channel {}, agent user id {}", - agentUser.getChannel(), agentUser.getId()); + agentUser.getChanneltype(), agentUser.getId()); } // 更新访客的状态为可以接收邀请 - final OnlineUser onlineUser = onlineUserRes.findOneByUseridAndOrgi( - agentUser.getUserid(), agentUser.getOrgi()); - if (onlineUser != null) { - onlineUser.setInvitestatus(MainContext.OnlineUserInviteStatus.DEFAULT.toString()); - onlineUserRes.save(onlineUser); + final PassportWebIMUser passportWebIMUser = onlineUserRes.findOneByUserid( + agentUser.getUserid()); + if (passportWebIMUser != null) { + passportWebIMUser.setInvitestatus(MainContext.OnlineUserInviteStatus.DEFAULT.toString()); + onlineUserRes.save(passportWebIMUser); logger.info( - "[finishAgentService] onlineUser id {}, status {}, invite status {}", onlineUser.getId(), - onlineUser.getStatus(), onlineUser.getInvitestatus()); + "[finishAgentService] onlineUser id {}, status {}, invite status {}", passportWebIMUser.getId(), + passportWebIMUser.getStatus(), passportWebIMUser.getInvitestatus()); } // 当前访客服务已经结束,为坐席寻找新访客 if (agentStatus != null) { if ((ACDServiceRouter.getAcdPolicyService().getAgentUsersBySkill(agentStatus, agentUser.getSkill()) - 1) < sessionConfig.getMaxuser()) { - assignVisitors(agentStatus.getAgentno(), orgi); + assignVisitors(agentStatus.getAgentno()); } } agentStatusProxy.broadcastAgentsStatus( - orgi, "end", "success", agentUser != null ? agentUser.getId() : null); + "end", "success", agentUser != null ? agentUser.getId() : null); } else { - logger.info("[finishAgentService] orgi {}, invalid agent user, should not be null", orgi); + logger.info("[finishAgentService] invalid agent user, should not be null"); } } @@ -481,11 +474,10 @@ public class ACDAgentService { * 包括数据库记录及缓存信息 * * @param agentUser - * @param orgi * @return */ - public void finishAgentUser(final AgentUser agentUser, final String orgi) throws CSKefuException { - logger.info("[finishAgentUser] userId {}, orgi {}", agentUser.getUserid(), orgi); + public void finishAgentUser(final AgentUser agentUser) throws CSKefuException { + logger.info("[finishAgentUser] userId {}", agentUser.getUserid()); if (agentUser == null || agentUser.getId() == null) { throw new CSKefuException("Invalid agentUser info"); @@ -496,7 +488,7 @@ public class ACDAgentService { * 未结束聊天,先结束对话,然后删除记录 */ // 删除缓存 - finishAgentService(agentUser, orgi); + finishAgentService(agentUser); } // 删除数据库里的AgentUser记录 @@ -511,36 +503,32 @@ public class ACDAgentService { * * @param agentStatus 坐席状态 * @param agentUser 坐席访客会话 - * @param orgi 租户ID * @param finished 结束服务 * @return */ public AgentService resolveAgentService( AgentStatus agentStatus, final AgentUser agentUser, - final String orgi, final boolean finished) { AgentService agentService = new AgentService(); if (StringUtils.isNotBlank(agentUser.getAgentserviceid())) { - AgentService existAgentService = agentServiceRes.findByIdAndOrgi(agentUser.getAgentserviceid(), orgi); + AgentService existAgentService = agentServiceRes.findById(agentUser.getAgentserviceid()).orElse(null); if (existAgentService != null) { agentService = existAgentService; } else { agentService.setId(agentUser.getAgentserviceid()); } } - agentService.setOrgi(orgi); - final Date now = new Date(); // 批量复制属性 MainUtils.copyProperties(agentUser, agentService); - agentService.setChannel(agentUser.getChannel()); + agentService.setChanneltype(agentUser.getChanneltype()); agentService.setSessionid(agentUser.getSessionid()); // 此处为何设置loginDate为现在 agentUser.setLogindate(now); - OnlineUser onlineUser = onlineUserRes.findOneByUseridAndOrgi(agentUser.getUserid(), orgi); + PassportWebIMUser passportWebIMUser = onlineUserRes.findOneByUserid(agentUser.getUserid()); if (finished == true) { // 服务结束 @@ -553,9 +541,9 @@ public class ACDAgentService { agentService.setLeavemsgstatus(MainContext.LeaveMsgStatus.NOTPROCESS.toString()); //未处理的留言 } - if (onlineUser != null) { + if (passportWebIMUser != null) { // 更新OnlineUser对象,变更为默认状态,可以接受邀请 - onlineUser.setInvitestatus(MainContext.OnlineUserInviteStatus.DEFAULT.toString()); + passportWebIMUser.setInvitestatus(MainContext.OnlineUserInviteStatus.DEFAULT.toString()); } } else if (agentStatus != null) { agentService.setAgent(agentStatus.getAgentno()); @@ -592,7 +580,7 @@ public class ACDAgentService { agentService.setOwner(agentUser.getOwner()); agentService.setTimes(0); - final User agent = userRes.findOne(agentService.getAgentno()); + final User agent = userRes.findById(agentService.getAgentno()).orElse(null); agentUser.setAgentname(agent.getUname()); agentUser.setAgentno(agentService.getAgentno()); @@ -619,11 +607,11 @@ public class ACDAgentService { agentService.setWaittingtime((int) (System.currentTimeMillis() - agentUser.getCreatetime().getTime())); agentUser.setWaittingtime(agentService.getWaittingtime()); } - if (onlineUser != null) { - agentService.setOsname(onlineUser.getOpersystem()); - agentService.setBrowser(onlineUser.getBrowser()); + if (passportWebIMUser != null) { + agentService.setOsname(passportWebIMUser.getOpersystem()); + agentService.setBrowser(passportWebIMUser.getBrowser()); // 记录onlineUser的id - agentService.setDataid(onlineUser.getId()); + agentService.setDataid(passportWebIMUser.getId()); } agentService.setLogindate(agentUser.getCreatetime()); @@ -645,14 +633,14 @@ public class ACDAgentService { /** * 更新OnlineUser对象,变更为服务中,不可邀请 */ - if (onlineUser != null && !finished) { - onlineUser.setInvitestatus(MainContext.OnlineUserInviteStatus.INSERV.toString()); - onlineUserRes.save(onlineUser); + if (passportWebIMUser != null && !finished) { + passportWebIMUser.setInvitestatus(MainContext.OnlineUserInviteStatus.INSERV.toString()); + onlineUserRes.save(passportWebIMUser); } // 更新坐席服务人数,坐席更新时间到缓存 if (agentStatus != null) { - agentUserProxy.updateAgentStatus(agentStatus, orgi); + agentUserProxy.updateAgentStatus(agentStatus); } return agentService; } diff --git a/contact-center/app/src/main/java/com/cskefu/cc/acd/ACDChatbotService.java b/contact-center/app/src/main/java/com/cskefu/cc/acd/ACDChatbotService.java index ac01503a..d1dfe0bc 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/acd/ACDChatbotService.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/acd/ACDChatbotService.java @@ -1,17 +1,15 @@ -/* - * Copyright (C) 2019-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * +/* + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2019-2022 Chatopera Inc, , + * Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.acd; @@ -20,7 +18,7 @@ import com.cskefu.cc.basic.MainContext; import com.cskefu.cc.model.AgentService; import com.cskefu.cc.model.AgentUser; import com.cskefu.cc.persistence.repository.AgentServiceRepository; -import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -39,15 +37,14 @@ public class ACDChatbotService { * 为访客分配机器人客服, ACD策略,此处 AgentStatus 是建议 的 坐席, 如果启用了 历史服务坐席 优先策略, 则会默认检查历史坐席是否空闲,如果空闲,则分配,如果不空闲,则 分配当前建议的坐席 * * @param agentUser - * @param orgi * @return * @throws Exception */ - public AgentService processChatbotService(final String botName, final AgentUser agentUser, final String orgi) { + public AgentService processChatbotService(final String botName, final AgentUser agentUser) { AgentService agentService = new AgentService(); //放入缓存的对象 Date now = new Date(); if (StringUtils.isNotBlank(agentUser.getAgentserviceid())) { - agentService = agentServiceRes.findByIdAndOrgi(agentUser.getAgentserviceid(), orgi); + agentService = agentServiceRes.findById(agentUser.getAgentserviceid()).orElse(null); agentService.setEndtime(now); if (agentService.getServicetime() != null) { agentService.setSessiontimes(System.currentTimeMillis() - agentService.getServicetime().getTime()); @@ -56,12 +53,11 @@ public class ACDChatbotService { } else { agentService.setServicetime(now); agentService.setLogindate(now); - agentService.setOrgi(orgi); agentService.setOwner(agentUser.getContextid()); agentService.setSessionid(agentUser.getSessionid()); agentService.setRegion(agentUser.getRegion()); agentService.setUsername(agentUser.getUsername()); - agentService.setChannel(agentUser.getChannel()); + agentService.setChanneltype(agentUser.getChanneltype()); if (botName != null) { agentService.setAgentusername(botName); } diff --git a/contact-center/app/src/main/java/com/cskefu/cc/acd/ACDPolicyService.java b/contact-center/app/src/main/java/com/cskefu/cc/acd/ACDPolicyService.java index 8b5f6993..d0eb72d6 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/acd/ACDPolicyService.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/acd/ACDPolicyService.java @@ -1,22 +1,19 @@ -/* - * Copyright (C) 2019-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * +/* + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2019-2022 Chatopera Inc, , + * Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.acd; -import com.cskefu.cc.basic.Constants; import com.cskefu.cc.basic.MainContext; import com.cskefu.cc.basic.MainUtils; import com.cskefu.cc.cache.Cache; @@ -25,7 +22,7 @@ import com.cskefu.cc.persistence.repository.*; import com.cskefu.cc.proxy.OrganProxy; import com.cskefu.cc.util.HashMapUtils; import com.cskefu.cc.util.WebIMReport; -import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -50,13 +47,13 @@ public class ACDPolicyService { private SessionConfigRepository sessionConfigRes; @Autowired - private OnlineUserRepository onlineUserRes; + private PassportWebIMUserRepository onlineUserRes; @Autowired private AgentUserRepository agentUserRes; @Autowired - private SNSAccountRepository snsAccountRes; + private ChannelRepository snsAccountRes; @Autowired private OrganProxy organProxy; @@ -69,10 +66,10 @@ public class ACDPolicyService { @SuppressWarnings("unchecked") public List initSessionConfigList() { List sessionConfigList; - if ((sessionConfigList = cache.findOneSessionConfigListByOrgi(Constants.SYSTEM_ORGI)) == null) { + if ((sessionConfigList = cache.findOneSessionConfigList()) == null) { sessionConfigList = sessionConfigRes.findAll(); if (sessionConfigList != null && sessionConfigList.size() > 0) { - cache.putSessionConfigListByOrgi(sessionConfigList, Constants.SYSTEM_ORGI); + cache.putSessionConfigList(sessionConfigList); } } return sessionConfigList; @@ -81,17 +78,16 @@ public class ACDPolicyService { /** * 载入坐席 ACD策略配置 * - * @param orgi * @return */ - public SessionConfig initSessionConfig(String organid, final String orgi) { + public SessionConfig initSessionConfig(String organid) { SessionConfig sessionConfig; - if ((sessionConfig = cache.findOneSessionConfigByOrgi(organid, orgi)) == null) { - sessionConfig = sessionConfigRes.findByOrgiAndSkill(orgi, organid); + if ((sessionConfig = cache.findOneSessionConfig(organid)) == null) { + sessionConfig = sessionConfigRes.findBySkill(organid); if (sessionConfig == null) { sessionConfig = new SessionConfig(); } else { - cache.putSessionConfigByOrgi(sessionConfig, organid, orgi); + cache.putSessionConfig(sessionConfig, organid); } } @@ -136,19 +132,17 @@ public class ACDPolicyService { * 优先级: 1. 指定坐席;2. 指定技能组; 3. 租户所有的坐席 * * @param agentUser - * @param orgi * @return */ public List filterOutAvailableAgentStatus( final AgentUser agentUser, - final String orgi, final SessionConfig sessionConfig) { logger.info( - "[filterOutAvailableAgentStatus] pre-conditions: agentUser.agentno {}, orgi {}, skill {}, onlineUser {}", - agentUser.getAgentno(), orgi, agentUser.getSkill(), agentUser.getUserid() + "[filterOutAvailableAgentStatus] pre-conditions: agentUser.agentno {}, skill {}, onlineUser {}", + agentUser.getAgentno(), agentUser.getSkill(), agentUser.getUserid() ); List agentStatuses = new ArrayList<>(); - Map map = cache.findAllReadyAgentStatusByOrgi(orgi); + Map map = cache.findAllReadyAgentStatus(); // DEBUG if (map.size() > 0) { @@ -168,7 +162,7 @@ public class ACDPolicyService { } if (agentUser != null && StringUtils.isNotBlank(agentUser.getAgentno())) { - User user = userRes.findById(agentUser.getAgentno()); + User user = userRes.findById(agentUser.getAgentno()).orElse(null); if (user != null && !user.isSuperadmin()) { // 用户不为空,并且不是超级管理员 // 指定坐席 @@ -236,9 +230,8 @@ public class ACDPolicyService { * * TODO 指定技能组无用户,停止分配 */ - - SNSAccount snsAccount = snsAccountRes.findBySnsidAndOrgi(agentUser.getAppid(), orgi); - Map allOrgan = organProxy.findAllOrganByParentIdAndOrgi(snsAccount.getOrgan(), orgi); + Channel channel = snsAccountRes.findBySnsid(agentUser.getAppid()).get(); + Map allOrgan = organProxy.findAllOrganByParentId(channel.getOrgan()); // allOrgan.keySet().retainAll // 对于该租户的所有客服 @@ -313,7 +306,6 @@ public class ACDPolicyService { public AgentStatus filterOutAgentStatusWithPolicies( final SessionConfig sessionConfig, final List agentStatuses, - final String orgi, final String onlineUserId, final boolean isInvite) { AgentStatus agentStatus = null; @@ -341,7 +333,7 @@ public class ACDPolicyService { logger.info("[filterOutAgentStatusWithPolicies] check agent against chat history."); // 启用了历史坐席优先 , 查找 历史服务坐席 List webIMaggs = MainUtils.getWebIMDataAgg( - onlineUserRes.findBySkillAndOrgiForDistinctAgent(sessionConfig.getSkill(), orgi, onlineUserId)); + onlineUserRes.findBySkillForDistinctAgent(sessionConfig.getSkill(), onlineUserId)); for (WebIMReport report : webIMaggs) { for (final AgentStatus o : agentStatuses) { if (StringUtils.equals( @@ -399,7 +391,7 @@ public class ACDPolicyService { } public int getAgentUsersBySkill(AgentStatus agentStatus, String skill) { - return agentUserRes.countByAgentnoAndStatusAndOrgiAndSkill(agentStatus.getAgentno(), MainContext.AgentUserStatusEnum.INSERVICE.toString(), agentStatus.getOrgi(), skill); + return agentUserRes.countByAgentnoAndStatusAndSkill(agentStatus.getAgentno(), MainContext.AgentUserStatusEnum.INSERVICE.toString(), skill); } } diff --git a/contact-center/app/src/main/java/com/cskefu/cc/acd/ACDQueueService.java b/contact-center/app/src/main/java/com/cskefu/cc/acd/ACDQueueService.java index 15dfe6cc..da035095 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/acd/ACDQueueService.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/acd/ACDQueueService.java @@ -1,24 +1,22 @@ -/* - * Copyright (C) 2019-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * +/* + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2019-2022 Chatopera Inc, , + * Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.acd; import com.cskefu.cc.cache.Cache; import com.cskefu.cc.model.AgentUser; -import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -35,9 +33,9 @@ public class ACDQueueService { private Cache cache; @SuppressWarnings("unchecked") - public int getQueueIndex(String agent, String orgi, String skill) { + public int getQueueIndex(String agent, String skill) { int queneUsers = 0; - Map map = cache.getAgentUsersInQueByOrgi(orgi); + Map map = cache.getAgentUsersInQue(); for (final Map.Entry entry : map.entrySet()) { if (StringUtils.isNotBlank(skill)) { diff --git a/contact-center/app/src/main/java/com/cskefu/cc/acd/ACDServiceRouter.java b/contact-center/app/src/main/java/com/cskefu/cc/acd/ACDServiceRouter.java index 85407efd..cf7bd181 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/acd/ACDServiceRouter.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/acd/ACDServiceRouter.java @@ -1,17 +1,15 @@ -/* - * Copyright (C) 2019-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * +/* + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2019-2022 Chatopera Inc, , + * Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.acd; diff --git a/contact-center/app/src/main/java/com/cskefu/cc/acd/ACDVisitorDispatcher.java b/contact-center/app/src/main/java/com/cskefu/cc/acd/ACDVisitorDispatcher.java index 8bd80ebc..0d9dfade 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/acd/ACDVisitorDispatcher.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/acd/ACDVisitorDispatcher.java @@ -1,17 +1,15 @@ -/* - * Copyright (C) 2019-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * +/* + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2019-2022 Chatopera Inc, , + * Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.acd; @@ -25,7 +23,7 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; /** * 处置访客分配 diff --git a/contact-center/app/src/main/java/com/cskefu/cc/acd/ACDWorkMonitor.java b/contact-center/app/src/main/java/com/cskefu/cc/acd/ACDWorkMonitor.java index 4967f7ca..d8d24739 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/acd/ACDWorkMonitor.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/acd/ACDWorkMonitor.java @@ -1,17 +1,15 @@ -/* - * Copyright (C) 2019-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * +/* + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2019-2022 Chatopera Inc, , + * Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.acd; @@ -26,7 +24,7 @@ import com.cskefu.cc.persistence.repository.AgentServiceRepository; import com.cskefu.cc.persistence.repository.AgentUserRepository; import com.cskefu.cc.persistence.repository.WorkMonitorRepository; import com.cskefu.cc.proxy.OrganProxy; -import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -58,28 +56,26 @@ public class ACDWorkMonitor { /** * 获得 当前服务状态 * - * @param orgi * @return */ @SuppressWarnings({"unchecked", "rawtypes"}) - public AgentReport getAgentReport(String orgi) { - return getAgentReport(null, orgi); + public AgentReport getAgentReport() { + return getAgentReport(null); } /** * 获得一个技能组的坐席状态 * * @param organ - * @param orgi * @return */ - public AgentReport getAgentReport(String organ, String orgi) { + public AgentReport getAgentReport(String organ) { /** * 统计当前在线的坐席数量 */ AgentReport report = new AgentReport(); - Map readys = cache.getAgentStatusReadyByOrig(orgi); + Map readys = cache.getAgentStatusReady(); int readyNum = 0; int busyNum = 0; @@ -104,7 +100,6 @@ public class ACDWorkMonitor { } report.setAgents(readyNum); report.setBusy(busyNum); - report.setOrgi(orgi); /** * 统计当前服务中的用户数量 @@ -113,20 +108,20 @@ public class ACDWorkMonitor { if (organ != null) { Organ currentOrgan = new Organ(); currentOrgan.setId(organ); - Map organs = organProxy.findAllOrganByParentAndOrgi(currentOrgan, orgi); + Map organs = organProxy.findAllOrganByParent(currentOrgan); - report.setUsers(agentServiceRes.countByOrgiAndStatusAndAgentskillIn(orgi, MainContext.AgentUserStatusEnum.INSERVICE.toString(), organs.keySet())); - report.setInquene(agentUserRes.countByOrgiAndStatusAndSkillIn(orgi, MainContext.AgentUserStatusEnum.INQUENE.toString(), organs.keySet())); + report.setUsers(agentServiceRes.countByStatusAndAgentskillIn(MainContext.AgentUserStatusEnum.INSERVICE.toString(), organs.keySet())); + report.setInquene(agentUserRes.countByStatusAndSkillIn(MainContext.AgentUserStatusEnum.INQUENE.toString(), organs.keySet())); } else { // 服务中 - report.setUsers(cache.getInservAgentUsersSizeByOrgi(orgi)); + report.setUsers(cache.getInservAgentUsersSize()); // 等待中 - report.setInquene(cache.getInqueAgentUsersSizeByOrgi(orgi)); + report.setInquene(cache.getInqueAgentUsersSize()); } // DEBUG logger.info( - "[getAgentReport] orgi {}, organ {}, agents {}, busy {}, users {}, inqueue {}", orgi, organ, + "[getAgentReport] organ {}, agents {}, busy {}, users {}, inqueue {}", organ, report.getAgents(), report.getBusy(), report.getUsers(), report.getInquene() ); return report; @@ -138,7 +133,6 @@ public class ACDWorkMonitor { * @param status 工作状态,也就是上一个状态 * @param current 下一个工作状态 * @param worktype 类型 : 语音OR 文本 - * @param orgi * @param lasttime */ public void recordAgentStatus( @@ -150,7 +144,6 @@ public class ACDWorkMonitor { String status, String current, String worktype, - String orgi, Date lasttime ) { WorkMonitor workMonitor = new WorkMonitor(); @@ -169,17 +162,16 @@ public class ACDWorkMonitor { workMonitor.setBusy(true); } if (status.equals(MainContext.AgentStatusEnum.READY.toString())) { - int count = workMonitorRes.countByAgentAndDatestrAndStatusAndOrgi( + int count = workMonitorRes.countByAgentAndDatestrAndStatus( agent, MainUtils.simpleDateFormat.format(new Date()), - MainContext.AgentStatusEnum.READY.toString(), orgi + MainContext.AgentStatusEnum.READY.toString() ); if (count == 0) { workMonitor.setFirsttime(true); } } if (current.equals(MainContext.AgentStatusEnum.NOTREADY.toString())) { - List workMonitorList = workMonitorRes.findByOrgiAndAgentAndDatestrAndFirsttime( - orgi, agent, MainUtils.simpleDateFormat.format(new Date()), true); + List workMonitorList = workMonitorRes.findByAgentAndDatestrAndFirsttime(agent, MainUtils.simpleDateFormat.format(new Date()), true); if (workMonitorList.size() > 0) { WorkMonitor firstWorkMonitor = workMonitorList.get(0); if (firstWorkMonitor.getFirsttimes() == 0) { @@ -193,7 +185,6 @@ public class ACDWorkMonitor { workMonitor.setDatestr(MainUtils.simpleDateFormat.format(new Date())); workMonitor.setName(agent); - workMonitor.setOrgi(orgi); workMonitor.setUserid(userid); workMonitorRes.save(workMonitor); diff --git a/contact-center/app/src/main/java/com/cskefu/cc/acd/basic/ACDComposeContext.java b/contact-center/app/src/main/java/com/cskefu/cc/acd/basic/ACDComposeContext.java index 090e8cb9..2c67c435 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/acd/basic/ACDComposeContext.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/acd/basic/ACDComposeContext.java @@ -1,17 +1,15 @@ -/* - * Copyright (C) 2019-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * +/* + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2019-2022 Chatopera Inc, , + * Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.acd.basic; @@ -23,12 +21,11 @@ import com.cskefu.cc.util.IP; public class ACDComposeContext extends Message { // 技能组及渠道 - private String orgi; private String organid; private Organ organ; private String appid; - private String channel; - private SNSAccount snsAccount; + private String channeltype; + private Channel channel; private String sessionid; // 策略 @@ -55,7 +52,7 @@ public class ACDComposeContext extends Message { // 访客 private String onlineUserId; - private OnlineUser onlineUser; + private PassportWebIMUser passportWebIMUser; private String onlineUserNickname; private String onlineUserHeadimgUrl; @@ -94,22 +91,22 @@ public class ACDComposeContext extends Message { this.appid = appid; } - public String getChannel() { + public String getChannelType() { + return channeltype; + } + + public void setChannelType(String channelType) { + this.channeltype = channelType; + } + + public Channel getSnsAccount() { return channel; } - public void setChannel(String channel) { + public void setSnsAccount(Channel channel) { this.channel = channel; } - public SNSAccount getSnsAccount() { - return snsAccount; - } - - public void setSnsAccount(SNSAccount snsAccount) { - this.snsAccount = snsAccount; - } - public SessionConfig getSessionConfig() { return sessionConfig; } @@ -190,12 +187,12 @@ public class ACDComposeContext extends Message { this.agentUser = agentUser; } - public OnlineUser getOnlineUser() { - return onlineUser; + public PassportWebIMUser getOnlineUser() { + return passportWebIMUser; } - public void setOnlineUser(OnlineUser onlineUser) { - this.onlineUser = onlineUser; + public void setOnlineUser(PassportWebIMUser passportWebIMUser) { + this.passportWebIMUser = passportWebIMUser; } public AgentService getAgentService() { @@ -286,14 +283,6 @@ public class ACDComposeContext extends Message { this.ownerid = ownerid; } - public String getOrgi() { - return orgi; - } - - public void setOrgi(String orgi) { - this.orgi = orgi; - } - public String getOnlineUserHeadimgUrl() { return onlineUserHeadimgUrl; } diff --git a/contact-center/app/src/main/java/com/cskefu/cc/acd/basic/ACDMessageHelper.java b/contact-center/app/src/main/java/com/cskefu/cc/acd/basic/ACDMessageHelper.java index 7a1e4804..d788622b 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/acd/basic/ACDMessageHelper.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/acd/basic/ACDMessageHelper.java @@ -1,17 +1,15 @@ -/* - * Copyright (C) 2019-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * +/* + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2019-2022 Chatopera Inc, , + * Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.acd.basic; @@ -23,7 +21,7 @@ import com.cskefu.cc.model.AgentUser; import com.cskefu.cc.model.SessionConfig; import com.cskefu.cc.util.IP; import com.cskefu.cc.util.IPTools; -import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -50,8 +48,7 @@ public class ACDMessageHelper { ctx.setOnlineUserId(agentUser.getUserid()); ctx.setOnlineUserNickname(agentUser.getNickname()); ctx.setOrganid(agentUser.getSkill()); - ctx.setOrgi(agentUser.getOrgi()); - ctx.setChannel(agentUser.getChannel()); + ctx.setChannelType(agentUser.getChanneltype()); ctx.setAgentno(agentUser.getAgentno()); ctx.setBrowser(agentUser.getBrowser()); ctx.setOsname(agentUser.getOsname()); @@ -78,15 +75,14 @@ public class ACDMessageHelper { * * @param agentService * @param channel - * @param orgi * @return */ - public String getSuccessMessage(AgentService agentService, String channel, String orgi) { + public String getSuccessMessage(AgentService agentService, String channel) { String queneTip = "" + agentService.getAgentusername() + ""; if (!MainContext.ChannelType.WEBIM.toString().equals(channel)) { queneTip = agentService.getAgentusername(); } - SessionConfig sessionConfig = acdPolicyService.initSessionConfig(agentService.getSkill(), orgi); + SessionConfig sessionConfig = acdPolicyService.initSessionConfig(agentService.getSkill()); String successMsg = "坐席分配成功," + queneTip + "为您服务。"; if (StringUtils.isNotBlank(sessionConfig.getSuccessmsg())) { successMsg = sessionConfig.getSuccessmsg().replaceAll("\\{agent\\}", queneTip); @@ -98,11 +94,10 @@ public class ACDMessageHelper { * 通知消息内容:和坐席断开 * * @param channel - * @param orgi * @return */ - public String getServiceFinishMessage(String channel, String organid, String orgi) { - SessionConfig sessionConfig = acdPolicyService.initSessionConfig(organid, orgi); + public String getServiceFinishMessage(String channel, String organid) { + SessionConfig sessionConfig = acdPolicyService.initSessionConfig(organid); String queneTip = "坐席已断开和您的对话"; if (StringUtils.isNotBlank(sessionConfig.getFinessmsg())) { queneTip = sessionConfig.getFinessmsg(); @@ -115,11 +110,10 @@ public class ACDMessageHelper { * 通知消息内容:和坐席断开,刷新页面 * * @param channel - * @param orgi * @return */ - public String getServiceOffMessage(String channel, String organid, String orgi) { - SessionConfig sessionConfig = acdPolicyService.initSessionConfig(organid, orgi); + public String getServiceOffMessage(String channel, String organid) { + SessionConfig sessionConfig = acdPolicyService.initSessionConfig(organid); String queneTip = "坐席已断开和您的对话,刷新页面为您分配新的坐席"; if (StringUtils.isNotBlank(sessionConfig.getFinessmsg())) { queneTip = sessionConfig.getFinessmsg(); @@ -127,7 +121,7 @@ public class ACDMessageHelper { return queneTip; } - public String getNoAgentMessage(int queneIndex, String channel, String organid, String orgi) { + public String getNoAgentMessage(int queneIndex, String channel, String organid) { if (queneIndex < 0) { queneIndex = 0; } @@ -135,7 +129,7 @@ public class ACDMessageHelper { if (!MainContext.ChannelType.WEBIM.toString().equals(channel)) { queneTip = String.valueOf(queneIndex); } - SessionConfig sessionConfig = acdPolicyService.initSessionConfig(organid, orgi); + SessionConfig sessionConfig = acdPolicyService.initSessionConfig(organid); String noAgentTipMsg = "坐席全忙,已进入等待队列,您也可以在其他时间再来咨询。"; if (StringUtils.isNotBlank(sessionConfig.getNoagentmsg())) { noAgentTipMsg = sessionConfig.getNoagentmsg().replaceAll("\\{num\\}", queneTip); @@ -143,13 +137,13 @@ public class ACDMessageHelper { return noAgentTipMsg; } - public String getQueneMessage(int queneIndex, String channel, String organid, String orgi) { + public String getQueneMessage(int queneIndex, String channel, String organid) { String queneTip = "" + queneIndex + ""; if (!MainContext.ChannelType.WEBIM.toString().equals(channel)) { queneTip = String.valueOf(queneIndex); } - SessionConfig sessionConfig = acdPolicyService.initSessionConfig(organid, orgi); + SessionConfig sessionConfig = acdPolicyService.initSessionConfig(organid); String agentBusyTipMsg = "正在排队,请稍候,在您之前,还有 " + queneTip + " 位等待用户。"; if (StringUtils.isNotBlank(sessionConfig.getAgentbusymsg())) { agentBusyTipMsg = sessionConfig.getAgentbusymsg().replaceAll("\\{num\\}", queneTip); @@ -163,7 +157,6 @@ public class ACDMessageHelper { * * @param onlineUserId * @param nickname - * @param orgi * @param session * @param appid * @param ip @@ -185,7 +178,6 @@ public class ACDMessageHelper { public static ACDComposeContext getWebIMComposeContext( final String onlineUserId, final String nickname, - final String orgi, final String session, final String appid, final String ip, @@ -215,8 +207,7 @@ public class ACDMessageHelper { ctx.setOnlineUserId(onlineUserId); ctx.setOnlineUserNickname(nickname); ctx.setOrganid(skill); - ctx.setOrgi(orgi); - ctx.setChannel(channel); + ctx.setChannelType(channel); ctx.setAgentno(agent); ctx.setBrowser(browser); ctx.setOsname(osname); diff --git a/contact-center/app/src/main/java/com/cskefu/cc/acd/basic/IACDDispatcher.java b/contact-center/app/src/main/java/com/cskefu/cc/acd/basic/IACDDispatcher.java index 19740e76..e9ac6202 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/acd/basic/IACDDispatcher.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/acd/basic/IACDDispatcher.java @@ -1,18 +1,16 @@ /* - * Copyright (C) 2017 优客服-多渠道客服系统 - * Modifications copyright (C) 2018-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2018- Jun. 2023 Chatopera Inc, , Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (C) 2017 优客服-多渠道客服系统, Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.acd.basic; diff --git a/contact-center/app/src/main/java/com/cskefu/cc/acd/middleware/visitor/ACDVisAllocatorMw.java b/contact-center/app/src/main/java/com/cskefu/cc/acd/middleware/visitor/ACDVisAllocatorMw.java index 5b0bbac6..d8483b21 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/acd/middleware/visitor/ACDVisAllocatorMw.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/acd/middleware/visitor/ACDVisAllocatorMw.java @@ -1,17 +1,15 @@ -/* - * Copyright (C) 2019-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * +/* + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2019-2022 Chatopera Inc, , + * Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.acd.middleware.visitor; @@ -47,18 +45,18 @@ public class ACDVisAllocatorMw implements Middleware { * 查询条件,当前在线的 坐席,并且 未达到最大 服务人数的坐席 */ final List agentStatuses = acdPolicyService.filterOutAvailableAgentStatus( - ctx.getAgentUser(), ctx.getOrgi(), ctx.getSessionConfig()); + ctx.getAgentUser(), ctx.getSessionConfig()); /** * 处理ACD 的 技能组请求和 坐席请求 */ AgentStatus agentStatus = acdPolicyService.filterOutAgentStatusWithPolicies( - ctx.getSessionConfig(), agentStatuses, ctx.getOrgi(), ctx.getOnlineUserId(), ctx.isInvite()); + ctx.getSessionConfig(), agentStatuses, ctx.getOnlineUserId(), ctx.isInvite()); AgentService agentService = null; try { agentService = acdAgentService.resolveAgentService( - agentStatus, ctx.getAgentUser(), ctx.getOrgi(), false); + agentStatus, ctx.getAgentUser(), false); } catch (Exception ex) { logger.warn("[allotAgent] exception: ", ex); } diff --git a/contact-center/app/src/main/java/com/cskefu/cc/acd/middleware/visitor/ACDVisBindingMw.java b/contact-center/app/src/main/java/com/cskefu/cc/acd/middleware/visitor/ACDVisBindingMw.java index 793039c2..489581c5 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/acd/middleware/visitor/ACDVisBindingMw.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/acd/middleware/visitor/ACDVisBindingMw.java @@ -1,17 +1,15 @@ -/* - * Copyright (C) 2019-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * +/* + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2019-2022 Chatopera Inc, , + * Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.acd.middleware.visitor; @@ -57,7 +55,7 @@ public class ACDVisBindingMw implements Middleware { if (StringUtils.isNotBlank(ctx.getOrganid())) { logger.info("[apply] bind skill {}", ctx.getOrganid()); // 绑定技能组 - Organ organ = organRes.findOne(ctx.getOrganid()); + Organ organ = organRes.findById(ctx.getOrganid()).orElse(null); if (organ != null) { ctx.getAgentUser().setSkill(organ.getId()); ctx.setOrgan(organ); @@ -73,7 +71,7 @@ public class ACDVisBindingMw implements Middleware { // 绑定坐席有可能是因为前端展示了技能组和坐席 // 也有可能是坐席发送了邀请,该访客接收邀请 ctx.getAgentUser().setAgentno(ctx.getAgentno()); - User agent = userRes.findOne(ctx.getAgentno()); + User agent = userRes.findById(ctx.getAgentno()).orElse(null); ctx.setAgent(agent); ctx.getAgentUser().setAgentname(agent.getUname()); } else { diff --git a/contact-center/app/src/main/java/com/cskefu/cc/acd/middleware/visitor/ACDVisBodyParserMw.java b/contact-center/app/src/main/java/com/cskefu/cc/acd/middleware/visitor/ACDVisBodyParserMw.java index 4f658137..7da261a2 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/acd/middleware/visitor/ACDVisBodyParserMw.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/acd/middleware/visitor/ACDVisBodyParserMw.java @@ -1,17 +1,15 @@ -/* - * Copyright (C) 2019-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * +/* + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2019-2022 Chatopera Inc, , + * Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.acd.middleware.visitor; @@ -24,13 +22,13 @@ import com.cskefu.cc.cache.Cache; import com.cskefu.cc.model.AgentUser; import com.cskefu.cc.model.AgentUserContacts; import com.cskefu.cc.model.Contacts; -import com.cskefu.cc.persistence.es.ContactsRepository; +import com.cskefu.cc.persistence.repository.ContactsRepository; import com.cskefu.cc.persistence.repository.AgentUserContactsRepository; import com.cskefu.cc.proxy.AgentStatusProxy; import com.cskefu.cc.proxy.AgentUserProxy; import com.chatopera.compose4j.Functional; import com.chatopera.compose4j.Middleware; -import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -77,7 +75,7 @@ public class ACDVisBodyParserMw implements Middleware { * NOTE AgentUser代表一次会话记录,在上一个会话结束,并且由坐席人员点击"清除"后,会从数据库中删除 * 此处查询到的,可能是之前的会话。其状态需要验证,所以不一定是由TA来服务本次会话。 */ - AgentUser agentUser = cache.findOneAgentUserByUserIdAndOrgi(ctx.getOnlineUserId(), ctx.getOrgi()).orElseGet( + AgentUser agentUser = cache.findOneAgentUserByUserId(ctx.getOnlineUserId()).orElseGet( () -> { /** * NOTE 新创建的AgentUser不需要设置Status和Agentno @@ -85,10 +83,9 @@ public class ACDVisBodyParserMw implements Middleware { */ AgentUser p = new AgentUser( ctx.getOnlineUserId(), - ctx.getChannel(), + ctx.getChannelType(), ctx.getOnlineUserId(), ctx.getOnlineUserNickname(), - ctx.getOrgi(), ctx.getAppid()); logger.info("[apply] create new agent user id {}", p.getId()); return p; @@ -97,7 +94,6 @@ public class ACDVisBodyParserMw implements Middleware { logger.info("[apply] resolve agent user id {}", agentUser.getId()); - agentUser.setOrgi(ctx.getOrgi()); agentUser.setUsername(resolveAgentUsername(agentUser, ctx.getOnlineUserNickname())); agentUser.setOsname(ctx.getOsname()); agentUser.setBrowser(ctx.getBrowser()); @@ -137,22 +133,19 @@ public class ACDVisBodyParserMw implements Middleware { ctx.setMessage( acdMessageHelper.getSuccessMessage( ctx.getAgentService(), - ctx.getChannel(), - ctx.getOrgi())); + ctx.getChannelType())); // TODO 判断 INSERVICE 时,agentService 对应的 agentUser logger.info( "[apply] agent service: agentno {}, \n agentuser id {} \n user {} \n channel {} \n status {} \n queue index {}", ctx.getAgentService().getAgentno(), ctx.getAgentService().getAgentuserid(), ctx.getAgentService().getUserid(), - ctx.getAgentService().getChannel(), + ctx.getAgentService().getChanneltype(), ctx.getAgentService().getStatus(), ctx.getAgentService().getQueneindex()); if (StringUtils.isNotBlank(ctx.getAgentService().getAgentuserid())) { - agentUserProxy.findOne(ctx.getAgentService().getAgentuserid()).ifPresent(p -> { - ctx.setAgentUser(p); - }); + agentUserProxy.findOne(ctx.getAgentService().getAgentuserid()).ifPresent(ctx::setAgentUser); } // TODO 如果是 INSERVICE 那么 agentService.getAgentuserid 就一定不能为空? @@ -168,35 +161,32 @@ public class ACDVisBodyParserMw implements Middleware { // } agentStatusProxy.broadcastAgentsStatus( - ctx.getOrgi(), "user", MainContext.AgentUserStatusEnum.INSERVICE.toString(), + "user", MainContext.AgentUserStatusEnum.INSERVICE.toString(), ctx.getAgentUser().getId()); break; case INQUENE: // 处理结果:进入排队队列 ctx.getAgentService().setQueneindex( acdQueueService.getQueueIndex( - ctx.getAgentUser().getAgentno(), ctx.getOrgi(), ctx.getAgentUser().getSkill())); + ctx.getAgentUser().getAgentno(), ctx.getAgentUser().getSkill())); if (ctx.getAgentService().getQueneindex() > 0) { // 当前有坐席,要排队 ctx.setMessage(acdMessageHelper.getQueneMessage( ctx.getAgentService().getQueneindex(), - ctx.getAgentUser().getChannel(), - ctx.getOrganid(), - ctx.getOrgi())); + ctx.getAgentUser().getChanneltype(), + ctx.getOrganid())); } else { // TODO 什么是否返回 noAgentMessage, 是否在是 INQUENE 时 getQueneindex == 0 // 当前没有坐席,要留言 ctx.setNoagent(true); ctx.setMessage(acdMessageHelper.getNoAgentMessage( ctx.getAgentService().getQueneindex(), - ctx.getChannel(), - ctx.getOrganid(), - ctx.getOrgi())); + ctx.getChannelType(), + ctx.getOrganid())); } - agentStatusProxy.broadcastAgentsStatus( - ctx.getOrgi(), "user", MainContext.AgentUserStatusEnum.INQUENE.toString(), + agentStatusProxy.broadcastAgentsStatus("user", MainContext.AgentUserStatusEnum.INQUENE.toString(), ctx.getAgentUser().getId()); break; @@ -209,9 +199,8 @@ public class ACDVisBodyParserMw implements Middleware { ctx.setNoagent(true); ctx.setMessage(acdMessageHelper.getNoAgentMessage( 0, - ctx.getChannel(), - ctx.getOrganid(), - ctx.getOrgi())); + ctx.getChannelType(), + ctx.getOrganid())); } logger.info( @@ -239,8 +228,8 @@ public class ACDVisBodyParserMw implements Middleware { } // 查找会话联系人关联表 - AgentUserContacts agentUserContact = agentUserContactsRes.findOneByUseridAndOrgi( - agentUser.getUserid(), agentUser.getOrgi()).orElse(null); + AgentUserContacts agentUserContact = agentUserContactsRes.findOneByUserid( + agentUser.getUserid()).orElse(null); if (agentUserContact != null) { Contacts contact = contactsRes.findOneById(agentUserContact.getContactsid()).orElseGet(null); if (contact != null) { diff --git a/contact-center/app/src/main/java/com/cskefu/cc/acd/middleware/visitor/ACDVisServiceMw.java b/contact-center/app/src/main/java/com/cskefu/cc/acd/middleware/visitor/ACDVisServiceMw.java index 05290331..afc377d6 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/acd/middleware/visitor/ACDVisServiceMw.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/acd/middleware/visitor/ACDVisServiceMw.java @@ -1,17 +1,15 @@ -/* - * Copyright (C) 2019-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * +/* + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2019-2022 Chatopera Inc, , + * Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.acd.middleware.visitor; @@ -22,7 +20,7 @@ import com.cskefu.cc.acd.basic.ACDMessageHelper; import com.cskefu.cc.basic.MainContext; import com.chatopera.compose4j.Functional; import com.chatopera.compose4j.Middleware; -import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -53,14 +51,13 @@ public class ACDVisServiceMw implements Middleware { case INQUENE: logger.info("[apply] agent user is in queue"); int queueIndex = acdQueueService.getQueueIndex( - ctx.getAgentUser().getAgentno(), ctx.getOrgi(), + ctx.getAgentUser().getAgentno(), ctx.getOrganid()); ctx.setMessage( acdMessageHelper.getQueneMessage( queueIndex, - ctx.getChannel(), - ctx.getOrganid(), - ctx.getOrgi())); + ctx.getChannelType(), + ctx.getOrganid())); break; case INSERVICE: // 该访客与坐席正在服务中,忽略新的连接 diff --git a/contact-center/app/src/main/java/com/cskefu/cc/acd/middleware/visitor/ACDVisSessionCfgMw.java b/contact-center/app/src/main/java/com/cskefu/cc/acd/middleware/visitor/ACDVisSessionCfgMw.java index 285c53b3..be149c3f 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/acd/middleware/visitor/ACDVisSessionCfgMw.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/acd/middleware/visitor/ACDVisSessionCfgMw.java @@ -1,17 +1,15 @@ -/* - * Copyright (C) 2019-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * +/* + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2019-2022 Chatopera Inc, , + * Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.acd.middleware.visitor; @@ -46,17 +44,16 @@ public class ACDVisSessionCfgMw implements Middleware { @Override public void apply(final ACDComposeContext ctx, final Functional next) { - SessionConfig sessionConfig = acdPolicyService.initSessionConfig(ctx.getOrganid(), - ctx.getOrgi()); + SessionConfig sessionConfig = acdPolicyService.initSessionConfig(ctx.getOrganid()); ctx.setSessionConfig(sessionConfig); // 查询就绪的坐席,如果指定技能组则按照技能组查询 AgentReport report; if (StringUtils.isNotBlank(ctx.getOrganid())) { - report = acdWorkMonitor.getAgentReport(ctx.getOrganid(), ctx.getOrgi()); + report = acdWorkMonitor.getAgentReport(ctx.getOrganid()); } else { - report = acdWorkMonitor.getAgentReport(ctx.getOrgi()); + report = acdWorkMonitor.getAgentReport(); } ctx.setAgentReport(report); @@ -67,7 +64,7 @@ public class ACDVisSessionCfgMw implements Middleware { ctx.setMessage(sessionConfig.getNotinwhmsg()); } else if (report.getAgents() == 0) { // 没有就绪的坐席 - if (ctx.getChannel().equals(MainContext.ChannelType.MESSENGER.toString())) { + if (ctx.getChannelType().equals(MainContext.ChannelType.MESSENGER.toString())) { next.apply(); } else { logger.info("[apply] find no agents, redirect to leave a message."); diff --git a/contact-center/app/src/main/java/com/cskefu/cc/activemq/AgentAuditSubscription.java b/contact-center/app/src/main/java/com/cskefu/cc/activemq/AgentAuditSubscription.java index e9977605..606b5389 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/activemq/AgentAuditSubscription.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/activemq/AgentAuditSubscription.java @@ -1,17 +1,15 @@ -/* - * Copyright (C) 2019-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * +/* + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2019-2022 Chatopera Inc, , + * Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.activemq; @@ -27,7 +25,7 @@ import com.cskefu.cc.socketio.client.NettyClients; import com.cskefu.cc.util.SerializeUtil; import com.google.gson.JsonObject; import com.google.gson.JsonParser; -import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -62,15 +60,14 @@ public class AgentAuditSubscription { try { final JsonObject json = new JsonParser().parse(msg).getAsJsonObject(); - if (json.has("orgi") && json.has("data") && + if (json.has("data") && json.has("agentUserId") && json.has("event") && json.has("agentno")) { // 查找关联的会话监控信息 - final AgentUserAudit agentUserAudit = cache.findOneAgentUserAuditByOrgiAndId( - json.get("orgi").getAsString(), + final AgentUserAudit agentUserAudit = cache.findOneAgentUserAuditById( json.get("agentUserId").getAsString()).orElseGet(() -> { - final AgentUser agentUser = agentUserRes.findOne(json.get("agentUserId").getAsString()); + final AgentUser agentUser = agentUserRes.findById(json.get("agentUserId").getAsString()).orElse(null); if (agentUser != null) { return agentAuditProxy.updateAgentUserAudits(agentUser); } else { diff --git a/contact-center/app/src/main/java/com/cskefu/cc/activemq/AgentSessionSubscription.java b/contact-center/app/src/main/java/com/cskefu/cc/activemq/AgentSessionSubscription.java index f5b9e9de..0c11c2f0 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/activemq/AgentSessionSubscription.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/activemq/AgentSessionSubscription.java @@ -1,17 +1,15 @@ -/* - * Copyright (C) 2019-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * +/* + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2019-2022 Chatopera Inc, , + * Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.activemq; diff --git a/contact-center/app/src/main/java/com/cskefu/cc/activemq/AgentSubscription.java b/contact-center/app/src/main/java/com/cskefu/cc/activemq/AgentSubscription.java index 9f16ce1f..b7c53367 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/activemq/AgentSubscription.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/activemq/AgentSubscription.java @@ -1,12 +1,14 @@ -/* - * Copyright (C) 2019-2022 Chatopera Inc, All rights reserved. +/* + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * Copyright (C) 2019-2022 Chatopera Inc, All rights reserved. * - * This software and related documentation are provided under a license agreement containing - * restrictions on use and disclosure and are protected by intellectual property laws. - * Except as expressly permitted in your license agreement or allowed by law, you may not use, - * copy, reproduce, translate, broadcast, modify, license, transmit, distribute, exhibit, perform, - * publish, or display any part, in any form, or by any means. Reverse engineering, disassembly, - * or decompilation of this software, unless required by law for interoperability, is prohibited. */ package com.cskefu.cc.activemq; diff --git a/contact-center/app/src/main/java/com/cskefu/cc/activemq/BlackListEventSubscription.java b/contact-center/app/src/main/java/com/cskefu/cc/activemq/BlackListEventSubscription.java index a5107ed0..c3b41101 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/activemq/BlackListEventSubscription.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/activemq/BlackListEventSubscription.java @@ -1,17 +1,15 @@ -/* - * Copyright (C) 2019-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * +/* + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2019-2022 Chatopera Inc, , + * Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.activemq; @@ -20,7 +18,7 @@ import com.alibaba.fastjson.JSONObject; import com.cskefu.cc.basic.Constants; import com.cskefu.cc.cache.Cache; import com.cskefu.cc.persistence.repository.BlackListRepository; -import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -52,10 +50,9 @@ public class BlackListEventSubscription { try { final JSONObject json = JSON.parseObject(payload); final String userId = json.getString("userId"); - final String orgi = json.getString("orgi"); - if (StringUtils.isNotBlank(userId) && StringUtils.isNotBlank(orgi)) { - cache.findOneBlackEntityByUserIdAndOrgi(userId, orgi).ifPresent(blackListRes::delete); + if (StringUtils.isNotBlank(userId)) { + cache.findOneBlackEntityByUserId(userId).ifPresent(blackListRes::delete); } else { logger.warn("[onMessage] error: invalid payload"); } diff --git a/contact-center/app/src/main/java/com/cskefu/cc/activemq/BrokerPublisher.java b/contact-center/app/src/main/java/com/cskefu/cc/activemq/BrokerPublisher.java index 06d8b337..b22c110b 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/activemq/BrokerPublisher.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/activemq/BrokerPublisher.java @@ -1,26 +1,31 @@ -/* - * Copyright (C) 2019-2022 Chatopera Inc, All rights reserved. +/* + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * Copyright (C) 2019-2022 Chatopera Inc, All rights reserved. * - * This software and related documentation are provided under a license agreement containing - * restrictions on use and disclosure and are protected by intellectual property laws. - * Except as expressly permitted in your license agreement or allowed by law, you may not use, - * copy, reproduce, translate, broadcast, modify, license, transmit, distribute, exhibit, perform, - * publish, or display any part, in any form, or by any means. Reverse engineering, disassembly, - * or decompilation of this software, unless required by law for interoperability, is prohibited. */ package com.cskefu.cc.activemq; import com.alibaba.fastjson.JSONObject; +import jakarta.annotation.PostConstruct; import org.apache.activemq.ScheduledMessage; import org.apache.activemq.command.ActiveMQTopic; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jms.core.JmsMessagingTemplate; import org.springframework.jms.core.JmsTemplate; +import org.springframework.messaging.Message; +import org.springframework.messaging.core.MessagePostProcessor; import org.springframework.stereotype.Component; -import javax.annotation.PostConstruct; import java.util.Map; @Component @@ -36,7 +41,6 @@ public class BrokerPublisher { logger.info("[ActiveMQ Publisher] setup successfully."); } - /** * 时延消息 * diff --git a/contact-center/app/src/main/java/com/cskefu/cc/activemq/OnlineUserSubscription.java b/contact-center/app/src/main/java/com/cskefu/cc/activemq/OnlineUserSubscription.java index e65c8381..2a6d5c93 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/activemq/OnlineUserSubscription.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/activemq/OnlineUserSubscription.java @@ -1,12 +1,14 @@ -/* - * Copyright (C) 2019-2022 Chatopera Inc, All rights reserved. +/* + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * Copyright (C) 2019-2022 Chatopera Inc, All rights reserved. * - * This software and related documentation are provided under a license agreement containing - * restrictions on use and disclosure and are protected by intellectual property laws. - * Except as expressly permitted in your license agreement or allowed by law, you may not use, - * copy, reproduce, translate, broadcast, modify, license, transmit, distribute, exhibit, perform, - * publish, or display any part, in any form, or by any means. Reverse engineering, disassembly, - * or decompilation of this software, unless required by law for interoperability, is prohibited. */ package com.cskefu.cc.activemq; @@ -22,7 +24,7 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.jms.annotation.JmsListener; import org.springframework.stereotype.Component; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; /** * IM OnlineUser diff --git a/contact-center/app/src/main/java/com/cskefu/cc/activemq/SocketioConnEventSubscription.java b/contact-center/app/src/main/java/com/cskefu/cc/activemq/SocketioConnEventSubscription.java index a22786bb..932a6230 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/activemq/SocketioConnEventSubscription.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/activemq/SocketioConnEventSubscription.java @@ -1,12 +1,14 @@ -/* - * Copyright (C) 2019-2022 Chatopera Inc, All rights reserved. +/* + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * Copyright (C) 2019-2022 Chatopera Inc, All rights reserved. * - * This software and related documentation are provided under a license agreement containing - * restrictions on use and disclosure and are protected by intellectual property laws. - * Except as expressly permitted in your license agreement or allowed by law, you may not use, - * copy, reproduce, translate, broadcast, modify, license, transmit, distribute, exhibit, perform, - * publish, or display any part, in any form, or by any means. Reverse engineering, disassembly, - * or decompilation of this software, unless required by law for interoperability, is prohibited. */ package com.cskefu.cc.activemq; @@ -27,7 +29,7 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.jms.annotation.JmsListener; import org.springframework.stereotype.Component; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; import java.util.Date; /** @@ -65,10 +67,9 @@ public class SocketioConnEventSubscription { try { JsonParser parser = new JsonParser(); JsonObject j = parser.parse(payload).getAsJsonObject(); - if (j.has("userId") && j.has("orgi") && j.has("isAdmin")) { - final AgentStatus agentStatus = cache.findOneAgentStatusByAgentnoAndOrig( - j.get("userId").getAsString(), - j.get("orgi").getAsString()); + if (j.has("userId") && j.has("isAdmin")) { + final AgentStatus agentStatus = cache.findOneAgentStatusByAgentno( + j.get("userId").getAsString()); if (agentStatus != null && (!agentStatus.isConnected())) { /** * 处理该坐席为离线 @@ -76,7 +77,6 @@ public class SocketioConnEventSubscription { // 重分配坐席 ACDComposeContext ctx = new ACDComposeContext(); ctx.setAgentno(agentStatus.getAgentno()); - ctx.setOrgi(agentStatus.getOrgi()); acdAgentDispatcher.dequeue(ctx); if (ctx.isResolved()) { logger.info("[onMessage] re-allotAgent for user's visitors successfully."); @@ -90,19 +90,19 @@ public class SocketioConnEventSubscription { agentStatus.setUpdatetime(new Date()); // 设置该坐席状态为离线 - cache.deleteAgentStatusByAgentnoAndOrgi(agentStatus.getAgentno(), agentStatus.getOrgi()); + cache.deleteAgentStatusByAgentno(agentStatus.getAgentno()); agentStatusRes.save(agentStatus); // 记录坐席工作日志 acdWorkMonitor.recordAgentStatus(agentStatus.getAgentno(), - agentStatus.getUsername(), - agentStatus.getAgentno(), - j.get("isAdmin").getAsBoolean(), - agentStatus.getAgentno(), - agentStatus.getStatus(), - MainContext.AgentStatusEnum.OFFLINE.toString(), - MainContext.AgentWorkType.MEIDIACHAT.toString(), - agentStatus.getOrgi(), null); + agentStatus.getUsername(), + agentStatus.getAgentno(), + j.get("isAdmin").getAsBoolean(), + agentStatus.getAgentno(), + agentStatus.getStatus(), + MainContext.AgentStatusEnum.OFFLINE.toString(), + MainContext.AgentWorkType.MEIDIACHAT.toString(), + null); } else if (agentStatus == null) { // 该坐席已经完成离线设置 logger.info("[onMessage] agent is already offline, skip any further operations"); diff --git a/contact-center/app/src/main/java/com/cskefu/cc/aspect/AgentStatusAspect.java b/contact-center/app/src/main/java/com/cskefu/cc/aspect/AgentStatusAspect.java index 7280e34f..fd710c34 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/aspect/AgentStatusAspect.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/aspect/AgentStatusAspect.java @@ -1,17 +1,15 @@ -/* - * Copyright (C) 2019-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * +/* + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2019-2022 Chatopera Inc, , + * Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.aspect; @@ -39,12 +37,12 @@ public class AgentStatusAspect { @After("execution(* com.cskefu.cc.persistence.repository.AgentStatusRepository.save(..))") public void save(final JoinPoint joinPoint) { final AgentStatus agentStatus = (AgentStatus) joinPoint.getArgs()[0]; - cache.putAgentStatusByOrgi(agentStatus, agentStatus.getOrgi()); + cache.putAgentStatus(agentStatus); } @After("execution(* com.cskefu.cc.persistence.repository.AgentStatusRepository.delete(..))") public void delete(final JoinPoint joinPoint) { final AgentStatus agentStatus = (AgentStatus) joinPoint.getArgs()[0]; - cache.deleteAgentStatusByAgentnoAndOrgi(agentStatus.getAgentno(), agentStatus.getOrgi()); + cache.deleteAgentStatusByAgentno(agentStatus.getAgentno()); } } diff --git a/contact-center/app/src/main/java/com/cskefu/cc/aspect/AgentUserAspect.java b/contact-center/app/src/main/java/com/cskefu/cc/aspect/AgentUserAspect.java index fb251643..e342ff09 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/aspect/AgentUserAspect.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/aspect/AgentUserAspect.java @@ -1,17 +1,15 @@ -/* - * Copyright (C) 2019-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * +/* + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2019-2022 Chatopera Inc, , + * Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.aspect; @@ -22,7 +20,7 @@ import com.cskefu.cc.cache.RedisCommand; import com.cskefu.cc.cache.RedisKey; import com.cskefu.cc.model.AgentUser; import com.cskefu.cc.proxy.AgentAuditProxy; -import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.StringUtils; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.After; @@ -69,7 +67,7 @@ public class AgentUserAspect { agentAuditProxy.updateAgentUserAudits(agentUser); // 同步缓存 - cache.putAgentUserByOrgi(agentUser, agentUser.getOrgi()); + cache.putAgentUser(agentUser); } @After("execution(* com.cskefu.cc.persistence.repository.AgentUserRepository.delete(..))") @@ -78,8 +76,8 @@ public class AgentUserAspect { logger.info( "[delete] agentUser id {}, agentno {}, userId {}", agentUser.getId(), agentUser.getAgentno(), agentUser.getUserid()); - cache.deleteAgentUserAuditByOrgiAndId(agentUser.getOrgi(), agentUser.getId()); - cache.deleteAgentUserByUserIdAndOrgi(agentUser, agentUser.getOrgi()); + cache.deleteAgentUserAuditById(agentUser.getId()); + cache.deleteAgentUserByUserId(agentUser); } /** @@ -92,18 +90,17 @@ public class AgentUserAspect { @Around("@annotation(com.cskefu.cc.aspect.AgentUserAspect.LinkAgentUser)") public Object LinkAgentUser(ProceedingJoinPoint joinPoint) throws Throwable { final AgentUser updated = (AgentUser) joinPoint.getArgs()[0]; - final String orgi = (String) joinPoint.getArgs()[1]; Object proceed = joinPoint.proceed(); // after things are done. logger.info( - "[linkAgentUser] agentUser: status {}, userId {}, agentno {}, orgi {}", updated.getStatus(), - updated.getUserid(), updated.getAgentno(), orgi); + "[linkAgentUser] agentUser: status {}, userId {}, agentno {}", updated.getStatus(), + updated.getUserid(), updated.getAgentno()); if (StringUtils.equals(updated.getStatus(), MainContext.AgentUserStatusEnum.END.toString())) { // 从集合中删除 redisCommand.removeSetVal( - RedisKey.getInServAgentUsersByAgentnoAndOrgi(updated.getAgentno(), orgi), updated.getUserid()); + RedisKey.getInServAgentUsersByAgentno(updated.getAgentno()), updated.getUserid()); } else if (StringUtils.equals(updated.getStatus(), MainContext.AgentUserStatusEnum.INSERVICE.toString())) { redisCommand.insertSetVal( - RedisKey.getInServAgentUsersByAgentnoAndOrgi(updated.getAgentno(), orgi), updated.getUserid()); + RedisKey.getInServAgentUsersByAgentno(updated.getAgentno()), updated.getUserid()); } else if (StringUtils.equals(updated.getStatus(), MainContext.AgentUserStatusEnum.INQUENE.toString())) { logger.info("[linkAgentUser] ignored inque agent user, haven't resolve one agent yet."); } else { diff --git a/contact-center/app/src/main/java/com/cskefu/cc/aspect/BlackEntityAspect.java b/contact-center/app/src/main/java/com/cskefu/cc/aspect/BlackEntityAspect.java index c81052ee..223bc85f 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/aspect/BlackEntityAspect.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/aspect/BlackEntityAspect.java @@ -1,17 +1,15 @@ -/* - * Copyright (C) 2019-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * +/* + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2019-2022 Chatopera Inc, , + * Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.aspect; @@ -39,14 +37,14 @@ public class BlackEntityAspect { @After("execution(* com.cskefu.cc.persistence.repository.BlackListRepository.save(..))") public void save(final JoinPoint joinPoint) { final BlackEntity blackEntity = (BlackEntity) joinPoint.getArgs()[0]; - logger.info("[save] blackEntity userId {}, orgi {}", blackEntity.getUserid(), blackEntity.getOrgi()); - cache.putBlackEntityByOrgi(blackEntity, blackEntity.getOrgi()); + logger.info("[save] blackEntity userId {}", blackEntity.getUserid()); + cache.putBlackEntity(blackEntity); } @After("execution(* com.cskefu.cc.persistence.repository.BlackListRepository.delete(..))") public void delete(final JoinPoint joinPoint) { final BlackEntity blackEntity = (BlackEntity) joinPoint.getArgs()[0]; - logger.info("[delete] blackEntity userId {}, orgi {}", blackEntity.getUserid(), blackEntity.getOrgi()); - cache.deleteBlackEntityByUserIdAndOrgi(blackEntity.getUserid(), blackEntity.getOrgi()); + logger.info("[delete] blackEntity userId {}", blackEntity.getUserid()); + cache.deleteBlackEntityByUserId(blackEntity.getUserid()); } } diff --git a/contact-center/app/src/main/java/com/cskefu/cc/aspect/OnlineUserAspect.java b/contact-center/app/src/main/java/com/cskefu/cc/aspect/OnlineUserAspect.java index c82279c7..7951f90b 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/aspect/OnlineUserAspect.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/aspect/OnlineUserAspect.java @@ -1,24 +1,22 @@ -/* - * Copyright (C) 2019-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * +/* + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2019-2022 Chatopera Inc, , + * Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.aspect; import com.cskefu.cc.basic.MainContext; import com.cskefu.cc.cache.Cache; -import com.cskefu.cc.model.OnlineUser; -import org.apache.commons.lang.StringUtils; +import com.cskefu.cc.model.PassportWebIMUser; +import org.apache.commons.lang3.StringUtils; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; @@ -40,19 +38,19 @@ public class OnlineUserAspect { * * @param joinPoint */ - @Before("execution(* com.cskefu.cc.persistence.repository.OnlineUserRepository.save(..))") + @Before("execution(* com.cskefu.cc.persistence.repository.PassportWebIMUserRepository.save(..))") public void save(final JoinPoint joinPoint) { - final OnlineUser onlineUser = (OnlineUser) joinPoint.getArgs()[0]; + final PassportWebIMUser passportWebIMUser = (PassportWebIMUser) joinPoint.getArgs()[0]; // logger.info( // "[save] put onlineUser id {}, status {}, invite status {}", onlineUser.getId(), onlineUser.getStatus(), // onlineUser.getInvitestatus()); - if (StringUtils.isNotBlank(onlineUser.getStatus())) { - switch (MainContext.OnlineUserStatusEnum.toValue(onlineUser.getStatus())) { + if (StringUtils.isNotBlank(passportWebIMUser.getStatus())) { + switch (MainContext.OnlineUserStatusEnum.toValue(passportWebIMUser.getStatus())) { case OFFLINE: - cache.deleteOnlineUserByIdAndOrgi(onlineUser.getId(), onlineUser.getOrgi()); + cache.deleteOnlineUserById(passportWebIMUser.getId()); break; default: - cache.putOnlineUserByOrgi(onlineUser, onlineUser.getOrgi()); + cache.putOnlineUser(passportWebIMUser); } } } diff --git a/contact-center/app/src/main/java/com/cskefu/cc/aspect/SyncDatabaseAspect.java b/contact-center/app/src/main/java/com/cskefu/cc/aspect/SyncDatabaseAspect.java index e9145bd6..afa8afbe 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/aspect/SyncDatabaseAspect.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/aspect/SyncDatabaseAspect.java @@ -1,22 +1,19 @@ /* - * Copyright (C) 2017 优客服-多渠道客服系统 - * Modifications copyright (C) 2018-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2018- Jun. 2023 Chatopera Inc, , Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (C) 2017 优客服-多渠道客服系统, Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.aspect; -import com.cskefu.cc.model.ESBean; import com.cskefu.cc.persistence.hibernate.BaseService; import com.cskefu.cc.util.CskefuList; import org.aspectj.lang.ProceedingJoinPoint; @@ -89,11 +86,7 @@ public class SyncDatabaseAspect { if (data instanceof List) { dbDataRes.deleteAll((List) data); } else { - if (data instanceof ESBean) { - dbDataRes.delete(data); - } else { - dbDataRes.delete(data); - } + dbDataRes.delete(data); } } } diff --git a/contact-center/app/src/main/java/com/cskefu/cc/basic/Constants.java b/contact-center/app/src/main/java/com/cskefu/cc/basic/Constants.java index a033678c..6df47781 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/basic/Constants.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/basic/Constants.java @@ -1,17 +1,15 @@ -/* - * Copyright (C) 2019-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * +/* + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2019-2022 Chatopera Inc, , + * Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.basic; @@ -29,7 +27,6 @@ public class Constants { /** * 系统配置 */ - public static final String SYSTEM_ORGI = "cskefu"; public static final String USER_SESSION_NAME = "user"; public static final String ORGAN_SESSION_NAME = "organ"; public static final String GUEST_USER = "guest"; @@ -208,11 +205,16 @@ public class Constants { /** * 聊天机器人 */ - public static final HashSet CHATBOT_VALID_LANGS = new HashSet(Arrays.asList("zh_CN", "en_US")); + public static final HashSet CHATBOT_VALID_LANGS = new HashSet<>(Arrays.asList("zh_CN", "en_US")); public static final String CHATBOT_CHATBOT_FIRST = "机器人客服优先"; public static final String CHATBOT_HUMAN_FIRST = "人工客服优先"; public static final String CHATBOT_CHATBOT_ONLY = "仅机器人客服"; - public static final HashSet CHATBOT_VALID_WORKMODELS = new HashSet(Arrays.asList(CHATBOT_CHATBOT_FIRST, CHATBOT_HUMAN_FIRST, CHATBOT_CHATBOT_ONLY)); + public static final HashSet CHATBOT_VALID_WORKMODELS = new HashSet<>(Arrays.asList(CHATBOT_CHATBOT_FIRST, CHATBOT_HUMAN_FIRST, CHATBOT_CHATBOT_ONLY)); + /** + * AUTH + */ + public static final String AUTH_TOKEN_TYPE_BEARER = "Bearer"; + public static final String AUTH_TOKEN_TYPE_BASIC = "Basic"; } diff --git a/contact-center/app/src/main/java/com/cskefu/cc/basic/MainContext.java b/contact-center/app/src/main/java/com/cskefu/cc/basic/MainContext.java index a4e950a6..753d6d74 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/basic/MainContext.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/basic/MainContext.java @@ -1,24 +1,20 @@ /* - * Copyright (C) 2017 优客服-多渠道客服系统 - * Modifications copyright (C) 2018-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2018- Jun. 2023 Chatopera Inc, , Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (C) 2017 优客服-多渠道客服系统, Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.basic; -import com.cskefu.cc.basic.resource.ActivityResource; -import com.cskefu.cc.basic.resource.BatchResource; import com.cskefu.cc.cache.Cache; import com.cskefu.cc.cache.RedisCommand; import com.cskefu.cc.peer.PeerSyncIM; @@ -26,11 +22,10 @@ import com.cskefu.cc.util.DateConverter; import com.cskefu.cc.util.SystemEnvHelper; import com.fasterxml.jackson.annotation.JsonProperty; import org.apache.commons.beanutils.ConvertUtils; -import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.ApplicationContext; -import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; import java.util.HashMap; import java.util.HashSet; @@ -43,14 +38,12 @@ public class MainContext { private static boolean imServerRunning = false; // IM服务状态 - private static Set modules = new HashSet(); + private static final Set modules = new HashSet<>(); - public static Map> csKeFuResourceMap = new HashMap>(); + public static final Map> csKeFuResourceMap = new HashMap<>(); private static ApplicationContext applicationContext; - private static ElasticsearchTemplate templet; - private static RedisCommand redisCommand; private static Cache cache; @@ -59,8 +52,6 @@ public class MainContext { static { ConvertUtils.register(new DateConverter(), java.util.Date.class); - csKeFuResourceMap.put(TaskType.ACTIVE.toString(), ActivityResource.class); - csKeFuResourceMap.put(TaskType.BATCH.toString(), BatchResource.class); } public enum AskSectionType { @@ -339,8 +330,8 @@ public class MainContext { CALLIN_DIST("呼入挂断", 8), CALLIN_FAIL("呼入失败", 9); - private String name; - private int index; + private final String name; + private final int index; CallWireEventType(final String name, final int index) { this.name = name; @@ -663,8 +654,8 @@ public class MainContext { OFFLINE("离线", 6), SERVICES("服务", 7); - private String name; - private int index; + private final String name; + private final int index; AgentStatusEnum(final String name, final int index) { this.name = name; @@ -947,14 +938,6 @@ public class MainContext { return applicationContext; } - public static ElasticsearchTemplate getTemplet() { - return templet; - } - - public static void setTemplet(ElasticsearchTemplate templet) { - MainContext.templet = templet; - } - /** * 系统级的加密密码 , 从CA获取 * diff --git a/contact-center/app/src/main/java/com/cskefu/cc/basic/MainUtils.java b/contact-center/app/src/main/java/com/cskefu/cc/basic/MainUtils.java index 490e9ae7..146a8a7f 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/basic/MainUtils.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/basic/MainUtils.java @@ -1,18 +1,16 @@ /* - * Copyright (C) 2017 优客服-多渠道客服系统 - * Modifications copyright (C) 2018-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2018- Jun. 2023 Chatopera Inc, , Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (C) 2017 优客服-多渠道客服系统, Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.basic; @@ -25,7 +23,6 @@ import com.aliyuncs.profile.DefaultProfile; import com.aliyuncs.profile.IClientProfile; import com.cskefu.cc.model.*; import com.cskefu.cc.persistence.repository.*; -import com.cskefu.cc.util.WebIMReport; import com.cskefu.cc.util.*; import com.cskefu.cc.util.asr.AsrResult; import com.cskefu.cc.util.mail.MailSender; @@ -42,13 +39,14 @@ import de.neuland.pug4j.parser.node.Node; import de.neuland.pug4j.template.PugTemplate; import de.neuland.pug4j.template.ReaderTemplateLoader; import io.netty.handler.codec.http.HttpHeaders; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import net.coobird.thumbnailator.Thumbnails; import org.apache.commons.beanutils.BeanUtilsBean; import org.apache.commons.beanutils.ConversionException; import org.apache.commons.beanutils.ConvertUtils; -import org.apache.commons.beanutils.Converter; import org.apache.commons.codec.binary.Base64; -import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.StringUtils; import org.jasypt.util.text.BasicTextEncryptor; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; @@ -62,8 +60,6 @@ import org.springframework.beans.FatalBeanException; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import java.awt.image.BufferedImage; import java.beans.BeanInfo; import java.beans.Introspector; @@ -83,13 +79,13 @@ import java.util.regex.Pattern; public class MainUtils { private final static Logger logger = LoggerFactory.getLogger(MainUtils.class); - private static MD5 md5 = new MD5(); + private static final MD5 md5 = new MD5(); - public static SimpleDateFormat dateFormate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + public static final SimpleDateFormat dateFormate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - public static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); + public static final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); - public static SimpleDateFormat timeRangeDateFormat = new SimpleDateFormat("HH:mm"); + public static final SimpleDateFormat timeRangeDateFormat = new SimpleDateFormat("HH:mm"); /** * 当前时间+已过随机生成的 长整形数字 @@ -214,7 +210,7 @@ public class MainUtils { * @return */ public static Map getRequestParam(HttpServletRequest request) { - Map values = new HashMap(); + Map values = new HashMap<>(); Enumeration enums = request.getParameterNames(); while (enums.hasMoreElements()) { String param = enums.nextElement(); @@ -232,7 +228,7 @@ public class MainUtils { StringBuffer strb = new StringBuffer(); while (names.hasMoreElements()) { String name = names.nextElement(); - if (name.indexOf("password") < 0) { //不记录 任何包含 password 的参数内容 + if (!name.contains("password")) { //不记录 任何包含 password 的参数内容 if (strb.length() > 0) { strb.append(","); } @@ -348,15 +344,15 @@ public class MainUtils { //=================OS======================= - if (userAgent.toLowerCase().indexOf("windows") >= 0) { + if (userAgent.toLowerCase().contains("windows")) { os = "windows"; - } else if (userAgent.toLowerCase().indexOf("mac") >= 0) { + } else if (userAgent.toLowerCase().contains("mac")) { os = "mac"; - } else if (userAgent.toLowerCase().indexOf("x11") >= 0) { + } else if (userAgent.toLowerCase().contains("x11")) { os = "unix"; - } else if (userAgent.toLowerCase().indexOf("android") >= 0) { + } else if (userAgent.toLowerCase().contains("android")) { os = "android"; - } else if (userAgent.toLowerCase().indexOf("iphone") >= 0) { + } else if (userAgent.toLowerCase().contains("iphone")) { os = "iphone"; } else { os = "UnKnown"; @@ -364,8 +360,8 @@ public class MainUtils { //===============Browser=========================== if (user.contains("qqbrowser")) { browser = "QQBrowser"; - } else if (user.contains("msie") || user.indexOf("rv:11") > -1) { - if (user.indexOf("rv:11") >= 0) { + } else if (user.contains("msie") || user.contains("rv:11")) { + if (user.contains("rv:11")) { browser = "IE11"; } else { String substring = userAgent.substring(userAgent.indexOf("MSIE")).split(";")[0]; @@ -388,13 +384,11 @@ public class MainUtils { } } else if (user.contains("chrome")) { browser = "Chrome"; - } else if ((user.indexOf("mozilla/7.0") > -1) || (user.indexOf("netscape6") != -1) || (user.indexOf( - "mozilla/4.7") != -1) || (user.indexOf("mozilla/4.78") != -1) || (user.indexOf( - "mozilla/4.08") != -1) || (user.indexOf("mozilla/3") != -1)) { + } else if ((user.contains("mozilla/7.0")) || (user.contains("netscape6")) || (user.contains("mozilla/4.7")) || (user.contains("mozilla/4.78")) || (user.contains("mozilla/4.08")) || (user.contains("mozilla/3"))) { //browser=(userAgent.substring(userAgent.indexOf("MSIE")).split(" ")[0]).replace("/", "-"); browser = "Netscape-?"; - } else if ((user.indexOf("mozilla") > -1)) { + } else if ((user.contains("mozilla"))) { //browser=(userAgent.substring(userAgent.indexOf("MSIE")).split(" ")[0]).replace("/", "-"); if (browserDetails.indexOf(" ") > 0) { browser = browserDetails.substring(0, browserDetails.indexOf(" ")); @@ -445,8 +439,8 @@ public class MainUtils { WebIMReport report = new WebIMReport(); if (values != null && values.size() > 0) { - for (int i = 0; i < values.size(); i++) { - Object[] value = (Object[]) values.get(i); + for (Object o : values) { + Object[] value = (Object[]) o; if (value.length >= 2) { String invitestatus = (String) value[0]; if (MainContext.OnlineUserInviteStatus.DEFAULT.toString().equals( @@ -470,10 +464,10 @@ public class MainUtils { * @return */ public static List getWebIMInviteAgg(List values) { - List webIMReportList = new ArrayList(); + List webIMReportList = new ArrayList<>(); if (values != null && values.size() > 0) { - for (int i = 0; i < values.size(); i++) { - Object[] value = (Object[]) values.get(i); + for (Object o : values) { + Object[] value = (Object[]) o; WebIMReport report = new WebIMReport(); if (value.length == 3) { report.setData((String) value[0]); @@ -493,10 +487,10 @@ public class MainUtils { * @return */ public static List getWebIMDataAgg(List values) { - List webIMReportList = new ArrayList(); + List webIMReportList = new ArrayList<>(); if (values != null && values.size() > 0) { - for (int i = 0; i < values.size(); i++) { - Object[] value = (Object[]) values.get(i); + for (Object o : values) { + Object[] value = (Object[]) o; WebIMReport report = new WebIMReport(); if (value.length == 2) { if (value[0] == null || value[0].toString().equalsIgnoreCase("null") || StringUtils.isBlank(value[0].toString())) { @@ -522,8 +516,8 @@ public class MainUtils { WebIMReport report = new WebIMReport(); if (values != null && values.size() > 0) { - for (int i = 0; i < values.size(); i++) { - Object[] value = (Object[]) values.get(i); + for (Object o : values) { + Object[] value = (Object[]) o; if (value.length >= 2) { String invitestatus = (String) value[0]; if (MainContext.OnlineUserInviteStatus.DEFAULT.toString().equals( @@ -549,8 +543,8 @@ public class MainUtils { public static WeiXinReport getWeiXinReportResult(List values) { WeiXinReport report = new WeiXinReport(); if (values != null && values.size() > 0) { - for (int i = 0; i < values.size(); i++) { - Object[] value = (Object[]) values.get(i); + for (Object o : values) { + Object[] value = (Object[]) o; if (value.length >= 2) { String event = (String) value[0]; if (MainContext.WeiXinEventType.SUB.toString().equals(event)) { @@ -569,7 +563,7 @@ public class MainUtils { if (obj == null) { return null; } - Map map = new HashMap(); + Map map = new HashMap<>(); try { BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass()); PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors(); @@ -600,31 +594,26 @@ public class MainUtils { } public static void populate(Object bean, Map properties) throws IllegalAccessException, InvocationTargetException { - ConvertUtils.register(new Converter() { - @SuppressWarnings("rawtypes") - @Override - public Object convert(Class arg0, Object arg1) { - if (arg1 == null) { - return null; - } - if (arg1 instanceof Date) { - return arg1; - } else if (!(arg1 instanceof String)) { - throw new ConversionException("只支持字符串转换 !"); - } - String str = (String) arg1; - if (str.trim().equals("")) { - return null; - } + ConvertUtils.register((arg0, arg1) -> { + if (arg1 == null) { + return null; + } + if (arg1 instanceof Date) { + return arg1; + } else if (!(arg1 instanceof String)) { + throw new ConversionException("只支持字符串转换 !"); + } + String str = (String) arg1; + if (str.trim().equals("")) { + return null; + } - SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - - try { - return sd.parse(str); - } catch (Exception e) { - throw new RuntimeException(e); - } + SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + try { + return sd.parse(str); + } catch (Exception e) { + throw new RuntimeException(e); } }, java.util.Date.class); @@ -648,6 +637,12 @@ public class MainUtils { public static Object toObject(byte[] data) throws Exception { ByteArrayInputStream input = new ByteArrayInputStream(data); ObjectInputStream objectInput = new ObjectInputStream(input); + + // https://github.com/cskefu/cskefu/issues/177 + // https://www.davidvlijmincx.com/posts/creating_context_specific_deserialization_filters/ + ObjectInputFilter filter = ObjectInputFilter.Config.createFilter("java.util.List;com.cskefu.cc.model;!*"); + objectInput.setObjectInputFilter(filter); + return objectInput.readObject(); } @@ -715,7 +710,7 @@ public class MainUtils { Elements pngs = document.select("img[src]"); for (Element element : pngs) { String imgUrl = element.attr("src"); - if (imgUrl.indexOf("/res/image") >= 0) { + if (imgUrl.contains("/res/image")) { element.attr("class", "ukefu-media-image"); } } @@ -752,24 +747,21 @@ public class MainUtils { return workintTime; } - public static File processImage(final File destFile, final File imageFile) throws IOException { + public static void processImage(final File destFile, final File imageFile) throws IOException { if (imageFile != null && imageFile.exists()) { Thumbnails.of(imageFile).imageType(BufferedImage.TYPE_INT_ARGB).width(460).keepAspectRatio(true).toFile(destFile); } - return destFile; } - public static File scaleImage(final File destFile, final File imageFile, float quality) throws IOException { + public static void scaleImage(final File destFile, final File imageFile, float quality) throws IOException { if (imageFile != null && imageFile.exists()) { Thumbnails.of(imageFile).scale(1f).outputQuality(quality).toFile(destFile); } - return destFile; } public static String processEmoti(String message) { Pattern pattern = Pattern.compile("\\[([\\d]*?)\\]"); - SystemConfig systemConfig = MainContext.getCache().findOneSystemByIdAndOrgi( - "systemConfig", Constants.SYSTEM_ORGI); + SystemConfig systemConfig = MainContext.getCache().findOneSystemById("systemConfig"); Matcher matcher = pattern.matcher(message); StringBuffer strb = new StringBuffer(); @@ -819,12 +811,12 @@ public class MainUtils { return ip; } - public static boolean secConfirm(SecretRepository secRes, String orgi, String confirm) { + public static boolean secConfirm(SecretRepository secRes, String confirm) { /** * 先调用 IMServer */ boolean execute = false; - List secretConfig = secRes.findByOrgi(orgi); + List secretConfig = secRes.findAll(); if (StringUtils.isNotBlank(confirm)) { if (secretConfig != null && secretConfig.size() > 0) { Secret secret = secretConfig.get(0); @@ -844,11 +836,13 @@ public class MainUtils { * @return */ public static SystemConfig getSystemConfig() { - SystemConfig systemConfig = MainContext.getCache().findOneSystemByIdAndOrgi( - "systemConfig", Constants.SYSTEM_ORGI); + SystemConfig systemConfig = MainContext.getCache().findOneSystemById("systemConfig"); if (systemConfig == null) { SystemConfigRepository systemConfigRes = MainContext.getContext().getBean(SystemConfigRepository.class); - systemConfig = systemConfigRes.findByOrgi(Constants.SYSTEM_ORGI); + List systemConfigs = systemConfigRes.findAll(); + if (systemConfigs.size() > 0) { + systemConfig = systemConfigs.get(0); + } } return systemConfig; } @@ -861,8 +855,7 @@ public class MainUtils { public static void initSystemSecField(TablePropertiesRepository tpRes) { if (tpRes != null) { List tpList = tpRes.findBySecfield(true); - MainContext.getCache().putSystemListByIdAndOrgi( - Constants.CSKEFU_SYSTEM_SECFIELD, Constants.SYSTEM_ORGI, tpList); + MainContext.getCache().putSystemListById(Constants.CSKEFU_SYSTEM_SECFIELD, tpList); } } @@ -872,10 +865,10 @@ public class MainUtils { * @return */ public static void initSystemArea() { - MainContext.getCache().deleteSystembyIdAndOrgi(Constants.CSKEFU_SYSTEM_AREA, Constants.SYSTEM_ORGI); + MainContext.getCache().deleteSystembyId(Constants.CSKEFU_SYSTEM_AREA); AreaTypeRepository areaTypeRes = MainContext.getContext().getBean(AreaTypeRepository.class); - MainContext.getCache().putSystemListByIdAndOrgi( - Constants.CSKEFU_SYSTEM_AREA, Constants.SYSTEM_ORGI, areaTypeRes.findAll()); + MainContext.getCache().putSystemListById( + Constants.CSKEFU_SYSTEM_AREA, areaTypeRes.findAll()); } /** @@ -883,19 +876,19 @@ public class MainUtils { * * @return */ - public static void initAdv(String orgi, String skill) { - MainContext.getCache().deleteSystembyIdAndOrgi(Constants.CSKEFU_SYSTEM_ADV + "_" + skill, orgi); + public static void initAdv(String skill) { + MainContext.getCache().deleteSystembyId(Constants.CSKEFU_SYSTEM_ADV + "_" + skill); AdTypeRepository adRes = MainContext.getContext().getBean(AdTypeRepository.class); - MainContext.getCache().putSystemListByIdAndOrgi( - Constants.CSKEFU_SYSTEM_ADV + "_" + skill, orgi, adRes.findByOrgiAndSkill(orgi, skill)); + MainContext.getCache().putSystemListById( + Constants.CSKEFU_SYSTEM_ADV + "_" + skill, adRes.findBySkill(skill)); } public static Template getTemplate(String id) { Template templet = null; - if ((templet = MainContext.getCache().findOneSystemByIdAndOrgi(id, Constants.SYSTEM_ORGI)) == null) { + if ((templet = MainContext.getCache().findOneSystemById(id)) == null) { TemplateRepository templateRes = MainContext.getContext().getBean(TemplateRepository.class); - templet = templateRes.findByIdAndOrgi(id, Constants.SYSTEM_ORGI); - MainContext.getCache().putSystemByIdAndOrgi(id, Constants.SYSTEM_ORGI, templet); + templet = templateRes.findById(id).orElse(null); + MainContext.getCache().putSystemById(id, templet); } return templet; } @@ -905,18 +898,17 @@ public class MainUtils { * * @param adpos * @param skill - * @param orgi * @return */ - public static List getPointAdvs(String adpos, String skill, String orgi) { - List adTypeList = new ArrayList(); - List cacheAdTypeList = MainContext.getCache().findOneSystemListByIdAndOrgi( - Constants.CSKEFU_SYSTEM_ADV + "_" + skill, orgi); + public static List getPointAdvs(String adpos, String skill) { + List adTypeList = new ArrayList<>(); + List cacheAdTypeList = MainContext.getCache().findOneSystemListById( + Constants.CSKEFU_SYSTEM_ADV + "_" + skill); if (cacheAdTypeList == null) { AdTypeRepository adRes = MainContext.getContext().getBean(AdTypeRepository.class); - cacheAdTypeList = adRes.findByOrgiAndSkill(orgi, skill); - MainContext.getCache().putSystemListByIdAndOrgi( - Constants.CSKEFU_SYSTEM_ADV + "_" + skill, orgi, cacheAdTypeList); + cacheAdTypeList = adRes.findBySkill(skill); + MainContext.getCache().putSystemListById( + Constants.CSKEFU_SYSTEM_ADV + "_" + skill, cacheAdTypeList); } List sysDicList = Dict.getInstance().getDic(Constants.CSKEFU_SYSTEM_ADPOS_DIC); SysDic sysDic = null; @@ -945,12 +937,12 @@ public class MainUtils { * @return */ @SuppressWarnings("unchecked") - public static AdType getPointAdv(String adpos, String skill, String orgi) { - List ads = getPointAdvs(adpos, skill, orgi); + public static AdType getPointAdv(String adpos, String skill) { + List ads = getPointAdvs(adpos, skill); return weitht(ads); } - private static Random random = new Random(); + private static final Random random = new Random(); /** * 按照权重,获取广告内容 @@ -1034,7 +1026,7 @@ public class MainUtils { SystemConfig config = MainUtils.getSystemConfig(); if (config != null && config.isEnablemail() && config.getEmailid() != null) { SystemMessage systemMessage = MainContext.getContext().getBean( - SystemMessageRepository.class).findByIdAndOrgi(config.getEmailid(), config.getOrgi()); + SystemMessageRepository.class).findById(config.getEmailid()).orElse(null); MailSender sender = new MailSender( systemMessage.getSmtpserver(), systemMessage.getMailfrom(), systemMessage.getSmtpuser(), decryption(systemMessage.getSmtppassword()), systemMessage.getSeclev(), systemMessage.getSslport()); @@ -1111,7 +1103,7 @@ public class MainUtils { * @return */ public static Object getDaysParam(String text) { - Map context = new HashMap(); + Map context = new HashMap<>(); context.put("T", processDays()); context.put("t", processDays()); context.put("M", processMonth()); @@ -1238,7 +1230,7 @@ public class MainUtils { SystemConfig config = MainUtils.getSystemConfig(); if (config != null) { SystemMessage systemMessage = MainContext.getContext().getBean( - SystemMessageRepository.class).findByIdAndOrgi(id, config.getOrgi()); + SystemMessageRepository.class).findById(id).orElse(null); if (systemMessage == null) { return false; } @@ -1302,12 +1294,11 @@ public class MainUtils { * @param userid * @param client * @param session - * @param orgi * @param ipaddr * @param hostname * @return */ - public static WorkSession createWorkSession(String userid, String client, String session, String orgi, String ipaddr, String hostname, String admin, boolean first) { + public static WorkSession createWorkSession(String userid, String client, String session, String ipaddr, String hostname, String admin, boolean first) { WorkSession workSession = new WorkSession(); workSession.setCreatetime(new Date()); workSession.setBegintime(new Date()); @@ -1325,7 +1316,6 @@ public class MainUtils { workSession.setUserid(userid); workSession.setClientid(client); workSession.setSessionid(session); - workSession.setOrgi(orgi); workSession.setDatestr(MainUtils.simpleDateFormat.format(new Date())); diff --git a/contact-center/app/src/main/java/com/cskefu/cc/basic/TerminateBean.java b/contact-center/app/src/main/java/com/cskefu/cc/basic/TerminateBean.java index 530e66f0..e2b93c96 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/basic/TerminateBean.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/basic/TerminateBean.java @@ -1,22 +1,20 @@ -/* - * Copyright (C) 2022 Chatopera Inc, All rights reserved. - * - * This software and related documentation are provided under a license agreement containing - * restrictions on use and disclosure and are protected by intellectual property laws. - * Except as expressly permitted in your license agreement or allowed by law, you may not use, - * copy, reproduce, translate, broadcast, modify, license, transmit, distribute, exhibit, perform, - * publish, or display any part, in any form, or by any means. Reverse engineering, disassembly, - * or decompilation of this software, unless required by law for interoperability, is prohibited. +/** + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * Copyright Jun. 2023 Chatopera Inc. . All rights reserved. */ package com.cskefu.cc.basic; -import javax.annotation.PreDestroy; - -import com.chatopera.cc.BlessingAndUnblessing; +import jakarta.annotation.PreDestroy; public class TerminateBean { - @PreDestroy - public void onDestroy() throws Exception { - BlessingAndUnblessing.print(); - } + @PreDestroy + public void onDestroy() throws Exception { + } } diff --git a/contact-center/app/src/main/java/com/cskefu/cc/basic/Viewport.java b/contact-center/app/src/main/java/com/cskefu/cc/basic/Viewport.java index 8e9233e7..446d15d4 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/basic/Viewport.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/basic/Viewport.java @@ -1,18 +1,16 @@ /* - * Copyright (C) 2017 优客服-多渠道客服系统 - * Modifications copyright (C) 2018-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2018- Jun. 2023 Chatopera Inc, , Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (C) 2017 优客服-多渠道客服系统, Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.basic; diff --git a/contact-center/app/src/main/java/com/cskefu/cc/basic/auth/AuthRedisTemplate.java b/contact-center/app/src/main/java/com/cskefu/cc/basic/auth/AuthRedisTemplate.java index 4268ccc0..ed6171da 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/basic/auth/AuthRedisTemplate.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/basic/auth/AuthRedisTemplate.java @@ -1,17 +1,15 @@ -/* - * Copyright (C) 2019-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * +/* + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2019-2022 Chatopera Inc, , + * Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.basic.auth; diff --git a/contact-center/app/src/main/java/com/cskefu/cc/basic/auth/BasicTokenMgr.java b/contact-center/app/src/main/java/com/cskefu/cc/basic/auth/BasicTokenMgr.java new file mode 100644 index 00000000..613ce08d --- /dev/null +++ b/contact-center/app/src/main/java/com/cskefu/cc/basic/auth/BasicTokenMgr.java @@ -0,0 +1,32 @@ +/** + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * Copyright Jun. 2023 Chatopera Inc. . All rights reserved. + */ +package com.cskefu.cc.basic.auth; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +@Component +public class BasicTokenMgr { + final static Logger logger = LoggerFactory.getLogger(BasicTokenMgr.class); + + /** + * Generate basic token with username and password + * + * @param username + * @param password + * @return + */ + public String generate(final String username, final String password) { + return null; + } +} diff --git a/contact-center/app/src/main/java/com/cskefu/cc/basic/auth/AuthToken.java b/contact-center/app/src/main/java/com/cskefu/cc/basic/auth/BearerTokenMgr.java similarity index 59% rename from contact-center/app/src/main/java/com/cskefu/cc/basic/auth/AuthToken.java rename to contact-center/app/src/main/java/com/cskefu/cc/basic/auth/BearerTokenMgr.java index 76eba2dc..2c36e0d3 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/basic/auth/AuthToken.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/basic/auth/BearerTokenMgr.java @@ -1,24 +1,23 @@ -/* - * Copyright (C) 2019-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * +/* + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2019-2022 Chatopera Inc, , + * Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.basic.auth; +import com.cskefu.cc.basic.Constants; import com.cskefu.cc.cache.RedisKey; import com.cskefu.cc.model.User; import com.cskefu.cc.util.SerializeUtil; -import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -26,16 +25,16 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.data.redis.core.ValueOperations; import org.springframework.stereotype.Component; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; import java.util.concurrent.TimeUnit; /** * 认证和授权的API Token管理 */ @Component -public class AuthToken { +public class BearerTokenMgr { - private final static Logger logger = LoggerFactory.getLogger(AuthToken.class); + private final static Logger logger = LoggerFactory.getLogger(BearerTokenMgr.class); @Value("${server.session-timeout}") private int timeout; @@ -50,6 +49,19 @@ public class AuthToken { redisValOps = authRedisTemplate.opsForValue(); } + /** + * Remove token with Bearer prefix + * + * @param token + * @return + */ + private String trimToken(final String token) { + if (token.startsWith(Constants.AUTH_TOKEN_TYPE_BEARER)) { + return StringUtils.substring(token, 7); + } + return token; + } + /** * 设置一个KEY的过期时间 * @@ -60,9 +72,8 @@ public class AuthToken { authRedisTemplate.expire(key, seconds, TimeUnit.SECONDS); } - - private String authKey(final String auth) { - return RedisKey.getLoginUserKey(auth); + private String resolveTokenKey(final String token) { + return RedisKey.getApiTokenBearerKeyWithValue(trimToken(token)); } /********************************** @@ -71,13 +82,13 @@ public class AuthToken { **********************************/ /** - * @param auth 授权的KEY - * @param loginUser 已经登录的用户 + * @param token 授权的KEY + * @param user 已经登录的用户 */ - public void putUserByAuth(final String auth, final User loginUser) { - if (StringUtils.isNotBlank(auth) && loginUser != null) { - String serialized = SerializeUtil.serialize(loginUser); - final String key = authKey(auth); + public void update(final String token, final User user) { + if (StringUtils.isNotBlank(token) && user != null) { + String serialized = SerializeUtil.serialize(user); + final String key = resolveTokenKey(token); redisValOps.set(key, serialized); expire(key, timeout); } else { @@ -89,21 +100,21 @@ public class AuthToken { /** * 判断一个Auth是否是有效的 * - * @param auth + * @param token * @return */ - public boolean existUserByAuth(final String auth) { - return authRedisTemplate.hasKey(authKey(auth)); + public boolean existToken(final String token) { + return authRedisTemplate.hasKey(resolveTokenKey(token)); } /** * 根据租户ID和认证Auth获得一个登录用户 * - * @param auth + * @param token * @return */ - public User findUserByAuth(final String auth) { - String serialized = redisValOps.get(authKey(auth)); + public User retrieve(final String token) { + String serialized = redisValOps.get(resolveTokenKey(token)); if (StringUtils.isNotBlank(serialized)) { return (User) SerializeUtil.deserialize(serialized); } @@ -113,9 +124,9 @@ public class AuthToken { /** * 登出已经登录的系统用户 * - * @param auth + * @param token */ - public void deleteUserByAuth(final String auth) { - authRedisTemplate.delete(authKey(auth)); + public void delete(final String token) { + authRedisTemplate.delete(resolveTokenKey(token)); } } diff --git a/contact-center/app/src/main/java/com/cskefu/cc/basic/plugins/AbstractPluginConfigurer.java b/contact-center/app/src/main/java/com/cskefu/cc/basic/plugins/AbstractPluginConfigurer.java index 5130570e..6378e513 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/basic/plugins/AbstractPluginConfigurer.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/basic/plugins/AbstractPluginConfigurer.java @@ -1,3 +1,13 @@ +/* + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.cskefu.cc.basic.plugins; import java.util.HashMap; diff --git a/contact-center/app/src/main/java/com/cskefu/cc/basic/plugins/IPluginConfigurer.java b/contact-center/app/src/main/java/com/cskefu/cc/basic/plugins/IPluginConfigurer.java index 74a07539..226b7469 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/basic/plugins/IPluginConfigurer.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/basic/plugins/IPluginConfigurer.java @@ -1,17 +1,15 @@ -/* - * Copyright (C) 2019-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * +/* + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2019-2022 Chatopera Inc, , + * Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.basic.plugins; diff --git a/contact-center/app/src/main/java/com/cskefu/cc/basic/plugins/PluginRegistry.java b/contact-center/app/src/main/java/com/cskefu/cc/basic/plugins/PluginRegistry.java index 950b0b42..91f0ddd6 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/basic/plugins/PluginRegistry.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/basic/plugins/PluginRegistry.java @@ -1,22 +1,20 @@ -/* - * Copyright (C) 2019-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * +/* + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2019-2022 Chatopera Inc, , + * Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.basic.plugins; import com.cskefu.cc.basic.MainContext; -import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Component; import java.util.ArrayList; @@ -42,12 +40,11 @@ public class PluginRegistry { * 添加插件 * * @param plugin - * @return */ - public boolean addPlugin(final IPluginConfigurer plugin) { + public void addPlugin(final IPluginConfigurer plugin) { for (final IPluginConfigurer x : plugins) { if (StringUtils.equalsIgnoreCase(x.getPluginId(), plugin.getPluginId())) { - return false; + return; } } @@ -56,7 +53,6 @@ public class PluginRegistry { } plugins.add(plugin); - return true; } /** diff --git a/contact-center/app/src/main/java/com/cskefu/cc/basic/resource/ActivityResource.java b/contact-center/app/src/main/java/com/cskefu/cc/basic/resource/ActivityResource.java deleted file mode 100644 index b19fbbd5..00000000 --- a/contact-center/app/src/main/java/com/cskefu/cc/basic/resource/ActivityResource.java +++ /dev/null @@ -1,380 +0,0 @@ -/* - * Copyright (C) 2017 优客服-多渠道客服系统 - * Modifications copyright (C) 2018-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.cskefu.cc.basic.resource; - -import com.cskefu.cc.basic.Constants; -import com.cskefu.cc.basic.MainContext; -import com.cskefu.cc.basic.MainUtils; -import com.cskefu.cc.model.*; -import com.cskefu.cc.persistence.impl.BatchDataProcess; -import com.cskefu.cc.persistence.impl.ESDataExchangeImpl; -import com.cskefu.cc.persistence.repository.*; -import com.cskefu.cc.util.es.SearchTools; -import com.cskefu.cc.util.es.UKDataBean; -import org.apache.commons.lang3.StringUtils; -import org.springframework.data.domain.PageImpl; - -import java.util.Date; -import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; - -public class ActivityResource extends Resource{ - - private JobDetail jobDetail ; - private FormFilterRepository formFilterRes ; - private FormFilterItemRepository formFilterItemRes ; - private PageImpl dataList ; - private MetadataTable metadataTable ; - private FormFilter formFilter = null ; - private List callAgentList ; - - - private CallAgent current ; - - private UKefuCallOutTask task ; - private UKefuCallOutFilter filter ; - - private UKefuCallOutTaskRepository callOutTaskRes ; - - private UKefuCallOutFilterRepository callOutFilterRes ; - - private JobDetailRepository batchRes; - - private MetadataRepository metadataRes ; - - private JobDetail batch ; - - private AtomicInteger assignorganInt = new AtomicInteger() /***分配到坐席***/, assignInt = new AtomicInteger() /***分配到部门***/ , assignAiInt = new AtomicInteger() /***分配到AI***/ ,atomInt = new AtomicInteger() ; - - private BatchDataProcess batchDataProcess ; - - public ActivityResource(JobDetail jobDetail) { - this.jobDetail = jobDetail ; - this.formFilterRes = MainContext.getContext().getBean(FormFilterRepository.class) ; - this.formFilterItemRes = MainContext.getContext().getBean(FormFilterItemRepository.class) ; - this.callOutTaskRes = MainContext.getContext().getBean(UKefuCallOutTaskRepository.class); - this.callOutFilterRes = MainContext.getContext().getBean(UKefuCallOutFilterRepository.class); - this.batchRes = MainContext.getContext().getBean(JobDetailRepository.class); - this.metadataRes = MainContext.getContext().getBean(MetadataRepository.class); - this.batchDataProcess = new BatchDataProcess(null , MainContext.getContext().getBean(ESDataExchangeImpl.class)) ; - } - - @Override - public void begin() throws Exception { - if(!StringUtils.isBlank(jobDetail.getFilterid())) { - formFilter = formFilterRes.findByIdAndOrgi(jobDetail.getFilterid(), this.jobDetail.getOrgi()) ; - List formFilterList = formFilterItemRes.findByOrgiAndFormfilterid(this.jobDetail.getOrgi(), jobDetail.getFilterid()) ; - if(formFilter!=null && !StringUtils.isBlank(formFilter.getFiltertype())) { - if(formFilter.getFiltertype().equals(MainContext.FormFilterType.BATCH.toString())) { - batch = batchRes.findByIdAndOrgi(formFilter.getBatid(), this.jobDetail.getOrgi()) ; - if(batch!=null && !StringUtils.isBlank(batch.getActid())) { - metadataTable = metadataRes.findByTablename(batch.getActid()) ; - } - }else { //业务表 - if(!StringUtils.isBlank(formFilter.getTableid())) { - metadataTable = metadataRes.findById(formFilter.getTableid()) ; - } - } - } - if(metadataTable!=null) { - /** - * 只加载 未分配的有效名单数据 - */ - if(isRecovery()) { - //回收数据 , 需要传入回收的目标 : 包括 批次ID,任务ID,筛选ID,活动ID - dataList = SearchTools.recoversearch(this.jobDetail.getOrgi(), this.jobDetail.getExectype(), this.jobDetail.getExectarget() , metadataTable ,(int) Math.ceil(this.jobDetail.getStartindex()/50000), 50000) ; - }else { - dataList = SearchTools.dissearch(this.jobDetail.getOrgi(), formFilter, formFilterList , metadataTable ,(int) Math.ceil(this.jobDetail.getStartindex()/50000), 50000) ; - } - } - this.callAgentList = MainContext.getContext().getBean(CallAgentRepository.class).findByActidAndOrgi(this.jobDetail.getId() , this.jobDetail.getOrgi()) ; - /** - * 生成 活动任务, 然后完成分配 , 同时还需要生成 筛选表单的筛选记录 , 在后台管理界面上可以看到 - */ - if(this.callAgentList!=null && this.callAgentList.size() > 0) { - this.current = this.callAgentList.remove(0) ; - } - - this.jobDetail.setExecnum(this.jobDetail.getExecnum() + 1); - - if(this.isRecovery() && !StringUtils.isBlank(this.jobDetail.getExectype()) && (this.jobDetail.getExectype().equals("filterid") || this.jobDetail.getExectype().equals("filterskill") || this.jobDetail.getExectype().equals("taskskill") || this.jobDetail.getExectype().equals("taskid"))) { - if(this.jobDetail.getExectype().equals("filterid") || this.jobDetail.getExectype().equals("filterskill")) { - this.filter = this.callOutFilterRes.findByIdAndOrgi(this.jobDetail.getExectarget(), this.jobDetail.getOrgi()) ; - }else if(this.jobDetail.getExectype().equals("taskid") || this.jobDetail.getExectype().equals("taskskill") ) { - this.task = this.callOutTaskRes.findByIdAndOrgi(this.jobDetail.getExectarget(), this.jobDetail.getOrgi()) ; - } - }else { - task = new UKefuCallOutTask() ; - task.setName(this.jobDetail.getName() + "_" + MainUtils.dateFormate.format(new Date())); - task.setBatid(formFilter.getBatid()); - - task.setOrgi(this.jobDetail.getOrgi()); - - if(this.isRecovery()) { - task.setExectype(MainContext.ActivityExecType.RECOVERY.toString()); - }else { - task.setExectype(MainContext.ActivityExecType.DEFAULT.toString()); - } - - task.setFilterid(formFilter.getId()); - task.setActid(this.jobDetail.getId()); - - task.setExecnum(this.jobDetail.getExecnum()); - - task.setOrgan(this.jobDetail.getOrgan()); - - task.setCreatetime(new Date()); - if(this.dataList!=null) { - task.setNamenum((int) this.dataList.getTotalElements()); - task.setNotassigned((int) this.dataList.getTotalElements()); - } - - this.callOutTaskRes.save(task) ; - - filter = new UKefuCallOutFilter() ; - - formFilter.setExecnum(formFilter.getExecnum() + 1); - - MainUtils.copyProperties(task, filter); - filter.setName(this.formFilter.getName() + "_" + MainUtils.dateFormate.format(new Date())); - filter.setExecnum(formFilter.getExecnum()); - this.callOutFilterRes.save(filter) ; - } - } - } - - @Override - public void end(boolean clear) throws Exception { - if(this.atomInt.intValue() > 0) { - this.batchDataProcess.end(); - } - //doNothing - /** - * FormFilter的执行信息更新,执行次数 - */ - if(formFilterRes!=null && this.formFilter != null) { - this.formFilter.setFilternum(this.formFilter.getFilternum()+1); - formFilterRes.save(this.formFilter) ; - } - /** - * 批次的信息更新,批次剩余未分配的名单总数 , 已分配的名单总数 - */ - if(this.batchRes!=null && this.batch != null) { - if(this.isRecovery()) { - batch.setAssigned(batch.getAssigned() - this.atomInt.intValue()); - }else { - batch.setAssigned(batch.getAssigned() + this.atomInt.intValue()); - } - batch.setNotassigned(batch.getNamenum() - batch.getAssigned()); - this.batchRes.save(batch) ; - } - if(this.task!=null) { - if(this.isRecovery()) { - if(!StringUtils.isBlank(this.jobDetail.getExecto())) { - this.task.setReorgannum(this.atomInt.intValue()); - }else { - this.task.setRenum(this.atomInt.intValue()); - } - }else { - this.task.setAssigned(this.assignInt.intValue()); - this.task.setAssignedorgan(this.assignorganInt.intValue()); - this.task.setAssignedai(this.assignAiInt.intValue()); - this.task.setNotassigned(this.task.getNamenum() - this.assignInt.intValue() - this.assignorganInt.intValue() - this.assignAiInt.intValue()); - } - this.callOutTaskRes.save(this.task) ; - } - if(this.filter!=null) { - if(this.isRecovery()) { - if(!StringUtils.isBlank(this.jobDetail.getExecto())) { - this.filter.setReorgannum(this.atomInt.intValue()); - }else { - this.filter.setRenum(this.atomInt.intValue()); - } - }else { - this.filter.setAssigned(this.assignInt.intValue()); - this.filter.setAssignedorgan(this.assignorganInt.intValue()); - this.filter.setAssignedai(this.assignAiInt.intValue()); - this.filter.setNotassigned(this.task.getNamenum() - this.assignInt.intValue() - this.assignorganInt.intValue() - this.assignAiInt.intValue()); - } - this.callOutFilterRes.save(this.filter) ; - } - - /** - * 更新任务状态,记录生成的任务信息 - */ - this.jobDetail.setExecmd(null); - this.jobDetail.setExectype(null); - this.jobDetail.setExectarget(null); - this.jobDetail.setExecto(null); - } - - @Override - public JobDetail getJob() { - return this.jobDetail; - } - - @Override - public void process(OutputTextFormat meta, JobDetail job) throws Exception { - /** - * 执行分配 - */ - if(this.isRecovery()) { - if(!StringUtils.isBlank(this.jobDetail.getExecto())) { - meta.getDataBean().getValues().put(Constants.CSKEFU_SYSTEM_DIS_AGENT, null) ; - meta.getDataBean().getValues().put(Constants.CSKEFU_SYSTEM_DIS_AI, null) ; -// meta.getDataBean().getValues().put(Constants.CSKEFU_SYSTEM_DIS_ORGAN, this.jobDetail.getExecto()) ; - meta.getDataBean().getValues().put(Constants.CSKEFU_SYSTEM_DIS_TIME, System.currentTimeMillis()) ; - meta.getDataBean().getValues().put("status", MainContext.NamesDisStatusType.DISORGAN.toString()) ; - }else { - meta.getDataBean().getValues().put(Constants.CSKEFU_SYSTEM_DIS_AI, null) ; - meta.getDataBean().getValues().put(Constants.CSKEFU_SYSTEM_DIS_AGENT, null) ; - meta.getDataBean().getValues().put(Constants.CSKEFU_SYSTEM_DIS_ORGAN, null) ; - meta.getDataBean().getValues().put(Constants.CSKEFU_SYSTEM_DIS_TIME, null) ; - meta.getDataBean().getValues().put("status", MainContext.NamesDisStatusType.NOT.toString()) ; - } - }else { - if(this.current!=null && meta!=null && meta.getDataBean()!=null) { - this.current.getDisnames().incrementAndGet() ; - /** - * - */ - meta.getDataBean().getValues().put(Constants.CSKEFU_SYSTEM_DIS_TIME, System.currentTimeMillis()) ; - - meta.getDataBean().getValues().put("actid", this.jobDetail.getId()) ; - meta.getDataBean().getValues().put("metaid", this.metadataTable.getTablename()) ; - meta.getDataBean().getValues().put("batid", this.formFilter.getBatid()) ; - - meta.getDataBean().getValues().put("taskid", this.task.getId()) ; - meta.getDataBean().getValues().put("filterid", this.formFilter.getId()) ; - meta.getDataBean().getValues().put("calloutfilid", this.filter.getId()) ; - - meta.getDataBean().getValues().put("taskid", this.task.getId()) ; - - - if(!StringUtils.isBlank(this.jobDetail.getUserid())){ - meta.getDataBean().getValues().put("assuser", this.jobDetail.getUserid()) ; - }else{ - meta.getDataBean().getValues().put("assuser", this.jobDetail.getCreater()) ; - } - /** - * 任务ID - */ - - if("agent".equals(this.current.getDistype())) { - meta.getDataBean().getValues().put("status", MainContext.NamesDisStatusType.DISAGENT.toString()) ; - meta.getDataBean().getValues().put(Constants.CSKEFU_SYSTEM_DIS_AGENT, this.current.getDistarget()) ; - meta.getDataBean().getValues().put(Constants.CSKEFU_SYSTEM_DIS_ORGAN, this.current.getOrgan()) ; - this.assignInt.incrementAndGet() ; - }else if("skill".equals(this.current.getDistype())) { - meta.getDataBean().getValues().put("status", MainContext.NamesDisStatusType.DISORGAN.toString()) ; - meta.getDataBean().getValues().put(Constants.CSKEFU_SYSTEM_DIS_ORGAN, this.current.getDistarget()) ; - this.assignorganInt.incrementAndGet() ; - }else if("ai".equals(this.current.getDistype())) { - meta.getDataBean().getValues().put("status", MainContext.NamesDisStatusType.DISAI.toString()) ; - meta.getDataBean().getValues().put(Constants.CSKEFU_SYSTEM_DIS_AI, this.current.getDistarget()) ; - meta.getDataBean().getValues().put(Constants.CSKEFU_SYSTEM_DIS_ORGAN, this.current.getOrgan()) ; - this.assignAiInt.incrementAndGet() ; - } - } - } - meta.getDataBean().getValues().put("updatetime", System.currentTimeMillis()) ; - - /** - * 更新记录(是否同时保存分配信息,以便于查看分配历史?) - */ - batchDataProcess.process(meta.getDataBean()); - } - - @Override - public OutputTextFormat next() throws Exception { - OutputTextFormat outputTextFormat = null; - if(this.dataList!=null && this.current!=null) { - synchronized (this.dataList) { - if(atomInt.intValue() < this.dataList.getContent().size()) { - if(this.isRecovery()) { - UKDataBean dataBean = this.dataList.getContent().get(atomInt.intValue()) ; - outputTextFormat = new OutputTextFormat(this.jobDetail); - if(this.formFilter!=null) { - outputTextFormat.setTitle(this.formFilter.getName()); - } - outputTextFormat.setDataBean(dataBean); - atomInt.incrementAndGet() ; - }else if(this.dataList!=null) { - if(this.current.getDisnames().intValue() >= this.current.getDisnum() ) { - if(this.callAgentList.size() > 0) { - this.current = this.callAgentList.remove(0) ; - }else { - this.current = null ; - } - } - if(this.current != null) { - UKDataBean dataBean = this.dataList.getContent().get(atomInt.intValue()) ; - outputTextFormat = new OutputTextFormat(this.jobDetail); - if(this.formFilter!=null) { - outputTextFormat.setTitle(this.formFilter.getName()); - } - outputTextFormat.setDataBean(dataBean); - - atomInt.incrementAndGet() ; - - /** - * 修改为平均分配的方式 , 每个坐席或者部门评价分配 - */ - this.callAgentList.add(this.current) ; - if(this.callAgentList.size() > 0) { - this.current = this.callAgentList.remove(0) ; - } - } - } - } - } - } - return outputTextFormat; - } - - @Override - public boolean isAvailable() { - return true; - } - - @Override - public OutputTextFormat getText(OutputTextFormat object) throws Exception { - return object; - } - - @Override - public void rmResource() { - /** - * 啥也不做 - */ - } - - @Override - public void updateTask() throws Exception { - /** - * 更新任务状态,记录生成的任务信息 - */ - this.jobDetail.setExecmd(null); - this.jobDetail.setExectype(null); - this.jobDetail.setExectarget(null); - this.jobDetail.setExecto(null); - } - - private boolean isRecovery() { - return StringUtils.isNotBlank(this.jobDetail.getExecmd()) && this.jobDetail.getExecmd().equals("recovery") ; - } -} diff --git a/contact-center/app/src/main/java/com/cskefu/cc/basic/resource/BatchResource.java b/contact-center/app/src/main/java/com/cskefu/cc/basic/resource/BatchResource.java deleted file mode 100644 index b618f149..00000000 --- a/contact-center/app/src/main/java/com/cskefu/cc/basic/resource/BatchResource.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright (C) 2017 优客服-多渠道客服系统 - * Modifications copyright (C) 2018-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.cskefu.cc.basic.resource; - -import com.cskefu.cc.basic.MainContext; -import com.cskefu.cc.basic.MainUtils; -import com.cskefu.cc.model.JobDetail; -import com.cskefu.cc.model.MetadataTable; -import com.cskefu.cc.persistence.impl.BatchDataProcess; -import com.cskefu.cc.persistence.impl.ESDataExchangeImpl; -import com.cskefu.cc.persistence.repository.MetadataRepository; -import com.cskefu.cc.persistence.repository.ReporterRepository; -import com.cskefu.cc.util.dsdata.DSData; -import com.cskefu.cc.util.dsdata.DSDataEvent; -import com.cskefu.cc.util.dsdata.ExcelImportProecess; -import org.apache.commons.io.FileUtils; -import org.apache.commons.lang3.StringUtils; - -import java.io.File; -import java.net.URL; -import java.util.Date; -import java.util.HashMap; - -public class BatchResource extends Resource{ - - private JobDetail jobDetail ; - private MetadataTable metadataTable ; - private ESDataExchangeImpl esDataExchange = null ; - - private MetadataRepository metadataRes ; - - private ReporterRepository reporterRes ; - - public BatchResource(JobDetail jobDetail) { - this.jobDetail = jobDetail ; - this.metadataRes = MainContext.getContext().getBean(MetadataRepository.class); - this.reporterRes = MainContext.getContext().getBean(ReporterRepository.class); - this.esDataExchange = MainContext.getContext().getBean(ESDataExchangeImpl.class); - } - - @Override - public void begin() throws Exception { - if(!StringUtils.isBlank(jobDetail.getActid())) { - metadataTable = metadataRes.findByTablename(jobDetail.getActid()) ; - } - DSDataEvent event = new DSDataEvent(); - String path = MainContext.getContext().getEnvironment().getProperty("web.upload-path") ; - File tempFile = null ; - if(metadataTable!=null && !StringUtils.isBlank(this.jobDetail.getBatchtype()) && this.jobDetail.getBatchtype().equals("plan")) { - if(!StringUtils.isBlank(this.jobDetail.getImptype())) { - if(this.jobDetail.getImptype().equals("local")) { - tempFile = new File(MainUtils.getTemplet(this.jobDetail.getImpurl(), new HashMap())); - }else if(this.jobDetail.getImptype().equals("remote")){ - FileUtils.copyURLToFile(new URL(MainUtils.getTemplet(this.jobDetail.getImpurl(), new HashMap())), tempFile = File.createTempFile("UKeFu-CallOut-Temp", ".xls")); - } - } - if(tempFile.exists()) { - String fileName = "callout/batch/"+ MainUtils.getUUID() + tempFile.getName().substring(tempFile.getName().lastIndexOf(".")) ; - File excelFile = new File(path , fileName) ; - if(!excelFile.getParentFile().exists()){ - excelFile.getParentFile().mkdirs() ; - } - - event.setTablename(metadataTable.getTablename()); - event.setDSData(new DSData(null ,excelFile , tempFile.getName(), null)); - event.setOrgi(this.jobDetail.getOrgi()); - event.getValues().put("creater", this.jobDetail.getCreater()) ; - - FileUtils.copyFile(tempFile, new File(path , fileName)); - - event.getDSData().setTask(metadataTable); - event.getDSData().setProcess(new BatchDataProcess(metadataTable, esDataExchange)); - event.setOrgi(this.jobDetail.getOrgi()); - event.setBatid(this.jobDetail.getId()); - event.getDSData().setJobDetail(this.jobDetail); - - event.getDSData().getReport().setOrgi(this.jobDetail.getOrgi()); - event.getDSData().getReport().setDataid(this.jobDetail.getId()); - event.getDSData().getReport().setTitle(this.jobDetail.getName() + "_" + MainUtils.dateFormate.format(new Date())); - }else { - event.getDSData().getReport().setError(true); - if(tempFile!=null) { - event.getDSData().getReport().setErrormsg(tempFile.getAbsolutePath() + " Not Exist!"); - } - } - reporterRes.save(event.getDSData().getReport()) ; - new ExcelImportProecess(event).process() ; //启动导入任务 - } - } - - @Override - public void end(boolean clear) throws Exception { - - } - - @Override - public JobDetail getJob() { - return this.jobDetail; - } - - @Override - public void process(OutputTextFormat meta, JobDetail job) throws Exception { - - } - - @Override - public OutputTextFormat next() throws Exception { - return null ; - } - - @Override - public boolean isAvailable() { - return true; - } - - @Override - public OutputTextFormat getText(OutputTextFormat object) throws Exception { - return object; - } - - @Override - public void rmResource() { - /** - * 啥也不做 - */ - } - - @Override - public void updateTask() throws Exception { - - } -} diff --git a/contact-center/app/src/main/java/com/cskefu/cc/basic/resource/OutputTextFormat.java b/contact-center/app/src/main/java/com/cskefu/cc/basic/resource/OutputTextFormat.java index 49d67fe2..fd2cbe96 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/basic/resource/OutputTextFormat.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/basic/resource/OutputTextFormat.java @@ -1,18 +1,16 @@ /* - * Copyright (C) 2017 优客服-多渠道客服系统 - * Modifications copyright (C) 2018-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2018- Jun. 2023 Chatopera Inc, , Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (C) 2017 优客服-多渠道客服系统, Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.basic.resource; @@ -27,7 +25,7 @@ public class OutputTextFormat { private String title ; private String parent ; - private Map data = new HashMap(); + private Map data = new HashMap<>(); private JobDetail job ; private UKDataBean dataBean ; diff --git a/contact-center/app/src/main/java/com/cskefu/cc/basic/resource/Resource.java b/contact-center/app/src/main/java/com/cskefu/cc/basic/resource/Resource.java index cde8ff78..cc66e66e 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/basic/resource/Resource.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/basic/resource/Resource.java @@ -1,18 +1,16 @@ /* - * Copyright (C) 2017 优客服-多渠道客服系统 - * Modifications copyright (C) 2018-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2018- Jun. 2023 Chatopera Inc, , Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (C) 2017 优客服-多渠道客服系统, Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.basic.resource; @@ -20,7 +18,8 @@ import com.cskefu.cc.basic.MainContext; import com.cskefu.cc.model.JobDetail; import java.lang.reflect.InvocationTargetException; -import java.util.logging.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * @author jaddy0302 Rivulet Resource.java 2010-3-6 @@ -28,7 +27,7 @@ import java.util.logging.Logger; */ public abstract class Resource { - public static Logger log = Logger.getLogger(Resource.class.getName()) ; + public static Logger log = LoggerFactory.getLogger(Resource.class.getName()) ; public abstract void begin() throws Exception; @@ -107,7 +106,7 @@ public abstract class Resource { */ public boolean val(String inputFile , String acceptDocType){ String file = inputFile!=null ? inputFile.toLowerCase() :null ; - return file!=null && acceptDocType!=null && ((acceptDocType.indexOf(file.substring(file.lastIndexOf(".")+1))>=0||acceptDocType.indexOf("all")>=0)) ; + return file!=null && acceptDocType!=null && ((acceptDocType.contains(file.substring(file.lastIndexOf(".") + 1)) || acceptDocType.contains("all"))) ; } } diff --git a/contact-center/app/src/main/java/com/cskefu/cc/cache/Cache.java b/contact-center/app/src/main/java/com/cskefu/cc/cache/Cache.java index 28c26842..5e082b48 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/cache/Cache.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/cache/Cache.java @@ -1,17 +1,15 @@ -/* - * Copyright (C) 2019-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * +/* + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2019-2022 Chatopera Inc, , + * Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.cache; @@ -20,14 +18,14 @@ import com.cskefu.cc.basic.MainContext; import com.cskefu.cc.exception.CSKefuCacheException; import com.cskefu.cc.model.*; import com.cskefu.cc.persistence.repository.AgentUserRepository; -import com.cskefu.cc.persistence.repository.OnlineUserRepository; +import com.cskefu.cc.persistence.repository.PassportWebIMUserRepository; import com.cskefu.cc.util.SerializeUtil; import com.cskefu.cc.util.freeswitch.model.CallCenterAgent; -import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import org.apache.commons.lang3.StringUtils; import java.io.Serializable; import java.util.*; @@ -38,7 +36,7 @@ public class Cache { final static private Logger logger = LoggerFactory.getLogger(Cache.class); @Autowired - private OnlineUserRepository onlineUserRes; + private PassportWebIMUserRepository onlineUserRes; @Autowired private AgentUserRepository agentUserRes; @@ -49,37 +47,35 @@ public class Cache { /** * 获得就绪的坐席列表 * - * @param orgi 租户 * @return */ - public Map getAgentStatusReadyByOrig(final String orgi) { - Map agentStatuses = redisCommand.getHash(RedisKey.getAgentStatusReadyHashKey(orgi)); + public Map getAgentStatusReady() { + Map agentStatuses = redisCommand.getHash(RedisKey.getAgentStatusReadyHashKey()); return convertFromStringToAgentStatus(agentStatuses); } /** - * 通过访客ID和ORGI获得访客坐席关联关系 + * 通过访客ID获得访客坐席关联关系 * * @param userId - * @param orgi * @return */ - public Optional findOneAgentUserByUserIdAndOrgi(final String userId, final String orgi) { - if (redisCommand.hasHashKV(RedisKey.getAgentUserInQueHashKey(orgi), userId)) { + public Optional findOneAgentUserByUserId(final String userId) { + if (redisCommand.hasHashKV(RedisKey.getAgentUserInQueHashKey(), userId)) { // 排队等待中 return Optional.ofNullable((AgentUser) SerializeUtil.deserialize( - redisCommand.getHashKV(RedisKey.getAgentUserInQueHashKey(orgi), userId))); - } else if (redisCommand.hasHashKV(RedisKey.getAgentUserInServHashKey(orgi), userId)) { + redisCommand.getHashKV(RedisKey.getAgentUserInQueHashKey(), userId))); + } else if (redisCommand.hasHashKV(RedisKey.getAgentUserInServHashKey(), userId)) { // 服务中 return Optional.ofNullable((AgentUser) SerializeUtil.deserialize( - redisCommand.getHashKV(RedisKey.getAgentUserInServHashKey(orgi), userId))); - } else if (redisCommand.hasHashKV(RedisKey.getAgentUserEndHashKey(orgi), userId)) { + redisCommand.getHashKV(RedisKey.getAgentUserInServHashKey(), userId))); + } else if (redisCommand.hasHashKV(RedisKey.getAgentUserEndHashKey(), userId)) { // 已经结束 return Optional.ofNullable((AgentUser) SerializeUtil.deserialize( - redisCommand.getHashKV(RedisKey.getAgentUserEndHashKey(orgi), userId))); + redisCommand.getHashKV(RedisKey.getAgentUserEndHashKey(), userId))); } else { // 缓存中没有找到,继续到数据库查找 - return agentUserRes.findOneByUseridAndOrgi(userId, orgi); + return agentUserRes.findOneByUserid(userId); } } @@ -87,11 +83,10 @@ public class Cache { /** * 返回排队中的客服列表 * - * @param orgi * @return */ - public Map getAgentUsersInQueByOrgi(final String orgi) { - Map agentUsers = redisCommand.getHash(RedisKey.getAgentUserInQueHashKey(orgi)); + public Map getAgentUsersInQue() { + Map agentUsers = redisCommand.getHash(RedisKey.getAgentUserInQueHashKey()); Map map = new HashMap<>(); for (final Map.Entry entry : agentUsers.entrySet()) { final AgentUser obj = SerializeUtil.deserialize(entry.getValue()); @@ -105,10 +100,9 @@ public class Cache { * TODO 将访客对应的客服的服务列表变更 * * @param userid - * @param orgi */ - public void deleteAgentUserInservByAgentUserIdAndOrgi(final String userid, final String orgi) { - redisCommand.delHashKV(RedisKey.getAgentUserInServHashKey(orgi), userid); + public void deleteAgentUserInservByAgentUserId(final String userid) { + redisCommand.delHashKV(RedisKey.getAgentUserInServHashKey(), userid); } @@ -116,21 +110,19 @@ public class Cache { * 将访客ID从排队队列中删除 * * @param userid - * @param orgi */ - public void deleteAgentUserInqueByAgentUserIdAndOrgi(final String userid, final String orgi) { - redisCommand.delHashKV(RedisKey.getAgentUserInQueHashKey(orgi), userid); + public void deleteAgentUserInqueByAgentUserId(final String userid) { + redisCommand.delHashKV(RedisKey.getAgentUserInQueHashKey(), userid); } /** * 获得一个坐席的状态 * * @param agentno 坐席ID - * @param orgi 租户ID * @return */ - public AgentStatus findOneAgentStatusByAgentnoAndOrig(final String agentno, final String orgi) { - String status = getAgentStatusStatus(agentno, orgi); + public AgentStatus findOneAgentStatusByAgentno(final String agentno) { + String status = getAgentStatusStatus(agentno); logger.debug("[findOneAgentStatusByAgentnoAndOrig] agentno {}, status {}", agentno, status); // 缓存中没有该坐席状态,该坐席目前是离线的 @@ -138,7 +130,7 @@ public class Cache { return null; } - String val = redisCommand.getHashKV(RedisKey.getAgentStatusHashKeyByStatusStr(orgi, status), agentno); + String val = redisCommand.getHashKV(RedisKey.getAgentStatusHashKeyByStatusStr(status), agentno); AgentStatus result = SerializeUtil.deserialize(val); logger.debug("[findOneAgentStatusByAgentnoAndOrig] result: username {}", result.getUsername()); return result; @@ -148,16 +140,15 @@ public class Cache { * 更新坐席状态 * * @param agentStatus - * @param orgi */ - public void putAgentStatusByOrgi(AgentStatus agentStatus, String orgi) { - String pre = getAgentStatusStatus(agentStatus.getAgentno(), orgi); // 坐席前状态 + public void putAgentStatus(AgentStatus agentStatus) { + String pre = getAgentStatusStatus(agentStatus.getAgentno()); // 坐席前状态 if (StringUtils.equals(pre, MainContext.AgentStatusEnum.OFFLINE.toString())) { // 之前不存在,新建缓存 if ((!StringUtils.equals(agentStatus.getStatus(), MainContext.AgentStatusEnum.OFFLINE.toString()))) { redisCommand.setHashKV( - RedisKey.getAgentStatusHashKeyByStatusStr(orgi, agentStatus.getStatus()), + RedisKey.getAgentStatusHashKeyByStatusStr(agentStatus.getStatus()), agentStatus.getAgentno(), SerializeUtil.serialize(agentStatus)); } return; @@ -165,15 +156,15 @@ public class Cache { // 之前存在,与将要更新的状态一致 if (StringUtils.equals(pre, agentStatus.getStatus())) { redisCommand.setHashKV( - RedisKey.getAgentStatusHashKeyByStatusStr(orgi, pre), agentStatus.getAgentno(), + RedisKey.getAgentStatusHashKeyByStatusStr(pre), agentStatus.getAgentno(), SerializeUtil.serialize(agentStatus)); return; } else { // 之前存在,而且与新状态不一致 - redisCommand.delHashKV(RedisKey.getAgentStatusHashKeyByStatusStr(orgi, pre), agentStatus.getAgentno()); + redisCommand.delHashKV(RedisKey.getAgentStatusHashKeyByStatusStr(pre), agentStatus.getAgentno()); if (!StringUtils.equals(agentStatus.getStatus(), MainContext.AgentStatusEnum.OFFLINE.toString())) { redisCommand.setHashKV( - RedisKey.getAgentStatusHashKeyByStatusStr(orgi, agentStatus.getStatus()), + RedisKey.getAgentStatusHashKeyByStatusStr(agentStatus.getStatus()), agentStatus.getAgentno(), SerializeUtil.serialize(agentStatus)); } } @@ -183,12 +174,11 @@ public class Cache { /** * 获得一个租户的就绪坐席状态 * - * @param orgi * @return */ - public Map findAllReadyAgentStatusByOrgi(final String orgi) { + public Map findAllReadyAgentStatus() { List keys = new ArrayList<>(); - keys.add(RedisKey.getAgentStatusReadyHashKey(orgi)); + keys.add(RedisKey.getAgentStatusReadyHashKey()); Map map = redisCommand.getAllMembersInMultiHash(keys); return convertFromStringToAgentStatus(map); @@ -197,14 +187,13 @@ public class Cache { /** * 获得一个租户的所有坐席状态 * - * @param orgi * @return */ - public Map findAllAgentStatusByOrgi(final String orgi) { + public Map findAllAgentStatus() { List keys = new ArrayList<>(); // TODO 增加支持更多状态 - keys.add(RedisKey.getAgentStatusReadyHashKey(orgi)); - keys.add(RedisKey.getAgentStatusNotReadyHashKey(orgi)); + keys.add(RedisKey.getAgentStatusReadyHashKey()); + keys.add(RedisKey.getAgentStatusNotReadyHashKey()); Map map = redisCommand.getAllMembersInMultiHash(keys); return convertFromStringToAgentStatus(map); @@ -215,7 +204,7 @@ public class Cache { * Inline方法 */ private static Map convertFromStringToAgentStatus(final Map map) { - Map result = new HashMap(); + Map result = new HashMap<>(); for (Map.Entry entry : map.entrySet()) { AgentStatus obj = SerializeUtil.deserialize(entry.getValue()); result.put(entry.getKey(), obj); @@ -228,12 +217,11 @@ public class Cache { * Delete Agent Status * * @param agentno - * @param orgi */ - public void deleteAgentStatusByAgentnoAndOrgi(final String agentno, final String orgi) { - String status = getAgentStatusStatus(agentno, orgi); + public void deleteAgentStatusByAgentno(final String agentno) { + String status = getAgentStatusStatus(agentno); if (!StringUtils.equals(MainContext.AgentStatusEnum.OFFLINE.toString(), status)) { - redisCommand.delHashKV(RedisKey.getAgentStatusHashKeyByStatusStr(orgi, status), agentno); + redisCommand.delHashKV(RedisKey.getAgentStatusHashKeyByStatusStr(status), agentno); } } @@ -242,14 +230,13 @@ public class Cache { * 只返回大类状态 * * @param agentno - * @param orgi * @return */ - private String getAgentStatusStatus(final String agentno, final String orgi) { + private String getAgentStatusStatus(final String agentno) { // 首先判断这个坐席的状态是READY还是BUSY,再去更新 - if (redisCommand.hasHashKV(RedisKey.getAgentStatusReadyHashKey(orgi), agentno)) { + if (redisCommand.hasHashKV(RedisKey.getAgentStatusReadyHashKey(), agentno)) { return MainContext.AgentStatusEnum.READY.toString(); - } else if (redisCommand.hasHashKV(RedisKey.getAgentStatusNotReadyHashKey(orgi), agentno)) { + } else if (redisCommand.hasHashKV(RedisKey.getAgentStatusNotReadyHashKey(), agentno)) { return MainContext.AgentStatusEnum.NOTREADY.toString(); } else { return MainContext.AgentStatusEnum.OFFLINE.toString(); @@ -261,12 +248,11 @@ public class Cache { * 获得技能组的坐席状态 * * @param skill - * @param orgi * @return */ - public List getAgentStatusBySkillAndOrgi(final String skill, final String orgi) { - Map map = findAllAgentStatusByOrgi(orgi); - List agentList = new ArrayList(); + public List getAgentStatusBySkill(final String skill) { + Map map = findAllAgentStatus(); + List agentList = new ArrayList<>(); for (Map.Entry entry : map.entrySet()) { if (StringUtils.isNotBlank(skill)) { @@ -285,11 +271,10 @@ public class Cache { /** * 获得指定租户的就绪的坐席个数 * - * @param orgi * @return */ - public int getAgentStatusReadySizeByOrgi(final String orgi) { - return Math.toIntExact(redisCommand.getHashSize(RedisKey.getAgentStatusReadyHashKey(orgi))); + public int getAgentStatusReadySize() { + return Math.toIntExact(redisCommand.getHashSize(RedisKey.getAgentStatusReadyHashKey())); } @@ -305,32 +290,31 @@ public class Cache { * 但是之前那个关联坐席的信息需要删除,要另行维护 * * @param agentUser 最新的agentUser的状态 - * @param orgi */ @AgentUserAspect.LinkAgentUser - public void putAgentUserByOrgi(AgentUser agentUser, String orgi) { - if (redisCommand.hasHashKV(RedisKey.getAgentUserInServHashKey(orgi), agentUser.getUserid())) { + public void putAgentUser(AgentUser agentUser) { + if (redisCommand.hasHashKV(RedisKey.getAgentUserInServHashKey(), agentUser.getUserid())) { // 服务中 if (!StringUtils.equals( agentUser.getStatus(), MainContext.AgentUserStatusEnum.INSERVICE.toString())) { // 删除旧记录 - redisCommand.delHashKV(RedisKey.getAgentUserInServHashKey(orgi), agentUser.getUserid()); + redisCommand.delHashKV(RedisKey.getAgentUserInServHashKey(), agentUser.getUserid()); } - } else if (redisCommand.hasHashKV(RedisKey.getAgentUserInQueHashKey(orgi), agentUser.getUserid())) { + } else if (redisCommand.hasHashKV(RedisKey.getAgentUserInQueHashKey(), agentUser.getUserid())) { // 等待服务 if (!StringUtils.equals( agentUser.getStatus(), MainContext.AgentUserStatusEnum.INQUENE.toString())) { // 删除旧记录 - redisCommand.delHashKV(RedisKey.getAgentUserInQueHashKey(orgi), agentUser.getUserid()); + redisCommand.delHashKV(RedisKey.getAgentUserInQueHashKey(), agentUser.getUserid()); } } // 更新新记录,忽略状态为END的agentUser,已结束的服务不加入缓存 if (!StringUtils.equals(agentUser.getStatus(), MainContext.AgentUserStatusEnum.END.toString())) { redisCommand.setHashKV( - RedisKey.getAgentUserHashKeyByStatusStr(orgi, agentUser.getStatus()), agentUser.getUserid(), + RedisKey.getAgentUserHashKeyByStatusStr(agentUser.getStatus()), agentUser.getUserid(), SerializeUtil.serialize(agentUser)); } } @@ -340,13 +324,12 @@ public class Cache { * 获得一个客服服务中的访客列表 * * @param agentno - * @param orgi * @return */ - public List findInservAgentUsersByAgentnoAndOrgi(final String agentno, final String orgi) { - logger.info("[findInservAgentUsersByAgentnoAndOrgi] agentno {}, orgi {}", agentno, orgi); + public List findInservAgentUsersByAgentno(final String agentno) { + logger.info("[findInservAgentUsersByAgentno] agentno {}", agentno); List result = new ArrayList<>(); - List ids = redisCommand.getSet(RedisKey.getInServAgentUsersByAgentnoAndOrgi(agentno, orgi)); + List ids = redisCommand.getSet(RedisKey.getInServAgentUsersByAgentno(agentno)); if (ids.size() == 0) { // no inserv agentUser return result; } else { @@ -360,48 +343,44 @@ public class Cache { * 获得一个坐席服务中的访客数量 * * @param agentno - * @param orgi * @return */ - public int getInservAgentUsersSizeByAgentnoAndOrgi(final String agentno, final String orgi) { - return Math.toIntExact(redisCommand.getSetSize(RedisKey.getInServAgentUsersByAgentnoAndOrgi(agentno, orgi))); + public int getInservAgentUsersSizeByAgentno(final String agentno) { + return Math.toIntExact(redisCommand.getSetSize(RedisKey.getInServAgentUsersByAgentno(agentno))); } /** * 获得服务中的访客的数量 * - * @param orgi * @return */ - public int getInservAgentUsersSizeByOrgi(final String orgi) { - return redisCommand.getHashSize(RedisKey.getAgentUserInServHashKey(orgi)); + public int getInservAgentUsersSize() { + return redisCommand.getHashSize(RedisKey.getAgentUserInServHashKey()); } /** * 获得等待中的访客的数量 * - * @param orgi * @return */ - public int getInqueAgentUsersSizeByOrgi(final String orgi) { - return redisCommand.getHashSize(RedisKey.getAgentUserInQueHashKey(orgi)); + public int getInqueAgentUsersSize() { + return redisCommand.getHashSize(RedisKey.getAgentUserInQueHashKey()); } /** * Delete agentUser * * @param agentUser - * @param orgi */ @AgentUserAspect.LinkAgentUser - public void deleteAgentUserByUserIdAndOrgi(final AgentUser agentUser, String orgi) { - if (redisCommand.hasHashKV(RedisKey.getAgentUserInQueHashKey(orgi), agentUser.getUserid())) { + public void deleteAgentUserByUserId(final AgentUser agentUser) { + if (redisCommand.hasHashKV(RedisKey.getAgentUserInQueHashKey(), agentUser.getUserid())) { // 排队等待中 - redisCommand.delHashKV(RedisKey.getAgentUserInQueHashKey(orgi), agentUser.getUserid()); - } else if (redisCommand.hasHashKV(RedisKey.getAgentUserInServHashKey(orgi), agentUser.getUserid())) { - redisCommand.delHashKV(RedisKey.getAgentUserInServHashKey(orgi), agentUser.getUserid()); - } else if (redisCommand.hasHashKV(RedisKey.getAgentUserEndHashKey(orgi), agentUser.getUserid())) { - redisCommand.delHashKV(RedisKey.getAgentUserEndHashKey(orgi), agentUser.getUserid()); + redisCommand.delHashKV(RedisKey.getAgentUserInQueHashKey(), agentUser.getUserid()); + } else if (redisCommand.hasHashKV(RedisKey.getAgentUserInServHashKey(), agentUser.getUserid())) { + redisCommand.delHashKV(RedisKey.getAgentUserInServHashKey(), agentUser.getUserid()); + } else if (redisCommand.hasHashKV(RedisKey.getAgentUserEndHashKey(), agentUser.getUserid())) { + redisCommand.delHashKV(RedisKey.getAgentUserEndHashKey(), agentUser.getUserid()); } else { // TODO 考虑是否有其他状态保存 } @@ -410,14 +389,14 @@ public class Cache { /*************************** * CousultInvite 相关 ***************************/ - public void putConsultInviteByOrgi(final String orgi, final CousultInvite cousultInvite) { + public void putConsultInvite(final CousultInvite cousultInvite) { redisCommand.setHashKV( - RedisKey.getConsultInvitesByOrgi(orgi), cousultInvite.getSnsaccountid(), + RedisKey.getConsultInvites(), cousultInvite.getSnsaccountid(), SerializeUtil.serialize(cousultInvite)); } - public CousultInvite findOneConsultInviteBySnsidAndOrgi(final String snsid, final String orgi) { - String serialized = redisCommand.getHashKV(RedisKey.getConsultInvitesByOrgi(orgi), snsid); + public CousultInvite findOneConsultInviteBySnsid(final String snsid) { + String serialized = redisCommand.getHashKV(RedisKey.getConsultInvites(), snsid); if (StringUtils.isBlank(serialized)) { return null; } else { @@ -425,8 +404,8 @@ public class Cache { } } - public void deleteConsultInviteBySnsidAndOrgi(final String snsid, final String orgi) { - redisCommand.delHashKV(RedisKey.getConsultInvitesByOrgi(orgi), snsid); + public void deleteConsultInviteBySnsid(final String snsid) { + redisCommand.delHashKV(RedisKey.getConsultInvites(), snsid); } @@ -437,34 +416,32 @@ public class Cache { /** * 更新 onlineUser * - * @param onlineUser - * @param orgi + * @param passportWebIMUser */ - public void putOnlineUserByOrgi(final OnlineUser onlineUser, final String orgi) { + public void putOnlineUser(final PassportWebIMUser passportWebIMUser) { // 此处onlineUser的id 与 onlineUser userId相同 redisCommand.setHashKV( - RedisKey.getOnlineUserHashKey(orgi), onlineUser.getId(), SerializeUtil.serialize(onlineUser)); + RedisKey.getOnlineUserHashKey(), passportWebIMUser.getId(), SerializeUtil.serialize(passportWebIMUser)); } /** * 获得 onlineUser * * @param id - * @param orgi * @return */ - public OnlineUser findOneOnlineUserByUserIdAndOrgi(final String id, final String orgi) { - String serialized = redisCommand.getHashKV(RedisKey.getOnlineUserHashKey(orgi), id); + public PassportWebIMUser findOneOnlineUserByUserId(final String id) { + String serialized = redisCommand.getHashKV(RedisKey.getOnlineUserHashKey(), id); if (StringUtils.isBlank(serialized)) { // query with MySQL - return onlineUserRes.findOneByUseridAndOrgi(id, orgi); + return onlineUserRes.findOneByUserid(id); } else { return convertFromStringToOnlineUser(serialized); } } - private static OnlineUser convertFromStringToOnlineUser(final String serialized) { - OnlineUser obj = SerializeUtil.deserialize(serialized); + private static PassportWebIMUser convertFromStringToOnlineUser(final String serialized) { + PassportWebIMUser obj = SerializeUtil.deserialize(serialized); return obj; } @@ -472,19 +449,16 @@ public class Cache { * 删除 onlineUser * * @param id - * @param orgi */ - public void deleteOnlineUserByIdAndOrgi(final String id, final String orgi) { - redisCommand.delHashKV(RedisKey.getOnlineUserHashKey(orgi), id); + public void deleteOnlineUserById(final String id) { + redisCommand.delHashKV(RedisKey.getOnlineUserHashKey(), id); } /** * 根据租户ID获得在线访客的列表大小 - * - * @param orgi */ - public int getOnlineUserSizeByOrgi(final String orgi) { - return redisCommand.getHashSize(RedisKey.getOnlineUserHashKey(orgi)); + public int getOnlineUserSize() { + return redisCommand.getHashSize(RedisKey.getOnlineUserHashKey()); } @@ -493,16 +467,15 @@ public class Cache { * * @param userid * @param agentno - * @param orgi */ - public void deleteOnlineUserIdFromAgentStatusByUseridAndAgentnoAndOrgi(final String userid, final String agentno, final String orgi) { - redisCommand.removeSetVal(RedisKey.getInServAgentUsersByAgentnoAndOrgi(agentno, orgi), userid); + public void deleteOnlineUserIdFromAgentStatusByUseridAndAgentno(final String userid, final String agentno) { + redisCommand.removeSetVal(RedisKey.getInServAgentUsersByAgentno(agentno), userid); } - private Map convertFromStringToOnlineUsers(final Map map) { - Map result = new HashMap<>(); + private Map convertFromStringToOnlineUsers(final Map map) { + Map result = new HashMap<>(); for (Map.Entry entry : map.entrySet()) { - OnlineUser x = SerializeUtil.deserialize(entry.getValue()); + PassportWebIMUser x = SerializeUtil.deserialize(entry.getValue()); result.put(entry.getKey(), x); } return result; @@ -517,22 +490,20 @@ public class Cache { * 更新CallCenterAgent * * @param id - * @param orgi * @param agent */ - public void putCallCenterAgentByIdAndOrgi(final String id, final String orgi, final CallCenterAgent agent) { - redisCommand.setHashKV(RedisKey.getCallCenterAgentHashKeyByOrgi(orgi), id, SerializeUtil.serialize(agent)); + public void putCallCenterAgentById(final String id, final CallCenterAgent agent) { + redisCommand.setHashKV(RedisKey.getCallCenterAgentHashKey(), id, SerializeUtil.serialize(agent)); } /** * 根据ID和租户ID获得CallCenterAgent * * @param id - * @param orgi * @return */ - public CallCenterAgent findOneCallCenterAgentByIdAndOrgi(final String id, final String orgi) { - String serialized = redisCommand.getHashKV(RedisKey.getCallCenterAgentHashKeyByOrgi(orgi), id); + public CallCenterAgent findOneCallCenterAgentById(final String id) { + String serialized = redisCommand.getHashKV(RedisKey.getCallCenterAgentHashKey(), id); if (StringUtils.isNotBlank(serialized)) { return (CallCenterAgent) SerializeUtil.deserialize(serialized); } else { @@ -544,21 +515,19 @@ public class Cache { * 删除CallCenterAgent * * @param id - * @param orgi */ - public void deleteCallCenterAgentByIdAndOrgi(final String id, final String orgi) { - redisCommand.delHashKV(RedisKey.getCallCenterAgentHashKeyByOrgi(orgi), id); + public void deleteCallCenterAgentById(final String id) { + redisCommand.delHashKV(RedisKey.getCallCenterAgentHashKey(), id); } /** * 根据租户ID获得所有的CallCenterAgent * - * @param orgi * @return */ - public Map findAllCallCenterAgentsByOrgi(final String orgi) { - Map map = redisCommand.getHash(RedisKey.getCallCenterAgentHashKeyByOrgi(orgi)); + public Map findAllCallCenterAgents() { + Map map = redisCommand.getHash(RedisKey.getCallCenterAgentHashKey()); Map result = new HashMap<>(); for (Map.Entry entry : map.entrySet()) { @@ -572,14 +541,14 @@ public class Cache { * 访客黑名单 */ // 将访客放在租户的黑名单中 - public void putBlackEntityByOrgi(final BlackEntity blackEntity, final String orgi) { + public void putBlackEntity(final BlackEntity blackEntity) { redisCommand.setHashKV( - RedisKey.getBlackEntityKeyByOrgi(orgi), blackEntity.getUserid(), SerializeUtil.serialize(blackEntity)); + RedisKey.getBlackEntityKey(), blackEntity.getUserid(), SerializeUtil.serialize(blackEntity)); } // 通过指定的访客和租户查找黑名单 - public Optional findOneBlackEntityByUserIdAndOrgi(final String userid, final String orgi) { - String ser = redisCommand.getHashKV(RedisKey.getBlackEntityKeyByOrgi(orgi), userid); + public Optional findOneBlackEntityByUserId(final String userid) { + String ser = redisCommand.getHashKV(RedisKey.getBlackEntityKey(), userid); if (StringUtils.isBlank(ser)) { return Optional.empty(); } @@ -588,20 +557,20 @@ public class Cache { } // 将一个访客从黑名单中移除 - public void deleteBlackEntityByUserIdAndOrgi(final String userid, final String orgi) { - redisCommand.delHashKV(RedisKey.getBlackEntityKeyByOrgi(orgi), userid); + public void deleteBlackEntityByUserId(final String userid) { + redisCommand.delHashKV(RedisKey.getBlackEntityKey(), userid); } // 指定的访客是否在租户的黑名单中 - public boolean existBlackEntityByUserIdAndOrgi(final String userid, final String orgi) { - return redisCommand.hasHashKV(RedisKey.getBlackEntityKeyByOrgi(orgi), userid); + public boolean existBlackEntityByUserId(final String userid) { + return redisCommand.hasHashKV(RedisKey.getBlackEntityKey(), userid); } // 根据租户ID获得所有访客的黑名单 - public Map findAllBlackEntityByOrgi(final String orgi) { + public Map findAllBlackEntity() { Map result = new HashMap<>(); for (Map.Entry entry : redisCommand.getHash( - RedisKey.getBlackEntityKeyByOrgi(orgi)).entrySet()) { + RedisKey.getBlackEntityKey()).entrySet()) { result.put(entry.getKey(), SerializeUtil.deserialize(entry.getValue())); } return result; @@ -611,12 +580,12 @@ public class Cache { /***************************** * Job 相关 *****************************/ - public void putJobByIdAndOrgi(final String jobId, final String orgi, final JobDetail job) { - redisCommand.setHashKV(RedisKey.getJobHashKeyByOrgi(orgi), jobId, SerializeUtil.serialize(job)); + public void putJobById(final String jobId, final JobDetail job) { + redisCommand.setHashKV(RedisKey.getJobHashKey(), jobId, SerializeUtil.serialize(job)); } - public JobDetail findOneJobByIdAndOrgi(final String jobId, final String orgi) { - String serialized = redisCommand.getHashKV(RedisKey.getJobHashKeyByOrgi(orgi), jobId); + public JobDetail findOneJobById(final String jobId) { + String serialized = redisCommand.getHashKV(RedisKey.getJobHashKey(), jobId); if (StringUtils.isNotBlank(serialized)) { return (JobDetail) SerializeUtil.deserialize(serialized); @@ -624,35 +593,35 @@ public class Cache { return null; } - public boolean existJobByIdAndOrgi(final String jobId, final String orgi) { - return redisCommand.hasHashKV(RedisKey.getJobHashKeyByOrgi(orgi), jobId); + public boolean existJobById(final String jobId) { + return redisCommand.hasHashKV(RedisKey.getJobHashKey(), jobId); } - public void deleteJobByJobIdAndOrgi(final String jobId, final String orgi) { - redisCommand.delHashKV(RedisKey.getJobHashKeyByOrgi(orgi), jobId); + public void deleteJobByJobId(final String jobId) { + redisCommand.delHashKV(RedisKey.getJobHashKey(), jobId); } /** * 系统词典相关 */ // 存储根词典 - public void putSysDicByOrgi(final String id, final String orgi, final SysDic sysDic) { - redisCommand.setHashKV(RedisKey.getSysDicHashKeyByOrgi(orgi), id, SerializeUtil.serialize(sysDic)); + public void putSysDic(final String id, final SysDic sysDic) { + redisCommand.setHashKV(RedisKey.getSysDicHashKey(), id, SerializeUtil.serialize(sysDic)); } // 将指定租户的系统词典清空 - public void eraseSysDicByOrgi(final String orgi) { - redisCommand.delete(RedisKey.getSysDicHashKeyByOrgi(orgi)); + public void eraseSysDic() { + redisCommand.delete(RedisKey.getSysDicHashKey()); } // 存储词典子项 - public void putSysDicByOrgi(final String code, final String orgi, final List sysDics) { - redisCommand.setHashKV(RedisKey.getSysDicHashKeyByOrgi(orgi), code, SerializeUtil.serialize(sysDics)); + public void putSysDic(final String code, final List sysDics) { + redisCommand.setHashKV(RedisKey.getSysDicHashKey(), code, SerializeUtil.serialize(sysDics)); } // 获得词典的子项列表 - public List getSysDicItemsByCodeAndOrgi(final String code, final String orgi) { - String serialized = redisCommand.getHashKV(RedisKey.getSysDicHashKeyByOrgi(orgi), code); + public List getSysDicItemsByCode(final String code) { + String serialized = redisCommand.getHashKV(RedisKey.getSysDicHashKey(), code); if (serialized != null) { return (List) SerializeUtil.deserialize(serialized); } @@ -660,8 +629,8 @@ public class Cache { } // 获得词典子项 - public SysDic findOneSysDicByCodeAndOrgi(final String code, final String orgi) { - String serialized = redisCommand.getHashKV(RedisKey.getSysDicHashKeyByOrgi(orgi), code); + public SysDic findOneSysDicByCode(final String code) { + String serialized = redisCommand.getHashKV(RedisKey.getSysDicHashKey(), code); if (StringUtils.isBlank(serialized)) { return null; @@ -671,8 +640,8 @@ public class Cache { } // 获得词典 - public SysDic findOneSysDicByIdAndOrgi(final String id, final String orgi) { - String serialized = redisCommand.getHashKV(RedisKey.getSysDicHashKeyByOrgi(orgi), id); + public SysDic findOneSysDicById(final String id) { + String serialized = redisCommand.getHashKV(RedisKey.getSysDicHashKey(), id); if (StringUtils.isBlank(serialized)) { return null; @@ -682,63 +651,63 @@ public class Cache { } // 批量存储 - public void putSysDicByOrgi(List vals, final String orgi) { + public void putSysDic(List vals) { Map map = new HashMap<>(); for (final SysDic dic : vals) { map.put(dic.getId(), SerializeUtil.serialize(dic)); } - redisCommand.hmset(RedisKey.getSysDicHashKeyByOrgi(orgi), map); + redisCommand.hmset(RedisKey.getSysDicHashKey(), map); } - public void deleteSysDicByIdAndOrgi(final String id, final String orgi) { - redisCommand.delHashKV(RedisKey.getSysDicHashKeyByOrgi(orgi), id); + public void deleteSysDicById(final String id) { + redisCommand.delHashKV(RedisKey.getSysDicHashKey(), id); } - public boolean existSysDicByIdAndOrgi(final String id, final String orgi) { - return redisCommand.hasHashKV(RedisKey.getSysDicHashKeyByOrgi(orgi), id); + public boolean existSysDicById(final String id) { + return redisCommand.hasHashKV(RedisKey.getSysDicHashKey(), id); } /** * System 相关 */ - public void putSystemByIdAndOrgi(final String id, final String orgi, final T obj) { - redisCommand.setHashKV(RedisKey.getSystemHashKeyByOrgi(orgi), id, SerializeUtil.serialize(obj)); + public void putSystemById(final String id, final T obj) { + redisCommand.setHashKV(RedisKey.getSystemHashKey(), id, SerializeUtil.serialize(obj)); } - public void putSystemListByIdAndOrgi(final String id, final String orgi, final List obj) { - redisCommand.setHashKV(RedisKey.getSystemHashKeyByOrgi(orgi), id, SerializeUtil.serialize(obj)); + public void putSystemListById(final String id, final List obj) { + redisCommand.setHashKV(RedisKey.getSystemHashKey(), id, SerializeUtil.serialize(obj)); } - public void putSystemMapByIdAndOrgi(final String id, final String orgi, final Map obj) { - redisCommand.setHashKV(RedisKey.getSystemHashKeyByOrgi(orgi), id, SerializeUtil.serialize(obj)); + public void putSystemMapById(final String id, final Map obj) { + redisCommand.setHashKV(RedisKey.getSystemHashKey(), id, SerializeUtil.serialize(obj)); } - public boolean existSystemByIdAndOrgi(final String id, final String orgi) { - return redisCommand.hasHashKV(RedisKey.getSystemHashKeyByOrgi(orgi), id); + public boolean existSystemById(final String id) { + return redisCommand.hasHashKV(RedisKey.getSystemHashKey(), id); } - public void deleteSystembyIdAndOrgi(final String id, final String orgi) { - redisCommand.delHashKV(RedisKey.getSystemHashKeyByOrgi(orgi), id); + public void deleteSystembyId(final String id) { + redisCommand.delHashKV(RedisKey.getSystemHashKey(), id); } - public T findOneSystemByIdAndOrgi(final String id, final String orgi) { - String serialized = redisCommand.getHashKV(RedisKey.getSystemHashKeyByOrgi(orgi), id); + public T findOneSystemById(final String id) { + String serialized = redisCommand.getHashKV(RedisKey.getSystemHashKey(), id); if (StringUtils.isNotBlank(serialized)) { return (T) SerializeUtil.deserialize(serialized); } return null; } - public List findOneSystemListByIdAndOrgi(final String id, final String orgi) { - String serialized = redisCommand.getHashKV(RedisKey.getSystemHashKeyByOrgi(orgi), id); + public List findOneSystemListById(final String id) { + String serialized = redisCommand.getHashKV(RedisKey.getSystemHashKey(), id); if (StringUtils.isNotBlank(serialized)) { return (List) SerializeUtil.deserialize(serialized); } return null; } - public Map findOneSystemMapByIdAndOrgi(final String id, final String orgi) { - String serialized = redisCommand.getHashKV(RedisKey.getSystemHashKeyByOrgi(orgi), id); + public Map findOneSystemMapById(final String id) { + String serialized = redisCommand.getHashKV(RedisKey.getSystemHashKey(), id); if (StringUtils.isNotBlank(serialized)) { return (Map) SerializeUtil.deserialize(serialized); } @@ -746,40 +715,40 @@ public class Cache { } // 获得系统cache的列表大小 - public int getSystemSizeByOrgi(final String orgi) { - return redisCommand.getHashSize(RedisKey.getSystemHashKeyByOrgi(orgi)); + public int getSystemSize() { + return redisCommand.getHashSize(RedisKey.getSystemHashKey()); } /************************** * Session Config 相关 **************************/ - public void putSessionConfigByOrgi(final SessionConfig sessionConfig, String organid, final String orgi) { - redisCommand.put(RedisKey.getSessionConfig(organid, orgi), SerializeUtil.serialize(sessionConfig)); + public void putSessionConfig(final SessionConfig sessionConfig, String organid) { + redisCommand.put(RedisKey.getSessionConfig(organid), SerializeUtil.serialize(sessionConfig)); } - public SessionConfig findOneSessionConfigByOrgi(String organid, final String orgi) { - String serialized = redisCommand.get(RedisKey.getSessionConfig(organid, orgi)); + public SessionConfig findOneSessionConfig(String organid) { + String serialized = redisCommand.get(RedisKey.getSessionConfig(organid)); if (StringUtils.isNotBlank(serialized)) { return (SessionConfig) SerializeUtil.deserialize(serialized); } return null; } - public void deleteSessionConfigByOrgi(String organid, final String orgi) { - redisCommand.delete(RedisKey.getSessionConfig(organid, orgi)); + public void deleteSessionConfig(String organid) { + redisCommand.delete(RedisKey.getSessionConfig(organid)); } - public boolean existSessionConfigByOrgi(String organid, final String orgi) { - return redisCommand.exists(RedisKey.getSessionConfig(organid, orgi)); + public boolean existSessionConfig(String organid) { + return redisCommand.exists(RedisKey.getSessionConfig(organid)); } - public void putSessionConfigListByOrgi(final List lis, final String orgi) { - redisCommand.put(RedisKey.getSessionConfigList(orgi), SerializeUtil.serialize(lis)); + public void putSessionConfigList(final List lis) { + redisCommand.put(RedisKey.getSessionConfigList(), SerializeUtil.serialize(lis)); } - public List findOneSessionConfigListByOrgi(final String orgi) { - String serialized = redisCommand.get(RedisKey.getSessionConfigList(orgi)); + public List findOneSessionConfigList() { + String serialized = redisCommand.get(RedisKey.getSessionConfigList()); if (StringUtils.isNotBlank(serialized)) { return (List) SerializeUtil.deserialize(serialized); } @@ -787,40 +756,40 @@ public class Cache { return null; } - public void deleteSessionConfigListByOrgi(final String orgi) { - redisCommand.delete(RedisKey.getSessionConfigList(orgi)); + public void deleteSessionConfigList() { + redisCommand.delete(RedisKey.getSessionConfigList()); } - public boolean existSessionConfigListByOrgi(final String orgi) { - return redisCommand.exists(RedisKey.getSessionConfigList(orgi)); + public boolean existSessionConfigList() { + return redisCommand.exists(RedisKey.getSessionConfigList()); } /****************************************** * Customer Chats Audit 相关 ******************************************/ - public void putAgentUserAuditByOrgi(final String orgi, final AgentUserAudit audit) throws CSKefuCacheException { + public void putAgentUserAudit(final AgentUserAudit audit) throws CSKefuCacheException { if (StringUtils.isBlank(audit.getAgentUserId())) { throw new CSKefuCacheException("agentUserId is required."); } redisCommand.setHashKV( - RedisKey.getCustomerChatsAuditKeyByOrgi(orgi), audit.getAgentUserId(), SerializeUtil.serialize(audit)); + RedisKey.getCustomerChatsAuditKey(), audit.getAgentUserId(), SerializeUtil.serialize(audit)); } - public void deleteAgentUserAuditByOrgiAndId(final String orgi, final String agentUserId) { - redisCommand.delHashKV(RedisKey.getCustomerChatsAuditKeyByOrgi(orgi), agentUserId); + public void deleteAgentUserAuditById(final String agentUserId) { + redisCommand.delHashKV(RedisKey.getCustomerChatsAuditKey(), agentUserId); } - public Optional findOneAgentUserAuditByOrgiAndId(final String orgi, final String agentUserId) { - logger.info("[findOneAgentUserAuditByOrgiAndId] orgi {}, agentUserId {}", orgi, agentUserId); - String serialized = redisCommand.getHashKV(RedisKey.getCustomerChatsAuditKeyByOrgi(orgi), agentUserId); + public Optional findOneAgentUserAuditById(final String agentUserId) { + logger.info("[findOneAgentUserAuditById] agentUserId {}", agentUserId); + String serialized = redisCommand.getHashKV(RedisKey.getCustomerChatsAuditKey(), agentUserId); if (StringUtils.isBlank(serialized)) { return Optional.empty(); } return Optional.ofNullable((AgentUserAudit) SerializeUtil.deserialize(serialized)); } - public boolean existAgentUserAuditByOrgiAndId(final String orgi, final String agentUserId) { - return redisCommand.hasHashKV(RedisKey.getCustomerChatsAuditKeyByOrgi(orgi), agentUserId); + public boolean existAgentUserAuditById(final String agentUserId) { + return redisCommand.hasHashKV(RedisKey.getCustomerChatsAuditKey(), agentUserId); } @@ -833,22 +802,21 @@ public class Cache { * * @param agentno * @param sessionId - * @param orgi */ - public void putUserSessionByAgentnoAndSessionIdAndOrgi(final String agentno, final String sessionId, final String orgi) { - redisCommand.setHashKV(RedisKey.getUserSessionKeyByOrgi(orgi), agentno, sessionId); + public void putUserSessionByAgentnoAndSessionId(final String agentno, final String sessionId) { + redisCommand.setHashKV(RedisKey.getUserSessionKey(), agentno, sessionId); } - public boolean existUserSessionByAgentnoAndOrgi(final String agentno, final String orgi) { - return redisCommand.hasHashKV(RedisKey.getUserSessionKeyByOrgi(orgi), agentno); + public boolean existUserSessionByAgentno(final String agentno) { + return redisCommand.hasHashKV(RedisKey.getUserSessionKey(), agentno); } - public String findOneSessionIdByAgentnoAndOrgi(final String agentno, final String orgi) { - return redisCommand.getHashKV(RedisKey.getUserSessionKeyByOrgi(orgi), agentno); + public String findOneSessionIdByAgentno(final String agentno) { + return redisCommand.getHashKV(RedisKey.getUserSessionKey(), agentno); } - public void deleteUserSessionByAgentnoAndOrgi(final String agentno, final String orgi) { - redisCommand.delHashKV(RedisKey.getUserSessionKeyByOrgi(orgi), agentno); + public void deleteUserSessionByAgentno(final String agentno) { + redisCommand.delHashKV(RedisKey.getUserSessionKey(), agentno); } } diff --git a/contact-center/app/src/main/java/com/cskefu/cc/cache/RedisCommand.java b/contact-center/app/src/main/java/com/cskefu/cc/cache/RedisCommand.java index 72015884..68fb96c6 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/cache/RedisCommand.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/cache/RedisCommand.java @@ -1,17 +1,15 @@ -/* - * Copyright (C) 2019-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * +/* + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2019-2022 Chatopera Inc, , + * Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.cache; @@ -22,7 +20,7 @@ import org.springframework.data.redis.core.*; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; import java.util.*; import java.util.concurrent.TimeUnit; @@ -62,12 +60,10 @@ public class RedisCommand { * * @param key * @param serialized - * @return */ - public boolean put(final String key, final String serialized) { + public void put(final String key, final String serialized) { boolean result = true; redisValOps.set(key, serialized); - return result; } public String get(final String key) { @@ -270,15 +266,12 @@ public class RedisCommand { * * @param key 键 * @param map 对应多个键值 - * @return true 成功 false 失败 */ - public boolean hmset(final String key, final Map map) { + public void hmset(final String key, final Map map) { try { redisHashOps.putAll(key, map); - return true; } catch (Exception e) { logger.error("hmset bad things happen", e); - return false; } } diff --git a/contact-center/app/src/main/java/com/cskefu/cc/cache/RedisKey.java b/contact-center/app/src/main/java/com/cskefu/cc/cache/RedisKey.java index ba4b65b0..824b3351 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/cache/RedisKey.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/cache/RedisKey.java @@ -1,17 +1,15 @@ -/* - * Copyright (C) 2019-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * +/* + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2019-2022 Chatopera Inc, , + * Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.cache; @@ -32,13 +30,11 @@ public class RedisKey { /** * 获得坐席列表指定字符串状态的KEY * - * @param orgi 租户ID * @return */ - public static String getAgentStatusHashKeyByStatusStr(final String orgi, final String status) { + public static String getAgentStatusHashKeyByStatusStr(final String status) { StringBuffer sb = new StringBuffer(); - sb.append(orgi); - sb.append(":agent:status:"); + sb.append("agent:status:"); sb.append(status); return sb.toString(); } @@ -46,21 +42,19 @@ public class RedisKey { /** * 就绪的客服列表KEY * - * @param orgi 租户ID * @return */ - public static String getAgentStatusReadyHashKey(final String orgi) { - return getAgentStatusHashKeyByStatusStr(orgi, MainContext.AgentStatusEnum.READY.toString()); + public static String getAgentStatusReadyHashKey() { + return getAgentStatusHashKeyByStatusStr(MainContext.AgentStatusEnum.READY.toString()); } /** * 未就绪的坐席 * - * @param orgi * @return */ - public static String getAgentStatusNotReadyHashKey(final String orgi) { - return getAgentStatusHashKeyByStatusStr(orgi, MainContext.AgentStatusEnum.NOTREADY.toString()); + public static String getAgentStatusNotReadyHashKey() { + return getAgentStatusHashKeyByStatusStr(MainContext.AgentStatusEnum.NOTREADY.toString()); } @@ -69,14 +63,12 @@ public class RedisKey { /** * 获得坐席访客关联列表指定字符串状态的KEY * - * @param orgi * @param status * @return */ - public static String getAgentUserHashKeyByStatusStr(final String orgi, final String status) { + public static String getAgentUserHashKeyByStatusStr(final String status) { StringBuffer sb = new StringBuffer(); - sb.append(orgi); - sb.append(":agent:user:"); + sb.append("agent:user:"); sb.append(status); return sb.toString(); } @@ -84,40 +76,36 @@ public class RedisKey { /** * 排队中的访客KEY * - * @param orgi * @return */ - public static String getAgentUserInQueHashKey(final String orgi) { - return getAgentUserHashKeyByStatusStr(orgi, MainContext.AgentUserStatusEnum.INQUENE.toString()); + public static String getAgentUserInQueHashKey() { + return getAgentUserHashKeyByStatusStr(MainContext.AgentUserStatusEnum.INQUENE.toString()); } /** * 服务中的访客 * - * @param orgi * @return */ - public static String getAgentUserInServHashKey(final String orgi) { - return getAgentUserHashKeyByStatusStr(orgi, MainContext.AgentUserStatusEnum.INSERVICE.toString()); + public static String getAgentUserInServHashKey() { + return getAgentUserHashKeyByStatusStr(MainContext.AgentUserStatusEnum.INSERVICE.toString()); } /** * 结束服务的访客 * - * @param orgi * @return */ - public static String getAgentUserEndHashKey(final String orgi) { - return getAgentUserHashKeyByStatusStr(orgi, MainContext.AgentUserStatusEnum.END.toString()); + public static String getAgentUserEndHashKey() { + return getAgentUserHashKeyByStatusStr(MainContext.AgentUserStatusEnum.END.toString()); } /** * 获得一个坐席的服务中的访客列表KEY */ - public static String getInServAgentUsersByAgentnoAndOrgi(final String agentno, final String orgi) { + public static String getInServAgentUsersByAgentno(final String agentno) { StringBuffer sb = new StringBuffer(); - sb.append(orgi); - sb.append(":agent:"); + sb.append("agent:"); sb.append(agentno); sb.append(":inserv"); return sb.toString(); @@ -129,13 +117,11 @@ public class RedisKey { /** * 存储AgentUser监控信息的存储Hash的KEY * - * @param orgi * @return */ - public static String getCustomerChatsAuditKeyByOrgi(final String orgi) { + public static String getCustomerChatsAuditKey() { StringBuffer sb = new StringBuffer(); - sb.append(orgi); - sb.append(":audit:customerchats"); + sb.append("audit:customerchats"); return sb.toString(); } @@ -145,13 +131,11 @@ public class RedisKey { /** * 获得在线访客列表 * - * @param orgi * @return */ - public static String getOnlineUserHashKey(final String orgi) { + public static String getOnlineUserHashKey() { StringBuffer sb = new StringBuffer(); - sb.append(orgi); - sb.append(":visitor:online"); + sb.append("visitor:online"); return sb.toString(); } @@ -162,65 +146,56 @@ public class RedisKey { * 包括管理员,坐席等,访客不在该列 * 在该列表中的用户代表在线的系统用户,通过浏览器或API访问了系统 * - * @param orgi * @return */ - public static String getLoginUserKey(final String auth) { + public static String getApiTokenBearerKeyWithValue(final String token) { StringBuffer sb = new StringBuffer(); - sb.append("token:"); - sb.append(auth); + sb.append("api:token:bearer:"); + sb.append(token); return sb.toString(); } /** * CallCenter Agent 相关 * - * @param orgi * @return */ - public static String getCallCenterAgentHashKeyByOrgi(final String orgi) { + public static String getCallCenterAgentHashKey() { StringBuffer sb = new StringBuffer(); - sb.append(orgi); - sb.append(":callcenter:agent"); + sb.append("callcenter:agent"); return sb.toString(); } /** * Job 相关 * - * @param orgi * @return */ - public static String getJobHashKeyByOrgi(final String orgi) { + public static String getJobHashKey() { StringBuffer sb = new StringBuffer(); - sb.append(orgi); - sb.append(":job"); + sb.append("job"); return sb.toString(); } /** * System 相关 * - * @param orgi * @return */ - public static String getSystemHashKeyByOrgi(final String orgi) { + public static String getSystemHashKey() { StringBuffer sb = new StringBuffer(); - sb.append(orgi); - sb.append(":system"); + sb.append("system"); return sb.toString(); } /** * 系统词典 * - * @param orgi * @return */ - public static String getSysDicHashKeyByOrgi(final String orgi) { + public static String getSysDicHashKey() { StringBuffer sb = new StringBuffer(); - sb.append(orgi); - sb.append(":sysdic"); + sb.append("sysdic"); return sb.toString(); } @@ -228,20 +203,16 @@ public class RedisKey { /** * 坐席会话配置相关 * - * @param orgi * @return */ - public static String getSessionConfigList(final String orgi) { + public static String getSessionConfigList() { StringBuffer sb = new StringBuffer(); - sb.append(orgi); - sb.append(":session:config:list"); + sb.append("session:config:list"); return sb.toString(); } - public static String getSessionConfig(String organid, final String orgi) { + public static String getSessionConfig(String organid) { StringBuffer sb = new StringBuffer(); - sb.append(orgi); - sb.append(":"); sb.append(organid); sb.append(":session:config"); return sb.toString(); @@ -250,10 +221,9 @@ public class RedisKey { /** * SocketIO连接相关 */ - public static String getWebIMAgentSocketIOByAgentnoAndOrgi(final String agentno, final String orgi) { + public static String getWebIMAgentSocketIOByAgentno(final String agentno) { StringBuffer sb = new StringBuffer(); - sb.append(orgi); - sb.append(":agent:socketio:"); + sb.append("agent:socketio:"); sb.append(agentno); return sb.toString(); } @@ -261,30 +231,27 @@ public class RedisKey { /** * CousultInvite 相关 */ - public static String getConsultInvitesByOrgi(final String orgi) { + public static String getConsultInvites() { StringBuffer sb = new StringBuffer(); - sb.append(orgi); - sb.append(":consultinvite"); + sb.append("consultinvite"); return sb.toString(); } /** * 和访客黑名单相关 */ - public static String getBlackEntityKeyByOrgi(final String orgi) { + public static String getBlackEntityKey() { StringBuffer sb = new StringBuffer(); - sb.append(orgi); - sb.append(":visitor:blacklist"); + sb.append("visitor:blacklist"); return sb.toString(); } /** * 系统登录用户的会话Session信息 */ - public static String getUserSessionKeyByOrgi(final String orgi) { + public static String getUserSessionKey() { StringBuffer sb = new StringBuffer(); - sb.append(orgi); - sb.append(":user:session"); + sb.append("user:session"); return sb.toString(); } diff --git a/contact-center/app/src/main/java/com/cskefu/cc/config/ActiveMQConfigure.java b/contact-center/app/src/main/java/com/cskefu/cc/config/ActiveMQConfigure.java index 00ab4eeb..05dd52e3 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/config/ActiveMQConfigure.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/config/ActiveMQConfigure.java @@ -1,23 +1,24 @@ -/* - * Copyright (C) 2019-2022 Chatopera Inc, All rights reserved. +/* + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * Copyright (C) 2019-2022 Chatopera Inc, All rights reserved. * - * This software and related documentation are provided under a license agreement containing - * restrictions on use and disclosure and are protected by intellectual property laws. - * Except as expressly permitted in your license agreement or allowed by law, you may not use, - * copy, reproduce, translate, broadcast, modify, license, transmit, distribute, exhibit, perform, - * publish, or display any part, in any form, or by any means. Reverse engineering, disassembly, - * or decompilation of this software, unless required by law for interoperability, is prohibited. */ package com.cskefu.cc.config; +import jakarta.jms.ConnectionFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.jms.annotation.EnableJms; import org.springframework.jms.config.DefaultJmsListenerContainerFactory; import org.springframework.jms.config.JmsListenerContainerFactory; -import javax.jms.ConnectionFactory; - @EnableJms @Configuration public class ActiveMQConfigure { diff --git a/contact-center/app/src/main/java/com/cskefu/cc/config/ApiRequestMatchingFilter.java b/contact-center/app/src/main/java/com/cskefu/cc/config/ApiRequestMatchingFilter.java index d06678bf..1b617742 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/config/ApiRequestMatchingFilter.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/config/ApiRequestMatchingFilter.java @@ -1,39 +1,40 @@ /* - * Copyright (C) 2017 优客服-多渠道客服系统 - * Modifications copyright (C) 2018-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2018- Jun. 2023 Chatopera Inc, , Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (C) 2017 优客服-多渠道客服系统, Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.config; import com.cskefu.cc.basic.MainContext; -import com.cskefu.cc.basic.auth.AuthToken; -import org.apache.commons.lang.StringUtils; +import com.cskefu.cc.basic.auth.BearerTokenMgr; +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus; import org.springframework.security.web.util.matcher.RequestMatcher; -import javax.servlet.*; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.*; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; +import static com.cskefu.cc.basic.Constants.AUTH_TOKEN_TYPE_BASIC; +import static com.cskefu.cc.basic.Constants.AUTH_TOKEN_TYPE_BEARER; + public class ApiRequestMatchingFilter implements Filter { private static final Logger logger = LoggerFactory.getLogger(ApiRequestMatchingFilter.class); - private RequestMatcher[] ignoredRequests; - private static AuthToken authToken; + private final RequestMatcher[] ignoredRequests; + private static BearerTokenMgr bearerTokenMgr; public ApiRequestMatchingFilter(RequestMatcher... matcher) { @@ -46,7 +47,7 @@ public class ApiRequestMatchingFilter implements Filter { String method = request.getMethod(); - if (!StringUtils.isBlank(method) && method.equalsIgnoreCase("options")) { + if (StringUtils.isNotBlank(method) && method.equalsIgnoreCase("options")) { response.setHeader("Access-Control-Allow-Origin", "*"); response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT"); response.setHeader("Access-Control-Max-Age", "3600"); @@ -65,11 +66,40 @@ public class ApiRequestMatchingFilter implements Filter { if (StringUtils.isBlank(authorization)) { authorization = request.getParameter("authorization"); } - if (StringUtils.isNotBlank(authorization) && - getAuthToken().existUserByAuth(authorization)) { - chain.doFilter(req, resp); + + if (StringUtils.isNotBlank(authorization)) { + // set the default value for backward compatibility as bear token bare metal + String authorizationTrimed = authorization; + String authorizationTokenType = AUTH_TOKEN_TYPE_BEARER; + if (authorization.startsWith(String.format("%s ", AUTH_TOKEN_TYPE_BEARER))) { + authorizationTrimed = StringUtils.substring(authorization, 7); + authorizationTokenType = AUTH_TOKEN_TYPE_BEARER; + } else if (authorization.startsWith(String.format("%s ", AUTH_TOKEN_TYPE_BASIC))) { + authorizationTrimed = StringUtils.substring(authorization, 6); + authorizationTokenType = AUTH_TOKEN_TYPE_BASIC; + } + + if (StringUtils.isNotBlank(authorizationTrimed)) { + switch (authorizationTokenType) { + case AUTH_TOKEN_TYPE_BEARER: + if (getBearerTokenMgr().existToken(authorizationTrimed)) { + chain.doFilter(req, resp); + } else { + response.sendRedirect("/auth/error"); + } + break; + case AUTH_TOKEN_TYPE_BASIC: + // TODO + response.sendRedirect("/auth/error"); + break; + default: + response.sendRedirect("/auth/error"); + } + } else { + response.sendRedirect("/auth/error"); + } } else { - response.sendRedirect("/tokens/error"); + response.sendRedirect("/auth/error"); } } else { chain.doFilter(req, resp); @@ -87,11 +117,11 @@ public class ApiRequestMatchingFilter implements Filter { } - private static AuthToken getAuthToken() { - if (authToken == null) { - authToken = MainContext.getContext().getBean(AuthToken.class); + private static BearerTokenMgr getBearerTokenMgr() { + if (bearerTokenMgr == null) { + bearerTokenMgr = MainContext.getContext().getBean(BearerTokenMgr.class); } - return authToken; + return bearerTokenMgr; } } \ No newline at end of file diff --git a/contact-center/app/src/main/java/com/cskefu/cc/config/AppCtxRefreshEventListener.java b/contact-center/app/src/main/java/com/cskefu/cc/config/AppCtxRefreshEventListener.java index 99c3379b..234abb1a 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/config/AppCtxRefreshEventListener.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/config/AppCtxRefreshEventListener.java @@ -1,18 +1,16 @@ /* - * Copyright (C) 2017 优客服-多渠道客服系统 - * Modifications copyright (C) 2018-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2018- Jun. 2023 Chatopera Inc, , Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (C) 2017 优客服-多渠道客服系统, Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.config; @@ -25,10 +23,7 @@ import com.cskefu.cc.cache.Cache; import com.cskefu.cc.model.BlackEntity; import com.cskefu.cc.model.SysDic; import com.cskefu.cc.model.SystemConfig; -import com.cskefu.cc.persistence.repository.BlackListRepository; -import com.cskefu.cc.persistence.repository.SysDicRepository; -import com.cskefu.cc.persistence.repository.SystemConfigRepository; -import com.cskefu.cc.persistence.repository.TablePropertiesRepository; +import com.cskefu.cc.persistence.repository.*; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -41,6 +36,85 @@ public class AppCtxRefreshEventListener implements ApplicationListener sysDicList = sysDicRes.findAll(); + Map> rootDictItems = new HashMap<>(); // 关联根词典及其子项 + Map rootDics = new HashMap<>(); + Set parents = new HashSet<>(); + + // 获得所有根词典 + for (final SysDic dic : sysDicList) { + if (StringUtils.equals(dic.getParentid(), "0")) { + parents.add(dic.getId()); + rootDics.put(dic.getId(), dic); + } + } + + // 向根词典中添加子项 + for (final SysDic dic : sysDicList) { + if ((!StringUtils.equals(dic.getParentid(), "0")) && + parents.contains(dic.getDicid())) { + // 不是根词典,并且包含在一个根词典内 + if (!rootDictItems.containsKey(dic.getDicid())) { + rootDictItems.put(dic.getDicid(), new ArrayList<>()); + } + rootDictItems.get(dic.getDicid()).add(dic); + } + } + + // 更新缓存 + // TODO 集群时注意!!! + // 此处为长时间的操作,如果在一个集群中,会操作共享内容,非常不可靠 + // 所以,当前代码不支持集群,需要解决启动上的这个问题! + + // 存储根词典 TODO 此处只考虑了系统默认租户 + cache.putSysDic(new ArrayList<>(rootDics.values())); + + for (final Map.Entry> entry : rootDictItems.entrySet()) { + SysDic rootDic = rootDics.get(entry.getKey()); + // 打印根词典信息 + logger.debug("[onApplicationEvent] root dict: {}, code {}, name {}, item size {}", entry.getKey(), rootDics.get(entry.getKey()).getCode(), rootDics.get(entry.getKey()).getName(), entry.getValue().size()); + // 存储子项列表 + cache.putSysDic(rootDic.getCode(), entry.getValue()); + // 存储子项成员 + cache.putSysDic(entry.getValue()); + } + + List blackList = blackListRes.findAll(); + for (final BlackEntity black : blackList) { + if (StringUtils.isNotBlank(black.getUserid())) { + if (black.getEndtime() == null || black.getEndtime().after(new Date())) { + cache.putSystemById(black.getUserid(), black); + } + } + } + + /** + * 加载系统全局配置 + */ + SystemConfigRepository systemConfigRes = event.getApplicationContext().getBean(SystemConfigRepository.class); + List configs = systemConfigRes.findAll(); + SystemConfig config = configs.size() > 0 ? configs.get(0) : null; + if (config != null) { + cache.putSystemById("systemConfig", config); + } + logger.warn("[StartedEventListener] setup Sysdicts in Redis done, strategy {}", cacheSetupStrategy); + } else { + logger.warn("[onApplicationEvent] skip initialize sysdicts."); + } + } + @Override public void onApplicationEvent(ContextRefreshedEvent event) { if (MainContext.getContext() == null) { @@ -51,80 +125,7 @@ public class AppCtxRefreshEventListener implements ApplicationListener sysDicList = sysDicRes.findAll(); - Map> rootDictItems = new HashMap<>(); // 关联根词典及其子项 - Map rootDics = new HashMap<>(); - Set parents = new HashSet<>(); - - // 获得所有根词典 - for (final SysDic dic : sysDicList) { - if (StringUtils.equals(dic.getParentid(), "0")) { - parents.add(dic.getId()); - rootDics.put(dic.getId(), dic); - } - } - - // 向根词典中添加子项 - for (final SysDic dic : sysDicList) { - if ((!StringUtils.equals(dic.getParentid(), "0")) && - parents.contains(dic.getDicid())) { - // 不是根词典,并且包含在一个根词典内 - if (!rootDictItems.containsKey(dic.getDicid())) { - rootDictItems.put(dic.getDicid(), new ArrayList()); - } - rootDictItems.get(dic.getDicid()).add(dic); - } - } - - // 更新缓存 - // TODO 集群时注意!!! - // 此处为长时间的操作,如果在一个集群中,会操作共享内容,非常不可靠 - // 所以,当前代码不支持集群,需要解决启动上的这个问题! - - // 存储根词典 TODO 此处只考虑了系统默认租户 - cache.putSysDicByOrgi(new ArrayList<>(rootDics.values()), Constants.SYSTEM_ORGI); - - for (final Map.Entry> entry : rootDictItems.entrySet()) { - SysDic rootDic = rootDics.get(entry.getKey()); - // 打印根词典信息 - logger.debug("[onApplicationEvent] root dict: {}, code {}, name {}, item size {}", entry.getKey(), rootDics.get(entry.getKey()).getCode(), rootDics.get(entry.getKey()).getName(), entry.getValue().size()); - // 存储子项列表 - cache.putSysDicByOrgi(rootDic.getCode(), Constants.SYSTEM_ORGI, entry.getValue()); - // 存储子项成员 - cache.putSysDicByOrgi(entry.getValue(), Constants.SYSTEM_ORGI); - } - - List blackList = blackListRes.findByOrgi(Constants.SYSTEM_ORGI); - for (final BlackEntity black : blackList) { - if (StringUtils.isNotBlank(black.getUserid())) { - if (black.getEndtime() == null || black.getEndtime().after(new Date())) { - cache.putSystemByIdAndOrgi(black.getUserid(), black.getOrgi(), black); - } - } - } - - /** - * 加载系统全局配置 - */ - SystemConfigRepository systemConfigRes = event.getApplicationContext().getBean(SystemConfigRepository.class); - SystemConfig config = systemConfigRes.findByOrgi(Constants.SYSTEM_ORGI); - if (config != null) { - cache.putSystemByIdAndOrgi("systemConfig", Constants.SYSTEM_ORGI, config); - } - logger.info("[StartedEventListener] setup Sysdicts in Redis done, strategy {}", cacheSetupStrategy); - } else { - logger.info("[onApplicationEvent] skip initialize sysdicts."); - } + setupSysdicCacheAndExtras(event, cacheSetupStrategy, cache, sysDicRes, blackListRes); MainUtils.initSystemArea(); @@ -140,5 +141,13 @@ public class AppCtxRefreshEventListener implements ApplicationListener { + logger.warn("[onApplicationEvent] inited JPA sql."); + }); + } } } \ No newline at end of file diff --git a/contact-center/app/src/main/java/com/cskefu/cc/config/ApplicationStartupListener.java b/contact-center/app/src/main/java/com/cskefu/cc/config/ApplicationStartupListener.java index f667de1e..774b8164 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/config/ApplicationStartupListener.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/config/ApplicationStartupListener.java @@ -1,50 +1,48 @@ /* - * Copyright (C) 2017 优客服-多渠道客服系统 - * Modifications copyright (C) 2018-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2018- Jun. 2023 Chatopera Inc, , Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (C) 2017 优客服-多渠道客服系统, Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.config; -import com.cskefu.cc.basic.MainContext; -import com.cskefu.cc.model.Favorites; -import com.cskefu.cc.model.WorkOrders; +import com.cskefu.cc.proxy.UserProxy; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.context.ApplicationListener; -import org.springframework.context.event.ContextRefreshedEvent; -import org.springframework.data.elasticsearch.ElasticsearchException; -import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; import org.springframework.stereotype.Component; @Component -public class ApplicationStartupListener implements ApplicationListener { - - @Autowired ElasticsearchTemplate elasticSearchTemplate; +public class ApplicationStartupListener implements ApplicationListener { + + final private static Logger logger = LoggerFactory.getLogger(ApplicationStartupListener.class); + + @Value("${extras.auth.super-admin.pass}") + private String superAdminPass; + + @Autowired + private UserProxy userProxy; @Override - public void onApplicationEvent(ContextRefreshedEvent event) { - if (!elasticSearchTemplate.indexExists(WorkOrders.class)) { - elasticSearchTemplate.createIndex(WorkOrders.class); + public void onApplicationEvent(final ApplicationReadyEvent event) { + if (StringUtils.isNotBlank(superAdminPass)) { + logger.warn("Reset Superadmin Password by ENV variable EXTRAS_AUTH_SUPER_ADMIN_PASS=********"); + if (!userProxy.resetAccountPasswordByUsername("admin", superAdminPass)) { + logger.error("Reset Superadmin Password failure. Check 1) admin user do exist in DB with username admin."); + } } - if (!elasticSearchTemplate.indexExists(Favorites.class)) { - elasticSearchTemplate.createIndex(Favorites.class); - } - try { - elasticSearchTemplate.getMapping(WorkOrders.class); - } catch (ElasticsearchException e) { - elasticSearchTemplate.putMapping(Favorites.class); - elasticSearchTemplate.putMapping(WorkOrders.class); - } - MainContext.setTemplet(elasticSearchTemplate); + return; } } \ No newline at end of file diff --git a/contact-center/app/src/main/java/com/cskefu/cc/config/CSKeFuExceptionHandler.java b/contact-center/app/src/main/java/com/cskefu/cc/config/CSKeFuExceptionHandler.java index 5d509a35..ace7402a 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/config/CSKeFuExceptionHandler.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/config/CSKeFuExceptionHandler.java @@ -1,18 +1,16 @@ /* - * Copyright (C) 2017 优客服-多渠道客服系统 - * Modifications copyright (C) 2018-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2018- Jun. 2023 Chatopera Inc, , Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (C) 2017 优客服-多渠道客服系统, Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.config; diff --git a/contact-center/app/src/main/java/com/cskefu/cc/config/CSKeFuWebAppConfigurer.java b/contact-center/app/src/main/java/com/cskefu/cc/config/CSKeFuWebAppConfigurer.java index 821702da..7ec87210 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/config/CSKeFuWebAppConfigurer.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/config/CSKeFuWebAppConfigurer.java @@ -1,34 +1,35 @@ /* - * Copyright (C) 2017 优客服-多渠道客服系统 - * Modifications copyright (C) 2018-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2018- Jun. 2023 Chatopera Inc, , Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (C) 2017 优客服-多渠道客服系统, Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.config; import com.cskefu.cc.interceptor.*; +import com.cskefu.cc.util.SystemEnvHelper; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Configuration; -import org.springframework.web.servlet.config.annotation.CorsRegistry; -import org.springframework.web.servlet.config.annotation.InterceptorRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; +import org.springframework.web.servlet.config.annotation.*; @Configuration -public class CSKeFuWebAppConfigurer - extends WebMvcConfigurerAdapter { - +public class CSKeFuWebAppConfigurer implements WebMvcConfigurer { + private final static Logger logger = LoggerFactory.getLogger(CSKeFuWebAppConfigurer.class); + private final static String ENABLE_LOG_REQUEST = SystemEnvHelper.parseFromApplicationProps("extras.log.request"); /** * https://www.baeldung.com/spring-cors + * * @param registry */ @Override @@ -37,6 +38,17 @@ public class CSKeFuWebAppConfigurer registry.addMapping("/**").allowedOrigins("*"); } + @Override + @SuppressWarnings("deprecation") + public void configurePathMatch(PathMatchConfigurer configurer) { + configurer.setUseSuffixPatternMatch(Boolean.TRUE); + } + + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + registry.addResourceHandler("/**").addResourceLocations("classpath:/static/"); + } + @Override public void addInterceptors(InterceptorRegistry registry) { // 多个拦截器组成一个拦截器链 @@ -45,8 +57,14 @@ public class CSKeFuWebAppConfigurer registry.addInterceptor(new UserExperiencePlanInterceptorHandler()).addPathPatterns("/**").excludePathPatterns("/im/**", "/res/image*", "/res/file*", "/cs/**", "/messenger/webhook/*"); registry.addInterceptor(new UserInterceptorHandler()).addPathPatterns("/**").excludePathPatterns("/login.html", "/im/**", "/res/image*", "/res/file*", "/cs/**", "/messenger/webhook/*"); registry.addInterceptor(new CrossInterceptorHandler()).addPathPatterns("/**"); - registry.addInterceptor(new LogIntercreptorHandler()).addPathPatterns("/**"); + + if (StringUtils.equalsIgnoreCase(ENABLE_LOG_REQUEST, "on")) { + logger.warn("Logging request into DB as in ENV: ENABLE_LOG_REQUEST=on"); + registry.addInterceptor(new RequestLogIntercreptorHandler()).addPathPatterns("/**"); + } else { + logger.info("Disable Logging request into DB."); + } + registry.addInterceptor(new ViewsInterceptorHandler()).addPathPatterns("/**"); - super.addInterceptors(registry); } } \ No newline at end of file diff --git a/contact-center/app/src/main/java/com/cskefu/cc/config/DelegateRequestMatchingFilter.java b/contact-center/app/src/main/java/com/cskefu/cc/config/DelegateRequestMatchingFilter.java index 19154952..98644f0d 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/config/DelegateRequestMatchingFilter.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/config/DelegateRequestMatchingFilter.java @@ -1,18 +1,16 @@ /* - * Copyright (C) 2017 优客服-多渠道客服系统 - * Modifications copyright (C) 2018-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2018- Jun. 2023 Chatopera Inc, , Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (C) 2017 优客服-多渠道客服系统, Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.config; @@ -21,13 +19,13 @@ import com.cskefu.cc.model.User; import org.apache.catalina.connector.ClientAbortException; import org.springframework.security.web.util.matcher.RequestMatcher; -import javax.servlet.*; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.*; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; public class DelegateRequestMatchingFilter implements Filter { - private RequestMatcher[] ignoredRequests; + private final RequestMatcher[] ignoredRequests; public DelegateRequestMatchingFilter(RequestMatcher... matcher) { this.ignoredRequests = matcher; diff --git a/contact-center/app/src/main/java/com/cskefu/cc/config/DruidConfiguration.java b/contact-center/app/src/main/java/com/cskefu/cc/config/DruidConfiguration.java deleted file mode 100644 index c7f8a21d..00000000 --- a/contact-center/app/src/main/java/com/cskefu/cc/config/DruidConfiguration.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 2017 优客服-多渠道客服系统 - * Modifications copyright (C) 2018-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.cskefu.cc.config; - -import com.alibaba.druid.support.http.StatViewServlet; -import com.alibaba.druid.support.http.WebStatFilter; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.jdbc.DatabaseDriver; -import org.springframework.boot.web.servlet.FilterRegistrationBean; -import org.springframework.boot.web.servlet.ServletRegistrationBean; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import javax.sql.DataSource; - -@Configuration -@ConditionalOnClass(com.alibaba.druid.pool.DruidDataSource.class) -@ConditionalOnProperty(name = "spring.datasource.type", havingValue = "com.alibaba.druid.pool.DruidDataSource", matchIfMissing = true) -public class DruidConfiguration { - - @SuppressWarnings("unchecked") - protected T createDataSource(DataSourceProperties properties, - Class type) { - return (T) properties.initializeDataSourceBuilder().type(type).build(); - } - - /** - * @see org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration.Tomcat 仿写的你可以去了解 - * @param properties 读入的配置 - * @return DruidDataSource - */ - @Bean - @ConfigurationProperties("spring.datasource.druid") - public com.alibaba.druid.pool.DruidDataSource dataSource(DataSourceProperties properties) { - - com.alibaba.druid.pool.DruidDataSource dataSource = createDataSource(properties, com.alibaba.druid.pool.DruidDataSource.class); - - DatabaseDriver databaseDriver = DatabaseDriver.fromJdbcUrl(properties.determineUrl()); - - String validationQuery = databaseDriver.getValidationQuery(); - if (validationQuery != null) { - dataSource.setTestOnBorrow(true); - dataSource.setValidationQuery(validationQuery); - } - - return dataSource; - } - - - /** - * 注册一个StatViewServlet - * @return - */ - @Bean - public ServletRegistrationBean DruidStatViewServle2(){ - //org.springframework.boot.context.embedded.ServletRegistrationBean提供类的进行注册. - ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(),"/druid/*"); - //添加初始化参数:initParams - //白名单: -// servletRegistrationBean.addInitParameter("allow","127.0.0.1"); - //IP黑名单 (存在共同时,deny优先于allow) : 如果满足deny的话提示:Sorry, you are not permitted to view this page. -// servletRegistrationBean.addInitParameter("deny","192.168.1.73"); - //登录查看信息的账号密码. - servletRegistrationBean.addInitParameter("loginUsername","admin"); - servletRegistrationBean.addInitParameter("loginPassword","123456"); - //是否能够重置数据. - servletRegistrationBean.addInitParameter("resetEnable","false"); - return servletRegistrationBean; - } - - /** - * 注册一个:filterRegistrationBean - * @return - */ - - @Bean - public FilterRegistrationBean druidStatFilter2(){ - FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new WebStatFilter()); - //添加过滤规则. - filterRegistrationBean.addUrlPatterns("/*"); - //添加不需要忽略的格式信息. - filterRegistrationBean.addInitParameter("exclusions","*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid2/*"); - return filterRegistrationBean; - } -} \ No newline at end of file diff --git a/contact-center/app/src/main/java/com/cskefu/cc/config/ExecutorConfig.java b/contact-center/app/src/main/java/com/cskefu/cc/config/ExecutorConfig.java index b7fd8046..f02f9544 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/config/ExecutorConfig.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/config/ExecutorConfig.java @@ -1,18 +1,16 @@ /* - * Copyright (C) 2017 优客服-多渠道客服系统 - * Modifications copyright (C) 2018-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2018- Jun. 2023 Chatopera Inc, , Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (C) 2017 优客服-多渠道客服系统, Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.config; @@ -28,8 +26,8 @@ import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; */ @Configuration public class ExecutorConfig { - private static int CORE_POOL_SIZE = 7; - private static int MAX_POOL_SIZE = 100; + private static final int CORE_POOL_SIZE = 7; + private static final int MAX_POOL_SIZE = 100; /** * 作业平台使用的线程池 diff --git a/contact-center/app/src/main/java/com/cskefu/cc/config/MessagingServerConfigure.java b/contact-center/app/src/main/java/com/cskefu/cc/config/MessagingServerConfigure.java index 07a2ba62..840bf984 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/config/MessagingServerConfigure.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/config/MessagingServerConfigure.java @@ -1,39 +1,32 @@ /* - * Copyright (C) 2017 优客服-多渠道客服系统 - * Modifications copyright (C) 2018-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2018- Jun. 2023 Chatopera Inc, , Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (C) 2017 优客服-多渠道客服系统, Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.config; -import com.cskefu.cc.basic.MainUtils; -import com.cskefu.cc.exception.InstantMessagingExceptionListener; -import com.corundumstudio.socketio.AuthorizationListener; import com.corundumstudio.socketio.Configuration; -import com.corundumstudio.socketio.HandshakeData; import com.corundumstudio.socketio.SocketIOServer; import com.corundumstudio.socketio.annotation.SpringAnnotationScanner; +import com.cskefu.cc.exception.InstantMessagingExceptionListener; +import jakarta.annotation.PreDestroy; import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.web.ServerProperties; +import org.springframework.boot.web.server.Ssl; import org.springframework.context.annotation.Bean; -import javax.annotation.PreDestroy; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; import java.io.InputStream; -import java.security.NoSuchAlgorithmException; -import java.util.Properties; @org.springframework.context.annotation.Configuration public class MessagingServerConfigure { @@ -46,9 +39,6 @@ public class MessagingServerConfigure { @Value("${cs.im.server.ssl.port}") private Integer sslPort; - @Value("${web.upload-path}") - private String path; - @Value("${uk.im.server.threads}") private String threads; @@ -63,15 +53,18 @@ public class MessagingServerConfigure { } } + @Autowired + private ServerProperties serverProperties; + @Bean - public SocketIOServer socketIOServer() throws NoSuchAlgorithmException, IOException { + public SocketIOServer socketIOServer() { Configuration config = new Configuration(); //解决对此重启服务时,netty端口被占用问题 com.corundumstudio.socketio.SocketConfig tmpConfig = new com.corundumstudio.socketio.SocketConfig(); tmpConfig.setReuseAddress(true); config.setSocketConfig(tmpConfig); -// config.setHostname("localhost"); +// config.setHostname(host); config.setPort(port); // config.getSocketConfig().setReuseAddress(true); @@ -79,38 +72,28 @@ public class MessagingServerConfigure { // config.setOrigin("*"); config.setExceptionListener(new InstantMessagingExceptionListener()); - File sslFile = new File(path, "ssl/https.properties"); - if (sslFile.exists()) { - Properties sslProperties = new Properties(); - - try (FileInputStream in = new FileInputStream(sslFile)) { - sslProperties.load(in); - } - if (StringUtils.isNotBlank(sslProperties.getProperty("key-store")) && StringUtils.isNotBlank( - sslProperties.getProperty("key-store-password"))) { - config.setKeyStorePassword(MainUtils.decryption(sslProperties.getProperty("key-store-password"))); - InputStream stream = new FileInputStream( - new File(path, "ssl/" + sslProperties.getProperty("key-store"))); - config.setKeyStore(stream); - } - } - - // config.setSSLProtocol("https"); - int workThreads = StringUtils.isNotBlank(threads) && threads.matches("[\\d]{1,6}") ? Integer.parseInt( - threads) : 100; + int workThreads = StringUtils.isNotBlank(threads) && threads.matches("[\\d]{1,6}") ? Integer.parseInt(threads) : 100; config.setWorkerThreads(workThreads); // config.setStoreFactory(new HazelcastStoreFactory()); - config.setAuthorizationListener(new AuthorizationListener() { - public boolean isAuthorized(HandshakeData data) { - return true; - } - }); + config.setAuthorizationListener(data -> true); config.getSocketConfig().setReuseAddress(true); config.getSocketConfig().setSoLinger(0); config.getSocketConfig().setTcpNoDelay(true); config.getSocketConfig().setTcpKeepAlive(true); +// ServerProperties serverProperties = applicationContext.getBean(ServerProperties.class); + + Ssl ssl = serverProperties.getSsl(); + if (ssl != null) { + String keyStore = ssl.getKeyStore(); + String keyStorePassword = ssl.getKeyStorePassword(); + if (StringUtils.isNotEmpty(keyStore) && StringUtils.isNotEmpty(keyStorePassword)) { + InputStream keyStoreStream = this.getClass().getResourceAsStream("/" + keyStore.trim().split(":")[1]); + config.setKeyStore(keyStoreStream); + config.setKeyStorePassword(keyStorePassword); + } + } return server = new SocketIOServer(config); } @@ -123,4 +106,4 @@ public class MessagingServerConfigure { public void destory() { server.stop(); } -} \ No newline at end of file +} \ No newline at end of file diff --git a/contact-center/app/src/main/java/com/cskefu/cc/config/PugConfig.java b/contact-center/app/src/main/java/com/cskefu/cc/config/PugConfig.java index 4873c045..ef3467da 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/config/PugConfig.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/config/PugConfig.java @@ -1,17 +1,15 @@ -/* - * Copyright (C) 2020 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * +/* + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2019-2022 Chatopera Inc, , + * Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.config; @@ -30,7 +28,6 @@ public class PugConfig { @Value("${spring.pug4j.template-loader-path}") private String templatePath; - @Bean public SpringTemplateLoader templateLoader() { SpringTemplateLoader templateLoader = new SpringTemplateLoader(); diff --git a/contact-center/app/src/main/java/com/cskefu/cc/config/PugCskefuViewResolver.java b/contact-center/app/src/main/java/com/cskefu/cc/config/PugCskefuViewResolver.java index 543d4922..e208bc43 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/config/PugCskefuViewResolver.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/config/PugCskefuViewResolver.java @@ -1,3 +1,13 @@ +/* + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.cskefu.cc.config; import de.neuland.pug4j.spring.view.PugView; @@ -10,7 +20,7 @@ public class PugCskefuViewResolver extends PugViewResolver { AbstractUrlBasedView view = super.buildView(viewName); if (viewName.startsWith("/resource/css")) { PugView pugView = (PugView) view; - pugView.setContentType("text/css ; charset=UTF-8"); + pugView.setContentType("text/css; charset=UTF-8"); } return view; } diff --git a/contact-center/app/src/main/java/com/cskefu/cc/config/RedisConfigure.java b/contact-center/app/src/main/java/com/cskefu/cc/config/RedisConfigure.java index 7dffa596..6c3c607b 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/config/RedisConfigure.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/config/RedisConfigure.java @@ -1,24 +1,21 @@ -/* - * Copyright (C) 2019-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * +/* + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2019-2022 Chatopera Inc, , + * Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.config; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; +import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.listener.RedisMessageListenerContainer; import java.util.concurrent.Executors; @@ -26,13 +23,10 @@ import java.util.concurrent.Executors; @Configuration public class RedisConfigure { - @Autowired - JedisConnectionFactory jedisConnectionFactory; - @Bean - RedisMessageListenerContainer redisContainer() { + RedisMessageListenerContainer redisContainer(RedisConnectionFactory redisConnectionFactory) { final RedisMessageListenerContainer container = new RedisMessageListenerContainer(); - container.setConnectionFactory(jedisConnectionFactory); + container.setConnectionFactory(redisConnectionFactory); container.setTaskExecutor(Executors.newFixedThreadPool(100)); return container; } diff --git a/contact-center/app/src/main/java/com/cskefu/cc/config/ShutdownConfig.java b/contact-center/app/src/main/java/com/cskefu/cc/config/ShutdownConfig.java index 823d59a0..59fff8a5 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/config/ShutdownConfig.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/config/ShutdownConfig.java @@ -1,12 +1,13 @@ -/* - * Copyright (C) 2022 Chatopera Inc, All rights reserved. - * - * This software and related documentation are provided under a license agreement containing - * restrictions on use and disclosure and are protected by intellectual property laws. - * Except as expressly permitted in your license agreement or allowed by law, you may not use, - * copy, reproduce, translate, broadcast, modify, license, transmit, distribute, exhibit, perform, - * publish, or display any part, in any form, or by any means. Reverse engineering, disassembly, - * or decompilation of this software, unless required by law for interoperability, is prohibited. +/** + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * Copyright Jun. 2023 Chatopera Inc. . All rights reserved. */ package com.cskefu.cc.config; diff --git a/contact-center/app/src/main/java/com/cskefu/cc/config/StringToDateConverter.java b/contact-center/app/src/main/java/com/cskefu/cc/config/StringToDateConverter.java index ee3d357e..32ef2197 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/config/StringToDateConverter.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/config/StringToDateConverter.java @@ -1,22 +1,20 @@ /* - * Copyright (C) 2017 优客服-多渠道客服系统 - * Modifications copyright (C) 2018-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2018- Jun. 2023 Chatopera Inc, , Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (C) 2017 优客服-多渠道客服系统, Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.config; -import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.StringUtils; import org.springframework.core.convert.converter.Converter; import java.text.SimpleDateFormat; diff --git a/contact-center/app/src/main/java/com/cskefu/cc/config/WebConfigBeans.java b/contact-center/app/src/main/java/com/cskefu/cc/config/WebConfigBeans.java index ae8803fc..ef313b2b 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/config/WebConfigBeans.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/config/WebConfigBeans.java @@ -1,18 +1,16 @@ /* - * Copyright (C) 2017 优客服-多渠道客服系统 - * Modifications copyright (C) 2018-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2018- Jun. 2023 Chatopera Inc, , Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (C) 2017 优客服-多渠道客服系统, Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.config; @@ -24,7 +22,7 @@ import org.springframework.web.bind.support.ConfigurableWebBindingInitializer; import org.springframework.web.multipart.support.StandardServletMultipartResolver; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; @Configuration public class WebConfigBeans { diff --git a/contact-center/app/src/main/java/com/cskefu/cc/config/WebSecurityConfig.java b/contact-center/app/src/main/java/com/cskefu/cc/config/WebSecurityConfig.java index 64c96708..ceaff2d8 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/config/WebSecurityConfig.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/config/WebSecurityConfig.java @@ -1,26 +1,32 @@ /* - * Copyright (C) 2017 优客服-多渠道客服系统 - * Modifications copyright (C) 2018-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2018- Jun. 2023 Chatopera Inc, , Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (C) 2017 优客服-多渠道客服系统, Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.config; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.config.annotation.web.configurers.CsrfConfigurer; +import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; import org.springframework.security.web.csrf.CsrfToken; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; @@ -28,29 +34,26 @@ import org.springframework.security.web.util.matcher.RequestMatcher; import org.springframework.web.filter.OncePerRequestFilter; import org.springframework.web.util.WebUtils; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import java.io.IOException; @Configuration @EnableWebSecurity -public class WebSecurityConfig extends WebSecurityConfigurerAdapter { +public class WebSecurityConfig { - @Override - protected void configure(HttpSecurity http) throws Exception { - http.addFilterAfter(tokenInfoTokenFilterSecurityInterceptor() , BasicAuthenticationFilter.class) - .antMatcher("*/*").authorizeRequests() - .anyRequest().permitAll() - .and().addFilterAfter(csrfHeaderFilter(), BasicAuthenticationFilter.class) - .addFilterAfter(apiTokenFilterSecurityInterceptor(), BasicAuthenticationFilter.class); - } @Bean - public Filter tokenInfoTokenFilterSecurityInterceptor() throws Exception - { + public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { + http + .addFilterAfter(tokenInfoTokenFilterSecurityInterceptor(), BasicAuthenticationFilter.class) + .authorizeHttpRequests(authorize -> authorize.requestMatchers("/**").permitAll()) + .csrf().disable().headers().frameOptions().sameOrigin() +// .addFilterAfter(csrfHeaderFilter(), BasicAuthenticationFilter.class) // TODO lecjy + .and().addFilterAfter(apiTokenFilterSecurityInterceptor(), BasicAuthenticationFilter.class); + http.headers().contentTypeOptions().disable(); + return http.build(); + } + + @Bean + public Filter tokenInfoTokenFilterSecurityInterceptor() throws Exception { RequestMatcher autconfig = new AntPathRequestMatcher("/autoconfig/**"); RequestMatcher configprops = new AntPathRequestMatcher("/configprops/**"); RequestMatcher beans = new AntPathRequestMatcher("/beans/**"); @@ -67,15 +70,14 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { // RequestMatcher health = new AntPathRequestMatcher("/health/**"); // RequestMatcher metrics = new AntPathRequestMatcher("/metrics/**"); // return new DelegateRequestMatchingFilter(autconfig , configprops , beans , dump , env , health , info , mappings , metrics , trace, druid); - return new DelegateRequestMatchingFilter(autconfig , configprops , beans , dump , env , mappings , trace, druid); + return new DelegateRequestMatchingFilter(autconfig, configprops, beans, dump, env, mappings, trace, druid); } - + @Bean - public Filter apiTokenFilterSecurityInterceptor() throws Exception - { + public Filter apiTokenFilterSecurityInterceptor() throws Exception { return new ApiRequestMatchingFilter(new AntPathRequestMatcher("/api/**")); } - + private Filter csrfHeaderFilter() { return new OncePerRequestFilter() { diff --git a/contact-center/app/src/main/java/com/cskefu/cc/config/WebServerContainerConfigure.java b/contact-center/app/src/main/java/com/cskefu/cc/config/WebServerContainerConfigure.java index 1c20a22a..d52bfa78 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/config/WebServerContainerConfigure.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/config/WebServerContainerConfigure.java @@ -1,27 +1,26 @@ /* - * Copyright (C) 2017 优客服-多渠道客服系统 - * Modifications copyright (C) 2018-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2018- Jun. 2023 Chatopera Inc, , Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (C) 2017 优客服-多渠道客服系统, Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.config; import org.apache.catalina.connector.Connector; +import org.apache.coyote.ProtocolHandler; import org.apache.coyote.http11.Http11NioProtocol; +import org.apache.tomcat.util.http.Rfc6265CookieProcessor; import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory; -import org.springframework.boot.context.embedded.tomcat.TomcatConnectorCustomizer; -import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory; +import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer; +import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -41,21 +40,26 @@ public class WebServerContainerConfigure { private String path; @Bean - public EmbeddedServletContainerFactory createEmbeddedServletContainerFactory() throws IOException, NoSuchAlgorithmException { - TomcatEmbeddedServletContainerFactory tomcatFactory = new TomcatEmbeddedServletContainerFactory(); + public TomcatServletWebServerFactory createEmbeddedServletContainerFactory() throws IOException, NoSuchAlgorithmException { + TomcatServletWebServerFactory tomcatFactory = new TomcatServletWebServerFactory(); tomcatFactory.addConnectorCustomizers(new CSKeFuTomcatConnectorCustomizer(maxthread, maxconnections)); + // Enable cookie value with space + // https://stackoverflow.com/questions/38687210/error-with-cookie-value-when-adding-a-new-spring-session + // TODO lecjy + tomcatFactory.addContextCustomizers(context -> context.setCookieProcessor(new Rfc6265CookieProcessor())); return tomcatFactory; } class CSKeFuTomcatConnectorCustomizer implements TomcatConnectorCustomizer { - private Integer maxthread; - private Integer maxconnection; + private final Integer maxthread; + private final Integer maxconnection; CSKeFuTomcatConnectorCustomizer(Integer maxthread, Integer maxconnection) { this.maxthread = maxthread; this.maxconnection = maxconnection; } + @Override public void customize(Connector connector) { Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler(); //设置最大连接数 diff --git a/contact-center/app/src/main/java/com/cskefu/cc/config/WebServerSessionConfigure.java b/contact-center/app/src/main/java/com/cskefu/cc/config/WebServerSessionConfigure.java index 839c3146..3c9a93c0 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/config/WebServerSessionConfigure.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/config/WebServerSessionConfigure.java @@ -1,23 +1,21 @@ -/* - * Copyright (C) 2019-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * +/* + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2019-2022 Chatopera Inc, , + * Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.config; import com.cskefu.cc.basic.auth.AuthRedisTemplate; import com.cskefu.cc.cache.RedisKey; -import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -25,10 +23,12 @@ import org.springframework.context.annotation.Primary; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.StringRedisSerializer; -import org.springframework.session.data.redis.RedisFlushMode; -import org.springframework.session.data.redis.RedisOperationsSessionRepository; +import org.springframework.session.FlushMode; +import org.springframework.session.data.redis.RedisSessionRepository; import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; +import java.time.Duration; + /** * maxInactiveIntervalInSeconds: 设置 Session 失效时间, @@ -39,22 +39,21 @@ import org.springframework.session.data.redis.config.annotation.web.http.EnableR */ @Configuration -@EnableRedisHttpSession() public class WebServerSessionConfigure { /** * spring在多长时间后强制使redis中的session失效,默认是1800.(单位/秒) */ @Value("${server.session-timeout}") - private int maxInactiveIntervalInSeconds; + private long maxInactiveIntervalInSeconds; - @Value("${spring.redis.host}") + @Value("${spring.data.redis.host}") private String host; - @Value("${spring.redis.port}") + @Value("${spring.data.redis.port}") private int port; - @Value("${spring.redis.password}") + @Value("${spring.data.redis.password}") private String pass; @Value("${spring.redis.session.db}") @@ -63,21 +62,22 @@ public class WebServerSessionConfigure { @Value("${spring.redis.token.db}") private int tokenDb; - @Value("${spring.redis.timeout}") + @Value("${spring.data.redis.timeout}") private int timeout; @Primary @Bean - public RedisOperationsSessionRepository sessionRepository(RedisTemplate sessionRedisTemplate) { - RedisOperationsSessionRepository sessionRepository = new RedisOperationsSessionRepository(sessionRedisTemplate); - sessionRepository.setDefaultMaxInactiveInterval(maxInactiveIntervalInSeconds); - sessionRepository.setRedisFlushMode(RedisFlushMode.IMMEDIATE); + // TODO lecjy + public RedisSessionRepository sessionRepository(RedisTemplate sessionRedisTemplate) { + RedisSessionRepository sessionRepository = new RedisSessionRepository(sessionRedisTemplate); + sessionRepository.setDefaultMaxInactiveInterval(Duration.ofSeconds(maxInactiveIntervalInSeconds)); + sessionRepository.setFlushMode(FlushMode.IMMEDIATE); sessionRepository.setRedisKeyNamespace(RedisKey.CACHE_SESSIONS); return sessionRepository; } @Bean - public RedisTemplate sessionRedisTemplate() { + public RedisTemplate sessionRedisTemplate() { JedisConnectionFactory factory = new JedisConnectionFactory(); factory.setHostName(host); factory.setPort(port); @@ -87,7 +87,7 @@ public class WebServerSessionConfigure { } factory.setTimeout(timeout); factory.afterPropertiesSet(); - RedisTemplate template = new RedisTemplate(); + RedisTemplate template = new RedisTemplate<>(); template.setKeySerializer(new StringRedisSerializer()); template.setHashKeySerializer(new StringRedisSerializer()); template.setConnectionFactory(factory); diff --git a/contact-center/app/src/main/java/com/cskefu/cc/controller/ApplicationController.java b/contact-center/app/src/main/java/com/cskefu/cc/controller/ApplicationController.java index c04b2e11..6fa79179 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/controller/ApplicationController.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/controller/ApplicationController.java @@ -1,18 +1,16 @@ /* - * Copyright (C) 2017 优客服-多渠道客服系统 - * Modifications copyright (C) 2018-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2018- Jun. 2023 Chatopera Inc, , Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (C) 2017 优客服-多渠道客服系统, Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.controller; @@ -22,6 +20,7 @@ import com.cskefu.cc.basic.MainContext; import com.cskefu.cc.basic.MainUtils; import com.cskefu.cc.cache.Cache; import com.cskefu.cc.model.Organ; +import com.cskefu.cc.model.PbxHost; import com.cskefu.cc.model.User; import com.cskefu.cc.persistence.repository.ExtensionRepository; import com.cskefu.cc.persistence.repository.OrganRepository; @@ -37,8 +36,8 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.servlet.ModelAndView; -import javax.servlet.http.HttpServletRequest; -import javax.validation.Valid; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.validation.Valid; import java.security.NoSuchAlgorithmException; import java.util.HashMap; import java.util.List; @@ -96,10 +95,10 @@ public class ApplicationController extends Handler { view.addObject( "skills", - organProxy.findAllOrganByParentAndOrgi(currentOrgan, super.getOrgi(request)).keySet().stream().collect(Collectors.joining(",")) + organProxy.findAllOrganByParent(currentOrgan).keySet().stream().collect(Collectors.joining(",")) ); - view.addObject("agentStatusReport", acdWorkMonitor.getAgentReport(currentOrgan != null ? currentOrgan.getId() : null, logined.getOrgi())); + view.addObject("agentStatusReport", acdWorkMonitor.getAgentReport(currentOrgan != null ? currentOrgan.getId() : null)); view.addObject("istenantshare", false); view.addObject("timeDifference", timezone.getRawOffset()); view.addObject("organList", organs); @@ -112,24 +111,23 @@ public class ApplicationController extends Handler { view.addObject("appCustomerEntity", appCustomerEntity); // 在线坐席状态信息 - view.addObject("agentStatus", cache.findOneAgentStatusByAgentnoAndOrig(logined.getId(), logined.getOrgi())); + view.addObject("agentStatus", cache.findOneAgentStatusByAgentno(logined.getId())); // 呼叫中心信息 if (MainContext.hasModule(Constants.CSKEFU_MODULE_CALLCENTER) && logined.isCallcenter()) { - extensionRes.findByAgentnoAndOrgi(logined.getId(), logined.getOrgi()).ifPresent(ext -> { - pbxHostRes.findById(ext.getHostid()).ifPresent(pbx -> { - Map webrtcData = new HashMap<>(); - webrtcData.put("callCenterWebrtcIP", pbx.getWebrtcaddress()); - webrtcData.put("callCenterWebRtcPort", pbx.getWebrtcport()); - webrtcData.put("callCenterExtensionNum", ext.getExtension()); - try { - webrtcData.put("callCenterExtensionPassword", MainUtils.decryption(ext.getPassword())); - } catch (NoSuchAlgorithmException e) { - logger.error("[admin]", e); - webrtcData.put("callCenterError", "Invalid data for callcenter agent."); - } - view.addObject("webrtc", webrtcData); - }); + extensionRes.findByAgentno(logined.getId()).ifPresent(ext -> { + PbxHost one = pbxHostRes.findById(ext.getHostid()).orElse(null); + Map webrtcData = new HashMap<>(); + webrtcData.put("callCenterWebrtcIP", one.getWebrtcaddress()); + webrtcData.put("callCenterWebRtcPort", one.getWebrtcport()); + webrtcData.put("callCenterExtensionNum", ext.getExtension()); + try { + webrtcData.put("callCenterExtensionPassword", MainUtils.decryption(ext.getPassword())); + } catch (NoSuchAlgorithmException e) { + logger.error("[admin]", e); + webrtcData.put("callCenterError", "Invalid data for callcenter agent."); + } + view.addObject("webrtc", webrtcData); }); } @@ -145,7 +143,7 @@ public class ApplicationController extends Handler { @ResponseBody public String setOrgan(HttpServletRequest request, @Valid String organ) { if (StringUtils.isNotBlank(organ)) { - Organ currentOrgan = organRepository.findByIdAndOrgi(organ, super.getOrgi(request)); + Organ currentOrgan = organRepository.findById(organ).orElse(null); if (currentOrgan != null) { request.getSession(true).setAttribute(Constants.ORGAN_SESSION_NAME, currentOrgan); } @@ -158,7 +156,7 @@ public class ApplicationController extends Handler { public ModelAndView lazyAgentStatus(HttpServletRequest request) { ModelAndView view = request(super.createView("/public/agentstatustext")); Organ currentOrgan = super.getOrgan(request); - view.addObject("agentStatusReport", acdWorkMonitor.getAgentReport(currentOrgan != null ? currentOrgan.getId() : null, super.getOrgi(request))); + view.addObject("agentStatusReport", acdWorkMonitor.getAgentReport(currentOrgan != null ? currentOrgan.getId() : null)); return view; } diff --git a/contact-center/app/src/main/java/com/cskefu/cc/controller/Handler.java b/contact-center/app/src/main/java/com/cskefu/cc/controller/Handler.java index 901a6c35..2c5becc2 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/controller/Handler.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/controller/Handler.java @@ -1,25 +1,23 @@ /* - * Copyright (C) 2017 优客服-多渠道客服系统 - * Modifications copyright (C) 2018-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2018- Jun. 2023 Chatopera Inc, , Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (C) 2017 优客服-多渠道客服系统, Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.controller; import com.cskefu.cc.basic.Constants; import com.cskefu.cc.basic.MainUtils; import com.cskefu.cc.basic.Viewport; -import com.cskefu.cc.basic.auth.AuthToken; +import com.cskefu.cc.basic.auth.BearerTokenMgr; import com.cskefu.cc.cache.Cache; import com.cskefu.cc.controller.api.QueryParams; import com.cskefu.cc.exception.CSKefuException; @@ -29,29 +27,26 @@ import com.cskefu.cc.model.User; import com.cskefu.cc.persistence.blob.JpaBlobHelper; import com.cskefu.cc.persistence.repository.StreamingFileRepository; import com.cskefu.cc.proxy.OrganProxy; - -import org.apache.commons.lang.StringUtils; -import org.elasticsearch.index.query.BoolQueryBuilder; -import org.elasticsearch.index.query.QueryBuilders; -import org.elasticsearch.index.query.QueryStringQueryBuilder; -import org.elasticsearch.index.query.QueryStringQueryBuilder.Operator; -import org.elasticsearch.index.query.RangeQueryBuilder; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.codec.binary.Base64; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; -import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.SessionAttributes; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.servlet.ModelAndView; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletRequest; import java.io.IOException; -import java.text.ParseException; +import java.io.ByteArrayInputStream; +import java.util.ArrayList; +import java.util.List; import java.util.Map; -import static org.elasticsearch.index.query.QueryBuilders.termQuery; +import static com.cskefu.cc.basic.Constants.AUTH_TOKEN_TYPE_BASIC; +import static com.cskefu.cc.basic.Constants.AUTH_TOKEN_TYPE_BEARER; @Controller @SessionAttributes @@ -68,7 +63,7 @@ public class Handler { private Cache cache; @Autowired - private AuthToken authToken; + private BearerTokenMgr bearerTokenMgr; @Autowired private OrganProxy organProxy; @@ -92,14 +87,26 @@ public class Handler { } } } + + // trim token if (StringUtils.isNotBlank(authorization)) { - user = authToken.findUserByAuth(authorization); + String authorizationTrimed = authorization; + if (authorization.startsWith(String.format("%s ", AUTH_TOKEN_TYPE_BEARER))) { + authorizationTrimed = StringUtils.substring(authorization, 7); + if (StringUtils.isNotBlank(authorizationTrimed)) { + user = bearerTokenMgr.retrieve(authorizationTrimed); + } + } else if (authorization.startsWith(String.format("%s ", AUTH_TOKEN_TYPE_BASIC))) { + authorizationTrimed = StringUtils.substring(authorization, 6); + // TODO https://gitlab.chatopera.com/chatopera/chatopera.bot/issues/1292 + // get user with basic token mgr + } } + if (user == null) { user = new User(); user.setId(MainUtils.getContextID(request.getSession().getId())); user.setUsername(Constants.GUEST_USER + "_" + MainUtils.genIDByKey(user.getId())); - user.setOrgi(Constants.SYSTEM_ORGI); user.setSessionid(user.getId()); } } else { @@ -132,15 +139,36 @@ public class Handler { } } + /** + * 获得该用户的组织机构及附属组织机构的数组 + * + * @param user + * @return + */ + public List getMyAffiliatesFlat(final User user) { + ArrayList organIds = new ArrayList<>(user.getAffiliates()); + return organIds; + } + + /** + * 获得当前用户导航的组织机构和附属组织机构的信息 + * + * @param user + * @return + */ + public List getMyCurrentAffiliatesFlat(final User user) { + ArrayList organIds = new ArrayList<>(user.getCurrOrganAffiliates()); + return organIds; + } + /** * 构建ElasticSearch基于部门查询的Filter * * @param request - * @param boolQueryBuilder * @return * @throws CSKefuException */ - public boolean esOrganFilter(final HttpServletRequest request, final BoolQueryBuilder boolQueryBuilder) + public boolean preCheckPermissions(final HttpServletRequest request) throws CSKefuException { // 组合部门条件 User u = getUser(request); @@ -160,156 +188,6 @@ public class Handler { return true; } - /** - * @param queryBuilder - * @param request - */ - public BoolQueryBuilder search(BoolQueryBuilder queryBuilder, ModelMap map, HttpServletRequest request) { - queryBuilder.must(termQuery("orgi", this.getOrgi(request))); - - // 搜索框 - if (StringUtils.isNotBlank(request.getParameter("q"))) { - String q = request.getParameter("q"); - q = q.replaceAll("(OR|AND|NOT|:|\\(|\\))", ""); - if (StringUtils.isNotBlank(q)) { - queryBuilder.must( - QueryBuilders.boolQuery().must(new QueryStringQueryBuilder(q).defaultOperator(Operator.AND))); - map.put("q", q); - } - } - - // 筛选表单 - if (StringUtils.isNotBlank(request.getParameter("filterid"))) { - queryBuilder.must(termQuery("filterid", request.getParameter("filterid"))); - map.put("filterid", request.getParameter("filterid")); - } - - // 批次 - if (StringUtils.isNotBlank(request.getParameter("batid"))) { - queryBuilder.must(termQuery("batid", request.getParameter("batid"))); - map.put("batid", request.getParameter("batid")); - } - - // 活动 - if (StringUtils.isNotBlank(request.getParameter("actid"))) { - queryBuilder.must(termQuery("actid", request.getParameter("actid"))); - map.put("actid", request.getParameter("actid")); - } - - // 业务状态 - if (StringUtils.isNotBlank(request.getParameter("workstatus"))) { - queryBuilder.must(termQuery("workstatus", request.getParameter("workstatus"))); - map.put("workstatus", request.getParameter("workstatus")); - } - - // 拨打状态 - if (StringUtils.isNotBlank(request.getParameter("callstatus"))) { - queryBuilder.must(termQuery("callstatus", request.getParameter("callstatus"))); - map.put("callstatus", request.getParameter("callstatus")); - } - - // 预约状态 - if (StringUtils.isNotBlank(request.getParameter("apstatus"))) { - queryBuilder.must(termQuery("apstatus", request.getParameter("apstatus"))); - map.put("apstatus", request.getParameter("apstatus")); - } - - RangeQueryBuilder rangeQuery = null; - // 拨打时间区间查询 - if (StringUtils.isNotBlank(request.getParameter("callbegin")) || StringUtils.isNotBlank( - request.getParameter("callend"))) { - - if (StringUtils.isNotBlank(request.getParameter("callbegin"))) { - try { - - rangeQuery = QueryBuilders.rangeQuery("calltime").from( - MainUtils.dateFormate.parse(request.getParameter("callbegin")).getTime()); - } catch (ParseException e) { - - e.printStackTrace(); - } - } - if (StringUtils.isNotBlank(request.getParameter("callend"))) { - - try { - - if (rangeQuery == null) { - rangeQuery = QueryBuilders.rangeQuery("calltime").to( - MainUtils.dateFormate.parse(request.getParameter("callend")).getTime()); - } else { - rangeQuery.to(MainUtils.dateFormate.parse(request.getParameter("callend")).getTime()); - } - } catch (ParseException e) { - - e.printStackTrace(); - } - - } - map.put("callbegin", request.getParameter("callbegin")); - map.put("callend", request.getParameter("callend")); - } - // 预约时间区间查询 - if (StringUtils.isNotBlank(request.getParameter("apbegin")) || StringUtils.isNotBlank( - request.getParameter("apend"))) { - - if (StringUtils.isNotBlank(request.getParameter("apbegin"))) { - try { - - rangeQuery = QueryBuilders.rangeQuery("aptime").from( - MainUtils.dateFormate.parse(request.getParameter("apbegin")).getTime()); - } catch (ParseException e) { - - e.printStackTrace(); - } - } - if (StringUtils.isNotBlank(request.getParameter("apend"))) { - - try { - - if (rangeQuery == null) { - rangeQuery = QueryBuilders.rangeQuery("aptime").to( - MainUtils.dateFormate.parse(request.getParameter("apend")).getTime()); - } else { - rangeQuery.to(MainUtils.dateFormate.parse(request.getParameter("apend")).getTime()); - } - } catch (ParseException e) { - - e.printStackTrace(); - } - - } - map.put("apbegin", request.getParameter("apbegin")); - map.put("apend", request.getParameter("apend")); - } - - if (rangeQuery != null) { - queryBuilder.must(rangeQuery); - } - - // 外呼任务id - if (StringUtils.isNotBlank(request.getParameter("taskid"))) { - queryBuilder.must(termQuery("taskid", request.getParameter("taskid"))); - map.put("taskid", request.getParameter("taskid")); - } - // 坐席 - if (StringUtils.isNotBlank(request.getParameter("owneruser"))) { - queryBuilder.must(termQuery("owneruser", request.getParameter("owneruser"))); - map.put("owneruser", request.getParameter("owneruser")); - } - // 部门 - if (StringUtils.isNotBlank(request.getParameter("ownerdept"))) { - queryBuilder.must(termQuery("ownerdept", request.getParameter("ownerdept"))); - map.put("ownerdept", request.getParameter("ownerdept")); - } - // 分配状态 - if (StringUtils.isNotBlank(request.getParameter("status"))) { - queryBuilder.must(termQuery("status", request.getParameter("status"))); - map.put("status", request.getParameter("status")); - } - - return queryBuilder; - } - /** * 创建或从HTTP会话中查找到访客的User对象,该对象不在数据库中,属于临时会话。 * 这个User很可能是打开一个WebIM访客聊天控件,随机生成用户名,之后和Contact关联 @@ -332,8 +210,7 @@ public class Handler { if (StringUtils.isNotBlank(nickname)) { user.setUsername(nickname); } else { - Map sessionMessage = cache.findOneSystemMapByIdAndOrgi( - request.getSession().getId(), Constants.SYSTEM_ORGI); + Map sessionMessage = cache.findOneSystemMapById(request.getSession().getId()); if (sessionMessage != null) { String struname = sessionMessage.get("username"); String strcname = sessionMessage.get("company_name"); @@ -362,8 +239,7 @@ public class Handler { if (StringUtils.isNotBlank(nickname)) { user.setUsername(nickname); } else { - Map sessionMessage = cache.findOneSystemMapByIdAndOrgi( - sessionid, Constants.SYSTEM_ORGI); + Map sessionMessage = cache.findOneSystemMapById(sessionid); if (sessionMessage != null) { String struname = sessionMessage.get("username"); String strcname = sessionMessage.get("company_name"); @@ -476,15 +352,6 @@ public class Handler { return pagesize; } - public String getOrgi() { - return Constants.SYSTEM_ORGI; - } - - // FIXME: 保存此处是为了兼容之前到代码,宜去掉 - public String getOrgi(HttpServletRequest request) { - return getOrgi(); - } - public long getStarttime() { return starttime; } @@ -511,6 +378,30 @@ public class Handler { return fileid; } + /** + * 使用Blob保存文件 + * + * @param dataStr Data URL 图片数据 + * @return id + * @throws IOException + */ + public String saveImageFileWithDataURL(String dataStr) throws IOException { + String[] cell = dataStr.split(";"); + String mime = cell[0].substring(5); + String base64Str = cell[1].substring(7); + byte[] buf = Base64.decodeBase64(base64Str); + + StreamingFile sf = new StreamingFile(); + final String fileid = MainUtils.getUUID(); + sf.setId(fileid); + sf.setMime(mime); + sf.setData(jpaBlobHelper.createBlob(new ByteArrayInputStream(buf), + buf.length)); + sf.setName(fileid); + streamingFileRes.save(sf); + return fileid; + } + public String getSchema(HttpServletRequest request) { String schema = request.getScheme(); String headerProto = request.getHeader("X-Forwarded-Proto"); diff --git a/contact-center/app/src/main/java/com/cskefu/cc/controller/LoginController.java b/contact-center/app/src/main/java/com/cskefu/cc/controller/LoginController.java index fbeb1117..8a3a5e11 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/controller/LoginController.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/controller/LoginController.java @@ -1,18 +1,16 @@ /* - * Copyright (C) 2017 优客服-多渠道客服系统 - * Modifications copyright (C) 2018-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2018- Jun. 2023 Chatopera Inc, , Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (C) 2017 优客服-多渠道客服系统, Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.controller; @@ -20,7 +18,7 @@ import com.cskefu.cc.acd.ACDWorkMonitor; import com.cskefu.cc.basic.Constants; import com.cskefu.cc.basic.MainContext; import com.cskefu.cc.basic.MainUtils; -import com.cskefu.cc.basic.auth.AuthToken; +import com.cskefu.cc.basic.auth.BearerTokenMgr; import com.cskefu.cc.model.AgentStatus; import com.cskefu.cc.model.Organ; import com.cskefu.cc.model.SystemConfig; @@ -30,9 +28,10 @@ import com.cskefu.cc.persistence.repository.UserRepository; import com.cskefu.cc.persistence.repository.UserRoleRepository; import com.cskefu.cc.proxy.AgentProxy; import com.cskefu.cc.proxy.AgentSessionProxy; +import com.cskefu.cc.proxy.OrganProxy; import com.cskefu.cc.proxy.UserProxy; import com.cskefu.cc.util.Menu; -import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.StringUtils; import org.jasypt.exceptions.EncryptionOperationNotPossibleException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -45,10 +44,10 @@ import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.servlet.ModelAndView; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.validation.Valid; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.Valid; import java.io.UnsupportedEncodingException; import java.security.NoSuchAlgorithmException; import java.util.Date; @@ -69,7 +68,7 @@ public class LoginController extends Handler { private UserRoleRepository userRoleRes; @Autowired - private AuthToken authToken; + private BearerTokenMgr bearerTokenMgr; @Autowired private AgentProxy agentProxy; @@ -119,7 +118,7 @@ public class LoginController extends Handler { @RequestMapping(value = "/login", method = RequestMethod.GET) @Menu(type = "apps", subtype = "user", access = true) public ModelAndView login(HttpServletRequest request, HttpServletResponse response, - @RequestHeader(value = "referer", required = false) String referer, @Valid String msg) { + @RequestHeader(value = "referer", required = false) String referer, @Valid String msg) { ModelAndView view = new ModelAndView("redirect:/"); if (request.getSession(true).getAttribute(Constants.USER_SESSION_NAME) == null) { view = new ModelAndView("/login"); @@ -139,7 +138,7 @@ public class LoginController extends Handler { try { flagid = MainUtils.decryption(cookie.getValue()); if (StringUtils.isNotBlank(flagid)) { - User user = userRepository.findById(flagid); + User user = userRepository.findById(flagid).orElse(null); if (user != null) { view = this.processLogin(request, user, referer); } @@ -160,9 +159,9 @@ public class LoginController extends Handler { view.addObject("msg", msg); } SystemConfig systemConfig = MainUtils.getSystemConfig(); - if (systemConfig != null && systemConfig.isEnableregorgi()) { - view.addObject("show", true); - } + + // is Enable reg tenant +// view.addObject("show", false); if (systemConfig != null) { view.addObject("systemConfig", systemConfig); } @@ -213,11 +212,11 @@ public class LoginController extends Handler { } // add authorization code for rest api - final String orgi = loginUser.getOrgi(); - String auth = MainUtils.getUUID(); - authToken.putUserByAuth(auth, loginUser); + String uuid = MainUtils.getUUID(); + String token = String.format("%s %s", Constants.AUTH_TOKEN_TYPE_BEARER, uuid); + bearerTokenMgr.update(token, loginUser); userRepository.save(loginUser); // 更新登录状态到数据库 - response.addCookie((new Cookie("authorization", auth))); + response.addCookie((new Cookie("authorization", uuid))); // 该登录用户是坐席,并且具有坐席对话的角色 if ((loginUser.isAgent() && @@ -229,8 +228,8 @@ public class LoginController extends Handler { * 登录成功,设置该坐席为就绪状态(默认) ****************************************/ // https://gitlab.chatopera.com/chatopera/cosinee.w4l/issues/306 - final AgentStatus agentStatus = agentProxy.resolveAgentStatusByAgentnoAndOrgi( - loginUser.getId(), orgi, loginUser.getSkills()); + final AgentStatus agentStatus = agentProxy.resolveAgentStatusByAgentno( + loginUser.getId(), loginUser.getSkills()); agentStatus.setBusy(false); agentProxy.ready(loginUser, agentStatus, false); @@ -243,7 +242,7 @@ public class LoginController extends Handler { MainContext.AgentStatusEnum.OFFLINE.toString(), MainContext.AgentStatusEnum.READY.toString(), MainContext.AgentWorkType.MEIDIACHAT.toString(), - orgi, null); + null); } catch (Exception e) { logger.error("[login] set agent status", e); @@ -262,9 +261,9 @@ public class LoginController extends Handler { } } SystemConfig systemConfig = MainUtils.getSystemConfig(); - if (systemConfig != null && systemConfig.isEnableregorgi()) { - view.addObject("show", true); - } + // is Enable reg tenant +// view.addObject("show", false); + if (systemConfig != null) { view.addObject("systemConfig", systemConfig); } @@ -287,7 +286,7 @@ public class LoginController extends Handler { loginUser.setLogin(true); // 更新redis session信息,用以支持sso agentSessionProxy.updateUserSession( - loginUser.getId(), MainUtils.getContextID(request.getSession().getId()), loginUser.getOrgi()); + loginUser.getId(), MainUtils.getContextID(request.getSession().getId())); loginUser.setSessionid(MainUtils.getContextID(request.getSession().getId())); if (StringUtils.isNotBlank(referer)) { @@ -302,17 +301,19 @@ public class LoginController extends Handler { && !loginUser.isAdmin()) { view = new ModelAndView("redirect:/apps/tenant/index"); } - List userRoleList = userRoleRes.findByOrgiAndUser(loginUser.getOrgi(), loginUser); + List userRoleList = userRoleRes.findByUser(loginUser); if (userRoleList != null && userRoleList.size() > 0) { for (UserRole userRole : userRoleList) { loginUser.getRoleList().add(userRole.getRole()); } } - // 获取用户部门以及下级部门 + // 获取用户所在部门及附属部门的信息 userProxy.attachOrgansPropertiesForUser(loginUser); + Organ currentOrgan = super.getOrgan(request); + userProxy.attachCurrentOrgansPropertiesForUser(loginUser, currentOrgan); // 添加角色信息 userProxy.attachRolesMap(loginUser, currentOrgan); @@ -338,7 +339,7 @@ public class LoginController extends Handler { */ @RequestMapping("/logout") public String logout(HttpServletRequest request, HttpServletResponse response, - @RequestParam(value = "code", required = false) String code) throws UnsupportedEncodingException { + @RequestParam(value = "code", required = false) String code) throws UnsupportedEncodingException { final User user = super.getUser(request); request.getSession().removeAttribute(Constants.USER_SESSION_NAME); request.getSession().invalidate(); @@ -388,7 +389,6 @@ public class LoginController extends Handler { if (StringUtils.isNotBlank(user.getPassword())) { user.setPassword(MainUtils.md5(user.getPassword())); } - user.setOrgi(super.getOrgi()); userRepository.save(user); } ModelAndView view = this.processLogin(request, user, ""); @@ -414,4 +414,4 @@ public class LoginController extends Handler { } return msg; } -} \ No newline at end of file +} diff --git a/contact-center/app/src/main/java/com/cskefu/cc/controller/admin/AdminController.java b/contact-center/app/src/main/java/com/cskefu/cc/controller/admin/AdminController.java index 8f3d7ebd..ae21de94 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/controller/admin/AdminController.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/controller/admin/AdminController.java @@ -1,18 +1,16 @@ /* - * Copyright (C) 2017 优客服-多渠道客服系统 - * Modifications copyright (C) 2018-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2018- Jun. 2023 Chatopera Inc, , Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (C) 2017 优客服-多渠道客服系统, Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.controller.admin; @@ -23,20 +21,20 @@ import com.cskefu.cc.basic.MainUtils; import com.cskefu.cc.cache.Cache; import com.cskefu.cc.controller.Handler; import com.cskefu.cc.model.User; -import com.cskefu.cc.persistence.repository.OnlineUserRepository; +import com.cskefu.cc.persistence.repository.PassportWebIMUserRepository; import com.cskefu.cc.persistence.repository.UserEventRepository; import com.cskefu.cc.persistence.repository.UserRepository; import com.cskefu.cc.proxy.OnlineUserProxy; import com.cskefu.cc.socketio.client.NettyClients; import com.cskefu.cc.util.Menu; -import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import java.util.ArrayList; import java.util.List; @@ -50,7 +48,7 @@ public class AdminController extends Handler { private UserRepository userRes; @Autowired - private OnlineUserRepository onlineUserRes; + private PassportWebIMUserRepository onlineUserRes; @Autowired private UserEventRepository userEventRes; @@ -62,46 +60,45 @@ public class AdminController extends Handler { public ModelAndView index(ModelMap map, HttpServletRequest request) { ModelAndView view = request(super.createView("redirect:/")); User user = super.getUser(request); - view.addObject("agentStatusReport", acdWorkMonitor.getAgentReport(user.getOrgi())); - view.addObject("agentStatus", cache.findOneAgentStatusByAgentnoAndOrig(user.getId(), user.getOrgi())); + view.addObject("agentStatusReport", acdWorkMonitor.getAgentReport()); + view.addObject("agentStatus", cache.findOneAgentStatusByAgentno(user.getId())); return view; } private void aggValues(ModelMap map, HttpServletRequest request) { - String orgi = super.getOrgi(request); - map.put("onlineUserCache", cache.getOnlineUserSizeByOrgi(orgi)); + map.put("onlineUserCache", cache.getOnlineUserSize()); map.put("onlineUserClients", OnlineUserProxy.webIMClients.size()); map.put("chatClients", NettyClients.getInstance().size()); - map.put("systemCaches", cache.getSystemSizeByOrgi(Constants.SYSTEM_ORGI)); + map.put("systemCaches", cache.getSystemSize()); - map.put("agentReport", acdWorkMonitor.getAgentReport(orgi)); - map.put("webIMReport", MainUtils.getWebIMReport(userEventRes.findByOrgiAndCreatetimeRange(super.getOrgi(request), MainUtils.getStartTime(), MainUtils.getEndTime()))); + map.put("agentReport", acdWorkMonitor.getAgentReport()); + map.put("webIMReport", MainUtils.getWebIMReport(userEventRes.findByCreatetimeRange(MainUtils.getStartTime(), MainUtils.getEndTime()))); map.put("agents", getAgent(request).size()); - map.put("webIMInvite", MainUtils.getWebIMInviteStatus(onlineUserRes.findByOrgiAndStatus(super.getOrgi(request), MainContext.OnlineUserStatusEnum.ONLINE.toString()))); + map.put("webIMInvite", MainUtils.getWebIMInviteStatus(onlineUserRes.findByStatus(MainContext.OnlineUserStatusEnum.ONLINE.toString()))); - map.put("inviteResult", MainUtils.getWebIMInviteResult(onlineUserRes.findByOrgiAndAgentnoAndCreatetimeRange(super.getOrgi(request), super.getUser(request).getId(), MainUtils.getStartTime(), MainUtils.getEndTime()))); + map.put("inviteResult", MainUtils.getWebIMInviteResult(onlineUserRes.findByAgentnoAndCreatetimeRange(super.getUser(request).getId(), MainUtils.getStartTime(), MainUtils.getEndTime()))); - map.put("agentUserCount", onlineUserRes.countByAgentForAgentUser(super.getOrgi(request), MainContext.AgentUserStatusEnum.INSERVICE.toString(), super.getUser(request).getId(), MainUtils.getStartTime(), MainUtils.getEndTime())); + map.put("agentUserCount", onlineUserRes.countByAgentForAgentUser(MainContext.AgentUserStatusEnum.INSERVICE.toString(), super.getUser(request).getId(), MainUtils.getStartTime(), MainUtils.getEndTime())); - map.put("agentServicesCount", onlineUserRes.countByAgentForAgentUser(super.getOrgi(request), MainContext.AgentUserStatusEnum.END.toString(), super.getUser(request).getId(), MainUtils.getStartTime(), MainUtils.getEndTime())); + map.put("agentServicesCount", onlineUserRes.countByAgentForAgentUser(MainContext.AgentUserStatusEnum.END.toString(), super.getUser(request).getId(), MainUtils.getStartTime(), MainUtils.getEndTime())); - map.put("agentServicesAvg", onlineUserRes.countByAgentForAvagTime(super.getOrgi(request), MainContext.AgentUserStatusEnum.END.toString(), super.getUser(request).getId(), MainUtils.getStartTime(), MainUtils.getEndTime())); + map.put("agentServicesAvg", onlineUserRes.countByAgentForAvagTime(MainContext.AgentUserStatusEnum.END.toString(), super.getUser(request).getId(), MainUtils.getStartTime(), MainUtils.getEndTime())); - map.put("webInviteReport", MainUtils.getWebIMInviteAgg(onlineUserRes.findByOrgiAndCreatetimeRange(super.getOrgi(request), MainContext.ChannelType.WEBIM.toString(), MainUtils.getLast30Day(), MainUtils.getEndTime()))); + map.put("webInviteReport", MainUtils.getWebIMInviteAgg(onlineUserRes.findByCreatetimeRange(MainContext.ChannelType.WEBIM.toString(), MainUtils.getLast30Day(), MainUtils.getEndTime()))); - map.put("agentConsultReport", MainUtils.getWebIMDataAgg(onlineUserRes.findByOrgiAndCreatetimeRangeForAgent(super.getOrgi(request), MainUtils.getLast30Day(), MainUtils.getEndTime()))); + map.put("agentConsultReport", MainUtils.getWebIMDataAgg(onlineUserRes.findByCreatetimeRangeForAgent(MainUtils.getLast30Day(), MainUtils.getEndTime()))); - map.put("clentConsultReport", MainUtils.getWebIMDataAgg(onlineUserRes.findByOrgiAndCreatetimeRangeForClient(super.getOrgi(request), MainUtils.getLast30Day(), MainUtils.getEndTime(), MainContext.ChannelType.WEBIM.toString()))); + map.put("clentConsultReport", MainUtils.getWebIMDataAgg(onlineUserRes.findByCreatetimeRangeForClient(MainUtils.getLast30Day(), MainUtils.getEndTime(), MainContext.ChannelType.WEBIM.toString()))); - map.put("browserConsultReport", MainUtils.getWebIMDataAgg(onlineUserRes.findByOrgiAndCreatetimeRangeForBrowser(super.getOrgi(request), MainUtils.getLast30Day(), MainUtils.getEndTime(), MainContext.ChannelType.WEBIM.toString()))); + map.put("browserConsultReport", MainUtils.getWebIMDataAgg(onlineUserRes.findByCreatetimeRangeForBrowser(MainUtils.getLast30Day(), MainUtils.getEndTime(), MainContext.ChannelType.WEBIM.toString()))); } private List getAgent(HttpServletRequest request) { //获取当前产品or租户坐席数 - List userList = userRes.findByOrgiAndAgentAndDatastatus(super.getOrgi(request), true, false); - return userList.isEmpty() ? new ArrayList() : userList; + List userList = userRes.findByAgentAndDatastatus(true, false); + return userList.isEmpty() ? new ArrayList<>() : userList; } @RequestMapping("/admin/content") @@ -118,7 +115,7 @@ public class AdminController extends Handler { } @RequestMapping("/admin/auth/infoacq") - @Menu(type = "admin", subtype = "infoacq", access = false, admin = true) + @Menu(type = "admin", subtype = "infoacq", admin = true) public ModelAndView infoacq(ModelMap map, HttpServletRequest request) { String inacq = (String) request.getSession().getAttribute(Constants.CSKEFU_SYSTEM_INFOACQ); if (StringUtils.isNotBlank(inacq)) { diff --git a/contact-center/app/src/main/java/com/cskefu/cc/controller/admin/OrganController.java b/contact-center/app/src/main/java/com/cskefu/cc/controller/admin/OrganController.java index d7a0a240..dadf3216 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/controller/admin/OrganController.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/controller/admin/OrganController.java @@ -1,18 +1,16 @@ /* - * Copyright (C) 2017 优客服-多渠道客服系统 - * Modifications copyright (C) 2018-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2018- Jun. 2023 Chatopera Inc, , Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (C) 2017 优客服-多渠道客服系统, Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.controller.admin; @@ -25,7 +23,7 @@ import com.cskefu.cc.proxy.OrganProxy; import com.cskefu.cc.proxy.UserProxy; import com.cskefu.cc.util.Menu; import com.cskefu.cc.util.json.GsonTools; -import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -34,8 +32,8 @@ import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; -import javax.servlet.http.HttpServletRequest; -import javax.validation.Valid; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.validation.Valid; import java.util.*; /** @@ -81,14 +79,14 @@ public class OrganController extends Handler { private Collection getOwnOragans(HttpServletRequest request) { Organ currentOrgan = super.getOrgan(request); - return organProxy.findAllOrganByParentAndOrgi(currentOrgan, super.getOrgi()).values(); + return organProxy.findAllOrganByParent(currentOrgan).values(); } @RequestMapping("/index") @Menu(type = "admin", subtype = "organ") public ModelAndView index(ModelMap map, HttpServletRequest request, @Valid String organ, @Valid String msg) { Organ currentOrgan = super.getOrgan(request); - List organList = organRepository.findByOrgi(super.getOrgi()); + List organList = organRepository.findAll(); map.addAttribute("organList", getOwnOragans(request)); if (organList.size() > 0) { Organ organData = null; @@ -104,22 +102,19 @@ public class OrganController extends Handler { } if (organData != null) { map.addAttribute( - "userList", userProxy.findByOrganAndOrgiAndDatastatus( + "userList", userProxy.findByOrganAndDatastatus( organData.getId(), - super.getOrgi(), false)); // 处理附属组织 - final Map affiliates = organProxy.findAllOrganByParentAndOrgi(organData, - super.getOrgi()); + final Map affiliates = organProxy.findAllOrganByParent(organData); List affiliateUsers = new ArrayList<>(); for (final Map.Entry o : affiliates.entrySet()) { if (StringUtils.equals(o.getKey(), organData.getId())) continue; - List ousers = userProxy.findByOrganAndOrgiAndDatastatus( + List ousers = userProxy.findByOrganAndDatastatus( o.getKey(), - super.getOrgi(), false); if (ousers != null && ousers.size() > 0) { for (User u : ousers) { @@ -135,8 +130,8 @@ public class OrganController extends Handler { } } map.addAttribute("currentOrgan", currentOrgan); - map.addAttribute("areaList", areaRepository.findByOrgi(super.getOrgi())); - map.addAttribute("roleList", roleRepository.findByOrgi(super.getOrgi())); + map.addAttribute("areaList", areaRepository.findAll()); + map.addAttribute("roleList", roleRepository.findAll()); map.put("msg", msg); return request(super.createView("/admin/organ/index")); } @@ -144,12 +139,12 @@ public class OrganController extends Handler { @RequestMapping("/add") @Menu(type = "admin", subtype = "organ") public ModelAndView add(ModelMap map, HttpServletRequest request, @Valid String parent, @Valid String area) { - map.addAttribute("areaList", areaRepository.findByOrgi(super.getOrgi())); + map.addAttribute("areaList", areaRepository.findAll()); if (!StringUtils.isBlank(parent)) { - map.addAttribute("organ", organRepository.findByIdAndOrgi(parent, super.getOrgi())); + map.addAttribute("organ", organRepository.findById(parent).orElse(null)); } if (!StringUtils.isBlank(area)) { - map.addAttribute("area", areaRepository.findByIdAndOrgi(area, super.getOrgi())); + map.addAttribute("area", areaRepository.findById(area).orElse(null)); } map.addAttribute("organList", getOwnOragans(request)); @@ -160,13 +155,12 @@ public class OrganController extends Handler { @RequestMapping("/save") @Menu(type = "admin", subtype = "organ") public ModelAndView save(HttpServletRequest request, @Valid Organ organ) { - Organ tempOrgan = organRepository.findByNameAndOrgi(organ.getName(), super.getOrgi(request)); + Organ tempOrgan = organRepository.findByName(organ.getName()); String msg = "admin_organ_new_success"; String firstId = null; if (tempOrgan != null) { msg = "admin_organ_update_name_not"; // 分类名字重复 } else { - organ.setOrgi(super.getOrgi()); firstId = organ.getId(); organRepository.save(organ); @@ -186,12 +180,11 @@ public class OrganController extends Handler { @RequestMapping("/seluser") @Menu(type = "admin", subtype = "seluser", admin = true) public ModelAndView seluser(ModelMap map, HttpServletRequest request, @Valid String organ) { - Map organs = organProxy.findAllOrganByParentAndOrgi(super.getOrgan(request), - super.getOrgi(request)); + Map organs = organProxy.findAllOrganByParent(super.getOrgan(request)); map.addAttribute("userList", userProxy.findUserInOrgans(organs.keySet())); - Organ organData = organRepository.findByIdAndOrgi(organ, super.getOrgi()); + Organ organData = organRepository.findById(organ).orElse(null); map.addAttribute("userOrganList", userProxy - .findByOrganAndOrgiAndDatastatus(organ, super.getOrgi(), false)); + .findByOrganAndDatastatus(organ, false)); map.addAttribute("organ", organData); return request(super.createView("/admin/organ/seluser")); } @@ -214,9 +207,9 @@ public class OrganController extends Handler { final User loginUser = super.getUser(request); if (users != null && users.length > 0) { - List chosen = new ArrayList(Arrays.asList(users)); - Organ organData = organRepository.findByIdAndOrgi(organ, super.getOrgi()); - List organUserList = userRepository.findAll(chosen); + List chosen = new ArrayList<>(Arrays.asList(users)); + Organ organData = organRepository.findById(organ).orElse(null); + List organUserList = userRepository.findAllById(chosen); for (final User user : organUserList) { OrganUser ou = organUserRes.findByUseridAndOrgan(user.getId(), organ); @@ -248,19 +241,18 @@ public class OrganController extends Handler { /** * 以下更新技能组状态 */ - AgentStatus agentStatus = cache.findOneAgentStatusByAgentnoAndOrig( - user.getId(), super.getOrgi()); + AgentStatus agentStatus = cache.findOneAgentStatusByAgentno(user.getId()); // TODO 因为一个用户可以包含在多个技能组中,所以,skill应该对应 // 一个List列表,此处需要重构Skill为列表 if (agentStatus != null) { userProxy.attachOrgansPropertiesForUser(user); agentStatus.setSkills(user.getSkills()); - cache.putAgentStatusByOrgi(agentStatus, super.getOrgi()); + cache.putAgentStatus(agentStatus); } } } - userRepository.save(organUserList); + userRepository.saveAll(organUserList); } return request(super.createView("redirect:/admin/organ/index.html?organ=" + organ)); @@ -290,8 +282,8 @@ public class OrganController extends Handler { public ModelAndView edit(ModelMap map, HttpServletRequest request, @Valid String id) { ModelAndView view = request(super.createView("/admin/organ/edit")); Organ currentOrgan = super.getOrgan(request); - map.addAttribute("areaList", areaRepository.findByOrgi(super.getOrgi())); - view.addObject("organData", organRepository.findByIdAndOrgi(id, super.getOrgi())); + map.addAttribute("areaList", areaRepository.findAll()); + view.addObject("organData", organRepository.findById(id).orElse(null)); view.addObject("isRootOrgan", id.equals(currentOrgan.getId())); map.addAttribute("organList", getOwnOragans(request)); return view; @@ -300,7 +292,7 @@ public class OrganController extends Handler { @RequestMapping("/update") @Menu(type = "admin", subtype = "organ") public ModelAndView update(HttpServletRequest request, @Valid Organ organ) { - String msg = organProxy.updateOrgan(organ, super.getOrgi(request), super.getUser(request)); + String msg = organProxy.updateOrgan(organ, super.getUser(request)); return request(super.createView( "redirect:/admin/organ/index.html?msg=" + msg + "&organ=" + organ.getId())); } @@ -316,14 +308,14 @@ public class OrganController extends Handler { } map.addAttribute("cacheList", Dict.getInstance().getDic(Constants.CSKEFU_SYSTEM_AREA_DIC)); - map.addAttribute("organData", organRepository.findByIdAndOrgi(id, super.getOrgi())); + map.addAttribute("organData", organRepository.findById(id).orElse(null)); return request(super.createView("/admin/organ/area")); } @RequestMapping("/area/update") @Menu(type = "admin", subtype = "organ") public ModelAndView areaupdate(HttpServletRequest request, @Valid Organ organ) { - Organ tempOrgan = organRepository.findByIdAndOrgi(organ.getId(), super.getOrgi()); + Organ tempOrgan = organRepository.findById(organ.getId()).orElse(null); String msg = "admin_organ_update_success"; if (tempOrgan != null) { tempOrgan.setArea(organ.getArea()); @@ -340,8 +332,8 @@ public class OrganController extends Handler { public ModelAndView delete(HttpServletRequest request, @Valid Organ organ) { String msg = "admin_organ_delete"; - Organ organSelf = organRepository.findByIdAndOrgi(organ.getId(), super.getOrgi()); - List organParentAre = organRepository.findByOrgiAndParent(organSelf.getOrgi(), organSelf.getId()); + Organ organSelf = organRepository.findById(organ.getId()).orElse(null); + List organParentAre = organRepository.findByParent(organSelf.getId()); if (organ != null && organParentAre != null && organParentAre.size() > 0) { msg = "admin_oran_not_delete"; } else if (organ != null) { @@ -359,9 +351,9 @@ public class OrganController extends Handler { @RequestMapping("/auth/save") @Menu(type = "admin", subtype = "role") public ModelAndView authsave(HttpServletRequest request, @Valid String id, @Valid String menus) { - Organ organData = organRepository.findByIdAndOrgi(id, super.getOrgi()); - List organRoleList = organRoleRes.findByOrgiAndOrgan(super.getOrgi(), organData); - organRoleRes.delete(organRoleList); + Organ organData = organRepository.findById(id).orElse(null); + List organRoleList = organRoleRes.findByOrgan(organData); + organRoleRes.deleteAll(organRoleList); if (!StringUtils.isBlank(menus)) { String[] menusarray = menus.split(","); for (String menu : menusarray) { @@ -373,7 +365,6 @@ public class OrganController extends Handler { organRole.setOrgan(organData); organRole.setCreater(super.getUser(request).getId()); - organRole.setOrgi(super.getOrgi(request)); organRole.setCreatetime(new Date()); organRoleRes.save(organRole); } diff --git a/contact-center/app/src/main/java/com/cskefu/cc/controller/admin/RoleController.java b/contact-center/app/src/main/java/com/cskefu/cc/controller/admin/RoleController.java index 601012e4..eb9571f2 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/controller/admin/RoleController.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/controller/admin/RoleController.java @@ -1,18 +1,16 @@ /* - * Copyright (C) 2017 优客服-多渠道客服系统 - * Modifications copyright (C) 2018-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2018- Jun. 2023 Chatopera Inc, , Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (C) 2017 优客服-多渠道客服系统, Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.controller.admin; @@ -27,7 +25,7 @@ import com.cskefu.cc.proxy.OrganProxy; import com.cskefu.cc.proxy.UserProxy; import com.cskefu.cc.util.Menu; import com.cskefu.cc.util.json.GsonTools; -import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -38,8 +36,8 @@ import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; -import javax.servlet.http.HttpServletRequest; -import javax.validation.Valid; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.validation.Valid; import java.util.Arrays; import java.util.Date; import java.util.List; @@ -74,7 +72,7 @@ public class RoleController extends Handler { public ModelAndView index(ModelMap map, HttpServletRequest request, @Valid String role, @Valid String msg) { Organ currentOrgan = super.getOrgan(request); - List roleList = roleRepository.findByOrgi(super.getOrgi()); + List roleList = roleRepository.findAll(); map.addAttribute("roleList", roleList); map.addAttribute("msg", msg); map.addAttribute("currentOrgan", currentOrgan); @@ -91,16 +89,15 @@ public class RoleController extends Handler { map.addAttribute("roleData", roleData = roleList.get(0)); } if (roleData != null) { - Map organs = organProxy.findAllOrganByParentAndOrgi(currentOrgan, - super.getOrgi(request)); + Map organs = organProxy.findAllOrganByParent(currentOrgan); // List userIds = userProxy.findUserIdsInOrgans(organs.keySet()); // Page userRoleList = // userRoleRes.findByOrganAndRole(currentOrgan.getId(), roleData, - // new PageRequest(super.getP(request), super.getPs(request))); + // PageRequest.of(super.getP(request), super.getPs(request))); Page userRoleList = userRoleRes.findByOrganInAndRole(organs.keySet(), roleData, - new PageRequest(super.getP(request), super.getPs(request))); + PageRequest.of(super.getP(request), super.getPs(request))); if (userRoleList.getContent().size() > 0) { for (UserRole ur : userRoleList.getContent()) { @@ -130,12 +127,11 @@ public class RoleController extends Handler { @Menu(type = "admin", subtype = "role") public ModelAndView save(HttpServletRequest request, @Valid Role role) { Organ currentOrgan = super.getOrgan(request); - Role tempRole = roleRepository.findByNameAndOrgi(role.getName(), super.getOrgi()); + Role tempRole = roleRepository.findByName(role.getName()); String msg = "admin_role_save_success"; if (tempRole != null) { msg = "admin_role_save_exist"; } else { - role.setOrgi(super.getOrgi()); role.setCreater(super.getUser(request).getId()); role.setCreatetime(new Date()); role.setUpdatetime(new Date()); @@ -150,8 +146,8 @@ public class RoleController extends Handler { public ModelAndView seluser(ModelMap map, HttpServletRequest request, @Valid String role) { Organ currentOrgan = super.getOrgan(request); map.addAttribute("userList", userProxy.findUserInOrgans(Arrays.asList(currentOrgan.getId()))); - Role roleData = roleRepository.findByIdAndOrgi(role, super.getOrgi()); - map.addAttribute("userRoleList", userRoleRes.findByOrgiAndRole(super.getOrgi(), roleData)); + Role roleData = roleRepository.findById(role).orElse(null); + map.addAttribute("userRoleList", userRoleRes.findByRole(roleData)); map.addAttribute("role", roleData); return request(super.createView("/admin/role/seluser")); } @@ -160,8 +156,8 @@ public class RoleController extends Handler { @Menu(type = "admin", subtype = "saveuser", admin = true) public ModelAndView saveuser(HttpServletRequest request, @Valid String[] users, @Valid String role) { Organ currentOrgan = super.getOrgan(request); - Role roleData = roleRepository.findByIdAndOrgi(role, super.getOrgi()); - List userRoleList = userRoleRes.findByOrganAndRole(super.getOrgi(), roleData); + Role roleData = roleRepository.findById(role).orElse(null); + List userRoleList = userRoleRes.findByRole(roleData); if (users != null && users.length > 0) { for (String user : users) { boolean exist = false; @@ -175,7 +171,6 @@ public class RoleController extends Handler { UserRole userRole = new UserRole(); userRole.setUser(new User(user)); userRole.setRole(new Role(role)); - userRole.setOrgi(super.getOrgi()); userRole.setCreater(super.getUser(request).getId()); userRole.setOrgan(currentOrgan.getId()); userRoleRes.save(userRole); @@ -189,7 +184,7 @@ public class RoleController extends Handler { @Menu(type = "admin", subtype = "role") public ModelAndView userroledelete(HttpServletRequest request, @Valid String id, @Valid String role) { if (role != null) { - userRoleRes.delete(id); + userRoleRes.deleteById(id); } return request(super.createView("redirect:/admin/role/index.html?role=" + role)); } @@ -198,18 +193,18 @@ public class RoleController extends Handler { @Menu(type = "admin", subtype = "role") public ModelAndView edit(ModelMap map, HttpServletRequest request, @Valid String id) { ModelAndView view = request(super.createView("/admin/role/edit")); - view.addObject("roleData", roleRepository.findByIdAndOrgi(id, super.getOrgi())); + view.addObject("roleData", roleRepository.findById(id).orElse(null)); return view; } @RequestMapping("/update") @Menu(type = "admin", subtype = "role") public ModelAndView update(HttpServletRequest request, @Valid Role role) { - Role tempRoleExist = roleRepository.findByNameAndOrgi(role.getName(), super.getOrgi()); + Role tempRoleExist = roleRepository.findByName(role.getName()); String msg = ""; if (tempRoleExist == null) { msg = "admin_role_update_success"; - Role tempRole = roleRepository.findByIdAndOrgi(role.getId(), super.getOrgi()); + Role tempRole = roleRepository.findById(role.getId()).orElse(null); tempRole.setName(role.getName()); tempRole.setUpdatetime(new Date()); roleRepository.save(tempRole); @@ -224,7 +219,7 @@ public class RoleController extends Handler { public ModelAndView delete(HttpServletRequest request, @Valid Role role) { String msg = "admin_role_delete"; if (role != null) { - userRoleRes.delete(userRoleRes.findByOrgiAndRole(super.getOrgi(), role)); + userRoleRes.deleteAll(userRoleRes.findByRole(role)); roleRepository.delete(role); } else { msg = "admin_role_not_exist"; @@ -241,9 +236,9 @@ public class RoleController extends Handler { map.addAttribute("resourceList", sysDicRes.findByDicid(sysDic.getId())); } map.addAttribute("sysDic", sysDic); - Role role = roleRepository.findByIdAndOrgi(id, super.getOrgi()); + Role role = roleRepository.findById(id).orElse(null); map.addAttribute("role", role); - map.addAttribute("roleAuthList", roleAuthRes.findByRoleidAndOrgi(role.getId(), super.getOrgi())); + map.addAttribute("roleAuthList", roleAuthRes.findByRoleid(role.getId())); return request(super.createView("/admin/role/auth")); } @@ -252,8 +247,8 @@ public class RoleController extends Handler { public ModelAndView authsave(HttpServletRequest request, @Valid String id, @Valid String menus) { // logger.info("[authsave] id {}, menus {}", id, menus); - List roleAuthList = roleAuthRes.findByRoleidAndOrgi(id, super.getOrgi()); - roleAuthRes.delete(roleAuthList); + List roleAuthList = roleAuthRes.findByRoleid(id); + roleAuthRes.deleteAll(roleAuthList); if (StringUtils.isNotBlank(menus)) { String[] menuarray = menus.split(","); @@ -270,7 +265,6 @@ public class RoleController extends Handler { logger.debug("[authsave] get sysdict {}, code {}, name {}, parent {}", sysDic.getId(), sysDic.getCode(), sysDic.getName(), sysDic.getParentid()); roleAuth.setCreater(super.getUser(request).getId()); - roleAuth.setOrgi(super.getOrgi()); roleAuth.setCreatetime(new Date()); roleAuth.setName(sysDic.getName()); roleAuth.setDicvalue(sysDic.getCode()); diff --git a/contact-center/app/src/main/java/com/cskefu/cc/controller/admin/UsersController.java b/contact-center/app/src/main/java/com/cskefu/cc/controller/admin/UsersController.java index f9088b34..8133c2da 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/controller/admin/UsersController.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/controller/admin/UsersController.java @@ -1,18 +1,16 @@ /* - * Copyright (C) 2017 优客服-多渠道客服系统 - * Modifications copyright (C) 2018-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2018- Jun. 2023 Chatopera Inc, , Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (C) 2017 优客服-多渠道客服系统, Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.controller.admin; @@ -21,17 +19,13 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; -import javax.servlet.http.HttpServletRequest; -import javax.validation.Valid; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.validation.Valid; import com.cskefu.cc.basic.Constants; import com.cskefu.cc.basic.MainContext; import com.cskefu.cc.controller.Handler; -import com.cskefu.cc.model.Organ; -import com.cskefu.cc.model.OrganUser; -import com.cskefu.cc.model.Role; -import com.cskefu.cc.model.User; -import com.cskefu.cc.model.UserRole; +import com.cskefu.cc.model.*; import com.cskefu.cc.persistence.repository.ExtensionRepository; import com.cskefu.cc.persistence.repository.OrganUserRepository; import com.cskefu.cc.persistence.repository.PbxHostRepository; @@ -89,7 +83,7 @@ public class UsersController extends Handler { /** * 只返回根用户:只属于该部门的非下级部门的用户 - * + * * @param map * @param request * @return @@ -103,7 +97,7 @@ public class UsersController extends Handler { organs.add(currentOrgan.getId()); map.addAttribute("currentOrgan", currentOrgan); - map.addAttribute("userList", userProxy.findUserInOrgans(organs, new PageRequest( + map.addAttribute("userList", userProxy.findUserInOrgans(organs, PageRequest.of( super.getP(request), super.getPs(request), Sort.Direction.ASC, @@ -117,8 +111,8 @@ public class UsersController extends Handler { public ModelAndView add(ModelMap map, HttpServletRequest request) { ModelAndView view = request(super.createView("/admin/user/add")); Organ currentOrgan = super.getOrgan(request); - Map organs = organProxy.findAllOrganByParentAndOrgi(currentOrgan, super.getOrgi(request)); - List sysRoles = roleRes.findByOrgi(super.getOrgi(request)); + Map organs = organProxy.findAllOrganByParent(currentOrgan); + List sysRoles = roleRes.findAll(); map.addAttribute("currentOrgan", currentOrgan); map.addAttribute("organList", organs.values()); map.addAttribute("sysRoles", sysRoles); @@ -130,17 +124,16 @@ public class UsersController extends Handler { @Menu(type = "admin", subtype = "user") public ModelAndView edit(ModelMap map, HttpServletRequest request, @Valid String id) { ModelAndView view = request(super.createView("/admin/user/edit")); - User user = userRepository.findById(id); + User user = userRepository.findById(id).orElse(null); if (user != null && MainContext.hasModule(Constants.CSKEFU_MODULE_CALLCENTER)) { // 加载呼叫中心信息 - extensionRes.findByAgentnoAndOrgi(user.getId(), user.getOrgi()).ifPresent(p -> { + extensionRes.findByAgentno(user.getId()).ifPresent(p -> { user.setExtensionId(p.getId()); user.setExtension(p); - pbxHostRes.findById(p.getHostid()).ifPresent(b -> { - user.setPbxhostId(b.getId()); - user.setPbxHost(b); - }); + PbxHost one = pbxHostRes.findById(p.getHostid()).orElse(null); + user.setPbxhostId(one.getId()); + user.setPbxHost(one); }); } view.addObject("userData", user); @@ -152,21 +145,21 @@ public class UsersController extends Handler { public ModelAndView delete(HttpServletRequest request, @Valid User user) { String msg = "admin_user_delete"; if (user != null) { - User dbUser = userRepository.getOne(user.getId()); + User dbUser = userRepository.findById(user.getId()).orElse(null); if (dbUser.isSuperadmin()) { msg = "admin_user_abandoned"; } else { // 删除用户的时候,同时删除用户对应的权限数据 - List userRole = userRoleRes.findByOrgiAndUser(super.getOrgi(), user); - userRoleRes.delete(userRole); + List userRole = userRoleRes.findByUser(user); + userRoleRes.deleteAll(userRole); // 删除用户对应的组织机构关系 List organUsers = organUserRes.findByUserid(user.getId()); - organUserRes.delete(organUsers); + organUserRes.deleteAll(organUsers); userRepository.delete(dbUser); AgentSessionProxy agentSessionProxy = MainContext.getContext().getBean(AgentSessionProxy.class); - agentSessionProxy.deleteUserSession(dbUser.getId(), dbUser.getOrgi()); + agentSessionProxy.deleteUserSession(dbUser.getId()); } } else { msg = "admin_user_not_exist"; diff --git a/contact-center/app/src/main/java/com/cskefu/cc/controller/admin/channel/SNSAccountIMController.java b/contact-center/app/src/main/java/com/cskefu/cc/controller/admin/channel/ChannelController.java similarity index 57% rename from contact-center/app/src/main/java/com/cskefu/cc/controller/admin/channel/SNSAccountIMController.java rename to contact-center/app/src/main/java/com/cskefu/cc/controller/admin/channel/ChannelController.java index 4f46a5b0..93c5ff0f 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/controller/admin/channel/SNSAccountIMController.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/controller/admin/channel/ChannelController.java @@ -1,205 +1,200 @@ -/* - * Copyright (C) 2017 优客服-多渠道客服系统 - * Modifications copyright (C) 2018-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.cskefu.cc.controller.admin.channel; - -import com.cskefu.cc.basic.MainContext; -import com.cskefu.cc.basic.MainUtils; -import com.cskefu.cc.cache.Cache; -import com.cskefu.cc.controller.Handler; -import com.cskefu.cc.model.*; -import com.cskefu.cc.persistence.repository.ConsultInviteRepository; -import com.cskefu.cc.persistence.repository.OrganRepository; -import com.cskefu.cc.persistence.repository.SNSAccountRepository; -import com.cskefu.cc.persistence.repository.SecretRepository; -import com.cskefu.cc.proxy.OrganProxy; -import com.cskefu.cc.util.Base62; -import com.cskefu.cc.util.Menu; -import org.apache.commons.lang.StringUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.PageRequest; -import org.springframework.stereotype.Controller; -import org.springframework.ui.ModelMap; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.servlet.ModelAndView; - -import javax.servlet.http.HttpServletRequest; -import javax.validation.Valid; -import java.security.NoSuchAlgorithmException; -import java.util.Date; -import java.util.List; -import java.util.Map; - -/** - * - */ -@Controller -@RequestMapping("/admin/im") -public class SNSAccountIMController extends Handler { - - @Autowired - private SNSAccountRepository snsAccountRes; - - @Autowired - private ConsultInviteRepository invite; - - @Autowired - private SecretRepository secRes; - - @Autowired - private OrganProxy organProxy; - - @Autowired - private OrganRepository organRes; - - @Autowired - private Cache cache; - - - @RequestMapping("/index") - @Menu(type = "admin", subtype = "im", access = false, admin = true) - public ModelAndView index(ModelMap map, HttpServletRequest request, @Valid String execute, @RequestParam(name = "status", required = false) String status) { - Map organs = organProxy.findAllOrganByParentAndOrgi(super.getOrgan(request), super.getOrgi(request)); - map.addAttribute("snsAccountList", snsAccountRes.findBySnstypeAndOrgiAndOrgan(MainContext.ChannelType.WEBIM.toString(), super.getOrgi(request), organs.keySet(), new PageRequest(super.getP(request), super.getPs(request)))); - - map.addAttribute("status", status); - List secretConfig = secRes.findByOrgi(super.getOrgi(request)); - if (secretConfig != null && secretConfig.size() > 0) { - map.addAttribute("secret", secretConfig.get(0)); - } - if (StringUtils.isNotBlank(execute) && execute.equals("false")) { - map.addAttribute("execute", execute); - } - return request(super.createView("/admin/channel/im/index")); - } - - @RequestMapping("/add") - @Menu(type = "admin", subtype = "send", access = false, admin = true) - public ModelAndView add(ModelMap map, HttpServletRequest request) { - Organ currentOrgan = super.getOrgan(request); - map.put("organ", currentOrgan); - return request(super.createView("/admin/channel/im/add")); - } - - @RequestMapping("/save") - @Menu(type = "admin", subtype = "weixin") - public ModelAndView save(HttpServletRequest request, - @Valid SNSAccount snsAccount) throws NoSuchAlgorithmException { - Organ currentOrgan = super.getOrgan(request); - String status = "new_webim_fail"; - if (StringUtils.isNotBlank(snsAccount.getBaseURL())) { - snsAccount.setSnsid(Base62.encode(snsAccount.getBaseURL()).toLowerCase()); - int count = snsAccountRes.countBySnsidAndOrgi(snsAccount.getSnsid(), super.getOrgi(request)); - if (count == 0) { - status = "new_webim_success"; - snsAccount.setOrgi(super.getOrgi(request)); - snsAccount.setSnstype(MainContext.ChannelType.WEBIM.toString()); - snsAccount.setCreatetime(new Date()); - User curr = super.getUser(request); - snsAccount.setCreater(curr.getId()); - snsAccount.setOrgan(currentOrgan.getId()); - - snsAccountRes.save(snsAccount); - - /** - * 同时创建CousultInvite 记录 - */ - CousultInvite coultInvite = invite.findBySnsaccountidAndOrgi(snsAccount.getSnsid(), super.getOrgi(request)); - if (coultInvite == null) { - coultInvite = new CousultInvite(); - coultInvite.setSnsaccountid(snsAccount.getSnsid()); - coultInvite.setCreate_time(new Date()); - coultInvite.setOrgi(super.getOrgi(request)); - coultInvite.setName(snsAccount.getName()); - coultInvite.setOwner(snsAccount.getCreater()); - coultInvite.setSkill(false); // 不启动技能组 - coultInvite.setConsult_skill_fixed(false); // 不绑定唯一技能组 - coultInvite.setAi(false); - coultInvite.setAifirst(false); - invite.save(coultInvite); - } - } - } - return request(super.createView("redirect:/admin/im/index.html?status=" + status)); - } - - @RequestMapping("/delete") - @Menu(type = "weixin", subtype = "delete") - public ModelAndView delete(ModelMap map, HttpServletRequest request, @Valid String id, @Valid String confirm) { - boolean execute; - if (execute = MainUtils.secConfirm(secRes, super.getOrgi(request), confirm)) { - SNSAccount snsAccount = snsAccountRes.findByIdAndOrgi(id, super.getOrgi(request)); - if (snsAccountRes != null) { - // 删除网站渠道记录 - snsAccountRes.delete(snsAccount); - /** - * 删除网站渠道客服配置 - */ - CousultInvite coultInvite = invite.findBySnsaccountidAndOrgi(snsAccount.getSnsid(), super.getOrgi(request)); - if (coultInvite != null) { - invite.delete(coultInvite); - } - // 删除缓存 - cache.deleteConsultInviteBySnsidAndOrgi(snsAccount.getSnsid(), super.getOrgi(request)); - } - } - - return request(super.createView("redirect:/admin/im/index.html?execute=" + execute)); - } - - @RequestMapping("/edit") - @Menu(type = "admin", subtype = "send", access = false, admin = true) - public ModelAndView edit(ModelMap map, HttpServletRequest request, @Valid String id) { - SNSAccount snsAccount = snsAccountRes.findByIdAndOrgi(id, super.getOrgi(request)); - Organ organ = organRes.findOne(snsAccount.getOrgan()); - map.put("organ", organ); - map.addAttribute("snsAccount", snsAccount); - return request(super.createView("/admin/channel/im/edit")); - } - - @RequestMapping("/update") - @Menu(type = "admin", subtype = "send", access = false, admin = true) - public ModelAndView update(HttpServletRequest request, @Valid SNSAccount snsAccount) throws NoSuchAlgorithmException { - SNSAccount oldSnsAccount = snsAccountRes.findByIdAndOrgi(snsAccount.getId(), super.getOrgi(request)); - if (oldSnsAccount != null) { - oldSnsAccount.setName(snsAccount.getName()); - oldSnsAccount.setBaseURL(snsAccount.getBaseURL()); - oldSnsAccount.setUpdatetime(new Date()); - /** - * SNSID如果有变更,需要同时变更 CoultInvite 表的 记录 - */ - if (StringUtils.isNotBlank(oldSnsAccount.getSnsid())) { - CousultInvite coultInvite = invite.findBySnsaccountidAndOrgi(oldSnsAccount.getSnsid(), super.getOrgi(request)); - if (coultInvite == null) { - /** - * 同时创建CousultInvite 记录 - */ - coultInvite = new CousultInvite(); - coultInvite.setSnsaccountid(oldSnsAccount.getSnsid()); - coultInvite.setCreate_time(new Date()); - coultInvite.setOrgi(super.getOrgi(request)); - coultInvite.setName(snsAccount.getName()); - invite.save(coultInvite); - } - } - - oldSnsAccount.setSnstype(MainContext.ChannelType.WEBIM.toString()); - snsAccountRes.save(oldSnsAccount); - } - return request(super.createView("redirect:/admin/im/index.html")); - } +/* + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * Copyright (C) 2018- Jun. 2023 Chatopera Inc, , Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (C) 2017 优客服-多渠道客服系统, Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 + */ +package com.cskefu.cc.controller.admin.channel; + +import com.cskefu.cc.basic.MainContext; +import com.cskefu.cc.basic.MainUtils; +import com.cskefu.cc.cache.Cache; +import com.cskefu.cc.controller.Handler; +import com.cskefu.cc.model.*; +import com.cskefu.cc.persistence.repository.ConsultInviteRepository; +import com.cskefu.cc.persistence.repository.OrganRepository; +import com.cskefu.cc.persistence.repository.ChannelRepository; +import com.cskefu.cc.persistence.repository.SecretRepository; +import com.cskefu.cc.proxy.OrganProxy; +import com.cskefu.cc.util.Base62; +import com.cskefu.cc.util.Menu; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.servlet.ModelAndView; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.validation.Valid; +import java.security.NoSuchAlgorithmException; +import java.util.Date; +import java.util.List; +import java.util.Map; + +/** + * + */ +@Controller +@RequestMapping("/admin/im") +public class ChannelController extends Handler { + + @Autowired + private ChannelRepository snsAccountRes; + + @Autowired + private ConsultInviteRepository invite; + + @Autowired + private SecretRepository secRes; + + @Autowired + private OrganProxy organProxy; + + @Autowired + private OrganRepository organRes; + + @Autowired + private Cache cache; + + + @RequestMapping("/index") + @Menu(type = "admin", subtype = "im", admin = true) + public ModelAndView index(ModelMap map, HttpServletRequest request, @Valid String execute, @RequestParam(name = "status", required = false) String status) { + Map organs = organProxy.findAllOrganByParent(super.getOrgan(request)); + map.addAttribute("snsAccountList", snsAccountRes.findByTypeAndOrgan(MainContext.ChannelType.WEBIM.toString(), organs.keySet(), PageRequest.of(super.getP(request), super.getPs(request)))); + + map.addAttribute("status", status); + List secretConfig = secRes.findAll(); + if (secretConfig != null && secretConfig.size() > 0) { + map.addAttribute("secret", secretConfig.get(0)); + } + if (StringUtils.isNotBlank(execute) && execute.equals("false")) { + map.addAttribute("execute", execute); + } + return request(super.createView("/admin/channel/im/index")); + } + + @RequestMapping("/add") + @Menu(type = "admin", subtype = "send", admin = true) + public ModelAndView add(ModelMap map, HttpServletRequest request) { + Organ currentOrgan = super.getOrgan(request); + map.put("organ", currentOrgan); + return request(super.createView("/admin/channel/im/add")); + } + + @RequestMapping("/save") + @Menu(type = "admin", subtype = "weixin") + public ModelAndView save(HttpServletRequest request, + @Valid Channel channel) throws NoSuchAlgorithmException { + Organ currentOrgan = super.getOrgan(request); + String status = "new_webim_fail"; + if (StringUtils.isNotBlank(channel.getBaseURL())) { + channel.setSnsid(Base62.encode(channel.getBaseURL()).toLowerCase()); + int count = snsAccountRes.countBySnsid(channel.getSnsid()); + if (count == 0) { + status = "new_webim_success"; + channel.setType(MainContext.ChannelType.WEBIM.toString()); + channel.setCreatetime(new Date()); + User curr = super.getUser(request); + channel.setCreater(curr.getId()); + channel.setOrgan(currentOrgan.getId()); + + snsAccountRes.save(channel); + + /** + * 同时创建CousultInvite 记录 + */ + CousultInvite coultInvite = invite.findBySnsaccountid(channel.getSnsid()); + if (coultInvite == null) { + coultInvite = new CousultInvite(); + coultInvite.setSnsaccountid(channel.getSnsid()); + coultInvite.setCreate_time(new Date()); + coultInvite.setName(channel.getName()); + coultInvite.setOwner(channel.getCreater()); + coultInvite.setSkill(false); // 不启动技能组 + coultInvite.setConsult_skill_fixed(false); // 不绑定唯一技能组 + coultInvite.setAi(false); + coultInvite.setAifirst(false); + invite.save(coultInvite); + } + } + } + return request(super.createView("redirect:/admin/im/index.html?status=" + status)); + } + + @RequestMapping("/delete") + @Menu(type = "weixin", subtype = "delete") + public ModelAndView delete(ModelMap map, HttpServletRequest request, @Valid String id, @Valid String confirm) { + boolean execute; + if (execute = MainUtils.secConfirm(secRes, confirm)) { + Channel channel = snsAccountRes.findById(id).orElse(null); + if (snsAccountRes != null) { + // 删除网站渠道记录 + snsAccountRes.delete(channel); + /** + * 删除网站渠道客服配置 + */ + CousultInvite coultInvite = invite.findBySnsaccountid(channel.getSnsid()); + if (coultInvite != null) { + invite.delete(coultInvite); + } + // 删除缓存 + cache.deleteConsultInviteBySnsid(channel.getSnsid()); + } + } + + return request(super.createView("redirect:/admin/im/index.html?execute=" + execute)); + } + + @RequestMapping("/edit") + @Menu(type = "admin", subtype = "send", admin = true) + public ModelAndView edit(ModelMap map, HttpServletRequest request, @Valid String id) { + Channel channel = snsAccountRes.findById(id).orElse(null); + Organ organ = organRes.findById(channel.getOrgan()).orElse(null); + map.put("organ", organ); + map.addAttribute("channel", channel); + return request(super.createView("/admin/channel/im/edit")); + } + + @RequestMapping("/update") + @Menu(type = "admin", subtype = "send", admin = true) + public ModelAndView update(HttpServletRequest request, @Valid Channel channel) throws NoSuchAlgorithmException { + Channel oldChannel = snsAccountRes.findById(channel.getId()).orElse(null); + if (oldChannel != null) { + oldChannel.setName(channel.getName()); + oldChannel.setBaseURL(channel.getBaseURL()); + oldChannel.setUpdatetime(new Date()); + /** + * SNSID如果有变更,需要同时变更 CoultInvite 表的 记录 + */ + if (StringUtils.isNotBlank(oldChannel.getSnsid())) { + CousultInvite coultInvite = invite.findBySnsaccountid(oldChannel.getSnsid()); + if (coultInvite == null) { + /** + * 同时创建CousultInvite 记录 + */ + coultInvite = new CousultInvite(); + coultInvite.setSnsaccountid(oldChannel.getSnsid()); + coultInvite.setCreate_time(new Date()); + coultInvite.setName(channel.getName()); + invite.save(coultInvite); + } + } + + oldChannel.setType(MainContext.ChannelType.WEBIM.toString()); + snsAccountRes.save(oldChannel); + } + return request(super.createView("redirect:/admin/im/index.html")); + } } \ No newline at end of file diff --git a/contact-center/app/src/main/java/com/cskefu/cc/controller/admin/channel/WebIMController.java b/contact-center/app/src/main/java/com/cskefu/cc/controller/admin/channel/WebIMController.java index 895bbf4a..f4970096 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/controller/admin/channel/WebIMController.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/controller/admin/channel/WebIMController.java @@ -1,18 +1,16 @@ /* - * Copyright (C) 2017 优客服-多渠道客服系统 - * Modifications copyright (C) 2018-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2018- Jun. 2023 Chatopera Inc, , Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (C) 2017 优客服-多渠道客服系统, Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.controller.admin.channel; @@ -20,11 +18,12 @@ import com.cskefu.cc.cache.Cache; import com.cskefu.cc.controller.Handler; import com.cskefu.cc.model.CousultInvite; import com.cskefu.cc.model.Organ; +import com.cskefu.cc.model.Channel; import com.cskefu.cc.model.User; import com.cskefu.cc.persistence.repository.*; import com.cskefu.cc.proxy.OnlineUserProxy; import com.cskefu.cc.util.Menu; -import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -36,11 +35,12 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.servlet.ModelAndView; -import javax.servlet.http.HttpServletRequest; -import javax.validation.Valid; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.validation.Valid; import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.Optional; @Controller @RequestMapping("/admin/webim") @@ -63,7 +63,7 @@ public class WebIMController extends Handler { private String path; @Autowired - private SNSAccountRepository snsAccountRes; + private ChannelRepository snsAccountRes; @Autowired private Cache cache; @@ -71,15 +71,17 @@ public class WebIMController extends Handler { @RequestMapping("/index") @Menu(type = "app", subtype = "app", admin = true) public ModelAndView index(ModelMap map, HttpServletRequest request, @Valid String snsid) { - CousultInvite coultInvite = OnlineUserProxy.consult(snsid, super.getOrgi(request)); - logger.info("[index] snsaccount Id {}, Ai {}, Aifirst {}, Ainame {}, Aisuccess {}, Aiid {}", coultInvite.getSnsaccountid(), coultInvite.isAi(), coultInvite.isAifirst(), coultInvite.getAiname(), coultInvite.getAisuccesstip(), coultInvite.getAiid()); + CousultInvite coultInvite = OnlineUserProxy.consult(snsid); if (coultInvite != null) { + logger.info("[index] snsaccount Id {}, Ai {}, Aifirst {}, Ainame {}, Aisuccess {}, Aiid {}", coultInvite.getSnsaccountid(), coultInvite.isAi(), coultInvite.isAifirst(), coultInvite.getAiname(), coultInvite.getAisuccesstip(), coultInvite.getAiid()); map.addAttribute("inviteData", coultInvite); map.addAttribute("skillGroups", getSkillGroups(request)); map.addAttribute("agentList", getUsers(request)); map.addAttribute("port", request.getServerPort()); - map.addAttribute("snsAccount", snsAccountRes.findBySnsidAndOrgi(snsid, super.getOrgi(request))); + + Optional snsAccountOpt = snsAccountRes.findBySnsid(snsid); + snsAccountOpt.ifPresent(snsAccount -> map.addAttribute("channel", snsAccount)); } return request(super.createView("/admin/webim/index")); } @@ -101,20 +103,19 @@ public class WebIMController extends Handler { logger.info("[save] snsaccount Id {}, Ai {}, Aifirst {}, Ainame {}, Aisuccess {}, Aiid {}", inviteData.getSnsaccountid(), inviteData.isAi(), inviteData.isAifirst(), inviteData.getAiname(), inviteData.getAisuccesstip(), inviteData.getAiid()); if (StringUtils.isNotBlank(inviteData.getSnsaccountid())) { - CousultInvite tempData = inviteRes.findBySnsaccountidAndOrgi(inviteData.getSnsaccountid(), super.getOrgi(request)); + CousultInvite tempData = inviteRes.findBySnsaccountid(inviteData.getSnsaccountid()); if (tempData != null) { tempData.setConsult_vsitorbtn_model(inviteData.getConsult_vsitorbtn_model()); tempData.setConsult_vsitorbtn_color(inviteData.getConsult_vsitorbtn_color()); tempData.setConsult_vsitorbtn_position(inviteData.getConsult_vsitorbtn_position()); tempData.setConsult_vsitorbtn_content(inviteData.getConsult_vsitorbtn_content()); - tempData.setConsult_vsitorbtn_display(inviteData.getConsult_vsitorbtn_display()); + tempData.setConsult_vsitorbtn_delay(inviteData.getConsult_vsitorbtn_delay()); tempData.setConsult_dialog_color(inviteData.getConsult_dialog_color()); inviteData = tempData; } } else { inviteData.setSnsaccountid(super.getUser(request).getId()); } - inviteData.setOrgi(super.getOrgi(request)); // 网页品牌标识 if (webimlogo != null && webimlogo.getOriginalFilename().lastIndexOf(".") > 0) { inviteData.setConsult_dialog_logo(super.saveImageFileWithMultipart(webimlogo)); @@ -125,32 +126,31 @@ public class WebIMController extends Handler { inviteData.setConsult_dialog_headimg(super.saveImageFileWithMultipart(agentheadimg)); } inviteRes.save(inviteData); - cache.putConsultInviteByOrgi(inviteData.getOrgi(), inviteData); + cache.putConsultInvite(inviteData); return request(super.createView("redirect:/admin/webim/index.html?snsid=" + inviteData.getSnsaccountid())); } @RequestMapping("/profile") @Menu(type = "app", subtype = "profile", admin = true) public ModelAndView profile(ModelMap map, HttpServletRequest request, @Valid String snsid) { - CousultInvite coultInvite = OnlineUserProxy.consult(snsid, super.getOrgi(request)); - logger.info("[profile] snsaccount Id {}, Ai {}, Aifirst {}, Ainame {}, Aisuccess {}, Aiid {}", coultInvite.getSnsaccountid(), coultInvite.isAi(), coultInvite.isAifirst(), coultInvite.getAiname(), coultInvite.getAisuccesstip(), coultInvite.getAiid()); + CousultInvite coultInvite = OnlineUserProxy.consult(snsid); if (coultInvite != null) { + logger.info("[profile] snsaccount Id {}, Ai {}, Aifirst {}, Ainame {}, Aisuccess {}, Aiid {}", coultInvite.getSnsaccountid(), coultInvite.isAi(), coultInvite.isAifirst(), coultInvite.getAiname(), coultInvite.getAisuccesstip(), coultInvite.getAiid()); map.addAttribute("inviteData", coultInvite); map.addAttribute("skillGroups", getSkillGroups(request)); } map.addAttribute("import", request.getServerPort()); - map.addAttribute("snsAccount", snsAccountRes.findBySnsidAndOrgi(snsid, super.getOrgi(request))); + Optional snsAccountOpt = snsAccountRes.findBySnsid(snsid); + snsAccountOpt.ifPresent(snsAccount -> map.addAttribute("channel", snsAccount)); - map.put("serviceAiList", serviceAiRes.findByOrgi(super.getOrgi(request))); + map.put("serviceAiList", serviceAiRes.findAll()); return request(super.createView("/admin/webim/profile")); } @RequestMapping("/profile/save") @Menu(type = "admin", subtype = "profile", admin = true) public ModelAndView saveprofile(HttpServletRequest request, @Valid CousultInvite inviteData, @RequestParam(value = "dialogad", required = false) MultipartFile dialogad) throws IOException { - final String orgi = super.getOrgi(request); - CousultInvite tempInviteData; logger.info("[profile/save] snsaccount Id {}, Ai {}, Aifirst {}, Ainame {}, Aisuccess {}, Aiid {}, traceUser {}", inviteData.getSnsaccountid(), @@ -163,7 +163,7 @@ public class WebIMController extends Handler { if (inviteData != null && StringUtils.isNotBlank(inviteData.getId())) { // 从Cache及DB加载consult - tempInviteData = OnlineUserProxy.consult(inviteData.getSnsaccountid(), orgi); + tempInviteData = OnlineUserProxy.consult(inviteData.getSnsaccountid()); if (tempInviteData != null) { tempInviteData.setDialog_name(inviteData.getDialog_name()); @@ -227,21 +227,22 @@ public class WebIMController extends Handler { inviteRes.save(inviteData); } - cache.putConsultInviteByOrgi(orgi, inviteData); + cache.putConsultInvite(inviteData); return request(super.createView("redirect:/admin/webim/profile.html?snsid=" + inviteData.getSnsaccountid())); } @RequestMapping("/invote") @Menu(type = "app", subtype = "invote", admin = true) public ModelAndView invote(ModelMap map, HttpServletRequest request, @Valid String snsid) { - CousultInvite coultInvite = OnlineUserProxy.consult(snsid, super.getOrgi(request)); - logger.info("[invote] snsaccount Id {}, Ai {}, Aifirst {}, Ainame {}, Aisuccess {}, Aiid {}", coultInvite.getSnsaccountid(), coultInvite.isAi(), coultInvite.isAifirst(), coultInvite.getAiname(), coultInvite.getAisuccesstip(), coultInvite.getAiid()); + CousultInvite coultInvite = OnlineUserProxy.consult(snsid); if (coultInvite != null) { + logger.info("[invote] snsaccount Id {}, Ai {}, Aifirst {}, Ainame {}, Aisuccess {}, Aiid {}", coultInvite.getSnsaccountid(), coultInvite.isAi(), coultInvite.isAifirst(), coultInvite.getAiname(), coultInvite.getAisuccesstip(), coultInvite.getAiid()); map.addAttribute("inviteData", coultInvite); } map.addAttribute("import", request.getServerPort()); - map.addAttribute("snsAccount", snsAccountRes.findBySnsidAndOrgi(snsid, super.getOrgi(request))); + Optional snsAccountOpt = snsAccountRes.findBySnsid(snsid); + snsAccountOpt.ifPresent(snsAccount -> map.addAttribute("channel", snsAccount)); return request(super.createView("/admin/webim/invote")); } @@ -252,7 +253,7 @@ public class WebIMController extends Handler { logger.info("[invote/save] snsaccount Id {}, Ai {}, Aifirst {}, Ainame {}, Aisuccess {}, Aiid {}", inviteData.getSnsaccountid(), inviteData.isAi(), inviteData.isAifirst(), inviteData.getAiname(), inviteData.getAisuccesstip(), inviteData.getAiid()); if (inviteData != null && StringUtils.isNotBlank(inviteData.getId())) { - tempInviteData = OnlineUserProxy.consult(inviteData.getSnsaccountid(), super.getOrgi(request)); + tempInviteData = OnlineUserProxy.consult(inviteData.getSnsaccountid()); if (tempInviteData != null) { tempInviteData.setConsult_invite_enable(inviteData.isConsult_invite_enable()); tempInviteData.setConsult_invite_content(inviteData.getConsult_invite_content()); @@ -271,7 +272,7 @@ public class WebIMController extends Handler { } else { inviteRes.save(inviteData); } - cache.putConsultInviteByOrgi(inviteData.getOrgi(), inviteData); + cache.putConsultInvite(inviteData); return request(super.createView("redirect:/admin/webim/invote.html?snsid=" + inviteData.getSnsaccountid())); } @@ -283,7 +284,7 @@ public class WebIMController extends Handler { */ private List getSkillGroups(HttpServletRequest request) { List skillgroups = new ArrayList<>(); - List allgroups = organRes.findByOrgi(super.getOrgi(request)); + List allgroups = organRes.findAll(); for (Organ o : allgroups) { if (o.isSkill()) { skillgroups.add(o); @@ -299,7 +300,7 @@ public class WebIMController extends Handler { * @return */ private List getUsers(HttpServletRequest request) { - List userList = userRes.findByOrgiAndAgentAndDatastatus(super.getOrgi(request), true, false); + List userList = userRes.findByAgentAndDatastatus(true, false); return userList; } } \ No newline at end of file diff --git a/contact-center/app/src/main/java/com/cskefu/cc/controller/admin/config/SystemConfigController.java b/contact-center/app/src/main/java/com/cskefu/cc/controller/admin/config/SystemConfigController.java index 38ed0ac1..195cfe68 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/controller/admin/config/SystemConfigController.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/controller/admin/config/SystemConfigController.java @@ -1,18 +1,16 @@ /* - * Copyright (C) 2017 优客服-多渠道客服系统 - * Modifications copyright (C) 2018-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2018- Jun. 2023 Chatopera Inc, , Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (C) 2017 优客服-多渠道客服系统, Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.controller.admin.config; @@ -32,10 +30,8 @@ import com.cskefu.cc.persistence.repository.SystemMessageRepository; import com.cskefu.cc.persistence.repository.TemplateRepository; import com.cskefu.cc.util.Menu; import com.corundumstudio.socketio.SocketIOServer; -import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.validation.BindingResult; @@ -44,27 +40,18 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.servlet.ModelAndView; -import javax.servlet.http.HttpServletRequest; -import javax.validation.Valid; -import java.io.File; -import java.io.FileOutputStream; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.validation.Valid; import java.io.IOException; import java.security.NoSuchAlgorithmException; import java.sql.SQLException; import java.util.Date; import java.util.List; -import java.util.Properties; @Controller @RequestMapping("/admin/config") public class SystemConfigController extends Handler { - @Value("${uk.im.server.port}") - private Integer port; - - @Value("${web.upload-path}") - private String path; - @Autowired private SocketIOServer server; @@ -96,7 +83,8 @@ public class SystemConfigController extends Handler { } map.addAttribute("server", server); map.addAttribute("imServerStatus", MainContext.getIMServerStatus()); - List secretConfig = secRes.findByOrgi(super.getOrgi(request)); + List secretConfig = secRes.findAll(); + // check out secretConfig if (secretConfig != null && secretConfig.size() > 0) { map.addAttribute("secret", secretConfig.get(0)); @@ -118,20 +106,19 @@ public class SystemConfigController extends Handler { if (callCenterDic != null) { map.addAttribute( "templateList", - templateRes.findByTemplettypeAndOrgi(callCenterDic.getId(), super.getOrgi(request))); + templateRes.findByTemplettype(callCenterDic.getId())); } if (workOrderDic != null) { map.addAttribute( "workOrderList", - templateRes.findByTemplettypeAndOrgi(workOrderDic.getId(), super.getOrgi(request))); + templateRes.findByTemplettype(workOrderDic.getId())); } if (smsDic != null) { - map.addAttribute("smsList", templateRes.findByTemplettypeAndOrgi(smsDic.getId(), super.getOrgi(request))); + map.addAttribute("smsList", templateRes.findByTemplettype(smsDic.getId())); } map.addAttribute( - "sysMessageList", systemMessageRes.findByMsgtypeAndOrgi(MainContext.SystemMessageType.EMAIL.toString(), - super.getOrgi(request))); + "sysMessageList", systemMessageRes.findByMsgtype(MainContext.SystemMessageType.EMAIL.toString())); if (StringUtils.isNotBlank(execute) && execute.equals("false")) { map.addAttribute("execute", execute); @@ -151,10 +138,10 @@ public class SystemConfigController extends Handler { } @RequestMapping("/stopimserver") - @Menu(type = "admin", subtype = "stopimserver", access = false, admin = true) + @Menu(type = "admin", subtype = "stopimserver", admin = true) public ModelAndView stopimserver(ModelMap map, HttpServletRequest request, @Valid String confirm) throws SQLException { boolean execute; - if (execute = MainUtils.secConfirm(secRes, super.getOrgi(request), confirm)) { + if (execute = MainUtils.secConfirm(secRes, confirm)) { server.stop(); MainContext.setIMServerStatus(false); } @@ -162,14 +149,14 @@ public class SystemConfigController extends Handler { } @RequestMapping("/startentim") - @Menu(type = "admin", subtype = "startentim", access = false, admin = true) + @Menu(type = "admin", subtype = "startentim", admin = true) public ModelAndView startentim(ModelMap map, HttpServletRequest request) throws SQLException { MainContext.enableModule(Constants.CSKEFU_MODULE_ENTIM); return request(super.createView("redirect:/admin/config/index.html")); } @RequestMapping("/stopentim") - @Menu(type = "admin", subtype = "stopentim", access = false, admin = true) + @Menu(type = "admin", subtype = "stopentim", admin = true) public ModelAndView stopentim(ModelMap map, HttpServletRequest request) throws SQLException { MainContext.removeModule(Constants.CSKEFU_MODULE_ENTIM); return request(super.createView("redirect:/admin/config/index.html")); @@ -184,10 +171,10 @@ public class SystemConfigController extends Handler { * @throws SQLException */ @RequestMapping("/stop") - @Menu(type = "admin", subtype = "stop", access = false, admin = true) + @Menu(type = "admin", subtype = "stop", admin = true) public ModelAndView stop(ModelMap map, HttpServletRequest request, @Valid String confirm) throws SQLException { boolean execute = false; - if (execute = MainUtils.secConfirm(secRes, super.getOrgi(request), confirm)) { + if (execute = MainUtils.secConfirm(secRes, confirm)) { server.stop(); MainContext.setIMServerStatus(false); System.exit(0); @@ -207,14 +194,8 @@ public class SystemConfigController extends Handler { @RequestParam(value = "consolelogo", required = false) MultipartFile consolelogo, @RequestParam(value = "favlogo", required = false) MultipartFile favlogo, @Valid Secret secret) throws SQLException, IOException, NoSuchAlgorithmException { - /*SystemConfig systemConfig = systemConfigRes.findByOrgi(super.getOrgi(request)) ; - config.setOrgi(super.getOrgi(request));*/ - SystemConfig systemConfig = systemConfigRes.findByOrgi(Constants.SYSTEM_ORGI); - config.setOrgi(Constants.SYSTEM_ORGI); + SystemConfig systemConfig = systemConfigRes.findOne(); String msg = "0"; - if (StringUtils.isBlank(config.getJkspassword())) { - config.setJkspassword(null); - } if (systemConfig == null) { config.setCreater(super.getUser(request).getId()); config.setCreatetime(new Date()); @@ -222,29 +203,6 @@ public class SystemConfigController extends Handler { } else { MainUtils.copyProperties(config, systemConfig); } - if (config.isEnablessl()) { - if (keyfile != null && keyfile.getBytes() != null && keyfile.getBytes().length > 0 && keyfile.getOriginalFilename() != null && keyfile.getOriginalFilename().length() > 0) { - FileUtils.writeByteArrayToFile( - new File(path, "ssl/" + keyfile.getOriginalFilename()), keyfile.getBytes()); - systemConfig.setJksfile(keyfile.getOriginalFilename()); - File sslFilePath = new File(path, "ssl/https.properties"); - if (!sslFilePath.getParentFile().exists()) { - sslFilePath.getParentFile().mkdirs(); - } - Properties prop = new Properties(); - FileOutputStream oFile = new FileOutputStream(sslFilePath);//true表示追加打开 - prop.setProperty("key-store-password", MainUtils.encryption(systemConfig.getJkspassword())); - prop.setProperty("key-store", systemConfig.getJksfile()); - prop.store(oFile, "SSL Properties File"); - oFile.close(); - } - } else if (new File(path, "ssl").exists()) { - File[] sslFiles = new File(path, "ssl").listFiles(); - for (File sslFile : sslFiles) { - sslFile.delete(); - } - } - if (loginlogo != null && StringUtils.isNotBlank( loginlogo.getOriginalFilename()) && loginlogo.getOriginalFilename().lastIndexOf(".") > 0) { systemConfig.setLoginlogo(super.saveImageFileWithMultipart(loginlogo)); @@ -259,7 +217,7 @@ public class SystemConfigController extends Handler { } if (secret != null && StringUtils.isNotBlank(secret.getPassword())) { - List secretConfig = secRes.findByOrgi(super.getOrgi(request)); + List secretConfig = secRes.findAll(); String repassword = request.getParameter("repassword"); if (StringUtils.isNotBlank(repassword) && repassword.equals(secret.getPassword())) { if (secretConfig != null && secretConfig.size() > 0) { @@ -274,7 +232,6 @@ public class SystemConfigController extends Handler { msg = "3"; } } else { - secret.setOrgi(super.getOrgi(request)); secret.setCreater(super.getUser(request).getId()); secret.setCreatetime(new Date()); secret.setPassword(MainUtils.md5(secret.getPassword())); @@ -294,7 +251,7 @@ public class SystemConfigController extends Handler { // 保存到数据库 systemConfigRes.save(systemConfig); - MainContext.getCache().putSystemByIdAndOrgi("systemConfig", super.getOrgi(request), systemConfig); + MainContext.getCache().putSystemById("systemConfig", systemConfig); map.addAttribute("imServerStatus", MainContext.getIMServerStatus()); return request(super.createView("redirect:/admin/config/index.html?msg=" + msg)); diff --git a/contact-center/app/src/main/java/com/cskefu/cc/controller/admin/config/SystemMessageController.java b/contact-center/app/src/main/java/com/cskefu/cc/controller/admin/config/SystemMessageController.java index 88783470..f2fdab4c 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/controller/admin/config/SystemMessageController.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/controller/admin/config/SystemMessageController.java @@ -1,18 +1,16 @@ /* - * Copyright (C) 2017 优客服-多渠道客服系统 - * Modifications copyright (C) 2018-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2018- Jun. 2023 Chatopera Inc, , Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (C) 2017 优客服-多渠道客服系统, Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.controller.admin.config; @@ -34,8 +32,8 @@ import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; -import javax.servlet.http.HttpServletRequest; -import javax.validation.Valid; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.validation.Valid; import java.io.IOException; import java.security.NoSuchAlgorithmException; import java.util.List; @@ -53,8 +51,8 @@ public class SystemMessageController extends Handler { @RequestMapping("/email/index") @Menu(type = "setting", subtype = "email") public ModelAndView index(ModelMap map, HttpServletRequest request) throws IOException { - Page emails = systemMessageRepository.findByMsgtypeAndOrgi("email", super.getOrgi(request), new PageRequest(super.getP(request), super.getPs(request))); - List organs = organRes.findByOrgi(super.getOrgi(request)); + Page emails = systemMessageRepository.findByMsgtype("email", PageRequest.of(super.getP(request), super.getPs(request))); + List organs = organRes.findAll(); emails.getContent().stream().forEach(p -> { organs.stream().filter(o -> StringUtils.equals(p.getOrgan(), o.getId())).findAny().ifPresent(o -> p.setOrgan(o.getName())); @@ -67,14 +65,13 @@ public class SystemMessageController extends Handler { @RequestMapping("/email/add") @Menu(type = "admin", subtype = "email") public ModelAndView add(ModelMap map, HttpServletRequest request) { - map.put("organList", organRes.findByOrgi(super.getOrgi(request))); + map.put("organList", organRes.findAll()); return request(super.createView("/admin/email/add")); } @RequestMapping("/email/save") @Menu(type = "admin", subtype = "user") public ModelAndView save(HttpServletRequest request, @Valid SystemMessage email) throws NoSuchAlgorithmException { - email.setOrgi(super.getOrgi(request)); email.setMsgtype(MainContext.SystemMessageType.EMAIL.toString()); if (!StringUtils.isBlank(email.getSmtppassword())) { email.setSmtppassword(MainUtils.encryption(email.getSmtppassword())); @@ -86,18 +83,17 @@ public class SystemMessageController extends Handler { @RequestMapping("/email/edit") @Menu(type = "admin", subtype = "email") public ModelAndView edit(ModelMap map, HttpServletRequest request, @Valid String id) { - map.put("organList", organRes.findByOrgi(super.getOrgi(request))); - map.addAttribute("email", systemMessageRepository.findByIdAndOrgi(id, super.getOrgi(request))); + map.put("organList", organRes.findAll()); + map.addAttribute("email", systemMessageRepository.findById(id).orElse(null)); return request(super.createView("/admin/email/edit")); } @RequestMapping("/email/update") @Menu(type = "admin", subtype = "user", admin = true) public ModelAndView update(HttpServletRequest request, @Valid SystemMessage email) throws NoSuchAlgorithmException { - SystemMessage temp = systemMessageRepository.findByIdAndOrgi(email.getId(), super.getOrgi(request)); + SystemMessage temp = systemMessageRepository.findById(email.getId()).orElse(null); if (email != null) { email.setCreatetime(temp.getCreatetime()); - email.setOrgi(temp.getOrgi()); email.setMsgtype(MainContext.SystemMessageType.EMAIL.toString()); if (!StringUtils.isBlank(email.getSmtppassword())) { email.setSmtppassword(MainUtils.encryption(email.getSmtppassword())); @@ -112,7 +108,7 @@ public class SystemMessageController extends Handler { @RequestMapping("/email/delete") @Menu(type = "admin", subtype = "user") public ModelAndView delete(HttpServletRequest request, @Valid SystemMessage email) { - SystemMessage temp = systemMessageRepository.findByIdAndOrgi(email.getId(), super.getOrgi(request)); + SystemMessage temp = systemMessageRepository.findById(email.getId()).orElse(null); if (email != null) { systemMessageRepository.delete(temp); } @@ -123,7 +119,7 @@ public class SystemMessageController extends Handler { @RequestMapping("/sms/index") @Menu(type = "setting", subtype = "sms") public ModelAndView smsindex(ModelMap map, HttpServletRequest request) throws IOException { - map.addAttribute("smsList", systemMessageRepository.findByMsgtypeAndOrgi("sms", super.getOrgi(request), new PageRequest(super.getP(request), super.getPs(request)))); + map.addAttribute("smsList", systemMessageRepository.findByMsgtype("sms", PageRequest.of(super.getP(request), super.getPs(request)))); return request(super.createView("/admin/sms/index")); } @@ -137,7 +133,6 @@ public class SystemMessageController extends Handler { @RequestMapping("/sms/save") @Menu(type = "admin", subtype = "sms") public ModelAndView smssave(HttpServletRequest request, @Valid SystemMessage sms) throws NoSuchAlgorithmException { - sms.setOrgi(super.getOrgi(request)); sms.setMsgtype(MainContext.SystemMessageType.SMS.toString()); if (!StringUtils.isBlank(sms.getSmtppassword())) { sms.setSmtppassword(MainUtils.encryption(sms.getSmtppassword())); @@ -150,17 +145,16 @@ public class SystemMessageController extends Handler { @Menu(type = "admin", subtype = "sms") public ModelAndView smsedit(ModelMap map, HttpServletRequest request, @Valid String id) { map.addAttribute("smsType", Dict.getInstance().getDic("com.dic.sms.type")); - map.addAttribute("sms", systemMessageRepository.findByIdAndOrgi(id, super.getOrgi(request))); + map.addAttribute("sms", systemMessageRepository.findById(id).orElse(null)); return request(super.createView("/admin/sms/edit")); } @RequestMapping("/sms/update") @Menu(type = "admin", subtype = "sms", admin = true) public ModelAndView smsupdate(HttpServletRequest request, @Valid SystemMessage sms) throws NoSuchAlgorithmException { - SystemMessage temp = systemMessageRepository.findByIdAndOrgi(sms.getId(), super.getOrgi(request)); + SystemMessage temp = systemMessageRepository.findById(sms.getId()).orElse(null); if (sms != null) { sms.setCreatetime(temp.getCreatetime()); - sms.setOrgi(temp.getOrgi()); sms.setMsgtype(MainContext.SystemMessageType.SMS.toString()); if (!StringUtils.isBlank(sms.getSmtppassword())) { sms.setSmtppassword(MainUtils.encryption(sms.getSmtppassword())); @@ -175,7 +169,7 @@ public class SystemMessageController extends Handler { @RequestMapping("/sms/delete") @Menu(type = "admin", subtype = "sms") public ModelAndView smsdelete(HttpServletRequest request, @Valid SystemMessage sms) { - SystemMessage temp = systemMessageRepository.findByIdAndOrgi(sms.getId(), super.getOrgi(request)); + SystemMessage temp = systemMessageRepository.findById(sms.getId()).orElse(null); if (sms != null) { systemMessageRepository.delete(temp); } diff --git a/contact-center/app/src/main/java/com/cskefu/cc/controller/admin/system/MetadataController.java b/contact-center/app/src/main/java/com/cskefu/cc/controller/admin/system/MetadataController.java index a8c5126a..fba17dac 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/controller/admin/system/MetadataController.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/controller/admin/system/MetadataController.java @@ -1,22 +1,19 @@ /* - * Copyright (C) 2017 优客服-多渠道客服系统 - * Modifications copyright (C) 2018-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2018- Jun. 2023 Chatopera Inc, , Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (C) 2017 优客服-多渠道客服系统, Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.controller.admin.system; -import com.cskefu.cc.basic.MainContext; import com.cskefu.cc.basic.MainUtils; import com.cskefu.cc.controller.Handler; import com.cskefu.cc.model.*; @@ -24,35 +21,31 @@ import com.cskefu.cc.persistence.hibernate.BaseService; import com.cskefu.cc.persistence.repository.MetadataRepository; import com.cskefu.cc.persistence.repository.SysDicRepository; import com.cskefu.cc.persistence.repository.TablePropertiesRepository; -import com.cskefu.cc.util.CskefuList; import com.cskefu.cc.util.Menu; import com.cskefu.cc.util.metadata.DatabaseMetaDataHandler; import com.cskefu.cc.util.metadata.UKColumnMetadata; import com.cskefu.cc.util.metadata.UKTableMetaData; -import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.StringUtils; import org.hibernate.Session; -import org.hibernate.jdbc.Work; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.BeansException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.PageRequest; -import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; -import javax.servlet.http.HttpServletRequest; -import javax.validation.Valid; +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.validation.Valid; import java.sql.Connection; import java.sql.SQLException; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; -import java.util.List; @Controller @RequestMapping("/admin/metadata") @@ -79,21 +72,21 @@ public class MetadataController extends Handler { @RequestMapping("/index") @Menu(type = "admin", subtype = "metadata", admin = true) public ModelAndView index(ModelMap map, HttpServletRequest request) throws SQLException { - map.addAttribute("metadataList", metadataRes.findAll(new PageRequest(super.getP(request), super.getPs(request)))); + map.addAttribute("metadataList", metadataRes.findAll(PageRequest.of(super.getP(request), super.getPs(request)))); return request(super.createView("/admin/system/metadata/index")); } @RequestMapping("/edit") @Menu(type = "admin", subtype = "metadata", admin = true) public ModelAndView edit(ModelMap map, HttpServletRequest request, @Valid String id) { - map.addAttribute("metadata", metadataRes.findById(id)); + map.addAttribute("metadata", metadataRes.findById(id).orElse(null)); return request(super.createView("/admin/system/metadata/edit")); } @RequestMapping("/update") @Menu(type = "admin", subtype = "metadata", admin = true) public ModelAndView update(ModelMap map, HttpServletRequest request, @Valid MetadataTable metadata) throws SQLException { - MetadataTable table = metadataRes.findById(metadata.getId()); + MetadataTable table = metadataRes.findById(metadata.getId()).orElse(null); table.setName(metadata.getName()); table.setFromdb(metadata.isFromdb()); table.setListblocktemplet(metadata.getListblocktemplet()); @@ -105,7 +98,7 @@ public class MetadataController extends Handler { @RequestMapping("/properties/edit") @Menu(type = "admin", subtype = "metadata", admin = true) public ModelAndView propertiesedit(ModelMap map, HttpServletRequest request, @Valid String id) { - map.addAttribute("tp", tablePropertiesRes.findById(id)); + map.addAttribute("tp", tablePropertiesRes.findById(id).orElse(null)); map.addAttribute("sysdicList", sysDicRes.findByParentid("0")); map.addAttribute("dataImplList", Dict.getInstance().getDic("com.dic.data.impl")); @@ -115,7 +108,7 @@ public class MetadataController extends Handler { @RequestMapping("/properties/update") @Menu(type = "admin", subtype = "metadata", admin = true) public ModelAndView propertiesupdate(ModelMap map, HttpServletRequest request, @Valid TableProperties tp) throws SQLException { - TableProperties tableProperties = tablePropertiesRes.findById(tp.getId()); + TableProperties tableProperties = tablePropertiesRes.findById(tp.getId()).orElse(null); tableProperties.setName(tp.getName()); tableProperties.setSeldata(tp.isSeldata()); tableProperties.setSeldatacode(tp.getSeldatacode()); @@ -140,7 +133,7 @@ public class MetadataController extends Handler { @RequestMapping("/delete") @Menu(type = "admin", subtype = "metadata", admin = true) public ModelAndView delete(ModelMap map, HttpServletRequest request, @Valid String id) throws SQLException { - MetadataTable table = metadataRes.findById(id); + MetadataTable table = metadataRes.findById(id).orElse(null); metadataRes.delete(table); return request(super.createView("redirect:/admin/metadata/index.html")); } @@ -149,7 +142,7 @@ public class MetadataController extends Handler { @Menu(type = "admin", subtype = "metadata", admin = true) public ModelAndView batdelete(ModelMap map, HttpServletRequest request, @Valid String[] ids) throws SQLException { if (ids != null && ids.length > 0) { - metadataRes.delete(metadataRes.findAll(Arrays.asList(ids))); + metadataRes.deleteAll(metadataRes.findAllById(Arrays.asList(ids))); } return request(super.createView("redirect:/admin/metadata/index.html")); } @@ -157,7 +150,7 @@ public class MetadataController extends Handler { @RequestMapping("/properties/delete") @Menu(type = "admin", subtype = "metadata", admin = true) public ModelAndView propertiesdelete(ModelMap map, HttpServletRequest request, @Valid String id, @Valid String tbid) throws SQLException { - TableProperties prop = tablePropertiesRes.findById(id); + TableProperties prop = tablePropertiesRes.findById(id).orElse(null); tablePropertiesRes.delete(prop); return request(super.createView("redirect:/admin/metadata/table.html?id=" + (!StringUtils.isBlank(tbid) ? tbid : prop.getDbtableid()))); } @@ -166,7 +159,7 @@ public class MetadataController extends Handler { @Menu(type = "admin", subtype = "metadata", admin = true) public ModelAndView propertiesbatdelete(ModelMap map, HttpServletRequest request, @Valid String[] ids, @Valid String tbid) throws SQLException { if (ids != null && ids.length > 0) { - tablePropertiesRes.delete(tablePropertiesRes.findAll(Arrays.asList(ids))); + tablePropertiesRes.deleteAll(tablePropertiesRes.findAllById(Arrays.asList(ids))); } return request(super.createView("redirect:/admin/metadata/table.html?id=" + tbid)); } @@ -176,7 +169,7 @@ public class MetadataController extends Handler { public ModelAndView table(ModelMap map, HttpServletRequest request, @Valid String id) throws SQLException { map.addAttribute("propertiesList", tablePropertiesRes.findByDbtableid(id)); map.addAttribute("tbid", id); - map.addAttribute("table", metadataRes.findById(id)); + map.addAttribute("table", metadataRes.findById(id).orElse(null)); return request(super.createView("/admin/system/metadata/table")); } @@ -185,14 +178,12 @@ public class MetadataController extends Handler { public ModelAndView imptb(final ModelMap map, HttpServletRequest request) throws Exception { Session session = (Session) em.getDelegate(); - session.doWork(new Work() { - public void execute(Connection connection) throws SQLException { - try { - map.addAttribute("tablesList", - DatabaseMetaDataHandler.getTables(connection)); - } catch (Exception e) { - logger.error("When import metadata", e); - } + session.doWork(connection -> { + try { + map.addAttribute("tablesList", + DatabaseMetaDataHandler.getTables(connection)); + } catch (Exception e) { + logger.error("When import metadata", e); } }); @@ -207,29 +198,26 @@ public class MetadataController extends Handler { if (tables != null && tables.length > 0) { Session session = (Session) em.getDelegate(); session.doWork( - new Work() { - public void execute(Connection connection) throws SQLException { - try { - for (String table : tables) { - int count = metadataRes.countByTablename(table); - if (count == 0) { - MetadataTable metaDataTable = new MetadataTable(); - //当前记录没有被添加过,进行正常添加 - metaDataTable.setTablename(table); - metaDataTable.setOrgi(user.getOrgi()); - metaDataTable.setId(MainUtils.md5(metaDataTable.getTablename())); - metaDataTable.setTabledirid("0"); - metaDataTable.setCreater(user.getId()); - metaDataTable.setCreatername(user.getUsername()); - metaDataTable.setName(table); - metaDataTable.setUpdatetime(new Date()); - metaDataTable.setCreatetime(new Date()); - metadataRes.save(processMetadataTable(DatabaseMetaDataHandler.getTable(connection, metaDataTable.getTablename()), metaDataTable)); - } + connection -> { + try { + for (String table : tables) { + int count = metadataRes.countByTablename(table); + if (count == 0) { + MetadataTable metaDataTable = new MetadataTable(); + //当前记录没有被添加过,进行正常添加 + metaDataTable.setTablename(table); + metaDataTable.setId(MainUtils.md5(metaDataTable.getTablename())); + metaDataTable.setTabledirid("0"); + metaDataTable.setCreater(user.getId()); + metaDataTable.setCreatername(user.getUsername()); + metaDataTable.setName(table); + metaDataTable.setUpdatetime(new Date()); + metaDataTable.setCreatetime(new Date()); + metadataRes.save(processMetadataTable(DatabaseMetaDataHandler.getTable(connection, metaDataTable.getTablename()), metaDataTable)); } - } catch (Exception e) { - logger.error("When import metadata", e); } + } catch (Exception e) { + logger.error("When import metadata", e); } } ); @@ -240,12 +228,10 @@ public class MetadataController extends Handler { } private MetadataTable processMetadataTable(UKTableMetaData metaData, MetadataTable table) { - table.setTableproperty(new ArrayList()); + table.setTableproperty(new ArrayList<>()); if (metaData != null) { for (UKColumnMetadata colum : metaData.getColumnMetadatas()) { TableProperties tablePorperties = new TableProperties(colum.getName().toLowerCase(), colum.getTypeName(), colum.getColumnSize(), metaData.getName().toLowerCase()); - tablePorperties.setOrgi(table.getOrgi()); - tablePorperties.setDatatypecode(0); tablePorperties.setLength(colum.getColumnSize()); tablePorperties.setDatatypename(getDataTypeName(colum.getTypeName())); @@ -267,7 +253,7 @@ public class MetadataController extends Handler { public String getDataTypeName(String type) { String typeName = "text"; - if (type.indexOf("varchar") >= 0) { + if (type.contains("varchar")) { typeName = "text"; } else if (type.equalsIgnoreCase("date") || type.equalsIgnoreCase("datetime")) { typeName = type.toLowerCase(); @@ -281,17 +267,7 @@ public class MetadataController extends Handler { @Menu(type = "admin", subtype = "metadata", admin = true) public ModelAndView clean(ModelMap map, HttpServletRequest request, @Valid String id) throws SQLException, BeansException, ClassNotFoundException { if (!StringUtils.isBlank(id)) { - MetadataTable table = metadataRes.findById(id); - if (table.isFromdb() && !StringUtils.isBlank(table.getListblocktemplet())) { - SysDic dic = Dict.getInstance().getDicItem(table.getListblocktemplet()); - if (dic != null) { - Object bean = MainContext.getContext().getBean(Class.forName(dic.getCode())); - if (bean instanceof ElasticsearchRepository) { - ElasticsearchRepository jpa = (ElasticsearchRepository) bean; - jpa.deleteAll(); - } - } - } + MetadataTable table = metadataRes.findById(id).orElse(null); } return request(super.createView("redirect:/admin/metadata/index.html")); } @@ -301,27 +277,9 @@ public class MetadataController extends Handler { @Menu(type = "admin", subtype = "metadata", admin = true) public ModelAndView synctoes(ModelMap map, HttpServletRequest request, @Valid String id) throws SQLException, BeansException, ClassNotFoundException { if (!StringUtils.isBlank(id)) { - MetadataTable table = metadataRes.findById(id); + MetadataTable table = metadataRes.findById(id).orElse(null); if (table.isFromdb() && !StringUtils.isBlank(table.getListblocktemplet())) { SysDic dic = Dict.getInstance().getDicItem(table.getListblocktemplet()); - - if (dic != null) { - Object bean = MainContext.getContext().getBean(Class.forName(dic.getCode())); - if (bean instanceof ElasticsearchRepository) { - ElasticsearchRepository jpa = (ElasticsearchRepository) bean; - if (!StringUtils.isBlank(table.getPreviewtemplet())) { - SysDic jpaDic = Dict.getInstance().getDicItem(table.getPreviewtemplet()); - List dataList = service.list(jpaDic.getCode()); - List values = new CskefuList(); - for (Object object : dataList) { - values.add(object); - } - if (dataList.size() > 0) { - jpa.save(values); - } - } - } - } } } return request(super.createView("redirect:/admin/metadata/index.html")); @@ -332,23 +290,9 @@ public class MetadataController extends Handler { @Menu(type = "admin", subtype = "metadata", admin = true) public ModelAndView synctodb(ModelMap map, HttpServletRequest request, @Valid String id) throws SQLException, BeansException, ClassNotFoundException { if (!StringUtils.isBlank(id)) { - MetadataTable table = metadataRes.findById(id); + MetadataTable table = metadataRes.findById(id).orElse(null); if (table.isFromdb() && !StringUtils.isBlank(table.getListblocktemplet())) { SysDic dic = Dict.getInstance().getDicItem(table.getListblocktemplet()); - - if (dic != null) { - Object bean = MainContext.getContext().getBean(Class.forName(dic.getCode())); - if (bean instanceof ElasticsearchRepository) { - ElasticsearchRepository jpa = (ElasticsearchRepository) bean; - if (!StringUtils.isBlank(table.getPreviewtemplet())) { - Iterable dataList = jpa.findAll(); - for (Object object : dataList) { - service.delete(object); - service.save(object); - } - } - } - } } } return request(super.createView("redirect:/admin/metadata/index.html")); diff --git a/contact-center/app/src/main/java/com/cskefu/cc/controller/admin/system/SysDicController.java b/contact-center/app/src/main/java/com/cskefu/cc/controller/admin/system/SysDicController.java index 335d99db..776aaced 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/controller/admin/system/SysDicController.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/controller/admin/system/SysDicController.java @@ -1,18 +1,16 @@ /* - * Copyright (C) 2017 优客服-多渠道客服系统 - * Modifications copyright (C) 2018-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2018- Jun. 2023 Chatopera Inc, , Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (C) 2017 优客服-多渠道客服系统, Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.controller.admin.system; @@ -21,7 +19,7 @@ import com.cskefu.cc.controller.Handler; import com.cskefu.cc.model.SysDic; import com.cskefu.cc.persistence.repository.SysDicRepository; import com.cskefu.cc.util.Menu; -import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort.Direction; @@ -30,8 +28,8 @@ import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; -import javax.servlet.http.HttpServletRequest; -import javax.validation.Valid; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.validation.Valid; import java.util.Date; import java.util.List; @@ -49,7 +47,7 @@ public class SysDicController extends Handler { @RequestMapping("/index") @Menu(type = "admin", subtype = "sysdic") public ModelAndView index(ModelMap map, HttpServletRequest request) { - map.addAttribute("sysDicList", sysDicRes.findByParentid("0", new PageRequest(super.getP(request), super.getPs(request), Direction.DESC, "createtime"))); + map.addAttribute("sysDicList", sysDicRes.findByParentid("0", PageRequest.of(super.getP(request), super.getPs(request), Direction.DESC, "createtime"))); return request(super.createView("/admin/system/sysdic/index")); } @@ -64,14 +62,13 @@ public class SysDicController extends Handler { public ModelAndView save(HttpServletRequest request, @Valid SysDic dic) { List sysDicList = sysDicRes.findByCodeOrName(dic.getCode(), dic.getName()); String msg = null; - String orgi = super.getOrgi(request); if (sysDicList.size() == 0) { dic.setParentid("0"); dic.setHaschild(true); dic.setCreater(super.getUser(request).getId()); dic.setCreatetime(new Date()); sysDicRes.save(dic); - reloadSysDicItem(dic, orgi); + reloadSysDicItem(dic); } else { msg = "exist"; } @@ -81,7 +78,7 @@ public class SysDicController extends Handler { @RequestMapping("/edit") @Menu(type = "admin", subtype = "sysdic") public ModelAndView edit(ModelMap map, HttpServletRequest request, @Valid String id, @Valid String p) { - map.addAttribute("sysDic", sysDicRes.findById(id)); + map.addAttribute("sysDic", sysDicRes.findById(id).orElse(null)); map.addAttribute("p", p); return request(super.createView("/admin/system/sysdic/edit")); } @@ -91,7 +88,7 @@ public class SysDicController extends Handler { public ModelAndView update(HttpServletRequest request, @Valid SysDic dic, @Valid String p) { List sysDicList = sysDicRes.findByCodeOrName(dic.getCode(), dic.getName()); if (sysDicList.size() == 0 || (sysDicList.size() == 1 && sysDicList.get(0).getId().equals(dic.getId()))) { - SysDic sysDic = sysDicRes.findById(dic.getId()); + SysDic sysDic = sysDicRes.findById(dic.getId()).orElse(null); sysDic.setName(dic.getName()); sysDic.setCode(dic.getCode()); sysDic.setCtype(dic.getCtype()); @@ -99,8 +96,7 @@ public class SysDicController extends Handler { sysDic.setIconstr(dic.getIconstr()); sysDic.setDescription(dic.getDescription()); sysDicRes.save(sysDic); - String orgi = super.getOrgi(request); - reloadSysDicItem(sysDic, orgi); + reloadSysDicItem(sysDic); } return request(super.createView("redirect:/admin/sysdic/index.html?p=" + p)); } @@ -108,11 +104,11 @@ public class SysDicController extends Handler { @RequestMapping("/delete") @Menu(type = "admin", subtype = "sysdic") public ModelAndView delete(ModelMap map, HttpServletRequest request, @Valid String id, @Valid String p) { - SysDic sysDic = sysDicRes.findById(id); - sysDicRes.delete(sysDicRes.findByDicid(id)); + SysDic sysDic = sysDicRes.findById(id).orElse(null); + sysDicRes.deleteAll(sysDicRes.findByDicid(id)); sysDicRes.delete(sysDic); - reloadSysDicItem(sysDic, super.getOrgi(request)); + reloadSysDicItem(sysDic); return request(super.createView("redirect:/admin/sysdic/index.html?p=" + p)); } @@ -120,15 +116,15 @@ public class SysDicController extends Handler { @RequestMapping("/dicitem") @Menu(type = "admin", subtype = "sysdic") public ModelAndView dicitem(ModelMap map, HttpServletRequest request, @Valid String id) { - map.addAttribute("sysDic", sysDicRes.findById(id)); - map.addAttribute("sysDicList", sysDicRes.findByParentid(id, new PageRequest(super.getP(request), super.getPs(request), Direction.DESC, "createtime"))); + map.addAttribute("sysDic", sysDicRes.findById(id).orElse(null)); + map.addAttribute("sysDicList", sysDicRes.findByParentid(id, PageRequest.of(super.getP(request), super.getPs(request), Direction.DESC, "createtime"))); return request(super.createView("/admin/system/sysdic/dicitem")); } @RequestMapping("/dicitem/add") @Menu(type = "admin", subtype = "sysdic") public ModelAndView dicitemadd(ModelMap map, HttpServletRequest request, @Valid String id, @Valid String p) { - map.addAttribute("sysDic", sysDicRes.findById(id)); + map.addAttribute("sysDic", sysDicRes.findById(id).orElse(null)); map.addAttribute("p", p); return request(super.createView("/admin/system/sysdic/dicitemadd")); } @@ -138,14 +134,12 @@ public class SysDicController extends Handler { public ModelAndView dicitemsave(HttpServletRequest request, @Valid SysDic dic, @Valid String p) { List sysDicList = sysDicRes.findByDicidAndName(dic.getDicid(), dic.getName()); String msg = null; - String orgi = super.getOrgi(request); if (sysDicList.size() == 0) { dic.setHaschild(true); - dic.setOrgi(orgi); dic.setCreater(super.getUser(request).getId()); dic.setCreatetime(new Date()); sysDicRes.save(dic); - reloadSysDicItem(dic, orgi); + reloadSysDicItem(dic); } else { msg = "exist"; } @@ -155,29 +149,28 @@ public class SysDicController extends Handler { /** * 更新系统词典缓存 * @param dic - * @param orgi */ - public void reloadSysDicItem(final SysDic dic, final String orgi) { - cache.putSysDicByOrgi(dic.getId(), orgi, dic); + public void reloadSysDicItem(final SysDic dic) { + cache.putSysDic(dic.getId(), dic); if (StringUtils.isNotBlank(dic.getDicid())) { // 该数据为某词典的子项 // 首先获得根词典 - SysDic root = cache.findOneSysDicByIdAndOrgi(dic.getDicid(), orgi); + SysDic root = cache.findOneSysDicById(dic.getDicid()); // 获得其目前的全部子项,此处是从数据库提取 // 而不是缓存,因为缓存的数据已经旧了 List sysDicList = sysDicRes.findByDicid(dic.getDicid()); // 更新其全部子项数据到缓存 - cache.putSysDicByOrgi(root.getCode(), orgi, sysDicList); + cache.putSysDic(root.getCode(), sysDicList); } else if (dic.getParentid().equals("0")) { // 如果该数据为某根词典 List sysDicList = sysDicRes.findByDicid(dic.getId()); - cache.putSysDicByOrgi(dic.getCode(), orgi, sysDicList); + cache.putSysDic(dic.getCode(), sysDicList); } } @RequestMapping("/dicitem/batadd") @Menu(type = "admin", subtype = "sysdic") public ModelAndView dicitembatadd(ModelMap map, HttpServletRequest request, @Valid String id, @Valid String p) { - map.addAttribute("sysDic", sysDicRes.findById(id)); + map.addAttribute("sysDic", sysDicRes.findById(id).orElse(null)); map.addAttribute("p", p); return request(super.createView("/admin/system/sysdic/batadd")); } @@ -187,13 +180,10 @@ public class SysDicController extends Handler { public ModelAndView dicitembatsave(HttpServletRequest request, @Valid SysDic sysDic, @Valid String content, @Valid String p) { String[] dicitems = content.split("[\n\r\n]"); int count = 0; - String orig = super.getOrgi(request); for (String dicitem : dicitems) { String[] dicValues = dicitem.split("[\t, ;]{1,}"); if (dicValues.length == 2 && dicValues[0].length() > 0 && dicValues[1].length() > 0) { SysDic dic = new SysDic(); - dic.setOrgi(orig); - dic.setName(dicValues[0]); dic.setCode(dicValues[1]); dic.setCreater(super.getUser(request).getId()); @@ -208,7 +198,7 @@ public class SysDicController extends Handler { } } - reloadSysDicItem(sysDicRes.getOne(sysDic.getParentid()), orig); + reloadSysDicItem(sysDicRes.findById(sysDic.getParentid()).orElse(null)); return request(super.createView("redirect:/admin/sysdic/dicitem.html?id=" + sysDic.getParentid() + "&p=" + p)); } @@ -216,7 +206,7 @@ public class SysDicController extends Handler { @RequestMapping("/dicitem/edit") @Menu(type = "admin", subtype = "sysdic") public ModelAndView dicitemedit(ModelMap map, HttpServletRequest request, @Valid String id, @Valid String p) { - map.addAttribute("sysDic", sysDicRes.findById(id)); + map.addAttribute("sysDic", sysDicRes.findById(id).orElse(null)); map.addAttribute("p", p); return request(super.createView("/admin/system/sysdic/dicitemedit")); } @@ -225,20 +215,18 @@ public class SysDicController extends Handler { @Menu(type = "admin", subtype = "sysdic") public ModelAndView dicitemupdate(HttpServletRequest request, @Valid SysDic dic, @Valid String p) { List sysDicList = sysDicRes.findByDicidAndName(dic.getDicid(), dic.getName()); - String orgi = super.getOrgi(request); if (sysDicList.size() == 0 || (sysDicList.size() == 1 && sysDicList.get(0).getId().equals(dic.getId()))) { - SysDic sysDic = sysDicRes.findById(dic.getId()); + SysDic sysDic = sysDicRes.findById(dic.getId()).orElse(null); sysDic.setName(dic.getName()); sysDic.setCode(dic.getCode()); sysDic.setCtype(dic.getCtype()); - sysDic.setOrgi(orgi); sysDic.setIconskin(dic.getIconskin()); sysDic.setIconstr(dic.getIconstr()); sysDic.setDiscode(dic.isDiscode()); sysDic.setDescription(dic.getDescription()); sysDicRes.save(sysDic); - reloadSysDicItem(sysDic, orgi); + reloadSysDicItem(sysDic); } return request(super.createView("redirect:/admin/sysdic/dicitem.html?id=" + dic.getParentid() + "&p=" + p)); } @@ -246,10 +234,10 @@ public class SysDicController extends Handler { @RequestMapping("/dicitem/delete") @Menu(type = "admin", subtype = "sysdic") public ModelAndView dicitemdelete(ModelMap map, HttpServletRequest request, @Valid String id, @Valid String p) { - sysDicRes.delete(sysDicRes.findByDicid(id)); - SysDic dic = sysDicRes.getOne(id); + sysDicRes.deleteAll(sysDicRes.findByDicid(id)); + SysDic dic = sysDicRes.findById(id).orElse(null); sysDicRes.delete(dic); - reloadSysDicItem(dic, super.getOrgi(request)); + reloadSysDicItem(dic); return request(super.createView("redirect:/admin/sysdic/dicitem.html?id=" + dic.getParentid() + "&p=" + p)); } diff --git a/contact-center/app/src/main/java/com/cskefu/cc/controller/admin/system/TemplateController.java b/contact-center/app/src/main/java/com/cskefu/cc/controller/admin/system/TemplateController.java index cd07210b..b4933f4a 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/controller/admin/system/TemplateController.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/controller/admin/system/TemplateController.java @@ -1,18 +1,16 @@ /* - * Copyright (C) 2017 优客服-多渠道客服系统 - * Modifications copyright (C) 2018-2022 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd. + * , Licensed under the Chunsong Public + * License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * Copyright (C) 2018- Jun. 2023 Chatopera Inc, , Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (C) 2017 优客服-多渠道客服系统, Licensed under the Apache License, Version 2.0, + * http://www.apache.org/licenses/LICENSE-2.0 */ package com.cskefu.cc.controller.admin.system; @@ -35,158 +33,157 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.servlet.ModelAndView; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.validation.Valid; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.Valid; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; @Controller @RequestMapping("/admin/template") -public class TemplateController extends Handler{ - - - @Autowired - private TemplateRepository templateRes; - - @Autowired - private SysDicRepository dicRes; +public class TemplateController extends Handler { - @Autowired - private Cache cache; + + @Autowired + private TemplateRepository templateRes; + + @Autowired + private SysDicRepository dicRes; + + @Autowired + private Cache cache; @RequestMapping("/index") - @Menu(type = "admin" , subtype = "template" , access = false , admin = true) - public ModelAndView index(ModelMap map , HttpServletRequest request) { - map.addAttribute("sysDicList", Dict.getInstance().getDic(Constants.CSKEFU_SYSTEM_DIC)); + @Menu(type = "admin", subtype = "template", admin = true) + public ModelAndView index(ModelMap map, HttpServletRequest request) { + map.addAttribute("sysDicList", Dict.getInstance().getDic(Constants.CSKEFU_SYSTEM_DIC)); return request(super.createView("/admin/system/template/index")); } - + @RequestMapping("/expall") - @Menu(type = "admin" , subtype = "template" , access = false , admin = true) - public void expall(ModelMap map , HttpServletRequest request , HttpServletResponse response) throws Exception { - List