1
0
mirror of https://github.com/chatopera/cosin.git synced 2025-08-01 16:38:02 +08:00

#937 add license mng menu

Signed-off-by: Hai Liang Wang <hai@chatopera.com>
This commit is contained in:
Hai Liang Wang 2023-09-21 16:28:47 +08:00
parent 63c5750181
commit f55785883a
13 changed files with 542 additions and 64 deletions

View File

@ -226,4 +226,9 @@ public class Constants {
public static final String LICENSEIDS = "LICENSEIDS";
public static final String METAKV_DATATYPE_STRING = "string";
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";
}

View File

@ -0,0 +1,140 @@
/*
* 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.controller.admin;
import com.chatopera.store.sdk.exceptions.InvalidResponseException;
import com.cskefu.cc.basic.Constants;
import com.cskefu.cc.controller.Handler;
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.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import java.util.Date;
import java.util.List;
@Controller
@RequestMapping("/admin/license")
public class LicenseCtrl extends Handler {
private final static Logger logger = LoggerFactory.getLogger(LicenseCtrl.class);
@Autowired
private LicenseProxy licenseProxy;
@RequestMapping("/index")
@Menu(type = "admin", subtype = "license")
public ModelAndView index(ModelMap map, HttpServletRequest request) {
User user = super.getUser(request);
if (user.isSuperadmin()) {
try {
List<JSONObject> licenses = licenseProxy.getLicensesFromStore();
map.addAttribute(Constants.UPDATETIME, new Date());
map.addAttribute(Constants.LICENSES, licenses);
} 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 = "license")
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 = "license")
public ModelAndView save(ModelMap map,
HttpServletRequest request,
@Valid String licenseShortId) throws MetaKvInvalidKeyException {
User user = super.getUser(request);
logger.info("[save] licenseShortId {}", licenseShortId);
if (user.isSuperadmin()) {
// 验证该证书不在当前证书列表中
JSONArray currents = licenseProxy.getLicensesInMetakv();
String msg = "";
boolean isAddedBefore = false;
for (int i = 0; i < currents.length(); i++) {
JSONObject item = (JSONObject) currents.get(i);
if (StringUtils.equals(item.getString("shortId"), licenseShortId)) {
isAddedBefore = true;
break;
}
}
if (isAddedBefore) {
msg = "already_added";
return request(super.createView(
"redirect:/admin/license/index.html?msg=" + msg));
}
// 验证该证书存在
try {
JSONObject licenseData = licenseProxy.getLicenseFromStore(licenseShortId);
JSONObject licenseKvData = new JSONObject();
licenseKvData.put(Constants.SHORTID, licenseData.getJSONObject(Constants.LICENSE).getString(Constants.SHORTID));
licenseKvData.put(Constants.ADDDATE, new Date());
// 添加该证书
currents.put(0, licenseKvData);
licenseProxy.createOrUpdateMetaKv(Constants.LICENSEIDS, currents.toString(), Constants.METAKV_DATATYPE_STRING);
// 跳转回到证书列表
List<JSONObject> licenses = licenseProxy.getLicensesFromStore();
map.addAttribute(Constants.LICENSES, licenses);
map.addAttribute("updateTime", new Date());
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"));
}
}
}

View File

@ -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 MetaKvInvalidKeyException extends Exception{
public MetaKvInvalidKeyException(final String s){
super(s);
}
}

View File

@ -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 MetaKvNotExistException extends Exception{
public MetaKvNotExistException(final String s){
super(s);
}
}

View File

@ -10,7 +10,7 @@ import java.util.Date;
@Entity
@Table(name = "cs_metakv")
@org.hibernate.annotations.Proxy(lazy = false)
public class Metakv implements java.io.Serializable {
public class MetaKv implements java.io.Serializable {
@Id
private String metakey;

View File

@ -10,13 +10,13 @@
*/
package com.cskefu.cc.persistence.repository;
import com.cskefu.cc.model.Metakv;
import com.cskefu.cc.model.MetaKv;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.Optional;
public interface MetakvRepository extends JpaRepository<Metakv, String> {
public interface MetaKvRepository extends JpaRepository<MetaKv, String> {
Optional<Metakv> findFirstByMetakey(final String p1);
Optional<MetaKv> findFirstByMetakey(final String p1);
}

View File

@ -16,25 +16,33 @@ import com.chatopera.store.sdk.exceptions.InvalidResponseException;
import com.cskefu.cc.basic.Constants;
import com.cskefu.cc.basic.MainContext;
import com.cskefu.cc.basic.MainUtils;
import com.cskefu.cc.model.Metakv;
import com.cskefu.cc.persistence.repository.MetakvRepository;
import com.cskefu.cc.exception.MetaKvInvalidKeyException;
import com.cskefu.cc.exception.MetaKvNotExistException;
import com.cskefu.cc.model.MetaKv;
import com.cskefu.cc.persistence.repository.MetaKvRepository;
import com.cskefu.cc.util.Base62;
import com.cskefu.cc.util.DateConverter;
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.boot.SpringApplication;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.Optional;
import java.text.ParseException;
import java.util.*;
/**
* 证书服务
*/
@Service
public class LicenseProxy {
private final static Logger logger = LoggerFactory.getLogger(LicenseProxy.class);
@Autowired
private MetakvRepository metkvRes;
private MetaKvRepository metaKvRes;
@Autowired
private QuotaWdClient quotaWdClient;
@ -65,24 +73,65 @@ public class LicenseProxy {
/**
* Init local data for License
*/
Optional<Metakv> metaServerinstIdOpt = metkvRes.findFirstByMetakey(Constants.LICENSE_SERVER_INST_ID);
Optional<MetaKv> metaServerinstIdOpt = metaKvRes.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);
createMetaKv(Constants.LICENSE_SERVER_INST_ID, serverinstId, Constants.METAKV_DATATYPE_STRING);
}
Optional<Metakv> metaServicenameOpt = metkvRes.findFirstByMetakey(Constants.LICENSE_SERVICE_NAME);
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);
createMetaKv(Constants.LICENSE_SERVICE_NAME, serviceName, Constants.METAKV_DATATYPE_STRING);
}
Optional<Metakv> metaLicensesOpt = metkvRes.findFirstByMetakey(Constants.LICENSEIDS);
Optional<MetaKv> metaLicensesOpt = metaKvRes.findFirstByMetakey(Constants.LICENSEIDS);
if (metaLicensesOpt.isEmpty()) {
// 没有 license 信息初始化
createMetakv(Constants.LICENSEIDS, (new JSONArray()).toString(), Constants.METAKV_DATATYPE_STRING);
createMetaKv(Constants.LICENSEIDS, (new JSONArray()).toString(), Constants.METAKV_DATATYPE_STRING);
}
}
/**
* MetaKv 表中取得数据 MetaKv
*
* @param key
* @return
* @throws MetaKvNotExistException
*/
public MetaKv retrieveMetaKv(final String key) throws MetaKvNotExistException, MetaKvInvalidKeyException {
if (StringUtils.isBlank(key)) {
throw new MetaKvInvalidKeyException("Key must not be empy");
}
Optional<MetaKv> kvOpt = metaKvRes.findFirstByMetakey(key);
if (kvOpt.isEmpty()) {
throw new MetaKvNotExistException(key + " not exist");
} else {
return kvOpt.get();
}
}
/**
* 创建或更新 MetaKv
* UpdateOnExist
*
* @param key
* @param value
* @param datatype
*/
public MetaKv createOrUpdateMetaKv(final String key, final String value, final String datatype) throws MetaKvInvalidKeyException {
try {
MetaKv kv = retrieveMetaKv(key);
kv.setMetavalue(value);
kv.setUpdatetime(new Date());
metaKvRes.save(kv);
return kv;
} catch (MetaKvNotExistException e) {
return createMetaKv(key, value, datatype);
}
}
@ -94,16 +143,17 @@ public class LicenseProxy {
* @param value
* @param datatype
*/
public void createMetakv(final String key, final String value, final String datatype) {
public MetaKv createMetaKv(final String key, final String value, final String datatype) {
Date now = new Date();
Metakv metakv = new Metakv();
MetaKv metakv = new MetaKv();
metakv.setCreatetime(now);
metakv.setUpdatetime(now);
metakv.setMetakey(key);
metakv.setMetavalue(value);
metakv.setDatatype(datatype);
metkvRes.save(metakv);
metaKvRes.save(metakv);
return metakv;
}
/**
@ -119,4 +169,81 @@ public class LicenseProxy {
return sb.toString();
}
/**
* 从数据库及证书商店获得证书列表信息
*
* @return
*/
public List<JSONObject> getLicensesFromStore() throws InvalidResponseException {
List<JSONObject> result = new ArrayList<>();
try {
JSONArray ja = new JSONArray((retrieveMetaKv(Constants.LICENSEIDS).getMetavalue()));
HashMap<String, String> addDates = new HashMap<>();
List<String> licenseIds = new ArrayList<>();
for (int i = 0; i < ja.length(); i++) {
JSONObject obj = ((JSONObject) ja.get(i));
licenseIds.add(obj.getString(Constants.SHORTID));
addDates.put(obj.getString(Constants.SHORTID), obj.getString(Constants.ADDDATE));
}
Response resp = quotaWdClient.getLicensesInfo(licenseIds);
JSONArray data = (JSONArray) resp.getData();
for (int i = 0; i < data.length(); i++) {
JSONObject lic = (JSONObject) data.get(i);
try {
Date addDate = DateConverter.parseCSTAsChinaTimezone(addDates.get(lic.getJSONObject(Constants.LICENSE).getString(Constants.SHORTID)));
lic.put(Constants.ADDDATE, addDate);
} catch (ParseException e) {
logger.info("[getLicensesFromStore] can not resolve add date");
}
result.add(lic);
}
} catch (MetaKvNotExistException e) {
logger.info("[getLicenses] no LICENSEIDS data in MySQL DB");
} catch (MetaKvInvalidKeyException e) {
throw new RuntimeException(e);
}
return result;
}
/**
* 获得在 MetaKV 表中的 license 信息
*
* @return JSONArray
*/
public JSONArray getLicensesInMetakv() {
try {
String value = retrieveMetaKv(Constants.LICENSEIDS).getMetavalue();
return new JSONArray(value);
} catch (MetaKvNotExistException e) {
return new JSONArray();
} catch (MetaKvInvalidKeyException e) {
return new JSONArray();
}
}
/**
* @param licenseShortId
* @return
* @throws InvalidResponseException
*/
public JSONObject getLicenseFromStore(final String licenseShortId) throws InvalidResponseException {
Response resp = quotaWdClient.getLicenseInfo(licenseShortId);
if (resp.getRc() == 0) {
JSONArray data = (JSONArray) resp.getData();
if (data.length() != 1)
throw new InvalidResponseException("Unexpected data in Response.");
return (JSONObject) (data).get(0);
} else {
throw new InvalidResponseException("Unexpected Response.");
}
}
}

View File

@ -16,10 +16,17 @@ package com.cskefu.cc.util;
import org.apache.commons.beanutils.converters.DateTimeConverter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class DateConverter extends DateTimeConverter {
final public static String ZONE_ID_DEFAULT = "Asia/Shanghai";
// format date string like `Wed Aug 30 16:30:23 CST 2023` to Date
public static SimpleDateFormat TIMEZONE_CHINA_FORMAT_DEFAULT = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US);
public DateConverter() {
}
@ -51,4 +58,17 @@ public class DateConverter extends DateTimeConverter {
}
return super.convertToType(arg0, arg1);
}
/**
* Java将CST的时间字符串转换成需要的日期格式字符串
* https://blog.csdn.net/qq_44868502/article/details/103511505
* (new Date()).toString() String to Date 的转化
*
* @param dstr
* @return
* @throws ParseException
*/
static public Date parseCSTAsChinaTimezone(final String dstr) throws ParseException {
return (Date) TIMEZONE_CHINA_FORMAT_DEFAULT.parse(dstr);
}
}

