From 3cb64fa66414fce5069990026e197e639a1333b7 Mon Sep 17 00:00:00 2001 From: Hai Liang Wang Date: Sun, 24 Sep 2023 14:48:59 +0800 Subject: [PATCH] https://gitee.com/cskefu/cskefu/issues/I836RO add billing resource for user, add server instance section Signed-off-by: Hai Liang Wang --- .../controller/admin/LicenseController.java | 24 ++++++-- .../com/cskefu/cc/proxy/LicenseProxy.java | 6 +- .../main/java/com/cskefu/cc/util/Base62.java | 15 +++++ .../java/com/cskefu/cc/util/PugHelper.java | 56 ++++++++++++++++++ .../templates/admin/include/left.pug | 11 +++- .../templates/admin/license/index.pug | 13 +++- .../templates/admin/license/instance.pug | 59 +++++++++++++++++++ 7 files changed, 170 insertions(+), 14 deletions(-) create mode 100644 contact-center/app/src/main/resources/templates/admin/license/instance.pug 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 index 1fef4837..07b82405 100644 --- 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 @@ -45,7 +45,7 @@ public class LicenseController extends Handler { private LicenseProxy licenseProxy; @RequestMapping("/index") - @Menu(type = "admin", subtype = "license") + @Menu(type = "admin", subtype = "licenseList") public ModelAndView index(ModelMap map, HttpServletRequest request) { User user = super.getUser(request); if (user.isSuperadmin()) { @@ -65,7 +65,7 @@ public class LicenseController extends Handler { } @RequestMapping("/add") - @Menu(type = "admin", subtype = "license") + @Menu(type = "admin", subtype = "licenseList") public ModelAndView add(ModelMap map, HttpServletRequest request) { User user = super.getUser(request); if (user.isSuperadmin()) { @@ -84,7 +84,7 @@ public class LicenseController extends Handler { * @return */ @RequestMapping("/save") - @Menu(type = "admin", subtype = "license") + @Menu(type = "admin", subtype = "licenseList") public ModelAndView save(ModelMap map, HttpServletRequest request, @Valid String licenseShortId) throws MetaKvInvalidKeyException, InvalidRequestException { @@ -152,7 +152,7 @@ public class LicenseController extends Handler { // 跳转回到证书列表 List licenses = licenseProxy.getLicensesInStore(); map.addAttribute(Constants.LICENSES, licenses); - map.addAttribute("updateTime", new Date()); + map.addAttribute(Constants.UPDATETIME, new Date()); map.addAttribute(Constants.LICENSESTOREPROVIDER, licenseProxy.getLicenseStoreProvider()); return request(super.createView("/admin/license/index")); @@ -173,7 +173,7 @@ public class LicenseController extends Handler { } @RequestMapping("/delete/{licenseShortId}") - @Menu(type = "admin", subtype = "license") + @Menu(type = "admin", subtype = "licenseList") public ModelAndView delete(ModelMap map, HttpServletRequest request, @PathVariable String licenseShortId) throws MetaKvInvalidKeyException { @@ -215,4 +215,18 @@ public class LicenseController extends Handler { } } + @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/proxy/LicenseProxy.java b/contact-center/app/src/main/java/com/cskefu/cc/proxy/LicenseProxy.java index f99bc2bb..cfc722a8 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/proxy/LicenseProxy.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/proxy/LicenseProxy.java @@ -95,11 +95,11 @@ public class LicenseProxy { * * @return */ - private String resolveServerinstId() { + public String resolveServerinstId() { Optional metaServerinstIdOpt = metaKvRes.findFirstByMetakey(Constants.LICENSE_SERVER_INST_ID); if (metaServerinstIdOpt.isEmpty()) { // 没有 serverinstId 信息,初始化 - final String serverinstId = MainUtils.getUUID(); + final String serverinstId = Base62.generateShortId(); createMetaKv(Constants.LICENSE_SERVER_INST_ID, serverinstId, Constants.METAKV_DATATYPE_STRING); return serverinstId; } @@ -122,7 +122,7 @@ public class LicenseProxy { * * @return */ - private String resolveServicename() { + public String resolveServicename() { Optional metaServicenameOpt = metaKvRes.findFirstByMetakey(Constants.LICENSE_SERVICE_NAME); if (metaServicenameOpt.isEmpty()) { // 没有 Service Name 信息,初始化 diff --git a/contact-center/app/src/main/java/com/cskefu/cc/util/Base62.java b/contact-center/app/src/main/java/com/cskefu/cc/util/Base62.java index 64cd5722..132fbbba 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/util/Base62.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/util/Base62.java @@ -15,8 +15,11 @@ package com.cskefu.cc.util; import org.apache.commons.codec.digest.DigestUtils; +import org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.lang3.StringUtils; +import java.text.SimpleDateFormat; +import java.util.Date; import java.util.Random; public class Base62 { @@ -63,8 +66,20 @@ public class Base62 { System.out.println(messagr); } + + /** + * 生成 16 位随机字符串作为 ID + * https://stackoverflow.com/questions/4267475/generating-8-character-only-uuids + */ + public static String generateShortId() { + SimpleDateFormat df = new SimpleDateFormat("yyMMdd"); + String randomStr = RandomStringUtils.randomAlphanumeric(10); + return df.format(new Date()) + randomStr; + } + /** * 生成随机字符串 + * * @param targetStringLength * @return */ diff --git a/contact-center/app/src/main/java/com/cskefu/cc/util/PugHelper.java b/contact-center/app/src/main/java/com/cskefu/cc/util/PugHelper.java index 540cbb81..7dd04410 100644 --- a/contact-center/app/src/main/java/com/cskefu/cc/util/PugHelper.java +++ b/contact-center/app/src/main/java/com/cskefu/cc/util/PugHelper.java @@ -12,6 +12,8 @@ package com.cskefu.cc.util; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; +import com.chatopera.store.enums.LICSTATUS; +import com.chatopera.store.exceptions.EnumValueException; import org.apache.commons.lang3.StringUtils; import java.text.SimpleDateFormat; @@ -104,4 +106,58 @@ public class PugHelper { Collections.reverse(result); return result; } + + /** + * 获得证书状态的中文 + * + * @param status + * @return + */ + public String getLicstatusInChinese(final String status) { + try { + LICSTATUS licstatus = LICSTATUS.toValue(status); + switch (licstatus) { + case NOTFOUND -> { + return "未找到"; + } + case EXHAUSTED -> { + return "配额耗尽"; + } + case INUSE -> { + return "使用中"; + } + case EXPIRED -> { + return "已过期"; + } + default -> { + return status; + } + } + } catch (EnumValueException e) { + return "未知"; + } + } + + /** + * 截取字符串,首先根据分隔符分隔,然后选取前 N 个,使用连接符连接返回 + * @param orignal + * @param splitBy + * @param firstN + * @param joinWith + * @return + */ + public String splitStringAndJoinWith(final String orignal, final String splitBy, final int firstN, final String joinWith) { + String[] splits = StringUtils.split(orignal, splitBy); + int n = Math.min(splits.length, firstN); + List joined = new ArrayList<>(); + for (int i = 0; i < n; i++) { + joined.add(splits[i]); + } + + if (joined.size() > 0) { + return StringUtils.join(joined, joinWith); + } else { + return ""; + } + } } diff --git a/contact-center/app/src/main/resources/templates/admin/include/left.pug b/contact-center/app/src/main/resources/templates/admin/include/left.pug index 450595f0..c8af840c 100644 --- a/contact-center/app/src/main/resources/templates/admin/include/left.pug +++ b/contact-center/app/src/main/resources/templates/admin/include/left.pug @@ -70,13 +70,18 @@ ul.layui-nav.layui-nav-tree(lay-filter='demo') a(href='/admin/metadata/index.html') 元数据 dd(class={'layui-this': subtype == 'template'}) a(href='/admin/template/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') 短信通知设置 - + if user.superadmin + li.layui-nav-item.layui-nav-itemed + a.layui-nav-title(href='javascript:;') 使用授权 + dl.layui-nav-child + dd(class={'layui-this': subtype == 'licenseInst'}) + a(href='/admin/license/instance.html') 实例信息 + dd(class={'layui-this': subtype == 'licenseList'}) + a(href='/admin/license/index.html') 授权证书列表 script. function openChatbot() { window.parent.active.tabAdd($(".iframe_btn").data('href'), $(".iframe_btn").data('title'), $(".iframe_btn").data('id')); diff --git a/contact-center/app/src/main/resources/templates/admin/license/index.pug b/contact-center/app/src/main/resources/templates/admin/license/index.pug index c53e9ea8..2093c03c 100644 --- a/contact-center/app/src/main/resources/templates/admin/license/index.pug +++ b/contact-center/app/src/main/resources/templates/admin/license/index.pug @@ -23,12 +23,17 @@ block content span 打开证书商店 .row(style='padding:5px;') + blockquote.layui-elem-quote.layui-quote-nm + i.layui-icon(style="color:gray")  + font(color="#999").layui-word-aux balala ... + .col-lg-12 table.layui-table(lay-skin='line') colgroup col(width='10%') col(width='10%') - col(width='15%') + col(width='10%') + col(width='20%') col(width='10%') col(width='10%') col(width='10%') @@ -37,6 +42,7 @@ block content thead tr th 证书 ID + th 状态 th 产品标识 th 产品名称 th 有效期截止 @@ -49,12 +55,13 @@ block content tr - var messupLicenseShortId = pugHelper.messupStringWithStars(item.license.shortId) td= messupLicenseShortId + td= pugHelper.getLicstatusInChinese(item.license.status) td= item.product.shortId td= item.product.name - td= item.license.effectivedateend + td= pugHelper.splitStringAndJoinWith(item.license.effectivedateend, " ", 1, "") td= item.license.quotaeffectiveremaining td= item.user.nickname - td= pugHelper.formatDate('yyyy-MM-dd HH:mm:ss', item.addDate) + td= pugHelper.formatDate('yyyy-MM-dd', item.addDate) td(style="white-space:nowrap;" nowrap="nowrap") a(href="#", onclick="copyLicenseId2ClipboardOnOS('" + item.license.shortId + "');return false;") i.layui-icon  diff --git a/contact-center/app/src/main/resources/templates/admin/license/instance.pug b/contact-center/app/src/main/resources/templates/admin/license/instance.pug new file mode 100644 index 00000000..7f03ecd4 --- /dev/null +++ b/contact-center/app/src/main/resources/templates/admin/license/instance.pug @@ -0,0 +1,59 @@ +//- 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. +extends /admin/include/layout.pug +block content + .row: .col-lg-12 + h1.site-h1(style='background-color:#FFFFFF;') + | 实例信息 + span(style='float:right;') + .layui-btn-group.ukefu-btn-group + button.layui-btn.layui-btn-small(onclick='openLicenseStorePage()') + span 打开证书商店 + + .row(style='padding:5px;') + blockquote.layui-elem-quote.layui-quote-nm + i.layui-icon(style="color:gray")  + font(color="#999").layui-word-aux balala ... + + .col-lg-12 + fieldset.layui-elem-field + legend(style='font-size:13px!important;') 实例 ID + span.layui-field-box #{SERVERINSTID} + span    + button(style='font-size:10px!important;' onclick='copyServerinstId2ClipboardOnOS("' +SERVERINSTID + '")') + span 复制 + + fieldset.layui-elem-field + legend(style='font-size:13px!important;') 实例名称 + span.layui-field-box #{SERVICENAME} + span    + button(style='font-size:10px!important;' onclick='copyServicename2ClipboardOnOS("' +SERVICENAME + '")') + span 复制 + script. + layui.use(['laypage', 'layer'], function () { + var laypage = layui.laypage + , layer = layui.layer; + }); + + function copyServerinstId2ClipboardOnOS(val){ + copyValue2ClipboardOnOS(val, (err) => { + top.layer.msg('复制完成', {icon: 1, time: 2000, offset: 't'}); + }) + } + + function copyServicename2ClipboardOnOS(val){ + copyValue2ClipboardOnOS(val, (err) => { + top.layer.msg('复制完成', {icon: 1, time: 2000, offset: 't'}); + }) + } + + function openLicenseStorePage() { + var licenseStoreProvider = "#{licenseStoreProvider}"; + window.open(licenseStoreProvider, "_blank"); + } \ No newline at end of file