mirror of
https://github.com/chatopera/cosin.git
synced 2025-07-11 20:17:03 +08:00
https://gitee.com/cskefu/cskefu/issues/I836RO enable billing for agentuser resources
Signed-off-by: Hai Liang Wang <hai@chatopera.com>
This commit is contained in:
parent
a14671b70d
commit
8c0448f7fc
@ -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<ACDComposeContext> {
|
||||
@Autowired
|
||||
private ACDMessageHelper acdMessageHelper;
|
||||
|
||||
@Autowired
|
||||
private LicenseProxy licenseProxy;
|
||||
|
||||
/**
|
||||
* 设置AgentUser基本信息
|
||||
*
|
||||
@ -87,6 +92,16 @@ public class ACDVisBodyParserMw implements Middleware<ACDComposeContext> {
|
||||
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;
|
||||
});
|
||||
|
@ -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];
|
||||
|
@ -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<AgentUser> agentUserList = agentUserRepository.findByUserid(userid);
|
||||
List<AgentUser> 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);
|
||||
|
@ -61,6 +61,7 @@
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.Valid;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.text.ParseException;
|
||||
@ -245,7 +246,10 @@
|
||||
ModelMap map,
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response,
|
||||
@Valid String sort) throws IOException {
|
||||
@Valid String sort,
|
||||
boolean licenseVerifiedPass,
|
||||
String licenseBillingMsg) throws IOException {
|
||||
logger.info("[index] licenseVerifiedPass {}, licenseBillingMsg {}", licenseVerifiedPass, licenseBillingMsg);
|
||||
final User logined = super.getUser(request);
|
||||
ModelAndView view = request(super.createView("/apps/agent/index"));
|
||||
agentUserProxy.buildIndexViewWithModels(view, map, request, response, sort, logined, null);
|
||||
@ -254,7 +258,11 @@
|
||||
|
||||
@RequestMapping("/agentusers")
|
||||
@Menu(type = "apps", subtype = "agent")
|
||||
public ModelAndView agentusers(HttpServletRequest request, String userid) {
|
||||
public ModelAndView agentusers(HttpServletRequest request,
|
||||
String userid,
|
||||
boolean licenseVerifiedPass,
|
||||
String licenseBillingMsg) {
|
||||
logger.info("[agentusers] userid {}, licenseVerifiedPass {}, licenseBillingMsg {}", userid, licenseVerifiedPass, licenseBillingMsg);
|
||||
ModelAndView view = request(super.createView("/apps/agent/agentusers"));
|
||||
User logined = super.getUser(request);
|
||||
view.addObject(
|
||||
@ -263,7 +271,8 @@
|
||||
List<AgentUser> agentUserList = agentUserRes.findByUserid(userid);
|
||||
view.addObject(
|
||||
"curagentuser", agentUserList != null && agentUserList.size() > 0 ? agentUserList.get(0) : null);
|
||||
|
||||
view.addObject("licenseVerifiedPass", licenseVerifiedPass);
|
||||
view.addObject("licenseBillingMsg", licenseBillingMsg);
|
||||
return view;
|
||||
}
|
||||
|
||||
|
@ -117,7 +117,7 @@ public class IMController extends Handler {
|
||||
private LeaveMsgRepository leaveMsgRes;
|
||||
|
||||
@Autowired
|
||||
private AgentUserRepository agentUserRepository;
|
||||
private AgentUserRepository agentUserRes;
|
||||
|
||||
@Autowired
|
||||
private AttachmentRepository attachementRes;
|
||||
@ -822,7 +822,7 @@ public class IMController extends Handler {
|
||||
Contacts contacts1 = contactsRes.findOneByWluidAndWlsidAndWlcidAndDatastatus(
|
||||
uid, sid, cid, false);
|
||||
if (contacts1 != null) {
|
||||
agentUserRepository.findOneByUserid(userid).ifPresent(p -> {
|
||||
agentUserRes.findOneByUserid(userid).ifPresent(p -> {
|
||||
// 关联AgentService的联系人
|
||||
if (StringUtils.isNotBlank(p.getAgentserviceid())) {
|
||||
AgentService agentService = agentServiceRepository.findById(p.getAgentserviceid()).orElse(null);
|
||||
|
@ -77,9 +77,6 @@ public class ChatServiceController extends Handler {
|
||||
@Autowired
|
||||
private AgentStatusRepository agentStatusRepository;
|
||||
|
||||
@Autowired
|
||||
private AgentUserRepository agentUserRepository;
|
||||
|
||||
@Autowired
|
||||
private LeaveMsgRepository leaveMsgRes;
|
||||
|
||||
@ -233,7 +230,7 @@ public class ChatServiceController extends Handler {
|
||||
if (agentUser != null) {
|
||||
agentUser.setAgentno(agentno);
|
||||
agentUser.setAgentname(targetAgent.getUname());
|
||||
agentUserRepository.save(agentUser);
|
||||
agentUserRes.save(agentUser);
|
||||
if (MainContext.AgentUserStatusEnum.INSERVICE.toString().equals(
|
||||
agentUser.getStatus())) {
|
||||
// 转接 , 发送消息给 目标坐席
|
||||
@ -288,11 +285,11 @@ public class ChatServiceController extends Handler {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
agentUser = agentUserRepository.findById(agentService.getAgentuserid()).orElse(null);
|
||||
agentUser = agentUserRes.findById(agentService.getAgentuserid()).orElse(null);
|
||||
if (agentUser != null) {
|
||||
agentUser.setAgentno(agentno);
|
||||
agentUser.setAgentname(targetAgent.getUname());
|
||||
agentUserRepository.save(agentUser);
|
||||
agentUserRes.save(agentUser);
|
||||
}
|
||||
}
|
||||
|
||||
@ -317,7 +314,7 @@ public class ChatServiceController extends Handler {
|
||||
AgentService agentService = agentServiceRes.findById(id).orElse(null);
|
||||
if (agentService != null) {
|
||||
User user = super.getUser(request);
|
||||
AgentUser agentUser = agentUserRepository.findById(agentService.getAgentuserid()).orElse(null);
|
||||
AgentUser agentUser = agentUserRes.findById(agentService.getAgentuserid()).orElse(null);
|
||||
if (agentUser != null) {
|
||||
acdAgentService.finishAgentUser(agentUser);
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ import org.hibernate.annotations.GenericGenerator;
|
||||
import org.hibernate.annotations.Proxy;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
@ -105,6 +106,7 @@ public class AgentUser implements Serializable, Comparable<AgentUser> {
|
||||
|
||||
@Transient
|
||||
private boolean tip = false;
|
||||
|
||||
@Transient
|
||||
private boolean agentTip = false;
|
||||
|
||||
@ -119,11 +121,25 @@ public class AgentUser implements Serializable, Comparable<AgentUser> {
|
||||
|
||||
@Transient
|
||||
private boolean fromhis = false;
|
||||
|
||||
@Transient
|
||||
private boolean online = false;
|
||||
|
||||
@Transient
|
||||
private boolean disconnect = false;
|
||||
|
||||
/**
|
||||
* 证书验证通过
|
||||
*/
|
||||
@Transient
|
||||
private boolean licenseVerifiedPass = true;
|
||||
|
||||
/**
|
||||
* 证书验证提示信息
|
||||
*/
|
||||
@Transient
|
||||
private String licenseBillingMsg;
|
||||
|
||||
|
||||
public AgentUser() {
|
||||
}
|
||||
@ -617,4 +633,22 @@ public class AgentUser implements Serializable, Comparable<AgentUser> {
|
||||
public void setAgentname(String agentname) {
|
||||
this.agentname = agentname;
|
||||
}
|
||||
|
||||
@Transient
|
||||
public boolean isLicenseVerifiedPass() {
|
||||
return licenseVerifiedPass;
|
||||
}
|
||||
|
||||
public void setLicenseVerifiedPass(boolean licenseVerifiedPass) {
|
||||
this.licenseVerifiedPass = licenseVerifiedPass;
|
||||
}
|
||||
|
||||
@Transient
|
||||
public String getLicenseBillingMsg() {
|
||||
return licenseBillingMsg;
|
||||
}
|
||||
|
||||
public void setLicenseBillingMsg(String licenseBillingMsg) {
|
||||
this.licenseBillingMsg = licenseBillingMsg;
|
||||
}
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ import org.springframework.web.servlet.ModelAndView;
|
||||
import jakarta.servlet.http.Cookie;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
@ -96,6 +97,8 @@ public class AgentUserProxy {
|
||||
@Lazy
|
||||
private PeerSyncIM peerSyncIM;
|
||||
|
||||
@Autowired
|
||||
private LicenseProxy licenseProxy;
|
||||
|
||||
/**
|
||||
* 与联系人主动聊天前查找获取AgentUser
|
||||
|
@ -19,6 +19,7 @@ import com.cskefu.cc.basic.Constants;
|
||||
import com.cskefu.cc.basic.MainContext;
|
||||
import com.cskefu.cc.basic.MainUtils;
|
||||
import com.cskefu.cc.exception.*;
|
||||
import com.cskefu.cc.model.AgentUser;
|
||||
import com.cskefu.cc.model.ExecuteResult;
|
||||
import com.cskefu.cc.model.MetaKv;
|
||||
import com.cskefu.cc.persistence.repository.MetaKvRepository;
|
||||
@ -511,5 +512,33 @@ public class LicenseProxy {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 访客会话执行计费
|
||||
*
|
||||
* @param agentUser
|
||||
* @return
|
||||
*/
|
||||
public ExecuteResult writeDownAgentUserUsageInStore(final AgentUser agentUser) {
|
||||
// 检查是否还在体验阶段
|
||||
ExecuteResult er = new ExecuteResult();
|
||||
int alreadyUsed = getResourceUsageInMetaKv(MainContext.BillingResource.AGENGUSER);
|
||||
if (alreadyUsed <= 100) {
|
||||
// 可以免费创建 100 个访客会话
|
||||
er.setRc(ExecuteResult.RC_SUCC);
|
||||
return er;
|
||||
}
|
||||
|
||||
try {
|
||||
writeDownResourceUsageInStore(MainContext.BillingResource.AGENGUSER, 1);
|
||||
er.setRc(ExecuteResult.RC_SUCC);
|
||||
} catch (BillingQuotaException e) {
|
||||
er.setRc(ExecuteResult.RC_ERR1);
|
||||
er.setMsg(e.getMessage());
|
||||
} catch (BillingResourceException e) {
|
||||
er.setRc(ExecuteResult.RC_ERR2);
|
||||
er.setMsg(e.getMessage());
|
||||
}
|
||||
|
||||
return er;
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,10 @@ newmessage['mp3'] = '/images/message.mp3';
|
||||
ring['mp3'] = '/images/ring.mp3';
|
||||
$(document).ready(function () {
|
||||
var protocol = window.location.protocol.replace(/:/g, '');
|
||||
socket = io(protocol+'://'+hostname+':'+port+"/im/agent?userid="+userid+"&session="+session+"&admin="+adminuser , {transports: ['websocket'], upgrade: false});
|
||||
socket = io(protocol + '://' + hostname + ':' + port + "/im/agent?userid=" + userid + "&session=" + session + "&admin=" + adminuser, {
|
||||
transports: ['websocket'],
|
||||
upgrade: false
|
||||
});
|
||||
socket.on('connect', function () {
|
||||
console.log("[IM] 连接初始化成功");
|
||||
//请求服务端记录 当前用户在线事件
|
||||
@ -30,8 +33,8 @@ $(document).ready(function(){
|
||||
socket.on('chatevent', function (data) {
|
||||
// console.log(data.messageType + " ..... message:"+data.message);
|
||||
}).on('task', function (data) {
|
||||
|
||||
}).on('new', function (data) {
|
||||
console.log("new data ...", data);
|
||||
if ($('#customerChatAudit').length > 0) {
|
||||
if (customerChatAudit.$('#agentuser_' + data.userid).length > 0 && customerChatAudit.$("#chat_users li").length > 1) {
|
||||
customerChatAudit.$('#agentuser_' + data.userid).remove();
|
||||
@ -49,11 +52,15 @@ $(document).ready(function(){
|
||||
"</div>");
|
||||
}
|
||||
}
|
||||
if($('#multiMediaDialogWin').length > 0 && multiMediaDialogWin != null && multiMediaDialogWin.$ &&multiMediaDialogWin.$('#agentusers').length > 0){
|
||||
|
||||
if ($('#multiMediaDialogWin').length > 0 &&
|
||||
multiMediaDialogWin != null &&
|
||||
multiMediaDialogWin.$ &&
|
||||
multiMediaDialogWin.$('#agentusers').length > 0) {
|
||||
multiMediaDialogWin.Proxy.newAgentUserService(data, "agent");
|
||||
} else {
|
||||
//来电弹屏
|
||||
$('#agentdesktop').attr('data-href' , '/agent/index.html?userid='+data.userid).click();
|
||||
$('#agentdesktop').attr('data-href', '/agent/index.html?userid=' + data.userid + '&licenseVerifiedPass=' + data.licenseVerifiedPass + '&licenseBillingMsg=' + data.licenseBillingMsg).click();
|
||||
WebIM.audioplayer('audioplane', newuser, false); // 播放
|
||||
}
|
||||
}).on('status', function (data) {
|
||||
|
@ -343,6 +343,7 @@ function newMessageScorllBottom(type, msgType) {
|
||||
|
||||
var Proxy = {
|
||||
newAgentUserService: function (data, type) {
|
||||
console.log("newAgentUserService data type", data, type)
|
||||
if ($('#tip_message_' + data.userid).length > 0) {
|
||||
var channel = data.channeltype
|
||||
if (channel) {
|
||||
@ -356,9 +357,9 @@ var Proxy = {
|
||||
} else {
|
||||
if ($('.chat-list-item.active').length > 0) {
|
||||
var id = $('.chat-list-item.active').data('id');
|
||||
type == "agent" ? loadURL('/agent/agentusers.html?newuser=true&userid=' + id, '#agentusers') : loadURL('/apps/cca/agentusers.html?newuser=true&userid=' + id, '#agentuserscca');
|
||||
type == "agent" ? loadURL('/agent/agentusers.html?newuser=true&userid=' + id + '&licenseVerifiedPass=' + data.licenseVerifiedPass + '&licenseBillingMsg=' + data.licenseBillingMsg, '#agentusers') : loadURL('/apps/cca/agentusers.html?newuser=true&userid=' + id + "&licenseVerifiedPass=" + data.licenseVerifiedPass + "&licenseBillingMsg=" + data.licenseBillingMsg, '#agentuserscca');
|
||||
} else {
|
||||
type == "agent" ? location.href = "/agent/index.html?newuser=true" : location.href = "/apps/cca/index.html?newuser=true";
|
||||
type == "agent" ? location.href = "/agent/index.html?newuser=true&licenseVerifiedPass=" + data.licenseVerifiedPass + "&licenseBillingMsg=" + data.licenseBillingMsg : location.href = "/apps/cca/index.html?newuser=true&licenseVerifiedPass=" + data.licenseVerifiedPass + "&licenseBillingMsg=" + data.licenseBillingMsg;
|
||||
}
|
||||
}
|
||||
if (data.userid == cursession) {
|
||||
@ -504,7 +505,11 @@ var Proxy = {
|
||||
}
|
||||
},
|
||||
tipMsgForm: function (href) {
|
||||
top.layer.prompt({formType: 2, title: '请输入拉黑原因', area: ['300px', '50px']}, function (value, index, elem) {
|
||||
top.layer.prompt({
|
||||
formType: 2,
|
||||
title: '请输入拉黑原因',
|
||||
area: ['300px', '50px']
|
||||
}, function (value, index, elem) {
|
||||
location.href = href + "&description=" + encodeURIComponent(value);
|
||||
top.layer.close(index);
|
||||
});
|
||||
|
@ -80,3 +80,11 @@
|
||||
.last-msg
|
||||
small.ukefu-badge.bg-red(id="last_msg_" + agentuser.userid,style="#{(agentuser.tokenum == 0 || (curagentuser && curagentuser.id == agentuser.id)) ? 'display:none' : ''}")
|
||||
| #{agentuser.tokenum ? agentuser.tokenum : 0}
|
||||
script(language="javascript").
|
||||
$(document).ready(function () {
|
||||
var licenseVerifiedPass = #{licenseVerifiedPass};
|
||||
var licenseBillingMsg = '#{licenseBillingMsg}';
|
||||
if (licenseBillingMsg) {
|
||||
handleGeneralCodeInQueryPathOrApiResp(licenseBillingMsg);
|
||||
}
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user