1
0
mirror of https://github.com/chatopera/cosin.git synced 2025-07-16 00:22:22 +08:00
Signed-off-by: Hai Liang Wang <hai@chatopera.com>
This commit is contained in:
Hai Liang Wang 2023-09-18 15:49:52 +08:00
parent e69dfd398d
commit 629abe88d2
15 changed files with 718 additions and 455 deletions

View File

@ -88,6 +88,7 @@
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>3.1.3</version>
<executions>
<execution>
<goals>

View File

@ -217,4 +217,13 @@ 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 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 LICENSES = "LICENSES";
public static final String METAKV_DATATYPE_STRING = "string";
}

View File

@ -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<ContextRe
private static final Logger logger = LoggerFactory.getLogger(AppCtxRefreshEventListener.class);
private void setupSysdicCacheAndExtras(final ContextRefreshedEvent event, final String cacheSetupStrategy, final Cache cache, final SysDicRepository sysDicRes, final BlackListRepository blackListRes) {
if (!StringUtils.equalsIgnoreCase(cacheSetupStrategy, Constants.cache_setup_strategy_skip)) {
@ -138,6 +138,9 @@ public class AppCtxRefreshEventListener implements ApplicationListener<ContextRe
logger.info("[Plugins] registered plugin id {}, class {}", p.getPluginId(), p.getClass().getName());
}
// 初始化 ServerInstId
LicenseProxy licenseProxy = event.getApplicationContext().getBean(LicenseProxy.class);
licenseProxy.checkOnStartup();
} else {
logger.info("[onApplicationEvent] bypass, initialization has been done already.");
}

View File

@ -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;

View File

@ -31,7 +31,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;

View File

@ -31,7 +31,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;

View File

@ -0,0 +1,77 @@
package com.cskefu.cc.model;
import jakarta.persistence.*;
import java.util.Date;
/**
* 存储元数据
*/
@Entity
@Table(name = "cs_metakv")
@org.hibernate.annotations.Proxy(lazy = false)
public class Metakv implements java.io.Serializable {
@Id
private String metakey;
private String metavalue;
private String datatype;
private String comment;
@Temporal(TemporalType.TIMESTAMP)
private Date updatetime;
@Temporal(TemporalType.TIMESTAMP)
private Date createtime;
public String getMetakey() {
return metakey;
}
public void setMetakey(String metakey) {
this.metakey = metakey;
}
public String getMetavalue() {
return metavalue;
}
public void setMetavalue(String metavalue) {
this.metavalue = metavalue;
}
public String getDatatype() {
return datatype;
}
public void setDatatype(String datatype) {
this.datatype = datatype;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
public Date getUpdatetime() {
return updatetime;
}
public void setUpdatetime(Date updatetime) {
this.updatetime = updatetime;
}
public Date getCreatetime() {
return createtime;
}
public void setCreatetime(Date createtime) {
this.createtime = createtime;
}
}

View File

@ -0,0 +1,22 @@
/*
* 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.persistence.repository;
import com.cskefu.cc.model.Metakv;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.Optional;
public interface MetakvRepository extends JpaRepository<Metakv, String> {
Optional<Metakv> findFirstByMetakey(final String p1);
}

View File

@ -0,0 +1,93 @@
/*
* 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.proxy;
import com.cskefu.cc.basic.Constants;
import com.cskefu.cc.basic.MainUtils;
import com.cskefu.cc.model.Metakv;
import com.cskefu.cc.persistence.repository.MetakvRepository;
import com.cskefu.cc.util.Base62;
import org.json.JSONArray;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.Optional;
@Service
public class LicenseProxy {
private final static Logger logger = LoggerFactory.getLogger(LicenseProxy.class);
@Autowired
private MetakvRepository metkvRes;
/**
* 初始化 serverinstId
* serverinstId 作为服务唯一的实例ID
*/
public void checkOnStartup() {
Optional<Metakv> metaServerinstIdOpt = metkvRes.findFirstByMetakey(Constants.LICENSE_SERVER_INST_ID);
if (metaServerinstIdOpt.isEmpty()) {
// 没有 serverinstId 信息初始化
final String serverinstId = MainUtils.getUUID();
createMetakv(Constants.LICENSE_SERVER_INST_ID, serverinstId, Constants.METAKV_DATATYPE_STRING);
}
Optional<Metakv> metaServicenameOpt = metkvRes.findFirstByMetakey(Constants.LICENSE_SERVICE_NAME);
if (metaServicenameOpt.isEmpty()) {
// 没有 Service Name 信息初始化
final String serviceName = generateLicenseServiceName();
createMetakv(Constants.LICENSE_SERVICE_NAME, serviceName, Constants.METAKV_DATATYPE_STRING);
}
Optional<Metakv> metaLicensesOpt = metkvRes.findFirstByMetakey(Constants.LICENSES);
if (metaLicensesOpt.isEmpty()) {
// 没有 license 信息初始化
createMetakv(Constants.LICENSES, (new JSONArray()).toString(), Constants.METAKV_DATATYPE_STRING);
}
}
/**
* 建立 Metakv 数据
*
* @param key
* @param value
* @param datatype
*/
public void createMetakv(final String key, final String value, final String datatype) {
Date now = new Date();
Metakv metakv = new Metakv();
metakv.setCreatetime(now);
metakv.setUpdatetime(now);
metakv.setMetakey(key);
metakv.setMetavalue(value);
metakv.setDatatype(datatype);
metkvRes.save(metakv);
}
/**
* 生成随机字符串作为服务名称
*
* @return
*/
private String generateLicenseServiceName() {
StringBuffer sb = new StringBuffer();
sb.append(Constants.LICENSE_SERVICE_NAME_PREFIX);
sb.append(Base62.generatingRandomAlphanumericString(5));
return sb.toString();
}
}

