mirror of
https://github.com/chatopera/cosin.git
synced 2025-06-16 18:30:03 +08:00
https://gitee.com/cskefu/cskefu/issues/I836RO enable writedown qutoa for user account creation
Signed-off-by: Hai Liang Wang <hai@chatopera.com>
This commit is contained in:
parent
1cc39f5901
commit
c6f9726ef3
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd.
|
||||||
|
* <https://www.chatopera.com>, 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -220,12 +220,13 @@ public class Constants {
|
|||||||
/**
|
/**
|
||||||
* License
|
* License
|
||||||
*/
|
*/
|
||||||
public static final String PRODUCT_BASIC_ID = "cskefu001";
|
public static final String PRODUCT_ID_CSKEFU001 = "cskefu001";
|
||||||
public static final String LICENSE_SERVER_INST_ID = "SERVERINSTID";
|
public static final String LICENSE_SERVER_INST_ID = "SERVERINSTID";
|
||||||
public static final String LICENSE_SERVICE_NAME = "SERVICENAME";
|
public static final String LICENSE_SERVICE_NAME = "SERVICENAME";
|
||||||
public static final String LICENSE_SERVICE_NAME_PREFIX = "春松客服";
|
public static final String LICENSE_SERVICE_NAME_PREFIX = "春松客服";
|
||||||
public static final String LICENSEIDS = "LICENSEIDS";
|
public static final String LICENSEIDS = "LICENSEIDS";
|
||||||
public static final String METAKV_DATATYPE_STRING = "string";
|
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 SHORTID = "shortId";
|
||||||
public static final String LICENSES = "licenses";
|
public static final String LICENSES = "licenses";
|
||||||
public static final String ADDDATE = "addDate";
|
public static final String ADDDATE = "addDate";
|
||||||
@ -234,4 +235,8 @@ public class Constants {
|
|||||||
public static final String STATUS = "status";
|
public static final String STATUS = "status";
|
||||||
public static final String PRODUCT = "product";
|
public static final String PRODUCT = "product";
|
||||||
public static final String LICENSESTOREPROVIDER = "licenseStoreProvider";
|
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";
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
public static void setApplicationContext(ApplicationContext context) {
|
||||||
applicationContext = context;
|
applicationContext = context;
|
||||||
context.getBean(TerminateBean.class);
|
context.getBean(TerminateBean.class);
|
||||||
|
@ -38,8 +38,8 @@ import java.util.List;
|
|||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
@RequestMapping("/admin/license")
|
@RequestMapping("/admin/license")
|
||||||
public class LicenseCtrl extends Handler {
|
public class LicenseController extends Handler {
|
||||||
private final static Logger logger = LoggerFactory.getLogger(LicenseCtrl.class);
|
private final static Logger logger = LoggerFactory.getLogger(LicenseController.class);
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private LicenseProxy licenseProxy;
|
private LicenseProxy licenseProxy;
|
||||||
@ -50,7 +50,7 @@ public class LicenseCtrl extends Handler {
|
|||||||
User user = super.getUser(request);
|
User user = super.getUser(request);
|
||||||
if (user.isSuperadmin()) {
|
if (user.isSuperadmin()) {
|
||||||
try {
|
try {
|
||||||
List<JSONObject> licenses = licenseProxy.getLicensesFromStore();
|
List<JSONObject> licenses = licenseProxy.getLicensesInStore();
|
||||||
map.addAttribute(Constants.UPDATETIME, new Date());
|
map.addAttribute(Constants.UPDATETIME, new Date());
|
||||||
map.addAttribute(Constants.LICENSES, licenses);
|
map.addAttribute(Constants.LICENSES, licenses);
|
||||||
map.addAttribute(Constants.LICENSESTOREPROVIDER, licenseProxy.getLicenseStoreProvider());
|
map.addAttribute(Constants.LICENSESTOREPROVIDER, licenseProxy.getLicenseStoreProvider());
|
||||||
@ -119,11 +119,11 @@ public class LicenseCtrl extends Handler {
|
|||||||
licenseProxy.existLicenseInStore(licenseShortId);
|
licenseProxy.existLicenseInStore(licenseShortId);
|
||||||
|
|
||||||
// 验证该证书的所属产品没有现在没有其它证书:同一个产品最多只有一个证书
|
// 验证该证书的所属产品没有现在没有其它证书:同一个产品最多只有一个证书
|
||||||
JSONObject licBasic = licenseProxy.getLicenseBasicsFromStore(licenseShortId);
|
JSONObject licBasic = licenseProxy.getLicenseBasicsInStore(licenseShortId);
|
||||||
final String productId = licBasic.getJSONObject(Constants.PRODUCT).getString(Constants.SHORTID);
|
final String productId = licBasic.getJSONObject(Constants.PRODUCT).getString(Constants.SHORTID);
|
||||||
|
|
||||||
boolean isProductAdded = false;
|
boolean isProductAdded = false;
|
||||||
JSONArray addedLicenseBasicsFromStore = licenseProxy.getAddedLicenseBasicsFromStore();
|
JSONArray addedLicenseBasicsFromStore = licenseProxy.getAddedLicenseBasicsInStore();
|
||||||
|
|
||||||
for (int i = 0; i < addedLicenseBasicsFromStore.length(); i++) {
|
for (int i = 0; i < addedLicenseBasicsFromStore.length(); i++) {
|
||||||
JSONObject item = (JSONObject) addedLicenseBasicsFromStore.get(i);
|
JSONObject item = (JSONObject) addedLicenseBasicsFromStore.get(i);
|
||||||
@ -145,11 +145,12 @@ public class LicenseCtrl extends Handler {
|
|||||||
JSONObject licenseKvData = new JSONObject();
|
JSONObject licenseKvData = new JSONObject();
|
||||||
licenseKvData.put(Constants.SHORTID, licenseShortId);
|
licenseKvData.put(Constants.SHORTID, licenseShortId);
|
||||||
licenseKvData.put(Constants.ADDDATE, new Date());
|
licenseKvData.put(Constants.ADDDATE, new Date());
|
||||||
|
licenseKvData.put(Constants.PRODUCT_ID, productId);
|
||||||
currents.put(0, licenseKvData);
|
currents.put(0, licenseKvData);
|
||||||
licenseProxy.createOrUpdateMetaKv(Constants.LICENSEIDS, currents.toString(), Constants.METAKV_DATATYPE_STRING);
|
licenseProxy.createOrUpdateMetaKv(Constants.LICENSEIDS, currents.toString(), Constants.METAKV_DATATYPE_STRING);
|
||||||
|
|
||||||
// 跳转回到证书列表
|
// 跳转回到证书列表
|
||||||
List<JSONObject> licenses = licenseProxy.getLicensesFromStore();
|
List<JSONObject> licenses = licenseProxy.getLicensesInStore();
|
||||||
map.addAttribute(Constants.LICENSES, licenses);
|
map.addAttribute(Constants.LICENSES, licenses);
|
||||||
map.addAttribute("updateTime", new Date());
|
map.addAttribute("updateTime", new Date());
|
||||||
map.addAttribute(Constants.LICENSESTOREPROVIDER, licenseProxy.getLicenseStoreProvider());
|
map.addAttribute(Constants.LICENSESTOREPROVIDER, licenseProxy.getLicenseStoreProvider());
|
||||||
@ -197,7 +198,7 @@ public class LicenseCtrl extends Handler {
|
|||||||
licenseProxy.createOrUpdateMetaKv(Constants.LICENSEIDS, post.toString(), Constants.METAKV_DATATYPE_STRING);
|
licenseProxy.createOrUpdateMetaKv(Constants.LICENSEIDS, post.toString(), Constants.METAKV_DATATYPE_STRING);
|
||||||
|
|
||||||
// 跳转回到证书列表
|
// 跳转回到证书列表
|
||||||
List<JSONObject> licenses = licenseProxy.getLicensesFromStore();
|
List<JSONObject> licenses = licenseProxy.getLicensesInStore();
|
||||||
map.addAttribute(Constants.LICENSES, licenses);
|
map.addAttribute(Constants.LICENSES, licenses);
|
||||||
map.addAttribute("updateTime", new Date());
|
map.addAttribute("updateTime", new Date());
|
||||||
map.addAttribute(Constants.LICENSESTOREPROVIDER, licenseProxy.getLicenseStoreProvider());
|
map.addAttribute(Constants.LICENSESTOREPROVIDER, licenseProxy.getLicenseStoreProvider());
|
@ -183,7 +183,9 @@ public class ApiUserController extends Handler {
|
|||||||
User user = userProxy.parseUserFromJson(payload);
|
User user = userProxy.parseUserFromJson(payload);
|
||||||
JsonObject resp = userProxy.createNewUser(user, parentOrgan);
|
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);
|
Role role = roleRes.findById(roleId).orElse(null);
|
||||||
UserRole userRole = new UserRole();
|
UserRole userRole = new UserRole();
|
||||||
userRole.setUser(user);
|
userRole.setUser(user);
|
||||||
|
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd.
|
||||||
|
* <https://www.chatopera.com>, 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-Jun. 2023 Chatopera Inc, <https://www.chatopera.com>,
|
||||||
|
* Licensed under the Apache License, Version 2.0,
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*/
|
||||||
|
package com.cskefu.cc.exception;
|
||||||
|
|
||||||
|
public class BillingQuotaException extends Exception {
|
||||||
|
|
||||||
|
public final static String SUFFIX = "billingquotaexception.";
|
||||||
|
|
||||||
|
// metakv 中没有找到可以支持配额的证书类型
|
||||||
|
public final static String NO_LICENSE_FOUND = SUFFIX + "no_license_found";
|
||||||
|
// 返回值异常,可能是网络连接不上,稍后再试
|
||||||
|
public static final String RESPONSE_UNEXPECTED = SUFFIX + "response_unexpected";
|
||||||
|
// 请求参数不合法
|
||||||
|
public static final String INVALID_REQUEST_BODY = SUFFIX + "invalid_request_body";
|
||||||
|
// 证书在证书商店不存在
|
||||||
|
public static final String LICENSE_INVALID = SUFFIX + "license_invalid";
|
||||||
|
// 证书关联的产品信息不合法
|
||||||
|
public static final String PRODUCT_INVALID = SUFFIX + "product_invalid";
|
||||||
|
// 证书失效或耗尽
|
||||||
|
public static final String LICENSE_EXPIRED_OR_EXHAUSTED = SUFFIX + "license_expired_or_exhausted";
|
||||||
|
// 证书关闭了对该 serverinst 的支持
|
||||||
|
public static final String LICENSE_DISABLED_SERVERINST = SUFFIX + "license_disabled_serverinst";
|
||||||
|
// 证书不支持配额回退
|
||||||
|
public static final String LICENSE_UNSUPPORT_REFUND = SUFFIX + "license_unsupport_refund";
|
||||||
|
// 证书配额余量不足,不能完成本次请求
|
||||||
|
public static final String LICENSE_QUOTA_INADEQUATE = SUFFIX + "license_quota_inadequate";
|
||||||
|
// 内部错误,不应该发生
|
||||||
|
public static final String INTERNAL_ERROR = SUFFIX + "internal_error";
|
||||||
|
|
||||||
|
public BillingQuotaException(final String s) {
|
||||||
|
super(s);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd.
|
||||||
|
* <https://www.chatopera.com>, 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-Jun. 2023 Chatopera Inc, <https://www.chatopera.com>,
|
||||||
|
* Licensed under the Apache License, Version 2.0,
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*/
|
||||||
|
package com.cskefu.cc.exception;
|
||||||
|
|
||||||
|
public class BillingResourceException extends Exception{
|
||||||
|
public BillingResourceException(final String s){
|
||||||
|
super(s);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,91 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd.
|
||||||
|
* <https://www.chatopera.com>, 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.model;
|
||||||
|
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
public class ExecuteResult implements Serializable {
|
||||||
|
public final static int RC_SUCC = 0;
|
||||||
|
public final static int RC_ERR1 = 1;
|
||||||
|
public final static int RC_ERR2 = 2;
|
||||||
|
public final static int RC_ERR3 = 3;
|
||||||
|
public final static int RC_ERR4 = 4;
|
||||||
|
public final static int RC_ERR5 = 5;
|
||||||
|
public final static int RC_ERR6 = 6;
|
||||||
|
public final static int RC_ERR7 = 7;
|
||||||
|
public final static int RC_ERR8 = 8;
|
||||||
|
public final static int RC_ERR9 = 9;
|
||||||
|
|
||||||
|
private int rc; // 0 for success, errors other
|
||||||
|
private String error;
|
||||||
|
private String msg;
|
||||||
|
private JSONObject data;
|
||||||
|
|
||||||
|
|
||||||
|
public ExecuteResult() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExecuteResult(final int rc, final String msg) {
|
||||||
|
this.rc = rc;
|
||||||
|
this.msg = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExecuteResult(final int rc, final String msg, final String error) {
|
||||||
|
this.rc = rc;
|
||||||
|
this.msg = msg;
|
||||||
|
this.error = error;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExecuteResult(final int rc,
|
||||||
|
final String msg,
|
||||||
|
final String error,
|
||||||
|
final JSONObject data) {
|
||||||
|
this.rc = rc;
|
||||||
|
this.msg = msg;
|
||||||
|
this.error = error;
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRc() {
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRc(int rc) {
|
||||||
|
this.rc = rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getError() {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setError(String error) {
|
||||||
|
this.error = error;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMsg() {
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMsg(String msg) {
|
||||||
|
this.msg = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONObject getData() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setData(JSONObject data) {
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
}
|
@ -18,9 +18,8 @@ import com.chatopera.store.sdk.exceptions.InvalidResponseException;
|
|||||||
import com.cskefu.cc.basic.Constants;
|
import com.cskefu.cc.basic.Constants;
|
||||||
import com.cskefu.cc.basic.MainContext;
|
import com.cskefu.cc.basic.MainContext;
|
||||||
import com.cskefu.cc.basic.MainUtils;
|
import com.cskefu.cc.basic.MainUtils;
|
||||||
import com.cskefu.cc.exception.LicenseNotFoundException;
|
import com.cskefu.cc.exception.*;
|
||||||
import com.cskefu.cc.exception.MetaKvInvalidKeyException;
|
import com.cskefu.cc.model.ExecuteResult;
|
||||||
import com.cskefu.cc.exception.MetaKvNotExistException;
|
|
||||||
import com.cskefu.cc.model.MetaKv;
|
import com.cskefu.cc.model.MetaKv;
|
||||||
import com.cskefu.cc.persistence.repository.MetaKvRepository;
|
import com.cskefu.cc.persistence.repository.MetaKvRepository;
|
||||||
import com.cskefu.cc.util.Base62;
|
import com.cskefu.cc.util.Base62;
|
||||||
@ -50,6 +49,16 @@ public class LicenseProxy {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private QuotaWdClient quotaWdClient;
|
private QuotaWdClient quotaWdClient;
|
||||||
|
|
||||||
|
private static final Map<MainContext.BillingResource, Integer> BILLING_RES_QUOTA_MAPPINGS = new HashMap<>();
|
||||||
|
|
||||||
|
static {
|
||||||
|
BILLING_RES_QUOTA_MAPPINGS.put(MainContext.BillingResource.USER, 100);
|
||||||
|
BILLING_RES_QUOTA_MAPPINGS.put(MainContext.BillingResource.AGENGUSER, 1);
|
||||||
|
BILLING_RES_QUOTA_MAPPINGS.put(MainContext.BillingResource.CHANNELWEBIM, 100);
|
||||||
|
BILLING_RES_QUOTA_MAPPINGS.put(MainContext.BillingResource.CONTACT, 1);
|
||||||
|
BILLING_RES_QUOTA_MAPPINGS.put(MainContext.BillingResource.ORGAN, 10);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化 serverinstId
|
* 初始化 serverinstId
|
||||||
* serverinstId 作为服务唯一的实例ID
|
* serverinstId 作为服务唯一的实例ID
|
||||||
@ -76,20 +85,31 @@ public class LicenseProxy {
|
|||||||
/**
|
/**
|
||||||
* Init local data for License
|
* Init local data for License
|
||||||
*/
|
*/
|
||||||
|
resolveServerinstId();
|
||||||
|
resolveServicename();
|
||||||
|
resolveLicenseIds();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 读取或初始化 serverinstId
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private String resolveServerinstId() {
|
||||||
Optional<MetaKv> metaServerinstIdOpt = metaKvRes.findFirstByMetakey(Constants.LICENSE_SERVER_INST_ID);
|
Optional<MetaKv> metaServerinstIdOpt = metaKvRes.findFirstByMetakey(Constants.LICENSE_SERVER_INST_ID);
|
||||||
if (metaServerinstIdOpt.isEmpty()) {
|
if (metaServerinstIdOpt.isEmpty()) {
|
||||||
// 没有 serverinstId 信息,初始化
|
// 没有 serverinstId 信息,初始化
|
||||||
final String serverinstId = MainUtils.getUUID();
|
final String serverinstId = MainUtils.getUUID();
|
||||||
createMetaKv(Constants.LICENSE_SERVER_INST_ID, serverinstId, Constants.METAKV_DATATYPE_STRING);
|
createMetaKv(Constants.LICENSE_SERVER_INST_ID, serverinstId, Constants.METAKV_DATATYPE_STRING);
|
||||||
|
return serverinstId;
|
||||||
}
|
}
|
||||||
|
return metaServerinstIdOpt.get().getMetavalue();
|
||||||
|
}
|
||||||
|
|
||||||
Optional<MetaKv> metaServicenameOpt = metaKvRes.findFirstByMetakey(Constants.LICENSE_SERVICE_NAME);
|
/**
|
||||||
if (metaServicenameOpt.isEmpty()) {
|
* 读取或初始化 licenseIds
|
||||||
// 没有 Service Name 信息,初始化
|
*/
|
||||||
final String serviceName = generateLicenseServiceName();
|
private void resolveLicenseIds() {
|
||||||
createMetaKv(Constants.LICENSE_SERVICE_NAME, serviceName, Constants.METAKV_DATATYPE_STRING);
|
|
||||||
}
|
|
||||||
|
|
||||||
Optional<MetaKv> metaLicensesOpt = metaKvRes.findFirstByMetakey(Constants.LICENSEIDS);
|
Optional<MetaKv> metaLicensesOpt = metaKvRes.findFirstByMetakey(Constants.LICENSEIDS);
|
||||||
if (metaLicensesOpt.isEmpty()) {
|
if (metaLicensesOpt.isEmpty()) {
|
||||||
// 没有 license 信息,初始化
|
// 没有 license 信息,初始化
|
||||||
@ -97,6 +117,22 @@ public class LicenseProxy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 读取或初始化 serviceName
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private String resolveServicename() {
|
||||||
|
Optional<MetaKv> metaServicenameOpt = metaKvRes.findFirstByMetakey(Constants.LICENSE_SERVICE_NAME);
|
||||||
|
if (metaServicenameOpt.isEmpty()) {
|
||||||
|
// 没有 Service Name 信息,初始化
|
||||||
|
final String serviceName = generateLicenseServiceName();
|
||||||
|
createMetaKv(Constants.LICENSE_SERVICE_NAME, serviceName, Constants.METAKV_DATATYPE_STRING);
|
||||||
|
return serviceName;
|
||||||
|
}
|
||||||
|
return metaServicenameOpt.get().getMetavalue();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 从 MetaKv 表中取得数据 MetaKv
|
* 从 MetaKv 表中取得数据 MetaKv
|
||||||
*
|
*
|
||||||
@ -159,6 +195,27 @@ public class LicenseProxy {
|
|||||||
return metakv;
|
return metakv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 增加 MetaKv 中的 Key 的值,作为 Integer 做增量,不存在则初始化其值为 0,然后增量操作
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
* @param incrValue
|
||||||
|
*/
|
||||||
|
public MetaKv increValueInMetaKv(final String key, final int incrValue) {
|
||||||
|
try {
|
||||||
|
MetaKv kv = retrieveMetaKv(key);
|
||||||
|
int pre = Integer.parseInt(kv.getMetavalue());
|
||||||
|
kv.setMetavalue(Integer.toString(pre + incrValue));
|
||||||
|
kv.setUpdatetime(new Date());
|
||||||
|
metaKvRes.save(kv);
|
||||||
|
return kv;
|
||||||
|
} catch (MetaKvNotExistException e) {
|
||||||
|
return createMetaKv(key, Integer.toString(incrValue), Constants.METAKV_DATATYPE_INT);
|
||||||
|
} catch (MetaKvInvalidKeyException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成随机字符串,作为服务名称
|
* 生成随机字符串,作为服务名称
|
||||||
*
|
*
|
||||||
@ -178,7 +235,7 @@ public class LicenseProxy {
|
|||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public List<JSONObject> getLicensesFromStore() throws InvalidResponseException {
|
public List<JSONObject> getLicensesInStore() throws InvalidResponseException {
|
||||||
List<JSONObject> result = new ArrayList<>();
|
List<JSONObject> result = new ArrayList<>();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -240,7 +297,7 @@ public class LicenseProxy {
|
|||||||
* @return
|
* @return
|
||||||
* @throws InvalidResponseException
|
* @throws InvalidResponseException
|
||||||
*/
|
*/
|
||||||
public JSONObject getLicenseBasicsFromStore(final String licenseShortId) throws InvalidResponseException, InvalidRequestException {
|
public JSONObject getLicenseBasicsInStore(final String licenseShortId) throws InvalidResponseException, InvalidRequestException {
|
||||||
Response resp = quotaWdClient.getLicenseBasics(licenseShortId);
|
Response resp = quotaWdClient.getLicenseBasics(licenseShortId);
|
||||||
if (resp.getRc() == 0) {
|
if (resp.getRc() == 0) {
|
||||||
JSONArray data = (JSONArray) resp.getData();
|
JSONArray data = (JSONArray) resp.getData();
|
||||||
@ -260,7 +317,7 @@ public class LicenseProxy {
|
|||||||
* @return
|
* @return
|
||||||
* @throws InvalidResponseException
|
* @throws InvalidResponseException
|
||||||
*/
|
*/
|
||||||
public JSONArray getAddedLicenseBasicsFromStore() throws InvalidResponseException {
|
public JSONArray getAddedLicenseBasicsInStore() throws InvalidResponseException {
|
||||||
JSONArray arr = getLicensesInMetakv();
|
JSONArray arr = getLicensesInMetakv();
|
||||||
List<String> ids = new ArrayList<>();
|
List<String> ids = new ArrayList<>();
|
||||||
|
|
||||||
@ -314,4 +371,120 @@ public class LicenseProxy {
|
|||||||
public String getLicenseStoreProvider() {
|
public String getLicenseStoreProvider() {
|
||||||
return quotaWdClient.getBaseUrl();
|
return quotaWdClient.getBaseUrl();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得资源用量存储
|
||||||
|
*
|
||||||
|
* @param resourceKey
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String getResourceUsageKey(final String resourceKey) {
|
||||||
|
StringBuffer sb = new StringBuffer();
|
||||||
|
sb.append(Constants.RESOURCES_USAGE_KEY_PREFIX);
|
||||||
|
sb.append("_");
|
||||||
|
sb.append(StringUtils.toRootUpperCase(resourceKey));
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 增加计费资源用量
|
||||||
|
*
|
||||||
|
* @param billingResource
|
||||||
|
* @param consume
|
||||||
|
*/
|
||||||
|
public void increResourceUsageInMetaKv(final MainContext.BillingResource billingResource, int consume) throws BillingResourceException {
|
||||||
|
switch (billingResource) {
|
||||||
|
case USER:
|
||||||
|
case CONTACT:
|
||||||
|
case ORGAN:
|
||||||
|
case AGENGUSER:
|
||||||
|
case CHANNELWEBIM:
|
||||||
|
increValueInMetaKv(getResourceUsageKey(billingResource.toString()), consume);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new BillingResourceException("invalid_billing_resource_type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得春松客服 cskefu001 产品的证书标识 ID
|
||||||
|
* 春松客服证书基本类型
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private String getLicenseIdAsCskefu001InMetaKv() throws BillingQuotaException {
|
||||||
|
JSONArray curr = getLicensesInMetakv();
|
||||||
|
for (int i = 0; i < curr.length(); i++) {
|
||||||
|
JSONObject jo = (JSONObject) curr.get(i);
|
||||||
|
if (jo.has(Constants.PRODUCT_ID) &&
|
||||||
|
StringUtils.equals(jo.getString(Constants.PRODUCT_ID), Constants.PRODUCT_ID_CSKEFU001)) {
|
||||||
|
return jo.getString(Constants.SHORTID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new BillingQuotaException(BillingQuotaException.NO_LICENSE_FOUND);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行配额变更操作
|
||||||
|
*
|
||||||
|
* @param billingResource
|
||||||
|
* @param consume
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public ExecuteResult writeDownResourceUsageInStore(final MainContext.BillingResource billingResource, int consume) throws BillingQuotaException, BillingResourceException {
|
||||||
|
ExecuteResult er = new ExecuteResult();
|
||||||
|
|
||||||
|
// 请求操作配额
|
||||||
|
String licenseId = getLicenseIdAsCskefu001InMetaKv();
|
||||||
|
String serverinstId = resolveServerinstId();
|
||||||
|
String servicename = resolveServicename();
|
||||||
|
|
||||||
|
try {
|
||||||
|
Response resp = quotaWdClient.write(licenseId,
|
||||||
|
serverinstId, servicename, consume * BILLING_RES_QUOTA_MAPPINGS.get(billingResource));
|
||||||
|
// 识别操作是否完成,并处理
|
||||||
|
if (resp.getRc() == 0) {
|
||||||
|
final JSONObject data = (JSONObject) resp.getData();
|
||||||
|
|
||||||
|
// 配额操作成功,执行计数
|
||||||
|
increResourceUsageInMetaKv(billingResource, consume);
|
||||||
|
} else if (resp.getRc() == 1 || resp.getRc() == 2) {
|
||||||
|
throw new BillingQuotaException(BillingQuotaException.INVALID_REQUEST_BODY);
|
||||||
|
} else if (resp.getRc() == 3) {
|
||||||
|
// 证书商店中不存在
|
||||||
|
throw new BillingQuotaException(BillingQuotaException.LICENSE_INVALID);
|
||||||
|
} else if (resp.getRc() == 4) {
|
||||||
|
// 证书商店中不存在该产品或产品类型无效
|
||||||
|
throw new BillingQuotaException(BillingQuotaException.PRODUCT_INVALID);
|
||||||
|
} else if (resp.getRc() == 5) {
|
||||||
|
// 该证书不支持资源回退
|
||||||
|
throw new BillingQuotaException(BillingQuotaException.LICENSE_UNSUPPORT_REFUND);
|
||||||
|
} else if (resp.getRc() == 6) {
|
||||||
|
// 证书失效或耗尽,不支持继续扣除配额
|
||||||
|
throw new BillingQuotaException(BillingQuotaException.LICENSE_EXPIRED_OR_EXHAUSTED);
|
||||||
|
} else if (resp.getRc() == 7) {
|
||||||
|
// 该证书禁用了该 serverinstId
|
||||||
|
throw new BillingQuotaException(BillingQuotaException.LICENSE_DISABLED_SERVERINST);
|
||||||
|
} else if (resp.getRc() == 8) {
|
||||||
|
// 配额扣除额度超过该证书目前的剩余量
|
||||||
|
throw new BillingQuotaException(BillingQuotaException.LICENSE_QUOTA_INADEQUATE);
|
||||||
|
} else {
|
||||||
|
// 未知情况
|
||||||
|
logger.error("[writeDownResourceUsageInStore] resp data {}", resp.toString());
|
||||||
|
throw new BillingQuotaException(BillingQuotaException.INTERNAL_ERROR);
|
||||||
|
}
|
||||||
|
} catch (InvalidResponseException e) {
|
||||||
|
// TODO 处理异常信息
|
||||||
|
logger.error("[writeDownResourceUsageInStore] error ", e);
|
||||||
|
throw new BillingQuotaException(BillingQuotaException.RESPONSE_UNEXPECTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
// er.setRc(ExecuteResult.RC_ERR1);
|
||||||
|
// if (er.getRc() != ExecuteResult.RC_SUCC) {
|
||||||
|
// throw new BillingQuotaException(BillingQuotaException.NO_LICENSE_FOUND);
|
||||||
|
// }
|
||||||
|
|
||||||
|
return er;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ package com.cskefu.cc.proxy;
|
|||||||
import com.cskefu.cc.basic.Constants;
|
import com.cskefu.cc.basic.Constants;
|
||||||
import com.cskefu.cc.basic.MainContext;
|
import com.cskefu.cc.basic.MainContext;
|
||||||
import com.cskefu.cc.basic.MainUtils;
|
import com.cskefu.cc.basic.MainUtils;
|
||||||
|
import com.cskefu.cc.exception.BillingQuotaException;
|
||||||
import com.cskefu.cc.model.*;
|
import com.cskefu.cc.model.*;
|
||||||
import com.cskefu.cc.persistence.repository.*;
|
import com.cskefu.cc.persistence.repository.*;
|
||||||
import com.cskefu.cc.util.restapi.RestUtils;
|
import com.cskefu.cc.util.restapi.RestUtils;
|
||||||
@ -29,6 +30,8 @@ import org.springframework.data.domain.Pageable;
|
|||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import jakarta.persistence.criteria.Predicate;
|
import jakarta.persistence.criteria.Predicate;
|
||||||
|
|
||||||
|
import java.lang.reflect.UndeclaredThrowableException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@ -79,22 +82,34 @@ public class UserProxy {
|
|||||||
public JsonObject createNewUser(final User user, Organ organ) {
|
public JsonObject createNewUser(final User user, Organ organ) {
|
||||||
JsonObject result = new JsonObject();
|
JsonObject result = new JsonObject();
|
||||||
String msg = validUser(user);
|
String msg = validUser(user);
|
||||||
if (StringUtils.equalsIgnoreCase(msg, "new_user_success")) {
|
|
||||||
|
if (StringUtils.equalsIgnoreCase(msg, Constants.NEW_USER_SUCCESS)) {
|
||||||
// 此时 msg 是 new_user_success
|
// 此时 msg 是 new_user_success
|
||||||
user.setSuperadmin(false); // 不支持创建第二个系统管理员
|
user.setSuperadmin(false); // 不支持创建第二个系统管理员
|
||||||
|
try {
|
||||||
|
if (StringUtils.isNotBlank(user.getPassword())) {
|
||||||
|
user.setPassword(MainUtils.md5(user.getPassword()));
|
||||||
|
}
|
||||||
|
userRes.save(user);
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(user.getPassword())) {
|
if (organ != null) {
|
||||||
user.setPassword(MainUtils.md5(user.getPassword()));
|
OrganUser ou = new OrganUser();
|
||||||
}
|
ou.setUserid(user.getId());
|
||||||
userRes.save(user);
|
ou.setOrgan(organ.getId());
|
||||||
|
organUserRes.save(ou);
|
||||||
if (organ != null) {
|
}
|
||||||
OrganUser ou = new OrganUser();
|
} catch (Exception e) {
|
||||||
ou.setUserid(user.getId());
|
if (e instanceof UndeclaredThrowableException) {
|
||||||
ou.setOrgan(organ.getId());
|
logger.error("[createNewUser] BillingQuotaException", e);
|
||||||
organUserRes.save(ou);
|
if (StringUtils.startsWith(e.getCause().getMessage(), BillingQuotaException.SUFFIX)) {
|
||||||
|
msg = e.getCause().getMessage();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logger.error("[createNewUser] err", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 新账号未通过验证,返回创建失败信息msg
|
// 新账号未通过验证,返回创建失败信息msg
|
||||||
result.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_SUCC);
|
result.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_SUCC);
|
||||||
result.addProperty(RestUtils.RESP_KEY_DATA, msg);
|
result.addProperty(RestUtils.RESP_KEY_DATA, msg);
|
||||||
|
@ -56,5 +56,35 @@ function processUserAddOrUpdateResult(responsecode, cb){
|
|||||||
layer.msg('用户编辑成功',{icon: 1, time: 1000});
|
layer.msg('用户编辑成功',{icon: 1, time: 1000});
|
||||||
cb();
|
cb();
|
||||||
break;
|
break;
|
||||||
|
case 'billingquotaexception.no_license_found':
|
||||||
|
layer.msg('【使用授权证书】证书不存在,联系系统超级管理员导入。',{icon: 2, time: 5000});
|
||||||
|
break;
|
||||||
|
case 'billingquotaexception.response_unexpected':
|
||||||
|
layer.msg('【使用授权证书】证书商店返回异常,稍后再试。',{icon: 2, time: 5000});
|
||||||
|
break;
|
||||||
|
case 'billingquotaexception.invalid_request_body':
|
||||||
|
layer.msg('【使用授权证书】请求证书商店参数不合法,请获取最新软件代码。',{icon: 2, time: 5000});
|
||||||
|
break;
|
||||||
|
case 'billingquotaexception.license_invalid':
|
||||||
|
layer.msg('【使用授权证书】证书商店中不存在该证书,请联系系统超级管理员导入。',{icon: 2, time: 5000});
|
||||||
|
break;
|
||||||
|
case 'billingquotaexception.product_invalid':
|
||||||
|
layer.msg('【使用授权证书】产品或产品款式不存在,请联系系统超级管理员导入新证书。',{icon: 2, time: 5000});
|
||||||
|
break;
|
||||||
|
case 'billingquotaexception.license_expired_or_exhausted':
|
||||||
|
layer.msg('【使用授权证书】证书过期或耗尽,请升级证书或绑定新证书。',{icon: 2, time: 5000});
|
||||||
|
break;
|
||||||
|
case 'billingquotaexception.license_disabled_serverinst':
|
||||||
|
layer.msg('【使用授权证书】证书商店禁用了本服务实例。',{icon: 2, time: 5000});
|
||||||
|
break;
|
||||||
|
case 'billingquotaexception.license_unsupport_refund':
|
||||||
|
layer.msg('【使用授权证书】目前使用的证书不支持回退配额。',{icon: 2, time: 5000});
|
||||||
|
break;
|
||||||
|
case 'billingquotaexception.license_quota_inadequate':
|
||||||
|
layer.msg('【使用授权证书】本次操作需要使用的配额资源超过证书中剩余配额,请联系系统超级管理员升级证书。',{icon: 2, time: 5000});
|
||||||
|
break;
|
||||||
|
case 'billingquotaexception.internal_error':
|
||||||
|
layer.msg('【使用授权证书】系统错误,稍后再试。',{icon: 2, time: 5000});
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -121,6 +121,8 @@ block content
|
|||||||
layer.msg('新用户创建成功',{icon: 1, time: 1000})
|
layer.msg('新用户创建成功',{icon: 1, time: 1000})
|
||||||
else if (msg == 'edit_user_success')
|
else if (msg == 'edit_user_success')
|
||||||
layer.msg('用户编辑成功', {icon: 1, time: 1000})
|
layer.msg('用户编辑成功', {icon: 1, time: 1000})
|
||||||
|
else if (msg == 'billingquotaexception.no_license_found')
|
||||||
|
layer.msg('证书不存在,联系系统超级管理员导入授权使用证书',{icon: 2, time: 3000})
|
||||||
});
|
});
|
||||||
layui.use(['laypage', 'layer'], function(){
|
layui.use(['laypage', 'layer'], function(){
|
||||||
var laypage = layui.laypage
|
var laypage = layui.laypage
|
||||||
|
Loading…
x
Reference in New Issue
Block a user