diff --git a/.gitee/ISSUE_TEMPLATE/01_help.yml b/.gitee/ISSUE_TEMPLATE/01_help.yml
new file mode 100644
index 00000000..8cc7ac72
--- /dev/null
+++ b/.gitee/ISSUE_TEMPLATE/01_help.yml
@@ -0,0 +1,30 @@
+name: 求助
+description: 开发环境搭建、功能咨询和使用问题等
+labels: ["help-wanted"]
+assignees:
+ - zhangchanglong2021
+body:
+- type: markdown
+ attributes:
+ value: "## 描述"
+- type: textarea
+ id: content1
+ attributes:
+ label: "详细描述问题后优先处理解决! 截图、错误日志等"
+ value: |
+ 1. 针对某功能,需要提供详细描述文档
+ 2. xxx
+ 3. xxx
+ ...
+ validations:
+ required: true
+- type: textarea
+ id: content2
+ attributes:
+ label: "代码版本"
+ value: |
+ 1. Git commit hash (`git rev-parse HEAD`),进入代码库并执行
+ 或
+ 2. v7, v8, v9 ...
+ validations:
+ required: true
\ No newline at end of file
diff --git a/.gitee/ISSUE_TEMPLATE/02_bug.yml b/.gitee/ISSUE_TEMPLATE/02_bug.yml
new file mode 100644
index 00000000..1452d318
--- /dev/null
+++ b/.gitee/ISSUE_TEMPLATE/02_bug.yml
@@ -0,0 +1,30 @@
+name: 软件缺陷
+description: 报告软件缺陷
+labels: ["bug"]
+assignees:
+ - kaifuny
+body:
+- type: markdown
+ attributes:
+ value: "## 描述"
+- type: textarea
+ id: content1
+ attributes:
+ label: "详细描述问题后优先处理解决! 截图、错误日志等"
+ value: |
+ 1. 如何重现
+ 2. xxx
+ 3. xxx
+ ...
+ validations:
+ required: true
+- type: textarea
+ id: content2
+ attributes:
+ label: "代码版本"
+ value: |
+ 1. Git commit hash (`git rev-parse HEAD`),进入代码库并执行
+ 或
+ 2. v7, v8, v9 ...
+ validations:
+ required: true
\ No newline at end of file
diff --git a/.gitee/ISSUE_TEMPLATE/03_requirement.yml b/.gitee/ISSUE_TEMPLATE/03_requirement.yml
new file mode 100644
index 00000000..abb0c4f5
--- /dev/null
+++ b/.gitee/ISSUE_TEMPLATE/03_requirement.yml
@@ -0,0 +1,30 @@
+name: 需求
+description: 增加新需求、反馈建议
+labels: ["requirement"]
+assignees:
+ - kaifuny
+body:
+- type: markdown
+ attributes:
+ value: "## 描述"
+- type: textarea
+ id: content1
+ attributes:
+ label: "详细描述需求"
+ value: |
+ 1. xxx 模块需要支持 xxx 功能
+ 2. xxx
+ 3. xxx
+ ...
+ validations:
+ required: true
+- type: textarea
+ id: content2
+ attributes:
+ label: "代码版本"
+ value: |
+ 1. Git commit hash (`git rev-parse HEAD`),进入代码库并执行
+ 或
+ 2. v7, v8, v9 ...
+ validations:
+ required: true
\ No newline at end of file
diff --git a/.gitee/ISSUE_TEMPLATE/04_profiling.yml b/.gitee/ISSUE_TEMPLATE/04_profiling.yml
new file mode 100644
index 00000000..44647c5f
--- /dev/null
+++ b/.gitee/ISSUE_TEMPLATE/04_profiling.yml
@@ -0,0 +1,30 @@
+name: 性能优化
+description: 瓶颈分析、性能优化建议和安全漏洞等
+labels: ["profiling"]
+assignees:
+ - lecjy
+body:
+- type: markdown
+ attributes:
+ value: "## 描述"
+- type: textarea
+ id: content1
+ attributes:
+ label: "详细描述需求"
+ value: |
+ 1. xxx 模块需要支持 xxx 功能
+ 2. xxx
+ 3. xxx
+ ...
+ validations:
+ required: true
+- type: textarea
+ id: content2
+ attributes:
+ label: "代码版本"
+ value: |
+ 1. Git commit hash (`git rev-parse HEAD`),进入代码库并执行
+ 或
+ 2. v7, v8, v9 ...
+ validations:
+ required: true
\ No newline at end of file
diff --git a/.gitee/ISSUE_TEMPLATE/05_userstory.yml b/.gitee/ISSUE_TEMPLATE/05_userstory.yml
new file mode 100644
index 00000000..7e63130d
--- /dev/null
+++ b/.gitee/ISSUE_TEMPLATE/05_userstory.yml
@@ -0,0 +1,35 @@
+name: 用户故事
+description: 用户故事
+title: "[us] "
+labels: ["userstory"]
+assignees:
+ - kaifuny
+body:
+- type: markdown
+ attributes:
+ value: "## 描述"
+- type: textarea
+ id: content1
+ attributes:
+ label: "详细描述需求"
+ value: |
+ ## 用户主体
+
+ ## 用户故事
+
+ ## 交互流程
+
+ ## 交互细节
+ ...
+ validations:
+ required: true
+- type: textarea
+ id: content2
+ attributes:
+ label: "代码版本"
+ value: |
+ 1. Git commit hash (`git rev-parse HEAD`),进入代码库并执行
+ 或
+ 2. v7, v8, v9 ...
+ validations:
+ required: true
\ No newline at end of file
diff --git a/.gitee/ISSUE_TEMPLATE/config.yaml b/.gitee/ISSUE_TEMPLATE/config.yaml
new file mode 100644
index 00000000..80c0b2ab
--- /dev/null
+++ b/.gitee/ISSUE_TEMPLATE/config.yaml
@@ -0,0 +1,11 @@
+blank_issues_enabled: false
+contact_links:
+ - name: 文档中心
+ url: https://docs.cskefu.com/
+ about: 提供春松客服使用指南、教程、基本功能使用、介绍和常见问题解答
+ - name: 春松客服大讲堂
+ url: https://gitee.com/cskefu/cskefu-djt/blob/main/README.md
+ about: 提供春松客服定制化开发技能课程
+ - name: 商务洽谈
+ url: https://www.chatopera.com/price.html
+ about: 提供春松客服定制化开发、机器人客服平台等
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.gitee/PULL_REQUEST_TEMPLATE/bug_fix.md
similarity index 89%
rename from .github/PULL_REQUEST_TEMPLATE.md
rename to .gitee/PULL_REQUEST_TEMPLATE/bug_fix.md
index 76b95f03..fe4becfd 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.gitee/PULL_REQUEST_TEMPLATE/bug_fix.md
@@ -1,13 +1,21 @@
+---
+reviewers : cskefu/reviewers
+---
+
## 描述
+### 关联 Issue #
+
## 解决的问题
+
## 测试情况
+
@@ -15,13 +23,17 @@
## 截屏
## 变更的类型
+
-- [ ] 解决Bug
+
+- [ ] 解决 Bug
- [ ] 新功能(不影响其他功能)
- [ ] 对其他功能有影响
-## 检查:
+## 检查
+
+
- [ ] 我的变更和代码规范一致
- [ ] 我的变更需要更新文档
- [ ] 我已经更新了对应的文档
diff --git a/.gitee/PULL_REQUEST_TEMPLATE/documentation.md b/.gitee/PULL_REQUEST_TEMPLATE/documentation.md
new file mode 100644
index 00000000..ee0ce348
--- /dev/null
+++ b/.gitee/PULL_REQUEST_TEMPLATE/documentation.md
@@ -0,0 +1,9 @@
+---
+reviewers : cskefu/reviewers
+---
+
+### Requirements for Contributing Documentation
+
+## 变更说明
+
+### 关联 Issue #
diff --git a/.gitee/PULL_REQUEST_TEMPLATE/performance_improvement.md b/.gitee/PULL_REQUEST_TEMPLATE/performance_improvement.md
new file mode 100644
index 00000000..7f50fb0e
--- /dev/null
+++ b/.gitee/PULL_REQUEST_TEMPLATE/performance_improvement.md
@@ -0,0 +1,9 @@
+---
+reviewers : cskefu/reviewers
+---
+
+### Requirements for Contributing a Performance Improvement
+
+## 性能提升
+
+### 关联 Issue #
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
deleted file mode 100644
index 3add9bf1..00000000
--- a/.github/ISSUE_TEMPLATE.md
+++ /dev/null
@@ -1,12 +0,0 @@
-# 描述
-
-## 现在行为
-
-## 预期行为
-
-# 解决方案
-
-# 环境
-
-* 代码版本:
-Git commit hash (`git rev-parse HEAD`)
diff --git a/.github/workflows/gitee.yml b/.github/workflows/gitee.yml
deleted file mode 100644
index f316dd61..00000000
--- a/.github/workflows/gitee.yml
+++ /dev/null
@@ -1,19 +0,0 @@
-name: gitee
-
-on:
- - push
- - delete
-
-jobs:
- sync:
- runs-on: ubuntu-latest
- name: Git Repo Sync
- steps:
- - uses: actions/checkout@v3
- with:
- fetch-depth: 0
- - uses: wangchucheng/git-repo-sync@v0.1.0
- with:
- target-url: https://gitee.com/cskefu/cskefu.git
- target-username: ${{ secrets.USERNAME }}
- target-token: ${{ secrets.ACCESS_TOKEN }}
\ No newline at end of file
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index f5736fbd..f5ff8b0c 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,10 +1,8 @@
# Contributing
-成为春松客服贡献者
-
## 提交反馈
-在[春松客服 GitHub Issues](https://github.com/cskefu/cskefu/issues)中,先搜索是否有重复的。然后进行补充或新建 Issue。
+在[春松客服 Issues](https://gitee.com/cskefu/cskefu/issues)中,先搜索是否有重复的。然后进行补充或新建 Issue。
## 提交代码
@@ -15,25 +13,14 @@
春松客服文档中心的项目,也是开源的,地址在:
-[https://github.com/cskefu/cskefu-docs](https://github.com/cskefu/cskefu-docs)
+[https://gitee.com/cskefu/docs](https://gitee.com/cskefu/docs)
春松客服文档 Markdown 文件路径:
-[https://github.com/cskefu/cskefu-docs/tree/main/docs](https://github.com/cskefu/cskefu-docs/tree/main/docs)
+[https://gitee.com/cskefu/docs/tree/main/docs](https://gitee.com/cskefu/docs/tree/main/docs)
更新文档:
-1)提交 PR 到[春松客服文档中心 GitHub 仓库](https://github.com/cskefu/cskefu-docs/tree/main/docs),一步到位。
+1)提交 PR 到[春松客服文档中心 Git 仓库](https://gitee.com/cskefu/docs/tree/main),一步到位。
-2)提交 Issue 到[春松客服 Issues](https://github.com/cskefu/cskefu/issues/new), 并撰写文档内容,使用该方案则需要后续其他协作者提交到 [春松客服文档中心 GitHub 仓库](https://github.com/cskefu/cskefu-docs) 中。
-
-## 期待您成为春松客服贡献者
-
-不管是何种贡献,只有大小之分,而无本质区别。
-
-一起贡献,一起好!
-没有贡献,都不好!
-
-团结是共赢,分裂是全输。
-
-
+2)提交 Issue 到[春松客服 Issues](https://gitee.com/cskefu/cskefu/issues/new), 并撰写文档内容,使用该方案则需要后续其他协作者提交到 [春松客服文档中心 Git 仓库](https://gitee.com/cskefu/docs) 中。
diff --git a/README.md b/README.md
index ba3a8f6e..2145d3b9 100644
--- a/README.md
+++ b/README.md
@@ -31,18 +31,6 @@
新版本介绍:[观看春松客服 v8 新版本发布会 @ 2023-07-01](https://www.cskefu.com/2023/07/03/community-conf/)
-## 媒体报道
-
-
-
-- [春松客服:通过开源加云原生模式,大规模交付智能客服系统](https://www.cskefu.com/2022/04/11/cskefu-opensource-plus-cloud-model/)
-
-- [春松客服荣获 GVP 企业级开源项目认证](http://www.ctiforum.com/news/guonei/578988.html)
-
-- [Chatopera 王海良:做好开源客服系统 | OpenTEKr 专访](https://www.bilibili.com/video/BV1qF411p7hW)
-
----
-
## 开发者列表 ✨
:evergreen_tree: 春松客服是开源的智能客服系统,于 2018 年 9 月由 [Chatopera](https://www.chatopera.com) 发布,在开源社区协作中优化和完善,春松客服属于[春松客服开源社区](https://github.com/cskefu/cskefu#%E6%98%A5%E6%9D%BE%E5%AE%A2%E6%9C%8D%E5%BC%80%E6%BA%90%E7%A4%BE%E5%8C%BA)。
@@ -134,27 +122,35 @@
欢迎页
-
+
-### 坐席工作台
+
+展开查看更多产品截图
+
-登录演示环境,查看更多产品能力:[https://demo.cskefu.com/](https://demo.cskefu.com/)
+
+ 坐席工作台
+
+
-| **登录账号** | **密码** | **角色** |
-| ------------ | --------- | -------------- |
-| admin | admin1234 | 系统超级管理员 |
-| zhangsan | agent1234 | 客服坐席人员 |
+
+ 坐席监控
+
+
-### 网页端访客示例
+
+ 集成客服机器人
+
+
-[https://demo.cskefu.com/testclient.html](http://demo.cskefu.com/testclient.html)
+
+ 客服机器人应答
+
+
-- 登录张三后可接待访客,否则显示没有客服人员在线
-
-### 机器人客服示例
-
-[https://oh-my.cskefu.com/im/text/0nhckh.html](https://oh-my.cskefu.com/im/text/0nhckh.html)
+
+
## 快速开始
@@ -210,13 +206,11 @@
在春松客服开源社区,我们建立关系、发现认同、合作共赢!
- 了解春松客服采用的开源许可协议,参考[文档](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/)
+- 了解春松客服的开发计划,参考[文档](https://github.com/cskefu/cskefu/issues)
+- 如何发布春松客服人物志,向社区介绍自己,参考[文档](https://www.cskefu.com/join-us/)
- 如何提交反馈、文档,参考[文档](./CONTRIBUTING.md)
+- 如何成为春松客服开发者,参考[文档](https://docs.cskefu.com/docs/osc/devonboard/)
- 如何提交代码,参考[文档](https://docs.cskefu.com/docs/osc/contribution)
-- 如何最新的春松客服开发进展:订阅[春松客服邮件列表](https://lists.cskefu.com/cgi-bin/mailman/listinfo/dev)
-- 如何获得春松客服商业插件和服务,参考[文档](https://www.chatopera.com/price.html)
春松客服之所以开源,是基于这样一种信念:爱人也是爱己,利他也是利己。
因春松客服受益,而不回报开源社区的用户,我们不欢迎使用春松客服:我们开源并不是为了你们,你们是不被祝福的。
@@ -241,7 +235,7 @@
- [IDE 配置和使用之 VSCode](https://docs.cskefu.com/docs/osc/ide_vscode)
- 定制开发技能
- [系统集成之 RestAPIs](https://docs.cskefu.com/docs/osc/restapi)
- - [从零开始学习定制春松客服技能:春松客服大讲堂 PPT 课件及视频](https://github.com/cskefu/cskefu.djt)
+ - [从零开始学习定制春松客服技能:春松客服大讲堂 PPT 课件及视频](https://store.chatopera.com/product/cskfdjt19)
- [掌握春松客服前端框架 Pugjs,介绍及使用注意事项](https://blog.csdn.net/samurais/article/details/114576611)
- [提交代码](https://docs.cskefu.com/docs/osc/contribution)
diff --git a/contact-center/app/pom.xml b/contact-center/app/pom.xml
index 01da5fe9..df97d49d 100644
--- a/contact-center/app/pom.xml
+++ b/contact-center/app/pom.xml
@@ -88,6 +88,7 @@
org.springframework.boot
spring-boot-maven-plugin
+ 3.1.3
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 d0eb72d6..91daf55f 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
@@ -27,8 +27,10 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
import java.util.*;
+import java.util.stream.Collectors;
/**
* 坐席自动分配策略集
@@ -58,6 +60,8 @@ public class ACDPolicyService {
@Autowired
private OrganProxy organProxy;
+ @Autowired
+ private OrganRepository organRepository;
/**
* 载入坐席 ACD策略配置
*
@@ -85,12 +89,26 @@ public class ACDPolicyService {
if ((sessionConfig = cache.findOneSessionConfig(organid)) == null) {
sessionConfig = sessionConfigRes.findBySkill(organid);
if (sessionConfig == null) {
- sessionConfig = new SessionConfig();
+ List list = organRepository.findAll();
+ if (CollectionUtils.isEmpty(list)) {
+ return new SessionConfig();
+ } else {
+ Map map = list.stream().collect(Collectors.toMap(item -> item.getId(), item -> item.getParent()));
+ List configList = sessionConfigRes.findAll();
+ if (CollectionUtils.isEmpty(configList)) {
+ return new SessionConfig();
+ } else {
+ Map skillMap = configList.stream().collect(Collectors.toMap(item -> item.getSkill(), item -> item));
+ if (map.get(organid) == null || skillMap.get(map.get(organid)) == null) {
+ return new SessionConfig();
+ }
+ return skillMap.get(map.get(organid));
+ }
+ }
} else {
cache.putSessionConfig(sessionConfig, organid);
}
}
-
return sessionConfig;
}
@@ -394,4 +412,4 @@ public class ACDPolicyService {
return agentUserRes.countByAgentnoAndStatusAndSkill(agentStatus.getAgentno(), MainContext.AgentUserStatusEnum.INSERVICE.toString(), skill);
}
-}
+}
\ No newline at end of file
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 7da261a2..9aae742a 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,14 +1,14 @@
-/*
- * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd.
- * , Licensed under the Chunsong Public
+/*
+ * 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,
+ * Copyright (C) 2019-2022 Chatopera Inc, ,
+ * Licensed under the Apache License, Version 2.0,
* http://www.apache.org/licenses/LICENSE-2.0
*/
@@ -22,12 +22,14 @@ 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.model.ExecuteResult;
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 com.cskefu.cc.proxy.LicenseProxy;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -62,6 +64,9 @@ public class ACDVisBodyParserMw implements Middleware {
@Autowired
private ACDMessageHelper acdMessageHelper;
+ @Autowired
+ private LicenseProxy licenseProxy;
+
/**
* 设置AgentUser基本信息
*
@@ -87,6 +92,16 @@ public class ACDVisBodyParserMw implements Middleware {
ctx.getOnlineUserId(),
ctx.getOnlineUserNickname(),
ctx.getAppid());
+
+ // 执行计费逻辑
+ ExecuteResult writeDownResult = licenseProxy.writeDownAgentUserUsageInStore(p);
+
+ if (writeDownResult.getRc() != ExecuteResult.RC_SUCC) {
+ // 配额操作失败,提示座席
+ p.setLicenseVerifiedPass(false);
+ p.setLicenseBillingMsg(writeDownResult.getMsg());
+ }
+
logger.info("[apply] create new agent user id {}", p.getId());
return p;
});
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 e342ff09..8b5f57e5 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,14 +1,14 @@
-/*
- * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd.
- * , Licensed under the Chunsong Public
+/*
+ * 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,
+ * Copyright (C) 2019-2022 Chatopera Inc, ,
+ * Licensed under the Apache License, Version 2.0,
* http://www.apache.org/licenses/LICENSE-2.0
*/
@@ -18,14 +18,17 @@ import com.cskefu.cc.basic.MainContext;
import com.cskefu.cc.cache.Cache;
import com.cskefu.cc.cache.RedisCommand;
import com.cskefu.cc.cache.RedisKey;
+import com.cskefu.cc.exception.BillingResourceException;
import com.cskefu.cc.model.AgentUser;
import com.cskefu.cc.proxy.AgentAuditProxy;
+import com.cskefu.cc.proxy.LicenseProxy;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -51,6 +54,31 @@ public class AgentUserAspect {
@Autowired
private AgentAuditProxy agentAuditProxy;
+ @Autowired
+ private LicenseProxy licenseProxy;
+
+ @Before("execution(* com.cskefu.cc.persistence.repository.AgentUserRepository.save(..))")
+ public void beforeSave(final JoinPoint joinPoint) {
+ final AgentUser agentUser = (AgentUser) joinPoint.getArgs()[0];
+
+ if (StringUtils.isBlank(agentUser.getId())) {
+ logger.info("[beforeSave] agentUser id is blank");
+
+ if (StringUtils.isNotBlank(agentUser.getOpttype()) && StringUtils.equals(MainContext.OptType.CHATBOT.toString(), agentUser.getOpttype())) {
+ // 机器人座席支持的对话,跳过计数
+ agentUser.setLicenseVerifiedPass(true);
+ return;
+ }
+
+ // 计数加一
+ try {
+ licenseProxy.increResourceUsageInMetaKv(MainContext.BillingResource.AGENGUSER, 1);
+ } catch (BillingResourceException e) {
+ logger.error("[beforeSave] error", e.toString());
+ }
+ }
+ }
+
@After("execution(* com.cskefu.cc.persistence.repository.AgentUserRepository.save(..))")
public void save(final JoinPoint joinPoint) {
final AgentUser agentUser = (AgentUser) joinPoint.getArgs()[0];
diff --git a/contact-center/app/src/main/java/com/cskefu/cc/aspect/ChannelAspect.java b/contact-center/app/src/main/java/com/cskefu/cc/aspect/ChannelAspect.java
new file mode 100644
index 00000000..499c4701
--- /dev/null
+++ b/contact-center/app/src/main/java/com/cskefu/cc/aspect/ChannelAspect.java
@@ -0,0 +1,51 @@
+/*
+ * 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.aspect;
+
+import com.cskefu.cc.basic.MainContext;
+import com.cskefu.cc.exception.BillingQuotaException;
+import com.cskefu.cc.exception.BillingResourceException;
+import com.cskefu.cc.model.Channel;
+import com.cskefu.cc.model.User;
+import com.cskefu.cc.proxy.LicenseProxy;
+import org.apache.commons.lang3.StringUtils;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Before;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Aspect
+@Component
+public class ChannelAspect {
+
+ private final static Logger logger = LoggerFactory.getLogger(ChannelAspect.class);
+
+ @Autowired
+ private LicenseProxy licenseProxy;
+
+ @Before("execution(* com.cskefu.cc.persistence.repository.ChannelRepository.save(..))")
+ public void beforeSave(final JoinPoint joinPoint) throws BillingResourceException, BillingQuotaException {
+ final Channel channel = (Channel) joinPoint.getArgs()[0];
+ logger.info("[beforeSave] before channel id {}, type {}", channel.getId(), channel.getType());
+ if (StringUtils.isBlank(channel.getId())) {
+ // create new Channel
+ if (StringUtils.equals(channel.getType(), MainContext.ChannelType.WEBIM.toString())) {
+ // create new WEBIM channel
+ licenseProxy.writeDownResourceUsageInStore(MainContext.BillingResource.CHANNELWEBIM, 1);
+ }
+ } else {
+ // update existed Channel
+ }
+ }
+}
diff --git a/contact-center/app/src/main/java/com/cskefu/cc/aspect/ContactsAspect.java b/contact-center/app/src/main/java/com/cskefu/cc/aspect/ContactsAspect.java
new file mode 100644
index 00000000..8c7f3e6b
--- /dev/null
+++ b/contact-center/app/src/main/java/com/cskefu/cc/aspect/ContactsAspect.java
@@ -0,0 +1,50 @@
+/*
+ * 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.aspect;
+
+import com.cskefu.cc.basic.MainContext;
+import com.cskefu.cc.basic.MainUtils;
+import com.cskefu.cc.exception.BillingQuotaException;
+import com.cskefu.cc.exception.BillingResourceException;
+import com.cskefu.cc.model.Contacts;
+import com.cskefu.cc.model.User;
+import com.cskefu.cc.proxy.LicenseProxy;
+import org.apache.commons.lang3.StringUtils;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Before;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Aspect
+@Component
+public class ContactsAspect {
+
+ private final static Logger logger = LoggerFactory.getLogger(ContactsAspect.class);
+
+ @Autowired
+ private LicenseProxy licenseProxy;
+
+ @Before("execution(* com.cskefu.cc.persistence.repository.ContactsRepository.save(..))")
+ public void beforeSave(final JoinPoint joinPoint) throws BillingResourceException, BillingQuotaException {
+ final Contacts contacts = (Contacts) joinPoint.getArgs()[0];
+ logger.info("[save] before contacts id {}", contacts.getId());
+ if (StringUtils.isBlank(contacts.getId())) {
+ // 执行配额扣除
+ licenseProxy.writeDownResourceUsageInStore(MainContext.BillingResource.CONTACT, 1);
+ contacts.setId(MainUtils.getUUID());
+ } else {
+ // update existed user
+ }
+ }
+}
diff --git a/contact-center/app/src/main/java/com/cskefu/cc/aspect/OrganAspect.java b/contact-center/app/src/main/java/com/cskefu/cc/aspect/OrganAspect.java
new file mode 100644
index 00000000..69e1f4a7
--- /dev/null
+++ b/contact-center/app/src/main/java/com/cskefu/cc/aspect/OrganAspect.java
@@ -0,0 +1,47 @@
+/*
+ * 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.aspect;
+
+import com.cskefu.cc.basic.MainContext;
+import com.cskefu.cc.exception.BillingQuotaException;
+import com.cskefu.cc.exception.BillingResourceException;
+import com.cskefu.cc.model.Channel;
+import com.cskefu.cc.model.Organ;
+import com.cskefu.cc.proxy.LicenseProxy;
+import org.apache.commons.lang3.StringUtils;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Before;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Aspect
+@Component
+public class OrganAspect {
+ private final static Logger logger = LoggerFactory.getLogger(OrganAspect.class);
+
+ @Autowired
+ private LicenseProxy licenseProxy;
+
+ @Before("execution(* com.cskefu.cc.persistence.repository.OrganRepository.save(..))")
+ public void beforeSave(final JoinPoint joinPoint) throws BillingResourceException, BillingQuotaException {
+ final Organ organ = (Organ) joinPoint.getArgs()[0];
+ logger.info("[beforeSave] before organ id {}", organ.getId());
+ if (StringUtils.isBlank(organ.getId())) {
+ // create new organ
+ licenseProxy.writeDownResourceUsageInStore(MainContext.BillingResource.ORGAN, 1);
+ } else {
+ // update existed Channel
+ }
+ }
+}
diff --git a/contact-center/app/src/main/java/com/cskefu/cc/aspect/UserAspect.java b/contact-center/app/src/main/java/com/cskefu/cc/aspect/UserAspect.java
new file mode 100644
index 00000000..1f67cc90
--- /dev/null
+++ b/contact-center/app/src/main/java/com/cskefu/cc/aspect/UserAspect.java
@@ -0,0 +1,47 @@
+/*
+ * 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.aspect;
+
+import com.cskefu.cc.basic.MainContext;
+import com.cskefu.cc.exception.BillingQuotaException;
+import com.cskefu.cc.exception.BillingResourceException;
+import com.cskefu.cc.model.User;
+import com.cskefu.cc.proxy.LicenseProxy;
+import org.apache.commons.lang3.StringUtils;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Before;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Aspect
+@Component
+public class UserAspect {
+
+ private final static Logger logger = LoggerFactory.getLogger(UserAspect.class);
+
+ @Autowired
+ private LicenseProxy licenseProxy;
+
+ @Before("execution(* com.cskefu.cc.persistence.repository.UserRepository.save(..))")
+ public void beforeSave(final JoinPoint joinPoint) throws BillingResourceException, BillingQuotaException {
+ final User user = (User) joinPoint.getArgs()[0];
+ logger.info("[save] before user id {}", user.getId());
+ if (StringUtils.isBlank(user.getId())) {
+ // 执行配额扣除
+ licenseProxy.writeDownResourceUsageInStore(MainContext.BillingResource.USER, 1);
+ } else {
+ // update existed user
+ }
+ }
+}
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 6df47781..8fc7cdfe 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,14 +1,14 @@
-/*
- * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd.
- * , Licensed under the Chunsong Public
+/*
+ * 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,
+ * 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;
@@ -217,4 +217,26 @@ public class Constants {
public static final String AUTH_TOKEN_TYPE_BEARER = "Bearer";
public static final String AUTH_TOKEN_TYPE_BASIC = "Basic";
+ /**
+ * License
+ */
+ public static final String PRODUCT_ID_CSKEFU001 = "cskefu001";
+ public static final String LICENSE_SERVER_INST_ID = "SERVERINSTID";
+ public static final String LICENSE_SERVICE_NAME = "SERVICENAME";
+ public static final String LICENSE_SERVICE_NAME_PREFIX = "春松客服";
+ public static final String LICENSEIDS = "LICENSEIDS";
+ public static final String METAKV_DATATYPE_STRING = "string";
+ public static final String METAKV_DATATYPE_INT = "int";
+ public static final String SHORTID = "shortId";
+ public static final String LICENSES = "licenses";
+ public static final String ADDDATE = "addDate";
+ public static final String LICENSE = "license";
+ public static final String UPDATETIME = "updateTime";
+ public static final String STATUS = "status";
+ public static final String PRODUCT = "product";
+ public static final String LICENSESTOREPROVIDER = "licenseStoreProvider";
+ public static final String USER = "user";
+ public static final String RESOURCES_USAGE_KEY_PREFIX = "RESOURCES_USAGE";
+ public static final String NEW_USER_SUCCESS = "new_user_success";
+ public static final String PRODUCT_ID = "productId";
}
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 753d6d74..8e3f25ce 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,15 +1,15 @@
/*
- * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd.
- * , Licensed under the Chunsong Public
+ * 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,
+ * 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,
+ * Copyright (C) 2017 优客服-多渠道客服系统, Licensed under the Apache License, Version 2.0,
* http://www.apache.org/licenses/LICENSE-2.0
*/
@@ -929,6 +929,31 @@ public class MainContext {
}
}
+ /**
+ * 计费资源
+ */
+ public enum BillingResource {
+ USER, // 系统用户
+ AGENGUSER, // 访客会话
+ CONTACT, // 联系人
+ ORGAN, // 组织机构
+ CHANNELWEBIM; // 网页渠道
+
+ @Override
+ public String toString() {
+ return super.toString().toLowerCase();
+ }
+
+ public static BillingResource toValue(final String str) {
+ for (final BillingResource item : values()) {
+ if (StringUtils.equalsIgnoreCase(item.toString(), str)) {
+ return item;
+ }
+ }
+ throw new IllegalArgumentException();
+ }
+ }
+
public static void setApplicationContext(ApplicationContext context) {
applicationContext = context;
context.getBean(TerminateBean.class);
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 234abb1a..51d4a6a8 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
@@ -24,6 +24,7 @@ import com.cskefu.cc.model.BlackEntity;
import com.cskefu.cc.model.SysDic;
import com.cskefu.cc.model.SystemConfig;
import com.cskefu.cc.persistence.repository.*;
+import com.cskefu.cc.proxy.LicenseProxy;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -36,7 +37,6 @@ public class AppCtxRefreshEventListener implements ApplicationListener, 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.chatopera.store.sdk.QuotaWdClient;
+import com.chatopera.store.sdk.exceptions.InvalidProviderException;
+import com.cskefu.cc.basic.MainContext;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.SpringApplication;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class QuotaWdClientConfig {
+
+ @Value("${license.store.provider}")
+ private String licenseStoreProvider;
+
+ /**
+ * 证书商店服务客户端
+ *
+ * @return
+ */
+ @Bean
+ public QuotaWdClient quotaWdClient() throws InvalidProviderException {
+ if (StringUtils.isBlank(licenseStoreProvider)) {
+ System.out.println("[license] invalid license provider info, service is terminated.");
+ System.exit(1);
+ }
+
+ QuotaWdClient quotaWdClient = new QuotaWdClient();
+ return quotaWdClient;
+ }
+}
diff --git a/contact-center/app/src/main/java/com/cskefu/cc/controller/admin/LicenseController.java b/contact-center/app/src/main/java/com/cskefu/cc/controller/admin/LicenseController.java
new file mode 100644
index 00000000..2c404e16
--- /dev/null
+++ b/contact-center/app/src/main/java/com/cskefu/cc/controller/admin/LicenseController.java
@@ -0,0 +1,231 @@
+/*
+ * 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.controller.admin;
+
+import com.chatopera.store.sdk.exceptions.InvalidRequestException;
+import com.chatopera.store.sdk.exceptions.InvalidResponseException;
+import com.cskefu.cc.basic.Constants;
+import com.cskefu.cc.controller.Handler;
+import com.cskefu.cc.exception.LicenseNotFoundException;
+import com.cskefu.cc.exception.MetaKvInvalidKeyException;
+import com.cskefu.cc.model.User;
+import com.cskefu.cc.proxy.LicenseProxy;
+import com.cskefu.cc.util.Menu;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.validation.Valid;
+import org.apache.commons.lang3.StringUtils;
+import org.json.JSONArray;
+import org.json.JSONObject;
+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.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.servlet.ModelAndView;
+
+import java.util.Date;
+import java.util.List;
+
+@Controller
+@RequestMapping("/admin/license")
+public class LicenseController extends Handler {
+ private final static Logger logger = LoggerFactory.getLogger(LicenseController.class);
+
+ @Autowired
+ private LicenseProxy licenseProxy;
+
+ @RequestMapping("/index")
+ @Menu(type = "admin", subtype = "licenseList")
+ public ModelAndView index(ModelMap map, HttpServletRequest request) {
+ User user = super.getUser(request);
+ if (user.isSuperadmin()) {
+ try {
+ List licenses = licenseProxy.getLicensesInStore();
+ map.addAttribute(Constants.UPDATETIME, new Date());
+ map.addAttribute(Constants.LICENSES, licenses);
+ map.addAttribute(Constants.LICENSESTOREPROVIDER, licenseProxy.getLicenseStoreProvider());
+
+ } catch (InvalidResponseException e) {
+ throw new RuntimeException(e);
+ }
+ return request(super.createView("/admin/license/index"));
+ } else {
+ return request(super.createView("/public/error"));
+ }
+ }
+
+ @RequestMapping("/add")
+ @Menu(type = "admin", subtype = "licenseList")
+ public ModelAndView add(ModelMap map, HttpServletRequest request) {
+ User user = super.getUser(request);
+ if (user.isSuperadmin()) {
+ return request(super.createView("/admin/license/add"));
+ } else {
+ return request(super.createView("/public/error"));
+ }
+ }
+
+ /**
+ * 保存新的证书
+ *
+ * @param map
+ * @param request
+ * @param licenseShortId
+ * @return
+ */
+ @RequestMapping("/save")
+ @Menu(type = "admin", subtype = "licenseList")
+ public ModelAndView save(ModelMap map,
+ HttpServletRequest request,
+ @Valid String licenseShortId) throws MetaKvInvalidKeyException, InvalidRequestException {
+ User user = super.getUser(request);
+ logger.info("[save] licenseShortId {}", licenseShortId);
+ String msg = "";
+
+ if (user.isSuperadmin()) {
+ try {
+ /**
+ * 验证证书可以添加
+ */
+ // 验证该证书不在当前证书列表中
+ JSONArray currents = licenseProxy.getLicensesInMetakv();
+ boolean isAddedBefore = false;
+
+ for (int i = 0; i < currents.length(); i++) {
+ JSONObject item = (JSONObject) currents.get(i);
+ if (StringUtils.equals(item.getString(Constants.SHORTID), licenseShortId)) {
+ isAddedBefore = true;
+ break;
+ }
+ }
+
+ if (isAddedBefore) {
+ msg = "already_added";
+ return request(super.createView(
+ "redirect:/admin/license/index.html?msg=" + msg));
+ }
+
+ // 验证该证书存在
+ licenseProxy.existLicenseInStore(licenseShortId);
+
+ // 验证该证书的所属产品没有现在没有其它证书:同一个产品最多只有一个证书
+ JSONObject licBasic = licenseProxy.getLicenseBasicsInStore(licenseShortId);
+ final String productId = licBasic.getJSONObject(Constants.PRODUCT).getString(Constants.SHORTID);
+
+ boolean isProductAdded = false;
+ JSONArray addedLicenseBasicsFromStore = licenseProxy.getAddedLicenseBasicsInStore();
+
+ for (int i = 0; i < addedLicenseBasicsFromStore.length(); i++) {
+ JSONObject item = (JSONObject) addedLicenseBasicsFromStore.get(i);
+ if (StringUtils.equals(item.getJSONObject(Constants.PRODUCT).getString(Constants.SHORTID), productId)) {
+ isProductAdded = true;
+ break;
+ }
+ }
+
+ if (isProductAdded) {
+ msg = "product_added_already";
+ return request(super.createView(
+ "redirect:/admin/license/index.html?msg=" + msg));
+ }
+
+ /**
+ * 添加该证书
+ */
+ JSONObject licenseKvData = new JSONObject();
+ licenseKvData.put(Constants.SHORTID, licenseShortId);
+ licenseKvData.put(Constants.ADDDATE, new Date());
+ licenseKvData.put(Constants.PRODUCT_ID, productId);
+ currents.put(0, licenseKvData);
+ licenseProxy.createOrUpdateMetaKv(Constants.LICENSEIDS, currents.toString(), Constants.METAKV_DATATYPE_STRING);
+
+ // 跳转回到证书列表
+ List licenses = licenseProxy.getLicensesInStore();
+ map.addAttribute(Constants.LICENSES, licenses);
+ map.addAttribute(Constants.UPDATETIME, new Date());
+ map.addAttribute(Constants.LICENSESTOREPROVIDER, licenseProxy.getLicenseStoreProvider());
+
+ return request(super.createView("/admin/license/index"));
+ } catch (InvalidResponseException e) {
+ logger.warn("[save] error in getLicenseFromStore", e);
+ msg = "invalid_id";
+ return request(super.createView(
+ "redirect:/admin/license/index.html?msg=" + msg));
+ } catch (LicenseNotFoundException e) {
+ logger.warn("[save] error in getLicenseFromStore", e);
+ msg = "notfound_id";
+ return request(super.createView(
+ "redirect:/admin/license/index.html?msg=" + msg));
+ }
+ } else {
+ return request(super.createView("/public/error"));
+ }
+ }
+
+ @RequestMapping("/delete/{licenseShortId}")
+ @Menu(type = "admin", subtype = "licenseList")
+ public ModelAndView delete(ModelMap map,
+ HttpServletRequest request,
+ @PathVariable String licenseShortId) throws MetaKvInvalidKeyException {
+ User user = super.getUser(request);
+ logger.info("[delete] licenseShortId {}", licenseShortId);
+ String msg = "";
+
+ if (user.isSuperadmin()) {
+ try {
+ JSONArray currents = licenseProxy.getLicensesInMetakv();
+ JSONArray post = new JSONArray();
+ for (int i = 0; i < currents.length(); i++) {
+ JSONObject item = (JSONObject) currents.get(i);
+ if (!StringUtils.equals(item.getString(Constants.SHORTID), licenseShortId)) {
+ post.put(item);
+ }
+ }
+
+ /**
+ * 添加该证书
+ */
+ licenseProxy.createOrUpdateMetaKv(Constants.LICENSEIDS, post.toString(), Constants.METAKV_DATATYPE_STRING);
+
+ // 跳转回到证书列表
+ List licenses = licenseProxy.getLicensesInStore();
+ map.addAttribute(Constants.LICENSES, licenses);
+ map.addAttribute("updateTime", new Date());
+ map.addAttribute(Constants.LICENSESTOREPROVIDER, licenseProxy.getLicenseStoreProvider());
+
+ return request(super.createView("/admin/license/index"));
+ } catch (InvalidResponseException e) {
+ logger.warn("[save] error in getLicenseFromStore", e);
+ msg = "invalid_id";
+ return request(super.createView(
+ "redirect:/admin/license/index.html?msg=" + msg));
+ }
+ } else {
+ return request(super.createView("/public/error"));
+ }
+ }
+
+ @RequestMapping("/instance")
+ @Menu(type = "admin", subtype = "licenseInst")
+ public ModelAndView getInstanceInfo(ModelMap map, HttpServletRequest request) {
+ User user = super.getUser(request);
+ if (user.isSuperadmin()) {
+ map.addAttribute(Constants.LICENSE_SERVICE_NAME, licenseProxy.resolveServicename());
+ map.addAttribute(Constants.LICENSE_SERVER_INST_ID, licenseProxy.resolveServerinstId());
+ map.addAttribute(Constants.LICENSESTOREPROVIDER, licenseProxy.getLicenseStoreProvider());
+ return request(super.createView("/admin/license/instance"));
+ } else {
+ return request(super.createView("/public/error"));
+ }
+ }
+}
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 dadf3216..d44d5087 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,15 +1,15 @@
/*
- * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd.
- * , Licensed under the Chunsong Public
+ * 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,
+ * 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,
+ * 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;
@@ -17,6 +17,7 @@ package com.cskefu.cc.controller.admin;
import com.cskefu.cc.basic.Constants;
import com.cskefu.cc.cache.Cache;
import com.cskefu.cc.controller.Handler;
+import com.cskefu.cc.exception.BillingQuotaException;
import com.cskefu.cc.model.*;
import com.cskefu.cc.persistence.repository.*;
import com.cskefu.cc.proxy.OrganProxy;
@@ -34,6 +35,8 @@ import org.springframework.web.servlet.ModelAndView;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
+
+import java.lang.reflect.UndeclaredThrowableException;
import java.util.*;
/**
@@ -157,16 +160,26 @@ public class OrganController extends Handler {
public ModelAndView save(HttpServletRequest request, @Valid Organ organ) {
Organ tempOrgan = organRepository.findByName(organ.getName());
String msg = "admin_organ_new_success";
- String firstId = null;
+ String createdId = null;
if (tempOrgan != null) {
msg = "admin_organ_update_name_not"; // 分类名字重复
} else {
- firstId = organ.getId();
-
- organRepository.save(organ);
+ try {
+ organRepository.save(organ);
+ createdId = organ.getId();
+ } catch (Exception e) {
+ if (e instanceof UndeclaredThrowableException) {
+ logger.error("[save] BillingQuotaException", e);
+ if (StringUtils.startsWith(e.getCause().getMessage(), BillingQuotaException.SUFFIX)) {
+ msg = e.getCause().getMessage();
+ }
+ } else {
+ logger.error("[save] err", e);
+ }
+ }
}
return request(super.createView(
- "redirect:/admin/organ/index.html?msg=" + msg + "&organ=" + firstId));
+ "redirect:/admin/organ/index.html?msg=" + msg + "&organ=" + createdId));
}
/**
diff --git a/contact-center/app/src/main/java/com/cskefu/cc/controller/admin/channel/ChannelController.java b/contact-center/app/src/main/java/com/cskefu/cc/controller/admin/channel/ChannelController.java
index 93c5ff0f..53a7cf18 100644
--- a/contact-center/app/src/main/java/com/cskefu/cc/controller/admin/channel/ChannelController.java
+++ b/contact-center/app/src/main/java/com/cskefu/cc/controller/admin/channel/ChannelController.java
@@ -1,15 +1,15 @@
/*
- * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd.
- * , Licensed under the Chunsong Public
+ * 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,
+ * 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,
+ * 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;
@@ -18,6 +18,7 @@ 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.exception.BillingQuotaException;
import com.cskefu.cc.model.*;
import com.cskefu.cc.persistence.repository.ConsultInviteRepository;
import com.cskefu.cc.persistence.repository.OrganRepository;
@@ -27,6 +28,8 @@ 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.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Controller;
@@ -37,6 +40,8 @@ import org.springframework.web.servlet.ModelAndView;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
+
+import java.lang.reflect.UndeclaredThrowableException;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.List;
@@ -48,6 +53,7 @@ import java.util.Map;
@Controller
@RequestMapping("/admin/im")
public class ChannelController extends Handler {
+ private final static Logger logger = LoggerFactory.getLogger(ChannelController.class);
@Autowired
private ChannelRepository snsAccountRes;
@@ -93,40 +99,59 @@ public class ChannelController extends Handler {
return request(super.createView("/admin/channel/im/add"));
}
+ /**
+ * 创建新的网站渠道
+ *
+ * @param request
+ * @param channel
+ * @return
+ * @throws NoSuchAlgorithmException
+ */
@RequestMapping("/save")
- @Menu(type = "admin", subtype = "weixin")
+ @Menu(type = "admin", subtype = "im")
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());
+ try {
+ 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);
+ 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);
+ /**
+ * 同时创建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);
+ }
+ }
+ } catch (Exception e) {
+ if (e instanceof UndeclaredThrowableException) {
+ logger.error("[save] BillingQuotaException", e);
+ if (StringUtils.startsWith(e.getCause().getMessage(), BillingQuotaException.SUFFIX)) {
+ status = e.getCause().getMessage();
+ }
+ } else {
+ logger.error("[save] err", e);
}
}
}
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 fba17dac..a9208a84 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
@@ -41,7 +41,7 @@ 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;
diff --git a/contact-center/app/src/main/java/com/cskefu/cc/controller/api/ApiContactsController.java b/contact-center/app/src/main/java/com/cskefu/cc/controller/api/ApiContactsController.java
index dbcb38bc..b28e4df7 100644
--- a/contact-center/app/src/main/java/com/cskefu/cc/controller/api/ApiContactsController.java
+++ b/contact-center/app/src/main/java/com/cskefu/cc/controller/api/ApiContactsController.java
@@ -46,6 +46,8 @@ import org.springframework.web.bind.annotation.RestController;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
+
+import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Optional;
@@ -84,7 +86,7 @@ public class ApiContactsController extends Handler {
if (!StringUtils.isBlank(creater)) {
User user = super.getUser(request);
- contactsList = contactsRepository.findByCreaterAndSharesAndDatastatus(user.getId(), "all", false,
+ contactsList = contactsRepository.findByCreaterAndSharesInAndDatastatus(user.getId(), Arrays.asList(user.getId(),"all"), false,
PageRequest.of(
super.getP(request),
super.getPs(request)));
diff --git a/contact-center/app/src/main/java/com/cskefu/cc/controller/api/ApiUserController.java b/contact-center/app/src/main/java/com/cskefu/cc/controller/api/ApiUserController.java
index 86cfb791..08956ef1 100644
--- a/contact-center/app/src/main/java/com/cskefu/cc/controller/api/ApiUserController.java
+++ b/contact-center/app/src/main/java/com/cskefu/cc/controller/api/ApiUserController.java
@@ -1,15 +1,15 @@
/*
- * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd.
- * , Licensed under the Chunsong Public
+ * 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,
+ * 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,
+ * Copyright (C) 2017 优客服-多渠道客服系统, Licensed under the Apache License, Version 2.0,
* http://www.apache.org/licenses/LICENSE-2.0
*/
package com.cskefu.cc.controller.api;
@@ -183,7 +183,9 @@ public class ApiUserController extends Handler {
User user = userProxy.parseUserFromJson(payload);
JsonObject resp = userProxy.createNewUser(user, parentOrgan);
- if (StringUtils.isNotEmpty(roleId)) {
+ if (StringUtils.isNotEmpty(roleId) &&
+ StringUtils.equals(resp.get(RestUtils.RESP_KEY_DATA).getAsString(),
+ Constants.NEW_USER_SUCCESS)) {
Role role = roleRes.findById(roleId).orElse(null);
UserRole userRole = new UserRole();
userRole.setUser(user);
diff --git a/contact-center/app/src/main/java/com/cskefu/cc/controller/apps/AgentAuditController.java b/contact-center/app/src/main/java/com/cskefu/cc/controller/apps/AgentAuditController.java
index e781cf0b..86c7e958 100644
--- a/contact-center/app/src/main/java/com/cskefu/cc/controller/apps/AgentAuditController.java
+++ b/contact-center/app/src/main/java/com/cskefu/cc/controller/apps/AgentAuditController.java
@@ -71,9 +71,6 @@ public class AgentAuditController extends Handler {
@Autowired
private UserRepository userRes;
- @Autowired
- private AgentUserRepository agentUserRepository;
-
@Autowired
private ChatMessageRepository chatMessageRepository;
@@ -245,7 +242,7 @@ public class AgentAuditController extends Handler {
view.addObject(
"agentUserList", agentUserRes.findByStatusAndAgentnoIsNot(
MainContext.AgentUserStatusEnum.INSERVICE.toString(), logined.getId(), defaultSort));
- List agentUserList = agentUserRepository.findByUserid(userid);
+ List agentUserList = agentUserRes.findByUserid(userid);
view.addObject(
"curagentuser", agentUserList != null && agentUserList.size() > 0 ? agentUserList.get(0) : null);
@@ -266,7 +263,7 @@ public class AgentAuditController extends Handler {
}
ModelAndView view = request(super.createView(mainagentuser));
final User logined = super.getUser(request);
- AgentUser agentUser = agentUserRepository.findById(id).orElse(null);
+ AgentUser agentUser = agentUserRes.findById(id).orElse(null);
if (agentUser != null) {
view.addObject("curagentuser", agentUser);
diff --git a/contact-center/app/src/main/java/com/cskefu/cc/controller/apps/AgentController.java b/contact-center/app/src/main/java/com/cskefu/cc/controller/apps/AgentController.java
index dc4e0935..431bd2d0 100644
--- a/contact-center/app/src/main/java/com/cskefu/cc/controller/apps/AgentController.java
+++ b/contact-center/app/src/main/java/com/cskefu/cc/controller/apps/AgentController.java
@@ -1252,4 +1252,4 @@
return request(super.createView("redirect:/agent/index.html"));
}
- }
+ }
\ No newline at end of file
diff --git a/contact-center/app/src/main/java/com/cskefu/cc/controller/apps/ContactsController.java b/contact-center/app/src/main/java/com/cskefu/cc/controller/apps/ContactsController.java
index ad9f4401..3bb55b2a 100644
--- a/contact-center/app/src/main/java/com/cskefu/cc/controller/apps/ContactsController.java
+++ b/contact-center/app/src/main/java/com/cskefu/cc/controller/apps/ContactsController.java
@@ -1,21 +1,22 @@
/*
- * Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd.
- * , Licensed under the Chunsong Public
+ * 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,
+ * 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,
+ * Copyright (C) 2017 优客服-多渠道客服系统, Licensed under the Apache License, Version 2.0,
* http://www.apache.org/licenses/LICENSE-2.0
*/
package com.cskefu.cc.controller.apps;
import com.cskefu.cc.basic.MainUtils;
import com.cskefu.cc.controller.Handler;
+import com.cskefu.cc.exception.BillingQuotaException;
import com.cskefu.cc.exception.CSKefuException;
import com.cskefu.cc.model.*;
import com.cskefu.cc.persistence.repository.*;
@@ -47,8 +48,10 @@ import org.springframework.web.servlet.ModelAndView;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
+
import java.io.File;
import java.io.IOException;
+import java.lang.reflect.UndeclaredThrowableException;
import java.text.SimpleDateFormat;
import java.util.*;
@@ -143,8 +146,8 @@ public class ContactsController extends Handler {
map.put("ckind", ckind);
}
- Page contacts = contactsRes.findByCreaterAndSharesAndDatastatus(logined.getId(),
- logined.getId(),
+ Page contacts = contactsRes.findByCreaterAndSharesInAndDatastatus(logined.getId(),
+ Arrays.asList(logined.getId(),"all"),
false,
PageRequest.of(
super.getP(request),
@@ -177,8 +180,8 @@ public class ContactsController extends Handler {
map.put("ckind", ckind);
}
- Page contacts = contactsRes.findByCreaterAndSharesAndDatastatus(logined.getId(),
- logined.getId(),
+ Page contacts = contactsRes.findByCreaterAndSharesInAndDatastatus(logined.getId(),
+ Arrays.asList(logined.getId(),"all"),
false,
PageRequest.of(
super.getP(request),
@@ -211,8 +214,8 @@ public class ContactsController extends Handler {
map.put("ckind", ckind);
}
- Page contacts = contactsRes.findByCreaterAndSharesAndDatastatus(logined.getId(),
- logined.getId(),
+ Page contacts = contactsRes.findByCreaterAndSharesInAndDatastatus(logined.getId(),
+ Arrays.asList(logined.getId(),"all"),
false,
PageRequest.of(
super.getP(request),
@@ -255,13 +258,11 @@ public class ContactsController extends Handler {
@RequestParam(name = "idselflocation", required = false) String selflocation) {
final User logined = super.getUser(request);
Organ currentOrgan = super.getOrgan(request);
- String skypeIDReplace = contactsProxy.sanitizeSkypeId(contacts.getSkypeid());
String msg = "";
- Contacts contact = contactsRes.findByskypeidAndDatastatus(skypeIDReplace, false);
// 添加数据
- if (contacts.getSkypeid() != null && contact == null) {
- logger.info("[save] 数据库没有相同skypeid");
+ try {
+ contacts.setId(null);
contacts.setCreater(logined.getId());
if (currentOrgan != null && StringUtils.isBlank(contacts.getOrgan())) {
@@ -274,11 +275,16 @@ public class ContactsController extends Handler {
}
contactsRes.save(contacts);
msg = "new_contacts_success";
-
- return request(super.createView(
- "redirect:/apps/contacts/index.html?ckind=" + contacts.getCkind() + "&msg=" + msg));
+ } catch (Exception e) {
+ if (e instanceof UndeclaredThrowableException) {
+ logger.error("[save] BillingQuotaException", e);
+ if (StringUtils.startsWith(e.getCause().getMessage(), BillingQuotaException.SUFFIX)) {
+ msg = e.getCause().getMessage();
+ }
+ } else {
+ logger.error("[save] err", e);
+ }
}
- msg = "new_contacts_fail";
return request(super.createView(
"redirect:/apps/contacts/index.html?ckind=" + contacts.getCkind() + "&msg=" + msg));
}
@@ -478,8 +484,8 @@ public class ContactsController extends Handler {
map.put("ckind", ckind);
}
- Iterable contactsList = contactsRes.findByCreaterAndSharesAndDatastatus(
- logined.getId(), logined.getId(), false, PageRequest.of(super.getP(request), super.getPs(request)));
+ Iterable contactsList = contactsRes.findByCreaterAndSharesInAndDatastatus(
+ logined.getId(), Arrays.asList(logined.getId(),"all"),false, PageRequest.of(super.getP(request), super.getPs(request)));
MetadataTable table = metadataRes.findByTablename("uk_contacts");
List