View File

@ -17,6 +17,8 @@ package com.cskefu.cc.util;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import java.util.Random;
public class Base62 {
private static final int BINARY = 0x2;
@ -60,4 +62,23 @@ public class Base62 {
private static void print(Object messagr) {
System.out.println(messagr);
}
/**
* 生成随机字符串
* @param targetStringLength
* @return
*/
public static String generatingRandomAlphanumericString(final int targetStringLength) {
int leftLimit = 48; // numeral '0'
int rightLimit = 122; // letter 'z'
Random random = new Random();
String generatedString = random.ints(leftLimit, rightLimit + 1)
.filter(i -> (i <= 57 || i >= 65) && (i <= 90 || i >= 97))
.limit(targetStringLength)
.collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
.toString();
return generatedString;
}
}

View File

@ -138,6 +138,24 @@ CREATE TABLE `cs_fb_otn_follow` (
-- Records of cs_fb_otn_follow
-- ----------------------------
-- ----------------------------
-- Table structure for cs_metakv
-- ----------------------------
DROP TABLE IF EXISTS `cs_metakv`;
CREATE TABLE `cs_metakv` (
`metakey` varchar(512) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '元数据字段名,唯一标识',
`metavalue` text COLLATE utf8mb4_unicode_ci COMMENT '元数据值',
`createtime` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updatetime` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`datatype` varchar(256) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'string' COMMENT '数据类型',
`comment` varchar(1024) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '字段备注描述',
PRIMARY KEY (`metakey`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='系统内置元数据';
-- ----------------------------
-- Records of cs_metakv
-- ----------------------------
-- ----------------------------
-- Table structure for cs_organ_user
-- ----------------------------

View File

@ -0,0 +1,14 @@
USE `cosinee`;
-- -----------------
-- prepare variables
-- -----------------
CREATE TABLE IF NOT EXISTS `cs_metakey` (
`metakey` varchar(512) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '元数据字段名,唯一标识',
`metavalue` text COLLATE utf8mb4_unicode_ci COMMENT '元数据值',
`createtime` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updatetime` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`datatype` varchar(256) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'string' COMMENT '数据类型',
`comment` varchar(1024) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '字段备注描述',
PRIMARY KEY (`metakey`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='系统内置元数据';

View File

@ -400,12 +400,19 @@
<artifactId>compose4j</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.chatopera.bot</groupId>
<artifactId>sdk</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>com.chatopera.store</groupId>
<artifactId>store-sdk</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- Required for Java 11 https://github.com/cskefu/cskefu/issues/714 -->
<dependency>
<groupId>javax.xml.bind</groupId>