This commit is contained in:
jack ning
2025-03-11 08:54:04 +08:00
parent dafbdd10f5
commit aff433d772
10 changed files with 300 additions and 41 deletions

View File

@@ -0,0 +1,15 @@
package com.bytedesk.core.base;
public class BasePermissions {
protected static final String HAS_AUTHORITY = "hasAuthority('%s')";
protected static final String HAS_ANY_AUTHORITY = "hasAnyAuthority(%s)";
protected static String formatAuthority(String authority) {
return String.format(HAS_AUTHORITY, authority);
}
protected static String formatAnyAuthority(String... authorities) {
return String.format(HAS_ANY_AUTHORITY, String.join(", ", authorities));
}
}

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-06-08 14:43:05
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2025-03-05 13:13:24
* @LastEditTime: 2025-03-11 08:41:22
* @Description: bytedesk.com https://github.com/Bytedesk/bytedesk
* Please be aware of the BSL license restrictions before installing Bytedesk IM
* selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license.
@@ -16,7 +16,7 @@ package com.bytedesk.core.category;
public enum CategoryTypeEnum {
AUTOREPLY,
QUICKREPLY,
// FAQ,
THREAD,
HELPCENTER,
ROBOT,
LLM,

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-05-11 18:14:28
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2025-03-08 12:31:51
* @LastEditTime: 2025-03-11 08:53:03
* @Description: bytedesk.com https://github.com/Bytedesk/bytedesk
* Please be aware of the BSL license restrictions before installing Bytedesk IM
* selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license.
@@ -20,7 +20,7 @@ import com.bytedesk.core.enums.PlatformEnum;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EntityListeners;
// import jakarta.persistence.EntityListeners;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Builder;
@@ -36,7 +36,7 @@ import lombok.experimental.Accessors;
@EqualsAndHashCode(callSuper = true)
@AllArgsConstructor
@NoArgsConstructor
@EntityListeners({TagEntityListener.class})
// @EntityListeners({TagEntityListener.class})
@Table(name = "bytedesk_core_tag")
public class TagEntity extends BaseEntity {

View File

@@ -1,8 +1,8 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2024-11-05 16:58:18
* @LastEditors: jack ning github@bytedesk.com
* @LastEditTime: 2025-03-08 10:32:22
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2025-03-11 08:49:51
* @Description: bytedesk.com https://github.com/Bytedesk/bytedesk
* Please be aware of the BSL license restrictions before installing Bytedesk IM
* selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license.
@@ -13,17 +13,19 @@
*/
package com.bytedesk.core.tag;
public class TagPermissions {
import com.bytedesk.core.base.BasePermissions;
public class TagPermissions extends BasePermissions {
public static final String TAG_PREFIX = "TAG_";
// Tag permissions
public static final String TAG_CREATE = "hasAuthority('TAG_CREATE')";
public static final String TAG_READ = "hasAuthority('TAG_READ')";
public static final String TAG_UPDATE = "hasAuthority('TAG_UPDATE')";
public static final String TAG_DELETE = "hasAuthority('TAG_DELETE')";
public static final String TAG_EXPORT = "hasAuthority('TAG_EXPORT')";
public static final String TAG_CREATE = formatAuthority(TAG_PREFIX + "CREATE");
public static final String TAG_READ = formatAuthority(TAG_PREFIX + "READ");
public static final String TAG_UPDATE = formatAuthority(TAG_PREFIX + "UPDATE");
public static final String TAG_DELETE = formatAuthority(TAG_PREFIX + "DELETE");
public static final String TAG_EXPORT = formatAuthority(TAG_PREFIX + "EXPORT");
//
public static final String TAG_ANY = "hasAnyAuthority('TAG_CREATE', 'TAG_READ', 'TAG_UPDATE', 'TAG_EXPORT', 'TAG_DELETE')";
public static final String TAG_ANY = formatAnyAuthority(TAG_PREFIX + "CREATE", TAG_PREFIX + "READ", TAG_PREFIX + "UPDATE", TAG_PREFIX + "EXPORT", TAG_PREFIX + "DELETE");
}
}

View File

@@ -0,0 +1,134 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2025-02-03 13:42:18
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2025-03-11 08:39:02
* @Description: bytedesk.com https://github.com/Bytedesk/bytedesk
* Please be aware of the BSL license restrictions before installing Bytedesk IM
* selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license.
* Business Source License 1.1: https://github.com/Bytedesk/bytedesk/blob/main/LICENSE
* contact: 270580156@qq.com
*
* Copyright (c) 2025 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.core.thread;
import com.bytedesk.core.constant.I18Consts;
public class ThreadCategories {
/**
* Technical Support Categories
* 技术支持类
*/
public static final String[] TECHNICAL_SUPPORT = {
I18Consts.I18N_PREFIX + "thread.category.technical_support", // parent
// I18Consts.I18N_PREFIX + "thread.category.technical.system_error", // children
// I18Consts.I18N_PREFIX + "thread.category.technical.software_issue",
// I18Consts.I18N_PREFIX + "thread.category.technical.hardware_issue",
// I18Consts.I18N_PREFIX + "thread.category.technical.network_issue",
// I18Consts.I18N_PREFIX + "thread.category.technical.account_permission"
};
/**
* Service Request Categories
* 服务请求类
*/
public static final String[] SERVICE_REQUEST = {
I18Consts.I18N_PREFIX + "thread.category.service_request", // parent
// I18Consts.I18N_PREFIX + "thread.category.service.new_account", // children
// I18Consts.I18N_PREFIX + "thread.category.service.permission_change",
// I18Consts.I18N_PREFIX + "thread.category.service.device_request",
// I18Consts.I18N_PREFIX + "thread.category.service.environment_setup",
// I18Consts.I18N_PREFIX + "thread.category.service.data_recovery"
};
/**
* Consultation Categories
* 咨询类
*/
public static final String[] CONSULTATION = {
I18Consts.I18N_PREFIX + "thread.category.consultation", // parent
// I18Consts.I18N_PREFIX + "thread.category.consult.product_usage", // children
// I18Consts.I18N_PREFIX + "thread.category.consult.technical_solution",
// I18Consts.I18N_PREFIX + "thread.category.consult.business_process"
};
/**
* Complaint & Suggestion Categories
* 投诉与建议类
*/
public static final String[] COMPLAINT_SUGGESTION = {
I18Consts.I18N_PREFIX + "thread.category.complaint_suggestion", // parent
// I18Consts.I18N_PREFIX + "thread.category.complaint.service_quality", // children
// I18Consts.I18N_PREFIX + "thread.category.complaint.system_improvement",
// I18Consts.I18N_PREFIX + "thread.category.complaint.process_optimization"
};
/**
* Operation & Maintenance Categories
* 运维类
*/
public static final String[] OPERATION_MAINTENANCE = {
I18Consts.I18N_PREFIX + "thread.category.operation_maintenance", // parent
// I18Consts.I18N_PREFIX + "thread.category.operation.system_maintenance", // children
// I18Consts.I18N_PREFIX + "thread.category.operation.data_backup",
// I18Consts.I18N_PREFIX + "thread.category.operation.monitoring_alert",
// I18Consts.I18N_PREFIX + "thread.category.operation.security_issue",
// I18Consts.I18N_PREFIX + "thread.category.operation.performance_optimization"
// 其他
I18Consts.I18N_PREFIX + "thread.category.other",
};
/**
* Helper method to determine if a category is a parent category
* @param category The category key to check
* @return true if it's a parent category
*/
public static boolean isParentCategory(String category) {
return !category.contains(".");
}
/**
* Helper method to get parent category key for a child category
* @param childCategory The child category key
* @return The parent category key
*/
public static String getParentCategory(String childCategory) {
if (isParentCategory(childCategory)) {
return null;
}
String[] parts = childCategory.split("\\.");
return I18Consts.I18N_PREFIX + "thread.category." + parts[2];
}
/**
* Get all categories as a single array
* @return Array containing all categories
*/
public static String[] getAllCategories() {
int totalLength = TECHNICAL_SUPPORT.length + SERVICE_REQUEST.length +
CONSULTATION.length + COMPLAINT_SUGGESTION.length +
OPERATION_MAINTENANCE.length;
String[] allCategories = new String[totalLength];
int index = 0;
System.arraycopy(TECHNICAL_SUPPORT, 0, allCategories, index, TECHNICAL_SUPPORT.length);
index += TECHNICAL_SUPPORT.length;
System.arraycopy(SERVICE_REQUEST, 0, allCategories, index, SERVICE_REQUEST.length);
index += SERVICE_REQUEST.length;
System.arraycopy(CONSULTATION, 0, allCategories, index, CONSULTATION.length);
index += CONSULTATION.length;
System.arraycopy(COMPLAINT_SUGGESTION, 0, allCategories, index, COMPLAINT_SUGGESTION.length);
index += COMPLAINT_SUGGESTION.length;
System.arraycopy(OPERATION_MAINTENANCE, 0, allCategories, index, OPERATION_MAINTENANCE.length);
return allCategories;
}
}

View File

@@ -0,0 +1,99 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2025-03-11 08:40:10
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2025-03-11 08:40:14
* @Description: bytedesk.com https://github.com/Bytedesk/bytedesk
* Please be aware of the BSL license restrictions before installing Bytedesk IM
* selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license.
* Business Source License 1.1: https://github.com/Bytedesk/bytedesk/blob/main/LICENSE
* contact: 270580156@qq.com
*
* Copyright (c) 2025 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.core.thread;
import org.springframework.beans.factory.SmartInitializingSingleton;
import org.springframework.stereotype.Component;
import com.bytedesk.core.category.CategoryRequest;
import com.bytedesk.core.category.CategoryRestService;
import com.bytedesk.core.category.CategoryTypeEnum;
import com.bytedesk.core.constant.BytedeskConsts;
import com.bytedesk.core.constant.I18Consts;
import com.bytedesk.core.enums.LevelEnum;
import com.bytedesk.core.enums.PermissionEnum;
import com.bytedesk.core.rbac.authority.AuthorityRequest;
import com.bytedesk.core.rbac.authority.AuthorityRestService;
import com.bytedesk.core.utils.Utils;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Component
@AllArgsConstructor
public class ThreadInitializer implements SmartInitializingSingleton {
private final AuthorityRestService authorityService;
private final CategoryRestService categoryService;
@Override
public void afterSingletonsInstantiated() {
initAuthority();
initThreadCategory();
}
private void initAuthority() {
for (PermissionEnum permission : PermissionEnum.values()) {
String permissionValue = ThreadPermissions.THREAD_PREFIX + permission.name();
if (authorityService.existsByValue(permissionValue)) {
// log.info("Thread authority {} already exists", permissionValue);
continue;
}
AuthorityRequest authRequest = AuthorityRequest.builder()
.name(I18Consts.I18N_PREFIX + permissionValue)
.value(permissionValue)
.description("Permission for " + permissionValue)
.build();
authRequest.setUid(permissionValue.toLowerCase());
authorityService.create(authRequest);
}
}
private void initThreadCategory() {
log.info("initThreadCategory");
String orgUid = BytedeskConsts.DEFAULT_ORGANIZATION_UID;
for (String category : ThreadCategories.getAllCategories()) {
// log.info("initThreadCategory: {}", category);
// if (ThreadCategories.isParentCategory(category)) { // 父类
CategoryRequest categoryRequest = CategoryRequest.builder()
.name(category)
.orderNo(0)
.level(LevelEnum.ORGANIZATION.name())
.platform(BytedeskConsts.PLATFORM_BYTEDESK)
.build();
categoryRequest.setType(CategoryTypeEnum.THREAD.name());
categoryRequest.setUid(Utils.formatUid(orgUid, category));
categoryRequest.setOrgUid(orgUid);
categoryService.create(categoryRequest);
// } else { // 子类
// String parentCategory = ThreadCategories.getParentCategory(category);
// CategoryRequest categoryRequest = CategoryRequest.builder()
// .parentUid(orgUid + parentCategory)
// .name(category)
// .orderNo(0)
// .level(LevelEnum.ORGANIZATION.name())
// .platform(BytedeskConsts.PLATFORM_BYTEDESK)
// .build();
// categoryRequest.setType(CategoryTypeEnum.THREAD.name());
// categoryRequest.setUid(orgUid + category);
// categoryRequest.setOrgUid(orgUid);
// categoryService.create(categoryRequest);
// }
}
}
}

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-11-05 16:58:18
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-11-05 16:58:22
* @LastEditTime: 2025-03-11 08:51:42
* @Description: bytedesk.com https://github.com/Bytedesk/bytedesk
* Please be aware of the BSL license restrictions before installing Bytedesk IM
* selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license.
@@ -13,15 +13,18 @@
*/
package com.bytedesk.core.thread;
public class ThreadPermissions {
import com.bytedesk.core.base.BasePermissions;
public class ThreadPermissions extends BasePermissions {
public static final String THREAD_PREFIX = "THREAD_";
// Thread permissions
public static final String THREAD_CREATE = "hasAuthority('THREAD_CREATE')";
public static final String THREAD_READ = "hasAuthority('THREAD_READ')";
public static final String THREAD_UPDATE = "hasAuthority('THREAD_UPDATE')";
public static final String THREAD_DELETE = "hasAuthority('THREAD_DELETE')";
public static final String THREAD_EXPORT = "hasAuthority('THREAD_EXPORT')";
public static final String THREAD_CREATE = formatAuthority(THREAD_PREFIX + "CREATE");
public static final String THREAD_READ = formatAuthority(THREAD_PREFIX + "READ");
public static final String THREAD_UPDATE = formatAuthority(THREAD_PREFIX + "UPDATE");
public static final String THREAD_DELETE = formatAuthority(THREAD_PREFIX + "DELETE");
public static final String THREAD_EXPORT = formatAuthority(THREAD_PREFIX + "EXPORT");
public static final String THREAD_ANY = formatAnyAuthority(THREAD_PREFIX + "CREATE", THREAD_PREFIX + "READ", THREAD_PREFIX + "UPDATE", THREAD_PREFIX + "EXPORT", THREAD_PREFIX + "DELETE");
}