View File

@ -12,6 +12,7 @@ package com.cskefu.cc.util;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import org.apache.commons.lang3.StringUtils;
import java.text.SimpleDateFormat;
import java.util.*;
@ -42,8 +43,39 @@ public class PugHelper {
return new String(charr);
}
/**
* 在字符串中替换一些字符为 *, 起到混淆加密遮盖的敏感信息的目的
*
* @param prev
* @return
*/
public String messupStringWithStars(final String prev) {
StringBuffer sb = new StringBuffer();
if (prev.length() >= 6) {
sb.append("***");
int initial = prev.length() - 4;
for (int i = initial; i < prev.length(); i++) {
sb.append(prev.charAt(i));
}
} else { // < 6
if (prev.length() <= 2 && prev.length() > 0) {
return "***";
} else { // 2 < length < 6
sb.append("***");
int initial = prev.length() - 2;
for (int i = initial; i < prev.length(); i++) {
sb.append(prev.charAt(i));
}
}
}
return sb.toString();
}
/**
* String 转化为 JSONArray
*
* @param str
* @return
*/

View File

@ -51,6 +51,13 @@ ul.layui-nav.layui-nav-tree(lay-filter='demo')
dd(class={'layui-this': subtype == 'interf'})
a(href='/admin/weixin/interf.html') 接口管理
| &ndash;&gt;
if user.superadmin
li.layui-nav-item.layui-nav-itemed
a.layui-nav-title(href='javascript:;') 人工智能
dl.layui-nav-child
if models.contains("chatbot") && (user.roleAuthMap["A09"] || user.admin)
dd
a(href='javascript:void(0)',data-title="智能机器人",onclick="openChatbot()",data-href="/admin/system/chatbot/index.html",class="iframe_btn",data-id="chatbotIntegrationWin", data-type="tabAdd") 智能机器人
if user.superadmin
li.layui-nav-item.layui-nav-itemed
a.layui-nav-title(href='javascript:;') 系统设置
@ -61,15 +68,14 @@ ul.layui-nav.layui-nav-tree(lay-filter='demo')
a(href='/admin/sysdic/index.html') 字典管理
dd(class={'layui-this': subtype == 'metadata'})
a(href='/admin/metadata/index.html') 元数据
if models.contains("chatbot") && (user.roleAuthMap["A09"] || user.admin)
dd
a(href='javascript:void(0)',data-title="智能机器人",onclick="openChatbot()",data-href="/admin/system/chatbot/index.html",class="iframe_btn",data-id="chatbotIntegrationWin", data-type="tabAdd") 智能机器人
dd(class={'layui-this': subtype == 'template'})
a(href='/admin/template/index.html') 系统模板
dd(class={'layui-this': subtype == 'email'})
a(href='/admin/email/index.html') 邮件通知设置
dd(class={'layui-this': subtype == 'sms'})
a(href='/admin/sms/index.html') 短信通知设置
dd(class={'layui-this': subtype == 'license'})
a(href='/admin/license/index.html') 使用授权证书
//dd(class={'layui-this': subtype == 'email'})
// a(href='/admin/email/index.html') 邮件通知设置
//dd(class={'layui-this': subtype == 'sms'})
// a(href='/admin/sms/index.html') 短信通知设置
script.
function openChatbot() {

View File

@ -0,0 +1,31 @@
//- 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.
.uk-layui-form
form.layui-form(action='/admin/license/save.html', method='post')
.layui-form-item(style='margin-top:10px;')
.layui-inline
label.layui-form-label(style='width:150px;') 证书短标识:
.layui-input-inline
input.layui-input(type='text', name='licenseShortId', required, lay-verify='required', autocomplete='off')
.layui-form-mid.layui-word-aux
font(color='red') *
.layui-form-button
.layui-button-block
button.layui-btn(lay-submit, lay-filter='formNewLicense') 立即提交
button.layui-btn.layui-btn-original(type='reset') 重置
script.
layui.use('form', function () {
var form = layui.form();
form.render(); //更新全部
});
layui.use('element', function () {
var element = layui.element();
});

View File

@ -0,0 +1,78 @@
//- 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.
extends /admin/include/layout.pug
block content
.row: .col-lg-12
h1.site-h1(style='background-color:#FFFFFF;')
| 使用授权证书列表 (#{licenses.size()})
| ,更新时间 #{pugHelper.formatDate('yyyy-MM-dd HH:mm:ss', updateTime)}
span(style='float:right;')
button.layui-btn.layui-btn-small.green(href='/admin/license/add.html', data-toggle='ajax', data-width='550', data-height='450', data-title='添加使用授权证书')
| 添加使用授权证书
.row(style='padding:5px;')
.col-lg-12
table.layui-table(lay-skin='line')
colgroup
col(width='10%')
col(width='10%')
col(width='15%')
col(width='10%')
col(width='15%')
col(width='10%')
col(width='10%')
col(width='1%')
thead
tr
th 证书标识
th 产品标识
th 产品名称
th 有效期截止
th 配额剩余
th 所属人昵称
th 添加时间
th(style='white-space:nowrap;', nowrap) 操作
tbody
for item in licenses
tr
td= pugHelper.messupStringWithStars(item.license.shortId)
td= item.product.shortId
td= item.product.name
td= item.license.effectivedateend
td= item.license.quotaeffectiveremaining
td= item.user.nickname
td= pugHelper.formatDate('yyyy-MM-dd HH:mm:ss', item.addDate)
td(style="white-space:nowrap;" nowrap="nowrap")
a(href="/admin/license/edit.html?id=" + item.license.shortId, data-toggle="ajax", data-width="550", data-height="450", data-title="编辑使用授权证书")
i.layui-icon &#xe642;
span 编辑
a(href="/admin/license/delete.html?id=" + item.license.shortId style="margin-left:10px;" data-toggle="tip" title="请确认是否删除使用授权证书?")
i.layui-icon(style="color:red;") &#x1006;
span 删除
.row(style='padding:5px;')
.col-lg-12#page(style='text-align:center;')
script.
layui.use(['laypage', 'layer'], function () {
var laypage = layui.laypage
, layer = layui.layer;
// laypage({
// cont: 'page'
// , pages: #{emailList.totalPages} //总页数
// , curr: #{emailList.number + 1}
// , groups: 5 //连续显示分页数
// , jump: function (data, first) {
// if (!first) {
// location.href = "/admin/email/index.html?p=" + data.curr;
// }
// }
// });
});

View File

@ -2229,7 +2229,6 @@ CREATE TABLE `uk_organ` (
-- Records of uk_organ
-- ----------------------------
INSERT INTO `uk_organ` VALUES ('2c9e80867d65eb5c017d65f17ceb0019', '售前坐席A组', null, null, null, null, null, null, '4028a0866f9403f1016f9405a05d000e', '1', '');
INSERT INTO `uk_organ` VALUES ('40288296874ae16101874ae4f2670016', '机器人平台', null, null, null, null, null, null, '4028a0866f9403f1016f9405a05d000e', '0', '');
INSERT INTO `uk_organ` VALUES ('4028a0866f9403f1016f9405a05d000e', '我的企业', null, null, null, null, 'cskefu', null, '0', '0', '');
-- ----------------------------